From d06b4a9f05438ba39bb4613ab05ee49a996b85b7 Mon Sep 17 00:00:00 2001 From: stefanjones Date: Tue, 26 Nov 2002 10:11:50 +0000 Subject: [PATCH] tclspice 0.2.7 import --- AUTHORS | 75 +- ChangeLog | 235 ++ DEVICES | 167 -- FAQ | 530 ++-- Makefile.am | 7 +- NEWS | 224 +- README | 69 +- acconfig.h | 24 + autogen.sh | 28 +- configure.in | 329 +- contrib/ChangeLog | 12 +- contrib/mslib/inc_inp.c | 24 +- contrib/mslib/makefile | 7 +- contrib/spiceprm/CHANGES | 7 + contrib/spiceprm/spiceprm | 5 +- doc/ChangeLog | 12 + doc/ngspice.texi | 861 +++--- man/man1/Makefile.am | 2 +- src/ChangeLog | 79 + src/Makefile.am | 213 +- src/frontend/ChangeLog | 271 +- src/frontend/Makefile.am | 280 +- src/frontend/arg.c | 11 +- src/frontend/aspice.c | 34 +- src/frontend/breakp.c | 4 +- src/frontend/breakp2.c | 5 +- src/frontend/circuits.c | 25 +- src/frontend/circuits.h | 11 +- src/frontend/cpitf.c | 21 +- src/frontend/define.c | 7 +- src/frontend/device.c | 158 +- src/frontend/device.h | 4 + src/frontend/diff.c | 36 +- src/frontend/diff.h | 10 +- src/frontend/dimens.c | 20 +- src/frontend/dimens.h | 4 +- src/frontend/display.c | 57 +- src/frontend/dotcards.c | 245 +- src/frontend/evaluate.c | 456 +-- src/frontend/evaluate.h | 7 +- src/frontend/fourier.c | 222 +- src/frontend/fourier.h | 3 +- src/frontend/gens.c | 45 +- src/frontend/gens.h | 4 +- src/frontend/inp.c | 300 +- src/frontend/inpcom.c | 98 +- src/frontend/interp.c | 339 +-- src/frontend/linear.c | 4 +- src/frontend/misccoms.c | 231 +- src/frontend/misccoms.h | 1 - src/frontend/miscvars.c | 2 +- src/frontend/mw_coms.c | 6 +- src/frontend/newcoms.c | 5 +- src/frontend/nutinp.c | 9 +- src/frontend/options.c | 6 +- src/frontend/outitf.c | 428 ++- src/frontend/parse.c | 19 +- src/frontend/parse.h | 7 +- src/frontend/points.c | 20 +- src/frontend/postcoms.c | 546 +--- src/frontend/postsc.c | 60 +- src/frontend/rawfile.c | 18 +- src/frontend/resource.c | 45 +- src/frontend/runcoms.c | 76 +- src/frontend/runcoms2.c | 86 +- src/frontend/shyu.c | 4 +- src/frontend/spec.c | 8 +- src/frontend/spiceif.c | 585 +++- src/frontend/spiceif.h | 4 + src/frontend/subckt.c | 181 +- src/frontend/typesdef.c | 11 +- src/frontend/vectors.c | 278 +- src/frontend/where.c | 23 +- src/include/ChangeLog | 23 + src/include/Makefile.am | 109 +- src/include/cktdefs.h | 253 +- src/include/complex.h | 321 +- src/include/cpdefs.h | 78 +- src/include/cpextern.h | 24 +- src/include/cpstd.h | 49 +- src/include/defines.h | 5 - src/include/devdefs.h | 61 +- src/include/distodef.h | 25 +- src/include/ftedefs.h | 15 +- src/include/ftedev.h | 2 +- src/include/fteext.h | 64 +- src/include/fteinput.h | 4 +- src/include/fteparse.h | 26 +- src/include/gendefs.h | 2 + src/include/hlpdefs.h | 3 +- src/include/iferrmsg.h | 6 +- src/include/ifsim.h | 89 +- src/include/inpdefs.h | 67 +- src/include/inpptree.h | 5 + src/include/jobdefs.h | 11 - src/include/macros.h | 89 +- src/include/ngspice.h | 46 +- src/include/optdefs.h | 26 + src/include/sensgen.h | 1 + src/include/smpdefs.h | 68 +- src/include/sperror.h | 13 +- src/include/spmatrix.h | 221 +- src/include/tskdefs.h | 9 + src/main.c | 122 +- src/maths/Makefile.am | 2 +- src/maths/cmaths/Makefile.am | 29 +- src/maths/cmaths/cmath1.c | 11 +- src/maths/cmaths/cmath2.c | 143 +- src/maths/cmaths/cmath2.h | 6 + src/maths/cmaths/cmath3.c | 10 +- src/maths/cmaths/cmath4.c | 52 +- src/maths/ni/ChangeLog | 5 + src/maths/ni/niconv.c | 4 - src/maths/ni/niiter.c | 50 +- src/maths/ni/nipzmeth.c | 46 +- src/maths/ni/nireinit.c | 9 +- src/maths/sparse/Makefile.am | 21 +- src/maths/sparse/spalloc.c | 461 ++- src/maths/sparse/spbuild.c | 505 ++-- src/maths/sparse/spcombin.c | 53 +- src/maths/sparse/spdefs.h | 323 +- src/maths/sparse/spextra.c | 165 -- src/maths/sparse/spfactor.c | 1243 ++++---- src/maths/sparse/spoutput.c | 424 ++- src/maths/sparse/spsmp.c | 247 +- src/maths/sparse/spsolve.c | 334 +-- src/maths/sparse/sputils.c | 1252 ++++---- src/misc/ChangeLog | 16 +- src/misc/Makefile.am | 18 +- src/misc/alloc.c | 63 +- src/misc/alloc.h | 2 + src/misc/dup2.c | 3 +- src/misc/ivars.c | 47 +- src/misc/misc_time.c | 1 + src/misc/mktemp.c | 8 +- src/misc/printnum.c | 14 +- src/misc/printnum.h | 2 +- src/misc/string.c | 9 +- src/misc/tilde.c | 6 +- src/ngspice.c | 222 +- src/ngspice.idx | Bin 13464 -> 13464 bytes src/ngspice.txt | 413 +-- src/spicelib/devices/ChangeLog | 64 + src/spicelib/devices/Makefile.am | 29 +- src/spicelib/devices/asrc/Makefile.am | 35 +- src/spicelib/devices/asrc/asrcacld.c | 123 +- src/spicelib/devices/asrc/asrcask.c | 2 +- src/spicelib/devices/asrc/asrcconv.c | 4 +- src/spicelib/devices/asrc/asrcdel.c | 2 +- src/spicelib/devices/asrc/asrcfbr.c | 8 +- src/spicelib/devices/asrc/asrcitf.h | 73 +- src/spicelib/devices/asrc/asrcload.c | 57 +- src/spicelib/devices/asrc/asrcmdel.c | 10 +- src/spicelib/devices/asrc/asrcpar.c | 2 +- src/spicelib/devices/asrc/asrcpzld.c | 4 +- src/spicelib/devices/asrc/asrcset.c | 10 +- src/spicelib/devices/bjt/ChangeLog | 8 +- src/spicelib/devices/bjt/Makefile.am | 60 +- src/spicelib/devices/bjt/bjtacld.c | 6 +- src/spicelib/devices/bjt/bjtconv.c | 6 +- src/spicelib/devices/bjt/bjtdisto.c | 7 +- src/spicelib/devices/bjt/bjtdset.c | 816 ++--- src/spicelib/devices/bjt/bjtdset.h | 2 +- src/spicelib/devices/bjt/bjtext.h | 33 +- src/spicelib/devices/bjt/bjtgetic.c | 4 +- src/spicelib/devices/bjt/bjtitf.h | 91 +- src/spicelib/devices/bjt/bjtload.c | 102 +- src/spicelib/devices/bjt/bjtnoise.c | 7 +- src/spicelib/devices/bjt/bjtparam.c | 2 +- src/spicelib/devices/bjt/bjtpzld.c | 8 +- src/spicelib/devices/bjt/bjtsacl.c | 4 +- src/spicelib/devices/bjt/bjtsetup.c | 52 +- src/spicelib/devices/bjt/bjtsload.c | 4 +- src/spicelib/devices/bjt/bjtsprt.c | 6 +- src/spicelib/devices/bjt/bjtsset.c | 6 +- src/spicelib/devices/bjt/bjtsupd.c | 6 +- src/spicelib/devices/bjt/bjttemp.c | 8 +- src/spicelib/devices/bjt/bjttrunc.c | 6 +- src/spicelib/devices/bsim1/Makefile.am | 50 +- src/spicelib/devices/bsim1/b1acld.c | 6 +- src/spicelib/devices/bsim1/b1cvtest.c | 6 +- src/spicelib/devices/bsim1/b1disto.c | 7 +- src/spicelib/devices/bsim1/b1dset.c | 6 +- src/spicelib/devices/bsim1/b1eval.c | 6 +- src/spicelib/devices/bsim1/b1ld.c | 25 +- src/spicelib/devices/bsim1/b1moscap.c | 2 +- src/spicelib/devices/bsim1/b1pzld.c | 8 +- src/spicelib/devices/bsim1/b1set.c | 31 +- src/spicelib/devices/bsim1/b1temp.c | 4 +- src/spicelib/devices/bsim1/b1trunc.c | 6 +- src/spicelib/devices/bsim1/bsim1ext.h | 2 + src/spicelib/devices/bsim1/bsim1itf.h | 79 +- src/spicelib/devices/bsim2/Makefile.am | 46 +- src/spicelib/devices/bsim2/b2acld.c | 6 +- src/spicelib/devices/bsim2/b2cvtest.c | 6 +- src/spicelib/devices/bsim2/b2eval.c | 6 +- src/spicelib/devices/bsim2/b2ld.c | 25 +- src/spicelib/devices/bsim2/b2moscap.c | 2 +- src/spicelib/devices/bsim2/b2pzld.c | 8 +- src/spicelib/devices/bsim2/b2set.c | 39 +- src/spicelib/devices/bsim2/b2temp.c | 8 +- src/spicelib/devices/bsim2/b2trunc.c | 6 +- src/spicelib/devices/bsim2/bsim2itf.h | 76 +- src/spicelib/devices/bsim3/Makefile.am | 46 +- src/spicelib/devices/bsim3/b3.c | 22 +- src/spicelib/devices/bsim3/b3acld.c | 573 ++-- src/spicelib/devices/bsim3/b3ask.c | 91 +- src/spicelib/devices/bsim3/b3check.c | 27 +- src/spicelib/devices/bsim3/b3cvtest.c | 29 +- src/spicelib/devices/bsim3/b3del.c | 23 - src/spicelib/devices/bsim3/b3dest.c | 23 - src/spicelib/devices/bsim3/b3getic.c | 20 - src/spicelib/devices/bsim3/b3ld.c | 185 +- src/spicelib/devices/bsim3/b3mask.c | 20 - src/spicelib/devices/bsim3/b3mdel.c | 23 - src/spicelib/devices/bsim3/b3mpar.c | 3300 ++++++++++----------- src/spicelib/devices/bsim3/b3noi.c | 33 +- src/spicelib/devices/bsim3/b3par.c | 28 +- src/spicelib/devices/bsim3/b3pzld.c | 31 +- src/spicelib/devices/bsim3/b3set.c | 1911 ++++++------ src/spicelib/devices/bsim3/b3temp.c | 32 +- src/spicelib/devices/bsim3/b3trunc.c | 26 +- src/spicelib/devices/bsim3/bsim3def.h | 9 +- src/spicelib/devices/bsim3/bsim3itf.h | 81 +- src/spicelib/devices/bsim3v1/Makefile.am | 44 +- src/spicelib/devices/bsim3v1/b3v1.c | 13 - src/spicelib/devices/bsim3v1/b3v1acld.c | 20 +- src/spicelib/devices/bsim3v1/b3v1ask.c | 14 - src/spicelib/devices/bsim3v1/b3v1check.c | 18 +- src/spicelib/devices/bsim3v1/b3v1cvtest.c | 20 +- src/spicelib/devices/bsim3v1/b3v1del.c | 14 - src/spicelib/devices/bsim3v1/b3v1dest.c | 14 - src/spicelib/devices/bsim3v1/b3v1getic.c | 15 - src/spicelib/devices/bsim3v1/b3v1ld.c | 97 +- src/spicelib/devices/bsim3v1/b3v1mask.c | 14 - src/spicelib/devices/bsim3v1/b3v1mdel.c | 14 - src/spicelib/devices/bsim3v1/b3v1mpar.c | 15 - src/spicelib/devices/bsim3v1/b3v1noi.c | 37 +- src/spicelib/devices/bsim3v1/b3v1par.c | 14 - src/spicelib/devices/bsim3v1/b3v1pzld.c | 22 +- src/spicelib/devices/bsim3v1/b3v1set.c | 25 +- src/spicelib/devices/bsim3v1/b3v1temp.c | 25 +- src/spicelib/devices/bsim3v1/b3v1trunc.c | 20 +- src/spicelib/devices/bsim3v1/bsim3v1itf.h | 83 +- src/spicelib/devices/bsim3v2/Makefile.am | 44 +- src/spicelib/devices/bsim3v2/b3v2.c | 14 - src/spicelib/devices/bsim3v2/b3v2acld.c | 22 +- src/spicelib/devices/bsim3v2/b3v2ask.c | 14 - src/spicelib/devices/bsim3v2/b3v2check.c | 18 +- src/spicelib/devices/bsim3v2/b3v2cvtest.c | 20 +- src/spicelib/devices/bsim3v2/b3v2del.c | 14 - src/spicelib/devices/bsim3v2/b3v2dest.c | 14 - src/spicelib/devices/bsim3v2/b3v2getic.c | 14 - src/spicelib/devices/bsim3v2/b3v2ld.c | 54 +- src/spicelib/devices/bsim3v2/b3v2mask.c | 14 - src/spicelib/devices/bsim3v2/b3v2mdel.c | 14 - src/spicelib/devices/bsim3v2/b3v2mpar.c | 14 - src/spicelib/devices/bsim3v2/b3v2noi.c | 27 +- src/spicelib/devices/bsim3v2/b3v2par.c | 14 - src/spicelib/devices/bsim3v2/b3v2pzld.c | 22 +- src/spicelib/devices/bsim3v2/b3v2set.c | 26 +- src/spicelib/devices/bsim3v2/b3v2temp.c | 20 +- src/spicelib/devices/bsim3v2/b3v2trunc.c | 20 +- src/spicelib/devices/bsim3v2/bsim3v2itf.h | 82 +- src/spicelib/devices/bsim4/ChangeLog | 9 + src/spicelib/devices/bsim4/Makefile.am | 48 +- src/spicelib/devices/bsim4/b4.c | 47 +- src/spicelib/devices/bsim4/b4acld.c | 78 +- src/spicelib/devices/bsim4/b4ask.c | 78 +- src/spicelib/devices/bsim4/b4check.c | 111 +- src/spicelib/devices/bsim4/b4cvtest.c | 38 +- src/spicelib/devices/bsim4/b4del.c | 9 +- src/spicelib/devices/bsim4/b4dest.c | 9 +- src/spicelib/devices/bsim4/b4geo.c | 12 +- src/spicelib/devices/bsim4/b4getic.c | 14 +- src/spicelib/devices/bsim4/b4ld.c | 466 +-- src/spicelib/devices/bsim4/b4mask.c | 16 +- src/spicelib/devices/bsim4/b4mdel.c | 10 +- src/spicelib/devices/bsim4/b4mpar.c | 19 +- src/spicelib/devices/bsim4/b4noi.c | 27 +- src/spicelib/devices/bsim4/b4par.c | 10 +- src/spicelib/devices/bsim4/b4pzld.c | 79 +- src/spicelib/devices/bsim4/b4set.c | 105 +- src/spicelib/devices/bsim4/b4temp.c | 167 +- src/spicelib/devices/bsim4/b4trunc.c | 17 +- src/spicelib/devices/bsim4/bsim4def.h | 131 +- src/spicelib/devices/bsim4/bsim4ext.h | 5 +- src/spicelib/devices/bsim4/bsim4itf.h | 81 +- src/spicelib/devices/cap/Makefile.am | 50 +- src/spicelib/devices/cap/capacld.c | 6 +- src/spicelib/devices/cap/capask.c | 6 +- src/spicelib/devices/cap/capitf.h | 81 +- src/spicelib/devices/cap/capload.c | 8 +- src/spicelib/devices/cap/cappzld.c | 6 +- src/spicelib/devices/cap/capsacl.c | 6 +- src/spicelib/devices/cap/capsetup.c | 6 +- src/spicelib/devices/cap/capsload.c | 6 +- src/spicelib/devices/cap/capsprt.c | 6 +- src/spicelib/devices/cap/capsset.c | 6 +- src/spicelib/devices/cap/capsupd.c | 6 +- src/spicelib/devices/cap/captemp.c | 4 +- src/spicelib/devices/cap/captrunc.c | 8 +- src/spicelib/devices/cccs/Makefile.am | 34 +- src/spicelib/devices/cccs/cccsitf.h | 78 +- src/spicelib/devices/cccs/cccsload.c | 4 +- src/spicelib/devices/cccs/cccspzld.c | 4 +- src/spicelib/devices/cccs/cccssacl.c | 4 +- src/spicelib/devices/cccs/cccsset.c | 8 +- src/spicelib/devices/cccs/cccssld.c | 4 +- src/spicelib/devices/cccs/cccssprt.c | 6 +- src/spicelib/devices/cccs/cccssset.c | 6 +- src/spicelib/devices/ccvs/Makefile.am | 36 +- src/spicelib/devices/ccvs/ccvsfbr.c | 8 +- src/spicelib/devices/ccvs/ccvsitf.h | 79 +- src/spicelib/devices/ccvs/ccvsload.c | 4 +- src/spicelib/devices/ccvs/ccvspzld.c | 4 +- src/spicelib/devices/ccvs/ccvssacl.c | 4 +- src/spicelib/devices/ccvs/ccvsset.c | 10 +- src/spicelib/devices/ccvs/ccvssld.c | 4 +- src/spicelib/devices/ccvs/ccvssprt.c | 6 +- src/spicelib/devices/ccvs/ccvssset.c | 6 +- src/spicelib/devices/csw/Makefile.am | 35 +- src/spicelib/devices/csw/cswacld.c | 6 +- src/spicelib/devices/csw/cswdefs.h | 3 +- src/spicelib/devices/csw/cswext.h | 5 + src/spicelib/devices/csw/cswitf.h | 76 +- src/spicelib/devices/csw/cswload.c | 139 +- src/spicelib/devices/csw/cswmpar.c | 4 +- src/spicelib/devices/csw/cswnoise.c | 7 +- src/spicelib/devices/csw/cswpzld.c | 6 +- src/spicelib/devices/csw/cswsetup.c | 6 +- src/spicelib/devices/dio/Makefile.am | 58 +- src/spicelib/devices/dio/dioacld.c | 6 +- src/spicelib/devices/dio/dioconv.c | 4 +- src/spicelib/devices/dio/diodisto.c | 4 +- src/spicelib/devices/dio/diodset.c | 13 +- src/spicelib/devices/dio/dioext.h | 4 + src/spicelib/devices/dio/dioitf.h | 96 +- src/spicelib/devices/dio/dioload.c | 33 +- src/spicelib/devices/dio/dionoise.c | 7 +- src/spicelib/devices/dio/diopzld.c | 6 +- src/spicelib/devices/dio/diosacl.c | 4 +- src/spicelib/devices/dio/diosetup.c | 21 +- src/spicelib/devices/dio/diosload.c | 4 +- src/spicelib/devices/dio/diosprt.c | 6 +- src/spicelib/devices/dio/diosset.c | 6 +- src/spicelib/devices/dio/diosupd.c | 6 +- src/spicelib/devices/dio/diotemp.c | 18 +- src/spicelib/devices/dio/diotrunc.c | 6 +- src/spicelib/devices/ind/Makefile.am | 62 +- src/spicelib/devices/ind/indacld.c | 6 +- src/spicelib/devices/ind/indext.h | 36 +- src/spicelib/devices/ind/inditf.h | 157 +- src/spicelib/devices/ind/indload.c | 10 +- src/spicelib/devices/ind/indpzld.c | 4 +- src/spicelib/devices/ind/indsacl.c | 10 +- src/spicelib/devices/ind/indsetup.c | 8 +- src/spicelib/devices/ind/indsload.c | 10 +- src/spicelib/devices/ind/indsprt.c | 6 +- src/spicelib/devices/ind/indsset.c | 6 +- src/spicelib/devices/ind/indsupd.c | 10 +- src/spicelib/devices/ind/indtrunc.c | 8 +- src/spicelib/devices/ind/mutacld.c | 6 +- src/spicelib/devices/ind/mutpzld.c | 6 +- src/spicelib/devices/ind/mutsetup.c | 6 +- src/spicelib/devices/ind/mutsprt.c | 4 +- src/spicelib/devices/ind/mutsset.c | 6 +- src/spicelib/devices/isrc/Makefile.am | 30 +- src/spicelib/devices/isrc/isrcacct.c | 8 +- src/spicelib/devices/isrc/isrcacld.c | 6 +- src/spicelib/devices/isrc/isrcitf.h | 66 +- src/spicelib/devices/isrc/isrcload.c | 10 +- src/spicelib/devices/isrc/isrcpar.c | 12 + src/spicelib/devices/isrc/isrctemp.c | 4 +- src/spicelib/devices/jfet/Makefile.am | 46 +- src/spicelib/devices/jfet/jfetacld.c | 6 +- src/spicelib/devices/jfet/jfetdist.c | 4 +- src/spicelib/devices/jfet/jfetdset.c | 4 +- src/spicelib/devices/jfet/jfetext.h | 3 + src/spicelib/devices/jfet/jfetitf.h | 81 +- src/spicelib/devices/jfet/jfetload.c | 122 +- src/spicelib/devices/jfet/jfetnoi.c | 7 +- src/spicelib/devices/jfet/jfetpzld.c | 8 +- src/spicelib/devices/jfet/jfetset.c | 35 +- src/spicelib/devices/jfet/jfettemp.c | 4 +- src/spicelib/devices/jfet/jfettrun.c | 6 +- src/spicelib/devices/jfet2/Makefile.am | 46 +- src/spicelib/devices/jfet2/jfet2acld.c | 6 +- src/spicelib/devices/jfet2/jfet2itf.h | 73 +- src/spicelib/devices/jfet2/jfet2load.c | 18 +- src/spicelib/devices/jfet2/jfet2noi.c | 7 +- src/spicelib/devices/jfet2/jfet2set.c | 8 +- src/spicelib/devices/jfet2/jfet2temp.c | 4 +- src/spicelib/devices/jfet2/jfet2trun.c | 6 +- src/spicelib/devices/ltra/Makefile.am | 38 +- src/spicelib/devices/ltra/ltra.c | 14 - src/spicelib/devices/ltra/ltraacct.c | 6 +- src/spicelib/devices/ltra/ltraacld.c | 4 +- src/spicelib/devices/ltra/ltraext.h | 3 + src/spicelib/devices/ltra/ltraitf.h | 68 +- src/spicelib/devices/ltra/ltraload.c | 8 +- src/spicelib/devices/ltra/ltramisc.c | 6 +- src/spicelib/devices/ltra/ltraset.c | 18 +- src/spicelib/devices/ltra/ltratemp.c | 4 +- src/spicelib/devices/ltra/ltratrun.c | 6 +- src/spicelib/devices/mes/Makefile.am | 46 +- src/spicelib/devices/mes/mesacl.c | 6 +- src/spicelib/devices/mes/mesdisto.c | 4 +- src/spicelib/devices/mes/mesdset.c | 4 +- src/spicelib/devices/mes/mesext.h | 3 + src/spicelib/devices/mes/mesitf.h | 80 +- src/spicelib/devices/mes/mesload.c | 38 +- src/spicelib/devices/mes/mesnoise.c | 7 +- src/spicelib/devices/mes/mespzld.c | 6 +- src/spicelib/devices/mes/messetup.c | 35 +- src/spicelib/devices/mes/mestemp.c | 2 +- src/spicelib/devices/mes/mestrunc.c | 6 +- src/spicelib/devices/mos1/Makefile.am | 56 +- src/spicelib/devices/mos1/mos1.c | 2 + src/spicelib/devices/mos1/mos1acld.c | 15 +- src/spicelib/devices/mos1/mos1ask.c | 29 +- src/spicelib/devices/mos1/mos1conv.c | 6 +- src/spicelib/devices/mos1/mos1defs.h | 6 +- src/spicelib/devices/mos1/mos1dist.c | 4 +- src/spicelib/devices/mos1/mos1dset.c | 31 +- src/spicelib/devices/mos1/mos1ext.h | 2 + src/spicelib/devices/mos1/mos1itf.h | 94 +- src/spicelib/devices/mos1/mos1load.c | 620 ++-- src/spicelib/devices/mos1/mos1mpar.c | 2 +- src/spicelib/devices/mos1/mos1noi.c | 9 +- src/spicelib/devices/mos1/mos1par.c | 5 + src/spicelib/devices/mos1/mos1pzld.c | 15 +- src/spicelib/devices/mos1/mos1sacl.c | 6 +- src/spicelib/devices/mos1/mos1set.c | 37 +- src/spicelib/devices/mos1/mos1sld.c | 4 +- src/spicelib/devices/mos1/mos1sprt.c | 12 +- src/spicelib/devices/mos1/mos1sset.c | 6 +- src/spicelib/devices/mos1/mos1supd.c | 6 +- src/spicelib/devices/mos1/mos1temp.c | 45 +- src/spicelib/devices/mos1/mos1trun.c | 6 +- src/spicelib/devices/mos2/Makefile.am | 59 +- src/spicelib/devices/mos2/mos2.c | 2 + src/spicelib/devices/mos2/mos2acld.c | 13 +- src/spicelib/devices/mos2/mos2ask.c | 29 +- src/spicelib/devices/mos2/mos2conv.c | 6 +- src/spicelib/devices/mos2/mos2defs.h | 6 + src/spicelib/devices/mos2/mos2dist.c | 4 +- src/spicelib/devices/mos2/mos2dset.c | 31 +- src/spicelib/devices/mos2/mos2ext.h | 4 + src/spicelib/devices/mos2/mos2itf.h | 94 +- src/spicelib/devices/mos2/mos2load.c | 141 +- src/spicelib/devices/mos2/mos2mask.c | 2 +- src/spicelib/devices/mos2/mos2mpar.c | 2 +- src/spicelib/devices/mos2/mos2noi.c | 11 +- src/spicelib/devices/mos2/mos2par.c | 5 + src/spicelib/devices/mos2/mos2pzld.c | 15 +- src/spicelib/devices/mos2/mos2sacl.c | 6 +- src/spicelib/devices/mos2/mos2set.c | 36 +- src/spicelib/devices/mos2/mos2sld.c | 4 +- src/spicelib/devices/mos2/mos2sprt.c | 11 +- src/spicelib/devices/mos2/mos2sset.c | 6 +- src/spicelib/devices/mos2/mos2supd.c | 6 +- src/spicelib/devices/mos2/mos2temp.c | 46 +- src/spicelib/devices/mos2/mos2trun.c | 6 +- src/spicelib/devices/mos3/Makefile.am | 59 +- src/spicelib/devices/mos3/mos3.c | 7 + src/spicelib/devices/mos3/mos3acld.c | 20 +- src/spicelib/devices/mos3/mos3ask.c | 32 +- src/spicelib/devices/mos3/mos3conv.c | 6 +- src/spicelib/devices/mos3/mos3defs.h | 17 + src/spicelib/devices/mos3/mos3dist.c | 4 +- src/spicelib/devices/mos3/mos3dset.c | 45 +- src/spicelib/devices/mos3/mos3ext.h | 2 + src/spicelib/devices/mos3/mos3itf.h | 94 +- src/spicelib/devices/mos3/mos3load.c | 1900 ++++++------ src/spicelib/devices/mos3/mos3mask.c | 19 + src/spicelib/devices/mos3/mos3mpar.c | 19 +- src/spicelib/devices/mos3/mos3noi.c | 11 +- src/spicelib/devices/mos3/mos3par.c | 6 + src/spicelib/devices/mos3/mos3pzld.c | 19 +- src/spicelib/devices/mos3/mos3sacl.c | 6 +- src/spicelib/devices/mos3/mos3set.c | 44 +- src/spicelib/devices/mos3/mos3sld.c | 18 +- src/spicelib/devices/mos3/mos3sprt.c | 11 +- src/spicelib/devices/mos3/mos3sset.c | 6 +- src/spicelib/devices/mos3/mos3supd.c | 6 +- src/spicelib/devices/mos3/mos3temp.c | 97 +- src/spicelib/devices/mos3/mos3trun.c | 6 +- src/spicelib/devices/mos6/Makefile.am | 34 +- src/spicelib/devices/mos6/mos6ask.c | 21 +- src/spicelib/devices/mos6/mos6conv.c | 6 +- src/spicelib/devices/mos6/mos6ext.h | 7 - src/spicelib/devices/mos6/mos6itf.h | 68 +- src/spicelib/devices/mos6/mos6load.c | 135 +- src/spicelib/devices/mos6/mos6mask.c | 2 +- src/spicelib/devices/mos6/mos6mpar.c | 2 +- src/spicelib/devices/mos6/mos6set.c | 30 +- src/spicelib/devices/mos6/mos6temp.c | 6 +- src/spicelib/devices/mos6/mos6trun.c | 6 +- src/spicelib/devices/res/Makefile.am | 42 +- src/spicelib/devices/res/res.c | 14 +- src/spicelib/devices/res/resask.c | 8 +- src/spicelib/devices/res/resdefs.h | 14 +- src/spicelib/devices/res/resitf.h | 86 +- src/spicelib/devices/res/resload.c | 19 +- src/spicelib/devices/res/resmask.c | 4 + src/spicelib/devices/res/resmpar.c | 5 + src/spicelib/devices/res/resnoise.c | 2 +- src/spicelib/devices/res/resparam.c | 8 + src/spicelib/devices/res/restemp.c | 27 +- src/spicelib/devices/sw/Makefile.am | 37 +- src/spicelib/devices/sw/swacload.c | 6 +- src/spicelib/devices/sw/swdefs.h | 3 +- src/spicelib/devices/sw/swext.h | 3 + src/spicelib/devices/sw/switf.h | 76 +- src/spicelib/devices/sw/swload.c | 144 +- src/spicelib/devices/sw/swmparam.c | 6 +- src/spicelib/devices/sw/swnoise.c | 7 +- src/spicelib/devices/sw/swpzload.c | 6 +- src/spicelib/devices/sw/swsetup.c | 6 +- src/spicelib/devices/tra/Makefile.am | 35 +- src/spicelib/devices/tra/traacct.c | 8 +- src/spicelib/devices/tra/traacld.c | 4 +- src/spicelib/devices/tra/traitf.h | 67 +- src/spicelib/devices/tra/traload.c | 6 +- src/spicelib/devices/tra/trasetup.c | 10 +- src/spicelib/devices/tra/tratemp.c | 4 +- src/spicelib/devices/tra/tratrunc.c | 6 +- src/spicelib/devices/urc/Makefile.am | 28 +- src/spicelib/devices/urc/urcext.h | 16 +- src/spicelib/devices/urc/urcitf.h | 69 +- src/spicelib/devices/urc/urcmpar.c | 2 +- src/spicelib/devices/urc/urcsetup.c | 97 +- src/spicelib/devices/vccs/Makefile.am | 36 +- src/spicelib/devices/vccs/vccsitf.h | 81 +- src/spicelib/devices/vccs/vccsload.c | 4 +- src/spicelib/devices/vccs/vccspzld.c | 4 +- src/spicelib/devices/vccs/vccssacl.c | 4 +- src/spicelib/devices/vccs/vccsset.c | 6 +- src/spicelib/devices/vccs/vccssld.c | 4 +- src/spicelib/devices/vccs/vccssprt.c | 6 +- src/spicelib/devices/vccs/vccssset.c | 6 +- src/spicelib/devices/vcvs/Makefile.am | 38 +- src/spicelib/devices/vcvs/vcvsfbr.c | 8 +- src/spicelib/devices/vcvs/vcvsitf.h | 80 +- src/spicelib/devices/vcvs/vcvsload.c | 4 +- src/spicelib/devices/vcvs/vcvspzld.c | 4 +- src/spicelib/devices/vcvs/vcvssacl.c | 4 +- src/spicelib/devices/vcvs/vcvsset.c | 10 +- src/spicelib/devices/vcvs/vcvssld.c | 4 +- src/spicelib/devices/vcvs/vcvssprt.c | 6 +- src/spicelib/devices/vcvs/vcvssset.c | 6 +- src/spicelib/devices/vsrc/Makefile.am | 38 +- src/spicelib/devices/vsrc/vsrcacct.c | 8 +- src/spicelib/devices/vsrc/vsrcacld.c | 6 +- src/spicelib/devices/vsrc/vsrcfbr.c | 8 +- src/spicelib/devices/vsrc/vsrcitf.h | 70 +- src/spicelib/devices/vsrc/vsrcload.c | 59 +- src/spicelib/devices/vsrc/vsrcpar.c | 11 + src/spicelib/devices/vsrc/vsrcpzld.c | 4 +- src/spicelib/devices/vsrc/vsrcpzs.c | 21 +- src/spicelib/devices/vsrc/vsrcset.c | 10 +- src/spicelib/devices/vsrc/vsrctemp.c | 4 +- tests/Makefile.am | 18 +- tests/README | 15 + tests/diffpair.out | 17 +- tests/fourbitadder.out | 444 ++- 567 files changed, 17245 insertions(+), 19095 deletions(-) diff --git a/AUTHORS b/AUTHORS index de7f02b21..58082e6c2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,39 +1,40 @@ +@c This file will be processed with texinfo. + SPICE was originally written at The University of Berkeley (USA). +Since then, there have been many people working on the software. +The following people have contributed in some way: +Giles C. Billingsley, +Mansun Chan, +Wayne A. Christopher, +Glao S. Dezai , +Daniele Foci , +Noah Friedman , +David A. Gates, +Alan Gillespie , +JianHui Huang, +Jeffrey M. Hsu, +S. Hwang, +Chris Inbody , +Gordon M. Jacobs, +Min-Chie Jeng, +Kenneth H. Keller, +Mathew Lew, +Weidong Liu, +Richard D. McRoberts, +Manfred Metzger , +Paolo Nenzi , +Gary W. Ng, +Hong June Park, +Arno Peters , +Serban-Mihai Popescu , +Thomas L. Quarles, +Emmanuel Rouat , +Jaijeet S. Roychowdhury, +Takayasu Sakurai, +Kanwar Jit Singh, +Andrew Tuckey +Michael Widlok , +and many others... - -Contributors: -------------- - -Giles C. Billingsley -Mansun Chan -Wayne A. Christopher -Noah Friedman -David A. Gates -JianHui Huang -Jeffrey M. Hsu -S. Hwang -Gordon M. Jacobs -Min-Chie Jeng -Kenneth H. Keller -Mathew Lew -Weidong Liu -Gary W. Ng -Hong June Park -Thomas L. Quarles -Jaijeet S. Roychowdhury -Takayasu Sakurai -Kanwar Jit Singh -Andrew Tuckey - -NGSPICE is now actively hacked by: - - * Glao S. Dezai - * Daniele Foci - * Chris Inbody - * Paolo Nenzi - * Arno Peters - * Serban-Mihai Popescu - * Emmanuel Rouat - * Michael Widlok - -(and many others...) +If you feel you should be on this list, write to +. diff --git a/ChangeLog b/ChangeLog index 95cc12a0b..209d86836 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,238 @@ +2001-12-05 Emmanuel Rouat + + * configure.in: removed (unnecessary) macros to handle GNU getopt + (I'm an idiot!) + +2001-12-04 Emmanuel Rouat + + * configure.in, main.c: Forgot a bit to handle GNU getopt correctly + +2001-11-25 Emmanuel Rouat + + * configure.in: New way (cleaner) to handle GNU getopt. + +2001-01-21 Paolo Nenzi + + * bsim3soi_dd/*: BSIM3SOI (DD) support added as level 11. Added tests in + tests directory (tests/bsim3soidd/*). + + * ???: Integrated patch form Alan Gillespie + to revert the spice raw format to the spice3 original. + + * configure.in: corrected a bug that broke the on line help system. + Help system now works again but its text is a little bit outdated. + + * ???: all binaries now have ng prependend, so ngspice can be installed + with other spice flavours. + + +2000-10-18 Arno W. Peters + + * Makefile.am: Changes for notes dir -> NOTES file conversion. + + * tests/Makefile.am: Make distcheck target work again. + +2000-10-17 Arno W. Peters + + * TODO: Little updates. + +2000-10-14 Arno W. Peters + + * acconfig.h, configure.in, src/frontend/inpcom.c, + src/include/complex.h src/include/macros.h, src/include/memory.h + src/include/ngspice.h, src/maths/cmaths/Makefile.am + src/maths/cmaths/cmath1.c, src/maths/cmaths/cmath2.c + src/maths/cmaths/cmath3.c, src/maths/cmaths/cmath4.c + src/maths/cmaths/test_cx_j.c, src/maths/cmaths/test_cx_mag.c + src/maths/cmaths/test_cx_ph.c, src/misc/alloc.c src/misc/alloc.h: + Added support for the Boehm-Weiser conservative garbage collector. + + * NOTES, src/maths/cmaths/cmath.h: Added. + + * notes/Linux.changes, notes/dbx, notes/internal, notes/mac_port + notes/porting, notes/spice2: Removed or incorporated into + NOTES. + + * *: replaced malloc, realloc and free calls to use tmalloc, + trealloc and txfree. + +2000-09-05 Arno W. Peters + + * ???: Paolo and I have integrated patches from Alan Gillespie + . + +2000-07-28 Arno W. Peters + + * tests/polezero/*.out: Changed the content of these files because + the bug that caused the incorrect pole-zero results have been + traced to src/spicelib/analysis/cktpzstr.c. + +2000-07-05 Arno W. Peters + + * src/devices/dev.c: Added first_device() and next_device() to + abstract manipulations to the devices list. Now change all the + code that uses direct access to these functions... + +2000-07-03 Arno W. Peters + + * src/parser/alias.c, src/parser/alias.h: contain frontend alias + command. Moved them to src/frontend/com_alias.c and + src/frontend/com_alias.h. Updated Makefile.am's as appropreate. + + * src/parser/front.c, src/parser/front.h, src/parser/history.c, + src/parser/history.h, src/parser/modify.c, src/parser/modify.h, + src/parser/variable.c, src/parser/variable.h: Empty files. + Removed. + + * src/include/spconfig.h: Removed spCOMPLEX, + spSEPARATED_COMPLEX_VECTORS and spCOMPATIBILITY defines. This + made including this file from src/include/spmatrix.h unnecessary. + Moved this file to src/maths/sparse/spconfig.h. + + * src/include/spmatrix.h: Removed include of + src/include/spconfig.h. + + * src/maths/sparse/spalloc.c, src/maths/sparse/spbuild.c, + src/maths/sparse/spcombin.c, src/maths/sparse/spdefs.h, + src/maths/sparse/spfactor.c, src/maths/sparse/spoutput.c, + src/maths/sparse/spsmp.c, src/maths/sparse/spsolve.c, + src/maths/sparse/sputils.c: The other files affected by the + removal of spCOMPLEX, spSEPARATED_COMPLEX_VECTORS and + spCOMPATIBILITY defines. Also: assertions are enabled by + default. + + * src/include/smpdefs.h, src/maths/sparse/spsmp.c: SMPmatrix is + now a typedef for void, instead of char. Updated all function + declarations to match this. Also added function prototypes not + previously mentioned in src/include/smpdefs.h. + + * src/include/complex.h: Updates of cast from char * to void * + + * src/analysis/cktsens.c: Matrixes cannot be created non-complex. + Also added a check to detect an error condition on delta_Y = + spCreate(...). + + +2000-06-27 Arno W. Peters + + * src/parser: Refactored commands from the frontend into the + frontend directory. Major changes to organization, but not to + functionality. + +2000-06-19 Arno W. Peters + + * src/analysis/cktask.c: moved to src/devices. + + * src/analysis/cktbindn.c: moved, renamed to + src/devices/cktbindnode.c. + + * src/analysis/cktfdev.c: moved, renamed to + src/devices/cktfinddev.c. + +2000-06-18 Arno W. Peters + + * AUTHORS, doc/ngspice.texi: Included an acknowledgements + section. + +2000-06-16 Arno W. Peters + + * src/frontend/doplot.c: Refactored into the following files: + src/frontend/com_asciiplot.c src/frontend/com_asciiplot.h + src/frontend/com_hardcopy.c src/frontend/com_hardcopy.h + src/frontend/com_plot.c src/frontend/com_plot.h + src/frontend/com_xgraph.c src/frontend/com_xgraph.h + src/frontend/plotting/plotit.c src/frontend/plotting/plotit.h + + * src/frontend/Makefile.am src/frontend/plotting/Makefile.am: + Updated to match the new files. + +2000-06-15 Arno W. Peters + + * src/frontend/graphdb.c, src/frontend/graphdb.c, + src/frontend/Makefile.am, src/frontend/plotting/graphdb.c, + src/frontend/plotting/graphdb.c, + src/frontend/plotting/Makefile.am: Moved plotting specific files + into plotting directory. + +2000-06-05 Arno W. Peters + + * tests/*: Added a little hierarchy to the tests. Removed + config.sh in favor of check.sh. This script does all checking. + Made names of the tests better reflect the circuit under test. + +2000-06-03 Arno W. Peters + + * src/include/complex.h, src/include/macros.h, + src/include/memory.h, src/maths/sparse/spdefs.h: Moved definitions + of complex into complex.h. There are three different ways to + declare a complex number in Spice. We need further work to reduce + this to only one. + + * src/maths/cmaths/Makefile.am, src/maths/cmaths/.cvsignore, + src/maths/cmaths/test_cx_ph.c: Added a new test and updated the + corresponding support files. + +2000-06-02 Arno W. Peters + + * src/circuit/inp2dot.c: Refactoring introduced a bug in the line + parsing. Passing line as an extra parameter to the refactored + functions fixes the bug. + +2000-05-30 Arno W. Peters + + * TODO: Updated. + + * src/maths/cmaths/Makefile.am, src/maths/cmaths/test_cx_mag.c, + src/maths/cmaths/test_cx_j.c: Added first testcases for complex + math library. + +2000-05-25 Arno W. Peters + + * src/circuit/inp2dot.c: First refactoring of INP2dot into smaller + functions. Still needs work. + + * src/circuit/sperror.c: Reworked, now much simpler. + + * src/include/inpdefs.h, src/include/sperror.h: Removed redundancy + in the definition of function prototypes. + +2000-05-06 Arno W. Peters + + * src/include/fte*: Broken header files into smaller pieces. This + avoids long recompile times as less needs to be rebuilt on changes + to the header files. Adjusted all callers to use the new header + files. Left a warning message in the header file to indicate its + obsolence. You will see this message when compiling. + + * src/frontend/*: Reorganized part of the frontend commands into + their own source file. Moved plotting parts into new plotting + directory. + + * src/devices/*: Removed all RCS log and rcsid from the devices + source files. They only give extra clutter and all the + information you need is available through CVS. + +2000-05-04 Arno W. Peters + + * src/maths/ni/nipzmeth.c: Corrected an overeager deletion. + +2000-05-03 Arno W. Peters + + * source tree: removed most of `#ifdef notdef' and made converted + some function calls from K&R -> ANSI. + +2000-05-01 Arno W. Peters + + * Added .cvsignore files to prevent CVS from marking generated + files as unknown. + + * src/devices/Makefile.am, src/devices/dev.c, src/devices/dev.h, + src/Makefile.am, src/ngspice.c, src/main.c: Refactored devices + initialization code into the devices dir. + + * tests/respart.cir, tests/respart.out, tests/respart.sh: + additional tests for resistor. + 1999-12-07 Arno Peters * source tree: Added MAINTAINERCLEANFILES to Makefile.am to diff --git a/DEVICES b/DEVICES index b2f85b3b8..e69de29bb 100644 --- a/DEVICES +++ b/DEVICES @@ -1,167 +0,0 @@ -DEVICES -------------------------------------------------------------------------------- - -This file contains the status of devices available in ng-spice. This file will -be updated every time the device cospecific code is altered/changed. - - - ************************************** - ********** Linear devices ********** - ************************************** - -CAP - Capacitor - Initial Release - -IND - Inductor - Initial Release - -RES - Resistor - This is a modified version of the spice3 resistance model. This model - supports different ac and dc values (ac=...). This changes are - introduced by Serban Popescu. This device needs more testing. - TO BE TESTED AND IMPROVED. - - - ************************************** - ******** Distributed elements ******** - ************************************** - -TRA - Transmission line - Initial release - -LTRA - Lossy Transmission line - Initial release - -URC - Uniform distributed RC line - Initial release - - - ************************************** - ********** V/I Sources ********** - ************************************** - - ASRC - Arbitrary Source - Initial Release - - CCCS - Current Controlled Current Source - Initial Release - - CCVS - Current Controlled Voltage Source - Initial Release - - ISRC - Independent Current Source - Initial Release - - VCCS - Voltage Controlled Current Source - Initial Release - - VCVS - Voltage Controlled Voltage Source - Initial Release - - VSRC - Indipendent Voltage Source - Initial Release - - - ************************************** - ********* Switches ********** - ************************************** - -CSW - Current controlled switch - Initial release - -SW - Voltage controlled switch - Initial release - - - ************************************** - ********** Diodes ********** - ************************************** - - DIO - Junction Diode - Initial Release - - - ************************************** - *********** Bipolar Devices ********** - ************************************** - - BJT - Bipolar Junction Transistor - Initial Relelase - - - ************************************** - ********** FET Devices ********** - ************************************** - - JFET - Junction Field Effect transistor - Initial Release - - JFET2 - Jfet PS model - Initial release. TO BE TESTED - - - ************************************** - ********* MES devices ********* - ************************************** - -MES - MESfet model - Initial release - - - ************************************** - ********* MOS devices ********* - ************************************** - - MOS1 - Level 1 MOS model - Initial Release - - MOS2 - Level 2 MOS model - Initial Release - - MOS3 - Level 3 MOS model - Initial Release - - MOS6 - Level 6 MOS model - Initial Release - - BSIM1 - BSIM model level 1 - Initial Release - - BSIM2 - BSIM model level 2 - Initial Release - - BSIM3 - BSIM model level 3 - This is the BSIM3v3.2.2 model from Berkeley device group. - You can find some test netlists with results for this model - at http://www-device.eecs.berkeley.edu/~bsim3. - - - BSIM3v1 - BSIM model level 3 - This is the BSIM3v3.1 model modified by Serban Popescu. This - is level 49 model. It is an implementation that supports - HDIF and M parameters. Test netlists are available at the URL - above. - TO BE TESTED AND IMPROVED. - - BSIM3v2 - BSIM model level 3 - This is the BSIM3v3.2 model. It is proved only for compatibility - with existing netlists and parameters files. As always, tests are - availabe on the Berkeley's device group site (at the above URL). - - BSIM4 - BSIM model level 4 (0.18 um) - Initial Release. TO BE TESTED. - - - ************************************** - ********** SOI Devices ********* - ************************************** - - -BSIM3SOI_DD - SOI model (dynamic depletion) - NOT YET IMPLEMENTED. - -BSIM3SOI_FD - SOI model (fully depleted devices) - NOT YET IMPLEMENTED. - -BSIM3SOI_PD - SOI model (partially depleted devices) - NOT YET IMPLEMENTED. diff --git a/FAQ b/FAQ index ae7a008f0..589ce6547 100644 --- a/FAQ +++ b/FAQ @@ -1,299 +1,377 @@ + Ngspice F.A.Q.Version 1.0 + Maintened by Paolo Nenzi + Last update: 05/12/2001 + + This document contains the Frequently Asked Questions (and Answers) + for ngspice project. + ______________________________________________________________________ + + Table of Contents - NG-Spice F.A.Q. - Frequently Asked Questions - (and Answers) + 1. INTRODUCTION AND GENERAL INFORMATION + 1.1 What is ngspice? + 1.2 Why resurrecting Berkeley's Spice? + 1.3 What is the project's goal? + 1.4 What you are going to do? + 1.5 Legal issues + 1.6 What mailing lists exist for ngspice? + 1.7 Are the mailing lists archived anywhere? + 1.8 What newsgroups exist for ngspice? + 1.9 Where can I get a copy of ngspice? + 1.10 Where should I look on the World Wide Web for ngspice stuff? + 1.11 Where should I look on the World Wide Web for Spice documentation? - Maintened by Daniele Foci - Last update: 29/08/1999 - - -CONTENTS - -1. INTRODUCTION AND GENERAL INFORMATION - 1.1 What is NG-Spice? - 1.2 Why resurrecting Berkeley's Spice? - 1.3 What is the project's goal? - 1.4 What you are going to do ? - 1.5 Legal issues - 1.6 What mailing lists exist for NG-Spice? - 1.7 Are the mailing lists archived anywhere? - 1.8 What newsgroups exist for NG-Spice? - 1.9 Where can I get a copy of NG-Spice? - 1.10 Where should I look on the World Wide Web for NG-Spice stuff? -2. DEVELOPMENT + 2. DEVELOPMENT 2.1 What is the current version? 2.2 What are the latest features in the current release? - 2.3 What does it look like ? - 2.4 Who are the authors of ng-spice ? + 2.3 What does it look like? + 2.4 Who are the authors of ngspice? 2.5 How can I report a bug/request for a feature? 2.6 How can I join the development? -3. SOLUTIONS TO COMMON MISCELLANEOUS PROBLEMS + + 3. SOLUTIONS TO COMMON MISCELLANEOUS PROBLEMS 3.1 What systems are supported? 3.2 I get errors when I try to compile the source code, why? - 3.3 This document didn't answer my question. Where else can I look for - an answer? -4. ADMINISTRATIVE INFORMATION AND ACKNOWLEDGEMENTS + 3.3 This document didn't answer my question. Where else can I look for an answer? + + 4. ADMINISTRATIVE INFORMATION AND ACKNOWLEDGEMENTS 4.1 Feedback 4.2 Formats in which this FAQ is available 4.3 Authorship and acknowledgements 4.4 Disclaimer and Copyright -------------------------------------------------------------------------------- -1. INTRODUCTION AND GENERAL INFORMATION + ______________________________________________________________________ -1.1 What is NG-Spice? - - NG-spice is the name of a project and of a program in the project. Spice is - the famous circuit simulator developed by the CAD Group of the University - of California at Berkeley (UCB). The NG prefix has a lot of meanings: Next - Generation, New Good, etc. Choose or invent the one you prefer. The NG-spice - project aims to improve the capabilities of the Spice3 circuit simulator. - The heart of the project is the ng-spice program, a circuit simulator - derived from spice3f5. - -1.2 Why resurrecting Berkeley's Spice? - - Berkeley's Spice can be considered the father of most circuit simulators - available today. It is an old but still good piece of software, it may not - be the fastest or the most reliable but it's free, it's available in - source code and most of the electrical simulators inherited it's syntax. - On the more technical side, spice3 uses good numerical algorithms - ( most commercial implementations have only strengthened them), implements - most of the models for MOSFET submicron designs and has a powerful set of - analyses. On the more "social" side, spice3 it's well introduced in the - academic environment. - -1.3 What is the project's goal? - - The final goal of NG-spice project is to develop a reliable, fast and - friendly circuit simulator for mixed signal/mixed level simulation. - Easy isn't it ;-). - -1.4 What you are going to do? - - The NG-spice project is divided in two main overlapping phases. The first - phase is strictly pertinent to the spice3f5 code: during this phase the - original spice3f5 code will be "cleaned" and corrected and small improvements - made to it. In phase one the Autoconf interface will replace the Berkeley's - one and this will lead to a different structure of the sources. - The second phase is the development of improvements in the ngspice code - (the old spice3f5 code cleaned and corrected) and of some programs that will - interface with it, like a schematic editor and a waveform viewer. A list of - proposed improvements follows: - - 1) The framework (or Graphic User Interface): - Spice is (and should continue to be) a command line or a text tool, but - this makes very difficult to design large circuits. To overcome this - difficulty, a schematic entry tool and a waveform viewer tools are needed. - Nevertheless, there are other tools that can be useful: a parts database, - an editor which higlights the syntax, a symbol editor, etc. - Most of these program already exists in the open source world, so they - need only to be integrated in a common EDA environment. - - 2) Documentation: - Commercial simulators have very good manuals with tutorials, models - equations explained, example of use, suggestions, etc. This line of - development has the task of providing the final spice user with an ordered - and comprehensive set of information on the program and its features. - The documentation should be useful for the student as well as for the - circuit professional. - - 3) Improvements to the Spice code: - This is the hard part. The target of this direction is to make ngspice a - commercial grade simulator. This means improving it's speed, its - numerical strenght, include the latest models available and some other - important features: - - * Numerical Algorithms: - - More stable algorithms for integration (as Runge-Kutta Methods). - - Better convergence in Operating Point Calculation replacing the - Newton-Raphson algorithm, a modified version of Fixed-Point - Homotopy. - - * Devices: - - Behavioral device: enhance the B device of spice3 to accepts IF THEN - ELSE conditions, and digital keywords like DELAY, - HIGHV, LOWV, etc. to simulate simple digital - device. - - Dynamically Loadable Devices: reduce the memory occupied by the - simulator by using shared object code - for devices. Each device is a .so - library that is inserted only if the - circuit contains an element modeled by - the device. If we are simulating CMOS, - we do not need BJT or SOI (in most of - the situations). - - Code Level Modeling: let users write their devices in C and use - them in the simulator. - - Improving device: include additional parameters to some devices as - HDIF, LDIF, etc. - - * New types of analysis, oriented to circuits syntesis and optimization: - - Network analysis: given four nodes, extract z,y,s and the other - double bipole paramters. - - Monte Carlo analysis: statistical simulation based on device - tolerances. - - Worst Case analysis: find the worst case of operation of a given - circuit based on device tolerances. - - Parametric analysis: repeat an analysis when one or more parameters - assumes different values. - - * Faster handling of sparse matrices. - - * Possibility to mesure circuit pameters, like the delay between two - nodes, etc. - - * ... whatever else can be judged useful. + 11.. IINNTTRROODDUUCCTTIIOONN AANNDD GGEENNEERRAALL IINNFFOORRMMAATTIIOONN -1.5 Legal issues - [not written yet: GPL vs. Berkeley] + 11..11.. WWhhaatt iiss nnggssppiiccee?? -1.6 What mailing lists exist for NG-Spice? + Ngspice is the name of a project and of a program in the project. + Spice is the famous circuit simulator developed by the CAD Group of + the University of California at Berkeley (UCB). The NG prefix has a + lot of meanings: Next Generation, New Good, etc. Choose or invent the + one you prefer. The ngspice project aims to improve the capabilities + of the Spice3 circuit simulator. The heart of the project is the + ngspice program, a circuit simulator derived from spice3f5. - Only one. Send an empty message to to - have information on subscription. -1.7 Is the mailing lists archived anywhere? + 11..22.. WWhhyy rreessuurrrreeccttiinngg BBeerrkkeelleeyy''ss SSppiiccee?? - Yes, the list is archived. Send an empty message to - to have information on how to retrieve - old messages. + Berkeley's Spice can be considered the father of most circuit + simulators available today. It is an old but still good piece of + software, it may not be the fastest or the most reliable but it's + free, it's available in source code and most of the electrical + simulators inherited it's syntax. On the more technical side, spice3 + uses good numerical algorithms (most commercial implementations have + only strengthened them), implements most of the models for MOSFET + submicron designs and has a powerful set of analyses. On the more + "social" side, spice3 it's well introduced in the academic + environment. -1.8 What newsgroups exist for NG-Spice? + + 11..33.. WWhhaatt iiss tthhee pprroojjeecctt''ss ggooaall?? + + + The final goal of ngspice project is to develop a reliable, fast and + friendly circuit simulator for mixed signal/mixed level simulation. + Easy isn't it? ;-). + + + 11..44.. WWhhaatt yyoouu aarree ggooiinngg ttoo ddoo?? + + + We are going to develop a circuit simulation program. The line of + development follows two parallel paths: + + 1. EEnnhhaanncceemmeennttss aanndd bbuugg--ffiixxiinngg ooff tthhee oorriiggiinnaall ssppiiccee33ff55 ccooddee.. + + 2. DDeevveellppppmmeenntt ooff aa nneeww GGPPLL''eedd ssiimmuullaattoorr.. + + The first phat will lead to a better spice3f5 and nothing more than + this, while the second one will bring us a new simulator, + compatible with its father but more expandable and presumably + faster and numerically stronger. + + There is another project in ngspice: the development of one or more + frontend to the new simulator. One of the key issues of our project is + to let users design the front end they want, using the widget set and + the language they prefer. For this reason ngspice differs a lot from + spice3f5: in ngspice there is a clear distinction between the front + end and the back end. In ngspice the front end takes care of the + interaction with the user. It is back-end's task to maintain the + object database, to exchange data with the simulator, etc. + + There are various improvements we are planning, some follows: + + 1. TThhee ffrraammeewwoorrkk ((oorr GGrraapphhiicc UUsseerr IInntteerrffaaccee)):: Spice is (and should + continue to be) a command line or a text tool, but this makes very + difficult to design large circuits. To overcome this difficulty, a + schematic entry tool and a waveform viewer tools are needed. + Nevertheless, there are other tools that can be useful: a parts + database, an editor which higlights the syntax, a symbol editor, + etc. Most of these program already exists in the open source world, + so they need only to be integrated in a common EDA environment. + + 2. DDooccuummeennttaattiioonn:: Commercial simulators have very good manuals with + tutorials, models equations explained, example of use, suggestions, + etc. This line of development has the task of providing the final + spice user with an ordered and comprehensive set of information on + the program and its features. The documentation should be useful + for the student as well as for the circuit professional. + + 3. IImmpprroovveemmeennttss ttoo tthhee SSppiiccee ccooddee:: This is the hard part. The target + of this direction is to make ngspice a commercial grade simulator. + This means improving it's speed, its numerical strenght, include + the latest models available and some other important features: + + +o Numerical Algorithms: + + +o More stable algorithms for integration (as Runge-Kutta + Methods (?) ). + + +o Better convergence in Operating Point Calculation adding a + modified version of Fixed-Point Homotopy to the Newton- + Raphson algorithm, + + +o Devices: + + +o Behavioral device: enhance the B device of spice3 to accepts + IF THEN ELSE conditions, and digital keywords like DELAY, + HIGHV, LOWV, etc. to simulate simple digital macromodels. + + +o Dynamically Loadable Devices: reduce the memory occupied by + the simulator by using shared object code for devices. Each + device is a .so library that is inserted only if the circuit + contains an element modeled by the device. If we are + simulating CMOS, we do not need BJT or SOI (in most of the + situations). + + +o Code Level Modeling: let users write their devices in C and + use them in the simulator. + + +o Improving device: include additional parameters to some + devices as HDIF, LDIF, etc. + + +o New types of analysis, oriented to circuits syntesis and + optimization: + + +o Network analysis: given four nodes, extract z,y,s and the + other double bipole paramters. + + +o Monte Carlo analysis: statistical simulation based on device + tolerances. + + +o Worst Case analysis: find the worst case of operation of a + given circuit based on device parameters tolerances. + + +o Parametric analysis: repeat an analysis when one or more + parameters assumes different values. + + +o Faster handling of sparse matrices. + + +o Possibility to mesure circuit pameters, like the delay between + two nodes, etc. + + +o Whatever else can be judged useful. + + + 11..55.. LLeeggaall iissssuueess + + The improved spice3f5 will be relased under the original Berkeley's + lincese. The new simulator will be released as GPL. Make ngspice a GPL + program, allow us to link a lot of good code laying on the net and + obviously contribute to the GPL community. + + + 11..66.. WWhhaatt mmaaiilliinngg lliissttss eexxiisstt ffoorr nnggssppiiccee?? + + There are three mailing lists dedicated to the ngspice project. Send + an empty message to the following addresses to get information on + subscription. + + + + + + + + + 11..77.. AArree tthhee mmaaiilliinngg lliissttss aarrcchhiivveedd aannyywwhheerree?? + + Yes, the list are archived. Look at the project's web site to access + archives. + + + 11..88.. WWhhaatt nneewwssggrroouuppss eexxiisstt ffoorr nnggssppiiccee?? None. Sorry. -1.9 Where can I get a copy of NG-Spice? - You can download NG-Spice from: - ftp://ieee.ing.uniroma1.it/pub/ng-spice/distribution/ + 11..99.. WWhheerree ccaann II ggeett aa ccooppyy ooff nnggssppiiccee?? -1.10 Where should I look on the World Wide Web for NG-Spice stuff? + You can download ngspice from: - There is a WWW page for NG-Spice. The URL is: - http://geda.seul.org under the tools section. + -2. DEVELOPMENT + 11..1100.. WWhheerree sshhoouulldd II llooookk oonn tthhee WWoorrlldd WWiiddee WWeebb ffoorr nnggssppiiccee ssttuuffff?? -2.1 What is the current version? + Look at the official NG-Spice Web Page + - 0.3 (released on 30/08/1999) -2.2 What are the latest features in the current release? + 11..1111.. WWhheerree sshhoouulldd II llooookk oonn tthhee WWoorrlldd WWiiddee WWeebb ffoorr SSppiiccee ddooccuummeennttaa-- + ttiioonn?? - * New features: - - Autoconf interface. - - BSIM 3.2.2 Model. - - PS jfet Model (jfet level 2). - - Temperature and resistance sweeps. - - "spec" command for spectrum analysis. + 50 Circuits analyzed with SPICE + - * Bug fixes: - - Altermod command connected to the parser. - - Some memory leaks closed. - - Spice3f5 fixes available on the net. + -2.3 What does it look like ? + + 22.. DDEEVVEELLOOPPMMEENNTT + + + + 22..11.. WWhhaatt iiss tthhee ccuurrrreenntt vveerrssiioonn?? + + rework-14 (released on 10/12/2001) + + + 22..22.. WWhhaatt aarree tthhee llaatteesstt ffeeaattuurreess iinn tthhee ccuurrrreenntt rreelleeaassee?? + + New features: + + +o New functions for vectors: vecmax (find max element in a vector), + vecmin (find minimum element in a vector), vecd (differentiate a + vector). + + +o BSIM 4 and support EKV models. + + Bug fixes: + + +o Some memory leaks closed. + + +o Error reporting more verbose + + + + 22..33.. WWhhaatt ddooeess iitt llooookk lliikkee?? This is a command line utility, no screenshots! -2.4 Who are the authors of ng-spice ? + + 22..44.. WWhhoo aarree tthhee aauutthhoorrss ooff nnggssppiiccee?? The development is open to anyone who wish to contribute. - People who contributed are: - * Daniele Foci - * Paolo Nenzi - * Arno Peters - * Serban-Mihai Popescu - * Emmanuel Rouat - * Michael Widlok - - This list is surely incomplete (due to open development group), there are - many people who contributed with improvements, pieces of code, bux fixes, - etc. If you have contributed and do not appear, write to: - ng-spice@ieee.ing.uniroma1.it + People who contributed are (in alphabetical order): + + +o Daniele Foci + + +o Paolo Nenzi + + +o Arno Peters + + +o Serban-Mihai Popescu + + +o Emmanuel Rouat + + +o Michael Widlok + + + This list is surely incomplete (due to open development group), there + are many people who contributed with improvements, pieces of code, bug + fixes, etc. If you have contributed and do not appear, write to: + + + and ask to be included. -2.5 How can I report a bug/request for a feature? - Write in the mailing list. + 22..55.. HHooww ccaann II rreeppoorrtt aa bbuugg//rreeqquueesstt ffoorr aa ffeeaattuurree?? -2.6 How can I join the development? + Look at the projects summary page: ngspice summary page - To join the development just code the feature you want to add and send your - patch in the mailing list. Before you start coding check the latest - development release of NG-Spice from our CVS. It might be that your feature - has already been implemented. - To access the anonymous CVS do the following: + 22..66.. HHooww ccaann II jjooiinn tthhee ddeevveellooppmmeenntt?? - 1) Install cvs on your machine (version 1.9.x - 1.10.x are just fine). - 2) Set one of the following environment variables: - For bash: - export CVSROOT=:pserver:anonymous@ieee.ing.uniroma1.it:/var/services/cvsroot - For csh/tcsh: - setenv CVSROOT :pserver:anonymous@ieee.ing.uniroma1.it:/var/services/cvsroot - 3) Login to the cvs server by running: - $> cvs login - The password is 'guest' (without the quotes of course). You will only - have to do this once. - 4) Checkout the appropriate files executing the following commands: - $> mkdir somedirectory - $> cd somedirectory - $> cvs co ng-spice - 5) Wait for the cvs logout. + To join the development just code the feature you want to add and send + your patch in the mailing list. Before you start coding check the + latest development release of ngspice from our CVS. It might be that + your feature has already been implemented. -3. SOLUTIONS TO COMMON MISCELLANEOUS PROBLEMS + 33.. SSOOLLUUTTIIOONNSS TTOO CCOOMMMMOONN MMIISSCCEELLLLAANNEEOOUUSS PPRROOBBLLEEMMSS -3.1 What systems are supported? + + + 33..11.. WWhhaatt ssyysstteemmss aarree ssuuppppoorrtteedd?? This is the updated list: - Hardware O.S. Compiler Functional? - ---------------- ------------------ -------------- ----------- - i386 Linux (RedHat) gcc yes - i386 Linux (Debian) gcc yes - i386 Linux (SuSE) gcc yes - IBM Risc 6000 AiX lcc no - SUN Solaris 7 gcc yes - SUN Solaris 7 SUN Workshop ? + Hardware O.S. Version Compiler Functional? + ---------------- ----------------------- -------------- ----------- + ???? HP-UX 10.10 gcc 2.95.2 yes + IBM Risc 6000 ??? lcc no + i386 Debian GNU/Linux 2.1 gcc 2.7.2 yes + i386 Red Hat Linux 5.2 gcc 2.7.2 yes + i386 SuSE Linux 6.0 gcc 2.7.2 yes + i386 Linux (SuSE) gcc yes + UltraSPARC Solaris 7 gcc yes + UltraSPARC Solaris 7 SUN Workshop ? -3.2 I get errors when I try to compile the source code, why? + + + MS-Dos, VMS and MacOS are no longer supported. + + + 33..22.. II ggeett eerrrroorrss wwhheenn II ttrryy ttoo ccoommppiillee tthhee ssoouurrccee ccooddee,, wwhhyy?? [not written yet] -3.3 This document didn't answer my question. Where else can I look for - an answer? - Read old messages from the mailing list archive, search the web site or read - the docs. Upgrade to the latest version of NG-Spice, many problems are fixed - in the new versions. If you still can't find an answer, post your question - to the mailing list. + 33..33.. TThhiiss ddooccuummeenntt ddiiddnn''tt aannsswweerr mmyy qquueessttiioonn.. WWhheerree eellssee ccaann II llooookk + ffoorr aann aannsswweerr?? + + Read old messages from the mailing list archive, search the web site + or read the docs. Upgrade to the latest version of ngspice, many + problems are fixed in the new versions. If you still can't find an + answer, post your question to the mailing list. -4. ADMINISTRATIVE INFORMATION AND ACKNOWLEDGEMENTS + 44.. AADDMMIINNIISSTTRRAATTIIVVEE IINNFFOORRMMAATTIIOONN AANNDD AACCKKNNOOWWLLEEDDGGEEMMEENNTTSS -4.1 Feedback - Send your comments about this F.A.Q. to . - Send your comments about NG-Spice to . + 44..11.. FFeeeeddbbaacckk -4.2 Formats in which this FAQ is available + Send your comments about this F.A.Q. to: - This document is available only in ASCII format in the NG-Spice source + Paolo Nenzi . + + Send your comments about ngspice to: + + Paolo Nenzi . + + + 44..22.. FFoorrmmaattss iinn wwhhiicchh tthhiiss FFAAQQ iiss aavvaaiillaabbllee + + This document is available only in ASCII format in the ngspice source package. -4.3 Authorship and acknowledgements + + 44..33.. AAuutthhoorrsshhiipp aanndd aacckknnoowwlleeddggeemmeennttss Parts of the questions and answers are originate from Paolo Nenzi. -4.4 Disclaimer and Copyright - This document is provided as is. The information in it is not warranted to - be correct: you use it at your own risk. + 44..44.. DDiissccllaaiimmeerr aanndd CCooppyyrriigghhtt + + This document is provided as is. The information in it is not + warranted to be correct: you use it at your own risk. + + + diff --git a/Makefile.am b/Makefile.am index 92d9ea14e..16f0cdd55 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ SUBDIRS = doc src man tests -EXTRA_DIST = FAQ acconfig.h autogen.sh notes contrib +EXTRA_DIST = FAQ acconfig.h autogen.sh NOTES contrib BUGS MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess \ config.h.in config.sub configure install-sh \ @@ -13,3 +13,8 @@ mrproper: maintainer-clean rm -f `find . -type f -name "*~" -print` rm -f `find . -type f -name "*.orig" -print` rm -f `find . -type f -name "*.rej" -print` + +tcl: + cd src && $(MAKE) tcl +tcl_install: + cd src && $(MAKE) tcl_install diff --git a/NEWS b/NEWS index 4ae42e4c9..9ea36931c 100644 --- a/NEWS +++ b/NEWS @@ -1,16 +1,212 @@ +Ng-spice-rework-14 +============ + +This is a major release in terms of bug-fixes. Some enhancements +have been included: BSIM4 model and support for EKV model. The +source code for the latter must be obtained from EKV web site +(see DEVICE for more info). To enable EKV support you have +to obtain the code first and then use the configure switch +"--enable-ekv". + +The spice code contains an option to debug frontend code, now +this is available in configure as "--enable-ftedebug". + + + +Ng-spice-rework-13 +============ + +This is a major release in terms of fixes and enhancements. +A garbage collector support has been added. If the configuration +script detects that you have installed GC (Bohem-Weiser conservative +garbage collector), it will use it. Some memory leaks have been +fixed too. + +Enhancements to the code comes from Alan's contribute code, a +description of improvements follows (extracted form Alan's mail): + +Output File Format Changes - + + Rawfile format changed to PSPICE Probe format (Usable with + Demo version of Microsim's Probe). + + (NOTE: Do not rely on this, we may revert to the old format + in the next release). + + Text mode .OP results even though "rawfile" written. + + Internal device nodes are not saved to "rawfile" (reduces + file size). Optionally, these internal nodes can be replaced + by device currents and saved. + + +DC Convergence Enhancements - + + "Source-Stepping" algorithm modified with a "Dynamic" step size. + After each successful step, the node voltages are saved, the + source-factor is increased by the step-factor, and the step-factor + is increased (for the next step). If the step fails, i.e. the + circuit does not converge, the source-factor is set to the value + from the previous successful step, the previously stored node + voltages are restored, the step-factor is reduced, the source + factor is increased by this smaller step-factor, and convergance + is attempted again. + + Same thing done for "Gmin-stepping" algorithm. + + "Gshunt" option added. This sets the "diagGmin" variable used in + the gmin-stepping algorithm to a non-zero value for the final + solution. (Normally this is set to zero for the final solution). + This helps for circuits with floating nodes (and for some others + too). + + The Gmin implementation across the substrate diodes of MOS1, MOS2, + MOS3, MOS6 and BSIM3 devices, and across BJT base-emitter and + base-collector diodes, was incorrect. Correcting this dramatically + improved DC convergance. (I think this also effects BSIM1 and 2 + but I haven't fixed them yet !) + + The gm, gmb and gds calculations in the MOS3 model were all wrong. + The device equations were fixed, leading to much improved + convergance. + + The Vcrit value used for diode voltage limiting was calculated + without taking into account the device area (and in some cases + without using the temperature corrected saturation current). + This could cause floating point overflows, especially in device + models designed to be scaled by a small area, e.g. 2u by 2u diodes + (area=4e-12). This is now fixed for Diode, BJT, MOS1, MOS2, and + MOS3 models. + + The diode voltage limiting was modified to add negative voltage + limiting. Negative diode voltages are now limited to 3*Vdp-10, + where Vdp is the voltage from the previous iteration. If Vdp is + positive, then the voltage is limited to -10V. This prevents some + more floating point overflows. (Actually, I'm still playing with + the best values for this). + + The Spice3 "fix" for the MOS3 gds discontinuity between the + linear and saturated regions only works if the VMAX parameter + is non-zero. A "tweak" has been added for the VMAX=0 case. + + +Transient Convergance Enhancements - + + Temperature correction of various diode capacitances was implemented + slightly incorrectly, leading to capacitance discontinuities in + simulations at temperatures other than nominal. This affected the + Diode and MOS3 models. + + A mistake in the implementation of the MOS3 source-bulk capacitance + model resulted in a charge storage discontinuity. This has been fixed. + + The level 2 MOSFET model seems to calculate Von and Vth values for + the threshold and subthreshold values respectively, but then uses + Vbin to calculate the Vdsat voltage used to find the drain current. + However, a jump statement uses Von to decide that the device is in + the "cutoff" region, which means that when this jump allows the + drain current to be calculated, Vdsat can already be well above + zero. This leads to a discontinuity of drain current with respect + to gate voltage. The code is now modified to use Vbin for the jump + decision. It looks like the code should actually use Vth as the + threshold voltage, but since PSPICE and HSPICE both follow the + original Berkeley code, this was left alone. + + +New Model Parameters - + + A PSPICE/HSPICE-like "M" device parameter (i.e. M devices in + parallel) was added to the MOS1,2,3 and BSIM3 mosfet models. + + +Input Read-in and Checking - + + Numbers beginning with a + sign got the input routine confused. + Fixed now. + + Attempts to nodeset (or .IC) non-existant nodes are flagged with a + warning. + + PWL statements on Voltage or Current sources are now checked for + "non-increasing" time-points at the start of the simulation. + Previously each time-point was checked as it was reached during + the simulation, which could be very annoying if you made a mistake + which caused the simulation to fail after hours of run-time. + + A check which was performed at the end of each sub-circuit expansion + was moved to the top level. This check makes sure that all sub-circuits + have been defined, but in its original position, it meant that if a + sub-circuit included ANY .MODEL statements at all, then ALL the models + called in that sub-circuit must also be defined within that + sub-circuit. Now SPICE behaves as expected, i.e. a subcircuit may + define its own models, but may also use models defined at any level + above. + + +Miscellaneous Fixes/Enhancements - + + MOS devices reported only half of the Meyer capacitances, and did not + include overlap capacitances, when reporting to the .OP printout, or + when storing device capacitances to the "rawfile". + + The ideal switch devices had no time-step control to stop their + controlling voltages/currents overshooting the switching thresholds. + The time-step control has been modified to use the last two time + points to estimate if the next one will move the controlling + voltage/current past a switching threshold. If this looks likely, + then the time-step is reduced. + + The "rawfile" writing routines have been modified to print the + "reference value" to the console during the simulation. This lets + the user see exactly how far and how fast the simulation is + proceeding. + + .OP printout tidied up a lot to make the printout clearer. + + Analysis order changed to fix a "feature" where, if you ask for + a .OP and a .TRAN in the same simulation, the node voltages + printed out correspond to the .OP, but the device data was from + the last timepoint of the .TRAN + + +Etc. - + + There are other minor bug fixes, and changes to reduce compiler + warnings. There are probably some more significant fixes which + I've forgotten :-) + + +Ng-spice-rework-12 +============ +Arno did a great work this summer! +The pole-zero analysis has been corrected. The error was introduced +in an attempt to eliminate compiler warnings. The source has been +reworked and info file have been updated. As you may see, a new dir +called "spicelib" has been created, another step toward the separation +of the simulator from the frontend. + +Ng-spice-rework-11 +============ + +Resistor code (device) has been modified to conform to spice3 device +coding standard. +A new step function (U2) has been introduced. +Documentation updated. + Ng-spice-rework-10 ============ -Added BSIM4 model and closed a couple of serious bugs. Added DEVICES file -to distribution. This file contains the status of device models in this -simulator. Read it, this file can save you a lot of time. +Added BSIM4 model and closed a couple of serious bugs. Added DEVICES +file to distribution. This file contains the status of device models +in this simulator. Read it, this file can save you a lot of time. Ng-spice-rework-9 ============ -Thanks to Arno Peters now all device models are dynamically loaed on demand. -Thay are linked as shared libraries. The next step is the dlopen() one which -will make possible to link devices without any recompilation. +Thanks to Arno Peters now all device models are dynamically loaed on +demand. Thay are linked as shared libraries. The next step is the +dlopen() one which will make possible to link devices without any +recompilation. @@ -74,13 +270,13 @@ Ng-spice-rework-6 (29 Jan 2000) This porting includes: -1) BSIM3V3.1 model as level 49. This is the version modified by Serban Popescu - which understands the M parameter and implements HDIF. +1) BSIM3V3.1 model as level 49. This is the version modified by Serban +Popescu which understands the M parameter and implements HDIF. 2) BSIM3V3.2 model al Level 50. This is the standard Berkeley version. -3) Now the resistor model can accepts two differents values for DC and AC - resistance. +3) Now the resistor model can accepts two differents values for DC and +AC resistance. @@ -94,11 +290,11 @@ Ng-spice-rework-4 (22/12/99) This porting includes a new feature: -1) dynamically loading of some device code as an experimental feature for - the future GPL simulator. Thanks to Arno Peters and Manu Rouat. +1) dynamically loading of some device code as an experimental feature +for the future GPL simulator. Thanks to Arno Peters and Manu Rouat. -2) Patched the following bug (thanks to Andrew Tuckey for having supplied the - patch). +2) Patched the following bug (thanks to Andrew Tuckey for having +supplied the patch). * Wsw (current controlled switch) in subckt, parsing bug. * scale factor in arbitrary source. diff --git a/README b/README index 88cf887d5..75914fc24 100644 --- a/README +++ b/README @@ -1,32 +1,32 @@ README for NGSPICE ------------------ -This long message describes what NG-SPICE may become in the (near ?) +This long message describes what NGSPICE may become in the (near ?) future. I used a question mark because, as you will read, most of the -features of ng-spice are found on Hi-quality commercial products and +features of ngspice are found on Hi-quality commercial products and (which is the true reason) I have no idea on how can be implemented. ** Why resurrecting Berkeley's Spice ? -Berkeley's spice can be considered the father of most circuit simulator +Berkeley's spice can be considered the father of most circuit simulators available today. It is an old but still good piece of software. It may not be the fastest or the most reliable, but it's free, it is available in source code, and most of the electrical simulators inherited it's syntax. On the more technical side, spice3f4(5) uses good numerical algorithms (commercial implementations have only strengthened them), implements most of the models for MOSFET submicron designs and has a powerful set of -analyses. On the more "social" side: it's weel introduced in the +analyses. On the more "social" side: it's well introduced in the academic environment. -** What does NG-SPICE mean ? +** What does NGSPICE mean ? It stands for Next Generation Spice but that's not the official name of -the projest. This projects still lacks a name. NG-SPICE is a temporary +the projest. This projects still lacks a name. NGSPICE is a temporary name. -** What will NG-SPICE be ? +** What will NGSPICE be ? Berkeley's Spice lacks in three directions: @@ -51,53 +51,56 @@ Berkeley's Spice lacks in three directions: program and it's features. The documentation should be useful for the student as well as for the circuit professional. - * Improvements to the spice code: This is the hard part. Th target of - this direction is to make ng-spice a commercial grade simulator. This + * Improvements to the spice code: This is the hard part. The target of + this direction is to make ngspice a commercial grade simulator. This means improving it's speed, it's numerical robustness, include the latest models available and some other important features. I will describe some of them briefly: - Analyses - - Network analisys: given four nodes, extract z,y,s and the other - double bipole paramters. + Network analysis: given four nodes, extract z,y,s and the other + double bipole parameters. - Monte Carlo analisys: statistical simulation based on device - tolerances. + Monte Carlo analysis: statistical simulation based on device + parameters tolerances. - Worst Case analisys: find the worst case of operation of a given - circuit based on device tolerances. + Worst Case analysis: find the worst case of operation of a given + circuit based on device parameters tolerances. - Parametric analisys: repeat an analysis when one or more parameters + Parametric analysis: repeat an analysis when one or more parameters assumes different values. - Devices - Behavioral device: enhance the B device of spice3 to accepts IF THEN ELSE conditions, and digital keywords like DELAY, HIGHV. LOWV, etc to - simulate simple digital device. + simulate simple digital circuits. Dynamically loading of device: reduce the memory occupied by the - simulator by using shared object code for devices. Each device + simulator using shared object code for devices. Each device is a .so library that is inserted only if the circuit contains an element modeled by the device. If we are simulating CMOS, we do not need BJT or SOI (in most of the situations). Code Level Modeling: Let users write their devices in C and use them in the simulator. I have discovered a couple of standars - for doing this at the Sematech ftp site. + for doing this at the Sematech ftp site. Improving device: Include additional parameters to some devices: - HDIF, LDIF, etc. (Serban, can you explain better). + HDIF, LDIF, etc. - Numerical Algs - Integration: include (if necessary) more stable algorithms for - integration. Runge-Kutta Methods ? + integration. What about Runge-Kutta Methods ? + + How if we check LKC at every node as convergence test ? Linearization: Are there better algorithms for nonlinear equations the the Newton raphson ? - Sparse Matrix - - Faster handling of sparse matrices. + Faster handling of sparse matrices: new processors offers generous + caches and vectors operations. - Options - @@ -136,25 +139,27 @@ MAILING LISTS: There are three mailing lists dedicated to the development of ngspice. -ng-spice@ieee.ing.uniroma1.it: This list is the list for the users of the - ng-spice simulator. +ngspice-users@lists.sourceforge.net: This list is the list for the users of the + ngspice simulator. -ng-spice-devel@ieee.ing.uniroma1.it: ng-spice development issues. +ngspice-devel@lists.sourceforge.net: ngspice development issues. Developers and + "want to be" developers should + subscribe here. -ng-spice-frontends@ieee.ing.uniroma1.it: issues related to development of - frontends for ng-spice. +ngspice-frontend@list.sourceforge.net: issues related to development of + frontends for ngspice. To subscribe the list(s), send a message to: - - - + + + WEB SITE: -------- -This project is hosted on the IEEE Central & South Italy Section Server. -The home page is http://ieee.ing.uniroma1.it/ngspice +This project is hosted on Sourceforge. +The home page is http://ngspice.sourceforge.net Manu (emmanuel.rouat@wanadoo.fr) Paolo (p.nenzi@ieee.org) diff --git a/acconfig.h b/acconfig.h index 48a739cf5..3d0660370 100644 --- a/acconfig.h +++ b/acconfig.h @@ -8,6 +8,9 @@ /* Define the build date */ #define NGSPICEBUILDDATE none +/* Define if we want garbage collection enabled */ +#undef HAVE_LIBGC + /* Define if we have termcap */ #undef HAVE_TERMCAP @@ -22,3 +25,24 @@ /* Define if we want some experimental code */ #undef EXPERIMENTAL_CODE + +/* Define if we want noise integration code */ +#undef INT_NOISE + +/* Undefine HAVE_EKV since it is not included in the standard distribution */ +#undef HAVE_EKV + +/* Define if we have GNU readline */ +#undef HAVE_GNUREADLINE + +/* We do not want spurios debug info into non-developer code */ +#undef FTEDEBUG + +/*The xspice enhancements*/ +#undef XSPICE + +/*Tcl Spice module*/ +#undef TCL_MODULE + +/* Spice cluster support */ +#undef CLUSTER diff --git a/autogen.sh b/autogen.sh index a816809d6..e44aa04a5 100755 --- a/autogen.sh +++ b/autogen.sh @@ -2,8 +2,8 @@ # Run this to generate all the initial makefiles, etc. PROJECT=ng-spice -TEST_TYPE=-d -FILE=src/circuit +TEST_TYPE=-f +FILE=DEVICES DIE=0 @@ -40,34 +40,10 @@ test $TEST_TYPE $FILE || { exit 1 } -if test -z "$*"; then - echo "I am going to run ./configure with no arguments - if you wish " - echo "to pass any to it, please specify them on the $0 command line." -fi -case $CC in -*lcc | *lcc\ *) am_opt=--include-deps;; -esac - -#echo "Running gettextize... Ignore non-fatal messages." -# Hmm, we specify --force here, since otherwise things don't -# get added reliably, but we don't want to overwrite intl -# while making dist. -#echo "no" | gettextize --copy --force - -echo "Running libtoolize" libtoolize --copy --force - aclocal $ACLOCAL_FLAGS - # optionally feature autoheader (autoheader --version) < /dev/null > /dev/null 2>&1 && autoheader - automake -c -a $am_opt autoconf - -./configure "$@" - -echo -echo "Now type 'make' to compile $PROJECT." - diff --git a/configure.in b/configure.in index 409b083c5..852140532 100644 --- a/configure.in +++ b/configure.in @@ -1,8 +1,16 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(src/main.c) + dnl Create a configuration header AM_CONFIG_HEADER(config.h) +dnl Initialize automake stuff +AM_INIT_AUTOMAKE(ng-spice-rework,14) + +dnl --enable-ftedebug : enable frontend debug macros +AC_ARG_ENABLE(ftedebug, + [ --enable-ftedebug Enable ngspice frontend debug]) + dnl --enable-ansi : try to force --ansi option to the compiler AC_ARG_ENABLE(ansi, [ --enable-ansi Force --ansi option for compilation]) @@ -27,13 +35,33 @@ dnl --enable-sense2 : define HAVE_SENSE2 for the code AC_ARG_ENABLE(sense2, [ --enable-sense2 Use spice2 sensitivity analysis]) +dnl --enable-intnoise : define INT_NOISE for the code +AC_ARG_ENABLE(intnoise, + [ --enable-intnoise Enables noise integration in noise analysis]) + +dnl --enable-smoketest : a smoketest +AC_ARG_ENABLE(smoketest, + [ --enable-smoketest Enables smoketest compile]) + dnl --enable-experimental : define EXPERIMENTAL_CODE for the code AC_ARG_ENABLE(experimental, [ --enable-experimental Enables some experimental code]) +dnl --enable-ekv: define HAVE_EKV in the code. This is for EKV model support +AC_ARG_ENABLE(ekv, + [ --enable-ekv Enables ekv model *not in standard distribution*]) -dnl Initialize automake stuff -AM_INIT_AUTOMAKE(ng-spice-rework,10) +dnl --enable-xspice: define XSPICE in the code. This is for xspice support +AC_ARG_ENABLE(xspice, + [ --enable-xspice Enables XSpice enchancements, experimental *not in standard distribution*]) + +dnl --enable-tcl: define TCL_MODULE in the code. This is for tcl support +AC_ARG_ENABLE(tcl, + [ --enable-tcl Compiles the tcl module instead, experimental, see README in src/tcl/README]) + +dnl --enable-cluster: define CLUSTER in the code. This is for tcl support +AC_ARG_ENABLE(cluster, + [ --enable-cluster Enables cluster support, experimental *not in standard distribution*]) dnl Enable maintainer commands only if requested AM_MAINTAINER_MODE @@ -52,6 +80,7 @@ if test "$enable_debug" = "no"; then CFLAGS=" " fi + dnl Not sure that this will work.... if test "$with_checkergcc" = "yes"; then CC="checkergcc" @@ -68,24 +97,20 @@ if test "$enable_ansi" = "yes"; then fi fi - +if test "$enable_smoketest" = "yes"; then +dnl CFLAGS="$CFLAGS -Werror" + CFLAGS="$CFLAGS -pedantic -W -Wmissing-prototypes" + CFLAGS="$CFLAGS -Wstrict-prototypes -Wtraditional" + CFLAGS="$CFLAGS -Wconversion -Wshadow -Wpointer-arith" + CFLAGS="$CFLAGS -Wcast-qual -Wcast-align -Wwrite-strings" + CFLAGS="$CFLAGS -Waggregate-return -fshort-enums -fno-common" + CFLAGS="$CFLAGS -Wnested-externs -Dinline= -g -O4" +fi dnl Chech system we're on , and tune accordingly AC_CANONICAL_HOST -case "$host" in - -*bsd* ) CFLAGS="$CFLAGS";; -*linux*) CFLAGS="$CFLAGS";; -*rs6000* ) CFLAGS="$CFLAGS";; -*sgi* ) CFLAGS="$CFLAGS";; -*sun* ) CFLAGS="$CFLAGS";; -*ultrix* ) CFLAGS="$CFLAGS";; - -esac - - dnl Checks for programs @@ -93,6 +118,99 @@ AC_LIBTOOL_DLOPEN AM_PROG_LIBTOOL + + +dnl +dnl The tclSpice options +dnl +if test "$enable_tcl" = "yes"; then + AC_DEFINE(TCL_MODULE) + with_x=no + + + AC_MSG_CHECKING([for tclConfig.sh]) + tcl_config_sh="" + if test "x$blt_with_tcl" != "x" ; then + for dir in \ + $blt_with_tcl + do + if test -r "$dir/tclConfig.sh" ; then + tcl_config_sh="$dir/tclConfig.sh" + break + elif test -r "$dir/lib/tclConfig.sh" ; then + tcl_config_sh="$dir/lib/tclConfig.sh" + break + elif test -r "$dir/unix/tclConfig.sh" ; then + tcl_config_sh="$dir/unix/tclConfig.sh" + break + fi + done +else + for dir in \ + $prefix \ + $exec_prefix + do + if test -r "$dir/tclConfig.sh" ; then + tcl_config_sh="$dir/tclConfig.sh" + break + elif test -r "$dir/lib/tclConfig.sh" ; then + tcl_config_sh="$dir/lib/tclConfig.sh" + break + elif test -r "$dir/unix/tclConfig.sh" ; then + tcl_config_sh="$dir/unix/tclConfig.sh" + break + fi + done + + + if test "x$tcl_config_sh" = "x" ; then + for dir in \ + `ls -dr /usr/local/tcl/tcl[[7-9]].[[0-9]]* 2>/dev/null` \ + /usr/local/tcl \ + /usr/local \ + /usr + do + if test -r "$dir/tclConfig.sh" ; then + tcl_config_sh="$dir/tclConfig.sh" + break + elif test -r "$dir/lib/tclConfig.sh" ; then + tcl_config_sh="$dir/lib/tclConfig.sh" + break + fi + done + fi +fi + +AC_MSG_RESULT([${tcl_config_sh}]) + +if test "x$tcl_config_sh" = "x" ; then + echo "can't find Tcl configuration script \"tclConfig.sh\"" + exit 1 +fi + +. $tcl_config_sh + +AC_MSG_CHECKING(for TCL module BLT) +rm -f conftest.tcl +cat > conftest.tcl << EOF +package require BLT; +exit; +EOF +if (wish conftest.tcl; exit) 2>/dev/null; then + AC_MSG_RESULT(Found) +else + AC_MSG_ERROR(Couldn't find BLT) +fi +rm -f conftest.tcl + +else + TCL_PACKAGE_PATH="" + TCL_BUILD_LIB_SPEC="" +fi + +AC_SUBST(TCL_PACKAGE_PATH) +AC_SUBST(TCL_BUILD_LIB_SPEC) + dnl Checks for X11 header files and libraries - X11 support can be disabled dnl by passing the '--without-x' option to configure: @@ -109,8 +227,9 @@ dnl libraries are present (error if they are not) if test ! "$no_x" = "yes" ; then X_LIBS="$X_LIBS -lX11 -lXt" AC_CHECK_LIB(Xext, XShmAttach,X_LIBS="$X_LIBS -lXext",AC_MSG_ERROR(Couldn't find Xext librairies), $X_LIBS $X_EXTRA_LIBS) - AC_CHECK_LIB(Xaw,main,X_LIBS="$X_LIBS -lXaw",AC_MSG_ERROR(Couldn't find Xaw librairies),$X_LIBS $X_EXTRA_LIBS) AC_CHECK_LIB(Xmu,main,X_LIBS="$X_LIBS -lXmu",AC_MSG_ERROR(Couldn't find Xmu librairies), $X_LIBS $X_EXTRA_LIBS) + AC_CHECK_LIB(Xaw,main,X_LIBS="$X_LIBS -lXaw",AC_MSG_ERROR(Couldn't find Xaw librairies),$X_LIBS $X_EXTRA_LIBS) + fi @@ -126,7 +245,7 @@ AC_SEARCH_LIBS(tputs,ncurses termcap,AC_DEFINE(HAVE_TERMCAP), AC_HEADER_DIRENT -AC_CHECK_HEADERS(ctype.h unistd.h pwd.h fcntl.h) +AC_CHECK_HEADERS(ctype.h unistd.h pwd.h fcntl.h string.h) AC_HEADER_SYS_WAIT AC_HEADER_STAT @@ -158,6 +277,13 @@ AC_CHECK_HEADERS(float.h limits.h values.h) dnl Check for a few mathematical functions: AC_CHECK_FUNCS(erfc logb scalb scalbn asinh acosh atanh) +AC_MSG_RESULT(Checking for the presence of the Garbage Collector:) +dnl Check for the garbage collector: +AC_CHECK_LIB(gc,GC_malloc,AC_DEFINE(HAVE_LIBGC) LIBS="$LIBS -lgc") + +dnl Check for the asprintf function: +AC_CHECK_FUNCS(asprintf) + # Expand the prefix variable (this is really annoying!) if eval "test x$prefix = xNONE"; then @@ -167,7 +293,7 @@ else fi AC_DEFINE_UNQUOTED(NGSPICEBINDIR, "`echo $dprefix/bin`" ) -AC_DEFINE_UNQUOTED(NGSPICEDATADIR, "`echo $dprefix/share/ng-spice`" ) +AC_DEFINE_UNQUOTED(NGSPICEDATADIR, "`echo $dprefix/share/ng-spice-rework`" ) AC_DEFINE_UNQUOTED(NGSPICEBUILDDATE, "`date`" ) @@ -185,11 +311,75 @@ if test "$enable_predictor" = "yes"; then AC_DEFINE(PREDICTOR) AC_MSG_RESULT(PREDICTOR algorithm enabled) fi +if test "$enable_intnoise" = "yes"; then + AC_DEFINE(INT_NOISE) + AC_MSG_RESULT(Noise integration enabled) +fi if test "$enable_experimental" = "yes"; then AC_DEFINE(EXPERIMENTAL_CODE) AC_MSG_RESULT(EXPERIMENTAL_CODE enabled) fi +if test "$enable_ftedebug" = "yes"; then + AC_DEFINE(FTEDEBUG) + AC_MSG_RESULT(WARNING: Frontend debug is enabled) +fi + + +if test "$enable_ekv" = "yes"; then + AC_MSG_RESULT(Model EKV included) + AC_DEFINE(HAVE_EKV) + EKVDIR="ekv" + EKVLIB="spicelib/devices/ekv/libekv.la" +else + EKVDIR="" + EKVLIB="" +fi +AC_SUBST(EKVDIR) +AC_SUBST(EKVLIB) + +if test "$enable_xspice" = "yes"; then + AC_MSG_RESULT(X-Spice features included) + AC_DEFINE(XSPICE) + XSPICEDIR="xspice" + XSPICELIB1="$XSPICEDIR/xspice.o \ + $XSPICEDIR/mif/libmifxsp.a \ + $XSPICEDIR/cm/libcmxsp.a" + XSPICELIB2="$XSPICEDIR/evt/libevtxsp.a \ + $XSPICEDIR/enh/libenhxsp.a \ + $XSPICEDIR/ipc/libipcxsp.a \ + $XSPICEDIR/idn/libidnxsp.a \ + -ldl" + +else + XSPCIEDIR="" + XSPICELIB1="" + XSPICELIB2="" +fi +AC_SUBST(XSPICEDIR) +AC_SUBST(XSPICELIB1) +AC_SUBST(XSPICELIB2) + +dnl Printout Tcl option +if test "$enable_tcl" = "yes"; then + AC_MSG_RESULT(Tcl module being made, use "make tcl" and "make tcl_install", read README in src/tcl/README) +fi + +dnl Cluster option +if test "$enable_cluster" = "yes"; then + AC_MSG_RESULT(Cluster version is being compiled) + AC_DEFINE(CLUSTER) + LIBS="$LIBS -lpthread" +fi + +dnl --with-readline : the user wants to use readline library +AC_ARG_WITH(readline, + [ --with-readline Use the readline package: SEE README], + AC_MSG_RESULT(Checking for readline library:) +dnl Check for the readline library: + AC_CHECK_LIB(readline,readline, AC_DEFINE(HAVE_GNUREADLINE) LIBS="$LIBS -lreadline") +) + AC_OUTPUT( \ Makefile \ @@ -197,49 +387,78 @@ doc/Makefile \ man/Makefile \ man/man1/Makefile \ src/Makefile \ -src/analysis/Makefile \ -src/circuit/Makefile \ -src/devices/Makefile \ -src/devices/asrc/Makefile \ -src/devices/bjt/Makefile \ -src/devices/bsim1/Makefile \ -src/devices/bsim2/Makefile \ -src/devices/bsim3v1/Makefile \ -src/devices/bsim3/Makefile \ -src/devices/bsim4/Makefile \ -src/devices/bsim3v2/Makefile \ -src/devices/cap/Makefile \ -src/devices/cccs/Makefile \ -src/devices/ccvs/Makefile \ -src/devices/csw/Makefile \ -src/devices/devsup/Makefile \ -src/devices/dio/Makefile \ -src/devices/disto/Makefile \ -src/devices/ind/Makefile \ -src/devices/isrc/Makefile \ -src/devices/jfet/Makefile \ -src/devices/jfet2/Makefile \ -src/devices/ltra/Makefile \ -src/devices/mes/Makefile \ -src/devices/mos1/Makefile \ -src/devices/mos2/Makefile \ -src/devices/mos3/Makefile \ -src/devices/mos6/Makefile \ -src/devices/res/Makefile \ -src/devices/sw/Makefile \ -src/devices/tra/Makefile \ -src/devices/urc/Makefile \ -src/devices/vccs/Makefile \ -src/devices/vcvs/Makefile \ -src/devices/vsrc/Makefile \ +src/spicelib/Makefile \ +src/spicelib/analysis/Makefile \ +src/spicelib/devices/Makefile \ +src/spicelib/devices/asrc/Makefile \ +src/spicelib/devices/bjt/Makefile \ +src/spicelib/devices/bjt2/Makefile \ +src/spicelib/devices/bsim1/Makefile \ +src/spicelib/devices/bsim2/Makefile \ +src/spicelib/devices/bsim3v1/Makefile \ +src/spicelib/devices/bsim3/Makefile \ +src/spicelib/devices/bsim4/Makefile \ +src/spicelib/devices/bsim3v2/Makefile \ +src/spicelib/devices/bsim3soi_pd/Makefile \ +src/spicelib/devices/bsim3soi_fd/Makefile \ +src/spicelib/devices/bsim3soi_dd/Makefile \ +src/spicelib/devices/cap/Makefile \ +src/spicelib/devices/cccs/Makefile \ +src/spicelib/devices/ccvs/Makefile \ +src/spicelib/devices/csw/Makefile \ +src/spicelib/devices/cpl/Makefile \ +src/spicelib/devices/dio/Makefile \ +src/spicelib/devices/ekv/Makefile \ +src/spicelib/devices/ind/Makefile \ +src/spicelib/devices/isrc/Makefile \ +src/spicelib/devices/hfet1/Makefile \ +src/spicelib/devices/hfet2/Makefile \ +src/spicelib/devices/jfet/Makefile \ +src/spicelib/devices/jfet2/Makefile \ +src/spicelib/devices/ltra/Makefile \ +src/spicelib/devices/mes/Makefile \ +src/spicelib/devices/mesa/Makefile \ +src/spicelib/devices/mos1/Makefile \ +src/spicelib/devices/mos2/Makefile \ +src/spicelib/devices/mos3/Makefile \ +src/spicelib/devices/mos6/Makefile \ +src/spicelib/devices/mos9/Makefile \ +src/spicelib/devices/res/Makefile \ +src/spicelib/devices/soi3/Makefile \ +src/spicelib/devices/sw/Makefile \ +src/spicelib/devices/tra/Makefile \ +src/spicelib/devices/txl/Makefile \ +src/spicelib/devices/urc/Makefile \ +src/spicelib/devices/vccs/Makefile \ +src/spicelib/devices/vcvs/Makefile \ +src/spicelib/devices/vsrc/Makefile \ +src/spicelib/parser/Makefile \ src/frontend/Makefile \ -src/hlp/Makefile \ +src/frontend/help/Makefile \ +src/frontend/parser/Makefile \ +src/frontend/plotting/Makefile \ src/include/Makefile \ src/maths/Makefile \ src/maths/cmaths/Makefile \ src/maths/ni/Makefile \ +src/maths/deriv/Makefile \ +src/maths/poly/Makefile \ src/maths/sparse/Makefile \ src/misc/Makefile \ -src/parser/Makefile \ +src/xspice/Makefile \ +src/xspice/cm/Makefile \ +src/xspice/mif/Makefile \ +src/xspice/evt/Makefile \ +src/xspice/enh/Makefile \ +src/xspice/ipc/Makefile \ +src/xspice/idn/Makefile \ tests/Makefile \ +tests/filters/Makefile \ +tests/polezero/Makefile \ +tests/resistance/Makefile \ +tests/bsim3soipd/Makefile \ +tests/bsim3soifd/Makefile \ +tests/bsim3soidd/Makefile \ +tests/bsim4/Makefile \ +tests/mesa/Makefile ) diff --git a/contrib/ChangeLog b/contrib/ChangeLog index 9ebcd5e43..f74466c7b 100644 --- a/contrib/ChangeLog +++ b/contrib/ChangeLog @@ -1,10 +1,16 @@ -2000-03-22 Paolo Nenzi +2000-10-10 Arno W. Peters + + * mslib, spiceprm: Michael Widlok released new version of his + programs. + +2000-03-22 Paolo Nenzi - * mslib: Major update. M. Widlok sent the new version of it's programs. + * mslib: Major update. M. Widlok sent the new version of it's + programs. * spiceprm: Major update. See above line. -1999-09-14 Arno +1999-09-14 Arno W. Peters * mslib: Added. diff --git a/contrib/mslib/inc_inp.c b/contrib/mslib/inc_inp.c index c8436a075..f2c540453 100644 --- a/contrib/mslib/inc_inp.c +++ b/contrib/mslib/inc_inp.c @@ -92,10 +92,11 @@ readlib(struct LSData *lib, FILE * tlib, \ { char name[BSIZE]; - int numi, wflag; + int numi, wflag, nextsub; numi = 0; wflag = NOWRITE; + nextsub = 0; while (fgets(buf, bsizer, lib->filedes)) { @@ -128,7 +129,16 @@ readlib(struct LSData *lib, FILE * tlib, \ case (SUBLLINE): if (sub) { - if (checkname(sub, name)) + if (wflag==WRITESUB) + { + /* subckt inside subckt + not so funny */ + nextsub++; + fputs(buf, tlib); + break; + } + + if (checkname(sub, name)) { wflag = WRITESUB; numi++; @@ -150,12 +160,20 @@ readlib(struct LSData *lib, FILE * tlib, \ break; case (ENDSLLINE): - if (wflag == WRITESUB) + if (nextsub) + { + nextsub--; + fputs(buf, tlib); + break; + } else { + + if (wflag == WRITESUB) { fprintf(tlib, "%s\n* End Subckt\n\n", buf); } wflag = NOWRITE; break; + } case (CONTLLINE): if (wflag != NOWRITE) diff --git a/contrib/mslib/makefile b/contrib/mslib/makefile index 186038480..63a0b3e25 100644 --- a/contrib/mslib/makefile +++ b/contrib/mslib/makefile @@ -7,6 +7,9 @@ HDRS= datadef.h SRCC= inc_main.c inc_inp.c inc_LSD.c mslib: $(OBJS) - $(CC) $(LDFLAGS) -o $@ $(OBJS) + $(CC) $(LDFLAGS) -o $@ $(OBJS) -$(OBJS): $(HDRS) \ No newline at end of file +clean: + $(RM) $(OBJS) mslib + +$(OBJS): $(HDRS) diff --git a/contrib/spiceprm/CHANGES b/contrib/spiceprm/CHANGES index 9988a99b6..e7d53da8a 100644 --- a/contrib/spiceprm/CHANGES +++ b/contrib/spiceprm/CHANGES @@ -1,3 +1,10 @@ +------------------------------- +MW. 01-10-2000 +Bugs Fixes - +----------- +.subckt inside another parametrized .subckt works right now. + + ---------------------------------------------------------------------- Version 0.11 January 2, 1996 ---------------------------------------------------------------------- diff --git a/contrib/spiceprm/spiceprm b/contrib/spiceprm/spiceprm index 71fc5b93a..c5d82253f 100755 --- a/contrib/spiceprm/spiceprm +++ b/contrib/spiceprm/spiceprm @@ -163,8 +163,9 @@ sub prm_scan { } $hasprm = 0; undef @list; $sublist = ''; + last PRM_TST; } - last PRM_TST; +# MW. 'last PRM_TST' should be inside 'if' loop to allow nestle subckts. } if ($depth) { push(@list, $_); @@ -248,7 +249,7 @@ sub prm_wr { last PRMWR_SCAN; } if (/^\.ends/) { - if (--$depth == 0) { $sublist = ''; } + if (--$depth == 0) { $sublist = ''; } else { $sublist =~ s/(\#\w+)$//; } } prm_wrline($_); diff --git a/doc/ChangeLog b/doc/ChangeLog index 718e27a8f..b79ae6101 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,15 @@ +2001-12-05 Emmanuel Rouat + + * ngspice.texi: changed (most) references of spice3 to ngspice. + +2001-12-04 Emmanuel Rouat + + * ngspice.texi: corrected a few bugs, and made some chapters readable. + +2000-05-22 Paolo Nenzi + * ngspice.texi: Added text for u2 function and for resistance ac + paramter. + 1999-09-06 Arno Peters * ngspice.texi: Added TeX equivalents for some formula. diff --git a/doc/ngspice.texi b/doc/ngspice.texi index f309c901e..1f5eed6bf 100644 --- a/doc/ngspice.texi +++ b/doc/ngspice.texi @@ -1,12 +1,12 @@ \input texinfo @c -*-texinfo-*- @c %**start of header @setfilename ngspice.info -@settitle SPICE User Manual +@settitle NGSPICE User Manual @setchapternewpage odd @c %**end of header @ifinfo -This file documents SPICE. +This file documents NGSPICE. Copyright 1996 The Regents of the University of California. @@ -40,7 +40,7 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. @c two methods of forming a title page. @titlepage -@title SPICE User Manual +@title NGSPICE User Manual @c @subtitle SUBTITLE-IF-ANY @c @subtitle SECOND-SUBTITLE @author @@ -80,7 +80,7 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. @end titlepage -@node Top, Introduction, (dir), (dir) +@node Top, Acknowledgements, (dir), (dir) @ifinfo This document describes ... @@ -90,6 +90,7 @@ of the program named ... @end ifinfo @menu +* Acknowledgements:: * Introduction:: * Circuit Description:: * Circuit Elements and Models:: @@ -106,11 +107,58 @@ of the program named ... @c @cindex Index entry for First Chapter -@node Introduction, Circuit Description, Top, Top +@node Acknowledgements, Introduction, Top, Top +@comment node-name, next, previous, up +@chapter Acknowledgements + +@c FIXME: Get this baby to work with make distcheck target. +@c +@c @include ../AUTHORS + +SPICE was originally written at The University of Berkeley (USA). +Since then, there have been many people working on the software. +The following people have contributed in some way: +Giles C. Billingsley, +Mansun Chan, +Wayne A. Christopher, +Glao S. Dezai , +Daniele Foci , +Noah Friedman , +David A. Gates, +JianHui Huang, +Jeffrey M. Hsu, +S. Hwang, +Chris Inbody , +Gordon M. Jacobs, +Min-Chie Jeng, +Kenneth H. Keller, +Mathew Lew, +Weidong Liu, +Richard D. McRoberts, +Manfred Metzger , +Paolo Nenzi , +Gary W. Ng, +Hong June Park, +Arno Peters , +Serban-Mihai Popescu , +Thomas L. Quarles, +Emmanuel Rouat , +Jaijeet S. Roychowdhury, +Takayasu Sakurai, +Kanwar Jit Singh, +Andrew Tuckey , +Michael Widlok , +and many others... + +If you feel you should be on this list, write to +. + + +@node Introduction, Circuit Description, Acknowledgements, Top @comment node-name, next, previous, up @chapter Introduction -SPICE is a general-purpose circuit simulation program for nonlinear +NGSPICE is a general-purpose circuit simulation program for nonlinear dc, nonlinear transient, and linear ac analyses. Circuits may contain resistors, capacitors, inductors, mutual inductors, independent voltage and current sources, four types of dependent sources, lossless @@ -118,12 +166,12 @@ and lossy transmission lines (two separate implementations), switches, uniform distributed RC lines, and the five most common semiconductor devices: diodes, BJTs, JFETs, MESFETs, and MOSFETs. -The SPICE3 version is based directly on SPICE 2G.6. While SPICE3 is -being developed to include new features, it continues to support those -capabilities and models which remain in extensive use in the SPICE2 -program. +NGSPICE is a continuation of SPICE3, while SPICE3 version is based +directly on SPICE 2G.6. While NGSPICE is being developed to include new +features, it continues to support those capabilities and models which +remain in extensive use in the SPICE2 program. -SPICE has built-in models for the semiconductor devices, and the user +NGSPICE has built-in models for the semiconductor devices, and the user need specify only the pertinent model parameter values. The model for the BJT is based on the integral-charge model of Gummel and Poon; however, if the Gummel- Poon parameters are not specified, the model @@ -166,7 +214,7 @@ effects, and chargecontrolled capacitances. @subsection DC Analysis -The dc analysis portion of SPICE determines the dc operating point of +The dc analysis portion of NGSPICE determines the dc operating point of the circuit with inductors shorted and capacitors opened. The dc analysis options are specified on the .DC, .TF, and .OP control lines. A dc analysis is automatically performed prior to a transient analysis @@ -185,7 +233,7 @@ each sequential source value. @subsection AC Small-Signal Analysis -The ac small-signal portion of SPICE computes the ac output variables +The ac small-signal portion of NGSPICE computes the ac output variables as a function of frequency. The program first computes the dc operating point of the circuit and determines linearized, small-signal models for all of the nonlinear devices in the circuit. The resultant @@ -201,7 +249,7 @@ input. @node Transient Analysis, Pole-Zero Analysis, AC Small-Signal Analysis, Types of Analysis @subsection Transient Analysis -The transient analysis portion of SPICE computes the transient output +The transient analysis portion of NGSPICE computes the transient output variables as a function of time over a user-specified time interval. The initial conditions are automatically determined by a dc analysis. All sources which are not time dependent (for example, power supplies) @@ -213,7 +261,7 @@ on a .TRAN control line. @subsection Pole-Zero Analysis -The pole-zero analysis portion of SPICE computes the poles and/or +The pole-zero analysis portion of NGSPICE computes the poles and/or zeros in the small-signal ac transfer function. The program first computes the dc operating point and then determines the linearized, small-signal models for all the nonlinear devices in the circuit. @@ -241,7 +289,7 @@ finds an excessive number of poles or zeros. @subsection Small-Signal Distortion Analysis -The distortion analysis portion of SPICE computes steady-state +The distortion analysis portion of NGSPICE computes steady-state harmonic and intermodulation products for small input signal magnitudes. If signals of a single frequency are specified as the input to the circuit, the complex values of the second and third @@ -264,9 +312,9 @@ calculations. @subsection Sensitivity Analysis -Spice3 will calculate either the DC operating-point sensitivity or the +Ngspice will calculate either the DC operating-point sensitivity or the AC small-signal sensitivity of an output variable with respect to all -circuit variables, including model parameters. Spice calculates the +circuit variables, including model parameters. ngspice calculates the difference in an output variable (either a node voltage or a branch current) by perturbing each parameter of each device independently. Since the method is a numerical approximation, the results may @@ -281,7 +329,7 @@ usually a very large amount of data). @subsection Noise Analysis -The noise analysis portion of SPICE does analysis device-generated +The noise analysis portion of NGSPICE does analysis device-generated noise for the given circuit. When provided with an input source and an output port, the analysis calculates the noise contributions of each device (and each noise generator within the device) to the output @@ -301,7 +349,7 @@ stationary gaussian process. @node Analysis at Different Temperatures, Convergence, Types of Analysis, Introduction @section Analysis at Different Temperatures -All input data for SPICE is assumed to have been measured at a nominal +All input data for NGSPICE is assumed to have been measured at a nominal temperature of 27°C, which can be changed by use of the TNOM parameter on the .OPTION control line. This value can further be overridden for any device which models temperature effects by @@ -314,7 +362,7 @@ through the specification of a TEMP parameter on the instance. Temperature dependent support is provided for resistors, diodes, JFETs, BJTs, and level 1, 2, and 3 MOSFETs. BSIM (levels 4 and 5) MOSFETs have an alternate temperature dependency scheme which adjusts -all of the model parameters before input to SPICE. For details of the +all of the model parameters before input to NGSPICE. For details of the BSIM temperature adjustment, see [6] and [7]. @@ -409,7 +457,7 @@ exponent, XTI, is usually 2. Temperature appears explicitly in the value of junction potential, U -(in spice PHI), for all the device models. The temperature dependence +(in ngspice PHI), for all the device models. The temperature dependence is determined by: @tex @@ -498,7 +546,7 @@ The node voltages converge to within a tolerance of 0.1% or 1 microvolt @end enumerate -Although the algorithm used in SPICE has been found to be very +Although the algorithm used in NGSPICE has been found to be very reliable, in some cases it fails to converge to a solution. When this failure occurs, the program terminates the job. @@ -526,7 +574,7 @@ desired state. @node General Structure and Conventions, Basics, Circuit Description, Circuit Description @section General Structure and Conventions -The circuit to be analyzed is described to SPICE by a set of element +The circuit to be analyzed is described to NGSPICE by a set of element lines, which define the circuit topology and element values, and a set of control lines, which define the model parameters and the run controls. The first line in the input file must be the title, and the @@ -538,7 +586,7 @@ Each element in the circuit is specified by an element line that contains the element name, the circuit nodes to which the element is connected, and the values of the parameters that determine the electrical characteristics of the element. The first letter of the -element name specifies the element type. The format for the SPICE +element name specifies the element type. The format for the NGSPICE element types is given in what follows. The strings XXXXXXX, YYYYYYY, and ZZZZZZZ denote arbitrary alphanumeric strings. For example, a resistor name must begin with the letter R and can contain one or more @@ -549,7 +597,7 @@ section. Fields on a line are separated by one or more blanks, a comma, an equal ('=') sign, or a left or right parenthesis; extra spaces are ignored. A line may be continued by entering a '+' (plus) in column 1 -of the following line; SPICE continues reading beginning with column +of the following line; NGSPICE continues reading beginning with column 2. A name field must begin with a letter (A through Z) and cannot contain @@ -569,7 +617,7 @@ floating point number followed by one of the following scale factors: @math{@code{K} = 10^3} @math{@code{mil} = 25.4^-6} @math{@code{m} = 10^-3} - @math{@code{u} = @code{M} = 10^-6} + @math{@code{u} = 10^-6} @math{@code{n} = 10^-9} @math{@code{p} = 10^-12} @math{@code{f} = 10^-15} @@ -582,7 +630,7 @@ $$ \code{K} &= 10^3 \cr \code{mil} &= 25.4^{-6} \cr \code{m} &= 10^{-3} \cr - \code{u} = \code{M} &= 10^{-6} \cr + \code{u} &= 10^{-6} \cr \code{n} &= 10^{-9} \cr \code{p} &= 10^{-12} \cr \code{f} &= 10^{-15} \cr} @@ -597,9 +645,9 @@ M, MA, MSec, and MMhos all represent the same scale factor. Note that number. Nodes names may be arbitrary character strings. The datum (ground) -node must be named '0'. Note the difference in SPICE3 where the nodes +node must be named '0'. Note the difference in NGSPICE where the nodes are treated as character strings and not evaluated as numbers, thus -'0' and '00' are distinct nodes in SPICE3 but not in SPICE2. The +'0' and '00' are distinct nodes in NGSPICE but not in SPICE2. The circuit cannot contain a loop of voltage sources and/or inductors and cannot contain a cut-set of current sources and/or capacitors. Each node in the circuit must have a dc path to ground. Every node must @@ -677,7 +725,7 @@ The "End" line must always be the last in the input The asterisk in the first column indicates that this line is a comment line. Comment lines may be placed anywhere in the circuit description. Note that - SPICE3 also considers any line with leading white space + NGSPICE also considers any line with leading white space to be a comment. @@ -703,11 +751,11 @@ The asterisk in the first column indicates that Most simple circuit elements typically require only a few parameter values. However, some devices (semiconductor devices in particular) -that are included in SPICE require many parameter values. Often, many +that are included in NGSPICE require many parameter values. Often, many devices in a circuit are defined by the same set of device model parameters. For these reasons, a set of device model parameters is defined on a separate .MODEL line and assigned a unique model name. The -device element lines in SPICE then refer to the model name. +device element lines in NGSPICE then refer to the model name. For these more complex device types, each device element line contains the device name, the nodes to which the device is connected, and the @@ -794,7 +842,7 @@ next section along with the description of device element lines. @section Subcircuits -A subcircuit that consists of SPICE elements can be defined and +A subcircuit that consists of NGSPICE elements can be defined and referenced in a fashion similar to device models. The subcircuit is defined in the input file by a grouping of element lines; the program then automatically inserts the group of elements wherever the subcircuit @@ -887,7 +935,7 @@ are being made. @end example -Subcircuits are used in SPICE by specifying pseudo-elements beginning +Subcircuits are used in NGSPICE by specifying pseudo-elements beginning with the letter X, followed by the circuit nodes to be used in expanding the subcircuit. @@ -913,10 +961,10 @@ the subcircuit. Frequently, portions of circuit descriptions will be reused in several input files, particularly with common models and subcircuits. In any -spice input file, the ".include" line may be used to copy some other +ngspice input file, the ".include" line may be used to copy some other file as if that second file appeared in place of the ".include" line in the original file. There is no restriction on the file name -imposed by spice beyond those imposed by the local operating system. +imposed by ngspice beyond those imposed by the local operating system. @node Circuit Elements and Models, Analyses and Output Control, Circuit Description, Top @@ -929,7 +977,7 @@ etc.) is optional but indicate the presence of any delimiter. Further, future implementations may require the punctuation as stated. A consistent style adhering to the punctuation shown here makes the input easier to understand. With respect to branch voltages and currents, -SPICE uniformly uses the associated reference convention (current flows +NGSPICE uniformly uses the associated reference convention (current flows in the direction of voltage drop). @@ -963,7 +1011,7 @@ in the direction of voltage drop). General form: @example - RXXXXXXX N1 N2 VALUE + RXXXXXXX N1 N2 VALUE @end example @@ -972,14 +1020,27 @@ in the direction of voltage drop). @example R1 1 2 100 RC1 12 17 1K + R2 5 7 1K ac=2K + RL 1 4 2K m=2 @end example N1 and N2 are the two element nodes. VALUE is the resistance (in ohms) -and may be positive or negative but not zero. - +and may be positive or negative but not zero. It is possible to specify +a different resistance value for ac calculations, using the "ac" +parameter. The value of ac resistance must not be zero. If you do not +specify the "ac" parameter, it will be defaulted to VALUE. +The "m" parameter is the "multiplication factor" and scale is the "scale" +factor: + Resistance = Resistance * Scale / M +Setting m to "val" is like putting m equal resistance in parallel. +The "scale" parameter let the designer to choose a different scale +for elements. +Note: ac parameter can be considered "safe" since rework-11 + Scale parameter is not applied to l,w and other geometric + parameters. @node Semiconductor Resistors, Semiconductor Resistor Model (R), Resistors, Elementary Devices @subsection Semiconductor Resistors @@ -987,7 +1048,7 @@ and may be positive or negative but not zero. General form: @example - RXXXXXXX N1 N2 + RXXXXXXX N1 N2 m= @end example @@ -1163,11 +1224,19 @@ compute the capacitance from strictly geometric information. The capacitor has a capacitance computed as +@tex +$$ + {\rm CAP} = {\rm CJ} ({\rm LENGTH} - {\rm NARROW}) + ({\rm WIDTH} - {\rm NARROW}) + + 2 {\rm CJSW} ({\rm LENGTH} + {\rm WIDTH} - 2 {\rm NARROW}) +$$ +@end tex +@ifnottex @example -CAP = CJ (LENGTH - NARROW) (WIDTH - NARROW) - + 2 CJSW (LENGTH + WIDTH - 2 NARROW) + CAP = CJ (LENGTH - NARROW) (WIDTH - NARROW) + + 2 CJSW (LENGTH + WIDTH - 2 NARROW) @end example - +@end ifnottex @node Inductors, Coupled (Mutual) Inductors, Semiconductor Capacitor Model (C), Elementary Devices @subsection Inductors @@ -1262,7 +1331,7 @@ from the positive node, through the source, to the negative node. @subsection Switch Model (SW/CSW) -The switch model allows an almost ideal switch to be described in SPICE. +The switch model allows an almost ideal switch to be described in NGSPICE. The switch is not quite ideal, in that the resistance can not change from 0 to infinity, but must always have a finite positive value. By proper selection of the on and off resistances, they can be effectively @@ -1305,7 +1374,7 @@ analysis should be decreased by using the .OPTIONS control line and specifying TRTOL to be less than the default value of 7.0. When switches are placed around capacitors, then the option CHGTOL should also be reduced. Suggested values for these two options are 1.0 and -1e-16 respectively. These changes inform SPICE3 to be more careful +1e-16 respectively. These changes inform NGSPICE to be more careful around the switch points so that no errors are made due to the rapid change in the circuit. @@ -1353,7 +1422,7 @@ flow from the positive node, through the source, to the negative node. A current source of positive value forces current to flow out of the N+ node, through the source, and into the N- node. Voltage sources, in addition to being used for circuit excitation, are the 'ammeters' for -SPICE, that is, zero valued voltage sources may be inserted into the +NGSPICE, that is, zero valued voltage sources may be inserted into the circuit for the purpose of measuring current. They of course have no effect on circuit operation since they represent short-circuits. @@ -1520,15 +1589,15 @@ The shape of the waveform is described by the following table: @example time value ----------------------------------------------------------------------------- +--------------------------------------------------------------------- 0 to TD1 V1 - | ------------| - TAU1 - | -(t - TD1) | -(t - TD2) -TD1 to TD2 V1 + (V2 - V1) 1 - e - | ----------| | ----------| - | TAU1 | | TAU2 | -TD2 to TSTOP V1 + (V2 - V1) - e + (V1 - V2) 1 - e + | -(t - TD1)| +TD1 to TD2 V1 + (V2-V1).|1-e ----------| + | TAU1 | + + | -(t - TD1)| | -(t - TD2)| +TD2 to TSTOP V1 + (V2-V1).|1-e ----------| + (V1-V2).|1-e ---------| + | TAU1 | | TAU2 | @end example @@ -1597,7 +1666,6 @@ $$ @end tex @ifnottex @example - | | V(t)=V + V sin 2 J FC t + MDI sin(2 J FS t) O A | | @@ -1612,7 +1680,7 @@ $$ @subsection Linear Dependent Sources -SPICE allows circuits to contain linear dependent sources characterized +NGSPICE allows circuits to contain linear dependent sources characterized by any of the four equations @tex @@ -1792,15 +1860,19 @@ The function "u" is the unit step function, with a value of one for arguments greater than one and a value of zero for arguments less than zero. The function "uramp" is the integral of the unit step: for an input x, the value is zero if x is less than zero, or if x is greater -than zero the value is x. These two functions are useful in sythesizing -piece-wise non-linear functions, though convergence may be adversely -affected. +than zero the value is x. The function "u2" returns a value of zero for +arguments less than zero, one for arguments greater than one and assumes +the value of the argument between these limits .These three functions are +useful in sythesizing piece-wise non-linear functions, though convergence +may be adversely affected. +Note: "u2" function has been introduced in rework-11. The following standard operators are defined: + @example -+ - * / @^{@ } unary - ++ - * / @{ @} unary - @end example @@ -2091,15 +2163,21 @@ junction capacitance equivalent to the capacitance replaced, and with a saturation current of ISPERL amps per meter of transmission line and an optional series resistance equivalent to RSPERL ohms per meter. -@multitable @columnfractions .15 .4 .2 .1 .1 -@item name @tab parameter @tab units @tab default @tab example area -@item K @tab Propagation Constant @tab - @tab 2.0 @tab 1.2 -@item FMAX @tab Maximum Frequency of interest @tab Hz @tab 1.0G @tab 6.5Meg -@item RPERL @tab Resistance per unit length @tab Z/m @tab 1000 @tab 10 -@item CPERL @tab Capacitance per unit length @tab F/m @tab 1.0e-15 @tab 1pF -@item ISPERL @tab Saturation Current per unit length @tab A/m @tab 0 -@tab - -@item RSPERL @tab Diode Resistance per unit length @tab Z/m @tab 0 @tab - - +@multitable @columnfractions .1 .45 .1 .15 .1 .1 +@item name @tab parameter + @tab units @tab default @tab example +@item K @tab Propagation Constant + @tab - @tab 2.0 @tab 1.2 +@item FMAX @tab Maximum Frequency of interest + @tab Hz @tab 1.0G @tab 6.5Meg +@item RPERL @tab Resistance per unit length + @tab Z/m @tab 1000 @tab 10 +@item CPERL @tab Capacitance per unit length + @tab F/m @tab 1.0e-15 @tab 1pF +@item ISPERL @tab Saturation Current per unit length + @tab A/m @tab 0 @tab - +@item RSPERL @tab Diode Resistance per unit length + @tab Z/m @tab 0 @tab - @end multitable @@ -2200,7 +2278,7 @@ exponential increase in the reverse diode current and is determined by the parameters BV and IBV (both of which are positive numbers). -@multitable @columnfractions .1 .4 .2 .1 .1 .1 +@multitable @columnfractions .1 .45 .15 .15 .15 .1 @item name @tab parameter @tab units @tab default @tab example @tab area @item IS @tab saturation current @tab A @tab 1.0e-14 @tab 1.0e-14 @tab * @item RS @tab ohmic resistance @tab Z @tab 0 @tab 10 @tab * @@ -2220,7 +2298,6 @@ the parameters BV and IBV (both of which are positive numbers). @tab - @tab 0.5 @tab depletion capacitance formula @item BV @tab reverse breakdown voltage @tab V @tab infinite @tab 40.0 @item IBV @tab current at breakdown voltage @tab A @tab 1.0e-3 - @tab o @item TNOM @tab parameter measurement temperature @tab C @tab 27 @tab 50 @end multitable @@ -2267,7 +2344,7 @@ specification on the .OPTION control line. @subsection BJT Models (NPN/PNP) -The bipolar junction transistor model in SPICE is an adaptation of the +The bipolar junction transistor model in NGSPICE is an adaptation of the integral charge control model of Gummel and Poon. This modified Gummel-Poon model extends the original model to include several effects at high bias levels. The model automatically simplifies to the simpler @@ -2302,7 +2379,7 @@ accepted. Modified Gummel-Poon BJT Parameters. -@multitable @columnfractions .1 .4 .2 .1 .1 .1 +@multitable @columnfractions .1 .45 .15 .15 .15 .1 @item name @tab parameter @tab units @tab default @tab example @tab area @item IS @tab transport saturation current @tab A @tab 1.0e-16 @tab 1.0e-15 @tab * @@ -2359,7 +2436,7 @@ internal base node @tab - @tab 1 @item AF @tab flicker-noise exponent @tab - @tab 1 @item FC @tab coefficient for forward-bias depletion capacitance formula @tab - @tab 0.5 @tab o -@item TNOM @tab Parameter measurement temperature @tab C @tab 27 @tab 50 +@item TNOM @tab Parameter measurement temperature @tab °C @tab 27 @tab 50 @end multitable @@ -2413,7 +2490,7 @@ junction voltage and are defined by the parameters CGS, CGD, and PB. Note that in Spice3f and later, a fitting parameter B has been added. For details, see [9]. -@multitable @columnfractions .1 .4 .1 .1 .1 .1 +@multitable @columnfractions .1 .45 .15 .15 .15 .1 @item name @tab parameter @tab units @tab default @tab example @tab area @item VTO @tab threshold voltage (@math{V_T0}) @tab V @tab -2.0 @tab -2.0 @item BETA @tab transconductance parameter (B) @@ -2493,7 +2570,7 @@ level 4 or 5 (BSIM) devices. @subsection MOSFET Models (NMOS/PMOS) -SPICE provides four MOSFET device models, which differ in the +NGSPICE provides four MOSFET device models, which differ in the formulation of the I-V characteristic. The variable LEVEL specifies the model to be used: @@ -2527,7 +2604,7 @@ MOS6 (as described in [2]) The dc characteristics of the level 1 through level 3 MOSFETs are defined by the device parameters VTO, KP, LAMBDA, PHI and GAMMA. These -parameters are computed by SPICE if process parameters (NSUB, TOX, ...) +parameters are computed by NGSPICE if process parameters (NSUB, TOX, ...) are given, but userspecified values always override. VTO is positive (negative) for enhancement mode and negative (positive) for depletion mode N-channel (P-channel) devices. Charge storage is modeled by three @@ -2562,91 +2639,105 @@ parameter has been detected (see [10]). The supplied fix has been implemented in Spice3f2 and later. Since this fix may affect parameter fitting, the option "BADMOS3" may be set to use the old implementation (see the section on simulation variables and the ".OPTIONS" line). -SPICE level 1, 2, 3 and 6 parameters: +NGSPICE level 1, 2, 3 and 6 parameters: -@example -name parameter units default example - - 1 LEVEL model index - 1 - 2 VTO zero-bias threshold voltage (V ) V 0.0 1.0 - TO 2 - 3 KP transconductance parameter A/V 2.0e-5 3.1e-5 - 1/2 - 4 GAMMA bulk threshold parameter (\) V 0.0 0.37 - 5 PHI surface potential (U) V 0.6 0.65 - 6 LAMBDA channel-length modulation - (MOS1 and MOS2 only) (L) 1/V 0.0 0.02 - 7 RD drain ohmic resistance Z 0.0 1.0 - 8 RS source ohmic resistance Z 0.0 1.0 - 9 CBD zero-bias B-D junction capacitance F 0.0 20fF - 10 CBS zero-bias B-S junction capacitance F 0.0 20fF - 11 IS bulk junction saturation current (I ) A 1.0e-14 1.0e-15 - S - 12 PB bulk junction potential V 0.8 0.87 - 13 CGSO gate-source overlap capacitance - per meter channel width F/m 0.0 4.0e-11 - 14 CGDO gate-drain overlap capacitance - per meter channel width F/m 0.0 4.0e-11 - 15 CGBO gate-bulk overlap capacitance - per meter channel length F/m 0.0 2.0e-10 - 16 RSH drain and source diffusion - sheet resistance Z/[] 0.0 10.0 - 17 CJ zero-bias bulk junction bottom cap. - 2 - per sq-meter of junction area F/m 0.0 2.0e-4 - 18 MJ bulk junction bottom grading coeff. - 0.5 0.5 - 19 CJSW zero-bias bulk junction sidewall cap. - per meter of junction perimeter F/m 0.0 1.0e-9 - 20 MJSW bulk junction sidewall grading coeff. - 0.50(level1) - 0.33(level2, 3) - 21 JS bulk junction saturation current - 2 - per sq-meter of junction area A/m 1.0e-8 - 22 TOX oxide thickness meter 1.0e-7 1.0e-7 - 3 - 23 NSUB substrate doping 1/cm 0.0 4.0e15 - 2 - 24 NSS surface state density 1/cm 0.0 1.0e10 - 2 - 25 NFS fast surface state density 1/cm 0.0 1.0e10 - - 26 TPG type of gate material: - 1.0 - +1 opp. to substrate - -1 same as substrate - 0 Al gate - 27 XJ metallurgical junction depth meter 0.0 1M - 28 LD lateral diffusion meter 0.0 0.8M - 2 - 29 UO surface mobility cm /Vs 600 700 - 30 UCRIT critical field for mobility - degradation (MOS2 only) V/cm 1.0e4 1.0e4 - 31 UEXP critical field exponent in - mobility degradation (MOS2 only) - 0.0 0.1 - 32 UTRA transverse field coeff. (mobility) - (deleted for MOS2) - 0.0 0.3 - 33 VMAX maximum drift velocity of carriers m/s 0.0 5.0e4 - 34 NEFF total channel-charge (fixed and - mobile) coefficient (MOS2 only) - 1.0 5.0 - 35 KF flicker noise coefficient - 0.0 1.0e-26 - 36 AF flicker noise exponent - 1.0 1.2 - 37 FC coefficient for forward-bias - depletion capacitance formula - 0.5 - 38 DELTA width effect on threshold voltage - (MOS2 and MOS3) - 0.0 1.0 - 39 THETA mobility modulation (MOS3 only) 1/V 0.0 0.1 - 40 ETA static feedback (MOS3 only) - 0.0 1.0 - 41 KAPPA saturation field factor (MOS3 only) - 0.2 0.5 - o - 42 TNOM parameter measurement temperature C 27 50 -@end example +@multitable @columnfractions .1 .45 .15 .15 .15 +@item name @tab parameter + @tab units @tab default @tab example +@item LEVEL @tab model index + @tab - @tab 1 +@item VTO @tab zero-bias threshold voltage (@math{V_T0}) + @tab V @tab 0.0 @tab 1.0 +@item KP @tab transconductance parameter + @tab @math{A/V^2} @tab 2.0e-5 @tab 3.1e-5 +@item GAMMA @tab bulk threshold parameter + @tab @math{V^1/2} @tab 0.0 @tab 0.37 +@item PHI @tab surface potential (U) + @tab V @tab 0.6 @tab 0.65 +@item LAMBDA @tab channel-length modulation (MOS1 and MOS2 only) (L) + @tab 1/V @tab 0.0 @tab 0.02 +@item RD @tab drain ohmic resistance + @tab Z @tab 0.0 @tab 1.0 +@item RS @tab source ohmic resistance + @tab Z @tab 0.0 @tab 1.0 +@item CBD @tab zero-bias B-D junction capacitance + @tab F @tab 0.0 @tab 20fF +@item CBS @tab zero-bias B-S junction capacitance + @tab F @tab 0.0 @tab 20fF +@item IS @tab bulk junction saturation current (@math{I_S}) + @tab A @tab 1.0e-14 @tab 1.0e-15 +@item PB @tab bulk junction potential + @tab V @tab 0.8 @tab 0.87 +@item CGSO @tab gate-source overlap capacitance per meter channel width + @tab F/m @tab 0.0 @tab 4.0e-11 +@item CGDO @tab gate-drain overlap capacitance per meter channel width + @tab F/m @tab 0.0 @tab 4.0e-11 +@item CGBO @tab gate-bulk overlap capacitance per meter channel length + @tab F/m @tab 0.0 @tab 2.0e-10 +@item RSH @tab drain and source diffusion sheet resistance + @tab Z/[] @tab 0.0 @tab 10.0 +@item CJ @tab zero-bias bulk junction bottom cap. per sq-meter of junction area + @tab @math{F/m^2} @tab 0.0 @tab 2.0e-4 +@item MJ @tab bulk junction bottom grading coeff. + @tab - @tab 0.5 @tab 0.5 +@item CJSW @tab zero-bias bulk junction sidewall cap. per meter of junction perimeter + @tab F/m @tab 0.0 @tab 1.0e-9 +@item MJSW @tab bulk junction sidewall grading coeff. + @tab - @tab 0.50(level1), 0.33(level2, 3) +@item JS @tab bulk junction saturation current per sq-meter of junction area + @tab @math{A/m^2} @tab 1.0e-8 +@item TOX @tab oxide thickness + @tab meter @tab 1.0e-7 @tab 1.0e-7 +@item NSUB @tab substrate doping + @tab @math{1/cm^3} @tab 0.0 @tab 4.0e15 +@item NSS @tab surface state density + @tab @math{1/cm^2} @tab 0.0 @tab 1.0e10 +@item NFS @tab fast surface state density + @tab @math{1/cm^2} @tab 0.0 @tab 1.0e10 +@item TPG @tab type of gate material: + +1 opp. to substrate, -1 same as substrate, 0 Al gate + @tab - @tab 1.0 +@item XJ @tab metallurgical junction depth + @tab meter @tab 0.0 @tab 1M +@item LD @tab lateral diffusion + @tab meter @tab 0.0 @tab 0.8M +@item UO @tab surface mobility + @tab @math{cm^2/Vs} @tab 600 @tab 700 +@item UCRIT @tab critical field for mobility degradation (MOS2 only) + @tab V/cm @tab 1.0e4 @tab 1.0e4 +@item UEXP @tab critical field exponent in mobility degradation (MOS2 only) + @tab - @tab 0.0 @tab 0.1 +@item UTRA @tab transverse field coeff. (mobility) (deleted for MOS2) + @tab - @tab 0.0 @tab 0.3 +@item VMAX @tab maximum drift velocity of carriers + @tab m/s @tab 0.0 @tab 5.0e4 +@item NEFF @tab total channel-charge (fixed and mobile) coefficient (MOS2 only) + @tab - @tab 1.0 @tab 5.0 +@item KF @tab flicker noise coefficient + @tab - @tab 0.0 @tab 1.0e-26 +@item AF @tab flicker noise exponent + @tab - @tab 1.0 @tab 1.2 +@item FC @tab coefficient for forward-bias depletion capacitance formula + @tab - @tab 0.5 +@item DELTA @tab width effect on threshold voltage (MOS2 and MOS3) + @tab - @tab 0.0 @tab 1.0 +@item THETA @tab mobility modulation (MOS3 only) + @tab 1/V @tab 0.0 @tab 0.1 +@item ETA @tab static feedback (MOS3 only) + @tab - @tab 0.0 @tab 1.0 +@item KAPPA @tab saturation field factor (MOS3 only) + @tab - @tab 0.2 @tab 0.5 +@item TNOM @tab parameter measurement temperature + @tab °C @tab 27 @tab 50 +@end multitable The level 4 and level 5 (BSIM1 and BSIM2) parameters are all values obtained from process characterization, and can be generated automatically. J. Pierret [4] describes a means of generating a -'process' file, and the program Proc2Mod provided with SPICE3 converts +'process' file, and the program Proc2Mod provided with NGSPICE converts this file into a sequence of BSIM1 ".MODEL" lines suitable for inclusion -in a SPICE input file. Parameters marked below with an * in the l/w +in a NGSPICE input file. Parameters marked below with an * in the l/w column also have corresponding parameters with a length and width dependency. For example, VFB is the basic parameter with units of Volts, and LVFB and WVFB also exist and have units of Volt-Mmeter The @@ -2699,7 +2790,7 @@ $$ -Note that unlike the other models in SPICE, the BSIM model is designed +Note that unlike the other models in NGSPICE, the BSIM model is designed for use with a process characterization system that provides all the parameters, thus there are no defaults for the parameters, and leaving one out is considered an error. For an example set of parameters and @@ -2707,7 +2798,7 @@ the format of a process file, see the SPICE2 implementation notes[3]. For more information on BSIM2, see reference [5]. - SPICE BSIM (level 4) parameters. + NGSPICE BSIM (level 4) parameters. @example name parameter units l/w @@ -2886,8 +2977,8 @@ batch mode, the analyses specified by the control lines in the input file (e.g. ".ac", ".tran", etc.) are immediately executed (unless ".control" lines exists; see the section on the interactive command interpretor). If the -r rawfile option is given then all data generated -is written to a Spice3 rawfile. The rawfile may be read by either the -interactive mode of Spice3 or by nutmeg; see the previous section for +is written to a Ngspice rawfile. The rawfile may be read by either the +interactive mode of Ngspice or by nutmeg; see the previous section for details. In this case, the .SAVE line (see below) may be used to record the value of internal device variables (see Appendix B). @@ -2910,7 +3001,7 @@ meant for compatibility with Spice2. @section Simulator Variables (.OPTIONS) -Various parameters of the simulations available in Spice3 can be altered +Various parameters of the simulations available in Ngspice can be altered to control the accuracy, speed, or default values for some devices. These parameters may be changed via the "set" command (described later in the section on the interactive front-end) or via the ".OPTIONS" line: @@ -2933,7 +3024,7 @@ The options line allows the user to reset program control and user options for specific simulation purposes. Additional options for Nutmeg may be specified as well and take effect when Nutmeg reads the input file. Options specified to Nutmeg via the 'set' command are also passed -on to SPICE3 as if specified on a .OPTIONS line. See the following +on to NGSPICE as if specified on a .OPTIONS line. See the following section on the interactive command interpreter for the parameters which may be set with a .OPTIONS line and the format of the 'set' command. Any combination of the following options may be included, in any order. @@ -2988,7 +3079,7 @@ resets the dc transfer curve iteration limit. The default is 50. @item ITL3=x resets the lower transient analysis iteration limit. the default value -is 4. (Note: not implemented in Spice3). +is 4. (Note: not implemented in Ngspice). @item ITL4=x @@ -2998,7 +3089,7 @@ resets the transient analysis timepoint iteration limit. the default is @item ITL5=x resets the transient analysis total iteration limit. the default is -5000. Set ITL5=0 to omit this test. (Note: not implemented in Spice3). +5000. Set ITL5=0 to omit this test. (Note: not implemented in Ngspice). @item KEEPOPINFO @@ -3008,7 +3099,7 @@ is large and you do not want to run a (redundant) ".OP" analysis. @item METHOD=name -sets the numerical integration method used by SPICE. Possible names are +sets the numerical integration method used by NGSPICE. Possible names are "Gear" or "trapezoidal" (or just "trap"). The default is trapezoidal. @item PIVREL=x @@ -3044,7 +3135,7 @@ specification on any temperature dependent device model. @item TRTOL=x resets the transient error tolerance. The default value is 7.0. This -parameter is an estimate of the factor by which SPICE overestimates the +parameter is an estimate of the factor by which NGSPICE overestimates the actual truncation error. @item TRYTOCOMPACT @@ -3176,7 +3267,7 @@ dc bias (initial transient) solution is computed before the transient analysis. In this case, the node voltages specified on the .IC control line is forced to the desired initial values during the bias solution. During transient analysis, the constraint on these node voltages is -removed. This is the preferred method since it allows SPICE to compute +removed. This is the preferred method since it allows NGSPICE to compute a consistent dc solution. @end enumerate @@ -3226,7 +3317,7 @@ DEC stands for decade variation, and ND is the number of points per decade. OCT stands for octave variation, and NO is the number of points per octave. LIN stands for linear variation, and NP is the number of points. FSTART is the starting frequency, and FSTOP is the final -frequency. If this line is included in the input file, SPICE performs +frequency. If this line is included in the input file, NGSPICE performs an AC analysis of the circuit over the specified frequency range. Note that in order for this analysis to be meaningful, at least one independent source must have been specified with an ac value. @@ -3432,7 +3523,7 @@ A@math{^2} for integrated noise). @end example -The inclusion of this line in an input file directs SPICE to determine +The inclusion of this line in an input file directs NGSPICE to determine the dc operating point of the circuit with inductors shorted and capacitors opened. Note: a DC analysis is automatically performed prior to a transient analysis to determine the transient initial conditions, @@ -3542,10 +3633,10 @@ or per percent change of input). The TF line defines the small-signal output and input for the dc small-signal analysis. OUTVAR is the smallsignal output variable and -INSRC is the small-signal input source. If this line is included, SPICE +INSRC is the small-signal input source. If this line is included, NGSPICE computes the dc small-signal value of the transfer function (output/input), input resistance, and output resistance. For the first -example, SPICE would compute the ratio of V(5, 3) to VIN, the +example, NGSPICE would compute the ratio of V(5, 3) to VIN, the small-signal input resistance at VIN, and the smallsignal output resistance measured across nodes 5 and 3. @@ -3579,15 +3670,15 @@ omitted, it is assumed to be zero. The transient analysis always begins at time zero. In the interval , the circuit is analyzed (to reach a steady state), but no outputs are stored. In the interval , the circuit is analyzed and outputs are stored. TMAX -is the maximum stepsize that SPICE uses; for default, the program +is the maximum stepsize that NGSPICE uses; for default, the program chooses either TSTEP or (TSTOP-TSTART)/50.0, whichever is smaller. TMAX is useful when one wishes to guarantee a computing interval which is smaller than the printer increment, TSTEP. UIC (use initial conditions) is an optional keyword which indicates that -the user does not want SPICE to solve for the quiescent operating point +the user does not want NGSPICE to solve for the quiescent operating point before beginning the transient analysis. If this keyword is specified, -SPICE uses the values specified using IC=... on the various elements as +NGSPICE uses the values specified using IC=... on the various elements as the initial transient condition and proceeds with the analysis. If the .IC control line has been specified, then the node voltages on the .IC line are used to compute the initial conditions for the devices. Look @@ -3626,8 +3717,8 @@ UIC is not specified. The vectors listed on the .SAVE line are recorded in the rawfile for use -later with spice3 or nutmeg (nutmeg is just the data-analysis half of -spice3, without the ability to simulate). The standard vector names are +later with ngspice or nutmeg (nutmeg is just the data-analysis half of +ngspice, without the ability to simulate). The standard vector names are accepted. If no .SAVE line is given, then the default set of vectors are saved (node voltages and voltage source branch currents). If .SAVE lines are given, only those vectors specified are saved. For more @@ -3662,7 +3753,7 @@ NOISE, or DISTO) for which the specified outputs are desired. The form for voltage or current output variables is the same as given in the previous section for the print command; Spice2 restricts the output variable to the following forms (though this restriction is not enforced -by Spice3): +by Ngspice): @table @code @@ -3757,7 +3848,7 @@ There is no limit on the number of .PLOT lines specified for each type of anal @end example -The Four (or Fourier) line controls whether SPICE performs a Fourier +The Four (or Fourier) line controls whether NGSPICE performs a Fourier analysis as a part of the transient analysis. FREQ is the fundamental frequency, and OV1, desired. The Fourier analysis is performed over the interval , where TSTOP is the final time specified @@ -3771,33 +3862,33 @@ set to period/100.0 (or less for very high-Q circuits). @node Interactive Interpreter, Bibliography, Analyses and Output Control, Top @chapter Interactive Interpreter -Spice3 consists of a simulator and a front-end for data analysis and +Ngspice consists of a simulator and a front-end for data analysis and plotting. The front-end may be run as a separate "stand-alone" program under the name Nutmeg. -Nutmeg will read in the "raw" data output file created by spice -r or -with the write command in an interactive Spice3 session. Nutmeg or -interactive Spice3 can plot data from a simulation on a graphics +Nutmeg will read in the "raw" data output file created by ngspice -r or +with the write command in an interactive Ngspice session. Nutmeg or +interactive Ngspice can plot data from a simulation on a graphics terminal or a workstation display. Most of the commands available in -the interactive Spice3 front end are available in nutmeg; where this is -not the case, Spice-only commands have been marked with an asterisk +the interactive Ngspice front end are available in nutmeg; where this is +not the case, ngspice-only commands have been marked with an asterisk ("*"). Note that the raw output file is different from the data that Spice2 writes to the standard output, which may also be produced by -spice3 with the "-b" command line option. +ngspice with the "-b" command line option. -Spice and Nutmeg use the X Window System for plotting if they find the +Ngspice and Nutmeg use the X Window System for plotting if they find the environment variable DISPLAY. Otherwise, a graphics-terminal independent interface (MFB) is used. If you are using X on a workstation, the DISPLAY variable should already be set; if you want to display graphics on a system different from the one you are running -Spice3 or Nutmeg on, DISPLAY should be of the form "machine:0.0". See +Ngspice or Nutmeg on, DISPLAY should be of the form "machine:0.0". See the appropriate documentation on the X Window Sytem for more details. Command Synopsis @example - spice [ -n ] [ -t term ] [ -r rawfile] [ -b ] [ -i ] [ input file ... ] + ngspice [ -n ] [ -t term ] [ -r rawfile] [ -b ] [ -i ] [ input file ... ] nutmeg [ - ] [ -n ] [ -t term ] [ datafile ... ] @end example @@ -3815,7 +3906,7 @@ files are given. Nutmeg only. @item -n (or -N) -Don't try to source the file ".spiceinit" upon startup. Normally spice +Don't try to source the file ".spiceinit" upon startup. Normally ngspice and nutmeg try to find the file in the current directory, and if it is not found then in the user's home directory. @@ -3825,44 +3916,44 @@ The program is being run on a terminal with mfb name term. @item -b (or -B) -Run in batch mode. Spice3 reads the default input source (e.g. +Run in batch mode. Ngspice reads the default input source (e.g. keyboard) or reads the given input file and performs the analyses specified; output is either Spice2-like line-printer plots ("ascii -plots") or a spice rawfile. See the following section for details. +plots") or a ngspice rawfile. See the following section for details. Note that if the input source is not a terminal (e.g. using the IO -redirection notation of "<") Spice3 defaults to batch mode (-i -overrides). This option is valid for Spice3 only. +redirection notation of "<") Ngspice defaults to batch mode (-i +overrides). This option is valid for Ngspice only. @item -s (or -S) Run in server mode. This is like batch mode, except that a temporary rawfile is used and then written to the standard output, preceded by a line with a single "@@", after the simulation is done. This mode is used -by the spice daemon. This option is valid for Spice3 only. +by the ngspice daemon. This option is valid for Ngspice only. @item -i (or -I) Run in interactive mode. This is useful if the standard input is not a terminal but interactive mode is desired. Command completion is not available unless the standard input is a terminal, however. This option -is valid for Spice3 only. +is valid for Ngspice only. @item -r rawfile (or -P rawfile) Use rawfile as the default file into which the results of the simulation -are saved. This option is valid for Spice3 only. +are saved. This option is valid for Ngspice only. @end table -Further arguments to spice are taken to be Spice3 input files, which are +Further arguments to ngspice are taken to be Ngspice input files, which are read and saved (if running in batch mode then they are run immediately). -Spice3 accepts most Spice2 input file, and output ascii plots, fourier +Ngspice accepts most Spice2 input file, and output ascii plots, fourier analyses, and node printouts as specified in .plot, .four, and .print cards. If an out parameter is given on a .width card, the effect is the -same as set width = .... Since Spice3 ascii plots do not use multiple +same as set width = .... Since Ngspice ascii plots do not use multiple ranges, however, if vectors together on a .plot card have different ranges they are not provide as much information as they would in Spice2. -The output of Spice3 is also much less verbose than Spice2, in that the +The output of Ngspice is also much less verbose than Spice2, in that the only data printed is that requested by the above cards. For nutmeg, further arguments are taken to be data files in binary or @@ -3883,7 +3974,7 @@ may contain any number of data sets from different analyses. @node Expressions, Command Interpretation, Interactive Interpreter, Interactive Interpreter @section Expressions, Functions, and Constants -Spice and Nutmeg data is in the form of vectors: time, voltage, etc. +Ngspice and Nutmeg data is in the form of vectors: time, voltage, etc. Each vector has a type, and vectors can be operated on and combined algebraicly in ways consistent with their types. Vectors are normally created when a data file is read in (see the load command below), and @@ -4034,9 +4125,9 @@ componant of that vector's scale. A vector may be either the name of a vector already defined or a floating-point number (a scalar). A number may be written in any format -acceptable to SPICE, such as 14.6Meg or -1.231e-4. Note that you can +acceptable to NGSPICE, such as 14.6Meg or -1.231e-4. Note that you can either use scientific notation or one of the abbreviations like MEG or -G, but not both. As with SPICE, a number may have trailing alphabetic +G, but not both. As with NGSPICE, a number may have trailing alphabetic characters after it. The notation expr [num] denotes the num'th element of expr. For @@ -4064,7 +4155,7 @@ for instance. Thus some (contrived) examples of expressions are: @end example -Vector names in spice may have a name such as @@name[param], where name +Vector names in ngspice may have a name such as @@name[param], where name is either the name of a device instance or model. This denotes the value of the param parameter of the device or model. See Appendix B for details of what parameters are available. The value is a vector of @@ -4135,9 +4226,9 @@ another, it must save its argv and argc since they are altered. Also, command files may not be re-entrant since there are no local variables. (Of course, the procedures may explicitly manipulate a stack...) This way one can write scripts analogous to shell scripts for nutmeg and -Spice3. +Ngspice. -Note that for the script to work with Spice3, it must begin with a blank +Note that for the script to work with Ngspice, it must begin with a blank line (or whatever else, since it is thrown away) and then a line with .control on it. This is an unfortunate result of the source command being used for both circuit input and command file execution. Note also @@ -4304,7 +4395,7 @@ because asciiplot uses a simple-minded linear interpolation. @node Aspice, Bug, Asciiplot, Commands -@subsection Aspice: Asynchronous spice run +@subsection Aspice: Asynchronous ngspice run General Form: @@ -4313,7 +4404,7 @@ because asciiplot uses a simple-minded linear interpolation. @end example -Start a SPICE-3 run, and when it is finished load the resulting data. +Start a NGSPICE run, and when it is finished load the resulting data. The raw data is kept in a temporary file. If output-file is specified then the diagnostic output is directed into that file, otherwise it is thrown away. @@ -4332,7 +4423,7 @@ thrown away. Send a bug report. Please include a short summary of the problem, the version number and name of the operating system that you are running, -the version of Spice that you are running, and the relevant spice input +the version of ngspice that you are running, and the relevant ngspice input file. (If you have defined BUGADDR, the mail is delivered to there.) @@ -4491,7 +4582,7 @@ Echos the given text to the screen. @end example -Print the current Spice3 input file into a file, call up the editor on +Print the current Ngspice input file into a file, call up the editor on that file and allow the user to modify it, and then read it back in, replacing the original file. If a filename is given, then edit that file and load it, making the circuit the current one. @@ -4511,7 +4602,7 @@ file and load it, making the circuit the current one. Does a fourier analysis of each of the given values, using the first 10 multiples of the fundamental frequency (or the first nfreqs, if that variable is set - see below). The output is like that of the .four -Spice3 line. The values may be any valid expression. The values are +Ngspice line. The values may be any valid expression. The values are interpolated onto a fixed-space grid with the number of points given by the fourgridsize variable, or 200 if it is not set. The interpolation is of degree polydegree if that variable is set, or 1. If polydegree is @@ -4537,7 +4628,7 @@ plot(1) program or lpr with the -g flag. @node Help, History, Hardcopy, Commands -@subsection Help: Print summaries of Spice3 commands +@subsection Help: Print summaries of Ngspice commands General Form: @@ -4564,7 +4655,7 @@ few major commands is printed. Print out the history, or the last number commands typed at the -keyboard. Note: in Spice3 version 3a7 and earlier, all commands +keyboard. Note: in Ngspice version 3a7 and earlier, all commands (including ones read from files) were saved. @@ -4579,14 +4670,14 @@ keyboard. Note: in Spice3 version 3a7 and earlier, all commands @end example -Incrementally plot the values of the nodes while Spice3 runs. The iplot +Incrementally plot the values of the nodes while Ngspice runs. The iplot command can be used with the where command to find trouble spots in a transient simulation. @node Jobs, Let, Iplot, Commands -@subsection Jobs: List active asynchronous spice runs +@subsection Jobs: List active asynchronous ngspice runs General Form: @@ -4595,7 +4686,7 @@ transient simulation. @end example -Report on the asynchronous SPICE-3 jobs currently running. Nutmeg +Report on the asynchronous NGSPICE jobs currently running. Nutmeg checks to see if the jobs are finished every time you execute a command. If it is done then the data is loaded and becomes available. @@ -4636,7 +4727,7 @@ of tstep, tstart, and tstop in the currently active transient analysis. The currently loaded input file must include a transient analysis (a tran command may be run interactively before the last reset, alternately), and the current plot must be from this transient analysis. -This command is needed because Spice3 doesn't output the results from a +This command is needed because Ngspice doesn't output the results from a transient analysis in the same manner that Spice2 did. @@ -4762,7 +4853,7 @@ first column unless the variable noprintscale is true. @node Quit, Rehash, Print, Commands -@subsection Quit: Leave Spice3 or Nutmeg +@subsection Quit: Leave Ngspice or Nutmeg General Form: @@ -4771,7 +4862,7 @@ first column unless the variable noprintscale is true. @end example -Quit nutmeg or spice. +Quit nutmeg or ngspice. @@ -4848,7 +4939,7 @@ Resume a simulation after a stop or interruption (control-C). @node Rspice, Run, Resume, Commands -@subsection Rspice: Remote spice submission +@subsection Rspice: Remote ngspice submission General Form: @@ -4857,12 +4948,12 @@ Resume a simulation after a stop or interruption (control-C). @end example -Runs a SPICE-3 remotely taking the input file as a SPICE-3 input file, -or the current circuit if no argument is given. Nutmeg or Spice3 waits +Runs a NGSPICE remotely taking the input file as a NGSPICE input file, +or the current circuit if no argument is given. Nutmeg or Ngspice waits for the job to complete, and passes output from the remote job to the user's standard output. When the job is finished the data is loaded in as with aspice. If the variable rhost is set, nutmeg connects to this -host instead of the default remote Spice3 server machine. This command +host instead of the default remote Ngspice server machine. This command uses the "rsh" command and thereby requires authentication via a ".rhosts" file or other equivalent method. Note that "rsh" refers to the "remote shell" program, which may be "remsh" on your system; to @@ -4947,23 +5038,28 @@ loaded. Currently valid resources are: General Form: @example - save [all | output ...] - .save [all | output ...] + save [all | allv | alli | output ...] + .save [all | allv | alli | output ...] @end example Save a set of outputs, discarding the rest. If a node has been mentioned in a save command, it appears in the working plot after a run -has completed, or in the rawfile if spice is run in batch mode. If a +has completed, or in the rawfile if ngspice is run in batch mode. If a node is traced or plotted (see below) it is also saved. For backward compatibility, if there are no save commands given, all outputs are saved. -When the keyword "all" appears in the save command, all default values -(node voltages and voltage source currents) are saved in addition to any -other values listed. - +When the keyword "all" or the keyword "allv", appears in the save command, +all node voltages, voltage source currents and inductor currents are saved +in addition to any other values listed. If the keyword "alli" appears in +the save command, all devices currents are saved. +Note: the current implementation saves only the currents of devices which + have internal nodes, i.e. MOSFETs with non zero RD and RS; BJTs with + non-zero RC, RB and RE; DIODEs with non-zero RS; etc. Resistor and + capacitor currents are not saved with this option. These deficiencies + will be addressed in a later revision. @node Sens, Set, Save, Commands @subsection Sens*: Run a sensitivity analysis @@ -5043,7 +5139,7 @@ the setplot and display commands and are used by diff, below.) If the vectors defined. Note that here the word "plot" refers to a group of vectors that are the -result of one SPICE run. When more than one file is loaded in, or more +result of one NGSPICE run. When more than one file is loaded in, or more than one plot is present in one file, nutmeg keeps them separate and only shows you the vectors in the current plot. @@ -5147,7 +5243,7 @@ single letter specifying the device type letter, "letter:subckt:", @node Source, Status, Showmod, Commands -@subsection Source: Read a Spice3 input file +@subsection Source: Read a Ngspice input file General Form: @@ -5156,16 +5252,16 @@ single letter specifying the device type letter, "letter:subckt:", @end example -For Spice3: Read the Spice3 input file file. Nutmeg and Spice3 commands +For Ngspice: Read the Ngspice input file file. Nutmeg and Ngspice commands may be included in the file, and must be enclosed between the lines .control and .endc. These commands are executed immediately after the circuit is loaded, so a control line of ac ... works the same as the corresponding .ac card. The first line in any input file is considered a title line and not parsed but kept as the name of the circuit. The -exception to this rule is the file .spiceinit. Thus, a Spice3 command +exception to this rule is the file .spiceinit. Thus, a Ngspice command script must begin with a blank line and then with a acters *# is considered a control line. This makes it possible to imbed commands in -Spice3 input files that are ignored by earlier versions of Spice2 +Ngspice input files that are ignored by earlier versions of Spice2 For Nutmeg: Reads commands from the file filename. Lines beginning with the character * are considered comments and ignored. @@ -5291,7 +5387,7 @@ for more details. This command transposes a multidimensional vector. No analysis in -Spice3 produces multidimensional vectors, although the DC transfer curve +Ngspice produces multidimensional vectors, although the DC transfer curve may be run with two varying sources. You must use the "reshape" command to reform the one-dimensional vectors into two dimensional vectors. In addition, the default scale is incorrect for plotting. You must plot @@ -5301,11 +5397,11 @@ example (circuit to produce the tranfer characteristic of a MOS transistor): @example - spice3 > dc vgg 0 5 1 vdd 0 5 1 - spice3 > plot i(vdd) - spice3 > reshape all [6,6] - spice3 > transpose i(vdd) v(drain) - spice3 > plot i(vdd) vs v(drain)[0] + ngspice > dc vgg 0 5 1 vdd 0 5 1 + ngspice > plot i(vdd) + ngspice > reshape all [6,6] + ngspice > transpose i(vdd) v(drain) + ngspice > plot i(vdd) vs v(drain)[0] @end example @@ -5352,7 +5448,7 @@ Clear the value of the specified variable(s) (word). @node Version, Where, Unset, Commands -@subsection Version: Print the version of Spice +@subsection Version: Print the version of ngspice General Form: @@ -5363,7 +5459,7 @@ Clear the value of the specified variable(s) (word). Print out the version of nutmeg that is running. If there are arguments, it checks to make sure that the arguments match the current -version of SPICE. (This is mainly used as a Command: line in rawfiles.) +version of NGSPICE. (This is mainly used as a Command: line in rawfiles.) @@ -5425,7 +5521,7 @@ expression list is all. @end example -The spice3/nutmeg xgraph command plots data like the plot command but +The ngspice/nutmeg xgraph command plots data like the plot command but via xgraph, a popular X11 plotting program. If file is either "temp" or "tmp" a temporary file is used to hold the @@ -5602,9 +5698,9 @@ control structures may be examined with the debugging command cdump. @section Variables -The operation of both Nutmeg and Spice3 may be affected by setting +The operation of both Nutmeg and Ngspice may be affected by setting variables with the "set" command. In addition to the variables -mentioned below, the set command in Spice3 also affect the behaviour of +mentioned below, the set command in Ngspice also affect the behaviour of the simulator via the options previously described under the section on ".OPTIONS". @@ -5711,7 +5807,7 @@ This is a printf(3s) style format string used to specify the command to use for sending plot(5)-style plots to a printer or plotter. The first parameter sup plied is the printer name, the second parameter supplied is a file name con taining the plot. Both parameters are strings. It -is trivial to cause Spice3 to abort by supplying a unreasonable format +is trivial to cause Ngspice to abort by supplying a unreasonable format string. @item lprps @@ -5720,7 +5816,7 @@ This is a printf(3s) style format string used to specify the command to use for sending PostScript plots to a printer or plotter. The first parameter supplied is the printer name, the second parame ter supplied is a file name containing the plot. Both parameters are strings. It is -trivial to cause Spice3 to abort by supplying a unreasonable format +trivial to cause Ngspice to abort by supplying a unreasonable format string. @item nfreqs @@ -5827,7 +5923,7 @@ Overrides the name used for generating rspice runs (default is @item rhost -The machine to use for remote SPICE-3 runs, in stead of the default one +The machine to use for remote NGSPICE runs, in stead of the default one (see the description of the rspice command, below). @item rprogram @@ -5842,8 +5938,8 @@ before continuing. @item sourcepath A list of the directories to search when a source command is given. The -default is the current directory and the standard spice library -(/usr/local/lib/spice, or whatever LIBPATH is #defined to in the Spice3 +default is the current directory and the standard ngspice library +(/usr/local/lib/ngspice, or whatever LIBPATH is #defined to in the Ngspice source. @item spicepath @@ -5881,7 +5977,7 @@ The width of the page for asciiplot and print col. @item x11lineararcs Some X11 implementations have poor arc drawing. If you set this option, -Spice3 will plot using an approximation to the curve using straight +Ngspice will plot using an approximation to the curve using straight lines. @item xbrushheight @@ -5899,7 +5995,7 @@ The plot may not look good if this is a variable-width font. @end vtable -There are several set variables that Spice3 uses but Nutmeg does +There are several set variables that Ngspice uses but Nutmeg does not. They are: @vtable @code @@ -5915,7 +6011,7 @@ The name of the model card (normally @item noaskquit Do not check to make sure that there are no circuits suspended and no -plots un saved. Normally Spice3 warns the user when he tries to quit if +plots un saved. Normally Ngspice warns the user when he tries to quit if this is the case. @item nobjthack @@ -5943,7 +6039,7 @@ begin subcircuits (normally @section MISCELLANEOUS -If there are subcircuits in the input file, Spice3 expands instances of +If there are subcircuits in the input file, Ngspice expands instances of them. A subcircuit is delimited by the cards .subckt and .ends, or whatever the value of the variables substart and subend is, respectively. An instance of a subcircuit is created by specifying a @@ -5964,7 +6060,7 @@ specifies instances of subcircuits, instead of 'x'. Nutmeg occasionally checks to see if it is getting close to running out of space, and warns the user if this is the case. (This is more likely -to be useful with the SPICE front end.) +to be useful with the NGSPICE front end.) C-shell type quoting with "" and '', and backquote substitution may be used. Within single quotes, no further substitution (like history @@ -6012,7 +6108,7 @@ You may type multiple commands on one line, separated by semicolons. If you want to use a different mfbcap file than the default (usually ~cad/lib/mfbcap), you have to set the environment variable SPICE_MFBCAP -before you start nutmeg or spice. The -m option and the mfbcap variable +before you start nutmeg or ngspice. The -m option and the mfbcap variable no longer work. If X is being used, the cursor may be positioned at any point on the @@ -6082,7 +6178,7 @@ The hardcopy command is useless on VMS and other systems without the plot command, unless the user has a program that understands plot(5) format. -Spice3 recognizes all the notations used in SPICE2 .plot cards, and +Ngspice recognizes all the notations used in SPICE2 .plot cards, and translates vp(1) into ph(v(1)), and so forth. However, if there are spaces in these names it won't work. Hence v(1, 2) and (-.5, .5) aren't recognized. @@ -6097,7 +6193,7 @@ you can set the variable "nobjthack" which forces BJTs to have 4 nodes The @@name[param] notation might not work with trace, iplot, etc. yet. The first line of a command file (except for the .spiceinit file) should -be a comment, otherwise SPICE may create an empty circuit. +be a comment, otherwise NGSPICE may create an empty circuit. Files specified on the command line are read before .spiceinit is read. @@ -6434,6 +6530,7 @@ and model, but are provided as a quick reference guide. @node Uniform RC line, Arbitrary Source, Model and Device Parameters, Model and Device Parameters @section URC: Uniform R.C. line +@example ------------------------------------------------------------ | URC - instance parameters (input-output) | @@ -6469,10 +6566,12 @@ and model, but are provided as a quick reference guide. | isperl Saturation current per length | | rsperl Diode resistance per length | ------------------------------------------------------------ +@end example @node Arbitrary Source, Bipolar Junction Transistor, Uniform RC line, Model and Device Parameters @section ASRC: Arbitrary Source +@example ------------------------------------------------------------ | ASRC - instance parameters (input-only) | @@ -6490,10 +6589,12 @@ and model, but are provided as a quick reference guide. | pos_node Positive Node | | neg_node Negative Node | ------------------------------------------------------------ +@end example @node Bipolar Junction Transistor, BSIM1 Berkeley Short Channel IGFET Model, Arbitrary Source, Model and Device Parameters @section BJT: Bipolar Junction Transistor - + @example + ------------------------------------------------------------ | BJT - instance parameters (input-only) | |-----------------------------------------------------------+ @@ -6657,10 +6758,12 @@ and model, but are provided as a quick reference guide. | transtimevbcfact Transit time VBC factor | | excessphasefactor Excess phase fact. | ------------------------------------------------------------ +@end example @node BSIM1 Berkeley Short Channel IGFET Model, BSIM2 Berkeley Short Channel IGFET Model, Bipolar Junction Transistor, Model and Device Parameters @section BSIM1: Berkeley Short Channel IGFET Model +@example ------------------------------------------------------------ | BSIM1 - instance parameters (input-only) | @@ -6701,7 +6804,7 @@ and model, but are provided as a quick reference guide. | BSIM1 - model parameters (input-output) | |-----------------------------------------------------------+ | vfb Flat band voltage | - lvfb Length dependence of vfb +|lvfb Length dependence of vfb | | wvfb Width dependence of vfb | | phi Strong inversion surface potential | ------------------------------------------------------------ @@ -6725,7 +6828,7 @@ and model, but are provided as a quick reference guide. --------------------------------------------------------------------- -| BSIM1 - model input-output parameters - continued| +| BSIM1 - model input-output parameters - continued | |--------------------------------------------------------------------+ |wx2e Width dependence of x2e | |x3e VDS dependence of eta | @@ -6808,10 +6911,12 @@ and model, but are provided as a quick reference guide. |wdf Default width of source drain diffusion in um | |dell Length reduction of source drain diffusion | --------------------------------------------------------------------------- +@end example @node BSIM2 Berkeley Short Channel IGFET Model, Fixed capacitor, BSIM1 Berkeley Short Channel IGFET Model, Model and Device Parameters @section BSIM2: Berkeley Short Channel IGFET Model +@example ------------------------------------------------------------ | BSIM2 - instance parameters (input-only) | @@ -6957,90 +7062,101 @@ and model, but are provided as a quick reference guide. | wu1d Width depence of u1d | | n0 Subthreshold slope at VDS=0 VBS=0 | | ln0 Length dependence of n0 | -| continued | +| continued | ------------------------------------------------------------ - ------------------------------------------------------------------------ + -------------------------------------------------------------- | BSIM2 - model input-output parameters - continued | -|-----------------------------------------------------------------------+ -|wn0 Width dependence of n0 | -|nb VBS dependence of n | -|lnb Length dependence of nb | -|wnb Width dependence of nb | - ------------------------------------------------------------------------ -|nd VDS dependence of n | -|lnd Length dependence of nd | -|wnd Width dependence of nd | -|vof0 Threshold voltage offset AT VDS=0 VBS=0 | -|-----------------------------------------------------------------------+ -|lvof0 Length dependence of vof0 | -|wvof0 Width dependence of vof0 | -|vofb VBS dependence of vof | -|lvofb Length dependence of vofb | - ------------------------------------------------------------------------ -|wvofb Width dependence of vofb | -|vofd VDS dependence of vof | -|lvofd Length dependence of vofd | -|wvofd Width dependence of vofd | -|-----------------------------------------------------------------------+ -|ai0 Pre-factor of hot-electron effect. | -|lai0 Length dependence of ai0 | -|wai0 Width dependence of ai0 | -|aib VBS dependence of ai | - ------------------------------------------------------------------------ -|laib Length dependence of aib | -|waib Width dependence of aib | -|bi0 Exponential factor of hot-electron effect. | -|lbi0 Length dependence of bi0 | -|-----------------------------------------------------------------------+ -|wbi0 Width dependence of bi0 | -|bib VBS dependence of bi | -|lbib Length dependence of bib | -|wbib Width dependence of bib | - ------------------------------------------------------------------------ -|vghigh Upper bound of the cubic spline function. | -|lvghigh Length dependence of vghigh | -|wvghigh Width dependence of vghigh | -|vglow Lower bound of the cubic spline function. | -|-----------------------------------------------------------------------+ -|lvglow Length dependence of vglow | -|wvglow Width dependence of vglow | -|tox Gate oxide thickness in um | -|temp Temperature in degree Celcius | - ------------------------------------------------------------------------ -|vdd Maximum Vds | -|vgg Maximum Vgs | -|vbb Maximum Vbs | -|cgso Gate source overlap capacitance per unit channel width(m) -|-----------------------------------------------------------------------+ -|cgdo Gate drain overlap capacitance per unit channel width(m)| -|cgbo Gate bulk overlap capacitance per unit channel length(m)| -|xpart Flag for channel charge partitioning | +|--------------------------------------------------------------+ +|wn0 Width dependence of n0 | +|nb VBS dependence of n | +|lnb Length dependence of nb | +|wnb Width dependence of nb | + --------------------------------------------------------------+ +|nd VDS dependence of n | +|lnd Length dependence of nd | +|wnd Width dependence of nd | +|vof0 Threshold voltage offset AT VDS=0 VBS=0 | +|--------------------------------------------------------------+ +|lvof0 Length dependence of vof0 | +|wvof0 Width dependence of vof0 | +|vofb VBS dependence of vof | +|lvofb Length dependence of vofb | + --------------------------------------------------------------+ +|wvofb Width dependence of vofb | +|vofd VDS dependence of vof | +|lvofd Length dependence of vofd | +|wvofd Width dependence of vofd | +|--------------------------------------------------------------+ +|ai0 Pre-factor of hot-electron effect. | +|lai0 Length dependence of ai0 | +|wai0 Width dependence of ai0 | +|aib VBS dependence of ai | + --------------------------------------------------------------+ +|laib Length dependence of aib | +|waib Width dependence of aib | +|bi0 Exponential factor of hot-electron effect. | +|lbi0 Length dependence of bi0 | +|--------------------------------------------------------------+ +|wbi0 Width dependence of bi0 | +|bib VBS dependence of bi | +|lbib Length dependence of bib | +|wbib Width dependence of bib | + --------------------------------------------------------------+ +|vghigh Upper bound of the cubic spline function. | +|lvghigh Length dependence of vghigh | +|wvghigh Width dependence of vghigh | +|vglow Lower bound of the cubic spline function. | +|--------------------------------------------------------------+ +|lvglow Length dependence of vglow | +|wvglow Width dependence of vglow | +|tox Gate oxide thickness in um | +|temp Temperature in degree Celcius | + --------------------------------------------------------------+ +|vdd Maximum Vds | +|vgg Maximum Vgs | +|vbb Maximum Vbs | +|cgso Gate source overlap capacitance per unit | +| channel width(m) | +|--------------------------------------------------------------+ +|cgdo Gate drain overlap capacitance | +| per unit channel width(m) | +|cgbo Gate bulk overlap capacitance | +| per unit channel length(m) | +|xpart Flag for channel charge partitioning | | continued | - ------------------------------------------------------------------------ + --------------------------------------------------------------- - --------------------------------------------------------------------------- -| BSIM2 - model input-output parameters - continued | -|--------------------------------------------------------------------------+ -|rsh Source drain diffusion sheet resistance in ohm per square | -|js Source drain junction saturation current per unit area | -|pb Source drain junction built in potential | - mj Source drain bottom junction capacitance grading coefficient -| | - --------------------------------------------------------------------------- -|pbsw Source drain side junction capacitance built in potential | -|mjsw Source drain side junction capacitance grading coefficient | -|cj Source drain bottom junction capacitance per unit area | -|cjsw Source drain side junction capacitance per unit area | -|wdf Default width of source drain diffusion in um | -|dell Length reduction of source drain diffusion | - --------------------------------------------------------------------------- + --------------------------------------------------------------- +| BSIM2 - model input-output parameters | +|--------------------------------------------------------------+ +|rsh Source drain diffusion sheet resistance | +| in ohm per square | +|js Source drain junction saturation current | +| per unit area | +|pb Source drain junction built in potential | +|mj Source drain bottom junction capacitance | +| grading coefficient | + --------------------------------------------------------------+ +|pbsw Source drain side junction capacitance | +| built in potential | +|mjsw Source drain side junction capacitance | +| grading coefficient | +|cj Source drain bottom junction capacitance | +| per unit area | +|cjsw Source drain side junction capacitance | +| per unit area | +|wdf Default width of source drain diffusion in um | +|dell Length reduction of source drain diffusion | + --------------------------------------------------------------- +@end example @node Fixed capacitor, Current controlled current source, BSIM2 Berkeley Short Channel IGFET Model, Model and Device Parameters @section Capacitor: Fixed capacitor +@example ------------------------------------------------------------ | Capacitor - instance parameters (input-output) | @@ -7075,10 +7191,12 @@ and model, but are provided as a quick reference guide. | defw Default width | | narrow width correction factor | ------------------------------------------------------------ +@end example @node Current controlled current source, Linear current controlled current source, Fixed capacitor, Model and Device Parameters @section CCCS: Current controlled current source +@example ------------------------------------------------------------ | CCCS - instance parameters (input-output) | @@ -7097,10 +7215,12 @@ and model, but are provided as a quick reference guide. | v CCCS voltage at output | | p CCCS power | ------------------------------------------------------------ +@end example @node Linear current controlled current source, Current controlled ideal switch, Current controlled current source, Model and Device Parameters @section CCVS: Linear current controlled current source +@example ------------------------------------------------------------ | CCVS - instance parameters (input-output) | @@ -7119,11 +7239,13 @@ and model, but are provided as a quick reference guide. | v CCVS output voltage | | p CCVS power | ------------------------------------------------------------ +@end example @node Current controlled ideal switch, Junction Diode model, Linear current controlled current source, Model and Device Parameters @section CSwitch: Current controlled ideal switch +@example ------------------------------------------------------------ | CSwitch - instance parameters (input-only) | @@ -7167,10 +7289,12 @@ and model, but are provided as a quick reference guide. | gon Closed conductance | | goff Open conductance | ------------------------------------------------------------ +@end example @node Junction Diode model, Inductor, Current controlled ideal switch, Model and Device Parameters @section Diode: Junction Diode model +@example ------------------------------------------------------------ | Diode - instance parameters (input-output) | @@ -7234,10 +7358,12 @@ and model, but are provided as a quick reference guide. |-----------------------------------------------------------+ | cond Ohmic conductance | ------------------------------------------------------------ +@end example @node Inductor, Mutual inductors, Junction Diode model, Model and Device Parameters @section Inductor: Inductors +@example ------------------------------------------------------------ | Inductor - instance parameters (input-output) | @@ -7258,10 +7384,12 @@ and model, but are provided as a quick reference guide. p instantaneous power dissipated by the inductor | | ------------------------------------------------------------- +@end example @node Mutual inductors, Independent current source, Inductor, Model and Device Parameters @section mutual: Mutual inductors +@example ------------------------------------------------------------ | mutual - instance parameters (input-output) | @@ -7271,10 +7399,12 @@ and model, but are provided as a quick reference guide. | inductor1 First coupled inductor | | inductor2 Second coupled inductor | ------------------------------------------------------------ +@end example @node Independent current source, Junction Field effect transistor, Mutual inductors, Model and Device Parameters @section Isource: Independent current source +@example ------------------------------------------------------------ | Isource - instance parameters (input-only) | @@ -7316,10 +7446,12 @@ and model, but are provided as a quick reference guide. | v Voltage across the supply | | p Power supplied by the source | ------------------------------------------------------------ +@end example @node Junction Field effect transistor, Lossy transmission line, Independent current source, Model and Device Parameters @section JFET: Junction Field effect transistor +@example ------------------------------------------------------------ | JFET - instance parameters (input-output) | @@ -7377,7 +7509,7 @@ and model, but are provided as a quick reference guide. | rd Drain ohmic resistance | | rs Source ohmic resistance | | cgs G-S junction capactance | -| continued | +| continued | ------------------------------------------------------------ @@ -7403,10 +7535,12 @@ and model, but are provided as a quick reference guide. | gd Drain conductance | | gs Source conductance | ------------------------------------------------------------ +@end example @node Lossy transmission line, GaAs MESFET model, Junction Field effect transistor, Model and Device Parameters @section LTRA: Lossy transmission line +@example ------------------------------------------------------------ | LTRA - instance parameters (input-only) | @@ -7446,22 +7580,24 @@ and model, but are provided as a quick reference guide. |len length of line | |nocontrol No timestep control | |steplimit always limit timestep to 0.8*(delay of line) -| continued | +| continued | ------------------------------------------------------------ - ----------------------------------------------------------------------------------- -| LTRA - model input-output parameters - continued | -|----------------------------------------------------------------------------------+ -|nosteplimit don't always limit timestep to 0.8*(delay of line) | -|lininterp use linear interpolation | -|quadinterp use quadratic interpolation | -|mixedinterp use linear interpolation if quadratic results look unacceptable | - ----------------------------------------------------------------------------------- -|truncnr use N-R iterations for step calculation in LTRAtrunc | -|truncdontcut don't limit timestep to keep impulse response calculation errors low -|compactrel special reltol for straight line checking | -|compactabs special abstol for straight line checking | - ----------------------------------------------------------------------------------- + --------------------------------------------------------------------- +| LTRA - model input-output parameters - continued | +|---------------------------------------------------------------------+ +|nosteplimit don't always limit timestep to 0.8*(delay of line) | +|lininterp use linear interpolation | +|quadinterp use quadratic interpolation | +|mixedinterp use linear interpolation if quadratic results | +| look unacceptable | + --------------------------------------------------------------------- +|truncnr use N-R iterations for step calculation in LTRAtrunc | +|truncdontcut don't limit timestep to keep impulse response | +| calculation errors low | +|compactrel special reltol for straight line checking | +|compactabs special abstol for straight line checking | + --------------------------------------------------------------------- ------------------------------------------------------------ @@ -7470,10 +7606,12 @@ and model, but are provided as a quick reference guide. | rel Rel. rate of change of deriv. for bkpt | | abs Abs. rate of change of deriv. for bkpt | ------------------------------------------------------------ +@end example @node GaAs MESFET model, Level 1 MOSfet model, Lossy transmission line, Model and Device Parameters @section MES: GaAs MESFET model +@example ------------------------------------------------------------ | MES - instance parameters (input-output) | @@ -7561,10 +7699,12 @@ and model, but are provided as a quick reference guide. | depl_cap Depletion capacitance | | vcrit Critical voltage | ------------------------------------------------------------ +@end example @node Level 1 MOSfet model, Level 2 MOSfet model, GaAs MESFET model, Model and Device Parameters @section Mos1: Level 1 MOSfet model with Meyer capacitance model +@example ------------------------------------------------------------ | Mos1 - instance parameters (input-only) | @@ -7731,10 +7871,12 @@ and model, but are provided as a quick reference guide. |-----------------------------------------------------------+ | type N-channel or P-channel MOS | ------------------------------------------------------------ +@end example @node Level 2 MOSfet model, Level 3 MOSfet model, Level 1 MOSfet model, Model and Device Parameters @section Mos2: Level 2 MOSfet model with Meyer capacitance model +@example ------------------------------------------------------------ | Mos2 - instance parameters (input-only) | @@ -7906,10 +8048,12 @@ and model, but are provided as a quick reference guide. |-----------------------------------------------------------+ | type N-channel or P-channel MOS | ------------------------------------------------------------ +@end example @node Level 3 MOSfet model, Level 6 MOSfet model, Level 2 MOSfet model, Model and Device Parameters @section Mos3: Level 3 MOSfet model with Meyer capacitance model +@example ------------------------------------------------------------ @@ -8084,10 +8228,12 @@ and model, but are provided as a quick reference guide. |-----------------------------------------------------------+ | type N-channel or P-channel MOS | ------------------------------------------------------------ +@end example @node Level 6 MOSfet model, Simple linear resistor, Level 3 MOSfet model, Model and Device Parameters @section Mos6: Level 6 MOSfet model with Meyer capacitance model +@example ------------------------------------------------------------ @@ -8258,10 +8404,12 @@ and model, but are provided as a quick reference guide. |-----------------------------------------------------------+ | type N-channel or P-channel MOS | ------------------------------------------------------------ +@end example @node Simple linear resistor, Ideal voltage controlled switch, Level 6 MOSfet model, Model and Device Parameters @section Resistor: Simple linear resistor +@example ------------------------------------------------------------ | Resistor - instance parameters (input-output) | @@ -8298,10 +8446,12 @@ and model, but are provided as a quick reference guide. | defw Default device width | | tnom Parameter measurement temperature | ------------------------------------------------------------ +@end example @node Ideal voltage controlled switch, Lossless transmission line, Simple linear resistor, Model and Device Parameters @section Switch: Ideal voltage controlled switch +@example ------------------------------------------------------------ | Switch - instance parameters (input-only) | @@ -8346,10 +8496,12 @@ and model, but are provided as a quick reference guide. | gon Conductance when closed | | goff Conductance when open | ------------------------------------------------------------ +@end example @node Lossless transmission line, Voltage controlled current source, Ideal voltage controlled switch, Model and Device Parameters @section Tranline: Lossless transmission line +@example ------------------------------------------------------------ | Tranline - instance parameters (input-only) | @@ -8386,10 +8538,12 @@ and model, but are provided as a quick reference guide. | neg_node2 Negative node of end 2 of t. line | | delays Delayed values of excitation | ------------------------------------------------------------ +@end example @node Voltage controlled current source, Voltage controlled voltage source, Lossless transmission line, Model and Device Parameters @section VCCS: Voltage controlled current source +@example ------------------------------------------------------------ | VCCS - instance parameters (input-only) | @@ -8417,10 +8571,12 @@ and model, but are provided as a quick reference guide. | v Voltage across output | | p Power | ------------------------------------------------------------ +@end example @node Voltage controlled voltage source, Independent voltage source, Voltage controlled current source, Model and Device Parameters @section VCVS: Voltage controlled voltage source +@example ------------------------------------------------------------ | VCVS - instance parameters (input-only) | @@ -8448,10 +8604,12 @@ and model, but are provided as a quick reference guide. | v Output voltage | | p Power | ------------------------------------------------------------ +@end example @node Independent voltage source, , Voltage controlled voltage source, Model and Device Parameters @section Vsource: Independent voltage source +@example ------------------------------------------------------------ | Vsource - instance parameters (input-only) | @@ -8492,5 +8650,6 @@ and model, but are provided as a quick reference guide. | i Voltage source current | | p Instantaneous power | ------------------------------------------------------------ +@end example @bye diff --git a/man/man1/Makefile.am b/man/man1/Makefile.am index 1818ad812..832669a65 100644 --- a/man/man1/Makefile.am +++ b/man/man1/Makefile.am @@ -1,7 +1,7 @@ ## Process this file with automake to produce Makefile.in -man_MANS = spice.1 nutmeg.1 sconvert.1 +man_MANS = ngspice.1 ngnutmeg.1 ngsconvert.1 EXTRA_DIST = $(man_MANS) diff --git a/src/ChangeLog b/src/ChangeLog index 04999df89..797bb4c7a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,82 @@ +2001-12-04 Emmanuel Rouat + + * maths/cmaths/Makefile.am (noinst_PROGRAMS): test programs + shouldnt get installed + +2000-10-13 Arno W. Peters + + * ngspice.txt: changes SPICE: to NGSPICE: to restore help + functionality. Thanks go to Michael Widlok for the analysis. + +2000-07-21 Arno W. Peters + + * src/analysis/*: Moved these files into src/devices/analysis. + The files in this directory implement the analysis and simulation + for electrical circuits. + + This is the final step to separating the Spice sources into a + library part and a frontend part. Now, the devices subdirectory + has to be renamed to spicelib and the devices that are now + scattered in that directory should be moved into a new devices + directory. + + * configure.in, src/Makefile.am, src/devices/Makefile.am: Files + affected by the move. + +2000-07-20 Arno W. Peters + + * src/hlp/*: moved these files into src/frontend/help. The files + in this directory implement the help system for the frontend. + + * configure.in, src/Makefile.am, src/frontend/Makefile.am: Files + affected by the move. + + * src/circuit/*: moved these files into src/devices/parser. The + files in this directory take a model line from the input file and + add the corresponding element to the representation of + the circuit in memory. + + * configure.in, src/Makefile.am, src/devices/Makefile.am: Files + affected by the move. + +2000-07-18 Arno W. Peters + + * main.c: Added the call to the initialization function of the + devices. + +2000-07-07 Arno W. Peters + + * parser/cshpar.c: Separated out com_chdir(), com_echo(), + com_rehash() and com_shell() and moved them into frontend + directory. + + * frontend/com_chdir.c, frontend/com_echo.c, frontend/com_rehash.c, + frontend/com_shell.c: Their new homes. + + * parser/quote.c, parser/quote.h: The quote/unquote functions are + used exclusively in the frontend, moved them there. + + * frontend/quote.c, frontend/quote.h: Their new location. + + * parser/input.c, parser/input.h: Input, output and error streams + handled in the frontend. Moved to the frontend directory. + + * frontend/streams.c: Its new home. + + * frontend/Makefile.am: Updates for new files. + + * frontend/breakp2.c, frontend/newcoms.c, frontend/postcoms.c, + frontend/resource.c, frontend/terminal.h, frontend/variable.c, + frontend/variable.h, frontend/com_compose.c, + frontend/com_display.c, frontend/com_setscale.c, + frontend/com_strcmp.c: Include files update. + + * parser/var2.c, parser/var2.h: Empty files, removed. + + * parser/Makefile.am: Updates for removed files. + + * parser/lexical.c: Small adjustments + 2000-04-04 Paolo Nenzi * ngspice.c: Added support for BSIM4. diff --git a/src/Makefile.am b/src/Makefile.am index 24f81d8b4..26dace547 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,61 +1,64 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS = analysis circuit devices frontend hlp maths misc parser include +SUBDIRS = misc maths frontend spicelib include @XSPICEDIR@ -bin_PROGRAMS = ngspice nutmeg help sconvert proc2mod multidec makeidx +bin_PROGRAMS = ngspice ngnutmeg nghelp ngsconvert ngproc2mod ngmultidec makeidx -EXTRA_DIST = ngspice.txt ngspice.idx +EXTRA_DIST = ngspice.txt spinit setplot spectrum helpdatadir = $(pkgdatadir)/helpdir -helpdata_DATA = ngspice.idx ngspice.txt +helpdata_DATA = ngspice.txt +initdatadir = $(pkgdatadir)/scripts + +initdata_DATA = spinit setplot spectrum DYNAMIC_DEVICELIBS = \ - devices/asrc/libasrc.la \ - devices/bjt/libbjt.la \ - devices/bsim1/libbsim1.la \ - devices/bsim2/libbsim2.la \ - devices/bsim3/libbsim3.la \ - devices/bsim4/libbsim4.la \ - devices/bsim3v1/libbsim3v1.la \ - devices/bsim3v2/libbsim3v2.la \ - devices/cap/libcap.la \ - devices/cccs/libcccs.la \ - devices/ccvs/libccvs.la \ - devices/csw/libcsw.la \ - devices/devsup/libdevsup.la \ - devices/dio/libdio.la \ - devices/disto/libdisto.la \ - devices/ind/libind.la \ - devices/isrc/libisrc.la \ - devices/jfet/libjfet.la \ - devices/jfet2/libjfet2.la \ - devices/ltra/libltra.la \ - devices/cccs/libcccs.la \ - devices/ccvs/libccvs.la \ - devices/csw/libcsw.la \ - devices/devsup/libdevsup.la \ - devices/dio/libdio.la \ - devices/disto/libdisto.la \ - devices/ind/libind.la \ - devices/isrc/libisrc.la \ - devices/jfet/libjfet.la \ - devices/jfet2/libjfet2.la \ - devices/ltra/libltra.la \ - devices/mes/libmes.la \ - devices/mos1/libmos1.la \ - devices/mos2/libmos2.la \ - devices/mos3/libmos3.la \ - devices/mos6/libmos6.la \ - devices/res/libres.la \ - devices/sw/libsw.la \ - devices/tra/libtra.la \ - devices/urc/liburc.la \ - devices/vccs/libvccs.la \ - devices/vcvs/libvcvs.la \ - devices/vsrc/libvsrc.la + spicelib/devices/asrc/libasrc.la \ + spicelib/devices/bjt/libbjt.la \ +## spicelib/devices/bjt2/libbjt2.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.la \ + 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.la \ + 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 ## Build ngspice first: @@ -67,75 +70,80 @@ ngspice_SOURCES = \ ngspice_LDADD = \ spice.o \ frontend/libfte.a \ - $(DYNAMIC_DEVICELIBS) \ - analysis/libckt.a \ - parser/libparser.a \ - hlp/libhlp.a \ - circuit/libinp.a \ + frontend/plotting/libplotting.a \ + @XSPICELIB1@ \ + spicelib/devices/dev.o \ + $(DYNAMIC_DEVICELIBS) \ + spicelib/analysis/libckt.a \ + spicelib/devices/libdev.a \ + @XSPICELIB2@ \ + frontend/parser/libparser.a \ + frontend/help/libhlp.a \ + spicelib/parser/libinp.a \ + maths/deriv/libderiv.a \ maths/cmaths/libcmaths.a \ + maths/poly/libpoly.a \ maths/ni/libni.a \ maths/sparse/libsparse.a \ - misc/libmisc.a - + misc/libmisc.a spice.o: main.c $(COMPILE) -DSIMULATOR -o spice.o -c $(srcdir)/main.c ## nutmeg: -nutmeg_SOURCES = \ +ngnutmeg_SOURCES = \ main.c \ conf.c \ conf.h \ - nutmeg.c + ngnutmeg.c -nutmeg_LDADD = \ +ngnutmeg_LDADD = \ frontend/libfte.a \ - parser/libparser.a \ - hlp/libhlp.a \ + frontend/plotting/libplotting.a \ + frontend/parser/libparser.a \ + frontend/help/libhlp.a \ maths/cmaths/libcmaths.a \ + maths/poly/libpoly.a \ misc/libmisc.a - - ## help: -help_SOURCES = help.c +nghelp_SOURCES = nghelp.c -help_LDADD = \ - hlp/libhlp.a \ - parser/libparser.a \ +nghelp_LDADD = \ + frontend/help/libhlp.a \ + frontend/parser/libparser.a \ + frontend/libfte.a \ misc/libmisc.a - ## sconvert: -sconvert_SOURCES = sconvert.c +ngsconvert_SOURCES = ngsconvert.c -sconvert_LDADD = \ +ngsconvert_LDADD = \ frontend/libfte.a \ - parser/libparser.a \ - misc/libmisc.a - + frontend/parser/libparser.a \ + misc/libmisc.a ## proc2mod: -proc2mod_SOURCES = proc2mod.c +ngproc2mod_SOURCES = ngproc2mod.c -proc2mod_LDADD = \ - parser/libparser.a \ - circuit/libinp.a \ +ngproc2mod_LDADD = \ + frontend/parser/libparser.a \ + spicelib/parser/libinp.a \ misc/libmisc.a ## multidec: -multidec_SOURCES = multidec.c +ngmultidec_SOURCES = ngmultidec.c -multidec_LDADD = \ +ngmultidec_LDADD = \ maths/sparse/libsparse.a \ misc/libmisc.a @@ -155,8 +163,57 @@ all: ## General Includes and libraries: -INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/devices @X_CFLAGS@ +INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices @X_CFLAGS@ LIBS = @LIBS@ @X_LIBS@ @X_PRE_LIBS@ @X_EXTRA_LIBS@ MAINTAINERCLEANFILES = Makefile.in + +CLEANFILES = pkgIndex.tcl libspice.so + +TCL_PKG_PATH = @TCL_PACKAGE_PATH@ + +TCLSPICE_VERSION = 0.2.7 + +TCL_FILES = libspice.so pkgIndex.tcl + +LIBSPICE_OBJS = tclspice.o + +pkgIndex.tcl: pkgIndex.tcl.in + rm -f pkgIndex.tcl + sed -e 's;%LIB_DIR%;$(TCL_PKG_PATH);g' pkgIndex.tcl.in | \ + sed -e 's;%VERSION%;$(TCLSPICE_VERSION);g' > pkgIndex.tcl + +tcl_install: tcl-install-recursive install-tclspice + +tcl-install-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) install) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; + +install-tclspice: ${TCL_FILES} + install -c -m 644 libspice.so $(TCL_PKG_PATH) + mkdir -p $(TCL_PKG_PATH)/spice + install -c -m 644 pkgIndex.tcl $(TCL_PKG_PATH)/spice + +tclspice.o: tclspice.c + $(COMPILE) -c -fpic tclspice.c -DTCLSPICE_version="\"$(TCLSPICE_VERSION)\"" + +libspice.so: $(ngspice_OBJECTS) $(LIBSPICE_OBJS) $(ngspice_DEPENDENCIES) + $(LINK) $(ngspice_LDFLAGS) $(ngspice_OBJECTS) $(ngspice_LDADD) $(LIBS) $(LIBSPICE_OBJS) -shared -lpthread + if test -f .libs/$@ ; then \ + mv .libs/$@ ./ ;\ + rmdir .libs ;\ + fi + +tcl: tcl-recursive + +tcl-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) all) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; + make ${TCL_FILES} diff --git a/src/frontend/ChangeLog b/src/frontend/ChangeLog index 2c38e19e4..a59b5e15f 100644 --- a/src/frontend/ChangeLog +++ b/src/frontend/ChangeLog @@ -1,31 +1,230 @@ +2001-11-25 Emmanuel Rouat + + * circuits.h: transfered definition of sstructire 'circ' to ftedefs.h + +2001-02-07 Paolo Nenzi + + * outitf.c: From a message Alan sento to the mailing list: + ---------- Forwarded message ---------- + Date: Tue, 6 Feb 2001 11:11:56 -0000 + From: "Gillespie, Alan" + Reply-To: ng-spice-devel@ieee.ing.uniroma1.it + To: "Ng-Spice-Devel (E-mail)" + Subject: [ng-spice-devel] Reference variable update in interactive mode + + + I've tweaked outitf.c so that the reference variable value + is updated to the screen in interactive mode. I forgot to + save the old version first, though, so I couldn't do a diff, + so I'm just attaching the whole new outitf.c file. Also, I've + updated the documentation as follows :- + + + + Modifications to "outitf.c" + --------------------------- + + A number of modifications have been applied to outitf.c in + order to achieve the following "improvements" :- + + 1) Spice3, by default, saved all node voltages, including + nodes internal to the devices. These extra nodes add + dramatically to the amount of data saved, but don't add + significantly to the useful information about the circuit. + So, instead of saving these nodes, a "hack" has been + introduced which checks a new spice option, and either + discards the internal node, or saves some device currents + instead. + + 2) During long simulations, spice would sit "staring back + blankly", giving no clue as to how well the simulation + was, or wasn't, proceeding. In order to give a little + more feedback, another "hack", in the data writing routine, + writes the value of the reference variable to the error + stream, which is usually the screen. In order to minimize + the CPU time "wasted" doing this, the routine will only + reprint the value if more than a quarter of a second since + the last screen update. The result is that this feedback + adds no significant extra time to performance of the + simulation. + + 3) The original file writing routines used to write each data + value to the file individually. A buffering scheme was added, + which collects each row of data in a buffer, and the writes + the whole buffer in one call. This gave a significant + performance improvement (up to 20%) on HPUX, with all currents + saved in large circuits, although there was no significant + difference on Windows 95. The improvement has not been + measured on Linux. + + 4) A check was added to make sure the file write was successful. + Spice3 could easily fill the hard disk, but would continue to + churn away, producing no more useful data. Now it will exit + gracefully. I can't remember why I thought this was important, + but at least it means that a PC with power management will be + able to power down after a long overnight simulation has + ceased to produce any more useful data. + + Changes + ------- + The routine beginPlot is called at the beginning of the simulation + to select which nodes and variables will be saved. The first + modification is at the point where it checks the "save" list. This + is the list of tokens attached to the .save lines read from the + spice source file. The routine now checks for "allv" and "alli" + as well as "all". "allv" is treated as a synonym for "all". If + "all" or "allv" is found, then a saveall flag is set, and if "alli" + is found then a new savealli flag is set. + + Next, the addDataDesc routine is called for every variable to be + saved. This is done by stepping through an array called dataNames[]. + I'm not quite sure where this array comes from, but it was quite + easy to add an if statement to stop it calling addDataDesc if + dataNames[i] points to a string containing any of the following - + + #internal + #source + #drain + #collector + #emitter + #base + + That seems to catch all the internal device nodes. + The next addition is a new pass through the dataNames[] array + specifically looking for those strings. (This pass is only performed + if the savealli flag has been set). When one of the strings is found, + a bunch of if-then-else statements creates a corresponding string + which is submitted to the add addSpecialDesc routine. This saves the + relevant device current. Note that since mosfets have only two + internal nodes, but four terminal currents, and bipolars have three + internal nodes and four terminal currents, some internal nodes have + to save more than one terminal current. + + This last change is a clumsy hack, and only works if the devices in + question actually have internal nodes. Resistors and capacitors, for + instance, never have internal nodes, and so their terminal currents + will not cannot be saved with the .save alli card. Also, any bipolar, + mosfet or diodes with zero valued parasitic resistances (rd, rs, rc, + rb, re) will not be allocated internal nodes, and so their terminal + currents will not be saved by this hack, either. + + Further down outitf.c, the OUTpData routine is called whenever a + new row of data is ready to be written to file. Near the top of this, + the reference variable is written to file separately from the rest of + the variables. This is a convenient point for a couple of statements + which check the elapsed time since the last update, and write the + reference value to stderr if it's time. Slightly further down the + routine is the section for writing data to a "plot", i.e. retaining + it in memory. A similar statement or two writes the reference value + to the screen for this case, i.e. interactive mode. At the end of the + OUTpData routine, a new check has been added to see if there was an + error writing to the rawfile. If so, the shouldstop flag is set to + TRUE, and the simulation will abort. + + Scanning down outitf.c, the next modification is in the fileInit + routine. The first statement initialises the lastclock variable. + This is used later when deciding if it's time to write the reference + value to the screen. + + Next, the fileInit_pass2 routine writes the name strings to the start + of the rawfile. At the end of this routine there is now a statement + which checks if this will be a binary rawfile, and if so, it allocates + a row buffer of the correct length. + + The fileStartPoint routine seems to be called before each row of data + is written, and so this is a convenient point to reset the buffer + pointer to zero. + + The fileAddRealValue and fileAddComplexValue routines now simply write + the relevant values to the buffer, and increment the buffer pointer. + Previously they called the fwrite library routine to actually write + the data. If the rawfile is not a binary one, however, they just write + the text as before. + + The fileEndPoint routine was previously empty. Now it actually calls + fwrite to write the whole buffer to the file (if it's a binary file). + + Finally the fileEnd routine prints the total number of data points to + the screen, and de-allocates the row buffer (if it was a binary + rawfile). + + Congratulations to whoever put these dummy routines in in the first + place, since that allowed the buffering to be added very easily. + +2001-01-23 Paolo Nenzi + + * subckt.c: added some code (very, very experimental) + to support mos devices with variable number of nodes + (5 to 7) in subcircuit expansion. This hack is necessary + since SOI devices can have up to 7 nodes. + +2000-11-07 Arno W. Peters + + * com_history, com_alias, parser/cshpar.c, parser/complete.c: + Applied patch by Michael Widlok. It fixes command completion and + history list. In the process, Michael also fixed a memory leak. + +2000-09-09 Arno W. Peters + + * commands.c: Use fourier.h. + + * dotcards.c: Update to prevent segfault. + + * fourier.c, fourier.h: com_fourier is now calling fourier(), a + function with more parameters. + + * dotcards.c: Added assertions to guard a double indirection, now + ngspice will bomb out on an assertion instead of a segfault. + +2000-07-18 Arno W. Peters + + * com_ahelp.c, com_help.c, com_plot.c, com_set.c, com_unset.c: + Updated header file includes. + + * quote.c: Code formatting changes. + +2000-07-16 Arno W. Peters + + * com_set.h: New header file. + + * com_state.c, com_state.h: Separated from debugcom.c. + + * com_dump.c, com_dump.h: Separated from debugcom.c. + + * debugcom.c, debugcom.h: Removed. + + * Makefile.am: Updates for added/removed files. + 2000-03-22 Paolo Nenzi - * rawfile.c: Applied Michael Widlok patch. - - * spiceif.c: Applied Michael Widlok patch. + * rawfile.c: Applied Michael Widlok patch. + + * spiceif.c: Applied Michael Widlok patch. 2000-03-12 Paolo Nenzi - - * x11.c: Cleared the code. Rewmoved some empty return on void functions. + + * x11.c: Cleared the code. Rewmoved some empty return on void + functions. 1999-12-20 Paolo Nenzi - outif.c: - To fix various "save"-related segmentation faults, make this one-line patch - to outitf.c: line 356, change - unique = devname; to unique = copy(devname); + + * outif.c: To fix various "save"-related segmentation faults, make + this one-line patch to outitf.c: line 356, change unique = + devname; to unique = copy(devname); 1999-12-20 Paolo Nenzi - subckt.c: - Bug: Current controlled switch subcircuit does not expand - the controlling source correctly: vsrc expands to name:vsrc, - not to v:name:src. - Fix: changed this file to indicate that w device has only 2 - not 3 nodes and 1 not zero controlling sources. + + * subckt.c: Bug: Current controlled switch subcircuit does not + expand the controlling source correctly: vsrc expands to + name:vsrc, not to v:name:src. + + Fix: changed this file to indicate that w device has only 2 not 3 + nodes and 1 not zero controlling sources. 1999-09-07 Emmanuel Rouat - * *.c: put back static functions declarations back in the .c files (shouldn't - be in .h files!) + * *.c: put back static functions declarations back in the .c files + (shouldn't be in .h files!) 1999-09-07 Arno @@ -34,7 +233,7 @@ * cmath1.c: * cmath2.c: removed most warnings about possible use of - uninitialized variables. Only two remain in cx_sqrt(). + uninitialized variables. Only two remain in cx_sqrt(). 1999-09-06 Arno Peters @@ -104,16 +303,14 @@ * resource.c: removed tests on HAS_UNIX_SEGMENT_HACK - * xgraph.c (ft_xgraph): - * options.c (cp_usrset): - * misccoms.c: removed tests on HAS_SYSTEM + * xgraph.c (ft_xgraph), options.c (cp_usrset), misccoms.c: removed + tests on HAS_SYSTEM - * nutinp.c: - * inp.c (com_source): - (doedit): removed tests on HAS_SYSTEM (always true?) + * nutinp.c, inp.c (com_source, doedit): removed tests on + HAS_SYSTEM (always true?) - * doplot.c (com_hardcopy): removed tests on HAS_UNLINK (always true) - (com_hardcopy): removed tests on HAS_SYSTEM (always true?) + * doplot.c (com_hardcopy): removed tests on HAS_UNLINK (always + true), removed tests on HAS_SYSTEM (always true?) * signal.c: * evaluate.c (doop): @@ -127,28 +324,22 @@ * aspice.c: changed HAS_WAIT into HAVE_SYS_WAIT_H - * inpcom.c: - * breakp.c: changed HAS_CTYPE into HAVE_CTYPE_H + * inpcom.c, breakp.c: changed HAS_CTYPE into HAVE_CTYPE_H 1999-08-03 Emmanuel Rouat - * signal.c: - * resource.c: - * evaluate.c: - * aspice.c: changed SIGNAL_TYPE into RETSIGTYPE + * signal.c, resource.c, evaluate.c, aspice.c: changed SIGNAL_TYPE + into RETSIGTYPE 1999-07-31 Emmanuel Rouat - * Makefile.am: added @X_CFLAGS@ (X11 header files) to INCLUDES and removed - unused LIBS list. + * Makefile.am: added @X_CFLAGS@ (X11 header files) to INCLUDES and + removed unused LIBS list. 28-07-1999 emmanuel.rouat@wanadoo.fr (Manu Rouat) - * graf.c: - * display.c: - * doplot.c: - * x11.c: changed HAS_X11 define to X_DISPLAY_MISSING, which is supplied - by autoconf in config.h + * graf.c, display.c, doplot.c, x11.c: changed HAS_X11 define + to X_DISPLAY_MISSING, which is supplied by autoconf in config.h - * removed -DWANT_X11 in Makefile.am + * Makefile.am: removed -DWANT_X11 diff --git a/src/frontend/Makefile.am b/src/frontend/Makefile.am index d5fa3dbf5..e5e96e2f3 100644 --- a/src/frontend/Makefile.am +++ b/src/frontend/Makefile.am @@ -1,125 +1,173 @@ ## Process this file with automake to produce Makefile.in +SUBDIRS = plotting help parser + noinst_LIBRARIES = libfte.a libfte_a_SOURCES = \ - agraf.c \ - agraf.h \ - arg.c \ - arg.h \ - aspice.c \ - aspice.h \ - breakp.c \ - breakp.h \ - breakp2.c \ - breakp2.h \ - circuits.c \ - circuits.h \ - clip.c \ - clip.h \ - compose.c \ - compose.h \ - cpitf.c \ - cpitf.h \ - debugcom.c \ - debugcom.h \ - define.c \ - define.h \ - device.c \ - device.h \ - diff.c \ - diff.h \ - dimens.c \ - dimens.h \ - display.c \ - display.h \ - doplot.c \ - doplot.h \ - dotcards.c \ - dotcards.h \ - error.c \ - error.h \ - evaluate.c \ - evaluate.h \ - fourier.c \ - fourier.h \ - gens.c \ - gens.h \ - graf.c \ - graf.h \ - graphdb.c \ - graphdb.h \ - grid.c \ - grid.h \ - inp.c \ - inp.h \ - inpcom.c \ - inpcom.h \ - interp.c \ - interp.h \ - linear.c \ - linear.h \ - misccoms.c \ - misccoms.h \ - miscvars.c \ - miscvars.h \ - mw_coms.c \ - mw_coms.h \ - newcoms.c \ - newcoms.h \ - nutctab.c \ - nutctab.h \ - nutinp.c \ - nutinp.h \ - nutmegif.c \ - nutmegif.h \ - options.c \ - options.h \ - outitf.c \ - outitf.h \ - parse.c \ - parse.h \ - plot5.c \ - plot5.h \ - plotcurv.c \ - plotcurv.h \ - points.c \ - points.h \ - postcoms.c \ - postcoms.h \ - postsc.c \ - postsc.h \ - rawfile.c \ - rawfile.h \ - resource.c \ - resource.h \ - runcoms.c \ - runcoms.h \ - runcoms2.c \ - runcoms2.h \ - shyu.c \ - shyu.h \ - signal_handler.c\ - signal_handler.h\ - spec.c \ - spec.h \ - spcmdtab.c \ - spiceif.c \ - spiceif.h \ - subckt.c \ - subckt.h \ - typesdef.c \ - typesdef.h \ - vectors.c \ - vectors.h \ - where.c \ - where.h \ - x11.c \ - x11.h \ - xgraph.c \ - xgraph.h - + commands.c \ + commands.h \ + com_ahelp.c \ + com_ahelp.h \ + com_alias.c \ + com_alias.h \ + com_asciiplot.c \ + com_asciiplot.h \ + com_cdump.c \ + com_cdump.h \ + com_chdir.c \ + com_compose.c \ + com_compose.h \ + com_display.c \ + com_display.h \ + com_dump.c \ + com_dump.h \ + com_echo.c \ + com_ghelp.c \ + com_ghelp.h \ + com_hardcopy.c \ + com_hardcopy.h \ + com_help.c \ + com_help.h \ + com_history.c \ + com_history.h \ + com_let.c \ + com_let.h \ + com_option.c \ + com_option.h \ + com_dl.c \ + com_dl.h \ + com_plot.c \ + com_plot.h \ + com_rehash.c \ + com_set.c \ + com_set.h \ + com_setscale.c \ + com_setscale.h \ + com_shell.c \ + com_shift.c \ + com_state.c \ + com_state.h \ + com_strcmp.c \ + com_strcmp.h \ + com_unset.c \ + com_xgraph.c \ + com_xgraph.h \ + completion.h \ + control.h \ + control.c \ + ftehelp.h \ + hcomp.c \ + hcomp.h \ + init.c \ + init.h \ + quote.c \ + quote.h \ + streams.h \ + streams.c \ + terminal.c \ + terminal.h \ + variable.c \ + variable.h \ + \ + arg.c \ + arg.h \ + aspice.c \ + aspice.h \ + breakp.c \ + breakp.h \ + breakp2.c \ + breakp2.h \ + circuits.c \ + circuits.h \ + cpitf.c \ + cpitf.h \ + define.c \ + define.h \ + device.c \ + device.h \ + diff.c \ + diff.h \ + dimens.c \ + dimens.h \ + display.c \ + display.h \ + dotcards.c \ + dotcards.h \ + error.c \ + error.h \ + evaluate.c \ + evaluate.h \ + fourier.c \ + fourier.h \ + gens.c \ + gens.h \ + inp.c \ + inp.h \ + inpcom.c \ + inpcom.h \ + interp.c \ + interp.h \ + linear.c \ + linear.h \ + misccoms.c \ + misccoms.h \ + miscvars.c \ + miscvars.h \ + mw_coms.c \ + mw_coms.h \ + newcoms.c \ + newcoms.h \ + nutinp.c \ + nutinp.h \ + nutmegif.c \ + nutmegif.h \ + options.c \ + options.h \ + outitf.c \ + outitf.h \ + parse.c \ + parse.h \ + points.c \ + points.h \ + postcoms.c \ + postcoms.h \ + postsc.c \ + postsc.h \ + rawfile.c \ + rawfile.h \ + resource.c \ + resource.h \ + runcoms.c \ + runcoms.h \ + runcoms2.c \ + runcoms2.h \ + shyu.c \ + shyu.h \ + signal_handler.c\ + signal_handler.h\ + spec.c \ + spec.h \ + spiceif.c \ + spiceif.h \ + subckt.c \ + subckt.h \ + typesdef.c \ + typesdef.h \ + vectors.c \ + vectors.h \ + where.c \ + where.h +# TESTS = testcommands +# +# bin_PROGRAMS = testcommands +# +# testcommands_SOURCES = \ +# testcommands.c \ +# testcommands.h +# +# testcommands_LDADD = libfte.a plotting/libplotting.a ../misc/libmisc.a INCLUDES = -I$(top_srcdir)/src/include @X_CFLAGS@ diff --git a/src/frontend/arg.c b/src/frontend/arg.c index e62afde7c..ee5c020da 100644 --- a/src/frontend/arg.c +++ b/src/frontend/arg.c @@ -8,12 +8,13 @@ Author: 1987 Jeffrey M. Hsu and prompt the user if necessary. */ -#include "ngspice.h" -#include "fteinput.h" -#include "cpdefs.h" -#include "fteext.h" -#include "arg.h" +#include +#include +#include +#include +#include "arg.h" +#include "variable.h" static void common(char *string, struct wordlist *wl, struct comm *command); diff --git a/src/frontend/aspice.c b/src/frontend/aspice.c index 1e4aadc1c..0a3bd777e 100644 --- a/src/frontend/aspice.c +++ b/src/frontend/aspice.c @@ -10,8 +10,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "aspice.h" +#include "aspice.h" +#include "variable.h" +#include "circuits.h" # ifdef HAVE_SYS_WAIT_H /* should be more tests here I think */ @@ -31,7 +33,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include #include "fteinp.h" -#include "ftedata.h" +#include "dvec.h" #ifndef SEEK_SET @@ -174,13 +176,21 @@ sigchild(void) * whether the exit was normal or not. */ +#if defined(__NetBSD__) + pid_t status; +#else + union wait status; +#endif + + + void ft_checkkids(void) { - struct proc *p, *lp; + struct proc *p = NULL, *lp = NULL; char buf[BSIZE_SP]; FILE *fp; - int pid; + int pid = 0; static bool here = FALSE; /* Don't want to be re-entrant. */ if (!numchanged || here) @@ -189,10 +199,10 @@ ft_checkkids(void) here = TRUE; while (numchanged > 0) { - pid = wait((union wait *) NULL); + pid = wait(&status); if (pid == -1) { - fprintf(cp_err, -"ft_checkkids: Internal Error: should be %d jobs done but there aren't any.\n", + fprintf(cp_err, + "ft_checkkids: Internal Error: should be %d jobs done but there aren't any.\n", numchanged); numchanged = 0; running = NULL; @@ -293,12 +303,6 @@ com_rspice(wordlist *wl) pid = fork( ); if (pid == 0) { -#ifdef notdef - char com_buf[200]; - - sprintf(com_buf, "%s %s %s -s", remote_shell, rhost, program); - printf("executing: \"%s\"\n", com_buf); -#endif /* I am the "server" process */ close(to_serv[1]); close(from_serv[0]); @@ -381,10 +385,6 @@ com_rspice(wordlist *wl) fprintf(stderr, "Error reading rawdata: %s\n", buf); continue; } -#ifdef notdef - fprintf(stderr, "adjusting rawfile: write \"%d\" at %ld\n", - num, pos); -#endif if (fseek(out, pos, SEEK_SET)) fprintf(stderr, "Error adjusting rawfile: write \"%d\" at %ld\n", diff --git a/src/frontend/breakp.c b/src/frontend/breakp.c index 1496cba6d..5b5e702b1 100644 --- a/src/frontend/breakp.c +++ b/src/frontend/breakp.c @@ -10,10 +10,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" #include "ftedebug.h" #include "breakp.h" +#include "completion.h" static bool satisfied(struct dbcomm *d, struct plot *plot); static void printcond(struct dbcomm *d, FILE *fp); @@ -164,6 +165,7 @@ com_iplot(wordlist *wl) d->db_type = DB_IPLOT; d->db_nodename1 = copy(s); } + tfree(s);/*DG: avoid memory leak */ d->db_also = currentdb; currentdb = d; wl = wl->wl_next; diff --git a/src/frontend/breakp2.c b/src/frontend/breakp2.c index 01e8b84f3..c714002c6 100644 --- a/src/frontend/breakp2.c +++ b/src/frontend/breakp2.c @@ -10,8 +10,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" #include "ftedebug.h" + +#include "quote.h" #include "breakp2.h" @@ -83,6 +85,7 @@ settrace(wordlist *wl, int what, char *name) d->db_nodename1 = copy(s); /* wrd_chtrace(s, TRUE, what); */ } + tfree(s);/*DG avoid memoy leak */ if (dbs) { for (td = dbs; td->db_next; td = td->db_next) ; diff --git a/src/frontend/circuits.c b/src/frontend/circuits.c index c0afbffca..f1a1ee8da 100644 --- a/src/frontend/circuits.c +++ b/src/frontend/circuits.c @@ -3,32 +3,22 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group **********/ -/* - * - * Routines for dealing with the circuit database. This is currently - * unimplemented. - */ +/* Routines for dealing with the circuit database. This is currently + * unimplemented. */ #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" #include "circuits.h" struct circ *ft_curckt = NULL; /* The default active circuit. */ struct circ *ft_circuits = NULL; -struct subcirc *ft_subcircuits = NULL; /* Now stuff to deal with circuits */ - -void -ft_setccirc(char *name) -{ -} - /* Add a circuit to the circuit list */ void @@ -38,12 +28,3 @@ ft_newcirc(struct circ *ckt) ft_circuits = ckt; return; } - -/* Add a new subcircuit to the subcircuit list */ - - -void -ft_newsubcirc(struct subcirc *sckt) -{ -} - diff --git a/src/frontend/circuits.h b/src/frontend/circuits.h index 842c6ca62..cbfb8bdbd 100644 --- a/src/frontend/circuits.h +++ b/src/frontend/circuits.h @@ -7,9 +7,16 @@ #define CIRCUITS_H_INCLUDED -void ft_setccirc(char *name); + +struct subcirc { + char *sc_name; /* Whatever... */ +} ; + + +extern struct circ *ft_curckt; /* The default active circuit. */ + + void ft_newcirc(struct circ *ckt); -void ft_newsubcirc(struct subcirc *sckt); #endif diff --git a/src/frontend/cpitf.c b/src/frontend/cpitf.c index f57463341..4e869eabd 100644 --- a/src/frontend/cpitf.c +++ b/src/frontend/cpitf.c @@ -3,13 +3,22 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group **********/ +/* + * SJB 22 May 2001 + * Corrected freeing of memory in ft_cpinit() + */ + #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" #include "fteparse.h" #include "cpitf.h" +#include + +#include "completion.h" +#include "variable.h" /* Set some standard variables and aliases, etc, and init the ccom stuff. */ @@ -19,7 +28,7 @@ ft_cpinit(void) wordlist *wl; wordlist wl1, wl2, wl3; bool found = FALSE, t = TRUE; - char buf[BSIZE_SP], **x, *s, *r; + char buf[BSIZE_SP], **x, *s, *r,*copys; struct comm *c; int i; FILE *fp; @@ -202,11 +211,12 @@ ft_cpinit(void) /* Now source the standard startup file. */ /* XXX strange */ - for (s = cp_tildexpand(Lib_Path); s && *s; ) { + for (copys=s=cp_tildexpand(Lib_Path); s && *s; ) {/*DG*/ while (isspace(*s)) s++; for (r = buf; *s && !isspace(*s); r++, s++) *r = *s; + tfree(copys); /* sjb - it's safe to free this here */ (void) strcpy(r, DIR_PATHSEP); (void) strcat(r, "spinit"); if ((fp = fopen(buf, "r"))) { @@ -232,14 +242,15 @@ ft_cpinit(void) } tcap_init( ); - + /* tfree(copys);*/ /*DG Avoid memory leak*/ + /* SJB - must not free here as cp_tildexpande() can return NULL */ return; } /* Decide whether a condition is TRUE or not. */ bool -cp_isTRUE(wordlist *wl) +cp_istrue(wordlist *wl) { int i; struct dvec *v; diff --git a/src/frontend/define.c b/src/frontend/define.c index acb430aba..0cf15ee31 100644 --- a/src/frontend/define.c +++ b/src/frontend/define.c @@ -17,10 +17,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" #include "fteparse.h" #include "define.h" +#include "completion.h" /* static declarations */ static void savetree(struct pnode *pn); @@ -265,7 +266,7 @@ ft_substdef(char *name, struct pnode *args) struct udfunc *udf; struct pnode *tp; char *s; - int arity = 0, rarity; + int arity = 0, rarity = 0; bool found = FALSE; if (args) @@ -439,7 +440,7 @@ com_undefine(wordlist *wlist) */ void -ft_pnode(struct pn *pn) +ft_pnode(struct pnode *pn) { prtree1(pn, cp_err); } diff --git a/src/frontend/device.c b/src/frontend/device.c index 373ae20f2..09667aa9b 100644 --- a/src/frontend/device.c +++ b/src/frontend/device.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group +Modified: 2000 AlansFixes **********/ /* @@ -13,8 +14,10 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group #include "cpdefs.h" #include "ftedefs.h" #include "dgen.h" -#include "device.h" +#include "circuits.h" +#include "device.h" +#include "variable.h" static wordlist *devexpand(char *name); @@ -74,7 +77,7 @@ all_show(wordlist *wl, int mode) if (!cp_getvar("width", VT_NUM, (char *) &screen_width)) screen_width = DEF_WIDTH; - count = screen_width / 11 - 1; + count = (screen_width - LEFT_WIDTH) / (DEV_WIDTH + 1); n = 0; do { @@ -166,7 +169,7 @@ all_show(wordlist *wl, int mode) i = 0; do { - printf(" device "); + printf("%*s", LEFT_WIDTH, "device"); j = dgen_for_n(dg, count, printstr, "n", i); i += 1; printf("\n"); @@ -175,7 +178,7 @@ all_show(wordlist *wl, int mode) if (ft_sim->devices[dg->dev_type_no]->numModelParms) { i = 0; do { - printf(" model "); + printf("%*s", LEFT_WIDTH, "model"); j = dgen_for_n(dg, count, printstr, "m", i); i += 1; printf("\n"); @@ -188,7 +191,7 @@ all_show(wordlist *wl, int mode) else if (!params) param_forall(dg, DGEN_DEFPARAMS); if (params) - wl_forall(params, listparam, dg); + wl_forall(params, (void *)listparam, (void *)dg); printf("\n"); } else if (ft_sim->devices[dg->dev_type_no]->numModelParms) { @@ -198,7 +201,7 @@ all_show(wordlist *wl, int mode) n += 1; i = 0; do { - printf(" model "); + printf("%*s", LEFT_WIDTH, "model"); j = dgen_for_n(dg, count, printstr, "m", i); i += 1; printf("\n"); @@ -210,7 +213,7 @@ all_show(wordlist *wl, int mode) else if (!params) param_forall(dg, DGEN_DEFPARAMS); if (params) - wl_forall(params, listparam, dg); + wl_forall(params, (void *) listparam, (void *)dg); printf("\n"); } } @@ -234,16 +237,16 @@ printstr(dgen *dg, char *name) { if (*name == 'n') { if (dg->instance) - printf(" %9.9s", dg->instance->GENname); + printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->instance->GENname); else - printf(" "); + printf(" %*s", DEV_WIDTH, ""); } else if (*name == 'm') { if (dg->model) - printf(" %9.9s", dg->model->GENmodName); + printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, dg->model->GENmodName); else - printf(" "); + printf(" %*s", DEV_WIDTH, ""); } else - printf(" "); + printf(" %*s", DEV_WIDTH, ""); return 0; } @@ -276,9 +279,10 @@ param_forall(dgen *dg, int flags) j = 0; do { if (!j) - printf("%10.10s", plist[i].keyword); + printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, + plist[i].keyword); else - printf(" "); + printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, " "); k = dgen_for_n(dg, count, printvals, (char *) (plist + i), j); printf("\n"); @@ -321,10 +325,10 @@ listparam(wordlist *p, dgen *dg) j = 0; do { if (!j) - printf("%10.10s", p->wl_word); + printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word); else - printf(" "); - k = dgen_for_n(dg, count, printvals, plist + i, j); + printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, " "); + k = dgen_for_n(dg, count, printvals, (void *)(plist + i), j); printf("\n"); j += 1; } while (k > 0); @@ -332,9 +336,9 @@ listparam(wordlist *p, dgen *dg) j = 0; do { if (!j) - printf("%10.10s", p->wl_word); + printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word); else - printf(" "); + printf("%*s", LEFT_WIDTH, " "); k = dgen_for_n(dg, count, bogus1, 0, j); printf("\n"); j += 1; @@ -344,9 +348,9 @@ listparam(wordlist *p, dgen *dg) j = 0; do { if (!j) - printf("%10.10s", p->wl_word); + printf("%*.*s", LEFT_WIDTH, LEFT_WIDTH, p->wl_word); else - printf(" "); + printf("%*s", LEFT_WIDTH, " "); k = dgen_for_n(dg, count, bogus2, 0, j); printf("\n"); j += 1; @@ -356,13 +360,13 @@ listparam(wordlist *p, dgen *dg) int bogus1(dgen *dg) { - printf(" ---------"); + printf(" %*s", DEV_WIDTH, "---------"); return 0; } int bogus2(dgen *dg) { - printf(" ?????????"); + printf(" %*s", DEV_WIDTH, "?????????"); return 0; } @@ -398,54 +402,54 @@ printvals(dgen *dg, IFparm *p, int i) if (p->dataType & IF_VECTOR) { switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) { case IF_FLAG: - printf(" % 9d", val.v.vec.iVec[i]); + printf(" % *d", DEV_WIDTH, val.v.vec.iVec[i]); break; case IF_INTEGER: - printf(" % 9d", val.v.vec.iVec[i]); + printf(" % *d", DEV_WIDTH, val.v.vec.iVec[i]); break; case IF_REAL: - printf(" % 9.3g", val.v.vec.rVec[i]); + printf(" % *.6g", DEV_WIDTH, val.v.vec.rVec[i]); break; case IF_COMPLEX: if (!(i % 2)) - printf(" % 9.3g", val.v.vec.cVec[i / 2].real); + printf(" % *.6g", DEV_WIDTH, val.v.vec.cVec[i / 2].real); else - printf(" % 9.3g", val.v.vec.cVec[i / 2].imag); + printf(" % *.6g", DEV_WIDTH, val.v.vec.cVec[i / 2].imag); break; case IF_STRING: - printf(" %9.9s", val.v.vec.sVec[i]); + printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.sVec[i]); break; case IF_INSTANCE: - printf(" %9.9s", val.v.vec.uVec[i]); + printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.v.vec.uVec[i]); break; default: - printf(" ******** "); + printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** "); } } else { switch ((p->dataType & IF_VARTYPES) & ~IF_VECTOR) { case IF_FLAG: - printf(" % 9d", val.iValue); + printf(" % *d", DEV_WIDTH, val.iValue); break; case IF_INTEGER: - printf(" % 9d", val.iValue); + printf(" % *d", DEV_WIDTH, val.iValue); break; case IF_REAL: - printf(" % 9.3g", val.rValue); + printf(" % *.6g", DEV_WIDTH, val.rValue); break; case IF_COMPLEX: if (i % 2) - printf(" % 9.3g", val.cValue.real); + printf(" % *.6g", DEV_WIDTH, val.cValue.real); else - printf(" % 9.3g", val.cValue.imag); + printf(" % *.6g", DEV_WIDTH, val.cValue.imag); break; case IF_STRING: - printf(" %9.9s", val.sValue); + printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.sValue); break; case IF_INSTANCE: - printf(" %9.9s ", val.uValue); + printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, val.uValue); break; default: - printf(" ******** "); + printf(" % *.*s", DEV_WIDTH, DEV_WIDTH, " ******** "); } } @@ -566,10 +570,6 @@ com_altermod(wordlist *wl) void com_alter_common(wordlist *wl, int do_model) { -#ifdef notdef - struct variable var, *nv, *prev; - double *dd; -#endif wordlist *eqword, *words; char *dev, *p; char *param; @@ -650,78 +650,6 @@ com_alter_common(wordlist *wl, int do_model) /* Vector data (dv) should get garbage-collected. */ return; - -#ifdef notdef - while (wl) { - param = wl->wl_word; - wl = wl->wl_next; - - if (!wl) { - val = param; - param = NULL; - } else { - val = wl->wl_word; - wl = wl->wl_next; - } - - /* Now figure out what the value should be... */ - if (eq(val, "TRUE")) { - var.va_type = VT_BOOL; - var.va_bool = TRUE; - } else if (eq(val, "FALSE")) { - var.va_type = VT_BOOL; - var.va_bool = FALSE; - } else if (eq(val, "[")) { - var.va_type = VT_LIST; - prev = NULL; - while (wl && !eq(wl->wl_word, "]")) { - val = wl->wl_word; - nv = alloc(struct variable); - if (dd = ft_numparse(&val, FALSE)) { - nv->va_type = VT_REAL; - nv->va_real = *dd; - } else { - fprintf(cp_err, "Error: \"%s\" is not a number\n", val); - break; - } - if (!prev) - var.va_vlist = nv; - else - prev->va_next = nv; - nv->va_next = NULL; - wl = wl->wl_next; - prev = nv; - } - if (wl && eq(wl->wl_word, "]")) { - wl = wl->wl_next; - } else { - while (nv) { - prev = nv->va_next; - tfree(nv); - nv = prev; - } - return; - } - } else if (dd = ft_numparse(&val, FALSE)) { - var.va_type = VT_REAL; - var.va_real = *dd; - } else { - var.va_type = VT_STRING; - var.va_string = val; - } - - if_setparam(ft_curckt->ci_ckt, &dev, param, &var, do_model); - - if (var.va_type == VT_LIST) { - for (nv = var.va_vlist; nv; nv = prev) { - prev = nv->va_next; - tfree(nv); - } - } - - } -#endif - } /* Given a device name, possibly with wildcards, return the matches. */ diff --git a/src/frontend/device.h b/src/frontend/device.h index 4899e7d8f..3daf76c69 100644 --- a/src/frontend/device.h +++ b/src/frontend/device.h @@ -1,11 +1,15 @@ /************* * Header file for device.c * 1999 E. Rouat + * Modified: 2000 AlansFixes ************/ #ifndef DEVICE_H_INCLUDED #define DEVICE_H_INCLUDED +#define LEFT_WIDTH 11 +#define DEV_WIDTH 21 + void com_showmod(wordlist *wl); void com_show(wordlist *wl); int printstr(dgen *dg, char *name); diff --git a/src/frontend/diff.c b/src/frontend/diff.c index e4c80cefb..1109ede24 100644 --- a/src/frontend/diff.c +++ b/src/frontend/diff.c @@ -1,18 +1,20 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +Modified: 2001 Paolo Nenzi (printnum) **********/ /* * Do a 'diff' of two plots. */ -#include "ngspice.h" -#include "cpdefs.h" -#include "ftedefs.h" -#include "ftedata.h" -#include "ftecmath.h" +#include +#include +#include +#include + #include "diff.h" +#include "variable.h" /* Determine if two vectors have the 'same' name. */ @@ -21,6 +23,7 @@ static bool nameeq(char *n1, char *n2) { char buf1[BSIZE_SP], buf2[BSIZE_SP]; + int i; if (eq(n1, n2)) @@ -50,8 +53,9 @@ com_diff(wordlist *wl) struct dvec *v1, *v2; double d1, d2; complex c1, c2, c3; - register int i, j; + int i, j; wordlist *tw; + char numbuf[BSIZE_SP],numbuf2[BSIZE_SP] ,numbuf3[BSIZE_SP], numbuf4[BSIZE_SP]; /* For printnum */ if (!cp_getvar("diff_vntol", VT_REAL, (char *) &vntol)) vntol = 1.0e-6; @@ -203,14 +207,16 @@ com_diff(wordlist *wl) d2 = v2->v_realdata[i]; if (MAX(fabs(d1), fabs(d2)) * reltol + tol < fabs(d1 - d2)) { + printnum(numbuf, d1); fprintf(cp_out, "%s.%s[%d] = %-15s ", p1->pl_typename, v1->v_name, i, - printnum(d1)); + numbuf); + printnum(numbuf, d2); fprintf(cp_out, "%s.%s[%d] = %s\n", p2->pl_typename, v2->v_name, i, - printnum(d2)); + numbuf); } } else { c1 = v1->v_compdata[i]; @@ -223,14 +229,20 @@ com_diff(wordlist *wl) cmax = MAX(cm1, cm2); if (cmax * reltol + tol < cmag(&c3)) { + + printnum(numbuf, realpart(&c1)); + printnum(numbuf2, imagpart(&c1)); + printnum(numbuf3, realpart(&c2)); + printnum(numbuf4, imagpart(&c2)); + fprintf(cp_out, "%s.%s[%d] = %-10s, %-10s %s.%s[%d] = %-10s, %s\n", p1->pl_typename, v1->v_name, i, - copy(printnum(realpart(&c1))), - copy(printnum(imagpart(&c1))), + numbuf, + numbuf2, p2->pl_typename, v2->v_name, i, - copy(printnum(realpart(&c2))), - copy(printnum(imagpart(&c2)))); + numbuf3, + numbuf4); } } } diff --git a/src/frontend/diff.h b/src/frontend/diff.h index 63b2557b1..053d13629 100644 --- a/src/frontend/diff.h +++ b/src/frontend/diff.h @@ -3,12 +3,12 @@ * 1999 E. Rouat ************/ -#ifndef DIFF_H_INCLUDED -#define DIFF_H_INCLUDED +#ifndef _DIFF_H +#define _DIFF_H + +#include + void com_diff(wordlist *wl); - - - #endif diff --git a/src/frontend/dimens.c b/src/frontend/dimens.c index db8788273..f5c9d1da6 100644 --- a/src/frontend/dimens.c +++ b/src/frontend/dimens.c @@ -8,21 +8,22 @@ Author: 1992 David A. Gates, U. C. Berkeley CAD Group */ #include "ngspice.h" -#include "ftedata.h" /* For MAXDIMS */ +#include "dvec.h" /* For MAXDIMS */ #include "dimens.h" /* * Create a string of the form "12,1,10". */ -char * -dimstring(int *data, int length) +void +dimstring(int *data, int length, char *retstring) { int i; char buf[BSIZE_SP]; + if (!data || length < 1) - return NULL; + retstring = ""; buf[0] = '\0'; for (i=0; i < length; i++) { @@ -30,26 +31,27 @@ dimstring(int *data, int length) (i < length - 1) ? "," : ""); } /* XXX Should I return a copy instead? */ - return(buf); + /* qui ci devo fare una copia */ + strcpy(retstring, buf); } /* * Create a string of the form "[12][1][10]". */ -char * -indexstring(int *data, int length) +void +indexstring(int *data, int length, char *retstring) { int i; char buf[BSIZE_SP]; if (!data || length < 1) - return NULL; + retstring = ""; buf[0] = '\0'; for (i=0; i < length; i++) { sprintf(buf + strlen(buf), "[%d]", data[i]); } - return(buf); + strcpy(retstring, buf); } /* diff --git a/src/frontend/dimens.h b/src/frontend/dimens.h index fa55fc668..269d0bae3 100644 --- a/src/frontend/dimens.h +++ b/src/frontend/dimens.h @@ -6,8 +6,8 @@ #ifndef DIMENS_H_INCLUDED #define DIMENS_H_INCLUDED -char * dimstring(int *data, int length); -char * indexstring(int *data, int length); +void dimstring(int *data, int length, char *retstring); +void indexstring(int *data, int length, char *retstring); int incindex(int *counts, int numcounts, int *dims, int numdims); int emptydims(int *data, int length); int atodims(char *p, int *data, int *outlength); diff --git a/src/frontend/display.c b/src/frontend/display.c index 6f2006f42..75a93f2af 100644 --- a/src/frontend/display.c +++ b/src/frontend/display.c @@ -3,19 +3,22 @@ Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#include "ngspice.h" -#include "ftegraph.h" -#include "ftedev.h" -#include "fteinput.h" -#include "cpdefs.h" /* for VT_STRING */ -#include "ftedefs.h" /* for mylog() */ +#include +#include +#include +#include +#include /* for VT_STRING */ +#include /* for mylog() */ + +#ifdef TCL_MODULE +#include +#endif + #include "display.h" - - - +#include "variable.h" /* static declarations */ -static int gen_DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny); +static void gen_DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny); static int gen_Input(REQUEST *request, RESPONSE *response); static int nop(void); static int nodev(void); @@ -52,7 +55,7 @@ DISPDEVICE device[] = { nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, gen_Input, - nop,}, + (void *)nop,}, #ifndef X_DISPLAY_MISSING {"X11", 0, 0, 1024, 864, 0, 0, X11_Init, X11_NewViewport, @@ -63,6 +66,14 @@ DISPDEVICE device[] = { gen_DatatoScreen,}, #endif +#ifdef TCL_MODULE + {"Tk", 0, 0, 1024, 864, 0, 0, sp_Tk_Init, sp_Tk_NewViewport, + sp_Tk_Close, sp_Tk_Clear, + sp_Tk_DrawLine, sp_Tk_Arc, sp_Tk_Text, sp_Tk_DefineColor, sp_Tk_DefineLinestyle, + sp_Tk_SetLinestyle, sp_Tk_SetColor, sp_Tk_Update, + nodev, nodev, nodev, nodev, + gen_DatatoScreen,}, +#endif {"plot5", 0, 0, 1000, 1000, 0, 0, Plt5_Init, Plt5_NewViewport, Plt5_Close, Plt5_Clear, @@ -83,7 +94,7 @@ DISPDEVICE device[] = { nodev, nodev, nodev, nodev, nodev, nodev, nodev, nodev, nodev, nodev, nodev, gen_Input, - nodev,}, + (void *)nodev,}, }; @@ -135,7 +146,9 @@ DevInit(void) } #endif - +#ifdef TCL_MODULE + dispdev = FindDev("Tk"); +#endif if (!dispdev) { externalerror( @@ -230,7 +243,7 @@ void Update(void) /* note: screen coordinates are relative to window so need to add viewport offsets */ -static int +static void gen_DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny) { @@ -276,19 +289,6 @@ void DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny) } -#ifdef notdef -/* -NDCtoScreen(x0, y0, px, py) - double x0, y0; - int *px, *py; -{ - - (*(dispdev->NDCtoScreen))(x0, y0, px, py); - -} -*/ -#endif - void Input(REQUEST *request, RESPONSE *response) { @@ -311,6 +311,7 @@ gen_Input(REQUEST *request, RESPONSE *response) response->option = error_option; break; } +return 0; } /* no operation, do nothing */ @@ -335,7 +336,7 @@ void SaveText(GRAPH *graph, char *text, int x, int y) struct _keyed *keyed; - keyed = (struct _keyed *) calloc(1, sizeof(struct _keyed)); + keyed = (struct _keyed *) tmalloc(sizeof(struct _keyed)); if (!graph->keyed) { graph->keyed = keyed; diff --git a/src/frontend/dotcards.c b/src/frontend/dotcards.c index 9bc26e27e..620af5462 100644 --- a/src/frontend/dotcards.c +++ b/src/frontend/dotcards.c @@ -1,32 +1,54 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +Modified: 2000 AlansFixes **********/ /* * Spice-2 compatibility stuff for .plot, .print, .four, and .width. */ +#include +#include +#include -#include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" #include "fteinp.h" +#include + +#include "circuits.h" #include "dotcards.h" - - +#include "variable.h" +#include "fourier.h" /* Extract all the .save lines */ static void fixdotplot(wordlist *wl); static void fixdotprint(wordlist *wl); static char * fixem(char *string); -static bool setcplot(char *name); static wordlist * gettoks(char *s); extern void com_save2 (wordlist *wl, char *name); + + +static struct plot * +setcplot(char *name) +{ + struct plot *pl; + + for (pl = plot_list; pl; pl = pl->pl_next) { + if (ciprefix(name, pl->pl_typename)) { + return pl; + } + } + return NULL; +} + + + void ft_dotsaves(void) { @@ -145,61 +167,65 @@ ft_cktcoms(bool terse) static wordlist twl = { "col", NULL, NULL } ; struct plot *pl; int i, found; + char numbuf[BSIZE_SP]; /* For printnum*/ all.wl_next = NULL; all.wl_word = "all"; if (!ft_curckt) return 1; - if (!ft_curckt->ci_commands) + + plot_cur = setcplot("op"); + if (!ft_curckt->ci_commands && !plot_cur) goto nocmds; coms = ft_curckt->ci_commands; cp_interactive = FALSE; - /* Circuit name */ - fprintf(cp_out, "Circuit: %s\nDate: %s\n\n", ft_curckt->ci_name, - datestring()); - fprintf(cp_out, "\n"); - /* Listing */ if (ft_listprint) { if (terse) fprintf(cp_err, ".options: no listing, rawfile was generated.\n"); else inp_list(cp_out, ft_curckt->ci_deck, ft_curckt->ci_options, - LS_DECK); + LS_DECK); } /* If there was a .op line, then we have to do the .op output. */ - if (setcplot("op")) { - if (terse) { - fprintf(cp_out, "OP information in rawfile.\n"); - } else { - fprintf(cp_out, "\nOperating point information:\n\n"); - fprintf(cp_out, "\tNode\tVoltage\n"); - fprintf(cp_out, "\t----\t-------\n"); - for (v = plot_cur->pl_dvecs; v; v = v->v_next) { - if (!isreal(v)) { - fprintf(cp_err, - "Internal error: op vector %s not real\n", - v->v_name); - continue; + plot_cur = setcplot("op"); + if (plot_cur != NULL) { + assert(plot_cur->pl_dvecs != NULL); + if (plot_cur->pl_dvecs->v_realdata!=NULL) { + if (terse) { + fprintf(cp_out, "OP information in rawfile.\n"); + } else { + fprintf(cp_out, "\t%-30s%15s\n", "Node", "Voltage"); + fprintf(cp_out, "\t%-30s%15s\n", "----", "-------"); + fprintf(cp_out, "\t----\t-------\n"); + for (v = plot_cur->pl_dvecs; v; v = v->v_next) { + if (!isreal(v)) { + fprintf(cp_err, + "Internal error: op vector %s not real\n", + v->v_name); + continue; + } + if ((v->v_type == SV_VOLTAGE) && (*(v->v_name)!='@')) { + printnum(numbuf, v->v_realdata[0]); + fprintf(cp_out, "\t%-30s%15s\n", v->v_name, numbuf); + } } - if (v->v_type == SV_VOLTAGE) - fprintf(cp_out, "\t%s\t%s\n", v->v_name, - printnum(v->v_realdata[0])); - } - fprintf(cp_out, "\n\tSource\tCurrent\n"); - fprintf(cp_out, "\t------\t-------\n\n"); - for (v = plot_cur->pl_dvecs; v; v = v->v_next) - if (v->v_type == SV_CURRENT) - fprintf(cp_out, "\t%s\t%s\n", v->v_name, - printnum(v->v_realdata[0])); - fprintf(cp_out, "\n"); + fprintf(cp_out, "\n\tSource\tCurrent\n"); + fprintf(cp_out, "\t------\t-------\n\n"); + for (v = plot_cur->pl_dvecs; v; v = v->v_next) + if (v->v_type == SV_CURRENT) { + printnum(numbuf, v->v_realdata[0]); + fprintf(cp_out, "\t%-30s%15s\n", v->v_name, numbuf); + } + fprintf(cp_out, "\n"); - if (!ft_nomod) - com_showmod(&all); - com_show(&all); + if (!ft_nomod) + com_showmod(&all); + com_show(&all); + } } } @@ -238,7 +264,7 @@ ft_cktcoms(bool terse) } else if (eq(command->wl_word, ".print")) { if (terse) { fprintf(cp_out, - ".print line ignored since rawfile was produced.\n"); + ".print line ignored since rawfile was produced.\n"); } else { command = command->wl_next; if (!command) { @@ -261,12 +287,12 @@ ft_cktcoms(bool terse) } if (!found) fprintf(cp_err, "Error: .print: no %s analysis found.\n", - plottype); + plottype); } } else if (eq(command->wl_word, ".plot")) { if (terse) { fprintf(cp_out, - ".plot line ignored since rawfile was produced.\n"); + ".plot line ignored since rawfile was produced.\n"); } else { command = command->wl_next; if (!command) { @@ -289,35 +315,40 @@ ft_cktcoms(bool terse) } if (!found) fprintf(cp_err, "Error: .plot: no %s analysis found.\n", - plottype); + plottype); } } else if (ciprefix(".four", command->wl_word)) { if (terse) { fprintf(cp_out, - ".fourier line ignored since rawfile was produced.\n"); - } else if (setcplot("tran")) { - com_fourier(command->wl_next); - fprintf(cp_out, "\n\n"); - } else - fprintf(cp_err, - "No transient data available for fourier analysis"); + ".fourier line ignored since rawfile was produced.\n"); + } else { + int err; + + plot_cur = setcplot("tran"); + err = fourier(command->wl_next, plot_cur); + if (!err) + fprintf(cp_out, "\n\n"); + else + fprintf(cp_err, "No transient data available for " + "fourier analysis"); + } } else if (!eq(command->wl_word, ".save") - && !eq(command->wl_word, ".op") - && !eq(command->wl_word, ".tf")) + && !eq(command->wl_word, ".op") + && !eq(command->wl_word, ".tf")) { goto bad; } coms = coms->wl_next; } -nocmds: + nocmds: /* Now the node table */ if (ft_nodesprint) ; /* The options */ if (ft_optsprint) { - fprintf(cp_err, "Options:\n\n"); + fprintf(cp_out, "Options:\n\n"); cp_vprint(); (void) putc('\n', cp_out); } @@ -329,10 +360,11 @@ nocmds: } else com_rusage((wordlist *) NULL); - (void) putc('\n', cp_out); + putc('\n', cp_out); return 0; -bad: fprintf(cp_err, "Internal Error: ft_cktcoms: bad commands\n"); + bad: + fprintf(cp_err, "Internal Error: ft_cktcoms: bad commands\n"); return 1; } @@ -349,6 +381,7 @@ static void fixdotplot(wordlist *wl) { char buf[BSIZE_SP], *s; + char numbuf[128]; /* Printnum Fix */ double *d, d1, d2; while (wl) { @@ -379,13 +412,14 @@ fixdotplot(wordlist *wl) wl->wl_next = alloc(struct wordlist); wl->wl_next->wl_prev = wl; wl = wl->wl_next; - (void) strcpy(buf, printnum(d1)); - wl->wl_word = copy(buf); + + printnum(numbuf, d1); + wl->wl_word = copy(numbuf); wl->wl_next = alloc(struct wordlist); wl->wl_next->wl_prev = wl; wl = wl->wl_next; - (void) strcpy(buf, printnum(d2)); - wl->wl_word = copy(buf); + printnum(numbuf, d2); + wl->wl_word = copy(numbuf); } wl = wl->wl_next; } @@ -405,7 +439,8 @@ fixdotprint(wordlist *wl) static char * fixem(char *string) { - char buf[BSIZE_SP], *s, *t, *ss = string; + char buf[BSIZE_SP], *s, *t; + char *ss = string; /* Get rid of ss ? */ if (ciprefix("v(", string) &&strchr(string, ',')) { for (s = string; *s && (*s != ','); s++) @@ -469,94 +504,6 @@ fixem(char *string) return (string); } -/* Don't bother with ccom strangeness here. */ - -static bool -setcplot(char *name) -{ - struct plot *pl; - - for (pl = plot_list; pl; pl = pl->pl_next) { - if (ciprefix(name, pl->pl_typename)) { - plot_cur = pl; - return (TRUE); - } - } - return (FALSE); -} - -#ifdef notdef -static wordlist * -gettoks(s) - char *s; -{ - char *t, *r, buf[64]; - wordlist *wl = NULL, *end = NULL; - bool iflag; - - while (t = gettok(&s)) { - if (*t == '(' /* ) */) { - /* This is a (upper, lower) thing -- ignore. */ - continue; - } else if (!index(t, '(' /*)*/ )) { - if (end) { - end->wl_next = alloc(struct wordlist); - end->wl_next->wl_prev = end; - end = end->wl_next; - } else - wl = end = alloc(struct wordlist); - end->wl_word = copy(t); - } else if (!index(t, ',')) { - iflag = ((*t == 'i') || (*t == 'I')) ? TRUE : FALSE; - while (*t != '(' /*)*/) - t++; - t++; - for (r = t; *r && *r != /*(*/ ')'; r++) - ; - *r = '\0'; - if (end) { - end->wl_next = alloc(struct wordlist); - end->wl_next->wl_prev = end; - end = end->wl_next; - } else - wl = end = alloc(struct wordlist); - if (iflag) { - (void) sprintf(buf, "%s#branch", t); - t = buf; - } - end->wl_word = copy(t); - } else { - /* The painful case */ - while (*t != '(' /*)*/) - t++; - t++; - for (r = t; *r && *r != ','; r++) - ; - *r = '\0'; - if (end) { - end->wl_next = alloc(struct wordlist); - end->wl_next->wl_prev = end; - end = end->wl_next; - } else - wl = end = alloc(struct wordlist); - end->wl_word = copy(t); - t = r + 1; - for (r = t; *r && *r != /*(*/ ')'; r++) - ; - *r = '\0'; - if (end) { - end->wl_next = alloc(struct wordlist); - end->wl_next->wl_prev = end; - end = end->wl_next; - } else - wl = end = alloc(struct wordlist); - end->wl_word = copy(t); - } - } - return (wl); -} -#endif - static wordlist * gettoks(char *s) { diff --git a/src/frontend/evaluate.c b/src/frontend/evaluate.c index 92189e32f..45ed75169 100644 --- a/src/frontend/evaluate.c +++ b/src/frontend/evaluate.c @@ -7,14 +7,13 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group * Convert a parse tree to a list of data vectors. */ -#include "ngspice.h" -#include "cpdefs.h" -#include "ftedefs.h" -#include "ftedata.h" -#include "fteparse.h" -#include "ftecmath.h" #include #include + +#include +#include +#include + #include "evaluate.h" @@ -22,9 +21,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group static RETSIGTYPE sig_matherr(void); static struct dvec * apply_func(struct func *func, struct pnode *arg); static char * mkcname(char what, char *v1, char *v2); -static struct dvec * doop(char what, void *(*func) (/* ??? */), - struct pnode *arg1, struct pnode *arg2); - /* We are careful here to catch SIGILL and recognise them as math errors. @@ -47,7 +43,7 @@ sig_matherr(void) struct dvec * ft_evaluate(struct pnode *node) { - struct dvec *d; + struct dvec *d = NULL; if (!node) return (NULL); @@ -81,8 +77,226 @@ ft_evaluate(struct pnode *node) return (d); } -/* The binary operations. */ +/* Operate on two vectors, and return a third with the data, length, and flags + * fields filled in. Add it to the current plot and get rid of the two args. + */ + +static struct dvec * +doop(char what, + void*(*func) (void *data1, void *data2, + short int datatype1, short int datatype2, + int length), + struct pnode *arg1, + struct pnode *arg2) +{ + struct dvec *v1, *v2, *res; + complex *c1 = NULL, *c2 = NULL , lc; + double *d1 = NULL, *d2 = NULL, ld; + int length = 0, i; + void *data; + bool free1 = FALSE, free2 = FALSE, relflag = FALSE; + + v1 = ft_evaluate(arg1); + v2 = ft_evaluate(arg2); + if (!v1 || !v2) + return (NULL); + + /* Now the question is, what do we do when one or both of these + * has more than one vector? This is definitely not a good + * thing. For the time being don't do anything. + */ + if (v1->v_link2 || v2->v_link2) { + fprintf(cp_err, "Warning: no operations on wildcards yet.\n"); + if (v1->v_link2 && v2->v_link2) + fprintf(cp_err, "\t(You couldn't do that one anyway)\n"); + return (NULL); + } + + /* How do we handle operations on multi-dimensional vectors? + * For now, we only allow operations between one-D vectors, + * equivalently shaped multi-D vectors, or a multi-D vector and + * a one-D vector. It's not at all clear what to do in the other cases. + * So only check shape requirement if its an operation between two multi-D + * arrays. + */ + if ((v1->v_numdims > 1) && (v2->v_numdims > 1)) { + if (v1->v_numdims != v2->v_numdims) { + fprintf(cp_err, + "Warning: operands %s and %s have incompatible shapes.\n", + v1->v_name, v2->v_name); + return (NULL); + } + for (i = 1; i < v1->v_numdims; i++) { + if ((v1->v_dims[i] != v2->v_dims[i])) { + fprintf(cp_err, + "Warning: operands %s and %s have incompatible shapes.\n", + v1->v_name, v2->v_name); + return (NULL); + } + } + } + + /* This is a bad way to do this. */ + switch (what) { + case '=': + case '>': + case '<': + case 'G': + case 'L': + case 'N': + case '&': + case '|': + case '~': + relflag = TRUE; + } + + /* Don't bother to do type checking. Maybe this should go in at + * some point. + */ + + /* Make sure we have data of the same length. */ + length = ((v1->v_length > v2->v_length) ? v1->v_length : v2->v_length); + if (v1->v_length < length) { + free1 = TRUE; + if (isreal(v1)) { + ld = 0.0; + d1 = (double *) tmalloc(length * sizeof (double)); + for (i = 0; i < v1->v_length; i++) + d1[i] = v1->v_realdata[i]; + if (length > 0) + ld = v1->v_realdata[v1->v_length - 1]; + for ( ; i < length; i++) + d1[i] = ld; + } else { + realpart(&lc) = 0.0; + imagpart(&lc) = 0.0; + c1 = (complex *) tmalloc(length * sizeof (complex)); + for (i = 0; i < v1->v_length; i++) + c1[i] = v1->v_compdata[i]; + if (length > 0) + lc = v1->v_compdata[v1->v_length - 1]; + for ( ; i < length; i++) + c1[i] = lc; + } + } else + if (isreal(v1)) + d1 = v1->v_realdata; + else + c1 = v1->v_compdata; + if (v2->v_length < length) { + free2 = TRUE; + if (isreal(v2)) { + ld = 0.0; + d2 = (double *) tmalloc(length * sizeof (double)); + for (i = 0; i < v2->v_length; i++) + d2[i] = v2->v_realdata[i]; + if (length > 0) + ld = v2->v_realdata[v2->v_length - 1]; + for ( ; i < length; i++) + d2[i] = ld; + } else { + realpart(&lc) = 0.0; + imagpart(&lc) = 0.0; + c2 = (complex *) tmalloc(length * sizeof (complex)); + for (i = 0; i < v2->v_length; i++) + c2[i] = v2->v_compdata[i]; + if (length > 0) + lc = v2->v_compdata[v1->v_length - 1]; + for ( ; i < length; i++) + c2[i] = lc; + } + } else + if (isreal(v2)) + d2 = v2->v_realdata; + else + c2 = v2->v_compdata; + + /* Some of the math routines generate SIGILL if the argument is + * out of range. Catch this here. + */ + if (setjmp(matherrbuf)) { + return (NULL); + } + (void) signal(SIGILL, (SIGNAL_FUNCTION) sig_matherr); + + /* Now pass the vectors to the appropriate function. */ + data = ((*func) ((isreal(v1) ? (void *) d1 : (void *) c1), + (isreal(v2) ? (void *) d2 : (void *) c2), + (isreal(v1) ? VF_REAL : VF_COMPLEX), + (isreal(v2) ? VF_REAL : VF_COMPLEX), + length)); + /* Back to normal */ + (void) signal(SIGILL, SIG_DFL); + + if (!data) + return (NULL); + /* Make up the new vector. */ + res = alloc(struct dvec); + ZERO(res,struct dvec); + if (relflag || (isreal(v1) && isreal(v2) && (func != cx_comma))) { + res->v_flags = (v1->v_flags | v2->v_flags | + VF_REAL) & ~ VF_COMPLEX; + res->v_realdata = (double *) data; + } else { + res->v_flags = (v1->v_flags | v2->v_flags | + VF_COMPLEX) & ~ VF_REAL; + res->v_compdata = (complex *) data; + } + + res->v_name = mkcname(what, v1->v_name, v2->v_name); + res->v_length = length; + + /* This is a non-obvious thing */ + if (v1->v_scale != v2->v_scale) { + fprintf(cp_err, "Warning: scales of %s and %s are different.\n", + v1->v_name, v2->v_name); + res->v_scale = NULL; + } else + res->v_scale = v1->v_scale; + + /* Copy a few useful things */ + res->v_defcolor = v1->v_defcolor; + res->v_gridtype = v1->v_gridtype; + res->v_plottype = v1->v_plottype; + + /* Copy dimensions. */ + if (v1->v_numdims > v2->v_numdims) { + res->v_numdims = v1->v_numdims; + for (i = 0; i < v1->v_numdims; i++) + res->v_dims[i] = v1->v_dims[i]; + } else { + res->v_numdims = v2->v_numdims; + for (i = 0; i < v2->v_numdims; i++) + res->v_dims[i] = v2->v_dims[i]; + } + + /* This depends somewhat on what the operation is. XXX Should fix */ + res->v_type = v1->v_type; + vec_new(res); + + /* Free the temporary data areas we used, if we allocated any. */ + if (free1) { + if (isreal(v1)) { + tfree(d1); + } else { + tfree(c1); + } + } + if (free2) { + if (isreal(v2)) { + tfree(d2); + } else { + tfree(c2); + } + } + + return (res); +} + + + +/* The binary operations. */ struct dvec * op_plus(struct pnode *arg1, struct pnode *arg2) { @@ -476,6 +690,11 @@ apply_func(struct func *func, struct pnode *arg) } (void) signal(SIGILL, (SIGNAL_FUNCTION) sig_matherr); +#if 0 + /* FIXME: The call to (*func->fu_func) has too many arguments; + hence the compiler quits. How to circumvent this (without + losing function prototypes)? For now, these functions have + been disabled. */ if (eq(func->fu_name, "interpolate") || eq(func->fu_name, "deriv")) /* Ack */ { @@ -487,13 +706,16 @@ apply_func(struct func *func, struct pnode *arg) v->v_length, &len, &type, v->v_plot, plot_cur, v->v_dims[0])); } else { +#endif data = ((*func->fu_func) ((isreal(v) ? (void *) v->v_realdata : (void *) v->v_compdata), (short) (isreal(v) ? VF_REAL : VF_COMPLEX), v->v_length, &len, &type)); +#if 0 } +#endif /* Back to normal */ (void) signal(SIGILL, SIG_DFL); @@ -586,215 +808,3 @@ mkcname(char what, char *v1, char *v2) return (s); } -/* Operate on two vectors, and return a third with the data, length, and flags - * fields filled in. Add it to the current plot and get rid of the two args. - */ - -static struct dvec * -doop(char what, void*(*func) (/* ??? */), struct pnode *arg1, - struct pnode *arg2) -{ - struct dvec *v1, *v2, *res; - complex *c1, *c2, lc; - double *d1, *d2, ld; - int length, i; - void *data; - bool free1 = FALSE, free2 = FALSE, relflag = FALSE; - - v1 = ft_evaluate(arg1); - v2 = ft_evaluate(arg2); - if (!v1 || !v2) - return (NULL); - - /* Now the question is, what do we do when one or both of these - * has more than one vector? This is definitely not a good - * thing. For the time being don't do anything. - */ - if (v1->v_link2 || v2->v_link2) { - fprintf(cp_err, "Warning: no operations on wildcards yet.\n"); - if (v1->v_link2 && v2->v_link2) - fprintf(cp_err, "\t(You couldn't do that one anyway)\n"); - return (NULL); - } - - /* How do we handle operations on multi-dimensional vectors? - * For now, we only allow operations between one-D vectors, - * equivalently shaped multi-D vectors, or a multi-D vector and - * a one-D vector. It's not at all clear what to do in the other cases. - * So only check shape requirement if its an operation between two multi-D - * arrays. - */ - if ((v1->v_numdims > 1) && (v2->v_numdims > 1)) { - if (v1->v_numdims != v2->v_numdims) { - fprintf(cp_err, - "Warning: operands %s and %s have incompatible shapes.\n", - v1->v_name, v2->v_name); - return (NULL); - } - for (i = 1; i < v1->v_numdims; i++) { - if ((v1->v_dims[i] != v2->v_dims[i])) { - fprintf(cp_err, - "Warning: operands %s and %s have incompatible shapes.\n", - v1->v_name, v2->v_name); - return (NULL); - } - } - } - - /* This is a bad way to do this. */ - switch (what) { - case '=': - case '>': - case '<': - case 'G': - case 'L': - case 'N': - case '&': - case '|': - case '~': - relflag = TRUE; - } - - /* Don't bother to do type checking. Maybe this should go in at - * some point. - */ - - /* Make sure we have data of the same length. */ - length = ((v1->v_length > v2->v_length) ? v1->v_length : v2->v_length); - if (v1->v_length < length) { - free1 = TRUE; - if (isreal(v1)) { - ld = 0.0; - d1 = (double *) tmalloc(length * sizeof (double)); - for (i = 0; i < v1->v_length; i++) - d1[i] = v1->v_realdata[i]; - if (length > 0) - ld = v1->v_realdata[v1->v_length - 1]; - for ( ; i < length; i++) - d1[i] = ld; - } else { - realpart(&lc) = 0.0; - imagpart(&lc) = 0.0; - c1 = (complex *) tmalloc(length * sizeof (complex)); - for (i = 0; i < v1->v_length; i++) - c1[i] = v1->v_compdata[i]; - if (length > 0) - lc = v1->v_compdata[v1->v_length - 1]; - for ( ; i < length; i++) - c1[i] = lc; - } - } else - if (isreal(v1)) - d1 = v1->v_realdata; - else - c1 = v1->v_compdata; - if (v2->v_length < length) { - free2 = TRUE; - if (isreal(v2)) { - ld = 0.0; - d2 = (double *) tmalloc(length * sizeof (double)); - for (i = 0; i < v2->v_length; i++) - d2[i] = v2->v_realdata[i]; - if (length > 0) - ld = v2->v_realdata[v2->v_length - 1]; - for ( ; i < length; i++) - d2[i] = ld; - } else { - realpart(&lc) = 0.0; - imagpart(&lc) = 0.0; - c2 = (complex *) tmalloc(length * sizeof (complex)); - for (i = 0; i < v2->v_length; i++) - c2[i] = v2->v_compdata[i]; - if (length > 0) - lc = v2->v_compdata[v1->v_length - 1]; - for ( ; i < length; i++) - c2[i] = lc; - } - } else - if (isreal(v2)) - d2 = v2->v_realdata; - else - c2 = v2->v_compdata; - - /* Some of the math routines generate SIGILL if the argument is - * out of range. Catch this here. - */ - if (setjmp(matherrbuf)) { - return (NULL); - } - (void) signal(SIGILL, (SIGNAL_FUNCTION) sig_matherr); - - /* Now pass the vectors to the appropriate function. */ - data = ((*func) ((isreal(v1) ? (void *) d1 : (void *) c1), - (isreal(v2) ? (void *) d2 : (void *) c2), - (isreal(v1) ? VF_REAL : VF_COMPLEX), - (isreal(v2) ? VF_REAL : VF_COMPLEX), - length)); - /* Back to normal */ - (void) signal(SIGILL, SIG_DFL); - - if (!data) - return (NULL); - /* Make up the new vector. */ - res = alloc(struct dvec); - ZERO(res,struct dvec); - if (relflag || (isreal(v1) && isreal(v2) && (func != cx_comma))) { - res->v_flags = (v1->v_flags | v2->v_flags | - VF_REAL) & ~ VF_COMPLEX; - res->v_realdata = (double *) data; - } else { - res->v_flags = (v1->v_flags | v2->v_flags | - VF_COMPLEX) & ~ VF_REAL; - res->v_compdata = (complex *) data; - } - - res->v_name = mkcname(what, v1->v_name, v2->v_name); - res->v_length = length; - - /* This is a non-obvious thing */ - if (v1->v_scale != v2->v_scale) { - fprintf(cp_err, "Warning: scales of %s and %s are different.\n", - v1->v_name, v2->v_name); - res->v_scale = NULL; - } else - res->v_scale = v1->v_scale; - - /* Copy a few useful things */ - res->v_defcolor = v1->v_defcolor; - res->v_gridtype = v1->v_gridtype; - res->v_plottype = v1->v_plottype; - - /* Copy dimensions. */ - if (v1->v_numdims > v2->v_numdims) { - res->v_numdims = v1->v_numdims; - for (i = 0; i < v1->v_numdims; i++) - res->v_dims[i] = v1->v_dims[i]; - } else { - res->v_numdims = v2->v_numdims; - for (i = 0; i < v2->v_numdims; i++) - res->v_dims[i] = v2->v_dims[i]; - } - - /* This depends somewhat on what the operation is. XXX Should fix */ - res->v_type = v1->v_type; - vec_new(res); - - /* Free the temporary data areas we used, if we allocated any. */ - if (free1) { - if (isreal(v1)) { - tfree(d1); - } else { - tfree(c1); - } - } - if (free2) { - if (isreal(v2)) { - tfree(d2); - } else { - tfree(c2); - } - } - - return (res); -} - diff --git a/src/frontend/evaluate.h b/src/frontend/evaluate.h index 155805142..950389ca8 100644 --- a/src/frontend/evaluate.h +++ b/src/frontend/evaluate.h @@ -3,8 +3,11 @@ * 1999 E. Rouat ************/ -#ifndef EVALUATE_H_INCLUDED -#define EVALUATE_H_INCLUDED +#ifndef _EVALUATE_H +#define _EVALUATE_H + +#include +#include struct dvec * ft_evaluate(struct pnode *node); struct dvec * op_plus(struct pnode *arg1, struct pnode *arg2); diff --git a/src/frontend/fourier.c b/src/frontend/fourier.c index e68f3dde0..737323b11 100644 --- a/src/frontend/fourier.c +++ b/src/frontend/fourier.c @@ -12,11 +12,13 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" #include "fteparse.h" #include "sperror.h" #include "const.h" + #include "fourier.h" +#include "variable.h" /* static declarations */ @@ -29,12 +31,15 @@ static int CKTfour(int ndata, int numFreq, double *thd, double *Time, double *Va #define DEF_FOURGRIDSIZE 200 + /* CKTfour(ndata,numFreq,thd,Time,Value,FundFreq,Freq,Mag,Phase,nMag,nPhase) * len 10 ? inp inp inp out out out out out */ -void -com_fourier(wordlist *wl) +/* FIXME: This function leaks memory due to non local exit bypassing + freeing of memory at the end of the function. */ +int +fourier(wordlist *wl, struct plot *current_plot) { struct dvec *time, *vec; struct pnode *names, *first_name; @@ -47,11 +52,14 @@ com_fourier(wordlist *wl) char xbuf[20]; int shift; + if (!current_plot) + return 1; + sprintf(xbuf, "%1.1e", 0.0); shift = strlen(xbuf) - 7; - if (!plot_cur || !plot_cur->pl_scale) { + if (!current_plot || !current_plot->pl_scale) { fprintf(cp_err, "Error: no vectors loaded.\n"); - return; + return 1; } if ((!cp_getvar("nfreqs", VT_NUM, (char *) &nfreqs)) || (nfreqs < 1)) @@ -63,15 +71,15 @@ com_fourier(wordlist *wl) (fourgridsize < 1)) fourgridsize = DEF_FOURGRIDSIZE; - time = plot_cur->pl_scale; + time = current_plot->pl_scale; if (!isreal(time)) { fprintf(cp_err, "Error: fourier needs real time scale\n"); - return; + return 1; } s = wl->wl_word; if (!(ff = ft_numparse(&s, FALSE)) || (*ff <= 0.0)) { fprintf(cp_err, "Error: bad fund freq %s\n", wl->wl_word); - return; + return 1; } fundfreq = *ff; @@ -112,8 +120,8 @@ com_fourier(wordlist *wl) d = 1 / fundfreq; /* The wavelength... */ if (dp[1] - dp[0] < d) { fprintf(cp_err, - "Error: wavelength longer than time span\n"); - return; + "Error: wavelength longer than time span\n"); + return 1; } else if (dp[1] - dp[0] > d) { dp[0] = dp[1] - d; } @@ -129,7 +137,7 @@ com_fourier(wordlist *wl) polydegree)) { fprintf(cp_err, "Error: can't interpolate\n"); - return; + return 1; } timescale = grid; } else { @@ -143,7 +151,7 @@ com_fourier(wordlist *wl) nphase); if (err != OK) { ft_sperror(err, "fourier"); - return; + return 1; } fprintf(cp_out, "Fourier analysis for %s:\n", @@ -183,9 +191,18 @@ com_fourier(wordlist *wl) tfree(phase); tfree(nmag); tfree(nphase); - return; + return 0; } + +void +com_fourier(wordlist *wl) +{ + fourier(wl, plot_cur); +} + + + static char * pn(double num) { @@ -196,50 +213,54 @@ pn(double num) i = 6; if (num < 0.0) - (void) sprintf(buf, "%.*g", i - 1, num); + sprintf(buf, "%.*g", i - 1, num); else - (void) sprintf(buf, "%.*g", i, num); + sprintf(buf, "%.*g", i, num); return (copy(buf)); } -/* - * CKTfour() - perform fourier analysis of an output vector. - * Due to the construction of the program which places all the - * output data in the post-processor, the fourier analysis can not - * be done directly. This function allows the post processor to - * hand back vectors of time and data values to have the fourier analysis - * performed on them. + +/* CKTfour() - perform fourier analysis of an output vector. * - */ - - + * Due to the construction of the program which places all the output + * data in the post-processor, the fourier analysis can not be done + * directly. This function allows the post processor to hand back + * vectors of time and data values to have the fourier analysis + * performed on them. */ static int -CKTfour(int ndata, int numFreq, double *thd, double *Time, double *Value, double FundFreq, double *Freq, double *Mag, double *Phase, double *nMag, double *nPhase) - /* number of entries in the Time and Value arrays */ - /* number of harmonics to calculate */ - /* total harmonic distortion (percent) to be returned */ - /* times at which the voltage/current values were measured*/ - /* voltage or current vector whose transform is desired */ - /* the fundamental frequency of the analysis */ - /* the frequency value of the various harmonics */ - /* the Magnitude of the fourier transform */ - /* the Phase of the fourier transform */ - /* the normalized magnitude of the transform: nMag(fund)=1*/ - /* the normalized phase of the transform: Nphase(fund)=0 */ - /* note we can consider these as a set of arrays: The sizes are: - * Time[ndata], Value[ndata] - * Freq[numFreq],Mag[numfreq],Phase[numfreq],nMag[numfreq],nPhase[numfreq] +CKTfour(int ndata, /* number of entries in the Time and + Value arrays */ + int numFreq, /* number of harmonics to calculate */ + double *thd, /* total harmonic distortion (percent) + to be returned */ + double *Time, /* times at which the voltage/current + values were measured*/ + double *Value, /* voltage or current vector whose + transform is desired */ + double FundFreq, /* the fundamental frequency of the + analysis */ + double *Freq, /* the frequency value of the various + harmonics */ + double *Mag, /* the Magnitude of the fourier + transform */ + double *Phase, /* the Phase of the fourier transform */ + double *nMag, /* the normalized magnitude of the + transform: nMag(fund)=1*/ + double *nPhase) /* the normalized phase of the + transform: Nphase(fund)=0 */ +{ + /* Note: we can consider these as a set of arrays. The sizes are: + * Time[ndata], Value[ndata], Freq[numFreq], Mag[numfreq], + * Phase[numfreq], nMag[numfreq], nPhase[numfreq] + * * The arrays must all be allocated by the caller. * The Time and Value array must be reasonably distributed over at * least one full period of the fundamental Frequency for the * fourier transform to be useful. The function will take the * last period of the frequency as data for the transform. - */ - -{ -/* we are assuming that the caller has provided exactly one period - * of the fundamental frequency. - */ + * + * We are assuming that the caller has provided exactly one period + * of the fundamental frequency. */ int i; int j; double tmp; @@ -272,112 +293,3 @@ CKTfour(int ndata, int numFreq, double *thd, double *Time, double *Value, double *thd = 100*sqrt(*thd); return(OK); } - -#ifdef notdef - /* What is this code? An old DFT? */ - double initial; /* starting time */ - double final; /* final time */ - double elapsed; /* elapsed time */ - double tmp; - int start=0; - int n; - int m; - int edge; - - *thd = 0; - final = Time[ndata-1]; - initial = Time[0]; - elapsed = final - initial; - if( (elapsed-1/FundFreq)< -.01/FundFreq ){ - /* not enough data for a full period */ - return(E_BADPARM); - } - elapsed = 1/FundFreq; /* set to desired elapsed time */ - initial = final - elapsed; /* set to desired starting time */ - while(Time[start] initial) { - /* interesting case - need to handle previous point */ - /* first, make sure that there is a point on the other side of - * the beginning of time. - */ - if(start-2 < 0) { - /* point doesn't exist, so we have to fudge - * things slightly - by bumping edge up, we re-use the first - * point in the interval for the last point before the - * interval - should be only for very small error in - * interval boundaries, so shouldn't be significant, and is - * better than ignoring the interval - */ - edge = start-1; - } else { - edge = start-2; - } - for(m=0;m1) *thd += nMag[m] * nMag[m]; - } - *thd = 100 * sqrt(*thd); - return(OK); - -#endif diff --git a/src/frontend/fourier.h b/src/frontend/fourier.h index 597f7cf2f..e30e237b8 100644 --- a/src/frontend/fourier.h +++ b/src/frontend/fourier.h @@ -7,7 +7,6 @@ #define FOURIER_H_INCLUDED void com_fourier(wordlist *wl); - - +int fourier(wordlist *wl, struct plot *current); #endif diff --git a/src/frontend/gens.c b/src/frontend/gens.c index 7951bebbc..ed4779a91 100644 --- a/src/frontend/gens.c +++ b/src/frontend/gens.c @@ -16,7 +16,7 @@ static void dgen_next(dgen **dgx); void -wl_forall(wordlist *wl, int (*fn) (/* ??? */), char *data) +wl_forall(wordlist *wl, void (*fn) (/* ??? */), void *data) { while (wl) { (*fn)(wl, data); @@ -40,27 +40,6 @@ dgen_init(GENcircuit *ckt, wordlist *wl, int nomix, int flag, int model) prevp = &wl; -#ifdef notdef - for (w = wl; w; w = w->wl_next) { - if (!strcmp(w->wl_word, "#")) { - model = 1; - *prevp = w->wl_next; - flag |= DGEN_DEFDEVS; - } else if (index(w->wl_word, '#')) - model = 1; - else - instance = 1; - prevp = &w->wl_next; - } - - if (instance && model) { - fprintf(stderr, - "Error: can't mix instances and models"); - tfree(dg); - return NULL; - } -#endif - if (model) dg->flags = (DGEN_ALL & ~ DGEN_INSTANCE) | DGEN_INIT; else @@ -77,7 +56,7 @@ dgen_init(GENcircuit *ckt, wordlist *wl, int nomix, int flag, int model) } int -dgen_for_n(dgen *dg, int n, int (*fn) (/* ??? */), char *data, int subindex) +dgen_for_n(dgen *dg, int n, int (*fn) (/* ??? */), void *data, int subindex) { dgen dgx, *dgxp; int dnum, i, j, k; @@ -172,15 +151,7 @@ dgen_next(dgen **dgx) if (need & DGEN_MODEL && !dg->model) continue; -#ifdef notdef - if (dg->instance) - printf("Maybe : %s\n", dg->instance->GENname); - if (dg->model) - printf("Maybe mod : %s\n", dg->model->GENmodName); -#endif - /* Filter */ - if (!dg->dev_list) { if ((dg->flags & DGEN_ALLDEVS) || ((dg->flags & DGEN_DEFDEVS) @@ -263,11 +234,6 @@ dgen_next(dgen **dgx) } /* Now compare */ -#ifdef notdef - printf("Type: %c, subckt: %s, name: %s\n", - type ? type : '0', subckt, device); -#endif - if (dg->instance) dev_name = dg->instance->GENname; else @@ -334,13 +300,6 @@ dgen_next(dgen **dgx) break; } -#ifdef notdef - if (done == 1) - printf("Accepted\n"); - else - printf("Skipped\n"); -#endif - } if (done == 2) diff --git a/src/frontend/gens.h b/src/frontend/gens.h index c1c206b11..dd4848f45 100644 --- a/src/frontend/gens.h +++ b/src/frontend/gens.h @@ -6,9 +6,9 @@ #ifndef GENS_H_INCLUDED #define GENS_H_INCLUDED -void wl_forall(wordlist *wl, int (*fn) (/* ??? */), char *data); +void wl_forall(wordlist *wl, void (*fn) (/* ??? */), void *data); dgen * dgen_init(GENcircuit *ckt, wordlist *wl, int nomix, int flag, int model); -int dgen_for_n(dgen *dg, int n, int (*fn) (/* ??? */), char *data, int subindex); +int dgen_for_n(dgen *dg, int n, int (*fn) (/* ??? */), void *data, int subindex); void dgen_nth_next(dgen **dg, int n); diff --git a/src/frontend/inp.c b/src/frontend/inp.c index 66e626b3c..3cae141c8 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -3,6 +3,12 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Wayne A. Christopher **********/ +/* + * SJB 22 May 2001 + * Fixed memory leaks accociated with freeing memory used by lines in the input deck + * in inp_spsource(). New line_free() routine added to help with this. + */ + /* * Stuff for dealing with spice input decks and command scripts, and * the listing routines. @@ -12,11 +18,20 @@ Author: 1985 Wayne A. Christopher #include "cpdefs.h" #include "inpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" #include "fteinp.h" #include "inp.h" +#include "circuits.h" +#include "completion.h" +#include "variable.h" +#ifdef XSPICE +/* gtri - add - 12/12/90 - wbk - include new stuff */ +#include "ipctiein.h" +#include "enh.h" +/* gtri - end - 12/12/90 */ +#endif /* static declarations */ static char * upper(register char *string); @@ -71,8 +86,9 @@ com_listing(wordlist *wl) return; } + static char * -upper(register char *string) +upper(char *string) { static char buf[BSIZE_SP]; @@ -89,11 +105,10 @@ upper(register char *string) } -/* Provide an input listing on the specified file of the given - * card deck. The listing should be of either LS_PHYSICAL or LS_LOGICAL - * or LS_DECK lines as specified by the type parameter. - */ +/* Provide an input listing on the specified file of the given card + * deck. The listing should be of either LS_PHYSICAL or LS_LOGICAL or + * LS_DECK lines as specified by the type parameter. */ void inp_list(FILE *file, struct line *deck, struct line *extras, int type) { @@ -102,12 +117,20 @@ inp_list(FILE *file, struct line *deck, struct line *extras, int type) bool renumber; bool useout = (file == cp_out); int i = 1; +/* gtri - wbk - 03/07/91 - Don't use 'more' type output if ipc enabled */ +#ifdef XSPICE + if(g_ipc.enabled) { + useout = FALSE; + } +#endif +/* gtri - end - 03/07/91 */ if (useout) out_init(); - (void) cp_getvar("renumber", VT_BOOL, (char *) &renumber); + cp_getvar("renumber", VT_BOOL, (char *) &renumber); if (type == LS_LOGICAL) { -top1: for (here = deck; here; here = here->li_next) { +top1: + for (here = deck; here; here = here->li_next) { if (renumber) here->li_linenum = i; i++; @@ -119,10 +142,7 @@ top1: for (here = deck; here; here = here->li_next) { sprintf(out_pbuf, "%6d : %s\n", here->li_linenum, upper(here->li_line)); - out_send(out_pbuf); -/* out_printf("%6d : %s\n", - here->li_linenum, - upper(here->li_line)); */ + out_send(out_pbuf); } else fprintf(file, "%6d : %s\n", here->li_linenum, @@ -141,13 +161,13 @@ top1: for (here = deck; here; here = here->li_next) { goto top1; } if (useout) { -/* out_printf("%6d : .end\n", i); */ sprintf(out_pbuf, "%6d : .end\n", i); out_send(out_pbuf); } else fprintf(file, "%6d : .end\n", i); } else if ((type == LS_PHYSICAL) || (type == LS_DECK)) { -top2: for (here = deck; here; here = here->li_next) { +top2: + for (here = deck; here; here = here->li_next) { if ((here->li_actual == NULL) || (here == deck)) { if (renumber) here->li_linenum = i; @@ -158,28 +178,28 @@ top2: for (here = deck; here; here = here->li_next) { if (type == LS_PHYSICAL) { if (useout) { sprintf(out_pbuf, "%6d : %s\n", - here->li_linenum, - upper(here->li_line)); - out_send(out_pbuf); + here->li_linenum, + upper(here->li_line)); + out_send(out_pbuf); } else fprintf(file, "%6d : %s\n", - here->li_linenum, - upper(here->li_line)); + here->li_linenum, + upper(here->li_line)); } else { if (useout) out_printf("%s\n", - upper(here->li_line)); + upper(here->li_line)); else fprintf(file, "%s\n", - upper(here->li_line)); + upper(here->li_line)); } if (here->li_error && (type == LS_PHYSICAL)) { if (useout) out_printf("%s\n", - here->li_error); + here->li_error); else fprintf(file, "%s\n", - here->li_error); + here->li_error); } } else { for (there = here->li_actual; there; @@ -191,13 +211,13 @@ top2: for (here = deck; here; here = here->li_next) { if (type == LS_PHYSICAL) { if (useout) { sprintf(out_pbuf, "%6d : %s\n", - there->li_linenum, - upper(there->li_line)); - out_send(out_pbuf); + there->li_linenum, + upper(there->li_line)); + out_send(out_pbuf); } else fprintf(file, "%6d : %s\n", - there->li_linenum, - upper(there->li_line)); + there->li_linenum, + upper(there->li_line)); } else { if (useout) out_printf("%s\n", @@ -242,18 +262,36 @@ top2: for (here = deck; here; here = here->li_next) { return; } -/* The routine to source a spice input deck. We read the deck in, take out - * the front-end commands, and create a CKT structure. Also we filter out - * the following cards: .save, .width, .four, .print, and .plot, to perform - * after the run is over. +/* + * Free memory used by a line. + * If recure is TRUE then recursivly free all lines linked via the li_next field. + * If recurse is FALSE free only this line. + * All lines linked via the li_actual field are always recursivly freed. + * SJB - 22nd May 2001 */ +void +line_free(struct line * deck, bool recurse) { + if(!deck) + return; + tfree(deck->li_line); + tfree(deck->li_error); + if(recurse) + line_free(deck->li_next,TRUE); + line_free(deck->li_actual,TRUE); + tfree(deck); +} + +/* The routine to source a spice input deck. We read the deck in, take + * out the front-end commands, and create a CKT structure. Also we + * filter out the following cards: .save, .width, .four, .print, and + * .plot, to perform after the run is over. */ void inp_spsource(FILE *fp, bool comfile, char *filename) { struct line *deck, *dd, *ld; - struct line *realdeck, *options; - char *tt, name[BSIZE_SP], *s, *t; + struct line *realdeck, *options = NULL; + char *tt = NULL, name[BSIZE_SP], *s, *t; bool nosubckts, commands = FALSE; wordlist *wl = NULL, *end = NULL, *wl_first = NULL; wordlist *controls = NULL; @@ -263,7 +301,7 @@ inp_spsource(FILE *fp, bool comfile, char *filename) inp_readall(fp, &deck); if (!deck) { /* MW. We must close fp always when returning */ - (void) fclose(fp); + fclose(fp); return; } @@ -280,11 +318,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename) } fclose(fp); - /* Now save the IO context and start a new control set. After - * we are done with the source we'll put the old file descriptors - * back. I guess we could use a FILE stack, but since this routine - * is recursive anyway. - */ + /* Now save the IO context and start a new control set. After we + * are done with the source we'll put the old file descriptors + * back. I guess we could use a FILE stack, but since this + * routine is recursive anyway. */ lastin = cp_curin; lastout = cp_curout; lasterr = cp_curerr; @@ -294,13 +331,11 @@ inp_spsource(FILE *fp, bool comfile, char *filename) cp_pushcontrol(); - /* We should now go through the deck and execute front-end + /* We should now go through the deck and execute front-end * commands and remove them. Front-end commands are enclosed by - * the cards .control and .endc, unless comfile - * is TRUE, in which case every line must be a front-end command. - * There are too many problems with matching the first word on - * the line. - */ + * the cards .control and .endc, unless comfile is TRUE, in which + * case every line must be a front-end command. There are too + * many problems with matching the first word on the line. */ ld = deck; if (comfile) { /* This is easy. */ @@ -311,12 +346,13 @@ inp_spsource(FILE *fp, bool comfile, char *filename) if (!ciprefix(".control", dd->li_line) && !ciprefix(".endc", dd->li_line)) { if (dd->li_line[0] == '*') - (void) cp_evloop(dd->li_line + 2); + cp_evloop(dd->li_line + 2); else - (void) cp_evloop(dd->li_line); + cp_evloop(dd->li_line); } - tfree(dd->li_line); - tfree(dd); + line_free(dd,FALSE); /* SJB - free this line's memory */ + /* tfree(dd->li_line); + tfree(dd); */ } } else { for (dd = deck->li_next; dd; dd = ld->li_next) { @@ -326,7 +362,7 @@ inp_spsource(FILE *fp, bool comfile, char *filename) ld = dd; continue; } - (void) strncpy(name, dd->li_line, BSIZE_SP); + strncpy(name, dd->li_line, BSIZE_SP); for (s = name; *s && isspace(*s); s++) ; for (t = s; *t && !isspace(*t); t++) @@ -335,17 +371,19 @@ inp_spsource(FILE *fp, bool comfile, char *filename) if (ciprefix(".control", dd->li_line)) { ld->li_next = dd->li_next; - tfree(dd->li_line); - tfree(dd); + line_free(dd,FALSE); /* SJB - free this line's memory */ + /* tfree(dd->li_line); + tfree(dd); */ if (commands) - fprintf(cp_err, - "Warning: redundant .control card\n"); + fprintf(cp_err, + "Warning: redundant .control card\n"); else commands = TRUE; } else if (ciprefix(".endc", dd->li_line)) { ld->li_next = dd->li_next; - tfree(dd->li_line); - tfree(dd); + line_free(dd,FALSE); /* SJB - free this line's memory */ +/* tfree(dd->li_line); + tfree(dd); */ if (commands) commands = FALSE; else @@ -361,23 +399,30 @@ inp_spsource(FILE *fp, bool comfile, char *filename) controls = wl; if (prefix("*#", dd->li_line)) wl->wl_word = copy(dd->li_line + 2); - else + else { wl->wl_word = dd->li_line; + dd->li_line = 0; /* SJB - prevent line_free() freeing the string (now pointed at by wl->wl_word) */ + } ld->li_next = dd->li_next; - tfree(dd); + line_free(dd,FALSE); /* SJB - free this line's memory */ +/* tfree(dd); */ } else if (!*dd->li_line) { - /* So blank lines in com files don't get - * considered as circuits. - */ + /* So blank lines in com files don't get considered as + * circuits. */ ld->li_next = dd->li_next; - tfree(dd->li_line); - tfree(dd); + line_free(dd,FALSE); /* SJB - free this line's memory */ +/* tfree(dd->li_line); + tfree(dd); */ } else { inp_casefix(s); inp_casefix(dd->li_line); - if (eq(s, ".width") || ciprefix(".four", s) || eq(s, ".plot") - || eq(s, ".print") || eq(s, ".save") - || eq(s, ".op") || eq(s, ".tf")) + if (eq(s, ".width") + || ciprefix(".four", s) + || eq(s, ".plot") + || eq(s, ".print") + || eq(s, ".save") + || eq(s, ".op") + || eq(s, ".tf")) { if (end) { end->wl_next = alloc(struct wordlist); @@ -389,8 +434,9 @@ inp_spsource(FILE *fp, bool comfile, char *filename) if (!eq(s, ".op") && !eq(s, ".tf")) { ld->li_next = dd->li_next; - tfree(dd->li_line); - tfree(dd); + line_free(dd,FALSE); /* SJB - free this line's memory */ +/* tfree(dd->li_line); + tfree(dd); */ } else ld = dd; } else @@ -401,33 +447,41 @@ inp_spsource(FILE *fp, bool comfile, char *filename) /* There is something left after the controls. */ fprintf(cp_out, "\nCircuit: %s\n\n", tt); - /* Now expand subcircuit macros. Note that we have to - * fix the case before we do this but after we - * deal with the commands. - */ - if (!cp_getvar("nosubckt", VT_BOOL, (char *) - &nosubckts)) - deck->li_next = inp_subcktexpand(deck-> - li_next); +#ifdef XSPICE +/* gtri - wbk - Translate all SPICE 2G6 polynomial type sources */ + deck->li_next = ENHtranslate_poly(deck->li_next); +/* gtri - end - Translate all SPICE 2G6 polynomial type sources */ +#endif + + /* Now expand subcircuit macros. Note that we have to fix + * the case before we do this but after we deal with the + * commands. */ + if (!cp_getvar("nosubckt", VT_BOOL, (char *) &nosubckts)) + if((deck->li_next = inp_subcktexpand(deck->li_next)) == NULL){ + line_free(realdeck,TRUE); + line_free(deck->li_actual, TRUE); + return; + } + line_free(deck->li_actual,FALSE); /* SJB - free memory used by old li_actual (if any) */ deck->li_actual = realdeck; inp_dodeck(deck, tt, wl_first, FALSE, options, filename); } /* Now that the deck is loaded, do the commands */ if (controls) { - for (end = wl = wl_reverse(controls); wl; - wl = wl->wl_next) - (void) cp_evloop(wl->wl_word); - + for (end = wl = wl_reverse(controls); wl; wl = wl->wl_next) + cp_evloop(wl->wl_word); + wl_free(end); - /* MW. Memory leak fixed here */ - } } + /*saj, to process save commands always, not just in batch mode + *(breaks encapsulation of frountend and parsing commands slightly)*/ + ft_dotsaves(); + /* Now reset everything. Pop the control stack, and fix up the IO - * as it was before the source. - */ + * as it was before the source. */ cp_popcontrol(); cp_curin = lastin; @@ -436,14 +490,14 @@ inp_spsource(FILE *fp, bool comfile, char *filename) return; } -/* This routine is cut in half here because com_rset has to do what follows - * also. End is the list of commands we execute when the job is finished: - * we only bother with this if we might be running in batch mode, since - * it isn't much use otherwise. - */ +/* This routine is cut in half here because com_rset has to do what + * follows also. End is the list of commands we execute when the job + * is finished: we only bother with this if we might be running in + * batch mode, since it isn't much use otherwise. */ void -inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, struct line *options, char *filename) +inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, + struct line *options, char *filename) { struct circ *ct; struct line *dd; @@ -454,8 +508,7 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, struct line * bool noparse, ii; /* First throw away any old error messages there might be and fix - * the case of the lines. - */ + * the case of the lines. */ for (dd = deck; dd; dd = dd->li_next) { if (dd->li_error) { tfree(dd->li_error); @@ -473,7 +526,7 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, struct line * } ft_curckt = ct = alloc(struct circ); } - (void) cp_getvar("noparse", VT_BOOL, (char *) &noparse); + cp_getvar("noparse", VT_BOOL, (char *) &noparse); if (!noparse) ckt = if_inpdeck(deck, &tab); else @@ -483,6 +536,10 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, struct line * for (dd = deck; dd; dd = dd->li_next) if (dd->li_error) { char *p, *q; +#ifdef XSPICE +/* gtri - modify - 12/12/90 - wbk - add setting of ipc syntax error flag */ g_ipc.syntax_error = IPC_TRUE; +#endif +/* gtri - end - 12/12/90 */ p = dd->li_error; do { q =strchr(p, '\n'); @@ -501,25 +558,18 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, struct line * } while (p && *p); } - /* Add this circuit to the circuit list. If reuse is TRUE then - * use the ft_curckt structure. - */ - + /* Add this circuit to the circuit list. If reuse is TRUE then use + * the ft_curckt structure. */ if (!reuse) { -#ifdef notdef - /* Unused time-waster. */ - for (dd = deck->li_next; dd; dd = dd->li_next) - if_setndnames(dd->li_line); -#endif - /* Be sure that ci_devices and ci_nodes are valid */ ft_curckt->ci_devices = cp_kwswitch(CT_DEVNAMES, (char *) NULL); - (void) cp_kwswitch(CT_DEVNAMES, ft_curckt->ci_devices); + cp_kwswitch(CT_DEVNAMES, ft_curckt->ci_devices); ft_curckt->ci_nodes = cp_kwswitch(CT_NODENAMES, (char *) NULL); - (void) cp_kwswitch(CT_NODENAMES, ft_curckt->ci_nodes); + cp_kwswitch(CT_NODENAMES, ft_curckt->ci_nodes); ft_newcirc(ct); - /* ft_setccirc(); */ ft_curckt = ct; + /* Assign current circuit */ + ft_curckt = ct; } ct->ci_name = tt; ct->ci_deck = deck; @@ -582,11 +632,10 @@ inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, struct line * return; } -/* Edit and re-load the current input deck. Note that if these commands are - * used on a non-unix machine, they will leave spice.tmp junk files lying - * around. - */ +/* Edit and re-load the current input deck. Note that if these + * commands are used on a non-unix machine, they will leave spice.tmp + * junk files lying around. */ void com_edit(wordlist *wl) { @@ -626,8 +675,9 @@ com_edit(wordlist *wl) inp_list(fp, ft_curckt->ci_deck, ft_curckt->ci_options, LS_DECK); fprintf(cp_err, - "Warning: editing a temporary file -- circuit not saved\n"); - (void) fclose(fp); + "Warning: editing a temporary file -- " + "circuit not saved\n"); + fclose(fp); } else if (!ft_curckt) { if (!(fp = fopen(filename, "w"))) { perror(filename); @@ -635,7 +685,7 @@ com_edit(wordlist *wl) return; } fprintf(fp, "SPICE 3 test deck\n"); - (void) fclose(fp); + fclose(fp); } if (!doedit(filename)) { cp_interactive = inter; @@ -649,11 +699,11 @@ com_edit(wordlist *wl) } inp_spsource(fp, FALSE, permfile ? filename : (char *) NULL); - /* (void) fclose(fp); */ + /* fclose(fp); */ /* MW. inp_spsource already closed fp */ if (ft_curckt && !ft_curckt->ci_filename) - (void) unlink(filename); + unlink(filename); } cp_interactive = inter; @@ -662,7 +712,7 @@ com_edit(wordlist *wl) fprintf(cp_out, "run circuit? "); fflush(cp_out); - (void) fgets(buf, BSIZE_SP, stdin); + fgets(buf, BSIZE_SP, stdin); if (buf[0] != 'n') { fprintf(cp_out, "running circuit\n"); com_run(NULL); @@ -683,10 +733,10 @@ doedit(char *filename) if (Def_Editor && *Def_Editor) editor = Def_Editor; else - editor = "/usr/ucb/vi"; + editor = "/usr/bin/vi"; } } - (void) sprintf(buf, "%s %s", editor, filename); + sprintf(buf, "%s %s", editor, filename); return (system(buf) ? FALSE : TRUE); } @@ -716,17 +766,17 @@ com_source(wordlist *wl) while (wl) { if (!(tp = inp_pathopen(wl->wl_word, "r"))) { perror(wl->wl_word); - (void) fclose(fp); + fclose(fp); cp_interactive = TRUE; - (void) unlink(tempfile); + unlink(tempfile); return; } while ((i = fread(buf, 1, BSIZE_SP, tp)) > 0) - (void) fwrite(buf, 1, i, fp); - (void) fclose(tp); + fwrite(buf, 1, i, fp); + fclose(tp); wl = wl->wl_next; } - (void) fseek(fp, (long) 0, 0); + fseek(fp, (long) 0, 0); } else fp = inp_pathopen(wl->wl_word, "r"); if (fp == NULL) { @@ -743,7 +793,7 @@ com_source(wordlist *wl) inp_spsource(fp, FALSE, tempfile ? (char *) NULL : wl->wl_word); cp_interactive = inter; if (tempfile) - (void) unlink(tempfile); + unlink(tempfile); return; } diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index bef3c6203..36fea0592 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -6,16 +6,32 @@ Author: 1985 Wayne A. Christopher /* * For dealing with spice input decks and command scripts */ + +/* + * SJB 22 May 2001 + * Fixed memory leaks in inp_readall() when first(?) line of input begins with a '@'. + * Fixed memory leaks in inp_readall() when .include lines have errors + * Fixed crash where a NULL pointer gets freed in inp_readall() + */ #include #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" #include "fteinp.h" -#include "inpcom.h" +#include "inpcom.h" +#include "variable.h" + +#ifdef XSPICE +/* gtri - add - 12/12/90 - wbk - include new stuff */ +#include "ipctiein.h" +#include "enh.h" +/* gtri - end - 12/12/90 */ +#endif + /* This routine reads a line (of arbitrary length), up to a '\n' or 'EOF' * and returns a pointer to the resulting null terminated string. * The '\n' if found, is included in the returned string. @@ -54,7 +70,7 @@ readline(FILE *fd) } } if (!strlen) { - free(strptr); + tfree(strptr); return (NULL); } strptr[strlen] = '\0'; @@ -108,14 +124,54 @@ inp_pathopen(char *name, char *mode) void inp_readall(FILE *fp, struct line **data) { - struct line *end = NULL, *cc, *prev = NULL, *working, *newcard; + struct line *end = NULL, *cc = NULL, *prev = NULL, *working, *newcard; char *buffer, *s, *t, c; + /* segfault fix */ + char *copys=NULL; int line = 1; FILE *newfp; +/* gtri - modify - 12/12/90 - wbk - read from mailbox if ipc enabled */ +#ifdef XSPICE + Ipc_Status_t ipc_status; + char ipc_buffer[1025]; /* Had better be big enough */ + int ipc_len; + + while (1) { + + /* If IPC is not enabled, do equivalent of what SPICE did before */ + if(! g_ipc.enabled) { + buffer = readline(fp); + if(! buffer) + break; + } + else { + /* else, get the line from the ipc channel. */ + /* We assume that newlines are not sent by the client */ + /* so we add them here */ + ipc_status = ipc_get_line(ipc_buffer, &ipc_len, IPC_WAIT); + if(ipc_status == IPC_STATUS_END_OF_DECK) { + buffer = NULL; + break; + } + else if(ipc_status == IPC_STATUS_OK) { + buffer = (void *) MALLOC(strlen(ipc_buffer) + 3); + strcpy(buffer, ipc_buffer); + strcat(buffer, "\n"); + } + else { /* No good way to report this so just die */ + exit(1); + } + } + +/* gtri - end - 12/12/90 */ +#else while ((buffer = readline(fp))) { - if (*buffer == '@') +#endif + if (*buffer == '@') { + tfree(buffer); /* was allocated by readline() */ break; + } for (s = buffer; *s && (*s != '\n'); s++) ; if (!*s) { @@ -129,19 +185,34 @@ inp_readall(FILE *fp, struct line **data) while (isspace(*s)) s++; if (!*s) { - fprintf(cp_err, - "Error: .include filename missing\n"); + fprintf(cp_err, "Error: .include filename missing\n"); + tfree(buffer); /* was allocated by readline() */ continue; } for (t = s; *t && !isspace(*t); t++) ; *t = '\0'; - if (*s == '~') - s = cp_tildexpand(s); + + if (*s == '~') { + copys = cp_tildexpand(s); /* allocates memory, but can also return NULL */ + if(copys != NULL) { + s = copys; /* reuse s, but remember, buffer still points to allocated memory */ + } + } + if (!(newfp = inp_pathopen(s, "r"))) { perror(s); + if(copys) { + tfree(copys); /* allocated by the cp_tildexpand() above */ + } + tfree(buffer); /* allocated by readline() above */ continue; } + + if(copys) { + tfree(copys); /* allocated by the cp_tildexpand() above */ + } + inp_readall(newfp, &newcard); (void) fclose(newfp); @@ -242,8 +313,9 @@ inp_readall(FILE *fp, struct line **data) return; } + void -inp_casefix(register char *string) +inp_casefix(char *string) { #ifdef HAVE_CTYPE_H if (string) @@ -254,8 +326,10 @@ inp_casefix(register char *string) #endif if (*string == '"') { *string++ = ' '; - while (*string && *string != '"') string++; - if (*string == '"') *string = ' '; + while (*string && *string != '"') + string++; + if (*string == '"') + *string = ' '; } if (!isspace(*string) && !isprint(*string)) *string = '_'; diff --git a/src/frontend/interp.c b/src/frontend/interp.c index b5957d1d5..d24177ae4 100644 --- a/src/frontend/interp.c +++ b/src/frontend/interp.c @@ -10,338 +10,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" #include "interp.h" -/* Interpolate data from oscale to nscale. data is assumed to be olen long, - * ndata will be nlen long. Returns FALSE if the scales are too strange - * to deal with. Note that we are guaranteed that either both scales are - * strictly increasing or both are strictly decreasing. - */ - - -/* static declarations */ -static int putinterval(double *poly, int degree, double *nvec, int last, double *nscale, - int nlen, double oval, int sign); -static void printmat(char *name, double *mat, int m, int n); - - -bool -ft_interpolate(double *data, double *ndata, double *oscale, int olen, double *nscale, int nlen, int degree) -{ - double *result, *scratch, *xdata, *ydata; - int sign, lastone, i, l; - - if ((olen < 2) || (nlen < 2)) { - fprintf(cp_err, "Error: lengths too small to interpolate.\n"); - return (FALSE); - } - if ((degree < 1) || (degree > olen)) { - fprintf(cp_err, "Error: degree is %d, can't interpolate.\n", - degree); - return (FALSE); - } - - if (oscale[1] < oscale[0]) - sign = -1; - else - sign = 1; - - scratch = (double *) tmalloc((degree + 1) * (degree + 2) * - sizeof (double)); - result = (double *) tmalloc((degree + 1) * sizeof (double)); - xdata = (double *) tmalloc((degree + 1) * sizeof (double)); - ydata = (double *) tmalloc((degree + 1) * sizeof (double)); - - /* Deal with the first degree pieces. */ - bcopy((char *) data, (char *) ydata, (degree + 1) * sizeof (double)); - bcopy((char *) oscale, (char *) xdata, (degree + 1) * sizeof (double)); - - while (!ft_polyfit(xdata, ydata, result, degree, scratch)) { - /* If it doesn't work this time, bump the interpolation - * degree down by one. - */ - - if (--degree == 0) { - fprintf(cp_err, "ft_interpolate: Internal Error.\n"); - return (FALSE); - } - - } - - /* Add this part of the curve. What we do is evaluate the polynomial - * at those points between the last one and the one that is greatest, - * without being greater than the leftmost old scale point, or least - * if the scale is decreasing at the end of the interval we are looking - * at. - */ - lastone = -1; - for (i = 0; i < degree; i++) { - lastone = putinterval(result, degree, ndata, lastone, - nscale, nlen, xdata[i], sign); - } - - /* Now plot the rest, piece by piece. l is the - * last element under consideration. - */ - for (l = degree + 1; l < olen; l++) { - - /* Shift the old stuff by one and get another value. */ - for (i = 0; i < degree; i++) { - xdata[i] = xdata[i + 1]; - ydata[i] = ydata[i + 1]; - } - ydata[i] = data[l]; - xdata[i] = oscale[l]; - - while (!ft_polyfit(xdata, ydata, result, degree, scratch)) { - if (--degree == 0) { - fprintf(cp_err, - "interpolate: Internal Error.\n"); - return (FALSE); - } - } - lastone = putinterval(result, degree, ndata, lastone, - nscale, nlen, xdata[i], sign); - } - if (lastone < nlen - 1) /* ??? */ - ndata[nlen - 1] = data[olen - 1]; - tfree(scratch); - tfree(xdata); - tfree(ydata); - tfree(result); - return (TRUE); -} - -/* Takes n = (degree+1) doubles, and fills in result with the n coefficients - * of the polynomial that will fit them. It also takes a pointer to an - * array of n ^ 2 + n doubles to use for scratch -- we want to make this - * fast and avoid doing mallocs for each call. - */ - -bool -ft_polyfit(double *xdata, double *ydata, double *result, int degree, double *scratch) -{ - register double *mat1 = scratch; - register int l, k, j, i; - register int n = degree + 1; - register double *mat2 = scratch + n * n; /* XXX These guys are hacks! */ - double d; - -/* -fprintf(cp_err, "n = %d, xdata = ( ", n); - for (i = 0; i < n; i++) - fprintf(cp_err, "%G ", xdata[i]); - fprintf(cp_err, ")\n"); - fprintf(cp_err, "ydata = ( "); - for (i = 0; i < n; i++) - fprintf(cp_err, "%G ", ydata[i]); - fprintf(cp_err, ")\n"); -*/ - - bzero((char *) result, n * sizeof(double)); - bzero((char *) mat1, n * n * sizeof (double)); - bcopy((char *) ydata, (char *) mat2, n * sizeof (double)); - - /* Fill in the matrix with x^k for 0 <= k <= degree for each point */ - l = 0; - for (i = 0; i < n; i++) { - d = 1.0; - for (j = 0; j < n; j++) { - mat1[l] = d; - d *= xdata[i]; - l += 1; - } - } - - /* Do Gauss-Jordan elimination on mat1. */ - for (i = 0; i < n; i++) { - int lindex; - double largest; - /* choose largest pivot */ - for (j=i, largest = mat1[i * n + i], lindex = i; j < n; j++) { - if (fabs(mat1[j * n + i]) > largest) { - largest = fabs(mat1[j * n + i]); - lindex = j; - } - } - if (lindex != i) { - /* swap rows i and lindex */ - for (k = 0; k < n; k++) { - d = mat1[i * n + k]; - mat1[i * n + k] = mat1[lindex * n + k]; - mat1[lindex * n + k] = d; - } - d = mat2[i]; - mat2[i] = mat2[lindex]; - mat2[lindex] = d; - } -#ifdef notdef - if (mat1[i * n + i] == 0.0) - for (j = i; j < n; j++) - if (mat1[j * n + i] != 0.0) { - /* Swap rows i and j. */ - for (k = 0; k < n; k++) { - d = mat1[i * n + k]; - mat1[i * n + k] = - mat1[j * n + k]; - mat1[j * n + k] = d; - } - d = mat2[i]; - mat2[i] = mat2[j]; - mat2[j] = d; - break; - } -#endif - /* Make sure we have a non-zero pivot. */ - if (mat1[i * n + i] == 0.0) { - /* this should be rotated. */ - return (FALSE); - } - for (j = i + 1; j < n; j++) { - d = mat1[j * n + i] / mat1[i * n + i]; - for (k = 0; k < n; k++) - mat1[j * n + k] -= d * mat1[i * n + k]; - mat2[j] -= d * mat2[i]; - } - } - - for (i = n - 1; i > 0; i--) - for (j = i - 1; j >= 0; j--) { - d = mat1[j * n + i] / mat1[i * n + i]; - for (k = 0; k < n; k++) - mat1[j * n + k] -= - d * mat1[i * n + k]; - mat2[j] -= d * mat2[i]; - } - - /* Now write the stuff into the result vector. */ - for (i = 0; i < n; i++) { - result[i] = mat2[i] / mat1[i * n + i]; - /* printf(cp_err, "result[%d] = %G\n", i, result[i]);*/ - } - -#define ABS_TOL 0.001 -#define REL_TOL 0.001 - - /* Let's check and make sure the coefficients are ok. If they aren't, - * just return FALSE. This is not the best way to do it. - */ - for (i = 0; i < n; i++) { - d = ft_peval(xdata[i], result, degree); - if (fabs(d - ydata[i]) > ABS_TOL) { - /* - fprintf(cp_err, - "Error: polyfit: x = %le, y = %le, int = %le\n", - xdata[i], ydata[i], d); - printmat("mat1", mat1, n, n); - printmat("mat2", mat2, n, 1); - */ - return (FALSE); - } else if (fabs(d - ydata[i]) / (fabs(d) > ABS_TOL ? fabs(d) : - ABS_TOL) > REL_TOL) { - /* - fprintf(cp_err, - "Error: polyfit: x = %le, y = %le, int = %le\n", - xdata[i], ydata[i], d); - printmat("mat1", mat1, n, n); - printmat("mat2", mat2, n, 1); - */ - return (FALSE); - } - } - - return (TRUE); -} - -/* Returns thestrchr of the last element that was calculated. oval is the - * value of the old scale at the end of the interval that is being interpolated - * from, and sign is 1 if the old scale was increasing, and -1 if it was - * decreasing. - */ - -static int -putinterval(double *poly, int degree, double *nvec, int last, double *nscale, int nlen, double oval, int sign) -{ - int end, i; - - /* See how far we have to go. */ - for (end = last + 1; end < nlen; end++) - if (nscale[end] * sign > oval * sign) - break; - end--; - - for (i = last + 1; i <= end; i++) - nvec[i] = ft_peval(nscale[i], poly, degree); - return (end); -} - -static void -printmat(char *name, double *mat, int m, int n) -{ - int i, j; - - printf("\n\r=== Matrix: %s ===\n\r", name); - for (i = 0; i < m; i++) { - printf(" | "); - for (j = 0; j < n; j++) - printf("%G ", mat[i * n + j]); - printf("|\n\r"); - } - printf("===\n\r"); - return; -} - -double -ft_peval(double x, double *coeffs, int degree) -{ - double y; - int i; - - if (!coeffs) - return 0.0; /* XXX Should not happen */ - - y = coeffs[degree]; /* there are (degree+1) coeffs */ - - for (i = degree - 1; i >= 0; i--) { - y *= x; - y += coeffs[i]; - } - - return y; -} - -#ifdef notdef - -XXX The following code is rediculous - -/* This should be a macro or be asm coded if possible. */ - -double -ft_peval(pt, coeffs, degree) - double pt, *coeffs; - register int degree; -{ - register int i, j; - double d = 0.0, f; - - /* fprintf(cp_err, "peval "); - for (i = 0; i <= degree; i++) - fprintf(cp_err, "%G ", coeffs[i]); - fprintf(cp_err, "at %G", pt); - */ - for (i = 0; i <= degree; i++) { - f = 1.0; - for (j = 0; j < i; j++) - f *= pt; - d += f * coeffs[i]; - } - /* fprintf(cp_err, " = %G\n", d);*/ - return (d); -} -#endif - void lincopy(struct dvec *ov, double *newscale, int newlen, struct dvec *oldscale) { @@ -374,12 +46,3 @@ lincopy(struct dvec *ov, double *newscale, int newlen, struct dvec *oldscale) return; } -void -ft_polyderiv(double *coeffs, int degree) -{ - int i; - - for (i = 0; i < degree; i++) { - coeffs[i] = (i + 1) * coeffs[i + 1]; - } -} diff --git a/src/frontend/linear.c b/src/frontend/linear.c index 0ac8006fc..302230bcb 100644 --- a/src/frontend/linear.c +++ b/src/frontend/linear.c @@ -6,7 +6,9 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" + +#include "circuits.h" #include "linear.h" diff --git a/src/frontend/misccoms.c b/src/frontend/misccoms.c index 636e4f3b7..b0d338b93 100644 --- a/src/frontend/misccoms.c +++ b/src/frontend/misccoms.c @@ -6,234 +6,18 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" #include "ftehelp.h" #include "hlpdefs.h" #include "misccoms.h" +#include "circuits.h" +#include "hcomp.h" +#include "variable.h" + static void byemesg(void); -void -com_help(wordlist *wl) -{ - struct comm *c; - struct comm *ccc[512]; /* Should be enough. */ - int numcoms, i; - bool allflag = FALSE; - - if (wl && eq(wl->wl_word, "all")) { - allflag = TRUE; - wl = NULL; /* XXX Probably right */ - } - - /* We want to use more mode whether "moremode" is set or not. */ - out_moremode = TRUE; - out_init(); - out_moremode = FALSE; - if (wl == NULL) { - out_printf( - "For a complete description read the Spice3 User's Manual manual.\n"); - - if (!allflag) { - out_printf( - "For a list of all commands type \"help all\", for a short\n"); - out_printf( - "description of \"command\", type \"help command\".\n"); - } - - /* Sort the commands */ - for (numcoms = 0; cp_coms[numcoms].co_func != NULL; numcoms++) - ccc[numcoms] = &cp_coms[numcoms]; - qsort((char *) ccc, numcoms, sizeof (struct comm *), hcomp); - - for (i = 0; i < numcoms; i++) { - if ((ccc[i]->co_spiceonly && ft_nutmeg) || - (ccc[i]->co_help == NULL) || - (!allflag && !ccc[i]->co_major)) - continue; - out_printf("%s ", ccc[i]->co_comname); - out_printf(ccc[i]->co_help, cp_program); - out_send("\n"); - } - } else { - while (wl != NULL) { - for (c = &cp_coms[0]; c->co_func != NULL; c++) - if (eq(wl->wl_word, c->co_comname)) { - out_printf("%s ", c->co_comname); - out_printf(c->co_help, cp_program); - if (c->co_spiceonly && ft_nutmeg) - out_send( - " (Not available in nutmeg)"); - out_send("\n"); - break; - } - if (c->co_func == NULL) { - /* See if this is aliased. */ - struct alias *al; - - for (al = cp_aliases; al; al = al->al_next) - if (eq(al->al_name, wl->wl_word)) - break; - if (al == NULL) - fprintf(cp_out, - "Sorry, no help for %s.\n", - wl->wl_word); - else { - out_printf("%s is aliased to ", - wl->wl_word); - /* Minor badness here... */ - wl_print(al->al_text, cp_out); - out_send("\n"); - } - } - wl = wl->wl_next; - } - } - out_send("\n"); - return; -} - -void -com_ahelp(wordlist *wl) -{ - - int i, n; - /* assert: number of commands must be less than 512 */ - struct comm *cc[512]; - int env = 0; - struct comm *com; - int level; - char slevel[256]; - - if (wl) { - com_help(wl); - return; - } - - out_init(); - - /* determine environment */ - if (plot_list->pl_next) { /* plots load */ - env |= E_HASPLOTS; - } else { - env |= E_NOPLOTS; - } - - /* determine level */ - if (cp_getvar("level", VT_STRING, slevel)) { - switch (*slevel) { - case 'b': level = 1; - break; - case 'i': level = 2; - break; - case 'a': level = 4; - break; - default: level = 1; - break; - } - } else { - level = 1; - } - - out_printf( - "For a complete description read the Spice3 User's Manual manual.\n"); - out_printf( - "For a list of all commands type \"help all\", for a short\n"); - out_printf( - "description of \"command\", type \"help command\".\n"); - - /* sort the commands */ - for (n = 0; cp_coms[n].co_func != (void (*)()) NULL; n++) { - cc[n] = &cp_coms[n]; - } - qsort((char *) cc, n, sizeof(struct comm *), hcomp); - - /* filter the commands */ - for (i=0; i< n; i++) { - com = cc[i]; - if ((com->co_env < (level << 13)) && (!(com->co_env & 4095) || - (env & com->co_env))) { - if ((com->co_spiceonly && ft_nutmeg) || - (com->co_help == (char *) NULL)) { - continue; - } - out_printf("%s ", com->co_comname); - out_printf(com->co_help, cp_program); - out_send("\n"); - } - } - - out_send("\n"); - - return; - -} - -void -com_ghelp(wordlist *wl) -{ - char *npath, *path = Help_Path, buf[BSIZE_SP]; - int i; - - if (cp_getvar("helppath", VT_STRING, buf)) - path = copy(buf); - if (!path) { - fprintf(cp_err, "Note: defaulting to old help.\n\n"); - com_help(wl); - return; - } - if (!(npath = cp_tildexpand(path))) { - fprintf(cp_err, "Note: can't find help dir %s\n", path); - fprintf(cp_err, "Defaulting to old help.\n\n"); - com_help(wl); - return; - } - path = npath; - if (cp_getvar("helpregfont", VT_STRING, buf)) - hlp_regfontname = copy(buf); - if (cp_getvar("helpboldfont", VT_STRING, buf)) - hlp_boldfontname = copy(buf); - if (cp_getvar("helpitalicfont", VT_STRING, buf)) - hlp_italicfontname = copy(buf); - if (cp_getvar("helptitlefont", VT_STRING, buf)) - hlp_titlefontname = copy(buf); - if (cp_getvar("helpbuttonfont", VT_STRING, buf)) - hlp_buttonfontname = copy(buf); - if (cp_getvar("helpinitxpos", VT_NUM, (char *) &i)) - hlp_initxpos = i; - if (cp_getvar("helpinitypos", VT_NUM, (char *) &i)) - hlp_initypos = i; - if (cp_getvar("helpbuttonstyle", VT_STRING, buf)) { - if (cieq(buf, "left")) - hlp_buttonstyle = BS_LEFT; - else if (cieq(buf, "center")) - hlp_buttonstyle = BS_CENTER; - else if (cieq(buf, "unif")) - hlp_buttonstyle = BS_UNIF; - else - fprintf(cp_err, "Warning: no such button style %s\n", - buf); - } - if (cp_getvar("width", VT_NUM, (char *) &i)) - hlp_width = i; - if (cp_getvar("display", VT_STRING, buf)) - hlp_displayname = copy(buf); - else if (cp_getvar("device", VT_STRING, buf)) - hlp_displayname = copy(buf); - else - hlp_displayname = NULL; - hlp_main(path, wl); - return; -} - -int -hcomp(struct comm **c1, struct comm **c2) -{ - return (strcmp((*c1)->co_comname, (*c2)->co_comname)); -} - - void com_quit(wordlist *wl) { @@ -302,11 +86,6 @@ com_quit(wordlist *wl) #ifdef SYSTEM_MAIL -#define MAIL_BUGS_ -#endif - -#ifdef MAIL_BUGS_ - void com_bug(wordlist *wl) diff --git a/src/frontend/misccoms.h b/src/frontend/misccoms.h index 849f84c92..d478a25ab 100644 --- a/src/frontend/misccoms.h +++ b/src/frontend/misccoms.h @@ -9,7 +9,6 @@ void com_help(wordlist *wl); void com_ahelp(wordlist *wl); void com_ghelp(wordlist *wl); -int hcomp(struct comm **c1, struct comm **c2); void com_quit(wordlist *wl); void com_bug(wordlist *wl); void com_version(wordlist *wl); diff --git a/src/frontend/miscvars.c b/src/frontend/miscvars.c index eeb4c8a57..95da681bf 100644 --- a/src/frontend/miscvars.c +++ b/src/frontend/miscvars.c @@ -6,7 +6,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" #include "fteinp.h" #include "miscvars.h" diff --git a/src/frontend/mw_coms.c b/src/frontend/mw_coms.c index fd7fab110..f7bdae5f2 100644 --- a/src/frontend/mw_coms.c +++ b/src/frontend/mw_coms.c @@ -7,9 +7,11 @@ #include "ftedefs.h" #include "ftedev.h" #include "ftedebug.h" -#include "ftedata.h" -#include "mw_coms.h" +#include "dvec.h" +#include "circuits.h" +#include "mw_coms.h" +#include "variable.h" extern FILE *rawfileFp; extern bool rawfileBinary; diff --git a/src/frontend/newcoms.c b/src/frontend/newcoms.c index 93ded1cc6..3bd5bd7f0 100644 --- a/src/frontend/newcoms.c +++ b/src/frontend/newcoms.c @@ -10,9 +10,10 @@ Copyright 1992 Regents of the University of California. All rights reserved. #include "cpdefs.h" #include "ftedefs.h" #include "fteparse.h" -#include "ftedata.h" -#include "newcoms.h" +#include "dvec.h" +#include "newcoms.h" +#include "quote.h" /* * reshape v(1) vxx#branch [10] diff --git a/src/frontend/nutinp.c b/src/frontend/nutinp.c index 7b38dc68c..9c6c5fdd2 100644 --- a/src/frontend/nutinp.c +++ b/src/frontend/nutinp.c @@ -10,10 +10,11 @@ Author: 1985 Wayne A. Christopher #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" #include "fteinp.h" -#include "nutinp.h" +#include "nutinp.h" +#include "variable.h" /* The routine to source a spice input deck. We read the deck in, take out * the front-end commands, and create a CKT structure. Also we filter out @@ -28,8 +29,8 @@ void inp_nutsource(FILE *fp, bool comfile, char *filename) { struct line *deck, *dd, *ld; - struct line *realdeck, *options; - char *tt, name[BSIZE_SP], *s, *t; + struct line *realdeck, *options = NULL; + char *tt = NULL, name[BSIZE_SP], *s, *t; bool nosubckts, commands = FALSE; wordlist *wl = NULL, *end = NULL; wordlist *controls = NULL; diff --git a/src/frontend/options.c b/src/frontend/options.c index 369166e57..78022de0c 100644 --- a/src/frontend/options.c +++ b/src/frontend/options.c @@ -13,10 +13,12 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" #include "fteinp.h" -#include "options.h" +#include "circuits.h" +#include "options.h" +#include "variable.h" /* static declarations */ diff --git a/src/frontend/outitf.c b/src/frontend/outitf.c index db5de7c17..f33cfbb85 100644 --- a/src/frontend/outitf.c +++ b/src/frontend/outitf.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1988 Wayne A. Christopher, U. C. Berkeley CAD Group +Modified: 2000 AlansFixes **********/ /* @@ -13,17 +14,25 @@ Author: 1988 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" -#include "fteconst.h" +#include "dvec.h" +#include "plot.h" +#include "sim.h" #include "inpdefs.h" /* for INPtables */ #include "ifsim.h" #include "jobdefs.h" #include "iferrmsg.h" +#include "circuits.h" #include "outitf.h" - +#include "variable.h" +#include +#include +#include "cktdefs.h" +#include extern void gr_end_iplot(void); -extern SPICEanalysis *analInfo[]; +extern char *spice_analysis_get_name(int index); +extern char *spice_analysis_get_description(int index); + /* static declarations */ static int beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, @@ -47,16 +56,23 @@ static bool name_eq(char *n1, char *n2); static bool getSpecial(dataDesc *desc, runDesc *run, IFvalue *val); static void freeRun(runDesc *run); - +/*Output data to spice module saj*/ +#ifdef TCL_MODULE +#include "tclspice.h" +#endif +/*saj*/ #define DOUBLE_PRECISION 15 - +static clock_t lastclock, currclock; +static double *rowbuf; +static int column, rowbuflen; static bool shouldstop = FALSE; /* Tell simulator to stop next time it asks. */ static bool printinfo = FALSE; /* Print informational "error messages". */ + /* The two "begin plot" routines share all their internals... */ @@ -66,22 +82,21 @@ extern bool ft_getOutReq (FILE **fpp, struct plot **plotp, bool *binp, char *nam int OUTpBeginPlot(void *circuitPtr, void *analysisPtr, IFuid analName, IFuid refName, int refType, int numNames, IFuid *dataNames, int dataType, void **plotPtr) { - char *name; - + char *name; #ifdef PARALLEL_ARCH if (ARCHme != 0) return(OK); #endif /* PARALLEL_ARCH */ - if (ft_curckt->ci_ckt == circuitPtr) - name = ft_curckt->ci_name; - else - name = "circuit name"; - - return (beginPlot(analysisPtr, circuitPtr, name, - (char *) analName, (char *) refName, refType, numNames, - (char **) dataNames, dataType, FALSE, - (runDesc **) plotPtr)); + if (ft_curckt->ci_ckt == circuitPtr) + name = ft_curckt->ci_name; + else + name = "circuit name"; + + return (beginPlot(analysisPtr, circuitPtr, name, + (char *) analName, (char *) refName, refType, numNames, + (char **) dataNames, dataType, FALSE, + (runDesc **) plotPtr)); } int @@ -102,12 +117,24 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch { runDesc *run; struct save_info *saves; - bool *savesused; + bool *savesused = NULL; int numsaves; - int i, j, depind; + int i, j, depind = 0; char namebuf[BSIZE_SP], parambuf[BSIZE_SP], depbuf[BSIZE_SP]; - bool saveall = TRUE; + char *ch, tmpname[BSIZE_SP]; + bool saveall = TRUE; + bool savealli = FALSE; char *an_name; + /*to resume a run saj + *All it does is reassign the file pointer and return (requires *runp to be NULL if this is not needed) + */ + if(dataType == 666 && numNames == 666){ + run = *runp; + run->writeOut = ft_getOutReq(&run->fp, &run->runPlot, &run->binary, + run->type, run->name); + + } else { + /*end saj*/ /* Check to see if we want to print informational data. */ if (cp_getvar("printinfo", VT_BOOL, (char *) &printinfo)) @@ -123,7 +150,7 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch run->windowed = windowed; run->numData = 0; - an_name = analInfo[((JOB *) analysisPtr)->JOBtype]->public.name; + an_name = spice_analysis_get_name(((JOB *) analysisPtr)->JOBtype); /* Now let's see which of these things we need. First toss in the * reference vector. Then toss in anything that getSaves() tells @@ -135,17 +162,29 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch savesused = (bool *) tmalloc(sizeof (bool) * numsaves); saveall = FALSE; for (i = 0; i < numsaves; i++) { - if (saves[i].analysis && !cieq(saves[i].analysis, an_name)) { + if (saves[i].analysis && !cieq((char *)saves[i].analysis, an_name)) { /* ignore this one this time around */ - savesused[i] = TRUE; + savesused[i] = TRUE; continue; } - if (cieq(saves[i].name, "all")) { + +/* Check for ".save all" and new synonym ".save allv" */ + + if (cieq(saves[i].name, "all") || cieq(saves[i].name, "allv")) { saveall = TRUE; savesused[i] = TRUE; saves[i].used = 1; continue; } + +/* And now for the new ".save alli" option */ + + if (cieq(saves[i].name, "alli")) { + savealli = TRUE; + savesused[i] = TRUE; + saves[i].used = 1; + continue; + } } } @@ -179,10 +218,80 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch } else { for (i = 0; i < numNames; i++) if (!refName || !name_eq(dataNames[i], refName)) { - addDataDesc(run, dataNames[i], dataType, i); + +/* Save the node as long as it's an internal device node */ + + if (!strstr(dataNames[i], "#internal") && + !strstr(dataNames[i], "#source") && + !strstr(dataNames[i], "#drain") && + !strstr(dataNames[i], "#collector") && + !strstr(dataNames[i], "#emitter") && + !strstr(dataNames[i], "#base")) { + addDataDesc(run, dataNames[i], dataType, i); + } } } + /* Pass 1 and a bit. + This is a new pass which searches for all the internal device + nodes, and saves the terminal currents instead */ + + if (savealli) { + depind=0; + for (i = 0; i < numNames; i++) { + if (strstr(dataNames[i], "#internal") || + strstr(dataNames[i], "#source") || + strstr(dataNames[i], "#drain") || + strstr(dataNames[i], "#collector") || + strstr(dataNames[i], "#emitter") || + strstr(dataNames[i], "#base")) { + tmpname[0]='@'; + tmpname[1]='\0'; + strncat(tmpname, dataNames[i], BSIZE_SP-1); + ch=strchr(tmpname, '#'); + + if (strstr(ch, "#collector")!=NULL) { + strcpy(ch, "[ic]"); + } else if (strstr(ch, "#base")!=NULL) { + strcpy(ch, "[ib]"); + } else if (strstr(ch, "#emitter")!=NULL) { + strcpy(ch, "[ie]"); + if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) { + addSpecialDesc(run, tmpname, namebuf, parambuf, depind); + }; + strcpy(ch, "[is]"); + } else if (strstr(ch, "#drain")!=NULL) { + strcpy(ch, "[id]"); + if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) { + addSpecialDesc(run, tmpname, namebuf, parambuf, depind); + }; + strcpy(ch, "[ig]"); + } else if (strstr(ch, "#source")!=NULL) { + strcpy(ch, "[is]"); + if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) { + addSpecialDesc(run, tmpname, namebuf, parambuf, depind); + }; + strcpy(ch, "[ib]"); + } else + if ((strstr(ch, "#internal")!=NULL)&&(tmpname[1]=='d')) { + strcpy(ch, "[id]"); + } else { + fprintf(cp_err, + "Debug: could output current for %s\n", tmpname); + continue; + }; + if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) { + if (*depbuf) { fprintf( stderr, + "Warning : unexpected dependant variable on %s\n", tmpname); + } else { + addSpecialDesc(run, tmpname, namebuf, parambuf, depind); + } + } + } + } + } + + /* Pass 2. */ for (i = 0; i < numsaves; i++) { if (savesused[i]) @@ -227,14 +336,14 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch tfree(savesused); } - if (numNames - && (run->numData == 1 - && (run->refIndex != -1 - || run->numData == 0) - && run->refIndex == -1)) + if (numNames && + (run->numData == 1 + && run->refIndex != -1 + || run->numData == 0 + && run->refIndex == -1)) { fprintf(cp_err, "Error: no data saved for %s; analysis not run\n", - analInfo[((JOB *) analysisPtr)->JOBtype]->public.description); + spice_analysis_get_description(((JOB *) analysisPtr)->JOBtype)); return E_NOTFOUND; } @@ -252,6 +361,12 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch run->runPlot->pl_ndims = 1; } + /*Start BLT, initilises the blt vectors saj*/ +#ifdef TCL_MODULE + blt_init(run); +#endif + } + /*end saj*/ return (OK); } @@ -320,7 +435,6 @@ addSpecialDesc(runDesc *run, char *name, char *devname, char *param, int depind) return (OK); } - int OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) @@ -333,23 +447,48 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) #endif /* PARALLEL_ARCH */ run->pointCount++; +#ifdef TCL_MODULE + steps_completed = run->pointCount; +#endif if (run->writeOut) { if (run->pointCount == 1) fileInit_pass2(plotPtr); fileStartPoint(run->fp, run->binary, run->pointCount); - if (run->refIndex != -1) { - if (run->isComplex) + if (run->isComplex){ fileAddComplexValue(run->fp, run->binary, refValue->cValue); - else - fileAddRealValue(run->fp, run->binary, refValue->rValue); - } +/* While we're looking at the reference value, print it to the screen + every quarter of a second, to give some feedback without using + too much CPU time */ + + currclock = clock(); + if ((currclock-lastclock)>(0.25*CLOCKS_PER_SEC)) { + fprintf(stderr, " Reference value : % 12.5e\r", + refValue->cValue.real); + lastclock = currclock; + } + } else { + +/* And the same for a non-complex value */ + + fileAddRealValue(run->fp, run->binary, refValue->rValue); + currclock = clock(); + if ((currclock-lastclock)>(0.25*CLOCKS_PER_SEC)) { + fprintf(stderr, " Reference value : % 12.5e\r", refValue->rValue); + lastclock = currclock; + } + } + } for (i = 0; i < run->numData; i++) { /* we've already printed reference vec first */ - if (run->data[i].outIndex == -1) continue; - + if (run->data[i].outIndex == -1){ +#ifdef TCL_MODULE + blt_add(i,refValue->rValue); +#endif + continue; + } if (run->data[i].regular) { if(run->data[i].type == IF_REAL) fileAddRealValue(run->fp, run->binary, @@ -364,7 +503,27 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) } else { /* should pre-check instance */ if (!getSpecial(&run->data[i], run, &val)) + { + +/* If this is the first data point, print a warning for any unrecognized + variables, since this has not already been checked */ + + if (run->pointCount==1) + fprintf(stderr, "Warning: unrecognized variable - %s\n", + run->data[i].name); + + if (run->isComplex) { + val.cValue.real=0; + val.cValue.imag=0; + fileAddComplexValue(run->fp, run->binary, + val.cValue); + } else { + val.rValue=0; + fileAddRealValue(run->fp, run->binary, + val.rValue); + }; continue; + }; if (run->data[i].type == IF_REAL) fileAddRealValue(run->fp, run->binary, val.rValue); @@ -374,50 +533,88 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) else fprintf(stderr, "OUTpData: unsupported data type\n"); } +#ifdef TCL_MODULE + blt_add(i,valuePtr->v.vec.rVec + [run->data[i].outIndex]); +#endif } fileEndPoint(run->fp, run->binary); + +/* Check that the write to disk completed successfully, otherwise abort */ + + if (ferror(run->fp)) { + fprintf(stderr, "Warning: rawfile write error !!\n"); + shouldstop = TRUE; + }; } else { - for (i = 0; i < run->numData; i++) { - if (run->data[i].outIndex == -1) { - if (run->data[i].type == IF_REAL) - plotAddRealValue(&run->data[i], + +/* This is interactive mode. Update the screen with the reference + variable just the same */ + + currclock = clock(); + if ((currclock-lastclock)>(0.25*CLOCKS_PER_SEC)) { + if (run->isComplex) { + fprintf(stderr, " Reference value : % 12.5e\r", + refValue->cValue.real); + } else { + fprintf(stderr, " Reference value : % 12.5e\r", refValue->rValue); - else if (run->data[i].type == IF_COMPLEX) - plotAddComplexValue(&run->data[i], - refValue->cValue); + } + lastclock = currclock; + } + + for (i = 0; i < run->numData; i++) { +#ifdef TCL_MODULE + /*Locks the blt vector to stop access*/ + blt_lockvec(i); +#endif + if (run->data[i].outIndex == -1) { + if (run->data[i].type == IF_REAL) + plotAddRealValue(&run->data[i], + refValue->rValue); + else if (run->data[i].type == IF_COMPLEX) + plotAddComplexValue(&run->data[i], + refValue->cValue); } else if (run->data[i].regular) { - if (run->data[i].type == IF_REAL) - plotAddRealValue(&run->data[i], - valuePtr->v.vec.rVec - [run->data[i].outIndex]); - else if (run->data[i].type == IF_COMPLEX) - plotAddComplexValue(&run->data[i], - valuePtr->v.vec.cVec - [run->data[i].outIndex]); + if (run->data[i].type == IF_REAL) + plotAddRealValue(&run->data[i], + valuePtr->v.vec.rVec + [run->data[i].outIndex]); + else if (run->data[i].type == IF_COMPLEX) + plotAddComplexValue(&run->data[i], + valuePtr->v.vec.cVec + [run->data[i].outIndex]); } else { - /* should pre-check instance */ - if (!getSpecial(&run->data[i], run, &val)) - continue; - if (run->data[i].type == IF_REAL) - plotAddRealValue(&run->data[i], - val.rValue); - else if (run->data[i].type == IF_COMPLEX) - plotAddComplexValue(&run->data[i], + /* should pre-check instance */ + if (!getSpecial(&run->data[i], run, &val)) + continue; + if (run->data[i].type == IF_REAL) + plotAddRealValue(&run->data[i], + val.rValue); + else if (run->data[i].type == IF_COMPLEX) + plotAddComplexValue(&run->data[i], val.cValue); - else - fprintf(stderr, "OUTpData: unsupported data type\n"); + else + fprintf(stderr, "OUTpData: unsupported data type\n"); } +#ifdef TCL_MODULE + /*relinks and unlocks vector*/ + blt_relink(i,(run->data[i]).vec); +#endif } gr_iplot(run->runPlot); } if (ft_bpcheck(run->runPlot, run->pointCount) == FALSE) - shouldstop = TRUE; + shouldstop = TRUE; + +#ifdef TCL_MODULE + Tcl_ExecutePerLoop(); +#endif return (OK); } - /* ARGSUSED */ /* until some code gets written */ int @@ -526,6 +723,8 @@ fileInit(runDesc *run) { char buf[513]; int i; + + lastclock = clock(); /* This is a hack. */ run->isComplex = FALSE; @@ -551,15 +750,17 @@ fileInit(runDesc *run) fputs(buf, run->fp); sprintf(buf, "No. Points: "); i += strlen(buf); - fputs(buf, run->fp); + fputs(buf, run->fp); fflush(run->fp); /* Gotta do this for LATTICE. */ if (run->fp == stdout || (run->pointPos = ftell(run->fp)) <= 0) - run->pointPos = i; + run->pointPos = i; fprintf(run->fp, "0 \n"); /* Save 8 spaces here. */ - + fprintf(run->fp, "Command: version %s\n", ft_sim->version); - fprintf(run->fp, "Variables:\n"); + fprintf(run->fp, "Variables:\n"); + + fprintf(stderr, "No. of Data Columns : %d \n", run->numData); return; } @@ -571,6 +772,7 @@ fileInit_pass2(runDesc *run) char *name, buf[BSIZE_SP]; for (i = 0; i < run->numData; i++) { + if (isdigit(*run->data[i].name)) { (void) sprintf(buf, "V(%s)", run->data[i].name); name = buf; @@ -583,20 +785,31 @@ fileInit_pass2(runDesc *run) type = SV_TIME; else if (cieq(name, "frequency")) type = SV_FREQUENCY; - else + else type = SV_VOLTAGE; - + fprintf(run->fp, "\t%d\t%s\t%s", i, name, ft_typenames(type)); - if (run->data[i].gtype == GRID_XLOG) - fprintf(run->fp, "\tgrid=3"); - fprintf(run->fp, "\n"); + if (run->data[i].gtype == GRID_XLOG) + fprintf(run->fp, "\tgrid=3"); + fprintf(run->fp, "\n"); } - fprintf(run->fp, "%s:\n", run->binary ? "Binary" : "Values"); + fprintf(run->fp, "%s:\n", run->binary ? "Binary" : "Values"); + + fflush(run->fp); /* Make all sure this gets to disk */ + + /* Allocate Row buffer */ + + if (run->binary) { + rowbuflen=(run->numData)*sizeof(double); + if (run->isComplex) rowbuflen *=2; + rowbuf=(double *)tmalloc(rowbuflen); + } else rowbuf=NULL; return; + } static void @@ -604,6 +817,10 @@ fileStartPoint(FILE *fp, bool bin, int num) { if (!bin) fprintf(fp, "%d\t", num - 1); + + /* reset buffer pointer to zero */ + + column = 0; return; } @@ -612,11 +829,11 @@ static void fileAddRealValue(FILE *fp, bool bin, double value) { if (bin) - fwrite((char *) &value, sizeof (double), 1, fp); + rowbuf[column++]=value; else - fprintf(fp, "\t%.*e\n", DOUBLE_PRECISION, value); - - return; + fprintf(fp, "\t%.*e\n", DOUBLE_PRECISION, value); + + return; } static void @@ -624,8 +841,8 @@ fileAddComplexValue(FILE *fp, bool bin, IFcomplex value) { if (bin) { - fwrite((char *) &value.real, sizeof (double), 1, fp); - fwrite((char *) &value.imag, sizeof (double), 1, fp); + rowbuf[column++]=value.real; + rowbuf[column++]=value.imag; } else { fprintf(fp, "\t%.*e,%.*e\n", DOUBLE_PRECISION, value.real, DOUBLE_PRECISION, value.imag); @@ -637,7 +854,11 @@ fileAddComplexValue(FILE *fp, bool bin, IFcomplex value) static void fileEndPoint(FILE *fp, bool bin) { - return; + if (bin) { + /* write row buffer to file */ + fwrite((char *)rowbuf, rowbuflen, 1, fp); + }; /* otherwise the data has already been written */ + return; } /* Here's the hack... Run back and fill in the number of points. */ @@ -650,7 +871,8 @@ fileEnd(runDesc *run) if (run->fp != stdout) { place = ftell(run->fp); fseek(run->fp, run->pointPos, 0); - fprintf(run->fp, "%d", run->pointCount); + fprintf(run->fp, "%d", run->pointCount); + fprintf(stderr, "\nNo. of Data Rows : %d\n", run->pointCount); fseek(run->fp, place, 0); } else { /* Yet another hack-around */ @@ -658,6 +880,11 @@ fileEnd(runDesc *run) } fflush(run->fp); + if (run->binary) { + /* deallocate row buffer */ + tfree(rowbuf); + } + return; } @@ -761,7 +988,7 @@ plotAddComplexValue(dataDesc *desc, IFcomplex value) static void plotEnd(runDesc *run) { - + fprintf(stderr, "\nNo. of Data Rows : %d\n", run->pointCount); return; } @@ -779,7 +1006,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind) *dev = *param = *ind = '\0'; if (*name != '@') - return (FALSE); + return FALSE; name++; s = dev; @@ -787,7 +1014,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind) *s++ = *name++; *s = '\0'; if (!*name) - return (TRUE); + return TRUE; name++; s = param; @@ -797,7 +1024,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind) if (*name == ']') return (!name[1] ? TRUE : FALSE); else if (!*name) - return (FALSE); + return FALSE; name++; s = ind; @@ -805,9 +1032,9 @@ parseSpecial(char *name, char *dev, char *param, char *ind) *s++ = *name++; *s = '\0'; if (*name && !name[1]) - return (TRUE); + return TRUE; else - return (FALSE); + return FALSE; } /* This routine must match two names with or without a V() around them. */ @@ -820,14 +1047,14 @@ name_eq(char *n1, char *n2) if ((s =strchr(n1, '('))) { strcpy(buf1, s); if (!(s =strchr(buf1, ')'))) - return (FALSE); + return FALSE; *s = '\0'; n1 = buf1; } if ((s =strchr(n2, '('))) { strcpy(buf2, s); if (!(s =strchr(buf2, ')'))) - return (FALSE); + return FALSE; *s = '\0'; n2 = buf2; } @@ -846,7 +1073,7 @@ getSpecial(dataDesc *desc, runDesc *run, IFvalue *val) desc->specName, &desc->specFast, ft_sim, &desc->type, &selector) == OK) { desc->type &= (IF_REAL | IF_COMPLEX); /* mask out other bits */ - return(TRUE); + return TRUE; } else if ((vv = if_getstat(run->circuit, &desc->name[1]))) { /* skip @ sign */ desc->type = IF_REAL; @@ -857,13 +1084,13 @@ getSpecial(dataDesc *desc, runDesc *run, IFvalue *val) else if (vv->va_type == VT_BOOL) val->rValue = (vv->va_bool ? 1.0 : 0.0); else { - return (FALSE); /* not a real */ + return FALSE; /* not a real */ } tfree(vv); - return(TRUE); + return TRUE; } - return (FALSE); + return FALSE; } static void @@ -873,17 +1100,14 @@ freeRun(runDesc *run) int i; for (i=0; i < run->numData; i++) { -/* vec_free(run->data[i].vec); */ /* kill run, leave plot */ tfree(run->data[i].name); tfree(run->data[i].specParamName); } tfree(run->data); -/* killplot(run->runPlot); */ /* kill run, leave plot */ - - free(run->type); - free(run->name); - free(run); + tfree(run->type); + tfree(run->name); + tfree(run); } diff --git a/src/frontend/parse.c b/src/frontend/parse.c index 88cbf86a5..3979efc86 100644 --- a/src/frontend/parse.c +++ b/src/frontend/parse.c @@ -8,12 +8,12 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group * This also handles relational and logical expressions. */ -#include "ngspice.h" -#include "cpdefs.h" -#include "ftedefs.h" -#include "fteparse.h" -#include "ftedata.h" -#include "ftecmath.h" +#include +#include +#include +#include +#include + #include "parse.h" @@ -598,8 +598,15 @@ struct func ft_funcs[] = { { "vector", cx_vector } , { "unitvec", cx_unitvec } , { "length", cx_length } , + { "vecmin", cx_min } , + { "vecmax", cx_max } , + { "vecd", cx_d } , +#if 0 + /* These functions have been temporarily been disabled. See + their definitions for the reason. */ { "interpolate",cx_interpolate } , { "deriv", cx_deriv } , +#endif { "v", NULL } , { NULL, NULL } } ; diff --git a/src/frontend/parse.h b/src/frontend/parse.h index 46d8bbe61..390f9afb5 100644 --- a/src/frontend/parse.h +++ b/src/frontend/parse.h @@ -3,8 +3,11 @@ * 1999 E. Rouat ************/ -#ifndef PARSE_H_INCLUDED -#define PARSE_H_INCLUDED +#ifndef _PARSE_H +#define _PARSE_H + +#include +#include struct pnode * ft_getpnames(wordlist *wl, bool check); void free_pnode(struct pnode *t); diff --git a/src/frontend/points.c b/src/frontend/points.c index cfe2ee74c..3e7f5f199 100644 --- a/src/frontend/points.c +++ b/src/frontend/points.c @@ -3,19 +3,19 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group **********/ -#include "ngspice.h" -#include "cpdefs.h" -#include "ftedefs.h" -#include "ftedata.h" -#include "ftegraph.h" -#include "ftedbgra.h" +#include +#include +#include +#include +#include +#include + #include "points.h" -/* Returns the minimum and maximum values of a dvec. Returns a pointer to - * static data. If real is TRUE look at the real parts, otherwise the imag - * parts. - */ +/* Returns the minimum and maximum values of a dvec. Returns a pointer + * to static data. If real is TRUE look at the real parts, otherwise + * the imag parts. */ diff --git a/src/frontend/postcoms.c b/src/frontend/postcoms.c index 89b79fb0a..15ee068f4 100644 --- a/src/frontend/postcoms.c +++ b/src/frontend/postcoms.c @@ -7,256 +7,22 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group * Various post-processor commands having to do with vectors. */ -#include "ngspice.h" -#include "cpdefs.h" -#include "ftedefs.h" -#include "fteparse.h" -#include "ftedata.h" -#include "postcoms.h" +#include +#include +#include +#include +#include +#include +#include "completion.h" +#include "postcoms.h" +#include "quote.h" +#include "variable.h" /* static declarations */ -static void pvec(struct dvec *d); -static int dcomp(struct dvec **v1, struct dvec **v2); static void killplot(struct plot *pl); -void -com_let(wordlist *wl) -{ - char *p, *q, *s; - int indices[MAXDIMS]; - int numdims; - wordlist fake_wl; - int need_open; - int offset, length; - struct pnode *nn; - struct dvec *n, *t; - int i, cube; - int depth; - int newvec; - char *rhs; - - fake_wl.wl_next = NULL; - - if (!wl) { - com_display((wordlist *) NULL); - return; - } - - p = wl_flatten(wl); - - /* extract indices */ - numdims = 0; - if ((rhs =strchr(p, '='))) { - *rhs++ = 0; - } else { - fprintf(cp_err, "Error: bad let syntax\n"); - return; - } - if ((s =strchr(p, '['))) { - need_open = 0; - *s++ = 0; - while (!need_open || *s == '[') { - depth = 0; - if (need_open) - s++; - for (q = s; *q && (*q != ']' && (*q != ',' || depth > 0)); q++) { - switch (*q) { - case '[': - depth += 1; - break; - case ']': - depth -= 1; - break; - } - } - - if (depth != 0 || !*q) { - printf("syntax error specifyingstrchr\n"); - return; - } - - if (*q == ']') - need_open = 1; - else - need_open = 0; - if (*q) - *q++ = 0; - -/* MW. let[x,y] is not supported - we don't need this code - - * evaluate expression between s and q - fake_wl.wl_word = s; - nn = ft_getpnames(&fake_wl, TRUE); - t = ft_evaluate(nn); - - free_pnode(nn); - - if (!t) { - fprintf(cp_err, "Error: badstrchr.\n"); // MW. When t == NULL something is wrong - tfree(p); - return; - } - - if (!isreal(t) || t->v_link2 || t->v_length != 1 || !t->v_realdata) - { - fprintf(cp_err, "Error:strchr is not a scalar.\n"); - tfree(p); - - return; - } - j = t->v_realdata[0]; - * ignore sanity checks for now - - if (j < 0) { - printf("negativestrchr (%d) is not allowed\n", j); - tfree(p); - return; - } - - indices[numdims++] = j; - - - - - * MW. Next line does not hurt. I don't know what it is doing - */ - - for (s = q; *s && isspace(*s); s++) - ; - } - } - /* vector name at p */ - - for (q = p + strlen(p) - 1; *q <= ' ' && p <= q; q--) - ; - - *++q = 0; - - /* sanity check */ - if (eq(p, "all") ||strchr(p, '@')) { - fprintf(cp_err, "Error: bad variable name %s\n", p); - return; - } - - /* evaluate rhs */ - fake_wl.wl_word = rhs; - nn = ft_getpnames(&fake_wl, TRUE); - if (nn == NULL) { - /* XXX error message */ - tfree(p); - return; - } - t = ft_evaluate(nn); - if (!t) { - fprintf(cp_err, "Error: Can't evaluate %s\n", rhs); - tfree(p); - return; - } - - if (t->v_link2) - fprintf(cp_err, "Warning: extra wildcard values ignored\n"); - - n = vec_get(p); - - if (n) { - /* re-allocate? */ - /* vec_free(n); */ - newvec = 0; - } else { - if (numdims) { - fprintf(cp_err, "Can't assign into a subindex of a new vector\n"); - tfree(p); - return; - } - - /* create and assign a new vector */ - n = alloc(struct dvec); - ZERO(n, struct dvec); - n->v_name = copy(p); - n->v_type = t->v_type; - n->v_flags = (t->v_flags | VF_PERMANENT); - n->v_length = t->v_length; - - if (!t->v_numdims) { - n->v_numdims = 1; - n->v_dims[0] = n->v_length; - } else { - n->v_numdims = t->v_numdims; - for (i = 0; i < t->v_numdims; i++) - n->v_dims[i] = t->v_dims[i]; - } - - if (isreal(t)) - n->v_realdata = (double *) tmalloc(n->v_length * sizeof(double)); - else - n->v_compdata = (complex *) tmalloc(n->v_length * sizeof(complex)); - newvec = 1; - vec_new(n); - } - - /* fix-up dimensions */ - if (n->v_numdims < 1) { - n->v_numdims = 1; - n->v_dims[0] = n->v_length; - } - - /* Compare dimensions */ - offset = 0; - length = n->v_length; - - cube = 1; - for (i = n->v_numdims - 1; i >= numdims; i--) - cube *= n->v_dims[i]; - - for (i = numdims - 1; i >= 0; i--) { - offset += cube * indices[i]; - if (i < n->v_numdims) { - cube *= n->v_dims[i]; - length /= n->v_dims[i]; - } - } - - /* length is the size of the unit refered to */ - /* cube ends up being the length */ - - if (length > t->v_length) { - fprintf(cp_err, "left-hand expression is too small (need %d)\n", - length * cube); - if (newvec) - n->v_flags &= ~VF_PERMANENT; - tfree(p); - return; - } - if (isreal(t) != isreal(n)) { - fprintf(cp_err, - "Types of vectors are not the same (real vs. complex)\n"); - if (newvec) - n->v_flags &= ~VF_PERMANENT; - tfree(p); - return; - } else if (isreal(t)) { - bcopy((char *) t->v_realdata, (char *) (n->v_realdata + offset), - length * sizeof (double)); - } else { - bcopy((char *) t->v_compdata, (char *) (n->v_compdata + offset), - length * sizeof (complex)); - } - - n->v_minsignal = 0.0; /* How do these get reset ??? */ - n->v_maxsignal = 0.0; - - n->v_scale = t->v_scale; - - if (newvec) - cp_addkword(CT_VECTOR, n->v_name); - - /* XXXX Free t !?! */ - tfree(p); - return; -} - /* Undefine vectors. */ void @@ -274,12 +40,15 @@ com_unlet(wordlist *wl) void com_load(wordlist *wl) { - +char *copypath; if (!wl) ft_loadfile(ft_rawfile); else while (wl) { - ft_loadfile(cp_unquote(wl->wl_word)); + /*ft_loadfile(cp_unquote(wl->wl_word)); DG: bad memory leak*/ + copypath=cp_unquote(wl->wl_word);/*DG*/ + ft_loadfile(copypath); + tfree(copypath); wl = wl->wl_next; } @@ -298,17 +67,19 @@ com_load(wordlist *wl) void com_print(wordlist *wl) { - struct dvec *v, *lv, *bv, *nv, *vecs = NULL; + struct dvec *v, *lv = NULL, *bv, *nv, *vecs = NULL; int i, j, ll, width = DEF_WIDTH, height = DEF_HEIGHT, npoints, lineno; struct pnode *nn; struct plot *p; bool col = TRUE, nobreak = FALSE, noprintscale, plotnames = FALSE; bool optgiven = FALSE; char *s, buf[BSIZE_SP], buf2[BSIZE_SP]; + char numbuf[BSIZE_SP], numbuf2[BSIZE_SP]; /* Printnum buffers */ int ngood; if (wl == NULL) return; + if (eq(wl->wl_word, "col")) { col = TRUE; optgiven = TRUE; @@ -371,19 +142,30 @@ com_print(wordlist *wl) ll = 10; if (v->v_length == 1) { if (isreal(v)) { - out_printf("%s = %s\n", buf, - printnum(*v->v_realdata)); + printnum(numbuf, *v->v_realdata); + out_printf("%s = %s\n", buf, numbuf); } else { + /*DG: memory leak here copy of the string returned by printnum will never be freed out_printf("%s = %s,%s\n", buf, copy(printnum(realpart(v->v_compdata))), - copy(printnum(imagpart(v->v_compdata)))); + copy(printnum(imagpart(v->v_compdata)))); */ + + printnum(numbuf, realpart(v->v_compdata)); + printnum(numbuf2, imagpart(v->v_compdata)); + + out_printf("%s = %s,%s\n", buf, + numbuf, + numbuf2); + + } } else { out_printf("%s = ( ", buf); for (i = 0; i < v->v_length; i++) if (isreal(v)) { - (void) strcpy(buf, - printnum(v->v_realdata[i])); + + printnum(numbuf, v->v_realdata[i]); + (void) strcpy(buf, numbuf); out_send(buf); ll += strlen(buf); ll = (ll + 7) / 8; @@ -394,9 +176,12 @@ com_print(wordlist *wl) } else out_send("\t"); } else { + /*DG*/ + printnum(numbuf, realpart(&v->v_compdata[i])); + printnum(numbuf2, imagpart(&v->v_compdata[i])); (void) sprintf(buf, "%s,%s", - copy(printnum(realpart(&v->v_compdata[i]))), - copy(printnum(imagpart(&v->v_compdata[i])))); + numbuf, + numbuf2); out_send(buf); ll += strlen(buf); ll = (ll + 7) / 8; @@ -694,6 +479,7 @@ com_transpose(wordlist *wl) while (wl) { s = cp_unquote(wl->wl_word); d = vec_get(s); + tfree(s); /*DG: Avoid Memory Leak */ if (d == NULL) fprintf(cp_err, "Error: no such vector as %s.\n", wl->wl_word); @@ -708,259 +494,7 @@ com_transpose(wordlist *wl) } } -/* Set the default scale to the named vector. If no vector named, - * find and print the default scale. - */ - -void -com_setscale(wordlist *wl) -{ - struct dvec *d; - char *s; - - if (plot_cur) { - if (wl) { - s = cp_unquote(wl->wl_word); - d = vec_get(s); - if (d == NULL) - fprintf(cp_err, "Error: no such vector as %s.\n", - wl->wl_word); - else - plot_cur->pl_scale = d; - } else if (plot_cur->pl_scale) { - pvec(plot_cur->pl_scale); - } - } else { - fprintf(cp_err, "Error: no current plot.\n"); - } -} - - -/* Display vector status, etc. Note that this only displays stuff from the - * current plot, and you must do a setplot to see the rest of it. - */ - -void -com_display(wordlist *wl) -{ - struct dvec *d; - struct dvec **dvs; - int len = 0, i = 0; - bool b; - char *s; - - /* Maybe he wants to know about just a few vectors. */ - - out_init(); - while (wl) { - s = cp_unquote(wl->wl_word); - d = vec_get(s); - if (d == NULL) - fprintf(cp_err, "Error: no such vector as %s.\n", - wl->wl_word); - else - while (d) { - pvec(d); - d = d->v_link2; - } - if (wl->wl_next == NULL) - return; - wl = wl->wl_next; - } - if (plot_cur) - for (d = plot_cur->pl_dvecs; d; d = d->v_next) - len++; - if (len == 0) { - fprintf(cp_out, "There are no vectors currently active.\n"); - return; - } - out_printf("Here are the vectors currently active:\n\n"); - dvs = (struct dvec **) tmalloc(len * (sizeof (struct dvec *))); - for (d = plot_cur->pl_dvecs, i = 0; d; d = d->v_next, i++) - dvs[i] = d; - if (!cp_getvar("nosort", VT_BOOL, (char *) &b)) - qsort((char *) dvs, len, sizeof (struct dvec *), dcomp); - - out_printf("Title: %s\n", plot_cur->pl_title); - out_printf("Name: %s (%s)\nDate: %s\n\n", - plot_cur->pl_typename, plot_cur->pl_name, - plot_cur->pl_date); - for (i = 0; i < len; i++) { - d = dvs[i]; - pvec(d); - } - return; -} - -static void -pvec(struct dvec *d) -{ - char buf[BSIZE_SP], buf2[BSIZE_SP]; - - sprintf(buf, " %-20s: %s, %s, %d long", d->v_name, - ft_typenames(d->v_type), isreal(d) ? "real" : - "complex", d->v_length); - if (d->v_flags & VF_MINGIVEN) { - sprintf(buf2, ", min = %g", d->v_minsignal); - strcat(buf, buf2); - } - if (d->v_flags & VF_MAXGIVEN) { - sprintf(buf2, ", max = %g", d->v_maxsignal); - strcat(buf, buf2); - } - switch (d->v_gridtype) { - - case GRID_LOGLOG: - strcat(buf, ", grid = loglog"); - break; - - case GRID_XLOG: - strcat(buf, ", grid = xlog"); - break; - - case GRID_YLOG: - strcat(buf, ", grid = ylog"); - break; - - case GRID_POLAR: - strcat(buf, ", grid = polar"); - break; - - case GRID_SMITH: - strcat(buf, ", grid = smith (xformed)"); - break; - - case GRID_SMITHGRID: - strcat(buf, ", grid = smithgrid (not xformed)"); - break; - } - switch (d->v_plottype) { - - case PLOT_COMB: - strcat(buf, ", plot = comb"); - break; - - case PLOT_POINT: - strcat(buf, ", plot = point"); - break; - - } - if (d->v_defcolor) { - sprintf(buf2, ", color = %s", d->v_defcolor); - strcat(buf, buf2); - } - if (d->v_scale) { - sprintf(buf2, ", scale = %s", d->v_scale->v_name); - strcat(buf, buf2); - } - if (d->v_numdims > 1) { - sprintf(buf2, ", dims = [%s]", dimstring(d->v_dims, d->v_numdims)); - strcat(buf, buf2); - } - if (d->v_plot->pl_scale == d) { - strcat(buf, " [default scale]\n"); - } else { - strcat(buf, "\n"); - } - out_send(buf); - return; -} - -#ifdef notdef - -/* Set the current working plot. */ - -void -com_splot(wl) - wordlist *wl; -{ - struct plot *p; - char buf[BSIZE_SP], *s; - - if (wl == NULL) { - fprintf(cp_out, "\tType the name of the desired plot:\n\n"); - fprintf(cp_out, "\tnew\tNew plot\n"); - for (p = plot_list; p; p = p->pl_next) { - if (plot_cur == p) - fprintf(cp_out, "Current"); - fprintf(cp_out, "\t%s\t%s (%s)\n", - p->pl_typename, p->pl_title, p->pl_name); - } - fprintf(cp_out, "? "); - (void) fflush(cp_out); - (void) fgets(buf, BSIZE_SP, cp_in); - clearerr(cp_in); - for (s = buf; *s && !isspace(*s); s++) - ; - *s = '\0'; - } else { - (void) strcpy(buf, wl->wl_word); - } - if (prefix("new", buf)) { - p = plot_alloc("unknown"); - p->pl_title = copy("Anonymous"); - p->pl_name = copy("unknown"); - p->pl_next = plot_list; - plot_list = p; - } else { - for (p = plot_list; p; p = p->pl_next) - if (plot_prefix(buf, p->pl_typename)) - break; - if (!p) { - fprintf(cp_err, "Error: no such plot.\n"); - return; - } - } - plot_cur->pl_ccom = cp_kwswitch(CT_VECTOR, p->pl_ccom); - plot_cur = p; - plot_docoms(plot_cur->pl_commands); - if (wl) - fprintf(cp_out, "%s %s (%s)\n", p->pl_typename, p->pl_title, - p->pl_name); - return; -} - -#endif - -/* For the sort in display. */ - -static int -dcomp(struct dvec **v1, struct dvec **v2) -{ - return (strcmp((*v1)->v_name, (*v2)->v_name)); -} - -#ifdef notdef - -/* Figure out what the name of this vector should be (if it is a number, - * then make it 'V' or 'I')... Note that the data is static. - */ - -static char * -dname(d) - struct dvec *d; -{ - static char buf[128]; - char *s; - - for (s = d->v_name; *s; s++) - if (!isdigit(*s)) - return (d->v_name); - switch (d->v_type) { - case SV_VOLTAGE: - (void) sprintf(buf, "V(%s)", d->v_name); - return (buf); - case SV_CURRENT: - (void) sprintf(buf, "I(%s)", d->v_name); - return (buf); - } - return (d->v_name); -} - -#endif - /* Take a set of vectors and form a new vector of the nth elements of each. */ - void com_cross(wordlist *wl) { diff --git a/src/frontend/postsc.c b/src/frontend/postsc.c index a8ee78d18..d736b71bc 100644 --- a/src/frontend/postsc.c +++ b/src/frontend/postsc.c @@ -9,12 +9,13 @@ Author: 1988 Jeffrey M. Hsu #include "ngspice.h" #include "cpdefs.h" -#include "ftegraph.h" +#include "graph.h" #include "ftedbgra.h" #include "ftedev.h" #include "fteinput.h" -#include "postsc.h" +#include "postsc.h" +#include "variable.h" #define RAD_TO_DEG (180.0 / M_PI) #define DEVDEP(g) (*((PSdevdep *) (g)->devdep)) @@ -115,16 +116,6 @@ PS_Init(void) ytadj = YTADJ * scale * fontsize / 10; } -#ifdef notdef - if (fontsize > 11) - gridsize = GRIDSIZES; - else - gridsize = GRIDSIZE; - - dispdev->width = gridsize+16*fontwidth; /* was 612, p.w.h. */ - dispdev->height = gridsize+8*fontheight; /* was 612, p.w.h. */ -#endif - screenflag = 0; dispdev->minx = XOFF / scale; dispdev->miny = YOFF / scale; @@ -149,40 +140,6 @@ PS_NewViewport(GRAPH *graph) /* hardcopying from the screen */ screenflag = 1; - - /* scale to fit on 8 1/2 square */ -#ifdef notdef - /* Face it, this is bogus */ -#ifdef notdef - fprintf(plotfile, "%g %g scale\n", - (double) dispdev->width / graph->absolute.width, - (double) dispdev->height / graph->absolute.height); -#endif - - scalex = (double) graph->absolute.width / dispdev->width; - scaley = (double) graph->absolute.height / dispdev->width; - /* scale left and bottom printer margin */ - scaleps = ((scalex > scaley) ? scalex : scaley) / scale; - xoff = (int) (scaleps * (double) XOFF); - yoff = (int) (scaleps * (double) YOFF); - xtadj = 0; - ytadj = 0; - scalex = (double) dispdev->width / graph->absolute.width; - scaley = (double) dispdev->width / graph->absolute.height; - - if (gtype == GRID_SMITH || gtype == GRID_SMITHGRID - || gtype == GRID_POLAR) - { - scaleps = scale * ((scalex < scaley) ? scalex : scaley); - fprintf(plotfile, "%g %g scale\n", scaleps, scaleps); - } else { - fprintf(plotfile, "%g %g scale\n", scale*scalex, scale*scaley); - } - - /* re-scale linestyles */ - gr_relinestyle(graph); -#endif - } /* reasonable values, used in gr_ for placement */ @@ -202,17 +159,14 @@ PS_NewViewport(GRAPH *graph) fprintf(plotfile, "%%!PS-Adobe-3.0 EPSF-3.0\n"); fprintf(plotfile, "%%%%Creator: nutmeg\n"); fprintf(plotfile, "%%%%BoundingBox: %d %d %d %d\n", - (int) (.75 * 72), (int) (.75 * 72), - (int) (8.5 * 72), (int) (8.5 * 72)); + (int) (.75 * 72), (int) (.75 * 72), + (int) (8.5 * 72), (int) (8.5 * 72)); -#ifdef notdef - if (!screenflag) -#endif - fprintf(plotfile, "%g %g scale\n", 1.0 / scale, 1.0 / scale); + fprintf(plotfile, "%g %g scale\n", 1.0 / scale, 1.0 / scale); /* set up a reasonable font */ fprintf(plotfile, "/%s findfont %d scalefont setfont\n", - psfont, (int) (fontsize * scale)); + psfont, (int) (fontsize * scale)); graph->devdep = tmalloc(sizeof(PSdevdep)); DEVDEP(graph).lastlinestyle = -1; diff --git a/src/frontend/rawfile.c b/src/frontend/rawfile.c index 8f96ac24e..5cc6d206d 100644 --- a/src/frontend/rawfile.c +++ b/src/frontend/rawfile.c @@ -11,9 +11,10 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" -#include "rawfile.h" +#include "dvec.h" +#include "rawfile.h" +#include "variable.h" /* static declarations */ static void fixdims(struct dvec *v, char *s); @@ -37,6 +38,7 @@ raw_write(char *name, struct plot *pl, bool app, bool binary) wordlist *wl; struct variable *vv; double dd; + char buf[BSIZE_SP]; if (!cp_getvar("nopadding", VT_BOOL, (char *) &raw_padding)) raw_padding = FALSE; @@ -90,7 +92,8 @@ raw_write(char *name, struct plot *pl, bool app, bool binary) fprintf(fp, "No. Variables: %d\n", nvars); fprintf(fp, "No. Points: %d\n", length); if (numdims > 1) { - fprintf(fp, "Dimensions: %s\n", dimstring(dims, numdims)); + dimstring(dims, numdims, buf); + fprintf(fp, "Dimensions: %s\n", buf); } for (wl = pl->pl_commands; wl; wl = wl->wl_next) @@ -146,7 +149,8 @@ raw_write(char *name, struct plot *pl, bool app, bool binary) writedims = TRUE; } if (writedims) { - fprintf(fp, " dims=%s", dimstring(v->v_dims, v->v_numdims)); + dimstring(v->v_dims, v->v_numdims, buf); + fprintf(fp, " dims=%s",buf); } (void) putc('\n', fp); } @@ -241,7 +245,7 @@ raw_read(char *name) char *date = 0; struct plot *plots = NULL, *curpl = NULL; char buf[BSIZE_SP], buf2[BSIZE_SP], *s, *t, *r; - int flags, nvars, npoints, i, j; + int flags = 0, nvars = 0, npoints = 0, i, j; int ndimpoints, numdims=0, dims[MAXDIMS]; bool raw_padded = TRUE; double junk; @@ -303,7 +307,7 @@ raw_read(char *name) } else if (ciprefix("flags:", buf)) { s = buf; skip(s); - while (t = gettok(&s)) { + while ((t = gettok(&s))) { if (cieq(t, "real")) flags |= VF_REAL; else if (cieq(t, "complex")) @@ -453,7 +457,7 @@ raw_read(char *name) v->v_name = copy(buf2); } /* Now come the strange options... */ - while (t = gettok(&s)) { + while ((t = gettok(&s))) { if (ciprefix("min=", t)) { if (sscanf(t + 4, "%lf", &v->v_minsignal) != 1) diff --git a/src/frontend/resource.c b/src/frontend/resource.c index 6645c36ea..d9fa08414 100644 --- a/src/frontend/resource.c +++ b/src/frontend/resource.c @@ -11,10 +11,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" + +#include "circuits.h" +#include "quote.h" #include "resource.h" - - - +#include "variable.h" /* static declarations */ static void printres(char *name); @@ -31,10 +32,13 @@ char *enddata; void init_rlimits(void) { - +#ifndef __MINGW32__ startdata = (char *) baseaddr( ); enddata = sbrk(0); - +#else + startdata = 0; + enddata = 0; +#endif } void @@ -57,13 +61,17 @@ init_time(void) void com_rusage(wordlist *wl) { +char* copyword; /* Fill in the SPICE accounting structure... */ if (wl && (eq(wl->wl_word, "everything") || eq(wl->wl_word, "all"))) { printres((char *) NULL); } else if (wl) { for (; wl; wl = wl->wl_next) { - printres(cp_unquote(wl->wl_word)); + /* printres(cp_unquote(wl->wl_word)); DG: bad, memory leak*/ + copyword=cp_unquote(wl->wl_word);/*DG*/ + printres(copyword); + tfree(copyword); if (wl->wl_next) (void) putc('\n', cp_out); } @@ -86,7 +94,7 @@ ft_ckspace(void) static long old_usage = 0; char *hi; - +#ifndef __MINGW32__ # ifdef HAVE_GETRLIMIT struct rlimit rld; @@ -103,8 +111,10 @@ ft_ckspace(void) # endif hi=sbrk(0); usage = (long) (hi - enddata); - - +#else + usage = 0; + limit = 0; +#endif if (limit < 0) return; /* what else do you do? */ @@ -304,7 +314,7 @@ fault(void) signal(SIGSEGV, (SIGNAL_FUNCTION) fault); /* SysV style */ longjmp(env, 1); } - +#ifndef __MINGW32__ static void * baseaddr(void) { @@ -326,16 +336,6 @@ baseaddr(void) at = (char *) ((((long)low >> LOG2_PAGESIZE) + ((long)high >> LOG2_PAGESIZE)) << (LOG2_PAGESIZE - 1)); -# ifdef notdef - at = (char *) ((((int) low + (int) high) / 2 + 0x7ff) - & ~(long) 0xfff); - /* nearest page */ -# endif -# ifdef notdef - printf( - "high = %#8x low = %#8x at = %#8x\n", - high, low, at); -# endif if (at == low || at == high) { break; @@ -357,13 +357,10 @@ baseaddr(void) } while (1); -# ifdef notdef - printf ("start is at %#x, end is at %#x\n", high, sbrk(0)); -# endif (void) signal(SIGSEGV, (SIGNAL_FUNCTION) orig_signal); return (void *) high; } - +#endif # ifdef notdef main( ) { diff --git a/src/frontend/runcoms.c b/src/frontend/runcoms.c index 4b37c2cba..560df7738 100644 --- a/src/frontend/runcoms.c +++ b/src/frontend/runcoms.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +Modified: 2000 AlansFixes **********/ /* @@ -12,8 +13,18 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ftedefs.h" #include "ftedev.h" #include "ftedebug.h" -#include "ftedata.h" +#include "dvec.h" + +#include "circuits.h" +#include "completion.h" #include "runcoms.h" +#include "variable.h" + +#ifdef XSPICE +/* gtri - add - 12/12/90 - wbk - include ipc stuff */ +#include "ipctiein.h" +/* gtri - end - 12/12/90 */ +#endif /* static declarations */ static int dosim(char *what, wordlist *wl); @@ -30,6 +41,11 @@ extern struct dbcomm *dbs; FILE *rawfileFp; bool rawfileBinary; +#define RAWBUF_SIZE 32768 +char rawfileBuf[RAWBUF_SIZE]; +/*To tell resume the rawfile name saj*/ +char *last_used_rawfile = NULL; +/*end saj */ void com_scirc(wordlist *wl) @@ -144,7 +160,7 @@ com_noise(wordlist *wl) static int dosim(char *what, wordlist *wl) { - wordlist *ww; + wordlist *ww = NULL; bool dofile = FALSE; char buf[BSIZE_SP]; struct circ *ct; @@ -194,10 +210,6 @@ dosim(char *what, wordlist *wl) ft_setflag = FALSE; return 0; } -#ifdef notdef - if (ft_curckt->ci_runonce) - com_rset((wordlist *) NULL); -#endif /* From now on until the next prompt, an interrupt will just * set a flag and let spice finish up, then control will be @@ -212,9 +224,10 @@ dosim(char *what, wordlist *wl) if (!*wl->wl_word) rawfileFp = stdout; else if (!(rawfileFp = fopen(wl->wl_word, "w"))) { - perror(wl->wl_word); - ft_setflag = FALSE; - return 1; + setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE); + perror(wl->wl_word); + ft_setflag = FALSE; + return 1; } rawfileBinary = !ascii; #ifdef PARALLEL_ARCH @@ -224,12 +237,16 @@ dosim(char *what, wordlist *wl) #endif /* PARALLEL_ARCH */ } else { rawfileFp = NULL; -#ifdef notdef - XXX why? - plot_num++; /* There should be a better way */ -#endif } - + /*save rawfile name saj*/ + if(last_used_rawfile) free((void *)last_used_rawfile); + if(rawfileFp){ + last_used_rawfile = copy(wl->wl_word); + }else { + last_used_rawfile = NULL; + } + /*end saj*/ + /* Spice calls wrd_init and wrd_end itself */ ft_curckt->ci_inprogress = TRUE; if (eq(what,"sens2")) { @@ -237,6 +254,13 @@ dosim(char *what, wordlist *wl) /* The circuit was interrupted somewhere. */ fprintf(cp_err, "%s simulation interrupted\n", what); +#ifdef XSPICE + /* gtri - add - 12/12/90 - wbk - record error and return errchk */ + g_ipc.run_error = IPC_TRUE; + if(g_ipc.enabled) + ipc_send_errchk(); + /* gtri - end - 12/12/90 */ +#endif } else ft_curckt->ci_inprogress = FALSE; } else { @@ -244,6 +268,13 @@ dosim(char *what, wordlist *wl) if (err == 1) { /* The circuit was interrupted somewhere. */ fprintf(cp_err, "%s simulation interrupted\n", what); +#ifdef XSPICE + /* gtri - add - 12/12/90 - wbk - record error and return errchk */ + g_ipc.run_error = IPC_TRUE; + if(g_ipc.enabled) + ipc_send_errchk(); + /* gtri - end - 12/12/90 */ +#endif err = 0; } else if (err == 2) { fprintf(cp_err, "%s simulation(s) aborted\n", what); @@ -252,8 +283,14 @@ dosim(char *what, wordlist *wl) } else ft_curckt->ci_inprogress = FALSE; } - if (rawfileFp) - (void) fclose(rawfileFp); + if (rawfileFp){ + if (ftell(rawfileFp)==0) { + (void) fclose(rawfileFp); + (void) remove(wl->wl_word); + } else { + (void) fclose(rawfileFp); + } + } ft_curckt->ci_runonce = TRUE; ft_setflag = FALSE; return err; @@ -288,6 +325,13 @@ bool ft_getOutReq(FILE **fpp, struct plot **plotp, bool *binp, char *name, char *title) { /*struct plot *pl;*/ +#ifndef BATCH + + if ( (strcmp(name, "Operating Point")==0) || + (strcmp(name, "AC Operating Point")==0) ) { + return (FALSE); + }; +#endif if (rawfileFp) { *fpp = rawfileFp; diff --git a/src/frontend/runcoms2.c b/src/frontend/runcoms2.c index adef8c205..455a0f973 100644 --- a/src/frontend/runcoms2.c +++ b/src/frontend/runcoms2.c @@ -12,12 +12,19 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ftedefs.h" #include "ftedev.h" #include "ftedebug.h" -#include "ftedata.h" -#include "runcoms2.h" +#include "dvec.h" +#include "circuits.h" +#include "runcoms2.h" +#include "variable.h" extern FILE *rawfileFp; extern bool rawfileBinary; +/*rawfile output saj*/ +extern char *last_used_rawfile; +#define RAWBUF_SIZE 32768 +char rawfileBuf[RAWBUF_SIZE]; +/*end saj*/ extern struct dbcomm *dbs; /* Continue a simulation. If there is non in progress, this is the @@ -40,6 +47,22 @@ com_resume(wordlist *wl) { struct dbcomm *db; int err; + + /*rawfile output saj*/ + bool dofile = FALSE; + char buf[BSIZE_SP]; + bool ascii = AsciiRawFile; + /*end saj*/ + + /*saj fix segment*/ + if (!ft_curckt) { + fprintf(cp_err, "Error: there aren't any circuits loaded.\n"); + return; + } else if (ft_curckt->ci_ckt == NULL) { /* Set noparse? */ + fprintf(cp_err, "Error: circuit not parsed.\n"); + return; + } + /*saj*/ if (ft_curckt->ci_inprogress == FALSE) { fprintf(cp_err, "Note: run starting\n"); @@ -49,13 +72,70 @@ com_resume(wordlist *wl) ft_curckt->ci_inprogress = TRUE; ft_setflag = TRUE; + + reset_trace( ); for ( db = dbs, resumption = FALSE; db; db = db->db_next ) if( db->db_type == DB_IPLOT || db->db_type == DB_IPLOTALL ) { resumption = TRUE; } + + /*rawfile output saj*/ + if (last_used_rawfile) + dofile = TRUE; + + if (cp_getvar("filetype", VT_STRING, buf)) { + if (eq(buf, "binary")) + ascii = FALSE; + else if (eq(buf, "ascii")) + ascii = TRUE; + else + fprintf(cp_err, + "Warning: strange file type \"%s\" (using \"ascii\")\n", + buf); + } + + if (dofile) { +#ifdef PARALLEL_ARCH + if (ARCHme == 0) { +#endif /* PARALLEL_ARCH */ + if (!last_used_rawfile) + rawfileFp = stdout; + else if (!(rawfileFp = fopen(last_used_rawfile, "a"))) { + setvbuf(rawfileFp, rawfileBuf, _IOFBF, RAWBUF_SIZE); + perror(last_used_rawfile); + ft_setflag = FALSE; + return; + } + rawfileBinary = !ascii; +#ifdef PARALLEL_ARCH + } else { + rawfileFp = NULL; + } +#endif /* PARALLEL_ARCH */ + } else { + rawfileFp = NULL; + } + + + + + /*end saj*/ + err = if_run(ft_curckt->ci_ckt, "resume", (wordlist *) NULL, - ft_curckt->ci_symtab); + ft_curckt->ci_symtab); + + /*close rawfile saj*/ + if (rawfileFp){ + if (ftell(rawfileFp)==0) { + (void) fclose(rawfileFp); + (void) remove(last_used_rawfile); + } else { + (void) fclose(rawfileFp); + } + } + /*end saj*/ + if (err == 1) { /* The circuit was interrupted somewhere. */ diff --git a/src/frontend/shyu.c b/src/frontend/shyu.c index ebb364c40..c1a7a8c1d 100644 --- a/src/frontend/shyu.c +++ b/src/frontend/shyu.c @@ -14,11 +14,13 @@ Copyright 1990 Regents of the University of California. All rights reserved. #include "cpdefs.h" #include "ftedefs.h" #include "fteinp.h" -#include "fteconst.h" +#include "sim.h" #include "devdefs.h" #include "inpdefs.h" #include "iferrmsg.h" #include "ifsim.h" + +#include "circuits.h" #include "shyu.h" diff --git a/src/frontend/spec.c b/src/frontend/spec.c index b78f369c7..e904d8bae 100644 --- a/src/frontend/spec.c +++ b/src/frontend/spec.c @@ -9,9 +9,11 @@ Author: 1994 Anthony E. Parker, Department of Electronics, Macquarie Uni. #include "ngspice.h" #include "ftedefs.h" -#include "ftedata.h" -#include "spec.h" +#include "dvec.h" +#include "sim.h" +#include "spec.h" +#include "variable.h" void com_spec(wordlist *wl) @@ -23,7 +25,7 @@ com_spec(wordlist *wl) int fpts, i, j, k, tlen, ngood; bool trace; char *s; - struct dvec *f, *vlist, *lv, *vec; + struct dvec *f, *vlist, *lv = NULL, *vec; struct pnode *names, *first_name; if (!plot_cur || !plot_cur->pl_scale) { diff --git a/src/frontend/spiceif.c b/src/frontend/spiceif.c index af414b488..0b445d60e 100644 --- a/src/frontend/spiceif.c +++ b/src/frontend/spiceif.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +Modified: 2000 AlansFixes **********/ /* @@ -13,14 +14,27 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice.h" #include "cpdefs.h" +#include "tskdefs.h" /* Is really needed ? */ #include "ftedefs.h" #include "fteinp.h" -#include "fteconst.h" #include "inpdefs.h" #include "iferrmsg.h" #include "ifsim.h" -#include "spiceif.h" +#include "circuits.h" +#include "spiceif.h" +#include "variable.h" + +#ifdef XSPICE +/* gtri - add - wbk - 11/9/90 - include MIF function prototypes */ +#include "mifproto.h" +/* gtri - end - wbk - 11/9/90 */ + +/* gtri - evt - wbk - 5/20/91 - Add stuff for user-defined nodes */ +#include "evtproto.h" +#include "evtudn.h" +/* gtri - end - wbk - 5/20/91 - Add stuff for user-defined nodes */ +#endif /* static declarations */ static struct variable * parmtovar(IFvalue *pv, IFparm *opt); @@ -49,27 +63,32 @@ if_inpdeck(struct line *deck, INPtables **tab) i++; *tab = INPtabInit(i); ft_curckt->ci_symtab = *tab; - if ((err = (*(ft_sim->newCircuit))(&ckt)) - != OK) { + + err = (*(ft_sim->newCircuit))(&ckt); + if (err != OK) { ft_sperror(err, "CKTinit"); return (NULL); } + err = IFnewUid(ckt,&taskUid,(IFuid)NULL,"default",UID_TASK,(void**)NULL); if(err) { ft_sperror(err,"newUid"); return(NULL); } + err = (*(ft_sim->newTask))(ckt,(void**)&(ft_curckt->ci_defTask),taskUid); if(err) { ft_sperror(err,"newTask"); return(NULL); } + for(j=0;jnumAnalyses;j++) { if(strcmp(ft_sim->analyses[j]->name,"options")==0) { which = j; break; } } + if(which != -1) { err = IFnewUid(ckt,&optUid,(IFuid)NULL,"options",UID_ANALYSIS, (void**)NULL); @@ -77,6 +96,7 @@ if_inpdeck(struct line *deck, INPtables **tab) ft_sperror(err,"newUid"); return(NULL); } + err = (*(ft_sim->newAnalysis))(ft_curckt->ci_ckt,which,optUid, (void**)&(ft_curckt->ci_defOpt), (void*)ft_curckt->ci_defTask); @@ -84,24 +104,44 @@ if_inpdeck(struct line *deck, INPtables **tab) ft_sperror(err,"createOptions"); return(NULL); } + ft_curckt->ci_curOpt = ft_curckt->ci_defOpt; } + ft_curckt->ci_curTask = ft_curckt->ci_defTask; INPpas1((void *) ckt, (card *) deck->li_next,(INPtables *)*tab); INPpas2((void *) ckt, (card *) deck->li_next, (INPtables *) *tab,ft_curckt->ci_defTask); INPkillMods(); + + /* INPpas2 has been modified to ignore .NODESET and .IC + * cards. These are left till INPpas3 so that we can check for + * nodeset/ic of non-existant nodes. */ + + INPpas3((void *) ckt, (card *) deck->li_next, + (INPtables *) *tab,ft_curckt->ci_defTask, ft_sim->nodeParms, + ft_sim->numNodeParms); + +#ifdef XSPICE +/* gtri - begin - wbk - 6/6/91 - Finish initialization of event driven structures */ + err = EVTinit((void *) ckt); + if(err) { + ft_sperror(err,"EVTinit"); + return(NULL); + } +/* gtri - end - wbk - 6/6/91 - Finish initialization of event driven structures */ +#endif + return (ckt); } -/* Do a run of the circuit, of the given type. Type "resume" is special -- - * it means to resume whatever simulation that was in progress. The - * return value of this routine is 0 if the exit was ok, and 1 if there was - * a reason to interrupt the circuit (interrupt typed at the keyboard, - * error in the simulation, etc). args should be the entire command line, - * e.g. "tran 1 10 20 uic" - */ +/* Do a run of the circuit, of the given type. Type "resume" is + * special -- it means to resume whatever simulation that was in + * progress. The return value of this routine is 0 if the exit was ok, + * and 1 if there was a reason to interrupt the circuit (interrupt + * typed at the keyboard, error in the simulation, etc). args should + * be the entire command line, e.g. "tran 1 10 20 uic" */ int if_run(char *t, char *what, wordlist *args, char *tab) { @@ -112,17 +152,26 @@ if_run(char *t, char *what, wordlist *args, char *tab) int j; int which = -1; IFuid specUid,optUid; - + + /* First parse the line... */ - if (eq(what, "tran") || eq(what, "ac") || eq(what, "dc") - || eq(what, "op") || eq(what, "pz") || eq(what,"disto") - || eq(what, "adjsen") || eq(what, "sens") || eq(what,"tf") - || eq(what, "noise")) { + if (eq(what, "tran") + || eq(what, "ac") + || eq(what, "dc") + || eq(what, "op") + || eq(what, "pz") + || eq(what,"disto") + || eq(what, "adjsen") + || eq(what, "sens") + || eq(what,"tf") + || eq(what, "noise")) + { (void) sprintf(buf, ".%s", wl_flatten(args)); deck.li_next = deck.li_actual = NULL; deck.li_error = NULL; deck.li_linenum = 0; deck.li_line = buf; + if(ft_curckt->ci_specTask) { err=(*(ft_sim->deleteTask))(ft_curckt->ci_ckt, ft_curckt->ci_specTask); @@ -139,10 +188,14 @@ if_run(char *t, char *what, wordlist *args, char *tab) } err = (*(ft_sim->newTask))(ft_curckt->ci_ckt, (void**)&(ft_curckt->ci_specTask),specUid); + + if(err) { ft_sperror(err,"newTask"); return(2); } + + for(j=0;jnumAnalyses;j++) { if(strcmp(ft_sim->analyses[j]->name,"options")==0) { which = j; @@ -163,29 +216,89 @@ if_run(char *t, char *what, wordlist *args, char *tab) ft_sperror(err,"createOptions"); return(2); } - ft_curckt->ci_curOpt = ft_curckt->ci_specOpt; + ft_curckt->ci_curOpt = ft_curckt->ci_specOpt; + + /* This is a very dirty hack but it is the only one I + was able to find without intervening on all the code + It will be changed in the future. */ + + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKtemp = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKtemp; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKnomTemp = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKnomTemp; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKgmin = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKgmin; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKgshunt = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKgshunt; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKabstol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKabstol; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKreltol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKreltol; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKchgtol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKchgtol; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKvoltTol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKvoltTol; +#ifdef NEWTRUNC + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKlteReltol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKlteReltol; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKlteAbstol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKlteAbstol; +#endif + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKtrtol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKtrtol; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKbypass = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKbypass; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKtranMaxIter = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKtranMaxIter; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKdcMaxIter = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdcMaxIter; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKdcTrcvMaxIter = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdcTrcvMaxIter; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKintegrateMethod = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKintegrateMethod; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKmaxOrder = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKmaxOrder; + + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKnumSrcSteps = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKnumSrcSteps; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKnumGminSteps = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKnumGminSteps; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKgminFactor = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKgminFactor; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKpivotAbsTol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKpivotAbsTol; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKpivotRelTol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKpivotRelTol; + + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKdefaultMosM = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdefaultMosM; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKdefaultMosL = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdefaultMosL; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKdefaultMosW = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdefaultMosW; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKdefaultMosAD = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdefaultMosAD; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKdefaultMosAS = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdefaultMosAS; + + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKnoOpIter = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKnoOpIter; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKtryToCompact = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKtryToCompact; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKbadMos3 = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKbadMos3; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKkeepOpInfo = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKkeepOpInfo; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKcopyNodesets = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKcopyNodesets; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKnodeDamping = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKnodeDamping; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKabsDv = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKabsDv; + ((TSKtask *)(ft_curckt->ci_specOpt))->TSKrelDv = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKrelDv; + + } ft_curckt->ci_curTask = ft_curckt->ci_specTask; - INPpas2(ckt, (card *) &deck, (INPtables *)tab, ft_curckt->ci_specTask); + + + INPpas2(ckt, (card *) &deck, (INPtables *)tab, ft_curckt->ci_specTask); + if (deck.li_error) { fprintf(cp_err, "Warning: %s\n", deck.li_error); return 2; } } + +/* -- *** BUG! ****/ +/* -- A bug fix suggested by Cecil Aswell (aswell@netcom.com) to let */ +/* -- the interactive analysis commands get the current temperature */ +/* -- and other options. */ + if( eq(what,"run") ) { ft_curckt->ci_curTask = ft_curckt->ci_defTask; ft_curckt->ci_curOpt = ft_curckt->ci_defOpt; } - if ( (eq(what, "tran")) || - (eq(what, "ac")) || - (eq(what, "dc")) || - (eq(what, "op")) || - (eq(what, "pz")) || - (eq(what, "disto")) || - (eq(what, "noise")) || - eq(what, "adjsen") || eq(what, "sens") || eq(what,"tf") || - (eq(what, "run")) ) { +/* -- Find out what we are supposed to do. */ + + if ( (eq(what, "tran")) + ||(eq(what, "ac")) + ||(eq(what, "dc")) + ||(eq(what, "op")) + ||(eq(what, "pz")) + ||(eq(what, "disto")) + ||(eq(what, "noise")) + ||(eq(what, "adjsen")) + ||(eq(what, "sens")) + ||(eq(what,"tf")) + ||(eq(what, "run")) ) { if ((err = (*(ft_sim->doAnalyses))(ckt, 1, ft_curckt->ci_curTask))!=OK){ ft_sperror(err, "doAnalyses"); /* wrd_end(); */ @@ -725,44 +838,6 @@ finddev(void *ck, char *name, void **devptr, void **modptr) } -#ifdef notdef -/* XXX Not useful */ -/* Extract the node and device names from the line and add them to the command - * completion structure. This is probably not a good thing to do if it - * takes too much time. - */ - - /* BLOW THIS AWAY */ - -void -if_setndnames(line) - char *line; -{ - char *t; - int i; - - while (isspace(*line)) - line++; - - if (!*line || (*line == '*') || (*line == '.')) - return; - t = gettok(&line); - - if (!(i = inp_numnodes(*t))) - return; - if ((*t == 'q') || (*t == 'Q')) - i = 3; - - cp_addkword(CT_DEVNAMES, t); - while (i-- > 0) { - t = gettok(&line); - if (t) - cp_addkword(CT_NODENAMES, t); - } - return; -} -#endif - /* get an analysis parameter by name instead of id */ int @@ -806,7 +881,7 @@ if_tranparams(struct circ *ci, double *start, double *stop, double *step) UID_ANALYSIS, (void**)NULL); if(err != OK) return(FALSE); err =(*(ft_sim->findAnalysis))(ci->ci_ckt,&which, &anal,tranUid, - ci->ci_curTask,(IFuid *)NULL); + ci->ci_curTask,(IFuid )NULL); if(err != OK) return(FALSE); err = if_analQbyName(ci->ci_ckt,which,anal,"tstart",&tmp); if(err != OK) return(FALSE); @@ -884,3 +959,381 @@ if_getstat(void *ckt, char *name) } } +#ifdef EXPERIMENTAL_CODE + +#include +#include + +/* arg0: circuit file, arg1: data file */ +void com_loadsnap(wordlist *wl) { + int error = 0; + FILE *file; + int tmpI, i, size; + CKTcircuit *my_ckt, *ckt; + + /* + Phesudo code: + + source(file_name); + This should setup all the device structs, voltage nodes, etc. + + call cktsetup; + This is needed to setup vector mamory allocation for vectors and branch nodes + + load_binary_data(info); + Overwrite the allocated numbers, rhs etc, with saved data + */ + + + if (ft_curckt) { + fprintf(cp_err, "Error: there is already a circuit loaded.\n"); + return; + } + + /* source the circuit */ + inp_source(wl->wl_word); + if (!ft_curckt) { + return; + } + + /* allocate all the vectors, with luck! */ + if (!error) + error = CKTsetup((CKTcircuit *)ft_curckt->ci_ckt); + if (!error) + error = CKTtemp((CKTcircuit *)ft_curckt->ci_ckt); + + if(error) { + fprintf(cp_err,"Some error in the CKT setup fncts!\n"); + return; + } + + /* so it resumes ... */ + ft_curckt->ci_inprogress = TRUE; + + + /* now load the binary file */ + + + ckt = (CKTcircuit *)ft_curckt->ci_ckt; + + file = fopen(wl->wl_next->wl_word,"rb"); + + if(!file) { + fprintf(cp_err, + "Error: Couldn't open \"%s\" for reading\n", + wl->wl_next->wl_word); + return; + } + + fread(&tmpI,sizeof(int),1,file); + if(tmpI != sizeof(CKTcircuit) ) { + fprintf(cp_err,"loaded num: %d, expected num: %d\n",tmpI,sizeof(CKTcircuit)); + fprintf(cp_err, + "Error: snapshot saved with different version of spice\n"); + fclose(file); + return; + } + + my_ckt = (CKTcircuit *)tmalloc(sizeof(CKTcircuit)); + + fread(my_ckt,sizeof(CKTcircuit),1,file); + +#define _t(name) ckt->name = my_ckt->name +#define _ta(name,size)\ + do{ int __i; for(__i=0;__iCKTmaxOrder+1;i++) { + _foo(ckt->CKTstates[i],double,ckt->CKTnumStates); + } + + size = SMPmatSize(ckt->CKTmatrix) + 1; + _foo(ckt->CKTrhs, double,size); + _foo(ckt->CKTrhsOld, double,size); + _foo(ckt->CKTrhsSpare, double,size); + _foo(ckt->CKTirhs, double,size); + _foo(ckt->CKTirhsOld, double,size); + _foo(ckt->CKTirhsSpare, double,size); + _foo(ckt->CKTrhsOp, double,size); + _foo(ckt->CKTsenRhs, double,size); + _foo(ckt->CKTseniRhs, double,size); + + _foo(ckt->CKTtimePoints,double,-1); + _foo(ckt->CKTdeltaList,double,-1); + + _foo(ckt->CKTbreaks,double,ckt->CKTbreakSize); + + _foo((TSKtask *)ft_curckt->ci_curTask,TSKtask,1); + + /* To stop the Free */ + ((TSKtask *)ft_curckt->ci_curTask)->TSKname = NULL; + ((TSKtask *)ft_curckt->ci_curTask)->jobs = NULL; + + _foo(((TSKtask *)ft_curckt->ci_curTask)->TSKname,char,-1); + + _foo(((TRANan *)((TSKtask *)ft_curckt->ci_curTask)->jobs),TRANan,1); + ((TSKtask *)ft_curckt->ci_curTask)->jobs->JOBname = NULL; + ckt->CKTcurJob = (JOB *)((TSKtask *)ft_curckt->ci_curTask)->jobs; + + _foo(((TSKtask *)ft_curckt->ci_curTask)->jobs->JOBname,char,-1); + + ((TSKtask *)ft_curckt->ci_curTask)->jobs->JOBnextJob = NULL; + + ((TRANan *)((TSKtask *)ft_curckt->ci_curTask)->jobs)->TRANplot = NULL; + + _foo(ckt->CKTstat,STATistics,1); + + tfree(my_ckt); + fclose(file); + + /* Finally to resume the plot in some fashion */ + + /* a worked out version of this should be enough */ + { + IFuid *nameList; + int numNames; + IFuid timeUid; + + error = CKTnames(ckt,&numNames,&nameList); + if(error){ + fprintf(cp_err,"error in CKTnames\n"); + return; + } + (*(SPfrontEnd->IFnewUid))((void *)ckt,&timeUid,(IFuid)NULL, + "time", UID_OTHER, (void **)NULL); + error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob, + ckt->CKTcurJob->JOBname,timeUid,IF_REAL,numNames,nameList, + IF_REAL,&(((TRANan*)ckt->CKTcurJob)->TRANplot)); + if(error) { + fprintf(cp_err,"error in CKTnames\n"); + return; + } + } + + + + return ; +} + +void com_savesnap(wordlist *wl) { + FILE *file; + int i, size; + CKTcircuit *ckt; + TSKtask *task; + + if (!ft_curckt) { + fprintf(cp_err, "Error: there is no circuit loaded.\n"); + return; + } else if (ft_curckt->ci_ckt == NULL) { /* Set noparse? */ + fprintf(cp_err, "Error: circuit not parsed.\n"); + return; + } + + /* save the data */ + + ckt = (CKTcircuit *)ft_curckt->ci_ckt; + + task = (TSKtask *)ft_curckt->ci_curTask; + + if(task->jobs->JOBtype != 4) { + fprintf(cp_err,"Only saving of tran analysis is implemented\n"); + return; + } + + file = fopen(wl->wl_word,"wb"); + + if(!file) { + fprintf(cp_err, + "Error: Couldn't open \"%s\" for writing\n",wl->wl_word); + return; + } + +#undef _foo +#define _foo(name,type,num)\ + do {\ + int __i;\ + if(name) {\ + __i = (num) * sizeof(type); fwrite(&__i,sizeof(int),1,file);\ + if((num))\ + fwrite(name,sizeof(type),(num),file);\ + } else {\ + __i = 0;\ + fprintf(cp_err,#name " is NULL, zero written\n");\ + fwrite(&__i,sizeof(int),1,file);\ + }\ + } while(0) + + + _foo(ckt,CKTcircuit,1); + + /* To save list + + double *(CKTstates[8]); + double *CKTrhs; + double *CKTrhsOld; + double *CKTrhsSpare; + double *CKTirhs; + double *CKTirhsOld; + double *CKTirhsSpare; + double *CKTrhsOp; + double *CKTsenRhs; + double *CKTseniRhs; + double *CKTtimePoints; list of all accepted timepoints in + the current transient simulation + double *CKTdeltaList; list of all timesteps in the + current transient simulation + + */ + + + for(i=0;i<=ckt->CKTmaxOrder+1;i++) { + _foo(ckt->CKTstates[i],double,ckt->CKTnumStates); + } + + + + size = SMPmatSize(ckt->CKTmatrix) + 1; + + _foo(ckt->CKTrhs,double,size); + _foo(ckt->CKTrhsOld,double,size); + _foo(ckt->CKTrhsSpare,double,size); + _foo(ckt->CKTirhs,double,size); + _foo(ckt->CKTirhsOld,double,size); + _foo(ckt->CKTirhsSpare,double,size); + _foo(ckt->CKTrhsOp,double,size); + _foo(ckt->CKTsenRhs,double,size); + _foo(ckt->CKTseniRhs,double,size); + + _foo(ckt->CKTtimePoints,double,ckt->CKTtimeListSize); + _foo(ckt->CKTdeltaList,double,ckt->CKTtimeListSize); + + /* need to save the breakpoints, or something */ + + _foo(ckt->CKTbreaks,double,ckt->CKTbreakSize); + + + /* now save the TSK struct, ft_curckt->ci_curTask*/ + + _foo(task,TSKtask,1); + _foo(task->TSKname,char,(strlen(task->TSKname)+1)); + + /* now save the JOB struct task->jobs */ + /* lol, only allow one job, tough! */ + /* Note that JOB is a base class, need to save actual type!! */ + + _foo(task->jobs,TRANan,1); + + _foo(task->jobs->JOBname,char,(strlen(task->jobs->JOBname)+1)); + + + /* Finally the stats */ + + _foo(ckt->CKTstat,STATistics,1); + + + fclose(file); + + return; + +} + +#endif diff --git a/src/frontend/spiceif.h b/src/frontend/spiceif.h index 4367e29af..55346cd05 100644 --- a/src/frontend/spiceif.h +++ b/src/frontend/spiceif.h @@ -18,6 +18,10 @@ int if_analQbyName(void *ckt, int which, void *anal, char *name, IFvalue *parm) bool if_tranparams(struct circ *ci, double *start, double *stop, double *step); struct variable * if_getstat(void *ckt, char *name); +#ifdef EXPERIMENTAL_CODE +void if_loadsnap(wordlist *wl); +void if_savesnap(wordlist *wl); +#endif #endif diff --git a/src/frontend/subckt.c b/src/frontend/subckt.c index dbc26a588..46baaf888 100644 --- a/src/frontend/subckt.c +++ b/src/frontend/subckt.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +Modified: 2000 AlansFixes **********/ /* @@ -12,8 +13,15 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "cpdefs.h" #include "ftedefs.h" #include "fteinp.h" -#include "subckt.h" +#ifdef XSPICE +/* gtri - add - wbk - 11/9/90 - include MIF function prototypes */ +#include "mifproto.h" +/* gtri - end - wbk - 11/9/90 */ +#endif + +#include "subckt.h" +#include "variable.h" /* static declarations */ static struct line * doit(struct line *deck); @@ -113,6 +121,14 @@ inp_subcktexpand(struct line *deck) ll = doit(deck); + /* Now check to see if there are still subckt instances undefined... */ + if (ll!=NULL) for (c = ll; c; c = c->li_next) + if (ciprefix(invoke, c->li_line)) { + fprintf(cp_err, "Error: unknown subckt: %s\n", + c->li_line); + return NULL; + } + return (ll); } @@ -293,13 +309,6 @@ doit(struct line *deck) return (NULL); } - /* Now check to see if there are still subckt instances undefined... */ - for (c = deck; c; c = c->li_next) - if (ciprefix(invoke, c->li_line)) { - fprintf(cp_err, "Error: unknown subckt: %s\n", - c->li_line); - error = 1; - } if (error) return NULL; /* error message already reported; should free( ) */ @@ -348,6 +357,14 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub char *buffer, *name, *s, *t, ch; int nnodes, i; +#ifdef XSPICE + /* gtri - add - wbk - 10/23/90 - add new local variables */ + + char *next_name; /* for look-ahead during tokenizing */ + + /* gtri - end - wbk - 10/23/90 */ +#endif + i = settrans(formal, actual, subname); if (i < 0) { fprintf(stderr, @@ -370,6 +387,102 @@ translate(struct line *deck, char *formal, char *actual, char *scname, char *sub /* Nothing any good here. */ continue; +#ifdef XSPICE +/* gtri - add - wbk - 10/23/90 - process A devices specially */ +/* since they have a more involved and variable length node syntax */ + + case 'a': + case 'A': + + /* translate the instance name according to normal rules */ + + buffer = tmalloc(10000); /* XXXXX */ + + s = c->li_line; + name = MIFgettok(&s); + + /* maschmann + sprintf(buffer, "%s:%s ", name, scname); */ + sprintf(buffer, "a:%s:%s ", scname, name+1 ); + + + + /* Now translate the nodes, looking ahead one token to recognize */ + /* when we reach the model name which should not be translated */ + /* here. */ + + next_name = MIFgettok(&s); + + while(1) { + + /* rotate the tokens and get the the next one */ + + name = next_name; + next_name = MIFgettok(&s); + + /* if next token is NULL, name holds the model name, so exit */ + + if(next_name == NULL) + break; + + /* Process the token in name. If it is special, then don't */ + /* translate it. */ + + switch(*name) { + + case '[': + case ']': + case '~': + sprintf(buffer + strlen(buffer), "%s ", name); + break; + + case '%': + + sprintf(buffer + strlen(buffer), "%%"); + + /* don't translate the port type identifier */ + + name = next_name; + next_name = MIFgettok(&s); + + sprintf(buffer + strlen(buffer), "%s ", name); + break; + + default: + + /* must be a node name at this point, so translate it */ + + t = gettrans(name); + if (t) + sprintf(buffer + strlen(buffer), "%s ", t); + else + /* maschmann: changed order + sprintf(buffer + strlen(buffer), "%s:%s ", name, scname); */ + if(name[0]=='v' || name[0]=='V') sprintf(buffer + strlen(buffer), "v:%s:%s ", scname, name+1); + else sprintf(buffer + strlen(buffer), "%s:%s ", scname, name); + + break; + + } /* switch */ + + } /* while */ + + + /* copy in the last token, which is the model name */ + + if(name) + sprintf(buffer + strlen(buffer), "%s ", name); + + /* Set s to null string for compatibility with code */ + /* after switch statement */ + + s = ""; + + break; + +/* gtri - end - wbk - 10/23/90 */ +#endif + default: s = c->li_line; name = gettok(&s); @@ -566,6 +679,13 @@ gettrans(char *name) { int i; +#ifdef XSPICE + /* gtri - wbk - 2/27/91 - don't translate the reserved word 'null' */ + if (eq(name, "null")) + return (name); + /* gtri - end */ +#endif + if (eq(name, "0")) return (name); for (i = 0; table[i].t_old; i++) @@ -577,11 +697,17 @@ gettrans(char *name) static int numnodes(char *name) { +/* gtri - comment - wbk - 10/23/90 - Do not modify this routine for */ +/* 'A' type devices since the callers will not know how to find the */ +/* nodes even if they know how many there are. Modify the callers */ +/* instead. */ +/* gtri - end - wbk - 10/23/90 */ + char c; struct subs *sss; char *s, *t, buf[4 * BSIZE_SP]; wordlist *wl; - int n, i; + int n, i, gotit; while (*name && isspace(*name)) name++; @@ -609,6 +735,41 @@ numnodes(char *name) return (sss->su_numargs); } n = inp_numnodes(c); + + /* Added this code for variable number of nodes on BSIM3SOI devices */ + /* The consequence of this code is that the value returned by the */ + /* inp_numnodes(c) call must be regarded as "maximun number of nodes */ + /* for a given device type. */ + /* Paolo Nenzi Jan-2001 */ + + /* I hope that works, this code is very very untested */ + + if (c=='m') { /* IF this is a mos */ + + i = 0; + s = buf; + gotit = 0; + t = gettok(&s); /* Skip component name */ + while ((i < n) && (*s) && !gotit) { + t = gettok(&s); + for (wl = modnames; wl; wl = wl->wl_next) + if (eq(t, wl->wl_word)) + gotit = 1; + i++; + } + + /* Note: node checks must be done on #_of_node-1 because the */ + /* "while" cicle increments the counter even when a model is */ + /* recognized. This code may be better! */ + + if (i < 5) { + fprintf(cp_err, "Error: too few nodes for MOS: %s\n", name); + return(0); + } + return(i-1); /* compesate the unnecessary inrement in the while cicle */ + } + + if (nobjthack || (c != 'q')) return (n); for (s = buf, i = 0; *s && (i < 4); i++) @@ -928,7 +1089,7 @@ inp_numnodes(char c) case 'j': return (3); case 'k': return (0); case 'l': return (2); - case 'm': return (4); + case 'm': return (7); /* This means that 7 is the maximun number of nodes */ case 'o': return (4); case 'q': return (4); case 'r': return (2); diff --git a/src/frontend/typesdef.c b/src/frontend/typesdef.c index 0c53ab906..8b74a23af 100644 --- a/src/frontend/typesdef.c +++ b/src/frontend/typesdef.c @@ -10,7 +10,7 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" #include "typesdef.h" @@ -32,7 +32,7 @@ struct plotab { /* note: This should correspond to SV_ defined in FTEconstant.h */ struct type types[NUMTYPES] = { { "notype", NULL } , - { "time", "S" } , + { "time", "s" } , { "frequency", "Hz" } , { "voltage", "V" } , { "current", "A" } , @@ -42,13 +42,6 @@ struct type types[NUMTYPES] = { { "inoise-integrated", "V or A" } , { "output-noise", NULL } , { "input-noise", NULL } , -#ifdef notdef - { "HD2", NULL } , - { "HD3", NULL } , - { "DIM2", NULL } , - { "SIM2", NULL } , - { "DIM3", NULL } , -#endif { "pole", NULL } , { "zero", NULL } , { "s-param", NULL } , diff --git a/src/frontend/vectors.c b/src/frontend/vectors.c index 380903428..e30967600 100644 --- a/src/frontend/vectors.c +++ b/src/frontend/vectors.c @@ -7,35 +7,153 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group * Routines for dealing with the vector database. */ -#include "ngspice.h" -#include "cpdefs.h" -#include "ftedefs.h" -#include "ftedata.h" +#include +#include +#include +#include +#include + +#include "circuits.h" +#include "completion.h" +#include "variable.h" #include "vectors.h" +#include "plotting/plotting.h" -/* static declarations */ +#ifdef XSPICE +/* gtri - begin - add function prototype for EVTfindvec */ +struct dvec *EVTfindvec(char *node); +/* gtri - end - add function prototype for EVTfindvec */ +#endif -static struct dvec * findvec(char *word, struct plot *pl); -static struct dvec * sortvecs(struct dvec *d); -static int veccmp(struct dvec **d1, struct dvec **d2); -static int namecmp(char *s, char *t); +/* Find a named vector in a plot. We are careful to copy the vector if + * v_link2 is set, because otherwise we will get screwed up. */ +static struct dvec * +findvec(char *word, struct plot *pl) +{ + struct dvec *d, *newv = NULL, *end = NULL, *v; + char buf[BSIZE_SP]; + + if (pl == NULL) + return (NULL); + + if (cieq(word, "all")) { + for (d = pl->pl_dvecs; d; d = d->v_next) { + if (d->v_flags & VF_PERMANENT) { + if (d->v_link2) { + v = vec_copy(d); + vec_new(v); + } else + v = d; + if (end) + end->v_link2 = v; + else + newv = v; + end = v; + } + } + return (newv); + } + + for (d = pl->pl_dvecs; d; d = d->v_next) + if (cieq(word, d->v_name) && (d->v_flags & VF_PERMANENT)) + break; + if (!d) { + (void) sprintf(buf, "v(%s)", word); + for (d = pl->pl_dvecs; d; d = d->v_next) + if (cieq(buf, d->v_name) && (d->v_flags & VF_PERMANENT)) + break; + } +#ifdef XSPICE +/* gtri - begin - Add processing for getting event-driven vector */ + + if(!d) + d = EVTfindvec(word); + +/* gtri - end - Add processing for getting event-driven vector */ +#endif + if (d && d->v_link2) { + d = vec_copy(d); + vec_new(d); + } + + return (d); +} -/* Where 'constants' go when defined on initialization. */ +/* If there are imbedded numeric strings, compare them numerically, not + * alphabetically. + */ +static int +namecmp(const void *a, const void *b) +{ + int i, j; -static struct plot constantplot = { - "Constant values", "Sat Aug 16 10:55:15 PDT 1986", "constants", - "const", NULL, NULL, NULL, NULL, NULL, NULL, TRUE -} ; + char *s = (char *) a; + char *t = (char *) b; + for (;;) { + while ((*s == *t) && !isdigit(*s) && *s) + s++, t++; + if (!*s) + return (0); + if ((*s != *t) && (!isdigit(*s) || !isdigit(*t))) + return (*s - *t); + + /* The beginning of a number... Grab the two numbers and then + * compare them... */ + for (i = 0; isdigit(*s); s++) + i = i * 10 + *s - '0'; + for (j = 0; isdigit(*t); t++) + j = j * 10 + *t - '0'; + + if (i != j) + return (i - j); + } +} -struct plot *plot_cur = &constantplot; -struct plot *plot_list = &constantplot; -int plotl_changed; /* TRUE after a load */ -int plot_num = 1; +static int +veccmp(const void *a, const void *b) +{ + int i; + struct dvec **d1 = (struct dvec **) a; + struct dvec **d2 = (struct dvec **) b; + + if ((i = namecmp((*d1)->v_plot->pl_typename, + (*d2)->v_plot->pl_typename)) != 0) + return (i); + return (namecmp((*d1)->v_name, (*d2)->v_name)); +} + + +/* Sort all the vectors in d, first by plot name and then by vector + * name. Do the right thing with numbers. */ +static struct dvec * +sortvecs(struct dvec *d) +{ + struct dvec **array, *t; + int i, j; + + for (t = d, i = 0; t; t = t->v_link2) + i++; + if (i < 2) + return (d); + array = (struct dvec **) tmalloc(i * sizeof (struct dvec *)); + for (t = d, i = 0; t; t = t->v_link2) + array[i++] = t; + + qsort((char *) array, i, sizeof (struct dvec *), veccmp); + + /* Now string everything back together... */ + for (j = 0; j < i - 1; j++) + array[j]->v_link2 = array[j + 1]; + array[j]->v_link2 = NULL; + d = array[0]; + tfree(array); + return (d); +} + /* Load in a rawfile. */ - void ft_loadfile(char *file) { @@ -304,54 +422,6 @@ vec_get(char *word) return (sortvecs(d)); } -/* Find a named vector in a plot. We are careful to copy the vector - * if v_link2 is set, because otherwise we will get screwed up. - */ - -static struct dvec * -findvec(char *word, struct plot *pl) -{ - struct dvec *d, *newv = NULL, *end = NULL, *v; - char buf[BSIZE_SP]; - - if (pl == NULL) - return (NULL); - - if (cieq(word, "all")) { - for (d = pl->pl_dvecs; d; d = d->v_next) { - if (d->v_flags & VF_PERMANENT) { - if (d->v_link2) { - v = vec_copy(d); - vec_new(v); - } else - v = d; - if (end) - end->v_link2 = v; - else - newv = v; - end = v; - } - } - return (newv); - } - - for (d = pl->pl_dvecs; d; d = d->v_next) - if (cieq(word, d->v_name) && (d->v_flags & VF_PERMANENT)) - break; - if (!d) { - (void) sprintf(buf, "v(%s)", word); - for (d = pl->pl_dvecs; d; d = d->v_next) - if (cieq(buf, d->v_name) && (d->v_flags & VF_PERMANENT)) - break; - } - if (d && d->v_link2) { - d = vec_copy(d); - vec_new(d); - } - - return (d); -} - /* Execute the commands for a plot. This is done whenever a plot becomes * the current plot. */ @@ -615,75 +685,7 @@ vec_basename(struct dvec *v) return (copy(s)); } -/* Sort all the vectors in d, first by plot name and then by vector name. - * Do the right thing with numbers. - */ -static struct dvec * -sortvecs(struct dvec *d) -{ - struct dvec **array, *t; - int i, j; - - for (t = d, i = 0; t; t = t->v_link2) - i++; - if (i < 2) - return (d); - array = (struct dvec **) tmalloc(i * sizeof (struct dvec *)); - for (t = d, i = 0; t; t = t->v_link2) - array[i++] = t; - - qsort((char *) array, i, sizeof (struct dvec *), veccmp); - - /* Now string everything back together... */ - for (j = 0; j < i - 1; j++) - array[j]->v_link2 = array[j + 1]; - array[j]->v_link2 = NULL; - d = array[0]; - tfree(array); - return (d); -} - -static int -veccmp(struct dvec **d1, struct dvec **d2) -{ - int i; - - if ((i = namecmp((*d1)->v_plot->pl_typename, - (*d2)->v_plot->pl_typename)) != 0) - return (i); - return (namecmp((*d1)->v_name, (*d2)->v_name)); -} - -/* If there are imbedded numeric strings, compare them numerically, not - * alphabetically. - */ - -static int -namecmp(char *s, char *t) -{ - int i, j; - - for (;;) { - while ((*s == *t) && !isdigit(*s) && *s) - s++, t++; - if (!*s) - return (0); - if ((*s != *t) && (!isdigit(*s) || !isdigit(*t))) - return (*s - *t); - - /* The beginning of a number... Grab the two numbers - * and then compare them... - */ - for (i = 0; isdigit(*s); s++) - i = i * 10 + *s - '0'; - for (j = 0; isdigit(*t); t++) - j = j * 10 + *t - '0'; - - if (i != j) - return (i - j); - } -} /* Make a plot the current one. This gets called by cp_usrset() when one @@ -818,7 +820,7 @@ vec_mkfamily(struct dvec *v) int size, numvecs, i, j, count[MAXDIMS]; int totalsize; struct dvec *vecs, *d; - char buf[BSIZE_SP]; + char buf[BSIZE_SP], buf2[BSIZE_SP]; if (v->v_numdims < 2) return (v); @@ -838,8 +840,8 @@ vec_mkfamily(struct dvec *v) for (i = 0; i < MAXDIMS; i++) count[i] = 0; for (d = vecs, j = 0; d; j++, d = d->v_link2) { - (void) sprintf(buf, "%s%s", v->v_name, - indexstring(count, v->v_numdims - 1)); + indexstring(count, v->v_numdims - 1, buf2); + (void) sprintf(buf, "%s%s", v->v_name, buf2); d->v_name = copy(buf); d->v_type = v->v_type; d->v_flags = v->v_flags; diff --git a/src/frontend/where.c b/src/frontend/where.c index b8d27ab23..c0ef2597f 100644 --- a/src/frontend/where.c +++ b/src/frontend/where.c @@ -6,21 +6,40 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice.h" #include "cpdefs.h" #include "ftedefs.h" -#include "ftedata.h" +#include "dvec.h" #include "ftehelp.h" #include "hlpdefs.h" -#include "where.h" +#include "circuits.h" +#include "where.h" void com_where(void) { char *msg; + /*CDHW typing where with no current circuit caused crashes CDHW*/ + if (!ft_curckt) { + fprintf(cp_err, "There is no current circuit\n"); + return; } + else if (ft_curckt->ci_ckt != "") { + fprintf(cp_err, "No unconverged node found.\n"); + return; + } + msg = (*ft_sim->nonconvErr)((void *) (ft_curckt->ci_ckt), 0); + + printf("%s", msg); + + + + +/* if (ft_curckt) { msg = (*ft_sim->nonconvErr)((void *) (ft_curckt->ci_ckt), 0); fprintf(cp_out, "%s", msg); } else { fprintf(cp_err, "Error: no circuit loaded.\n"); } + +*/ } diff --git a/src/include/ChangeLog b/src/include/ChangeLog index 1dacb9d72..7d908a57d 100644 --- a/src/include/ChangeLog +++ b/src/include/ChangeLog @@ -1,3 +1,26 @@ +2001-11-25 Emmanuel Rouat + + * ftedefs.h: added definition of structure circ (taken from circuits.h) + +2000-09-09 Arno W. Peters + + * fteext.h: Removed prototype for com_fourier(). Use + src/frontend/fourier.h for the proper prototype. + +2000-07-18 Arno W. Peters + + * cpdefs.h: Moved quote() and strip() macro's to ... + + * wordlist.h: ... here. Also added ANSI C prototypes for all + functions that manipulate wordlists. + + * defines.h: Removed CAPZEROBYPASS, NEWCONV and CAPBYPASS as they + are no longer used in the code. + +2000-05-22 Paolo Nenzi + + * inpptree.h: Applied Widlok patch (u2 function). + 1999-11-30 Emmanuel Rouat * ngspice.h: substitutes spice.h diff --git a/src/include/Makefile.am b/src/include/Makefile.am index 45b7561a3..846fddf20 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -1,59 +1,60 @@ ## Process this file with automake to produce Makefile.in noinst_HEADERS = \ - acdefs.h \ - arch.h \ - cktdefs.h \ - complex.h \ - const.h \ - cpdefs.h \ - cpextern.h \ - cpstd.h \ - defines.h \ - devdefs.h \ - dgen.h \ - distodef.h \ - ftecmath.h \ - fteconst.h \ - ftedata.h \ - ftedbgra.h \ - ftedebug.h \ - ftedefs.h \ - ftedev.h \ - fteext.h \ - ftegraf.h \ - ftegraph.h \ - ftehelp.h \ - fteinp.h \ - fteinput.h \ - fteparse.h \ - gendefs.h \ - hlpdefs.h \ - iferrmsg.h \ - ifsim.h \ - inpdefs.h \ - inpmacs.h \ - inpptree.h \ - jobdefs.h \ - macros.h \ - missing_math.h \ - ngspice.h \ - noisedef.h \ - opdefs.h \ - optdefs.h \ - pzdefs.h \ - sen2defs.h \ - sensdefs.h \ - sensgen.h \ - smpdefs.h \ - spconfig.h \ - sperror.h \ - spmatrix.h \ - struct.h \ - suffix.h \ - tfdefs.h \ - trandefs.h \ - trcvdefs.h \ - tskdefs.h + acdefs.h \ + bool.h \ + cktdefs.h \ + complex.h \ + const.h \ + cpdefs.h \ + cpextern.h \ + cpstd.h \ + defines.h \ + devdefs.h \ + dgen.h \ + distodef.h \ + dvec.h \ + ftedbgra.h \ + ftedebug.h \ + ftedefs.h \ + ftedev.h \ + fteext.h \ + fteinp.h \ + fteinput.h \ + fteparse.h \ + gendefs.h \ + graph.h \ + grid.h \ + hlpdefs.h \ + iferrmsg.h \ + ifsim.h \ + inpdefs.h \ + inpmacs.h \ + inpptree.h \ + jobdefs.h \ + macros.h \ + memory.h \ + missing_math.h \ + ngspice.h \ + noisedef.h \ + opdefs.h \ + optdefs.h \ + plot.h \ + pnode.h \ + pzdefs.h \ + sen2defs.h \ + sensdefs.h \ + sensgen.h \ + sim.h \ + smpdefs.h \ + sperror.h \ + spmatrix.h \ + suffix.h \ + terminal.h \ + tfdefs.h \ + trandefs.h \ + trcvdefs.h \ + tskdefs.h \ + wordlist.h MAINTAINERCLEANFILES = Makefile.in diff --git a/src/include/cktdefs.h b/src/include/cktdefs.h index b4d20bce8..6cb71e9ca 100644 --- a/src/include/cktdefs.h +++ b/src/include/cktdefs.h @@ -1,14 +1,23 @@ /* * Copyright (c) 1985 Thomas L. Quarles * Modified 1999 Paolo Nenzi - Removed non STDC definitions + * Modified 2000 AlansFixes */ #ifndef CKT #define CKT "CKTdefs.h $Revision$ on $Date$ " -#define MAXNUMDEVS 32 /* Max number of possible devices; */ -extern int DEVmaxnum; /* Not sure if still used */ -#define MAXNUMDEVNODES 4 /* Max No. of nodes per device */ - /* Need to change for SOI devs ? */ +/* gtri - evt - wbk - 5/20/91 - add event-driven and enhancements data */ +#ifdef XSPICE +#include "evt.h" +#include "enh.h" +#endif +/* gtri - evt - wbk - 5/20/91 - add event-driven and enhancements data */ + + +#define MAXNUMDEVS 40 /* Max number of possible devices PN:XXX may cause toubles*/ +extern int DEVmaxnum; /* Not sure if still used */ +#define MAXNUMDEVNODES 4 /* Max No. of nodes per device */ + /* Need to change for SOI devs ? */ #include "smpdefs.h" #include "ifsim.h" @@ -31,13 +40,13 @@ typedef struct sCKTnode { #define NODE_VOLTAGE SP_VOLTAGE #define NODE_CURRENT SP_CURRENT - int number; /* Number of the node */ - double ic; /* Value of the initial condition */ - double nodeset; /* Value of the .nodeset option */ - double *ptr; /* ??? */ - struct sCKTnode *next; /* pointer to the next node */ - unsigned int icGiven:1; /* FLAG ic given */ - unsigned int nsGiven:1; /* FLAG nodeset given */ + int number; /* Number of the node */ + double ic; /* Value of the initial condition */ + double nodeset; /* Value of the .nodeset option */ + double *ptr; /* ??? */ + struct sCKTnode *next; /* pointer to the next node */ + unsigned int icGiven:1; /* FLAG ic given */ + unsigned int nsGiven:1; /* FLAG nodeset given */ } CKTnode; /* defines for node parameters */ @@ -48,11 +57,23 @@ typedef struct sCKTnode { typedef struct { - GENmodel *CKThead[MAXNUMDEVS]; /* The max number of loadable devices */ - STATistics *CKTstat; /* The STATistics structure */ - double *(CKTstates[8]); /* Used as memory of past steps ??? */ - /* Some shortcut for CKTstates */ + +/* gtri - begin - wbk - change declaration to allow dynamic sizing */ + +/* An associated change is made in CKTinit.c to alloc the space */ +/* required for the pointers. No changes are needed to the source */ +/* code at the 3C1 level, although the compiler will generate */ +/* slightly different code for references to this data. */ + + GENmodel **CKThead; /*The max number of loadable devices */ + +/* gtri - end - wbk - change declaration to allow dynamic sizing */ + + STATistics *CKTstat; /* The STATistics structure */ + double *(CKTstates[8]); /* Used as memory of past steps ??? */ + + /* Some shortcut for CKTstates */ #define CKTstate0 CKTstates[0] #define CKTstate1 CKTstates[1] #define CKTstate2 CKTstates[2] @@ -61,40 +82,44 @@ typedef struct { #define CKTstate5 CKTstates[5] #define CKTstate6 CKTstates[6] #define CKTstate7 CKTstates[7] - double CKTtime; /* ??? */ - double CKTdelta; /* ??? */ - double CKTdeltaOld[7]; /* Memory for ??? */ - double CKTtemp; /* Actual temperature of CKT */ - double CKTnomTemp; /* Reference temperature 27 C ? */ - double CKTvt; /* Thernmal voltage at CKTtemp */ - double CKTag[7]; /* the gear variable coefficient matrix */ + double CKTtime; /* ??? */ + double CKTdelta; /* ??? */ + double CKTdeltaOld[7]; /* Memory for ??? */ + double CKTtemp; /* Actual temperature of CKT */ + double CKTnomTemp; /* Reference temperature 27 C ? */ + double CKTvt; /* Thernmal voltage at CKTtemp */ + double CKTag[7]; /* the gear variable coefficient matrix */ #ifdef PREDICTOR - double CKTagp[7]; /* the gear predictor variable coefficient matrix */ + double CKTagp[7]; /* the gear predictor variable + coefficient matrix */ #endif /*PREDICTOR*/ - int CKTorder; /* the integration method order */ - int CKTmaxOrder; /* maximum integration method order */ - int CKTintegrateMethod; /* the integration method to be used */ + int CKTorder; /* the integration method order */ + int CKTmaxOrder; /* maximum integration method order */ + int CKTintegrateMethod; /* the integration method to be used */ /* known integration methods */ #define TRAPEZOIDAL 1 #define GEAR 2 - SMPmatrix *CKTmatrix; /* pointer to sparse matrix */ - int CKTniState; /* internal state */ - double *CKTrhs; /* current rhs value - being loaded */ - double *CKTrhsOld; /* previous rhs value for convergence testing */ - double *CKTrhsSpare; /* spare rhs value for reordering */ - double *CKTirhs; /* current rhs value - being loaded (imag) */ - double *CKTirhsOld; /* previous rhs value (imaginary)*/ - double *CKTirhsSpare; /* spare rhs value (imaginary)*/ + SMPmatrix *CKTmatrix; /* pointer to sparse matrix */ + int CKTniState; /* internal state */ + double *CKTrhs; /* current rhs value - being loaded */ + double *CKTrhsOld; /* previous rhs value for convergence + testing */ + double *CKTrhsSpare; /* spare rhs value for reordering */ + double *CKTirhs; /* current rhs value - being loaded + (imag) */ + double *CKTirhsOld; /* previous rhs value (imaginary)*/ + double *CKTirhsSpare; /* spare rhs value (imaginary)*/ #ifdef PREDICTOR - double *CKTpred; /* predicted solution vector */ - double *CKTsols[8]; /* previous 8 solutions */ + double *CKTpred; /* predicted solution vector */ + double *CKTsols[8]; /* previous 8 solutions */ #endif /* PREDICTOR */ - double *CKTrhsOp; /* opearating point values */ - double *CKTsenRhs; /* current sensitivity rhs values */ - double *CKTseniRhs; /* current sensitivity rhs values (imag)*/ + double *CKTrhsOp; /* opearating point values */ + double *CKTsenRhs; /* current sensitivity rhs values */ + double *CKTseniRhs; /* current sensitivity rhs values + (imag)*/ /* @@ -112,19 +137,21 @@ typedef struct { #define NIDIDPREORDER 0x100 #define NIPZSHOULDREORDER 0x200 - int CKTmaxEqNum; /* And this ? */ - int CKTcurrentAnalysis; /* the analysis in progress (if any) */ + int CKTmaxEqNum; /* And this ? */ + int CKTcurrentAnalysis; /* the analysis in progress (if any) */ /* defines for the value of CKTcurrentAnalysis */ /* are in TSKdefs.h */ - CKTnode *CKTnodes; /* ??? */ - CKTnode *CKTlastNode; /* ??? */ + CKTnode *CKTnodes; /* ??? */ + CKTnode *CKTlastNode; /* ??? */ - /* This define should be somewhere else ??? */ + /* This define should be somewhere else ??? */ #define NODENAME(ckt,nodenum) CKTnodName(ckt,nodenum) - int CKTnumStates; /* Number of sates effectively valid ??? */ - long CKTmode; /* Mode of operation of the circuit ??? */ + int CKTnumStates; /* Number of sates effectively valid + ??? */ + long CKTmode; /* Mode of operation of the circuit + ??? */ /* defines for CKTmode */ @@ -151,68 +178,85 @@ typedef struct { /* old 'nosolv' paramater */ #define MODEUIC 0x10000l - int CKTbypass; /* bypass option, how does it work ? */ - int CKTdcMaxIter; /* iteration limit for dc op. (itl1) */ - int CKTdcTrcvMaxIter; /* iteration limit for dc tran. curv (itl2) */ - int CKTtranMaxIter; /* iteration limit for each timepoint for tran*/ - /* (itl4) */ - int CKTbreakSize; /* ??? */ - int CKTbreak; /* ??? */ - double CKTsaveDelta; /* ??? */ - double CKTminBreak; /* ??? */ - double *CKTbreaks; /* List of breakpoints ??? */ - double CKTabstol; /* --- */ - double CKTpivotAbsTol; /* --- */ - double CKTpivotRelTol; /* --- */ - double CKTreltol; /* --- */ - double CKTchgtol; /* --- */ - double CKTvoltTol; /* --- */ - /* What is this define for ? */ + int CKTbypass; /* bypass option, how does it work ? */ + int CKTdcMaxIter; /* iteration limit for dc op. (itl1) */ + int CKTdcTrcvMaxIter; /* iteration limit for dc tran. curv + (itl2) */ + int CKTtranMaxIter; /* iteration limit for each timepoint + for tran*/ + /* (itl4) */ + int CKTbreakSize; /* ??? */ + int CKTbreak; /* ??? */ + double CKTsaveDelta; /* ??? */ + double CKTminBreak; /* ??? */ + double *CKTbreaks; /* List of breakpoints ??? */ + double CKTabstol; /* --- */ + double CKTpivotAbsTol; /* --- */ + double CKTpivotRelTol; /* --- */ + double CKTreltol; /* --- */ + double CKTchgtol; /* --- */ + double CKTvoltTol; /* --- */ + /* What is this define for ? */ #ifdef NEWTRUNC double CKTlteReltol; double CKTlteAbstol; #endif /* NEWTRUNC */ - double CKTgmin; /* Parallel Conductance --- */ - double CKTdelmin; /* ??? */ - double CKTtrtol; /* ??? */ - double CKTfinalTime; /* ??? */ - double CKTstep; /* ??? */ - double CKTmaxStep; /* ??? */ - double CKTinitTime; /* ??? */ - double CKTomega; /* ??? */ - double CKTsrcFact; /* ??? */ - double CKTdiagGmin; /* ??? */ - int CKTnumSrcSteps; /* ??? */ - int CKTnumGminSteps; /* ??? */ - int CKTnoncon; /* ??? */ - double CKTdefaultMosL; /* Default Channel Lenght of MOS devices */ - double CKTdefaultMosW; /* Default Channel Width of MOS devics */ - double CKTdefaultMosAD; /* Default Drain Area of MOS */ - double CKTdefaultMosAS; /* Default Source Area of MOS */ - unsigned int CKThadNodeset:1; /* ??? */ - unsigned int CKTfixLimit:1; /* flag to indicate that the limiting of - * MOSFETs should be done as in SPICE2 */ - unsigned int CKTnoOpIter:1; /* flag to indicate not to try the operating - * point brute force, but to use gmin stepping - * first */ - unsigned int CKTisSetup:1; /* flag to indicate if CKTsetup done */ - JOB *CKTcurJob; /* Next analysis to be performed ??? */ + double CKTgmin; /* Parallel Conductance --- */ + double CKTgshunt; + double CKTdelmin; /* ??? */ + double CKTtrtol; /* ??? */ + double CKTfinalTime; /* ??? */ + double CKTstep; /* ??? */ + double CKTmaxStep; /* ??? */ + double CKTinitTime; /* ??? */ + double CKTomega; /* ??? */ + double CKTsrcFact; /* ??? */ + double CKTdiagGmin; /* ??? */ + int CKTnumSrcSteps; /* ??? */ + int CKTnumGminSteps; /* ??? */ + double CKTgminFactor; + int CKTnoncon; /* ??? */ + double CKTdefaultMosM; + double CKTdefaultMosL; /* Default Channel Lenght of MOS devices */ + double CKTdefaultMosW; /* Default Channel Width of MOS devics */ + double CKTdefaultMosAD; /* Default Drain Area of MOS */ + double CKTdefaultMosAS; /* Default Source Area of MOS */ + unsigned int CKThadNodeset:1; /* ??? */ + unsigned int CKTfixLimit:1; /* flag to indicate that the limiting + of MOSFETs should be done as in + SPICE2 */ + unsigned int CKTnoOpIter:1; /* flag to indicate not to try the operating + point brute force, but to use gmin stepping + first */ + unsigned int CKTisSetup:1; /* flag to indicate if CKTsetup done */ + JOB *CKTcurJob; /* Next analysis to be performed ??? */ - SENstruct *CKTsenInfo; /* the sensitivity information */ - double *CKTtimePoints; /* list of all accepted timepoints in the + SENstruct *CKTsenInfo; /* the sensitivity information */ + double *CKTtimePoints; /* list of all accepted timepoints in + the current transient simulation */ + double *CKTdeltaList; /* list of all timesteps in the current transient simulation */ - double *CKTdeltaList; /* list of all timesteps in the current - transient simulation */ - int CKTtimeListSize; /* size of above lists */ - int CKTtimeIndex; /* current position in above lists */ - int CKTsizeIncr; /* amount to increment size of above arrays - when you run out of space */ - unsigned int CKTtryToCompact:1; /* try to compact past history for LTRA - lines */ - unsigned int CKTbadMos3:1; /* Use old, unfixed MOS3 equations */ - unsigned int CKTkeepOpInfo:1; /* flag for small signal analyses */ - int CKTtroubleNode; /* Non-convergent node number */ - GENinstance *CKTtroubleElt; /* Non-convergent device instance */ + int CKTtimeListSize; /* size of above lists */ + int CKTtimeIndex; /* current position in above lists */ + int CKTsizeIncr; /* amount to increment size of above + arrays when you run out of space */ + unsigned int CKTtryToCompact:1; /* try to compact past history for LTRA + lines */ + unsigned int CKTbadMos3:1; /* Use old, unfixed MOS3 equations */ + unsigned int CKTkeepOpInfo:1; /* flag for small signal analyses */ + unsigned int CKTcopyNodesets:1; /* NodesetFIX */ + unsigned int CKTnodeDamping:1; /* flag for node damping fix */ + double CKTabsDv; /* abs limit for iter-iter voltage change */ + double CKTrelDv; /* rel limit for iter-iter voltage change */ + int CKTtroubleNode; /* Non-convergent node number */ + GENinstance *CKTtroubleElt; /* Non-convergent device instance */ + +/* gtri - evt - wbk - 5/20/91 - add event-driven and enhancements data */ +#ifdef XSPICE + Evt_Ckt_Data_t *evt; /* all data about event driven stuff */ + Enh_Ckt_Data_t *enh; /* data used by general enhancements */ +#endif +/* gtri - evt - wbk - 5/20/91 - add event-driven and enhancements data */ } CKTcircuit; @@ -241,6 +285,7 @@ extern int CKTdltMod( void *, void *); extern int CKTdltNod( void *, void *); extern int CKTdoJob( void *, int , void *); extern void CKTdump( CKTcircuit *, double, void *); +extern void CKTncDump(CKTcircuit *); extern int CKTfndAnal( void *, int *, void **, IFuid , void *, IFuid ); extern int CKTfndBranch( CKTcircuit *, IFuid); extern int CKTfndDev( void *, int *, void **, IFuid , void *, IFuid ); @@ -289,7 +334,7 @@ extern int CKTsetBreak( CKTcircuit *, double ); extern int CKTsetNodPm( void *, void *, int , IFvalue *, IFvalue *); extern int CKTsetOpt( void *, void *, int , IFvalue *); extern int CKTsetup( CKTcircuit *); -extern int CKTunsetup(CKTcircuit *ckt); +extern int CKTunsetup(CKTcircuit *); extern int CKTtemp( CKTcircuit *); extern char *CKTtrouble(void *, char *); extern void CKTterr( int , CKTcircuit *, double *); @@ -314,7 +359,6 @@ extern void SENdestroy( SENstruct *); extern int SENsetParm( CKTcircuit *, void *, int , IFvalue *); extern int SENstartup( CKTcircuit *); extern int SPIinit( IFfrontEnd *, IFsimulator **); -extern char * SPerror( int ); extern int TFanal( CKTcircuit *, int ); extern int TFaskQuest( CKTcircuit *, void *, int , IFvalue *); extern int TFsetParm( CKTcircuit *, void *, int , IFvalue *); @@ -334,6 +378,7 @@ extern int NIpzSym(PZtrial **, PZtrial *); extern int NIpzSym2(PZtrial **, PZtrial *); extern int NIreinit( CKTcircuit *); extern int NIsenReinit( CKTcircuit *); +extern int NIdIter (CKTcircuit *); extern IFfrontEnd *SPfrontEnd; #endif /*CKT*/ diff --git a/src/include/complex.h b/src/include/complex.h index 5aff8e5c4..1212ee2af 100644 --- a/src/include/complex.h +++ b/src/include/complex.h @@ -1,12 +1,24 @@ /* * Copyright (c) 1985 Thomas L. Quarles - * Modified: Paolo Nenzi 1999 + * Modified: 1999 Paolo Nenzi, 2000 Arno W. Peters */ -#ifndef CMPLX -#define CMPLX "complex.h $Revision$ on $Date$ " +#ifndef _COMPLEX_H +#define _COMPLEX_H -/* header file containing definitions for complex functions - * + +/* Complex numbers. */ +struct _complex1 { /* IBM portability... */ + double cx_real; + double cx_imag; +} ; + +typedef struct _complex1 complex; + +#define realpart(cval) ((struct _complex1 *) (cval))->cx_real +#define imagpart(cval) ((struct _complex1 *) (cval))->cx_imag + + +/* * Each expects two arguments for each complex number - a real and an * imaginary part. */ @@ -15,26 +27,62 @@ typedef struct { double imag; } SPcomplex; +/* + * COMPLEX NUMBER DATA STRUCTURE + * + * >>> Structure fields: + * Real (RealNumber) + * The real portion of the number. Real must be the first + * field in this structure. + * Imag (RealNumber) + * The imaginary portion of the number. This field must follow + * immediately after Real. + */ + +#define spREAL double + +/* Begin `RealNumber'. */ +typedef spREAL RealNumber, *RealVector; + +/* Begin `ComplexNumber'. */ +typedef struct +{ RealNumber Real; + RealNumber Imag; +} ComplexNumber, *ComplexVector; + + +/* Some defines used mainly in cmath.c. */ +#define FTEcabs(d) (((d) < 0.0) ? - (d) : (d)) +#define cph(c) (atan2(imagpart(c), (realpart(c)))) +#define cmag(c) (sqrt(imagpart(c) * imagpart(c) + realpart(c) * realpart(c))) +#define radtodeg(c) (cx_degrees ? ((c) / 3.14159265358979323846 * 180) : (c)) +#define degtorad(c) (cx_degrees ? ((c) * 3.14159265358979323846 / 180) : (c)) +#define rcheck(cond, name) if (!(cond)) { \ + fprintf(cp_err, "Error: argument out of range for %s\n", name); \ + return (NULL); } + + +#define cdiv(r1, i1, r2, i2, r3, i3) \ +{ \ + double r, s; \ + if (FTEcabs(r2) > FTEcabs(i2)) { \ + r = (i2) / (r2); \ + s = (r2) + r * (i2); \ + (r3) = ((r1) + r * (i1)) / s; \ + (i3) = ((i1) - r * (r1)) / s; \ + } else { \ + r = (r2) / (i2); \ + s = (i2) + r * (r2); \ + (r3) = (r * (r1) + (i1)) / s; \ + (i3) = (r * (i1) - (r1)) / s; \ + } \ +} + + + #define DC_ABS(a,b) (fabs(a) + fabs(b)) -/* Why that ??? */ -#ifdef notdef -#define DC_DIV(a,b,c,d,x,y) { \ - double r,s;\ - if(fabs(c)>fabs(d)) { \ - r=(d)/(c);\ - s=(c)+r*(d);\ - x=((a)+(b)*r)/s;\ - y=((b)-(a)*r)/s;\ - } else { \ - r=(c)/(d);\ - s=(d)+r*(c);\ - x=((a)*r+(b))/s;\ - y=((b)*r-(a))/s;\ - }\ -} -#endif /*notdef */ /* * Division among complex numbers @@ -67,14 +115,6 @@ typedef struct { } -/* Why that ??? */ -#ifdef notdef -#define DC_MINUS(a,b,c,d,x,y) { \ - (x) = (a) - (c) ;\ - (y) = (b) - (d) ;\ -} -#endif /*notdef*/ - /* * Difference among complex numbers a+jb and c+jd * a = a - c amd b = b - d @@ -227,6 +267,225 @@ typedef struct { (A).imag = (B.imag) - (C.imag); \ } +/* Macro function that returns the approx absolute value of a complex + number. */ +#define ELEMENT_MAG(ptr) (ABS((ptr)->Real) + ABS((ptr)->Imag)) + +/* Complex assignment statements. */ +#define CMPLX_ASSIGN(to,from) \ +{ (to).Real = (from).Real; \ + (to).Imag = (from).Imag; \ +} +#define CMPLX_CONJ_ASSIGN(to,from) \ +{ (to).Real = (from).Real; \ + (to).Imag = -(from).Imag; \ +} +#define CMPLX_NEGATE_ASSIGN(to,from) \ +{ (to).Real = -(from).Real; \ + (to).Imag = -(from).Imag; \ +} +#define CMPLX_CONJ_NEGATE_ASSIGN(to,from) \ +{ (to).Real = -(from).Real; \ + (to).Imag = (from).Imag; \ +} +#define CMPLX_CONJ(a) (a).Imag = -(a).Imag +#define CMPLX_NEGATE(a) \ +{ (a).Real = -(a).Real; \ + (a).Imag = -(a).Imag; \ +} + +/* Macro that returns the approx magnitude (L-1 norm) of a complex number. */ +#define CMPLX_1_NORM(a) (ABS((a).Real) + ABS((a).Imag)) + +/* Macro that returns the approx magnitude (L-infinity norm) of a complex. */ +#define CMPLX_INF_NORM(a) (MAX (ABS((a).Real),ABS((a).Imag))) + +/* Macro function that returns the magnitude (L-2 norm) of a complex number. */ +#define CMPLX_2_NORM(a) (sqrt((a).Real*(a).Real + (a).Imag*(a).Imag)) + +/* Macro function that performs complex addition. */ +#define CMPLX_ADD(to,from_a,from_b) \ +{ (to).Real = (from_a).Real + (from_b).Real; \ + (to).Imag = (from_a).Imag + (from_b).Imag; \ +} + +/* Macro function that performs complex subtraction. */ +#define CMPLX_SUBT(to,from_a,from_b) \ +{ (to).Real = (from_a).Real - (from_b).Real; \ + (to).Imag = (from_a).Imag - (from_b).Imag; \ +} + +/* Macro function that is equivalent to += operator for complex numbers. */ +#define CMPLX_ADD_ASSIGN(to,from) \ +{ (to).Real += (from).Real; \ + (to).Imag += (from).Imag; \ +} + +/* Macro function that is equivalent to -= operator for complex numbers. */ +#define CMPLX_SUBT_ASSIGN(to,from) \ +{ (to).Real -= (from).Real; \ + (to).Imag -= (from).Imag; \ +} + +/* Macro function that multiplies a complex number by a scalar. */ +#define SCLR_MULT(to,sclr,cmplx) \ +{ (to).Real = (sclr) * (cmplx).Real; \ + (to).Imag = (sclr) * (cmplx).Imag; \ +} + +/* Macro function that multiply-assigns a complex number by a scalar. */ +#define SCLR_MULT_ASSIGN(to,sclr) \ +{ (to).Real *= (sclr); \ + (to).Imag *= (sclr); \ +} + +/* Macro function that multiplies two complex numbers. */ +#define CMPLX_MULT(to,from_a,from_b) \ +{ (to).Real = (from_a).Real * (from_b).Real - \ + (from_a).Imag * (from_b).Imag; \ + (to).Imag = (from_a).Real * (from_b).Imag + \ + (from_a).Imag * (from_b).Real; \ +} + +/* Macro function that implements to *= from for complex numbers. */ +#define CMPLX_MULT_ASSIGN(to,from) \ +{ RealNumber to_real_ = (to).Real; \ + (to).Real = to_real_ * (from).Real - \ + (to).Imag * (from).Imag; \ + (to).Imag = to_real_ * (from).Imag + \ + (to).Imag * (from).Real; \ +} + +/* Macro function that multiplies two complex numbers, the first of which is + * conjugated. */ +#define CMPLX_CONJ_MULT(to,from_a,from_b) \ +{ (to).Real = (from_a).Real * (from_b).Real + \ + (from_a).Imag * (from_b).Imag; \ + (to).Imag = (from_a).Real * (from_b).Imag - \ + (from_a).Imag * (from_b).Real; \ +} + +/* Macro function that multiplies two complex numbers and then adds them + * to another. to = add + mult_a * mult_b */ +#define CMPLX_MULT_ADD(to,mult_a,mult_b,add) \ +{ (to).Real = (mult_a).Real * (mult_b).Real - \ + (mult_a).Imag * (mult_b).Imag + (add).Real; \ + (to).Imag = (mult_a).Real * (mult_b).Imag + \ + (mult_a).Imag * (mult_b).Real + (add).Imag; \ +} + +/* Macro function that subtracts the product of two complex numbers from + * another. to = subt - mult_a * mult_b */ +#define CMPLX_MULT_SUBT(to,mult_a,mult_b,subt) \ +{ (to).Real = (subt).Real - (mult_a).Real * (mult_b).Real + \ + (mult_a).Imag * (mult_b).Imag; \ + (to).Imag = (subt).Imag - (mult_a).Real * (mult_b).Imag - \ + (mult_a).Imag * (mult_b).Real; \ +} + +/* Macro function that multiplies two complex numbers and then adds them + * to another. to = add + mult_a* * mult_b where mult_a* represents mult_a + * conjugate. */ +#define CMPLX_CONJ_MULT_ADD(to,mult_a,mult_b,add) \ +{ (to).Real = (mult_a).Real * (mult_b).Real + \ + (mult_a).Imag * (mult_b).Imag + (add).Real; \ + (to).Imag = (mult_a).Real * (mult_b).Imag - \ + (mult_a).Imag * (mult_b).Real + (add).Imag; \ +} + +/* Macro function that multiplies two complex numbers and then adds them + * to another. to += mult_a * mult_b */ +#define CMPLX_MULT_ADD_ASSIGN(to,from_a,from_b) \ +{ (to).Real += (from_a).Real * (from_b).Real - \ + (from_a).Imag * (from_b).Imag; \ + (to).Imag += (from_a).Real * (from_b).Imag + \ + (from_a).Imag * (from_b).Real; \ +} + +/* Macro function that multiplies two complex numbers and then subtracts them + * from another. */ +#define CMPLX_MULT_SUBT_ASSIGN(to,from_a,from_b) \ +{ (to).Real -= (from_a).Real * (from_b).Real - \ + (from_a).Imag * (from_b).Imag; \ + (to).Imag -= (from_a).Real * (from_b).Imag + \ + (from_a).Imag * (from_b).Real; \ +} + +/* Macro function that multiplies two complex numbers and then adds them + * to the destination. to += from_a* * from_b where from_a* represents from_a + * conjugate. */ +#define CMPLX_CONJ_MULT_ADD_ASSIGN(to,from_a,from_b) \ +{ (to).Real += (from_a).Real * (from_b).Real + \ + (from_a).Imag * (from_b).Imag; \ + (to).Imag += (from_a).Real * (from_b).Imag - \ + (from_a).Imag * (from_b).Real; \ +} + +/* Macro function that multiplies two complex numbers and then subtracts them + * from the destination. to -= from_a* * from_b where from_a* represents from_a + * conjugate. */ +#define CMPLX_CONJ_MULT_SUBT_ASSIGN(to,from_a,from_b) \ +{ (to).Real -= (from_a).Real * (from_b).Real + \ + (from_a).Imag * (from_b).Imag; \ + (to).Imag -= (from_a).Real * (from_b).Imag - \ + (from_a).Imag * (from_b).Real; \ +} + +/* + * Macro functions that provide complex division. + */ + +/* Complex division: to = num / den */ +#define CMPLX_DIV(to,num,den) \ +{ RealNumber r_, s_; \ + if (((den).Real >= (den).Imag AND (den).Real > -(den).Imag) OR \ + ((den).Real < (den).Imag AND (den).Real <= -(den).Imag)) \ + { r_ = (den).Imag / (den).Real; \ + s_ = (den).Real + r_*(den).Imag; \ + (to).Real = ((num).Real + r_*(num).Imag)/s_; \ + (to).Imag = ((num).Imag - r_*(num).Real)/s_; \ + } \ + else \ + { r_ = (den).Real / (den).Imag; \ + s_ = (den).Imag + r_*(den).Real; \ + (to).Real = (r_*(num).Real + (num).Imag)/s_; \ + (to).Imag = (r_*(num).Imag - (num).Real)/s_; \ + } \ +} + +/* Complex division and assignment: num /= den */ +#define CMPLX_DIV_ASSIGN(num,den) \ +{ RealNumber r_, s_, t_; \ + if (((den).Real >= (den).Imag AND (den).Real > -(den).Imag) OR \ + ((den).Real < (den).Imag AND (den).Real <= -(den).Imag)) \ + { r_ = (den).Imag / (den).Real; \ + s_ = (den).Real + r_*(den).Imag; \ + t_ = ((num).Real + r_*(num).Imag)/s_; \ + (num).Imag = ((num).Imag - r_*(num).Real)/s_; \ + (num).Real = t_; \ + } \ + else \ + { r_ = (den).Real / (den).Imag; \ + s_ = (den).Imag + r_*(den).Real; \ + t_ = (r_*(num).Real + (num).Imag)/s_; \ + (num).Imag = (r_*(num).Imag - (num).Real)/s_; \ + (num).Real = t_; \ + } \ +} + +/* Complex reciprocation: to = 1.0 / den */ +#define CMPLX_RECIPROCAL(to,den) \ +{ RealNumber r_; \ + if (((den).Real >= (den).Imag && (den).Real > -(den).Imag) || \ + ((den).Real < (den).Imag && (den).Real <= -(den).Imag)) \ + { r_ = (den).Imag / (den).Real; \ + (to).Imag = -r_*((to).Real = 1.0/((den).Real + r_*(den).Imag)); \ + } \ + else \ + { r_ = (den).Real / (den).Imag; \ + (to).Real = -r_*((to).Imag = -1.0/((den).Imag + r_*(den).Real));\ + } \ +} -#endif /*CMPLX*/ +#endif /*_COMPLEX_H */ diff --git a/src/include/cpdefs.h b/src/include/cpdefs.h index f6b62f2d6..550270640 100644 --- a/src/include/cpdefs.h +++ b/src/include/cpdefs.h @@ -18,17 +18,38 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group /* Information about spice commands. */ struct comm { - char *co_comname; /* The name of the command. */ - void (*co_func) (); /* The function that handles the command. */ - bool co_stringargs; /* Collapse the arguments into a string. */ - bool co_spiceonly; /* These can't be used from nutmeg. */ - bool co_major; /* Is this a "major" command? */ - long co_cctypes[4]; /* Bitmasks for command completion. */ - unsigned int co_env;/* print help message on this environment mask */ - int co_minargs; /* minimum number of arguments required */ - int co_maxargs; /* maximum number of arguments allowed */ - int (*co_argfn) (); /* The fn that prompts the user. */ - char *co_help; /* When these are printed, printf(string, av[0]) .. */ + /* The name of the command. */ + char *co_comname; + + /* The function that handles the command. */ + void (*co_func) (wordlist *wl); + + /* Collapse the arguments into a string. */ + bool co_stringargs; + + /* These can't be used from nutmeg. */ + bool co_spiceonly; + + /* Is this a "major" command? */ + bool co_major; + + /* Bitmasks for command completion. */ + long co_cctypes[4]; + + /* print help message on this environment mask */ + unsigned int co_env; + + /* minimum number of arguments required */ + int co_minargs; + + /* maximum number of arguments allowed */ + int co_maxargs; + + /* The fn that prompts the user. */ + void (*co_argfn) (wordlist *wl, struct comm *command); + + /* When these are printed, printf(string, av[0]) .. */ + char *co_help; }; #define LOTS 1000 @@ -44,34 +65,7 @@ struct histent { struct histent *hi_prev; }; -/* Variables that are accessible to the parser via $varname expansions. - * If the type is VT_LIST the value is a pointer to a list of the elements. - */ -struct variable { - char va_type; - char *va_name; - union { - bool vV_bool; - int vV_num; - double vV_real; - char *vV_string; - struct variable *vV_list; - } va_V; - struct variable *va_next; /* Link. */ -} ; - -#define va_bool va_V.vV_bool -#define va_num va_V.vV_num -#define va_real va_V.vV_real -#define va_string va_V.vV_string -#define va_vlist va_V.vV_list - -#define VT_BOOL 1 -#define VT_NUM 2 -#define VT_REAL 3 -#define VT_STRING 4 -#define VT_LIST 5 /* The values returned by cp_userset(). */ @@ -97,14 +91,6 @@ struct alias { #define CPC_BRR 004 /* Break word to right of character. */ #define CPC_BRL 010 /* Break word to left of character. */ -/* For quoting individual characters. '' strings are all quoted, but `` and - * "" strings are maintained as single words with the quotes around them. - * Note that this won't work on non-ascii machines. - */ - -#define quote(c) ((c) | 0200) -#define strip(c) ((c) & 0177) - #define CT_ALIASES 1 #define CT_LABEL 15 diff --git a/src/include/cpextern.h b/src/include/cpextern.h index 345b43aef..975c2d4b7 100644 --- a/src/include/cpextern.h +++ b/src/include/cpextern.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group +Modified: 2000 AlansFixes **********/ /* @@ -10,6 +11,10 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group #ifndef CPEXTERN_H #define CPEXTERN_H +#include "wordlist.h" +#include "bool.h" + + /* alias.c */ extern struct alias *cp_aliases; @@ -18,6 +23,7 @@ extern void com_unalias(); extern void cp_paliases(); extern void cp_setalias(); extern void cp_unalias(); + extern wordlist *cp_doalias(); /* backquote.c */ @@ -95,7 +101,7 @@ extern int cp_maxhistlength; extern struct histent *cp_lastone; extern void com_history(); extern void cp_addhistent(); -extern void cp_hprint(); +void cp_hprint(int eventhi, int eventlo, bool rev); extern wordlist *cp_histsubst(); /* lexical.c */ @@ -123,6 +129,7 @@ extern bool out_isatty; extern void out_init(); #ifndef out_printf /* don't want to declare it if we have #define'ed it */ + extern void out_printf(); #endif extern void out_send(); @@ -141,7 +148,7 @@ extern void cp_printword(char *string, FILE *fp); extern bool cp_unixcom(); extern void cp_hstat(); -extern void cp_rehash(); +void cp_rehash(char *pathlist, bool docc); /* variable.c */ @@ -153,33 +160,30 @@ extern bool cp_nonomatch; extern char cp_dol; extern void cp_remvar(char *varname); extern void cp_vset(char *varname, char type, char *value); -extern wordlist *cp_varwl(struct variable *var); extern struct variable *cp_setparse(wordlist *wl); /* var2.c */ -extern wordlist *vareval(char *string); -extern wordlist *cp_variablesubst(wordlist *wlist); extern void cp_vprint(void); extern void com_set(wordlist *wl); +extern void com_option(wordlist *wl); +extern void com_state(wordlist *wl); extern void com_unset(wordlist *wl); extern void com_shift(wordlist *wl); -extern bool cp_getvar(char *name, int type, char *retval); -extern wordlist *cp_variablesubst(wordlist *wlist); +extern bool cp_getvar(char *name, int type, void *retval); /* cpinterface.c etc -- stuff CP needs from FTE */ -extern bool cp_istrue(); +extern bool cp_istrue(wordlist *wl); extern bool cp_oddcomm(); extern void cp_doquit(); extern void cp_periodic(); extern void ft_cpinit(); extern struct comm *cp_coms; -extern double *ft_numparse(); extern char *cp_program; extern bool ft_nutmeg; extern struct variable *cp_enqvar(); extern void cp_usrvars(); -extern int cp_usrset(); +int cp_usrset(struct variable *var, bool isset); extern void fatal(); #endif diff --git a/src/include/cpstd.h b/src/include/cpstd.h index d1dd24e56..8b2b297fa 100644 --- a/src/include/cpstd.h +++ b/src/include/cpstd.h @@ -11,63 +11,30 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group #ifndef _STD_H_ #define _STD_H_ -typedef int bool; - #ifndef FILE /* XXX Bogus */ # include #endif -/* Doubly linked lists of words. */ +/* FIXME: Split this file and adjust all callers to use new header files */ +#if 0 +#warning "Please use bool.h, wordlist.h or complex.h rather than cpstd.h" +#endif -struct wordlist { - char *wl_word; - struct wordlist *wl_next; - struct wordlist *wl_prev; -} ; - -typedef struct wordlist wordlist; - -/* Complex numbers. */ - -struct _complex { /* IBM portability... */ - double cx_real; - double cx_imag; -} ; - -typedef struct _complex complex; - -#define realpart(cval) ((struct _complex *) (cval))->cx_real -#define imagpart(cval) ((struct _complex *) (cval))->cx_imag +#include "bool.h" +#include "wordlist.h" +#include "complex.h" /* Externs defined in std.c */ extern char *getusername(); extern char *gethome(); extern char *tildexpand(); -extern char *printnum(); +extern void printnum(); extern int cp_numdgt; extern void fatal(); -/* extern void setenv(); */ - extern void cp_printword(); -/* Externs from wlist.c */ - -extern char **wl_mkvec(); -extern char *wl_flatten(); -extern int wl_length(); -extern void wl_free(); -extern void wl_print(); -extern void wl_sort(); -extern wordlist *wl_append(); -extern wordlist *wl_build(); -extern wordlist *wl_copy(); -extern wordlist *wl_range(); -extern wordlist *wl_nthelem(); -extern wordlist *wl_reverse(); -extern wordlist *wl_splice(); - #endif /* _STD_H_*/ diff --git a/src/include/defines.h b/src/include/defines.h index f519e467f..bea978a1e 100644 --- a/src/include/defines.h +++ b/src/include/defines.h @@ -80,11 +80,6 @@ * #define-s that are always on */ -#define CAPZEROBYPASS -#define NEWCONV -/* #define CAPBYPASS Internal use only */ - - /* On Unix the following should always be true, so they should jump out */ #define HAS_ASCII diff --git a/src/include/devdefs.h b/src/include/devdefs.h index 739a7a877..d776fe14e 100644 --- a/src/include/devdefs.h +++ b/src/include/devdefs.h @@ -13,7 +13,6 @@ Author: 1985 Thomas L. Quarles #include "noisedef.h" #include "complex.h" -#ifdef __STDC__ double DEVlimvds(double,double); double DEVpnjlim(double,double,double,double,int*); double DEVfetlim(double,double,double); @@ -21,30 +20,11 @@ void DEVcmeyer(double,double,double,double,double,double,double,double,double, double,double,double*,double*,double*,double,double,double,double); void DEVqmeyer(double,double,double,double,double,double*,double*,double*, double,double); -#ifdef notdef -void DEVcap(CKTcircuit*, double, double, double, double, double, double, - double, double, double, double, double, double, double, double, - double*, double*, double*, double*, double*, double*, double*, - double*, double*, double*, double*, double*, double, double, - double, double*, double*, double); -#endif double DEVpred(CKTcircuit*,int); -#else /* stdc */ -double DEVlimvds(); -double DEVpnjlim(); -double DEVfetlim(); -void DEVcmeyer(); -void DEVqmeyer(); -#ifdef notdef -void DEVcap(); -#endif -double DEVpred(); -#endif /* stdc */ typedef struct SPICEdev { IFdevice DEVpublic; -#ifdef __STDC__ int (*DEVparam)(int,IFvalue*,GENinstance*,IFvalue *); /* routine to input a parameter to a device instance */ int (*DEVmodParam)(int,IFvalue*,GENmodel*); @@ -100,50 +80,13 @@ typedef struct SPICEdev { /* procedure to do distortion operations */ int (*DEVnoise)(int, int, GENmodel*,CKTcircuit*, Ndata *, double *); /* noise routine */ - -#else /* stdc */ - - int (*DEVparam)(); /* routine to input a parameter to a device instance */ - int (*DEVmodParam)(); /* routine to input a paramater to a model */ - int (*DEVload)(); /* routine to load the device into the matrix */ - int (*DEVsetup)(); /* setup routine to preprocess devices once before - * soloution begins */ - int (*DEVunsetup)(); /* clean up before running again */ - - int (*DEVpzSetup)(); /* setup routine to process devices specially for - * pz analysis */ - int (*DEVtemperature)(); /* subroutine to do temperature dependent - * setup processing */ - int (*DEVtrunc)(); /* subroutine to perform truncation error calc. */ - int (*DEVfindBranch)(); /* subroutine to search for device branch eq.s */ - int (*DEVacLoad)(); /* ac analysis loading function */ - int (*DEVaccept)(); /* subroutine to call on acceptance of a timepoint */ - void (*DEVdestroy)(); /* subroutine to destroy all models and instances */ - int (*DEVmodDelete)(); /* subroutine to delete a model and all instances */ - int (*DEVdelete)(); /* subroutine to delete an instance */ - int (*DEVsetic)(); /* routine to pick up device init conds from rhs */ - int (*DEVask)(); /* routine to ask about device details*/ - int (*DEVmodAsk)(); /* routine to ask about model details*/ - int (*DEVpzLoad)(); /* routine to load for pole-zero analysis */ - int (*DEVconvTest)(); /* convergence test function */ - - int (*DEVsenSetup)(); /* routine to setup the device sensitivity info */ - int (*DEVsenLoad)(); /* routine to load the device sensitivity info */ - int (*DEVsenUpdate)(); /* routine to update the device sensitivity info */ - int (*DEVsenAcLoad)(); /* routine to load the device ac sensitivity info*/ - void (*DEVsenPrint)(); /* subroutine to print out sensitivity info */ - int (*DEVsenTrunc)(); /* subroutine to print out sensitivity info */ - int (*DEVdisto)(); /* distortion routine */ - int (*DEVnoise)(); /* noise routine */ - -#endif /* stdc */ - int *DEVinstSize; /* size of an instance */ int *DEVmodSize; /* size of a model */ } SPICEdev; /* instance of structure for each possible type of device */ -/* IOP( ) Input/output parameter + +/* IOP( ) Input/output parameter * IOPP( ) IO parameter which the principle value of a device (used * for naming output variables in sensetivity) * IOPA( ) IO parameter significant for time-varying (non-dc) analyses diff --git a/src/include/distodef.h b/src/include/distodef.h index cf5bfcbec..6d7c5947d 100644 --- a/src/include/distodef.h +++ b/src/include/distodef.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1988 Jaijeet S Roychowdhury +Modified: 2000 AlansFixes **********/ #ifndef DISTODEF @@ -198,18 +199,18 @@ extern double DFiF12(double, double, double, double, extern double DFn2F12(DpassStr*); extern double DFi2F12(DpassStr*); -extern void EqualDeriv(Dderivs *new, Dderivs *old); -extern void TimesDeriv(Dderivs *new, Dderivs *old, double k); -extern void InvDeriv(Dderivs *new, Dderivs *old); -extern void MultDeriv(Dderivs *new, Dderivs *old1, Dderivs *old2); -extern void CubeDeriv(Dderivs *new, Dderivs *old); -extern void PlusDeriv(Dderivs *new, Dderivs *old1, Dderivs *old2); -extern void SqrtDeriv(Dderivs *new, Dderivs *old); -extern void DivDeriv(Dderivs *new, Dderivs *old1, Dderivs *old2); -extern void PowDeriv(Dderivs *new, Dderivs *old, double emm); -extern void AtanDeriv(Dderivs *new, Dderivs *old); -extern void CosDeriv(Dderivs *new, Dderivs *old); -extern void ExpDeriv(Dderivs *new, Dderivs *old); +extern void EqualDeriv(Dderivs *, Dderivs *); +extern void TimesDeriv(Dderivs *, Dderivs *, double); +extern void InvDeriv(Dderivs *, Dderivs *); +extern void MultDeriv(Dderivs *, Dderivs *, Dderivs *); +extern void CubeDeriv(Dderivs *, Dderivs *); +extern void PlusDeriv(Dderivs *, Dderivs *, Dderivs *); +extern void SqrtDeriv(Dderivs *, Dderivs *); +extern void DivDeriv(Dderivs *, Dderivs *, Dderivs *); +extern void PowDeriv(Dderivs *, Dderivs *, double); +extern void AtanDeriv(Dderivs *, Dderivs *); +extern void CosDeriv(Dderivs *, Dderivs *); +extern void ExpDeriv(Dderivs *, Dderivs *); diff --git a/src/include/ftedefs.h b/src/include/ftedefs.h index accd88509..5c4fdc702 100644 --- a/src/include/ftedefs.h +++ b/src/include/ftedefs.h @@ -16,6 +16,12 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "fteparse.h" #include "fteinp.h" +struct save_info { + char *name; + IFuid *analysis; + int used; +}; + /* The curcuits that are currently available to the user. */ struct circ { @@ -41,15 +47,6 @@ struct circ { char *ci_curOpt; /* the most recent options anal. for the circuit */ } ; -struct subcirc { - char *sc_name; /* Whatever... */ -} ; - -struct save_info { - char *name; - IFuid *analysis; - int used; -}; #define mylog10(xx) (((xx) > 0.0) ? log10(xx) : (- log10(HUGE))) diff --git a/src/include/ftedev.h b/src/include/ftedev.h index 272cf02f8..1d4d9bd00 100644 --- a/src/include/ftedev.h +++ b/src/include/ftedev.h @@ -31,7 +31,7 @@ typedef struct { int (*MakeMenu)(); int (*MakeDialog)(); int (*Input)(); - int (*DatatoScreen)(); + void (*DatatoScreen)(); } DISPDEVICE; extern DISPDEVICE *dispdev; diff --git a/src/include/fteext.h b/src/include/fteext.h index d808a2209..64d0864bb 100644 --- a/src/include/fteext.h +++ b/src/include/fteext.h @@ -1,7 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group -Modified: 1999 Paolo Nenzi +Modified: 1999 Paolo Nenzi - 2000 AlansFixes **********/ /* @@ -15,15 +15,12 @@ Modified: 1999 Paolo Nenzi /* needed to find out what the interface structures look like */ #include "ifsim.h" -#include "fteparse.h" +#include "dvec.h" +#include "plot.h" #include "cpdefs.h" #include "ftedefs.h" #include "fteinp.h" -/* agraf.c */ - -extern void ft_agraf(); - /* arg.c */ extern void arg_plot(); @@ -52,6 +49,7 @@ extern bool ft_bpcheck(); extern void com_delete(); extern void com_iplot(); extern void com_save(); +extern void com_save2(wordlist *, char *); extern void com_step(); extern void com_stop(); extern void com_sttus(); @@ -59,14 +57,18 @@ extern void com_trce(); extern void ft_trquery(); extern void dbfree( ); + +/* breakp2.c */ + +extern int ft_getSaves(struct save_info **); + + /* circuits.c */ extern struct circ *ft_curckt; extern struct circ *ft_circuits; extern struct subcirc *ft_subcircuits; -extern void ft_setccirc(); extern void ft_newcirc(); -extern void ft_newsubcirc(); /* clip.c */ @@ -101,6 +103,11 @@ extern void *cx_mean(void *, short int , int , int *, short int *); extern void *cx_length(void *, short int , int , int *, short int *); extern void *cx_vector(void *, short int , int , int *, short int *); extern void *cx_unitvec(void *, short int , int , int *, short int *); + +/* Routoure JM : somme useful functions */ +extern void *cx_min(void *, short int , int , int *, short int *); +extern void *cx_max(void *, short int , int , int *, short int *); +extern void *cx_d(void *, short int , int , int *, short int *); extern void *cx_plus(void *, void *, short int , short int , int ); extern void *cx_minus(void *, void *, short int , short int , int ); @@ -175,7 +182,7 @@ extern bool ft_nopage; extern bool ft_nomod; extern bool ft_nodesprint; extern bool ft_optsprint; -extern int ft_cktcoms(); +extern int ft_cktcoms(bool terse); extern void ft_dotsaves(); extern int ft_savedotargs(); @@ -185,6 +192,10 @@ extern void fatal(); extern void fperror(); extern void ft_sperror(); extern char ErrorMessage[]; +extern void internalerror(char *); +extern void externalerror(char *); + + /* evaluate.c */ @@ -209,9 +220,6 @@ extern struct dvec *op_times(); extern struct dvec *op_uminus(); extern struct dvec *op_range(); -/* fourier.c */ - -extern void com_fourier(); /* spec.c */ @@ -244,7 +252,6 @@ extern void gi_update(); extern bool gr_gmode; extern bool gr_hmode; -extern bool gr_init(); extern void gr_clean(); extern void gr_end(); extern void gr_iplot(); @@ -270,9 +277,10 @@ extern void gr_fixgrid(); extern void com_edit(); extern void com_listing(); extern void com_source(); -extern void inp_dodeck(); +void inp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, + struct line *options, char *filename); extern void inp_source(); -extern void inp_spsource(); +void inp_spsource(FILE *fp, bool comfile, char *filename); extern void inp_casefix(); extern void inp_list(); extern void inp_readall(); @@ -280,8 +288,9 @@ extern FILE *inp_pathopen(); /* nutinp.c */ -extern void inp_nutsource(); -extern void nutinp_dodeck(); +void inp_nutsource(FILE *fp, bool comfile, char *filename); +void nutinp_dodeck(struct line *deck, char *tt, wordlist *end, bool reuse, + struct line *options, char *filename); extern void nutcom_source(); /* interpolate.c */ @@ -313,13 +322,13 @@ extern void com_ghelp(); extern void com_help(); extern void com_quit(); extern void com_version(); -extern int hcomp(); +extern int hcomp(); extern void com_where(); /* numparse.c */ extern bool ft_strictnumparse; -extern double *ft_numparse(); +double * ft_numparse(char **s, bool whole); /* options.c */ @@ -342,14 +351,14 @@ extern int cp_userset(); extern struct func ft_funcs[]; extern struct func func_not; extern struct func func_uminus; -extern struct pnode *ft_getpnames(); +extern struct pnode * ft_getpnames(wordlist *wl, bool check); extern void free_pnode(); /* plotcurve.c */ -extern int ft_findpoint(); -extern double *ft_minmax(); -extern void ft_graf(); +extern int ft_findpoint(double pt, double *lims, int maxp, int minp, bool islog); +extern double * ft_minmax(struct dvec *v, bool real); +extern void ft_graf(struct dvec *v, struct dvec *xs, bool nostart); /* plotinterface.c */ @@ -379,9 +388,8 @@ extern void com_setscale(); extern void com_transpose(); /* rawfile.c */ - extern int raw_prec; -extern void raw_write(); +extern void raw_write(char *name, struct plot *pl, bool app, bool binary); extern struct plot *raw_read(); /* resource.c */ @@ -407,6 +415,8 @@ extern void com_disto(); extern void com_noise(); extern int ft_dorun(); +extern bool ft_getOutReq(FILE **, struct plot **, bool *, char *, char *); + /* spice.c & nutmeg.c */ extern bool ft_nutmeg; @@ -523,9 +533,9 @@ extern void com_clearplot(); extern void com_reshape(); /* dimens.c */ -extern char *dimstring(); +extern void dimstring(); extern int atodims(); -extern char *indexstring(); +extern void indexstring(); extern int incindex( ); #endif /* FTEext_h */ diff --git a/src/include/fteinput.h b/src/include/fteinput.h index d50bb8dd1..dc6fd9f82 100644 --- a/src/include/fteinput.h +++ b/src/include/fteinput.h @@ -4,8 +4,6 @@ Author: 1988 Jeffrey M. Hsu **********/ /* - $Header$ - Defs to use the Input routine. char_option is used by the lexer and the command interpreter @@ -22,7 +20,7 @@ Author: 1988 Jeffrey M. Hsu #include -#include "ftegraph.h" +#include "graph.h" typedef enum { error_option, /* a reply option only */ diff --git a/src/include/fteparse.h b/src/include/fteparse.h index 160e1f4a2..179da7712 100644 --- a/src/include/fteparse.h +++ b/src/include/fteparse.h @@ -12,17 +12,15 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #define FTEPARSE -#include "ftedata.h" +#include "cpstd.h" +#include "dvec.h" +#include "plot.h" -struct pnode { - char *pn_name; /* If non-NULL, the name. */ - struct dvec *pn_value; /* Non-NULL in a terminal node. */ - struct func *pn_func; /* Non-NULL is a function. */ - struct op *pn_op; /* Operation if the above two NULL. */ - struct pnode *pn_left; /* Left branch or function argument. */ - struct pnode *pn_right; /* Right branch. */ - struct pnode *pn_next; /* For expression lists. */ -} ; +/* FIXME: Split this file and adjust all callers. */ +#if 0 +#warning "Please use a more specific header than fteparse.h" +#endif +#include "pnode.h" /* Operations. These should really be considered functions. */ @@ -36,8 +34,12 @@ struct op { /* The functions that are available. */ struct func { - char *fu_name; /* The print name of the function. */ - void *(*fu_func)(); /* The function. */ + /* The print name of the function. */ + char *fu_name; + + /* The function. */ + void *(*fu_func)(void *data, short int type, int length, + int *newlength, short int *newtype); } ; /* User-definable functions. The idea of ud_name is that the args are diff --git a/src/include/gendefs.h b/src/include/gendefs.h index 805ec2243..9e9c3c486 100644 --- a/src/include/gendefs.h +++ b/src/include/gendefs.h @@ -24,6 +24,8 @@ typedef struct sGENinstance { int GENnode3; /* appropriate node numbers */ int GENnode4; /* appropriate node numbers */ int GENnode5; /* appropriate node numbers */ + int GENnode6; /* added to create body node 01/06/99 */ + int GENnode7; /* added to create temp node 2/03/99 */ } GENinstance ; diff --git a/src/include/hlpdefs.h b/src/include/hlpdefs.h index d539cbc17..c2ff3f004 100644 --- a/src/include/hlpdefs.h +++ b/src/include/hlpdefs.h @@ -1,7 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group -Modified 1999 Emmanuel Rouat +Modified 1999 Emmanuel Rouat - 2000 AlansFixes **********/ /* @@ -118,6 +118,7 @@ extern void hlp_pathfix(char *buf); extern topic *hlp_read(fplace *place); extern void hlp_free(void); extern long findsubject(char *filename, char *subject); +extern bool hlp_approvedfile(); /* provide.c */ diff --git a/src/include/iferrmsg.h b/src/include/iferrmsg.h index 630b5b293..0516b81ff 100644 --- a/src/include/iferrmsg.h +++ b/src/include/iferrmsg.h @@ -44,13 +44,13 @@ Author: 1986 Thomas L. Quarles /* changed in the future */ extern char *errMsg; /* descriptive message about what went wrong */ - /* MUST be malloc()'d - front end will free() */ + /* MUST be tmalloc()'d - front end will tfree() */ /* this should be a detailed message,and is assumed */ - /* malloc()'d so that you will feel free to add */ + /* tmalloc()'d so that you will feel free to add */ /* lots of descriptive information with sprintf*/ extern char *errRtn; /* name of the routine declaring error */ - /* should not be malloc()'d, will not be free()'d */ + /* should not be tmalloc()'d, will not be free()'d */ /* This should be a simple constant in your routine */ /* and thus can be set correctly even if we run out */ /* of memory */ diff --git a/src/include/ifsim.h b/src/include/ifsim.h index 8f5a4f734..7c89c48a7 100644 --- a/src/include/ifsim.h +++ b/src/include/ifsim.h @@ -6,14 +6,14 @@ Author: 1986 Thomas L. Quarles #ifndef IFSIMULATOR #define IFSIMULATOR -/* - * We don't always have access to an ANSI C compiler yet, so we - * make the following convenient definition - */ +/* gtri - add - wbk - 10/11/90 - for structs referenced in IFdevice */ +#ifdef XSPICE +#include "mifparse.h" +#include "mifcmdat.h" +#endif +/* gtri - end - wbk - 10/11/90 */ -/* Removed code for non STDC compilers Paolo Nenzi 2000*/ - /* * structure: IFparm * @@ -180,14 +180,14 @@ typedef struct sIFparseTree { * should arrange to free it when appropriate. * * The responsibilities of the data supplier are: - * Any vectors referenced by the structure are to be malloc()'d + * Any vectors referenced by the structure are to be tmalloc()'d * and are assumed to have been turned over to the recipient and - * thus should not be re-used or free()'d. + * thus should not be re-used or tfree()'d. * * The responsibilities of the data recipient are: * scalar valued data is to be copied by the recipient * vector valued data is now the property of the recipient, - * and must be free()'d when no longer needed. + * and must be tfree()'d when no longer needed. * * Character strings are a special case: Since it is assumed * that all character strings are directly descended from input @@ -276,8 +276,22 @@ typedef struct sIFdevice { int *numModelParms; /* number of model parameter descriptors */ IFparm *modelParms; /* array of model parameter descriptors */ - int flags; /* DEV_ */ +/* gtri - modify - wbk - 10/11/90 - add entries to hold data required */ +/* by new parser */ +#ifdef XSPICE + void ((*cm_func)(Mif_Private_t *)); /* pointer to code model function */ + int num_conn; /* number of code model connections */ + Mif_Conn_Info_t *conn; /* array of connection info for mif parser */ + + int num_param; /* number of parameters = numModelParms */ + Mif_Param_Info_t *param; /* array of parameter info for mif parser */ + + int num_inst_var; /* number of instance vars = numInstanceParms */ + Mif_Inst_Var_Info_t *inst_var; /* array of instance var info for mif parser */ +/* gtri - end - wbk - 10/11/90 */ +#endif + int flags; /* DEV_ */ } IFdevice; @@ -321,7 +335,6 @@ typedef struct sIFsimulator { char *description; /* description of this simulator */ char *version; /* version or revision level of simulator*/ -#ifdef __STDC__ int ((*newCircuit)(void **)); /* create new circuit */ int ((*deleteCircuit)(void *)); @@ -383,42 +396,6 @@ typedef struct sIFsimulator { int ((*doAnalyses)(void*,int,void*)); char *((*nonconvErr)(void*,char *)); /* return nonconvergence error */ -#else - int ((*newCircuit)()); /* create new circuit */ - int ((*deleteCircuit)()); /* destroy old circuit's data structures */ - - int ((*newNode)()); /* create new node */ - int ((*groundNode)()); /* create ground node */ - int ((*bindNode)()); /* bind a node to a terminal */ - int ((*findNode)()); /* find a node by name */ - int ((*instToNode)()); /* find the node attached to a terminal */ - int ((*setNodeParm)()); /* set a parameter on a node */ - int ((*askNodeQuest)()); /* ask a question about a node */ - int ((*deleteNode)()); /* delete a node from the circuit */ - - int ((*newInstance)()); /* create new instance */ - int ((*setInstanceParm)()); /* set a parameter on an instance */ - int ((*askInstanceQuest)()); /* ask a question about an instance */ - int ((*findInstance)()); /* find a specific instance */ - int ((*deleteInstance)()); /* delete an instance from the circuit */ - - int ((*newModel)()); /* create new model */ - int ((*setModelParm)()); /* set a parameter on a model */ - int ((*askModelQuest)()); /* ask a questions about a model */ - int ((*findModel)()); /* find a specific model */ - int ((*deleteModel)()); /* delete a model from the circuit*/ - - int ((*newTask)()); /* create a new task */ - int ((*newAnalysis)()); /* create new analysis within a task */ - int ((*setAnalysisParm)()); /* set a parameter on an analysis */ - int ((*askAnalysisQuest)()); /* ask a question about an analysis */ - int ((*findAnalysis)()); /* find a specific analysis */ - int ((*findTask)()); /* find a specific task */ - int ((*deleteTask)()); /* delete a task */ - - int ((*doAnalyses)()); /* run a specified task */ - char *((*nonconvErr)()); /* return nonconvergence error */ -#endif /* STDC */ int numDevices; /* number of device types supported */ IFdevice **devices; /* array of device type descriptors */ @@ -445,7 +422,6 @@ typedef struct sIFsimulator { */ typedef struct sIFfrontEnd { -#ifdef __STDC__ int ((*IFnewUid)(void*,IFuid*,IFuid,char*,int,void**)); /* create a new UID in the circuit */ int ((*IFdelUid)(void*,IFuid,int)); @@ -478,23 +454,6 @@ typedef struct sIFfrontEnd { /* end nested domain */ int ((*OUTattributes)(void *,IFuid*,int,IFvalue*)); /* specify output attributes of node */ -#else /* not STDC */ - int ((*IFnewUid)()); /* create a new UID in the circuit */ - int ((*IFdelUid)()); /* create a new UID in the circuit */ - int ((*IFpauseTest)()); /* should we stop now? */ - double ((*IFseconds)()); /* what time is it? */ - int ((*IFerror)()); /* output an error or warning message */ - int ((*OUTpBeginPlot)()); /* start pointwise output plot */ - int ((*OUTpData)()); /* data for pointwise plot */ - int ((*OUTwBeginPlot)()); /* start windowed output plot */ - int ((*OUTwReference)()); /* independent vector for windowed plot */ - int ((*OUTwData)()); /* data for windowed plot */ - int ((*OUTwEnd)()); /* signal end of windows */ - int ((*OUTendPlot)()); /* end of plot */ - int ((*OUTbeginDomain)()); /* start nested domain */ - int ((*OUTendDomain)()); /* end nested domain */ - int ((*OUTattributes)()); /* specify output attributes of node */ -#endif /* STDC */ } IFfrontEnd; /* flags for the first argument to IFerror */ diff --git a/src/include/inpdefs.h b/src/include/inpdefs.h index 8f7cfa7e1..5f815754d 100644 --- a/src/include/inpdefs.h +++ b/src/include/inpdefs.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #ifndef INP @@ -77,7 +78,6 @@ typedef struct sINPmodel{ #define LOGICAL 1 #define PHYSICAL 2 -#ifdef __STDC__ int IFnewUid(void*,IFuid*,IFuid,char*,int,void**); int IFdelUid(void*,IFuid,int); int INPaName(char*,IFvalue*,void*,int*,char*,void**,IFsimulator*,int*, @@ -96,6 +96,7 @@ int INPgetTok(char**,char**,int); void INPgetTree(char**,INPparseTree**,void*,INPtables*); IFvalue * INPgetValue(void*,char**,int,INPtables*); int INPgndInsert(void*,char**,INPtables*,void**); +int INPinsertNofree(char **token, INPtables *tab); int INPinsert(char**,INPtables*); int INPretrieve(char**,INPtables*); int INPremove(char*,INPtables*); @@ -104,6 +105,7 @@ int INPmakeMod(char*,int,card*); char *INPmkTemp(char*); void INPpas1(void*,card*,INPtables*); void INPpas2(void*,card*,INPtables*,void *); +void INPpas3(void*,card*,INPtables*,void *,IFparm*,int); int INPpName(char*,IFvalue*,void*,int,void*); int INPtermInsert(void*,char**,INPtables*,void**); int INPmkTerm(void*,char**,INPtables*,void**); @@ -121,6 +123,7 @@ void INP2K(void*,INPtables*,card*); void INP2L(void*,INPtables*,card*); void INP2M(void*,INPtables*,card*); void INP2O(void*,INPtables*,card*); +void INP2P(void*,INPtables*,card*); void INP2Q(void*,INPtables*,card*,void*); void INP2R(void*,INPtables*,card*); void INP2S(void*,INPtables*,card*); @@ -128,70 +131,10 @@ void INP2T(void*,INPtables*,card*); void INP2U(void*,INPtables*,card*); void INP2V(void*,INPtables*,card*); void INP2W(void*,INPtables*,card*); +void INP2Y(void*,INPtables*,card*); void INP2Z(void*,INPtables*,card*); int INP2dot(void*,INPtables*,card*,void*,void*); INPtables *INPtabInit(int); void INPkillMods(void); void INPtabEnd(INPtables *); -#else /* stdc */ -int IFnewUid(); -int IFdelUid(); -int INPaName(); -IFvalue * INPgetValue(); -INPtables *INPtabInit(); -char * INPdevParse(); -char * INPdomodel(); -char * INPerrCat(); -char * INPfindLev(); -char * INPgetMod(); -char *INPerror(); -char *INPmkTemp(); -double INPevaluate(); -int INPapName(); -int INPgetTitle(); -int INPgetTok(); -int INPgndInsert(); -int INPlookMod(); -int INPmakeMod(); -int INPpName(); -int INPreadAll(); -int INPtermInsert(); -int INPmkTerm(); -int INPtypelook(); -void INPcaseFix(); -void INPdoOpts(); -int INPinsert(); -int INPretrieve(); -int INPremove(); -void INPkillMods(); -void INPlist(); -void INPpas1() ; -void INPpas2() ; -void INPtabEnd(); -void INPptPrint(); -void INPgetTree(); -void INP2B(); -void INP2C(); -void INP2D(); -void INP2E(); -void INP2F(); -void INP2G(); -void INP2H(); -void INP2I(); -void INP2J(); -void INP2K(); -void INP2L(); -void INP2M(); -void INP2O(); -void INP2Q(); -void INP2R(); -void INP2S(); -void INP2T(); -void INP2U(); -void INP2V(); -void INP2W(); -void INP2Z(); -int INP2dot(); -#endif /* stdc */ - #endif /*INP*/ diff --git a/src/include/inpptree.h b/src/include/inpptree.h index 1d08ea7df..5d8d2cb26 100644 --- a/src/include/inpptree.h +++ b/src/include/inpptree.h @@ -92,6 +92,9 @@ typedef struct INPparseNode { #define PTF_SGN 18 #define PTF_USTEP 19 #define PTF_URAMP 20 +/* MW. PTF_CIF - next function */ +#define PTF_USTEP2 21 + /* The following things are used by the parser -- these are the token types the * lexer returns. @@ -155,6 +158,8 @@ extern double PTsqrt(); extern double PTtan(); extern double PTtanh(); extern double PTustep(); +/* MW. PTcif declaration */ +extern double PTustep2(); extern double PTuramp(); extern double PTuminus(); diff --git a/src/include/jobdefs.h b/src/include/jobdefs.h index 71bbe2412..fd47d7959 100644 --- a/src/include/jobdefs.h +++ b/src/include/jobdefs.h @@ -16,17 +16,6 @@ typedef struct sJOB{ } JOB; -typedef struct { - IFanalysis public; - int size; - int domain; - int do_ic; - int (*(setParm))( ); - int (*(askQuest))( ); - int (*an_init)( ); - int (*an_func)( ); -} SPICEanalysis; - #define NODOMAIN 0 #define TIMEDOMAIN 1 #define FREQUENCYDOMAIN 2 diff --git a/src/include/macros.h b/src/include/macros.h index 486df0741..7a203b986 100644 --- a/src/include/macros.h +++ b/src/include/macros.h @@ -14,46 +14,6 @@ #define NUMELEMS(ARRAY) (sizeof(ARRAY)/sizeof(*ARRAY)) -/* - * Macros for complex mathematical functions. - */ - -/* Some defines used mainly in cmath.c. */ -#define alloc_c(len) ((complex *) tmalloc((len) * sizeof (complex))) -#define alloc_d(len) ((double *) tmalloc((len) * sizeof (double))) -#define FTEcabs(d) (((d) < 0.0) ? - (d) : (d)) -#define cph(c) (atan2(imagpart(c), (realpart(c)))) -#define cmag(c) (sqrt(imagpart(c) * imagpart(c) + realpart(c) * realpart(c))) -#define radtodeg(c) (cx_degrees ? ((c) / 3.14159265358979323846 * 180) : (c)) -#define degtorad(c) (cx_degrees ? ((c) * 3.14159265358979323846 / 180) : (c)) -#define rcheck(cond, name) if (!(cond)) { \ - fprintf(cp_err, "Error: argument out of range for %s\n", name); \ - return (NULL); } - - -#define cdiv(r1, i1, r2, i2, r3, i3) \ -{ \ - double r, s; \ - if (FTEcabs(r2) > FTEcabs(i2)) { \ - r = (i2) / (r2); \ - s = (r2) + r * (i2); \ - (r3) = ((r1) + r * (i1)) / s; \ - (i3) = ((i1) - r * (r1)) / s; \ - } else { \ - r = (r2) / (i2); \ - s = (i2) + r * (r2); \ - (r3) = (r * (r1) + (i1)) / s; \ - (i3) = (r * (i1) - (r1)) / s; \ - } \ -} - - - - -#define tfree(x) (txfree(x), x = 0) -#define alloc(TYPE) ((TYPE *) tmalloc(sizeof(TYPE))) - - #define eq(a,b) (!strcmp((a), (b))) #define eqc(a,b) (cieq((a), (b))) #define isalphanum(c) (isalpha(c) || isdigit(c)) @@ -61,11 +21,6 @@ 'a') && ((c) <= 'f')) ? ((c) - 'a' + 10) : ((((c) >= 'A') && \ ((c) <= 'F')) ? ((c) - 'A' + 10) : 0))) -#define MALLOC(x) tmalloc((unsigned)(x)) -#define FREE(x) {if (x) {free((char *)(x));(x) = 0;}} -#define REALLOC(x,y) trealloc((char *)(x),(unsigned)(y)) -#define ZERO(PTR,TYPE) (bzero((PTR),sizeof(TYPE))) - #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) @@ -73,29 +28,29 @@ #define ABORT() fflush(stderr);fflush(stdout);abort(); -#define ERROR(CODE,MESSAGE) { \ - errMsg = MALLOC(strlen(MESSAGE) + 1); \ - strcpy(errMsg, (MESSAGE)); \ - return (CODE); \ +#define ERROR(CODE,MESSAGE) { \ + errMsg = (char *) tmalloc(strlen(MESSAGE) + 1); \ + strcpy(errMsg, (MESSAGE)); \ + return (CODE); \ } -#define NEW(TYPE) ((TYPE *) MALLOC(sizeof(TYPE))) -#define NEWN(TYPE,COUNT) ((TYPE *) MALLOC(sizeof(TYPE) * (COUNT))) +#define NEW(TYPE) ((TYPE *) tmalloc(sizeof(TYPE))) +#define NEWN(TYPE,COUNT) ((TYPE *) tmalloc(sizeof(TYPE) * (COUNT))) -#define R_NORM(A,B) { \ - if ((A) == 0.0) { \ - (B) = 0; \ - } else { \ - while (fabs(A) > 1.0) { \ - (B) += 1; \ - (A) /= 2.0; \ - } \ - while (fabs(A) < 0.5) { \ - (B) -= 1; \ - (A) *= 2.0; \ - } \ - } \ +#define R_NORM(A,B) { \ + if ((A) == 0.0) { \ + (B) = 0; \ + } else { \ + while (fabs(A) > 1.0) { \ + (B) += 1; \ + (A) /= 2.0; \ + } \ + while (fabs(A) < 0.5) { \ + (B) -= 1; \ + (A) *= 2.0; \ + } \ + } \ } @@ -105,10 +60,4 @@ #define DEBUGMSG(testargs) #endif - -#define realpart(cval) ((struct _complex *) (cval))->cx_real -#define imagpart(cval) ((struct _complex *) (cval))->cx_imag - - - #endif /* _MACROS_H_ */ diff --git a/src/include/ngspice.h b/src/include/ngspice.h index 31026b5d1..83a7a3b19 100644 --- a/src/include/ngspice.h +++ b/src/include/ngspice.h @@ -7,17 +7,25 @@ * This file will eventually replace spice.h and lots of other * files in src/include */ - +#define _GNU_SOURCE #include -#include -#include - +#include +#ifdef HAVE_LIMITS_H +# include +#endif +#include "memory.h" #include "defines.h" #include "macros.h" +#include +#include + +#ifndef HUGE +#define HUGE HUGE_VAL +#endif #ifdef STDC_HEADERS # include @@ -95,22 +103,14 @@ struct timeb timebegin; #endif #ifdef HAS_TIME_ -# ifdef HAVE_GETTIMEOFDAY -/* extern char *timezone(); */ /* never used ? (ER) */ -# endif -extern char *asctime(); -extern struct tm *localtime(); +#include #endif -extern char *sbrk(); - - - -/* Functions declarations from src/misc/[].c */ - -extern void *tmalloc(size_t num); -extern void *trealloc(void *str, size_t num); -extern void txfree(void *ptr); +#ifdef __MINGW32__ +#define srandom srand +#define random rand +#define index strchr +#endif extern char *gettok(char **s); extern void appendc(char *s, char c); @@ -122,12 +122,12 @@ extern char *tilde_expand(char *string); extern char *smktemp(char *id); -extern char *copy(); -extern int prefix(); -extern int substring(); -extern void cp_printword(); +extern char *copy(char *str); +extern int prefix(char *p, char *str); +extern int substring(char *sub, char *str); +extern void cp_printword(char *string, FILE *fp); -extern char *datestring(); +extern char *datestring(void); extern double seconds(void); /* Some external variables */ diff --git a/src/include/optdefs.h b/src/include/optdefs.h index d31eb690a..5df48e853 100644 --- a/src/include/optdefs.h +++ b/src/include/optdefs.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #ifndef OPT @@ -104,4 +105,29 @@ typedef struct { #define OPT_TRANSYNC 59 #define OPT_ACSYNC 60 +/* AlansFixes: It is not possible to use the same numbers of the + original Alan code. The following options are all AlansFixes */ + +#define OPT_GSHUNT 61 /* Original: 48 */ +#define OPT_DEFM 62 /* Original: 46 */ +#define OPT_GMINFACT 63 /* Original: 47 */ +#define OPT_COPYNODESETS 64 /* Original: 49 (NodesetFix) */ +#define OPT_NODEDAMPING 65 /* Original: 50 (Node_Damping) */ +#define OPT_ABSDV 66 /* Original: 51 (Node_Damping) */ +#define OPT_RELDV 67 /* Original: 52 (Node_Damping) */ + +#ifdef XSPICE +/* gtri - begin - wbk - add new options */ +#define OPT_ENH_NOOPALTER 100 +#define OPT_ENH_RAMPTIME 101 +#define OPT_EVT_MAX_EVT_PASSES 102 +#define OPT_EVT_MAX_OP_ALTER 103 +#define OPT_ENH_CONV_LIMIT 104 +#define OPT_ENH_CONV_ABS_STEP 105 +#define OPT_ENH_CONV_STEP 106 +#define OPT_MIF_AUTO_PARTIAL 107 +#define OPT_ENH_RSHUNT 108 +/* gtri - end - wbk - add new options */ +#endif + #endif /*OPT*/ diff --git a/src/include/sensgen.h b/src/include/sensgen.h index 60aaa76cd..fe3a4e004 100644 --- a/src/include/sensgen.h +++ b/src/include/sensgen.h @@ -18,3 +18,4 @@ struct s_sgen { extern sgen *sgen_init( ); extern int sgen_next( ); +extern int sgen_setp(sgen*, CKTcircuit*, IFvalue* ); /* AlansFixes */ diff --git a/src/include/smpdefs.h b/src/include/smpdefs.h index bb3b6e8f5..a051b2ad0 100644 --- a/src/include/smpdefs.h +++ b/src/include/smpdefs.h @@ -1,63 +1,47 @@ #ifndef SMP #define SMP -typedef char SMPmatrix; +typedef void SMPmatrix; typedef struct MatrixElement *SMPelement; /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #include "complex.h" #include -#ifdef __STDC__ int SMPaddElt( SMPmatrix *, int , int , double ); -void SMPcClear( SMPmatrix *); -int SMPcLUfac( SMPmatrix *, double ); -int SMPcProdDiag( SMPmatrix *, SPcomplex *, int *); -int SMPcReorder( SMPmatrix * , double , double , int *); -void SMPcSolve( SMPmatrix *, double [], double [], double [], double []); -void SMPclear( SMPmatrix *); -void SMPcolSwap( SMPmatrix * , int , int ); -void SMPdestroy( SMPmatrix *); -int SMPfillup( SMPmatrix * ); -SMPelement * SMPfindElt( SMPmatrix *, int , int , int ); -void SMPgetError( SMPmatrix *, int *, int *); -int SMPluFac( SMPmatrix *, double , double ); double * SMPmakeElt( SMPmatrix * , int , int ); +void SMPcClear( SMPmatrix *); +void SMPclear( SMPmatrix *); +int SMPcLUfac( SMPmatrix *, double ); +int SMPluFac( SMPmatrix *, double , double ); +int SMPcReorder( SMPmatrix * , double , double , int *); +int SMPreorder( SMPmatrix * , double , double , double ); +void SMPcaSolve(SMPmatrix *Matrix, double RHS[], double iRHS[], + double Spare[], double iSpare[]); +void SMPcSolve( SMPmatrix *, double [], double [], double [], double []); +void SMPsolve( SMPmatrix *, double [], double []); int SMPmatSize( SMPmatrix *); int SMPnewMatrix( SMPmatrix ** ); -int SMPnewNode( int , SMPmatrix *); +void SMPdestroy( SMPmatrix *); int SMPpreOrder( SMPmatrix *); void SMPprint( SMPmatrix * , FILE *); -int SMPreorder( SMPmatrix * , double , double , double ); -void SMProwSwap( SMPmatrix * , int , int ); -void SMPsolve( SMPmatrix *, double [], double []); -#else /* stdc */ -int SMPaddElt(); -void SMPcClear(); -int SMPcLUfac(); -int SMPcProdDiag(); -int SMPcReorder(); -void SMPcSolve(); -void SMPclear(); -void SMPcolSwap(); -void SMPdestroy(); -int SMPfillup(); -SMPelement * SMPfindElt(); -void SMPgetError(); -int SMPluFac(); -double * SMPmakeElt(); -int SMPmatSize(); -int SMPnewMatrix(); -int SMPnewNode(); -int SMPpreOrder(); -void SMPprint(); -int SMPreorder(); -void SMProwSwap(); -void SMPsolve(); -#endif /* stdc */ +void SMPgetError( SMPmatrix *, int *, int *); +int SMPcProdDiag( SMPmatrix *, SPcomplex *, int *); +int SMPcDProd(SMPmatrix *Matrix, SPcomplex *pMantissa, int *pExponent); +SMPelement * SMPfindElt( SMPmatrix *, int , int , int ); +int SMPcZeroCol(SMPmatrix *eMatrix, int Col); +int SMPcAddCol(SMPmatrix *eMatrix, int Accum_Col, int Addend_Col); +int SMPzeroRow(SMPmatrix *eMatrix, int Row); +void spConstMult(SMPmatrix*, double); +#ifdef PARALLEL_ARCH +void SMPcombine(SMPmatrix *Matrix, double RHS[], double Spare[]); +void SMPcCombine(SMPmatrix *Matrix, double RHS[], double Spare[], + double iRHS[], double iSpare[]); +#endif #endif /*SMP*/ diff --git a/src/include/sperror.h b/src/include/sperror.h index 2c9fe3486..d3ef2f3b6 100644 --- a/src/include/sperror.h +++ b/src/include/sperror.h @@ -3,15 +3,15 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles **********/ -#ifndef ERRORS -#define ERRORS +#ifndef _SPERROR_H +#define _SPERROR_H #include "ngspice.h" #include "iferrmsg.h" - /* - * definitions for error codes returned by SPICE3 routines. - */ +/* + * definitions for error codes returned by SPICE3 routines. + */ #define E_INTERN E_PANIC #define E_BADMATRIX (E_PRIVATE+1)/* ill-formed matrix can't be decomposed */ @@ -35,5 +35,6 @@ Author: 1985 Thomas L. Quarles #define E_MULTIERR (E_PRIVATE+18) /* multiple errors from diff. processes */ #endif /* PARALLEL_ARCH */ -char *SPerror(); +const char *SPerror(int type); + #endif diff --git a/src/include/spmatrix.h b/src/include/spmatrix.h index 83afafc15..225264284 100644 --- a/src/include/spmatrix.h +++ b/src/include/spmatrix.h @@ -42,17 +42,6 @@ #ifndef spOKAY -/* - * IMPORTS - * - * >>> Import descriptions: - * spConfig.h - * Macros that customize the sparse matrix routines. - */ - -#include "spconfig.h" - - @@ -76,8 +65,7 @@ * Fatal error. A zero was encountered on the diagonal the matrix. This * does not necessarily imply that the matrix is singular. When this * error occurs, the matrix should be reconstructed and factored using - * spOrderAndFactor(). In spCOMPATIBILITY mode, spZERO_DIAG is - * indistinguishable from spSINGULAR. + * spOrderAndFactor(). * spSINGULAR * Fatal error. Matrix is singular, so no unique solution exists. * spNO_MEMORY @@ -108,21 +96,6 @@ #define spFATAL E_BADMATRIX -#if spCOMPATIBILITY -#define NO_ERROR spOKAY -#define UNDER_FLOW spOKAY -#define OVER_FLOW spOKAY -#define ILL_CONDITIONED spSMALL_PIVOT -#define SINGULAR spSINGULAR -#define NO_MEMORY spNO_MEMORY -#define RANGE spPANIC - -#define FATAL spFATAL - -#undef spZERO_DIAG -#define spZERO_DIAG spSINGULAR -#endif /* spCOMPATIBILITY */ - @@ -145,10 +118,6 @@ #define spREAL double /* #define void int */ -#if spCOMPATIBILITY -#define SPARSE_REAL spREAL -#endif - /* @@ -242,15 +211,6 @@ *((template).Element4Negated+1) -= imag; \ } -#if spCOMPATIBILITY -#define ADD_REAL_ELEMENT_TO_MATRIX spADD_REAL_ELEMENT -#define ADD_IMAG_ELEMENT_TO_MATRIX spADD_IMAG_ELEMENT -#define ADD_COMPLEX_ELEMENT_TO_MATRIX spADD_COMPLEX_ELEMENT -#define ADD_REAL_QUAD_ELEMENT_TO_MATRIX spADD_REAL_ELEMENT -#define ADD_IMAG_QUAD_ELEMENT_TO_MATRIX spADD_IMAG_ELEMENT -#define ADD_COMPLEX_QUAD_ELEMENT_TO_MATRIX spADD_COMPLEX_ELEMENT -#endif - @@ -272,10 +232,6 @@ * before being placed in Element3 and Element4. */ -#if spCOMPATIBILITY -#define spTemplate TemplateStruct -#endif - /* Begin `spTemplate'. */ struct spTemplate { spREAL *Element1 ; @@ -296,146 +252,47 @@ struct spTemplate /* Begin function declarations. */ -#ifdef __STDC__ - -/* For compilers that understand function prototypes. */ - -extern void spClear( char* ); -extern spREAL spCondition( char*, spREAL, int* ); -extern char *spCreate( int, int, int* ); -extern void spDeleteRowAndCol( char*, int, int ); -extern void spDestroy( char* ); -extern int spElementCount( char* ); -extern int spError( char* ); -extern int spFactor( char* ); -extern int spFileMatrix( char*, char*, char*, int, int, int ); -extern int spFileStats( char*, char*, char* ); -extern int spFillinCount( char* ); -extern int spGetAdmittance( char*, int, int, struct spTemplate* ); -extern spREAL *spGetElement( char*, int, int ); +extern void spClear( void * ); +extern spREAL spCondition( void *, spREAL, int* ); +extern void *spCreate( int, int, int* ); +extern void spDeleteRowAndCol( void *, int, int ); +extern void spDestroy(void *); +extern int spElementCount( void * ); +extern int spError( void * ); +extern int spFactor( void * ); +extern int spFileMatrix( void *, char *, char *, int, int, int ); +extern int spFileStats( void *, char *, char * ); +extern int spFillinCount( void * ); +extern int spGetAdmittance( void *, int, int, struct spTemplate* ); +extern spREAL *spGetElement( void *, int, int ); extern char *spGetInitInfo( spREAL* ); -extern int spGetOnes( char*, int, int, int, struct spTemplate* ); -extern int spGetQuad( char*, int, int, int, int, struct spTemplate* ); -extern int spGetSize( char*, int ); -extern int spInitialize( char*, int (*)() ); -extern void spInstallInitInfo( spREAL*, char* ); -extern spREAL spLargestElement( char* ); -extern void spMNA_Preorder( char* ); -extern spREAL spNorm( char* ); -extern int spOrderAndFactor( char*, spREAL*, spREAL, spREAL, int ); -extern int spOriginalCount( char *); -extern void spPartition( char*, int ); -extern void spPrint( char*, int, int, int ); -extern spREAL spPseudoCondition( char* ); -extern spREAL spRoundoff( char*, spREAL ); -extern void spScale( char*, spREAL*, spREAL* ); -extern void spSetComplex( char* ); -extern void spSetReal( char* ); -extern void spStripFills( char* ); -extern void spWhereSingular( char*, int*, int* ); +extern int spGetOnes( void *, int, int, int, struct spTemplate* ); +extern int spGetQuad( void *, int, int, int, int, struct spTemplate* ); +extern int spGetSize( void *, int ); +extern int spInitialize( void *, int (*)() ); +extern void spInstallInitInfo( spREAL*, void * ); +extern spREAL spLargestElement( void * ); +extern void spMNA_Preorder( void * ); +extern spREAL spNorm( void * ); +extern int spOrderAndFactor( void *, spREAL*, spREAL, spREAL, int ); +extern int spOriginalCount( void *); +extern void spPartition( void *, int ); +extern void spPrint( void *, int, int, int ); +extern spREAL spPseudoCondition( void * ); +extern spREAL spRoundoff( void *, spREAL ); +extern void spScale( void *, spREAL*, spREAL* ); +extern void spSetComplex( void * ); +extern void spSetReal( void * ); +extern void spStripFills( void * ); +extern void spWhereSingular( void *, int*, int* ); /* Functions with argument lists that are dependent on options. */ -#if spCOMPLEX -extern void spDeterminant ( char*, int*, spREAL*, spREAL* ); -#else /* NOT spCOMPLEX */ -extern void spDeterminant ( char*, int*, spREAL* ); -#endif /* NOT spCOMPLEX */ -#if spCOMPLEX && spSEPARATED_COMPLEX_VECTORS -extern int spFileVector( char*, char* , spREAL*, spREAL*); -extern void spMultiply( char*, spREAL*, spREAL*, spREAL*, spREAL* ); -extern void spMultTransposed(char*,spREAL*,spREAL*,spREAL*,spREAL*); -extern void spSolve( char*, spREAL*, spREAL*, spREAL*, spREAL* ); -extern void spSolveTransposed(char*,spREAL*,spREAL*,spREAL*,spREAL*); -#else /* NOT (spCOMPLEX && spSEPARATED_COMPLEX_VECTORS) */ -extern int spFileVector( char*, char* , spREAL* ); -extern void spMultiply( char*, spREAL*, spREAL* ); -extern void spMultTransposed( char*, spREAL*, spREAL* ); -extern void spSolve( char*, spREAL*, spREAL* ); -extern void spSolveTransposed( char*, spREAL*, spREAL* ); -#endif /* NOT (spCOMPLEX && spSEPARATED_COMPLEX_VECTORS) */ - -#else /* NOT defined(__STDC__) */ - -/* For compilers that do not understand function prototypes. */ - -extern void spClear(); -extern spREAL spCondition(); -extern char *spCreate(); -extern void spDeleteRowAndCol(); -extern void spDestroy(); -extern void spDeterminant (); -extern int spElementCount(); -extern int spError(); -extern int spFactor(); -extern int spFileMatrix(); -extern int spFileStats(); -extern int spFileVector(); -extern int spFillinCount(); -extern int spGetAdmittance(); -extern spREAL *spGetElement(); -extern char *spGetInitInfo(); -extern int spGetOnes(); -extern int spGetQuad(); -extern int spGetSize(); -extern int spInitialize(); -extern void spInstallInitInfo(); -extern spREAL spLargestElement(); -extern void spMNA_Preorder(); -extern void spMultiply(); -extern void spMultTransposed(); -extern spREAL spNorm(); -extern int spOrderAndFactor(); -extern int spOriginalCount(); -extern void spPartition(); -extern void spPrint(); -extern spREAL spPseudoCondition(); -extern spREAL spRoundoff(); -extern void spScale(); -extern void spSetComplex(); -extern void spSetReal(); -extern void spSolve(); -extern void spSolveTransposed(); -extern void spStripFills(); -extern void spWhereSingular(); -#endif /* defined(__STDC__) */ - -#if spCOMPATIBILITY -extern char *AllocateMatrix(); -extern spREAL *AddElementToMatrix(); -extern void AddRealElementToMatrix(); -extern void AddImagElementToMatrix(); -extern void AddComplexElementToMatrix(); -extern void AddAdmittanceToMatrix(); -extern void AddOnesToMatrix(); -extern void AddQuadToMatrix(); -extern void AddRealQuadElementToMatrix(); -extern void AddImagQuadElementToMatrix(); -extern void AddComplexQuadElementToMatrix(); -extern void CleanMatrix(); -extern void ClearMatrix(); -extern int ClearMatrixError(); -extern void DeallocateMatrix(); -extern void DeleteRowAndColFromMatrix(); -extern void Determinant(); -extern int DecomposeMatrix(); -extern int GetMatrixSize(); -extern int MatrixElementCount(); -extern int MatrixFillinCount(); -extern void MatrixMultiply(); -extern spREAL MatrixRoundoffError(); -extern int MatrixError(); -extern int OrderAndDecomposeMatrix(); -extern void OutputMatrixToFile(); -extern void OutputStatisticsToFile(); -extern void OutputVectorToFile(); -extern void PreorderForModifiedNodal(); -extern void PrintMatrix(); -extern void SetMatrixComplex(); -extern void SetMatrixReal(); -extern void SolveMatrix(); -extern void SolveTransposedMatrix(); -extern void ScaleMatrix(); -#endif /* spCOMPATIBILITY */ +extern void spDeterminant ( void *, int*, spREAL*, spREAL* ); +extern int spFileVector( void *, char * , spREAL*, spREAL*); +extern void spMultiply( void *, spREAL*, spREAL*, spREAL*, spREAL* ); +extern void spMultTransposed(void *,spREAL*,spREAL*,spREAL*,spREAL*); +extern void spSolve( void *, spREAL*, spREAL*, spREAL*, spREAL* ); +extern void spSolveTransposed(void *,spREAL*,spREAL*,spREAL*,spREAL*); #endif /* spOKAY */ diff --git a/src/include/tskdefs.h b/src/include/tskdefs.h index f009e8744..c74dcb103 100644 --- a/src/include/tskdefs.h +++ b/src/include/tskdefs.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* */ @@ -33,6 +34,7 @@ typedef struct { /* (itl4) */ int TSKnumSrcSteps; /* number of steps for source stepping */ int TSKnumGminSteps; /* number of steps for Gmin stepping */ + double TSKgminFactor; /* factor for Gmin stepping */ double TSKminBreak; double TSKabstol; double TSKpivotAbsTol; @@ -45,8 +47,10 @@ typedef struct { double TSKlteAbstol; #endif /* NEWTRUNC */ double TSKgmin; + double TSKgshunt; /* shunt conductance (CKTdiagGmin) */ double TSKdelmin; double TSKtrtol; + double TSKdefaultMosM; double TSKdefaultMosL; double TSKdefaultMosW; double TSKdefaultMosAD; @@ -56,6 +60,11 @@ typedef struct { unsigned int TSKtryToCompact:1; /* flag for LTRA lines */ unsigned int TSKbadMos3:1; /* flag for MOS3 models */ unsigned int TSKkeepOpInfo:1; /* flag for small signal analyses */ + unsigned int TSKcopyNodesets:1; /* flag for nodeset copy */ + unsigned int TSKnodeDamping:1; /* flag for node damping */ + double TSKabsDv; /* abs limit for iter-iter voltage change */ + double TSKrelDv; /* rel limit for iter-iter voltage change */ + }TSKtask; #endif /*TSK*/ diff --git a/src/main.c b/src/main.c index 1f0b6f062..3980d9e0b 100644 --- a/src/main.c +++ b/src/main.c @@ -5,24 +5,34 @@ Author: 1985 Wayne A. Christopher The main routine for ngspice */ +#include + #include +#ifdef HAVE_STRING_H +#include +#endif /* HAVE_STRING_H */ #include #include #include -#define _GNU_SOURCE -#include -#include "ngspice.h" -#include "ifsim.h" -#include "inpdefs.h" -#include "iferrmsg.h" -#include "cpdefs.h" -#include "ftedefs.h" -#include "ftedev.h" -#include "ftedebug.h" -#include "const.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* saj xspice headers */ +#ifdef XSPICE +#include "ipctiein.h" +#include "mif.h" +#include "enh.h" +#endif #ifdef HAVE_PWD_H #include @@ -143,6 +153,40 @@ if_getstat(char *n, char *c) return (NULL); } +#ifdef EXPERIMENTAL_CODE +void com_loadsnap(wordlist *wl) { return; } +void com_savesnap(wordlist *wl) { return; } +#endif + + +#ifdef XSPICE +/* saj to get nutmeg to compile, not nice but necessary */ +Ipc_Tiein_t g_ipc; +Ipc_Status_t ipc_send_errchk(void ) { + Ipc_Status_t x=0; + return(x); +} +Ipc_Status_t ipc_get_line(char *str , int *len , Ipc_Wait_t wait ){ + Ipc_Status_t x=0; + return(x); +} +struct line *ENHtranslate_poly(struct line *deck){ + return(NULL); +} +int load_opus(char *name){ + return(1); +} +char *MIFgettok(char **s){ + return(NULL); +} +void EVTprint(wordlist *wl){ + return; +} +struct dvec *EVTfindvec(char *node){ + return NULL; +} +#endif + #endif /* SIMULATOR */ char *hlp_filelist[] = { "ngspice", 0 }; @@ -155,11 +199,19 @@ double CONSTvt0; double CONSTKoverQ; double CONSTe; IFfrontEnd *SPfrontEnd = NULL; - +int DEVmaxnum = 0; int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator) { +#ifdef SIMULATOR + spice_init_devices(); + SIMinfo.numDevices = DEVmaxnum = num_devices(); + SIMinfo.devices = devices_ptr(); + SIMinfo.numAnalyses = spice_num_analysis(); + SIMinfo.analyses = spice_analysis_ptr(); +#endif /* SIMULATOR */ + SPfrontEnd = frontEnd; *simulator = &SIMinfo; CONSTroot2 = sqrt(2.); @@ -227,21 +279,11 @@ append_to_stream(FILE *dest, FILE *source) while ((i = fread(buf, 1, BSIZE_SP, source)) > 0) fwrite(buf, i, 1, dest); } - -int -main(int argc, char **argv) -{ - int c; - int err; - bool gotone = FALSE; - #ifdef SIMULATOR - int error2; - extern int OUTpBeginPlot(), OUTpData(), OUTwBeginPlot(), OUTwReference(); extern int OUTwData(), OUTwEnd(), OUTendPlot(), OUTbeginDomain(); extern int OUTendDomain(), OUTstopnow(), OUTerror(), OUTattributes(); - static IFfrontEnd nutmeginfo = { + IFfrontEnd nutmeginfo = { IFnewUid, IFdelUid, OUTstopnow, @@ -258,13 +300,23 @@ main(int argc, char **argv) OUTendDomain, OUTattributes }; +#endif +int +main(int argc, char **argv) +{ + int c; + int err; + bool gotone = FALSE; + char* copystring;/*DG*/ +#ifdef SIMULATOR + int error2; + #else /* ~ SIMULATOR */ bool gdata = TRUE; #endif /* ~ SIMULATOR */ char buf[BSIZE_SP]; - bool ciprefix(); bool readinit = TRUE; bool rflag = FALSE; bool istty = TRUE; @@ -475,7 +527,7 @@ main(int argc, char **argv) signal(SIGBUS, sigbus); #endif #ifdef SIGSEGV - signal(SIGSEGV, sigsegv); +//want core files! signal(SIGSEGV, sigsegv); #endif #ifdef SIGSYS signal(SIGSYS, sig_sys); @@ -492,12 +544,20 @@ main(int argc, char **argv) struct passwd *pw; pw = getpwuid(getuid()); + +#ifdef HAVE_ASPRINTF asprintf(&s, "%s/.spiceinit", pw->pw_dir); +#else /* ~ HAVE_ASPRINTF */ +#define INITSTR "/.spiceinit" +if ( (s=(char *) malloc(1 + strlen(pw->pw_dir)+strlen(INITSTR))) == NULL){ + fprintf(stderr,"malloc failed\n"); + exit(1); + } + sprintf(s,"%s%s",pw->pw_dir,INITSTR); +#endif /* HAVE_ASPRINTF */ + if (access(s, 0) == 0) inp_source(s); - /* free(s); */ - /* FIXME: Do we need to free() char* fields in pw as well? */ - /* free(pw); */ } #else /* ~ HAVE_PWD_H */ /* Try to source the file "spice.rc" in the current directory. */ @@ -512,7 +572,9 @@ main(int argc, char **argv) com_version(NULL); DevInit( ); if (News_File && *News_File) { - fp = fopen(cp_tildexpand(News_File), "r"); + copystring=cp_tildexpand(News_File);/*DG Memory leak */ + fp = fopen(copystring, "r"); + tfree(copystring); if (fp) { while (fgets(buf, BSIZE_SP, fp)) fputs(buf, stdout); @@ -606,7 +668,7 @@ evl: * save too much. */ cp_interactive = FALSE; if (rflag) { - ft_dotsaves(); + /* saj done already in inp_spsource ft_dotsaves();*/ error2 = ft_dorun(ft_rawfile); if (ft_cktcoms(TRUE) || error2) shutdown(EXIT_BAD); diff --git a/src/maths/Makefile.am b/src/maths/Makefile.am index 793998744..fbf0b1bd5 100644 --- a/src/maths/Makefile.am +++ b/src/maths/Makefile.am @@ -1,4 +1,4 @@ # Process this file with automake -SUBDIRS = cmaths ni sparse +SUBDIRS = cmaths ni sparse poly deriv MAINTAINERCLEANFILES = Makefile.in diff --git a/src/maths/cmaths/Makefile.am b/src/maths/cmaths/Makefile.am index b9795ae61..5fedf543a 100644 --- a/src/maths/cmaths/Makefile.am +++ b/src/maths/cmaths/Makefile.am @@ -3,6 +3,7 @@ noinst_LIBRARIES = libcmaths.a libcmaths_a_SOURCES = \ + cmath.h \ cmath1.c \ cmath1.h \ cmath2.c \ @@ -12,8 +13,34 @@ libcmaths_a_SOURCES = \ cmath4.c \ cmath4.h +noinst_PROGRAMS = test_cx_mag test_cx_j test_cx_ph +test_cx_ph_SOURCES = \ + test_cx_ph.c -INCLUDES = -I$(top_srcdir)/src/include +test_cx_ph_LDADD = \ + libcmaths.a \ + ../../misc/libmisc.a \ + @TCL_BUILD_LIB_SPEC@ + +test_cx_mag_SOURCES = \ + test_cx_mag.c + +test_cx_mag_LDADD = \ + libcmaths.a \ + ../../misc/libmisc.a \ + @TCL_BUILD_LIB_SPEC@ + +test_cx_j_SOURCES = \ + test_cx_j.c + +test_cx_j_LDADD = \ + libcmaths.a \ + ../../misc/libmisc.a \ + @TCL_BUILD_LIB_SPEC@ + +TESTS = test_cx_mag test_cx_j test_cx_ph + +INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/maths/poly MAINTAINERCLEANFILES = Makefile.in diff --git a/src/maths/cmaths/cmath1.c b/src/maths/cmaths/cmath1.c index fd61677ff..d755d0bab 100644 --- a/src/maths/cmaths/cmath1.c +++ b/src/maths/cmaths/cmath1.c @@ -16,11 +16,12 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group * */ -#include "ngspice.h" -#include "cpdefs.h" -#include "ftedefs.h" -#include "ftedata.h" -#include "ftecmath.h" +#include +#include +#include +#include + +#include "cmath.h" #include "cmath1.h" diff --git a/src/maths/cmaths/cmath2.c b/src/maths/cmaths/cmath2.c index 4333867d1..26c7c982d 100644 --- a/src/maths/cmaths/cmath2.c +++ b/src/maths/cmaths/cmath2.c @@ -15,11 +15,12 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group * and return a char * that is cast to complex or double. */ -#include "ngspice.h" -#include "cpdefs.h" -#include "ftedefs.h" -#include "ftedata.h" -#include "ftecmath.h" +#include +#include +#include +#include + +#include "cmath.h" #include "cmath2.h" static double * @@ -105,7 +106,7 @@ cx_atan(void *data, short int type, int length, int *newlength, short int *newty double -cx_max(void *data, short int type, int length) +cx_max_local(void *data, short int type, int length) { double largest = 0.0; @@ -134,7 +135,7 @@ cx_norm(void *data, short int type, int length, int *newlength, short int *newty { double largest = 0.0; - largest = cx_max(data, type, length); + largest = cx_max_local(data, type, length); if (largest == 0.0) { fprintf(cp_err, "Error: can't normalize a 0 vector\n"); return (NULL); @@ -520,3 +521,131 @@ cx_mod(void *data1, void *data2, short int datatype1, short int datatype2, int l } } + +/* Routoure JM : Compute the max of a vector. */ + +void * +cx_max(void *data, short int type, int length, int *newlength, short int *newtype) +{ + *newlength = 1; + /* test if length >0 et affiche un message d'erreur */ + rcheck(length > 0, "mean"); + if (type == VF_REAL) { + double largest=0.0; + double *d; + double *dd = (double *) data; + int i; + + d = alloc_d(1); + *newtype = VF_REAL; + largest=dd[0]; + for (i = 1; i < length; i++) + if (dd[i]>largest) largest=dd[i]; + *d=largest; + return ((void *) d); + } else { + double largest_real=0.0; + double largest_complex=0.0; + complex *c; + complex *cc = (complex *) data; + int i; + + c = alloc_c(1); + *newtype = VF_COMPLEX; + largest_real=realpart(cc); + largest_complex=imagpart(cc); + for (i = 0; i < length; i++) { + if (realpart(cc + i)>largest_real) largest_real=realpart(cc + i); + if (imagpart(cc + i)>largest_complex) largest_complex=imagpart(cc + i); + } + realpart(c) = largest_real; + imagpart(c) = largest_complex; + return ((void *) c); + } +} +/* Routoure JM : Compute the min of a vector. */ + +void * +cx_min(void *data, short int type, int length, int *newlength, short int *newtype) +{ + *newlength = 1; + /* test if length >0 et affiche un message d'erreur */ + rcheck(length > 0, "mean"); + if (type == VF_REAL) { + double smallest; + double *d; + double *dd = (double *) data; + int i; + + d = alloc_d(1); + *newtype = VF_REAL; + smallest=dd[0]; + for (i = 1; i < length; i++) + if (dd[i]0 et affiche un message d'erreur */ + rcheck(length > 0, "deriv"); + if (type == VF_REAL) { + double *d; + double *dd = (double *) data; + int i; + + d = alloc_d(length); + *newtype = VF_REAL; + d[0]=dd[1]-dd[0]; + d[length-1]=dd[length-1]-dd[length-2]; + for (i = 1; i < length-1; i++) + d[i]=dd[i+1]-dd[i-1]; + + return ((void *) d); + } else { + + complex *c; + complex *cc = (complex *) data; + int i; + + c = alloc_c(length); + *newtype = VF_COMPLEX; + realpart(c)=realpart(cc+1)-realpart(cc); + imagpart(c)=imagpart(cc+1)-imagpart(cc); + realpart(c+length-1)=realpart(cc+length-1)-realpart(cc+length-2); + imagpart(c+length-1)=imagpart(cc+length-1)-imagpart(cc+length-2); + + + for (i = 1; i < (length-1); i++) { + realpart(c+i)=realpart(cc+i+1)-realpart(cc+i-1); + imagpart(c+i)=imagpart(cc+i+1)-imagpart(cc+i-1); + + } + return ((void *) c); + } +} diff --git a/src/maths/cmaths/cmath2.h b/src/maths/cmaths/cmath2.h index 1be23e970..16cdf668f 100644 --- a/src/maths/cmaths/cmath2.h +++ b/src/maths/cmaths/cmath2.h @@ -20,6 +20,12 @@ void * cx_plus(void *data1, void *data2, short int datatype1, short int datatype void * cx_minus(void *data1, void *data2, short int datatype1, short int datatype2, int length); void * cx_times(void *data1, void *data2, short int datatype1, short int datatype2, int length); void * cx_mod(void *data1, void *data2, short int datatype1, short int datatype2, int length); +void * cx_max(void *data, short int type, int length, int *newlength, short int *newtype); +void * cx_min(void *data, short int type, int length, int *newlength, short int *newtype); +void * cx_d(void *data, short int type, int length, int *newlength, short int *newtype); #endif + + + diff --git a/src/maths/cmaths/cmath3.c b/src/maths/cmaths/cmath3.c index db6b799d7..7c6f8c4d1 100644 --- a/src/maths/cmaths/cmath3.c +++ b/src/maths/cmaths/cmath3.c @@ -15,11 +15,11 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group * and return a char * that is cast to complex or double. */ -#include "ngspice.h" -#include "cpdefs.h" -#include "ftedefs.h" -#include "ftedata.h" -#include "ftecmath.h" +#include +#include +#include + +#include "cmath.h" #include "cmath3.h" diff --git a/src/maths/cmaths/cmath4.c b/src/maths/cmaths/cmath4.c index 833d13560..aca045e7b 100644 --- a/src/maths/cmaths/cmath4.c +++ b/src/maths/cmaths/cmath4.c @@ -15,13 +15,18 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group * and return a char * that is cast to complex or double. */ -#include "ngspice.h" -#include "cpdefs.h" -#include "ftedefs.h" -#include "ftedata.h" -#include "ftecmath.h" -#include "cmath4.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cmath.h" +#include "cmath4.h" void * cx_and(void *data1, void *data2, short int datatype1, short int datatype2, int length) @@ -123,6 +128,12 @@ cx_not(void *data, short int type, int length, int *newlength, short int *newtyp return ((void *) d); } +#if 0 +/* These functions have been temporarily disabled. They contain code + only found in the frontend and their prototype does not conform to + the prototypes found for other complex functions. They will not be + re-enabled until these issues have been resolved. */ + /* This is a strange function. What we do is fit a polynomial to the * curve, of degree $polydegree, and then evaluate it at the points * in the time scale. What we do is this: for every set of points that @@ -130,9 +141,8 @@ cx_not(void *data, short int type, int length, int *newlength, short int *newtyp * (i.e, between the last value of the old scale we went from to this * one). At the ends we just use what we have... We have to detect * badness here too... - * Note that we pass arguments differently for this one cx_ function... - */ - + * + * Note that we pass arguments differently for this one cx_ function... */ void * cx_interpolate(void *data, short int type, int length, int *newlength, short int *newtype, struct plot *pl, struct plot *newpl, int grouping) { @@ -155,28 +165,10 @@ cx_interpolate(void *data, short int type, int length, int *newlength, short int if (iscomplex(ns)) { fprintf(cp_err, "Error: new scale has complex data\n"); return (NULL); - /* - for (i = ns->v_length - 1; i >= 0; i--) - if (imagpart(&ns->v_compdata[i])) { - fprintf(cp_err, - "Error: new scale has complex data\n"); - return (NULL); - } - osbuf = alloc_d(olen); - */ } if (iscomplex(os)) { fprintf(cp_err, "Error: old scale has complex data\n"); return (NULL); - /* - for (i = os->v_length - 1; i >= 0; i--) - if (imagpart(&os->v_compdata[i])) { - fprintf(cp_err, - "Error: old scale has complex data\n"); - return (NULL); - } - nsbuf = alloc_d(nlen); - */ } if (length != os->v_length) { @@ -188,9 +180,8 @@ cx_interpolate(void *data, short int type, int length, int *newlength, short int return (NULL); } - /* Now make sure that either both scales are strictly increasing or - * both are strictly decreasing. - */ + /* Now make sure that either both scales are strictly increasing + * or both are strictly decreasing. */ if (os->v_realdata[0] < os->v_realdata[1]) oincreasing = TRUE; else @@ -377,3 +368,4 @@ cx_deriv(void *data, short int type, int length, int *newlength, short int *newt } } +#endif diff --git a/src/maths/ni/ChangeLog b/src/maths/ni/ChangeLog index 97fb7914c..2f12d9a01 100644 --- a/src/maths/ni/ChangeLog +++ b/src/maths/ni/ChangeLog @@ -1,3 +1,8 @@ +2000-07-18 Arno W. Peters + + * niconv.c: Removed NEWCONV. This symbol was defined by default, + adjusted the code to this reality. + 1999-09-03 Emmanuel Rouat * *.h: added header file for each .c file diff --git a/src/maths/ni/niconv.c b/src/maths/ni/niconv.c index d85028914..ed293be81 100644 --- a/src/maths/ni/niconv.c +++ b/src/maths/ni/niconv.c @@ -59,12 +59,8 @@ NIconvTest(register CKTcircuit *ckt) } -#ifdef NEWCONV i = CKTconvTest(ckt); if (i) ckt->CKTtroubleNode = 0; return(i); -#else /* NEWCONV */ - return(0); -#endif /* NEWCONV */ } diff --git a/src/maths/ni/niiter.c b/src/maths/ni/niiter.c index 9b58daef8..d49ba0123 100644 --- a/src/maths/ni/niiter.c +++ b/src/maths/ni/niiter.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2001 AlansFixes **********/ /* @@ -36,6 +37,9 @@ NIiter(register CKTcircuit *ckt, int maxIter) static char *msg = "Too many iterations without convergence"; + CKTnode *node; /* current matrix entry */ + double diff, maxdiff, damp_factor, *OldCKTstate0=NULL; + iterno=0; ipass=0; @@ -81,6 +85,7 @@ NIiter(register CKTcircuit *ckt, int maxIter) #ifdef STEPDEBUG printf("load returned error \n"); #endif + FREE(OldCKTstate0); return(error); } /*printf("after loading, before solving\n");*/ @@ -93,6 +98,7 @@ NIiter(register CKTcircuit *ckt, int maxIter) #ifdef STEPDEBUG printf("pre-order returned error \n"); #endif + FREE(OldCKTstate0); return(error); /* badly formed matrix */ } ckt->CKTniState |= NIDIDPREORDER; @@ -123,6 +129,7 @@ NIiter(register CKTcircuit *ckt, int maxIter) #ifdef STEPDEBUG printf("reorder returned error \n"); #endif + FREE(OldCKTstate0); return(error); /* can't handle these errors - pass up! */ } ckt->CKTniState &= ~NISHOULDREORDER; @@ -145,10 +152,18 @@ NIiter(register CKTcircuit *ckt, int maxIter) #ifdef STEPDEBUG printf("lufac returned error \n"); #endif + FREE(OldCKTstate0); return(error); } } - + /*moved it to here as if xspice is included then CKTload changes + CKTnumStates the first time it is run */ + if(!OldCKTstate0) + OldCKTstate0=(double *)MALLOC((ckt->CKTnumStates+1)*sizeof(double)); + for(i=0;iCKTnumStates;i++) { + *(OldCKTstate0+i) = *(ckt->CKTstate0+i); + }; + startTime = (*(SPfrontEnd->IFseconds))(); SMPsolve(ckt->CKTmatrix,ckt->CKTrhs,ckt->CKTrhsSpare); ckt->CKTstat->STATsolveTime += (*(SPfrontEnd->IFseconds))()- @@ -176,6 +191,7 @@ NIiter(register CKTcircuit *ckt, int maxIter) #ifdef STEPDEBUG printf("iterlim exceeded \n"); #endif + FREE(OldCKTstate0); return(E_ITERLIM); } if(ckt->CKTnoncon==0 && iterno!=1) { @@ -188,6 +204,36 @@ NIiter(register CKTcircuit *ckt, int maxIter) #endif } + if( (ckt->CKTnodeDamping!=0) && (ckt->CKTnoncon!=0) && + ((ckt->CKTmode & MODETRANOP) || (ckt->CKTmode & MODEDCOP)) && + (iterno>1) ) { + maxdiff=0; + for (node = ckt->CKTnodes->next; node; node = node->next) { + if(node->type == NODE_VOLTAGE) { + diff = (ckt->CKTrhs)[node->number] - + (ckt->CKTrhsOld)[node->number]; + if (diff>maxdiff) maxdiff=diff; + }; + }; + if (maxdiff>10) { + damp_factor=10/maxdiff; + if (damp_factor<0.1) damp_factor=0.1; + for (node = ckt->CKTnodes->next; node; node = node->next) { + diff = (ckt->CKTrhs)[node->number] - + (ckt->CKTrhsOld)[node->number]; + (ckt->CKTrhs)[node->number]=(ckt->CKTrhsOld)[node->number] + + (damp_factor * diff); + }; + for(i=0;iCKTnumStates;i++) { + diff = *(ckt->CKTstate0+i) - *(OldCKTstate0+i); + *(ckt->CKTstate0+i) = *(OldCKTstate0+i) + + (damp_factor * diff); + }; + }; + } + + + if(ckt->CKTmode & MODEINITFLOAT) { if ((ckt->CKTmode & MODEDC) && ( ckt->CKThadNodeset) ) { @@ -198,6 +244,7 @@ NIiter(register CKTcircuit *ckt, int maxIter) } if(ckt->CKTnoncon == 0) { ckt->CKTstat->STATnumIter += iterno; + FREE(OldCKTstate0); return(OK); } } else if(ckt->CKTmode & MODEINITJCT) { @@ -219,6 +266,7 @@ NIiter(register CKTcircuit *ckt, int maxIter) #ifdef STEPDEBUG printf("bad initf state \n"); #endif + FREE(OldCKTstate0); return(E_INTERN); /* impossible - no such INITF flag! */ } diff --git a/src/maths/ni/nipzmeth.c b/src/maths/ni/nipzmeth.c index ff2482f99..d265947bb 100644 --- a/src/maths/ni/nipzmeth.c +++ b/src/maths/ni/nipzmeth.c @@ -19,6 +19,8 @@ static unsigned int Debug = 0; */ #endif +extern void zaddeq(double *a, int *amag, double x, int xmag, double y, int ymag); + extern int CKTpzTrapped; double NIpzK; int NIpzK_mag; @@ -26,55 +28,13 @@ int NIpzK_mag; int NIpzSym(PZtrial **set, PZtrial *new) { -#ifndef notdef return NIpzSym2(set, new); -#else - double a, b, c, x0, x1; - double dx0, dx1; - int a_mag, b_mag, c_mag; - - dx0 = set[1]->s.real - set[0]->s.real; - dx1 = set[2]->s.real - set[1]->s.real; - - zaddeq(&a, &a_mag, set[1]->f_def.real, set[1]->mag_def, - -set[0]->f_def.real, set[0]->mag_def); - a /= dx0; - zaddeq(&b, &b_mag, set[2]->f_def.real, set[2]->mag_def, - -set[1]->f_def.real, set[1]->mag_def); - b /= dx1; - zaddeq(&c, &c_mag, b, b_mag, -a, a_mag); - - /* XXX What if c == 0.0 ? */ - - x0 = (set[0]->s.real + set[1]->s.real) / 2.0; - x1 = (set[1]->s.real + set[2]->s.real) / 2.0; - - c /= (x1 - x0); - - new->s.real = - a / c; - c_mag -= a_mag; - - new->s.imag = 0.0; - - while (c_mag > 0) { - new->s.real /= 2.0; - c_mag -= 1; - } - while (c_mag < 0) { - new->s.real *= 2.0; - c_mag += 1; - } - new->s.real += set[0]->s.real; -#endif } int NIpzComplex(PZtrial **set, PZtrial *new) { return NIpzSym2(set, new); -#ifdef notdef - NIpzMuller(set, new); -#endif } int @@ -257,7 +217,7 @@ NIpzSym2(PZtrial **set, PZtrial *new) int tmag; int error; int disc_mag; - int new_mag; + int new_mag = 0; error = OK; diff --git a/src/maths/ni/nireinit.c b/src/maths/ni/nireinit.c index 8b50e1bb7..f0a9e3f34 100644 --- a/src/maths/ni/nireinit.c +++ b/src/maths/ni/nireinit.c @@ -21,9 +21,12 @@ Author: 1985 Thomas L. Quarles (type *) MALLOC((size)*sizeof(type))) == NULL) return(E_NOMEM); int -NIreinit(register CKTcircuit *ckt) +NIreinit( CKTcircuit *ckt) { - register int size; + int size; +#ifdef PREDICTOR + int i; +#endif size = SMPmatSize(ckt->CKTmatrix); CKALLOC(CKTrhs,size+1,double); @@ -34,7 +37,7 @@ NIreinit(register CKTcircuit *ckt) CKALLOC(CKTirhsSpare,size+1,double); #ifdef PREDICTOR CKALLOC(CKTpred,size+1,double); - for(i=0;i<8;i++) { + for( i=0;i<8;i++) { CKALLOC(CKTsols[i],size+1,double); } #endif /* PREDICTOR */ diff --git a/src/maths/sparse/Makefile.am b/src/maths/sparse/Makefile.am index a9fb22371..ddedb9686 100644 --- a/src/maths/sparse/Makefile.am +++ b/src/maths/sparse/Makefile.am @@ -3,16 +3,17 @@ noinst_LIBRARIES = libsparse.a libsparse_a_SOURCES = \ - spalloc.c \ - spbuild.c \ - spcombin.c \ - spdefs.h \ - spextra.c \ - spfactor.c \ - spoutput.c \ - spsmp.c \ - spsolve.c \ - sputils.c + spalloc.c \ + spbuild.c \ + spcombin.c \ + spconfig.h \ + spdefs.h \ + spextra.c \ + spfactor.c \ + spoutput.c \ + spsmp.c \ + spsolve.c \ + sputils.c diff --git a/src/maths/sparse/spalloc.c b/src/maths/sparse/spalloc.c index 733a2b3d1..b9e8e6e22 100644 --- a/src/maths/sparse/spalloc.c +++ b/src/maths/sparse/spalloc.c @@ -47,15 +47,6 @@ * or implied warranty. */ -#ifdef notdef -static char copyright[] = - "Sparse1.3: Copyright (c) 1985,86,87,88,89,90 by Kenneth S. Kundert"; -static char RCSid[] = - "@(#)$Header$"; -#endif - - - /* * IMPORTS * @@ -67,6 +58,7 @@ static char RCSid[] = * spDefs.h * Matrix type and macro definitions for the sparse matrix routines. */ +#include #define spINSIDE_SPARSE #include "spconfig.h" @@ -84,15 +76,9 @@ static char RCSid[] = * Function declarations */ -#ifdef __STDC__ static void InitializeElementBlocks( MatrixPtr, int, int ); -static void RecordAllocation( MatrixPtr, char* ); +static void RecordAllocation( MatrixPtr, void *); static void AllocateBlockOfAllocationList( MatrixPtr ); -#else /* __STDC__ */ -static void InitializeElementBlocks(); -static void RecordAllocation(); -static void AllocateBlockOfAllocationList(); -#endif /* __STDC__ */ @@ -133,51 +119,42 @@ static void AllocateBlockOfAllocationList(); * Error is cleared in this routine. */ -char * -spCreate( Size, Complex, pError ) - -int Size, *pError; -BOOLEAN Complex; +void * +spCreate(int Size, int Complex, int *pError) { -register unsigned SizePlusOne; -register MatrixPtr Matrix; -register int I; -int AllocatedSize; + unsigned SizePlusOne; + MatrixPtr Matrix; + int I; + int AllocatedSize; -/* Begin `spCreate'. */ -/* Clear error flag. */ + /* Begin `spCreate'. */ + /* Clear error flag. */ *pError = spOKAY; -/* Test for valid size. */ - if ((Size < 0) OR (Size == 0 AND NOT EXPANDABLE)) - { *pError = spPANIC; + /* Test for valid size. */ + if ((Size < 0) || (Size == 0 && !EXPANDABLE)) { + *pError = spPANIC; return NULL; } -/* Test for valid type. */ -#if NOT spCOMPLEX - if (Complex) - { *pError = spPANIC; - return NULL; - } -#endif -#if NOT REAL - if (NOT Complex) - { *pError = spPANIC; - return NULL; + /* Test for valid type. */ +#if !REAL + if (!Complex) { + *pError = spPANIC; + return NULL; } #endif -/* Create Matrix. */ + /* Create Matrix. */ AllocatedSize = MAX( Size, MINIMUM_ALLOCATED_SIZE ); SizePlusOne = (unsigned)(AllocatedSize + 1); - if ((Matrix = ALLOC(struct MatrixFrame, 1)) == NULL) - { *pError = spNO_MEMORY; - return NULL; + if ((Matrix = ALLOC(struct MatrixFrame, 1)) == NULL) { + *pError = spNO_MEMORY; + return NULL; } -/* Initialize matrix */ + /* Initialize matrix */ Matrix->ID = SPARSE_ID; Matrix->Complex = Complex; Matrix->PreviousMatrixWasComplex = Complex; @@ -217,14 +194,12 @@ int AllocatedSize; Matrix->ElementsRemaining = 0; Matrix->FillinsRemaining = 0; - RecordAllocation( Matrix, (char *)Matrix ); + RecordAllocation( Matrix, (void *)Matrix ); if (Matrix->Error == spNO_MEMORY) goto MemoryError; -/* Take out the trash. */ + /* Take out the trash. */ Matrix->TrashCan.Real = 0.0; -#if spCOMPLEX Matrix->TrashCan.Imag = 0.0; -#endif Matrix->TrashCan.Row = 0; Matrix->TrashCan.Col = 0; Matrix->TrashCan.NextInRow = NULL; @@ -233,67 +208,68 @@ int AllocatedSize; Matrix->TrashCan.pInitInfo = NULL; #endif -/* Allocate space in memory for Diag pointer vector. */ + /* Allocate space in memory for Diag pointer vector. */ CALLOC( Matrix->Diag, ElementPtr, SizePlusOne); if (Matrix->Diag == NULL) goto MemoryError; -/* Allocate space in memory for FirstInCol pointer vector. */ + /* Allocate space in memory for FirstInCol pointer vector. */ CALLOC( Matrix->FirstInCol, ElementPtr, SizePlusOne); if (Matrix->FirstInCol == NULL) goto MemoryError; -/* Allocate space in memory for FirstInRow pointer vector. */ + /* Allocate space in memory for FirstInRow pointer vector. */ CALLOC( Matrix->FirstInRow, ElementPtr, SizePlusOne); if (Matrix->FirstInRow == NULL) goto MemoryError; -/* Allocate space in memory for IntToExtColMap vector. */ + /* Allocate space in memory for IntToExtColMap vector. */ if (( Matrix->IntToExtColMap = ALLOC(int, SizePlusOne)) == NULL) goto MemoryError; -/* Allocate space in memory for IntToExtRowMap vector. */ + /* Allocate space in memory for IntToExtRowMap vector. */ if (( Matrix->IntToExtRowMap = ALLOC(int, SizePlusOne)) == NULL) goto MemoryError; -/* Initialize MapIntToExt vectors. */ + /* Initialize MapIntToExt vectors. */ for (I = 1; I <= AllocatedSize; I++) - { Matrix->IntToExtRowMap[I] = I; + { + Matrix->IntToExtRowMap[I] = I; Matrix->IntToExtColMap[I] = I; } #if TRANSLATE -/* Allocate space in memory for ExtToIntColMap vector. */ + /* Allocate space in memory for ExtToIntColMap vector. */ if (( Matrix->ExtToIntColMap = ALLOC(int, SizePlusOne)) == NULL) goto MemoryError; -/* Allocate space in memory for ExtToIntRowMap vector. */ + /* Allocate space in memory for ExtToIntRowMap vector. */ if (( Matrix->ExtToIntRowMap = ALLOC(int, SizePlusOne)) == NULL) goto MemoryError; -/* Initialize MapExtToInt vectors. */ - for (I = 1; I <= AllocatedSize; I++) - { Matrix->ExtToIntColMap[I] = -1; - Matrix->ExtToIntRowMap[I] = -1; + /* Initialize MapExtToInt vectors. */ + for (I = 1; I <= AllocatedSize; I++) { + Matrix->ExtToIntColMap[I] = -1; + Matrix->ExtToIntRowMap[I] = -1; } Matrix->ExtToIntColMap[0] = 0; Matrix->ExtToIntRowMap[0] = 0; #endif -/* Allocate space for fill-ins and initial set of elements. */ + /* Allocate space for fill-ins and initial set of elements. */ InitializeElementBlocks( Matrix, SPACE_FOR_ELEMENTS*AllocatedSize, - SPACE_FOR_FILL_INS*AllocatedSize ); + SPACE_FOR_FILL_INS*AllocatedSize ); if (Matrix->Error == spNO_MEMORY) goto MemoryError; - return (char *)Matrix; + return (void *)Matrix; -MemoryError: + MemoryError: -/* Deallocate matrix and return no pointer to matrix if there is not enough - memory. */ + /* Deallocate matrix and return no pointer to matrix if there is not enough + memory. */ *pError = spNO_MEMORY; - spDestroy( (char *)Matrix); + spDestroy( (void *)Matrix); return NULL; } @@ -329,48 +305,46 @@ MemoryError: */ ElementPtr -spcGetElement( Matrix ) - -MatrixPtr Matrix; +spcGetElement(MatrixPtr Matrix) { -ElementPtr pElements; + ElementPtr pElements; -/* Begin `spcGetElement'. */ + /* Begin `spcGetElement'. */ -#if NOT COMBINE OR STRIP OR LINT -/* Allocate block of MatrixElements if necessary. */ - if (Matrix->ElementsRemaining == 0) - { pElements = ALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION); - RecordAllocation( Matrix, (char *)pElements ); +#if !COMBINE || STRIP || LINT + /* Allocate block of MatrixElements if necessary. */ + if (Matrix->ElementsRemaining == 0) { + pElements = ALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION); + RecordAllocation( Matrix, (void *)pElements ); if (Matrix->Error == spNO_MEMORY) return NULL; Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION; Matrix->NextAvailElement = pElements; } #endif -#if COMBINE OR STRIP OR LINT +#if COMBINE || STRIP || LINT if (Matrix->ElementsRemaining == 0) - { pListNode = Matrix->LastElementListNode; + { + pListNode = Matrix->LastElementListNode; -/* First see if there are any stripped elements left. */ - if (pListNode->Next != NULL) - { Matrix->LastElementListNode = pListNode = pListNode->Next; + /* First see if there are any stripped elements left. */ + if (pListNode->Next != NULL) { + Matrix->LastElementListNode = pListNode = pListNode->Next; Matrix->ElementsRemaining = pListNode->NumberOfElementsInList; Matrix->NextAvailElement = pListNode->pElementList; - } - else - { -/* Allocate block of elements. */ + } else { + /* Allocate block of elements. */ pElements = ALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION); - RecordAllocation( Matrix, (char *)pElements ); + RecordAllocation( Matrix, (void *)pElements ); if (Matrix->Error == spNO_MEMORY) return NULL; Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION; Matrix->NextAvailElement = pElements; -/* Allocate an element list structure. */ + /* Allocate an element list structure. */ pListNode->Next = ALLOC(struct ElementListNodeStruct,1); - RecordAllocation( Matrix, (char *)pListNode->Next ); - if (Matrix->Error == spNO_MEMORY) return NULL; + RecordAllocation( Matrix, (void *)pListNode->Next ); + if (Matrix->Error == spNO_MEMORY) + return NULL; Matrix->LastElementListNode = pListNode = pListNode->Next; pListNode->pElementList = pElements; @@ -380,7 +354,7 @@ ElementPtr pElements; } #endif -/* Update Element counter and return pointer to Element. */ + /* Update Element counter and return pointer to Element. */ Matrix->ElementsRemaining--; return Matrix->NextAvailElement++; @@ -396,11 +370,11 @@ ElementPtr pElements; /* * ELEMENT ALLOCATION INITIALIZATION * - * This routine allocates space for matrix fill-ins and an initial set of - * elements. Besides being faster than allocating space for elements one - * at a time, it tends to keep the fill-ins physically close to the other - * matrix elements in the computer memory. This keeps virtual memory paging - * to a minimum. + * This routine allocates space for matrix fill-ins and an initial + * set of elements. Besides being faster than allocating space for + * elements one at a time, it tends to keep the fill-ins physically + * close to the other matrix elements in the computer memory. This + * keeps virtual memory paging to a minimum. * * >>> Arguments: * Matrix (MatrixPtr) @@ -420,30 +394,26 @@ ElementPtr pElements; * A pointer to the first element in the group of elements being allocated. * * >>> Possible errors: - * spNO_MEMORY - */ + * spNO_MEMORY */ static void -InitializeElementBlocks( Matrix, InitialNumberOfElements, - NumberOfFillinsExpected ) - -MatrixPtr Matrix; -int InitialNumberOfElements, NumberOfFillinsExpected; +InitializeElementBlocks(MatrixPtr Matrix, int InitialNumberOfElements, + int NumberOfFillinsExpected) { -ElementPtr pElement; + ElementPtr pElement; -/* Begin `InitializeElementBlocks'. */ + /* Begin `InitializeElementBlocks'. */ -/* Allocate block of MatrixElements for elements. */ + /* Allocate block of MatrixElements for elements. */ pElement = ALLOC(struct MatrixElement, InitialNumberOfElements); - RecordAllocation( Matrix, (char *)pElement ); + RecordAllocation( Matrix, (void *)pElement ); if (Matrix->Error == spNO_MEMORY) return; Matrix->ElementsRemaining = InitialNumberOfElements; Matrix->NextAvailElement = pElement; -/* Allocate an element list structure. */ + /* Allocate an element list structure. */ Matrix->FirstElementListNode = ALLOC(struct ElementListNodeStruct,1); - RecordAllocation( Matrix, (char *)Matrix->FirstElementListNode ); + RecordAllocation( Matrix, (void *)Matrix->FirstElementListNode ); if (Matrix->Error == spNO_MEMORY) return; Matrix->LastElementListNode = Matrix->FirstElementListNode; @@ -452,16 +422,16 @@ ElementPtr pElement; InitialNumberOfElements; Matrix->FirstElementListNode->Next = NULL; -/* Allocate block of MatrixElements for fill-ins. */ + /* Allocate block of MatrixElements for fill-ins. */ pElement = ALLOC(struct MatrixElement, NumberOfFillinsExpected); - RecordAllocation( Matrix, (char *)pElement ); + RecordAllocation( Matrix, (void *)pElement ); if (Matrix->Error == spNO_MEMORY) return; Matrix->FillinsRemaining = NumberOfFillinsExpected; Matrix->NextAvailFillin = pElement; -/* Allocate a fill-in list structure. */ + /* Allocate a fill-in list structure. */ Matrix->FirstFillinListNode = ALLOC(struct FillinListNodeStruct,1); - RecordAllocation( Matrix, (char *)Matrix->FirstFillinListNode ); + RecordAllocation( Matrix, (void *)Matrix->FirstFillinListNode ); if (Matrix->Error == spNO_MEMORY) return; Matrix->LastFillinListNode = Matrix->FirstFillinListNode; @@ -484,10 +454,10 @@ ElementPtr pElement; /* * FILL-IN ALLOCATION * - * This routine allocates space for matrix fill-ins. It requests large blocks - * of storage from the system and doles out individual elements as required. - * This technique, as opposed to allocating elements individually, tends to - * speed the allocation process. + * This routine allocates space for matrix fill-ins. It requests + * large blocks of storage from the system and doles out individual + * elements as required. This technique, as opposed to allocating + * elements individually, tends to speed the allocation process. * * >>> Returned: * A pointer to the fill-in. @@ -497,43 +467,38 @@ ElementPtr pElement; * Pointer to matrix. * * >>> Possible errors: - * spNO_MEMORY - */ + * spNO_MEMORY */ ElementPtr -spcGetFillin( Matrix ) - -MatrixPtr Matrix; +spcGetFillin(MatrixPtr Matrix) { -/* Begin `spcGetFillin'. */ + /* Begin `spcGetFillin'. */ -#if NOT STRIP OR LINT +#if !STRIP || LINT if (Matrix->FillinsRemaining == 0) return spcGetElement( Matrix ); #endif -#if STRIP OR LINT +#if STRIP || LINT - if (Matrix->FillinsRemaining == 0) - { pListNode = Matrix->LastFillinListNode; + if (Matrix->FillinsRemaining == 0) { + pListNode = Matrix->LastFillinListNode; -/* First see if there are any stripped fill-ins left. */ - if (pListNode->Next != NULL) - { Matrix->LastFillinListNode = pListNode = pListNode->Next; + /* First see if there are any stripped fill-ins left. */ + if (pListNode->Next != NULL) { + Matrix->LastFillinListNode = pListNode = pListNode->Next; Matrix->FillinsRemaining = pListNode->NumberOfFillinsInList; Matrix->NextAvailFillin = pListNode->pFillinList; - } - else - { -/* Allocate block of fill-ins. */ + } else { + /* Allocate block of fill-ins. */ pFillins = ALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION); - RecordAllocation( Matrix, (char *)pFillins ); + RecordAllocation( Matrix, (void *)pFillins ); if (Matrix->Error == spNO_MEMORY) return NULL; Matrix->FillinsRemaining = ELEMENTS_PER_ALLOCATION; Matrix->NextAvailFillin = pFillins; -/* Allocate a fill-in list structure. */ + /* Allocate a fill-in list structure. */ pListNode->Next = ALLOC(struct FillinListNodeStruct,1); - RecordAllocation( Matrix, (char *)pListNode->Next ); + RecordAllocation( Matrix, (void *)pListNode->Next ); if (Matrix->Error == spNO_MEMORY) return NULL; Matrix->LastFillinListNode = pListNode = pListNode->Next; @@ -544,7 +509,7 @@ MatrixPtr Matrix; } #endif -/* Update Fill-in counter and return pointer to Fill-in. */ + /* Update Fill-in counter and return pointer to Fill-in. */ Matrix->FillinsRemaining--; return Matrix->NextAvailFillin++; } @@ -560,50 +525,43 @@ MatrixPtr Matrix; /* * RECORD A MEMORY ALLOCATION * - * This routine is used to record all memory allocations so that the memory - * can be freed later. + * This routine is used to record all memory allocations so that the + * memory can be freed later. * * >>> Arguments: * Matrix (MatrixPtr) * Pointer to the matrix. - * AllocatedPtr (char *) - * The pointer returned by malloc or calloc. These pointers are saved in - * a list so that they can be easily freed. + * AllocatedPtr (void *) + * The pointer returned by tmalloc or calloc. These pointers are + * saved in a list so that they can be easily freed. * * >>> Possible errors: - * spNO_MEMORY - */ + * spNO_MEMORY */ static void -RecordAllocation( Matrix, AllocatedPtr ) - -MatrixPtr Matrix; -char *AllocatedPtr; +RecordAllocation(MatrixPtr Matrix, void *AllocatedPtr ) { -/* Begin `RecordAllocation'. */ -/* - * If Allocated pointer is NULL, assume that malloc returned a NULL pointer, - * which indicates a spNO_MEMORY error. - */ - if (AllocatedPtr == NULL) - { Matrix->Error = spNO_MEMORY; + /* Begin `RecordAllocation'. */ + /* If Allocated pointer is NULL, assume that tmalloc returned a + * NULL pointer, which indicates a spNO_MEMORY error. */ + if (AllocatedPtr == NULL) { + Matrix->Error = spNO_MEMORY; return; } -/* Allocate block of MatrixElements if necessary. */ - if (Matrix->RecordsRemaining == 0) - { AllocateBlockOfAllocationList( Matrix ); - if (Matrix->Error == spNO_MEMORY) - { FREE(AllocatedPtr); + /* Allocate block of MatrixElements if necessary. */ + if (Matrix->RecordsRemaining == 0) { + AllocateBlockOfAllocationList( Matrix ); + if (Matrix->Error == spNO_MEMORY) { + FREE(AllocatedPtr); return; } } -/* Add Allocated pointer to Allocation List. */ + /* Add Allocated pointer to Allocation List. */ (++Matrix->TopOfAllocationList)->AllocatedPtr = AllocatedPtr; Matrix->RecordsRemaining--; return; - } @@ -624,42 +582,41 @@ char *AllocatedPtr; * * >>> Local variables: * ListPtr (AllocationListPtr) - * Pointer to the list that contains the pointers to segments of memory - * that were allocated by the operating system for the current matrix. + * Pointer to the list that contains the pointers to segments of + * memory that were allocated by the operating system for the + * current matrix. * * >>> Possible errors: - * spNO_MEMORY - */ + * spNO_MEMORY */ static void -AllocateBlockOfAllocationList( Matrix ) - -MatrixPtr Matrix; +AllocateBlockOfAllocationList(MatrixPtr Matrix) { -register int I; -register AllocationListPtr ListPtr; + int I; + AllocationListPtr ListPtr; -/* Begin `AllocateBlockOfAllocationList'. */ -/* Allocate block of records for allocation list. */ + /* Begin `AllocateBlockOfAllocationList'. */ + /* Allocate block of records for allocation list. */ ListPtr = ALLOC(struct AllocationRecord, (ELEMENTS_PER_ALLOCATION+1)); - if (ListPtr == NULL) - { Matrix->Error = spNO_MEMORY; + if (ListPtr == NULL) { + Matrix->Error = spNO_MEMORY; return; } -/* String entries of allocation list into singly linked list. List is linked - such that any record points to the one before it. */ + /* String entries of allocation list into singly linked list. + List is linked such that any record points to the one before + it. */ ListPtr->NextRecord = Matrix->TopOfAllocationList; Matrix->TopOfAllocationList = ListPtr; ListPtr += ELEMENTS_PER_ALLOCATION; - for (I = ELEMENTS_PER_ALLOCATION; I > 0; I--) - { ListPtr->NextRecord = ListPtr - 1; - ListPtr--; + for (I = ELEMENTS_PER_ALLOCATION; I > 0; I--) { + ListPtr->NextRecord = ListPtr - 1; + ListPtr--; } -/* Record allocation of space for allocation list on allocation list. */ - Matrix->TopOfAllocationList->AllocatedPtr = (char *)ListPtr; + /* Record allocation of space for allocation list on allocation list. */ + Matrix->TopOfAllocationList->AllocatedPtr = (void *)ListPtr; Matrix->RecordsRemaining = ELEMENTS_PER_ALLOCATION; return; @@ -678,7 +635,7 @@ register AllocationListPtr ListPtr; * Deallocates pointers and elements of Matrix. * * >>> Arguments: - * Matrix (char *) + * Matrix (void *) * Pointer to the matrix frame which is to be removed from memory. * * >>> Local variables: @@ -693,18 +650,16 @@ register AllocationListPtr ListPtr; */ void -spDestroy( eMatrix ) - -register char *eMatrix; +spDestroy(void *eMatrix) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register AllocationListPtr ListPtr, NextListPtr; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + AllocationListPtr ListPtr, NextListPtr; -/* Begin `spDestroy'. */ - ASSERT( IS_SPARSE( Matrix ) ); + /* Begin `spDestroy'. */ + assert( IS_SPARSE( Matrix ) ); -/* Deallocate the vectors that are located in the matrix frame. */ + /* Deallocate the vectors that are located in the matrix frame. */ FREE( Matrix->IntToExtColMap ); FREE( Matrix->IntToExtRowMap ); FREE( Matrix->ExtToIntColMap ); @@ -719,17 +674,14 @@ register AllocationListPtr ListPtr, NextListPtr; FREE( Matrix->DoRealDirect ); FREE( Matrix->Intermediate ); -/* Sequentially step through the list of allocated pointers freeing pointers - * along the way. */ + /* Sequentially step through the list of allocated pointers + * freeing pointers along the way. */ ListPtr = Matrix->TopOfAllocationList; - while (ListPtr != NULL) - { NextListPtr = ListPtr->NextRecord; - if ((char *) ListPtr == ListPtr->AllocatedPtr) - { + while (ListPtr != NULL) { + NextListPtr = ListPtr->NextRecord; + if ((void *) ListPtr == ListPtr->AllocatedPtr) { FREE( ListPtr ); - } - else - { + } else { FREE( ListPtr->AllocatedPtr ); } ListPtr = NextListPtr; @@ -746,29 +698,27 @@ register AllocationListPtr ListPtr, NextListPtr; /* * RETURN MATRIX ERROR STATUS * - * This function is used to determine the error status of the given matrix. + * This function is used to determine the error status of the given + * matrix. * * >>> Returned: * The error status of the given matrix. * * >>> Arguments: - * eMatrix (char *) - * The matrix for which the error status is desired. - */ - + * eMatrix (void *) + * The matrix for which the error status is desired. */ int -spError( eMatrix ) - -char *eMatrix; +spError(void *eMatrix ) { -/* Begin `spError'. */ + /* Begin `spError'. */ - if (eMatrix != NULL) - { ASSERT(((MatrixPtr)eMatrix)->ID == SPARSE_ID); + if (eMatrix != NULL) { + assert(((MatrixPtr)eMatrix)->ID == SPARSE_ID); return ((MatrixPtr)eMatrix)->Error; + } else { + /* This error may actually be spPANIC, no way to tell. */ + return spNO_MEMORY; } - else return spNO_MEMORY; /* This error may actually be spPANIC, - * no way to tell. */ } @@ -786,7 +736,7 @@ char *eMatrix; * detected as singular or where a zero was detected on the diagonal. * * >>> Arguments: - * eMatrix (char *) + * eMatrix (void *) * The matrix for which the error status is desired. * pRow (int *) * The row number. @@ -795,18 +745,16 @@ char *eMatrix; */ void -spWhereSingular( eMatrix, pRow, pCol ) - -char *eMatrix; -int *pRow, *pCol; +spWhereSingular(void *eMatrix, int *pRow, int *pCol) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; + MatrixPtr Matrix = (MatrixPtr)eMatrix; -/* Begin `spWhereSingular'. */ - ASSERT( IS_SPARSE( Matrix ) ); + /* Begin `spWhereSingular'. */ + assert( IS_SPARSE( Matrix ) ); - if (Matrix->Error == spSINGULAR OR Matrix->Error == spZERO_DIAG) - { *pRow = Matrix->SingularRow; + if (Matrix->Error == spSINGULAR || Matrix->Error == spZERO_DIAG) + { + *pRow = Matrix->SingularRow; *pCol = Matrix->SingularCol; } else *pRow = *pCol = 0; @@ -825,9 +773,9 @@ MatrixPtr Matrix = (MatrixPtr)eMatrix; * the matrix is returned. * * >>> Arguments: - * eMatrix (char *) + * eMatrix (void *) * Pointer to matrix. - * External (BOOLEAN) + * External (int) * If External is set TRUE, the external size , i.e., the value of the * largest external row or column number encountered is returned. * Otherwise the TRUE size of the matrix is returned. These two sizes @@ -835,15 +783,12 @@ MatrixPtr Matrix = (MatrixPtr)eMatrix; */ int -spGetSize( eMatrix, External ) - -char *eMatrix; -BOOLEAN External; +spGetSize(void *eMatrix, int External) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; + MatrixPtr Matrix = (MatrixPtr)eMatrix; -/* Begin `spGetSize'. */ - ASSERT( IS_SPARSE( Matrix ) ); + /* Begin `spGetSize'. */ + assert( IS_SPARSE( Matrix ) ); #if TRANSLATE if (External) @@ -868,31 +813,27 @@ MatrixPtr Matrix = (MatrixPtr)eMatrix; * Forces matrix to be either real or complex. * * >>> Arguments: - * eMatrix (char *) + * eMatrix (void *) * Pointer to matrix. */ void -spSetReal( eMatrix ) - -char *eMatrix; +spSetReal(void *eMatrix) { -/* Begin `spSetReal'. */ + /* Begin `spSetReal'. */ - ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) AND REAL); + assert( IS_SPARSE( (MatrixPtr)eMatrix )); ((MatrixPtr)eMatrix)->Complex = NO; return; } void -spSetComplex( eMatrix ) - -char *eMatrix; +spSetComplex(void *eMatrix) { -/* Begin `spSetComplex'. */ + /* Begin `spSetComplex'. */ - ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) AND spCOMPLEX); + assert( IS_SPARSE( (MatrixPtr)eMatrix )); ((MatrixPtr)eMatrix)->Complex = YES; return; } @@ -913,40 +854,34 @@ char *eMatrix; * of original elements can be returned. * * >>> Arguments: - * eMatrix (char *) + * eMatrix (void *) * Pointer to matrix. */ int -spFillinCount( eMatrix ) - -char *eMatrix; +spFillinCount(void *eMatrix) { -/* Begin `spFillinCount'. */ + /* Begin `spFillinCount'. */ - ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) ); + assert( IS_SPARSE( (MatrixPtr)eMatrix ) ); return ((MatrixPtr)eMatrix)->Fillins; } int -spElementCount( eMatrix ) - -char *eMatrix; +spElementCount(void *eMatrix) { -/* Begin `spElementCount'. */ + /* Begin `spElementCount'. */ - ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) ); + assert( IS_SPARSE( (MatrixPtr)eMatrix ) ); return ((MatrixPtr)eMatrix)->Elements; } int -spOriginalCount( eMatrix ) - -char *eMatrix; +spOriginalCount(void *eMatrix) { -/* Begin `spOriginalCount'. */ + /* Begin `spOriginalCount'. */ - ASSERT( IS_SPARSE( (MatrixPtr)eMatrix ) ); + assert( IS_SPARSE( (MatrixPtr)eMatrix ) ); return ((MatrixPtr)eMatrix)->Originals; } diff --git a/src/maths/sparse/spbuild.c b/src/maths/sparse/spbuild.c index b4d404dc4..07d3e9c69 100644 --- a/src/maths/sparse/spbuild.c +++ b/src/maths/sparse/spbuild.c @@ -44,15 +44,6 @@ * or implied warranty. */ -#ifdef notdef -static char copyright[] = - "Sparse1.3: Copyright (c) 1985,86,87,88,89,90 by Kenneth S. Kundert"; -static char RCSid[] = - "@(#)$Header$"; -#endif - - - /* * IMPORTS @@ -65,6 +56,7 @@ static char RCSid[] = * spDefs.h * Matrix type and macro definitions for the sparse matrix routines. */ +#include #define spINSIDE_SPARSE #include "spconfig.h" @@ -78,17 +70,9 @@ static char RCSid[] = /* * Function declarations */ - -#ifdef __STDC__ static void Translate( MatrixPtr, int*, int* ); static void EnlargeMatrix( MatrixPtr, int ); static void ExpandTranslationArrays( MatrixPtr, int ); -#else /* __STDC__ */ -static void Translate(); -static void EnlargeMatrix(); -static void ExpandTranslationArrays(); -#endif /* __STDC__ */ - @@ -109,45 +93,45 @@ static void ExpandTranslationArrays(); */ void -spClear( eMatrix ) - -char *eMatrix; +spClear(void *eMatrix ) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register ElementPtr pElement; -register int I; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + ElementPtr pElement; + int I; -/* Begin `spClear'. */ - ASSERT( IS_SPARSE( Matrix ) ); + /* Begin `spClear'. */ + assert( IS_SPARSE( Matrix ) ); -/* Clear matrix. */ -#if spCOMPLEX - if (Matrix->PreviousMatrixWasComplex OR Matrix->Complex) - { for (I = Matrix->Size; I > 0; I--) - { pElement = Matrix->FirstInCol[I]; - while (pElement != NULL) - { pElement->Real = 0.0; - pElement->Imag = 0.0; - pElement = pElement->NextInCol; - } - } + /* Clear matrix. */ + if (Matrix->PreviousMatrixWasComplex || Matrix->Complex) + { + for (I = Matrix->Size; I > 0; I--) + { + pElement = Matrix->FirstInCol[I]; + while (pElement != NULL) + { + pElement->Real = 0.0; + pElement->Imag = 0.0; + pElement = pElement->NextInCol; + } + } } else -#endif - { for (I = Matrix->Size; I > 0; I--) - { pElement = Matrix->FirstInCol[I]; - while (pElement != NULL) - { pElement->Real = 0.0; - pElement = pElement->NextInCol; - } - } + { + for (I = Matrix->Size; I > 0; I--) + { + pElement = Matrix->FirstInCol[I]; + while (pElement != NULL) + { + pElement->Real = 0.0; + pElement = pElement->NextInCol; + } + } } -/* Empty the trash. */ + /* Empty the trash. */ Matrix->TrashCan.Real = 0.0; -#if spCOMPLEX Matrix->TrashCan.Imag = 0.0; -#endif Matrix->Error = spOKAY; Matrix->Factored = NO; @@ -203,24 +187,21 @@ register int I; */ RealNumber * -spGetElement( eMatrix, Row, Col ) - -char *eMatrix; -int Row, Col; +spGetElement(void *eMatrix, int Row, int Col) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -RealNumber *pElement; -ElementPtr spcFindElementInCol(); -void Translate(); + MatrixPtr Matrix = (MatrixPtr)eMatrix; + RealNumber *pElement; + ElementPtr spcFindElementInCol(); + void Translate(); -/* Begin `spGetElement'. */ - ASSERT( IS_SPARSE( Matrix ) AND Row >= 0 AND Col >= 0 ); + /* Begin `spGetElement'. */ + assert( IS_SPARSE( Matrix ) && Row >= 0 && Col >= 0 ); - if ((Row == 0) OR (Col == 0)) - return &Matrix->TrashCan.Real; + if ((Row == 0) || (Col == 0)) + return &Matrix->TrashCan.Real; -#if NOT TRANSLATE - ASSERT(Matrix->NeedsOrdering); +#if !TRANSLATE + assert(Matrix->NeedsOrdering); #endif #if TRANSLATE @@ -228,40 +209,38 @@ void Translate(); if (Matrix->Error == spNO_MEMORY) return NULL; #endif -#if NOT TRANSLATE -#if NOT EXPANDABLE - ASSERT(Row <= Matrix->Size AND Col <= Matrix->Size); +#if !TRANSLATE +#if !EXPANDABLE + assert(Row <= Matrix->Size && Col <= Matrix->Size); #endif #if EXPANDABLE -/* Re-size Matrix if necessary. */ - if ((Row > Matrix->Size) OR (Col > Matrix->Size)) - EnlargeMatrix( Matrix, MAX(Row, Col) ); + /* Re-size Matrix if necessary. */ + if ((Row > Matrix->Size) || (Col > Matrix->Size)) + EnlargeMatrix( Matrix, MAX(Row, Col) ); if (Matrix->Error == spNO_MEMORY) return NULL; #endif #endif -/* - * The condition part of the following if statement tests to see if the - * element resides along the diagonal, if it does then it tests to see - * if the element has been created yet (Diag pointer not NULL). The - * pointer to the element is then assigned to Element after it is cast - * into a pointer to a RealNumber. This casting makes the pointer into - * a pointer to Real. This statement depends on the fact that Real - * is the first record in the MatrixElement structure. - */ + /* The condition part of the following if statement tests to see + * if the element resides along the diagonal, if it does then it + * tests to see if the element has been created yet (Diag pointer + * not NULL). The pointer to the element is then assigned to + * Element after it is cast into a pointer to a RealNumber. This + * casting makes the pointer into a pointer to Real. This + * statement depends on the fact that Real is the first record in + * the MatrixElement structure. */ - if ((Row != Col) OR ((pElement = (RealNumber *)Matrix->Diag[Row]) == NULL)) + if ((Row != Col) || ((pElement = (RealNumber *)Matrix->Diag[Row]) == NULL)) { -/* - * Element does not exist or does not reside along diagonal. Search - * column for element. As in the if statement above, the pointer to the - * element which is returned by spcFindElementInCol is cast into a - * pointer to Real, a RealNumber. - */ - pElement = (RealNumber*)spcFindElementInCol( Matrix, - &(Matrix->FirstInCol[Col]), - Row, Col, YES ); + /* Element does not exist or does not reside along diagonal. + * Search column for element. As in the if statement above, + * the pointer to the element which is returned by + * spcFindElementInCol is cast into a pointer to Real, a + * RealNumber. */ + pElement = (RealNumber*)spcFindElementInCol( Matrix, + &(Matrix->FirstInCol[Col]), + Row, Col, YES ); } return pElement; } @@ -299,7 +278,7 @@ void Translate(); * Row being searched for. * Col (int) * Column being searched. - * CreateIfMissing (BOOLEAN) + * CreateIfMissing (int) * Indicates what to do if element is not found, create one or return a * NULL pointer. * @@ -309,40 +288,37 @@ void Translate(); */ ElementPtr -spcFindElementInCol( Matrix, LastAddr, Row, Col, CreateIfMissing ) - -MatrixPtr Matrix; -register ElementPtr *LastAddr; -register int Row; -int Col; -BOOLEAN CreateIfMissing; +spcFindElementInCol(MatrixPtr Matrix, ElementPtr *LastAddr, + int Row, int Col, int CreateIfMissing) { -register ElementPtr pElement; -ElementPtr spcCreateElement(); + ElementPtr pElement; + ElementPtr spcCreateElement(); -/* Begin `spcFindElementInCol'. */ + /* Begin `spcFindElementInCol'. */ pElement = *LastAddr; -/* Search for element. */ + /* Search for element. */ while (pElement != NULL) - { if (pElement->Row < Row) + { + if (pElement->Row < Row) { -/* Have not reached element yet. */ - LastAddr = &(pElement->NextInCol); - pElement = pElement->NextInCol; + /* Have not reached element yet. */ + LastAddr = &(pElement->NextInCol); + pElement = pElement->NextInCol; } - else if (pElement->Row == Row) + else if (pElement->Row == Row) { -/* Reached element. */ - return pElement; + /* Reached element. */ + return pElement; } - else break; /* while loop */ + else break; /* while loop */ } -/* Element does not exist and must be created. */ + /* Element does not exist and must be created. */ if (CreateIfMissing) - return spcCreateElement( Matrix, Row, Col, LastAddr, NO ); - else return NULL; + return spcCreateElement( Matrix, Row, Col, LastAddr, NO ); + else + return NULL; } @@ -387,41 +363,39 @@ ElementPtr spcCreateElement(); */ static void -Translate( Matrix, Row, Col ) - -MatrixPtr Matrix; -int *Row, *Col; +Translate(MatrixPtr Matrix, int *Row, int *Col) { -register int IntRow, IntCol, ExtRow, ExtCol; + int IntRow, IntCol, ExtRow, ExtCol; -/* Begin `Translate'. */ + /* Begin `Translate'. */ ExtRow = *Row; ExtCol = *Col; -/* Expand translation arrays if necessary. */ - if ((ExtRow > Matrix->AllocatedExtSize) OR + /* Expand translation arrays if necessary. */ + if ((ExtRow > Matrix->AllocatedExtSize) || (ExtCol > Matrix->AllocatedExtSize)) { ExpandTranslationArrays( Matrix, MAX(ExtRow, ExtCol) ); if (Matrix->Error == spNO_MEMORY) return; } -/* Set ExtSize if necessary. */ - if ((ExtRow > Matrix->ExtSize) OR (ExtCol > Matrix->ExtSize)) + /* Set ExtSize if necessary. */ + if ((ExtRow > Matrix->ExtSize) || (ExtCol > Matrix->ExtSize)) Matrix->ExtSize = MAX(ExtRow, ExtCol); -/* Translate external row or node number to internal row or node number. */ + /* Translate external row or node number to internal row or node number. */ if ((IntRow = Matrix->ExtToIntRowMap[ExtRow]) == -1) - { Matrix->ExtToIntRowMap[ExtRow] = ++Matrix->CurrentSize; + { + Matrix->ExtToIntRowMap[ExtRow] = ++Matrix->CurrentSize; Matrix->ExtToIntColMap[ExtRow] = Matrix->CurrentSize; IntRow = Matrix->CurrentSize; -#if NOT EXPANDABLE - ASSERT(IntRow <= Matrix->Size); +#if !EXPANDABLE + assert(IntRow <= Matrix->Size); #endif #if EXPANDABLE -/* Re-size Matrix if necessary. */ + /* Re-size Matrix if necessary. */ if (IntRow > Matrix->Size) EnlargeMatrix( Matrix, IntRow ); if (Matrix->Error == spNO_MEMORY) return; @@ -431,18 +405,19 @@ register int IntRow, IntCol, ExtRow, ExtCol; Matrix->IntToExtColMap[IntRow] = ExtRow; } -/* Translate external column or node number to internal column or node number.*/ + /* Translate external column or node number to internal column or node number.*/ if ((IntCol = Matrix->ExtToIntColMap[ExtCol]) == -1) - { Matrix->ExtToIntRowMap[ExtCol] = ++Matrix->CurrentSize; + { + Matrix->ExtToIntRowMap[ExtCol] = ++Matrix->CurrentSize; Matrix->ExtToIntColMap[ExtCol] = Matrix->CurrentSize; IntCol = Matrix->CurrentSize; -#if NOT EXPANDABLE - ASSERT(IntCol <= Matrix->Size); +#if !EXPANDABLE + assert(IntCol <= Matrix->Size); #endif #if EXPANDABLE -/* Re-size Matrix if necessary. */ + /* Re-size Matrix if necessary. */ if (IntCol > Matrix->Size) EnlargeMatrix( Matrix, IntCol ); if (Matrix->Error == spNO_MEMORY) return; @@ -499,24 +474,19 @@ register int IntRow, IntCol, ExtRow, ExtCol; */ int -spGetAdmittance( Matrix, Node1, Node2, Template ) - -char *Matrix; -int Node1, Node2; -struct spTemplate *Template; +spGetAdmittance(void *Matrix, int Node1, int Node2, + struct spTemplate *Template) { - -/* Begin `spGetAdmittance'. */ + /* Begin `spGetAdmittance'. */ Template->Element1 = spGetElement(Matrix, Node1, Node1 ); Template->Element2 = spGetElement(Matrix, Node2, Node2 ); Template->Element3Negated = spGetElement( Matrix, Node2, Node1 ); Template->Element4Negated = spGetElement( Matrix, Node1, Node2 ); - if - ( (Template->Element1 == NULL) - OR (Template->Element2 == NULL) - OR (Template->Element3Negated == NULL) - OR (Template->Element4Negated == NULL) - ) return spNO_MEMORY; + if ((Template->Element1 == NULL) || + (Template->Element2 == NULL) || + (Template->Element3Negated == NULL) || + (Template->Element4Negated == NULL)) + return spNO_MEMORY; if (Node1 == 0) SWAP( RealNumber*, Template->Element1, Template->Element2 ); @@ -587,23 +557,19 @@ struct spTemplate *Template; */ int -spGetQuad( Matrix, Row1, Row2, Col1, Col2, Template ) - -char *Matrix; -int Row1, Row2, Col1, Col2; -struct spTemplate *Template; +spGetQuad(void *Matrix, int Row1, int Row2, int Col1, int Col2, + struct spTemplate *Template) { -/* Begin `spGetQuad'. */ + /* Begin `spGetQuad'. */ Template->Element1 = spGetElement( Matrix, Row1, Col1); Template->Element2 = spGetElement( Matrix, Row2, Col2 ); Template->Element3Negated = spGetElement( Matrix, Row2, Col1 ); Template->Element4Negated = spGetElement( Matrix, Row1, Col2 ); - if - ( (Template->Element1 == NULL) - OR (Template->Element2 == NULL) - OR (Template->Element3Negated == NULL) - OR (Template->Element4Negated == NULL) - ) return spNO_MEMORY; + if ((Template->Element1 == NULL) || + (Template->Element2 == NULL) || + (Template->Element3Negated == NULL) || + (Template->Element4Negated == NULL)) + return spNO_MEMORY; if (Template->Element1 == &((MatrixPtr)Matrix)->TrashCan.Real) SWAP( RealNumber *, Template->Element1, Template->Element2 ); @@ -662,23 +628,19 @@ struct spTemplate *Template; */ int -spGetOnes(Matrix, Pos, Neg, Eqn, Template) - -char *Matrix; -int Pos, Neg, Eqn; -struct spTemplate *Template; +spGetOnes(void *Matrix, int Pos, int Neg, int Eqn, + struct spTemplate *Template) { -/* Begin `spGetOnes'. */ + /* Begin `spGetOnes'. */ Template->Element4Negated = spGetElement( Matrix, Neg, Eqn ); Template->Element3Negated = spGetElement( Matrix, Eqn, Neg ); Template->Element2 = spGetElement( Matrix, Pos, Eqn ); Template->Element1 = spGetElement( Matrix, Eqn, Pos ); - if - ( (Template->Element1 == NULL) - OR (Template->Element2 == NULL) - OR (Template->Element3Negated == NULL) - OR (Template->Element4Negated == NULL) - ) return spNO_MEMORY; + if ((Template->Element1 == NULL) || + (Template->Element2 == NULL) || + (Template->Element3Negated == NULL) || + (Template->Element4Negated == NULL)) + return spNO_MEMORY; spADD_REAL_QUAD( *Template, 1.0 ); return spOKAY; @@ -712,7 +674,7 @@ struct spTemplate *Template; * This contains the address of the pointer to the element just above the * one being created. It is used to speed the search and it is updated with * address of the created element. - * Fillin (BOOLEAN) + * Fillin (int) * Flag that indicates if created element is to be a fill-in. * * >>> Local variables: @@ -732,78 +694,73 @@ struct spTemplate *Template; */ ElementPtr -spcCreateElement( Matrix, Row, Col, LastAddr, Fillin ) - -MatrixPtr Matrix; -int Row; -register int Col; -register ElementPtr *LastAddr; -BOOLEAN Fillin; +spcCreateElement(MatrixPtr Matrix, int Row, int Col, + ElementPtr *LastAddr, int Fillin) { -register ElementPtr pElement, pLastElement; -ElementPtr pCreatedElement, spcGetElement(), spcGetFillin(); + ElementPtr pElement, pLastElement; + ElementPtr pCreatedElement, spcGetElement(), spcGetFillin(); -/* Begin `spcCreateElement'. */ + /* Begin `spcCreateElement'. */ if (Matrix->RowsLinked) { -/* Row pointers cannot be ignored. */ + /* Row pointers cannot be ignored. */ if (Fillin) - { pElement = spcGetFillin( Matrix ); + { + pElement = spcGetFillin( Matrix ); Matrix->Fillins++; } else - { pElement = spcGetElement( Matrix ); + { + pElement = spcGetElement( Matrix ); Matrix->Originals++; Matrix->NeedsOrdering = YES; } if (pElement == NULL) return NULL; -/* If element is on diagonal, store pointer in Diag. */ + /* If element is on diagonal, store pointer in Diag. */ if (Row == Col) Matrix->Diag[Row] = pElement; -/* Initialize Element. */ + /* Initialize Element. */ pCreatedElement = pElement; pElement->Row = Row; pElement->Col = Col; pElement->Real = 0.0; -#if spCOMPLEX pElement->Imag = 0.0; -#endif #if INITIALIZE pElement->pInitInfo = NULL; #endif -/* Splice element into column. */ + /* Splice element into column. */ pElement->NextInCol = *LastAddr; *LastAddr = pElement; - /* Search row for proper element position. */ + /* Search row for proper element position. */ pElement = Matrix->FirstInRow[Row]; pLastElement = NULL; while (pElement != NULL) { -/* Search for element row position. */ + /* Search for element row position. */ if (pElement->Col < Col) { -/* Have not reached desired element. */ + /* Have not reached desired element. */ pLastElement = pElement; pElement = pElement->NextInRow; } else pElement = NULL; } -/* Splice element into row. */ + /* Splice element into row. */ pElement = pCreatedElement; if (pLastElement == NULL) { -/* Element is first in row. */ + /* Element is first in row. */ pElement->NextInRow = Matrix->FirstInRow[Row]; Matrix->FirstInRow[Row] = pElement; } else -/* Element is not first in row. */ { + /* Element is not first in row. */ pElement->NextInRow = pLastElement->NextInRow; pLastElement->NextInRow = pElement; } @@ -811,34 +768,30 @@ ElementPtr pCreatedElement, spcGetElement(), spcGetFillin(); } else { -/* - * Matrix has not been factored yet. Thus get element rather than fill-in. - * Also, row pointers can be ignored. - */ + /* Matrix has not been factored yet. Thus get element rather + * than fill-in. Also, row pointers can be ignored. */ -/* Allocate memory for Element. */ + /* Allocate memory for Element. */ pElement = spcGetElement( Matrix ); Matrix->Originals++; if (pElement == NULL) return NULL; -/* If element is on diagonal, store pointer in Diag. */ + /* If element is on diagonal, store pointer in Diag. */ if (Row == Col) Matrix->Diag[Row] = pElement; -/* Initialize Element. */ + /* Initialize Element. */ pCreatedElement = pElement; pElement->Row = Row; #if DEBUG pElement->Col = Col; #endif pElement->Real = 0.0; -#if spCOMPLEX pElement->Imag = 0.0; -#endif #if INITIALIZE pElement->pInitInfo = NULL; #endif -/* Splice element into column. */ + /* Splice element into column. */ pElement->NextInCol = *LastAddr; *LastAddr = pElement; } @@ -874,30 +827,29 @@ ElementPtr pCreatedElement, spcGetElement(), spcGetFillin(); * currently being operated upon. * FirstInRowArray (ArrayOfElementPtrs) * A pointer to the FirstInRow array. Same as Matrix->FirstInRow but - * resides in a register and requires less indirection so is faster to + * resides in a and requires less indirection so is faster to * use. * Col (int) * Column currently being operated upon. */ void -spcLinkRows( Matrix ) - -MatrixPtr Matrix; +spcLinkRows(MatrixPtr Matrix) { -register ElementPtr pElement, *FirstInRowEntry; -register ArrayOfElementPtrs FirstInRowArray; -register int Col; + ElementPtr pElement, *FirstInRowEntry; + ArrayOfElementPtrs FirstInRowArray; + int Col; -/* Begin `spcLinkRows'. */ + /* Begin `spcLinkRows'. */ FirstInRowArray = Matrix->FirstInRow; for (Col = Matrix->Size; Col >= 1; Col--) { -/* Generate row links for the elements in the Col'th column. */ + /* Generate row links for the elements in the Col'th column. */ pElement = Matrix->FirstInCol[Col]; while (pElement != NULL) - { pElement->Col = Col; + { + pElement->Col = Col; FirstInRowEntry = &FirstInRowArray[pElement->Row]; pElement->NextInRow = *FirstInRowEntry; *FirstInRowEntry = pElement; @@ -932,48 +884,48 @@ register int Col; */ static void -EnlargeMatrix( Matrix, NewSize ) - -MatrixPtr Matrix; -register int NewSize; +EnlargeMatrix(MatrixPtr Matrix, int NewSize) { -register int I, OldAllocatedSize = Matrix->AllocatedSize; + int I, OldAllocatedSize = Matrix->AllocatedSize; -/* Begin `EnlargeMatrix'. */ + /* Begin `EnlargeMatrix'. */ Matrix->Size = NewSize; if (NewSize <= OldAllocatedSize) return; -/* Expand the matrix frame. */ + /* Expand the matrix frame. */ NewSize = MAX( NewSize, EXPANSION_FACTOR * OldAllocatedSize ); Matrix->AllocatedSize = NewSize; if (( REALLOC(Matrix->IntToExtColMap, int, NewSize+1)) == NULL) - { Matrix->Error = spNO_MEMORY; + { + Matrix->Error = spNO_MEMORY; return; } if (( REALLOC(Matrix->IntToExtRowMap, int, NewSize+1)) == NULL) - { Matrix->Error = spNO_MEMORY; + { + Matrix->Error = spNO_MEMORY; return; } if (( REALLOC(Matrix->Diag, ElementPtr, NewSize+1)) == NULL) - { Matrix->Error = spNO_MEMORY; + { + Matrix->Error = spNO_MEMORY; return; } if (( REALLOC(Matrix->FirstInCol, ElementPtr, NewSize+1)) == NULL) - { Matrix->Error = spNO_MEMORY; + { + Matrix->Error = spNO_MEMORY; return; } if (( REALLOC(Matrix->FirstInRow, ElementPtr, NewSize+1)) == NULL) - { Matrix->Error = spNO_MEMORY; + { + Matrix->Error = spNO_MEMORY; return; } -/* - * Destroy the Markowitz and Intermediate vectors, they will be recreated - * in spOrderAndFactor(). - */ + /* Destroy the Markowitz and Intermediate vectors, they will be + * recreated in spOrderAndFactor(). */ FREE( Matrix->MarkowitzRow ); FREE( Matrix->MarkowitzCol ); FREE( Matrix->MarkowitzProd ); @@ -982,9 +934,10 @@ register int I, OldAllocatedSize = Matrix->AllocatedSize; FREE( Matrix->Intermediate ); Matrix->InternalVectorsAllocated = NO; -/* Initialize the new portion of the vectors. */ + /* Initialize the new portion of the vectors. */ for (I = OldAllocatedSize+1; I <= NewSize; I++) - { Matrix->IntToExtColMap[I] = I; + { + Matrix->IntToExtColMap[I] = I; Matrix->IntToExtRowMap[I] = I; Matrix->Diag[I] = NULL; Matrix->FirstInRow[I] = NULL; @@ -1021,35 +974,35 @@ register int I, OldAllocatedSize = Matrix->AllocatedSize; */ static void -ExpandTranslationArrays( Matrix, NewSize ) - -MatrixPtr Matrix; -register int NewSize; +ExpandTranslationArrays(MatrixPtr Matrix, int NewSize) { -register int I, OldAllocatedSize = Matrix->AllocatedExtSize; + int I, OldAllocatedSize = Matrix->AllocatedExtSize; -/* Begin `ExpandTranslationArrays'. */ + /* Begin `ExpandTranslationArrays'. */ Matrix->ExtSize = NewSize; if (NewSize <= OldAllocatedSize) return; -/* Expand the translation arrays ExtToIntRowMap and ExtToIntColMap. */ + /* Expand the translation arrays ExtToIntRowMap and ExtToIntColMap. */ NewSize = MAX( NewSize, EXPANSION_FACTOR * OldAllocatedSize ); Matrix->AllocatedExtSize = NewSize; if (( REALLOC(Matrix->ExtToIntRowMap, int, NewSize+1)) == NULL) - { Matrix->Error = spNO_MEMORY; + { + Matrix->Error = spNO_MEMORY; return; } if (( REALLOC(Matrix->ExtToIntColMap, int, NewSize+1)) == NULL) - { Matrix->Error = spNO_MEMORY; + { + Matrix->Error = spNO_MEMORY; return; } -/* Initialize the new portion of the vectors. */ + /* Initialize the new portion of the vectors. */ for (I = OldAllocatedSize+1; I <= NewSize; I++) - { Matrix->ExtToIntRowMap[I] = -1; + { + Matrix->ExtToIntRowMap[I] = -1; Matrix->ExtToIntColMap[I] = -1; } @@ -1099,72 +1052,68 @@ register int I, OldAllocatedSize = Matrix->AllocatedExtSize; */ void -spInstallInitInfo( pElement, pInitInfo ) - -RealNumber *pElement; -char *pInitInfo; +spInstallInitInfo(RealNumber *pElement, char *pInitInfo) { -/* Begin `spInstallInitInfo'. */ - ASSERT(pElement != NULL); + /* Begin `spInstallInitInfo'. */ + assert(pElement != NULL); ((ElementPtr)pElement)->pInitInfo = pInitInfo; } char * -spGetInitInfo( pElement ) - -RealNumber *pElement; +spGetInitInfo(RealNumber *pElement) { -/* Begin `spGetInitInfo'. */ - ASSERT(pElement != NULL); + /* Begin `spGetInitInfo'. */ + assert(pElement != NULL); return (char *)((ElementPtr)pElement)->pInitInfo; } int -spInitialize( eMatrix, pInit ) - -char *eMatrix; -int (*pInit)(); +spInitialize(void *eMatrix, int (*pInit)()) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register ElementPtr pElement; -int J, Error, Col; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + ElementPtr pElement; + int J, Error, Col; -/* Begin `spInitialize'. */ - ASSERT( IS_SPARSE( Matrix ) ); + /* Begin `spInitialize'. */ + assert( IS_SPARSE( Matrix ) ); -#if spCOMPLEX -/* Clear imaginary part of matrix if matrix is real but was complex. */ - if (Matrix->PreviousMatrixWasComplex AND NOT Matrix->Complex) - { for (J = Matrix->Size; J > 0; J--) - { pElement = Matrix->FirstInCol[J]; + /* Clear imaginary part of matrix if matrix is real but was complex. */ + if (Matrix->PreviousMatrixWasComplex && !Matrix->Complex) + { + for (J = Matrix->Size; J > 0; J--) + { + pElement = Matrix->FirstInCol[J]; while (pElement != NULL) - { pElement->Imag = 0.0; + { + pElement->Imag = 0.0; pElement = pElement->NextInCol; } } } -#endif /* spCOMPLEX */ -/* Initialize the matrix. */ + /* Initialize the matrix. */ for (J = Matrix->Size; J > 0; J--) - { pElement = Matrix->FirstInCol[J]; + { + pElement = Matrix->FirstInCol[J]; Col = Matrix->IntToExtColMap[J]; while (pElement != NULL) - { if (pElement->pInitInfo == NULL) - { pElement->Real = 0.0; -# if spCOMPLEX - pElement->Imag = 0.0; -# endif + { + if (pElement->pInitInfo == NULL) + { + pElement->Real = 0.0; + pElement->Imag = 0.0; } else - { Error = (*pInit)((RealNumber *)pElement, pElement->pInitInfo, + { + Error = (*pInit)((RealNumber *)pElement, pElement->pInitInfo, Matrix->IntToExtRowMap[pElement->Row], Col); if (Error) - { Matrix->Error = spFATAL; + { + Matrix->Error = spFATAL; return Error; } @@ -1173,11 +1122,9 @@ int J, Error, Col; } } -/* Empty the trash. */ + /* Empty the trash. */ Matrix->TrashCan.Real = 0.0; -#if spCOMPLEX Matrix->TrashCan.Imag = 0.0; -#endif Matrix->Error = spOKAY; Matrix->Factored = NO; diff --git a/src/maths/sparse/spcombin.c b/src/maths/sparse/spcombin.c index d262520b1..9679509ee 100644 --- a/src/maths/sparse/spcombin.c +++ b/src/maths/sparse/spcombin.c @@ -30,15 +30,6 @@ * or implied warranty. */ -#ifdef notdef -static char copyright[] = - "Sparse1.3: Copyright (c) 1985,86,87,88,89,90 by Kenneth S. Kundert"; -static char RCSid[] = - "@(#)$Header$"; -#endif - - - /* * IMPORTS * @@ -67,20 +58,10 @@ static char RCSid[] = #if COMBINE -#ifdef __STDC__ -#if spSEPARATED_COMPLEX_VECTORS static void CombineComplexMatrix( MatrixPtr, RealVector, RealVector, RealVector, RealVector ); -#else -static void CombineComplexMatrix( MatrixPtr, RealVector, RealVector ); -#endif static void ClearBuffer( MatrixPtr, int, int, ElementPtr ); static void ClearComplexBuffer( MatrixPtr, int, int, ElementPtr ); -#else /* __STDC__ */ -static void CombineComplexMatrix(); -static void ClearBuffer(); -static void ClearComplexBuffer(); -#endif /* __STDC__ */ /* * COMBINE MATRICES ON A MULTIPROCESSOR @@ -100,10 +81,10 @@ static void ClearComplexBuffer(); static double Buffer[SPBSIZE]; void -spCombine( eMatrix, RHS, Spare IMAG_VECTORS ) +spCombine( eMatrix, RHS, Spare, iRHS, iSolution ) char *eMatrix; -RealVector RHS, Spare IMAG_VECTORS; +RealVector RHS, Spare, iRHS, iSolution; { MatrixPtr Matrix = (MatrixPtr)eMatrix; register ElementPtr pElement; @@ -114,18 +95,15 @@ struct ElementListNodeStruct *pListNode; long type = MT_COMBINE, length = Matrix->Size + 1; /* Begin `spCombine'. */ - ASSERT( IS_VALID(Matrix) AND NOT Matrix->Factored ); - if (NOT Matrix->InternalVectorsAllocated) + assert( IS_VALID(Matrix) && !Matrix->Factored ); + if (!Matrix->InternalVectorsAllocated) spcCreateInternalVectors( Matrix ); -#if spCOMPLEX if (Matrix->Complex) { - CombineComplexMatrix( Matrix, RHS, Spare IMAG_VECTORS ); + CombineComplexMatrix( Matrix, RHS, Spare, iRHS, iSolution ); return; } -#endif -#if REAL Size = Matrix->Size; /* Mark original non-zeroes. */ @@ -176,15 +154,14 @@ long type = MT_COMBINE, length = Matrix->Size + 1; DGOP_( &type, RHS, &length, "+" ); return; -#endif /* REAL */ } -#if spCOMPLEX + static void -CombineComplexMatrix( Matrix, RHS, Spare IMAG_VECTORS ) +CombineComplexMatrix( Matrix, RHS, Spare, iRHS, iSolution ) MatrixPtr Matrix; -RealVector RHS, Spare IMAG_VECTORS; +RealVector RHS, Spare, iRHS, iSolution; { register ElementPtr pElement; register int I, Size; @@ -194,7 +171,7 @@ struct ElementListNodeStruct *pListNode; long type = MT_COMBINE, length = Matrix->Size + 1; /* Begin `CombineComplexMatrix'. */ - ASSERT(Matrix->Complex); + assert(Matrix->Complex); Size = Matrix->Size; /* Mark original non-zeroes. */ @@ -244,19 +221,13 @@ long type = MT_COMBINE, length = Matrix->Size + 1; } /* Sum all RHS's together */ -#if spSEPARATED_COMPLEX_VECTORS DGOP_( &type, RHS, &length, "+" ); DGOP_( &type, iRHS, &length, "+" ); -#else - length *= 2; - DGOP_( &type, RHS, &length, "+" ); -#endif return; } -#endif /* spCOMPLEX */ -#if REAL + static void ClearBuffer( Matrix, NumElems, StartCol, StartElement ) @@ -290,9 +261,8 @@ ElementPtr StartElement; pElement = pElement->NextInCol; } } -#endif REAL -#if spCOMPLEX + static void ClearComplexBuffer( Matrix, DataCount, StartCol, StartElement ) @@ -327,5 +297,4 @@ ElementPtr StartElement; pElement = pElement->NextInCol; } } -#endif /* spCOMPLEX */ #endif /* COMBINE */ diff --git a/src/maths/sparse/spdefs.h b/src/maths/sparse/spdefs.h index faefba48a..0e11ab5ba 100644 --- a/src/maths/sparse/spdefs.h +++ b/src/maths/sparse/spdefs.h @@ -1,3 +1,5 @@ +#ifndef _SPDEFS_H +#define _SPDEFS_H /* * DATA STRUCTURE AND MACRO DEFINITIONS for Sparse. * @@ -36,96 +38,29 @@ * IMPORTS */ +#include #include -#include "ngspice.h" #undef ABORT #undef MALLOC #undef FREE #undef REALLOC -/* - * If running lint, change some of the compiler options to get a more - * complete inspection. - */ - -#ifdef lint -#undef REAL -#undef spCOMPLEX -#undef EXPANDABLE -#undef TRANSLATE -#undef INITIALIZE -#undef DELETE -#undef STRIP -#undef MODIFIED_NODAL -#undef QUAD_ELEMENT -#undef TRANSPOSE -#undef SCALING -#undef DOCUMENTATION -#undef MULTIPLICATION -#undef DETERMINANT -#undef CONDITION -#undef PSEUDOCONDITION -#undef FORTRAN -#undef DEBUG -#undef spCOMPATIBILITY - - - -#define REAL YES -#define spCOMPLEX YES -#define EXPANDABLE YES -#define TRANSLATE YES -#define INITIALIZE YES -#define DELETE YES -#define STRIP YES -#define MODIFIED_NODAL YES -#define QUAD_ELEMENT YES -#define TRANSPOSE YES -#define SCALING YES -#define DOCUMENTATION YES -#define MULTIPLICATION YES -#define DETERMINANT YES -#define CONDITION YES -#define PSEUDOCONDITION YES -#define FORTRAN YES -#define DEBUG YES -#define spCOMPATIBILITY YES - -#define LINT YES -#else /* not lint */ -#define LINT NO -#endif /* not lint */ - - - - - /* * MACRO DEFINITIONS * * Macros are distinguished by using solely capital letters in their - * identifiers. This contrasts with C defined identifiers which are strictly - * lower case, and program variable and procedure names which use both upper - * and lower case. - */ + * identifiers. This contrasts with C defined identifiers which are + * strictly lower case, and program variable and procedure names + * which use both upper and lower case. */ /* Begin macros. */ -/* Boolean data type */ -#define BOOLEAN int #define NO 0 #define YES 1 -#define NOT ! -#define AND && -#define OR || -/* NULL pointer */ -#ifndef NULL -#define NULL 0 -#endif #define SPARSE_ID 0x772773 /* Arbitrary (is Sparse on phone). */ #define IS_SPARSE(matrix) ((matrix) != NULL && \ @@ -151,11 +86,7 @@ #define SWAP(type, a, b) {type swapx; swapx = a; a = b; b = swapx;} /* Macro function that returns the approx absolute value of a complex number. */ -#if spCOMPLEX #define ELEMENT_MAG(ptr) (ABS((ptr)->Real) + ABS((ptr)->Imag)) -#else -#define ELEMENT_MAG(ptr) ((ptr)->Real < 0.0 ? -(ptr)->Real : (ptr)->Real) -#endif /* Complex assignment statements. */ #define CMPLX_ASSIGN(to,from) \ @@ -317,114 +248,6 @@ (from_a).Imag * (from_b).Real; \ } -/* - * Macro functions that provide complex division. - */ - -/* Complex division: to = num / den */ -#define CMPLX_DIV(to,num,den) \ -{ RealNumber r_, s_; \ - if (((den).Real >= (den).Imag AND (den).Real > -(den).Imag) OR \ - ((den).Real < (den).Imag AND (den).Real <= -(den).Imag)) \ - { r_ = (den).Imag / (den).Real; \ - s_ = (den).Real + r_*(den).Imag; \ - (to).Real = ((num).Real + r_*(num).Imag)/s_; \ - (to).Imag = ((num).Imag - r_*(num).Real)/s_; \ - } \ - else \ - { r_ = (den).Real / (den).Imag; \ - s_ = (den).Imag + r_*(den).Real; \ - (to).Real = (r_*(num).Real + (num).Imag)/s_; \ - (to).Imag = (r_*(num).Imag - (num).Real)/s_; \ - } \ -} - -/* Complex division and assignment: num /= den */ -#define CMPLX_DIV_ASSIGN(num,den) \ -{ RealNumber r_, s_, t_; \ - if (((den).Real >= (den).Imag AND (den).Real > -(den).Imag) OR \ - ((den).Real < (den).Imag AND (den).Real <= -(den).Imag)) \ - { r_ = (den).Imag / (den).Real; \ - s_ = (den).Real + r_*(den).Imag; \ - t_ = ((num).Real + r_*(num).Imag)/s_; \ - (num).Imag = ((num).Imag - r_*(num).Real)/s_; \ - (num).Real = t_; \ - } \ - else \ - { r_ = (den).Real / (den).Imag; \ - s_ = (den).Imag + r_*(den).Real; \ - t_ = (r_*(num).Real + (num).Imag)/s_; \ - (num).Imag = (r_*(num).Imag - (num).Real)/s_; \ - (num).Real = t_; \ - } \ -} - -/* Complex reciprocation: to = 1.0 / den */ -#define CMPLX_RECIPROCAL(to,den) \ -{ RealNumber r_; \ - if (((den).Real >= (den).Imag AND (den).Real > -(den).Imag) OR \ - ((den).Real < (den).Imag AND (den).Real <= -(den).Imag)) \ - { r_ = (den).Imag / (den).Real; \ - (to).Imag = -r_*((to).Real = 1.0/((den).Real + r_*(den).Imag)); \ - } \ - else \ - { r_ = (den).Real / (den).Imag; \ - (to).Real = -r_*((to).Imag = -1.0/((den).Imag + r_*(den).Real));\ - } \ -} - - - - - - -/* - * ASSERT and ABORT - * - * Macro used to assert that if the code is working correctly, then - * a condition must be true. If not, then execution is terminated - * and an error message is issued stating that there is an internal - * error and giving the file and line number. These assertions are - * not evaluated unless the DEBUG flag is true. - */ - -#if DEBUG -#define ASSERT(condition) if (NOT(condition)) ABORT() -#else -#define ASSERT(condition) -#endif - -#if DEBUG -#define ABORT() \ -{ (void)fflush(stdout); \ - (void)fprintf(stderr, "sparse: panic in file `%s' at line %d.\n", \ - __FILE__, __LINE__); \ - (void)fflush(stderr); \ - abort(); \ -} -#else -#define ABORT() -#endif - - - - - -/* - * IMAGINARY VECTORS - * - * The imaginary vectors iRHS and iSolution are only needed when the - * options spCOMPLEX and spSEPARATED_COMPLEX_VECTORS are set. The following - * macro makes it easy to include or exclude these vectors as needed. - */ - -#if spCOMPLEX AND spSEPARATED_COMPLEX_VECTORS -#define IMAG_VECTORS , iRHS, iSolution -#define IMAG_RHS , iRHS -#else -#define IMAG_VECTORS -#define IMAG_RHS -#endif #define ALLOC(type,number) ((type *)tmalloc((unsigned)(sizeof(type)*(number)))) #define REALLOC(ptr,type,number) \ @@ -432,56 +255,19 @@ #define FREE(ptr) { if ((ptr) != NULL) txfree((char *)(ptr)); (ptr) = NULL; } -/* Calloc that properly handles allocating a cleared vector. */ -#define CALLOC(ptr,type,number) \ -{ int i; ptr = ALLOC(type, number); \ - if (ptr != (type *)NULL) \ - for(i=(number)-1;i>=0; i--) ptr[i] = (type) 0; \ + +/* A new calloc */ +#ifndef HAVE_LIBGC +#define CALLOC(ptr,type,number) \ +{ ptr = (type *) calloc(number, sizeof(type)); \ } +#else /* HAVE_LIBCG */ +#define CALLOC(ptr,type,number) \ +{ ptr = (type *) tmalloc(((size_t)number) * sizeof(type)); \ +} +#endif - - - - - - -/* - * REAL NUMBER - */ - -/* Begin `RealNumber'. */ - -typedef spREAL RealNumber, *RealVector; - - - - - - - - -/* - * COMPLEX NUMBER DATA STRUCTURE - * - * >>> Structure fields: - * Real (RealNumber) - * The real portion of the number. Real must be the first - * field in this structure. - * Imag (RealNumber) - * The imaginary portion of the number. This field must follow - * immediately after Real. - */ - -/* Begin `ComplexNumber'. */ - -typedef struct -{ RealNumber Real; - RealNumber Imag; -} ComplexNumber, *ComplexVector; - - - - +#include "complex.h" @@ -532,10 +318,9 @@ typedef struct /* Begin `MatrixElement'. */ struct MatrixElement -{ RealNumber Real; -#if spCOMPLEX +{ + RealNumber Real; RealNumber Imag; -#endif int Row; int Col; struct MatrixElement *NextInRow; @@ -573,7 +358,8 @@ typedef ElementPtr *ArrayOfElementPtrs; /* Begin `AllocationRecord'. */ struct AllocationRecord -{ char *AllocatedPtr; +{ + char *AllocatedPtr; struct AllocationRecord *NextRecord; }; @@ -608,7 +394,8 @@ typedef struct AllocationRecord *AllocationListPtr; /* Begin `FillinListNodeStruct'. */ struct FillinListNodeStruct -{ ElementPtr pFillinList; +{ + ElementPtr pFillinList; int NumberOfFillinsInList; struct FillinListNodeStruct *Next; }; @@ -616,7 +403,8 @@ struct FillinListNodeStruct /* Similar to above, but keeps track of the original Elements */ /* Begin `ElementListNodeStruct'. */ struct ElementListNodeStruct -{ ElementPtr pElementList; +{ + ElementPtr pElementList; int NumberOfElementsInList; struct ElementListNodeStruct *Next; }; @@ -654,7 +442,7 @@ struct ElementListNodeStruct * grow to when EXPANDABLE is set true and AllocatedSize is the largest * the matrix can get without requiring that the matrix frame be * reallocated. - * Complex (BOOLEAN) + * Complex (int) * The flag which indicates whether the matrix is complex (true) or * real. * CurrentSize (int) @@ -663,12 +451,12 @@ struct ElementListNodeStruct * rows and columns that have elements in them. * Diag (ArrayOfElementPtrs) * Array of pointers that points to the diagonal elements. - * DoCmplxDirect (BOOLEAN *) + * DoCmplxDirect (int *) * Array of flags, one for each column in matrix. If a flag is true * then corresponding column in a complex matrix should be eliminated * in spFactor() using direct addressing (rather than indirect * addressing). - * DoRealDirect (BOOLEAN *) + * DoRealDirect (int *) * Array of flags, one for each column in matrix. If a flag is true * then corresponding column in a real matrix should be eliminated * in spFactor() using direct addressing (rather than indirect @@ -685,7 +473,7 @@ struct ElementListNodeStruct * ExtToIntRowMap (int []) * An array that is used to convert external row numbers to internal * external row numbers. Present only if TRANSLATE option is set true. - * Factored (BOOLEAN) + * Factored (int) * Indicates if matrix has been factored. This flag is set true in * spFactor() and spOrderAndFactor() and set false in spCreate() * and spClear(). @@ -706,7 +494,7 @@ struct ElementListNodeStruct * array used during forward and backward substitution. It is * commonly called y when the forward and backward substitution process is * denoted Ax = b => Ly = b and Ux = y. - * InternalVectorsAllocated (BOOLEAN) + * InternalVectorsAllocated (int) * A flag that indicates whether the Markowitz vectors and the * Intermediate vector have been created. * These vectors are created in spcCreateInternalVectors(). @@ -730,19 +518,19 @@ struct ElementListNodeStruct * The maximum number of off-diagonal element in the rows of L, the * lower triangular matrix. This quantity is used when computing an * estimate of the roundoff error in the matrix. - * NeedsOrdering (BOOLEAN) + * NeedsOrdering (int) * This is a flag that signifies that the matrix needs to be ordered * or reordered. NeedsOrdering is set true in spCreate() and * spGetElement() or spGetAdmittance() if new elements are added to the * matrix after it has been previously factored. It is set false in * spOrderAndFactor(). - * NumberOfInterchangesIsOdd (BOOLEAN) + * NumberOfInterchangesIsOdd (int) * Flag that indicates the sum of row and column interchange counts * is an odd number. Used when determining the sign of the determinant. * Originals (int) * The number of original elements (total elements minus fill ins) * present in matrix. - * Partitioned (BOOLEAN) + * Partitioned (int) * This flag indicates that the columns of the matrix have been * partitioned into two groups. Those that will be addressed directly * and those that will be addressed indirectly in spFactor(). @@ -752,7 +540,7 @@ struct ElementListNodeStruct * Row pivot was chosen from. * PivotSelectionMethod (char) * Character that indicates which pivot search method was successful. - * PreviousMatrixWasComplex (BOOLEAN) + * PreviousMatrixWasComplex (int) * This flag in needed to determine how to clear the matrix. When * dealing with real matrices, it is important that the imaginary terms * in the matrix elements be zero. Thus, if the previous matrix was @@ -761,11 +549,11 @@ struct ElementListNodeStruct * RelThreshold (RealNumber) * The magnitude an element must have relative to others in its row * to be considered as a pivot candidate, except as a last resort. - * Reordered (BOOLEAN) + * Reordered (int) * This flag signifies that the matrix has been reordered. It * is cleared in spCreate(), set in spMNA_Preorder() and * spOrderAndFactor() and is used in spPrint(). - * RowsLinked (BOOLEAN) + * RowsLinked (int) * A flag that indicates whether the row pointers exist. The AddByIndex * routines do not generate the row pointers, which are needed by some * of the other routines, such as spOrderAndFactor() and spScale(). @@ -822,43 +610,44 @@ struct ElementListNodeStruct /* Begin `MatrixFrame'. */ struct MatrixFrame -{ RealNumber AbsThreshold; +{ + RealNumber AbsThreshold; int AllocatedSize; int AllocatedExtSize; - BOOLEAN Complex; + int Complex; int CurrentSize; ArrayOfElementPtrs Diag; - BOOLEAN *DoCmplxDirect; - BOOLEAN *DoRealDirect; + int *DoCmplxDirect; + int *DoRealDirect; int Elements; int Error; int ExtSize; int *ExtToIntColMap; int *ExtToIntRowMap; - BOOLEAN Factored; + int Factored; int Fillins; ArrayOfElementPtrs FirstInCol; ArrayOfElementPtrs FirstInRow; unsigned long ID; RealVector Intermediate; - BOOLEAN InternalVectorsAllocated; + int InternalVectorsAllocated; int *IntToExtColMap; int *IntToExtRowMap; int *MarkowitzRow; int *MarkowitzCol; long *MarkowitzProd; int MaxRowCountInLowerTri; - BOOLEAN NeedsOrdering; - BOOLEAN NumberOfInterchangesIsOdd; + int NeedsOrdering; + int NumberOfInterchangesIsOdd; int Originals; - BOOLEAN Partitioned; + int Partitioned; int PivotsOriginalCol; int PivotsOriginalRow; char PivotSelectionMethod; - BOOLEAN PreviousMatrixWasComplex; + int PreviousMatrixWasComplex; RealNumber RelThreshold; - BOOLEAN Reordered; - BOOLEAN RowsLinked; + int Reordered; + int RowsLinked; int SingularCol; int SingularRow; int Singletons; @@ -885,7 +674,6 @@ typedef struct MatrixFrame *MatrixPtr; * Function declarations */ -#ifdef __STDC__ extern ElementPtr spcGetElement( MatrixPtr ); extern ElementPtr spcGetFillin( MatrixPtr ); extern ElementPtr spcFindElementInCol( MatrixPtr, ElementPtr*, int, int, int ); @@ -894,13 +682,6 @@ extern void spcCreateInternalVectors( MatrixPtr ); extern void spcLinkRows( MatrixPtr ); extern void spcColExchange( MatrixPtr, int, int ); extern void spcRowExchange( MatrixPtr, int, int ); -#else /* __STDC__ */ -extern ElementPtr spcGetElement(); -extern ElementPtr spcGetFillin(); -extern ElementPtr spcFindElementInCol(); -extern ElementPtr spcCreateElement(); -extern void spcCreateInternalVectors(); -extern void spcLinkRows(); -extern void spcColExchange(); -extern void spcRowExchange(); -#endif /* __STDC__ */ + +#endif + diff --git a/src/maths/sparse/spextra.c b/src/maths/sparse/spextra.c index 58fbfb780..b2c83c0dd 100644 --- a/src/maths/sparse/spextra.c +++ b/src/maths/sparse/spextra.c @@ -28,20 +28,6 @@ #include "spdefs.h" - - - -/* - * Function declarations - */ - -#ifdef __STDC__ -#if spSEPARATED_COMPLEX_VECTORS -#else -#endif -#else /* __STDC__ */ -#endif /* __STDC__ */ - void spConstMult(matrix, constant) MatrixPtr matrix; @@ -59,154 +45,3 @@ spConstMult(matrix, constant) } } - -#ifdef notdef - -int spccc = 0; -int spccc_hold = -1; -int spccc_h1 = 1; -int spccc_h2 = 1; -int spccc_h3 = 1; -int spccc_h4 = 1; -int spccc_h5 = 1; -int spccc_h11 = 1; -int spccc_h12 = 1; -int spccc_h13 = 1; -int spccc_h15 = 1; -int spccc_h99 = 1; - -spCheck(matrix, key) - MatrixPtr matrix; - int key; -{ - ElementPtr e; - int i, n, k; - int size = matrix->Size; - - spccc += 1; - if (spccc == spccc_hold) - hold_matrix99( ); - - for (i = 1; i <= size; i++) { - k = -1; - if (!(key & 2)) { - for (n = 0, e = matrix->FirstInCol[i]; e && n <= size; - e = e->NextInCol) - { - if (k >= e->Row) - hold_matrix2( ); - if (e->Col != i) - hold_matrix3( ); - if (e->NextInRow && e->Col >= e->NextInRow->Col) - hold_matrix5( ); - - k = e->Row; - n += 1; - } - if (n > size) - hold_matrix1( ); - } - - k = -1; - if (matrix->RowsLinked && !(key & 1)) { - for (n = 0, e = matrix->FirstInRow[i]; e && n <= size; - e = e->NextInRow) - { - if (k >= e->Col) - hold_matrix12( ); - if (e->Row != i) - hold_matrix13( ); - if (e->NextInCol && e->Row >= e->NextInCol->Row) - hold_matrix15( ); - - k = e->Col; - n += 1; - } - if (n > size) - hold_matrix11( ); - } - } - -} - -hold_matrix1( ) -{ - if (spccc_h1) { - printf("BAD MATRIX"); - fflush(stdout); - } -} - -hold_matrix2( ) -{ - if (spccc_h2) { - printf("BAD MATRIX 2"); - fflush(stdout); - } -} - -hold_matrix3( ) -{ - if (spccc_h3) { - printf("BAD MATRIX 3"); - fflush(stdout); - } -} - -hold_matrix4( ) -{ - if (spccc_h4) { - printf("BAD MATRIX 3"); - fflush(stdout); - } -} - -hold_matrix5( ) -{ - if (spccc_h5) { - printf("BAD MATRIX 5"); - fflush(stdout); - } -} - -hold_matrix11( ) -{ - if (spccc_h11) { - printf("BAD MATRIX 11"); - fflush(stdout); - } -} - -hold_matrix12( ) -{ - if (spccc_h12) { - printf("BAD MATRIX 12"); - fflush(stdout); - } -} - -hold_matrix13( ) -{ - if (spccc_h13) { - printf("BAD MATRIX 13"); - fflush(stdout); - } -} - -hold_matrix15( ) -{ - if (spccc_h15) { - printf("BAD MATRIX 15"); - fflush(stdout); - } -} - -hold_matrix99( ) -{ - if (spccc_h99) { - printf("BAD MATRIX 99"); - fflush(stdout); - } -} - -#endif diff --git a/src/maths/sparse/spfactor.c b/src/maths/sparse/spfactor.c index 41406691f..195181583 100644 --- a/src/maths/sparse/spfactor.c +++ b/src/maths/sparse/spfactor.c @@ -44,15 +44,6 @@ * or implied warranty. */ -#ifdef notdef -static char copyright[] = - "Sparse1.3: Copyright (c) 1985,86,87,88,89,90 by Kenneth S. Kundert"; -static char RCSid[] = - "@(#)$Header$"; -#endif - - - /* * IMPORTS * @@ -64,6 +55,7 @@ static char RCSid[] = * spDefs.h * Matrix type and macro definitions for the sparse matrix routines. */ +#include #define spINSIDE_SPARSE #include "spconfig.h" @@ -164,7 +156,7 @@ static int ZeroPivot( MatrixPtr, int ); * pivot an element that has suffered heavy cancellation and as a * result mainly consists of roundoff error. Once a valid * threshold is given, it becomes the new default. - * DiagPivoting (BOOLEAN) + * DiagPivoting (int) * A flag indicating that pivot selection should be confined to the * diagonal if possible. If DiagPivoting is nonzero and if * DIAGONAL_PIVOTING is enabled pivots will be chosen only from @@ -186,7 +178,7 @@ static int ZeroPivot( MatrixPtr, int ); * >>> Local variables: * pPivot (ElementPtr) * Pointer to the element being used as a pivot. - * ReorderingRequired (BOOLEAN) + * ReorderingRequired (int) * Flag that indicates whether reordering is required. * * >>> Possible errors: @@ -197,86 +189,86 @@ static int ZeroPivot( MatrixPtr, int ); */ int -spOrderAndFactor( eMatrix, RHS, RelThreshold, AbsThreshold, DiagPivoting ) - -char *eMatrix; -RealNumber RHS[], RelThreshold, AbsThreshold; -BOOLEAN DiagPivoting; +spOrderAndFactor(void *eMatrix, RealNumber RHS[], RealNumber RelThreshold, + RealNumber AbsThreshold, int DiagPivoting) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -ElementPtr pPivot; -int Step, Size, ReorderingRequired; -ElementPtr SearchForPivot(); -RealNumber LargestInCol, FindLargestInCol(); + MatrixPtr Matrix = (MatrixPtr)eMatrix; + ElementPtr pPivot; + int Step, Size, ReorderingRequired; + ElementPtr SearchForPivot(); + RealNumber LargestInCol, FindLargestInCol(); -/* Begin `spOrderAndFactor'. */ - ASSERT( IS_VALID(Matrix) AND NOT Matrix->Factored); + /* Begin `spOrderAndFactor'. */ + assert( IS_VALID(Matrix) && !Matrix->Factored); Matrix->Error = spOKAY; Size = Matrix->Size; - if (RelThreshold <= 0.0) RelThreshold = Matrix->RelThreshold; - if (RelThreshold > 1.0) RelThreshold = Matrix->RelThreshold; + if (RelThreshold <= 0.0) + RelThreshold = Matrix->RelThreshold; + if (RelThreshold > 1.0) + RelThreshold = Matrix->RelThreshold; Matrix->RelThreshold = RelThreshold; - if (AbsThreshold < 0.0) AbsThreshold = Matrix->AbsThreshold; + if (AbsThreshold < 0.0) + AbsThreshold = Matrix->AbsThreshold; Matrix->AbsThreshold = AbsThreshold; ReorderingRequired = NO; - if (NOT Matrix->NeedsOrdering) + if (!Matrix->NeedsOrdering) { -/* Matrix has been factored before and reordering is not required. */ + /* Matrix has been factored before and reordering is not required. */ for (Step = 1; Step <= Size; Step++) - { pPivot = Matrix->Diag[Step]; + { + pPivot = Matrix->Diag[Step]; LargestInCol = FindLargestInCol(pPivot->NextInCol); if ((LargestInCol * RelThreshold < ELEMENT_MAG(pPivot))) - { if (Matrix->Complex) + { + if (Matrix->Complex) ComplexRowColElimination( Matrix, pPivot ); else RealRowColElimination( Matrix, pPivot ); } else - { ReorderingRequired = YES; + { + ReorderingRequired = YES; break; /* for loop */ } } - if (NOT ReorderingRequired) + if (!ReorderingRequired) goto Done; else { -/* - * A pivot was not large enough to maintain accuracy, - * so a partial reordering is required. - */ + /* A pivot was not large enough to maintain accuracy, so a + * partial reordering is required. */ #if (ANNOTATE >= ON_STRANGE_BEHAVIOR) printf("Reordering, Step = %1d\n", Step); #endif } - } /* End of if(NOT Matrix->NeedsOrdering) */ + } /* End of if(!Matrix->NeedsOrdering) */ else { -/* - * This is the first time the matrix has been factored. These few statements - * indicate to the rest of the code that a full reodering is required rather - * than a partial reordering, which occurs during a failure of a fast - * factorization. - */ + /* This is the first time the matrix has been factored. These + * few statements indicate to the rest of the code that a full + * reodering is required rather than a partial reordering, + * which occurs during a failure of a fast factorization. */ Step = 1; - if (NOT Matrix->RowsLinked) + if (!Matrix->RowsLinked) spcLinkRows( Matrix ); - if (NOT Matrix->InternalVectorsAllocated) + if (!Matrix->InternalVectorsAllocated) spcCreateInternalVectors( Matrix ); if (Matrix->Error >= spFATAL) return Matrix->Error; } -/* Form initial Markowitz products. */ + /* Form initial Markowitz products. */ CountMarkowitz( Matrix, RHS, Step ); MarkowitzProducts( Matrix, Step ); Matrix->MaxRowCountInLowerTri = -1; -/* Perform reordering and factorization. */ + /* Perform reordering and factorization. */ for (; Step <= Size; Step++) - { pPivot = SearchForPivot( Matrix, Step, DiagPivoting ); + { + pPivot = SearchForPivot( Matrix, Step, DiagPivoting ); if (pPivot == NULL) return MatrixIsSingular( Matrix, Step ); ExchangeRowsAndCols( Matrix, pPivot, Step ); @@ -293,7 +285,7 @@ RealNumber LargestInCol, FindLargestInCol(); #endif } -Done: + Done: Matrix->NeedsOrdering = NO; Matrix->Reordered = YES; Matrix->Factored = YES; @@ -313,15 +305,15 @@ Done: * This routine is the companion routine to spOrderAndFactor(). * Unlike spOrderAndFactor(), spFactor() cannot change the ordering. * It is also faster than spOrderAndFactor(). The standard way of - * using these two routines is to first use spOrderAndFactor() for the - * initial factorization. For subsequent factorizations, spFactor() - * is used if there is some assurance that little growth will occur - * (say for example, that the matrix is diagonally dominant). If - * spFactor() is called for the initial factorization of the matrix, - * then spOrderAndFactor() is automatically called with the default - * threshold. This routine uses "row at a time" LU factorization. - * Pivots are associated with the lower triangular matrix and the - * diagonals of the upper triangular matrix are ones. + * using these two routines is to first use spOrderAndFactor() for + * the initial factorization. For subsequent factorizations, + * spFactor() is used if there is some assurance that little growth + * will occur (say for example, that the matrix is diagonally + * dominant). If spFactor() is called for the initial factorization + * of the matrix, then spOrderAndFactor() is automatically called + * with the default threshold. This routine uses "row at a time" LU + * factorization. Pivots are associated with the lower triangular + * matrix and the diagonals of the upper triangular matrix are ones. * * >>> Returned: * The error code is returned. Possible errors are listed below. @@ -335,94 +327,98 @@ Done: * spSINGULAR * spZERO_DIAG * spSMALL_PIVOT - * Error is cleared in this function. - */ + * Error is cleared in this function. */ int -spFactor( eMatrix ) - -char *eMatrix; +spFactor(void *eMatrix) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register ElementPtr pElement; -register ElementPtr pColumn; -register int Step, Size; -RealNumber Mult; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + ElementPtr pElement; + ElementPtr pColumn; + int Step, Size; + RealNumber Mult; -/* Begin `spFactor'. */ - ASSERT( IS_VALID(Matrix) AND NOT Matrix->Factored); + /* Begin `spFactor'. */ + assert( IS_VALID(Matrix) && !Matrix->Factored); if (Matrix->NeedsOrdering) - { return spOrderAndFactor( eMatrix, (RealVector)NULL, + { + return spOrderAndFactor( eMatrix, (RealVector)NULL, 0.0, 0.0, DIAG_PIVOTING_AS_DEFAULT ); } - if (NOT Matrix->Partitioned) spPartition( eMatrix, spDEFAULT_PARTITION ); -#if spCOMPLEX - if (Matrix->Complex) return FactorComplexMatrix( Matrix ); -#endif + if (!Matrix->Partitioned) spPartition( eMatrix, spDEFAULT_PARTITION ); + if (Matrix->Complex) + return FactorComplexMatrix( Matrix ); -#if REAL Size = Matrix->Size; if (Matrix->Diag[1]->Real == 0.0) return ZeroPivot( Matrix, 1 ); Matrix->Diag[1]->Real = 1.0 / Matrix->Diag[1]->Real; -/* Start factorization. */ + /* Start factorization. */ for (Step = 2; Step <= Size; Step++) - { if (Matrix->DoRealDirect[Step]) - { /* Update column using direct addressing scatter-gather. */ - register RealNumber *Dest = (RealNumber *)Matrix->Intermediate; + { + if (Matrix->DoRealDirect[Step]) + { + /* Update column using direct addressing scatter-gather. */ + RealNumber *Dest = (RealNumber *)Matrix->Intermediate; -/* Scatter. */ + /* Scatter. */ pElement = Matrix->FirstInCol[Step]; while (pElement != NULL) - { Dest[pElement->Row] = pElement->Real; + { + Dest[pElement->Row] = pElement->Real; pElement = pElement->NextInCol; } -/* Update column. */ + /* Update column. */ pColumn = Matrix->FirstInCol[Step]; while (pColumn->Row < Step) - { pElement = Matrix->Diag[pColumn->Row]; + { + pElement = Matrix->Diag[pColumn->Row]; pColumn->Real = Dest[pColumn->Row] * pElement->Real; while ((pElement = pElement->NextInCol) != NULL) Dest[pElement->Row] -= pColumn->Real * pElement->Real; pColumn = pColumn->NextInCol; } -/* Gather. */ + /* Gather. */ pElement = Matrix->Diag[Step]->NextInCol; while (pElement != NULL) - { pElement->Real = Dest[pElement->Row]; + { + pElement->Real = Dest[pElement->Row]; pElement = pElement->NextInCol; } -/* Check for singular matrix. */ + /* Check for singular matrix. */ if (Dest[Step] == 0.0) return ZeroPivot( Matrix, Step ); Matrix->Diag[Step]->Real = 1.0 / Dest[Step]; } else - { /* Update column using indirect addressing scatter-gather. */ - register RealNumber **pDest = (RealNumber **)Matrix->Intermediate; + { + /* Update column using indirect addressing scatter-gather. */ + RealNumber **pDest = (RealNumber **)Matrix->Intermediate; -/* Scatter. */ + /* Scatter. */ pElement = Matrix->FirstInCol[Step]; while (pElement != NULL) - { pDest[pElement->Row] = &pElement->Real; + { + pDest[pElement->Row] = &pElement->Real; pElement = pElement->NextInCol; } -/* Update column. */ + /* Update column. */ pColumn = Matrix->FirstInCol[Step]; while (pColumn->Row < Step) - { pElement = Matrix->Diag[pColumn->Row]; + { + pElement = Matrix->Diag[pColumn->Row]; Mult = (*pDest[pColumn->Row] *= pElement->Real); while ((pElement = pElement->NextInCol) != NULL) *pDest[pElement->Row] -= Mult * pElement->Real; pColumn = pColumn->NextInCol; } -/* Check for singular matrix. */ + /* Check for singular matrix. */ if (Matrix->Diag[Step]->Real == 0.0) return ZeroPivot( Matrix, Step ); Matrix->Diag[Step]->Real = 1.0 / Matrix->Diag[Step]->Real; @@ -431,7 +427,6 @@ RealNumber Mult; Matrix->Factored = YES; return (Matrix->Error = spOKAY); -#endif /* REAL */ } @@ -439,7 +434,6 @@ RealNumber Mult; -#if spCOMPLEX /* * FACTOR COMPLEX MATRIX * @@ -463,87 +457,97 @@ FactorComplexMatrix( Matrix ) MatrixPtr Matrix; { -register ElementPtr pElement; -register ElementPtr pColumn; -register int Step, Size; -ComplexNumber Mult, Pivot; + ElementPtr pElement; + ElementPtr pColumn; + int Step, Size; + ComplexNumber Mult, Pivot; -/* Begin `FactorComplexMatrix'. */ - ASSERT(Matrix->Complex); + /* Begin `FactorComplexMatrix'. */ + assert(Matrix->Complex); Size = Matrix->Size; pElement = Matrix->Diag[1]; if (ELEMENT_MAG(pElement) == 0.0) return ZeroPivot( Matrix, 1 ); -/* Cmplx expr: *pPivot = 1.0 / *pPivot. */ + /* Cmplx expr: *pPivot = 1.0 / *pPivot. */ CMPLX_RECIPROCAL( *pElement, *pElement ); -/* Start factorization. */ + /* Start factorization. */ for (Step = 2; Step <= Size; Step++) - { if (Matrix->DoCmplxDirect[Step]) - { /* Update column using direct addressing scatter-gather. */ - register ComplexNumber *Dest; + { + if (Matrix->DoCmplxDirect[Step]) + { + /* Update column using direct addressing scatter-gather. */ + ComplexNumber *Dest; Dest = (ComplexNumber *)Matrix->Intermediate; -/* Scatter. */ + /* Scatter. */ pElement = Matrix->FirstInCol[Step]; while (pElement != NULL) - { Dest[pElement->Row] = *(ComplexNumber *)pElement; + { + Dest[pElement->Row] = *(ComplexNumber *)pElement; pElement = pElement->NextInCol; } -/* Update column. */ + /* Update column. */ pColumn = Matrix->FirstInCol[Step]; while (pColumn->Row < Step) - { pElement = Matrix->Diag[pColumn->Row]; + { + pElement = Matrix->Diag[pColumn->Row]; /* Cmplx expr: Mult = Dest[pColumn->Row] * (1.0 / *pPivot). */ CMPLX_MULT(Mult, Dest[pColumn->Row], *pElement); CMPLX_ASSIGN(*pColumn, Mult); while ((pElement = pElement->NextInCol) != NULL) - { /* Cmplx expr: Dest[pElement->Row] -= Mult * pElement */ + { + /* Cmplx expr: Dest[pElement->Row] -= Mult * pElement */ CMPLX_MULT_SUBT_ASSIGN(Dest[pElement->Row],Mult,*pElement); } pColumn = pColumn->NextInCol; } -/* Gather. */ + /* Gather. */ pElement = Matrix->Diag[Step]->NextInCol; while (pElement != NULL) - { *(ComplexNumber *)pElement = Dest[pElement->Row]; + { + *(ComplexNumber *)pElement = Dest[pElement->Row]; pElement = pElement->NextInCol; } -/* Check for singular matrix. */ + /* Check for singular matrix. */ Pivot = Dest[Step]; if (CMPLX_1_NORM(Pivot) == 0.0) return ZeroPivot( Matrix, Step ); CMPLX_RECIPROCAL( *Matrix->Diag[Step], Pivot ); } else - { /* Update column using direct addressing scatter-gather. */ - register ComplexNumber **pDest; + { + /* Update column using direct addressing scatter-gather. */ + ComplexNumber **pDest; pDest = (ComplexNumber **)Matrix->Intermediate; -/* Scatter. */ + /* Scatter. */ pElement = Matrix->FirstInCol[Step]; while (pElement != NULL) - { pDest[pElement->Row] = (ComplexNumber *)pElement; + { + pDest[pElement->Row] = (ComplexNumber *)pElement; pElement = pElement->NextInCol; } -/* Update column. */ + /* Update column. */ pColumn = Matrix->FirstInCol[Step]; while (pColumn->Row < Step) - { pElement = Matrix->Diag[pColumn->Row]; + { + pElement = Matrix->Diag[pColumn->Row]; /* Cmplx expr: Mult = *pDest[pColumn->Row] * (1.0 / *pPivot). */ CMPLX_MULT(Mult, *pDest[pColumn->Row], *pElement); CMPLX_ASSIGN(*pDest[pColumn->Row], Mult); while ((pElement = pElement->NextInCol) != NULL) - { /* Cmplx expr: *pDest[pElement->Row] -= Mult * pElement */ - CMPLX_MULT_SUBT_ASSIGN(*pDest[pElement->Row],Mult,*pElement); + { + /* Cmplx expr: *pDest[pElement->Row] -= Mult * pElement */ + CMPLX_MULT_SUBT_ASSIGN(*pDest[pElement->Row],Mult,*pElement); } pColumn = pColumn->NextInCol; } -/* Check for singular matrix. */ + /* Check for singular matrix. */ pElement = Matrix->Diag[Step]; if (ELEMENT_MAG(pElement) == 0.0) return ZeroPivot( Matrix, Step ); CMPLX_RECIPROCAL( *pElement, *pElement ); @@ -553,7 +557,6 @@ ComplexNumber Mult, Pivot; Matrix->Factored = YES; return (Matrix->Error = spOKAY); } -#endif /* spCOMPLEX */ @@ -568,97 +571,95 @@ ComplexNumber Mult, Pivot; * which addressing mode is fastest. This information is used in * spFactor() to speed the factorization. * - * When factoring a previously ordered matrix using spFactor(), Sparse - * operates on a row-at-a-time basis. For speed, on each step, the - * row being updated is copied into a full vector and the operations - * are performed on that vector. This can be done one of two ways, - * either using direct addressing or indirect addressing. Direct - * addressing is fastest when the matrix is relatively dense and - * indirect addressing is best when the matrix is quite sparse. The - * user selects the type of partition used with Mode. If Mode is set - * to spDIRECT_PARTITION, then the all rows are placed in the direct - * addressing partition. Similarly, if Mode is set to + * When factoring a previously ordered matrix using spFactor(), + * Sparse operates on a row-at-a-time basis. For speed, on each + * step, the row being updated is copied into a full vector and the + * operations are performed on that vector. This can be done one of + * two ways, either using direct addressing or indirect addressing. + * Direct addressing is fastest when the matrix is relatively dense + * and indirect addressing is best when the matrix is quite sparse. + * The user selects the type of partition used with Mode. If Mode is + * set to spDIRECT_PARTITION, then the all rows are placed in the + * direct addressing partition. Similarly, if Mode is set to * spINDIRECT_PARTITION, then the all rows are placed in the indirect * addressing partition. By setting Mode to spAUTO_PARTITION, the * user allows Sparse to select the partition for each row * individually. spFactor() generally runs faster if Sparse is * allowed to choose its own partitioning, however choosing a - * partition is expensive. The time required to choose a partition is - * of the same order of the cost to factor the matrix. If you plan to - * factor a large number of matrices with the same structure, it is - * best to let Sparse choose the partition. Otherwise, you should - * choose the partition based on the predicted density of the matrix. + * partition is expensive. The time required to choose a partition + * is of the same order of the cost to factor the matrix. If you + * plan to factor a large number of matrices with the same structure, + * it is best to let Sparse choose the partition. Otherwise, you + * should choose the partition based on the predicted density of the + * matrix. * * >>> Arguments: * Matrix (char *) * Pointer to matrix. * Mode (int) * Mode must be one of three special codes: spDIRECT_PARTITION, - * spINDIRECT_PARTITION, or spAUTO_PARTITION. - */ + * spINDIRECT_PARTITION, or spAUTO_PARTITION. */ void -spPartition( eMatrix, Mode ) - -char *eMatrix; -int Mode; +spPartition(void *eMatrix, int Mode) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register ElementPtr pElement, pColumn; -register int Step, Size; -register int *Nc, *No, *Nm; -BOOLEAN *DoRealDirect, *DoCmplxDirect; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + ElementPtr pElement, pColumn; + int Step, Size; + int *Nc, *No, *Nm; + int *DoRealDirect, *DoCmplxDirect; -/* Begin `spPartition'. */ - ASSERT( IS_SPARSE( Matrix ) ); + /* Begin `spPartition'. */ + assert( IS_SPARSE( Matrix ) ); if (Matrix->Partitioned) return; Size = Matrix->Size; DoRealDirect = Matrix->DoRealDirect; DoCmplxDirect = Matrix->DoCmplxDirect; Matrix->Partitioned = YES; -/* If partition is specified by the user, this is easy. */ + /* If partition is specified by the user, this is easy. */ if (Mode == spDEFAULT_PARTITION) Mode = DEFAULT_PARTITION; if (Mode == spDIRECT_PARTITION) - { for (Step = 1; Step <= Size; Step++) -#if REAL + { + for (Step = 1; Step <= Size; Step++) { DoRealDirect[Step] = YES; -#endif -#if spCOMPLEX - DoCmplxDirect[Step] = YES; -#endif + DoCmplxDirect[Step] = YES; + } return; } else if (Mode == spINDIRECT_PARTITION) - { for (Step = 1; Step <= Size; Step++) -#if REAL + { + for (Step = 1; Step <= Size; Step++) + { DoRealDirect[Step] = NO; -#endif -#if spCOMPLEX - DoCmplxDirect[Step] = NO; -#endif + DoCmplxDirect[Step] = NO; + } return; } - else ASSERT( Mode == spAUTO_PARTITION ); + else + assert( Mode == spAUTO_PARTITION ); -/* Otherwise, count all operations needed in when factoring matrix. */ + /* Otherwise, count all operations needed in when factoring matrix. */ Nc = (int *)Matrix->MarkowitzRow; No = (int *)Matrix->MarkowitzCol; Nm = (int *)Matrix->MarkowitzProd; -/* Start mock-factorization. */ + /* Start mock-factorization. */ for (Step = 1; Step <= Size; Step++) - { Nc[Step] = No[Step] = Nm[Step] = 0; + { + Nc[Step] = No[Step] = Nm[Step] = 0; pElement = Matrix->FirstInCol[Step]; while (pElement != NULL) - { Nc[Step]++; + { + Nc[Step]++; pElement = pElement->NextInCol; } pColumn = Matrix->FirstInCol[Step]; while (pColumn->Row < Step) - { pElement = Matrix->Diag[pColumn->Row]; + { + pElement = Matrix->Diag[pColumn->Row]; Nm[Step]++; while ((pElement = pElement->NextInCol) != NULL) No[Step]++; @@ -668,53 +669,42 @@ BOOLEAN *DoRealDirect, *DoCmplxDirect; for (Step = 1; Step <= Size; Step++) { -/* - * The following are just estimates based on a count on the number of - * machine instructions used on each machine to perform the various - * tasks. It was assumed that each machine instruction required the - * same amount of time (I don't believe this is TRUE for the VAX, and - * have no idea if this is TRUE for the 68000 family). For optimum - * performance, these numbers should be tuned to the machine. - * Nc is the number of nonzero elements in the column. - * Nm is the number of multipliers in the column. - * No is the number of operations in the inner loop. - */ + /* The following are just estimates based on a count on the + * number of machine instructions used on each machine to + * perform the various tasks. It was assumed that each + * machine instruction required the same amount of time (I + * don't believe this is TRUE for the VAX, and have no idea if + * this is TRUE for the 68000 family). For optimum + * performance, these numbers should be tuned to the machine. + * + * Nc is the number of nonzero elements in the column. + * Nm is the number of multipliers in the column. + * No is the number of operations in the inner loop. */ #define generic #ifdef hp9000s300 -#if REAL DoRealDirect[Step] = (Nm[Step] + No[Step] > 3*Nc[Step] - 2*Nm[Step]); -#endif -#if spCOMPLEX /* On the hp350, it is never profitable to use direct for complex. */ DoCmplxDirect[Step] = NO; -#endif #undef generic #endif #ifdef vax -#if REAL DoRealDirect[Step] = (Nm[Step] + No[Step] > 3*Nc[Step] - 2*Nm[Step]); -#endif -#if spCOMPLEX DoCmplxDirect[Step] = (Nm[Step] + No[Step] > 7*Nc[Step] - 4*Nm[Step]); -#endif #undef generic #endif #ifdef generic -#if REAL DoRealDirect[Step] = (Nm[Step] + No[Step] > 3*Nc[Step] - 2*Nm[Step]); -#endif -#if spCOMPLEX DoCmplxDirect[Step] = (Nm[Step] + No[Step] > 7*Nc[Step] - 4*Nm[Step]); -#endif #undef generic #endif } #if (ANNOTATE == FULL) - { int Ops = 0; + { + int Ops = 0; for (Step = 1; Step <= Size; Step++) Ops += No[Step]; printf("Operation count for inner loop of factorization = %d.\n", Ops); @@ -751,54 +741,46 @@ spcCreateInternalVectors( Matrix ) MatrixPtr Matrix; { -int Size; + int Size; -/* Begin `spcCreateInternalVectors'. */ -/* Create Markowitz arrays. */ + /* Begin `spcCreateInternalVectors'. */ + /* Create Markowitz arrays. */ Size= Matrix->Size; if (Matrix->MarkowitzRow == NULL) - { if (( Matrix->MarkowitzRow = ALLOC(int, Size+1)) == NULL) - Matrix->Error = spNO_MEMORY; + { + if (( Matrix->MarkowitzRow = ALLOC(int, Size+1)) == NULL) + Matrix->Error = spNO_MEMORY; } if (Matrix->MarkowitzCol == NULL) - { if (( Matrix->MarkowitzCol = ALLOC(int, Size+1)) == NULL) - Matrix->Error = spNO_MEMORY; + { + if (( Matrix->MarkowitzCol = ALLOC(int, Size+1)) == NULL) + Matrix->Error = spNO_MEMORY; } if (Matrix->MarkowitzProd == NULL) - { if (( Matrix->MarkowitzProd = ALLOC(long, Size+2)) == NULL) - Matrix->Error = spNO_MEMORY; + { + if (( Matrix->MarkowitzProd = ALLOC(long, Size+2)) == NULL) + Matrix->Error = spNO_MEMORY; } -/* Create DoDirect vectors for use in spFactor(). */ -#if REAL - if (Matrix->DoRealDirect == NULL) - { if (( Matrix->DoRealDirect = ALLOC(BOOLEAN, Size+1)) == NULL) - Matrix->Error = spNO_MEMORY; + /* Create DoDirect vectors for use in spFactor(). */ + if (Matrix->DoRealDirect == NULL) { + if (( Matrix->DoRealDirect = ALLOC(int, Size+1)) == NULL) + Matrix->Error = spNO_MEMORY; } -#endif -#if spCOMPLEX - if (Matrix->DoCmplxDirect == NULL) - { if (( Matrix->DoCmplxDirect = ALLOC(BOOLEAN, Size+1)) == NULL) - Matrix->Error = spNO_MEMORY; + if (Matrix->DoCmplxDirect == NULL) { + if (( Matrix->DoCmplxDirect = ALLOC(int, Size+1)) == NULL) + Matrix->Error = spNO_MEMORY; } -#endif -/* Create Intermediate vectors for use in MatrixSolve. */ -#if spCOMPLEX - if (Matrix->Intermediate == NULL) - { if ((Matrix->Intermediate = ALLOC(RealNumber,2*(Size+1))) == NULL) - Matrix->Error = spNO_MEMORY; + /* Create Intermediate vectors for use in MatrixSolve. */ + if (Matrix->Intermediate == NULL) { + if ((Matrix->Intermediate = ALLOC(RealNumber,2*(Size+1))) == NULL) + Matrix->Error = spNO_MEMORY; } -#else - if (Matrix->Intermediate == NULL) - { if ((Matrix->Intermediate = ALLOC(RealNumber, Size+1)) == NULL) - Matrix->Error = spNO_MEMORY; - } -#endif if (Matrix->Error != spNO_MEMORY) - Matrix->InternalVectorsAllocated = YES; + Matrix->InternalVectorsAllocated = YES; return; } @@ -836,71 +818,44 @@ int Size; */ static void -CountMarkowitz( Matrix, RHS, Step ) - -MatrixPtr Matrix; -register RealVector RHS; -int Step; +CountMarkowitz(MatrixPtr Matrix, RealVector RHS, int Step) { -register int Count, I, Size = Matrix->Size; -register ElementPtr pElement; -int ExtRow; + int Count, I, Size = Matrix->Size; + ElementPtr pElement; + int ExtRow; -/* Begin `CountMarkowitz'. */ + /* Begin `CountMarkowitz'. */ -/* Correct array pointer for ARRAY_OFFSET. */ -#if NOT ARRAY_OFFSET -#if spSEPARATED_COMPLEX_VECTORS OR NOT spCOMPLEX - if (RHS != NULL) --RHS; -#else - if (RHS != NULL) - { if (Matrix->Complex) RHS -= 2; - else --RHS; - } -#endif -#endif - -/* Generate MarkowitzRow Count for each row. */ - for (I = Step; I <= Size; I++) - { -/* Set Count to -1 initially to remove count due to pivot element. */ + /* Generate MarkowitzRow Count for each row. */ + for (I = Step; I <= Size; I++) { + /* Set Count to -1 initially to remove count due to pivot element. */ Count = -1; pElement = Matrix->FirstInRow[I]; - while (pElement != NULL AND pElement->Col < Step) + while (pElement != NULL && pElement->Col < Step) pElement = pElement->NextInRow; - while (pElement != NULL) - { Count++; + while (pElement != NULL) { + Count++; pElement = pElement->NextInRow; } -/* Include nonzero elements in the RHS vector. */ + /* Include nonzero elements in the RHS vector. */ ExtRow = Matrix->IntToExtRowMap[I]; -#if spSEPARATED_COMPLEX_VECTORS OR NOT spCOMPLEX if (RHS != NULL) - if (RHS[ExtRow] != 0.0) Count++; -#else - if (RHS != NULL) - { if (Matrix->Complex) - { if ((RHS[2*ExtRow] != 0.0) OR (RHS[2*ExtRow+1] != 0.0)) - Count++; - } - else if (RHS[I] != 0.0) Count++; - } -#endif + if (RHS[ExtRow] != 0.0) + Count++; Matrix->MarkowitzRow[I] = Count; } -/* Generate the MarkowitzCol count for each column. */ - for (I = Step; I <= Size; I++) - { -/* Set Count to -1 initially to remove count due to pivot element. */ + /* Generate the MarkowitzCol count for each column. */ + for (I = Step; I <= Size; I++) { + /* Set Count to -1 initially to remove count due to pivot element. */ Count = -1; pElement = Matrix->FirstInCol[I]; - while (pElement != NULL AND pElement->Row < Step) + while (pElement != NULL && pElement->Row < Step) pElement = pElement->NextInCol; - while (pElement != NULL) - { Count++; + while (pElement != NULL) { + Count++; pElement = pElement->NextInCol; } Matrix->MarkowitzCol[I] = Count; @@ -946,36 +901,31 @@ int ExtRow; */ static void -MarkowitzProducts( Matrix, Step ) - -MatrixPtr Matrix; -int Step; +MarkowitzProducts(MatrixPtr Matrix, int Step) { -register int I, *pMarkowitzRow, *pMarkowitzCol; -register long Product, *pMarkowitzProduct; -register int Size = Matrix->Size; -double fProduct; + int I, *pMarkowitzRow, *pMarkowitzCol; + long Product, *pMarkowitzProduct; + int Size = Matrix->Size; + double fProduct; -/* Begin `MarkowitzProducts'. */ + /* Begin `MarkowitzProducts'. */ Matrix->Singletons = 0; pMarkowitzProduct = &(Matrix->MarkowitzProd[Step]); pMarkowitzRow = &(Matrix->MarkowitzRow[Step]); pMarkowitzCol = &(Matrix->MarkowitzCol[Step]); - for (I = Step; I <= Size; I++) - { -/* If chance of overflow, use real numbers. */ - if ((*pMarkowitzRow > LARGEST_SHORT_INTEGER AND *pMarkowitzCol != 0) OR - (*pMarkowitzCol > LARGEST_SHORT_INTEGER AND *pMarkowitzRow != 0)) - { fProduct = (double)(*pMarkowitzRow++) * (double)(*pMarkowitzCol++); + for (I = Step; I <= Size; I++) { + /* If chance of overflow, use real numbers. */ + if ((*pMarkowitzRow > LARGEST_SHORT_INTEGER && *pMarkowitzCol != 0) || + (*pMarkowitzCol > LARGEST_SHORT_INTEGER && *pMarkowitzRow != 0)) { + fProduct = (double)(*pMarkowitzRow++) * (double)(*pMarkowitzCol++); if (fProduct >= LARGEST_LONG_INTEGER) *pMarkowitzProduct++ = LARGEST_LONG_INTEGER; else *pMarkowitzProduct++ = fProduct; - } - else - { Product = *pMarkowitzRow++ * *pMarkowitzCol++; + } else { + Product = *pMarkowitzRow++ * *pMarkowitzCol++; if ((*pMarkowitzProduct++ = Product) == 0) Matrix->Singletons++; } @@ -1038,19 +988,21 @@ SearchForPivot( Matrix, Step, DiagPivoting ) MatrixPtr Matrix; int Step, DiagPivoting; { -register ElementPtr ChosenPivot; +ElementPtr ChosenPivot; ElementPtr SearchForSingleton(); ElementPtr QuicklySearchDiagonal(); ElementPtr SearchDiagonal(); ElementPtr SearchEntireMatrix(); -/* Begin `SearchForPivot'. */ + /* Begin `SearchForPivot'. */ -/* If singletons exist, look for an acceptable one to use as pivot. */ + /* If singletons exist, look for an acceptable one to use as pivot. */ if (Matrix->Singletons) - { ChosenPivot = SearchForSingleton( Matrix, Step ); + { + ChosenPivot = SearchForSingleton( Matrix, Step ); if (ChosenPivot != NULL) - { Matrix->PivotSelectionMethod = 's'; + { + Matrix->PivotSelectionMethod = 's'; return ChosenPivot; } } @@ -1058,7 +1010,7 @@ ElementPtr SearchEntireMatrix(); #if DIAGONAL_PIVOTING if (DiagPivoting) { -/* + /* * Either no singletons exist or they weren't acceptable. Take quick first * pass at searching diagonal. First search for element on diagonal of * remaining submatrix with smallest Markowitz product, then check to see @@ -1066,23 +1018,25 @@ ElementPtr SearchEntireMatrix(); */ ChosenPivot = QuicklySearchDiagonal( Matrix, Step ); if (ChosenPivot != NULL) - { Matrix->PivotSelectionMethod = 'q'; + { + Matrix->PivotSelectionMethod = 'q'; return ChosenPivot; } -/* + /* * Quick search of diagonal failed, carefully search diagonal and check each * pivot candidate numerically before even tentatively accepting it. */ ChosenPivot = SearchDiagonal( Matrix, Step ); if (ChosenPivot != NULL) - { Matrix->PivotSelectionMethod = 'd'; + { + Matrix->PivotSelectionMethod = 'd'; return ChosenPivot; } } #endif /* DIAGONAL_PIVOTING */ -/* No acceptable pivot found yet, search entire matrix. */ + /* No acceptable pivot found yet, search entire matrix. */ ChosenPivot = SearchEntireMatrix( Matrix, Step ); Matrix->PivotSelectionMethod = 'e'; @@ -1139,22 +1093,22 @@ SearchForSingleton( Matrix, Step ) MatrixPtr Matrix; int Step; { -register ElementPtr ChosenPivot; -register int I; -register long *pMarkowitzProduct; + ElementPtr ChosenPivot; + int I; + long *pMarkowitzProduct; int Singletons; RealNumber PivotMag, FindBiggestInColExclude(); -/* Begin `SearchForSingleton'. */ -/* Initialize pointer that is to scan through MarkowitzProduct vector. */ + /* Begin `SearchForSingleton'. */ + /* Initialize pointer that is to scan through MarkowitzProduct vector. */ pMarkowitzProduct = &(Matrix->MarkowitzProd[Matrix->Size+1]); Matrix->MarkowitzProd[Matrix->Size+1] = Matrix->MarkowitzProd[Step]; -/* Decrement the count of available singletons, on the assumption that an + /* Decrement the count of available singletons, on the assumption that an * acceptable one will be found. */ Singletons = Matrix->Singletons--; -/* + /* * Assure that following while loop will always terminate, this is just * preventive medicine, if things are working right this should never * be needed. @@ -1163,9 +1117,9 @@ RealNumber PivotMag, FindBiggestInColExclude(); while (Singletons-- > 0) { -/* Singletons exist, find them. */ + /* Singletons exist, find them. */ -/* + /* * This is tricky. Am using a pointer to sequentially step through the * MarkowitzProduct array. Search terminates when singleton (Product = 0) * is found. Note that the conditional in the while statement @@ -1185,7 +1139,8 @@ RealNumber PivotMag, FindBiggestInColExclude(); */ while ( *pMarkowitzProduct-- ) - { /* + { + /* * N bottles of beer on the wall; * N bottles of beer. * you take one down and pass it around; @@ -1194,51 +1149,56 @@ RealNumber PivotMag, FindBiggestInColExclude(); } I = pMarkowitzProduct - Matrix->MarkowitzProd + 1; -/* Assure that I is valid. */ + /* Assure that I is valid. */ if (I < Step) break; /* while (Singletons-- > 0) */ if (I > Matrix->Size) I = Step; -/* Singleton has been found in either/both row or/and column I. */ + /* Singleton has been found in either/both row or/and column I. */ if ((ChosenPivot = Matrix->Diag[I]) != NULL) { -/* Singleton lies on the diagonal. */ + /* Singleton lies on the diagonal. */ PivotMag = ELEMENT_MAG(ChosenPivot); if - ( PivotMag > Matrix->AbsThreshold AND + ( PivotMag > Matrix->AbsThreshold && PivotMag > Matrix->RelThreshold * FindBiggestInColExclude( Matrix, ChosenPivot, Step ) ) return ChosenPivot; } else { -/* Singleton does not lie on diagonal, find it. */ + /* Singleton does not lie on diagonal, find it. */ if (Matrix->MarkowitzCol[I] == 0) - { ChosenPivot = Matrix->FirstInCol[I]; - while ((ChosenPivot != NULL) AND (ChosenPivot->Row < Step)) + { + ChosenPivot = Matrix->FirstInCol[I]; + while ((ChosenPivot != NULL) && (ChosenPivot->Row < Step)) ChosenPivot = ChosenPivot->NextInCol; if (ChosenPivot != NULL) - { /* Reduced column has no elements, matrix is singular. */ + { + /* Reduced column has no elements, matrix is singular. */ break; } PivotMag = ELEMENT_MAG(ChosenPivot); if - ( PivotMag > Matrix->AbsThreshold AND + ( PivotMag > Matrix->AbsThreshold && PivotMag > Matrix->RelThreshold * FindBiggestInColExclude( Matrix, ChosenPivot, Step ) ) return ChosenPivot; else - { if (Matrix->MarkowitzRow[I] == 0) - { ChosenPivot = Matrix->FirstInRow[I]; - while((ChosenPivot != NULL) AND (ChosenPivot->ColMarkowitzRow[I] == 0) + { + ChosenPivot = Matrix->FirstInRow[I]; + while((ChosenPivot != NULL) && (ChosenPivot->ColNextInRow; if (ChosenPivot != NULL) - { /* Reduced row has no elements, matrix is singular. */ + { + /* Reduced row has no elements, matrix is singular. */ break; } PivotMag = ELEMENT_MAG(ChosenPivot); if - ( PivotMag > Matrix->AbsThreshold AND + ( PivotMag > Matrix->AbsThreshold && PivotMag > Matrix->RelThreshold * FindBiggestInColExclude( Matrix, ChosenPivot, @@ -1248,26 +1208,28 @@ RealNumber PivotMag, FindBiggestInColExclude(); } } else - { ChosenPivot = Matrix->FirstInRow[I]; - while ((ChosenPivot != NULL) AND (ChosenPivot->Col < Step)) + { + ChosenPivot = Matrix->FirstInRow[I]; + while ((ChosenPivot != NULL) && (ChosenPivot->Col < Step)) ChosenPivot = ChosenPivot->NextInRow; if (ChosenPivot != NULL) - { /* Reduced row has no elements, matrix is singular. */ + { + /* Reduced row has no elements, matrix is singular. */ break; } PivotMag = ELEMENT_MAG(ChosenPivot); if - ( PivotMag > Matrix->AbsThreshold AND + ( PivotMag > Matrix->AbsThreshold && PivotMag > Matrix->RelThreshold * FindBiggestInColExclude( Matrix, ChosenPivot, Step ) ) return ChosenPivot; } } -/* Singleton not acceptable (too small), try another. */ + /* Singleton not acceptable (too small), try another. */ } /* end of while(lSingletons>0) */ -/* + /* * All singletons were unacceptable. Restore Matrix->Singletons count. * Initial assumption that an acceptable singleton would be found was wrong. */ @@ -1361,24 +1323,24 @@ QuicklySearchDiagonal( Matrix, Step ) MatrixPtr Matrix; int Step; { -register long MinMarkowitzProduct, *pMarkowitzProduct; -register ElementPtr pDiag, pOtherInRow, pOtherInCol; +long MinMarkowitzProduct, *pMarkowitzProduct; + ElementPtr pDiag, pOtherInRow, pOtherInCol; int I, NumberOfTies; ElementPtr ChosenPivot, TiedElements[MAX_MARKOWITZ_TIES + 1]; RealNumber Magnitude, LargestInCol, Ratio, MaxRatio; RealNumber LargestOffDiagonal; RealNumber FindBiggestInColExclude(); -/* Begin `QuicklySearchDiagonal'. */ + /* Begin `QuicklySearchDiagonal'. */ NumberOfTies = -1; MinMarkowitzProduct = LARGEST_LONG_INTEGER; pMarkowitzProduct = &(Matrix->MarkowitzProd[Matrix->Size+2]); Matrix->MarkowitzProd[Matrix->Size+1] = Matrix->MarkowitzProd[Step]; -/* Assure that following while loop will always terminate. */ + /* Assure that following while loop will always terminate. */ Matrix->MarkowitzProd[Step-1] = -1; -/* + /* * This is tricky. Am using a pointer in the inner while loop to * sequentially step through the MarkowitzProduct array. Search * terminates when the Markowitz product of zero placed at location @@ -1398,8 +1360,10 @@ RealNumber FindBiggestInColExclude(); */ for(;;) /* Endless for loop. */ - { while (MinMarkowitzProduct < *(--pMarkowitzProduct)) - { /* + { + while (MinMarkowitzProduct < *(--pMarkowitzProduct)) + { + /* * N bottles of beer on the wall; * N bottles of beer. * You take one down and pass it around; @@ -1409,7 +1373,7 @@ RealNumber FindBiggestInColExclude(); I = pMarkowitzProduct - Matrix->MarkowitzProd; -/* Assure that I is valid; if I < Step, terminate search. */ + /* Assure that I is valid; if I < Step, terminate search. */ if (I < Step) break; /* Endless for loop */ if (I > Matrix->Size) I = Step; @@ -1420,35 +1384,40 @@ RealNumber FindBiggestInColExclude(); if (*pMarkowitzProduct == 1) { -/* Case where only one element exists in row and column other than diagonal. */ + /* Case where only one element exists in row and column other than diagonal. */ -/* Find off diagonal elements. */ + /* Find off diagonal elements. */ pOtherInRow = pDiag->NextInRow; pOtherInCol = pDiag->NextInCol; - if (pOtherInRow == NULL AND pOtherInCol == NULL) - { pOtherInRow = Matrix->FirstInRow[I]; + if (pOtherInRow == NULL && pOtherInCol == NULL) + { + pOtherInRow = Matrix->FirstInRow[I]; while(pOtherInRow != NULL) - { if (pOtherInRow->Col >= Step AND pOtherInRow->Col != I) + { + if (pOtherInRow->Col >= Step && pOtherInRow->Col != I) break; pOtherInRow = pOtherInRow->NextInRow; } pOtherInCol = Matrix->FirstInCol[I]; while(pOtherInCol != NULL) - { if (pOtherInCol->Row >= Step AND pOtherInCol->Row != I) + { + if (pOtherInCol->Row >= Step && pOtherInCol->Row != I) break; pOtherInCol = pOtherInCol->NextInCol; } } -/* Accept diagonal as pivot if diagonal is larger than off diagonals and the + /* Accept diagonal as pivot if diagonal is larger than off diagonals and the * off diagonals are placed symmetricly. */ - if (pOtherInRow != NULL AND pOtherInCol != NULL) - { if (pOtherInRow->Col == pOtherInCol->Row) - { LargestOffDiagonal = MAX(ELEMENT_MAG(pOtherInRow), + if (pOtherInRow != NULL && pOtherInCol != NULL) + { + if (pOtherInRow->Col == pOtherInCol->Row) + { + LargestOffDiagonal = MAX(ELEMENT_MAG(pOtherInRow), ELEMENT_MAG(pOtherInCol)); if (Magnitude >= LargestOffDiagonal) { -/* Accept pivot, it is unlikely to contribute excess error. */ + /* Accept pivot, it is unlikely to contribute excess error. */ return pDiag; } } @@ -1457,37 +1426,40 @@ RealNumber FindBiggestInColExclude(); if (*pMarkowitzProduct < MinMarkowitzProduct) { -/* Notice strict inequality in test. This is a new smallest MarkowitzProduct. */ + /* Notice strict inequality in test. This is a new smallest MarkowitzProduct. */ TiedElements[0] = pDiag; MinMarkowitzProduct = *pMarkowitzProduct; NumberOfTies = 0; } else { -/* This case handles Markowitz ties. */ + /* This case handles Markowitz ties. */ if (NumberOfTies < MAX_MARKOWITZ_TIES) - { TiedElements[++NumberOfTies] = pDiag; + { + TiedElements[++NumberOfTies] = pDiag; if (NumberOfTies >= MinMarkowitzProduct * TIES_MULTIPLIER) break; /* Endless for loop */ } } } /* End of endless for loop. */ -/* Test to see if any element was chosen as a pivot candidate. */ + /* Test to see if any element was chosen as a pivot candidate. */ if (NumberOfTies < 0) return NULL; -/* Determine which of tied elements is best numerically. */ + /* Determine which of tied elements is best numerically. */ ChosenPivot = NULL; MaxRatio = 1.0 / Matrix->RelThreshold; for (I = 0; I <= NumberOfTies; I++) - { pDiag = TiedElements[I]; + { + pDiag = TiedElements[I]; Magnitude = ELEMENT_MAG(pDiag); LargestInCol = FindBiggestInColExclude( Matrix, pDiag, Step ); Ratio = LargestInCol / Magnitude; if (Ratio < MaxRatio) - { ChosenPivot = pDiag; + { + ChosenPivot = pDiag; MaxRatio = Ratio; } } @@ -1560,23 +1532,23 @@ QuicklySearchDiagonal( Matrix, Step ) MatrixPtr Matrix; int Step; { -register long MinMarkowitzProduct, *pMarkowitzProduct; -register ElementPtr pDiag; +long MinMarkowitzProduct, *pMarkowitzProduct; + ElementPtr pDiag; int I; ElementPtr ChosenPivot, pOtherInRow, pOtherInCol; RealNumber Magnitude, LargestInCol, LargestOffDiagonal; RealNumber FindBiggestInColExclude(); -/* Begin `QuicklySearchDiagonal'. */ + /* Begin `QuicklySearchDiagonal'. */ ChosenPivot = NULL; MinMarkowitzProduct = LARGEST_LONG_INTEGER; pMarkowitzProduct = &(Matrix->MarkowitzProd[Matrix->Size+2]); Matrix->MarkowitzProd[Matrix->Size+1] = Matrix->MarkowitzProd[Step]; -/* Assure that following while loop will always terminate. */ + /* Assure that following while loop will always terminate. */ Matrix->MarkowitzProd[Step-1] = -1; -/* + /* * This is tricky. Am using a pointer in the inner while loop to * sequentially step through the MarkowitzProduct array. Search * terminates when the Markowitz product of zero placed at location @@ -1596,13 +1568,15 @@ RealNumber FindBiggestInColExclude(); */ for (;;) /* Endless for loop. */ - { while (*(--pMarkowitzProduct) >= MinMarkowitzProduct) - { /* Just passing through. */ + { + while (*(--pMarkowitzProduct) >= MinMarkowitzProduct) + { + /* Just passing through. */ } I = pMarkowitzProduct - Matrix->MarkowitzProd; -/* Assure that I is valid; if I < Step, terminate search. */ + /* Assure that I is valid; if I < Step, terminate search. */ if (I < Step) break; /* Endless for loop */ if (I > Matrix->Size) I = Step; @@ -1613,35 +1587,40 @@ RealNumber FindBiggestInColExclude(); if (*pMarkowitzProduct == 1) { -/* Case where only one element exists in row and column other than diagonal. */ + /* Case where only one element exists in row and column other than diagonal. */ -/* Find off-diagonal elements. */ + /* Find off-diagonal elements. */ pOtherInRow = pDiag->NextInRow; pOtherInCol = pDiag->NextInCol; - if (pOtherInRow == NULL AND pOtherInCol == NULL) - { pOtherInRow = Matrix->FirstInRow[I]; + if (pOtherInRow == NULL && pOtherInCol == NULL) + { + pOtherInRow = Matrix->FirstInRow[I]; while(pOtherInRow != NULL) - { if (pOtherInRow->Col >= Step AND pOtherInRow->Col != I) + { + if (pOtherInRow->Col >= Step && pOtherInRow->Col != I) break; pOtherInRow = pOtherInRow->NextInRow; } pOtherInCol = Matrix->FirstInCol[I]; while(pOtherInCol != NULL) - { if (pOtherInCol->Row >= Step AND pOtherInCol->Row != I) + { + if (pOtherInCol->Row >= Step && pOtherInCol->Row != I) break; pOtherInCol = pOtherInCol->NextInCol; } } -/* Accept diagonal as pivot if diagonal is larger than off-diagonals and the + /* Accept diagonal as pivot if diagonal is larger than off-diagonals and the * off-diagonals are placed symmetricly. */ - if (pOtherInRow != NULL AND pOtherInCol != NULL) - { if (pOtherInRow->Col == pOtherInCol->Row) - { LargestOffDiagonal = MAX(ELEMENT_MAG(pOtherInRow), + if (pOtherInRow != NULL && pOtherInCol != NULL) + { + if (pOtherInRow->Col == pOtherInCol->Row) + { + LargestOffDiagonal = MAX(ELEMENT_MAG(pOtherInRow), ELEMENT_MAG(pOtherInCol)); if (Magnitude >= LargestOffDiagonal) { -/* Accept pivot, it is unlikely to contribute excess error. */ + /* Accept pivot, it is unlikely to contribute excess error. */ return pDiag; } } @@ -1653,7 +1632,8 @@ RealNumber FindBiggestInColExclude(); } /* End of endless for loop. */ if (ChosenPivot != NULL) - { LargestInCol = FindBiggestInColExclude( Matrix, ChosenPivot, Step ); + { + LargestInCol = FindBiggestInColExclude( Matrix, ChosenPivot, Step ); if( ELEMENT_MAG(ChosenPivot) <= Matrix->RelThreshold * LargestInCol ) ChosenPivot = NULL; } @@ -1697,7 +1677,7 @@ RealNumber FindBiggestInColExclude(); * ChosenPivot (ElementPtr) * Pointer to the element that has been chosen to be the pivot. * Size (int) - * Local version of size which is placed in a register to increase speed. + * Local version of size which is placed in a to increase speed. * Magnitude (RealNumber) * Absolute value of diagonal element. * MinMarkowitzProduct (long) @@ -1723,24 +1703,28 @@ static ElementPtr SearchDiagonal( Matrix, Step ) MatrixPtr Matrix; -register int Step; +int Step; { -register int J; -register long MinMarkowitzProduct, *pMarkowitzProduct; -register int I; -register ElementPtr pDiag; -int NumberOfTies, Size = Matrix->Size; -ElementPtr ChosenPivot; -RealNumber Magnitude, Ratio, RatioOfAccepted, LargestInCol; -RealNumber FindBiggestInColExclude(); + int J; + long MinMarkowitzProduct, *pMarkowitzProduct; + int I; + ElementPtr pDiag; + int NumberOfTies = 0; + int Size = Matrix->Size; + + ElementPtr ChosenPivot; + RealNumber Magnitude, Ratio; + RealNumber RatioOfAccepted = 0; + RealNumber LargestInCol; + RealNumber FindBiggestInColExclude(); -/* Begin `SearchDiagonal'. */ + /* Begin `SearchDiagonal'. */ ChosenPivot = NULL; MinMarkowitzProduct = LARGEST_LONG_INTEGER; pMarkowitzProduct = &(Matrix->MarkowitzProd[Size+2]); Matrix->MarkowitzProd[Size+1] = Matrix->MarkowitzProd[Step]; -/* Start search of diagonal. */ + /* Start search of diagonal. */ for (J = Size+1; J > Step; J--) { if (*(--pMarkowitzProduct) > MinMarkowitzProduct) @@ -1754,14 +1738,15 @@ RealNumber FindBiggestInColExclude(); if ((Magnitude = ELEMENT_MAG(pDiag)) <= Matrix->AbsThreshold) continue; /* for loop */ -/* Test to see if diagonal's magnitude is acceptable. */ + /* Test to see if diagonal's magnitude is acceptable. */ LargestInCol = FindBiggestInColExclude( Matrix, pDiag, Step ); if (Magnitude <= Matrix->RelThreshold * LargestInCol) continue; /* for loop */ if (*pMarkowitzProduct < MinMarkowitzProduct) { -/* Notice strict inequality in test. This is a new smallest MarkowitzProduct. */ + /* Notice strict inequality in test. This is a new + smallest MarkowitzProduct. */ ChosenPivot = pDiag; MinMarkowitzProduct = *pMarkowitzProduct; RatioOfAccepted = LargestInCol / Magnitude; @@ -1769,11 +1754,12 @@ RealNumber FindBiggestInColExclude(); } else { -/* This case handles Markowitz ties. */ + /* This case handles Markowitz ties. */ NumberOfTies++; Ratio = LargestInCol / Magnitude; if (Ratio < RatioOfAccepted) - { ChosenPivot = pDiag; + { + ChosenPivot = pDiag; RatioOfAccepted = Ratio; } if (NumberOfTies >= MinMarkowitzProduct * TIES_MULTIPLIER) @@ -1821,7 +1807,7 @@ RealNumber FindBiggestInColExclude(); * LargestElementMag (RealNumber) * Magnitude of the largest element yet found in the reduced submatrix. * Size (int) - * Local version of Size; placed in a register for speed. + * Local version of Size; placed in a for speed. * Magnitude (RealNumber) * Absolute value of diagonal element. * MinMarkowitzProduct (long) @@ -1854,24 +1840,28 @@ SearchEntireMatrix( Matrix, Step ) MatrixPtr Matrix; int Step; { -register int I, Size = Matrix->Size; -register ElementPtr pElement; -int NumberOfTies; -long Product, MinMarkowitzProduct; -ElementPtr ChosenPivot, pLargestElement; -RealNumber Magnitude, LargestElementMag, Ratio, RatioOfAccepted, LargestInCol; -RealNumber FindLargestInCol(); + int I, Size = Matrix->Size; + ElementPtr pElement; + int NumberOfTies = 0; + long Product, MinMarkowitzProduct; + ElementPtr ChosenPivot; + ElementPtr pLargestElement = NULL; + RealNumber Magnitude, LargestElementMag, Ratio; + RealNumber RatioOfAccepted = 0; + RealNumber LargestInCol; + RealNumber FindLargestInCol(); -/* Begin `SearchEntireMatrix'. */ + /* Begin `SearchEntireMatrix'. */ ChosenPivot = NULL; LargestElementMag = 0.0; MinMarkowitzProduct = LARGEST_LONG_INTEGER; -/* Start search of matrix on column by column basis. */ + /* Start search of matrix on column by column basis. */ for (I = Step; I <= Size; I++) - { pElement = Matrix->FirstInCol[I]; + { + pElement = Matrix->FirstInCol[I]; - while (pElement != NULL AND pElement->Row < Step) + while (pElement != NULL && pElement->Row < Step) pElement = pElement->NextInCol; if((LargestInCol = FindLargestInCol(pElement)) == 0.0) @@ -1879,26 +1869,30 @@ RealNumber FindLargestInCol(); while (pElement != NULL) { -/* Check to see if element is the largest encountered so far. If so, record - its magnitude and address. */ + /* Check to see if element is the largest encountered so + far. If so, record its magnitude and address. */ if ((Magnitude = ELEMENT_MAG(pElement)) > LargestElementMag) - { LargestElementMag = Magnitude; + { + LargestElementMag = Magnitude; pLargestElement = pElement; } -/* Calculate element's MarkowitzProduct. */ + /* Calculate element's MarkowitzProduct. */ Product = Matrix->MarkowitzRow[pElement->Row] * - Matrix->MarkowitzCol[pElement->Col]; + Matrix->MarkowitzCol[pElement->Col]; -/* Test to see if element is acceptable as a pivot candidate. */ - if ((Product <= MinMarkowitzProduct) AND - (Magnitude > Matrix->RelThreshold * LargestInCol) AND + /* Test to see if element is acceptable as a pivot + candidate. */ + if ((Product <= MinMarkowitzProduct) && + (Magnitude > Matrix->RelThreshold * LargestInCol) && (Magnitude > Matrix->AbsThreshold)) { -/* Test to see if element has lowest MarkowitzProduct yet found, or whether it - is tied with an element found earlier. */ + /* Test to see if element has lowest MarkowitzProduct + yet found, or whether it is tied with an element + found earlier. */ if (Product < MinMarkowitzProduct) { -/* Notice strict inequality in test. This is a new smallest MarkowitzProduct. */ + /* Notice strict inequality in test. This is a new + smallest MarkowitzProduct. */ ChosenPivot = pElement; MinMarkowitzProduct = Product; RatioOfAccepted = LargestInCol / Magnitude; @@ -1906,11 +1900,12 @@ RealNumber FindLargestInCol(); } else { -/* This case handles Markowitz ties. */ + /* This case handles Markowitz ties. */ NumberOfTies++; Ratio = LargestInCol / Magnitude; if (Ratio < RatioOfAccepted) - { ChosenPivot = pElement; + { + ChosenPivot = pElement; RatioOfAccepted = Ratio; } if (NumberOfTies >= MinMarkowitzProduct * TIES_MULTIPLIER) @@ -1924,7 +1919,8 @@ RealNumber FindLargestInCol(); if (ChosenPivot != NULL) return ChosenPivot; if (LargestElementMag == 0.0) - { Matrix->Error = spSINGULAR; + { + Matrix->Error = spSINGULAR; return NULL; } @@ -1946,14 +1942,14 @@ RealNumber FindLargestInCol(); /* * DETERMINE THE MAGNITUDE OF THE LARGEST ELEMENT IN A COLUMN * - * This routine searches a column and returns the magnitude of the largest - * element. This routine begins the search at the element pointed to by - * pElement, the parameter. + * This routine searches a column and returns the magnitude of the + * largest element. This routine begins the search at the element + * pointed to by pElement, the parameter. * - * The search is conducted by starting at the element specified by a pointer, - * which should be one below the diagonal, and moving down the column. On - * the way down the column, the magnitudes of the elements are tested to see - * if they are the largest yet found. + * The search is conducted by starting at the element specified by a + * pointer, which should be one below the diagonal, and moving down + * the column. On the way down the column, the magnitudes of the + * elements are tested to see if they are the largest yet found. * * >>> Returned: * The magnitude of the largest element in the column below and including @@ -1968,20 +1964,20 @@ RealNumber FindLargestInCol(); * Largest (RealNumber) * The magnitude of the largest element. * Magnitude (RealNumber) - * The magnitude of the currently active element. - */ + * The magnitude of the currently active element. */ static RealNumber FindLargestInCol( pElement ) -register ElementPtr pElement; + ElementPtr pElement; { -RealNumber Magnitude, Largest = 0.0; + RealNumber Magnitude, Largest = 0.0; -/* Begin `FindLargestInCol'. */ -/* Search column for largest element beginning at Element. */ + /* Begin `FindLargestInCol'. */ + /* Search column for largest element beginning at Element. */ while (pElement != NULL) - { if ((Magnitude = ELEMENT_MAG(pElement)) > Largest) + { + if ((Magnitude = ELEMENT_MAG(pElement)) > Largest) Largest = Magnitude; pElement = pElement->NextInCol; } @@ -2041,32 +2037,34 @@ static RealNumber FindBiggestInColExclude( Matrix, pElement, Step ) MatrixPtr Matrix; -register ElementPtr pElement; -register int Step; + ElementPtr pElement; + int Step; { -register int Row; + int Row; int Col; RealNumber Largest, Magnitude; -/* Begin `FindBiggestInColExclude'. */ + /* Begin `FindBiggestInColExclude'. */ Row = pElement->Row; Col = pElement->Col; pElement = Matrix->FirstInCol[Col]; -/* Travel down column until reduced submatrix is entered. */ - while ((pElement != NULL) AND (pElement->Row < Step)) + /* Travel down column until reduced submatrix is entered. */ + while ((pElement != NULL) && (pElement->Row < Step)) pElement = pElement->NextInCol; -/* Initialize the variable Largest. */ + /* Initialize the variable Largest. */ if (pElement->Row != Row) Largest = ELEMENT_MAG(pElement); else Largest = 0.0; -/* Search rest of column for largest element, avoiding excluded element. */ + /* Search rest of column for largest element, avoiding excluded element. */ while ((pElement = pElement->NextInCol) != NULL) - { if ((Magnitude = ELEMENT_MAG(pElement)) > Largest) - { if (pElement->Row != Row) + { + if ((Magnitude = ELEMENT_MAG(pElement)) > Largest) + { + if (pElement->Row != Row) Largest = Magnitude; } } @@ -2119,23 +2117,24 @@ ExchangeRowsAndCols( Matrix, pPivot, Step ) MatrixPtr Matrix; ElementPtr pPivot; -register int Step; +int Step; { -register int Row, Col; + int Row, Col; long OldMarkowitzProd_Step, OldMarkowitzProd_Row, OldMarkowitzProd_Col; ElementPtr spcFindElementInCol(); -/* Begin `ExchangeRowsAndCols'. */ + /* Begin `ExchangeRowsAndCols'. */ Row = pPivot->Row; Col = pPivot->Col; Matrix->PivotsOriginalRow = Row; Matrix->PivotsOriginalCol = Col; - if ((Row == Step) AND (Col == Step)) return; + if ((Row == Step) && (Col == Step)) return; -/* Exchange rows and columns. */ + /* Exchange rows and columns. */ if (Row == Col) - { spcRowExchange( Matrix, Step, Row ); + { + spcRowExchange( Matrix, Step, Row ); spcColExchange( Matrix, Step, Col ); SWAP( long, Matrix->MarkowitzProd[Step], Matrix->MarkowitzProd[Row] ); SWAP( ElementPtr, Matrix->Diag[Row], Matrix->Diag[Step] ); @@ -2143,39 +2142,43 @@ ElementPtr spcFindElementInCol(); else { -/* Initialize variables that hold old Markowitz products. */ + /* Initialize variables that hold old Markowitz products. */ OldMarkowitzProd_Step = Matrix->MarkowitzProd[Step]; OldMarkowitzProd_Row = Matrix->MarkowitzProd[Row]; OldMarkowitzProd_Col = Matrix->MarkowitzProd[Col]; -/* Exchange rows. */ + /* Exchange rows. */ if (Row != Step) - { spcRowExchange( Matrix, Step, Row ); + { + spcRowExchange( Matrix, Step, Row ); Matrix->NumberOfInterchangesIsOdd = - NOT Matrix->NumberOfInterchangesIsOdd; + !Matrix->NumberOfInterchangesIsOdd; Matrix->MarkowitzProd[Row] = Matrix->MarkowitzRow[Row] * Matrix->MarkowitzCol[Row]; -/* Update singleton count. */ + /* Update singleton count. */ if ((Matrix->MarkowitzProd[Row]==0) != (OldMarkowitzProd_Row==0)) - { if (OldMarkowitzProd_Row == 0) + { + if (OldMarkowitzProd_Row == 0) Matrix->Singletons--; else Matrix->Singletons++; } } -/* Exchange columns. */ + /* Exchange columns. */ if (Col != Step) - { spcColExchange( Matrix, Step, Col ); + { + spcColExchange( Matrix, Step, Col ); Matrix->NumberOfInterchangesIsOdd = - NOT Matrix->NumberOfInterchangesIsOdd; + !Matrix->NumberOfInterchangesIsOdd; Matrix->MarkowitzProd[Col] = Matrix->MarkowitzCol[Col] * Matrix->MarkowitzRow[Col]; -/* Update singleton count. */ + /* Update singleton count. */ if ((Matrix->MarkowitzProd[Col]==0) != (OldMarkowitzProd_Col==0)) - { if (OldMarkowitzProd_Col == 0) + { + if (OldMarkowitzProd_Col == 0) Matrix->Singletons--; else Matrix->Singletons++; @@ -2186,7 +2189,8 @@ ElementPtr spcFindElementInCol(); Col, Col, NO ); } if (Row != Step) - { Matrix->Diag[Row] = spcFindElementInCol( Matrix, + { + Matrix->Diag[Row] = spcFindElementInCol( Matrix, Matrix->FirstInCol+Row, Row, Row, NO ); } @@ -2194,11 +2198,12 @@ ElementPtr spcFindElementInCol(); Matrix->FirstInCol+Step, Step, Step, NO ); -/* Update singleton count. */ + /* Update singleton count. */ Matrix->MarkowitzProd[Step] = Matrix->MarkowitzCol[Step] * Matrix->MarkowitzRow[Step]; if ((Matrix->MarkowitzProd[Step]==0) != (OldMarkowitzProd_Step==0)) - { if (OldMarkowitzProd_Step == 0) + { + if (OldMarkowitzProd_Step == 0) Matrix->Singletons--; else Matrix->Singletons++; @@ -2250,44 +2255,49 @@ spcRowExchange( Matrix, Row1, Row2 ) MatrixPtr Matrix; int Row1, Row2; { -register ElementPtr Row1Ptr, Row2Ptr; + ElementPtr Row1Ptr, Row2Ptr; int Column; ElementPtr Element1, Element2; -/* Begin `spcRowExchange'. */ + /* Begin `spcRowExchange'. */ if (Row1 > Row2) SWAP(int, Row1, Row2); Row1Ptr = Matrix->FirstInRow[Row1]; Row2Ptr = Matrix->FirstInRow[Row2]; - while (Row1Ptr != NULL OR Row2Ptr != NULL) + while (Row1Ptr != NULL || Row2Ptr != NULL) { -/* Exchange elements in rows while traveling from left to right. */ + /* Exchange elements in rows while traveling from left to right. */ if (Row1Ptr == NULL) - { Column = Row2Ptr->Col; + { + Column = Row2Ptr->Col; Element1 = NULL; Element2 = Row2Ptr; Row2Ptr = Row2Ptr->NextInRow; } else if (Row2Ptr == NULL) - { Column = Row1Ptr->Col; + { + Column = Row1Ptr->Col; Element1 = Row1Ptr; Element2 = NULL; Row1Ptr = Row1Ptr->NextInRow; } else if (Row1Ptr->Col < Row2Ptr->Col) - { Column = Row1Ptr->Col; + { + Column = Row1Ptr->Col; Element1 = Row1Ptr; Element2 = NULL; Row1Ptr = Row1Ptr->NextInRow; } else if (Row1Ptr->Col > Row2Ptr->Col) - { Column = Row2Ptr->Col; + { + Column = Row2Ptr->Col; Element1 = NULL; Element2 = Row2Ptr; Row2Ptr = Row2Ptr->NextInRow; } else /* Row1Ptr->Col == Row2Ptr->Col */ - { Column = Row1Ptr->Col; + { + Column = Row1Ptr->Col; Element1 = Row1Ptr; Element2 = Row2Ptr; Row1Ptr = Row1Ptr->NextInRow; @@ -2295,7 +2305,7 @@ ElementPtr Element1, Element2; } ExchangeColElements( Matrix, Row1, Element1, Row2, Element2, Column); - } /* end of while(Row1Ptr != NULL OR Row2Ptr != NULL) */ + } /* end of while(Row1Ptr != NULL || Row2Ptr != NULL) */ if (Matrix->InternalVectorsAllocated) SWAP( int, Matrix->MarkowitzRow[Row1], Matrix->MarkowitzRow[Row2]); @@ -2352,44 +2362,49 @@ spcColExchange( Matrix, Col1, Col2 ) MatrixPtr Matrix; int Col1, Col2; { -register ElementPtr Col1Ptr, Col2Ptr; + ElementPtr Col1Ptr, Col2Ptr; int Row; ElementPtr Element1, Element2; -/* Begin `spcColExchange'. */ + /* Begin `spcColExchange'. */ if (Col1 > Col2) SWAP(int, Col1, Col2); Col1Ptr = Matrix->FirstInCol[Col1]; Col2Ptr = Matrix->FirstInCol[Col2]; - while (Col1Ptr != NULL OR Col2Ptr != NULL) + while (Col1Ptr != NULL || Col2Ptr != NULL) { -/* Exchange elements in rows while traveling from top to bottom. */ + /* Exchange elements in rows while traveling from top to bottom. */ if (Col1Ptr == NULL) - { Row = Col2Ptr->Row; + { + Row = Col2Ptr->Row; Element1 = NULL; Element2 = Col2Ptr; Col2Ptr = Col2Ptr->NextInCol; } else if (Col2Ptr == NULL) - { Row = Col1Ptr->Row; + { + Row = Col1Ptr->Row; Element1 = Col1Ptr; Element2 = NULL; Col1Ptr = Col1Ptr->NextInCol; } else if (Col1Ptr->Row < Col2Ptr->Row) - { Row = Col1Ptr->Row; + { + Row = Col1Ptr->Row; Element1 = Col1Ptr; Element2 = NULL; Col1Ptr = Col1Ptr->NextInCol; } else if (Col1Ptr->Row > Col2Ptr->Row) - { Row = Col2Ptr->Row; + { + Row = Col2Ptr->Row; Element1 = NULL; Element2 = Col2Ptr; Col2Ptr = Col2Ptr->NextInCol; } else /* Col1Ptr->Row == Col2Ptr->Row */ - { Row = Col1Ptr->Row; + { + Row = Col1Ptr->Row; Element1 = Col1Ptr; Element2 = Col2Ptr; Col1Ptr = Col1Ptr->NextInCol; @@ -2397,7 +2412,7 @@ ElementPtr Element1, Element2; } ExchangeRowElements( Matrix, Col1, Element1, Col2, Element2, Row); - } /* end of while(Col1Ptr != NULL OR Col2Ptr != NULL) */ + } /* end of while(Col1Ptr != NULL || Col2Ptr != NULL) */ if (Matrix->InternalVectorsAllocated) SWAP( int, Matrix->MarkowitzCol[Col1], Matrix->MarkowitzCol[Col2]); @@ -2457,39 +2472,42 @@ static void ExchangeColElements( Matrix, Row1, Element1, Row2, Element2, Column ) MatrixPtr Matrix; -register ElementPtr Element1, Element2; + ElementPtr Element1, Element2; int Row1, Row2, Column; { ElementPtr *ElementAboveRow1, *ElementAboveRow2; ElementPtr ElementBelowRow1, ElementBelowRow2; -register ElementPtr pElement; + ElementPtr pElement; -/* Begin `ExchangeColElements'. */ -/* Search to find the ElementAboveRow1. */ + /* Begin `ExchangeColElements'. */ + /* Search to find the ElementAboveRow1. */ ElementAboveRow1 = &(Matrix->FirstInCol[Column]); pElement = *ElementAboveRow1; while (pElement->Row < Row1) - { ElementAboveRow1 = &(pElement->NextInCol); + { + ElementAboveRow1 = &(pElement->NextInCol); pElement = *ElementAboveRow1; } if (Element1 != NULL) - { ElementBelowRow1 = Element1->NextInCol; + { + ElementBelowRow1 = Element1->NextInCol; if (Element2 == NULL) { -/* Element2 does not exist, move Element1 down to Row2. */ - if ( ElementBelowRow1 != NULL AND ElementBelowRow1->Row < Row2 ) + /* Element2 does not exist, move Element1 down to Row2. */ + if ( ElementBelowRow1 != NULL && ElementBelowRow1->Row < Row2 ) { -/* Element1 must be removed from linked list and moved. */ + /* Element1 must be removed from linked list and moved. */ *ElementAboveRow1 = ElementBelowRow1; -/* Search column for Row2. */ + /* Search column for Row2. */ pElement = ElementBelowRow1; do - { ElementAboveRow2 = &(pElement->NextInCol); + { + ElementAboveRow2 = &(pElement->NextInCol); pElement = *ElementAboveRow2; - } while (pElement != NULL AND pElement->Row < Row2); + } while (pElement != NULL && pElement->Row < Row2); -/* Place Element1 in Row2. */ + /* Place Element1 in Row2. */ *ElementAboveRow2 = Element1; Element1->NextInCol = pElement; *ElementAboveRow1 =ElementBelowRow1; @@ -2498,26 +2516,27 @@ register ElementPtr pElement; } else { -/* Element2 does exist, and the two elements must be exchanged. */ + /* Element2 does exist, and the two elements must be exchanged. */ if ( ElementBelowRow1->Row == Row2) { -/* Element2 is just below Element1, exchange them. */ + /* Element2 is just below Element1, exchange them. */ Element1->NextInCol = Element2->NextInCol; Element2->NextInCol = Element1; *ElementAboveRow1 = Element2; } else { -/* Element2 is not just below Element1 and must be searched for. */ + /* Element2 is not just below Element1 and must be searched for. */ pElement = ElementBelowRow1; do - { ElementAboveRow2 = &(pElement->NextInCol); + { + ElementAboveRow2 = &(pElement->NextInCol); pElement = *ElementAboveRow2; } while (pElement->Row < Row2); ElementBelowRow2 = Element2->NextInCol; -/* Switch Element1 and Element2. */ + /* Switch Element1 and Element2. */ *ElementAboveRow1 = Element2; Element2->NextInCol = ElementBelowRow1; *ElementAboveRow2 = Element1; @@ -2529,19 +2548,21 @@ register ElementPtr pElement; } else { -/* Element1 does not exist. */ + /* Element1 does not exist. */ ElementBelowRow1 = pElement; -/* Find Element2. */ + /* Find Element2. */ if (ElementBelowRow1->Row != Row2) - { do - { ElementAboveRow2 = &(pElement->NextInCol); + { + do + { + ElementAboveRow2 = &(pElement->NextInCol); pElement = *ElementAboveRow2; } while (pElement->Row < Row2); ElementBelowRow2 = Element2->NextInCol; -/* Move Element2 to Row1. */ + /* Move Element2 to Row1. */ *ElementAboveRow2 = Element2->NextInCol; *ElementAboveRow1 = Element2; Element2->NextInCol = ElementBelowRow1; @@ -2600,38 +2621,41 @@ ExchangeRowElements( Matrix, Col1, Element1, Col2, Element2, Row ) MatrixPtr Matrix; int Col1, Col2, Row; -register ElementPtr Element1, Element2; +ElementPtr Element1, Element2; { ElementPtr *ElementLeftOfCol1, *ElementLeftOfCol2; ElementPtr ElementRightOfCol1, ElementRightOfCol2; -register ElementPtr pElement; + ElementPtr pElement; -/* Begin `ExchangeRowElements'. */ -/* Search to find the ElementLeftOfCol1. */ + /* Begin `ExchangeRowElements'. */ + /* Search to find the ElementLeftOfCol1. */ ElementLeftOfCol1 = &(Matrix->FirstInRow[Row]); pElement = *ElementLeftOfCol1; while (pElement->Col < Col1) - { ElementLeftOfCol1 = &(pElement->NextInRow); + { + ElementLeftOfCol1 = &(pElement->NextInRow); pElement = *ElementLeftOfCol1; } if (Element1 != NULL) - { ElementRightOfCol1 = Element1->NextInRow; + { + ElementRightOfCol1 = Element1->NextInRow; if (Element2 == NULL) { -/* Element2 does not exist, move Element1 to right to Col2. */ - if ( ElementRightOfCol1 != NULL AND ElementRightOfCol1->Col < Col2 ) + /* Element2 does not exist, move Element1 to right to Col2. */ + if ( ElementRightOfCol1 != NULL && ElementRightOfCol1->Col < Col2 ) { -/* Element1 must be removed from linked list and moved. */ + /* Element1 must be removed from linked list and moved. */ *ElementLeftOfCol1 = ElementRightOfCol1; -/* Search Row for Col2. */ + /* Search Row for Col2. */ pElement = ElementRightOfCol1; do - { ElementLeftOfCol2 = &(pElement->NextInRow); + { + ElementLeftOfCol2 = &(pElement->NextInRow); pElement = *ElementLeftOfCol2; - } while (pElement != NULL AND pElement->Col < Col2); + } while (pElement != NULL && pElement->Col < Col2); -/* Place Element1 in Col2. */ + /* Place Element1 in Col2. */ *ElementLeftOfCol2 = Element1; Element1->NextInRow = pElement; *ElementLeftOfCol1 =ElementRightOfCol1; @@ -2640,26 +2664,27 @@ register ElementPtr pElement; } else { -/* Element2 does exist, and the two elements must be exchanged. */ + /* Element2 does exist, and the two elements must be exchanged. */ if ( ElementRightOfCol1->Col == Col2) { -/* Element2 is just right of Element1, exchange them. */ + /* Element2 is just right of Element1, exchange them. */ Element1->NextInRow = Element2->NextInRow; Element2->NextInRow = Element1; *ElementLeftOfCol1 = Element2; } else { -/* Element2 is not just right of Element1 and must be searched for. */ + /* Element2 is not just right of Element1 and must be searched for. */ pElement = ElementRightOfCol1; do - { ElementLeftOfCol2 = &(pElement->NextInRow); + { + ElementLeftOfCol2 = &(pElement->NextInRow); pElement = *ElementLeftOfCol2; } while (pElement->Col < Col2); ElementRightOfCol2 = Element2->NextInRow; -/* Switch Element1 and Element2. */ + /* Switch Element1 and Element2. */ *ElementLeftOfCol1 = Element2; Element2->NextInRow = ElementRightOfCol1; *ElementLeftOfCol2 = Element1; @@ -2671,19 +2696,21 @@ register ElementPtr pElement; } else { -/* Element1 does not exist. */ + /* Element1 does not exist. */ ElementRightOfCol1 = pElement; -/* Find Element2. */ + /* Find Element2. */ if (ElementRightOfCol1->Col != Col2) - { do - { ElementLeftOfCol2 = &(pElement->NextInRow); + { + do + { + ElementLeftOfCol2 = &(pElement->NextInRow); pElement = *ElementLeftOfCol2; } while (pElement->Col < Col2); ElementRightOfCol2 = Element2->NextInRow; -/* Move Element2 to Col1. */ + /* Move Element2 to Col1. */ *ElementLeftOfCol2 = Element2->NextInRow; *ElementLeftOfCol1 = Element2; Element2->NextInRow = ElementRightOfCol1; @@ -2734,19 +2761,19 @@ static void RealRowColElimination( Matrix, pPivot ) MatrixPtr Matrix; -register ElementPtr pPivot; + ElementPtr pPivot; { -#if REAL -register ElementPtr pSub; -register int Row; -register ElementPtr pLower, pUpper; -extern ElementPtr CreateFillin(); + ElementPtr pSub; + int Row; + ElementPtr pLower, pUpper; + extern ElementPtr CreateFillin(); -/* Begin `RealRowColElimination'. */ + /* Begin `RealRowColElimination'. */ -/* Test for zero pivot. */ + /* Test for zero pivot. */ if (ABS(pPivot->Real) == 0.0) - { (void)MatrixIsSingular( Matrix, pPivot->Row ); + { + (void)MatrixIsSingular( Matrix, pPivot->Row ); return; } pPivot->Real = 1.0 / pPivot->Real; @@ -2754,23 +2781,26 @@ extern ElementPtr CreateFillin(); pUpper = pPivot->NextInRow; while (pUpper != NULL) { -/* Calculate upper triangular element. */ + /* Calculate upper triangular element. */ pUpper->Real *= pPivot->Real; pSub = pUpper->NextInCol; pLower = pPivot->NextInCol; while (pLower != NULL) - { Row = pLower->Row; + { + Row = pLower->Row; -/* Find element in row that lines up with current lower triangular element. */ - while (pSub != NULL AND pSub->Row < Row) + /* Find element in row that lines up with current lower triangular element. */ + while (pSub != NULL && pSub->Row < Row) pSub = pSub->NextInCol; -/* Test to see if desired element was not found, if not, create fill-in. */ - if (pSub == NULL OR pSub->Row > Row) - { pSub = CreateFillin( Matrix, Row, pUpper->Col ); + /* Test to see if desired element was not found, if not, create fill-in. */ + if (pSub == NULL || pSub->Row > Row) + { + pSub = CreateFillin( Matrix, Row, pUpper->Col ); if (pSub == NULL) - { Matrix->Error = spNO_MEMORY; + { + Matrix->Error = spNO_MEMORY; return; } } @@ -2781,7 +2811,6 @@ extern ElementPtr CreateFillin(); pUpper = pUpper->NextInRow; } return; -#endif /* REAL */ } @@ -2823,19 +2852,19 @@ static void ComplexRowColElimination( Matrix, pPivot ) MatrixPtr Matrix; -register ElementPtr pPivot; + ElementPtr pPivot; { -#if spCOMPLEX -register ElementPtr pSub; -register int Row; -register ElementPtr pLower, pUpper; -ElementPtr CreateFillin(); + ElementPtr pSub; + int Row; + ElementPtr pLower, pUpper; + ElementPtr CreateFillin(); -/* Begin `ComplexRowColElimination'. */ + /* Begin `ComplexRowColElimination'. */ -/* Test for zero pivot. */ + /* Test for zero pivot. */ if (ELEMENT_MAG(pPivot) == 0.0) - { (void)MatrixIsSingular( Matrix, pPivot->Row ); + { + (void)MatrixIsSingular( Matrix, pPivot->Row ); return; } CMPLX_RECIPROCAL(*pPivot, *pPivot); @@ -2843,29 +2872,32 @@ ElementPtr CreateFillin(); pUpper = pPivot->NextInRow; while (pUpper != NULL) { -/* Calculate upper triangular element. */ -/* Cmplx expr: *pUpper = *pUpper * (1.0 / *pPivot). */ + /* Calculate upper triangular element. */ + /* Cmplx expr: *pUpper = *pUpper * (1.0 / *pPivot). */ CMPLX_MULT_ASSIGN(*pUpper, *pPivot); pSub = pUpper->NextInCol; pLower = pPivot->NextInCol; while (pLower != NULL) - { Row = pLower->Row; + { + Row = pLower->Row; -/* Find element in row that lines up with current lower triangular element. */ - while (pSub != NULL AND pSub->Row < Row) + /* Find element in row that lines up with current lower triangular element. */ + while (pSub != NULL && pSub->Row < Row) pSub = pSub->NextInCol; -/* Test to see if desired element was not found, if not, create fill-in. */ - if (pSub == NULL OR pSub->Row > Row) - { pSub = CreateFillin( Matrix, Row, pUpper->Col ); + /* Test to see if desired element was not found, if not, create fill-in. */ + if (pSub == NULL || pSub->Row > Row) + { + pSub = CreateFillin( Matrix, Row, pUpper->Col ); if (pSub == NULL) - { Matrix->Error = spNO_MEMORY; + { + Matrix->Error = spNO_MEMORY; return; } } -/* Cmplx expr: pElement -= *pUpper * pLower. */ + /* Cmplx expr: pElement -= *pUpper * pLower. */ CMPLX_MULT_SUBT_ASSIGN(*pSub, *pUpper, *pLower); pSub = pSub->NextInCol; pLower = pLower->NextInCol; @@ -2873,7 +2905,6 @@ ElementPtr CreateFillin(); pUpper = pUpper->NextInRow; } return; -#endif /* spCOMPLEX */ } @@ -2909,22 +2940,25 @@ UpdateMarkowitzNumbers( Matrix, pPivot ) MatrixPtr Matrix; ElementPtr pPivot; { -register int Row, Col; -register ElementPtr ColPtr, RowPtr; -register int *MarkoRow = Matrix->MarkowitzRow, *MarkoCol = Matrix->MarkowitzCol; -double Product; + int Row, Col; + ElementPtr ColPtr, RowPtr; + int *MarkoRow = Matrix->MarkowitzRow; + int *MarkoCol = Matrix->MarkowitzCol; + double Product; -/* Begin `UpdateMarkowitzNumbers'. */ + /* Begin `UpdateMarkowitzNumbers'. */ -/* Update Markowitz numbers. */ + /* Update Markowitz numbers. */ for (ColPtr = pPivot->NextInCol; ColPtr != NULL; ColPtr = ColPtr->NextInCol) - { Row = ColPtr->Row; + { + Row = ColPtr->Row; --MarkoRow[Row]; -/* Form Markowitz product while being cautious of overflows. */ - if ((MarkoRow[Row] > LARGEST_SHORT_INTEGER AND MarkoCol[Row] != 0) OR - (MarkoCol[Row] > LARGEST_SHORT_INTEGER AND MarkoRow[Row] != 0)) - { Product = MarkoCol[Row] * MarkoRow[Row]; + /* Form Markowitz product while being cautious of overflows. */ + if ((MarkoRow[Row] > LARGEST_SHORT_INTEGER && MarkoCol[Row] != 0) || + (MarkoCol[Row] > LARGEST_SHORT_INTEGER && MarkoRow[Row] != 0)) + { + Product = MarkoCol[Row] * MarkoRow[Row]; if (Product >= LARGEST_LONG_INTEGER) Matrix->MarkowitzProd[Row] = LARGEST_LONG_INTEGER; else @@ -2935,21 +2969,23 @@ double Product; Matrix->Singletons++; } - for (RowPtr = pPivot->NextInRow; RowPtr != NULL; RowPtr = RowPtr->NextInRow) - { Col = RowPtr->Col; + for (RowPtr = pPivot->NextInRow; + RowPtr != NULL; + RowPtr = RowPtr->NextInRow) { + Col = RowPtr->Col; --MarkoCol[Col]; -/* Form Markowitz product while being cautious of overflows. */ - if ((MarkoRow[Col] > LARGEST_SHORT_INTEGER AND MarkoCol[Col] != 0) OR - (MarkoCol[Col] > LARGEST_SHORT_INTEGER AND MarkoRow[Col] != 0)) - { Product = MarkoCol[Col] * MarkoRow[Col]; + /* Form Markowitz product while being cautious of overflows. */ + if ((MarkoRow[Col] > LARGEST_SHORT_INTEGER && MarkoCol[Col] != 0) || + (MarkoCol[Col] > LARGEST_SHORT_INTEGER && MarkoRow[Col] != 0)) { + Product = MarkoCol[Col] * MarkoRow[Col]; if (Product >= LARGEST_LONG_INTEGER) Matrix->MarkowitzProd[Col] = LARGEST_LONG_INTEGER; else Matrix->MarkowitzProd[Col] = Product; } else Matrix->MarkowitzProd[Col] = MarkoRow[Col] * MarkoCol[Col]; - if ((MarkoCol[Col] == 0) AND (MarkoRow[Col] != 0)) + if ((MarkoCol[Col] == 0) && (MarkoRow[Col] != 0)) Matrix->Singletons++; } return; @@ -2995,36 +3031,38 @@ static ElementPtr CreateFillin( Matrix, Row, Col ) MatrixPtr Matrix; -register int Row; +int Row; int Col; { -register ElementPtr pElement, *ppElementAbove; + ElementPtr pElement, *ppElementAbove; ElementPtr spcCreateElement(); -/* Begin `CreateFillin'. */ + /* Begin `CreateFillin'. */ -/* Find Element above fill-in. */ + /* Find Element above fill-in. */ ppElementAbove = &Matrix->FirstInCol[Col]; pElement = *ppElementAbove; while (pElement != NULL) - { if (pElement->Row < Row) - { ppElementAbove = &pElement->NextInCol; + { + if (pElement->Row < Row) + { + ppElementAbove = &pElement->NextInCol; pElement = *ppElementAbove; } else break; /* while loop */ } -/* End of search, create the element. */ + /* End of search, create the element. */ pElement = spcCreateElement( Matrix, Row, Col, ppElementAbove, YES ); -/* Update Markowitz counts and products. */ + /* Update Markowitz counts and products. */ Matrix->MarkowitzProd[Row] = ++Matrix->MarkowitzRow[Row] * Matrix->MarkowitzCol[Row]; - if ((Matrix->MarkowitzRow[Row] == 1) AND (Matrix->MarkowitzCol[Row] != 0)) + if ((Matrix->MarkowitzRow[Row] == 1) && (Matrix->MarkowitzCol[Row] != 0)) Matrix->Singletons--; Matrix->MarkowitzProd[Col] = ++Matrix->MarkowitzCol[Col] * Matrix->MarkowitzRow[Col]; - if ((Matrix->MarkowitzRow[Col] != 0) AND (Matrix->MarkowitzCol[Col] == 1)) + if ((Matrix->MarkowitzRow[Col] != 0) && (Matrix->MarkowitzCol[Col] == 1)) Matrix->Singletons--; return pElement; @@ -3059,7 +3097,7 @@ MatrixIsSingular( Matrix, Step ) MatrixPtr Matrix; int Step; { -/* Begin `MatrixIsSingular'. */ + /* Begin `MatrixIsSingular'. */ Matrix->SingularRow = Matrix->IntToExtRowMap[ Step ]; Matrix->SingularCol = Matrix->IntToExtColMap[ Step ]; @@ -3073,7 +3111,7 @@ ZeroPivot( Matrix, Step ) MatrixPtr Matrix; int Step; { -/* Begin `ZeroPivot'. */ + /* Begin `ZeroPivot'. */ Matrix->SingularRow = Matrix->IntToExtRowMap[ Step ]; Matrix->SingularCol = Matrix->IntToExtColMap[ Step ]; @@ -3102,13 +3140,14 @@ int Step; { int I; -/* Begin `WriteStatus'. */ + /* Begin `WriteStatus'. */ printf("Step = %1d ", Step); printf("Pivot found at %1d,%1d using ", Matrix->PivotsOriginalRow, Matrix->PivotsOriginalCol); switch(Matrix->PivotSelectionMethod) - { case 's': printf("SearchForSingleton\n"); break; + { + case 's': printf("SearchForSingleton\n"); break; case 'q': printf("QuicklySearchDiagonal\n"); break; case 'd': printf("SearchDiagonal\n"); break; case 'e': printf("SearchEntireMatrix\n"); break; @@ -3151,8 +3190,6 @@ int I; printf("%2d ", Matrix->ExtToIntColMap[I]); printf("\n\n"); -/* spPrint((char *)Matrix, NO, YES); */ - return; } diff --git a/src/maths/sparse/spoutput.c b/src/maths/sparse/spoutput.c index 35cb3fd98..51ba12973 100644 --- a/src/maths/sparse/spoutput.c +++ b/src/maths/sparse/spoutput.c @@ -34,14 +34,6 @@ * or implied warranty. */ -#ifdef notdef -static char copyright[] = - "Sparse1.3: Copyright (c) 1985,86,87,88,89,90 by Kenneth S. Kundert"; -static char RCSid[] = - "$Header$"; -#endif - - /* * IMPORTS * @@ -53,6 +45,7 @@ static char RCSid[] = * spDefs.h * Matrix type and macro definitions for the sparse matrix routines. */ +#include #define spINSIDE_SPARSE #include "spconfig.h" @@ -138,30 +131,32 @@ int Printer_Width = PRINTER_WIDTH; */ void -spPrint( eMatrix, PrintReordered, Data, Header ) - -char *eMatrix; -int PrintReordered, Data, Header; +spPrint(void *eMatrix, int PrintReordered, int Data, int Header) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register int J = 0; -int I, Row, Col, Size, Top, StartCol = 1, StopCol, Columns, ElementCount = 0; -double Magnitude, SmallestDiag, SmallestElement; -double LargestElement = 0.0, LargestDiag = 0.0; -ElementPtr pElement, *pImagElements; -int *PrintOrdToIntRowMap, *PrintOrdToIntColMap; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + int J = 0; + int I, Row, Col, Size, Top; + int StartCol = 1, StopCol, Columns, ElementCount = 0; + double Magnitude; + double SmallestDiag = 0; + double SmallestElement = 0; + double LargestElement = 0.0, LargestDiag = 0.0; + ElementPtr pElement, *pImagElements; + int *PrintOrdToIntRowMap, *PrintOrdToIntColMap; -/* Begin `spPrint'. */ - ASSERT( IS_SPARSE( Matrix ) ); + /* Begin `spPrint'. */ + assert( IS_SPARSE( Matrix ) ); Size = Matrix->Size; CALLOC(pImagElements, ElementPtr, Printer_Width / 10 + 1); if ( pImagElements == NULL) - { Matrix->Error = spNO_MEMORY; + { + Matrix->Error = spNO_MEMORY; FREE(pImagElements); return; } -/* Create a packed external to internal row and column translation array. */ + /* Create a packed external to internal row and column translation + array. */ # if TRANSLATE Top = Matrix->AllocatedExtSize; #else @@ -169,37 +164,43 @@ int *PrintOrdToIntRowMap, *PrintOrdToIntColMap; #endif CALLOC( PrintOrdToIntRowMap, int, Top + 1 ); if ( PrintOrdToIntRowMap == NULL) - { Matrix->Error = spNO_MEMORY; + { + Matrix->Error = spNO_MEMORY; FREE(pImagElements); return; } CALLOC( PrintOrdToIntColMap, int, Top + 1 ); if (PrintOrdToIntColMap == NULL) - { Matrix->Error = spNO_MEMORY; + { + Matrix->Error = spNO_MEMORY; FREE(pImagElements); FREE(PrintOrdToIntRowMap); return; } for (I = 1; I <= Size; I++) - { PrintOrdToIntRowMap[ Matrix->IntToExtRowMap[I] ] = I; + { + PrintOrdToIntRowMap[ Matrix->IntToExtRowMap[I] ] = I; PrintOrdToIntColMap[ Matrix->IntToExtColMap[I] ] = I; } -/* Pack the arrays. */ + /* Pack the arrays. */ for (J = 1, I = 1; I <= Top; I++) - { if (PrintOrdToIntRowMap[I] != 0) + { + if (PrintOrdToIntRowMap[I] != 0) PrintOrdToIntRowMap[ J++ ] = PrintOrdToIntRowMap[ I ]; } for (J = 1, I = 1; I <= Top; I++) - { if (PrintOrdToIntColMap[I] != 0) + { + if (PrintOrdToIntColMap[I] != 0) PrintOrdToIntColMap[ J++ ] = PrintOrdToIntColMap[ I ]; } -/* Print header. */ + /* Print header. */ if (Header) - { printf("MATRIX SUMMARY\n\n"); + { + printf("MATRIX SUMMARY\n\n"); printf("Size of matrix = %1d x %1d.\n", Size, Size); - if ( Matrix->Reordered AND PrintReordered ) + if ( Matrix->Reordered && PrintReordered ) printf("Matrix has been reordered.\n"); putchar('\n'); @@ -212,29 +213,30 @@ int *PrintOrdToIntRowMap, *PrintOrdToIntColMap; SmallestDiag = SmallestElement; } -/* Determine how many columns to use. */ + /* Determine how many columns to use. */ Columns = Printer_Width; if (Header) Columns -= 5; if (Data) Columns = (Columns+1) / 10; -/* - * Print matrix by printing groups of complete columns until all the columns - * are printed. - */ + /* Print matrix by printing groups of complete columns until all + * the columns are printed. */ J = 0; while ( J <= Size ) - -/* Calculatestrchr of last column to printed in this group. */ - { StopCol = StartCol + Columns - 1; + { + /* Calculatestrchr of last column to printed in this group. */ + StopCol = StartCol + Columns - 1; if (StopCol > Size) StopCol = Size; -/* Label the columns. */ + /* Label the columns. */ if (Header) - { if (Data) - { printf(" "); + { + if (Data) + { + printf(" "); for (I = StartCol; I <= StopCol; I++) - { if (PrintReordered) + { + if (PrintReordered) Col = I; else Col = PrintOrdToIntColMap[I]; @@ -243,64 +245,70 @@ int *PrintOrdToIntRowMap, *PrintOrdToIntColMap; printf("\n\n"); } else - { if (PrintReordered) + { + if (PrintReordered) printf("Columns %1d to %1d.\n",StartCol,StopCol); else - { printf("Columns %1d to %1d.\n", - Matrix->IntToExtColMap[ PrintOrdToIntColMap[StartCol] ], - Matrix->IntToExtColMap[ PrintOrdToIntColMap[StopCol] ]); + { + printf("Columns %1d to %1d.\n", + Matrix->IntToExtColMap[ PrintOrdToIntColMap[StartCol] ], + Matrix->IntToExtColMap[ PrintOrdToIntColMap[StopCol] ]); } } } -/* Print every row ... */ + /* Print every row ... */ for (I = 1; I <= Size; I++) - { if (PrintReordered) + { + if (PrintReordered) Row = I; else Row = PrintOrdToIntRowMap[I]; if (Header) - { if (PrintReordered AND NOT Data) + { + if (PrintReordered && !Data) printf("%4d", I); else printf("%4d", Matrix->IntToExtRowMap[ Row ]); - if (NOT Data) putchar(' '); + if (!Data) putchar(' '); } -/* ... in each column of the group. */ + /* ... in each column of the group. */ for (J = StartCol; J <= StopCol; J++) - { if (PrintReordered) + { + if (PrintReordered) Col = J; else Col = PrintOrdToIntColMap[J]; pElement = Matrix->FirstInCol[Col]; - while(pElement != NULL AND pElement->Row != Row) + while(pElement != NULL && pElement->Row != Row) pElement = pElement->NextInCol; if (Data) pImagElements[J - StartCol] = pElement; if (pElement != NULL) - -/* Case where element exists */ - { if (Data) + { + /* Case where element exists */ + if (Data) printf(" %9.3g", (double)pElement->Real); else putchar('x'); -/* Update status variables */ + /* Update status variables */ if ( (Magnitude = ELEMENT_MAG(pElement)) > LargestElement ) LargestElement = Magnitude; - if ((Magnitude < SmallestElement) AND (Magnitude != 0.0)) + if ((Magnitude < SmallestElement) && (Magnitude != 0.0)) SmallestElement = Magnitude; ElementCount++; } -/* Case where element is structurally zero */ + /* Case where element is structurally zero */ else - { if (Data) + { + if (Data) printf(" ..."); else putchar('.'); @@ -308,55 +316,61 @@ int *PrintOrdToIntRowMap, *PrintOrdToIntColMap; } putchar('\n'); -#if spCOMPLEX - if (Matrix->Complex AND Data) - { printf(" "); + if (Matrix->Complex && Data) + { + printf(" "); for (J = StartCol; J <= StopCol; J++) - { if (pImagElements[J - StartCol] != NULL) - { printf(" %8.2gj", + { + if (pImagElements[J - StartCol] != NULL) + { + printf(" %8.2gj", (double)pImagElements[J-StartCol]->Imag); } else printf(" "); } putchar('\n'); } -#endif /* spCOMPLEX */ } -/* Calculatestrchr of first column in next group. */ + /* Calculatestrchr of first column in next group. */ StartCol = StopCol; StartCol++; putchar('\n'); } if (Header) - { printf("\nLargest element in matrix = %-1.4g.\n", LargestElement); + { + printf("\nLargest element in matrix = %-1.4g.\n", LargestElement); printf("Smallest element in matrix = %-1.4g.\n", SmallestElement); -/* Search for largest and smallest diagonal values */ + /* Search for largest and smallest diagonal values */ for (I = 1; I <= Size; I++) - { if (Matrix->Diag[I] != NULL) - { Magnitude = ELEMENT_MAG( Matrix->Diag[I] ); + { + if (Matrix->Diag[I] != NULL) + { + Magnitude = ELEMENT_MAG( Matrix->Diag[I] ); if ( Magnitude > LargestDiag ) LargestDiag = Magnitude; if ( Magnitude < SmallestDiag ) SmallestDiag = Magnitude; } } - /* Print the largest and smallest diagonal values */ + /* Print the largest and smallest diagonal values */ if ( Matrix->Factored ) - { printf("\nLargest diagonal element = %-1.4g.\n", LargestDiag); + { + printf("\nLargest diagonal element = %-1.4g.\n", LargestDiag); printf("Smallest diagonal element = %-1.4g.\n", SmallestDiag); } else - { printf("\nLargest pivot element = %-1.4g.\n", LargestDiag); + { + printf("\nLargest pivot element = %-1.4g.\n", LargestDiag); printf("Smallest pivot element = %-1.4g.\n", SmallestDiag); } - /* Calculate and print sparsity and number of fill-ins created. */ + /* Calculate and print sparsity and number of fill-ins created. */ printf("\nDensity = %2.2f%%.\n", ((double)(ElementCount * 100)) / - ((double)(Size * Size))); + ((double)(Size * Size))); printf("Number of originals = %1d.\n", Matrix->Originals); - if (NOT Matrix->NeedsOrdering) + if (!Matrix->NeedsOrdering) printf("Number of fill-ins = %1d.\n", Matrix->Fillins); } putchar('\n'); @@ -395,14 +409,14 @@ int *PrintOrdToIntRowMap, *PrintOrdToIntColMap; * Name of file into which matrix is to be written. * Label (char *) * String that is transferred to file and is used as a label. - * Reordered (BOOLEAN) + * Reordered (int) * Specifies whether matrix should be output in reordered form, * or in original order. - * Data (BOOLEAN) + * Data (int) * Indicates that the element values should be output along with * the indices for each element. This parameter must be TRUE if * matrix is to be read by the sparse test program. - * Header (BOOLEAN) + * Header (int) * Indicates that header is desired. This parameter must be TRUE if * matrix is to be read by the sparse test program. * @@ -420,113 +434,124 @@ int *PrintOrdToIntRowMap, *PrintOrdToIntColMap; */ int -spFileMatrix( eMatrix, File, Label, Reordered, Data, Header ) - -char *eMatrix, *Label, *File; -int Reordered, Data, Header; +spFileMatrix(void *eMatrix, char *File, char *Label, int Reordered, + int Data, int Header) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register int I, Size; -register ElementPtr pElement; -int Row, Col, Err; -FILE *pMatrixFile, *fopen(); + MatrixPtr Matrix = (MatrixPtr)eMatrix; + int I, Size; + ElementPtr pElement; + int Row, Col, Err; + FILE *pMatrixFile; -/* Begin `spFileMatrix'. */ - ASSERT( IS_SPARSE( Matrix ) ); + /* Begin `spFileMatrix'. */ + assert( IS_SPARSE( Matrix ) ); -/* Open file matrix file in write mode. */ + /* Open file matrix file in write mode. */ if ((pMatrixFile = fopen(File, "w")) == NULL) return 0; -/* Output header. */ + /* Output header. */ Size = Matrix->Size; if (Header) - { if (Matrix->Factored AND Data) - { Err = fprintf - ( pMatrixFile, - "Warning : The following matrix is factored in to LU form.\n" - ); - if (Err < 0) return 0; + { + if (Matrix->Factored && Data) + { + Err = fprintf(pMatrixFile, + "Warning : The following matrix is " + "factored in to LU form.\n"); + if (Err < 0) + return 0; } - if (fprintf(pMatrixFile, "%s\n", Label) < 0) return 0; + if (fprintf(pMatrixFile, "%s\n", Label) < 0) + return 0; Err = fprintf( pMatrixFile, "%d\t%s\n", Size, - (Matrix->Complex ? "complex" : "real")); - if (Err < 0) return 0; + (Matrix->Complex ? "complex" : "real")); + if (Err < 0) + return 0; } -/* Output matrix. */ - if (NOT Data) - { for (I = 1; I <= Size; I++) - { pElement = Matrix->FirstInCol[I]; + /* Output matrix. */ + if (!Data) + { + for (I = 1; I <= Size; I++) + { + pElement = Matrix->FirstInCol[I]; while (pElement != NULL) - { if (Reordered) - { Row = pElement->Row; + { + if (Reordered) + { + Row = pElement->Row; Col = I; } else - { Row = Matrix->IntToExtRowMap[pElement->Row]; + { + Row = Matrix->IntToExtRowMap[pElement->Row]; Col = Matrix->IntToExtColMap[I]; } pElement = pElement->NextInCol; if (fprintf(pMatrixFile, "%d\t%d\n", Row, Col) < 0) return 0; } } -/* Output terminator, a line of zeros. */ + /* Output terminator, a line of zeros. */ if (Header) if (fprintf(pMatrixFile, "0\t0\n") < 0) return 0; } -#if spCOMPLEX - if (Data AND Matrix->Complex) - { for (I = 1; I <= Size; I++) - { pElement = Matrix->FirstInCol[I]; + if (Data && Matrix->Complex) + { + for (I = 1; I <= Size; I++) + { + pElement = Matrix->FirstInCol[I]; while (pElement != NULL) - { if (Reordered) - { Row = pElement->Row; + { + if (Reordered) + { + Row = pElement->Row; Col = I; } else - { Row = Matrix->IntToExtRowMap[pElement->Row]; + { + Row = Matrix->IntToExtRowMap[pElement->Row]; Col = Matrix->IntToExtColMap[I]; } Err = fprintf - ( pMatrixFile,"%d\t%d\t%-.15g\t%-.15g\n", - Row, Col, (double)pElement->Real, (double)pElement->Imag - ); + ( pMatrixFile,"%d\t%d\t%-.15g\t%-.15g\n", + Row, Col, (double)pElement->Real, (double)pElement->Imag + ); if (Err < 0) return 0; pElement = pElement->NextInCol; } } -/* Output terminator, a line of zeros. */ + /* Output terminator, a line of zeros. */ if (Header) if (fprintf(pMatrixFile,"0\t0\t0.0\t0.0\n") < 0) return 0; } -#endif /* spCOMPLEX */ -#if REAL - if (Data AND NOT Matrix->Complex) - { for (I = 1; I <= Size; I++) - { pElement = Matrix->FirstInCol[I]; + if (Data && !Matrix->Complex) + { + for (I = 1; I <= Size; I++) + { + pElement = Matrix->FirstInCol[I]; while (pElement != NULL) - { Row = Matrix->IntToExtRowMap[pElement->Row]; + { + Row = Matrix->IntToExtRowMap[pElement->Row]; Col = Matrix->IntToExtColMap[I]; Err = fprintf - ( pMatrixFile,"%d\t%d\t%-.15g\n", - Row, Col, (double)pElement->Real - ); + ( pMatrixFile,"%d\t%d\t%-.15g\n", + Row, Col, (double)pElement->Real + ); if (Err < 0) return 0; pElement = pElement->NextInCol; } } -/* Output terminator, a line of zeros. */ + /* Output terminator, a line of zeros. */ if (Header) if (fprintf(pMatrixFile,"0\t0\t0.0\n") < 0) return 0; } -#endif /* REAL */ -/* Close file. */ + /* Close file. */ if (fclose(pMatrixFile) < 0) return 0; return 1; } @@ -555,11 +580,9 @@ FILE *pMatrixFile, *fopen(); * File (char *) * Name of file into which matrix is to be written. * RHS (RealNumber []) - * Right-hand side vector. This is only the real portion if - * spSEPARATED_COMPLEX_VECTORS is TRUE. + * Right-hand side vector, real portion * iRHS (RealNumber []) - * Right-hand side vector, imaginary portion. Not necessary if matrix - * is real or if spSEPARATED_COMPLEX_VECTORS is set FALSE. + * Right-hand side vector, imaginary portion. * * >>> Local variables: * pMatrixFile (FILE *) @@ -567,86 +590,47 @@ FILE *pMatrixFile, *fopen(); * Size (int) * The size of the matrix. * - * >>> Obscure Macros - * IMAG_RHS - * Replaces itself with `, iRHS' if the options spCOMPLEX and - * spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears - * without a trace. */ int -spFileVector( eMatrix, File, RHS IMAG_RHS ) - -char *eMatrix, *File; -RealVector RHS IMAG_RHS; +spFileVector(void *eMatrix, char *File, RealVector RHS, RealVector iRHS) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register int I, Size, Err; -FILE *pMatrixFile; -FILE *fopen(); + MatrixPtr Matrix = (MatrixPtr)eMatrix; + int I, Size, Err; + FILE *pMatrixFile; + FILE *fopen(); -/* Begin `spFileVector'. */ - ASSERT( IS_SPARSE( Matrix ) AND RHS != NULL) + /* Begin `spFileVector'. */ + assert( IS_SPARSE( Matrix ) && RHS != NULL); -/* Open File in append mode. */ - if ((pMatrixFile = fopen(File,"a")) == NULL) - return 0; + /* Open File in append mode. */ + pMatrixFile = fopen(File,"a"); + if (pMatrixFile == NULL) + return 0; -/* Correct array pointers for ARRAY_OFFSET. */ -#if NOT ARRAY_OFFSET -#if spCOMPLEX - if (Matrix->Complex) - { -#if spSEPARATED_COMPLEX_VECTORS - ASSERT(iRHS != NULL) - --RHS; - --iRHS; -#else - RHS -= 2; -#endif - } - else -#endif /* spCOMPLEX */ - --RHS; -#endif /* NOT ARRAY_OFFSET */ - - -/* Output vector. */ + /* Output vector. */ Size = Matrix->Size; -#if spCOMPLEX if (Matrix->Complex) { -#if spSEPARATED_COMPLEX_VECTORS for (I = 1; I <= Size; I++) - { Err = fprintf - ( pMatrixFile, "%-.15g\t%-.15g\n", - (double)RHS[I], (double)iRHS[I] - ); + { + Err = fprintf + ( pMatrixFile, "%-.15g\t%-.15g\n", + (double)RHS[I], (double)iRHS[I] + ); if (Err < 0) return 0; } -#else - for (I = 1; I <= Size; I++) - { Err = fprintf - ( pMatrixFile, "%-.15g\t%-.15g\n", - (double)RHS[2*I], (double)RHS[2*I+1] - ); - if (Err < 0) return 0; - } -#endif } -#endif /* spCOMPLEX */ -#if REAL AND spCOMPLEX else -#endif -#if REAL - { for (I = 1; I <= Size; I++) - { if (fprintf(pMatrixFile, "%-.15g\n", (double)RHS[I]) < 0) + { + for (I = 1; I <= Size; I++) + { + if (fprintf(pMatrixFile, "%-.15g\n", (double)RHS[I]) < 0) return 0; } } -#endif /* REAL */ -/* Close file. */ + /* Close file. */ if (fclose(pMatrixFile) < 0) return 0; return 1; } @@ -696,27 +680,25 @@ FILE *fopen(); */ int -spFileStats( eMatrix, File, Label ) - -char *eMatrix, *File, *Label; +spFileStats(void *eMatrix, char *File, char *Label) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register int Size, I; -register ElementPtr pElement; -int NumberOfElements; -RealNumber Data, LargestElement, SmallestElement; -FILE *pStatsFile, *fopen(); + MatrixPtr Matrix = (MatrixPtr)eMatrix; + int Size, I; + ElementPtr pElement; + int NumberOfElements; + RealNumber Data, LargestElement, SmallestElement; + FILE *pStatsFile, *fopen(); -/* Begin `spFileStats'. */ - ASSERT( IS_SPARSE( Matrix ) ); + /* Begin `spFileStats'. */ + assert( IS_SPARSE( Matrix ) ); -/* Open File in append mode. */ + /* Open File in append mode. */ if ((pStatsFile = fopen(File, "a")) == NULL) return 0; -/* Output statistics. */ + /* Output statistics. */ Size = Matrix->Size; - if (NOT Matrix->Factored) + if (!Matrix->Factored) fprintf(pStatsFile, "Matrix has not been factored.\n"); fprintf(pStatsFile, "||| Starting new matrix |||\n"); fprintf(pStatsFile, "%s\n", Label); @@ -726,19 +708,21 @@ FILE *pStatsFile, *fopen(); fprintf(pStatsFile, "Matrix is real.\n"); fprintf(pStatsFile," Size = %d\n",Size); -/* Search matrix. */ + /* Search matrix. */ NumberOfElements = 0; LargestElement = 0.0; SmallestElement = LARGEST_REAL; for (I = 1; I <= Size; I++) - { pElement = Matrix->FirstInCol[I]; + { + pElement = Matrix->FirstInCol[I]; while (pElement != NULL) - { NumberOfElements++; + { + NumberOfElements++; Data = ELEMENT_MAG(pElement); if (Data > LargestElement) LargestElement = Data; - if (Data < SmallestElement AND Data != 0.0) + if (Data < SmallestElement && Data != 0.0) SmallestElement = Data; pElement = pElement->NextInCol; } @@ -746,7 +730,7 @@ FILE *pStatsFile, *fopen(); SmallestElement = MIN( SmallestElement, LargestElement ); -/* Output remaining statistics. */ + /* Output remaining statistics. */ fprintf(pStatsFile, " Initial number of elements = %d\n", NumberOfElements - Matrix->Fillins); fprintf(pStatsFile, @@ -766,7 +750,7 @@ FILE *pStatsFile, *fopen(); fprintf(pStatsFile," Largest Element = %e\n", LargestElement); fprintf(pStatsFile," Smallest Element = %e\n\n\n", SmallestElement); -/* Close file. */ + /* Close file. */ (void)fclose(pStatsFile); return 1; } diff --git a/src/maths/sparse/spsmp.c b/src/maths/sparse/spsmp.c index 39af150e5..eab788435 100644 --- a/src/maths/sparse/spsmp.c +++ b/src/maths/sparse/spsmp.c @@ -47,12 +47,10 @@ * To be compatible with SPICE, the following Sparse compiler options * (in spConfig.h) should be set as shown below: * - * REAL YES * EXPANDABLE YES * TRANSLATE NO * INITIALIZE NO or YES, YES for use with test prog. * DIAGONAL_PIVOTING YES - * ARRAY_OFFSET YES * MODIFIED_MARKOWITZ NO * DELETE NO * STRIP NO @@ -66,11 +64,7 @@ * STABILITY NO * CONDITION NO * PSEUDOCONDITION NO - * FORTRAN NO * DEBUG YES - * spCOMPLEX 1 - * spSEPARATED_COMPLEX_VECTORS 1 - * spCOMPATIBILITY 0 * * spREAL double */ @@ -90,16 +84,6 @@ * any purpose. It is provided `as is', without express or implied warranty. */ -#ifdef notdef -static char copyright[] = - "Sparse1.3: Copyright (c) 1985,86,87,88,89,90 by Kenneth S. Kundert"; -static char RCSid[] = - "@(#)$Header$"; -#endif - - - - /* * IMPORTS * @@ -110,63 +94,56 @@ static char RCSid[] = * Spice3's matrix macro definitions. */ -#include "ngspice.h" +#include +#include + +#include #include -#include "spmatrix.h" -#include "smpdefs.h" + +#include +#include + #include "spdefs.h" -/* #define NO 0 */ -/* #define YES 1 */ -#ifdef __STDC__ -static void LoadGmin( char * /*eMatrix*/, double /*Gmin*/ ); -#else -static void LoadGmin( ); -#endif +static void LoadGmin(SMPmatrix *eMatrix, double Gmin); + /* * SMPaddElt() */ int -SMPaddElt( Matrix, Row, Col, Value ) -SMPmatrix *Matrix; -int Row, Col; -double Value; +SMPaddElt(SMPmatrix *Matrix, int Row, int Col, double Value) { - *spGetElement( (char *)Matrix, Row, Col ) = Value; - return spError( (char *)Matrix ); + *spGetElement( (void *)Matrix, Row, Col ) = Value; + return spError( (void *)Matrix ); } /* * SMPmakeElt() */ double * -SMPmakeElt( Matrix, Row, Col ) -SMPmatrix *Matrix; -int Row, Col; +SMPmakeElt(SMPmatrix *Matrix, int Row, int Col) { - return spGetElement( (char *)Matrix, Row, Col ); + return spGetElement( (void *)Matrix, Row, Col ); } /* * SMPcClear() */ void -SMPcClear( Matrix ) -SMPmatrix *Matrix; +SMPcClear(SMPmatrix *Matrix) { - spClear( (char *)Matrix ); + spClear( (void *)Matrix ); } /* * SMPclear() */ void -SMPclear( Matrix ) -SMPmatrix *Matrix; +SMPclear(SMPmatrix *Matrix) { - spClear( (char *)Matrix ); + spClear( (void *)Matrix ); } /* @@ -174,12 +151,10 @@ SMPmatrix *Matrix; */ /*ARGSUSED*/ int -SMPcLUfac( Matrix, PivTol ) -SMPmatrix *Matrix; -double PivTol; +SMPcLUfac(SMPmatrix *Matrix, double PivTol) { - spSetComplex( (char *)Matrix ); - return spFactor( (char *)Matrix ); + spSetComplex( (void *)Matrix ); + return spFactor( (void *)Matrix ); } /* @@ -187,27 +162,23 @@ double PivTol; */ /*ARGSUSED*/ int -SMPluFac( Matrix, PivTol, Gmin ) -SMPmatrix *Matrix; -double PivTol, Gmin; +SMPluFac(SMPmatrix *Matrix, double PivTol, double Gmin) { - spSetReal( (char *)Matrix ); - LoadGmin( (char *)Matrix, Gmin ); - return spFactor( (char *)Matrix ); + spSetReal( (void *)Matrix ); + LoadGmin( (void *)Matrix, Gmin ); + return spFactor( (void *)Matrix ); } /* * SMPcReorder() */ int -SMPcReorder( Matrix, PivTol, PivRel, NumSwaps ) -SMPmatrix *Matrix; -double PivTol, PivRel; -int *NumSwaps; +SMPcReorder(SMPmatrix *Matrix, double PivTol, double PivRel, + int *NumSwaps) { *NumSwaps = 1; - spSetComplex( (char *)Matrix ); - return spOrderAndFactor( (char *)Matrix, (spREAL*)NULL, + spSetComplex( (void *)Matrix ); + return spOrderAndFactor( (void *)Matrix, (spREAL*)NULL, (spREAL)PivRel, (spREAL)PivTol, YES ); } @@ -215,13 +186,11 @@ int *NumSwaps; * SMPreorder() */ int -SMPreorder( Matrix, PivTol, PivRel, Gmin ) -SMPmatrix *Matrix; -double PivTol, PivRel, Gmin; +SMPreorder(SMPmatrix *Matrix, double PivTol, double PivRel, double Gmin) { - spSetReal( (char *)Matrix ); - LoadGmin( (char *)Matrix, Gmin ); - return spOrderAndFactor( (char *)Matrix, (spREAL*)NULL, + spSetReal( (void *)Matrix ); + LoadGmin( (void *)Matrix, Gmin ); + return spOrderAndFactor( (void *)Matrix, (spREAL*)NULL, (spREAL)PivRel, (spREAL)PivTol, YES ); } @@ -229,53 +198,47 @@ double PivTol, PivRel, Gmin; * SMPcaSolve() */ void -SMPcaSolve( Matrix, RHS, iRHS, Spare, iSpare) -SMPmatrix *Matrix; -double RHS[], iRHS[], Spare[], iSpare[]; +SMPcaSolve(SMPmatrix *Matrix, double RHS[], double iRHS[], + double Spare[], double iSpare[]) { - spSolveTransposed( (char *)Matrix, RHS, RHS, iRHS, iRHS ); + spSolveTransposed( (void *)Matrix, RHS, RHS, iRHS, iRHS ); } /* * SMPcSolve() */ void -SMPcSolve( Matrix, RHS, iRHS, Spare, iSpare) -SMPmatrix *Matrix; -double RHS[], iRHS[], Spare[], iSpare[]; +SMPcSolve(SMPmatrix *Matrix, double RHS[], double iRHS[], + double Spare[], double iSpare[]) { - spSolve( (char *)Matrix, RHS, RHS, iRHS, iRHS ); + spSolve( (void *)Matrix, RHS, RHS, iRHS, iRHS ); } /* * SMPsolve() */ void -SMPsolve( Matrix, RHS, Spare ) -SMPmatrix *Matrix; -double RHS[], Spare[]; +SMPsolve(SMPmatrix *Matrix, double RHS[], double Spare[]) { - spSolve( (char *)Matrix, RHS, RHS, (spREAL*)NULL, (spREAL*)NULL ); + spSolve( (void *)Matrix, RHS, RHS, (spREAL*)NULL, (spREAL*)NULL ); } /* * SMPmatSize() */ int -SMPmatSize( Matrix ) -SMPmatrix *Matrix; +SMPmatSize(SMPmatrix *Matrix) { - return spGetSize( (char *)Matrix, 1 ); + return spGetSize( (void *)Matrix, 1 ); } /* * SMPnewMatrix() */ int -SMPnewMatrix( pMatrix ) -SMPmatrix **pMatrix; +SMPnewMatrix(SMPmatrix **pMatrix) { -int Error; + int Error; *pMatrix = (SMPmatrix *)spCreate( 0, 1, &Error ); return Error; } @@ -284,21 +247,19 @@ int Error; * SMPdestroy() */ void -SMPdestroy( Matrix ) -SMPmatrix *Matrix; +SMPdestroy(SMPmatrix *Matrix) { - spDestroy( (char *)Matrix ); + spDestroy( (void *)Matrix ); } /* * SMPpreOrder() */ int -SMPpreOrder( Matrix ) -SMPmatrix *Matrix; +SMPpreOrder(SMPmatrix *Matrix) { - spMNA_Preorder( (char *)Matrix ); - return spError( (char *)Matrix ); + spMNA_Preorder( (void *)Matrix ); + return spError( (void *)Matrix ); } /* @@ -306,22 +267,18 @@ SMPmatrix *Matrix; */ /*ARGSUSED*/ void -SMPprint( Matrix, File ) -SMPmatrix *Matrix; -FILE *File; +SMPprint(SMPmatrix *Matrix, FILE *File) { - spPrint( (char *)Matrix, 0, 1, 1 ); + spPrint( (void *)Matrix, 0, 1, 1 ); } /* * SMPgetError() */ void -SMPgetError( Matrix, Col, Row) -SMPmatrix *Matrix; -int *Row, *Col; +SMPgetError(SMPmatrix *Matrix, int *Col, int *Row) { - spWhereSingular( (char *)Matrix, Row, Col ); + spWhereSingular( (void *)Matrix, Row, Col ); } /* @@ -329,29 +286,23 @@ int *Row, *Col; * note: obsolete for Spice3d2 and later */ int -SMPcProdDiag( Matrix, pMantissa, pExponent) -SMPmatrix *Matrix; -SPcomplex *pMantissa; -int *pExponent; +SMPcProdDiag(SMPmatrix *Matrix, SPcomplex *pMantissa, int *pExponent) { - spDeterminant( (char *)Matrix, pExponent, &(pMantissa->real), + spDeterminant( (void *)Matrix, pExponent, &(pMantissa->real), &(pMantissa->imag) ); - return spError( (char *)Matrix ); + return spError( (void *)Matrix ); } /* * SMPcDProd() */ int -SMPcDProd( Matrix, pMantissa, pExponent) -SMPmatrix *Matrix; -SPcomplex *pMantissa; -int *pExponent; +SMPcDProd(SMPmatrix *Matrix, SPcomplex *pMantissa, int *pExponent) { double re, im, x, y, z; int p; - spDeterminant( (char *)Matrix, &p, &re, &im); + spDeterminant( (void *)Matrix, &p, &re, &im); #ifndef M_LN2 #define M_LN2 0.69314718055994530942 @@ -421,7 +372,7 @@ int *pExponent; printf("Determinant 10->2: (%20g,%20g)^%d\n", pMantissa->real, pMantissa->imag, *pExponent); #endif - return spError( (char *)Matrix ); + return spError( (void *)Matrix ); } @@ -443,17 +394,15 @@ int *pExponent; */ static void -LoadGmin( eMatrix, Gmin ) -char *eMatrix; -register double Gmin; +LoadGmin(SMPmatrix *eMatrix, double Gmin) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register int I; -register ArrayOfElementPtrs Diag; -register ElementPtr diag; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + int I; + ArrayOfElementPtrs Diag; + ElementPtr diag; -/* Begin `LoadGmin'. */ - ASSERT( IS_SPARSE( Matrix ) ); + /* Begin `LoadGmin'. */ + assert( IS_SPARSE( Matrix ) ); if (Gmin != 0.0) { Diag = Matrix->Diag; @@ -478,17 +427,13 @@ register ElementPtr diag; */ SMPelement * -SMPfindElt( eMatrix, Row, Col, CreateIfMissing ) - -SMPmatrix *eMatrix; -int Row, Col; -int CreateIfMissing; +SMPfindElt(SMPmatrix *eMatrix, int Row, int Col, int CreateIfMissing) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -ElementPtr Element; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + ElementPtr Element; -/* Begin `SMPfindElt'. */ - ASSERT( IS_SPARSE( Matrix ) ); + /* Begin `SMPfindElt'. */ + assert( IS_SPARSE( Matrix ) ); Row = Matrix->ExtToIntRowMap[Row]; Col = Matrix->ExtToIntColMap[Col]; Element = Matrix->FirstInCol[Col]; @@ -502,10 +447,9 @@ ElementPtr Element; * SMPcZeroCol() */ int -SMPcZeroCol( Matrix, Col ) -MatrixPtr Matrix; -int Col; +SMPcZeroCol(SMPmatrix *eMatrix, int Col) { + MatrixPtr Matrix = (MatrixPtr)eMatrix; ElementPtr Element; Col = Matrix->ExtToIntColMap[Col]; @@ -518,17 +462,16 @@ int Col; Element->Imag = 0.0; } - return spError( (char *)Matrix ); + return spError( (void *)Matrix ); } /* * SMPcAddCol() */ int -SMPcAddCol( Matrix, Accum_Col, Addend_Col ) -MatrixPtr Matrix; -int Accum_Col, Addend_Col; +SMPcAddCol(SMPmatrix *eMatrix, int Accum_Col, int Addend_Col) { + MatrixPtr Matrix = (MatrixPtr)eMatrix; ElementPtr Accum, Addend, *Prev; Accum_Col = Matrix->ExtToIntColMap[Accum_Col]; @@ -551,17 +494,16 @@ int Accum_Col, Addend_Col; Addend = Addend->NextInCol; } - return spError( (char *)Matrix ); + return spError( (void *)Matrix ); } /* * SMPzeroRow() */ int -SMPzeroRow( Matrix, Row ) -MatrixPtr Matrix; -int Row; +SMPzeroRow(SMPmatrix *eMatrix, int Row) { + MatrixPtr Matrix = (MatrixPtr)eMatrix; ElementPtr Element; Row = Matrix->ExtToIntColMap[Row]; @@ -569,8 +511,7 @@ int Row; if (Matrix->RowsLinked == NO) spcLinkRows(Matrix); -#if spCOMPLEX - if (Matrix->PreviousMatrixWasComplex OR Matrix->Complex) { + if (Matrix->PreviousMatrixWasComplex || Matrix->Complex) { for (Element = Matrix->FirstInRow[Row]; Element != NULL; Element = Element->NextInRow) @@ -578,9 +519,7 @@ int Row; Element->Real = 0.0; Element->Imag = 0.0; } - } else -#endif - { + } else { for (Element = Matrix->FirstInRow[Row]; Element != NULL; Element = Element->NextInRow) @@ -589,7 +528,7 @@ int Row; } } - return spError( (char *)Matrix ); + return spError( (void *)Matrix ); } #ifdef PARALLEL_ARCH @@ -597,24 +536,20 @@ int Row; * SMPcombine() */ void -SMPcombine( Matrix, RHS, Spare ) -SMPmatrix *Matrix; -double RHS[], Spare[]; +SMPcombine(SMPmatrix *Matrix, double RHS[], double Spare[]) { - spSetReal( (char *)Matrix ); - spCombine( (char *)Matrix, RHS, Spare, (spREAL*)NULL, (spREAL*)NULL ); + spSetReal( (void *)Matrix ); + spCombine( (void *)Matrix, RHS, Spare, (spREAL*)NULL, (spREAL*)NULL ); } /* * SMPcCombine() */ void -SMPcCombine( Matrix, RHS, Spare, iRHS, iSpare ) -SMPmatrix *Matrix; -double RHS[], Spare[]; -double iRHS[], iSpare[]; +SMPcCombine(SMPmatrix *Matrix, double RHS[], double Spare[], + double iRHS[], double iSpare[]) { - spSetComplex( (char *)Matrix ); - spCombine( (char *)Matrix, RHS, Spare, iRHS, iSpare ); + spSetComplex( (void *)Matrix ); + spCombine( (void *)Matrix, RHS, Spare, iRHS, iSpare ); } #endif /* PARALLEL_ARCH */ diff --git a/src/maths/sparse/spsolve.c b/src/maths/sparse/spsolve.c index 2b65a0ed8..7db3c85be 100644 --- a/src/maths/sparse/spsolve.c +++ b/src/maths/sparse/spsolve.c @@ -34,15 +34,6 @@ * or implied warranty. */ -#ifdef notdef -static char copyright[] = - "Sparse1.3: Copyright (c) 1985,86,87,88,89,90 by Kenneth S. Kundert"; -static char RCSid[] = - "@(#)$Header$"; -#endif - - - /* * IMPORTS * @@ -54,6 +45,7 @@ static char RCSid[] = * spDefs.h * Matrix type and macro definitions for the sparse matrix routines. */ +#include #define spINSIDE_SPARSE #include "spconfig.h" @@ -67,20 +59,10 @@ static char RCSid[] = * Function declarations */ -#ifdef __STDC__ -#if spSEPARATED_COMPLEX_VECTORS static void SolveComplexMatrix( MatrixPtr, RealVector, RealVector, RealVector, RealVector ); static void SolveComplexTransposedMatrix( MatrixPtr, RealVector, RealVector, RealVector, RealVector ); -#else -static void SolveComplexMatrix( MatrixPtr, RealVector, RealVector ); -static void SolveComplexTransposedMatrix( MatrixPtr, RealVector, RealVector ); -#endif -#else /* __STDC__ */ -static void SolveComplexMatrix(); -static void SolveComplexTransposedMatrix(); -#endif /* __STDC__ */ @@ -111,13 +93,10 @@ static void SolveComplexTransposedMatrix(); * iRHS (RealVector) * iRHS is the imaginary portion of the input data array, the right * hand side. This data is undisturbed and may be reused for other solves. - * This argument is only necessary if matrix is complex and if - * spSEPARATED_COMPLEX_VECTOR is set TRUE. * iSolution (RealVector) * iSolution is the imaginary portion of the output data array. This * routine is constructed such that iRHS and iSolution can be - * the same array. This argument is only necessary if matrix is complex - * and if spSEPARATED_COMPLEX_VECTOR is set TRUE. + * the same array. * * >>> Local variables: * Intermediate (RealVector) @@ -140,89 +119,77 @@ static void SolveComplexTransposedMatrix(); * Size of matrix. Made local to reduce indirection. * Temp (RealNumber) * Temporary storage for entries in arrays. - * - * >>> Obscure Macros - * IMAG_VECTORS - * Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and - * spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears - * without a trace. */ /*VARARGS3*/ void -spSolve( eMatrix, RHS, Solution IMAG_VECTORS ) - -char *eMatrix; -RealVector RHS, Solution IMAG_VECTORS; +spSolve(void *eMatrix, RealVector RHS, RealVector Solution, + RealVector iRHS, RealVector iSolution) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register ElementPtr pElement; -register RealVector Intermediate; -register RealNumber Temp; -register int I, *pExtOrder, Size; -ElementPtr pPivot; -void SolveComplexMatrix(); + MatrixPtr Matrix = (MatrixPtr)eMatrix; + ElementPtr pElement; + RealVector Intermediate; + RealNumber Temp; + int I, *pExtOrder, Size; + ElementPtr pPivot; + void SolveComplexMatrix(); -/* Begin `spSolve'. */ - ASSERT( IS_VALID(Matrix) AND IS_FACTORED(Matrix) ); + /* Begin `spSolve'. */ + assert( IS_VALID(Matrix) && IS_FACTORED(Matrix) ); -#if spCOMPLEX if (Matrix->Complex) - { SolveComplexMatrix( Matrix, RHS, Solution IMAG_VECTORS ); + { + SolveComplexMatrix( Matrix, RHS, Solution, iRHS, iSolution ); return; } -#endif -#if REAL Intermediate = Matrix->Intermediate; Size = Matrix->Size; -/* Correct array pointers for ARRAY_OFFSET. */ -#if NOT ARRAY_OFFSET - --RHS; - --Solution; -#endif - -/* Initialize Intermediate vector. */ + /* Initialize Intermediate vector. */ pExtOrder = &Matrix->IntToExtRowMap[Size]; for (I = Size; I > 0; I--) Intermediate[I] = RHS[*(pExtOrder--)]; -/* Forward elimination. Solves Lc = b.*/ + /* Forward elimination. Solves Lc = b.*/ for (I = 1; I <= Size; I++) - { -/* This step of the elimination is skipped if Temp equals zero. */ + { + + /* This step of the elimination is skipped if Temp equals zero. */ if ((Temp = Intermediate[I]) != 0.0) - { pPivot = Matrix->Diag[I]; + { + pPivot = Matrix->Diag[I]; Intermediate[I] = (Temp *= pPivot->Real); pElement = pPivot->NextInCol; while (pElement != NULL) - { Intermediate[pElement->Row] -= Temp * pElement->Real; + { + Intermediate[pElement->Row] -= Temp * pElement->Real; pElement = pElement->NextInCol; } } } -/* Backward Substitution. Solves Ux = c.*/ + /* Backward Substitution. Solves Ux = c.*/ for (I = Size; I > 0; I--) - { Temp = Intermediate[I]; + { + Temp = Intermediate[I]; pElement = Matrix->Diag[I]->NextInRow; while (pElement != NULL) - { Temp -= pElement->Real * Intermediate[pElement->Col]; + { + Temp -= pElement->Real * Intermediate[pElement->Col]; pElement = pElement->NextInRow; } Intermediate[I] = Temp; } -/* Unscramble Intermediate vector while placing data in to Solution vector. */ + /* Unscramble Intermediate vector while placing data in to Solution vector. */ pExtOrder = &Matrix->IntToExtColMap[Size]; for (I = Size; I > 0; I--) Solution[*(pExtOrder--)] = Intermediate[I]; return; -#endif /* REAL */ } @@ -235,7 +202,6 @@ void SolveComplexMatrix(); -#if spCOMPLEX /* * SOLVE COMPLEX MATRIX EQUATION * @@ -289,69 +255,50 @@ void SolveComplexMatrix(); * Size of matrix. Made local to reduce indirection. * Temp (ComplexNumber) * Temporary storage for entries in arrays. - * - * >>> Obscure Macros - * IMAG_VECTORS - * Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and - * spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears - * without a trace. */ static void -SolveComplexMatrix( Matrix, RHS, Solution IMAG_VECTORS ) +SolveComplexMatrix( Matrix, RHS, Solution , iRHS, iSolution ) MatrixPtr Matrix; -RealVector RHS, Solution IMAG_VECTORS; +RealVector RHS, Solution , iRHS, iSolution; { -register ElementPtr pElement; -register ComplexVector Intermediate; -register int I, *pExtOrder, Size; -ElementPtr pPivot; -ComplexNumber Temp; + ElementPtr pElement; + ComplexVector Intermediate; + int I, *pExtOrder, Size; + ElementPtr pPivot; + ComplexNumber Temp; -/* Begin `SolveComplexMatrix'. */ + /* Begin `SolveComplexMatrix'. */ Size = Matrix->Size; Intermediate = (ComplexVector)Matrix->Intermediate; -/* Correct array pointers for ARRAY_OFFSET. */ -#if NOT ARRAY_OFFSET -#if spSEPARATED_COMPLEX_VECTORS - --RHS; --iRHS; - --Solution; --iSolution; -#else - RHS -= 2; Solution -= 2; -#endif -#endif - -/* Initialize Intermediate vector. */ + /* Initialize Intermediate vector. */ pExtOrder = &Matrix->IntToExtRowMap[Size]; -#if spSEPARATED_COMPLEX_VECTORS for (I = Size; I > 0; I--) - { Intermediate[I].Real = RHS[*(pExtOrder)]; + { + Intermediate[I].Real = RHS[*(pExtOrder)]; Intermediate[I].Imag = iRHS[*(pExtOrder--)]; } -#else - ExtVector = (ComplexVector)RHS; - for (I = Size; I > 0; I--) - Intermediate[I] = ExtVector[*(pExtOrder--)]; -#endif -/* Forward substitution. Solves Lc = b.*/ + /* Forward substitution. Solves Lc = b.*/ for (I = 1; I <= Size; I++) - { Temp = Intermediate[I]; + { + Temp = Intermediate[I]; -/* This step of the substitution is skipped if Temp equals zero. */ - if ((Temp.Real != 0.0) OR (Temp.Imag != 0.0)) - { pPivot = Matrix->Diag[I]; -/* Cmplx expr: Temp *= (1.0 / Pivot). */ + /* This step of the substitution is skipped if Temp equals zero. */ + if ((Temp.Real != 0.0) || (Temp.Imag != 0.0)) + { + pPivot = Matrix->Diag[I]; + /* Cmplx expr: Temp *= (1.0 / Pivot). */ CMPLX_MULT_ASSIGN(Temp, *pPivot); Intermediate[I] = Temp; pElement = pPivot->NextInCol; while (pElement != NULL) { -/* Cmplx expr: Intermediate[Element->Row] -= Temp * *Element. */ + /* Cmplx expr: Intermediate[Element->Row] -= Temp * *Element. */ CMPLX_MULT_SUBT_ASSIGN(Intermediate[pElement->Row], Temp, *pElement); pElement = pElement->NextInCol; @@ -359,37 +306,32 @@ ComplexNumber Temp; } } -/* Backward Substitution. Solves Ux = c.*/ + /* Backward Substitution. Solves Ux = c.*/ for (I = Size; I > 0; I--) - { Temp = Intermediate[I]; + { + Temp = Intermediate[I]; pElement = Matrix->Diag[I]->NextInRow; while (pElement != NULL) { -/* Cmplx expr: Temp -= *Element * Intermediate[Element->Col]. */ + /* Cmplx expr: Temp -= *Element * Intermediate[Element->Col]. */ CMPLX_MULT_SUBT_ASSIGN(Temp, *pElement,Intermediate[pElement->Col]); pElement = pElement->NextInRow; } Intermediate[I] = Temp; } -/* Unscramble Intermediate vector while placing data in to Solution vector. */ + /* Unscramble Intermediate vector while placing data in to Solution vector. */ pExtOrder = &Matrix->IntToExtColMap[Size]; -#if spSEPARATED_COMPLEX_VECTORS for (I = Size; I > 0; I--) - { Solution[*(pExtOrder)] = Intermediate[I].Real; + { + Solution[*(pExtOrder)] = Intermediate[I].Real; iSolution[*(pExtOrder--)] = Intermediate[I].Imag; } -#else - ExtVector = (ComplexVector)Solution; - for (I = Size; I > 0; I--) - ExtVector[*(pExtOrder--)] = Intermediate[I]; -#endif return; } -#endif /* spCOMPLEX */ @@ -457,88 +399,77 @@ ComplexNumber Temp; * Size of matrix. Made local to reduce indirection. * Temp (RealNumber) * Temporary storage for entries in arrays. - * - * >>> Obscure Macros - * IMAG_VECTORS - * Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and - * spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears - * without a trace. */ /*VARARGS3*/ void -spSolveTransposed( eMatrix, RHS, Solution IMAG_VECTORS ) - -char *eMatrix; -RealVector RHS, Solution IMAG_VECTORS; +spSolveTransposed(void *eMatrix, RealVector RHS, RealVector Solution, + RealVector iRHS, RealVector iSolution) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register ElementPtr pElement; -register RealVector Intermediate; -register int I, *pExtOrder, Size; -ElementPtr pPivot; -RealNumber Temp; -void SolveComplexTransposedMatrix(); + MatrixPtr Matrix = (MatrixPtr)eMatrix; + ElementPtr pElement; + RealVector Intermediate; + int I, *pExtOrder, Size; + ElementPtr pPivot; + RealNumber Temp; + void SolveComplexTransposedMatrix(); -/* Begin `spSolveTransposed'. */ - ASSERT( IS_VALID(Matrix) AND IS_FACTORED(Matrix) ); + /* Begin `spSolveTransposed'. */ + assert( IS_VALID(Matrix) && IS_FACTORED(Matrix) ); -#if spCOMPLEX if (Matrix->Complex) - { SolveComplexTransposedMatrix( Matrix, RHS, Solution IMAG_VECTORS ); + { + SolveComplexTransposedMatrix( Matrix, RHS, Solution , iRHS, iSolution ); return; } -#endif -#if REAL Size = Matrix->Size; Intermediate = Matrix->Intermediate; -/* Correct array pointers for ARRAY_OFFSET. */ -#if NOT ARRAY_OFFSET - --RHS; - --Solution; -#endif - -/* Initialize Intermediate vector. */ + /* Initialize Intermediate vector. */ pExtOrder = &Matrix->IntToExtColMap[Size]; for (I = Size; I > 0; I--) Intermediate[I] = RHS[*(pExtOrder--)]; -/* Forward elimination. */ + /* Forward elimination. */ for (I = 1; I <= Size; I++) - { -/* This step of the elimination is skipped if Temp equals zero. */ + { + + /* This step of the elimination is skipped if Temp equals zero. */ if ((Temp = Intermediate[I]) != 0.0) - { pElement = Matrix->Diag[I]->NextInRow; + { + pElement = Matrix->Diag[I]->NextInRow; while (pElement != NULL) - { Intermediate[pElement->Col] -= Temp * pElement->Real; + { + Intermediate[pElement->Col] -= Temp * pElement->Real; pElement = pElement->NextInRow; } } } -/* Backward Substitution. */ + /* Backward Substitution. */ for (I = Size; I > 0; I--) - { pPivot = Matrix->Diag[I]; + { + pPivot = Matrix->Diag[I]; Temp = Intermediate[I]; pElement = pPivot->NextInCol; while (pElement != NULL) - { Temp -= pElement->Real * Intermediate[pElement->Row]; + { + Temp -= pElement->Real * Intermediate[pElement->Row]; pElement = pElement->NextInCol; } Intermediate[I] = Temp * pPivot->Real; } -/* Unscramble Intermediate vector while placing data in to Solution vector. */ + /* Unscramble Intermediate vector while placing data in to + Solution vector. */ pExtOrder = &Matrix->IntToExtRowMap[Size]; for (I = Size; I > 0; I--) Solution[*(pExtOrder--)] = Intermediate[I]; return; -#endif /* REAL */ } #endif /* TRANSPOSE */ @@ -551,7 +482,7 @@ void SolveComplexTransposedMatrix(); -#if TRANSPOSE AND spCOMPLEX +#if TRANSPOSE /* * SOLVE COMPLEX TRANSPOSED MATRIX EQUATION * @@ -569,23 +500,18 @@ void SolveComplexTransposedMatrix(); * RHS (RealVector) * RHS is the input data array, the right hand * side. This data is undisturbed and may be reused for other solves. - * This vector is only the real portion if the matrix is complex and - * spSEPARATED_COMPLEX_VECTORS is set TRUE. + * This vector is only the real portion if the matrix is complex. * Solution (RealVector) * Solution is the real portion of the output data array. This routine * is constructed such that RHS and Solution can be the same array. - * This vector is only the real portion if the matrix is complex and - * spSEPARATED_COMPLEX_VECTORS is set TRUE. + * This vector is only the real portion if the matrix is complex. * iRHS (RealVector) * iRHS is the imaginary portion of the input data array, the right * hand side. This data is undisturbed and may be reused for other solves. - * If either spCOMPLEX or spSEPARATED_COMPLEX_VECTOR is set FALSE, there - * is no need to supply this array. * iSolution (RealVector) * iSolution is the imaginary portion of the output data array. This * routine is constructed such that iRHS and iSolution can be - * the same array. If spCOMPLEX or spSEPARATED_COMPLEX_VECTOR is set - * FALSE, there is no need to supply this array. + * the same array. * * >>> Local variables: * Intermediate (ComplexVector) @@ -608,65 +534,46 @@ void SolveComplexTransposedMatrix(); * Size of matrix. Made local to reduce indirection. * Temp (ComplexNumber) * Temporary storage for entries in arrays. - * - * >>> Obscure Macros - * IMAG_VECTORS - * Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and - * spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears - * without a trace. */ static void -SolveComplexTransposedMatrix(Matrix, RHS, Solution IMAG_VECTORS ) +SolveComplexTransposedMatrix(Matrix, RHS, Solution , iRHS, iSolution ) MatrixPtr Matrix; -RealVector RHS, Solution IMAG_VECTORS; +RealVector RHS, Solution , iRHS, iSolution; { -register ElementPtr pElement; -register ComplexVector Intermediate; -register int I, *pExtOrder, Size; -ElementPtr pPivot; -ComplexNumber Temp; + ElementPtr pElement; + ComplexVector Intermediate; + int I, *pExtOrder, Size; + ElementPtr pPivot; + ComplexNumber Temp; -/* Begin `SolveComplexTransposedMatrix'. */ + /* Begin `SolveComplexTransposedMatrix'. */ Size = Matrix->Size; Intermediate = (ComplexVector)Matrix->Intermediate; -/* Correct array pointers for ARRAY_OFFSET. */ -#if NOT ARRAY_OFFSET -#if spSEPARATED_COMPLEX_VECTORS - --RHS; --iRHS; - --Solution; --iSolution; -#else - RHS -= 2; Solution -= 2; -#endif -#endif - -/* Initialize Intermediate vector. */ + /* Initialize Intermediate vector. */ pExtOrder = &Matrix->IntToExtColMap[Size]; -#if spSEPARATED_COMPLEX_VECTORS for (I = Size; I > 0; I--) - { Intermediate[I].Real = RHS[*(pExtOrder)]; + { + Intermediate[I].Real = RHS[*(pExtOrder)]; Intermediate[I].Imag = iRHS[*(pExtOrder--)]; } -#else - ExtVector = (ComplexVector)RHS; - for (I = Size; I > 0; I--) - Intermediate[I] = ExtVector[*(pExtOrder--)]; -#endif -/* Forward elimination. */ + /* Forward elimination. */ for (I = 1; I <= Size; I++) - { Temp = Intermediate[I]; + { + Temp = Intermediate[I]; -/* This step of the elimination is skipped if Temp equals zero. */ - if ((Temp.Real != 0.0) OR (Temp.Imag != 0.0)) - { pElement = Matrix->Diag[I]->NextInRow; + /* This step of the elimination is skipped if Temp equals zero. */ + if ((Temp.Real != 0.0) || (Temp.Imag != 0.0)) + { + pElement = Matrix->Diag[I]->NextInRow; while (pElement != NULL) { -/* Cmplx expr: Intermediate[Element->Col] -= Temp * *Element. */ + /* Cmplx expr: Intermediate[Element->Col] -= Temp * *Element. */ CMPLX_MULT_SUBT_ASSIGN( Intermediate[pElement->Col], Temp, *pElement); pElement = pElement->NextInRow; @@ -674,37 +581,34 @@ ComplexNumber Temp; } } -/* Backward Substitution. */ + /* Backward Substitution. */ for (I = Size; I > 0; I--) - { pPivot = Matrix->Diag[I]; + { + pPivot = Matrix->Diag[I]; Temp = Intermediate[I]; pElement = pPivot->NextInCol; while (pElement != NULL) { -/* Cmplx expr: Temp -= Intermediate[Element->Row] * *Element. */ + /* Cmplx expr: Temp -= Intermediate[Element->Row] * *Element. */ CMPLX_MULT_SUBT_ASSIGN(Temp,Intermediate[pElement->Row],*pElement); pElement = pElement->NextInCol; } -/* Cmplx expr: Intermediate = Temp * (1.0 / *pPivot). */ + /* Cmplx expr: Intermediate = Temp * (1.0 / *pPivot). */ CMPLX_MULT(Intermediate[I], Temp, *pPivot); } -/* Unscramble Intermediate vector while placing data in to Solution vector. */ + /* Unscramble Intermediate vector while placing data in to + Solution vector. */ pExtOrder = &Matrix->IntToExtRowMap[Size]; -#if spSEPARATED_COMPLEX_VECTORS for (I = Size; I > 0; I--) - { Solution[*(pExtOrder)] = Intermediate[I].Real; + { + Solution[*(pExtOrder)] = Intermediate[I].Real; iSolution[*(pExtOrder--)] = Intermediate[I].Imag; } -#else - ExtVector = (ComplexVector)Solution; - for (I = Size; I > 0; I--) - ExtVector[*(pExtOrder--)] = Intermediate[I]; -#endif return; } -#endif /* TRANSPOSE AND spCOMPLEX */ +#endif /* TRANSPOSE */ diff --git a/src/maths/sparse/sputils.c b/src/maths/sparse/sputils.c index 491d1a85c..7aa20c329 100644 --- a/src/maths/sparse/sputils.c +++ b/src/maths/sparse/sputils.c @@ -47,15 +47,6 @@ * or implied warranty. */ -#ifdef notdef -static char copyright[] = - "Sparse1.3: Copyright (c) 1985,86,87,88,89,90 by Kenneth S. Kundert"; -static char RCSid[] = - "@(#)$Header$"; -#endif - - - /* * IMPORTS * @@ -67,6 +58,7 @@ static char RCSid[] = * spDefs.h * Matrix type and macro definitions for the sparse matrix routines. */ +#include #define spINSIDE_SPARSE #include "spconfig.h" @@ -77,21 +69,14 @@ static char RCSid[] = -/* - * Function declarations - */ +/* Function declarations */ static int CountTwins( MatrixPtr, int, ElementPtr*, ElementPtr* ); static void SwapCols( MatrixPtr, ElementPtr, ElementPtr ); -#if spSEPARATED_COMPLEX_VECTORS static void ComplexMatrixMultiply( MatrixPtr, RealVector, RealVector, RealVector, RealVector ); static void ComplexTransposedMatrixMultiply( MatrixPtr, RealVector, RealVector, RealVector, RealVector); -#else -static void ComplexMatrixMultiply( MatrixPtr, RealVector, RealVector ); -static void ComplexTransposedMatrixMultiply(MatrixPtr, RealVector, RealVector); -#endif @@ -176,59 +161,65 @@ static void ComplexTransposedMatrixMultiply(MatrixPtr, RealVector, RealVector); * pTwin2 (ElementPtr) * Pointer to the twin found in the row belonging to the zero diagonal. * belonging to the zero diagonal. - * AnotherPassNeeded (BOOLEAN) + * AnotherPassNeeded (int) * Flag indicating that at least one zero diagonal with symmetric twins * remain. * StartAt (int) * Column number of first zero diagonal with symmetric twins. - * Swapped (BOOLEAN) + * Swapped (int) * Flag indicating that columns were swapped on this pass. * Twins (int) * Number of symmetric twins corresponding to current zero diagonal. */ void -spMNA_Preorder( eMatrix ) - -char *eMatrix; +spMNA_Preorder(void *eMatrix) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register int J, Size; -ElementPtr pTwin1, pTwin2; -int Twins, StartAt = 1; -BOOLEAN Swapped, AnotherPassNeeded; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + int J, Size; + ElementPtr pTwin1, pTwin2; + int Twins, StartAt = 1; + int Swapped, AnotherPassNeeded; -/* Begin `spMNA_Preorder'. */ - ASSERT( IS_VALID(Matrix) AND NOT Matrix->Factored ); + /* Begin `spMNA_Preorder'. */ + assert( IS_VALID(Matrix) && !Matrix->Factored ); if (Matrix->RowsLinked) return; Size = Matrix->Size; Matrix->Reordered = YES; do - { AnotherPassNeeded = Swapped = NO; + { + AnotherPassNeeded = Swapped = NO; -/* Search for zero diagonals with lone twins. */ + /* Search for zero diagonals with lone twins. */ for (J = StartAt; J <= Size; J++) - { if (Matrix->Diag[J] == NULL) - { Twins = CountTwins( Matrix, J, &pTwin1, &pTwin2 ); + { + if (Matrix->Diag[J] == NULL) + { + Twins = CountTwins( Matrix, J, &pTwin1, &pTwin2 ); if (Twins == 1) - { /* Lone twins found, swap rows. */ + { + /* Lone twins found, swap rows. */ SwapCols( Matrix, pTwin1, pTwin2 ); Swapped = YES; } - else if ((Twins > 1) AND NOT AnotherPassNeeded) - { AnotherPassNeeded = YES; + else if ((Twins > 1) && !AnotherPassNeeded) + { + AnotherPassNeeded = YES; StartAt = J; } } } -/* All lone twins are gone, look for zero diagonals with multiple twins. */ + /* All lone twins are gone, look for zero diagonals with multiple twins. */ if (AnotherPassNeeded) - { for (J = StartAt; NOT Swapped AND (J <= Size); J++) - { if (Matrix->Diag[J] == NULL) - { Twins = CountTwins( Matrix, J, &pTwin1, &pTwin2 ); + { + for (J = StartAt; !Swapped && (J <= Size); J++) + { + if (Matrix->Diag[J] == NULL) + { + Twins = CountTwins( Matrix, J, &pTwin1, &pTwin2 ); SwapCols( Matrix, pTwin1, pTwin2 ); Swapped = YES; } @@ -256,28 +247,26 @@ MatrixPtr Matrix; int Col; ElementPtr *ppTwin1, *ppTwin2; { -int Row, Twins = 0; -ElementPtr pTwin1, pTwin2; + int Row, Twins = 0; + ElementPtr pTwin1, pTwin2; -/* Begin `CountTwins'. */ + /* Begin `CountTwins'. */ pTwin1 = Matrix->FirstInCol[Col]; while (pTwin1 != NULL) - { if (ABS(pTwin1->Real) == 1.0) - { Row = pTwin1->Row; + { + if (ABS(pTwin1->Real) == 1.0) + { + Row = pTwin1->Row; pTwin2 = Matrix->FirstInCol[Row]; - while ((pTwin2 != NULL) AND (pTwin2->Row != Col)) + while ((pTwin2 != NULL) && (pTwin2->Row != Col)) pTwin2 = pTwin2->NextInCol; - if ((pTwin2 != NULL) AND (ABS(pTwin2->Real) == 1.0)) - { /* Found symmetric twins. */ + if ((pTwin2 != NULL) && (ABS(pTwin2->Real) == 1.0)) + { + /* Found symmetric twins. */ if (++Twins >= 2) return Twins; -#ifdef notdef - (*ppTwin1 = pTwin1)/*->Col = Col XXX */; - (*ppTwin2 = pTwin2)/*->Col = Row XXX */; -#else (*ppTwin1 = pTwin1)->Col = Col; (*ppTwin2 = pTwin2)->Col = Row; -#endif } } pTwin1 = pTwin1->NextInCol; @@ -301,18 +290,9 @@ SwapCols( Matrix, pTwin1, pTwin2 ) MatrixPtr Matrix; ElementPtr pTwin1, pTwin2; { -int Col1 = pTwin1->Col, Col2 = pTwin2->Col; + int Col1 = pTwin1->Col, Col2 = pTwin2->Col; -/* Begin `SwapCols'. */ - -#ifdef notdef -ElementPtr e; /*XXX*/ - /* XXX Update column numbers */ - for (e = Matrix->FirstInCol[Col1]; e != NULL; e = e->NextInCol) - e->Col = Col2; - for (e = Matrix->FirstInCol[Col2]; e != NULL; e = e->NextInCol) - e->Col = Col1; -#endif + /* Begin `SwapCols'. */ SWAP (ElementPtr, Matrix->FirstInCol[Col1], Matrix->FirstInCol[Col2]); SWAP (int, Matrix->IntToExtColMap[Col1], Matrix->IntToExtColMap[Col2]); @@ -323,7 +303,7 @@ ElementPtr e; /*XXX*/ Matrix->Diag[Col1] = pTwin2; Matrix->Diag[Col2] = pTwin1; - Matrix->NumberOfInterchangesIsOdd = NOT Matrix->NumberOfInterchangesIsOdd; + Matrix->NumberOfInterchangesIsOdd = !Matrix->NumberOfInterchangesIsOdd; return; } #endif /* MODIFIED_NODAL */ @@ -397,62 +377,59 @@ void spScale( eMatrix, RHS_ScaleFactors, SolutionScaleFactors ) char *eMatrix; -register RealVector RHS_ScaleFactors, SolutionScaleFactors; + RealVector RHS_ScaleFactors, SolutionScaleFactors; { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register ElementPtr pElement; -register int I, lSize, *pExtOrder; -RealNumber ScaleFactor; -void ScaleComplexMatrix(); + MatrixPtr Matrix = (MatrixPtr)eMatrix; + ElementPtr pElement; + int I, lSize, *pExtOrder; + RealNumber ScaleFactor; + void ScaleComplexMatrix(); -/* Begin `spScale'. */ - ASSERT( IS_VALID(Matrix) AND NOT Matrix->Factored ); - if (NOT Matrix->RowsLinked) spcLinkRows( Matrix ); + /* Begin `spScale'. */ + assert( IS_VALID(Matrix) && !Matrix->Factored ); + if (!Matrix->RowsLinked) spcLinkRows( Matrix ); -#if spCOMPLEX if (Matrix->Complex) - { ScaleComplexMatrix( Matrix, RHS_ScaleFactors, SolutionScaleFactors ); + { + ScaleComplexMatrix( Matrix, RHS_ScaleFactors, SolutionScaleFactors ); return; } -#endif -#if REAL lSize = Matrix->Size; -/* Correct pointers to arrays for ARRAY_OFFSET */ -#if NOT ARRAY_OFFSET - --RHS_ScaleFactors; - --SolutionScaleFactors; -#endif - -/* Scale Rows */ + /* Scale Rows */ pExtOrder = &Matrix->IntToExtRowMap[1]; for (I = 1; I <= lSize; I++) - { if ((ScaleFactor = RHS_ScaleFactors[*(pExtOrder++)]) != 1.0) - { pElement = Matrix->FirstInRow[I]; + { + if ((ScaleFactor = RHS_ScaleFactors[*(pExtOrder++)]) != 1.0) + { + pElement = Matrix->FirstInRow[I]; while (pElement != NULL) - { pElement->Real *= ScaleFactor; + { + pElement->Real *= ScaleFactor; pElement = pElement->NextInRow; } } } -/* Scale Columns */ + /* Scale Columns */ pExtOrder = &Matrix->IntToExtColMap[1]; for (I = 1; I <= lSize; I++) - { if ((ScaleFactor = SolutionScaleFactors[*(pExtOrder++)]) != 1.0) - { pElement = Matrix->FirstInCol[I]; + { + if ((ScaleFactor = SolutionScaleFactors[*(pExtOrder++)]) != 1.0) + { + pElement = Matrix->FirstInCol[I]; while (pElement != NULL) - { pElement->Real *= ScaleFactor; + { + pElement->Real *= ScaleFactor; pElement = pElement->NextInCol; } } } return; -#endif /* REAL */ } #endif /* SCALING */ @@ -464,7 +441,7 @@ void ScaleComplexMatrix(); -#if spCOMPLEX AND SCALING +#if SCALING /* * SCALE COMPLEX MATRIX * @@ -525,43 +502,43 @@ static void ScaleComplexMatrix( Matrix, RHS_ScaleFactors, SolutionScaleFactors ) MatrixPtr Matrix; -register RealVector RHS_ScaleFactors, SolutionScaleFactors; + RealVector RHS_ScaleFactors, SolutionScaleFactors; { -register ElementPtr pElement; -register int I, lSize, *pExtOrder; -RealNumber ScaleFactor; + ElementPtr pElement; + int I, lSize, *pExtOrder; + RealNumber ScaleFactor; -/* Begin `ScaleComplexMatrix'. */ + /* Begin `ScaleComplexMatrix'. */ lSize = Matrix->Size; -/* Correct pointers to arrays for ARRAY_OFFSET */ -#if NOT ARRAY_OFFSET - --RHS_ScaleFactors; - --SolutionScaleFactors; -#endif - -/* Scale Rows */ + /* Scale Rows */ pExtOrder = &Matrix->IntToExtRowMap[1]; for (I = 1; I <= lSize; I++) - { if ((ScaleFactor = RHS_ScaleFactors[*(pExtOrder++)]) != 1.0) - { pElement = Matrix->FirstInRow[I]; + { + if ((ScaleFactor = RHS_ScaleFactors[*(pExtOrder++)]) != 1.0) + { + pElement = Matrix->FirstInRow[I]; while (pElement != NULL) - { pElement->Real *= ScaleFactor; + { + pElement->Real *= ScaleFactor; pElement->Imag *= ScaleFactor; pElement = pElement->NextInRow; } } } -/* Scale Columns */ + /* Scale Columns */ pExtOrder = &Matrix->IntToExtColMap[1]; for (I = 1; I <= lSize; I++) - { if ((ScaleFactor = SolutionScaleFactors[*(pExtOrder++)]) != 1.0) - { pElement = Matrix->FirstInCol[I]; + { + if ((ScaleFactor = SolutionScaleFactors[*(pExtOrder++)]) != 1.0) + { + pElement = Matrix->FirstInCol[I]; while (pElement != NULL) - { pElement->Real *= ScaleFactor; + { + pElement->Real *= ScaleFactor; pElement->Imag *= ScaleFactor; pElement = pElement->NextInCol; } @@ -569,7 +546,7 @@ RealNumber ScaleFactor; } return; } -#endif /* SCALING AND spCOMPLEX */ +#endif /* SCALING */ @@ -596,55 +573,37 @@ RealNumber ScaleFactor; * Solution is the vector being multiplied by the matrix. * iRHS (RealVector) * iRHS is the imaginary portion of the right hand side. This is - * what is being solved for. This is only necessary if the matrix is - * complex and spSEPARATED_COMPLEX_VECTORS is TRUE. + * what is being solved for. * iSolution (RealVector) * iSolution is the imaginary portion of the vector being multiplied - * by the matrix. This is only necessary if the matrix is - * complex and spSEPARATED_COMPLEX_VECTORS is TRUE. - * - * >>> Obscure Macros - * IMAG_VECTORS - * Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and - * spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears - * without a trace. + * by the matrix. */ void -spMultiply( eMatrix, RHS, Solution IMAG_VECTORS ) - -char *eMatrix; -RealVector RHS, Solution IMAG_VECTORS; +spMultiply(void *eMatrix, RealVector RHS, RealVector Solution, + RealVector iRHS, RealVector iSolution) { -register ElementPtr pElement; -register RealVector Vector; -register RealNumber Sum; -register int I, *pExtOrder; -MatrixPtr Matrix = (MatrixPtr)eMatrix; -extern void ComplexMatrixMultiply(); + ElementPtr pElement; + RealVector Vector; + RealNumber Sum; + int I, *pExtOrder; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + extern void ComplexMatrixMultiply(); -/* Begin `spMultiply'. */ - ASSERT( IS_SPARSE( Matrix ) AND NOT Matrix->Factored ); - if (NOT Matrix->RowsLinked) + /* Begin `spMultiply'. */ + assert( IS_SPARSE( Matrix ) && !Matrix->Factored ); + if (!Matrix->RowsLinked) spcLinkRows(Matrix); - if (NOT Matrix->InternalVectorsAllocated) + if (!Matrix->InternalVectorsAllocated) spcCreateInternalVectors( Matrix ); -#if spCOMPLEX if (Matrix->Complex) - { ComplexMatrixMultiply( Matrix, RHS, Solution IMAG_VECTORS ); + { + ComplexMatrixMultiply( Matrix, RHS, Solution , iRHS, iSolution ); return; } -#endif -#if REAL -#if NOT ARRAY_OFFSET -/* Correct array pointers for ARRAY_OFFSET. */ - --RHS; - --Solution; -#endif - -/* Initialize Intermediate vector with reordered Solution vector. */ + /* Initialize Intermediate vector with reordered Solution vector. */ Vector = Matrix->Intermediate; pExtOrder = &Matrix->IntToExtColMap[Matrix->Size]; for (I = Matrix->Size; I > 0; I--) @@ -652,17 +611,18 @@ extern void ComplexMatrixMultiply(); pExtOrder = &Matrix->IntToExtRowMap[Matrix->Size]; for (I = Matrix->Size; I > 0; I--) - { pElement = Matrix->FirstInRow[I]; + { + pElement = Matrix->FirstInRow[I]; Sum = 0.0; while (pElement != NULL) - { Sum += pElement->Real * Vector[pElement->Col]; + { + Sum += pElement->Real * Vector[pElement->Col]; pElement = pElement->NextInRow; } RHS[*pExtOrder--] = Sum; } return; -#endif /* REAL */ } #endif /* MULTIPLICATION */ @@ -672,7 +632,7 @@ extern void ComplexMatrixMultiply(); -#if spCOMPLEX AND MULTIPLICATION +#if MULTIPLICATION /* * COMPLEX MATRIX MULTIPLICATION * @@ -685,86 +645,58 @@ extern void ComplexMatrixMultiply(); * Pointer to the matrix. * RHS (RealVector) * RHS is the right hand side. This is what is being solved for. - * This is only the real portion of the right-hand side if the matrix - * is complex and spSEPARATED_COMPLEX_VECTORS is set TRUE. * Solution (RealVector) - * Solution is the vector being multiplied by the matrix. This is only - * the real portion if the matrix is complex and - * spSEPARATED_COMPLEX_VECTORS is set TRUE. + * Solution is the vector being multiplied by the matrix. * iRHS (RealVector) * iRHS is the imaginary portion of the right hand side. This is - * what is being solved for. This is only necessary if the matrix is - * complex and spSEPARATED_COMPLEX_VECTORS is TRUE. + * what is being solved for. * iSolution (RealVector) * iSolution is the imaginary portion of the vector being multiplied - * by the matrix. This is only necessary if the matrix is - * complex and spSEPARATED_COMPLEX_VECTORS is TRUE. - * - * >>> Obscure Macros - * IMAG_VECTORS - * Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and - * spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears - * without a trace. + * by the matrix. */ static void -ComplexMatrixMultiply( Matrix, RHS, Solution IMAG_VECTORS ) +ComplexMatrixMultiply( Matrix, RHS, Solution , iRHS, iSolution ) MatrixPtr Matrix; -RealVector RHS, Solution IMAG_VECTORS; +RealVector RHS, Solution , iRHS, iSolution; { -register ElementPtr pElement; -register ComplexVector Vector; -ComplexNumber Sum; -register int I, *pExtOrder; + ElementPtr pElement; + ComplexVector Vector; + ComplexNumber Sum; + int I, *pExtOrder; -/* Begin `ComplexMatrixMultiply'. */ + /* Begin `ComplexMatrixMultiply'. */ -/* Correct array pointers for ARRAY_OFFSET. */ -#if NOT ARRAY_OFFSET -#if spSEPARATED_COMPLEX_VECTORS - --RHS; --iRHS; - --Solution; --iSolution; -#else - RHS -= 2; Solution -= 2; -#endif -#endif - -/* Initialize Intermediate vector with reordered Solution vector. */ + /* Initialize Intermediate vector with reordered Solution vector. */ Vector = (ComplexVector)Matrix->Intermediate; pExtOrder = &Matrix->IntToExtColMap[Matrix->Size]; -#if spSEPARATED_COMPLEX_VECTORS for (I = Matrix->Size; I > 0; I--) - { Vector[I].Real = Solution[*pExtOrder]; + { + Vector[I].Real = Solution[*pExtOrder]; Vector[I].Imag = iSolution[*(pExtOrder--)]; } -#else - for (I = Matrix->Size; I > 0; I--) - Vector[I] = ((ComplexVector)Solution)[*(pExtOrder--)]; -#endif pExtOrder = &Matrix->IntToExtRowMap[Matrix->Size]; for (I = Matrix->Size; I > 0; I--) - { pElement = Matrix->FirstInRow[I]; + { + pElement = Matrix->FirstInRow[I]; Sum.Real = Sum.Imag = 0.0; while (pElement != NULL) - { /* Cmplx expression : Sum += Element * Vector[Col] */ + { + /* Cmplx expression : Sum += Element * Vector[Col] */ CMPLX_MULT_ADD_ASSIGN( Sum, *pElement, Vector[pElement->Col] ); pElement = pElement->NextInRow; } -#if spSEPARATED_COMPLEX_VECTORS RHS[*pExtOrder] = Sum.Real; iRHS[*pExtOrder--] = Sum.Imag; -#else - ((ComplexVector)RHS)[*pExtOrder--] = Sum; -#endif } return; } -#endif /* spCOMPLEX AND MULTIPLICATION */ +#endif /* MULTIPLICATION */ @@ -773,7 +705,7 @@ register int I, *pExtOrder; -#if MULTIPLICATION AND TRANSPOSE +#if MULTIPLICATION && TRANSPOSE /* * TRANSPOSED MATRIX MULTIPLICATION * @@ -791,53 +723,35 @@ register int I, *pExtOrder; * Solution is the vector being multiplied by the matrix. * iRHS (RealVector) * iRHS is the imaginary portion of the right hand side. This is - * what is being solved for. This is only necessary if the matrix is - * complex and spSEPARATED_COMPLEX_VECTORS is TRUE. + * what is being solved for. * iSolution (RealVector) * iSolution is the imaginary portion of the vector being multiplied - * by the matrix. This is only necessary if the matrix is - * complex and spSEPARATED_COMPLEX_VECTORS is TRUE. - * - * >>> Obscure Macros - * IMAG_VECTORS - * Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and - * spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears - * without a trace. + * by the matrix. */ void -spMultTransposed( eMatrix, RHS, Solution IMAG_VECTORS ) - -char *eMatrix; -RealVector RHS, Solution IMAG_VECTORS; +spMultTransposed(void *eMatrix, RealVector RHS, RealVector Solution, + RealVector iRHS, RealVector iSolution) { -register ElementPtr pElement; -register RealVector Vector; -register RealNumber Sum; -register int I, *pExtOrder; -MatrixPtr Matrix = (MatrixPtr)eMatrix; -extern void ComplexTransposedMatrixMultiply(); + ElementPtr pElement; + RealVector Vector; + RealNumber Sum; + int I, *pExtOrder; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + extern void ComplexTransposedMatrixMultiply(); -/* Begin `spMultTransposed'. */ - ASSERT( IS_SPARSE( Matrix ) AND NOT Matrix->Factored ); - if (NOT Matrix->InternalVectorsAllocated) + /* Begin `spMultTransposed'. */ + assert( IS_SPARSE( Matrix ) && !Matrix->Factored ); + if (!Matrix->InternalVectorsAllocated) spcCreateInternalVectors( Matrix ); -#if spCOMPLEX if (Matrix->Complex) - { ComplexTransposedMatrixMultiply( Matrix, RHS, Solution IMAG_VECTORS ); + { + ComplexTransposedMatrixMultiply( Matrix, RHS, Solution , iRHS, iSolution ); return; } -#endif -#if REAL -#if NOT ARRAY_OFFSET -/* Correct array pointers for ARRAY_OFFSET. */ - --RHS; - --Solution; -#endif - -/* Initialize Intermediate vector with reordered Solution vector. */ + /* Initialize Intermediate vector with reordered Solution vector. */ Vector = Matrix->Intermediate; pExtOrder = &Matrix->IntToExtRowMap[Matrix->Size]; for (I = Matrix->Size; I > 0; I--) @@ -845,19 +759,20 @@ extern void ComplexTransposedMatrixMultiply(); pExtOrder = &Matrix->IntToExtColMap[Matrix->Size]; for (I = Matrix->Size; I > 0; I--) - { pElement = Matrix->FirstInCol[I]; + { + pElement = Matrix->FirstInCol[I]; Sum = 0.0; while (pElement != NULL) - { Sum += pElement->Real * Vector[pElement->Row]; + { + Sum += pElement->Real * Vector[pElement->Row]; pElement = pElement->NextInCol; } RHS[*pExtOrder--] = Sum; } return; -#endif /* REAL */ } -#endif /* MULTIPLICATION AND TRANSPOSE */ +#endif /* MULTIPLICATION && TRANSPOSE */ @@ -865,7 +780,7 @@ extern void ComplexTransposedMatrixMultiply(); -#if spCOMPLEX AND MULTIPLICATION AND TRANSPOSE +#if MULTIPLICATION && TRANSPOSE /* * COMPLEX TRANSPOSED MATRIX MULTIPLICATION * @@ -878,86 +793,58 @@ extern void ComplexTransposedMatrixMultiply(); * Pointer to the matrix. * RHS (RealVector) * RHS is the right hand side. This is what is being solved for. - * This is only the real portion of the right-hand side if the matrix - * is complex and spSEPARATED_COMPLEX_VECTORS is set TRUE. * Solution (RealVector) - * Solution is the vector being multiplied by the matrix. This is only - * the real portion if the matrix is complex and - * spSEPARATED_COMPLEX_VECTORS is set TRUE. + * Solution is the vector being multiplied by the matrix. * iRHS (RealVector) * iRHS is the imaginary portion of the right hand side. This is - * what is being solved for. This is only necessary if the matrix is - * complex and spSEPARATED_COMPLEX_VECTORS is TRUE. + * what is being solved for. * iSolution (RealVector) * iSolution is the imaginary portion of the vector being multiplied - * by the matrix. This is only necessary if the matrix is - * complex and spSEPARATED_COMPLEX_VECTORS is TRUE. - * - * >>> Obscure Macros - * IMAG_VECTORS - * Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and - * spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears - * without a trace. + * by the matrix. */ static void -ComplexTransposedMatrixMultiply( Matrix, RHS, Solution IMAG_VECTORS ) +ComplexTransposedMatrixMultiply( Matrix, RHS, Solution , iRHS, iSolution ) MatrixPtr Matrix; -RealVector RHS, Solution IMAG_VECTORS; +RealVector RHS, Solution , iRHS, iSolution; { -register ElementPtr pElement; -register ComplexVector Vector; -ComplexNumber Sum; -register int I, *pExtOrder; + ElementPtr pElement; + ComplexVector Vector; + ComplexNumber Sum; + int I, *pExtOrder; -/* Begin `ComplexMatrixMultiply'. */ + /* Begin `ComplexMatrixMultiply'. */ -/* Correct array pointers for ARRAY_OFFSET. */ -#if NOT ARRAY_OFFSET -#if spSEPARATED_COMPLEX_VECTORS - --RHS; --iRHS; - --Solution; --iSolution; -#else - RHS -= 2; Solution -= 2; -#endif -#endif - -/* Initialize Intermediate vector with reordered Solution vector. */ + /* Initialize Intermediate vector with reordered Solution vector. */ Vector = (ComplexVector)Matrix->Intermediate; pExtOrder = &Matrix->IntToExtRowMap[Matrix->Size]; -#if spSEPARATED_COMPLEX_VECTORS for (I = Matrix->Size; I > 0; I--) - { Vector[I].Real = Solution[*pExtOrder]; + { + Vector[I].Real = Solution[*pExtOrder]; Vector[I].Imag = iSolution[*(pExtOrder--)]; } -#else - for (I = Matrix->Size; I > 0; I--) - Vector[I] = ((ComplexVector)Solution)[*(pExtOrder--)]; -#endif pExtOrder = &Matrix->IntToExtColMap[Matrix->Size]; for (I = Matrix->Size; I > 0; I--) - { pElement = Matrix->FirstInCol[I]; + { + pElement = Matrix->FirstInCol[I]; Sum.Real = Sum.Imag = 0.0; while (pElement != NULL) - { /* Cmplx expression : Sum += Element * Vector[Row] */ + { + /* Cmplx expression : Sum += Element * Vector[Row] */ CMPLX_MULT_ADD_ASSIGN( Sum, *pElement, Vector[pElement->Row] ); pElement = pElement->NextInCol; } -#if spSEPARATED_COMPLEX_VECTORS RHS[*pExtOrder] = Sum.Real; iRHS[*pExtOrder--] = Sum.Imag; -#else - ((ComplexVector)RHS)[*pExtOrder--] = Sum; -#endif } return; } -#endif /* spCOMPLEX AND MULTIPLICATION AND TRANSPOSE */ +#endif /* MULTIPLICATION && TRANSPOSE */ @@ -1002,66 +889,60 @@ register int I, *pExtOrder; * Norm (RealNumber) * L-infinity norm of a complex number. * Size (int) - * Local storage for Matrix->Size. Placed in a register for speed. + * Local storage for Matrix->Size. Placed in a for speed. * Temp (RealNumber) * Temporary storage for real portion of determinant. */ -#if spCOMPLEX void -spDeterminant( eMatrix, pExponent, pDeterminant, piDeterminant ) -RealNumber *piDeterminant; -#else -void -spDeterminant( eMatrix, pExponent, pDeterminant ) -#endif - -char *eMatrix; -register RealNumber *pDeterminant; -int *pExponent; +spDeterminant(void *eMatrix, int *pExponent, RealNumber *pDeterminant, + RealNumber *piDeterminant) { -register MatrixPtr Matrix = (MatrixPtr)eMatrix; -register int I, Size; -RealNumber Norm, nr, ni; -ComplexNumber Pivot, cDeterminant; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + int I, Size; + RealNumber Norm, nr, ni; + ComplexNumber Pivot, cDeterminant; #define NORM(a) (nr = ABS((a).Real), ni = ABS((a).Imag), MAX (nr,ni)) -/* Begin `spDeterminant'. */ - ASSERT( IS_SPARSE( Matrix ) AND IS_FACTORED(Matrix) ); + /* Begin `spDeterminant'. */ + assert( IS_SPARSE( Matrix ) && IS_FACTORED(Matrix) ); *pExponent = 0; if (Matrix->Error == spSINGULAR) - { *pDeterminant = 0.0; -#if spCOMPLEX + { + *pDeterminant = 0.0; if (Matrix->Complex) *piDeterminant = 0.0; -#endif return; } Size = Matrix->Size; I = 0; -#if spCOMPLEX if (Matrix->Complex) /* Complex Case. */ - { cDeterminant.Real = 1.0; + { + cDeterminant.Real = 1.0; cDeterminant.Imag = 0.0; while (++I <= Size) - { CMPLX_RECIPROCAL( Pivot, *Matrix->Diag[I] ); + { + CMPLX_RECIPROCAL( Pivot, *Matrix->Diag[I] ); CMPLX_MULT_ASSIGN( cDeterminant, Pivot ); -/* Scale Determinant. */ + /* Scale Determinant. */ Norm = NORM( cDeterminant ); if (Norm != 0.0) - { while (Norm >= 1.0e12) - { cDeterminant.Real *= 1.0e-12; + { + while (Norm >= 1.0e12) + { + cDeterminant.Real *= 1.0e-12; cDeterminant.Imag *= 1.0e-12; *pExponent += 12; Norm = NORM( cDeterminant ); } while (Norm < 1.0e-12) - { cDeterminant.Real *= 1.0e12; + { + cDeterminant.Real *= 1.0e12; cDeterminant.Imag *= 1.0e12; *pExponent -= 12; Norm = NORM( cDeterminant ); @@ -1069,17 +950,20 @@ ComplexNumber Pivot, cDeterminant; } } -/* Scale Determinant again, this time to be between 1.0 <= x < 10.0. */ + /* Scale Determinant again, this time to be between 1.0 <= x < 10.0. */ Norm = NORM( cDeterminant ); if (Norm != 0.0) - { while (Norm >= 10.0) - { cDeterminant.Real *= 0.1; + { + while (Norm >= 10.0) + { + cDeterminant.Real *= 0.1; cDeterminant.Imag *= 0.1; (*pExponent)++; Norm = NORM( cDeterminant ); } while (Norm < 1.0) - { cDeterminant.Real *= 10.0; + { + cDeterminant.Real *= 10.0; cDeterminant.Imag *= 10.0; (*pExponent)--; Norm = NORM( cDeterminant ); @@ -1091,45 +975,49 @@ ComplexNumber Pivot, cDeterminant; *pDeterminant = cDeterminant.Real; *piDeterminant = cDeterminant.Imag; } -#endif /* spCOMPLEX */ -#if REAL AND spCOMPLEX else -#endif -#if REAL - { /* Real Case. */ + { + /* Real Case. */ *pDeterminant = 1.0; while (++I <= Size) - { *pDeterminant /= Matrix->Diag[I]->Real; + { + *pDeterminant /= Matrix->Diag[I]->Real; -/* Scale Determinant. */ + /* Scale Determinant. */ if (*pDeterminant != 0.0) - { while (ABS(*pDeterminant) >= 1.0e12) - { *pDeterminant *= 1.0e-12; + { + while (ABS(*pDeterminant) >= 1.0e12) + { + *pDeterminant *= 1.0e-12; *pExponent += 12; } while (ABS(*pDeterminant) < 1.0e-12) - { *pDeterminant *= 1.0e12; + { + *pDeterminant *= 1.0e12; *pExponent -= 12; } } } -/* Scale Determinant again, this time to be between 1.0 <= x < 10.0. */ + /* Scale Determinant again, this time to be between 1.0 <= x < + 10.0. */ if (*pDeterminant != 0.0) - { while (ABS(*pDeterminant) >= 10.0) - { *pDeterminant *= 0.1; + { + while (ABS(*pDeterminant) >= 10.0) + { + *pDeterminant *= 0.1; (*pExponent)++; } while (ABS(*pDeterminant) < 1.0) - { *pDeterminant *= 10.0; + { + *pDeterminant *= 10.0; (*pExponent)--; } } if (Matrix->NumberOfInterchangesIsOdd) *pDeterminant = -*pDeterminant; } -#endif /* REAL */ } #endif /* DETERMINANT */ @@ -1170,25 +1058,27 @@ spStripFills( eMatrix ) char *eMatrix; { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -struct FillinListNodeStruct *pListNode; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + struct FillinListNodeStruct *pListNode; -/* Begin `spStripFills'. */ - ASSERT( IS_SPARSE( Matrix ) ); + /* Begin `spStripFills'. */ + assert( IS_SPARSE( Matrix ) ); if (Matrix->Fillins == 0) return; Matrix->NeedsOrdering = YES; Matrix->Elements -= Matrix->Fillins; Matrix->Fillins = 0; -/* Mark the fill-ins. */ - { register ElementPtr pFillin, pLastFillin; + /* Mark the fill-ins. */ + { + ElementPtr pFillin, pLastFillin; pListNode = Matrix->LastFillinListNode = Matrix->FirstFillinListNode; Matrix->FillinsRemaining = pListNode->NumberOfFillinsInList; Matrix->NextAvailFillin = pListNode->pFillinList; while (pListNode != NULL) - { pFillin = pListNode->pFillinList; + { + pFillin = pListNode->pFillinList; pLastFillin = &(pFillin[ pListNode->NumberOfFillinsInList - 1 ]); while (pFillin <= pLastFillin) (pFillin++)->Row = 0; @@ -1196,16 +1086,20 @@ struct FillinListNodeStruct *pListNode; } } -/* Unlink fill-ins by searching for elements marked with Row = 0. */ - { register ElementPtr pElement, *ppElement; - register int I, Size = Matrix->Size; + /* Unlink fill-ins by searching for elements marked with Row = 0. */ + { + ElementPtr pElement, *ppElement; + int I, Size = Matrix->Size; -/* Unlink fill-ins in all columns. */ + /* Unlink fill-ins in all columns. */ for (I = 1; I <= Size; I++) - { ppElement = &(Matrix->FirstInCol[I]); + { + ppElement = &(Matrix->FirstInCol[I]); while ((pElement = *ppElement) != NULL) - { if (pElement->Row == 0) - { *ppElement = pElement->NextInCol; /* Unlink fill-in. */ + { + if (pElement->Row == 0) + { + *ppElement = pElement->NextInCol; /* Unlink fill-in. */ if (Matrix->Diag[pElement->Col] == pElement) Matrix->Diag[pElement->Col] = NULL; } @@ -1214,11 +1108,13 @@ struct FillinListNodeStruct *pListNode; } } -/* Unlink fill-ins in all rows. */ + /* Unlink fill-ins in all rows. */ for (I = 1; I <= Size; I++) - { ppElement = &(Matrix->FirstInRow[I]); + { + ppElement = &(Matrix->FirstInRow[I]); while ((pElement = *ppElement) != NULL) - { if (pElement->Row == 0) + { + if (pElement->Row == 0) *ppElement = pElement->NextInRow; /* Unlink fill-in. */ else ppElement = &pElement->NextInRow; /* Skip element. */ @@ -1228,18 +1124,18 @@ struct FillinListNodeStruct *pListNode; return; } -/* Same as above, but strips entire matrix without destroying the frame. - * This assumes that the matrix will be replaced with one of the same size. - */ +/* Same as above, but strips entire matrix without destroying the + * frame. This assumes that the matrix will be replaced with one of + * the same size. */ void spStripMatrix( eMatrix ) char *eMatrix; { -MatrixPtr Matrix = (MatrixPtr)eMatrix; + MatrixPtr Matrix = (MatrixPtr)eMatrix; -/* Begin `spStripMatrix'. */ - ASSERT( IS_SPARSE( Matrix ) ); + /* Begin `spStripMatrix'. */ + assert( IS_SPARSE( Matrix ) ); if (Matrix->Elements == 0) return; Matrix->RowsLinked = NO; Matrix->NeedsOrdering = YES; @@ -1247,8 +1143,9 @@ MatrixPtr Matrix = (MatrixPtr)eMatrix; Matrix->Originals = 0; Matrix->Fillins = 0; -/* Reset the element lists. */ - { register ElementPtr pElement; + /* Reset the element lists. */ + { + ElementPtr pElement; struct ElementListNodeStruct *pListNode; pListNode = Matrix->LastElementListNode = Matrix->FirstElementListNode; @@ -1256,8 +1153,9 @@ MatrixPtr Matrix = (MatrixPtr)eMatrix; Matrix->NextAvailElement = pListNode->pElementList; } -/* Reset the fill-in lists. */ - { register ElementPtr pFillin; + /* Reset the fill-in lists. */ + { + ElementPtr pFillin; struct FillinListNodeStruct *pListNode; pListNode = Matrix->LastFillinListNode = Matrix->FirstFillinListNode; @@ -1265,10 +1163,12 @@ MatrixPtr Matrix = (MatrixPtr)eMatrix; Matrix->NextAvailFillin = pListNode->pFillinList; } -/* Reset the Row, Column and Diag pointers */ - { register int I, Size = Matrix->Size; + /* Reset the Row, Column and Diag pointers */ + { + int I, Size = Matrix->Size; for (I = 1; I <= Size; I++) - { Matrix->FirstInRow[I] = NULL; + { + Matrix->FirstInRow[I] = NULL; Matrix->FirstInCol[I] = NULL; Matrix->Diag[I] = NULL; } @@ -1282,7 +1182,7 @@ MatrixPtr Matrix = (MatrixPtr)eMatrix; -#if TRANSLATE AND DELETE +#if TRANSLATE && DELETE /* * DELETE A ROW AND COLUMN FROM THE MATRIX * @@ -1318,55 +1218,53 @@ MatrixPtr Matrix = (MatrixPtr)eMatrix; */ void -spDeleteRowAndCol( eMatrix, Row, Col ) - -char *eMatrix; -int Row, Col; +spDeleteRowAndCol(char *eMatrix, int Row, int Col ) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register ElementPtr pElement, *ppElement, pLastElement; -int Size, ExtRow, ExtCol; -ElementPtr spcFindElementInCol(); + MatrixPtr Matrix = (MatrixPtr)eMatrix; + ElementPtr pElement, *ppElement, pLastElement; + int Size, ExtRow, ExtCol; + ElementPtr spcFindElementInCol(); -/* Begin `spDeleteRowAndCol'. */ + /* Begin `spDeleteRowAndCol'. */ - ASSERT( IS_SPARSE(Matrix) AND Row > 0 AND Col > 0 ); - ASSERT( Row <= Matrix->ExtSize AND Col <= Matrix->ExtSize ); + assert( IS_SPARSE(Matrix) && Row > 0 && Col > 0 ); + assert( Row <= Matrix->ExtSize && Col <= Matrix->ExtSize ); Size = Matrix->Size; ExtRow = Row; ExtCol = Col; - if (NOT Matrix->RowsLinked) spcLinkRows( Matrix ); + if (!Matrix->RowsLinked) + spcLinkRows( Matrix ); Row = Matrix->ExtToIntRowMap[Row]; Col = Matrix->ExtToIntColMap[Col]; - ASSERT( Row > 0 AND Col > 0 ); + assert( Row > 0 && Col > 0 ); -/* Move Row so that it is the last row in the matrix. */ + /* Move Row so that it is the last row in the matrix. */ if (Row != Size) spcRowExchange( Matrix, Row, Size ); -/* Move Col so that it is the last column in the matrix. */ + /* Move Col so that it is the last column in the matrix. */ if (Col != Size) spcColExchange( Matrix, Col, Size ); -/* Correct Diag pointers. */ + /* Correct Diag pointers. */ if (Row == Col) - SWAP( ElementPtr, Matrix->Diag[Row], Matrix->Diag[Size] ) - else - { Matrix->Diag[Row] = spcFindElementInCol( Matrix, Matrix->FirstInCol+Row, - Row, Row, NO ); - Matrix->Diag[Col] = spcFindElementInCol( Matrix, Matrix->FirstInCol+Col, - Col, Col, NO ); + SWAP( ElementPtr, Matrix->Diag[Row], Matrix->Diag[Size] ); + else { + Matrix->Diag[Row] = spcFindElementInCol(Matrix, + Matrix->FirstInCol+Row, + Row, Row, NO ); + Matrix->Diag[Col] = spcFindElementInCol(Matrix, + Matrix->FirstInCol+Col, + Col, Col, NO ); } -/* - * Delete last row and column of the matrix. - */ -/* Break the column links to every element in the last row. */ + /* Delete last row and column of the matrix. */ + /* Break the column links to every element in the last row. */ pLastElement = Matrix->FirstInRow[ Size ]; - while (pLastElement != NULL) - { ppElement = &(Matrix->FirstInCol[ pLastElement->Col ]); - while ((pElement = *ppElement) != NULL) - { if (pElement == pLastElement) + while (pLastElement != NULL) { + ppElement = &(Matrix->FirstInCol[ pLastElement->Col ]); + while ((pElement = *ppElement) != NULL) { + if (pElement == pLastElement) *ppElement = NULL; /* Unlink last element in column. */ else ppElement = &pElement->NextInCol; /* Skip element. */ @@ -1374,20 +1272,20 @@ ElementPtr spcFindElementInCol(); pLastElement = pLastElement->NextInRow; } -/* Break the row links to every element in the last column. */ + /* Break the row links to every element in the last column. */ pLastElement = Matrix->FirstInCol[ Size ]; - while (pLastElement != NULL) - { ppElement = &(Matrix->FirstInRow[ pLastElement->Row ]); - while ((pElement = *ppElement) != NULL) - { if (pElement == pLastElement) - *ppElement = NULL; /* Unlink last element in row. */ + while (pLastElement != NULL) { + ppElement = &(Matrix->FirstInRow[ pLastElement->Row ]); + while ((pElement = *ppElement) != NULL) { + if (pElement == pLastElement) + *ppElement = NULL; /* Unlink last element in row. */ else - ppElement = &pElement->NextInRow; /* Skip element. */ + ppElement = &pElement->NextInRow; /* Skip element. */ } pLastElement = pLastElement->NextInCol; } -/* Clean up some details. */ + /* Clean up some details. */ Matrix->Size = Size - 1; Matrix->Diag[Size] = NULL; Matrix->FirstInRow[Size] = NULL; @@ -1416,12 +1314,12 @@ ElementPtr spcFindElementInCol(); * pivots. This quantity is an indicator of ill-conditioning in the * matrix. If this ratio is large, and if the matrix is scaled such * that uncertainties in the RHS and the matrix entries are - * equilibrated, then the matrix is ill-conditioned. However, a small - * ratio does not necessarily imply that the matrix is - * well-conditioned. This routine must only be used after a matrix has - * been factored by spOrderAndFactor() or spFactor() and before it is - * cleared by spClear() or spInitialize(). The pseudocondition is - * faster to compute than the condition number calculated by + * equilibrated, then the matrix is ill-conditioned. However, a + * small ratio does not necessarily imply that the matrix is + * well-conditioned. This routine must only be used after a matrix + * has been factored by spOrderAndFactor() or spFactor() and before + * it is cleared by spClear() or spInitialize(). The pseudocondition + * is faster to compute than the condition number calculated by * spCondition(), but is not as informative. * * >>> Returns: @@ -1430,35 +1328,33 @@ ElementPtr spcFindElementInCol(); * * >>> Arguments: * eMatrix (char *) - * Pointer to the matrix. - */ + * Pointer to the matrix. */ RealNumber -spPseudoCondition( eMatrix ) - -char *eMatrix; +spPseudoCondition(char *eMatrix) { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register int I; -register ArrayOfElementPtrs Diag; -RealNumber MaxPivot, MinPivot, Mag; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + int I; + ArrayOfElementPtrs Diag; + RealNumber MaxPivot, MinPivot, Mag; -/* Begin `spPseudoCondition'. */ + /* Begin `spPseudoCondition'. */ - ASSERT( IS_SPARSE(Matrix) AND IS_FACTORED(Matrix) ); - if (Matrix->Error == spSINGULAR OR Matrix->Error == spZERO_DIAG) + assert( IS_SPARSE(Matrix) && IS_FACTORED(Matrix) ); + if (Matrix->Error == spSINGULAR || Matrix->Error == spZERO_DIAG) return 0.0; Diag = Matrix->Diag; MaxPivot = MinPivot = ELEMENT_MAG( Diag[1] ); for (I = 2; I <= Matrix->Size; I++) - { Mag = ELEMENT_MAG( Diag[I] ); - if (Mag > MaxPivot) - MaxPivot = Mag; - else if (Mag < MinPivot) - MinPivot = Mag; + { + Mag = ELEMENT_MAG( Diag[I] ); + if (Mag > MaxPivot) + MaxPivot = Mag; + else if (Mag < MinPivot) + MinPivot = Mag; } - ASSERT( MaxPivot > 0.0); + assert( MaxPivot > 0.0); return MaxPivot / MinPivot; } #endif @@ -1475,20 +1371,22 @@ RealNumber MaxPivot, MinPivot, Mag; * ESTIMATE CONDITION NUMBER * * Computes an estimate of the condition number using a variation on - * the LINPACK condition number estimation algorithm. This quantity is - * an indicator of ill-conditioning in the matrix. To avoid problems - * with overflow, the reciprocal of the condition number is returned. - * If this number is small, and if the matrix is scaled such that - * uncertainties in the RHS and the matrix entries are equilibrated, - * then the matrix is ill-conditioned. If the this number is near - * one, the matrix is well conditioned. This routine must only be - * used after a matrix has been factored by spOrderAndFactor() or - * spFactor() and before it is cleared by spClear() or spInitialize(). + * the LINPACK condition number estimation algorithm. This quantity + * is an indicator of ill-conditioning in the matrix. To avoid + * problems with overflow, the reciprocal of the condition number is + * returned. If this number is small, and if the matrix is scaled + * such that uncertainties in the RHS and the matrix entries are + * equilibrated, then the matrix is ill-conditioned. If the this + * number is near one, the matrix is well conditioned. This routine + * must only be used after a matrix has been factored by + * spOrderAndFactor() or spFactor() and before it is cleared by + * spClear() or spInitialize(). * * Unlike the LINPACK condition number estimator, this routines * returns the L infinity condition number. This is an artifact of * Sparse placing ones on the diagonal of the upper triangular matrix - * rather than the lower. This difference should be of no importance. + * rather than the lower. This difference should be of no + * importance. * * References: * A.K. Cline, C.B. Moler, G.W. Stewart, J.H. Wilkinson. An estimate @@ -1521,8 +1419,7 @@ RealNumber MaxPivot, MinPivot, Mag; * * >>> Possible errors: * spSINGULAR - * spNO_MEMORY - */ + * spNO_MEMORY */ RealNumber spCondition( eMatrix, NormOfMatrix, pError ) @@ -1531,60 +1428,53 @@ char *eMatrix; RealNumber NormOfMatrix; int *pError; { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register ElementPtr pElement; -register RealVector T, Tm; -register int I, K, Row; -ElementPtr pPivot; -int Size; -RealNumber E, Em, Wp, Wm, ASp, ASm, ASw, ASy, ASv, ASz, MaxY, ScaleFactor; -RealNumber Linpack, OLeary, InvNormOfInverse, ComplexCondition(); + MatrixPtr Matrix = (MatrixPtr)eMatrix; + ElementPtr pElement; + RealVector T, Tm; + int I, K, Row; + ElementPtr pPivot; + int Size; + RealNumber E, Em, Wp, Wm, ASp, ASm, ASw, ASy, ASv, ASz, MaxY, ScaleFactor; + RealNumber Linpack, OLeary, InvNormOfInverse, ComplexCondition(); #define SLACK 1e4 -/* Begin `spCondition'. */ + /* Begin `spCondition'. */ - ASSERT( IS_SPARSE(Matrix) AND IS_FACTORED(Matrix) ); + assert( IS_SPARSE(Matrix) && IS_FACTORED(Matrix) ); *pError = Matrix->Error; if (Matrix->Error >= spFATAL) return 0.0; if (NormOfMatrix == 0.0) - { *pError = spSINGULAR; + { + *pError = spSINGULAR; return 0.0; } -#if spCOMPLEX if (Matrix->Complex) return ComplexCondition( Matrix, NormOfMatrix, pError ); -#endif -#if REAL Size = Matrix->Size; T = Matrix->Intermediate; -#if spCOMPLEX Tm = Matrix->Intermediate + Size; -#else - Tm = ALLOC( RealNumber, Size+1 ); - if (Tm == NULL) - { *pError = spNO_MEMORY; - return 0.0; - } -#endif for (I = Size; I > 0; I--) T[I] = 0.0; -/* - * Part 1. Ay = e. - * Solve Ay = LUy = e where e consists of +1 and -1 terms with the sign - * chosen to maximize the size of w in Lw = e. Since the terms in w can - * get very large, scaling is used to avoid overflow. - */ + /* + * Part 1. Ay = e. + * + * Solve Ay = LUy = e where e consists of +1 and -1 terms with the + * sign chosen to maximize the size of w in Lw = e. Since the + * terms in w can get very large, scaling is used to avoid + * overflow. */ -/* Forward elimination. Solves Lw = e while choosing e. */ + /* Forward elimination. Solves Lw = e while choosing e. */ E = 1.0; for (I = 1; I <= Size; I++) - { pPivot = Matrix->Diag[I]; + { + pPivot = Matrix->Diag[I]; if (T[I] < 0.0) Em = -E; else Em = E; Wm = (Em + T[I]) * pPivot->Real; if (ABS(Wm) > SLACK) - { ScaleFactor = 1.0 / MAX( SQR( SLACK ), ABS(Wm) ); + { + ScaleFactor = 1.0 / MAX( SQR( SLACK ), ABS(Wm) ); for (K = Size; K > 0; K--) T[K] *= ScaleFactor; E *= ScaleFactor; Em *= ScaleFactor; @@ -1594,10 +1484,12 @@ RealNumber Linpack, OLeary, InvNormOfInverse, ComplexCondition(); ASp = ABS(T[I] - Em); ASm = ABS(Em + T[I]); -/* Update T for both values of W, minus value is placed in Tm. */ + /* Update T for both values of W, minus value is placed in + Tm. */ pElement = pPivot->NextInCol; while (pElement != NULL) - { Row = pElement->Row; + { + Row = pElement->Row; Tm[Row] = T[Row] - (Wm * pElement->Real); T[Row] -= (Wp * pElement->Real); ASp += ABS(T[Row]); @@ -1605,115 +1497,127 @@ RealNumber Linpack, OLeary, InvNormOfInverse, ComplexCondition(); pElement = pElement->NextInCol; } -/* If minus value causes more growth, overwrite T with its values. */ + /* If minus value causes more growth, overwrite T with its + values. */ if (ASm > ASp) - { T[I] = Wm; + { + T[I] = Wm; pElement = pPivot->NextInCol; while (pElement != NULL) - { T[pElement->Row] = Tm[pElement->Row]; + { + T[pElement->Row] = Tm[pElement->Row]; pElement = pElement->NextInCol; } } else T[I] = Wp; } -/* Compute 1-norm of T, which now contains w, and scale ||T|| to 1/SLACK. */ + /* Compute 1-norm of T, which now contains w, and scale ||T|| to + 1/SLACK. */ for (ASw = 0.0, I = Size; I > 0; I--) ASw += ABS(T[I]); ScaleFactor = 1.0 / (SLACK * ASw); if (ScaleFactor < 0.5) - { for (I = Size; I > 0; I--) T[I] *= ScaleFactor; + { + for (I = Size; I > 0; I--) T[I] *= ScaleFactor; E *= ScaleFactor; } -/* Backward Substitution. Solves Uy = w.*/ + /* Backward Substitution. Solves Uy = w.*/ for (I = Size; I >= 1; I--) - { pElement = Matrix->Diag[I]->NextInRow; + { + pElement = Matrix->Diag[I]->NextInRow; while (pElement != NULL) - { T[I] -= pElement->Real * T[pElement->Col]; + { + T[I] -= pElement->Real * T[pElement->Col]; pElement = pElement->NextInRow; } if (ABS(T[I]) > SLACK) - { ScaleFactor = 1.0 / MAX( SQR( SLACK ), ABS(T[I]) ); + { + ScaleFactor = 1.0 / MAX( SQR( SLACK ), ABS(T[I]) ); for (K = Size; K > 0; K--) T[K] *= ScaleFactor; E *= ScaleFactor; } } -/* Compute 1-norm of T, which now contains y, and scale ||T|| to 1/SLACK. */ + /* Compute 1-norm of T, which now contains y, and scale ||T|| to + 1/SLACK. */ for (ASy = 0.0, I = Size; I > 0; I--) ASy += ABS(T[I]); ScaleFactor = 1.0 / (SLACK * ASy); if (ScaleFactor < 0.5) - { for (I = Size; I > 0; I--) T[I] *= ScaleFactor; + { + for (I = Size; I > 0; I--) T[I] *= ScaleFactor; ASy = 1.0 / SLACK; E *= ScaleFactor; } -/* Compute infinity-norm of T for O'Leary's estimate. */ + /* Compute infinity-norm of T for O'Leary's estimate. */ for (MaxY = 0.0, I = Size; I > 0; I--) if (MaxY < ABS(T[I])) MaxY = ABS(T[I]); -/* - * Part 2. A* z = y where the * represents the transpose. - * Recall that A = LU implies A* = U* L*. - */ + /* + * Part 2. + * + * A* z = y where the * represents the transpose. Recall that A = + * LU implies A* = U* L*. */ -/* Forward elimination, U* v = y. */ + /* Forward elimination, U* v = y. */ for (I = 1; I <= Size; I++) - { pElement = Matrix->Diag[I]->NextInRow; + { + pElement = Matrix->Diag[I]->NextInRow; while (pElement != NULL) - { T[pElement->Col] -= T[I] * pElement->Real; + { + T[pElement->Col] -= T[I] * pElement->Real; pElement = pElement->NextInRow; } if (ABS(T[I]) > SLACK) - { ScaleFactor = 1.0 / MAX( SQR( SLACK ), ABS(T[I]) ); + { + ScaleFactor = 1.0 / MAX( SQR( SLACK ), ABS(T[I]) ); for (K = Size; K > 0; K--) T[K] *= ScaleFactor; ASy *= ScaleFactor; } } -/* Compute 1-norm of T, which now contains v, and scale ||T|| to 1/SLACK. */ + /* Compute 1-norm of T, which now contains v, and scale ||T|| to 1/SLACK. */ for (ASv = 0.0, I = Size; I > 0; I--) ASv += ABS(T[I]); ScaleFactor = 1.0 / (SLACK * ASv); if (ScaleFactor < 0.5) - { for (I = Size; I > 0; I--) T[I] *= ScaleFactor; + { + for (I = Size; I > 0; I--) T[I] *= ScaleFactor; ASy *= ScaleFactor; } -/* Backward Substitution, L* z = v. */ + /* Backward Substitution, L* z = v. */ for (I = Size; I >= 1; I--) - { pPivot = Matrix->Diag[I]; + { + pPivot = Matrix->Diag[I]; pElement = pPivot->NextInCol; while (pElement != NULL) - { T[I] -= pElement->Real * T[pElement->Row]; + { + T[I] -= pElement->Real * T[pElement->Row]; pElement = pElement->NextInCol; } T[I] *= pPivot->Real; if (ABS(T[I]) > SLACK) - { ScaleFactor = 1.0 / MAX( SQR( SLACK ), ABS(T[I]) ); + { + ScaleFactor = 1.0 / MAX( SQR( SLACK ), ABS(T[I]) ); for (K = Size; K > 0; K--) T[K] *= ScaleFactor; ASy *= ScaleFactor; } } -/* Compute 1-norm of T, which now contains z. */ + /* Compute 1-norm of T, which now contains z. */ for (ASz = 0.0, I = Size; I > 0; I--) ASz += ABS(T[I]); -#if NOT spCOMPLEX - FREE( Tm ); -#endif - Linpack = ASy / ASz; OLeary = E / MaxY; InvNormOfInverse = MIN( Linpack, OLeary ); return InvNormOfInverse / NormOfMatrix; -#endif /* REAL */ } -#if spCOMPLEX /* * ESTIMATE CONDITION NUMBER * @@ -1742,44 +1646,48 @@ MatrixPtr Matrix; RealNumber NormOfMatrix; int *pError; { -register ElementPtr pElement; -register ComplexVector T, Tm; -register int I, K, Row; -ElementPtr pPivot; -int Size; -RealNumber E, Em, ASp, ASm, ASw, ASy, ASv, ASz, MaxY, ScaleFactor; -RealNumber Linpack, OLeary, InvNormOfInverse; -ComplexNumber Wp, Wm; + ElementPtr pElement; + ComplexVector T, Tm; + int I, K, Row; + ElementPtr pPivot; + int Size; + RealNumber E, Em, ASp, ASm, ASw, ASy, ASv, ASz, MaxY, ScaleFactor; + RealNumber Linpack, OLeary, InvNormOfInverse; + ComplexNumber Wp, Wm; -/* Begin `ComplexCondition'. */ + /* Begin `ComplexCondition'. */ Size = Matrix->Size; T = (ComplexVector)Matrix->Intermediate; Tm = ALLOC( ComplexNumber, Size+1 ); if (Tm == NULL) - { *pError = spNO_MEMORY; + { + *pError = spNO_MEMORY; return 0.0; } for (I = Size; I > 0; I--) T[I].Real = T[I].Imag = 0.0; -/* - * Part 1. Ay = e. - * Solve Ay = LUy = e where e consists of +1 and -1 terms with the sign - * chosen to maximize the size of w in Lw = e. Since the terms in w can - * get very large, scaling is used to avoid overflow. - */ + /* + * Part 1. Ay = e. + * + * Solve Ay = LUy = e where e consists of +1 and -1 terms with the + * sign chosen to maximize the size of w in Lw = e. Since the + * terms in w can get very large, scaling is used to avoid + * overflow. */ -/* Forward elimination. Solves Lw = e while choosing e. */ + /* Forward elimination. Solves Lw = e while choosing e. */ E = 1.0; for (I = 1; I <= Size; I++) - { pPivot = Matrix->Diag[I]; + { + pPivot = Matrix->Diag[I]; if (T[I].Real < 0.0) Em = -E; else Em = E; Wm = T[I]; Wm.Real += Em; ASm = CMPLX_1_NORM( Wm ); CMPLX_MULT_ASSIGN( Wm, *pPivot ); if (CMPLX_1_NORM(Wm) > SLACK) - { ScaleFactor = 1.0 / MAX( SQR( SLACK ), CMPLX_1_NORM(Wm) ); + { + ScaleFactor = 1.0 / MAX( SQR( SLACK ), CMPLX_1_NORM(Wm) ); for (K = Size; K > 0; K--) SCLR_MULT_ASSIGN( T[K], ScaleFactor ); E *= ScaleFactor; Em *= ScaleFactor; @@ -1791,10 +1699,11 @@ ComplexNumber Wp, Wm; ASp = CMPLX_1_NORM( Wp ); CMPLX_MULT_ASSIGN( Wp, *pPivot ); -/* Update T for both values of W, minus value is placed in Tm. */ + /* Update T for both values of W, minus value is placed in Tm. */ pElement = pPivot->NextInCol; while (pElement != NULL) - { Row = pElement->Row; + { + Row = pElement->Row; /* Cmplx expr: Tm[Row] = T[Row] - (Wp * *pElement). */ CMPLX_MULT_SUBT( Tm[Row], Wm, *pElement, T[Row] ); /* Cmplx expr: T[Row] -= Wp * *pElement. */ @@ -1804,100 +1713,116 @@ ComplexNumber Wp, Wm; pElement = pElement->NextInCol; } -/* If minus value causes more growth, overwrite T with its values. */ + /* If minus value causes more growth, overwrite T with its + values. */ if (ASm > ASp) - { T[I] = Wm; + { + T[I] = Wm; pElement = pPivot->NextInCol; while (pElement != NULL) - { T[pElement->Row] = Tm[pElement->Row]; + { + T[pElement->Row] = Tm[pElement->Row]; pElement = pElement->NextInCol; } } else T[I] = Wp; } -/* Compute 1-norm of T, which now contains w, and scale ||T|| to 1/SLACK. */ + /* Compute 1-norm of T, which now contains w, and scale ||T|| to + 1/SLACK. */ for (ASw = 0.0, I = Size; I > 0; I--) ASw += CMPLX_1_NORM(T[I]); ScaleFactor = 1.0 / (SLACK * ASw); if (ScaleFactor < 0.5) - { for (I = Size; I > 0; I--) SCLR_MULT_ASSIGN( T[I], ScaleFactor ); + { + for (I = Size; I > 0; I--) SCLR_MULT_ASSIGN( T[I], ScaleFactor ); E *= ScaleFactor; } -/* Backward Substitution. Solves Uy = w.*/ + /* Backward Substitution. Solves Uy = w.*/ for (I = Size; I >= 1; I--) - { pElement = Matrix->Diag[I]->NextInRow; + { + pElement = Matrix->Diag[I]->NextInRow; while (pElement != NULL) - { /* Cmplx expr: T[I] -= T[pElement->Col] * *pElement. */ + { + /* Cmplx expr: T[I] -= T[pElement->Col] * *pElement. */ CMPLX_MULT_SUBT_ASSIGN( T[I], T[pElement->Col], *pElement ); pElement = pElement->NextInRow; } if (CMPLX_1_NORM(T[I]) > SLACK) - { ScaleFactor = 1.0 / MAX( SQR( SLACK ), CMPLX_1_NORM(T[I]) ); + { + ScaleFactor = 1.0 / MAX( SQR( SLACK ), CMPLX_1_NORM(T[I]) ); for (K = Size; K > 0; K--) SCLR_MULT_ASSIGN( T[K], ScaleFactor ); E *= ScaleFactor; } } -/* Compute 1-norm of T, which now contains y, and scale ||T|| to 1/SLACK. */ + /* Compute 1-norm of T, which now contains y, and scale ||T|| to + 1/SLACK. */ for (ASy = 0.0, I = Size; I > 0; I--) ASy += CMPLX_1_NORM(T[I]); ScaleFactor = 1.0 / (SLACK * ASy); if (ScaleFactor < 0.5) - { for (I = Size; I > 0; I--) SCLR_MULT_ASSIGN( T[I], ScaleFactor ); + { + for (I = Size; I > 0; I--) SCLR_MULT_ASSIGN( T[I], ScaleFactor ); ASy = 1.0 / SLACK; E *= ScaleFactor; } -/* Compute infinity-norm of T for O'Leary's estimate. */ + /* Compute infinity-norm of T for O'Leary's estimate. */ for (MaxY = 0.0, I = Size; I > 0; I--) if (MaxY < CMPLX_1_NORM(T[I])) MaxY = CMPLX_1_NORM(T[I]); -/* - * Part 2. A* z = y where the * represents the transpose. - * Recall that A = LU implies A* = U* L*. - */ + /* Part 2. A* z = y where the * represents the transpose. Recall + * that A = LU implies A* = U* L*. */ -/* Forward elimination, U* v = y. */ + /* Forward elimination, U* v = y. */ for (I = 1; I <= Size; I++) - { pElement = Matrix->Diag[I]->NextInRow; + { + pElement = Matrix->Diag[I]->NextInRow; while (pElement != NULL) - { /* Cmplx expr: T[pElement->Col] -= T[I] * *pElement. */ + { + /* Cmplx expr: T[pElement->Col] -= T[I] * *pElement. */ CMPLX_MULT_SUBT_ASSIGN( T[pElement->Col], T[I], *pElement ); pElement = pElement->NextInRow; } if (CMPLX_1_NORM(T[I]) > SLACK) - { ScaleFactor = 1.0 / MAX( SQR( SLACK ), CMPLX_1_NORM(T[I]) ); + { + ScaleFactor = 1.0 / MAX( SQR( SLACK ), CMPLX_1_NORM(T[I]) ); for (K = Size; K > 0; K--) SCLR_MULT_ASSIGN( T[K], ScaleFactor ); ASy *= ScaleFactor; } } -/* Compute 1-norm of T, which now contains v, and scale ||T|| to 1/SLACK. */ + /* Compute 1-norm of T, which now contains v, and scale ||T|| to + 1/SLACK. */ for (ASv = 0.0, I = Size; I > 0; I--) ASv += CMPLX_1_NORM(T[I]); ScaleFactor = 1.0 / (SLACK * ASv); if (ScaleFactor < 0.5) - { for (I = Size; I > 0; I--) SCLR_MULT_ASSIGN( T[I], ScaleFactor ); + { + for (I = Size; I > 0; I--) SCLR_MULT_ASSIGN( T[I], ScaleFactor ); ASy *= ScaleFactor; } -/* Backward Substitution, L* z = v. */ + /* Backward Substitution, L* z = v. */ for (I = Size; I >= 1; I--) - { pPivot = Matrix->Diag[I]; + { + pPivot = Matrix->Diag[I]; pElement = pPivot->NextInCol; while (pElement != NULL) - { /* Cmplx expr: T[I] -= T[pElement->Row] * *pElement. */ + { + /* Cmplx expr: T[I] -= T[pElement->Row] * *pElement. */ CMPLX_MULT_SUBT_ASSIGN( T[I], T[pElement->Row], *pElement ); pElement = pElement->NextInCol; } CMPLX_MULT_ASSIGN( T[I], *pPivot ); if (CMPLX_1_NORM(T[I]) > SLACK) - { ScaleFactor = 1.0 / MAX( SQR( SLACK ), CMPLX_1_NORM(T[I]) ); + { + ScaleFactor = 1.0 / MAX( SQR( SLACK ), CMPLX_1_NORM(T[I]) ); for (K = Size; K > 0; K--) SCLR_MULT_ASSIGN( T[K], ScaleFactor ); ASy *= ScaleFactor; } } -/* Compute 1-norm of T, which now contains z. */ + /* Compute 1-norm of T, which now contains z. */ for (ASz = 0.0, I = Size; I > 0; I--) ASz += CMPLX_1_NORM(T[I]); FREE( Tm ); @@ -1907,7 +1832,6 @@ ComplexNumber Wp, Wm; InvNormOfInverse = MIN( Linpack, OLeary ); return InvNormOfInverse / NormOfMatrix; } -#endif /* spCOMPLEX */ @@ -1934,42 +1858,44 @@ spNorm( eMatrix ) char *eMatrix; { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register ElementPtr pElement; -register int I; -RealNumber Max = 0.0, AbsRowSum; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + ElementPtr pElement; + int I; + RealNumber Max = 0.0, AbsRowSum; -/* Begin `spNorm'. */ - ASSERT( IS_SPARSE(Matrix) AND NOT IS_FACTORED(Matrix) ); - if (NOT Matrix->RowsLinked) spcLinkRows( Matrix ); + /* Begin `spNorm'. */ + assert( IS_SPARSE(Matrix) && !IS_FACTORED(Matrix) ); + if (!Matrix->RowsLinked) spcLinkRows( Matrix ); -/* Compute row sums. */ -#if REAL - if (NOT Matrix->Complex) - { for (I = Matrix->Size; I > 0; I--) - { pElement = Matrix->FirstInRow[I]; + /* Compute row sums. */ + if (!Matrix->Complex) + { + for (I = Matrix->Size; I > 0; I--) + { + pElement = Matrix->FirstInRow[I]; AbsRowSum = 0.0; while (pElement != NULL) - { AbsRowSum += ABS( pElement->Real ); + { + AbsRowSum += ABS( pElement->Real ); pElement = pElement->NextInRow; } if (Max < AbsRowSum) Max = AbsRowSum; } } -#endif -#if spCOMPLEX - if (Matrix->Complex) - { for (I = Matrix->Size; I > 0; I--) - { pElement = Matrix->FirstInRow[I]; + else + { + for (I = Matrix->Size; I > 0; I--) + { + pElement = Matrix->FirstInRow[I]; AbsRowSum = 0.0; while (pElement != NULL) - { AbsRowSum += CMPLX_1_NORM( *pElement ); + { + AbsRowSum += CMPLX_1_NORM( *pElement ); pElement = pElement->NextInRow; } if (Max < AbsRowSum) Max = AbsRowSum; } } -#endif return Max; } #endif /* CONDITION */ @@ -1984,20 +1910,21 @@ RealNumber Max = 0.0, AbsRowSum; * STABILITY OF FACTORIZATION * * The following routines are used to gauge the stability of a - * factorization. If the factorization is determined to be too unstable, - * then the matrix should be reordered. The routines compute quantities - * that are needed in the computation of a bound on the error attributed - * to any one element in the matrix during the factorization. In other - * words, there is a matrix E = [e_ij] of error terms such that A+E = LU. - * This routine finds a bound on |e_ij|. Erisman & Reid [1] showed that - * |e_ij| < 3.01 u rho m_ij, where u is the machine rounding unit, - * rho = max a_ij where the max is taken over every row i, column j, and - * step k, and m_ij is the number of multiplications required in the - * computation of l_ij if i > j or u_ij otherwise. Barlow [2] showed that - * rho < max_i || l_i ||_p max_j || u_j ||_q where 1/p + 1/q = 1. + * factorization. If the factorization is determined to be too + * unstable, then the matrix should be reordered. The routines + * compute quantities that are needed in the computation of a bound + * on the error attributed to any one element in the matrix during + * the factorization. In other words, there is a matrix E = [e_ij] + * of error terms such that A+E = LU. This routine finds a bound on + * |e_ij|. Erisman & Reid [1] showed that |e_ij| < 3.01 u rho m_ij, + * where u is the machine rounding unit, rho = max a_ij where the max + * is taken over every row i, column j, and step k, and m_ij is the + * number of multiplications required in the computation of l_ij if i + * > j or u_ij otherwise. Barlow [2] showed that rho < max_i || l_i + * ||_p max_j || u_j ||_q where 1/p + 1/q = 1. * - * The first routine finds the magnitude on the largest element in the - * matrix. If the matrix has not yet been factored, the largest + * The first routine finds the magnitude on the largest element in + * the matrix. If the matrix has not yet been factored, the largest * element is found by direct search. If the matrix is factored, a * bound on the largest element in any of the reduced submatrices is * computed using Barlow with p = oo and q = 1. The ratio of these @@ -2012,14 +1939,15 @@ RealNumber Max = 0.0, AbsRowSum; * * Using only the size of the matrix as an upper bound on m_ij and * Barlow's bound, the user can estimate the size of the matrix error - * terms e_ij using the bound of Erisman and Reid. The second routine - * computes a tighter bound (with more work) based on work by Gear - * [3], |e_ij| < 1.01 u rho (t c^3 + (1 + t)c^2) where t is the + * terms e_ij using the bound of Erisman and Reid. The second + * routine computes a tighter bound (with more work) based on work by + * Gear [3], |e_ij| < 1.01 u rho (t c^3 + (1 + t)c^2) where t is the * threshold and c is the maximum number of off-diagonal elements in * any row of L. The expensive part of computing this bound is - * determining the maximum number of off-diagonals in L, which changes - * only when the order of the matrix changes. This number is computed - * and saved, and only recomputed if the matrix is reordered. + * determining the maximum number of off-diagonals in L, which + * changes only when the order of the matrix changes. This number is + * computed and saved, and only recomputed if the matrix is + * reordered. * * [1] A. M. Erisman, J. K. Reid. Monitoring the stability of the * triangular factorization of a sparse matrix. Numerische @@ -2030,8 +1958,7 @@ RealNumber Max = 0.0, AbsRowSum; * and Statistical Computing." Vol. 7, No. 1, January 1986, pp 166-168. * * [3] I. S. Duff, A. M. Erisman, J. K. Reid. "Direct Methods for Sparse - * Matrices." Oxford 1986. pp 99. - */ + * Matrices." Oxford 1986. pp 99. */ /* * LARGEST ELEMENT IN MATRIX @@ -2051,98 +1978,110 @@ spLargestElement( eMatrix ) char *eMatrix; { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register int I; -RealNumber Mag, AbsColSum, Max = 0.0, MaxRow = 0.0, MaxCol = 0.0; -RealNumber Pivot; -ComplexNumber cPivot; -register ElementPtr pElement, pDiag; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + int I; + RealNumber Mag, AbsColSum, Max = 0.0, MaxRow = 0.0, MaxCol = 0.0; + RealNumber Pivot; + ComplexNumber cPivot; + ElementPtr pElement, pDiag; -/* Begin `spLargestElement'. */ - ASSERT( IS_SPARSE(Matrix) ); + /* Begin `spLargestElement'. */ + assert( IS_SPARSE(Matrix) ); -#if REAL - if (Matrix->Factored AND NOT Matrix->Complex) - { if (Matrix->Error == spSINGULAR) return 0.0; + if (Matrix->Factored && !Matrix->Complex) + { + if (Matrix->Error == spSINGULAR) return 0.0; -/* Find the bound on the size of the largest element over all factorization. */ + /* Find the bound on the size of the largest element over all + factorization. */ for (I = 1; I <= Matrix->Size; I++) - { pDiag = Matrix->Diag[I]; + { + pDiag = Matrix->Diag[I]; -/* Lower triangular matrix. */ + /* Lower triangular matrix. */ Pivot = 1.0 / pDiag->Real; Mag = ABS( Pivot ); if (Mag > MaxRow) MaxRow = Mag; pElement = Matrix->FirstInRow[I]; while (pElement != pDiag) - { Mag = ABS( pElement->Real ); + { + Mag = ABS( pElement->Real ); if (Mag > MaxRow) MaxRow = Mag; pElement = pElement->NextInRow; } -/* Upper triangular matrix. */ + /* Upper triangular matrix. */ pElement = Matrix->FirstInCol[I]; AbsColSum = 1.0; /* Diagonal of U is unity. */ while (pElement != pDiag) - { AbsColSum += ABS( pElement->Real ); + { + AbsColSum += ABS( pElement->Real ); pElement = pElement->NextInCol; } if (AbsColSum > MaxCol) MaxCol = AbsColSum; } } - else if (NOT Matrix->Complex) - { for (I = 1; I <= Matrix->Size; I++) - { pElement = Matrix->FirstInCol[I]; + else if (!Matrix->Complex) + { + for (I = 1; I <= Matrix->Size; I++) + { + pElement = Matrix->FirstInCol[I]; while (pElement != NULL) - { Mag = ABS( pElement->Real ); + { + Mag = ABS( pElement->Real ); if (Mag > Max) Max = Mag; pElement = pElement->NextInCol; } } return Max; } -#endif -#if spCOMPLEX - if (Matrix->Factored AND Matrix->Complex) - { if (Matrix->Error == spSINGULAR) return 0.0; + if (Matrix->Factored && Matrix->Complex) + { + if (Matrix->Error == spSINGULAR) return 0.0; -/* Find the bound on the size of the largest element over all factorization. */ + /* Find the bound on the size of the largest element over all + factorization. */ for (I = 1; I <= Matrix->Size; I++) - { pDiag = Matrix->Diag[I]; + { + pDiag = Matrix->Diag[I]; -/* Lower triangular matrix. */ + /* Lower triangular matrix. */ CMPLX_RECIPROCAL( cPivot, *pDiag ); Mag = CMPLX_1_NORM( cPivot ); if (Mag > MaxRow) MaxRow = Mag; pElement = Matrix->FirstInRow[I]; while (pElement != pDiag) - { Mag = CMPLX_1_NORM( *pElement ); + { + Mag = CMPLX_1_NORM( *pElement ); if (Mag > MaxRow) MaxRow = Mag; pElement = pElement->NextInRow; } -/* Upper triangular matrix. */ + /* Upper triangular matrix. */ pElement = Matrix->FirstInCol[I]; AbsColSum = 1.0; /* Diagonal of U is unity. */ while (pElement != pDiag) - { AbsColSum += CMPLX_1_NORM( *pElement ); + { + AbsColSum += CMPLX_1_NORM( *pElement ); pElement = pElement->NextInCol; } if (AbsColSum > MaxCol) MaxCol = AbsColSum; } } else if (Matrix->Complex) - { for (I = 1; I <= Matrix->Size; I++) - { pElement = Matrix->FirstInCol[I]; + { + for (I = 1; I <= Matrix->Size; I++) + { + pElement = Matrix->FirstInCol[I]; while (pElement != NULL) - { Mag = CMPLX_1_NORM( *pElement ); + { + Mag = CMPLX_1_NORM( *pElement ); if (Mag > Max) Max = Mag; pElement = pElement->NextInCol; } } return Max; } -#endif return MaxRow * MaxCol; } @@ -2171,24 +2110,27 @@ spRoundoff( eMatrix, Rho ) char *eMatrix; RealNumber Rho; { -MatrixPtr Matrix = (MatrixPtr)eMatrix; -register ElementPtr pElement; -register int Count, I, MaxCount = 0; -RealNumber Reid, Gear; + MatrixPtr Matrix = (MatrixPtr)eMatrix; + ElementPtr pElement; + int Count, I, MaxCount = 0; + RealNumber Reid, Gear; -/* Begin `spRoundoff'. */ - ASSERT( IS_SPARSE(Matrix) AND IS_FACTORED(Matrix) ); + /* Begin `spRoundoff'. */ + assert( IS_SPARSE(Matrix) && IS_FACTORED(Matrix) ); -/* Compute Barlow's bound if it is not given. */ + /* Compute Barlow's bound if it is not given. */ if (Rho < 0.0) Rho = spLargestElement( eMatrix ); -/* Find the maximum number of off-diagonals in L if not previously computed. */ + /* Find the maximum number of off-diagonals in L if not previously computed. */ if (Matrix->MaxRowCountInLowerTri < 0) - { for (I = Matrix->Size; I > 0; I--) - { pElement = Matrix->FirstInRow[I]; + { + for (I = Matrix->Size; I > 0; I--) + { + pElement = Matrix->FirstInRow[I]; Count = 0; while (pElement->Col < I) - { Count++; + { + Count++; pElement = pElement->NextInRow; } if (Count > MaxCount) MaxCount = Count; @@ -2197,7 +2139,7 @@ RealNumber Reid, Gear; } else MaxCount = Matrix->MaxRowCountInLowerTri; -/* Compute error bound. */ + /* Compute error bound. */ Gear = 1.01*((MaxCount + 1) * Matrix->RelThreshold + 1.0) * SQR(MaxCount); Reid = 3.01 * Matrix->Size; @@ -2238,13 +2180,14 @@ spErrorMessage( eMatrix, Stream, Originator ) char *eMatrix, *Originator; FILE *Stream; { -int Row, Col, Error; + int Row, Col, Error; -/* Begin `spErrorMessage'. */ + /* Begin `spErrorMessage'. */ if (eMatrix == NULL) Error = spNO_MEMORY; else - { ASSERT(((MatrixPtr)eMatrix)->ID == SPARSE_ID); + { + assert(((MatrixPtr)eMatrix)->ID == SPARSE_ID); Error = ((MatrixPtr)eMatrix)->Error; } @@ -2255,29 +2198,34 @@ int Row, Col, Error; fprintf( Stream, "fatal error, "); else fprintf( Stream, "warning, "); -/* - * Print particular error message. - * Do not use switch statement because error codes may not be unique. - */ + + /* Print particular error message. Do not use switch statement + * because error codes may not be unique. */ if (Error == spPANIC) fprintf( Stream, "Sparse called improperly.\n"); else if (Error == spNO_MEMORY) fprintf( Stream, "insufficient memory available.\n"); else if (Error == spSINGULAR) - { spWhereSingular( eMatrix, &Row, &Col ); + { + spWhereSingular( eMatrix, &Row, &Col ); fprintf( Stream, "singular matrix detected at row %d and column %d.\n", Row, Col); } else if (Error == spZERO_DIAG) - { spWhereSingular( eMatrix, &Row, &Col ); + { + spWhereSingular( eMatrix, &Row, &Col ); fprintf( Stream, "zero diagonal detected at row %d and column %d.\n", Row, Col); } else if (Error == spSMALL_PIVOT) - { fprintf( Stream, - "unable to find a pivot that is larger than absolute threshold.\n"); + { + fprintf( Stream, + "unable to find a pivot that is larger than absolute threshold.\n"); + } + else + { + abort(); } - else ABORT(); return; } #endif /* DOCUMENTATION */ diff --git a/src/misc/ChangeLog b/src/misc/ChangeLog index 1fa6bbd2f..f79b36883 100644 --- a/src/misc/ChangeLog +++ b/src/misc/ChangeLog @@ -1,9 +1,17 @@ +2000-07-18 Arno W. Peters + + * Makefile.am: Added wlist.c. + + * wlist.c: moved here from src/parser/wlist.c + 2000-03-11 Paolo Nenzi - * missing_math.c: as Chris wrote: - In missing_math.c line 50: changed the preprocessor directive "#elif" to "#else" because the - elif must have a condition (ie. else if ...). - Again seemingly no adverse side effects. + * missing_math.c: as Chris wrote: + + In missing_math.c line 50: changed the preprocessor directive + "#elif" to "#else" because the elif must have a condition + (ie. else if ...). Again seemingly no adverse side + effects. 1999-09-07 Arno diff --git a/src/misc/Makefile.am b/src/misc/Makefile.am index d3f96ba5a..2477d316d 100644 --- a/src/misc/Makefile.am +++ b/src/misc/Makefile.am @@ -2,7 +2,11 @@ noinst_LIBRARIES = libmisc.a + libmisc_a_SOURCES = \ + getopt1.c \ + getopt.c \ + getopt.h \ alloc.c \ alloc.h \ dup2.c \ @@ -16,11 +20,19 @@ libmisc_a_SOURCES = \ printnum.c \ printnum.h \ string.c \ - string.h \ + stringutil.h \ + terminal.c \ + terminal.h \ tilde.c \ tilde.h \ - misc_time.c \ - misc_time.h + misc_time.c \ + misc_time.h \ + wlist.c + +## Note that the getopt files get compiled unconditionnaly but some +## magic #define away the body of their own code if the compilation environment +## provides an implementation of its own (like GNU libc) + diff --git a/src/misc/alloc.c b/src/misc/alloc.c index bea3931f5..9566a9fd6 100644 --- a/src/misc/alloc.c +++ b/src/misc/alloc.c @@ -5,14 +5,20 @@ Copyright 1990 Regents of the University of California. All rights reserved. /* * Memory alloction functions */ +#include -#include "ngspice.h" +#ifndef HAVE_LIBGC +#include #include -#include "alloc.h" +#include +/*saj For Tcl module locking*/ +#ifdef TCL_MODULE +#include +#endif /* Malloc num bytes and initialize to zero. Fatal error if the space can't - * be malloc'd. Return NULL for a request for 0 bytes. + * be tmalloc'd. Return NULL for a request for 0 bytes. */ /* New implementation of tmalloc, it uses calloc and does not call bzero() */ @@ -21,9 +27,22 @@ void * tmalloc(size_t num) { void *s; - if (!num) +/*saj*/ +#ifdef TCL_MODULE + struct Tcl_Mutex *alloc; + alloc = Tcl_GetAllocMutex(); +#endif + if (!num) return NULL; - s = calloc(num,1); +/*saj*/ +#ifdef TCL_MODULE + Tcl_MutexLock(alloc); +#endif + s = calloc(num,1); +/*saj*/ +#ifdef TCL_MODULE + Tcl_MutexUnlock(alloc); +#endif if (!s){ fprintf(stderr, "malloc: Internal Error: can't allocate %d bytes. \n", num); @@ -36,18 +55,29 @@ void * trealloc(void *ptr, size_t num) { void *s; - +/*saj*/ +#ifdef TCL_MODULE + struct Tcl_Mutex *alloc; + alloc = Tcl_GetAllocMutex(); +#endif if (!num) { if (ptr) free(ptr); return NULL; } - if (!ptr) s = tmalloc(num); - else + else { +/*saj*/ +#ifdef TCL_MODULE + Tcl_MutexLock(alloc); +#endif s = realloc(ptr, num); - +/*saj*/ +#ifdef TCL_MODULE + Tcl_MutexUnlock(alloc); +#endif + } if (!s) { fprintf(stderr, "realloc: Internal Error: can't allocate %d bytes.\n", num); @@ -110,7 +140,18 @@ trealloc(void *str, size_t num) void txfree(void *ptr) { - if (ptr) - free(ptr); +/*saj*/ +#ifdef TCL_MODULE + struct Tcl_Mutex *alloc; + alloc = Tcl_GetAllocMutex(); + Tcl_MutexLock(alloc); +#endif + if (ptr) + free(ptr); +/*saj*/ +#ifdef TCL_MODULE + Tcl_MutexUnlock(alloc); +#endif } +#endif diff --git a/src/misc/alloc.h b/src/misc/alloc.h index 7a9a98386..1b7b25548 100644 --- a/src/misc/alloc.h +++ b/src/misc/alloc.h @@ -6,8 +6,10 @@ #ifndef ALLOC_H_INCLUDED #define ALLOC_H_INCLUDED +#ifndef HAVE_LIBGC void * tmalloc(size_t num); void * trealloc(void *ptr, size_t num); void txfree(void *ptr); +#endif #endif diff --git a/src/misc/dup2.c b/src/misc/dup2.c index b25bd8861..5b343b091 100644 --- a/src/misc/dup2.c +++ b/src/misc/dup2.c @@ -1,3 +1,4 @@ +/* Modified: 2000 AlansFixes */ #include #include "ngspice.h" #include "dup2.h" @@ -16,5 +17,5 @@ dup2(int oldd, int newd) return 0; } #else -int Dummy_Symbol; +int Dummy_Symbol_2; #endif diff --git a/src/misc/ivars.c b/src/misc/ivars.c index 20490d6a1..4db2aa877 100644 --- a/src/misc/ivars.c +++ b/src/misc/ivars.c @@ -4,6 +4,12 @@ Copyright 1991 Regents of the University of California. All rights reserved. #include "ngspice.h" #include "ivars.h" + +#ifdef HAVE_STRING_H +#include +#endif /* HAVE_STRING_H */ + +#include #include char *Spice_Path; @@ -28,16 +34,39 @@ mkvar(char **p, char *path_prefix, char *var_dir, char *env_var) /* Override by environment variables */ buffer = getenv(env_var); + +#ifdef HAVE_ASPRINTF if (buffer) asprintf(p, "%s", buffer); else asprintf(p, "%s%s%s", path_prefix, DIR_PATHSEP, var_dir); +#else /* ~ HAVE_ASPRINTF */ + if (buffer){ + if ( (*p = (char *) malloc(strlen(buffer)+1)) == NULL){ + fprintf(stderr,"malloc failed\n"); + exit(1); + } + sprintf(*p,"%s",buffer); + /* asprintf(p, "%s", buffer); */ + } + else{ + if ( (*p = (char *) malloc(strlen(path_prefix) + + strlen(DIR_PATHSEP) + strlen(var_dir) + 1)) == NULL){ + fprintf(stderr,"malloc failed\n"); + exit(1); + } + sprintf(*p, "%s%s%s", path_prefix, DIR_PATHSEP, var_dir); + /* asprintf(p, "%s%s%s", path_prefix, DIR_PATHSEP, var_dir); */ + } +#endif /* HAVE_ASPRINTF */ } void ivars(void) { - + + char *temp=NULL; + env_overr(&Spice_Exec_Dir, "SPICE_EXEC_DIR"); env_overr(&Spice_Lib_Dir, "SPICE_LIB_DIR"); @@ -50,15 +79,19 @@ ivars(void) env_overr(&Spice_Host, "SPICE_HOST"); env_overr(&Bug_Addr, "SPICE_BUGADDR"); env_overr(&Def_Editor, "SPICE_EDITOR"); - env_overr(&AsciiRawFile, "SPICE_ASCIIRAWFILE"); + env_overr(&temp, "SPICE_ASCIIRAWFILE"); + + if(temp) + AsciiRawFile = atoi(temp); + } void cleanvars(void) { - free(News_File); - free(Default_MFB_Cap); - free(Help_Path); - free(Lib_Path); - free(Spice_Path); + txfree(News_File); + txfree(Default_MFB_Cap); + txfree(Help_Path); + txfree(Lib_Path); + txfree(Spice_Path); } diff --git a/src/misc/misc_time.c b/src/misc/misc_time.c index acbfd12af..3913335dd 100644 --- a/src/misc/misc_time.c +++ b/src/misc/misc_time.c @@ -9,6 +9,7 @@ Copyright 1990 Regents of the University of California. All rights reserved. #include #include "ngspice.h" #include +#include #include "misc_time.h" #ifdef HAVE_LOCALTIME diff --git a/src/misc/mktemp.c b/src/misc/mktemp.c index 39cbd0643..6aa03b7ae 100644 --- a/src/misc/mktemp.c +++ b/src/misc/mktemp.c @@ -9,13 +9,17 @@ Copyright 1990 Regents of the University of California. All rights reserved. */ #include "ngspice.h" -#include "stdio.h" +#include #include "mktemp.h" #ifdef HAVE_UNISTD_H #include #endif +#ifdef HAVE_STRING_H +#include +#endif + #ifndef TEMPFORMAT #define TEMPFORMAT "temp%s%d" #endif @@ -35,7 +39,7 @@ smktemp(char *id) id = "sp"; sprintf(rbuf, TEMPFORMAT, id, num); - nbuf = (char *) malloc(strlen(rbuf) + 1); + nbuf = (char *) tmalloc(strlen(rbuf) + 1); strcpy(nbuf, rbuf); return nbuf; diff --git a/src/misc/printnum.c b/src/misc/printnum.c index 6ff51adfb..134406f7d 100644 --- a/src/misc/printnum.c +++ b/src/misc/printnum.c @@ -1,10 +1,11 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +Modified: 2001 Paolo Nenzi **********/ -/* Print a number in a reasonable form. This is the sort of thing that - * %G does, but more appropriate for spice. Returns static data. +/* Paolo Nenzi 2001: printnum does not returns static data anymore. + * It is up to the caller to allocate space for strings. */ #include "ngspice.h" @@ -13,10 +14,8 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group int cp_numdgt = -1; -char * -printnum(double num) +void printnum(char *buf, double num) { - static char buf[128]; int n; if (cp_numdgt > 1) @@ -26,7 +25,6 @@ printnum(double num) if (num < 0.0) n--; - (void) sprintf(buf, "%.*le", n, num); - - return (buf); + (void) sprintf(buf, "%.*e", n, num); + } diff --git a/src/misc/printnum.h b/src/misc/printnum.h index 3995f210b..e405c69db 100644 --- a/src/misc/printnum.h +++ b/src/misc/printnum.h @@ -6,6 +6,6 @@ #ifndef PRINTNUM_H_INCLUDED #define PRINTNUM_H_INCLUDED -char * printnum(double num); +void printnum(char * buf, double num); #endif diff --git a/src/misc/string.c b/src/misc/string.c index 54e114762..e0c9a7642 100644 --- a/src/misc/string.c +++ b/src/misc/string.c @@ -7,9 +7,14 @@ Copyright 1990 Regents of the University of California. All rights reserved. */ #include +#include + +#ifdef HAVE_STRING_H +#include +#endif + #include "ngspice.h" -#include "stdio.h" -#include "string.h" +#include "stringutil.h" int prefix(register char *p, register char *s) diff --git a/src/misc/tilde.c b/src/misc/tilde.c index 8633e366b..ece5fde70 100644 --- a/src/misc/tilde.c +++ b/src/misc/tilde.c @@ -2,10 +2,12 @@ Copyright 1991 Regents of the University of California. All rights reserved. **********/ - #include +#include +#ifdef HAVE_STRING_H +#include +#endif #include "ngspice.h" -#include #include "tilde.h" #ifdef HAVE_PWD_H diff --git a/src/ngspice.c b/src/ngspice.c index b30de3a59..628003d82 100644 --- a/src/ngspice.c +++ b/src/ngspice.c @@ -3,56 +3,6 @@ #include "conf.h" -/* - * Analyses - */ -#define AN_op -#define AN_dc -#define AN_tf -#define AN_ac -#define AN_tran -#define AN_pz -#define AN_disto -#define AN_noise -#define AN_sense - -/* - * Devices - */ -#define DEV_asrc -#define DEV_bjt -#define DEV_bsim1 -#define DEV_bsim2 -#define DEV_bsim3 -#define DEV_bsim4 -#define DEV_bsim3v1 -#define DEV_bsim3v2 -#define DEV_cap -#define DEV_cccs -#define DEV_ccvs -#define DEV_csw -#define DEV_dio -#define DEV_ind -#define DEV_isrc -#define DEV_jfet -#define DEV_jfet2 -#define DEV_ltra -#define DEV_mes -#define DEV_mos1 -#define DEV_mos2 -#define DEV_mos3 -#define DEV_mos6 -#define DEV_res -#define DEV_sw -#define DEV_tra -#define DEV_urc -#define DEV_vccs -#define DEV_vcvs -#define DEV_vsrc - -#define DEVICES_USED "asrc bjt bsim1 bsim2 bsim3 bsim3v2 bsim3v1 cap cccs ccvs csw dio ind isrc jfet ltra mes mos1 mos2 mos3 mos6 res sw tra urc vccs vcvs vsrc" -#define ANALYSES_USED "op dc tf ac tran pz disto noise sense" - /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ @@ -65,108 +15,11 @@ Copyright 1990 Regents of the University of California. All rights reserved. #include -#include "noisedef.h" #include "devdefs.h" +#include "noisedef.h" #include "suffix.h" -#include "asrc/asrcitf.h" -#include "bjt/bjtitf.h" -#include "cap/capitf.h" -#include "cccs/cccsitf.h" -#include "ccvs/ccvsitf.h" -#include "csw/cswitf.h" -#include "dio/dioitf.h" -#include "ind/inditf.h" -#include "isrc/isrcitf.h" -#include "mos1/mos1itf.h" -#include "mos6/mos6itf.h" -#include "res/resitf.h" -#include "sw/switf.h" -#include "vccs/vccsitf.h" -#include "vcvs/vcvsitf.h" -#include "vsrc/vsrcitf.h" -#include "bsim1/bsim1itf.h" -#include "bsim2/bsim2itf.h" -#include "bsim3/bsim3itf.h" -#include "bsim4/bsim4itf.h" -#include "bsim3v1/bsim3v1itf.h" -#include "bsim3v2/bsim3v2itf.h" -#include "mos2/mos2itf.h" -#include "mos3/mos3itf.h" -#include "jfet/jfetitf.h" -#include "jfet2/jfet2itf.h" -#include "mes/mesitf.h" -#include "ltra/ltraitf.h" -#include "tra/traitf.h" -#include "urc/urcitf.h" - - -extern SPICEanalysis OPTinfo; -extern SPICEanalysis ACinfo; -extern SPICEanalysis DCTinfo; -extern SPICEanalysis DCOinfo; -extern SPICEanalysis TRANinfo; -extern SPICEanalysis PZinfo; -extern SPICEanalysis TFinfo; -extern SPICEanalysis DISTOinfo; -extern SPICEanalysis NOISEinfo; -extern SPICEanalysis SENSinfo; - - -SPICEanalysis *analInfo[] = { - &OPTinfo, - &ACinfo, - &DCTinfo, - &DCOinfo, - &TRANinfo, - &PZinfo, - &TFinfo, - &DISTOinfo, - &NOISEinfo, - &SENSinfo, - -}; - -int ANALmaxnum = sizeof(analInfo)/sizeof(SPICEanalysis*); -SPICEdev *DEVices[] = { - - /* URC must appear before the resistor, capacitor, and diode */ - &URCinfo, - &ASRCinfo, - &BJTinfo, - &B1info, - &B2info, - &BSIM3info, - &B4info, - &BSIM3V2info, - &BSIM3V1info, - &CAPinfo, - &CCCSinfo, - &CCVSinfo, - &CSWinfo, - &DIOinfo, - &INDinfo, - &MUTinfo, - &ISRCinfo, - &JFETinfo, - &JFET2info, - <RAinfo, - &MESinfo, - &MOS1info, - &MOS2info, - &MOS3info, - &MOS6info, - &RESinfo, - &SWinfo, - &TRAinfo, - &VCCSinfo, - &VCVSinfo, - &VSRCinfo, -}; - -/* my internal global constant for number of device types */ -int DEVmaxnum = sizeof(DEVices)/sizeof(SPICEdev *); /* XXX Should be -1 ? There is always an extra null element at the end ? */ static char * specSigList[] = { "time" @@ -179,50 +32,49 @@ static IFparm nodeParms[] = { }; IFsimulator SIMinfo = { - "ngspice", /* name */ - "Circuit level simulation program", /* more about me */ - Spice_Version, /* version */ + "ngspice", /* name */ + "Circuit level simulation program", /* more about me */ + Spice_Version, /* version */ - CKTinit, /* newCircuit function */ - CKTdestroy, /* deleteCircuit function */ + CKTinit, /* newCircuit function */ + CKTdestroy, /* deleteCircuit function */ - CKTnewNode, /* newNode function */ - CKTground, /* groundNode function */ - CKTbindNode, /* bindNode function */ - CKTfndNode, /* findNode function */ - CKTinst2Node, /* instToNode function */ - CKTsetNodPm, /* setNodeParm function */ - CKTaskNodQst, /* askNodeQuest function */ - CKTdltNod, /* deleteNode function */ + CKTnewNode, /* newNode function */ + CKTground, /* groundNode function */ + CKTbindNode, /* bindNode function */ + CKTfndNode, /* findNode function */ + CKTinst2Node, /* instToNode function */ + CKTsetNodPm, /* setNodeParm function */ + CKTaskNodQst, /* askNodeQuest function */ + CKTdltNod, /* deleteNode function */ - CKTcrtElt, /* newInstance function */ - CKTparam, /* setInstanceParm function */ - CKTask, /* askInstanceQuest function */ - CKTfndDev, /* findInstance funciton */ - CKTdltInst, /* deleteInstance function */ + CKTcrtElt, /* newInstance function */ + CKTparam, /* setInstanceParm function */ + CKTask, /* askInstanceQuest function */ + CKTfndDev, /* findInstance funciton */ + CKTdltInst, /* deleteInstance function */ - CKTmodCrt, /* newModel function */ - CKTmodParam, /* setModelParm function */ - CKTmodAsk, /* askModelQuest function */ - CKTfndMod, /* findModel function */ - CKTdltMod, /* deleteModel function */ + CKTmodCrt, /* newModel function */ + CKTmodParam, /* setModelParm function */ + CKTmodAsk, /* askModelQuest function */ + CKTfndMod, /* findModel function */ + CKTdltMod, /* deleteModel function */ - CKTnewTask, /* newTask function */ - CKTnewAnal, /* newAnalysis function */ - CKTsetAnalPm, /* setAnalysisParm function */ - CKTaskAnalQ, /* askAnalysisQuest function */ - CKTfndAnal, /* findAnalysis function */ - CKTfndTask, /* findTask function */ - CKTdelTask, /* deleteTask function */ + CKTnewTask, /* newTask function */ + CKTnewAnal, /* newAnalysis function */ + CKTsetAnalPm, /* setAnalysisParm function */ + CKTaskAnalQ, /* askAnalysisQuest function */ + CKTfndAnal, /* findAnalysis function */ + CKTfndTask, /* findTask function */ + CKTdelTask, /* deleteTask function */ - CKTdoJob, /* doAnalyses function */ - CKTtrouble, /* non-convergence message function */ + CKTdoJob, /* doAnalyses function */ + CKTtrouble, /* non-convergence message function */ - sizeof(DEVices)/sizeof(SPICEdev *), - (IFdevice**)DEVices, - - sizeof(analInfo)/sizeof(SPICEanalysis *), - (IFanalysis **)analInfo, + 0, /* Initialized in SIMinit() */ + NULL, /* Initialized in SIMinit() */ + 0, /* Initialized in SIMinit() */ + NULL, /* Initialized in SIMinit() */ sizeof(nodeParms)/sizeof(IFparm), nodeParms, diff --git a/src/ngspice.idx b/src/ngspice.idx index 5036ddd30fb0a42b737712a4476564f05c323b69..6cda8a5f93aa5a0d22140da056c5a64132aa5e99 100644 GIT binary patch delta 2031 zcmYLJeQ;FO6+idB-F@%v=53M%q6uFsUkQPH;ez=fo9?|?aA`g^$pXq~oMp2i&x!k% zeY;S!sF{?p)fU~J+ObZXDLAFAg4WhLgB?)^t<(-^w51hBoL~kRrs!aYA`GRycQ>{F zoVmZ>dFR}Fe(#*~jQNcD)OX0^`90iK>jCKG_;b>n_q)g&Xb?^wz&>GZd|KEk{8-pJ zoKHEqjB(0oX$>Brj2d-#kuq`v>l97~al5du;O~X)!E3_)0NWj$1aVB*7w{cnBd9w$ zb*8Y#$@I$Y0QKRX&H*HjHnJE0>XaW>x;PofdtIC^eFXQrm|igs(4VwT8z;5f^L~w% z@4=LMEB-~RrSvgzWaI$8ta9=@ydv!T*rIXrF7DQNiElpuw{q#x1pyn8EaWirjf9B@o5>5$w z9hZ7IIf|yRJMoaPZ{uYTr&rJ8gC%qEPo8RW7S^zZk{z|f{JP8jtfls?pt?g~c! zjNKKSyovb=P9Gh{lY+XAmA7#E(ijfj!aQ@IqriK+yF)#lc$=>w?{~XO4^jvvW~^Pp(c)V4j=+U$gnV%DkGP?V(dlEjw~DFfj|-nUj7>}1J%JD8*-nqf z3vt@X4=IEbBbLmr!0Nx@#9ZdN=kFBOS-Fgv%*f;=XHHSLGoBerSZNv6tgZS~5XsSW zF>2owzBrG$mP}KK$O3{YKSyDMwY6BK+u3k|LKl)n9d!FeJTjko0+$3~+F3It%W6?~ zUl!Pk<5*?8tNjXv-a=+s$?~gsVgb`ne?=jhF;iK2qqbF1pf6_@fC5<+pIyl4OB$Y8 z$nAx`wC@1zyRh!=C6X<`s(zCPhb3fDHuM}j?j&Cc7eQBNo1MwY& z&&6CW5h$6Ose|5Ei#Km$p4Ih|%_hu@6ud<%SyjNY^tCh)!1oq0`lDv_E@pbPRk%jX z;o`fS)=FgUEXwv|5Kk>;)VCfNEMfXoMEJ7tY_52jrhT(l63K!RI-HA2WX&i((vS5^ znKr#yfmkM9XcHa&u%&=fGP?oK-%~_(+LEiKnNAF1a2Zp5Lket64PkdxyJ{xo*%p7M zo&Iwe-PMeaj9^bS(|&co0-G~JVIi9vnk)tG+Lno@ao@r=+Gk@`4WpSII9S8n^jlKl zbTXdBFKSveczu@woub5eO*k1d=NT(H#qiY3IufMGT+qk~Sdg=5j+`EE#$$14r z(Wuz&k-PjMF~VyM=f4!-;tz>7@iz(P4$80MmX(ZNxsDSnnW5hNzds=T#*c~P>xk8b z2$vV{uVb{%hcDJK*SiZH5E{Uj>w@aq8i!bgF{!ke>Q`3^G!W@-l9;aBj7RF3F@H>C zi>KoWGizmJHnsUp!EiqFbm#an0kJ&LL7zB|CmNV`=tDa#en2U0o`6iPdr^fYa~)2dK7Q2VvcKHH~}XcI^1yKE2nI;)F}3fb#y>+!KSav XpbHH22AFf%Y{BAGV~1n$To?Qo4*^gA delta 2031 zcmYLJZE%xS7C!gB$@`HsF)6grA`n4nsWi0m)eqa6d)rECLs}9Fl+oFc#`5l#B;*4I z#0m&F&N%F54?4)M3}w}Ec7++1-5;#-A<8&7+MPPGE;_=3yQ@V7Q9G>YqW30M|D3tc zbKY~$J#=h5lQJ20+I z#&`89`qD0OWTXp^Xq-HNW5RC2dYzN?_=wJnUKs-5iEMHp*5|>kdYx^;^8lfZW+u88 zM@kl306;;%!ReuwaJRuo2uBRA?>Yw1l^sZ9cX^`%r{BO{8zWorSsN#h<0WDD;4HgL zXA0}aL&Empbvvg|e2klmrr=q71-TzL6>(CI$Ax_YiGvqSAp|-T>GVJ>oyMG_jy_3o z*inXmaLggI@ofhutI_S`^vT)S<7A`}pAq2ne7xXf#?dAMt!APxhH+&aPhhsR3}NPM}a5dWvgu9*0)aB4D^( zIzv(0~~! z=w#4EM=?H`*{=UZ(CMgYCUIn1gYoDw36o}2_JnrexOicIEP2hYQAs?j9U`IKle|!UXmox3qTf%2PgtfDp>^FzyIh`Dc75MfX?w`W!Gv1@np2()mSV~@A^xSz0OCqVhXd)@2>h%A8D2UiVvJln(FFbrZ zQ?Fd6;Fkq7YsP;lbR^aksz7GyRZ>CcOObczC@$cFsq0Hrepip9t4 zppFW>bqBM5R3+I=)J#di>-E2R^H`RC54~K2Z_Z$pEkx%`X53mNTx-pT3h%yHCsAT! zLAItwe19gRr#Mc#lNrBm7rsm+lPx6E^>6N%L@cj_0eb=xCB_vm4Wf4z(|;RQAe@Ti z+r$8KMIOcF?G9MEs({kTgj_9kv~x8!&t}@GUnsCV-iLwmCT-Fhc}|Nz(?o}&Xsckf zG=@tnnBLQ`z>1VmSjc9Bi@#D}Wq&G?#G&bp^!o&sS2F5JSDmw2BfVl}&h{(t>m6+)Lltgz-5{FWsU*XJkzbhib%hZXHzMzC>oc^Tr;>D-4oB|GW#;yO{R$s|v8?_Z3(t-TEHxzKc1Z{YU{{SC?4t z{*@k|nBhf^p)VES;uncN@ze@tF+KMc_ReMW@f)~*E^|C{^Jo78>33A#`k7gnkJxL& zUsf}E(us$wnL6us3;05Kq`Fz#cc(?{!myNDjP=Ah0)_m6T8Zg%Aw1z_j)xzy0FNXi zQ8SZB$=kH2Ul9!F<4?C + + * asrc/asrcset.c, bjt/bjtsetup.c, bsim1/b1set.c, bsim2/b2set.c, + bsim3/b3set.c, bsim3v2/b3v2set.c, bsim4/b4set.c, ccvs/ccvsset.c, + dio/diosetup.c, ind/indsetup.c, jfet/jfetset.c, jfet2/jfet2set.c, + ltra/ltraset.c, mes/messetup.c, mos1/mos1set.c, mos2/mos2set.c, + mos3/mos3set.c, mos6/mos6set.c, tra/trasetup.c, urc/urcsetup.c, + vcvs/vcvsset.c, vsrc/vsrcset.c: Removed HAS_BATCHSIM preprocessor + checks. + +2000-07-21 Arno W. Peters + + * README: Updated. + +2000-07-10 Arno W. Peters + + * asrc/asrcinit.c, asrc/asrcitf.h, bjt/bjtinit.c, bjt/bjtitf.h, + bsim1/b1init.c, bsim1/b1itf.h, bsim2/b2init.c, bsim2/b2itf.h, + bsim3/b3init.c, bsim3/b3itf.h, bsim3v1/b3v1init.c, + bsim3v1/b3v1itf.h, bsim3v2/b3v2init.c, bsim3v2/b3v2itf.h, + bsim4/b4init.c, bsim4/b4itf.h, cap/capinit.c, cap/capitf.h, + cccs/cccsinit.c, cccs/cccsitf.h, ccvs/ccvsinit.c, ccvs/ccvsitf.h, + csw/cswinit.c, csw/cswitf.h, dio/dioinit.c, dio/dioitf.h, + ind/indinit.c, ind/inditf.h, isrc/isrcinit.c, isrc/isrcitf.h, + jfet/jfetinit.c, jfet/jfetitf.h, jfet2/jfet2init.c, + jfet2/jfet2itf.h, ltra/ltrainit.c, ltra/ltraitf.h, mes/mesinit.c, + mes/mesitf.h, mos1/mos1init.c, mos1/mos1itf.h, mos2/mos2init.c, + mos2/mos2itf.h, mos3/mos3init.c, mos3/mos3itf.h, mos6/mos6init.c, + mos6/mos6itf.h, res/resinit.c, res/resitf.h, sw/swinit.c, + sw/switf.h, tra/trainit.c, tra/traitf.h, urc/urcinit.c, + urc/urcitf.h, vccs/vccsinit.c, vccs/vccsitf.h, vcvs/vcvsinit.c, + vcvs/vcvsitf.h, vsrc/vsrcinit.c, vsrc/vsrcitf.h: Moved the device + info structure from every devices' *itf.h file into a new *init.c + file. Moved external declaration of addresses into *init.h file. + Removed conditional compilation based on the AN_* defines + as they were by default defined. The calling code will only get a + pointer to a SPICEdev structure. This takes us another step + closer to loadable devices. + +2000-07-09 Arno W. Peters + + * devlist.c, devlist.h, test_devlist.c: Removed. This idea is not + yet ready to be implemented. The dependency of the analysis code + on CKThead for storing the device parameters at the same index as + the device model in the DEVices variable caused trouble. + +2000-07-08 Arno W. Peters + + * devlist.c, test_devlist.c: Additional checks revealed a bug, + first_device() and next_device() should now do what they are + supposed to do. + +2000-07-07 Arno W. Peters + + * devlist.c, devlist.h: Another step towards + dynamically loadable devices. The first_device() and + next_device() functions abstract away the actual + implementation of the devices list. Currently it is a fixed + length array, when we start supporting dynamically loaded devices, + this is no longer true. + + * test_devlist.c: Checks the implementation of first_device() + and next_device(). + 2000-04-04 Paolo Nenzi * Makefile.am: Added support for BSIM4 diff --git a/src/spicelib/devices/Makefile.am b/src/spicelib/devices/Makefile.am index 6fa8ebcaa..ea8940c63 100644 --- a/src/spicelib/devices/Makefile.am +++ b/src/spicelib/devices/Makefile.am @@ -3,36 +3,61 @@ SUBDIRS = \ asrc \ bjt \ +## bjt2 \ bsim1 \ bsim2 \ bsim3 \ bsim4 \ bsim3v1 \ bsim3v2 \ + bsim3soi_pd \ + bsim3soi_fd \ + bsim3soi_dd \ cap \ cccs \ ccvs \ + cpl \ csw \ - devsup \ dio \ - disto \ + @EKVDIR@ \ ind \ isrc \ + hfet1 \ + hfet2 \ jfet \ jfet2 \ ltra \ mes \ + mesa \ mos1 \ mos2 \ mos3 \ mos6 \ + mos9 \ res \ + soi3 \ sw \ tra \ + txl \ urc \ vccs \ vcvs \ vsrc +noinst_LIBRARIES = libdev.a + +libdev_a_SOURCES = \ + dev.c \ + dev.h \ + devsup.c \ + cktaccept.c \ + cktaccept.h \ + cktask.c \ + cktbindnode.c \ + cktcrte.c \ + cktfinddev.c \ + cktinit.c + +INCLUDES = -I$(top_srcdir)/src/include MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/asrc/Makefile.am b/src/spicelib/devices/asrc/Makefile.am index 0aa14b0ea..fa2349d3f 100644 --- a/src/spicelib/devices/asrc/Makefile.am +++ b/src/spicelib/devices/asrc/Makefile.am @@ -2,23 +2,24 @@ pkglib_LTLIBRARIES = libasrc.la -libasrc_la_SOURCES = \ - asrc.c \ - asrcacld.c \ - asrcask.c \ - asrcconv.c \ - asrcdefs.h \ - asrcdel.c \ - asrcdest.c \ - asrcext.h \ - asrcfbr.c \ - asrcitf.h \ - asrcload.c \ - asrcmdel.c \ - asrcpar.c \ - asrcpzld.c \ - asrcset.c - +libasrc_la_SOURCES = \ + asrc.c \ + asrcacld.c \ + asrcask.c \ + asrcconv.c \ + asrcdefs.h \ + asrcdel.c \ + asrcdest.c \ + asrcext.h \ + asrcfbr.c \ + asrcitf.h \ + asrcinit.c \ + asrcinit.h \ + asrcload.c \ + asrcmdel.c \ + asrcpar.c \ + asrcpzld.c \ + asrcset.c INCLUDES = -I$(top_srcdir)/src/include diff --git a/src/spicelib/devices/asrc/asrcacld.c b/src/spicelib/devices/asrc/asrcacld.c index 9321518cc..c3c115d91 100644 --- a/src/spicelib/devices/asrc/asrcacld.c +++ b/src/spicelib/devices/asrc/asrcacld.c @@ -16,9 +16,7 @@ Author: 1988 Kanwar Jit Singh /*ARGSUSED*/ int -ASRCacLoad(inModel,ckt) -GENmodel *inModel; -CKTcircuit *ckt; +ASRCacLoad(GENmodel *inModel, CKTcircuit *ckt) { /* @@ -27,8 +25,8 @@ CKTcircuit *ckt; * been precomputed and stored with the instance model. */ - register ASRCmodel *model = (ASRCmodel*)inModel; - register ASRCinstance *here; + ASRCmodel *model = (ASRCmodel*)inModel; + ASRCinstance *here; int i, v_first, j; double *derivs; double rhs; @@ -38,71 +36,62 @@ CKTcircuit *ckt; /* loop through all the instances of the model */ for (here = model->ASRCinstances; here != NULL ; - here = here->ASRCnextInstance) { - if (here->ASRCowner != ARCHme) continue; + here = here->ASRCnextInstance) { + if (here->ASRCowner != ARCHme) continue; - /* - * Get the function and its derivatives from the - * field in the instance structure. The field is - * an array of doubles holding the rhs, and the - * entries of the jacobian. - */ + /* + * Get the function and its derivatives from the + * field in the instance structure. The field is + * an array of doubles holding the rhs, and the + * entries of the jacobian. + */ - v_first = 1; - j=0; - derivs = here->ASRCacValues; - rhs = (here->ASRCacValues)[here->ASRCtree->numVars]; + v_first = 1; + j=0; + derivs = here->ASRCacValues; + rhs = (here->ASRCacValues)[here->ASRCtree->numVars]; - for(i=0; i < here->ASRCtree->numVars; i++){ - switch(here->ASRCtree->varTypes[i]){ - case IF_INSTANCE: - if( here->ASRCtype == ASRC_VOLTAGE){ - /* CCVS */ - if(v_first){ - *(here->ASRCposptr[j++]) += 1.0; - *(here->ASRCposptr[j++]) -= 1.0; - *(here->ASRCposptr[j++]) -= 1.0; - *(here->ASRCposptr[j++]) += 1.0; - v_first = 0; - } - *(here->ASRCposptr[j++]) -= derivs[i]; - } else{ - /* CCCS */ - *(here->ASRCposptr[j++]) += derivs[i]; - *(here->ASRCposptr[j++]) -= derivs[i]; - } - break; - case IF_NODE: - if(here->ASRCtype == ASRC_VOLTAGE){ - /* VCVS */ - if( v_first){ - *(here->ASRCposptr[j++]) += 1.0; - *(here->ASRCposptr[j++]) -= 1.0; - *(here->ASRCposptr[j++]) -= 1.0; - *(here->ASRCposptr[j++]) += 1.0; - v_first = 0; - } - *(here->ASRCposptr[j++]) -= derivs[i]; - } else { - /*VCCS*/ - *(here->ASRCposptr[j++]) += derivs[i]; - *(here->ASRCposptr[j++]) -= derivs[i]; - } - break; - default: - return(E_BADPARM); - } - } -#ifdef notdef - /* Insert the RHS */ - if( here->ASRCtype == ASRC_VOLTAGE){ - *(ckt->CKTrhs+(here->ASRCbranch)) += rhs; - } else { - *(ckt->CKTrhs+(here->ASRCposNode)) -= rhs; - *(ckt->CKTrhs+(here->ASRCnegNode)) += rhs; - } -#endif - } + for(i=0; i < here->ASRCtree->numVars; i++){ + switch(here->ASRCtree->varTypes[i]){ + case IF_INSTANCE: + if( here->ASRCtype == ASRC_VOLTAGE){ + /* CCVS */ + if(v_first){ + *(here->ASRCposptr[j++]) += 1.0; + *(here->ASRCposptr[j++]) -= 1.0; + *(here->ASRCposptr[j++]) -= 1.0; + *(here->ASRCposptr[j++]) += 1.0; + v_first = 0; + } + *(here->ASRCposptr[j++]) -= derivs[i]; + } else{ + /* CCCS */ + *(here->ASRCposptr[j++]) += derivs[i]; + *(here->ASRCposptr[j++]) -= derivs[i]; + } + break; + case IF_NODE: + if(here->ASRCtype == ASRC_VOLTAGE){ + /* VCVS */ + if( v_first){ + *(here->ASRCposptr[j++]) += 1.0; + *(here->ASRCposptr[j++]) -= 1.0; + *(here->ASRCposptr[j++]) -= 1.0; + *(here->ASRCposptr[j++]) += 1.0; + v_first = 0; + } + *(here->ASRCposptr[j++]) -= derivs[i]; + } else { + /*VCCS*/ + *(here->ASRCposptr[j++]) += derivs[i]; + *(here->ASRCposptr[j++]) -= derivs[i]; + } + break; + default: + return(E_BADPARM); + } + } + } } return(OK); } diff --git a/src/spicelib/devices/asrc/asrcask.c b/src/spicelib/devices/asrc/asrcask.c index 8059aed46..0656de0ed 100644 --- a/src/spicelib/devices/asrc/asrcask.c +++ b/src/spicelib/devices/asrc/asrcask.c @@ -30,7 +30,7 @@ ASRCask(ckt,instPtr,which,value,select) IFvalue *value; IFvalue *select; { - register ASRCinstance *here = (ASRCinstance*)instPtr; + ASRCinstance *here = (ASRCinstance*)instPtr; switch(which) { case ASRC_CURRENT: diff --git a/src/spicelib/devices/asrc/asrcconv.c b/src/spicelib/devices/asrc/asrcconv.c index 95afcb913..665b6f748 100644 --- a/src/spicelib/devices/asrc/asrcconv.c +++ b/src/spicelib/devices/asrc/asrcconv.c @@ -15,8 +15,8 @@ ASRCconvTest( inModel, ckt) GENmodel *inModel; CKTcircuit *ckt; { - register ASRCmodel *model = (ASRCmodel *)inModel; - register ASRCinstance *here; + ASRCmodel *model = (ASRCmodel *)inModel; + ASRCinstance *here; int i, node_num, branch; double diff; double prev; diff --git a/src/spicelib/devices/asrc/asrcdel.c b/src/spicelib/devices/asrc/asrcdel.c index ebfb5e79f..ee3714902 100644 --- a/src/spicelib/devices/asrc/asrcdel.c +++ b/src/spicelib/devices/asrc/asrcdel.c @@ -20,7 +20,7 @@ ASRCdelete(model,name,fast) GENinstance **fast; { - register ASRCinstance **instPtr = (ASRCinstance**)fast; + ASRCinstance **instPtr = (ASRCinstance**)fast; ASRCmodel *modPtr = (ASRCmodel*)model; ASRCinstance **prev = NULL; diff --git a/src/spicelib/devices/asrc/asrcfbr.c b/src/spicelib/devices/asrc/asrcfbr.c index d3f05cb51..94c2ed05d 100644 --- a/src/spicelib/devices/asrc/asrcfbr.c +++ b/src/spicelib/devices/asrc/asrcfbr.c @@ -17,12 +17,12 @@ Author: 1987 Kanwar Jit Singh int ASRCfindBr(ckt,inputModel,name) - register CKTcircuit *ckt; + CKTcircuit *ckt; GENmodel *inputModel; - register IFuid name; + IFuid name; { - register ASRCinstance *here; - register ASRCmodel *model = (ASRCmodel*)inputModel; + ASRCinstance *here; + ASRCmodel *model = (ASRCmodel*)inputModel; int error; CKTnode *tmp; diff --git a/src/spicelib/devices/asrc/asrcitf.h b/src/spicelib/devices/asrc/asrcitf.h index fa64272b1..0f5b12436 100644 --- a/src/spicelib/devices/asrc/asrcitf.h +++ b/src/spicelib/devices/asrc/asrcitf.h @@ -1,80 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_asrc - #ifndef DEV_ASRC #define DEV_ASRC -#include "asrcext.h" -extern IFparm ASRCpTable[ ]; -extern char *ASRCnames[ ]; -extern int ASRCpTSize; -extern int ASRCnSize; -extern int ASRCiSize; -extern int ASRCmSize; - -SPICEdev ASRCinfo = { - { - "ASRC", - "Arbitrary Source ", - - &ASRCnSize, - &ASRCnSize, - ASRCnames, - - &ASRCpTSize, - ASRCpTable, - - 0, - NULL, - DEV_DEFAULT - }, - - ASRCparam, - NULL, - ASRCload, - ASRCsetup, - ASRCunsetup, - ASRCsetup, - NULL, - NULL, - ASRCfindBr, - ASRCacLoad, /* ac and normal load functions NOT identical */ - NULL, - ASRCdestroy, -#ifdef DELETES - ASRCmDelete, - ASRCdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - NULL, - NULL, - NULL, -#ifdef AN_pz - ASRCpzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ -#ifdef NEWCONV - ASRCconvTest, -#else /* NEWCONV */ - NULL, -#endif /* NEWCONV */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, /* DISTO */ - NULL, /* NOISE */ - - &ASRCiSize, - &ASRCmSize -}; +extern SPICEdev *get_asrc_info(void); #endif -#endif diff --git a/src/spicelib/devices/asrc/asrcload.c b/src/spicelib/devices/asrc/asrcload.c index 04717c527..2a7613f62 100644 --- a/src/spicelib/devices/asrc/asrcload.c +++ b/src/spicelib/devices/asrc/asrcload.c @@ -27,8 +27,8 @@ CKTcircuit *ckt; * sparse matrix previously provided */ - register ASRCmodel *model = (ASRCmodel*)inModel; - register ASRCinstance *here; + ASRCmodel *model = (ASRCmodel*)inModel; + ASRCinstance *here; int i, v_first, j, branch; int node_num; int size; @@ -39,7 +39,7 @@ CKTcircuit *ckt; /* loop through all the instances of the model */ for (here = model->ASRCinstances; here != NULL ; - here=here->ASRCnextInstance) + here=here->ASRCnextInstance) { if (here->ASRCowner != ARCHme) continue; @@ -49,13 +49,13 @@ CKTcircuit *ckt; v_first = 1; i = here->ASRCtree->numVars; if (asrc_nvals < i) { - if (asrc_nvals) { - FREE(asrc_vals); - FREE(asrc_derivs); - } - asrc_nvals = i; - asrc_vals = NEWN(double, i); - asrc_derivs = NEWN(double, i); + if (asrc_nvals) { + FREE(asrc_vals); + FREE(asrc_derivs); + } + asrc_nvals = i; + asrc_vals = NEWN(double, i); + asrc_derivs = NEWN(double, i); } j=0; @@ -65,42 +65,21 @@ CKTcircuit *ckt; */ for( i=0; i < here->ASRCtree->numVars; i++){ if( here->ASRCtree->varTypes[i] == IF_INSTANCE){ - branch = CKTfndBranch(ckt, - here->ASRCtree->vars[i].uValue); - asrc_vals[i] = *(ckt->CKTrhsOld+branch); + branch = CKTfndBranch(ckt, + here->ASRCtree->vars[i].uValue); + asrc_vals[i] = *(ckt->CKTrhsOld+branch); } else { - node_num = ((CKTnode *)(here->ASRCtree->vars[i]. - nValue))->number; - asrc_vals[i] = *(ckt->CKTrhsOld+node_num); + node_num = ((CKTnode *)(here->ASRCtree->vars[i]. + nValue))->number; + asrc_vals[i] = *(ckt->CKTrhsOld+node_num); } } if ((*(here->ASRCtree->IFeval))(here->ASRCtree,ckt->CKTgmin, &rhs, - asrc_vals,asrc_derivs) == OK) + asrc_vals,asrc_derivs) == OK) { /* The convergence test */ - - if ( (ckt->CKTmode & MODEINITFIX) || - (ckt->CKTmode & MODEINITFLOAT) ) - { -#ifndef NEWCONV - prev = here->ASRCprev_value; - diff = fabs( prev - rhs); - if ( here->ASRCtype == ASRC_VOLTAGE) { - tol = ckt->CKTreltol * - MAX(fabs(rhs),fabs(prev)) + ckt->CKTvoltTol; - } else { - tol = ckt->CKTreltol * - MAX(fabs(rhs),fabs(prev)) + ckt->CKTabstol; - } - - if ( diff > tol) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; - } -#endif /* NEWCONV */ - } here->ASRCprev_value = rhs; /* The ac load precomputation and storage */ @@ -109,7 +88,7 @@ CKTcircuit *ckt; size = (here->ASRCtree->numVars)+1 ; here->ASRCacValues = NEWN(double, size); for ( i = 0; i < here->ASRCtree->numVars; i++){ - here->ASRCacValues[i] = asrc_derivs[i]; + here->ASRCacValues[i] = asrc_derivs[i]; } } diff --git a/src/spicelib/devices/asrc/asrcmdel.c b/src/spicelib/devices/asrc/asrcmdel.c index 20d6825f4..2a68253c8 100644 --- a/src/spicelib/devices/asrc/asrcmdel.c +++ b/src/spicelib/devices/asrc/asrcmdel.c @@ -21,11 +21,11 @@ ASRCmDelete(modList,modname,killModel) { - register ASRCmodel **model = (ASRCmodel**)modList; - register ASRCmodel *modfast = (ASRCmodel*)killModel; - register ASRCinstance *here; - register ASRCinstance *prev = NULL; - register ASRCmodel **oldmod; + ASRCmodel **model = (ASRCmodel**)modList; + ASRCmodel *modfast = (ASRCmodel*)killModel; + ASRCinstance *here; + ASRCinstance *prev = NULL; + ASRCmodel **oldmod; oldmod = model; for( ; *model ; model = &((*model)->ASRCnextModel)) { if( (*model)->ASRCmodName == modname || diff --git a/src/spicelib/devices/asrc/asrcpar.c b/src/spicelib/devices/asrc/asrcpar.c index 76df8202e..098eda7c8 100644 --- a/src/spicelib/devices/asrc/asrcpar.c +++ b/src/spicelib/devices/asrc/asrcpar.c @@ -22,7 +22,7 @@ ASRCparam(param,value,fast,select) GENinstance *fast; IFvalue *select; { - register ASRCinstance *here = (ASRCinstance*)fast; + ASRCinstance *here = (ASRCinstance*)fast; switch(param) { case ASRC_VOLTAGE: here->ASRCtype = ASRC_VOLTAGE; diff --git a/src/spicelib/devices/asrc/asrcpzld.c b/src/spicelib/devices/asrc/asrcpzld.c index f9c5b1fec..02af43dee 100644 --- a/src/spicelib/devices/asrc/asrcpzld.c +++ b/src/spicelib/devices/asrc/asrcpzld.c @@ -23,8 +23,8 @@ ASRCpzLoad(inModel,ckt,s) * sparse matrix previously provided */ { - register ASRCmodel *model = (ASRCmodel*)inModel; - register ASRCinstance *here; + ASRCmodel *model = (ASRCmodel*)inModel; + ASRCinstance *here; double value; int i, v_first, j, branch; int node_num; diff --git a/src/spicelib/devices/asrc/asrcset.c b/src/spicelib/devices/asrc/asrcset.c index 10708d3c4..2201f72de 100644 --- a/src/spicelib/devices/asrc/asrcset.c +++ b/src/spicelib/devices/asrc/asrcset.c @@ -17,17 +17,17 @@ Author: 1987 Kanwar Jit Singh /*ARGSUSED*/ int ASRCsetup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int *states; /* load the voltage source structure with those * pointers needed later for fast matrix loading */ { - register ASRCinstance *here; - register ASRCmodel *model = (ASRCmodel*)inModel; + ASRCinstance *here; + ASRCmodel *model = (ASRCmodel*)inModel; int error, i, j; int v_first; CKTnode *tmp; @@ -147,7 +147,6 @@ ASRCunsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM ASRCmodel *model; ASRCinstance *here; @@ -163,6 +162,5 @@ ASRCunsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/bjt/ChangeLog b/src/spicelib/devices/bjt/ChangeLog index bc1d9061c..e9e419883 100644 --- a/src/spicelib/devices/bjt/ChangeLog +++ b/src/spicelib/devices/bjt/ChangeLog @@ -1,8 +1,12 @@ -1999-09-07 Arno +2000-09-02 Arno W. Peters + + * bjtdset.c: reformatted + +1999-09-07 Arno W. Peters * bjtnoise.c: removed unused variable `error'. -1999-09-06 Arno Peters +1999-09-06 Arno W. Peters * bjtnoise.c: Reformatted comment. diff --git a/src/spicelib/devices/bjt/Makefile.am b/src/spicelib/devices/bjt/Makefile.am index 0cefc40f7..5d0e4655c 100644 --- a/src/spicelib/devices/bjt/Makefile.am +++ b/src/spicelib/devices/bjt/Makefile.am @@ -2,35 +2,37 @@ pkglib_LTLIBRARIES = libbjt.la -libbjt_la_SOURCES = \ - bjt.c \ - bjtacld.c \ - bjtask.c \ - bjtconv.c \ - bjtdefs.h \ - bjtdel.c \ - bjtdest.c \ - bjtdisto.c \ - bjtdset.c \ - bjtdset.h \ - bjtext.h \ - bjtgetic.c \ - bjtitf.h \ - bjtload.c \ - bjtmask.c \ - bjtmdel.c \ - bjtmpar.c \ - bjtnoise.c \ - bjtparam.c \ - bjtpzld.c \ - bjtsacl.c \ - bjtsetup.c \ - bjtsload.c \ - bjtsprt.c \ - bjtsset.c \ - bjtsupd.c \ - bjttemp.c \ - bjttrunc.c +libbjt_la_SOURCES = \ + bjt.c \ + bjtacld.c \ + bjtask.c \ + bjtconv.c \ + bjtdefs.h \ + bjtdel.c \ + bjtdest.c \ + bjtdisto.c \ + bjtdset.c \ + bjtdset.h \ + bjtext.h \ + bjtgetic.c \ + bjtinit.c \ + bjtinit.h \ + bjtitf.h \ + bjtload.c \ + bjtmask.c \ + bjtmdel.c \ + bjtmpar.c \ + bjtnoise.c \ + bjtparam.c \ + bjtpzld.c \ + bjtsacl.c \ + bjtsetup.c \ + bjtsload.c \ + bjtsprt.c \ + bjtsset.c \ + bjtsupd.c \ + bjttemp.c \ + bjttrunc.c diff --git a/src/spicelib/devices/bjt/bjtacld.c b/src/spicelib/devices/bjt/bjtacld.c index 2f1b45b8b..f647e2c28 100644 --- a/src/spicelib/devices/bjt/bjtacld.c +++ b/src/spicelib/devices/bjt/bjtacld.c @@ -18,12 +18,12 @@ Author: 1985 Thomas L. Quarles int BJTacLoad(inModel,ckt) - register GENmodel *inModel; + GENmodel *inModel; CKTcircuit *ckt; { - register BJTinstance *here; - register BJTmodel *model = (BJTmodel*)inModel; + BJTinstance *here; + BJTmodel *model = (BJTmodel*)inModel; double gcpr; double gepr; double gpi; diff --git a/src/spicelib/devices/bjt/bjtconv.c b/src/spicelib/devices/bjt/bjtconv.c index 17a5ec917..99baeee10 100644 --- a/src/spicelib/devices/bjt/bjtconv.c +++ b/src/spicelib/devices/bjt/bjtconv.c @@ -18,11 +18,11 @@ Author: 1985 Thomas L. Quarles int BJTconvTest(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register BJTinstance *here; - register BJTmodel *model = (BJTmodel *) inModel; + BJTinstance *here; + BJTmodel *model = (BJTmodel *) inModel; double tol; double cc; double cchat; diff --git a/src/spicelib/devices/bjt/bjtdisto.c b/src/spicelib/devices/bjt/bjtdisto.c index 08c993454..a5bfc39bd 100644 --- a/src/spicelib/devices/bjt/bjtdisto.c +++ b/src/spicelib/devices/bjt/bjtdisto.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1988 Jaijeet S Roychowdhury +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -17,7 +18,7 @@ Author: 1988 Jaijeet S Roychowdhury * the correct value */ int -BJTdisto(int mode, GENmodel *genmodel, register CKTcircuit *ckt) +BJTdisto(int mode, GENmodel *genmodel, CKTcircuit *ckt) { BJTmodel *model = (BJTmodel *) genmodel; DISTOAN* job = (DISTOAN*) ckt->CKTcurJob; @@ -39,13 +40,13 @@ BJTdisto(int mode, GENmodel *genmodel, register CKTcircuit *ckt) double r2h1m2y,i2h1m2y; double r2h1m2z, i2h1m2z; double temp, itemp; - register BJTinstance *here; + BJTinstance *here; #ifdef DISTODEBUG double time; #endif if (mode == D_SETUP) - return(BJTdSetup(model,ckt)); + return(BJTdSetup((GENmodel *)model,ckt)); if ((mode == D_TWOF1) || (mode == D_THRF1) || (mode == D_F1PF2) || (mode == D_F1MF2) || diff --git a/src/spicelib/devices/bjt/bjtdset.c b/src/spicelib/devices/bjt/bjtdset.c index fae419274..884c95390 100644 --- a/src/spicelib/devices/bjt/bjtdset.c +++ b/src/spicelib/devices/bjt/bjtdset.c @@ -23,8 +23,8 @@ Author: 1988 Jaijeet S Roychowdhury int BJTdSetup(GENmodel *inModel, CKTcircuit *ckt) { - register BJTmodel *model = (BJTmodel*)inModel; - register BJTinstance *here; + BJTmodel *model = (BJTmodel*)inModel; + BJTinstance *here; double arg; double c2; double c4; @@ -96,57 +96,57 @@ BJTdSetup(GENmodel *inModel, CKTcircuit *ckt) double vbed; double vbb; -double lcapbc1 = 0.0; -double lcapbc2 = 0.0; -double lcapbc3 = 0.0; + double lcapbc1 = 0.0; + double lcapbc2 = 0.0; + double lcapbc3 = 0.0; -double lcapsc1 = 0.0; -double lcapsc2 = 0.0; -double lcapsc3 = 0.0; -double ic; -double dummy; -Dderivs d_p, d_q, d_r; -Dderivs d_dummy, d_q1, d_qb, d_dummy2; -Dderivs d_arg, d_sqarg, d_ic, d_q2; -Dderivs d_z, d_tanz, d_vbb, d_ibb, d_rbb; -Dderivs d_ib, d_cbe, d_tff, d_qbe; + double lcapsc1 = 0.0; + double lcapsc2 = 0.0; + double lcapsc3 = 0.0; + double ic; + double dummy; + Dderivs d_p, d_q, d_r; + Dderivs d_dummy, d_q1, d_qb, d_dummy2; + Dderivs d_arg, d_sqarg, d_ic, d_q2; + Dderivs d_z, d_tanz, d_vbb, d_ibb, d_rbb; + Dderivs d_ib, d_cbe, d_tff, d_qbe; -d_p.value = 0.0; -d_p.d1_p = 1.0; -d_p.d1_q = 0.0; -d_p.d1_r = 0.0; -d_p.d2_p2 = 0.0; -d_p.d2_q2 = 0.0; -d_p.d2_r2 = 0.0; -d_p.d2_pq = 0.0; -d_p.d2_qr = 0.0; -d_p.d2_pr = 0.0; -d_p.d3_p3 = 0.0; -d_p.d3_q3 = 0.0; -d_p.d3_r3 = 0.0; -d_p.d3_p2q = 0.0; -d_p.d3_p2r = 0.0; -d_p.d3_pq2 = 0.0; -d_p.d3_q2r = 0.0; -d_p.d3_pr2 = 0.0; -d_p.d3_qr2 = 0.0; -d_p.d3_pqr = 0.0; + d_p.value = 0.0; + d_p.d1_p = 1.0; + d_p.d1_q = 0.0; + d_p.d1_r = 0.0; + d_p.d2_p2 = 0.0; + d_p.d2_q2 = 0.0; + d_p.d2_r2 = 0.0; + d_p.d2_pq = 0.0; + d_p.d2_qr = 0.0; + d_p.d2_pr = 0.0; + d_p.d3_p3 = 0.0; + d_p.d3_q3 = 0.0; + d_p.d3_r3 = 0.0; + d_p.d3_p2q = 0.0; + d_p.d3_p2r = 0.0; + d_p.d3_pq2 = 0.0; + d_p.d3_q2r = 0.0; + d_p.d3_pr2 = 0.0; + d_p.d3_qr2 = 0.0; + d_p.d3_pqr = 0.0; -EqualDeriv(&d_q, &d_p); -d_q.d1_q = 1.0; -d_q.d1_p = 0.0; + EqualDeriv(&d_q, &d_p); + d_q.d1_q = 1.0; + d_q.d1_p = 0.0; -EqualDeriv(&d_r, &d_p); -d_r.d1_r = 1.0; -d_r.d1_p = 0.0; + EqualDeriv(&d_r, &d_p); + d_r.d1_r = 1.0; + d_r.d1_p = 0.0; -/* loop through all the models */ -for( ; model != NULL; model = model->BJTnextModel ) { + /* loop through all the models */ + for( ; model != NULL; model = model->BJTnextModel ) { /* loop through all the instances of the model */ for (here = model->BJTinstances; here != NULL ; - here=here->BJTnextInstance) { + here=here->BJTnextInstance) { vt = here->BJTtemp * CONSTKoverQ; @@ -169,60 +169,56 @@ for( ; model != NULL; model = model->BJTnextModel ) { /* * initialization */ - vbe= model->BJTtype*(*(ckt->CKTrhsOld + here->BJTbasePrimeNode) - - *(ckt->CKTrhsOld + here->BJTemitPrimeNode)); - vbc= model->BJTtype*(*(ckt->CKTrhsOld + here->BJTbaseNode) - - *(ckt->CKTrhsOld + here->BJTcolPrimeNode)); - vbx=model->BJTtype*( - *(ckt->CKTrhsOld+here->BJTbaseNode)- - *(ckt->CKTrhsOld+here->BJTcolPrimeNode)); - vsc=model->BJTtype*( - *(ckt->CKTrhsOld+here->BJTsubstNode)- - *(ckt->CKTrhsOld+here->BJTcolPrimeNode)); + vbe= model->BJTtype*(*(ckt->CKTrhsOld + here->BJTbasePrimeNode) - + *(ckt->CKTrhsOld + here->BJTemitPrimeNode)); + vbc= model->BJTtype*(*(ckt->CKTrhsOld + here->BJTbaseNode) - + *(ckt->CKTrhsOld + here->BJTcolPrimeNode)); + vbx=model->BJTtype*( + *(ckt->CKTrhsOld+here->BJTbaseNode)- + *(ckt->CKTrhsOld+here->BJTcolPrimeNode)); + vsc=model->BJTtype*( + *(ckt->CKTrhsOld+here->BJTsubstNode)- + *(ckt->CKTrhsOld+here->BJTcolPrimeNode)); - vbb=model->BJTtype*( - *(ckt->CKTrhsOld+here->BJTbaseNode) - - *(ckt->CKTrhsOld+here->BJTbasePrimeNode)); + vbb=model->BJTtype*( + *(ckt->CKTrhsOld+here->BJTbaseNode) - + *(ckt->CKTrhsOld+here->BJTbasePrimeNode)); - vbed = vbe; /* this is just a dummy variable - * it is the delayed vbe to be - * used in the delayed gm generator - */ + vbed = vbe; /* this is just a dummy variable + * it is the delayed vbe to be + * used in the delayed gm generator + */ - /* ic = f1(vbe,vbc,vbed) + f2(vbc) + f3(vbc) - * - * we shall calculate the taylor coeffs of - * ic wrt vbe, vbed, and vbc and store them away. - * the equations f1 f2 and f3 are given elsewhere; - * we shall start off with f1, compute - * derivs. upto third order and then do f2 and - * f3 and add their derivatives. - * - * Since f1 above is a function of three variables, it - * will be convenient to use derivative structures - * to compute the derivatives of f1. For this - * computation, p=vbe, q=vbc, r=vbed. - * - * ib = f1(vbe) + f2(vbc) (not the same f's as - * above, in case you are - * wondering!) - * the gbe's gbc's gben's and gbcn's are - * convenient subsidiary variables. - * - * irb = f(vbe, vbc, vbb) - the vbe & vbc - * dependencies arise from the - * qb term. - * qbe = f1(vbe,vbc) + f2(vbe) - * - * derivative structures will be used again in the - * above two equations. p=vbe, q=vbc, r=vbb. - * - * qbc = f(vbc) ; qbx = f(vbx) - * - * qss = f(vsc) - */ + /* ic = f1(vbe,vbc,vbed) + f2(vbc) + f3(vbc) + * + * we shall calculate the taylor coeffs of ic wrt vbe, + * vbed, and vbc and store them away. the equations f1 f2 + * and f3 are given elsewhere; we shall start off with f1, + * compute derivs. upto third order and then do f2 and f3 + * and add their derivatives. + * + * Since f1 above is a function of three variables, it + * will be convenient to use derivative structures to + * compute the derivatives of f1. For this computation, + * p=vbe, q=vbc, r=vbed. + * + * ib = f1(vbe) + f2(vbc) (not the same f's as above, in + * case you are wondering!) the gbe's gbc's gben's and + * gbcn's are convenient subsidiary variables. + * + * irb = f(vbe, vbc, vbb) - the vbe & vbc dependencies + * arise from the qb term. + * + * qbe = f1(vbe,vbc) + f2(vbe) + * + * derivative structures will be used again in the above + * two equations. p=vbe, q=vbc, r=vbb. + * + * qbc = f(vbc) ; qbx = f(vbx) + * + * qss = f(vsc) */ /* * determine dc current and derivitives */ @@ -283,19 +279,21 @@ for( ; model != NULL; model = model->BJTnextModel ) { /* * determine base charge terms */ - /* q1 is a function of 2 variables p=vbe and q=vbc. r= - * anything - */ + /* q1 is a function of 2 variables p=vbe and q=vbc. r= + * anything + */ q1=1/(1-model->BJTinvEarlyVoltF*vbc-model->BJTinvEarlyVoltR*vbe); dummy = (1-model->BJTinvEarlyVoltF*vbc- - model->BJTinvEarlyVoltR*vbe); - EqualDeriv(&d_dummy, &d_p); - d_dummy.value = dummy; - d_dummy.d1_p = - model->BJTinvEarlyVoltR; - d_dummy.d1_q = - model->BJTinvEarlyVoltF; - /* q1 = 1/dummy */ - InvDeriv(&d_q1, &d_dummy); /* now q1 and its derivatives are - set up */ + model->BJTinvEarlyVoltR*vbe); + EqualDeriv(&d_dummy, &d_p); + d_dummy.value = dummy; + d_dummy.d1_p = - model->BJTinvEarlyVoltR; + d_dummy.d1_q = - model->BJTinvEarlyVoltF; + + /* q1 = 1/dummy */ + InvDeriv(&d_q1, &d_dummy); + + /* now q1 and its derivatives are set up */ if(oik == 0 && oikr == 0) { qb=q1; EqualDeriv(&d_qb, &d_q1); @@ -312,21 +310,21 @@ for( ; model != NULL; model = model->BJTnextModel ) { arg=MAX(0,1+4*q2); if (arg == 0.) { - EqualDeriv(&d_arg,&d_p); - d_arg.d1_p = 0.0; + EqualDeriv(&d_arg,&d_p); + d_arg.d1_p = 0.0; } else { - TimesDeriv(&d_arg,&d_q2,4.0); - d_arg.value += 1.; + TimesDeriv(&d_arg,&d_q2,4.0); + d_arg.value += 1.; } sqarg=1; EqualDeriv(&d_sqarg,&d_p); d_sqarg.value = 1.0; d_sqarg.d1_p = 0.0; if(arg != 0){ - sqarg=sqrt(arg); - SqrtDeriv(&d_sqarg, &d_arg); + sqarg=sqrt(arg); + SqrtDeriv(&d_sqarg, &d_arg); } qb=q1*(1+sqarg)/2; @@ -337,129 +335,131 @@ for( ; model != NULL; model = model->BJTnextModel ) { TimesDeriv(&d_qb, &d_qb, 0.5); } -ic = (cbe - cbc)/qb; -/* cbe is a fn of vbed only; cbc of vbc; and qb of vbe and vbc */ -/* p=vbe, q=vbc, r=vbed; now dummy = cbe - cbc */ -EqualDeriv(&d_dummy, &d_p); -d_dummy.d1_p = 0.0; -d_dummy.value = cbe-cbc; -d_dummy.d1_r = gbe; -d_dummy.d2_r2 = gbe2; -d_dummy.d3_r3 = gbe3; -d_dummy.d1_q = -gbc; -d_dummy.d2_q2 = -gbc2; -d_dummy.d3_q3 = -gbc3; + ic = (cbe - cbc)/qb; + /* cbe is a fn of vbed only; cbc of vbc; and qb of vbe and vbc */ + /* p=vbe, q=vbc, r=vbed; now dummy = cbe - cbc */ + EqualDeriv(&d_dummy, &d_p); + d_dummy.d1_p = 0.0; + d_dummy.value = cbe-cbc; + d_dummy.d1_r = gbe; + d_dummy.d2_r2 = gbe2; + d_dummy.d3_r3 = gbe3; + d_dummy.d1_q = -gbc; + d_dummy.d2_q2 = -gbc2; + d_dummy.d3_q3 = -gbc3; -DivDeriv(&d_ic, &d_dummy, &d_qb); + DivDeriv(&d_ic, &d_dummy, &d_qb); -d_ic.value -= cbc/here->BJTtBetaR + cbcn; -d_ic.d1_q -= gbc/here->BJTtBetaR + gbcn; -d_ic.d2_q2 -= gbc2/here->BJTtBetaR + gbcn2; -d_ic.d3_q3 -= gbc3/here->BJTtBetaR + gbcn3; + d_ic.value -= cbc/here->BJTtBetaR + cbcn; + d_ic.d1_q -= gbc/here->BJTtBetaR + gbcn; + d_ic.d2_q2 -= gbc2/here->BJTtBetaR + gbcn2; + d_ic.d3_q3 -= gbc3/here->BJTtBetaR + gbcn3; -/* check this point: where is the f2(vbe) contribution to ic ? */ + /* check this point: where is the f2(vbe) contribution to ic ? */ - /* ic derivatives all set up now */ + /* ic derivatives all set up now */ /* base spread resistance */ - if ( !((rbpr == 0.0) && (rbpi == 0.0))) - { - cb=cbe/here->BJTtBetaF+cben+cbc/here->BJTtBetaR+cbcn; - /* we are calculating derivatives w.r.t cb itself */ - /* - gx=rbpr+rbpi/qb; - */ - - if (cb != 0.0) { - if((xjrb != 0.0) && (rbpi != 0.0)) { - /* p = ib, q, r = anything */ - dummy=MAX(cb/xjrb,1e-9); - EqualDeriv(&d_dummy, &d_p); - d_dummy.value = dummy; - d_dummy.d1_p = 1/xjrb; - SqrtDeriv(&d_dummy, &d_dummy); - TimesDeriv(&d_dummy, &d_dummy, 2.4317); - + if ( !((rbpr == 0.0) && (rbpi == 0.0))) + { + cb=cbe/here->BJTtBetaF+cben+cbc/here->BJTtBetaR+cbcn; + /* we are calculating derivatives w.r.t cb itself */ /* - dummy2=(-1+sqrt(1+14.59025*MAX(cb/xjrb,1e-9))); + gx=rbpr+rbpi/qb; */ - EqualDeriv(&d_dummy2, &d_p); - d_dummy2.value = 1+14.59025*MAX(cb/xjrb,1e-9); - d_dummy2.d1_p = 14.59025/xjrb; - SqrtDeriv(&d_dummy2, &d_dummy2); - d_dummy2.value -= 1.0; - DivDeriv(&d_z, &d_dummy2, &d_dummy); - TanDeriv(&d_tanz, &d_z); + if (cb != 0.0) { + if((xjrb != 0.0) && (rbpi != 0.0)) { + /* p = ib, q, r = anything */ + dummy=MAX(cb/xjrb,1e-9); + EqualDeriv(&d_dummy, &d_p); + d_dummy.value = dummy; + d_dummy.d1_p = 1/xjrb; + SqrtDeriv(&d_dummy, &d_dummy); + TimesDeriv(&d_dummy, &d_dummy, 2.4317); - /*now using dummy = tanz - z and dummy2 = z*tanz*tanz */ - TimesDeriv(&d_dummy, &d_z, -1.0); - PlusDeriv(&d_dummy, &d_dummy, &d_tanz); + /* + dummy2=(-1+sqrt(1+14.59025*MAX(cb/xjrb,1e-9))); + */ + EqualDeriv(&d_dummy2, &d_p); + d_dummy2.value = 1+14.59025*MAX(cb/xjrb,1e-9); + d_dummy2.d1_p = 14.59025/xjrb; + SqrtDeriv(&d_dummy2, &d_dummy2); + d_dummy2.value -= 1.0; - MultDeriv(&d_dummy2, &d_tanz, &d_tanz); - MultDeriv(&d_dummy2, &d_dummy2, &d_z); + DivDeriv(&d_z, &d_dummy2, &d_dummy); + TanDeriv(&d_tanz, &d_z); - DivDeriv(&d_rbb , &d_dummy, &d_dummy2); - TimesDeriv(&d_rbb,&d_rbb, 3.0*rbpi); - d_rbb.value += rbpr; + /* now using dummy = tanz - z and dummy2 = + z*tanz*tanz */ + TimesDeriv(&d_dummy, &d_z, -1.0); + PlusDeriv(&d_dummy, &d_dummy, &d_tanz); - MultDeriv(&d_vbb, &d_rbb, &d_p); + MultDeriv(&d_dummy2, &d_tanz, &d_tanz); + MultDeriv(&d_dummy2, &d_dummy2, &d_z); - /* power series inversion to get the conductance derivatives */ + DivDeriv(&d_rbb , &d_dummy, &d_dummy2); + TimesDeriv(&d_rbb,&d_rbb, 3.0*rbpi); + d_rbb.value += rbpr; - if (d_vbb.d1_p != 0) { - gbb1 = 1/d_vbb.d1_p; - gbb2 = -(d_vbb.d2_p2*0.5)*gbb1*gbb1; - gbb3 = gbb1*gbb1*gbb1*gbb1*(-(d_vbb.d3_p3/6.0) - + 2*(d_vbb.d2_p2*0.5)*(d_vbb.d2_p2*0.5)*gbb1); + MultDeriv(&d_vbb, &d_rbb, &d_p); + + /* power series inversion to get the + conductance derivatives */ + + if (d_vbb.d1_p != 0) { + gbb1 = 1/d_vbb.d1_p; + gbb2 = -(d_vbb.d2_p2*0.5)*gbb1*gbb1; + gbb3 = gbb1*gbb1*gbb1*gbb1*(-(d_vbb.d3_p3/6.0) + + 2*(d_vbb.d2_p2*0.5)*(d_vbb.d2_p2*0.5)*gbb1); + } + else + printf("\nd_vbb.d1_p = 0 in base spread resistance calculations\n"); + + + /* r = vbb */ + EqualDeriv(&d_ibb, &d_r); + d_ibb.value = cb; + d_ibb.d1_r = gbb1; + d_ibb.d2_r2 = 2*gbb2; + d_ibb.d3_r3 = 6.0*gbb3; + } + else + { + /* + rbb = rbpr + rbpi/qb; + ibb = vbb /rbb; = f(vbe, vbc, vbb) + */ + + EqualDeriv(&d_rbb,&d_p); + d_rbb.d1_p = 0.0; + if (rbpi != 0.0) { + InvDeriv(&d_rbb, &d_qb); + TimesDeriv(&d_rbb, &d_rbb,rbpi); + } + d_rbb.value += rbpr; + + EqualDeriv(&d_ibb,&d_r); + d_ibb.value = vbb; + DivDeriv(&d_ibb,&d_ibb,&d_rbb); + + } } else - printf("\nd_vbb.d1_p = 0 in base spread resistance calculations\n"); - - -/* r = vbb */ -EqualDeriv(&d_ibb, &d_r); -d_ibb.value = cb; -d_ibb.d1_r = gbb1; -d_ibb.d2_r2 = 2*gbb2; -d_ibb.d3_r3 = 6.0*gbb3; - } - else - { - /* - rbb = rbpr + rbpi/qb; - ibb = vbb /rbb; = f(vbe, vbc, vbb) - */ - - EqualDeriv(&d_rbb,&d_p); - d_rbb.d1_p = 0.0; - if (rbpi != 0.0) { - InvDeriv(&d_rbb, &d_qb); - TimesDeriv(&d_rbb, &d_rbb,rbpi); - } - d_rbb.value += rbpr; - - EqualDeriv(&d_ibb,&d_r); - d_ibb.value = vbb; - DivDeriv(&d_ibb,&d_ibb,&d_rbb); - - } + { + EqualDeriv(&d_ibb,&d_r); + if (rbpr != 0.0) + d_ibb.d1_r = 1/rbpr; + } } else { - EqualDeriv(&d_ibb,&d_r); - if (rbpr != 0.0) - d_ibb.d1_r = 1/rbpr; - } - } - else - { - EqualDeriv(&d_ibb,&d_p); - d_ibb.d1_p = 0.0; + EqualDeriv(&d_ibb,&d_p); + d_ibb.d1_p = 0.0; } - /* formulae for base spread resistance over! */ + /* formulae for base spread resistance over! */ /* ib term */ @@ -475,233 +475,233 @@ d_ibb.d3_r3 = 6.0*gbb3; d_ib.d3_q3 = gbc3/here->BJTtBetaR + gbcn3; /* ib term over */ - /* - * charge storage elements - */ - tf=model->BJTtransitTimeF; - tr=model->BJTtransitTimeR; - czbe=here->BJTtBEcap*here->BJTarea; - pe=here->BJTtBEpot; - xme=model->BJTjunctionExpBE; - cdis=model->BJTbaseFractionBCcap; - ctot=here->BJTtBCcap*here->BJTarea; - czbc=ctot*cdis; - czbx=ctot-czbc; - pc=here->BJTtBCpot; - xmc=model->BJTjunctionExpBC; - fcpe=here->BJTtDepCap; - czcs=model->BJTcapCS*here->BJTarea; - ps=model->BJTpotentialSubstrate; - xms=model->BJTexponentialSubstrate; - xtf=model->BJTtransitTimeBiasCoeffF; - ovtf=model->BJTtransitTimeVBCFactor; - xjtf=model->BJTtransitTimeHighCurrentF*here->BJTarea; - if(tf != 0 && vbe >0) { - EqualDeriv(&d_cbe, &d_p); - d_cbe.value = cbe; - d_cbe.d1_p = gbe; - d_cbe.d2_p2 = gbe2; - d_cbe.d3_p3 = gbe3; - if(xtf != 0){ - if(ovtf != 0) { + /* + * charge storage elements + */ + tf=model->BJTtransitTimeF; + tr=model->BJTtransitTimeR; + czbe=here->BJTtBEcap*here->BJTarea; + pe=here->BJTtBEpot; + xme=model->BJTjunctionExpBE; + cdis=model->BJTbaseFractionBCcap; + ctot=here->BJTtBCcap*here->BJTarea; + czbc=ctot*cdis; + czbx=ctot-czbc; + pc=here->BJTtBCpot; + xmc=model->BJTjunctionExpBC; + fcpe=here->BJTtDepCap; + czcs=model->BJTcapCS*here->BJTarea; + ps=model->BJTpotentialSubstrate; + xms=model->BJTexponentialSubstrate; + xtf=model->BJTtransitTimeBiasCoeffF; + ovtf=model->BJTtransitTimeVBCFactor; + xjtf=model->BJTtransitTimeHighCurrentF*here->BJTarea; + if(tf != 0 && vbe >0) { + EqualDeriv(&d_cbe, &d_p); + d_cbe.value = cbe; + d_cbe.d1_p = gbe; + d_cbe.d2_p2 = gbe2; + d_cbe.d3_p3 = gbe3; + if(xtf != 0){ + if(ovtf != 0) { /* dummy = exp ( vbc*ovtf) */ EqualDeriv(&d_dummy, &d_q); d_dummy.value = vbc*ovtf; d_dummy.d1_q = ovtf; ExpDeriv(&d_dummy, &d_dummy); - } - else - { + } + else + { EqualDeriv(&d_dummy,&d_p); d_dummy.value = 1.0; d_dummy.d1_p = 0.0; - } - if(xjtf != 0) { - EqualDeriv(&d_dummy2, &d_cbe); - d_dummy2.value += xjtf; - DivDeriv(&d_dummy2, &d_cbe, &d_dummy2); - MultDeriv (&d_dummy2, &d_dummy2, &d_dummy2); - } - else - { - EqualDeriv(&d_dummy2,&d_p); - d_dummy2.value = 1.0; - d_dummy2.d1_p = 0.0; - } + } + if(xjtf != 0) { + EqualDeriv(&d_dummy2, &d_cbe); + d_dummy2.value += xjtf; + DivDeriv(&d_dummy2, &d_cbe, &d_dummy2); + MultDeriv (&d_dummy2, &d_dummy2, &d_dummy2); + } + else + { + EqualDeriv(&d_dummy2,&d_p); + d_dummy2.value = 1.0; + d_dummy2.d1_p = 0.0; + } - MultDeriv(&d_tff, &d_dummy, &d_dummy2); - TimesDeriv(&d_tff, &d_tff, tf*xtf); - d_tff.value += tf; - } - else - { - EqualDeriv(&d_tff,&d_p); - d_tff.value = tf; - d_tff.d1_p = 0.0; - } + MultDeriv(&d_tff, &d_dummy, &d_dummy2); + TimesDeriv(&d_tff, &d_tff, tf*xtf); + d_tff.value += tf; + } + else + { + EqualDeriv(&d_tff,&d_p); + d_tff.value = tf; + d_tff.d1_p = 0.0; + } - /* qbe = tff/qb*cbe */ + /* qbe = tff/qb*cbe */ -/* - dummy = tff/qb; - */ - /* these are the cbe coeffs */ -DivDeriv(&d_dummy, &d_tff, &d_qb); -MultDeriv(&d_qbe, &d_dummy, &d_cbe); + /* + dummy = tff/qb; + */ + /* these are the cbe coeffs */ + DivDeriv(&d_dummy, &d_tff, &d_qb); + MultDeriv(&d_qbe, &d_dummy, &d_cbe); - } - else - { - EqualDeriv(&d_qbe, &d_p); - d_qbe.value = 0.0; - d_qbe.d1_p = 0.0; - } - if (vbe < fcpe) { - arg=1-vbe/pe; - sarg=exp(-xme*log(arg)); - lcapbe1 = czbe*sarg; - lcapbe2 = + } + else + { + EqualDeriv(&d_qbe, &d_p); + d_qbe.value = 0.0; + d_qbe.d1_p = 0.0; + } + if (vbe < fcpe) { + arg=1-vbe/pe; + sarg=exp(-xme*log(arg)); + lcapbe1 = czbe*sarg; + lcapbe2 = 0.5*czbe*xme*sarg/(arg*pe); - lcapbe3 = + lcapbe3 = czbe*xme*(xme+1)*sarg/(arg*arg*pe*pe*6); - } else { - f1=here->BJTtf1; - f2=model->BJTf2; - f3=model->BJTf3; - czbef2=czbe/f2; - lcapbe1 = czbef2*(f3+xme*vbe/pe); - lcapbe2 = 0.5*xme*czbef2/pe; - lcapbe3 = 0.0; - } - d_qbe.d1_p += lcapbe1; - d_qbe.d2_p2 += lcapbe2*2.; - d_qbe.d3_p3 += lcapbe3*6.; + } else { + f1=here->BJTtf1; + f2=model->BJTf2; + f3=model->BJTf3; + czbef2=czbe/f2; + lcapbe1 = czbef2*(f3+xme*vbe/pe); + lcapbe2 = 0.5*xme*czbef2/pe; + lcapbe3 = 0.0; + } + d_qbe.d1_p += lcapbe1; + d_qbe.d2_p2 += lcapbe2*2.; + d_qbe.d3_p3 += lcapbe3*6.; - fcpc=here->BJTtf4; - f1=here->BJTtf5; - f2=model->BJTf6; - f3=model->BJTf7; - if (vbc < fcpc) { - arg=1-vbc/pc; - sarg=exp(-xmc*log(arg)); - lcapbc1 = czbc*sarg; - lcapbc2 = + fcpc=here->BJTtf4; + f1=here->BJTtf5; + f2=model->BJTf6; + f3=model->BJTf7; + if (vbc < fcpc) { + arg=1-vbc/pc; + sarg=exp(-xmc*log(arg)); + lcapbc1 = czbc*sarg; + lcapbc2 = 0.5*czbc*xmc*sarg/(arg*pc); - lcapbc3 = + lcapbc3 = czbc*xmc*(xmc+1)*sarg/(arg*arg*pc*pc*6); - } else { - czbcf2=czbc/f2; - lcapbc1 = czbcf2*(f3+xmc*vbc/pc); - lcapbc2 = 0.5*xmc*czbcf2/pc; - lcapbc3 = 0; - } - if(vbx < fcpc) { - arg=1-vbx/pc; - sarg=exp(-xmc*log(arg)); - lcapbx1 = czbx*sarg; - lcapbx2 = + } else { + czbcf2=czbc/f2; + lcapbc1 = czbcf2*(f3+xmc*vbc/pc); + lcapbc2 = 0.5*xmc*czbcf2/pc; + lcapbc3 = 0; + } + if(vbx < fcpc) { + arg=1-vbx/pc; + sarg=exp(-xmc*log(arg)); + lcapbx1 = czbx*sarg; + lcapbx2 = 0.5*czbx*xmc*sarg/(arg*pc); - lcapbx3 = + lcapbx3 = czbx*xmc*(xmc+1)*sarg/(arg*arg*pc*pc*6); - } else { - czbxf2=czbx/f2; - lcapbx1 = czbxf2*(f3+xmc*vbx/pc); - lcapbx2 = 0.5*xmc*czbxf2/pc; - lcapbx3 = 0; - } - if(vsc < 0){ - arg=1-vsc/ps; - sarg=exp(-xms*log(arg)); - lcapsc1 = czcs*sarg; - lcapsc2 = + } else { + czbxf2=czbx/f2; + lcapbx1 = czbxf2*(f3+xmc*vbx/pc); + lcapbx2 = 0.5*xmc*czbxf2/pc; + lcapbx3 = 0; + } + if(vsc < 0){ + arg=1-vsc/ps; + sarg=exp(-xms*log(arg)); + lcapsc1 = czcs*sarg; + lcapsc2 = 0.5*czcs*xms*sarg/(arg*ps); - lcapsc3 = + lcapsc3 = czcs*xms*(xms+1)*sarg/(arg*arg*ps*ps*6); - } else { - lcapsc1 = czcs*(1+xms*vsc/ps); - lcapsc2 = czcs*0.5*xms/ps; - lcapsc3 = 0; - } + } else { + lcapsc1 = czcs*(1+xms*vsc/ps); + lcapsc2 = czcs*0.5*xms/ps; + lcapsc3 = 0; + } - /* - * store small-signal parameters - */ -here->ic_x = d_ic.d1_p; -here->ic_y = d_ic.d1_q; -here->ic_xd = d_ic.d1_r; -here->ic_x2 = 0.5*model->BJTtype*d_ic.d2_p2; -here->ic_y2 = 0.5*model->BJTtype*d_ic.d2_q2; -here->ic_w2 = 0.5*model->BJTtype*d_ic.d2_r2; -here->ic_xy = model->BJTtype*d_ic.d2_pq; -here->ic_yw = model->BJTtype*d_ic.d2_qr; -here->ic_xw = model->BJTtype*d_ic.d2_pr; -here->ic_x3 = d_ic.d3_p3/6.; -here->ic_y3 = d_ic.d3_q3/6.; -here->ic_w3 = d_ic.d3_r3/6.; -here->ic_x2w = 0.5*d_ic.d3_p2r; -here->ic_x2y = 0.5*d_ic.d3_p2q; -here->ic_y2w = 0.5*d_ic.d3_q2r; -here->ic_xy2 = 0.5*d_ic.d3_pq2; -here->ic_xw2 = 0.5*d_ic.d3_pr2; -here->ic_yw2 = 0.5*d_ic.d3_qr2; -here->ic_xyw = d_ic.d3_pqr; + /* + * store small-signal parameters + */ + here->ic_x = d_ic.d1_p; + here->ic_y = d_ic.d1_q; + here->ic_xd = d_ic.d1_r; + here->ic_x2 = 0.5*model->BJTtype*d_ic.d2_p2; + here->ic_y2 = 0.5*model->BJTtype*d_ic.d2_q2; + here->ic_w2 = 0.5*model->BJTtype*d_ic.d2_r2; + here->ic_xy = model->BJTtype*d_ic.d2_pq; + here->ic_yw = model->BJTtype*d_ic.d2_qr; + here->ic_xw = model->BJTtype*d_ic.d2_pr; + here->ic_x3 = d_ic.d3_p3/6.; + here->ic_y3 = d_ic.d3_q3/6.; + here->ic_w3 = d_ic.d3_r3/6.; + here->ic_x2w = 0.5*d_ic.d3_p2r; + here->ic_x2y = 0.5*d_ic.d3_p2q; + here->ic_y2w = 0.5*d_ic.d3_q2r; + here->ic_xy2 = 0.5*d_ic.d3_pq2; + here->ic_xw2 = 0.5*d_ic.d3_pr2; + here->ic_yw2 = 0.5*d_ic.d3_qr2; + here->ic_xyw = d_ic.d3_pqr; -here->ib_x = d_ib.d1_p; -here->ib_y = d_ib.d1_q; -here->ib_x2 = 0.5*model->BJTtype*d_ib.d2_p2; -here->ib_y2 = 0.5*model->BJTtype*d_ib.d2_q2; -here->ib_xy = model->BJTtype*d_ib.d2_pq; -here->ib_x3 = d_ib.d3_p3/6.; -here->ib_y3 = d_ib.d3_q3/6.; -here->ib_x2y = 0.5*d_ib.d3_p2q; -here->ib_xy2 = 0.5*d_ib.d3_pq2; + here->ib_x = d_ib.d1_p; + here->ib_y = d_ib.d1_q; + here->ib_x2 = 0.5*model->BJTtype*d_ib.d2_p2; + here->ib_y2 = 0.5*model->BJTtype*d_ib.d2_q2; + here->ib_xy = model->BJTtype*d_ib.d2_pq; + here->ib_x3 = d_ib.d3_p3/6.; + here->ib_y3 = d_ib.d3_q3/6.; + here->ib_x2y = 0.5*d_ib.d3_p2q; + here->ib_xy2 = 0.5*d_ib.d3_pq2; -here->ibb_x = d_ibb.d1_p; -here->ibb_y = d_ibb.d1_q; -here->ibb_z = d_ibb.d1_r; -here->ibb_x2 = 0.5*model->BJTtype*d_ibb.d2_p2; -here->ibb_y2 = 0.5*model->BJTtype*d_ibb.d2_q2; -here->ibb_z2 = 0.5*model->BJTtype*d_ibb.d2_r2; -here->ibb_xy = model->BJTtype*d_ibb.d2_pq; -here->ibb_yz = model->BJTtype*d_ibb.d2_qr; -here->ibb_xz = model->BJTtype*d_ibb.d2_pr; -here->ibb_x3 = d_ibb.d3_p3/6.; -here->ibb_y3 = d_ibb.d3_q3/6.; -here->ibb_z3 = d_ibb.d3_r3/6.; -here->ibb_x2z = 0.5*d_ibb.d3_p2r; -here->ibb_x2y = 0.5*d_ibb.d3_p2q; -here->ibb_y2z = 0.5*d_ibb.d3_q2r; -here->ibb_xy2 = 0.5*d_ibb.d3_pq2; -here->ibb_xz2 = 0.5*d_ibb.d3_pr2; -here->ibb_yz2 = 0.5*d_ibb.d3_qr2; -here->ibb_xyz = d_ibb.d3_pqr; + here->ibb_x = d_ibb.d1_p; + here->ibb_y = d_ibb.d1_q; + here->ibb_z = d_ibb.d1_r; + here->ibb_x2 = 0.5*model->BJTtype*d_ibb.d2_p2; + here->ibb_y2 = 0.5*model->BJTtype*d_ibb.d2_q2; + here->ibb_z2 = 0.5*model->BJTtype*d_ibb.d2_r2; + here->ibb_xy = model->BJTtype*d_ibb.d2_pq; + here->ibb_yz = model->BJTtype*d_ibb.d2_qr; + here->ibb_xz = model->BJTtype*d_ibb.d2_pr; + here->ibb_x3 = d_ibb.d3_p3/6.; + here->ibb_y3 = d_ibb.d3_q3/6.; + here->ibb_z3 = d_ibb.d3_r3/6.; + here->ibb_x2z = 0.5*d_ibb.d3_p2r; + here->ibb_x2y = 0.5*d_ibb.d3_p2q; + here->ibb_y2z = 0.5*d_ibb.d3_q2r; + here->ibb_xy2 = 0.5*d_ibb.d3_pq2; + here->ibb_xz2 = 0.5*d_ibb.d3_pr2; + here->ibb_yz2 = 0.5*d_ibb.d3_qr2; + here->ibb_xyz = d_ibb.d3_pqr; -here->qbe_x = d_qbe.d1_p; -here->qbe_y = d_qbe.d1_q; -here->qbe_x2 = 0.5*model->BJTtype*d_qbe.d2_p2; -here->qbe_y2 = 0.5*model->BJTtype*d_qbe.d2_q2; -here->qbe_xy = model->BJTtype*d_qbe.d2_pq; -here->qbe_x3 = d_qbe.d3_p3/6.; -here->qbe_y3 = d_qbe.d3_q3/6.; -here->qbe_x2y = 0.5*d_qbe.d3_p2q; -here->qbe_xy2 = 0.5*d_qbe.d3_pq2; + here->qbe_x = d_qbe.d1_p; + here->qbe_y = d_qbe.d1_q; + here->qbe_x2 = 0.5*model->BJTtype*d_qbe.d2_p2; + here->qbe_y2 = 0.5*model->BJTtype*d_qbe.d2_q2; + here->qbe_xy = model->BJTtype*d_qbe.d2_pq; + here->qbe_x3 = d_qbe.d3_p3/6.; + here->qbe_y3 = d_qbe.d3_q3/6.; + here->qbe_x2y = 0.5*d_qbe.d3_p2q; + here->qbe_xy2 = 0.5*d_qbe.d3_pq2; -here->capbc1 = lcapbc1; -here->capbc2 = lcapbc2; -here->capbc3 = lcapbc3; + here->capbc1 = lcapbc1; + here->capbc2 = lcapbc2; + here->capbc3 = lcapbc3; -here->capbx1 = lcapbx1; -here->capbx2 = lcapbx2; -here->capbx3 = lcapbx3; + here->capbx1 = lcapbx1; + here->capbx2 = lcapbx2; + here->capbx3 = lcapbx3; -here->capsc1 = lcapsc1; -here->capsc2 = lcapsc2; -here->capsc3 = lcapsc3; - } - } - return(OK); - } + here->capsc1 = lcapsc1; + here->capsc2 = lcapsc2; + here->capsc3 = lcapsc3; + } + } + return(OK); +} diff --git a/src/spicelib/devices/bjt/bjtdset.h b/src/spicelib/devices/bjt/bjtdset.h index b13f82662..d3b28685c 100644 --- a/src/spicelib/devices/bjt/bjtdset.h +++ b/src/spicelib/devices/bjt/bjtdset.h @@ -1,6 +1,6 @@ #ifndef __BJTDSET_H #define __BJTDSET_H -int BJTdSetup(BJTmodel *inModel, CKTcircuit *ckt); +int BJTdSetup(GENmodel *inModel, CKTcircuit *ckt); #endif diff --git a/src/spicelib/devices/bjt/bjtext.h b/src/spicelib/devices/bjt/bjtext.h index 8e48adc2e..fa0c77edd 100644 --- a/src/spicelib/devices/bjt/bjtext.h +++ b/src/spicelib/devices/bjt/bjtext.h @@ -1,9 +1,12 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AnalsFixes **********/ +#ifndef __BJTEXT_H +#define __BJTEXT_H + -#ifdef __STDC__ extern int BJTacLoad(GENmodel *,CKTcircuit*); extern int BJTask(CKTcircuit *,GENinstance*,int,IFvalue*,IFvalue*); extern int BJTconvTest(GENmodel*,CKTcircuit*); @@ -27,29 +30,7 @@ extern int BJTtemp(GENmodel*,CKTcircuit*); extern int BJTtrunc(GENmodel*,CKTcircuit*,double*); extern int BJTdisto(int,GENmodel*,CKTcircuit*); extern int BJTnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); -#else /* stdc */ -extern int BJTacLoad(); -extern int BJTask(); -extern int BJTconvTest(); -extern int BJTdelete(); -extern void BJTdestroy(); -extern int BJTgetic(); -extern int BJTload(); -extern int BJTmAsk(); -extern int BJTmDelete(); -extern int BJTmParam(); -extern int BJTparam(); -extern int BJTpzLoad(); -extern int BJTsAcLoad(); -extern int BJTsLoad(); -extern void BJTsPrint(); -extern int BJTsSetup(); -extern int BJTsUpdate(); -extern int BJTsetup(); -extern int BJTunsetup(); -extern int BJTtemp(); -extern int BJTtrunc(); -extern int BJTdisto(); -extern int BJTnoise(); -#endif /* stdc */ +extern int BJTdSetup(GENmodel*, register CKTcircuit*); + +#endif diff --git a/src/spicelib/devices/bjt/bjtgetic.c b/src/spicelib/devices/bjt/bjtgetic.c index 45d3cde95..4665a7cd9 100644 --- a/src/spicelib/devices/bjt/bjtgetic.c +++ b/src/spicelib/devices/bjt/bjtgetic.c @@ -21,12 +21,12 @@ Author: 1985 Thomas L. Quarles int BJTgetic(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { BJTmodel *model = (BJTmodel*)inModel; - register BJTinstance *here; + BJTinstance *here; /* * grab initial conditions out of rhs array. User specified, so use * external nodes to get values diff --git a/src/spicelib/devices/bjt/bjtitf.h b/src/spicelib/devices/bjt/bjtitf.h index f1e2c9181..2b96ae41c 100644 --- a/src/spicelib/devices/bjt/bjtitf.h +++ b/src/spicelib/devices/bjt/bjtitf.h @@ -1,99 +1,10 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_bjt - #ifndef DEV_BJT #define DEV_BJT -#include "bjtext.h" -extern IFparm BJTpTable[ ]; -extern IFparm BJTmPTable[ ]; -extern char *BJTnames[ ]; -extern int BJTpTSize; -extern int BJTmPTSize; -extern int BJTnSize; -extern int BJTiSize; -extern int BJTmSize; +extern SPICEdev *get_bjt_info(void); -SPICEdev BJTinfo = { - { "BJT", - "Bipolar Junction Transistor", - - &BJTnSize, - &BJTnSize, - BJTnames, - - &BJTpTSize, - BJTpTable, - - &BJTmPTSize, - BJTmPTable, - DEV_DEFAULT - }, - - BJTparam, - BJTmParam, - BJTload, - BJTsetup, - BJTunsetup, - BJTsetup, - BJTtemp, - BJTtrunc, - NULL, - BJTacLoad, - NULL, - BJTdestroy, -#ifdef DELETES - BJTmDelete, - BJTdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - BJTgetic, - BJTask, - BJTmAsk, -#ifdef AN_pz - BJTpzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ -#ifdef NEWCONV - BJTconvTest, -#else /* NEWCONV */ - NULL, -#endif /* NEWCONV */ - -#ifdef AN_sense2 - BJTsSetup, - BJTsLoad, - BJTsUpdate, - BJTsAcLoad, - BJTsPrint, -#else /* AN_sense2 */ - NULL, - NULL, - NULL, - NULL, - NULL, -#endif /* AN_sense2 */ - NULL, -#ifdef AN_disto - BJTdisto, -#else /* AN_disto */ - NULL, -#endif /* AN_disto */ -#ifdef AN_noise - BJTnoise, -#else /* AN_noise */ - NULL, -#endif /* AN_noise */ - - &BJTiSize, - &BJTmSize - -}; #endif -#endif diff --git a/src/spicelib/devices/bjt/bjtload.c b/src/spicelib/devices/bjt/bjtload.c index 3e8d4ef5a..8868fa7b4 100644 --- a/src/spicelib/devices/bjt/bjtload.c +++ b/src/spicelib/devices/bjt/bjtload.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* @@ -22,13 +23,13 @@ int BJTload(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* actually load the current resistance value into the * sparse matrix previously provided */ { - register BJTmodel *model = (BJTmodel*)inModel; - register BJTinstance *here; + BJTmodel *model = (BJTmodel*)inModel; + BJTinstance *here; double arg1; double arg2; double arg3; @@ -313,7 +314,7 @@ BJTload(inModel,ckt) cbhat= *(ckt->CKTstate0 + here->BJTcb)+ *(ckt->CKTstate0 + here->BJTgpi)*delvbe+ *(ckt->CKTstate0 + here->BJTgmu)* delvbc; -#ifndef NOBYPASS + /* * bypass if solution has not changed */ @@ -354,7 +355,7 @@ BJTload(inModel,ckt) geqbx = *(ckt->CKTstate0 + here->BJTgeqbx); goto load; } -#endif /*NOBYPASS*/ + /* * limit nonlinear branch voltages */ @@ -369,43 +370,65 @@ BJTload(inModel,ckt) * determine dc current and derivitives */ next1: vtn=vt*model->BJTemissionCoeffF; - if(vbe > -5*vtn){ + + if(vbe >= -3*vtn){ evbe=exp(vbe/vtn); - cbe=csat*(evbe-1)+ckt->CKTgmin*vbe; - gbe=csat*evbe/vtn+ckt->CKTgmin; - if (c2 == 0) { - cben=0; - gben=0; - } else { + cbe=csat*(evbe-1); + gbe=csat*evbe/vtn; + } else { + arg=3*vtn/(vbe*CONSTe); + arg = arg * arg * arg; + cbe = -csat*(1+arg); + gbe = csat*3*arg/vbe; + } + if (c2 == 0) { + cben=0; + gben=0; + } else { + if(vbe >= -3*vte){ evben=exp(vbe/vte); cben=c2*(evben-1); gben=c2*evben/vte; - } - } else { - gbe = -csat/vbe+ckt->CKTgmin; - cbe=gbe*vbe; - gben = -c2/vbe; - cben=gben*vbe; - } - vtn=vt*model->BJTemissionCoeffR; - if(vbc > -5*vtn) { - evbc=exp(vbc/vtn); - cbc=csat*(evbc-1)+ckt->CKTgmin*vbc; - gbc=csat*evbc/vtn+ckt->CKTgmin; - if (c4 == 0) { - cbcn=0; - gbcn=0; } else { + arg=3*vte/(vbe*CONSTe); + arg = arg * arg * arg; + cben = -c2*(1+arg); + gben = c2*3*arg/vbe; + } + } + gben+=ckt->CKTgmin; + cben+=ckt->CKTgmin*vbe; + + vtn=vt*model->BJTemissionCoeffR; + + if(vbc >= -3*vtn) { + evbc=exp(vbc/vtn); + cbc=csat*(evbc-1); + gbc=csat*evbc/vtn; + } else { + arg=3*vtn/(vbc*CONSTe); + arg = arg * arg * arg; + cbc = -csat*(1+arg); + gbc = csat*3*arg/vbc; + } + if (c4 == 0) { + cbcn=0; + gbcn=0; + } else { + if(vbc >= -3*vtc) { evbcn=exp(vbc/vtc); cbcn=c4*(evbcn-1); gbcn=c4*evbcn/vtc; + } else { + arg=3*vtc/(vbc*CONSTe); + arg = arg * arg * arg; + cbcn = -c4*(1+arg); + gbcn = c4*3*arg/vbc; } - } else { - gbc = -csat/vbc+ckt->CKTgmin; - cbc = gbc*vbc; - gbcn = -c4/vbc; - cbcn=gbcn*vbc; } + gbcn+=ckt->CKTgmin; + cbcn+=ckt->CKTgmin*vbc; + /* * determine base charge terms */ @@ -652,21 +675,6 @@ next1: vtn=vt*model->BJTemissionCoeffF; if (icheck == 1) { ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) here; -#ifndef NEWCONV - } else { - tol=ckt->CKTreltol*MAX(fabs(cchat),fabs(cc))+ckt->CKTabstol; - if (fabs(cchat-cc) > tol) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; - } else { - tol=ckt->CKTreltol*MAX(fabs(cbhat),fabs(cb))+ - ckt->CKTabstol; - if (fabs(cbhat-cb) > tol) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; - } - } -#endif /* NEWCONV */ } } diff --git a/src/spicelib/devices/bjt/bjtnoise.c b/src/spicelib/devices/bjt/bjtnoise.c index f9fe22301..60a11cd6b 100644 --- a/src/spicelib/devices/bjt/bjtnoise.c +++ b/src/spicelib/devices/bjt/bjtnoise.c @@ -7,7 +7,6 @@ Author: 1987 Gary W. Ng #include #include "bjtdefs.h" #include "cktdefs.h" -#include "fteconst.h" #include "iferrmsg.h" #include "noisedef.h" #include "suffix.h" @@ -31,12 +30,12 @@ BJTnoise (mode, operation, genmodel, ckt, data, OnDens) int mode; int operation; CKTcircuit *ckt; - register Ndata *data; + Ndata *data; double *OnDens; { BJTmodel *firstModel = (BJTmodel *) genmodel; - register BJTmodel *model; - register BJTinstance *inst; + BJTmodel *model; + BJTinstance *inst; char name[N_MXVLNTH]; double tempOnoise; double tempInoise; diff --git a/src/spicelib/devices/bjt/bjtparam.c b/src/spicelib/devices/bjt/bjtparam.c index 742a4e070..8922fca63 100644 --- a/src/spicelib/devices/bjt/bjtparam.c +++ b/src/spicelib/devices/bjt/bjtparam.c @@ -27,7 +27,7 @@ BJTparam(param,value,instPtr,select) GENinstance *instPtr; IFvalue *select; { - register BJTinstance *here = (BJTinstance*)instPtr; + BJTinstance *here = (BJTinstance*)instPtr; switch(param) { case BJT_AREA: diff --git a/src/spicelib/devices/bjt/bjtpzld.c b/src/spicelib/devices/bjt/bjtpzld.c index 736817b19..ed1110c06 100644 --- a/src/spicelib/devices/bjt/bjtpzld.c +++ b/src/spicelib/devices/bjt/bjtpzld.c @@ -17,12 +17,12 @@ Author: 1985 Thomas L. Quarles int BJTpzLoad(inModel,ckt,s) GENmodel *inModel; - register CKTcircuit *ckt; - register SPcomplex *s; + CKTcircuit *ckt; + SPcomplex *s; { - register BJTmodel *model = (BJTmodel*)inModel; - register BJTinstance *here; + BJTmodel *model = (BJTmodel*)inModel; + BJTinstance *here; double gcpr; double gepr; double gpi; diff --git a/src/spicelib/devices/bjt/bjtsacl.c b/src/spicelib/devices/bjt/bjtsacl.c index 0932e06d0..4968879e3 100644 --- a/src/spicelib/devices/bjt/bjtsacl.c +++ b/src/spicelib/devices/bjt/bjtsacl.c @@ -25,8 +25,8 @@ CKTcircuit *ckt; { - register BJTmodel *model = (BJTmodel*)inModel; - register BJTinstance *here; + BJTmodel *model = (BJTmodel*)inModel; + BJTinstance *here; double SaveState[25]; int error; int flag; diff --git a/src/spicelib/devices/bjt/bjtsetup.c b/src/spicelib/devices/bjt/bjtsetup.c index 061abf6f6..bce2a9da0 100644 --- a/src/spicelib/devices/bjt/bjtsetup.c +++ b/src/spicelib/devices/bjt/bjtsetup.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* @@ -22,7 +23,7 @@ Author: 1985 Thomas L. Quarles int BJTsetup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; CKTcircuit *ckt; int *states; @@ -31,8 +32,8 @@ BJTsetup(matrix,inModel,ckt,states) */ { - register BJTmodel *model = (BJTmodel*)inModel; - register BJTinstance *here; + BJTmodel *model = (BJTmodel*)inModel; + BJTinstance *here; int error; CKTnode *tmp; @@ -148,8 +149,12 @@ BJTsetup(matrix,inModel,ckt,states) /* loop through all the instances of the model */ for (here = model->BJTinstances; here != NULL ; here=here->BJTnextInstance) { - if (here->BJTowner != ARCHme) goto matrixpointers; + CKTnode *tmpNode; + IFuid tmpName; + if (here->BJTowner != ARCHme) + goto matrixpointers; + if(!here->BJTareaGiven) { here->BJTarea = 1; } @@ -166,6 +171,18 @@ matrixpointers: error = CKTmkVolt(ckt,&tmp,here->BJTname,"collector"); if(error) return(error); here->BJTcolPrimeNode = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; +/* fprintf(stderr, "Nodeset copied from %s\n", tmpName); + fprintf(stderr, " to %s\n", tmp->name); + fprintf(stderr, " value %g\n", + tmp->nodeset);*/ + } + } + } } if(model->BJTbaseResist == 0) { here->BJTbasePrimeNode = here->BJTbaseNode; @@ -173,6 +190,18 @@ matrixpointers: error = CKTmkVolt(ckt,&tmp,here->BJTname, "base"); if(error) return(error); here->BJTbasePrimeNode = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,2,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; +/* fprintf(stderr, "Nodeset copied from %s\n", tmpName); + fprintf(stderr, " to %s\n", tmp->name); + fprintf(stderr, " value %g\n", + tmp->nodeset);*/ + } + } + } } if(model->BJTemitterResist == 0) { here->BJTemitPrimeNode = here->BJTemitNode; @@ -180,6 +209,19 @@ matrixpointers: error = CKTmkVolt(ckt,&tmp,here->BJTname, "emitter"); if(error) return(error); here->BJTemitPrimeNode = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; +/* fprintf(stderr, "Nodeset copied from %s\n", tmpName); + fprintf(stderr, " to %s\n", tmp->name); + fprintf(stderr, " value %g\n", + tmp->nodeset);*/ + } + } + } + } /* macro to make elements with built in test for out of memory */ @@ -220,7 +262,6 @@ BJTunsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM BJTmodel *model; BJTinstance *here; @@ -250,6 +291,5 @@ BJTunsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/bjt/bjtsload.c b/src/spicelib/devices/bjt/bjtsload.c index c3a07ff05..8359b913d 100644 --- a/src/spicelib/devices/bjt/bjtsload.c +++ b/src/spicelib/devices/bjt/bjtsload.c @@ -23,8 +23,8 @@ BJTsLoad(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { - register BJTmodel *model = (BJTmodel*)inModel; - register BJTinstance *here; + BJTmodel *model = (BJTmodel*)inModel; + BJTinstance *here; double SaveState0[27]; int i; int iparmno; diff --git a/src/spicelib/devices/bjt/bjtsprt.c b/src/spicelib/devices/bjt/bjtsprt.c index fc06c6a44..efdc0a252 100644 --- a/src/spicelib/devices/bjt/bjtsprt.c +++ b/src/spicelib/devices/bjt/bjtsprt.c @@ -21,11 +21,11 @@ Author: 1985 Thomas L. Quarles void BJTsPrint(inModel,ckt) -register CKTcircuit *ckt; +CKTcircuit *ckt; GENmodel *inModel; { - register BJTmodel *model = (BJTmodel*)inModel; - register BJTinstance *here; + BJTmodel *model = (BJTmodel*)inModel; + BJTinstance *here; printf("BJTS-----------------\n"); /* loop through all the BJT models */ diff --git a/src/spicelib/devices/bjt/bjtsset.c b/src/spicelib/devices/bjt/bjtsset.c index f02ac3497..954a819a4 100644 --- a/src/spicelib/devices/bjt/bjtsset.c +++ b/src/spicelib/devices/bjt/bjtsset.c @@ -20,11 +20,11 @@ Author: 1985 Thomas L. Quarles int BJTsSetup(info,inModel) - register SENstruct *info; + SENstruct *info; GENmodel *inModel; { - register BJTmodel *model = (BJTmodel*)inModel; - register BJTinstance *here; + BJTmodel *model = (BJTmodel*)inModel; + BJTinstance *here; #ifdef STEPDEBUG printf(" BJTsensetup \n"); diff --git a/src/spicelib/devices/bjt/bjtsupd.c b/src/spicelib/devices/bjt/bjtsupd.c index eb1cb344b..05a4d5141 100644 --- a/src/spicelib/devices/bjt/bjtsupd.c +++ b/src/spicelib/devices/bjt/bjtsupd.c @@ -19,10 +19,10 @@ Author: 1985 Thomas L. Quarles int BJTsUpdate(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register BJTmodel *model = (BJTmodel*)inModel; - register BJTinstance *here; + BJTmodel *model = (BJTmodel*)inModel; + BJTinstance *here; int iparmno; double sb; double sbprm; diff --git a/src/spicelib/devices/bjt/bjttemp.c b/src/spicelib/devices/bjt/bjttemp.c index 5a24553d5..1cb254df6 100644 --- a/src/spicelib/devices/bjt/bjttemp.c +++ b/src/spicelib/devices/bjt/bjttemp.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -23,8 +24,8 @@ BJTtemp(inModel,ckt) */ { - register BJTmodel *model = (BJTmodel *)inModel; - register BJTinstance *here; + BJTmodel *model = (BJTmodel *)inModel; + BJTinstance *here; double xfc; double vt; double ratlog; @@ -185,7 +186,8 @@ BJTtemp(inModel,ckt) here->BJTtf5 = here->BJTtBCpot * (1 - exp((1 - model->BJTjunctionExpBC) * xfc)) / (1 - model->BJTjunctionExpBC); - here->BJTtVcrit = vt * log(vt / (CONSTroot2*model->BJTsatCur)); + here->BJTtVcrit = vt * + log(vt / (CONSTroot2*here->BJTtSatCur*here->BJTarea)); } } diff --git a/src/spicelib/devices/bjt/bjttrunc.c b/src/spicelib/devices/bjt/bjttrunc.c index 443fbe84b..e27be8fae 100644 --- a/src/spicelib/devices/bjt/bjttrunc.c +++ b/src/spicelib/devices/bjt/bjttrunc.c @@ -21,12 +21,12 @@ Author: 1985 Thomas L. Quarles int BJTtrunc(inModel,ckt,timeStep) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; double *timeStep; { - register BJTmodel *model = (BJTmodel*)inModel; - register BJTinstance *here; + BJTmodel *model = (BJTmodel*)inModel; + BJTinstance *here; for( ; model != NULL; model = model->BJTnextModel) { for(here=model->BJTinstances;here!=NULL;here = here->BJTnextInstance){ diff --git a/src/spicelib/devices/bsim1/Makefile.am b/src/spicelib/devices/bsim1/Makefile.am index 6c1a35940..70ad8239a 100644 --- a/src/spicelib/devices/bsim1/Makefile.am +++ b/src/spicelib/devices/bsim1/Makefile.am @@ -2,30 +2,32 @@ pkglib_LTLIBRARIES = libbsim1.la -libbsim1_la_SOURCES = \ - b1.c \ - b1acld.c \ - b1ask.c \ - b1cvtest.c \ - b1del.c \ - b1dest.c \ - b1disto.c \ - b1dset.c \ - b1eval.c \ - b1getic.c \ - b1ld.c \ - b1mask.c \ - b1mdel.c \ - b1moscap.c \ - b1mpar.c \ - b1par.c \ - b1pzld.c \ - b1set.c \ - b1temp.c \ - b1trunc.c \ - bsim1def.h \ - bsim1ext.h \ - bsim1itf.h +libbsim1_la_SOURCES = \ + b1.c \ + b1acld.c \ + b1ask.c \ + b1cvtest.c \ + b1del.c \ + b1dest.c \ + b1disto.c \ + b1dset.c \ + b1eval.c \ + b1getic.c \ + b1ld.c \ + b1mask.c \ + b1mdel.c \ + b1moscap.c \ + b1mpar.c \ + b1par.c \ + b1pzld.c \ + b1set.c \ + b1temp.c \ + b1trunc.c \ + bsim1def.h \ + bsim1ext.h \ + bsim1init.c \ + bsim1init.h \ + bsim1itf.h diff --git a/src/spicelib/devices/bsim1/b1acld.c b/src/spicelib/devices/bsim1/b1acld.c index 138b428c1..8ff2919ec 100644 --- a/src/spicelib/devices/bsim1/b1acld.c +++ b/src/spicelib/devices/bsim1/b1acld.c @@ -16,10 +16,10 @@ Author: 1985 Hong J. Park, Thomas L. Quarles int B1acLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register B1model *model = (B1model*)inModel; - register B1instance *here; + B1model *model = (B1model*)inModel; + B1instance *here; int xnrm; int xrev; double gdpr; diff --git a/src/spicelib/devices/bsim1/b1cvtest.c b/src/spicelib/devices/bsim1/b1cvtest.c index d46835c60..b6bfd5805 100644 --- a/src/spicelib/devices/bsim1/b1cvtest.c +++ b/src/spicelib/devices/bsim1/b1cvtest.c @@ -17,14 +17,14 @@ int B1convTest(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* actually load the current value into the * sparse matrix previously provided */ { - register B1model *model = (B1model*)inModel; - register B1instance *here; + B1model *model = (B1model*)inModel; + B1instance *here; double cbd; double cbhat; double cbs; diff --git a/src/spicelib/devices/bsim1/b1disto.c b/src/spicelib/devices/bsim1/b1disto.c index de55d1d04..6855800d7 100644 --- a/src/spicelib/devices/bsim1/b1disto.c +++ b/src/spicelib/devices/bsim1/b1disto.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1988 Jaijeet S Roychowdhury +Modified: AlansFixes **********/ #include "ngspice.h" @@ -14,7 +15,7 @@ Author: 1988 Jaijeet S Roychowdhury int B1disto(mode,genmodel,ckt) GENmodel *genmodel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int mode; /* assuming here that ckt->CKTomega has been initialised to @@ -40,10 +41,10 @@ B1disto(mode,genmodel,ckt) double r2h1m2y,i2h1m2y; double r2h1m2z, i2h1m2z; double temp, itemp; - register B1instance *here; + B1instance *here; if (mode == D_SETUP) - return(B1dSetup(model,ckt)); + return(B1dSetup((GENmodel *)model,ckt)); if ((mode == D_TWOF1) || (mode == D_THRF1) || (mode == D_F1PF2) || (mode == D_F1MF2) || diff --git a/src/spicelib/devices/bsim1/b1dset.c b/src/spicelib/devices/bsim1/b1dset.c index e6a410b40..9d664a0a2 100644 --- a/src/spicelib/devices/bsim1/b1dset.c +++ b/src/spicelib/devices/bsim1/b1dset.c @@ -18,11 +18,11 @@ int B1dSetup(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register B1model* model = (B1model*)inModel; - register B1instance *here; + B1model* model = (B1model*)inModel; + B1instance *here; double DrainSatCurrent; double EffectiveLength; double GateBulkOverlapCap; diff --git a/src/spicelib/devices/bsim1/b1eval.c b/src/spicelib/devices/bsim1/b1eval.c index b4779c07d..6caef6dd3 100644 --- a/src/spicelib/devices/bsim1/b1eval.c +++ b/src/spicelib/devices/bsim1/b1eval.c @@ -21,9 +21,9 @@ B1evaluate(vds,vbs,vgs,here,model,gmPointer,gdsPointer,gmbsPointer, cbgbPointer,cbdbPointer,cbsbPointer,cdgbPointer,cddbPointer, cdsbPointer,cdrainPointer,vonPointer,vdsatPointer,ckt) - register CKTcircuit *ckt; - register B1model *model; - register B1instance *here; + CKTcircuit *ckt; + B1model *model; + B1instance *here; double vds; double vbs; double vgs; diff --git a/src/spicelib/devices/bsim1/b1ld.c b/src/spicelib/devices/bsim1/b1ld.c index a1cccab01..05a8b38c6 100644 --- a/src/spicelib/devices/bsim1/b1ld.c +++ b/src/spicelib/devices/bsim1/b1ld.c @@ -17,14 +17,14 @@ int B1load(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* actually load the current value into the * sparse matrix previously provided */ { - register B1model *model = (B1model*)inModel; - register B1instance *here; + B1model *model = (B1model*)inModel; + B1instance *here; double DrainSatCurrent = 0.0; double EffectiveLength = 0.0; double GateBulkOverlapCap = 0.0; @@ -123,9 +123,7 @@ B1load(inModel,ckt) double vt0 = 0.0; double args[8]; int ByPass = 0; -#ifndef NOBYPASS double tempv = 0.0; -#endif /*NOBYPASS*/ int error = 0; @@ -280,7 +278,6 @@ B1load(inModel,ckt) *(ckt->CKTstate0 + here->B1gbd) * delvbd + *(ckt->CKTstate0 + here->B1gbs) * delvbs ; -#ifndef NOBYPASS /* now lets see if we can bypass (ugh) */ /* following should be one big if connected by && all over @@ -344,7 +341,6 @@ B1load(inModel,ckt) goto line850; } } -#endif /*NOBYPASS*/ von = model->B1type * here->B1von; if(*(ckt->CKTstate0 + here->B1vds) >=0) { @@ -495,21 +491,6 @@ B1load(inModel,ckt) if (Check == 1) { ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) here; -#ifndef NEWCONV - } else { - tol=ckt->CKTreltol*MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol; - if (fabs(cdhat-cd) >= tol) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; - } else { - tol=ckt->CKTreltol*MAX(fabs(cbhat),fabs(cbs+cbd))+ - ckt->CKTabstol; - if (fabs(cbhat-(cbs+cbd)) > tol) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; - } - } -#endif /* NEWCONV */ } } *(ckt->CKTstate0 + here->B1vbs) = vbs; diff --git a/src/spicelib/devices/bsim1/b1moscap.c b/src/spicelib/devices/bsim1/b1moscap.c index dd69fc20c..ad1d96b41 100644 --- a/src/spicelib/devices/bsim1/b1moscap.c +++ b/src/spicelib/devices/bsim1/b1moscap.c @@ -26,7 +26,7 @@ B1mosCap(ckt,vgd,vgs,vgb, gcbsbPointer,gcdgbPointer,gcddbPointer,gcdsbPointer, gcsgbPointer,gcsdbPointer,gcssbPointer,qGatePointer,qBulkPointer, qDrainPointer,qSourcePointer) - register CKTcircuit *ckt; + CKTcircuit *ckt; double vgd; double vgs; double vgb; diff --git a/src/spicelib/devices/bsim1/b1pzld.c b/src/spicelib/devices/bsim1/b1pzld.c index d1c47f8e3..3df57b7cd 100644 --- a/src/spicelib/devices/bsim1/b1pzld.c +++ b/src/spicelib/devices/bsim1/b1pzld.c @@ -17,11 +17,11 @@ Author: 1985 Thomas L. Quarles int B1pzLoad(inModel,ckt,s) GENmodel *inModel; - register CKTcircuit *ckt; - register SPcomplex *s; + CKTcircuit *ckt; + SPcomplex *s; { - register B1model *model = (B1model*)inModel; - register B1instance *here; + B1model *model = (B1model*)inModel; + B1instance *here; int xnrm; int xrev; double gdpr; diff --git a/src/spicelib/devices/bsim1/b1set.c b/src/spicelib/devices/bsim1/b1set.c index 4e4cc6210..2a697fbd8 100644 --- a/src/spicelib/devices/bsim1/b1set.c +++ b/src/spicelib/devices/bsim1/b1set.c @@ -14,17 +14,17 @@ Author: 1985 Hong J. Park, Thomas L. Quarles int B1setup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; - register GENmodel *inModel; - register CKTcircuit *ckt; + SMPmatrix *matrix; + GENmodel *inModel; + CKTcircuit *ckt; int *states; /* load the B1 device structure with those pointers needed later * for fast matrix loading */ { - register B1model *model = (B1model*)inModel; - register B1instance *here; + B1model *model = (B1model*)inModel; + B1instance *here; int error; CKTnode *tmp; @@ -271,6 +271,9 @@ B1setup(matrix,inModel,ckt,states) for (here = model->B1instances; here != NULL ; here=here->B1nextInstance) { + CKTnode *tmpNode; + IFuid tmpName; + if (here->B1owner == ARCHme) { /* allocate a chunk of the state vector */ here->B1states = *states; @@ -325,6 +328,14 @@ B1setup(matrix,inModel,ckt,states) error = CKTmkVolt(ckt,&tmp,here->B1name,"drain"); if(error) return(error); here->B1dNodePrime = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } } else { here->B1dNodePrime = here->B1dNode; } @@ -337,6 +348,14 @@ B1setup(matrix,inModel,ckt,states) error = CKTmkVolt(ckt,&tmp,here->B1name,"source"); if(error) return(error); here->B1sNodePrime = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } } } else { here->B1sNodePrime = here->B1sNode; @@ -383,7 +402,6 @@ B1unsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM B1model *model; B1instance *here; @@ -407,6 +425,5 @@ B1unsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/bsim1/b1temp.c b/src/spicelib/devices/bsim1/b1temp.c index 1d3d74be2..a399e0da8 100644 --- a/src/spicelib/devices/bsim1/b1temp.c +++ b/src/spicelib/devices/bsim1/b1temp.c @@ -22,8 +22,8 @@ B1temp(inModel,ckt) */ { - register B1model *model = (B1model*) inModel; - register B1instance *here; + B1model *model = (B1model*) inModel; + B1instance *here; double EffChanLength; double EffChanWidth; double Cox; diff --git a/src/spicelib/devices/bsim1/b1trunc.c b/src/spicelib/devices/bsim1/b1trunc.c index f67b63701..240005a32 100644 --- a/src/spicelib/devices/bsim1/b1trunc.c +++ b/src/spicelib/devices/bsim1/b1trunc.c @@ -13,12 +13,12 @@ Author: 1985 Hong J. Park, Thomas L. Quarles int B1trunc(inModel,ckt,timeStep) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; double *timeStep; { - register B1model *model = (B1model*)inModel; - register B1instance *here; + B1model *model = (B1model*)inModel; + B1instance *here; #ifdef STEPDEBUG double debugtemp; #endif /* STEPDEBUG */ diff --git a/src/spicelib/devices/bsim1/bsim1ext.h b/src/spicelib/devices/bsim1/bsim1ext.h index 97a13b41c..96f6b43b7 100644 --- a/src/spicelib/devices/bsim1/bsim1ext.h +++ b/src/spicelib/devices/bsim1/bsim1ext.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Hong June Park, Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #ifdef __STDC__ @@ -26,6 +27,7 @@ extern int B1unsetup(GENmodel*,CKTcircuit*); extern int B1temp(GENmodel*,CKTcircuit*); extern int B1trunc(GENmodel*,CKTcircuit*,double*); extern int B1disto(int,GENmodel*,CKTcircuit*); +extern int B1dSetup(GENmodel*, register CKTcircuit*); #else /* stdc */ extern int B1acLoad(); extern int B1ask(); diff --git a/src/spicelib/devices/bsim1/bsim1itf.h b/src/spicelib/devices/bsim1/bsim1itf.h index 8f9bed9f9..9964a7c2a 100644 --- a/src/spicelib/devices/bsim1/bsim1itf.h +++ b/src/spicelib/devices/bsim1/bsim1itf.h @@ -1,86 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_bsim1 - #ifndef DEV_BSIM1 #define DEV_BSIM1 -#include "bsim1ext.h" -extern IFparm B1pTable[ ]; -extern IFparm B1mPTable[ ]; -extern char *B1names[ ]; -extern int B1pTSize; -extern int B1mPTSize; -extern int B1nSize; -extern int B1iSize; -extern int B1mSize; - -SPICEdev B1info = { - { "BSIM1", - "Berkeley Short Channel IGFET Model", - - &B1nSize, - &B1nSize, - B1names, - - &B1pTSize, - B1pTable, - - &B1mPTSize, - B1mPTable, - DEV_DEFAULT - }, - - B1param, - B1mParam, - B1load, - B1setup, - B1unsetup, - B1setup, - B1temp, - B1trunc, - NULL, - B1acLoad, - NULL, - B1destroy, -#ifdef DELETES - B1mDelete, - B1delete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - B1getic, - B1ask, - B1mAsk, -#ifdef AN_pz - B1pzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ -#ifdef NEWCONV - B1convTest, -#else /* NEWCONV */ - NULL, -#endif /* NEWCONV */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -#ifdef AN_disto - B1disto, -#else - NULL, -#endif - NULL, /* NOISE */ - - &B1iSize, - &B1mSize - -}; +SPICEdev *get_bsim1_info(void); #endif -#endif diff --git a/src/spicelib/devices/bsim2/Makefile.am b/src/spicelib/devices/bsim2/Makefile.am index c1c39d0d1..e30a04bf4 100644 --- a/src/spicelib/devices/bsim2/Makefile.am +++ b/src/spicelib/devices/bsim2/Makefile.am @@ -2,28 +2,30 @@ pkglib_LTLIBRARIES = libbsim2.la -libbsim2_la_SOURCES = \ - b2.c \ - b2acld.c \ - b2ask.c \ - b2cvtest.c \ - b2del.c \ - b2dest.c \ - b2eval.c \ - b2getic.c \ - b2ld.c \ - b2mask.c \ - b2mdel.c \ - b2moscap.c \ - b2mpar.c \ - b2par.c \ - b2pzld.c \ - b2set.c \ - b2temp.c \ - b2trunc.c \ - bsim2def.h \ - bsim2ext.h \ - bsim2itf.h +libbsim2_la_SOURCES = \ + b2.c \ + b2acld.c \ + b2ask.c \ + b2cvtest.c \ + b2del.c \ + b2dest.c \ + b2eval.c \ + b2getic.c \ + b2ld.c \ + b2mask.c \ + b2mdel.c \ + b2moscap.c \ + b2mpar.c \ + b2par.c \ + b2pzld.c \ + b2set.c \ + b2temp.c \ + b2trunc.c \ + bsim2def.h \ + bsim2ext.h \ + bsim2init.c \ + bsim2init.h \ + bsim2itf.h diff --git a/src/spicelib/devices/bsim2/b2acld.c b/src/spicelib/devices/bsim2/b2acld.c index 5ba9bc679..854810134 100644 --- a/src/spicelib/devices/bsim2/b2acld.c +++ b/src/spicelib/devices/bsim2/b2acld.c @@ -16,10 +16,10 @@ Author: 1985 Hong J. Park, Thomas L. Quarles int B2acLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register B2model *model = (B2model*)inModel; - register B2instance *here; + B2model *model = (B2model*)inModel; + B2instance *here; int xnrm; int xrev; double gdpr; diff --git a/src/spicelib/devices/bsim2/b2cvtest.c b/src/spicelib/devices/bsim2/b2cvtest.c index 81c561b7e..87a7e1959 100644 --- a/src/spicelib/devices/bsim2/b2cvtest.c +++ b/src/spicelib/devices/bsim2/b2cvtest.c @@ -17,14 +17,14 @@ int B2convTest(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* actually load the current value into the * sparse matrix previously provided */ { - register B2model *model = (B2model*)inModel; - register B2instance *here; + B2model *model = (B2model*)inModel; + B2instance *here; double cbd; double cbhat; double cbs; diff --git a/src/spicelib/devices/bsim2/b2eval.c b/src/spicelib/devices/bsim2/b2eval.c index 5b8963896..9b34e144e 100644 --- a/src/spicelib/devices/bsim2/b2eval.c +++ b/src/spicelib/devices/bsim2/b2eval.c @@ -19,9 +19,9 @@ void B2evaluate(Vds,Vbs,Vgs,here,model,gm,gds,gmb,qg,qb,qd,cgg,cgd,cgs, cbg,cbd,cbs,cdg,cdd,cds,Ids,von,vdsat,ckt) - register CKTcircuit *ckt; - register B2model *model; - register B2instance *here; + CKTcircuit *ckt; + B2model *model; + B2instance *here; double Vds,Vbs,Vgs; double *gm,*gds,*gmb,*qg,*qb,*qd,*cgg,*cgd,*cgs,*cbg; double *cbd,*cbs,*cdg,*cdd,*cds,*Ids,*von,*vdsat; diff --git a/src/spicelib/devices/bsim2/b2ld.c b/src/spicelib/devices/bsim2/b2ld.c index ed6f3c885..ad5f2888c 100644 --- a/src/spicelib/devices/bsim2/b2ld.c +++ b/src/spicelib/devices/bsim2/b2ld.c @@ -17,14 +17,14 @@ int B2load(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* actually load the current value into the * sparse matrix previously provided */ { - register B2model *model = (B2model*)inModel; - register B2instance *here; + B2model *model = (B2model*)inModel; + B2instance *here; double DrainSatCurrent; double EffectiveLength; double GateBulkOverlapCap; @@ -123,9 +123,7 @@ B2load(inModel,ckt) double vt0; double args[7]; int ByPass; -#ifndef NOBYPASS double tempv; -#endif /*NOBYPASS*/ int error; @@ -280,7 +278,6 @@ B2load(inModel,ckt) *(ckt->CKTstate0 + here->B2gbd) * delvbd + *(ckt->CKTstate0 + here->B2gbs) * delvbs ; -#ifndef NOBYPASS /* now lets see if we can bypass (ugh) */ /* following should be one big if connected by && all over @@ -344,7 +341,6 @@ B2load(inModel,ckt) goto line850; } } -#endif /*NOBYPASS*/ von = model->B2type * here->B2von; if(*(ckt->CKTstate0 + here->B2vds) >=0) { @@ -496,21 +492,6 @@ B2load(inModel,ckt) if (Check == 1) { ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) here; -#ifndef NEWCONV - } else { - tol=ckt->CKTreltol*MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol; - if (fabs(cdhat-cd) >= tol) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; - } else { - tol=ckt->CKTreltol*MAX(fabs(cbhat),fabs(cbs+cbd))+ - ckt->CKTabstol; - if (fabs(cbhat-(cbs+cbd)) > tol) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; - } - } -#endif /* NEWCONV */ } } *(ckt->CKTstate0 + here->B2vbs) = vbs; diff --git a/src/spicelib/devices/bsim2/b2moscap.c b/src/spicelib/devices/bsim2/b2moscap.c index 0071bbfb0..5d84424d5 100644 --- a/src/spicelib/devices/bsim2/b2moscap.c +++ b/src/spicelib/devices/bsim2/b2moscap.c @@ -26,7 +26,7 @@ B2mosCap(ckt,vgd,vgs,vgb, gcbsbPointer,gcdgbPointer,gcddbPointer,gcdsbPointer, gcsgbPointer,gcsdbPointer,gcssbPointer,qGatePointer,qBulkPointer, qDrainPointer,qSourcePointer) - register CKTcircuit *ckt; + CKTcircuit *ckt; double vgd; double vgs; double vgb; diff --git a/src/spicelib/devices/bsim2/b2pzld.c b/src/spicelib/devices/bsim2/b2pzld.c index aa4bb91ce..d9f4bbfb9 100644 --- a/src/spicelib/devices/bsim2/b2pzld.c +++ b/src/spicelib/devices/bsim2/b2pzld.c @@ -17,11 +17,11 @@ Author: 1985 Thomas L. Quarles int B2pzLoad(inModel,ckt,s) GENmodel *inModel; - register CKTcircuit *ckt; - register SPcomplex *s; + CKTcircuit *ckt; + SPcomplex *s; { - register B2model *model = (B2model*)inModel; - register B2instance *here; + B2model *model = (B2model*)inModel; + B2instance *here; int xnrm; int xrev; double gdpr; diff --git a/src/spicelib/devices/bsim2/b2set.c b/src/spicelib/devices/bsim2/b2set.c index 6722afcb4..e54dadd33 100644 --- a/src/spicelib/devices/bsim2/b2set.c +++ b/src/spicelib/devices/bsim2/b2set.c @@ -14,17 +14,17 @@ Author: 1988 Min-Chie Jeng, Hong J. Park, Thomas L. Quarles int B2setup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; - register GENmodel *inModel; - register CKTcircuit *ckt; + SMPmatrix *matrix; + GENmodel *inModel; + CKTcircuit *ckt; int *states; /* load the B2 device structure with those pointers needed later * for fast matrix loading */ { - register B2model *model = (B2model*)inModel; - register B2instance *here; + B2model *model = (B2model*)inModel; + B2instance *here; int error; CKTnode *tmp; @@ -492,8 +492,19 @@ B2setup(matrix,inModel,ckt,states) (here->B2drainSquares != 0.0 ) && (here->B2dNodePrime == 0) ) { error = CKTmkVolt(ckt,&tmp,here->B2name,"drain"); - if(error) return(error); + if(error) return(error); here->B2dNodePrime = tmp->number; + if (ckt->CKTcopyNodesets) { + CKTnode *tmpNode; + IFuid tmpName; + + if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } } else { here->B2dNodePrime = here->B2dNode; } @@ -504,8 +515,20 @@ B2setup(matrix,inModel,ckt,states) (here->B2sNodePrime == 0) ) { if(here->B2sNodePrime == 0) { error = CKTmkVolt(ckt,&tmp,here->B2name,"source"); - if(error) return(error); + if(error) + return(error); here->B2sNodePrime = tmp->number; + if (ckt->CKTcopyNodesets) { + CKTnode *tmpNode; + IFuid tmpName; + + if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } } } else { here->B2sNodePrime = here->B2sNode; @@ -553,7 +576,6 @@ B2unsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM B2model *model; B2instance *here; @@ -577,6 +599,5 @@ B2unsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/bsim2/b2temp.c b/src/spicelib/devices/bsim2/b2temp.c index 6a20742e2..48ce48308 100644 --- a/src/spicelib/devices/bsim2/b2temp.c +++ b/src/spicelib/devices/bsim2/b2temp.c @@ -22,9 +22,9 @@ B2temp(inModel,ckt) */ { - register B2model *model = (B2model*) inModel; - register B2instance *here; - register struct bsim2SizeDependParam *pSizeDependParamKnot, *pLastKnot; + B2model *model = (B2model*) inModel; + B2instance *here; + struct bsim2SizeDependParam *pSizeDependParamKnot, *pLastKnot; double EffectiveLength; double EffectiveWidth; double CoxWoverL, Inv_L, Inv_W, tmp; @@ -71,7 +71,7 @@ B2temp(inModel,ckt) } if (Size_Not_Found) - { here->pParam = (struct bsim2SizeDependParam *)malloc( + { here->pParam = (struct bsim2SizeDependParam *)tmalloc( sizeof(struct bsim2SizeDependParam)); if (pLastKnot == NULL) model->pSizeDependParamKnot = here->pParam; diff --git a/src/spicelib/devices/bsim2/b2trunc.c b/src/spicelib/devices/bsim2/b2trunc.c index e61d4b8cc..11d2f9d19 100644 --- a/src/spicelib/devices/bsim2/b2trunc.c +++ b/src/spicelib/devices/bsim2/b2trunc.c @@ -13,12 +13,12 @@ Author: 1985 Hong J. Park, Thomas L. Quarles int B2trunc(inModel,ckt,timeStep) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; double *timeStep; { - register B2model *model = (B2model*)inModel; - register B2instance *here; + B2model *model = (B2model*)inModel; + B2instance *here; #ifdef STEPDEBUG double debugtemp; #endif /* STEPDEBUG */ diff --git a/src/spicelib/devices/bsim2/bsim2itf.h b/src/spicelib/devices/bsim2/bsim2itf.h index 593233a9f..2f77f903a 100644 --- a/src/spicelib/devices/bsim2/bsim2itf.h +++ b/src/spicelib/devices/bsim2/bsim2itf.h @@ -1,83 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_bsim2 - #ifndef DEV_BSIM2 #define DEV_BSIM2 -#include "bsim2ext.h" - -extern IFparm B2pTable[ ]; -extern IFparm B2mPTable[ ]; -extern char *B2names[ ]; -extern int B2pTSize; -extern int B2mPTSize; -extern int B2nSize; -extern int B2iSize; -extern int B2mSize; - -SPICEdev B2info = { - { "BSIM2", - "Berkeley Short Channel IGFET Model", - - &B2nSize, - &B2nSize, - B2names, - - &B2pTSize, - B2pTable, - - &B2mPTSize, - B2mPTable, - DEV_DEFAULT - }, - - B2param, - B2mParam, - B2load, - B2setup, - B2unsetup, - B2setup, - B2temp, - B2trunc, - NULL, - B2acLoad, - NULL, - B2destroy, -#ifdef DELETES - B2mDelete, - B2delete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - B2getic, - B2ask, - B2mAsk, -#ifdef AN_pz - B2pzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ -#ifdef NEWCONV - B2convTest, -#else /* NEWCONV */ - NULL, -#endif /* NEWCONV */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - - &B2iSize, - &B2mSize - -}; +SPICEdev *get_bsim2_info(void); #endif -#endif diff --git a/src/spicelib/devices/bsim3/Makefile.am b/src/spicelib/devices/bsim3/Makefile.am index 0e9484e83..fa3ed4ec1 100644 --- a/src/spicelib/devices/bsim3/Makefile.am +++ b/src/spicelib/devices/bsim3/Makefile.am @@ -2,28 +2,30 @@ pkglib_LTLIBRARIES = libbsim3.la -libbsim3_la_SOURCES = \ - b3.c \ - b3acld.c \ - b3ask.c \ - b3check.c \ - b3cvtest.c \ - b3del.c \ - b3dest.c \ - b3getic.c \ - b3ld.c \ - b3mask.c \ - b3mdel.c \ - b3mpar.c \ - b3noi.c \ - b3par.c \ - b3pzld.c \ - b3set.c \ - b3temp.c \ - b3trunc.c \ - bsim3def.h \ - bsim3ext.h \ - bsim3itf.h +libbsim3_la_SOURCES = \ + b3.c \ + b3acld.c \ + b3ask.c \ + b3check.c \ + b3cvtest.c \ + b3del.c \ + b3dest.c \ + b3getic.c \ + b3ld.c \ + b3mask.c \ + b3mdel.c \ + b3mpar.c \ + b3noi.c \ + b3par.c \ + b3pzld.c \ + b3set.c \ + b3temp.c \ + b3trunc.c \ + bsim3def.h \ + bsim3ext.h \ + bsim3init.c \ + bsim3init.h \ + bsim3itf.h diff --git a/src/spicelib/devices/bsim3/b3.c b/src/spicelib/devices/bsim3/b3.c index cf363d432..4d78e07e6 100644 --- a/src/spicelib/devices/bsim3/b3.c +++ b/src/spicelib/devices/bsim3/b3.c @@ -1,27 +1,8 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. Author: 1997-1999 Weidong Liu. +Modified: 2000 AlansFixes File: b3.c **********/ @@ -34,6 +15,7 @@ File: b3.c IFparm BSIM3pTable[] = { /* parameters */ IOP( "l", BSIM3_L, IF_REAL , "Length"), IOP( "w", BSIM3_W, IF_REAL , "Width"), +IOP( "m", BSIM3_M, IF_REAL , "Parallel multiplier"), IOP( "ad", BSIM3_AD, IF_REAL , "Drain area"), IOP( "as", BSIM3_AS, IF_REAL , "Source area"), IOP( "pd", BSIM3_PD, IF_REAL , "Drain perimeter"), diff --git a/src/spicelib/devices/bsim3/b3acld.c b/src/spicelib/devices/bsim3/b3acld.c index c9ea1c300..480ee12ee 100644 --- a/src/spicelib/devices/bsim3/b3acld.c +++ b/src/spicelib/devices/bsim3/b3acld.c @@ -1,30 +1,8 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.2 1999/08/23 18:14:39 manu - Added cleanup patch by Arno Peters - also added 'make check' to configure - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. Author: 1997-1999 Weidong Liu. +Modified: 2000 AlansFixes File: b3acld.c **********/ @@ -37,322 +15,317 @@ File: b3acld.c int -BSIM3acLoad(inModel,ckt) -GENmodel *inModel; -register CKTcircuit *ckt; +BSIM3acLoad(GENmodel *inModel, CKTcircuit *ckt) { -register BSIM3model *model = (BSIM3model*)inModel; -register BSIM3instance *here; -double xcggb, xcgdb, xcgsb, xcbgb, xcbdb, xcbsb, xcddb, xcssb, xcdgb; -double gdpr, gspr, gds, gbd, gbs, capbd, capbs, xcsgb, xcdsb, xcsdb; -double cggb, cgdb, cgsb, cbgb, cbdb, cbsb, cddb, cdgb, cdsb, omega; -double GSoverlapCap, GDoverlapCap, GBoverlapCap, FwdSum, RevSum, Gm, Gmbs; -double dxpart, sxpart, xgtg, xgtd, xgts, xgtb, xcqgb, xcqdb, xcqsb, xcqbb; -double gbspsp, gbbdp, gbbsp, gbspg, gbspb; -double gbspdp, gbdpdp, gbdpg, gbdpb, gbdpsp; -double ddxpart_dVd, ddxpart_dVg, ddxpart_dVb, ddxpart_dVs; -double dsxpart_dVd, dsxpart_dVg, dsxpart_dVb, dsxpart_dVs; -double T1, CoxWL, qcheq, Cdg, Cdd, Cds, Csg, Csd, Css; -double ScalingFactor = 1.0e-9; - + BSIM3model *model = (BSIM3model*)inModel; + BSIM3instance *here; + double xcggb, xcgdb, xcgsb, xcbgb, xcbdb, xcbsb, xcddb, xcssb, xcdgb; + double gdpr, gspr, gds, gbd, gbs, capbd, capbs, xcsgb, xcdsb, xcsdb; + double cggb, cgdb, cgsb, cbgb, cbdb, cbsb, cddb, cdgb, cdsb, omega; + double GSoverlapCap, GDoverlapCap, GBoverlapCap, FwdSum, RevSum, Gm, Gmbs; + double dxpart, sxpart, xgtg, xgtd, xgts, xgtb, xcqgb, xcqdb, xcqsb, xcqbb; + double gbspsp, gbbdp, gbbsp, gbspg, gbspb; + double gbspdp, gbdpdp, gbdpg, gbdpb, gbdpsp; + double ddxpart_dVd, ddxpart_dVg, ddxpart_dVb, ddxpart_dVs; + double dsxpart_dVd, dsxpart_dVg, dsxpart_dVb, dsxpart_dVs; + double T1, CoxWL, qcheq, Cdg, Cdd, Cds, Csg, Csd, Css; + double ScalingFactor = 1.0e-9; + double m; + omega = ckt->CKTomega; - for (; model != NULL; model = model->BSIM3nextModel) - { for (here = model->BSIM3instances; here!= NULL; - here = here->BSIM3nextInstance) { - if (here->BSIM3owner != ARCHme) continue; - if (here->BSIM3mode >= 0) - { Gm = here->BSIM3gm; - Gmbs = here->BSIM3gmbs; - FwdSum = Gm + Gmbs; - RevSum = 0.0; + for (; model != NULL; model = model->BSIM3nextModel) { + for (here = model->BSIM3instances; here!= NULL; + here = here->BSIM3nextInstance) { + if (here->BSIM3owner != ARCHme) + continue; + if (here->BSIM3mode >= 0) { + Gm = here->BSIM3gm; + Gmbs = here->BSIM3gmbs; + FwdSum = Gm + Gmbs; + RevSum = 0.0; - gbbdp = -here->BSIM3gbds; - gbbsp = here->BSIM3gbds + here->BSIM3gbgs + here->BSIM3gbbs; + gbbdp = -here->BSIM3gbds; + gbbsp = here->BSIM3gbds + here->BSIM3gbgs + here->BSIM3gbbs; - gbdpg = here->BSIM3gbgs; - gbdpb = here->BSIM3gbbs; - gbdpdp = here->BSIM3gbds; - gbdpsp = -(gbdpg + gbdpb + gbdpdp); + gbdpg = here->BSIM3gbgs; + gbdpb = here->BSIM3gbbs; + gbdpdp = here->BSIM3gbds; + gbdpsp = -(gbdpg + gbdpb + gbdpdp); + + gbspdp = 0.0; + gbspg = 0.0; + gbspb = 0.0; + gbspsp = 0.0; - gbspdp = 0.0; - gbspg = 0.0; - gbspb = 0.0; - gbspsp = 0.0; + if (here->BSIM3nqsMod == 0) { + cggb = here->BSIM3cggb; + cgsb = here->BSIM3cgsb; + cgdb = here->BSIM3cgdb; - if (here->BSIM3nqsMod == 0) - { cggb = here->BSIM3cggb; - cgsb = here->BSIM3cgsb; - cgdb = here->BSIM3cgdb; + cbgb = here->BSIM3cbgb; + cbsb = here->BSIM3cbsb; + cbdb = here->BSIM3cbdb; - cbgb = here->BSIM3cbgb; - cbsb = here->BSIM3cbsb; - cbdb = here->BSIM3cbdb; + cdgb = here->BSIM3cdgb; + cdsb = here->BSIM3cdsb; + cddb = here->BSIM3cddb; - cdgb = here->BSIM3cdgb; - cdsb = here->BSIM3cdsb; - cddb = here->BSIM3cddb; + xgtg = xgtd = xgts = xgtb = 0.0; + sxpart = 0.6; + dxpart = 0.4; + ddxpart_dVd = ddxpart_dVg = ddxpart_dVb + = ddxpart_dVs = 0.0; + dsxpart_dVd = dsxpart_dVg = dsxpart_dVb + = dsxpart_dVs = 0.0; + } else { + cggb = cgdb = cgsb = 0.0; + cbgb = cbdb = cbsb = 0.0; + cdgb = cddb = cdsb = 0.0; - xgtg = xgtd = xgts = xgtb = 0.0; - sxpart = 0.6; - dxpart = 0.4; - ddxpart_dVd = ddxpart_dVg = ddxpart_dVb - = ddxpart_dVs = 0.0; - dsxpart_dVd = dsxpart_dVg = dsxpart_dVb - = dsxpart_dVs = 0.0; - } - else - { cggb = cgdb = cgsb = 0.0; - cbgb = cbdb = cbsb = 0.0; - cdgb = cddb = cdsb = 0.0; - - xgtg = here->BSIM3gtg; - xgtd = here->BSIM3gtd; - xgts = here->BSIM3gts; - xgtb = here->BSIM3gtb; + xgtg = here->BSIM3gtg; + xgtd = here->BSIM3gtd; + xgts = here->BSIM3gts; + xgtb = here->BSIM3gtb; - xcqgb = here->BSIM3cqgb * omega; - xcqdb = here->BSIM3cqdb * omega; - xcqsb = here->BSIM3cqsb * omega; - xcqbb = here->BSIM3cqbb * omega; + xcqgb = here->BSIM3cqgb * omega; + xcqdb = here->BSIM3cqdb * omega; + xcqsb = here->BSIM3cqsb * omega; + xcqbb = here->BSIM3cqbb * omega; - CoxWL = model->BSIM3cox * here->pParam->BSIM3weffCV - * here->pParam->BSIM3leffCV; - qcheq = -(here->BSIM3qgate + here->BSIM3qbulk); - if (fabs(qcheq) <= 1.0e-5 * CoxWL) - { if (model->BSIM3xpart < 0.5) - { dxpart = 0.4; - } - else if (model->BSIM3xpart > 0.5) - { dxpart = 0.0; - } - else - { dxpart = 0.5; - } - ddxpart_dVd = ddxpart_dVg = ddxpart_dVb - = ddxpart_dVs = 0.0; - } - else - { dxpart = here->BSIM3qdrn / qcheq; - Cdd = here->BSIM3cddb; - Csd = -(here->BSIM3cgdb + here->BSIM3cddb - + here->BSIM3cbdb); - ddxpart_dVd = (Cdd - dxpart * (Cdd + Csd)) / qcheq; - Cdg = here->BSIM3cdgb; - Csg = -(here->BSIM3cggb + here->BSIM3cdgb - + here->BSIM3cbgb); - ddxpart_dVg = (Cdg - dxpart * (Cdg + Csg)) / qcheq; + CoxWL = model->BSIM3cox * here->pParam->BSIM3weffCV + * here->pParam->BSIM3leffCV; + qcheq = -(here->BSIM3qgate + here->BSIM3qbulk); + if (fabs(qcheq) <= 1.0e-5 * CoxWL) { + if (model->BSIM3xpart < 0.5) { + dxpart = 0.4; + } + else if (model->BSIM3xpart > 0.5) { + dxpart = 0.0; + } else { + dxpart = 0.5; + } + ddxpart_dVd = ddxpart_dVg = ddxpart_dVb + = ddxpart_dVs = 0.0; + } else { + dxpart = here->BSIM3qdrn / qcheq; + Cdd = here->BSIM3cddb; + Csd = -(here->BSIM3cgdb + here->BSIM3cddb + + here->BSIM3cbdb); + ddxpart_dVd = (Cdd - dxpart * (Cdd + Csd)) / qcheq; + Cdg = here->BSIM3cdgb; + Csg = -(here->BSIM3cggb + here->BSIM3cdgb + + here->BSIM3cbgb); + ddxpart_dVg = (Cdg - dxpart * (Cdg + Csg)) / qcheq; - Cds = here->BSIM3cdsb; - Css = -(here->BSIM3cgsb + here->BSIM3cdsb - + here->BSIM3cbsb); - ddxpart_dVs = (Cds - dxpart * (Cds + Css)) / qcheq; + Cds = here->BSIM3cdsb; + Css = -(here->BSIM3cgsb + here->BSIM3cdsb + + here->BSIM3cbsb); + ddxpart_dVs = (Cds - dxpart * (Cds + Css)) / qcheq; - ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg - + ddxpart_dVs); - } - sxpart = 1.0 - dxpart; - dsxpart_dVd = -ddxpart_dVd; - dsxpart_dVg = -ddxpart_dVg; - dsxpart_dVs = -ddxpart_dVs; - dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg + dsxpart_dVs); - } - } - else - { Gm = -here->BSIM3gm; - Gmbs = -here->BSIM3gmbs; - FwdSum = 0.0; - RevSum = -(Gm + Gmbs); + ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg + + ddxpart_dVs); + } + sxpart = 1.0 - dxpart; + dsxpart_dVd = -ddxpart_dVd; + dsxpart_dVg = -ddxpart_dVg; + dsxpart_dVs = -ddxpart_dVs; + dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg + dsxpart_dVs); + } + } else { + Gm = -here->BSIM3gm; + Gmbs = -here->BSIM3gmbs; + FwdSum = 0.0; + RevSum = -(Gm + Gmbs); - gbbsp = -here->BSIM3gbds; - gbbdp = here->BSIM3gbds + here->BSIM3gbgs + here->BSIM3gbbs; + gbbsp = -here->BSIM3gbds; + gbbdp = here->BSIM3gbds + here->BSIM3gbgs + here->BSIM3gbbs; - gbdpg = 0.0; - gbdpsp = 0.0; - gbdpb = 0.0; - gbdpdp = 0.0; + gbdpg = 0.0; + gbdpsp = 0.0; + gbdpb = 0.0; + gbdpdp = 0.0; - gbspg = here->BSIM3gbgs; - gbspsp = here->BSIM3gbds; - gbspb = here->BSIM3gbbs; - gbspdp = -(gbspg + gbspsp + gbspb); + gbspg = here->BSIM3gbgs; + gbspsp = here->BSIM3gbds; + gbspb = here->BSIM3gbbs; + gbspdp = -(gbspg + gbspsp + gbspb); - if (here->BSIM3nqsMod == 0) - { cggb = here->BSIM3cggb; - cgsb = here->BSIM3cgdb; - cgdb = here->BSIM3cgsb; + if (here->BSIM3nqsMod == 0) { + cggb = here->BSIM3cggb; + cgsb = here->BSIM3cgdb; + cgdb = here->BSIM3cgsb; - cbgb = here->BSIM3cbgb; - cbsb = here->BSIM3cbdb; - cbdb = here->BSIM3cbsb; + cbgb = here->BSIM3cbgb; + cbsb = here->BSIM3cbdb; + cbdb = here->BSIM3cbsb; - cdgb = -(here->BSIM3cdgb + cggb + cbgb); - cdsb = -(here->BSIM3cddb + cgsb + cbsb); - cddb = -(here->BSIM3cdsb + cgdb + cbdb); + cdgb = -(here->BSIM3cdgb + cggb + cbgb); + cdsb = -(here->BSIM3cddb + cgsb + cbsb); + cddb = -(here->BSIM3cdsb + cgdb + cbdb); - xgtg = xgtd = xgts = xgtb = 0.0; - sxpart = 0.4; - dxpart = 0.6; - ddxpart_dVd = ddxpart_dVg = ddxpart_dVb - = ddxpart_dVs = 0.0; - dsxpart_dVd = dsxpart_dVg = dsxpart_dVb - = dsxpart_dVs = 0.0; - } - else - { cggb = cgdb = cgsb = 0.0; - cbgb = cbdb = cbsb = 0.0; - cdgb = cddb = cdsb = 0.0; + xgtg = xgtd = xgts = xgtb = 0.0; + sxpart = 0.4; + dxpart = 0.6; + ddxpart_dVd = ddxpart_dVg = ddxpart_dVb + = ddxpart_dVs = 0.0; + dsxpart_dVd = dsxpart_dVg = dsxpart_dVb + = dsxpart_dVs = 0.0; + } else { + cggb = cgdb = cgsb = 0.0; + cbgb = cbdb = cbsb = 0.0; + cdgb = cddb = cdsb = 0.0; - xgtg = here->BSIM3gtg; - xgtd = here->BSIM3gts; - xgts = here->BSIM3gtd; - xgtb = here->BSIM3gtb; + xgtg = here->BSIM3gtg; + xgtd = here->BSIM3gts; + xgts = here->BSIM3gtd; + xgtb = here->BSIM3gtb; - xcqgb = here->BSIM3cqgb * omega; - xcqdb = here->BSIM3cqsb * omega; - xcqsb = here->BSIM3cqdb * omega; - xcqbb = here->BSIM3cqbb * omega; + xcqgb = here->BSIM3cqgb * omega; + xcqdb = here->BSIM3cqsb * omega; + xcqsb = here->BSIM3cqdb * omega; + xcqbb = here->BSIM3cqbb * omega; - CoxWL = model->BSIM3cox * here->pParam->BSIM3weffCV - * here->pParam->BSIM3leffCV; - qcheq = -(here->BSIM3qgate + here->BSIM3qbulk); - if (fabs(qcheq) <= 1.0e-5 * CoxWL) - { if (model->BSIM3xpart < 0.5) - { sxpart = 0.4; - } - else if (model->BSIM3xpart > 0.5) - { sxpart = 0.0; - } - else - { sxpart = 0.5; - } - dsxpart_dVd = dsxpart_dVg = dsxpart_dVb - = dsxpart_dVs = 0.0; - } - else - { sxpart = here->BSIM3qdrn / qcheq; - Css = here->BSIM3cddb; - Cds = -(here->BSIM3cgdb + here->BSIM3cddb - + here->BSIM3cbdb); - dsxpart_dVs = (Css - sxpart * (Css + Cds)) / qcheq; - Csg = here->BSIM3cdgb; - Cdg = -(here->BSIM3cggb + here->BSIM3cdgb - + here->BSIM3cbgb); - dsxpart_dVg = (Csg - sxpart * (Csg + Cdg)) / qcheq; + CoxWL = model->BSIM3cox * here->pParam->BSIM3weffCV + * here->pParam->BSIM3leffCV; + qcheq = -(here->BSIM3qgate + here->BSIM3qbulk); + if (fabs(qcheq) <= 1.0e-5 * CoxWL) { + if (model->BSIM3xpart < 0.5) { + sxpart = 0.4; + } else if (model->BSIM3xpart > 0.5) { + sxpart = 0.0; + } else { + sxpart = 0.5; + } + dsxpart_dVd = dsxpart_dVg = dsxpart_dVb + = dsxpart_dVs = 0.0; + } else { + sxpart = here->BSIM3qdrn / qcheq; + Css = here->BSIM3cddb; + Cds = -(here->BSIM3cgdb + here->BSIM3cddb + + here->BSIM3cbdb); + dsxpart_dVs = (Css - sxpart * (Css + Cds)) / qcheq; + Csg = here->BSIM3cdgb; + Cdg = -(here->BSIM3cggb + here->BSIM3cdgb + + here->BSIM3cbgb); + dsxpart_dVg = (Csg - sxpart * (Csg + Cdg)) / qcheq; - Csd = here->BSIM3cdsb; - Cdd = -(here->BSIM3cgsb + here->BSIM3cdsb - + here->BSIM3cbsb); - dsxpart_dVd = (Csd - sxpart * (Csd + Cdd)) / qcheq; + Csd = here->BSIM3cdsb; + Cdd = -(here->BSIM3cgsb + here->BSIM3cdsb + + here->BSIM3cbsb); + dsxpart_dVd = (Csd - sxpart * (Csd + Cdd)) / qcheq; - dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg - + dsxpart_dVs); - } - dxpart = 1.0 - sxpart; - ddxpart_dVd = -dsxpart_dVd; - ddxpart_dVg = -dsxpart_dVg; - ddxpart_dVs = -dsxpart_dVs; - ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg + ddxpart_dVs); - } - } + dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg + + dsxpart_dVs); + } + dxpart = 1.0 - sxpart; + ddxpart_dVd = -dsxpart_dVd; + ddxpart_dVg = -dsxpart_dVg; + ddxpart_dVs = -dsxpart_dVs; + ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg + ddxpart_dVs); + } + } - T1 = *(ckt->CKTstate0 + here->BSIM3qdef) * here->BSIM3gtau; - gdpr = here->BSIM3drainConductance; - gspr = here->BSIM3sourceConductance; - gds = here->BSIM3gds; - gbd = here->BSIM3gbd; - gbs = here->BSIM3gbs; - capbd = here->BSIM3capbd; - capbs = here->BSIM3capbs; + T1 = *(ckt->CKTstate0 + here->BSIM3qdef) * here->BSIM3gtau; + gdpr = here->BSIM3drainConductance; + gspr = here->BSIM3sourceConductance; + gds = here->BSIM3gds; + gbd = here->BSIM3gbd; + gbs = here->BSIM3gbs; + capbd = here->BSIM3capbd; + capbs = here->BSIM3capbs; - GSoverlapCap = here->BSIM3cgso; - GDoverlapCap = here->BSIM3cgdo; - GBoverlapCap = here->pParam->BSIM3cgbo; + GSoverlapCap = here->BSIM3cgso; + GDoverlapCap = here->BSIM3cgdo; + GBoverlapCap = here->pParam->BSIM3cgbo; - xcdgb = (cdgb - GDoverlapCap) * omega; - xcddb = (cddb + capbd + GDoverlapCap) * omega; - xcdsb = cdsb * omega; - xcsgb = -(cggb + cbgb + cdgb + GSoverlapCap) * omega; - xcsdb = -(cgdb + cbdb + cddb) * omega; - xcssb = (capbs + GSoverlapCap - (cgsb + cbsb + cdsb)) * omega; - xcggb = (cggb + GDoverlapCap + GSoverlapCap + GBoverlapCap) - * omega; - xcgdb = (cgdb - GDoverlapCap ) * omega; - xcgsb = (cgsb - GSoverlapCap) * omega; - xcbgb = (cbgb - GBoverlapCap) * omega; - xcbdb = (cbdb - capbd ) * omega; - xcbsb = (cbsb - capbs ) * omega; + xcdgb = (cdgb - GDoverlapCap) * omega; + xcddb = (cddb + capbd + GDoverlapCap) * omega; + xcdsb = cdsb * omega; + xcsgb = -(cggb + cbgb + cdgb + GSoverlapCap) * omega; + xcsdb = -(cgdb + cbdb + cddb) * omega; + xcssb = (capbs + GSoverlapCap - (cgsb + cbsb + cdsb)) * omega; + xcggb = (cggb + GDoverlapCap + GSoverlapCap + GBoverlapCap) + * omega; + xcgdb = (cgdb - GDoverlapCap ) * omega; + xcgsb = (cgsb - GSoverlapCap) * omega; + xcbgb = (cbgb - GBoverlapCap) * omega; + xcbdb = (cbdb - capbd ) * omega; + xcbsb = (cbsb - capbs ) * omega; - *(here->BSIM3GgPtr +1) += xcggb; - *(here->BSIM3BbPtr +1) -= xcbgb + xcbdb + xcbsb; - *(here->BSIM3DPdpPtr +1) += xcddb; - *(here->BSIM3SPspPtr +1) += xcssb; - *(here->BSIM3GbPtr +1) -= xcggb + xcgdb + xcgsb; - *(here->BSIM3GdpPtr +1) += xcgdb; - *(here->BSIM3GspPtr +1) += xcgsb; - *(here->BSIM3BgPtr +1) += xcbgb; - *(here->BSIM3BdpPtr +1) += xcbdb; - *(here->BSIM3BspPtr +1) += xcbsb; - *(here->BSIM3DPgPtr +1) += xcdgb; - *(here->BSIM3DPbPtr +1) -= xcdgb + xcddb + xcdsb; - *(here->BSIM3DPspPtr +1) += xcdsb; - *(here->BSIM3SPgPtr +1) += xcsgb; - *(here->BSIM3SPbPtr +1) -= xcsgb + xcsdb + xcssb; - *(here->BSIM3SPdpPtr +1) += xcsdb; + + m = here->BSIM3m; - *(here->BSIM3DdPtr) += gdpr; - *(here->BSIM3SsPtr) += gspr; - *(here->BSIM3BbPtr) += gbd + gbs - here->BSIM3gbbs; - *(here->BSIM3DPdpPtr) += gdpr + gds + gbd + RevSum - + dxpart * xgtd + T1 * ddxpart_dVd + gbdpdp; - *(here->BSIM3SPspPtr) += gspr + gds + gbs + FwdSum - + sxpart * xgts + T1 * dsxpart_dVs + gbspsp; + *(here->BSIM3GgPtr +1) += m * xcggb; + *(here->BSIM3BbPtr +1) -= xcbgb + xcbdb + xcbsb; + *(here->BSIM3DPdpPtr +1) += m * xcddb; + *(here->BSIM3SPspPtr +1) += m * xcssb; + *(here->BSIM3GbPtr +1) -= xcggb + xcgdb + xcgsb; + *(here->BSIM3GdpPtr +1) += m * xcgdb; + *(here->BSIM3GspPtr +1) += m * xcgsb; + *(here->BSIM3BgPtr +1) += m * xcbgb; + *(here->BSIM3BdpPtr +1) += m * xcbdb; + *(here->BSIM3BspPtr +1) += m * xcbsb; + *(here->BSIM3DPgPtr +1) += m * xcdgb; + *(here->BSIM3DPbPtr +1) -= xcdgb + xcddb + xcdsb; + *(here->BSIM3DPspPtr +1) += m * xcdsb; + *(here->BSIM3SPgPtr +1) += m * xcsgb; + *(here->BSIM3SPbPtr +1) -= xcsgb + xcsdb + xcssb; + *(here->BSIM3SPdpPtr +1) += m * xcsdb; - *(here->BSIM3DdpPtr) -= gdpr; - *(here->BSIM3SspPtr) -= gspr; + *(here->BSIM3DdPtr) += m * gdpr; + *(here->BSIM3SsPtr) += m * gspr; + *(here->BSIM3BbPtr) += m * (gbd + gbs - here->BSIM3gbbs); + *(here->BSIM3DPdpPtr) += m * (gdpr + gds + gbd + RevSum + +dxpart * xgtd + T1 * ddxpart_dVd + gbdpdp); + *(here->BSIM3SPspPtr) += m * (gspr + gds + gbs + FwdSum + +sxpart * xgts + T1 * dsxpart_dVs + gbspsp); - *(here->BSIM3BgPtr) -= here->BSIM3gbgs; - *(here->BSIM3BdpPtr) -= gbd - gbbdp; - *(here->BSIM3BspPtr) -= gbs - gbbsp; + *(here->BSIM3DdpPtr) -= m * gdpr; + *(here->BSIM3SspPtr) -= m * gspr; - *(here->BSIM3DPdPtr) -= gdpr; - *(here->BSIM3DPgPtr) += Gm + dxpart * xgtg + T1 * ddxpart_dVg - + gbdpg; - *(here->BSIM3DPbPtr) -= gbd - Gmbs - dxpart * xgtb - - T1 * ddxpart_dVb - gbdpb; - *(here->BSIM3DPspPtr) -= gds + FwdSum - dxpart * xgts - - T1 * ddxpart_dVs - gbdpsp; + *(here->BSIM3BgPtr) -= m * here->BSIM3gbgs; + *(here->BSIM3BdpPtr) -= m * (gbd - gbbdp); + *(here->BSIM3BspPtr) -= m * (gbs - gbbsp); - *(here->BSIM3SPgPtr) -= Gm - sxpart * xgtg - T1 * dsxpart_dVg - - gbspg; - *(here->BSIM3SPsPtr) -= gspr; - *(here->BSIM3SPbPtr) -= gbs + Gmbs - sxpart * xgtb - - T1 * dsxpart_dVb - gbspb; - *(here->BSIM3SPdpPtr) -= gds + RevSum - sxpart * xgtd - - T1 * dsxpart_dVd - gbspdp; + *(here->BSIM3DPdPtr) -= m * gdpr; + *(here->BSIM3DPgPtr) += m * (Gm + dxpart * xgtg + T1 * ddxpart_dVg + + gbdpg); + *(here->BSIM3DPbPtr) -= m * (gbd - Gmbs - dxpart * xgtb + - T1 * ddxpart_dVb - gbdpb); + *(here->BSIM3DPspPtr) -= m * (gds + FwdSum - dxpart * xgts + - T1 * ddxpart_dVs - gbdpsp); - *(here->BSIM3GgPtr) -= xgtg; - *(here->BSIM3GbPtr) -= xgtb; - *(here->BSIM3GdpPtr) -= xgtd; - *(here->BSIM3GspPtr) -= xgts; + *(here->BSIM3SPgPtr) -= m * (Gm - sxpart * xgtg - T1 * dsxpart_dVg + - gbspg); + *(here->BSIM3SPsPtr) -= m * gspr; + *(here->BSIM3SPbPtr) -= m * (gbs + Gmbs - sxpart * xgtb + - T1 * dsxpart_dVb - gbspb); + *(here->BSIM3SPdpPtr) -= m * (gds + RevSum - sxpart * xgtd + - T1 * dsxpart_dVd - gbspdp); - if (here->BSIM3nqsMod) - { *(here->BSIM3QqPtr +1) += omega * ScalingFactor; - *(here->BSIM3QgPtr +1) -= xcqgb; - *(here->BSIM3QdpPtr +1) -= xcqdb; - *(here->BSIM3QspPtr +1) -= xcqsb; - *(here->BSIM3QbPtr +1) -= xcqbb; + *(here->BSIM3GgPtr) -= m * xgtg; + *(here->BSIM3GbPtr) -= m * xgtb; + *(here->BSIM3GdpPtr) -= m * xgtd; + *(here->BSIM3GspPtr) -= m * xgts; - *(here->BSIM3QqPtr) += here->BSIM3gtau; + if (here->BSIM3nqsMod) { + *(here->BSIM3QqPtr +1) += m * (omega * ScalingFactor); + *(here->BSIM3QgPtr +1) -= m * xcqgb; + *(here->BSIM3QdpPtr +1) -= m * xcqdb; + *(here->BSIM3QspPtr +1) -= m * xcqsb; + *(here->BSIM3QbPtr +1) -= m * xcqbb; - *(here->BSIM3DPqPtr) += dxpart * here->BSIM3gtau; - *(here->BSIM3SPqPtr) += sxpart * here->BSIM3gtau; - *(here->BSIM3GqPtr) -= here->BSIM3gtau; + *(here->BSIM3QqPtr) += m * here->BSIM3gtau; - *(here->BSIM3QgPtr) += xgtg; - *(here->BSIM3QdpPtr) += xgtd; - *(here->BSIM3QspPtr) += xgts; - *(here->BSIM3QbPtr) += xgtb; - } + *(here->BSIM3DPqPtr) += m * (dxpart * here->BSIM3gtau); + *(here->BSIM3SPqPtr) += m * (sxpart * here->BSIM3gtau); + *(here->BSIM3GqPtr) -= m * here->BSIM3gtau; + + *(here->BSIM3QgPtr) += m * xgtg; + *(here->BSIM3QdpPtr) += m * xgtd; + *(here->BSIM3QspPtr) += m * xgts; + *(here->BSIM3QbPtr) += m * xgtb; + } } } return(OK); diff --git a/src/spicelib/devices/bsim3/b3ask.c b/src/spicelib/devices/bsim3/b3ask.c index 63f24a6e1..16c903c67 100644 --- a/src/spicelib/devices/bsim3/b3ask.c +++ b/src/spicelib/devices/bsim3/b3ask.c @@ -1,26 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.2 1999/08/28 21:00:03 manu - Big commit - merged ngspice.h, misc.h and util.h - protoized fte - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -55,6 +32,9 @@ BSIM3instance *here = (BSIM3instance*)inst; case BSIM3_W: value->rValue = here->BSIM3w; return(OK); + case BSIM3_M: + value->rValue = here->BSIM3m; + return(OK); case BSIM3_AS: value->rValue = here->BSIM3sourceArea; return(OK); @@ -108,9 +88,11 @@ BSIM3instance *here = (BSIM3instance*)inst; return(OK); case BSIM3_SOURCECONDUCT: value->rValue = here->BSIM3sourceConductance; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_DRAINCONDUCT: value->rValue = here->BSIM3drainConductance; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_VBD: value->rValue = *(ckt->CKTstate0 + here->BSIM3vbd); @@ -126,78 +108,103 @@ BSIM3instance *here = (BSIM3instance*)inst; return(OK); case BSIM3_CD: value->rValue = here->BSIM3cd; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_CBS: - value->rValue = here->BSIM3cbs; + value->rValue = here->BSIM3cbs; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_CBD: - value->rValue = here->BSIM3cbd; + value->rValue = here->BSIM3cbd; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_GM: - value->rValue = here->BSIM3gm; + value->rValue = here->BSIM3gm; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_GDS: - value->rValue = here->BSIM3gds; + value->rValue = here->BSIM3gds; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_GMBS: value->rValue = here->BSIM3gmbs; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_GBD: - value->rValue = here->BSIM3gbd; + value->rValue = here->BSIM3gbd; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_GBS: - value->rValue = here->BSIM3gbs; + value->rValue = here->BSIM3gbs; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_QB: - value->rValue = *(ckt->CKTstate0 + here->BSIM3qb); + value->rValue = *(ckt->CKTstate0 + here->BSIM3qb); + value->rValue *= here->BSIM3m; return(OK); case BSIM3_CQB: value->rValue = *(ckt->CKTstate0 + here->BSIM3cqb); + value->rValue *= here->BSIM3m; return(OK); case BSIM3_QG: - value->rValue = *(ckt->CKTstate0 + here->BSIM3qg); + value->rValue = *(ckt->CKTstate0 + here->BSIM3qg); + value->rValue *= here->BSIM3m; return(OK); case BSIM3_CQG: - value->rValue = *(ckt->CKTstate0 + here->BSIM3cqg); + value->rValue = *(ckt->CKTstate0 + here->BSIM3cqg); + value->rValue *= here->BSIM3m; return(OK); case BSIM3_QD: - value->rValue = *(ckt->CKTstate0 + here->BSIM3qd); + value->rValue = *(ckt->CKTstate0 + here->BSIM3qd); + value->rValue *= here->BSIM3m; return(OK); case BSIM3_CQD: - value->rValue = *(ckt->CKTstate0 + here->BSIM3cqd); + value->rValue = *(ckt->CKTstate0 + here->BSIM3cqd); + value->rValue *= here->BSIM3m; return(OK); case BSIM3_CGG: - value->rValue = here->BSIM3cggb; + value->rValue = here->BSIM3cggb; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_CGD: value->rValue = here->BSIM3cgdb; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_CGS: value->rValue = here->BSIM3cgsb; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_CDG: - value->rValue = here->BSIM3cdgb; + value->rValue = here->BSIM3cdgb; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_CDD: - value->rValue = here->BSIM3cddb; + value->rValue = here->BSIM3cddb; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_CDS: - value->rValue = here->BSIM3cdsb; + value->rValue = here->BSIM3cdsb; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_CBG: value->rValue = here->BSIM3cbgb; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_CBDB: value->rValue = here->BSIM3cbdb; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_CBSB: value->rValue = here->BSIM3cbsb; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_CAPBD: - value->rValue = here->BSIM3capbd; + value->rValue = here->BSIM3capbd; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_CAPBS: value->rValue = here->BSIM3capbs; + value->rValue *= here->BSIM3m; return(OK); case BSIM3_VON: value->rValue = here->BSIM3von; @@ -206,10 +213,12 @@ BSIM3instance *here = (BSIM3instance*)inst; value->rValue = here->BSIM3vdsat; return(OK); case BSIM3_QBS: - value->rValue = *(ckt->CKTstate0 + here->BSIM3qbs); + value->rValue = *(ckt->CKTstate0 + here->BSIM3qbs); + value->rValue *= here->BSIM3m; return(OK); case BSIM3_QBD: - value->rValue = *(ckt->CKTstate0 + here->BSIM3qbd); + value->rValue = *(ckt->CKTstate0 + here->BSIM3qbd); + value->rValue *= here->BSIM3m; return(OK); default: return(E_BADPARM); diff --git a/src/spicelib/devices/bsim3/b3check.c b/src/spicelib/devices/bsim3/b3check.c index dd99be6b0..5275c823d 100644 --- a/src/spicelib/devices/bsim3/b3check.c +++ b/src/spicelib/devices/bsim3/b3check.c @@ -1,26 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.2 1999/08/28 21:00:03 manu - Big commit - merged ngspice.h, misc.h and util.h - protoized fte - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: Min-Chie Jeng. @@ -41,8 +18,8 @@ File: b3check.c int BSIM3checkModel(model, here, ckt) -register BSIM3model *model; -register BSIM3instance *here; +BSIM3model *model; +BSIM3instance *here; CKTcircuit *ckt; { struct bsim3SizeDependParam *pParam; diff --git a/src/spicelib/devices/bsim3/b3cvtest.c b/src/spicelib/devices/bsim3/b3cvtest.c index 608618a68..efc11d12b 100644 --- a/src/spicelib/devices/bsim3/b3cvtest.c +++ b/src/spicelib/devices/bsim3/b3cvtest.c @@ -1,26 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.2 1999/08/28 21:00:03 manu - Big commit - merged ngspice.h, misc.h and util.h - protoized fte - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -43,10 +20,10 @@ File: b3cvtest.c int BSIM3convTest(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { -register BSIM3model *model = (BSIM3model*)inModel; -register BSIM3instance *here; +BSIM3model *model = (BSIM3model*)inModel; +BSIM3instance *here; double delvbd, delvbs, delvds, delvgd, delvgs, vbd, vbs, vds; double cbd, cbhat, cbs, cd, cdhat, tol, vgd, vgdo, vgs; diff --git a/src/spicelib/devices/bsim3/b3del.c b/src/spicelib/devices/bsim3/b3del.c index dfc53a29d..dd94259b8 100644 --- a/src/spicelib/devices/bsim3/b3del.c +++ b/src/spicelib/devices/bsim3/b3del.c @@ -1,26 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.2 1999/08/28 21:00:03 manu - Big commit - merged ngspice.h, misc.h and util.h - protoized fte - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3/b3dest.c b/src/spicelib/devices/bsim3/b3dest.c index f879dbfeb..5fb8ab439 100644 --- a/src/spicelib/devices/bsim3/b3dest.c +++ b/src/spicelib/devices/bsim3/b3dest.c @@ -1,26 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.2 1999/08/28 21:00:03 manu - Big commit - merged ngspice.h, misc.h and util.h - protoized fte - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3/b3getic.c b/src/spicelib/devices/bsim3/b3getic.c index 630c20cd9..69fe29c10 100644 --- a/src/spicelib/devices/bsim3/b3getic.c +++ b/src/spicelib/devices/bsim3/b3getic.c @@ -1,23 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3/b3ld.c b/src/spicelib/devices/bsim3/b3ld.c index ffcee4ebf..64b1c6198 100644 --- a/src/spicelib/devices/bsim3/b3ld.c +++ b/src/spicelib/devices/bsim3/b3ld.c @@ -1,37 +1,9 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.4 1999/09/06 16:10:27 manu - Added patch by Arno Peters - - Revision 1.3 1999/08/28 21:00:03 manu - Big commit - merged ngspice.h, misc.h and util.h - protoized fte - - Revision 1.2 1999/08/23 18:14:39 manu - Added cleanup patch by Arno Peters - also added 'make check' to configure - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1991 JianHui Huang and Min-Chie Jeng. Modified by Mansun Chan (1995). Author: 1997-1999 Weidong Liu. +Modified: 2000 AlansFixes File: b3ld.c **********/ @@ -61,10 +33,10 @@ File: b3ld.c int BSIM3load(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { -register BSIM3model *model = (BSIM3model*)inModel; -register BSIM3instance *here; +BSIM3model *model = (BSIM3model*)inModel; +BSIM3instance *here; double SourceSatCurrent, DrainSatCurrent; double ag0, qgd, qgs, qgb, von, cbhat, VgstNVt, ExpVgst; double cdrain, cdhat, cdreq, ceqbd, ceqbs, ceqqb, ceqqd, ceqqg, ceq, geq; @@ -147,6 +119,8 @@ double Cgg, Cgd, Cgb, Cdg, Cdd, Cds; double Csg, Csd, Css, Csb, Cbg, Cbd, Cbb; double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Qac0, Qsub0; double dQac0_dVg, dQac0_dVb, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb; + +double m; struct bsim3SizeDependParam *pParam; int ByPass, Check, ChargeComputationNeeded, error; @@ -271,7 +245,6 @@ for (; model != NULL; model = model->BSIM3nextModel) + here->BSIM3gbds * delvds; } -#ifndef NOBYPASS /* following should be one big if connected by && all over * the place, but some C compilers can't handle that, so * we split it up here to let them digest it in stages @@ -316,7 +289,6 @@ for (; model != NULL; model = model->BSIM3nextModel) } } -#endif /*NOBYPASS*/ von = here->BSIM3von; if (*(ckt->CKTstate0 + here->BSIM3vds) >= 0.0) { vgs = DEVfetlim(vgs, *(ckt->CKTstate0+here->BSIM3vgs), von); @@ -349,6 +321,8 @@ for (; model != NULL; model = model->BSIM3nextModel) vbd = vbs - vds; vgd = vgs - vds; vgb = vgs - vbs; + + m=here->BSIM3m; /* Source/drain junction diode DC model begins */ Nvtm = model->BSIM3vtm * model->BSIM3jctEmissionCoeff; @@ -362,29 +336,29 @@ for (; model != NULL; model = model->BSIM3nextModel) * model->BSIM3jctSidewallTempSatCurDensity; } if (SourceSatCurrent <= 0.0) - { here->BSIM3gbs = ckt->CKTgmin; + { here->BSIM3gbs = ckt->CKTgmin/m; here->BSIM3cbs = here->BSIM3gbs * vbs; } else { if (model->BSIM3ijth == 0.0) { evbs = exp(vbs / Nvtm); - here->BSIM3gbs = SourceSatCurrent * evbs / Nvtm + ckt->CKTgmin; + here->BSIM3gbs = SourceSatCurrent * evbs / Nvtm + (ckt->CKTgmin/m); here->BSIM3cbs = SourceSatCurrent * (evbs - 1.0) - + ckt->CKTgmin * vbs; + + (ckt->CKTgmin/m) * vbs; } else { if (vbs < here->BSIM3vjsm) { evbs = exp(vbs / Nvtm); - here->BSIM3gbs = SourceSatCurrent * evbs / Nvtm + ckt->CKTgmin; + here->BSIM3gbs = SourceSatCurrent * evbs / Nvtm + (ckt->CKTgmin/m); here->BSIM3cbs = SourceSatCurrent * (evbs - 1.0) - + ckt->CKTgmin * vbs; + + (ckt->CKTgmin/m) * vbs; } else { T0 = here->BSIM3IsEvjsm / Nvtm; - here->BSIM3gbs = T0 + ckt->CKTgmin; + here->BSIM3gbs = T0 + (ckt->CKTgmin/m); here->BSIM3cbs = here->BSIM3IsEvjsm - SourceSatCurrent + T0 * (vbs - here->BSIM3vjsm) - + ckt->CKTgmin * vbs; + + (ckt->CKTgmin/m) * vbs; } } } @@ -399,29 +373,29 @@ for (; model != NULL; model = model->BSIM3nextModel) * model->BSIM3jctSidewallTempSatCurDensity; } if (DrainSatCurrent <= 0.0) - { here->BSIM3gbd = ckt->CKTgmin; + { here->BSIM3gbd = (ckt->CKTgmin/m); here->BSIM3cbd = here->BSIM3gbd * vbd; } else { if (model->BSIM3ijth == 0.0) { evbd = exp(vbd / Nvtm); - here->BSIM3gbd = DrainSatCurrent * evbd / Nvtm + ckt->CKTgmin; + here->BSIM3gbd = DrainSatCurrent * evbd / Nvtm + (ckt->CKTgmin/m); here->BSIM3cbd = DrainSatCurrent * (evbd - 1.0) - + ckt->CKTgmin * vbd; + + (ckt->CKTgmin/m) * vbd; } else { if (vbd < here->BSIM3vjdm) { evbd = exp(vbd / Nvtm); - here->BSIM3gbd = DrainSatCurrent * evbd / Nvtm + ckt->CKTgmin; + here->BSIM3gbd = DrainSatCurrent * evbd / Nvtm + (ckt->CKTgmin/m); here->BSIM3cbd = DrainSatCurrent * (evbd - 1.0) - + ckt->CKTgmin * vbd; + + (ckt->CKTgmin/m) * vbd; } else { T0 = here->BSIM3IsEvjdm / Nvtm; - here->BSIM3gbd = T0 + ckt->CKTgmin; + here->BSIM3gbd = T0 + (ckt->CKTgmin/m); here->BSIM3cbd = here->BSIM3IsEvjdm - DrainSatCurrent + T0 * (vbd - here->BSIM3vjdm) - + ckt->CKTgmin * vbd; + + (ckt->CKTgmin/m) * vbd; } } } @@ -2325,29 +2299,6 @@ finished: if ((here->BSIM3off == 0) || (!(ckt->CKTmode & MODEINITFIX))) { if (Check == 1) { ckt->CKTnoncon++; -#ifndef NEWCONV - } - else - { if (here->BSIM3mode >= 0) - { Idtot = here->BSIM3cd + here->BSIM3csub - here->BSIM3cbd; - } - else - { Idtot = here->BSIM3cd - here->BSIM3cbd; - } - tol = ckt->CKTreltol * MAX(fabs(cdhat), fabs(Idtot)) - + ckt->CKTabstol; - if (fabs(cdhat - Idtot) >= tol) - { ckt->CKTnoncon++; - } - else - { Ibtot = here->BSIM3cbs + here->BSIM3cbd - here->BSIM3csub; - tol = ckt->CKTreltol * MAX(fabs(cbhat), fabs(Ibtot)) - + ckt->CKTabstol; - if (fabs(cbhat - Ibtot)) > tol) - { ckt->CKTnoncon++; - } - } -#endif /* NEWCONV */ } } *(ckt->CKTstate0 + here->BSIM3vbs) = vbs; @@ -2887,71 +2838,71 @@ line900: cqdef = -cqdef; cqcheq = -cqcheq; } - - (*(ckt->CKTrhs + here->BSIM3gNode) -= ceqqg); - (*(ckt->CKTrhs + here->BSIM3bNode) -=(ceqbs + ceqbd + ceqqb)); - (*(ckt->CKTrhs + here->BSIM3dNodePrime) += (ceqbd - cdreq - ceqqd)); - (*(ckt->CKTrhs + here->BSIM3sNodePrime) += (cdreq + ceqbs + ceqqg + + (*(ckt->CKTrhs + here->BSIM3gNode) -= m*ceqqg); + (*(ckt->CKTrhs + here->BSIM3bNode) -= m*(ceqbs + ceqbd + ceqqb)); + (*(ckt->CKTrhs + here->BSIM3dNodePrime) +=m*(ceqbd - cdreq - ceqqd)); + (*(ckt->CKTrhs + here->BSIM3sNodePrime) += m*(cdreq + ceqbs + ceqqg + ceqqb + ceqqd)); if (here->BSIM3nqsMod) - *(ckt->CKTrhs + here->BSIM3qNode) += (cqcheq - cqdef); + *(ckt->CKTrhs + here->BSIM3qNode) += m*(cqcheq - cqdef); /* * load y matrix */ T1 = qdef * here->BSIM3gtau; - (*(here->BSIM3DdPtr) += here->BSIM3drainConductance); - (*(here->BSIM3GgPtr) += gcggb - ggtg); - (*(here->BSIM3SsPtr) += here->BSIM3sourceConductance); - (*(here->BSIM3BbPtr) += here->BSIM3gbd + here->BSIM3gbs - - gcbgb - gcbdb - gcbsb - here->BSIM3gbbs); - (*(here->BSIM3DPdpPtr) += here->BSIM3drainConductance + (*(here->BSIM3DdPtr) += m*here->BSIM3drainConductance); + (*(here->BSIM3GgPtr) += m*(gcggb - ggtg)); + (*(here->BSIM3SsPtr) += m*here->BSIM3sourceConductance); + (*(here->BSIM3BbPtr) += m*(here->BSIM3gbd + here->BSIM3gbs + - gcbgb - gcbdb - gcbsb - here->BSIM3gbbs)); + (*(here->BSIM3DPdpPtr) += m*(here->BSIM3drainConductance + here->BSIM3gds + here->BSIM3gbd + RevSum + gcddb + dxpart * ggtd - + T1 * ddxpart_dVd + gbdpdp); - (*(here->BSIM3SPspPtr) += here->BSIM3sourceConductance + + T1 * ddxpart_dVd + gbdpdp)); + (*(here->BSIM3SPspPtr) += m*(here->BSIM3sourceConductance + here->BSIM3gds + here->BSIM3gbs + FwdSum + gcssb + sxpart * ggts - + T1 * dsxpart_dVs + gbspsp); - (*(here->BSIM3DdpPtr) -= here->BSIM3drainConductance); - (*(here->BSIM3GbPtr) -= gcggb + gcgdb + gcgsb + ggtb); - (*(here->BSIM3GdpPtr) += gcgdb - ggtd); - (*(here->BSIM3GspPtr) += gcgsb - ggts); - (*(here->BSIM3SspPtr) -= here->BSIM3sourceConductance); - (*(here->BSIM3BgPtr) += gcbgb - here->BSIM3gbgs); - (*(here->BSIM3BdpPtr) += gcbdb - here->BSIM3gbd + gbbdp); - (*(here->BSIM3BspPtr) += gcbsb - here->BSIM3gbs + gbbsp); - (*(here->BSIM3DPdPtr) -= here->BSIM3drainConductance); - (*(here->BSIM3DPgPtr) += Gm + gcdgb + dxpart * ggtg - + T1 * ddxpart_dVg + gbdpg); - (*(here->BSIM3DPbPtr) -= here->BSIM3gbd - Gmbs + gcdgb + gcddb + + T1 * dsxpart_dVs + gbspsp)); + (*(here->BSIM3DdpPtr) -= m*here->BSIM3drainConductance); + (*(here->BSIM3GbPtr) -= m*(gcggb + gcgdb + gcgsb + ggtb)); + (*(here->BSIM3GdpPtr) += m*(gcgdb - ggtd)); + (*(here->BSIM3GspPtr) += m*(gcgsb - ggts)); + (*(here->BSIM3SspPtr) -= m*here->BSIM3sourceConductance); + (*(here->BSIM3BgPtr) += m*(gcbgb - here->BSIM3gbgs)); + (*(here->BSIM3BdpPtr) += m*(gcbdb - here->BSIM3gbd + gbbdp)); + (*(here->BSIM3BspPtr) += m*(gcbsb - here->BSIM3gbs + gbbsp)); + (*(here->BSIM3DPdPtr) -= m*here->BSIM3drainConductance); + (*(here->BSIM3DPgPtr) += m*(Gm + gcdgb + dxpart * ggtg + + T1 * ddxpart_dVg + gbdpg)); + (*(here->BSIM3DPbPtr) -= m*(here->BSIM3gbd - Gmbs + gcdgb + gcddb + gcdsb - dxpart * ggtb - - T1 * ddxpart_dVb - gbdpb); - (*(here->BSIM3DPspPtr) -= here->BSIM3gds + FwdSum - gcdsb - - dxpart * ggts - T1 * ddxpart_dVs - gbdpsp); - (*(here->BSIM3SPgPtr) += gcsgb - Gm + sxpart * ggtg - + T1 * dsxpart_dVg + gbspg); - (*(here->BSIM3SPsPtr) -= here->BSIM3sourceConductance); - (*(here->BSIM3SPbPtr) -= here->BSIM3gbs + Gmbs + gcsgb + gcsdb + - T1 * ddxpart_dVb - gbdpb)); + (*(here->BSIM3DPspPtr) -= m*(here->BSIM3gds + FwdSum - gcdsb + - dxpart * ggts - T1 * ddxpart_dVs - gbdpsp)); + (*(here->BSIM3SPgPtr) += m*(gcsgb - Gm + sxpart * ggtg + + T1 * dsxpart_dVg + gbspg)); + (*(here->BSIM3SPsPtr) -= m*here->BSIM3sourceConductance); + (*(here->BSIM3SPbPtr) -= m*(here->BSIM3gbs + Gmbs + gcsgb + gcsdb + gcssb - sxpart * ggtb - - T1 * dsxpart_dVb - gbspb); - (*(here->BSIM3SPdpPtr) -= here->BSIM3gds + RevSum - gcsdb - - sxpart * ggtd - T1 * dsxpart_dVd - gbspdp); + - T1 * dsxpart_dVb - gbspb)); + (*(here->BSIM3SPdpPtr) -= m*(here->BSIM3gds + RevSum - gcsdb + - sxpart * ggtd - T1 * dsxpart_dVd - gbspdp)); if (here->BSIM3nqsMod) - { *(here->BSIM3QqPtr) += (gqdef + here->BSIM3gtau); + { *(here->BSIM3QqPtr) += m*(gqdef + here->BSIM3gtau); - *(here->BSIM3DPqPtr) += (dxpart * here->BSIM3gtau); - *(here->BSIM3SPqPtr) += (sxpart * here->BSIM3gtau); - *(here->BSIM3GqPtr) -= here->BSIM3gtau; + *(here->BSIM3DPqPtr) += m*(dxpart * here->BSIM3gtau); + *(here->BSIM3SPqPtr) += m*(sxpart * here->BSIM3gtau); + *(here->BSIM3GqPtr) -= m*here->BSIM3gtau; - *(here->BSIM3QgPtr) += (ggtg - gcqgb); - *(here->BSIM3QdpPtr) += (ggtd - gcqdb); - *(here->BSIM3QspPtr) += (ggts - gcqsb); - *(here->BSIM3QbPtr) += (ggtb - gcqbb); + *(here->BSIM3QgPtr) += m*(ggtg - gcqgb); + *(here->BSIM3QdpPtr) += m*(ggtd - gcqdb); + *(here->BSIM3QspPtr) += m*(ggts - gcqsb); + *(here->BSIM3QbPtr) += m*(ggtb - gcqbb); } - + line1000: ; } /* End of Mosfet Instance */ diff --git a/src/spicelib/devices/bsim3/b3mask.c b/src/spicelib/devices/bsim3/b3mask.c index f2db3c3b9..f2c41aea1 100644 --- a/src/spicelib/devices/bsim3/b3mask.c +++ b/src/spicelib/devices/bsim3/b3mask.c @@ -1,23 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3/b3mdel.c b/src/spicelib/devices/bsim3/b3mdel.c index 386b4a7c8..7836f349b 100644 --- a/src/spicelib/devices/bsim3/b3mdel.c +++ b/src/spicelib/devices/bsim3/b3mdel.c @@ -1,26 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.2 1999/08/28 21:00:03 manu - Big commit - merged ngspice.h, misc.h and util.h - protoized fte - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3/b3mpar.c b/src/spicelib/devices/bsim3/b3mpar.c index 107a32282..7ba57a744 100644 --- a/src/spicelib/devices/bsim3/b3mpar.c +++ b/src/spicelib/devices/bsim3/b3mpar.c @@ -1,26 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.2 1999/08/28 21:00:03 manu - Big commit - merged ngspice.h, misc.h and util.h - protoized fte - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -37,1662 +14,1663 @@ File: b3mpar.c int -BSIM3mParam(param,value,inMod) -int param; -IFvalue *value; -GENmodel *inMod; +BSIM3mParam (param, value, inMod) + int param; + IFvalue *value; + GENmodel *inMod; { - BSIM3model *mod = (BSIM3model*)inMod; - switch(param) - { case BSIM3_MOD_MOBMOD : - mod->BSIM3mobMod = value->iValue; - mod->BSIM3mobModGiven = TRUE; - break; - case BSIM3_MOD_BINUNIT : - mod->BSIM3binUnit = value->iValue; - mod->BSIM3binUnitGiven = TRUE; - break; - case BSIM3_MOD_PARAMCHK : - mod->BSIM3paramChk = value->iValue; - mod->BSIM3paramChkGiven = TRUE; - break; - case BSIM3_MOD_CAPMOD : - mod->BSIM3capMod = value->iValue; - mod->BSIM3capModGiven = TRUE; - break; - case BSIM3_MOD_NOIMOD : - mod->BSIM3noiMod = value->iValue; - mod->BSIM3noiModGiven = TRUE; - break; - case BSIM3_MOD_VERSION : - mod->BSIM3version = value->sValue; - mod->BSIM3versionGiven = TRUE; - break; - case BSIM3_MOD_TOX : - mod->BSIM3tox = value->rValue; - mod->BSIM3toxGiven = TRUE; - break; - case BSIM3_MOD_TOXM : - mod->BSIM3toxm = value->rValue; - mod->BSIM3toxmGiven = TRUE; - break; + BSIM3model *mod = (BSIM3model *) inMod; + switch (param) + { + case BSIM3_MOD_MOBMOD: + mod->BSIM3mobMod = value->iValue; + mod->BSIM3mobModGiven = TRUE; + break; + case BSIM3_MOD_BINUNIT: + mod->BSIM3binUnit = value->iValue; + mod->BSIM3binUnitGiven = TRUE; + break; + case BSIM3_MOD_PARAMCHK: + mod->BSIM3paramChk = value->iValue; + mod->BSIM3paramChkGiven = TRUE; + break; + case BSIM3_MOD_CAPMOD: + mod->BSIM3capMod = value->iValue; + mod->BSIM3capModGiven = TRUE; + break; + case BSIM3_MOD_NOIMOD: + mod->BSIM3noiMod = value->iValue; + mod->BSIM3noiModGiven = TRUE; + break; + case BSIM3_MOD_VERSION: + mod->BSIM3version = value->sValue; + mod->BSIM3versionGiven = TRUE; + break; + case BSIM3_MOD_TOX: + mod->BSIM3tox = value->rValue; + mod->BSIM3toxGiven = TRUE; + break; + case BSIM3_MOD_TOXM: + mod->BSIM3toxm = value->rValue; + mod->BSIM3toxmGiven = TRUE; + break; - case BSIM3_MOD_CDSC : - mod->BSIM3cdsc = value->rValue; - mod->BSIM3cdscGiven = TRUE; - break; - case BSIM3_MOD_CDSCB : - mod->BSIM3cdscb = value->rValue; - mod->BSIM3cdscbGiven = TRUE; - break; + case BSIM3_MOD_CDSC: + mod->BSIM3cdsc = value->rValue; + mod->BSIM3cdscGiven = TRUE; + break; + case BSIM3_MOD_CDSCB: + mod->BSIM3cdscb = value->rValue; + mod->BSIM3cdscbGiven = TRUE; + break; - case BSIM3_MOD_CDSCD : - mod->BSIM3cdscd = value->rValue; - mod->BSIM3cdscdGiven = TRUE; - break; + case BSIM3_MOD_CDSCD: + mod->BSIM3cdscd = value->rValue; + mod->BSIM3cdscdGiven = TRUE; + break; - case BSIM3_MOD_CIT : - mod->BSIM3cit = value->rValue; - mod->BSIM3citGiven = TRUE; - break; - case BSIM3_MOD_NFACTOR : - mod->BSIM3nfactor = value->rValue; - mod->BSIM3nfactorGiven = TRUE; - break; - case BSIM3_MOD_XJ: - mod->BSIM3xj = value->rValue; - mod->BSIM3xjGiven = TRUE; - break; - case BSIM3_MOD_VSAT: - mod->BSIM3vsat = value->rValue; - mod->BSIM3vsatGiven = TRUE; - break; - case BSIM3_MOD_A0: - mod->BSIM3a0 = value->rValue; - mod->BSIM3a0Given = TRUE; - break; - - case BSIM3_MOD_AGS: - mod->BSIM3ags= value->rValue; - mod->BSIM3agsGiven = TRUE; - break; - - case BSIM3_MOD_A1: - mod->BSIM3a1 = value->rValue; - mod->BSIM3a1Given = TRUE; - break; - case BSIM3_MOD_A2: - mod->BSIM3a2 = value->rValue; - mod->BSIM3a2Given = TRUE; - break; - case BSIM3_MOD_AT: - mod->BSIM3at = value->rValue; - mod->BSIM3atGiven = TRUE; - break; - case BSIM3_MOD_KETA: - mod->BSIM3keta = value->rValue; - mod->BSIM3ketaGiven = TRUE; - break; - case BSIM3_MOD_NSUB: - mod->BSIM3nsub = value->rValue; - mod->BSIM3nsubGiven = TRUE; - break; - case BSIM3_MOD_NPEAK: - mod->BSIM3npeak = value->rValue; - mod->BSIM3npeakGiven = TRUE; - if (mod->BSIM3npeak > 1.0e20) - mod->BSIM3npeak *= 1.0e-6; - break; - case BSIM3_MOD_NGATE: - mod->BSIM3ngate = value->rValue; - mod->BSIM3ngateGiven = TRUE; - if (mod->BSIM3ngate > 1.0e23) - mod->BSIM3ngate *= 1.0e-6; - break; - case BSIM3_MOD_GAMMA1: - mod->BSIM3gamma1 = value->rValue; - mod->BSIM3gamma1Given = TRUE; - break; - case BSIM3_MOD_GAMMA2: - mod->BSIM3gamma2 = value->rValue; - mod->BSIM3gamma2Given = TRUE; - break; - case BSIM3_MOD_VBX: - mod->BSIM3vbx = value->rValue; - mod->BSIM3vbxGiven = TRUE; - break; - case BSIM3_MOD_VBM: - mod->BSIM3vbm = value->rValue; - mod->BSIM3vbmGiven = TRUE; - break; - case BSIM3_MOD_XT: - mod->BSIM3xt = value->rValue; - mod->BSIM3xtGiven = TRUE; - break; - case BSIM3_MOD_K1: - mod->BSIM3k1 = value->rValue; - mod->BSIM3k1Given = TRUE; - break; - case BSIM3_MOD_KT1: - mod->BSIM3kt1 = value->rValue; - mod->BSIM3kt1Given = TRUE; - break; - case BSIM3_MOD_KT1L: - mod->BSIM3kt1l = value->rValue; - mod->BSIM3kt1lGiven = TRUE; - break; - case BSIM3_MOD_KT2: - mod->BSIM3kt2 = value->rValue; - mod->BSIM3kt2Given = TRUE; - break; - case BSIM3_MOD_K2: - mod->BSIM3k2 = value->rValue; - mod->BSIM3k2Given = TRUE; - break; - case BSIM3_MOD_K3: - mod->BSIM3k3 = value->rValue; - mod->BSIM3k3Given = TRUE; - break; - case BSIM3_MOD_K3B: - mod->BSIM3k3b = value->rValue; - mod->BSIM3k3bGiven = TRUE; - break; - case BSIM3_MOD_NLX: - mod->BSIM3nlx = value->rValue; - mod->BSIM3nlxGiven = TRUE; - break; - case BSIM3_MOD_W0: - mod->BSIM3w0 = value->rValue; - mod->BSIM3w0Given = TRUE; - break; - case BSIM3_MOD_DVT0: - mod->BSIM3dvt0 = value->rValue; - mod->BSIM3dvt0Given = TRUE; - break; - case BSIM3_MOD_DVT1: - mod->BSIM3dvt1 = value->rValue; - mod->BSIM3dvt1Given = TRUE; - break; - case BSIM3_MOD_DVT2: - mod->BSIM3dvt2 = value->rValue; - mod->BSIM3dvt2Given = TRUE; - break; - case BSIM3_MOD_DVT0W: - mod->BSIM3dvt0w = value->rValue; - mod->BSIM3dvt0wGiven = TRUE; - break; - case BSIM3_MOD_DVT1W: - mod->BSIM3dvt1w = value->rValue; - mod->BSIM3dvt1wGiven = TRUE; - break; - case BSIM3_MOD_DVT2W: - mod->BSIM3dvt2w = value->rValue; - mod->BSIM3dvt2wGiven = TRUE; - break; - case BSIM3_MOD_DROUT: - mod->BSIM3drout = value->rValue; - mod->BSIM3droutGiven = TRUE; - break; - case BSIM3_MOD_DSUB: - mod->BSIM3dsub = value->rValue; - mod->BSIM3dsubGiven = TRUE; - break; - case BSIM3_MOD_VTH0: - mod->BSIM3vth0 = value->rValue; - mod->BSIM3vth0Given = TRUE; - break; - case BSIM3_MOD_UA: - mod->BSIM3ua = value->rValue; - mod->BSIM3uaGiven = TRUE; - break; - case BSIM3_MOD_UA1: - mod->BSIM3ua1 = value->rValue; - mod->BSIM3ua1Given = TRUE; - break; - case BSIM3_MOD_UB: - mod->BSIM3ub = value->rValue; - mod->BSIM3ubGiven = TRUE; - break; - case BSIM3_MOD_UB1: - mod->BSIM3ub1 = value->rValue; - mod->BSIM3ub1Given = TRUE; - break; - case BSIM3_MOD_UC: - mod->BSIM3uc = value->rValue; - mod->BSIM3ucGiven = TRUE; - break; - case BSIM3_MOD_UC1: - mod->BSIM3uc1 = value->rValue; - mod->BSIM3uc1Given = TRUE; - break; - case BSIM3_MOD_U0 : - mod->BSIM3u0 = value->rValue; - mod->BSIM3u0Given = TRUE; - break; - case BSIM3_MOD_UTE : - mod->BSIM3ute = value->rValue; - mod->BSIM3uteGiven = TRUE; - break; - case BSIM3_MOD_VOFF: - mod->BSIM3voff = value->rValue; - mod->BSIM3voffGiven = TRUE; - break; - case BSIM3_MOD_DELTA : - mod->BSIM3delta = value->rValue; - mod->BSIM3deltaGiven = TRUE; - break; - case BSIM3_MOD_RDSW: - mod->BSIM3rdsw = value->rValue; - mod->BSIM3rdswGiven = TRUE; - break; - case BSIM3_MOD_PRWG: - mod->BSIM3prwg = value->rValue; - mod->BSIM3prwgGiven = TRUE; - break; - case BSIM3_MOD_PRWB: - mod->BSIM3prwb = value->rValue; - mod->BSIM3prwbGiven = TRUE; - break; - case BSIM3_MOD_PRT: - mod->BSIM3prt = value->rValue; - mod->BSIM3prtGiven = TRUE; - break; - case BSIM3_MOD_ETA0: - mod->BSIM3eta0 = value->rValue; - mod->BSIM3eta0Given = TRUE; - break; - case BSIM3_MOD_ETAB: - mod->BSIM3etab = value->rValue; - mod->BSIM3etabGiven = TRUE; - break; - case BSIM3_MOD_PCLM: - mod->BSIM3pclm = value->rValue; - mod->BSIM3pclmGiven = TRUE; - break; - case BSIM3_MOD_PDIBL1: - mod->BSIM3pdibl1 = value->rValue; - mod->BSIM3pdibl1Given = TRUE; - break; - case BSIM3_MOD_PDIBL2: - mod->BSIM3pdibl2 = value->rValue; - mod->BSIM3pdibl2Given = TRUE; - break; - case BSIM3_MOD_PDIBLB: - mod->BSIM3pdiblb = value->rValue; - mod->BSIM3pdiblbGiven = TRUE; - break; - case BSIM3_MOD_PSCBE1: - mod->BSIM3pscbe1 = value->rValue; - mod->BSIM3pscbe1Given = TRUE; - break; - case BSIM3_MOD_PSCBE2: - mod->BSIM3pscbe2 = value->rValue; - mod->BSIM3pscbe2Given = TRUE; - break; - case BSIM3_MOD_PVAG: - mod->BSIM3pvag = value->rValue; - mod->BSIM3pvagGiven = TRUE; - break; - case BSIM3_MOD_WR : - mod->BSIM3wr = value->rValue; - mod->BSIM3wrGiven = TRUE; - break; - case BSIM3_MOD_DWG : - mod->BSIM3dwg = value->rValue; - mod->BSIM3dwgGiven = TRUE; - break; - case BSIM3_MOD_DWB : - mod->BSIM3dwb = value->rValue; - mod->BSIM3dwbGiven = TRUE; - break; - case BSIM3_MOD_B0 : - mod->BSIM3b0 = value->rValue; - mod->BSIM3b0Given = TRUE; - break; - case BSIM3_MOD_B1 : - mod->BSIM3b1 = value->rValue; - mod->BSIM3b1Given = TRUE; - break; - case BSIM3_MOD_ALPHA0 : - mod->BSIM3alpha0 = value->rValue; - mod->BSIM3alpha0Given = TRUE; - break; - case BSIM3_MOD_ALPHA1 : - mod->BSIM3alpha1 = value->rValue; - mod->BSIM3alpha1Given = TRUE; - break; - case BSIM3_MOD_BETA0 : - mod->BSIM3beta0 = value->rValue; - mod->BSIM3beta0Given = TRUE; - break; - case BSIM3_MOD_IJTH : - mod->BSIM3ijth = value->rValue; - mod->BSIM3ijthGiven = TRUE; - break; - case BSIM3_MOD_VFB : - mod->BSIM3vfb = value->rValue; - mod->BSIM3vfbGiven = TRUE; - break; + case BSIM3_MOD_CIT: + mod->BSIM3cit = value->rValue; + mod->BSIM3citGiven = TRUE; + break; + case BSIM3_MOD_NFACTOR: + mod->BSIM3nfactor = value->rValue; + mod->BSIM3nfactorGiven = TRUE; + break; + case BSIM3_MOD_XJ: + mod->BSIM3xj = value->rValue; + mod->BSIM3xjGiven = TRUE; + break; + case BSIM3_MOD_VSAT: + mod->BSIM3vsat = value->rValue; + mod->BSIM3vsatGiven = TRUE; + break; + case BSIM3_MOD_A0: + mod->BSIM3a0 = value->rValue; + mod->BSIM3a0Given = TRUE; + break; - case BSIM3_MOD_ELM : - mod->BSIM3elm = value->rValue; - mod->BSIM3elmGiven = TRUE; - break; - case BSIM3_MOD_CGSL : - mod->BSIM3cgsl = value->rValue; - mod->BSIM3cgslGiven = TRUE; - break; - case BSIM3_MOD_CGDL : - mod->BSIM3cgdl = value->rValue; - mod->BSIM3cgdlGiven = TRUE; - break; - case BSIM3_MOD_CKAPPA : - mod->BSIM3ckappa = value->rValue; - mod->BSIM3ckappaGiven = TRUE; - break; - case BSIM3_MOD_CF : - mod->BSIM3cf = value->rValue; - mod->BSIM3cfGiven = TRUE; - break; - case BSIM3_MOD_CLC : - mod->BSIM3clc = value->rValue; - mod->BSIM3clcGiven = TRUE; - break; - case BSIM3_MOD_CLE : - mod->BSIM3cle = value->rValue; - mod->BSIM3cleGiven = TRUE; - break; - case BSIM3_MOD_DWC : - mod->BSIM3dwc = value->rValue; - mod->BSIM3dwcGiven = TRUE; - break; - case BSIM3_MOD_DLC : - mod->BSIM3dlc = value->rValue; - mod->BSIM3dlcGiven = TRUE; - break; - case BSIM3_MOD_VFBCV : - mod->BSIM3vfbcv = value->rValue; - mod->BSIM3vfbcvGiven = TRUE; - break; - case BSIM3_MOD_ACDE : - mod->BSIM3acde = value->rValue; - mod->BSIM3acdeGiven = TRUE; - break; - case BSIM3_MOD_MOIN : - mod->BSIM3moin = value->rValue; - mod->BSIM3moinGiven = TRUE; - break; - case BSIM3_MOD_NOFF : - mod->BSIM3noff = value->rValue; - mod->BSIM3noffGiven = TRUE; - break; - case BSIM3_MOD_VOFFCV : - mod->BSIM3voffcv = value->rValue; - mod->BSIM3voffcvGiven = TRUE; - break; - case BSIM3_MOD_TCJ : - mod->BSIM3tcj = value->rValue; - mod->BSIM3tcjGiven = TRUE; - break; - case BSIM3_MOD_TPB : - mod->BSIM3tpb = value->rValue; - mod->BSIM3tpbGiven = TRUE; - break; - case BSIM3_MOD_TCJSW : - mod->BSIM3tcjsw = value->rValue; - mod->BSIM3tcjswGiven = TRUE; - break; - case BSIM3_MOD_TPBSW : - mod->BSIM3tpbsw = value->rValue; - mod->BSIM3tpbswGiven = TRUE; - break; - case BSIM3_MOD_TCJSWG : - mod->BSIM3tcjswg = value->rValue; - mod->BSIM3tcjswgGiven = TRUE; - break; - case BSIM3_MOD_TPBSWG : - mod->BSIM3tpbswg = value->rValue; - mod->BSIM3tpbswgGiven = TRUE; - break; + case BSIM3_MOD_AGS: + mod->BSIM3ags = value->rValue; + mod->BSIM3agsGiven = TRUE; + break; - /* Length dependence */ - case BSIM3_MOD_LCDSC : - mod->BSIM3lcdsc = value->rValue; - mod->BSIM3lcdscGiven = TRUE; - break; + case BSIM3_MOD_A1: + mod->BSIM3a1 = value->rValue; + mod->BSIM3a1Given = TRUE; + break; + case BSIM3_MOD_A2: + mod->BSIM3a2 = value->rValue; + mod->BSIM3a2Given = TRUE; + break; + case BSIM3_MOD_AT: + mod->BSIM3at = value->rValue; + mod->BSIM3atGiven = TRUE; + break; + case BSIM3_MOD_KETA: + mod->BSIM3keta = value->rValue; + mod->BSIM3ketaGiven = TRUE; + break; + case BSIM3_MOD_NSUB: + mod->BSIM3nsub = value->rValue; + mod->BSIM3nsubGiven = TRUE; + break; + case BSIM3_MOD_NPEAK: + mod->BSIM3npeak = value->rValue; + mod->BSIM3npeakGiven = TRUE; + if (mod->BSIM3npeak > 1.0e20) + mod->BSIM3npeak *= 1.0e-6; + break; + case BSIM3_MOD_NGATE: + mod->BSIM3ngate = value->rValue; + mod->BSIM3ngateGiven = TRUE; + if (mod->BSIM3ngate > 1.0e23) + mod->BSIM3ngate *= 1.0e-6; + break; + case BSIM3_MOD_GAMMA1: + mod->BSIM3gamma1 = value->rValue; + mod->BSIM3gamma1Given = TRUE; + break; + case BSIM3_MOD_GAMMA2: + mod->BSIM3gamma2 = value->rValue; + mod->BSIM3gamma2Given = TRUE; + break; + case BSIM3_MOD_VBX: + mod->BSIM3vbx = value->rValue; + mod->BSIM3vbxGiven = TRUE; + break; + case BSIM3_MOD_VBM: + mod->BSIM3vbm = value->rValue; + mod->BSIM3vbmGiven = TRUE; + break; + case BSIM3_MOD_XT: + mod->BSIM3xt = value->rValue; + mod->BSIM3xtGiven = TRUE; + break; + case BSIM3_MOD_K1: + mod->BSIM3k1 = value->rValue; + mod->BSIM3k1Given = TRUE; + break; + case BSIM3_MOD_KT1: + mod->BSIM3kt1 = value->rValue; + mod->BSIM3kt1Given = TRUE; + break; + case BSIM3_MOD_KT1L: + mod->BSIM3kt1l = value->rValue; + mod->BSIM3kt1lGiven = TRUE; + break; + case BSIM3_MOD_KT2: + mod->BSIM3kt2 = value->rValue; + mod->BSIM3kt2Given = TRUE; + break; + case BSIM3_MOD_K2: + mod->BSIM3k2 = value->rValue; + mod->BSIM3k2Given = TRUE; + break; + case BSIM3_MOD_K3: + mod->BSIM3k3 = value->rValue; + mod->BSIM3k3Given = TRUE; + break; + case BSIM3_MOD_K3B: + mod->BSIM3k3b = value->rValue; + mod->BSIM3k3bGiven = TRUE; + break; + case BSIM3_MOD_NLX: + mod->BSIM3nlx = value->rValue; + mod->BSIM3nlxGiven = TRUE; + break; + case BSIM3_MOD_W0: + mod->BSIM3w0 = value->rValue; + mod->BSIM3w0Given = TRUE; + break; + case BSIM3_MOD_DVT0: + mod->BSIM3dvt0 = value->rValue; + mod->BSIM3dvt0Given = TRUE; + break; + case BSIM3_MOD_DVT1: + mod->BSIM3dvt1 = value->rValue; + mod->BSIM3dvt1Given = TRUE; + break; + case BSIM3_MOD_DVT2: + mod->BSIM3dvt2 = value->rValue; + mod->BSIM3dvt2Given = TRUE; + break; + case BSIM3_MOD_DVT0W: + mod->BSIM3dvt0w = value->rValue; + mod->BSIM3dvt0wGiven = TRUE; + break; + case BSIM3_MOD_DVT1W: + mod->BSIM3dvt1w = value->rValue; + mod->BSIM3dvt1wGiven = TRUE; + break; + case BSIM3_MOD_DVT2W: + mod->BSIM3dvt2w = value->rValue; + mod->BSIM3dvt2wGiven = TRUE; + break; + case BSIM3_MOD_DROUT: + mod->BSIM3drout = value->rValue; + mod->BSIM3droutGiven = TRUE; + break; + case BSIM3_MOD_DSUB: + mod->BSIM3dsub = value->rValue; + mod->BSIM3dsubGiven = TRUE; + break; + case BSIM3_MOD_VTH0: + mod->BSIM3vth0 = value->rValue; + mod->BSIM3vth0Given = TRUE; + break; + case BSIM3_MOD_UA: + mod->BSIM3ua = value->rValue; + mod->BSIM3uaGiven = TRUE; + break; + case BSIM3_MOD_UA1: + mod->BSIM3ua1 = value->rValue; + mod->BSIM3ua1Given = TRUE; + break; + case BSIM3_MOD_UB: + mod->BSIM3ub = value->rValue; + mod->BSIM3ubGiven = TRUE; + break; + case BSIM3_MOD_UB1: + mod->BSIM3ub1 = value->rValue; + mod->BSIM3ub1Given = TRUE; + break; + case BSIM3_MOD_UC: + mod->BSIM3uc = value->rValue; + mod->BSIM3ucGiven = TRUE; + break; + case BSIM3_MOD_UC1: + mod->BSIM3uc1 = value->rValue; + mod->BSIM3uc1Given = TRUE; + break; + case BSIM3_MOD_U0: + mod->BSIM3u0 = value->rValue; + mod->BSIM3u0Given = TRUE; + break; + case BSIM3_MOD_UTE: + mod->BSIM3ute = value->rValue; + mod->BSIM3uteGiven = TRUE; + break; + case BSIM3_MOD_VOFF: + mod->BSIM3voff = value->rValue; + mod->BSIM3voffGiven = TRUE; + break; + case BSIM3_MOD_DELTA: + mod->BSIM3delta = value->rValue; + mod->BSIM3deltaGiven = TRUE; + break; + case BSIM3_MOD_RDSW: + mod->BSIM3rdsw = value->rValue; + mod->BSIM3rdswGiven = TRUE; + break; + case BSIM3_MOD_PRWG: + mod->BSIM3prwg = value->rValue; + mod->BSIM3prwgGiven = TRUE; + break; + case BSIM3_MOD_PRWB: + mod->BSIM3prwb = value->rValue; + mod->BSIM3prwbGiven = TRUE; + break; + case BSIM3_MOD_PRT: + mod->BSIM3prt = value->rValue; + mod->BSIM3prtGiven = TRUE; + break; + case BSIM3_MOD_ETA0: + mod->BSIM3eta0 = value->rValue; + mod->BSIM3eta0Given = TRUE; + break; + case BSIM3_MOD_ETAB: + mod->BSIM3etab = value->rValue; + mod->BSIM3etabGiven = TRUE; + break; + case BSIM3_MOD_PCLM: + mod->BSIM3pclm = value->rValue; + mod->BSIM3pclmGiven = TRUE; + break; + case BSIM3_MOD_PDIBL1: + mod->BSIM3pdibl1 = value->rValue; + mod->BSIM3pdibl1Given = TRUE; + break; + case BSIM3_MOD_PDIBL2: + mod->BSIM3pdibl2 = value->rValue; + mod->BSIM3pdibl2Given = TRUE; + break; + case BSIM3_MOD_PDIBLB: + mod->BSIM3pdiblb = value->rValue; + mod->BSIM3pdiblbGiven = TRUE; + break; + case BSIM3_MOD_PSCBE1: + mod->BSIM3pscbe1 = value->rValue; + mod->BSIM3pscbe1Given = TRUE; + break; + case BSIM3_MOD_PSCBE2: + mod->BSIM3pscbe2 = value->rValue; + mod->BSIM3pscbe2Given = TRUE; + break; + case BSIM3_MOD_PVAG: + mod->BSIM3pvag = value->rValue; + mod->BSIM3pvagGiven = TRUE; + break; + case BSIM3_MOD_WR: + mod->BSIM3wr = value->rValue; + mod->BSIM3wrGiven = TRUE; + break; + case BSIM3_MOD_DWG: + mod->BSIM3dwg = value->rValue; + mod->BSIM3dwgGiven = TRUE; + break; + case BSIM3_MOD_DWB: + mod->BSIM3dwb = value->rValue; + mod->BSIM3dwbGiven = TRUE; + break; + case BSIM3_MOD_B0: + mod->BSIM3b0 = value->rValue; + mod->BSIM3b0Given = TRUE; + break; + case BSIM3_MOD_B1: + mod->BSIM3b1 = value->rValue; + mod->BSIM3b1Given = TRUE; + break; + case BSIM3_MOD_ALPHA0: + mod->BSIM3alpha0 = value->rValue; + mod->BSIM3alpha0Given = TRUE; + break; + case BSIM3_MOD_ALPHA1: + mod->BSIM3alpha1 = value->rValue; + mod->BSIM3alpha1Given = TRUE; + break; + case BSIM3_MOD_BETA0: + mod->BSIM3beta0 = value->rValue; + mod->BSIM3beta0Given = TRUE; + break; + case BSIM3_MOD_IJTH: + mod->BSIM3ijth = value->rValue; + mod->BSIM3ijthGiven = TRUE; + break; + case BSIM3_MOD_VFB: + mod->BSIM3vfb = value->rValue; + mod->BSIM3vfbGiven = TRUE; + break; + + case BSIM3_MOD_ELM: + mod->BSIM3elm = value->rValue; + mod->BSIM3elmGiven = TRUE; + break; + case BSIM3_MOD_CGSL: + mod->BSIM3cgsl = value->rValue; + mod->BSIM3cgslGiven = TRUE; + break; + case BSIM3_MOD_CGDL: + mod->BSIM3cgdl = value->rValue; + mod->BSIM3cgdlGiven = TRUE; + break; + case BSIM3_MOD_CKAPPA: + mod->BSIM3ckappa = value->rValue; + mod->BSIM3ckappaGiven = TRUE; + break; + case BSIM3_MOD_CF: + mod->BSIM3cf = value->rValue; + mod->BSIM3cfGiven = TRUE; + break; + case BSIM3_MOD_CLC: + mod->BSIM3clc = value->rValue; + mod->BSIM3clcGiven = TRUE; + break; + case BSIM3_MOD_CLE: + mod->BSIM3cle = value->rValue; + mod->BSIM3cleGiven = TRUE; + break; + case BSIM3_MOD_DWC: + mod->BSIM3dwc = value->rValue; + mod->BSIM3dwcGiven = TRUE; + break; + case BSIM3_MOD_DLC: + mod->BSIM3dlc = value->rValue; + mod->BSIM3dlcGiven = TRUE; + break; + case BSIM3_MOD_VFBCV: + mod->BSIM3vfbcv = value->rValue; + mod->BSIM3vfbcvGiven = TRUE; + break; + case BSIM3_MOD_ACDE: + mod->BSIM3acde = value->rValue; + mod->BSIM3acdeGiven = TRUE; + break; + case BSIM3_MOD_MOIN: + mod->BSIM3moin = value->rValue; + mod->BSIM3moinGiven = TRUE; + break; + case BSIM3_MOD_NOFF: + mod->BSIM3noff = value->rValue; + mod->BSIM3noffGiven = TRUE; + break; + case BSIM3_MOD_VOFFCV: + mod->BSIM3voffcv = value->rValue; + mod->BSIM3voffcvGiven = TRUE; + break; + case BSIM3_MOD_TCJ: + mod->BSIM3tcj = value->rValue; + mod->BSIM3tcjGiven = TRUE; + break; + case BSIM3_MOD_TPB: + mod->BSIM3tpb = value->rValue; + mod->BSIM3tpbGiven = TRUE; + break; + case BSIM3_MOD_TCJSW: + mod->BSIM3tcjsw = value->rValue; + mod->BSIM3tcjswGiven = TRUE; + break; + case BSIM3_MOD_TPBSW: + mod->BSIM3tpbsw = value->rValue; + mod->BSIM3tpbswGiven = TRUE; + break; + case BSIM3_MOD_TCJSWG: + mod->BSIM3tcjswg = value->rValue; + mod->BSIM3tcjswgGiven = TRUE; + break; + case BSIM3_MOD_TPBSWG: + mod->BSIM3tpbswg = value->rValue; + mod->BSIM3tpbswgGiven = TRUE; + break; + + /* Length dependence */ + case BSIM3_MOD_LCDSC: + mod->BSIM3lcdsc = value->rValue; + mod->BSIM3lcdscGiven = TRUE; + break; - case BSIM3_MOD_LCDSCB : - mod->BSIM3lcdscb = value->rValue; - mod->BSIM3lcdscbGiven = TRUE; - break; - case BSIM3_MOD_LCDSCD : - mod->BSIM3lcdscd = value->rValue; - mod->BSIM3lcdscdGiven = TRUE; - break; - case BSIM3_MOD_LCIT : - mod->BSIM3lcit = value->rValue; - mod->BSIM3lcitGiven = TRUE; - break; - case BSIM3_MOD_LNFACTOR : - mod->BSIM3lnfactor = value->rValue; - mod->BSIM3lnfactorGiven = TRUE; - break; - case BSIM3_MOD_LXJ: - mod->BSIM3lxj = value->rValue; - mod->BSIM3lxjGiven = TRUE; - break; - case BSIM3_MOD_LVSAT: - mod->BSIM3lvsat = value->rValue; - mod->BSIM3lvsatGiven = TRUE; - break; - - - case BSIM3_MOD_LA0: - mod->BSIM3la0 = value->rValue; - mod->BSIM3la0Given = TRUE; - break; - case BSIM3_MOD_LAGS: - mod->BSIM3lags = value->rValue; - mod->BSIM3lagsGiven = TRUE; - break; - case BSIM3_MOD_LA1: - mod->BSIM3la1 = value->rValue; - mod->BSIM3la1Given = TRUE; - break; - case BSIM3_MOD_LA2: - mod->BSIM3la2 = value->rValue; - mod->BSIM3la2Given = TRUE; - break; - case BSIM3_MOD_LAT: - mod->BSIM3lat = value->rValue; - mod->BSIM3latGiven = TRUE; - break; - case BSIM3_MOD_LKETA: - mod->BSIM3lketa = value->rValue; - mod->BSIM3lketaGiven = TRUE; - break; - case BSIM3_MOD_LNSUB: - mod->BSIM3lnsub = value->rValue; - mod->BSIM3lnsubGiven = TRUE; - break; - case BSIM3_MOD_LNPEAK: - mod->BSIM3lnpeak = value->rValue; - mod->BSIM3lnpeakGiven = TRUE; - if (mod->BSIM3lnpeak > 1.0e20) - mod->BSIM3lnpeak *= 1.0e-6; - break; - case BSIM3_MOD_LNGATE: - mod->BSIM3lngate = value->rValue; - mod->BSIM3lngateGiven = TRUE; - if (mod->BSIM3lngate > 1.0e23) - mod->BSIM3lngate *= 1.0e-6; - break; - case BSIM3_MOD_LGAMMA1: - mod->BSIM3lgamma1 = value->rValue; - mod->BSIM3lgamma1Given = TRUE; - break; - case BSIM3_MOD_LGAMMA2: - mod->BSIM3lgamma2 = value->rValue; - mod->BSIM3lgamma2Given = TRUE; - break; - case BSIM3_MOD_LVBX: - mod->BSIM3lvbx = value->rValue; - mod->BSIM3lvbxGiven = TRUE; - break; - case BSIM3_MOD_LVBM: - mod->BSIM3lvbm = value->rValue; - mod->BSIM3lvbmGiven = TRUE; - break; - case BSIM3_MOD_LXT: - mod->BSIM3lxt = value->rValue; - mod->BSIM3lxtGiven = TRUE; - break; - case BSIM3_MOD_LK1: - mod->BSIM3lk1 = value->rValue; - mod->BSIM3lk1Given = TRUE; - break; - case BSIM3_MOD_LKT1: - mod->BSIM3lkt1 = value->rValue; - mod->BSIM3lkt1Given = TRUE; - break; - case BSIM3_MOD_LKT1L: - mod->BSIM3lkt1l = value->rValue; - mod->BSIM3lkt1lGiven = TRUE; - break; - case BSIM3_MOD_LKT2: - mod->BSIM3lkt2 = value->rValue; - mod->BSIM3lkt2Given = TRUE; - break; - case BSIM3_MOD_LK2: - mod->BSIM3lk2 = value->rValue; - mod->BSIM3lk2Given = TRUE; - break; - case BSIM3_MOD_LK3: - mod->BSIM3lk3 = value->rValue; - mod->BSIM3lk3Given = TRUE; - break; - case BSIM3_MOD_LK3B: - mod->BSIM3lk3b = value->rValue; - mod->BSIM3lk3bGiven = TRUE; - break; - case BSIM3_MOD_LNLX: - mod->BSIM3lnlx = value->rValue; - mod->BSIM3lnlxGiven = TRUE; - break; - case BSIM3_MOD_LW0: - mod->BSIM3lw0 = value->rValue; - mod->BSIM3lw0Given = TRUE; - break; - case BSIM3_MOD_LDVT0: - mod->BSIM3ldvt0 = value->rValue; - mod->BSIM3ldvt0Given = TRUE; - break; - case BSIM3_MOD_LDVT1: - mod->BSIM3ldvt1 = value->rValue; - mod->BSIM3ldvt1Given = TRUE; - break; - case BSIM3_MOD_LDVT2: - mod->BSIM3ldvt2 = value->rValue; - mod->BSIM3ldvt2Given = TRUE; - break; - case BSIM3_MOD_LDVT0W: - mod->BSIM3ldvt0w = value->rValue; - mod->BSIM3ldvt0wGiven = TRUE; - break; - case BSIM3_MOD_LDVT1W: - mod->BSIM3ldvt1w = value->rValue; - mod->BSIM3ldvt1wGiven = TRUE; - break; - case BSIM3_MOD_LDVT2W: - mod->BSIM3ldvt2w = value->rValue; - mod->BSIM3ldvt2wGiven = TRUE; - break; - case BSIM3_MOD_LDROUT: - mod->BSIM3ldrout = value->rValue; - mod->BSIM3ldroutGiven = TRUE; - break; - case BSIM3_MOD_LDSUB: - mod->BSIM3ldsub = value->rValue; - mod->BSIM3ldsubGiven = TRUE; - break; - case BSIM3_MOD_LVTH0: - mod->BSIM3lvth0 = value->rValue; - mod->BSIM3lvth0Given = TRUE; - break; - case BSIM3_MOD_LUA: - mod->BSIM3lua = value->rValue; - mod->BSIM3luaGiven = TRUE; - break; - case BSIM3_MOD_LUA1: - mod->BSIM3lua1 = value->rValue; - mod->BSIM3lua1Given = TRUE; - break; - case BSIM3_MOD_LUB: - mod->BSIM3lub = value->rValue; - mod->BSIM3lubGiven = TRUE; - break; - case BSIM3_MOD_LUB1: - mod->BSIM3lub1 = value->rValue; - mod->BSIM3lub1Given = TRUE; - break; - case BSIM3_MOD_LUC: - mod->BSIM3luc = value->rValue; - mod->BSIM3lucGiven = TRUE; - break; - case BSIM3_MOD_LUC1: - mod->BSIM3luc1 = value->rValue; - mod->BSIM3luc1Given = TRUE; - break; - case BSIM3_MOD_LU0 : - mod->BSIM3lu0 = value->rValue; - mod->BSIM3lu0Given = TRUE; - break; - case BSIM3_MOD_LUTE : - mod->BSIM3lute = value->rValue; - mod->BSIM3luteGiven = TRUE; - break; - case BSIM3_MOD_LVOFF: - mod->BSIM3lvoff = value->rValue; - mod->BSIM3lvoffGiven = TRUE; - break; - case BSIM3_MOD_LDELTA : - mod->BSIM3ldelta = value->rValue; - mod->BSIM3ldeltaGiven = TRUE; - break; - case BSIM3_MOD_LRDSW: - mod->BSIM3lrdsw = value->rValue; - mod->BSIM3lrdswGiven = TRUE; - break; - case BSIM3_MOD_LPRWB: - mod->BSIM3lprwb = value->rValue; - mod->BSIM3lprwbGiven = TRUE; - break; - case BSIM3_MOD_LPRWG: - mod->BSIM3lprwg = value->rValue; - mod->BSIM3lprwgGiven = TRUE; - break; - case BSIM3_MOD_LPRT: - mod->BSIM3lprt = value->rValue; - mod->BSIM3lprtGiven = TRUE; - break; - case BSIM3_MOD_LETA0: - mod->BSIM3leta0 = value->rValue; - mod->BSIM3leta0Given = TRUE; - break; - case BSIM3_MOD_LETAB: - mod->BSIM3letab = value->rValue; - mod->BSIM3letabGiven = TRUE; - break; - case BSIM3_MOD_LPCLM: - mod->BSIM3lpclm = value->rValue; - mod->BSIM3lpclmGiven = TRUE; - break; - case BSIM3_MOD_LPDIBL1: - mod->BSIM3lpdibl1 = value->rValue; - mod->BSIM3lpdibl1Given = TRUE; - break; - case BSIM3_MOD_LPDIBL2: - mod->BSIM3lpdibl2 = value->rValue; - mod->BSIM3lpdibl2Given = TRUE; - break; - case BSIM3_MOD_LPDIBLB: - mod->BSIM3lpdiblb = value->rValue; - mod->BSIM3lpdiblbGiven = TRUE; - break; - case BSIM3_MOD_LPSCBE1: - mod->BSIM3lpscbe1 = value->rValue; - mod->BSIM3lpscbe1Given = TRUE; - break; - case BSIM3_MOD_LPSCBE2: - mod->BSIM3lpscbe2 = value->rValue; - mod->BSIM3lpscbe2Given = TRUE; - break; - case BSIM3_MOD_LPVAG: - mod->BSIM3lpvag = value->rValue; - mod->BSIM3lpvagGiven = TRUE; - break; - case BSIM3_MOD_LWR : - mod->BSIM3lwr = value->rValue; - mod->BSIM3lwrGiven = TRUE; - break; - case BSIM3_MOD_LDWG : - mod->BSIM3ldwg = value->rValue; - mod->BSIM3ldwgGiven = TRUE; - break; - case BSIM3_MOD_LDWB : - mod->BSIM3ldwb = value->rValue; - mod->BSIM3ldwbGiven = TRUE; - break; - case BSIM3_MOD_LB0 : - mod->BSIM3lb0 = value->rValue; - mod->BSIM3lb0Given = TRUE; - break; - case BSIM3_MOD_LB1 : - mod->BSIM3lb1 = value->rValue; - mod->BSIM3lb1Given = TRUE; - break; - case BSIM3_MOD_LALPHA0 : - mod->BSIM3lalpha0 = value->rValue; - mod->BSIM3lalpha0Given = TRUE; - break; - case BSIM3_MOD_LALPHA1 : - mod->BSIM3lalpha1 = value->rValue; - mod->BSIM3lalpha1Given = TRUE; - break; - case BSIM3_MOD_LBETA0 : - mod->BSIM3lbeta0 = value->rValue; - mod->BSIM3lbeta0Given = TRUE; - break; - case BSIM3_MOD_LVFB : - mod->BSIM3lvfb = value->rValue; - mod->BSIM3lvfbGiven = TRUE; - break; - - case BSIM3_MOD_LELM : - mod->BSIM3lelm = value->rValue; - mod->BSIM3lelmGiven = TRUE; - break; - case BSIM3_MOD_LCGSL : - mod->BSIM3lcgsl = value->rValue; - mod->BSIM3lcgslGiven = TRUE; - break; - case BSIM3_MOD_LCGDL : - mod->BSIM3lcgdl = value->rValue; - mod->BSIM3lcgdlGiven = TRUE; - break; - case BSIM3_MOD_LCKAPPA : - mod->BSIM3lckappa = value->rValue; - mod->BSIM3lckappaGiven = TRUE; - break; - case BSIM3_MOD_LCF : - mod->BSIM3lcf = value->rValue; - mod->BSIM3lcfGiven = TRUE; - break; - case BSIM3_MOD_LCLC : - mod->BSIM3lclc = value->rValue; - mod->BSIM3lclcGiven = TRUE; - break; - case BSIM3_MOD_LCLE : - mod->BSIM3lcle = value->rValue; - mod->BSIM3lcleGiven = TRUE; - break; - case BSIM3_MOD_LVFBCV : - mod->BSIM3lvfbcv = value->rValue; - mod->BSIM3lvfbcvGiven = TRUE; - break; - case BSIM3_MOD_LACDE : - mod->BSIM3lacde = value->rValue; - mod->BSIM3lacdeGiven = TRUE; - break; - case BSIM3_MOD_LMOIN : - mod->BSIM3lmoin = value->rValue; - mod->BSIM3lmoinGiven = TRUE; - break; - case BSIM3_MOD_LNOFF : - mod->BSIM3lnoff = value->rValue; - mod->BSIM3lnoffGiven = TRUE; - break; - case BSIM3_MOD_LVOFFCV : - mod->BSIM3lvoffcv = value->rValue; - mod->BSIM3lvoffcvGiven = TRUE; - break; - - /* Width dependence */ - case BSIM3_MOD_WCDSC : - mod->BSIM3wcdsc = value->rValue; - mod->BSIM3wcdscGiven = TRUE; - break; - - - case BSIM3_MOD_WCDSCB : - mod->BSIM3wcdscb = value->rValue; - mod->BSIM3wcdscbGiven = TRUE; - break; - case BSIM3_MOD_WCDSCD : - mod->BSIM3wcdscd = value->rValue; - mod->BSIM3wcdscdGiven = TRUE; - break; - case BSIM3_MOD_WCIT : - mod->BSIM3wcit = value->rValue; - mod->BSIM3wcitGiven = TRUE; - break; - case BSIM3_MOD_WNFACTOR : - mod->BSIM3wnfactor = value->rValue; - mod->BSIM3wnfactorGiven = TRUE; - break; - case BSIM3_MOD_WXJ: - mod->BSIM3wxj = value->rValue; - mod->BSIM3wxjGiven = TRUE; - break; - case BSIM3_MOD_WVSAT: - mod->BSIM3wvsat = value->rValue; - mod->BSIM3wvsatGiven = TRUE; - break; + case BSIM3_MOD_LCDSCB: + mod->BSIM3lcdscb = value->rValue; + mod->BSIM3lcdscbGiven = TRUE; + break; + case BSIM3_MOD_LCDSCD: + mod->BSIM3lcdscd = value->rValue; + mod->BSIM3lcdscdGiven = TRUE; + break; + case BSIM3_MOD_LCIT: + mod->BSIM3lcit = value->rValue; + mod->BSIM3lcitGiven = TRUE; + break; + case BSIM3_MOD_LNFACTOR: + mod->BSIM3lnfactor = value->rValue; + mod->BSIM3lnfactorGiven = TRUE; + break; + case BSIM3_MOD_LXJ: + mod->BSIM3lxj = value->rValue; + mod->BSIM3lxjGiven = TRUE; + break; + case BSIM3_MOD_LVSAT: + mod->BSIM3lvsat = value->rValue; + mod->BSIM3lvsatGiven = TRUE; + break; - case BSIM3_MOD_WA0: - mod->BSIM3wa0 = value->rValue; - mod->BSIM3wa0Given = TRUE; - break; - case BSIM3_MOD_WAGS: - mod->BSIM3wags = value->rValue; - mod->BSIM3wagsGiven = TRUE; - break; - case BSIM3_MOD_WA1: - mod->BSIM3wa1 = value->rValue; - mod->BSIM3wa1Given = TRUE; - break; - case BSIM3_MOD_WA2: - mod->BSIM3wa2 = value->rValue; - mod->BSIM3wa2Given = TRUE; - break; - case BSIM3_MOD_WAT: - mod->BSIM3wat = value->rValue; - mod->BSIM3watGiven = TRUE; - break; - case BSIM3_MOD_WKETA: - mod->BSIM3wketa = value->rValue; - mod->BSIM3wketaGiven = TRUE; - break; - case BSIM3_MOD_WNSUB: - mod->BSIM3wnsub = value->rValue; - mod->BSIM3wnsubGiven = TRUE; - break; - case BSIM3_MOD_WNPEAK: - mod->BSIM3wnpeak = value->rValue; - mod->BSIM3wnpeakGiven = TRUE; - if (mod->BSIM3wnpeak > 1.0e20) - mod->BSIM3wnpeak *= 1.0e-6; - break; - case BSIM3_MOD_WNGATE: - mod->BSIM3wngate = value->rValue; - mod->BSIM3wngateGiven = TRUE; - if (mod->BSIM3wngate > 1.0e23) - mod->BSIM3wngate *= 1.0e-6; - break; - case BSIM3_MOD_WGAMMA1: - mod->BSIM3wgamma1 = value->rValue; - mod->BSIM3wgamma1Given = TRUE; - break; - case BSIM3_MOD_WGAMMA2: - mod->BSIM3wgamma2 = value->rValue; - mod->BSIM3wgamma2Given = TRUE; - break; - case BSIM3_MOD_WVBX: - mod->BSIM3wvbx = value->rValue; - mod->BSIM3wvbxGiven = TRUE; - break; - case BSIM3_MOD_WVBM: - mod->BSIM3wvbm = value->rValue; - mod->BSIM3wvbmGiven = TRUE; - break; - case BSIM3_MOD_WXT: - mod->BSIM3wxt = value->rValue; - mod->BSIM3wxtGiven = TRUE; - break; - case BSIM3_MOD_WK1: - mod->BSIM3wk1 = value->rValue; - mod->BSIM3wk1Given = TRUE; - break; - case BSIM3_MOD_WKT1: - mod->BSIM3wkt1 = value->rValue; - mod->BSIM3wkt1Given = TRUE; - break; - case BSIM3_MOD_WKT1L: - mod->BSIM3wkt1l = value->rValue; - mod->BSIM3wkt1lGiven = TRUE; - break; - case BSIM3_MOD_WKT2: - mod->BSIM3wkt2 = value->rValue; - mod->BSIM3wkt2Given = TRUE; - break; - case BSIM3_MOD_WK2: - mod->BSIM3wk2 = value->rValue; - mod->BSIM3wk2Given = TRUE; - break; - case BSIM3_MOD_WK3: - mod->BSIM3wk3 = value->rValue; - mod->BSIM3wk3Given = TRUE; - break; - case BSIM3_MOD_WK3B: - mod->BSIM3wk3b = value->rValue; - mod->BSIM3wk3bGiven = TRUE; - break; - case BSIM3_MOD_WNLX: - mod->BSIM3wnlx = value->rValue; - mod->BSIM3wnlxGiven = TRUE; - break; - case BSIM3_MOD_WW0: - mod->BSIM3ww0 = value->rValue; - mod->BSIM3ww0Given = TRUE; - break; - case BSIM3_MOD_WDVT0: - mod->BSIM3wdvt0 = value->rValue; - mod->BSIM3wdvt0Given = TRUE; - break; - case BSIM3_MOD_WDVT1: - mod->BSIM3wdvt1 = value->rValue; - mod->BSIM3wdvt1Given = TRUE; - break; - case BSIM3_MOD_WDVT2: - mod->BSIM3wdvt2 = value->rValue; - mod->BSIM3wdvt2Given = TRUE; - break; - case BSIM3_MOD_WDVT0W: - mod->BSIM3wdvt0w = value->rValue; - mod->BSIM3wdvt0wGiven = TRUE; - break; - case BSIM3_MOD_WDVT1W: - mod->BSIM3wdvt1w = value->rValue; - mod->BSIM3wdvt1wGiven = TRUE; - break; - case BSIM3_MOD_WDVT2W: - mod->BSIM3wdvt2w = value->rValue; - mod->BSIM3wdvt2wGiven = TRUE; - break; - case BSIM3_MOD_WDROUT: - mod->BSIM3wdrout = value->rValue; - mod->BSIM3wdroutGiven = TRUE; - break; - case BSIM3_MOD_WDSUB: - mod->BSIM3wdsub = value->rValue; - mod->BSIM3wdsubGiven = TRUE; - break; - case BSIM3_MOD_WVTH0: - mod->BSIM3wvth0 = value->rValue; - mod->BSIM3wvth0Given = TRUE; - break; - case BSIM3_MOD_WUA: - mod->BSIM3wua = value->rValue; - mod->BSIM3wuaGiven = TRUE; - break; - case BSIM3_MOD_WUA1: - mod->BSIM3wua1 = value->rValue; - mod->BSIM3wua1Given = TRUE; - break; - case BSIM3_MOD_WUB: - mod->BSIM3wub = value->rValue; - mod->BSIM3wubGiven = TRUE; - break; - case BSIM3_MOD_WUB1: - mod->BSIM3wub1 = value->rValue; - mod->BSIM3wub1Given = TRUE; - break; - case BSIM3_MOD_WUC: - mod->BSIM3wuc = value->rValue; - mod->BSIM3wucGiven = TRUE; - break; - case BSIM3_MOD_WUC1: - mod->BSIM3wuc1 = value->rValue; - mod->BSIM3wuc1Given = TRUE; - break; - case BSIM3_MOD_WU0 : - mod->BSIM3wu0 = value->rValue; - mod->BSIM3wu0Given = TRUE; - break; - case BSIM3_MOD_WUTE : - mod->BSIM3wute = value->rValue; - mod->BSIM3wuteGiven = TRUE; - break; - case BSIM3_MOD_WVOFF: - mod->BSIM3wvoff = value->rValue; - mod->BSIM3wvoffGiven = TRUE; - break; - case BSIM3_MOD_WDELTA : - mod->BSIM3wdelta = value->rValue; - mod->BSIM3wdeltaGiven = TRUE; - break; - case BSIM3_MOD_WRDSW: - mod->BSIM3wrdsw = value->rValue; - mod->BSIM3wrdswGiven = TRUE; - break; - case BSIM3_MOD_WPRWB: - mod->BSIM3wprwb = value->rValue; - mod->BSIM3wprwbGiven = TRUE; - break; - case BSIM3_MOD_WPRWG: - mod->BSIM3wprwg = value->rValue; - mod->BSIM3wprwgGiven = TRUE; - break; - case BSIM3_MOD_WPRT: - mod->BSIM3wprt = value->rValue; - mod->BSIM3wprtGiven = TRUE; - break; - case BSIM3_MOD_WETA0: - mod->BSIM3weta0 = value->rValue; - mod->BSIM3weta0Given = TRUE; - break; - case BSIM3_MOD_WETAB: - mod->BSIM3wetab = value->rValue; - mod->BSIM3wetabGiven = TRUE; - break; - case BSIM3_MOD_WPCLM: - mod->BSIM3wpclm = value->rValue; - mod->BSIM3wpclmGiven = TRUE; - break; - case BSIM3_MOD_WPDIBL1: - mod->BSIM3wpdibl1 = value->rValue; - mod->BSIM3wpdibl1Given = TRUE; - break; - case BSIM3_MOD_WPDIBL2: - mod->BSIM3wpdibl2 = value->rValue; - mod->BSIM3wpdibl2Given = TRUE; - break; - case BSIM3_MOD_WPDIBLB: - mod->BSIM3wpdiblb = value->rValue; - mod->BSIM3wpdiblbGiven = TRUE; - break; - case BSIM3_MOD_WPSCBE1: - mod->BSIM3wpscbe1 = value->rValue; - mod->BSIM3wpscbe1Given = TRUE; - break; - case BSIM3_MOD_WPSCBE2: - mod->BSIM3wpscbe2 = value->rValue; - mod->BSIM3wpscbe2Given = TRUE; - break; - case BSIM3_MOD_WPVAG: - mod->BSIM3wpvag = value->rValue; - mod->BSIM3wpvagGiven = TRUE; - break; - case BSIM3_MOD_WWR : - mod->BSIM3wwr = value->rValue; - mod->BSIM3wwrGiven = TRUE; - break; - case BSIM3_MOD_WDWG : - mod->BSIM3wdwg = value->rValue; - mod->BSIM3wdwgGiven = TRUE; - break; - case BSIM3_MOD_WDWB : - mod->BSIM3wdwb = value->rValue; - mod->BSIM3wdwbGiven = TRUE; - break; - case BSIM3_MOD_WB0 : - mod->BSIM3wb0 = value->rValue; - mod->BSIM3wb0Given = TRUE; - break; - case BSIM3_MOD_WB1 : - mod->BSIM3wb1 = value->rValue; - mod->BSIM3wb1Given = TRUE; - break; - case BSIM3_MOD_WALPHA0 : - mod->BSIM3walpha0 = value->rValue; - mod->BSIM3walpha0Given = TRUE; - break; - case BSIM3_MOD_WALPHA1 : - mod->BSIM3walpha1 = value->rValue; - mod->BSIM3walpha1Given = TRUE; - break; - case BSIM3_MOD_WBETA0 : - mod->BSIM3wbeta0 = value->rValue; - mod->BSIM3wbeta0Given = TRUE; - break; - case BSIM3_MOD_WVFB : - mod->BSIM3wvfb = value->rValue; - mod->BSIM3wvfbGiven = TRUE; - break; + case BSIM3_MOD_LA0: + mod->BSIM3la0 = value->rValue; + mod->BSIM3la0Given = TRUE; + break; + case BSIM3_MOD_LAGS: + mod->BSIM3lags = value->rValue; + mod->BSIM3lagsGiven = TRUE; + break; + case BSIM3_MOD_LA1: + mod->BSIM3la1 = value->rValue; + mod->BSIM3la1Given = TRUE; + break; + case BSIM3_MOD_LA2: + mod->BSIM3la2 = value->rValue; + mod->BSIM3la2Given = TRUE; + break; + case BSIM3_MOD_LAT: + mod->BSIM3lat = value->rValue; + mod->BSIM3latGiven = TRUE; + break; + case BSIM3_MOD_LKETA: + mod->BSIM3lketa = value->rValue; + mod->BSIM3lketaGiven = TRUE; + break; + case BSIM3_MOD_LNSUB: + mod->BSIM3lnsub = value->rValue; + mod->BSIM3lnsubGiven = TRUE; + break; + case BSIM3_MOD_LNPEAK: + mod->BSIM3lnpeak = value->rValue; + mod->BSIM3lnpeakGiven = TRUE; + if (mod->BSIM3lnpeak > 1.0e20) + mod->BSIM3lnpeak *= 1.0e-6; + break; + case BSIM3_MOD_LNGATE: + mod->BSIM3lngate = value->rValue; + mod->BSIM3lngateGiven = TRUE; + if (mod->BSIM3lngate > 1.0e23) + mod->BSIM3lngate *= 1.0e-6; + break; + case BSIM3_MOD_LGAMMA1: + mod->BSIM3lgamma1 = value->rValue; + mod->BSIM3lgamma1Given = TRUE; + break; + case BSIM3_MOD_LGAMMA2: + mod->BSIM3lgamma2 = value->rValue; + mod->BSIM3lgamma2Given = TRUE; + break; + case BSIM3_MOD_LVBX: + mod->BSIM3lvbx = value->rValue; + mod->BSIM3lvbxGiven = TRUE; + break; + case BSIM3_MOD_LVBM: + mod->BSIM3lvbm = value->rValue; + mod->BSIM3lvbmGiven = TRUE; + break; + case BSIM3_MOD_LXT: + mod->BSIM3lxt = value->rValue; + mod->BSIM3lxtGiven = TRUE; + break; + case BSIM3_MOD_LK1: + mod->BSIM3lk1 = value->rValue; + mod->BSIM3lk1Given = TRUE; + break; + case BSIM3_MOD_LKT1: + mod->BSIM3lkt1 = value->rValue; + mod->BSIM3lkt1Given = TRUE; + break; + case BSIM3_MOD_LKT1L: + mod->BSIM3lkt1l = value->rValue; + mod->BSIM3lkt1lGiven = TRUE; + break; + case BSIM3_MOD_LKT2: + mod->BSIM3lkt2 = value->rValue; + mod->BSIM3lkt2Given = TRUE; + break; + case BSIM3_MOD_LK2: + mod->BSIM3lk2 = value->rValue; + mod->BSIM3lk2Given = TRUE; + break; + case BSIM3_MOD_LK3: + mod->BSIM3lk3 = value->rValue; + mod->BSIM3lk3Given = TRUE; + break; + case BSIM3_MOD_LK3B: + mod->BSIM3lk3b = value->rValue; + mod->BSIM3lk3bGiven = TRUE; + break; + case BSIM3_MOD_LNLX: + mod->BSIM3lnlx = value->rValue; + mod->BSIM3lnlxGiven = TRUE; + break; + case BSIM3_MOD_LW0: + mod->BSIM3lw0 = value->rValue; + mod->BSIM3lw0Given = TRUE; + break; + case BSIM3_MOD_LDVT0: + mod->BSIM3ldvt0 = value->rValue; + mod->BSIM3ldvt0Given = TRUE; + break; + case BSIM3_MOD_LDVT1: + mod->BSIM3ldvt1 = value->rValue; + mod->BSIM3ldvt1Given = TRUE; + break; + case BSIM3_MOD_LDVT2: + mod->BSIM3ldvt2 = value->rValue; + mod->BSIM3ldvt2Given = TRUE; + break; + case BSIM3_MOD_LDVT0W: + mod->BSIM3ldvt0w = value->rValue; + mod->BSIM3ldvt0wGiven = TRUE; + break; + case BSIM3_MOD_LDVT1W: + mod->BSIM3ldvt1w = value->rValue; + mod->BSIM3ldvt1wGiven = TRUE; + break; + case BSIM3_MOD_LDVT2W: + mod->BSIM3ldvt2w = value->rValue; + mod->BSIM3ldvt2wGiven = TRUE; + break; + case BSIM3_MOD_LDROUT: + mod->BSIM3ldrout = value->rValue; + mod->BSIM3ldroutGiven = TRUE; + break; + case BSIM3_MOD_LDSUB: + mod->BSIM3ldsub = value->rValue; + mod->BSIM3ldsubGiven = TRUE; + break; + case BSIM3_MOD_LVTH0: + mod->BSIM3lvth0 = value->rValue; + mod->BSIM3lvth0Given = TRUE; + break; + case BSIM3_MOD_LUA: + mod->BSIM3lua = value->rValue; + mod->BSIM3luaGiven = TRUE; + break; + case BSIM3_MOD_LUA1: + mod->BSIM3lua1 = value->rValue; + mod->BSIM3lua1Given = TRUE; + break; + case BSIM3_MOD_LUB: + mod->BSIM3lub = value->rValue; + mod->BSIM3lubGiven = TRUE; + break; + case BSIM3_MOD_LUB1: + mod->BSIM3lub1 = value->rValue; + mod->BSIM3lub1Given = TRUE; + break; + case BSIM3_MOD_LUC: + mod->BSIM3luc = value->rValue; + mod->BSIM3lucGiven = TRUE; + break; + case BSIM3_MOD_LUC1: + mod->BSIM3luc1 = value->rValue; + mod->BSIM3luc1Given = TRUE; + break; + case BSIM3_MOD_LU0: + mod->BSIM3lu0 = value->rValue; + mod->BSIM3lu0Given = TRUE; + break; + case BSIM3_MOD_LUTE: + mod->BSIM3lute = value->rValue; + mod->BSIM3luteGiven = TRUE; + break; + case BSIM3_MOD_LVOFF: + mod->BSIM3lvoff = value->rValue; + mod->BSIM3lvoffGiven = TRUE; + break; + case BSIM3_MOD_LDELTA: + mod->BSIM3ldelta = value->rValue; + mod->BSIM3ldeltaGiven = TRUE; + break; + case BSIM3_MOD_LRDSW: + mod->BSIM3lrdsw = value->rValue; + mod->BSIM3lrdswGiven = TRUE; + break; + case BSIM3_MOD_LPRWB: + mod->BSIM3lprwb = value->rValue; + mod->BSIM3lprwbGiven = TRUE; + break; + case BSIM3_MOD_LPRWG: + mod->BSIM3lprwg = value->rValue; + mod->BSIM3lprwgGiven = TRUE; + break; + case BSIM3_MOD_LPRT: + mod->BSIM3lprt = value->rValue; + mod->BSIM3lprtGiven = TRUE; + break; + case BSIM3_MOD_LETA0: + mod->BSIM3leta0 = value->rValue; + mod->BSIM3leta0Given = TRUE; + break; + case BSIM3_MOD_LETAB: + mod->BSIM3letab = value->rValue; + mod->BSIM3letabGiven = TRUE; + break; + case BSIM3_MOD_LPCLM: + mod->BSIM3lpclm = value->rValue; + mod->BSIM3lpclmGiven = TRUE; + break; + case BSIM3_MOD_LPDIBL1: + mod->BSIM3lpdibl1 = value->rValue; + mod->BSIM3lpdibl1Given = TRUE; + break; + case BSIM3_MOD_LPDIBL2: + mod->BSIM3lpdibl2 = value->rValue; + mod->BSIM3lpdibl2Given = TRUE; + break; + case BSIM3_MOD_LPDIBLB: + mod->BSIM3lpdiblb = value->rValue; + mod->BSIM3lpdiblbGiven = TRUE; + break; + case BSIM3_MOD_LPSCBE1: + mod->BSIM3lpscbe1 = value->rValue; + mod->BSIM3lpscbe1Given = TRUE; + break; + case BSIM3_MOD_LPSCBE2: + mod->BSIM3lpscbe2 = value->rValue; + mod->BSIM3lpscbe2Given = TRUE; + break; + case BSIM3_MOD_LPVAG: + mod->BSIM3lpvag = value->rValue; + mod->BSIM3lpvagGiven = TRUE; + break; + case BSIM3_MOD_LWR: + mod->BSIM3lwr = value->rValue; + mod->BSIM3lwrGiven = TRUE; + break; + case BSIM3_MOD_LDWG: + mod->BSIM3ldwg = value->rValue; + mod->BSIM3ldwgGiven = TRUE; + break; + case BSIM3_MOD_LDWB: + mod->BSIM3ldwb = value->rValue; + mod->BSIM3ldwbGiven = TRUE; + break; + case BSIM3_MOD_LB0: + mod->BSIM3lb0 = value->rValue; + mod->BSIM3lb0Given = TRUE; + break; + case BSIM3_MOD_LB1: + mod->BSIM3lb1 = value->rValue; + mod->BSIM3lb1Given = TRUE; + break; + case BSIM3_MOD_LALPHA0: + mod->BSIM3lalpha0 = value->rValue; + mod->BSIM3lalpha0Given = TRUE; + break; + case BSIM3_MOD_LALPHA1: + mod->BSIM3lalpha1 = value->rValue; + mod->BSIM3lalpha1Given = TRUE; + break; + case BSIM3_MOD_LBETA0: + mod->BSIM3lbeta0 = value->rValue; + mod->BSIM3lbeta0Given = TRUE; + break; + case BSIM3_MOD_LVFB: + mod->BSIM3lvfb = value->rValue; + mod->BSIM3lvfbGiven = TRUE; + break; - case BSIM3_MOD_WELM : - mod->BSIM3welm = value->rValue; - mod->BSIM3welmGiven = TRUE; - break; - case BSIM3_MOD_WCGSL : - mod->BSIM3wcgsl = value->rValue; - mod->BSIM3wcgslGiven = TRUE; - break; - case BSIM3_MOD_WCGDL : - mod->BSIM3wcgdl = value->rValue; - mod->BSIM3wcgdlGiven = TRUE; - break; - case BSIM3_MOD_WCKAPPA : - mod->BSIM3wckappa = value->rValue; - mod->BSIM3wckappaGiven = TRUE; - break; - case BSIM3_MOD_WCF : - mod->BSIM3wcf = value->rValue; - mod->BSIM3wcfGiven = TRUE; - break; - case BSIM3_MOD_WCLC : - mod->BSIM3wclc = value->rValue; - mod->BSIM3wclcGiven = TRUE; - break; - case BSIM3_MOD_WCLE : - mod->BSIM3wcle = value->rValue; - mod->BSIM3wcleGiven = TRUE; - break; - case BSIM3_MOD_WVFBCV : - mod->BSIM3wvfbcv = value->rValue; - mod->BSIM3wvfbcvGiven = TRUE; - break; - case BSIM3_MOD_WACDE : - mod->BSIM3wacde = value->rValue; - mod->BSIM3wacdeGiven = TRUE; - break; - case BSIM3_MOD_WMOIN : - mod->BSIM3wmoin = value->rValue; - mod->BSIM3wmoinGiven = TRUE; - break; - case BSIM3_MOD_WNOFF : - mod->BSIM3wnoff = value->rValue; - mod->BSIM3wnoffGiven = TRUE; - break; - case BSIM3_MOD_WVOFFCV : - mod->BSIM3wvoffcv = value->rValue; - mod->BSIM3wvoffcvGiven = TRUE; - break; + case BSIM3_MOD_LELM: + mod->BSIM3lelm = value->rValue; + mod->BSIM3lelmGiven = TRUE; + break; + case BSIM3_MOD_LCGSL: + mod->BSIM3lcgsl = value->rValue; + mod->BSIM3lcgslGiven = TRUE; + break; + case BSIM3_MOD_LCGDL: + mod->BSIM3lcgdl = value->rValue; + mod->BSIM3lcgdlGiven = TRUE; + break; + case BSIM3_MOD_LCKAPPA: + mod->BSIM3lckappa = value->rValue; + mod->BSIM3lckappaGiven = TRUE; + break; + case BSIM3_MOD_LCF: + mod->BSIM3lcf = value->rValue; + mod->BSIM3lcfGiven = TRUE; + break; + case BSIM3_MOD_LCLC: + mod->BSIM3lclc = value->rValue; + mod->BSIM3lclcGiven = TRUE; + break; + case BSIM3_MOD_LCLE: + mod->BSIM3lcle = value->rValue; + mod->BSIM3lcleGiven = TRUE; + break; + case BSIM3_MOD_LVFBCV: + mod->BSIM3lvfbcv = value->rValue; + mod->BSIM3lvfbcvGiven = TRUE; + break; + case BSIM3_MOD_LACDE: + mod->BSIM3lacde = value->rValue; + mod->BSIM3lacdeGiven = TRUE; + break; + case BSIM3_MOD_LMOIN: + mod->BSIM3lmoin = value->rValue; + mod->BSIM3lmoinGiven = TRUE; + break; + case BSIM3_MOD_LNOFF: + mod->BSIM3lnoff = value->rValue; + mod->BSIM3lnoffGiven = TRUE; + break; + case BSIM3_MOD_LVOFFCV: + mod->BSIM3lvoffcv = value->rValue; + mod->BSIM3lvoffcvGiven = TRUE; + break; - /* Cross-term dependence */ - case BSIM3_MOD_PCDSC : - mod->BSIM3pcdsc = value->rValue; - mod->BSIM3pcdscGiven = TRUE; - break; + /* Width dependence */ + case BSIM3_MOD_WCDSC: + mod->BSIM3wcdsc = value->rValue; + mod->BSIM3wcdscGiven = TRUE; + break; - case BSIM3_MOD_PCDSCB : - mod->BSIM3pcdscb = value->rValue; - mod->BSIM3pcdscbGiven = TRUE; - break; - case BSIM3_MOD_PCDSCD : - mod->BSIM3pcdscd = value->rValue; - mod->BSIM3pcdscdGiven = TRUE; - break; - case BSIM3_MOD_PCIT : - mod->BSIM3pcit = value->rValue; - mod->BSIM3pcitGiven = TRUE; - break; - case BSIM3_MOD_PNFACTOR : - mod->BSIM3pnfactor = value->rValue; - mod->BSIM3pnfactorGiven = TRUE; - break; - case BSIM3_MOD_PXJ: - mod->BSIM3pxj = value->rValue; - mod->BSIM3pxjGiven = TRUE; - break; - case BSIM3_MOD_PVSAT: - mod->BSIM3pvsat = value->rValue; - mod->BSIM3pvsatGiven = TRUE; - break; + case BSIM3_MOD_WCDSCB: + mod->BSIM3wcdscb = value->rValue; + mod->BSIM3wcdscbGiven = TRUE; + break; + case BSIM3_MOD_WCDSCD: + mod->BSIM3wcdscd = value->rValue; + mod->BSIM3wcdscdGiven = TRUE; + break; + case BSIM3_MOD_WCIT: + mod->BSIM3wcit = value->rValue; + mod->BSIM3wcitGiven = TRUE; + break; + case BSIM3_MOD_WNFACTOR: + mod->BSIM3wnfactor = value->rValue; + mod->BSIM3wnfactorGiven = TRUE; + break; + case BSIM3_MOD_WXJ: + mod->BSIM3wxj = value->rValue; + mod->BSIM3wxjGiven = TRUE; + break; + case BSIM3_MOD_WVSAT: + mod->BSIM3wvsat = value->rValue; + mod->BSIM3wvsatGiven = TRUE; + break; - case BSIM3_MOD_PA0: - mod->BSIM3pa0 = value->rValue; - mod->BSIM3pa0Given = TRUE; - break; - case BSIM3_MOD_PAGS: - mod->BSIM3pags = value->rValue; - mod->BSIM3pagsGiven = TRUE; - break; - case BSIM3_MOD_PA1: - mod->BSIM3pa1 = value->rValue; - mod->BSIM3pa1Given = TRUE; - break; - case BSIM3_MOD_PA2: - mod->BSIM3pa2 = value->rValue; - mod->BSIM3pa2Given = TRUE; - break; - case BSIM3_MOD_PAT: - mod->BSIM3pat = value->rValue; - mod->BSIM3patGiven = TRUE; - break; - case BSIM3_MOD_PKETA: - mod->BSIM3pketa = value->rValue; - mod->BSIM3pketaGiven = TRUE; - break; - case BSIM3_MOD_PNSUB: - mod->BSIM3pnsub = value->rValue; - mod->BSIM3pnsubGiven = TRUE; - break; - case BSIM3_MOD_PNPEAK: - mod->BSIM3pnpeak = value->rValue; - mod->BSIM3pnpeakGiven = TRUE; - if (mod->BSIM3pnpeak > 1.0e20) - mod->BSIM3pnpeak *= 1.0e-6; - break; - case BSIM3_MOD_PNGATE: - mod->BSIM3pngate = value->rValue; - mod->BSIM3pngateGiven = TRUE; - if (mod->BSIM3pngate > 1.0e23) - mod->BSIM3pngate *= 1.0e-6; - break; - case BSIM3_MOD_PGAMMA1: - mod->BSIM3pgamma1 = value->rValue; - mod->BSIM3pgamma1Given = TRUE; - break; - case BSIM3_MOD_PGAMMA2: - mod->BSIM3pgamma2 = value->rValue; - mod->BSIM3pgamma2Given = TRUE; - break; - case BSIM3_MOD_PVBX: - mod->BSIM3pvbx = value->rValue; - mod->BSIM3pvbxGiven = TRUE; - break; - case BSIM3_MOD_PVBM: - mod->BSIM3pvbm = value->rValue; - mod->BSIM3pvbmGiven = TRUE; - break; - case BSIM3_MOD_PXT: - mod->BSIM3pxt = value->rValue; - mod->BSIM3pxtGiven = TRUE; - break; - case BSIM3_MOD_PK1: - mod->BSIM3pk1 = value->rValue; - mod->BSIM3pk1Given = TRUE; - break; - case BSIM3_MOD_PKT1: - mod->BSIM3pkt1 = value->rValue; - mod->BSIM3pkt1Given = TRUE; - break; - case BSIM3_MOD_PKT1L: - mod->BSIM3pkt1l = value->rValue; - mod->BSIM3pkt1lGiven = TRUE; - break; - case BSIM3_MOD_PKT2: - mod->BSIM3pkt2 = value->rValue; - mod->BSIM3pkt2Given = TRUE; - break; - case BSIM3_MOD_PK2: - mod->BSIM3pk2 = value->rValue; - mod->BSIM3pk2Given = TRUE; - break; - case BSIM3_MOD_PK3: - mod->BSIM3pk3 = value->rValue; - mod->BSIM3pk3Given = TRUE; - break; - case BSIM3_MOD_PK3B: - mod->BSIM3pk3b = value->rValue; - mod->BSIM3pk3bGiven = TRUE; - break; - case BSIM3_MOD_PNLX: - mod->BSIM3pnlx = value->rValue; - mod->BSIM3pnlxGiven = TRUE; - break; - case BSIM3_MOD_PW0: - mod->BSIM3pw0 = value->rValue; - mod->BSIM3pw0Given = TRUE; - break; - case BSIM3_MOD_PDVT0: - mod->BSIM3pdvt0 = value->rValue; - mod->BSIM3pdvt0Given = TRUE; - break; - case BSIM3_MOD_PDVT1: - mod->BSIM3pdvt1 = value->rValue; - mod->BSIM3pdvt1Given = TRUE; - break; - case BSIM3_MOD_PDVT2: - mod->BSIM3pdvt2 = value->rValue; - mod->BSIM3pdvt2Given = TRUE; - break; - case BSIM3_MOD_PDVT0W: - mod->BSIM3pdvt0w = value->rValue; - mod->BSIM3pdvt0wGiven = TRUE; - break; - case BSIM3_MOD_PDVT1W: - mod->BSIM3pdvt1w = value->rValue; - mod->BSIM3pdvt1wGiven = TRUE; - break; - case BSIM3_MOD_PDVT2W: - mod->BSIM3pdvt2w = value->rValue; - mod->BSIM3pdvt2wGiven = TRUE; - break; - case BSIM3_MOD_PDROUT: - mod->BSIM3pdrout = value->rValue; - mod->BSIM3pdroutGiven = TRUE; - break; - case BSIM3_MOD_PDSUB: - mod->BSIM3pdsub = value->rValue; - mod->BSIM3pdsubGiven = TRUE; - break; - case BSIM3_MOD_PVTH0: - mod->BSIM3pvth0 = value->rValue; - mod->BSIM3pvth0Given = TRUE; - break; - case BSIM3_MOD_PUA: - mod->BSIM3pua = value->rValue; - mod->BSIM3puaGiven = TRUE; - break; - case BSIM3_MOD_PUA1: - mod->BSIM3pua1 = value->rValue; - mod->BSIM3pua1Given = TRUE; - break; - case BSIM3_MOD_PUB: - mod->BSIM3pub = value->rValue; - mod->BSIM3pubGiven = TRUE; - break; - case BSIM3_MOD_PUB1: - mod->BSIM3pub1 = value->rValue; - mod->BSIM3pub1Given = TRUE; - break; - case BSIM3_MOD_PUC: - mod->BSIM3puc = value->rValue; - mod->BSIM3pucGiven = TRUE; - break; - case BSIM3_MOD_PUC1: - mod->BSIM3puc1 = value->rValue; - mod->BSIM3puc1Given = TRUE; - break; - case BSIM3_MOD_PU0 : - mod->BSIM3pu0 = value->rValue; - mod->BSIM3pu0Given = TRUE; - break; - case BSIM3_MOD_PUTE : - mod->BSIM3pute = value->rValue; - mod->BSIM3puteGiven = TRUE; - break; - case BSIM3_MOD_PVOFF: - mod->BSIM3pvoff = value->rValue; - mod->BSIM3pvoffGiven = TRUE; - break; - case BSIM3_MOD_PDELTA : - mod->BSIM3pdelta = value->rValue; - mod->BSIM3pdeltaGiven = TRUE; - break; - case BSIM3_MOD_PRDSW: - mod->BSIM3prdsw = value->rValue; - mod->BSIM3prdswGiven = TRUE; - break; - case BSIM3_MOD_PPRWB: - mod->BSIM3pprwb = value->rValue; - mod->BSIM3pprwbGiven = TRUE; - break; - case BSIM3_MOD_PPRWG: - mod->BSIM3pprwg = value->rValue; - mod->BSIM3pprwgGiven = TRUE; - break; - case BSIM3_MOD_PPRT: - mod->BSIM3pprt = value->rValue; - mod->BSIM3pprtGiven = TRUE; - break; - case BSIM3_MOD_PETA0: - mod->BSIM3peta0 = value->rValue; - mod->BSIM3peta0Given = TRUE; - break; - case BSIM3_MOD_PETAB: - mod->BSIM3petab = value->rValue; - mod->BSIM3petabGiven = TRUE; - break; - case BSIM3_MOD_PPCLM: - mod->BSIM3ppclm = value->rValue; - mod->BSIM3ppclmGiven = TRUE; - break; - case BSIM3_MOD_PPDIBL1: - mod->BSIM3ppdibl1 = value->rValue; - mod->BSIM3ppdibl1Given = TRUE; - break; - case BSIM3_MOD_PPDIBL2: - mod->BSIM3ppdibl2 = value->rValue; - mod->BSIM3ppdibl2Given = TRUE; - break; - case BSIM3_MOD_PPDIBLB: - mod->BSIM3ppdiblb = value->rValue; - mod->BSIM3ppdiblbGiven = TRUE; - break; - case BSIM3_MOD_PPSCBE1: - mod->BSIM3ppscbe1 = value->rValue; - mod->BSIM3ppscbe1Given = TRUE; - break; - case BSIM3_MOD_PPSCBE2: - mod->BSIM3ppscbe2 = value->rValue; - mod->BSIM3ppscbe2Given = TRUE; - break; - case BSIM3_MOD_PPVAG: - mod->BSIM3ppvag = value->rValue; - mod->BSIM3ppvagGiven = TRUE; - break; - case BSIM3_MOD_PWR : - mod->BSIM3pwr = value->rValue; - mod->BSIM3pwrGiven = TRUE; - break; - case BSIM3_MOD_PDWG : - mod->BSIM3pdwg = value->rValue; - mod->BSIM3pdwgGiven = TRUE; - break; - case BSIM3_MOD_PDWB : - mod->BSIM3pdwb = value->rValue; - mod->BSIM3pdwbGiven = TRUE; - break; - case BSIM3_MOD_PB0 : - mod->BSIM3pb0 = value->rValue; - mod->BSIM3pb0Given = TRUE; - break; - case BSIM3_MOD_PB1 : - mod->BSIM3pb1 = value->rValue; - mod->BSIM3pb1Given = TRUE; - break; - case BSIM3_MOD_PALPHA0 : - mod->BSIM3palpha0 = value->rValue; - mod->BSIM3palpha0Given = TRUE; - break; - case BSIM3_MOD_PALPHA1 : - mod->BSIM3palpha1 = value->rValue; - mod->BSIM3palpha1Given = TRUE; - break; - case BSIM3_MOD_PBETA0 : - mod->BSIM3pbeta0 = value->rValue; - mod->BSIM3pbeta0Given = TRUE; - break; - case BSIM3_MOD_PVFB : - mod->BSIM3pvfb = value->rValue; - mod->BSIM3pvfbGiven = TRUE; - break; + case BSIM3_MOD_WA0: + mod->BSIM3wa0 = value->rValue; + mod->BSIM3wa0Given = TRUE; + break; + case BSIM3_MOD_WAGS: + mod->BSIM3wags = value->rValue; + mod->BSIM3wagsGiven = TRUE; + break; + case BSIM3_MOD_WA1: + mod->BSIM3wa1 = value->rValue; + mod->BSIM3wa1Given = TRUE; + break; + case BSIM3_MOD_WA2: + mod->BSIM3wa2 = value->rValue; + mod->BSIM3wa2Given = TRUE; + break; + case BSIM3_MOD_WAT: + mod->BSIM3wat = value->rValue; + mod->BSIM3watGiven = TRUE; + break; + case BSIM3_MOD_WKETA: + mod->BSIM3wketa = value->rValue; + mod->BSIM3wketaGiven = TRUE; + break; + case BSIM3_MOD_WNSUB: + mod->BSIM3wnsub = value->rValue; + mod->BSIM3wnsubGiven = TRUE; + break; + case BSIM3_MOD_WNPEAK: + mod->BSIM3wnpeak = value->rValue; + mod->BSIM3wnpeakGiven = TRUE; + if (mod->BSIM3wnpeak > 1.0e20) + mod->BSIM3wnpeak *= 1.0e-6; + break; + case BSIM3_MOD_WNGATE: + mod->BSIM3wngate = value->rValue; + mod->BSIM3wngateGiven = TRUE; + if (mod->BSIM3wngate > 1.0e23) + mod->BSIM3wngate *= 1.0e-6; + break; + case BSIM3_MOD_WGAMMA1: + mod->BSIM3wgamma1 = value->rValue; + mod->BSIM3wgamma1Given = TRUE; + break; + case BSIM3_MOD_WGAMMA2: + mod->BSIM3wgamma2 = value->rValue; + mod->BSIM3wgamma2Given = TRUE; + break; + case BSIM3_MOD_WVBX: + mod->BSIM3wvbx = value->rValue; + mod->BSIM3wvbxGiven = TRUE; + break; + case BSIM3_MOD_WVBM: + mod->BSIM3wvbm = value->rValue; + mod->BSIM3wvbmGiven = TRUE; + break; + case BSIM3_MOD_WXT: + mod->BSIM3wxt = value->rValue; + mod->BSIM3wxtGiven = TRUE; + break; + case BSIM3_MOD_WK1: + mod->BSIM3wk1 = value->rValue; + mod->BSIM3wk1Given = TRUE; + break; + case BSIM3_MOD_WKT1: + mod->BSIM3wkt1 = value->rValue; + mod->BSIM3wkt1Given = TRUE; + break; + case BSIM3_MOD_WKT1L: + mod->BSIM3wkt1l = value->rValue; + mod->BSIM3wkt1lGiven = TRUE; + break; + case BSIM3_MOD_WKT2: + mod->BSIM3wkt2 = value->rValue; + mod->BSIM3wkt2Given = TRUE; + break; + case BSIM3_MOD_WK2: + mod->BSIM3wk2 = value->rValue; + mod->BSIM3wk2Given = TRUE; + break; + case BSIM3_MOD_WK3: + mod->BSIM3wk3 = value->rValue; + mod->BSIM3wk3Given = TRUE; + break; + case BSIM3_MOD_WK3B: + mod->BSIM3wk3b = value->rValue; + mod->BSIM3wk3bGiven = TRUE; + break; + case BSIM3_MOD_WNLX: + mod->BSIM3wnlx = value->rValue; + mod->BSIM3wnlxGiven = TRUE; + break; + case BSIM3_MOD_WW0: + mod->BSIM3ww0 = value->rValue; + mod->BSIM3ww0Given = TRUE; + break; + case BSIM3_MOD_WDVT0: + mod->BSIM3wdvt0 = value->rValue; + mod->BSIM3wdvt0Given = TRUE; + break; + case BSIM3_MOD_WDVT1: + mod->BSIM3wdvt1 = value->rValue; + mod->BSIM3wdvt1Given = TRUE; + break; + case BSIM3_MOD_WDVT2: + mod->BSIM3wdvt2 = value->rValue; + mod->BSIM3wdvt2Given = TRUE; + break; + case BSIM3_MOD_WDVT0W: + mod->BSIM3wdvt0w = value->rValue; + mod->BSIM3wdvt0wGiven = TRUE; + break; + case BSIM3_MOD_WDVT1W: + mod->BSIM3wdvt1w = value->rValue; + mod->BSIM3wdvt1wGiven = TRUE; + break; + case BSIM3_MOD_WDVT2W: + mod->BSIM3wdvt2w = value->rValue; + mod->BSIM3wdvt2wGiven = TRUE; + break; + case BSIM3_MOD_WDROUT: + mod->BSIM3wdrout = value->rValue; + mod->BSIM3wdroutGiven = TRUE; + break; + case BSIM3_MOD_WDSUB: + mod->BSIM3wdsub = value->rValue; + mod->BSIM3wdsubGiven = TRUE; + break; + case BSIM3_MOD_WVTH0: + mod->BSIM3wvth0 = value->rValue; + mod->BSIM3wvth0Given = TRUE; + break; + case BSIM3_MOD_WUA: + mod->BSIM3wua = value->rValue; + mod->BSIM3wuaGiven = TRUE; + break; + case BSIM3_MOD_WUA1: + mod->BSIM3wua1 = value->rValue; + mod->BSIM3wua1Given = TRUE; + break; + case BSIM3_MOD_WUB: + mod->BSIM3wub = value->rValue; + mod->BSIM3wubGiven = TRUE; + break; + case BSIM3_MOD_WUB1: + mod->BSIM3wub1 = value->rValue; + mod->BSIM3wub1Given = TRUE; + break; + case BSIM3_MOD_WUC: + mod->BSIM3wuc = value->rValue; + mod->BSIM3wucGiven = TRUE; + break; + case BSIM3_MOD_WUC1: + mod->BSIM3wuc1 = value->rValue; + mod->BSIM3wuc1Given = TRUE; + break; + case BSIM3_MOD_WU0: + mod->BSIM3wu0 = value->rValue; + mod->BSIM3wu0Given = TRUE; + break; + case BSIM3_MOD_WUTE: + mod->BSIM3wute = value->rValue; + mod->BSIM3wuteGiven = TRUE; + break; + case BSIM3_MOD_WVOFF: + mod->BSIM3wvoff = value->rValue; + mod->BSIM3wvoffGiven = TRUE; + break; + case BSIM3_MOD_WDELTA: + mod->BSIM3wdelta = value->rValue; + mod->BSIM3wdeltaGiven = TRUE; + break; + case BSIM3_MOD_WRDSW: + mod->BSIM3wrdsw = value->rValue; + mod->BSIM3wrdswGiven = TRUE; + break; + case BSIM3_MOD_WPRWB: + mod->BSIM3wprwb = value->rValue; + mod->BSIM3wprwbGiven = TRUE; + break; + case BSIM3_MOD_WPRWG: + mod->BSIM3wprwg = value->rValue; + mod->BSIM3wprwgGiven = TRUE; + break; + case BSIM3_MOD_WPRT: + mod->BSIM3wprt = value->rValue; + mod->BSIM3wprtGiven = TRUE; + break; + case BSIM3_MOD_WETA0: + mod->BSIM3weta0 = value->rValue; + mod->BSIM3weta0Given = TRUE; + break; + case BSIM3_MOD_WETAB: + mod->BSIM3wetab = value->rValue; + mod->BSIM3wetabGiven = TRUE; + break; + case BSIM3_MOD_WPCLM: + mod->BSIM3wpclm = value->rValue; + mod->BSIM3wpclmGiven = TRUE; + break; + case BSIM3_MOD_WPDIBL1: + mod->BSIM3wpdibl1 = value->rValue; + mod->BSIM3wpdibl1Given = TRUE; + break; + case BSIM3_MOD_WPDIBL2: + mod->BSIM3wpdibl2 = value->rValue; + mod->BSIM3wpdibl2Given = TRUE; + break; + case BSIM3_MOD_WPDIBLB: + mod->BSIM3wpdiblb = value->rValue; + mod->BSIM3wpdiblbGiven = TRUE; + break; + case BSIM3_MOD_WPSCBE1: + mod->BSIM3wpscbe1 = value->rValue; + mod->BSIM3wpscbe1Given = TRUE; + break; + case BSIM3_MOD_WPSCBE2: + mod->BSIM3wpscbe2 = value->rValue; + mod->BSIM3wpscbe2Given = TRUE; + break; + case BSIM3_MOD_WPVAG: + mod->BSIM3wpvag = value->rValue; + mod->BSIM3wpvagGiven = TRUE; + break; + case BSIM3_MOD_WWR: + mod->BSIM3wwr = value->rValue; + mod->BSIM3wwrGiven = TRUE; + break; + case BSIM3_MOD_WDWG: + mod->BSIM3wdwg = value->rValue; + mod->BSIM3wdwgGiven = TRUE; + break; + case BSIM3_MOD_WDWB: + mod->BSIM3wdwb = value->rValue; + mod->BSIM3wdwbGiven = TRUE; + break; + case BSIM3_MOD_WB0: + mod->BSIM3wb0 = value->rValue; + mod->BSIM3wb0Given = TRUE; + break; + case BSIM3_MOD_WB1: + mod->BSIM3wb1 = value->rValue; + mod->BSIM3wb1Given = TRUE; + break; + case BSIM3_MOD_WALPHA0: + mod->BSIM3walpha0 = value->rValue; + mod->BSIM3walpha0Given = TRUE; + break; + case BSIM3_MOD_WALPHA1: + mod->BSIM3walpha1 = value->rValue; + mod->BSIM3walpha1Given = TRUE; + break; + case BSIM3_MOD_WBETA0: + mod->BSIM3wbeta0 = value->rValue; + mod->BSIM3wbeta0Given = TRUE; + break; + case BSIM3_MOD_WVFB: + mod->BSIM3wvfb = value->rValue; + mod->BSIM3wvfbGiven = TRUE; + break; - case BSIM3_MOD_PELM : - mod->BSIM3pelm = value->rValue; - mod->BSIM3pelmGiven = TRUE; - break; - case BSIM3_MOD_PCGSL : - mod->BSIM3pcgsl = value->rValue; - mod->BSIM3pcgslGiven = TRUE; - break; - case BSIM3_MOD_PCGDL : - mod->BSIM3pcgdl = value->rValue; - mod->BSIM3pcgdlGiven = TRUE; - break; - case BSIM3_MOD_PCKAPPA : - mod->BSIM3pckappa = value->rValue; - mod->BSIM3pckappaGiven = TRUE; - break; - case BSIM3_MOD_PCF : - mod->BSIM3pcf = value->rValue; - mod->BSIM3pcfGiven = TRUE; - break; - case BSIM3_MOD_PCLC : - mod->BSIM3pclc = value->rValue; - mod->BSIM3pclcGiven = TRUE; - break; - case BSIM3_MOD_PCLE : - mod->BSIM3pcle = value->rValue; - mod->BSIM3pcleGiven = TRUE; - break; - case BSIM3_MOD_PVFBCV : - mod->BSIM3pvfbcv = value->rValue; - mod->BSIM3pvfbcvGiven = TRUE; - break; - case BSIM3_MOD_PACDE : - mod->BSIM3pacde = value->rValue; - mod->BSIM3pacdeGiven = TRUE; - break; - case BSIM3_MOD_PMOIN : - mod->BSIM3pmoin = value->rValue; - mod->BSIM3pmoinGiven = TRUE; - break; - case BSIM3_MOD_PNOFF : - mod->BSIM3pnoff = value->rValue; - mod->BSIM3pnoffGiven = TRUE; - break; - case BSIM3_MOD_PVOFFCV : - mod->BSIM3pvoffcv = value->rValue; - mod->BSIM3pvoffcvGiven = TRUE; - break; + case BSIM3_MOD_WELM: + mod->BSIM3welm = value->rValue; + mod->BSIM3welmGiven = TRUE; + break; + case BSIM3_MOD_WCGSL: + mod->BSIM3wcgsl = value->rValue; + mod->BSIM3wcgslGiven = TRUE; + break; + case BSIM3_MOD_WCGDL: + mod->BSIM3wcgdl = value->rValue; + mod->BSIM3wcgdlGiven = TRUE; + break; + case BSIM3_MOD_WCKAPPA: + mod->BSIM3wckappa = value->rValue; + mod->BSIM3wckappaGiven = TRUE; + break; + case BSIM3_MOD_WCF: + mod->BSIM3wcf = value->rValue; + mod->BSIM3wcfGiven = TRUE; + break; + case BSIM3_MOD_WCLC: + mod->BSIM3wclc = value->rValue; + mod->BSIM3wclcGiven = TRUE; + break; + case BSIM3_MOD_WCLE: + mod->BSIM3wcle = value->rValue; + mod->BSIM3wcleGiven = TRUE; + break; + case BSIM3_MOD_WVFBCV: + mod->BSIM3wvfbcv = value->rValue; + mod->BSIM3wvfbcvGiven = TRUE; + break; + case BSIM3_MOD_WACDE: + mod->BSIM3wacde = value->rValue; + mod->BSIM3wacdeGiven = TRUE; + break; + case BSIM3_MOD_WMOIN: + mod->BSIM3wmoin = value->rValue; + mod->BSIM3wmoinGiven = TRUE; + break; + case BSIM3_MOD_WNOFF: + mod->BSIM3wnoff = value->rValue; + mod->BSIM3wnoffGiven = TRUE; + break; + case BSIM3_MOD_WVOFFCV: + mod->BSIM3wvoffcv = value->rValue; + mod->BSIM3wvoffcvGiven = TRUE; + break; - case BSIM3_MOD_TNOM : - mod->BSIM3tnom = value->rValue; - mod->BSIM3tnomGiven = TRUE; - break; - case BSIM3_MOD_CGSO : - mod->BSIM3cgso = value->rValue; - mod->BSIM3cgsoGiven = TRUE; - break; - case BSIM3_MOD_CGDO : - mod->BSIM3cgdo = value->rValue; - mod->BSIM3cgdoGiven = TRUE; - break; - case BSIM3_MOD_CGBO : - mod->BSIM3cgbo = value->rValue; - mod->BSIM3cgboGiven = TRUE; - break; - case BSIM3_MOD_XPART : - mod->BSIM3xpart = value->rValue; - mod->BSIM3xpartGiven = TRUE; - break; - case BSIM3_MOD_RSH : - mod->BSIM3sheetResistance = value->rValue; - mod->BSIM3sheetResistanceGiven = TRUE; - break; - case BSIM3_MOD_JS : - mod->BSIM3jctSatCurDensity = value->rValue; - mod->BSIM3jctSatCurDensityGiven = TRUE; - break; - case BSIM3_MOD_JSW : - mod->BSIM3jctSidewallSatCurDensity = value->rValue; - mod->BSIM3jctSidewallSatCurDensityGiven = TRUE; - break; - case BSIM3_MOD_PB : - mod->BSIM3bulkJctPotential = value->rValue; - mod->BSIM3bulkJctPotentialGiven = TRUE; - break; - case BSIM3_MOD_MJ : - mod->BSIM3bulkJctBotGradingCoeff = value->rValue; - mod->BSIM3bulkJctBotGradingCoeffGiven = TRUE; - break; - case BSIM3_MOD_PBSW : - mod->BSIM3sidewallJctPotential = value->rValue; - mod->BSIM3sidewallJctPotentialGiven = TRUE; - break; - case BSIM3_MOD_MJSW : - mod->BSIM3bulkJctSideGradingCoeff = value->rValue; - mod->BSIM3bulkJctSideGradingCoeffGiven = TRUE; - break; - case BSIM3_MOD_CJ : - mod->BSIM3unitAreaJctCap = value->rValue; - mod->BSIM3unitAreaJctCapGiven = TRUE; - break; - case BSIM3_MOD_CJSW : - mod->BSIM3unitLengthSidewallJctCap = value->rValue; - mod->BSIM3unitLengthSidewallJctCapGiven = TRUE; - break; - case BSIM3_MOD_NJ : - mod->BSIM3jctEmissionCoeff = value->rValue; - mod->BSIM3jctEmissionCoeffGiven = TRUE; - break; - case BSIM3_MOD_PBSWG : - mod->BSIM3GatesidewallJctPotential = value->rValue; - mod->BSIM3GatesidewallJctPotentialGiven = TRUE; - break; - case BSIM3_MOD_MJSWG : - mod->BSIM3bulkJctGateSideGradingCoeff = value->rValue; - mod->BSIM3bulkJctGateSideGradingCoeffGiven = TRUE; - break; - case BSIM3_MOD_CJSWG : - mod->BSIM3unitLengthGateSidewallJctCap = value->rValue; - mod->BSIM3unitLengthGateSidewallJctCapGiven = TRUE; - break; - case BSIM3_MOD_XTI : - mod->BSIM3jctTempExponent = value->rValue; - mod->BSIM3jctTempExponentGiven = TRUE; - break; - case BSIM3_MOD_LINT : - mod->BSIM3Lint = value->rValue; - mod->BSIM3LintGiven = TRUE; - break; - case BSIM3_MOD_LL : - mod->BSIM3Ll = value->rValue; - mod->BSIM3LlGiven = TRUE; - break; - case BSIM3_MOD_LLC : - mod->BSIM3Llc = value->rValue; - mod->BSIM3LlcGiven = TRUE; - break; - case BSIM3_MOD_LLN : - mod->BSIM3Lln = value->rValue; - mod->BSIM3LlnGiven = TRUE; - break; - case BSIM3_MOD_LW : - mod->BSIM3Lw = value->rValue; - mod->BSIM3LwGiven = TRUE; - break; - case BSIM3_MOD_LWC : - mod->BSIM3Lwc = value->rValue; - mod->BSIM3LwcGiven = TRUE; - break; - case BSIM3_MOD_LWN : - mod->BSIM3Lwn = value->rValue; - mod->BSIM3LwnGiven = TRUE; - break; - case BSIM3_MOD_LWL : - mod->BSIM3Lwl = value->rValue; - mod->BSIM3LwlGiven = TRUE; - break; - case BSIM3_MOD_LWLC : - mod->BSIM3Lwlc = value->rValue; - mod->BSIM3LwlcGiven = TRUE; - break; - case BSIM3_MOD_LMIN : - mod->BSIM3Lmin = value->rValue; - mod->BSIM3LminGiven = TRUE; - break; - case BSIM3_MOD_LMAX : - mod->BSIM3Lmax = value->rValue; - mod->BSIM3LmaxGiven = TRUE; - break; - case BSIM3_MOD_WINT : - mod->BSIM3Wint = value->rValue; - mod->BSIM3WintGiven = TRUE; - break; - case BSIM3_MOD_WL : - mod->BSIM3Wl = value->rValue; - mod->BSIM3WlGiven = TRUE; - break; - case BSIM3_MOD_WLC : - mod->BSIM3Wlc = value->rValue; - mod->BSIM3WlcGiven = TRUE; - break; - case BSIM3_MOD_WLN : - mod->BSIM3Wln = value->rValue; - mod->BSIM3WlnGiven = TRUE; - break; - case BSIM3_MOD_WW : - mod->BSIM3Ww = value->rValue; - mod->BSIM3WwGiven = TRUE; - break; - case BSIM3_MOD_WWC : - mod->BSIM3Wwc = value->rValue; - mod->BSIM3WwcGiven = TRUE; - break; - case BSIM3_MOD_WWN : - mod->BSIM3Wwn = value->rValue; - mod->BSIM3WwnGiven = TRUE; - break; - case BSIM3_MOD_WWL : - mod->BSIM3Wwl = value->rValue; - mod->BSIM3WwlGiven = TRUE; - break; - case BSIM3_MOD_WWLC : - mod->BSIM3Wwlc = value->rValue; - mod->BSIM3WwlcGiven = TRUE; - break; - case BSIM3_MOD_WMIN : - mod->BSIM3Wmin = value->rValue; - mod->BSIM3WminGiven = TRUE; - break; - case BSIM3_MOD_WMAX : - mod->BSIM3Wmax = value->rValue; - mod->BSIM3WmaxGiven = TRUE; - break; + /* Cross-term dependence */ + case BSIM3_MOD_PCDSC: + mod->BSIM3pcdsc = value->rValue; + mod->BSIM3pcdscGiven = TRUE; + break; - case BSIM3_MOD_NOIA : - mod->BSIM3oxideTrapDensityA = value->rValue; - mod->BSIM3oxideTrapDensityAGiven = TRUE; - break; - case BSIM3_MOD_NOIB : - mod->BSIM3oxideTrapDensityB = value->rValue; - mod->BSIM3oxideTrapDensityBGiven = TRUE; - break; - case BSIM3_MOD_NOIC : - mod->BSIM3oxideTrapDensityC = value->rValue; - mod->BSIM3oxideTrapDensityCGiven = TRUE; - break; - case BSIM3_MOD_EM : - mod->BSIM3em = value->rValue; - mod->BSIM3emGiven = TRUE; - break; - case BSIM3_MOD_EF : - mod->BSIM3ef = value->rValue; - mod->BSIM3efGiven = TRUE; - break; - case BSIM3_MOD_AF : - mod->BSIM3af = value->rValue; - mod->BSIM3afGiven = TRUE; - break; - case BSIM3_MOD_KF : - mod->BSIM3kf = value->rValue; - mod->BSIM3kfGiven = TRUE; - break; - case BSIM3_MOD_NMOS : - if(value->iValue) { - mod->BSIM3type = 1; - mod->BSIM3typeGiven = TRUE; - } - break; - case BSIM3_MOD_PMOS : - if(value->iValue) { - mod->BSIM3type = - 1; - mod->BSIM3typeGiven = TRUE; - } - break; - default: - return(E_BADPARM); + + case BSIM3_MOD_PCDSCB: + mod->BSIM3pcdscb = value->rValue; + mod->BSIM3pcdscbGiven = TRUE; + break; + case BSIM3_MOD_PCDSCD: + mod->BSIM3pcdscd = value->rValue; + mod->BSIM3pcdscdGiven = TRUE; + break; + case BSIM3_MOD_PCIT: + mod->BSIM3pcit = value->rValue; + mod->BSIM3pcitGiven = TRUE; + break; + case BSIM3_MOD_PNFACTOR: + mod->BSIM3pnfactor = value->rValue; + mod->BSIM3pnfactorGiven = TRUE; + break; + case BSIM3_MOD_PXJ: + mod->BSIM3pxj = value->rValue; + mod->BSIM3pxjGiven = TRUE; + break; + case BSIM3_MOD_PVSAT: + mod->BSIM3pvsat = value->rValue; + mod->BSIM3pvsatGiven = TRUE; + break; + + + case BSIM3_MOD_PA0: + mod->BSIM3pa0 = value->rValue; + mod->BSIM3pa0Given = TRUE; + break; + case BSIM3_MOD_PAGS: + mod->BSIM3pags = value->rValue; + mod->BSIM3pagsGiven = TRUE; + break; + case BSIM3_MOD_PA1: + mod->BSIM3pa1 = value->rValue; + mod->BSIM3pa1Given = TRUE; + break; + case BSIM3_MOD_PA2: + mod->BSIM3pa2 = value->rValue; + mod->BSIM3pa2Given = TRUE; + break; + case BSIM3_MOD_PAT: + mod->BSIM3pat = value->rValue; + mod->BSIM3patGiven = TRUE; + break; + case BSIM3_MOD_PKETA: + mod->BSIM3pketa = value->rValue; + mod->BSIM3pketaGiven = TRUE; + break; + case BSIM3_MOD_PNSUB: + mod->BSIM3pnsub = value->rValue; + mod->BSIM3pnsubGiven = TRUE; + break; + case BSIM3_MOD_PNPEAK: + mod->BSIM3pnpeak = value->rValue; + mod->BSIM3pnpeakGiven = TRUE; + if (mod->BSIM3pnpeak > 1.0e20) + mod->BSIM3pnpeak *= 1.0e-6; + break; + case BSIM3_MOD_PNGATE: + mod->BSIM3pngate = value->rValue; + mod->BSIM3pngateGiven = TRUE; + if (mod->BSIM3pngate > 1.0e23) + mod->BSIM3pngate *= 1.0e-6; + break; + case BSIM3_MOD_PGAMMA1: + mod->BSIM3pgamma1 = value->rValue; + mod->BSIM3pgamma1Given = TRUE; + break; + case BSIM3_MOD_PGAMMA2: + mod->BSIM3pgamma2 = value->rValue; + mod->BSIM3pgamma2Given = TRUE; + break; + case BSIM3_MOD_PVBX: + mod->BSIM3pvbx = value->rValue; + mod->BSIM3pvbxGiven = TRUE; + break; + case BSIM3_MOD_PVBM: + mod->BSIM3pvbm = value->rValue; + mod->BSIM3pvbmGiven = TRUE; + break; + case BSIM3_MOD_PXT: + mod->BSIM3pxt = value->rValue; + mod->BSIM3pxtGiven = TRUE; + break; + case BSIM3_MOD_PK1: + mod->BSIM3pk1 = value->rValue; + mod->BSIM3pk1Given = TRUE; + break; + case BSIM3_MOD_PKT1: + mod->BSIM3pkt1 = value->rValue; + mod->BSIM3pkt1Given = TRUE; + break; + case BSIM3_MOD_PKT1L: + mod->BSIM3pkt1l = value->rValue; + mod->BSIM3pkt1lGiven = TRUE; + break; + case BSIM3_MOD_PKT2: + mod->BSIM3pkt2 = value->rValue; + mod->BSIM3pkt2Given = TRUE; + break; + case BSIM3_MOD_PK2: + mod->BSIM3pk2 = value->rValue; + mod->BSIM3pk2Given = TRUE; + break; + case BSIM3_MOD_PK3: + mod->BSIM3pk3 = value->rValue; + mod->BSIM3pk3Given = TRUE; + break; + case BSIM3_MOD_PK3B: + mod->BSIM3pk3b = value->rValue; + mod->BSIM3pk3bGiven = TRUE; + break; + case BSIM3_MOD_PNLX: + mod->BSIM3pnlx = value->rValue; + mod->BSIM3pnlxGiven = TRUE; + break; + case BSIM3_MOD_PW0: + mod->BSIM3pw0 = value->rValue; + mod->BSIM3pw0Given = TRUE; + break; + case BSIM3_MOD_PDVT0: + mod->BSIM3pdvt0 = value->rValue; + mod->BSIM3pdvt0Given = TRUE; + break; + case BSIM3_MOD_PDVT1: + mod->BSIM3pdvt1 = value->rValue; + mod->BSIM3pdvt1Given = TRUE; + break; + case BSIM3_MOD_PDVT2: + mod->BSIM3pdvt2 = value->rValue; + mod->BSIM3pdvt2Given = TRUE; + break; + case BSIM3_MOD_PDVT0W: + mod->BSIM3pdvt0w = value->rValue; + mod->BSIM3pdvt0wGiven = TRUE; + break; + case BSIM3_MOD_PDVT1W: + mod->BSIM3pdvt1w = value->rValue; + mod->BSIM3pdvt1wGiven = TRUE; + break; + case BSIM3_MOD_PDVT2W: + mod->BSIM3pdvt2w = value->rValue; + mod->BSIM3pdvt2wGiven = TRUE; + break; + case BSIM3_MOD_PDROUT: + mod->BSIM3pdrout = value->rValue; + mod->BSIM3pdroutGiven = TRUE; + break; + case BSIM3_MOD_PDSUB: + mod->BSIM3pdsub = value->rValue; + mod->BSIM3pdsubGiven = TRUE; + break; + case BSIM3_MOD_PVTH0: + mod->BSIM3pvth0 = value->rValue; + mod->BSIM3pvth0Given = TRUE; + break; + case BSIM3_MOD_PUA: + mod->BSIM3pua = value->rValue; + mod->BSIM3puaGiven = TRUE; + break; + case BSIM3_MOD_PUA1: + mod->BSIM3pua1 = value->rValue; + mod->BSIM3pua1Given = TRUE; + break; + case BSIM3_MOD_PUB: + mod->BSIM3pub = value->rValue; + mod->BSIM3pubGiven = TRUE; + break; + case BSIM3_MOD_PUB1: + mod->BSIM3pub1 = value->rValue; + mod->BSIM3pub1Given = TRUE; + break; + case BSIM3_MOD_PUC: + mod->BSIM3puc = value->rValue; + mod->BSIM3pucGiven = TRUE; + break; + case BSIM3_MOD_PUC1: + mod->BSIM3puc1 = value->rValue; + mod->BSIM3puc1Given = TRUE; + break; + case BSIM3_MOD_PU0: + mod->BSIM3pu0 = value->rValue; + mod->BSIM3pu0Given = TRUE; + break; + case BSIM3_MOD_PUTE: + mod->BSIM3pute = value->rValue; + mod->BSIM3puteGiven = TRUE; + break; + case BSIM3_MOD_PVOFF: + mod->BSIM3pvoff = value->rValue; + mod->BSIM3pvoffGiven = TRUE; + break; + case BSIM3_MOD_PDELTA: + mod->BSIM3pdelta = value->rValue; + mod->BSIM3pdeltaGiven = TRUE; + break; + case BSIM3_MOD_PRDSW: + mod->BSIM3prdsw = value->rValue; + mod->BSIM3prdswGiven = TRUE; + break; + case BSIM3_MOD_PPRWB: + mod->BSIM3pprwb = value->rValue; + mod->BSIM3pprwbGiven = TRUE; + break; + case BSIM3_MOD_PPRWG: + mod->BSIM3pprwg = value->rValue; + mod->BSIM3pprwgGiven = TRUE; + break; + case BSIM3_MOD_PPRT: + mod->BSIM3pprt = value->rValue; + mod->BSIM3pprtGiven = TRUE; + break; + case BSIM3_MOD_PETA0: + mod->BSIM3peta0 = value->rValue; + mod->BSIM3peta0Given = TRUE; + break; + case BSIM3_MOD_PETAB: + mod->BSIM3petab = value->rValue; + mod->BSIM3petabGiven = TRUE; + break; + case BSIM3_MOD_PPCLM: + mod->BSIM3ppclm = value->rValue; + mod->BSIM3ppclmGiven = TRUE; + break; + case BSIM3_MOD_PPDIBL1: + mod->BSIM3ppdibl1 = value->rValue; + mod->BSIM3ppdibl1Given = TRUE; + break; + case BSIM3_MOD_PPDIBL2: + mod->BSIM3ppdibl2 = value->rValue; + mod->BSIM3ppdibl2Given = TRUE; + break; + case BSIM3_MOD_PPDIBLB: + mod->BSIM3ppdiblb = value->rValue; + mod->BSIM3ppdiblbGiven = TRUE; + break; + case BSIM3_MOD_PPSCBE1: + mod->BSIM3ppscbe1 = value->rValue; + mod->BSIM3ppscbe1Given = TRUE; + break; + case BSIM3_MOD_PPSCBE2: + mod->BSIM3ppscbe2 = value->rValue; + mod->BSIM3ppscbe2Given = TRUE; + break; + case BSIM3_MOD_PPVAG: + mod->BSIM3ppvag = value->rValue; + mod->BSIM3ppvagGiven = TRUE; + break; + case BSIM3_MOD_PWR: + mod->BSIM3pwr = value->rValue; + mod->BSIM3pwrGiven = TRUE; + break; + case BSIM3_MOD_PDWG: + mod->BSIM3pdwg = value->rValue; + mod->BSIM3pdwgGiven = TRUE; + break; + case BSIM3_MOD_PDWB: + mod->BSIM3pdwb = value->rValue; + mod->BSIM3pdwbGiven = TRUE; + break; + case BSIM3_MOD_PB0: + mod->BSIM3pb0 = value->rValue; + mod->BSIM3pb0Given = TRUE; + break; + case BSIM3_MOD_PB1: + mod->BSIM3pb1 = value->rValue; + mod->BSIM3pb1Given = TRUE; + break; + case BSIM3_MOD_PALPHA0: + mod->BSIM3palpha0 = value->rValue; + mod->BSIM3palpha0Given = TRUE; + break; + case BSIM3_MOD_PALPHA1: + mod->BSIM3palpha1 = value->rValue; + mod->BSIM3palpha1Given = TRUE; + break; + case BSIM3_MOD_PBETA0: + mod->BSIM3pbeta0 = value->rValue; + mod->BSIM3pbeta0Given = TRUE; + break; + case BSIM3_MOD_PVFB: + mod->BSIM3pvfb = value->rValue; + mod->BSIM3pvfbGiven = TRUE; + break; + + case BSIM3_MOD_PELM: + mod->BSIM3pelm = value->rValue; + mod->BSIM3pelmGiven = TRUE; + break; + case BSIM3_MOD_PCGSL: + mod->BSIM3pcgsl = value->rValue; + mod->BSIM3pcgslGiven = TRUE; + break; + case BSIM3_MOD_PCGDL: + mod->BSIM3pcgdl = value->rValue; + mod->BSIM3pcgdlGiven = TRUE; + break; + case BSIM3_MOD_PCKAPPA: + mod->BSIM3pckappa = value->rValue; + mod->BSIM3pckappaGiven = TRUE; + break; + case BSIM3_MOD_PCF: + mod->BSIM3pcf = value->rValue; + mod->BSIM3pcfGiven = TRUE; + break; + case BSIM3_MOD_PCLC: + mod->BSIM3pclc = value->rValue; + mod->BSIM3pclcGiven = TRUE; + break; + case BSIM3_MOD_PCLE: + mod->BSIM3pcle = value->rValue; + mod->BSIM3pcleGiven = TRUE; + break; + case BSIM3_MOD_PVFBCV: + mod->BSIM3pvfbcv = value->rValue; + mod->BSIM3pvfbcvGiven = TRUE; + break; + case BSIM3_MOD_PACDE: + mod->BSIM3pacde = value->rValue; + mod->BSIM3pacdeGiven = TRUE; + break; + case BSIM3_MOD_PMOIN: + mod->BSIM3pmoin = value->rValue; + mod->BSIM3pmoinGiven = TRUE; + break; + case BSIM3_MOD_PNOFF: + mod->BSIM3pnoff = value->rValue; + mod->BSIM3pnoffGiven = TRUE; + break; + case BSIM3_MOD_PVOFFCV: + mod->BSIM3pvoffcv = value->rValue; + mod->BSIM3pvoffcvGiven = TRUE; + break; + + case BSIM3_MOD_TNOM: + mod->BSIM3tnom = value->rValue + 273.15; + mod->BSIM3tnomGiven = TRUE; + break; + case BSIM3_MOD_CGSO: + mod->BSIM3cgso = value->rValue; + mod->BSIM3cgsoGiven = TRUE; + break; + case BSIM3_MOD_CGDO: + mod->BSIM3cgdo = value->rValue; + mod->BSIM3cgdoGiven = TRUE; + break; + case BSIM3_MOD_CGBO: + mod->BSIM3cgbo = value->rValue; + mod->BSIM3cgboGiven = TRUE; + break; + case BSIM3_MOD_XPART: + mod->BSIM3xpart = value->rValue; + mod->BSIM3xpartGiven = TRUE; + break; + case BSIM3_MOD_RSH: + mod->BSIM3sheetResistance = value->rValue; + mod->BSIM3sheetResistanceGiven = TRUE; + break; + case BSIM3_MOD_JS: + mod->BSIM3jctSatCurDensity = value->rValue; + mod->BSIM3jctSatCurDensityGiven = TRUE; + break; + case BSIM3_MOD_JSW: + mod->BSIM3jctSidewallSatCurDensity = value->rValue; + mod->BSIM3jctSidewallSatCurDensityGiven = TRUE; + break; + case BSIM3_MOD_PB: + mod->BSIM3bulkJctPotential = value->rValue; + mod->BSIM3bulkJctPotentialGiven = TRUE; + break; + case BSIM3_MOD_MJ: + mod->BSIM3bulkJctBotGradingCoeff = value->rValue; + mod->BSIM3bulkJctBotGradingCoeffGiven = TRUE; + break; + case BSIM3_MOD_PBSW: + mod->BSIM3sidewallJctPotential = value->rValue; + mod->BSIM3sidewallJctPotentialGiven = TRUE; + break; + case BSIM3_MOD_MJSW: + mod->BSIM3bulkJctSideGradingCoeff = value->rValue; + mod->BSIM3bulkJctSideGradingCoeffGiven = TRUE; + break; + case BSIM3_MOD_CJ: + mod->BSIM3unitAreaJctCap = value->rValue; + mod->BSIM3unitAreaJctCapGiven = TRUE; + break; + case BSIM3_MOD_CJSW: + mod->BSIM3unitLengthSidewallJctCap = value->rValue; + mod->BSIM3unitLengthSidewallJctCapGiven = TRUE; + break; + case BSIM3_MOD_NJ: + mod->BSIM3jctEmissionCoeff = value->rValue; + mod->BSIM3jctEmissionCoeffGiven = TRUE; + break; + case BSIM3_MOD_PBSWG: + mod->BSIM3GatesidewallJctPotential = value->rValue; + mod->BSIM3GatesidewallJctPotentialGiven = TRUE; + break; + case BSIM3_MOD_MJSWG: + mod->BSIM3bulkJctGateSideGradingCoeff = value->rValue; + mod->BSIM3bulkJctGateSideGradingCoeffGiven = TRUE; + break; + case BSIM3_MOD_CJSWG: + mod->BSIM3unitLengthGateSidewallJctCap = value->rValue; + mod->BSIM3unitLengthGateSidewallJctCapGiven = TRUE; + break; + case BSIM3_MOD_XTI: + mod->BSIM3jctTempExponent = value->rValue; + mod->BSIM3jctTempExponentGiven = TRUE; + break; + case BSIM3_MOD_LINT: + mod->BSIM3Lint = value->rValue; + mod->BSIM3LintGiven = TRUE; + break; + case BSIM3_MOD_LL: + mod->BSIM3Ll = value->rValue; + mod->BSIM3LlGiven = TRUE; + break; + case BSIM3_MOD_LLC: + mod->BSIM3Llc = value->rValue; + mod->BSIM3LlcGiven = TRUE; + break; + case BSIM3_MOD_LLN: + mod->BSIM3Lln = value->rValue; + mod->BSIM3LlnGiven = TRUE; + break; + case BSIM3_MOD_LW: + mod->BSIM3Lw = value->rValue; + mod->BSIM3LwGiven = TRUE; + break; + case BSIM3_MOD_LWC: + mod->BSIM3Lwc = value->rValue; + mod->BSIM3LwcGiven = TRUE; + break; + case BSIM3_MOD_LWN: + mod->BSIM3Lwn = value->rValue; + mod->BSIM3LwnGiven = TRUE; + break; + case BSIM3_MOD_LWL: + mod->BSIM3Lwl = value->rValue; + mod->BSIM3LwlGiven = TRUE; + break; + case BSIM3_MOD_LWLC: + mod->BSIM3Lwlc = value->rValue; + mod->BSIM3LwlcGiven = TRUE; + break; + case BSIM3_MOD_LMIN: + mod->BSIM3Lmin = value->rValue; + mod->BSIM3LminGiven = TRUE; + break; + case BSIM3_MOD_LMAX: + mod->BSIM3Lmax = value->rValue; + mod->BSIM3LmaxGiven = TRUE; + break; + case BSIM3_MOD_WINT: + mod->BSIM3Wint = value->rValue; + mod->BSIM3WintGiven = TRUE; + break; + case BSIM3_MOD_WL: + mod->BSIM3Wl = value->rValue; + mod->BSIM3WlGiven = TRUE; + break; + case BSIM3_MOD_WLC: + mod->BSIM3Wlc = value->rValue; + mod->BSIM3WlcGiven = TRUE; + break; + case BSIM3_MOD_WLN: + mod->BSIM3Wln = value->rValue; + mod->BSIM3WlnGiven = TRUE; + break; + case BSIM3_MOD_WW: + mod->BSIM3Ww = value->rValue; + mod->BSIM3WwGiven = TRUE; + break; + case BSIM3_MOD_WWC: + mod->BSIM3Wwc = value->rValue; + mod->BSIM3WwcGiven = TRUE; + break; + case BSIM3_MOD_WWN: + mod->BSIM3Wwn = value->rValue; + mod->BSIM3WwnGiven = TRUE; + break; + case BSIM3_MOD_WWL: + mod->BSIM3Wwl = value->rValue; + mod->BSIM3WwlGiven = TRUE; + break; + case BSIM3_MOD_WWLC: + mod->BSIM3Wwlc = value->rValue; + mod->BSIM3WwlcGiven = TRUE; + break; + case BSIM3_MOD_WMIN: + mod->BSIM3Wmin = value->rValue; + mod->BSIM3WminGiven = TRUE; + break; + case BSIM3_MOD_WMAX: + mod->BSIM3Wmax = value->rValue; + mod->BSIM3WmaxGiven = TRUE; + break; + + case BSIM3_MOD_NOIA: + mod->BSIM3oxideTrapDensityA = value->rValue; + mod->BSIM3oxideTrapDensityAGiven = TRUE; + break; + case BSIM3_MOD_NOIB: + mod->BSIM3oxideTrapDensityB = value->rValue; + mod->BSIM3oxideTrapDensityBGiven = TRUE; + break; + case BSIM3_MOD_NOIC: + mod->BSIM3oxideTrapDensityC = value->rValue; + mod->BSIM3oxideTrapDensityCGiven = TRUE; + break; + case BSIM3_MOD_EM: + mod->BSIM3em = value->rValue; + mod->BSIM3emGiven = TRUE; + break; + case BSIM3_MOD_EF: + mod->BSIM3ef = value->rValue; + mod->BSIM3efGiven = TRUE; + break; + case BSIM3_MOD_AF: + mod->BSIM3af = value->rValue; + mod->BSIM3afGiven = TRUE; + break; + case BSIM3_MOD_KF: + mod->BSIM3kf = value->rValue; + mod->BSIM3kfGiven = TRUE; + break; + case BSIM3_MOD_NMOS: + if (value->iValue) + { + mod->BSIM3type = 1; + mod->BSIM3typeGiven = TRUE; + } + break; + case BSIM3_MOD_PMOS: + if (value->iValue) + { + mod->BSIM3type = -1; + mod->BSIM3typeGiven = TRUE; + } + break; + default: + return (E_BADPARM); } - return(OK); + return (OK); } - - diff --git a/src/spicelib/devices/bsim3/b3noi.c b/src/spicelib/devices/bsim3/b3noi.c index 831cdace5..425dfc6dc 100644 --- a/src/spicelib/devices/bsim3/b3noi.c +++ b/src/spicelib/devices/bsim3/b3noi.c @@ -1,29 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.3 1999/08/28 21:00:03 manu - Big commit - merged ngspice.h, misc.h and util.h - protoized fte - - Revision 1.2 1999/08/23 18:14:39 manu - Added cleanup patch by Arno Peters - also added 'make check' to configure - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Gary W. Ng and Min-Chie Jeng. @@ -36,7 +10,6 @@ File: b3noi.c #include #include "bsim3def.h" #include "cktdefs.h" -#include "fteconst.h" #include "iferrmsg.h" #include "noisedef.h" #include "suffix.h" @@ -124,11 +97,11 @@ BSIM3noise (mode, operation, inModel, ckt, data, OnDens) int mode, operation; GENmodel *inModel; CKTcircuit *ckt; -register Ndata *data; +Ndata *data; double *OnDens; { -register BSIM3model *model = (BSIM3model *)inModel; -register BSIM3instance *here; +BSIM3model *model = (BSIM3model *)inModel; +BSIM3instance *here; struct bsim3SizeDependParam *pParam; char name[N_MXVLNTH]; double tempOnoise; diff --git a/src/spicelib/devices/bsim3/b3par.c b/src/spicelib/devices/bsim3/b3par.c index 47785513d..7761ebfcb 100644 --- a/src/spicelib/devices/bsim3/b3par.c +++ b/src/spicelib/devices/bsim3/b3par.c @@ -1,30 +1,8 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.2 1999/08/28 21:00:03 manu - Big commit - merged ngspice.h, misc.h and util.h - protoized fte - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. Author: 1997-1999 Weidong Liu. +Modified: 2000 AlansFixes File: b3par.c **********/ @@ -52,6 +30,10 @@ IFvalue *select; here->BSIM3l = value->rValue; here->BSIM3lGiven = TRUE; break; + case BSIM3_M: + here->BSIM3m = value->rValue; + here->BSIM3mGiven = TRUE; + break; case BSIM3_AS: here->BSIM3sourceArea = value->rValue; here->BSIM3sourceAreaGiven = TRUE; diff --git a/src/spicelib/devices/bsim3/b3pzld.c b/src/spicelib/devices/bsim3/b3pzld.c index d37489f71..18247e726 100644 --- a/src/spicelib/devices/bsim3/b3pzld.c +++ b/src/spicelib/devices/bsim3/b3pzld.c @@ -1,26 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.2 1999/08/23 18:14:39 manu - Added cleanup patch by Arno Peters - also added 'make check' to configure - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -39,11 +16,11 @@ File: b3pzld.c int BSIM3pzLoad(inModel,ckt,s) GENmodel *inModel; -register CKTcircuit *ckt; -register SPcomplex *s; +CKTcircuit *ckt; +SPcomplex *s; { -register BSIM3model *model = (BSIM3model*)inModel; -register BSIM3instance *here; +BSIM3model *model = (BSIM3model*)inModel; +BSIM3instance *here; double xcggb, xcgdb, xcgsb, xcgbb, xcbgb, xcbdb, xcbsb, xcbbb; double xcdgb, xcddb, xcdsb, xcdbb, xcsgb, xcsdb, xcssb, xcsbb; double gdpr, gspr, gds, gbd, gbs, capbd, capbs, FwdSum, RevSum, Gm, Gmbs; diff --git a/src/spicelib/devices/bsim3/b3set.c b/src/spicelib/devices/bsim3/b3set.c index f81df237c..51db6987b 100644 --- a/src/spicelib/devices/bsim3/b3set.c +++ b/src/spicelib/devices/bsim3/b3set.c @@ -1,33 +1,9 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.3 1999/08/28 21:00:03 manu - Big commit - merged ngspice.h, misc.h and util.h - protoized fte - - Revision 1.2 1999/08/23 18:14:39 manu - Added cleanup patch by Arno Peters - also added 'make check' to configure - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. Author: 1997-1999 Weidong Liu. + +Modified: 2000 AlansFixes File: b3set.c **********/ @@ -51,895 +27,947 @@ File: b3set.c #define Meter2Micron 1.0e6 int -BSIM3setup(matrix,inModel,ckt,states) -register SMPmatrix *matrix; -register GENmodel *inModel; -register CKTcircuit *ckt; -int *states; +BSIM3setup (matrix, inModel, ckt, states) + SMPmatrix *matrix; + GENmodel *inModel; + CKTcircuit *ckt; + int *states; { -register BSIM3model *model = (BSIM3model*)inModel; -register BSIM3instance *here; -int error; -CKTnode *tmp; + BSIM3model *model = (BSIM3model *) inModel; + BSIM3instance *here; + int error; + CKTnode *tmp; - /* loop through all the BSIM3 device models */ - for( ; model != NULL; model = model->BSIM3nextModel ) + /* loop through all the BSIM3 device models */ + for (; model != NULL; model = model->BSIM3nextModel) { /* Default value Processing for BSIM3 MOSFET Models */ - if (!model->BSIM3typeGiven) - model->BSIM3type = NMOS; - if (!model->BSIM3mobModGiven) - model->BSIM3mobMod = 1; - if (!model->BSIM3binUnitGiven) - model->BSIM3binUnit = 1; - if (!model->BSIM3paramChkGiven) - model->BSIM3paramChk = 0; - if (!model->BSIM3capModGiven) - model->BSIM3capMod = 3; - if (!model->BSIM3noiModGiven) - model->BSIM3noiMod = 1; - if (!model->BSIM3versionGiven) - model->BSIM3version = "3.2.2"; - if (!model->BSIM3toxGiven) - model->BSIM3tox = 150.0e-10; - model->BSIM3cox = 3.453133e-11 / model->BSIM3tox; - if (!model->BSIM3toxmGiven) - model->BSIM3toxm = model->BSIM3tox; + if (!model->BSIM3typeGiven) + model->BSIM3type = NMOS; + if (!model->BSIM3mobModGiven) + model->BSIM3mobMod = 1; + if (!model->BSIM3binUnitGiven) + model->BSIM3binUnit = 1; + if (!model->BSIM3paramChkGiven) + model->BSIM3paramChk = 0; + if (!model->BSIM3capModGiven) + model->BSIM3capMod = 3; + if (!model->BSIM3noiModGiven) + model->BSIM3noiMod = 1; + if (!model->BSIM3versionGiven) + model->BSIM3version = "3.2.2"; + if (!model->BSIM3toxGiven) + model->BSIM3tox = 150.0e-10; + model->BSIM3cox = 3.453133e-11 / model->BSIM3tox; + if (!model->BSIM3toxmGiven) + model->BSIM3toxm = model->BSIM3tox; - if (!model->BSIM3cdscGiven) - model->BSIM3cdsc = 2.4e-4; /* unit Q/V/m^2 */ - if (!model->BSIM3cdscbGiven) - model->BSIM3cdscb = 0.0; /* unit Q/V/m^2 */ - if (!model->BSIM3cdscdGiven) - model->BSIM3cdscd = 0.0; /* unit Q/V/m^2 */ - if (!model->BSIM3citGiven) - model->BSIM3cit = 0.0; /* unit Q/V/m^2 */ - if (!model->BSIM3nfactorGiven) - model->BSIM3nfactor = 1; - if (!model->BSIM3xjGiven) - model->BSIM3xj = .15e-6; - if (!model->BSIM3vsatGiven) - model->BSIM3vsat = 8.0e4; /* unit m/s */ - if (!model->BSIM3atGiven) - model->BSIM3at = 3.3e4; /* unit m/s */ - if (!model->BSIM3a0Given) - model->BSIM3a0 = 1.0; - if (!model->BSIM3agsGiven) - model->BSIM3ags = 0.0; - if (!model->BSIM3a1Given) - model->BSIM3a1 = 0.0; - if (!model->BSIM3a2Given) - model->BSIM3a2 = 1.0; - if (!model->BSIM3ketaGiven) - model->BSIM3keta = -0.047; /* unit / V */ - if (!model->BSIM3nsubGiven) - model->BSIM3nsub = 6.0e16; /* unit 1/cm3 */ - if (!model->BSIM3npeakGiven) - model->BSIM3npeak = 1.7e17; /* unit 1/cm3 */ - if (!model->BSIM3ngateGiven) - model->BSIM3ngate = 0; /* unit 1/cm3 */ - if (!model->BSIM3vbmGiven) - model->BSIM3vbm = -3.0; - if (!model->BSIM3xtGiven) - model->BSIM3xt = 1.55e-7; - if (!model->BSIM3kt1Given) - model->BSIM3kt1 = -0.11; /* unit V */ - if (!model->BSIM3kt1lGiven) - model->BSIM3kt1l = 0.0; /* unit V*m */ - if (!model->BSIM3kt2Given) - model->BSIM3kt2 = 0.022; /* No unit */ - if (!model->BSIM3k3Given) - model->BSIM3k3 = 80.0; - if (!model->BSIM3k3bGiven) - model->BSIM3k3b = 0.0; - if (!model->BSIM3w0Given) - model->BSIM3w0 = 2.5e-6; - if (!model->BSIM3nlxGiven) - model->BSIM3nlx = 1.74e-7; - if (!model->BSIM3dvt0Given) - model->BSIM3dvt0 = 2.2; - if (!model->BSIM3dvt1Given) - model->BSIM3dvt1 = 0.53; - if (!model->BSIM3dvt2Given) - model->BSIM3dvt2 = -0.032; /* unit 1 / V */ + if (!model->BSIM3cdscGiven) + model->BSIM3cdsc = 2.4e-4; /* unit Q/V/m^2 */ + if (!model->BSIM3cdscbGiven) + model->BSIM3cdscb = 0.0; /* unit Q/V/m^2 */ + if (!model->BSIM3cdscdGiven) + model->BSIM3cdscd = 0.0; /* unit Q/V/m^2 */ + if (!model->BSIM3citGiven) + model->BSIM3cit = 0.0; /* unit Q/V/m^2 */ + if (!model->BSIM3nfactorGiven) + model->BSIM3nfactor = 1; + if (!model->BSIM3xjGiven) + model->BSIM3xj = .15e-6; + if (!model->BSIM3vsatGiven) + model->BSIM3vsat = 8.0e4; /* unit m/s */ + if (!model->BSIM3atGiven) + model->BSIM3at = 3.3e4; /* unit m/s */ + if (!model->BSIM3a0Given) + model->BSIM3a0 = 1.0; + if (!model->BSIM3agsGiven) + model->BSIM3ags = 0.0; + if (!model->BSIM3a1Given) + model->BSIM3a1 = 0.0; + if (!model->BSIM3a2Given) + model->BSIM3a2 = 1.0; + if (!model->BSIM3ketaGiven) + model->BSIM3keta = -0.047; /* unit / V */ + if (!model->BSIM3nsubGiven) + model->BSIM3nsub = 6.0e16; /* unit 1/cm3 */ + if (!model->BSIM3npeakGiven) + model->BSIM3npeak = 1.7e17; /* unit 1/cm3 */ + if (!model->BSIM3ngateGiven) + model->BSIM3ngate = 0; /* unit 1/cm3 */ + if (!model->BSIM3vbmGiven) + model->BSIM3vbm = -3.0; + if (!model->BSIM3xtGiven) + model->BSIM3xt = 1.55e-7; + if (!model->BSIM3kt1Given) + model->BSIM3kt1 = -0.11; /* unit V */ + if (!model->BSIM3kt1lGiven) + model->BSIM3kt1l = 0.0; /* unit V*m */ + if (!model->BSIM3kt2Given) + model->BSIM3kt2 = 0.022; /* No unit */ + if (!model->BSIM3k3Given) + model->BSIM3k3 = 80.0; + if (!model->BSIM3k3bGiven) + model->BSIM3k3b = 0.0; + if (!model->BSIM3w0Given) + model->BSIM3w0 = 2.5e-6; + if (!model->BSIM3nlxGiven) + model->BSIM3nlx = 1.74e-7; + if (!model->BSIM3dvt0Given) + model->BSIM3dvt0 = 2.2; + if (!model->BSIM3dvt1Given) + model->BSIM3dvt1 = 0.53; + if (!model->BSIM3dvt2Given) + model->BSIM3dvt2 = -0.032; /* unit 1 / V */ - if (!model->BSIM3dvt0wGiven) - model->BSIM3dvt0w = 0.0; - if (!model->BSIM3dvt1wGiven) - model->BSIM3dvt1w = 5.3e6; - if (!model->BSIM3dvt2wGiven) - model->BSIM3dvt2w = -0.032; + if (!model->BSIM3dvt0wGiven) + model->BSIM3dvt0w = 0.0; + if (!model->BSIM3dvt1wGiven) + model->BSIM3dvt1w = 5.3e6; + if (!model->BSIM3dvt2wGiven) + model->BSIM3dvt2w = -0.032; - if (!model->BSIM3droutGiven) - model->BSIM3drout = 0.56; - if (!model->BSIM3dsubGiven) - model->BSIM3dsub = model->BSIM3drout; - if (!model->BSIM3vth0Given) - model->BSIM3vth0 = (model->BSIM3type == NMOS) ? 0.7 : -0.7; - if (!model->BSIM3uaGiven) - model->BSIM3ua = 2.25e-9; /* unit m/V */ - if (!model->BSIM3ua1Given) - model->BSIM3ua1 = 4.31e-9; /* unit m/V */ - if (!model->BSIM3ubGiven) - model->BSIM3ub = 5.87e-19; /* unit (m/V)**2 */ - if (!model->BSIM3ub1Given) - model->BSIM3ub1 = -7.61e-18; /* unit (m/V)**2 */ - if (!model->BSIM3ucGiven) - model->BSIM3uc = (model->BSIM3mobMod == 3) ? -0.0465 : -0.0465e-9; - if (!model->BSIM3uc1Given) - model->BSIM3uc1 = (model->BSIM3mobMod == 3) ? -0.056 : -0.056e-9; - if (!model->BSIM3u0Given) - model->BSIM3u0 = (model->BSIM3type == NMOS) ? 0.067 : 0.025; - if (!model->BSIM3uteGiven) - model->BSIM3ute = -1.5; - if (!model->BSIM3voffGiven) - model->BSIM3voff = -0.08; - if (!model->BSIM3deltaGiven) - model->BSIM3delta = 0.01; - if (!model->BSIM3rdswGiven) - model->BSIM3rdsw = 0; - if (!model->BSIM3prwgGiven) - model->BSIM3prwg = 0.0; /* unit 1/V */ - if (!model->BSIM3prwbGiven) - model->BSIM3prwb = 0.0; - if (!model->BSIM3prtGiven) - if (!model->BSIM3prtGiven) - model->BSIM3prt = 0.0; - if (!model->BSIM3eta0Given) - model->BSIM3eta0 = 0.08; /* no unit */ - if (!model->BSIM3etabGiven) - model->BSIM3etab = -0.07; /* unit 1/V */ - if (!model->BSIM3pclmGiven) - model->BSIM3pclm = 1.3; /* no unit */ - if (!model->BSIM3pdibl1Given) - model->BSIM3pdibl1 = .39; /* no unit */ - if (!model->BSIM3pdibl2Given) - model->BSIM3pdibl2 = 0.0086; /* no unit */ - if (!model->BSIM3pdiblbGiven) - model->BSIM3pdiblb = 0.0; /* 1/V */ - if (!model->BSIM3pscbe1Given) - model->BSIM3pscbe1 = 4.24e8; - if (!model->BSIM3pscbe2Given) - model->BSIM3pscbe2 = 1.0e-5; - if (!model->BSIM3pvagGiven) - model->BSIM3pvag = 0.0; - if (!model->BSIM3wrGiven) - model->BSIM3wr = 1.0; - if (!model->BSIM3dwgGiven) - model->BSIM3dwg = 0.0; - if (!model->BSIM3dwbGiven) - model->BSIM3dwb = 0.0; - if (!model->BSIM3b0Given) - model->BSIM3b0 = 0.0; - if (!model->BSIM3b1Given) - model->BSIM3b1 = 0.0; - if (!model->BSIM3alpha0Given) - model->BSIM3alpha0 = 0.0; - if (!model->BSIM3alpha1Given) - model->BSIM3alpha1 = 0.0; - if (!model->BSIM3beta0Given) - model->BSIM3beta0 = 30.0; - if (!model->BSIM3ijthGiven) - model->BSIM3ijth = 0.1; /* unit A */ + if (!model->BSIM3droutGiven) + model->BSIM3drout = 0.56; + if (!model->BSIM3dsubGiven) + model->BSIM3dsub = model->BSIM3drout; + if (!model->BSIM3vth0Given) + model->BSIM3vth0 = (model->BSIM3type == NMOS) ? 0.7 : -0.7; + if (!model->BSIM3uaGiven) + model->BSIM3ua = 2.25e-9; /* unit m/V */ + if (!model->BSIM3ua1Given) + model->BSIM3ua1 = 4.31e-9; /* unit m/V */ + if (!model->BSIM3ubGiven) + model->BSIM3ub = 5.87e-19; /* unit (m/V)**2 */ + if (!model->BSIM3ub1Given) + model->BSIM3ub1 = -7.61e-18; /* unit (m/V)**2 */ + if (!model->BSIM3ucGiven) + model->BSIM3uc = (model->BSIM3mobMod == 3) ? -0.0465 : -0.0465e-9; + if (!model->BSIM3uc1Given) + model->BSIM3uc1 = (model->BSIM3mobMod == 3) ? -0.056 : -0.056e-9; + if (!model->BSIM3u0Given) + model->BSIM3u0 = (model->BSIM3type == NMOS) ? 0.067 : 0.025; + if (!model->BSIM3uteGiven) + model->BSIM3ute = -1.5; + if (!model->BSIM3voffGiven) + model->BSIM3voff = -0.08; + if (!model->BSIM3deltaGiven) + model->BSIM3delta = 0.01; + if (!model->BSIM3rdswGiven) + model->BSIM3rdsw = 0; + if (!model->BSIM3prwgGiven) + model->BSIM3prwg = 0.0; /* unit 1/V */ + if (!model->BSIM3prwbGiven) + model->BSIM3prwb = 0.0; + if (!model->BSIM3prtGiven) + if (!model->BSIM3prtGiven) + model->BSIM3prt = 0.0; + if (!model->BSIM3eta0Given) + model->BSIM3eta0 = 0.08; /* no unit */ + if (!model->BSIM3etabGiven) + model->BSIM3etab = -0.07; /* unit 1/V */ + if (!model->BSIM3pclmGiven) + model->BSIM3pclm = 1.3; /* no unit */ + if (!model->BSIM3pdibl1Given) + model->BSIM3pdibl1 = .39; /* no unit */ + if (!model->BSIM3pdibl2Given) + model->BSIM3pdibl2 = 0.0086; /* no unit */ + if (!model->BSIM3pdiblbGiven) + model->BSIM3pdiblb = 0.0; /* 1/V */ + if (!model->BSIM3pscbe1Given) + model->BSIM3pscbe1 = 4.24e8; + if (!model->BSIM3pscbe2Given) + model->BSIM3pscbe2 = 1.0e-5; + if (!model->BSIM3pvagGiven) + model->BSIM3pvag = 0.0; + if (!model->BSIM3wrGiven) + model->BSIM3wr = 1.0; + if (!model->BSIM3dwgGiven) + model->BSIM3dwg = 0.0; + if (!model->BSIM3dwbGiven) + model->BSIM3dwb = 0.0; + if (!model->BSIM3b0Given) + model->BSIM3b0 = 0.0; + if (!model->BSIM3b1Given) + model->BSIM3b1 = 0.0; + if (!model->BSIM3alpha0Given) + model->BSIM3alpha0 = 0.0; + if (!model->BSIM3alpha1Given) + model->BSIM3alpha1 = 0.0; + if (!model->BSIM3beta0Given) + model->BSIM3beta0 = 30.0; + if (!model->BSIM3ijthGiven) + model->BSIM3ijth = 0.1; /* unit A */ - if (!model->BSIM3elmGiven) - model->BSIM3elm = 5.0; - if (!model->BSIM3cgslGiven) - model->BSIM3cgsl = 0.0; - if (!model->BSIM3cgdlGiven) - model->BSIM3cgdl = 0.0; - if (!model->BSIM3ckappaGiven) - model->BSIM3ckappa = 0.6; - if (!model->BSIM3clcGiven) - model->BSIM3clc = 0.1e-6; - if (!model->BSIM3cleGiven) - model->BSIM3cle = 0.6; - if (!model->BSIM3vfbcvGiven) - model->BSIM3vfbcv = -1.0; - if (!model->BSIM3acdeGiven) - model->BSIM3acde = 1.0; - if (!model->BSIM3moinGiven) - model->BSIM3moin = 15.0; - if (!model->BSIM3noffGiven) - model->BSIM3noff = 1.0; - if (!model->BSIM3voffcvGiven) - model->BSIM3voffcv = 0.0; - if (!model->BSIM3tcjGiven) - model->BSIM3tcj = 0.0; - if (!model->BSIM3tpbGiven) - model->BSIM3tpb = 0.0; - if (!model->BSIM3tcjswGiven) - model->BSIM3tcjsw = 0.0; - if (!model->BSIM3tpbswGiven) - model->BSIM3tpbsw = 0.0; - if (!model->BSIM3tcjswgGiven) - model->BSIM3tcjswg = 0.0; - if (!model->BSIM3tpbswgGiven) - model->BSIM3tpbswg = 0.0; + if (!model->BSIM3elmGiven) + model->BSIM3elm = 5.0; + if (!model->BSIM3cgslGiven) + model->BSIM3cgsl = 0.0; + if (!model->BSIM3cgdlGiven) + model->BSIM3cgdl = 0.0; + if (!model->BSIM3ckappaGiven) + model->BSIM3ckappa = 0.6; + if (!model->BSIM3clcGiven) + model->BSIM3clc = 0.1e-6; + if (!model->BSIM3cleGiven) + model->BSIM3cle = 0.6; + if (!model->BSIM3vfbcvGiven) + model->BSIM3vfbcv = -1.0; + if (!model->BSIM3acdeGiven) + model->BSIM3acde = 1.0; + if (!model->BSIM3moinGiven) + model->BSIM3moin = 15.0; + if (!model->BSIM3noffGiven) + model->BSIM3noff = 1.0; + if (!model->BSIM3voffcvGiven) + model->BSIM3voffcv = 0.0; + if (!model->BSIM3tcjGiven) + model->BSIM3tcj = 0.0; + if (!model->BSIM3tpbGiven) + model->BSIM3tpb = 0.0; + if (!model->BSIM3tcjswGiven) + model->BSIM3tcjsw = 0.0; + if (!model->BSIM3tpbswGiven) + model->BSIM3tpbsw = 0.0; + if (!model->BSIM3tcjswgGiven) + model->BSIM3tcjswg = 0.0; + if (!model->BSIM3tpbswgGiven) + model->BSIM3tpbswg = 0.0; - /* Length dependence */ - if (!model->BSIM3lcdscGiven) - model->BSIM3lcdsc = 0.0; - if (!model->BSIM3lcdscbGiven) - model->BSIM3lcdscb = 0.0; - if (!model->BSIM3lcdscdGiven) - model->BSIM3lcdscd = 0.0; - if (!model->BSIM3lcitGiven) - model->BSIM3lcit = 0.0; - if (!model->BSIM3lnfactorGiven) - model->BSIM3lnfactor = 0.0; - if (!model->BSIM3lxjGiven) - model->BSIM3lxj = 0.0; - if (!model->BSIM3lvsatGiven) - model->BSIM3lvsat = 0.0; - if (!model->BSIM3latGiven) - model->BSIM3lat = 0.0; - if (!model->BSIM3la0Given) - model->BSIM3la0 = 0.0; - if (!model->BSIM3lagsGiven) - model->BSIM3lags = 0.0; - if (!model->BSIM3la1Given) - model->BSIM3la1 = 0.0; - if (!model->BSIM3la2Given) - model->BSIM3la2 = 0.0; - if (!model->BSIM3lketaGiven) - model->BSIM3lketa = 0.0; - if (!model->BSIM3lnsubGiven) - model->BSIM3lnsub = 0.0; - if (!model->BSIM3lnpeakGiven) - model->BSIM3lnpeak = 0.0; - if (!model->BSIM3lngateGiven) - model->BSIM3lngate = 0.0; - if (!model->BSIM3lvbmGiven) - model->BSIM3lvbm = 0.0; - if (!model->BSIM3lxtGiven) - model->BSIM3lxt = 0.0; - if (!model->BSIM3lkt1Given) - model->BSIM3lkt1 = 0.0; - if (!model->BSIM3lkt1lGiven) - model->BSIM3lkt1l = 0.0; - if (!model->BSIM3lkt2Given) - model->BSIM3lkt2 = 0.0; - if (!model->BSIM3lk3Given) - model->BSIM3lk3 = 0.0; - if (!model->BSIM3lk3bGiven) - model->BSIM3lk3b = 0.0; - if (!model->BSIM3lw0Given) - model->BSIM3lw0 = 0.0; - if (!model->BSIM3lnlxGiven) - model->BSIM3lnlx = 0.0; - if (!model->BSIM3ldvt0Given) - model->BSIM3ldvt0 = 0.0; - if (!model->BSIM3ldvt1Given) - model->BSIM3ldvt1 = 0.0; - if (!model->BSIM3ldvt2Given) - model->BSIM3ldvt2 = 0.0; - if (!model->BSIM3ldvt0wGiven) - model->BSIM3ldvt0w = 0.0; - if (!model->BSIM3ldvt1wGiven) - model->BSIM3ldvt1w = 0.0; - if (!model->BSIM3ldvt2wGiven) - model->BSIM3ldvt2w = 0.0; - if (!model->BSIM3ldroutGiven) - model->BSIM3ldrout = 0.0; - if (!model->BSIM3ldsubGiven) - model->BSIM3ldsub = 0.0; - if (!model->BSIM3lvth0Given) - model->BSIM3lvth0 = 0.0; - if (!model->BSIM3luaGiven) - model->BSIM3lua = 0.0; - if (!model->BSIM3lua1Given) - model->BSIM3lua1 = 0.0; - if (!model->BSIM3lubGiven) - model->BSIM3lub = 0.0; - if (!model->BSIM3lub1Given) - model->BSIM3lub1 = 0.0; - if (!model->BSIM3lucGiven) - model->BSIM3luc = 0.0; - if (!model->BSIM3luc1Given) - model->BSIM3luc1 = 0.0; - if (!model->BSIM3lu0Given) - model->BSIM3lu0 = 0.0; - if (!model->BSIM3luteGiven) - model->BSIM3lute = 0.0; - if (!model->BSIM3lvoffGiven) - model->BSIM3lvoff = 0.0; - if (!model->BSIM3ldeltaGiven) - model->BSIM3ldelta = 0.0; - if (!model->BSIM3lrdswGiven) - model->BSIM3lrdsw = 0.0; - if (!model->BSIM3lprwbGiven) - model->BSIM3lprwb = 0.0; - if (!model->BSIM3lprwgGiven) - model->BSIM3lprwg = 0.0; - if (!model->BSIM3lprtGiven) - model->BSIM3lprt = 0.0; - if (!model->BSIM3leta0Given) - model->BSIM3leta0 = 0.0; - if (!model->BSIM3letabGiven) - model->BSIM3letab = -0.0; - if (!model->BSIM3lpclmGiven) - model->BSIM3lpclm = 0.0; - if (!model->BSIM3lpdibl1Given) - model->BSIM3lpdibl1 = 0.0; - if (!model->BSIM3lpdibl2Given) - model->BSIM3lpdibl2 = 0.0; - if (!model->BSIM3lpdiblbGiven) - model->BSIM3lpdiblb = 0.0; - if (!model->BSIM3lpscbe1Given) - model->BSIM3lpscbe1 = 0.0; - if (!model->BSIM3lpscbe2Given) - model->BSIM3lpscbe2 = 0.0; - if (!model->BSIM3lpvagGiven) - model->BSIM3lpvag = 0.0; - if (!model->BSIM3lwrGiven) - model->BSIM3lwr = 0.0; - if (!model->BSIM3ldwgGiven) - model->BSIM3ldwg = 0.0; - if (!model->BSIM3ldwbGiven) - model->BSIM3ldwb = 0.0; - if (!model->BSIM3lb0Given) - model->BSIM3lb0 = 0.0; - if (!model->BSIM3lb1Given) - model->BSIM3lb1 = 0.0; - if (!model->BSIM3lalpha0Given) - model->BSIM3lalpha0 = 0.0; - if (!model->BSIM3lalpha1Given) - model->BSIM3lalpha1 = 0.0; - if (!model->BSIM3lbeta0Given) - model->BSIM3lbeta0 = 0.0; - if (!model->BSIM3lvfbGiven) - model->BSIM3lvfb = 0.0; + /* Length dependence */ + if (!model->BSIM3lcdscGiven) + model->BSIM3lcdsc = 0.0; + if (!model->BSIM3lcdscbGiven) + model->BSIM3lcdscb = 0.0; + if (!model->BSIM3lcdscdGiven) + model->BSIM3lcdscd = 0.0; + if (!model->BSIM3lcitGiven) + model->BSIM3lcit = 0.0; + if (!model->BSIM3lnfactorGiven) + model->BSIM3lnfactor = 0.0; + if (!model->BSIM3lxjGiven) + model->BSIM3lxj = 0.0; + if (!model->BSIM3lvsatGiven) + model->BSIM3lvsat = 0.0; + if (!model->BSIM3latGiven) + model->BSIM3lat = 0.0; + if (!model->BSIM3la0Given) + model->BSIM3la0 = 0.0; + if (!model->BSIM3lagsGiven) + model->BSIM3lags = 0.0; + if (!model->BSIM3la1Given) + model->BSIM3la1 = 0.0; + if (!model->BSIM3la2Given) + model->BSIM3la2 = 0.0; + if (!model->BSIM3lketaGiven) + model->BSIM3lketa = 0.0; + if (!model->BSIM3lnsubGiven) + model->BSIM3lnsub = 0.0; + if (!model->BSIM3lnpeakGiven) + model->BSIM3lnpeak = 0.0; + if (!model->BSIM3lngateGiven) + model->BSIM3lngate = 0.0; + if (!model->BSIM3lvbmGiven) + model->BSIM3lvbm = 0.0; + if (!model->BSIM3lxtGiven) + model->BSIM3lxt = 0.0; + if (!model->BSIM3lkt1Given) + model->BSIM3lkt1 = 0.0; + if (!model->BSIM3lkt1lGiven) + model->BSIM3lkt1l = 0.0; + if (!model->BSIM3lkt2Given) + model->BSIM3lkt2 = 0.0; + if (!model->BSIM3lk3Given) + model->BSIM3lk3 = 0.0; + if (!model->BSIM3lk3bGiven) + model->BSIM3lk3b = 0.0; + if (!model->BSIM3lw0Given) + model->BSIM3lw0 = 0.0; + if (!model->BSIM3lnlxGiven) + model->BSIM3lnlx = 0.0; + if (!model->BSIM3ldvt0Given) + model->BSIM3ldvt0 = 0.0; + if (!model->BSIM3ldvt1Given) + model->BSIM3ldvt1 = 0.0; + if (!model->BSIM3ldvt2Given) + model->BSIM3ldvt2 = 0.0; + if (!model->BSIM3ldvt0wGiven) + model->BSIM3ldvt0w = 0.0; + if (!model->BSIM3ldvt1wGiven) + model->BSIM3ldvt1w = 0.0; + if (!model->BSIM3ldvt2wGiven) + model->BSIM3ldvt2w = 0.0; + if (!model->BSIM3ldroutGiven) + model->BSIM3ldrout = 0.0; + if (!model->BSIM3ldsubGiven) + model->BSIM3ldsub = 0.0; + if (!model->BSIM3lvth0Given) + model->BSIM3lvth0 = 0.0; + if (!model->BSIM3luaGiven) + model->BSIM3lua = 0.0; + if (!model->BSIM3lua1Given) + model->BSIM3lua1 = 0.0; + if (!model->BSIM3lubGiven) + model->BSIM3lub = 0.0; + if (!model->BSIM3lub1Given) + model->BSIM3lub1 = 0.0; + if (!model->BSIM3lucGiven) + model->BSIM3luc = 0.0; + if (!model->BSIM3luc1Given) + model->BSIM3luc1 = 0.0; + if (!model->BSIM3lu0Given) + model->BSIM3lu0 = 0.0; + if (!model->BSIM3luteGiven) + model->BSIM3lute = 0.0; + if (!model->BSIM3lvoffGiven) + model->BSIM3lvoff = 0.0; + if (!model->BSIM3ldeltaGiven) + model->BSIM3ldelta = 0.0; + if (!model->BSIM3lrdswGiven) + model->BSIM3lrdsw = 0.0; + if (!model->BSIM3lprwbGiven) + model->BSIM3lprwb = 0.0; + if (!model->BSIM3lprwgGiven) + model->BSIM3lprwg = 0.0; + if (!model->BSIM3lprtGiven) + model->BSIM3lprt = 0.0; + if (!model->BSIM3leta0Given) + model->BSIM3leta0 = 0.0; + if (!model->BSIM3letabGiven) + model->BSIM3letab = -0.0; + if (!model->BSIM3lpclmGiven) + model->BSIM3lpclm = 0.0; + if (!model->BSIM3lpdibl1Given) + model->BSIM3lpdibl1 = 0.0; + if (!model->BSIM3lpdibl2Given) + model->BSIM3lpdibl2 = 0.0; + if (!model->BSIM3lpdiblbGiven) + model->BSIM3lpdiblb = 0.0; + if (!model->BSIM3lpscbe1Given) + model->BSIM3lpscbe1 = 0.0; + if (!model->BSIM3lpscbe2Given) + model->BSIM3lpscbe2 = 0.0; + if (!model->BSIM3lpvagGiven) + model->BSIM3lpvag = 0.0; + if (!model->BSIM3lwrGiven) + model->BSIM3lwr = 0.0; + if (!model->BSIM3ldwgGiven) + model->BSIM3ldwg = 0.0; + if (!model->BSIM3ldwbGiven) + model->BSIM3ldwb = 0.0; + if (!model->BSIM3lb0Given) + model->BSIM3lb0 = 0.0; + if (!model->BSIM3lb1Given) + model->BSIM3lb1 = 0.0; + if (!model->BSIM3lalpha0Given) + model->BSIM3lalpha0 = 0.0; + if (!model->BSIM3lalpha1Given) + model->BSIM3lalpha1 = 0.0; + if (!model->BSIM3lbeta0Given) + model->BSIM3lbeta0 = 0.0; + if (!model->BSIM3lvfbGiven) + model->BSIM3lvfb = 0.0; - if (!model->BSIM3lelmGiven) - model->BSIM3lelm = 0.0; - if (!model->BSIM3lcgslGiven) - model->BSIM3lcgsl = 0.0; - if (!model->BSIM3lcgdlGiven) - model->BSIM3lcgdl = 0.0; - if (!model->BSIM3lckappaGiven) - model->BSIM3lckappa = 0.0; - if (!model->BSIM3lclcGiven) - model->BSIM3lclc = 0.0; - if (!model->BSIM3lcleGiven) - model->BSIM3lcle = 0.0; - if (!model->BSIM3lcfGiven) - model->BSIM3lcf = 0.0; - if (!model->BSIM3lvfbcvGiven) - model->BSIM3lvfbcv = 0.0; - if (!model->BSIM3lacdeGiven) - model->BSIM3lacde = 0.0; - if (!model->BSIM3lmoinGiven) - model->BSIM3lmoin = 0.0; - if (!model->BSIM3lnoffGiven) - model->BSIM3lnoff = 0.0; - if (!model->BSIM3lvoffcvGiven) - model->BSIM3lvoffcv = 0.0; + if (!model->BSIM3lelmGiven) + model->BSIM3lelm = 0.0; + if (!model->BSIM3lcgslGiven) + model->BSIM3lcgsl = 0.0; + if (!model->BSIM3lcgdlGiven) + model->BSIM3lcgdl = 0.0; + if (!model->BSIM3lckappaGiven) + model->BSIM3lckappa = 0.0; + if (!model->BSIM3lclcGiven) + model->BSIM3lclc = 0.0; + if (!model->BSIM3lcleGiven) + model->BSIM3lcle = 0.0; + if (!model->BSIM3lcfGiven) + model->BSIM3lcf = 0.0; + if (!model->BSIM3lvfbcvGiven) + model->BSIM3lvfbcv = 0.0; + if (!model->BSIM3lacdeGiven) + model->BSIM3lacde = 0.0; + if (!model->BSIM3lmoinGiven) + model->BSIM3lmoin = 0.0; + if (!model->BSIM3lnoffGiven) + model->BSIM3lnoff = 0.0; + if (!model->BSIM3lvoffcvGiven) + model->BSIM3lvoffcv = 0.0; - /* Width dependence */ - if (!model->BSIM3wcdscGiven) - model->BSIM3wcdsc = 0.0; - if (!model->BSIM3wcdscbGiven) - model->BSIM3wcdscb = 0.0; - if (!model->BSIM3wcdscdGiven) - model->BSIM3wcdscd = 0.0; - if (!model->BSIM3wcitGiven) - model->BSIM3wcit = 0.0; - if (!model->BSIM3wnfactorGiven) - model->BSIM3wnfactor = 0.0; - if (!model->BSIM3wxjGiven) - model->BSIM3wxj = 0.0; - if (!model->BSIM3wvsatGiven) - model->BSIM3wvsat = 0.0; - if (!model->BSIM3watGiven) - model->BSIM3wat = 0.0; - if (!model->BSIM3wa0Given) - model->BSIM3wa0 = 0.0; - if (!model->BSIM3wagsGiven) - model->BSIM3wags = 0.0; - if (!model->BSIM3wa1Given) - model->BSIM3wa1 = 0.0; - if (!model->BSIM3wa2Given) - model->BSIM3wa2 = 0.0; - if (!model->BSIM3wketaGiven) - model->BSIM3wketa = 0.0; - if (!model->BSIM3wnsubGiven) - model->BSIM3wnsub = 0.0; - if (!model->BSIM3wnpeakGiven) - model->BSIM3wnpeak = 0.0; - if (!model->BSIM3wngateGiven) - model->BSIM3wngate = 0.0; - if (!model->BSIM3wvbmGiven) - model->BSIM3wvbm = 0.0; - if (!model->BSIM3wxtGiven) - model->BSIM3wxt = 0.0; - if (!model->BSIM3wkt1Given) - model->BSIM3wkt1 = 0.0; - if (!model->BSIM3wkt1lGiven) - model->BSIM3wkt1l = 0.0; - if (!model->BSIM3wkt2Given) - model->BSIM3wkt2 = 0.0; - if (!model->BSIM3wk3Given) - model->BSIM3wk3 = 0.0; - if (!model->BSIM3wk3bGiven) - model->BSIM3wk3b = 0.0; - if (!model->BSIM3ww0Given) - model->BSIM3ww0 = 0.0; - if (!model->BSIM3wnlxGiven) - model->BSIM3wnlx = 0.0; - if (!model->BSIM3wdvt0Given) - model->BSIM3wdvt0 = 0.0; - if (!model->BSIM3wdvt1Given) - model->BSIM3wdvt1 = 0.0; - if (!model->BSIM3wdvt2Given) - model->BSIM3wdvt2 = 0.0; - if (!model->BSIM3wdvt0wGiven) - model->BSIM3wdvt0w = 0.0; - if (!model->BSIM3wdvt1wGiven) - model->BSIM3wdvt1w = 0.0; - if (!model->BSIM3wdvt2wGiven) - model->BSIM3wdvt2w = 0.0; - if (!model->BSIM3wdroutGiven) - model->BSIM3wdrout = 0.0; - if (!model->BSIM3wdsubGiven) - model->BSIM3wdsub = 0.0; - if (!model->BSIM3wvth0Given) - model->BSIM3wvth0 = 0.0; - if (!model->BSIM3wuaGiven) - model->BSIM3wua = 0.0; - if (!model->BSIM3wua1Given) - model->BSIM3wua1 = 0.0; - if (!model->BSIM3wubGiven) - model->BSIM3wub = 0.0; - if (!model->BSIM3wub1Given) - model->BSIM3wub1 = 0.0; - if (!model->BSIM3wucGiven) - model->BSIM3wuc = 0.0; - if (!model->BSIM3wuc1Given) - model->BSIM3wuc1 = 0.0; - if (!model->BSIM3wu0Given) - model->BSIM3wu0 = 0.0; - if (!model->BSIM3wuteGiven) - model->BSIM3wute = 0.0; - if (!model->BSIM3wvoffGiven) - model->BSIM3wvoff = 0.0; - if (!model->BSIM3wdeltaGiven) - model->BSIM3wdelta = 0.0; - if (!model->BSIM3wrdswGiven) - model->BSIM3wrdsw = 0.0; - if (!model->BSIM3wprwbGiven) - model->BSIM3wprwb = 0.0; - if (!model->BSIM3wprwgGiven) - model->BSIM3wprwg = 0.0; - if (!model->BSIM3wprtGiven) - model->BSIM3wprt = 0.0; - if (!model->BSIM3weta0Given) - model->BSIM3weta0 = 0.0; - if (!model->BSIM3wetabGiven) - model->BSIM3wetab = 0.0; - if (!model->BSIM3wpclmGiven) - model->BSIM3wpclm = 0.0; - if (!model->BSIM3wpdibl1Given) - model->BSIM3wpdibl1 = 0.0; - if (!model->BSIM3wpdibl2Given) - model->BSIM3wpdibl2 = 0.0; - if (!model->BSIM3wpdiblbGiven) - model->BSIM3wpdiblb = 0.0; - if (!model->BSIM3wpscbe1Given) - model->BSIM3wpscbe1 = 0.0; - if (!model->BSIM3wpscbe2Given) - model->BSIM3wpscbe2 = 0.0; - if (!model->BSIM3wpvagGiven) - model->BSIM3wpvag = 0.0; - if (!model->BSIM3wwrGiven) - model->BSIM3wwr = 0.0; - if (!model->BSIM3wdwgGiven) - model->BSIM3wdwg = 0.0; - if (!model->BSIM3wdwbGiven) - model->BSIM3wdwb = 0.0; - if (!model->BSIM3wb0Given) - model->BSIM3wb0 = 0.0; - if (!model->BSIM3wb1Given) - model->BSIM3wb1 = 0.0; - if (!model->BSIM3walpha0Given) - model->BSIM3walpha0 = 0.0; - if (!model->BSIM3walpha1Given) - model->BSIM3walpha1 = 0.0; - if (!model->BSIM3wbeta0Given) - model->BSIM3wbeta0 = 0.0; - if (!model->BSIM3wvfbGiven) - model->BSIM3wvfb = 0.0; + /* Width dependence */ + if (!model->BSIM3wcdscGiven) + model->BSIM3wcdsc = 0.0; + if (!model->BSIM3wcdscbGiven) + model->BSIM3wcdscb = 0.0; + if (!model->BSIM3wcdscdGiven) + model->BSIM3wcdscd = 0.0; + if (!model->BSIM3wcitGiven) + model->BSIM3wcit = 0.0; + if (!model->BSIM3wnfactorGiven) + model->BSIM3wnfactor = 0.0; + if (!model->BSIM3wxjGiven) + model->BSIM3wxj = 0.0; + if (!model->BSIM3wvsatGiven) + model->BSIM3wvsat = 0.0; + if (!model->BSIM3watGiven) + model->BSIM3wat = 0.0; + if (!model->BSIM3wa0Given) + model->BSIM3wa0 = 0.0; + if (!model->BSIM3wagsGiven) + model->BSIM3wags = 0.0; + if (!model->BSIM3wa1Given) + model->BSIM3wa1 = 0.0; + if (!model->BSIM3wa2Given) + model->BSIM3wa2 = 0.0; + if (!model->BSIM3wketaGiven) + model->BSIM3wketa = 0.0; + if (!model->BSIM3wnsubGiven) + model->BSIM3wnsub = 0.0; + if (!model->BSIM3wnpeakGiven) + model->BSIM3wnpeak = 0.0; + if (!model->BSIM3wngateGiven) + model->BSIM3wngate = 0.0; + if (!model->BSIM3wvbmGiven) + model->BSIM3wvbm = 0.0; + if (!model->BSIM3wxtGiven) + model->BSIM3wxt = 0.0; + if (!model->BSIM3wkt1Given) + model->BSIM3wkt1 = 0.0; + if (!model->BSIM3wkt1lGiven) + model->BSIM3wkt1l = 0.0; + if (!model->BSIM3wkt2Given) + model->BSIM3wkt2 = 0.0; + if (!model->BSIM3wk3Given) + model->BSIM3wk3 = 0.0; + if (!model->BSIM3wk3bGiven) + model->BSIM3wk3b = 0.0; + if (!model->BSIM3ww0Given) + model->BSIM3ww0 = 0.0; + if (!model->BSIM3wnlxGiven) + model->BSIM3wnlx = 0.0; + if (!model->BSIM3wdvt0Given) + model->BSIM3wdvt0 = 0.0; + if (!model->BSIM3wdvt1Given) + model->BSIM3wdvt1 = 0.0; + if (!model->BSIM3wdvt2Given) + model->BSIM3wdvt2 = 0.0; + if (!model->BSIM3wdvt0wGiven) + model->BSIM3wdvt0w = 0.0; + if (!model->BSIM3wdvt1wGiven) + model->BSIM3wdvt1w = 0.0; + if (!model->BSIM3wdvt2wGiven) + model->BSIM3wdvt2w = 0.0; + if (!model->BSIM3wdroutGiven) + model->BSIM3wdrout = 0.0; + if (!model->BSIM3wdsubGiven) + model->BSIM3wdsub = 0.0; + if (!model->BSIM3wvth0Given) + model->BSIM3wvth0 = 0.0; + if (!model->BSIM3wuaGiven) + model->BSIM3wua = 0.0; + if (!model->BSIM3wua1Given) + model->BSIM3wua1 = 0.0; + if (!model->BSIM3wubGiven) + model->BSIM3wub = 0.0; + if (!model->BSIM3wub1Given) + model->BSIM3wub1 = 0.0; + if (!model->BSIM3wucGiven) + model->BSIM3wuc = 0.0; + if (!model->BSIM3wuc1Given) + model->BSIM3wuc1 = 0.0; + if (!model->BSIM3wu0Given) + model->BSIM3wu0 = 0.0; + if (!model->BSIM3wuteGiven) + model->BSIM3wute = 0.0; + if (!model->BSIM3wvoffGiven) + model->BSIM3wvoff = 0.0; + if (!model->BSIM3wdeltaGiven) + model->BSIM3wdelta = 0.0; + if (!model->BSIM3wrdswGiven) + model->BSIM3wrdsw = 0.0; + if (!model->BSIM3wprwbGiven) + model->BSIM3wprwb = 0.0; + if (!model->BSIM3wprwgGiven) + model->BSIM3wprwg = 0.0; + if (!model->BSIM3wprtGiven) + model->BSIM3wprt = 0.0; + if (!model->BSIM3weta0Given) + model->BSIM3weta0 = 0.0; + if (!model->BSIM3wetabGiven) + model->BSIM3wetab = 0.0; + if (!model->BSIM3wpclmGiven) + model->BSIM3wpclm = 0.0; + if (!model->BSIM3wpdibl1Given) + model->BSIM3wpdibl1 = 0.0; + if (!model->BSIM3wpdibl2Given) + model->BSIM3wpdibl2 = 0.0; + if (!model->BSIM3wpdiblbGiven) + model->BSIM3wpdiblb = 0.0; + if (!model->BSIM3wpscbe1Given) + model->BSIM3wpscbe1 = 0.0; + if (!model->BSIM3wpscbe2Given) + model->BSIM3wpscbe2 = 0.0; + if (!model->BSIM3wpvagGiven) + model->BSIM3wpvag = 0.0; + if (!model->BSIM3wwrGiven) + model->BSIM3wwr = 0.0; + if (!model->BSIM3wdwgGiven) + model->BSIM3wdwg = 0.0; + if (!model->BSIM3wdwbGiven) + model->BSIM3wdwb = 0.0; + if (!model->BSIM3wb0Given) + model->BSIM3wb0 = 0.0; + if (!model->BSIM3wb1Given) + model->BSIM3wb1 = 0.0; + if (!model->BSIM3walpha0Given) + model->BSIM3walpha0 = 0.0; + if (!model->BSIM3walpha1Given) + model->BSIM3walpha1 = 0.0; + if (!model->BSIM3wbeta0Given) + model->BSIM3wbeta0 = 0.0; + if (!model->BSIM3wvfbGiven) + model->BSIM3wvfb = 0.0; - if (!model->BSIM3welmGiven) - model->BSIM3welm = 0.0; - if (!model->BSIM3wcgslGiven) - model->BSIM3wcgsl = 0.0; - if (!model->BSIM3wcgdlGiven) - model->BSIM3wcgdl = 0.0; - if (!model->BSIM3wckappaGiven) - model->BSIM3wckappa = 0.0; - if (!model->BSIM3wcfGiven) - model->BSIM3wcf = 0.0; - if (!model->BSIM3wclcGiven) - model->BSIM3wclc = 0.0; - if (!model->BSIM3wcleGiven) - model->BSIM3wcle = 0.0; - if (!model->BSIM3wvfbcvGiven) - model->BSIM3wvfbcv = 0.0; - if (!model->BSIM3wacdeGiven) - model->BSIM3wacde = 0.0; - if (!model->BSIM3wmoinGiven) - model->BSIM3wmoin = 0.0; - if (!model->BSIM3wnoffGiven) - model->BSIM3wnoff = 0.0; - if (!model->BSIM3wvoffcvGiven) - model->BSIM3wvoffcv = 0.0; + if (!model->BSIM3welmGiven) + model->BSIM3welm = 0.0; + if (!model->BSIM3wcgslGiven) + model->BSIM3wcgsl = 0.0; + if (!model->BSIM3wcgdlGiven) + model->BSIM3wcgdl = 0.0; + if (!model->BSIM3wckappaGiven) + model->BSIM3wckappa = 0.0; + if (!model->BSIM3wcfGiven) + model->BSIM3wcf = 0.0; + if (!model->BSIM3wclcGiven) + model->BSIM3wclc = 0.0; + if (!model->BSIM3wcleGiven) + model->BSIM3wcle = 0.0; + if (!model->BSIM3wvfbcvGiven) + model->BSIM3wvfbcv = 0.0; + if (!model->BSIM3wacdeGiven) + model->BSIM3wacde = 0.0; + if (!model->BSIM3wmoinGiven) + model->BSIM3wmoin = 0.0; + if (!model->BSIM3wnoffGiven) + model->BSIM3wnoff = 0.0; + if (!model->BSIM3wvoffcvGiven) + model->BSIM3wvoffcv = 0.0; - /* Cross-term dependence */ - if (!model->BSIM3pcdscGiven) - model->BSIM3pcdsc = 0.0; - if (!model->BSIM3pcdscbGiven) - model->BSIM3pcdscb = 0.0; - if (!model->BSIM3pcdscdGiven) - model->BSIM3pcdscd = 0.0; - if (!model->BSIM3pcitGiven) - model->BSIM3pcit = 0.0; - if (!model->BSIM3pnfactorGiven) - model->BSIM3pnfactor = 0.0; - if (!model->BSIM3pxjGiven) - model->BSIM3pxj = 0.0; - if (!model->BSIM3pvsatGiven) - model->BSIM3pvsat = 0.0; - if (!model->BSIM3patGiven) - model->BSIM3pat = 0.0; - if (!model->BSIM3pa0Given) - model->BSIM3pa0 = 0.0; - - if (!model->BSIM3pagsGiven) - model->BSIM3pags = 0.0; - if (!model->BSIM3pa1Given) - model->BSIM3pa1 = 0.0; - if (!model->BSIM3pa2Given) - model->BSIM3pa2 = 0.0; - if (!model->BSIM3pketaGiven) - model->BSIM3pketa = 0.0; - if (!model->BSIM3pnsubGiven) - model->BSIM3pnsub = 0.0; - if (!model->BSIM3pnpeakGiven) - model->BSIM3pnpeak = 0.0; - if (!model->BSIM3pngateGiven) - model->BSIM3pngate = 0.0; - if (!model->BSIM3pvbmGiven) - model->BSIM3pvbm = 0.0; - if (!model->BSIM3pxtGiven) - model->BSIM3pxt = 0.0; - if (!model->BSIM3pkt1Given) - model->BSIM3pkt1 = 0.0; - if (!model->BSIM3pkt1lGiven) - model->BSIM3pkt1l = 0.0; - if (!model->BSIM3pkt2Given) - model->BSIM3pkt2 = 0.0; - if (!model->BSIM3pk3Given) - model->BSIM3pk3 = 0.0; - if (!model->BSIM3pk3bGiven) - model->BSIM3pk3b = 0.0; - if (!model->BSIM3pw0Given) - model->BSIM3pw0 = 0.0; - if (!model->BSIM3pnlxGiven) - model->BSIM3pnlx = 0.0; - if (!model->BSIM3pdvt0Given) - model->BSIM3pdvt0 = 0.0; - if (!model->BSIM3pdvt1Given) - model->BSIM3pdvt1 = 0.0; - if (!model->BSIM3pdvt2Given) - model->BSIM3pdvt2 = 0.0; - if (!model->BSIM3pdvt0wGiven) - model->BSIM3pdvt0w = 0.0; - if (!model->BSIM3pdvt1wGiven) - model->BSIM3pdvt1w = 0.0; - if (!model->BSIM3pdvt2wGiven) - model->BSIM3pdvt2w = 0.0; - if (!model->BSIM3pdroutGiven) - model->BSIM3pdrout = 0.0; - if (!model->BSIM3pdsubGiven) - model->BSIM3pdsub = 0.0; - if (!model->BSIM3pvth0Given) - model->BSIM3pvth0 = 0.0; - if (!model->BSIM3puaGiven) - model->BSIM3pua = 0.0; - if (!model->BSIM3pua1Given) - model->BSIM3pua1 = 0.0; - if (!model->BSIM3pubGiven) - model->BSIM3pub = 0.0; - if (!model->BSIM3pub1Given) - model->BSIM3pub1 = 0.0; - if (!model->BSIM3pucGiven) - model->BSIM3puc = 0.0; - if (!model->BSIM3puc1Given) - model->BSIM3puc1 = 0.0; - if (!model->BSIM3pu0Given) - model->BSIM3pu0 = 0.0; - if (!model->BSIM3puteGiven) - model->BSIM3pute = 0.0; - if (!model->BSIM3pvoffGiven) - model->BSIM3pvoff = 0.0; - if (!model->BSIM3pdeltaGiven) - model->BSIM3pdelta = 0.0; - if (!model->BSIM3prdswGiven) - model->BSIM3prdsw = 0.0; - if (!model->BSIM3pprwbGiven) - model->BSIM3pprwb = 0.0; - if (!model->BSIM3pprwgGiven) - model->BSIM3pprwg = 0.0; - if (!model->BSIM3pprtGiven) - model->BSIM3pprt = 0.0; - if (!model->BSIM3peta0Given) - model->BSIM3peta0 = 0.0; - if (!model->BSIM3petabGiven) - model->BSIM3petab = 0.0; - if (!model->BSIM3ppclmGiven) - model->BSIM3ppclm = 0.0; - if (!model->BSIM3ppdibl1Given) - model->BSIM3ppdibl1 = 0.0; - if (!model->BSIM3ppdibl2Given) - model->BSIM3ppdibl2 = 0.0; - if (!model->BSIM3ppdiblbGiven) - model->BSIM3ppdiblb = 0.0; - if (!model->BSIM3ppscbe1Given) - model->BSIM3ppscbe1 = 0.0; - if (!model->BSIM3ppscbe2Given) - model->BSIM3ppscbe2 = 0.0; - if (!model->BSIM3ppvagGiven) - model->BSIM3ppvag = 0.0; - if (!model->BSIM3pwrGiven) - model->BSIM3pwr = 0.0; - if (!model->BSIM3pdwgGiven) - model->BSIM3pdwg = 0.0; - if (!model->BSIM3pdwbGiven) - model->BSIM3pdwb = 0.0; - if (!model->BSIM3pb0Given) - model->BSIM3pb0 = 0.0; - if (!model->BSIM3pb1Given) - model->BSIM3pb1 = 0.0; - if (!model->BSIM3palpha0Given) - model->BSIM3palpha0 = 0.0; - if (!model->BSIM3palpha1Given) - model->BSIM3palpha1 = 0.0; - if (!model->BSIM3pbeta0Given) - model->BSIM3pbeta0 = 0.0; - if (!model->BSIM3pvfbGiven) - model->BSIM3pvfb = 0.0; + /* Cross-term dependence */ + if (!model->BSIM3pcdscGiven) + model->BSIM3pcdsc = 0.0; + if (!model->BSIM3pcdscbGiven) + model->BSIM3pcdscb = 0.0; + if (!model->BSIM3pcdscdGiven) + model->BSIM3pcdscd = 0.0; + if (!model->BSIM3pcitGiven) + model->BSIM3pcit = 0.0; + if (!model->BSIM3pnfactorGiven) + model->BSIM3pnfactor = 0.0; + if (!model->BSIM3pxjGiven) + model->BSIM3pxj = 0.0; + if (!model->BSIM3pvsatGiven) + model->BSIM3pvsat = 0.0; + if (!model->BSIM3patGiven) + model->BSIM3pat = 0.0; + if (!model->BSIM3pa0Given) + model->BSIM3pa0 = 0.0; - if (!model->BSIM3pelmGiven) - model->BSIM3pelm = 0.0; - if (!model->BSIM3pcgslGiven) - model->BSIM3pcgsl = 0.0; - if (!model->BSIM3pcgdlGiven) - model->BSIM3pcgdl = 0.0; - if (!model->BSIM3pckappaGiven) - model->BSIM3pckappa = 0.0; - if (!model->BSIM3pcfGiven) - model->BSIM3pcf = 0.0; - if (!model->BSIM3pclcGiven) - model->BSIM3pclc = 0.0; - if (!model->BSIM3pcleGiven) - model->BSIM3pcle = 0.0; - if (!model->BSIM3pvfbcvGiven) - model->BSIM3pvfbcv = 0.0; - if (!model->BSIM3pacdeGiven) - model->BSIM3pacde = 0.0; - if (!model->BSIM3pmoinGiven) - model->BSIM3pmoin = 0.0; - if (!model->BSIM3pnoffGiven) - model->BSIM3pnoff = 0.0; - if (!model->BSIM3pvoffcvGiven) - model->BSIM3pvoffcv = 0.0; + if (!model->BSIM3pagsGiven) + model->BSIM3pags = 0.0; + if (!model->BSIM3pa1Given) + model->BSIM3pa1 = 0.0; + if (!model->BSIM3pa2Given) + model->BSIM3pa2 = 0.0; + if (!model->BSIM3pketaGiven) + model->BSIM3pketa = 0.0; + if (!model->BSIM3pnsubGiven) + model->BSIM3pnsub = 0.0; + if (!model->BSIM3pnpeakGiven) + model->BSIM3pnpeak = 0.0; + if (!model->BSIM3pngateGiven) + model->BSIM3pngate = 0.0; + if (!model->BSIM3pvbmGiven) + model->BSIM3pvbm = 0.0; + if (!model->BSIM3pxtGiven) + model->BSIM3pxt = 0.0; + if (!model->BSIM3pkt1Given) + model->BSIM3pkt1 = 0.0; + if (!model->BSIM3pkt1lGiven) + model->BSIM3pkt1l = 0.0; + if (!model->BSIM3pkt2Given) + model->BSIM3pkt2 = 0.0; + if (!model->BSIM3pk3Given) + model->BSIM3pk3 = 0.0; + if (!model->BSIM3pk3bGiven) + model->BSIM3pk3b = 0.0; + if (!model->BSIM3pw0Given) + model->BSIM3pw0 = 0.0; + if (!model->BSIM3pnlxGiven) + model->BSIM3pnlx = 0.0; + if (!model->BSIM3pdvt0Given) + model->BSIM3pdvt0 = 0.0; + if (!model->BSIM3pdvt1Given) + model->BSIM3pdvt1 = 0.0; + if (!model->BSIM3pdvt2Given) + model->BSIM3pdvt2 = 0.0; + if (!model->BSIM3pdvt0wGiven) + model->BSIM3pdvt0w = 0.0; + if (!model->BSIM3pdvt1wGiven) + model->BSIM3pdvt1w = 0.0; + if (!model->BSIM3pdvt2wGiven) + model->BSIM3pdvt2w = 0.0; + if (!model->BSIM3pdroutGiven) + model->BSIM3pdrout = 0.0; + if (!model->BSIM3pdsubGiven) + model->BSIM3pdsub = 0.0; + if (!model->BSIM3pvth0Given) + model->BSIM3pvth0 = 0.0; + if (!model->BSIM3puaGiven) + model->BSIM3pua = 0.0; + if (!model->BSIM3pua1Given) + model->BSIM3pua1 = 0.0; + if (!model->BSIM3pubGiven) + model->BSIM3pub = 0.0; + if (!model->BSIM3pub1Given) + model->BSIM3pub1 = 0.0; + if (!model->BSIM3pucGiven) + model->BSIM3puc = 0.0; + if (!model->BSIM3puc1Given) + model->BSIM3puc1 = 0.0; + if (!model->BSIM3pu0Given) + model->BSIM3pu0 = 0.0; + if (!model->BSIM3puteGiven) + model->BSIM3pute = 0.0; + if (!model->BSIM3pvoffGiven) + model->BSIM3pvoff = 0.0; + if (!model->BSIM3pdeltaGiven) + model->BSIM3pdelta = 0.0; + if (!model->BSIM3prdswGiven) + model->BSIM3prdsw = 0.0; + if (!model->BSIM3pprwbGiven) + model->BSIM3pprwb = 0.0; + if (!model->BSIM3pprwgGiven) + model->BSIM3pprwg = 0.0; + if (!model->BSIM3pprtGiven) + model->BSIM3pprt = 0.0; + if (!model->BSIM3peta0Given) + model->BSIM3peta0 = 0.0; + if (!model->BSIM3petabGiven) + model->BSIM3petab = 0.0; + if (!model->BSIM3ppclmGiven) + model->BSIM3ppclm = 0.0; + if (!model->BSIM3ppdibl1Given) + model->BSIM3ppdibl1 = 0.0; + if (!model->BSIM3ppdibl2Given) + model->BSIM3ppdibl2 = 0.0; + if (!model->BSIM3ppdiblbGiven) + model->BSIM3ppdiblb = 0.0; + if (!model->BSIM3ppscbe1Given) + model->BSIM3ppscbe1 = 0.0; + if (!model->BSIM3ppscbe2Given) + model->BSIM3ppscbe2 = 0.0; + if (!model->BSIM3ppvagGiven) + model->BSIM3ppvag = 0.0; + if (!model->BSIM3pwrGiven) + model->BSIM3pwr = 0.0; + if (!model->BSIM3pdwgGiven) + model->BSIM3pdwg = 0.0; + if (!model->BSIM3pdwbGiven) + model->BSIM3pdwb = 0.0; + if (!model->BSIM3pb0Given) + model->BSIM3pb0 = 0.0; + if (!model->BSIM3pb1Given) + model->BSIM3pb1 = 0.0; + if (!model->BSIM3palpha0Given) + model->BSIM3palpha0 = 0.0; + if (!model->BSIM3palpha1Given) + model->BSIM3palpha1 = 0.0; + if (!model->BSIM3pbeta0Given) + model->BSIM3pbeta0 = 0.0; + if (!model->BSIM3pvfbGiven) + model->BSIM3pvfb = 0.0; - /* unit degree celcius */ - if (!model->BSIM3tnomGiven) - model->BSIM3tnom = ckt->CKTnomTemp; - else - model->BSIM3tnom = model->BSIM3tnom + 273.15; - if (!model->BSIM3LintGiven) - model->BSIM3Lint = 0.0; - if (!model->BSIM3LlGiven) - model->BSIM3Ll = 0.0; - if (!model->BSIM3LlcGiven) - model->BSIM3Llc = model->BSIM3Ll; - if (!model->BSIM3LlnGiven) - model->BSIM3Lln = 1.0; - if (!model->BSIM3LwGiven) - model->BSIM3Lw = 0.0; - if (!model->BSIM3LwcGiven) - model->BSIM3Lwc = model->BSIM3Lw; - if (!model->BSIM3LwnGiven) - model->BSIM3Lwn = 1.0; - if (!model->BSIM3LwlGiven) - model->BSIM3Lwl = 0.0; - if (!model->BSIM3LwlcGiven) - model->BSIM3Lwlc = model->BSIM3Lwl; - if (!model->BSIM3LminGiven) - model->BSIM3Lmin = 0.0; - if (!model->BSIM3LmaxGiven) - model->BSIM3Lmax = 1.0; - if (!model->BSIM3WintGiven) - model->BSIM3Wint = 0.0; - if (!model->BSIM3WlGiven) - model->BSIM3Wl = 0.0; - if (!model->BSIM3WlcGiven) - model->BSIM3Wlc = model->BSIM3Wl; - if (!model->BSIM3WlnGiven) - model->BSIM3Wln = 1.0; - if (!model->BSIM3WwGiven) - model->BSIM3Ww = 0.0; - if (!model->BSIM3WwcGiven) - model->BSIM3Wwc = model->BSIM3Ww; - if (!model->BSIM3WwnGiven) - model->BSIM3Wwn = 1.0; - if (!model->BSIM3WwlGiven) - model->BSIM3Wwl = 0.0; - if (!model->BSIM3WwlcGiven) - model->BSIM3Wwlc = model->BSIM3Wwl; - if (!model->BSIM3WminGiven) - model->BSIM3Wmin = 0.0; - if (!model->BSIM3WmaxGiven) - model->BSIM3Wmax = 1.0; - if (!model->BSIM3dwcGiven) - model->BSIM3dwc = model->BSIM3Wint; - if (!model->BSIM3dlcGiven) - model->BSIM3dlc = model->BSIM3Lint; - if (!model->BSIM3cfGiven) - model->BSIM3cf = 2.0 * EPSOX / M_PI - * log(1.0 + 0.4e-6 / model->BSIM3tox); - if (!model->BSIM3cgdoGiven) - { if (model->BSIM3dlcGiven && (model->BSIM3dlc > 0.0)) - { model->BSIM3cgdo = model->BSIM3dlc * model->BSIM3cox - - model->BSIM3cgdl ; + if (!model->BSIM3pelmGiven) + model->BSIM3pelm = 0.0; + if (!model->BSIM3pcgslGiven) + model->BSIM3pcgsl = 0.0; + if (!model->BSIM3pcgdlGiven) + model->BSIM3pcgdl = 0.0; + if (!model->BSIM3pckappaGiven) + model->BSIM3pckappa = 0.0; + if (!model->BSIM3pcfGiven) + model->BSIM3pcf = 0.0; + if (!model->BSIM3pclcGiven) + model->BSIM3pclc = 0.0; + if (!model->BSIM3pcleGiven) + model->BSIM3pcle = 0.0; + if (!model->BSIM3pvfbcvGiven) + model->BSIM3pvfbcv = 0.0; + if (!model->BSIM3pacdeGiven) + model->BSIM3pacde = 0.0; + if (!model->BSIM3pmoinGiven) + model->BSIM3pmoin = 0.0; + if (!model->BSIM3pnoffGiven) + model->BSIM3pnoff = 0.0; + if (!model->BSIM3pvoffcvGiven) + model->BSIM3pvoffcv = 0.0; + + /* unit degree celcius */ + if (!model->BSIM3tnomGiven) + model->BSIM3tnom = ckt->CKTnomTemp; + /* else + model->BSIM3tnom = model->BSIM3tnom + 273.15; */ + if (!model->BSIM3LintGiven) + model->BSIM3Lint = 0.0; + if (!model->BSIM3LlGiven) + model->BSIM3Ll = 0.0; + if (!model->BSIM3LlcGiven) + model->BSIM3Llc = model->BSIM3Ll; + if (!model->BSIM3LlnGiven) + model->BSIM3Lln = 1.0; + if (!model->BSIM3LwGiven) + model->BSIM3Lw = 0.0; + if (!model->BSIM3LwcGiven) + model->BSIM3Lwc = model->BSIM3Lw; + if (!model->BSIM3LwnGiven) + model->BSIM3Lwn = 1.0; + if (!model->BSIM3LwlGiven) + model->BSIM3Lwl = 0.0; + if (!model->BSIM3LwlcGiven) + model->BSIM3Lwlc = model->BSIM3Lwl; + if (!model->BSIM3LminGiven) + model->BSIM3Lmin = 0.0; + if (!model->BSIM3LmaxGiven) + model->BSIM3Lmax = 1.0; + if (!model->BSIM3WintGiven) + model->BSIM3Wint = 0.0; + if (!model->BSIM3WlGiven) + model->BSIM3Wl = 0.0; + if (!model->BSIM3WlcGiven) + model->BSIM3Wlc = model->BSIM3Wl; + if (!model->BSIM3WlnGiven) + model->BSIM3Wln = 1.0; + if (!model->BSIM3WwGiven) + model->BSIM3Ww = 0.0; + if (!model->BSIM3WwcGiven) + model->BSIM3Wwc = model->BSIM3Ww; + if (!model->BSIM3WwnGiven) + model->BSIM3Wwn = 1.0; + if (!model->BSIM3WwlGiven) + model->BSIM3Wwl = 0.0; + if (!model->BSIM3WwlcGiven) + model->BSIM3Wwlc = model->BSIM3Wwl; + if (!model->BSIM3WminGiven) + model->BSIM3Wmin = 0.0; + if (!model->BSIM3WmaxGiven) + model->BSIM3Wmax = 1.0; + if (!model->BSIM3dwcGiven) + model->BSIM3dwc = model->BSIM3Wint; + if (!model->BSIM3dlcGiven) + model->BSIM3dlc = model->BSIM3Lint; + if (!model->BSIM3cfGiven) + model->BSIM3cf = 2.0 * EPSOX / M_PI + * log (1.0 + 0.4e-6 / model->BSIM3tox); + if (!model->BSIM3cgdoGiven) + { + if (model->BSIM3dlcGiven && (model->BSIM3dlc > 0.0)) + { + model->BSIM3cgdo = model->BSIM3dlc * model->BSIM3cox + - model->BSIM3cgdl; } - else - model->BSIM3cgdo = 0.6 * model->BSIM3xj * model->BSIM3cox; + else + model->BSIM3cgdo = 0.6 * model->BSIM3xj * model->BSIM3cox; } - if (!model->BSIM3cgsoGiven) - { if (model->BSIM3dlcGiven && (model->BSIM3dlc > 0.0)) - { model->BSIM3cgso = model->BSIM3dlc * model->BSIM3cox - - model->BSIM3cgsl ; + if (!model->BSIM3cgsoGiven) + { + if (model->BSIM3dlcGiven && (model->BSIM3dlc > 0.0)) + { + model->BSIM3cgso = model->BSIM3dlc * model->BSIM3cox + - model->BSIM3cgsl; } - else - model->BSIM3cgso = 0.6 * model->BSIM3xj * model->BSIM3cox; + else + model->BSIM3cgso = 0.6 * model->BSIM3xj * model->BSIM3cox; } - if (!model->BSIM3cgboGiven) - { model->BSIM3cgbo = 2.0 * model->BSIM3dwc * model->BSIM3cox; + if (!model->BSIM3cgboGiven) + { + model->BSIM3cgbo = 2.0 * model->BSIM3dwc * model->BSIM3cox; } - if (!model->BSIM3xpartGiven) - model->BSIM3xpart = 0.0; - if (!model->BSIM3sheetResistanceGiven) - model->BSIM3sheetResistance = 0.0; - if (!model->BSIM3unitAreaJctCapGiven) - model->BSIM3unitAreaJctCap = 5.0E-4; - if (!model->BSIM3unitLengthSidewallJctCapGiven) - model->BSIM3unitLengthSidewallJctCap = 5.0E-10; - if (!model->BSIM3unitLengthGateSidewallJctCapGiven) - model->BSIM3unitLengthGateSidewallJctCap = model->BSIM3unitLengthSidewallJctCap ; - if (!model->BSIM3jctSatCurDensityGiven) - model->BSIM3jctSatCurDensity = 1.0E-4; - if (!model->BSIM3jctSidewallSatCurDensityGiven) - model->BSIM3jctSidewallSatCurDensity = 0.0; - if (!model->BSIM3bulkJctPotentialGiven) - model->BSIM3bulkJctPotential = 1.0; - if (!model->BSIM3sidewallJctPotentialGiven) - model->BSIM3sidewallJctPotential = 1.0; - if (!model->BSIM3GatesidewallJctPotentialGiven) - model->BSIM3GatesidewallJctPotential = model->BSIM3sidewallJctPotential; - if (!model->BSIM3bulkJctBotGradingCoeffGiven) - model->BSIM3bulkJctBotGradingCoeff = 0.5; - if (!model->BSIM3bulkJctSideGradingCoeffGiven) - model->BSIM3bulkJctSideGradingCoeff = 0.33; - if (!model->BSIM3bulkJctGateSideGradingCoeffGiven) - model->BSIM3bulkJctGateSideGradingCoeff = model->BSIM3bulkJctSideGradingCoeff; - if (!model->BSIM3jctEmissionCoeffGiven) - model->BSIM3jctEmissionCoeff = 1.0; - if (!model->BSIM3jctTempExponentGiven) - model->BSIM3jctTempExponent = 3.0; - if (!model->BSIM3oxideTrapDensityAGiven) - { if (model->BSIM3type == NMOS) - model->BSIM3oxideTrapDensityA = 1e20; - else - model->BSIM3oxideTrapDensityA=9.9e18; + if (!model->BSIM3xpartGiven) + model->BSIM3xpart = 0.0; + if (!model->BSIM3sheetResistanceGiven) + model->BSIM3sheetResistance = 0.0; + if (!model->BSIM3unitAreaJctCapGiven) + model->BSIM3unitAreaJctCap = 5.0E-4; + if (!model->BSIM3unitLengthSidewallJctCapGiven) + model->BSIM3unitLengthSidewallJctCap = 5.0E-10; + if (!model->BSIM3unitLengthGateSidewallJctCapGiven) + model->BSIM3unitLengthGateSidewallJctCap = + model->BSIM3unitLengthSidewallJctCap; + if (!model->BSIM3jctSatCurDensityGiven) + model->BSIM3jctSatCurDensity = 1.0E-4; + if (!model->BSIM3jctSidewallSatCurDensityGiven) + model->BSIM3jctSidewallSatCurDensity = 0.0; + if (!model->BSIM3bulkJctPotentialGiven) + model->BSIM3bulkJctPotential = 1.0; + if (!model->BSIM3sidewallJctPotentialGiven) + model->BSIM3sidewallJctPotential = 1.0; + if (!model->BSIM3GatesidewallJctPotentialGiven) + model->BSIM3GatesidewallJctPotential = + model->BSIM3sidewallJctPotential; + if (!model->BSIM3bulkJctBotGradingCoeffGiven) + model->BSIM3bulkJctBotGradingCoeff = 0.5; + if (!model->BSIM3bulkJctSideGradingCoeffGiven) + model->BSIM3bulkJctSideGradingCoeff = 0.33; + if (!model->BSIM3bulkJctGateSideGradingCoeffGiven) + model->BSIM3bulkJctGateSideGradingCoeff = + model->BSIM3bulkJctSideGradingCoeff; + if (!model->BSIM3jctEmissionCoeffGiven) + model->BSIM3jctEmissionCoeff = 1.0; + if (!model->BSIM3jctTempExponentGiven) + model->BSIM3jctTempExponent = 3.0; + if (!model->BSIM3oxideTrapDensityAGiven) + { + if (model->BSIM3type == NMOS) + model->BSIM3oxideTrapDensityA = 1e20; + else + model->BSIM3oxideTrapDensityA = 9.9e18; } - if (!model->BSIM3oxideTrapDensityBGiven) - { if (model->BSIM3type == NMOS) - model->BSIM3oxideTrapDensityB = 5e4; - else - model->BSIM3oxideTrapDensityB = 2.4e3; + if (!model->BSIM3oxideTrapDensityBGiven) + { + if (model->BSIM3type == NMOS) + model->BSIM3oxideTrapDensityB = 5e4; + else + model->BSIM3oxideTrapDensityB = 2.4e3; } - if (!model->BSIM3oxideTrapDensityCGiven) - { if (model->BSIM3type == NMOS) - model->BSIM3oxideTrapDensityC = -1.4e-12; - else - model->BSIM3oxideTrapDensityC = 1.4e-12; + if (!model->BSIM3oxideTrapDensityCGiven) + { + if (model->BSIM3type == NMOS) + model->BSIM3oxideTrapDensityC = -1.4e-12; + else + model->BSIM3oxideTrapDensityC = 1.4e-12; } - if (!model->BSIM3emGiven) - model->BSIM3em = 4.1e7; /* V/m */ - if (!model->BSIM3efGiven) - model->BSIM3ef = 1.0; - if (!model->BSIM3afGiven) - model->BSIM3af = 1.0; - if (!model->BSIM3kfGiven) - model->BSIM3kf = 0.0; - /* loop through all the instances of the model */ - for (here = model->BSIM3instances; here != NULL ; - here=here->BSIM3nextInstance) - { - if (here->BSIM3owner == ARCHme) { - /* allocate a chunk of the state vector */ - here->BSIM3states = *states; - *states += BSIM3numStates; + if (!model->BSIM3emGiven) + model->BSIM3em = 4.1e7; /* V/m */ + if (!model->BSIM3efGiven) + model->BSIM3ef = 1.0; + if (!model->BSIM3afGiven) + model->BSIM3af = 1.0; + if (!model->BSIM3kfGiven) + model->BSIM3kf = 0.0; + /* loop through all the instances of the model */ + for (here = model->BSIM3instances; here != NULL; + here = here->BSIM3nextInstance) + { + if (here->BSIM3owner == ARCHme) + { + /* allocate a chunk of the state vector */ + + here->BSIM3states = *states; + *states += BSIM3numStates; } - - /* perform the parameter defaulting */ - if (!here->BSIM3drainAreaGiven) - here->BSIM3drainArea = 0.0; - if (!here->BSIM3drainPerimeterGiven) - here->BSIM3drainPerimeter = 0.0; - if (!here->BSIM3drainSquaresGiven) - here->BSIM3drainSquares = 1.0; - if (!here->BSIM3icVBSGiven) - here->BSIM3icVBS = 0.0; - if (!here->BSIM3icVDSGiven) - here->BSIM3icVDS = 0.0; - if (!here->BSIM3icVGSGiven) - here->BSIM3icVGS = 0.0; - if (!here->BSIM3lGiven) - here->BSIM3l = 5.0e-6; - if (!here->BSIM3sourceAreaGiven) - here->BSIM3sourceArea = 0.0; - if (!here->BSIM3sourcePerimeterGiven) - here->BSIM3sourcePerimeter = 0.0; - if (!here->BSIM3sourceSquaresGiven) - here->BSIM3sourceSquares = 1.0; - if (!here->BSIM3wGiven) - here->BSIM3w = 5.0e-6; - if (!here->BSIM3nqsModGiven) - here->BSIM3nqsMod = 0; - - /* process drain series resistance */ - if ((model->BSIM3sheetResistance > 0.0) && - (here->BSIM3drainSquares > 0.0 ) && - (here->BSIM3dNodePrime == 0)) - { error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"drain"); - if(error) return(error); - here->BSIM3dNodePrime = tmp->number; - } - else - { here->BSIM3dNodePrime = here->BSIM3dNode; - } - - /* process source series resistance */ - if ((model->BSIM3sheetResistance > 0.0) && - (here->BSIM3sourceSquares > 0.0 ) && - (here->BSIM3sNodePrime == 0)) - { error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"source"); - if(error) return(error); - here->BSIM3sNodePrime = tmp->number; - } - else - { here->BSIM3sNodePrime = here->BSIM3sNode; - } - /* internal charge node */ - - if ((here->BSIM3nqsMod) && (here->BSIM3qNode == 0)) - { error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"charge"); - if(error) return(error); - here->BSIM3qNode = tmp->number; - } - else - { here->BSIM3qNode = 0; - } + /* perform the parameter defaulting */ + if (!here->BSIM3drainAreaGiven) + here->BSIM3drainArea = 0.0; + if (!here->BSIM3drainPerimeterGiven) + here->BSIM3drainPerimeter = 0.0; + if (!here->BSIM3drainSquaresGiven) + here->BSIM3drainSquares = 1.0; + if (!here->BSIM3icVBSGiven) + here->BSIM3icVBS = 0.0; + if (!here->BSIM3icVDSGiven) + here->BSIM3icVDS = 0.0; + if (!here->BSIM3icVGSGiven) + here->BSIM3icVGS = 0.0; + if (!here->BSIM3lGiven) + here->BSIM3l = 5.0e-6; + if (!here->BSIM3sourceAreaGiven) + here->BSIM3sourceArea = 0.0; + if (!here->BSIM3sourcePerimeterGiven) + here->BSIM3sourcePerimeter = 0.0; + if (!here->BSIM3sourceSquaresGiven) + here->BSIM3sourceSquares = 1.0; + if (!here->BSIM3wGiven) + here->BSIM3w = 5.0e-6; + if (!here->BSIM3nqsModGiven) + here->BSIM3nqsMod = 0; - /* set Sparse Matrix Pointers */ + if (!here->BSIM3mGiven) + here->BSIM3m = 1; + + /* process drain series resistance */ + if ((model->BSIM3sheetResistance > 0.0) && + (here->BSIM3drainSquares > 0.0) && (here->BSIM3dNodePrime == 0)) + { + error = CKTmkVolt (ckt, &tmp, here->BSIM3name, "drain"); + if (error) + return (error); + here->BSIM3dNodePrime = tmp->number; + if (ckt->CKTcopyNodesets) + { + CKTnode *tmpNode; + IFuid tmpName; + + if (CKTinst2Node (ckt, here, 1, &tmpNode, &tmpName) == OK) + { + if (tmpNode->nsGiven) + { + tmp->nodeset = tmpNode->nodeset; + tmp->nsGiven = tmpNode->nsGiven; + } + } + } + } + else + { + here->BSIM3dNodePrime = here->BSIM3dNode; + } + + /* process source series resistance */ + if ((model->BSIM3sheetResistance > 0.0) && + (here->BSIM3sourceSquares > 0.0) && + (here->BSIM3sNodePrime == 0)) + { + error = CKTmkVolt (ckt, &tmp, here->BSIM3name, "source"); + if (error) + return (error); + here->BSIM3sNodePrime = tmp->number; + if (ckt->CKTcopyNodesets) + { + CKTnode *tmpNode; + IFuid tmpName; + + if (CKTinst2Node (ckt, here, 3, &tmpNode, &tmpName) == OK) + { + if (tmpNode->nsGiven) + { + tmp->nodeset = tmpNode->nodeset; + tmp->nsGiven = tmpNode->nsGiven; + } + } + } + } + else + { + here->BSIM3sNodePrime = here->BSIM3sNode; + } + + /* internal charge node */ + + if ((here->BSIM3nqsMod) && (here->BSIM3qNode == 0)) + { + error = CKTmkVolt (ckt, &tmp, here->BSIM3name, "charge"); + if (error) + return (error); + here->BSIM3qNode = tmp->number; + } + else + { + here->BSIM3qNode = 0; + } + + /* set Sparse Matrix Pointers */ /* macro to make elements with built in test for out of memory */ #define TSTALLOC(ptr,first,second) \ @@ -947,77 +975,70 @@ if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ return(E_NOMEM);\ } - TSTALLOC(BSIM3DdPtr, BSIM3dNode, BSIM3dNode) - TSTALLOC(BSIM3GgPtr, BSIM3gNode, BSIM3gNode) - TSTALLOC(BSIM3SsPtr, BSIM3sNode, BSIM3sNode) - TSTALLOC(BSIM3BbPtr, BSIM3bNode, BSIM3bNode) - TSTALLOC(BSIM3DPdpPtr, BSIM3dNodePrime, BSIM3dNodePrime) - TSTALLOC(BSIM3SPspPtr, BSIM3sNodePrime, BSIM3sNodePrime) - TSTALLOC(BSIM3DdpPtr, BSIM3dNode, BSIM3dNodePrime) - TSTALLOC(BSIM3GbPtr, BSIM3gNode, BSIM3bNode) - TSTALLOC(BSIM3GdpPtr, BSIM3gNode, BSIM3dNodePrime) - TSTALLOC(BSIM3GspPtr, BSIM3gNode, BSIM3sNodePrime) - TSTALLOC(BSIM3SspPtr, BSIM3sNode, BSIM3sNodePrime) - TSTALLOC(BSIM3BdpPtr, BSIM3bNode, BSIM3dNodePrime) - TSTALLOC(BSIM3BspPtr, BSIM3bNode, BSIM3sNodePrime) - TSTALLOC(BSIM3DPspPtr, BSIM3dNodePrime, BSIM3sNodePrime) - TSTALLOC(BSIM3DPdPtr, BSIM3dNodePrime, BSIM3dNode) - TSTALLOC(BSIM3BgPtr, BSIM3bNode, BSIM3gNode) - TSTALLOC(BSIM3DPgPtr, BSIM3dNodePrime, BSIM3gNode) - TSTALLOC(BSIM3SPgPtr, BSIM3sNodePrime, BSIM3gNode) - TSTALLOC(BSIM3SPsPtr, BSIM3sNodePrime, BSIM3sNode) - TSTALLOC(BSIM3DPbPtr, BSIM3dNodePrime, BSIM3bNode) - TSTALLOC(BSIM3SPbPtr, BSIM3sNodePrime, BSIM3bNode) - TSTALLOC(BSIM3SPdpPtr, BSIM3sNodePrime, BSIM3dNodePrime) - - TSTALLOC(BSIM3QqPtr, BSIM3qNode, BSIM3qNode) - - TSTALLOC(BSIM3QdpPtr, BSIM3qNode, BSIM3dNodePrime) - TSTALLOC(BSIM3QspPtr, BSIM3qNode, BSIM3sNodePrime) - TSTALLOC(BSIM3QgPtr, BSIM3qNode, BSIM3gNode) - TSTALLOC(BSIM3QbPtr, BSIM3qNode, BSIM3bNode) - TSTALLOC(BSIM3DPqPtr, BSIM3dNodePrime, BSIM3qNode) - TSTALLOC(BSIM3SPqPtr, BSIM3sNodePrime, BSIM3qNode) - TSTALLOC(BSIM3GqPtr, BSIM3gNode, BSIM3qNode) - TSTALLOC(BSIM3BqPtr, BSIM3bNode, BSIM3qNode) - - } + TSTALLOC (BSIM3DdPtr, BSIM3dNode, BSIM3dNode) + TSTALLOC (BSIM3GgPtr, BSIM3gNode, BSIM3gNode) + TSTALLOC (BSIM3SsPtr, BSIM3sNode, BSIM3sNode) + TSTALLOC (BSIM3BbPtr, BSIM3bNode, BSIM3bNode) + TSTALLOC (BSIM3DPdpPtr, BSIM3dNodePrime, BSIM3dNodePrime) + TSTALLOC (BSIM3SPspPtr, BSIM3sNodePrime, BSIM3sNodePrime) + TSTALLOC (BSIM3DdpPtr, BSIM3dNode, BSIM3dNodePrime) + TSTALLOC (BSIM3GbPtr, BSIM3gNode, BSIM3bNode) + TSTALLOC (BSIM3GdpPtr, BSIM3gNode, BSIM3dNodePrime) + TSTALLOC (BSIM3GspPtr, BSIM3gNode, BSIM3sNodePrime) + TSTALLOC (BSIM3SspPtr, BSIM3sNode, BSIM3sNodePrime) + TSTALLOC (BSIM3BdpPtr, BSIM3bNode, BSIM3dNodePrime) + TSTALLOC (BSIM3BspPtr, BSIM3bNode, BSIM3sNodePrime) + TSTALLOC (BSIM3DPspPtr, BSIM3dNodePrime, BSIM3sNodePrime) + TSTALLOC (BSIM3DPdPtr, BSIM3dNodePrime, BSIM3dNode) + TSTALLOC (BSIM3BgPtr, BSIM3bNode, BSIM3gNode) + TSTALLOC (BSIM3DPgPtr, BSIM3dNodePrime, BSIM3gNode) + TSTALLOC (BSIM3SPgPtr, BSIM3sNodePrime, BSIM3gNode) + TSTALLOC (BSIM3SPsPtr, BSIM3sNodePrime, BSIM3sNode) + TSTALLOC (BSIM3DPbPtr, BSIM3dNodePrime, BSIM3bNode) + TSTALLOC (BSIM3SPbPtr, BSIM3sNodePrime, BSIM3bNode) + TSTALLOC (BSIM3SPdpPtr, BSIM3sNodePrime, BSIM3dNodePrime) + TSTALLOC (BSIM3QqPtr, BSIM3qNode, BSIM3qNode) + TSTALLOC (BSIM3QdpPtr, BSIM3qNode, BSIM3dNodePrime) + TSTALLOC (BSIM3QspPtr, BSIM3qNode, BSIM3sNodePrime) + TSTALLOC (BSIM3QgPtr, BSIM3qNode, BSIM3gNode) + TSTALLOC (BSIM3QbPtr, BSIM3qNode, BSIM3bNode) + TSTALLOC (BSIM3DPqPtr, BSIM3dNodePrime, BSIM3qNode) + TSTALLOC (BSIM3SPqPtr, BSIM3sNodePrime, BSIM3qNode) + TSTALLOC (BSIM3GqPtr, BSIM3gNode, BSIM3qNode) + TSTALLOC (BSIM3BqPtr, BSIM3bNode, BSIM3qNode)} } - return(OK); -} + return (OK); +} int -BSIM3unsetup(inModel,ckt) - GENmodel *inModel; - CKTcircuit *ckt; +BSIM3unsetup (inModel, ckt) + GENmodel *inModel; + CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM - BSIM3model *model; - BSIM3instance *here; + BSIM3model *model; + BSIM3instance *here; - for (model = (BSIM3model *)inModel; model != NULL; - model = model->BSIM3nextModel) + for (model = (BSIM3model *) inModel; model != NULL; + model = model->BSIM3nextModel) { - for (here = model->BSIM3instances; here != NULL; - here=here->BSIM3nextInstance) + for (here = model->BSIM3instances; here != NULL; + here = here->BSIM3nextInstance) { - if (here->BSIM3dNodePrime - && here->BSIM3dNodePrime != here->BSIM3dNode) + if (here->BSIM3dNodePrime + && here->BSIM3dNodePrime != here->BSIM3dNode) { - CKTdltNNum(ckt, here->BSIM3dNodePrime); - here->BSIM3dNodePrime = 0; + CKTdltNNum (ckt, here->BSIM3dNodePrime); + here->BSIM3dNodePrime = 0; } - if (here->BSIM3sNodePrime - && here->BSIM3sNodePrime != here->BSIM3sNode) + if (here->BSIM3sNodePrime + && here->BSIM3sNodePrime != here->BSIM3sNode) { - CKTdltNNum(ckt, here->BSIM3sNodePrime); - here->BSIM3sNodePrime = 0; + CKTdltNNum (ckt, here->BSIM3sNodePrime); + here->BSIM3sNodePrime = 0; } } } -#endif - return OK; + return OK; } - diff --git a/src/spicelib/devices/bsim3/b3temp.c b/src/spicelib/devices/bsim3/b3temp.c index 8f9b64908..2fe8580a1 100644 --- a/src/spicelib/devices/bsim3/b3temp.c +++ b/src/spicelib/devices/bsim3/b3temp.c @@ -1,29 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.3 1999/08/28 21:00:03 manu - Big commit - merged ngspice.h, misc.h and util.h - protoized fte - - Revision 1.2 1999/08/23 18:14:39 manu - Added cleanup patch by Arno Peters - also added 'make check' to configure - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /*********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -59,8 +33,8 @@ BSIM3temp(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -register BSIM3model *model = (BSIM3model*) inModel; -register BSIM3instance *here; +BSIM3model *model = (BSIM3model*) inModel; +BSIM3instance *here; struct bsim3SizeDependParam *pSizeDependParamKnot, *pLastKnot, *pParam; double tmp, tmp1, tmp2, tmp3, Eg, Eg0, ni, T0, T1, T2, T3, T4, T5, Ldrn, Wdrn; double delTemp, Temp, TRatio, Inv_L, Inv_W, Inv_LW, Vtm0, Tnom; @@ -186,7 +160,7 @@ int Size_Not_Found; } if (Size_Not_Found) - { pParam = (struct bsim3SizeDependParam *)malloc( + { pParam = (struct bsim3SizeDependParam *)tmalloc( sizeof(struct bsim3SizeDependParam)); if (pLastKnot == NULL) model->pSizeDependParamKnot = pParam; diff --git a/src/spicelib/devices/bsim3/b3trunc.c b/src/spicelib/devices/bsim3/b3trunc.c index b76d9c955..e856cdc84 100644 --- a/src/spicelib/devices/bsim3/b3trunc.c +++ b/src/spicelib/devices/bsim3/b3trunc.c @@ -1,23 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - Revision 1.1.1.1 1999/11/15 10:35:08 root - Rework imported sources - - Revision 1.1.1.1 1999/07/30 09:05:13 root - NG-Spice starting sources - - * Revision 3.2.2 1999/4/20 18:00:00 Weidong - * BSIM3v3.2.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -37,11 +17,11 @@ File: b3trunc.c int BSIM3trunc(inModel,ckt,timeStep) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; double *timeStep; { -register BSIM3model *model = (BSIM3model*)inModel; -register BSIM3instance *here; +BSIM3model *model = (BSIM3model*)inModel; +BSIM3instance *here; #ifdef STEPDEBUG double debugtemp; diff --git a/src/spicelib/devices/bsim3/bsim3def.h b/src/spicelib/devices/bsim3/bsim3def.h index 8270edb91..0ec5a05f4 100644 --- a/src/spicelib/devices/bsim3/bsim3def.h +++ b/src/spicelib/devices/bsim3/bsim3def.h @@ -2,6 +2,7 @@ Copyright 1999 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. Author: 1997-1999 Weidong Liu. +Modified: 2000 AlansFixes File: bsim3def.h **********/ @@ -20,7 +21,8 @@ typedef struct sBSIM3instance struct sBSIM3instance *BSIM3nextInstance; IFuid BSIM3name; int BSIM3owner; /* number of owner process */ - int BSIM3states; /* index into state table for this device */ + int BSIM3states; /* index into state table for this device */ + int BSIM3dNode; int BSIM3gNode; int BSIM3sNode; @@ -43,6 +45,7 @@ typedef struct sBSIM3instance double BSIM3l; double BSIM3w; + double BSIM3m; double BSIM3drainArea; double BSIM3sourceArea; double BSIM3drainSquares; @@ -106,6 +109,7 @@ typedef struct sBSIM3instance unsigned BSIM3lGiven :1; unsigned BSIM3wGiven :1; + unsigned BSIM3mGiven :1; unsigned BSIM3drainAreaGiven :1; unsigned BSIM3sourceAreaGiven :1; unsigned BSIM3drainSquaresGiven :1; @@ -152,7 +156,7 @@ typedef struct sBSIM3instance double *BSIM3SPqPtr; double *BSIM3BqPtr; - /* int BSIM3states; index into state table for this device */ + #define BSIM3vbd BSIM3states+ 0 #define BSIM3vbs BSIM3states+ 1 #define BSIM3vgs BSIM3states+ 2 @@ -1213,6 +1217,7 @@ typedef struct sBSIM3model /* device parameters */ #define BSIM3_W 1 #define BSIM3_L 2 +#define BSIM3_M 15 #define BSIM3_AS 3 #define BSIM3_AD 4 #define BSIM3_PS 5 diff --git a/src/spicelib/devices/bsim3/bsim3itf.h b/src/spicelib/devices/bsim3/bsim3itf.h index 518207ace..a9cac28c2 100644 --- a/src/spicelib/devices/bsim3/bsim3itf.h +++ b/src/spicelib/devices/bsim3/bsim3itf.h @@ -3,88 +3,9 @@ Copyright 1999 Regents of the University of California. All rights reserved. Author: 1991 JianHui Huang and Min-Chie Jeng. File: bsim3itf.h **********/ -#ifdef DEV_bsim3 - #ifndef DEV_BSIM3 #define DEV_BSIM3 -#include "bsim3ext.h" - -extern IFparm BSIM3pTable[ ]; -extern IFparm BSIM3mPTable[ ]; -extern char *BSIM3names[ ]; -extern int BSIM3pTSize; -extern int BSIM3mPTSize; -extern int BSIM3nSize; -extern int BSIM3iSize; -extern int BSIM3mSize; - -SPICEdev BSIM3info = { - { "BSIM3", - "Berkeley Short Channel IGFET Model Version-3", - - &BSIM3nSize, - &BSIM3nSize, - BSIM3names, - - &BSIM3pTSize, - BSIM3pTable, - - &BSIM3mPTSize, - BSIM3mPTable, - DEV_DEFAULT - }, - - BSIM3param, - BSIM3mParam, - BSIM3load, - BSIM3setup, - BSIM3unsetup, - BSIM3setup, - BSIM3temp, - BSIM3trunc, - NULL, - BSIM3acLoad, - NULL, - BSIM3destroy, -#ifdef DELETES - BSIM3mDelete, - BSIM3delete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - BSIM3getic, - BSIM3ask, - BSIM3mAsk, -#ifdef AN_pz - BSIM3pzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ -#ifdef NEWCONV - BSIM3convTest, -#else /* NEWCONV */ - NULL, -#endif /* NEWCONV */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - -#ifdef AN_noise - BSIM3noise, -#else /* AN_noise */ - NULL, -#endif /* AN_noise */ - - &BSIM3iSize, - &BSIM3mSize - -}; +SPICEdev *get_bsim3_info(void); #endif -#endif diff --git a/src/spicelib/devices/bsim3v1/Makefile.am b/src/spicelib/devices/bsim3v1/Makefile.am index b491d87ea..256fbd07b 100644 --- a/src/spicelib/devices/bsim3v1/Makefile.am +++ b/src/spicelib/devices/bsim3v1/Makefile.am @@ -3,27 +3,29 @@ pkglib_LTLIBRARIES = libbsim3v1.la libbsim3v1_la_SOURCES = \ - b3v1.c \ - b3v1acld.c \ - b3v1ask.c \ - b3v1check.c \ - b3v1cvtest.c \ - b3v1del.c \ - b3v1dest.c \ - b3v1getic.c \ - b3v1ld.c \ - b3v1mask.c \ - b3v1mdel.c \ - b3v1mpar.c \ - b3v1noi.c \ - b3v1par.c \ - b3v1pzld.c \ - b3v1set.c \ - b3v1temp.c \ - b3v1trunc.c \ - bsim3v1def.h \ - bsim3v1ext.h \ - bsim3v1itf.h + b3v1.c \ + b3v1acld.c \ + b3v1ask.c \ + b3v1check.c \ + b3v1cvtest.c \ + b3v1del.c \ + b3v1dest.c \ + b3v1getic.c \ + b3v1ld.c \ + b3v1mask.c \ + b3v1mdel.c \ + b3v1mpar.c \ + b3v1noi.c \ + b3v1par.c \ + b3v1pzld.c \ + b3v1set.c \ + b3v1temp.c \ + b3v1trunc.c \ + bsim3v1def.h \ + bsim3v1ext.h \ + bsim3v1init.c \ + bsim3v1init.h \ + bsim3v1itf.h diff --git a/src/spicelib/devices/bsim3v1/b3v1.c b/src/spicelib/devices/bsim3v1/b3v1.c index 011aff762..d97d6e1b4 100644 --- a/src/spicelib/devices/bsim3v1/b3v1.c +++ b/src/spicelib/devices/bsim3v1/b3v1.c @@ -1,16 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:48:03 yuhua - * BSIM3v3.1 release - * -*/ -static char rcsid[] = "$Id$"; - -/**********************************/ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v1/b3v1acld.c b/src/spicelib/devices/bsim3v1/b3v1acld.c index b64166e1a..cd3c67571 100644 --- a/src/spicelib/devices/bsim3v1/b3v1acld.c +++ b/src/spicelib/devices/bsim3v1/b3v1acld.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:51:00 yuhua - * BSIM3v3.1 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -29,10 +15,10 @@ File: b3v1acld.c int BSIM3V1acLoad(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { -register BSIM3V1model *model = (BSIM3V1model*)inModel; -register BSIM3V1instance *here; +BSIM3V1model *model = (BSIM3V1model*)inModel; +BSIM3V1instance *here; double xcggb, xcgdb, xcgsb, xcbgb, xcbdb, xcbsb, xcddb, xcssb, xcdgb; double gdpr, gspr, gds, gbd, gbs, capbd, capbs, xcsgb, xcdsb, xcsdb; double cggb, cgdb, cgsb, cbgb, cbdb, cbsb, cddb, cdgb, cdsb, omega; diff --git a/src/spicelib/devices/bsim3v1/b3v1ask.c b/src/spicelib/devices/bsim3v1/b3v1ask.c index a80c2273f..ef824972a 100644 --- a/src/spicelib/devices/bsim3v1/b3v1ask.c +++ b/src/spicelib/devices/bsim3v1/b3v1ask.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:51:33 yuhua - * BSIM3v3.1 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v1/b3v1check.c b/src/spicelib/devices/bsim3v1/b3v1check.c index ffde6e3d8..16d58dfce 100644 --- a/src/spicelib/devices/bsim3v1/b3v1check.c +++ b/src/spicelib/devices/bsim3v1/b3v1check.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:52:18 yuhua - * BSIM3v3.1 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: Min-Chie Jeng. @@ -31,8 +17,8 @@ File: b3v1check.c int BSIM3V1checkModel(model, here, ckt) -register BSIM3V1model *model; -register BSIM3V1instance *here; +BSIM3V1model *model; +BSIM3V1instance *here; CKTcircuit *ckt; { struct bsim3v1SizeDependParam *pParam; diff --git a/src/spicelib/devices/bsim3v1/b3v1cvtest.c b/src/spicelib/devices/bsim3v1/b3v1cvtest.c index f62ec2197..33e900bd9 100644 --- a/src/spicelib/devices/bsim3v1/b3v1cvtest.c +++ b/src/spicelib/devices/bsim3v1/b3v1cvtest.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:53:26 yuhua - * BSIM3v3.1 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -33,10 +19,10 @@ File: b3v1cvtest.c int BSIM3V1convTest(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { -register BSIM3V1model *model = (BSIM3V1model*)inModel; -register BSIM3V1instance *here; +BSIM3V1model *model = (BSIM3V1model*)inModel; +BSIM3V1instance *here; double delvbd, delvbs, delvds, delvgd, delvgs, vbd, vbs, vds; double cbd, cbhat, cbs, cd, cdhat, tol, vgd, vgdo, vgs; diff --git a/src/spicelib/devices/bsim3v1/b3v1del.c b/src/spicelib/devices/bsim3v1/b3v1del.c index ed6c40317..04e78c3de 100644 --- a/src/spicelib/devices/bsim3v1/b3v1del.c +++ b/src/spicelib/devices/bsim3v1/b3v1del.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:53:53 yuhua - * BSIM3v3.1 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v1/b3v1dest.c b/src/spicelib/devices/bsim3v1/b3v1dest.c index d9cc9cbda..38038920a 100644 --- a/src/spicelib/devices/bsim3v1/b3v1dest.c +++ b/src/spicelib/devices/bsim3v1/b3v1dest.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:54:27 yuhua - * BSIM3v3.1 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v1/b3v1getic.c b/src/spicelib/devices/bsim3v1/b3v1getic.c index 3114f3b02..5f22ec84a 100644 --- a/src/spicelib/devices/bsim3v1/b3v1getic.c +++ b/src/spicelib/devices/bsim3v1/b3v1getic.c @@ -1,18 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:54:55 yuhua - * BSIM3v3.1 - * release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v1/b3v1ld.c b/src/spicelib/devices/bsim3v1/b3v1ld.c index 445915653..bf98c291c 100644 --- a/src/spicelib/devices/bsim3v1/b3v1ld.c +++ b/src/spicelib/devices/bsim3v1/b3v1ld.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:55:29 yuhua - * BSIM3v3.1 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1991 JianHui Huang and Min-Chie Jeng. @@ -45,10 +31,10 @@ Modified by Mansun Chan (1995) int BSIM3V1load(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { -register BSIM3V1model *model = (BSIM3V1model*)inModel; -register BSIM3V1instance *here; +BSIM3V1model *model = (BSIM3V1model*)inModel; +BSIM3V1instance *here; double SourceSatCurrent, DrainSatCurrent; double ag0, qgd, qgs, qgb, von, cbhat, VgstNVt, ExpVgst; double cdrain, cdhat, cdreq, ceqbd, ceqbs, ceqqb, ceqqd, ceqqg, ceq, geq; @@ -56,54 +42,48 @@ double czbd, czbdsw, czbdswg, czbs, czbssw, czbsswg, evbd, evbs, arg, sarg; double delvbd, delvbs, delvds, delvgd, delvgs; double Vfbeff, dVfbeff_dVg, dVfbeff_dVd, dVfbeff_dVb, V3, V4; double gcbdb, gcbgb, gcbsb, gcddb, gcdgb, gcdsb, gcgdb, gcggb, gcgsb, gcsdb; -double gcsgb, gcssb, tol, PhiB, PhiBSW, MJ, MJSW, PhiBSWG, MJSWG; +double gcsgb, gcssb, PhiB, PhiBSW, MJ, MJSW, PhiBSWG, MJSWG; double vbd, vbs, vds, vgb, vgd, vgs, vgdo, xfact; double qgate=0.0, qbulk=0.0, qdrn=0.0, qsrc=0.0, cqgate=0.0, cqbulk=0.0, cqdrn=0.0; double Vds, Vgs, Vbs, Gmbs, FwdSum, RevSum; -double Vgs_eff, Vfb, dVfb_dVb, dVfb_dVd, dVbs_dVb; +double Vgs_eff, Vfb, dVfb_dVb, dVfb_dVd; double Phis, dPhis_dVb, sqrtPhis, dsqrtPhis_dVb, Vth, dVth_dVb, dVth_dVd; double Vgst, dVgst_dVg, dVgst_dVb, dVgs_eff_dVg, Nvtm; -double Vgdt, Vgsaddvth, Vgsaddvth2, Vgsaddvth1o3, n, dn_dVb, Vtm; -double ExpArg, ExpArg1, V0; +double n, dn_dVb, Vtm; +double ExpArg, V0; double Denomi, dDenomi_dVg, dDenomi_dVd, dDenomi_dVb; double ueff, dueff_dVg, dueff_dVd, dueff_dVb; -double Esat, dEsat_dVg, dEsat_dVd, dEsat_dVb, Vdsat, Vdsat0; +double Esat, Vdsat; double EsatL, dEsatL_dVg, dEsatL_dVd, dEsatL_dVb; -double Ilimit, Iexp, dIexp_dVg, dIexp_dVd, dIexp_dVb; double dVdsat_dVg, dVdsat_dVb, dVdsat_dVd, Vasat, dAlphaz_dVg, dAlphaz_dVb; -double dVasat_dVg, dVasat_dVb, dVasat_dVd, Va, Va2, dVa_dVd, dVa_dVg, dVa_dVb; +double dVasat_dVg, dVasat_dVb, dVasat_dVd, Va, dVa_dVd, dVa_dVg, dVa_dVb; double Vbseff, dVbseff_dVb, VbseffCV, dVbseffCV_dVb; -double Arg1, Arg2, One_Third_CoxWL, Two_Third_CoxWL, Alphaz, CoxWL; -double dqbulk_dVb, dVgdt_dVg, dVgdt_dVd, dVgdt_dVb; +double Arg1, One_Third_CoxWL, Two_Third_CoxWL, Alphaz, CoxWL; double T0, dT0_dVg, dT0_dVd, dT0_dVb; double T1, dT1_dVg, dT1_dVd, dT1_dVb; double T2, dT2_dVg, dT2_dVd, dT2_dVb; double T3, dT3_dVg, dT3_dVd, dT3_dVb; -double T4, dT4_dVg, dT4_dVd, dT4_dVb; -double T5, dT5_dVg, dT5_dVd, dT5_dVb; -double T6, dT6_dVg, dT6_dVd, dT6_dVb; +double T4; +double T5; +double T6; double T7, dT7_dVg, dT7_dVd, dT7_dVb; -double T8, dT8_dVg, dT8_dVd, dT8_dVb; -double T9, dT9_dVg, dT9_dVd, dT9_dVb; -double T10, dT10_dVg, dT10_dVb, dT10_dVd; +double T8; +double T9; +double T10; double T11, T12; double tmp, Abulk, dAbulk_dVb, Abulk0, dAbulk0_dVb; -double T100, T101; double VACLM, dVACLM_dVg, dVACLM_dVd, dVACLM_dVb; double VADIBL, dVADIBL_dVg, dVADIBL_dVd, dVADIBL_dVb; -double VAHCE, dVAHCE_dVg, dVAHCE_dVd, dVAHCE_dVb; double Xdep, dXdep_dVb, lt1, dlt1_dVb, ltw, dltw_dVb, Delt_vth, dDelt_vth_dVb; -double Theta0, dTheta0_dVb, Theta1, dTheta1_dVb; -double Thetarout, dThetarout_dVb, TempRatio, tmp1, tmp2, tmp3, tmp4; -double DIBL_Sft, dDIBL_Sft_dVd, DIBL_fact, Lambda, dLambda_dVg; -double Rout_Vgs_factor, dRout_Vgs_factor_dVg, dRout_Vgs_factor_dVb; -double dRout_Vgs_factor_dVd; +double Theta0, dTheta0_dVb; +double TempRatio, tmp1, tmp2, tmp3, tmp4; +double DIBL_Sft, dDIBL_Sft_dVd, Lambda, dLambda_dVg; double tempv, a1; double Vgsteff, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb; double Vdseff, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb; double VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb; -double diffVds, diffVdsCV; +double diffVds; double dAbulk_dVg, dn_dVd ; double beta, dbeta_dVg, dbeta_dVd, dbeta_dVb; double gche, dgche_dVg, dgche_dVd, dgche_dVb; @@ -112,29 +92,28 @@ double fgche2, dfgche2_dVg, dfgche2_dVd, dfgche2_dVb; double Idl, dIdl_dVg, dIdl_dVd, dIdl_dVb; double Idsa, dIdsa_dVg, dIdsa_dVd, dIdsa_dVb; double Ids, Gm, Gds, Gmb; -double Isub, Isubd, Isubs, Gbd, Gbg, Gbb; +double Isub, Gbd, Gbg, Gbb; double VASCBE, dVASCBE_dVg, dVASCBE_dVd, dVASCBE_dVb; double CoxWovL; double Rds, dRds_dVg, dRds_dVb, WVCox, WVCoxRds; -double Vgst2Vtm, VdsatCV, dVdsatCV_dVd, dVdsatCV_dVg, dVdsatCV_dVb; +double Vgst2Vtm, VdsatCV, dVdsatCV_dVg, dVdsatCV_dVb; double Leff, Weff, dWeff_dVg, dWeff_dVb; double AbulkCV, dAbulkCV_dVb; double qgdo, qgso, cgdo, cgso; -double qcheq, qdef, gqdef, cqdef, cqcheq, gtau_diff, gtau_drift, csreq; -double gcqdb,gcqsb,gcqgb,gcqbb,vss; +double qcheq, qdef, gqdef, cqdef, cqcheq, gtau_diff, gtau_drift; +double gcqdb,gcqsb,gcqgb,gcqbb; double dxpart, sxpart; double gbspsp, gbbdp, gbbsp, gbspg, gbspb, gbspdp; double gbdpdp, gbdpg, gbdpb, gbdpsp; -double Cgg, Cgd, Cgs, Cgb, Cdg, Cdd, Cds, Cdb, Qg, Qd; -double Csg, Csd, Css, Csb, Cbg, Cbd, Cbs, Cbb, Qs, Qb; -double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Csg1, Csd1, Csb1, Qac0, Qsub0; +double Cgg, Cgd, Cgb; +double Csg, Csd, Csb, Cbg, Cbd, Cbb; +double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Qac0, Qsub0; double dQac0_dVg, dQac0_dVd, dQac0_dVb, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb; struct bsim3v1SizeDependParam *pParam; -int ByPass, Check, ChargeComputationNeeded, J, error, I; -double junk[50]; +int ByPass, Check, ChargeComputationNeeded, error; for (; model != NULL; model = model->BSIM3V1nextModel) { for (here = model->BSIM3V1instances; here != NULL; @@ -246,7 +225,6 @@ for (; model != NULL; model = model->BSIM3V1nextModel) cbhat = here->BSIM3V1cbs + here->BSIM3V1cbd + here->BSIM3V1gbd * delvbd + here->BSIM3V1gbs * delvbs; -#ifndef NOBYPASS /* following should be one big if connected by && all over * the place, but some C compilers can't handle that, so * we split it up here to let them digest it in stages @@ -291,7 +269,6 @@ for (; model != NULL; model = model->BSIM3V1nextModel) } } -#endif /*NOBYPASS*/ von = here->BSIM3V1von; if (*(ckt->CKTstate0 + here->BSIM3V1vds) >= 0.0) { vgs = DEVfetlim(vgs, *(ckt->CKTstate0+here->BSIM3V1vgs), von); @@ -2049,24 +2026,6 @@ finished: /* returning Values to Calling Routine */ if ((here->BSIM3V1off == 0) || (!(ckt->CKTmode & MODEINITFIX))) { if (Check == 1) { ckt->CKTnoncon++; -#ifndef NEWCONV - } - else - { tol = ckt->CKTreltol * MAX(fabs(cdhat), fabs(here->BSIM3V1cd)) - + ckt->CKTabstol; - if (fabs(cdhat - here->BSIM3V1cd) >= tol) - { ckt->CKTnoncon++; - } - else - { tol = ckt->CKTreltol * MAX(fabs(cbhat), - fabs(here->BSIM3V1cbs + here->BSIM3V1cbd)) - + ckt->CKTabstol; - if (fabs(cbhat - (here->BSIM3V1cbs + here->BSIM3V1cbd)) - > tol) - { ckt->CKTnoncon++; - } - } -#endif /* NEWCONV */ } } *(ckt->CKTstate0 + here->BSIM3V1vbs) = vbs; diff --git a/src/spicelib/devices/bsim3v1/b3v1mask.c b/src/spicelib/devices/bsim3v1/b3v1mask.c index 06231ea4b..778dad8a4 100644 --- a/src/spicelib/devices/bsim3v1/b3v1mask.c +++ b/src/spicelib/devices/bsim3v1/b3v1mask.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:55:50 yuhua - * BSIM3v3.1 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v1/b3v1mdel.c b/src/spicelib/devices/bsim3v1/b3v1mdel.c index 12b74cfc4..d0262f8d3 100644 --- a/src/spicelib/devices/bsim3v1/b3v1mdel.c +++ b/src/spicelib/devices/bsim3v1/b3v1mdel.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:56:18 yuhua - * BSIM3v3.1 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v1/b3v1mpar.c b/src/spicelib/devices/bsim3v1/b3v1mpar.c index a16af0334..08581dbbe 100644 --- a/src/spicelib/devices/bsim3v1/b3v1mpar.c +++ b/src/spicelib/devices/bsim3v1/b3v1mpar.c @@ -1,18 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:56:49 yuhua - *  - * BSIM3v3.1 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v1/b3v1noi.c b/src/spicelib/devices/bsim3v1/b3v1noi.c index b61eb79de..a2a72b867 100644 --- a/src/spicelib/devices/bsim3v1/b3v1noi.c +++ b/src/spicelib/devices/bsim3v1/b3v1noi.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:57:51 yuhua - * BSIM3v3.1 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Gary W. Ng and Min-Chie Jeng. @@ -23,7 +9,6 @@ File: b3v1noi.c #include #include "bsim3v1def.h" #include "cktdefs.h" -#include "fteconst.h" #include "iferrmsg.h" #include "noisedef.h" #include "suffix.h" @@ -59,14 +44,15 @@ extern void NevalSrc(); extern double Nintegrate(); double -StrongInversionNoiseEval(vgs, vds, model, here, freq, temp) +StrongInversionNoiseEvalV1(vgs, vds, model, here, freq, temp) double vgs, vds, freq, temp; BSIM3V1model *model; BSIM3V1instance *here; { struct bsim3v1SizeDependParam *pParam; double cd, esat, DelClm, EffFreq, N0, Nl, Vgst; -double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, Ssi; +double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9; +double Ssi; pParam = here->pParam; cd = fabs(here->BSIM3V1cd); @@ -111,11 +97,11 @@ BSIM3V1noise (mode, operation, inModel, ckt, data, OnDens) int mode, operation; GENmodel *inModel; CKTcircuit *ckt; -register Ndata *data; +Ndata *data; double *OnDens; { -register BSIM3V1model *model = (BSIM3V1model *)inModel; -register BSIM3V1instance *here; +BSIM3V1model *model = (BSIM3V1model *)inModel; +BSIM3V1instance *here; struct bsim3v1SizeDependParam *pParam; char name[N_MXVLNTH]; double tempOnoise; @@ -124,11 +110,10 @@ double noizDens[BSIM3V1NSRCS]; double lnNdens[BSIM3V1NSRCS]; double vgs, vds, Slimit; -double N0, Nl; -double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13; -double n, ExpArg, Ssi, Swi; +double T1, T10, T11; +double Ssi, Swi; -int error, i; +int i; /* define the names of the noise sources */ static char *BSIM3V1nNames[BSIM3V1NSRCS] = @@ -268,7 +253,7 @@ int error, i; vgs = vgs + vds; } if (vgs >= here->BSIM3V1von + 0.1) - { Ssi = StrongInversionNoiseEval(vgs, + { Ssi = StrongInversionNoiseEvalV1(vgs, vds, model, here, data->freq, ckt->CKTtemp); noizDens[BSIM3V1FLNOIZ] *= Ssi; @@ -283,7 +268,7 @@ int error, i; * 4.0e36; Swi = T10 / T11 * here->BSIM3V1cd * here->BSIM3V1cd; - Slimit = StrongInversionNoiseEval( + Slimit = StrongInversionNoiseEvalV1( here->BSIM3V1von + 0.1, vds, model, here, data->freq, ckt->CKTtemp); T1 = Swi + Slimit; diff --git a/src/spicelib/devices/bsim3v1/b3v1par.c b/src/spicelib/devices/bsim3v1/b3v1par.c index f3becbdc1..87664b82c 100644 --- a/src/spicelib/devices/bsim3v1/b3v1par.c +++ b/src/spicelib/devices/bsim3v1/b3v1par.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:58:18 yuhua - * BSIM3v3.1 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v1/b3v1pzld.c b/src/spicelib/devices/bsim3v1/b3v1pzld.c index 7c99e3f91..fbf2fbf14 100644 --- a/src/spicelib/devices/bsim3v1/b3v1pzld.c +++ b/src/spicelib/devices/bsim3v1/b3v1pzld.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:58:46 yuhua - * BSIM3v3.1 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -29,11 +15,11 @@ File: b3v1pzld.c int BSIM3V1pzLoad(inModel,ckt,s) GENmodel *inModel; -register CKTcircuit *ckt; -register SPcomplex *s; +CKTcircuit *ckt; +SPcomplex *s; { -register BSIM3V1model *model = (BSIM3V1model*)inModel; -register BSIM3V1instance *here; +BSIM3V1model *model = (BSIM3V1model*)inModel; +BSIM3V1instance *here; double xcggb, xcgdb, xcgsb, xcbgb, xcbdb, xcbsb, xcddb, xcssb, xcdgb; double gdpr, gspr, gds, gbd, gbs, capbd, capbs, xcsgb, xcdsb, xcsdb; double cggb, cgdb, cgsb, cbgb, cbdb, cbsb, cddb, cdgb, cdsb; diff --git a/src/spicelib/devices/bsim3v1/b3v1set.c b/src/spicelib/devices/bsim3v1/b3v1set.c index d2608fa27..eb54c5c10 100644 --- a/src/spicelib/devices/bsim3v1/b3v1set.c +++ b/src/spicelib/devices/bsim3v1/b3v1set.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:59:17 yuhua - * BSIM3v3.1 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -40,17 +26,16 @@ File: b3v1set.c int BSIM3V1setup(matrix,inModel,ckt,states) -register SMPmatrix *matrix; -register GENmodel *inModel; -register CKTcircuit *ckt; +SMPmatrix *matrix; +GENmodel *inModel; +CKTcircuit *ckt; int *states; { -register BSIM3V1model *model = (BSIM3V1model*)inModel; -register BSIM3V1instance *here; +BSIM3V1model *model = (BSIM3V1model*)inModel; +BSIM3V1instance *here; int error; CKTnode *tmp; -double tmp1, tmp2; /* loop through all the BSIM3V1 device models */ for( ; model != NULL; model = model->BSIM3V1nextModel ) diff --git a/src/spicelib/devices/bsim3v1/b3v1temp.c b/src/spicelib/devices/bsim3v1/b3v1temp.c index d6ef90a83..cab2870c1 100644 --- a/src/spicelib/devices/bsim3v1/b3v1temp.c +++ b/src/spicelib/devices/bsim3v1/b3v1temp.c @@ -1,18 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 19:59:49 yuhua - * BSIM3v3.1 release - - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /*********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -47,11 +32,11 @@ BSIM3V1temp(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -register BSIM3V1model *model = (BSIM3V1model*) inModel; -register BSIM3V1instance *here; +BSIM3V1model *model = (BSIM3V1model*) inModel; +BSIM3V1instance *here; struct bsim3v1SizeDependParam *pSizeDependParamKnot, *pLastKnot, *pParam; -double tmp, tmp1, tmp2, Eg, Eg0, ni, T0, T1, T2, T3, T4, T5, Ldrn, Wdrn; -double Temp, TRatio, Inv_L, Inv_W, Inv_LW, Dw, Dl, Vtm0, Tnom; +double tmp1, tmp2, Eg, Eg0, ni, T0, T1, T2, T3, Ldrn, Wdrn; +double Temp, TRatio, Inv_L, Inv_W, Inv_LW, Vtm0, Tnom; int Size_Not_Found; /* loop through all the BSIM3V1 device models */ @@ -120,7 +105,7 @@ int Size_Not_Found; } if (Size_Not_Found) - { pParam = (struct bsim3v1SizeDependParam *)malloc( + { pParam = (struct bsim3v1SizeDependParam *)tmalloc( sizeof(struct bsim3v1SizeDependParam)); if (pLastKnot == NULL) model->pSizeDependParamKnot = pParam; diff --git a/src/spicelib/devices/bsim3v1/b3v1trunc.c b/src/spicelib/devices/bsim3v1/b3v1trunc.c index 1e6828450..fa3e351c4 100644 --- a/src/spicelib/devices/bsim3v1/b3v1trunc.c +++ b/src/spicelib/devices/bsim3v1/b3v1trunc.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* -$Log$ -Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi -Imported sources - - * Revision 3.1 96/12/08 20:00:16 yuhua - * BSIM3v3.1 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -30,11 +16,11 @@ File: b3v1trunc.c int BSIM3V1trunc(inModel,ckt,timeStep) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; double *timeStep; { -register BSIM3V1model *model = (BSIM3V1model*)inModel; -register BSIM3V1instance *here; +BSIM3V1model *model = (BSIM3V1model*)inModel; +BSIM3V1instance *here; #ifdef STEPDEBUG double debugtemp; diff --git a/src/spicelib/devices/bsim3v1/bsim3v1itf.h b/src/spicelib/devices/bsim3v1/bsim3v1itf.h index 2c1d50386..c0c84feb8 100644 --- a/src/spicelib/devices/bsim3v1/bsim3v1itf.h +++ b/src/spicelib/devices/bsim3v1/bsim3v1itf.h @@ -3,90 +3,9 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1991 JianHui Huang and Min-Chie Jeng. File: bsim3v1itf.h **********/ -#ifdef DEV_bsim3v1 - #ifndef DEV_BSIM3V1 #define DEV_BSIM3V1 -#include "bsim3v1ext.h" - -extern IFparm BSIM3V1pTable[ ]; -extern IFparm BSIM3V1mPTable[ ]; -extern char *BSIM3V1names[ ]; -extern int BSIM3V1pTSize; -extern int BSIM3V1mPTSize; -extern int BSIM3V1nSize; -extern int BSIM3V1iSize; -extern int BSIM3V1mSize; - -SPICEdev BSIM3V1info = { - { "BSIM3V1", - "Berkeley Short Channel IGFET Model Version-3 (3v3.1)", - - &BSIM3V1nSize, - &BSIM3V1nSize, - BSIM3V1names, - - &BSIM3V1pTSize, - BSIM3V1pTable, - - &BSIM3V1mPTSize, - BSIM3V1mPTable, - DEV_DEFAULT, - - }, - - BSIM3V1param, - BSIM3V1mParam, - BSIM3V1load, - BSIM3V1setup, - NULL, - BSIM3V1setup, - BSIM3V1temp, - BSIM3V1trunc, - NULL, - BSIM3V1acLoad, - NULL, - BSIM3V1destroy, -#ifdef DELETES - BSIM3V1mDelete, - BSIM3V1delete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - BSIM3V1getic, - BSIM3V1ask, - BSIM3V1mAsk, -#ifdef AN_pz - BSIM3V1pzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ -#ifdef NEWCONV - BSIM3V1convTest, -#else /* NEWCONV */ - NULL, -#endif /* NEWCONV */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - -#ifdef AN_noise - BSIM3V1noise, -#else /* AN_noise */ - NULL, -#endif /* AN_noise */ - - &BSIM3V1iSize, - &BSIM3V1mSize - -}; +SPICEdev *get_bsim3v1_info(void); #endif -#endif - diff --git a/src/spicelib/devices/bsim3v2/Makefile.am b/src/spicelib/devices/bsim3v2/Makefile.am index 539e76857..19ef09e8a 100644 --- a/src/spicelib/devices/bsim3v2/Makefile.am +++ b/src/spicelib/devices/bsim3v2/Makefile.am @@ -3,27 +3,29 @@ pkglib_LTLIBRARIES = libbsim3v2.la libbsim3v2_la_SOURCES = \ - b3v2.c \ - b3v2acld.c \ - b3v2ask.c \ - b3v2check.c \ - b3v2cvtest.c \ - b3v2del.c \ - b3v2dest.c \ - b3v2getic.c \ - b3v2ld.c \ - b3v2mask.c \ - b3v2mdel.c \ - b3v2mpar.c \ - b3v2noi.c \ - b3v2par.c \ - b3v2pzld.c \ - b3v2set.c \ - b3v2temp.c \ - b3v2trunc.c \ - bsim3v2def.h \ - bsim3v2ext.h \ - bsim3v2itf.h + b3v2.c \ + b3v2acld.c \ + b3v2ask.c \ + b3v2check.c \ + b3v2cvtest.c \ + b3v2del.c \ + b3v2dest.c \ + b3v2getic.c \ + b3v2ld.c \ + b3v2mask.c \ + b3v2mdel.c \ + b3v2mpar.c \ + b3v2noi.c \ + b3v2par.c \ + b3v2pzld.c \ + b3v2set.c \ + b3v2temp.c \ + b3v2trunc.c \ + bsim3v2def.h \ + bsim3v2ext.h \ + bsim3v2init.c \ + bsim3v2init.h \ + bsim3v2itf.h diff --git a/src/spicelib/devices/bsim3v2/b3v2.c b/src/spicelib/devices/bsim3v2/b3v2.c index 41747bf28..df0b58565 100644 --- a/src/spicelib/devices/bsim3v2/b3v2.c +++ b/src/spicelib/devices/bsim3v2/b3v2.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v2/b3v2acld.c b/src/spicelib/devices/bsim3v2/b3v2acld.c index 6d43dd8c4..160ef7b4a 100644 --- a/src/spicelib/devices/bsim3v2/b3v2acld.c +++ b/src/spicelib/devices/bsim3v2/b3v2acld.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -30,10 +16,10 @@ File: b3acld.c int BSIM3V2acLoad(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { -register BSIM3V2model *model = (BSIM3V2model*)inModel; -register BSIM3V2instance *here; +BSIM3V2model *model = (BSIM3V2model*)inModel; +BSIM3V2instance *here; double xcggb, xcgdb, xcgsb, xcbgb, xcbdb, xcbsb, xcddb, xcssb, xcdgb; double gdpr, gspr, gds, gbd, gbs, capbd, capbs, xcsgb, xcdsb, xcsdb; double cggb, cgdb, cgsb, cbgb, cbdb, cbsb, cddb, cdgb, cdsb, omega; @@ -43,7 +29,7 @@ double gbspsp, gbbdp, gbbsp, gbspg, gbspb; double gbspdp, gbdpdp, gbdpg, gbdpb, gbdpsp; double ddxpart_dVd, ddxpart_dVg, ddxpart_dVb, ddxpart_dVs; double dsxpart_dVd, dsxpart_dVg, dsxpart_dVb, dsxpart_dVs; -double T1, CoxWL, qcheq, Cdg, Cdd, Cds, Cdb, Csg, Csd, Css, Csb; +double T1, CoxWL, qcheq, Cdg, Cdd, Cds, Csg, Csd, Css; omega = ckt->CKTomega; for (; model != NULL; model = model->BSIM3V2nextModel) diff --git a/src/spicelib/devices/bsim3v2/b3v2ask.c b/src/spicelib/devices/bsim3v2/b3v2ask.c index fa8660009..5580399e6 100644 --- a/src/spicelib/devices/bsim3v2/b3v2ask.c +++ b/src/spicelib/devices/bsim3v2/b3v2ask.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v2/b3v2check.c b/src/spicelib/devices/bsim3v2/b3v2check.c index 175d4f01d..14056d79a 100644 --- a/src/spicelib/devices/bsim3v2/b3v2check.c +++ b/src/spicelib/devices/bsim3v2/b3v2check.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: Min-Chie Jeng. @@ -32,8 +18,8 @@ File: b3v2check.c int BSIM3V2checkModel(model, here, ckt) -register BSIM3V2model *model; -register BSIM3V2instance *here; +BSIM3V2model *model; +BSIM3V2instance *here; CKTcircuit *ckt; { struct BSIM3V2SizeDependParam *pParam; diff --git a/src/spicelib/devices/bsim3v2/b3v2cvtest.c b/src/spicelib/devices/bsim3v2/b3v2cvtest.c index c8cd7f883..b6e8e105b 100644 --- a/src/spicelib/devices/bsim3v2/b3v2cvtest.c +++ b/src/spicelib/devices/bsim3v2/b3v2cvtest.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -33,10 +19,10 @@ File: b3v2cvtest.c int BSIM3V2convTest(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { -register BSIM3V2model *model = (BSIM3V2model*)inModel; -register BSIM3V2instance *here; +BSIM3V2model *model = (BSIM3V2model*)inModel; +BSIM3V2instance *here; double delvbd, delvbs, delvds, delvgd, delvgs, vbd, vbs, vds; double cbd, cbhat, cbs, cd, cdhat, tol, vgd, vgdo, vgs; diff --git a/src/spicelib/devices/bsim3v2/b3v2del.c b/src/spicelib/devices/bsim3v2/b3v2del.c index 0bac0ef1b..948ddd19e 100644 --- a/src/spicelib/devices/bsim3v2/b3v2del.c +++ b/src/spicelib/devices/bsim3v2/b3v2del.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v2/b3v2dest.c b/src/spicelib/devices/bsim3v2/b3v2dest.c index 03c0737f4..024113c1b 100644 --- a/src/spicelib/devices/bsim3v2/b3v2dest.c +++ b/src/spicelib/devices/bsim3v2/b3v2dest.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v2/b3v2getic.c b/src/spicelib/devices/bsim3v2/b3v2getic.c index 7a385c5d2..1c7f64752 100644 --- a/src/spicelib/devices/bsim3v2/b3v2getic.c +++ b/src/spicelib/devices/bsim3v2/b3v2getic.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v2/b3v2ld.c b/src/spicelib/devices/bsim3v2/b3v2ld.c index 42e81a335..7d3e0f727 100644 --- a/src/spicelib/devices/bsim3v2/b3v2ld.c +++ b/src/spicelib/devices/bsim3v2/b3v2ld.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1991 JianHui Huang and Min-Chie Jeng. @@ -46,10 +32,10 @@ File: b3ld.c 1/3/92 int BSIM3V2load(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { -register BSIM3V2model *model = (BSIM3V2model*)inModel; -register BSIM3V2instance *here; +BSIM3V2model *model = (BSIM3V2model*)inModel; +BSIM3V2instance *here; double SourceSatCurrent, DrainSatCurrent; double ag0, qgd, qgs, qgb, von, cbhat, VgstNVt, ExpVgst; double cdrain, cdhat, cdreq, ceqbd, ceqbs, ceqqb, ceqqd, ceqqg, ceq, geq; @@ -139,8 +125,7 @@ double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Csg1, Csd1, Csb1, Qac0, Qsub0; double dQac0_dVg, dQac0_dVd, dQac0_dVb, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb; struct BSIM3V2SizeDependParam *pParam; -int ByPass, Check, ChargeComputationNeeded, J, error, I; -double junk[50]; +int ByPass, Check, ChargeComputationNeeded, error; ScalingFactor = 1.0e-9; ChargeComputationNeeded = @@ -262,7 +247,6 @@ for (; model != NULL; model = model->BSIM3V2nextModel) + here->BSIM3V2gbds * delvds; } -#ifndef NOBYPASS /* following should be one big if connected by && all over * the place, but some C compilers can't handle that, so * we split it up here to let them digest it in stages @@ -307,7 +291,6 @@ for (; model != NULL; model = model->BSIM3V2nextModel) } } -#endif /*NOBYPASS*/ von = here->BSIM3V2von; if (*(ckt->CKTstate0 + here->BSIM3V2vds) >= 0.0) { vgs = DEVfetlim(vgs, *(ckt->CKTstate0+here->BSIM3V2vgs), von); @@ -2306,32 +2289,9 @@ finished: /* * check convergence */ - if ((here->BSIM3V2off == 0) || (!(ckt->CKTmode & MODEINITFIX))) - { if (Check == 1) - { ckt->CKTnoncon++; -#ifndef NEWCONV - } - else - { if (here->BSIM3V2mode >= 0) - { Idtot = here->BSIM3V2cd + here->BSIM3V2csub - here->BSIM3V2cbd; - } - else - { Idtot = here->BSIM3V2cd - here->BSIM3V2cbd; - } - tol = ckt->CKTreltol * MAX(fabs(cdhat), fabs(Idtot)) - + ckt->CKTabstol; - if (fabs(cdhat - Idtot) >= tol) - { ckt->CKTnoncon++; - } - else - { Ibtot = here->BSIM3V2cbs + here->BSIM3V2cbd - here->BSIM3V2csub; - tol = ckt->CKTreltol * MAX(fabs(cbhat), fabs(Ibtot)) - + ckt->CKTabstol; - if (fabs(cbhat - Ibtot)) > tol) - { ckt->CKTnoncon++; - } - } -#endif /* NEWCONV */ + if ((here->BSIM3V2off == 0) || (!(ckt->CKTmode & MODEINITFIX))) { + if (Check == 1) { + ckt->CKTnoncon++; } } *(ckt->CKTstate0 + here->BSIM3V2vbs) = vbs; diff --git a/src/spicelib/devices/bsim3v2/b3v2mask.c b/src/spicelib/devices/bsim3v2/b3v2mask.c index 695d3a10e..73f7a3b8d 100644 --- a/src/spicelib/devices/bsim3v2/b3v2mask.c +++ b/src/spicelib/devices/bsim3v2/b3v2mask.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v2/b3v2mdel.c b/src/spicelib/devices/bsim3v2/b3v2mdel.c index 5a2628b51..e5109f277 100644 --- a/src/spicelib/devices/bsim3v2/b3v2mdel.c +++ b/src/spicelib/devices/bsim3v2/b3v2mdel.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v2/b3v2mpar.c b/src/spicelib/devices/bsim3v2/b3v2mpar.c index a8c8fdfcb..568bcae70 100644 --- a/src/spicelib/devices/bsim3v2/b3v2mpar.c +++ b/src/spicelib/devices/bsim3v2/b3v2mpar.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v2/b3v2noi.c b/src/spicelib/devices/bsim3v2/b3v2noi.c index 69b851ad0..0a8da1d4d 100644 --- a/src/spicelib/devices/bsim3v2/b3v2noi.c +++ b/src/spicelib/devices/bsim3v2/b3v2noi.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Gary W. Ng and Min-Chie Jeng. @@ -23,7 +9,6 @@ File: b3v2noi.c #include #include "bsim3v2def.h" #include "cktdefs.h" -#include "fteconst.h" #include "iferrmsg.h" #include "noisedef.h" #include "suffix.h" @@ -59,7 +44,7 @@ extern void NevalSrc(); extern double Nintegrate(); double -StrongInversionNoiseEval(vgs, vds, model, here, freq, temp) +StrongInversionNoiseEvalV2(vgs, vds, model, here, freq, temp) double vgs, vds, freq, temp; BSIM3V2model *model; BSIM3V2instance *here; @@ -111,11 +96,11 @@ BSIM3V2noise (mode, operation, inModel, ckt, data, OnDens) int mode, operation; GENmodel *inModel; CKTcircuit *ckt; -register Ndata *data; +Ndata *data; double *OnDens; { -register BSIM3V2model *model = (BSIM3V2model *)inModel; -register BSIM3V2instance *here; +BSIM3V2model *model = (BSIM3V2model *)inModel; +BSIM3V2instance *here; struct BSIM3V2SizeDependParam *pParam; char name[N_MXVLNTH]; double tempOnoise; @@ -268,7 +253,7 @@ int error, i; vgs = vgs + vds; } if (vgs >= here->BSIM3V2von + 0.1) - { Ssi = StrongInversionNoiseEval(vgs, + { Ssi = StrongInversionNoiseEvalV2(vgs, vds, model, here, data->freq, ckt->CKTtemp); noizDens[BSIM3V2FLNOIZ] *= Ssi; @@ -283,7 +268,7 @@ int error, i; * 4.0e36; Swi = T10 / T11 * here->BSIM3V2cd * here->BSIM3V2cd; - Slimit = StrongInversionNoiseEval( + Slimit = StrongInversionNoiseEvalV2( here->BSIM3V2von + 0.1, vds, model, here, data->freq, ckt->CKTtemp); T1 = Swi + Slimit; diff --git a/src/spicelib/devices/bsim3v2/b3v2par.c b/src/spicelib/devices/bsim3v2/b3v2par.c index 6f96a9271..2cc48b1b2 100644 --- a/src/spicelib/devices/bsim3v2/b3v2par.c +++ b/src/spicelib/devices/bsim3v2/b3v2par.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. diff --git a/src/spicelib/devices/bsim3v2/b3v2pzld.c b/src/spicelib/devices/bsim3v2/b3v2pzld.c index 13a47eece..fd4cc04c7 100644 --- a/src/spicelib/devices/bsim3v2/b3v2pzld.c +++ b/src/spicelib/devices/bsim3v2/b3v2pzld.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -30,11 +16,11 @@ File: b3v2pzld.c int BSIM3V2pzLoad(inModel,ckt,s) GENmodel *inModel; -register CKTcircuit *ckt; -register SPcomplex *s; +CKTcircuit *ckt; +SPcomplex *s; { -register BSIM3V2model *model = (BSIM3V2model*)inModel; -register BSIM3V2instance *here; +BSIM3V2model *model = (BSIM3V2model*)inModel; +BSIM3V2instance *here; double xcggb, xcgdb, xcgsb, xcgbb, xcbgb, xcbdb, xcbsb, xcbbb; double xcdgb, xcddb, xcdsb, xcdbb, xcsgb, xcsdb, xcssb, xcsbb; double gdpr, gspr, gds, gbd, gbs, capbd, capbs, FwdSum, RevSum, Gm, Gmbs; diff --git a/src/spicelib/devices/bsim3v2/b3v2set.c b/src/spicelib/devices/bsim3v2/b3v2set.c index 7c9aa2b70..d40616c9d 100644 --- a/src/spicelib/devices/bsim3v2/b3v2set.c +++ b/src/spicelib/devices/bsim3v2/b3v2set.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -41,13 +27,13 @@ File: b3v2set.c int BSIM3V2setup(matrix,inModel,ckt,states) -register SMPmatrix *matrix; -register GENmodel *inModel; -register CKTcircuit *ckt; +SMPmatrix *matrix; +GENmodel *inModel; +CKTcircuit *ckt; int *states; { -register BSIM3V2model *model = (BSIM3V2model*)inModel; -register BSIM3V2instance *here; +BSIM3V2model *model = (BSIM3V2model*)inModel; +BSIM3V2instance *here; int error; CKTnode *tmp; @@ -982,7 +968,6 @@ BSIM3V2unsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM BSIM3V2model *model; BSIM3V2instance *here; @@ -1006,6 +991,5 @@ BSIM3V2unsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/bsim3v2/b3v2temp.c b/src/spicelib/devices/bsim3v2/b3v2temp.c index fe79bf4aa..ea14780a3 100644 --- a/src/spicelib/devices/bsim3v2/b3v2temp.c +++ b/src/spicelib/devices/bsim3v2/b3v2temp.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /*********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -47,8 +33,8 @@ BSIM3V2temp(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -register BSIM3V2model *model = (BSIM3V2model*) inModel; -register BSIM3V2instance *here; +BSIM3V2model *model = (BSIM3V2model*) inModel; +BSIM3V2instance *here; struct BSIM3V2SizeDependParam *pSizeDependParamKnot, *pLastKnot, *pParam; double tmp, tmp1, tmp2, tmp3, Eg, Eg0, ni, T0, T1, T2, T3, T4, T5, Ldrn, Wdrn; double delTemp, Temp, TRatio, Inv_L, Inv_W, Inv_LW, Dw, Dl, Vtm0, Tnom; @@ -174,7 +160,7 @@ int Size_Not_Found; } if (Size_Not_Found) - { pParam = (struct BSIM3V2SizeDependParam *)malloc( + { pParam = (struct BSIM3V2SizeDependParam *)tmalloc( sizeof(struct BSIM3V2SizeDependParam)); if (pLastKnot == NULL) model->pSizeDependParamKnot = pParam; diff --git a/src/spicelib/devices/bsim3v2/b3v2trunc.c b/src/spicelib/devices/bsim3v2/b3v2trunc.c index 41dbfd83e..23b9546ec 100644 --- a/src/spicelib/devices/bsim3v2/b3v2trunc.c +++ b/src/spicelib/devices/bsim3v2/b3v2trunc.c @@ -1,17 +1,3 @@ -/* $Id$ */ -/* - $Log$ - Revision 1.1.1.1 2000-04-27 20:03:59 pnenzi - Imported sources - - * Revision 3.2 1998/6/16 18:00:00 Weidong - * BSIM3v3.2 release - * -*/ -static char rcsid[] = "$Id$"; - -/*************************************/ - /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1995 Min-Chie Jeng and Mansun Chan. @@ -30,11 +16,11 @@ File: b3v2trunc.c int BSIM3V2trunc(inModel,ckt,timeStep) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; double *timeStep; { -register BSIM3V2model *model = (BSIM3V2model*)inModel; -register BSIM3V2instance *here; +BSIM3V2model *model = (BSIM3V2model*)inModel; +BSIM3V2instance *here; #ifdef STEPDEBUG double debugtemp; diff --git a/src/spicelib/devices/bsim3v2/bsim3v2itf.h b/src/spicelib/devices/bsim3v2/bsim3v2itf.h index df8fcbd47..666329678 100644 --- a/src/spicelib/devices/bsim3v2/bsim3v2itf.h +++ b/src/spicelib/devices/bsim3v2/bsim3v2itf.h @@ -3,89 +3,9 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1991 JianHui Huang and Min-Chie Jeng. File: bsim3v2itf.h **********/ -#ifdef DEV_bsim3v2 - #ifndef DEV_BSIM3V2 #define DEV_BSIM3V2 -#include "bsim3v2ext.h" - -extern IFparm BSIM3V2pTable[ ]; -extern IFparm BSIM3V2mPTable[ ]; -extern char *BSIM3V2names[ ]; -extern int BSIM3V2pTSize; -extern int BSIM3V2mPTSize; -extern int BSIM3V2nSize; -extern int BSIM3V2iSize; -extern int BSIM3V2mSize; - -SPICEdev BSIM3V2info = { - { "BSIM3V2", - "Berkeley Short Channel IGFET Model Version-3 (3v3.2)", - - &BSIM3V2nSize, - &BSIM3V2nSize, - BSIM3V2names, - - &BSIM3V2pTSize, - BSIM3V2pTable, - - &BSIM3V2mPTSize, - BSIM3V2mPTable, - DEV_DEFAULT - }, - - BSIM3V2param, - BSIM3V2mParam, - BSIM3V2load, - BSIM3V2setup, - BSIM3V2unsetup, - BSIM3V2setup, - BSIM3V2temp, - BSIM3V2trunc, - NULL, - BSIM3V2acLoad, - NULL, - BSIM3V2destroy, -#ifdef DELETES - BSIM3V2mDelete, - BSIM3V2delete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - BSIM3V2getic, - BSIM3V2ask, - BSIM3V2mAsk, -#ifdef AN_pz - BSIM3V2pzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ -#ifdef NEWCONV - BSIM3V2convTest, -#else /* NEWCONV */ - NULL, -#endif /* NEWCONV */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - -#ifdef AN_noise - BSIM3V2noise, -#else /* AN_noise */ - NULL, -#endif /* AN_noise */ - - &BSIM3V2iSize, - &BSIM3V2mSize - -}; +SPICEdev *get_bsim3v2_info(void); #endif -#endif - diff --git a/src/spicelib/devices/bsim4/ChangeLog b/src/spicelib/devices/bsim4/ChangeLog index 1a877696d..5f1ef1717 100644 --- a/src/spicelib/devices/bsim4/ChangeLog +++ b/src/spicelib/devices/bsim4/ChangeLog @@ -1,3 +1,12 @@ +2001-11-26 Paolo Nenzi + + * *.c *.h: Code cleanups and made Manu import conformant to ngspice + interface. Readded code for multiprocessors. + +2001-11-25 Emmanuel Rouat + + * *.c *.h: Updated to version BSIM4.2.1 + 2000-04-04 Paolo Nenzi * *.c, *.h: Initial bsim4 support. Modified all files to conform diff --git a/src/spicelib/devices/bsim4/Makefile.am b/src/spicelib/devices/bsim4/Makefile.am index dc5028300..f5e3b51ee 100644 --- a/src/spicelib/devices/bsim4/Makefile.am +++ b/src/spicelib/devices/bsim4/Makefile.am @@ -2,29 +2,31 @@ pkglib_LTLIBRARIES = libbsim4.la -libbsim4_la_SOURCES = \ - b4.c \ - b4acld.c \ - b4ask.c \ - b4check.c \ - b4cvtest.c \ - b4del.c \ - b4dest.c \ - b4geo.c \ - b4getic.c \ - b4ld.c \ - b4mask.c \ - b4mdel.c \ - b4mpar.c \ - b4noi.c \ - b4par.c \ - b4pzld.c \ - b4set.c \ - b4temp.c \ - b4trunc.c \ - bsim4def.h \ - bsim4ext.h \ - bsim4itf.h +libbsim4_la_SOURCES = \ + b4.c \ + b4acld.c \ + b4ask.c \ + b4check.c \ + b4cvtest.c \ + b4del.c \ + b4dest.c \ + b4geo.c \ + b4getic.c \ + b4ld.c \ + b4mask.c \ + b4mdel.c \ + b4mpar.c \ + b4noi.c \ + b4par.c \ + b4pzld.c \ + b4set.c \ + b4temp.c \ + b4trunc.c \ + bsim4def.h \ + bsim4ext.h \ + bsim4init.c \ + bsim4init.h \ + bsim4itf.h diff --git a/src/spicelib/devices/bsim4/b4.c b/src/spicelib/devices/bsim4/b4.c index b210f5425..c07fd939a 100644 --- a/src/spicelib/devices/bsim4/b4.c +++ b/src/spicelib/devices/bsim4/b4.c @@ -1,16 +1,20 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4.c of BSIM4.0.0. - * Authors: Weidong Liu, Kanyu M. Cao, Xiaodong Jin, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. + * + * Modified by Xuemei Xi, 10/05/2001. **********/ #include "ngspice.h" #include #include "devdefs.h" #include "bsim4def.h" +#include "suffix.h" IFparm BSIM4pTable[] = { /* parameters */ IOP( "l", BSIM4_L, IF_REAL , "Length"), @@ -43,9 +47,42 @@ OP( "gds", BSIM4_GDS, IF_REAL, "Gds"), OP( "vdsat", BSIM4_VDSAT, IF_REAL, "Vdsat"), OP( "vth", BSIM4_VON, IF_REAL, "Vth"), OP( "id", BSIM4_CD, IF_REAL, "Ids"), +OP( "ibd", BSIM4_CBD, IF_REAL, "Ibd"), +OP( "ibs", BSIM4_CBS, IF_REAL, "Ibs"), +OP( "isub", BSIM4_CSUB, IF_REAL, "Isub"), +OP( "igidl", BSIM4_IGIDL, IF_REAL, "Igidl"), +OP( "igisl", BSIM4_IGISL, IF_REAL, "Igisl"), +OP( "igs", BSIM4_IGS, IF_REAL, "Igs"), +OP( "igd", BSIM4_IGD, IF_REAL, "Igd"), +OP( "igb", BSIM4_IGB, IF_REAL, "Igb"), +OP( "igcs", BSIM4_IGCS, IF_REAL, "Igcs"), +OP( "igcd", BSIM4_IGCD, IF_REAL, "Igcd"), OP( "vbs", BSIM4_VBS, IF_REAL, "Vbs"), OP( "vgs", BSIM4_VGS, IF_REAL, "Vgs"), OP( "vds", BSIM4_VDS, IF_REAL, "Vds"), +OP( "cgg", BSIM4_CGGB, IF_REAL, "Cggb"), +OP( "cgs", BSIM4_CGSB, IF_REAL, "Cgsb"), +OP( "cgd", BSIM4_CGDB, IF_REAL, "Cgdb"), +OP( "cbg", BSIM4_CBGB, IF_REAL, "Cbgb"), +OP( "cbd", BSIM4_CBDB, IF_REAL, "Cbdb"), +OP( "cbs", BSIM4_CBSB, IF_REAL, "Cbsb"), +OP( "cdg", BSIM4_CDGB, IF_REAL, "Cdgb"), +OP( "cdd", BSIM4_CDDB, IF_REAL, "Cddb"), +OP( "cds", BSIM4_CDSB, IF_REAL, "Cdsb"), +OP( "csg", BSIM4_CSGB, IF_REAL, "Csgb"), +OP( "csd", BSIM4_CSDB, IF_REAL, "Csdb"), +OP( "css", BSIM4_CSSB, IF_REAL, "Cssb"), +OP( "cgb", BSIM4_CGBB, IF_REAL, "Cgbb"), +OP( "cdb", BSIM4_CDBB, IF_REAL, "Cdbb"), +OP( "csb", BSIM4_CSBB, IF_REAL, "Csbb"), +OP( "cbb", BSIM4_CBBB, IF_REAL, "Cbbb"), +OP( "capbd", BSIM4_CAPBD, IF_REAL, "Capbd"), +OP( "capbs", BSIM4_CAPBS, IF_REAL, "Capbs"), +OP( "qg", BSIM4_QG, IF_REAL, "Qgate"), +OP( "qb", BSIM4_QB, IF_REAL, "Qbulk"), +OP( "qd", BSIM4_QD, IF_REAL, "Qdrain"), +OP( "qs", BSIM4_QS, IF_REAL, "Qsource"), +OP( "qinv", BSIM4_QINV, IF_REAL, "Qinversion"), }; IFparm BSIM4mPTable[] = { /* model parameters */ @@ -254,6 +291,8 @@ IOP( "clc", BSIM4_MOD_CLC, IF_REAL, "Vdsat parameter for C-V model"), IOP( "cle", BSIM4_MOD_CLE, IF_REAL, "Vdsat parameter for C-V model"), IOP( "dwc", BSIM4_MOD_DWC, IF_REAL, "Delta W for C-V model"), IOP( "dlc", BSIM4_MOD_DLC, IF_REAL, "Delta L for C-V model"), +IOP( "xw", BSIM4_MOD_XW, IF_REAL, "W offset for channel width due to mask/etch effect"), +IOP( "xl", BSIM4_MOD_XL, IF_REAL, "L offset for channel length due to mask/etch effect"), IOP( "dlcig", BSIM4_MOD_DLCIG, IF_REAL, "Delta L for Ig model"), IOP( "dwj", BSIM4_MOD_DWJ, IF_REAL, "Delta W for S/D junctions"), diff --git a/src/spicelib/devices/bsim4/b4acld.c b/src/spicelib/devices/bsim4/b4acld.c index b722958f7..28dc21b8a 100644 --- a/src/spicelib/devices/bsim4/b4acld.c +++ b/src/spicelib/devices/bsim4/b4acld.c @@ -1,10 +1,13 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4acld.c of BSIM4.0.0. - * Authors: Weidong Liu, Xiaodong Jin, Kanyu M. Cao, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4acld.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. + * + * Modified by Xuemei Xi 10/05/2001 **********/ #include "ngspice.h" @@ -14,13 +17,14 @@ #include "sperror.h" + int BSIM4acLoad(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { -register BSIM4model *model = (BSIM4model*)inModel; -register BSIM4instance *here; +BSIM4model *model = (BSIM4model*)inModel; +BSIM4instance *here; double gjbd, gjbs, geltd, gcrg, gcrgg, gcrgd, gcrgs, gcrgb; double xcbgb, xcbdb, xcbsb, xcbbb; @@ -48,13 +52,14 @@ double gmr, gmi, gmbsr, gmbsi, gdsr, gdsi; double FwdSumr, RevSumr, Gmr, Gmbsr, Gdsr; double FwdSumi, RevSumi, Gmi, Gmbsi, Gdsi; struct bsim4SizeDependParam *pParam; +double ggidld, ggidlg, ggidlb,ggisld, ggislg, ggislb, ggisls; omega = ckt->CKTomega; for (; model != NULL; model = model->BSIM4nextModel) { for (here = model->BSIM4instances; here!= NULL; here = here->BSIM4nextInstance) - { if (here->BSIM4owner != ARCHme) continue; - pParam = here->pParam; + { if (here->BSIM4owner != ARCHme) continue; + pParam = here->pParam; capbd = here->BSIM4capbd; capbs = here->BSIM4capbs; cgso = here->BSIM4cgso; @@ -146,13 +151,12 @@ struct bsim4SizeDependParam *pParam; FwdSumi = Gmi + Gmbsi; RevSumi = 0.0; - gbbdp = -(here->BSIM4gbds + here->BSIM4ggidld); - gbbsp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs - - here->BSIM4ggidls; - gbdpg = here->BSIM4gbgs + here->BSIM4ggidlg; - gbdpdp = here->BSIM4gbds + here->BSIM4ggidld; - gbdpb = here->BSIM4gbbs + here->BSIM4ggidlb; - gbdpsp = -(gbdpg + gbdpdp + gbdpb) + here->BSIM4ggidls; + gbbdp = -(here->BSIM4gbds); + gbbsp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs; + gbdpg = here->BSIM4gbgs; + gbdpdp = here->BSIM4gbds; + gbdpb = here->BSIM4gbbs; + gbdpsp = -(gbdpg + gbdpdp + gbdpb); gbspdp = 0.0; gbspg = 0.0; @@ -290,19 +294,18 @@ struct bsim4SizeDependParam *pParam; FwdSumi = 0.0; RevSumi = -(Gmi + Gmbsi); - gbbsp = -(here->BSIM4gbds + here->BSIM4ggidld); - gbbdp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs - - here->BSIM4ggidls; + gbbsp = -(here->BSIM4gbds); + gbbdp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs; gbdpg = 0.0; gbdpsp = 0.0; gbdpb = 0.0; gbdpdp = 0.0; - gbspg = here->BSIM4gbgs + here->BSIM4ggidlg; - gbspsp = here->BSIM4gbds + here->BSIM4ggidld; - gbspb = here->BSIM4gbbs + here->BSIM4ggidlb; - gbspdp = -(gbspg + gbspsp + gbspb) + here->BSIM4ggidls; + gbspg = here->BSIM4gbgs; + gbspsp = here->BSIM4gbds; + gbspb = here->BSIM4gbbs; + gbspdp = -(gbspg + gbspsp + gbspb); if (model->BSIM4igcMod) { gIstotg = here->BSIM4gIgsg + here->BSIM4gIgcdg; @@ -575,12 +578,37 @@ struct bsim4SizeDependParam *pParam; *(here->BSIM4BPdpPtr +1) += xcbdb; *(here->BSIM4BPdpPtr) -= gjbd - gbbdp + gIbtotd; *(here->BSIM4BPgpPtr +1) += xcbgb; - *(here->BSIM4BPgpPtr) -= here->BSIM4gbgs + here->BSIM4ggidlg + gIbtotg; + *(here->BSIM4BPgpPtr) -= here->BSIM4gbgs + gIbtotg; *(here->BSIM4BPspPtr +1) += xcbsb; *(here->BSIM4BPspPtr) -= gjbs - gbbsp + gIbtots; *(here->BSIM4BPbpPtr +1) += xcbbb; *(here->BSIM4BPbpPtr) += gjbd + gjbs - here->BSIM4gbbs - - here->BSIM4ggidlb - gIbtotb; + - gIbtotb; + ggidld = here->BSIM4ggidld; + ggidlg = here->BSIM4ggidlg; + ggidlb = here->BSIM4ggidlb; + ggislg = here->BSIM4ggislg; + ggisls = here->BSIM4ggisls; + ggislb = here->BSIM4ggislb; + + /* stamp gidl */ + (*(here->BSIM4DPdpPtr) += ggidld); + (*(here->BSIM4DPgpPtr) += ggidlg); + (*(here->BSIM4DPspPtr) -= (ggidlg + ggidld) + ggidlb); + (*(here->BSIM4DPbpPtr) += ggidlb); + (*(here->BSIM4BPdpPtr) -= ggidld); + (*(here->BSIM4BPgpPtr) -= ggidlg); + (*(here->BSIM4BPspPtr) += (ggidlg + ggidld) + ggidlb); + (*(here->BSIM4BPbpPtr) -= ggidlb); + /* stamp gisl */ + (*(here->BSIM4SPdpPtr) -= (ggisls + ggislg) + ggislb); + (*(here->BSIM4SPgpPtr) += ggislg); + (*(here->BSIM4SPspPtr) += ggisls); + (*(here->BSIM4SPbpPtr) += ggislb); + (*(here->BSIM4BPdpPtr) += (ggislg + ggisls) + ggislb); + (*(here->BSIM4BPgpPtr) -= ggislg); + (*(here->BSIM4BPspPtr) -= ggisls); + (*(here->BSIM4BPbpPtr) -= ggislb); if (here->BSIM4rbodyMod) { (*(here->BSIM4DPdbPtr +1) += xcdbdb); diff --git a/src/spicelib/devices/bsim4/b4ask.c b/src/spicelib/devices/bsim4/b4ask.c index 9449eff48..e3353cb57 100644 --- a/src/spicelib/devices/bsim4/b4ask.c +++ b/src/spicelib/devices/bsim4/b4ask.c @@ -1,10 +1,13 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4ask.c of BSIM4.0.0. - * Authors: Weidong Liu, Kanyu M. Cao, Xiaodong Jin, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4ask.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. + * + * Modified by Xuemei Xi, 10/05/2001. **********/ #include "ngspice.h" @@ -16,6 +19,7 @@ #include "bsim4def.h" #include "sperror.h" + int BSIM4ask(ckt,inst,which,value,select) CKTcircuit *ckt; @@ -162,6 +166,30 @@ BSIM4instance *here = (BSIM4instance*)inst; case BSIM4_CBD: value->rValue = here->BSIM4cbd; return(OK); + case BSIM4_CSUB: + value->rValue = here->BSIM4csub; + return(OK); + case BSIM4_IGIDL: + value->rValue = here->BSIM4Igidl; + return(OK); + case BSIM4_IGISL: + value->rValue = here->BSIM4Igisl; + return(OK); + case BSIM4_IGS: + value->rValue = here->BSIM4Igs; + return(OK); + case BSIM4_IGD: + value->rValue = here->BSIM4Igd; + return(OK); + case BSIM4_IGB: + value->rValue = here->BSIM4Igb; + return(OK); + case BSIM4_IGCS: + value->rValue = here->BSIM4Igcs; + return(OK); + case BSIM4_IGCD: + value->rValue = here->BSIM4Igcd; + return(OK); case BSIM4_GM: value->rValue = here->BSIM4gm; return(OK); @@ -179,7 +207,7 @@ BSIM4instance *here = (BSIM4instance*)inst; return(OK); case BSIM4_QB: value->rValue = *(ckt->CKTstate0 + here->BSIM4qb); - return(OK); + return(OK); case BSIM4_CQB: value->rValue = *(ckt->CKTstate0 + here->BSIM4cqb); return(OK); @@ -191,29 +219,32 @@ BSIM4instance *here = (BSIM4instance*)inst; return(OK); case BSIM4_QD: value->rValue = *(ckt->CKTstate0 + here->BSIM4qd); - return(OK); + return(OK); case BSIM4_CQD: value->rValue = *(ckt->CKTstate0 + here->BSIM4cqd); return(OK); - case BSIM4_CGG: + case BSIM4_QS: + value->rValue = *(ckt->CKTstate0 + here->BSIM4qs); + return(OK); + case BSIM4_CGGB: value->rValue = here->BSIM4cggb; return(OK); - case BSIM4_CGD: + case BSIM4_CGDB: value->rValue = here->BSIM4cgdb; return(OK); - case BSIM4_CGS: + case BSIM4_CGSB: value->rValue = here->BSIM4cgsb; return(OK); - case BSIM4_CDG: + case BSIM4_CDGB: value->rValue = here->BSIM4cdgb; return(OK); - case BSIM4_CDD: + case BSIM4_CDDB: value->rValue = here->BSIM4cddb; return(OK); - case BSIM4_CDS: + case BSIM4_CDSB: value->rValue = here->BSIM4cdsb; return(OK); - case BSIM4_CBG: + case BSIM4_CBGB: value->rValue = here->BSIM4cbgb; return(OK); case BSIM4_CBDB: @@ -222,6 +253,27 @@ BSIM4instance *here = (BSIM4instance*)inst; case BSIM4_CBSB: value->rValue = here->BSIM4cbsb; return(OK); + case BSIM4_CSGB: + value->rValue = here->BSIM4csgb; + return(OK); + case BSIM4_CSDB: + value->rValue = here->BSIM4csdb; + return(OK); + case BSIM4_CSSB: + value->rValue = here->BSIM4cssb; + return(OK); + case BSIM4_CGBB: + value->rValue = here->BSIM4cgbb; + return(OK); + case BSIM4_CDBB: + value->rValue = here->BSIM4cdbb; + return(OK); + case BSIM4_CSBB: + value->rValue = here->BSIM4csbb; + return(OK); + case BSIM4_CBBB: + value->rValue = here->BSIM4cbbb; + return(OK); case BSIM4_CAPBD: value->rValue = here->BSIM4capbd; return(OK); diff --git a/src/spicelib/devices/bsim4/b4check.c b/src/spicelib/devices/bsim4/b4check.c index 362e9204c..50fb00be1 100644 --- a/src/spicelib/devices/bsim4/b4check.c +++ b/src/spicelib/devices/bsim4/b4check.c @@ -1,10 +1,13 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4check.c of BSIM4.0.0. - * Authors: Weidong Liu, Kanyu M. Cao, Xiaodong Jin, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4check.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. + * Modified by Xuemei Xi, 04/06/2001. + * Modified by Xuemei Xi, 10/05/2001. **********/ #include "ngspice.h" @@ -17,11 +20,10 @@ #include "sperror.h" #include "devdefs.h" - int BSIM4checkModel(model, here, ckt) -register BSIM4model *model; -register BSIM4instance *here; +BSIM4model *model; +BSIM4instance *here; CKTcircuit *ckt; { struct bsim4SizeDependParam *pParam; @@ -31,21 +33,22 @@ FILE *fplog; if ((fplog = fopen("bsim4.out", "w")) != NULL) { pParam = here->pParam; fprintf(fplog, "BSIM4: Berkeley Short Channel IGFET Model-4\n"); - fprintf(fplog, "Developed by Dr. Weidong Liu, Xiaodong Jin, Kanyu M. Cao and Prof. Chenming Hu in 2000.\n"); + fprintf(fplog, "Developed by Weidong Liu, Xuemei Xi , Xiaodong Jin, Kanyu M. Cao and Prof. Chenming Hu in 2001.\n"); fprintf(fplog, "\n"); fprintf(fplog, "++++++++++ BSIM4 PARAMETER CHECKING BELOW ++++++++++\n"); - if (strcmp(model->BSIM4version, "4.0.0") != 0) - { fprintf(fplog, "Warning: This model is BSIM4.0.0; you specified a wrong version number.\n"); - printf("Warning: This model is BSIM4.0.0; you specified a wrong version number.\n"); + if (strcmp(model->BSIM4version, "4.2.1") != 0) + { fprintf(fplog, "Warning: This model is BSIM4.2.1; you specified a wrong version number.\n"); + printf("Warning: This model is BSIM4.2.1; you specified a wrong version number.\n"); } fprintf(fplog, "Model = %s\n", model->BSIM4modName); if ((here->BSIM4rgateMod == 2) || (here->BSIM4rgateMod == 3)) { if ((here->BSIM4trnqsMod == 1) || (here->BSIM4acnqsMod == 1)) - fprintf(fplog, "Warning: You've selected both Rg and charge deficit NQS; select one only.\n"); - printf("Warning: You've selected both Rg and charge deficit NQS; select one only.\n"); + { fprintf(fplog, "Warning: You've selected both Rg and charge deficit NQS; select one only.\n"); + printf("Warning: You've selected both Rg and charge deficit NQS; select one only.\n"); + } } @@ -207,15 +210,10 @@ FILE *fplog; printf("Fatal: Number of finger = %g is smaller than one.\n", here->BSIM4nf); Fatal_Flag = 1; } - if (here->BSIM4nf > 500.0) - { here->BSIM4nf = 20.0; - fprintf(fplog, "Warning: Nf = %g is too large; reset to 20.0.\n", here->BSIM4nf); - printf("Warning: Nf = %g is too large; reset to 20.0.\n", here->BSIM4nf); - } - if (here->BSIM4l <= model->BSIM4xgl) - { fprintf(fplog, "Fatal: The parameter xgl must be smaller than Ldrawn.\n"); - printf("Fatal: The parameter xgl must be smaller than Ldrawn.\n"); + if ((here->BSIM4l + model->BSIM4xl) <= model->BSIM4xgl) + { fprintf(fplog, "Fatal: The parameter xgl must be smaller than Ldrawn+XL.\n"); + printf("Fatal: The parameter xgl must be smaller than Ldrawn+XL.\n"); Fatal_Flag = 1; } if (model->BSIM4ngcon < 1.0) @@ -274,64 +272,65 @@ FILE *fplog; pParam->BSIM4moin); printf("Warning: Moin = %g is too large.\n", pParam->BSIM4moin); } - - if (pParam->BSIM4acde < 0.4) - { fprintf(fplog, "Warning: Acde = %g is too small.\n", - pParam->BSIM4acde); - printf("Warning: Acde = %g is too small.\n", pParam->BSIM4acde); - } - if (pParam->BSIM4acde > 1.6) - { fprintf(fplog, "Warning: Acde = %g is too large.\n", - pParam->BSIM4acde); - printf("Warning: Acde = %g is too large.\n", pParam->BSIM4acde); - } + if(model->BSIM4capMod ==2) { + if (pParam->BSIM4acde < 0.4) + { fprintf(fplog, "Warning: Acde = %g is too small.\n", + pParam->BSIM4acde); + printf("Warning: Acde = %g is too small.\n", pParam->BSIM4acde); + } + if (pParam->BSIM4acde > 1.6) + { fprintf(fplog, "Warning: Acde = %g is too large.\n", + pParam->BSIM4acde); + printf("Warning: Acde = %g is too large.\n", pParam->BSIM4acde); + } + } if (model->BSIM4paramChk ==1) { /* Check L and W parameters */ - if (pParam->BSIM4leff <= 5.0e-8) - { fprintf(fplog, "Warning: Leff = %g may be too small.\n", - pParam->BSIM4leff); - printf("Warning: Leff = %g may be too small.\n", + if (pParam->BSIM4leff <= 1.0e-9) + { fprintf(fplog, "Warning: Leff = %g <= 1.0e-9. Recommended Leff >= 1e-8 \n", + pParam->BSIM4leff); + printf("Warning: Leff = %g <= 1.0e-9. Recommended Leff >= 1e-8 \n", pParam->BSIM4leff); } - if (pParam->BSIM4leffCV <= 5.0e-8) - { fprintf(fplog, "Warning: Leff for CV = %g may be too small.\n", + if (pParam->BSIM4leffCV <= 1.0e-9) + { fprintf(fplog, "Warning: Leff for CV = %g <= 1.0e-9. Recommended LeffCV >=1e-8 \n", + pParam->BSIM4leffCV); + printf("Warning: Leff for CV = %g <= 1.0e-9. Recommended LeffCV >=1e-8 \n", pParam->BSIM4leffCV); - printf("Warning: Leff for CV = %g may be too small.\n", - pParam->BSIM4leffCV); } - if (pParam->BSIM4weff <= 1.0e-7) - { fprintf(fplog, "Warning: Weff = %g may be too small.\n", + if (pParam->BSIM4weff <= 1.0e-9) + { fprintf(fplog, "Warning: Weff = %g <= 1.0e-9. Recommended Weff >=1e-7 \n", pParam->BSIM4weff); - printf("Warning: Weff = %g may be too small.\n", + printf("Warning: Weff = %g <= 1.0e-9. Recommended Weff >=1e-7 \n", pParam->BSIM4weff); } - if (pParam->BSIM4weffCV <= 1.0e-7) - { fprintf(fplog, "Warning: Weff for CV = %g may be too small.\n", + if (pParam->BSIM4weffCV <= 1.0e-9) + { fprintf(fplog, "Warning: Weff for CV = %g <= 1.0e-9. Recommended WeffCV >= 1e-7 \n", + pParam->BSIM4weffCV); + printf("Warning: Weff for CV = %g <= 1.0e-9. Recommended WeffCV >= 1e-7 \n", pParam->BSIM4weffCV); - printf("Warning: Weff for CV = %g may be too small.\n", - pParam->BSIM4weffCV); } /* Check threshold voltage parameters */ - if (model->BSIM4toxe < 1.0e-9) - { fprintf(fplog, "Warning: Toxe = %g is less than 10A.\n", + if (model->BSIM4toxe < 1.0e-10) + { fprintf(fplog, "Warning: Toxe = %g is less than 1A. Recommended Toxe >= 5A\n", model->BSIM4toxe); - printf("Warning: Toxe = %g is less than 10A.\n", model->BSIM4toxe); + printf("Warning: Toxe = %g is less than 1A. Recommended Toxe >= 5A\n", model->BSIM4toxe); } - if (model->BSIM4toxp < 1.0e-9) - { fprintf(fplog, "Warning: Toxp = %g is less than 10A.\n", + if (model->BSIM4toxp < 1.0e-10) + { fprintf(fplog, "Warning: Toxp = %g is less than 1A. Recommended Toxp >= 5A\n", model->BSIM4toxp); - printf("Warning: Toxp = %g is less than 10A.\n", model->BSIM4toxp); + printf("Warning: Toxp = %g is less than 1A. Recommended Toxp >= 5A\n", model->BSIM4toxp); } - if (model->BSIM4toxm < 1.0e-9) - { fprintf(fplog, "Warning: Toxm = %g is less than 10A.\n", + if (model->BSIM4toxm < 1.0e-10) + { fprintf(fplog, "Warning: Toxm = %g is less than 1A. Recommended Toxm >= 5A\n", model->BSIM4toxm); - printf("Warning: Toxm = %g is less than 10A.\n", model->BSIM4toxm); + printf("Warning: Toxm = %g is less than 1A. Recommended Toxm >= 5A\n", model->BSIM4toxm); } if (pParam->BSIM4ndep <= 1.0e12) diff --git a/src/spicelib/devices/bsim4/b4cvtest.c b/src/spicelib/devices/bsim4/b4cvtest.c index 512c9e1bd..2626b5a5f 100644 --- a/src/spicelib/devices/bsim4/b4cvtest.c +++ b/src/spicelib/devices/bsim4/b4cvtest.c @@ -1,10 +1,13 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4cvtest.c of BSIM4.0.0. - * Authors: Weidong Liu, Kanyu M. Cao, Xiaodong Jin, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4cvtest.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. + * + * Modified by Xuemei Xi, 10/05/2001. **********/ #include "ngspice.h" @@ -18,13 +21,14 @@ #include "sperror.h" + int BSIM4convTest(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { -register BSIM4model *model = (BSIM4model*)inModel; -register BSIM4instance *here; +BSIM4model *model = (BSIM4model*)inModel; +BSIM4instance *here; double delvbd, delvbs, delvds, delvgd, delvgs; double delvdbd, delvsbs; double delvbd_jct, delvbs_jct; @@ -40,7 +44,8 @@ double tol0, tol1, tol2, tol3, tol4, tol5, tol6; { for (here = model->BSIM4instances; here != NULL ; here=here->BSIM4nextInstance) { - if (here->BSIM4owner != ARCHme) continue; + if (here->BSIM4owner != ARCHme) continue; + vds = model->BSIM4type * (*(ckt->CKTrhsOld + here->BSIM4dNodePrime) - *(ckt->CKTrhsOld + here->BSIM4sNodePrime)); @@ -108,10 +113,11 @@ double tol0, tol1, tol2, tol3, tol4, tol5, tol6; * delvds + here->BSIM4gIgbb * delvbs; } else - { Idtot = here->BSIM4cd + here->BSIM4cbd; - cdhat = Idtot + here->BSIM4gbd * delvbd_jct + here->BSIM4gmbs - * delvbd + here->BSIM4gm * delvgd - - here->BSIM4gds * delvds; + { Idtot = here->BSIM4cd + here->BSIM4cbd - here->BSIM4Igisl; + cdhat = Idtot + here->BSIM4gbd * delvbd_jct + here->BSIM4gmbs + * delvbd + here->BSIM4gm * delvgd + - here->BSIM4gds * delvds - here->BSIM4ggislg * vgd + - here->BSIM4ggislb * vbd + here->BSIM4ggisls * vds; Igstot = here->BSIM4Igs + here->BSIM4Igcd; cgshat = Igstot + here->BSIM4gIgsg * delvgs + here->BSIM4gIgcdg * delvgd @@ -167,18 +173,20 @@ double tol0, tol1, tol2, tol3, tol4, tol5, tol6; } Ibtot = here->BSIM4cbs + here->BSIM4cbd - - here->BSIM4Igidl - here->BSIM4csub; + - here->BSIM4Igidl - here->BSIM4Igisl - here->BSIM4csub; if (here->BSIM4mode >= 0) { cbhat = Ibtot + here->BSIM4gbd * delvbd_jct + here->BSIM4gbs * delvbs_jct - (here->BSIM4gbbs + here->BSIM4ggidlb) * delvbs - (here->BSIM4gbgs + here->BSIM4ggidlg) * delvgs - - (here->BSIM4gbds + here->BSIM4ggidld) * delvds; + - (here->BSIM4gbds + here->BSIM4ggidld) * delvds + - here->BSIM4ggislg * delvgd - here->BSIM4ggislb* delvbd + here->BSIM4ggisls * delvds ; } else { cbhat = Ibtot + here->BSIM4gbs * delvbs_jct + here->BSIM4gbd * delvbd_jct - (here->BSIM4gbbs + here->BSIM4ggidlb) * delvbd - (here->BSIM4gbgs + here->BSIM4ggidlg) * delvgd - + (here->BSIM4gbds + here->BSIM4ggidld) * delvds; + + (here->BSIM4gbds + here->BSIM4ggidld) * delvds + - here->BSIM4ggislg * delvgs - here->BSIM4ggislb * delvbs + here->BSIM4ggisls * delvds; } tol6 = ckt->CKTreltol * MAX(fabs(cbhat), fabs(Ibtot)) + ckt->CKTabstol; diff --git a/src/spicelib/devices/bsim4/b4del.c b/src/spicelib/devices/bsim4/b4del.c index ef326a86d..fde0870bc 100644 --- a/src/spicelib/devices/bsim4/b4del.c +++ b/src/spicelib/devices/bsim4/b4del.c @@ -1,9 +1,10 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4del.c of BSIM4.0.0. - * Authors: Weidong Liu, Kanyu M. Cao, Xiaodong Jin, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4del.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. **********/ diff --git a/src/spicelib/devices/bsim4/b4dest.c b/src/spicelib/devices/bsim4/b4dest.c index ae96f883f..d1c5f2bd4 100644 --- a/src/spicelib/devices/bsim4/b4dest.c +++ b/src/spicelib/devices/bsim4/b4dest.c @@ -1,9 +1,10 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4dest.c of BSIM4.0.0. - * Authors: Weidong Liu, Kanyu M. Cao, Xiaodong Jin, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4dest.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. **********/ diff --git a/src/spicelib/devices/bsim4/b4geo.c b/src/spicelib/devices/bsim4/b4geo.c index 6f1122471..616d478db 100644 --- a/src/spicelib/devices/bsim4/b4geo.c +++ b/src/spicelib/devices/bsim4/b4geo.c @@ -1,9 +1,10 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4geo.c of BSIM4.0.0. - * Authors: Weidong Liu, Kanyu M. Cao, Xiaodong Jin, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4geo.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. **********/ @@ -259,7 +260,8 @@ double nuIntD = 0.0, nuEndD = 0.0, nuIntS = 0.0, nuEndS = 0.0; *Rtot = Rint; else *Rtot = Rint * Rend / (Rint + Rend); - +if(*Rtot==0.0) + printf("Warning: Zero resistance returned from RdseffGeo\n"); return 0; } diff --git a/src/spicelib/devices/bsim4/b4getic.c b/src/spicelib/devices/bsim4/b4getic.c index 2f9e9688c..0c1550e04 100644 --- a/src/spicelib/devices/bsim4/b4getic.c +++ b/src/spicelib/devices/bsim4/b4getic.c @@ -1,9 +1,10 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4getic.c of BSIM4.0.0. - * Authors: Weidong Liu, Kanyu M. Cao, Xiaodong Jin, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4getic.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. **********/ @@ -14,7 +15,6 @@ #include "sperror.h" - int BSIM4getic(inModel,ckt) GENmodel *inModel; @@ -25,8 +25,8 @@ BSIM4instance *here; for (; model ; model = model->BSIM4nextModel) { for (here = model->BSIM4instances; here; here = here->BSIM4nextInstance) - { if (here->BSIM4owner != ARCHme) continue; - if (!here->BSIM4icVDSGiven) + { if (here->BSIM4owner != ARCHme) continue; + if (!here->BSIM4icVDSGiven) { here->BSIM4icVDS = *(ckt->CKTrhs + here->BSIM4dNode) - *(ckt->CKTrhs + here->BSIM4sNode); } diff --git a/src/spicelib/devices/bsim4/b4ld.c b/src/spicelib/devices/bsim4/b4ld.c index 30f81e433..e89ad662e 100644 --- a/src/spicelib/devices/bsim4/b4ld.c +++ b/src/spicelib/devices/bsim4/b4ld.c @@ -1,11 +1,14 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4ld.c of BSIM4.0.0. - * Author: Weidong Liu, Kanyu M. Cao, Xiaodong Jin, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4ld.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. - ******/ + + * Modified by Xuemei Xi, 10/05/2001. + **********/ #include "ngspice.h" #include @@ -17,7 +20,6 @@ #include "sperror.h" #include "devdefs.h" - #define MAX_EXP 5.834617425e14 #define MIN_EXP 1.713908431e-15 #define EXP_THRESHOLD 34.0 @@ -28,6 +30,7 @@ #define DELTA_3 0.02 #define DELTA_4 0.02 +int BSIM4polyDepletion(double phi, double ngate,double coxe, double Vgs, double *Vgs_eff, double *dVgs_eff_dVg); int BSIM4load(inModel,ckt) @@ -83,6 +86,7 @@ double Igs, dIgs_dVg, dIgs_dVs, Igd, dIgd_dVg, dIgd_dVd; double Igbacc, dIgbacc_dVg, dIgbacc_dVd, dIgbacc_dVb; double Igbinv, dIgbinv_dVg, dIgbinv_dVd, dIgbinv_dVb; double Igb, dIgb_dVg, dIgb_dVd, dIgb_dVb; +double Pigcd, dPigcd_dVg, dPigcd_dVd, dPigcd_dVb; double Istoteq, gIstotg, gIstotd, gIstots, gIstotb; double Idtoteq, gIdtotg, gIdtotd, gIdtots, gIdtotb; double Ibtoteq, gIbtotg, gIbtotd, gIbtots, gIbtotb; @@ -117,7 +121,7 @@ double T7, dT7_dVg, dT7_dVd, dT7_dVb; double T8, dT8_dVg, dT8_dVd, dT8_dVb; double T9, dT9_dVg, dT9_dVd, dT9_dVb; double T10, dT10_dVg, dT10_dVb, dT10_dVd; -double T11, T12; +double T11, T12, T13, T14; double tmp, Abulk, dAbulk_dVb, Abulk0, dAbulk0_dVb; double Cclm, dCclm_dVg, dCclm_dVd, dCclm_dVb; double FP, dFP_dVg, PvagTerm, dPvagTerm_dVg, dPvagTerm_dVd, dPvagTerm_dVb; @@ -161,6 +165,10 @@ double Cgg, Cgd, Cgs, Cgb, Cdg, Cdd, Cds, Cdb, Qg, Qd; double Csg, Csd, Css, Csb, Cbg, Cbd, Cbs, Cbb, Qs, Qb; double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Csg1, Csd1, Csb1, Qac0, Qsub0; double dQac0_dVg, dQac0_dVb, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb; +double ggidld, ggidlg, ggidlb,ggisld, ggislg, ggislb, ggisls; +double Igisl, Ggisld, Ggislg, Ggislb, Ggisls; + + struct bsim4SizeDependParam *pParam; int ByPass, ChargeComputationNeeded, error, Check, Check1, Check2; @@ -175,8 +183,7 @@ ChargeComputationNeeded = for (; model != NULL; model = model->BSIM4nextModel) { for (here = model->BSIM4instances; here != NULL; here = here->BSIM4nextInstance) - { - if (here->BSIM4owner != ARCHme) continue; + { if (here->BSIM4owner != ARCHme) continue; Check = Check1 = Check2 = 1; ByPass = 0; pParam = here->pParam; @@ -372,11 +379,12 @@ for (; model != NULL; model = model->BSIM4nextModel) + (here->BSIM4gm + here->BSIM4gbgs + here->BSIM4ggidlg) * delvgs + (here->BSIM4gds + here->BSIM4gbds + here->BSIM4ggidld) * delvds; Ibtot = here->BSIM4cbs + here->BSIM4cbd - - here->BSIM4Igidl - here->BSIM4csub; + - here->BSIM4Igidl - here->BSIM4Igisl - here->BSIM4csub; cbhat = Ibtot + here->BSIM4gbd * delvbd_jct + here->BSIM4gbs * delvbs_jct - (here->BSIM4gbbs + here->BSIM4ggidlb) * delvbs - (here->BSIM4gbgs + here->BSIM4ggidlg) * delvgs - - (here->BSIM4gbds + here->BSIM4ggidld) * delvds; + - (here->BSIM4gbds + here->BSIM4ggidld) * delvds + - here->BSIM4ggislg * delvgd - here->BSIM4ggislb* delvbd + here->BSIM4ggisls * delvds ; Igstot = here->BSIM4Igs + here->BSIM4Igcs; cgshat = Igstot + (here->BSIM4gIgsg + here->BSIM4gIgcsg) * delvgs @@ -391,16 +399,18 @@ for (; model != NULL; model = model->BSIM4nextModel) * delvds + here->BSIM4gIgbb * delvbs; } else - { Idtot = here->BSIM4cd + here->BSIM4cbd; + { Idtot = here->BSIM4cd + here->BSIM4cbd - here->BSIM4Igisl; cdhat = Idtot + here->BSIM4gbd * delvbd_jct + here->BSIM4gmbs * delvbd + here->BSIM4gm * delvgd - - here->BSIM4gds * delvds; + - here->BSIM4gds * delvds - here->BSIM4ggislg * vgd + - here->BSIM4ggislb * vbd + here->BSIM4ggisls * vds; Ibtot = here->BSIM4cbs + here->BSIM4cbd - - here->BSIM4Igidl - here->BSIM4csub; + - here->BSIM4Igidl - here->BSIM4Igisl - here->BSIM4csub; cbhat = Ibtot + here->BSIM4gbs * delvbs_jct + here->BSIM4gbd * delvbd_jct - (here->BSIM4gbbs + here->BSIM4ggidlb) * delvbd - (here->BSIM4gbgs + here->BSIM4ggidlg) * delvgd - + (here->BSIM4gbds + here->BSIM4ggidld) * delvds; + + (here->BSIM4gbds + here->BSIM4ggidld) * delvds + - here->BSIM4ggislg * delvgs - here->BSIM4ggislb * delvbs + here->BSIM4ggisls * delvds; Igstot = here->BSIM4Igs + here->BSIM4Igcd; cgshat = Igstot + here->BSIM4gIgsg * delvgs + here->BSIM4gIgcdg * delvgd @@ -917,7 +927,7 @@ for (; model != NULL; model = model->BSIM4nextModel) T3 = T2 * T2; T4 = T3 + 2.0 * T1 * MIN_EXP; T5 = T1 / T4; - dT1_dVb = -T0 * T1 * dlt1_dVb / lt1; + dT1_dVb = -T0 * T1 * dltw_dVb / ltw; /* bugfix -JX */ dT5_dVb = dT1_dVb * (T4 - 2.0 * T1 * (T2 + MIN_EXP)) / T4 / T4; } else @@ -1014,24 +1024,24 @@ for (; model != NULL; model = model->BSIM4nextModel) /* Poly Gate Si Depletion Effect */ T0 = pParam->BSIM4vfb + pParam->BSIM4phi; - if ((pParam->BSIM4ngate > 1.0e18) - && (pParam->BSIM4ngate < 1.0e25) && (Vgs > T0)) - { T1 = 1.0e6 * Charge_q * EPSSI * pParam->BSIM4ngate - / (model->BSIM4coxe * model->BSIM4coxe); - T8 = Vgs - T0; - T4 = sqrt(1.0 + 2.0 * T8 / T1); - T2 = 2.0 * T8 / (T4 + 1.0); - T3 = 0.5 * T2 * T2 / T1; /* T3 = Vpoly */ - T7 = 1.12 - T3 - 0.05; - T6 = sqrt(T7 * T7 + 0.224); - T5 = 1.12 - 0.5 * (T7 + T6); - Vgs_eff = Vgs - T5; - dVgs_eff_dVg = 1.0 - (0.5 - 0.5 / T4) * (1.0 + T7 / T6); - } - else - { Vgs_eff = Vgs; - dVgs_eff_dVg = 1.0; - } + + BSIM4polyDepletion(T0, pParam->BSIM4ngate, model->BSIM4coxe, vgs, &vgs_eff, &dvgs_eff_dvg); + + BSIM4polyDepletion(T0, pParam->BSIM4ngate, model->BSIM4coxe, vgd, &vgd_eff, &dvgd_eff_dvg); + + if(here->BSIM4mode>0) { + Vgs_eff = vgs_eff; + dVgs_eff_dVg = dvgs_eff_dvg; + } else { + Vgs_eff = vgd_eff; + dVgs_eff_dVg = dvgd_eff_dvg; + } + here->BSIM4vgs_eff = vgs_eff; + here->BSIM4vgd_eff = vgd_eff; + here->BSIM4dvgs_eff_dvg = dvgs_eff_dvg; + here->BSIM4dvgd_eff_dvg = dvgd_eff_dvg; + + Vgst = Vgs_eff - Vth; /* Calculate Vgsteff */ @@ -1851,14 +1861,17 @@ for (; model != NULL; model = model->BSIM4nextModel) } /* Calculate GIDL current */ + vgs_eff = here->BSIM4vgs_eff; + dvgs_eff_dvg = here->BSIM4dvgs_eff_dvg; T0 = 3.0 * model->BSIM4toxe; - T1 = (Vds - Vgs_eff - pParam->BSIM4egidl) / T0; - if ((pParam->BSIM4agidl <= 0.0) || (pParam->BSIM4bgidl <= 0.0) || (T1 < 0.0) - || (pParam->BSIM4cgidl <= 0.0) || (Vdb < 0.0)) + + T1 = (vds - vgs_eff - pParam->BSIM4egidl ) / T0; + if ((pParam->BSIM4agidl <= 0.0) || (pParam->BSIM4bgidl <= 0.0) + || (T1 <= 0.0) || (pParam->BSIM4cgidl <= 0.0) || (vbd > 0.0)) Igidl = Ggidld = Ggidlg = Ggidlb = 0.0; - else - { dT1_dVd = 1.0 / T0; - dT1_dVg = -dVgs_eff_dVg * dT1_dVd; + else { + dT1_dVd = 1.0 / T0; + dT1_dVg = -dvgs_eff_dvg * dT1_dVd; T2 = pParam->BSIM4bgidl / T1; if (T2 < 100.0) { Igidl = pParam->BSIM4agidl * pParam->BSIM4weffCJ * T1 * exp(-T2); @@ -1866,28 +1879,69 @@ for (; model != NULL; model = model->BSIM4nextModel) Ggidld = T3 * dT1_dVd; Ggidlg = T3 * dT1_dVg; } - else + else { Igidl = pParam->BSIM4agidl * pParam->BSIM4weffCJ * 3.720075976e-44; Ggidld = Igidl * dT1_dVd; Ggidlg = Igidl * dT1_dVg; Igidl *= T1; } - - T4 = Vdb * Vdb; - T5 = Vdb * T4; + + T4 = vbd * vbd; + T5 = -vbd * T4; T6 = pParam->BSIM4cgidl + T5; - T7 = T5 / T6; - T8 = 3.0 * pParam->BSIM4cgidl * T4 / T6 / T6; - Ggidld = Ggidld * T7 + Igidl * T8; - Ggidlg = Ggidlg * T7; - Ggidlb = -Igidl * T8; - Igidl *= T7; + T7 = T5 / T6; + T8 = 3.0 * pParam->BSIM4cgidl * T4 / T6 / T6; + Ggidld = Ggidld * T7 + Igidl * T8; + Ggidlg = Ggidlg * T7; + Ggidlb = -Igidl * T8; + Igidl *= T7; } here->BSIM4Igidl = Igidl; - here->BSIM4ggidld = Ggidld; + here->BSIM4ggidld = Ggidld; here->BSIM4ggidlg = Ggidlg; here->BSIM4ggidlb = Ggidlb; + /* Calculate GISL current: bugfix recommended by TI -JX */ + vgd_eff = here->BSIM4vgd_eff; + dvgd_eff_dvg = here->BSIM4dvgd_eff_dvg; + + T1 = (-vds - vgd_eff - pParam->BSIM4egidl ) / T0; + + if ((pParam->BSIM4agidl <= 0.0) || (pParam->BSIM4bgidl <= 0.0) + || (T1 <= 0.0) || (pParam->BSIM4cgidl <= 0.0) || (vbs > 0.0)) + Igisl = Ggisls = Ggislg = Ggislb = 0.0; + else { + dT1_dVd = 1.0 / T0; + dT1_dVg = -dvgd_eff_dvg * dT1_dVd; + T2 = pParam->BSIM4bgidl / T1; + if (T2 < 100.0) + { Igisl = pParam->BSIM4agidl * pParam->BSIM4weffCJ * T1 * exp(-T2); + T3 = Igisl * (1.0 + T2) / T1; + Ggisls = T3 * dT1_dVd; + Ggislg = T3 * dT1_dVg; + } + else + { Igisl = pParam->BSIM4agidl * pParam->BSIM4weffCJ * 3.720075976e-44; + Ggisls = Igisl * dT1_dVd; + Ggislg = Igisl * dT1_dVg; + Igisl *= T1; + } + + T4 = vbs * vbs; + T5 = -vbs * T4; + T6 = pParam->BSIM4cgidl + T5; + T7 = T5 / T6; + T8 = 3.0 * pParam->BSIM4cgidl * T4 / T6 / T6; + Ggisls = Ggisls * T7 + Igisl * T8; + Ggislg = Ggislg * T7; + Ggislb = -Igisl * T8; + Igisl *= T7; + } + here->BSIM4Igisl = Igisl; + here->BSIM4ggisls = Ggisls; + here->BSIM4ggislg = Ggislg; + here->BSIM4ggislb = Ggislb; + /* Calculate gate tunneling current */ if ((model->BSIM4igcMod != 0) || (model->BSIM4igbMod != 0)) @@ -1938,7 +1992,7 @@ for (; model != NULL; model = model->BSIM4nextModel) if (model->BSIM4igcMod) { T0 = Vtm * pParam->BSIM4nigc; - VxNVt = (Vgs_eff - model->BSIM4type * pParam->BSIM4vth0) / T0; /* Vth instead of Vth0 may be used */ + VxNVt = (Vgs_eff - model->BSIM4type * pParam->BSIM4vth0) / T0; if (VxNVt > EXP_THRESHOLD) { Vaux = Vgs_eff - model->BSIM4type * pParam->BSIM4vth0; dVaux_dVg = dVgs_eff_dVg; @@ -1953,8 +2007,8 @@ for (; model != NULL; model = model->BSIM4nextModel) { ExpVxNVt = exp(VxNVt); Vaux = T0 * log(1.0 + ExpVxNVt); dVaux_dVg = ExpVxNVt / (1.0 + ExpVxNVt); - dVaux_dVd = -dVaux_dVg * 0.0; - dVaux_dVb = -dVaux_dVg * 0.0; + dVaux_dVd = 0.0; + dVaux_dVb = 0.0; dVaux_dVg *= dVgs_eff_dVg; } @@ -1992,40 +2046,74 @@ for (; model != NULL; model = model->BSIM4nextModel) dIgc_dVd = T11 * (T2 * dT6_dVd + T6 * dT2_dVd); dIgc_dVb = T11 * (T2 * dT6_dVb + T6 * dT2_dVb); - T7 = -pParam->BSIM4pigcd * Vds; - T8 = T7 * T7 + 2.0e-4; - dT8_dVd = -2.0 * pParam->BSIM4pigcd * T7; - if (T7 > EXP_THRESHOLD) - { T9 = MAX_EXP; - dT9_dVd = 0.0; - } - else if (T7 < -EXP_THRESHOLD) + if (model->BSIM4pigcdGiven) + { Pigcd = pParam->BSIM4pigcd; + dPigcd_dVg = dPigcd_dVd = dPigcd_dVb = 0.0; + } + else + { T11 = pParam->BSIM4Bechvb * model->BSIM4toxe; + T12 = Vgsteff + 1.0e-20; + T13 = T11 / T12 / T12; + T14 = -T13 / T12; + Pigcd = T13 * (1.0 - 0.5 * Vdseff / T12); + dPigcd_dVg = T14 * (2.0 + 0.5 * (dVdseff_dVg + * Vgsteff - 3.0 * Vdseff) / T12); + dPigcd_dVd = 0.5 * T14 * dVdseff_dVd + + dPigcd_dVg * dVgsteff_dVd; + dPigcd_dVb = 0.5 * T14 * dVdseff_dVb + + dPigcd_dVg * dVgsteff_dVb; + dPigcd_dVg *= dVgsteff_dVg; + } + + T7 = -Pigcd * Vds; + dT7_dVg = -Vds * dPigcd_dVg; + dT7_dVd = -Pigcd - Vds * dPigcd_dVd; + dT7_dVb = -Vds * dPigcd_dVb; + T8 = T7 * T7 + 2.0e-4; + dT8_dVg = 2.0 * T7; + dT8_dVd = dT8_dVg * dT7_dVd; + dT8_dVb = dT8_dVg * dT7_dVb; + dT8_dVg *= dT7_dVg; + + if (T7 > EXP_THRESHOLD) + { T9 = MAX_EXP; + dT9_dVg = dT9_dVd = dT9_dVb = 0.0; + } + else if (T7 < -EXP_THRESHOLD) { T9 = MIN_EXP; - dT9_dVd = 0.0; + dT9_dVg = dT9_dVd = dT9_dVb = 0.0; } else { T9 = exp(T7); - dT9_dVd = -T9 * pParam->BSIM4pigcd; + dT9_dVg = T9 * dT7_dVg; + dT9_dVd = T9 * dT7_dVd; + dT9_dVb = T9 * dT7_dVb; } - T0 = T8 * T8; - T1 = T9 - 1.0 + 1.0e-4; - T10 = (T1 - T7) / T8; - dT10_dVd = ((pParam->BSIM4pigcd + dT9_dVd) * T8 - - (T1 - T7) * dT8_dVd) / T0; - Igcs = Igc * T10; - dIgcs_dVg = dIgc_dVg * T10; + T0 = T8 * T8; + T1 = T9 - 1.0 + 1.0e-4; + T10 = (T1 - T7) / T8; + dT10_dVg = (dT9_dVg - dT7_dVg - T10 * dT8_dVg) / T8; + dT10_dVd = (dT9_dVd - dT7_dVd - T10 * dT8_dVd) / T8; + dT10_dVb = (dT9_dVb - dT7_dVb - T10 * dT8_dVb) / T8; + + Igcs = Igc * T10; + dIgcs_dVg = dIgc_dVg * T10 + Igc * dT10_dVg; dIgcs_dVd = dIgc_dVd * T10 + Igc * dT10_dVd; - dIgcs_dVb = dIgc_dVb * T10; + dIgcs_dVb = dIgc_dVb * T10 + Igc * dT10_dVb; T1 = T9 - 1.0 - 1.0e-4; T10 = (T7 * T9 - T1) / T8; - dT10_dVd = (-pParam->BSIM4pigcd * T9 + (T7 - 1.0) - * dT9_dVd - T10 * dT8_dVd) / T8; + dT10_dVg = (dT7_dVg * T9 + (T7 - 1.0) * dT9_dVg + - T10 * dT8_dVg) / T8; + dT10_dVd = (dT7_dVd * T9 + (T7 - 1.0) * dT9_dVd + - T10 * dT8_dVd) / T8; + dT10_dVb = (dT7_dVb * T9 + (T7 - 1.0) * dT9_dVb + - T10 * dT8_dVb) / T8; Igcd = Igc * T10; - dIgcd_dVg = dIgc_dVg * T10; + dIgcd_dVg = dIgc_dVg * T10 + Igc * dT10_dVg; dIgcd_dVd = dIgc_dVd * T10 + Igc * dT10_dVd; - dIgcd_dVb = dIgc_dVb * T10; + dIgcd_dVb = dIgc_dVb * T10 + Igc * dT10_dVb; here->BSIM4Igcs = Igcs; here->BSIM4gIgcsg = dIgcs_dVg; @@ -2036,7 +2124,6 @@ for (; model != NULL; model = model->BSIM4nextModel) here->BSIM4gIgcdd = dIgcd_dVd; here->BSIM4gIgcdb = dIgcd_dVb * dVbseff_dVb; - T0 = vgs - pParam->BSIM4vfbsd; vgs_eff = sqrt(T0 * T0 + 1.0e-4); dvgs_eff_dvg = T0 / vgs_eff; @@ -2244,6 +2331,11 @@ for (; model != NULL; model = model->BSIM4nextModel) here->BSIM4ggidld *= here->BSIM4nf; here->BSIM4ggidlg *= here->BSIM4nf; here->BSIM4ggidlb *= here->BSIM4nf; + + here->BSIM4Igisl *= here->BSIM4nf; + here->BSIM4ggisls *= here->BSIM4nf; + here->BSIM4ggislg *= here->BSIM4nf; + here->BSIM4ggislb *= here->BSIM4nf; here->BSIM4Igcs *= here->BSIM4nf; here->BSIM4gIgcsg *= here->BSIM4nf; @@ -2269,6 +2361,8 @@ for (; model != NULL; model = model->BSIM4nextModel) here->BSIM4ggidls = -(here->BSIM4ggidld + here->BSIM4ggidlg + here->BSIM4ggidlb); + here->BSIM4ggisld = -(here->BSIM4ggisls + here->BSIM4ggislg + + here->BSIM4ggislb); here->BSIM4gIgbs = -(here->BSIM4gIgbg + here->BSIM4gIgbd + here->BSIM4gIgbb); here->BSIM4gIgcss = -(here->BSIM4gIgcsg + here->BSIM4gIgcsd @@ -2279,24 +2373,41 @@ for (; model != NULL; model = model->BSIM4nextModel) if (model->BSIM4tnoiMod == 0) - { T0 = Abulk * Vdseff; + { Abulk = Abulk0 * pParam->BSIM4abulkCVfactor; + Vdsat = Vgsteff / Abulk; + T0 = Vdsat - Vds - DELTA_4; + T1 = sqrt(T0 * T0 + 4.0 * DELTA_4 * Vdsat); + if (T0 >= 0.0) + Vdseff = Vdsat - 0.5 * (T0 + T1); + else + { T3 = (DELTA_4 + DELTA_4) / (T1 - T0); + T4 = 1.0 - T3; + T5 = Vdsat * T3 / (T1 - T0); + Vdseff = Vdsat * T4; + } + if (Vds == 0.0) + Vdseff = 0.0; + + T0 = Abulk * Vdseff; T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1.0e-20); T2 = Vdseff / T1; T3 = T0 * T2; here->BSIM4qinv = Coxeff * pParam->BSIM4weffCV * here->BSIM4nf * pParam->BSIM4leffCV - * (Vgsteff - 0.5 * T0 + Abulk * T3); - } + * (Vgsteff - 0.5 * T0 + Abulk * T3); + } /* * BSIM4 C-V begins */ - if ((model->BSIM4xpart < 0) || (!ChargeComputationNeeded)) + if ((model->BSIM4xpart < 0) || (!ChargeComputationNeeded)) { qgate = qdrn = qsrc = qbulk = 0.0; here->BSIM4cggb = here->BSIM4cgsb = here->BSIM4cgdb = 0.0; here->BSIM4cdgb = here->BSIM4cdsb = here->BSIM4cddb = 0.0; here->BSIM4cbgb = here->BSIM4cbsb = here->BSIM4cbdb = 0.0; + here->BSIM4csgb = here->BSIM4cssb = here->BSIM4csdb = 0.0; + here->BSIM4cgbb = here->BSIM4csbb = here->BSIM4cdbb = here->BSIM4cbbb = 0.0; here->BSIM4cqdb = here->BSIM4cqsb = here->BSIM4cqgb = here->BSIM4cqbb = 0.0; here->BSIM4gtau = 0.0; @@ -2534,7 +2645,7 @@ for (; model != NULL; model = model->BSIM4nextModel) here->BSIM4cbgb = -(here->BSIM4cggb + here->BSIM4cdgb + T12); here->BSIM4cbdb = -(here->BSIM4cgdb - + here->BSIM4cddb + T11); + + here->BSIM4cddb + T10); /* bug fix */ here->BSIM4cbsb = -(here->BSIM4cgsb + here->BSIM4cdsb + tmp); } @@ -2830,7 +2941,7 @@ for (; model != NULL; model = model->BSIM4nextModel) here->BSIM4cbdb = Cbd; } - /* New Charge-Thickness capMod (CTM) begins */ + /* Charge-Thickness capMod (CTM) begins */ else if (model->BSIM4capMod == 2) { V3 = pParam->BSIM4vfbzb - Vgs_eff + VbseffCV - DELTA_3; if (pParam->BSIM4vfbzb <= 0.0) @@ -3095,9 +3206,17 @@ for (; model != NULL; model = model->BSIM4nextModel) } /* End of CTM */ } + here->BSIM4csgb = - here->BSIM4cggb - here->BSIM4cdgb - here->BSIM4cbgb; + here->BSIM4csdb = - here->BSIM4cgdb - here->BSIM4cddb - here->BSIM4cbdb; + here->BSIM4cssb = - here->BSIM4cgsb - here->BSIM4cdsb - here->BSIM4cbsb; + here->BSIM4cgbb = - here->BSIM4cgdb - here->BSIM4cggb - here->BSIM4cgsb; + here->BSIM4cdbb = - here->BSIM4cddb - here->BSIM4cdgb - here->BSIM4cdsb; + here->BSIM4cbbb = - here->BSIM4cbgb - here->BSIM4cbdb - here->BSIM4cbsb; + here->BSIM4csbb = - here->BSIM4cgbb - here->BSIM4cdbb - here->BSIM4cbbb; here->BSIM4qgate = qgate; here->BSIM4qbulk = qbulk; here->BSIM4qdrn = qdrn; + here->BSIM4qsrc = -(qgate + qbulk + qdrn); /* NQS begins */ if ((here->BSIM4trnqsMod) || (here->BSIM4acnqsMod)) @@ -3132,13 +3251,13 @@ finished: /* Calculate junction C-V */ if (ChargeComputationNeeded) - { czbd = model->BSIM4DunitAreaJctCap * here->BSIM4Adeff; - czbs = model->BSIM4SunitAreaJctCap * here->BSIM4Aseff; - czbdsw = model->BSIM4DunitLengthSidewallJctCap * here->BSIM4Pdeff; - czbdswg = model->BSIM4DunitLengthGateSidewallJctCap + { czbd = model->BSIM4DunitAreaTempJctCap * here->BSIM4Adeff; /* bug fix */ + czbs = model->BSIM4SunitAreaTempJctCap * here->BSIM4Aseff; + czbdsw = model->BSIM4DunitLengthSidewallTempJctCap * here->BSIM4Pdeff; + czbdswg = model->BSIM4DunitLengthGateSidewallTempJctCap * pParam->BSIM4weffCJ * here->BSIM4nf; - czbssw = model->BSIM4SunitLengthSidewallJctCap * here->BSIM4Pseff; - czbsswg = model->BSIM4SunitLengthGateSidewallJctCap + czbssw = model->BSIM4SunitLengthSidewallTempJctCap * here->BSIM4Pseff; + czbsswg = model->BSIM4SunitLengthGateSidewallTempJctCap * pParam->BSIM4weffCJ * here->BSIM4nf; MJS = model->BSIM4SbulkJctBotGradingCoeff; @@ -3257,46 +3376,6 @@ finished: if ((here->BSIM4off == 0) || (!(ckt->CKTmode & MODEINITFIX))) { if (Check == 1) { ckt->CKTnoncon++; -#ifndef NEWCONV - } - else - { if (here->BSIM4mode >= 0) - { Idtot = here->BSIM4cd + here->BSIM4csub - + here->BSIM4Igidl - here->BSIM4cbd; - } - else - { Idtot = here->BSIM4cd + here->BSIM4cbd; - } - tol0 = ckt->CKTreltol * MAX(fabs(cdhat), fabs(Idtot)) - + ckt->CKTabstol; - tol1 = ckt->CKTreltol * MAX(fabs(cseshat), fabs(Isestot)) - + ckt->CKTabstol; - tol2 = ckt->CKTreltol * MAX(fabs(cdedhat), fabs(Idedtot)) - + ckt->CKTabstol; - tol3 = ckt->CKTreltol * MAX(fabs(cgshat), fabs(Igstot)) - + ckt->CKTabstol; - tol4 = ckt->CKTreltol * MAX(fabs(cgdhat), fabs(Igdtot)) - + ckt->CKTabstol; - tol5 = ckt->CKTreltol * MAX(fabs(cgbhat), fabs(Igbtot)) - + ckt->CKTabstol; - if ((fabs(cdhat - Idtot) >= tol0) || (fabs(cseshat - Isestot) >= tol1) - || (fabs(cdedhat - Idedtot) >= tol2)) - { ckt->CKTnoncon++; - } - else if ((fabs(cgshat - Igstot) >= tol3) || (fabs(cgdhat - Igdtot) >= tol4) - || (fabs(cgbhat - Igbtot) >= tol5)) - { ckt->CKTnoncon++; - } - else - { Ibtot = here->BSIM4cbs + here->BSIM4cbd - - here->BSIM4Igidl - here->BSIM4csub; - tol6 = ckt->CKTreltol * MAX(fabs(cbhat), fabs(Ibtot)) - + ckt->CKTabstol; - if (fabs(cbhat - Ibtot) > tol6) - { ckt->CKTnoncon++; - } - } -#endif /* NEWCONV */ } } *(ckt->CKTstate0 + here->BSIM4vds) = vds; @@ -3316,24 +3395,12 @@ finished: if (!ChargeComputationNeeded) goto line850; - if (model->BSIM4capMod == 0) - { if (vgd < 0.0) - { cgdo = pParam->BSIM4cgdo; + if (model->BSIM4capMod == 0) /* code merge -JX */ + { + cgdo = pParam->BSIM4cgdo; qgdo = pParam->BSIM4cgdo * vgd; - } - else - { cgdo = pParam->BSIM4cgdo; - qgdo = pParam->BSIM4cgdo * vgd; - } - - if (vgs < 0.0) - { cgso = pParam->BSIM4cgso; + cgso = pParam->BSIM4cgso; qgso = pParam->BSIM4cgso * vgs; - } - else - { cgso = pParam->BSIM4cgso; - qgso = pParam->BSIM4cgso * vgs; - } } else /* For both capMod == 1 and 2 */ { T0 = vgd + DELTA_1; @@ -3770,6 +3837,8 @@ line755: *(ckt->CKTstate0 + here->BSIM4qg) = qgate; *(ckt->CKTstate0 + here->BSIM4qd) = qdrn - *(ckt->CKTstate0 + here->BSIM4qbd); + *(ckt->CKTstate0 + here->BSIM4qs) = qsrc + - *(ckt->CKTstate0 + here->BSIM4qbs); if (here->BSIM4rgateMod == 3) *(ckt->CKTstate0 + here->BSIM4qgmid) = qgmid; @@ -3942,16 +4011,16 @@ line900: - (here->BSIM4gbds + here->BSIM4ggidld) * vds - (here->BSIM4gbgs + here->BSIM4ggidlg) * vgs - (here->BSIM4gbbs + here->BSIM4ggidlb) * vbs); - ceqbs = 0.0; + ceqbs = model->BSIM4type * (here->BSIM4Igisl + here->BSIM4ggisls * vds + - here->BSIM4ggislg * vgd - here->BSIM4ggislb * vbd); - gbbdp = -(here->BSIM4gbds + here->BSIM4ggidld); - gbbsp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs - - here->BSIM4ggidls; - - gbdpg = here->BSIM4gbgs + here->BSIM4ggidlg; - gbdpdp = here->BSIM4gbds + here->BSIM4ggidld; - gbdpb = here->BSIM4gbbs + here->BSIM4ggidlb; - gbdpsp = -(gbdpg + gbdpdp + gbdpb) + here->BSIM4ggidls; + gbbdp = -(here->BSIM4gbds); + gbbsp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs; + + gbdpg = here->BSIM4gbgs; + gbdpdp = here->BSIM4gbds; + gbdpb = here->BSIM4gbbs; + gbdpsp = -(gbdpg + gbdpdp + gbdpb); gbspg = 0.0; gbspdp = 0.0; @@ -4029,25 +4098,25 @@ line900: ceqdrn = -model->BSIM4type * (cdrain + here->BSIM4gds * vds + Gm * vgd + Gmbs * vbd); - ceqbs = model->BSIM4type * (here->BSIM4csub + here->BSIM4Igidl - + (here->BSIM4gbds + here->BSIM4ggidld) * vds - - (here->BSIM4gbgs + here->BSIM4ggidlg) * vgd - - (here->BSIM4gbbs + here->BSIM4ggidlb) * vbd); - ceqbd = 0.0; + ceqbs = model->BSIM4type * (here->BSIM4csub + here->BSIM4Igisl + + (here->BSIM4gbds + here->BSIM4ggisls) * vds + - (here->BSIM4gbgs + here->BSIM4ggislg) * vgd + - (here->BSIM4gbbs + here->BSIM4ggislb) * vbd); + ceqbd = model->BSIM4type * (here->BSIM4Igidl - here->BSIM4ggidld * vds + - here->BSIM4ggidlg * vgs - here->BSIM4ggidlb * vbs); - gbbsp = -(here->BSIM4gbds + here->BSIM4ggidld); - gbbdp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs - - here->BSIM4ggidls; + gbbsp = -(here->BSIM4gbds); + gbbdp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs; gbdpg = 0.0; gbdpsp = 0.0; gbdpb = 0.0; gbdpdp = 0.0; - gbspg = here->BSIM4gbgs + here->BSIM4ggidlg; - gbspsp = here->BSIM4gbds + here->BSIM4ggidld; - gbspb = here->BSIM4gbbs + here->BSIM4ggidlb; - gbspdp = -(gbspg + gbspsp + gbspb) + here->BSIM4ggidls; + gbspg = here->BSIM4gbgs; + gbspsp = here->BSIM4gbds; + gbspb = here->BSIM4gbbs; + gbspdp = -(gbspg + gbspsp + gbspb); if (model->BSIM4igcMod) { gIstotg = here->BSIM4gIgsg + here->BSIM4gIgcdg; @@ -4302,16 +4371,43 @@ line900: - gstots + FwdSum + gcssb + gbspsp + sxpart * ggts - gIstots); (*(here->BSIM4SPsPtr) -= gspr + gstot); (*(here->BSIM4SPbpPtr) -= gjbs + gstotb + Gmbs - gcsbb - gbspb - sxpart * ggtb - - T1 * dsxpart_dVb) + gIstotb; + - T1 * dsxpart_dVb + gIstotb); (*(here->BSIM4SspPtr) -= gspr - gstots); (*(here->BSIM4SsPtr) += gspr + gstot); (*(here->BSIM4BPdpPtr) += gcbdb - gjbd + gbbdp - gIbtotd); - (*(here->BSIM4BPgpPtr) += gcbgb - here->BSIM4gbgs - here->BSIM4ggidlg - gIbtotg); + (*(here->BSIM4BPgpPtr) += gcbgb - here->BSIM4gbgs - gIbtotg); (*(here->BSIM4BPspPtr) += gcbsb - gjbs + gbbsp - gIbtots); (*(here->BSIM4BPbpPtr) += gjbd + gjbs + gcbbb - here->BSIM4gbbs - - here->BSIM4ggidlb - gIbtotb); + - gIbtotb); + + ggidld = here->BSIM4ggidld; + ggidlg = here->BSIM4ggidlg; + ggidlb = here->BSIM4ggidlb; + ggislg = here->BSIM4ggislg; + ggisls = here->BSIM4ggisls; + ggislb = here->BSIM4ggislb; + + /* stamp gidl */ + (*(here->BSIM4DPdpPtr) += ggidld); + (*(here->BSIM4DPgpPtr) += ggidlg); + (*(here->BSIM4DPspPtr) -= (ggidlg + ggidld + ggidlb)); + (*(here->BSIM4DPbpPtr) += ggidlb); + (*(here->BSIM4BPdpPtr) -= ggidld); + (*(here->BSIM4BPgpPtr) -= ggidlg); + (*(here->BSIM4BPspPtr) += (ggidlg + ggidld + ggidlb)); + (*(here->BSIM4BPbpPtr) -= ggidlb); + /* stamp gisl */ + (*(here->BSIM4SPdpPtr) -= (ggisls + ggislg + ggislb)); + (*(here->BSIM4SPgpPtr) += ggislg); + (*(here->BSIM4SPspPtr) += ggisls); + (*(here->BSIM4SPbpPtr) += ggislb); + (*(here->BSIM4BPdpPtr) += (ggislg + ggisls + ggislb)); + (*(here->BSIM4BPgpPtr) -= ggislg); + (*(here->BSIM4BPspPtr) -= ggisls); + (*(here->BSIM4BPbpPtr) -= ggislb); + if (here->BSIM4rbodyMod) { (*(here->BSIM4DPdbPtr) += gcdbdb - here->BSIM4gbd); @@ -4362,3 +4458,35 @@ line1000: ; return(OK); } + +/* function to compute poly depletion effect */ +int BSIM4polyDepletion( + double phi, + double ngate, + double coxe, + double Vgs, + double *Vgs_eff, + double *dVgs_eff_dVg) +{ + double T1, T2, T3, T4, T5, T6, T7, T8; + + /* Poly Gate Si Depletion Effect */ + if ((ngate > 1.0e18) && + (ngate < 1.0e25) && (Vgs > phi)) { + T1 = 1.0e6 * CHARGE * EPSSI * ngate / (coxe * coxe); + T8 = Vgs - phi; + T4 = sqrt(1.0 + 2.0 * T8 / T1); + T2 = 2.0 * T8 / (T4 + 1.0); + T3 = 0.5 * T2 * T2 / T1; /* T3 = Vpoly */ + T7 = 1.12 - T3 - 0.05; + T6 = sqrt(T7 * T7 + 0.224); + T5 = 1.12 - 0.5 * (T7 + T6); + *Vgs_eff = Vgs - T5; + *dVgs_eff_dVg = 1.0 - (0.5 - 0.5 / T4) * (1.0 + T7 / T6); + } + else { + *Vgs_eff = Vgs; + *dVgs_eff_dVg = 1.0; + } + return(0); +} diff --git a/src/spicelib/devices/bsim4/b4mask.c b/src/spicelib/devices/bsim4/b4mask.c index 909e5b2e8..7ee477130 100644 --- a/src/spicelib/devices/bsim4/b4mask.c +++ b/src/spicelib/devices/bsim4/b4mask.c @@ -1,12 +1,14 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4mask.c of BSIM4.0.0. - * Authors: Weidong Liu, Xiaodong Jin, Kanyu M. Cao, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4mask.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. **********/ + #include "ngspice.h" #include #include "ifsim.h" @@ -517,6 +519,12 @@ IFvalue *value; case BSIM4_MOD_DLC: value->rValue = model->BSIM4dlc; return(OK); + case BSIM4_MOD_XW: + value->rValue = model->BSIM4xw; + return(OK); + case BSIM4_MOD_XL: + value->rValue = model->BSIM4xl; + return(OK); case BSIM4_MOD_DLCIG: value->rValue = model->BSIM4dlcig; return(OK); diff --git a/src/spicelib/devices/bsim4/b4mdel.c b/src/spicelib/devices/bsim4/b4mdel.c index cf1b072d9..c472a97be 100644 --- a/src/spicelib/devices/bsim4/b4mdel.c +++ b/src/spicelib/devices/bsim4/b4mdel.c @@ -1,9 +1,10 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4mdel.c of BSIM4.0.0. - * Authors: Weidong Liu, Kanyu M. Cao, Xiaodong Jin, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4mdel.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. **********/ @@ -12,6 +13,7 @@ #include "bsim4def.h" #include "sperror.h" + int BSIM4mDelete(inModel,modname,kill) GENmodel **inModel; diff --git a/src/spicelib/devices/bsim4/b4mpar.c b/src/spicelib/devices/bsim4/b4mpar.c index f75555628..a4606612e 100644 --- a/src/spicelib/devices/bsim4/b4mpar.c +++ b/src/spicelib/devices/bsim4/b4mpar.c @@ -1,10 +1,13 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4mpar.c of BSIM4.0.0. - * Authors: Weidong Liu, Kanyu M. Cao, Xiaodong Jin, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4mpar.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. + * + * Modified by Xuemei Xi 04/06/2001 **********/ #include "ngspice.h" @@ -683,6 +686,14 @@ GENmodel *inMod; mod->BSIM4dlc = value->rValue; mod->BSIM4dlcGiven = TRUE; break; + case BSIM4_MOD_XW : + mod->BSIM4xw = value->rValue; + mod->BSIM4xwGiven = TRUE; + break; + case BSIM4_MOD_XL : + mod->BSIM4xl = value->rValue; + mod->BSIM4xlGiven = TRUE; + break; case BSIM4_MOD_DLCIG : mod->BSIM4dlcig = value->rValue; mod->BSIM4dlcigGiven = TRUE; diff --git a/src/spicelib/devices/bsim4/b4noi.c b/src/spicelib/devices/bsim4/b4noi.c index e7e8b5159..434d01713 100644 --- a/src/spicelib/devices/bsim4/b4noi.c +++ b/src/spicelib/devices/bsim4/b4noi.c @@ -1,10 +1,13 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4noi.c of BSIM4.0.0. - * Authors: Weidong Liu, Xiaodong Jin, Kanyu M. Cao, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4noi.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. + + * Modified by Xuemei Xi, 10/05/2001. **********/ #include "ngspice.h" @@ -12,7 +15,6 @@ #include #include "bsim4def.h" #include "cktdefs.h" -#include "fteconst.h" #include "iferrmsg.h" #include "noisedef.h" #include "const.h" @@ -40,9 +42,12 @@ double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, Ssi; pParam = here->pParam; cd = fabs(here->BSIM4cd); esat = 2.0 * pParam->BSIM4vsattemp / here->BSIM4ueff; - T0 = ((((Vds - here->BSIM4Vdseff) / pParam->BSIM4litl) - + model->BSIM4em) / esat); - DelClm = pParam->BSIM4litl * log (MAX(T0, N_MINLOG)); + if(model->BSIM4em<=0.0) DelClm = 0.0; /* flicker noise modified -JX */ + else { + T0 = ((((Vds - here->BSIM4Vdseff) / pParam->BSIM4litl) + + model->BSIM4em) / esat); + DelClm = pParam->BSIM4litl * log (MAX(T0, N_MINLOG)); + } EffFreq = pow(freq, model->BSIM4ef); T1 = CHARGE * CHARGE * CONSTboltz * cd * temp * here->BSIM4ueff; T2 = 1.0e10 * EffFreq * here->BSIM4Abulk * model->BSIM4coxe @@ -72,11 +77,11 @@ BSIM4noise (mode, operation, inModel, ckt, data, OnDens) int mode, operation; GENmodel *inModel; CKTcircuit *ckt; -register Ndata *data; +Ndata *data; double *OnDens; { -register BSIM4model *model = (BSIM4model *)inModel; -register BSIM4instance *here; +BSIM4model *model = (BSIM4model *)inModel; +BSIM4instance *here; struct bsim4SizeDependParam *pParam; char name[N_MXVLNTH]; double tempOnoise; diff --git a/src/spicelib/devices/bsim4/b4par.c b/src/spicelib/devices/bsim4/b4par.c index 486a5c2b8..aa4b450e9 100644 --- a/src/spicelib/devices/bsim4/b4par.c +++ b/src/spicelib/devices/bsim4/b4par.c @@ -1,9 +1,10 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4par.c of BSIM4.0.0. - * Authors: Weidong Liu, Kanyu M. Cao, Xiaodong Jin, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4par.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. **********/ @@ -13,7 +14,6 @@ #include "bsim4def.h" #include "sperror.h" - int BSIM4param(param,value,inst,select) int param; diff --git a/src/spicelib/devices/bsim4/b4pzld.c b/src/spicelib/devices/bsim4/b4pzld.c index 3b6495a19..7d07f2da1 100644 --- a/src/spicelib/devices/bsim4/b4pzld.c +++ b/src/spicelib/devices/bsim4/b4pzld.c @@ -1,10 +1,13 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4pzld.c of BSIM4.0.0. - * Authors: Weidong Liu, Kanyu M. Cao, Xiaodong Jin, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4pzld.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. + + * Modified by Xuemei Xi, 10/05/2001. **********/ #include "ngspice.h" @@ -14,15 +17,14 @@ #include "sperror.h" #include "bsim4def.h" - int BSIM4pzLoad(inModel,ckt,s) GENmodel *inModel; -register CKTcircuit *ckt; -register SPcomplex *s; +CKTcircuit *ckt; +SPcomplex *s; { -register BSIM4model *model = (BSIM4model*)inModel; -register BSIM4instance *here; +BSIM4model *model = (BSIM4model*)inModel; +BSIM4instance *here; double gjbd, gjbs, geltd, gcrg, gcrgg, gcrgd, gcrgs, gcrgb; double xcggb, xcgdb, xcgsb, xcgbb, xcbgb, xcbdb, xcbsb, xcbbb; @@ -45,11 +47,13 @@ double dsxpart_dVd, dsxpart_dVg, dsxpart_dVb, dsxpart_dVs; double T0, T1, CoxWL, qcheq, Cdg, Cdd, Cds, Cdb, Csg, Csd, Css, Csb; double ScalingFactor = 1.0e-9; struct bsim4SizeDependParam *pParam; +double ggidld, ggidlg, ggidlb,ggisld, ggislg, ggislb, ggisls; + for (; model != NULL; model = model->BSIM4nextModel) { for (here = model->BSIM4instances; here!= NULL; here = here->BSIM4nextInstance) - { if (here->BSIM4owner != ARCHme) continue; + { if (here->BSIM4owner != ARCHme) continue; pParam = here->pParam; capbd = here->BSIM4capbd; capbs = here->BSIM4capbs; @@ -63,13 +67,12 @@ struct bsim4SizeDependParam *pParam; FwdSum = Gm + Gmbs; RevSum = 0.0; - gbbdp = -(here->BSIM4gbds + here->BSIM4ggidld); - gbbsp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs - - here->BSIM4ggidls; - gbdpg = here->BSIM4gbgs + here->BSIM4ggidlg; - gbdpdp = here->BSIM4gbds + here->BSIM4ggidld; - gbdpb = here->BSIM4gbbs + here->BSIM4ggidlb; - gbdpsp = -(gbdpg + gbdpdp + gbdpb) + here->BSIM4ggidls; + gbbdp = -(here->BSIM4gbds); + gbbsp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs; + gbdpg = here->BSIM4gbgs; + gbdpdp = here->BSIM4gbds; + gbdpb = here->BSIM4gbbs; + gbdpsp = -(gbdpg + gbdpdp + gbdpb); gbspdp = 0.0; gbspg = 0.0; @@ -262,19 +265,18 @@ struct bsim4SizeDependParam *pParam; FwdSum = 0.0; RevSum = -(Gm + Gmbs); - gbbsp = -(here->BSIM4gbds + here->BSIM4ggidld); - gbbdp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs - - here->BSIM4ggidls; + gbbsp = -(here->BSIM4gbds); + gbbdp = here->BSIM4gbds + here->BSIM4gbgs + here->BSIM4gbbs; gbdpg = 0.0; gbdpsp = 0.0; gbdpb = 0.0; gbdpdp = 0.0; - gbspg = here->BSIM4gbgs + here->BSIM4ggidlg; - gbspsp = here->BSIM4gbds + here->BSIM4ggidld; - gbspb = here->BSIM4gbbs + here->BSIM4ggidlb; - gbspdp = -(gbspg + gbspsp + gbspb) + here->BSIM4ggidls; + gbspg = here->BSIM4gbgs; + gbspsp = here->BSIM4gbds; + gbspb = here->BSIM4gbbs; + gbspdp = -(gbspg + gbspsp + gbspb); if (model->BSIM4igcMod) { gIstotg = here->BSIM4gIgsg + here->BSIM4gIgcdg; @@ -650,14 +652,39 @@ struct bsim4SizeDependParam *pParam; *(here->BSIM4BPdpPtr) -= gjbd - gbbdp + gIbtotd; *(here->BSIM4BPgpPtr ) += xcbgb * s->real; *(here->BSIM4BPgpPtr +1) += xcbgb * s->imag; - *(here->BSIM4BPgpPtr) -= here->BSIM4gbgs + here->BSIM4ggidlg + gIbtotg; + *(here->BSIM4BPgpPtr) -= here->BSIM4gbgs + gIbtotg; *(here->BSIM4BPspPtr ) += xcbsb * s->real; *(here->BSIM4BPspPtr +1) += xcbsb * s->imag; *(here->BSIM4BPspPtr) -= gjbs - gbbsp + gIbtots; *(here->BSIM4BPbpPtr ) += xcbbb * s->real; *(here->BSIM4BPbpPtr +1) += xcbbb * s->imag; *(here->BSIM4BPbpPtr) += gjbd + gjbs - here->BSIM4gbbs - - gIbtotb - here->BSIM4ggidlb; + - gIbtotb; + ggidld = here->BSIM4ggidld; + ggidlg = here->BSIM4ggidlg; + ggidlb = here->BSIM4ggidlb; + ggislg = here->BSIM4ggislg; + ggisls = here->BSIM4ggisls; + ggislb = here->BSIM4ggislb; + + /* stamp gidl */ + (*(here->BSIM4DPdpPtr) += ggidld); + (*(here->BSIM4DPgpPtr) += ggidlg); + (*(here->BSIM4DPspPtr) -= (ggidlg + ggidld) + ggidlb); + (*(here->BSIM4DPbpPtr) += ggidlb); + (*(here->BSIM4BPdpPtr) -= ggidld); + (*(here->BSIM4BPgpPtr) -= ggidlg); + (*(here->BSIM4BPspPtr) += (ggidlg + ggidld) + ggidlb); + (*(here->BSIM4BPbpPtr) -= ggidlb); + /* stamp gisl */ + (*(here->BSIM4SPdpPtr) -= (ggisls + ggislg) + ggislb); + (*(here->BSIM4SPgpPtr) += ggislg); + (*(here->BSIM4SPspPtr) += ggisls); + (*(here->BSIM4SPbpPtr) += ggislb); + (*(here->BSIM4BPdpPtr) += (ggislg + ggisls) + ggislb); + (*(here->BSIM4BPgpPtr) -= ggislg); + (*(here->BSIM4BPspPtr) -= ggisls); + (*(here->BSIM4BPbpPtr) -= ggislb); if (here->BSIM4rbodyMod) { (*(here->BSIM4DPdbPtr ) += xcdbdb * s->real); diff --git a/src/spicelib/devices/bsim4/b4set.c b/src/spicelib/devices/bsim4/b4set.c index 3141dc46c..e15e88214 100644 --- a/src/spicelib/devices/bsim4/b4set.c +++ b/src/spicelib/devices/bsim4/b4set.c @@ -1,15 +1,20 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4set.c of BSIM4.0.0. - * Authors: Weidong Liu, Xiaodong Jin, Kanyu M. Cao, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4set.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. + * Modified by Xuemei Xi, 04/06/2001. + * Modified by Xuemei Xi, 10/05/2001. **********/ #include "ngspice.h" #include #include +#include "jobdefs.h" /* Needed because the model searches for noise Analysis */ +#include "ftedefs.h" /* " " */ #include "smpdefs.h" #include "cktdefs.h" #include "bsim4def.h" @@ -27,17 +32,27 @@ int BSIM4setup(matrix,inModel,ckt,states) -register SMPmatrix *matrix; -register GENmodel *inModel; -register CKTcircuit *ckt; +SMPmatrix *matrix; +GENmodel *inModel; +CKTcircuit *ckt; int *states; { -register BSIM4model *model = (BSIM4model*)inModel; -register BSIM4instance *here; +BSIM4model *model = (BSIM4model*)inModel; +BSIM4instance *here; int error; CKTnode *tmp; - double tmp1, tmp2; +int noiseAnalGiven = 0, createNode; /* Criteria for new node creation */ +double Rtot, DMCGeff, DMCIeff, DMDGeff; +JOB *job; + + /* Search for a noise analysis request */ + for (job = ((TSKtask *)(ft_curckt->ci_curTask))->jobs;job;job = job->JOBnextJob) { + if(strcmp(job->JOBname,"Noise Analysis")==0) { + noiseAnalGiven = 1; + break; + } + } /* loop through all the BSIM4 device models */ for( ; model != NULL; model = model->BSIM4nextModel ) @@ -145,7 +160,7 @@ double tmp1, tmp2; } if (!model->BSIM4versionGiven) - model->BSIM4version = "4.0.0"; + model->BSIM4version = "4.2.1"; if (!model->BSIM4toxrefGiven) model->BSIM4toxref = 30.0e-10; if (!model->BSIM4toxeGiven) @@ -1214,6 +1229,10 @@ double tmp1, tmp2; model->BSIM4dwc = model->BSIM4Wint; if (!model->BSIM4dlcGiven) model->BSIM4dlc = model->BSIM4Lint; + if (!model->BSIM4xlGiven) + model->BSIM4xl = 0.0; + if (!model->BSIM4xwGiven) + model->BSIM4xw = 0.0; if (!model->BSIM4dlcigGiven) model->BSIM4dlcig = model->BSIM4Lint; if (!model->BSIM4dwjGiven) @@ -1306,6 +1325,9 @@ double tmp1, tmp2; model->BSIM4af = 1.0; if (!model->BSIM4kfGiven) model->BSIM4kf = 0.0; + DMCGeff = model->BSIM4dmcg - model->BSIM4dmcgt; + DMCIeff = model->BSIM4dmci; + DMDGeff = model->BSIM4dmdg - model->BSIM4dmcgt; /* * End processing models and begin to loop @@ -1313,14 +1335,14 @@ double tmp1, tmp2; */ for (here = model->BSIM4instances; here != NULL ; - here=here->BSIM4nextInstance) + here=here->BSIM4nextInstance) { - if (here->BSIM4owner == ARCHme) { + if (here->BSIM4owner == ARCHme) { /* allocate a chunk of the state vector */ here->BSIM4states = *states; *states += BSIM4numStates; } - /* perform the parameter defaulting */ + /* perform the parameter defaulting */ if (!here->BSIM4lGiven) here->BSIM4l = 5.0e-6; if (!here->BSIM4wGiven) @@ -1401,8 +1423,29 @@ double tmp1, tmp2; } /* process drain series resistance */ - if (((here->BSIM4rgeoMod != 0) || (model->BSIM4rdsMod != 0) - || (model->BSIM4tnoiMod != 0)) && (here->BSIM4dNodePrime == 0)) + createNode = 0; + if ( (model->BSIM4rdsMod != 0) + || (model->BSIM4tnoiMod != 0 && noiseAnalGiven)) + { + createNode = 1; + } else if (model->BSIM4sheetResistance > 0) + { + if (here->BSIM4drainSquaresGiven + && here->BSIM4drainSquares > 0) + { + createNode = 1; + } else if (!here->BSIM4drainSquaresGiven + && (here->BSIM4rgeoMod != 0)) + { + BSIM4RdseffGeo(here->BSIM4nf, here->BSIM4geoMod, + here->BSIM4rgeoMod, here->BSIM4min, + here->BSIM4w, model->BSIM4sheetResistance, + DMCGeff, DMCIeff, DMDGeff, 0, &Rtot); + if(Rtot > 0) + createNode = 1; + } + } + if ( createNode != 0 && (here->BSIM4dNodePrime == 0)) { error = CKTmkVolt(ckt,&tmp,here->BSIM4name,"drain"); if(error) return(error); here->BSIM4dNodePrime = tmp->number; @@ -1410,16 +1453,37 @@ double tmp1, tmp2; else { here->BSIM4dNodePrime = here->BSIM4dNode; } + /* process source series resistance */ - if (((here->BSIM4rgeoMod != 0) || (model->BSIM4rdsMod != 0) - || (model->BSIM4tnoiMod != 0)) && (here->BSIM4sNodePrime == 0)) + createNode = 0; + if ( (model->BSIM4rdsMod != 0) + || (model->BSIM4tnoiMod != 0 && noiseAnalGiven)) + { + createNode = 1; + } else if (model->BSIM4sheetResistance > 0) + { + if (here->BSIM4sourceSquaresGiven + && here->BSIM4sourceSquares > 0) + { + createNode = 1; + } else if (!here->BSIM4sourceSquaresGiven + && (here->BSIM4rgeoMod != 0)) + { + BSIM4RdseffGeo(here->BSIM4nf, here->BSIM4geoMod, + here->BSIM4rgeoMod, here->BSIM4min, + here->BSIM4w, model->BSIM4sheetResistance, + DMCGeff, DMCIeff, DMDGeff, 1, &Rtot); + if(Rtot > 0) + createNode = 1; + } + } + if ( createNode != 0 && here->BSIM4sNodePrime == 0) { error = CKTmkVolt(ckt,&tmp,here->BSIM4name,"source"); if(error) return(error); here->BSIM4sNodePrime = tmp->number; } else here->BSIM4sNodePrime = here->BSIM4sNode; - if ((here->BSIM4rgateMod > 0) && (here->BSIM4gNodePrime == 0)) { error = CKTmkVolt(ckt,&tmp,here->BSIM4name,"gate"); @@ -1587,7 +1651,7 @@ BSIM4unsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM + BSIM4model *model; BSIM4instance *here; @@ -1611,6 +1675,5 @@ BSIM4unsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/bsim4/b4temp.c b/src/spicelib/devices/bsim4/b4temp.c index 2c6f270ad..c84334d3f 100644 --- a/src/spicelib/devices/bsim4/b4temp.c +++ b/src/spicelib/devices/bsim4/b4temp.c @@ -1,10 +1,13 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4temp.c of BSIM4.0.0. - * Authors: Weidong Liu, Xiaodong Jin, Kanyu M. Cao, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4temp.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. + * Modified by Xuemei Xi, 04/06/2001. + * Modified by Xuemei Xi, 10/05/2001. **********/ #include "ngspice.h" @@ -47,11 +50,11 @@ BSIM4temp(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -register BSIM4model *model = (BSIM4model*) inModel; -register BSIM4instance *here; +BSIM4model *model = (BSIM4model*) inModel; +BSIM4instance *here; struct bsim4SizeDependParam *pSizeDependParamKnot, *pLastKnot, *pParam; double tmp, tmp1, tmp2, tmp3, Eg, Eg0, ni; -double T0, T1, T2, T3, T4, T5, T8, T9, Ldrn, Wdrn; +double T0, T1, T2, T3, T4, T5, T8, T9, Lnew, Wnew; double delTemp, Temp, TRatio, Inv_L, Inv_W, Inv_LW, Dw, Dl, Vtm0, Tnom; double dumPs, dumPd, dumAs, dumAd, PowWeffWr; double DMCGeff, DMCIeff, DMDGeff; @@ -184,46 +187,46 @@ int Size_Not_Found; delTemp = ckt->CKTtemp - model->BSIM4tnom; T0 = model->BSIM4tcj * delTemp; if (T0 >= -1.0) - { model->BSIM4SunitAreaJctCap *= 1.0 + T0; - model->BSIM4DunitAreaJctCap *= 1.0 + T0; + { model->BSIM4SunitAreaTempJctCap = model->BSIM4SunitAreaJctCap *(1.0 + T0); /*bug_fix -JX */ + model->BSIM4DunitAreaTempJctCap = model->BSIM4DunitAreaJctCap *(1.0 + T0); } else { if (model->BSIM4SunitAreaJctCap > 0.0) - { model->BSIM4SunitAreaJctCap = 0.0; + { model->BSIM4SunitAreaTempJctCap = 0.0; fprintf(stderr, "Temperature effect has caused cjs to be negative. Cjs is clamped to zero.\n"); } if (model->BSIM4DunitAreaJctCap > 0.0) - { model->BSIM4DunitAreaJctCap = 0.0; + { model->BSIM4DunitAreaTempJctCap = 0.0; fprintf(stderr, "Temperature effect has caused cjd to be negative. Cjd is clamped to zero.\n"); } } T0 = model->BSIM4tcjsw * delTemp; if (T0 >= -1.0) - { model->BSIM4SunitLengthSidewallJctCap *= 1.0 + T0; - model->BSIM4DunitLengthSidewallJctCap *= 1.0 + T0; + { model->BSIM4SunitLengthSidewallTempJctCap = model->BSIM4SunitLengthSidewallJctCap *(1.0 + T0); + model->BSIM4DunitLengthSidewallTempJctCap = model->BSIM4DunitLengthSidewallJctCap *(1.0 + T0); } else { if (model->BSIM4SunitLengthSidewallJctCap > 0.0) - { model->BSIM4SunitLengthSidewallJctCap = 0.0; + { model->BSIM4SunitLengthSidewallTempJctCap = 0.0; fprintf(stderr, "Temperature effect has caused cjsws to be negative. Cjsws is clamped to zero.\n"); } if (model->BSIM4DunitLengthSidewallJctCap > 0.0) - { model->BSIM4DunitLengthSidewallJctCap = 0.0; + { model->BSIM4DunitLengthSidewallTempJctCap = 0.0; fprintf(stderr, "Temperature effect has caused cjswd to be negative. Cjswd is clamped to zero.\n"); } } T0 = model->BSIM4tcjswg * delTemp; if (T0 >= -1.0) - { model->BSIM4SunitLengthGateSidewallJctCap *= 1.0 + T0; - model->BSIM4DunitLengthGateSidewallJctCap *= 1.0 + T0; + { model->BSIM4SunitLengthGateSidewallTempJctCap = model->BSIM4SunitLengthGateSidewallJctCap *(1.0 + T0); + model->BSIM4DunitLengthGateSidewallTempJctCap = model->BSIM4DunitLengthGateSidewallJctCap *(1.0 + T0); } else { if (model->BSIM4SunitLengthGateSidewallJctCap > 0.0) - { model->BSIM4SunitLengthGateSidewallJctCap = 0.0; + { model->BSIM4SunitLengthGateSidewallTempJctCap = 0.0; fprintf(stderr, "Temperature effect has caused cjswgs to be negative. Cjswgs is clamped to zero.\n"); } if (model->BSIM4DunitLengthGateSidewallJctCap > 0.0) - { model->BSIM4DunitLengthGateSidewallJctCap = 0.0; + { model->BSIM4DunitLengthGateSidewallTempJctCap = 0.0; fprintf(stderr, "Temperature effect has caused cjswgd to be negative. Cjswgd is clamped to zero.\n"); } } @@ -326,6 +329,7 @@ int Size_Not_Found; && (here->BSIM4nf == pSizeDependParamKnot->NFinger)) { Size_Not_Found = 0; here->pParam = pSizeDependParamKnot; + pParam = here->pParam; /*bug-fix */ } else { pLastKnot = pSizeDependParamKnot; @@ -346,11 +350,11 @@ int Size_Not_Found; pParam->Length = here->BSIM4l; pParam->Width = here->BSIM4w; pParam->NFinger = here->BSIM4nf; - Ldrn = here->BSIM4l; - Wdrn = here->BSIM4w / here->BSIM4nf; + Lnew = here->BSIM4l + model->BSIM4xl ; + Wnew = here->BSIM4w / here->BSIM4nf + model->BSIM4xw; - T0 = pow(Ldrn, model->BSIM4Lln); - T1 = pow(Wdrn, model->BSIM4Lwn); + T0 = pow(Lnew, model->BSIM4Lln); + T1 = pow(Wnew, model->BSIM4Lwn); tmp1 = model->BSIM4Ll / T0 + model->BSIM4Lw / T1 + model->BSIM4Lwl / (T0 * T1); pParam->BSIM4dl = model->BSIM4Lint + tmp1; @@ -359,17 +363,17 @@ int Size_Not_Found; pParam->BSIM4dlc = model->BSIM4dlc + tmp2; pParam->BSIM4dlcig = model->BSIM4dlcig + tmp2; - T2 = pow(Ldrn, model->BSIM4Wln); - T3 = pow(Wdrn, model->BSIM4Wwn); + T2 = pow(Lnew, model->BSIM4Wln); + T3 = pow(Wnew, model->BSIM4Wwn); tmp1 = model->BSIM4Wl / T2 + model->BSIM4Ww / T3 + model->BSIM4Wwl / (T2 * T3); pParam->BSIM4dw = model->BSIM4Wint + tmp1; tmp2 = model->BSIM4Wlc / T2 + model->BSIM4Wwc / T3 - + model->BSIM4Wwlc / (T2 * T3); + + model->BSIM4Wwlc / (T2 * T3); pParam->BSIM4dwc = model->BSIM4dwc + tmp2; pParam->BSIM4dwj = model->BSIM4dwj + tmp2; - pParam->BSIM4leff = here->BSIM4l - 2.0 * pParam->BSIM4dl; + pParam->BSIM4leff = Lnew - 2.0 * pParam->BSIM4dl; if (pParam->BSIM4leff <= 0.0) { IFuid namarray[2]; namarray[0] = model->BSIM4modName; @@ -380,8 +384,7 @@ int Size_Not_Found; return(E_BADPARM); } - pParam->BSIM4weff = here->BSIM4w / here->BSIM4nf - - 2.0 * pParam->BSIM4dw; + pParam->BSIM4weff = Wnew - 2.0 * pParam->BSIM4dw; if (pParam->BSIM4weff <= 0.0) { IFuid namarray[2]; namarray[0] = model->BSIM4modName; @@ -392,7 +395,7 @@ int Size_Not_Found; return(E_BADPARM); } - pParam->BSIM4leffCV = here->BSIM4l - 2.0 * pParam->BSIM4dlc; + pParam->BSIM4leffCV = Lnew - 2.0 * pParam->BSIM4dlc; if (pParam->BSIM4leffCV <= 0.0) { IFuid namarray[2]; namarray[0] = model->BSIM4modName; @@ -403,8 +406,7 @@ int Size_Not_Found; return(E_BADPARM); } - pParam->BSIM4weffCV = here->BSIM4w / here->BSIM4nf - - 2.0 * pParam->BSIM4dwc; + pParam->BSIM4weffCV = Wnew - 2.0 * pParam->BSIM4dwc; if (pParam->BSIM4weffCV <= 0.0) { IFuid namarray[2]; namarray[0] = model->BSIM4modName; @@ -415,8 +417,7 @@ int Size_Not_Found; return(E_BADPARM); } - pParam->BSIM4weffCJ = here->BSIM4w / here->BSIM4nf - - 2.0 * pParam->BSIM4dwj; + pParam->BSIM4weffCJ = Wnew - 2.0 * pParam->BSIM4dwj; if (pParam->BSIM4weffCJ <= 0.0) { IFuid namarray[2]; namarray[0] = model->BSIM4modName; @@ -1248,7 +1249,7 @@ int Size_Not_Found; here->BSIM4grgeltd = model->BSIM4rshg * (model->BSIM4xgw + pParam->BSIM4weffCJ / 3.0 / model->BSIM4ngcon) / (model->BSIM4ngcon * here->BSIM4nf * - (here->BSIM4l - model->BSIM4xgl)); + (Lnew - model->BSIM4xgl)); if (here->BSIM4grgeltd > 0.0) here->BSIM4grgeltd = 1.0 / here->BSIM4grgeltd; else @@ -1300,47 +1301,69 @@ int Size_Not_Found; &dumPs, &dumPd, &dumAs, &(here->BSIM4Adeff)); /* Processing S/D resistance and conductance below */ - if (here->BSIM4rgeoMod == 0) - here->BSIM4sourceConductance = 0.0; - else if (here->BSIM4sourceSquaresGiven) - here->BSIM4sourceConductance = model->BSIM4sheetResistance + if(here->BSIM4sNodePrime != here->BSIM4sNode) + { + here->BSIM4sourceConductance = 0.0; + if(here->BSIM4sourceSquaresGiven) + { + here->BSIM4sourceConductance = model->BSIM4sheetResistance * here->BSIM4sourceSquares; - else - BSIM4RdseffGeo(here->BSIM4nf, here->BSIM4geoMod, here->BSIM4rgeoMod, here->BSIM4min, - pParam->BSIM4weffCJ, model->BSIM4sheetResistance, - DMCGeff, DMCIeff, DMDGeff, 1, &(here->BSIM4sourceConductance)); + } else if (here->BSIM4rgeoMod > 0) + { + BSIM4RdseffGeo(here->BSIM4nf, here->BSIM4geoMod, + here->BSIM4rgeoMod, here->BSIM4min, + pParam->BSIM4weffCJ, model->BSIM4sheetResistance, + DMCGeff, DMCIeff, DMDGeff, 1, &(here->BSIM4sourceConductance)); + } else + { + here->BSIM4sourceConductance = 0.0; + } - if (here->BSIM4rgeoMod == 0) - here->BSIM4drainConductance = 0.0; - else if (here->BSIM4drainSquaresGiven) - here->BSIM4drainConductance = model->BSIM4sheetResistance - * here->BSIM4drainSquares; - else - BSIM4RdseffGeo(here->BSIM4nf, here->BSIM4geoMod, here->BSIM4rgeoMod, here->BSIM4min, - pParam->BSIM4weffCJ, model->BSIM4sheetResistance, - DMCGeff, DMCIeff, DMDGeff, 0, &(here->BSIM4drainConductance)); - - if (here->BSIM4drainConductance > 0.0) - here->BSIM4drainConductance = 1.0 / here->BSIM4drainConductance; - else - here->BSIM4drainConductance = 0.0; - - if (here->BSIM4sourceConductance > 0.0) - here->BSIM4sourceConductance = 1.0 / here->BSIM4sourceConductance; - else + if (here->BSIM4sourceConductance > 0.0) + here->BSIM4sourceConductance = 1.0 + / here->BSIM4sourceConductance; + else + { + here->BSIM4sourceConductance = 1.0e3; /* mho */ + printf ("Warning: Source conductance reset to 1.0e3 mho.\n"); + } + } else + { here->BSIM4sourceConductance = 0.0; + } + if(here->BSIM4dNodePrime != here->BSIM4dNode) + { + here->BSIM4drainConductance = 0.0; + if(here->BSIM4drainSquaresGiven) + { + here->BSIM4drainConductance = model->BSIM4sheetResistance + * here->BSIM4drainSquares; + } else if (here->BSIM4rgeoMod > 0) + { + BSIM4RdseffGeo(here->BSIM4nf, here->BSIM4geoMod, + here->BSIM4rgeoMod, here->BSIM4min, + pParam->BSIM4weffCJ, model->BSIM4sheetResistance, + DMCGeff, DMCIeff, DMDGeff, 0, &(here->BSIM4drainConductance)); + } else + { + here->BSIM4drainConductance = 0.0; + } - if (((here->BSIM4rgeoMod != 0) || (model->BSIM4rdsMod != 0) - || (model->BSIM4tnoiMod != 0)) && (here->BSIM4sourceConductance == 0.0)) - { here->BSIM4sourceConductance = 1.0e3; /* mho */ - printf("Warning: Source conductance reset to 1.0e3 mho.\n"); - } - if (((here->BSIM4rgeoMod != 0) || (model->BSIM4rdsMod != 0) - || (model->BSIM4tnoiMod != 0)) && (here->BSIM4drainConductance == 0.0)) - { here->BSIM4drainConductance = 1.0e3; /* mho */ - printf("Warning: Drain conductance reset to 1.0e3 mho.\n"); - } /* End of Rsd processing */ + if (here->BSIM4drainConductance > 0.0) + here->BSIM4drainConductance = 1.0 + / here->BSIM4drainConductance; + else + { + here->BSIM4drainConductance = 1.0e3; /* mho */ + printf ("Warning: Drain conductance reset to 1.0e3 mho.\n"); + } + } else + { + here->BSIM4drainConductance = 0.0; + } + + /* End of Rsd processing */ Nvtms = model->BSIM4vtm * model->BSIM4SjctEmissionCoeff; @@ -1465,7 +1488,7 @@ int Size_Not_Found; { IFuid namarray[2]; namarray[0] = model->BSIM4modName; namarray[1] = here->BSIM4name; - (*(SPfrontEnd->IFerror)) (ERR_FATAL, "Fatal error(s) detected during BSIM4.0.0 parameter checking for %s in model %s", namarray); + (*(SPfrontEnd->IFerror)) (ERR_FATAL, "Fatal error(s) detected during BSIM4.2.1 parameter checking for %s in model %s", namarray); return(E_BADPARM); } } /* End instance */ diff --git a/src/spicelib/devices/bsim4/b4trunc.c b/src/spicelib/devices/bsim4/b4trunc.c index bb39b7901..d6e881e65 100644 --- a/src/spicelib/devices/bsim4/b4trunc.c +++ b/src/spicelib/devices/bsim4/b4trunc.c @@ -1,9 +1,10 @@ -/**** BSIM4.0.0, Released by Weidong Liu 3/24/2000 ****/ +/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/ /********** - * Copyright 2000 Regents of the University of California. All rights reserved. - * File: b4trunc.c of BSIM4.0.0. - * Authors: Weidong Liu, Kanyu M. Cao, Xiaodong Jin, Chenming Hu. + * Copyright 2001 Regents of the University of California. All rights reserved. + * File: b4trunc.c of BSIM4.2.1. + * Author: 2000 Weidong Liu + * Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu. * Project Director: Prof. Chenming Hu. **********/ @@ -18,11 +19,11 @@ int BSIM4trunc(inModel,ckt,timeStep) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; double *timeStep; { -register BSIM4model *model = (BSIM4model*)inModel; -register BSIM4instance *here; +BSIM4model *model = (BSIM4model*)inModel; +BSIM4instance *here; #ifdef STEPDEBUG double debugtemp; @@ -32,7 +33,7 @@ register BSIM4instance *here; { for (here = model->BSIM4instances; here != NULL; here = here->BSIM4nextInstance) { - if (here->BSIM4owner != ARCHme) continue; + if (here->BSIM4owner != ARCHme) continue; #ifdef STEPDEBUG debugtemp = *timeStep; #endif /* STEPDEBUG */ diff --git a/src/spicelib/devices/bsim4/bsim4def.h b/src/spicelib/devices/bsim4/bsim4def.h index 0450ad2cf..b46a09273 100644 --- a/src/spicelib/devices/bsim4/bsim4def.h +++ b/src/spicelib/devices/bsim4/bsim4def.h @@ -1,6 +1,7 @@ /********** -Copyright 2000 Regents of the University of California. All rights reserved. +Copyright 2001 Regents of the University of California. All rights reserved. Author: 2000 Weidong Liu. +Modified by Xuemei Xi October 2001 File: bsim4def.h **********/ @@ -100,6 +101,10 @@ typedef struct sBSIM4instance /* OP point */ double BSIM4Vgsteff; + double BSIM4vgs_eff; + double BSIM4vgd_eff; + double BSIM4dvgs_eff_dvg; + double BSIM4dvgd_eff_dvg; double BSIM4Vdseff; double BSIM4nstar; double BSIM4Abulk; @@ -111,6 +116,7 @@ typedef struct sBSIM4instance double BSIM4cbd; double BSIM4csub; double BSIM4Igidl; + double BSIM4Igisl; double BSIM4gm; double BSIM4gds; double BSIM4gmbs; @@ -124,6 +130,10 @@ typedef struct sBSIM4instance double BSIM4ggidlg; double BSIM4ggidls; double BSIM4ggidlb; + double BSIM4ggisld; + double BSIM4ggislg; + double BSIM4ggisls; + double BSIM4ggislb; double BSIM4Igcs; double BSIM4gIgcsg; @@ -178,6 +188,13 @@ typedef struct sBSIM4instance double BSIM4cdgb; double BSIM4cddb; double BSIM4cdsb; + double BSIM4csgb; + double BSIM4csdb; + double BSIM4cssb; + double BSIM4cgbb; + double BSIM4cdbb; + double BSIM4csbb; + double BSIM4cbbb; double BSIM4capbd; double BSIM4capbs; @@ -189,6 +206,7 @@ typedef struct sBSIM4instance double BSIM4qgate; double BSIM4qbulk; double BSIM4qdrn; + double BSIM4qsrc; double BSIM4qchqs; double BSIM4taunet; @@ -308,6 +326,7 @@ typedef struct sBSIM4instance double *BSIM4GPqPtr; double *BSIM4SPqPtr; + #define BSIM4vbd BSIM4states+ 0 #define BSIM4vbs BSIM4states+ 1 #define BSIM4vgs BSIM4states+ 2 @@ -339,8 +358,9 @@ typedef struct sBSIM4instance #define BSIM4qcdump BSIM4states+ 25 #define BSIM4cqcdump BSIM4states+ 26 #define BSIM4qdef BSIM4states+ 27 +#define BSIM4qs BSIM4states+ 28 -#define BSIM4numStates 28 +#define BSIM4numStates 29 /* indices to the array of BSIM4 NOISE SOURCES */ @@ -741,6 +761,8 @@ typedef struct sBSIM4model double BSIM4cle; double BSIM4dwc; double BSIM4dlc; + double BSIM4xw; + double BSIM4xl; double BSIM4dlcig; double BSIM4dwj; double BSIM4noff; @@ -1220,6 +1242,12 @@ typedef struct sBSIM4model double BSIM4DjctTempSatCurDensity; double BSIM4DjctSidewallTempSatCurDensity; double BSIM4DjctGateSidewallTempSatCurDensity; + double BSIM4SunitAreaTempJctCap; + double BSIM4DunitAreaTempJctCap; + double BSIM4SunitLengthSidewallTempJctCap; + double BSIM4DunitLengthSidewallTempJctCap; + double BSIM4SunitLengthGateSidewallTempJctCap; + double BSIM4DunitLengthGateSidewallTempJctCap; double BSIM4oxideTrapDensityA; double BSIM4oxideTrapDensityB; @@ -1398,6 +1426,8 @@ typedef struct sBSIM4model unsigned BSIM4cleGiven :1; unsigned BSIM4dwcGiven :1; unsigned BSIM4dlcGiven :1; + unsigned BSIM4xwGiven :1; + unsigned BSIM4xlGiven :1; unsigned BSIM4dlcigGiven :1; unsigned BSIM4dwjGiven :1; unsigned BSIM4noffGiven :1; @@ -2511,37 +2541,39 @@ typedef struct sBSIM4model #define BSIM4_MOD_WMAX 864 #define BSIM4_MOD_DWC 865 #define BSIM4_MOD_DLC 866 -#define BSIM4_MOD_EM 867 -#define BSIM4_MOD_EF 868 -#define BSIM4_MOD_AF 869 -#define BSIM4_MOD_KF 870 -#define BSIM4_MOD_NJS 871 -#define BSIM4_MOD_XTIS 872 -#define BSIM4_MOD_PBSWGS 873 -#define BSIM4_MOD_MJSWGS 874 -#define BSIM4_MOD_CJSWGS 875 -#define BSIM4_MOD_JSWS 876 -#define BSIM4_MOD_LLC 877 -#define BSIM4_MOD_LWC 878 -#define BSIM4_MOD_LWLC 879 -#define BSIM4_MOD_WLC 880 -#define BSIM4_MOD_WWC 881 -#define BSIM4_MOD_WWLC 882 -#define BSIM4_MOD_DWJ 883 -#define BSIM4_MOD_JSD 884 -#define BSIM4_MOD_PBD 885 -#define BSIM4_MOD_MJD 886 -#define BSIM4_MOD_PBSWD 887 -#define BSIM4_MOD_MJSWD 888 -#define BSIM4_MOD_CJD 889 -#define BSIM4_MOD_CJSWD 890 -#define BSIM4_MOD_NJD 891 -#define BSIM4_MOD_XTID 892 -#define BSIM4_MOD_PBSWGD 893 -#define BSIM4_MOD_MJSWGD 894 -#define BSIM4_MOD_CJSWGD 895 -#define BSIM4_MOD_JSWD 896 -#define BSIM4_MOD_DLCIG 897 +#define BSIM4_MOD_XL 867 +#define BSIM4_MOD_XW 868 +#define BSIM4_MOD_EM 869 +#define BSIM4_MOD_EF 870 +#define BSIM4_MOD_AF 871 +#define BSIM4_MOD_KF 872 +#define BSIM4_MOD_NJS 873 +#define BSIM4_MOD_XTIS 874 +#define BSIM4_MOD_PBSWGS 875 +#define BSIM4_MOD_MJSWGS 876 +#define BSIM4_MOD_CJSWGS 877 +#define BSIM4_MOD_JSWS 878 +#define BSIM4_MOD_LLC 879 +#define BSIM4_MOD_LWC 880 +#define BSIM4_MOD_LWLC 881 +#define BSIM4_MOD_WLC 882 +#define BSIM4_MOD_WWC 883 +#define BSIM4_MOD_WWLC 884 +#define BSIM4_MOD_DWJ 885 +#define BSIM4_MOD_JSD 886 +#define BSIM4_MOD_PBD 887 +#define BSIM4_MOD_MJD 888 +#define BSIM4_MOD_PBSWD 889 +#define BSIM4_MOD_MJSWD 890 +#define BSIM4_MOD_CJD 891 +#define BSIM4_MOD_CJSWD 892 +#define BSIM4_MOD_NJD 893 +#define BSIM4_MOD_XTID 894 +#define BSIM4_MOD_PBSWGD 895 +#define BSIM4_MOD_MJSWGD 896 +#define BSIM4_MOD_CJSWGD 897 +#define BSIM4_MOD_JSWD 898 +#define BSIM4_MOD_DLCIG 899 /* device questions */ #define BSIM4_DNODE 945 @@ -2574,17 +2606,17 @@ typedef struct sBSIM4model #define BSIM4_CQG 972 #define BSIM4_QD 973 #define BSIM4_CQD 974 -#define BSIM4_CGG 975 -#define BSIM4_CGD 976 -#define BSIM4_CGS 977 -#define BSIM4_CBG 978 +#define BSIM4_CGGB 975 +#define BSIM4_CGDB 976 +#define BSIM4_CGSB 977 +#define BSIM4_CBGB 978 #define BSIM4_CAPBD 979 #define BSIM4_CQBD 980 #define BSIM4_CAPBS 981 #define BSIM4_CQBS 982 -#define BSIM4_CDG 983 -#define BSIM4_CDD 984 -#define BSIM4_CDS 985 +#define BSIM4_CDGB 983 +#define BSIM4_CDDB 984 +#define BSIM4_CDSB 985 #define BSIM4_VON 986 #define BSIM4_VDSAT 987 #define BSIM4_QBS 988 @@ -2593,7 +2625,26 @@ typedef struct sBSIM4model #define BSIM4_DRAINCONDUCT 991 #define BSIM4_CBDB 992 #define BSIM4_CBSB 993 +#define BSIM4_CSUB 994 +#define BSIM4_QINV 995 +#define BSIM4_IGIDL 996 +#define BSIM4_CSGB 997 +#define BSIM4_CSDB 998 +#define BSIM4_CSSB 999 +#define BSIM4_CGBB 1000 +#define BSIM4_CDBB 1001 +#define BSIM4_CSBB 1002 +#define BSIM4_CBBB 1003 +#define BSIM4_QS 1004 +#define BSIM4_IGISL 1005 +#define BSIM4_IGS 1006 +#define BSIM4_IGD 1007 +#define BSIM4_IGB 1008 +#define BSIM4_IGCS 1009 +#define BSIM4_IGCD 1010 + +# #include "bsim4ext.h" #ifdef __STDC__ diff --git a/src/spicelib/devices/bsim4/bsim4ext.h b/src/spicelib/devices/bsim4/bsim4ext.h index 4cc7979c2..4e4977201 100644 --- a/src/spicelib/devices/bsim4/bsim4ext.h +++ b/src/spicelib/devices/bsim4/bsim4ext.h @@ -1,6 +1,7 @@ /********** -Copyright 2000 Regents of the University of California. All rights reserved. -Author: 2000 Weidong Liu. +Copyright 2001 Regents of the University of California. All rights reserved. +Author: 2000 Weidong Liu +Author: 2001 Xuemei Xi File: bsim4ext.h **********/ diff --git a/src/spicelib/devices/bsim4/bsim4itf.h b/src/spicelib/devices/bsim4/bsim4itf.h index 403f05c8b..08c4ec852 100644 --- a/src/spicelib/devices/bsim4/bsim4itf.h +++ b/src/spicelib/devices/bsim4/bsim4itf.h @@ -1,88 +1,13 @@ /********** -Copyright 2000 Regents of the University of California. All rights reserved. +Copyright 2001 Regents of the University of California. All rights reserved. Author: 2000 Weidong Liu. +Author: 2001 Xuemei Xi File: bsim4itf.h **********/ -#ifdef DEV_bsim4 #ifndef DEV_BSIM4 #define DEV_BSIM4 -#include "bsim4ext.h" - -extern IFparm BSIM4pTable[ ]; -extern IFparm BSIM4mPTable[ ]; -extern char *BSIM4names[ ]; -extern int BSIM4pTSize; -extern int BSIM4mPTSize; -extern int BSIM4nSize; -extern int BSIM4iSize; -extern int BSIM4mSize; - -SPICEdev B4info = { - { "BSIM4", - "Berkeley Short Channel IGFET Model-4", - - &BSIM4nSize, - &BSIM4nSize, - BSIM4names, - - &BSIM4pTSize, - BSIM4pTable, - - &BSIM4mPTSize, - BSIM4mPTable, - DEV_DEFAULT - }, - BSIM4param, - BSIM4mParam, - BSIM4load, - BSIM4setup, - BSIM4unsetup, - BSIM4setup, - BSIM4temp, - BSIM4trunc, - NULL, - BSIM4acLoad, - NULL, - BSIM4destroy, -#ifdef DELETES - BSIM4mDelete, - BSIM4delete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - BSIM4getic, - BSIM4ask, - BSIM4mAsk, -#ifdef AN_pz - BSIM4pzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ -#ifdef NEWCONV - BSIM4convTest, -#else /* NEWCONV */ - NULL, -#endif /* NEWCONV */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - -#ifdef AN_noise - BSIM4noise, -#else /* AN_noise */ - NULL, -#endif /* AN_noise */ - - &BSIM4iSize, - &BSIM4mSize -}; +SPICEdev *get_bsim4_info(void); #endif -#endif diff --git a/src/spicelib/devices/cap/Makefile.am b/src/spicelib/devices/cap/Makefile.am index f24c04913..79545d4c4 100644 --- a/src/spicelib/devices/cap/Makefile.am +++ b/src/spicelib/devices/cap/Makefile.am @@ -2,30 +2,32 @@ pkglib_LTLIBRARIES = libcap.la -libcap_la_SOURCES = \ - cap.c \ - capacld.c \ - capask.c \ - capdefs.h \ - capdel.c \ - capdest.c \ - capext.h \ - capgetic.c \ - capitf.h \ - capload.c \ - capmask.c \ - capmdel.c \ - capmpar.c \ - capparam.c \ - cappzld.c \ - capsacl.c \ - capsetup.c \ - capsload.c \ - capsprt.c \ - capsset.c \ - capsupd.c \ - captemp.c \ - captrunc.c +libcap_la_SOURCES = \ + cap.c \ + capacld.c \ + capask.c \ + capdefs.h \ + capdel.c \ + capdest.c \ + capext.h \ + capgetic.c \ + capinit.c \ + capinit.h \ + capitf.h \ + capload.c \ + capmask.c \ + capmdel.c \ + capmpar.c \ + capparam.c \ + cappzld.c \ + capsacl.c \ + capsetup.c \ + capsload.c \ + capsprt.c \ + capsset.c \ + capsupd.c \ + captemp.c \ + captrunc.c diff --git a/src/spicelib/devices/cap/capacld.c b/src/spicelib/devices/cap/capacld.c index f1990eab7..2b37c34d2 100644 --- a/src/spicelib/devices/cap/capacld.c +++ b/src/spicelib/devices/cap/capacld.c @@ -16,12 +16,12 @@ Author: 1985 Thomas L. Quarles int CAPacLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register CAPmodel *model = (CAPmodel*)inModel; + CAPmodel *model = (CAPmodel*)inModel; double val; - register CAPinstance *here; + CAPinstance *here; for( ; model != NULL; model = model->CAPnextModel) { for( here = model->CAPinstances;here != NULL; diff --git a/src/spicelib/devices/cap/capask.c b/src/spicelib/devices/cap/capask.c index d1b7b81d7..74af35722 100644 --- a/src/spicelib/devices/cap/capask.c +++ b/src/spicelib/devices/cap/capask.c @@ -56,7 +56,7 @@ CAPask(ckt,inst, which, value, select) } else { value->rValue = *(ckt->CKTstate0 + here->CAPccap); } - } + } else value->rValue = *(ckt->CKTstate0 + here->CAPccap); return(OK); case CAP_POWER: if (ckt->CKTcurrentAnalysis & DOING_AC) { @@ -74,7 +74,9 @@ CAPask(ckt,inst, which, value, select) (*(ckt->CKTrhsOld + here->CAPposNode) - *(ckt->CKTrhsOld + here->CAPnegNode)); } - } + } else value->rValue = *(ckt->CKTstate0 + here->CAPccap) * + (*(ckt->CKTrhsOld + here->CAPposNode) - + *(ckt->CKTrhsOld + here->CAPnegNode)); return(OK); case CAP_QUEST_SENS_DC: if(ckt->CKTsenInfo){ diff --git a/src/spicelib/devices/cap/capitf.h b/src/spicelib/devices/cap/capitf.h index 5ce8503cb..04c8266e8 100644 --- a/src/spicelib/devices/cap/capitf.h +++ b/src/spicelib/devices/cap/capitf.h @@ -1,88 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_cap - #ifndef DEV_CAP #define DEV_CAP -#include "capext.h" -extern IFparm CAPpTable[ ]; -extern IFparm CAPmPTable[ ]; -extern char *CAPnames[ ]; -extern int CAPpTSize; -extern int CAPmPTSize; -extern int CAPnSize; -extern int CAPiSize; -extern int CAPmSize; - -SPICEdev CAPinfo = { - { "Capacitor", - "Fixed capacitor", - - &CAPnSize, - &CAPnSize, - CAPnames, - - &CAPpTSize, - CAPpTable, - - &CAPmPTSize, - CAPmPTable, - 0 - }, - - CAPparam, - CAPmParam, - CAPload, - CAPsetup, - NULL, - CAPsetup, - CAPtemp, - CAPtrunc, - NULL, - CAPacLoad, - NULL, - CAPdestroy, -#ifdef DELETES - CAPmDelete, - CAPdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - CAPgetic, - CAPask, - CAPmAsk, -#ifdef AN_pz - CAPpzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ - NULL, -#ifdef AN_sense2 - CAPsSetup, - CAPsLoad, - CAPsUpdate, - CAPsAcLoad, - CAPsPrint, -#else /* AN_sense2 */ - NULL, - NULL, - NULL, - NULL, - NULL, -#endif /* AN_sense2 */ - NULL, - NULL, /* DISTO */ - NULL, /* NOISE */ - - &CAPiSize, - &CAPmSize - - -}; - +SPICEdev *get_cap_info(void); #endif -#endif diff --git a/src/spicelib/devices/cap/capload.c b/src/spicelib/devices/cap/capload.c index 849233866..765e48964 100644 --- a/src/spicelib/devices/cap/capload.c +++ b/src/spicelib/devices/cap/capload.c @@ -15,14 +15,14 @@ int CAPload(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* actually load the current capacitance value into the * sparse matrix previously provided */ { - register CAPmodel *model = (CAPmodel*)inModel; - register CAPinstance *here; - register int cond1; + CAPmodel *model = (CAPmodel*)inModel; + CAPinstance *here; + int cond1; double vcap; double geq; double ceq; diff --git a/src/spicelib/devices/cap/cappzld.c b/src/spicelib/devices/cap/cappzld.c index 6f646dd0a..dc53f1da1 100644 --- a/src/spicelib/devices/cap/cappzld.c +++ b/src/spicelib/devices/cap/cappzld.c @@ -19,12 +19,12 @@ int CAPpzLoad(inModel,ckt,s) GENmodel *inModel; CKTcircuit *ckt; - register SPcomplex *s; + SPcomplex *s; { - register CAPmodel *model = (CAPmodel*)inModel; + CAPmodel *model = (CAPmodel*)inModel; double val; - register CAPinstance *here; + CAPinstance *here; for( ; model != NULL; model = model->CAPnextModel) { for( here = model->CAPinstances;here != NULL; diff --git a/src/spicelib/devices/cap/capsacl.c b/src/spicelib/devices/cap/capsacl.c index 1109b4e2d..13514dc03 100644 --- a/src/spicelib/devices/cap/capsacl.c +++ b/src/spicelib/devices/cap/capsacl.c @@ -22,11 +22,11 @@ int CAPsAcLoad(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { - register CAPmodel *model = (CAPmodel*)inModel; - register CAPinstance *here; + CAPmodel *model = (CAPmodel*)inModel; + CAPinstance *here; double vcap; double ivcap; double val; diff --git a/src/spicelib/devices/cap/capsetup.c b/src/spicelib/devices/cap/capsetup.c index bc2abc389..2a69642f2 100644 --- a/src/spicelib/devices/cap/capsetup.c +++ b/src/spicelib/devices/cap/capsetup.c @@ -16,7 +16,7 @@ Author: 1985 Thomas L. Quarles /*ARGSUSED*/ int CAPsetup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; CKTcircuit *ckt; int *states; @@ -25,8 +25,8 @@ CAPsetup(matrix,inModel,ckt,states) */ { - register CAPmodel *model = (CAPmodel*)inModel; - register CAPinstance *here; + CAPmodel *model = (CAPmodel*)inModel; + CAPinstance *here; /* loop through all the capacitor models */ for( ; model != NULL; model = model->CAPnextModel ) { diff --git a/src/spicelib/devices/cap/capsload.c b/src/spicelib/devices/cap/capsload.c index 028f7927b..8761826e3 100644 --- a/src/spicelib/devices/cap/capsload.c +++ b/src/spicelib/devices/cap/capsload.c @@ -21,10 +21,10 @@ Author: 1985 Thomas L. Quarles int CAPsLoad(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { - register CAPmodel *model = (CAPmodel*)inModel; - register CAPinstance *here; + CAPmodel *model = (CAPmodel*)inModel; + CAPinstance *here; int iparmno; double vcap; double Osxp; diff --git a/src/spicelib/devices/cap/capsprt.c b/src/spicelib/devices/cap/capsprt.c index 541a4922b..fe6d440b7 100644 --- a/src/spicelib/devices/cap/capsprt.c +++ b/src/spicelib/devices/cap/capsprt.c @@ -21,10 +21,10 @@ Author: 1985 Thomas L. Quarles void CAPsPrint(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register CAPmodel *model = (CAPmodel*)inModel; - register CAPinstance *here; + CAPmodel *model = (CAPmodel*)inModel; + CAPinstance *here; printf("CAPACITORS-----------------\n"); /* loop through all the capacitor models */ diff --git a/src/spicelib/devices/cap/capsset.c b/src/spicelib/devices/cap/capsset.c index 8de7c4d6d..c8750c40d 100644 --- a/src/spicelib/devices/cap/capsset.c +++ b/src/spicelib/devices/cap/capsset.c @@ -20,12 +20,12 @@ Author: 1985 Thomas L. Quarles int CAPsSetup(info,inModel) - register SENstruct *info; + SENstruct *info; GENmodel *inModel; { - register CAPmodel *model = (CAPmodel*)inModel; - register CAPinstance *here; + CAPmodel *model = (CAPmodel*)inModel; + CAPinstance *here; /* loop through all the capacitor models */ for( ; model != NULL; model = model->CAPnextModel ) { diff --git a/src/spicelib/devices/cap/capsupd.c b/src/spicelib/devices/cap/capsupd.c index cf47d6a04..4782314d1 100644 --- a/src/spicelib/devices/cap/capsupd.c +++ b/src/spicelib/devices/cap/capsupd.c @@ -19,10 +19,10 @@ Author: 1985 Thomas L. Quarles int CAPsUpdate(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register CAPmodel *model = (CAPmodel*)inModel; - register CAPinstance *here; + CAPmodel *model = (CAPmodel*)inModel; + CAPinstance *here; int iparmno; double s1; double s2; diff --git a/src/spicelib/devices/cap/captemp.c b/src/spicelib/devices/cap/captemp.c index 2c90695bc..47f24a917 100644 --- a/src/spicelib/devices/cap/captemp.c +++ b/src/spicelib/devices/cap/captemp.c @@ -24,8 +24,8 @@ CAPtemp(inModel,ckt) CKTcircuit *ckt; { - register CAPmodel *model = (CAPmodel*)inModel; - register CAPinstance *here; + CAPmodel *model = (CAPmodel*)inModel; + CAPinstance *here; /* loop through all the capacitor models */ for( ; model != NULL; model = model->CAPnextModel ) { diff --git a/src/spicelib/devices/cap/captrunc.c b/src/spicelib/devices/cap/captrunc.c index b7b6a15ee..0e3a86ce6 100644 --- a/src/spicelib/devices/cap/captrunc.c +++ b/src/spicelib/devices/cap/captrunc.c @@ -16,11 +16,11 @@ Author: 1985 Thomas L. Quarles int CAPtrunc(inModel,ckt,timeStep) GENmodel *inModel; - register CKTcircuit *ckt; - register double *timeStep; + CKTcircuit *ckt; + double *timeStep; { - register CAPmodel *model = (CAPmodel*)inModel; - register CAPinstance *here; + CAPmodel *model = (CAPmodel*)inModel; + CAPinstance *here; for( ; model!= NULL; model = model->CAPnextModel) { for(here = model->CAPinstances ; here != NULL ; diff --git a/src/spicelib/devices/cccs/Makefile.am b/src/spicelib/devices/cccs/Makefile.am index c909f2ace..97ad77d9e 100644 --- a/src/spicelib/devices/cccs/Makefile.am +++ b/src/spicelib/devices/cccs/Makefile.am @@ -3,22 +3,24 @@ pkglib_LTLIBRARIES = libcccs.la libcccs_la_SOURCES = \ - cccs.c \ - cccsask.c \ - cccsdefs.h \ - cccsdel.c \ - cccsdest.c \ - cccsext.h \ - cccsitf.h \ - cccsload.c \ - cccsmdel.c \ - cccspar.c \ - cccspzld.c \ - cccssacl.c \ - cccsset.c \ - cccssld.c \ - cccssprt.c \ - cccssset.c + cccs.c \ + cccsask.c \ + cccsdefs.h \ + cccsdel.c \ + cccsdest.c \ + cccsext.h \ + cccsinit.c \ + cccsinit.h \ + cccsitf.h \ + cccsload.c \ + cccsmdel.c \ + cccspar.c \ + cccspzld.c \ + cccssacl.c \ + cccsset.c \ + cccssld.c \ + cccssprt.c \ + cccssset.c diff --git a/src/spicelib/devices/cccs/cccsitf.h b/src/spicelib/devices/cccs/cccsitf.h index 4a0eabf2a..ce4f23661 100644 --- a/src/spicelib/devices/cccs/cccsitf.h +++ b/src/spicelib/devices/cccs/cccsitf.h @@ -1,85 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_cccs - #ifndef DEV_CCCS #define DEV_CCCS -#include "cccsext.h" -extern IFparm CCCSpTable[ ]; -extern char *CCCSnames[ ]; -extern int CCCSpTSize; -extern int CCCSnSize; -extern int CCCSiSize; -extern int CCCSmSize; - -SPICEdev CCCSinfo = { - { "CCCS", - "Current controlled current source", - - &CCCSnSize, - &CCCSnSize, - CCCSnames, - - &CCCSpTSize, - CCCSpTable, - - 0, - NULL, - DEV_DEFAULT - }, - - CCCSparam, - NULL, - CCCSload, - CCCSsetup, - NULL, - CCCSsetup, - NULL, - NULL, - NULL, - CCCSload, - NULL, - CCCSdestroy, -#ifdef DELETES - CCCSmDelete, - CCCSdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - NULL, - CCCSask, - NULL, -#ifdef AN_pz - CCCSpzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ - NULL, -#ifdef AN_sense2 - CCCSsSetup, - CCCSsLoad, - NULL, - CCCSsAcLoad, - CCCSsPrint, - NULL, -#else /* AN_sense2 */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -#endif /* AN_sense2 */ - NULL, /* DISTO */ - NULL, /* NOISE */ - - &CCCSiSize, - &CCCSmSize - -}; +SPICEdev *get_cccs_info(void); #endif -#endif diff --git a/src/spicelib/devices/cccs/cccsload.c b/src/spicelib/devices/cccs/cccsload.c index f6576f625..c9d387d1e 100644 --- a/src/spicelib/devices/cccs/cccsload.c +++ b/src/spicelib/devices/cccs/cccsload.c @@ -24,8 +24,8 @@ CCCSload(inModel,ckt) * sparse matrix previously provided */ { - register CCCSmodel *model = (CCCSmodel*)inModel; - register CCCSinstance *here; + CCCSmodel *model = (CCCSmodel*)inModel; + CCCSinstance *here; /* loop through all the voltage source models */ for( ; model != NULL; model = model->CCCSnextModel ) { diff --git a/src/spicelib/devices/cccs/cccspzld.c b/src/spicelib/devices/cccs/cccspzld.c index 8b1269722..535d545c3 100644 --- a/src/spicelib/devices/cccs/cccspzld.c +++ b/src/spicelib/devices/cccs/cccspzld.c @@ -26,8 +26,8 @@ CCCSpzLoad(inModel,ckt,s) * sparse matrix previously provided */ { - register CCCSmodel *model = (CCCSmodel*)inModel; - register CCCSinstance *here; + CCCSmodel *model = (CCCSmodel*)inModel; + CCCSinstance *here; /* loop through all the voltage source models */ for( ; model != NULL; model = model->CCCSnextModel ) { diff --git a/src/spicelib/devices/cccs/cccssacl.c b/src/spicelib/devices/cccs/cccssacl.c index 488b16b91..bbf80e6de 100644 --- a/src/spicelib/devices/cccs/cccssacl.c +++ b/src/spicelib/devices/cccs/cccssacl.c @@ -23,8 +23,8 @@ CCCSsAcLoad(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { - register CCCSmodel *model = (CCCSmodel*)inModel; - register CCCSinstance *here; + CCCSmodel *model = (CCCSmodel*)inModel; + CCCSinstance *here; double ic; double i_ic; diff --git a/src/spicelib/devices/cccs/cccsset.c b/src/spicelib/devices/cccs/cccsset.c index 4fb9946cc..26c274f15 100644 --- a/src/spicelib/devices/cccs/cccsset.c +++ b/src/spicelib/devices/cccs/cccsset.c @@ -21,13 +21,13 @@ Author: 1985 Thomas L. Quarles /*ARGSUSED*/ int CCCSsetup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int *states; { - register CCCSmodel *model = (CCCSmodel*)inModel; - register CCCSinstance *here; + CCCSmodel *model = (CCCSmodel*)inModel; + CCCSinstance *here; /* loop through all the voltage source models */ for( ; model != NULL; model = model->CCCSnextModel ) { diff --git a/src/spicelib/devices/cccs/cccssld.c b/src/spicelib/devices/cccs/cccssld.c index 190605d91..a3bae935c 100644 --- a/src/spicelib/devices/cccs/cccssld.c +++ b/src/spicelib/devices/cccs/cccssld.c @@ -23,8 +23,8 @@ CCCSsLoad(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { - register CCCSmodel *model = (CCCSmodel*)inModel; - register CCCSinstance *here; + CCCSmodel *model = (CCCSmodel*)inModel; + CCCSinstance *here; double ic ; /* loop through all the CCCS models */ diff --git a/src/spicelib/devices/cccs/cccssprt.c b/src/spicelib/devices/cccs/cccssprt.c index 2a733b672..500fcf548 100644 --- a/src/spicelib/devices/cccs/cccssprt.c +++ b/src/spicelib/devices/cccs/cccssprt.c @@ -21,10 +21,10 @@ Author: 1985 Thomas L. Quarles void CCCSsPrint(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register CCCSmodel *model = (CCCSmodel*)inModel; - register CCCSinstance *here; + CCCSmodel *model = (CCCSmodel*)inModel; + CCCSinstance *here; printf("CURRENT CONTROLLED CURRENT SOURCES-----------------\n"); /* loop through all the voltage source models */ diff --git a/src/spicelib/devices/cccs/cccssset.c b/src/spicelib/devices/cccs/cccssset.c index 7bd7e58f6..6b537aed7 100644 --- a/src/spicelib/devices/cccs/cccssset.c +++ b/src/spicelib/devices/cccs/cccssset.c @@ -20,11 +20,11 @@ Author: 1985 Thomas L. Quarles int CCCSsSetup(info,inModel) - register SENstruct *info; + SENstruct *info; GENmodel *inModel; { - register CCCSmodel *model = (CCCSmodel*)inModel; - register CCCSinstance *here; + CCCSmodel *model = (CCCSmodel*)inModel; + CCCSinstance *here; /* loop through all the CCCS models */ for( ; model != NULL; model = model->CCCSnextModel ) { diff --git a/src/spicelib/devices/ccvs/Makefile.am b/src/spicelib/devices/ccvs/Makefile.am index 580d2f186..276650832 100644 --- a/src/spicelib/devices/ccvs/Makefile.am +++ b/src/spicelib/devices/ccvs/Makefile.am @@ -3,23 +3,25 @@ pkglib_LTLIBRARIES = libccvs.la libccvs_la_SOURCES = \ - ccvs.c \ - ccvsask.c \ - ccvsdefs.h \ - ccvsdel.c \ - ccvsdest.c \ - ccvsext.h \ - ccvsfbr.c \ - ccvsitf.h \ - ccvsload.c \ - ccvsmdel.c \ - ccvspar.c \ - ccvspzld.c \ - ccvssacl.c \ - ccvsset.c \ - ccvssld.c \ - ccvssprt.c \ - ccvssset.c + ccvs.c \ + ccvsask.c \ + ccvsdefs.h \ + ccvsdel.c \ + ccvsdest.c \ + ccvsext.h \ + ccvsfbr.c \ + ccvsinit.c \ + ccvsinit.h \ + ccvsitf.h \ + ccvsload.c \ + ccvsmdel.c \ + ccvspar.c \ + ccvspzld.c \ + ccvssacl.c \ + ccvsset.c \ + ccvssld.c \ + ccvssprt.c \ + ccvssset.c diff --git a/src/spicelib/devices/ccvs/ccvsfbr.c b/src/spicelib/devices/ccvs/ccvsfbr.c index f5f2c6335..a8b79e3ec 100644 --- a/src/spicelib/devices/ccvs/ccvsfbr.c +++ b/src/spicelib/devices/ccvs/ccvsfbr.c @@ -15,12 +15,12 @@ Author: 1985 Thomas L. Quarles int CCVSfindBr(ckt,inModel,name) - register CKTcircuit *ckt; + CKTcircuit *ckt; GENmodel *inModel; - register IFuid name; + IFuid name; { - register CCVSmodel *model = (CCVSmodel*)inModel; - register CCVSinstance *here; + CCVSmodel *model = (CCVSmodel*)inModel; + CCVSinstance *here; int error; CKTnode *tmp; diff --git a/src/spicelib/devices/ccvs/ccvsitf.h b/src/spicelib/devices/ccvs/ccvsitf.h index 869c0e541..e9b77d387 100644 --- a/src/spicelib/devices/ccvs/ccvsitf.h +++ b/src/spicelib/devices/ccvs/ccvsitf.h @@ -1,86 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_ccvs - #ifndef DEV_CCVS #define DEV_CCVS -#include "ccvsext.h" -extern IFparm CCVSpTable[ ]; -extern char *CCVSnames[ ]; -extern int CCVSpTSize; -extern int CCVSnSize; -extern int CCVSiSize; -extern int CCVSmSize; - -SPICEdev CCVSinfo = { - { - "CCVS", - "Linear current controlled current source", - - &CCVSnSize, - &CCVSnSize, - CCVSnames, - - &CCVSpTSize, - CCVSpTable, - - 0, - NULL, - DEV_DEFAULT - }, - - CCVSparam, - NULL, - CCVSload, - CCVSsetup, - CCVSunsetup, - CCVSsetup, - NULL, - NULL, - CCVSfindBr, - CCVSload, /* ac and normal load functions identical */ - NULL, - CCVSdestroy, -#ifdef DELETES - CCVSmDelete, - CCVSdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - NULL, - CCVSask, - NULL, -#ifdef AN_pz - CCVSpzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ - NULL, -#ifdef AN_sense2 - CCVSsSetup, - CCVSsLoad, - NULL, - CCVSsAcLoad, - CCVSsPrint, - NULL, -#else /* NOSENS */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -#endif /* NOSENS */ - NULL, /* DISTO */ - NULL, /* NOISE */ - - &CCVSiSize, - &CCVSmSize - -}; +SPICEdev *get_ccvs_info(void); #endif -#endif diff --git a/src/spicelib/devices/ccvs/ccvsload.c b/src/spicelib/devices/ccvs/ccvsload.c index a4f0a8387..0cba86663 100644 --- a/src/spicelib/devices/ccvs/ccvsload.c +++ b/src/spicelib/devices/ccvs/ccvsload.c @@ -24,8 +24,8 @@ CCVSload(inModel,ckt) * sparse matrix previously provided */ { - register CCVSmodel *model = (CCVSmodel*)inModel; - register CCVSinstance *here; + CCVSmodel *model = (CCVSmodel*)inModel; + CCVSinstance *here; /* loop through all the voltage source models */ for( ; model != NULL; model = model->CCVSnextModel ) { diff --git a/src/spicelib/devices/ccvs/ccvspzld.c b/src/spicelib/devices/ccvs/ccvspzld.c index ee8b9c0b1..88e3b6e78 100644 --- a/src/spicelib/devices/ccvs/ccvspzld.c +++ b/src/spicelib/devices/ccvs/ccvspzld.c @@ -26,8 +26,8 @@ CCVSpzLoad(inModel,ckt,s) * sparse matrix previously provided */ { - register CCVSmodel *model = (CCVSmodel*)inModel; - register CCVSinstance *here; + CCVSmodel *model = (CCVSmodel*)inModel; + CCVSinstance *here; /* loop through all the voltage source models */ for( ; model != NULL; model = model->CCVSnextModel ) { diff --git a/src/spicelib/devices/ccvs/ccvssacl.c b/src/spicelib/devices/ccvs/ccvssacl.c index 43887ab5c..335c6cd50 100644 --- a/src/spicelib/devices/ccvs/ccvssacl.c +++ b/src/spicelib/devices/ccvs/ccvssacl.c @@ -23,8 +23,8 @@ CCVSsAcLoad(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { - register CCVSmodel *model = (CCVSmodel*)inModel; - register CCVSinstance *here; + CCVSmodel *model = (CCVSmodel*)inModel; + CCVSinstance *here; double ic,i_ic; /* loop through all the voltage source models */ diff --git a/src/spicelib/devices/ccvs/ccvsset.c b/src/spicelib/devices/ccvs/ccvsset.c index 21438e73f..6c7a04d58 100644 --- a/src/spicelib/devices/ccvs/ccvsset.c +++ b/src/spicelib/devices/ccvs/ccvsset.c @@ -17,13 +17,13 @@ Author: 1985 Thomas L. Quarles /*ARGSUSED*/ int CCVSsetup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int *states; { - register CCVSmodel *model = (CCVSmodel*)inModel; - register CCVSinstance *here; + CCVSmodel *model = (CCVSmodel*)inModel; + CCVSinstance *here; int error; CKTnode *tmp; @@ -70,7 +70,6 @@ CCVSunsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM CCVSmodel *model; CCVSinstance *here; @@ -86,6 +85,5 @@ CCVSunsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/ccvs/ccvssld.c b/src/spicelib/devices/ccvs/ccvssld.c index 82688cb7d..325daf846 100644 --- a/src/spicelib/devices/ccvs/ccvssld.c +++ b/src/spicelib/devices/ccvs/ccvssld.c @@ -22,8 +22,8 @@ CCVSsLoad(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { - register CCVSmodel *model = (CCVSmodel*)inModel; - register CCVSinstance *here; + CCVSmodel *model = (CCVSmodel*)inModel; + CCVSinstance *here; double ic; /* loop through all the voltage source models */ diff --git a/src/spicelib/devices/ccvs/ccvssprt.c b/src/spicelib/devices/ccvs/ccvssprt.c index dc8eb2625..8b28c41ad 100644 --- a/src/spicelib/devices/ccvs/ccvssprt.c +++ b/src/spicelib/devices/ccvs/ccvssprt.c @@ -20,10 +20,10 @@ Author: 1985 Thomas L. Quarles void CCVSsPrint(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register CCVSmodel *model = (CCVSmodel*)inModel; - register CCVSinstance *here; + CCVSmodel *model = (CCVSmodel*)inModel; + CCVSinstance *here; printf("CURRENT CONTROLLED VOLTAGE SOURCES-----------------\n"); /* loop through all the voltage source models */ diff --git a/src/spicelib/devices/ccvs/ccvssset.c b/src/spicelib/devices/ccvs/ccvssset.c index 101554984..8212eb006 100644 --- a/src/spicelib/devices/ccvs/ccvssset.c +++ b/src/spicelib/devices/ccvs/ccvssset.c @@ -19,12 +19,12 @@ Author: 1985 Thomas L. Quarles int CCVSsSetup(info,inModel) - register SENstruct *info; + SENstruct *info; GENmodel *inModel; { - register CCVSmodel *model = (CCVSmodel*)inModel; - register CCVSinstance *here; + CCVSmodel *model = (CCVSmodel*)inModel; + CCVSinstance *here; /* loop through all the voltage source models */ for( ; model != NULL; model = model->CCVSnextModel ) { diff --git a/src/spicelib/devices/csw/Makefile.am b/src/spicelib/devices/csw/Makefile.am index aea784875..ba1cf6364 100644 --- a/src/spicelib/devices/csw/Makefile.am +++ b/src/spicelib/devices/csw/Makefile.am @@ -3,22 +3,25 @@ pkglib_LTLIBRARIES = libcsw.la libcsw_la_SOURCES = \ - csw.c \ - cswacld.c \ - cswask.c \ - cswdefs.h \ - cswdel.c \ - cswdest.c \ - cswext.h \ - cswitf.h \ - cswload.c \ - cswmask.c \ - cswmdel.c \ - cswmpar.c \ - cswnoise.c \ - cswparam.c \ - cswpzld.c \ - cswsetup.c + csw.c \ + cswacld.c \ + cswask.c \ + cswdefs.h \ + cswdel.c \ + cswdest.c \ + cswext.h \ + cswinit.c \ + cswinit.h \ + cswitf.h \ + cswload.c \ + cswmask.c \ + cswmdel.c \ + cswmpar.c \ + cswnoise.c \ + cswparam.c \ + cswpzld.c \ + cswsetup.c \ + cswtrunc.c diff --git a/src/spicelib/devices/csw/cswacld.c b/src/spicelib/devices/csw/cswacld.c index 47da954a2..ed99d3175 100644 --- a/src/spicelib/devices/csw/cswacld.c +++ b/src/spicelib/devices/csw/cswacld.c @@ -17,15 +17,15 @@ int CSWacLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* load the current values into the * sparse matrix previously provided * during AC analysis */ { - register CSWmodel *model = (CSWmodel*)inModel; - register CSWinstance *here; + CSWmodel *model = (CSWmodel*)inModel; + CSWinstance *here; double g_now; int current_state; diff --git a/src/spicelib/devices/csw/cswdefs.h b/src/spicelib/devices/csw/cswdefs.h index 4d288160c..5f6b4f62d 100644 --- a/src/spicelib/devices/csw/cswdefs.h +++ b/src/spicelib/devices/csw/cswdefs.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Gordon M. Jacobs +Modified: 2000 AlansFixes **********/ #ifndef CSW @@ -54,7 +55,7 @@ typedef struct sCSWinstance { #define CSW_ON_CONDUCTANCE 1.0 /* default on conductance = 1 mho */ #define CSW_OFF_CONDUCTANCE ckt->CKTgmin /* default off conductance */ -#define CSW_NUM_STATES 1 +#define CSW_NUM_STATES 2 typedef struct sCSWmodel { /* model structure for a switch */ int CSWmodType; /* type index of this device type */ diff --git a/src/spicelib/devices/csw/cswext.h b/src/spicelib/devices/csw/cswext.h index 0f3f50dea..0eefa4570 100644 --- a/src/spicelib/devices/csw/cswext.h +++ b/src/spicelib/devices/csw/cswext.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Gordon M. Jacobs +Modified: 2000 AlansFixes **********/ #ifdef __STDC__ @@ -16,6 +17,9 @@ extern int CSWparam(int,IFvalue*,GENinstance*,IFvalue*); extern int CSWpzLoad(GENmodel*,CKTcircuit*,SPcomplex*); extern int CSWsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int CSWnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); + +extern int CSWtrunc(GENmodel*,CKTcircuit*,double*); + #else /* stdc */ extern int CSWask(); extern int CSWacLoad(); @@ -29,5 +33,6 @@ extern int CSWparam(); extern int CSWpzLoad(); extern int CSWsetup(); extern int CSWnoise(); +extern int CSWtrunc(); #endif /* stdc */ diff --git a/src/spicelib/devices/csw/cswitf.h b/src/spicelib/devices/csw/cswitf.h index 83e40397c..b8a6960ff 100644 --- a/src/spicelib/devices/csw/cswitf.h +++ b/src/spicelib/devices/csw/cswitf.h @@ -1,83 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_csw - #ifndef DEV_CSW #define DEV_CSW -#include "cswext.h" -extern IFparm CSWpTable[ ]; -extern IFparm CSWmPTable[ ]; -extern char *CSWnames[ ]; -extern int CSWpTSize; -extern int CSWmPTSize; -extern int CSWnSize; -extern int CSWiSize; -extern int CSWmSize; - -SPICEdev CSWinfo = { - { "CSwitch", - "Current controlled ideal switch", - - &CSWnSize, - &CSWnSize, - CSWnames, - - &CSWpTSize, - CSWpTable, - - &CSWmPTSize, - CSWmPTable, - 0 - }, - - CSWparam, - CSWmParam, - CSWload, - CSWsetup, - NULL, - CSWsetup, - NULL, - NULL, - NULL, - CSWacLoad, - NULL, - CSWdestroy, -#ifdef DELETES - CSWmDelete, - CSWdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - NULL, - CSWask, - CSWmAsk, -#ifdef AN_pz - CSWpzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, /* DISTO */ -#ifdef AN_noise - CSWnoise, -#else /* AN_noise */ - NULL, -#endif /* AN_noise */ - - &CSWiSize, - &CSWmSize - -}; - +extern SPICEdev *get_csw_info(void); #endif -#endif diff --git a/src/spicelib/devices/csw/cswload.c b/src/spicelib/devices/csw/cswload.c index 4103852b7..2e5504f15 100644 --- a/src/spicelib/devices/csw/cswload.c +++ b/src/spicelib/devices/csw/cswload.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Gordon Jacobs +Modified: 2001 Jon Engelbert **********/ #include "ngspice.h" @@ -14,18 +15,20 @@ Author: 1985 Gordon Jacobs int CSWload(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* actually load the current values into the * sparse matrix previously provided */ { - register CSWmodel *model = (CSWmodel*)inModel; - register CSWinstance *here; + CSWmodel *model = (CSWmodel*)inModel; + CSWinstance *here; double g_now; double i_ctrl; - double previous_state; - double current_state; + double previous_state = -1; + double current_state = -1, old_current_state = -1; + double REALLY_OFF = 0, REALLY_ON = 1; // switch is on or off, not in hysteresis region. + double HYST_OFF = 2, HYST_ON = 3; // switch is on or off while control value is in hysteresis region. /* loop through all the switch models */ for( ; model != NULL; model = model->CSWnextModel ) { @@ -33,7 +36,13 @@ CSWload(inModel,ckt) /* loop through all the instances of the model */ for (here = model->CSWinstances; here != NULL ; here=here->CSWnextInstance) { - if (here->CSWowner != ARCHme) continue; + + if (here->CSWowner != ARCHme) continue; + + old_current_state = *(ckt->CKTstates[0] + here->CSWstate); + previous_state = *(ckt->CKTstates[1] + here->CSWstate); + i_ctrl = *(ckt->CKTrhsOld + + here->CSWcontBranch); /* decide the state of the switch */ @@ -41,64 +50,94 @@ CSWload(inModel,ckt) if(here->CSWzero_stateGiven) { /* switch specified "on" */ - *(ckt->CKTstate0 + here->CSWstate) = 1.0; - current_state = 1.0; + if ((model->CSWiHysteresis >= 0) && (i_ctrl > (model->CSWiThreshold + model->CSWiHysteresis))) + current_state = REALLY_ON; + else if ((model->CSWiHysteresis < 0) && (i_ctrl > (model->CSWiThreshold - model->CSWiHysteresis))) + current_state = REALLY_ON; + else + current_state = HYST_ON; } else { - *(ckt->CKTstate0 + here->CSWstate) = 0.0; - current_state = 0.0; + if ((model->CSWiHysteresis >= 0) && (i_ctrl < (model->CSWiThreshold - model->CSWiHysteresis))) + current_state = REALLY_OFF; + else if ((model->CSWiHysteresis < 0) && (i_ctrl < (model->CSWiThreshold + model->CSWiHysteresis))) + current_state = REALLY_OFF; + else + current_state = HYST_OFF; } + } else if (ckt->CKTmode & (MODEINITSMSIG)) { - previous_state = *(ckt->CKTstate0 + here->CSWstate); current_state = previous_state; } else if (ckt->CKTmode & (MODEINITFLOAT)) { /* use state0 since INITTRAN or INITPRED already called */ - previous_state = *(ckt->CKTstate0 + here->CSWstate); - i_ctrl = *(ckt->CKTrhsOld + - here->CSWcontBranch); - if(i_ctrl > (model->CSWiThreshold+model->CSWiHysteresis)) { - *(ckt->CKTstate0 + here->CSWstate) = 1.0; - current_state = 1.0; - } - else if(i_ctrl < (model->CSWiThreshold - - model->CSWiHysteresis)) { - *(ckt->CKTstate0 + here->CSWstate) = 0.0; - current_state = 0.0; - } - else { - current_state = previous_state; - } - if(current_state != previous_state) { - ckt->CKTnoncon++; /* ensure one more iteration */ - ckt->CKTtroubleElt = (GENinstance *) here; + if (model->CSWiHysteresis > 0) { + if (i_ctrl > (model->CSWiThreshold + model->CSWiHysteresis)) { + current_state = REALLY_ON; + } else if (i_ctrl < (model->CSWiThreshold - model->CSWiHysteresis)) { + current_state = REALLY_OFF; + } else { + current_state = previous_state; + } + } else { + if (i_ctrl > (model->CSWiThreshold - model->CSWiHysteresis)) { + current_state = REALLY_ON; + } else if (i_ctrl < (model->CSWiThreshold + model->CSWiHysteresis)) { + current_state = REALLY_OFF; + } else { // in hysteresis... change value if going from low to hysteresis, or from hi to hysteresis. + // if previous state was in hysteresis, then don't change the state.. + if ((previous_state == HYST_OFF) || (previous_state == HYST_ON)) { + current_state = previous_state; + } else if (previous_state == REALLY_ON) { + current_state = HYST_OFF; + } else if (previous_state == REALLY_OFF) { + current_state = HYST_ON; + } else + internalerror("bad value for previous region in swload"); + } + } + + if(current_state != old_current_state) { + ckt->CKTnoncon++; /* ensure one more iteration */ + ckt->CKTtroubleElt = (GENinstance *) here; } } else if (ckt->CKTmode & (MODEINITTRAN|MODEINITPRED)) { - previous_state = *(ckt->CKTstate1 + here->CSWstate); - i_ctrl = *(ckt->CKTrhsOld + - here->CSWcontBranch); + if (model->CSWiHysteresis > 0) { + if (i_ctrl > (model->CSWiThreshold + model->CSWiHysteresis)) { + current_state = REALLY_ON; + } else if (i_ctrl < (model->CSWiThreshold - model->CSWiHysteresis)) { + current_state = REALLY_OFF; + } else { + current_state = previous_state; + } + } else { + if (i_ctrl > (model->CSWiThreshold - model->CSWiHysteresis)) { + current_state = REALLY_ON; + } else if (i_ctrl < (model->CSWiThreshold + model->CSWiHysteresis)) { + current_state = REALLY_OFF; + } else { // in hysteresis... change value if going from low to hysteresis, or from hi to hysteresis. + // if previous state was in hysteresis, then don't change the state.. + if ((previous_state == HYST_OFF) || (previous_state == HYST_ON)) { + current_state = previous_state; + } else if (previous_state == REALLY_ON) { + current_state = HYST_OFF; + } else if (previous_state == REALLY_OFF) { + current_state = HYST_ON; + } else + internalerror("bad value for previous region in cswload"); + } + } + } - if(i_ctrl > (model->CSWiThreshold+model->CSWiHysteresis)) { - current_state = 1; - } else if(i_ctrl < (model->CSWiThreshold - - model->CSWiHysteresis)) { - current_state = 0; - } else { - current_state = previous_state; - } - - if(current_state == 0) { - *(ckt->CKTstate0 + here->CSWstate) = 0.0; - } else { - *(ckt->CKTstate0 + here->CSWstate) = 1.0; - } - - } - - g_now = current_state?(model->CSWonConduct):(model->CSWoffConduct); + *(ckt->CKTstates[0] + here->CSWstate) = current_state; + *(ckt->CKTstates[1] + here->CSWstate) = previous_state; + if ((current_state == REALLY_ON) || (current_state == HYST_ON)) + g_now = model->CSWonConduct; + else + g_now = model->CSWoffConduct; here->CSWcond = g_now; *(here->CSWposPosptr) += g_now; diff --git a/src/spicelib/devices/csw/cswmpar.c b/src/spicelib/devices/csw/cswmpar.c index 5b4573c76..b7708f2be 100644 --- a/src/spicelib/devices/csw/cswmpar.c +++ b/src/spicelib/devices/csw/cswmpar.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Gordon Jacobs +Modified: 2001 Jon Englebert **********/ /* */ @@ -40,7 +41,8 @@ CSWmParam(param,value,inModel) break; case CSW_IHYS: /* take absolute value of hysteresis voltage */ - model->CSWiHysteresis = fabs(value->rValue); +// model->CSWiHysteresis = fabs(value->rValue); + model->CSWiHysteresis = value->rValue; model->CSWhystGiven = TRUE; break; default: diff --git a/src/spicelib/devices/csw/cswnoise.c b/src/spicelib/devices/csw/cswnoise.c index 34282a7aa..a47f696f4 100644 --- a/src/spicelib/devices/csw/cswnoise.c +++ b/src/spicelib/devices/csw/cswnoise.c @@ -7,7 +7,6 @@ Author: 1987 Gary W. Ng #include #include "cswdefs.h" #include "cktdefs.h" -#include "fteconst.h" #include "iferrmsg.h" #include "noisedef.h" #include "suffix.h" @@ -31,12 +30,12 @@ CSWnoise (mode, operation, genmodel, ckt, data, OnDens) int operation; GENmodel *genmodel; CKTcircuit *ckt; - register Ndata *data; + Ndata *data; double *OnDens; { CSWmodel *firstModel = (CSWmodel *) genmodel; - register CSWmodel *model; - register CSWinstance *inst; + CSWmodel *model; + CSWinstance *inst; char name[N_MXVLNTH]; double tempOutNoise; double tempInNoise; diff --git a/src/spicelib/devices/csw/cswpzld.c b/src/spicelib/devices/csw/cswpzld.c index fa588402b..89ec610da 100644 --- a/src/spicelib/devices/csw/cswpzld.c +++ b/src/spicelib/devices/csw/cswpzld.c @@ -18,7 +18,7 @@ Author: 1985 Gordon Jacobs int CSWpzLoad(inModel,ckt,s) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; SPcomplex *s; /* load the current values into the @@ -26,8 +26,8 @@ CSWpzLoad(inModel,ckt,s) * during AC analysis */ { - register CSWmodel *model = (CSWmodel*)inModel; - register CSWinstance *here; + CSWmodel *model = (CSWmodel*)inModel; + CSWinstance *here; double g_now; int current_state; diff --git a/src/spicelib/devices/csw/cswsetup.c b/src/spicelib/devices/csw/cswsetup.c index 79d84cb9e..0b18572a6 100644 --- a/src/spicelib/devices/csw/cswsetup.c +++ b/src/spicelib/devices/csw/cswsetup.c @@ -15,7 +15,7 @@ Author: 1985 Gordon Jacobs int CSWsetup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; CKTcircuit *ckt; int *states; @@ -24,8 +24,8 @@ CSWsetup(matrix,inModel,ckt,states) */ { - register CSWmodel *model = (CSWmodel*)inModel; - register CSWinstance *here; + CSWmodel *model = (CSWmodel*)inModel; + CSWinstance *here; /* loop through all the current source models */ for( ; model != NULL; model = model->CSWnextModel ) { diff --git a/src/spicelib/devices/dio/Makefile.am b/src/spicelib/devices/dio/Makefile.am index 600e63d84..6d96b7935 100644 --- a/src/spicelib/devices/dio/Makefile.am +++ b/src/spicelib/devices/dio/Makefile.am @@ -2,34 +2,36 @@ pkglib_LTLIBRARIES = libdio.la -libdio_la_SOURCES = \ - dio.c \ - dioacld.c \ - dioask.c \ - dioconv.c \ - diodefs.h \ - diodel.c \ - diodest.c \ - diodisto.c \ - diodset.c \ - dioext.h \ - diogetic.c \ - dioitf.h \ - dioload.c \ - diomask.c \ - diomdel.c \ - diompar.c \ - dionoise.c \ - dioparam.c \ - diopzld.c \ - diosacl.c \ - diosetup.c \ - diosload.c \ - diosprt.c \ - diosset.c \ - diosupd.c \ - diotemp.c \ - diotrunc.c +libdio_la_SOURCES = \ + dio.c \ + dioacld.c \ + dioask.c \ + dioconv.c \ + diodefs.h \ + diodel.c \ + diodest.c \ + diodisto.c \ + diodset.c \ + dioext.h \ + diogetic.c \ + dioinit.c \ + dioinit.h \ + dioitf.h \ + dioload.c \ + diomask.c \ + diomdel.c \ + diompar.c \ + dionoise.c \ + dioparam.c \ + diopzld.c \ + diosacl.c \ + diosetup.c \ + diosload.c \ + diosprt.c \ + diosset.c \ + diosupd.c \ + diotemp.c \ + diotrunc.c INCLUDES = -I$(top_srcdir)/src/include diff --git a/src/spicelib/devices/dio/dioacld.c b/src/spicelib/devices/dio/dioacld.c index d04911bfa..f2fa5db91 100644 --- a/src/spicelib/devices/dio/dioacld.c +++ b/src/spicelib/devices/dio/dioacld.c @@ -16,14 +16,14 @@ Author: 1985 Thomas L. Quarles int DIOacLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register DIOmodel *model = (DIOmodel*)inModel; + DIOmodel *model = (DIOmodel*)inModel; double gspr; double geq; double xceq; - register DIOinstance *here; + DIOinstance *here; /* loop through all the diode models */ for( ; model != NULL; model = model->DIOnextModel ) { diff --git a/src/spicelib/devices/dio/dioconv.c b/src/spicelib/devices/dio/dioconv.c index dac6f6b17..f8f4fd718 100644 --- a/src/spicelib/devices/dio/dioconv.c +++ b/src/spicelib/devices/dio/dioconv.c @@ -20,8 +20,8 @@ DIOconvTest(inModel,ckt) /* Check the devices for convergence */ { - register DIOmodel *model = (DIOmodel*)inModel; - register DIOinstance *here; + DIOmodel *model = (DIOmodel*)inModel; + DIOinstance *here; double delvd,vd,cdhat,cd; double tol; /* loop through all the diode models */ diff --git a/src/spicelib/devices/dio/diodisto.c b/src/spicelib/devices/dio/diodisto.c index 2f7385722..8de0ec718 100644 --- a/src/spicelib/devices/dio/diodisto.c +++ b/src/spicelib/devices/dio/diodisto.c @@ -14,7 +14,7 @@ Author: 1988 Jaijeet S Roychowdhury int DIOdisto(mode,genmodel,ckt) GENmodel *genmodel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int mode; /* assuming here that ckt->CKTomega has been initialised to @@ -32,7 +32,7 @@ DIOdisto(mode,genmodel,ckt) double r2h11x,i2h11x; double r2h1m2x,i2h1m2x; double temp, itemp; - register DIOinstance *here; + DIOinstance *here; if (mode == D_SETUP) return(DIOdSetup(model,ckt)); diff --git a/src/spicelib/devices/dio/diodset.c b/src/spicelib/devices/dio/diodset.c index d1dc69670..9c6e3637e 100644 --- a/src/spicelib/devices/dio/diodset.c +++ b/src/spicelib/devices/dio/diodset.c @@ -11,16 +11,13 @@ Author: 1988 Jaijeet S Roychowdhury #include "sperror.h" #include "suffix.h" -int -DIOdSetup(model,ckt) -register DIOmodel *model; -CKTcircuit *ckt; -/* actually load the current resistance value into the - * sparse matrix previously provided - */ +/* actually load the current resistance value into the sparse matrix + * previously provided */ +int +DIOdSetup(DIOmodel *model, CKTcircuit *ckt) { - register DIOinstance *here; + DIOinstance *here; double arg; double csat; /* area-scaled saturation current */ double czero; diff --git a/src/spicelib/devices/dio/dioext.h b/src/spicelib/devices/dio/dioext.h index eb2f91926..86109c14e 100644 --- a/src/spicelib/devices/dio/dioext.h +++ b/src/spicelib/devices/dio/dioext.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #ifdef __STDC__ @@ -29,6 +30,9 @@ extern int DIOtrunc(GENmodel*,CKTcircuit*,double*); extern int DIOdisto(int,GENmodel*,CKTcircuit*); extern int DIOnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); +extern int DIOdSetup(DIOmodel*,CKTcircuit*); + + #else /* stdc */ extern int DIOacLoad(); diff --git a/src/spicelib/devices/dio/dioitf.h b/src/spicelib/devices/dio/dioitf.h index b3f083ff2..be0e69139 100644 --- a/src/spicelib/devices/dio/dioitf.h +++ b/src/spicelib/devices/dio/dioitf.h @@ -1,103 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_dio - #ifndef DEV_DIO #define DEV_DIO -#include "dioext.h" -extern IFparm DIOpTable[ ]; -extern IFparm DIOmPTable[ ]; -extern char *DIOnames[ ]; -extern int DIOpTSize; -extern int DIOmPTSize; -extern int DIOnSize; -extern int DIOiSize; -extern int DIOmSize; - -SPICEdev DIOinfo = { - { - "Diode", - "Junction Diode model", - - &DIOnSize, - &DIOnSize, - DIOnames, - - &DIOpTSize, - DIOpTable, - - &DIOmPTSize, - DIOmPTable, - DEV_DEFAULT - }, - - DIOparam, - DIOmParam, - DIOload, - DIOsetup, - DIOunsetup, - DIOsetup, - DIOtemp, - DIOtrunc, - NULL, - DIOacLoad, - NULL, - DIOdestroy, -#ifdef DELETES - DIOmDelete, - DIOdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - DIOgetic, - DIOask, - DIOmAsk, -#ifdef AN_pz - DIOpzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ -#ifdef NEWCONV - DIOconvTest, -#else /* NEWCONV */ - NULL, -#endif /* NEWCONV */ - -#ifdef AN_sense2 - DIOsSetup, - DIOsLoad, - DIOsUpdate, - DIOsAcLoad, - DIOsPrint, - NULL, -#else /* AN_sense */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -#endif /* AN_sense */ -#ifdef AN_disto - DIOdisto, -#else /* AN_disto */ - NULL, -#endif /* AN_disto */ -#ifdef AN_noise - DIOnoise, -#else /* AN_noise */ - NULL, -#endif /* AN_noise */ - - &DIOiSize, - &DIOmSize - - -}; - +extern SPICEdev *get_dio_info(void); #endif -#endif diff --git a/src/spicelib/devices/dio/dioload.c b/src/spicelib/devices/dio/dioload.c index 497dc30c0..d1481d5b3 100644 --- a/src/spicelib/devices/dio/dioload.c +++ b/src/spicelib/devices/dio/dioload.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -21,8 +22,8 @@ DIOload(inModel,ckt) * sparse matrix previously provided */ { - register DIOmodel *model = (DIOmodel*)inModel; - register DIOinstance *here; + DIOmodel *model = (DIOmodel*)inModel; + DIOinstance *here; double arg; double capd; double cd; @@ -136,7 +137,6 @@ DIOload(inModel,ckt) /* * bypass if solution has not changed */ -#ifndef NOBYPASS if ((!(ckt->CKTmode & MODEINITPRED)) && (ckt->CKTbypass)) { tol=ckt->CKTvoltTol + ckt->CKTreltol* MAX(fabs(vd),fabs(*(ckt->CKTstate0 +here->DIOvoltage))); @@ -153,7 +153,7 @@ DIOload(inModel,ckt) } } } -#endif /* NOBYPASS */ + /* * limit new junction voltage */ @@ -177,7 +177,7 @@ next1: if (vd >= -3*vte) { evd = exp(vd/vte); cd = csat*(evd-1)+ckt->CKTgmin*vd; gd = csat*evd/vte+ckt->CKTgmin; - } else if((!(here->DIOtBrkdwnV))|| + } else if((!(model->DIObreakdownVoltageGiven)) || vd >= -here->DIOtBrkdwnV) { arg=3*vte/(vd*CONSTe); arg = arg * arg * arg; @@ -188,17 +188,17 @@ next1: if (vd >= -3*vte) { cd = -csat*evrev+ckt->CKTgmin*vd; gd=csat*evrev/vte + ckt->CKTgmin; } - if( ((ckt->CKTmode & (MODETRAN | MODEAC | MODEINITSMSIG)) || - (ckt->CKTmode & MODETRANOP)) && (ckt->CKTmode & MODEUIC) ) { + if ((ckt->CKTmode & (MODETRAN | MODEAC | MODEINITSMSIG)) || + ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) { /* * charge storage elements */ czero=here->DIOtJctCap*here->DIOarea; if (vd < here->DIOtDepCap){ - arg=1-vd/model->DIOjunctionPot; + arg=1-vd/here->DIOtJctPot; sarg=exp(-model->DIOgradingCoeff*log(arg)); *(ckt->CKTstate0 + here->DIOcapCharge) = - model->DIOtransitTime*cd+model->DIOjunctionPot* + model->DIOtransitTime*cd+here->DIOtJctPot* czero* (1-arg*sarg)/(1-model->DIOgradingCoeff); capd=model->DIOtransitTime*gd+czero*sarg; } else { @@ -206,11 +206,11 @@ next1: if (vd >= -3*vte) { *(ckt->CKTstate0 + here->DIOcapCharge) = model->DIOtransitTime*cd+czero*here->DIOtF1+czof2* (model->DIOf3*(vd-here->DIOtDepCap)+ - (model->DIOgradingCoeff/(model->DIOjunctionPot+ - model->DIOjunctionPot))*(vd*vd-here->DIOtDepCap* + (model->DIOgradingCoeff/(here->DIOtJctPot+ + here->DIOtJctPot))*(vd*vd-here->DIOtDepCap* here->DIOtDepCap)); capd=model->DIOtransitTime*gd+czof2*(model->DIOf3+ - model->DIOgradingCoeff*vd/model->DIOjunctionPot); + model->DIOgradingCoeff*vd/here->DIOtJctPot); } here->DIOcap = capd; @@ -272,15 +272,6 @@ next1: if (vd >= -3*vte) { if (Check == 1) { ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) here; -#ifndef NEWCONV - } else { - tol=ckt->CKTreltol* - MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol; - if (fabs(cdhat-cd) > tol) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; - } -#endif /* NEWCONV */ } } next2: *(ckt->CKTstate0 + here->DIOvoltage) = vd; diff --git a/src/spicelib/devices/dio/dionoise.c b/src/spicelib/devices/dio/dionoise.c index 83a3dafae..624faa0ef 100644 --- a/src/spicelib/devices/dio/dionoise.c +++ b/src/spicelib/devices/dio/dionoise.c @@ -7,7 +7,6 @@ Author: 1987 Gary W. Ng #include #include "diodefs.h" #include "cktdefs.h" -#include "fteconst.h" #include "iferrmsg.h" #include "noisedef.h" #include "suffix.h" @@ -31,12 +30,12 @@ DIOnoise (mode, operation, genmodel, ckt, data, OnDens) int operation; GENmodel *genmodel; CKTcircuit *ckt; - register Ndata *data; + Ndata *data; double *OnDens; { DIOmodel *firstModel = (DIOmodel *) genmodel; - register DIOmodel *model; - register DIOinstance *inst; + DIOmodel *model; + DIOinstance *inst; char name[N_MXVLNTH]; double tempOnoise; double tempInoise; diff --git a/src/spicelib/devices/dio/diopzld.c b/src/spicelib/devices/dio/diopzld.c index 1a9f4a6e9..4f7dff7a4 100644 --- a/src/spicelib/devices/dio/diopzld.c +++ b/src/spicelib/devices/dio/diopzld.c @@ -17,14 +17,14 @@ Author: 1985 Thomas L. Quarles int DIOpzLoad(inModel,ckt,s) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; SPcomplex *s; { - register DIOmodel *model = (DIOmodel*)inModel; + DIOmodel *model = (DIOmodel*)inModel; double gspr; double geq; double xceq; - register DIOinstance *here; + DIOinstance *here; /* loop through all the diode models */ for( ; model != NULL; model = model->DIOnextModel ) { diff --git a/src/spicelib/devices/dio/diosacl.c b/src/spicelib/devices/dio/diosacl.c index cef623b93..3e46bd455 100644 --- a/src/spicelib/devices/dio/diosacl.c +++ b/src/spicelib/devices/dio/diosacl.c @@ -24,8 +24,8 @@ DIOsAcLoad(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { - register DIOmodel *model = (DIOmodel*)inModel; - register DIOinstance *here; + DIOmodel *model = (DIOmodel*)inModel; + DIOinstance *here; double SaveState[5]; int error; int i; diff --git a/src/spicelib/devices/dio/diosetup.c b/src/spicelib/devices/dio/diosetup.c index 6d201853e..7c8d08a40 100644 --- a/src/spicelib/devices/dio/diosetup.c +++ b/src/spicelib/devices/dio/diosetup.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* load the diode structure with those pointers needed later @@ -17,13 +18,13 @@ Author: 1985 Thomas L. Quarles int DIOsetup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; CKTcircuit *ckt; int *states; { - register DIOmodel *model = (DIOmodel*)inModel; - register DIOinstance *here; + DIOmodel *model = (DIOmodel*)inModel; + DIOinstance *here; int error; CKTnode *tmp; @@ -86,9 +87,21 @@ matrixpointers: if(model->DIOresist == 0) { here->DIOposPrimeNode = here->DIOposNode; } else if(here->DIOposPrimeNode == 0) { + + CKTnode *tmpNode; + IFuid tmpName; + error = CKTmkVolt(ckt,&tmp,here->DIOname,"internal"); if(error) return(error); here->DIOposPrimeNode = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } } /* macro to make elements with built in test for out of memory */ @@ -114,7 +127,6 @@ DIOunsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM DIOmodel *model; DIOinstance *here; @@ -133,6 +145,5 @@ DIOunsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/dio/diosload.c b/src/spicelib/devices/dio/diosload.c index 937ae39be..864a8a3a5 100644 --- a/src/spicelib/devices/dio/diosload.c +++ b/src/spicelib/devices/dio/diosload.c @@ -23,8 +23,8 @@ DIOsLoad(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { - register DIOmodel *model = (DIOmodel*)inModel; - register DIOinstance *here; + DIOmodel *model = (DIOmodel*)inModel; + DIOinstance *here; int iparmno; int error; int i; diff --git a/src/spicelib/devices/dio/diosprt.c b/src/spicelib/devices/dio/diosprt.c index 1db6b8937..280db644a 100644 --- a/src/spicelib/devices/dio/diosprt.c +++ b/src/spicelib/devices/dio/diosprt.c @@ -21,10 +21,10 @@ Author: 1985 Thomas L. Quarles void DIOsPrint(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register DIOmodel *model = (DIOmodel*)inModel; - register DIOinstance *here; + DIOmodel *model = (DIOmodel*)inModel; + DIOinstance *here; printf("DIOS-----------------\n"); /* loop through all the diode models */ diff --git a/src/spicelib/devices/dio/diosset.c b/src/spicelib/devices/dio/diosset.c index 9e6bdaefd..afe8f7325 100644 --- a/src/spicelib/devices/dio/diosset.c +++ b/src/spicelib/devices/dio/diosset.c @@ -20,11 +20,11 @@ Author: 1985 Thomas L. Quarles int DIOsSetup(info,inModel) - register SENstruct *info; + SENstruct *info; GENmodel *inModel; { - register DIOmodel *model = (DIOmodel*)inModel; - register DIOinstance *here; + DIOmodel *model = (DIOmodel*)inModel; + DIOinstance *here; /* loop through all the diode models */ for( ; model != NULL; model = model->DIOnextModel ) { diff --git a/src/spicelib/devices/dio/diosupd.c b/src/spicelib/devices/dio/diosupd.c index 9e939408c..aa76ef402 100644 --- a/src/spicelib/devices/dio/diosupd.c +++ b/src/spicelib/devices/dio/diosupd.c @@ -19,10 +19,10 @@ Author: 1985 Thomas L. Quarles int DIOsUpdate(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register DIOmodel *model = (DIOmodel*)inModel; - register DIOinstance *here; + DIOmodel *model = (DIOmodel*)inModel; + DIOinstance *here; int iparmno; double sposprm; double sneg; diff --git a/src/spicelib/devices/dio/diotemp.c b/src/spicelib/devices/dio/diotemp.c index d93a90186..742b7fda0 100644 --- a/src/spicelib/devices/dio/diotemp.c +++ b/src/spicelib/devices/dio/diotemp.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* perform the temperature update to the diode */ @@ -16,9 +17,9 @@ Author: 1985 Thomas L. Quarles int DIOtemp(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register DIOmodel *model = (DIOmodel*)inModel; + DIOmodel *model = (DIOmodel*)inModel; double xfc; double vte; double cbv; @@ -27,8 +28,8 @@ DIOtemp(inModel,ckt) double tol; double vt; double vtnom; - register DIOinstance *here; - register int iter; + DIOinstance *here; + int iter; char *emsg; /* loop through all the diode models */ @@ -111,7 +112,10 @@ DIOtemp(inModel,ckt) here->DIOtJctPot; /* and Vcrit */ vte=model->DIOemissionCoeff*vt; - here->DIOtVcrit=vte*log(vte/(CONSTroot2*here->DIOtSatCur)); + + here->DIOtVcrit=vte* + log(vte/(CONSTroot2*here->DIOtSatCur*here->DIOarea)); + /* and now to copute the breakdown voltage, again, using * temperature adjusted basic parameters */ if (model->DIObreakdownVoltageGiven){ @@ -121,12 +125,12 @@ DIOtemp(inModel,ckt) emsg = MALLOC(100); if(emsg == (char *)NULL) return(E_NOMEM); (void)sprintf(emsg, - "%%s: breakdown current increased to %g to resolve incompatability", + "%%s: breakdown current increased to %g to resolve", cbv); (*(SPfrontEnd->IFerror))(ERR_WARNING,emsg,&(here->DIOname)); FREE(emsg); (*(SPfrontEnd->IFerror))(ERR_WARNING, - "with specified saturation current",(IFuid*)NULL); + "incompatibility with specified saturation current",(IFuid*)NULL); xbv=model->DIObreakdownVoltage; } else { tol=ckt->CKTreltol*cbv; diff --git a/src/spicelib/devices/dio/diotrunc.c b/src/spicelib/devices/dio/diotrunc.c index 2e165d78f..1d4b805a3 100644 --- a/src/spicelib/devices/dio/diotrunc.c +++ b/src/spicelib/devices/dio/diotrunc.c @@ -16,11 +16,11 @@ Author: 1985 Thomas L. Quarles int DIOtrunc(inModel,ckt,timeStep) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; double *timeStep; { - register DIOmodel *model = (DIOmodel*)inModel; - register DIOinstance *here; + DIOmodel *model = (DIOmodel*)inModel; + DIOinstance *here; for( ; model != NULL; model = model->DIOnextModel) { for(here=model->DIOinstances;here!=NULL;here = here->DIOnextInstance){ diff --git a/src/spicelib/devices/ind/Makefile.am b/src/spicelib/devices/ind/Makefile.am index 322388b18..e864492c2 100644 --- a/src/spicelib/devices/ind/Makefile.am +++ b/src/spicelib/devices/ind/Makefile.am @@ -2,36 +2,38 @@ pkglib_LTLIBRARIES = libind.la -libind_la_SOURCES = \ - ind.c \ - indacld.c \ - indask.c \ - inddefs.h \ - inddel.c \ - inddest.c \ - indext.h \ - inditf.h \ - indload.c \ - indmdel.c \ - indparam.c \ - indpzld.c \ - indsacl.c \ - indsetup.c \ - indsload.c \ - indsprt.c \ - indsset.c \ - indsupd.c \ - indtrunc.c \ - mutacld.c \ - mutask.c \ - mutdel.c \ - mutdest.c \ - mutmdel.c \ - mutparam.c \ - mutpzld.c \ - mutsetup.c \ - mutsprt.c \ - mutsset.c +libind_la_SOURCES = \ + ind.c \ + indacld.c \ + indask.c \ + inddefs.h \ + inddel.c \ + inddest.c \ + indext.h \ + indinit.c \ + indinit.h \ + inditf.h \ + indload.c \ + indmdel.c \ + indparam.c \ + indpzld.c \ + indsacl.c \ + indsetup.c \ + indsload.c \ + indsprt.c \ + indsset.c \ + indsupd.c \ + indtrunc.c \ + mutacld.c \ + mutask.c \ + mutdel.c \ + mutdest.c \ + mutmdel.c \ + mutparam.c \ + mutpzld.c \ + mutsetup.c \ + mutsprt.c \ + mutsset.c diff --git a/src/spicelib/devices/ind/indacld.c b/src/spicelib/devices/ind/indacld.c index 34270665a..ef3a3e3e7 100644 --- a/src/spicelib/devices/ind/indacld.c +++ b/src/spicelib/devices/ind/indacld.c @@ -16,11 +16,11 @@ Author: 1985 Thomas L. Quarles int INDacLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register INDmodel *model = (INDmodel*)inModel; + INDmodel *model = (INDmodel*)inModel; double val; - register INDinstance *here; + INDinstance *here; for( ; model != NULL; model = model->INDnextModel) { for( here = model->INDinstances;here != NULL; diff --git a/src/spicelib/devices/ind/indext.h b/src/spicelib/devices/ind/indext.h index 02687490a..2c08067de 100644 --- a/src/spicelib/devices/ind/indext.h +++ b/src/spicelib/devices/ind/indext.h @@ -2,8 +2,9 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles **********/ +#ifndef _INDEXT_H +#define _INDEXT_H -#ifdef __STDC__ extern int INDacLoad(GENmodel*,CKTcircuit*); extern int INDask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); extern int INDdelete(GENmodel*,IFuid,GENinstance**); @@ -20,28 +21,7 @@ extern int INDsUpdate(GENmodel*,CKTcircuit*); extern int INDsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int INDunsetup(GENmodel*,CKTcircuit*); extern int INDtrunc(GENmodel*,CKTcircuit*,double*); -#else /* stdc */ -extern int INDacLoad(); -extern int INDask(); -extern int INDdelete(); -extern void INDdestroy(); -extern int INDload(); -extern int INDmDelete(); -extern int INDparam(); -extern int INDpzLoad(); -extern int INDsAcLoad(); -extern int INDsLoad(); -extern void INDsPrint(); -extern int INDsSetup(); -extern int INDsUpdate(); -extern int INDsetup(); -extern int INDunsetup(); -extern int INDtrunc(); -#endif /* stdc */ -#ifdef MUTUAL - -#ifdef __STDC__ extern int MUTacLoad(GENmodel*,CKTcircuit*); extern int MUTask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); extern int MUTdelete(GENmodel*,IFuid,GENinstance**); @@ -52,17 +32,5 @@ extern int MUTpzLoad(GENmodel*,CKTcircuit*,SPcomplex*); extern void MUTsPrint(GENmodel*,CKTcircuit*); extern int MUTsSetup(SENstruct*,GENmodel*); extern int MUTsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); -#else /* stdc */ -extern int MUTacLoad(); -extern int MUTask(); -extern int MUTdelete(); -extern void MUTdestroy(); -extern int MUTmDelete(); -extern int MUTparam(); -extern int MUTpzLoad(); -extern void MUTsPrint(); -extern int MUTsSetup(); -extern int MUTsetup(); -#endif /* stdc */ #endif diff --git a/src/spicelib/devices/ind/inditf.h b/src/spicelib/devices/ind/inditf.h index faeaae5df..6bde9842d 100644 --- a/src/spicelib/devices/ind/inditf.h +++ b/src/spicelib/devices/ind/inditf.h @@ -1,163 +1,10 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_ind - #ifndef DEV_IND #define DEV_IND -#define MUTUAL - -#include "indext.h" -extern IFparm INDpTable[ ]; -extern char *INDnames[ ]; -extern int INDpTSize; -extern int INDnSize; -extern int INDiSize; -extern int INDmSize; - -SPICEdev INDinfo = { - { - "Inductor", - "Inductors", - - &INDnSize, - &INDnSize, - INDnames, - - &INDpTSize, - INDpTable, - - 0, - NULL, - 0 - }, - - INDparam, - NULL, - INDload, - INDsetup, - INDunsetup, - INDsetup, - NULL, - INDtrunc, - NULL, - INDacLoad, - NULL, - INDdestroy, -#ifdef DELETES - INDmDelete, - INDdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - NULL, - INDask, - NULL, -#ifdef AN_pz - INDpzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ - NULL, -#ifdef AN_sense2 - INDsSetup, - INDsLoad, - INDsUpdate, - INDsAcLoad, - INDsPrint, - NULL, -#else /* AN_sense2 */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -#endif /* AN_sense */ - NULL, /* DISTO */ - NULL, /* NOISE */ - - &INDiSize, - &INDmSize - -}; - -#ifdef MUTUAL -extern IFparm MUTpTable[ ]; -extern int MUTpTSize; -extern int MUTiSize; -extern int MUTmSize; - -SPICEdev MUTinfo = { - { - "mutual", - "Mutual inductors", - 0, /* term count */ - 0, /* term count */ - NULL, - - &MUTpTSize, - MUTpTable, - - 0, - NULL, - 0 - }, - - MUTparam, - NULL, - NULL,/* load handled by INDload */ - MUTsetup, - NULL, - MUTsetup, - NULL, - NULL, - NULL, - MUTacLoad, - NULL, - MUTdestroy, -#ifdef DELETES - MUTmDelete, - MUTdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - NULL, - MUTask, - NULL, -#ifdef AN_pz - MUTpzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ - NULL, -#ifdef AN_sense - MUTsSetup, - NULL, - NULL, - NULL, - MUTsPrint, - NULL, -#else /* AN_sense */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -#endif /* AN_sense */ - NULL, /* DISTO */ - NULL, /* NOISE */ - - &MUTiSize, - &MUTmSize - -}; - -#endif /*MUTUAL*/ +SPICEdev *get_ind_info(void); +SPICEdev *get_mut_info(void); #endif -#endif diff --git a/src/spicelib/devices/ind/indload.c b/src/spicelib/devices/ind/indload.c index df26dfb26..a96301fbc 100644 --- a/src/spicelib/devices/ind/indload.c +++ b/src/spicelib/devices/ind/indload.c @@ -18,16 +18,16 @@ Author: 1985 Thomas L. Quarles int INDload(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register INDmodel *model = (INDmodel*)inModel; - register INDinstance *here; + INDmodel *model = (INDmodel*)inModel; + INDinstance *here; double veq; double req; int error; #ifdef MUTUAL - register MUTinstance *muthere; - register MUTmodel *mutmodel; + MUTinstance *muthere; + MUTmodel *mutmodel; int ktype; int itype; #endif diff --git a/src/spicelib/devices/ind/indpzld.c b/src/spicelib/devices/ind/indpzld.c index b195c304b..d81c63198 100644 --- a/src/spicelib/devices/ind/indpzld.c +++ b/src/spicelib/devices/ind/indpzld.c @@ -21,9 +21,9 @@ INDpzLoad(inModel,ckt,s) CKTcircuit *ckt; SPcomplex *s; { - register INDmodel *model = (INDmodel*)inModel; + INDmodel *model = (INDmodel*)inModel; double val; - register INDinstance *here; + INDinstance *here; for( ; model != NULL; model = model->INDnextModel) { for( here = model->INDinstances;here != NULL; diff --git a/src/spicelib/devices/ind/indsacl.c b/src/spicelib/devices/ind/indsacl.c index 76dbeda9a..289538610 100644 --- a/src/spicelib/devices/ind/indsacl.c +++ b/src/spicelib/devices/ind/indsacl.c @@ -18,14 +18,14 @@ Author: 1985 Thomas L. Quarles int INDsAcLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register INDmodel *model = (INDmodel*)inModel; - register INDinstance *here; + INDmodel *model = (INDmodel*)inModel; + INDinstance *here; double cind,icind,val,ival; #ifdef MUTUAL - register MUTinstance *muthere; - register MUTmodel *mutmodel; + MUTinstance *muthere; + MUTmodel *mutmodel; double cind1; double icind1; double cind2; diff --git a/src/spicelib/devices/ind/indsetup.c b/src/spicelib/devices/ind/indsetup.c index 04e1965f0..104bf3567 100644 --- a/src/spicelib/devices/ind/indsetup.c +++ b/src/spicelib/devices/ind/indsetup.c @@ -13,7 +13,7 @@ Author: 1985 Thomas L. Quarles int INDsetup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; CKTcircuit *ckt; int *states; @@ -21,8 +21,8 @@ INDsetup(matrix,inModel,ckt,states) * for fast matrix loading */ { - register INDmodel *model = (INDmodel*)inModel; - register INDinstance *here; + INDmodel *model = (INDmodel*)inModel; + INDinstance *here; int error; CKTnode *tmp; @@ -68,7 +68,6 @@ INDunsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM INDmodel *model; INDinstance *here; @@ -84,6 +83,5 @@ INDunsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/ind/indsload.c b/src/spicelib/devices/ind/indsload.c index 7c23b4349..3fd027242 100644 --- a/src/spicelib/devices/ind/indsload.c +++ b/src/spicelib/devices/ind/indsload.c @@ -18,10 +18,10 @@ Author: 1985 Thomas L. Quarles int INDsLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register INDmodel *model = (INDmodel*)inModel; - register INDinstance *here; + INDmodel *model = (INDmodel*)inModel; + INDinstance *here; int iparmno; double cind; double Osxp; @@ -30,8 +30,8 @@ INDsLoad(inModel,ckt) SENstruct *info; #ifdef MUTUAL - register MUTinstance *muthere; - register MUTmodel *mutmodel; + MUTinstance *muthere; + MUTmodel *mutmodel; double cind1; double cind2; double rootl1; diff --git a/src/spicelib/devices/ind/indsprt.c b/src/spicelib/devices/ind/indsprt.c index afc5b6be6..2de24a336 100644 --- a/src/spicelib/devices/ind/indsprt.c +++ b/src/spicelib/devices/ind/indsprt.c @@ -18,10 +18,10 @@ Author: 1985 Thomas L. Quarles void INDsPrint(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { - register INDmodel *model = (INDmodel*)inModel; - register INDinstance *here; + INDmodel *model = (INDmodel*)inModel; + INDinstance *here; printf("INDUCTORS----------\n"); /* loop through all the inductor models */ diff --git a/src/spicelib/devices/ind/indsset.c b/src/spicelib/devices/ind/indsset.c index c5d1cb785..c1e036742 100644 --- a/src/spicelib/devices/ind/indsset.c +++ b/src/spicelib/devices/ind/indsset.c @@ -17,11 +17,11 @@ Author: 1985 Thomas L. Quarles int INDsSetup(info,inModel) - register SENstruct *info; + SENstruct *info; GENmodel *inModel; { - register INDmodel *model = (INDmodel*)inModel; - register INDinstance *here; + INDmodel *model = (INDmodel*)inModel; + INDinstance *here; /* loop through all the inductor models */ for( ; model != NULL; model = model->INDnextModel ) { diff --git a/src/spicelib/devices/ind/indsupd.c b/src/spicelib/devices/ind/indsupd.c index 79fdc0c2b..c9e8fda46 100644 --- a/src/spicelib/devices/ind/indsupd.c +++ b/src/spicelib/devices/ind/indsupd.c @@ -16,10 +16,10 @@ Author: 1985 Thomas L. Quarles int INDsUpdate(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register INDmodel *model = (INDmodel*)inModel; - register INDinstance *here; + INDmodel *model = (INDmodel*)inModel; + INDinstance *here; double cind; double sxp; double s1; @@ -30,8 +30,8 @@ INDsUpdate(inModel,ckt) double dummy2; SENstruct *info; #ifdef MUTUAL - register MUTinstance *muthere; - register MUTmodel *mutmodel; + MUTinstance *muthere; + MUTmodel *mutmodel; double sxp1; double sxp2; double cind1,cind2; diff --git a/src/spicelib/devices/ind/indtrunc.c b/src/spicelib/devices/ind/indtrunc.c index e97f29b25..c3a4cb26f 100644 --- a/src/spicelib/devices/ind/indtrunc.c +++ b/src/spicelib/devices/ind/indtrunc.c @@ -16,11 +16,11 @@ Author: 1985 Thomas L. Quarles int INDtrunc(inModel,ckt,timeStep) GENmodel *inModel; - register CKTcircuit *ckt; - register double *timeStep; + CKTcircuit *ckt; + double *timeStep; { - register INDmodel *model = (INDmodel*)inModel; - register INDinstance *here; + INDmodel *model = (INDmodel*)inModel; + INDinstance *here; for( ; model!= NULL; model = model->INDnextModel) { for(here = model->INDinstances ; here != NULL ; here = here->INDnextInstance) { diff --git a/src/spicelib/devices/ind/mutacld.c b/src/spicelib/devices/ind/mutacld.c index 6ef7121ea..47602fbd3 100644 --- a/src/spicelib/devices/ind/mutacld.c +++ b/src/spicelib/devices/ind/mutacld.c @@ -17,11 +17,11 @@ Author: 1985 Thomas L. Quarles int MUTacLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register MUTmodel *model = (MUTmodel*)inModel; + MUTmodel *model = (MUTmodel*)inModel; double val; - register MUTinstance *here; + MUTinstance *here; for( ; model != NULL; model = model->MUTnextModel) { for( here = model->MUTinstances;here != NULL; diff --git a/src/spicelib/devices/ind/mutpzld.c b/src/spicelib/devices/ind/mutpzld.c index 983288eda..8b3053dcd 100644 --- a/src/spicelib/devices/ind/mutpzld.c +++ b/src/spicelib/devices/ind/mutpzld.c @@ -20,11 +20,11 @@ int MUTpzLoad(inModel,ckt,s) GENmodel *inModel; CKTcircuit *ckt; - register SPcomplex *s; + SPcomplex *s; { - register MUTmodel *model = (MUTmodel*)inModel; + MUTmodel *model = (MUTmodel*)inModel; double val; - register MUTinstance *here; + MUTinstance *here; for( ; model != NULL; model = model->MUTnextModel) { for( here = model->MUTinstances;here != NULL; diff --git a/src/spicelib/devices/ind/mutsetup.c b/src/spicelib/devices/ind/mutsetup.c index 16d67a50d..6bce9baf5 100644 --- a/src/spicelib/devices/ind/mutsetup.c +++ b/src/spicelib/devices/ind/mutsetup.c @@ -21,13 +21,13 @@ Author: 1985 Thomas L. Quarles /*ARGSUSED*/ int MUTsetup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; CKTcircuit *ckt; int *states; { - register MUTmodel *model = (MUTmodel*)inModel; - register MUTinstance *here; + MUTmodel *model = (MUTmodel*)inModel; + MUTinstance *here; int ktype; int error; diff --git a/src/spicelib/devices/ind/mutsprt.c b/src/spicelib/devices/ind/mutsprt.c index 7bd8035e6..f70466afb 100644 --- a/src/spicelib/devices/ind/mutsprt.c +++ b/src/spicelib/devices/ind/mutsprt.c @@ -23,8 +23,8 @@ MUTsPrint(inModel,ckt) GENmodel *inModel; CKTcircuit* ckt; { - register MUTmodel *model = (MUTmodel*)inModel; - register MUTinstance *here; + MUTmodel *model = (MUTmodel*)inModel; + MUTinstance *here; printf("MUTUAL INDUCTORS-----------------\n"); /* loop through all the inductor models */ diff --git a/src/spicelib/devices/ind/mutsset.c b/src/spicelib/devices/ind/mutsset.c index e264dec0b..fafcdecb2 100644 --- a/src/spicelib/devices/ind/mutsset.c +++ b/src/spicelib/devices/ind/mutsset.c @@ -20,11 +20,11 @@ Author: 1985 Thomas L. Quarles /*ARGSUSED*/ int MUTsSetup(info,inModel) - register SENstruct *info; + SENstruct *info; GENmodel *inModel; { - register MUTmodel *model = (MUTmodel*)inModel; - register MUTinstance *here; + MUTmodel *model = (MUTmodel*)inModel; + MUTinstance *here; /* loop through all the inductor models */ for( ; model != NULL; model = model->MUTnextModel ) { diff --git a/src/spicelib/devices/isrc/Makefile.am b/src/spicelib/devices/isrc/Makefile.am index 0c691535b..19a4882f1 100644 --- a/src/spicelib/devices/isrc/Makefile.am +++ b/src/spicelib/devices/isrc/Makefile.am @@ -2,20 +2,22 @@ pkglib_LTLIBRARIES = libisrc.la -libisrc_la_SOURCES = \ - isrc.c \ - isrcacct.c \ - isrcacld.c \ - isrcask.c \ - isrcdefs.h \ - isrcdel.c \ - isrcdest.c \ - isrcext.h \ - isrcitf.h \ - isrcload.c \ - isrcmdel.c \ - isrcpar.c \ - isrctemp.c +libisrc_la_SOURCES = \ + isrc.c \ + isrcacct.c \ + isrcacld.c \ + isrcask.c \ + isrcdefs.h \ + isrcdel.c \ + isrcdest.c \ + isrcext.h \ + isrcinit.c \ + isrcinit.h \ + isrcitf.h \ + isrcload.c \ + isrcmdel.c \ + isrcpar.c \ + isrctemp.c diff --git a/src/spicelib/devices/isrc/isrcacct.c b/src/spicelib/devices/isrc/isrcacct.c index e0bcaa851..62794b451 100644 --- a/src/spicelib/devices/isrc/isrcacct.c +++ b/src/spicelib/devices/isrc/isrcacct.c @@ -13,12 +13,12 @@ Author: 1985 Thomas L. Quarles int ISRCaccept(ckt,inModel) - register CKTcircuit *ckt; + CKTcircuit *ckt; GENmodel *inModel; /* set up the breakpoint table. */ { - register ISRCmodel *model = (ISRCmodel*)inModel; - register ISRCinstance *here; + ISRCmodel *model = (ISRCmodel*)inModel; + ISRCinstance *here; int error; /* loop through all the voltage source models */ @@ -134,7 +134,7 @@ ISRCaccept(ckt,inModel) } break; case PWL: { - register int i; + int i; if(ckt->CKTtime < *(here->ISRCcoeffs)) { if(ckt->CKTbreak) { error = CKTsetBreak(ckt,*(here->ISRCcoeffs)); diff --git a/src/spicelib/devices/isrc/isrcacld.c b/src/spicelib/devices/isrc/isrcacld.c index 82b79b61b..6db0d79b5 100644 --- a/src/spicelib/devices/isrc/isrcacld.c +++ b/src/spicelib/devices/isrc/isrcacld.c @@ -13,10 +13,10 @@ Author: 1985 Thomas L. Quarles int ISRCacLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register ISRCmodel *model = (ISRCmodel*)inModel; - register ISRCinstance *here; + ISRCmodel *model = (ISRCmodel*)inModel; + ISRCinstance *here; for( ; model != NULL; model = model->ISRCnextModel ) { diff --git a/src/spicelib/devices/isrc/isrcitf.h b/src/spicelib/devices/isrc/isrcitf.h index da46bc780..c33e117c9 100644 --- a/src/spicelib/devices/isrc/isrcitf.h +++ b/src/spicelib/devices/isrc/isrcitf.h @@ -1,73 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_isrc - #ifndef DEV_ISRC #define DEV_ISRC -#include "isrcext.h" -extern IFparm ISRCpTable[ ]; -extern char *ISRCnames[ ]; -extern int ISRCpTSize; -extern int ISRCnSize; -extern int ISRCiSize; -extern int ISRCmSize; - -SPICEdev ISRCinfo = { - { - "Isource", - "Independent current source", - - &ISRCnSize, - &ISRCnSize, - ISRCnames, - - &ISRCpTSize, - ISRCpTable, - - 0, - NULL, - DEV_DEFAULT - }, - - ISRCparam, - NULL, - ISRCload, - NULL, - NULL, - NULL, - ISRCtemp, - NULL, - NULL, - ISRCacLoad, - ISRCaccept, - ISRCdestroy, -#ifdef DELETES - ISRCmDelete, - ISRCdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - NULL, - ISRCask, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, /* DISTO */ - NULL, /* NOISE */ - - &ISRCiSize, - &ISRCmSize -}; - +extern SPICEdev *get_isrc_info(void); #endif -#endif diff --git a/src/spicelib/devices/isrc/isrcload.c b/src/spicelib/devices/isrc/isrcload.c index 2fe5a344b..9652e0171 100644 --- a/src/spicelib/devices/isrc/isrcload.c +++ b/src/spicelib/devices/isrc/isrcload.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 Alansfixes **********/ #include "ngspice.h" @@ -14,13 +15,13 @@ Author: 1985 Thomas L. Quarles int ISRCload(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* actually load the current current value into the * sparse matrix previously provided */ { - register ISRCmodel *model = (ISRCmodel*)inModel; - register ISRCinstance *here; + ISRCmodel *model = (ISRCmodel*)inModel; + ISRCinstance *here; double value; double time; @@ -160,7 +161,7 @@ ISRCload(inModel,ckt) value = here->ISRCdcValue * ckt->CKTsrcFact; break; case PWL: { - register int i; + int i; if(time< *(here->ISRCcoeffs)) { value = *(here->ISRCcoeffs + 1) ; break; @@ -187,6 +188,7 @@ ISRCload(inModel,ckt) } } loadDone: + if (ckt->CKTmode & MODETRANOP) value *= ckt->CKTsrcFact; *(ckt->CKTrhs + (here->ISRCposNode)) += value; *(ckt->CKTrhs + (here->ISRCnegNode)) -= value; } diff --git a/src/spicelib/devices/isrc/isrcpar.c b/src/spicelib/devices/isrc/isrcpar.c index 9ccc71be3..84fd48a70 100644 --- a/src/spicelib/devices/isrc/isrcpar.c +++ b/src/spicelib/devices/isrc/isrcpar.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* */ @@ -21,6 +22,8 @@ ISRCparam(param,value,inst,select) GENinstance *inst; IFvalue *select; { + +int i; ISRCinstance *here = (ISRCinstance*)inst; switch(param) { case ISRC_DC: @@ -83,6 +86,15 @@ ISRCparam(param,value,inst,select) here->ISRCcoeffs = value->v.vec.rVec; here->ISRCfunctionOrder = value->v.numValue; here->ISRCcoeffsGiven = TRUE; + + for (i=0;i<((here->ISRCfunctionOrder/2)-1);i++) { + if (*(here->ISRCcoeffs+2*(i+1))<=*(here->ISRCcoeffs+2*i)) { + fprintf(stderr, "Warning : current source %s", + here->ISRCname); + fprintf(stderr, " has non-increasing PWL time points.\n"); + } + } + break; case ISRC_SFFM: if(value->v.numValue <2) return(E_BADPARM); diff --git a/src/spicelib/devices/isrc/isrctemp.c b/src/spicelib/devices/isrc/isrctemp.c index 94ea5207c..a8a26f16b 100644 --- a/src/spicelib/devices/isrc/isrctemp.c +++ b/src/spicelib/devices/isrc/isrctemp.c @@ -17,8 +17,8 @@ ISRCtemp(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { - register ISRCmodel *model = (ISRCmodel*)inModel; - register ISRCinstance *here; + ISRCmodel *model = (ISRCmodel*)inModel; + ISRCinstance *here; double radians; for( ; model != NULL; model = model->ISRCnextModel ) { diff --git a/src/spicelib/devices/jfet/Makefile.am b/src/spicelib/devices/jfet/Makefile.am index 5f5129403..fb69c4940 100644 --- a/src/spicelib/devices/jfet/Makefile.am +++ b/src/spicelib/devices/jfet/Makefile.am @@ -2,28 +2,30 @@ pkglib_LTLIBRARIES = libjfet.la -libjfet_la_SOURCES = \ - jfet.c \ - jfetacld.c \ - jfetask.c \ - jfetdefs.h \ - jfetdel.c \ - jfetdest.c \ - jfetdist.c \ - jfetdset.c \ - jfetext.h \ - jfetic.c \ - jfetitf.h \ - jfetload.c \ - jfetmask.c \ - jfetmdel.c \ - jfetmpar.c \ - jfetnoi.c \ - jfetpar.c \ - jfetpzld.c \ - jfetset.c \ - jfettemp.c \ - jfettrun.c +libjfet_la_SOURCES = \ + jfet.c \ + jfetacld.c \ + jfetask.c \ + jfetdefs.h \ + jfetdel.c \ + jfetdest.c \ + jfetdist.c \ + jfetdset.c \ + jfetext.h \ + jfetic.c \ + jfetinit.c \ + jfetinit.h \ + jfetitf.h \ + jfetload.c \ + jfetmask.c \ + jfetmdel.c \ + jfetmpar.c \ + jfetnoi.c \ + jfetpar.c \ + jfetpzld.c \ + jfetset.c \ + jfettemp.c \ + jfettrun.c diff --git a/src/spicelib/devices/jfet/jfetacld.c b/src/spicelib/devices/jfet/jfetacld.c index 151fe9a6b..86aab0d6f 100644 --- a/src/spicelib/devices/jfet/jfetacld.c +++ b/src/spicelib/devices/jfet/jfetacld.c @@ -16,10 +16,10 @@ Author: 1985 Thomas L. Quarles int JFETacLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register JFETmodel *model = (JFETmodel*)inModel; - register JFETinstance *here; + JFETmodel *model = (JFETmodel*)inModel; + JFETinstance *here; double gdpr; double gspr; double gm; diff --git a/src/spicelib/devices/jfet/jfetdist.c b/src/spicelib/devices/jfet/jfetdist.c index 0df391a14..522eb6a27 100644 --- a/src/spicelib/devices/jfet/jfetdist.c +++ b/src/spicelib/devices/jfet/jfetdist.c @@ -14,7 +14,7 @@ Author: 1988 Jaijeet S Roychowdhury int JFETdisto(mode,genmodel,ckt) GENmodel *genmodel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int mode; /* assuming here that ckt->CKTomega has been initialised to @@ -35,7 +35,7 @@ JFETdisto(mode,genmodel,ckt) double r2h1m2x,i2h1m2x; double r2h1m2y,i2h1m2y; double temp, itemp; - register JFETinstance *here; + JFETinstance *here; if (mode == D_SETUP) return(JFETdSetup(model,ckt)); diff --git a/src/spicelib/devices/jfet/jfetdset.c b/src/spicelib/devices/jfet/jfetdset.c index f11051946..d2aa4cc4b 100644 --- a/src/spicelib/devices/jfet/jfetdset.c +++ b/src/spicelib/devices/jfet/jfetdset.c @@ -22,8 +22,8 @@ JFETdSetup(inModel,ckt) * sparse matrix previously provided */ { - register JFETmodel *model = (JFETmodel*)inModel; - register JFETinstance *here; + JFETmodel *model = (JFETmodel*)inModel; + JFETinstance *here; double beta; double betap; double lcapgd1; diff --git a/src/spicelib/devices/jfet/jfetext.h b/src/spicelib/devices/jfet/jfetext.h index 9da1e4ea0..3a685d319 100644 --- a/src/spicelib/devices/jfet/jfetext.h +++ b/src/spicelib/devices/jfet/jfetext.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #ifdef __STDC__ @@ -22,6 +23,8 @@ extern int JFETtrunc(GENmodel*,CKTcircuit*,double*); extern int JFETdisto(int,GENmodel*,CKTcircuit*); extern int JFETnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); +extern int JFETdSetup(GENmodel*,CKTcircuit*); + #else /* stdc */ extern int JFETacLoad(); extern int JFETask(); diff --git a/src/spicelib/devices/jfet/jfetitf.h b/src/spicelib/devices/jfet/jfetitf.h index 1ac351fff..19da888b2 100644 --- a/src/spicelib/devices/jfet/jfetitf.h +++ b/src/spicelib/devices/jfet/jfetitf.h @@ -1,88 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_jfet - #ifndef DEV_JFET #define DEV_JFET -#include "jfetext.h" -extern IFparm JFETpTable[ ]; -extern IFparm JFETmPTable[ ]; -extern char *JFETnames[ ]; -extern int JFETpTSize; -extern int JFETmPTSize; -extern int JFETnSize; -extern int JFETiSize; -extern int JFETmSize; - -SPICEdev JFETinfo = { - { - "JFET", - "Junction Field effect transistor", - - &JFETnSize, - &JFETnSize, - JFETnames, - - &JFETpTSize, - JFETpTable, - - &JFETmPTSize, - JFETmPTable, - DEV_DEFAULT - }, - - JFETparam, - JFETmParam, - JFETload, - JFETsetup, - JFETunsetup, - JFETsetup, - JFETtemp, - JFETtrunc, - NULL, - JFETacLoad, - NULL, - JFETdestroy, -#ifdef DELETES - JFETmDelete, - JFETdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - JFETgetic, - JFETask, - JFETmAsk, -#ifdef AN_pz - JFETpzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -#ifdef AN_disto - JFETdisto, -#else /* AN_disto */ - NULL, -#endif /* AN_disto */ -#ifdef AN_noise - JFETnoise, -#else /* AN_noise */ - NULL, -#endif /* AN_noise */ - - &JFETiSize, - &JFETmSize - -}; - +SPICEdev *get_jfet_info(void); #endif -#endif diff --git a/src/spicelib/devices/jfet/jfetload.c b/src/spicelib/devices/jfet/jfetload.c index 3baeab8b8..e7a6835c0 100644 --- a/src/spicelib/devices/jfet/jfetload.c +++ b/src/spicelib/devices/jfet/jfetload.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes Sydney University mods Copyright(c) 1989 Anthony E. Parker, David J. Skellern Laboratory for Communication Science Engineering Sydney University Department of Electrical Engineering, Australia @@ -24,8 +25,8 @@ JFETload(inModel,ckt) * sparse matrix previously provided */ { - register JFETmodel *model = (JFETmodel*)inModel; - register JFETinstance *here; + JFETmodel *model = (JFETmodel*)inModel; + JFETinstance *here; double beta; double betap; double capgd; @@ -74,6 +75,8 @@ JFETload(inModel,ckt) int icheck; int ichk1; int error; + + double arg, vt_temp; /* loop through all the models */ for( ; model != NULL; model = model->JFETnextModel ) { @@ -219,22 +222,30 @@ JFETload(inModel,ckt) * determine dc current and derivatives */ vds=vgs-vgd; - if (vgs <= -5*here->JFETtemp*CONSTKoverQ) { - ggs = -csat/vgs+ckt->CKTgmin; - cg = ggs*vgs; + + vt_temp=here->JFETtemp*CONSTKoverQ; + if (vgs < -3*vt_temp) { + arg=3*vt_temp/(vgs*CONSTe); + arg = arg * arg * arg; + cg = -csat*(1+arg)+ckt->CKTgmin*vgs; + ggs = csat*3*arg/vgs+ckt->CKTgmin; } else { - evgs = exp(vgs/(here->JFETtemp*CONSTKoverQ)); - ggs = csat*evgs/(here->JFETtemp*CONSTKoverQ)+ckt->CKTgmin; + evgs = exp(vgs/vt_temp); + ggs = csat*evgs/vt_temp+ckt->CKTgmin; cg = csat*(evgs-1)+ckt->CKTgmin*vgs; } - if (vgd <= -5*(here->JFETtemp*CONSTKoverQ)) { - ggd = -csat/vgd+ckt->CKTgmin; - cgd = ggd*vgd; + + if (vgd < -3*vt_temp) { + arg=3*vt_temp/(vgd*CONSTe); + arg = arg * arg * arg; + cgd = -csat*(1+arg)+ckt->CKTgmin*vgd; + ggd = csat*3*arg/vgd+ckt->CKTgmin; } else { - evgd = exp(vgd/(here->JFETtemp*CONSTKoverQ)); - ggd = csat*evgd/(here->JFETtemp*CONSTKoverQ)+ckt->CKTgmin; + evgd = exp(vgd/vt_temp); + ggd = csat*evgd/vt_temp+ckt->CKTgmin; cgd = csat*(evgd-1)+ckt->CKTgmin*vgd; } + cg = cg+cgd; /* Modification for Sydney University JFET model */ @@ -312,76 +323,6 @@ JFETload(inModel,ckt) } } } -#ifdef notdef - /* The original section is now commented out */ - /* end Sydney University mod */ - /* - * compute drain current and derivitives for normal mode - */ - if (vds >= 0) { - vgst=vgs-model->JFETthreshold; - /* - * normal mode, cutoff region - */ - if (vgst <= 0) { - cdrain=0; - gm=0; - gds=0; - } else { - betap=beta*(1+model->JFETlModulation*vds); - twob=betap+betap; - if (vgst <= vds) { - /* - * normal mode, saturation region - */ - cdrain=betap*vgst*vgst; - gm=twob*vgst; - gds=model->JFETlModulation*beta*vgst*vgst; - } else { - /* - * normal mode, linear region - */ - cdrain=betap*vds*(vgst+vgst-vds); - gm=twob*vds; - gds=twob*(vgst-vds)+model->JFETlModulation*beta* - vds*(vgst+vgst-vds); - } - } - } else { - /* - * compute drain current and derivitives for inverse mode - */ - vgdt=vgd-model->JFETthreshold; - if (vgdt <= 0) { - /* - * inverse mode, cutoff region - */ - cdrain=0; - gm=0; - gds=0; - } else { - /* - * inverse mode, saturation region - */ - betap=beta*(1-model->JFETlModulation*vds); - twob=betap+betap; - if (vgdt <= -vds) { - cdrain = -betap*vgdt*vgdt; - gm = -twob*vgdt; - gds = model->JFETlModulation*beta*vgdt*vgdt-gm; - } else { - /* - * inverse mode, linear region - */ - cdrain=betap*vds*(vgdt+vgdt+vds); - gm=twob*vds; - gds=twob*vgdt-model->JFETlModulation*beta*vds* - (vgdt+vgdt+vds); - } - } - } - /* end of original section, now deleted (replaced w/SU mod */ -#endif /* * compute equivalent drain current source */ @@ -459,16 +400,13 @@ JFETload(inModel,ckt) /* * check convergence */ - if( (!(ckt->CKTmode & MODEINITFIX)) | (!(ckt->CKTmode & MODEUIC))) { - if( (icheck == 1) -#ifndef NEWCONV -/* XXX */ -#endif /*NEWCONV*/ - || (fabs(cghat-cg) >= ckt->CKTreltol* - MAX(fabs(cghat),fabs(cg))+ckt->CKTabstol) || - (fabs(cdhat-cd) > ckt->CKTreltol* - MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol) - ) { + if( (!(ckt->CKTmode & MODEINITFIX)) | + (!(ckt->CKTmode & MODEUIC))) { + if((icheck == 1) || + (fabs(cghat-cg) >= ckt->CKTreltol * + MAX(fabs(cghat), fabs(cg)) + ckt->CKTabstol) || + (fabs(cdhat-cd) > ckt->CKTreltol * + MAX(fabs(cdhat), fabs(cd)) + ckt->CKTabstol)) { ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) here; } diff --git a/src/spicelib/devices/jfet/jfetnoi.c b/src/spicelib/devices/jfet/jfetnoi.c index 85b3988ba..0f30658bd 100644 --- a/src/spicelib/devices/jfet/jfetnoi.c +++ b/src/spicelib/devices/jfet/jfetnoi.c @@ -7,7 +7,6 @@ Author: 1987 Gary W. Ng #include #include "jfetdefs.h" #include "cktdefs.h" -#include "fteconst.h" #include "iferrmsg.h" #include "noisedef.h" #include "suffix.h" @@ -30,12 +29,12 @@ JFETnoise (mode, operation, genmodel, ckt, data, OnDens) int operation; GENmodel *genmodel; CKTcircuit *ckt; - register Ndata *data; + Ndata *data; double *OnDens; { JFETmodel *firstModel = (JFETmodel *) genmodel; - register JFETmodel *model; - register JFETinstance *inst; + JFETmodel *model; + JFETinstance *inst; char name[N_MXVLNTH]; double tempOnoise; double tempInoise; diff --git a/src/spicelib/devices/jfet/jfetpzld.c b/src/spicelib/devices/jfet/jfetpzld.c index 997cf0af3..f7ac0de00 100644 --- a/src/spicelib/devices/jfet/jfetpzld.c +++ b/src/spicelib/devices/jfet/jfetpzld.c @@ -17,11 +17,11 @@ Author: 1985 Thomas L. Quarles int JFETpzLoad(inModel,ckt,s) GENmodel *inModel; - register CKTcircuit *ckt; - register SPcomplex *s; + CKTcircuit *ckt; + SPcomplex *s; { - register JFETmodel *model = (JFETmodel*)inModel; - register JFETinstance *here; + JFETmodel *model = (JFETmodel*)inModel; + JFETinstance *here; double gdpr; double gspr; double gm; diff --git a/src/spicelib/devices/jfet/jfetset.c b/src/spicelib/devices/jfet/jfetset.c index 5902604fe..e0d592194 100644 --- a/src/spicelib/devices/jfet/jfetset.c +++ b/src/spicelib/devices/jfet/jfetset.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes Sydney University mods Copyright(c) 1989 Anthony E. Parker, David J. Skellern Laboratory for Communication Science Engineering Sydney University Department of Electrical Engineering, Australia @@ -17,7 +18,7 @@ Sydney University mods Copyright(c) 1989 Anthony E. Parker, David J. Skellern int JFETsetup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; CKTcircuit *ckt; int *states; @@ -25,8 +26,8 @@ JFETsetup(matrix,inModel,ckt,states) * for fast matrix loading */ { - register JFETmodel *model = (JFETmodel*)inModel; - register JFETinstance *here; + JFETmodel *model = (JFETmodel*)inModel; + JFETinstance *here; int error; CKTnode *tmp; @@ -106,6 +107,19 @@ matrixpointers: error = CKTmkVolt(ckt,&tmp,here->JFETname,"source"); if(error) return(error); here->JFETsourcePrimeNode = tmp->number; + + if (ckt->CKTcopyNodesets) { + CKTnode *tmpNode; + IFuid tmpName; + + if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } + } else { here->JFETsourcePrimeNode = here->JFETsourceNode; } @@ -113,6 +127,19 @@ matrixpointers: error = CKTmkVolt(ckt,&tmp,here->JFETname,"drain"); if(error) return(error); here->JFETdrainPrimeNode = tmp->number; + + if (ckt->CKTcopyNodesets) { + CKTnode *tmpNode; + IFuid tmpName; + + if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } + } else { here->JFETdrainPrimeNode = here->JFETdrainNode; } @@ -154,7 +181,6 @@ JFETunsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM JFETmodel *model; JFETinstance *here; @@ -178,6 +204,5 @@ JFETunsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/jfet/jfettemp.c b/src/spicelib/devices/jfet/jfettemp.c index 0fa92c6ad..6f048fce4 100644 --- a/src/spicelib/devices/jfet/jfettemp.c +++ b/src/spicelib/devices/jfet/jfettemp.c @@ -22,8 +22,8 @@ JFETtemp(inModel,ckt) /* Pre-process the model parameters after a possible change */ { - register JFETmodel *model = (JFETmodel*)inModel; - register JFETinstance *here; + JFETmodel *model = (JFETmodel*)inModel; + JFETinstance *here; double xfc; double vt; double vtnom; diff --git a/src/spicelib/devices/jfet/jfettrun.c b/src/spicelib/devices/jfet/jfettrun.c index 8af535469..4dc854896 100644 --- a/src/spicelib/devices/jfet/jfettrun.c +++ b/src/spicelib/devices/jfet/jfettrun.c @@ -16,11 +16,11 @@ Author: 1985 Thomas L. Quarles int JFETtrunc(inModel,ckt,timeStep) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; double *timeStep; { - register JFETmodel *model = (JFETmodel*)inModel; - register JFETinstance *here; + JFETmodel *model = (JFETmodel*)inModel; + JFETinstance *here; for( ; model != NULL; model = model->JFETnextModel) { for(here=model->JFETinstances;here!=NULL;here = here->JFETnextInstance){ diff --git a/src/spicelib/devices/jfet2/Makefile.am b/src/spicelib/devices/jfet2/Makefile.am index 03b175bbc..73beb344e 100644 --- a/src/spicelib/devices/jfet2/Makefile.am +++ b/src/spicelib/devices/jfet2/Makefile.am @@ -2,28 +2,30 @@ pkglib_LTLIBRARIES = libjfet2.la -libjfet2_la_SOURCES = \ - jfet2.c \ - jfet2acld.c \ - jfet2ask.c \ - jfet2defs.h \ - jfet2del.c \ - jfet2dest.c \ - jfet2ext.h \ - jfet2ic.c \ - jfet2itf.h \ - jfet2load.c \ - jfet2mask.c \ - jfet2mdel.c \ - jfet2mpar.c \ - jfet2noi.c \ - jfet2par.c \ - jfet2parm.h \ - jfet2set.c \ - jfet2temp.c \ - jfet2trun.c \ - psmodel.c \ - psmodel.h +libjfet2_la_SOURCES = \ + jfet2.c \ + jfet2acld.c \ + jfet2ask.c \ + jfet2defs.h \ + jfet2del.c \ + jfet2dest.c \ + jfet2ext.h \ + jfet2ic.c \ + jfet2init.c \ + jfet2init.h \ + jfet2itf.h \ + jfet2load.c \ + jfet2mask.c \ + jfet2mdel.c \ + jfet2mpar.c \ + jfet2noi.c \ + jfet2par.c \ + jfet2parm.h \ + jfet2set.c \ + jfet2temp.c \ + jfet2trun.c \ + psmodel.c \ + psmodel.h diff --git a/src/spicelib/devices/jfet2/jfet2acld.c b/src/spicelib/devices/jfet2/jfet2acld.c index c2d441419..622162d40 100644 --- a/src/spicelib/devices/jfet2/jfet2acld.c +++ b/src/spicelib/devices/jfet2/jfet2acld.c @@ -19,10 +19,10 @@ Modified to add PS model and new parameter definitions ( Anthony E. Parker ) int JFET2acLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register JFET2model *model = (JFET2model*)inModel; - register JFET2instance *here; + JFET2model *model = (JFET2model*)inModel; + JFET2instance *here; double gdpr; double gspr; double gm; diff --git a/src/spicelib/devices/jfet2/jfet2itf.h b/src/spicelib/devices/jfet2/jfet2itf.h index cef2de662..600c37967 100644 --- a/src/spicelib/devices/jfet2/jfet2itf.h +++ b/src/spicelib/devices/jfet2/jfet2itf.h @@ -6,80 +6,9 @@ Modified to add PS model and new parameter definitions ( Anthony E. Parker ) Copyright 1994 Macquarie University, Sydney Australia. pz and disto not supported **********/ -#ifdef DEV_jfet2 - #ifndef DEV_JFET2 #define DEV_JFET2 -#include "jfet2ext.h" -extern IFparm JFET2pTable[ ]; -extern IFparm JFET2mPTable[ ]; -extern char *JFET2names[ ]; -extern int JFET2pTSize; -extern int JFET2mPTSize; -extern int JFET2nSize; -extern int JFET2iSize; -extern int JFET2mSize; - -SPICEdev JFET2info = { - { - "JFET2", - "Short channel field effect transistor", - - &JFET2nSize, - &JFET2nSize, - JFET2names, - - &JFET2pTSize, - JFET2pTable, - - &JFET2mPTSize, - JFET2mPTable, - DEV_DEFAULT - }, - - JFET2param, - JFET2mParam, - JFET2load, - JFET2setup, - JFET2unsetup, - JFET2setup, - JFET2temp, - JFET2trunc, - NULL, - JFET2acLoad, - NULL, - JFET2destroy, -#ifdef DELETES - JFET2mDelete, - JFET2delete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - JFET2getic, - JFET2ask, - JFET2mAsk, - NULL, /* AN_pz */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, /* AN_disto */ -#ifdef AN_noise - JFET2noise, -#else /* AN_noise */ - NULL, -#endif /* AN_noise */ - - &JFET2iSize, - &JFET2mSize - -}; - +SPICEdev *get_jfet2_info(void); #endif -#endif diff --git a/src/spicelib/devices/jfet2/jfet2load.c b/src/spicelib/devices/jfet2/jfet2load.c index 0e24f1aba..a04d9342a 100644 --- a/src/spicelib/devices/jfet2/jfet2load.c +++ b/src/spicelib/devices/jfet2/jfet2load.c @@ -27,8 +27,8 @@ JFET2load(inModel,ckt) * sparse matrix previously provided */ { - register JFET2model *model = (JFET2model*)inModel; - register JFET2instance *here; + JFET2model *model = (JFET2model*)inModel; + JFET2instance *here; double capgd; double capgs; double cd; @@ -271,15 +271,11 @@ JFET2load(inModel,ckt) * check convergence */ if( (!(ckt->CKTmode & MODEINITFIX)) | (!(ckt->CKTmode & MODEUIC))) { - if( (icheck == 1) -#ifndef NEWCONV -/* XXX */ -#endif /*NEWCONV*/ - || (fabs(cghat-cg) >= ckt->CKTreltol* - MAX(fabs(cghat),fabs(cg))+ckt->CKTabstol) || - (fabs(cdhat-cd) > ckt->CKTreltol* - MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol) - ) { + if((icheck == 1) || + (fabs(cghat-cg) >= ckt->CKTreltol* + MAX(fabs(cghat),fabs(cg))+ckt->CKTabstol) || + (fabs(cdhat-cd) > ckt->CKTreltol* + MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol)) { ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) here; } diff --git a/src/spicelib/devices/jfet2/jfet2noi.c b/src/spicelib/devices/jfet2/jfet2noi.c index d9fe4ea0a..a7dc49aca 100644 --- a/src/spicelib/devices/jfet2/jfet2noi.c +++ b/src/spicelib/devices/jfet2/jfet2noi.c @@ -11,7 +11,6 @@ Modified to jfet2 for PS model definition ( Anthony E. Parker ) #include #include "jfet2defs.h" #include "cktdefs.h" -#include "fteconst.h" #include "iferrmsg.h" #include "noisedef.h" #include "suffix.h" @@ -34,12 +33,12 @@ JFET2noise (mode, operation, genmodel, ckt, data, OnDens) int operation; GENmodel *genmodel; CKTcircuit *ckt; - register Ndata *data; + Ndata *data; double *OnDens; { JFET2model *firstModel = (JFET2model *) genmodel; - register JFET2model *model; - register JFET2instance *inst; + JFET2model *model; + JFET2instance *inst; char name[N_MXVLNTH]; double tempOnoise; double tempInoise; diff --git a/src/spicelib/devices/jfet2/jfet2set.c b/src/spicelib/devices/jfet2/jfet2set.c index 3a93e006e..7cd8ca6a3 100644 --- a/src/spicelib/devices/jfet2/jfet2set.c +++ b/src/spicelib/devices/jfet2/jfet2set.c @@ -19,7 +19,7 @@ Modified to add PS model and new parameter definitions ( Anthony E. Parker ) int JFET2setup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; CKTcircuit *ckt; int *states; @@ -27,8 +27,8 @@ JFET2setup(matrix,inModel,ckt,states) * for fast matrix loading */ { - register JFET2model *model = (JFET2model*)inModel; - register JFET2instance *here; + JFET2model *model = (JFET2model*)inModel; + JFET2instance *here; int error; CKTnode *tmp; @@ -106,7 +106,6 @@ JFET2unsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM JFET2model *model; JFET2instance *here; @@ -130,6 +129,5 @@ JFET2unsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/jfet2/jfet2temp.c b/src/spicelib/devices/jfet2/jfet2temp.c index fa28fcf0b..64c919806 100644 --- a/src/spicelib/devices/jfet2/jfet2temp.c +++ b/src/spicelib/devices/jfet2/jfet2temp.c @@ -27,8 +27,8 @@ JFET2temp(inModel,ckt) /* Pre-process the model parameters after a possible change */ { - register JFET2model *model = (JFET2model*)inModel; - register JFET2instance *here; + JFET2model *model = (JFET2model*)inModel; + JFET2instance *here; double xfc; double vt; double vtnom; diff --git a/src/spicelib/devices/jfet2/jfet2trun.c b/src/spicelib/devices/jfet2/jfet2trun.c index 07b687bc6..9df728ad4 100644 --- a/src/spicelib/devices/jfet2/jfet2trun.c +++ b/src/spicelib/devices/jfet2/jfet2trun.c @@ -20,11 +20,11 @@ Modified to jfet2 for PS model definition ( Anthony E. Parker ) int JFET2trunc(inModel,ckt,timeStep) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; double *timeStep; { - register JFET2model *model = (JFET2model*)inModel; - register JFET2instance *here; + JFET2model *model = (JFET2model*)inModel; + JFET2instance *here; for( ; model != NULL; model = model->JFET2nextModel) { for(here=model->JFET2instances;here!=NULL;here = here->JFET2nextInstance){ diff --git a/src/spicelib/devices/ltra/Makefile.am b/src/spicelib/devices/ltra/Makefile.am index a9c725ef1..fcd8ad18a 100644 --- a/src/spicelib/devices/ltra/Makefile.am +++ b/src/spicelib/devices/ltra/Makefile.am @@ -3,24 +3,26 @@ pkglib_LTLIBRARIES = libltra.la libltra_la_SOURCES = \ - ltra.c \ - ltraacct.c \ - ltraacld.c \ - ltraask.c \ - ltradefs.h \ - ltradel.c \ - ltradest.c \ - ltraext.h \ - ltraitf.h \ - ltraload.c \ - ltramask.c \ - ltramdel.c \ - ltramisc.c \ - ltrampar.c \ - ltrapar.c \ - ltraset.c \ - ltratemp.c \ - ltratrun.c + ltra.c \ + ltraacct.c \ + ltraacld.c \ + ltraask.c \ + ltradefs.h \ + ltradel.c \ + ltradest.c \ + ltraext.h \ + ltrainit.c \ + ltrainit.h \ + ltraitf.h \ + ltraload.c \ + ltramask.c \ + ltramdel.c \ + ltramisc.c \ + ltrampar.c \ + ltrapar.c \ + ltraset.c \ + ltratemp.c \ + ltratrun.c diff --git a/src/spicelib/devices/ltra/ltra.c b/src/spicelib/devices/ltra/ltra.c index 817a988e1..121048242 100644 --- a/src/spicelib/devices/ltra/ltra.c +++ b/src/spicelib/devices/ltra/ltra.c @@ -55,20 +55,6 @@ IFparm LTRAmPTable[] = { /* model parameters */ "special reltol for straight line checking"), IOPAU("compactabs", LTRA_MOD_STLINEABS, IF_REAL, "special abstol for straight line checking") -#ifdef notdef - IOP("f", LTRA_MOD_FREQ, IF_REAL, "Frequency"), - IOP("nl", LTRA_MOD_NL, IF_REAL, "Normalized length at frequency given"), - IOP("fullcontrol", LTRA_MOD_FULLCONTROL, IF_FLAG, "rigorous timestep control"), - IOP("halfcontrol", LTRA_MOD_HALFCONTROL, IF_FLAG, - "only the current step is considered for timestep control"), - IOP("print", LTRA_MOD_PRINT, IF_FLAG, "printing of debugging info on"), - IOP("noprint", LTRA_MOD_NOPRINT, IF_FLAG, "printing of debugging info off"), - IOP("ronly", LTRA_MOD_RONLY, IF_FLAG, "use special load routines for G=0"), - IOP("choprel", LTRA_MOD_CHOPREL, IF_REAL, - "special reltol for truncation of impulse responses"), - IOP("chopabs", LTRA_MOD_CHOPABS, IF_REAL, - "special abstol for truncation of impulse responses "), -#endif }; char *LTRAnames[] = { diff --git a/src/spicelib/devices/ltra/ltraacct.c b/src/spicelib/devices/ltra/ltraacct.c index f060519ce..0788e809c 100644 --- a/src/spicelib/devices/ltra/ltraacct.c +++ b/src/spicelib/devices/ltra/ltraacct.c @@ -12,11 +12,11 @@ Author: 1990 Jaijeet S. Roychowdhury int LTRAaccept(ckt, inModel) - register CKTcircuit *ckt; + CKTcircuit *ckt; GENmodel *inModel; { - register LTRAmodel *model = (LTRAmodel *) inModel; - register LTRAinstance *here; + LTRAmodel *model = (LTRAmodel *) inModel; + LTRAinstance *here; double v1, v2, v3, v4; double v5, v6, d1, d2, d3, d4; int tmp_test; diff --git a/src/spicelib/devices/ltra/ltraacld.c b/src/spicelib/devices/ltra/ltraacld.c index 1b43c4ea3..ec7718a54 100644 --- a/src/spicelib/devices/ltra/ltraacld.c +++ b/src/spicelib/devices/ltra/ltraacld.c @@ -21,8 +21,8 @@ LTRAacLoad(inModel, ckt) * matrix and the right-hand-side vector */ { - register LTRAmodel *model = (LTRAmodel *) inModel; - register LTRAinstance *here; + LTRAmodel *model = (LTRAmodel *) inModel; + LTRAinstance *here; double y0_r, y0_i, lambda_r, lambda_i, mag, theta; double exparg_r, exparg_i, explambda_r, explambda_i; double y0exp_r, y0exp_i; diff --git a/src/spicelib/devices/ltra/ltraext.h b/src/spicelib/devices/ltra/ltraext.h index 5cd0a5625..58aa13e9c 100644 --- a/src/spicelib/devices/ltra/ltraext.h +++ b/src/spicelib/devices/ltra/ltraext.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1990 Jaijeet S. Roychowdhury +Modified: 2000 AlansFixes **********/ #ifdef __STDC__ @@ -19,6 +20,8 @@ extern int LTRAunsetup(GENmodel*,CKTcircuit*); extern int LTRAtemp(GENmodel*,CKTcircuit*); extern int LTRAtrunc(GENmodel*,CKTcircuit*,double*); +extern int LTRAlinInterp(double,double,double,double*,double*); + extern int LTRAquadInterp(double,double,double,double,double*,double*,double*); /* extern double LTRAcoeffSetup(double*,int,double,double,double*,double,double*,int,int*); diff --git a/src/spicelib/devices/ltra/ltraitf.h b/src/spicelib/devices/ltra/ltraitf.h index 4e1259d98..b96c16a7d 100644 --- a/src/spicelib/devices/ltra/ltraitf.h +++ b/src/spicelib/devices/ltra/ltraitf.h @@ -3,75 +3,9 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1990 Jaijeet S. Roychowdhury **********/ -#ifdef DEV_ltra - #ifndef DEV_LTRA #define DEV_LTRA -#include "ltraext.h" -extern IFparm LTRApTable[ ]; -extern IFparm LTRAmPTable[ ]; -extern char *LTRAnames[ ]; -extern int LTRApTSize; -extern int LTRAmPTSize; -extern int LTRAnSize; -extern int LTRAiSize; -extern int LTRAmSize; - -SPICEdev LTRAinfo = { - { "LTRA", - "Lossy transmission line", - - <RAnSize, - <RAnSize, - LTRAnames, - - <RApTSize, - LTRApTable, - - <RAmPTSize, - LTRAmPTable, - 0 - }, - - LTRAparam, - LTRAmParam, - LTRAload, - LTRAsetup, - LTRAunsetup, - LTRAsetup, - LTRAtemp, - LTRAtrunc, - NULL, - LTRAacLoad /*LTRAacLoad*/, - LTRAaccept, - LTRAdestroy, -#ifdef DELETES - LTRAmDelete, - LTRAdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - NULL, /* getic */ - LTRAask, - LTRAmAsk, /* */ - NULL, /* pzLoad */ - NULL, /* convTest */ - NULL, /* sSetup */ - NULL, /* sLoad */ - NULL, /* sUpdate */ - NULL, /* sAcLoad */ - NULL, /* sPrint */ - NULL, /* */ - NULL, /* disto */ - NULL, /* noise */ - - <RAiSize, - <RAmSize - -}; - -#endif +SPICEdev *get_ltra_info(void); #endif diff --git a/src/spicelib/devices/ltra/ltraload.c b/src/spicelib/devices/ltra/ltraload.c index d3bd91d1d..f9203236f 100644 --- a/src/spicelib/devices/ltra/ltraload.c +++ b/src/spicelib/devices/ltra/ltraload.c @@ -14,14 +14,14 @@ Author: 1990 Jaijeet S. Roychowdhury int LTRAload(inModel, ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* * load the appropriate values for the current timepoint into the sparse * matrix and the right-hand-side vector */ { - register LTRAmodel *model = (LTRAmodel *) inModel; - register LTRAinstance *here; + LTRAmodel *model = (LTRAmodel *) inModel; + LTRAinstance *here; double t1, t2, t3; double qf1, qf2, qf3; double lf2, lf3; @@ -29,7 +29,7 @@ LTRAload(inModel, ckt) double dummy1, dummy2; int isaved; unsigned tdover; - register int i; + int i; double max, min; /* loop through all the transmission line models */ diff --git a/src/spicelib/devices/ltra/ltramisc.c b/src/spicelib/devices/ltra/ltramisc.c index 5085660e2..c63aa4535 100644 --- a/src/spicelib/devices/ltra/ltramisc.c +++ b/src/spicelib/devices/ltra/ltramisc.c @@ -855,7 +855,7 @@ LTRAstraightLineCheck(x1, y1, x2, y2, x3, y3, reltol, abstol) double LTRAlteCalculate(ckt, genmodel, geninstance, curtime) - register CKTcircuit *ckt; + CKTcircuit *ckt; GENmodel *genmodel; GENinstance *geninstance; double curtime; @@ -1427,8 +1427,8 @@ LTRAlteCalculate(ckt, genmodel, geninstance, curtime) */ /* - * double LTRAlteCalculate(ckt,model,instance,curtime) register CKTcircuit *ckt; - * register LTRAmodel *model; register LTRAinstance *instance; double + * double LTRAlteCalculate(ckt,model,instance,curtime) CKTcircuit *ckt; + * LTRAmodel *model; register LTRAinstance *instance; double * curtime; * * { double *h1dashTcoeffs, h1dashTfirstCoeff; double *h2Tcoeffs, h2TfirstCoeff; diff --git a/src/spicelib/devices/ltra/ltraset.c b/src/spicelib/devices/ltra/ltraset.c index 2a7cdedb4..a93c1c348 100644 --- a/src/spicelib/devices/ltra/ltraset.c +++ b/src/spicelib/devices/ltra/ltraset.c @@ -13,17 +13,17 @@ Author: 1990 Jaijeet S. Roychowdhury int LTRAsetup(matrix, inModel, ckt, state) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int *state; /* * load the transmission line structure with those pointers needed later for * fast matrix loading */ { - register LTRAmodel *model = (LTRAmodel *) inModel; - register LTRAinstance *here; + LTRAmodel *model = (LTRAmodel *) inModel; + LTRAinstance *here; int error; CKTnode *tmp; @@ -75,10 +75,6 @@ LTRAsetup(matrix, inModel, ckt, state) } if ((model->LTRAstepLimit != LTRA_MOD_NOSTEPLIMIT)) model->LTRAstepLimit = LTRA_MOD_STEPLIMIT; -#ifdef notdef - if ((model->LTRAprintFlag != LTRA_MOD_PRINT)) - model->LTRAprintFlag = LTRA_MOD_NOPRINT; -#endif if ((model->LTRAlteConType != LTRA_MOD_FULLCONTROL) && (model->LTRAlteConType != LTRA_MOD_HALFCONTROL)) model->LTRAlteConType = LTRA_MOD_NOCONTROL; @@ -231,7 +227,6 @@ LTRAunsetup(inModel, ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM LTRAmodel *model; LTRAinstance *here; @@ -240,15 +235,14 @@ LTRAunsetup(inModel, ckt) for (here = model->LTRAinstances; here != NULL; here = here->LTRAnextInstance) { if (here->LTRAbrEq1) { - CKTdltNNum(ckt, (void *) here->LTRAbrEq1); + CKTdltNNum(ckt, here->LTRAbrEq1); here->LTRAbrEq1 = 0; } if (here->LTRAbrEq2) { - CKTdltNNum(ckt, (void *) here->LTRAbrEq2); + CKTdltNNum(ckt, here->LTRAbrEq2); here->LTRAbrEq2 = 0; } } } -#endif return OK; } diff --git a/src/spicelib/devices/ltra/ltratemp.c b/src/spicelib/devices/ltra/ltratemp.c index 6fc3bcd91..2bc3c5f4d 100644 --- a/src/spicelib/devices/ltra/ltratemp.c +++ b/src/spicelib/devices/ltra/ltratemp.c @@ -20,8 +20,8 @@ LTRAtemp(inModel, ckt) * pre-process parameters for later use */ { - register LTRAmodel *model = (LTRAmodel *) inModel; - register LTRAinstance *here; + LTRAmodel *model = (LTRAmodel *) inModel; + LTRAinstance *here; /* loop through all the transmission line models */ for (; model != NULL; model = model->LTRAnextModel) { diff --git a/src/spicelib/devices/ltra/ltratrun.c b/src/spicelib/devices/ltra/ltratrun.c index 550784ee8..76d85050e 100644 --- a/src/spicelib/devices/ltra/ltratrun.c +++ b/src/spicelib/devices/ltra/ltratrun.c @@ -13,12 +13,12 @@ Author: 1990 Jaijeet S. Roychowdhury int LTRAtrunc(inModel, ckt, timeStep) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; double *timeStep; { - register LTRAmodel *model = (LTRAmodel *) inModel; - register LTRAinstance *here; + LTRAmodel *model = (LTRAmodel *) inModel; + LTRAinstance *here; double i1, i2, i3, i4; double i5, i6, d1, d2, d3, d4; double tmp; diff --git a/src/spicelib/devices/mes/Makefile.am b/src/spicelib/devices/mes/Makefile.am index 515f2a4fb..bb2bcf82d 100644 --- a/src/spicelib/devices/mes/Makefile.am +++ b/src/spicelib/devices/mes/Makefile.am @@ -2,28 +2,30 @@ pkglib_LTLIBRARIES = libmes.la -libmes_la_SOURCES = \ - mes.c \ - mesacl.c \ - mesask.c \ - mesdefs.h \ - mesdel.c \ - mesdest.c \ - mesdisto.c \ - mesdset.c \ - mesext.h \ - mesgetic.c \ - mesitf.h \ - mesload.c \ - mesmask.c \ - mesmdel.c \ - mesmpar.c \ - mesnoise.c \ - mesparam.c \ - mespzld.c \ - messetup.c \ - mestemp.c \ - mestrunc.c +libmes_la_SOURCES = \ + mes.c \ + mesacl.c \ + mesask.c \ + mesdefs.h \ + mesdel.c \ + mesdest.c \ + mesdisto.c \ + mesdset.c \ + mesext.h \ + mesgetic.c \ + mesinit.c \ + mesinit.h \ + mesitf.h \ + mesload.c \ + mesmask.c \ + mesmdel.c \ + mesmpar.c \ + mesnoise.c \ + mesparam.c \ + mespzld.c \ + messetup.c \ + mestemp.c \ + mestrunc.c diff --git a/src/spicelib/devices/mes/mesacl.c b/src/spicelib/devices/mes/mesacl.c index 4142e2e70..8cc25d8c9 100644 --- a/src/spicelib/devices/mes/mesacl.c +++ b/src/spicelib/devices/mes/mesacl.c @@ -16,10 +16,10 @@ Author: 1985 S. Hwang int MESacLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register MESmodel *model = (MESmodel*)inModel; - register MESinstance *here; + MESmodel *model = (MESmodel*)inModel; + MESinstance *here; double gdpr; double gspr; double gm; diff --git a/src/spicelib/devices/mes/mesdisto.c b/src/spicelib/devices/mes/mesdisto.c index ef6f35319..bd02a9cdc 100644 --- a/src/spicelib/devices/mes/mesdisto.c +++ b/src/spicelib/devices/mes/mesdisto.c @@ -14,7 +14,7 @@ Author: 1988 Jaijeet S Roychowdhury int MESdisto(mode,genmodel,ckt) GENmodel *genmodel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int mode; /* assuming here that ckt->CKTomega has been initialised to @@ -35,7 +35,7 @@ MESdisto(mode,genmodel,ckt) double r2h1m2x,i2h1m2x; double r2h1m2y,i2h1m2y; double temp, itemp; - register MESinstance *here; + MESinstance *here; if (mode == D_SETUP) return(MESdSetup(model,ckt)); diff --git a/src/spicelib/devices/mes/mesdset.c b/src/spicelib/devices/mes/mesdset.c index 0a49e0f42..c92398018 100644 --- a/src/spicelib/devices/mes/mesdset.c +++ b/src/spicelib/devices/mes/mesdset.c @@ -21,8 +21,8 @@ MESdSetup(inModel,ckt) * sparse matrix previously provided */ { - register MESmodel *model = (MESmodel*)inModel; - register MESinstance *here; + MESmodel *model = (MESmodel*)inModel; + MESinstance *here; double afact; double beta; double betap; diff --git a/src/spicelib/devices/mes/mesext.h b/src/spicelib/devices/mes/mesext.h index 7185d6867..0a9a9005b 100644 --- a/src/spicelib/devices/mes/mesext.h +++ b/src/spicelib/devices/mes/mesext.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 S. Hwang +Modified: 2000 AlansFixes **********/ #ifdef __STDC__ @@ -22,6 +23,8 @@ extern int MEStrunc(GENmodel*,CKTcircuit*,double*); extern int MESdisto(int,GENmodel*,CKTcircuit*); extern int MESnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); +extern int MESdSetup(GENmodel*,CKTcircuit*); + #else /* stdc */ extern int MESacLoad(); extern int MESask(); diff --git a/src/spicelib/devices/mes/mesitf.h b/src/spicelib/devices/mes/mesitf.h index e4f18bc62..6f9593f08 100644 --- a/src/spicelib/devices/mes/mesitf.h +++ b/src/spicelib/devices/mes/mesitf.h @@ -1,87 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_mes - #ifndef DEV_MES #define DEV_MES -#include "mesext.h" -extern IFparm MESpTable[ ]; -extern IFparm MESmPTable[ ]; -extern char *MESnames[ ]; -extern int MESpTSize; -extern int MESmPTSize; -extern int MESnSize; -extern int MESiSize; -extern int MESmSize; - -SPICEdev MESinfo = { - { - "MES", - "GaAs MESFET model", - - &MESnSize, - &MESnSize, - MESnames, - - &MESpTSize, - MESpTable, - - &MESmPTSize, - MESmPTable, - DEV_DEFAULT - }, - - MESparam, - MESmParam, - MESload, - MESsetup, - MESunsetup, - MESsetup, - MEStemp, - MEStrunc, - NULL, - MESacLoad, - NULL, - MESdestroy, -#ifdef DELETES - MESmDelete, - MESdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - MESgetic, - MESask, - MESmAsk, -#ifdef AN_pz - MESpzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -#ifdef AN_disto - MESdisto, -#else /* AN_disto */ - NULL, -#endif /* AN_disto */ -#ifdef AN_noise - MESnoise, -#else /* AN_noise */ - NULL, -#endif /* AN_noise */ - - &MESiSize, - &MESmSize - -}; +SPICEdev *get_mes_info(void); #endif -#endif diff --git a/src/spicelib/devices/mes/mesload.c b/src/spicelib/devices/mes/mesload.c index 7e2cc1f9e..0e81c0fe6 100644 --- a/src/spicelib/devices/mes/mesload.c +++ b/src/spicelib/devices/mes/mesload.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 S. Hwang +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -29,8 +30,8 @@ MESload(inModel,ckt) * sparse matrix previously provided */ { - register MESmodel *model = (MESmodel*)inModel; - register MESinstance *here; + MESmodel *model = (MESmodel*)inModel; + MESinstance *here; double afact; double beta; double betap; @@ -80,6 +81,7 @@ MESload(inModel,ckt) double vgst; double vto; double xfact; + double arg; int icheck; int ichk1; int error; @@ -230,22 +232,28 @@ MESload(inModel,ckt) * determine dc current and derivatives */ vds = vgs-vgd; - if (vgs <= -5*CONSTvt0) { - ggs = -csat/vgs+ckt->CKTgmin; - cg = ggs*vgs; + + if (vgs <= -3*CONSTvt0) { + arg=3*CONSTvt0/(vgs*CONSTe); + arg = arg * arg * arg; + cg = -csat*(1+arg)+ckt->CKTgmin*vgs; + ggs = csat*3*arg/vgs+ckt->CKTgmin; } else { evgs = exp(vgs/CONSTvt0); ggs = csat*evgs/CONSTvt0+ckt->CKTgmin; cg = csat*(evgs-1)+ckt->CKTgmin*vgs; } - if (vgd <= -5*CONSTvt0) { - ggd = -csat/vgd+ckt->CKTgmin; - cgd = ggd*vgd; + if (vgd <= -3*CONSTvt0) { + arg=3*CONSTvt0/(vgd*CONSTe); + arg = arg * arg * arg; + cgd = -csat*(1+arg)+ckt->CKTgmin*vgd; + ggd = csat*3*arg/vgd+ckt->CKTgmin; } else { evgd = exp(vgd/CONSTvt0); ggd = csat*evgd/CONSTvt0+ckt->CKTgmin; cgd = csat*(evgd-1)+ckt->CKTgmin*vgd; } + cg = cg+cgd; /* * compute drain current and derivitives for normal mode @@ -399,15 +407,11 @@ MESload(inModel,ckt) * check convergence */ if( (!(ckt->CKTmode & MODEINITFIX)) | (!(ckt->CKTmode & MODEUIC))) { - if( (icheck == 1) -#ifndef NEWCONV -/* XXX */ -#endif /* NEWCONV */ - || (fabs(cghat-cg) >= ckt->CKTreltol* - MAX(fabs(cghat),fabs(cg))+ckt->CKTabstol) || - (fabs(cdhat-cd) > ckt->CKTreltol* - MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol) - ) { + if((icheck == 1) || + (fabs(cghat-cg) >= ckt->CKTreltol * + MAX(fabs(cghat),fabs(cg))+ckt->CKTabstol) || + (fabs(cdhat-cd) > ckt->CKTreltol* + MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol)) { ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) here; } diff --git a/src/spicelib/devices/mes/mesnoise.c b/src/spicelib/devices/mes/mesnoise.c index 6b6b1b284..d715068de 100644 --- a/src/spicelib/devices/mes/mesnoise.c +++ b/src/spicelib/devices/mes/mesnoise.c @@ -7,7 +7,6 @@ Author: 1987 Gary W. Ng #include #include "mesdefs.h" #include "cktdefs.h" -#include "fteconst.h" #include "iferrmsg.h" #include "noisedef.h" #include "suffix.h" @@ -30,12 +29,12 @@ MESnoise (mode, operation, genmodel, ckt, data, OnDens) int operation; GENmodel *genmodel; CKTcircuit *ckt; - register Ndata *data; + Ndata *data; double *OnDens; { MESmodel *firstModel = (MESmodel *) genmodel; - register MESmodel *model; - register MESinstance *inst; + MESmodel *model; + MESinstance *inst; char name[N_MXVLNTH]; double tempOnoise; double tempInoise; diff --git a/src/spicelib/devices/mes/mespzld.c b/src/spicelib/devices/mes/mespzld.c index e9a3f917f..7ebe2175c 100644 --- a/src/spicelib/devices/mes/mespzld.c +++ b/src/spicelib/devices/mes/mespzld.c @@ -17,11 +17,11 @@ Author: 1985 S. Hwang int MESpzLoad(inModel,ckt,s) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; SPcomplex *s; { - register MESmodel *model = (MESmodel*)inModel; - register MESinstance *here; + MESmodel *model = (MESmodel*)inModel; + MESinstance *here; double gdpr; double gspr; double gm; diff --git a/src/spicelib/devices/mes/messetup.c b/src/spicelib/devices/mes/messetup.c index bf8c7c1e7..b3ddd4bfd 100644 --- a/src/spicelib/devices/mes/messetup.c +++ b/src/spicelib/devices/mes/messetup.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 S. Hwang +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -14,7 +15,7 @@ Author: 1985 S. Hwang int MESsetup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; CKTcircuit *ckt; int *states; @@ -22,8 +23,8 @@ MESsetup(matrix,inModel,ckt,states) * for fast matrix loading */ { - register MESmodel *model = (MESmodel*)inModel; - register MESinstance *here; + MESmodel *model = (MESmodel*)inModel; + MESinstance *here; int error; CKTnode *tmp; @@ -92,6 +93,19 @@ matrixpointers: error = CKTmkVolt(ckt,&tmp,here->MESname,"source"); if(error) return(error); here->MESsourcePrimeNode = tmp->number; + + if (ckt->CKTcopyNodesets) { + CKTnode *tmpNode; + IFuid tmpName; + + if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } + } else { here->MESsourcePrimeNode = here->MESsourceNode; } @@ -99,6 +113,19 @@ matrixpointers: error = CKTmkVolt(ckt,&tmp,here->MESname,"drain"); if(error) return(error); here->MESdrainPrimeNode = tmp->number; + + if (ckt->CKTcopyNodesets) { + CKTnode *tmpNode; + IFuid tmpName; + + if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } + } else { here->MESdrainPrimeNode = here->MESdrainNode; } @@ -140,7 +167,6 @@ MESunsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM MESmodel *model; MESinstance *here; @@ -164,6 +190,5 @@ MESunsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/mes/mestemp.c b/src/spicelib/devices/mes/mestemp.c index c331e41d7..285eb32db 100644 --- a/src/spicelib/devices/mes/mestemp.c +++ b/src/spicelib/devices/mes/mestemp.c @@ -21,7 +21,7 @@ MEStemp(inModel,ckt) * for fast matrix loading */ { - register MESmodel *model = (MESmodel*)inModel; + MESmodel *model = (MESmodel*)inModel; double xfc, temp; /* loop through all the diode models */ diff --git a/src/spicelib/devices/mes/mestrunc.c b/src/spicelib/devices/mes/mestrunc.c index 6a3517f00..2f7ff8e97 100644 --- a/src/spicelib/devices/mes/mestrunc.c +++ b/src/spicelib/devices/mes/mestrunc.c @@ -16,11 +16,11 @@ Author: 1985 S. Hwang int MEStrunc(inModel,ckt,timeStep) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; double *timeStep; { - register MESmodel *model = (MESmodel*)inModel; - register MESinstance *here; + MESmodel *model = (MESmodel*)inModel; + MESinstance *here; for( ; model != NULL; model = model->MESnextModel) { for(here=model->MESinstances;here!=NULL;here = here->MESnextInstance){ diff --git a/src/spicelib/devices/mos1/Makefile.am b/src/spicelib/devices/mos1/Makefile.am index 075322152..0bda56f8d 100644 --- a/src/spicelib/devices/mos1/Makefile.am +++ b/src/spicelib/devices/mos1/Makefile.am @@ -3,33 +3,35 @@ pkglib_LTLIBRARIES = libmos1.la libmos1_la_SOURCES = \ - mos1.c \ - mos1acld.c \ - mos1ask.c \ - mos1conv.c \ - mos1defs.h \ - mos1del.c \ - mos1dest.c \ - mos1dist.c \ - mos1dset.c \ - mos1ext.h \ - mos1ic.c \ - mos1itf.h \ - mos1load.c \ - mos1mask.c \ - mos1mdel.c \ - mos1mpar.c \ - mos1noi.c \ - mos1par.c \ - mos1pzld.c \ - mos1sacl.c \ - mos1set.c \ - mos1sld.c \ - mos1sprt.c \ - mos1sset.c \ - mos1supd.c \ - mos1temp.c \ - mos1trun.c + mos1.c \ + mos1acld.c \ + mos1ask.c \ + mos1conv.c \ + mos1defs.h \ + mos1del.c \ + mos1dest.c \ + mos1dist.c \ + mos1dset.c \ + mos1ext.h \ + mos1ic.c \ + mos1init.c \ + mos1init.h \ + mos1itf.h \ + mos1load.c \ + mos1mask.c \ + mos1mdel.c \ + mos1mpar.c \ + mos1noi.c \ + mos1par.c \ + mos1pzld.c \ + mos1sacl.c \ + mos1set.c \ + mos1sld.c \ + mos1sprt.c \ + mos1sset.c \ + mos1supd.c \ + mos1temp.c \ + mos1trun.c diff --git a/src/spicelib/devices/mos1/mos1.c b/src/spicelib/devices/mos1/mos1.c index 82f74bcf5..cdad2144e 100644 --- a/src/spicelib/devices/mos1/mos1.c +++ b/src/spicelib/devices/mos1/mos1.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1987 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -11,6 +12,7 @@ Author: 1987 Thomas L. Quarles #include "suffix.h" IFparm MOS1pTable[] = { /* parameters */ + IOPU("m", MOS1_M, IF_REAL , "Multiplier"), IOPU("l", MOS1_L, IF_REAL , "Length"), IOPU("w", MOS1_W, IF_REAL , "Width"), IOPU("ad", MOS1_AD, IF_REAL , "Drain area"), diff --git a/src/spicelib/devices/mos1/mos1acld.c b/src/spicelib/devices/mos1/mos1acld.c index 3299e7eeb..b6edf7785 100644 --- a/src/spicelib/devices/mos1/mos1acld.c +++ b/src/spicelib/devices/mos1/mos1acld.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* */ @@ -16,10 +17,10 @@ Author: 1985 Thomas L. Quarles int MOS1acLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register MOS1model *model = (MOS1model*)inModel; - register MOS1instance *here; + MOS1model *model = (MOS1model*)inModel; + MOS1instance *here; int xnrm; int xrev; double xgs; @@ -51,12 +52,14 @@ MOS1acLoad(inModel,ckt) * meyer's model parameters */ EffectiveLength=here->MOS1l - 2*model->MOS1latDiff; + GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor * - here->MOS1w; + here->MOS1m * here->MOS1w; GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor * - here->MOS1w; + here->MOS1m * here->MOS1w; GateBulkOverlapCap = model->MOS1gateBulkOverlapCapFactor * - EffectiveLength; + here->MOS1m * EffectiveLength; + capgs = ( *(ckt->CKTstate0+here->MOS1capgs)+ *(ckt->CKTstate0+here->MOS1capgs) + GateSourceOverlapCap ); diff --git a/src/spicelib/devices/mos1/mos1ask.c b/src/spicelib/devices/mos1/mos1ask.c index 2b471061b..ac6fb97b6 100644 --- a/src/spicelib/devices/mos1/mos1ask.c +++ b/src/spicelib/devices/mos1/mos1ask.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1987 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -34,11 +35,14 @@ MOS1ask(ckt,inst,which,value,select) value->rValue = here->MOS1temp-CONSTCtoK; return(OK); case MOS1_CGS: - value->rValue = *(ckt->CKTstate0 + here->MOS1capgs); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS1capgs); return(OK); case MOS1_CGD: - value->rValue = *(ckt->CKTstate0 + here->MOS1capgd); - return(OK); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS1capgd); + return(OK); + case MOS1_M: + value->rValue = here->MOS1m; + return(OK); case MOS1_L: value->rValue = here->MOS1l; return(OK); @@ -178,7 +182,11 @@ MOS1ask(ckt,inst,which,value,select) value->rValue = *(ckt->CKTstate0 + here->MOS1vds); return(OK); case MOS1_CAPGS: - value->rValue = *(ckt->CKTstate0 + here->MOS1capgs); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS1capgs); + /* add overlap capacitance */ + value->rValue += (here->sMOS1modPtr->MOS1gateSourceOverlapCapFactor) + * here->MOS1m + * (here->MOS1w); return(OK); case MOS1_QGS: value->rValue = *(ckt->CKTstate0 + here->MOS1qgs); @@ -187,7 +195,11 @@ MOS1ask(ckt,inst,which,value,select) value->rValue = *(ckt->CKTstate0 + here->MOS1cqgs); return(OK); case MOS1_CAPGD: - value->rValue = *(ckt->CKTstate0 + here->MOS1capgd); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS1capgd); + /* add overlap capacitance */ + value->rValue += (here->sMOS1modPtr->MOS1gateSourceOverlapCapFactor) + * here->MOS1m + * (here->MOS1w); return(OK); case MOS1_QGD: value->rValue = *(ckt->CKTstate0 + here->MOS1qgd); @@ -196,7 +208,12 @@ MOS1ask(ckt,inst,which,value,select) value->rValue = *(ckt->CKTstate0 + here->MOS1cqgd); return(OK); case MOS1_CAPGB: - value->rValue = *(ckt->CKTstate0 + here->MOS1capgb); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS1capgb); + /* add overlap capacitance */ + value->rValue += (here->sMOS1modPtr->MOS1gateBulkOverlapCapFactor) + * here->MOS1m + * (here->MOS1l + -2*(here->sMOS1modPtr->MOS1latDiff)); return(OK); case MOS1_QGB: value->rValue = *(ckt->CKTstate0 + here->MOS1qgb); diff --git a/src/spicelib/devices/mos1/mos1conv.c b/src/spicelib/devices/mos1/mos1conv.c index 50d882744..d9b976579 100644 --- a/src/spicelib/devices/mos1/mos1conv.c +++ b/src/spicelib/devices/mos1/mos1conv.c @@ -13,10 +13,10 @@ Author: 1985 Thomas L. Quarles int MOS1convTest(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register MOS1model *model = (MOS1model*)inModel; - register MOS1instance *here; + MOS1model *model = (MOS1model*)inModel; + MOS1instance *here; double delvbs; double delvbd; double delvgs; diff --git a/src/spicelib/devices/mos1/mos1defs.h b/src/spicelib/devices/mos1/mos1defs.h index fd1a254b0..1d47a28dd 100644 --- a/src/spicelib/devices/mos1/mos1defs.h +++ b/src/spicelib/devices/mos1/mos1defs.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #ifndef MOS1 @@ -30,6 +31,8 @@ typedef struct sMOS1instance { int MOS1bNode; /* number of the bulk node of the mosfet */ int MOS1dNodePrime; /* number of the internal drain node of the mosfet */ int MOS1sNodePrime; /* number of the internal source node of the mosfet */ + + double MOS1m; /* parallel device multiplier */ double MOS1l; /* the length of the channel region */ double MOS1w; /* the width of the channel region */ @@ -156,6 +159,7 @@ typedef struct sMOS1instance { unsigned MOS1off:1; /* non-zero to indicate device is off for dc analysis*/ unsigned MOS1tempGiven :1; /* instance temperature specified */ + unsigned MOS1mGiven :1; unsigned MOS1lGiven :1; unsigned MOS1wGiven :1; unsigned MOS1drainAreaGiven :1; @@ -406,7 +410,7 @@ typedef struct sMOS1model { /* model structure for a resistor */ #define MOS1_CS 18 #define MOS1_POWER 19 #define MOS1_TEMP 20 - +#define MOS1_M 21 /* model paramerers */ #define MOS1_MOD_VTO 101 #define MOS1_MOD_KP 102 diff --git a/src/spicelib/devices/mos1/mos1dist.c b/src/spicelib/devices/mos1/mos1dist.c index 615f9b62f..a0c884f54 100644 --- a/src/spicelib/devices/mos1/mos1dist.c +++ b/src/spicelib/devices/mos1/mos1dist.c @@ -14,7 +14,7 @@ Author: 1988 Jaijeet S Roychowdhury int MOS1disto(mode,genmodel,ckt) GENmodel *genmodel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int mode; /* assuming here that ckt->CKTomega has been initialised to @@ -40,7 +40,7 @@ MOS1disto(mode,genmodel,ckt) double r2h1m2y,i2h1m2y; double r2h1m2z, i2h1m2z; double temp, itemp; - register MOS1instance *here; + MOS1instance *here; if (mode == D_SETUP) return(MOS1dSetup(model,ckt)); diff --git a/src/spicelib/devices/mos1/mos1dset.c b/src/spicelib/devices/mos1/mos1dset.c index 89ced3ed3..8278f01ad 100644 --- a/src/spicelib/devices/mos1/mos1dset.c +++ b/src/spicelib/devices/mos1/mos1dset.c @@ -16,13 +16,13 @@ Author: 1988 Jaijeet S Roychowdhury int MOS1dSetup(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* actually load the current value into the * sparse matrix previously provided */ { - register MOS1model *model = (MOS1model *) inModel; - register MOS1instance *here; + MOS1model *model = (MOS1model *) inModel; + MOS1instance *here; double Beta; double DrainSatCur; double EffectiveLength; @@ -80,9 +80,6 @@ MOS1dSetup(inModel,ckt) double lcapbd2; double lcapbd3; double gmbds; -#ifndef NOBYPASS -#endif /*NOBYPASS*/ - /* loop through all the MOS1 device models */ @@ -94,26 +91,28 @@ MOS1dSetup(inModel,ckt) vt = CONSTKoverQ * here->MOS1temp; EffectiveLength=here->MOS1l - 2*model->MOS1latDiff; - if( (here->MOS1tSatCurDens == 0) || + + if( (here->MOS1tSatCurDens == 0) || (here->MOS1drainArea == 0) || (here->MOS1sourceArea == 0)) { - DrainSatCur = here->MOS1tSatCur; - SourceSatCur = here->MOS1tSatCur; + DrainSatCur = here->MOS1m * here->MOS1tSatCur; + SourceSatCur = here->MOS1m * here->MOS1tSatCur; } else { DrainSatCur = here->MOS1tSatCurDens * - here->MOS1drainArea; + here->MOS1m * here->MOS1drainArea; SourceSatCur = here->MOS1tSatCurDens * - here->MOS1sourceArea; + here->MOS1m * here->MOS1sourceArea; } GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor * - here->MOS1w; + here->MOS1m * here->MOS1w; GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor * - here->MOS1w; + here->MOS1m * here->MOS1w; GateBulkOverlapCap = model->MOS1gateBulkOverlapCapFactor * - EffectiveLength; - Beta = here->MOS1tTransconductance * here->MOS1w/EffectiveLength; + here->MOS1m * EffectiveLength; + Beta = here->MOS1tTransconductance * here->MOS1m * + here->MOS1w/EffectiveLength; OxideCap = model->MOS1oxideCapFactor * EffectiveLength * - here->MOS1w; + here->MOS1m * here->MOS1w; vbs = model->MOS1type * ( *(ckt->CKTrhsOld+here->MOS1bNode) - diff --git a/src/spicelib/devices/mos1/mos1ext.h b/src/spicelib/devices/mos1/mos1ext.h index 94306a507..5a4514b42 100644 --- a/src/spicelib/devices/mos1/mos1ext.h +++ b/src/spicelib/devices/mos1/mos1ext.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #ifdef __STDC__ @@ -27,6 +28,7 @@ extern int MOS1trunc(GENmodel*,CKTcircuit*,double*); extern int MOS1convTest(GENmodel*,CKTcircuit*); extern int MOS1disto(int,GENmodel*,CKTcircuit*); extern int MOS1noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); +extern int MOS1dSetup(GENmodel*,CKTcircuit*); #else /* stdc */ extern int MOS1acLoad(); diff --git a/src/spicelib/devices/mos1/mos1itf.h b/src/spicelib/devices/mos1/mos1itf.h index 38ad3361c..18491393e 100644 --- a/src/spicelib/devices/mos1/mos1itf.h +++ b/src/spicelib/devices/mos1/mos1itf.h @@ -1,101 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_mos1 - #ifndef DEV_MOS1 #define DEV_MOS1 -#include "mos1ext.h" -extern IFparm MOS1pTable[ ]; -extern IFparm MOS1mPTable[ ]; -extern char *MOS1names[ ]; -extern int MOS1pTSize; -extern int MOS1mPTSize; -extern int MOS1nSize; -extern int MOS1iSize; -extern int MOS1mSize; - -SPICEdev MOS1info = { - { - "Mos1", - "Level 1 MOSfet model with Meyer capacitance model", - - &MOS1nSize, - &MOS1nSize, - MOS1names, - - &MOS1pTSize, - MOS1pTable, - - &MOS1mPTSize, - MOS1mPTable, - DEV_DEFAULT - }, - - MOS1param, - MOS1mParam, - MOS1load, - MOS1setup, - MOS1unsetup, - MOS1setup, - MOS1temp, - MOS1trunc, - NULL, - MOS1acLoad, - NULL, - MOS1destroy, -#ifdef DELETES - MOS1mDelete, - MOS1delete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - MOS1getic, - MOS1ask, - MOS1mAsk, -#ifdef AN_pz - MOS1pzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ -#ifdef NEWCONV - MOS1convTest, -#else /* NEWCONV */ - NULL, -#endif /* NEWCONV */ - -#ifdef AN_sense2 - MOS1sSetup, - MOS1sLoad, - MOS1sUpdate, - MOS1sAcLoad, - MOS1sPrint, - NULL, -#else /* AN_sense2 */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -#endif /* AN_sense2 */ -#ifdef AN_disto - MOS1disto, -#else /* AN_disto */ - NULL, -#endif /* AN_disto */ -#ifdef AN_noise - MOS1noise, -#else /* AN_noise */ - NULL, -#endif /* AN_noise */ - - &MOS1iSize, - &MOS1mSize -}; - +extern SPICEdev *get_mos1_info(void); #endif -#endif diff --git a/src/spicelib/devices/mos1/mos1load.c b/src/spicelib/devices/mos1/mos1load.c index bdca66a70..be0bd20f1 100644 --- a/src/spicelib/devices/mos1/mos1load.c +++ b/src/spicelib/devices/mos1/mos1load.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -16,13 +17,13 @@ Author: 1985 Thomas L. Quarles int MOS1load(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* actually load the current value into the * sparse matrix previously provided */ { - register MOS1model *model = (MOS1model *) inModel; - register MOS1instance *here; + MOS1model *model = (MOS1model *) inModel; + MOS1instance *here; double Beta; double DrainSatCur; double EffectiveLength; @@ -75,30 +76,17 @@ MOS1load(inModel,ckt) double capgd; /* total gate-drain capacitance */ double capgb; /* total gate-bulk capacitance */ int Check; -#ifndef NOBYPASS double tempv; -#endif /*NOBYPASS*/ int error; -#ifdef CAPBYPASS - int senflag; -#endif /* CAPBYPASS */ int SenCond; -#ifdef CAPBYPASS - senflag = 0; - if(ckt->CKTsenInfo && ckt->CKTsenInfo->SENstatus == PERTURBATION && - (ckt->CKTsenInfo->SENmode & (ACSEN | TRANSEN))) { - senflag = 1; - } -#endif /* CAPBYPASS */ - /* loop through all the MOS1 device models */ for( ; model != NULL; model = model->MOS1nextModel ) { /* loop through all the instances of the model */ for (here = model->MOS1instances; here != NULL ; - here=here->MOS1nextInstance) { + here=here->MOS1nextInstance) { if (here->MOS1owner != ARCHme) continue; vt = CONSTKoverQ * here->MOS1temp; @@ -109,46 +97,44 @@ MOS1load(inModel,ckt) #endif /* SENSDEBUG */ if((ckt->CKTsenInfo->SENstatus == PERTURBATION)&& - (here->MOS1senPertFlag == OFF))continue; + (here->MOS1senPertFlag == OFF))continue; } SenCond = ckt->CKTsenInfo && here->MOS1senPertFlag; /* - + */ -#ifdef DETAILPROF -asm(" .globl mospta"); -asm("mospta:"); -#endif /*DETAILPROF*/ - /* first, we compute a few useful values - these could be * pre-computed, but for historical reasons are still done * here. They may be moved at the expense of instance size */ EffectiveLength=here->MOS1l - 2*model->MOS1latDiff; + if( (here->MOS1tSatCurDens == 0) || (here->MOS1drainArea == 0) || (here->MOS1sourceArea == 0)) { - DrainSatCur = here->MOS1tSatCur; - SourceSatCur = here->MOS1tSatCur; + DrainSatCur = here->MOS1m * here->MOS1tSatCur; + SourceSatCur = here->MOS1m * here->MOS1tSatCur; } else { DrainSatCur = here->MOS1tSatCurDens * - here->MOS1drainArea; + here->MOS1m * here->MOS1drainArea; SourceSatCur = here->MOS1tSatCurDens * - here->MOS1sourceArea; + here->MOS1m * here->MOS1sourceArea; } GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor * - here->MOS1w; + here->MOS1m * here->MOS1w; GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor * - here->MOS1w; + here->MOS1m * here->MOS1w; GateBulkOverlapCap = model->MOS1gateBulkOverlapCapFactor * - EffectiveLength; - Beta = here->MOS1tTransconductance * here->MOS1w/EffectiveLength; + here->MOS1m * EffectiveLength; + Beta = here->MOS1tTransconductance * here->MOS1m * + here->MOS1w/EffectiveLength; OxideCap = model->MOS1oxideCapFactor * EffectiveLength * - here->MOS1w; + here->MOS1m * here->MOS1w; + /* * ok - now to do the start-up operations * @@ -164,7 +150,7 @@ asm("mospta:"); printf("MOS1senPertFlag = ON \n"); #endif /* SENSDEBUG */ if((ckt->CKTsenInfo->SENmode == TRANSEN) && - (ckt->CKTmode & MODEINITTRAN)) { + (ckt->CKTmode & MODEINITTRAN)) { vgs = *(ckt->CKTstate1 + here->MOS1vgs); vds = *(ckt->CKTstate1 + here->MOS1vds); vbs = *(ckt->CKTstate1 + here->MOS1vbs); @@ -199,8 +185,8 @@ asm("mospta:"); if((ckt->CKTmode & (MODEINITFLOAT | MODEINITPRED | MODEINITSMSIG - | MODEINITTRAN)) || - ( (ckt->CKTmode & MODEINITFIX) && (!here->MOS1off) ) ) { + | MODEINITTRAN)) || + ( (ckt->CKTmode & MODEINITFIX) && (!here->MOS1off) ) ) { #ifndef PREDICTOR if(ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) { @@ -208,20 +194,20 @@ asm("mospta:"); xfact=ckt->CKTdelta/ckt->CKTdeltaOld[1]; *(ckt->CKTstate0 + here->MOS1vbs) = - *(ckt->CKTstate1 + here->MOS1vbs); + *(ckt->CKTstate1 + here->MOS1vbs); vbs = (1+xfact)* (*(ckt->CKTstate1 + here->MOS1vbs)) - -(xfact * (*(ckt->CKTstate2 + here->MOS1vbs))); + -(xfact * (*(ckt->CKTstate2 + here->MOS1vbs))); *(ckt->CKTstate0 + here->MOS1vgs) = - *(ckt->CKTstate1 + here->MOS1vgs); + *(ckt->CKTstate1 + here->MOS1vgs); vgs = (1+xfact)* (*(ckt->CKTstate1 + here->MOS1vgs)) - -(xfact * (*(ckt->CKTstate2 + here->MOS1vgs))); + -(xfact * (*(ckt->CKTstate2 + here->MOS1vgs))); *(ckt->CKTstate0 + here->MOS1vds) = - *(ckt->CKTstate1 + here->MOS1vds); + *(ckt->CKTstate1 + here->MOS1vds); vds = (1+xfact)* (*(ckt->CKTstate1 + here->MOS1vds)) - -(xfact * (*(ckt->CKTstate2 + here->MOS1vds))); + -(xfact * (*(ckt->CKTstate2 + here->MOS1vds))); *(ckt->CKTstate0 + here->MOS1vbd) = - *(ckt->CKTstate0 + here->MOS1vbs)- - *(ckt->CKTstate0 + here->MOS1vds); + *(ckt->CKTstate0 + here->MOS1vbs)- + *(ckt->CKTstate0 + here->MOS1vds); } else { #endif /* PREDICTOR */ @@ -245,7 +231,7 @@ asm("mospta:"); vbd=vbs-vds; vgd=vgs-vds; vgdo = *(ckt->CKTstate0 + here->MOS1vgs) - - *(ckt->CKTstate0 + here->MOS1vds); + *(ckt->CKTstate0 + here->MOS1vds); delvbs = vbs - *(ckt->CKTstate0 + here->MOS1vbs); delvbd = vbd - *(ckt->CKTstate0 + here->MOS1vbd); delvgs = vgs - *(ckt->CKTstate0 + here->MOS1vgs); @@ -265,7 +251,7 @@ asm("mospta:"); cdhat= here->MOS1cd - ( here->MOS1gbd - - here->MOS1gmbs) * delvbd - + here->MOS1gmbs) * delvbd - here->MOS1gm * delvgd + here->MOS1gds * delvds ; } @@ -275,82 +261,79 @@ asm("mospta:"); here->MOS1gbd * delvbd + here->MOS1gbs * delvbs ; /* - + */ -#ifdef DETAILPROF -asm(" .globl mosptb"); -asm("mosptb:"); -#endif /*DETAILPROF*/ -#ifndef NOBYPASS /* now lets see if we can bypass (ugh) */ - /* the following mess should be one if statement, but - * many compilers can't handle it all at once, so it - * is split into several successive if statements - */ - tempv = MAX(fabs(cbhat),fabs(here->MOS1cbs - + here->MOS1cbd))+ckt->CKTabstol; - if((!(ckt->CKTmode & (MODEINITPRED|MODEINITTRAN|MODEINITSMSIG) - )) && (ckt->CKTbypass) ) - if ( (fabs(cbhat-(here->MOS1cbs + - here->MOS1cbd)) < ckt->CKTreltol * - tempv)) - if( (fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs), - fabs(*(ckt->CKTstate0+here->MOS1vbs)))+ - ckt->CKTvoltTol))) - if ( (fabs(delvbd) < (ckt->CKTreltol * MAX(fabs(vbd), - fabs(*(ckt->CKTstate0+here->MOS1vbd)))+ - ckt->CKTvoltTol)) ) - if( (fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs), - fabs(*(ckt->CKTstate0+here->MOS1vgs)))+ - ckt->CKTvoltTol))) - if ( (fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), - fabs(*(ckt->CKTstate0+here->MOS1vds)))+ - ckt->CKTvoltTol)) ) - if( (fabs(cdhat- here->MOS1cd) < - ckt->CKTreltol * MAX(fabs(cdhat),fabs( - here->MOS1cd)) + ckt->CKTabstol) ) { + tempv = (MAX(fabs(cbhat), + fabs(here->MOS1cbs + here->MOS1cbd)) + + ckt->CKTabstol); + if ((!(ckt->CKTmode & + (MODEINITPRED|MODEINITTRAN|MODEINITSMSIG))) && + (ckt->CKTbypass) && + (fabs(cbhat-(here->MOS1cbs + + here->MOS1cbd)) < ckt->CKTreltol * tempv) && + (fabs(delvbs) < (ckt->CKTreltol * + MAX(fabs(vbs), + fabs( *(ckt->CKTstate0 + + here->MOS1vbs))) + + ckt->CKTvoltTol)) && + (fabs(delvbd) < (ckt->CKTreltol * + MAX(fabs(vbd), + fabs(*(ckt->CKTstate0 + + here->MOS1vbd))) + + ckt->CKTvoltTol)) && + (fabs(delvgs) < (ckt->CKTreltol * + MAX(fabs(vgs), + fabs(*(ckt->CKTstate0 + + here->MOS1vgs)))+ + ckt->CKTvoltTol)) && + (fabs(delvds) < (ckt->CKTreltol * + MAX(fabs(vds), + fabs(*(ckt->CKTstate0 + + here->MOS1vds))) + + ckt->CKTvoltTol)) && + (fabs(cdhat- here->MOS1cd) < (ckt->CKTreltol * + MAX(fabs(cdhat), + fabs(here->MOS1cd)) + + ckt->CKTabstol))) { /* bypass code */ - /* nothing interesting has changed since last - * iteration on this device, so we just - * copy all the values computed last iteration out - * and keep going - */ - vbs = *(ckt->CKTstate0 + here->MOS1vbs); - vbd = *(ckt->CKTstate0 + here->MOS1vbd); - vgs = *(ckt->CKTstate0 + here->MOS1vgs); - vds = *(ckt->CKTstate0 + here->MOS1vds); - vgd = vgs - vds; - vgb = vgs - vbs; - cdrain = here->MOS1mode * (here->MOS1cd + here->MOS1cbd); - if(ckt->CKTmode & (MODETRAN | MODETRANOP)) { - capgs = ( *(ckt->CKTstate0+here->MOS1capgs)+ - *(ckt->CKTstate1+here->MOS1capgs) + - GateSourceOverlapCap ); - capgd = ( *(ckt->CKTstate0+here->MOS1capgd)+ - *(ckt->CKTstate1+here->MOS1capgd) + - GateDrainOverlapCap ); - capgb = ( *(ckt->CKTstate0+here->MOS1capgb)+ - *(ckt->CKTstate1+here->MOS1capgb) + - GateBulkOverlapCap ); + /* nothing interesting has changed since last + * iteration on this device, so we just + * copy all the values computed last iteration out + * and keep going + */ + vbs = *(ckt->CKTstate0 + here->MOS1vbs); + vbd = *(ckt->CKTstate0 + here->MOS1vbd); + vgs = *(ckt->CKTstate0 + here->MOS1vgs); + vds = *(ckt->CKTstate0 + here->MOS1vds); + vgd = vgs - vds; + vgb = vgs - vbs; + cdrain = here->MOS1mode * (here->MOS1cd + here->MOS1cbd); + if(ckt->CKTmode & (MODETRAN | MODETRANOP)) { + capgs = ( *(ckt->CKTstate0+here->MOS1capgs)+ + *(ckt->CKTstate1+here->MOS1capgs) + + GateSourceOverlapCap ); + capgd = ( *(ckt->CKTstate0+here->MOS1capgd)+ + *(ckt->CKTstate1+here->MOS1capgd) + + GateDrainOverlapCap ); + capgb = ( *(ckt->CKTstate0+here->MOS1capgb)+ + *(ckt->CKTstate1+here->MOS1capgb) + + GateBulkOverlapCap ); + + if(ckt->CKTsenInfo){ + here->MOS1cgs = capgs; + here->MOS1cgd = capgd; + here->MOS1cgb = capgb; + } + } + goto bypass; + } - if(ckt->CKTsenInfo){ - here->MOS1cgs = capgs; - here->MOS1cgd = capgd; - here->MOS1cgb = capgb; - } - } - goto bypass; - } -#endif /*NOBYPASS*/ /* - + */ -#ifdef DETAILPROF -asm(" .globl mosptc"); -asm("mosptc:"); -#endif /*DETAILPROF*/ /* ok - bypass is out, do it the hard way */ von = model->MOS1type * here->MOS1von; @@ -365,7 +348,7 @@ asm("mosptc:"); if(*(ckt->CKTstate0 + here->MOS1vds) >=0) { vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->MOS1vgs) - ,von); + ,von); vds = vgs - vgd; vds = DEVlimvds(vds,*(ckt->CKTstate0 + here->MOS1vds)); vgd = vgs - vds; @@ -374,28 +357,24 @@ asm("mosptc:"); vds = vgs - vgd; if(!(ckt->CKTfixLimit)) { vds = -DEVlimvds(-vds,-(*(ckt->CKTstate0 + - here->MOS1vds))); + here->MOS1vds))); } vgs = vgd + vds; } if(vds >= 0) { vbs = DEVpnjlim(vbs,*(ckt->CKTstate0 + here->MOS1vbs), - vt,here->MOS1sourceVcrit,&Check); + vt,here->MOS1sourceVcrit,&Check); vbd = vbs-vds; } else { vbd = DEVpnjlim(vbd,*(ckt->CKTstate0 + here->MOS1vbd), - vt,here->MOS1drainVcrit,&Check); + vt,here->MOS1drainVcrit,&Check); vbs = vbd + vds; } #endif /*NODELIMITING*/ /* - + */ -#ifdef DETAILPROF -asm(" .globl mosptd"); -asm("mosptd:"); -#endif /*DETAILPROF*/ } else { /* ok - not one of the simple cases, so we have to @@ -408,9 +387,9 @@ asm("mosptd:"); vgs= model->MOS1type * here->MOS1icVGS; vbs= model->MOS1type * here->MOS1icVBS; if((vds==0) && (vgs==0) && (vbs==0) && - ((ckt->CKTmode & - (MODETRAN|MODEDCOP|MODEDCTRANCURVE)) || - (!(ckt->CKTmode & MODEUIC)))) { + ((ckt->CKTmode & + (MODETRAN|MODEDCOP|MODEDCTRANCURVE)) || + (!(ckt->CKTmode & MODEUIC)))) { vbs = -1; vgs = model->MOS1type * here->MOS1tVto; vds = 0; @@ -420,14 +399,9 @@ asm("mosptd:"); } } /* - + */ -#ifdef DETAILPROF -asm(" .globl mospte"); -asm("mospte:"); -#endif /*DETAILPROF*/ - /* * now all the preliminaries are over - we can start doing the * real work @@ -442,25 +416,22 @@ asm("mospte:"); * here we just evaluate the ideal diode current and the * corresponding derivative (conductance). */ -next1: if(vbs <= 0) { - here->MOS1gbs = SourceSatCur/vt; - here->MOS1cbs = here->MOS1gbs*vbs; - here->MOS1gbs += ckt->CKTgmin; +next1: if(vbs <= -3*vt) { + here->MOS1gbs = ckt->CKTgmin; + here->MOS1cbs = here->MOS1gbs*vbs-SourceSatCur; } else { evbs = exp(MIN(MAX_EXP_ARG,vbs/vt)); here->MOS1gbs = SourceSatCur*evbs/vt + ckt->CKTgmin; - here->MOS1cbs = SourceSatCur * (evbs-1); + here->MOS1cbs = SourceSatCur*(evbs-1) + ckt->CKTgmin*vbs; } - if(vbd <= 0) { - here->MOS1gbd = DrainSatCur/vt; - here->MOS1cbd = here->MOS1gbd *vbd; - here->MOS1gbd += ckt->CKTgmin; + if(vbd <= -3*vt) { + here->MOS1gbd = ckt->CKTgmin; + here->MOS1cbd = here->MOS1gbd*vbd-DrainSatCur; } else { evbd = exp(MIN(MAX_EXP_ARG,vbd/vt)); - here->MOS1gbd = DrainSatCur*evbd/vt +ckt->CKTgmin; - here->MOS1cbd = DrainSatCur *(evbd-1); + here->MOS1gbd = DrainSatCur*evbd/vt + ckt->CKTgmin; + here->MOS1cbd = DrainSatCur*(evbd-1) + ckt->CKTgmin*vbd; } - /* now to determine whether the user was able to correctly * identify the source and drain of his device */ @@ -472,29 +443,25 @@ next1: if(vbs <= 0) { here->MOS1mode = -1; } /* - + */ -#ifdef DETAILPROF -asm(" .globl mosptf"); -asm("mosptf:"); -#endif /*DETAILPROF*/ { - /* - * this block of code evaluates the drain current and its - * derivatives using the shichman-hodges model and the - * charges associated with the gate, channel and bulk for - * mosfets - * - */ + /* + * this block of code evaluates the drain current and its + * derivatives using the shichman-hodges model and the + * charges associated with the gate, channel and bulk for + * mosfets + * + */ - /* the following 4 variables are local to this code block until - * it is obvious that they can be made global - */ - double arg; - double betap; - double sarg; - double vgst; + /* the following 4 variables are local to this code block until + * it is obvious that they can be made global + */ + double arg; + double betap; + double sarg; + double vgst; if ((here->MOS1mode==1?vbs:vbd) <= 0 ) { sarg=sqrt(here->MOS1tPhi-(here->MOS1mode==1?vbs:vbd)); @@ -530,16 +497,16 @@ asm("mosptf:"); here->MOS1gds=model->MOS1lambda*Beta*vgst*vgst*.5; here->MOS1gmbs=here->MOS1gm*arg; } else { - /* - * linear region - */ + /* + * linear region + */ cdrain=betap*(vds*here->MOS1mode)* (vgst-.5*(vds*here->MOS1mode)); here->MOS1gm=betap*(vds*here->MOS1mode); here->MOS1gds=betap*(vgst-(vds*here->MOS1mode))+ - model->MOS1lambda*Beta* - (vds*here->MOS1mode)* - (vgst-.5*(vds*here->MOS1mode)); + model->MOS1lambda*Beta* + (vds*here->MOS1mode)* + (vgst-.5*(vds*here->MOS1mode)); here->MOS1gmbs=here->MOS1gm*arg; } } @@ -548,14 +515,9 @@ asm("mosptf:"); */ } /* - + */ -#ifdef DETAILPROF -asm(" .globl mosptg"); -asm("mosptg:"); -#endif /*DETAILPROF*/ - /* now deal with n vs p polarity */ here->MOS1von = model->MOS1type * von; @@ -581,152 +543,127 @@ asm("mosptg:"); * *.. bulk-drain and bulk-source depletion capacitances */ -#ifdef CAPBYPASS - if(((ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) || - fabs(delvbs) >= ckt->CKTreltol * MAX(fabs(vbs), - fabs(*(ckt->CKTstate0+here->MOS1vbs)))+ - ckt->CKTvoltTol)|| senflag) -#endif /*CAPBYPASS*/ { /* can't bypass the diode capacitance calculations */ -#ifdef CAPZEROBYPASS if(here->MOS1Cbs != 0 || here->MOS1Cbssw != 0 ) { -#endif /*CAPZEROBYPASS*/ - if (vbs < here->MOS1tDepCap){ - arg=1-vbs/here->MOS1tBulkPot; - /* - * the following block looks somewhat long and messy, - * but since most users use the default grading - * coefficients of .5, and sqrt is MUCH faster than an - * exp(log()) we use this special case code to buy time. - * (as much as 10% of total job time!) - */ + if (vbs < here->MOS1tDepCap){ + arg=1-vbs/here->MOS1tBulkPot; + /* + * the following block looks somewhat long and messy, + * but since most users use the default grading + * coefficients of .5, and sqrt is MUCH faster than an + * exp(log()) we use this special case code to buy time. + * (as much as 10% of total job time!) + */ #ifndef NOSQRT - if(model->MOS1bulkJctBotGradingCoeff == - model->MOS1bulkJctSideGradingCoeff) { - if(model->MOS1bulkJctBotGradingCoeff == .5) { - sarg = sargsw = 1/sqrt(arg); - } else { - sarg = sargsw = + if(model->MOS1bulkJctBotGradingCoeff == + model->MOS1bulkJctSideGradingCoeff) { + if(model->MOS1bulkJctBotGradingCoeff == .5) { + sarg = sargsw = 1/sqrt(arg); + } else { + sarg = sargsw = exp(-model->MOS1bulkJctBotGradingCoeff* - log(arg)); - } - } else { - if(model->MOS1bulkJctBotGradingCoeff == .5) { - sarg = 1/sqrt(arg); - } else { + log(arg)); + } + } else { + if(model->MOS1bulkJctBotGradingCoeff == .5) { + sarg = 1/sqrt(arg); + } else { #endif /*NOSQRT*/ - sarg = exp(-model->MOS1bulkJctBotGradingCoeff* - log(arg)); + sarg = exp(-model->MOS1bulkJctBotGradingCoeff* + log(arg)); #ifndef NOSQRT - } - if(model->MOS1bulkJctSideGradingCoeff == .5) { - sargsw = 1/sqrt(arg); - } else { + } + if(model->MOS1bulkJctSideGradingCoeff == .5) { + sargsw = 1/sqrt(arg); + } else { #endif /*NOSQRT*/ - sargsw =exp(-model->MOS1bulkJctSideGradingCoeff* - log(arg)); + sargsw =exp(-model->MOS1bulkJctSideGradingCoeff* + log(arg)); #ifndef NOSQRT - } - } + } + } #endif /*NOSQRT*/ - *(ckt->CKTstate0 + here->MOS1qbs) = - here->MOS1tBulkPot*(here->MOS1Cbs* - (1-arg*sarg)/(1-model->MOS1bulkJctBotGradingCoeff) - +here->MOS1Cbssw* - (1-arg*sargsw)/ - (1-model->MOS1bulkJctSideGradingCoeff)); - here->MOS1capbs=here->MOS1Cbs*sarg+ + *(ckt->CKTstate0 + here->MOS1qbs) = + here->MOS1tBulkPot*(here->MOS1Cbs* + (1-arg*sarg)/(1-model->MOS1bulkJctBotGradingCoeff) + +here->MOS1Cbssw* + (1-arg*sargsw)/ + (1-model->MOS1bulkJctSideGradingCoeff)); + here->MOS1capbs=here->MOS1Cbs*sarg+ here->MOS1Cbssw*sargsw; - } else { - *(ckt->CKTstate0 + here->MOS1qbs) = here->MOS1f4s + + } else { + *(ckt->CKTstate0 + here->MOS1qbs) = here->MOS1f4s + vbs*(here->MOS1f2s+vbs*(here->MOS1f3s/2)); - here->MOS1capbs=here->MOS1f2s+here->MOS1f3s*vbs; - } -#ifdef CAPZEROBYPASS + here->MOS1capbs=here->MOS1f2s+here->MOS1f3s*vbs; + } } else { - *(ckt->CKTstate0 + here->MOS1qbs) = 0; + *(ckt->CKTstate0 + here->MOS1qbs) = 0; here->MOS1capbs=0; } -#endif /*CAPZEROBYPASS*/ } -#ifdef CAPBYPASS - if(((ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) || - fabs(delvbd) >= ckt->CKTreltol * MAX(fabs(vbd), - fabs(*(ckt->CKTstate0+here->MOS1vbd)))+ - ckt->CKTvoltTol)|| senflag) -#endif /*CAPBYPASS*/ /* can't bypass the diode capacitance calculations */ { -#ifdef CAPZEROBYPASS if(here->MOS1Cbd != 0 || here->MOS1Cbdsw != 0 ) { -#endif /*CAPZEROBYPASS*/ - if (vbd < here->MOS1tDepCap) { - arg=1-vbd/here->MOS1tBulkPot; - /* - * the following block looks somewhat long and messy, - * but since most users use the default grading - * coefficients of .5, and sqrt is MUCH faster than an - * exp(log()) we use this special case code to buy time. - * (as much as 10% of total job time!) - */ + if (vbd < here->MOS1tDepCap) { + arg=1-vbd/here->MOS1tBulkPot; + /* + * the following block looks somewhat long and messy, + * but since most users use the default grading + * coefficients of .5, and sqrt is MUCH faster than an + * exp(log()) we use this special case code to buy time. + * (as much as 10% of total job time!) + */ #ifndef NOSQRT - if(model->MOS1bulkJctBotGradingCoeff == .5 && - model->MOS1bulkJctSideGradingCoeff == .5) { - sarg = sargsw = 1/sqrt(arg); - } else { - if(model->MOS1bulkJctBotGradingCoeff == .5) { - sarg = 1/sqrt(arg); - } else { + if(model->MOS1bulkJctBotGradingCoeff == .5 && + model->MOS1bulkJctSideGradingCoeff == .5) { + sarg = sargsw = 1/sqrt(arg); + } else { + if(model->MOS1bulkJctBotGradingCoeff == .5) { + sarg = 1/sqrt(arg); + } else { #endif /*NOSQRT*/ - sarg = exp(-model->MOS1bulkJctBotGradingCoeff* - log(arg)); + sarg = exp(-model->MOS1bulkJctBotGradingCoeff* + log(arg)); #ifndef NOSQRT - } - if(model->MOS1bulkJctSideGradingCoeff == .5) { - sargsw = 1/sqrt(arg); - } else { + } + if(model->MOS1bulkJctSideGradingCoeff == .5) { + sargsw = 1/sqrt(arg); + } else { #endif /*NOSQRT*/ - sargsw =exp(-model->MOS1bulkJctSideGradingCoeff* - log(arg)); + sargsw =exp(-model->MOS1bulkJctSideGradingCoeff* + log(arg)); #ifndef NOSQRT - } - } + } + } #endif /*NOSQRT*/ - *(ckt->CKTstate0 + here->MOS1qbd) = - here->MOS1tBulkPot*(here->MOS1Cbd* - (1-arg*sarg) - /(1-model->MOS1bulkJctBotGradingCoeff) - +here->MOS1Cbdsw* - (1-arg*sargsw) - /(1-model->MOS1bulkJctSideGradingCoeff)); - here->MOS1capbd=here->MOS1Cbd*sarg+ + *(ckt->CKTstate0 + here->MOS1qbd) = + here->MOS1tBulkPot*(here->MOS1Cbd* + (1-arg*sarg) + /(1-model->MOS1bulkJctBotGradingCoeff) + +here->MOS1Cbdsw* + (1-arg*sargsw) + /(1-model->MOS1bulkJctSideGradingCoeff)); + here->MOS1capbd=here->MOS1Cbd*sarg+ here->MOS1Cbdsw*sargsw; - } else { - *(ckt->CKTstate0 + here->MOS1qbd) = here->MOS1f4d + + } else { + *(ckt->CKTstate0 + here->MOS1qbd) = here->MOS1f4d + vbd * (here->MOS1f2d + vbd * here->MOS1f3d/2); - here->MOS1capbd=here->MOS1f2d + vbd * here->MOS1f3d; - } -#ifdef CAPZEROBYPASS - } else { - *(ckt->CKTstate0 + here->MOS1qbd) = 0; - here->MOS1capbd = 0; - } -#endif /*CAPZEROBYPASS*/ + here->MOS1capbd=here->MOS1f2d + vbd * here->MOS1f3d; + } + } else { + *(ckt->CKTstate0 + here->MOS1qbd) = 0; + here->MOS1capbd = 0; + } } /* - + */ -#ifdef DETAILPROF -asm(" .globl mospth"); -asm("mospth:"); -#endif /*DETAILPROF*/ - if(SenCond && (ckt->CKTsenInfo->SENmode==TRANSEN)) goto next2; if ( (ckt->CKTmode & MODETRAN) || ( (ckt->CKTmode&MODEINITTRAN) - && !(ckt->CKTmode&MODEUIC)) ) { + && !(ckt->CKTmode&MODEUIC)) ) { /* (above only excludes tranop, since we're only at this * point if tran or tranop ) */ @@ -739,27 +676,22 @@ asm("mospth:"); /* integrate the capacitors and save results */ error = NIintegrate(ckt,&geq,&ceq,here->MOS1capbd, - here->MOS1qbd); + here->MOS1qbd); if(error) return(error); here->MOS1gbd += geq; here->MOS1cbd += *(ckt->CKTstate0 + here->MOS1cqbd); here->MOS1cd -= *(ckt->CKTstate0 + here->MOS1cqbd); error = NIintegrate(ckt,&geq,&ceq,here->MOS1capbs, - here->MOS1qbs); + here->MOS1qbs); if(error) return(error); here->MOS1gbs += geq; here->MOS1cbs += *(ckt->CKTstate0 + here->MOS1cqbs); } } /* - + */ -#ifdef DETAILPROF -asm(" .globl mospti"); -asm("mospti:"); -#endif /*DETAILPROF*/ - if(SenCond) goto next2; @@ -767,53 +699,27 @@ asm("mospti:"); * check convergence */ if ( (here->MOS1off == 0) || - (!(ckt->CKTmode & (MODEINITFIX|MODEINITSMSIG))) ){ + (!(ckt->CKTmode & (MODEINITFIX|MODEINITSMSIG))) ){ if (Check == 1) { ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) here; -#ifndef NEWCONV - } else { - tol=ckt->CKTreltol*MAX(fabs(cdhat), - fabs(here->MOS1cd))+ckt->CKTabstol; - if (fabs(cdhat-here->MOS1cd) >= tol) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; - } else { - tol=ckt->CKTreltol*MAX(fabs(cbhat), - fabs(here->MOS1cbs+here->MOS1cbd))+ - ckt->CKTabstol; - if (fabs(cbhat-(here->MOS1cbs+here->MOS1cbd)) > tol) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; - } - } -#endif /*NEWCONV*/ } } /* - + */ -#ifdef DETAILPROF -asm(" .globl mosptj"); -asm("mosptj:"); -#endif /*DETAILPROF*/ - /* save things away for next time */ -next2: *(ckt->CKTstate0 + here->MOS1vbs) = vbs; + next2: *(ckt->CKTstate0 + here->MOS1vbs) = vbs; *(ckt->CKTstate0 + here->MOS1vbd) = vbd; *(ckt->CKTstate0 + here->MOS1vgs) = vgs; *(ckt->CKTstate0 + here->MOS1vds) = vds; /* - + */ -#ifdef DETAILPROF -asm(" .globl mosptk"); -asm("mosptk:"); -#endif /*DETAILPROF*/ /* * meyer's capacitor model */ @@ -830,27 +736,27 @@ asm("mosptk:"); */ if (here->MOS1mode > 0){ DEVqmeyer (vgs,vgd,vgb,von,vdsat, - (ckt->CKTstate0 + here->MOS1capgs), - (ckt->CKTstate0 + here->MOS1capgd), - (ckt->CKTstate0 + here->MOS1capgb), - here->MOS1tPhi,OxideCap); + (ckt->CKTstate0 + here->MOS1capgs), + (ckt->CKTstate0 + here->MOS1capgd), + (ckt->CKTstate0 + here->MOS1capgb), + here->MOS1tPhi,OxideCap); } else { DEVqmeyer (vgd,vgs,vgb,von,vdsat, - (ckt->CKTstate0 + here->MOS1capgd), - (ckt->CKTstate0 + here->MOS1capgs), - (ckt->CKTstate0 + here->MOS1capgb), - here->MOS1tPhi,OxideCap); + (ckt->CKTstate0 + here->MOS1capgd), + (ckt->CKTstate0 + here->MOS1capgs), + (ckt->CKTstate0 + here->MOS1capgb), + here->MOS1tPhi,OxideCap); } vgs1 = *(ckt->CKTstate1 + here->MOS1vgs); vgd1 = vgs1 - *(ckt->CKTstate1 + here->MOS1vds); vgb1 = vgs1 - *(ckt->CKTstate1 + here->MOS1vbs); if(ckt->CKTmode & (MODETRANOP|MODEINITSMSIG)) { capgs = 2 * *(ckt->CKTstate0+here->MOS1capgs)+ - GateSourceOverlapCap ; + GateSourceOverlapCap ; capgd = 2 * *(ckt->CKTstate0+here->MOS1capgd)+ - GateDrainOverlapCap ; + GateDrainOverlapCap ; capgb = 2 * *(ckt->CKTstate0+here->MOS1capgb)+ - GateBulkOverlapCap ; + GateBulkOverlapCap ; } else { capgs = ( *(ckt->CKTstate0+here->MOS1capgs)+ *(ckt->CKTstate1+here->MOS1capgs) + @@ -868,20 +774,16 @@ asm("mosptk:"); here->MOS1cgb = capgb; } /* - + */ -#ifdef DETAILPROF -asm(" .globl mosptl"); -asm("mosptl:"); -#endif /*DETAILPROF*/ /* * store small-signal parameters (for meyer's model) * all parameters already stored, so done... */ if(SenCond){ if((ckt->CKTsenInfo->SENmode == DCSEN)|| - (ckt->CKTsenInfo->SENmode == ACSEN)){ + (ckt->CKTsenInfo->SENmode == ACSEN)){ continue; } } @@ -916,11 +818,11 @@ asm("mosptl:"); } #endif /*PREDICTOR*/ } -bypass: + bypass: if(SenCond) continue; if ( (ckt->CKTmode & (MODEINITTRAN)) || - (! (ckt->CKTmode & (MODETRAN)) ) ) { + (! (ckt->CKTmode & (MODETRAN)) ) ) { /* * initialize to zero charge conductances * and current @@ -946,11 +848,11 @@ bypass: error = NIintegrate(ckt,&gcgb,&ceqgb,capgb,here->MOS1qgb); if(error) return(error); ceqgs=ceqgs-gcgs*vgs+ckt->CKTag[0]* - *(ckt->CKTstate0 + here->MOS1qgs); + *(ckt->CKTstate0 + here->MOS1qgs); ceqgd=ceqgd-gcgd*vgd+ckt->CKTag[0]* - *(ckt->CKTstate0 + here->MOS1qgd); + *(ckt->CKTstate0 + here->MOS1qgd); ceqgb=ceqgb-gcgb*vgb+ckt->CKTag[0]* - *(ckt->CKTstate0 + here->MOS1qgb); + *(ckt->CKTstate0 + here->MOS1qgb); } /* * store charge storage info for meyer's cap in lx table @@ -960,28 +862,28 @@ bypass: * load current vector */ ceqbs = model->MOS1type * - (here->MOS1cbs-(here->MOS1gbs-ckt->CKTgmin)*vbs); + (here->MOS1cbs-(here->MOS1gbs)*vbs); ceqbd = model->MOS1type * - (here->MOS1cbd-(here->MOS1gbd-ckt->CKTgmin)*vbd); + (here->MOS1cbd-(here->MOS1gbd)*vbd); if (here->MOS1mode >= 0) { xnrm=1; xrev=0; cdreq=model->MOS1type*(cdrain-here->MOS1gds*vds- - here->MOS1gm*vgs-here->MOS1gmbs*vbs); + here->MOS1gm*vgs-here->MOS1gmbs*vbs); } else { xnrm=0; xrev=1; cdreq = -(model->MOS1type)*(cdrain-here->MOS1gds*(-vds)- - here->MOS1gm*vgd-here->MOS1gmbs*vbd); + here->MOS1gm*vgd-here->MOS1gmbs*vbd); } *(ckt->CKTrhs + here->MOS1gNode) -= (model->MOS1type * (ceqgs + ceqgb + ceqgd)); *(ckt->CKTrhs + here->MOS1bNode) -= (ceqbs + ceqbd - model->MOS1type * ceqgb); *(ckt->CKTrhs + here->MOS1dNodePrime) += - (ceqbd - cdreq + model->MOS1type * ceqgd); + (ceqbd - cdreq + model->MOS1type * ceqgd); *(ckt->CKTrhs + here->MOS1sNodePrime) += - cdreq + ceqbs + model->MOS1type * ceqgs; + cdreq + ceqbs + model->MOS1type * ceqgs; /* * load y matrix */ @@ -991,11 +893,11 @@ bypass: *(here->MOS1SsPtr) += (here->MOS1sourceConductance); *(here->MOS1BbPtr) += (here->MOS1gbd+here->MOS1gbs+gcgb); *(here->MOS1DPdpPtr) += - (here->MOS1drainConductance+here->MOS1gds+ - here->MOS1gbd+xrev*(here->MOS1gm+here->MOS1gmbs)+gcgd); + (here->MOS1drainConductance+here->MOS1gds+ + here->MOS1gbd+xrev*(here->MOS1gm+here->MOS1gmbs)+gcgd); *(here->MOS1SPspPtr) += - (here->MOS1sourceConductance+here->MOS1gds+ - here->MOS1gbs+xnrm*(here->MOS1gm+here->MOS1gmbs)+gcgs); + (here->MOS1sourceConductance+here->MOS1gds+ + here->MOS1gbs+xnrm*(here->MOS1gm+here->MOS1gmbs)+gcgs); *(here->MOS1DdpPtr) += (-here->MOS1drainConductance); *(here->MOS1GbPtr) -= gcgb; *(here->MOS1GdpPtr) -= gcgd; @@ -1008,12 +910,12 @@ bypass: *(here->MOS1DPgPtr) += ((xnrm-xrev)*here->MOS1gm-gcgd); *(here->MOS1DPbPtr) += (-here->MOS1gbd+(xnrm-xrev)*here->MOS1gmbs); *(here->MOS1DPspPtr) += (-here->MOS1gds-xnrm* - (here->MOS1gm+here->MOS1gmbs)); + (here->MOS1gm+here->MOS1gmbs)); *(here->MOS1SPgPtr) += (-(xnrm-xrev)*here->MOS1gm-gcgs); *(here->MOS1SPsPtr) += (-here->MOS1sourceConductance); *(here->MOS1SPbPtr) += (-here->MOS1gbs-(xnrm-xrev)*here->MOS1gmbs); *(here->MOS1SPdpPtr) += (-here->MOS1gds-xrev* - (here->MOS1gm+here->MOS1gmbs)); + (here->MOS1gm+here->MOS1gmbs)); } } return(OK); diff --git a/src/spicelib/devices/mos1/mos1mpar.c b/src/spicelib/devices/mos1/mos1mpar.c index 4eefc0e7d..9e08d2b56 100644 --- a/src/spicelib/devices/mos1/mos1mpar.c +++ b/src/spicelib/devices/mos1/mos1mpar.c @@ -17,7 +17,7 @@ MOS1mParam(param,value,inModel) IFvalue *value; GENmodel *inModel; { - register MOS1model *model = (MOS1model *)inModel; + MOS1model *model = (MOS1model *)inModel; switch(param) { case MOS1_MOD_TNOM: model->MOS1tnom = value->rValue+CONSTCtoK; diff --git a/src/spicelib/devices/mos1/mos1noi.c b/src/spicelib/devices/mos1/mos1noi.c index 666a20281..1da24d77e 100644 --- a/src/spicelib/devices/mos1/mos1noi.c +++ b/src/spicelib/devices/mos1/mos1noi.c @@ -1,13 +1,13 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1987 Gary W. Ng +Modified: 2000 AlansFixes **********/ #include "ngspice.h" #include #include "mos1defs.h" #include "cktdefs.h" -#include "fteconst.h" #include "iferrmsg.h" #include "noisedef.h" #include "suffix.h" @@ -30,12 +30,12 @@ MOS1noise (mode, operation, genmodel, ckt, data, OnDens) int operation; GENmodel *genmodel; CKTcircuit *ckt; - register Ndata *data; + Ndata *data; double *OnDens; { MOS1model *firstModel = (MOS1model *) genmodel; - register MOS1model *model; - register MOS1instance *inst; + MOS1model *model; + MOS1instance *inst; char name[N_MXVLNTH]; double coxSquared; double tempOnoise; @@ -146,6 +146,7 @@ if (!data->namelist) return(E_NOMEM); exp(model->MOS1fNexp * log(MAX(fabs(inst->MOS1cd),N_MINLOG))) / (data->freq * inst->MOS1w * + inst->MOS1m * (inst->MOS1l - 2*model->MOS1latDiff) * coxSquared); lnNdens[MOS1FLNOIZ] = log(MAX(noizDens[MOS1FLNOIZ],N_MINLOG)); diff --git a/src/spicelib/devices/mos1/mos1par.c b/src/spicelib/devices/mos1/mos1par.c index a8dbce338..c0b137da7 100644 --- a/src/spicelib/devices/mos1/mos1par.c +++ b/src/spicelib/devices/mos1/mos1par.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* */ @@ -28,6 +29,10 @@ MOS1param(param,value,inst,select) here->MOS1temp = value->rValue+CONSTCtoK; here->MOS1tempGiven = TRUE; break; + case MOS1_M: + here->MOS1m = value->rValue; + here->MOS1mGiven = TRUE; + break; case MOS1_W: here->MOS1w = value->rValue; here->MOS1wGiven = TRUE; diff --git a/src/spicelib/devices/mos1/mos1pzld.c b/src/spicelib/devices/mos1/mos1pzld.c index 162dd9dd4..0f8d2f7d0 100644 --- a/src/spicelib/devices/mos1/mos1pzld.c +++ b/src/spicelib/devices/mos1/mos1pzld.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* */ @@ -17,11 +18,11 @@ Author: 1985 Thomas L. Quarles int MOS1pzLoad(inModel,ckt,s) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; SPcomplex *s; { - register MOS1model *model = (MOS1model*)inModel; - register MOS1instance *here; + MOS1model *model = (MOS1model*)inModel; + MOS1instance *here; int xnrm; int xrev; double xgs; @@ -53,12 +54,14 @@ MOS1pzLoad(inModel,ckt,s) * meyer's model parameters */ EffectiveLength=here->MOS1l - 2*model->MOS1latDiff; + GateSourceOverlapCap = model->MOS1gateSourceOverlapCapFactor * - here->MOS1w; + here->MOS1m * here->MOS1w; GateDrainOverlapCap = model->MOS1gateDrainOverlapCapFactor * - here->MOS1w; + here->MOS1m * here->MOS1w; GateBulkOverlapCap = model->MOS1gateBulkOverlapCapFactor * - EffectiveLength; + here->MOS1m * EffectiveLength; + capgs = ( 2* *(ckt->CKTstate0+here->MOS1capgs)+ GateSourceOverlapCap ); capgd = ( 2* *(ckt->CKTstate0+here->MOS1capgd)+ diff --git a/src/spicelib/devices/mos1/mos1sacl.c b/src/spicelib/devices/mos1/mos1sacl.c index 53fabf24a..eab4eff94 100644 --- a/src/spicelib/devices/mos1/mos1sacl.c +++ b/src/spicelib/devices/mos1/mos1sacl.c @@ -19,10 +19,10 @@ Author: 1985 Thomas L. Quarles int MOS1sAcLoad(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { - register MOS1model *model = (MOS1model*)inModel; - register MOS1instance *here; + MOS1model *model = (MOS1model*)inModel; + MOS1instance *here; int xnrm; int xrev; double A0; diff --git a/src/spicelib/devices/mos1/mos1set.c b/src/spicelib/devices/mos1/mos1set.c index 21067f6d8..1377fcb44 100644 --- a/src/spicelib/devices/mos1/mos1set.c +++ b/src/spicelib/devices/mos1/mos1set.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* load the MOS1 device structure with those pointers needed later @@ -17,13 +18,13 @@ Author: 1985 Thomas L. Quarles int MOS1setup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int *states; { - register MOS1model *model = (MOS1model *)inModel; - register MOS1instance *here; + MOS1model *model = (MOS1model *)inModel; + MOS1instance *here; int error; CKTnode *tmp; @@ -139,6 +140,19 @@ MOS1setup(matrix,inModel,ckt,states) error = CKTmkVolt(ckt,&tmp,here->MOS1name,"drain"); if(error) return(error); here->MOS1dNodePrime = tmp->number; + + if (ckt->CKTcopyNodesets) { + CKTnode *tmpNode; + IFuid tmpName; + + if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } + } else { here->MOS1dNodePrime = here->MOS1dNode; } @@ -150,6 +164,19 @@ MOS1setup(matrix,inModel,ckt,states) error = CKTmkVolt(ckt,&tmp,here->MOS1name,"source"); if(error) return(error); here->MOS1sNodePrime = tmp->number; + + if (ckt->CKTcopyNodesets) { + CKTnode *tmpNode; + IFuid tmpName; + + if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } + } else { here->MOS1sNodePrime = here->MOS1sNode; } @@ -192,7 +219,6 @@ MOS1unsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM MOS1model *model; MOS1instance *here; @@ -216,6 +242,5 @@ MOS1unsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/mos1/mos1sld.c b/src/spicelib/devices/mos1/mos1sld.c index 2b1bef937..e885afd1c 100644 --- a/src/spicelib/devices/mos1/mos1sld.c +++ b/src/spicelib/devices/mos1/mos1sld.c @@ -20,8 +20,8 @@ MOS1sLoad(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { - register MOS1model *model = (MOS1model *)inModel; - register MOS1instance *here; + MOS1model *model = (MOS1model *)inModel; + MOS1instance *here; double SaveState[44]; int save_mode; int i; diff --git a/src/spicelib/devices/mos1/mos1sprt.c b/src/spicelib/devices/mos1/mos1sprt.c index 0775d8e16..818ea38e3 100644 --- a/src/spicelib/devices/mos1/mos1sprt.c +++ b/src/spicelib/devices/mos1/mos1sprt.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* Pretty print the sensitivity info for all @@ -18,13 +19,13 @@ Author: 1985 Thomas L. Quarles void MOS1sPrint(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; /* Pretty print the sensitivity info for all the MOS1 * devices in the circuit. */ { - register MOS1model *model = (MOS1model *)inModel; - register MOS1instance *here; + MOS1model *model = (MOS1model *)inModel; + MOS1instance *here; printf("LEVEL 1 MOSFETS-----------------\n"); /* loop through all the MOS1 models */ @@ -41,7 +42,10 @@ register CKTcircuit *ckt; printf(" Drain, Gate , Source nodes: %s, %s ,%s\n", CKTnodName(ckt,here->MOS1dNode),CKTnodName(ckt,here->MOS1gNode), CKTnodName(ckt,here->MOS1sNode)); - + + printf(" Multiplier: %g ",here->MOS1m); + printf(here->MOS1mGiven ? "(specified)\n" : "(default)\n"); + printf(" Length: %g ",here->MOS1l); printf(here->MOS1lGiven ? "(specified)\n" : "(default)\n"); printf(" Width: %g ",here->MOS1w); diff --git a/src/spicelib/devices/mos1/mos1sset.c b/src/spicelib/devices/mos1/mos1sset.c index 59ca505cd..2096fc469 100644 --- a/src/spicelib/devices/mos1/mos1sset.c +++ b/src/spicelib/devices/mos1/mos1sset.c @@ -13,14 +13,14 @@ Author: 1985 Thomas L. Quarles int MOS1sSetup(info,inModel) -register SENstruct *info; +SENstruct *info; GENmodel *inModel; /* loop through all the devices and * allocate parameter #s to design parameters */ { - register MOS1model *model = (MOS1model *)inModel; - register MOS1instance *here; + MOS1model *model = (MOS1model *)inModel; + MOS1instance *here; /* loop through all the models */ for( ; model != NULL; model = model->MOS1nextModel ) { diff --git a/src/spicelib/devices/mos1/mos1supd.c b/src/spicelib/devices/mos1/mos1supd.c index 37fefe911..9726eb124 100644 --- a/src/spicelib/devices/mos1/mos1supd.c +++ b/src/spicelib/devices/mos1/mos1supd.c @@ -16,10 +16,10 @@ Author: 1985 Thomas L. Quarles int MOS1sUpdate(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register MOS1model *model = (MOS1model *)inModel; - register MOS1instance *here; + MOS1model *model = (MOS1model *)inModel; + MOS1instance *here; int iparmno; double sb; double sg; diff --git a/src/spicelib/devices/mos1/mos1temp.c b/src/spicelib/devices/mos1/mos1temp.c index ea93c84f5..cb94f6157 100644 --- a/src/spicelib/devices/mos1/mos1temp.c +++ b/src/spicelib/devices/mos1/mos1temp.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -14,10 +15,10 @@ Author: 1985 Thomas L. Quarles int MOS1temp(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register MOS1model *model = (MOS1model *)inModel; - register MOS1instance *here; + MOS1model *model = (MOS1model *)inModel; + MOS1instance *here; double egfet,egfet1; double fact1,fact2; @@ -137,6 +138,9 @@ MOS1temp(inModel,ckt) if(!here->MOS1drainAreaGiven) { here->MOS1drainArea = ckt->CKTdefaultMosAD; } + if(!here->MOS1mGiven) { + here->MOS1m = ckt->CKTdefaultMosM; + } if(!here->MOS1lGiven) { here->MOS1l = ckt->CKTdefaultMosL; } @@ -193,27 +197,30 @@ MOS1temp(inModel,ckt) (here->MOS1drainArea == 0) || (here->MOS1sourceArea == 0) ) { here->MOS1sourceVcrit = here->MOS1drainVcrit = - vt*log(vt/(CONSTroot2*here->MOS1tSatCur)); + vt*log(vt/(CONSTroot2*here->MOS1m*here->MOS1tSatCur)); } else { here->MOS1drainVcrit = vt * log( vt / (CONSTroot2 * + here->MOS1m * here->MOS1tSatCurDens * here->MOS1drainArea)); here->MOS1sourceVcrit = vt * log( vt / (CONSTroot2 * + here->MOS1m * here->MOS1tSatCurDens * here->MOS1sourceArea)); } if(model->MOS1capBDGiven) { - czbd = here->MOS1tCbd; + czbd = here->MOS1tCbd * here->MOS1m; } else { - if(model->MOS1bulkCapFactorGiven) { - czbd=here->MOS1tCj*here->MOS1drainArea; + if(model->MOS1bulkCapFactorGiven) { + czbd=here->MOS1tCj*here->MOS1m*here->MOS1drainArea; } else { czbd=0; } } if(model->MOS1sideWallCapFactorGiven) { - czbdsw= here->MOS1tCjsw * here->MOS1drainPerimiter; + czbdsw= here->MOS1tCjsw * here->MOS1drainPerimiter * + here->MOS1m; } else { czbdsw=0; } @@ -239,16 +246,17 @@ MOS1temp(inModel,ckt) (here->MOS1tDepCap*here->MOS1tDepCap) -here->MOS1tDepCap * here->MOS1f2d; if(model->MOS1capBSGiven) { - czbs=here->MOS1tCbs; + czbs=here->MOS1tCbs * here->MOS1m; } else { if(model->MOS1bulkCapFactorGiven) { - czbs=here->MOS1tCj*here->MOS1sourceArea; + czbs=here->MOS1tCj*here->MOS1sourceArea * here->MOS1m; } else { czbs=0; } } if(model->MOS1sideWallCapFactorGiven) { - czbssw = here->MOS1tCjsw * here->MOS1sourcePerimiter; + czbssw = here->MOS1tCjsw * here->MOS1sourcePerimiter * + here->MOS1m; } else { czbssw=0; } @@ -277,14 +285,16 @@ MOS1temp(inModel,ckt) if(model->MOS1drainResistanceGiven) { if(model->MOS1drainResistance != 0) { - here->MOS1drainConductance = 1/model->MOS1drainResistance; + here->MOS1drainConductance = here->MOS1m / + model->MOS1drainResistance; } else { here->MOS1drainConductance = 0; } } else if (model->MOS1sheetResistanceGiven) { if(model->MOS1sheetResistance != 0) { here->MOS1drainConductance = - 1/(model->MOS1sheetResistance*here->MOS1drainSquares); + here->MOS1m / + (model->MOS1sheetResistance*here->MOS1drainSquares); } else { here->MOS1drainConductance = 0; } @@ -293,14 +303,17 @@ MOS1temp(inModel,ckt) } if(model->MOS1sourceResistanceGiven) { if(model->MOS1sourceResistance != 0) { - here->MOS1sourceConductance = 1/model->MOS1sourceResistance; + here->MOS1sourceConductance = here->MOS1m / + model->MOS1sourceResistance; } else { here->MOS1sourceConductance = 0; } } else if (model->MOS1sheetResistanceGiven) { - if(model->MOS1sheetResistance != 0) { + if ((model->MOS1sheetResistance != 0) && + (here->MOS1sourceSquares != 0)) { here->MOS1sourceConductance = - 1/(model->MOS1sheetResistance*here->MOS1sourceSquares); + here->MOS1m / + (model->MOS1sheetResistance*here->MOS1sourceSquares); } else { here->MOS1sourceConductance = 0; } diff --git a/src/spicelib/devices/mos1/mos1trun.c b/src/spicelib/devices/mos1/mos1trun.c index d91420910..48dec293e 100644 --- a/src/spicelib/devices/mos1/mos1trun.c +++ b/src/spicelib/devices/mos1/mos1trun.c @@ -16,11 +16,11 @@ Author: 1985 Thomas L. Quarles int MOS1trunc(inModel,ckt,timeStep) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; double *timeStep; { - register MOS1model *model = (MOS1model *)inModel; - register MOS1instance *here; + MOS1model *model = (MOS1model *)inModel; + MOS1instance *here; for( ; model != NULL; model = model->MOS1nextModel) { for(here=model->MOS1instances;here!=NULL;here = here->MOS1nextInstance){ diff --git a/src/spicelib/devices/mos2/Makefile.am b/src/spicelib/devices/mos2/Makefile.am index 9d4ff7f62..e43de05a9 100644 --- a/src/spicelib/devices/mos2/Makefile.am +++ b/src/spicelib/devices/mos2/Makefile.am @@ -2,35 +2,36 @@ pkglib_LTLIBRARIES = libmos2.la -libmos2_la_SOURCES = \ - mos2.c \ - mos2acld.c \ - mos2ask.c \ - mos2conv.c \ - mos2defs.h \ - mos2del.c \ - mos2dest.c \ - mos2dist.c \ - mos2dset.c \ - mos2ext.h \ - mos2ic.c \ - mos2itf.h \ - mos2load.c \ - mos2mask.c \ - mos2mdel.c \ - mos2mpar.c \ - mos2noi.c \ - mos2par.c \ - mos2pzld.c \ - mos2sacl.c \ - mos2set.c \ - mos2sld.c \ - mos2sprt.c \ - mos2sset.c \ - mos2supd.c \ - mos2temp.c \ - mos2trun.c - +libmos2_la_SOURCES = \ + mos2.c \ + mos2acld.c \ + mos2ask.c \ + mos2conv.c \ + mos2defs.h \ + mos2del.c \ + mos2dest.c \ + mos2dist.c \ + mos2dset.c \ + mos2ext.h \ + mos2ic.c \ + mos2init.c \ + mos2init.h \ + mos2itf.h \ + mos2load.c \ + mos2mask.c \ + mos2mdel.c \ + mos2mpar.c \ + mos2noi.c \ + mos2par.c \ + mos2pzld.c \ + mos2sacl.c \ + mos2set.c \ + mos2sld.c \ + mos2sprt.c \ + mos2sset.c \ + mos2supd.c \ + mos2temp.c \ + mos2trun.c INCLUDES = -I$(top_srcdir)/src/include diff --git a/src/spicelib/devices/mos2/mos2.c b/src/spicelib/devices/mos2/mos2.c index 706db5ea3..b51c7b011 100644 --- a/src/spicelib/devices/mos2/mos2.c +++ b/src/spicelib/devices/mos2/mos2.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFIxes **********/ #include "ngspice.h" @@ -11,6 +12,7 @@ Author: 1985 Thomas L. Quarles #include "suffix.h" IFparm MOS2pTable[] = { /* parameters */ + IOPU("m", MOS2_M, IF_REAL , "Multiplier"), IOPU("l", MOS2_L, IF_REAL , "Length"), IOPU("w", MOS2_W, IF_REAL , "Width"), IOPU("ad", MOS2_AD, IF_REAL , "Drain area"), diff --git a/src/spicelib/devices/mos2/mos2acld.c b/src/spicelib/devices/mos2/mos2acld.c index e598ce039..f773ed78e 100644 --- a/src/spicelib/devices/mos2/mos2acld.c +++ b/src/spicelib/devices/mos2/mos2acld.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* */ @@ -16,10 +17,10 @@ Author: 1985 Thomas L. Quarles int MOS2acLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register MOS2model *model = (MOS2model *)inModel; - register MOS2instance *here; + MOS2model *model = (MOS2model *)inModel; + MOS2instance *here; int xnrm; int xrev; double xgs; @@ -52,11 +53,11 @@ MOS2acLoad(inModel,ckt) */ EffectiveLength=here->MOS2l - 2*model->MOS2latDiff; GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor * - here->MOS2w; + here->MOS2m * here->MOS2w; GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor * - here->MOS2w; + here->MOS2m * here->MOS2w; GateBulkOverlapCap = model->MOS2gateBulkOverlapCapFactor * - EffectiveLength; + here->MOS2m * EffectiveLength; capgs = ( *(ckt->CKTstate0+here->MOS2capgs)+ *(ckt->CKTstate0+here->MOS2capgs) + GateSourceOverlapCap ); diff --git a/src/spicelib/devices/mos2/mos2ask.c b/src/spicelib/devices/mos2/mos2ask.c index 14e05377a..1849e9344 100644 --- a/src/spicelib/devices/mos2/mos2ask.c +++ b/src/spicelib/devices/mos2/mos2ask.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1987 Mathew Lew and Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -34,14 +35,17 @@ MOS2ask(ckt,inst,which,value,select) value->rValue = here->MOS2temp-CONSTCtoK; return(OK); case MOS2_CGS: - value->rValue = *(ckt->CKTstate0 + here->MOS2capgs); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS2capgs); return(OK); case MOS2_CGD: - value->rValue = *(ckt->CKTstate0 + here->MOS2capgd); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS2capgd); + return(OK); + case MOS2_M: + value->rValue = here->MOS2m; return(OK); case MOS2_L: value->rValue = here->MOS2l; - return(OK); + return(OK); case MOS2_W: value->rValue = here->MOS2w; return(OK); @@ -178,7 +182,11 @@ MOS2ask(ckt,inst,which,value,select) value->rValue = *(ckt->CKTstate0 + here->MOS2vds); return(OK); case MOS2_CAPGS: - value->rValue = *(ckt->CKTstate0 + here->MOS2capgs); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS2capgs); +/* add overlap capacitance */ + value->rValue += (here->MOS2modPtr->MOS2gateSourceOverlapCapFactor) + * here->MOS2m + * (here->MOS2w); return(OK); case MOS2_QGS: value->rValue = *(ckt->CKTstate0 + here->MOS2qgs); @@ -187,7 +195,11 @@ MOS2ask(ckt,inst,which,value,select) value->rValue = *(ckt->CKTstate0 + here->MOS2cqgs); return(OK); case MOS2_CAPGD: - value->rValue = *(ckt->CKTstate0 + here->MOS2capgd); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS2capgd); +/* add overlap capacitance */ + value->rValue += (here->MOS2modPtr->MOS2gateSourceOverlapCapFactor) + * here->MOS2m + * (here->MOS2w); return(OK); case MOS2_QGD: value->rValue = *(ckt->CKTstate0 + here->MOS2qgd); @@ -196,7 +208,12 @@ MOS2ask(ckt,inst,which,value,select) value->rValue = *(ckt->CKTstate0 + here->MOS2cqgd); return(OK); case MOS2_CAPGB: - value->rValue = *(ckt->CKTstate0 + here->MOS2capgb); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS2capgb); +/* add overlap capacitance */ + value->rValue += (here->MOS2modPtr->MOS2gateBulkOverlapCapFactor) + * here->MOS2m + * (here->MOS2l + -2*(here->MOS2modPtr->MOS2latDiff)); return(OK); case MOS2_QGB: value->rValue = *(ckt->CKTstate0 + here->MOS2qgb); diff --git a/src/spicelib/devices/mos2/mos2conv.c b/src/spicelib/devices/mos2/mos2conv.c index 1a35108c1..2eeb5b9e7 100644 --- a/src/spicelib/devices/mos2/mos2conv.c +++ b/src/spicelib/devices/mos2/mos2conv.c @@ -13,10 +13,10 @@ Author: 1985 Thomas L. Quarles int MOS2convTest(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register MOS2model *model = (MOS2model *)inModel; - register MOS2instance *here; + MOS2model *model = (MOS2model *)inModel; + MOS2instance *here; double delvbs; double delvbd; double delvgs; diff --git a/src/spicelib/devices/mos2/mos2defs.h b/src/spicelib/devices/mos2/mos2defs.h index 5bec7c8eb..c35efb417 100644 --- a/src/spicelib/devices/mos2/mos2defs.h +++ b/src/spicelib/devices/mos2/mos2defs.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFIxes **********/ #ifndef MOS2 @@ -33,6 +34,8 @@ typedef struct sMOS2instance { int MOS2mode; /* device mode : 1 = normal, -1 = inverse */ + unsigned MOS2mGiven :1; + unsigned MOS2off :1;/* non-zero to indicate device is off for dc analysis*/ unsigned MOS2lGiven :1; unsigned MOS2wGiven :1; @@ -151,6 +154,8 @@ typedef struct sMOS2instance { /* the cureve matching Fc * Vj */ double MOS2tVbi; /* temperature adjusted Vbi */ + double MOS2m; /* parallel device multiplier */ + double MOS2l; /* the length of the channel region */ double MOS2w; /* the width of the channel region */ double MOS2drainArea; /* the area of the drain diffusion */ @@ -489,6 +494,7 @@ typedef struct sMOS2model { /* model structure for a resistor */ #define MOS2_TEMP 77 #define MOS2_SOURCERESIST 78 #define MOS2_DRAINRESIST 79 +#define MOS2_M 80 /* model paramerers */ #define MOS2_MOD_VTO 101 diff --git a/src/spicelib/devices/mos2/mos2dist.c b/src/spicelib/devices/mos2/mos2dist.c index d4f0c4ef1..a4bca0f4e 100644 --- a/src/spicelib/devices/mos2/mos2dist.c +++ b/src/spicelib/devices/mos2/mos2dist.c @@ -14,7 +14,7 @@ Author: 1988 Jaijeet S Roychowdhury int MOS2disto(mode,genmodel,ckt) GENmodel *genmodel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int mode; /* assuming here that ckt->CKTomega has been initialised to @@ -40,7 +40,7 @@ MOS2disto(mode,genmodel,ckt) double r2h1m2y,i2h1m2y; double r2h1m2z, i2h1m2z; double temp, itemp; - register MOS2instance *here; + MOS2instance *here; if (mode == D_SETUP) return(MOS2dSetup(model,ckt)); diff --git a/src/spicelib/devices/mos2/mos2dset.c b/src/spicelib/devices/mos2/mos2dset.c index 9dfcad00c..409c613db 100644 --- a/src/spicelib/devices/mos2/mos2dset.c +++ b/src/spicelib/devices/mos2/mos2dset.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1988 Jaijeet S Roychowdhury +Modified: 2000 AlansFixes **********/ #include @@ -23,13 +24,13 @@ static double sig2[4] = {1.0, 1.0,-1.0, -1.0}; int MOS2dSetup(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* actually load the current value into the * sparse matrix previously provided */ { - register MOS2model *model = (MOS2model *)inModel; - register MOS2instance *here; + MOS2model *model = (MOS2model *)inModel; + MOS2instance *here; double Beta; double DrainSatCur; double EffectiveLength; @@ -82,26 +83,28 @@ double gmbds; vt = CONSTKoverQ * here->MOS2temp; EffectiveLength=here->MOS2l - 2*model->MOS2latDiff; - if( (here->MOS2tSatCurDens == 0) || + + if( (here->MOS2tSatCurDens == 0) || (here->MOS2drainArea == 0) || (here->MOS2sourceArea == 0)) { - DrainSatCur = here->MOS2tSatCur; - SourceSatCur = here->MOS2tSatCur; + DrainSatCur = here->MOS2m * here->MOS2tSatCur; + SourceSatCur = here->MOS2m * here->MOS2tSatCur; } else { DrainSatCur = here->MOS2tSatCurDens * - here->MOS2drainArea; + here->MOS2m * here->MOS2drainArea; SourceSatCur = here->MOS2tSatCurDens * - here->MOS2sourceArea; + here->MOS2m * here->MOS2sourceArea; } GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor * - here->MOS2w; + here->MOS2m * here->MOS2w; GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor * - here->MOS2w; + here->MOS2m * here->MOS2w; GateBulkOverlapCap = model->MOS2gateBulkOverlapCapFactor * - EffectiveLength; - Beta = here->MOS2tTransconductance * here->MOS2w/EffectiveLength; + here->MOS2m * EffectiveLength; + Beta = here->MOS2tTransconductance * here->MOS2m * + here->MOS2w/EffectiveLength; OxideCap = model->MOS2oxideCapFactor * EffectiveLength * - here->MOS2w; + here->MOS2m * here->MOS2w; @@ -481,7 +484,7 @@ d_p.d3_pqr = 0.0; PlusDeriv(&d_cdonco,&d_cdonco,&d_dummy); TimesDeriv(&d_cdonco,&d_cdonco,-1.0); d_cdonco.value += factor; - xn = 1.0+cfs/OxideCap*here->MOS2w*EffectiveLength+cdonco; + xn = 1.0+cfs/OxideCap*here->MOS2m*here->MOS2w*EffectiveLength+cdonco; EqualDeriv(&d_xn,&d_cdonco); d_xn.value = xn; tmp = vt*xn; diff --git a/src/spicelib/devices/mos2/mos2ext.h b/src/spicelib/devices/mos2/mos2ext.h index fd472fc5b..a82c0b38a 100644 --- a/src/spicelib/devices/mos2/mos2ext.h +++ b/src/spicelib/devices/mos2/mos2ext.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #ifdef __STDC__ @@ -27,6 +28,9 @@ extern int MOS2temp(GENmodel*,CKTcircuit*); extern int MOS2trunc(GENmodel*,CKTcircuit*,double*); extern int MOS2disto(int,GENmodel*,CKTcircuit*); extern int MOS2noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); + +extern int MOS2dSetup(GENmodel*,CKTcircuit*); + #else /* stdc */ extern int MOS2acLoad(); extern int MOS2ask(); diff --git a/src/spicelib/devices/mos2/mos2itf.h b/src/spicelib/devices/mos2/mos2itf.h index 7a57d8332..2d51c4a7d 100644 --- a/src/spicelib/devices/mos2/mos2itf.h +++ b/src/spicelib/devices/mos2/mos2itf.h @@ -1,101 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_mos2 - #ifndef DEV_MOS2 #define DEV_MOS2 -#include "mos2ext.h" -extern IFparm MOS2pTable[ ]; -extern IFparm MOS2mPTable[ ]; -extern char *MOS2names[ ]; -extern int MOS2pTSize; -extern int MOS2mPTSize; -extern int MOS2nSize; -extern int MOS2iSize; -extern int MOS2mSize; - -SPICEdev MOS2info = { - { - "Mos2", - "Level 2 MOSfet model with Meyer capacitance model", - - &MOS2nSize, - &MOS2nSize, - MOS2names, - - &MOS2pTSize, - MOS2pTable, - - &MOS2mPTSize, - MOS2mPTable, - DEV_DEFAULT - }, - - MOS2param, - MOS2mParam, - MOS2load, - MOS2setup, - MOS2unsetup, - MOS2setup, - MOS2temp, - MOS2trunc, - NULL, - MOS2acLoad, - NULL, - MOS2destroy, -#ifdef DELETES - MOS2mDelete, - MOS2delete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - MOS2getic, - MOS2ask, - MOS2mAsk, -#ifdef AN_pz - MOS2pzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ -#ifdef NEWCONV - MOS2convTest, -#else /* NEWCONV */ - NULL, -#endif /* NEWCONV */ - -#ifdef AN_sense2 - MOS2sSetup, - MOS2sLoad, - MOS2sUpdate, - MOS2sAcLoad, - MOS2sPrint, - NULL, -#else /* AN_sense2 */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -#endif /* AN_sense2 */ -#ifdef AN_disto - MOS2disto, -#else /* AN_disto */ - NULL, -#endif /* AN_disto */ -#ifdef AN_noise - MOS2noise, -#else /* AN_noise */ - NULL, -#endif /* AN_noise */ - - &MOS2iSize, - &MOS2mSize -}; - +SPICEdev *get_mos2_info(void); #endif -#endif diff --git a/src/spicelib/devices/mos2/mos2load.c b/src/spicelib/devices/mos2/mos2load.c index 8115d4ee5..6ccda5825 100644 --- a/src/spicelib/devices/mos2/mos2load.c +++ b/src/spicelib/devices/mos2/mos2load.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 alansFixes **********/ #include "ngspice.h" @@ -22,13 +23,13 @@ static double sig2[4] = {1.0, 1.0,-1.0, -1.0}; int MOS2load(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* actually load the current value into the * sparse matrix previously provided */ { - register MOS2model *model = (MOS2model *)inModel; - register MOS2instance *here; + MOS2model *model = (MOS2model *)inModel; + MOS2instance *here; int error; double Beta; double DrainSatCur; @@ -82,27 +83,9 @@ MOS2load(inModel,ckt) int xnrm; int xrev; int Check; -#ifndef NOBYPASS double tempv; -#endif /*NOBYPASS*/ -#ifdef CAPBYPASS - int senflag; -#endif /* CAPBYPASS */ int SenCond=0; -#ifdef CAPBYPASS - senflag = 0; - if(ckt->CKTsenInfo){ - if(ckt->CKTsenInfo->SENstatus == PERTURBATION){ - if((ckt->CKTsenInfo->SENmode == ACSEN)|| - (ckt->CKTsenInfo->SENmode == TRANSEN)){ - senflag = 1; - } - } - } -#endif /* CAPBYPASS */ - - /* loop through all the MOS2 device models */ for( ; model != NULL; model = model->MOS2nextModel ) { @@ -126,26 +109,28 @@ MOS2load(inModel,ckt) } EffectiveLength=here->MOS2l - 2*model->MOS2latDiff; + if( (here->MOS2tSatCurDens == 0) || (here->MOS2drainArea == 0) || (here->MOS2sourceArea == 0)) { - DrainSatCur = here->MOS2tSatCur; - SourceSatCur = here->MOS2tSatCur; + DrainSatCur = here->MOS2m * here->MOS2tSatCur; + SourceSatCur = here->MOS2m * here->MOS2tSatCur; } else { - DrainSatCur = here->MOS2tSatCurDens * + DrainSatCur = here->MOS2m * here->MOS2tSatCurDens * here->MOS2drainArea; - SourceSatCur = here->MOS2tSatCurDens * + SourceSatCur = here->MOS2m * here->MOS2tSatCurDens * here->MOS2sourceArea; } GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor * - here->MOS2w; + here->MOS2m * here->MOS2w; GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor * - here->MOS2w; + here->MOS2m * here->MOS2w; GateBulkOverlapCap = model->MOS2gateBulkOverlapCapFactor * - EffectiveLength; - Beta = here->MOS2tTransconductance * here->MOS2w/EffectiveLength; + here->MOS2m * EffectiveLength; + Beta = here->MOS2tTransconductance * here->MOS2w * + here->MOS2m/EffectiveLength; OxideCap = model->MOS2oxideCapFactor * EffectiveLength * - here->MOS2w; + here->MOS2m * here->MOS2w; if(SenCond){ @@ -272,7 +257,6 @@ MOS2load(inModel,ckt) * can't handle it in one piece, so it is broken up * into several stages here */ -#ifndef NOBYPASS tempv = MAX(fabs(cbhat),fabs(here->MOS2cbs+here->MOS2cbd))+ ckt->CKTabstol; if((!(ckt->CKTmode & (MODEINITPRED|MODEINITTRAN|MODEINITSMSIG) @@ -325,7 +309,6 @@ MOS2load(inModel,ckt) } goto bypass; } -#endif /*NOBYPASS*/ /* ok - bypass is out, do it the hard way */ von = model->MOS2type * here->MOS2von; @@ -394,24 +377,23 @@ MOS2load(inModel,ckt) * correspoinding derivative (conductance). */ -next1: if(vbs <= 0) { - here->MOS2gbs = SourceSatCur/vt; - here->MOS2cbs = here->MOS2gbs*vbs; - here->MOS2gbs += ckt->CKTgmin; +next1: if(vbs <= -3*vt) { + here->MOS2gbs = ckt->CKTgmin; + here->MOS2cbs = here->MOS2gbs*vbs-SourceSatCur; } else { - evbs = exp(vbs/vt); + evbs = exp(MIN(MAX_EXP_ARG,vbs/vt)); here->MOS2gbs = SourceSatCur*evbs/vt + ckt->CKTgmin; - here->MOS2cbs = SourceSatCur * (evbs-1); + here->MOS2cbs = SourceSatCur*(evbs-1) + ckt->CKTgmin*vbs; } - if(vbd <= 0) { - here->MOS2gbd = DrainSatCur/vt; - here->MOS2cbd = here->MOS2gbd *vbd; - here->MOS2gbd += ckt->CKTgmin; + if(vbd <= -3*vt) { + here->MOS2gbd = ckt->CKTgmin; + here->MOS2cbd = here->MOS2gbd*vbd-DrainSatCur; } else { - evbd = exp(vbd/vt); - here->MOS2gbd = DrainSatCur*evbd/vt +ckt->CKTgmin; - here->MOS2cbd = DrainSatCur *(evbd-1); + evbd = exp(MIN(MAX_EXP_ARG,vbd/vt)); + here->MOS2gbd = DrainSatCur*evbd/vt + ckt->CKTgmin; + here->MOS2cbd = DrainSatCur*(evbd-1) + ckt->CKTgmin*vbd; } + if(vds >= 0) { /* normal mode */ here->MOS2mode = 1; @@ -581,7 +563,7 @@ next1: if(vbs <= 0) { dsrgdb = -0.5*sarg*tmp; d2sdb2 = -dsrgdb*tmp; } - if ((lvds-lvbs) >= 0) { + if ((lvbs-lvds) <= 0) { barg = sqrt(phiMinVbs+lvds); dbrgdb = -0.5/barg; d2bdb2 = 0.5*dbrgdb/(phiMinVbs+lvds); @@ -662,14 +644,17 @@ next1: if(vbs <= 0) { cfs = CHARGE*model->MOS2fastSurfaceStateDensity* 1e4 /*(cm**2/m**2)*/; cdonco = -(gamasd*dsrgdb+dgddvb*sarg)+factor; - xn = 1.0+cfs/OxideCap*here->MOS2w*EffectiveLength+cdonco; + + xn = 1.0+cfs/OxideCap*here->MOS2m* + here->MOS2w*EffectiveLength+cdonco; + tmp = vt*xn; von = von+tmp; argg = 1.0/tmp; vgst = lvgs-von; } else { vgst = lvgs-von; - if (lvgs <= von) { + if (lvgs <= vbin) { /* * cutoff region */ @@ -919,6 +904,13 @@ line610: goto line1050; } + if (model->MOS2fastSurfaceStateDensity != 0 && OxideCap != 0) { + if (lvgs > von) goto line900; + } else { + if (lvgs > vbin) goto line900; + goto doneval; + } + if (lvgs > von) goto line900; /* * subthreshold region @@ -1018,17 +1010,9 @@ doneval: * *.. bulk-drain and bulk-source depletion capacitances */ -#ifdef CAPBYPASS - if(((ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) || - fabs(delvbs) >= ckt->CKTreltol * MAX(fabs(vbs), - fabs(*(ckt->CKTstate0+here->MOS2vbs)))+ - ckt->CKTvoltTol)|| senflag) -#endif /*CAPBYPASS*/ { /* can't bypass the diode capacitance calculations */ -#ifdef CAPZEROBYPASS if(here->MOS2Cbs != 0 || here->MOS2Cbssw != 0) { -#endif /*CAPZEROBYPASS*/ if (vbs < here->MOS2tDepCap){ arg=1-vbs/here->MOS2tBulkPot; /* @@ -1080,24 +1064,14 @@ doneval: vbs*(here->MOS2f2s+vbs*(here->MOS2f3s/2)); here->MOS2capbs=here->MOS2f2s+here->MOS2f3s*vbs; } -#ifdef CAPZEROBYPASS } else { *(ckt->CKTstate0 + here->MOS2qbs) = 0; here->MOS2capbs=0; } -#endif /*CAPZEROBYPASS*/ } -#ifdef CAPBYPASS - if(((ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) || - fabs(delvbd) >= ckt->CKTreltol * MAX(fabs(vbd), - fabs(*(ckt->CKTstate0+here->MOS2vbd)))+ - ckt->CKTvoltTol)|| senflag) -#endif /*CAPBYPASS*/ /* can't bypass the diode capacitance calculations */ { -#ifdef CAPZEROBYPASS if(here->MOS2Cbd != 0 || here->MOS2Cbdsw != 0 ) { -#endif /*CAPZEROBYPASS*/ if (vbd < here->MOS2tDepCap) { arg=1-vbd/here->MOS2tBulkPot; /* @@ -1144,12 +1118,10 @@ doneval: vbd * (here->MOS2f2d + vbd * here->MOS2f3d/2); here->MOS2capbd=here->MOS2f2d + vbd * here->MOS2f3d; } -#ifdef CAPZEROBYPASS } else { *(ckt->CKTstate0 + here->MOS2qbd) = 0; here->MOS2capbd = 0; } -#endif /*CAPZEROBYPASS*/ } if(SenCond && (ckt->CKTsenInfo->SENmode==TRANSEN)) goto next2; @@ -1188,33 +1160,6 @@ doneval: if (Check == 1) { ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) here; -#ifndef NEWCONV -#ifdef STEPDEBUG - printf("MOS2: %s limiting noncon\n",here->MOS2name); -#endif /* STEPDEBUG */ - } else { - tol=ckt->CKTreltol*MAX(fabs(cdhat),fabs(here->MOS2cd))+ - ckt->CKTabstol; - if (fabs(cdhat-here->MOS2cd) >= tol) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; -#ifdef STEPDEBUG - printf("MOS2: %s cd noncon cd=%g, cdhat=%g, mode=%d\n", - here->MOS2name,here->MOS2cd,cdhat, - here->MOS2mode); -#endif /* STEPDEBUG */ - } else { - tol=ckt->CKTreltol* - MAX(fabs(cbhat),fabs(here->MOS2cbs+here->MOS2cbd))+ ckt->CKTabstol; - if (fabs(cbhat-(here->MOS2cbs+here->MOS2cbd)) > tol) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; -#ifdef STEPDEBUG - printf("MOS2: %s cb noncon\n",here->MOS2name); -#endif /* STEPDEBUG */ - } - } -#endif /* NEWCONV */ } } next2: *(ckt->CKTstate0 + here->MOS2vbs) = vbs; @@ -1309,9 +1254,7 @@ next2: *(ckt->CKTstate0 + here->MOS2vbs) = vbs; } #endif /* PREDICTOR */ } -#ifndef NOBYPASS bypass: -#endif /* NOBYPASS */ if(SenCond) continue; @@ -1354,9 +1297,9 @@ bypass: * load current vector */ ceqbs = model->MOS2type * - (here->MOS2cbs-(here->MOS2gbs-ckt->CKTgmin)*vbs); + (here->MOS2cbs-(here->MOS2gbs)*vbs); ceqbd = model->MOS2type * - (here->MOS2cbd-(here->MOS2gbd-ckt->CKTgmin)*vbd); + (here->MOS2cbd-(here->MOS2gbd)*vbd); if (here->MOS2mode >= 0) { xnrm=1; xrev=0; diff --git a/src/spicelib/devices/mos2/mos2mask.c b/src/spicelib/devices/mos2/mos2mask.c index 5f65978bf..4713b8efc 100644 --- a/src/spicelib/devices/mos2/mos2mask.c +++ b/src/spicelib/devices/mos2/mos2mask.c @@ -18,7 +18,7 @@ MOS2mAsk(ckt,inModel,param,value) int param; IFvalue *value; { - register MOS2model *model = (MOS2model *)inModel; + MOS2model *model = (MOS2model *)inModel; switch(param) { case MOS2_MOD_TNOM: value->rValue = model->MOS2tnom - CONSTCtoK; diff --git a/src/spicelib/devices/mos2/mos2mpar.c b/src/spicelib/devices/mos2/mos2mpar.c index 5a97a9151..3c85b9b70 100644 --- a/src/spicelib/devices/mos2/mos2mpar.c +++ b/src/spicelib/devices/mos2/mos2mpar.c @@ -20,7 +20,7 @@ MOS2mParam(param,value,inModel) IFvalue *value; GENmodel *inModel; { - register MOS2model *model = (MOS2model *)inModel; + MOS2model *model = (MOS2model *)inModel; switch(param) { case MOS2_MOD_TNOM: model->MOS2tnom = value->rValue+CONSTCtoK; diff --git a/src/spicelib/devices/mos2/mos2noi.c b/src/spicelib/devices/mos2/mos2noi.c index fea335003..9e9a6fa18 100644 --- a/src/spicelib/devices/mos2/mos2noi.c +++ b/src/spicelib/devices/mos2/mos2noi.c @@ -1,13 +1,13 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1987 Gary W. Ng +Modified: 2000 AlansFixes **********/ #include "ngspice.h" #include #include "mos2defs.h" #include "cktdefs.h" -#include "fteconst.h" #include "iferrmsg.h" #include "noisedef.h" #include "suffix.h" @@ -30,12 +30,12 @@ MOS2noise (mode, operation, genmodel, ckt, data, OnDens) int operation; GENmodel *genmodel; CKTcircuit *ckt; - register Ndata *data; + Ndata *data; double *OnDens; { MOS2model *firstModel = (MOS2model *) genmodel; - register MOS2model *model; - register MOS2instance *inst; + MOS2model *model; + MOS2instance *inst; char name[N_MXVLNTH]; double tempOnoise; double tempInoise; @@ -135,7 +135,8 @@ if (!data->namelist) return(E_NOMEM); noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef * exp(model->MOS2fNexp * log(MAX(fabs(inst->MOS2cd),N_MINLOG))) / - (data->freq * inst->MOS2w * + (data->freq * inst->MOS2w * + inst->MOS2m * (inst->MOS2l - 2*model->MOS2latDiff) * model->MOS2oxideCapFactor * model->MOS2oxideCapFactor); lnNdens[MOS2FLNOIZ] = diff --git a/src/spicelib/devices/mos2/mos2par.c b/src/spicelib/devices/mos2/mos2par.c index 24e002e2b..c661095f8 100644 --- a/src/spicelib/devices/mos2/mos2par.c +++ b/src/spicelib/devices/mos2/mos2par.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* */ @@ -28,6 +29,10 @@ MOS2param(param,value,inst,select) here->MOS2temp = value->rValue+CONSTCtoK; here->MOS2tempGiven = TRUE; break; + case MOS2_M: + here->MOS2m = value->rValue; + here->MOS2mGiven = TRUE; + break; case MOS2_W: here->MOS2w = value->rValue; here->MOS2wGiven = TRUE; diff --git a/src/spicelib/devices/mos2/mos2pzld.c b/src/spicelib/devices/mos2/mos2pzld.c index bf231d25b..73495230e 100644 --- a/src/spicelib/devices/mos2/mos2pzld.c +++ b/src/spicelib/devices/mos2/mos2pzld.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* */ @@ -17,11 +18,11 @@ Author: 1985 Thomas L. Quarles int MOS2pzLoad(inModel,ckt,s) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; SPcomplex *s; { - register MOS2model *model = (MOS2model *)inModel; - register MOS2instance *here; + MOS2model *model = (MOS2model *)inModel; + MOS2instance *here; int xnrm; int xrev; double xgs; @@ -53,12 +54,14 @@ MOS2pzLoad(inModel,ckt,s) * meyer's model parameters */ EffectiveLength=here->MOS2l - 2*model->MOS2latDiff; + GateSourceOverlapCap = model->MOS2gateSourceOverlapCapFactor * - here->MOS2w; + here->MOS2m * here->MOS2w; GateDrainOverlapCap = model->MOS2gateDrainOverlapCapFactor * - here->MOS2w; + here->MOS2m * here->MOS2w; GateBulkOverlapCap = model->MOS2gateBulkOverlapCapFactor * - EffectiveLength; + here->MOS2m * EffectiveLength; + capgs = ( 2* *(ckt->CKTstate0+here->MOS2capgs)+ GateSourceOverlapCap ); capgd = ( 2* *(ckt->CKTstate0+here->MOS2capgd)+ diff --git a/src/spicelib/devices/mos2/mos2sacl.c b/src/spicelib/devices/mos2/mos2sacl.c index cd014add3..d24dfe992 100644 --- a/src/spicelib/devices/mos2/mos2sacl.c +++ b/src/spicelib/devices/mos2/mos2sacl.c @@ -19,10 +19,10 @@ Author: 1985 Thomas L. Quarles int MOS2sAcLoad(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { - register MOS2model *model = (MOS2model *)inModel; - register MOS2instance *here; + MOS2model *model = (MOS2model *)inModel; + MOS2instance *here; int xnrm; int xrev; double A0; diff --git a/src/spicelib/devices/mos2/mos2set.c b/src/spicelib/devices/mos2/mos2set.c index 5e50bfb81..3b1e8afe2 100644 --- a/src/spicelib/devices/mos2/mos2set.c +++ b/src/spicelib/devices/mos2/mos2set.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -14,16 +15,16 @@ Author: 1985 Thomas L. Quarles int MOS2setup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int *states; /* load the MOS2 device structure with those pointers needed later * for fast matrix loading */ { - register MOS2model *model = (MOS2model *)inModel; - register MOS2instance *here; + MOS2model *model = (MOS2model *)inModel; + MOS2instance *here; int error; CKTnode *tmp; @@ -124,7 +125,10 @@ MOS2setup(matrix,inModel,ckt,states) /* loop through all the instances of the model */ for (here = model->MOS2instances; here != NULL ; here=here->MOS2nextInstance) { - + + CKTnode *tmpNode; + IFuid tmpName; + if (here->MOS2owner == ARCHme) { /* allocate a chunk of the state vector */ here->MOS2states = *states; @@ -165,6 +169,16 @@ MOS2setup(matrix,inModel,ckt,states) error = CKTmkVolt(ckt,&tmp,here->MOS2name,"internal#drain"); if(error) return(error); here->MOS2dNodePrime = tmp->number; + + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } + } else { here->MOS2dNodePrime = here->MOS2dNode; } @@ -176,6 +190,16 @@ MOS2setup(matrix,inModel,ckt,states) error = CKTmkVolt(ckt,&tmp,here->MOS2name,"internal#source"); if(error) return(error); here->MOS2sNodePrime = tmp->number; + + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } + } else { here->MOS2sNodePrime = here->MOS2sNode; } @@ -219,7 +243,6 @@ MOS2unsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM MOS2model *model; MOS2instance *here; @@ -243,6 +266,5 @@ MOS2unsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/mos2/mos2sld.c b/src/spicelib/devices/mos2/mos2sld.c index 0a31d6914..dd4019d54 100644 --- a/src/spicelib/devices/mos2/mos2sld.c +++ b/src/spicelib/devices/mos2/mos2sld.c @@ -20,8 +20,8 @@ MOS2sLoad(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { - register MOS2model *model = (MOS2model *)inModel; - register MOS2instance *here; + MOS2model *model = (MOS2model *)inModel; + MOS2instance *here; double SaveState[44]; int save_mode; int i; diff --git a/src/spicelib/devices/mos2/mos2sprt.c b/src/spicelib/devices/mos2/mos2sprt.c index a3890942d..c4a5820c1 100644 --- a/src/spicelib/devices/mos2/mos2sprt.c +++ b/src/spicelib/devices/mos2/mos2sprt.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -14,15 +15,15 @@ Author: 1985 Thomas L. Quarles void MOS2sPrint(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* Pretty print the sensitivity info for all the MOS2 * devices in the circuit. */ { - register MOS2model *model = (MOS2model *)inModel; - register MOS2instance *here; + MOS2model *model = (MOS2model *)inModel; + MOS2instance *here; - printf("LEVEL 1 MOSFETS-----------------\n"); + printf("LEVEL 2 MOSFETS-----------------\n"); /* loop through all the MOS2 models */ for( ; model != NULL; model = model->MOS2nextModel ) { @@ -38,6 +39,8 @@ MOS2sPrint(inModel,ckt) CKTnodName(ckt,here->MOS2dNode),CKTnodName(ckt,here->MOS2gNode), CKTnodName(ckt,here->MOS2sNode)); + printf(" Multiplier: %g ",here->MOS2m); + printf(here->MOS2mGiven ? "(specified)\n" : "(default)\n"); printf(" Length: %g ",here->MOS2l); printf(here->MOS2lGiven ? "(specified)\n" : "(default)\n"); printf(" Width: %g ",here->MOS2w); diff --git a/src/spicelib/devices/mos2/mos2sset.c b/src/spicelib/devices/mos2/mos2sset.c index b002d7946..b2462853e 100644 --- a/src/spicelib/devices/mos2/mos2sset.c +++ b/src/spicelib/devices/mos2/mos2sset.c @@ -13,14 +13,14 @@ Author: 1985 Thomas L. Quarles int MOS2sSetup(info,inModel) -register SENstruct *info; +SENstruct *info; GENmodel *inModel; /* loop through all the devices and * allocate parameter #s to design parameters */ { - register MOS2model *model = (MOS2model *)inModel; - register MOS2instance *here; + MOS2model *model = (MOS2model *)inModel; + MOS2instance *here; /* loop through all the models */ for( ; model != NULL; model = model->MOS2nextModel ) { diff --git a/src/spicelib/devices/mos2/mos2supd.c b/src/spicelib/devices/mos2/mos2supd.c index a3a13cb3e..b7a64b387 100644 --- a/src/spicelib/devices/mos2/mos2supd.c +++ b/src/spicelib/devices/mos2/mos2supd.c @@ -16,10 +16,10 @@ Author: 1985 Thomas L. Quarles int MOS2sUpdate(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register MOS2model *model = (MOS2model *)inModel; - register MOS2instance *here; + MOS2model *model = (MOS2model *)inModel; + MOS2instance *here; int iparmno; double sb; double sg; diff --git a/src/spicelib/devices/mos2/mos2temp.c b/src/spicelib/devices/mos2/mos2temp.c index b5f8d8521..f72f93345 100644 --- a/src/spicelib/devices/mos2/mos2temp.c +++ b/src/spicelib/devices/mos2/mos2temp.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -17,10 +18,10 @@ Author: 1985 Thomas L. Quarles int MOS2temp(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register MOS2model *model = (MOS2model *)inModel; - register MOS2instance *here; + MOS2model *model = (MOS2model *)inModel; + MOS2instance *here; double egfet; double wkfngs; double wkfng; @@ -147,6 +148,9 @@ MOS2temp(inModel,ckt) if(!here->MOS2drainAreaGiven) { here->MOS2drainArea = ckt->CKTdefaultMosAD; + } + if(!here->MOS2mGiven) { + here->MOS2m = ckt->CKTdefaultMosM; } if(!here->MOS2lGiven) { here->MOS2l = ckt->CKTdefaultMosL; @@ -159,14 +163,17 @@ MOS2temp(inModel,ckt) } if(model->MOS2drainResistanceGiven) { if(model->MOS2drainResistance != 0) { - here->MOS2drainConductance = 1/model->MOS2drainResistance; + here->MOS2drainConductance = here->MOS2m / + model->MOS2drainResistance; } else { here->MOS2drainConductance = 0; } } else if (model->MOS2sheetResistanceGiven) { - if(model->MOS2sheetResistance != 0) { + if((model->MOS2sheetResistance != 0) && + (here->MOS2drainSquares != 0)) { here->MOS2drainConductance = - 1/(model->MOS2sheetResistance*here->MOS2drainSquares); + here->MOS2m / + (model->MOS2sheetResistance*here->MOS2drainSquares); } else { here->MOS2drainConductance = 0; } @@ -175,14 +182,17 @@ MOS2temp(inModel,ckt) } if(model->MOS2sourceResistanceGiven) { if(model->MOS2sourceResistance != 0) { - here->MOS2sourceConductance = 1/model->MOS2sourceResistance; + here->MOS2sourceConductance = here->MOS2m / + model->MOS2sourceResistance; } else { here->MOS2sourceConductance = 0; } } else if (model->MOS2sheetResistanceGiven) { - if(model->MOS2sheetResistance != 0) { + if ((model->MOS2sheetResistance != 0) && + (here->MOS2sourceSquares != 0)) { here->MOS2sourceConductance = - 1/(model->MOS2sheetResistance*here->MOS2sourceSquares); + here->MOS2m / + (model->MOS2sheetResistance*here->MOS2sourceSquares); } else { here->MOS2sourceConductance = 0; } @@ -238,26 +248,29 @@ MOS2temp(inModel,ckt) (here->MOS2drainArea == 0) || (here->MOS2sourceArea == 0) ) { here->MOS2sourceVcrit = here->MOS2drainVcrit = - vt*log(vt/(CONSTroot2*here->MOS2tSatCur)); + vt*log(vt/(CONSTroot2*here->MOS2m*here->MOS2tSatCur)); } else { here->MOS2drainVcrit = vt * log( vt / (CONSTroot2 * + here->MOS2m * here->MOS2tSatCurDens * here->MOS2drainArea)); here->MOS2sourceVcrit = vt * log( vt / (CONSTroot2 * + here->MOS2m * here->MOS2tSatCurDens * here->MOS2sourceArea)); } if(model->MOS2capBDGiven) { - czbd = here->MOS2tCbd; + czbd = here->MOS2tCbd * here->MOS2m; } else { if(model->MOS2bulkCapFactorGiven) { - czbd=here->MOS2tCj*here->MOS2drainArea; + czbd=here->MOS2tCj*here->MOS2drainArea * here->MOS2m; } else { czbd=0; } } if(model->MOS2sideWallCapFactorGiven) { - czbdsw= here->MOS2tCjsw * here->MOS2drainPerimiter; + czbdsw= here->MOS2tCjsw * here->MOS2drainPerimiter * + here->MOS2m;; } else { czbdsw=0; } @@ -283,16 +296,17 @@ MOS2temp(inModel,ckt) (here->MOS2tDepCap*here->MOS2tDepCap) -here->MOS2tDepCap * here->MOS2f2d; if(model->MOS2capBSGiven) { - czbs=here->MOS2tCbs; + czbs=here->MOS2tCbs * here->MOS2m; } else { if(model->MOS2bulkCapFactorGiven) { - czbs=here->MOS2tCj*here->MOS2sourceArea; + czbs=here->MOS2tCj*here->MOS2sourceArea * here->MOS2m; } else { czbs=0; } } if(model->MOS2sideWallCapFactorGiven) { - czbssw = here->MOS2tCjsw * here->MOS2sourcePerimiter; + czbssw = here->MOS2tCjsw * here->MOS2sourcePerimiter * + here->MOS2m; } else { czbssw=0; } diff --git a/src/spicelib/devices/mos2/mos2trun.c b/src/spicelib/devices/mos2/mos2trun.c index 8a615dbef..2fc0f8f82 100644 --- a/src/spicelib/devices/mos2/mos2trun.c +++ b/src/spicelib/devices/mos2/mos2trun.c @@ -16,11 +16,11 @@ Author: 1985 Thomas L. Quarles int MOS2trunc(inModel,ckt,timeStep) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; double *timeStep; { - register MOS2model *model = (MOS2model *)inModel; - register MOS2instance *here; + MOS2model *model = (MOS2model *)inModel; + MOS2instance *here; for( ; model != NULL; model = model->MOS2nextModel) { for(here=model->MOS2instances;here!=NULL;here = here->MOS2nextInstance){ diff --git a/src/spicelib/devices/mos3/Makefile.am b/src/spicelib/devices/mos3/Makefile.am index 0006ec791..ea4407ffa 100644 --- a/src/spicelib/devices/mos3/Makefile.am +++ b/src/spicelib/devices/mos3/Makefile.am @@ -2,35 +2,36 @@ pkglib_LTLIBRARIES = libmos3.la -libmos3_la_SOURCES = \ - mos3.c \ - mos3acld.c \ - mos3ask.c \ - mos3conv.c \ - mos3defs.h \ - mos3del.c \ - mos3dest.c \ - mos3dist.c \ - mos3dset.c \ - mos3ext.h \ - mos3ic.c \ - mos3itf.h \ - mos3load.c \ - mos3mask.c \ - mos3mdel.c \ - mos3mpar.c \ - mos3noi.c \ - mos3par.c \ - mos3pzld.c \ - mos3sacl.c \ - mos3set.c \ - mos3sld.c \ - mos3sprt.c \ - mos3sset.c \ - mos3supd.c \ - mos3temp.c \ - mos3trun.c - +libmos3_la_SOURCES = \ + mos3.c \ + mos3acld.c \ + mos3ask.c \ + mos3conv.c \ + mos3defs.h \ + mos3del.c \ + mos3dest.c \ + mos3dist.c \ + mos3dset.c \ + mos3ext.h \ + mos3ic.c \ + mos3init.c \ + mos3init.h \ + mos3itf.h \ + mos3load.c \ + mos3mask.c \ + mos3mdel.c \ + mos3mpar.c \ + mos3noi.c \ + mos3par.c \ + mos3pzld.c \ + mos3sacl.c \ + mos3set.c \ + mos3sld.c \ + mos3sprt.c \ + mos3sset.c \ + mos3supd.c \ + mos3temp.c \ + mos3trun.c INCLUDES = -I$(top_srcdir)/src/include diff --git a/src/spicelib/devices/mos3/mos3.c b/src/spicelib/devices/mos3/mos3.c index 04c1566cb..faea44dfd 100644 --- a/src/spicelib/devices/mos3/mos3.c +++ b/src/spicelib/devices/mos3/mos3.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1987 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -11,6 +12,7 @@ Author: 1987 Thomas L. Quarles #include "suffix.h" IFparm MOS3pTable[] = { /* parameters */ + IOPU("m", MOS3_M, IF_REAL , "Multiplier"), IOPU("l", MOS3_L, IF_REAL , "Length"), IOPU("w", MOS3_W, IF_REAL , "Width"), IOPU("ad", MOS3_AD, IF_REAL , "Drain area"), @@ -131,6 +133,11 @@ IFparm MOS3mPTable[] = { /* model parameters */ IOPU("js", MOS3_MOD_JS, IF_REAL ,"Bulk jct. sat. current density"), IOP("tox", MOS3_MOD_TOX, IF_REAL ,"Oxide thickness"), IOP("ld", MOS3_MOD_LD, IF_REAL ,"Lateral diffusion"), + IOP("xl", MOS3_MOD_XL, IF_REAL ,"Length mask adjustment"), + IOP("wd", MOS3_MOD_WD, IF_REAL ,"Width Narrowing (Diffusion)"), + IOP("xw", MOS3_MOD_XW, IF_REAL ,"Width mask adjustment"), + IOPU("delvto", MOS3_MOD_DELVTO, IF_REAL ,"Threshold voltage Adjust"), + IOPR("delvt0", MOS3_MOD_DELVTO, IF_REAL ,"Threshold voltage Adjust"), IOP("u0", MOS3_MOD_U0, IF_REAL ,"Surface mobility"), IOPR("uo", MOS3_MOD_U0, IF_REAL ,"Surface mobility"), IOP("fc", MOS3_MOD_FC, IF_REAL ,"Forward bias jct. fit parm."), diff --git a/src/spicelib/devices/mos3/mos3acld.c b/src/spicelib/devices/mos3/mos3acld.c index a1db9e4b0..7e439c55d 100644 --- a/src/spicelib/devices/mos3/mos3acld.c +++ b/src/spicelib/devices/mos3/mos3acld.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* */ @@ -16,13 +17,14 @@ Author: 1985 Thomas L. Quarles int MOS3acLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register MOS3model *model = (MOS3model *)inModel; - register MOS3instance *here; + MOS3model *model = (MOS3model *)inModel; + MOS3instance *here; int xnrm; int xrev; double EffectiveLength; + double EffectiveWidth; double xgs; double xgd; double xgb; @@ -50,13 +52,17 @@ MOS3acLoad(inModel,ckt) /* * charge oriented model parameters */ - EffectiveLength=here->MOS3l-2*model->MOS3latDiff; + EffectiveWidth=here->MOS3w-2*model->MOS3widthNarrow+ + model->MOS3widthAdjust; + EffectiveLength=here->MOS3l - 2*model->MOS3latDiff+ + model->MOS3lengthAdjust; + GateSourceOverlapCap = model->MOS3gateSourceOverlapCapFactor * - here->MOS3w; + here->MOS3m * EffectiveWidth; GateDrainOverlapCap = model->MOS3gateDrainOverlapCapFactor * - here->MOS3w; + here->MOS3m * EffectiveWidth; GateBulkOverlapCap = model->MOS3gateBulkOverlapCapFactor * - EffectiveLength; + here->MOS3m * EffectiveLength; /* * meyer"s model parameters */ diff --git a/src/spicelib/devices/mos3/mos3ask.c b/src/spicelib/devices/mos3/mos3ask.c index 03f35a8b7..4da324cf7 100644 --- a/src/spicelib/devices/mos3/mos3ask.c +++ b/src/spicelib/devices/mos3/mos3ask.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1987 Mathew Lew and Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -34,10 +35,13 @@ MOS3ask(ckt,inst,which,value,select) value->rValue = here->MOS3temp-CONSTCtoK; return(OK); case MOS3_CGS: - value->rValue = *(ckt->CKTstate0 + here->MOS3capgs); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS3capgs); return(OK); case MOS3_CGD: - value->rValue = *(ckt->CKTstate0 + here->MOS3capgd); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS3capgd); + return(OK); + case MOS3_M: + value->rValue = here->MOS3m; return(OK); case MOS3_L: value->rValue = here->MOS3l; @@ -178,7 +182,13 @@ MOS3ask(ckt,inst,which,value,select) value->rValue = *(ckt->CKTstate0 + here->MOS3vds); return(OK); case MOS3_CAPGS: - value->rValue = *(ckt->CKTstate0 + here->MOS3capgs); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS3capgs); +/* add overlap capacitance */ + value->rValue += (here->MOS3modPtr->MOS3gateSourceOverlapCapFactor) + * here->MOS3m + * (here->MOS3w + +here->MOS3modPtr->MOS3widthAdjust + -2*(here->MOS3modPtr->MOS3widthNarrow)); return(OK); case MOS3_QGS: value->rValue = *(ckt->CKTstate0 + here->MOS3qgs); @@ -187,7 +197,13 @@ MOS3ask(ckt,inst,which,value,select) value->rValue = *(ckt->CKTstate0 + here->MOS3cqgs); return(OK); case MOS3_CAPGD: - value->rValue = *(ckt->CKTstate0 + here->MOS3capgd); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS3capgd); +/* add overlap capacitance */ + value->rValue += (here->MOS3modPtr->MOS3gateDrainOverlapCapFactor) + * here->MOS3m + * (here->MOS3w + +here->MOS3modPtr->MOS3widthAdjust + -2*(here->MOS3modPtr->MOS3widthNarrow)); return(OK); case MOS3_QGD: value->rValue = *(ckt->CKTstate0 + here->MOS3qgd); @@ -196,7 +212,13 @@ MOS3ask(ckt,inst,which,value,select) value->rValue = *(ckt->CKTstate0 + here->MOS3cqgd); return(OK); case MOS3_CAPGB: - value->rValue = *(ckt->CKTstate0 + here->MOS3capgb); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS3capgb); +/* add overlap capacitance */ + value->rValue += (here->MOS3modPtr->MOS3gateBulkOverlapCapFactor) + * here->MOS3m + * (here->MOS3l + +here->MOS3modPtr->MOS3lengthAdjust + -2*(here->MOS3modPtr->MOS3latDiff)); return(OK); case MOS3_QGB: value->rValue = *(ckt->CKTstate0 + here->MOS3qgb); diff --git a/src/spicelib/devices/mos3/mos3conv.c b/src/spicelib/devices/mos3/mos3conv.c index d5318d64a..853256fc4 100644 --- a/src/spicelib/devices/mos3/mos3conv.c +++ b/src/spicelib/devices/mos3/mos3conv.c @@ -13,10 +13,10 @@ Author: 1985 Thomas L. Quarles int MOS3convTest(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register MOS3model *model = (MOS3model *)inModel; - register MOS3instance *here; + MOS3model *model = (MOS3model *)inModel; + MOS3instance *here; double delvbs; double delvbd; double delvgs; diff --git a/src/spicelib/devices/mos3/mos3defs.h b/src/spicelib/devices/mos3/mos3defs.h index 70dfab657..8569eb597 100644 --- a/src/spicelib/devices/mos3/mos3defs.h +++ b/src/spicelib/devices/mos3/mos3defs.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlanFixes **********/ #ifndef MOS3 @@ -30,6 +31,7 @@ typedef struct sMOS3instance { int MOS3dNodePrime; /* number of the internal drain node of the mosfet */ int MOS3sNodePrime; /* number of the internal source node of the mosfet */ + double MOS3m; /* parallel device multiplier */ double MOS3l; /* the length of the channel region */ double MOS3w; /* the width of the channel region */ double MOS3drainArea; /* the area of the drain diffusion */ @@ -89,6 +91,7 @@ typedef struct sMOS3instance { unsigned MOS3off :1;/* non-zero to indicate device is off for dc analysis*/ unsigned MOS3tempGiven :1; /* instance temperature specified */ + unsigned MOS3mGiven :1; unsigned MOS3lGiven :1; unsigned MOS3wGiven :1; unsigned MOS3drainAreaGiven :1; @@ -321,6 +324,10 @@ typedef struct sMOS3model { /* model structure for a resistor */ int MOS3type; /* device type : 1 = nmos, -1 = pmos */ double MOS3tnom; /* temperature at which parameters measured */ double MOS3latDiff; + double MOS3lengthAdjust; /* New parm: mask adjustment to length */ + double MOS3widthNarrow; /* New parm to reduce effective width */ + double MOS3widthAdjust; /* New parm: mask adjustment to width */ + double MOS3delvt0; /* New parm: adjustment calculated vtO */ double MOS3jctSatCurDensity; /* input - use tSatCurDens*/ double MOS3jctSatCur; /* input - use tSatCur instead */ double MOS3drainResistance; @@ -362,6 +369,10 @@ typedef struct sMOS3model { /* model structure for a resistor */ unsigned MOS3typeGiven :1; unsigned MOS3latDiffGiven :1; + unsigned MOS3lengthAdjustGiven :1; + unsigned MOS3widthNarrowGiven :1; + unsigned MOS3widthAdjustGiven :1; + unsigned MOS3delvt0Given :1; unsigned MOS3jctSatCurDensityGiven :1; unsigned MOS3jctSatCurGiven :1; unsigned MOS3drainResistanceGiven :1; @@ -485,6 +496,7 @@ typedef struct sMOS3model { /* model structure for a resistor */ #define MOS3_TEMP 77 #define MOS3_SOURCERESIST 78 #define MOS3_DRAINRESIST 79 +#define MOS3_M 80 /* model parameters */ #define MOS3_MOD_VTO 101 @@ -532,6 +544,11 @@ typedef struct sMOS3model { /* model structure for a resistor */ #define MOS3_MOD_AF 143 #define MOS3_MOD_TYPE 144 +#define MOS3_MOD_XL 145 +#define MOS3_MOD_WD 146 +#define MOS3_MOD_XW 147 +#define MOS3_MOD_DELVTO 148 + /* device questions */ diff --git a/src/spicelib/devices/mos3/mos3dist.c b/src/spicelib/devices/mos3/mos3dist.c index 94e95af10..6221c83ee 100644 --- a/src/spicelib/devices/mos3/mos3dist.c +++ b/src/spicelib/devices/mos3/mos3dist.c @@ -14,7 +14,7 @@ Author: 1988 Jaijeet S Roychowdhury int MOS3disto(mode,genmodel,ckt) GENmodel *genmodel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int mode; /* assuming here that ckt->CKTomega has been initialised to @@ -40,7 +40,7 @@ MOS3disto(mode,genmodel,ckt) double r2h1m2y,i2h1m2y; double r2h1m2z, i2h1m2z; double temp, itemp; - register MOS3instance *here; + MOS3instance *here; if (mode == D_SETUP) return(MOS3dSetup(model,ckt)); diff --git a/src/spicelib/devices/mos3/mos3dset.c b/src/spicelib/devices/mos3/mos3dset.c index 6013da964..fe05c5f01 100644 --- a/src/spicelib/devices/mos3/mos3dset.c +++ b/src/spicelib/devices/mos3/mos3dset.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1988 Jaijeet S Roychowdhury +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -17,16 +18,17 @@ Author: 1988 Jaijeet S Roychowdhury int MOS3dSetup(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* actually load the current value into the * sparse matrix previously provided */ { - register MOS3model *model = (MOS3model *)inModel; - register MOS3instance *here; + MOS3model *model = (MOS3model *)inModel; + MOS3instance *here; double Beta; double DrainSatCur; double EffectiveLength; + double EffectiveWidth; double GateBulkOverlapCap; double GateDrainOverlapCap; double GateSourceOverlapCap; @@ -76,29 +78,32 @@ MOS3dSetup(inModel,ckt) * here. They may be moved at the expense of instance size */ - EffectiveLength=here->MOS3l - 2*model->MOS3latDiff; + EffectiveWidth=here->MOS3w-2*model->MOS3widthNarrow+ + model->MOS3widthAdjust; + EffectiveLength=here->MOS3l - 2*model->MOS3latDiff+ + model->MOS3lengthAdjust; + if( (here->MOS3tSatCurDens == 0) || (here->MOS3drainArea == 0) || (here->MOS3sourceArea == 0)) { - DrainSatCur = here->MOS3tSatCur; - SourceSatCur = here->MOS3tSatCur; + DrainSatCur = here->MOS3m * here->MOS3tSatCur; + SourceSatCur = here->MOS3m * here->MOS3tSatCur; } else { DrainSatCur = here->MOS3tSatCurDens * - here->MOS3drainArea; + here->MOS3m * here->MOS3drainArea; SourceSatCur = here->MOS3tSatCurDens * - here->MOS3sourceArea; + here->MOS3m * here->MOS3sourceArea; } GateSourceOverlapCap = model->MOS3gateSourceOverlapCapFactor * - here->MOS3w; + here->MOS3m * EffectiveWidth; GateDrainOverlapCap = model->MOS3gateDrainOverlapCapFactor * - here->MOS3w; + here->MOS3m * EffectiveWidth; GateBulkOverlapCap = model->MOS3gateBulkOverlapCapFactor * - EffectiveLength; - Beta = here->MOS3tTransconductance * here->MOS3w/EffectiveLength; + here->MOS3m * EffectiveLength; + Beta = here->MOS3tTransconductance * here->MOS3m * + EffectiveWidth/EffectiveLength; OxideCap = model->MOS3oxideCapFactor * EffectiveLength * - here->MOS3w; - - + here->MOS3m * EffectiveWidth; /* * ok - now to do the start-up operations @@ -381,7 +386,7 @@ d_p.d3_pqr = 0.0; fbodys = 0.5*gammas/(sqphbs+sqphbs); DivDeriv(&d_fbodys,&d_gammas,&d_sqphbs); TimesDeriv(&d_fbodys,&d_fbodys,0.25); - fbody = fbodys+model->MOS3narrowFactor/here->MOS3w; + fbody = fbodys+model->MOS3narrowFactor/EffectiveWidth; EqualDeriv(&d_fbody,&d_fbodys); d_fbody.value += fbody - fbodys; @@ -389,9 +394,10 @@ d_p.d3_pqr = 0.0; EqualDeriv(&d_onfbdy,&d_fbody); d_onfbdy.value += 1.0; InvDeriv(&d_onfbdy,&d_onfbdy); - qbonco =gammas*sqphbs+model->MOS3narrowFactor*phibs/here->MOS3w; + qbonco =gammas*sqphbs+model->MOS3narrowFactor*phibs/EffectiveWidth; EqualDeriv(&d_dummy,&d_phibs); - TimesDeriv(&d_dummy,&d_dummy,model->MOS3narrowFactor*here->MOS3w); + TimesDeriv(&d_dummy,&d_dummy,model-> + MOS3narrowFactor*EffectiveWidth); MultDeriv(&d_qbonco,&d_gammas,&d_sqphbs); PlusDeriv(&d_qbonco,&d_qbonco,&d_dummy); /* @@ -412,7 +418,8 @@ d_p.d3_pqr = 0.0; EqualDeriv(&d_von,&d_vth); if ( model->MOS3fastSurfaceStateDensity != 0.0 ) { csonco = CHARGE*model->MOS3fastSurfaceStateDensity * - 1e4 /*(cm**2/m**2)*/ *EffectiveLength*here->MOS3w/OxideCap;/*const*/ + 1e4 /*(cm**2/m**2)*/ *EffectiveLength*EffectiveWidth * + here->MOS3m/OxideCap; /*const*/ cdonco = 0.5*qbonco/phibs; DivDeriv(&d_cdonco,&d_qbonco,&d_phibs); TimesDeriv(&d_cdonco,&d_cdonco,0.5); diff --git a/src/spicelib/devices/mos3/mos3ext.h b/src/spicelib/devices/mos3/mos3ext.h index 06aa589a4..4807683a0 100644 --- a/src/spicelib/devices/mos3/mos3ext.h +++ b/src/spicelib/devices/mos3/mos3ext.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #ifdef __STDC__ @@ -27,6 +28,7 @@ extern int MOS3temp(GENmodel*,CKTcircuit*); extern int MOS3trunc(GENmodel*,CKTcircuit*,double*); extern int MOS3disto(int,GENmodel*,CKTcircuit*); extern int MOS3noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); +extern int MOS3dSetup(GENmodel*,CKTcircuit*); #else /* stdc */ extern int MOS3acLoad(); extern int MOS3ask(); diff --git a/src/spicelib/devices/mos3/mos3itf.h b/src/spicelib/devices/mos3/mos3itf.h index 27069b8fa..e7c301cd7 100644 --- a/src/spicelib/devices/mos3/mos3itf.h +++ b/src/spicelib/devices/mos3/mos3itf.h @@ -1,101 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_mos3 - #ifndef DEV_MOS3 #define DEV_MOS3 -#include "mos3ext.h" -extern IFparm MOS3pTable[ ]; -extern IFparm MOS3mPTable[ ]; -extern char *MOS3names[ ]; -extern int MOS3pTSize; -extern int MOS3mPTSize; -extern int MOS3nSize; -extern int MOS3iSize; -extern int MOS3mSize; - -SPICEdev MOS3info = { - { - "Mos3", - "Level 3 MOSfet model with Meyer capacitance model", - - &MOS3nSize, - &MOS3nSize, - MOS3names, - - &MOS3pTSize, - MOS3pTable, - - &MOS3mPTSize, - MOS3mPTable, - DEV_DEFAULT - }, - - MOS3param, - MOS3mParam, - MOS3load, - MOS3setup, - MOS3unsetup, - MOS3setup, - MOS3temp, - MOS3trunc, - NULL, - MOS3acLoad, - NULL, - MOS3destroy, -#ifdef DELETES - MOS3mDelete, - MOS3delete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - MOS3getic, - MOS3ask, - MOS3mAsk, -#ifdef AN_pz - MOS3pzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ -#ifdef NEWCONV - MOS3convTest, -#else /* NEWCONV */ - NULL, -#endif /* NEWCONV */ - -#ifdef AN_sense2 - MOS3sSetup, - MOS3sLoad, - MOS3sUpdate, - MOS3sAcLoad, - MOS3sPrint, - NULL, -#else /* AN_sense2 */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -#endif /* AN_sense2 */ -#ifdef AN_disto - MOS3disto, -#else /* AN_disto */ - NULL, -#endif /* AN_disto */ -#ifdef AN_noise - MOS3noise, -#else /* AN_noise */ - NULL, -#endif /* AN_noise */ - - &MOS3iSize, - &MOS3mSize - -}; +SPICEdev *get_mos3_info(void); #endif -#endif diff --git a/src/spicelib/devices/mos3/mos3load.c b/src/spicelib/devices/mos3/mos3load.c index d4d8242b4..e4a300dae 100644 --- a/src/spicelib/devices/mos3/mos3load.c +++ b/src/spicelib/devices/mos3/mos3load.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -13,19 +14,17 @@ Author: 1985 Thomas L. Quarles #include "sperror.h" #include "suffix.h" +/* actually load the current value into the sparse matrix previously + * provided */ int -MOS3load(inModel,ckt) - GENmodel *inModel; - register CKTcircuit *ckt; - /* actually load the current value into the - * sparse matrix previously provided - */ +MOS3load(GENmodel *inModel, CKTcircuit *ckt) { - register MOS3model *model = (MOS3model *)inModel; - register MOS3instance *here; + MOS3model *model = (MOS3model *)inModel; + MOS3instance *here; double Beta; double DrainSatCur; double EffectiveLength; + double EffectiveWidth; double GateBulkOverlapCap; double GateDrainOverlapCap; double GateSourceOverlapCap; @@ -74,39 +73,28 @@ MOS3load(inModel,ckt) double capgd; /* total gate-drain capacitance */ double capgb; /* total gate-bulk capacitance */ int Check; -#ifndef NOBYPASS double tempv; -#endif /*NOBYPASS*/ int error; -#ifdef CAPBYPASS - int senflag; -#endif /* CAPBYPASS */ int SenCond; double vt; /* vt at instance temperature */ -#ifdef CAPBYPASS - senflag = 0; -#endif /* CAPBYPASS */ if(ckt->CKTsenInfo){ if(ckt->CKTsenInfo->SENstatus == PERTURBATION) { if((ckt->CKTsenInfo->SENmode == ACSEN)|| - (ckt->CKTsenInfo->SENmode == TRANSEN)){ -#ifdef CAPBYPASS - senflag = 1; -#endif /* CAPBYPASS */ + (ckt->CKTsenInfo->SENmode == TRANSEN)){ } goto next; } } /* loop through all the MOS3 device models */ -next: + next: for( ; model != NULL; model = model->MOS3nextModel ) { /* loop through all the instances of the model */ for (here = model->MOS3instances; here != NULL ; - here=here->MOS3nextInstance) { + here=here->MOS3nextInstance) { if (here->MOS3owner != ARCHme) continue; vt = CONSTKoverQ * here->MOS3temp; @@ -122,44 +110,45 @@ next: } SenCond = ckt->CKTsenInfo && here->MOS3senPertFlag; -#ifdef DETAILPROF -asm(" .globl mos3pta"); -asm("mos3pta:"); -#endif /* DETAILPROF */ /* first, we compute a few useful values - these could be * pre-computed, but for historical reasons are still done - * here. They may be moved at the expense of instance size - */ + * here. They may be moved at the expense of instance + * size */ - EffectiveLength=here->MOS3l - 2*model->MOS3latDiff; - if( (here->MOS3tSatCurDens == 0) || - (here->MOS3drainArea == 0) || - (here->MOS3sourceArea == 0)) { - DrainSatCur = here->MOS3tSatCur; - SourceSatCur = here->MOS3tSatCur; + EffectiveWidth=here->MOS3w-2*model->MOS3widthNarrow+ + model->MOS3widthAdjust; + EffectiveLength=here->MOS3l - 2*model->MOS3latDiff+ + model->MOS3lengthAdjust; + + if( (here->MOS3tSatCurDens == 0) || + (here->MOS3drainArea == 0) || + (here->MOS3sourceArea == 0)) { + DrainSatCur = here->MOS3m * here->MOS3tSatCur; + SourceSatCur = here->MOS3m * here->MOS3tSatCur; } else { - DrainSatCur = here->MOS3tSatCurDens * - here->MOS3drainArea; - SourceSatCur = here->MOS3tSatCurDens * - here->MOS3sourceArea; + DrainSatCur = here->MOS3m * here->MOS3tSatCurDens * + here->MOS3drainArea; + SourceSatCur = here->MOS3m * here->MOS3tSatCurDens * + here->MOS3sourceArea; } GateSourceOverlapCap = model->MOS3gateSourceOverlapCapFactor * - here->MOS3w; + here->MOS3m * EffectiveWidth; GateDrainOverlapCap = model->MOS3gateDrainOverlapCapFactor * - here->MOS3w; + here->MOS3m * EffectiveWidth; GateBulkOverlapCap = model->MOS3gateBulkOverlapCapFactor * - EffectiveLength; - Beta = here->MOS3tTransconductance * here->MOS3w/EffectiveLength; + here->MOS3m * EffectiveLength; + Beta = here->MOS3tTransconductance * + here->MOS3m * EffectiveWidth/EffectiveLength; OxideCap = model->MOS3oxideCapFactor * EffectiveLength * - here->MOS3w; - + here->MOS3m * EffectiveWidth; + if(SenCond){ #ifdef SENSDEBUG printf("MOS3senPertFlag = ON \n"); #endif /* SENSDEBUG */ if((ckt->CKTsenInfo->SENmode == TRANSEN) && - (ckt->CKTmode & MODEINITTRAN)) { + (ckt->CKTmode & MODEINITTRAN)) { vgs = *(ckt->CKTstate1 + here->MOS3vgs); vds = *(ckt->CKTstate1 + here->MOS3vds); vbs = *(ckt->CKTstate1 + here->MOS3vbs); @@ -192,24 +181,20 @@ asm("mos3pta:"); goto next1; } -#ifdef DETAILPROF -asm(" .globl mos3ptax"); -asm("mos3ptax:"); -#endif /* DETAILPROF */ /* * ok - now to do the start-up operations * * we must get values for vbs, vds, and vgs from somewhere - * so we either predict them or recover them from last iteration - * These are the two most common cases - either a prediction - * step or the general iteration step and they - * share some code, so we put them first - others later on - */ + * so we either predict them or recover them from last + * iteration These are the two most common cases - either + * a prediction step or the general iteration step and + * they share some code, so we put them first - others + * later on */ if((ckt->CKTmode & (MODEINITFLOAT | MODEINITPRED | MODEINITSMSIG | - MODEINITTRAN)) || - ( (ckt->CKTmode & MODEINITFIX) && (!here->MOS3off) ) ) { + MODEINITTRAN)) || + ( (ckt->CKTmode & MODEINITFIX) && (!here->MOS3off) ) ) { #ifndef PREDICTOR if(ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) { @@ -217,20 +202,20 @@ asm("mos3ptax:"); xfact=ckt->CKTdelta/ckt->CKTdeltaOld[1]; *(ckt->CKTstate0 + here->MOS3vbs) = - *(ckt->CKTstate1 + here->MOS3vbs); + *(ckt->CKTstate1 + here->MOS3vbs); vbs = (1+xfact)* (*(ckt->CKTstate1 + here->MOS3vbs)) - -(xfact * (*(ckt->CKTstate2 + here->MOS3vbs))); + -(xfact * (*(ckt->CKTstate2 + here->MOS3vbs))); *(ckt->CKTstate0 + here->MOS3vgs) = - *(ckt->CKTstate1 + here->MOS3vgs); + *(ckt->CKTstate1 + here->MOS3vgs); vgs = (1+xfact)* (*(ckt->CKTstate1 + here->MOS3vgs)) - -(xfact * (*(ckt->CKTstate2 + here->MOS3vgs))); + -(xfact * (*(ckt->CKTstate2 + here->MOS3vgs))); *(ckt->CKTstate0 + here->MOS3vds) = - *(ckt->CKTstate1 + here->MOS3vds); + *(ckt->CKTstate1 + here->MOS3vds); vds = (1+xfact)* (*(ckt->CKTstate1 + here->MOS3vds)) - -(xfact * (*(ckt->CKTstate2 + here->MOS3vds))); + -(xfact * (*(ckt->CKTstate2 + here->MOS3vds))); *(ckt->CKTstate0 + here->MOS3vbd) = - *(ckt->CKTstate0 + here->MOS3vbs)- - *(ckt->CKTstate0 + here->MOS3vds); + *(ckt->CKTstate0 + here->MOS3vbs)- + *(ckt->CKTstate0 + here->MOS3vds); } else { #endif /*PREDICTOR*/ @@ -250,15 +235,11 @@ asm("mos3ptax:"); #endif /*PREDICTOR*/ /* now some common crunching for some more useful quantities */ -#ifdef DETAILPROF -asm(" .globl mos3ptay"); -asm("mos3ptay:"); -#endif /* DETAILPROF */ vbd=vbs-vds; vgd=vgs-vds; vgdo = *(ckt->CKTstate0 + here->MOS3vgs) - - *(ckt->CKTstate0 + here->MOS3vds); + *(ckt->CKTstate0 + here->MOS3vds); delvbs = vbs - *(ckt->CKTstate0 + here->MOS3vbs); delvbd = vbd - *(ckt->CKTstate0 + here->MOS3vbd); delvgs = vgs - *(ckt->CKTstate0 + here->MOS3vgs); @@ -278,7 +259,7 @@ asm("mos3ptay:"); cdhat= here->MOS3cd - ( here->MOS3gbd - - here->MOS3gmbs) * delvbd - + here->MOS3gmbs) * delvbd - here->MOS3gm * delvgd + here->MOS3gds * delvds ; } @@ -288,70 +269,60 @@ asm("mos3ptay:"); here->MOS3gbd * delvbd + here->MOS3gbs * delvbs ; -#ifdef DETAILPROF -asm(" .globl mos3ptb"); -asm("mos3ptb:"); -#endif /* DETAILPROF */ -#ifndef NOBYPASS /* now lets see if we can bypass (ugh) */ /* the following mess should be one if statement, but * many compilers can't handle it all at once, so it * is split into several successive if statements */ tempv = MAX(fabs(cbhat),fabs(here->MOS3cbs - + here->MOS3cbd))+ckt->CKTabstol; + + here->MOS3cbd))+ckt->CKTabstol; if((!(ckt->CKTmode & (MODEINITPRED|MODEINITTRAN|MODEINITSMSIG) - )) && (ckt->CKTbypass) ) - if ( (fabs(cbhat-(here->MOS3cbs + - here->MOS3cbd)) < ckt->CKTreltol * - tempv)) - if( (fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs), - fabs(*(ckt->CKTstate0+here->MOS3vbs)))+ - ckt->CKTvoltTol))) - if ( (fabs(delvbd) < (ckt->CKTreltol * MAX(fabs(vbd), - fabs(*(ckt->CKTstate0+here->MOS3vbd)))+ - ckt->CKTvoltTol)) ) - if( (fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs), - fabs(*(ckt->CKTstate0+here->MOS3vgs)))+ - ckt->CKTvoltTol))) - if ( (fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), - fabs(*(ckt->CKTstate0+here->MOS3vds)))+ - ckt->CKTvoltTol)) ) - if( (fabs(cdhat- here->MOS3cd) < - ckt->CKTreltol * MAX(fabs(cdhat),fabs( - here->MOS3cd)) + ckt->CKTabstol) ) { - /* bypass code */ - /* nothing interesting has changed since last - * iteration on this device, so we just - * copy all the values computed last iteration out - * and keep going - */ - vbs = *(ckt->CKTstate0 + here->MOS3vbs); - vbd = *(ckt->CKTstate0 + here->MOS3vbd); - vgs = *(ckt->CKTstate0 + here->MOS3vgs); - vds = *(ckt->CKTstate0 + here->MOS3vds); - vgd = vgs - vds; - vgb = vgs - vbs; - cdrain = here->MOS3mode * (here->MOS3cd + here->MOS3cbd); - if(ckt->CKTmode & (MODETRAN | MODETRANOP)) { - capgs = ( *(ckt->CKTstate0+here->MOS3capgs)+ - *(ckt->CKTstate1+here->MOS3capgs) + - GateSourceOverlapCap ); - capgd = ( *(ckt->CKTstate0+here->MOS3capgd)+ - *(ckt->CKTstate1+here->MOS3capgd) + - GateDrainOverlapCap ); - capgb = ( *(ckt->CKTstate0+here->MOS3capgb)+ - *(ckt->CKTstate1+here->MOS3capgb) + - GateBulkOverlapCap ); - } - goto bypass; - } -#endif /*NOBYPASS*/ + )) && (ckt->CKTbypass) ) + if ( (fabs(cbhat-(here->MOS3cbs + + here->MOS3cbd)) < ckt->CKTreltol * + tempv)) + if( (fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs), + fabs(*(ckt->CKTstate0+here->MOS3vbs)))+ + ckt->CKTvoltTol))) + if ( (fabs(delvbd) < (ckt->CKTreltol * MAX(fabs(vbd), + fabs(*(ckt->CKTstate0+here->MOS3vbd)))+ + ckt->CKTvoltTol)) ) + if( (fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs), + fabs(*(ckt->CKTstate0+here->MOS3vgs)))+ + ckt->CKTvoltTol))) + if ( (fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), + fabs(*(ckt->CKTstate0+here->MOS3vds)))+ + ckt->CKTvoltTol)) ) + if( (fabs(cdhat- here->MOS3cd) < + ckt->CKTreltol * MAX(fabs(cdhat),fabs( + here->MOS3cd)) + ckt->CKTabstol) ) { + /* bypass code */ + /* nothing interesting has changed since last + * iteration on this device, so we just + * copy all the values computed last iteration out + * and keep going + */ + vbs = *(ckt->CKTstate0 + here->MOS3vbs); + vbd = *(ckt->CKTstate0 + here->MOS3vbd); + vgs = *(ckt->CKTstate0 + here->MOS3vgs); + vds = *(ckt->CKTstate0 + here->MOS3vds); + vgd = vgs - vds; + vgb = vgs - vbs; + cdrain = here->MOS3mode * (here->MOS3cd + here->MOS3cbd); + if(ckt->CKTmode & (MODETRAN | MODETRANOP)) { + capgs = ( *(ckt->CKTstate0+here->MOS3capgs)+ + *(ckt->CKTstate1+here->MOS3capgs) + + GateSourceOverlapCap ); + capgd = ( *(ckt->CKTstate0+here->MOS3capgd)+ + *(ckt->CKTstate1+here->MOS3capgd) + + GateDrainOverlapCap ); + capgb = ( *(ckt->CKTstate0+here->MOS3capgb)+ + *(ckt->CKTstate1+here->MOS3capgb) + + GateBulkOverlapCap ); + } + goto bypass; + } -#ifdef DETAILPROF -asm(" .globl mos3ptc"); -asm("mos3ptc:"); -#endif /* DETAILPROF */ /* ok - bypass is out, do it the hard way */ von = model->MOS3type * here->MOS3von; @@ -366,7 +337,7 @@ asm("mos3ptc:"); if(*(ckt->CKTstate0 + here->MOS3vds) >=0) { vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->MOS3vgs) - ,von); + ,von); vds = vgs - vgd; vds = DEVlimvds(vds,*(ckt->CKTstate0 + here->MOS3vds)); vgd = vgs - vds; @@ -375,27 +346,23 @@ asm("mos3ptc:"); vds = vgs - vgd; if(!(ckt->CKTfixLimit)) { vds = -DEVlimvds(-vds,-(*(ckt->CKTstate0 + - here->MOS3vds))); + here->MOS3vds))); } vgs = vgd + vds; } if(vds >= 0) { vbs = DEVpnjlim(vbs,*(ckt->CKTstate0 + here->MOS3vbs), - vt,here->MOS3sourceVcrit,&Check); + vt,here->MOS3sourceVcrit,&Check); vbd = vbs-vds; } else { vbd = DEVpnjlim(vbd,*(ckt->CKTstate0 + here->MOS3vbd), - vt,here->MOS3drainVcrit,&Check); + vt,here->MOS3drainVcrit,&Check); vbs = vbd + vds; } #endif /*NODELIMITING*/ } else { -#ifdef DETAILPROF -asm(" .globl mos3ptd"); -asm("mos3ptd:"); -#endif /* DETAILPROF */ /* ok - not one of the simple cases, so we have to * look at all of the possibilities for why we were * called. We still just initialize the three voltages @@ -406,9 +373,9 @@ asm("mos3ptd:"); vgs= model->MOS3type * here->MOS3icVGS; vbs= model->MOS3type * here->MOS3icVBS; if((vds==0) && (vgs==0) && (vbs==0) && - ((ckt->CKTmode & - (MODETRAN|MODEDCOP|MODEDCTRANCURVE)) || - (!(ckt->CKTmode & MODEUIC)))) { + ((ckt->CKTmode & + (MODETRAN|MODEDCOP|MODEDCTRANCURVE)) || + (!(ckt->CKTmode & MODEUIC)))) { vbs = -1; vgs = model->MOS3type * here->MOS3tVto; vds = 0; @@ -418,10 +385,6 @@ asm("mos3ptd:"); } } -#ifdef DETAILPROF -asm(" .globl mos3pte"); -asm("mos3pte:"); -#endif /* DETAILPROF */ /* * now all the preliminaries are over - we can start doing the * real work @@ -436,23 +399,26 @@ asm("mos3pte:"); * here we just evaluate the ideal diode current and the * corresponding derivative (conductance). */ -next1: if(vbs <= 0) { - here->MOS3gbs = SourceSatCur/vt; - here->MOS3cbs = here->MOS3gbs*vbs; - here->MOS3gbs += ckt->CKTgmin; + +next1: if(vbs <= -3*vt) { + arg=3*vt/(vbs*CONSTe); + arg = arg * arg * arg; + here->MOS3cbs = -SourceSatCur*(1+arg)+ckt->CKTgmin*vbs; + here->MOS3gbs = SourceSatCur*3*arg/vbs+ckt->CKTgmin; } else { evbs = exp(MIN(MAX_EXP_ARG,vbs/vt)); here->MOS3gbs = SourceSatCur*evbs/vt + ckt->CKTgmin; - here->MOS3cbs = SourceSatCur * (evbs-1); + here->MOS3cbs = SourceSatCur*(evbs-1) + ckt->CKTgmin*vbs; } - if(vbd <= 0) { - here->MOS3gbd = DrainSatCur/vt; - here->MOS3cbd = here->MOS3gbd *vbd; - here->MOS3gbd += ckt->CKTgmin; + if(vbd <= -3*vt) { + arg=3*vt/(vbd*CONSTe); + arg = arg * arg * arg; + here->MOS3cbd = -DrainSatCur*(1+arg)+ckt->CKTgmin*vbd; + here->MOS3gbd = DrainSatCur*3*arg/vbd+ckt->CKTgmin; } else { evbd = exp(MIN(MAX_EXP_ARG,vbd/vt)); - here->MOS3gbd = DrainSatCur*evbd/vt +ckt->CKTgmin; - here->MOS3cbd = DrainSatCur *(evbd-1); + here->MOS3gbd = DrainSatCur*evbd/vt + ckt->CKTgmin; + here->MOS3cbd = DrainSatCur*(evbd-1) + ckt->CKTgmin*vbd; } /* now to determine whether the user was able to correctly @@ -466,877 +432,815 @@ next1: if(vbs <= 0) { here->MOS3mode = -1; } -#ifdef DETAILPROF -asm(" .globl mos3ptf"); -asm("mos3ptf:"); -#endif /* DETAILPROF */ { - /* - * subroutine moseq3(vds,vbs,vgs,gm,gds,gmbs, - * qg,qc,qb,cggb,cgdb,cgsb,cbgb,cbdb,cbsb) - */ + /* + * subroutine moseq3(vds,vbs,vgs,gm,gds,gmbs, + * qg,qc,qb,cggb,cgdb,cgsb,cbgb,cbdb,cbsb) + */ - /* - * this routine evaluates the drain current, its derivatives and - * the charges associated with the gate, channel and bulk - * for mosfets based on semi-empirical equations - */ + /* this routine evaluates the drain current, its + * derivatives and the charges associated with the + * gate, channel and bulk for mosfets based on + * semi-empirical equations */ - /* - common /mosarg/ vto,beta,gamma,phi,phib,cox,xnsub,xnfs,xd,xj,xld, - 1 xlamda,uo,uexp,vbp,utra,vmax,xneff,xl,xw,vbi,von,vdsat,qspof, - 2 beta0,beta1,cdrain,xqco,xqc,fnarrw,fshort,lev - common /status/ omega,time,delta,delold(7),ag(7),vt,xni,egfet, - 1 xmu,sfactr,mode,modedc,icalc,initf,method,iord,maxord,noncon, - 2 iterno,itemno,nosolv,modac,ipiv,ivmflg,ipostp,iscrch,iofile - common /knstnt/ twopi,xlog2,xlog10,root2,rad,boltz,charge,ctok, - 1 gmin,reltol,abstol,vntol,trtol,chgtol,eps0,epssil,epsox, - 2 pivtol,pivrel - */ - - /* equivalence (xlamda,alpha),(vbp,theta),(uexp,eta),(utra,xkappa)*/ - - double coeff0 = 0.0631353e0; - double coeff1 = 0.8013292e0; - double coeff2 = -0.01110777e0; - double oneoverxl; /* 1/effective length */ - double eta; /* eta from model after length factor */ - double phibs; /* phi - vbs */ - double sqphbs; /* square root of phibs */ - double dsqdvb; /* */ - double sqphis; /* square root of phi */ - double sqphs3; /* square root of phi cubed */ - double wps; - double oneoverxj; /* 1/junction depth */ - double xjonxl; /* junction depth/effective length */ - double djonxj; - double wponxj; - double arga; - double argb; - double argc; - double dwpdvb; - double dadvb; - double dbdvb; - double gammas; - double fbodys; - double fbody; - double onfbdy; - double qbonco; - double vbix; - double wconxj; - double dfsdvb; - double dfbdvb; - double dqbdvb; - double vth; - double dvtdvb; - double csonco; - double cdonco; - double dxndvb; - double dvodvb; - double dvodvd; - double vgsx; - double dvtdvd; - double onfg; - double fgate; - double us; - double dfgdvg; - double dfgdvd; - double dfgdvb; - double dvsdvg; - double dvsdvb; - double dvsdvd; - double xn; - double vdsc; - double onvdsc; - double dvsdga; - double vdsx; - double dcodvb; - double cdnorm; - double cdo; - double cd1; - double fdrain; - double fd2; - double dfddvg; - double dfddvb; - double dfddvd; - double gdsat; - double cdsat; - double gdoncd; - double gdonfd; - double gdonfg; - double dgdvg; - double dgdvd; - double dgdvb; - double emax; - double emongd; - double demdvg; - double demdvd; - double demdvb; - double delxl; - double dldvd; - double dldem; - double ddldvg; - double ddldvd; - double ddldvb; - double dlonxl; - double xlfact; - double diddl; - double gds0; - double emoncd; - double ondvt; - double onxn; - double wfact; - double gms; - double gmw; - double fshort; - - /* - * bypasses the computation of charges - */ - - /* - * reference cdrain equations to source and - * charge equations to bulk - */ - vdsat = 0.0; - oneoverxl = 1.0/EffectiveLength; - eta = model->MOS3eta * 8.15e-22/(model->MOS3oxideCapFactor* - EffectiveLength*EffectiveLength*EffectiveLength); - /* - *.....square root term - */ - if ( (here->MOS3mode==1?vbs:vbd) <= 0.0 ) { - phibs = here->MOS3tPhi-(here->MOS3mode==1?vbs:vbd); - sqphbs = sqrt(phibs); - dsqdvb = -0.5/sqphbs; - } else { - sqphis = sqrt(here->MOS3tPhi); - sqphs3 = here->MOS3tPhi*sqphis; - sqphbs = sqphis/(1.0+(here->MOS3mode==1?vbs:vbd)/ - (here->MOS3tPhi+here->MOS3tPhi)); - phibs = sqphbs*sqphbs; - dsqdvb = -phibs/(sqphs3+sqphs3); - } - /* - *.....short channel effect factor - */ - if ( (model->MOS3junctionDepth != 0.0) && - (model->MOS3coeffDepLayWidth != 0.0) ) { - wps = model->MOS3coeffDepLayWidth*sqphbs; - oneoverxj = 1.0/model->MOS3junctionDepth; - xjonxl = model->MOS3junctionDepth*oneoverxl; - djonxj = model->MOS3latDiff*oneoverxj; - wponxj = wps*oneoverxj; - wconxj = coeff0+coeff1*wponxj+coeff2*wponxj*wponxj; - arga = wconxj+djonxj; - argc = wponxj/(1.0+wponxj); - argb = sqrt(1.0-argc*argc); - fshort = 1.0-xjonxl*(arga*argb-djonxj); - dwpdvb = model->MOS3coeffDepLayWidth*dsqdvb; - dadvb = (coeff1+coeff2*(wponxj+wponxj))*dwpdvb*oneoverxj; - dbdvb = -argc*argc*(1.0-argc)*dwpdvb/(argb*wps); - dfsdvb = -xjonxl*(dadvb*argb+arga*dbdvb); - } else { - fshort = 1.0; - dfsdvb = 0.0; - } - /* - *.....body effect - */ - gammas = model->MOS3gamma*fshort; - fbodys = 0.5*gammas/(sqphbs+sqphbs); - fbody = fbodys+model->MOS3narrowFactor/here->MOS3w; - onfbdy = 1.0/(1.0+fbody); - dfbdvb = -fbodys*dsqdvb/sqphbs+fbodys*dfsdvb/fshort; - qbonco =gammas*sqphbs+model->MOS3narrowFactor*phibs/here->MOS3w; - dqbdvb = gammas*dsqdvb+model->MOS3gamma*dfsdvb*sqphbs- - model->MOS3narrowFactor/here->MOS3w; - /* - *.....static feedback effect - */ - vbix = here->MOS3tVbi*model->MOS3type-eta*(here->MOS3mode*vds); - /* - *.....threshold voltage - */ - vth = vbix+qbonco; - dvtdvd = -eta; - dvtdvb = dqbdvb; - /* - *.....joint weak inversion and strong inversion - */ - von = vth; - if ( model->MOS3fastSurfaceStateDensity != 0.0 ) { - csonco = CHARGE*model->MOS3fastSurfaceStateDensity * - 1e4 /*(cm**2/m**2)*/ *EffectiveLength*here->MOS3w/OxideCap; - cdonco = qbonco/(phibs+phibs); - xn = 1.0+csonco+cdonco; - von = vth+vt*xn; - dxndvb = dqbdvb/(phibs+phibs)-qbonco*dsqdvb/(phibs*sqphbs); - dvodvd = dvtdvd; - dvodvb = dvtdvb+vt*dxndvb; - } else { - /* - *.....cutoff region - */ - if ( (here->MOS3mode==1?vgs:vgd) <= von ) { - cdrain = 0.0; - here->MOS3gm = 0.0; - here->MOS3gds = 0.0; - here->MOS3gmbs = 0.0; - goto innerline1000; - } - } - /* - *.....device is on - */ - vgsx = MAX((here->MOS3mode==1?vgs:vgd),von); - /* - *.....mobility modulation by gate voltage - */ - onfg = 1.0+model->MOS3theta*(vgsx-vth); - fgate = 1.0/onfg; - us = here->MOS3tSurfMob * 1e-4 /*(m**2/cm**2)*/ *fgate; - dfgdvg = -model->MOS3theta*fgate*fgate; - dfgdvd = -dfgdvg*dvtdvd; - dfgdvb = -dfgdvg*dvtdvb; - /* - *.....saturation voltage - */ - vdsat = (vgsx-vth)*onfbdy; - if ( model->MOS3maxDriftVel <= 0.0 ) { - dvsdvg = onfbdy; - dvsdvd = -dvsdvg*dvtdvd; - dvsdvb = -dvsdvg*dvtdvb-vdsat*dfbdvb*onfbdy; - } else { - vdsc = EffectiveLength*model->MOS3maxDriftVel/us; - onvdsc = 1.0/vdsc; - arga = (vgsx-vth)*onfbdy; - argb = sqrt(arga*arga+vdsc*vdsc); - vdsat = arga+vdsc-argb; - dvsdga = (1.0-arga/argb)*onfbdy; - dvsdvg = dvsdga-(1.0-vdsc/argb)*vdsc*dfgdvg*onfg; - dvsdvd = -dvsdvg*dvtdvd; - dvsdvb = -dvsdvg*dvtdvb-arga*dvsdga*dfbdvb; - } - /* - *.....current factors in linear region - */ - vdsx = MIN((here->MOS3mode*vds),vdsat); - if ( vdsx == 0.0 ) goto line900; - cdo = vgsx-vth-0.5*(1.0+fbody)*vdsx; - dcodvb = -dvtdvb-0.5*dfbdvb*vdsx; - /* - *.....normalized drain current - */ - cdnorm = cdo*vdsx; - here->MOS3gm = vdsx; - here->MOS3gds = vgsx-vth-(1.0+fbody+dvtdvd)*vdsx; - here->MOS3gmbs = dcodvb*vdsx; - /* - *.....drain current without velocity saturation effect - */ - cd1 = Beta*cdnorm; - Beta = Beta*fgate; - cdrain = Beta*cdnorm; - here->MOS3gm = Beta*here->MOS3gm+dfgdvg*cd1; - here->MOS3gds = Beta*here->MOS3gds+dfgdvd*cd1; - here->MOS3gmbs = Beta*here->MOS3gmbs; - /* - *.....velocity saturation factor - */ - if ( model->MOS3maxDriftVel != 0.0 ) { - fdrain = 1.0/(1.0+vdsx*onvdsc); - fd2 = fdrain*fdrain; - arga = fd2*vdsx*onvdsc*onfg; - dfddvg = -dfgdvg*arga; - dfddvd = -dfgdvd*arga-fd2*onvdsc; - dfddvb = -dfgdvb*arga; - /* - *.....drain current - */ - here->MOS3gm = fdrain*here->MOS3gm+dfddvg*cdrain; - here->MOS3gds = fdrain*here->MOS3gds+dfddvd*cdrain; - here->MOS3gmbs = fdrain*here->MOS3gmbs+dfddvb*cdrain; - cdrain = fdrain*cdrain; - Beta = Beta*fdrain; - } - /* - *.....channel length modulation - */ - if ( (here->MOS3mode*vds) <= vdsat ) goto line700; - if ( model->MOS3maxDriftVel <= 0.0 ) goto line510; - if (model->MOS3alpha == 0.0) goto line700; - cdsat = cdrain; - gdsat = cdsat*(1.0-fdrain)*onvdsc; - gdsat = MAX(1.0e-12,gdsat); - gdoncd = gdsat/cdsat; - gdonfd = gdsat/(1.0-fdrain); - gdonfg = gdsat*onfg; - dgdvg = gdoncd*here->MOS3gm-gdonfd*dfddvg+gdonfg*dfgdvg; - dgdvd = gdoncd*here->MOS3gds-gdonfd*dfddvd+gdonfg*dfgdvd; - dgdvb = gdoncd*here->MOS3gmbs-gdonfd*dfddvb+gdonfg*dfgdvb; - - if (ckt->CKTbadMos3) - emax = cdsat*oneoverxl/gdsat; - else - emax = model->MOS3kappa * cdsat*oneoverxl/gdsat; - emoncd = emax/cdsat; - emongd = emax/gdsat; - demdvg = emoncd*here->MOS3gm-emongd*dgdvg; - demdvd = emoncd*here->MOS3gds-emongd*dgdvd; - demdvb = emoncd*here->MOS3gmbs-emongd*dgdvb; - - arga = 0.5*emax*model->MOS3alpha; - argc = model->MOS3kappa*model->MOS3alpha; - argb = sqrt(arga*arga+argc*((here->MOS3mode*vds)-vdsat)); - delxl = argb-arga; - if (argb != 0.0) { - dldvd = argc/(argb+argb); - dldem = 0.5*(arga/argb-1.0)*model->MOS3alpha; - } else { - dldvd = 0.0; - dldem = 0.0; - } - ddldvg = dldem*demdvg; - ddldvd = dldem*demdvd-dldvd; - ddldvb = dldem*demdvb; - goto line520; + double coeff0 = 0.0631353e0; + double coeff1 = 0.8013292e0; + double coeff2 = -0.01110777e0; + double oneoverxl; /* 1/effective length */ + double eta; /* eta from model after length factor */ + double phibs; /* phi - vbs */ + double sqphbs; /* square root of phibs */ + double dsqdvb; /* */ + double sqphis; /* square root of phi */ + double sqphs3; /* square root of phi cubed */ + double wps; + double oneoverxj; /* 1/junction depth */ + double xjonxl; /* junction depth/effective length */ + double djonxj; + double wponxj; + double arga; + double argb; + double argc; + double dwpdvb; + double dadvb; + double dbdvb; + double gammas; + double fbodys; + double fbody; + double onfbdy; + double qbonco; + double vbix; + double wconxj; + double dfsdvb; + double dfbdvb; + double dqbdvb; + double vth; + double dvtdvb; + double csonco; + double cdonco; + double dxndvb; + double dvodvb; + double dvodvd; + double vgsx; + double dvtdvd; + double onfg; + double fgate; + double us; + double dfgdvg; + double dfgdvd; + double dfgdvb; + double dvsdvg; + double dvsdvb; + double dvsdvd; + double xn; + double vdsc; + double onvdsc; + double dvsdga; + double vdsx; + double dcodvb; + double cdnorm; + double cdo; + double cd1; + double fdrain; + double fd2; + double dfddvg; + double dfddvb; + double dfddvd; + double gdsat; + double cdsat; + double gdoncd; + double gdonfd; + double gdonfg; + double dgdvg; + double dgdvd; + double dgdvb; + double emax; + double emongd; + double demdvg; + double demdvd; + double demdvb; + double delxl; + double dldvd; + double dldem; + double ddldvg; + double ddldvd; + double ddldvb; + double dlonxl; + double xlfact; + double diddl; + double gds0; + double emoncd; + double ondvt; + double onxn; + double wfact; + double gms; + double gmw; + double fshort; + + /* + * bypasses the computation of charges + */ + + /* + * reference cdrain equations to source and + * charge equations to bulk + */ + vdsat = 0.0; + oneoverxl = 1.0/EffectiveLength; + eta = model->MOS3eta * 8.15e-22/(model->MOS3oxideCapFactor* + EffectiveLength*EffectiveLength*EffectiveLength); + /* + *.....square root term + */ + if ( (here->MOS3mode==1?vbs:vbd) <= 0.0 ) { + phibs = here->MOS3tPhi-(here->MOS3mode==1?vbs:vbd); + sqphbs = sqrt(phibs); + dsqdvb = -0.5/sqphbs; + } else { + sqphis = sqrt(here->MOS3tPhi); + sqphs3 = here->MOS3tPhi*sqphis; + sqphbs = sqphis/(1.0+(here->MOS3mode==1?vbs:vbd)/ + (here->MOS3tPhi+here->MOS3tPhi)); + phibs = sqphbs*sqphbs; + dsqdvb = -phibs/(sqphs3+sqphs3); + } + /* + *.....short channel effect factor + */ + if ( (model->MOS3junctionDepth != 0.0) && + (model->MOS3coeffDepLayWidth != 0.0) ) { + wps = model->MOS3coeffDepLayWidth*sqphbs; + oneoverxj = 1.0/model->MOS3junctionDepth; + xjonxl = model->MOS3junctionDepth*oneoverxl; + djonxj = model->MOS3latDiff*oneoverxj; + wponxj = wps*oneoverxj; + wconxj = coeff0+coeff1*wponxj+coeff2*wponxj*wponxj; + arga = wconxj+djonxj; + argc = wponxj/(1.0+wponxj); + argb = sqrt(1.0-argc*argc); + fshort = 1.0-xjonxl*(arga*argb-djonxj); + dwpdvb = model->MOS3coeffDepLayWidth*dsqdvb; + dadvb = (coeff1+coeff2*(wponxj+wponxj))*dwpdvb*oneoverxj; + dbdvb = -argc*argc*(1.0-argc)*dwpdvb/(argb*wps); + dfsdvb = -xjonxl*(dadvb*argb+arga*dbdvb); + } else { + fshort = 1.0; + dfsdvb = 0.0; + } + /* + *.....body effect + */ + gammas = model->MOS3gamma*fshort; + fbodys = 0.5*gammas/(sqphbs+sqphbs); + fbody = fbodys+model->MOS3narrowFactor/EffectiveWidth; + onfbdy = 1.0/(1.0+fbody); + dfbdvb = -fbodys*dsqdvb/sqphbs+fbodys*dfsdvb/fshort; + qbonco =gammas*sqphbs+model->MOS3narrowFactor*phibs/EffectiveWidth; + dqbdvb = gammas*dsqdvb+model->MOS3gamma*dfsdvb*sqphbs- + model->MOS3narrowFactor/EffectiveWidth; + /* + *.....static feedback effect + */ + vbix = here->MOS3tVbi*model->MOS3type-eta*(here->MOS3mode*vds); + /* + *.....threshold voltage + */ + vth = vbix+qbonco; + dvtdvd = -eta; + dvtdvb = dqbdvb; + /* + *.....joint weak inversion and strong inversion + */ + von = vth; + if ( model->MOS3fastSurfaceStateDensity != 0.0 ) { + csonco = CHARGE*model->MOS3fastSurfaceStateDensity * + 1e4 /*(cm**2/m**2)*/ *EffectiveLength*EffectiveWidth * + here->MOS3m/OxideCap; + cdonco = qbonco/(phibs+phibs); + xn = 1.0+csonco+cdonco; + von = vth+vt*xn; + dxndvb = dqbdvb/(phibs+phibs)-qbonco*dsqdvb/(phibs*sqphbs); + dvodvd = dvtdvd; + dvodvb = dvtdvb+vt*dxndvb; + } else { + /* + *.....cutoff region + */ + if ( (here->MOS3mode==1?vgs:vgd) <= von ) { + cdrain = 0.0; + here->MOS3gm = 0.0; + here->MOS3gds = 0.0; + here->MOS3gmbs = 0.0; + goto innerline1000; + } + } + /* + *.....device is on + */ + vgsx = MAX((here->MOS3mode==1?vgs:vgd),von); + /* + *.....mobility modulation by gate voltage + */ + onfg = 1.0+model->MOS3theta*(vgsx-vth); + fgate = 1.0/onfg; + us = here->MOS3tSurfMob * 1e-4 /*(m**2/cm**2)*/ *fgate; + dfgdvg = -model->MOS3theta*fgate*fgate; + dfgdvd = -dfgdvg*dvtdvd; + dfgdvb = -dfgdvg*dvtdvb; + /* + *.....saturation voltage + */ + vdsat = (vgsx-vth)*onfbdy; + if ( model->MOS3maxDriftVel <= 0.0 ) { + dvsdvg = onfbdy; + dvsdvd = -dvsdvg*dvtdvd; + dvsdvb = -dvsdvg*dvtdvb-vdsat*dfbdvb*onfbdy; + } else { + vdsc = EffectiveLength*model->MOS3maxDriftVel/us; + onvdsc = 1.0/vdsc; + arga = (vgsx-vth)*onfbdy; + argb = sqrt(arga*arga+vdsc*vdsc); + vdsat = arga+vdsc-argb; + dvsdga = (1.0-arga/argb)*onfbdy; + dvsdvg = dvsdga-(1.0-vdsc/argb)*vdsc*dfgdvg*onfg; + dvsdvd = -dvsdvg*dvtdvd; + dvsdvb = -dvsdvg*dvtdvb-arga*dvsdga*dfbdvb; + } + /* + *.....current factors in linear region + */ + vdsx = MIN((here->MOS3mode*vds),vdsat); + if ( vdsx == 0.0 ) goto line900; + cdo = vgsx-vth-0.5*(1.0+fbody)*vdsx; + dcodvb = -dvtdvb-0.5*dfbdvb*vdsx; + /* + *.....normalized drain current + */ + cdnorm = cdo*vdsx; + here->MOS3gm = vdsx; + if ((here->MOS3mode*vds) > vdsat) here->MOS3gds = -dvtdvd*vdsx; + else here->MOS3gds = vgsx-vth-(1.0+fbody+dvtdvd)*vdsx; + here->MOS3gmbs = dcodvb*vdsx; + /* + *.....drain current without velocity saturation effect + */ + cd1 = Beta*cdnorm; + Beta = Beta*fgate; + cdrain = Beta*cdnorm; + here->MOS3gm = Beta*here->MOS3gm+dfgdvg*cd1; + here->MOS3gds = Beta*here->MOS3gds+dfgdvd*cd1; + here->MOS3gmbs = Beta*here->MOS3gmbs+dfgdvb*cd1; + /* + *.....velocity saturation factor + */ + if ( model->MOS3maxDriftVel > 0.0 ) { + fdrain = 1.0/(1.0+vdsx*onvdsc); + fd2 = fdrain*fdrain; + arga = fd2*vdsx*onvdsc*onfg; + dfddvg = -dfgdvg*arga; + if ((here->MOS3mode*vds) > vdsat) dfddvd = -dfgdvd*arga; + else dfddvd = -dfgdvd*arga-fd2*onvdsc; + dfddvb = -dfgdvb*arga; + /* + *.....drain current + */ + here->MOS3gm = fdrain*here->MOS3gm+dfddvg*cdrain; + here->MOS3gds = fdrain*here->MOS3gds+dfddvd*cdrain; + here->MOS3gmbs = fdrain*here->MOS3gmbs+dfddvb*cdrain; + cdrain = fdrain*cdrain; + Beta = Beta*fdrain; + } + /* + *.....channel length modulation + */ + + if ( (here->MOS3mode*vds) <= vdsat ) { + if ( (model->MOS3maxDriftVel > 0.0) || + (model->MOS3alpha == 0.0) || + (ckt->CKTbadMos3) ) goto line700; + else { + arga = (here->MOS3mode*vds)/vdsat; + delxl = sqrt(model->MOS3kappa*model->MOS3alpha*vdsat/8); + dldvd = 4*delxl*arga*arga*arga/vdsat; + arga *= arga; + arga *= arga; + delxl *= arga; + ddldvg = 0.0; + ddldvd = -dldvd; + ddldvb = 0.0; + goto line520; + }; + }; + + if ( model->MOS3maxDriftVel <= 0.0 ) goto line510; + if (model->MOS3alpha == 0.0) goto line700; + cdsat = cdrain; + gdsat = cdsat*(1.0-fdrain)*onvdsc; + gdsat = MAX(1.0e-12,gdsat); + gdoncd = gdsat/cdsat; + gdonfd = gdsat/(1.0-fdrain); + gdonfg = gdsat*onfg; + dgdvg = gdoncd*here->MOS3gm-gdonfd*dfddvg+gdonfg*dfgdvg; + dgdvd = gdoncd*here->MOS3gds-gdonfd*dfddvd+gdonfg*dfgdvd; + dgdvb = gdoncd*here->MOS3gmbs-gdonfd*dfddvb+gdonfg*dfgdvb; + + if (ckt->CKTbadMos3) + emax = cdsat*oneoverxl/gdsat; + else + emax = model->MOS3kappa * cdsat*oneoverxl/gdsat; + emoncd = emax/cdsat; + emongd = emax/gdsat; + demdvg = emoncd*here->MOS3gm-emongd*dgdvg; + demdvd = emoncd*here->MOS3gds-emongd*dgdvd; + demdvb = emoncd*here->MOS3gmbs-emongd*dgdvb; + + arga = 0.5*emax*model->MOS3alpha; + argc = model->MOS3kappa*model->MOS3alpha; + argb = sqrt(arga*arga+argc*((here->MOS3mode*vds)-vdsat)); + delxl = argb-arga; + if (argb != 0.0) { + dldvd = argc/(argb+argb); + dldem = 0.5*(arga/argb-1.0)*model->MOS3alpha; + } else { + dldvd = 0.0; + dldem = 0.0; + } + ddldvg = dldem*demdvg; + ddldvd = dldem*demdvd-dldvd; + ddldvb = dldem*demdvb; + goto line520; line510: - delxl = sqrt(model->MOS3kappa*((here->MOS3mode*vds)-vdsat)* - model->MOS3alpha); - dldvd = 0.5*delxl/((here->MOS3mode*vds)-vdsat); - ddldvg = 0.0; - ddldvd = -dldvd; - ddldvb = 0.0; - /* - *.....punch through approximation - */ + if (ckt->CKTbadMos3) { + delxl = sqrt(model->MOS3kappa*((here->MOS3mode*vds)-vdsat)* + model->MOS3alpha); + dldvd = 0.5*delxl/((here->MOS3mode*vds)-vdsat); + } else { + delxl = sqrt(model->MOS3kappa*model->MOS3alpha* + ((here->MOS3mode*vds)-vdsat+(vdsat/8))); + dldvd = 0.5*delxl/((here->MOS3mode*vds)-vdsat+(vdsat/8)); + }; + ddldvg = 0.0; + ddldvd = -dldvd; + ddldvb = 0.0; + /* + *.....punch through approximation + */ line520: - if ( delxl > (0.5*EffectiveLength) ) { - delxl = EffectiveLength-(EffectiveLength*EffectiveLength/ - (4.0*delxl)); - arga = 4.0*(EffectiveLength-delxl)*(EffectiveLength-delxl)/ - (EffectiveLength*EffectiveLength); - ddldvg = ddldvg*arga; - ddldvd = ddldvd*arga; - ddldvb = ddldvb*arga; - dldvd = dldvd*arga; - } - /* - *.....saturation region - */ - dlonxl = delxl*oneoverxl; - xlfact = 1.0/(1.0-dlonxl); - cdrain = cdrain*xlfact; - diddl = cdrain/(EffectiveLength-delxl); - here->MOS3gm = here->MOS3gm*xlfact+diddl*ddldvg; - gds0 = here->MOS3gds*xlfact+diddl*ddldvd; - here->MOS3gmbs = here->MOS3gmbs*xlfact+diddl*ddldvb; - here->MOS3gm = here->MOS3gm+gds0*dvsdvg; - here->MOS3gmbs = here->MOS3gmbs+gds0*dvsdvb; - here->MOS3gds = gds0*dvsdvd+diddl*dldvd; - /* - *.....finish strong inversion case - */ + if ( delxl > (0.5*EffectiveLength) ) { + delxl = EffectiveLength-(EffectiveLength*EffectiveLength/ + (4.0*delxl)); + arga = 4.0*(EffectiveLength-delxl)*(EffectiveLength-delxl)/ + (EffectiveLength*EffectiveLength); + ddldvg = ddldvg*arga; + ddldvd = ddldvd*arga; + ddldvb = ddldvb*arga; + dldvd = dldvd*arga; + } + /* + *.....saturation region + */ + dlonxl = delxl*oneoverxl; + xlfact = 1.0/(1.0-dlonxl); + + cd1 = cdrain; + cdrain = cdrain*xlfact; + diddl = cdrain/(EffectiveLength-delxl); + here->MOS3gm = here->MOS3gm*xlfact+diddl*ddldvg; + here->MOS3gmbs = here->MOS3gmbs*xlfact+diddl*ddldvb; + gds0 = diddl*ddldvd; + here->MOS3gm = here->MOS3gm+gds0*dvsdvg; + here->MOS3gmbs = here->MOS3gmbs+gds0*dvsdvb; + here->MOS3gds = here->MOS3gds*xlfact+diddl*dldvd+gds0*dvsdvd; +/* here->MOS3gds = (here->MOS3gds*xlfact)+gds0*dvsdvd- + (cd1*ddldvd/(EffectiveLength*(1-2*dlonxl+dlonxl*dlonxl)));*/ + + /* + *.....finish strong inversion case + */ line700: - if ( (here->MOS3mode==1?vgs:vgd) < von ) { - /* - *.....weak inversion - */ - onxn = 1.0/xn; - ondvt = onxn/vt; - wfact = exp( ((here->MOS3mode==1?vgs:vgd)-von)*ondvt ); - cdrain = cdrain*wfact; - gms = here->MOS3gm*wfact; - gmw = cdrain*ondvt; - here->MOS3gm = gmw; - if ((here->MOS3mode*vds) > vdsat) { - here->MOS3gm = here->MOS3gm+gds0*dvsdvg*wfact; - } - here->MOS3gds = here->MOS3gds*wfact+(gms-gmw)*dvodvd; - here->MOS3gmbs = here->MOS3gmbs*wfact+(gms-gmw)*dvodvb-gmw* - ((here->MOS3mode==1?vgs:vgd)-von)*onxn*dxndvb; - } - /* - *.....charge computation - */ - goto innerline1000; - /* - *.....special case of vds = 0.0d0 - */ + if ( (here->MOS3mode==1?vgs:vgd) < von ) { + /* + *.....weak inversion + */ + onxn = 1.0/xn; + ondvt = onxn/vt; + wfact = exp( ((here->MOS3mode==1?vgs:vgd)-von)*ondvt ); + cdrain = cdrain*wfact; + gms = here->MOS3gm*wfact; + gmw = cdrain*ondvt; + here->MOS3gm = gmw; + if ((here->MOS3mode*vds) > vdsat) { + here->MOS3gm = here->MOS3gm+gds0*dvsdvg*wfact; + } + here->MOS3gds = here->MOS3gds*wfact+(gms-gmw)*dvodvd; + here->MOS3gmbs = here->MOS3gmbs*wfact+(gms-gmw)*dvodvb-gmw* + ((here->MOS3mode==1?vgs:vgd)-von)*onxn*dxndvb; + } + /* + *.....charge computation + */ + goto innerline1000; + /* + *.....special case of vds = 0.0d0 + */ line900: - Beta = Beta*fgate; - cdrain = 0.0; - here->MOS3gm = 0.0; - here->MOS3gds = Beta*(vgsx-vth); - here->MOS3gmbs = 0.0; - if ( (model->MOS3fastSurfaceStateDensity != 0.0) && - ((here->MOS3mode==1?vgs:vgd) < von) ) { - here->MOS3gds *=exp(((here->MOS3mode==1?vgs:vgd)-von)/(vt*xn)); - } + Beta = Beta*fgate; + cdrain = 0.0; + here->MOS3gm = 0.0; + here->MOS3gds = Beta*(vgsx-vth); + here->MOS3gmbs = 0.0; + if ( (model->MOS3fastSurfaceStateDensity != 0.0) && + ((here->MOS3mode==1?vgs:vgd) < von) ) { + here->MOS3gds *=exp(((here->MOS3mode==1?vgs:vgd)-von)/(vt*xn)); + } innerline1000:; - /* - *.....done - */ - } - -#ifdef DETAILPROF -asm(" .globl mos3ptg"); -asm("mos3ptg:"); -#endif /* DETAILPROF */ - - /* now deal with n vs p polarity */ - - here->MOS3von = model->MOS3type * von; - here->MOS3vdsat = model->MOS3type * vdsat; - /* line 490 */ - /* - * COMPUTE EQUIVALENT DRAIN CURRENT SOURCE - */ - here->MOS3cd=here->MOS3mode * cdrain - here->MOS3cbd; - - if (ckt->CKTmode & (MODETRAN | MODETRANOP | MODEINITSMSIG)) { - /* - * now we do the hard part of the bulk-drain and bulk-source - * diode - we evaluate the non-linear capacitance and - * charge - * - * the basic equations are not hard, but the implementation - * is somewhat long in an attempt to avoid log/exponential - * evaluations - */ - /* - * charge storage elements - * - *.. bulk-drain and bulk-source depletion capacitances - */ -#ifdef CAPBYPASS - if(((ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) || - fabs(delvbs) >= ckt->CKTreltol * MAX(fabs(vbs), - fabs(*(ckt->CKTstate0+here->MOS3vbs)))+ - ckt->CKTvoltTol)|| senflag ) -#endif /*CAPBYPASS*/ - { - /* can't bypass the diode capacitance calculations */ -#ifdef CAPZEROBYPASS - if(here->MOS3Cbs != 0 || here->MOS3Cbssw != 0 ) { -#endif /*CAPZEROBYPASS*/ - if (vbs < here->MOS3tDepCap){ - arg=1-vbs/here->MOS3tBulkPot; - /* - * the following block looks somewhat long and messy, - * but since most users use the default grading - * coefficients of .5, and sqrt is MUCH faster than an - * exp(log()) we use this special case code to buy time. - * (as much as 10% of total job time!) - */ + /* + *.....done + */ + } + + + /* now deal with n vs p polarity */ + + here->MOS3von = model->MOS3type * von; + here->MOS3vdsat = model->MOS3type * vdsat; + /* line 490 */ + /* + * COMPUTE EQUIVALENT DRAIN CURRENT SOURCE + */ + here->MOS3cd=here->MOS3mode * cdrain - here->MOS3cbd; + + if (ckt->CKTmode & (MODETRAN | MODETRANOP | MODEINITSMSIG)) { + /* + * now we do the hard part of the bulk-drain and bulk-source + * diode - we evaluate the non-linear capacitance and + * charge + * + * the basic equations are not hard, but the implementation + * is somewhat long in an attempt to avoid log/exponential + * evaluations + */ + /* + * charge storage elements + * + *.. bulk-drain and bulk-source depletion capacitances + */ + { + /* can't bypass the diode capacitance calculations */ + if(here->MOS3Cbs != 0 || here->MOS3Cbssw != 0 ) { + if (vbs < here->MOS3tDepCap){ + arg=1-vbs/here->MOS3tBulkPot; + /* + * the following block looks somewhat long and messy, + * but since most users use the default grading + * coefficients of .5, and sqrt is MUCH faster than an + * exp(log()) we use this special case code to buy time. + * (as much as 10% of total job time!) + */ #ifndef NOSQRT - if(model->MOS3bulkJctBotGradingCoeff == - model->MOS3bulkJctSideGradingCoeff) { - if(model->MOS3bulkJctBotGradingCoeff == .5) { - sarg = sargsw = 1/sqrt(arg); - } else { - sarg = sargsw = - exp(-model->MOS3bulkJctBotGradingCoeff* - log(arg)); - } - } else { - if(model->MOS3bulkJctBotGradingCoeff == .5) { - sarg = 1/sqrt(arg); - } else { + if(model->MOS3bulkJctBotGradingCoeff == + model->MOS3bulkJctSideGradingCoeff) { + if(model->MOS3bulkJctBotGradingCoeff == .5) { + sarg = sargsw = 1/sqrt(arg); + } else { + sarg = sargsw = + exp(-model->MOS3bulkJctBotGradingCoeff* + log(arg)); + } + } else { + if(model->MOS3bulkJctBotGradingCoeff == .5) { + sarg = 1/sqrt(arg); + } else { #endif /*NOSQRT*/ - sarg = exp(-model->MOS3bulkJctBotGradingCoeff* - log(arg)); + sarg = exp(-model->MOS3bulkJctBotGradingCoeff* + log(arg)); #ifndef NOSQRT - } - if(model->MOS3bulkJctSideGradingCoeff == .5) { - sargsw = 1/sqrt(arg); - } else { + } + if(model->MOS3bulkJctSideGradingCoeff == .5) { + sargsw = 1/sqrt(arg); + } else { #endif /*NOSQRT*/ - sargsw =exp(-model->MOS3bulkJctSideGradingCoeff* - log(arg)); + sargsw =exp(-model->MOS3bulkJctSideGradingCoeff* + log(arg)); #ifndef NOSQRT - } - } + } + } #endif /*NOSQRT*/ - *(ckt->CKTstate0 + here->MOS3qbs) = - here->MOS3tBulkPot*(here->MOS3Cbs* - (1-arg*sarg)/(1-model->MOS3bulkJctBotGradingCoeff) - +here->MOS3Cbssw* - (1-arg*sargsw)/ - (1-model->MOS3bulkJctSideGradingCoeff)); - here->MOS3capbs=here->MOS3Cbs*sarg+ - here->MOS3Cbssw*sargsw; - } else { - *(ckt->CKTstate0 + here->MOS3qbs) = here->MOS3f4s + - vbs*(here->MOS3f2s+vbs*(here->MOS3f3s/2)); - here->MOS3capbs=here->MOS3f2s+here->MOS3f3s*vbs; - } -#ifdef CAPZEROBYPASS - } else { - *(ckt->CKTstate0 + here->MOS3qbs) = 0; - here->MOS3capbs=0; - } -#endif /*CAPZEROBYPASS*/ - } -#ifdef CAPBYPASS - if(((ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) || - fabs(delvbd) >= ckt->CKTreltol * MAX(fabs(vbd), - fabs(*(ckt->CKTstate0+here->MOS3vbd)))+ - ckt->CKTvoltTol)|| senflag ) -#endif /*CAPBYPASS*/ - /* can't bypass the diode capacitance calculations */ - { -#ifdef CAPZEROBYPASS - if(here->MOS3Cbd != 0 || here->MOS3Cbdsw != 0 ) { -#endif /*CAPZEROBYPASS*/ - if (vbd < here->MOS3tDepCap) { - arg=1-vbd/here->MOS3tBulkPot; - /* - * the following block looks somewhat long and messy, - * but since most users use the default grading - * coefficients of .5, and sqrt is MUCH faster than an - * exp(log()) we use this special case code to buy time. - * (as much as 10% of total job time!) - */ + *(ckt->CKTstate0 + here->MOS3qbs) = + here->MOS3tBulkPot*(here->MOS3Cbs* + (1-arg*sarg)/(1-model->MOS3bulkJctBotGradingCoeff) + +here->MOS3Cbssw* + (1-arg*sargsw)/ + (1-model->MOS3bulkJctSideGradingCoeff)); + here->MOS3capbs=here->MOS3Cbs*sarg+ + here->MOS3Cbssw*sargsw; + } else { + *(ckt->CKTstate0 + here->MOS3qbs) = here->MOS3f4s + + vbs*(here->MOS3f2s+vbs*(here->MOS3f3s/2)); + here->MOS3capbs=here->MOS3f2s+here->MOS3f3s*vbs; + } + } else { + *(ckt->CKTstate0 + here->MOS3qbs) = 0; + here->MOS3capbs=0; + } + } + /* can't bypass the diode capacitance calculations */ + { + if(here->MOS3Cbd != 0 || here->MOS3Cbdsw != 0 ) { + if (vbd < here->MOS3tDepCap) { + arg=1-vbd/here->MOS3tBulkPot; + /* + * the following block looks somewhat long and messy, + * but since most users use the default grading + * coefficients of .5, and sqrt is MUCH faster than an + * exp(log()) we use this special case code to buy time. + * (as much as 10% of total job time!) + */ #ifndef NOSQRT - if(model->MOS3bulkJctBotGradingCoeff == .5 && - model->MOS3bulkJctSideGradingCoeff == .5) { - sarg = sargsw = 1/sqrt(arg); - } else { - if(model->MOS3bulkJctBotGradingCoeff == .5) { - sarg = 1/sqrt(arg); - } else { + if(model->MOS3bulkJctBotGradingCoeff == .5 && + model->MOS3bulkJctSideGradingCoeff == .5) { + sarg = sargsw = 1/sqrt(arg); + } else { + if(model->MOS3bulkJctBotGradingCoeff == .5) { + sarg = 1/sqrt(arg); + } else { #endif /*NOSQRT*/ - sarg = exp(-model->MOS3bulkJctBotGradingCoeff* - log(arg)); + sarg = exp(-model->MOS3bulkJctBotGradingCoeff* + log(arg)); #ifndef NOSQRT - } - if(model->MOS3bulkJctSideGradingCoeff == .5) { - sargsw = 1/sqrt(arg); - } else { + } + if(model->MOS3bulkJctSideGradingCoeff == .5) { + sargsw = 1/sqrt(arg); + } else { #endif /*NOSQRT*/ - sargsw =exp(-model->MOS3bulkJctSideGradingCoeff* - log(arg)); + sargsw =exp(-model->MOS3bulkJctSideGradingCoeff* + log(arg)); #ifndef NOSQRT - } - } + } + } #endif /*NOSQRT*/ - *(ckt->CKTstate0 + here->MOS3qbd) = - here->MOS3tBulkPot*(here->MOS3Cbd* - (1-arg*sarg) - /(1-model->MOS3bulkJctBotGradingCoeff) - +here->MOS3Cbdsw* - (1-arg*sargsw) - /(1-model->MOS3bulkJctSideGradingCoeff)); - here->MOS3capbd=here->MOS3Cbd*sarg+ - here->MOS3Cbdsw*sargsw; - } else { - *(ckt->CKTstate0 + here->MOS3qbd) = here->MOS3f4d + - vbd * (here->MOS3f2d + vbd * here->MOS3f3d/2); - here->MOS3capbd=here->MOS3f2d + vbd * here->MOS3f3d; - } -#ifdef CAPZEROBYPASS - } else { - *(ckt->CKTstate0 + here->MOS3qbd) = 0; - here->MOS3capbd = 0; - } -#endif /*CAPZEROBYPASS*/ - } -#ifdef DETAILPROF -asm(" .globl mos3pth"); -asm("mos3pth:"); -#endif /* DETAILPROF */ - if(SenCond && (ckt->CKTsenInfo->SENmode==TRANSEN)) goto next2; - - if ( ckt->CKTmode & MODETRAN ) { - /* (above only excludes tranop, since we're only at this - * point if tran or tranop ) - */ - - /* - * calculate equivalent conductances and currents for - * depletion capacitors - */ - - /* integrate the capacitors and save results */ - - error = NIintegrate(ckt,&geq,&ceq,here->MOS3capbd, - here->MOS3qbd); - if(error) return(error); - here->MOS3gbd += geq; - here->MOS3cbd += *(ckt->CKTstate0 + here->MOS3cqbd); - here->MOS3cd -= *(ckt->CKTstate0 + here->MOS3cqbd); - error = NIintegrate(ckt,&geq,&ceq,here->MOS3capbs, - here->MOS3qbs); - if(error) return(error); - here->MOS3gbs += geq; - here->MOS3cbs += *(ckt->CKTstate0 + here->MOS3cqbs); - } - } -#ifdef DETAILPROF -asm(" .globl mos3pti"); -asm("mos3pti:"); -#endif /* DETAILPROF */ - if(SenCond) goto next2; - - /* - * check convergence - */ - if ( (here->MOS3off == 0) || - (!(ckt->CKTmode & (MODEINITFIX|MODEINITSMSIG))) ){ - if (Check == 1) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; -#ifndef NEWCONV - } else { - tol=ckt->CKTreltol*MAX(fabs(cdhat), - fabs(here->MOS3cd))+ckt->CKTabstol; - if (fabs(cdhat-here->MOS3cd) >= tol) { - ckt->CKTnoncon++; + *(ckt->CKTstate0 + here->MOS3qbd) = + here->MOS3tBulkPot*(here->MOS3Cbd* + (1-arg*sarg) + /(1-model->MOS3bulkJctBotGradingCoeff) + +here->MOS3Cbdsw* + (1-arg*sargsw) + /(1-model->MOS3bulkJctSideGradingCoeff)); + here->MOS3capbd=here->MOS3Cbd*sarg+ + here->MOS3Cbdsw*sargsw; + } else { + *(ckt->CKTstate0 + here->MOS3qbd) = here->MOS3f4d + + vbd * (here->MOS3f2d + vbd * here->MOS3f3d/2); + here->MOS3capbd=here->MOS3f2d + vbd * here->MOS3f3d; + } + } else { + *(ckt->CKTstate0 + here->MOS3qbd) = 0; + here->MOS3capbd = 0; + } + } + if(SenCond && (ckt->CKTsenInfo->SENmode==TRANSEN)) goto next2; + + if ( ckt->CKTmode & MODETRAN ) { + /* (above only excludes tranop, since we're only at this + * point if tran or tranop ) + */ + + /* + * calculate equivalent conductances and currents for + * depletion capacitors + */ + + /* integrate the capacitors and save results */ + + error = NIintegrate(ckt,&geq,&ceq,here->MOS3capbd, + here->MOS3qbd); + if(error) return(error); + here->MOS3gbd += geq; + here->MOS3cbd += *(ckt->CKTstate0 + here->MOS3cqbd); + here->MOS3cd -= *(ckt->CKTstate0 + here->MOS3cqbd); + error = NIintegrate(ckt,&geq,&ceq,here->MOS3capbs, + here->MOS3qbs); + if(error) return(error); + here->MOS3gbs += geq; + here->MOS3cbs += *(ckt->CKTstate0 + here->MOS3cqbs); + } + } + if(SenCond) goto next2; + + /* + * check convergence + */ + if ( (here->MOS3off == 0) || + (!(ckt->CKTmode & (MODEINITFIX|MODEINITSMSIG))) ){ + if (Check == 1) { + ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) here; - } else { - tol=ckt->CKTreltol*MAX(fabs(cbhat), - fabs(here->MOS3cbs+here->MOS3cbd))+ - ckt->CKTabstol; - if (fabs(cbhat-(here->MOS3cbs+here->MOS3cbd)) > tol) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; - } - } -#endif /* NEWCONV */ - } - } - -#ifdef DETAILPROF -asm(" .globl mos3ptj"); -asm("mos3ptj:"); -#endif /* DETAILPROF */ - - /* save things away for next time */ - -next2: *(ckt->CKTstate0 + here->MOS3vbs) = vbs; - *(ckt->CKTstate0 + here->MOS3vbd) = vbd; - *(ckt->CKTstate0 + here->MOS3vgs) = vgs; - *(ckt->CKTstate0 + here->MOS3vds) = vds; - -#ifdef DETAILPROF -asm(" .globl mos3ptk"); -asm("mos3ptk:"); -#endif /* DETAILPROF */ - - /* - * meyer's capacitor model - */ - if ( ckt->CKTmode & (MODETRAN | MODETRANOP | MODEINITSMSIG) ) { - /* - * calculate meyer's capacitors - */ - /* - * new cmeyer - this just evaluates at the current time, - * expects you to remember values from previous time - * returns 1/2 of non-constant portion of capacitance - * you must add in the other half from previous time - * and the constant part - */ - if (here->MOS3mode > 0){ - DEVqmeyer (vgs,vgd,vgb,von,vdsat, - (ckt->CKTstate0 + here->MOS3capgs), - (ckt->CKTstate0 + here->MOS3capgd), - (ckt->CKTstate0 + here->MOS3capgb), - here->MOS3tPhi,OxideCap); - } else { - DEVqmeyer (vgd,vgs,vgb,von,vdsat, - (ckt->CKTstate0 + here->MOS3capgd), - (ckt->CKTstate0 + here->MOS3capgs), - (ckt->CKTstate0 + here->MOS3capgb), - here->MOS3tPhi,OxideCap); - } - vgs1 = *(ckt->CKTstate1 + here->MOS3vgs); - vgd1 = vgs1 - *(ckt->CKTstate1 + here->MOS3vds); - vgb1 = vgs1 - *(ckt->CKTstate1 + here->MOS3vbs); - if(ckt->CKTmode & MODETRANOP) { - capgs = 2 * *(ckt->CKTstate0+here->MOS3capgs)+ - GateSourceOverlapCap ; - capgd = 2 * *(ckt->CKTstate0+here->MOS3capgd)+ - GateDrainOverlapCap ; - capgb = 2 * *(ckt->CKTstate0+here->MOS3capgb)+ - GateBulkOverlapCap ; - } else { - capgs = ( *(ckt->CKTstate0+here->MOS3capgs)+ - *(ckt->CKTstate1+here->MOS3capgs) + - GateSourceOverlapCap ); - capgd = ( *(ckt->CKTstate0+here->MOS3capgd)+ - *(ckt->CKTstate1+here->MOS3capgd) + - GateDrainOverlapCap ); - capgb = ( *(ckt->CKTstate0+here->MOS3capgb)+ - *(ckt->CKTstate1+here->MOS3capgb) + - GateBulkOverlapCap ); - } - if(ckt->CKTsenInfo){ - here->MOS3cgs = capgs; - here->MOS3cgd = capgd; - here->MOS3cgb = capgb; - } - -#ifdef DETAILPROF -asm(" .globl mos3ptl"); -asm("mos3ptl:"); -#endif /* DETAILPROF */ - /* - * store small-signal parameters (for meyer's model) - * all parameters already stored, so done... - */ - - - if(SenCond){ - if(ckt->CKTsenInfo->SENmode & (DCSEN|ACSEN)) { - continue; - } - } + } + } + + + /* save things away for next time */ + + next2: *(ckt->CKTstate0 + here->MOS3vbs) = vbs; + *(ckt->CKTstate0 + here->MOS3vbd) = vbd; + *(ckt->CKTstate0 + here->MOS3vgs) = vgs; + *(ckt->CKTstate0 + here->MOS3vds) = vds; + + + /* + * meyer's capacitor model + */ + if ( ckt->CKTmode & (MODETRAN | MODETRANOP | MODEINITSMSIG) ) { + /* + * calculate meyer's capacitors + */ + /* + * new cmeyer - this just evaluates at the current time, + * expects you to remember values from previous time + * returns 1/2 of non-constant portion of capacitance + * you must add in the other half from previous time + * and the constant part + */ + if (here->MOS3mode > 0){ + DEVqmeyer (vgs,vgd,vgb,von,vdsat, + (ckt->CKTstate0 + here->MOS3capgs), + (ckt->CKTstate0 + here->MOS3capgd), + (ckt->CKTstate0 + here->MOS3capgb), + here->MOS3tPhi,OxideCap); + } else { + DEVqmeyer (vgd,vgs,vgb,von,vdsat, + (ckt->CKTstate0 + here->MOS3capgd), + (ckt->CKTstate0 + here->MOS3capgs), + (ckt->CKTstate0 + here->MOS3capgb), + here->MOS3tPhi,OxideCap); + } + vgs1 = *(ckt->CKTstate1 + here->MOS3vgs); + vgd1 = vgs1 - *(ckt->CKTstate1 + here->MOS3vds); + vgb1 = vgs1 - *(ckt->CKTstate1 + here->MOS3vbs); + if(ckt->CKTmode & MODETRANOP) { + capgs = 2 * *(ckt->CKTstate0+here->MOS3capgs)+ + GateSourceOverlapCap ; + capgd = 2 * *(ckt->CKTstate0+here->MOS3capgd)+ + GateDrainOverlapCap ; + capgb = 2 * *(ckt->CKTstate0+here->MOS3capgb)+ + GateBulkOverlapCap ; + } else { + capgs = ( *(ckt->CKTstate0+here->MOS3capgs)+ + *(ckt->CKTstate1+here->MOS3capgs) + + GateSourceOverlapCap ); + capgd = ( *(ckt->CKTstate0+here->MOS3capgd)+ + *(ckt->CKTstate1+here->MOS3capgd) + + GateDrainOverlapCap ); + capgb = ( *(ckt->CKTstate0+here->MOS3capgb)+ + *(ckt->CKTstate1+here->MOS3capgb) + + GateBulkOverlapCap ); + } + if(ckt->CKTsenInfo){ + here->MOS3cgs = capgs; + here->MOS3cgd = capgd; + here->MOS3cgb = capgb; + } + + /* + * store small-signal parameters (for meyer's model) + * all parameters already stored, so done... + */ + + + if(SenCond){ + if(ckt->CKTsenInfo->SENmode & (DCSEN|ACSEN)) { + continue; + } + } #ifndef PREDICTOR - if (ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) { - *(ckt->CKTstate0 + here->MOS3qgs) = - (1+xfact) * *(ckt->CKTstate1 + here->MOS3qgs) - - xfact * *(ckt->CKTstate2 + here->MOS3qgs); - *(ckt->CKTstate0 + here->MOS3qgd) = - (1+xfact) * *(ckt->CKTstate1 + here->MOS3qgd) - - xfact * *(ckt->CKTstate2 + here->MOS3qgd); - *(ckt->CKTstate0 + here->MOS3qgb) = - (1+xfact) * *(ckt->CKTstate1 + here->MOS3qgb) - - xfact * *(ckt->CKTstate2 + here->MOS3qgb); - } else { + if (ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) { + *(ckt->CKTstate0 + here->MOS3qgs) = + (1+xfact) * *(ckt->CKTstate1 + here->MOS3qgs) + - xfact * *(ckt->CKTstate2 + here->MOS3qgs); + *(ckt->CKTstate0 + here->MOS3qgd) = + (1+xfact) * *(ckt->CKTstate1 + here->MOS3qgd) + - xfact * *(ckt->CKTstate2 + here->MOS3qgd); + *(ckt->CKTstate0 + here->MOS3qgb) = + (1+xfact) * *(ckt->CKTstate1 + here->MOS3qgb) + - xfact * *(ckt->CKTstate2 + here->MOS3qgb); + } else { #endif /*PREDICTOR*/ - if(ckt->CKTmode & MODETRAN) { - *(ckt->CKTstate0 + here->MOS3qgs) = (vgs-vgs1)*capgs + - *(ckt->CKTstate1 + here->MOS3qgs) ; - *(ckt->CKTstate0 + here->MOS3qgd) = (vgd-vgd1)*capgd + - *(ckt->CKTstate1 + here->MOS3qgd) ; - *(ckt->CKTstate0 + here->MOS3qgb) = (vgb-vgb1)*capgb + - *(ckt->CKTstate1 + here->MOS3qgb) ; - } else { - /* TRANOP only */ - *(ckt->CKTstate0 + here->MOS3qgs) = vgs*capgs; - *(ckt->CKTstate0 + here->MOS3qgd) = vgd*capgd; - *(ckt->CKTstate0 + here->MOS3qgb) = vgb*capgb; - } + if(ckt->CKTmode & MODETRAN) { + *(ckt->CKTstate0 + here->MOS3qgs) = (vgs-vgs1)*capgs + + *(ckt->CKTstate1 + here->MOS3qgs) ; + *(ckt->CKTstate0 + here->MOS3qgd) = (vgd-vgd1)*capgd + + *(ckt->CKTstate1 + here->MOS3qgd) ; + *(ckt->CKTstate0 + here->MOS3qgb) = (vgb-vgb1)*capgb + + *(ckt->CKTstate1 + here->MOS3qgb) ; + } else { + /* TRANOP only */ + *(ckt->CKTstate0 + here->MOS3qgs) = vgs*capgs; + *(ckt->CKTstate0 + here->MOS3qgd) = vgd*capgd; + *(ckt->CKTstate0 + here->MOS3qgb) = vgb*capgb; + } #ifndef PREDICTOR - } + } #endif /*PREDICTOR*/ - } -bypass: - if(SenCond) continue; -#ifdef DETAILPROF -asm(" .globl mos3ptm"); -asm("mos3ptm:"); -#endif /* DETAILPROF */ - - if ( (ckt->CKTmode & (MODEINITTRAN)) || - (! (ckt->CKTmode & (MODETRAN)) ) ) { - /* - * initialize to zero charge conductances - * and current - */ - gcgs=0; - ceqgs=0; - gcgd=0; - ceqgd=0; - gcgb=0; - ceqgb=0; - } else { - if(capgs == 0) *(ckt->CKTstate0 + here->MOS3cqgs) =0; - if(capgd == 0) *(ckt->CKTstate0 + here->MOS3cqgd) =0; - if(capgb == 0) *(ckt->CKTstate0 + here->MOS3cqgb) =0; - /* - * calculate equivalent conductances and currents for - * meyer"s capacitors - */ - error = NIintegrate(ckt,&gcgs,&ceqgs,capgs,here->MOS3qgs); - if(error) return(error); - error = NIintegrate(ckt,&gcgd,&ceqgd,capgd,here->MOS3qgd); - if(error) return(error); - error = NIintegrate(ckt,&gcgb,&ceqgb,capgb,here->MOS3qgb); - if(error) return(error); - ceqgs=ceqgs-gcgs*vgs+ckt->CKTag[0]* - *(ckt->CKTstate0 + here->MOS3qgs); - ceqgd=ceqgd-gcgd*vgd+ckt->CKTag[0]* - *(ckt->CKTstate0 + here->MOS3qgd); - ceqgb=ceqgb-gcgb*vgb+ckt->CKTag[0]* - *(ckt->CKTstate0 + here->MOS3qgb); - } - /* - * store charge storage info for meyer's cap in lx table - */ - -#ifdef DETAILPROF -asm(" .globl mos3ptn"); -asm("mos3ptn:"); -#endif /* DETAILPROF */ - /* - * load current vector - */ - ceqbs = model->MOS3type * - (here->MOS3cbs-(here->MOS3gbs-ckt->CKTgmin)*vbs); - ceqbd = model->MOS3type * - (here->MOS3cbd-(here->MOS3gbd-ckt->CKTgmin)*vbd); - if (here->MOS3mode >= 0) { - xnrm=1; - xrev=0; - cdreq=model->MOS3type*(cdrain-here->MOS3gds*vds- - here->MOS3gm*vgs-here->MOS3gmbs*vbs); - } else { - xnrm=0; - xrev=1; - cdreq = -(model->MOS3type)*(cdrain-here->MOS3gds*(-vds)- - here->MOS3gm*vgd-here->MOS3gmbs*vbd); - } - *(ckt->CKTrhs + here->MOS3gNode) -= - (model->MOS3type * (ceqgs + ceqgb + ceqgd)); - *(ckt->CKTrhs + here->MOS3bNode) -= - (ceqbs + ceqbd - model->MOS3type * ceqgb); - *(ckt->CKTrhs + here->MOS3dNodePrime) += - (ceqbd - cdreq + model->MOS3type * ceqgd); - *(ckt->CKTrhs + here->MOS3sNodePrime) += - cdreq + ceqbs + model->MOS3type * ceqgs; - /* - * load y matrix - */ -/*printf(" loading %s at time %g\n",here->MOS3name,ckt->CKTtime);*/ -/*printf("%g %g %g %g %g\n", here->MOS3drainConductance,gcgd+gcgs+gcgb, - here->MOS3sourceConductance,here->MOS3gbd,here->MOS3gbs);*/ -/*printf("%g %g %g %g %g\n",-gcgb,0.0,0.0,here->MOS3gds,here->MOS3gm);*/ -/*printf("%g %g %g %g %g\n", here->MOS3gds,here->MOS3gmbs,gcgd,-gcgs,-gcgd);*/ -/*printf("%g %g %g %g %g\n", -gcgs,-gcgd,0.0,-gcgs,0.0);*/ - - *(here->MOS3DdPtr) += (here->MOS3drainConductance); - *(here->MOS3GgPtr) += ((gcgd+gcgs+gcgb)); - *(here->MOS3SsPtr) += (here->MOS3sourceConductance); - *(here->MOS3BbPtr) += (here->MOS3gbd+here->MOS3gbs+gcgb); - *(here->MOS3DPdpPtr) += - (here->MOS3drainConductance+here->MOS3gds+ - here->MOS3gbd+xrev*(here->MOS3gm+here->MOS3gmbs)+gcgd); - *(here->MOS3SPspPtr) += - (here->MOS3sourceConductance+here->MOS3gds+ - here->MOS3gbs+xnrm*(here->MOS3gm+here->MOS3gmbs)+gcgs); - *(here->MOS3DdpPtr) += (-here->MOS3drainConductance); - *(here->MOS3GbPtr) -= gcgb; - *(here->MOS3GdpPtr) -= gcgd; - *(here->MOS3GspPtr) -= gcgs; - *(here->MOS3SspPtr) += (-here->MOS3sourceConductance); - *(here->MOS3BgPtr) -= gcgb; - *(here->MOS3BdpPtr) -= here->MOS3gbd; - *(here->MOS3BspPtr) -= here->MOS3gbs; - *(here->MOS3DPdPtr) += (-here->MOS3drainConductance); - *(here->MOS3DPgPtr) += ((xnrm-xrev)*here->MOS3gm-gcgd); - *(here->MOS3DPbPtr) += (-here->MOS3gbd+(xnrm-xrev)*here->MOS3gmbs); - *(here->MOS3DPspPtr) += (-here->MOS3gds- - xnrm*(here->MOS3gm+here->MOS3gmbs)); - *(here->MOS3SPgPtr) += (-(xnrm-xrev)*here->MOS3gm-gcgs); - *(here->MOS3SPsPtr) += (-here->MOS3sourceConductance); - *(here->MOS3SPbPtr) += (-here->MOS3gbs-(xnrm-xrev)*here->MOS3gmbs); - *(here->MOS3SPdpPtr) += (-here->MOS3gds- - xrev*(here->MOS3gm+here->MOS3gmbs)); - } + } + bypass: + if(SenCond) continue; + + if ( (ckt->CKTmode & (MODEINITTRAN)) || + (! (ckt->CKTmode & (MODETRAN)) ) ) { + /* + * initialize to zero charge conductances + * and current + */ + gcgs=0; + ceqgs=0; + gcgd=0; + ceqgd=0; + gcgb=0; + ceqgb=0; + } else { + if(capgs == 0) *(ckt->CKTstate0 + here->MOS3cqgs) =0; + if(capgd == 0) *(ckt->CKTstate0 + here->MOS3cqgd) =0; + if(capgb == 0) *(ckt->CKTstate0 + here->MOS3cqgb) =0; + /* + * calculate equivalent conductances and currents for + * meyer"s capacitors + */ + error = NIintegrate(ckt,&gcgs,&ceqgs,capgs,here->MOS3qgs); + if(error) return(error); + error = NIintegrate(ckt,&gcgd,&ceqgd,capgd,here->MOS3qgd); + if(error) return(error); + error = NIintegrate(ckt,&gcgb,&ceqgb,capgb,here->MOS3qgb); + if(error) return(error); + ceqgs=ceqgs-gcgs*vgs+ckt->CKTag[0]* + *(ckt->CKTstate0 + here->MOS3qgs); + ceqgd=ceqgd-gcgd*vgd+ckt->CKTag[0]* + *(ckt->CKTstate0 + here->MOS3qgd); + ceqgb=ceqgb-gcgb*vgb+ckt->CKTag[0]* + *(ckt->CKTstate0 + here->MOS3qgb); + } + /* + * store charge storage info for meyer's cap in lx table + */ + + /* + * load current vector + */ + ceqbs = model->MOS3type * + (here->MOS3cbs-(here->MOS3gbs)*vbs); + ceqbd = model->MOS3type * + (here->MOS3cbd-(here->MOS3gbd)*vbd); + if (here->MOS3mode >= 0) { + xnrm=1; + xrev=0; + cdreq=model->MOS3type*(cdrain-here->MOS3gds*vds- + here->MOS3gm*vgs-here->MOS3gmbs*vbs); + } else { + xnrm=0; + xrev=1; + cdreq = -(model->MOS3type)*(cdrain-here->MOS3gds*(-vds)- + here->MOS3gm*vgd-here->MOS3gmbs*vbd); + } + *(ckt->CKTrhs + here->MOS3gNode) -= + (model->MOS3type * (ceqgs + ceqgb + ceqgd)); + *(ckt->CKTrhs + here->MOS3bNode) -= + (ceqbs + ceqbd - model->MOS3type * ceqgb); + *(ckt->CKTrhs + here->MOS3dNodePrime) += + (ceqbd - cdreq + model->MOS3type * ceqgd); + *(ckt->CKTrhs + here->MOS3sNodePrime) += + cdreq + ceqbs + model->MOS3type * ceqgs; + /* + * load y matrix + */ + *(here->MOS3DdPtr) += (here->MOS3drainConductance); + *(here->MOS3GgPtr) += ((gcgd+gcgs+gcgb)); + *(here->MOS3SsPtr) += (here->MOS3sourceConductance); + *(here->MOS3BbPtr) += (here->MOS3gbd+here->MOS3gbs+gcgb); + *(here->MOS3DPdpPtr) += + (here->MOS3drainConductance+here->MOS3gds+ + here->MOS3gbd+xrev*(here->MOS3gm+here->MOS3gmbs)+gcgd); + *(here->MOS3SPspPtr) += + (here->MOS3sourceConductance+here->MOS3gds+ + here->MOS3gbs+xnrm*(here->MOS3gm+here->MOS3gmbs)+gcgs); + *(here->MOS3DdpPtr) += (-here->MOS3drainConductance); + *(here->MOS3GbPtr) -= gcgb; + *(here->MOS3GdpPtr) -= gcgd; + *(here->MOS3GspPtr) -= gcgs; + *(here->MOS3SspPtr) += (-here->MOS3sourceConductance); + *(here->MOS3BgPtr) -= gcgb; + *(here->MOS3BdpPtr) -= here->MOS3gbd; + *(here->MOS3BspPtr) -= here->MOS3gbs; + *(here->MOS3DPdPtr) += (-here->MOS3drainConductance); + *(here->MOS3DPgPtr) += ((xnrm-xrev)*here->MOS3gm-gcgd); + *(here->MOS3DPbPtr) += (-here->MOS3gbd+(xnrm-xrev)*here->MOS3gmbs); + *(here->MOS3DPspPtr) += (-here->MOS3gds- + xnrm*(here->MOS3gm+here->MOS3gmbs)); + *(here->MOS3SPgPtr) += (-(xnrm-xrev)*here->MOS3gm-gcgs); + *(here->MOS3SPsPtr) += (-here->MOS3sourceConductance); + *(here->MOS3SPbPtr) += (-here->MOS3gbs-(xnrm-xrev)*here->MOS3gmbs); + *(here->MOS3SPdpPtr) += (-here->MOS3gds- + xrev*(here->MOS3gm+here->MOS3gmbs)); + } } return(OK); } + diff --git a/src/spicelib/devices/mos3/mos3mask.c b/src/spicelib/devices/mos3/mos3mask.c index f316110a1..ec9584929 100644 --- a/src/spicelib/devices/mos3/mos3mask.c +++ b/src/spicelib/devices/mos3/mos3mask.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1987 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* */ @@ -89,6 +90,18 @@ MOS3mAsk(ckt,inst,which,value) case MOS3_MOD_LD: value->rValue = here->MOS3latDiff; return(OK); + case MOS3_MOD_XL: + value->rValue = here->MOS3lengthAdjust; + return(OK); + case MOS3_MOD_WD: + value->rValue = here->MOS3widthNarrow; + return(OK); + case MOS3_MOD_XW: + value->rValue = here->MOS3widthAdjust; + return(OK); + case MOS3_MOD_DELVTO: + value->rValue = here->MOS3delvt0; + return(OK); case MOS3_MOD_RSH: value->rValue = here->MOS3sheetResistance; return(OK); @@ -136,7 +149,13 @@ MOS3mAsk(ckt,inst,which,value) return(OK); case MOS3_MOD_KAPPA: value->rValue = here->MOS3kappa; + return(OK); + case MOS3_MOD_KF: + value->rValue = here->MOS3fNcoef; return(OK); + case MOS3_MOD_AF: + value->rValue = here->MOS3fNexp; + return(OK); case MOS3_MOD_TYPE: if (here->MOS3type > 0) value->sValue = "nmos"; diff --git a/src/spicelib/devices/mos3/mos3mpar.c b/src/spicelib/devices/mos3/mos3mpar.c index 4d47f2d7b..8176d1108 100644 --- a/src/spicelib/devices/mos3/mos3mpar.c +++ b/src/spicelib/devices/mos3/mos3mpar.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* */ @@ -20,7 +21,7 @@ MOS3mParam(param,value,inModel) IFvalue *value; GENmodel *inModel; { - register MOS3model *model = (MOS3model *)inModel; + MOS3model *model = (MOS3model *)inModel; switch(param) { case MOS3_MOD_VTO: model->MOS3vt0 = value->rValue; @@ -106,6 +107,22 @@ MOS3mParam(param,value,inModel) model->MOS3latDiff = value->rValue; model->MOS3latDiffGiven = TRUE; break; + case MOS3_MOD_XL: + model->MOS3lengthAdjust = value->rValue; + model->MOS3lengthAdjustGiven = TRUE; + break; + case MOS3_MOD_WD: + model->MOS3widthNarrow = value->rValue; + model->MOS3widthNarrowGiven = TRUE; + break; + case MOS3_MOD_XW: + model->MOS3widthAdjust = value->rValue; + model->MOS3widthAdjustGiven = TRUE; + break; + case MOS3_MOD_DELVTO: + model->MOS3delvt0 = value->rValue; + model->MOS3delvt0Given = TRUE; + break; case MOS3_MOD_U0: model->MOS3surfaceMobility = value->rValue; model->MOS3surfaceMobilityGiven = TRUE; diff --git a/src/spicelib/devices/mos3/mos3noi.c b/src/spicelib/devices/mos3/mos3noi.c index 228a443e0..e8704efa8 100644 --- a/src/spicelib/devices/mos3/mos3noi.c +++ b/src/spicelib/devices/mos3/mos3noi.c @@ -1,13 +1,13 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1987 Gary W. Ng +Modified: 2000 AlansFixes **********/ #include "ngspice.h" #include #include "mos3defs.h" #include "cktdefs.h" -#include "fteconst.h" #include "iferrmsg.h" #include "noisedef.h" #include "suffix.h" @@ -30,12 +30,12 @@ MOS3noise (mode, operation, genmodel, ckt, data, OnDens) int operation; GENmodel *genmodel; CKTcircuit *ckt; - register Ndata *data; + Ndata *data; double *OnDens; { MOS3model *firstModel = (MOS3model *) genmodel; - register MOS3model *model; - register MOS3instance *inst; + MOS3model *model; + MOS3instance *inst; char name[N_MXVLNTH]; double tempOnoise; double tempInoise; @@ -136,7 +136,8 @@ if (!data->namelist) return(E_NOMEM); noizDens[MOS3FLNOIZ] *= model->MOS3fNcoef * exp(model->MOS3fNexp * log(MAX(fabs(inst->MOS3cd),N_MINLOG))) / - (data->freq * inst->MOS3w * + (data->freq * + (inst->MOS3w - 2*model->MOS3widthNarrow) * (inst->MOS3l - 2*model->MOS3latDiff) * model->MOS3oxideCapFactor * model->MOS3oxideCapFactor); lnNdens[MOS3FLNOIZ] = diff --git a/src/spicelib/devices/mos3/mos3par.c b/src/spicelib/devices/mos3/mos3par.c index 7723975f4..b2f2ddf76 100644 --- a/src/spicelib/devices/mos3/mos3par.c +++ b/src/spicelib/devices/mos3/mos3par.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* */ @@ -24,6 +25,11 @@ MOS3param(param,value,inst,select) { MOS3instance *here = (MOS3instance *)inst; switch(param) { + + case MOS3_M: + here->MOS3m = value->rValue; + here->MOS3mGiven = TRUE; + break; case MOS3_W: here->MOS3w = value->rValue; here->MOS3wGiven = TRUE; diff --git a/src/spicelib/devices/mos3/mos3pzld.c b/src/spicelib/devices/mos3/mos3pzld.c index c8ba529da..7a1f886f6 100644 --- a/src/spicelib/devices/mos3/mos3pzld.c +++ b/src/spicelib/devices/mos3/mos3pzld.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* */ @@ -17,11 +18,11 @@ Author: 1985 Thomas L. Quarles int MOS3pzLoad(inModel,ckt,s) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; SPcomplex *s; { - register MOS3model *model = (MOS3model *)inModel; - register MOS3instance *here; + MOS3model *model = (MOS3model *)inModel; + MOS3instance *here; int xnrm; int xrev; double xgs; @@ -36,6 +37,7 @@ MOS3pzLoad(inModel,ckt,s) double GateDrainOverlapCap; double GateSourceOverlapCap; double EffectiveLength; + double EffectiveWidth; for( ; model != NULL; model = model->MOS3nextModel) { for(here = model->MOS3instances; here!= NULL; @@ -52,13 +54,16 @@ MOS3pzLoad(inModel,ckt,s) /* * meyer's model parameters */ - EffectiveLength=here->MOS3l - 2*model->MOS3latDiff; + EffectiveWidth=here->MOS3w-2*model->MOS3widthNarrow+ + model->MOS3widthAdjust; + EffectiveLength=here->MOS3l - 2*model->MOS3latDiff+ + model->MOS3lengthAdjust; GateSourceOverlapCap = model->MOS3gateSourceOverlapCapFactor * - here->MOS3w; + here->MOS3m * EffectiveWidth; GateDrainOverlapCap = model->MOS3gateDrainOverlapCapFactor * - here->MOS3w; + here->MOS3m * EffectiveWidth; GateBulkOverlapCap = model->MOS3gateBulkOverlapCapFactor * - EffectiveLength; + here->MOS3m * EffectiveLength; capgs = ( 2* *(ckt->CKTstate0+here->MOS3capgs)+ GateSourceOverlapCap ); capgd = ( 2* *(ckt->CKTstate0+here->MOS3capgd)+ diff --git a/src/spicelib/devices/mos3/mos3sacl.c b/src/spicelib/devices/mos3/mos3sacl.c index 5591afa36..7d8aa9875 100644 --- a/src/spicelib/devices/mos3/mos3sacl.c +++ b/src/spicelib/devices/mos3/mos3sacl.c @@ -19,10 +19,10 @@ Author: 1985 Thomas L. Quarles int MOS3sAcLoad(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { - register MOS3model *model = (MOS3model *)inModel; - register MOS3instance *here; + MOS3model *model = (MOS3model *)inModel; + MOS3instance *here; int xnrm; int xrev; double A0; diff --git a/src/spicelib/devices/mos3/mos3set.c b/src/spicelib/devices/mos3/mos3set.c index 4114cf0dd..e2b5f9ed7 100644 --- a/src/spicelib/devices/mos3/mos3set.c +++ b/src/spicelib/devices/mos3/mos3set.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. -Author: 1985 Thomas L. Quarles +Author: 1985 Thomas L. Quarlesù +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -17,17 +18,17 @@ Author: 1985 Thomas L. Quarles int MOS3setup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int *states; /* load the MOS3 device structure with those pointers needed later * for fast matrix loading */ { - register MOS3model *model = (MOS3model *)inModel; - register MOS3instance *here; + MOS3model *model = (MOS3model *)inModel; + MOS3instance *here; int error; CKTnode *tmp; @@ -41,6 +42,18 @@ MOS3setup(matrix,inModel,ckt,states) if(!model->MOS3latDiffGiven) { model->MOS3latDiff = 0; } + if(!model->MOS3lengthAdjustGiven) { + model->MOS3lengthAdjust = 0; + } + if(!model->MOS3widthNarrowGiven) { + model->MOS3widthNarrow = 0; + } + if(!model->MOS3widthAdjustGiven) { + model->MOS3widthAdjust = 0; + } + if(!model->MOS3delvt0Given) { + model->MOS3delvt0 = 0; + } if(!model->MOS3jctSatCurDensityGiven) { model->MOS3jctSatCurDensity = 0; } @@ -136,6 +149,9 @@ MOS3setup(matrix,inModel,ckt,states) for (here = model->MOS3instances; here != NULL ; here=here->MOS3nextInstance) { + CKTnode *tmpNode; + IFuid tmpName; + if (here->MOS3owner == ARCHme) { /* allocate a chunk of the state vector */ here->MOS3states = *states; @@ -183,6 +199,14 @@ MOS3setup(matrix,inModel,ckt,states) error = CKTmkVolt(ckt,&tmp,here->MOS3name,"internal#drain"); if(error) return(error); here->MOS3dNodePrime = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } } else { here->MOS3dNodePrime = here->MOS3dNode; } @@ -194,6 +218,14 @@ MOS3setup(matrix,inModel,ckt,states) error = CKTmkVolt(ckt,&tmp,here->MOS3name,"internal#source"); if(error) return(error); here->MOS3sNodePrime = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } } else { here->MOS3sNodePrime = here->MOS3sNode; } @@ -237,7 +269,6 @@ MOS3unsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM MOS3model *model; MOS3instance *here; @@ -261,6 +292,5 @@ MOS3unsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/mos3/mos3sld.c b/src/spicelib/devices/mos3/mos3sld.c index ab795d0ac..26edd8198 100644 --- a/src/spicelib/devices/mos3/mos3sld.c +++ b/src/spicelib/devices/mos3/mos3sld.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* actually load the current sensitivity @@ -20,8 +21,8 @@ MOS3sLoad(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { - register MOS3model *model = (MOS3model *)inModel; - register MOS3instance *here; + MOS3model *model = (MOS3model *)inModel; + MOS3instance *here; double SaveState[44]; int save_mode; int i; @@ -76,6 +77,7 @@ CKTcircuit *ckt; double sargsw; int offset; double EffectiveLength; + double EffectiveWidth; SENstruct *info; #ifdef SENSDEBUG @@ -315,8 +317,8 @@ CKTcircuit *ckt; DcsprmDp = ( - DcbsDp - DcdDp - DcbdDp - DcsprDp); if(flag == 0){ - EffectiveLength = here->MOS3l - - 2*model->MOS3latDiff; + EffectiveLength = here->MOS3l + - 2*model->MOS3latDiff + model->MOS3lengthAdjust; if(EffectiveLength == 0){ DqgsDp = 0; DqgdDp = 0; @@ -329,9 +331,11 @@ CKTcircuit *ckt; } } else{ - DqgsDp = model->MOS3type * qgs0 / here->MOS3w; - DqgdDp = model->MOS3type * qgd0 / here->MOS3w; - DqgbDp = model->MOS3type * qgb0 / here->MOS3w; + EffectiveWidth = here->MOS3w + - 2*model->MOS3widthNarrow + model->MOS3widthAdjust; + DqgsDp = model->MOS3type * qgs0 / EffectiveWidth; + DqgdDp = model->MOS3type * qgd0 / EffectiveWidth; + DqgbDp = model->MOS3type * qgb0 / EffectiveWidth; } diff --git a/src/spicelib/devices/mos3/mos3sprt.c b/src/spicelib/devices/mos3/mos3sprt.c index a504d0b6a..20e133666 100644 --- a/src/spicelib/devices/mos3/mos3sprt.c +++ b/src/spicelib/devices/mos3/mos3sprt.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* Pretty print the sensitivity info for all the MOS3 @@ -18,12 +19,12 @@ Author: 1985 Thomas L. Quarles void MOS3sPrint(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register MOS3model *model = (MOS3model *)inModel; - register MOS3instance *here; + MOS3model *model = (MOS3model *)inModel; + MOS3instance *here; - printf("LEVEL 1 MOSFETS-----------------\n"); + printf("LEVEL 3 MOSFETS-----------------\n"); /* loop through all the MOS3 models */ for( ; model != NULL; model = model->MOS3nextModel ) { @@ -39,6 +40,8 @@ MOS3sPrint(inModel,ckt) CKTnodName(ckt,here->MOS3dNode),CKTnodName(ckt,here->MOS3gNode), CKTnodName(ckt,here->MOS3sNode)); + printf(" Multiplier: %g ",here->MOS3m); + printf(here->MOS3mGiven ? "(specified)\n" : "(default)\n"); printf(" Length: %g ",here->MOS3l); printf(here->MOS3lGiven ? "(specified)\n" : "(default)\n"); printf(" Width: %g ",here->MOS3w); diff --git a/src/spicelib/devices/mos3/mos3sset.c b/src/spicelib/devices/mos3/mos3sset.c index 876691003..6cdb427f8 100644 --- a/src/spicelib/devices/mos3/mos3sset.c +++ b/src/spicelib/devices/mos3/mos3sset.c @@ -17,11 +17,11 @@ Author: 1985 Thomas L. Quarles int MOS3sSetup(info,inModel) - register SENstruct *info; + SENstruct *info; GENmodel *inModel; { - register MOS3model *model = (MOS3model *)inModel; - register MOS3instance *here; + MOS3model *model = (MOS3model *)inModel; + MOS3instance *here; /* loop through all the models */ for( ; model != NULL; model = model->MOS3nextModel ) { diff --git a/src/spicelib/devices/mos3/mos3supd.c b/src/spicelib/devices/mos3/mos3supd.c index 20d9dcb5e..ff4052608 100644 --- a/src/spicelib/devices/mos3/mos3supd.c +++ b/src/spicelib/devices/mos3/mos3supd.c @@ -14,10 +14,10 @@ Author: 1985 Thomas L. Quarles int MOS3sUpdate(inModel,ckt) GENmodel *inModel; -register CKTcircuit *ckt; +CKTcircuit *ckt; { - register MOS3model *model = (MOS3model *)inModel; - register MOS3instance *here; + MOS3model *model = (MOS3model *)inModel; + MOS3instance *here; int iparmno; double sb; double sg; diff --git a/src/spicelib/devices/mos3/mos3temp.c b/src/spicelib/devices/mos3/mos3temp.c index 52f4b0997..6ceec8b4e 100644 --- a/src/spicelib/devices/mos3/mos3temp.c +++ b/src/spicelib/devices/mos3/mos3temp.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -17,10 +18,10 @@ Author: 1985 Thomas L. Quarles int MOS3temp(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register MOS3model *model = (MOS3model *)inModel; - register MOS3instance *here; + MOS3model *model = (MOS3model *)inModel; + MOS3instance *here; double wkfngs; double wkfng; double fermig; @@ -36,6 +37,7 @@ MOS3temp(inModel,ckt) double arg1; double capfact; double gmanew,gmaold; + double ni_temp, nifact; /* loop through all the mosfet models */ for( ; model != NULL; model = model->MOS3nextModel) { @@ -49,7 +51,10 @@ MOS3temp(inModel,ckt) (model->MOS3tnom+1108); arg1 = -egfet1/(kt1+kt1)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP)); pbfact1 = -2*vtnom *(1.5*log(fact1)+CHARGE*arg1); - + nifact=(model->MOS3tnom/300)*sqrt(model->MOS3tnom/300); + nifact*=exp(0.5*egfet1*((1/(double)300)-(1/model->MOS3tnom))/ + CONSTKoverQ); + ni_temp=1.45e16*nifact; model->MOS3oxideCapFactor = 3.9 * 8.854214871e-12/ model->MOS3oxideThickness; @@ -59,11 +64,11 @@ MOS3temp(inModel,ckt) model->MOS3oxideCapFactor * 1e-4; } if(model->MOS3substrateDopingGiven) { - if(model->MOS3substrateDoping*1e6 /*(cm**3/m**3)*/ >1.45e16) { + if(model->MOS3substrateDoping*1e6 /*(cm**3/m**3)*/ >ni_temp) { if(!model->MOS3phiGiven) { model->MOS3phi = 2*vtnom* log(model->MOS3substrateDoping* - 1e6/*(cm**3/m**3)*//1.45e16); + 1e6/*(cm**3/m**3)*//ni_temp); model->MOS3phi = MAX(.1,model->MOS3phi); } fermis = model->MOS3type * .5 * model->MOS3phi; @@ -134,7 +139,9 @@ MOS3temp(inModel,ckt) arg = -egfet/(kt+kt)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP)); pbfact = -2*vt *(1.5*log(fact2)+CHARGE*arg); - + if(!here->MOS3mGiven) { + here->MOS3m = ckt->CKTdefaultMosM; + } if(!here->MOS3lGiven) { here->MOS3l = ckt->CKTdefaultMosL; } @@ -146,14 +153,17 @@ MOS3temp(inModel,ckt) } if(model->MOS3drainResistanceGiven) { if(model->MOS3drainResistance != 0) { - here->MOS3drainConductance = 1/model->MOS3drainResistance; + here->MOS3drainConductance = here->MOS3m / + model->MOS3drainResistance; } else { here->MOS3drainConductance = 0; } } else if (model->MOS3sheetResistanceGiven) { - if(model->MOS3sheetResistance != 0) { + if ((model->MOS3sheetResistance != 0) && + (here->MOS3drainSquares != 0)) { here->MOS3drainConductance = - 1/(model->MOS3sheetResistance*here->MOS3drainSquares); + here->MOS3m / + (model->MOS3sheetResistance*here->MOS3drainSquares); } else { here->MOS3drainConductance = 0; } @@ -162,14 +172,17 @@ MOS3temp(inModel,ckt) } if(model->MOS3sourceResistanceGiven) { if(model->MOS3sourceResistance != 0) { - here->MOS3sourceConductance = 1/model->MOS3sourceResistance; + here->MOS3sourceConductance = here->MOS3m / + model->MOS3sourceResistance; } else { here->MOS3sourceConductance = 0; } } else if (model->MOS3sheetResistanceGiven) { - if(model->MOS3sheetResistance != 0) { + if ((model->MOS3sheetResistance != 0) && + (here->MOS3sourceSquares != 0)) { here->MOS3sourceConductance = - 1/(model->MOS3sheetResistance*here->MOS3sourceSquares); + here->MOS3m / + (model->MOS3sheetResistance*here->MOS3sourceSquares); } else { here->MOS3sourceConductance = 0; } @@ -177,11 +190,20 @@ MOS3temp(inModel,ckt) here->MOS3sourceConductance = 0; } - if(here->MOS3l - 2 * model->MOS3latDiff <=0) { + if(here->MOS3l - 2 * model->MOS3latDiff + + model->MOS3lengthAdjust <1e-6) { (*(SPfrontEnd->IFerror))(ERR_FATAL, "%s: effective channel length less than zero", &(here->MOS3name)); - return(E_BADPARM); + return(E_PARMVAL); + } + + if(here->MOS3w - 2 * model->MOS3widthNarrow + + model->MOS3widthAdjust <1e-6) { + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "%s: effective channel width less than zero", + &(here->MOS3name)); + return(E_PARMVAL); } ratio4 = ratio * sqrt(ratio); @@ -189,7 +211,8 @@ MOS3temp(inModel,ckt) here->MOS3tSurfMob = model->MOS3surfaceMobility/ratio4; phio= (model->MOS3phi-pbfact1)/fact1; here->MOS3tPhi = fact2 * phio + pbfact; - here->MOS3tVbi = + here->MOS3tVbi = + model->MOS3delvt0 + model->MOS3vt0 - model->MOS3type * (model->MOS3gamma* sqrt(model->MOS3phi)) +.5*(egfet1-egfet) @@ -226,26 +249,29 @@ MOS3temp(inModel,ckt) (here->MOS3drainArea == 0) || (here->MOS3sourceArea == 0) ) { here->MOS3sourceVcrit = here->MOS3drainVcrit = - vt*log(vt/(CONSTroot2*model->MOS3jctSatCur)); + vt*log(vt/(CONSTroot2*here->MOS3m*here->MOS3tSatCur)); } else { here->MOS3drainVcrit = vt * log( vt / (CONSTroot2 * - model->MOS3jctSatCurDensity * here->MOS3drainArea)); + here->MOS3m * + here->MOS3tSatCurDens * here->MOS3drainArea)); here->MOS3sourceVcrit = vt * log( vt / (CONSTroot2 * - model->MOS3jctSatCurDensity * here->MOS3sourceArea)); + here->MOS3m * + here->MOS3tSatCurDens * here->MOS3sourceArea)); } if(model->MOS3capBDGiven) { - czbd = here->MOS3tCbd; + czbd = here->MOS3tCbd * here->MOS3m; } else { if(model->MOS3bulkCapFactorGiven) { - czbd=here->MOS3tCj*here->MOS3drainArea; + czbd=here->MOS3tCj*here->MOS3drainArea * here->MOS3m; } else { czbd=0; } } if(model->MOS3sideWallCapFactorGiven) { - czbdsw= here->MOS3tCjsw * here->MOS3drainPerimiter; + czbdsw= here->MOS3tCjsw * here->MOS3drainPerimiter * + here->MOS3m; } else { czbdsw=0; } @@ -260,27 +286,28 @@ MOS3temp(inModel,ckt) (1+model->MOS3bulkJctSideGradingCoeff))* sargsw/arg; here->MOS3f3d = czbd * model->MOS3bulkJctBotGradingCoeff * sarg/arg/ - model->MOS3bulkJctPotential + here->MOS3tBulkPot + czbdsw * model->MOS3bulkJctSideGradingCoeff * sargsw/arg / - model->MOS3bulkJctPotential; - here->MOS3f4d = czbd*model->MOS3bulkJctPotential*(1-arg*sarg)/ + here->MOS3tBulkPot; + here->MOS3f4d = czbd*here->MOS3tBulkPot*(1-arg*sarg)/ (1-model->MOS3bulkJctBotGradingCoeff) - + czbdsw*model->MOS3bulkJctPotential*(1-arg*sargsw)/ + + czbdsw*here->MOS3tBulkPot*(1-arg*sargsw)/ (1-model->MOS3bulkJctSideGradingCoeff) -here->MOS3f3d/2* (here->MOS3tDepCap*here->MOS3tDepCap) -here->MOS3tDepCap * here->MOS3f2d; if(model->MOS3capBSGiven) { - czbs=here->MOS3tCbs; + czbs = here->MOS3tCbs * here->MOS3m; } else { if(model->MOS3bulkCapFactorGiven) { - czbs=here->MOS3tCj*here->MOS3sourceArea; + czbs=here->MOS3tCj*here->MOS3sourceArea * here->MOS3m; } else { czbs=0; } } if(model->MOS3sideWallCapFactorGiven) { - czbssw = here->MOS3tCjsw * here->MOS3sourcePerimiter; + czbssw = here->MOS3tCjsw * here->MOS3sourcePerimiter * + here->MOS3m; } else { czbssw=0; } @@ -295,16 +322,16 @@ MOS3temp(inModel,ckt) (1+model->MOS3bulkJctSideGradingCoeff))* sargsw/arg; here->MOS3f3s = czbs * model->MOS3bulkJctBotGradingCoeff * sarg/arg/ - model->MOS3bulkJctPotential + here->MOS3tBulkPot + czbssw * model->MOS3bulkJctSideGradingCoeff * sargsw/arg / - model->MOS3bulkJctPotential; - here->MOS3f4s = czbs*model->MOS3bulkJctPotential*(1-arg*sarg)/ + here->MOS3tBulkPot; + here->MOS3f4s = czbs*here->MOS3tBulkPot*(1-arg*sarg)/ (1-model->MOS3bulkJctBotGradingCoeff) - + czbssw*model->MOS3bulkJctPotential*(1-arg*sargsw)/ + + czbssw*here->MOS3tBulkPot*(1-arg*sargsw)/ (1-model->MOS3bulkJctSideGradingCoeff) -here->MOS3f3s/2* - (here->MOS3tBulkPot*here->MOS3tBulkPot) - -here->MOS3tBulkPot * here->MOS3f2s; + (here->MOS3tDepCap*here->MOS3tDepCap) + -here->MOS3tDepCap * here->MOS3f2s; } } return(OK); diff --git a/src/spicelib/devices/mos3/mos3trun.c b/src/spicelib/devices/mos3/mos3trun.c index 5fa7c21c5..4dd134c41 100644 --- a/src/spicelib/devices/mos3/mos3trun.c +++ b/src/spicelib/devices/mos3/mos3trun.c @@ -13,11 +13,11 @@ Author: 1985 Thomas L. Quarles int MOS3trunc(inModel,ckt,timeStep) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; double *timeStep; { - register MOS3model *model = (MOS3model *)inModel; - register MOS3instance *here; + MOS3model *model = (MOS3model *)inModel; + MOS3instance *here; for( ; model != NULL; model = model->MOS3nextModel) { for(here=model->MOS3instances;here!=NULL;here = here->MOS3nextInstance){ diff --git a/src/spicelib/devices/mos6/Makefile.am b/src/spicelib/devices/mos6/Makefile.am index 8d59aa0df..beaf1e061 100644 --- a/src/spicelib/devices/mos6/Makefile.am +++ b/src/spicelib/devices/mos6/Makefile.am @@ -2,22 +2,24 @@ pkglib_LTLIBRARIES = libmos6.la -libmos6_la_SOURCES = \ - mos6.c \ - mos6ask.c \ - mos6conv.c \ - mos6defs.h \ - mos6dest.c \ - mos6ext.h \ - mos6ic.c \ - mos6itf.h \ - mos6load.c \ - mos6mask.c \ - mos6mpar.c \ - mos6par.c \ - mos6set.c \ - mos6temp.c \ - mos6trun.c +libmos6_la_SOURCES = \ + mos6.c \ + mos6ask.c \ + mos6conv.c \ + mos6defs.h \ + mos6dest.c \ + mos6ext.h \ + mos6ic.c \ + mos6init.c \ + mos6init.h \ + mos6itf.h \ + mos6load.c \ + mos6mask.c \ + mos6mpar.c \ + mos6par.c \ + mos6set.c \ + mos6temp.c \ + mos6trun.c diff --git a/src/spicelib/devices/mos6/mos6ask.c b/src/spicelib/devices/mos6/mos6ask.c index e9d465c18..272145034 100644 --- a/src/spicelib/devices/mos6/mos6ask.c +++ b/src/spicelib/devices/mos6/mos6ask.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1989 Takayasu Sakurai +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -34,10 +35,10 @@ MOS6ask(ckt,inst,which,value,select) value->rValue = here->MOS6temp-CONSTCtoK; return(OK); case MOS6_CGS: - value->rValue = *(ckt->CKTstate0 + here->MOS6capgs); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS6capgs); return(OK); case MOS6_CGD: - value->rValue = *(ckt->CKTstate0 + here->MOS6capgd); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS6capgd); return(OK); case MOS6_L: value->rValue = here->MOS6l; @@ -178,7 +179,10 @@ MOS6ask(ckt,inst,which,value,select) value->rValue = *(ckt->CKTstate0 + here->MOS6vds); return(OK); case MOS6_CAPGS: - value->rValue = *(ckt->CKTstate0 + here->MOS6capgs); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS6capgs); + /* add overlap capacitance */ + value->rValue += (here->sMOS6modPtr->MOS6gateSourceOverlapCapFactor) + * (here->MOS6w); return(OK); case MOS6_QGS: value->rValue = *(ckt->CKTstate0 + here->MOS6qgs); @@ -187,7 +191,10 @@ MOS6ask(ckt,inst,which,value,select) value->rValue = *(ckt->CKTstate0 + here->MOS6cqgs); return(OK); case MOS6_CAPGD: - value->rValue = *(ckt->CKTstate0 + here->MOS6capgd); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS6capgd); + /* add overlap capacitance */ + value->rValue += (here->sMOS6modPtr->MOS6gateSourceOverlapCapFactor) + * (here->MOS6w); return(OK); case MOS6_QGD: value->rValue = *(ckt->CKTstate0 + here->MOS6qgd); @@ -196,7 +203,11 @@ MOS6ask(ckt,inst,which,value,select) value->rValue = *(ckt->CKTstate0 + here->MOS6cqgd); return(OK); case MOS6_CAPGB: - value->rValue = *(ckt->CKTstate0 + here->MOS6capgb); + value->rValue = 2* *(ckt->CKTstate0 + here->MOS6capgb); + /* add overlap capacitance */ + value->rValue += (here->sMOS6modPtr->MOS6gateBulkOverlapCapFactor) + * (here->MOS6l + -2*(here->sMOS6modPtr->MOS6latDiff)); return(OK); case MOS6_QGB: value->rValue = *(ckt->CKTstate0 + here->MOS6qgb); diff --git a/src/spicelib/devices/mos6/mos6conv.c b/src/spicelib/devices/mos6/mos6conv.c index 5fa60bb52..85ccc755f 100644 --- a/src/spicelib/devices/mos6/mos6conv.c +++ b/src/spicelib/devices/mos6/mos6conv.c @@ -13,10 +13,10 @@ Author: 1989 Takayasu Sakurai int MOS6convTest(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register MOS6model *model = (MOS6model*)inModel; - register MOS6instance *here; + MOS6model *model = (MOS6model*)inModel; + MOS6instance *here; double delvbs; double delvbd; double delvgs; diff --git a/src/spicelib/devices/mos6/mos6ext.h b/src/spicelib/devices/mos6/mos6ext.h index e37ba67f3..4f55b4dc5 100644 --- a/src/spicelib/devices/mos6/mos6ext.h +++ b/src/spicelib/devices/mos6/mos6ext.h @@ -15,13 +15,6 @@ extern int MOS6mDelete(GENmodel**,IFuid,GENmodel*); extern int MOS6mParam(int,IFvalue*,GENmodel*); extern int MOS6param(int,IFvalue*,GENinstance*,IFvalue*); extern int MOS6pzLoad(GENmodel*,CKTcircuit*,SPcomplex*); -#ifdef notdef -extern int MOS6sAcLoad(GENmodel*,CKTcircuit*); -extern int MOS6sLoad(GENmodel*,CKTcircuit*); -extern void MOS6sPrint(GENmodel*,CKTcircuit*); -extern int MOS6sSetup(SENstruct*,GENmodel*); -extern int MOS6sUpdate(GENmodel*,CKTcircuit*); -#endif extern int MOS6setup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int MOS6unsetup(GENmodel*,CKTcircuit*); extern int MOS6temp(GENmodel*,CKTcircuit*); diff --git a/src/spicelib/devices/mos6/mos6itf.h b/src/spicelib/devices/mos6/mos6itf.h index b4951e05d..7b7fa6951 100644 --- a/src/spicelib/devices/mos6/mos6itf.h +++ b/src/spicelib/devices/mos6/mos6itf.h @@ -3,75 +3,9 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1989 T. Sakurai Modified: 1999 Paolo Nenzi **********/ -#ifdef DEV_mos6 - #ifndef DEV_MOS6 #define DEV_MOS6 -#include "mos6ext.h" -extern IFparm MOS6pTable[ ]; -extern IFparm MOS6mPTable[ ]; -extern char *MOS6names[ ]; -extern int MOS6nSize; -extern int MOS6pTSize; -extern int MOS6mPTSize; -extern int MOS6iSize; -extern int MOS6mSize; - -SPICEdev MOS6info = { - { - "Mos6", - "Level 6 MOSfet model with Meyer capacitance model", - - &MOS6nSize, - &MOS6nSize, - MOS6names, - - &MOS6pTSize, - MOS6pTable, - - &MOS6mPTSize, - MOS6mPTable, - DEV_DEFAULT - }, - - MOS6param, - MOS6mParam, - MOS6load, - MOS6setup, - MOS6unsetup, - NULL, /* PZsetup routine */ - MOS6temp, - MOS6trunc, - NULL, - NULL, /* MOS6acLoad, XXX */ - NULL, - MOS6destroy, - NULL, /* DELETES */ - NULL,/* DELETES */ - MOS6getic, - MOS6ask, - MOS6mAsk, - NULL, /*MOS6pzLoad, XXX */ -#ifdef NEWCONV - MOS6convTest, -#else /* NEWCONV */ - NULL, -#endif /* NEWCONV */ - - NULL /* MOS6sSetup */, - NULL /* MOS6sLoad */, - NULL /* MOS6sUpdate */, - NULL /* MOS6sAcLoad */, - NULL /* MOS6sPrint */, - NULL, - NULL, /* Distortion routine */ - NULL, /* Noise routine */ - - - &MOS6iSize, - &MOS6mSize -}; +SPICEdev *get_mos6_info(void); #endif -#endif diff --git a/src/spicelib/devices/mos6/mos6load.c b/src/spicelib/devices/mos6/mos6load.c index f0b5e8551..597740882 100644 --- a/src/spicelib/devices/mos6/mos6load.c +++ b/src/spicelib/devices/mos6/mos6load.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1989 Takayasu Sakurai +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -16,13 +17,13 @@ Author: 1989 Takayasu Sakurai int MOS6load(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* actually load the current value into the * sparse matrix previously provided */ { - register MOS6model *model = (MOS6model *) inModel; - register MOS6instance *here; + MOS6model *model = (MOS6model *) inModel; + MOS6instance *here; double betac; double DrainSatCur; double EffectiveLength; @@ -75,24 +76,11 @@ MOS6load(inModel,ckt) double capgd; /* total gate-drain capacitance */ double capgb; /* total gate-bulk capacitance */ int Check; -#ifndef NOBYPASS double tempv; -#endif /*NOBYPASS*/ int error; -#ifdef CAPBYPASS - int senflag; -#endif /* CAPBYPASS */ int SenCond; -#ifdef CAPBYPASS - senflag = 0; - if(ckt->CKTsenInfo && ckt->CKTsenInfo->SENstatus == PERTURBATION && - (ckt->CKTsenInfo->SENmode & (ACSEN | TRANSEN))) { - senflag = 1; - } -#endif /* CAPBYPASS */ - /* loop through all the MOS6 device models */ for( ; model != NULL; model = model->MOS6nextModel ) { @@ -118,10 +106,6 @@ MOS6load(inModel,ckt) */ -#ifdef DETAILPROF -asm(" .globl mospta"); -asm("mospta:"); -#endif /*DETAILPROF*/ /* first, we compute a few useful values - these could be * pre-computed, but for historical reasons are still done @@ -278,11 +262,6 @@ asm("mospta:"); */ -#ifdef DETAILPROF -asm(" .globl mosptb"); -asm("mosptb:"); -#endif /*DETAILPROF*/ -#ifndef NOBYPASS /* now lets see if we can bypass (ugh) */ /* the following mess should be one if statement, but * many compilers can't handle it all at once, so it @@ -342,15 +321,10 @@ asm("mosptb:"); } goto bypass; } -#endif /*NOBYPASS*/ /* */ -#ifdef DETAILPROF -asm(" .globl mosptc"); -asm("mosptc:"); -#endif /*DETAILPROF*/ /* ok - bypass is out, do it the hard way */ von = model->MOS6type * here->MOS6von; @@ -392,10 +366,6 @@ asm("mosptc:"); */ -#ifdef DETAILPROF -asm(" .globl mosptd"); -asm("mosptd:"); -#endif /*DETAILPROF*/ } else { /* ok - not one of the simple cases, so we have to @@ -423,10 +393,6 @@ asm("mosptd:"); */ -#ifdef DETAILPROF -asm(" .globl mospte"); -asm("mospte:"); -#endif /*DETAILPROF*/ /* * now all the preliminaries are over - we can start doing the @@ -442,23 +408,21 @@ asm("mospte:"); * here we just evaluate the ideal diode current and the * corresponding derivative (conductance). */ -next1: if(vbs <= 0) { - here->MOS6gbs = SourceSatCur/vt; - here->MOS6cbs = here->MOS6gbs*vbs; - here->MOS6gbs += ckt->CKTgmin; +next1: if(vbs <= -3*vt) { + here->MOS6gbs = ckt->CKTgmin; + here->MOS6cbs = here->MOS6gbs*vbs-SourceSatCur; } else { evbs = exp(MIN(MAX_EXP_ARG,vbs/vt)); here->MOS6gbs = SourceSatCur*evbs/vt + ckt->CKTgmin; - here->MOS6cbs = SourceSatCur * (evbs-1); + here->MOS6cbs = SourceSatCur*(evbs-1) + ckt->CKTgmin*vbs; } - if(vbd <= 0) { - here->MOS6gbd = DrainSatCur/vt; - here->MOS6cbd = here->MOS6gbd *vbd; - here->MOS6gbd += ckt->CKTgmin; + if(vbd <= -3*vt) { + here->MOS6gbd = ckt->CKTgmin; + here->MOS6cbd = here->MOS6gbd*vbd-DrainSatCur; } else { evbd = exp(MIN(MAX_EXP_ARG,vbd/vt)); - here->MOS6gbd = DrainSatCur*evbd/vt +ckt->CKTgmin; - here->MOS6cbd = DrainSatCur *(evbd-1); + here->MOS6gbd = DrainSatCur*evbd/vt + ckt->CKTgmin; + here->MOS6cbd = DrainSatCur*(evbd-1) + ckt->CKTgmin*vbd; } /* now to determine whether the user was able to correctly @@ -475,10 +439,6 @@ next1: if(vbs <= 0) { */ -#ifdef DETAILPROF -asm(" .globl mosptf"); -asm("mosptf:"); -#endif /*DETAILPROF*/ { /* * this block of code evaluates the drain current and its @@ -508,10 +468,8 @@ asm("mosptf:"); } vdshere = vds * here->MOS6mode; von=(here->MOS6tVbi*model->MOS6type)+model->MOS6gamma*sarg - - model->MOS6gamma1 * vbsvbd; -#if 0 + - model->MOS6gamma1 * vbsvbd - model->MOS6sigma * vdshere; -#endif vgon = (here->MOS6mode==1?vgs:vgd) - von; if (vgon <= 0) { @@ -573,10 +531,6 @@ asm("mosptf:"); */ -#ifdef DETAILPROF -asm(" .globl mosptg"); -asm("mosptg:"); -#endif /*DETAILPROF*/ /* now deal with n vs p polarity */ @@ -603,17 +557,9 @@ asm("mosptg:"); * *.. bulk-drain and bulk-source depletion capacitances */ -#ifdef CAPBYPASS - if(((ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) || - fabs(delvbs) >= ckt->CKTreltol * MAX(fabs(vbs), - fabs(*(ckt->CKTstate0+here->MOS6vbs)))+ - ckt->CKTvoltTol)|| senflag) -#endif /*CAPBYPASS*/ { /* can't bypass the diode capacitance calculations */ -#ifdef CAPZEROBYPASS if(here->MOS6Cbs != 0 || here->MOS6Cbssw != 0 ) { -#endif /*CAPZEROBYPASS*/ if (vbs < here->MOS6tDepCap){ arg=1-vbs/here->MOS6tBulkPot; /* @@ -665,24 +611,14 @@ asm("mosptg:"); vbs*(here->MOS6f2s+vbs*(here->MOS6f3s/2)); here->MOS6capbs=here->MOS6f2s+here->MOS6f3s*vbs; } -#ifdef CAPZEROBYPASS } else { *(ckt->CKTstate0 + here->MOS6qbs) = 0; here->MOS6capbs=0; } -#endif /*CAPZEROBYPASS*/ } -#ifdef CAPBYPASS - if(((ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) || - fabs(delvbd) >= ckt->CKTreltol * MAX(fabs(vbd), - fabs(*(ckt->CKTstate0+here->MOS6vbd)))+ - ckt->CKTvoltTol)|| senflag) -#endif /*CAPBYPASS*/ /* can't bypass the diode capacitance calculations */ { -#ifdef CAPZEROBYPASS if(here->MOS6Cbd != 0 || here->MOS6Cbdsw != 0 ) { -#endif /*CAPZEROBYPASS*/ if (vbd < here->MOS6tDepCap) { arg=1-vbd/here->MOS6tBulkPot; /* @@ -729,21 +665,15 @@ asm("mosptg:"); vbd * (here->MOS6f2d + vbd * here->MOS6f3d/2); here->MOS6capbd=here->MOS6f2d + vbd * here->MOS6f3d; } -#ifdef CAPZEROBYPASS } else { *(ckt->CKTstate0 + here->MOS6qbd) = 0; here->MOS6capbd = 0; } -#endif /*CAPZEROBYPASS*/ } /* */ -#ifdef DETAILPROF -asm(" .globl mospth"); -asm("mospth:"); -#endif /*DETAILPROF*/ if(SenCond && (ckt->CKTsenInfo->SENmode==TRANSEN)) goto next2; @@ -776,10 +706,6 @@ asm("mospth:"); */ -#ifdef DETAILPROF -asm(" .globl mospti"); -asm("mospti:"); -#endif /*DETAILPROF*/ if(SenCond) goto next2; @@ -792,33 +718,12 @@ asm("mospti:"); if (Check == 1) { ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) here; -#ifndef NEWCONV - } else { - tol=ckt->CKTreltol*MAX(fabs(cdhat), - fabs(here->MOS6cd))+ckt->CKTabstol; - if (fabs(cdhat-here->MOS6cd) >= tol) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; - } else { - tol=ckt->CKTreltol*MAX(fabs(cbhat), - fabs(here->MOS6cbs+here->MOS6cbd))+ - ckt->CKTabstol; - if (fabs(cbhat-(here->MOS6cbs+here->MOS6cbd)) > tol) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; - } - } -#endif /*NEWCONV*/ } } /* */ -#ifdef DETAILPROF -asm(" .globl mosptj"); -asm("mosptj:"); -#endif /*DETAILPROF*/ /* save things away for next time */ @@ -831,10 +736,6 @@ next2: *(ckt->CKTstate0 + here->MOS6vbs) = vbs; */ -#ifdef DETAILPROF -asm(" .globl mosptk"); -asm("mosptk:"); -#endif /*DETAILPROF*/ /* * meyer's capacitor model */ @@ -892,10 +793,6 @@ asm("mosptk:"); */ -#ifdef DETAILPROF -asm(" .globl mosptl"); -asm("mosptl:"); -#endif /*DETAILPROF*/ /* * store small-signal parameters (for meyer's model) * all parameters already stored, so done... @@ -981,9 +878,9 @@ bypass: * load current vector */ ceqbs = model->MOS6type * - (here->MOS6cbs-(here->MOS6gbs-ckt->CKTgmin)*vbs); + (here->MOS6cbs-(here->MOS6gbs)*vbs); ceqbd = model->MOS6type * - (here->MOS6cbd-(here->MOS6gbd-ckt->CKTgmin)*vbd); + (here->MOS6cbd-(here->MOS6gbd)*vbd); if (here->MOS6mode >= 0) { xnrm=1; xrev=0; diff --git a/src/spicelib/devices/mos6/mos6mask.c b/src/spicelib/devices/mos6/mos6mask.c index 4eb93831e..d31ba2ac9 100644 --- a/src/spicelib/devices/mos6/mos6mask.c +++ b/src/spicelib/devices/mos6/mos6mask.c @@ -18,7 +18,7 @@ MOS6mAsk(ckt,inModel,param,value) int param; IFvalue *value; { - register MOS6model *model = (MOS6model *)inModel; + MOS6model *model = (MOS6model *)inModel; switch(param) { case MOS6_MOD_TNOM: value->rValue = model->MOS6tnom; diff --git a/src/spicelib/devices/mos6/mos6mpar.c b/src/spicelib/devices/mos6/mos6mpar.c index 12441118f..b204b2290 100644 --- a/src/spicelib/devices/mos6/mos6mpar.c +++ b/src/spicelib/devices/mos6/mos6mpar.c @@ -20,7 +20,7 @@ MOS6mParam(param,value,inModel) IFvalue *value; GENmodel *inModel; { - register MOS6model *model = (MOS6model *)inModel; + MOS6model *model = (MOS6model *)inModel; switch(param) { case MOS6_MOD_TNOM: model->MOS6tnom = value->rValue+CONSTCtoK; diff --git a/src/spicelib/devices/mos6/mos6set.c b/src/spicelib/devices/mos6/mos6set.c index a6edf0720..705c5dcf5 100644 --- a/src/spicelib/devices/mos6/mos6set.c +++ b/src/spicelib/devices/mos6/mos6set.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1989 Takayasu Sakurai +Modified: 2000 AlansFixes **********/ /* load the MOS6 device structure with those pointers needed later @@ -17,13 +18,13 @@ Author: 1989 Takayasu Sakurai int MOS6setup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int *states; { - register MOS6model *model = (MOS6model *)inModel; - register MOS6instance *here; + MOS6model *model = (MOS6model *)inModel; + MOS6instance *here; int error; CKTnode *tmp; @@ -115,6 +116,9 @@ MOS6setup(matrix,inModel,ckt,states) /* loop through all the instances of the model */ for (here = model->MOS6instances; here != NULL ; here=here->MOS6nextInstance) { + CKTnode *tmpNode; + IFuid tmpName; + if (here->MOS6owner != ARCHme) goto matrixpointers; if(!here->MOS6drainPerimiterGiven) { @@ -155,6 +159,14 @@ matrixpointers: error = CKTmkVolt(ckt,&tmp,here->MOS6name,"drain"); if(error) return(error); here->MOS6dNodePrime = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } } else { here->MOS6dNodePrime = here->MOS6dNode; } @@ -166,6 +178,14 @@ matrixpointers: error = CKTmkVolt(ckt,&tmp,here->MOS6name,"source"); if(error) return(error); here->MOS6sNodePrime = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } } else { here->MOS6sNodePrime = here->MOS6sNode; } @@ -208,7 +228,6 @@ MOS6unsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM MOS6model *model; MOS6instance *here; @@ -232,6 +251,5 @@ MOS6unsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/mos6/mos6temp.c b/src/spicelib/devices/mos6/mos6temp.c index 238b0b21b..b66f2549a 100644 --- a/src/spicelib/devices/mos6/mos6temp.c +++ b/src/spicelib/devices/mos6/mos6temp.c @@ -14,10 +14,10 @@ Author: 1989 Takayasu Sakurai int MOS6temp(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register MOS6model *model = (MOS6model *)inModel; - register MOS6instance *here; + MOS6model *model = (MOS6model *)inModel; + MOS6instance *here; double egfet,egfet1; double fact1,fact2; diff --git a/src/spicelib/devices/mos6/mos6trun.c b/src/spicelib/devices/mos6/mos6trun.c index 992304b69..7ae138534 100644 --- a/src/spicelib/devices/mos6/mos6trun.c +++ b/src/spicelib/devices/mos6/mos6trun.c @@ -16,11 +16,11 @@ Author: 1989 Takayasu Sakurai int MOS6trunc(inModel,ckt,timeStep) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; double *timeStep; { - register MOS6model *model = (MOS6model *)inModel; - register MOS6instance *here; + MOS6model *model = (MOS6model *)inModel; + MOS6instance *here; for( ; model != NULL; model = model->MOS6nextModel) { for(here=model->MOS6instances;here!=NULL;here = here->MOS6nextInstance){ diff --git a/src/spicelib/devices/res/Makefile.am b/src/spicelib/devices/res/Makefile.am index bf50f74ad..1b6abeab7 100644 --- a/src/spicelib/devices/res/Makefile.am +++ b/src/spicelib/devices/res/Makefile.am @@ -3,26 +3,28 @@ pkglib_LTLIBRARIES = libres.la libres_la_SOURCES = \ - res.c \ - resask.c \ - resdefs.h \ - resdel.c \ - resdest.c \ - resext.h \ - resitf.h \ - resload.c \ - resmask.c \ - resmdel.c \ - resmpar.c \ - resnoise.c \ - resparam.c \ - respzld.c \ - ressacl.c \ - ressetup.c \ - ressload.c \ - ressprt.c \ - ressset.c \ - restemp.c + res.c \ + resask.c \ + resdefs.h \ + resdel.c \ + resdest.c \ + resext.h \ + resinit.c \ + resinit.h \ + resitf.h \ + resload.c \ + resmask.c \ + resmdel.c \ + resmpar.c \ + resnoise.c \ + resparam.c \ + respzld.c \ + ressacl.c \ + ressetup.c \ + ressload.c \ + ressprt.c \ + ressset.c \ + restemp.c diff --git a/src/spicelib/devices/res/res.c b/src/spicelib/devices/res/res.c index 050cb1080..4ba865909 100644 --- a/src/spicelib/devices/res/res.c +++ b/src/spicelib/devices/res/res.c @@ -2,6 +2,7 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles Modified: Apr 2000 - Paolo Nenzi +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -11,11 +12,13 @@ Modified: Apr 2000 - Paolo Nenzi #include "ifsim.h" IFparm RESpTable[] = { /* parameters */ - IOPP( "resistance", RES_RESIST, IF_REAL,"Resistance"), - IOPPA( "ac", RES_ACRESIST, IF_REAL, "AC resistance value"), - IOPZU( "temp", RES_TEMP, IF_REAL,"Instance operating temperature"), - IOPQU( "l", RES_LENGTH, IF_REAL,"Length"), - IOPZU( "w", RES_WIDTH, IF_REAL,"Width"), + IOPP( "resistance", RES_RESIST, IF_REAL,"Resistance"), + IOPAA( "ac", RES_ACRESIST, IF_REAL, "AC resistance value"), + IOPZU( "temp", RES_TEMP, IF_REAL,"Instance operating temperature"), + IOPQU( "l", RES_LENGTH, IF_REAL,"Length"), + IOPZU( "w", RES_WIDTH, IF_REAL,"Width"), + IOPU( "m", RES_M, IF_REAL, "Multiplication factor"), + IOPU( "scale", RES_SCALE, IF_REAL, "Scale factor"), IP( "sens_resist", RES_RESIST_SENS, IF_FLAG, "flag to request sensitivity WRT resistance"), OP( "i", RES_CURRENT,IF_REAL,"Current"), @@ -33,6 +36,7 @@ IFparm RESpTable[] = { /* parameters */ IFparm RESmPTable[] = { /* model parameters */ IOPQ( "rsh", RES_MOD_RSH, IF_REAL,"Sheet resistance"), IOPZ( "narrow", RES_MOD_NARROW, IF_REAL,"Narrowing of resistor"), + IOPZ( "short", RES_MOD_SHORT, IF_REAL,"Shortening of resistor"), IOPQ( "tc1", RES_MOD_TC1, IF_REAL,"First order temp. coefficient"), IOPQO( "tc2", RES_MOD_TC2, IF_REAL,"Second order temp. coefficient"), IOPX( "defw", RES_MOD_DEFWIDTH, IF_REAL,"Default device width"), diff --git a/src/spicelib/devices/res/resask.c b/src/spicelib/devices/res/resask.c index 23523d847..96a22d005 100644 --- a/src/spicelib/devices/res/resask.c +++ b/src/spicelib/devices/res/resask.c @@ -43,9 +43,15 @@ RESask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value, case RES_LENGTH: value->rValue = fast->RESlength; return(OK); - case RES_WIDTH : + case RES_WIDTH: value->rValue = fast->RESwidth; + return(OK); + case RES_SCALE: + value->rValue = fast->RESscale; return(OK); + case RES_M: + value->rValue = fast->RESm; + return(OK); case RES_QUEST_SENS_DC: if(ckt->CKTsenInfo){ value->rValue = *(ckt->CKTsenInfo->SEN_Sap[select->iValue + 1]+ diff --git a/src/spicelib/devices/res/resdefs.h b/src/spicelib/devices/res/resdefs.h index dee61c485..b6b3ccfbe 100644 --- a/src/spicelib/devices/res/resdefs.h +++ b/src/spicelib/devices/res/resdefs.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #ifndef RES @@ -36,6 +37,8 @@ typedef struct sRESinstance { double RESacConduct; /* AC conductance */ double RESwidth; /* width of the resistor */ double RESlength; /* length of the resistor */ + double RESscale; /* Scale factor */ + double RESm; /* Multiplicity factor for this instance */ double *RESposPosptr; /* pointer to sparse matrix diagonal at * (positive,positive) */ double *RESnegNegptr; /* pointer to sparse matrix diagonal at @@ -44,12 +47,14 @@ typedef struct sRESinstance { * (positive,negative) */ double *RESnegPosptr; /* pointer to sparse matrix offdiagonal at * (negative,positive) */ - unsigned RESresGiven : 1; /* flag to indicate resistance was specified */ + unsigned RESresGiven : 1; /* flag to indicate resistance was specified */ unsigned RESwidthGiven : 1; /* flag to indicate width given */ unsigned RESlengthGiven : 1; /* flag to indicate length given */ + unsigned RESscaleGiven : 1; /* flag to indicate scale given */ unsigned REStempGiven : 1; /* indicates temperature specified */ /* serban */ - unsigned RESacresGiven : 1; /* indicates AC value specified */ + unsigned RESacresGiven : 1; /* indicates AC value specified */ + unsigned RESmGiven : 1; /* indicates M parameter specified */ int RESsenParmNo; /* parameter # for sensitivity use; set equal to 0 if not a design parameter*/ #ifndef NONOISE @@ -77,12 +82,14 @@ typedef struct sRESmodel { /* model structure for a resistor */ double RESsheetRes; /* sheet resistance of devices in ohms/square */ double RESdefWidth; /* default width of a resistor */ double RESnarrow; /* amount by which device is narrower than drawn */ + double RESshort; /* amount by which device is shorter than drawn */ unsigned REStnomGiven: 1; /* flag to indicate nominal temp. was given */ unsigned REStc1Given : 1; /* flag to indicate tc1 was specified */ unsigned REStc2Given : 1; /* flag to indicate tc2 was specified */ unsigned RESsheetResGiven :1; /* flag to indicate sheet resistance given*/ unsigned RESdefWidthGiven :1; /* flag to indicate default width given */ unsigned RESnarrowGiven :1; /* flag to indicate narrow effect given */ + unsigned RESshortGiven :1; /* flag to indicate short effect given */ } RESmodel; /* device parameters */ @@ -97,6 +104,8 @@ typedef struct sRESmodel { /* model structure for a resistor */ /* serban */ #define RES_ACRESIST 10 #define RES_ACCONDUCT 11 +#define RES_M 12 /* pn */ +#define RES_SCALE 13 /* pn */ /* model parameters */ @@ -107,6 +116,7 @@ typedef struct sRESmodel { /* model structure for a resistor */ #define RES_MOD_NARROW 105 #define RES_MOD_R 106 #define RES_MOD_TNOM 107 +#define RES_MOD_SHORT 108 /* device questions */ #define RES_QUEST_SENS_REAL 201 diff --git a/src/spicelib/devices/res/resitf.h b/src/spicelib/devices/res/resitf.h index bfc6a7e8c..0d6d48a6c 100644 --- a/src/spicelib/devices/res/resitf.h +++ b/src/spicelib/devices/res/resitf.h @@ -1,93 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_res - #ifndef DEV_RES #define DEV_RES -#include "resext.h" -extern IFparm RESpTable[ ]; -extern IFparm RESmPTable[ ]; -extern char *RESnames[ ]; -extern int RESpTSize; -extern int RESmPTSize; -extern int RESnSize; -extern int RESiSize; -extern int RESmSize; - -SPICEdev RESinfo = { - { - "Resistor", - "Simple linear resistor", - - &RESnSize, - &RESnSize, - RESnames, - - &RESpTSize, - RESpTable, - - &RESmPTSize, - RESmPTable, - 0 - }, - - RESparam, - RESmParam, - RESload, - RESsetup, - NULL, - RESsetup, - REStemp, - NULL, - NULL, -/* serban - added ac support */ - RESacload, /* ac load and normal load are identical */ - NULL, - RESdestroy, -#ifdef DELETES - RESmDelete, - RESdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - NULL, - RESask, - RESmodAsk, -#ifdef AN_pz - RESpzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ - NULL, -#ifdef AN_sense2 - RESsSetup, - RESsLoad, - NULL, - RESsAcLoad, - RESsPrint, - NULL, -#else /* AN_sense2 */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -#endif /* AN_sense2 */ - NULL, /* Disto */ -#ifdef AN_noise - RESnoise, -#else /* AN_noise */ - NULL, -#endif /* AN_noise */ - - &RESiSize, - &RESmSize - -}; +SPICEdev *get_res_info(void); #endif -#endif diff --git a/src/spicelib/devices/res/resload.c b/src/spicelib/devices/res/resload.c index b2754c136..3682d7296 100644 --- a/src/spicelib/devices/res/resload.c +++ b/src/spicelib/devices/res/resload.c @@ -11,21 +11,20 @@ Modified: Apr 2000 - Paolo Nenzi #include "sperror.h" +/* actually load the current resistance value into the sparse matrix + * previously provided */ int RESload(GENmodel *inModel, CKTcircuit *ckt) - /* actually load the current resistance value into the - * sparse matrix previously provided - */ { RESmodel *model = (RESmodel *)inModel; - RESinstance *here; /* loop through all the resistor models */ for( ; model != NULL; model = model->RESnextModel ) { + RESinstance *here; /* loop through all the instances of the model */ for (here = model->RESinstances; here != NULL ; - here=here->RESnextInstance) { + here = here->RESnextInstance) { *(here->RESposPosptr) += here->RESconduct; *(here->RESnegNegptr) += here->RESconduct; @@ -36,21 +35,21 @@ RESload(GENmodel *inModel, CKTcircuit *ckt) return(OK); } + +/* actually load the current resistance value into the sparse matrix + * previously provided */ int RESacload(GENmodel *inModel, CKTcircuit *ckt) - /* actually load the current resistance value into the - * sparse matrix previously provided - */ { RESmodel *model = (RESmodel *)inModel; - RESinstance *here; /* loop through all the resistor models */ for( ; model != NULL; model = model->RESnextModel ) { + RESinstance *here; /* loop through all the instances of the model */ for (here = model->RESinstances; here != NULL ; - here=here->RESnextInstance) { + here = here->RESnextInstance) { if(here->RESacresGiven) { *(here->RESposPosptr) += here->RESacConduct; diff --git a/src/spicelib/devices/res/resmask.c b/src/spicelib/devices/res/resmask.c index 101dc2863..20421723e 100644 --- a/src/spicelib/devices/res/resmask.c +++ b/src/spicelib/devices/res/resmask.c @@ -2,6 +2,7 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles Modified: Apr 2000 - Paolo Nenzi +Modified: 2000 AlansFixes **********/ @@ -38,6 +39,9 @@ RESmodAsk(CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value) case RES_MOD_NARROW: value->rValue = model->RESnarrow; return(OK); + case RES_MOD_SHORT: + value->rValue = model->RESshort; + return(OK); default: return(E_BADPARM); } diff --git a/src/spicelib/devices/res/resmpar.c b/src/spicelib/devices/res/resmpar.c index 5350fdeb8..8af8fb906 100644 --- a/src/spicelib/devices/res/resmpar.c +++ b/src/spicelib/devices/res/resmpar.c @@ -2,6 +2,7 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles Modified: Apr 2000 - Paolo Nenzi +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -42,6 +43,10 @@ RESmParam(int param, IFvalue *value, GENmodel *inModel) model->RESnarrow = value->rValue; model->RESnarrowGiven = TRUE; break; + case RES_MOD_SHORT: + model->RESshort = value->rValue; + model->RESshortGiven = TRUE; + break; case RES_MOD_R: /* just being reassured by user that this is a resistor model */ /* no-op */ diff --git a/src/spicelib/devices/res/resnoise.c b/src/spicelib/devices/res/resnoise.c index 777694804..a14c58f44 100644 --- a/src/spicelib/devices/res/resnoise.c +++ b/src/spicelib/devices/res/resnoise.c @@ -8,7 +8,6 @@ Modified: Apr 2000 - Paolo Nenzi #include #include "resdefs.h" #include "cktdefs.h" -#include "fteconst.h" #include "iferrmsg.h" #include "noisedef.h" @@ -114,6 +113,7 @@ if (!data->namelist) return(E_NOMEM); if (data->freq == ((NOISEAN*)ckt->CKTcurJob)->NstartFreq) { inst->RESnVar[OUTNOIZ] = 0.0; + inst->RESnVar[INNOIZ] = 0.0; /* Clear input noise */ } } else { /* data->delFreq != 0.0 (we have to integrate) */ tempOutNoise = Nintegrate(noizDens, lnNdens, diff --git a/src/spicelib/devices/res/resparam.c b/src/spicelib/devices/res/resparam.c index 0bf029de0..3ac92875c 100644 --- a/src/spicelib/devices/res/resparam.c +++ b/src/spicelib/devices/res/resparam.c @@ -37,8 +37,16 @@ RESparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) here->RESlength = value->rValue; here->RESlengthGiven = TRUE; break; + case RES_SCALE: + here->RESscale = value->rValue; + here->RESscaleGiven = TRUE; + break; case RES_RESIST_SENS: here->RESsenParmNo = value->iValue; + break; + case RES_M: + here->RESm = value->rValue; + here->RESmGiven = TRUE; break; default: return(E_BADPARM); diff --git a/src/spicelib/devices/res/restemp.c b/src/spicelib/devices/res/restemp.c index 77d9060ed..c03c94b82 100644 --- a/src/spicelib/devices/res/restemp.c +++ b/src/spicelib/devices/res/restemp.c @@ -2,6 +2,7 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles Modified Apr 2000 - Paolo Nenzi +Modified: 2000 AlanSfixes **********/ #include "ngspice.h" @@ -30,12 +31,13 @@ REStemp(GENmodel *inModel, CKTcircuit *ckt) for( ; model != NULL; model = model->RESnextModel ) { /* Default Value Processing for Resistor Models */ - if(!model->REStnomGiven) model->REStnom = ckt->CKTnomTemp; + if(!model->REStnomGiven) model->REStnom = ckt->CKTnomTemp; if(!model->RESsheetResGiven) model->RESsheetRes = 0; if(!model->RESdefWidthGiven) model->RESdefWidth = 10.e-6; /*M*/ - if(!model->REStc1Given) model->REStempCoeff1 = 0; - if(!model->REStc2Given) model->REStempCoeff2 = 0; - if(!model->RESnarrowGiven) model->RESnarrow = 0; + if(!model->REStc1Given) model->REStempCoeff1 = 0; + if(!model->REStc2Given) model->REStempCoeff2 = 0; + if(!model->RESnarrowGiven) model->RESnarrow = 0; + if(!model->RESshortGiven) model->RESshort = 0; /* loop through all the instances of the model */ for (here = model->RESinstances; here != NULL ; @@ -43,14 +45,16 @@ REStemp(GENmodel *inModel, CKTcircuit *ckt) if (here->RESowner != ARCHme) continue; /* Default Value Processing for Resistor Instance */ - if(!here->REStempGiven) here->REStemp = ckt->CKTtemp; - if(!here->RESwidthGiven) here->RESwidth = model->RESdefWidth; - if(!here->RESlengthGiven) here->RESlength = 0 ; + if(!here->REStempGiven) here->REStemp = ckt->CKTtemp; + if(!here->RESwidthGiven) here->RESwidth = model->RESdefWidth; + if(!here->RESlengthGiven) here->RESlength = 0.0; + if(!here->RESscaleGiven) here->RESscale = 1.0; + if(!here->RESmGiven) here->RESm = 1.0; if(!here->RESresGiven) { if(model->RESsheetResGiven && (model->RESsheetRes != 0) && (here->RESlength != 0)) { here->RESresist = model->RESsheetRes * (here->RESlength - - model->RESnarrow) / (here->RESwidth - model->RESnarrow); + model->RESshort) / (here->RESwidth - model->RESnarrow); } else { (*(SPfrontEnd->IFerror))(ERR_WARNING, "%s: resistance=0, set to 1000",&(here->RESname)); @@ -62,11 +66,12 @@ REStemp(GENmodel *inModel, CKTcircuit *ckt) factor = 1.0 + (model->REStempCoeff1)*difference + (model->REStempCoeff2)*difference*difference; - here->RESconduct = 1.0/(here->RESresist * factor); + here -> RESconduct = here->RESm*(1.0/(here->RESresist * factor * here->RESscale)); + here -> RESacConduct = here -> RESconduct; /* default value */ - /* Paolo Nenzi: Temperature effects for AC value */ + /* Paolo Nenzi: AC value */ if(here->RESacresGiven) - here->RESacConduct = 1.0/(here->RESacResist * factor); + here->RESacConduct = here->RESm*(1.0/(here->RESacResist * factor * here->RESscale)); } } return(OK); diff --git a/src/spicelib/devices/sw/Makefile.am b/src/spicelib/devices/sw/Makefile.am index cd450566c..f4236ee5c 100644 --- a/src/spicelib/devices/sw/Makefile.am +++ b/src/spicelib/devices/sw/Makefile.am @@ -2,23 +2,26 @@ pkglib_LTLIBRARIES = libsw.la -libsw_la_SOURCES = \ - sw.c \ - swacload.c \ - swask.c \ - swdefs.h \ - swdelete.c \ - swdest.c \ - swext.h \ - switf.h \ - swload.c \ - swmask.c \ - swmdel.c \ - swmparam.c \ - swnoise.c \ - swparam.c \ - swpzload.c \ - swsetup.c +libsw_la_SOURCES = \ + sw.c \ + swacload.c \ + swask.c \ + swdefs.h \ + swdelete.c \ + swdest.c \ + swext.h \ + swinit.c \ + swinit.h \ + switf.h \ + swload.c \ + swmask.c \ + swmdel.c \ + swmparam.c \ + swnoise.c \ + swparam.c \ + swpzload.c \ + swsetup.c \ + swtrunc.c diff --git a/src/spicelib/devices/sw/swacload.c b/src/spicelib/devices/sw/swacload.c index 4c3ab45f2..e34306bdc 100644 --- a/src/spicelib/devices/sw/swacload.c +++ b/src/spicelib/devices/sw/swacload.c @@ -16,14 +16,14 @@ Author: 1985 Gordon Jacobs int SWacLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* load the current values into the * sparse matrix previously provided * during AC analysis. */ { - register SWmodel *model = (SWmodel *)inModel; - register SWinstance *here; + SWmodel *model = (SWmodel *)inModel; + SWinstance *here; double g_now; int current_state; diff --git a/src/spicelib/devices/sw/swdefs.h b/src/spicelib/devices/sw/swdefs.h index db50cb932..540d7934e 100644 --- a/src/spicelib/devices/sw/swdefs.h +++ b/src/spicelib/devices/sw/swdefs.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Gordon M. Jacobs +Modified: 2000 AlansFixes **********/ #ifndef SW @@ -53,7 +54,7 @@ typedef struct sSWinstance { #define SW_ON_CONDUCTANCE 1.0 /* default on conductance = 1 mho */ #define SW_OFF_CONDUCTANCE ckt->CKTgmin /* default off conductance */ -#define SW_NUM_STATES 1 +#define SW_NUM_STATES 2 typedef struct sSWmodel { /* model structure for a switch */ int SWmodType; /* type index of this device type */ diff --git a/src/spicelib/devices/sw/swext.h b/src/spicelib/devices/sw/swext.h index 492a540fd..08fb3543b 100644 --- a/src/spicelib/devices/sw/swext.h +++ b/src/spicelib/devices/sw/swext.h @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Gordon M. Jacobs +Modified: 2000 AlansFixes **********/ #ifdef __STDC__ @@ -16,6 +17,7 @@ extern int SWparam(int,IFvalue*,GENinstance*,IFvalue*); extern int SWpzLoad(GENmodel*,CKTcircuit*,SPcomplex*); extern int SWsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int SWnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); +extern int SWtrunc(GENmodel*,CKTcircuit*,double*); #else /* stdc */ extern int SWacLoad(); extern int SWask(); @@ -29,5 +31,6 @@ extern int SWparam(); extern int SWpzLoad(); extern int SWsetup(); extern int SWnoise(); +extern int SWtrunc(); #endif /* stdc */ diff --git a/src/spicelib/devices/sw/switf.h b/src/spicelib/devices/sw/switf.h index eb292972f..0aee8110c 100644 --- a/src/spicelib/devices/sw/switf.h +++ b/src/spicelib/devices/sw/switf.h @@ -1,83 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_sw - #ifndef DEV_SW #define DEV_SW -#include "swext.h" -extern IFparm SWpTable[ ]; -extern IFparm SWmPTable[ ]; -extern char *SWnames[ ]; -extern int SWpTSize; -extern int SWmPTSize; -extern int SWnSize; -extern int SWiSize; -extern int SWmSize; - -SPICEdev SWinfo = { - { - "Switch", - "Ideal voltage controlled switch", - - &SWnSize, - &SWnSize, - SWnames, - - &SWpTSize, - SWpTable, - - &SWmPTSize, - SWmPTable, - 0 - }, - - SWparam, - SWmParam, - SWload, - SWsetup, - NULL, - SWsetup, - NULL, - NULL, - NULL, - SWacLoad, - NULL, - SWdestroy, -#ifdef DELETES - SWmDelete, - SWdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - NULL, - SWask, - SWmAsk, -#ifdef AN_pz - SWpzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, /* DISTO */ -#ifdef AN_noise - SWnoise, -#else /* AN_noise */ - NULL, -#endif /* AN_noise */ - - &SWiSize, - &SWmSize - -}; +extern SPICEdev *get_sw_info(void); #endif -#endif diff --git a/src/spicelib/devices/sw/swload.c b/src/spicelib/devices/sw/swload.c index 16eea80b6..aaa38b484 100644 --- a/src/spicelib/devices/sw/swload.c +++ b/src/spicelib/devices/sw/swload.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Gordon Jacobs +Modified: 2001 Jon Engelbert **********/ #include "ngspice.h" @@ -14,17 +15,23 @@ Author: 1985 Gordon Jacobs int SWload(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* actually load the current values into the * sparse matrix previously provided */ { - register SWmodel *model = (SWmodel *) inModel; - register SWinstance *here; + SWmodel *model = (SWmodel *) inModel; + SWinstance *here; double g_now; double v_ctrl; - double previous_state; - double current_state; + double previous_state = -1; + double current_state = -1; + double old_current_state = -1; + double UNKNOWN = -1; + double REALLY_OFF = 0, REALLY_ON = 1; // switch is on or off, not in hysteresis region. + double HYST_OFF = 2, HYST_ON = 3; // switch is on or off while control value is in hysteresis region. +// double previous_region = -1; +// double current_region = -1; /* loop through all the switch models */ for( ; model != NULL; model = model->SWnextModel ) { @@ -33,72 +40,113 @@ SWload(inModel,ckt) for (here = model->SWinstances; here != NULL ; here=here->SWnextInstance) { if (here->SWowner != ARCHme) continue; + + old_current_state = *(ckt->CKTstates[0] + here->SWstate); + previous_state = *(ckt->CKTstates[1] + here->SWstate); - /* decide the state of the switch */ - + v_ctrl = *(ckt->CKTrhsOld + here->SWposCntrlNode) + - *(ckt->CKTrhsOld + here->SWnegCntrlNode); + + /* decide the state of the switch */ + if(ckt->CKTmode & (MODEINITFIX|MODEINITJCT)) { if(here->SWzero_stateGiven) { /* switch specified "on" */ - *(ckt->CKTstate0 + here->SWstate) = 1.0; - current_state = 1.0; + if ((model->SWvHysteresis >= 0) && (v_ctrl > (model->SWvThreshold + model->SWvHysteresis))) + current_state = REALLY_ON; + else if ((model->SWvHysteresis < 0) && (v_ctrl > (model->SWvThreshold - model->SWvHysteresis))) + current_state = REALLY_ON; + else + current_state = HYST_ON; } else { - *(ckt->CKTstate0 + here->SWstate) = 0.0; - current_state = 0.0; + if ((model->SWvHysteresis >= 0) && (v_ctrl < (model->SWvThreshold - model->SWvHysteresis))) + current_state = REALLY_OFF; + else if ((model->SWvHysteresis < 0) && (v_ctrl < (model->SWvThreshold + model->SWvHysteresis))) + current_state = REALLY_OFF; + else + current_state = HYST_OFF; } } else if (ckt->CKTmode & (MODEINITSMSIG)) { - previous_state = *(ckt->CKTstate0 + here->SWstate); current_state = previous_state; } else if (ckt->CKTmode & (MODEINITFLOAT)) { /* use state0 since INITTRAN or INITPRED already called */ - previous_state = *(ckt->CKTstate0 + here->SWstate); - v_ctrl = *(ckt->CKTrhsOld + here->SWposCntrlNode) - - *(ckt->CKTrhsOld + here->SWnegCntrlNode); - if(v_ctrl > (model->SWvThreshold + model->SWvHysteresis)) { - *(ckt->CKTstate0 + here->SWstate) = 1.0; - current_state = 1.0; - } else if(v_ctrl < (model->SWvThreshold - - model->SWvHysteresis)) { - *(ckt->CKTstate0 + here->SWstate) = 0.0; - current_state = 0.0; - } else { - current_state = previous_state; - } + if (model->SWvHysteresis > 0) { + if (v_ctrl > (model->SWvThreshold + model->SWvHysteresis)) { + current_state = REALLY_ON; + } else if (v_ctrl < (model->SWvThreshold - model->SWvHysteresis)) { + current_state = REALLY_OFF; + } else { + current_state = old_current_state; + } + } else { // negative hysteresis case. + if (v_ctrl > (model->SWvThreshold - model->SWvHysteresis)) + { + current_state = REALLY_ON; + } else if (v_ctrl < (model->SWvThreshold + model->SWvHysteresis)) + { + current_state = REALLY_OFF; + } else { // in hysteresis... change value if going from low to hysteresis, or from hi to hysteresis. + // if previous state was in hysteresis, then don't change the state.. + if ((previous_state == HYST_OFF) || (previous_state == HYST_ON)) { + current_state = previous_state; + } else if (previous_state == REALLY_ON) { + current_state = HYST_OFF; + } else if (previous_state == REALLY_OFF) { + current_state = HYST_ON; + } else + internalerror("bad value for previous state in swload"); + } + } - if(current_state != previous_state) { + if(current_state != old_current_state) { ckt->CKTnoncon++; /* ensure one more iteration */ - ckt->CKTtroubleElt = (GENinstance *) here; + ckt->CKTtroubleElt = (GENinstance *) here; } } else if(ckt->CKTmode & (MODEINITTRAN|MODEINITPRED) ) { - previous_state = *(ckt->CKTstate1 + here->SWstate); - v_ctrl = *(ckt->CKTrhsOld + here->SWposCntrlNode) - - *(ckt->CKTrhsOld + here->SWnegCntrlNode); + if (model->SWvHysteresis > 0) { + if (v_ctrl > (model->SWvThreshold + model->SWvHysteresis)) + current_state = REALLY_ON; + else if (v_ctrl < (model->SWvThreshold - model->SWvHysteresis)) + current_state = REALLY_OFF; + else + current_state = previous_state; + } else { // negative hysteresis case. + if (v_ctrl > (model->SWvThreshold - model->SWvHysteresis)) + current_state = REALLY_ON; + else if (v_ctrl < (model->SWvThreshold + model->SWvHysteresis)) + current_state = REALLY_OFF; + else { + current_state = 0.0; + if ((previous_state == HYST_ON) || (previous_state == HYST_OFF)) { + current_state = previous_state; + } else if (previous_state == REALLY_ON) { + current_state = REALLY_OFF; + } else if (previous_state == REALLY_OFF) { + current_state = REALLY_ON; + } + } + } + } +// code added to force the state to be updated. +// there is a possible problem. What if, during the transient analysis, the time is stepped +// forward enough to change the switch's state, but that time point is rejected as being too +// distant and then the time is pushed back to a time before the switch changed states. +// After analyzing the transient code, it seems that this is not a problem because state updating +// occurs before the convergence loop in transient processing. + *(ckt->CKTstates[0] + here->SWstate) = current_state; - if(v_ctrl > (model->SWvThreshold + model->SWvHysteresis)) { - current_state = 1.0; - } else if(v_ctrl < (model->SWvThreshold - - model->SWvHysteresis)) { - current_state = 0.0; - } else { - current_state = previous_state; - } - - if(current_state == 0) { - *(ckt->CKTstate0 + here->SWstate) = 0.0; - } else { - *(ckt->CKTstate0 + here->SWstate) = 1.0; - } - - } - - g_now = current_state?(model->SWonConduct):(model->SWoffConduct); + if ((current_state == REALLY_ON) || (current_state == HYST_ON)) + g_now = model->SWonConduct; + else + g_now = model->SWoffConduct; here->SWcond = g_now; *(here->SWposPosptr) += g_now; diff --git a/src/spicelib/devices/sw/swmparam.c b/src/spicelib/devices/sw/swmparam.c index b337adfc2..a2b25c5f1 100644 --- a/src/spicelib/devices/sw/swmparam.c +++ b/src/spicelib/devices/sw/swmparam.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Gordon Jacobs +Modified: 2001 Jon Engelbert **********/ /* */ @@ -41,8 +42,9 @@ SWmParam(param,value,inModel) break; case SW_MOD_VHYS: /* take absolute value of hysteresis voltage */ - model->SWvHysteresis = (value->rValue < 0) ? -(value->rValue) : - value->rValue; +// model->SWvHysteresis = (value->rValue < 0) ? -(value->rValue) : +// value->rValue; + model->SWvHysteresis = value->rValue; model->SWhystGiven = TRUE; break; default: diff --git a/src/spicelib/devices/sw/swnoise.c b/src/spicelib/devices/sw/swnoise.c index 2c5484e84..9e45f1538 100644 --- a/src/spicelib/devices/sw/swnoise.c +++ b/src/spicelib/devices/sw/swnoise.c @@ -7,7 +7,6 @@ Author: 1987 Gary W. Ng #include #include "swdefs.h" #include "cktdefs.h" -#include "fteconst.h" #include "iferrmsg.h" #include "noisedef.h" #include "suffix.h" @@ -31,12 +30,12 @@ SWnoise (mode, operation, genmodel, ckt, data, OnDens) int operation; GENmodel *genmodel; CKTcircuit *ckt; - register Ndata *data; + Ndata *data; double *OnDens; { SWmodel *firstModel = (SWmodel *) genmodel; - register SWmodel *model; - register SWinstance *inst; + SWmodel *model; + SWinstance *inst; char name[N_MXVLNTH]; double tempOutNoise; double tempInNoise; diff --git a/src/spicelib/devices/sw/swpzload.c b/src/spicelib/devices/sw/swpzload.c index da36352b3..90a19ff59 100644 --- a/src/spicelib/devices/sw/swpzload.c +++ b/src/spicelib/devices/sw/swpzload.c @@ -18,15 +18,15 @@ Author: 1985 Gordon Jacobs int SWpzLoad(inModel,ckt,s) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; SPcomplex *s; /* load the current values into the * sparse matrix previously provided * during AC analysis. */ { - register SWmodel *model = (SWmodel *)inModel; - register SWinstance *here; + SWmodel *model = (SWmodel *)inModel; + SWinstance *here; double g_now; int current_state; diff --git a/src/spicelib/devices/sw/swsetup.c b/src/spicelib/devices/sw/swsetup.c index 4a6b9505b..e5240926c 100644 --- a/src/spicelib/devices/sw/swsetup.c +++ b/src/spicelib/devices/sw/swsetup.c @@ -16,7 +16,7 @@ Author: 1985 Gordon Jacobs int SWsetup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; CKTcircuit *ckt; int *states; @@ -24,8 +24,8 @@ SWsetup(matrix,inModel,ckt,states) * for fast matrix loading */ { - register SWmodel *model = (SWmodel *)inModel; - register SWinstance *here; + SWmodel *model = (SWmodel *)inModel; + SWinstance *here; /* loop through all the current source models */ for( ; model != NULL; model = model->SWnextModel ) { diff --git a/src/spicelib/devices/tra/Makefile.am b/src/spicelib/devices/tra/Makefile.am index 669b84e84..8eed1f73d 100644 --- a/src/spicelib/devices/tra/Makefile.am +++ b/src/spicelib/devices/tra/Makefile.am @@ -2,23 +2,24 @@ pkglib_LTLIBRARIES = libtra.la -libtra_la_SOURCES = \ - tra.c \ - traacct.c \ - traacld.c \ - traask.c \ - tradefs.h \ - tradel.c \ - tradest.c \ - traext.h \ - traitf.h \ - traload.c \ - tramdel.c \ - traparam.c \ - trasetup.c \ - tratemp.c \ - tratrunc.c - +libtra_la_SOURCES = \ + tra.c \ + traacct.c \ + traacld.c \ + traask.c \ + tradefs.h \ + tradel.c \ + tradest.c \ + traext.h \ + trainit.c \ + trainit.h \ + traitf.h \ + traload.c \ + tramdel.c \ + traparam.c \ + trasetup.c \ + tratemp.c \ + tratrunc.c INCLUDES = -I$(top_srcdir)/src/include diff --git a/src/spicelib/devices/tra/traacct.c b/src/spicelib/devices/tra/traacct.c index c42ced7de..84eef8a10 100644 --- a/src/spicelib/devices/tra/traacct.c +++ b/src/spicelib/devices/tra/traacct.c @@ -15,12 +15,12 @@ Author: 1985 Thomas L. Quarles int TRAaccept(ckt,inModel) - register CKTcircuit *ckt; + CKTcircuit *ckt; GENmodel *inModel; { - register TRAmodel *model = (TRAmodel *)inModel; - register TRAinstance *here; - register int i=0,j; + TRAmodel *model = (TRAmodel *)inModel; + TRAinstance *here; + int i=0,j; double v1,v2,v3,v4; double v5,v6,d1,d2,d3,d4; double *from,*to; diff --git a/src/spicelib/devices/tra/traacld.c b/src/spicelib/devices/tra/traacld.c index e9ce9408e..db96a1ab7 100644 --- a/src/spicelib/devices/tra/traacld.c +++ b/src/spicelib/devices/tra/traacld.c @@ -18,8 +18,8 @@ TRAacLoad(inModel,ckt) * sparse matrix previously provided */ { - register TRAmodel *model = (TRAmodel *)inModel; - register TRAinstance *here; + TRAmodel *model = (TRAmodel *)inModel; + TRAinstance *here; double real; double imag; diff --git a/src/spicelib/devices/tra/traitf.h b/src/spicelib/devices/tra/traitf.h index 9e515a84f..0ba2a2ef8 100644 --- a/src/spicelib/devices/tra/traitf.h +++ b/src/spicelib/devices/tra/traitf.h @@ -1,74 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_tra - #ifndef DEV_TRA #define DEV_TRA -#include "traext.h" -extern IFparm TRApTable[ ]; -extern char *TRAnames[ ]; -extern int TRApTSize; -extern int TRAnSize; -extern int TRAiSize; -extern int TRAmSize; - -SPICEdev TRAinfo = { - { - "Tranline", - "Lossless transmission line", - - &TRAnSize, - &TRAnSize, - TRAnames, - - &TRApTSize, - TRApTable, - - 0, - NULL, - 0 - }, - - TRAparam, - NULL, - TRAload, - TRAsetup, - TRAunsetup, - TRAsetup, - TRAtemp, - TRAtrunc, - NULL, - TRAacLoad, - TRAaccept, - TRAdestroy, -#ifdef DELETES - TRAmDelete, - TRAdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - NULL, - TRAask, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, /* DISTO */ - NULL, /* NOISE */ - - &TRAiSize, - &TRAmSize - -}; - +SPICEdev *get_tra_info(void); #endif -#endif diff --git a/src/spicelib/devices/tra/traload.c b/src/spicelib/devices/tra/traload.c index e4dacbf2d..4b4bbb569 100644 --- a/src/spicelib/devices/tra/traload.c +++ b/src/spicelib/devices/tra/traload.c @@ -23,11 +23,11 @@ TRAload(inModel,ckt) * sparse matrix previously provided */ { - register TRAmodel *model = (TRAmodel *)inModel; - register TRAinstance *here; + TRAmodel *model = (TRAmodel *)inModel; + TRAinstance *here; double t1,t2,t3; double f1,f2,f3; - register int i; + int i; /* loop through all the transmission line models */ for( ; model != NULL; model = model->TRAnextModel ) { diff --git a/src/spicelib/devices/tra/trasetup.c b/src/spicelib/devices/tra/trasetup.c index 13588c23f..bf8354570 100644 --- a/src/spicelib/devices/tra/trasetup.c +++ b/src/spicelib/devices/tra/trasetup.c @@ -17,16 +17,16 @@ Author: 1985 Thomas L. Quarles /* ARGSUSED */ int TRAsetup(matrix,inModel,ckt,state) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int *state; /* load the transmission line structure with those pointers needed later * for fast matrix loading */ { - register TRAmodel *model = (TRAmodel *)inModel; - register TRAinstance *here; + TRAmodel *model = (TRAmodel *)inModel; + TRAinstance *here; int error; CKTnode *tmp; @@ -122,7 +122,6 @@ TRAunsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM TRAmodel *model; TRAinstance *here; @@ -150,6 +149,5 @@ TRAunsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/tra/tratemp.c b/src/spicelib/devices/tra/tratemp.c index 144e81445..64f178844 100644 --- a/src/spicelib/devices/tra/tratemp.c +++ b/src/spicelib/devices/tra/tratemp.c @@ -23,8 +23,8 @@ TRAtemp(inModel,ckt) * pre-process parameters for later use */ { - register TRAmodel *model = (TRAmodel *)inModel; - register TRAinstance *here; + TRAmodel *model = (TRAmodel *)inModel; + TRAinstance *here; /* loop through all the transmission line models */ for( ; model != NULL; model = model->TRAnextModel ) { diff --git a/src/spicelib/devices/tra/tratrunc.c b/src/spicelib/devices/tra/tratrunc.c index 95be3f0f6..78eb1997d 100644 --- a/src/spicelib/devices/tra/tratrunc.c +++ b/src/spicelib/devices/tra/tratrunc.c @@ -16,12 +16,12 @@ Author: 1985 Thomas L. Quarles int TRAtrunc(inModel,ckt,timeStep) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; double *timeStep; { - register TRAmodel *model = (TRAmodel *)inModel; - register TRAinstance *here; + TRAmodel *model = (TRAmodel *)inModel; + TRAinstance *here; double v1,v2,v3,v4; double v5,v6,d1,d2,d3,d4; double tmp; diff --git a/src/spicelib/devices/urc/Makefile.am b/src/spicelib/devices/urc/Makefile.am index bee09e353..b5de9045c 100644 --- a/src/spicelib/devices/urc/Makefile.am +++ b/src/spicelib/devices/urc/Makefile.am @@ -2,19 +2,21 @@ pkglib_LTLIBRARIES = liburc.la -liburc_la_SOURCES = \ - urc.c \ - urcask.c \ - urcdefs.h \ - urcdel.c \ - urcdest.c \ - urcext.h \ - urcitf.h \ - urcmask.c \ - urcmdel.c \ - urcmpar.c \ - urcparam.c \ - urcsetup.c +liburc_la_SOURCES = \ + urc.c \ + urcask.c \ + urcdefs.h \ + urcdel.c \ + urcdest.c \ + urcext.h \ + urcinit.c \ + urcinit.h \ + urcitf.h \ + urcmask.c \ + urcmdel.c \ + urcmpar.c \ + urcparam.c \ + urcsetup.c diff --git a/src/spicelib/devices/urc/urcext.h b/src/spicelib/devices/urc/urcext.h index 0b58b9ade..4cfe4172c 100644 --- a/src/spicelib/devices/urc/urcext.h +++ b/src/spicelib/devices/urc/urcext.h @@ -2,8 +2,9 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles **********/ +#ifndef _URCEXT_H +#define _URCEXT_H -#ifdef __STDC__ extern int URCask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); extern int URCdelete(GENmodel*,IFuid,GENinstance**); extern void URCdestroy(GENmodel**); @@ -13,14 +14,5 @@ extern int URCmParam(int,IFvalue*,GENmodel*); extern int URCparam(int,IFvalue*,GENinstance*,IFvalue*); extern int URCsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int URCunsetup(GENmodel*,CKTcircuit*); -#else /* stdc */ -extern int URCask(); -extern int URCdelete(); -extern void URCdestroy(); -extern int URCmAsk(); -extern int URCmDelete(); -extern int URCmParam(); -extern int URCparam(); -extern int URCsetup(); -extern int URCunsetup(); -#endif /* stdc */ + +#endif diff --git a/src/spicelib/devices/urc/urcitf.h b/src/spicelib/devices/urc/urcitf.h index ce9cefeb6..8cd534c75 100644 --- a/src/spicelib/devices/urc/urcitf.h +++ b/src/spicelib/devices/urc/urcitf.h @@ -1,76 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_urc - #ifndef DEV_URC #define DEV_URC -#include "urcext.h" -extern IFparm URCpTable[ ]; -extern IFparm URCmPTable[ ]; -extern char *URCnames[ ]; -extern int URCpTSize; -extern int URCmPTSize; -extern int URCnSize; -extern int URCiSize; -extern int URCmSize; - -SPICEdev URCinfo = { - { - "URC", /* MUST precede both resistors and capacitors */ - "Uniform R.C. line", - - &URCnSize, - &URCnSize, - URCnames, - - &URCpTSize, - URCpTable, - - &URCmPTSize, - URCmPTable, - 0 - }, - - URCparam, - URCmParam, - NULL, - URCsetup, - URCunsetup, - URCsetup, - NULL, - NULL, - NULL, - NULL, - NULL, - URCdestroy, -#ifdef DELETES - URCmDelete, - URCdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - NULL, - URCask, - URCmAsk, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, /* DISTO */ - NULL, /* NOISE */ - - &URCiSize, - &URCmSize - -}; - +extern SPICEdev *get_urc_info(void); #endif -#endif diff --git a/src/spicelib/devices/urc/urcmpar.c b/src/spicelib/devices/urc/urcmpar.c index cc352923a..b7471f4f8 100644 --- a/src/spicelib/devices/urc/urcmpar.c +++ b/src/spicelib/devices/urc/urcmpar.c @@ -19,7 +19,7 @@ URCmParam(param,value,inModel) IFvalue *value; GENmodel *inModel; { - register URCmodel *model = (URCmodel *)inModel; + URCmodel *model = (URCmodel *)inModel; switch(param) { case URC_MOD_K: model->URCk = value->rValue; diff --git a/src/spicelib/devices/urc/urcsetup.c b/src/spicelib/devices/urc/urcsetup.c index a65970506..eb73b490b 100644 --- a/src/spicelib/devices/urc/urcsetup.c +++ b/src/spicelib/devices/urc/urcsetup.c @@ -22,8 +22,8 @@ URCsetup(matrix,inModel,ckt,state) /* create the resistors/capacitors used to model the URC */ { - register URCmodel *model = (URCmodel *)inModel; - register URCinstance *here; + URCmodel *model = (URCmodel *)inModel; + URCinstance *here; int rtype; int ctype; int dtype; @@ -284,60 +284,63 @@ URCunsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM - IFuid varUid; - int error; - URCinstance *here; - URCmodel *model = (URCmodel *) inModel; - GENinstance *in; - GENmodel *modfast; - int type; + IFuid varUid; + int error; + URCinstance *here; + URCmodel *model = (URCmodel *) inModel; + GENinstance *in; + GENmodel *modfast; + int type; - /* Delete models, devices, and intermediate nodes; - */ + /* Delete models, devices, and intermediate nodes; */ - for ( ; model; model = model->URCnextModel) { - for (here = model->URCinstances; here; - here = here->URCnextInstance) - { - if(model->URCisPerLGiven) { - /* Diodes */ - error = (*(SPfrontEnd->IFnewUid))(ckt,&varUid,here->URCname, - "diodemod",UID_MODEL,(void **)NULL); - } else { - /* Capacitors */ - error = (*(SPfrontEnd->IFnewUid))((void *)ckt,&varUid, - here->URCname, "capmod",UID_MODEL,(void **)NULL); - } - if (error && error != E_EXISTS) - return error; + for ( ; model; model = model->URCnextModel) { + for (here = model->URCinstances; here; + here = here->URCnextInstance) + { + if(model->URCisPerLGiven) { + /* Diodes */ + error = (*(SPfrontEnd->IFnewUid))(ckt, &varUid, + here->URCname, + "diodemod", + UID_MODEL, + (void **)NULL); + } else { + /* Capacitors */ + error = (*(SPfrontEnd->IFnewUid))((void *)ckt, &varUid, + here->URCname, + "capmod", + UID_MODEL, + (void **)NULL); + } + if (error && error != E_EXISTS) + return error; - modfast = NULL; - type = -1; - error = CKTfndMod(ckt, &type, (void **) &modfast, varUid); - if (error) - return error; + modfast = NULL; + type = -1; + error = CKTfndMod(ckt, &type, (void **) &modfast, varUid); + if (error) + return error; - for (in = modfast->GENinstances; in; in = in->GENnextInstance) - CKTdltNNum(ckt, in->GENnode1); + for (in = modfast->GENinstances; in; in = in->GENnextInstance) + CKTdltNNum(ckt, in->GENnode1); - CKTdltMod(ckt, modfast); /* Does the elements too */ + CKTdltMod(ckt, modfast); /* Does the elements too */ - /* Resistors */ - error = (*(SPfrontEnd->IFnewUid))(ckt,&varUid,here->URCname, - "resmod",UID_MODEL,(void **)NULL); - if (error && error != E_EXISTS) - return error; + /* Resistors */ + error = (*(SPfrontEnd->IFnewUid))(ckt,&varUid,here->URCname, + "resmod",UID_MODEL,(void **)NULL); + if (error && error != E_EXISTS) + return error; - modfast = NULL; - type = -1; - error = CKTfndMod(ckt, &type, (void **) &modfast, varUid); - if (error) - return error; + modfast = NULL; + type = -1; + error = CKTfndMod(ckt, &type, (void **) &modfast, varUid); + if (error) + return error; - CKTdltMod(ckt, modfast); + CKTdltMod(ckt, modfast); } } -#endif return OK; } diff --git a/src/spicelib/devices/vccs/Makefile.am b/src/spicelib/devices/vccs/Makefile.am index 96dd6506e..34a64e6ef 100644 --- a/src/spicelib/devices/vccs/Makefile.am +++ b/src/spicelib/devices/vccs/Makefile.am @@ -2,23 +2,25 @@ pkglib_LTLIBRARIES = libvccs.la -libvccs_la_SOURCES = \ - vccs.c \ - vccsask.c \ - vccsdefs.h \ - vccsdel.c \ - vccsdest.c \ - vccsext.h \ - vccsitf.h \ - vccsload.c \ - vccsmdel.c \ - vccspar.c \ - vccspzld.c \ - vccssacl.c \ - vccsset.c \ - vccssld.c \ - vccssprt.c \ - vccssset.c +libvccs_la_SOURCES = \ + vccs.c \ + vccsask.c \ + vccsdefs.h \ + vccsdel.c \ + vccsdest.c \ + vccsext.h \ + vccsinit.c \ + vccsinit.h \ + vccsitf.h \ + vccsload.c \ + vccsmdel.c \ + vccspar.c \ + vccspzld.c \ + vccssacl.c \ + vccsset.c \ + vccssld.c \ + vccssprt.c \ + vccssset.c diff --git a/src/spicelib/devices/vccs/vccsitf.h b/src/spicelib/devices/vccs/vccsitf.h index 2850a8846..2427acb4d 100644 --- a/src/spicelib/devices/vccs/vccsitf.h +++ b/src/spicelib/devices/vccs/vccsitf.h @@ -1,88 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_vccs - #ifndef DEV_VCCS #define DEV_VCCS -#include "vccsext.h" -extern IFparm VCCSpTable[ ]; -extern char *VCCSnames[ ]; -extern int VCCSpTSize; -extern int VCCSnSize; -extern int VCCSiSize; -extern int VCCSmSize; - -SPICEdev VCCSinfo = { - { - "VCCS", - "Voltage controlled current source", - - &VCCSnSize, - &VCCSnSize, - VCCSnames, - - &VCCSpTSize, - VCCSpTable, - - 0, - NULL, - DEV_DEFAULT - }, - - VCCSparam, - NULL, - VCCSload, - VCCSsetup, - NULL, - VCCSsetup, - NULL, - NULL, - NULL, - VCCSload, /* ac and normal loads are identical */ - NULL, - VCCSdestroy, -#ifdef DELETES - VCCSmDelete, - VCCSdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - NULL, - VCCSask, - NULL, -#ifdef AN_pz - VCCSpzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ - NULL, -#ifdef AN_sense2 - VCCSsSetup, - VCCSsLoad, - NULL, - VCCSsAcLoad, - VCCSsPrint, - NULL, -#else /* AN_sense2 */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -#endif /* AN_sense2 */ - NULL, /* DISTO */ - NULL, /* NOISE */ - - &VCCSiSize, - &VCCSmSize - - -}; - +extern SPICEdev *get_vccs_info(void); #endif -#endif diff --git a/src/spicelib/devices/vccs/vccsload.c b/src/spicelib/devices/vccs/vccsload.c index 73653b240..8d2ced769 100644 --- a/src/spicelib/devices/vccs/vccsload.c +++ b/src/spicelib/devices/vccs/vccsload.c @@ -22,8 +22,8 @@ VCCSload(inModel,ckt) * sparse matrix previously provided */ { - register VCCSmodel *model = (VCCSmodel *)inModel; - register VCCSinstance *here; + VCCSmodel *model = (VCCSmodel *)inModel; + VCCSinstance *here; /* loop through all the source models */ for( ; model != NULL; model = model->VCCSnextModel ) { diff --git a/src/spicelib/devices/vccs/vccspzld.c b/src/spicelib/devices/vccs/vccspzld.c index 26d713976..b5ba89d6a 100644 --- a/src/spicelib/devices/vccs/vccspzld.c +++ b/src/spicelib/devices/vccs/vccspzld.c @@ -24,8 +24,8 @@ VCCSpzLoad(inModel,ckt,s) * sparse matrix previously provided */ { - register VCCSmodel *model = (VCCSmodel *)inModel; - register VCCSinstance *here; + VCCSmodel *model = (VCCSmodel *)inModel; + VCCSinstance *here; /* loop through all the source models */ for( ; model != NULL; model = model->VCCSnextModel ) { diff --git a/src/spicelib/devices/vccs/vccssacl.c b/src/spicelib/devices/vccs/vccssacl.c index 02ff2c6cf..aa56d45e2 100644 --- a/src/spicelib/devices/vccs/vccssacl.c +++ b/src/spicelib/devices/vccs/vccssacl.c @@ -23,8 +23,8 @@ VCCSsAcLoad(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { - register VCCSmodel *model = (VCCSmodel *)inModel; - register VCCSinstance *here; + VCCSmodel *model = (VCCSmodel *)inModel; + VCCSinstance *here; double vc; double ivc; diff --git a/src/spicelib/devices/vccs/vccsset.c b/src/spicelib/devices/vccs/vccsset.c index 610c388e3..c4c21729e 100644 --- a/src/spicelib/devices/vccs/vccsset.c +++ b/src/spicelib/devices/vccs/vccsset.c @@ -21,13 +21,13 @@ Author: 1985 Thomas L. Quarles /*ARGSUSED*/ int VCCSsetup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; CKTcircuit *ckt; int *states; { - register VCCSmodel *model = (VCCSmodel *)inModel; - register VCCSinstance *here; + VCCSmodel *model = (VCCSmodel *)inModel; + VCCSinstance *here; /* loop through all the current source models */ for( ; model != NULL; model = model->VCCSnextModel ) { diff --git a/src/spicelib/devices/vccs/vccssld.c b/src/spicelib/devices/vccs/vccssld.c index 664b46213..c3970f16d 100644 --- a/src/spicelib/devices/vccs/vccssld.c +++ b/src/spicelib/devices/vccs/vccssld.c @@ -23,8 +23,8 @@ VCCSsLoad(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { - register VCCSmodel *model = (VCCSmodel *)inModel; - register VCCSinstance *here; + VCCSmodel *model = (VCCSmodel *)inModel; + VCCSinstance *here; double vc; /* loop through all the source models */ diff --git a/src/spicelib/devices/vccs/vccssprt.c b/src/spicelib/devices/vccs/vccssprt.c index ac09f105c..c0a1db85a 100644 --- a/src/spicelib/devices/vccs/vccssprt.c +++ b/src/spicelib/devices/vccs/vccssprt.c @@ -21,10 +21,10 @@ Author: 1985 Thomas L. Quarles void VCCSsPrint(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register VCCSmodel *model = (VCCSmodel *)inModel; - register VCCSinstance *here; + VCCSmodel *model = (VCCSmodel *)inModel; + VCCSinstance *here; printf("VOLTAGE CONTROLLED CURRENT SOURCES-----------------\n"); /* loop through all the source models */ diff --git a/src/spicelib/devices/vccs/vccssset.c b/src/spicelib/devices/vccs/vccssset.c index 259032ca4..7271c79b6 100644 --- a/src/spicelib/devices/vccs/vccssset.c +++ b/src/spicelib/devices/vccs/vccssset.c @@ -20,11 +20,11 @@ Author: 1985 Thomas L. Quarles int VCCSsSetup(info,inModel) - register SENstruct *info; + SENstruct *info; GENmodel *inModel; { - register VCCSmodel *model = (VCCSmodel *)inModel; - register VCCSinstance *here; + VCCSmodel *model = (VCCSmodel *)inModel; + VCCSinstance *here; /* loop through all the current source models */ for( ; model != NULL; model = model->VCCSnextModel ) { diff --git a/src/spicelib/devices/vcvs/Makefile.am b/src/spicelib/devices/vcvs/Makefile.am index 50f021cd2..caff738c7 100644 --- a/src/spicelib/devices/vcvs/Makefile.am +++ b/src/spicelib/devices/vcvs/Makefile.am @@ -2,24 +2,26 @@ pkglib_LTLIBRARIES = libvcvs.la -libvcvs_la_SOURCES = \ - vcvs.c \ - vcvsask.c \ - vcvsdefs.h \ - vcvsdel.c \ - vcvsdest.c \ - vcvsext.h \ - vcvsfbr.c \ - vcvsitf.h \ - vcvsload.c \ - vcvsmdel.c \ - vcvspar.c \ - vcvspzld.c \ - vcvssacl.c \ - vcvsset.c \ - vcvssld.c \ - vcvssprt.c \ - vcvssset.c +libvcvs_la_SOURCES = \ + vcvs.c \ + vcvsask.c \ + vcvsdefs.h \ + vcvsdel.c \ + vcvsdest.c \ + vcvsext.h \ + vcvsfbr.c \ + vcvsinit.c \ + vcvsinit.h \ + vcvsitf.h \ + vcvsload.c \ + vcvsmdel.c \ + vcvspar.c \ + vcvspzld.c \ + vcvssacl.c \ + vcvsset.c \ + vcvssld.c \ + vcvssprt.c \ + vcvssset.c diff --git a/src/spicelib/devices/vcvs/vcvsfbr.c b/src/spicelib/devices/vcvs/vcvsfbr.c index 35620f245..be8eead72 100644 --- a/src/spicelib/devices/vcvs/vcvsfbr.c +++ b/src/spicelib/devices/vcvs/vcvsfbr.c @@ -16,12 +16,12 @@ Author: 1985 Thomas L. Quarles int VCVSfindBr(ckt,inModel,name) - register CKTcircuit *ckt; + CKTcircuit *ckt; GENmodel *inModel; - register IFuid name; + IFuid name; { - register VCVSmodel *model = (VCVSmodel *)inModel; - register VCVSinstance *here; + VCVSmodel *model = (VCVSmodel *)inModel; + VCVSinstance *here; int error; CKTnode *tmp; diff --git a/src/spicelib/devices/vcvs/vcvsitf.h b/src/spicelib/devices/vcvs/vcvsitf.h index 14475dc8b..d812d482e 100644 --- a/src/spicelib/devices/vcvs/vcvsitf.h +++ b/src/spicelib/devices/vcvs/vcvsitf.h @@ -1,87 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_vcvs - #ifndef DEV_VCVS #define DEV_VCVS -#include "vcvsext.h" -extern IFparm VCVSpTable[ ]; -extern char *VCVSnames[ ]; -extern int VCVSpTSize; -extern int VCVSnSize; -extern int VCVSiSize; -extern int VCVSmSize; - -SPICEdev VCVSinfo = { - { - "VCVS", - "Voltage controlled voltage source", - - &VCVSnSize, - &VCVSnSize, - VCVSnames, - - &VCVSpTSize, - VCVSpTable, - - 0, - NULL, - DEV_DEFAULT - }, - - VCVSparam, - NULL, - VCVSload, - VCVSsetup, - VCVSunsetup, - VCVSsetup, - NULL, - NULL, - VCVSfindBr, - VCVSload, /* AC and normal loads are identical */ - NULL, - VCVSdestroy, -#ifdef DELETES - VCVSmDelete, - VCVSdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - NULL, - VCVSask, - NULL, -#ifdef AN_pz - VCVSpzLoad, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ - NULL, -#ifdef AN_sense2 - VCVSsSetup, - VCVSsLoad, - NULL, - VCVSsAcLoad, - VCVSsPrint, - NULL, -#else /* AN_sense2 */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -#endif /* AN_sense2 */ - NULL, /* DISTO */ - NULL, /* NOISE */ - - &VCVSiSize, - &VCVSmSize - -}; - +SPICEdev *get_vcvs_info(void); #endif -#endif diff --git a/src/spicelib/devices/vcvs/vcvsload.c b/src/spicelib/devices/vcvs/vcvsload.c index dbe38d850..b8103011c 100644 --- a/src/spicelib/devices/vcvs/vcvsload.c +++ b/src/spicelib/devices/vcvs/vcvsload.c @@ -22,8 +22,8 @@ VCVSload(inModel,ckt) * sparse matrix previously provided */ { - register VCVSmodel *model = (VCVSmodel *)inModel; - register VCVSinstance *here; + VCVSmodel *model = (VCVSmodel *)inModel; + VCVSinstance *here; /* loop through all the voltage source models */ for( ; model != NULL; model = model->VCVSnextModel ) { diff --git a/src/spicelib/devices/vcvs/vcvspzld.c b/src/spicelib/devices/vcvs/vcvspzld.c index 8e890aba6..2a2191b7b 100644 --- a/src/spicelib/devices/vcvs/vcvspzld.c +++ b/src/spicelib/devices/vcvs/vcvspzld.c @@ -24,8 +24,8 @@ VCVSpzLoad(inModel,ckt,s) * sparse matrix previously provided */ { - register VCVSmodel *model = (VCVSmodel *)inModel; - register VCVSinstance *here; + VCVSmodel *model = (VCVSmodel *)inModel; + VCVSinstance *here; /* loop through all the voltage source models */ for( ; model != NULL; model = model->VCVSnextModel ) { diff --git a/src/spicelib/devices/vcvs/vcvssacl.c b/src/spicelib/devices/vcvs/vcvssacl.c index c7d840ebb..d094038c5 100644 --- a/src/spicelib/devices/vcvs/vcvssacl.c +++ b/src/spicelib/devices/vcvs/vcvssacl.c @@ -22,8 +22,8 @@ VCVSsAcLoad(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { - register VCVSmodel *model = (VCVSmodel *)inModel; - register VCVSinstance *here; + VCVSmodel *model = (VCVSmodel *)inModel; + VCVSinstance *here; double vc; double ivc; diff --git a/src/spicelib/devices/vcvs/vcvsset.c b/src/spicelib/devices/vcvs/vcvsset.c index 0a995992a..e58184390 100644 --- a/src/spicelib/devices/vcvs/vcvsset.c +++ b/src/spicelib/devices/vcvs/vcvsset.c @@ -18,13 +18,13 @@ Author: 1985 Thomas L. Quarles /*ARGSUSED*/ int VCVSsetup(matrix,inModel,ckt,states) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int *states; { - register VCVSmodel *model = (VCVSmodel *)inModel; - register VCVSinstance *here; + VCVSmodel *model = (VCVSmodel *)inModel; + VCVSinstance *here; int error; CKTnode *tmp; @@ -63,7 +63,6 @@ VCVSunsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM VCVSmodel *model; VCVSinstance *here; @@ -79,6 +78,5 @@ VCVSunsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/vcvs/vcvssld.c b/src/spicelib/devices/vcvs/vcvssld.c index f87d168af..ef2a62fd2 100644 --- a/src/spicelib/devices/vcvs/vcvssld.c +++ b/src/spicelib/devices/vcvs/vcvssld.c @@ -22,8 +22,8 @@ VCVSsLoad(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { - register VCVSmodel *model = (VCVSmodel *)inModel; - register VCVSinstance *here; + VCVSmodel *model = (VCVSmodel *)inModel; + VCVSinstance *here; double vc; /* loop through all the voltage source models */ diff --git a/src/spicelib/devices/vcvs/vcvssprt.c b/src/spicelib/devices/vcvs/vcvssprt.c index cb054cc0a..52926e957 100644 --- a/src/spicelib/devices/vcvs/vcvssprt.c +++ b/src/spicelib/devices/vcvs/vcvssprt.c @@ -20,10 +20,10 @@ Author: 1985 Thomas L. Quarles void VCVSsPrint(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register VCVSmodel *model = (VCVSmodel *)inModel; - register VCVSinstance *here; + VCVSmodel *model = (VCVSmodel *)inModel; + VCVSinstance *here; printf("VOLTAGE CONTROLLED VOLTAGE SOURCES-----------------\n"); /* loop through all the voltage source models */ diff --git a/src/spicelib/devices/vcvs/vcvssset.c b/src/spicelib/devices/vcvs/vcvssset.c index df44a0580..35827a8fc 100644 --- a/src/spicelib/devices/vcvs/vcvssset.c +++ b/src/spicelib/devices/vcvs/vcvssset.c @@ -20,11 +20,11 @@ Author: 1985 Thomas L. Quarles int VCVSsSetup(info,inModel) - register SENstruct *info; + SENstruct *info; GENmodel *inModel; { - register VCVSmodel *model = (VCVSmodel *)inModel; - register VCVSinstance *here; + VCVSmodel *model = (VCVSmodel *)inModel; + VCVSinstance *here; /* loop through all the voltage source models */ for( ; model != NULL; model = model->VCVSnextModel ) { diff --git a/src/spicelib/devices/vsrc/Makefile.am b/src/spicelib/devices/vsrc/Makefile.am index e3eb3a318..246577fc0 100644 --- a/src/spicelib/devices/vsrc/Makefile.am +++ b/src/spicelib/devices/vsrc/Makefile.am @@ -2,24 +2,26 @@ pkglib_LTLIBRARIES = libvsrc.la -libvsrc_la_SOURCES = \ - vsrc.c \ - vsrcacct.c \ - vsrcacld.c \ - vsrcask.c \ - vsrcdefs.h \ - vsrcdel.c \ - vsrcdest.c \ - vsrcext.h \ - vsrcfbr.c \ - vsrcitf.h \ - vsrcload.c \ - vsrcmdel.c \ - vsrcpar.c \ - vsrcpzld.c \ - vsrcpzs.c \ - vsrcset.c \ - vsrctemp.c +libvsrc_la_SOURCES = \ + vsrc.c \ + vsrcacct.c \ + vsrcacld.c \ + vsrcask.c \ + vsrcdefs.h \ + vsrcdel.c \ + vsrcdest.c \ + vsrcext.h \ + vsrcfbr.c \ + vsrcinit.c \ + vsrcinit.h \ + vsrcitf.h \ + vsrcload.c \ + vsrcmdel.c \ + vsrcpar.c \ + vsrcpzld.c \ + vsrcpzs.c \ + vsrcset.c \ + vsrctemp.c diff --git a/src/spicelib/devices/vsrc/vsrcacct.c b/src/spicelib/devices/vsrc/vsrcacct.c index a59765eb5..b14b716a4 100644 --- a/src/spicelib/devices/vsrc/vsrcacct.c +++ b/src/spicelib/devices/vsrc/vsrcacct.c @@ -13,13 +13,13 @@ Author: 1985 Thomas L. Quarles int VSRCaccept(ckt,inModel) - register CKTcircuit *ckt; + CKTcircuit *ckt; GENmodel *inModel; /* set up the breakpoint table. */ { - register VSRCmodel *model = (VSRCmodel *)inModel; - register VSRCinstance *here; + VSRCmodel *model = (VSRCmodel *)inModel; + VSRCinstance *here; int error; /* loop through all the voltage source models */ @@ -148,7 +148,7 @@ VSRCaccept(ckt,inModel) } break; case PWL: { - register int i; + int i; if(ckt->CKTtime < *(here->VSRCcoeffs)) { if(ckt->CKTbreak) { error = CKTsetBreak(ckt,*(here->VSRCcoeffs)); diff --git a/src/spicelib/devices/vsrc/vsrcacld.c b/src/spicelib/devices/vsrc/vsrcacld.c index f8f25376f..dffa4aba7 100644 --- a/src/spicelib/devices/vsrc/vsrcacld.c +++ b/src/spicelib/devices/vsrc/vsrcacld.c @@ -16,10 +16,10 @@ Author: 1985 Thomas L. Quarles int VSRCacLoad(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; { - register VSRCmodel *model = (VSRCmodel *)inModel; - register VSRCinstance *here; + VSRCmodel *model = (VSRCmodel *)inModel; + VSRCinstance *here; for( ; model != NULL; model = model->VSRCnextModel ) { diff --git a/src/spicelib/devices/vsrc/vsrcfbr.c b/src/spicelib/devices/vsrc/vsrcfbr.c index b2ecf433e..9edcbeb50 100644 --- a/src/spicelib/devices/vsrc/vsrcfbr.c +++ b/src/spicelib/devices/vsrc/vsrcfbr.c @@ -15,12 +15,12 @@ Author: 1985 Thomas L. Quarles int VSRCfindBr(ckt,inModel,name) - register CKTcircuit *ckt; + CKTcircuit *ckt; GENmodel *inModel; - register IFuid name; + IFuid name; { - register VSRCmodel *model = (VSRCmodel *)inModel; - register VSRCinstance *here; + VSRCmodel *model = (VSRCmodel *)inModel; + VSRCinstance *here; int error; CKTnode *tmp; diff --git a/src/spicelib/devices/vsrc/vsrcitf.h b/src/spicelib/devices/vsrc/vsrcitf.h index 4aeda0056..6792ee39d 100644 --- a/src/spicelib/devices/vsrc/vsrcitf.h +++ b/src/spicelib/devices/vsrc/vsrcitf.h @@ -1,77 +1,9 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. **********/ -#ifdef DEV_vsrc - #ifndef DEV_VSRC #define DEV_VSRC -#include "vsrcext.h" -extern IFparm VSRCpTable[ ]; -extern char *VSRCnames[ ]; -extern int VSRCpTSize; -extern int VSRCnSize; -extern int VSRCiSize; -extern int VSRCmSize; - -SPICEdev VSRCinfo = { - { - "Vsource", - "Independent voltage source", - - &VSRCnSize, - &VSRCnSize, - VSRCnames, - - &VSRCpTSize, - VSRCpTable, - - 0, - NULL, - DEV_DEFAULT - }, - - VSRCparam, - NULL, - VSRCload, - VSRCsetup, - VSRCunsetup, -#ifdef AN_pz - VSRCpzSetup, -#else /* AN_pz */ - NULL, -#endif /* AN_pz */ - VSRCtemp, - NULL, - VSRCfindBr, - VSRCacLoad, - VSRCaccept, - VSRCdestroy, -#ifdef DELETES - VSRCmDelete, - VSRCdelete, -#else /* DELETES */ - NULL, - NULL, -#endif /* DELETES */ - NULL, - VSRCask, - NULL, - VSRCpzLoad, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, /* DISTO */ - NULL, /* NOISE */ - - &VSRCiSize, - &VSRCmSize -}; - +SPICEdev *get_vsrc_info(void); #endif -#endif diff --git a/src/spicelib/devices/vsrc/vsrcload.c b/src/spicelib/devices/vsrc/vsrcload.c index b80d701be..2da813789 100644 --- a/src/spicelib/devices/vsrc/vsrcload.c +++ b/src/spicelib/devices/vsrc/vsrcload.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ #include "ngspice.h" @@ -14,14 +15,15 @@ Author: 1985 Thomas L. Quarles int VSRCload(inModel,ckt) GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; /* actually load the current voltage value into the * sparse matrix previously provided */ { - register VSRCmodel *model = (VSRCmodel *)inModel; - register VSRCinstance *here; + VSRCmodel *model = (VSRCmodel *)inModel; + VSRCinstance *here; double time; + double value; /* loop through all the voltage source models */ for( ; model != NULL; model = model->VSRCnextModel ) { @@ -38,8 +40,7 @@ VSRCload(inModel,ckt) if( (ckt->CKTmode & (MODEDCOP | MODEDCTRANCURVE)) && here->VSRCdcGiven ) { /* grab dc value */ - *(ckt->CKTrhs + (here->VSRCbranch)) += ckt->CKTsrcFact * - here->VSRCdcValue; + value = ckt->CKTsrcFact * here->VSRCdcValue; } else { if(ckt->CKTmode & (MODEDC)) { time = 0; @@ -49,7 +50,7 @@ VSRCload(inModel,ckt) /* use the transient functions */ switch(here->VSRCfunctionType) { default: { /* no function specified: use the DC value */ - *(ckt->CKTrhs + (here->VSRCbranch)) += here->VSRCdcValue; + value = here->VSRCdcValue; break; } @@ -82,15 +83,13 @@ VSRCload(inModel,ckt) time -= basetime; } if (time <= 0 || time >= TR + PW + TF) { - ckt->CKTrhs[here->VSRCbranch] += V1; + value = V1; } else if (time >= TR && time <= TR + PW) { - ckt->CKTrhs[here->VSRCbranch] += V2; + value = V2; } else if (time > 0 && time < TR) { - ckt->CKTrhs[here->VSRCbranch] += - V1 + (V2 - V1) * (time) / TR; + value = V1 + (V2 - V1) * (time) / TR; } else { /* time > TR + PW && < TR + PW + TF */ - ckt->CKTrhs[here->VSRCbranch] += - V2 + (V1 - V2) * (time - (TR + PW)) / TF; + value = V2 + (V1 - V2) * (time - (TR + PW)) / TF; } } @@ -105,12 +104,10 @@ VSRCload(inModel,ckt) #define THETA ((here->VSRCfunctionOrder >=5)?(*(here->VSRCcoeffs+4)):(0.0)) time -= TD; if (time <= 0) { - *(ckt->CKTrhs + (here->VSRCbranch)) += VO; + value = VO; } else { - *(ckt->CKTrhs + (here->VSRCbranch)) += - VO + VA * sin(FREQ * time * 2.0 * M_PI) * + value = VO + VA * sin(FREQ * time * 2.0 * M_PI) * exp(-(time*THETA)); - /* 2PI to convert from hz to radians/sec*/ } #undef VO #undef VA @@ -136,13 +133,11 @@ VSRCload(inModel,ckt) td1 = TD1; td2 = TD2; if(time <= td1) { - *(ckt->CKTrhs + (here->VSRCbranch)) += V1; + value = V1; } else if (time <= td2) { - *(ckt->CKTrhs + (here->VSRCbranch)) += - V1 + (V2-V1)*(1-exp(-(time-td1)/TAU1)); + value = V1 + (V2-V1)*(1-exp(-(time-td1)/TAU1)); } else { - *(ckt->CKTrhs + (here->VSRCbranch)) += - V1 + (V2-V1)*(1-exp(-(time-td1)/TAU1)) + + value = V1 + (V2-V1)*(1-exp(-(time-td1)/TAU1)) + (V1-V2)*(1-exp(-(time-td2)/TAU2)) ; } #undef V1 @@ -163,9 +158,9 @@ VSRCload(inModel,ckt) 0.0) #define FS (((here->VSRCfunctionOrder >=5) && (*(here->VSRCcoeffs+4)))? \ (*(here->VSRCcoeffs+4)):(1/ckt->CKTfinalTime)) - *(ckt->CKTrhs + (here->VSRCbranch)) += VO + VA * - sin((2 * 3.141592654 * FC * time) + - MDI * sin(2 * 3.141592654 * FS * time)); + value = VO + VA * + sin((2 * 3.141592654 * FC * time) + + MDI * sin(2 * 3.141592654 * FS * time)); #undef VO #undef VA #undef FC @@ -175,18 +170,17 @@ VSRCload(inModel,ckt) break; case PWL: { - register int i; + int i; double foo; if(time < *(here->VSRCcoeffs)) { foo = *(here->VSRCcoeffs + 1) ; - *(ckt->CKTrhs + (here->VSRCbranch)) += foo; + value = foo; goto loadDone; } for(i=0;i<(here->VSRCfunctionOrder/2)-1;i++) { if((*(here->VSRCcoeffs+2*i)==time)) { foo = *(here->VSRCcoeffs+2*i+1); - *(ckt->CKTrhs + (here->VSRCbranch)) += - foo; + value = foo; goto loadDone; } else if((*(here->VSRCcoeffs+2*i)VSRCcoeffs+2*(i+1)) >time)) { @@ -196,18 +190,19 @@ VSRCload(inModel,ckt) *(here->VSRCcoeffs+2*i))) * (*(here->VSRCcoeffs+2*i+3) - *(here->VSRCcoeffs+2*i+1))); - *(ckt->CKTrhs + (here->VSRCbranch)) += - foo; + value = foo; goto loadDone; } } foo = *(here->VSRCcoeffs+ here->VSRCfunctionOrder-1) ; - *(ckt->CKTrhs + (here->VSRCbranch)) += foo; + value = foo; break; } } } -loadDone: ; +loadDone: +if (ckt->CKTmode & MODETRANOP) value *= ckt->CKTsrcFact; + *(ckt->CKTrhs + (here->VSRCbranch)) += value; } } return(OK); diff --git a/src/spicelib/devices/vsrc/vsrcpar.c b/src/spicelib/devices/vsrc/vsrcpar.c index b7447a895..37d0e90f8 100644 --- a/src/spicelib/devices/vsrc/vsrcpar.c +++ b/src/spicelib/devices/vsrc/vsrcpar.c @@ -1,6 +1,7 @@ /********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes **********/ /* */ @@ -21,6 +22,7 @@ VSRCparam(param,value,inst,select) GENinstance *inst; IFvalue *select; { + int i; VSRCinstance *here = (VSRCinstance *)inst; switch(param) { case VSRC_DC: @@ -79,6 +81,15 @@ VSRCparam(param,value,inst,select) here->VSRCcoeffs = value->v.vec.rVec; here->VSRCfunctionOrder = value->v.numValue; here->VSRCcoeffsGiven = TRUE; + + for(i=0;i<(here->VSRCfunctionOrder/2)-1;i++) { + if(*(here->VSRCcoeffs+2*(i+1))<=*(here->VSRCcoeffs+2*i)) { + fprintf(stderr, "Warning : voltage source %s", + here->VSRCname); + fprintf(stderr, " has non-increasing PWL time points.\n"); + } + } + break; case VSRC_SFFM: here->VSRCfunctionType = SFFM; diff --git a/src/spicelib/devices/vsrc/vsrcpzld.c b/src/spicelib/devices/vsrc/vsrcpzld.c index 7041460f4..84f4f9791 100644 --- a/src/spicelib/devices/vsrc/vsrcpzld.c +++ b/src/spicelib/devices/vsrc/vsrcpzld.c @@ -18,8 +18,8 @@ VSRCpzLoad(inModel,ckt,s) CKTcircuit *ckt; SPcomplex *s; { - register VSRCmodel *model = (VSRCmodel *)inModel; - register VSRCinstance *here; + VSRCmodel *model = (VSRCmodel *)inModel; + VSRCinstance *here; for( ; model != NULL; model = model->VSRCnextModel ) { diff --git a/src/spicelib/devices/vsrc/vsrcpzs.c b/src/spicelib/devices/vsrc/vsrcpzs.c index e1161db40..a613545bc 100644 --- a/src/spicelib/devices/vsrc/vsrcpzs.c +++ b/src/spicelib/devices/vsrc/vsrcpzs.c @@ -11,19 +11,14 @@ Author: 1985 Thomas L. Quarles #include "sperror.h" #include "suffix.h" -/* ARGSUSED */ +/* load the voltage source structure with those pointers needed later + * for fast matrix loading */ int -VSRCpzSetup(matrix,inModel,ckt,state) - register SMPmatrix *matrix; - GENmodel *inModel; - register CKTcircuit *ckt; - int *state; - /* load the voltage source structure with those pointers needed later - * for fast matrix loading - */ +VSRCpzSetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, + int *state) { - register VSRCmodel *model = (VSRCmodel *)inModel; - register VSRCinstance *here; + VSRCmodel *model = (VSRCmodel *)inModel; + VSRCinstance *here; CKTnode *tmp; int error; @@ -32,9 +27,9 @@ VSRCpzSetup(matrix,inModel,ckt,state) /* loop through all the instances of the model */ for (here = model->VSRCinstances; here != NULL ; - here=here->VSRCnextInstance) { + here = here->VSRCnextInstance) { - if(here->VSRCbranch == 0) { + if (here->VSRCbranch == 0) { error = CKTmkCur(ckt,&tmp,here->VSRCname,"branch"); if(error) return(error); here->VSRCbranch = tmp->number; diff --git a/src/spicelib/devices/vsrc/vsrcset.c b/src/spicelib/devices/vsrc/vsrcset.c index d3758b520..4d72ed002 100644 --- a/src/spicelib/devices/vsrc/vsrcset.c +++ b/src/spicelib/devices/vsrc/vsrcset.c @@ -14,16 +14,16 @@ Author: 1985 Thomas L. Quarles /* ARGSUSED */ int VSRCsetup(matrix,inModel,ckt,state) - register SMPmatrix *matrix; + SMPmatrix *matrix; GENmodel *inModel; - register CKTcircuit *ckt; + CKTcircuit *ckt; int *state; /* load the voltage source structure with those pointers needed later * for fast matrix loading */ { - register VSRCmodel *model = (VSRCmodel *)inModel; - register VSRCinstance *here; + VSRCmodel *model = (VSRCmodel *)inModel; + VSRCinstance *here; CKTnode *tmp; int error; @@ -60,7 +60,6 @@ VSRCunsetup(inModel,ckt) GENmodel *inModel; CKTcircuit *ckt; { -#ifndef HAS_BATCHSIM VSRCmodel *model; VSRCinstance *here; @@ -76,6 +75,5 @@ VSRCunsetup(inModel,ckt) } } } -#endif return OK; } diff --git a/src/spicelib/devices/vsrc/vsrctemp.c b/src/spicelib/devices/vsrc/vsrctemp.c index 8dbae8ed7..d4acce280 100644 --- a/src/spicelib/devices/vsrc/vsrctemp.c +++ b/src/spicelib/devices/vsrc/vsrctemp.c @@ -19,8 +19,8 @@ VSRCtemp(inModel,ckt) /* Pre-process voltage source parameters */ { - register VSRCmodel *model = (VSRCmodel *)inModel; - register VSRCinstance *here; + VSRCmodel *model = (VSRCmodel *)inModel; + VSRCinstance *here; double radians; /* loop through all the voltage source models */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 36b6a187f..876e71c23 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,18 +1,18 @@ ## Process this file with automake to produce Makefile.in -TESTS = diffpair.sh fourbitadder.sh resistor.sh +SUBDIRS = resistance filters polezero bsim3soipd bsim3soifd bsim3soidd bsim4 mesa -TESTS_ENVIRONMENT = $(SHELL) +TESTS = \ + diffpair.cir \ + fourbitadder.cir + +TESTS_ENVIRONMENT = $(SHELL) $(srcdir)/check.sh $(top_builddir)/src/ngspice EXTRA_DIST = \ README \ - config.sh \ + check.sh \ + maketest.sh \ $(TESTS) \ - diffpair.cir \ - diffpair.out \ - fourbitadder.cir \ - fourbitadder.out \ - resistor.cir \ - resistor.out + $(TESTS:.cir=.out) MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/README b/tests/README index d10d80754..968afd5ff 100644 --- a/tests/README +++ b/tests/README @@ -1,3 +1,18 @@ +ngspice test files: +=================== + +The test directory contains several netlist designed to test ngspice functionality and correctness. +There are netlists that test devices behavior and netlists that test analyses correctness. + +REPLICATE TESTS + +Tests are done with an ngspice compiled with the following options: + + --enable-ftedebug <- Should have no effect + --enable-nobypass + --enavle-predictor + --enable-experimental <- Living on the edge :) + TO ADD NEW TESTS Take an existing test and adopt it to your liking. Add the test diff --git a/tests/diffpair.out b/tests/diffpair.out index cd91abbdf..d2165e421 100644 --- a/tests/diffpair.out +++ b/tests/diffpair.out @@ -1,18 +1,19 @@ +Error: no data saved for Sensitivity analysis; analysis not run +doAnalyses: not found + +run simulation(s) aborted Circuit: simple differential pair - CM and DM dc sensitivity -Circuit: simple differential pair - CM and DM dc sensitivity - - Transfer function information: transfer_function = -1.10340e-01 -output_impedance_at_v(5) = 9.446409e+03 -vcm#input_impedance = 1.792504e+06 +output_impedance_at_v(5) = 9.446401e+03 +vcm#input_impedance = 1.792489e+06 Transfer function information: -transfer_function = -8.78993e+01 -output_impedance_at_v(5) = 9.446409e+03 -vdm#input_impedance = 8.934967e+03 +transfer_function = -8.79002e+01 +output_impedance_at_v(5) = 9.446401e+03 +vdm#input_impedance = 8.934860e+03 diff --git a/tests/fourbitadder.out b/tests/fourbitadder.out index 99661b4c4..12766b629 100644 --- a/tests/fourbitadder.out +++ b/tests/fourbitadder.out @@ -1,76 +1,400 @@ Circuit: 4 bit adder -Circuit: 4 bit adder +Initial Transient Solution +-------------------------- + +Node Voltage +---- ------- +99 5 +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +8 0 +1:1:1:1:9 0.0179277 +1:1:1:1:5 0.826789 +1:1:1:1:6 4.97244 +1:1:1:1:8 3.54606e-09 +1:1:1:1:7 4.83208 +1:1:1:1:10 4.18989 +1:1:1:7 3.52783 +1:1:1:2:9 0.0363158 +1:1:1:2:5 0.844836 +1:1:1:2:6 4.99412 +1:1:1:2:8 3.66756e-09 +1:1:1:2:7 4.96415 +1:1:1:2:10 4.25286 +1:1:1:8 3.63074 +1:1:1:3:9 0.0363158 +1:1:1:3:5 0.844836 +1:1:1:3:6 4.99412 +1:1:1:3:8 3.66756e-09 +1:1:1:3:7 4.96415 +1:1:1:3:10 4.25286 +1:1:1:9 3.63074 +1:1:1:4:9 1.99534 +1:1:1:4:5 2.76452 +1:1:1:4:6 1.10792 +1:1:1:4:8 1.07019 +1:1:1:4:7 4.99984 +1:1:1:4:10 0.507271 +1:1:1:10 0.0253869 +1:1:1:5:9 0.0277172 +1:1:1:5:5 0.836398 +1:1:1:5:6 4.97251 +1:1:1:5:8 3.55613e-09 +1:1:1:5:7 4.83248 +1:1:1:5:10 4.19002 +1:1:1:11 3.52802 +1:1:1:6:9 0.0363158 +1:1:1:6:5 0.844836 +1:1:1:6:6 4.9941 +1:1:1:6:8 3.66742e-09 +1:1:1:6:7 4.96406 +1:1:1:6:10 4.25278 +1:1:1:12 3.63059 +1:1:1:7:9 0.0617017 +1:1:1:7:5 0.869755 +1:1:1:7:6 4.9941 +1:1:1:7:8 3.6935e-09 +1:1:1:7:7 4.96406 +1:1:1:7:10 4.25278 +1:1:1:13 3.63059 +1:1:1:8:9 1.98972 +1:1:1:8:5 2.75903 +1:1:1:8:6 1.10196 +1:1:1:8:8 1.06424 +1:1:1:8:7 4.99984 +1:1:1:8:10 0.500516 +9 0.0178393 +1:1:1:9:9 1.9967 +1:1:1:9:5 2.76585 +1:1:1:9:6 1.10936 +1:1:1:9:8 1.07163 +1:1:1:9:7 4.99984 +1:1:1:9:10 0.508909 +1:1:10 0.0272212 +1:1:2:1:9 0.0179277 +1:1:2:1:5 0.826789 +1:1:2:1:6 4.97244 +1:1:2:1:8 3.54606e-09 +1:1:2:1:7 4.83208 +1:1:2:1:10 4.18989 +1:1:2:7 3.52783 +1:1:2:2:9 0.0363158 +1:1:2:2:5 0.844836 +1:1:2:2:6 4.99412 +1:1:2:2:8 3.6676e-09 +1:1:2:2:7 4.96417 +1:1:2:2:10 4.25288 +1:1:2:8 3.63077 +1:1:2:3:9 0.0363158 +1:1:2:3:5 0.844836 +1:1:2:3:6 4.99412 +1:1:2:3:8 3.6676e-09 +1:1:2:3:7 4.96417 +1:1:2:3:10 4.25288 +1:1:2:9 3.63077 +1:1:2:4:9 1.9967 +1:1:2:4:5 2.76585 +1:1:2:4:6 1.10936 +1:1:2:4:8 1.07163 +1:1:2:4:7 4.99984 +1:1:2:4:10 0.508909 +1:1:2:10 0.0272212 +1:1:2:5:9 0.0451489 +1:1:2:5:5 0.85351 +1:1:2:5:6 4.97258 +1:1:2:5:8 3.57407e-09 +1:1:2:5:7 4.83293 +1:1:2:5:10 4.19017 +1:1:2:11 3.52824 +1:1:2:6:9 0.063536 +1:1:2:6:5 0.871555 +1:1:2:6:6 4.9941 +1:1:2:6:8 3.69541e-09 +1:1:2:6:7 4.96406 +1:1:2:6:10 4.25278 +1:1:2:12 3.63059 +1:1:2:7:9 0.063536 +1:1:2:7:5 0.871555 +1:1:2:7:6 4.9941 +1:1:2:7:8 3.69541e-09 +1:1:2:7:7 4.96406 +1:1:2:7:10 4.25278 +1:1:2:13 3.63059 +1:1:2:8:9 1.98972 +1:1:2:8:5 2.75903 +1:1:2:8:6 1.10196 +1:1:2:8:8 1.06424 +1:1:2:8:7 4.99984 +1:1:2:8:10 0.500516 +10 0.0178393 +1:1:2:9:9 1.9967 +1:1:2:9:5 2.76585 +1:1:2:9:6 1.10936 +1:1:2:9:8 1.07163 +1:1:2:9:7 4.99984 +1:1:2:9:10 0.508909 +1:16 0.0272212 +1:2:1:1:9 0.0179277 +1:2:1:1:5 0.826789 +1:2:1:1:6 4.97244 +1:2:1:1:8 3.54606e-09 +1:2:1:1:7 4.83208 +1:2:1:1:10 4.18989 +1:2:1:7 3.52783 +1:2:1:2:9 0.0363158 +1:2:1:2:5 0.844836 +1:2:1:2:6 4.99412 +1:2:1:2:8 3.6676e-09 +1:2:1:2:7 4.96417 +1:2:1:2:10 4.25288 +1:2:1:8 3.63077 +1:2:1:3:9 0.0363158 +1:2:1:3:5 0.844836 +1:2:1:3:6 4.99412 +1:2:1:3:8 3.6676e-09 +1:2:1:3:7 4.96417 +1:2:1:3:10 4.25288 +1:2:1:9 3.63077 +1:2:1:4:9 1.9967 +1:2:1:4:5 2.76585 +1:2:1:4:6 1.10936 +1:2:1:4:8 1.07163 +1:2:1:4:7 4.99984 +1:2:1:4:10 0.508909 +1:2:1:10 0.0272212 +1:2:1:5:9 0.0451489 +1:2:1:5:5 0.85351 +1:2:1:5:6 4.97258 +1:2:1:5:8 3.57407e-09 +1:2:1:5:7 4.83293 +1:2:1:5:10 4.19017 +1:2:1:11 3.52824 +1:2:1:6:9 0.063536 +1:2:1:6:5 0.871555 +1:2:1:6:6 4.9941 +1:2:1:6:8 3.69541e-09 +1:2:1:6:7 4.96406 +1:2:1:6:10 4.25278 +1:2:1:12 3.63059 +1:2:1:7:9 0.063536 +1:2:1:7:5 0.871555 +1:2:1:7:6 4.9941 +1:2:1:7:8 3.69541e-09 +1:2:1:7:7 4.96406 +1:2:1:7:10 4.25278 +1:2:1:13 3.63059 +1:2:1:8:9 1.98972 +1:2:1:8:5 2.75903 +1:2:1:8:6 1.10196 +1:2:1:8:8 1.06424 +1:2:1:8:7 4.99984 +1:2:1:8:10 0.500516 +11 0.0178393 +1:2:1:9:9 1.9967 +1:2:1:9:5 2.76585 +1:2:1:9:6 1.10936 +1:2:1:9:8 1.07163 +1:2:1:9:7 4.99984 +1:2:1:9:10 0.508909 +1:2:10 0.0272212 +1:2:2:1:9 0.0179277 +1:2:2:1:5 0.826789 +1:2:2:1:6 4.97243 +1:2:2:1:8 3.54601e-09 +1:2:2:1:7 4.83197 +1:2:2:1:10 4.18986 +1:2:2:7 3.52778 +1:2:2:2:9 0.0363158 +1:2:2:2:5 0.844836 +1:2:2:2:6 4.99412 +1:2:2:2:8 3.6676e-09 +1:2:2:2:7 4.96417 +1:2:2:2:10 4.25288 +1:2:2:8 3.63077 +1:2:2:3:9 0.0363158 +1:2:2:3:5 0.844836 +1:2:2:3:6 4.99412 +1:2:2:3:8 3.6676e-09 +1:2:2:3:7 4.96417 +1:2:2:3:10 4.25288 +1:2:2:9 3.63077 +1:2:2:4:9 1.9967 +1:2:2:4:5 2.76585 +1:2:2:4:6 1.10936 +1:2:2:4:8 1.07163 +1:2:2:4:7 4.99984 +1:2:2:4:10 0.508909 +1:2:2:10 0.0272212 +1:2:2:5:9 0.0451489 +1:2:2:5:5 0.85351 +1:2:2:5:6 4.97257 +1:2:2:5:8 3.57402e-09 +1:2:2:5:7 4.83282 +1:2:2:5:10 4.19014 +1:2:2:11 3.52819 +1:2:2:6:9 0.063536 +1:2:2:6:5 0.871555 +1:2:2:6:6 4.9941 +1:2:2:6:8 3.69541e-09 +1:2:2:6:7 4.96406 +1:2:2:6:10 4.25278 +1:2:2:12 3.63059 +1:2:2:7:9 0.063536 +1:2:2:7:5 0.871555 +1:2:2:7:6 4.9941 +1:2:2:7:8 3.69541e-09 +1:2:2:7:7 4.96406 +1:2:2:7:10 4.25278 +1:2:2:13 3.63059 +1:2:2:8:9 1.98972 +1:2:2:8:5 2.75903 +1:2:2:8:6 1.10196 +1:2:2:8:8 1.06424 +1:2:2:8:7 4.99984 +1:2:2:8:10 0.500516 +12 0.0178393 +1:2:2:9:9 1.98972 +1:2:2:9:5 2.75903 +1:2:2:9:6 1.10196 +1:2:2:9:8 1.06424 +1:2:2:9:7 4.99984 +1:2:2:9:10 0.500516 +13 0.0178393 +vin4b#branch 0.00207527 +vin4a#branch 0.00207527 +vin3b#branch 0.00207527 +vin3a#branch 0.00207527 +vin2b#branch 0.00207527 +vin2a#branch 0.00207527 +vin1b#branch 0.00207527 +vin1a#branch 0.00207527 +vcc#branch -0.0757537 4 bit adder -------------------------------------------------------------------------------- Index time v(1) -------------------------------------------------------------------------------- 0 0.000000e+00 0.000000e+00 -1 1.200000e-12 3.600000e-04 -2 1.542463e-12 4.627390e-04 -3 2.227390e-12 6.682170e-04 -4 3.597243e-12 1.079173e-03 -5 6.336950e-12 1.901085e-03 -6 1.181636e-11 3.544909e-03 -7 2.277519e-11 6.832557e-03 -8 4.469284e-11 1.340785e-02 -9 8.852815e-11 2.655844e-02 -10 1.761988e-10 5.285963e-02 -11 2.824896e-10 8.474689e-02 -12 4.024896e-10 1.207469e-01 -13 5.224896e-10 1.567469e-01 -14 6.424896e-10 1.927469e-01 -15 7.624896e-10 2.287469e-01 -16 8.824896e-10 2.647469e-01 -17 1.002490e-09 3.007469e-01 -18 1.122490e-09 3.367469e-01 -19 1.242490e-09 3.727469e-01 -20 1.362490e-09 4.087469e-01 -21 1.482490e-09 4.447469e-01 -22 1.602490e-09 4.807469e-01 -23 1.722490e-09 5.167469e-01 -24 1.842490e-09 5.527469e-01 -25 1.962490e-09 5.887469e-01 -26 2.082490e-09 6.247469e-01 -27 2.202490e-09 6.607469e-01 -28 2.322490e-09 6.967469e-01 -29 2.442490e-09 7.327469e-01 -30 2.562490e-09 7.687469e-01 -31 2.682490e-09 8.047469e-01 -32 2.802490e-09 8.407469e-01 -33 2.922490e-09 8.767469e-01 -34 3.042490e-09 9.127469e-01 -35 3.162490e-09 9.487469e-01 -36 3.282490e-09 9.847469e-01 -37 3.402490e-09 1.020747e+00 -38 3.522490e-09 1.056747e+00 -39 3.642490e-09 1.092747e+00 -40 3.762490e-09 1.128747e+00 -41 3.882490e-09 1.164747e+00 -42 4.002490e-09 1.200747e+00 -43 4.122490e-09 1.236747e+00 -44 4.242490e-09 1.272747e+00 -45 4.362490e-09 1.308747e+00 -46 4.482490e-09 1.344747e+00 -47 4.602490e-09 1.380747e+00 -48 4.722490e-09 1.416747e+00 -49 4.842490e-09 1.452747e+00 -50 4.962490e-09 1.488747e+00 -51 5.082490e-09 1.524747e+00 -52 5.202490e-09 1.560747e+00 -53 5.322490e-09 1.596747e+00 -54 5.442490e-09 1.632747e+00 +1 6.000000e-13 1.800000e-04 +2 7.422315e-13 2.226694e-04 +3 1.026694e-12 3.080083e-04 +4 1.595620e-12 4.786860e-04 +5 2.733472e-12 8.200415e-04 +6 5.009175e-12 1.502753e-03 +7 9.560581e-12 2.868174e-03 +8 1.866339e-11 5.599018e-03 +9 3.686902e-11 1.106071e-02 +10 7.328027e-11 2.198408e-02 +11 1.332803e-10 3.998408e-02 +12 1.932803e-10 5.798408e-02 +13 2.532803e-10 7.598408e-02 +14 3.132803e-10 9.398408e-02 +15 3.732803e-10 1.119841e-01 +16 4.332803e-10 1.299841e-01 +17 4.932803e-10 1.479841e-01 +18 5.532803e-10 1.659841e-01 +19 6.132803e-10 1.839841e-01 +20 6.732803e-10 2.019841e-01 +21 7.332803e-10 2.199841e-01 +22 7.932803e-10 2.379841e-01 +23 8.532803e-10 2.559841e-01 +24 9.132803e-10 2.739841e-01 +25 9.732803e-10 2.919841e-01 +26 1.033280e-09 3.099841e-01 +27 1.093280e-09 3.279841e-01 +28 1.153280e-09 3.459841e-01 +29 1.213280e-09 3.639841e-01 +30 1.273280e-09 3.819841e-01 +31 1.333280e-09 3.999841e-01 +32 1.393280e-09 4.179841e-01 +33 1.453280e-09 4.359841e-01 +34 1.513280e-09 4.539841e-01 +35 1.573280e-09 4.719841e-01 +36 1.633280e-09 4.899841e-01 +37 1.693280e-09 5.079841e-01 +38 1.753280e-09 5.259841e-01 +39 1.813280e-09 5.439841e-01 +40 1.873280e-09 5.619841e-01 +41 1.933280e-09 5.799841e-01 +42 1.993280e-09 5.979841e-01 +43 2.053280e-09 6.159841e-01 +44 2.113280e-09 6.339841e-01 +45 2.173280e-09 6.519841e-01 +46 2.233280e-09 6.699841e-01 +47 2.293280e-09 6.879841e-01 +48 2.353280e-09 7.059841e-01 +49 2.413280e-09 7.239841e-01 +50 2.473280e-09 7.419841e-01 +51 2.533280e-09 7.599841e-01 +52 2.593280e-09 7.779841e-01 +53 2.653280e-09 7.959841e-01 +54 2.713280e-09 8.139841e-01 Index time v(1) -------------------------------------------------------------------------------- -55 5.562490e-09 1.668747e+00 -56 5.682490e-09 1.704747e+00 -57 5.802490e-09 1.740747e+00 -58 5.922490e-09 1.776747e+00 -59 6.000000e-09 1.800000e+00 +55 2.773280e-09 8.319841e-01 +56 2.833280e-09 8.499841e-01 +57 2.893280e-09 8.679841e-01 +58 2.953280e-09 8.859841e-01 +59 3.013280e-09 9.039841e-01 +60 3.073280e-09 9.219841e-01 +61 3.133280e-09 9.399841e-01 +62 3.193280e-09 9.579841e-01 +63 3.253280e-09 9.759841e-01 +64 3.313280e-09 9.939841e-01 +65 3.373280e-09 1.011984e+00 +66 3.433280e-09 1.029984e+00 +67 3.493280e-09 1.047984e+00 +68 3.553280e-09 1.065984e+00 +69 3.613280e-09 1.083984e+00 +70 3.673280e-09 1.101984e+00 +71 3.733280e-09 1.119984e+00 +72 3.793280e-09 1.137984e+00 +73 3.853280e-09 1.155984e+00 +74 3.913280e-09 1.173984e+00 +75 3.973280e-09 1.191984e+00 +76 4.033280e-09 1.209984e+00 +77 4.093280e-09 1.227984e+00 +78 4.153280e-09 1.245984e+00 +79 4.213280e-09 1.263984e+00 +80 4.273280e-09 1.281984e+00 +81 4.333280e-09 1.299984e+00 +82 4.393280e-09 1.317984e+00 +83 4.453280e-09 1.335984e+00 +84 4.513280e-09 1.353984e+00 +85 4.573280e-09 1.371984e+00 +86 4.633280e-09 1.389984e+00 +87 4.693280e-09 1.407984e+00 +88 4.753280e-09 1.425984e+00 +89 4.813280e-09 1.443984e+00 +90 4.873280e-09 1.461984e+00 +91 4.933280e-09 1.479984e+00 +92 4.993280e-09 1.497984e+00 +93 5.053280e-09 1.515984e+00 +94 5.113280e-09 1.533984e+00 +95 5.173280e-09 1.551984e+00 +96 5.233280e-09 1.569984e+00 +97 5.293280e-09 1.587984e+00 +98 5.353280e-09 1.605984e+00 +99 5.413280e-09 1.623984e+00 +100 5.473280e-09 1.641984e+00 +101 5.533280e-09 1.659984e+00 +102 5.593280e-09 1.677984e+00 +103 5.653280e-09 1.695984e+00 +104 5.713280e-09 1.713984e+00 +105 5.773280e-09 1.731984e+00 +106 5.833280e-09 1.749984e+00 +107 5.893280e-09 1.767984e+00 +108 5.953280e-09 1.785984e+00 +109 6.000000e-09 1.800000e+00