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/BUGS b/BUGS new file mode 100644 index 000000000..65c5eb59d --- /dev/null +++ b/BUGS @@ -0,0 +1,7 @@ +This file contais a list of known but not yet fixed bugs in ngspice. +==================================================================== + +Rework 14: + If you run tests in the test tree, you will discover that some + of them fails because of a different value in "Reference Value". + Anyway, analyses results are not affected. 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/NOTES b/NOTES new file mode 100644 index 000000000..3851bcae1 --- /dev/null +++ b/NOTES @@ -0,0 +1,69 @@ +DEBUGGING SPICE + +To avoid a segmentation fault in the initial run, use the following +command in gdb: + + setenv SPICE_NO_DATASEG_CHECK "1" + +Or, the comparable command in your shell before running gdb. This +disable accurate tracking of how much memory is used. + +---------------------------------------------------------------------- +USING A GARBAGE COLLECTOR + +Get the Boehm-Weiser conservative garbage collector at the following +address: + + http://www.hpl.hp.com/personal/Hans_Boehm/gc/ + +Compile it with 'make liblinuxgc.so' and install libgc.so and gc.h +where the compiler can find them (i.e., /usr/local/lib and +/usr/local/include). Run configure and compile. + + +---------------------------------------------------------------------- +CREATING PATCHES + +If you don't have access to anonymous CVS: + + # extract the differences + $ diff -ruN ng-spice-rework-x ng-spice > my.patch + +where ng-spice-rework-x is the snapshot you used to base your changes +on. + +If you do have access to anonymous CVS: + + $ cvs diff -u > my.patch + +Note: this only works if you haven't added any files. Otherwise, the +first method is better. + +Now, send your patch to ng-spice mailing list. + + +---------------------------------------------------------------------- +INCORPORATING PATCHES + + # apply the patch + $ patch -p1 < my.patch + + # update the automatically generated files + $ sh autogen.sh + +---------------------------------------------------------------------- +INCOMPATIBILITIES BETWEEN SPICE3 AND SPICE2 + +The output format of spice3 is slightly different for .print and .plot +lines. Most notably, different traces on plots are not scaled +independently. This is most noticeable on phase/magnitude plots from +an AC analysis (also, phase is displayed in radians). Finally, +frequency for ".PRINT AC" lines is displayed as a complex quantity +with an all-zero imaginary component. + +For input, "POLY( )" sources are not supported (the non-linear +dependent source provides a more general replacement). Also, the +".ALTER" line is not supported. The Spice3 parser may be slightly +different on subtle points of reading input (lines need not start at +column 1 for instance). + 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/liblook b/contrib/mslib/liblook new file mode 100755 index 000000000..3cf1f8cb4 --- /dev/null +++ b/contrib/mslib/liblook @@ -0,0 +1,77 @@ +#!/bin/sh +#set -x -v + +# MW. Lib search / show program + +# usage liblook libname [text_to_find] [l_before] [l_after] + +LIBPATH=/usr/local/lib + +function trapper() + { + echo User break! + echo Exiting . . . + unset LIBPATH + exit 1 + } + +trap trapper SIGINT SIGQUIT + +function operror() + { + echo Incorrect parameters: $*, $# + echo Usage: liblook libname [text_to_find] [l_before] [l_after] + unset LIBPATH + exit 2 + } + +function showlib() + { + if test -f $LIBPATH/$1; then + less $LIBPATH/$1; exit 0; fi + + if test -f [C./$1; then + less ./$1; exit 0; fi + + echo Searching $1 in ~/ . . . + less $(find ~/ -name $1) + } + +function searchlib() + { + if test -f $LIBPATH/$1; then + echo File: $1; echo; + grep -B"$3" -A"$4" --ignore-case -e "$2" $LIBPATH/$1; + echo; exit 0; fi + + if test -f ./$1; then + echo File: $1; echo; + grep -B"$3" -A"$4" --ignore-case -e "$2" ./$1; + echo; exit 0; fi + +#if *.lib or sth like this + + echo Searching $1 in ~/ . . .;echo; + if (grep -B"$3" -A"$4" --ignore-case -e "$2" $(find ~/ -name $1)); then + echo; exit 0; fi + + echo Searching $1 in $LIBPATH;echo; + if (grep -B"$3" -A"$4" --ignore-case -e "$2" $(find $LIBPATH -name $1)); then + echo; exit 0; fi + + } + + +# Main body +if test $# -lt 1 -o $# -gt 4; then operror $*; fi + +case $# in +1) showlib $*;; +2) searchlib $1 $2 2 2;; +3) searchlib $1 $2 $3 2;; +4) searchlib $1 $2 $3 $4;; +esac + +unset LIBPATH +exit 0 + diff --git a/contrib/mslib/libprm b/contrib/mslib/libprm new file mode 100755 index 000000000..bfc8ae59d --- /dev/null +++ b/contrib/mslib/libprm @@ -0,0 +1,70 @@ +#!/bin/sh +#set -x -v + +# MW. Lip / Param parsing program for spice + +# -n normal, -f full (keep everything), -r replace original file +# -e new addition start with editor, then like normal + +export TMPLP=/tmp/LibPrm.$$- + +function trapper() + { + echo User break! + echo Exiting . . . + rm -f -v ${TMPLP}* + unset TMPLP + exit 1 + } + +trap trapper SIGINT SIGQUIT + +function operror() + { + echo Incorrect parameters: $*, $# + unset TMPLP + exit 2 + } + +function repnormpl() + { + mslib $1 ${TMPLP}1 + sed -n -e 'p' -e "1r ${TMPLP}1" $1 >${TMPLP}2 + spiceprm ${TMPLP}2 $2 + } + +function keepall() + { + mslib $1 + sed -n -e 'p' -e "1r $1.lib" $1 >${TMPLP}2 + spiceprm ${TMPLP}2 $2 + } + +function withedit() + { + joe $1 + mslib $1 ${TMPLP}1 + sed -n -e 'p' -e "1r ${TMPLP}1" $1 >${TMPLP}2 + spiceprm ${TMPLP}2 $2 + } + + +# Main body +if test $# -lt 2 -o $# -gt 3; then operror $*; fi +if !(test -f $2); then operror $*; fi + +case $1$# in +-r3) operror $*;; +-n2) repnormpl $2 ${2%.cir}.ckt;; +-n3) repnormpl $2 $3;; +-r2) repnormpl $2 $2;; +-f2) keepall $2 ${2%.cir}.ckt;; +-f3) keepall $2 $3;; +-e2) withedit $2 ${2%.cir}.ckt;; +-e3) withedit $2 $3;; +esac + +rm -f ${TMPLP}* +unset TMPLP +exit 0 + diff --git a/contrib/mslib/libprm_readme b/contrib/mslib/libprm_readme new file mode 100644 index 000000000..8f7bb3df7 --- /dev/null +++ b/contrib/mslib/libprm_readme @@ -0,0 +1,14 @@ +So, this is my idea of using parametrized subckts with spice3f4. + + First I create an input file like foo.cir and I include commands for +mslib (*MOD, *SUB, *LIB) in it. Then I run "libprm -n foo.cir". Libprm then +runs mslib first to get all models and subckts form given libraries and then +runs spiceprm to evaluate all used parameters. + This works quite right for me, and I hope that You will find my idea +useful. Spiceprm is not my program (I get it from Internet), but I think +that it will better to enclose all used programs in this packet. Spiceprm +has it's own directory with very good readme and examples. If You want to +find out more about libprm or mslib look for the source code. These are rather +short and easy programs - they are all that I could write in quite short +time. + \ No newline at end of file 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/man/man1/ngnutmeg.1 b/man/man1/ngnutmeg.1 new file mode 100644 index 000000000..28572b1a2 --- /dev/null +++ b/man/man1/ngnutmeg.1 @@ -0,0 +1,1057 @@ +.\" RCS Info: $Revision$ on $Date$ +.\" $Source$ +.\" Copyright (c) 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +.TH NUTMEG 1 "27 April 1987" +.UC 4 +.SH NAME +nutmeg \- spice post-processor +.SH SYNOPSIS +\fBnutmeg [ - ] [ -n ] [ -t term ] [ datafile ... ]\fR +.SH DESCRIPTION +.B Nutmeg +is a post processor for \s-2SPICE\s+2 \- it takes the raw +output file created +by \fBspice -r\fR +and plots the data on a graphics terminal or a workstation display. +Note that the raw output file is different from the +data that \s-2SPICE\s+2 writes to the standard output. +.PP +Arguments are: +.TP +\fB-\fR +Don't try to load the default data file ("rawspice") if no other files +are given. +.TP +\fB-n\fR (or \fB--no-spiceinit\fR) +Don't try to source the file ".spiceinit" upon startup. Normally \fBnutmeg\fR +tries to find the file in the current directory, and if it is not found then +in the user's home directory. +.TP +\fB-t term\fR (or \fB--term=term\fR) +The program is being run on a terminal with \fImfb\fR name \fBterm\fR. +.TP +\fB-h\fR (or \fB--help\fR) +Display a verbose help on the arguments available to the program. +.TP +\fB-v\fR (or \fB--version\fR) +Display a version number and copyright information of the program. +.PP +Further arguments are taken to be data files in binary or ascii format +(see \fBsconvert\fR(1)) which are loaded into nutmeg. If the file +is in binary format, it may be only partially completed (useful for +examining \s-2SPICE\s+2 ouput before the simulation is finished). One +file may contain any number of data sets from different analyses. +.PP +\fBNutmeg\fR +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 +.B load +command below), and when the initial datafile is loaded. They can +also be created with the +.B let +command. +.PP +An expression +is an algebraic +formula involving vectors and scalars (a scalar is a vector of +length 1), and the following operations: +.IP ++, -, *, %, /, ^, and ,. +.PP +% is the modulo operator, and the comma operator has two meanings: +if it is present in the argument list of a user-definable function, it +serves to seperate the arguments. Otherwise, the term \fBx , y\fR is +synonymous with \fBx + j(y)\fR. +.PP +Also available are the logical operations & (and), | (or), ! (not), +and the relational operations <, >, >=, <=, =, and <> (not equal). +If used in an algebraic expression they work like they would in C, +producing values of 0 or 1. The relational operators have the +following synonyms: +\fB"gt"\fR is >, +\fB"lt"\fR is <, +\fB"ge"\fR is >=, +\fB"le"\fR is <=, +\fB"ne"\fR is <>, +\fB"eq"\fR is =, +\fB"and"\fR is &, +\fB"or"\fR is |, +and +\fB"not"\fR is !. +These are useful when < and > might be confused with IO redirection +(which is almost always). +.PP +The following functions are available: +.IP +\fBmag(vector) \-\fR +The magnitude of vector. +.IP +\fBph(vector) \-\fR +The phase of vector. +.IP +\fBj(vector) \-\fR +\fIi\fR (sqrt(-1)) times vector. +.IP +\fBreal(vector) \-\fR +The real component of vector. +.IP +\fBimag(vector) \-\fR +The imaginary part of vector. +.IP +\fBdb(vector) \-\fR +20 * log10(mag(vector)). +.IP +\fBlog(vector) \-\fR +The logarithm (base 10) of the vector. +.IP +\fBln(vector) \-\fR +The natural logarithm (base e) of vector. +.IP +\fBexp(vector) \-\fR +e to the vector power. +.IP +\fBabs(vector) \-\fR +The absolute value of vector. +.IP +\fBsqrt(vector) \-\fR +The square root of vector. +.IP +\fBsin(vector) \-\fR +The sin of vector. +.IP +\fBcos(vector) \-\fR +The cosine of vector. +.IP +\fBtan(vector) \-\fR +The tangent of vector. +.IP +\fBatan(vector) \-\fR +The inverse tangent of vector. +.IP +\fBnorm(vector) \-\fR +The \fBvector\fR normalized to 1 (i.e, the largest magnitude of any component +will be 1). +.IP +\fBrnd(vector) \-\fR +A vector with each component a random integer between 0 and the absolute +value of the vectors's corresponding component. +.IP +\fBmean(vector) \-\fR +The result is a scalar (a length 1 vector) that is the mean of the elements +of \fBvector\fR. +.IP +\fBvector(number) \-\fR +The result is a vector of length \fBnumber\fR, with elements 0, 1, ... +\fBnumber - 1\fR. If \fBnumber\fR is a vector then just the first element +is taken, and if it isn't an integer then the floor of the magnitude is +used. +.IP +\fBlength(vector) \-\fR +The length of \fBvector\fR. +.IP +\fBinterpolate(plot.vector) \-\fR +The result of interpolating the named vector onto the scale of the current +plot. This function uses the variable \fBpolydegree\fR to determine +the degree of interpolation. +.PP +A vector may be either the name of a vector already defined, a floating- +point number (a scalar), or a list like \fB[elt1 elt2 ... eltn]\fR, which +is a vector of length n. +A number may be written in any format acceptable to \s-2SPICE\s+2, such +as \fB14.6MEG\fR or \fB-1.231E-4\fR. Note that you can either use +scientific notation or one of the abbreviations like \fIMEG\fR or \fIG\fR, +but not both. As with \s-2SPICE\s+2, a number may have trailing +alphabetic characters after it. +.PP +The notation \fBexpr [lower upper]\fR, where \fBlower\fR and \fBupper\fR +are numbers, denotes the range of elements from \fBexpr\fR between +\fBlower\fR and \fBupper\fR. The notation \fBexpr [num]\fR denotes +the \fBnum\fR'th element of \fBexpr\fR. If \fBupper\fR +is lower than \fBlower\fR, the order of the elements in the vector +is reversed. In all other cases, \fB[\fR and \fB]\fR serve to surround +literal vectors as described above. (You may have to use a lot of +parentheses to make sure that you get what you want. For instance, +you have to type \fBprint (foo) ([1 2])\fR to print the two vectors. +Otherwise it will be interpreted as a function call or a vector with an +index.) Note that the expression \fBfoo[10 20][5]\fR will \fInot\fR +yield the 15th element of \fBfoo\fR, but rather the 5th. In general only +the last index suffix on an expression will take effect. +.PP +To reference vectors in a plot that is not the +\fIcurrent plot\fR (see the \fBsetplot\fR command, below), the +notation \fBplotname.vecname\fR can be used. +.PP +Either a plotname or a vector name may be the wildcard \fBall\fR. If the +plotname is \fBall\fR, matching vectors from all plots are specified, and +if the vector name is \fBall\fR, all vectors in the specified plots are +referenced. Note that you may not use binary operations on expressions +involving wildcards \- it is not obvious what \fBall + all\fR should +denote, for instance. +.PP +Thus some (contrived) examples of expressions are: +.IP +\fBcos(TIME) + db(v(3))\fR +.IP +\fBsin(cos(log([1 2 3 4 5 6 7 8 9 10])))\fR +.IP +\fBTIME * rnd(v(9)) - 15 * cos(vin#branch) ^ [7.9e5 8]\fR +.IP +\fBnot ((ac3.FREQ[32] & tran1.TIME[10]) gt 3)\fR +.PP +.B Nutmeg +commands are as follows: +.TP +\fBplot exprs [ylimit ylo yhi] [xlimit xlo xhi] [xindices xilo xihi]\fR +.ce +\fB[xcompress comp] [xdelta xdel] [ydelta ydel] [xlog] [ylog] [vs xname]\fR +.ce +\fB[xlabel word] [ylabel word] [title word] [samep]\fR +Plot the given +.B exprs +on the screen (if you are on a graphics terminal). The +.B xlimit +and +.B ylimit +arguments determine the high and low x- and y-limits of the axes, +respectively. The +.B xindices +arguments determine what range of points are to be plotted \- everything +between the \fBxilo\fR'th point and the \fBxihi\fR'th point is plotted. +The +.B xcompress +argument specifies that only one out of every \fBcomp\fR points should +be plotted. If an \fBxdelta\fR or a \fBydelta\fR parameter is present, +it specifies the spacing between grid lines on the X- and Y-axis. +These parameter names may be abbreviated to +.B xl, +.B yl, +.B xind, +.B xcomp, +.B xdel, +and +.B ydel +respectively. +The +.B xname +argument is an expression to use as the scale on the x-axis. +If \fBxlog\fR or \fBylog\fR are present, the X or Y scale respectively +will be logarithmic. +The \fBxlabel\fR and \fBylabel\fR arguments cause the specified +labels to be used for the X and Y axes, respectively. +If \fBsamep\fR is given, the values of the other parameters (other than +\fBxname\fR) from the previous \fBplot, hardcopy,\fR or \fBasciiplot\fR +command will be used unless re-defined on the command line. +Finally, the \fBtitle\fR argument will be used in the place of the plot +name at the bottom of the graph. +.TP +\fBhardcopy file \fIplotargs\fR +Just like \fBplot\fR, except creates a file called +.B file +containing the plot. The file is an image in \fIplot(5)\fR format, +and can be printed by either the \fBplot(1)\fR program or \fBlpr\fR +with the \fB-g\fR flag. +.TP +\fBasciiplot \fIplotargs\fR +Produce a line printer plot of the vectors. +The plot is sent to the standard +output, so you can put it into a file with \fIasciiplot args ... > file\fR. +The \fBset\fR options \fBwidth, height,\fR and \fBnobreak\fR determine +the width and height of the plot, and whether there are page breaks, +respectively. Note that you will have problems if you try to \fBasciiplot\fR +something with an X-scale that isn't monotonic (i.e, something +like \fIsin(TIME)\fR ), because \fBasciiplot\fR uses a simple-minded sort +of linear interpolation. +.TP +\fBdefine function(arg1, arg2, ...) expression\fR +Define the \fIuser-definable function\fR with the name \fIfunction\fR +and arguments \fIarg1, arg2, ...\fR to be \fIexpression\fR, which +may involve the arguments. When the function is later used, the arguments +it is given are substituted for the formal arguments when it is parsed. +If \fIexpression\fR is not present, any definition for \fIfunction\fR +is printed, and if there are no arguments to \fIdefine\fR then all +currently active definitions are printed. Note that you may have different +functions defined with the same name but different arities. +Some useful definitions are: +.IP +define max(x,y) (x > y) * x + (x <= y) * y +.br +define min(x,y) (x < y) * x + (x >= y) * y +.TP +\fBundefine function ...\fR +Definitions for the named user-defined functions are deleted. +.TP +\fBlet name = expr\fR +Creates a new vector called +.B name +with the value specified by +.B expr, +an expression as described above. If \fBexpr\fR is [] (a zero-length vector) +then the vector becomes undefined. +If there are no arguments, \fBlet\fR is the same as \fBdisplay\fR. +.TP +\fBprint [col] [line] expr ... \fR +Prints the vector described by the expression +.B expr. +If the +.B col +argument is present, print the vectors named side by side. If \fBline\fR +is given, the vectors are printed horizontally. \fBcol\fR is the default, +unless all the vectors named have a length of one, in which case \fBline\fR +is the default. +The options +\fBwidth, length,\fR and \fBnobreak\fR are effective for this +command (see \fBasciiplot\fR). If the expression is \fBall\fR, +all of the vectors available are printed. Thus \fBprint col all > file\fR +will print everything in the file in \s-2SPICE\s+2\&2 format. +The scale vector (time, frequency) will always be in the first column +unless the variable \fBnoprintscale\fR is true. +.TP +\fBload [filename] ... \fR +Loads the raw data in either binary or ascii format +from the files named. The default filename is \fBrawspice\fR, or the argument +to the \fB-r\fR flag if there was one. +.TP +\fBsource filename\fR +Reads commands from the file +.B filename. +Lines beginning with the character \fB*\fR are considered comments and +ignored. +.TP +\fBhelp [all] [command ...]\fR +Prints help. If the argument \fBall\fR is given, a short description +of everything you could possibly type is printed. If \fBcommand\fRs are +given, descriptions of those commands are printed. Otherwise help for +only a few major commands is printed. +.TP +\fBdisplay [varname ...]\fR +Prints a summary of currently defined vectors, or of the names specified. +The vectors are sorted by name unless the variable \fBnosort\fR is set. +The information given is the name of the vector, the length, the +type of the vector, and whether it is real or complex data. Additionally, +one vector will be labeled \fB[scale]\fR. When a command such as +\fIplot\fR is given without a \fIvs\fR argument, this scale is used +for the X-axis. It is always the first vector in a rawfile, or +the first vector defined in a new plot. If you undefine the scale +(i.e, \fIlet TIME = []\fR), a random remaining +vector will become the scale. +.TP +\fBsetplot [plotname]\fR +Set the \fBcurrent plot\fR to the plot with the given +name, or if no name is given, prompt the user with a menu. +(Note that the plots are named as they are loaded, with names +like \fBtran1\fR or \fBop2\fR. These names are shown by the +\fBsetplot\fR and \fBdisplay\fR commands and are used by \fBdiff\fR, +below.) +If the +"New plot" item is selected, the current plot will become one with +no vectors defined. +Note that here the word "plot" refers +to a group of vectors that are the result of one \s-2SPICE\s+2 run. +When +more than one file is loaded in, or more than one plot is present +in one file, \fBnutmeg\fR keeps them seperate and only shows you the +vectors in the current plot. +.TP +\fBsettype type vector ...\fR +Change the type of the named vectors to \fBtype\fR. Type names can +be found in the manual page for \fBsconvert\fR. +.TP +\fBdiff plot1 plot2 [vec ...]\fR +Compare all the vectors in the specified \fIplots\fR, or only the named +vectors if any are given. There are different vectors in the two plots, +or any values in the vectors differ significantly the difference is +reported. The variables \fBabstol, reltol,\fR and \fBvntol\fR are used +to determine what "significantly" means (see the \s-2SPICE\s+2\&3 User's +Manual). +.TP +.B quit +Quit nutmeg. +.TP +.B bug +Send a bug report. (If you have defined BUGADDR, the mail will go there.) +.TP +\fBwrite [file] [exprs]\fR +Writes out the expr's to +.B file. +First vectors are grouped together by plots, and written out as such. +(I.e, if the expression list contained three vectors from one plot +and two from another, then two plots will be written, one with three +vectors and one with two.) Additionally, if the scale for a vector +isn't present, it is automatically written out as well. +The default format +is ascii, but this can be changed with the \fBset filetype\fR command. +The default filename is \fBrawspice\fR, or the argument to the \fB-r\fR +flag on the command line, if there was one, and the default expression +list is \fBall\fR. +.TP +\fBshell [args ...]\fR +Fork a shell, or execute the arguments as a command to the shell. +.TP +\fBalias [word] [text ...]\fR +Causes \fBword\fR to be aliased to \fBtext\fR. History substitutions may +be used, as in C-shell aliases. +.TP +\fBunalias [word ...]\fR +Removes any aliases present for the \fBword\fRs. +.TP +\fBhistory [number]\fR +Print out the history, or the last \fBnumber\fR commands typed at the keyboard. +\fINote:\fR in \*S version 3a7 and earlier, all commands (including ones read +from files) were saved. +.TP +\fBset [word] [word = value] ... \fR +Set the value of \fBword\fR to be \fBvalue\fR, if it is present. +You can set any word to be any value, numeric or string. If no value is +given then the value is the boolean 'true'. The value of \fIword\fR may +be inserted into a command by writing \fI$word\fR. +If a variable is set to a list of values that are enclosed in parentheses +(which +\fBmust\fR be seperated from their values by white space), the value +of the variable is the list. +The variables meaningful to \fBnutmeg\fR (of which there are too many) are: +.IP "" 16 +\fBabstol\fR +.br +The absolute tolerance used by the \fBdiff\fR command. +.IP +\fBappendwrite\fR +.br +Append to the file when a \fBwrite\fR command is issued, if one +already exists. +.IP +\fBcolor\fIN\fR +.br +These variables determine the colors used, if \fBX\fR is being run on +a color display. +\fIN\fR may be between 0 and 15. Color 0 is the background, color 1 +is the grid and text color, and colors 2 through 15 are used in order for +vectors plotted. The value of the \fBcolor\fR variables should be names +of colors, which may be found in the file \fB/usr/lib/rgb.txt\fR. +.IP +\fBcombplot\fR +.br +Plot vectors by drawing a vertical line from each point to the X-axis, +as opposed to joining the points. Note that this option is subsumed +in the \fIplottype\fR option, below. +.IP +\fBcpdebug\fR +.br +Print \fIcshpar\fR debugging information. (Must be complied with the +-DCPDEBUG flag.) +.IP +\fBdebug\fR +.br +If set then a lot of debugging information is printed. (Must be +compiled with the -DFTEDEBUG flag.) +.IP +\fBdevice\fR +.br +The name (/dev/tty??) of the graphics device. If this variable +isn't set then the user's terminal is used. To do plotting on +another monitor you will probably have to set both the \fBdevice\fR +and \fBterm\fR variables. (If \fBdevice\fR is set to the name of +a file, \fBnutmeg\fR will dump the graphics control codes into +this file -- this is useful for saving plots.) +.\".IP +.\"\fBdontplot\fR +.\".br +.\"No graphics control codes are actually sent. (Useful for debugging on +.\"non-graphics terminals.) +.IP +\fBecho\fR +.br +Print out each command before it is executed. +.IP +\fBfiletype\fR +.br +This can be either +.B ascii +or +.B binary, +and determines what the format of +.I rawfiles +will be. The default is +.B ascii. +.IP +\fBfourgridsize\fR +.br +How many points to use for interpolating into when doing fourier analysis. +.\".IP +.\"\fBgeometry\fIN\fR +.\".br +.\"The size and positioning information for X windows. \fIN\fR may be +.\"any positive integer, in which case it is the information for the \fIN\fR'th +.\"window on the screen, or may be omitted, in which case it is used whenever +.\"there is no information for the window. The geometry information is a string +.\"of the form \fR=\fIheight\fBx\fIwidth\fB+\fIxoff\fB+\fIyoff\fR, where the +.\"window will be of size \fIheight\fR by \fIwidth\fR and be positioned at +.\"(\fIxoff, yoff\fR), where (0,0) is the upper left hand corner of the screen. +.\"Either the positioning information or the size information may be omitted, +.\"in which case the window will be opened interactively (as will happen if no +.\"\fBgeometry\fR information is given). The method of interactive sizing is +.\"the same as for other X utilities. +.\"A typical use for the \fBgeometry\fR variables might be to set \fBmaxwins\fR +.\"to 3 and set \fBgeometry1, geometry2,\fR and \fBgeometry3\fR to position three +.\"plot windows in a row across the top of the screen. +.IP +\fBgridsize\fR +.br +If this variable is set to an integer, this number will be used as the number +of equally spaced points to use for the Y-axis when plotting. Otherwise +the current scale will be used (which may not have equally spaced points). +If the current scale isn't strictly monotonic, then this option will have +no effect. +.IP +\fBhcopydev\fR +.br +If this is set, when the \fBhardcopy\fR command is run the resulting file +is automatically printed on the printer named \fBhcopydev\fR with the +command \fIlpr -P\fBhcopydev\fI -g \fBfile\fR. +.IP +\fBhcopydevtype\fR +.br +This variable specifies the type of the printer output to use in the +\fBhardcopy\fR command. If hcopydevtype is not set, plot (5) format +is assumed. The standard distribution currently recognizes \fBpostscript\fR +as an alternative output format. When used in conjunction with +\fBhcopydev\fR, \fBhcopydevtype\fR should specify a format supported by +the printer. +.IP +\fBheight\fR +.br +The length of the page for \fBasciiplot\fR and \fBprint col\fR. +.IP +\fBhistory\fR +.br +The number of events to save in the history list. +.\".IP +.\"\fBmaxwins\fR +.\".br +.\"The maximum number of windows X should have on the screen at one time. +.\"If it has \fBmaxwins\fR or more windows, it will begin re-using them +.\"for plots in an oldest-first manner. +.IP +\fBnfreqs\fR +.br +The number of frequencies to compute in the +.B fourier +command. (Defaults to 10.) +.IP +\fBnobreak\fR +.br +Don't have \fBasciiplot\fR and \fBprint col\fR break between pages. +.IP +\fBnoasciiplotvalue\fR +.br +Don't print the first vector plotted to the left when doing an +\fBasciiplot\fR. +.IP +\fBnoclobber\fR +.br +Don't overwrite existing files when doing IO redirection. +.IP +\fBnoglob\fR +.br +Don't expand the global characters `*', `?', `[', and `]'. This is the +default. +.IP +\fBnogrid\fR +.br +Don't plot a grid when graphing curves (but do label the axes). +.IP +\fBnomoremode\fR +.br +If \fBnomoremode\fR is not set, whenever a large amount of data is being +printed to the screen (e.g, the \fBprint\fR or \fBasciiplot\fR commands), +the output will be stopped every screenful and will continue when +a carriage return is typed. If \fBnomoremode\fR is set then data will scroll +off the screen without hesitation. +.IP +\fBnonomatch\fR +.br +If \fBnoglob\fR is unset and a global expression cannot be matched, use +the global characters literally instead of complaining. +.IP +\fBnosort\fR +.br +Don't have \fBdisplay\fR sort the variable names. +.IP +\fBnoprintscale\fR +.br +Don't print the scale in the leftmost column when a \fBprint col\fR command +is given. +.IP +\fBnumdgt\fR +.br +The number of digits to print when printing tables of data (\fBfourier, print +col\fR). The default precision is 6 digits. On the VAX, approximately +16 decimal digits are available using double precision, so \fBnumdgt\fR +should not be more than 16. If the number is negative, one fewer digit +is printed to ensure constant widths in tables. +.IP +\fBplottype\fR +.br +This should be one of \fInormal\fR, \fIcomb\fR, or \fIpoint:\fBchars\fR. +\fInormal\fR, the default, causes points to be plotted as parts of connected +lines. \fIcomb\fR causes a comb plot to be done (see the description of the +\fIcombplot\fR variable above). \fIpoint\fR causes each point to be plotted +seperately \- the \fBchars\fR are a list of characters that will be used +for each vector plotted. If they are omitted then a default set is used. +.IP +\fBpolydegree\fR +.br +The degree of the polynomial that the \fBplot\fR command should fit +to the data. If \fIpolydegree\fR is N, then \fBnutmeg\fR will fit a degree N +polynomial to every set of N points and draw 10 intermediate points +in between each endpoint. If the points aren't monotonic, then it will try +rotating the curve and reducing the degree until a fit is achieved. +.IP +\fBpolysteps\fR +.br +The number of points to interpolate between every pair of points available +when doing curve fitting. The default is 10. (This should really be done +automatically.) +.IP +\fBprogram\fR +.br +The name of the current program (\fIargv[0]\fR). +.IP +\fBprompt\fR +.br +The prompt, with the character `!' replaced by the current event number. +.IP +\fBrawfile\fR +.br +The default name for rawfiles created. +.IP +\fBreltol\fR +.br +The relative tolerance used by the \fBdiff\fR command. +.IP +\fBrhost\fR +.br +The machine to use for remote \s-2SPICE-3\s+2 runs, instead of the +default one. (See the description of the \fBrspice\fR command, +below.) +.IP +\fBrprogram\fR +.br +The name of the remote program to use in the \fBrspice\fR command. +.\".IP +.\"\fBsavewins\fR +.\".br +.\"If true, then don't get rid of the plot window after the plot is done (X +.\"only). The window may be removed by clicking any mouse button inside of it. +.IP +\fBslowplot\fR +.br +Stop between each graph plotted and wait for the user to type +return before continuing. +.IP +\fBsourcepath\fR +.br +A list of the directories to search when a \fBsource\fR command is given. +The default is the current directory and the standard spice library +(\fI/usr/local/lib/spice\fR, or whatever \fBLIBPATH\fR is #defined to +in the \*S source. +.IP +\fBspicepath\fR +.br +The program to use for the \fBaspice\fR command. The default is +/cad/bin/spice. +.IP +\fBterm\fR +.br +The \fImfb\fR name of the current terminal. +.IP +\fBunits\fR +.br +If this is \fBdegrees\fR, then all the trig functions will use degrees +instead of radians. +.IP +\fBunixcom\fR +.br +If a command isn't defined, try to execute it as a \s-2UNIX\s+2 command. +Setting this option has the effect of giving a \fBrehash\fR command, +below. +This is useful for people who want to use \fBnutmeg\fR as a login shell. +.IP +\fBverbose\fR +.br +Be verbose. This is midway between \fBecho\fR and \fBdebug\fR / \fBcpdebug\fR. +.IP +\fBvntol\fR +.br +The absolute voltage tolerance used by the \fBdiff\fR command. +.IP +\fBwidth\fR +.br +The width of the page for \fBasciiplot\fR and \fBprint col\fR. +.IP +\fBxbrushheight\fR +.br +The height of the brush to use if \fBX\fR is being run. +.IP +\fBxbrushwidth\fR +.br +The width of the brush to use if \fBX\fR is being run. +.IP +\fBxfont\fR +.br +The name of the X font to use when plotting data and entering labels. +The plot may not look entirely great if this is a variable-width font. +.PP +.TP +\fBunset [word] ... \fR +Unset the variables \fBword\fR. +.TP +\fBshift [varname] [number]\fR +If \fIvarname\fR is the name of a list variable, it is shifted to the left +by \fInumber\fR elements. (I.e, the \fInumber\fR leftmost elements are +removed.) The default \fIvarname\fR is \fBargv\fR, and the default +\fInumber\fR is 1. +.TP +\fBrusage [resource ...]\fR +Print resource usage statistics. If any \fBresource\fR\&s are given, +just print the usage of that resource. Currently valid \fBresource\fR\&s +are: +.IP "" 16 +\fBelapsed\fR +.br +The amount of time elapsed since the last \fBrusage elaped\fR call. +.IP +\fBfaults\fR +.br +Number of page faults and context switches (BSD only). +.IP +\fBspace\fR +.br +Data space used. +.IP +\fBtime\fR +.br +CPU time used so far. +.IP +\fBeverything\fR +.br +All of the above. +.TP +\fBcd [directory]\fR +Change the current working directory to \fBdirectory\fR, or to the user's +home directory if none is given. +.TP +\fBaspice [output-file]\fR +Start a \s-2SPICE-3\s+2 run, and when it is finished load the data. The +raw data is kept in a temporary file. If \fIoutput-file\fR is specified +then the diagnostic output is directed into that file, otherwise it +is thrown away. +.TP +\fBjobs\fR +Report on the asynchronous \s-2SPICE-3\s+2 jobs currently running. +\fBNutmeg\fR 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. +.TP +\fBrspice [input file]\fR +Runs a \s-2SPICE-3\s+2 remotely taking the \fBinput file\fR as a +\s-2SPICE-3\s+2 input deck, or the current circuit if no argument is +given. \fBNutmeg\fR 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 \fRaspice\fR. If the variable +\fIrhost\fR is set, \fBnutmeg\fR will connect to this host instead of +the default remote \s-2SPICE-3\s+2 server machine. Note that this +command will only work if your system administrator is running a +\s-2SPICE-3\s+2 daemon on the remote host. If the variable \fIrprogram\fR +is set, then \fBrspice\fR will use this as the pathname to the program +to run. +.TP +\fBecho [stuff...]\fR +Echos the arguments. +.TP +\fBfourier fundamental_frequency [value ...]\fR +Does a fourier analysis of each of the given values, using the first 10 +multiples of the fundamental frequency (or the first \fInfreqs\fR, if that +variable is set \- see below). The output is like that of +the \fB.four\fR \*S card. The values may be any valid expression. +The values are interpolated onto a fixed-space grid with the number of +points given by the \fBfourgridsize\fR variable, or 200 if it is not set. +The interpolation will be of degree \fBpolydegree\fR if that variable is +set, or 1. If \fBpolydegree\fR is 0, then no interpolation will be done. +This is likely to give erroneous results if the time scale is not monotonic, +though. +.TP +\fBversion [version id]\fR +Print out the version of \fBnutmeg\fR that is running. +If there are arguments, it checks to make sure that the arguments match +the current version of \s-2SPICE\s+2. (This is mainly used as a \fBCommand:\fR +line in rawfiles.) +.TP +\fBrehash\fR +Recalculate the internal hash tables used when looking up UNIX commands, +and make all UNIX commands in the user's PATH available for command +completion. +This is useless unless you have \fBset unixcom\fR first (see above). +.PP +The following control structures are available: +.IP +.nf +\fBwhile\fR \fIcondition\fR + statement + ... +\fBend\fR +.fi +.PP +While \fIcondition\fR, an arbitrary algebraic expression, is true, +execute the statements. +.IP +.nf +\fBrepeat\fR \fI[number]\fR + statement + ... +\fBend\fR +.fi +.PP +Execute the statements \fInumber\fR times, or forever if no argument is +given. +.IP +.nf +\fBdowhile\fR \fIcondition\fR + statement + ... +\fBend\fR +.fi +.PP +The same as \fBwhile\fR, except that the \fIcondition\fR is tested after +the statements are executed. +.IP +.nf +\fBforeach\fR \fIvar\fR \fIvalue ...\fR + statement + ... +\fBend\fR +.fi +.PP +The statements are executed once for each of the \fIvalue\fRs, each time +with the variable \fIvar\fR set to the current one. (\fIvar\fR can be accessed +by the $\fIvar\fR notation \- see below). +.IP +.nf +\fBif\fR \fIcondition\fR + statement + ... +\fBelse\fR + statement + ... +\fBend\fR +.fi +.PP +If the \fIcondition\fR is non-zero then the first set of statements are +executed, otherwise the second set. The \fBelse\fR and the second set +of statements may be omitted. +.IP +\fBlabel\fR \fIword\fR +.PP +If a statement of the form \fBgoto\fI word\fR is encountered, control is +transfered to this point, otherwise this is a no-op. +.IP +\fBgoto\fR \fIword\fR +.PP +If a statement of the form \fBlabel\fI word\fR is present in the block +or an enclosing block, control is transfered there. Note that if the +label is at the top level, it \fImust\fR be before the \fBgoto\fR statement +(i.e, a forward \fBgoto\fR may occur only within a block). +.IP +\fBcontinue\fR +.PP +If there is a \fBwhile, dowhile,\fR or \fBforeach\fR block enclosing this +statement, control passes to the test, or in the case of \fBforeach\fR, +the next value is taken. +Otherwise an +error results. +.IP +\fBbreak\fR +.PP +If there is a \fBwhile, dowhile,\fR or \fBforeach\fR block enclosing this +statement, control passes out of the block. Otherwise an +error results. +.PP +Of course, control structures may be nested. When a block is entered +and the input is the terminal, the prompt becomes a number of >'s +equalling the number of blocks the user has entered. The current control +structures may be examined with the debugging command +.B cdump. +.PP +If a word is typed as a command, and there is no built-in command +with that name, the directories in the \fIsourcepath\fR list are searched +in order for the file. If it is found, it is read in as a command file (as +if it were \fBsource\fRd). Before it is read, however, the variables +\fIargc\fR and \fIargv\fR are set to the number of words following the +filename on the command line, and a list of those words respectively. +After the file is finished, these variables are \fBunset\fR. Note that +if a command file calls another, it must save its \fIargv\fR and \fIargc\fR +since they will get 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 \fBnutmeg\fR and +\*S. Note that for the script to work with \*S, it \fBmust\fR begin +with a blank line (or whatever you like, since it will be thrown away) +and then a line with \fB.control\fR on it. This is an unfortunate result +of the \fBsource\fR command being used for both circuit input and command +file execution. Note also that this allows the user to merely type the +name of a circuit file as a command, and it will be automatically run. +.PP +There are various command scripts installed in +\fI/usr/local/lib/spice/scripts\fR (or whatever the path is on your machine), +and the default \fIsourcepath\fR includes this directory, so you can use +these command files (almost) like builtin commands. +.PP +\fBNutmeg\fR will use either \fBX\fR or \fBMFB\fR, depending on whether +it finds the variable \fBDISPLAY\fR in the environment. If you are +using \fBX\fR on a workstation, it should already be present, but if you +want to display graphics on a different machine than the one you +are running \fBnutmeg\fR on, \fBDISPLAY\fR should be of the form +\fImachine\fR:0. +.PP +If \fBX\fR is being used, the cursor may be positioned at any +point on the screen when the window is up and characters typed at the +keyboard will be added to the window at that point. The window may +then be sent to a printer using the \fBxpr(1)\fR program. +.PP +There are a number of pre-defined constants in \fBnutmeg\fR. They are: +.na +.nf + pi pi + e The base of natural logarithms + c The speed of light + i The square root of -1 + kelvin Absolute 0 in Centigrade + echarge The charge on an electron + boltz Boltzman's constant + planck Planck's constant (h) + +.fi +.ad +.PP +These are all in MKS units. If you have another variable with +a name that conflicts with one of these then it takes precedence. +.PP +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 \s-2SPICE\s+2 +front end.) +.PP +C-shell type quoting with "" and '', and backquote substitution may +be used. Within single quotes, no further substitution (like +history substitution) is done, and within double quotes, the words +are kept together but further substitution is done. Any text between +backquotes is replaced by the result of executing the text as a command +to the shell. +.PP +Tenex-style ('set filec' in the 4.3 C-shell) +command, filename, and keyword completion is possible: If EOF +(control-D) is typed after the first character on the line, a list +of the commands or possible arguments is printed. (If it is alone +on the line it will exit \fBnutmeg\fR.) If escape is typed, then +\fBnutmeg\fR will try to complete what the user has already typed. +To get a list of all commands, the user should type ^D. +.PP +The values of variables may be used in commands by writing \fB$varname\fR +where the value of the variable is to appear. The special variables +\fI$$\fR and \fI$<\fR refer to the process ID of the program and a +line of input which is read from the terminal when the variable +is evaluated, respectively. If a variable has a name of the form +\fB$&word\fR, then \fBword\fR is considered a vector (see above), +and its value is taken to be the value of the variable. +If \fI$foo\fR is a valid variable, and is of type \fBlist\fR, then the +expression \fI$foo[low-high]\fR represents a range of elements. Either +the upper index or the lower may be left out, and the reverse of a list may +be obtained with \fI$foo[len-0]\fR. Also, the notation \fI$?foo\fR evaluates +to 1 if the variable \fIfoo\fR is defined, 0 otherwise, and \fI$#foo\fR +evaluates to the number of elements in \fIfoo\fR if it is a list, 1 if it +is a number or string, and 0 if it is a boolean variable. +.PP +History substitutions, similar to C-shell history substitutions, are +also available \- see the C-shell manual page for all of the details. +.PP +The characters ~, {, and } have the same effects as they do in the +C-Shell, i.e., home directory and alternative expansion. It is +possible to use the wildcard characters *, ?, [, and ] also, +but only if you \fBunset noglob\fR first. This makes them rather +useless for typing algebraic expressions, so you should \fBset noglob\fR +again after you are done with wildcard expansion. Note that the +pattern \fB[^abc]\fR will match all characters \fIexcept\fB a, b, +\fRand\fB c.\fR +.PP +IO redirection is available \- the symbols \fB>, >>, >&, >>&, \fRand\fB <\fR +have the same effects as in the C-shell. +.PP +You may type multiple commands on one line, seperated by semicolons. +.PP +If you want to use a different \fBmfbcap\fR file than the default (usually +\fB~cad/lib/mfbcap\fR), you have to set the environment variable \fBMFBCAP\fR +before you start \fBnutmeg\fR. The \fB-m\fR option and the \fBmfbcap\fR +variable no longer work. +.SH "VMS NOTES" +\fBNutmeg\fR can be run under VAX/VMS. Some features like command, etc +completion, expansion of *, ?, and [], backquote substitution, the +shell command, and so forth do not work. (In fact command completion +only works on 4.2 or 4.3 BSD.) +.PP +\fBNutmeg\fR will look for start-up +commands in the file \fIspice.rc\fR in the current directory. +.PP +The standard suffix for rawspice files in VMS is ".raw". +.PP +You will have to respond to the \fI-more-\fR prompt during plot with a +carriage return instead of any key as you can do on UNIX. +.SH "SEE ALSO" +sconvert(1), spice(1), mfb(3), writedata(3) +.SH AUTHOR +Wayne Christopher (faustus@cad.berkeley.edu) +.SH BUGS +.PP +The label entry facilities are very primitive \- after all, \fBnutmeg\fR isn't +a graphics editor (yet). You must be careful to type very slowly when +entering labels -- \fBnutmeg\fR checks the \fBX\fR event queue once +every second, and can get very confused if characters arrive faster than +that. +.PP +If you redefine colors after creating a plot window with X, and then +cause the window to be redrawn, it will not to the right thing. +.PP +When defining aliases like +.IP +\fIalias pdb plot db( '!:1' - '!:2' )\fR +.PP +you must be careful to quote the argument list substitutions in this +manner. If you quote the whole argument it might not work properly. +.PP +In a user-defined function, the arguments cannot be part of a name that +uses the \fIplot.vec\fR syntax. I.e, +.IP +\fIdefine poke(duck) cos(tran1.duck) +.PP +won't do the right thing. +.PP +If you type \fBplot all all\fR, or otherwise use a wildcard reference for +one plot twice in a command, bad things will happen. +.PP +The \fBasciiplot\fR command doesn't deal with log scales or the \fBdelta\fR +keywords. +.PP +There are probably some features that \fBnutmeg\fR doesn't have yet. +.SH CAVEATS +Often the names of terminals recognised by \fBMFB\fR are different +from those in /etc/termcap. Thus you may have to reset your terminal +type with the command +.IP +\fBset term = termname\fR +.PP +where \fBtermname\fR is the name in the \fBmfbcap\fR file. +.PP +The \fBhardcopy\fR command is useless on VMS and other systems without +the \fBplot\fR command, unless the user has a program that understands +\fIplot(5)\fR format. + diff --git a/man/man1/ngsconvert.1 b/man/man1/ngsconvert.1 new file mode 100644 index 000000000..6fcbc3a4f --- /dev/null +++ b/man/man1/ngsconvert.1 @@ -0,0 +1,127 @@ +.\" RCS Info: $Revision$ on $Date$ +.\" $Source$ +.\" Copyright (c) 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +.TH SCONVERT 1 "20 March 1986" +.UC 4 +.SH NAME +sconvert \- convert spice formats +.SH SYNOPSIS +.B sconvert fromtype fromfile totype tofile +.br +.B sconvert fromtype totype +.br +.B sconvert +.br +.SH DESCRIPTION +.B Sconvert +translates spice output files among three formats: the old +binary format, a new binary format, and a new ascii format. +The formats are specified by the +.B fromtype +and +.B totype +arguments: `o' for the old format, `b' for the new binary format, +and `a' for the new ascii format. +.B Fromtype +specifies the format to be read, and +.B totype +specifies the format to be written. +If +.B fromfile +and +.B tofile +are given, then they are used as the input and output, otherwise +standard input and output are used. (Note that this second option is +only available on \s-2UNIX\s+2 systems \- on VMS and other systems you must +supply the filenames.) +If no arguments are given, the parameters are prompted for. +.PP +Binary format is the preferred format for general use, as it is +the most economical in terms of space and speed of access, and ascii is +provided to make it easy to modify data files and transfer them +between machines with different floating-point formats. +The old format is provided only +for backward compatibility. The three formats are as follows: +.br +.nf + +.B Old: + + What Size in Bytes + + title 80 + date 8 + time 8 + numoutputs 2 + the integer 4 2 + variable names -- + char[numoutputs][8] numoutputs * 8 + types of output numoutputs * 2 + node index numoutputs * 2 + plot title numoutputs * 24 + the actual data numpoints * numoutputs * 8 + +.B Ascii: + + Title: \fITitle Card String\fR + Date: \fIDate\fR + [ Plotname: \fIPlot Name\fR + Flags: \fIcomplex\fR or \fIreal\fR + No. Variables: \fInumoutputs\fR + No. Points: \fInumpoints\fR + Command: \fInutmeg command\fR + Variables: 0 \fIvarname1\fR \fItypename1\fR + 1 \fIvarname2\fR \fItypename2\fR + etc... + Values: + 0 n n n n ... + 1 n n n n ... + And so forth... + ] repeated one or more times + +.PP +If one of the flags is \fIcomplex\fR, the points look like r,i where r and i +are floating point (in %e format). Otherwise they are in %e format. +Only one of \fIreal\fR and \fIcomplex\fR should appear. +.PP +The lines are guaranteed to be less than 80 columns wide (unless the +plot title or variable names are very long), so this format is safe +to mail between systems like CMS. +.PP +Any number of \fBCommand:\fR lines may appear between the \fBNo. Points:\fR +and the \fBVariables:\fR lines, and whenever the plot is loaded into +\fBnutmeg\fR they will be executed. +.nf + +.B Binary: + + \fITitle Card\fR (a NULL terminated string) + \fIDate, Time\fR (a NULL terminated string) + [ + \fIPlot title\fR (a NULL terminated string) + \fINumber of variables\fR (an int) + \fINumber of data points\fR (an int) + \fIflags\fR (a short) + \fIvariable header struct\fR (repeated numoutputs times) + \fIvariable name\fR (a NULL terminated string) + \fIvariable type\fR (an int) + \fIset of outputs\fR (repeated numpoints times) + ] repeated one or more times. + +.PP +A set of outputs is a vector of doubles of length numoutputs, or +a vector of real-imaginary pairs of doubles if the data is complex. +.SH "SEE ALSO" +nutmeg(1), spice(1), writedata(3) +.SH AUTHOR +Wayne Christopher (faustus@cad.berkeley.edu) +.SH BUGS +If variable names and the title +and plotname strings have trailing +blanks in them they will be stripped off when the file is read, if +it is in ascii format. +.PP +If a plot title begins with "Title:" \fBnutmeg\fR will be fooled into thinking +that this is an ascii format file. \fBSconvert\fR always requires the +type to be specified, however. + diff --git a/man/man1/ngspice.1 b/man/man1/ngspice.1 new file mode 100644 index 000000000..51385b861 --- /dev/null +++ b/man/man1/ngspice.1 @@ -0,0 +1,337 @@ +.\" RCS Info: $Revision$ on $Date$ +.\" $Source$ +.\" Copyright (c) 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +.TH SPICE 1 "20 March 1986" +.ds S \s-2SPICE\s+2\&3 +.UC 4 +.SH NAME +spice \- circuit simulator +.SH SYNOPSIS +\fBspice [ -n ] [ -t term ] [ -r rawfile] [ -b ] +[ -i ] [ input file ... ]\fR +.SH DESCRIPTION +This manual page describes the commands available for interactive +use of \*S. For details of circuit descriptions and the +process of simulating a circuit, see the \*S User's Manual. +The commands available are a superset of those available for +\fBnutmeg\fR \- only the additional commands available in \*S +are described here. You should be familiar with the manual page for +\fBnutmeg(1)\fR before reading this manual page. +.PP +Arguments are: +.TP +\fB-n\fR (or \fB--no-spiceinit\fR) +Don't try to source the file ".spiceinit" upon startup. Normally \*S +tries to find the file in the current directory, and if it is not found then +in the user's home directory. +.TP +\fB-q\fR (or \fB--completion\fR) +Enable command completion. +.TP +\fB-t term\fR (or \fB--term=term\fR) +The program is being run on a terminal with \fImfb\fR name \fBterm\fR. +.TP +\fB-b\fR (or \fB--batch\fR) +Run in batch mode. \*S will read the standard input or the specified +input file and do the simulation. Note that if the standard input +is not a terminal, \*S will default to batch mode, unless the +-i flag is given. +.TP +\fB-s\fR (or \fB--server\fR) +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. +.TP +\fB-i\fR (or \fB--interactive\fR) +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. +.TP +\fB-r rawfile\fR (or \fB--rawfile=file\fR) +Use \fBrawfile\fR as the default file into which the results of +the simulation are saved. +.TP +\fB-c circuitfile\fR (or \fB--circuitfile=circuitfile\fR) +Use \fBcircuitfile\fR as the default input deck. +.TP +\fB-h\fR (or \fB--help\fR) +Display a verbose help on the arguments available to the program. +.TP +\fB-v\fR (or \fB--version\fR) +Display a version number and copyright information of the program. +.PP +Further arguments are taken to be \*S input decks, which are read +and saved. (If batch mode is requested then they are run immediately.) +.PP +\*S will accept any \s-2SPICE\s+2\&2 input decks, and output +ascii plots, fourier analyses, and node printouts as specified +in .plot, .four, and .print cards. If a \fBout\fR parameter +is given on a .width card, the effect is the same as \fBset width = ...\fR. +Since \*S ascii plots do not use multiple ranges, however, if vectors +together on a .plot card have different ranges they will not provide +as much information as they would in \s-2SPICE\s+2\&2. The output +of \*S is also much less verbose than \s-2SPICE\s+2\&2, in that the only +data printed is that requested by the above cards. +.PP +Vector names are the same as in \fBnutmeg\fR, with this addition: +a name such as \fB@name[param]\fR, where \fBname\fR is either +the name of a device instance or model, denotes the value of the +\fBparam\fR parameter of the device or model. See the \*S User's +Manual for details of what parameters are available. The value is a +vector of length 1. This function is also available with the +\fBshow\fR command, and is available with variables for convenience for +command scripts. +.PP +\*S +commands are as follows (these are only those commands not also +available in \fBnutmeg\fR \- consult the \fBnutmeg\fR manual page for +more commands): +.TP +\fBsetcirc [circuit name]\fR +Change the current circuit. The current circuit is the one that is +used for the simulation commands below. When a circuit is loaded +with the \fIsource\fR command (see below) it becomes the +current circuit. +.TP +\fBop [.op card args]\fR +Do an operating point analysis. +.TP +\fBtran [.tran card args]\fR +Do a transient analysis. +.TP +\fBac [.ac card args]\fR +Do an ac analysis. +.TP +\fBdc [.dc card args]\fR +Do a dc transfer curve analysis. +.TP +\fBlisting [logical] [physical] [deck] [expand]\fR +Print a listing of the current circuit. If the \fBlogical\fR argument +is given, the listing is with all continuation lines collapsed +into one line, and if the \fBphysical\fR +argument is given the lines are printed out as they were found in +the file. The default is \fBlogical\fR. A \fBdeck\fR listing is just like +the \fBphysical\fR listing, except without the line numbers it recreates +the input file verbatim (except that it does not preserve case). +If the word \fBexpand\fR is present, the circuit will be printed with all +subcircuits expanded. +.TP +\fBedit [file]\fR +Print the current \*S deck 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 origonal deck. If a \fBfilename\fR is given, then edit that file +and load it, making the circuit the current one. +.TP +\fBresume\fR +Resume a simulation after a stop. +.TP +\fBshow \fR +Show a device parameter. +.TP +\fBalter \fR +Alter a device parameter. +.TP +\fBstate\fR +Print the state of the circuit. (This command is largely unimplemented.) +.TP +\fBsave [all] [output ...]\fR or \fB.save [all] [output ...]\fR +Save a set of outputs, discarding the rest. If a node has been mentioned +in a \fBsave\fR command, it will appear in the working plot after +a run has completed, or in the rawfile if spice is run in batch +mode. If a node is traced or plotted (see below) it will +also be saved. For backward compatibility, if there are \fBno\fR save +commands given, all outputs are saved. +.TP +\fBstop [ after n] [ when something cond something ] ... \fR +Set a breakpoint. The argument \fBafter n\fR means stop after \fBn\fR +iteration number \fBn\fR, and the argument +\fBwhen something cond something\fR means +stop when the first \fBsomething\fR is in the given relation with +the second \fBsomething\fR, the possible relations being +\fBeq\fR or = (equal to), +\fBne\fR or <> (not equal to), +\fBgt\fR or > (greater than), +\fBlt\fR or < (less than), +\fBge\fR or >= (greater than or equal to), and +\fBle\fR or <= (less than or equal to). +IO redirection is disabled for the \fBstop\fR command, since the relational +operations conflict with it (it doesn't produce any output anyway). +The \fBsomething\fR\&s above may be node names in +the running circuit, or real values. +If more than one condition is given, e.g. +\fBstop after 4 when v(1) > 4 when v(2) < 2\fR, the conjunction of +the conditions is implied. +.TP +\fBtrace [ node ...]\fR +Trace nodes. Every iteration the value of the node is printed to the +standard output. +.TP +\fBiplot [ node ...]\fR +Incrementally plot the values of the nodes while \*S runs. +.TP +\fBstep [number]\fR +Iterate \fBnumber\fR times, or once, and then stop. +.TP +\fBstatus\fR +Display all of the traces and breakpoints currently in effect. +.TP +\fBdelete [debug number ...]\fR +Delete the specified breakpoints and traces. The \fBdebug numbers\fR +are those shown by the \fBstatus\fR command. (Unless you do +\fBstatus > file\fR, in which case the debug numbers aren't printed.) +.TP +\fBreset\fR +Throw out any intermediate data in the circuit (e.g, after a breakpoint +or after one or more analyses have been done already), and re-parse +the deck. The circuit can then be re-run. (\fBNote\fR: this command +used to be \fBend\fR in \s-2SPICE\s+2 3a5 and earlier versions -- \fBend\fR +is now used for control structures.) The \fBrun\fR command will take +care of this automatically, so this command should not be necessary... +.TP +\fBrun [rawfile]\fR +Run the simulation as specified in the input file. If there were any +of the control cards .ac, .op, .tran, or .dc, they are executed. The output +is put in \fBrawfile\fR if it was given, in addition to being available +interactively. +.TP +\fBsource file\fR +Read the \*S input file \fBfile\fR. \fBNutmeg\fR and \*S commands may be +included in the file, and must be enclosed between the lines +\fI.control\fR and \fI.endc\fR. These commands +are executed immediately after the circuit is loaded, so a control line +of \fIac ...\fR will work the same as the corresponding \fI.ac\fR 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 \fI.spiceinit\fR. +Thus, a \*S command script must begin with a blank line and then with +a \fI.control\fR line. +Also, any line beginning with the characters *# is considered a control +line. This makes it possible to imbed commands in \*S input files +that will be ignored by earlier versions of \s-2SPICE\s+2. +\fINote:\fR in spice3a7 and before, the \fI.control\fR and \fI.endc\fR +lines were not needed, and any line beginning with the name of a front-end +command would be executed. +.TP +\fBlinearize vec ...\fR +Create a new plot with all of the vectors in the current plot, or +only those mentioned if arguments are given. The new vectors +will be interpolated onto a linear time scale, which is determined +by the values of \fBtstep, tstart,\fR and \fBtstop\fR in the +currently active transient analysis. The currently loaded deck +must include a transient analysis (a \fBtran\fR command may be run +interactively before the last \fBreset\fR, alternately), and the +current plot must be from this transient analysis. This command +is needed because \s-2SPICE\s+2\&3 doesn't output the results +from a transient analysis in the same manner that \s-2SPICE\s+2\&2 did. +.PP +There are several \fBset\fR variables that \*S uses but \fBnutmeg\fR +does not. They are: +.IP "" 16 +\fBeditor\fR +.br +The editor to use for the \fBedit\fR command. +.IP +\fBmodelcard\fR +.br +The name of the model card (normally \fB.model\fR). +.IP +\fBnoaskquit\fR +.br +Do not check to make sure that there are no circuits suspended and +no plots unsaved. Normally \*S will warn the user when he tries to +quit if this is the case. +.IP +\fBnobjthack\fR +.br +Assume that BJT's have 4 nodes. +.IP +\fBnoparse\fR +.br +Don't attempt to parse decks when they are read in (useful for +debugging). Of course, they +cannot be run if they are not parsed. +.IP +\fBnosubckt\fR +.br +Don't expand subcircuits. +.IP +\fBrenumber\fR +.br +Renumber input lines when a deck has \fB.include\fR's. +.IP +\fBsubend\fR +.br +The card to end subcircuits (normally \fB.ends\fR). +.IP +\fBsubinvoke\fR +.br +The prefix to invoke subcircuits (normally \fBx\fR). +.IP +\fBsubstart\fR +.br +The card to begin subcircuits (normally \fB.subckt\fR). +.PP +There are a number of \fBrusage\fR parameters available, in addition +to the ones available in \fBnutmeg\fR: +.IP "" 16 +.PP +If there are subcircuits in the input file, \*S expands instances of them. +A subcircuit is delimited by the cards +.B .subckt +and +.B .ends, +or whatever the value of the variables +.B substart +and +.B subend +is, respectively. An instance of a subcircuit is created by specifying +a device with type 'x' \- the device line is written +.IP +\fBxname node1 node2 ... subcktname\fR +.LP +where the nodes are the node names that replace the formal parameters +on the \fB.subckt\fR line. All nodes that are not formal parameters +are prepended with the name given to the instance and a ':', as are +the names of the devices in the subcircuit. If there are several nested +subcircuits, node and device names look like \fBsubckt1:subckt2:...:name\fR. +If the variable \fBsubinvoke\fR is set, then it is used as the prefix +that specifies instances of subcircuits, instead of 'x'. +.SH "VMS NOTES" +The standard suffix for rawspice files in VMS is ".raw". +.PP +You may have to redefine the value EDITOR if you wish to use the \fBedit\fR +command, since the default for VMS is "vi". +.SH "SEE ALSO" +nutmeg(1), sconvert(1), spice(1), mfb(3), writedata(3) +\*S User's Guide +.SH AUTHORS +\*S: Tom Quarles (quarles@cad.berkeley.edu) +.br +\fBnutmeg\fR / User interface: Wayne Christopher (faustus@cad.berkeley.edu) +.SH BUGS +.PP +\*S will recognise all the notations used in \s-2SPICE\s+2\&2 \fB.plot\fR +cards, and will translate \fBvp(1)\fR into \fBph(v(1))\fR, and so +forth. However, if there are spaces in these names it won't work. Hence +\fBv(1, 2)\fR and \fB(-.5, .5)\fR aren't recognised. +.PP +BJT's can have either 3 or 4 nodes, which makes it difficult for the subcircuit +expansion routines to decide what to rename. If the fourth parameter has +been declared as a model name, then it is assumed that there are 3 nodes, +otherwise it is considered a node. To disable this kludge, you can set +the variable "nobjthack", which will force BJT's to have 4 nodes (for the +purposes of subcircuit expansion, at least). +.PP +The \fB@name[param]\fR notation might not work with \fBtrace, iplot,\fR etc. +yet. +.PP +The first line of a command file (except for the \fI.spiceinit\fR file) +should be a comment. Otherwise \s-2SPICE\s+2 may create an empty circuit +structure. +.SH CAVEATS +.PP +\*S files specified on the command line are read in before the\fB .spiceinit\fR +file is read. Thus if you define aliases there that you call in a +\*S source file mentioned on the command line, they won't be recognised. + 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/README b/src/frontend/README new file mode 100644 index 000000000..9a1f9421f --- /dev/null +++ b/src/frontend/README @@ -0,0 +1,5 @@ +This directory contains the code that is behind the commands of the +interactive frontend. Note that every command has a source file +associated with it. The source file is prefixed with `com_' to +distinguish command source files from other supporting code. + 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/com_ahelp.c b/src/frontend/com_ahelp.c new file mode 100644 index 000000000..1f06d1d7e --- /dev/null +++ b/src/frontend/com_ahelp.c @@ -0,0 +1,89 @@ +#include +#include + +#include +#include +#include + +#include "variable.h" +#include "com_help.h" +#include "hcomp.h" +#include "ftehelp.h" + +#include "plotting/plotting.h" + + +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; + +} diff --git a/src/frontend/com_ahelp.h b/src/frontend/com_ahelp.h new file mode 100644 index 000000000..e246cec01 --- /dev/null +++ b/src/frontend/com_ahelp.h @@ -0,0 +1,7 @@ +#ifndef _COM_AHELP_H +#define _COM_AHELP_H + + +void com_ahelp(wordlist *wl); + +#endif diff --git a/src/frontend/com_alias.c b/src/frontend/com_alias.c new file mode 100644 index 000000000..645dc004d --- /dev/null +++ b/src/frontend/com_alias.c @@ -0,0 +1,241 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* Do alias substitution. */ + +#include "ngspice.h" +#include "cpdefs.h" +#include "com_alias.h" + +struct alias *cp_aliases = NULL; + + + +/* Return NULL if no alias was found. We can get away with just + * calling cp_histsubst now because the line will have gone onto the + * history list by now and cp_histsubst will look in the right place. */ +static wordlist * +asubst(wordlist *wlist) +{ + struct alias *al; + wordlist *wl, *w = NULL; + char *word; + + word = wlist->wl_word; + if (*word == '\\') { + wlist->wl_word++; + return (NULL); + } + for (al = cp_aliases; al; al = al->al_next) + if (eq(word, al->al_name)) + break; + if (!al) + return (NULL); + wl = cp_histsubst(wl_copy(al->al_text)); + + if (cp_didhsubst) { + /* Make sure that we have an up-to-date last history entry. */ + wl_free(cp_lastone->hi_wlist); + cp_lastone->hi_wlist = wl_copy(wl); + } else { + /* If it had no history args, then append the rest of the wl */ + for (w = wl; w->wl_next; w = w->wl_next); + w->wl_next = wl_copy(wlist->wl_next); + if (w->wl_next) + w->wl_next->wl_prev = w; + } + return (wl); +} + + + +/* MW. This function should not use cp_lastone, see cp_parse in cpshar.c + * Many things are deleted here and memory leak closed */ +wordlist * +cp_doalias(wordlist *wlist) +{ + int ntries; + wordlist *nwl, *nextc = NULL, *end = NULL; + wordlist *comm; + + while (wlist && eq(wlist->wl_word, cp_csep)) + wlist = wlist->wl_next; + wlist->wl_prev = NULL; + + /* The alias process is going to modify the "last" line typed, so + * save a copy of what it really is and restore it after aliasing + * is done. We have to do tricky things do get around the problems + * with ; ... */ + comm = wlist; + do { + end = comm->wl_prev; + comm->wl_prev = NULL; + for (nextc = comm; nextc; nextc = nextc->wl_next) + if (eq(nextc->wl_word, cp_csep)) { + if (nextc->wl_prev) + nextc->wl_prev->wl_next = NULL; + break; + } + + for (ntries = 21; ntries; ntries--) { + nwl = asubst(comm); + if (nwl == NULL) + break; + if (eq(nwl->wl_word, comm->wl_word)) { + /* Just once through... */ + wl_free(comm); + comm = nwl; + break; + } else { + wl_free(comm); + comm = nwl; + } + } + + if (!ntries) { + fprintf(cp_err, "Error: alias loop.\n"); + wlist->wl_word = NULL; + return (wlist); + } + comm->wl_prev = end; + if (!end) + wlist = comm; + else + end->wl_next = comm; + while (comm->wl_next) + comm = comm->wl_next; + comm->wl_next = nextc; + if (nextc) { + nextc->wl_prev = comm; + nextc = nextc->wl_next; + comm = nextc; + } + } while (nextc); + + return (wlist); +} + + +/* If we use this, aliases will be in alphabetical order. */ +void +cp_setalias(char *word, wordlist *wlist) +{ + struct alias *al, *ta; + + cp_unalias(word); + cp_addkword(CT_ALIASES, word); + if (cp_aliases == NULL) { + al = cp_aliases = alloc(struct alias); + al->al_next = NULL; + al->al_prev = NULL; + } else { + for (al = cp_aliases; al->al_next; al = al->al_next) { + if (strcmp(al->al_name, word) > 0) + break; + } + /* The new one goes before al */ + if (al->al_prev) { + al = al->al_prev; + ta = al->al_next; + al->al_next = alloc(struct alias); + al->al_next->al_prev = al; + al = al->al_next; + al->al_next = ta; + ta->al_prev = al; + } else { + cp_aliases = alloc(struct alias); + cp_aliases->al_next = al; + cp_aliases->al_prev = NULL; + al->al_prev = cp_aliases; + al = cp_aliases; + } + } + al->al_name = copy(word); + al->al_text = wl_copy(wlist); + cp_striplist(al->al_text); + /* We can afford to not worry about the bits, because before the + * keyword lookup is done the alias is evaluated. Make everything + * file completion, just in case... */ + cp_addcomm(word, (long) 1, (long) 1, (long) 1, (long) 1); + return; +} + +void +cp_unalias(char *word) +{ + struct alias *al; + + cp_remkword(CT_ALIASES, word); + for (al = cp_aliases; al; al = al->al_next) + if (eq(word, al->al_name)) + break; + if (al == NULL) + return; + if (al->al_next) + al->al_next->al_prev = al->al_prev; + if (al->al_prev) + al->al_prev->al_next = al->al_next; + else { + al->al_next->al_prev = NULL; + cp_aliases = al->al_next; + } + wl_free(al->al_text); + tfree(al->al_name); + tfree(al); + cp_remcomm(word); + return; +} + +void +cp_paliases(char *word) +{ + struct alias *al; + + for (al = cp_aliases; al; al = al->al_next) + if ((word == NULL) || eq(al->al_name, word)) { + if (!word) + fprintf(cp_out, "%s\t", al->al_name); + wl_print(al->al_text, cp_out); + (void) putc('\n', cp_out); + } + return; +} + +/* The routine for the "alias" command. */ + +void +com_alias(wordlist *wl) +{ + if (wl == NULL) + cp_paliases((char *) NULL); + else if (wl->wl_next == NULL) + cp_paliases(wl->wl_word); + else + cp_setalias(wl->wl_word, wl->wl_next); + return; +} + +void +com_unalias(wordlist *wl) +{ + struct alias *al, *na; + + if (eq(wl->wl_word, "*")) { + for (al = cp_aliases; al; al = na) { + na = al->al_next; + wl_free(al->al_text); + tfree(al->al_name); + tfree(al); + } + cp_aliases = NULL; + wl = wl->wl_next; + } + while (wl != NULL) { + cp_unalias(wl->wl_word); + wl = wl->wl_next; + } + return; +} + diff --git a/src/frontend/com_alias.h b/src/frontend/com_alias.h new file mode 100644 index 000000000..446117ba9 --- /dev/null +++ b/src/frontend/com_alias.h @@ -0,0 +1,16 @@ +/************* + * Header file for alias.c + * 1999 E. Rouat + ************/ + +#ifndef ALIAS_H_INCLUDED +#define ALIAS_H_INCLUDED + +wordlist * cp_doalias(wordlist *wlist); +void cp_setalias(char *word, wordlist *wlist); +void cp_unalias(char *word); +void cp_paliases(char *word); +void com_alias(wordlist *wl); +void com_unalias(wordlist *wl); + +#endif diff --git a/src/frontend/com_asciiplot.c b/src/frontend/com_asciiplot.c new file mode 100644 index 000000000..9576e1653 --- /dev/null +++ b/src/frontend/com_asciiplot.c @@ -0,0 +1,17 @@ +#include +#include + +#include +#include + +#include "plotting/plotit.h" + +#include "com_asciiplot.h" + + +void +com_asciiplot(wordlist *wl) +{ + plotit(wl, (char *) NULL, "lpr"); + return; +} diff --git a/src/frontend/com_asciiplot.h b/src/frontend/com_asciiplot.h new file mode 100644 index 000000000..b502c33be --- /dev/null +++ b/src/frontend/com_asciiplot.h @@ -0,0 +1,7 @@ +#ifndef _COM_ASCIIPLOT_H +#define _COM_ASCIIPLOT_H + +void com_asciiplot(wordlist *wl); + +#endif + diff --git a/src/frontend/com_cdump.c b/src/frontend/com_cdump.c new file mode 100644 index 000000000..3982e5fba --- /dev/null +++ b/src/frontend/com_cdump.c @@ -0,0 +1,140 @@ +#include + +#include + +#include "control.h" +#include "streams.h" + + +static int indent; + + +static void +tab(int num) +{ + int i; + + for (i = 0; i < num; i++) + putc(' ', cp_out); +} + + +static void +dodump(struct control *cc) +{ + struct control *tc; + + switch (cc->co_type) { + case CO_UNFILLED: + tab(indent); + fprintf(cp_out, "(unfilled)\n"); + break; + case CO_STATEMENT: + tab(indent); + wl_print(cc->co_text, cp_out); + putc('\n', cp_out); + break; + case CO_WHILE: + tab(indent); + fprintf(cp_out, "while "); + wl_print(cc->co_cond, cp_out); + putc('\n', cp_out); + indent += 8; + for (tc = cc->co_children; tc; tc = tc->co_next) + dodump(tc); + indent -= 8; + tab(indent); + fprintf(cp_out, "end\n"); + break; + case CO_REPEAT: + tab(indent); + fprintf(cp_out, "repeat "); + if (cc->co_numtimes != -1) + fprintf(cp_out, "%d\n", cc->co_numtimes); + else + putc('\n', cp_out); + indent += 8; + for (tc = cc->co_children; tc; tc = tc->co_next) + dodump(tc); + indent -= 8; + tab(indent); + fprintf(cp_out, "end\n"); + break; + case CO_DOWHILE: + tab(indent); + fprintf(cp_out, "dowhile "); + wl_print(cc->co_cond, cp_out); + putc('\n', cp_out); + indent += 8; + for (tc = cc->co_children; tc; tc = tc->co_next) + dodump(tc); + indent -= 8; + tab(indent); + fprintf(cp_out, "end\n"); + break; + case CO_IF: + tab(indent); + fprintf(cp_out, "if "); + wl_print(cc->co_cond, cp_out); + putc('\n', cp_out); + indent += 8; + for (tc = cc->co_children; tc; tc = tc->co_next) + dodump(tc); + indent -= 8; + tab(indent); + fprintf(cp_out, "end\n"); + break; + case CO_FOREACH: + tab(indent); + fprintf(cp_out, "foreach %s ", cc->co_foreachvar); + wl_print(cc->co_text, cp_out); + putc('\n', cp_out); + indent += 8; + for (tc = cc->co_children; tc; tc = tc->co_next) + dodump(tc); + indent -= 8; + tab(indent); + fprintf(cp_out, "end\n"); + break; + case CO_BREAK: + tab(indent); + if (cc->co_numtimes != 1) + fprintf(cp_out, "break %d\n", cc->co_numtimes); + else + fprintf(cp_out, "break\n"); + break; + case CO_CONTINUE: + tab(indent); + if (cc->co_numtimes != 1) + fprintf(cp_out, "continue %d\n", + cc->co_numtimes); + else + fprintf(cp_out, "continue\n"); + break; + case CO_LABEL: + tab(indent); + fprintf(cp_out, "label %s\n", cc->co_text->wl_word); + break; + case CO_GOTO: + tab(indent); + fprintf(cp_out, "goto %s\n", cc->co_text->wl_word); + break; + default: + tab(indent); + fprintf(cp_out, "bad type %d\n", cc->co_type); + break; + } + return; +} + + +void +com_cdump(wordlist *wl) +{ + struct control *c; + + indent = 0; + for (c = control[stackp]; c; c = c->co_next) + dodump(c); + return; +} diff --git a/src/frontend/com_cdump.h b/src/frontend/com_cdump.h new file mode 100644 index 000000000..ec6e5e145 --- /dev/null +++ b/src/frontend/com_cdump.h @@ -0,0 +1,6 @@ +#ifndef _COM_CDUMP_H +#define _COM_CDUMP_H + +void com_cdump(wordlist *wl); + +#endif diff --git a/src/frontend/com_chdir.c b/src/frontend/com_chdir.c new file mode 100644 index 000000000..18e61bcee --- /dev/null +++ b/src/frontend/com_chdir.c @@ -0,0 +1,58 @@ +#include +#include + +#include + +#include "quote.h" +#include "streams.h" + + +void +com_chdir(wordlist *wl) +{ + char *s; + struct passwd *pw; + extern struct passwd *getpwuid(uid_t); + char localbuf[257]; + int copied = 0; + + s = NULL; + + if (wl == NULL) { + + s = getenv("HOME"); + +#ifdef HAVE_PWD_H + if (s == NULL) { + pw = getpwuid(getuid()); + if (pw == NULL) { + fprintf(cp_err, "Can't get your password entry\n"); + return; + } + s = pw->pw_dir; + } +#endif + } else { + s = cp_unquote(wl->wl_word); + copied = 1; + } + + + + if (*s && chdir(s) == -1) + perror(s); + + if (copied) + tfree(s); + +#ifdef HAVE_GETCWD + s = getcwd(localbuf, sizeof(localbuf)); + if (s) + printf("Current directory: %s\n", s); + else + fprintf(cp_err, "Can't get current working directory.\n"); +#endif + + return; + +} diff --git a/src/frontend/com_compose.c b/src/frontend/com_compose.c new file mode 100644 index 000000000..1e0ee732e --- /dev/null +++ b/src/frontend/com_compose.c @@ -0,0 +1,484 @@ +/* The 'compose' command. This is a more powerful and convenient form + * of the 'let' command. */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "quote.h" +#include "com_compose.h" +#include "completion.h" + +/* Copy the data from a vector into a buffer with larger dimensions. */ +static void +dimxpand(struct dvec *v, int *newdims, double *data) +{ + complex *cdata = (complex *) data; + bool realflag = isreal(v); + int i, j, o, n, t, u; + int ncount[MAXDIMS], ocount[MAXDIMS]; + + for (i = 0; i < MAXDIMS; i++) + ncount[i] = ocount[i] = 0; + + for (;;) { + for (o = n = i = 0; i < v->v_numdims; i++) { + for (j = i, t = u = 1; j < v->v_numdims; j++) { + t *= v->v_dims[j]; + u *= newdims[j]; + } + o += ocount[i] * t; + n += ncount[i] * u; + } + + if (realflag) { + data[n] = v->v_realdata[o]; + } else { + realpart(&cdata[n]) = realpart(&v->v_compdata[o]); + imagpart(&cdata[n]) = imagpart(&v->v_compdata[o]); + } + /* Now find the nextstrchr element... */ + for (i = v->v_numdims - 1; i >= 0; i--) { + if ((ocount[i] < v->v_dims[i] - 1) && + (ncount[i] < newdims[i] - 1)) { + ocount[i]++; + ncount[i]++; + break; + } else + ocount[i] = ncount[i] = 0; + } + if (i < 0) + break; + } + + return; +} + + + + +/* The general syntax is 'compose name parm = val ...' + * The possible parms are: + * start The value at which the vector should start. + * stop The value at which the vector should end. + * step The difference between sucessive elements. + * lin The number of points, linearly spaced. + * log The number of points, logarithmically spaced. + * dec The number of points per decade, logarithmically spaced. + * center Where to center the range of points. + * span The size of the range of points. + * unif ?? + * gauss The number of points in the gaussian distribution. + * mean The mean value for the gass. dist. + * sd The standard deviation for the gauss. dist. + * random The number of randomly selected points. + * pool The name of a vector (must be already defined) to get + * random values -- default is 'unitvec(npoints)' + * + * The case 'compose name values val val ...' takes the values and creates a + * new vector -- the vals may be arbitrary expressions. + * + * NOTE: most of this doesn't work -- there will be plenty of unused variable + * lint messages... + */ + +void +com_compose(wordlist *wl) +{ + double start = 0.0; + double stop = 0.0; + double step = 0.0; + double lin = 0.0; + double center; + double span; + double mean, sd; + bool startgiven = FALSE, stopgiven = FALSE, stepgiven = FALSE; + bool lingiven = FALSE; + bool loggiven = FALSE, decgiven = FALSE, gaussgiven = FALSE; + bool randmgiven = FALSE; + bool spangiven = FALSE; + bool centergiven = FALSE; + bool meangiven = FALSE; + bool poolgiven = FALSE; + bool sdgiven = FALSE; + int log, dec, gauss, randm; + char *pool; + int i; + + char *resname, *s, *var, *val; + double *td, tt; + double *data = NULL; + complex *cdata = NULL; + int length = 0; + int dim, type = SV_NOTYPE, blocksize; + bool realflag = TRUE; + int dims[MAXDIMS]; + struct dvec *result, *vecs = NULL, *v, *lv = NULL; + struct pnode *pn, *first_pn; + bool reverse = FALSE; + + resname = cp_unquote(wl->wl_word); + vec_remove(resname); + wl = wl->wl_next; + if (eq(wl->wl_word, "values")) { + /* Build up the vector from the rest of the line... */ + wl = wl->wl_next; + if (!(pn = ft_getpnames(wl, TRUE))) + return; + first_pn = pn; + while (pn) { + if (!(v = ft_evaluate(pn))) + return; + if (!vecs) + vecs = lv = v; + else + lv->v_link2 = v; + for (lv = v; lv->v_link2; lv = lv->v_link2) + ; + pn = pn->pn_next; + } + free_pnode(first_pn); + /* Now make sure these are all of the same dimensionality. We + * can coerce the sizes... + */ + dim = vecs->v_numdims; + if (dim < 2) + dim = (vecs->v_length > 1) ? 1 : 0; + if (dim == MAXDIMS) { + fprintf(cp_err, "Error: max dimensionality is %d\n", + MAXDIMS); + return; + } + for (v = vecs; v; v = v->v_link2) + if (v->v_numdims < 2) + v->v_dims[0] = v->v_length; + + for (v = vecs->v_link2, length = 1; v; v = v->v_link2) { + i = v->v_numdims; + if (i < 2) + i = (v->v_length > 1) ? 1 : 0; + if (i != dim) { + fprintf(cp_err, + "Error: all vectors must be of the same dimensionality\n"); + return; + } + length++; + if (iscomplex(v)) + realflag = FALSE; + } + for (i = 0; i < dim; i++) { + dims[i] = vecs->v_dims[i]; + for (v = vecs->v_link2; v; v = v->v_link2) + if (v->v_dims[i] > dims[i]) + dims[i] = v->v_dims[i]; + } + dim++; + dims[dim - 1] = length; + for (i = 0, blocksize = 1; i < dim - 1; i++) + blocksize *= dims[i]; + if (realflag) + data = (double *) tmalloc(sizeof (double) * length * + blocksize); + else + cdata = (complex *) tmalloc(sizeof (complex) * length * + blocksize); + + /* Now copy all the data over... If the sizes are too small + * then the extra elements are left as 0. + */ + for (v = vecs, i = 0; v; v = v->v_link2) { + if (dim == 1) { + if (realflag && isreal(v)) + data[i] = v->v_realdata[0]; + else if (isreal(v)) { + realpart(&cdata[i]) = + realpart(&v->v_compdata[0]); + imagpart(&cdata[i]) = 0.0; + } else { + realpart(&cdata[i]) = + realpart(&v->v_compdata[0]); + imagpart(&cdata[i]) = + imagpart(&v->v_compdata[0]); + } + i++; + continue; + } + dimxpand(v, dims, (realflag ? (data + i * blocksize) : + (double *) (cdata + i * blocksize))); + } + + length *= blocksize; + } else { + /* Parse the line... */ + while (wl) { + if ((s =strchr(wl->wl_word, '=')) && s[1]) { + /* This is var=val. */ + *s = '\0'; + var = wl->wl_word; + val = s + 1; + wl = wl->wl_next; + } else if (index(wl->wl_word, '=')) { + /* This is var= val. */ + *s = '\0'; + var = wl->wl_word; + wl = wl->wl_next; + if (wl) { + val = wl->wl_word; + wl = wl->wl_next; + } else { + fprintf(cp_err, "Error: bad syntax\n"); + return; + } + } else { + /* This is var =val or var = val. */ + var = wl->wl_word; + wl = wl->wl_next; + if (wl) { + val = wl->wl_word; + if (*val != '=') { + fprintf(cp_err, + "Error: bad syntax\n"); + return; + } + val++; + if (!*val) { + wl = wl->wl_next; + if (wl) { + val = wl->wl_word; + } else { + fprintf(cp_err, + "Error: bad syntax\n"); + return; + } + } + wl = wl->wl_next; + } else { + fprintf(cp_err, "Error: bad syntax\n"); + return; + } + } + if (cieq(var, "start")) { + startgiven = TRUE; + if (!(td = ft_numparse(&val, FALSE))) { + fprintf(cp_err, + "Error: bad parm %s = %s\n", + var, val); + return; + } + start = *td; + } else if (cieq(var, "stop")) { + stopgiven = TRUE; + if (!(td = ft_numparse(&val, FALSE))) { + fprintf(cp_err, + "Error: bad parm %s = %s\n", + var, val); + return; + } + stop = *td; + } else if (cieq(var, "step")) { + stepgiven = TRUE; + if (!(td = ft_numparse(&val, FALSE))) { + fprintf(cp_err, + "Error: bad parm %s = %s\n", + var, val); + return; + } + step = *td; + } else if (cieq(var, "center")) { + centergiven = TRUE; + if (!(td = ft_numparse(&val, FALSE))) { + fprintf(cp_err, + "Error: bad parm %s = %s\n", + var, val); + return; + } + center = *td; + } else if (cieq(var, "span")) { + spangiven = TRUE; + if (!(td = ft_numparse(&val, FALSE))) { + fprintf(cp_err, + "Error: bad parm %s = %s\n", + var, val); + return; + } + span = *td; + } else if (cieq(var, "mean")) { + meangiven = TRUE; + if (!(td = ft_numparse(&val, FALSE))) { + fprintf(cp_err, + "Error: bad parm %s = %s\n", + var, val); + return; + } + mean = *td; + } else if (cieq(var, "sd")) { + sdgiven = TRUE; + if (!(td = ft_numparse(&val, FALSE))) { + fprintf(cp_err, + "Error: bad parm %s = %s\n", + var, val); + return; + } + sd = *td; + } else if (cieq(var, "lin")) { + lingiven = TRUE; + if (!(td = ft_numparse(&val, FALSE))) { + fprintf(cp_err, + "Error: bad parm %s = %s\n", + var, val); + return; + } + lin = *td; + } else if (cieq(var, "log")) { + loggiven = TRUE; + if (!(td = ft_numparse(&val, FALSE))) { + fprintf(cp_err, + "Error: bad parm %s = %s\n", + var, val); + return; + } + log = *td; + } else if (cieq(var, "dec")) { + decgiven = TRUE; + if (!(td = ft_numparse(&val, FALSE))) { + fprintf(cp_err, + "Error: bad parm %s = %s\n", + var, val); + return; + } + dec = *td; + } else if (cieq(var, "gauss")) { + gaussgiven = TRUE; + if (!(td = ft_numparse(&val, FALSE))) { + fprintf(cp_err, + "Error: bad parm %s = %s\n", + var, val); + return; + } + gauss = *td; + } else if (cieq(var, "random")) { + randmgiven = TRUE; + if (!(td = ft_numparse(&val, FALSE))) { + fprintf(cp_err, + "Error: bad parm %s = %s\n", + var, val); + return; + } + randm = *td; + } else if (cieq(var, "pool")) { + poolgiven = TRUE; + pool = val; + } + } + +#ifdef LINT +/* XXX Now, doesn't this look just a little suspicious */ + if (centergiven || spangiven || meangiven || sdgiven || + poolgiven) + j = k = l = m = q = inds = center + span + mean + sd + + log + dec + gauss + randm + pool; +#endif + /* Now see what we have... start and stop are pretty much + * compatible with everything... + */ + if (stepgiven && (step == 0.0)) { + fprintf(cp_err, "Error: step cannot = 0.0\n"); + return; + } + if (startgiven && stopgiven && (start > stop)) { + tt = start; + start = stop; + stop = tt; + reverse = TRUE; + } + if (lingiven + loggiven + decgiven + randmgiven + gaussgiven + > 1) { + fprintf(cp_err, + "Error: can have at most one of (lin, log, dec, random, gauss)\n"); + return; + } else if (lingiven + loggiven + decgiven + randmgiven + + gaussgiven == 0) { + /* Hmm, if we have a start, stop, and step we're ok. */ + if (startgiven && stopgiven && stepgiven) { + lingiven = TRUE; + lin = (stop - start) / step + 1; + stepgiven = FALSE; /* Problems below... */ + } else { + fprintf(cp_err, +"Error: either one of (lin, log, dec, random, gauss) must be given, or all\n"); + fprintf(cp_err, + "\tof (start, stop, and step) must be given.\n"); + return; + } + } + if (lingiven) { + /* Create a linear sweep... */ + data = (double *) tmalloc(sizeof (double) * (int) lin); + if (stepgiven && startgiven && stopgiven) { + if (step != (stop - start) / lin * (reverse ? + -1 : 1)) { + fprintf(cp_err, + "Warning: bad step -- should be %g\n", + (stop - start) / lin * + (reverse ? -1 : 1)); + stepgiven = FALSE; + } + } + if (!startgiven) { + if (stopgiven && stepgiven) { + start = stop - step * lin; + } else if (stopgiven) { + start = stop - lin; + } else { + start = 0; + } + startgiven = TRUE; + } + if (!stopgiven) { + if (stepgiven) + stop = start + lin * step; + else + stop = start + lin; + stopgiven = TRUE; + } + if (!stepgiven) { + step = (stop - start) / lin; + } + if (reverse) + for (i = 0, tt = stop; i < lin; + i++, tt -= step) + data[i] = tt; + else + for (i = 0, tt = start; i < lin; + i++, tt += step) + data[i] = tt; + length = lin; + } else if (loggiven || decgiven) { + /* Create a log sweep... */ + } else if (randmgiven) { + /* Create a set of random values... */ + } else if (gaussgiven) { + /* Create a gaussian distribution... */ + } + } + result = alloc(struct dvec); + ZERO(result, struct dvec); + result->v_name = copy(resname); + result->v_type = type; + result->v_flags = (realflag ? VF_REAL : VF_COMPLEX) | VF_PERMANENT; + if (realflag) + result->v_realdata = data; + else + result->v_compdata = cdata; + result->v_length = length; + result->v_numdims = 1; + result->v_dims[0] = length; + vec_new(result); + cp_addkword(CT_VECTOR, result->v_name); + tfree(resname);/*DG: resname has been copied so its remains allocated: memory leak One can remove this and not copy resname*/ + return; +} diff --git a/src/frontend/com_compose.h b/src/frontend/com_compose.h new file mode 100644 index 000000000..5f2d72516 --- /dev/null +++ b/src/frontend/com_compose.h @@ -0,0 +1,10 @@ + +#ifndef _COM_COMPOSE_H +#define _COM_COMPOSE_H + +#include + + +void com_compose(wordlist *wl); + +#endif diff --git a/src/frontend/com_display.c b/src/frontend/com_display.c new file mode 100644 index 000000000..71c0c2e31 --- /dev/null +++ b/src/frontend/com_display.c @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#include + +#include "com_display.h" +#include "quote.h" +#include "variable.h" +#include "plotting/plotting.h" +#include "plotting/pvec.h" + + +/* For the sort in display. */ +static int +dcomp(const void *d1, const void *d2) +{ + struct dvec **v1 = (struct dvec **) d1; + struct dvec **v2 = (struct dvec **) d2; + + return (strcmp((*v1)->v_name, (*v2)->v_name)); +} + + + +/* 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); + tfree(s);/*DG to avoid the cp_unquote memory leak */ + 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; +} diff --git a/src/frontend/com_display.h b/src/frontend/com_display.h new file mode 100644 index 000000000..d7bb80b4d --- /dev/null +++ b/src/frontend/com_display.h @@ -0,0 +1,8 @@ +#ifndef _COM_DISPLAY_H +#define _COM_DISPLAY_H + +#include + +void com_display(wordlist *wl); + +#endif diff --git a/src/frontend/com_dl.c b/src/frontend/com_dl.c new file mode 100755 index 000000000..b219393d5 --- /dev/null +++ b/src/frontend/com_dl.c @@ -0,0 +1,24 @@ +#include /* for wl */ +#include "ftedefs.h" +#include /* solve deps in dev.h*/ +#include <../spicelib/devices/dev.h> /*for load library commands*/ + +#ifdef XSPICE +void com_codemodel(wordlist *wl){ + wordlist *ww; + for(ww = wl;ww;ww = ww->wl_next) + if(load_opus(wl->wl_word)) + fprintf(cp_err,"Error: Library %s couldn't be loaded!\n",ww->wl_word); + return; +} +#endif +#ifdef DEVLIB +void com_use(wordlist *wl){ + wordlist *ww; + for(ww = wl;ww;ww = ww->wl_next) + if(load_dev(wl->wl_word)) + fprintf(cp_err,"Error: Library %s couldn't be loaded!\n",ww->wl_word); + return; +} +#endif + diff --git a/src/frontend/com_dl.h b/src/frontend/com_dl.h new file mode 100755 index 000000000..e8210cefd --- /dev/null +++ b/src/frontend/com_dl.h @@ -0,0 +1,12 @@ +#ifndef _COM_DL_H +#define _COM_DL_H 1 + +#ifdef XSPICE +void com_codemodel(wordlist *wl); +#endif + +#ifdef DEVLIB +void com_use(wordlist *wl); +#endif + +#endif diff --git a/src/frontend/com_dump.c b/src/frontend/com_dump.c new file mode 100644 index 000000000..25caa31b2 --- /dev/null +++ b/src/frontend/com_dump.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include +#include "circuits.h" +#include "com_dump.h" +#include "streams.h" +#include "fteext.h" + + +void +com_dump(wordlist *wl) +{ + if (!ft_curckt || !ft_curckt->ci_ckt) { + fprintf(cp_err, "Error: no circuit loaded.\n"); + return; + } + if_dump(ft_curckt->ci_ckt, cp_out); + return; +} diff --git a/src/frontend/com_dump.h b/src/frontend/com_dump.h new file mode 100644 index 000000000..36441e406 --- /dev/null +++ b/src/frontend/com_dump.h @@ -0,0 +1,6 @@ +#ifndef _COM_DUMP_H +#define _COM_DUMP_H + +void com_dump(wordlist *wl); + +#endif diff --git a/src/frontend/com_echo.c b/src/frontend/com_echo.c new file mode 100644 index 000000000..6c980b4b3 --- /dev/null +++ b/src/frontend/com_echo.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include + +#include "quote.h" +#include "streams.h" + +void +com_echo(wordlist *wlist) +{ char*copyword; + bool nl = TRUE; + + if (wlist && eq(wlist->wl_word, "-n")) { + wlist = wlist->wl_next; + nl = FALSE; + } + + while (wlist) { + /* fputs(cp_unquote(wlist->wl_word), cp_out); very bad the string allocated by cp_unquote could not be freed: memory leak*/ + copyword=cp_unquote(wlist->wl_word); + fputs(copyword, cp_out); + tfree(copyword); + if (wlist->wl_next) + fputs(" ", cp_out); + wlist = wlist->wl_next; + } + if (nl) + fputs("\n", cp_out); +} + diff --git a/src/frontend/com_ghelp.c b/src/frontend/com_ghelp.c new file mode 100644 index 000000000..7ce58c041 --- /dev/null +++ b/src/frontend/com_ghelp.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include + +#include "com_ghelp.h" +#include "com_help.h" +#include "variable.h" +#include "streams.h" +#include "cpextern.h" + +void +com_ghelp(wordlist *wl) +{ + char *npath; + char *path = Help_Path; + char 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; +} diff --git a/src/frontend/com_ghelp.h b/src/frontend/com_ghelp.h new file mode 100644 index 000000000..8fb3667f5 --- /dev/null +++ b/src/frontend/com_ghelp.h @@ -0,0 +1,8 @@ +#ifndef _COM_GHELP_H +#define _COM_GHELP_H + + +void com_ghelp(wordlist *wl); + +#endif + diff --git a/src/frontend/com_hardcopy.c b/src/frontend/com_hardcopy.c new file mode 100644 index 000000000..71a2649c2 --- /dev/null +++ b/src/frontend/com_hardcopy.c @@ -0,0 +1,168 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "plotting/plotit.h" +#include "plotting/graphdb.h" +#include "plotting/graf.h" + +#include "arg.h" +#include "display.h" +#include "com_hardcopy.h" +#include "variable.h" + + +/* hardcopy file plotargs, or 'hardcopy file' -- with no other args + * this prompts the user for a window to dump to a plot file. XXX no + * it doesn't. */ +void +com_hardcopy(wordlist *wl) +{ + char *buf2; + wordlist *process(wordlist *wlist); + char *fname; + char buf[BSIZE_SP], device[BSIZE_SP]; + bool tempf = FALSE; + char *devtype; + char format[513]; + int printed; + int hc_button; + int foundit; + + if (!cp_getvar("hcopydev", VT_STRING, device)) + *device = '\0'; + + if (wl) { + hc_button = 0; + fname = wl->wl_word; + wl = wl->wl_next; + } else { + hc_button = 1; + fname = smktemp("hc"); + tempf = TRUE; + } + + if (!cp_getvar("hcopydevtype", VT_STRING, buf)) { + devtype = "plot5"; + } else { + devtype = buf; + } + + /* enable screen plot selection for these display types */ + foundit = 0; + +#ifndef X_DISPLAY_MISSING + if (!wl && hc_button) { + + REQUEST request; + RESPONSE response; + GRAPH *tempgraph; + + request.option = click_option; + Input(&request, &response); + + if (response.option == error_option) return; + + if (response.reply.graph) { + + if (DevSwitch(devtype)) return; + tempgraph = CopyGraph(response.reply.graph); + tempgraph->devdep = fname; + if (NewViewport(tempgraph)) { + DevSwitch(NULL); + return; + } + gr_resize(tempgraph); + gr_redraw(tempgraph); + DestroyGraph(tempgraph->graphid); + DevSwitch(NULL); + foundit = 1; + } + } + +#endif + + + if (!foundit) { + + if (!wl) { + outmenuprompt("which variable ? "); + if ((buf2 = prompt(cp_in)) == (char *) -1) /* XXXX Sick */ + return; + wl = (struct wordlist *) tmalloc(sizeof(struct wordlist)); + wl->wl_word = buf2; + wl->wl_next = NULL; + wl = process(wl); + } + + + + if (DevSwitch(devtype)) return; + + if (!wl || !plotit(wl, fname, (char *) NULL)) { + printf("com_hardcopy: graph not defined\n"); + DevSwitch(NULL); /* remember to switch back */ + return; + } + + DevSwitch(NULL); + + } + + printed = 0; + + + if (*device) { +#ifdef SYSTEM_PLOT5LPR + if (!strcmp(devtype, "plot5") || !strcmp(devtype, "MFB")) { + if (!cp_getvar("lprplot5", VT_STRING, format)) + strcpy(format, SYSTEM_PLOT5LPR); + (void) sprintf(buf, format, device, fname); + fprintf(cp_out, "Printing %s on the %s printer.\n", fname, device); + (void) system(buf); + printed = 1; + } +#endif +#ifdef SYSTEM_PSLPR + if (!printed && !strcmp(devtype, "postscript")) { + /* note: check if that was a postscript printer XXX */ + if (!cp_getvar("lprps", VT_STRING, format)) + strcpy(format, SYSTEM_PSLPR); + (void) sprintf(buf, format, device, fname); + fprintf(cp_out, "Printing %s on the %s printer.\n", fname, device); + (void) system(buf); + printed = 1; + } +#endif + } + + if (!printed) { + if (!strcmp(devtype, "plot5")) { + fprintf(cp_out, + "The file \"%s\" may be printed with the Unix \"plot\" command,\n", + fname); + fprintf(cp_out, + "\tor by using the '-g' flag to the Unix lpr command.\n"); + } else if (!strcmp(devtype, "postscript")) { + fprintf(cp_out, + "The file \"%s\" may be printed on a postscript printer.\n", + fname); + } else if (!strcmp(devtype, "MFB")) { + fprintf(cp_out, + "The file \"%s\" may be printed on a MFB device.\n", + fname); + } + } + + if (tempf && *device) + (void) unlink(fname); + + return; +} diff --git a/src/frontend/com_hardcopy.h b/src/frontend/com_hardcopy.h new file mode 100644 index 000000000..67aa5d129 --- /dev/null +++ b/src/frontend/com_hardcopy.h @@ -0,0 +1,7 @@ +#ifndef _COM_HARDCOPY_H +#define _COM_HARDCOPY_H + + +void com_hardcopy(wordlist *wl); + +#endif diff --git a/src/frontend/com_help.c b/src/frontend/com_help.c new file mode 100644 index 000000000..f341afd03 --- /dev/null +++ b/src/frontend/com_help.c @@ -0,0 +1,87 @@ +#include +#include + +#include +#include +#include +#include + +#include "hcomp.h" + + +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.\n"); + + if (!allflag) { + out_printf("For a list of all commands " + "type \"help all\", for a short\n" + "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; +} diff --git a/src/frontend/com_help.h b/src/frontend/com_help.h new file mode 100644 index 000000000..d0ab82428 --- /dev/null +++ b/src/frontend/com_help.h @@ -0,0 +1,8 @@ +#ifndef _COM_HELP_H +#define _COM_HELP_H + + +void com_help(wordlist *wl); + +#endif + diff --git a/src/frontend/com_history.c b/src/frontend/com_history.c new file mode 100644 index 000000000..f6b03a77b --- /dev/null +++ b/src/frontend/com_history.c @@ -0,0 +1,493 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* Do history substitutions. */ + +#include +#include + +#include "com_history.h" + + +/* static declarations */ +static wordlist * dohsubst(char *string); +static wordlist * dohmod(char **string, wordlist *wl); +static wordlist * hpattern(char *buf); +static wordlist * hprefix(char *buf); +static wordlist * getevent(int num); +static void freehist(int num); +static char * dohs(char *pat, char *str); + + +struct histent *cp_lastone = NULL; +int cp_maxhistlength = 10000; /* Chris Inbody */ +char cp_hat = '^'; +char cp_bang = '!'; +bool cp_didhsubst; + +static struct histent *histlist = NULL; +static int histlength = 0; + +/* First check for a ^ at the beginning of the line, and then search + * each word for !. Following this can be any of string, number, + * ?string, -number ; then there may be a word specifier, the same as + * csh, and then the : modifiers. For the :s modifier, the syntax is + * :sXoooXnnnX, where X is any character, and ooo and nnn are strings + * not containing X. + */ + +wordlist * +cp_histsubst(wordlist *wlist) +{ + wordlist *nwl, *w, *n; + char buf[BSIZE_SP], *s, *b; + + /* Replace ^old^new with !:s^old^new. */ + + cp_didhsubst = FALSE; + if (*wlist->wl_word == cp_hat) { + (void) sprintf(buf, "%c%c:s%s", cp_bang, cp_bang, + wlist->wl_word); + tfree(wlist->wl_word); + wlist->wl_word = copy(buf); + } + for (w = wlist; w; w = w->wl_next) { + b = w->wl_word; + for (s = b; *s; s++) + if (*s == cp_bang) { + cp_didhsubst = TRUE; + n = dohsubst(s + 1); + if (!n) { + wlist->wl_word = NULL; + return (wlist); + } + if (b < s) { + (void) sprintf(buf, "%.*s%s", s - b, b, + n->wl_word); + tfree(n->wl_word); + n->wl_word = copy(buf); + } + nwl = wl_splice(w, n); + if (wlist == w) + wlist = n; + w = nwl; + break; + } + } + return (wlist); +} + +/* Do a history substitution on one word. Figure out which event is + * being referenced, then do word selections and modifications, and + * then stick anything left over on the end of the last word. + */ + +static wordlist * +dohsubst(char *string) +{ + wordlist *wl, *nwl; + char buf[BSIZE_SP], *s, *r = NULL, *t; + + if (*string == cp_bang) { + if (cp_lastone) { + wl = cp_lastone->hi_wlist; + string++; + } else { + fprintf(cp_err, "0: event not found.\n"); + return (NULL); + } + } else { + switch(*string) { + + case '-': + wl = getevent(cp_event - scannum(++string)); + if (!wl) + return (NULL); + while (isdigit(*string)) + string++; + break; + + case '?': + (void) strcpy(buf, string + 1); + if ((s =strchr(buf, '?'))) + *s = '\0'; + wl = hpattern(buf); + if (!wl) + return (NULL); + if (s == NULL) /* No modifiers on this one. */ + return (wl_copy(wl)); + break; + + case '\0': /* Maybe this should be cp_event. */ + wl = alloc(struct wordlist); + wl->wl_word = copy("!"); + wl->wl_next = NULL; + wl->wl_prev = NULL; + cp_didhsubst = FALSE; + return (wl); + + default: + if (isdigit(*string)) { + wl = getevent(scannum(string)); + if (!wl) + return (NULL); + while (isdigit(*string)) + string++; + } else { + (void) strcpy(buf, string); + for (s = ":^$*-%"; *s; s++) { + t =strchr(buf, *s); + if (t && ((t < r) || !r)) { + r = t; + string += r - buf; + } + } + if (r) + *r = '\0'; + else + while (*string) + string++; + if ((buf[0] == '\0') && cp_lastone) + wl = cp_lastone->hi_wlist; + else + wl = hprefix(buf); + if (!wl) + return (NULL); + } + } + } + if (wl == NULL) { /* Shouldn't happen. */ + fprintf(cp_err, "Event not found.\n"); + return (NULL); + } + nwl = dohmod(&string, wl_copy(wl)); + if (!nwl) + return (NULL); + if (*string) { + for (wl = nwl; wl->wl_next; wl = wl->wl_next) + ; + (void) sprintf(buf, "%s%s", wl->wl_word, string); + tfree(wl->wl_word); + wl->wl_word = copy(buf); + } + return (nwl); +} + +static wordlist * +dohmod(char **string, wordlist *wl) +{ + wordlist *w; + char *s; + char *r = NULL, *t; + int numwords, eventlo, eventhi, i; + bool globalsubst; + +anothermod: + numwords = wl_length(wl); + globalsubst = FALSE; + eventlo = 0; + eventhi = numwords - 1; + + /* Now we know what wordlist we want. Take care of modifiers now. */ + r = NULL; + for (s = ":^$*-%"; *s; s++) { + t =strchr(*string, *s); + if (t && ((t < r) || (r == NULL))) + r = t; + } + if (!r) /* No more modifiers. */ + return (wl); + + *string = r; + if (**string == ':') + (*string)++; + + switch(**string) { + case '$': /* Last word. */ + eventhi = eventlo = numwords - 1; + break; + case '*': /* Words 1 through $ */ + if (numwords == 1) + return (NULL); + eventlo = 1; + eventhi = numwords - 1; + break; + case '-': /* Words 0 through ... */ + eventlo = 0; + if (*(*string + 1)) + eventhi = scannum(*string + 1); + else + eventhi = numwords - 1; + if (eventhi > numwords - 1) + eventhi = numwords - 1; + break; + case 'p': /* Print the command and don't execute it. + * This doesn't work quite like csh. + */ + wl_print(wl, cp_out); + (void) putc('\n', cp_out); + return (NULL); + case 's': /* Do a substitution. */ + for (w = wl; w; w = w->wl_next) { + s = dohs(*string + 1, w->wl_word); + if (s) { + tfree(w->wl_word); + w->wl_word = s; + if (globalsubst == FALSE) { + while (**string) + (*string)++; + break; + } + } + } + /* In case globalsubst is TRUE... */ + while (**string) + (*string)++; + break; + default: + if (!isdigit(**string)) { + fprintf(cp_err, "Error: %s: bad modifier.\n", + *string); + return (NULL); + } + i = scannum(*string); + if (i > eventhi) { + fprintf(cp_err, "Error: bad event number %d\n", + i); + return (NULL); + } + eventhi = eventlo = i; + while (isdigit(**string)) + (*string)++; + if (**string == '*') + eventhi = numwords - 1; + if (**string == '-') { + if (!isdigit(*(*string + 1))) + eventhi = numwords - 1; + else { + eventhi = scannum(++*string); + while (isdigit(**string)) + (*string)++; + } + } + } + /* Now change the word list accordingly and make another pass + * if there is more of the substitute left. + */ + + wl = wl_range(wl, eventlo, eventhi); + numwords = wl_length(wl); + if (**string && *++*string) + goto anothermod; + return (wl); +} + +/* Look for an event with a pattern in it... */ + +static wordlist * +hpattern(char *buf) +{ + struct histent *hi; + wordlist *wl; + + if (*buf == '\0') { + fprintf(cp_err, "Bad pattern specification.\n"); + return (NULL); + } + for (hi = cp_lastone; hi; hi = hi->hi_prev) + for (wl = hi->hi_wlist; wl; wl = wl->wl_next) + if (substring(buf, wl->wl_word)) + return (hi->hi_wlist); + fprintf(cp_err, "%s: event not found.\n", buf); + return (NULL); +} + +static wordlist * +hprefix(char *buf) +{ + struct histent *hi; + + if (*buf == '\0') { + fprintf(cp_err, "Bad pattern specification.\n"); + return (NULL); + } + for (hi = cp_lastone; hi; hi = hi->hi_prev) + if (hi->hi_wlist && prefix(buf, hi->hi_wlist->wl_word)) + return (hi->hi_wlist); + fprintf(cp_err, "%s: event not found.\n", buf); + return (NULL); +} + +/* Add a wordlist to the history list. (Done after the first parse.) Note + * that if event numbers are given in a random order that's how they'll + * show up in the history list. + */ + +void +cp_addhistent(int event, wordlist *wlist) +{ + /* MW. This test is not needed if everything works right + if (cp_lastone && !cp_lastone->hi_wlist) + fprintf(cp_err, "Internal error: bad history list\n"); */ + + if (cp_lastone == NULL) { +/* MW. the begging - initialize histlength*/ + histlength = 1; + + cp_lastone = histlist = alloc(struct histent); + cp_lastone->hi_prev = NULL; + } else { + cp_lastone->hi_next = alloc(struct histent); + cp_lastone->hi_next->hi_prev = cp_lastone; + cp_lastone = cp_lastone->hi_next; + } + cp_lastone->hi_next = NULL; + cp_lastone->hi_event = event; + cp_lastone->hi_wlist = wl_copy(wlist); + freehist(histlength - cp_maxhistlength); + histlength++; + return; +} + +/* Get a copy of the wordlist associated with an event. Error if out + * of range. + */ + +static wordlist * +getevent(int num) +{ + struct histent *hi; + + for (hi = histlist; hi; hi = hi->hi_next) + if (hi->hi_event == num) + break; + if (hi == NULL) { + fprintf(cp_err, "%d: event not found.\n", num); + return (NULL); + } + return (wl_copy(hi->hi_wlist)); +} + +/* Print out history between eventhi and eventlo. + * This doesn't remember quoting, so 'hodedo' prints as hodedo. + */ + +void +cp_hprint(int eventhi, int eventlo, bool rev) +{ + struct histent *hi; + + if (rev) { + for (hi = histlist; hi->hi_next; hi = hi->hi_next) + ; + for (; hi; hi = hi->hi_prev) + if ((hi->hi_event <= eventhi) && + (hi->hi_event >= eventlo) && + hi->hi_wlist) { + fprintf(cp_out, "%d\t", hi->hi_event); + wl_print(hi->hi_wlist, cp_out); + (void) putc('\n', cp_out); + } + } else { + for (hi = histlist; hi; hi = hi->hi_next) + if ((hi->hi_event <= eventhi) && + (hi->hi_event >= eventlo) && + hi->hi_wlist) { + fprintf(cp_out, "%d\t", hi->hi_event); + wl_print(hi->hi_wlist, cp_out); + (void) putc('\n', cp_out); + } + } + return; +} + +/* This just gets rid of the first num entries on the history list, and + * decrements histlength. + */ + +static void +freehist(int num) +{ + struct histent *hi; + + if (num < 1) + return; + histlength -= num; + hi = histlist; + while (num-- && histlist->hi_next) + histlist = histlist->hi_next; + if (histlist->hi_prev) { + histlist->hi_prev->hi_next = NULL; + histlist->hi_prev = NULL; + } else + { + fprintf(cp_err, "Internal error: history list mangled\n"); + exit(0); /* Chris Inbody */ + } + while (hi->hi_next) { + wl_free(hi->hi_wlist); + hi = hi->hi_next; + tfree(hi->hi_prev); + } + wl_free(hi->hi_wlist); + tfree(hi); + return; +} + +/* Do a :s substitution. */ + +static char * +dohs(char *pat, char *str) +{ + char schar, *s, *p, buf[BSIZE_SP]; + int i = 0, plen; + bool ok = FALSE; + + pat = copy(pat); /* Don't want to mangle anything. */ + schar = *pat++; + s =strchr(pat, schar); + if (s == NULL) { + fprintf(cp_err, "Bad substitute.\n"); + return (NULL); + } + *s++ = '\0'; + p =strchr(s, schar); + if (p) + *p = '\0'; + plen = strlen(pat) - 1; + for (i = 0; *str; str++) { + if ((*str == *pat) && prefix(pat, str) && (ok == FALSE)) { + for (p = s; *p; p++) + buf[i++] = *p; + str += plen; + ok = TRUE; + } else + buf[i++] = *str; + } + buf[i] = '\0'; + if (ok) + return (copy(buf)); + else + return (NULL); +} + +/* The "history" command. history [-r] [number] */ + +void +com_history(wordlist *wl) +{ + bool rev = FALSE; + + if (wl && eq(wl->wl_word, "-r")) { + wl = wl->wl_next; + rev = TRUE; + } + if (wl == NULL) + cp_hprint(cp_event - 1, cp_event - histlength, rev); + else + cp_hprint(cp_event - 1, cp_event - 1 - atoi(wl->wl_word), rev); + return; +} + diff --git a/src/frontend/com_history.h b/src/frontend/com_history.h new file mode 100644 index 000000000..7b83b1272 --- /dev/null +++ b/src/frontend/com_history.h @@ -0,0 +1,16 @@ +/************* + * Header file for history.c + * 1999 E. Rouat + ************/ + +#ifndef _COM_HISTORY_H +#define _COM_HISTORY_H + +wordlist * cp_histsubst(wordlist *wlist); +void cp_addhistent(int event, wordlist *wlist); +void cp_hprint(int eventhi, int eventlo, bool rev); +void com_history(wordlist *wl); + + + +#endif diff --git a/src/frontend/com_let.c b/src/frontend/com_let.c new file mode 100644 index 000000000..e27ef0901 --- /dev/null +++ b/src/frontend/com_let.c @@ -0,0 +1,207 @@ +#include + +#include +#include +#include +#include + +#include "com_let.h" +#include "com_display.h" +#include "completion.h" + + +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; + 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; +} diff --git a/src/frontend/com_let.h b/src/frontend/com_let.h new file mode 100644 index 000000000..ccce6771f --- /dev/null +++ b/src/frontend/com_let.h @@ -0,0 +1,8 @@ +#ifndef _COM_LET_H +#define _COM_LET_H + +#include + +void com_let(wordlist *wl); + +#endif diff --git a/src/frontend/com_option.c b/src/frontend/com_option.c new file mode 100644 index 000000000..2ece53aa5 --- /dev/null +++ b/src/frontend/com_option.c @@ -0,0 +1,117 @@ +#include +#include "ngspice.h" +#include "cktdefs.h" +#include "ftedefs.h" +#include +#include "circuits.h" +#include +#include "variable.h" + + +/* The option command. Syntax is option [opt ...] [opt = val ...]. + * Val may be a string, an int, a float, or a list of the + * form (elt1 elt2 ...). */ +void +com_option(wordlist *wl) +{ + +struct variable *vars; + char *s; + + CKTcircuit *circuit = NULL; + + if (!ft_curckt) { + fprintf(cp_err, "Error: no circuit loaded\n"); + return; + } + + circuit = (CKTcircuit *)(ft_curckt->ci_ckt); + + + if (wl == NULL) { + printf("******************************\n"); + printf("* Current simulation options *\n"); + printf("******************************\n\n"); + printf("Temperatures:\n"); + printf("temp = %f\n",circuit->CKTtemp); + printf("tnom = %f\n",circuit->CKTnomTemp); + + printf("\nIntegration method summary:\n"); + switch (circuit->CKTintegrateMethod) + { + case TRAPEZOIDAL: + printf("Integration Method = TRAPEZOIDAL\n"); + break; + case GEAR: + printf("Integration Method = GEAR\n"); + break; + default: + printf("Unknown integration method\n"); + } + printf("MaxOrder = %d\n", circuit->CKTmaxOrder); + + printf("\nTolerances (absolute):\n"); + printf("abstol (current) = %f\n", circuit->CKTabstol); + printf("chgtol (charge) = %f\n", circuit->CKTchgtol); + printf("volttol (voltage) = %f\n", circuit->CKTvoltTol); + printf("pivotabstol (pivot) = %f\n", circuit->CKTpivotAbsTol); + + printf("\nTolerances (relative):\n"); + printf("reltol (current) = %f\n", circuit->CKTreltol); + printf("pivotreltol (pivot) = %f\n", circuit->CKTpivotRelTol); + + printf("\nTruncation error:\n"); + printf("trtol = %f\n", circuit->CKTtrtol); +#ifdef NEWTRUNC + printf("ltereltol = %f\n", circuit->CKTlteReltol); + printf("lteabstol = %f\n", circuit->CKTlteAbstol); +#endif /* NEWTRUNC */ + + printf("\nConductances:\n"); + printf("gmin (devices) = %f\n", circuit->CKTgmin); + printf("diaggmin (stepping) = %f\n", circuit->CKTdiagGmin); + printf("gshunt = %f\n", circuit->CKTgshunt); + + + printf("delmin = %f\n", circuit->CKTdelmin); + + printf("\nDefault parameters for MOS devices\n"); + printf("Default M: %f\n", circuit->CKTdefaultMosM); + printf("Default L: %f\n", circuit->CKTdefaultMosL); + printf("Default W: %f\n", circuit->CKTdefaultMosW); + printf("Default AD: %f\n", circuit->CKTdefaultMosAD); + printf("Default AS: %f\n", circuit->CKTdefaultMosAS); + + return; + } + vars = cp_setparse(wl); + + /* This is sort of a hassle... */ + while (vars) { + switch (vars->va_type) { + case VT_BOOL: + s = (char *) &vars->va_bool; + break; + case VT_NUM: + s = (char *) &vars->va_num; + break; + case VT_REAL: + s = (char *) &vars->va_real; + break; + case VT_STRING: + s = vars->va_string; + break; + case VT_LIST: + s = (char *) vars->va_vlist; + break; + default: + s = (char *) NULL; + } + + /* qui deve settare le opzioni di simulazione */ + cp_vset(vars->va_name, vars->va_type, s); + vars = vars->va_next; + } + return; +} + diff --git a/src/frontend/com_option.h b/src/frontend/com_option.h new file mode 100644 index 000000000..ef3163db0 --- /dev/null +++ b/src/frontend/com_option.h @@ -0,0 +1,6 @@ +#ifndef _COM_OPTION_H +#define _COM_OPTION_H + +void com_option(wordlist *wl); + +#endif diff --git a/src/frontend/com_plot.c b/src/frontend/com_plot.c new file mode 100644 index 000000000..526597239 --- /dev/null +++ b/src/frontend/com_plot.c @@ -0,0 +1,28 @@ +#include +#include + +#include +#include + +#include "plotting/plotit.h" + +#include "com_plot.h" + + +/* plot name ... [xl[imit]] xlo xhi] [yl[imit ylo yhi] [vs xname] */ +void +com_plot(wordlist *wl) +{ + plotit(wl, (char *) NULL, (char *) NULL); + return; +} + +#ifdef TCL_MODULE +void +com_bltplot(wordlist *wl) +{ + plotit(wl, (char *) NULL, "blt"); + return; +} + +#endif diff --git a/src/frontend/com_plot.h b/src/frontend/com_plot.h new file mode 100644 index 000000000..7e816b448 --- /dev/null +++ b/src/frontend/com_plot.h @@ -0,0 +1,10 @@ +#ifndef _COM_PLOT_H +#define _COM_PLOT_H + +void com_plot(wordlist *wl); + +#include +#ifdef TCL_MODULE +void com_bltplot(wordlist *wl); +#endif +#endif diff --git a/src/frontend/com_rehash.c b/src/frontend/com_rehash.c new file mode 100644 index 000000000..589372b04 --- /dev/null +++ b/src/frontend/com_rehash.c @@ -0,0 +1,24 @@ +#include +#include + +#include +#include + + +void +com_rehash(wordlist *wl) +{ + char *s; + + if (!cp_dounixcom) { + fprintf(cp_err, "Error: unixcom not set.\n"); + return; + } + s = getenv("PATH"); + if (s) + cp_rehash(s, TRUE); + else + fprintf(cp_err, "Error: no PATH in environment.\n"); + return; +} + diff --git a/src/frontend/com_set.c b/src/frontend/com_set.c new file mode 100644 index 000000000..9cc683d02 --- /dev/null +++ b/src/frontend/com_set.c @@ -0,0 +1,51 @@ +#include +#include + +#include +#include + +#include "variable.h" + + +/* The set command. Syntax is set [opt ...] [opt = val ...]. Val may + * be a string, an int, a float, or a list of the form (elt1 elt2 + * ...). */ +void +com_set(wordlist *wl) +{ + struct variable *vars; + char *s; + + if (wl == NULL) { + cp_vprint(); + return; + } + vars = cp_setparse(wl); + + /* This is sort of a hassle... */ + while (vars) { + switch (vars->va_type) { + case VT_BOOL: + s = (char *) &vars->va_bool; + break; + case VT_NUM: + s = (char *) &vars->va_num; + break; + case VT_REAL: + s = (char *) &vars->va_real; + break; + case VT_STRING: + s = vars->va_string; + break; + case VT_LIST: + s = (char *) vars->va_vlist; + break; + default: + s = (char *) NULL; + } + cp_vset(vars->va_name, vars->va_type, s); + vars = vars->va_next; + } + return; +} + diff --git a/src/frontend/com_set.h b/src/frontend/com_set.h new file mode 100644 index 000000000..00b929447 --- /dev/null +++ b/src/frontend/com_set.h @@ -0,0 +1,6 @@ +#ifndef _COM_SET_H +#define _COM_SET_H + +void com_set(wordlist *wl); + +#endif diff --git a/src/frontend/com_setscale.c b/src/frontend/com_setscale.c new file mode 100644 index 000000000..7418f30c1 --- /dev/null +++ b/src/frontend/com_setscale.c @@ -0,0 +1,37 @@ +#include +#include +#include + +#include "com_setscale.h" +#include "quote.h" +#include "streams.h" +#include "vectors.h" +#include "plotting/plotting.h" +#include "plotting/pvec.h" + + +/* 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(s) tfree(s);/*DG to avoid the cp_unquote memory leak */ + 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"); + } +} diff --git a/src/frontend/com_setscale.h b/src/frontend/com_setscale.h new file mode 100644 index 000000000..6ced5482b --- /dev/null +++ b/src/frontend/com_setscale.h @@ -0,0 +1,9 @@ +#ifndef _COM_SETSCALE_H +#define _COM_SETSCALE_H + +#include + + +void com_setscale(wordlist *wl); + +#endif diff --git a/src/frontend/com_shell.c b/src/frontend/com_shell.c new file mode 100644 index 000000000..145e6c6e5 --- /dev/null +++ b/src/frontend/com_shell.c @@ -0,0 +1,58 @@ +#include +#include +#include + +#include + + +/* Fork a shell. */ + +void +com_shell(wordlist *wl) +{ + char *com, *shell = NULL; + + shell = getenv("SHELL"); + if (shell == NULL) + shell = "/bin/csh"; + + cp_ccon(FALSE); + +#ifdef HAVE_VFORK_H + /* XXX Needs to switch process groups. Also, worry about suspend */ + /* Only bother for efficiency */ + pid = vfork(); + if (pid == 0) { + fixdescriptors(); + if (wl == NULL) { + execl(shell, shell, 0); + _exit(99); + } else { + com = wl_flatten(wl); + execl("/bin/sh", "sh", "-c", com, 0); + } + } else { + /* XXX Better have all these signals */ + svint = signal(SIGINT, SIG_DFL); + svquit = signal(SIGQUIT, SIG_DFL); + svtstp = signal(SIGTSTP, SIG_DFL); + /* XXX Sig on proc group */ + do { + r = wait((union wait *) NULL); + } while ((r != pid) && pid != -1); + signal(SIGINT, (SIGNAL_FUNCTION) svint); + signal(SIGQUIT, (SIGNAL_FUNCTION) svquit); + signal(SIGTSTP, (SIGNAL_FUNCTION) svtstp); + } +#else + /* Easier to forget about changing the io descriptors. */ + if (wl) { + com = wl_flatten(wl); + system(com); + } else + system(shell); +#endif + + return; +} + diff --git a/src/frontend/com_shift.c b/src/frontend/com_shift.c new file mode 100644 index 000000000..a53a816e1 --- /dev/null +++ b/src/frontend/com_shift.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include + +#include "variable.h" +#include "streams.h" + + +/* Shift a list variable, by default argv, one to the left (or more if + * a second argument is given. */ +void +com_shift(wordlist *wl) +{ + struct variable *v, *vv; + char *n = "argv"; + int num = 1; + + if (wl) { + n = wl->wl_word; + wl = wl->wl_next; + } + if (wl) + num = scannum(wl->wl_word); + + for (v = variables; v; v = v->va_next) + if (eq(v->va_name, n)) + break; + if (!v) { + fprintf(cp_err, "Error: %s: no such variable\n", n); + return; + } + if (v->va_type != VT_LIST) { + fprintf(cp_err, "Error: %s not of type list\n", n); + return; + } + for (vv = v->va_vlist; vv && (num > 0); num--) + vv = vv->va_next; + if (num) { + fprintf(cp_err, "Error: variable %s not long enough\n", n); + return; + } + + v->va_vlist = vv; + return; +} diff --git a/src/frontend/com_state.c b/src/frontend/com_state.c new file mode 100644 index 000000000..cb8beb128 --- /dev/null +++ b/src/frontend/com_state.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include +#include + +#include "circuits.h" +#include "com_state.h" +#include "streams.h" +#include "plotting/plotting.h" + + +void +com_state(wordlist *wl) +{ + if (!ft_curckt) { + fprintf(cp_err, "Error: no circuit loaded.\n"); + return; + } + fprintf(cp_out, "Current circuit: %s\n", ft_curckt->ci_name); + if (!ft_curckt->ci_inprogress) { + fprintf(cp_out, "No run in progress.\n"); + return; + } + fprintf(cp_out, "Type of run: %s\n", plot_cur->pl_name); + fprintf(cp_out, "Number of points so far: %d\n", + plot_cur->pl_scale->v_length); + fprintf(cp_out, "(That's all this command does so far)\n"); + return; +} diff --git a/src/frontend/com_state.h b/src/frontend/com_state.h new file mode 100644 index 000000000..08955a500 --- /dev/null +++ b/src/frontend/com_state.h @@ -0,0 +1,7 @@ +#ifndef _COM_STATE_H +#define _COM_STATE_H + +void com_state(wordlist *wl); + +#endif + diff --git a/src/frontend/com_strcmp.c b/src/frontend/com_strcmp.c new file mode 100644 index 000000000..1a035397a --- /dev/null +++ b/src/frontend/com_strcmp.c @@ -0,0 +1,28 @@ +#include +#include + +#include +#include + +#include "com_strcmp.h" +#include "quote.h" +#include "variable.h" + + +/* This is a truly evil thing */ +void +com_strcmp(wordlist *wl) +{ + char *var, *s1, *s2; + int i; + + var = wl->wl_word; + s1 = cp_unquote(wl->wl_next->wl_word); + s2 = cp_unquote(wl->wl_next->wl_next->wl_word); + + i = strcmp(s1, s2); + tfree(s1);/*DG cp_unquote memory leak*/ + tfree(s2); + cp_vset(var, VT_NUM, (char *) &i); + return; +} diff --git a/src/frontend/com_strcmp.h b/src/frontend/com_strcmp.h new file mode 100644 index 000000000..e94bfbe16 --- /dev/null +++ b/src/frontend/com_strcmp.h @@ -0,0 +1,7 @@ +#ifndef _COM_STRCMP_H +#define _COM_STRCMP_H + + +void com_strcmp(wordlist *wl); + +#endif diff --git a/src/frontend/com_unset.c b/src/frontend/com_unset.c new file mode 100644 index 000000000..3f3d8d5a1 --- /dev/null +++ b/src/frontend/com_unset.c @@ -0,0 +1,30 @@ +#include +#include + +#include +#include +#include + +#include "variable.h" + + +void +com_unset(wordlist *wl) +{ + char *name; + struct variable *var, *nv; + + if (eq(wl->wl_word, "*")) { + for (var = variables; var; var = nv) { + nv = var->va_next; + cp_remvar(var->va_name); + } + wl = wl->wl_next; + } + while (wl != NULL) { + name = wl->wl_word; + cp_remvar(name); + wl = wl->wl_next; + } + return; +} diff --git a/src/frontend/com_xgraph.c b/src/frontend/com_xgraph.c new file mode 100644 index 000000000..72ae95da2 --- /dev/null +++ b/src/frontend/com_xgraph.c @@ -0,0 +1,41 @@ +#include + +#include +#include +#include + +#include "plotting/plotit.h" + +#include "com_xgraph.h" + + +/* xgraph file plotargs */ +void +com_xgraph(wordlist *wl) +{ + char *fname; + bool tempf = FALSE; + + if (wl) { + fname = wl->wl_word; + wl = wl->wl_next; + } + if (!wl) { + return; + } + if (cieq(fname, "temp") || cieq(fname, "tmp")) { + fname = smktemp("xg"); + tempf = TRUE; + } + + (void) plotit(wl, fname, "xgraph"); + +#if 0 + /* Leave temp file sitting around so xgraph can grab it from + background. */ + if (tempf) + (void) unlink(fname); +#endif + + return; +} diff --git a/src/frontend/com_xgraph.h b/src/frontend/com_xgraph.h new file mode 100644 index 000000000..ef0ac2116 --- /dev/null +++ b/src/frontend/com_xgraph.h @@ -0,0 +1,6 @@ +#ifndef _COM_XGRAPH_H +#define _COM_XGRAPH_H + +void com_xgraph(wordlist *wl); + +#endif diff --git a/src/frontend/commands.c b/src/frontend/commands.c new file mode 100644 index 000000000..1666ee85c --- /dev/null +++ b/src/frontend/commands.c @@ -0,0 +1,820 @@ +/* NG-SPICE -- An electrical circuit simulator + * + * Copyright (c) 1990 University of California + * Copyright (c) 2000 Arno W. Peters + * + * Permission to use, copy, modify, and distribute this software and + * its documentation without fee, and without a written agreement is + * hereby granted, provided that the above copyright notice, this + * paragraph and the following three paragraphs appear in all copies. + * + * This software program and documentation are copyrighted by their + * authors. The software program and documentation are supplied "as + * is", without any accompanying services from the authors. The + * authors do not warrant that the operation of the program will be + * uninterrupted or error-free. The end-user understands that the + * program was developed for research purposes and is advised not to + * rely exclusively on the program for any reason. + * + * IN NO EVENT SHALL THE AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, + * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING + * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS + * DOCUMENTATION, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. THE AUTHORS SPECIFICALLY DISCLAIMS ANY + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + * SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE AUTHORS + * HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, + * ENHANCEMENTS, OR MODIFICATIONS. */ + +/* Table of available commands. Note that they're sorted so that the + * commands that appear in the spiceinit file are at the top. */ + +#include +#include +#include + +#include "ftehelp.h" +#include "commands.h" + +#include "com_ahelp.h" +#include "com_asciiplot.h" +#include "com_compose.h" +#include "com_display.h" +#include "com_hardcopy.h" +#include "com_help.h" +#include "com_let.h" +#include "com_plot.h" +#include "com_setscale.h" +#include "com_xgraph.h" +#include "com_state.h" +#include "fourier.h" + +#ifdef EXPERIMENTAL_CODE +#include "com_option.h" +void com_loadsnap(wordlist *wl); +void com_savesnap(wordlist *wl); +#endif + +#include "com_dl.h" + +#ifdef XSPICE +/* gtri - begin - wbk - add include files */ +#include "evtproto.h" +/* gtri - end - wbk - add include files */ +#endif + +/* FIXME: Integrate spcp_coms and nutcp_coms into one variable. */ + + +/* Bool fields: stringargs, spiceonly, major */ + +struct comm spcp_coms[] = { + { "let", com_let, FALSE, FALSE, TRUE, + { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS, + arg_let, + "varname = expr : Assign vector variables." } , + { "reshape", com_reshape, FALSE, FALSE, TRUE, + { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, + arg_let, + "vector ... [ shape ] : change the dimensions of a vector." } , + { "define", com_define, FALSE, FALSE, TRUE, + { 010000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[[func (args)] stuff] : Define a user-definable function." } , + { "set", com_set, FALSE, FALSE, TRUE, + { 020000, 020000, 020000, 020000 }, E_DEFHMASK, 0, LOTS, + arg_set, + "[option] [option = value] ... : Set a variable." } , + +#ifdef EXPERIMENTAL_CODE +/* PN support for altering options in interactive mode */ + { "option", com_option, FALSE, TRUE, TRUE, + { 020000, 020000, 020000, 020000 }, E_DEFHMASK, 0, LOTS, + arg_set, + "[option] [option = value] ... : Set a simulator option." } , + { "savesnap", com_savesnap, FALSE, FALSE, TRUE, + { 1, 040000, 040000, 040000 }, E_DEFHMASK, 1, 1, + (void (*)()) NULL, + "file : Save a snapshot." } , + { "loadsnap", com_loadsnap, FALSE, FALSE, TRUE, + { 1, 040000, 040000, 040000 }, E_DEFHMASK, 2, 2, + (void (*)()) NULL, + "file : Load a snapshot." } , +#endif + + { "alias", com_alias, FALSE, FALSE, FALSE, + { 02, 04, 04, 04 }, E_ADVANCED, 0, LOTS, + (void (*)()) NULL, + "[[word] alias] : Define an alias." } , + { "deftype", com_dftype, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 3, LOTS, + (void (*)()) NULL, + "spec name pat ... : Redefine vector and plot types.\n" } , + { "plot", com_plot, FALSE, FALSE, TRUE, + { 041000, 041000, 041000, 041000 }, E_BEGINNING | E_HASPLOTS, 1, LOTS, + arg_plot, + "expr ... [vs expr] [xl xlo xhi] [yl ylo yhi] : Plot things." }, +#ifdef TCL_MODULE + { "bltplot", com_bltplot, FALSE, FALSE, TRUE, + { 041000, 041000, 041000, 041000 }, E_BEGINNING | E_HASPLOTS, 1, LOTS, + arg_plot, + "expr ... [vs expr] [xl xlo xhi] [yl ylo yhi] : Plot things." }, +#endif + { "display", com_display, FALSE, FALSE, TRUE, + { 040000, 040000, 040000, 040000 }, E_BEGINNING, 0, LOTS, + arg_display, + ": Display vector status." } , + { "destroy", com_destroy, FALSE, FALSE, FALSE, + { 0400, 0400, 0400, 0400 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[plotname] ... : Throw away all the data in the plot." } , + { "setplot", com_splot, FALSE, FALSE, TRUE, + { 0400, 0, 0, 0 }, E_DEFHMASK, 0, 1, + (void (*)()) NULL, + "[plotname] : Change the current working plot." } , + { "setcirc", com_scirc, FALSE, TRUE, FALSE, + { 04, 0, 0, 0 }, E_DEFHMASK, 0, 1, + (void (*)()) NULL, + "[circuit name] : Change the current circuit." } , + { "setscale", com_setscale, FALSE, FALSE, FALSE, + { 040000, 0, 0, 0 }, E_DEFHMASK, 0, 1, + (void (*)()) NULL, + "[vecname] : Change default scale of current working plot." } , + { "transpose", com_transpose, FALSE, FALSE, FALSE, + { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "varname ... : Perform matrix transposition on multi-D vectors." } , + { "xgraph", com_xgraph, FALSE, FALSE, TRUE, + { 1, 041000, 041000, 041000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "file plotargs : Send plot to Xgraph-11." } , + { "hardcopy", com_hardcopy, FALSE, FALSE, TRUE, + { 1, 041000, 041000, 041000 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "file plotargs : Produce hardcopy plots." } , + { "asciiplot", com_asciiplot, FALSE, FALSE, TRUE, + { 041000, 041000, 041000, 041000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "plotargs : Produce ascii plots." } , + { "write", com_write, FALSE, FALSE, TRUE, + { 1, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "file expr ... : Write data to a file." } , + { "compose", com_compose, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 2, LOTS, + (void (*)()) NULL, + "var parm=val ... : Compose a vector." } , + { "unlet", com_unlet, FALSE, FALSE, FALSE, + { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "varname ... : Undefine vectors." } , + { "print", com_print, FALSE, FALSE, TRUE, + { 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS, + arg_print, + "[col] expr ... : Print vector values." } , +#ifdef XSPICE +/* gtri - begin - wbk - add event print command */ + { "eprint", EVTprint, FALSE, FALSE, TRUE, + { 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS, + (void (*)()) NULL, + "node node ... : Print event values." } , +/* gtri - end - wbk - add event print command */ + { "codemodel", com_codemodel, FALSE, FALSE, TRUE, + { 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS, + (void (*)()) NULL, + "library library ... : Loads the opus librarys." } , +#endif +#ifdef DEVLIB + { "use", com_use, FALSE, FALSE, TRUE, + { 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS, + (void (*)()) NULL, + "library library ... : Loads the device librarys." } , +#endif + { "load", com_load, FALSE, FALSE, TRUE, + { 1, 1, 1, 1 }, E_BEGINNING | E_NOPLOTS, 1, LOTS, + arg_load, + "file ... : Load in data." } , + { "cross", com_cross, FALSE, FALSE, TRUE, + { 040000, 0, 040000, 040000 }, E_DEFHMASK, 2, LOTS, + (void (*)()) NULL, + "vecname number [ vector ... ] : Make a vector in a strange way." } , + { "undefine", com_undefine, FALSE, FALSE, FALSE, + { 010000, 010000, 010000, 010000 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[func ...] : Undefine a user-definable function." } , + { "op", com_op, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.op line args] : Determine the operating point of the circuit." } , + { "tf", com_tf, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.tran line args] : Do a transient analysis." } , + { "tran", com_tran, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.tran line args] : Do a transient analysis." } , + { "ac", com_ac, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.ac line args] : Do an ac analysis." } , + { "dc", com_dc, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.dc line args] : Do a dc analysis." } , + { "pz", com_pz, FALSE, TRUE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.pz line args] : Do a pole / zero analysis." } , + { "sens", com_sens, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.sens line args] : Do a sensitivity analysis." } , + { "disto", com_disto, FALSE, TRUE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.disto line args] : Do an distortion analysis." } , + { "noise", com_noise, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.noise line args] : Do a noise analysis." } , + { "listing", com_listing, FALSE, TRUE, TRUE, + { 0100, 0100, 0100, 0100 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[logical] [physical] [deck] : Print the current circuit." } , + { "edit", com_edit, FALSE, TRUE, TRUE, + { 1, 0, 0, 0 }, E_DEFHMASK, 0, 1, + (void (*)()) NULL, + "[filename] : Edit a spice deck and then load it in." } , + { "dump", com_dump, FALSE, TRUE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Print a dump of the current circuit." } , + { "fourier", com_fourier, FALSE, FALSE, TRUE, + { 0, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "fund_freq vector ... : Do a fourier analysis of some data." } , + { "spec", com_spec, FALSE, FALSE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 4, LOTS, + (void (*)()) NULL, + "start_freq stop_freq step_freq vector ... : Create a frequency domain plot." } , + { "show", com_show, FALSE, TRUE, FALSE, + { 040, 040, 040, 040 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "devices ... : parameters ... : Print out device summary." } , + { "showmod", com_showmod, FALSE, TRUE, FALSE, + { 040, 040, 040, 040 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "models ... : parameters ... : Print out model summary." } , + { "alter", com_alter, FALSE, TRUE, FALSE, + { 040, 040, 040, 040 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "devspecs : parmname value : Alter device parameters." } , + { "altermod", com_altermod, FALSE, TRUE, FALSE, + { 040, 040, 040, 040 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "devspecs : parmname value : Alter model parameters." } , + { "resume", com_resume, FALSE, TRUE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Continue after a stop." } , + { "state", com_state, FALSE, TRUE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "(unimplemented) : Print the state of the circuit." }, + { "stop", com_stop, FALSE, TRUE, FALSE, + { 04200, 04200, 04200, 04200 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[stop args] : Set a breakpoint." } , + { "trace", com_trce, FALSE, TRUE, FALSE, + { 0200, 0200, 0200, 0200 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[all] [node ...] : Trace a node." } , + { "save", com_save, FALSE, TRUE, FALSE, + { 0200, 0200, 0200, 0200 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[all] [node ...] : Save a spice output." } , + { "iplot", com_iplot, FALSE, TRUE, TRUE, + { 0200, 0200, 0200, 0200 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[all] [node ...] : Incrementally plot a node." } , + { "status", com_sttus, FALSE, TRUE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Print the current breakpoints and traces." } , + { "delete", com_delete, FALSE, TRUE, FALSE, + { 020, 020, 020, 020 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[all] [break number ...] : Delete breakpoints and traces." } , + { "step", com_step, FALSE, TRUE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 1, + (void (*)()) NULL, + "[number] : Iterate number times, or one." } , + { "reset", com_rset, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Terminate a simulation after a breakpoint (formerly 'end')." } , + { "run", com_run, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 1, + (void (*)()) NULL, + "[rawfile] : Run the simulation as specified in the input file." } , + { "aspice", com_aspice, FALSE, FALSE, FALSE, + { 1, 1, 1, 1 }, E_DEFHMASK, 1, 2, + (void (*)()) NULL, + "file [outfile] : Run a spice job asynchronously." } , + { "jobs", com_jobs, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Report on asynchronous spice jobs." } , + { "rspice", com_rspice, FALSE, FALSE, FALSE, + { 1, 1, 1, 1 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[input file] : Run a spice job remotely." } , + { "bug", com_bug, FALSE, FALSE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Report a %s bug." } , + { "where", com_where, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Print last non-converging node or device" } , + { "newhelp", com_ahelp, FALSE, FALSE, TRUE, + { 010, 010, 010, 010 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[command name] ... : help." }, + { "tutorial", com_ghelp, FALSE, FALSE, TRUE, + { 023010, 023010, 023010, 023010 }, E_BEGINNING, 0, LOTS, + (void (*)()) NULL, + "[subject] ... : Hierarchical documentation browser." } , + { "help", com_ghelp, FALSE, FALSE, TRUE, + { 023010, 023010, 023010, 023010 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[subject] ... : Hierarchical documentation browser." } , + { "oldhelp", com_help, FALSE, FALSE, TRUE, + { 010, 010, 010, 010 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[command name] ... : Print help." } , + { "quit", com_quit, FALSE, FALSE, TRUE, + { 0, 0, 0, 0 }, E_BEGINNING, 0, 0, + (void (*)()) NULL, + ": Quit %s." } , + { "source", com_source, FALSE, FALSE, TRUE, + { 1, 1, 1, 1 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "file : Source a %s file." } , + { "shift", com_shift, FALSE, FALSE, FALSE, + { 020000, 0, 0, 0 }, E_DEFHMASK, 0, 2, + (void (*)()) NULL, + "[var] [number] : Shift argv or the named list var to the left." } , + { "unset", com_unset, FALSE, FALSE, FALSE, + { 020000, 020000, 020000, 020000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "varname ... : Unset a variable." } , + { "unalias", com_unalias, FALSE, FALSE, FALSE, + { 02, 02, 02, 02 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "word ... : Undefine an alias." } , + { "history", com_history, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 2, + (void (*)()) NULL, + "[-r] [number] : Print command history." } , + { "echo", com_echo, FALSE, FALSE, FALSE, + { 1, 1, 1, 1 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[stuff ...] : Print stuff." } , + { "shell", com_shell, FALSE, FALSE, TRUE, + { 1, 1, 1, 1 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[args] : Fork a shell, or execute the command." } , + { "rusage", com_rusage, FALSE, FALSE, FALSE, + { 02000, 02000, 02000, 02000 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[resource ...] : Print current resource usage." } , + { "cd", com_chdir, FALSE, FALSE, FALSE, + { 1, 0, 0, 0 }, E_DEFHMASK, 0, 1, + (void (*)()) NULL, + "[directory] : Change working directory." } , + { "version", com_version, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[number] : Print the version number." } , + { "diff", com_diff, FALSE, FALSE, FALSE, + { 0400, 0400, 040000, 040000 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "plotname plotname [vec ...] : 'diff' two plots." } , + { "rehash", com_rehash, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Rebuild the unix command database." } , + { "while", NULL, FALSE, FALSE, FALSE, + { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "condition : Execute while the condition is TRUE." } , + { "repeat", NULL, FALSE, FALSE, FALSE, + { 0, 0, 0, 0}, E_DEFHMASK, 0, 1, + (void (*)()) NULL, + "[number] : Repeat number times, or forever." } , + { "dowhile", NULL, FALSE, FALSE, FALSE, + { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "condition : Execute while the condition is TRUE." } , + { "foreach", NULL, FALSE, FALSE, FALSE, + { 0, 040000, 040000, 040000 }, E_DEFHMASK, 2, LOTS, + (void (*)()) NULL, + "variable value ... : Do once for each value." } , + { "if", NULL, FALSE, FALSE, FALSE, + { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "condition : Execute if the condition is TRUE." } , + { "else", NULL, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Goes with if." } , + { "end", NULL, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": End a block." } , + { "break", NULL, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Break out of a block." } , + { "continue", NULL, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Continue a loop." } , + { "label", NULL, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 1, 1, + (void (*)()) NULL, + "word : Create someplace to go to." } , + { "goto", NULL, FALSE, FALSE, FALSE, + { 0100000, 0, 0, 0 }, E_DEFHMASK, 1, 1, + (void (*)()) NULL, + "word : Go to a label." } , + { "cdump", com_cdump, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Dump the current control structures." } , + { "settype", com_stype, FALSE, FALSE, FALSE, + { 0200000, 040000, 040000, 040000 }, E_DEFHMASK, 2, LOTS, + (void (*)()) NULL, + "type vec ... : Change the type of a vector." } , + { "strcmp", com_strcmp, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 3, 3, + (void (*)()) NULL, + "varname s1 s2 : Set $varname to strcmp(s1, s2)." } , + { "linearize", com_linearize, FALSE, TRUE, FALSE, + { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + " [ vec ... ] : Convert plot into one with linear scale." } , + { 0, NULL, FALSE, FALSE, FALSE, { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + NULL } +}; + + +/* Bool fields: stringargs, spiceonly, major */ +struct comm nutcp_coms[] = { + { "let", com_let, FALSE, FALSE, TRUE, + { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS, + arg_let, + "varname = expr : Assign vector variables." } , + { "reshape", com_reshape, FALSE, FALSE, TRUE, + { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, + arg_let, + "vector ... [ shape ] : change the dimensions of a vector." } , + { "define", com_define, FALSE, FALSE, TRUE, + { 010000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[[func (args)] stuff] : Define a user-definable function." } , + { "set", com_set, FALSE, FALSE, TRUE, + { 020000, 020000, 020000, 020000 }, E_DEFHMASK, 0, LOTS, + arg_set, + "[option] [option = value] ... : Set a variable." } , + +#ifdef EXPERIMENTAL_CODE +/* PN support for altering options in interactive mode */ + { "option", com_option, FALSE, TRUE, TRUE, + { 020000, 020000, 020000, 020000 }, E_DEFHMASK, 0, LOTS, + arg_set, + "[option] [option = value] ... : Set a simulator option." } , +#endif + + { "alias", com_alias, FALSE, FALSE, FALSE, + { 02, 04, 04, 04 }, E_ADVANCED, 0, LOTS, + (void (*)()) NULL, + "[[word] alias] : Define an alias." } , + { "deftype", com_dftype, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 3, LOTS, + (void (*)()) NULL, + "spec name pat ... : Redefine vector and plot types.\n" } , + { "plot", com_plot, FALSE, FALSE, TRUE, + { 041000, 041000, 041000, 041000 }, E_BEGINNING | E_HASPLOTS, 1, LOTS, + arg_plot, + "expr ... [vs expr] [xl xlo xhi] [yl ylo yhi] : Plot things." }, + { "display", com_display, FALSE, FALSE, TRUE, + { 040000, 040000, 040000, 040000 }, E_BEGINNING, 0, LOTS, + arg_display, + ": Display vector status." } , + { "destroy", com_destroy, FALSE, FALSE, FALSE, + { 0400, 0400, 0400, 0400 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[plotname] ... : Throw away all the data in the plot." } , + { "setplot", com_splot, FALSE, FALSE, TRUE, + { 0400, 0, 0, 0 }, E_DEFHMASK, 0, 1, + (void (*)()) NULL, + "[plotname] : Change the current working plot." } , + { "setcirc", NULL, FALSE, TRUE, FALSE, + { 04, 0, 0, 0 }, E_DEFHMASK, 0, 1, + (void (*)()) NULL, + "[circuit name] : Change the current circuit." } , + { "setscale", com_setscale, FALSE, FALSE, FALSE, + { 040000, 0, 0, 0 }, E_DEFHMASK, 0, 1, + (void (*)()) NULL, + "[vecname] : Change default scale of current working plot." } , + { "transpose", com_transpose, FALSE, FALSE, FALSE, + { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "varname ... : Perform matrix transposition on multi-D vectors." } , + { "xgraph", com_xgraph, FALSE, FALSE, TRUE, + { 1, 041000, 041000, 041000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "file plotargs : Send plot to Xgraph-11." } , + { "hardcopy", com_hardcopy, FALSE, FALSE, TRUE, + { 1, 041000, 041000, 041000 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "file plotargs : Produce hardcopy plots." } , + { "asciiplot", com_asciiplot, FALSE, FALSE, TRUE, + { 041000, 041000, 041000, 041000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "plotargs : Produce ascii plots." } , + { "write", com_write, FALSE, FALSE, TRUE, + { 1, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "file expr ... : Write data to a file." } , + { "compose", com_compose, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 2, LOTS, + (void (*)()) NULL, + "var parm=val ... : Compose a vector." } , + { "unlet", com_unlet, FALSE, FALSE, FALSE, + { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "varname ... : Undefine vectors." } , + { "print", com_print, FALSE, FALSE, TRUE, + { 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS, + arg_print, + "[col] expr ... : Print vector values." } , + { "load", com_load, FALSE, FALSE, TRUE, + { 1, 1, 1, 1 }, E_BEGINNING | E_NOPLOTS, 1, LOTS, + arg_load, + "file ... : Load in data." } , + { "cross", com_cross, FALSE, FALSE, TRUE, + { 040000, 0, 040000, 040000 }, E_DEFHMASK, 2, LOTS, + (void (*)()) NULL, + "vecname number [ vector ... ] : Make a vector in a strange way." } , + { "undefine", com_undefine, FALSE, FALSE, FALSE, + { 010000, 010000, 010000, 010000 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[func ...] : Undefine a user-definable function." } , + { "op", NULL, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.op line args] : Determine the operating point of the circuit." } , + { "tran", NULL, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.tran line args] : Do a transient analysis." } , + { "ac", NULL, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.ac line args] : Do an ac analysis." } , + { "dc", NULL, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.dc line args] : Do a dc analysis." } , + { "pz", NULL, FALSE, TRUE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.pz line args] : Do a pole / zero analysis." } , + { "sens", NULL, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.ac line args] : Do a sensitivity analysis." } , + { "disto", NULL, FALSE, TRUE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.disto line args] : Do an distortion analysis." } , + { "noise", NULL, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[.noise line args] : Do a noise analysis." } , + { "listing", NULL, FALSE, TRUE, TRUE, + { 0100, 0100, 0100, 0100 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[logical] [physical] [deck] : Print the current circuit." } , + { "edit", NULL, FALSE, TRUE, TRUE, + { 1, 0, 0, 0 }, E_DEFHMASK, 0, 1, + (void (*)()) NULL, + "[filename] : Edit a spice deck and then load it in." } , + { "dump", NULL, FALSE, TRUE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Print a dump of the current circuit." } , + { "fourier", com_fourier, FALSE, FALSE, TRUE, + { 0, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "fund_freq vector ... : Do a fourier analysis of some data." } , + { "show", NULL, FALSE, TRUE, FALSE, + { 040, 040, 040, 040 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "devspecs ... : parmspecs ... : Print out device parameters." } , + { "alter", NULL, FALSE, TRUE, FALSE, + { 040, 040, 040, 040 }, E_DEFHMASK, 3, LOTS, + (void (*)()) NULL, + "devspecs : parmname value : Alter device parameters." } , + { "altermod", NULL, FALSE, TRUE, FALSE, + { 040, 040, 040, 040 }, E_DEFHMASK, 3, LOTS, + (void (*)()) NULL, + "devspecs : parmname value : Alter model parameters." } , + { "resume", NULL, FALSE, TRUE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Continue after a stop." } , + { "state", NULL, FALSE, TRUE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "(unimplemented) : Print the state of the circuit." }, + { "stop", NULL, FALSE, TRUE, FALSE, + { 04200, 04200, 04200, 04200 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[stop args] : Set a breakpoint." } , + { "trace", NULL, FALSE, TRUE, FALSE, + { 0200, 0200, 0200, 0200 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[all] [node ...] : Trace a node." } , + { "save", NULL, FALSE, TRUE, FALSE, + { 0200, 0200, 0200, 0200 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[all] [node ...] : Save a spice output." } , + { "iplot", NULL, FALSE, TRUE, TRUE, + { 0200, 0200, 0200, 0200 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[all] [node ...] : Incrementally plot a node." } , + { "status", NULL, FALSE, TRUE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Print the current breakpoints and traces." } , + { "delete", NULL, FALSE, TRUE, FALSE, + { 020, 020, 020, 020 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[all] [break number ...] : Delete breakpoints and traces." } , + { "step", NULL, FALSE, TRUE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 1, + (void (*)()) NULL, + "[number] : Iterate number times, or one." } , + { "reset", NULL, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Terminate a simulation after a breakpoint (formerly 'end')." } , + { "run", NULL, FALSE, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 1, + (void (*)()) NULL, + "[rawfile] : Run the simulation as specified in the input file." } , + { "bug", com_bug, FALSE, FALSE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Report a %s bug." } , + { "newhelp", com_ahelp, FALSE, FALSE, TRUE, + { 010, 010, 010, 010 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[command name] ... : help." }, + { "tutorial", com_ghelp, FALSE, FALSE, TRUE, + { 023010, 023010, 023010, 023010 }, E_BEGINNING, 0, LOTS, + (void (*)()) NULL, + "[subject] ... : Hierarchical documentation browser." } , + { "help", com_ghelp, FALSE, FALSE, TRUE, + { 023010, 023010, 023010, 023010 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[subject] ... : Hierarchical documentation browser." } , + { "oldhelp", com_help, FALSE, FALSE, TRUE, + { 010, 010, 010, 010 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[command name] ... : Print help." } , + { "quit", com_quit, FALSE, FALSE, TRUE, + { 0, 0, 0, 0 }, E_BEGINNING, 0, 0, + (void (*)()) NULL, + ": Quit %s." } , + { "source", nutcom_source, FALSE, FALSE, TRUE, + { 1, 1, 1, 1 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "file : Source a %s file." } , + { "shift", com_shift, FALSE, FALSE, FALSE, + { 020000, 0, 0, 0 }, E_DEFHMASK, 0, 2, + (void (*)()) NULL, + "[var] [number] : Shift argv or the named list var to the left." } , + { "unset", com_unset, FALSE, FALSE, FALSE, + { 020000, 020000, 020000, 020000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "varname ... : Unset a variable." } , + { "unalias", com_unalias, FALSE, FALSE, FALSE, + { 02, 02, 02, 02 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "word ... : Undefine an alias." } , + { "history", com_history, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 2, + (void (*)()) NULL, + "[-r] [number] : Print command history." } , + { "echo", com_echo, FALSE, FALSE, FALSE, + { 1, 1, 1, 1 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[stuff ...] : Print stuff." } , + { "shell", com_shell, FALSE, FALSE, TRUE, + { 1, 1, 1, 1 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[args] : Fork a shell, or execute the command." } , + { "rusage", com_rusage, FALSE, FALSE, FALSE, + { 02000, 02000, 02000, 02000 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[resource ...] : Print current resource usage." } , + { "cd", com_chdir, FALSE, FALSE, FALSE, + { 1, 0, 0, 0 }, E_DEFHMASK, 0, 1, + (void (*)()) NULL, + "[directory] : Change working directory." } , + { "version", com_version, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "[number] : Print the version number." } , + { "diff", com_diff, FALSE, FALSE, FALSE, + { 0400, 0400, 040000, 040000 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + "plotname plotname [vec ...] : 'diff' two plots." } , + { "rehash", com_rehash, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Rebuild the unix command database." } , + { "while", NULL, FALSE, FALSE, FALSE, + { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "condition : Execute while the condition is TRUE." } , + { "repeat", NULL, FALSE, FALSE, FALSE, + { 0, 0, 0, 0}, E_DEFHMASK, 0, 1, + (void (*)()) NULL, + "[number] : Repeat number times, or forever." } , + { "dowhile", NULL, FALSE, FALSE, FALSE, + { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "condition : Execute while the condition is TRUE." } , + { "foreach", NULL, FALSE, FALSE, FALSE, + { 0, 040000, 040000, 040000 }, E_DEFHMASK, 2, LOTS, + (void (*)()) NULL, + "variable value ... : Do once for each value." } , + { "if", NULL, FALSE, FALSE, FALSE, + { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, + (void (*)()) NULL, + "condition : Execute if the condition is TRUE." } , + { "else", NULL, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Goes with if." } , + { "end", NULL, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": End a block." } , + { "break", NULL, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Break out of a block." } , + { "continue", NULL, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Continue a loop." } , + { "label", NULL, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 1, 1, + (void (*)()) NULL, + "word : Create someplace to go to." } , + { "goto", NULL, FALSE, FALSE, FALSE, + { 0100000, 0, 0, 0 }, E_DEFHMASK, 1, 1, + (void (*)()) NULL, + "word : Go to a label." } , + { "cdump", com_cdump, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, + (void (*)()) NULL, + ": Dump the current control structures." } , + { "settype", com_stype, FALSE, FALSE, FALSE, + { 0200000, 040000, 040000, 040000 }, E_DEFHMASK, 2, LOTS, + (void (*)()) NULL, + "type vec ... : Change the type of a vector." } , + { "strcmp", com_strcmp, FALSE, FALSE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 3, 3, + (void (*)()) NULL, + "varname s1 s2 : Set $varname to strcmp(s1, s2)." } , + { "linearize", NULL, FALSE, TRUE, FALSE, + { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + " [ vec ... ] : Convert plot into one with linear scale." } , + + { 0, NULL, FALSE, FALSE, FALSE, { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + (void (*)()) NULL, + NULL } + +} ; diff --git a/src/frontend/commands.h b/src/frontend/commands.h new file mode 100644 index 000000000..a26246336 --- /dev/null +++ b/src/frontend/commands.h @@ -0,0 +1,8 @@ +#ifndef _COMMANDS_H +#define _COMMANDS_H + + +extern struct comm spcp_coms[]; +extern struct comm nutcp_coms[]; + +#endif diff --git a/src/frontend/completion.h b/src/frontend/completion.h new file mode 100644 index 000000000..c02334ed7 --- /dev/null +++ b/src/frontend/completion.h @@ -0,0 +1,25 @@ +#ifndef _COMPLETION_H +#define _COMPLETION_H + +/* The types for command completion keywords. Note that these + * constants are built into cmdtab.c, so DON'T change them unless you + * want to change all of the bitmasks in cp_coms. Note that this is + * spice- and nutmeg- dependent. */ + +#define CT_FILENAME 0 +#define CT_CKTNAMES 2 +#define CT_COMMANDS 3 +#define CT_DBNUMS 4 +#define CT_DEVNAMES 5 +#define CT_LISTINGARGS 6 +#define CT_NODENAMES 7 +#define CT_PLOT 8 +#define CT_PLOTKEYWORDS 9 +#define CT_RUSEARGS 10 +#define CT_STOPARGS 11 +#define CT_UDFUNCS 12 +#define CT_VARIABLES 13 +#define CT_VECTOR 14 +#define CT_TYPENAMES 16 + +#endif diff --git a/src/frontend/control.c b/src/frontend/control.c new file mode 100644 index 000000000..7b1a3e403 --- /dev/null +++ b/src/frontend/control.c @@ -0,0 +1,801 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* The front-end command loop. */ + +#include +#include + +#include "control.h" +#include "com_cdump.h" +#include "variable.h" +#include "fteext.h" + + +/* Return values from doblock(). I am assuming that nobody will use + * these characters in a string. */ +#define NORMAL '\001' +#define BROKEN '\002' +#define CONTINUED '\003' +#define NORMAL_STR "\001" +#define BROKEN_STR "\002" +#define CONTINUED_STR "\003" + +/* Are we waiting for a command? This lets signal handling be + * more clever. */ + +bool cp_cwait = FALSE; +char *cp_csep = ";"; + +bool cp_dounixcom = FALSE; + +/* We have to keep the control structures in a stack, so that when we + * do a 'source', we can push a fresh set onto the top... Actually + * there have to be two stacks -- one for the pointer to the list of + * control structs, and one for the 'current command' pointer... */ +struct control *control[CONTROLSTACKSIZE]; +struct control *cend[CONTROLSTACKSIZE]; +int stackp = 0; + + +/* If there is an argument, give this to cshpar to use instead of + * stdin. In a few places, we call cp_evloop again if it returns 1 and + * exit (or close a file) if it returns 0... Because of the way + * sources are done, we can't allow the control structures to get + * blown away every time we return -- probably every time we type + * source at the keyboard and every time a source returns to keyboard + * input is ok though -- use ft_controlreset. */ + +static char *noredirect[] = { "stop", NULL } ; /* Only one?? */ + + +static struct control * +findlabel(char *s, struct control *ct) +{ + while (ct) { + if ((ct->co_type == CO_LABEL) && eq(s, ct->co_text->wl_word)) + break; + ct = ct->co_next; + } + return (ct); +} + + +/* This is also in cshpar.c ... */ +static void +pwlist(wordlist *wlist, char *name) +{ + wordlist *wl; + + if (!cp_debug) + return; + fprintf(cp_err, "%s : [ ", name); + for (wl = wlist; wl; wl = wl->wl_next) + fprintf(cp_err, "%s ", wl->wl_word); + fprintf(cp_err, "]\n"); + return; +} + + + +/* Note that we only do io redirection when we get to here - we also + * postpone some other things until now. */ +static void +docommand(wordlist *wlist) +{ + char *r, *s, *t; + char *lcom; + int nargs; + int i; + struct comm *command; + wordlist *wl, *nextc, *ee, *rwlist; + + if (cp_debug) { + printf("docommand "); + wl_print(wlist, stdout); + putc('\n', stdout); + } + + /* Do all the things that used to be done by cshpar when the line + * was read... */ + wlist = cp_variablesubst(wlist); + pwlist(wlist, "After variable substitution"); + + wlist = cp_bquote(wlist); + pwlist(wlist, "After backquote substitution"); + + wlist = cp_doglob(wlist); + pwlist(wlist, "After globbing"); + + if (!wlist || !wlist->wl_word) + return; + + /* Now loop through all of the commands given. */ + rwlist = wlist; + do { + for (nextc = wlist; nextc; nextc = nextc->wl_next) + if (eq(nextc->wl_word, cp_csep)) + break; + + /* Temporarily hide the rest of the command... */ + if (nextc && nextc->wl_prev) + nextc->wl_prev->wl_next = NULL; + ee = wlist->wl_prev; + if (ee) + wlist->wl_prev = NULL; + + if (nextc == wlist) { + /* There was no text... */ + goto out; + } + + /* And do the redirection. */ + cp_ioreset(); + for (i = 0; noredirect[i]; i++) + if (eq(wlist->wl_word, noredirect[i])) + break; + if (!noredirect[i]) { + if (!(wlist = cp_redirect(wlist))) { + cp_ioreset(); + return; + } + } + + /* Get rid of all the 8th bits now... */ + cp_striplist(wlist); + + s = wlist->wl_word; + + /* Look for the command in the command list. */ + for (i = 0; cp_coms[i].co_comname; i++) { + /* strcmp(cp_coms[i].co_comname, s) ... */ + for (t = cp_coms[i].co_comname, r = s; *t && *r; + t++, r++) + if (*t != *r) + break; + if (!*t && !*r) + break; + } + + /* Now give the user-supplied command routine a try... */ + if (!cp_coms[i].co_func && cp_oddcomm(s, wlist->wl_next)) + goto out; + + /* If it's not there, try it as a unix command. */ + if (!cp_coms[i].co_comname) { + if (cp_dounixcom && cp_unixcom(wlist)) + goto out; + fprintf(cp_err,"%s: no such command available in %s\n", + s, cp_program); + goto out; + + /* If it's there but spiceonly, and this is nutmeg, error. */ + } else if (!cp_coms[i].co_func && ft_nutmeg && + (cp_coms[i].co_spiceonly)) { + fprintf(cp_err,"%s: command available only in spice\n", + s); + goto out; + } + + /* The command was a valid spice/nutmeg command. */ + command = &cp_coms[i]; + nargs = 0; + for (wl = wlist->wl_next; wl; wl = wl->wl_next) + nargs++; + if (command->co_stringargs) { + lcom = wl_flatten(wlist->wl_next); + (*command->co_func) ((void *)(lcom)); + } else { + if (nargs < command->co_minargs) { + if (command->co_argfn) { + (*command->co_argfn) (wlist->wl_next, command); + } else { + fprintf(cp_err, "%s: too few args.\n", s); + } + } else if (nargs > command->co_maxargs) { + fprintf(cp_err, "%s: too many args.\n", s); + } else + (*command->co_func) (wlist->wl_next); + } + + /* Now fix the pointers and advance wlist. */ + out: wlist->wl_prev = ee; + if (nextc) { + if (nextc->wl_prev) + nextc->wl_prev->wl_next = nextc; + wlist = nextc->wl_next; + } + } while (nextc && wlist); + + wl_free(rwlist); + + /* Do periodic sorts of things... */ + cp_periodic(); + + cp_ioreset(); + return; +} + + +/* Execute a block. There can be a number of return values from this routine. + * NORMAL indicates a normal termination + * BROKEN indicates a break -- if the caller is a breakable loop, + * terminate it, otherwise pass the break upwards + * CONTINUED indicates a continue -- if the caller is a continuable loop, + * continue, else pass the continue upwards + * Any other return code is considered a pointer to a string which is + * a label somewhere -- if this label is present in the block, + * goto it, otherwise pass it up. Note that this prevents jumping + * into a loop, which is good. + * + * Note that here is where we expand variables, ``, and globs for + * controls. + * + * The 'num' argument is used by break n and continue n. */ +static char * +doblock(struct control *bl, int *num) +{ + struct control *ch, *cn = NULL; + wordlist *wl; + char *i; + int nn; + + switch (bl->co_type) { + case CO_WHILE: + while (bl->co_cond && cp_istrue(bl->co_cond)) { + for (ch = bl->co_children; ch; ch = cn) { + cn = ch->co_next; + i = doblock(ch, &nn); + switch (*i) { + + case NORMAL: + break; + + case BROKEN: /* Break. */ + if (nn < 2) + return (NORMAL_STR); + else { + *num = nn - 1; + return (BROKEN_STR); + } + + case CONTINUED: /* Continue. */ + if (nn < 2) { + cn = NULL; + break; + } else { + *num = nn - 1; + return (CONTINUED_STR); + } + + default: + cn = findlabel(i, bl->co_children); + if (!cn) + return (i); + } + } + } + break; + + case CO_DOWHILE: + do { + for (ch = bl->co_children; ch; ch = cn) { + cn = ch->co_next; + i = doblock(ch, &nn); + switch (*i) { + + case NORMAL: + break; + + case BROKEN: /* Break. */ + if (nn < 2) + return (NORMAL_STR); + else { + *num = nn - 1; + return (BROKEN_STR); + } + + case CONTINUED: /* Continue. */ + if (nn < 2) { + cn = NULL; + break; + } else { + *num = nn - 1; + return (CONTINUED_STR); + } + + default: + cn = findlabel(i, bl->co_children); + if (!cn) + return (i); + } + } + } while (bl->co_cond && cp_istrue(bl->co_cond)); + break; + + case CO_REPEAT: + while ((bl->co_numtimes > 0) || + (bl->co_numtimes == -1)) { + if (bl->co_numtimes != -1) + bl->co_numtimes--; + for (ch = bl->co_children; ch; ch = cn) { + cn = ch->co_next; + i = doblock(ch, &nn); + switch (*i) { + + case NORMAL: + break; + + case BROKEN: /* Break. */ + if (nn < 2) + return (NORMAL_STR); + else { + *num = nn - 1; + return (BROKEN_STR); + } + + case CONTINUED: /* Continue. */ + if (nn < 2) { + cn = NULL; + break; + } else { + *num = nn - 1; + return (CONTINUED_STR); + } + + default: + cn = findlabel(i, bl->co_children); + if (!cn) + return (i); + } + } + } + break; + + case CO_IF: + if (bl->co_cond && cp_istrue(bl->co_cond)) { + for (ch = bl->co_children; ch; ch = cn) { + cn = ch->co_next; + i = doblock(ch, &nn); + if (*i > 2) { + cn = findlabel(i, + bl->co_children); + if (!cn) + return (i); + } else if (*i != NORMAL) { + *num = nn; + return (i); + } + } + } else { + for (ch = bl->co_elseblock; ch; ch = cn) { + cn = ch->co_next; + i = doblock(ch, &nn); + if (*i > 2) { + cn = findlabel(i, + bl->co_elseblock); + if (!cn) + return (i); + } else if (*i != NORMAL) { + *num = nn; + return (i); + } + } + } + break; + + case CO_FOREACH: + for (wl = cp_variablesubst(cp_bquote(cp_doglob(wl_copy(bl->co_text)))); + wl; + wl = wl->wl_next) { + cp_vset(bl->co_foreachvar, VT_STRING, wl->wl_word); + for (ch = bl->co_children; ch; ch = cn) { + cn = ch->co_next; + i = doblock(ch, &nn); + switch (*i) { + + case NORMAL: + break; + + case BROKEN: /* Break. */ + if (nn < 2) + return (NORMAL_STR); + else { + *num = nn - 1; + return (BROKEN_STR); + } + + case CONTINUED: /* Continue. */ + if (nn < 2) { + cn = NULL; + break; + } else { + *num = nn - 1; + return (CONTINUED_STR); + } + + default: + cn = findlabel(i, bl->co_children); + if (!cn) + return (i); + } + } + } + break; + + case CO_BREAK: + if (bl->co_numtimes > 0) { + *num = bl->co_numtimes; + return (BROKEN_STR); + } else { + fprintf(cp_err, "Warning: break %d a no-op\n", + bl->co_numtimes); + return (NORMAL_STR); + } + + case CO_CONTINUE: + if (bl->co_numtimes > 0) { + *num = bl->co_numtimes; + return (CONTINUED_STR); + } else { + fprintf(cp_err, "Warning: continue %d a no-op\n", + bl->co_numtimes); + return (NORMAL_STR); + } + + case CO_GOTO: + wl = cp_variablesubst(cp_bquote(cp_doglob( + wl_copy(bl->co_text)))); + return (wl->wl_word); + + case CO_LABEL: + /* Do nothing. */ + break; + + case CO_STATEMENT: + docommand(wl_copy(bl->co_text)); + break; + + case CO_UNFILLED: + /* There was probably an error here... */ + fprintf(cp_err, "Warning: ignoring previous error\n"); + break; + + default: + fprintf(cp_err, + "doblock: Internal Error: bad block type %d\n", + bl->co_type); + return (NORMAL_STR); + } + return (NORMAL_STR); +} + + +/* Get a command. This does all the bookkeeping things like turning + * command completion on and off... */ +static wordlist * +getcommand(char *string) +{ + wordlist *wlist; + int i = 0, j; + static char buf[64]; + struct control *c; + + if (cp_debug) + fprintf(cp_err, "calling getcommand %s\n", + string ? string : ""); + if (cend[stackp]) { + for (c = cend[stackp]->co_parent; c; c = c->co_parent) + i++; + if (i) { + for (j = 0; j < i; j++) + buf[j] = '>'; + buf[j] = ' '; + buf[j + 1] = '\0'; + cp_altprompt = buf; + } else + cp_altprompt = NULL; + } else + cp_altprompt = NULL; + + cp_cwait = TRUE; + wlist = cp_parse(string); + cp_cwait = FALSE; + if (cp_debug) { + printf("getcommand "); + wl_print(wlist, stdout); + putc('\n', stdout); + } + return (wlist); +} + + +int +cp_evloop(char *string) +{ + wordlist *wlist, *ww; + struct control *x; + char *i; + int nn; + +#define newblock cend[stackp]->co_children = alloc(struct control); \ + ZERO(cend[stackp]->co_children,struct control), \ + cend[stackp]->co_children->co_parent = cend[stackp]; \ + cend[stackp] = cend[stackp]->co_children; \ + cend[stackp]->co_type = CO_UNFILLED; + + for (;;) { + wlist = getcommand(string); + if (wlist == NULL) { /* End of file or end of user input. */ + if (cend[stackp]->co_parent && !string) { + cp_resetcontrol(); + continue; + } else + return (0); + } + if ((wlist->wl_word == NULL) || (*wlist->wl_word == '\0')) { + /* User just typed return. */ + if (string) + return (1); + else { + cp_event--; + continue; + } + } + + /* Just a check... */ + for (ww = wlist; ww; ww = ww->wl_next) + if (!ww->wl_word) { + fprintf(cp_err, + "cp_evloop: Internal Error: NULL word pointer\n"); + continue; + } + + + /* Add this to the control structure list. If cend->co_type is + * CO_UNFILLED, the last line was the beginning of a block, + * and this is the unfilled first statement. */ + if (cend[stackp] && (cend[stackp]->co_type != CO_UNFILLED)) { + cend[stackp]->co_next = alloc(struct control); + ZERO(cend[stackp]->co_next, struct control); + cend[stackp]->co_next->co_prev = cend[stackp]; + cend[stackp]->co_next->co_parent = + cend[stackp]->co_parent; + cend[stackp] = cend[stackp]->co_next; + } else if (!cend[stackp]) { + control[stackp] = cend[stackp] = alloc(struct control); + ZERO(cend[stackp], struct control); + } + + if (eq(wlist->wl_word, "while")) { + cend[stackp]->co_type = CO_WHILE; + cend[stackp]->co_cond = wlist->wl_next; + if (!cend[stackp]->co_cond) { + fprintf(stderr, + "Error: missing while condition.\n"); + } + newblock; + } else if (eq(wlist->wl_word, "dowhile")) { + cend[stackp]->co_type = CO_DOWHILE; + cend[stackp]->co_cond = wlist->wl_next; + if (!cend[stackp]->co_cond) { + fprintf(stderr, + "Error: missing dowhile condition.\n"); + } + newblock; + } else if (eq(wlist->wl_word, "repeat")) { + cend[stackp]->co_type = CO_REPEAT; + if (!wlist->wl_next) { + cend[stackp]->co_numtimes = -1; + } else { + char *s; + double *dd; + wlist = cp_variablesubst(cp_bquote( + cp_doglob(wl_copy(wlist)))); + s = wlist->wl_next->wl_word; + + dd = ft_numparse(&s, FALSE); + if (dd) { + if (*dd < 0) { + fprintf(cp_err, + "Error: can't repeat a negative number of times\n"); + *dd = 0.0; + } + cend[stackp]->co_numtimes = (int) *dd; + } else + fprintf(cp_err, + "Error: bad repeat argument %s\n", + wlist->wl_next->wl_word); + } + newblock; + } else if (eq(wlist->wl_word, "if")) { + cend[stackp]->co_type = CO_IF; + cend[stackp]->co_cond = wlist->wl_next; + if (!cend[stackp]->co_cond) { + fprintf(stderr, + "Error: missing if condition.\n"); + } + newblock; + } else if (eq(wlist->wl_word, "foreach")) { + cend[stackp]->co_type = CO_FOREACH; + if (wlist->wl_next) { + wlist = wlist->wl_next; + cend[stackp]->co_foreachvar = + copy(wlist->wl_word); + wlist = wlist->wl_next; + } else + fprintf(stderr, + "Error: missing foreach variable.\n"); + wlist = cp_doglob(wlist); + cend[stackp]->co_text = wl_copy(wlist); + newblock; + } else if (eq(wlist->wl_word, "label")) { + cend[stackp]->co_type = CO_LABEL; + if (wlist->wl_next) { + cend[stackp]->co_text = wl_copy(wlist->wl_next); + /* I think of everything, don't I? */ + cp_addkword(CT_LABEL, wlist->wl_next->wl_word); + if (wlist->wl_next->wl_next) + fprintf(cp_err, + "Warning: ignored extra junk after label.\n"); + } else + fprintf(stderr, "Error: missing label.\n"); + } else if (eq(wlist->wl_word, "goto")) { + /* Incidentally, this won't work if the values 1 and 2 ever get + * to be valid character pointers -- I think it's reasonably + * safe to assume they aren't... */ + cend[stackp]->co_type = CO_GOTO; + if (wlist->wl_next) { + cend[stackp]->co_text = wl_copy(wlist->wl_next); + if (wlist->wl_next->wl_next) + fprintf(cp_err, + "Warning: ignored extra junk after goto.\n"); + } else + fprintf(stderr, "Error: missing label.\n"); + } else if (eq(wlist->wl_word, "continue")) { + cend[stackp]->co_type = CO_CONTINUE; + if (wlist->wl_next) { + cend[stackp]->co_numtimes = scannum(wlist-> + wl_next->wl_word); + if (wlist->wl_next->wl_next) + fprintf(cp_err, + "Warning: ignored extra junk after continue %d.\n", + cend[stackp]->co_numtimes); + } else + cend[stackp]->co_numtimes = 1; + } else if (eq(wlist->wl_word, "break")) { + cend[stackp]->co_type = CO_BREAK; + if (wlist->wl_next) { + cend[stackp]->co_numtimes = scannum(wlist-> + wl_next->wl_word); + if (wlist->wl_next->wl_next) + fprintf(cp_err, + "Warning: ignored extra junk after break %d.\n", + cend[stackp]->co_numtimes); + } else + cend[stackp]->co_numtimes = 1; + } else if (eq(wlist->wl_word, "end")) { + /* Throw away this thing. */ + if (!cend[stackp]->co_parent) { + fprintf(stderr, "Error: no block to end.\n"); + cend[stackp]->co_type = CO_UNFILLED; + } else if (cend[stackp]->co_prev) { + cend[stackp]->co_prev->co_next = NULL; + x = cend[stackp]; + cend[stackp] = cend[stackp]->co_parent; + tfree(x); + } else { + x = cend[stackp]; + cend[stackp] = cend[stackp]->co_parent; + cend[stackp]->co_children = NULL; + tfree(x); + } + } else if (eq(wlist->wl_word, "else")) { + if (!cend[stackp]->co_parent || + (cend[stackp]->co_parent->co_type != + CO_IF)) { + fprintf(stderr, "Error: misplaced else.\n"); + cend[stackp]->co_type = CO_UNFILLED; + } else { + if (cend[stackp]->co_prev) + cend[stackp]->co_prev->co_next = NULL; + else + cend[stackp]->co_parent->co_children = NULL; + cend[stackp]->co_parent->co_elseblock = cend[stackp]; + cend[stackp]->co_prev = NULL; + } + } else { + cend[stackp]->co_type = CO_STATEMENT; + cend[stackp]->co_text = wlist; + } + if (!cend[stackp]->co_parent) { + x = cend[stackp]; + /* We have to toss this do-while loop in here so + * that gotos at the top level will work. + */ + do { + i = doblock(x, &nn); + switch (*i) { + case NORMAL: + break; + case BROKEN: + fprintf(cp_err, + "Error: break not in loop or too many break levels given\n"); + break; + case CONTINUED: + fprintf(cp_err, + "Error: continue not in loop or too many continue levels given\n"); + break; + default: + x = findlabel(i, control[stackp]); + if (!x) + fprintf(cp_err, "Error: label %s not found\n", i); + } + if (x) + x = x->co_next; + } while (x); + } + if (string) + return (1); /* The return value is irrelevant. */ + } +} + +/* This blows away the control structures... */ +void +cp_resetcontrol(void) +{ + if (cend[stackp] && cend[stackp]->co_parent) + fprintf(cp_err, "Warning: EOF before block terminated\n"); + /* We probably should free the control structures... */ + control[0] = cend[0] = NULL; + stackp = 0; + cp_kwswitch(CT_LABEL, (char *) NULL); + return; +} + + +/* Push or pop a new control structure set... */ +void +cp_popcontrol(void) +{ + if (cp_debug) + fprintf(cp_err, "pop: stackp: %d -> %d\n", stackp, stackp - 1); + if (stackp < 1) + fprintf(cp_err, "cp_popcontrol: Internal Error: stack empty\n"); + else + stackp--; + return; +} + + +void +cp_pushcontrol(void) +{ + if (cp_debug) + fprintf(cp_err, "push: stackp: %d -> %d\n", stackp, stackp + 1); + if (stackp > CONTROLSTACKSIZE - 2) { + fprintf(cp_err, "Error: stack overflow -- max depth = %d\n", + CONTROLSTACKSIZE); + stackp = 0; + } else { + stackp++; + control[stackp] = cend[stackp] = NULL; + } + return; +} + + +/* And this returns to the top level (for use in the interrupt handlers). */ +void +cp_toplevel(void) +{ + stackp = 0; + if (cend[stackp]) + while (cend[stackp]->co_parent) + cend[stackp] = cend[stackp]->co_parent; + return; +} + + diff --git a/src/frontend/control.h b/src/frontend/control.h new file mode 100644 index 000000000..7b5132193 --- /dev/null +++ b/src/frontend/control.h @@ -0,0 +1,45 @@ +#ifndef _CONTROL_H +#define _CONTROL_H + + +/* Stuff to do control structures. We keep a history (seperate from + * the cshpar history, for now at least) of commands and their event + * numbers, with a block considered as a statement. In a goto, the + * first word in co_text is where to go, likewise for label. For + * conditional controls, we have to call ft_getpnames and ft_evaluate + * each time, since the dvec pointers will change... Also we should do + * variable and backquote substitution each time... */ +struct control { + int co_type; /* One of CO_* ... */ + wordlist *co_cond; /* if, while, dowhile */ + char *co_foreachvar; /* foreach */ + int co_numtimes; /* repeat, break & continue levels */ + wordlist *co_text; /* Ordinary text and foreach values. */ + struct control *co_parent; /* If this is inside a block. */ + struct control *co_children; /* The contents of this block. */ + struct control *co_elseblock; /* For if-then-else. */ + struct control *co_next; + struct control *co_prev; +} ; + +enum co_command { + CO_UNFILLED, + CO_STATEMENT, + CO_WHILE, + CO_DOWHILE, + CO_IF, + CO_FOREACH, + CO_BREAK, + CO_CONTINUE, + CO_LABEL, + CO_GOTO, + CO_REPEAT +}; + +#define CONTROLSTACKSIZE 256 /* Better be enough. */ + +extern struct control *control[CONTROLSTACKSIZE]; +extern struct control *cend[CONTROLSTACKSIZE]; +extern int stackp; + +#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/ftehelp.h b/src/frontend/ftehelp.h new file mode 100644 index 000000000..de368fe80 --- /dev/null +++ b/src/frontend/ftehelp.h @@ -0,0 +1,22 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Jeffrey M. Hsu +**********/ + +/* + + Defines for help. +*/ + +#define E_HASPLOTS 1 +#define E_NOPLOTS 2 +#define E_HASGRAPHS 4 +#define E_MENUMODE 8 + +#define E_BEGINNING 4096 +#define E_INTERMED 8192 +#define E_ADVANCED 16384 +#define E_ALWAYS 32768 + +/* default is intermediate level */ +#define E_DEFHMASK 8192 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/hcomp.c b/src/frontend/hcomp.c new file mode 100644 index 000000000..657296618 --- /dev/null +++ b/src/frontend/hcomp.c @@ -0,0 +1,9 @@ +#include + +int +hcomp(const void *a, const void *b) +{ + struct comm **c1 = (struct comm **) a; + struct comm **c2 = (struct comm **) b; + return (strcmp((*c1)->co_comname, (*c2)->co_comname)); +} diff --git a/src/frontend/hcomp.h b/src/frontend/hcomp.h new file mode 100644 index 000000000..eed3558b8 --- /dev/null +++ b/src/frontend/hcomp.h @@ -0,0 +1,7 @@ +#ifndef _HCOMP_H +#define _HCOMP_H + + +int hcomp(const void *a, const void *b); + +#endif diff --git a/src/frontend/help/ChangeLog b/src/frontend/help/ChangeLog new file mode 100644 index 000000000..d6163fa49 --- /dev/null +++ b/src/frontend/help/ChangeLog @@ -0,0 +1,32 @@ +1999-08-12 Emmanuel Rouat + + * x11disp.c: made a cast to (XtCallbackProc) when necessary + + * readhelp.c: sanitised the code slighly + + * *.c: changed functions from K&R into ANSI using protoize + +1999-08-08 Emmanuel Rouat + + * xdisplay.c: removed all X10 related code + + * Makefile.am (DEFS): removed -DWANT_MFB (don't need it) + +1999-08-03 Emmanuel Rouat + + * readhelp.c: HAVE_SYS_DIR_H and HAVE_DIRENT_H instead of + HAS_BSDDIRS and HAS_SYSVDIRS. + +1999-07-31 Emmanuel Rouat + + * Makefile.am: added @X_CFLAGS@ in INCLUDES list and removed unused LIBS + + +28-07-1999 emmanuel.rouat@wanadoo.fr (Manu Rouat) + + * help.c: + * provide.c: + * x11disp.c: changed HAS_X11 define to X_DISPLAY_MISSING, which is supplied + by autoconf in config.h + + * removed -DWANT_X11 in Makefile.am \ No newline at end of file diff --git a/src/frontend/help/Makefile.am b/src/frontend/help/Makefile.am new file mode 100644 index 000000000..e2871d998 --- /dev/null +++ b/src/frontend/help/Makefile.am @@ -0,0 +1,18 @@ +## Process this file with automake to produce Makefile.in + +noinst_LIBRARIES = libhlp.a + +libhlp_a_SOURCES = \ + help.c \ + provide.c \ + readhelp.c \ + textdisp.c \ + xdisplay.c \ + x11disp.c + + + +INCLUDES = -I$(top_srcdir)/src/include @X_CFLAGS@ + + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/frontend/help/help.c b/src/frontend/help/help.c new file mode 100644 index 000000000..603b4c99e --- /dev/null +++ b/src/frontend/help/help.c @@ -0,0 +1,171 @@ +/********** +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 +**********/ + +/* + * The main entry point for the help system. + */ + +#include +#include "ngspice.h" +#include "cpstd.h" +#include "hlpdefs.h" +#include "suffix.h" + +char *hlp_directory; +extern char *hlp_filelist[]; +int hlp_ftablesize = 0; + +void +hlp_main(char *path, wordlist *wl) +{ + topic *top; + fplace *place; + + hlp_directory = path; + + if (wl) { + while (wl) { + if (!(place = findglobalsubject(wl->wl_word))) { + fprintf(stderr, "Error: No such topic: %s\n", + wl->wl_word); + wl = wl->wl_next; + continue; + } + if (!(top = hlp_read(place))) { + fprintf(stderr, "Error: can't read topic\n"); + wl = wl->wl_next; + continue; + } + hlp_provide(top); + wl = wl->wl_next; + } + } else { + if (!(place = findglobalsubject("main"))) { + fprintf(stderr, "Error: no main topic\n"); + return; + } + if (!(top = hlp_read(place))) { + fprintf(stderr, "Error: can't read topic\n"); + return; + } + hlp_provide(top); + } + +#ifdef X_DISPLAY_MISSING + hlp_free(); +#endif + + return; +} + +fplace * +findglobalsubject(char *subject) +{ + + fplace *place; + char **dict; + long fpos; + + place = 0; + for (dict = hlp_filelist; *dict && **dict; dict++) { + fpos = findsubject(*dict, subject); + if (fpos != -1) { + place = (fplace *) tmalloc(sizeof(fplace)); + place->fpos = fpos; + place->filename = copy(*dict); + place->fp = hlp_fopen(*dict); + break; + } + } + return(place); +} + +/* see if file is on filelist */ +bool +hlp_approvedfile(char *filename) +{ + char **s; + + for (s = hlp_filelist; *s && **s; s++) { + if (cieq(*s, filename)) return(TRUE); + } + return(FALSE); +} + +/* keep file pointers on top level files so we don't always have to do + fopen's */ +FILE *hlp_fopen(char *filename) +{ + static struct { + char filename[BSIZE_SP]; + FILE *fp; + } hlp_ftable[32]; + int i; + char buf[BSIZE_SP]; + + for (i=0; i < hlp_ftablesize; i++) { + if (cieq(filename, hlp_ftable[i].filename)) { + return(hlp_ftable[i].fp); + } + } + + /* not already in table */ + strcpy(buf, hlp_directory); /* set up pathname */ + strcat(buf, DIR_PATHSEP); + strcat(buf, filename); + strcat(buf, ".txt"); + hlp_pathfix(buf); + if (!(hlp_ftable[hlp_ftablesize].fp = fopen(buf, "r"))) { + perror(buf); + return (NULL); + } + + strcpy(hlp_ftable[hlp_ftablesize].filename, filename); + hlp_ftablesize++; + + return(hlp_ftable[hlp_ftablesize - 1].fp); + +} + +/* ARGSUSED */ +void +hlp_pathfix(char *buf) +{ + char *s, *t, *u, bufx[1025]; + char *dir_pathsep; + extern char *cp_tildexpand( ); + + dir_pathsep = DIR_PATHSEP; + + if (!buf) + return; + + s = cp_tildexpand(buf); + if (sizeof(DIR_PATHSEP) == 2) { + if (*dir_pathsep != '/') { + for (t = s; *t; t++) { + if (*t == '/') + *t = *dir_pathsep; + } + } else + strcpy(buf, s); + } else { + /* For vms; this probably doesn't work, but neither did the old code */ + for (s = bufx, t = buf; *t; t++) { + if (*t == '/') + for (u = DIR_PATHSEP; *u; u++) { + *s++ = *u; + } + else + *s++ = *t; + } + *s = 0; + strcpy(buf, s); + } + if (s) + tfree(s); + return; +} diff --git a/src/frontend/help/provide.c b/src/frontend/help/provide.c new file mode 100644 index 000000000..7afcdf301 --- /dev/null +++ b/src/frontend/help/provide.c @@ -0,0 +1,145 @@ +/********** +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 +**********/ + +/* + * faustus@cad.berkeley.edu, ucbvax!faustus + * Permission is granted to modify and re-distribute this code in any manner + * as long as this notice is preserved. All standard disclaimers apply. + * + * Toss the help window up on the screen, and deal with the graph... + */ + +#include +#include "ngspice.h" +#include "cpstd.h" +#include "hlpdefs.h" +#include "suffix.h" + +bool hlp_usex = FALSE; + +void +hlp_provide(topic *top) +{ + toplink *res; + topic *parent, *newtop; + + if (!top) + return; + +#ifndef X_DISPLAY_MISSING + if (getenv("DISPLAY") || hlp_displayname) + hlp_usex = TRUE; +#endif + + top->xposition = top->yposition = 0; + if (hlp_usex) { + if (!hlp_xdisplay(top)) { + fprintf(stderr, "Couldn't open X display.\n"); + return; + } + } else { + if (!hlp_tdisplay(top)) { + fprintf(stderr, "Couldn't display text\n"); + return; + } + } + +#ifndef X_DISPLAY_MISSING /* X11 does this asynchronously */ + if (hlp_usex) return; +#endif + + for (;;) { + if (hlp_usex) + res = hlp_xhandle(&parent); + else + res = hlp_thandle(&parent); + if (!res && !parent) { + /* No more windows. */ + hlp_killfamily(top); + if (hlp_usex) hlp_xclosedisplay(); /* need to change + display pointer back J.H. */ + return; + } + if (res) { + /* Create a new window... */ + if (hlp_usex) + hlp_xwait(parent, TRUE); + if (!(newtop = hlp_read(res->place))) { + fprintf(stderr, "Internal error: bad link\n"); + hlp_xwait(parent, FALSE); + continue; + } + if (hlp_usex) + hlp_xwait(parent, FALSE); + newtop->next = parent->children; + parent->children = newtop; + newtop->parent = parent; + newtop->xposition = parent->xposition + 50; + newtop->yposition = parent->yposition + 50; + if (hlp_usex) { + if (!hlp_xdisplay(newtop)) { + fprintf(stderr, "Couldn't open win\n"); + return; + } + } else { + if (!hlp_tdisplay(newtop)) { + fprintf(stderr, "Couldn't display\n"); + return; + } + } + } else { + /* Blow this one and its descendants away. */ + hlp_killfamily(parent); + hlp_fixchildren(parent); + if (parent == top) + return; + } + } + +} + +void +hlp_fixchildren(topic *parent) +{ + + topic *pa; + + if (parent->parent) { + if (parent->parent->children == parent) + parent->parent->children = + parent->next; + else { + for (pa = parent->parent->children; + pa->next; pa = pa->next) + if (pa->next == parent) + break; + if (!pa->next) { + fprintf(stderr, "bah...\n"); + } + pa->next = pa->next->next; + } + } +} + +/* Note that this doesn't actually free the data structures, just gets + * rid of the window. + */ + +void +hlp_killfamily(topic *top) +{ + topic *ch; + + for (ch = top->children; ch; ch = ch->next) + hlp_killfamily(ch); + if (hlp_usex) + hlp_xkillwin(top); + else + hlp_tkillwin(top); + top->children = NULL; + return; +} + diff --git a/src/frontend/help/readhelp.c b/src/frontend/help/readhelp.c new file mode 100644 index 000000000..8cc4f98ef --- /dev/null +++ b/src/frontend/help/readhelp.c @@ -0,0 +1,359 @@ +/********** +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 +**********/ + +/* + * SJB 20 May 2001 + * Bug fix in help_read() + * findsubject() now ignores case and does additional searches for partial matches + * when a complete match is not found - additional code based on code in MacSpice. + */ + +#include +#include "ngspice.h" +#include "cpstd.h" +#include "hlpdefs.h" +#include "suffix.h" + +static char *getsubject(fplace *place); +static toplink *getsubtoplink(char **ss); + +static topic *alltopics = NULL; + +static fplace *copy_fplace(fplace *place); + +static int +sortcmp(const void *a, const void *b) +{ + toplink **tlp1 = (toplink **) a; + toplink **tlp2 = (toplink **) b; + + return (strcmp((*tlp1)->description, (*tlp2)->description)); +} + + +static void +sortlist(toplink **tlp) +{ + toplink **vec, *tl; + int num = 0, i; + + for (tl = *tlp; tl; tl = tl->next) + num++; + if (!num) + return; + vec = (toplink **) tmalloc(sizeof (toplink *) * num); + for (tl = *tlp, i = 0; tl; tl = tl->next, i++) + vec[i] = tl; + (void) qsort((char *) vec, num, sizeof (toplink *), sortcmp); + *tlp = vec[0]; + for (i = 0; i < num - 1; i++) + vec[i]->next = vec[i + 1]; + vec[i]->next = NULL; + tfree(vec); + return; +} + + +topic * +hlp_read(fplace *place) +{ + char buf[BSIZE_SP]; + topic *top = alloc(topic); + toplink *topiclink; + toplink *tl, *tend = NULL; + wordlist *wl, *end = NULL; + int i, fchanges; + char *s; + bool mof = FALSE; + + if (!place) + return 0; + + top->place = copy_fplace(place); + + /* get the title */ + if (!place->fp) place->fp = hlp_fopen(place->filename); + if (!place->fp) return(NULL); + fseek(place->fp, place->fpos, 0); + (void) fgets(buf, BSIZE_SP, place->fp); /* skip subject */ + (void) fgets(buf, BSIZE_SP, place->fp); + for (s = buf; *s && (*s != '\n'); s++) + ; + *s = '\0'; + top->title = copy(&buf[7]); /* don't copy "TITLE: " */ + + /* get the text */ + /* skip to TEXT: */ + while (fgets(buf, BSIZE_SP, place->fp)) { + if (!strncmp("TEXT: ", buf, 6)) break; + if ((*buf == '\0') || /* SJB - bug fix */ + !strncmp("SEEALSO: ", buf, 9) || + !strncmp("SUBTOPIC: ", buf, 10)) { + /* no text */ + top->text = NULL; + goto endtext; + } + } + mof = TRUE; + while (mof && !strncmp("TEXT: ", buf, 6)) { + for (s = &buf[6], fchanges = 0; *s && (*s != '\n'); s++) + if (((s[0] == '\033') && s[1]) || + ((s[0] == '_') && (s[1] == '\b'))) + fchanges++; + *s = '\0'; + wl = alloc(wordlist); + wl->wl_word = copy(&buf[6]); + if (end) + end->wl_next = wl; + else + top->text = wl; + wl->wl_prev = end; + end = wl; + top->numlines++; + if ((i = strlen(&buf[6]) - fchanges) > top->maxcols) + top->maxcols = i; + mof = fgets(buf, BSIZE_SP, place->fp) == NULL ? FALSE : TRUE; + } +endtext: + + /* get subtopics */ + while(mof && !strncmp("SUBTOPIC: ", buf, 10)) { + s = &buf[10]; + /* process tokens within line, updating pointer */ + while (*s) { + if ((topiclink = getsubtoplink(&s))) { + if (tend) + tend->next = topiclink; + else + top->subtopics = topiclink; + tend = topiclink; + } + } + mof = fgets(buf, BSIZE_SP, place->fp) == NULL ? FALSE : TRUE; + } + + /* get see alsos */ + tend = NULL; + while(mof && !strncmp("SEEALSO: ", buf, 9)) { + s = &buf[9]; + /* process tokens within line, updating pointer */ + while (*s) { + if ((topiclink = getsubtoplink(&s))) { + if (tend) + tend->next = topiclink; + else + top->seealso = topiclink; + tend = topiclink; + } + } + mof = fgets(buf, BSIZE_SP, place->fp) == NULL ? FALSE : TRUE; + } + + /* Now we have to fill in the subjects + for the seealsos and subtopics. */ + for (tl = top->seealso; tl; tl = tl->next) + tl->description = getsubject(tl->place); + for (tl = top->subtopics; tl; tl = tl->next) + tl->description = getsubject(tl->place); + + sortlist(&top->seealso); + /* sortlist(&top->subtopics); It looks nicer if they + are in the original order */ + + top->readlink = alltopics; + alltopics = top; + + return (top); +} + +/* *ss is of the form filename:subject */ +static toplink *getsubtoplink(char **ss) +{ + toplink *tl; + char *tmp, *s, *t; + char subject[BSIZE_SP]; + + if (!**ss) return(NULL); + + s = *ss; + + tl = alloc(toplink); + if ((tmp =strchr(s, ':'))) { + tl->place = alloc(fplace); + tl->place->filename = strncpy( + tmalloc((unsigned) (sizeof (char) * (tmp - s + 1))), + s, (tmp - s)); + tl->place->filename[tmp - s] = '\0'; + strtolower(tl->place->filename); + + /* see if filename is on approved list */ + if (!hlp_approvedfile(tl->place->filename)) { + tfree(tl->place); + tfree(tl); + /* skip up to next comma or newline */ + while (*s && *s != ',' && *s != '\n') s++; + while (*s && (*s == ',' || *s == ' ' || *s == '\n')) s++; + *ss = s; + return(NULL); + } + + tl->place->fp = hlp_fopen(tl->place->filename); + for (s = tmp + 1, t = subject; *s && *s != ',' && *s != '\n'; s++) { + *t++ = *s; + } + *t = '\0'; + tl->place->fpos = findsubject(tl->place->filename, subject); + if (tl->place->fpos == -1) { + tfree(tl->place); + tfree(tl); + while (*s && (*s == ',' || *s == ' ' || *s == '\n')) s++; + *ss = s; + return(NULL); + } + } else { + fprintf(stderr, "bad filename:subject pair %s\n", s); + /* skip up to next free space */ + while (*s && *s != ',' && *s != '\n') s++; + while (*s && (*s == ',' || *s == ' ' || *s == '\n')) s++; + *ss = s; + tfree(tl->place); + tfree(tl); + return(NULL); + } + while (*s && (*s == ',' || *s == ' ' || *s == '\n')) s++; + *ss = s; + return(tl); +} + +/* returns a file position, -1 on error */ +long +findsubject(char *filename, char *subject) +{ + + FILE *fp; + char buf[BSIZE_SP]; + struct hlp_index indexitem; + + if (!filename) { + return -1; + } + + /* open up index for filename */ + sprintf(buf, "%s%s%s.idx", hlp_directory, DIR_PATHSEP, filename); + hlp_pathfix(buf); + if (!(fp = fopen(buf, "rb"))) { + perror(buf); + return(-1); + } + + /* try it exactly (but ignore case) */ + while(fread((char *) &indexitem, sizeof (struct hlp_index), 1, fp)) { + if (!strncasecmp(subject, indexitem.subject, 64)) { /* sjb - ignore case */ + fclose(fp); + return(indexitem.fpos); + } + } + + fclose(fp); + + if (!(fp = fopen(buf, "rb"))) { + perror(buf); + return(-1); + } + + /* try it abbreviated (ignore case) */ + while(fread((char *) &indexitem, sizeof (struct hlp_index), 1, fp)) { + if (!strncasecmp(indexitem.subject,subject, strlen(subject))) { + fclose(fp); + return(indexitem.fpos); + } + } + + fclose(fp); + + if (!(fp = fopen(buf, "rb"))) { + perror(buf); + return(-1); + } + + /* try it within */ /* FIXME: need a case independent version of strstr() */ + while(fread((char *) &indexitem, sizeof (struct hlp_index), 1, fp)) { + if (strstr(indexitem.subject,subject)) { + fclose(fp); + return(indexitem.fpos); + } + } + + fclose(fp); + return(-1); + +} + +static char * +getsubject(fplace *place) +{ + char buf[BSIZE_SP], *s; + + if (!place->fp) place->fp = hlp_fopen(place->filename); + if (!place->fp) return(NULL); + + fseek(place->fp, place->fpos, 0); + (void) fgets(buf, BSIZE_SP, place->fp); + for (s = buf; *s && (*s != '\n'); s++) + ; + *s = '\0'; + return (copy(&buf[9])); /* don't copy "SUBJECT: " */ +} + + +static +void tlfree(toplink *tl) +{ + toplink *nt = NULL; + + while (tl) { + tfree(tl->description); + tfree(tl->place->filename); + tfree(tl->place); + /* Don't free the button stuff... */ + nt = tl->next; + tfree(tl); + tl = nt; + } + return; +} + + +void +hlp_free(void) +{ + topic *top, *nt = NULL; + + for (top = alltopics; top; top = nt) { + nt = top->readlink; + tfree(top->title); + tfree(top->place); + wl_free(top->text); + tlfree(top->subtopics); + tlfree(top->seealso); + tfree(top); + } + alltopics = NULL; + return; +} + +static fplace * +copy_fplace(fplace *place) +{ + fplace *newplace; + + newplace = (fplace *) tmalloc(sizeof(fplace)); + newplace->filename = copy(place->filename); + newplace->fpos = place->fpos; + newplace->fp = place->fp; + + return(newplace); +} diff --git a/src/frontend/help/textdisp.c b/src/frontend/help/textdisp.c new file mode 100644 index 000000000..556a50dae --- /dev/null +++ b/src/frontend/help/textdisp.c @@ -0,0 +1,201 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + + +/* + * faustus@cad.berkeley.edu, ucbvax!faustus + * Permission is granted to modify and re-distribute this code in any manner + * as long as this notice is preserved. All standard disclaimers apply. + * + */ + +#include "ngspice.h" +#include "cpdefs.h" +#include "hlpdefs.h" +#include "suffix.h" + +static topic *curtop; +static bool quitflag; + +static void putline(char *s); +static int putstuff(toplink *tl, int base); + +int hlp_width = 72; + +bool +hlp_tdisplay(topic *top) +{ + wordlist *wl; + int i = 0; + + curtop = top; + + out_init(); + out_printf("\n\t%s\n", top->title); + for (wl = top->text; wl; wl = wl->wl_next) + putline(wl->wl_word); + if (top->subtopics) { + out_printf("\tSub-Topics:\n\n"); + i = putstuff(top->subtopics, 0); + } + if (top->seealso) { + out_printf("\n\tSee Also:\n\n"); + (void) putstuff(top->seealso, i); + } + out_printf("\n"); + return (TRUE); +} + +toplink * +hlp_thandle(topic **parent) +{ + char buf[BSIZE_SP], *s; + toplink *tl; + int num; + + quitflag = FALSE; + if (!curtop) { + *parent = NULL; + return (NULL); + } + for (;;) { + fprintf(cp_out, "Selection (`?' for help): "); + (void) fflush(cp_out); + if (!fgets(buf, BSIZE_SP, cp_in)) { + clearerr(stdin); + quitflag = TRUE; + *parent = NULL; + return (NULL); + } + + for (s = buf; *s && isspace(*s); s++) + ; + switch (*s) { + case '?': + fprintf(cp_out, +"\nType the number of a sub-topic or see also, or one of:\n\ +\tr\tReprint the current topic\n\ +\tp or CR\tReturn to the previous topic\n\ +\tq\tQuit help\n\ +\t?\tPrint this message\n\n"); + continue; + + case 'r': + (void) hlp_tdisplay(curtop); + continue; + + case 'q': + quitflag = TRUE; + *parent = NULL; + return (NULL); + + case 'p': + case '\n': + case '\r': + case '\0': + *parent = curtop; + return (NULL); + } + if (!isdigit(*s)) { + fprintf(cp_err, "Invalid command\n"); + continue; + } + num = atoi(s); + if (num <= 0) { + fprintf(cp_err, "Bad choice.\n"); + continue; + } + for (tl = curtop->subtopics; tl; tl = tl->next) + if (--num == 0) + break; + if (num) { + for (tl = curtop->seealso; tl; tl = tl->next) + if (--num == 0) + break; + } + if (num) { + fprintf(cp_err, "Bad choice.\n"); + continue; + } + *parent = curtop; + return (tl); + } +} + +/* ARGSUSED */ +void +hlp_tkillwin(topic *top) +{ + if (curtop) + curtop = curtop->parent; + if (curtop && !quitflag) + (void) hlp_tdisplay(curtop); + return; +} + +/* This has to rip out the font changes from the lines... */ + +static void +putline(char *s) +{ + char buf[BSIZE_SP]; + int i = 0; + + while (*s) { + if (((*s == '\033') && s[1]) || + ((*s == '_') && (s[1] == '\b'))) + s += 2; + else + buf[i++] = *s++; + } + buf[i] = '\0'; + out_printf("%s\n", buf); + return; +} + +/* Figure out the number of columns we can use. Assume an entry like + * nn) word -- add 5 characters to the width... + */ + +static int +putstuff(toplink *tl, int base) +{ + int maxwidth = 0, ncols, nrows, nbuts = 0, i, j, k; + toplink *tt; + + for (tt = tl; tt; tt = tt->next) { + if (strlen(tt->description) + 5 > maxwidth) + maxwidth = strlen(tt->description) + 5; + nbuts++; + } + ncols = hlp_width / maxwidth; + if (!ncols) { + fprintf(stderr, "Help, button too big!!\n"); + return (0); + } + if (ncols > nbuts) + ncols = nbuts; + maxwidth = hlp_width / ncols; + nrows = nbuts / ncols; + if (nrows * ncols < nbuts) + nrows++; + + for (i = 0; i < nrows; i++) { + for (tt = tl, j = 0; j < i; j++, tt = tt->next) + ; + for (j = 0; j < ncols; j++) { + if (tt) + out_printf("%2d) %-*s ", base + j * nrows + i + + 1, maxwidth - 5, tt->description); + for (k = 0; k < nrows; k++) + if (tt) + tt = tt->next; + + } + out_printf("\n"); + } + return (nbuts); +} + diff --git a/src/frontend/help/x11disp.c b/src/frontend/help/x11disp.c new file mode 100644 index 000000000..bf72dc6df --- /dev/null +++ b/src/frontend/help/x11disp.c @@ -0,0 +1,287 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: Jeffrey M. Hsu +Modified 1999 Emmanuel Rouat +**********/ + +#include +#include "ngspice.h" + +#ifndef X_DISPLAY_MISSING + +#include "cpstd.h" +#include "hlpdefs.h" +#include +#include +#include +#include +#include +#include +#include +#include + +static bool started = FALSE; +static topic *topics = NULL; +void newtopic(Widget w, caddr_t client_data, caddr_t call_data), delete(Widget w, caddr_t client_data, caddr_t call_data), quit(Widget w, caddr_t client_data, caddr_t call_data); +static void sputline(char *buf, char *s); + +/* Create a new window... */ +bool +hlp_xdisplay(topic *top) +{ + + toplink *tl; + handle *hand; + + wordlist *wl; + char *buf; + + static Arg titleargs[] = { + { XtNtop, (XtArgVal) XtChainTop }, + { XtNbottom, (XtArgVal) XtChainTop }, + { XtNleft, (XtArgVal) XtChainLeft }, + { XtNright, (XtArgVal) XtChainLeft }, + { XtNwidth, (XtArgVal) 650 }, + }; + + static Arg formargs[ ] = { + { XtNtop, (XtArgVal) XtChainTop }, + { XtNtop, (XtArgVal) XtChainTop }, + { XtNtop, (XtArgVal) XtChainTop }, + { XtNbottom, (XtArgVal) XtChainBottom }, + }; + Arg htextargs[7]; +/* Arg vportargs[5]; */ + static Arg bboxargs[ ] = { + { XtNtop, (XtArgVal) XtChainBottom }, + { XtNtop, (XtArgVal) XtChainBottom }, + { XtNtop, (XtArgVal) XtChainBottom }, + { XtNtop, (XtArgVal) XtChainBottom }, + { XtNbottom, (XtArgVal) XtChainBottom }, + { XtNleft, (XtArgVal) XtChainLeft }, + { XtNright, (XtArgVal) XtChainLeft }, + }; + Arg buttonargs[1]; + Arg labelargs[3]; + Widget buttonwidget; + + if (!started) { /* have to init everything */ + + /* assume X toolkit already initialize */ + + started = TRUE; + + } + + top->shellwidget = XtCreateApplicationShell("shell", + topLevelShellWidgetClass, NULL, 0); + + if (!top->parent) { + top->xposition = hlp_initxpos; + top->yposition = hlp_initypos; + } else { + top->xposition = top->parent->xposition + X_INCR; + top->yposition = top->parent->yposition + Y_INCR; + } + XtSetArg(formargs[0], XtNx, top->xposition); + XtSetArg(formargs[1], XtNy, top->yposition); + top->formwidget = XtCreateManagedWidget("form", formWidgetClass, + top->shellwidget, formargs, XtNumber(formargs)); + + /* we really want a title bar widget for this, sigh */ + top->titlewidget = XtCreateManagedWidget("title", + boxWidgetClass, top->formwidget, + titleargs, XtNumber(titleargs)); + XtSetArg(labelargs[0], XtNlabel, top->title); + XtCreateManagedWidget("titlelabel", labelWidgetClass, + top->titlewidget, labelargs, 1); + XtSetArg(buttonargs[0], XtNlabel, "quit help"); + buttonwidget = XtCreateManagedWidget("quit", commandWidgetClass, + top->titlewidget, buttonargs, 1); + XtAddCallback(buttonwidget, XtNcallback, (XtCallbackProc) quit, top); + XtSetArg(buttonargs[0], XtNlabel, "delete window"); + buttonwidget = XtCreateManagedWidget("delete", commandWidgetClass, + top->titlewidget, buttonargs, XtNumber(buttonargs)); + XtAddCallback(buttonwidget, XtNcallback, (XtCallbackProc) delete, top); + + buf = tmalloc(80 * top->numlines + 100); + buf[0] = '\0'; + for (wl = top->text; wl; wl = wl->wl_next) { + sputline(buf, wl->wl_word); + } + top->chartext = buf; /* make sure gets deallocated later XXX */ + XtSetArg(htextargs[0], XtNstring, top->chartext); + XtSetArg(htextargs[1], XtNallowResize, True); + XtSetArg(htextargs[2], XtNscrollHorizontal, True ); + XtSetArg(htextargs[3], XtNscrollVertical, True ); + XtSetArg(htextargs[4], XtNfromVert, top->titlewidget); + XtSetArg(htextargs[5], XtNwidth, 660); + XtSetArg(htextargs[6], XtNheight, 350); + top->textwidget = XtCreateManagedWidget("helptext", + asciiTextWidgetClass, top->formwidget, htextargs, + XtNumber(htextargs)); + + if (top->subtopics) { + XtSetArg(labelargs[0], XtNfromVert, top->textwidget); + XtSetArg(labelargs[1], XtNvertDistance, 8); + XtSetArg(labelargs[2], XtNlabel, "Subtopics: "); + top->sublabelwidget = XtCreateManagedWidget("sublabel", + labelWidgetClass, top->formwidget, labelargs, XtNumber(labelargs)); + + XtSetArg(bboxargs[0], XtNwidth, 400); + XtSetArg(bboxargs[1], XtNallowResize, True); + XtSetArg(bboxargs[2], XtNfromVert, top->sublabelwidget); + top->subboxwidget = XtCreateManagedWidget("buttonbox", + boxWidgetClass, top->formwidget, bboxargs, XtNumber(bboxargs)); + + for (tl = top->subtopics; tl; tl = tl->next) { + tl->button.text = tl->description; + tl->button.tag = tl->place; + if (!tl->button.text) + tl->button.text = ""; + + XtSetArg(buttonargs[0], XtNlabel, tl->button.text); + buttonwidget = XtCreateManagedWidget(tl->button.text, + commandWidgetClass, top->subboxwidget, buttonargs, + XtNumber(buttonargs)); + /* core leak XXX */ + hand = (handle *) tmalloc(sizeof (struct handle)); + hand->result = tl; + hand->parent = top; + XtAddCallback(buttonwidget, XtNcallback, (XtCallbackProc) newtopic, hand); + } + } + + if (top->seealso) { + if (top->subtopics) + XtSetArg(labelargs[0], XtNfromVert, top->subboxwidget); + else + XtSetArg(labelargs[0], XtNfromVert, top->textwidget); + XtSetArg(labelargs[1], XtNvertDistance, 8); + XtSetArg(labelargs[2], XtNlabel, "See also: "); + top->seelabelwidget = XtCreateManagedWidget("seelabel", + labelWidgetClass, top->formwidget, labelargs, XtNumber(labelargs)); + + XtSetArg(bboxargs[0], XtNwidth, 400); + XtSetArg(bboxargs[1], XtNallowResize, True); + XtSetArg(bboxargs[2], XtNfromVert, top->seelabelwidget); + top->seeboxwidget = XtCreateManagedWidget("buttonbox", + boxWidgetClass, top->formwidget, bboxargs, XtNumber(bboxargs)); + + for (tl = top->seealso; tl; tl = tl->next) { + tl->button.text = tl->description; + tl->button.tag = tl->place; + if (!tl->button.text) + tl->button.text = ""; + + XtSetArg(buttonargs[0], XtNlabel, tl->button.text); + buttonwidget = XtCreateManagedWidget(tl->button.text, + commandWidgetClass, top->seeboxwidget, buttonargs, 1); + hand = (handle *) tmalloc(sizeof (struct handle)); + /* core leak XXX */ + hand->result = tl; + hand->parent = top; + XtAddCallback(buttonwidget, XtNcallback, (XtCallbackProc) newtopic, hand); + } + } + + XtRealizeWidget(top->shellwidget); + + top->winlink = topics; + topics = top; + + return (TRUE); + +} + +void +newtopic(Widget w, caddr_t client_data, caddr_t call_data) +{ + topic *parent = ((handle *) client_data)->parent; + toplink *result = ((handle *) client_data)->result; + topic *newtop; + + if (!(newtop = hlp_read(result->place))) { + fprintf(stderr, "Internal error: bad link\n"); + } + + newtop->next = parent->children; + parent->children = newtop; + newtop->parent = parent; + newtop->xposition = parent->xposition + 50; + newtop->yposition = parent->yposition + 50; + if (!hlp_xdisplay(newtop)) { + fprintf(stderr, "Couldn't open win\n"); + return; + } +} + +void +delete(Widget w, caddr_t client_data, caddr_t call_data) +{ + + topic *top = (topic *) client_data; + + hlp_killfamily(top); + hlp_fixchildren(top); +} + +void +quit(Widget w, caddr_t client_data, caddr_t call_data) +{ + + topic *top = (topic *) client_data, *parent = top->parent; + + while (parent && parent->parent) parent = parent->parent; + hlp_killfamily(parent ? parent : top); +} + +void +hlp_xkillwin(topic *top) +{ + topic *last; + + if (top == topics) + topics = top->winlink; + else if (top->winlink) { /* we need this check for the + pathological case where you have two helps running, + normally hp_killfamily doesn't let this happen */ + for (last = topics; last->winlink; last = last->winlink) + if (last->winlink == top) { + last->winlink = top->winlink; + break; + } + if (!last->winlink) { + fprintf(stderr, "window not in list!!\n"); + return; + } + } + XtDestroyWidget(top->shellwidget); + return; +} + +/* rip out font changes and write at end of buffer */ +static void +sputline(char *buf, char *s) +{ + + char tmp[BSIZE_SP], *tmpp; + int i = 0; + + while (*s) { + if (((*s == '\033') && s[1]) || + ((*s == '_') && (s[1] == '\b'))) + s += 2; + else + tmp[i++] = *s++; + } + tmp[i] = '\0'; + + /* strcat can't handle long strings */ + tmpp = buf + strlen(buf); + sprintf(tmpp, "%s\n", tmp); + + return; +} + +#endif /* X_DISPLAY_MISSING */ diff --git a/src/frontend/help/xdisplay.c b/src/frontend/help/xdisplay.c new file mode 100644 index 000000000..6b86f85da --- /dev/null +++ b/src/frontend/help/xdisplay.c @@ -0,0 +1,34 @@ +/********** +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 +**********/ + +#include +#include "ngspice.h" +#include "cpstd.h" +#include "hlpdefs.h" +#include "suffix.h" + + +char *hlp_boldfontname = BOLD_FONT; +char *hlp_regfontname = REG_FONT; +char *hlp_italicfontname = ITALIC_FONT; +char *hlp_titlefontname = TITLE_FONT; +char *hlp_buttonfontname = BUTTON_FONT; +char *hlp_displayname = NULL; +int hlp_initxpos = START_XPOS; +int hlp_initypos = START_YPOS; +int hlp_buttonstyle = BS_LEFT; + + + +#ifdef X_DISPLAY_MISSING +/* ARGSUSED */ bool hlp_xdisplay(topic *top) { return (FALSE); } +/* ARGSUSED */ void hlp_xkillwin(topic *top) { } +#endif + +/* ARGSUSED */ void hlp_xwait(topic *top, bool on) { } +void hlp_xclosedisplay(void) {} +toplink * hlp_xhandle(topic **pp) { *pp = NULL; return (NULL); } + diff --git a/src/frontend/init.c b/src/frontend/init.c new file mode 100644 index 000000000..c6092a269 --- /dev/null +++ b/src/frontend/init.c @@ -0,0 +1,36 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* Initialize stuff. */ + +#include +#include + +#include "init.h" +#include "variable.h" + + +char cp_chars[128]; + +static char *singlec = "<>;&"; + +void +cp_init(void) +{ + char *s, *getenv(const char *); + + bzero(cp_chars, 128); + for (s = singlec; *s; s++) + cp_chars[(int) *s] = (CPC_BRR | CPC_BRL); + cp_vset("history", VT_NUM, (char *) &cp_maxhistlength); + + cp_curin = stdin; + cp_curout = stdout; + cp_curerr = stderr; + + cp_ioreset(); + + return; +} diff --git a/src/frontend/init.h b/src/frontend/init.h new file mode 100644 index 000000000..2544db117 --- /dev/null +++ b/src/frontend/init.h @@ -0,0 +1,6 @@ +#ifndef _INIT_H +#define _INIT_H + + + +#endif 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/parser/ChangeLog b/src/frontend/parser/ChangeLog new file mode 100644 index 000000000..54f144fd9 --- /dev/null +++ b/src/frontend/parser/ChangeLog @@ -0,0 +1,105 @@ +2000-07-18 Arno W. Peters + + * numparse.c: Updates of header file includes. Some formatting + changes. + + * wlist.c: Moved this file to src/misc/wlist.c + + * Makefile.am: Removed wlist.c + +2000-03-11 Paolo Nenzi + + * numparse.c: as wrote in Chris Inbody patch: In numparse.c line + 17 changed the arg type of "num" to double. This (so far :) seems + to have had no adverse effect. + +2000-03-11 Paolo Nenzi + + * history.c: applied Chris Inbody patch. He + wrote: I had some trouble running ng-spice in batch mode on a + fairly repetitive job (probably 10 - 20 commands repeated 256 + times in a single session :), it was giving me "mangled history" + errors and then seg faulting. + + [...] In history.c line 425, added an exit(0) call to the else + condition to prevent seg fault upon generation of the history list + error. On line 25, changed cp_maxhistlength to 10000 vs 1000. The + value of 10000 was enough to keep my task from crashing but there + may be a better way to do this,.. I didn't try an arbitrarily high + number because I'm not sure what effect it would have on memory + usage or progam size or speed. Maybe that's the best answer, just + bump the value to 1e6 or something that no one would ever + approach. + +1999-09-07 Arno + + * lexical.c: read() requires #include of unistd.h. + + * modify.c: removed warning about char subscript for array. + + * unixcom.h: removed prototypes for static tryexec(), hash(). + + * var2.c: added default case to remove warning. + +1999-09-04 Emmanuel Rouat + + * *.c: added header files for .c files + +1999-08-28 Emmanuel Rouat + + * Removed all #includes of misc.h and util.h (now in spice.h) + +1999-08-27 Paolo Nenzi + + * Removed #include "suffix.h", replaced GENERIC with void and + ansified the code with protoize. + +1999-08-08 Emmanuel Rouat + + * Removed HAS_DOSDIRS and HAS_POW10 code in directory + + * Makefile.am (libcp_a_SOURCES): removed spawn.c (vms only) + +1999-08-06 Emmanuel Rouat + + * unixcom.c (cp_unixcom): + * cshpar.c: removed test on HAS_SYSTEM (always true on Unix?) + + * backq.c (backeval): changed HAS_POPEN in HAVE_POPEN + + * cshpar.c (fileexists): changed HAS_ACCESS in HAVE_ACCESS + (com_chdir): removed test on HAS_CHDIR (always true on Unix) + (com_shell): removed test on HAS_UNIX_SIGS (always true on Unix) + + * unixcom.c (cp_unixcom): changed HAS_INTSYSWAIT in HAVE_SYS_WAIT_H + +1999-08-05 Emmanuel Rouat + + * cshpar.c (com_chdir): removed HAS_GETENV tests. + + * var2.c (vareval): removed test on HAS_GETPID + + * unixcom.c: changed HAS_GETCWD in HAVE_GETCWD and HAS_GETWD into + HAVE_GETWD + + * lexical.c, gloc.c, cshpar.c: changed HAS_GETPW in HAVE_PWD_H + (com_chdir): changed HAS_GETCWD in HAVE_GETCWD (and #included + unistd.h) + + * std.c: changed HAS_QSORT in HAVE_QSORT + +1999-08-04 Emmanuel Rouat + + * cshpar.c: changed HAS_WAIT2(??) into HAVE_SYS_WAIT_H + +1999-08-03 Emmanuel Rouat + + * output.c: changed HAS_TERMCAP in HAVE_TERMCAP + + * unixcom.c: changed HAS_VFORK in HAVE_VORK_H + + * unixcom.c, complete.c, glob.c: HAVE_SYS_DIR_H and HAVE_DIRENT_H + (instead of HAS_BSDDIRS and HAS_SYSVDIRS) + + * cshpar.c (com_shell): changed HAS_VFORK in HAVE_VORK_H + diff --git a/src/frontend/parser/Makefile.am b/src/frontend/parser/Makefile.am new file mode 100644 index 000000000..b143119a5 --- /dev/null +++ b/src/frontend/parser/Makefile.am @@ -0,0 +1,26 @@ +## Process this file with automake to produce Makefile.in + +noinst_LIBRARIES = libparser.a + +libparser_a_SOURCES = \ + backq.c \ + backq.h \ + complete.c \ + complete.h \ + cshpar.c \ + cshpar.h \ + glob.c \ + glob.h \ + input.c \ + input.h \ + lexical.c \ + lexical.h \ + numparse.c \ + numparse.h \ + std.c \ + unixcom.c \ + unixcom.h + + +INCLUDES = -I$(top_srcdir)/src/include +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/frontend/parser/backq.c b/src/frontend/parser/backq.c new file mode 100644 index 000000000..4b8afcb60 --- /dev/null +++ b/src/frontend/parser/backq.c @@ -0,0 +1,116 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* + * + * Do backquote substitution on a word list. + */ + +#include +#include "ngspice.h" +#include "cpdefs.h" +#include "backq.h" + + +static wordlist *backeval(char *string); + +char cp_back = '`'; + +wordlist * +cp_bquote(wordlist *wlist) +{ + wordlist *wl, *nwl; + char *s, *t, buf[BSIZE_SP], wbuf[BSIZE_SP], tbuf[BSIZE_SP]; + int i; + + for (wl = wlist; wl; wl = wl->wl_next) { + + t = wl->wl_word; + if (!t) + continue; + i = 0; +loop: s =strchr(t, cp_back); + if (s == NULL) + continue; + while (t < s) + wbuf[i++] = *t++; + wbuf[i] = '\0'; + (void) strcpy(buf, ++s); + s = buf; + t++; + while (*s && (*s != cp_back)) { + t++; /* Get s and t past the next backquote. */ + s++; + } + /* What the heck, let "echo `foo" work... */ + *s = '\0'; + t++; /* Get past the second ` */ + if (!(nwl = backeval(buf))) { + wlist->wl_word = NULL; + return (wlist); + } + (void) strcpy(buf, wbuf); + if (nwl->wl_word) { + (void) strcat(buf, nwl->wl_word); + tfree(nwl->wl_word); + } + nwl->wl_word = copy(buf); + + (void) strcpy(tbuf, t); + wl = wl_splice(wl, nwl); + for(wlist = wl; wlist->wl_prev; wlist = wlist->wl_prev); + /* MW. We must move to the begging of new wordlist. */ + + (void) strcpy(buf, wl->wl_word); + i = strlen(buf); + (void) strcat(buf, tbuf); + tfree(wl->wl_word); + wl->wl_word = copy(buf); + t = &wl->wl_word[i]; + s = wl->wl_word; + for (i = 0; s < t; s++) + wbuf[i++] = *s; + goto loop; + } + return (wlist); +} + +/* Do a popen with the string, and then reset the file pointers so that + * we can use the first pass of the parser on the output. + */ + +static wordlist * +backeval(char *string) +{ +#ifdef HAVE_POPEN + FILE *proc, *old; + wordlist *wl; + bool intv; + extern FILE *popen(const char *, const char *); + + proc = popen(string, "r"); + if (proc == NULL) { + fprintf(cp_err, "Error: can't evaluate %s.\n", string); + return (NULL); + } + old = cp_inp_cur; + cp_inp_cur = proc; + intv = cp_interactive; + cp_interactive = FALSE; + cp_bqflag = TRUE; + wl = cp_lexer((char *) NULL); + cp_bqflag = FALSE; + cp_inp_cur = old; + cp_interactive = intv; + (void) pclose(proc); + return (wl); +#else + wordlist *wl = alloc(struct wordlist); + + wl->wl_word = copy(string); + return (wl); +#endif +} + diff --git a/src/frontend/parser/backq.h b/src/frontend/parser/backq.h new file mode 100644 index 000000000..98a6ce1de --- /dev/null +++ b/src/frontend/parser/backq.h @@ -0,0 +1,12 @@ +/************* + * Header file for backq.c + * 1999 E. Rouat + ************/ + +#ifndef BACKQ_H_INCLUDED +#define BACKQ_H_INCLUDED + +wordlist * cp_bquote(wordlist *wlist); + + +#endif diff --git a/src/frontend/parser/complete.c b/src/frontend/parser/complete.c new file mode 100644 index 000000000..f6953ea8c --- /dev/null +++ b/src/frontend/parser/complete.c @@ -0,0 +1,735 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +Modified: 1999 Paolo Nenzi +**********/ + +/* + * Command completion code. We keep a data structure with information on each + * command, to make lookups fast. We also keep NCLASSES (which is sort of + * hardwired as 32) sets of keywords. Each command has an array of NARGS + * bitmasks (also hardwired as 4), stating whether the command takes that + * particular class of keywords in that position. Class 0 always means + * filename completion. + */ + +#include +#include "ngspice.h" +#include "cpdefs.h" +#include "complete.h" + + +#ifdef HAVE_SYS_DIR_H +#include +#include +#else +# ifdef HAVE_DIRENT_H +# include +# include +# ifndef direct +# define direct dirent +# endif +# endif +#endif +#ifdef HAVE_PWD_H +#include +#endif + +#ifndef __MINGW32__ + /* MW. We also need ioctl.h here I think */ +#include +#endif + +/* Be sure the ioctls get included in the following */ +#ifdef HAVE_SGTTY_H +#include +#else +#ifdef HAVE_TERMIO_H +#include +#else +#ifdef HAVE_TERMIOS_H +#include +#endif +#endif +#endif + + +#define CNTRL_D '\004' +#define ESCAPE '\033' +#define NCLASSES 32 + +bool cp_nocc; /* Don't do command completion. */ + + + +static struct ccom *commands = NULL; /* The available commands. */ +static struct ccom *keywords[NCLASSES]; /* Keywords. */ + + +/* static declarations */ + +static struct ccom * getccom(char *first); +static wordlist * ccfilec(char *buf); +static wordlist * ccmatch(char *word, struct ccom **dbase); +static void printem(wordlist *wl); +static wordlist * cctowl(struct ccom *cc, bool sib); +static struct ccom * clookup(register char *word, struct ccom **dd, bool pref, + bool create); +/* MW. I need top node in cdelete */ +static void cdelete(struct ccom *node, struct ccom **top); + + +#ifdef TIOCSTI + +void +cp_ccom(wordlist *wlist, char *buf, bool esc) +{ + struct ccom *cc; + wordlist *a, *pmatches = NULL; + char wbuf[BSIZE_SP], *s; + int i=0; + int j, arg; + + buf = cp_unquote(copy(buf)); + cp_wstrip(buf); + if (wlist->wl_next) { /* Not the first word. */ + cc = getccom(wlist->wl_word); + if (cc && cc->cc_invalid) + cc = NULL; + arg = wl_length(wlist) - 2; + if (arg > 3) + arg = 3; + /* First filenames. */ + if (cc && (cc->cc_kwords[arg] & 1)) { + pmatches = ccfilec(buf); + s =strrchr(buf, '/'); + i = strlen(s ? s + 1 : buf); + if ((*buf == '~') && !index(buf, '/')) + i--; + } + + /* The keywords. */ + for (j = 1; j < NCLASSES; j++) { + if (cc && (cc->cc_kwords[arg] & (1 << j))) { + /* Find all the matching keywords. */ + a = ccmatch(buf, &keywords[j]); + i = strlen(buf); + if (pmatches) + pmatches = wl_append(pmatches, a); + else + pmatches = a; + } + } + wl_sort(pmatches); + } else { + pmatches = ccmatch(buf, &commands); + i = strlen(buf); + } + if (!esc) { + printem(pmatches); + wl_free(pmatches); + return; + } + + if (pmatches == NULL) { + (void) putchar('\07'); + (void) fflush(cp_out); + return; + } + if (pmatches->wl_next == NULL) { + (void) strcpy(wbuf, &pmatches->wl_word[i]); + goto found; + } + /* Now we know which words might work. Extend the command as much + * as possible, then TIOCSTI the characters out. + */ + for (j = 0;; j++, i++) { + wbuf[j] = pmatches->wl_word[i]; + for (a = pmatches->wl_next; a; a = a->wl_next) + if (a->wl_word[i] != wbuf[j]) { + (void) putchar('\07'); + (void) fflush(cp_out); + wbuf[j] = '\0'; + goto found; + } + if (wbuf[j] == '\0') + goto found; + } +found: for (i = 0; wbuf[i]; i++) + (void) ioctl(fileno(cp_in), TIOCSTI, &wbuf[i]); + wl_free(pmatches); + return; +} + +/* Figure out what the command is, given the name. Returns NULL if there + * is no such command in the command list. This is tricky, because we have + * to do a preliminary history and alias parse. (Or at least we should.) + */ + +static struct ccom * +getccom(char *first) +{ + struct alias *al; + int ntries = 21; + + /* First look for aliases. Just interested in the first word... + * Don't bother doing history yet -- that might get complicated. + */ + while (ntries-- > 0) { + for (al = cp_aliases; al; al = al->al_next) + if (eq(first, al->al_name)) { + first = al->al_text->wl_word; + break; + } + if (al == NULL) + break; + } + if (ntries == 0) { + fprintf(cp_err, "\nError: alias loop.\n"); + return (NULL); + } + return (clookup(first, &commands, FALSE, FALSE)); +} + +/* Figure out what files match the prefix. */ + +static wordlist * +ccfilec(char *buf) +{ + DIR *wdir; + char *lcomp, *dir; + struct direct *de; + wordlist *wl = NULL, *t; + struct passwd *pw; + + buf = copy(buf); /* Don't mangle anything... */ + + lcomp =strrchr(buf, '/'); + if (lcomp == NULL) { + dir = "."; + lcomp = buf; + if (*buf == cp_til) { /* User name completion... */ + buf++; + while ((pw = getpwent())) { + if (prefix(buf, pw->pw_name)) { + if (wl == NULL) { + wl = alloc(struct wordlist); + wl->wl_next = NULL; + wl->wl_prev = NULL; + } else { + t = wl; + wl = alloc(struct wordlist); + wl->wl_prev = NULL; + wl->wl_next = t; + t->wl_prev = wl; + } + wl->wl_word = copy(pw->pw_name); + } + } + (void) endpwent(); + return (wl); + } + } else { + dir = buf; + *lcomp = '\0'; + lcomp++; + if (*dir == cp_til) { + dir = cp_tildexpand(dir); + if (dir == NULL) + return (NULL); + } + } + if (!(wdir = opendir(dir))) + return (NULL); + while ((de = readdir(wdir))) + if ((prefix(lcomp, de->d_name)) && (*lcomp || + (*de->d_name != '.'))) { + if (wl == NULL) { + wl = alloc(struct wordlist); + wl->wl_next = NULL; + wl->wl_prev = NULL; + } else { + t = wl; + wl = alloc(struct wordlist); + wl->wl_next = t; + t->wl_prev = wl; + wl->wl_prev = NULL; + } + wl->wl_word = copy(de->d_name); + } + (void) closedir(wdir); + + wl_sort(wl); + return (wl); +} + +/* See what keywords or commands match the prefix. Check extra also + * for matches, if it is non-NULL. Return a wordlist which is in + * alphabetical order. Note that we have to call this once for each + * class. + */ + +static wordlist * +ccmatch(char *word, struct ccom **dbase) +{ + wordlist *wl; + register struct ccom *cc; + + cc = clookup(word, dbase, TRUE, FALSE); + if (cc) { + if (*word) /* This is a big drag. */ + wl = cctowl(cc, FALSE); + else + wl = cctowl(cc, TRUE); + } else + wl = NULL; + return (wl); +} + +/* Print the words in the wordlist in columns. They are already + * sorted... This is a hard thing to do with wordlists... + */ + +static void +printem(wordlist *wl) +{ + wordlist *ww; + int maxl = 0, num, i, j, k, width = 79, ncols, nlines; + + (void) putchar('\n'); + if (wl == NULL) { + return; + } + num = wl_length(wl); + for (ww = wl; ww; ww = ww->wl_next) { + j = strlen(ww->wl_word); + if (j > maxl) + maxl = j; + } + if (++maxl % 8) + maxl += 8 - (maxl % 8); + ncols = width / maxl; + if (ncols == 0) + ncols = 1; + nlines = num / ncols + (num % ncols ? 1 : 0); + for (k = 0; k < nlines; k++) { + for (i = 0; i < ncols; i++) { + j = i * nlines + k; + if (j < num) { + fprintf(cp_out, "%-*s", maxl, + wl_nthelem(j, wl)->wl_word); + } else + break; + } + (void) putchar('\n'); + } + return; +} + +#else /* if not TIOCSTI */ +void +cp_ccom(wordlist *wlist, char *buf, bool esc) +{ + return; +} +#endif + +static wordlist * +cctowl(struct ccom *cc, bool sib) +{ + wordlist *wl, *end; + + if (!cc) + return (NULL); + if (!cc->cc_invalid) { + wl = alloc(struct wordlist); + wl->wl_word = copy(cc->cc_name); + wl->wl_prev = NULL; + wl->wl_next = cctowl(cc->cc_child, TRUE); + if (wl->wl_next) + wl->wl_next->wl_prev = wl; + } else + wl = cctowl(cc->cc_child, TRUE); + if (sib) { + if (wl) { + for (end = wl; end->wl_next; end = end->wl_next) + ; + end->wl_next = cctowl(cc->cc_sibling, TRUE); + if (end->wl_next) + end->wl_next->wl_prev = wl; + } else + wl = cctowl(cc->cc_sibling, TRUE); + } + return (wl); +} + +/* We use this in com_device... */ + +wordlist * +cp_cctowl(char *stuff) +{ + return (cctowl((struct ccom *) stuff, TRUE)); +} + +/* Turn on and off the escape break character and cooked mode. */ + +void +cp_ccon(bool on) +{ +#ifdef TIOCSTI +#ifdef HAVE_SGTTY_H + static bool ison = FALSE; + struct tchars tbuf; + struct sgttyb sbuf; + + if (cp_nocc || !cp_interactive || (ison == on)) + return; + ison = on; + + /* Set the terminal up -- make escape the break character, and + * make sure we aren't in raw or cbreak mode. Hope the (void) + * ioctl's won't fail. + */ + (void) ioctl(fileno(cp_in), TIOCGETC, (char *) &tbuf); + if (on) + tbuf.t_brkc = ESCAPE; + else + tbuf.t_brkc = '\0'; + (void) ioctl(fileno(cp_in), TIOCSETC, (char *) &tbuf); + + (void) ioctl(fileno(cp_in), TIOCGETP, (char *) &sbuf); + sbuf.sg_flags &= ~(RAW|CBREAK); + (void) ioctl(fileno(cp_in), TIOCSETP, (char *) &sbuf); +#else + +# ifdef HAVE_TERMIO_H + +# define TERM_GET TCGETA +# define TERM_SET TCSETA + static struct termio sbuf; + static struct termio OS_Buf; + +# else +# ifdef HAVE_TERMIOS_H + +# ifdef __NetBSD__ +# define TCGETS +# define TCSETS +# endif + +# define TERM_GET TCGETS +# define TERM_SET TCSETS + static struct termios sbuf; + static struct termios OS_Buf; + +# endif +# endif + +# if defined(TERM_GET) || defined(__NetBSD__) + static bool ison = FALSE; + + if (cp_nocc || !cp_interactive || (ison == on)) + return; + ison = on; + + if (ison == TRUE) { +#ifdef __NetBSD__ + tcgetattr(fileno(cp_in),&OS_Buf); +#else + (void) ioctl(fileno(cp_in), TERM_GET, (char *) &OS_Buf); +#endif + sbuf = OS_Buf; + sbuf.c_cc[VEOF] = 0; + sbuf.c_cc[VEOL] = ESCAPE; + sbuf.c_cc[VEOL2] = CNTRL_D; +#ifdef __NetBSD__ + tcsetattr(fileno(cp_in),TCSANOW,&sbuf); +#else + (void) ioctl(fileno(cp_in), TERM_SET, (char *) &sbuf); +#endif + } else { +#ifdef __NetBSD__ + tcsetattr(fileno(cp_in),TCSANOW,&OS_Buf); +#else + (void) ioctl(fileno(cp_in), TERM_SET, (char *) &OS_Buf); +#endif + } + +# endif +#endif + +#endif + + return; +} + +/* The following routines deal with the command and keyword databases. + * Say whether a given word exists in the command database. + */ + +bool +cp_comlook(char *word) +{ + if (word && *word && clookup(word, &commands, FALSE, FALSE)) + return (TRUE); + else + return (FALSE); +} + +/* Add a command to the database, with the given keywords and filename + * flag. */ + +void +cp_addcomm(char *word, long int bits0, long int bits1, long int bits2, long int bits3) +{ + struct ccom *cc; + + cc = clookup(word, &commands, FALSE, TRUE); + cc->cc_invalid = 0; + cc->cc_kwords[0] = bits0; + cc->cc_kwords[1] = bits1; + cc->cc_kwords[2] = bits2; + cc->cc_kwords[3] = bits3; + return; +} + +/* Remove a command from the database. */ + +void +cp_remcomm(char *word) +{ + struct ccom *cc; + + cc = clookup(word, &commands, FALSE, FALSE); + if (cc) + cdelete(cc, &commands); + return; +} + +/* Add a keyword to the database. */ + +void +cp_addkword(int class, char *word) +{ + struct ccom *cc; + + if ((class < 1) || (class >= NCLASSES)) { + fprintf(cp_err, "cp_addkword: Internal Error: bad class %d\n", + class); + return; + } + word = copy(word); + cc = clookup(word, &keywords[class], FALSE, TRUE); + cc->cc_invalid = 0; + return; +} + +/* Remove a keyword from the database. */ + +void +cp_remkword(int class, char *word) +{ + struct ccom *cc; + + if ((class < 1) || (class >= NCLASSES)) { + fprintf(cp_err, "cp_remkword: Internal Error: bad class %d\n", + class); + return; + } + cc = clookup(word, &keywords[class], FALSE, FALSE); + if (cc) + cdelete(cc, &keywords[class]); + return; +} + +/* This routine is used when there are several keyword sets that are + * to be switched between rapidly. The return value is the old tree at + * that position, and the keyword class given is set to the argument. + */ + +char * +cp_kwswitch(int class, char *tree) +{ + char *old; + + if ((class < 1) || (class >= NCLASSES)) { + fprintf(cp_err, "cp_addkword: Internal Error: bad class %d\n", + class); + return (NULL); + } + old = (char *) keywords[class]; + keywords[class] = (struct ccom *) tree; + return (old); +} + +/* Throw away all the stuff and prepare to rebuild it from scratch... */ + + +void +cp_ccrestart(bool kwords) +{ + /* Ack. */ + return; +} + +void +throwaway(struct ccom *dbase) +{ + if (dbase->cc_child) + throwaway(dbase->cc_child); + if (dbase->cc_sibling) + throwaway(dbase->cc_sibling); + tfree(dbase); + return; +} + +/* Look up a word in the database. Because of the way the tree is set + * up, this also works for looking up all words with a given prefix + * (if the pref arg is TRUE). If create is TRUE, then the node is + * created if it doesn't already exist. + */ + +static struct ccom * +clookup(register char *word, struct ccom **dd, bool pref, bool create) +{ + register struct ccom *place = *dd, *tmpc; + int ind = 0, i; + char buf[BSIZE_SP]; + + if (!place) { + /* This is the first time we were called. */ + if (!create) + return (NULL); + else { + *dd = place = alloc(struct ccom); + ZERO(place, struct ccom); + buf[0] = *word; + buf[1] = '\0'; + place->cc_name = copy(buf); + if (word[1]) + place->cc_invalid = 1; + } + } + while (word[ind]) { + /* Walk down the sibling list until we find a node that + * matches 'word' to 'ind' places. + */ + while ((place->cc_name[ind] < word[ind]) && place->cc_sibling) + place = place->cc_sibling; + if (place->cc_name[ind] < word[ind]) { + /* This line doesn't go out that far... */ + if (create) { + place->cc_sibling = alloc(struct ccom); + ZERO(place->cc_sibling, struct ccom); + place->cc_sibling->cc_ysibling = place; + place->cc_sibling->cc_parent = place->cc_parent; + place = place->cc_sibling; + place->cc_name = tmalloc(ind + 2); + for (i = 0; i < ind + 1; i++) + place->cc_name[i] = word[i]; + place->cc_name[ind + 1] = '\0'; + place->cc_invalid = 1; + } else { + return (NULL); + } + } else if (place->cc_name[ind] > word[ind]) { + if (create) { + /* Put this one between place and its pred. */ + tmpc = alloc(struct ccom); + ZERO(tmpc, struct ccom); + tmpc->cc_parent = place->cc_parent; + tmpc->cc_sibling = place; + tmpc->cc_ysibling = place->cc_ysibling; + place->cc_ysibling = tmpc; + place = tmpc; + if (tmpc->cc_ysibling) + tmpc->cc_ysibling->cc_sibling = tmpc; + else if (tmpc->cc_parent) + tmpc->cc_parent->cc_child = tmpc; + else + *dd = place; + place->cc_name = tmalloc(ind + 2); + for (i = 0; i < ind + 1; i++) + place->cc_name[i] = word[i]; + place->cc_name[ind + 1] = '\0'; + place->cc_invalid = 1; + } else { + return (NULL); + } + } + + /* place now points to that node that matches the word for + * ind + 1 characters. + */ + if (word[ind + 1]) { /* More to go... */ + if (!place->cc_child) { + /* No children, maybe make one and go on. */ + if (create) { + tmpc = alloc(struct ccom); + ZERO(tmpc, struct ccom); + tmpc->cc_parent = place; + place->cc_child = tmpc; + place = tmpc; + place->cc_name = tmalloc(ind + 3); + for (i = 0; i < ind + 2; i++) + place->cc_name[i] = word[i]; + place->cc_name[ind + 2] = '\0'; + if (word[ind + 2]) + place->cc_invalid = 1; + } else { + return (NULL); + } + } else + place = place->cc_child; + ind++; + } else + break; + } + if (!pref && !create && place->cc_invalid) { + /* This is no good, we want a real word. */ + return (NULL); + } + return (place); +} + +/* Delete a node from the tree. Returns the new tree... */ +/* MW. It is quite difficoult to free() everything right, but... + * Anyway this could be more optimal, I think */ + +static void +cdelete(struct ccom *node, struct ccom **top) +{ + /* if cc_child exist only mark as deleted */ + node->cc_invalid = 1; + if (node->cc_child) + return; + + /* fix cc_sibling */ + if (node->cc_sibling) + node->cc_sibling->cc_ysibling = node->cc_ysibling; + if (node->cc_ysibling) + node->cc_ysibling->cc_sibling = node->cc_sibling; + + /* if we have cc_parent, check if it should not be removed too */ + if (node->cc_parent) { + + /* this node will be free() */ + if (node->cc_parent->cc_child == node) { + if (node->cc_ysibling) + node->cc_parent->cc_child = node->cc_ysibling; + else + node->cc_parent->cc_child = node->cc_sibling; + } + if (node->cc_parent->cc_invalid == 1) + /* free parent only if it is invalid */ + cdelete(node->cc_parent, top); + } + + /* now free() everything and check the top */ + if (node == *top) + *top = node->cc_sibling; + free(node->cc_name); + free(node); + return; +} + diff --git a/src/frontend/parser/complete.h b/src/frontend/parser/complete.h new file mode 100644 index 000000000..1399d0e39 --- /dev/null +++ b/src/frontend/parser/complete.h @@ -0,0 +1,45 @@ +/************* + * Header file for complete.c + * 1999 E. Rouat + ************/ + +#ifndef COMPLETE_H_INCLUDED +#define COMPLETE_H_INCLUDED + +/* The data structure for the commands is as follows: every node has a pointer + * to its leftmost child, where the children of a node are those of which + * the node is a prefix. This means that for a word like "ducks", there + * must be nodes "d", "du", "duc", etc (which are all marked "invalid", + * of course). This data structure is called a "trie". + */ + + + +#define NARGS 4 + +struct ccom { + char *cc_name; /* Command or keyword name. */ + long cc_kwords[NARGS]; /* What this command takes. */ + char cc_invalid; /* This node has been deleted. */ + struct ccom *cc_child; /* Left-most child. */ + struct ccom *cc_sibling;/* Right (alph. greater) sibling. */ + struct ccom *cc_ysibling;/* Left (alph. less) sibling. */ + struct ccom *cc_parent; /* Parent node. */ +} ; + + +void cp_ccom(wordlist *wlist, char *buf, bool esc); +wordlist * cp_cctowl(char *stuff); +void cp_ccon(bool on); +bool cp_comlook(char *word); +void cp_addcomm(char *word, long int bits0, long int bits1, long int bits2, + long int bits3); +void cp_remcomm(char *word); +void cp_addkword(int class, char *word); +void cp_remkword(int class, char *word); +char * cp_kwswitch(int class, char *tree); +void cp_ccrestart(bool kwords); +void throwaway(struct ccom *dbase); + + +#endif diff --git a/src/frontend/parser/cshpar.c b/src/frontend/parser/cshpar.c new file mode 100644 index 000000000..28b8e2d2c --- /dev/null +++ b/src/frontend/parser/cshpar.c @@ -0,0 +1,110 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* + * The main entry point for cshpar. + */ + + +#include "ngspice.h" +#include "cpdefs.h" +#include +#include "cshpar.h" + +#ifdef HAVE_SGTTY_H +#include +#else +#ifdef HAVE_TERMIO_H +#include +#else +#ifdef HAVE_TERMIOS_H +#include +#endif +#endif +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_PWD_H +#include +#endif + + +#ifdef HAVE_SYS_WAIT_H +#include +#endif + + + +/* Things go as follows: + * (1) Read the line and do some initial quoting (by setting the 8th bit), + * and command ignoring. Also deal with command completion. + * (2) Do history substitutions. (!, ^) + * (3) Do alias substitution. + * + * In front.c these things get done: + * (4) Do variable substitution. ($varname) + * (5) Do backquote substitution. (``) + * (6) Do globbing. (*, ?, [], {}, ~) + * (7) Do io redirection. + */ + + +void fixdescriptors(void); +static void pwlist(wordlist *wlist, char *name); + + +wordlist * +cp_parse(char *string) +{ + wordlist *wlist; + + wlist = cp_lexer(string); + + if (!string) + cp_event++; + + if (!wlist || !wlist->wl_word) + return (wlist); + + pwlist(wlist, "Initial parse"); + + wlist = cp_histsubst(wlist); + if (!wlist || !wlist->wl_word) + return (wlist); + pwlist(wlist, "After history substitution"); + if (cp_didhsubst) { + wl_print(wlist, stdout); + putc('\n', stdout); + } + + /* Add the word list to the history. */ + /* MW. If string==NULL we do not have to do this, and then play + * with cp_lastone is not needed, but watch out cp_doalias */ + if ((*wlist->wl_word) && !(string)) + cp_addhistent(cp_event - 1, wlist); + + wlist = cp_doalias(wlist); + pwlist(wlist, "After alias substitution"); + pwlist(wlist, "Returning "); + return (wlist); +} + +static void +pwlist(wordlist *wlist, char *name) +{ + wordlist *wl; + + if (!cp_debug) + return; + fprintf(cp_err, "%s : [ ", name); + for (wl = wlist; wl; wl = wl->wl_next) + fprintf(cp_err, "%s ", wl->wl_word); + fprintf(cp_err, "]\n"); + return; +} + diff --git a/src/frontend/parser/cshpar.h b/src/frontend/parser/cshpar.h new file mode 100644 index 000000000..735302a60 --- /dev/null +++ b/src/frontend/parser/cshpar.h @@ -0,0 +1,20 @@ +/************* + * Header file for cshpar.c + * 1999 E. Rouat + ************/ + +#ifndef CSHPAR_H_INCLUDED +#define CSHPAR_H_INCLUDED + +wordlist * cp_parse(char *string); +void com_echo(wordlist *wlist); +wordlist * cp_redirect(wordlist *wl); +void cp_ioreset(void); +void com_shell(wordlist *wl); +void fixdescriptors(void); +void com_rehash(wordlist *wl); +void com_chdir(wordlist *wl); +void com_strcmp(wordlist *wl); + + +#endif diff --git a/src/frontend/parser/glob.c b/src/frontend/parser/glob.c new file mode 100644 index 000000000..4135e6eaa --- /dev/null +++ b/src/frontend/parser/glob.c @@ -0,0 +1,97 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* + * Expand global characters. + */ + +#include +#include "ngspice.h" +#include "cpdefs.h" +#include "glob.h" + +#ifdef HAVE_SYS_DIR_H +#include +#include +#else + +#ifdef HAVE_DIRENT_H +#include +#include +#ifndef direct +#define direct dirent +#endif +#endif + +#endif + +#ifdef HAVE_PWD_H +#include +#endif + + + +bool noglobs(); + +char cp_comma = ','; +char cp_til = '~'; + +/* For each word, go through two steps: expand the {}'s, and then do ?*[] + * globbing in them. Sort after the second phase but not the first... + */ + +/* MW. Now only tilde is supportef, {}*? don't work */ + +wordlist * +cp_doglob(wordlist *wlist) +{ + wordlist *wl; + char *s; + + + /* Do tilde expansion. */ + + for (wl = wlist; wl; wl = wl->wl_next) + if (*wl->wl_word == cp_til) { + s = cp_tildexpand(wl->wl_word); + if (!s) + *wl->wl_word = '\0'; /* MW. We Con't touch tmalloc addres */ + else + wl->wl_word = s; + } + + return (wlist); +} + +/* Expand tildes. */ + +char * +cp_tildexpand(char *string) +{ + char *result; + + result = tilde_expand(string); + + if (!result) { + if (cp_nonomatch) { + return copy(string); + } else { + return NULL; + } + } + return result; +} + + +/* Say whether the pattern p can match the string s. */ + +/* MW. Now simply compare strings */ + +bool +cp_globmatch(char *p, char *s) +{ + return(!(strcmp(p, s))); +} + diff --git a/src/frontend/parser/glob.h b/src/frontend/parser/glob.h new file mode 100644 index 000000000..01f73ce66 --- /dev/null +++ b/src/frontend/parser/glob.h @@ -0,0 +1,14 @@ +/************* + * Header file for glob.c + * 1999 E. Rouat + ************/ + +#ifndef GLOB_H_INCLUDED +#define GLOB_H_INCLUDED + +wordlist * cp_doglob(wordlist *wlist); +char * cp_tildexpand(char *string); +bool cp_globmatch(char *p, char *s); + + +#endif diff --git a/src/frontend/parser/input.c b/src/frontend/parser/input.c new file mode 100644 index 000000000..284e9c0e5 --- /dev/null +++ b/src/frontend/parser/input.c @@ -0,0 +1,60 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Jeffrey M. Hsu +**********/ + +/* + * Stand-alone input routine. + */ +#include +#include + +#include + +#include "fteinput.h" +#include "input.h" +#include "cpextern.h" + +/* A special 'getc' so that we can deal with ^D properly. There is no way for + * stdio to know if we have typed a ^D after some other characters, so + * don't use buffering at all + */ +int +inchar(FILE *fp) +{ + + char c; + int i; + + if (cp_interactive && !cp_nocc) { + do { + i = read((int) fileno(fp), &c, 1); + } while (i == -1 && errno == EINTR); + if (i == 0 || c == '\004') + return (EOF); + else if (i == -1) { + perror("read"); + return (EOF); + } else + return ((int) c); + } else + c = getc(fp); + return ((int) c); +} + + +extern void Input(REQUEST *req, RESPONSE *resp); + +int +input(FILE *fp) +{ + + REQUEST request; + RESPONSE response; + + request.option = char_option; + request.fp = fp; + Input(&request, &response); + return(response.reply.ch); + +} diff --git a/src/frontend/parser/input.h b/src/frontend/parser/input.h new file mode 100644 index 000000000..c5e9df378 --- /dev/null +++ b/src/frontend/parser/input.h @@ -0,0 +1,14 @@ +/************* + * Header file for input.c + * 1999 E. Rouat + ************/ + +#ifndef INPUT_H_INCLUDED +#define INPUT_H_INCLUDED + + +int inchar(FILE *fp); +int input(FILE *fp); + + +#endif diff --git a/src/frontend/parser/lexical.c b/src/frontend/parser/lexical.c new file mode 100644 index 000000000..659a4a7fc --- /dev/null +++ b/src/frontend/parser/lexical.c @@ -0,0 +1,316 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* + * Initial lexer. + */ + +#include +#include "ngspice.h" +#include "cpdefs.h" +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_PWD_H +#include +#include +#endif + +#ifndef __MINGW32__ + /* MW. Linux has TIOCSTI, so we include all headers here */ +#include +#endif + +#ifdef HAVE_SGTTY_H +#include +#include +#else +#ifdef HAVE_TERMIO_H +#include +#include +#else +#ifdef HAVE_TERMIOS_H +#include +#include +#endif +#endif +#endif + + +#include "fteinput.h" +#include "lexical.h" + +static void prompt(void); + + +FILE *cp_inp_cur = NULL; +int cp_event = 1; +bool cp_interactive = TRUE; +bool cp_bqflag = FALSE; +char *cp_promptstring = NULL; +char *cp_altprompt = NULL; +char cp_hash = '#'; + +static int numeofs = 0; + + +#define ESCAPE '\033' + +/* Return a list of words, with backslash quoting and '' quoting done. + * Strings en(void) closed in "" or `` are made single words and returned, + * but with the "" or `` still present. For the \ and '' cases, the + * 8th bit is turned on (as in csh) to prevent them from being recogized, + * and stripped off once all processing is done. We also have to deal with + * command, filename, and keyword completion here. + * If string is non-NULL, then use it instead of the fp. Escape and EOF + * have no business being in the string. + */ + +#define newword cw->wl_word = copy(buf); \ + cw->wl_next = alloc(struct wordlist); \ + cw->wl_next->wl_prev = cw; \ + cw = cw->wl_next; \ + cw->wl_next = NULL; \ + bzero(buf, BSIZE_SP); \ + i = 0; + +wordlist * +cp_lexer(char *string) +{ + int c; + int i, j; + wordlist *wlist = NULL, *cw = NULL; + char buf[BSIZE_SP], linebuf[BSIZE_SP], d; + int paren; + + if (cp_inp_cur == NULL) + cp_inp_cur = cp_in; + + if (!string && cp_interactive) { + cp_ccon(TRUE); + prompt(); + } +nloop: i = 0; + j = 0; + paren = 0; + bzero(linebuf, BSIZE_SP); + bzero(buf, BSIZE_SP); + wlist = cw = alloc(struct wordlist); + cw->wl_next = cw->wl_prev = NULL; + for (;;) { + if (string) { + c = *string++; + if (c == '\0') + c = '\n'; + if (c == ESCAPE) + c = '['; + } else + c = input(cp_inp_cur); + +gotchar: + if ((c != EOF) && (c != ESCAPE)) + linebuf[j++] = c; + if (c != EOF) + numeofs = 0; + if (i == BSIZE_SP - 1) { + fprintf(cp_err, "Warning: word too long.\n"); + c = ' '; + } + if (j == BSIZE_SP - 1) { + fprintf(cp_err, "Warning: line too long.\n"); + if (cp_bqflag) + c = EOF; + else + c = '\n'; + } + if (c != EOF) + c = strip(c); /* Don't need to do this really. */ + if ((c == '\\' && DIR_TERM != '\\') || (c == '\026') /* ^V */ ) { + c = quote(string ? *string++ : input(cp_inp_cur)); + linebuf[j++] = strip(c); + } + if ((c == '\n') && cp_bqflag) + c = ' '; + if ((c == EOF) && cp_bqflag) + c = '\n'; + if ((c == cp_hash) && !cp_interactive && (j == 1)) { + if (string) + return (NULL); + while (((c = input(cp_inp_cur)) != '\n') && + (c != EOF)); + goto nloop; + } + + if ((c == '(') || (c == '[')) /* MW. Nedded by parse() */ + paren++; + else if ((c == ')') || (c == ']')) + paren--; + + switch (c) { + case ' ': + case '\t': + if (i > 0) { + newword; + } + break; + + case '\n': + if (i) { + buf[i] = '\0'; + cw->wl_word = copy(buf); + } else if (cw->wl_prev) { + cw->wl_prev->wl_next = NULL; + tfree(cw); + } else { + cw->wl_word = NULL; + } + goto done; + + case '\'': + while (((c = (string ? *string++ : + input(cp_inp_cur))) != '\'') + && (i < BSIZE_SP - 1)) { + if ((c == '\n') || (c == EOF) || (c == ESCAPE)) + goto gotchar; + else { + buf[i++] = quote(c); + linebuf[j++] = c; + } + } + linebuf[j++] = '\''; + break; + + case '"': + case '`': + d = c; + buf[i++] = d; + while (((c = (string ? *string++ : input(cp_inp_cur))) + != d) && (i < BSIZE_SP - 2)) { + if ((c == '\n') || (c == EOF) || (c == ESCAPE)) + goto gotchar; + else if (c == '\\') { + linebuf[j++] = c; + c = (string ? *string++ : + input(cp_inp_cur)); + buf[i++] = quote(c); + linebuf[j++] = c; + } else { + buf[i++] = c; + linebuf[j++] = c; + } + } + buf[i++] = d; + linebuf[j++] = d; + break; + + case '\004': + case EOF: + if (cp_interactive && !cp_nocc && + (string == NULL)) { + if (j == 0) { + if (cp_ignoreeof && (numeofs++ + < 23)) { + fputs( + "Use \"quit\" to quit.\n", + stdout); + } else { + fputs("quit\n", stdout); + cp_doquit(); + } + goto done; + } + cp_ccom(wlist, buf, FALSE); + wl_free(wlist); + (void) fputc('\r', cp_out); + prompt(); + for (j = 0; linebuf[j]; j++) +#ifdef TIOCSTI + (void) ioctl(fileno(cp_out), TIOCSTI, linebuf + j); +#else + fputc(linebuf[j], cp_out); /* But you can't edit */ +#endif + goto nloop; + } else /* EOF during a source */ + { + if (cp_interactive) { + fputs("quit\n", stdout); + cp_doquit(); + goto done; + } else + return (NULL); + } + case ESCAPE: + if (cp_interactive && !cp_nocc) { + fputs("\b\b \b\b\r", cp_out); + prompt(); + for (j = 0; linebuf[j]; j++) +#ifdef TIOCSTI + (void) ioctl(fileno(cp_out), TIOCSTI, linebuf + j); +#else + fputc(linebuf[j], cp_out); /* But you can't edit */ +#endif + cp_ccom(wlist, buf, TRUE); + wl_free(wlist); + goto nloop; + } /* Else fall through */ + case ',': + if (paren < 1 && i > 0) { + newword; + break; + } + default: + /* We have to remember the special case $< + * here + */ + if ((cp_chars[c] & CPC_BRL) && (i > 0)) { + if ((c != '<') || (buf[i - 1] != '$')) { + newword; + } + } + buf[i++] = c; + if (cp_chars[c] & CPC_BRR) { + if ((c != '<') || (i < 2) || + (buf[i - 2] != '$')) { + newword; + } + } + } + } +done: + return (wlist); +} + +static void +prompt(void) +{ + char *s; + + if (cp_interactive == FALSE) + return; + if (cp_promptstring == NULL) + s = "-> "; + else + s = cp_promptstring; + if (cp_altprompt) + s = cp_altprompt; + while (*s) { + switch (strip(*s)) { + case '!': + fprintf(cp_out, "%d", cp_event); + break; + case '\\': + if (*(s + 1)) + (void) putc(strip(*++s), cp_out); + default: + (void) putc(strip(*s), cp_out); + } + s++; + } + (void) fflush(cp_out); + return; +} diff --git a/src/frontend/parser/lexical.h b/src/frontend/parser/lexical.h new file mode 100644 index 000000000..cf08fbee9 --- /dev/null +++ b/src/frontend/parser/lexical.h @@ -0,0 +1,15 @@ +/************* + * Header file for lexical.c + * 1999 E. Rouat + ************/ + +#ifndef LEXICAL_H_INCLUDED +#define LEXICAL_H_INCLUDED + + +wordlist * cp_lexer(char *string); +int inchar(FILE *fp); +int input(FILE *fp); + + +#endif diff --git a/src/frontend/parser/numparse.c b/src/frontend/parser/numparse.c new file mode 100644 index 000000000..64400819c --- /dev/null +++ b/src/frontend/parser/numparse.c @@ -0,0 +1,167 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* This routine parses a number. */ + +#include +#include +#include +#include "ftedefs.h" +#include "numparse.h" + + +static double +power10(double num) /* Chris Inbody */ +{ + double d = 1.0; + + while (num-- > 0) + d *= 10.0; + return (d); +} + + +bool ft_strictnumparse = FALSE; + +/* Parse a number. This will handle things like 10M, etc... If the number + * must not end before the end of the string, then whole is TRUE. + * If whole is FALSE and there is more left to the number, the argument + * is advanced to the end of the word. Returns NULL + * if no number can be found or if there are trailing characters when + * whole is TRUE. + * + * If ft_strictnumparse is TRUE, and whole is FALSE, the first of the + * trailing characters must be a '_'. */ +double * +ft_numparse(char **s, bool whole) +{ + double mant = 0.0; + int sign = 1, exsign = 1, p; + double expo = 0.0; + static double num; + char *string = *s; + + /* See if the number begins with + or -. */ + if (*string == '+') + string++; + else if (*string == '-') { + string++; + sign = -1; + } + + /* We don't want to recognise "P" as 0P, or .P as 0.0P... */ + if ((!isdigit(*string) && *string != '.') || + ((*string == '.') && !isdigit(string[1]))) + return (NULL); + + /* Now accumulate a number. Note ascii dependencies here... */ + while (isdigit(*string)) + mant = mant * 10.0 + (*string++ - '0'); + + /* Now maybe a decimal point. */ + if (*string == '.') { + string++; + p = 1; + while (isdigit(*string)) + mant += (*string++ - '0') / power10(p++); + } + + /* Now look for the scale factor or the exponent (can't have both). */ + switch (*string) { + case 'e': + case 'E': + /* Parse another number. */ + string++; + if (*string == '+') { + exsign = 1; + string++; + } else if (*string == '-') { + exsign = -1; + string++; + } + while(isdigit(*string)) + expo = expo * 10.0 + (*string++ - '0'); + if (*string == '.') { + string++; + p = 1; + while (isdigit(*string)) + expo += (*string++ - '0') / power10(p++); + } + expo *= exsign; + break; + case 't': + case 'T': + expo = 12.0; + string++; + break; + case 'g': + case 'G': + expo = 9.0; + string++; + break; + case 'k': + case 'K': + expo = 3.0; + string++; + break; + case 'u': + case 'U': + expo = -6.0; + string++; + break; + case 'n': + case 'N': + expo = -9.0; + string++; + break; + case 'p': + case 'P': + expo = -12.0; + string++; + break; + case 'f': + case 'F': + expo = -15.0; + string++; + break; + case 'm': + case 'M': + /* Can be either m, mil, or meg. */ + if (string[1] && string[2] && + ((string[1] == 'e') || (string[1] == 'E')) && + ((string[2] == 'g') || (string[2] == 'G'))) { + expo = 6.0; + string += 3; + } else if (string[1] && string[2] && + ((string[1] == 'i') || (string[1] == 'I')) && + ((string[2] == 'l') || (string[2] == 'L'))) { + expo = -6.0; + mant *= 25.4; + string += 3; + } else { + expo = -3.0; + string++; + } + break; + } + + if (whole && *string != '\0') { + return (NULL); + } else if (ft_strictnumparse && *string && isdigit(string[-1])) { + if (*string == '_') + while (isalpha(*string) || (*string == '_')) + string++; + else + return (NULL); + } else { + while (isalpha(*string) || (*string == '_')) + string++; + } + *s = string; + num = sign * mant * pow(10.0, expo); + if (ft_parsedb) + fprintf(cp_err, "numparse: got %e, left = %s\n", num, *s); + return (&num); +} diff --git a/src/frontend/parser/numparse.h b/src/frontend/parser/numparse.h new file mode 100644 index 000000000..44fd91fbc --- /dev/null +++ b/src/frontend/parser/numparse.h @@ -0,0 +1,14 @@ +/************* + * Header file for numparse.c + * 1999 E. Rouat + ************/ + +#ifndef NUMPARSE_H_INCLUDED +#define NUMPARSE_H_INCLUDED + + +double * ft_numparse(char **s, bool whole); + + + +#endif diff --git a/src/frontend/parser/std.c b/src/frontend/parser/std.c new file mode 100644 index 000000000..217084c12 --- /dev/null +++ b/src/frontend/parser/std.c @@ -0,0 +1,22 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* + * Standard utility routines. + * Most moved to MISC/ + */ + +#include +#include "ngspice.h" +#include "cpstd.h" + + +/* This might not be around. If not then forget about sorting. */ + +#ifndef HAVE_QSORT +#ifndef qsort +qsort() {} +#endif +#endif diff --git a/src/frontend/parser/unixcom.c b/src/frontend/parser/unixcom.c new file mode 100644 index 000000000..83de8b3d3 --- /dev/null +++ b/src/frontend/parser/unixcom.c @@ -0,0 +1,255 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* + * Routines to do execution of unix commands. + */ + +#include +#include "ngspice.h" +#include "cpdefs.h" +#include "unixcom.h" + +#ifdef HAVE_VFORK_H + +/* The only reason this exists is efficiency */ + +# ifdef HAVE_SYS_DIR_H +# include +# include +# else + +# ifdef HAVE_DIRENT_H +# include +# include +# ifndef direct +# define direct dirent +# endif +# endif +# endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include +#include + + +static bool tryexec(char *name, char *argv[]); +static int hash(register char *str); + + +struct hashent { + char *h_name; + char *h_path; + struct hashent *h_next; +} ; + +#define HASHSIZE 256 + +static struct hashent *hashtab[HASHSIZE]; +static char *dirbuffer; +static int dirlength, dirpos; + +/* Create the hash table for the given search path. pathlist is a : seperated + * list of directories. If docc is TRUE, then all the commands found are + * added to the command completion lists. + */ + +void +cp_rehash(char *pathlist, bool docc) +{ + register int i; + struct hashent *hh, *ht; + char buf[BSIZE_SP], pbuf[BSIZE_SP], *curpath; + DIR *pdir; + struct direct *entry; + + /* First clear out the old hash table. */ + for (i = 0; i < HASHSIZE; i++) { + for (hh = hashtab[i]; hh; hh = ht) { + ht = hh->h_next; + /* Don't free any of the other stuff -- it is too + * strange. + */ + tfree(hh); + } + hashtab[i] = NULL; + } + + while (pathlist && *pathlist) { + /* Copy one path to buf. We have to make sure that the path + * is a full path name. + */ + if (*pathlist == '/') + i = 0; + else { +#ifdef HAVE_GETWD + (void) getwd(buf); +#else +# ifdef HAVE_GETCWD + (void) getcwd(buf, sizeof(buf)); +# else + *buf = 0; +# endif +#endif + i = strlen(buf); + } + while (*pathlist && (*pathlist != ':')) + buf[i++] = *pathlist++; + while (*pathlist == ':') + pathlist++; + buf[i] = '\0'; + + curpath = copy(buf); + if (!(pdir = opendir(curpath))) + continue; + while (entry = readdir(pdir)) { + (void) strcpy(pbuf, curpath); + (void) strcat(pbuf, "/"); + (void) strcat(pbuf, entry->d_name); + /* Now we could make sure that it is really an + * executable, but that is too slow + * (as if "we" really cared). + */ + hh = alloc(struct hashent); + hh->h_name = copy(entry->d_name); + hh->h_path = curpath; + i = hash(entry->d_name); + /* Make sure this goes at the end, with + * possible duplications of names. + */ + if (hashtab[i]) { + ht = hashtab[i]; + while (ht->h_next) + ht = ht->h_next; + ht->h_next = hh; + } else + hashtab[i] = hh; + if (docc) { + /* Add to completion hash table. */ + cp_addcomm(entry->d_name, (long) 0, (long) 0, (long) 0, + (long) 0); + } + } + closedir(pdir); + } + return; +} + +/* The return value is FALSE if no command was found, and TRUE if it was. */ + +bool +cp_unixcom(wordlist *wl) +{ + int i; + register struct hashent *hh; + register char *name; + char **argv; + char buf[BSIZE_SP]; + + if (!wl) + return (FALSE); + name = wl->wl_word; + argv = wl_mkvec(wl); + if (cp_debug) { + printf("name: %s, argv: ", name); + wl_print(wl, stdout); + printf(".\n"); + } + if (index(name, '/')) + return (tryexec(name, argv)); + i = hash(name); + for (hh = hashtab[i]; hh; hh = hh->h_next) { + if (eq(name, hh->h_name)) { + (void) sprintf(buf, "%s/%s", hh->h_path, hh->h_name); + if (tryexec(buf, argv)) + return (TRUE); + } + } + return (FALSE); +} + +static bool +tryexec(char *name, char *argv[]) +{ +# ifdef HAVE_SYS_WAIT_H + int status; +# else + union wait status; +# endif + int pid, j; + RETSIGTYPE (*svint)( ), (*svquit)( ), (*svtstp)( ); + + pid = vfork( ); + if (pid == 0) { + fixdescriptors(); + (void) execv(name, argv); + (void) _exit(120); /* A random value. */ + /* NOTREACHED */ + } else { + svint = signal(SIGINT, SIG_DFL); + svquit = signal(SIGQUIT, SIG_DFL); + svtstp = signal(SIGTSTP, SIG_DFL); + do { + j = wait(&status); + } while (j != pid); + (void) signal(SIGINT, (SIGNAL_FUNCTION) svint); + (void) signal(SIGQUIT, (SIGNAL_FUNCTION) svquit); + (void) signal(SIGTSTP, (SIGNAL_FUNCTION) svtstp); + } + if (WTERMSIG(status) == 0 && WEXITSTATUS(status) == 120) + /*if ((status.w_termsig == 0) && (status.w_retcode == 120)) */ + return (FALSE); + else + return (TRUE); +} + +static int +hash(register char *str) +{ + register int i = 0; + + while (*str) + i += *str++; + return (i % HASHSIZE); +} + +/* Debugging. */ + +void +cp_hstat(void) +{ + struct hashent *hh; + int i; + + for (i = 0; i < HASHSIZE; i++) + for (hh = hashtab[i]; hh; hh = hh->h_next) + fprintf(cp_err, "i = %d, name = %s, path = %s\n", + i, hh->h_name, hh->h_path); + return; +} + +#else + +void +cp_rehash(char *pathlist, bool docc) +{ } + +bool +cp_unixcom(wordlist *wl) +{ + char *s = wl_flatten(wl); + + if (system(s)) + return (FALSE); + else + return (TRUE); + +} + +#endif diff --git a/src/frontend/parser/unixcom.h b/src/frontend/parser/unixcom.h new file mode 100644 index 000000000..64b15c02d --- /dev/null +++ b/src/frontend/parser/unixcom.h @@ -0,0 +1,16 @@ +/************* + * Header file for unixcom.c + * 1999 E. Rouat + ************/ + +#ifndef UNIXCOM_H_INCLUDED +#define UNIXCOM_H_INCLUDED + + +void cp_rehash(char *pathlist, bool docc); +bool cp_unixcom(wordlist *wl); +void cp_hstat(void); + + + +#endif diff --git a/src/frontend/plotting/ChangeLog b/src/frontend/plotting/ChangeLog new file mode 100644 index 000000000..09032d6f9 --- /dev/null +++ b/src/frontend/plotting/ChangeLog @@ -0,0 +1,9 @@ +2000-10-10 Arno W. Peters + + * graf.c: Removed need to press return after resizing the plot + window. + +2000-05-22 Paolo Nenzi + + * x11.c: Applied Widlok patch and reintroduced some #ifdef notdef + code. diff --git a/src/frontend/plotting/Makefile.am b/src/frontend/plotting/Makefile.am new file mode 100644 index 000000000..ec152081e --- /dev/null +++ b/src/frontend/plotting/Makefile.am @@ -0,0 +1,31 @@ +noinst_LIBRARIES = libplotting.a + +libplotting_a_SOURCES = \ + plotting.c \ + plotting.h \ + agraf.c \ + agraf.h \ + clip.c \ + clip.h \ + graf.c \ + graf.h \ + graphdb.c \ + graphdb.h \ + grid.c \ + grid.h \ + pvec.c \ + pvec.h \ + plot5.c \ + plot5.h \ + plotcurv.c \ + plotcurv.h \ + plotit.c \ + plotit.h \ + x11.c \ + x11.h \ + xgraph.c \ + xgraph.h + +INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/frontend @X_CFLAGS@ + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/frontend/plotting/agraf.c b/src/frontend/plotting/agraf.c new file mode 100644 index 000000000..f0059054b --- /dev/null +++ b/src/frontend/plotting/agraf.c @@ -0,0 +1,336 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* + * Line-printer (ASCII) plots. + */ + +#include "ngspice.h" +#include "cpdefs.h" +#include "ftedefs.h" +#include "dvec.h" +#include "fteparse.h" +#include "agraf.h" + +#include + +#define FUDGE 7 +#define MARGIN_BASE 11 +#define LCHAR '.' +#define MCHAR 'X' +#define PCHARS "+*=$%!0123456789" + +/* We should really deal with the xlog and delta arguments. This routine is + * full of magic numbers that make the formatting correct. + */ + + +void +ft_agraf(double *xlims, double *ylims, struct dvec *xscale, struct plot *plot, struct dvec *vecs, double xdel, double ydel, bool xlog, bool ylog, bool nointerp) +{ + int height; + bool nobreakp, novalue; + int maxx, maxy, omaxy; /* The size of the plotting area. */ + bool /* xlogscale = FALSE, */ ylogscale = FALSE; + char *field, buf[BSIZE_SP]; + char *line1, *line2, c, cb; + double xrange[2], yrange[2], x1, x2, yy1, y2, x, y; + int mag, hmt, lmt, dst, spacing, nsp, ypt, upper, lower, curline; + double tenpowmag, diff; + double *values = NULL; + struct dvec *v; + int margin = MARGIN_BASE; + int omargin; + int i, j, k; + int shift; + + + /* ANSI C does not specify how many digits are in an exponent for %c + * We assumed it was 2. If it's more, shift starting position over. + */ + sprintf(buf, "%1.1e", 0.0); /* expect 0.0e+00 */ + shift = strlen(buf) - 7; + margin += shift; + + /* Make sure the margin is correct */ + omargin = margin; + if (!cp_getvar("noasciiplotvalue", VT_BOOL, (char *) &novalue) && + !vec_eq(xscale, vecs)) { + margin *= 2; + } else + novalue = TRUE; + if ((xscale->v_gridtype == GRID_YLOG) || + (xscale->v_gridtype == GRID_LOGLOG)) + ylogscale = TRUE; + if (!cp_getvar("width", VT_NUM, (char *) &maxy)) { + maxy = DEF_WIDTH; + } + if (!cp_getvar("height", VT_NUM, (char *) &height)) + height = DEF_HEIGHT; + if (ft_nopage) + nobreakp = TRUE; + else + cp_getvar("nobreak", VT_BOOL, (char *) &nobreakp); + maxy -= (margin + FUDGE); + maxx = xscale->v_length; + xrange[0] = xlims[0]; + xrange[1] = xlims[1]; + yrange[0] = ylims[0]; + yrange[1] = ylims[1]; + + if (maxx < 2) { + fprintf(cp_err, + "Error: asciiplot can't handle scale with length < 2\n"); + return; + } + + if (maxx <= 0) { + fprintf(cp_err, "Note: no points to plot\n"); + return; + } + + for (v = vecs, i = 0; v; v = v->v_link2) { + v->v_linestyle = (PCHARS[i] ? PCHARS[i++] : '#'); + } + /* Now allocate the field and stuff. */ + field = tmalloc((maxy + 1) * (maxx + 1)); + line1 = tmalloc(maxy + margin + FUDGE + 1); + line2 = tmalloc(maxy + margin + FUDGE + 1); + if (!novalue) + values = (double *) tmalloc(maxx * sizeof (double)); + + /* Clear the field, put the lines in the right places, and create + * the headers. + */ + for (i = 0, j = (maxx + 1) * (maxy + 1); i < j; i++) + field[i] = ' '; + for (i = 0, j = maxy + margin + FUDGE; i < j; i++) { + line1[i] = '-'; + line2[i] = ' '; + } + line1[j] = line2[j] = '\0'; + + /* The following is similar to the stuff in grid.c */ + if ((xrange[0] > xrange[1]) || (yrange[0] > yrange[1])) { + fprintf(cp_err, + "ft_agraf: Internal Error: bad limits %g, %g, %g, %g\n", + xrange[0], xrange[1], yrange[0], yrange[1]); + return; + } + + /* gcc doesn't like !double */ + if (ylims[1] == 0.0) { + mag = (int) floor(mylog10(- ylims[0])); + tenpowmag = pow(10.0, (double) mag); + } else if (ylims[0] == 0.0) { + mag = (int) floor(mylog10(ylims[1])); + tenpowmag = pow(10.0, (double) mag); + } else { + diff = ylims[1] - ylims[0]; + mag = (int) floor(mylog10(diff)); + tenpowmag = pow(10.0, (double) mag); + } + + lmt = (int) floor(ylims[0] / tenpowmag); + yrange[0] = ylims[0] = lmt * tenpowmag; + hmt = (int) ceil(ylims[1] / tenpowmag); + yrange[1] = ylims[1] = hmt * tenpowmag; + + dst = hmt - lmt; + + /* This is a strange case; I don't know why it's here. */ + if (dst == 11) + dst = 12; + else if (dst == 1) { + dst = 10; + mag++; + hmt *= 10.0; + lmt *= 10.0; + } else if (dst == 0) { + dst = 2; + lmt -= 1; + hmt += 1; + } + + for (nsp = 4; nsp < 8; nsp++) + if (!(dst % nsp)) + break; + if (nsp == 8) + for (nsp = 2; nsp < 4; nsp++) + if (!(dst % nsp)) + break; + spacing = maxy / nsp; + + /* Reset the max X coordinate to deal with round-off error. */ + omaxy = maxy + 1; + maxy = spacing * nsp; + + for (i = 0, j = lmt; j <= hmt; i += spacing, j += dst / nsp) { + for (k = 0; k < maxx; k++) + field[k * omaxy + i] = LCHAR; + line1[i + margin + 2 * shift] = '|'; + (void) sprintf(buf, "%.2e", j * pow(10.0, (double) mag)); + bcopy(buf, &line2[i + margin - ((j < 0) ? 2 : 1) - shift], + strlen(buf)); + } + line1[i - spacing + margin + 1] = '\0'; + + for (i = 1; i < omargin - 1 && xscale->v_name[i - 1]; i++) + line2[i] = xscale->v_name[i - 1]; + if (!novalue) + for (i = omargin + 1; + i < margin - 2 && (vecs->v_name[i - omargin - 1]); + i++) + line2[i] = vecs->v_name[i - omargin - 1]; + + /* Now the buffers are all set up properly. Plot points for each + * vector using interpolation. For each point on the x-axis, find the + * two bracketing points in xscale, and then interpolate their + * y values for each vector. + */ + + upper = lower = 0; + for (i = 0; i < maxx; i++) { + if (nointerp) + x = isreal(xscale) ? xscale->v_realdata[i] : + realpart(&xscale->v_compdata[i]); + else if (xlog && xrange[0] > 0.0 && xrange[1] > 0.0) + x = xrange[0] * pow( 10.0, mylog10(xrange[1]/xrange[0]) + * i / (maxx - 1)); + else + x = xrange[0] + (xrange[1] - xrange[0]) * i / + (maxx - 1); + while ((isreal(xscale) ? (xscale->v_realdata[upper] < x) : + (realpart(&xscale->v_compdata[upper]) < x)) && + (upper < xscale->v_length - 1)) + upper++; + while ((isreal(xscale) ? (xscale->v_realdata[lower] < x) : + (realpart(&xscale->v_compdata[lower]) < x)) && + (lower < xscale->v_length - 1)) + lower++; + if ((isreal(xscale) ? (xscale->v_realdata[lower] > x) : + (realpart(&xscale->v_compdata[lower]) > x)) && + (lower > 0)) + lower--; + x1 = (isreal(xscale) ? xscale->v_realdata[lower] : + realpart(&xscale->v_compdata[lower])); + x2 = (isreal(xscale) ? xscale->v_realdata[upper] : + realpart(&xscale->v_compdata[upper])); + if (x1 > x2) { + fprintf(cp_err, "Error: X scale (%s) not monotonic\n", + xscale->v_name); + return; + } + for (v = vecs; v; v = v->v_link2) { + yy1 = (isreal(v) ? v->v_realdata[lower] : + realpart(&v->v_compdata[lower])); + y2 = (isreal(v) ? v->v_realdata[upper] : + realpart(&v->v_compdata[upper])); + if (x1 == x2) + y = yy1; + else + y = yy1 + (y2 - yy1) * (x - x1) / (x2 - x1); + if (!novalue && (v == vecs)) + values[i] = y; + ypt = ft_findpoint(y, yrange, maxy, 0, ylogscale); + c = field[omaxy * i + ypt]; + if ((c == ' ') || (c == LCHAR)) + field[omaxy * i + ypt] = (char) v->v_linestyle; + else + field[omaxy * i + ypt] = MCHAR; + } + } + + out_init(); + for (i = 0; i < omaxy + margin; i++) + out_send("-"); + out_send("\n"); + i = (omaxy + margin - strlen(plot->pl_title)) / 2; + while (i-- > 0) + out_send(" "); + (void) strcpy(buf, plot->pl_title); + buf[maxy + margin] = '\0'; /* Cut off if too wide */ + out_send(buf); + out_send("\n"); + (void) sprintf(buf, "%s %s", plot->pl_name, plot->pl_date); + buf[maxy + margin] = '\0'; + i = (omaxy + margin - strlen(buf)) / 2; + while (i-- > 0) + out_send(" "); + out_send(buf); + out_send("\n\n"); + curline = 7; + out_send("Legend: "); + i = 0; + j = (maxx + margin - 8) / 20; + if (j == 0) + j = 1; + for (v = vecs; v; v = v->v_link2) { + out_pbuf[0] = (char) v->v_linestyle; + out_pbuf[1] = '\0'; +/* out_printf("%c = %-17s", (char) v->v_linestyle, v->v_name); */ + out_printf("%s = %-17s", out_pbuf, v->v_name); + if (!(++i % j) && v->v_link2) { + out_send("\n "); + curline++; + } + } + out_send("\n"); + for (i = 0; i < omaxy + margin; i++) + out_send("-"); + out_send("\n"); + i = 0; + out_printf("%s\n%s\n", line2, line1); + curline += 2; + for (i = 0; i < maxx; i++) { + if (nointerp) + x = isreal(xscale) ? xscale->v_realdata[i] : + realpart(&xscale->v_compdata[i]); + else if (xlog && xrange[0] > 0.0 && xrange[1] > 0.0) + x = xrange[0] * pow( 10.0, mylog10(xrange[1]/xrange[0]) + * i / (maxx - 1)); + else + x = xrange[0] + (xrange[1] - xrange[0]) * i / (maxx - 1); + if (x < 0.0) { + sprintf(out_pbuf, "%.3e ", x); + out_send(out_pbuf); +/* out_printf("%.3e ", x); */ + } else { + sprintf(out_pbuf, " %.3e ", x); + out_send(out_pbuf); +/* out_printf(" %.3e ", x); */ + } + if (!novalue) { + if (values[i] < 0.0) { + sprintf(out_pbuf, "%.3e ", values[i]); + out_send(out_pbuf); +/* out_printf("%.3e ", values[i]); */ + } else { + sprintf(out_pbuf, " %.3e ", values[i]); + out_send(out_pbuf); +/* out_printf(" %.3e ", values[i]); */ + } + } + cb = field[(i + 1) * omaxy]; + field[(i + 1) * omaxy] = '\0'; + out_send(&field[i * omaxy]); + field[(i + 1) * omaxy] = cb; + out_send("\n"); + if (((curline++ % height) == 0) && (i < maxx - 1) && + !nobreakp) { + out_printf("%s\n%s\n\014\n%s\n%s\n", line1, line2, + line2, line1); + curline += 5; + } + } + out_printf("%s\n%s\n", line1, line2); + + tfree(field); + tfree(line1); + tfree(line2); + if (!novalue) + tfree(values); + return; +} diff --git a/src/frontend/plotting/agraf.h b/src/frontend/plotting/agraf.h new file mode 100644 index 000000000..c92b074de --- /dev/null +++ b/src/frontend/plotting/agraf.h @@ -0,0 +1,18 @@ +/************* + * Header file for agraf.c + * 1999 E. Rouat + ************/ + +#ifndef _AGRAF_H +#define _AGRAF_H + +#include +#include +#include + +void ft_agraf(double *xlims, double *ylims, struct dvec *xscale, + struct plot *plot, struct dvec *vecs, + double xdel, double ydel, bool xlog, bool ylog, + bool nointerp); + +#endif diff --git a/src/frontend/plotting/clip.c b/src/frontend/plotting/clip.c new file mode 100644 index 000000000..6e90e6106 --- /dev/null +++ b/src/frontend/plotting/clip.c @@ -0,0 +1,215 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1986 Wayne A. Christopyher, U. C. Berkeley CAD Group +Author: 1982 Giles Billingsley +**********/ + +/* + * Some routines to do clipping of polygons, etc to boxes. Most of this code + * was rescued from MFB: + * sccsid "@(#)mfbclip.c 1.2 12/21/83" + */ + +#include "ngspice.h" +#include "cpdefs.h" +#include "ftedefs.h" +#include "clip.h" + + +#define POLYGONBUFSIZE 512 +/* XXX */ + +#define CODEMINX 1 +#define CODEMINY 2 +#define CODEMAXX 4 +#define CODEMAXY 8 +#define CODE(x,y,c) c = 0;\ + if (x < l)\ + c = CODEMINX;\ + else if (x > r)\ + c = CODEMAXX;\ + if (y < b)\ + c |= CODEMINY;\ + else if (y > t)\ + c |= CODEMAXY; + + +#define SWAPINT(a, b) { int xxxx = (a); (a) = (b); (b) = xxxx; } + +/* clip_line will clip a line to a rectangular area. The returned + * value is 'TRUE' if the line is out of the AOI (therefore does not + * need to be displayed) and 'FALSE' if the line is in the AOI. + */ + +bool +clip_line(int *pX1, int *pY1, int *pX2, int *pY2, int l, int b, int r, int t) +{ + int x1 = *pX1; + int y1 = *pY1; + int x2 = *pX2; + int y2 = *pY2; + int x = 0, y = 0; + int c,c1,c2; + + CODE(x1,y1,c1) + CODE(x2,y2,c2) + while (c1 || c2) { + if (c1 & c2) + return (TRUE); /* Line is invisible. */ + if (!(c = c1)) + c = c2; + if (c & CODEMINX) { + y = y1+(y2-y1)*(l-x1)/(x2-x1); + x = l; + } else if (c & CODEMAXX) { + y = y1+(y2-y1)*(r-x1)/(x2-x1); + x = r; + } else if (c & CODEMINY) { + x = x1+(x2-x1)*(b-y1)/(y2-y1); + y = b; + } else if (c & CODEMAXY) { + x = x1+(x2-x1)*(t-y1)/(y2-y1); + y = t; + } + if (c == c1) { + x1 = x; + y1 = y; + CODE(x,y,c1) + } else { + x2 = x; + y2 = y; + CODE(x,y,c2) + } + } + *pX1 = x1; + *pY1 = y1; + *pX2 = x2; + *pY2 = y2; + return (FALSE); /* Line is at least partially visible.*/ +} + +/* This routine will clip a line to a circle, returning TRUE if the line + * is entirely outside the circle. Note that we have to be careful not + * to switch the points around, since in grid.c we need to know which is + * the outer point for putting the label on. + */ + +bool +clip_to_circle(int *x1, int *y1, int *x2, int *y2, int cx, int cy, int rad) +{ + double perplen, a, b, c; + double tx, ty, dt; + double dtheta; + double theta1, theta2, tt, alpha, beta, gamma; + bool flip = FALSE; + int i; + + /* Get the angles between the origin and the endpoints. */ + if ((*x1-cx) || (*y1-cy)) + theta1 = atan2((double) *y1 - cy, (double) *x1 - cx); + else + theta1 = M_PI; + if ((*x2-cx) || (*y2-cy)) + theta2 = atan2((double) *y2 - cy, (double) *x2 - cx); + else + theta2 = M_PI; + + if (theta1 < 0.0) + theta1 = 2 * M_PI + theta1; + if (theta2 < 0.0) + theta2 = 2 * M_PI + theta2; + + dtheta = theta2 - theta1; + if (dtheta > M_PI) + dtheta = dtheta - 2 * M_PI; + else if (dtheta < - M_PI) + dtheta = 2 * M_PI - dtheta; + + /* Make sure that p1 is the first point */ + if (dtheta < 0) { + tt = theta1; + theta1 = theta2; + theta2 = tt; + i = *x1; + *x1 = *x2; + *x2 = i; + i = *y1; + *y1 = *y2; + *y2 = i; + flip = TRUE; + dtheta = -dtheta; + } + + /* Figure out the distances between the points */ + a = sqrt((double) ((*x1 - cx) * (*x1 - cx) + (*y1 - cy) * (*y1 - cy))); + b = sqrt((double) ((*x2 - cx) * (*x2 - cx) + (*y2 - cy) * (*y2 - cy))); + c = sqrt((double) ((*x1 - *x2) * (*x1 - *x2) + + (*y1 - *y2) * (*y1 - *y2))); + + /* We have three cases now -- either the midpoint of the line is + * closest to the origon, or point 1 or point 2 is. Actually the + * midpoint won't in general be the closest, but if a point besides + * one of the endpoints is closest, the midpoint will be closer than + * both endpoints. + */ + tx = (*x1 + *x2) / 2; + ty = (*y1 + *y2) / 2; + dt = sqrt((double) ((tx - cx) * (tx - cx) + (ty - cy) * (ty - cy))); + if ((dt < a) && (dt < b)) { + /* This is wierd -- round-off errors I guess. */ + tt = (a * a + c * c - b * b) / (2 * a * c); + if (tt > 1.0) + tt = 1.0; + else if (tt < -1.0) + tt = -1.0; + alpha = acos(tt); + perplen = a * sin(alpha); + } else if (a < b) { + perplen = a; + } else { + perplen = b; + } + + /* Now we should see if the line is outside of the circle */ + if (perplen >= rad) + return (TRUE); + + /* It's at least partially inside */ + if (a > rad) { + tt = (a * a + c * c - b * b) / (2 * a * c); + if (tt > 1.0) + tt = 1.0; + else if (tt < -1.0) + tt = -1.0; + alpha = acos(tt); + gamma = asin(sin(alpha) * a / rad); + if (gamma < M_PI / 2) + gamma = M_PI - gamma; + beta = M_PI - alpha - gamma; + *x1 = cx + rad * cos(theta1 + beta); + *y1 = cy + rad * sin(theta1 + beta); + } + if (b > rad) { + tt = (c * c + b * b - a * a) / (2 * b * c); + if (tt > 1.0) + tt = 1.0; + else if (tt < -1.0) + tt = -1.0; + alpha = acos(tt); + gamma = asin(sin(alpha) * b / rad); + if (gamma < M_PI / 2) + gamma = M_PI - gamma; + beta = M_PI - alpha - gamma; + *x2 = cx + rad * cos(theta2 - beta); + *y2 = cy + rad * sin(theta2 - beta); + } + if (flip) { + i = *x1; + *x1 = *x2; + *x2 = i; + i = *y1; + *y1 = *y2; + *y2 = i; + } + return (FALSE); +} diff --git a/src/frontend/plotting/clip.h b/src/frontend/plotting/clip.h new file mode 100644 index 000000000..24fb3abbe --- /dev/null +++ b/src/frontend/plotting/clip.h @@ -0,0 +1,13 @@ +/************* + * Header file for clip.c + * 1999 E. Rouat + ************/ + +#ifndef CLIP_H_INCLUDED +#define CLIP_H_INCLUDED + + +bool clip_line(int *pX1, int *pY1, int *pX2, int *pY2, int l, int b, int r, int t); +bool clip_to_circle(int *x1, int *y1, int *x2, int *y2, int cx, int cy, int rad); + +#endif diff --git a/src/frontend/plotting/graf.c b/src/frontend/plotting/graf.c new file mode 100644 index 000000000..786b8b09c --- /dev/null +++ b/src/frontend/plotting/graf.c @@ -0,0 +1,1068 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Jeffrey M. Hsu +**********/ + +/* + * Most of the gr_ module resides here, in particular, gr_init + * and gr_point, expect for the gr_ grid routines. + * + */ + + +#include +#include "cpdefs.h" /* for VT_ */ +#include "cpextern.h" +#include +#include "ftedebug.h" /* for iplot */ +#include /* for struct dvec */ +#include "ftedefs.h" /* for FTEextern.h and IPOINT{MIN,MAX} */ +#include "fteinput.h" +#include +#include "ftedbgra.h" +#include "ftedev.h" +#include +#include +#include "../terminal.h" +#include "graf.h" + + +/* static declarations */ +static void gr_start_internal(struct dvec *dv, bool copyvec); +static int iplot(struct plot *pl, int id); +static void set(struct plot *plot, struct dbcomm *db, bool unset, int mode); +static char * getitright(char *buf, double num); + + +extern struct dbcomm *dbs; /* for iplot */ + +/* note: let's try to get rid of these */ +/* global variables */ +/* Graphics mode in progress, so signal handlers know to call gr_clean */ +/* bool gr_gmode = FALSE; */ + +/* for legends, set in gr_start, reset in gr_iplot and gr_init */ +static int plotno; +static int curcolor = 1; /* for assigning unique colors */ +static int curlst = 0; /* for assigning line styles */ + +/* invariant: currentgraph contains the current graph */ + +/* These are what gets plotted as points when you specify point plots */ +static char pointchars[128]; +#define DEFPOINTCHARS "oxabcdefhgijklmnpqrstuvwyz" + +/* Buffer for ticmarks if given a list */ +static char ticbuf[1024]; +static char *ticlist = ticbuf; +#define MAXTICS 100 +double *readtics(char *string); + +#define XFACTOR 2 /* How much to expand the X scale during iplot. */ +#define YFACTOR 1.5 /* How much to expand the Y scale during iplot. */ + +/* + * Start of a new graph. + * Fill in the data that gets displayed. + * Difference from old gr_init + * we don't try to determine the look of the screen from here + * leave to lower level routines + * + */ + +extern void SetGraphContext (int graphid); +extern void internalerror (char *message); +extern int NewViewport (GRAPH *pgraph); +extern void DevClear (void); +extern void gr_redrawgrid (GRAPH *graph); +extern void DatatoScreen (GRAPH *graph, double x, double y, int *screenx, int *screeny); +extern void SetLinestyle (int linestyleid); +extern void SetColor (int colorid); +extern void DrawLine (int x1, int y1, int x2, int y2); +extern void Text (char *text, int x, int y); +extern void SaveText (GRAPH *graph, char *text, int x, int y); +extern void Update (void); +extern void PushGraphContext (GRAPH *graph); +extern void PopGraphContext (void); +extern void Input (REQUEST *request, RESPONSE *response); +extern int DestroyGraph (int id); + +int +gr_init(double *xlims, double *ylims, /* The size of the screen. */ + char *xname, char *plotname, /* What to label things. */ + char *hcopy, /* The raster file. */ + int nplots, /* How many plots there will be. */ + double xdelta, double ydelta, /* Line increments for the scale. */ + GRIDTYPE gridtype, /* The grid type */ + PLOTTYPE plottype, /* and the plot type. */ + char *xlabel, char *ylabel, /* Labels for axes. */ + int xtype, int ytype, /* The types of the data graphed. */ + char *pname, + char *commandline) /* For xi_zoomdata() */ +{ + + GRAPH *graph; + int b; + wordlist *wl; + char *comb_title; + + + if (!(graph = NewGraph())) { + return(FALSE); + } + + /* + The global currentgraph will always be the current graph. + */ + SetGraphContext(graph->graphid); + + graph->onevalue = (xname ? FALSE : TRUE); + + /* communicate filename to plot 5 driver */ + if (hcopy) { + graph->devdep = hcopy; + } + + plotno = 0; + + /* note: should do only once, maybe in gr_init_once */ + if (!cp_getvar("pointchars", VT_STRING, pointchars)) + (void) strcpy(pointchars, DEFPOINTCHARS); + + if (!cp_getvar("ticmarks", VT_NUM, (char *) &graph->ticmarks)) { + if (cp_getvar("ticmarks", VT_BOOL, (char *) &b)) + graph->ticmarks = 10; + else + graph->ticmarks = 0; + } + + if (cp_getvar("ticlist", VT_LIST, ticlist)) { + wl = (wordlist *)vareval("ticlist"); + ticlist = (char *)wl_flatten(wl); + graph->ticdata = (double *) readtics(ticlist); + } else + graph->ticdata = NULL; + + if (!xlims || !ylims) { + internalerror("gr_init: no range specified"); + return(FALSE); + } + + /* save upper and lower limits */ + graph->data.xmin = xlims[0]; + graph->data.xmax = xlims[1]; + graph->data.ymin = ylims[0]; + graph->data.ymax = ylims[1]; + + /* note: have enum here or some better convention */ + if (NewViewport(graph) == 1) { + /* note: where is the error message generated? */ + /* note: undo tmallocs */ + fprintf(cp_err, "Can't open viewport for graphics.\n"); + return(FALSE); + } + + /* layout decisions */ + /* note: have to do before gr_fixgrid and after NewViewport */ + graph->viewportxoff = graph->fontwidth * 8; /* 8 lines on left */ + graph->viewportyoff = graph->fontheight * 4; /* 4 on bottom */ + + DevClear(); + + graph->grid.gridtype = gridtype; + graph->plottype = plottype; + graph->grid.xdatatype = xtype; + graph->grid.ydatatype = ytype; + graph->grid.xdelta = xdelta; + graph->grid.ydelta = ydelta; + graph->grid.ysized = 0; + graph->grid.xsized = 0; + + if (!graph->onevalue) { + if (xlabel) { + graph->grid.xlabel = xlabel; + } else { + graph->grid.xlabel = xname; + } + if (ylabel) { + graph->grid.ylabel = ylabel; + } + } else { + if (xlabel) { + graph->grid.xlabel = xlabel; + } else { + graph->grid.xlabel = "real"; + } + if (ylabel) { + graph->grid.ylabel = ylabel; + } else { + graph->grid.ylabel = "imag"; + } + } + + if (!pname) + pname = "(unknown)"; + if (!plotname) + plotname = "(unknown)"; + comb_title = tmalloc(strlen(plotname) + strlen(pname) + 3); + sprintf(comb_title, "%s: %s", pname, plotname); + graph->plotname = comb_title; + + gr_resize_internal(graph); + gr_redrawgrid(graph); + + /* Set up colors and line styles. */ + if (dispdev->numlinestyles == 1) + curlst = 0; /* Use the same one all the time. */ + else + curlst = 1; + /* XXX Special exception for SMITH */ + if (dispdev->numcolors > 2 && (graph->grid.gridtype == GRID_SMITH + || graph->grid.gridtype == GRID_SMITHGRID)) + { + curcolor = 3; + } else + curcolor = 1; + + graph->commandline = copy(commandline); + + return(TRUE); + +} + +/* + * Add a point to the curve we're currently drawing. + * Should be in between a gr_init() and a gr_end() + * expect when iplotting, very bad hack + * Differences from old gr_point: + * We save points here, instead of in lower levels. + * Assume we are in right context + * Save points in data space (not screen space). + * We pass two points in so we can multiplex plots. + * + */ +void +gr_point(struct dvec *dv, + double newx, double newy, + double oldx, double oldy, + int np) +{ + int oldtox, oldtoy; /* value before clipping */ + + char pointc[2]; + + int fromx, fromy, tox, toy; + int ymin, dummy; + + DatatoScreen(currentgraph, oldx, oldy, &fromx, &fromy); + DatatoScreen(currentgraph, newx, newy, &tox, &toy); + + /* note: we do not particularly want to clip here */ + oldtox = tox; oldtoy = toy; + if (!currentgraph->grid.circular) { + if (clip_line(&fromx, &fromy, &tox, &toy, + currentgraph->viewportxoff, currentgraph->viewportyoff, + currentgraph->viewport.width + currentgraph->viewportxoff, + currentgraph->viewport.height + currentgraph->viewportyoff)) + return; + } else { + if (clip_to_circle(&fromx, &fromy, &tox, &toy, + currentgraph->grid.xaxis.circular.center, + currentgraph->grid.yaxis.circular.center, + currentgraph->grid.xaxis.circular.radius)) + return; + } + + if (currentgraph->plottype != PLOT_POINT) { + SetLinestyle(dv->v_linestyle); + } else { + /* if PLOT_POINT, + don't want to plot an endpoint which have been clipped */ + if (tox != oldtox || toy != oldtoy) + return; + } + SetColor(dv->v_color); + + switch (currentgraph->plottype) { + double *tics; + case PLOT_LIN: + + /* If it's a linear plot, ignore first point since we don't + want to connect with oldx and oldy. */ + if (np) + DrawLine(fromx, fromy, tox, toy); + if ((tics = (double *) currentgraph->ticdata)) { + for (; *tics < HUGE; tics++) { + if (*tics == (double) np) { + Text("x", (int) (tox - currentgraph->fontwidth / 2), + (int) (toy - currentgraph->fontheight / 2)); + /* gr_redraw will redraw this w/o our having to save it + Guenther Roehrich 22-Jan-99 */ + /* SaveText(currentgraph, "x", + (int) (tox - currentgraph->fontwidth / 2), + (int) (toy - currentgraph->fontheight / 2)); */ + break; + } + } + } else if ((currentgraph->ticmarks >0) && (np > 0) + && (np % currentgraph->ticmarks == 0)) + { + /* Draw an 'x' */ + Text("x", (int) (tox - currentgraph->fontwidth / 2), + (int) (toy - currentgraph->fontheight / 2)); + /* gr_redraw will redraw this w/o our having to save it + Guenther Roehrich 22-Jan-99 */ + /* SaveText(currentgraph, "x", + (int) (tox - currentgraph->fontwidth / 2), + (int) (toy - currentgraph->fontheight / 2)); */ + } + break; + case PLOT_COMB: + DatatoScreen(currentgraph, + (double) 0, currentgraph->datawindow.ymin, + &dummy, &ymin); + DrawLine(tox, ymin, tox, toy); + break; + case PLOT_POINT: + /* Here, gi_linestyle is the character used for the point. */ + pointc[0] = dv->v_linestyle; + pointc[1] = '\0'; + Text(pointc, (int) (tox - currentgraph->fontwidth / 2), + (int) (toy - currentgraph->fontheight / 2)); + default: + break; + } + +} + +static void +gr_start_internal(struct dvec *dv, bool copyvec) +{ + + struct dveclist *link; + char *s; + + /* Do something special with poles and zeros. Poles are 'x's, and + * zeros are 'o's. */ + s = ft_typenames(dv->v_type); + if (eq(s, "pole")) { + dv->v_linestyle = 'x'; + return; + } else if (eq(s, "zero")) { + dv->v_linestyle = 'o'; + return; + } + + /* Find a (hopefully) new line style and color. */ + if (currentgraph->plottype == PLOT_POINT) { + if (pointchars[curlst - 1]) + curlst++; + else + curlst = 2; + } else if ((curlst > 0) && (++curlst == dispdev->numlinestyles)) + curlst = 2; + if ((curcolor > 0) && (++curcolor == dispdev->numcolors)) + curcolor = (((currentgraph->grid.gridtype == GRID_SMITH + || currentgraph->grid.gridtype == GRID_SMITHGRID) && + (dispdev->numcolors > 3)) ? 4 : 2); + if (currentgraph->plottype == PLOT_POINT) + dv->v_linestyle = pointchars[curlst - 2]; + else + dv->v_linestyle = curlst; + dv->v_color = curcolor; + + /* save the data so we can refresh */ + link = (struct dveclist *) tmalloc(sizeof(struct dveclist)); + link->next = currentgraph->plotdata; + + if (copyvec) { + link->vector = vec_copy(dv); + /* vec_copy doesn't set v_color or v_linestyle */ + link->vector->v_color = dv->v_color; + link->vector->v_linestyle = dv->v_linestyle; + link->vector->v_flags |= VF_PERMANENT; + } else { + link->vector = dv; + } + + currentgraph->plotdata = link; + + /* Put the legend entry on the screen. */ + drawlegend(currentgraph, plotno, dv); + + plotno++; + +} + +/* start one plot of a graph */ +void +gr_start(struct dvec *dv) +{ + + gr_start_internal(dv, TRUE); + +} + +/* make sure the linestyles in this graph don't exceed the number of + linestyles available in the current display device */ +void +gr_relinestyle(GRAPH *graph) +{ + + struct dveclist *link; + + for (link = graph->plotdata; link; link = link->next) { + if (graph->plottype == PLOT_POINT) continue; + if (!(link->vector->v_linestyle < dispdev->numlinestyles)) { + link->vector->v_linestyle %= dispdev->numlinestyles; + } + if (!(link->vector->v_color < dispdev->numcolors)) { + link->vector->v_color %= dispdev->numcolors; + } + } + +} + + /* PN static */ +void +drawlegend(GRAPH *graph, int plotno, struct dvec *dv) +{ + + int x, y, i; + char buf[16]; + + x = ((plotno % 2) ? graph->viewportxoff : + ((graph->viewport.width) / 2)); + y = graph->absolute.height - graph->fontheight + - ((plotno + 2) / 2) * (graph->fontheight); + i = y + graph->fontheight / 2 + 1; + SetColor(dv->v_color); + if (graph->plottype == PLOT_POINT) { + (void) sprintf(buf, "%c : ", dv->v_linestyle); + Text(buf, x + graph->viewport.width / 20 + - 3 * graph->fontwidth, y); + } else { + SetLinestyle(dv->v_linestyle); + DrawLine(x, i, x + graph->viewport.width / 20, i); + } + SetColor(1); + Text(dv->v_name, x + graph->viewport.width / 20 + + graph->fontwidth, y); + +} + +/* end one plot of a graph */ +void +gr_end(struct dvec *dv) +{ + Update(); +} + +/* Print text in the bottom line. */ + +void +gr_pmsg(char *text) +{ + char buf[BSIZE_SP]; + buf[0] = 0; + + Update(); + + if (cp_getvar("device", VT_STRING, buf) + && !(strcmp("/dev/tty", buf) == 0)) + fprintf(cp_err, "%s", text); + else + + /* MW. grid.xlabel may be NULL */ + if (currentgraph->grid.xlabel) + Text(text, currentgraph->viewport.width + - (strlen(currentgraph->grid.xlabel) + 3) + * currentgraph->fontwidth, + currentgraph->absolute.height - currentgraph->fontheight); + else + fprintf(cp_err, " %s \n", text); + + Update(); + return; +} + +void +gr_clean(void) +{ + Update(); + return; +} + +/* call this routine after viewport size changes */ +void +gr_resize(GRAPH *graph) +{ + + double oldxratio, oldyratio; + double scalex, scaley; + struct _keyed *k; + + oldxratio = graph->aspectratiox; + oldyratio = graph->aspectratioy; + + graph->grid.xsized = 0; + graph->grid.ysized = 0; + + gr_resize_internal(graph); + + /* scale keyed text */ + scalex = oldxratio / graph->aspectratiox; + scaley = oldyratio / graph->aspectratioy; + for (k = graph->keyed; k; k = k->next) { + k->x = (k->x - graph->viewportxoff) * scalex + graph->viewportxoff; + k->y = (k->y - graph->viewportyoff) * scaley + graph->viewportyoff; + } + + /* X also generates an expose after a resize. + + This is handled in X10 by not redrawing on resizes and waiting + for the expose event to redraw. In X11, the expose routine + tries to be clever and only redraws the region specified in an + expose event, which does not cover the entire region of the + plot if the resize was from a small window to a larger window. + So in order to keep the clever X11 expose event handling, we + have the X11 resize routine pull out expose events for that + window, and we redraw on resize also. */ +#ifdef X_DISPLAY_MISSING + gr_redraw(graph); +#endif + +} + +/* PN static */ +void +gr_resize_internal(GRAPH *graph) +{ + + if (!graph->grid.xsized) + graph->viewport.width = graph->absolute.width - + 1.4 * graph->viewportxoff; + if (!graph->grid.ysized) + graph->viewport.height = graph->absolute.height - + 2 * graph->viewportyoff; + + gr_fixgrid(graph, graph->grid.xdelta, graph->grid.ydelta, + graph->grid.xdatatype, graph->grid.ydatatype); + + /* cache width and height info to make DatatoScreen go fast */ + /* note: XXX see if this is actually used anywhere */ + graph->datawindow.width = graph->datawindow.xmax - + graph->datawindow.xmin; + graph->datawindow.height = graph->datawindow.ymax - + graph->datawindow.ymin; + + /* cache (datawindow size) / (viewport size) */ + graph->aspectratiox = graph->datawindow.width / graph->viewport.width; + graph->aspectratioy = graph->datawindow.height / graph->viewport.height; + +} + +/* redraw everything in struct graph */ +void +gr_redraw(GRAPH *graph) +{ + + struct dveclist *link; + + /* establish current graph so default graphic calls will work right */ + PushGraphContext(graph); + + DevClear(); + + /* redraw grid */ + gr_redrawgrid(graph); + + for (link=graph->plotdata, plotno = 0; link; + link = link->next, plotno++) { + /* redraw legend */ + drawlegend(graph, plotno, link->vector); + + /* replot data + if onevalue, pass it a NULL scale + otherwise, if vec has its own scale, pass that + else pass vec's plot's scale + */ + ft_graf(link->vector, + graph->onevalue ? (struct dvec *) NULL : + (link->vector->v_scale ? + link->vector->v_scale : + link->vector->v_plot->pl_scale), + TRUE); + } + + gr_restoretext(graph); + + PopGraphContext(); + +} + +void +gr_restoretext(GRAPH *graph) +{ + + struct _keyed *k; + + /* restore text */ + for (k=graph->keyed; k; k = k->next) { + SetColor(k->colorindex); + Text(k->text, k->x, k->y); + } + +} + +/* Do some incremental plotting. There are 3 cases: + * + * First, if length < IPOINTMIN, don't do anything. + * + * Second, if length = IPOINTMIN, plot what we have so far. + * + * Third, if length > IPOINTMIN, plot the last points and resize if + * needed. + * + * Note we don't check for pole / zero because they are of length 1. + * + * FIXME: there is a problem with multiple iplots that use the same + * vector, namely, that vector has the same color throughout. This is + * another reason why we need to pull color and linestyle out of dvec + * XXX Or maybe even something more drastic ?? */ + +extern bool resumption; + +static int +iplot(struct plot *pl, int id) +{ + int len = pl->pl_scale->v_length; + struct dvec *v, *xs = pl->pl_scale; + double *lims, dy; + double start, stop, step; + register int j; + bool changed = FALSE; + int yt; + char *yl = NULL; + double xlims[2], ylims[2]; + static REQUEST reqst = { checkup_option, 0 }; + int inited = 0; + char commandline[513]; + + for (j = 0, v = pl->pl_dvecs; v; v = v->v_next) + if (v->v_flags & VF_PLOT) + j++; + if (!j) + return(0); + if (ft_grdb) + fprintf(cp_err, "Entering iplot, len = %d\n\r", len); + + if (len < IPOINTMIN) { + /* Nothing yet */ + return(0); + } else if (len == IPOINTMIN || !id) { + resumption = FALSE; + /* Draw the grid for the first time, and plot everything. */ + lims = ft_minmax(xs, TRUE); + xlims[0] = lims[0]; + xlims[1] = lims[1]; + ylims[0] = HUGE; + ylims[1] = - ylims[0]; + for (v = pl->pl_dvecs; v; v = v->v_next) + if (v->v_flags & VF_PLOT) { + lims = ft_minmax(v, TRUE); + if (lims[0] < ylims[0]) + ylims[0] = lims[0]; + if (lims[1] > ylims[1]) + ylims[1] = lims[1]; + if (!yl) + yl = v->v_name; + } + if (ft_grdb) + fprintf(cp_err, + "iplot: after 5, xlims = %G, %G, ylims = %G, %G\n\r", + xlims[0], + xlims[1], + ylims[0], + ylims[1]); + for (yt = pl->pl_dvecs->v_type, v = pl->pl_dvecs->v_next; v; + v = v->v_next) + if ((v->v_flags & VF_PLOT) && (v->v_type != yt)) { + yt = 0; + break; + } + + /* note: have command options for iplot to specify xdelta, + etc. So don't need static variables hack. Assume default + values for now. */ + sprintf(commandline, "iplot %s", xs->v_name); + + (void) gr_init(xlims, ylims, xs->v_name, + pl->pl_title, (char *) NULL, j, 0.0, 0.0, + GRID_LIN, PLOT_LIN, xs->v_name, yl, xs->v_type, yt, + plot_cur->pl_typename, commandline); + for (v = pl->pl_dvecs; v; v = v->v_next) + if (v->v_flags & VF_PLOT) { + gr_start_internal(v, FALSE); + ft_graf(v, xs, TRUE); + } + inited = 1; + } else { + Input(&reqst, 0); + /* First see if we have to make the screen bigger */ + dy = (isreal(xs) ? xs->v_realdata[len - 1] : + realpart(&xs->v_compdata[len - 1])); + if (ft_grdb) + fprintf(cp_err, "x = %G\n\r", dy); + if (!if_tranparams(ft_curckt, &start, &stop, &step) || + !ciprefix("tran", pl->pl_typename)) { + stop = HUGE; + start = - stop; + } + while (dy < currentgraph->data.xmin) { + changed = TRUE; + if (ft_grdb) + fprintf(cp_err, "resize: xlo %G -> %G\n\r", + currentgraph->data.xmin, + currentgraph->data.xmin - + (currentgraph->data.xmax - + currentgraph->data.xmin) + * XFACTOR); + currentgraph->data.xmin -= + (currentgraph->data.xmax - + currentgraph->data.xmin) + * XFACTOR; + if (currentgraph->data.xmin < start) { + currentgraph->data.xmin = start; + break; + } + } + if (currentgraph->data.xmax < + currentgraph->data.xmin) + currentgraph->data.xmax = + currentgraph->data.xmin; + while (dy > currentgraph->data.xmax) { + changed = TRUE; + if (ft_grdb) + fprintf(cp_err, "resize: xhi %G -> %G\n\r", + currentgraph->data.xmax, + currentgraph->data.xmax + + (currentgraph->data.xmax - + currentgraph->data.xmin) * XFACTOR); + currentgraph->data.xmax += + (currentgraph->data.xmax - + currentgraph->data.xmin) * + XFACTOR; + if (currentgraph->data.xmax > stop) { + currentgraph->data.xmax = stop; + break; + } + } + for (v = pl->pl_dvecs; v; v = v->v_next) { + if (!(v->v_flags & VF_PLOT)) + continue; + dy = (isreal(v) ? v->v_realdata[len - 1] : + realpart(&v->v_compdata[len - 1])); + if (ft_grdb) + fprintf(cp_err, "y = %G\n\r", dy); + while (dy < currentgraph->data.ymin) { + changed = TRUE; + if (ft_grdb) + fprintf(cp_err, "resize: ylo %G -> %G\n\r", + currentgraph->data.ymin, + currentgraph->data.ymin - + (currentgraph->data.ymax - + currentgraph->data.ymin) * YFACTOR); + currentgraph->data.ymin -= + (currentgraph->data.ymax - + currentgraph->data.ymin) * YFACTOR; + } + if (currentgraph->data.ymax < + currentgraph->data.ymin) + currentgraph->data.ymax = + currentgraph->data.ymin; + while (dy > currentgraph->data.ymax) { + changed = TRUE; + if (ft_grdb) + fprintf(cp_err, "resize: yhi %G -> %G\n\r", + currentgraph->data.ymax, + currentgraph->data.ymax + + (currentgraph->data.ymax - + currentgraph->data.ymin) * YFACTOR); + currentgraph->data.ymax += + (currentgraph->data.ymax - + currentgraph->data.ymin) * YFACTOR; + } + } + if (changed) { + /* Redraw everything. */ + gr_pmsg("Resizing screen"); + gr_resize(currentgraph); + gr_redraw(currentgraph); + } else { + /* Just connect the last two points. This won't be done + * with curve interpolation, so it might look funny. */ + for (v = pl->pl_dvecs; v; v = v->v_next) + if (v->v_flags & VF_PLOT) { + gr_point(v, + (isreal(xs) ? xs->v_realdata[len - 1] : + realpart(&xs->v_compdata[len - 1])), + (isreal(v) ? v->v_realdata[len - 1] : + realpart(&v->v_compdata[len - 1])), + (isreal(xs) ? xs->v_realdata[len - 2] : + realpart(&xs->v_compdata[len - 2])), + (isreal(v) ? v->v_realdata[len - 2] : + realpart(&v->v_compdata[len - 2])), + len - 1); + } + } + } + Update(); + return(inited); +} + +static void +set(struct plot *plot, struct dbcomm *db, bool unset, int mode) +{ + + struct dvec *v; + struct dbcomm *dc; + + if (db->db_type == DB_IPLOTALL || db->db_type == DB_TRACEALL) { + for (v = plot->pl_dvecs; v; v = v->v_next) { + if (unset) + v->v_flags &= ~mode; + else + v->v_flags |= mode; + } + return; + } + for (dc = db; dc; dc = dc->db_also) { + v = vec_fromplot(dc->db_nodename1, plot); + if (!v || v->v_plot != plot) { + if (!eq(dc->db_nodename1, "0") && !unset) { + fprintf(cp_err, "Warning: node %s non-existent in %s.\n", + dc->db_nodename1, plot->pl_name); + /* note: XXX remove it from dbs, so won't get further errors */ + } + continue; + } + if (unset) + v->v_flags &= ~mode; + else + v->v_flags |= mode; + } + return; +} + +static char * +getitright(char *buf, double num) +{ + char *p; + int k; + + sprintf(buf, " % .5g", num); + p =strchr(buf, '.'); + + if (p) { + return p - 4; + } else { + k = strlen(buf); + if (k > 8) + return buf + 4; + else /* k >= 4 */ + return buf + k - 4; + } +} + +static int hit, hit2; + +void reset_trace(void) +{ + hit = -1; + hit2 = -1; +} + +void +gr_iplot(struct plot *plot) +{ + + struct dbcomm *db; + int dontpop; /* So we don't pop w/o push. */ + char buf[30]; + + hit = 0; + for (db = dbs; db; db = db->db_next) { + if (db->db_type == DB_IPLOT || db->db_type == DB_IPLOTALL) { + + if (db->db_graphid) PushGraphContext(FindGraph(db->db_graphid)); + + set(plot, db, FALSE, VF_PLOT); + + dontpop = 0; + if (iplot(plot, db->db_graphid)) { + /* graph just assigned */ + db->db_graphid = currentgraph->graphid; + dontpop = 1; + } + + set(plot, db, TRUE, VF_PLOT); + + if (!dontpop && db->db_graphid) PopGraphContext(); + + } else if (db->db_type == DB_TRACENODE || db->db_type == DB_TRACEALL) { + + struct dvec *v, *u; + int len; + + set(plot, db, FALSE, VF_PRINT); + + len = plot->pl_scale->v_length; + + dontpop = 0; + for (v = plot->pl_dvecs; v; v = v->v_next) { + if (v->v_flags & VF_PRINT) { + u = plot->pl_scale; + if (len <= 1 || hit <= 0 || hit2 < 0) { + if (len <= 1 || hit2 < 0) + term_clear( ); + else + term_home( ); + hit = 1; + hit2 = 1; + printf( + "\tExecution trace (remove with the \"delete\" command)"); + term_cleol( ); + printf("\n"); + + if (u) { + printf("%12s:", u->v_name); + if (isreal(u)) { + printf("%s", + getitright(buf, u->v_realdata[len - 1])); + } else { + + /* MW. Complex data here, realdata is NULL + (why someone use realdata here again) */ + printf("%s", + getitright(buf, u->v_compdata[len - 1].cx_real)); + printf(", %s", + getitright(buf, u->v_compdata[len - 1].cx_imag)); + } + term_cleol( ); + printf("\n"); + } + } + if (v == u) + continue; + printf("%12s:", v->v_name); + if (isreal(v)) { + printf("%s", getitright(buf, v->v_realdata[len - 1])); + } else { + + /* MW. Complex data again */ + printf("%s", getitright(buf, v->v_compdata[len - 1].cx_real)); + printf(", %s", getitright(buf, v->v_compdata[len - 1].cx_imag)); + } + term_cleol( ); + printf("\n"); + } + } + set(plot, db, TRUE, VF_PRINT); + + } + + } + +} + +/* This gets called after iplotting is done. We clear out the + * db_graphid fields. Copy the dvecs, which we referenced by + * reference, so DestroyGraph gets to free its own copy. + * + * Note: This is a clear case for separating the linestyle and color + * fields from dvec. */ + +void +gr_end_iplot(void) +{ + + struct dbcomm *db, *prev, *next; + GRAPH *graph; + struct dveclist *link; + struct dvec *dv; + + prev = NULL; + for (db = dbs; db; prev = db, db = next) { + next = db->db_next; + if (db->db_type == DB_DEADIPLOT) { + if (db->db_graphid) { + DestroyGraph(db->db_graphid); + if (prev) + prev->db_next = next; + else + dbs = next; + dbfree(db); + } + } else if (db->db_type == DB_IPLOT || db->db_type == DB_IPLOTALL) { + if (db->db_graphid) { + + /* get private copy of dvecs */ + graph = FindGraph(db->db_graphid); + + link = graph->plotdata; + + while (link) { + dv = link->vector; + link->vector = vec_copy(dv); + /* vec_copy doesn't set v_color or v_linestyle */ + link->vector->v_color = dv->v_color; + link->vector->v_linestyle = dv->v_linestyle; + link->vector->v_flags |= VF_PERMANENT; + link = link->next; + } + + db->db_graphid = 0; + } else { + /* warn that this wasn't plotted */ + fprintf(cp_err, "Warning: iplot %d was not executed.\n", + db->db_number); + } + } + } + + + return; +} + +double * +readtics(char *string) +{ + int i, k; + char *words, *worde; + double *tics, *ticsk; + + tics = (double *) tmalloc(MAXTICS * sizeof(double)); + ticsk = tics; + words = string; + + for (i = k = 0; *words && k < MAXTICS; words = worde) { + + while (isspace(*words)) + words++; + + worde = words; + while (isalpha(*worde) || isdigit(*worde)) + worde++; + + if (*worde) + *worde++ = '\0'; + + sscanf(words, "%lf", ticsk++); + + k++; + + } + *ticsk = HUGE; + return(tics); +} diff --git a/src/frontend/plotting/graf.h b/src/frontend/plotting/graf.h new file mode 100644 index 000000000..54c7342a0 --- /dev/null +++ b/src/frontend/plotting/graf.h @@ -0,0 +1,37 @@ +/************* + * Header file for graf.c + * 1999 E. Rouat + ************/ + +#ifndef _GRAF_H +#define _GRAF_H + +int gr_init(double *xlims, double *ylims, + char *xname, char *plotname, + char *hcopy, + int nplots, + double xdelta, double ydelta, + GRIDTYPE gridtype, + PLOTTYPE plottype, + char *xlabel, char *ylabel, + int xtype, int ytype, + char *pname, char *commandline); +void gr_point(struct dvec *dv, + double newx, double newy, + double oldx, double oldy, int np); +void gr_start(struct dvec *dv); +void gr_relinestyle(GRAPH *graph); +void drawlegend(GRAPH *graph, int plotno, struct dvec *dv); +void gr_end(struct dvec *dv); +void gr_pmsg(char *text); +void gr_clean(void); +void gr_resize(GRAPH *graph); +void gr_resize_internal(GRAPH *graph); +void gr_redraw(GRAPH *graph); +void gr_restoretext(GRAPH *graph); +void reset_trace(void); +void gr_iplot(struct plot *plot); +void gr_end_iplot(void); +double * readtics(char *string); + +#endif diff --git a/src/frontend/plotting/graphdb.c b/src/frontend/plotting/graphdb.c new file mode 100644 index 000000000..bf2e5b848 --- /dev/null +++ b/src/frontend/plotting/graphdb.c @@ -0,0 +1,283 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +**********/ + +/* + Manage graph data structure. +*/ + +#include +#include +#include +#include + +#include "graphdb.h" + + + +/* invariant: currentgraph contains the current graph */ +GRAPH *currentgraph; + +/* + * We use a linked list rather than a circular one because we + * expect few links per list and we don't need to add at the + * end of a list (we can add at the beginning). + */ + +/* linked list of graphs */ +typedef struct listgraph { + /* we use GRAPH here instead of a pointer to save a tmalloc */ + GRAPH graph; + struct listgraph *next; +} LISTGRAPH; +#define NEWLISTGRAPH (LISTGRAPH *) tmalloc(sizeof(LISTGRAPH)) + +#define NUMGBUCKETS 16 + +typedef struct gbucket { + LISTGRAPH *list; +} GBUCKET; + +static GBUCKET GBucket[NUMGBUCKETS]; + +/* note: Zero is not a valid id. This is used in plot() in graf.c. */ +static int RunningId = 1; + +/* initialize graph structure */ +#define SETGRAPH(pgraph, id) (pgraph)->graphid = (id); \ + (pgraph)->degree = 1; \ + (pgraph)->linestyle = -1 + +/* returns NULL on error */ + +extern void internalerror (char *message); +extern void SaveText (GRAPH *graph, char *text, int x, int y); + +GRAPH *NewGraph(void) +{ + + GRAPH *pgraph; + LISTGRAPH *list; + int BucketId = RunningId % NUMGBUCKETS; + + if (!(list = NEWLISTGRAPH)) { + internalerror("can't allocate a listgraph"); + return((GRAPH *) NULL); + } + + pgraph = &list->graph; + SETGRAPH(pgraph, RunningId); + + if (!GBucket[BucketId].list) { + GBucket[BucketId].list = list; + } else { + /* insert at front of current list */ + list->next = GBucket[BucketId].list; + GBucket[BucketId].list = list; + } + + RunningId++ ; + + return(pgraph); + +} + +/* Given graph id, return graph */ +GRAPH *FindGraph(int id) +{ + + LISTGRAPH *list; + + for (list = GBucket[id % NUMGBUCKETS].list; + list && list->graph.graphid != id; + list = list->next) + + ; + + if (list) + return(&list->graph); + else + return(NULL); + +} + +GRAPH *CopyGraph(GRAPH *graph) +{ + + GRAPH *ret; + struct _keyed *k; + struct dveclist *link, *newlink; + + ret = NewGraph(); + bcopy(graph, ret, sizeof(struct graph)); + + ret->graphid = RunningId - 1; /* restore id */ + + /* copy keyed */ + for (ret->keyed = NULL, k = graph->keyed; k; k = k->next) { + SaveText(ret, k->text, k->x, k->y); + } + + /* copy dvecs */ + ret->plotdata = NULL; + for (link = graph->plotdata; link; link = link->next) { + newlink = (struct dveclist *) tmalloc(sizeof(struct dveclist)); + newlink->next = ret->plotdata; + newlink->vector = vec_copy(link->vector); + /* vec_copy doesn't set v_color or v_linestyle */ + newlink->vector->v_color = link->vector->v_color; + newlink->vector->v_linestyle = link->vector->v_linestyle; + newlink->vector->v_flags |= VF_PERMANENT; + ret->plotdata = newlink; + } + + ret->commandline = copy(graph->commandline); + ret->plotname = copy(graph->plotname); + + return(ret); + +} + +int +DestroyGraph(int id) +{ + + LISTGRAPH *list, *lastlist; + struct _keyed *k, *nextk; + struct dveclist *d, *nextd; + extern struct dbcomm *dbs; + struct dbcomm *db; + + list = GBucket[id % NUMGBUCKETS].list; + lastlist = NULL; + while (list) { + if (list->graph.graphid == id) { /* found it */ + + /* Fix the iplot/trace dbs list */ + for (db = dbs; db && db->db_graphid != id; db = db->db_next) + ; + + if (db && (db->db_type == DB_IPLOT + || db->db_type == DB_IPLOTALL)) { + db->db_type = DB_DEADIPLOT; + /* Delete this later */ + return(0); + } + + /* adjust bucket pointers */ + if (lastlist) { + lastlist->next = list->next; + } else { + GBucket[id % NUMGBUCKETS].list = list->next; + } + + /* run through and de-allocate dynamically allocated keyed list */ + k=list->graph.keyed; + while (k) { + nextk = k->next; + tfree(k->text); + tfree(k); + k = nextk; + } + + /* de-allocate dveclist */ + d = list->graph.plotdata; + while (d) { + nextd = d->next; + tfree(d->vector->v_name); + if (isreal(d->vector)) { + tfree(d->vector->v_realdata); + } else { + tfree(d->vector->v_compdata); + } + tfree(d->vector); + tfree(d); + d = nextd; + } + + tfree(list->graph.commandline); + tfree(list->graph.plotname); + + /* If device dependent space allocated, free it. */ + if (list->graph.devdep) + tfree(list->graph.devdep); + tfree(list); + + return(1); + } + lastlist = list; + list = list->next; + } + + internalerror("tried to destroy non-existent graph"); + return (0); + +} + +/* free up all dynamically allocated data structures */ +void +FreeGraphs(void) +{ + + GBUCKET *gbucket; + LISTGRAPH *list, *deadl; + + for (gbucket = GBucket; gbucket < &GBucket[NUMGBUCKETS]; gbucket++) { + list = gbucket->list; + while (list) { + deadl = list; + list = list->next; + tfree(deadl); + } + } + +} + +void +SetGraphContext(int graphid) +{ + + currentgraph = FindGraph(graphid); + +} + +typedef struct gcstack { + GRAPH *pgraph; + struct gcstack *next; +} GCSTACK; +GCSTACK *gcstacktop; +#define NEWGCSTACK (GCSTACK *) tmalloc(sizeof(GCSTACK)) + +/* note: This Push and Pop has tricky semantics. + Push(graph) will push the currentgraph onto the stack + and set currentgraph to graph. + Pop() simply sets currentgraph to the top of the stack and pops stack. +*/ +void +PushGraphContext(GRAPH *graph) +{ + + GCSTACK *gcstack = NEWGCSTACK; + + if (!gcstacktop) { + gcstacktop = gcstack; + } else { + gcstack->next = gcstacktop; + gcstacktop = gcstack; + } + gcstacktop->pgraph = currentgraph; + currentgraph = graph; + +} + +void +PopGraphContext(void) +{ + + GCSTACK *dead; + + currentgraph = gcstacktop->pgraph; + dead = gcstacktop; + gcstacktop = gcstacktop->next; + tfree(dead); +} diff --git a/src/frontend/plotting/graphdb.h b/src/frontend/plotting/graphdb.h new file mode 100644 index 000000000..130e1450d --- /dev/null +++ b/src/frontend/plotting/graphdb.h @@ -0,0 +1,20 @@ +/************* + * Header file for graphdb.c + * 1999 E. Rouat + ************/ + +#ifndef GRAPHDB_H_INCLUDED +#define GRAPHDB_H_INCLUDED + +GRAPH *NewGraph(void); +GRAPH *FindGraph(int id); +GRAPH *CopyGraph(GRAPH *graph); +int DestroyGraph(int id); +void FreeGraphs(void); +void SetGraphContext(int graphid); +void PushGraphContext(GRAPH *graph); +void PopGraphContext(void); + + + +#endif diff --git a/src/frontend/plotting/grid.c b/src/frontend/plotting/grid.c new file mode 100644 index 000000000..5930b7e94 --- /dev/null +++ b/src/frontend/plotting/grid.c @@ -0,0 +1,1542 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Modified: 2001 AlansFixes +**********/ + +/* + + Routines to draw the various sorts of grids -- linear, log, polar. +*/ + +#include +#include +#include +#include + +#include "grid.h" + + +#define RAD_TO_DEG (180.0 / M_PI) +#define LABEL_CHARS 20 + + +/* static declarations */ +static double * lingrid(GRAPH *graph, double lo, double hi, double delta, int type, Axis axis); +static double * loggrid(GRAPH *graph, double lo, double hi, int type, Axis axis); +static void polargrid(GRAPH *graph); +static void drawpolargrid(GRAPH *graph); +static void adddeglabel(GRAPH *graph, int deg, int x, int y, int cx, int cy, int lx, int ly); +static void addradlabel(GRAPH *graph, int lab, double theta, int x, int y); +static void smithgrid(GRAPH *graph); +static void drawsmithgrid(GRAPH *graph); +static void arcset(GRAPH *graph, double rad, double prevrad, double irad, double iprevrad, + double radoff, int maxrad, int centx, int centy, int xoffset, int yoffset, + char *plab, char *nlab, int pdeg, int ndeg, int pxmin, int pxmax); +static double cliparc(double cx, double cy, double rad, double start, double end, int iclipx, + int iclipy, int icliprad, int flag); + + + + +/* note: scaleunits is static and never changed in this file + ie, can get rid of it */ +static bool scaleunits = TRUE; + + +extern void SetColor (int colorid); +extern void SetLinestyle (int linestyleid); +extern void Text (char *text, int x, int y); +void drawloggrid (GRAPH *graph, char *units, int hmt, int lmt, int decsp, int subs, int pp, Axis axis); +void drawlingrid (GRAPH *graph, char *units, int spacing, int nsp, double dst, double lmt, double hmt, bool onedec, int mult, double mag, int digits, Axis axis); +extern void DrawLine (int x1, int y1, int x2, int y2); +extern void Update (void); +extern void Arc (int x0, int y0, int radius, double theta1, double theta2); + +void +gr_fixgrid(GRAPH *graph, double xdelta, double ydelta, int xtype, int ytype) +{ + double *dd; + + if (graph->grid.gridtype == GRID_NONE) { + graph->grid.gridtype = GRID_LIN; + } + + SetColor(1); + SetLinestyle(1); + + if ((graph->data.xmin > graph->data.xmax) + || (graph->data.ymin > graph->data.ymax)) { + fprintf(cp_err, + "gr_fixgrid: Internal Error - bad limits: %g, %g, %g, %g\r\n", + graph->data.xmin, graph->data.xmax, + graph->data.ymin, graph->data.ymax); + return; + } + + if (graph->grid.gridtype == GRID_POLAR) { + graph->grid.circular = TRUE; + polargrid(graph); + return; + } else if (graph->grid.gridtype == GRID_SMITH + || graph->grid.gridtype == GRID_SMITHGRID) + { + graph->grid.circular = TRUE; + smithgrid(graph); + return; + } + graph->grid.circular = FALSE; + + if ((graph->grid.gridtype == GRID_YLOG) + || (graph->grid.gridtype == GRID_LOGLOG)) + dd = loggrid(graph, graph->data.ymin, graph->data.ymax, + ytype, y_axis); + else + dd = lingrid(graph, graph->data.ymin, graph->data.ymax, + ydelta, ytype, y_axis); + + graph->datawindow.ymin = dd[0]; + graph->datawindow.ymax = dd[1]; + + if ((graph->grid.gridtype == GRID_XLOG) + || (graph->grid.gridtype == GRID_LOGLOG)) + dd = loggrid(graph, graph->data.xmin, graph->data.xmax, + xtype, x_axis); + else + dd = lingrid(graph, graph->data.xmin, graph->data.xmax, + xdelta, xtype, x_axis); + + graph->datawindow.xmin = dd[0]; + graph->datawindow.xmax = dd[1]; + +/* do we really need this? */ +/* + SetLinestyle(0); + DrawLine(graph->viewportxoff, graph->viewportyoff, + graph->viewport.width + graph->viewportxoff, + graph->viewportyoff); + DrawLine(graph->viewportxoff, graph->viewportyoff, + graph->viewportxoff, + graph->viewport.height + graph->viewportyoff); + SetLinestyle(1); +*/ + + return; +} + +void +gr_redrawgrid(GRAPH *graph) +{ + + SetColor(1); + SetLinestyle(1); + /* draw labels */ + if (graph->grid.xlabel) { + Text(graph->grid.xlabel, + (int) (graph->absolute.width * 0.35), + graph->fontheight); + } + if (graph->grid.ylabel) { + if (graph->grid.gridtype == GRID_POLAR + || graph->grid.gridtype == GRID_SMITH + || graph->grid.gridtype == GRID_SMITHGRID) { + Text(graph->grid.ylabel, + graph->fontwidth, + (graph->absolute.height * 3) / 4 ); + } else { + Text(graph->grid.ylabel, + graph->fontwidth, + graph->absolute.height / 2 ); + } + } + + switch( graph->grid.gridtype ) { + case GRID_POLAR: + drawpolargrid(graph); + break; + case GRID_SMITH: + drawsmithgrid(graph); + break; + case GRID_SMITHGRID: + drawsmithgrid(graph); + break; + + + case GRID_XLOG: + case GRID_LOGLOG: + drawloggrid(graph, + graph->grid.xaxis.log.units, + graph->grid.xaxis.log.hmt, + graph->grid.xaxis.log.lmt, + graph->grid.xaxis.log.decsp, + graph->grid.xaxis.log.subs, + graph->grid.xaxis.log.pp, x_axis); + break; + default: + drawlingrid(graph, + graph->grid.xaxis.lin.units, + graph->grid.xaxis.lin.spacing, + graph->grid.xaxis.lin.numspace, + graph->grid.xaxis.lin.distance, + graph->grid.xaxis.lin.lowlimit, + graph->grid.xaxis.lin.highlimit, + graph->grid.xaxis.lin.onedec, + graph->grid.xaxis.lin.mult, + graph->grid.xaxis.lin.tenpowmag + / graph->grid.xaxis.lin.tenpowmagx, + graph->grid.xaxis.lin.digits, + x_axis); + break; + } + + switch( graph->grid.gridtype ) { + case GRID_POLAR: + case GRID_SMITH: + case GRID_SMITHGRID: + break; + + case GRID_YLOG: + case GRID_LOGLOG: + drawloggrid(graph, + graph->grid.yaxis.log.units, + graph->grid.yaxis.log.hmt, + graph->grid.yaxis.log.lmt, + graph->grid.yaxis.log.decsp, + graph->grid.yaxis.log.subs, + graph->grid.yaxis.log.pp, y_axis); + break; + default: + drawlingrid(graph, + graph->grid.yaxis.lin.units, + graph->grid.yaxis.lin.spacing, + graph->grid.yaxis.lin.numspace, + graph->grid.yaxis.lin.distance, + graph->grid.yaxis.lin.lowlimit, + graph->grid.yaxis.lin.highlimit, + graph->grid.yaxis.lin.onedec, + graph->grid.yaxis.lin.mult, + graph->grid.yaxis.lin.tenpowmag + / graph->grid.yaxis.lin.tenpowmagx, + graph->grid.yaxis.lin.digits, + y_axis); + break; + } + +} + +/* Plot a linear grid. Returns the new hi and lo limits. */ +static double * +lingrid(GRAPH *graph, double lo, double hi, double delta, int type, Axis axis) +{ + int mag, mag2, mag3; + double hmt, lmt, dst; + int nsp; + double tenpowmag = 0.0, tenpowmag2, step, spacing; + bool onedec = FALSE; + int margin; + int max; + static double dd[2]; + int mult = 1; + char buf[LABEL_CHARS], *s; + int slim, digits; + + if (axis == y_axis && graph->grid.ysized) { + lmt = graph->grid.yaxis.lin.lowlimit; + hmt = graph->grid.yaxis.lin.highlimit; + tenpowmag = graph->grid.yaxis.lin.tenpowmag; + dd[0] = lmt * tenpowmag; + dd[1] = hmt * tenpowmag; + return dd; + } + + if (axis == x_axis && graph->grid.xsized) { + lmt = graph->grid.xaxis.lin.lowlimit; + hmt = graph->grid.xaxis.lin.highlimit; + tenpowmag = graph->grid.xaxis.lin.tenpowmag; + dd[0] = lmt * tenpowmag; + dd[1] = hmt * tenpowmag; + return dd; + } + + if (delta < 0.0) { + fprintf(cp_err, "Warning: %cdelta is negative -- reversed\n", + (axis == x_axis) ? 'x' : 'y'); + delta = -delta; + } + + mag2 = floor(log10(fabs(hi - lo))); + tenpowmag2 = pow(10.0, (double) mag2); + + /* Round lo down, and hi up */ + + /* First, round lo _up_ and hi _down_ out to the 3rd digit of accuracy */ + lmt = (ceil(1000 * lo / tenpowmag2)) / 1000.0; + hmt = (floor(1000 * hi / tenpowmag2 + 0.9)) / 1000.0; + + lmt = floor(10.0 * lmt) / 10.0; + hmt = ceil(10.0 * hmt) / 10.0; + + lo = lmt * tenpowmag2; + hi = hmt * tenpowmag2; + + if (fabs(hi) > fabs(lo)) + mag = floor(log10(fabs(hi))); + else + mag = floor(log10(fabs(lo))); + + if (mag >= 0) + mag3 = ((int) (mag / 3)) * 3; + else + mag3 = - ((int) ((2 - mag) / 3)) * 3; + + if (scaleunits) + digits = mag3 - mag2; + else { + digits = mag - mag2; + mag3 = mag; + } + + if (digits < 1) + digits = 0; + + if (axis == x_axis) { + margin = graph->viewportxoff; + /*max = graph->viewport.width + graph->viewportxoff;*/ + max = graph->absolute.width - graph->viewportxoff; + } else { + graph->viewportxoff = (digits + 5 + mag - mag3) * graph->fontwidth; + margin = graph->viewportyoff; + /*max = graph->viewport.height + graph->viewportyoff;*/ + max = graph->absolute.height - graph->viewportyoff; + } + + /* Express the difference between the high and low values as + * diff = d * 10^mag. We know diff >= 0.0. If scaleunits is + * set then make sure that mag is modulo 3. + */ + + dst = hmt - lmt; + + /* We have to go from lmt to hmt, so think of some useful places + * to put grid lines. We will have a total of nsp lines, one + * every spacing pixels, which is every dst / nsp units. + */ + + if (scaleunits) { + static char scaleletters[ ] = "afpnum\0kMGT"; + char *p; + int i, j; + + tenpowmag = pow(10.0, (double) mag3); + + *buf = 0; + + i = (mag3 + 18) / 3; + + if (i < 0) + i = 6; /* No scale units */ + else if (i >= sizeof(scaleletters) - 1) { + /* sizeof includes '\0' at end, which is useless */ + /* i = sizeof(scaleletters) - 2; */ + i = 6; /* No scale units */ + } + + j = mag3 - i * 3 + 18; + if (j == 1) + (void) sprintf(buf, "x10 "); + else if (j == 2) + (void) sprintf(buf, "x100 "); + else if (j) + (void) sprintf(buf, "x10^%d ", j); + + if (scaleletters[i]) { + for (p = buf; *p; p++) + ; + *p++ = scaleletters[i]; + *p++ = 0; + } + + } else if (mag > 1) { + tenpowmag = pow(10.0, (double) mag); + (void) sprintf(buf, "x10^%d ", mag); + } + + if ((s = ft_typabbrev(type))) { + (void) strcat(buf, s); + } else { + (void) strcat(buf, "Units"); + } + + if (delta == 0.0) { + int i; + double step; + + static struct { float div_lim, step; } div_list[ ] = { + { 100.0, 10.0 }, + { 50.0, 5.0 }, + { 20.0, 2.0 }, + { 6.0, 1.0 }, + { 3.0, 0.5 }, + { 1.0, 0.2 }, + { 0.5, 0.1 }, + { 0.0, 0.05 }, + { 0.0, 0.01 } + }; + + for (i = 0; i < NUMELEMS(div_list); i++) { + if (dst > div_list[i].div_lim) { + break; + } + } + + do { + step = div_list[i].step; + nsp = (dst + step - 0.0001) / step; + spacing = (max - margin) / nsp; + i += 1; + } while (i < NUMELEMS(div_list) && spacing > 50); + + if (axis == x_axis) { + slim = digits + 5 + mag - mag3; + slim = graph->fontwidth * (slim + 1); + } else + slim = graph->fontheight * 3; + + while (i > 0 && spacing < slim + 3) { + i -= 1; + step = div_list[i].step; + nsp = (dst + step - 0.0001) / step; + spacing = (max - margin) / nsp; + } + + if (lmt < 0) + lmt = - ceil(-lmt / step) * step; + else + lmt = floor(lmt / step) * step; + + if (hmt < 0) + hmt = - floor(-hmt / step) * step; + else + hmt = ceil(hmt / step) * step; + + dst = hmt - lmt; + + lo = lmt * tenpowmag2; + hi = hmt * tenpowmag2; + + nsp = (dst + step - 0.0001) / step; + + } else { + /* The user told us where to put the grid lines. They will + * not be equally spaced in this case (i.e, the right edge + * won't be a line). + */ + nsp = (hi - lo) / delta; + if (nsp > 100) + nsp = 100; + step = (max - margin) * delta / (hi - lo); + } + spacing = (max - margin) / nsp; + + dd[0] = lo; + dd[1] = hi; + + /* Reset the max coordinate to deal with round-off error. */ + if (nsp && (delta == 0.0)) { + if (axis == x_axis) + graph->viewport.width = spacing * nsp; + else + graph->viewport.height = spacing * nsp; + } else if (!nsp) { + nsp = 1; + } + + /* have to save non-intuitive variables left over + from old algorithms for redraws */ + + if (axis == x_axis) { + graph->grid.xsized = 1; + graph->grid.xaxis.lin.onedec = onedec; + graph->grid.xaxis.lin.mult = mult; + graph->grid.xaxis.lin.tenpowmag = tenpowmag2; + graph->grid.xaxis.lin.tenpowmagx = tenpowmag; + graph->grid.xaxis.lin.digits = digits; + (void) strcpy(graph->grid.xaxis.lin.units, buf); + graph->grid.xaxis.lin.distance = dst; + graph->grid.xaxis.lin.lowlimit = lmt; + graph->grid.xaxis.lin.highlimit = hmt; + graph->grid.xaxis.lin.spacing = spacing; + graph->grid.xaxis.lin.numspace = nsp; + } else { + graph->grid.ysized = 1; + graph->grid.yaxis.lin.onedec = onedec; + graph->grid.yaxis.lin.mult = mult; + graph->grid.yaxis.lin.tenpowmag = tenpowmag2; + graph->grid.yaxis.lin.tenpowmagx = tenpowmag; + graph->grid.yaxis.lin.digits = digits; + (void) strcpy(graph->grid.yaxis.lin.units, buf); + graph->grid.yaxis.lin.distance = dst; + graph->grid.yaxis.lin.lowlimit = lmt; + graph->grid.yaxis.lin.highlimit = hmt; + graph->grid.yaxis.lin.spacing = spacing; + graph->grid.yaxis.lin.numspace = nsp; + } + + return (dd); +} + +/* PN static */ +void +drawlingrid(GRAPH *graph, char *units, int spacing, int nsp, double dst, double lmt, double hmt, bool onedec, int mult, double mag, int digits, Axis axis) +{ + + int i, j; + double m, step; + char buf[LABEL_CHARS]; + + /* i counts how many pixels we have drawn, and j counts which unit + * we are at. + */ + SetLinestyle(1); + step = floor((double) dst / nsp * 100.0 + 0.000001); + for (i = 0, m = lmt * 100.0; m - 0.001 <= hmt * 100.0; + i += spacing, m += step) + { + j = m; + if (j == 0) + SetLinestyle(0); + if (graph->grid.gridtype != GRID_NONE) { + if (axis == x_axis) + DrawLine(graph->viewportxoff + i, + graph->viewportyoff, graph->viewportxoff + i, + graph->viewport.height + graph->viewportyoff); + else + DrawLine(graph->viewportxoff, + graph->viewportyoff + i, + graph->viewport.width + graph->viewportxoff, + graph->viewportyoff + i); + } + if (j == 0) + SetLinestyle(1); + + (void) sprintf(buf, "%.*f", digits + 1, m * mag / 100.0); + + if (axis == x_axis) + Text(buf, graph->viewportxoff + i - + strlen(buf) / 2 * graph->fontwidth, + (int) (graph->fontheight * 2.5)); + else + Text(buf, graph->viewportxoff - + graph->fontwidth * (strlen(buf)), + graph->viewportyoff + i - + graph->fontheight / 2); + + /* This is to make sure things work when delta > hi - lo. */ + if (nsp == 1) + j += 1000; + } + if (axis == x_axis) + Text(units, (int) (graph->absolute.width * 0.6), + graph->fontheight); + else + Text(units, graph->fontwidth, + (int) (graph->absolute.height - 2 * graph->fontheight)); + Update(); + +} + +/* Plot a log grid. Note that we pay no attention to x- and y-delta here. */ +static double * +loggrid(GRAPH *graph, double lo, double hi, int type, Axis axis) +{ + static double dd[2]; + int margin; + int max; + int subs, pp, decsp, lmt, hmt; + int i, j; + double k; + double decs; + char buf[LABEL_CHARS], *s; + + if (axis == x_axis && graph->grid.xsized) { + lmt = graph->grid.xaxis.log.lmt; + hmt = graph->grid.xaxis.log.hmt; + dd[0] = pow(10.0, (double) lmt); + dd[1] = pow(10.0, (double) hmt); + return dd; + } else if (axis == y_axis && graph->grid.ysized) { + lmt = graph->grid.yaxis.log.lmt; + hmt = graph->grid.yaxis.log.hmt; + dd[0] = pow(10.0, (double) lmt); + dd[1] = pow(10.0, (double) hmt); + return dd; + } + + if (axis == x_axis) { + margin = graph->viewportxoff; + max = graph->absolute.width - graph->viewportxoff; + } else { + margin = graph->viewportyoff; + max = graph->absolute.height - graph->viewportyoff; + } + + /* How many orders of magnitude. We are already guaranteed that hi + * and lo are positive. + */ + + lmt = floor(mylog10(lo)); + hmt = ceil(mylog10(hi)); + + decs = hmt - lmt; + + pp = 1; + decsp = (max - margin) / decs; + + if (decsp < 20) { + pp = ceil(20.0 / decsp); + decsp *= pp; + subs = 1; + } else if (decsp > 50) { + static int divs[ ] = { 20, 10, 5, 4, 2, 1 }; + + k = 5.0 / decsp; + + for (i = 0; i < NUMELEMS(divs) - 1; i++) { + j = divs[i]; + if (-log10(((double) j - 1.0) / j) > k) + break; + } + + subs = divs[i]; + + } else + subs = 1; + + /* Start at a line */ + lmt = floor((double) lmt / pp) * pp; + decs = hmt - lmt; + decsp = (max - margin) / decs; + + dd[0] = pow(10.0, (double) lmt); + dd[1] = pow(10.0, (double) hmt); + + if ((s = ft_typabbrev(type))) { + (void) strcpy(buf, s); + } else { + (void) strcpy(buf, "Units"); + } + + if (axis == x_axis) { + (void) strcpy(graph->grid.xaxis.log.units, buf); + graph->viewport.width = decs * decsp; + graph->grid.xaxis.log.hmt = hmt; + graph->grid.xaxis.log.lmt = lmt; + graph->grid.xaxis.log.decsp = decsp; + graph->grid.xaxis.log.subs = subs; + graph->grid.xaxis.log.pp = pp; + graph->grid.xsized = 1; + } else { + (void) strcpy(graph->grid.yaxis.log.units, buf); + graph->viewport.height = decs * decsp; + graph->grid.yaxis.log.hmt = hmt; + graph->grid.yaxis.log.lmt = lmt; + graph->grid.yaxis.log.decsp = decsp; + graph->grid.yaxis.log.subs = subs; + graph->grid.yaxis.log.pp = pp; + graph->grid.ysized = 1; + } + + return (dd); + +} + +/* PN static */ +void +drawloggrid(GRAPH *graph, char *units, int hmt, int lmt, int decsp, int subs, int pp, Axis axis) +{ + int i, j, k, m; + double t; + char buf[LABEL_CHARS]; + + /* Now plot every pp'th decade line, with subs lines between them. */ + if (subs > 1) + SetLinestyle(0); + for (i = 0, j = lmt; j <= hmt; i += decsp * pp, j += pp) { + /* Draw the decade line */ + if (graph->grid.gridtype != GRID_NONE) { + if (axis == x_axis) + DrawLine(graph->viewportxoff + i, + graph->viewportyoff, + graph->viewportxoff + i, + graph->viewport.height + +graph->viewportyoff); + else + DrawLine(graph->viewportxoff, + graph->viewportyoff + i, + graph->viewport.width + + graph->viewportxoff, + graph->viewportyoff + i); + } + if (j == -2) + (void) sprintf(buf, "0.01"); + else if (j == -1) + (void) sprintf(buf, "0.1"); + else if (j == 0) + (void) sprintf(buf, "1"); + else if (j == 1) + (void) sprintf(buf, "10"); + else if (j == 2) + (void) sprintf(buf, "100"); + else + (void) sprintf(buf, "10^%d", j); + if (axis == x_axis) + Text(buf, graph->viewportxoff + i - strlen(buf) / 2, + (int) (graph->fontheight * 2.5)); + else + Text(buf, graph->viewportxoff - graph->fontwidth * + (strlen(buf) + 1), + graph->viewportyoff + i - + graph->fontheight / 2); + + if (j >= hmt) + break; + + /* Now draw the subdivision lines */ + if (subs > 1) { + SetLinestyle(1); + t = 10.0 / subs; + for (k = ceil(subs / 10.0) + 1; k < subs; k++) { + m = i + decsp * log10((double) t * k); + if (graph->grid.gridtype != GRID_NONE) { + if (axis == x_axis) + DrawLine(graph->viewportxoff + m, + graph->viewportyoff, + graph->viewportxoff + m, + graph->viewport.height + + graph->viewportyoff); + else + DrawLine(graph->viewportxoff, + graph->viewportyoff + m, + graph->viewport.width + + graph->viewportxoff, + graph->viewportyoff + m); + } + } + SetLinestyle(0); + } + } + if (axis == x_axis) + Text(units, (int) (graph->absolute.width * 0.6), + graph->fontheight); + else + Text(units, graph->fontwidth, + (int) (graph->absolute.height - 2 * graph->fontheight)); + Update(); +} + +/* Polar grids */ + +static void +polargrid(GRAPH *graph) +{ + double d, mx, my, tenpowmag; + int hmt, lmt, mag; + double minrad, maxrad; + bool centered = FALSE; + + /* Make sure that our area is square. */ + if (graph->viewport.width > graph->viewport.height) { + graph->viewport.width = graph->viewport.height; + } else { + graph->viewport.height = graph->viewport.width; + } + + /* Make sure that the borders are even */ + if (graph->viewport.width & 1) { + graph->viewport.width += 1; + graph->viewport.height += 1; + } + graph->grid.xaxis.circular.center = graph->viewport.width / 2 + + graph->viewportxoff; + graph->grid.yaxis.circular.center = graph->viewport.height / 2 + + graph->viewportyoff; + + graph->grid.xaxis.circular.radius = graph->viewport.width / 2; + + /* Figure out the minimum and maximum radii we're dealing with. */ + mx = (graph->data.xmin + graph->data.xmax) / 2; + my = (graph->data.ymin + graph->data.ymax) / 2; + d = sqrt(mx * mx + my * my); + maxrad = d + (graph->data.xmax - graph->data.xmin) / 2; + minrad = d - (graph->data.xmax - graph->data.xmin) / 2; + + if (maxrad == 0.0) { + fprintf(cp_err, "Error: 0 radius in polargrid\n"); + return; + } + if ((graph->data.xmin < 0) && (graph->data.ymin < 0) && + (graph->data.xmax > 0) && (graph->data.ymax > 0)) + minrad = 0; + if ((graph->data.xmin == - graph->data.xmax) + && (graph->data.ymin == -graph->data.ymax) + && (graph->data.xmin == graph->data.ymin)) + centered = TRUE; + + mag = floor(mylog10(maxrad)); + tenpowmag = pow(10.0, (double) mag); + hmt = maxrad / tenpowmag; + lmt = minrad / tenpowmag; + if (hmt * tenpowmag < maxrad) + hmt++; + if (lmt * tenpowmag > minrad) + lmt--; + maxrad = hmt * tenpowmag; + minrad = lmt * tenpowmag; + + /* Make sure that the range is square */ + mx = graph->data.xmax - graph->data.xmin; + my = graph->data.ymax - graph->data.ymin; + graph->datawindow.xmin = graph->data.xmin; + graph->datawindow.xmax = graph->data.xmax; + graph->datawindow.ymin = graph->data.ymin; + graph->datawindow.ymax = graph->data.ymax; + if (mx > my) { + graph->datawindow.ymin -= (mx - my) / 2; + graph->datawindow.ymax += (mx - my) / 2; + } else if (mx < my) { + graph->datawindow.xmin -= (my - mx) / 2; + graph->datawindow.xmax += (my - mx) / 2; + } + + /* Range is square with upper bound maxrad */ + + graph->grid.xaxis.circular.hmt = hmt; + graph->grid.xaxis.circular.lmt = lmt; + graph->grid.xaxis.circular.mag = mag; +} + + +static void +drawpolargrid(GRAPH *graph) +{ + double tenpowmag, theta; + int hmt, lmt, i, step, mag; + int relcx, relcy, relrad, dist, degs; + int x1, y1, x2, y2; + double minrad, maxrad, pixperunit; + char buf[64]; + + hmt = graph->grid.xaxis.circular.hmt; + lmt = graph->grid.xaxis.circular.lmt; + mag = graph->grid.xaxis.circular.mag; + tenpowmag = pow(10.0, (double) mag); + maxrad = hmt * tenpowmag; + minrad = lmt * tenpowmag; + + if ((minrad == 0) && ((hmt - lmt) > 5)) { + if (!((hmt - lmt) % 2)) + step = 2; + else if (!((hmt - lmt) % 3)) + step = 3; + else + step = 1; + } else + step = 1; + pixperunit = graph->grid.xaxis.circular.radius * 2 / + (graph->datawindow.xmax - graph->datawindow.xmin); + + relcx = - (graph->datawindow.xmin + graph->datawindow.xmax) / 2 + * pixperunit; + relcy = - (graph->datawindow.ymin + graph->datawindow.ymax) / 2 + * pixperunit; + + /* The distance from the center of the plotting area to the center of + * the logical area. + */ + dist = sqrt((double) (relcx * relcx + relcy * relcy)); + + SetLinestyle(0); + Arc(graph->grid.xaxis.circular.center, + graph->grid.yaxis.circular.center, + graph->grid.xaxis.circular.radius, + (double) 0.0, (double) 0.0); + SetLinestyle(1); + + /* Now draw the circles. */ + for (i = lmt; + (relrad = i * tenpowmag * pixperunit) + <= dist + graph->grid.xaxis.circular.radius; + i += step) + { + cliparc((double) graph->grid.xaxis.circular.center + relcx, + (double) graph->grid.yaxis.circular.center + relcy, + (double) relrad, 0.0, 0.0, + graph->grid.xaxis.circular.center, + graph->grid.yaxis.circular.center, + graph->grid.xaxis.circular.radius, 0); + /* Toss on the label */ + if (relcx || relcy) + theta = atan2((double) relcy, (double) relcx); + else + theta = M_PI; + if (i && (relrad > dist - graph->grid.xaxis.circular.radius)) + addradlabel(graph, i, theta, + (int) (graph->grid.xaxis.circular.center - + (relrad - dist) * cos(theta)), + (int) (graph->grid.yaxis.circular.center + - (relrad - dist) * sin(theta))); + } + + /* Now draw the spokes. We have two possible cases -- first, the + * origin may be inside the area -- in this case draw 12 spokes. + * Otherwise, draw several spokes at convenient places. + */ + if ((graph->datawindow.xmin <= 0.0) + && (graph->datawindow.xmax >= 0.0) + && (graph->datawindow.ymin <= 0.0) + && (graph->datawindow.ymax >= 0.0)) { + for (i = 0; i < 12; i++) { + x1 = graph->grid.xaxis.circular.center + relcx; + y1 = graph->grid.yaxis.circular.center + relcy; + x2 = x1 + graph->grid.xaxis.circular.radius * 2 + * cos(i * M_PI / 6); + y2 = y1 + graph->grid.xaxis.circular.radius * 2 + * sin(i * M_PI / 6); + if (!clip_to_circle(&x1, &y1, &x2, &y2, + graph->grid.xaxis.circular.center, + graph->grid.yaxis.circular.center, + graph->grid.xaxis.circular.radius)) + { + DrawLine(x1, y1, x2, y2); + /* Add a label here */ + /*XXXX*/ + adddeglabel(graph, i * 30, x2, y2, x1, y1, + graph->grid.xaxis.circular.center, + graph->grid.yaxis.circular.center); + } + } + } else { + /* Figure out the angle that we have to fill up */ + theta = 2 * asin((double) graph->grid.xaxis.circular.radius + / dist); + theta = theta * 180 / M_PI; /* Convert to degrees. */ + + /* See if we should put lines at 30, 15, 5, or 1 degree + * increments. + */ + if (theta / 30 > 3) + degs = 30; + else if (theta / 15 > 3) + degs = 15; + else if (theta / 5 > 3) + degs = 5; + else + degs = 1; + + /* We'll be cheap */ + for (i = 0; i < 360; i+= degs) { + x1 = graph->grid.xaxis.circular.center + relcx; + y1 = graph->grid.yaxis.circular.center + relcy; + x2 = x1 + dist * 2 * cos(i * M_PI / 180); + y2 = y1 + dist * 2 * sin(i * M_PI / 180); + if (!clip_to_circle(&x1, &y1, &x2, &y2, + graph->grid.xaxis.circular.center, + graph->grid.yaxis.circular.center, + graph->grid.xaxis.circular.radius)) { + DrawLine(x1, y1, x2, y2); + /* Put on the label */ + adddeglabel(graph, i, x2, y2, x1, y1, + graph->grid.xaxis.circular.center, + graph->grid.yaxis.circular.center); + } + } + } + + (void) sprintf(buf, "e%d", mag); + Text(buf, graph->grid.xaxis.circular.center + + graph->grid.xaxis.circular.radius, + graph->grid.yaxis.circular.center + - graph->grid.xaxis.circular.radius); + Update(); + return; +} + +/* Put a degree label on the screen, with 'deg' as the label, near point (x, y) + * such that the perpendicular to (cx, cy) and (x, y) doesn't overwrite the + * label. If the distance between the center and the point is + * too small, don't put the label on. + */ + +#define LOFF 5 +#define MINDIST 10 + +static void +adddeglabel(GRAPH *graph, int deg, int x, int y, int cx, int cy, int lx, int ly) +{ + char buf[8]; + int d, w, h; + double angle; + + if (sqrt((double) (x - cx) * (x - cx) + (y - cy) * (y - cy)) < MINDIST) + return; + (void) sprintf(buf, "%d", deg); + w = graph->fontwidth * (strlen(buf) + 1); + h = graph->fontheight * 1.5; + angle = atan2((double) (y - ly), (double) (x - lx)); + d = fabs(cos(angle)) * w / 2 + fabs(sin(angle)) * h / 2 + LOFF; + + x = x + d * cos(angle) - w / 2; + y = y + d * sin(angle) - h / 2; + + Text(buf, x, y); + Text("o", x + strlen(buf) * graph->fontwidth, + y + graph->fontheight / 2); + return; +} + +/* This is kind of wierd. If dist = 0, then this is the normal case, where + * the labels should go along the positive X-axis. Otherwise, to make + * sure that all circles drawn have labels, put the label near the circle + * along the line from the logical center to the physical center. + */ + +static void +addradlabel(GRAPH *graph, int lab, double theta, int x, int y) +{ + char buf[32]; + + (void) sprintf(buf, "%d", lab); + if (theta == M_PI) { + y = y - graph->fontheight - 2; + x = x - graph->fontwidth * strlen(buf) - 3; + } else + x = x - graph->fontwidth * strlen(buf) - 3; + Text(buf, x, y); + return; +} + + +/* Smith charts. */ + +#define gr_xcenter graph->grid.xaxis.circular.center +#define gr_ycenter graph->grid.yaxis.circular.center +#define gr_radius graph->grid.xaxis.circular.radius +#define gi_fntwidth graph->fontwidth +#define gi_fntheight graph->fontheight +#define gi_maxx graph->viewport.width+graph->viewportxoff +#define gr_xmargin graph->viewportxoff +#define gr_ymargin graph->viewportyoff + +static void +smithgrid(GRAPH *graph) +{ + double mx, my; + bool centered = FALSE; + + SetLinestyle(0); + + /* Make sure that our area is square. */ + if (graph->viewport.width > graph->viewport.height) { + graph->viewport.width = graph->viewport.height; + } else { + graph->viewport.height = graph->viewport.width; + } + + /* Make sure that the borders are even */ + if (graph->viewport.width & 1) { + graph->viewport.width += 1; + graph->viewport.height += 1; + } + + graph->grid.xaxis.circular.center = graph->viewport.width / 2 + + graph->viewportxoff; + graph->grid.yaxis.circular.center = graph->viewport.height / 2 + + graph->viewportyoff; + graph->grid.xaxis.circular.radius = graph->viewport.width / 2; + + + /* We have to make sure that the range is square. */ + graph->datawindow.xmin = graph->data.xmin; + graph->datawindow.xmax = graph->data.xmax; + graph->datawindow.ymin = graph->data.ymin; + graph->datawindow.ymax = graph->data.ymax; + + if (graph->datawindow.ymin > 0) + graph->datawindow.ymin *= -1; + if (graph->datawindow.xmin > 0) + graph->datawindow.xmin *= -1; + + if (graph->datawindow.ymax < 0) + graph->datawindow.ymax *= -1; + if (graph->datawindow.xmax < 0) + graph->datawindow.xmax *= -1; + + if (fabs(graph->datawindow.ymin) > fabs(graph->datawindow.ymax)) + graph->datawindow.ymax = - graph->datawindow.ymin; + else + graph->datawindow.ymin = - graph->datawindow.ymax; + + if (fabs(graph->datawindow.xmin) > fabs(graph->datawindow.xmax)) + graph->datawindow.xmax = - graph->datawindow.xmin; + else + graph->datawindow.xmin = - graph->datawindow.xmax; + + mx = graph->datawindow.xmax - graph->datawindow.xmin; + my = graph->datawindow.ymax - graph->datawindow.ymin; + if (mx > my) { + graph->datawindow.ymin -= (mx - my) / 2; + graph->datawindow.ymax += (mx - my) / 2; + } else if (mx < my) { + graph->datawindow.xmin -= (my - mx) / 2; + graph->datawindow.xmax += (my - mx) / 2; + } + + if ((graph->datawindow.xmin == - graph->datawindow.xmax) && + (graph->datawindow.ymin == - + graph->datawindow.ymax) && (graph->datawindow.xmin == + graph->datawindow.ymin)) + centered = TRUE; + + /* Issue a warning if our data range is not normalized */ + if (graph->datawindow.ymax > 1.1) { + printf("\nwarning: exceeding range for smith chart"); + printf("\nplease normalize your data to -1 < r < +1\n"); + } + +} + +/* maximum number of circles */ +#define CMAX 50 + +static void +drawsmithgrid(GRAPH *graph) +{ + double mx, my, tenpowmag, d, dphi[CMAX], minrad, maxrad, rnorm[CMAX]; + double pixperunit; + int mag, i = 0, j = 0, k; + double ir[CMAX], rr[CMAX], ki[CMAX], kr[CMAX], ks[CMAX]; + int xoff, yoff, zheight; + int basemag, plen; + char buf[64], plab[32], nlab[32]; + + /* Figure out the minimum and maximum radii we're dealing with. */ + mx = (graph->datawindow.xmin + graph->datawindow.xmax) / 2; + my = (graph->datawindow.ymin + graph->datawindow.ymax) / 2; + d = sqrt(mx * mx + my * my); + maxrad = d + (graph->datawindow.xmax - graph->datawindow.xmin) / 2; + minrad = d - (graph->datawindow.xmax - graph->datawindow.xmin) / 2; + + mag = floor(mylog10(maxrad)); + tenpowmag = pow(10.0, (double) mag); + + pixperunit = graph->viewport.width / (graph->datawindow.xmax - + graph->datawindow.xmin); + + xoff = - pixperunit * (graph->datawindow.xmin + graph->datawindow.xmax) / 2; + yoff = - pixperunit * (graph->datawindow.ymin + graph->datawindow.ymax) / 2; + + /* Sweep the range from 10e-20 to 10e20. If any arcs fall into the + * picture, plot the arc set. + */ + for (mag = -20; mag < 20; mag++) { + i = gr_radius * pow(10.0, (double) mag) / maxrad; + if (i > 10) { + j = 1; + break; + } else if (i > 5) { + j = 2; + break; + } else if (i > 2) { + j = 5; + break; + } + } + k = 1; + + /* SetLinestyle(1); takes too long */ + /* Problems with Suns on very large radii && linestyle */ + SetLinestyle(0); + + /* Now plot all the arc sets. Go as high as 5 times the radius that + * will fit on the screen. The base magnitude is one more than + * the least magnitude that will fit... + */ + if (i > 20) + basemag = mag; + else + basemag = mag + 1; + /* Go back one order of magnitude and have a closer look */ + mag -= 2; + j *= 10; + while (mag < 20) { + i = j * pow(10.0, (double) mag) * pixperunit / 2; + if (i / 5 > gr_radius + ((xoff > 0) ? xoff : - xoff)) + break; + rnorm[k] = j * pow(10.0, (double) (mag - basemag)); + dphi[k] = 2.0 * atan(rnorm[k]); + ir[k] = pixperunit * (1 + cos(dphi[k])) / sin(dphi[k]); + rr[k] = pixperunit * 0.5 * (((1 - rnorm[k]) / (1 + rnorm[k])) + 1); + (void) sprintf(plab, "%g", rnorm[k]); + plen = strlen(plab); + + /* See if the label will fit on the upper xaxis */ + /* wait for some k, so we don't get fooled */ + if (k > 6) { + if ((int) (gr_radius - xoff - pixperunit + 2 * rr[k]) < + plen * gi_fntwidth + 2) + break; + } + /* See if the label will fit on the lower xaxis */ + /* First look at the leftmost circle possible*/ + if ((int) (pixperunit - 2 * rr[k] + gr_radius + xoff + + fabs((double) yoff)) < plen * gi_fntwidth + 4) { + if (j == 95) { + j = 10; + mag++; + } else { + if (j < 20) + j += 1; + else + j += 5; + } + continue; + } + /* Then look at the circles following in the viewport */ + if (k>1 && (int) 2 * (rr[k-1] - rr[k]) < plen * gi_fntwidth + 4) { + if (j == 95) { + j = 10; + mag++; + } else { + if (j < 20) + j += 1; + else + j += 5; + } + continue; + } + if (j == 95) { + j = 10; + mag++; + } else { + if (j < 20) + j += 1; + else + j += 5; + } + ki[k-1] = ir[k]; + kr[k-1] = rr[k]; + k++; + if (k == CMAX) { + printf("drawsmithgrid: grid too complex\n"); + break; + } + } + k--; + + /* Now adjust the clipping radii */ + for (i = 0; i < k; i++) + ks[i] = ki[i]; + for (i = k-1, j = k-1; i >= 0; i -= 2, j--) { + ki[i] = ks[j]; + if (i > 0) + ki[i-1] = ks[j]; + } + for (i = 0; i < k; i++) + ks[i] = kr[i]; + for (i = k-1, j = k-1; (i >= 0) && (dphi[i] > M_PI / 2); i -= 2, j--) { + kr[i] = ks[j]; + if (i > 0) + kr[i-1] = ks[j]; + } + for ( ; i >= 0; i--, j--) + kr[i] = ks[j]; + + if ((yoff > - gr_radius) && (yoff < gr_radius)) { + zheight = gr_radius * cos(asin((double) yoff / gr_radius)); + zheight = (zheight > 0) ? zheight : - zheight; + } else { + zheight = gr_radius; + } + for (ki[k] = kr[k] = (double) 0; k > 0; k--) { + (void) sprintf(plab, "%g", rnorm[k]); + (void) sprintf(nlab, "-%g", rnorm[k]); + arcset(graph, rr[k], kr[k], ir[k], ki[k], pixperunit, + gr_radius, gr_xcenter, gr_ycenter, + xoff, yoff, plab, nlab, + (int) (0.5 + RAD_TO_DEG * (M_PI - dphi[k])), + (int) (0.5 + RAD_TO_DEG * (M_PI + dphi[k])), + gr_xcenter - zheight, + gr_xcenter + zheight); + } + if (mag == 20) { + fprintf(cp_err, "smithgrid: Internal Error: screwed up\n"); + return; + } + + SetLinestyle(0); + + Arc(gr_xcenter, gr_ycenter, gr_radius, 0.0, 0.0); +/* + if ((xoff > - gr_radius) && (xoff < gr_radius)) { + zheight = gr_radius * sin(acos((double) xoff / gr_radius)); + if (zheight < 0) + zheight = - zheight; + DrawLine(gr_xcenter + xoff, gr_ycenter - zheight, + gr_xcenter + xoff, gr_ycenter + zheight); + } + */ + if ((yoff > - gr_radius) && (yoff < gr_radius)) { + zheight = gr_radius * cos(asin((double) yoff / gr_radius)); + if (zheight < 0) + zheight = - zheight; + DrawLine(gr_xcenter - zheight, gr_ycenter + yoff, + gr_xcenter + zheight, gr_ycenter + yoff); + Text("0", gr_xcenter + zheight + gi_fntwidth, gr_ycenter + yoff - + gi_fntheight / 2); + Text("o", gr_xcenter + zheight + gi_fntwidth * 2, gr_ycenter + yoff); + Text("180", gr_xcenter - zheight - gi_fntwidth * 5, gr_ycenter + + yoff - gi_fntheight / 2); + Text("o", gr_xcenter - zheight - gi_fntwidth * 2, gr_ycenter + yoff); + } + +/* (void) sprintf(buf, "e%d", basemag); */ + (void) sprintf(buf, "e%d", 0); + Text(buf, gr_xcenter + gr_radius, gr_ycenter - gr_radius); + + Update(); + return; +} + +/* Draw one arc set. The arcs should have radius rad. The outermost circle is + * described by (centx, centy) and maxrad, and the distance from the right side + * of the bounding circle to the logical center of the other circles in pixels + * is xoffset (positive brings the negative plane into the picture). + * plab and nlab are the labels to put on the positive and negative X-arcs, + * respectively... If the X-axis isn't on the screen, then we have to be + * clever... + */ + +static void +arcset(GRAPH *graph, double rad, double prevrad, double irad, double iprevrad, double radoff, int maxrad, int centx, int centy, int xoffset, int yoffset, char *plab, char *nlab, int pdeg, int ndeg, int pxmin, int pxmax) +{ + double aclip; + double angle = atan2((double) iprevrad, (double) rad); + double iangle = atan2((double) prevrad, (double) irad); + int x, xlab, ylab; + + /* Let's be lazy and just draw everything -- we won't get called too + * much and the circles get clipped anyway... + */ + SetColor(18); + + cliparc((double) (centx + xoffset + radoff - rad), + (double) (centy + yoffset), rad, 2*angle, + 2 * M_PI - 2 * angle, centx, centy, maxrad, 0); + + + /* These circles are not part of the smith chart + * Let's draw them anyway + */ + cliparc((double) (centx + xoffset + radoff + rad), + (double) (centy + yoffset), rad, M_PI + 2 * angle, + M_PI - 2 * angle, centx, centy, maxrad, 0); + + /* Draw the upper and lower circles. */ + SetColor(19); + aclip = cliparc((double) (centx + xoffset + radoff), + (double) (centy + yoffset + irad), irad, + (double) (M_PI * 1.5 + 2 * iangle), + (double) (M_PI * 1.5 - 2 * iangle), centx, centy, maxrad, 1); + if ((aclip > M_PI / 180) && (pdeg > 1)) { + xlab = centx + xoffset + radoff + irad * cos(aclip); + ylab = centy + yoffset + irad * (1 + sin(aclip)); + if ((ylab - gr_ycenter) > graph->fontheight) { + SetColor(1); + adddeglabel(graph, pdeg, xlab, ylab, + gr_xcenter, gr_ycenter, gr_xcenter, gr_ycenter); +/* + ylab = centy + yoffset - irad * (1 + sin(aclip)); + adddeglabel(graph, ndeg, xlab, ylab, + gr_xcenter, gr_ycenter, gr_xcenter, gr_ycenter); + */ + SetColor(19); + } + } + aclip = cliparc((double) (centx + xoffset + radoff), + (double) (centy + yoffset - irad), irad, + (double) (M_PI / 2 + 2 * iangle), + (double) (M_PI / 2 - 2 * iangle), centx, centy, maxrad, + (iangle == 0)?2:0); + if ((aclip >= 0 && aclip < 2*M_PI - M_PI/180) && (pdeg < 359)) { + xlab = centx + xoffset + radoff + irad * cos(aclip); + ylab = centy + yoffset + irad * (sin(aclip) - 1); + SetColor(1); + adddeglabel(graph, ndeg, xlab, ylab, + gr_xcenter, gr_ycenter, gr_xcenter, gr_ycenter); + SetColor(19); + } + + /* Now toss the labels on... */ + SetColor(1); + + x = centx + xoffset + (int)radoff - 2 * (int)rad - + gi_fntwidth * strlen(plab) - 2; + if ((x > pxmin) && (x < pxmax)) { + if ((yoffset > - gr_radius) && (yoffset < gr_radius)) + Text(plab, x, centy + yoffset - gi_fntheight - 1); + else + Text(plab, x, gr_ymargin - 3 * gi_fntheight - 2); + } +/* + x = centx + xoffset + (int) radoff + 2 * (int)rad - + gi_fntwidth * strlen(nlab) - 2; + if ((x > gr_xmargin) && (x < gi_maxx)) + Text(nlab, x, centy + yoffset - gi_fntheight - 1); + */ + + return; +} + +/* This routine draws an arc and clips it to a circle. It's hard to figure + * out how it works without looking at the piece of scratch paaper I have + * in front of me, so let's hope it doesn't break... + * Converted to all doubles for CRAYs + */ + +static double +cliparc(double cx, double cy, double rad, double start, double end, int iclipx, int iclipy, int icliprad, int flag) +{ + double clipx, clipy, cliprad; + double sclip = 0.0, eclip = 0.0; + double x, y, tx, ty, dist; + double alpha, theta, phi, a1, a2, d, l; + bool in; + + clipx = (double) iclipx; + clipy = (double) iclipy; + cliprad = (double) icliprad; + x = cx - clipx; + y = cy - clipy; + dist = sqrt((double) (x * x + y * y)); + + if (!rad || !cliprad) + return(-1); + if (dist + rad < cliprad) { + /* The arc is entirely in the boundary. */ + Arc((int)cx, (int)cy, (int)rad, start, end); + return(flag?start:end); + } else if ((dist - rad >= cliprad) || (rad - dist >= cliprad)) { + /* The arc is outside of the boundary. */ + return(-1); + } + /* Now let's figure out the angles at which the arc crosses the + * circle. We know dist != 0. + */ + if (x) + phi = atan2((double) y, (double) x); + else if (y > 0) + phi = M_PI * 1.5; + else + phi = M_PI / 2; + if (cx > clipx) + theta = M_PI + phi; + else + theta = phi; + + alpha = (double) (dist * dist + rad * rad - cliprad * cliprad) / + (2 * dist * rad); + + /* Sanity check */ + if (alpha > 1.0) + alpha = 0.0; + else if (alpha < -1.0) + alpha = M_PI; + else + alpha = acos(alpha); + + a1 = theta + alpha; + a2 = theta - alpha; + while (a1 < 0) + a1 += M_PI * 2; + while (a2 < 0) + a2 += M_PI * 2; + while (a1 >= M_PI * 2) + a1 -= M_PI * 2; + while (a2 >= M_PI * 2) + a2 -= M_PI * 2; + + tx = cos(start) * rad + x; + ty = sin(start) * rad + y; + d = sqrt((double) tx * tx + ty * ty); + in = (d > cliprad) ? FALSE : TRUE; + + /* Now begin with start. If the point is in, draw to either end, a1, + * or a2, whichever comes first. + */ + d = M_PI * 3; + if ((end < d) && (end > start)) + d = end; + if ((a1 < d) && (a1 > start)) + d = a1; + if ((a2 < d) && (a2 > start)) + d = a2; + if (d == M_PI * 3) { + d = end; + if (a1 < d) + d = a1; + if (a2 < d) + d = a2; + } + + if (in) { + if (start > d) { + double tmp; + tmp = start; + start = d; + d = tmp; + } + Arc((int)cx, (int)cy, (int)rad, start, d); + sclip = start; + eclip = d; + } + if (d == end) + return(flag?sclip:eclip); + if (a1 != a2) + in = in ? FALSE : TRUE; + + /* Now go from here to the next point. */ + l = d; + d = M_PI * 3; + if ((end < d) && (end > l)) + d = end; + if ((a1 < d) && (a1 > l)) + d = a1; + if ((a2 < d) && (a2 > l)) + d = a2; + if (d == M_PI * 3) { + d = end; + if (a1 < d) + d = a1; + if (a2 < d) + d = a2; + } + + if (in) { + Arc((int)cx, (int)cy, (int)rad, l, d); + sclip = l; + eclip = d; + } + if (d == end) + return(flag?sclip:eclip); + in = in ? FALSE : TRUE; + + /* And from here to the end. */ + if (in) { + Arc((int)cx, (int)cy, (int)rad, d, end); + /* special case */ + if (flag != 2) { + sclip = d; + eclip = end; + } + } + return(flag%2?sclip:eclip); +} diff --git a/src/frontend/plotting/grid.h b/src/frontend/plotting/grid.h new file mode 100644 index 000000000..44db7c411 --- /dev/null +++ b/src/frontend/plotting/grid.h @@ -0,0 +1,18 @@ +/************* + * Header file for grid.c + * 1999 E. Rouat + ************/ + +#ifndef GRID_H_INCLUDED +#define GRID_H_INCLUDED + +typedef enum { x_axis, y_axis } Axis; + +void gr_fixgrid(GRAPH *graph, double xdelta, double ydelta, int xtype, int ytype); +void gr_redrawgrid(GRAPH *graph); +void drawlingrid(GRAPH *graph, char *units, int spacing, int nsp, double dst, double lmt, + double hmt, bool onedec, int mult, double mag, int digits, Axis axis); +void drawloggrid(GRAPH *graph, char *units, int hmt, int lmt, int decsp, int subs, + int pp, Axis axis); + +#endif diff --git a/src/frontend/plotting/plot5.c b/src/frontend/plotting/plot5.c new file mode 100644 index 000000000..25281c566 --- /dev/null +++ b/src/frontend/plotting/plot5.c @@ -0,0 +1,180 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +**********/ + +#include +#include +#include + +#include "plot5.h" + +static FILE *plotfile; + +#define putsi(a) putc((char) (a), plotfile); \ + putc((char) ((a) >> 8), plotfile) + +#define SOLID 0 +static char *linestyle[] = { "solid", "dotted", "longdashed", "shortdashed", + "dotdashed" }; +static int currentlinestyle = SOLID; + + +extern void gr_relinestyle (GRAPH *graph); +extern void internalerror (char *message); + +int +Plt5_Init(void) +{ + + dispdev->numlinestyles = 4; + dispdev->numcolors = 2; + + /* arbitrary */ + dispdev->width = 1000; + dispdev->height = 1000; + + return(0); + +} + +int +Plt5_NewViewport(GRAPH *graph) +{ + + if (!(plotfile = fopen(graph->devdep, "w"))) { + graph->devdep = (char *) NULL; + perror(graph->devdep); + return(1); + } + + if (graph->absolute.width) { + + /* hardcopying from the scree, + ie, we are passed a copy of an existing graph */ + putc('s', plotfile); + putsi(0); + putsi(0); + putsi(graph->absolute.width); + putsi(graph->absolute.height); + + /* re-scale linestyles */ + gr_relinestyle(graph); + + } else { + /* scale space */ + putc('s', plotfile); + putsi(0); + putsi(0); + putsi(dispdev->width); + putsi(dispdev->height); + + /* reasonable values, used in gr_ for placement */ + graph->fontwidth = 12; + graph->fontheight = 24; + + graph->absolute.width = dispdev->width; + graph->absolute.height = dispdev->height; + + } + + /* set to NULL so graphdb doesn't incorrectly de-allocate it */ + graph->devdep = (char *) NULL; + + return(0); + +} + +void +Plt5_Close(void) +{ + + /* in case Plt5_Close is called as part of an abort, + w/o having reached Plt5_NewViewport */ + if (plotfile) + fclose(plotfile); + +} + +void +Plt5_Clear(void) +{ + + /* do nothing */ + +} + +void +Plt5_DrawLine(int x1, int y1, int x2, int y2) +{ + + putc('l', plotfile); + putsi(x1); + putsi(y1); + putsi(x2); + putsi(y2); + +} + +/* ARGSUSED */ /* until some code gets written */ +void +Plt5_Arc(int x0, int y0, int radius, double theta1, double theta2) +{ + + +} + +void +Plt5_Text(char *text, int x, int y) +{ + + int savedlstyle; + + /* set linestyle to solid + or may get funny color text on some plotters */ + savedlstyle = currentlinestyle; + Plt5_SetLinestyle(SOLID); + + /* move to (x, y) */ + putc('m', plotfile); + putsi(x); + putsi(y); + + /* use the label option */ + fprintf(plotfile, "t%s\n", text); + + /* restore old linestyle */ + Plt5_SetLinestyle(savedlstyle); + +} + +int +Plt5_SetLinestyle(int linestyleid) +{ + + if (linestyleid < 0 || linestyleid > dispdev->numlinestyles) { + internalerror("bad linestyleid"); + return 0; + } + putc('f', plotfile); + fprintf(plotfile, "%s\n", linestyle[linestyleid]); + currentlinestyle = linestyleid; + return 0; +} + +/* ARGSUSED */ +void +Plt5_SetColor(int colorid) +{ + + /* do nothing */ + +} + +void +Plt5_Update(void) +{ + + fflush(plotfile); + +} + diff --git a/src/frontend/plotting/plot5.h b/src/frontend/plotting/plot5.h new file mode 100644 index 000000000..4b4e68528 --- /dev/null +++ b/src/frontend/plotting/plot5.h @@ -0,0 +1,20 @@ +/************* + * Header file for plot5.c + * 1999 E. Rouat + ************/ + +#ifndef PLOT5_H_INCLUDED +#define PLOT5_H_INCLUDED + +int Plt5_Init(void); +int Plt5_NewViewport(GRAPH *graph); +void Plt5_Close(void); +void Plt5_Clear(void); +void Plt5_DrawLine(int x1, int y1, int x2, int y2); +void Plt5_Arc(int x0, int y0, int radius, double theta1, double theta2); +void Plt5_Text(char *text, int x, int y); +int Plt5_SetLinestyle(int linestyleid); +void Plt5_SetColor(int colorid); +void Plt5_Update(void); + +#endif diff --git a/src/frontend/plotting/plotcurv.c b/src/frontend/plotting/plotcurv.c new file mode 100644 index 000000000..0883f8c0a --- /dev/null +++ b/src/frontend/plotting/plotcurv.c @@ -0,0 +1,343 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* + * Curve plotting routines and general (non-graphics) plotting things. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "plotcurv.h" + + +static void plotinterval(struct dvec *v, double lo, double hi, register double *coeffs, + int degree, bool rotated); + + +/* Plot the vector v, with scale xs. If we are doing curve-fitting, then + * do some tricky stuff. + */ + +void +ft_graf(struct dvec *v, struct dvec *xs, bool nostart) +{ + int degree, gridsize, length; + register int i, j, l; + double *scratch, *result, *gridbuf, *mm; + register double *xdata, *ydata; + bool rot, increasing = FALSE; + double dx = 0.0, dy = 0.0, lx = 0.0, ly = 0.0; + int dir; + + /* if already started, use saved degree */ + if (nostart) { + degree = currentgraph->degree; + } else { + if (!cp_getvar("polydegree", VT_NUM, (char *) °ree)) + degree = 1; + currentgraph->degree = degree; + } + if (degree > v->v_length) + degree = v->v_length; + if (degree < 1) { + fprintf(cp_err, "Error: polydegree is %d, can't plot...\n", + degree); + return; + } + + if (!cp_getvar("gridsize", VT_NUM, (char *) &gridsize)) + gridsize = 0; + if ((gridsize < 0) || (gridsize > 10000)) { + fprintf(cp_err, "Error: bad grid size %d\n", gridsize); + return; + } + if (gridsize && xs) { + if( isreal(xs) ) { + increasing = (xs->v_realdata[0] < xs->v_realdata[1]); + for (i = 0; i < xs->v_length - 1; i++) + if (increasing != (xs->v_realdata[i] < + xs->v_realdata[i + 1])) { + fprintf(cp_err, + "Warning: scale not monotonic, gridsize not relevant.\n"); + gridsize = 0; + break; + } + } else { + increasing = (realpart (&xs->v_compdata[0]) < + realpart( &xs->v_compdata[1])); + for (i = 0; i < xs->v_length - 1; i++) + if (increasing != (realpart( &xs->v_compdata[i]) < + realpart( &xs->v_compdata[i + 1]))) { + fprintf(cp_err, + "Warning: scale not monotonic, gridsize not relevant.\n"); + gridsize = 0; + break; + } + } + } + + if (!nostart) + gr_start(v); + + /* Do the one value case */ + + if (!xs) { + for (i = 0; i < v->v_length; i++) { + +/* We should do the one - point case too! + * Important for pole-zero for example + */ + if( v->v_length == 1 ) { + j = 0; + } else { + j = i-1; + if( i == 0 ) + continue; + } + + if (isreal(v)) { + /* This isn't good but we may as well do + * something useful. + */ + gr_point(v, v->v_realdata[i], + v->v_realdata[i], + v->v_realdata[j], + v->v_realdata[j], (j==i ? 1 : i)); + } else { + gr_point(v, realpart(&v->v_compdata[i]), + imagpart(&v->v_compdata[i]), + realpart(&v->v_compdata[j]), + imagpart(&v->v_compdata[j]), (j==i ? 1 : i)); + } + } + gr_end(v); + return; + } + + xs->v_flags |= VF_PERMANENT; + + /* First check the simple case, where we don't have to do any + * interpolation. + */ + if ((degree == 1) && (gridsize == 0)) { + dir = 0; + for (i = 0, j = v->v_length; i < j; i++) { + dx = isreal(xs) ? xs->v_realdata[i] : + realpart(&xs->v_compdata[i]); + dy = isreal(v) ? v->v_realdata[i] : + realpart(&v->v_compdata[i]); + if ((i == 0 || (dir > 0 ? lx > dx : dir < 0 ? lx < dx : 0)) + && xs->v_plot->pl_scale == xs) + { + gr_point(v, dx, dy, lx, ly, 0); + } else { + gr_point(v, dx, dy, lx, ly, i); + if (!dir) + dir = lx > dx ? -1 : lx < dx ? 1 : 0; + } + lx = dx; + ly = dy; + } + if (v->v_length == 1) + gr_point(v, dx, dy, lx, ly, 1); + gr_end(v); + return; + } + + if (gridsize < degree + 1) + gridsize = 0; + + if (gridsize) { + /* This is done quite differently from what we do below... */ + gridbuf = (double *) tmalloc(gridsize * sizeof (double)); + result = (double *) tmalloc(gridsize * sizeof (double)); + if (isreal(v)) + ydata = v->v_realdata; + else { + ydata = (double *) tmalloc(v->v_length * + sizeof (double)); + for (i = 0; i < v->v_length; i++) + ydata[i] = realpart(&v->v_compdata[i]); + } + if (isreal(xs)) + xdata = xs->v_realdata; + else { + xdata = (double *) tmalloc(xs->v_length * + sizeof (double)); + for (i = 0; i < xs->v_length; i++) + xdata[i] = realpart(&xs->v_compdata[i]); + } + + mm = ft_minmax(xs, TRUE); + dx = (mm[1] - mm[0]) / gridsize; + if (increasing) + for (i = 0, dy = mm[0]; i < gridsize; i++, dy += dx) + gridbuf[i] = dy; + else + for (i = 0, dy = mm[1]; i < gridsize; i++, dy -= dx) + gridbuf[i] = dy; + if (!ft_interpolate(ydata, result, xdata, v->v_length, gridbuf, + gridsize, degree)) { + fprintf(cp_err, "Error: can't put %s on gridsize %d\n", + v->v_name, gridsize); + return; + } + /* Now this is a problem. There's no way that we can + * figure out where to put the tic marks to correspond with + * the actual data... + */ + for (i = 0; i < gridsize; i++) + gr_point(v, gridbuf[i], result[i], gridbuf[i ? (i - 1) + : i], result[i ? (i - 1) : i], -1); + gr_end(v); + tfree(gridbuf); + tfree(result); + if (!isreal(v)) + tfree(ydata); + if (!isreal(xs)) + tfree(xdata); + return; + } + + /* We need to do curve fitting now. First get some scratch + * space + */ + 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)); + + + /* Plot the first degree segments... */ + if (isreal(v)) + bcopy((char *) v->v_realdata, (char *) ydata, + (degree + 1) * sizeof (double)); + else + for (i = 0; i <= degree; i++) + ydata[i] = realpart(&v->v_compdata[i]); + if (isreal(xs)) + bcopy((char *) xs->v_realdata, (char *) xdata, + (degree + 1) * sizeof (double)); + else + for (i = 0; i <= degree; i++) + xdata[i] = realpart(&xs->v_compdata[i]); + + rot = FALSE; + while (!ft_polyfit(xdata, ydata, result, degree, scratch)) { + /* Rotate the coordinate system 90 degrees and try again. + * If it doesn't work this time, bump the interpolation + * degree down by one... + */ + if (ft_polyfit(ydata, xdata, result, degree, scratch)) { + rot = TRUE; + break; + } + if (--degree == 0) { + fprintf(cp_err, "plotcurve: Internal Error: ack...\n"); + return; + } + } + + /* Plot this part of the curve... */ + for (i = 0; i < degree; i++) + if (rot) + plotinterval(v, ydata[i], ydata[i + 1], result, degree, + TRUE); + else + plotinterval(v, xdata[i], xdata[i + 1], result, degree, + FALSE); + + /* Now plot the rest, piece by piece... l is the + * last element under consideration. + */ + length = v->v_length; + for (l = degree + 1; l < length; 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]; + } + if (isreal(v)) + ydata[i] = v->v_realdata[l]; + else + ydata[i] = realpart(&v->v_compdata[l]); + if (isreal(xs)) + xdata[i] = xs->v_realdata[l]; + else + xdata[i] = realpart(&xs->v_compdata[l]); + + rot = FALSE; + while (!ft_polyfit(xdata, ydata, result, degree, scratch)) { + if (ft_polyfit(ydata, xdata, result, degree, scratch)) { + rot = TRUE; + break; + } + if (--degree == 0) { + fprintf(cp_err, + "plotcurve: Internal Error: ack...\n"); + return; + } + } + if (rot) + plotinterval(v, ydata[degree - 1], ydata[degree], + result, degree, TRUE); + else + plotinterval(v, xdata[degree - 1], xdata[degree], + result, degree, FALSE); + } + tfree(scratch); + tfree(xdata); + tfree(ydata); + tfree(result); + gr_end(v); + return; +} + +#define GRANULARITY 10 + +static void +plotinterval(struct dvec *v, double lo, double hi, register double *coeffs, int degree, bool rotated) +{ + double incr, dx, dy, lx, ly; + register int i; + int steps; + + /* + fprintf(cp_err, "plotinterval(%s, %G, %G, [ ", v->v_name, lo, hi); + for (i = 0; i <= degree; i++) + fprintf(cp_err, "%G ", coeffs[i]); + fprintf(cp_err, "], %d, %s)\n\r", degree, rotated ? "TRUE" : "FALSE"); + */ + + /* This is a problem -- how do we know what granularity to use? If + * the guy cares about this he will use gridsize. + */ + if (!cp_getvar("polysteps", VT_NUM, (char *) &steps)) + steps = GRANULARITY; + + incr = (hi - lo) / (double) (steps + 1); + dx = lo + incr; + lx = lo; + ly = ft_peval(lo, coeffs, degree); + for (i = 0; i <= steps; i++, dx += incr) { + dy = ft_peval(dx, coeffs, degree); + if (rotated) + gr_point(v, dy, dx, ly, lx, -1); + else + gr_point(v, dx, dy, lx, ly, -1); + lx = dx; + ly = dy; + /* fprintf(cp_err, "plot (%G, %G)\n\r", dx, dy); */ + } + return; +} diff --git a/src/frontend/plotting/plotcurv.h b/src/frontend/plotting/plotcurv.h new file mode 100644 index 000000000..5f466cc6d --- /dev/null +++ b/src/frontend/plotting/plotcurv.h @@ -0,0 +1,12 @@ +/************* + * Header file for plotcurv.c + * 1999 E. Rouat + ************/ + +#ifndef PLOTCURV_H_INCLUDED +#define PLOTCURV_H_INCLUDED + +void ft_graf(struct dvec *v, struct dvec *xs, bool nostart); + + +#endif diff --git a/src/frontend/plotting/plotit.c b/src/frontend/plotting/plotit.c new file mode 100644 index 000000000..f7327e0d6 --- /dev/null +++ b/src/frontend/plotting/plotit.c @@ -0,0 +1,981 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "plotit.h" +#include "agraf.h" +#include "xgraph.h" +#include "graf.h" + +static wordlist *wl_root; +static bool sameflag; + +#ifdef TCL_MODULE +#include +#endif + + +/* This routine gets parameters from the command line, which are of + * the form "name number ..." It returns a pointer to the parameter + * values. */ +static double * +getlims(wordlist *wl, char *name, int number) +{ + double *d, *td; + wordlist *beg, *wk; + char *ss; + int n; + + for (beg = wl; beg; beg = beg->wl_next) { + if (eq(beg->wl_word, name)) { + if (beg == wl) { + fprintf(cp_err, + "Syntax error: looking for plot parameters \"%s\".\n", + name); + return (NULL); + } + wk = beg; + if (number) { + d = (double *) tmalloc(sizeof (double) * + number); + for (n = 0; n < number; n++) { + wk = wk->wl_next; + if (!wk) { + fprintf(cp_err, + "Syntax error: not enough parameters for \"%s\".\n", + name); + return (NULL); + } + ss = wk->wl_word; + td = ft_numparse(&ss, FALSE); + if (td == NULL) + goto bad; + d[n] = *td; + } + } else + /* Minor hack... */ + d = (double *) 1; + + if (beg->wl_prev) + beg->wl_prev->wl_next = wk->wl_next; + if (wk->wl_next) { + wk->wl_next->wl_prev = beg->wl_prev; + wk->wl_next = NULL; + } + if (beg != wl_root) + wl_free(beg); + return (d); + } + } + return (NULL); +bad: + fprintf(cp_err, "Syntax error: bad parameters for \"%s\".\n", name); + return (NULL); +} + + + +/* Extend a data vector to length by replicating the last element, or + * truncate it if it is too long. */ +static void +xtend(struct dvec *v, int length) +{ + int i; + complex c, *oc; + double d, *od; + + if (v->v_length == length) + return; + if (v->v_length > length) { + v->v_length = length; + return; + } + if (isreal(v)) { + od = v->v_realdata; + v->v_realdata = (double *) tmalloc(length * sizeof (double)); + for (i = 0; i < v->v_length; i++) + v->v_realdata[i] = od[i]; + d = od[--i]; + while (i < length) + v->v_realdata[i++] = d; + tfree(od); + } else { + oc = v->v_compdata; + v->v_compdata = (complex *) tmalloc(length * sizeof (complex)); + for (i = 0; i < v->v_length; i++) { + realpart(&v->v_compdata[i]) = realpart(&oc[i]); + imagpart(&v->v_compdata[i]) = imagpart(&oc[i]); + } + realpart(&c) = realpart(&oc[--i]); + imagpart(&c) = imagpart(&oc[i]); + while (i < length) { + realpart(&v->v_compdata[i]) = realpart(&c); + imagpart(&v->v_compdata[i++]) = imagpart(&c); + tfree(oc); + } + } + v->v_length = length; + return; +} + + +/* Collapse every *xcomp elements into one, and use only the elements + * between xind[0] and xind[1]. + */ + +static void +compress(struct dvec *d, double *xcomp, double *xind) +{ + int cfac, ihi, ilo, newlen, i; + int sz = isreal(d) ? sizeof (double) : sizeof (complex); + double *dd; + complex *cc; + + if (xind) { + ilo = (int) xind[0]; + ihi = (int) xind[1]; + if ((ilo <= ihi) && (ilo > 0) && (ilo < d->v_length) && + (ihi > 1) && (ihi <= d->v_length)) { + newlen = ihi - ilo; + dd = (double *) tmalloc(newlen * sz); + cc = (complex *) dd; + if (isreal(d)) { + bcopy((char *) (d->v_realdata + ilo), + (char *) dd, newlen * sz); + tfree(d->v_realdata); + d->v_realdata = dd; + } else { + bcopy((char *) (d->v_compdata + ilo), + (char *) cc, newlen * sz); + tfree(d->v_compdata); + d->v_compdata = cc; + } + d->v_length = newlen; + } + } + + if (xcomp) { + cfac = (int) *xcomp; + if ((cfac > 1) && (cfac < d->v_length)) { + for (i = 0; i * cfac < d->v_length; i++) + if (isreal(d)) + d->v_realdata[i] = + d->v_realdata[i * cfac]; + else + d->v_compdata[i] = + d->v_compdata[i * cfac]; + d->v_length = i; + } + } + return; +} + + +/* Check for and remove a one-word keyword. */ +static bool +getflag(wordlist *wl, char *name) +{ + while (wl) { + if (eq(wl->wl_word, name)) { + if (wl->wl_prev) + wl->wl_prev->wl_next = wl->wl_next; + if (wl->wl_next) + wl->wl_next->wl_prev = wl->wl_prev; + return (TRUE); + } + wl = wl->wl_next; + } + return (FALSE); +} + + +/* Return a parameter of the form "xlabel foo" */ +static char * +getword(wordlist *wl, char *name) +{ + wordlist *beg; + char *s; + + for (beg = wl; beg; beg = beg->wl_next) { + if (eq(beg->wl_word, name)) { + if ((beg == wl) || !beg->wl_next) { + fprintf(cp_err, + "Syntax error: looking for plot keyword at \"%s\".\n", + name); + return (NULL); + } + s = copy(beg->wl_next->wl_word); + beg->wl_prev->wl_next = beg->wl_next->wl_next; + if (beg->wl_next->wl_next) + beg->wl_next->wl_next->wl_prev = beg->wl_prev; + beg->wl_next->wl_next = NULL; + wl_free(beg); + return (s); + } + } + return (NULL); +} + + +/* The common routine for all plotting commands. This does hardcopy + * and graphics plotting. */ +bool +plotit(wordlist *wl, char *hcopy, char *devname) +{ + /* All these things are static so that "samep" will work. */ + static double *xcompress = NULL, *xindices = NULL; + static double *xlim = NULL, *ylim = NULL; + static double *xdelta = NULL, *ydelta = NULL; + static char *xlabel = NULL, *ylabel = NULL, *title = NULL; + static bool nointerp = FALSE; + static GRIDTYPE gtype = GRID_LIN; + static PLOTTYPE ptype = PLOT_LIN; + + bool gfound = FALSE, pfound = FALSE, oneval = FALSE; + double *dd, ylims[2], xlims[2]; + struct pnode *n, *names; + struct dvec *dv, *d = NULL, *vecs = NULL, *lv, *lastvs = NULL; + char *xn; + int i, j, xt; + double tt, mx, my, rad; + wordlist *wwl, *tw; + char cline[BSIZE_SP], buf[BSIZE_SP], *pname; + + int newlen; + struct dvec *v, *newv_scale; + double *newdata, *newscale; + double tstep, tstart, tstop, ttime; + + if (!wl) + return FALSE; + wl_root = wl; + + /* First get the command line, without the limits. */ + wwl = wl_copy(wl); + (void) getlims(wwl, "xl", 2); + (void) getlims(wwl, "xlimit", 2); + (void) getlims(wwl, "yl", 2); + (void) getlims(wwl, "ylimit", 2); + (void) sprintf(cline, "plot %s", wl_flatten(wwl)); + + wl_free(wwl); + + /* Now extract all the parameters. */ + + /* In case the parameter is the first on the line, we need a + * "buffer" word... + */ + tw = alloc(struct wordlist); + wl->wl_prev = tw; + tw->wl_next = wl; + wl = tw; + tw->wl_word = ""; + + sameflag = getflag(wl, "samep"); + + if (!sameflag || !xlim) { + xlim = getlims(wl, "xl", 2); + if (!xlim) + xlim = getlims(wl, "xlimit", 2); + } else { + (void) getlims(wl, "xl", 2); + (void) getlims(wl, "xlimit", 2); + } + + if (!sameflag || !ylim) { + ylim = getlims(wl, "yl", 2); + if (!ylim) + ylim = getlims(wl, "ylimit", 2); + } else { + (void) getlims(wl, "yl", 2); + (void) getlims(wl, "ylimit", 2); + } + + if (!sameflag || !xcompress) { + xcompress = getlims(wl, "xcompress", 1); + if (!xcompress) + xcompress = getlims(wl, "xcomp", 1); + } else { + (void) getlims(wl, "xcompress", 1); + (void) getlims(wl, "xcomp", 1); + } + + if (!sameflag || !xindices) { + xindices = getlims(wl, "xindices", 2); + if (!xindices) + xindices = getlims(wl, "xind", 2); + } else { + (void) getlims(wl, "xindices", 2); + (void) getlims(wl, "xind", 2); + } + + if (!sameflag || !xdelta) { + xdelta = getlims(wl, "xdelta", 1); + if (!xdelta) + xdelta = getlims(wl, "xdel", 1); + } else { + (void) getlims(wl, "xdelta", 1); + (void) getlims(wl, "xdel", 1); + } + if (!sameflag || !ydelta) { + ydelta = getlims(wl, "ydelta", 1); + if (!ydelta) + ydelta = getlims(wl, "ydel", 1); + } else { + (void) getlims(wl, "ydelta", 1); + (void) getlims(wl, "ydel", 1); + } + + /* Get the grid type and the point type. Note we can't do if-else + * here because we want to catch all the grid types. + */ + if (getflag(wl, "lingrid")) { + if (gfound) + fprintf(cp_err, + "Warning: too many grid types given\n"); + else { + gtype = GRID_LIN; + gfound = TRUE; + } + } + if (getflag(wl, "loglog")) { + if (gfound) + fprintf(cp_err, + "Warning: too many grid types given\n"); + else { + gtype = GRID_LOGLOG; + gfound = TRUE; + } + } + if (getflag(wl, "nogrid")) { + if (gfound) + fprintf(cp_err, + "Warning: too many grid types given\n"); + else { + gtype = GRID_NONE; + gfound = TRUE; + } + } + if (getflag(wl, "linear")) { + if (gfound) + fprintf(cp_err, + "Warning: too many grid types given\n"); + else { + gtype = GRID_LIN; + gfound = TRUE; + } + } + if (getflag(wl, "xlog")) { + if (gfound) + fprintf(cp_err, + "Warning: too many grid types given\n"); + else { + gtype = GRID_XLOG; + gfound = TRUE; + } + } + if (getflag(wl, "ylog")) { + if (gfound) + fprintf(cp_err, + "Warning: too many grid types given\n"); + else { + gtype = GRID_YLOG; + gfound = TRUE; + } + } + if (getflag(wl, "polar")) { + if (gfound) + fprintf(cp_err, + "Warning: too many grid types given\n"); + else { + gtype = GRID_POLAR; + gfound = TRUE; + } + } + if (getflag(wl, "smith")) { + if (gfound) + fprintf(cp_err, + "Warning: too many grid types given\n"); + else { + gtype = GRID_SMITH; + gfound = TRUE; + } + } + if (getflag(wl, "smithgrid")) { + if (gfound) + fprintf(cp_err, + "Warning: too many grid types given\n"); + else { + gtype = GRID_SMITHGRID; + gfound = TRUE; + } + } + + if (!sameflag && !gfound) { + if (cp_getvar("gridstyle", VT_STRING, buf)) { + if (eq(buf, "lingrid")) + gtype = GRID_LIN; + else if (eq(buf, "loglog")) + gtype = GRID_LOGLOG; + else if (eq(buf, "xlog")) + gtype = GRID_XLOG; + else if (eq(buf, "ylog")) + gtype = GRID_YLOG; + else if (eq(buf, "smith")) + gtype = GRID_SMITH; + else if (eq(buf, "smithgrid")) + gtype = GRID_SMITHGRID; + else if (eq(buf, "polar")) + gtype = GRID_POLAR; + else if (eq(buf, "nogrid")) + gtype = GRID_NONE; + else { + fprintf(cp_err, + "Warning: strange grid type %s\n", + buf); + gtype = GRID_LIN; + } + gfound = TRUE; + } else + gtype = GRID_LIN; + } + + /* Now get the point type. */ + + if (getflag(wl, "linplot")) { + if (pfound) + fprintf(cp_err, + "Warning: too many plot types given\n"); + else { + ptype = PLOT_LIN; + pfound = TRUE; + } + } + if (getflag(wl, "combplot")) { + if (pfound) + fprintf(cp_err, + "Warning: too many plot types given\n"); + else { + ptype = PLOT_COMB; + pfound = TRUE; + } + } + if (getflag(wl, "pointplot")) { + if (pfound) + fprintf(cp_err, + "Warning: too many plot types given\n"); + else { + ptype = PLOT_POINT; + pfound = TRUE; + } + } + + if (!sameflag && !pfound) { + if (cp_getvar("plotstyle", VT_STRING, buf)) { + if (eq(buf, "linplot")) + ptype = PLOT_LIN; + else if (eq(buf, "combplot")) + ptype = PLOT_COMB; + else if (eq(buf, "pointplot")) + ptype = PLOT_POINT; + else { + fprintf(cp_err, + "Warning: strange plot type %s\n", + buf); + ptype = PLOT_LIN; + } + pfound = TRUE; + } else + ptype = PLOT_LIN; + } + + if (!sameflag || !xlabel) + xlabel = getword(wl, "xlabel"); + else + (void) getword(wl, "xlabel"); + if (!sameflag || !ylabel) + ylabel = getword(wl, "ylabel"); + else + (void) getword(wl, "ylabel"); + if (!sameflag || !title) + title = getword(wl, "title"); + else + (void) getword(wl, "title"); + + if (!sameflag) + nointerp = getflag(wl, "nointerp"); + else if (getflag(wl, "nointerp")) + nointerp = TRUE; + + wl = wl->wl_next; + if (!wl) { + fprintf(cp_err, "Error: no vectors given\n"); + return (FALSE); + } + + wl->wl_prev = NULL; + + /* Now parse the vectors. We have a list of the form + * "a b vs c d e vs f g h". Since it's a bit of a hassle for + * us to parse the vector boundaries here, we do this -- call + * ft_getpnames() without the check flag, and then look for 0-length + * vectors with the name "vs"... This is a sort of a gross hack, + * since we have to check for 0-length vectors ourselves after + * evaulating the pnodes... + */ + + names = ft_getpnames(wl, FALSE); + if (names == NULL) + return (FALSE); + + /* Now evaluate the names. */ + for (n = names, lv = NULL; n; n = n->pn_next) { + if (n->pn_value && (n->pn_value->v_length == 0) && + eq(n->pn_value->v_name, "vs")) { + if (!lv) { + fprintf(cp_err, "Error: misplaced vs arg\n"); + return (FALSE); + } else { + if (!(n = n->pn_next)) { + fprintf(cp_err, + "Error: missing vs arg\n"); + return (FALSE); + } + dv = ft_evaluate(n); + if (!dv) + return (FALSE); + if (lastvs) + lv = lastvs->v_link2; + else + lv = vecs; + while (lv) { + lv->v_scale = dv; + lastvs = lv; + lv = lv->v_link2; + } + } + continue; + } + dv = ft_evaluate(n); + if (!dv) + return (FALSE); + if (!d) + vecs = dv; + else + d->v_link2 = dv; + for (d = dv; d->v_link2; d = d->v_link2) + ; + lv = dv; + } + free_pnode(names); + d->v_link2 = NULL; + + /* Now check for 0-length vectors. */ + for (d = vecs; d; d = d->v_link2) + if (!d->v_length) { + fprintf(cp_err, "Error: %s: no such vector\n", + d->v_name); + return (FALSE); + } + + /* If there are higher dimensional vectors, transform them into a + * family of vectors. + */ + for (d = vecs, lv = NULL; d; d = d->v_link2) { + if (d->v_numdims > 1) { + if (lv) + lv->v_link2 = vec_mkfamily(d); + else + vecs = lv = vec_mkfamily(d); + while (lv->v_link2) + lv = lv->v_link2; + lv->v_link2 = d->v_link2; + d = lv; + } else { + lv = d; + } + } + + /* Now fill in the scales for vectors who aren't already fixed up. */ + for (d = vecs; d; d = d->v_link2) + if (!d->v_scale) { + if (d->v_plot->pl_scale) + d->v_scale = d->v_plot->pl_scale; + else + d->v_scale = d; + } + + + /* See if the log flag is set anywhere... */ + if (!gfound) { + for (d = vecs; d; d = d->v_link2) + if (d->v_scale && (d->v_scale->v_gridtype == GRID_XLOG)) + gtype = GRID_XLOG; + for (d = vecs; d; d = d->v_link2) + if (d->v_gridtype == GRID_YLOG) { + if ((gtype == GRID_XLOG) || + (gtype == GRID_LOGLOG)) + gtype = GRID_LOGLOG; + else + gtype = GRID_YLOG; + } + for (d = vecs; d; d = d->v_link2) + if (d->v_gridtype == GRID_SMITH || d->v_gridtype == GRID_SMITHGRID + || d->v_gridtype == GRID_POLAR) + { + gtype = d->v_gridtype; + break; + } + } + + /* See if there are any default plot types... Here, like above, we + * don't do entirely the best thing when there is a mixed set of + * default plot types... + */ + if (!sameflag && !pfound) { + ptype = PLOT_LIN; + for (d = vecs; d; d = d->v_link2) + if (d->v_plottype != PLOT_LIN) { + ptype = d->v_plottype; + break; + } + } + + /* Check and see if this is pole zero stuff. */ + if ((vecs->v_type == SV_POLE) || (vecs->v_type == SV_ZERO)) + oneval = TRUE; + + for (d = vecs; d; d = d->v_link2) + if (((d->v_type == SV_POLE) || (d->v_type == SV_ZERO)) != + oneval ? 1 : 0) { + fprintf(cp_err, +"Error: plot must be either all pole-zero or contain no poles or zeros\n"); + return (FALSE); + } + + if ((gtype == GRID_POLAR) || (gtype == GRID_SMITH + || gtype == GRID_SMITHGRID)) + { + oneval = TRUE; + } + + /* If we are plotting scalars, make sure there is enough + * data to fit on the screen. + */ + + for (d = vecs; d; d = d->v_link2) + if (d->v_length == 1) + xtend(d, d->v_scale->v_length); + + /* Now patch up each vector with the compression and thestrchr + * selection. + */ + if (xcompress || xindices) { + for (d = vecs; d; d = d->v_link2) { + compress(d, xcompress, xindices); + d->v_scale = vec_copy(d->v_scale); + compress(d->v_scale, xcompress, xindices); + } + } + + /* Transform for smith plots */ + if (gtype == GRID_SMITH) { + double re, im, rex, imx; + double r, i, x; + struct dvec **prevvp, *n; + int j; + + prevvp = &vecs; + for (d = vecs; d; d = d->v_link2) { + if (d->v_flags & VF_PERMANENT) { + n = vec_copy(d); + n->v_flags &= ~VF_PERMANENT; + n->v_link2 = d->v_link2; + d = n; + *prevvp = d; + } + prevvp = &d->v_link2; + + if (isreal(d)) { + fprintf(cp_err, + "Warning: plotting real data \"%s\" on a smith grid\n", + d->v_name); + + for (j = 0; j < d->v_length; j++) { + r = d->v_realdata[j]; + d->v_realdata[j] = (r - 1) / (r + 1); + } + } else { + for (j = 0; j < d->v_length; j++) { + /* (re - 1, im) / (re + 1, im) */ + + re = realpart(d->v_compdata + j); + im = imagpart(d->v_compdata + j); + + rex = re + 1; + imx = im; + re = re - 1; + + /* (re, im) / (rex, imx) */ + x = 1 - (imx / rex) * (imx / rex); + r = re / rex + im / rex * imx / rex; + i = im / rex - re / rex * imx / rex; + + realpart(d->v_compdata + j) = r / x; + imagpart(d->v_compdata + j) = i / x; + } + } + } + } + + /* Figure out the proper x- and y-axis limits. */ + if (ylim) { + ylims[0] = ylim[0]; + ylims[1] = ylim[1]; + } else if (oneval) { + ylims[0] = HUGE; + ylims[1] = - ylims[0]; + for (d = vecs; d; d = d->v_link2) { + dd = ft_minmax(d, TRUE); + if (dd[0] < ylims[0]) + ylims[0] = dd[0]; + if (dd[1] > ylims[1]) + ylims[1] = dd[1]; + } + } else { + ylims[0] = HUGE; + ylims[1] = - ylims[0]; + for (d = vecs; d; d = d->v_link2) { + dd = ft_minmax(d, TRUE); + if (dd[0] < ylims[0]) + ylims[0] = dd[0]; + if (dd[1] > ylims[1]) + ylims[1] = dd[1]; + } + + /* XXX */ + for (d = vecs; d; d = d->v_link2) { + if (d->v_flags & VF_MINGIVEN) + if (ylims[0] < d->v_minsignal) + ylims[0] = d->v_minsignal; + if (d->v_flags & VF_MAXGIVEN) + if (ylims[1] > d->v_maxsignal) + ylims[1] = d->v_maxsignal; + } + } + + if (xlim) { + xlims[0] = xlim[0]; + xlims[1] = xlim[1]; + } else if (oneval) { + xlims[0] = HUGE; + xlims[1] = - xlims[0]; + for (d = vecs; d; d = d->v_link2) { + dd = ft_minmax(d, FALSE); + + if (dd[0] < xlims[0]) + xlims[0] = dd[0]; + if (dd[1] > xlims[1]) + xlims[1] = dd[1]; + } + } else { + xlims[0] = HUGE; + xlims[1] = - xlims[0]; + for (d = vecs; d; d = d->v_link2) { + dd = ft_minmax(d->v_scale, TRUE); + if (dd[0] < xlims[0]) + xlims[0] = dd[0]; + if (dd[1] > xlims[1]) + xlims[1] = dd[1]; + } + for (d = vecs; d; d = d->v_link2) { + if (d->v_scale->v_flags & VF_MINGIVEN) + if (xlims[0] < d->v_scale->v_minsignal) + xlims[0] = d->v_scale->v_minsignal; + if (d->v_scale->v_flags & VF_MAXGIVEN) + if (xlims[1] > d->v_scale->v_maxsignal) + xlims[1] = d->v_scale->v_maxsignal; + } + } + + /* Do some coercion of the limits to make them reasonable. */ + if ((xlims[0] == 0) && (xlims[1] == 0)) { + xlims[0] = -1.0; + xlims[1] = 1.0; + } + if ((ylims[0] == 0) && (ylims[1] == 0)) { + ylims[0] = -1.0; + ylims[1] = 1.0; + } + if (xlims[0] > xlims[1]) { + tt = xlims[1]; + xlims[1] = xlims[0]; + xlims[0] = tt; + } + if (ylims[0] > ylims[1]) { + tt = ylims[1]; + ylims[1] = ylims[0]; + ylims[0] = tt; + } + if (xlims[0] == xlims[1]) { + xlims[0] *= (xlims[0] > 0) ? 0.9 : 1.1; + xlims[1] *= (xlims[1] > 0) ? 1.1 : 0.9; + } + if (ylims[0] == ylims[1]) { + /* || fabs(ylims[0])/(ylims[1]-ylims[0]) > 1.0e9 + || fabs(ylims[1])/(ylims[1]-ylims[0]) > 1.0e9) */ + ylims[0] *= (ylims[0] > 0) ? 0.9 : 1.1; + ylims[1] *= (ylims[1] > 0) ? 1.1 : 0.9; + } + + if ((xlims[0] <= 0.0) && ((gtype == GRID_XLOG) || + (gtype == GRID_LOGLOG))) { + fprintf(cp_err, + "Error: X values must be > 0 for log scale\n"); + return (FALSE); + } + if ((ylims[0] <= 0.0) && ((gtype == GRID_YLOG) || + (gtype == GRID_LOGLOG))) { + fprintf(cp_err, + "Error: Y values must be > 0 for log scale\n"); + return (FALSE); + } + + /* Fix the plot limits for smith and polar grids. */ + if ((!xlim || !ylim) && (gtype == GRID_POLAR)) { + /* (0,0) must be in the center of the screen. */ + mx = (fabs(xlims[0]) > fabs(xlims[1])) ? fabs(xlims[0]) : + fabs(xlims[1]); + my = (fabs(ylims[0]) > fabs(ylims[1])) ? fabs(ylims[0]) : + fabs(ylims[1]); + rad = (mx > my) ? mx : my; + /* rad = sqrt(mx * mx + my * my); */ + xlims[0] = - rad; + xlims[1] = rad; + ylims[0] = - rad; + ylims[1] = rad; + } else if ((!xlim || !ylim) && (gtype == GRID_SMITH + || gtype == GRID_SMITHGRID)) + { + xlims[0] = -1.0; + xlims[1] = 1.0; + ylims[0] = -1.0; + ylims[1] = 1.0; + } + + /* We don't want to try to deal with smith plots for asciiplot. */ + if (devname && eq(devname, "lpr")) { + /* check if we should (can) linearize */ + if (!(!ft_curckt || !ft_curckt->ci_ckt || + strcmp(ft_curckt->ci_name, plot_cur->pl_title) || + !if_tranparams(ft_curckt, &tstart, &tstop, &tstep) || + ((tstop - tstart) * tstep <= 0.0) || + ((tstop - tstart) < tstep) || + !plot_cur || !plot_cur->pl_dvecs || + !plot_cur->pl_scale || + !isreal(plot_cur->pl_scale) || + !ciprefix("tran", plot_cur->pl_typename))) { + + newlen = (tstop - tstart) / tstep + 1.5; + + newscale = (double *) tmalloc(newlen * sizeof(double)); + + newv_scale = alloc(struct dvec); + newv_scale->v_flags = vecs->v_scale->v_flags; + newv_scale->v_type = vecs->v_scale->v_type; + newv_scale->v_gridtype = vecs->v_scale->v_gridtype; + newv_scale->v_length = newlen; + newv_scale->v_name = copy(vecs->v_scale->v_name); + newv_scale->v_realdata = newscale; + + for (i = 0, ttime = tstart; i < newlen; i++, ttime += tstep) + newscale[i] = ttime; + + for (v = vecs; v; v= v->v_link2) { + newdata = (double *) tmalloc(newlen * sizeof (double)); + + if (!ft_interpolate(v->v_realdata, newdata, + v->v_scale->v_realdata, v->v_scale->v_length, + newscale, newlen, 1)) { + fprintf(cp_err, + "Error: can't interpolate %s\n", v->v_name); + return(FALSE); + } + + tfree(v->v_realdata); + v->v_realdata = newdata; + + /* Why go to all this trouble if agraf ignores it? */ + nointerp = TRUE; + } + + vecs->v_scale = newv_scale; + + } + ft_agraf(xlims, ylims, vecs->v_scale, vecs->v_plot, vecs, + xdelta ? *xdelta : 0.0, ydelta ? *ydelta : 0.0, + ((gtype == GRID_XLOG) || (gtype == GRID_LOGLOG)), + ((gtype == GRID_YLOG) || (gtype == GRID_LOGLOG)), + nointerp); + return (TRUE); + } + + /* See if there is one type we can give for the y scale... */ + for (j = vecs->v_type, d = vecs->v_link2; d; d = d->v_link2) + if (d->v_type != j) { + j = SV_NOTYPE; + break; + } + + if (devname && eq(devname, "xgraph")) { + /* Interface to XGraph-11 Plot Program */ + ft_xgraph(xlims, ylims, hcopy, + title ? title : vecs->v_plot->pl_title, + xlabel ? xlabel : ft_typabbrev(vecs->v_scale->v_type), + ylabel ? ylabel : ft_typabbrev(j), + gtype, ptype, vecs); + return (TRUE); + } + +#ifdef TCL_MODULE + if (devname && eq(devname, "blt")) { + /* Just send the pairs to Tcl/Tk */ + for (d = vecs; d; d = d->v_link2) { + blt_plot(d, oneval ? (struct dvec *) NULL : d->v_scale); + } + return (TRUE); + } +#endif + + for (d = vecs, i = 0; d; d = d->v_link2) + i++; + + /* Figure out the X name and the X type. This is sort of bad... */ + xn = vecs->v_scale->v_name; + xt = vecs->v_scale->v_type; + + pname = plot_cur->pl_typename; + + if (!gr_init(xlims, ylims, (oneval ? (char *) NULL : xn), + title ? title : vecs->v_plot->pl_title, hcopy, i, + xdelta ? *xdelta : 0.0, ydelta ? *ydelta : 0.0, gtype, + ptype, xlabel, ylabel, xt, j, pname, cline)) + return (FALSE); + + /* Now plot all the graphs. */ + for (d = vecs; d; d = d->v_link2) + ft_graf(d, oneval ? (struct dvec *) NULL : d->v_scale, FALSE); + + gr_clean(); + + return (TRUE); +} + diff --git a/src/frontend/plotting/plotit.h b/src/frontend/plotting/plotit.h new file mode 100644 index 000000000..17742effb --- /dev/null +++ b/src/frontend/plotting/plotit.h @@ -0,0 +1,6 @@ +#ifndef _PLOTIT_H +#define _PLOTIT_H + +bool plotit(wordlist *wl, char *hcopy, char *devname); + +#endif diff --git a/src/frontend/plotting/plotting.c b/src/frontend/plotting/plotting.c new file mode 100644 index 000000000..761049958 --- /dev/null +++ b/src/frontend/plotting/plotting.c @@ -0,0 +1,16 @@ +#include + +#include "plotting.h" + +/* Where 'constants' go when defined on initialization. */ + +struct plot constantplot = { + "Constant values", "Sat Aug 16 10:55:15 PDT 1986", "constants", + "const", NULL, NULL, NULL, NULL, NULL, NULL, TRUE +} ; + +struct plot *plot_cur = &constantplot; +struct plot *plot_list = &constantplot; +int plotl_changed; /* TRUE after a load */ + +int plot_num = 1; diff --git a/src/frontend/plotting/plotting.h b/src/frontend/plotting/plotting.h new file mode 100644 index 000000000..30f7cba76 --- /dev/null +++ b/src/frontend/plotting/plotting.h @@ -0,0 +1,12 @@ +#ifndef _PLOTTING_H +#define _PLOTTING_H + +#include + +extern struct plot constantplot; +extern struct plot *plot_cur; +extern struct plot *plot_list; +extern int plotl_changed; +extern int plot_num; + +#endif diff --git a/src/frontend/plotting/pvec.c b/src/frontend/plotting/pvec.c new file mode 100644 index 000000000..b4584c861 --- /dev/null +++ b/src/frontend/plotting/pvec.c @@ -0,0 +1,86 @@ +#include +#include +#include +#include + +#include "pvec.h" + +void +pvec(struct dvec *d) +{ + char buf[BSIZE_SP], buf2[BSIZE_SP], buf3[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; + + default: + } + + switch (d->v_plottype) { + + case PLOT_COMB: + strcat(buf, ", plot = comb"); + break; + + case PLOT_POINT: + strcat(buf, ", plot = point"); + break; + + default: + } + 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) { + dimstring(d->v_dims, d->v_numdims, buf3); + sprintf(buf2, ", dims = [%s]", buf3); + strcat(buf, buf2); + } + if (d->v_plot->pl_scale == d) { + strcat(buf, " [default scale]\n"); + } else { + strcat(buf, "\n"); + } + out_send(buf); + return; +} diff --git a/src/frontend/plotting/pvec.h b/src/frontend/plotting/pvec.h new file mode 100644 index 000000000..2b2ef883d --- /dev/null +++ b/src/frontend/plotting/pvec.h @@ -0,0 +1,8 @@ +#ifndef _PVEC_H +#define _PVEC_H + +#include + +void pvec(struct dvec *d); + +#endif diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c new file mode 100644 index 000000000..9fce9606b --- /dev/null +++ b/src/frontend/plotting/x11.c @@ -0,0 +1,1018 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Jeffrey M. Hsu +**********/ + +/* + X11 drivers. +*/ + + +#include + +#ifndef X_DISPLAY_MISSING + +# include +# include /* PN */ +# include /* PN */ + +# include +# include +# include +# include +# include +# include +# include + +/* Added X11/ prefix to the next includes - ER */ + +# include +# include +# include +# include +# include +# include +# include +# include +# include + +#include "x11.h" + +static void linear_arc(int x0, int y0, int radius, double theta1, double theta2); + + +# ifdef DEBUG +extern int _Xdebug; +# endif + + +#define RAD_TO_DEG (180.0 / M_PI) + +/* X dependent default parameters */ +#define DEF_FONT "10x14" +#define NUMLINESTYLES 8 +#define MW_LINEWIDTH 2 /* MW. I want larger lines */ +#define NXPLANES 5 /* note: What is this used for? */ +#define BOXSIZE 30 /* initial size of bounding box for zoomin */ + +typedef struct x11info { + Window window; + int isopen; + Widget shell, form, view, buttonbox, buttons[2]; + XFontStruct *font; + GC gc; + int lastx, lasty; /* used in X_DrawLine */ + int lastlinestyle; /* used in X_DrawLine */ +} X11devdep; + +#define DEVDEP(g) (*((X11devdep *) (g)->devdep)) + +static void linear_arc(int x0, int y0, int radius, double theta1, double theta2); +static Display *display; +static GC xorgc; +static char *xlinestyles[NUMLINESTYLES] = { /* test patterns XXX */ + "\001\001\001\001", /* solid */ + "\001\002\001\002", /* dots */ + "\007\007\007\007", /* longdash */ + "\003\003\003\003", /* shortdash */ + "\007\002\002\002", /* dots longdash */ + "\003\002\001\002", /* dots shortdash */ + "\003\003\007\003", /* short/longdash */ +}; + +static Widget toplevel; +static Bool noclear = False; +static GRAPH *lasthardcopy; /* graph user selected */ +static int X11_Open = 0; +static int numdispplanes; + + +extern void internalerror (char *message); +extern void externalerror (char *message); +static void initlinestyles (void); +static void initcolors (GRAPH *graph); +extern void PushGraphContext (GRAPH *graph); +extern void SetColor (int colorid); +extern void Text (char *text, int x, int y); +extern void SaveText (GRAPH *graph, char *text, int x, int y); +extern void PopGraphContext (void); +void slopelocation (GRAPH *graph, int x0, int y0); +void zoomin (GRAPH *graph); +static void X_ScreentoData (GRAPH *graph, int x, int y, double *fx, double *fy); +extern int DestroyGraph (int id); +extern void gr_redraw (GRAPH *graph); +extern void gr_resize (GRAPH *graph); + + +int +errorhandler(Display *display, XErrorEvent *errorev) +{ + XGetErrorText(display, errorev->error_code, ErrorMessage, 1024); + externalerror(ErrorMessage); + return 0; +} + + + +int +X11_Init(void) +{ + + char buf[512]; + char *displayname; + + XGCValues gcvalues; + + /* grrr, Xtk forced contortions */ + char *argv[2]; + int argc = 2; + + if (cp_getvar("display", VT_STRING, buf)) { + displayname = buf; + } else if (!(displayname = getenv("DISPLAY"))) { + internalerror("Can't open X display."); + return (1); + } + +# ifdef DEBUG + _Xdebug = 1; +# endif + + argv[0] = "ngspice"; + argv[1] = displayname; +/* + argv[2] = "-geometry"; + argv[3] = "=1x1+2+2"; +*/ + + /* initialize X toolkit */ + toplevel = XtInitialize("ngspice", "Nutmeg", NULL, 0, &argc, argv); + + display = XtDisplay(toplevel); + + X11_Open = 1; + + /* "invert" works better than "xor" for B&W */ + + /* xor gc should be a function of the pixels that are written on */ + /* gcvalues.function = GXxor; */ + /* this patch makes lines visible on true color displays + Guenther Roehrich 22-Jan-99 */ + gcvalues.function = GXinvert; + gcvalues.line_width = 1; + gcvalues.foreground = 1; + gcvalues.background = 0; + + xorgc = XCreateGC(display, DefaultRootWindow(display), + GCLineWidth | GCFunction | GCForeground | GCBackground, + &gcvalues); + + /* set correct information */ + dispdev->numlinestyles = NUMLINESTYLES; + dispdev->numcolors = NUMCOLORS; + + dispdev->width = DisplayWidth(display, DefaultScreen(display)); + dispdev->height = DisplayHeight(display, DefaultScreen(display)); + + /* we don't want non-fatal X errors to call exit */ + XSetErrorHandler(errorhandler); + + numdispplanes = DisplayPlanes(display, DefaultScreen(display)); + + return (0); + +} + +static void +initlinestyles(void) +{ + + int i; + + if (numdispplanes > 1) { + /* Dotted lines are a distraction when we have colors. */ + for (i = 2; i < NUMLINESTYLES; i++) { + xlinestyles[i] = xlinestyles[0]; + } + } + +} + +static void +initcolors(GRAPH *graph) +{ + int i; + static char *colornames[] = { "black", /* white */ + "white", "red", "blue", + "orange", "green", "pink", + "brown", "khaki", "plum", + "orchid", "violet", "maroon", + "turquoise", "sienna", "coral", + "cyan", "magenta", "gold", + "yellow", "" + }; + + XColor visualcolor, exactcolor; + char buf[BSIZE_SP], colorstring[BSIZE_SP]; + int xmaxcolors = NUMCOLORS; /* note: can we get rid of this? */ + + if (numdispplanes == 1) { + /* black and white */ + xmaxcolors = 2; + graph->colors[0] = DEVDEP(graph).view->core.background_pixel; + if (graph->colors[0] == WhitePixel(display, DefaultScreen(display))) + graph->colors[1] = BlackPixel(display, DefaultScreen(display)); + else + graph->colors[1] = WhitePixel(display, DefaultScreen(display)); + + } else { + if (numdispplanes < NXPLANES) + xmaxcolors = 1 << numdispplanes; + + for (i = 0; i < xmaxcolors; i++) { + (void) sprintf(buf, "color%d", i); + if (!cp_getvar(buf, VT_STRING, colorstring)) + (void) strcpy(colorstring, colornames[i]); + if (!XAllocNamedColor(display, + DefaultColormap(display, DefaultScreen(display)), + colorstring, &visualcolor, &exactcolor)) { + (void) sprintf(ErrorMessage, + "can't get color %s\n", colorstring); + externalerror(ErrorMessage); + graph->colors[i] = i ? BlackPixel(display, + DefaultScreen(display)) + : WhitePixel(display, DefaultScreen(display)); + continue; + } + graph->colors[i] = visualcolor.pixel; + + + /* MW. I don't need this, everyone must know what he is doing + if (i > 0 && + graph->colors[i] == DEVDEP(graph).view->core.background_pixel) { + graph->colors[i] = graph->colors[0]; + } */ + + } + /* MW. Set Beackgroound here */ + XSetWindowBackground(display, DEVDEP(graph).window, graph->colors[0]); + +/* if (graph->colors[0] != DEVDEP(graph).view->core.background_pixel) { + graph->colors[0] = DEVDEP(graph).view->core.background_pixel; + } */ + } + + for (i = xmaxcolors; i < NUMCOLORS; i++) { + graph->colors[i] = graph->colors[i + 1 - xmaxcolors]; + } +} + + +void +handlekeypressed(Widget w, caddr_t clientdata, caddr_t calldata) +{ + + XKeyEvent *keyev = (XKeyPressedEvent *) calldata; + GRAPH *graph = (GRAPH *) clientdata; + char text[4]; + int nbytes; + + nbytes = XLookupString(keyev, text, 4, NULL, NULL); + if (!nbytes) return; + /* write it */ + PushGraphContext(graph); + text[nbytes] = '\0'; + SetColor(1); + Text(text, keyev->x, graph->absolute.height - keyev->y); + /* save it */ + SaveText(graph, text, keyev->x, graph->absolute.height - keyev->y); + /* warp mouse so user can type in sequence */ + XWarpPointer(display, None, DEVDEP(graph).window, 0, 0, 0, 0, + keyev->x + XTextWidth(DEVDEP(graph).font, text, nbytes), + keyev->y); + PopGraphContext(); + +} + + +void +handlebuttonev(Widget w, caddr_t clientdata, caddr_t calldata) +{ + + XButtonEvent *buttonev = (XButtonEvent *) calldata; + + switch (buttonev->button) { + case Button1: + slopelocation((GRAPH *) clientdata, buttonev->x, buttonev->y); + break; + case Button3: + zoomin((GRAPH *) clientdata); + break; + } + +} + + +/* Recover from bad NewViewPort call. */ +#define RECOVERNEWVIEWPORT() tfree((char *) graph);\ + graph = (GRAPH *) NULL; + /* need to do this or else DestroyGraph will free it again */ + +/* NewViewport is responsible for filling in graph->viewport */ +int +X11_NewViewport(GRAPH *graph) +{ + + char fontname[513]; /* who knows . . . */ + char *p, *q; + Cursor cursor; + XSetWindowAttributes w_attrs; + XGCValues gcvalues; + static Arg formargs[ ] = { + { XtNleft, (XtArgVal) XtChainLeft }, + { XtNresizable, (XtArgVal) TRUE } + }; + static Arg bboxargs[ ] = { + { XtNfromHoriz, (XtArgVal) NULL }, + { XtNbottom, (XtArgVal) XtChainTop }, + { XtNtop, (XtArgVal) XtChainTop }, + { XtNleft, (XtArgVal) XtChainRight }, + { XtNright, (XtArgVal) XtChainRight } + }; + static Arg buttonargs[ ] = { + { XtNlabel, (XtArgVal) NULL }, + { XtNfromVert, (XtArgVal) NULL }, + { XtNbottom, (XtArgVal) XtChainTop }, + { XtNtop, (XtArgVal) XtChainTop }, + { XtNleft, (XtArgVal) XtRubber }, + { XtNright, (XtArgVal) XtRubber }, + { XtNresizable, (XtArgVal) TRUE } + }; + static Arg viewargs[] = { + { XtNresizable, (XtArgVal) TRUE }, + { XtNwidth, (XtArgVal) 300 }, + { XtNheight, (XtArgVal) 300 }, + { XtNright, (XtArgVal) XtChainRight } + }; + int trys; + + graph->devdep = tmalloc(sizeof(X11devdep)); + + /* set up new shell */ + DEVDEP(graph).shell = XtCreateApplicationShell("shell", + topLevelShellWidgetClass, NULL, 0); + + /* set up form widget */ + DEVDEP(graph).form = XtCreateManagedWidget("form", + formWidgetClass, DEVDEP(graph).shell, formargs, XtNumber(formargs)); + + /* set up viewport */ + DEVDEP(graph).view = XtCreateManagedWidget("viewport", widgetClass, + DEVDEP(graph).form, + viewargs, + XtNumber(viewargs)); + XtAddEventHandler(DEVDEP(graph).view, ButtonPressMask, FALSE, + (XtEventHandler) handlebuttonev, graph); + XtAddEventHandler(DEVDEP(graph).view, KeyPressMask, FALSE, + (XtEventHandler) handlekeypressed, graph); + XtAddEventHandler(DEVDEP(graph).view, StructureNotifyMask, FALSE, + (XtEventHandler) resize, graph); + XtAddEventHandler(DEVDEP(graph).view, ExposureMask, FALSE, + (XtEventHandler) redraw, graph); + + /* set up button box */ + XtSetArg(bboxargs[1], XtNfromHoriz, DEVDEP(graph).view); + DEVDEP(graph).buttonbox = XtCreateManagedWidget("buttonbox", + boxWidgetClass, DEVDEP(graph).form, bboxargs, XtNumber(bboxargs)); + + /* set up buttons */ + XtSetArg(buttonargs[0], XtNlabel, "quit"); + XtSetArg(bboxargs[1], XtNfromVert, NULL); + DEVDEP(graph).buttons[0] = XtCreateManagedWidget("quit", + commandWidgetClass, DEVDEP(graph).buttonbox, + buttonargs, 1); + XtAddCallback(DEVDEP(graph).buttons[0], XtNcallback, (XtCallbackProc) killwin, graph); + + XtSetArg(buttonargs[0], XtNlabel, "hardcopy"); + XtSetArg(bboxargs[1], XtNfromVert, DEVDEP(graph).buttons[0]); + DEVDEP(graph).buttons[1] = XtCreateManagedWidget("hardcopy", + commandWidgetClass, DEVDEP(graph).buttonbox, + buttonargs, 1); + XtAddCallback(DEVDEP(graph).buttons[1], XtNcallback, (XtCallbackProc) hardcopy, graph); + + /* set up fonts */ + if (!cp_getvar("font", VT_STRING, fontname)) { + (void) strcpy(fontname, DEF_FONT); + } + + for (p = fontname; *p && *p <= ' '; p++) + ; + if (p != fontname) { + for (q = fontname; *p; *q++ = *p++) + ; + *q = 0; + } + + trys = 1; + while (!(DEVDEP(graph).font = XLoadQueryFont(display, fontname))) { + sprintf(ErrorMessage, "can't open font %s", fontname); + strcpy(fontname, "fixed"); + if (trys > 1) { + internalerror(ErrorMessage); + RECOVERNEWVIEWPORT(); + return(1); + } + trys += 1; + } + + graph->fontwidth = DEVDEP(graph).font->max_bounds.rbearing - + DEVDEP(graph).font->min_bounds.lbearing + 1; + graph->fontheight = DEVDEP(graph).font->max_bounds.ascent + + DEVDEP(graph).font->max_bounds.descent + 1; + + XtRealizeWidget(DEVDEP(graph).shell); + + DEVDEP(graph).window = XtWindow(DEVDEP(graph).view); + DEVDEP(graph).isopen = 0; + w_attrs.bit_gravity = ForgetGravity; + XChangeWindowAttributes(display, DEVDEP(graph).window, CWBitGravity, + &w_attrs); + /* have to note font and set mask GCFont in XCreateGC, p.w.h. */ + gcvalues.font = DEVDEP(graph).font->fid; + gcvalues.line_width = MW_LINEWIDTH; + gcvalues.cap_style = CapNotLast; + gcvalues.function = GXcopy; + DEVDEP(graph).gc = XCreateGC(display, DEVDEP(graph).window, + GCFont | GCLineWidth | GCCapStyle | GCFunction, &gcvalues); + + /* should absolute.positions really be shell.pos? */ + graph->absolute.xpos = DEVDEP(graph).view->core.x; + graph->absolute.ypos = DEVDEP(graph).view->core.y; + graph->absolute.width = DEVDEP(graph).view->core.width; + graph->absolute.height = DEVDEP(graph).view->core.height; + + initlinestyles(); + initcolors(graph); + + /* set up cursor */ + cursor = XCreateFontCursor(display, XC_left_ptr); + XDefineCursor(display, DEVDEP(graph).window, cursor); + + return (0); +} + +/* This routine closes the X connection. + It is not to be called for finishing a graph. */ +void +X11_Close(void) +{ + XCloseDisplay(display); +} + +void +X11_DrawLine(int x1, int y1, int x2, int y2) +{ + + if (DEVDEP(currentgraph).isopen) + XDrawLine(display, DEVDEP(currentgraph).window, + DEVDEP(currentgraph).gc, + x1, currentgraph->absolute.height - y1, + x2, currentgraph->absolute.height - y2); + + +} + + +void +X11_Arc(int x0, int y0, int radius, double theta1, double theta2) +{ + + int t1, t2; + + if (!cp_getvar("x11lineararcs", VT_BOOL, (char *) &t1)) { + linear_arc(x0, y0, radius, theta1, theta2); + } + + if (DEVDEP(currentgraph).isopen) { + if (theta1 >= theta2) + theta2 = 2 * M_PI + theta2; + t1 = 64 * (180.0 / M_PI) * theta1; + t2 = 64 * (180.0 / M_PI) * theta2 - t1; + if (t2 == 0) + return; + XDrawArc(display, DEVDEP(currentgraph).window, DEVDEP(currentgraph).gc, + x0 - radius, + currentgraph->absolute.height - radius - y0, + 2 * radius, 2 * radius, t1, t2); + } +} + +/* note: x and y are the LOWER left corner of text */ +void +X11_Text(char *text, int x, int y) +{ + +/* We specify text position by lower left corner, so have to adjust for + X11's font nonsense. */ + + if (DEVDEP(currentgraph).isopen) + XDrawString(display, DEVDEP(currentgraph).window, + DEVDEP(currentgraph).gc, x, + currentgraph->absolute.height + - (y + DEVDEP(currentgraph).font->max_bounds.descent), + text, strlen(text)); + + /* note: unlike before, we do not save any text here */ + +} + + +int +X11_DefineColor(int colorid, double red, double green, double blue) +{ + internalerror("X11_DefineColor not implemented."); + return(0); +} + + +void +X11_DefineLinestyle(int linestyleid, int mask) +{ + internalerror("X11_DefineLinestyle not implemented."); +} + +void +X11_SetLinestyle(int linestyleid) +{ + XGCValues values; + + if (currentgraph->linestyle != linestyleid) { + + if ((linestyleid == 0 || numdispplanes > 1) && linestyleid != 1) { + /* solid if linestyle 0 or if has color, allow only one + * dashed linestyle */ + values.line_style = LineSolid; + } else { + values.line_style = LineOnOffDash; + } + XChangeGC(display, DEVDEP(currentgraph).gc, GCLineStyle, &values); + + currentgraph->linestyle = linestyleid; + XSetDashes(display, DEVDEP(currentgraph).gc, 0, + xlinestyles[linestyleid], 4); + } +} + +void +X11_SetColor(int colorid) +{ + + currentgraph->currentcolor = colorid; + XSetForeground(display, DEVDEP(currentgraph).gc, + currentgraph->colors[colorid]); + +} + +void +X11_Update(void) +{ + + if (X11_Open) + XSync(display, 0); + +} + +void +X11_Clear(void) +{ + + if (!noclear) /* hack so exposures look like they're handled nicely */ + XClearWindow(display, DEVDEP(currentgraph).window); + +} + +static void +X_ScreentoData(GRAPH *graph, int x, int y, double *fx, double *fy) +{ + double lmin, lmax; + + if (graph->grid.gridtype == GRID_XLOG + || graph->grid.gridtype == GRID_LOGLOG) + { + lmin = log10(graph->datawindow.xmin); + lmax = log10(graph->datawindow.xmax); + *fx = exp(((x - graph->viewportxoff) + * (lmax - lmin) / graph->viewport.width + lmin) + * M_LN10); + } else { + *fx = (x - graph->viewportxoff) * graph->aspectratiox + + graph->datawindow.xmin; + } + + if (graph->grid.gridtype == GRID_YLOG + || graph->grid.gridtype == GRID_LOGLOG) + { + lmin = log10(graph->datawindow.ymin); + lmax = log10(graph->datawindow.ymax); + *fy = exp(((graph->absolute.height - y - graph->viewportxoff) + * (lmax - lmin) / graph->viewport.height + lmin) + * M_LN10); + } else { + *fy = ((graph->absolute.height - y) - graph->viewportyoff) + * graph->aspectratioy + graph->datawindow.ymin; + } + +} + + + +void +slopelocation(GRAPH *graph, int x0, int y0) + + /* initial position of mouse */ +{ + + int x1, y1; + int x, y; + Window rootwindow, childwindow; + int rootx, rooty; + unsigned int state; + double fx0, fx1, fy0, fy1; + double angle; + + x1 = x0; + y1 = y0; + XQueryPointer(display, DEVDEP(graph).window, &rootwindow, &childwindow, + &rootx, &rooty, &x, &y, &state); + XDrawLine(display, DEVDEP(graph).window, xorgc, x0, y0, x0, y1-1); + XDrawLine(display, DEVDEP(graph).window, xorgc, x0, y1, x1, y1); + while (state & Button1Mask) { + if (x != x1 || y != y1) { + XDrawLine(display, DEVDEP(graph).window, xorgc, + x0, y0, x0, y1-1); + XDrawLine(display, DEVDEP(graph).window, xorgc, + x0, y1, x1, y1); + x1 = x; + y1 = y; + XDrawLine(display, DEVDEP(graph).window, xorgc, x0, y0, x0, y1-1); + XDrawLine(display, DEVDEP(graph).window, xorgc, x0, y1, x1, y1); + } + XQueryPointer(display, DEVDEP(graph).window, &rootwindow, + &childwindow, &rootx, &rooty, &x, &y, &state); + } + XDrawLine(display, DEVDEP(graph).window, xorgc, x0, y0, x0, y1-1); + XDrawLine(display, DEVDEP(graph).window, xorgc, x0, y1, x1, y1); + + X_ScreentoData(graph, x0, y0, &fx0, &fy0); + X_ScreentoData(graph, x1, y1, &fx1, &fy1); + + /* print it out */ + if (x1 == x0 && y1 == y0) { /* only one location */ + fprintf(stdout, "\nx0 = %g, y0 = %g\n", fx0, fy0); + if (graph->grid.gridtype == GRID_POLAR + || graph->grid.gridtype == GRID_SMITH + || graph->grid.gridtype == GRID_SMITHGRID) + { + angle = RAD_TO_DEG * atan2( fy0, fx0 ); + fprintf(stdout, "r0 = %g, a0 = %g\n", + sqrt( fx0*fx0 + fy0*fy0 ), + (angle>0)?angle:(double) 360+angle); + } + + + } else { /* need to print info about two points */ + fprintf(stdout, "\nx0 = %g, y0 = %g x1 = %g, y1 = %g\n", + fx0, fy0, fx1, fy1); + fprintf(stdout, "dx = %g, dy = %g\n", fx1-fx0, fy1 - fy0); + if (x1 != x0 && y1 != y0) { + /* add slope info if both dx and dy are zero, + because otherwise either dy/dx or dx/dy is zero, + which is uninteresting + */ + fprintf(stdout, "dy/dx = %g dx/dy = %g\n", + (fy1-fy0)/(fx1-fx0), (fx1-fx0)/(fy1-fy0)); + } + } + + return; + +} + +/* should be able to do this by sleight of hand on graph parameters */ +void +zoomin(GRAPH *graph) +{ +/* note: need to add circular boxes XXX */ + + int x0, y0, x1, y1; + double fx0, fx1, fy0, fy1, ftemp; + char buf[BSIZE_SP]; + char buf2[128]; + char *t; + wordlist *wl; + int dummy; + + Window rootwindow, childwindow; + int rootx, rooty; + unsigned int state; + int x, y, upperx, uppery, lowerx, lowery; + + /* open box and get area to zoom in on */ + + XQueryPointer(display, DEVDEP(graph).window, &rootwindow, + &childwindow, &rootx, &rooty, &x0, &y0, &state); + + x = lowerx = x1 = x0 + BOXSIZE; + y = lowery = y1 = y0 + BOXSIZE; + upperx = x0; + uppery = y0; + + XDrawRectangle(display, DEVDEP(graph).window, xorgc, + upperx, uppery, lowerx - upperx, lowery - uppery); + +/* note: what are src_x, src_y, src_width, and src_height for? XXX */ + XWarpPointer(display, None, DEVDEP(graph).window, 0, 0, 0, 0, x1, y1); + + while (state & Button3Mask) { + if (x != x1 || y != y1) { + XDrawRectangle(display, DEVDEP(graph).window, xorgc, + upperx, uppery, lowerx - upperx, lowery - uppery); + x1 = x; + y1 = y; + /* figure out upper left corner */ + /* remember X11's (and X10's) demented coordinate system */ + if (y0 < y1) { + uppery = y0; + upperx = x0; + lowery = y1; + lowerx = x1; + } else { + uppery = y1; + upperx = x1; + lowery = y0; + lowerx = x0; + } + XDrawRectangle(display, DEVDEP(graph).window, xorgc, + upperx, uppery, lowerx - upperx, lowery - uppery); + } + XQueryPointer(display, DEVDEP(graph).window, &rootwindow, + &childwindow, &rootx, &rooty, &x, &y, &state); + } + XDrawRectangle(display, DEVDEP(graph).window, xorgc, + upperx, uppery, lowerx - upperx, lowery - uppery); + + X_ScreentoData(graph, x0, y0, &fx0, &fy0); + X_ScreentoData(graph, x1, y1, &fx1, &fy1); + + if (fx0 > fx1) { + ftemp = fx0; + fx0 = fx1; + fx1 = ftemp; + } + if (fy0 > fy1) { + ftemp = fy0; + fy0 = fy1; + fy1 = ftemp; + } + + strncpy(buf2, graph->plotname, sizeof(buf2)); + if ((t =strchr(buf2, ':'))) + *t = 0; + + if (!eq(plot_cur->pl_typename, buf2)) { + (void) sprintf(buf, +"setplot %s; %s xlimit %.20e %.20e ylimit %.20e %.20e; setplot $curplot\n", + buf2, graph->commandline, fx0, fx1, fy0, fy1); + } else { + (void) sprintf(buf, "%s xlimit %e %e ylimit %e %e\n", + graph->commandline, fx0, fx1, fy0, fy1); + } + + /* hack for Gordon Jacobs */ + /* add to history list if plothistory is set */ + if (cp_getvar("plothistory", VT_BOOL, (char *) &dummy)) { + wl = cp_parse(buf); + (void) cp_addhistent(cp_event++, wl); + } + + (void) cp_evloop(buf); + +} + +void +hardcopy(Widget w, caddr_t client_data, caddr_t call_data) +{ + + lasthardcopy = (GRAPH *) client_data; + com_hardcopy(NULL); + +} + +void +killwin(Widget w, caddr_t client_data, caddr_t call_data) +{ + + GRAPH *graph = (GRAPH *) client_data; + + /* Iplots are done asynchronously */ + DEVDEP(graph).isopen = 0; +/* MW. Not sure but DestroyGraph might free() to much - try Xt...() first */ + XtDestroyWidget(DEVDEP(graph).shell); + DestroyGraph(graph->graphid); + + +} + +/* call higher gr_redraw routine */ +void +redraw(Widget w, caddr_t client_data, caddr_t call_data) +{ + + GRAPH *graph = (GRAPH *) client_data; + XExposeEvent *pev = (XExposeEvent *) call_data; + XEvent ev; + XRectangle rects[30]; + int n = 1; + + DEVDEP(graph).isopen = 1; + + + rects[0].x = pev->x; + rects[0].y = pev->y; + rects[0].width = pev->width; + rects[0].height = pev->height; + + /* XXX */ + /* pull out all other expose regions that need to be redrawn */ + while (n < 30 && XCheckWindowEvent(display, DEVDEP(graph).window, + (long) ExposureMask, &ev)) { + pev = (XExposeEvent *) &ev; + rects[n].x = pev->x; + rects[n].y = pev->y; + rects[n].width = pev->width; + rects[n].height = pev->height; + n++; + } + XSetClipRectangles(display, DEVDEP(graph).gc, 0, 0, + rects, n, Unsorted); + + noclear = True; + gr_redraw(graph); + noclear = False; + + XSetClipMask(display, DEVDEP(graph).gc, None); + +} + +void +resize(Widget w, caddr_t client_data, caddr_t call_data) +{ + + GRAPH *graph = (GRAPH *) client_data; + XEvent ev; + + /* pull out all other exposure events + Also, get rid of other StructureNotify events on this window. */ + + while (XCheckWindowEvent(display, DEVDEP(graph).window, + (long) /* ExposureMask | */ StructureNotifyMask, &ev)) + ; + + XClearWindow(display, DEVDEP(graph).window); + graph->absolute.width = w->core.width; + graph->absolute.height = w->core.height; + gr_resize(graph); + +} + + + +void +X11_Input(REQUEST *request, RESPONSE *response) +{ + + XEvent ev; + int nfds, readfds; + + switch (request->option) { + case char_option: + + nfds = ConnectionNumber(display) > fileno(request->fp) ? + ConnectionNumber(display) : + fileno(request->fp); + + while (1) { + + /* first read off the queue before doing the select */ + while (XtPending()) { + XtNextEvent(&ev); + XtDispatchEvent(&ev); + } + + readfds = 1 << fileno(request->fp) | + 1 << ConnectionNumber(display); + + /* block on ConnectionNumber and request->fp */ + /* PN: added fd_set * casting */ + select(nfds + 1, (fd_set *)&readfds, (fd_set *) NULL, (fd_set *) NULL, NULL); + + /* handle X events first */ + if (readfds & (1 << ConnectionNumber(display))) { + /* handle ALL X events */ + while (XtPending()) { + XtNextEvent(&ev); + XtDispatchEvent(&ev); + } + } + + if (readfds & (1 << fileno(request->fp))) { + response->reply.ch = inchar(request->fp); + goto out; + } + + } + break; + + case click_option: + /* let's fake this */ + response->reply.graph = lasthardcopy; + break; + + case button_option: + /* sit and handle events until get a button selection */ + internalerror("button_option not implemented"); + response->option = error_option; + return; + break; + + case checkup_option: + /* first read off the queue before doing the select */ + while (XtPending()) { + XtNextEvent(&ev); + XtDispatchEvent(&ev); + } + break; + + default: + internalerror("unrecognized input type"); + response->option = error_option; + return; + break; + } + +out: + if (response) + response->option = request->option; + return; + +} + +static void +linear_arc(int x0, int y0, int radius, double theta1, double theta2) + /* x coordinate of center */ + /* y coordinate of center */ + /* radius of arc */ + /* initial angle ( +x axis = 0 rad ) */ + /* final angle ( +x axis = 0 rad ) */ + /* + * Notes: + * Draws an arc of radius and center at (x0,y0) beginning at + * angle theta1 (in rad) and ending at theta2 + */ +{ + int x1, y1, x2, y2; + int s = 60; + double dphi, phi; + + x2 = x0 + (int) (radius * cos(theta1)); + y2 = y0 + (int) (radius * sin(theta1)); + + while(theta1 >= theta2) + theta2 += 2 * M_PI; + dphi = (theta2 - theta1) / s; + + if ((theta1 + dphi) == theta1) { + theta2 += 2 * M_PI; + dphi = (theta2 - theta1) / s; + } + + + for(phi = theta1 + dphi; phi < theta2; phi += dphi) { + x1 = x2; + y1 = y2; + x2 = x0 + (int)(radius * cos(phi)); + y2 = y0 + (int)(radius * sin(phi)); + X11_DrawLine(x1,y1,x2,y2); + } + + x1 = x2; + y1 = y2; + x2 = x0 + (int)(radius * cos(theta2)); + y2 = y0 + (int)(radius * sin(theta2)); + X11_DrawLine(x1,y1,x2,y2); +} + +#else +int x11_dummy_symbol; +/* otherwise, some linkers get upset */ +#endif /* X_DISPLAY_MISSING */ diff --git a/src/frontend/plotting/x11.h b/src/frontend/plotting/x11.h new file mode 100644 index 000000000..67d6e66c9 --- /dev/null +++ b/src/frontend/plotting/x11.h @@ -0,0 +1,32 @@ +/************* + * Header file for x11.c + * 1999 E. Rouat + ************/ + +#ifndef X11_H_INCLUDED +#define X11_H_INCLUDED + +int X11_Init(void); +int X11_NewViewport(GRAPH *graph); +void X11_Close(void); +void X11_DrawLine(int x1, int y1, int x2, int y2); +void X11_Arc(int x0, int y0, int radius, double theta1, double theta2); +void X11_Text(char *text, int x, int y); +int X11_DefineColor(int colorid, double red, double green, double blue); +void X11_DefineLinestyle(int linestyleid, int mask); +void X11_SetLinestyle(int linestyleid); +void X11_SetColor(int colorid); +void X11_Update(void); +void X11_Clear(void); +void handlekeypressed(Widget w, caddr_t clientdata, caddr_t calldata); +void handlebuttonev(Widget w, caddr_t clientdata, caddr_t calldata); +void slopelocation(GRAPH *graph, int x0, int y0); +void zoomin(GRAPH *graph); +void hardcopy(Widget w, caddr_t client_data, caddr_t call_data); +void killwin(Widget w, caddr_t client_data, caddr_t call_data); +void redraw(Widget w, caddr_t client_data, caddr_t call_data); +void resize(Widget w, caddr_t client_data, caddr_t call_data); +void X11_Input(REQUEST *request, RESPONSE *response); + + +#endif diff --git a/src/frontend/plotting/xgraph.c b/src/frontend/plotting/xgraph.c new file mode 100644 index 000000000..761c0a165 --- /dev/null +++ b/src/frontend/plotting/xgraph.c @@ -0,0 +1,167 @@ +/********** +Copyright 1992 Regents of the University of California. All rights reserved. +Author: 1992 David A. Gates, U. C. Berkeley CAD Group +**********/ + +/* + * Xgraph-11 plots. + */ + +#include "ngspice.h" +#include "cpdefs.h" +#include "ftedefs.h" +#include "dvec.h" +#include "fteparse.h" +#include "xgraph.h" + +#include + +#define XG_MAXVECTORS 64 + +void +ft_xgraph(double *xlims, double *ylims, char *filename, char *title, char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype, struct dvec *vecs) +{ + + FILE *file; + struct dvec *v, *scale; + double xval, yval; + int i, numVecs, linewidth; + bool xlog, ylog, nogrid, markers; + char buf[BSIZE_SP], pointstyle[BSIZE_SP], *text; + + /* Sanity checking. */ + for ( v = vecs, numVecs = 0; v; v = v->v_link2 ) { + numVecs++; + } + if (numVecs == 0) { + return; + } else if (numVecs > XG_MAXVECTORS) { + fprintf( cp_err, "Error: too many vectors for Xgraph.\n" ); + return; + } + if (!cp_getvar("xbrushwidth", VT_NUM, &linewidth)) + linewidth = 1; + if (linewidth < 1) linewidth = 1; + + if (!cp_getvar("pointstyle", VT_STRING, pointstyle)) { + markers = FALSE; + } else { + if (cieq(pointstyle,"markers")) { + markers = TRUE; + } else { + markers = FALSE; + } + } + + + /* Make sure the gridtype is supported. */ + switch (gridtype) { + case GRID_LIN: + nogrid = xlog = ylog = FALSE; + break; + case GRID_XLOG: + xlog = TRUE; + nogrid = ylog = FALSE; + break; + case GRID_YLOG: + ylog = TRUE; + nogrid = xlog = FALSE; + break; + case GRID_LOGLOG: + xlog = ylog = TRUE; + nogrid = FALSE; + break; + case GRID_NONE: + nogrid = TRUE; + xlog = ylog = FALSE; + break; + default: + fprintf( cp_err, "Error: grid type unsupported by Xgraph.\n" ); + return; + } + + /* Open the output file. */ + if (!(file = fopen(filename, "w"))) { + perror(filename); + return; + } + + /* Set up the file header. */ + if (title) { + text = cp_unquote(title); + fprintf( file, "TitleText: %s\n", text ); + tfree(text); + } + if (xlabel) { + text = cp_unquote(xlabel); + fprintf( file, "XUnitText: %s\n", text ); + tfree(text); + } + if (ylabel) { + text = cp_unquote(ylabel); + fprintf( file, "YUnitText: %s\n", text ); + tfree(text); + } + if (nogrid) { + fprintf( file, "Ticks: True\n" ); + } + if (xlog) { + fprintf( file, "LogX: True\n" ); + if (xlims) { + fprintf( file, "XLowLimit: % e\n", log10(xlims[0]) ); + fprintf( file, "XHighLimit: % e\n", log10(xlims[1]) ); + } + } else { + if (xlims) { + fprintf( file, "XLowLimit: % e\n", xlims[0] ); + fprintf( file, "XHighLimit: % e\n", xlims[1] ); + } + } + if (ylog) { + fprintf( file, "LogY: True\n" ); + if (ylims) { + fprintf( file, "YLowLimit: % e\n", log10(ylims[0]) ); + fprintf( file, "YHighLimit: % e\n", log10(ylims[1]) ); + } + } else { + if (ylims) { + fprintf( file, "YLowLimit: % e\n", ylims[0] ); + fprintf( file, "YHighLimit: % e\n", ylims[1] ); + } + } + fprintf( file, "LineWidth: %d\n", linewidth ); + fprintf( file, "BoundBox: True\n" ); + if (plottype == PLOT_COMB) { + fprintf( file, "BarGraph: True\n" ); + fprintf( file, "NoLines: True\n" ); + } else if (plottype == PLOT_POINT) { + if (markers) { + fprintf( file, "Markers: True\n" ); + } else { + fprintf( file, "LargePixels: True\n" ); + } + fprintf( file, "NoLines: True\n" ); + } + + /* Write out the data. */ + for ( v = vecs; v; v = v->v_link2 ) { + scale = v->v_scale; + if (v->v_name) { + fprintf( file, "\"%s\"\n", v->v_name ); + } + for ( i = 0; i < scale->v_length; i++ ) { + xval = isreal(scale) ? + scale->v_realdata[i] : realpart(&scale->v_compdata[i]); + yval = isreal(v) ? + v->v_realdata[i] : realpart(&v->v_compdata[i]); + fprintf( file, "% e % e\n", xval, yval ); + } + fprintf( file, "\n" ); + } + (void) fclose( file ); + (void) sprintf( buf, "xgraph %s &", filename ); + (void) system( buf ); + + + return; +} diff --git a/src/frontend/plotting/xgraph.h b/src/frontend/plotting/xgraph.h new file mode 100644 index 000000000..47cdc18c3 --- /dev/null +++ b/src/frontend/plotting/xgraph.h @@ -0,0 +1,16 @@ +/************* + * Header file for xgraph.c + * 1999 E. Rouat + ************/ + +#ifndef XGRAPH_H_INCLUDED +#define XGRAPH_H_INCLUDED + +void ft_xgraph(double *xlims, double *ylims, char *filename, char *title, + char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype, + struct dvec *vecs); + + + + +#endif 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/quote.c b/src/frontend/quote.c new file mode 100644 index 000000000..e4d8641af --- /dev/null +++ b/src/frontend/quote.c @@ -0,0 +1,92 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* + * + * Various things for quoting words. If this is not ascii, quote and + * strip are no-ops, so '' and \ quoting won't work. To fix this, sell + * your IBM machine and buy a vax. + */ + +#include "ngspice.h" +#include "cpdefs.h" +#include "quote.h" + + +/* Strip all the 8th bits from a string (destructively). */ + +void +cp_wstrip(char *str) +{ + char c, d; + + if (str) + while ((c = *str)) { /* assign and test */ + d = strip(c); + if (c != d) + *str = d; + str++; + } + return; +} + +/* Quote all characters in a word. */ + +void +cp_quoteword(char *str) +{ + if (str) + while (*str) { + *str = quote(*str); + str++; + } + return; +} + +/* Print a word (strip the word first). */ + +void +cp_printword(char *string, FILE *fp) +{ + char *s; + + if (string) + for (s = string; *s; s++) + (void) putc((strip(*s)), fp); + return; +} + +/* (Destructively) strip all the words in a wlist. */ + +void +cp_striplist(wordlist *wlist) +{ + wordlist *wl; + + for (wl = wlist; wl; wl = wl->wl_next) + cp_wstrip(wl->wl_word); + return; +} + +/* Remove the "" from a string. */ + +char * +cp_unquote(char *string) +{ + char *s; + int l; + if (string) { + s = copy(string); + + if (*s == '"') + s++; + + l = strlen(s) - 1; + if (s[l] == '"') + s[l] = '\0'; + return (s); + } else + return 0; +} diff --git a/src/frontend/quote.h b/src/frontend/quote.h new file mode 100644 index 000000000..5a9b659cc --- /dev/null +++ b/src/frontend/quote.h @@ -0,0 +1,17 @@ +/************* + * Header file for quote.c + * 1999 E. Rouat + ************/ + +#ifndef QUOTE_H_INCLUDED +#define QUOTE_H_INCLUDED + + +void cp_wstrip(char *str); +void cp_quoteword(char *str); +void cp_printword(char *string, FILE *fp); +void cp_striplist(wordlist *wlist); +char * cp_unquote(char *string); + + +#endif 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/streams.c b/src/frontend/streams.c new file mode 100644 index 000000000..2c7b38049 --- /dev/null +++ b/src/frontend/streams.c @@ -0,0 +1,216 @@ +#include +#include +#include +#include + +#include "variable.h" +#include "terminal.h" +#include "quote.h" +#include "streams.h" + + +bool cp_debug = FALSE; +char cp_gt = '>'; +char cp_lt = '<'; +char cp_amp = '&'; + +FILE *cp_in; +FILE *cp_out; +FILE *cp_err; + +/* These are the fps that cp_ioreset resets the cp_* to. They are + * changed by the source routines. */ + +FILE *cp_curin = NULL; +FILE *cp_curout = NULL; +FILE *cp_curerr = NULL; + + +static bool +fileexists(char *name) +{ +#ifdef HAVE_ACCESS + if (access(name, 0) == 0) + return (TRUE); +#endif + return (FALSE); +} + + +/* This routine sets the cp_{in,out,err} pointers and takes the io + * directions out of the command line. */ +wordlist * +cp_redirect(wordlist *wl) +{ + bool gotinput = FALSE, gotoutput = FALSE, goterror = FALSE; + bool app = FALSE, erralso = FALSE; + wordlist *w, *bt, *nw; + char *s,*copyword; + FILE *tmpfp; + + w = wl->wl_next; /* Don't consider empty commands. */ + while (w) { + if (*w->wl_word == cp_lt) { + bt = w; + if (gotinput) { + fprintf(cp_err, + "Error: ambiguous input redirect.\n"); + goto error; + } + gotinput = TRUE; + w = w->wl_next; + if (w == NULL) { + fprintf(cp_err, + "Error: missing name for input.\n"); + return (NULL); + } + if (*w->wl_word == cp_lt) { + /* Do reasonable stuff here... */ + } else { + /*tmpfp = fopen(cp_unquote(w->wl_word), "r"); DG very bad: memory leak the string allocated by cp_unquote is lost*/ + copyword=cp_unquote(w->wl_word);/*DG*/ + tmpfp = fopen(copyword, "r"); + tfree(copyword); + + if (!tmpfp) { + perror(w->wl_word); + goto error; + } else + cp_in = tmpfp; + } +#ifdef CPDEBUG + if (cp_debug) + fprintf(cp_err, "Input file is %s...\n", + w->wl_word); +#endif + bt->wl_prev->wl_next = w->wl_next; + if (w->wl_next) + w->wl_next->wl_prev = bt->wl_prev; + nw = w->wl_next; + w->wl_next = NULL; + w = nw; + wl_free(bt); + } else if (*w->wl_word == cp_gt) { + bt = w; + if (gotoutput) { + fprintf(cp_err, + "Error: ambiguous output redirect.\n"); + goto error; + } + gotoutput = TRUE; + w = w->wl_next; + if (w == NULL) { + fprintf(cp_err, + "Error: missing name for output.\n"); + return (NULL); + } + if (*w->wl_word == cp_gt) { + app = TRUE; + w = w->wl_next; + if (w == NULL) { + fprintf(cp_err, + "Error: missing name for output.\n"); + return (NULL); + } + } + if (*w->wl_word == cp_amp) { + erralso = TRUE; + if (goterror) { + fprintf(cp_err, + "Error: ambiguous error redirect.\n"); + return (NULL); + } + goterror = TRUE; + w = w->wl_next; + if (w == NULL) { + fprintf(cp_err, + "Error: missing name for output.\n"); + return (NULL); + } + } + s = cp_unquote(w->wl_word); + if (cp_noclobber && fileexists(s)) { + fprintf(stderr, "Error: %s: file exists\n", s); + goto error; + } + if (app) + tmpfp = fopen(s, "a"); + else + tmpfp = fopen(s, "w+"); + tfree(s);/*DG cp_unquote memory leak*/ + if (!tmpfp) { + perror(w->wl_word); + goto error; + } else { + cp_out = tmpfp; + out_isatty = FALSE; + } +#ifdef CPDEBUG + if (cp_debug) + fprintf(cp_err, "Output file is %s... %s\n", + w->wl_word, app ? "(append)" : ""); +#endif + bt->wl_prev->wl_next = w->wl_next; + if (w->wl_next) + w->wl_next->wl_prev = bt->wl_prev; + w = w->wl_next; + if (w) + w->wl_prev->wl_next = NULL; + wl_free(bt); + if (erralso) + cp_err = cp_out; + } else + w = w->wl_next; + } + return (wl); + +error: wl_free(wl); + return (NULL); +} + +/* Reset the cp_* FILE pointers to the standard ones. This is tricky, + * since if we are sourcing a command file, and io has been redirected + * from inside the file, we have to reset it back to what it was for + * the source, not for the top level. That way if you type "foo > + * bar" where foo is a script, and it has redirections of its own + * inside of it, none of the output from foo will get sent to + * stdout... */ + +void +cp_ioreset(void) +{ + if (cp_in != cp_curin) { + if (cp_in) + fclose(cp_in); + cp_in = cp_curin; + } + if (cp_out != cp_curout) { + if (cp_out) + fclose(cp_out); + cp_out = cp_curout; + } + if (cp_err != cp_curerr) { + if (cp_err) + fclose(cp_err); + cp_err = cp_curerr; + } + + /*** Minor bug here... */ + out_isatty = TRUE; + return; +} + + +/* Do this only right before an exec, since we lose the old std*'s. */ + +void +fixdescriptors(void) +{ + if (cp_in != stdin) + dup2(fileno(cp_in), fileno(stdin)); + if (cp_out != stdout) + dup2(fileno(cp_out), fileno(stdout)); + if (cp_err != stderr) + dup2(fileno(cp_err), fileno(stderr)); + return; +} diff --git a/src/frontend/streams.h b/src/frontend/streams.h new file mode 100644 index 000000000..44bc27765 --- /dev/null +++ b/src/frontend/streams.h @@ -0,0 +1,8 @@ +#ifndef _STREAMS_H +#define _STREAMS_H + +extern FILE *cp_in; +extern FILE *cp_out; +extern FILE *cp_err; + +#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/terminal.c b/src/frontend/terminal.c new file mode 100644 index 000000000..37037c56c --- /dev/null +++ b/src/frontend/terminal.c @@ -0,0 +1,330 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* + * Routines to handle "more"d output. There are some serious system + * dependencies in here, and it isn't clear that versions of this stuff + * can be written for every possible machine... + */ +#include + +#ifdef HAVE_SGTTY_H +#include +#endif + +#if 0 +/* Bad interaction with bool type in bool.h because curses also + defines this symbol. */ +#ifdef HAVE_TERMCAP +#include +#include +#endif +#endif + +#ifdef HAVE_TERMCAP +#include +#endif + +#include +#include + +#include "variable.h" +#include "terminal.h" + +static char *motion_chars; +static char *clear_chars; +static char *home_chars; +static char *cleol_chars; + + +#define DEF_SCRHEIGHT 24 +#define DEF_SCRWIDTH 80 + +bool out_moremode = TRUE; +bool out_isatty = TRUE; + +static int xsize, ysize; +static int xpos, ypos; +static bool noprint, nopause; + + +/* out_printf doesn't handle double arguments correctly, so we + sprintf into this buf and call out_send w/ it */ +char out_pbuf[BSIZE_SP]; + +/* Start output... */ + +void +out_init(void) +{ +#ifdef TIOCGWINSZ + struct winsize ws; +#endif + bool moremode; + + noprint = nopause = FALSE; + + if (cp_getvar("nomoremode", VT_BOOL, (char *) &moremode)) + out_moremode = FALSE; + else + out_moremode = TRUE; + if (!out_moremode || !cp_interactive) + out_isatty = FALSE; + + if (!out_isatty) + return; + + xsize = ysize = 0; + + /* Figure out the screen size. We try, in order, TIOCGSIZE, + * tgetent(), and cp_getvar(height). Default is 24 x 80. + */ + +#ifdef TIOCGWINSZ + if (!xsize || !ysize) { + (void) ioctl(fileno(stdout), TIOCGWINSZ, (char *) &ws); + xsize = ws.ws_col; + ysize = ws.ws_row; + } +#endif + + if (!xsize) + (void) cp_getvar("width", VT_NUM, (char *) &xsize); + if (!ysize) + (void) cp_getvar("height", VT_NUM, (char *) &ysize); + + if (!xsize) + xsize = DEF_SCRWIDTH; + if (!ysize) + ysize = DEF_SCRHEIGHT; + ysize -= 2; /* Fudge room... */ + xpos = ypos = 0; + + return; +} + +/* Putc may not be buffered (sp?), so we do it ourselves. */ + +static char staticbuf[BUFSIZ]; +struct { + int count; + char *ptr; +} ourbuf = { BUFSIZ, staticbuf }; + +/* send buffer out */ +void +outbufputc(void) +{ + + if (ourbuf.count != BUFSIZ) { + fputs(staticbuf, cp_out); + memset(staticbuf, 0, BUFSIZ-ourbuf.count); + ourbuf.count = BUFSIZ; + ourbuf.ptr = staticbuf; + } + +} + +static void +bufputc(char c) +{ + if (--ourbuf.count >= 0) { + *ourbuf.ptr++ = c; + } else { + /* Flush and reset the buffer */ + outbufputc(); + /* and store the character. */ + ourbuf.count--; + *ourbuf.ptr++ = c; + } +} + + +/* prompt for a return */ +void +promptreturn(void) +{ + char buf[16]; +moe: + fprintf(cp_out, + "\n\t-- hit return for more, ? for help -- "); + if (!fgets(buf, 16, cp_in)) { + clearerr(cp_in); + *buf = 'q'; + } + switch (*buf) { + case '\n': + break; + case 'q': + noprint = TRUE; + break; + case 'c': + nopause = TRUE; + break; + case ' ': + break; + case '?': + fprintf(cp_out, +"\nPossible responses:\n\ +\t : Print another screenful\n\ +\tq : Discard the rest of the output\n\ +\tc : Continuously print the rest of the output\n\ +\t? : Print this help message\n"); + goto moe; + default: + fprintf(cp_out, "Character %d is no good\n", *buf); + goto moe; + } + +} + +/* Print a string to the output. If this would cause the screen to scroll, + * print "more". + */ + +void +out_send(char *string) +{ + + if (noprint) + return; + if (!out_isatty || nopause) { + fputs(string, cp_out); + return; + } + while (*string) { + switch (*string) { + case '\n': + xpos = 0; + ypos++; + break; + case '\f': + ypos = ysize; + xpos = 0; + break; + case '\t': + xpos = xpos / 8 + 1; + xpos *= 8; + break; + default: + xpos++; + break; + } + while (xpos >= xsize) { + xpos -= xsize; + ypos++; + } + if (ypos >= ysize) { + outbufputc(); /* out goes buffer */ + promptreturn(); + (void) fflush(cp_out); + ypos = xpos = 0; + } + bufputc(*string); /* we need to buffer these */ + string++; + } + (void) outbufputc(); + return; +} + +/* Printf some stuff using more mode. */ + +#define MAXLEN 4096 + + +void +out_printf(char *fmt, char *s1, char *s2, char *s3, char *s4, char *s5, char *s6, char *s7, char *s8, char *s9, char *s10) +{ + char buf[MAXLEN]; + + sprintf(buf, fmt, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10); + + out_send(buf); + return; +} + +static int +outfn(int c) +{ + putc(c, stdout); + return c; +} + + +void +tcap_init(void) +{ + char *s; +#ifdef HAVE_TERMCAP + char tbuf[1025]; + static char buf2[100]; + char *charbuf; + + charbuf = buf2; + + if ((s = getenv("TERM"))) { + if (tgetent(tbuf, s) != -1) { + xsize = tgetnum("co"); + ysize = tgetnum("li"); + if ((xsize <= 0) || (ysize <= 0)) + xsize = ysize = 0; + clear_chars = (char *) tgetstr("cl", &charbuf); + motion_chars = (char *) tgetstr("cm", &charbuf); + home_chars = (char *) tgetstr("ho", &charbuf); + cleol_chars = (char *) tgetstr("ce", &charbuf); + } + } +#endif + + if (!xsize) { + if ((s = getenv("COLS"))) + xsize = atoi(s); + if (xsize <= 0) + xsize = 0; + } + + if (!ysize) { + if ((s = getenv("LINES"))) + ysize = atoi(s); + if (ysize <= 0) + ysize = 0; + } +} + + +void +term_clear(void) +{ +#ifdef HAVE_TERMCAP + if (*clear_chars) + tputs(clear_chars, 1, outfn); + else + fputs("\n", stdout); +#endif +} + + +void +term_home(void) +{ +#ifdef HAVE_TERMCAP + if (*home_chars) + tputs(home_chars, 1, outfn); + else if (*motion_chars) + tputs(tgoto(motion_chars, 1, 1), 1, outfn); + else + fputs("\n", stdout); +#endif +} + + +void +term_cleol(void) +{ +#ifdef HAVE_TERMCAP + if (*cleol_chars) + tputs(cleol_chars, 1, outfn); +#endif +} diff --git a/src/frontend/terminal.h b/src/frontend/terminal.h new file mode 100644 index 000000000..bf045a59f --- /dev/null +++ b/src/frontend/terminal.h @@ -0,0 +1,18 @@ +#ifndef _TERMINAL_H +#define _TERMINAL_H + +extern bool out_isatty; + +void out_init(void); +void outbufputc(void); +void promptreturn(void); +void out_send(char *string); +void out_printf(char *fmt, char *s1, char *s2, char *s3, + char *s4, char *s5, char *s6, + char *s7, char *s8, char *s9, char *s10); +void term_clear(void); +void term_home(void); +void term_cleol(void); +void tcap_init(void); + +#endif 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/variable.c b/src/frontend/variable.c new file mode 100644 index 000000000..39b57c0c4 --- /dev/null +++ b/src/frontend/variable.c @@ -0,0 +1,823 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "circuits.h" +#include "com_history.h" +#include "quote.h" +#include "streams.h" +#include "variable.h" + + +bool cp_noglob = TRUE; +bool cp_nonomatch = FALSE; +bool cp_noclobber = FALSE; +bool cp_ignoreeof = FALSE; + +struct variable *variables = NULL; + +wordlist * +cp_varwl(struct variable *var) +{ + wordlist *wl = NULL, *w, *wx = NULL; + char buf[BSIZE_SP],*copystring; + struct variable *vt; + + switch(var->va_type) { + case VT_BOOL: + /* Can't ever be FALSE. */ + sprintf(buf, "%s", var->va_bool ? "TRUE" : "FALSE"); + break; + case VT_NUM: + sprintf(buf, "%d", var->va_num); + break; + case VT_REAL: + /* This is a case where printnum isn't too good... */ + sprintf(buf, "%G", var->va_real); + break; + case VT_STRING: + /*strcpy(buf, cp_unquote(var->va_string)); DG: memory leak here*/ + copystring= cp_unquote(var->va_string);/*DG*/ + strcpy(buf,copystring); + tfree(copystring); + + break; + case VT_LIST: /* The tricky case. */ + for (vt = var->va_vlist; vt; vt = vt->va_next) { + w = cp_varwl(vt); + if (wl == NULL) + wl = wx = w; + else { + wx->wl_next = w; + w->wl_prev = wx; + wx = w; + } + } + return (wl); + default: + fprintf(cp_err, + "cp_varwl: Internal Error: bad variable type %d\n", + var->va_type); + return (NULL); + } + wl = alloc(struct wordlist); + wl->wl_next = wl->wl_prev = NULL; + wl->wl_word = copy(buf); + return (wl); +} + + +/* Set a variable. */ +void +cp_vset(char *varname, char type, char *value) +{ + struct variable *v, *u, *w; + int i; + bool alreadythere = FALSE; + char* copyvarname; + + + /* varname = cp_unquote(varname); DG: Memory leak old varname is lost*/ + + copyvarname = cp_unquote(varname); + + w = NULL; + for (v = variables; v; v = v->va_next) { + if (eq(copyvarname, v->va_name)) { + alreadythere = TRUE; + break; + } + w = v; + } + if (!v) { + v = alloc(struct variable); + v->va_name = copy(copyvarname); + v->va_next = NULL; + } + switch (type) { + case VT_BOOL: + if (* ((bool *) value) == FALSE) { + cp_remvar(copyvarname); + return; + } else + v->va_bool = TRUE; + break; + + case VT_NUM: + v->va_num = * (int *) value; + break; + + case VT_REAL: + v->va_real = * (double *) value; + break; + + case VT_STRING: + v->va_string = copy(value); + break; + + case VT_LIST: + v->va_vlist = (struct variable *) value; + break; + + default: + fprintf(cp_err, + "cp_vset: Internal Error: bad variable type %d.\n", + type); + return; + } + v->va_type = type; + + /* Now, see if there is anything interesting going on. We + * recognise these special variables: noglob, nonomatch, history, + * echo, noclobber, prompt, and verbose. cp_remvar looks for these + * variables too. The host program will get any others. */ + if (eq(copyvarname, "noglob")) + cp_noglob = TRUE; + else if (eq(copyvarname, "nonomatch")) + cp_nonomatch = TRUE; + else if (eq(copyvarname, "history") && (type == VT_NUM)) + cp_maxhistlength = v->va_num; + else if (eq(copyvarname, "history") && (type == VT_REAL)) + cp_maxhistlength = v->va_real; + else if (eq(copyvarname, "noclobber")) + cp_noclobber = TRUE; + else if (eq(copyvarname, "prompt") && (type == VT_STRING)) + cp_promptstring = copy(v->va_string); + else if (eq(copyvarname, "ignoreeof")) + cp_ignoreeof = TRUE; + else if (eq(copyvarname, "cpdebug")) { + cp_debug = TRUE; +#ifndef CPDEBUG + fprintf(cp_err, + "Warning: program not compiled with cshpar debug messages\n"); +#endif + } + + switch (i = cp_usrset(v, TRUE)) { + + case US_OK: + /* Normal case. */ + if (!alreadythere) { + v->va_next = variables; + variables = v; + } + break; + + case US_DONTRECORD: + /* Do nothing... */ + if (alreadythere) { + fprintf(cp_err, "cp_vset: Internal Error: " + "%s already there, but 'dont record'\n", v->va_name); + } + break; + + case US_READONLY: + fprintf(cp_err, "Error: %s is a read-only variable.\n", v->va_name); + if (alreadythere) + fprintf(cp_err, "cp_vset: Internal Error: " + "it was already there too!!\n"); + break; + + case US_SIMVAR: + if (alreadythere) { + /* somehow it got into the front-end list of variables */ + if (w) { + w->va_next = v->va_next; + } else { + variables = v->va_next; + } + } + alreadythere = FALSE; + if (ft_curckt) { + for (u = ft_curckt->ci_vars; u; u = u->va_next) + if (eq(copyvarname, u->va_name)) { + alreadythere = TRUE; + break; + } + if (!alreadythere) { + v->va_next = ft_curckt->ci_vars; + ft_curckt->ci_vars = v; + } else { + w = u->va_next; + bcopy(v, u, sizeof(*u)); + u->va_next = w; + } + } + break; + + case US_NOSIMVAR: + /* What do you do? */ + tfree(v); + + break; + + default: + fprintf(cp_err, "cp_vset: Internal Error: bad US val %d\n", i); + break; + } + tfree(copyvarname); + return; +} + + +struct variable * +cp_setparse(wordlist *wl) +{ + char *name, *val, *copyval, *s, *ss; + double *td; + struct variable *listv = NULL, *vv, *lv = NULL; + struct variable *vars = NULL; + int balance; + + while (wl) { + name = cp_unquote(wl->wl_word); + wl = wl->wl_next; + if (((wl == NULL) || (*wl->wl_word != '=')) && + strchr(name, '=') == NULL) { + vv = alloc(struct variable); + vv->va_name = copy(name); + vv->va_type = VT_BOOL; + vv->va_bool = TRUE; + vv->va_next = vars; + vars = vv; + tfree(name);/*DG: cp_unquote Memory leak*/ + continue; + } + if (wl && eq(wl->wl_word, "=")) { + wl = wl->wl_next; + if (wl == NULL) { + fprintf(cp_err, "Error: bad set form.\n"); + tfree(name);/*DG: cp_unquote Memory leak*/ + return (NULL); + } + val = wl->wl_word; + wl = wl->wl_next; + } else if (wl && (*wl->wl_word == '=')) { + val = wl->wl_word + 1; + wl = wl->wl_next; + } else if ((s =strchr(name, '='))) { + val = s + 1; + *s = '\0'; + if (*val == '\0') { + if (!wl) { + fprintf(cp_err, + "Error: %s equals what?.\n", + name); + tfree(name);/*DG: cp_unquote Memory leak: free name before exiting*/ + return (NULL); + } else { + val = wl->wl_word; + wl = wl->wl_next; + } + } + } else { + fprintf(cp_err, "Error: bad set form.\n"); + tfree(name);/*DG: cp_unquote Memory leak: free name befor exiting */ + return (NULL); + } + /* val = cp_unquote(val); DG: bad old val is lost*/ + copyval=cp_unquote(val);/*DG*/ + strcpy(val,copyval); + tfree(copyval); + if (eq(val, "(")) { /* ) */ + /* The beginning of a list... We have to walk down the + * list until we find a close paren... If there are nested + * ()'s, treat them as tokens... */ + balance = 1; + while (wl && wl->wl_word) { + if (eq(wl->wl_word, "(")) { + balance++; + } else if (eq(wl->wl_word, ")")) { + if (!--balance) + break; + } + vv = alloc(struct variable); + vv->va_next = NULL; + copyval = ss = cp_unquote(wl->wl_word); + td = ft_numparse(&ss, FALSE); + if (td) { + vv->va_type = VT_REAL; + vv->va_real = *td; + } else { + vv->va_type = VT_STRING; + vv->va_string = copy(ss); + } + tfree(copyval);/*DG: must free ss any way to avoid cp_unquote memory leak*/ + if (listv) { + lv->va_next = vv; + lv = vv; + } else + listv = lv = vv; + wl = wl->wl_next; + } + if (balance && !wl) { + fprintf(cp_err, "Error: bad set form.\n"); + return (NULL); + } + + vv = alloc(struct variable); + vv->va_name = copy(name); + vv->va_type = VT_LIST; + vv->va_vlist = listv; + vv->va_next = vars; + vars = vv; + + wl = wl->wl_next; + continue; + } + + copyval = ss = cp_unquote(val); + td = ft_numparse(&ss, FALSE); + vv = alloc(struct variable); + vv->va_name = copy(name); + vv->va_next = vars; + vars = vv; + if (td) { + /*** We should try to get VT_NUM's... */ + vv->va_type = VT_REAL; + vv->va_real = *td; + } else { + vv->va_type = VT_STRING; + vv->va_string = copy(val); + } + tfree(copyval);/*DG: must free ss any way to avoid cp_unquote memory leak */ + } + return (vars); +} + + +void +cp_remvar(char *varname) +{ + struct variable *v, *u, *lv = NULL; + bool found = TRUE; + int i; + + for (v = variables; v; v = v->va_next) { + if (eq(v->va_name, varname)) + break; + lv = v; + } + if (!v) { + /* Gotta make up a var struct for cp_usrset()... */ + v = alloc(struct variable); + ZERO(v, struct variable); + v->va_name = varname; + v->va_type = VT_NUM; + v->va_bool = 0; + found = FALSE; + } + + /* Note that 'unset history' doesn't do anything here... Causes + * trouble... */ + if (eq(varname, "noglob")) + cp_noglob = FALSE; + else if (eq(varname, "nonomatch")) + cp_nonomatch = FALSE; + else if (eq(varname, "noclobber")) + cp_noclobber = FALSE; + else if (eq(varname, "prompt")){ + /* cp_promptstring = ""; Memory leak here the last allocated reference wil be lost*/ + if(cp_promptstring) { + strcpy(cp_promptstring,"");/*DG avoid memory leak*/ + } + } + else if (eq(varname, "cpdebug")) + cp_debug = FALSE; + else if (eq(varname, "ignoreeof")) + cp_ignoreeof = FALSE; + + switch (i = cp_usrset(v, FALSE)) { + + case US_OK: + /* Normal case. */ + if (found) { + if (lv) + lv->va_next = v->va_next; + else + variables = v->va_next; + } + break; + + case US_DONTRECORD: + /* Do nothing... */ + if (found) + fprintf(cp_err, "cp_remvar: Internal Error: var %d\n", *varname); + break; + + case US_READONLY: + /* Badness... */ + fprintf(cp_err, "Error: %s is read-only.\n", v->va_name); + if (found) + fprintf(cp_err, "cp_remvar: Internal Error: var %d\n", *varname); + break; + + case US_SIMVAR: + lv = NULL; + if (ft_curckt) { + for (u = ft_curckt->ci_vars; u; u = u->va_next) { + if (eq(varname, u->va_name)) { + break; + } + lv = u; + } + if (u) { + if (lv) + lv->va_next = u->va_next; + else + ft_curckt->ci_vars = u->va_next; + tfree(u); + } + } + break; + + default: + fprintf(cp_err, "cp_remvar: Internal Error: US val %d\n", i); + break; + } + + tfree(v); + return; +} + + +/* Determine the value of a variable. Fail if the variable is unset, + * and if the type doesn't match, try and make it work... */ +bool +cp_getvar(char *name, int type, void *retval) +{ + struct variable *v; + + for (v = variables; v; v = v->va_next) + if (eq(name, v->va_name)) + break; + if (v == NULL) { + if (type == VT_BOOL) + * (bool *) retval = FALSE; + return (FALSE); + } + if (v->va_type == type) { + switch (type) { + case VT_BOOL: + * (bool *) retval = TRUE; + break; + case VT_NUM: { + int *i; + i = (int *) retval; + *i = v->va_num; + break; + } + case VT_REAL: { + double *d; + d = (double *) retval; + *d = v->va_real; + break; + } + case VT_STRING: { /* Gotta be careful to have room. */ + char *s; + s = cp_unquote(v->va_string); + cp_wstrip(s); + (void) strcpy(retval, s); + tfree(s);/*DG*/ + break; + } + case VT_LIST: { /* Funny case... */ + struct variable **tv; + tv = (struct variable **) retval; + *tv = v->va_vlist; + break; + } + default: + fprintf(cp_err, + "cp_getvar: Internal Error: bad var type %d.\n", + type); + break; + } + return (TRUE); + } else { + /* Try to coerce it.. */ + if ((type == VT_NUM) && (v->va_type == VT_REAL)) { + int *i; + i = (int *) retval; + *i = (int) v->va_real; + return (TRUE); + } else if ((type == VT_REAL) && (v->va_type == VT_NUM)) { + double *d; + d = (double *) retval; + *d = (double) v->va_num; + return (TRUE); + } else if ((type == VT_STRING) && (v->va_type == VT_NUM)) { + (void) sprintf(retval, "%d", v->va_num); + return (TRUE); + } else if ((type == VT_STRING) && (v->va_type == VT_REAL)) { + (void) sprintf(retval, "%f", v->va_real); + return (TRUE); + } + return (FALSE); + } +} + + +/* A variable substitution is indicated by a $, and the variable name + * is the following string of non-special characters. All variable + * values are inserted as a single word, except for lists, which are a + * list of words. A routine cp_usrset must be supplied by the host + * program to deal with variables that aren't used by cshpar -- it + * should be cp_usrset(var, isset), where var is a variable *, and + * isset is TRUE if the variable is being set, FALSE if unset. Also + * required is a routine cp_enqvar(name) which returns a struct + * variable *, which allows the host program to provide values for + * non-cshpar variables. */ + +char cp_dol = '$'; + +/* Non-alphanumeric characters that may appear in variable names. < is very + * special... + */ + +#define VALIDCHARS "$-_<#?@.()[]&" + +wordlist * +cp_variablesubst(wordlist *wlist) +{ + wordlist *wl, *nwl; + char *s, *t, buf[BSIZE_SP], wbuf[BSIZE_SP], tbuf[BSIZE_SP]; + /* MW. tbuf holds curret word after wl_splice() calls free() on it */ + int i; + + for (wl = wlist; wl; wl = wl->wl_next) { + t = wl->wl_word; + i = 0; + while ((s =strchr(t, cp_dol))) { + while (t < s) + wbuf[i++] = *t++; + wbuf[i] = '\0'; + (void) strcpy(buf, ++s); + s = buf; + t++; + while (*s && (isalphanum(*s) || + strchr(VALIDCHARS, *s))) { + /* Get s and t past the end of the var name. */ + t++; + s++; + } + *s = '\0'; + nwl = vareval(buf); + if (i) { + (void) strcpy(buf, wbuf); + if (nwl) { + (void) strcat(buf, nwl->wl_word); + tfree(nwl->wl_word); + } else { + nwl = alloc(struct wordlist); + nwl->wl_next = nwl->wl_prev = NULL; + } + nwl->wl_word = copy(buf); + } + + (void) strcpy(tbuf, t); /* MW. Save t*/ + if (!(wl = wl_splice(wl, nwl))) + return (NULL); + /* This is bad... */ + for (wlist = wl; wlist->wl_prev; wlist = wlist->wl_prev) + ; + (void) strcpy(buf, wl->wl_word); + i = strlen(buf); + (void) strcat(buf, tbuf); /* MW. tbuf is used here only */ + + tfree(wl->wl_word); + wl->wl_word = copy(buf); + t = &wl->wl_word[i]; + s = wl->wl_word; + for (i = 0; s < t; s++) + wbuf[i++] = *s; + } + } + return (wlist); +} + + +/* Evaluate a variable. */ +wordlist * +vareval(char *string) +{ + struct variable *v; + wordlist *wl; + char buf[BSIZE_SP], *s; + char *oldstring = copy(string); + char *range = NULL; + int i, up, low; + + cp_wstrip(string); + if ((s =strchr(string, '['))) { + *s = '\0'; + range = s + 1; + } + + switch (*string) { + + case '$': + wl = alloc(struct wordlist); + wl->wl_next = wl->wl_prev = NULL; + + + (void) sprintf(buf, "%d", getpid()); + + wl->wl_word = copy(buf); + return (wl); + + case '<': + (void) fflush(cp_out); + if (!fgets(buf, BSIZE_SP, cp_in)) { + clearerr(cp_in); + (void) strcpy(buf, "EOF"); + } + for (s = buf; *s && (*s != '\n'); s++) + ; + *s = '\0'; + wl = cp_lexer(buf); + /* This is a hack. */ + if (!wl->wl_word) + wl->wl_word = copy(""); + return (wl); + + case '?': + wl = alloc(struct wordlist); + wl->wl_next = wl->wl_prev = NULL; + string++; + for (v = variables; v; v = v->va_next) + if (eq(v->va_name, string)) + break; + if (!v) + v = cp_enqvar(string); + wl->wl_word = copy(v ? "1" : "0"); + return (wl); + + case '#': + wl = alloc(struct wordlist); + wl->wl_next = wl->wl_prev = NULL; + string++; + for (v = variables; v; v = v->va_next) + if (eq(v->va_name, string)) + break; + if (!v) + v = cp_enqvar(string); + if (!v) { + fprintf(cp_err, "Error: %s: no such variable.\n", + string); + return (NULL); + } + if (v->va_type == VT_LIST) + for (v = v->va_vlist, i = 0; v; v = v->va_next) + i++; + else + i = (v->va_type != VT_BOOL); + (void) sprintf(buf, "%d", i); + wl->wl_word = copy(buf); + return (wl); + + case '\0': + wl = alloc(struct wordlist); + wl->wl_next = wl->wl_prev = NULL; + wl->wl_word = copy("$"); + return (wl); + } + + /* The notation var[stuff] has two meanings... If this is a real + * variable, then the [] denotes range, but if this is a strange + * (e.g, device parameter) variable, it could be anything... + */ + for (v = variables; v; v = v->va_next) + if (eq(v->va_name, string)) + break; + if (!v && isdigit(*string)) { + for (v = variables; v; v = v->va_next) + if (eq(v->va_name, "argv")) + break; + range = string; + } + if (!v) { + range = NULL; + string = oldstring; + v = cp_enqvar(string); + } + if (!v && (s = getenv(string))) { + wl = alloc(struct wordlist); + wl->wl_next = wl->wl_prev = NULL; + wl->wl_word = copy(s); + return (wl); + } + if (!v) { + fprintf(cp_err, "Error: %s: no such variable.\n", string); + return (NULL); + } + wl = cp_varwl(v); + + /* Now parse and deal with 'range' ... */ + if (range) { + for (low = 0; isdigit(*range); range++) + low = low * 10 + *range - '0'; + if ((*range == '-') && isdigit(range[1])) + for (up = 0, range++; isdigit(*range); range++) + up = up * 10 + *range - '0'; + else if (*range == '-') + up = wl_length(wl); + else + up = low; + up--, low--; + wl = wl_range(wl, low, up); + } + + return (wl); +} + + +static int +vcmp(const void *a, const void *b) +{ + int i; + struct xxx *v1 = (struct xxx *) a; + struct xxx *v2 = (struct xxx *) b; + if ((i = strcmp(v1->x_v->va_name, v2->x_v->va_name))) + return (i); + else + return (v1->x_char - v2->x_char); +} + + + +/* Print the values of currently defined variables. */ +void +cp_vprint(void) +{ + struct variable *v; + struct variable *uv1, *uv2; + wordlist *wl; + int i, j; + char *s; + struct xxx *vars; + + cp_usrvars(&uv1, &uv2); + + for (v = uv1, i = 0; v; v = v->va_next) + i++; + for (v = uv2; v; v = v->va_next) + i++; + for (v = variables; v; v = v->va_next) + i++; + + vars = (struct xxx *) tmalloc(sizeof (struct xxx) * i); + + out_init(); + for (v = variables, i = 0; v; v = v->va_next, i++) { + vars[i].x_v = v; + vars[i].x_char = ' '; + } + for (v = uv1; v; v = v->va_next, i++) { + vars[i].x_v = v; + vars[i].x_char = '*'; + } + for (v = uv2; v; v = v->va_next, i++) { + vars[i].x_v = v; + vars[i].x_char = '+'; + } + + qsort((char *) vars, i, sizeof (struct xxx), vcmp); + + for (j = 0; j < i; j++) { + if (j && eq(vars[j].x_v->va_name, vars[j - 1].x_v->va_name)) + continue; + v = vars[j].x_v; + if (v->va_type == VT_BOOL) { +/* out_printf("%c %s\n", vars[j].x_char, v->va_name); */ + sprintf(out_pbuf, "%c %s\n", vars[j].x_char, v->va_name); + out_send(out_pbuf); + } else { + out_printf("%c %s\t", vars[j].x_char, v->va_name); + wl = vareval(v->va_name); + s = wl_flatten(wl); + if (v->va_type == VT_LIST) { + out_printf("( %s )\n", s); + } else + out_printf("%s\n", s); + } + } + + tfree(vars); + return; +} diff --git a/src/frontend/variable.h b/src/frontend/variable.h new file mode 100644 index 000000000..161d6b90e --- /dev/null +++ b/src/frontend/variable.h @@ -0,0 +1,57 @@ +#ifndef _VARIABLE_H +#define _VARIABLE_H + +/* 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 + +enum vt_types { + VT_BOOL, + VT_NUM, + VT_REAL, + VT_STRING, + VT_LIST +}; + +struct xxx { + struct variable *x_v; + char x_char; +} ; + + +extern struct variable *variables; +extern bool cp_noglob; +extern bool cp_nonomatch; +extern bool cp_noclobber; +extern bool cp_ignoreeof; + +// extern struct variable *variables; +wordlist * cp_varwl(struct variable *var); +void cp_vset(char *varname, char type, char *value); +struct variable * cp_setparse(wordlist *wl); +void cp_remvar(char *varname); +bool cp_getvar(char *name, int type, void *retval); +wordlist * cp_variablesubst(wordlist *wlist); +wordlist * vareval(char *string); +void cp_vprint(void); + + +#endif 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/bool.h b/src/include/bool.h new file mode 100644 index 000000000..868c6653a --- /dev/null +++ b/src/include/bool.h @@ -0,0 +1,8 @@ +#ifndef _BOOL_H +#define _BOOL_H + +typedef unsigned char bool; +#define TRUE 1 +#define FALSE 0 + +#endif 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/cluster.h b/src/include/cluster.h new file mode 100755 index 000000000..6e4dde2d6 --- /dev/null +++ b/src/include/cluster.h @@ -0,0 +1,24 @@ +#ifndef _CLUSTER_H_ +#define _CLUSTER_H_ +#include + +/* Cluster definitions */ +#define PORT 1234 +#define TIME_PORT 1235 +#define DOMAIN_NAME "cluster.multigig" +#define CLUSTER_WIDTH 4 +#define TIME_HOST "time.cluster.multigig" +/* does all the setups */ +extern int CLUsetup(CKTcircuit *ckt); + +/* reads input pipes and sets voltages*/ +/* call each time the present time is changed, ie just before NIinter*/ +extern int CLUinput(CKTcircuit *ckt); + +/* call after each accepted timestep, ie CKTdump */ +extern int CLUoutput(CKTcircuit *ckt); + + +/* the time step control */ +extern int CLUsync(double time,double *delta, int error); +#endif diff --git a/src/include/cm.h b/src/include/cm.h new file mode 100755 index 000000000..8590f50b9 --- /dev/null +++ b/src/include/cm.h @@ -0,0 +1,49 @@ +#ifndef CM_DEFINED +#define CM_DEFINED + +/* =========================================================================== +FILE CM.h + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file is includes all include data in the CM package. + +INTERFACES + + None. + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + +#include "cmtypes.h" +#include "cmconstants.h" // K.A. wrong name +//#include "Cmconsta.h" +#include "cmproto.h" +#include "mifcmdat.h" + + +#endif /* CM_DEFINED */ diff --git a/src/include/cmconstants.h b/src/include/cmconstants.h new file mode 100755 index 000000000..13d9146be --- /dev/null +++ b/src/include/cmconstants.h @@ -0,0 +1,57 @@ +#ifndef CMCONSTANTS_DEFINED +#define CMCONSTANTS_DEFINED + +/* =========================================================================== +FILE CMconstants.h + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains constants used by code models. + +INTERFACES + + None. + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + +#include "miftypes.h" + +/***** Define Constants *******************************************/ + +#define FALSE 0 +#define TRUE 1 + +#define DC MIF_DC +#define AC MIF_AC +#define TRANSIENT MIF_TRAN + +#define ANALOG MIF_ANALOG +#define EVENT MIF_EVENT_DRIVEN + + +#endif /* CMCONSTANTS_DEFINED */ diff --git a/src/include/cmproto.h b/src/include/cmproto.h new file mode 100755 index 000000000..9f8baf5ed --- /dev/null +++ b/src/include/cmproto.h @@ -0,0 +1,95 @@ +#ifndef CMPROTO_DEFINED +#define CMPROTO_DEFINED + +/* =========================================================================== +FILE CMproto.h + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Jeff Murray, Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains ANSI C function prototypes for cm_xxx functions + called by code models. + +INTERFACES + + None. + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + +/* Prototypes for functions used by internal code models */ +/* The actual functions reside in ../ICM/CMutil.c */ +/* 12/17/90 */ + + +#include "cmtypes.h" + + +void cm_climit_fcn(double in, double in_offset, double cntl_upper, + double cntl_lower, double lower_delta, + double upper_delta, double limit_range, + double gain, int percent, double *out_final, + double *pout_pin_final, double *pout_pcntl_lower_final, + double *pout_pcntl_upper_final); + + + +void cm_smooth_corner(double x_input, double x_center, double y_center, + double domain, double lower_slope, double upper_slope, + double *y_output, double *dy_dx); +void cm_smooth_discontinuity(double x_input, double x_lower, double y_lower, + double x_upper, double y_upper, + double *y_output, double *dy_dx); +double cm_smooth_pwl(double x_input, double *x, double *y, int size, + double input_domain, double *dout_din); + +double cm_analog_ramp_factor(void); +void *cm_analog_alloc(int tag, int bytes); +void *cm_analog_get_ptr(int tag, int timepoint); +int cm_analog_integrate(double integrand, double *integral, double *partial); +int cm_analog_converge(double *state); +int cm_analog_set_temp_bkpt(double time); +int cm_analog_set_perm_bkpt(double time); +void cm_analog_not_converged(void); +void cm_analog_auto_partial(void); + +void *cm_event_alloc(int tag, int bytes); +void *cm_event_get_ptr(int tag, int timepoint); +int cm_event_queue(double time); + +char *cm_message_get_errmsg(void); +int cm_message_send(char *msg); + +double cm_netlist_get_c(void); +double cm_netlist_get_l(void); + +Complex_t cm_complex_set(double real, double imag); +Complex_t cm_complex_add(Complex_t x, Complex_t y); +Complex_t cm_complex_subtract(Complex_t x, Complex_t y); +Complex_t cm_complex_multiply(Complex_t x, Complex_t y); +Complex_t cm_complex_divide(Complex_t x, Complex_t y); + +#endif /* CMPROTO_DEFINED */ diff --git a/src/include/cmtypes.h b/src/include/cmtypes.h new file mode 100755 index 000000000..372e0aa04 --- /dev/null +++ b/src/include/cmtypes.h @@ -0,0 +1,71 @@ +#ifndef CMTYPES_DEFINED +#define CMTYPES_DEFINED + +/* =========================================================================== +FILE CMtypes.h + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Jeff Murray, Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains type definitions used by code models. + +INTERFACES + + None. + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + +#include "miftypes.h" + +/***** Define Typedefs ********************************************/ + +typedef int Boolean_t; + +typedef Mif_Complex_t Complex_t; + + +typedef enum { + ZERO, /* Normally referenced as 0 */ + ONE, /* Normally referenced as 1 */ + UNKNOWN, /* Unknown */ +} Digital_State_t; + +typedef enum { + STRONG, /* strong */ + RESISTIVE, /* resistive */ + HI_IMPEDANCE, /* high impedance */ + UNDETERMINED, /* unknown strength */ +} Digital_Strength_t; + +typedef struct { + Digital_State_t state; + Digital_Strength_t strength; +} Digital_t; + + + +#endif /* CMTYPES_DEFINED */ 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/dllitf.h b/src/include/dllitf.h new file mode 100755 index 000000000..716b13da6 --- /dev/null +++ b/src/include/dllitf.h @@ -0,0 +1,79 @@ +/* + DLL load interface + (c)2000 Arpad Buermen +*/ + +#ifndef __DLLITF_H +#define __DLLITF_H + +#include "mifproto.h" +#include "cmproto.h" + + +// This structure contains pointers to core SPICE OPUS functions used in CMs and UDNs. +// A pointer to this structure is passed to the dll when the dll is loaded. + +struct coreInfo_t { + // MIF stuff + void ((*dllitf_MIF_INP2A)(void *, INPtables *, card *)); + char * ((*dllitf_MIFgetMod)(void *, char *, INPmodel **, INPtables *)); + IFvalue * ((*dllitf_MIFgetValue)(void *, char **, int, INPtables *, char **)); + int ((*dllitf_MIFsetup)(SMPmatrix *, GENmodel *, CKTcircuit *, int *)); + int ((*dllitf_MIFunsetup)(GENmodel *, CKTcircuit *)); + int ((*dllitf_MIFload)(GENmodel *, CKTcircuit *)); + int ((*dllitf_MIFmParam)(int, IFvalue *, GENmodel *)); + int ((*dllitf_MIFask)(CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *)); + int ((*dllitf_MIFmAsk)(CKTcircuit *, GENmodel *, int, IFvalue *)); + int ((*dllitf_MIFtrunc)(GENmodel *, CKTcircuit *, double *)); + int ((*dllitf_MIFconvTest)(GENmodel *, CKTcircuit *)); + int ((*dllitf_MIFdelete)(GENmodel *, IFuid, GENinstance **)); + int ((*dllitf_MIFmDelete)(GENmodel **, IFuid, GENmodel *)); + void ((*dllitf_MIFdestroy)(GENmodel **)); + char * ((*dllitf_MIFgettok)(char **)); + char * ((*dllitf_MIFget_token)(char **, Mif_Token_Type_t *)); + Mif_Cntl_Src_Type_t ((*dllitf_MIFget_cntl_src_type)(Mif_Port_Type_t, Mif_Port_Type_t)); + char * ((*dllitf_MIFcopy)(char *)); + // CM stuff + void ((*dllitf_cm_climit_fcn)(double, double, double, double, double, double, + double, double, int, double *, double *, double *, + double *)); + void ((*dllitf_cm_smooth_corner)(double, double, double, double, double, double, + double *, double *)); + void ((*dllitf_cm_smooth_discontinuity)(double, double, double, double, double, + double *, double *)); + double ((*dllitf_cm_smooth_pwl)(double, double *, double *, int, double, double *)); + double ((*dllitf_cm_analog_ramp_factor)(void)); + void * ((*dllitf_cm_analog_alloc)(int, int)); + void * ((*dllitf_cm_analog_get_ptr)(int, int)); + int ((*dllitf_cm_analog_integrate)(double, double *, double *)); + int ((*dllitf_cm_analog_converge)(double *)); + int ((*dllitf_cm_analog_set_temp_bkpt)(double)); + int ((*dllitf_cm_analog_set_perm_bkpt)(double)); + void ((*dllitf_cm_analog_not_converged)(void)); + void ((*dllitf_cm_analog_auto_partial)(void)); + void * ((*dllitf_cm_event_alloc)(int, int)); + void * ((*dllitf_cm_event_get_ptr)(int, int)); + int ((*dllitf_cm_event_queue)(double)); + char * ((*dllitf_cm_message_get_errmsg)(void)); + int ((*dllitf_cm_message_send)(char *)); + double ((*dllitf_cm_netlist_get_c)(void)); + double ((*dllitf_cm_netlist_get_l)(void)); + Complex_t ((*dllitf_cm_complex_set)(double, double)); + Complex_t ((*dllitf_cm_complex_add)(Complex_t, Complex_t)); + Complex_t ((*dllitf_cm_complex_subtract)(Complex_t, Complex_t)); + Complex_t ((*dllitf_cm_complex_multiply)(Complex_t, Complex_t)); + Complex_t ((*dllitf_cm_complex_divide)(Complex_t, Complex_t)); + FILE * ((*dllitf_cm_stream_out)(void)); + FILE * ((*dllitf_cm_stream_in)(void)); + FILE * ((*dllitf_cm_stream_err)(void)); + /*Other stuff*/ + void * ((*dllitf_malloc_pj)(size_t)); + void * ((*dllitf_calloc_pj)(size_t, size_t)); + void * ((*dllitf_realloc_pj)(void *, size_t)); + void ((*dllitf_free_pj)(void *)); + char * ((*dllitf_tmalloc)(int)); + char * ((*dllitf_trealloc)(char *, int)); + void ((*dllitf_txfree)(char *)); +}; + +#endif diff --git a/src/include/dvec.h b/src/include/dvec.h new file mode 100644 index 000000000..44d6c04fe --- /dev/null +++ b/src/include/dvec.h @@ -0,0 +1,71 @@ +#ifndef _DVEC_H +#define _DVEC_H + +#include "complex.h" +#include "grid.h" + + +/* Dvec flags. */ +enum dvec_flags { + VF_REAL = (1 << 0), /* The data is real. */ + VF_COMPLEX = (1 << 1), /* The data is complex. */ + VF_ACCUM = (1 << 2), /* writedata should save this vector. */ + VF_PLOT = (1 << 3), /* writedata should incrementally plot it. */ + VF_PRINT = (1 << 4), /* writedata should print this vector. */ + VF_MINGIVEN = (1 << 5), /* The v_minsignal value is valid. */ + VF_MAXGIVEN = (1 << 6), /* The v_maxsignal value is valid. */ + VF_PERMANENT = (1 << 7) /* Don't garbage collect this vector. */ +}; + + +/* Plot types. */ +typedef enum { + PLOT_LIN, PLOT_COMB, PLOT_POINT +} PLOTTYPE; + + +/* A (possibly multi-dimensional) data vector. The data is represented + * internally by a 1-d array. The number of dimensions and the size + * of each dimension is recorded, along with v_length, the total size of + * the array. If the dimensionality is 0 or 1, v_length is significant + * instead of v_numdims and v_dims, and the vector is handled in the old + * manner. + */ + +#define MAXDIMS 8 + +struct dvec { + char *v_name; /* Same as so_vname. */ + int v_type; /* Same as so_vtype. */ + short v_flags; /* Flags (a combination of VF_*). */ + double *v_realdata; /* Real data. */ + complex *v_compdata; /* Complex data. */ + double v_minsignal; /* Minimum value to plot. */ + double v_maxsignal; /* Maximum value to plot. */ + GRIDTYPE v_gridtype; /* One of GRID_*. */ + PLOTTYPE v_plottype; /* One of PLOT_*. */ + int v_length; /* Length of the vector. */ + int v_rlength; /* How much space we really have. */ + int v_outindex; /* Index if writedata is building the + vector. */ + int v_linestyle; /* What line style we are using. */ + int v_color; /* What color we are using. */ + char *v_defcolor; /* The name of a color to use. */ + int v_numdims; /* How many dims -- 0 = scalar (len = 1). */ + int v_dims[MAXDIMS]; /* The actual size in each dimension. */ + struct plot *v_plot; /* The plot structure (if it has one). */ + struct dvec *v_next; /* Link for list of plot vectors. */ + struct dvec *v_link2; /* Extra link for things like print. */ + struct dvec *v_scale; /* If this has a non-standard scale... */ +} ; + +#define isreal(v) ((v)->v_flags & VF_REAL) +#define iscomplex(v) ((v)->v_flags & VF_COMPLEX) + +/* list of data vectors being displayed */ +struct dveclist { + struct dvec *vector; + struct dveclist *next; +}; + +#endif diff --git a/src/include/enh.h b/src/include/enh.h new file mode 100755 index 000000000..18108d4be --- /dev/null +++ b/src/include/enh.h @@ -0,0 +1,109 @@ +#ifndef ENH_HEADER +#define ENH_HEADER x + +/* =========================================================================== +FILE ENH.h + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains typedefs used by the event-driven algorithm. + +INTERFACES + + None. + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + + +#include "miftypes.h" +#include "fteinp.h" + +/* +The following data is used in implementing various enhancements made to the +simulator. The main struct is dynamically allocated in ckt so that incremental additions +can be made more easily without the need to recompile multiple modules. +Allocation and initialization is done in CKTinit.c which should be the only +module needed to recompile after additions are made here. +*/ + + +typedef enum { + ENH_ANALOG_NODE, /* An analog node */ + ENH_EVENT_NODE, /* An event-driven node */ + ENH_ANALOG_BRANCH, /* A branch current */ + ENH_ANALOG_INSTANCE, /* An analog instance */ + ENH_EVENT_INSTANCE, /* An event-driven instance */ + ENH_HYBRID_INSTANCE, /* A hybrid (analog/event-driven) instance */ +} Enh_Conv_Source_t; + + +typedef struct { + double current; /* The current dynamic breakpoint time */ + double last; /* The last used dynamic breakpoint time */ +} Enh_Bkpt_t; + +typedef struct { + double ramptime; /* supply ramping time specified on .options */ +} Enh_Ramp_t; + +typedef struct { + Mif_Boolean_t last_NIiter_call; /* True if this is the last call to NIiter() */ + Mif_Boolean_t report_conv_probs; /* True if conv test functions should send debug info */ +} Enh_Conv_Debug_t; + + +typedef struct { + Mif_Boolean_t enabled; /* True if convergence limiting enabled on code models */ + double abs_step; /* Minimum limiting step size */ + double step; /* Fractional step amount */ +} Enh_Conv_Limit_t; + + +typedef struct { + Mif_Boolean_t enabled; /* True if rshunt option used */ + double gshunt; /* 1.0 / rshunt */ + int num_nodes; /* Number of nodes in matrix */ + double **diag; /* Pointers to matrix diagonals */ +} Enh_Rshunt_t; + + +typedef struct { + Enh_Bkpt_t breakpoint; /* Data used by dynamic breakpoints */ + Enh_Ramp_t ramp; /* New options added to simulator */ + Enh_Conv_Debug_t conv_debug; /* Convergence debug info dumping data */ + Enh_Conv_Limit_t conv_limit; /* Convergence limiting info */ + Enh_Rshunt_t rshunt_data; /* Shunt conductance from nodes to ground */ +} Enh_Ckt_Data_t; + + + +void ENHreport_conv_prob(Enh_Conv_Source_t type, char *name, char *msg); +struct line *ENHtranslate_poly(struct line *deck); + + +#endif /* ENH_HEADER */ diff --git a/src/include/evt.h b/src/include/evt.h new file mode 100755 index 000000000..1a5da1008 --- /dev/null +++ b/src/include/evt.h @@ -0,0 +1,371 @@ +#ifndef EVT_HEADER +#define EVT_HEADER x + +/* =========================================================================== +FILE EVT.h + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the definition of the evt data structure and all + its substructures. The single evt structure is housed inside of + the main 3C1 circuit structure 'ckt' and contains virtually all + information about the event-driven simulation. + +INTERFACES + + None. + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + + +#include "mifdefs.h" +#include "mifcmdat.h" +#include "miftypes.h" + + + +/* ************** */ +/* Info structure */ +/* ************** */ + + +typedef struct Evt_Output_Info_s { + struct Evt_Output_Info_s *next; /* the next in the linked list */ + int node_index; /* index into node info struct for this output */ + int output_subindex; /* index into output data in node data struct */ + int inst_index; /* Index of instance the port is on */ + int port_index; /* Index of port the output corresponds to */ +} Evt_Output_Info_t; + +typedef struct Evt_Port_Info_s { + struct Evt_Port_Info_s *next; /* the next in the linked list of node info */ + int inst_index; /* Index of instance the port is on */ + int node_index; /* index of node the port is connected to */ + char *node_name; /* name of node port is connected to */ + char *inst_name; /* instance name */ + char *conn_name; /* connection name on instance */ + int port_num; /* port number of instance connector */ +} Evt_Port_Info_t; + +typedef struct Evt_Inst_Index_s { + struct Evt_Inst_Index_s *next; /* the next in the linked list */ + int index; /* the value of the index */ +} Evt_Inst_Index_t; + +typedef struct Evt_Node_Info_s { + struct Evt_Node_Info_s *next; /* the next in the linked list */ + char *name; /* Name of node in deck */ + int udn_index; /* Index of the node type */ + Mif_Boolean_t invert; /* True if need to make inverted copy */ + int num_ports; /* Number of ports connected to this node */ + int num_outputs; /* Number of outputs connected to this node */ + int num_insts; /* The number of insts receiving node as input */ + Evt_Inst_Index_t *inst_list; /* Linked list of indexes of these instances */ +} Evt_Node_Info_t; + +typedef struct Evt_Inst_Info_s { + struct Evt_Inst_Info_s *next; /* the next in the linked list of node info */ + MIFinstance *inst_ptr; /* Pointer to MIFinstance struct for this instance */ +} Evt_Inst_Info_t; + +typedef struct { + Evt_Inst_Info_t *inst_list; /* static info about event/hybrid instances */ + Evt_Node_Info_t *node_list; /* static info about event nodes */ + Evt_Port_Info_t *port_list; /* static info about event ports */ + Evt_Output_Info_t *output_list; /* static info about event outputs */ + int *hybrid_index; /* vector of inst indexs for hybrids */ + Evt_Inst_Info_t **inst_table; /* vector of pointers to elements in inst_list */ + Evt_Node_Info_t **node_table; /* vector of pointers to elements in node_list */ + Evt_Port_Info_t **port_table; /* vector of pointers to elements in port_list */ + Evt_Output_Info_t **output_table; /* vector of pointers to elements in output_list */ +} Evt_Info_t; + + + + + + + + +/* *************** */ +/* Queue structure */ +/* *************** */ + + + +typedef struct Evt_Inst_Event_s { + struct Evt_Inst_Event_s *next; /* the next in the linked list */ + double event_time; /* Time for this event to happen */ + double posted_time; /* Time at which event was entered in queue */ +} Evt_Inst_Event_t; + +typedef struct { + Evt_Inst_Event_t **head; /* Beginning of linked lists */ + Evt_Inst_Event_t ***current; /* Beginning of pending events */ + Evt_Inst_Event_t ***last_step; /* Values of 'current' at last accepted timepoint */ + Evt_Inst_Event_t **free; /* Linked lists of items freed by backups */ + double last_time; /* Time at which last_step was set */ + double next_time; /* Earliest next event time in queue */ + int num_modified; /* Number modified since last accepted timepoint */ + int *modified_index; /* Indexes of modified instances */ + Mif_Boolean_t *modified; /* Flags used to prevent multiple entries */ + int num_pending; /* Count of number of pending events in lists */ + int *pending_index; /* Indexes of pending events */ + Mif_Boolean_t *pending; /* Flags used to prevent multiple entries */ + int num_to_call; /* Count of number of instances that need to be called */ + int *to_call_index; /* Indexes of instances to be called */ + Mif_Boolean_t *to_call; /* Flags used to prevent multiple entries */ +} Evt_Inst_Queue_t; + + + + +typedef struct { + int num_to_eval; /* Count of number of nodes that need to be evaluated */ + int *to_eval_index; /* Indexes of nodes to be evaluated */ + Mif_Boolean_t *to_eval; /* Flags used to prevent multiple entries */ + int num_changed; /* Count of number of nodes that changed */ + int *changed_index; /* Indexes of nodes that changed */ + Mif_Boolean_t *changed; /* Flags used to prevent multiple entries */ +} Evt_Node_Queue_t; + + + + +typedef struct Evt_Output_Event_s { + struct Evt_Output_Event_s *next; /* the next in the linked list */ + double event_time; /* Time for this event to happen */ + double posted_time; /* Time at which event was entered in queue */ + Mif_Boolean_t removed; /* True if event has been deactivated */ + double removed_time; /* Time at which event was deactivated */ + void *value; /* The delayed value sent to this output */ +} Evt_Output_Event_t; + +typedef struct { + Evt_Output_Event_t **head; /* Beginning of linked lists */ + Evt_Output_Event_t ***current; /* Beginning of pending events */ + Evt_Output_Event_t ***last_step; /* Values of 'current' at last accepted timepoint */ + Evt_Output_Event_t **free; /* Linked lists of items freed by backups */ + double last_time; /* Time at which last_step was set */ + double next_time; /* Earliest next event time in queue */ + int num_modified; /* Number modified since last accepted timepoint */ + int *modified_index; /* Indexes of modified outputs */ + Mif_Boolean_t *modified; /* Flags used to prevent multiple entries */ + int num_pending; /* Count of number of pending events in lists */ + int *pending_index; /* Indexes of pending events */ + Mif_Boolean_t *pending; /* Flags used to prevent multiple entries */ + int num_changed; /* Count of number of outputs that changed */ + int *changed_index; /* Indexes of outputs that changed */ + Mif_Boolean_t *changed; /* Flags used to prevent multiple entries */ +} Evt_Output_Queue_t; + + + + +typedef struct { + Evt_Inst_Queue_t inst; /* dynamic queue for instances */ + Evt_Node_Queue_t node; /* dynamic queue of changing nodes */ + Evt_Output_Queue_t output; /* dynamic queue of delayed outputs */ +} Evt_Queue_t; + + + + +/* ************** */ +/* Data structure */ +/* ************** */ + + + + +typedef struct Evt_Node_s { + struct Evt_Node_s *next; /* pointer to next in linked list */ + Mif_Boolean_t op; /* true if computed from op analysis */ + double step; /* DC step or time at which data was computed */ + void **output_value; /* Array of outputs posted to this node */ + void *node_value; /* Resultant computed from output values */ + void *inverted_value; /* Inverted copy of node_value */ +} Evt_Node_t; + +typedef struct { + Evt_Node_t **head; /* Beginning of linked lists */ + Evt_Node_t ***tail; /* Location of last item added to list */ + Evt_Node_t ***last_step; /* 'tail' at last accepted timepoint */ + Evt_Node_t **free; /* Linked lists of items freed by backups */ + int num_modified; /* Number modified since last accepted timepoint */ + int *modified_index; /* Indexes of modified nodes */ + Mif_Boolean_t *modified; /* Flags used to prevent multiple entries */ + Evt_Node_t *rhs; /* Location where model outputs are placed */ + Evt_Node_t *rhsold; /* Location where model inputs are retrieved */ + double *total_load; /* Location where total load inputs are retrieved */ +} Evt_Node_Data_t; + + + + +typedef struct Evt_State_s { + struct Evt_State_s *next; /* Pointer to next state */ + struct Evt_State_s *prev; /* Pointer to previous state */ + double step; /* Time at which state was assigned (0 for DC) */ + void *block; /* Block of memory holding all states on inst */ +} Evt_State_t; + + +typedef struct Evt_State_Desc_s { + struct Evt_State_Desc_s *next; /* Pointer to next description */ + int tag; /* Tag for this state */ + int size; /* Size of this state */ + int offset; /* Offset of this state into the state block */ +} Evt_State_Desc_t; + + +typedef struct { + Evt_State_t **head; /* Beginning of linked lists */ + Evt_State_t ***tail; /* Location of last item added to list */ + Evt_State_t ***last_step; /* 'tail' at last accepted timepoint */ + Evt_State_t **free; /* Linked lists of items freed by backups */ + int num_modified; /* Number modified since last accepted timepoint */ + int *modified_index; /* List of indexes modified */ + Mif_Boolean_t *modified; /* Flags used to prevent multiple entries */ + int *total_size; /* Total bytes for all states allocated */ + Evt_State_Desc_t **desc; /* Lists of description structures */ +} Evt_State_Data_t; + + + + +typedef struct Evt_Msg_s { + struct Evt_Msg_s *next; /* Pointer to next state */ + Mif_Boolean_t op; /* true if output from op analysis */ + double step; /* DC step or time at which message was output */ + char *text; /* The value of the message text */ + int port_index; /* The index of the port from which the message came */ +} Evt_Msg_t; + + +typedef struct { + Evt_Msg_t **head; /* Beginning of linked lists */ + Evt_Msg_t ***tail; /* Location of last item added to list */ + Evt_Msg_t ***last_step; /* 'tail' at last accepted timepoint */ + Evt_Msg_t **free; /* Linked lists of items freed by backups */ + int num_modified; /* Number modified since last accepted timepoint */ + int *modified_index; /* List of indexes modified */ + Mif_Boolean_t *modified; /* Flags used to prevent multiple entries */ +} Evt_Msg_Data_t; + + +typedef struct { + int op_alternations; /* Total alternations between event and analog */ + int op_load_calls; /* Total load calls in DCOP analysis */ + int op_event_passes; /* Total passes through event iteration loop */ + int tran_load_calls; /* Total inst calls in transient analysis */ + int tran_time_backups; /* Number of transient timestep cuts */ +} Evt_Statistic_t; + + + + +typedef struct { + Evt_Node_Data_t *node; /* dynamic event solution vector */ + Evt_State_Data_t *state; /* dynamic event instance state data */ + Evt_Msg_Data_t *msg; /* dynamic event message data */ + Evt_Statistic_t *statistics; /* Statistics for events, etc. */ +} Evt_Data_t; + + + +/* **************** */ +/* Counts structure */ +/* **************** */ + + +typedef struct { + int num_insts; /* number of event/hybrid instances parsed */ + int num_hybrids; /* number of hybrids parsed */ + int num_hybrid_outputs; /* number of outputs on all hybrids parsed */ + int num_nodes; /* number of event nodes parsed */ + int num_ports; /* number of event ports parsed */ + int num_outputs; /* number of event outputs parsed */ +} Evt_Count_t; + + + +/* **************** */ +/* Limits structure */ +/* **************** */ + + +typedef struct { + int max_event_passes; /* maximum loops in attempting convergence of event nodes */ + int max_op_alternations; /* maximum loops through event/analog alternation */ +} Evt_Limit_t; + + +/* ************** */ +/* Jobs structure */ +/* ************** */ + + +typedef struct { + int num_jobs; /* Number of jobs run */ + char **job_name; /* Names of different jobs */ + Evt_Node_Data_t **node_data; /* node_data for different jobs */ + Evt_State_Data_t **state_data; /* state_data for different jobs */ + Evt_Msg_Data_t **msg_data; /* messages for different jobs */ + Evt_Statistic_t **statistics; /* Statistics for different jobs */ +} Evt_Job_t; + + + +/* ***************** */ +/* Options structure */ +/* ***************** */ + + +typedef struct { + Mif_Boolean_t op_alternate; /* Alternate analog/event solutions in OP analysis */ +} Evt_Option_t; + + +/* ****************** */ +/* Main evt structure */ +/* ****************** */ + +typedef struct { + Evt_Count_t counts; /* Number of insts, nodes, etc. */ + Evt_Info_t info; /* Static info about insts, etc. */ + Evt_Queue_t queue; /* Dynamic queued events */ + Evt_Data_t data; /* Results and state data */ + Evt_Limit_t limits; /* Iteration limits, etc. */ + Evt_Job_t jobs; /* Data held from multiple job runs */ + Evt_Option_t options; /* Data input on .options cards */ +} Evt_Ckt_Data_t; + + + +#endif /* EVT_HEADER */ diff --git a/src/include/evtproto.h b/src/include/evtproto.h new file mode 100755 index 000000000..104814472 --- /dev/null +++ b/src/include/evtproto.h @@ -0,0 +1,124 @@ +#ifndef EVTPROTO_HEADER +#define EVTPROTO_HEADER x + +/* =========================================================================== +FILE EVTproto.h + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains ANSI C function prototypes for functions + in the event-driven simulation algorithm package. + +INTERFACES + + None. + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + +#include "cktdefs.h" +#include "cpstd.h" +#include "mifdefs.h" +#include "ipc.h" + + +/* ******************* */ +/* Function Prototypes */ +/* ******************* */ + + +int EVTinit(CKTcircuit *ckt); +/*int EVTinit2(CKTcircuit *ckt);*/ + +void EVTtermInsert( + CKTcircuit *ckt, + MIFinstance *fast, + char *node_name, + char *type_name, + int conn_num, + int port_num, + char **err_msg); + +int EVTsetup(CKTcircuit *ckt); + +int EVTiter(CKTcircuit *ckt); + +void EVTbackup(CKTcircuit *ckt, double new_time); + +double EVTnext_time(CKTcircuit *ckt); + +void EVTqueue_output( + CKTcircuit *ckt, + int output_index, + int udn_index, + Evt_Output_Event_t *new_event, + double posted_time, + double event_time); + + +void EVTqueue_inst( + CKTcircuit *ckt, + int inst_index, + double posted_time, + double event_time); + +void EVTdequeue(CKTcircuit *ckt, double time); + +int EVTload(CKTcircuit *ckt, int inst_index); + +void EVTprint(wordlist *wl); + +int EVTop( + CKTcircuit *ckt, + long firstmode, + long continuemode, + int max_iter, + Mif_Boolean_t first_call); + +void EVTop_save( + CKTcircuit *ckt, + Mif_Boolean_t op, + double step); + +void EVTnode_copy( + CKTcircuit *ckt, + int node_index, + Evt_Node_t *from, + Evt_Node_t **to); + +void EVTcall_hybrids(CKTcircuit *ckt); + +void EVTdump( + CKTcircuit *ckt, + Ipc_Anal_t mode, + double step); + +void EVTaccept( + CKTcircuit *ckt, /* main circuit struct */ + double time); /* time at which analog soln was accepted */ + +#endif /* EVTPROTO_HEADER */ diff --git a/src/include/evtudn.h b/src/include/evtudn.h new file mode 100755 index 000000000..20f9b7d94 --- /dev/null +++ b/src/include/evtudn.h @@ -0,0 +1,123 @@ +#ifndef EVTUDN_HEADER +#define EVTUDN_HEADER x + +/* =========================================================================== +FILE EVTudn.h + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the definition of "User-Defined Nodes". + These nodes are integrated into the simulator similar to the + way models are tied into SPICE 3C1, so that new node types + can be relatively easily added. The functions (required and + optional) are listed below. For optional functions, the + function can be left undefined and the pointer placed into the + Evt_Udn_Info_t structure can be specified as NULL. + + Required functions: + create - allocate data structure used as inputs and outputs to code models + initialize - set structure to appropriate initial value for first use as model input + copy - make a copy of the contents into created but possibly uninitialized structure + compare - determine if two structures are equal in value + + Optional functions: + dismantle - free allocations _inside_ structure (but not structure itself) + invert - invert logical value of structure + resolve - determine the resultant when multiple outputs are connected to a node + plot_val - output a real value for specified structure component for plotting purposes + print_val - output a string value for specified structure component for printing + ipc_val - output a binary data structure and size of the structure for IPC + +INTERFACES + + None. + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + + +#include "miftypes.h" /* for Mif_Boolean_t used in udn_..._compare */ + +#define MALLOCED_PTR (*evt_struct_ptr) +#define STRUCT_PTR evt_struct_ptr +#define STRUCT_PTR_1 evt_struct_ptr_1 +#define STRUCT_PTR_2 evt_struct_ptr_2 +#define EQUAL (*evt_equal) +#define INPUT_STRUCT_PTR evt_input_struct_ptr +#define OUTPUT_STRUCT_PTR evt_output_struct_ptr +#define INPUT_STRUCT_PTR_ARRAY evt_input_struct_ptr_array +#define INPUT_STRUCT_PTR_ARRAY_SIZE evt_input_struct_ptr_array_size +#define STRUCT_MEMBER_ID evt_struct_member_id +#define PLOT_VAL (*evt_plot_val) +#define PRINT_VAL (*evt_print_val) +#define IPC_VAL (*evt_ipc_val) +#define IPC_VAL_SIZE (*evt_ipc_val_size) + +#define CREATE_ARGS void **evt_struct_ptr +#define INITIALIZE_ARGS void *evt_struct_ptr +#define COMPARE_ARGS void *evt_struct_ptr_1, \ + void *evt_struct_ptr_2, \ + Mif_Boolean_t *evt_equal +#define COPY_ARGS void *evt_input_struct_ptr, \ + void *evt_output_struct_ptr +#define DISMANTLE_ARGS void *evt_struct_ptr +#define INVERT_ARGS void *evt_struct_ptr +#define RESOLVE_ARGS int evt_input_struct_ptr_array_size, \ + void **evt_input_struct_ptr_array, \ + void *evt_output_struct_ptr +#define PLOT_VAL_ARGS void *evt_struct_ptr, \ + char *evt_struct_member_id, \ + double *evt_plot_val +#define PRINT_VAL_ARGS void *evt_struct_ptr, \ + char *evt_struct_member_id, \ + char **evt_print_val +#define IPC_VAL_ARGS void *evt_struct_ptr, \ + void **evt_ipc_val, \ + int *evt_ipc_val_size + + +typedef struct { + char *name; + char *description; + void ((*create)(CREATE_ARGS)); + void ((*dismantle)(DISMANTLE_ARGS)); + void ((*initialize)(INITIALIZE_ARGS)); + void ((*invert)(INVERT_ARGS)); + void ((*copy)(COPY_ARGS)); + void ((*resolve)(RESOLVE_ARGS)); + void ((*compare)(COMPARE_ARGS)); + void ((*plot_val)(PLOT_VAL_ARGS)); + void ((*print_val)(PRINT_VAL_ARGS)); + void ((*ipc_val)(IPC_VAL_ARGS)); +} Evt_Udn_Info_t; + + +extern int g_evt_num_udn_types; +extern Evt_Udn_Info_t **g_evt_udn_info; + + +#endif /* EVTUDN_HEADER */ 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/graph.h b/src/include/graph.h new file mode 100644 index 000000000..6b4ad4bfa --- /dev/null +++ b/src/include/graph.h @@ -0,0 +1,138 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Jeffrey M. Hsu +**********/ + +/* + This file contains the graph structure. +*/ + +#ifndef _GRAPH_H +#define _GRAPH_H + +#include "grid.h" +#include "plot.h" +#include "dvec.h" /* for struct dvec */ + +/* Device-independent data structure for plots. */ + +#define NUMCOLORS 20 + +typedef struct graph { + int graphid; + struct dveclist *plotdata; /* normalized data */ + char *plotname; /* name of plot this graph is in */ + int onevalue; /* boolean variable, + true if plotting one value + against itself (real vs imaginary) */ + int degree; /* degree of polynomial interpretation */ + + int currentcolor; + int linestyle; + + struct { + int height, width; + } viewport; + int viewportxoff; /* x offset of viewport w/in graph */ + int viewportyoff; /* y offset of viewport w/in graph */ + + struct { + int xpos; /* x position of graph in screen coord */ + int ypos; /* y position of graph in screen coord */ + int width; /* width of window on screen */ + int height; /* height of window on screen */ + } absolute; + + struct { + double xmin, ymin, xmax, ymax; + } data; + + struct { + double xmin, ymin, xmax, ymax; + /* cache: width = xmax - xmin height = ymax - ymin */ + double width, height; + } datawindow; + + /* note: this int is device dependent */ + int colors[NUMCOLORS]; + + /* cache (datawindow size) / (viewport size) */ + double aspectratiox, aspectratioy; + + int ticmarks; /* mark every ticmark'th point */ + double *ticdata; + int fontwidth, fontheight; /* for use in grid */ + + PLOTTYPE plottype; /* defined in FTEconstant.h */ + struct { + GRIDTYPE gridtype; /* defined in FTEconstant.h */ + int circular; /* TRUE if circular plot area */ + union { + struct { + char units[16]; /* unit labels */ + int spacing, numspace; + double distance, lowlimit, highlimit; + int mult; + int onedec; /* a boolean */ + int hacked; /* true if hi - lo already hacked up */ + double tenpowmag; + double tenpowmagx; + int digits; + } lin; + struct { + char units[16]; /* unit labels */ + int hmt, lmt, decsp, subs, pp; + } log; + struct { + char units[16]; /* unit labels */ + int radius, center; + double mrad; + int lmt; + int hmt, mag; /* added, p.w.h. */ + } circular; /* bogus, rework when write polar grids, etc */ + } xaxis, yaxis; + int xdatatype, ydatatype; + int xsized, ysized; + double xdelta, ydelta; /* if non-zero, user-specified deltas */ + char *xlabel, *ylabel; + } grid; + + int numbuttons; /* number of buttons */ + struct { + int id; + char *message; + } *buttons; + int buttonsxoff; /* viewportxoff + x size of viewport */ + int buttonsyoff; + + struct { + int width, height; + char message[161]; /* two lines of text */ + } messagebox; + int messagexoff; + int messageyoff; + + /* characters the user typed on graph */ +/* note: think up better names */ + struct _keyed { + char *text; + int x, y; + int colorindex; /* index into colors array */ + struct _keyed *next; + } *keyed; + + /* for zoomin */ + char *commandline; + + /* Space here is allocated by NewViewport + and de-allocated by DestroyGraph. + */ + char *devdep; + +} GRAPH; + +#define NEWGRAPH (GRAPH *) tmalloc(sizeof(GRAPH)) + +#define rnd(x) (int) ((x)+0.5) + +#endif diff --git a/src/include/grid.h b/src/include/grid.h new file mode 100644 index 000000000..3de2b3a6d --- /dev/null +++ b/src/include/grid.h @@ -0,0 +1,12 @@ +#ifndef _GRID_H +#define _GRID_H + +/* Grid types. + + Note: SMITHGRID is only a smith grid, SMITH transforms the data */ +typedef enum { + GRID_NONE, GRID_LIN, GRID_LOGLOG, GRID_XLOG, + GRID_YLOG, GRID_POLAR, GRID_SMITH, GRID_SMITHGRID +} GRIDTYPE; + +#endif 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/ipc.h b/src/include/ipc.h new file mode 100755 index 000000000..a75c5d078 --- /dev/null +++ b/src/include/ipc.h @@ -0,0 +1,122 @@ +/* $Id$ + * + */ +/*============================================================================ +FILE IPC.h + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Steve Tynor + +MODIFICATIONS + + + +SUMMARY + + Provides compatibility for the new SPICE simulator to both the MSPICE user + interface and BCP (via ATESSE v.1 style AEGIS mailboxes) and the new ATESSE + v.2 Simulator Interface and BCP (via Bsd Sockets). + +INTERFACES + + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +#ifndef IPC_DEFINED +#define IPC_DEFINED + + +#define IPC_MAX_LINE_LEN 80 +#define IPC_MAX_PATH_LEN 2048 + +/* Known socket port for server and client to communicate: */ +#define SOCKET_PORT 1064 + +/* Recognition character for Beginning Of Line of message: */ +#define BOL_CHAR '\\' + +/* Length (in bytes) of a socket message header: */ +#define SOCK_MSG_HDR_LEN 5 + + +typedef int Ipc_Boolean_t; + +#define IPC_FALSE 0 +#define IPC_TRUE 1 + +typedef struct { /* Don't change this type! It is cast elsewhere */ + double real; + double imag; +} Ipc_Complex_t; + +/*---------------------------------------------------------------------------*/ +typedef enum { + IPC_STATUS_OK, + IPC_STATUS_NO_DATA, + IPC_STATUS_END_OF_DECK, + IPC_STATUS_EOF, + IPC_STATUS_ERROR, +} Ipc_Status_t; + +#if 0 +/*---------------------------------------------------------------------------*/ +typedef void* Ipc_Connection_t; +/* + * A connection is an `opaque' type - the user has no access to the details of + * the implementation. Indeed the details are different depending on whether + * underlying transport mechanism is AEGIS Mailboxes or Bsd Sockets (or + * something else...) + */ +#endif + +/*---------------------------------------------------------------------------*/ +typedef enum { + IPC_WAIT, + IPC_NO_WAIT, +} Ipc_Wait_t; + +/*---------------------------------------------------------------------------*/ +typedef enum { + IPC_PROTOCOL_V1, /* >DATAB records in ATESSE v.1 format + * Handles v.1 style logfile name passing protocol + */ + IPC_PROTOCOL_V2, /* >DATAB records in ATESSE v.2 format + */ +} Ipc_Protocol_t; + +/*---------------------------------------------------------------------------*/ +typedef enum { + IPC_MODE_BATCH, + IPC_MODE_INTERACTIVE, +} Ipc_Mode_t; + + +/*---------------------------------------------------------------------------*/ +typedef enum { + IPC_ANAL_DCOP, + IPC_ANAL_DCTRCURVE, + IPC_ANAL_AC, + IPC_ANAL_TRAN, +} Ipc_Anal_t; + + + +#endif /* IPC_DEFINED */ diff --git a/src/include/ipcproto.h b/src/include/ipcproto.h new file mode 100755 index 000000000..b211baf6b --- /dev/null +++ b/src/include/ipcproto.h @@ -0,0 +1,52 @@ + +/* IPC.c */ +Ipc_Boolean_t kw_match (char *keyword , char *str ); +Ipc_Status_t ipc_initialize_server (char *server_name , Ipc_Mode_t m , Ipc_Protocol_t p ); +Ipc_Status_t ipc_terminate_server (void ); +Ipc_Status_t ipc_get_line (char *str , int *len , Ipc_Wait_t wait ); +Ipc_Status_t ipc_flush (void ); +Ipc_Status_t ipc_send_line_binary (char *str , int len ); +Ipc_Status_t ipc_send_line (char *str ); +Ipc_Status_t ipc_send_data_prefix (double time ); +Ipc_Status_t ipc_send_dcop_prefix (void ); +Ipc_Status_t ipc_send_data_suffix (void ); +Ipc_Status_t ipc_send_dcop_suffix (void ); +Ipc_Status_t ipc_send_errchk (void ); +Ipc_Status_t ipc_send_end (void ); +int stuff_binary_v1 (double d1 , double d2 , int n , char *buf , int pos ); +Ipc_Status_t ipc_send_double (char *tag , double value ); +Ipc_Status_t ipc_send_complex (char *tag , Ipc_Complex_t value ); +Ipc_Status_t ipc_send_int (char *tag , int value ); +Ipc_Status_t ipc_send_boolean (char *tag , Ipc_Boolean_t value ); +Ipc_Status_t ipc_send_string (char *tag , char *value ); +Ipc_Status_t ipc_send_int_array (char *tag , int array_len , int *value ); +Ipc_Status_t ipc_send_double_array (char *tag , int array_len , double *value ); +Ipc_Status_t ipc_send_complex_array (char *tag , int array_len , Ipc_Complex_t *value ); +Ipc_Status_t ipc_send_boolean_array (char *tag , int array_len , Ipc_Boolean_t *value ); +Ipc_Status_t ipc_send_string_array (char *tag , int array_len , char **value ); +Ipc_Status_t ipc_send_evtdict_prefix (); +Ipc_Status_t ipc_send_evtdict_suffix (); +Ipc_Status_t ipc_send_evtdata_prefix (); +Ipc_Status_t ipc_send_evtdata_suffix (); +Ipc_Status_t ipc_send_event(int, double, double, char *, void *, int); + +/* IPCtiein.c */ +void ipc_handle_stop (void ); +void ipc_handle_returni (void ); +void ipc_handle_mintime (double time ); +void ipc_handle_vtrans (char *vsrc , char *dev ); +void ipc_send_stdout (void ); +void ipc_send_stderr (void ); +Ipc_Status_t ipc_send_std_files (void ); +Ipc_Boolean_t ipc_screen_name (char *name , char *mapped_name ); +int ipc_get_devices (void *circuit , char *device , char ***names , double **modtypes ); +void ipc_free_devices (int num_items , char **names , double *modtypes ); +void ipc_check_pause_stop (void ); + +/* IPCaegis.c */ +Ipc_Status_t ipc_transport_initialize_server (char *server_name , Ipc_Mode_t m , Ipc_Protocol_t p , char *batch_filename ); +Ipc_Status_t extract_msg (char *str , int *len ); +Ipc_Status_t ipc_transport_get_line (char *str , int *len , Ipc_Wait_t wait ); +Ipc_Status_t ipc_transport_terminate_server (void ); +Ipc_Status_t ipc_transport_send_line (char *str , int len ); + diff --git a/src/include/ipctiein.h b/src/include/ipctiein.h new file mode 100755 index 000000000..4a3670bf0 --- /dev/null +++ b/src/include/ipctiein.h @@ -0,0 +1,96 @@ +/*============================================================================ +FILE IPCtiein.h + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + Provides a protocol independent interface between the simulator + and the IPC method used to interface to CAE packages. + +INTERFACES + + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + + +#ifndef IPC_TIEIN_DEFINED +#define IPC_TIEIN_DEFINED + + +#include "ipc.h" +#include "ipcproto.h" + + +#define IPC_STDOUT_FILE_NAME "/usr/tmp/atesse_xspice.out" +#define IPC_STDERR_FILE_NAME "/usr/tmp/atesse_xspice.err" + + +/* +Ipc_Vtrans_t is used by functions that return results to translate +voltage source names to the names of the devices they monitor. +This table is built from #VTRANS cards in the incoming deck and +is provided for ATESSE 1.0 compatibility. +*/ + +typedef struct { + int size; /* Size of arrays */ + char **vsrc_name; /* Array of voltage source name prefixes */ + char **device_name; /* Array of device names the vsources map to */ +} Ipc_Vtrans_t; + + +/* +Ipc_Tiein_t is used by the SPICE mods that take care of interprocess communications +activities. +*/ + +typedef struct { + + Ipc_Boolean_t enabled; /* True if we are using IPC */ + Ipc_Mode_t mode; /* INTERACTIVE or BATCH mode */ + Ipc_Anal_t anal_type; /* DCOP, AC, ... mode */ + Ipc_Boolean_t syntax_error; /* True if error occurred during parsing */ + Ipc_Boolean_t run_error; /* True if error occurred during simulation */ + Ipc_Boolean_t errchk_sent; /* True if #ERRCHK has been sent */ + Ipc_Boolean_t returni; /* True if simulator should return currents */ + double mintime; /* Minimum time between timepoints returned */ + double last_time; /* Last timepoint returned */ + double cpu_time; /* CPU time used during simulation */ + Ipc_Boolean_t *send; /* Used by OUTinterface to determine what to send */ + char *log_file; /* Path to write log file */ + Ipc_Vtrans_t vtrans; /* Used by OUTinterface to translate v sources */ + Ipc_Boolean_t stop_analysis; /* True if analysis should be terminated */ + +} Ipc_Tiein_t; + + + +extern Ipc_Tiein_t g_ipc; + + +#endif /* IPC_TIEIN_DEFINED */ + 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/memory.h b/src/include/memory.h new file mode 100644 index 000000000..2453b1b36 --- /dev/null +++ b/src/include/memory.h @@ -0,0 +1,26 @@ +#ifndef _MEMORY_H +#define _MEMORY_H + +#ifndef HAVE_LIBGC +extern void *tmalloc(size_t num); +extern void *trealloc(void *str, size_t num); +extern void txfree(void *ptr); + +#define tfree(x) (txfree(x), x = 0) + +#else +#include + +#define tmalloc(m) GC_malloc(m) +#define trealloc(m,n) GC_realloc((m),(n)) +#define tfree(m) +#define txfree(m) +#endif + +#define alloc(TYPE) ((TYPE *) tmalloc(sizeof(TYPE))) +#define MALLOC(x) tmalloc((unsigned)(x)) +#define FREE(x) {if (x) {txfree((char *)(x));(x) = 0;}} +#define REALLOC(x,y) trealloc((char *)(x),(unsigned)(y)) +#define ZERO(PTR,TYPE) (bzero((PTR),sizeof(TYPE))) + +#endif diff --git a/src/include/mif.h b/src/include/mif.h new file mode 100755 index 000000000..106412299 --- /dev/null +++ b/src/include/mif.h @@ -0,0 +1,84 @@ +#ifndef MIF +#define MIF + +/* =========================================================================== +FILE MIF.h + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file structure definitions global data used with the MIF package. + The global data structure is used to circumvent the need to modify + argument lists in existing SPICE 3C1 functions. + +INTERFACES + + None. + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + +#include "miftypes.h" +#include "mifdefs.h" +#include "cktdefs.h" + + +typedef struct { + Mif_Boolean_t init; /* TRUE if first call to model */ + Mif_Boolean_t anal_init; /* TRUE if first call for this analysis type */ + Mif_Analysis_t anal_type; /* The type of analysis being performed */ + Mif_Call_Type_t call_type; /* Type of call to code model - analog or event-driven */ + double evt_step; /* The current DC step or time in event analysis */ +} Mif_Circuit_Info_t; + + +typedef struct { + double current; /* The current dynamic breakpoint time */ + double last; /* The last used dynamic breakpoint time */ +} Mif_Bkpt_Info_t; + + +typedef struct { + Mif_Boolean_t global; /* Set by .option to force all models to use auto */ + Mif_Boolean_t local; /* Set by individual model to request auto partials */ +} Mif_Auto_Partial_t; + + +typedef struct { + Mif_Circuit_Info_t circuit; /* Circuit data that will be needed by MIFload */ + MIFinstance *instance; /* Current instance struct */ + CKTcircuit *ckt; /* The ckt struct for the circuit */ + char *errmsg; /* An error msg from a cm_... function */ + Mif_Bkpt_Info_t breakpoint; /* Data used by dynamic breakpoints */ + Mif_Auto_Partial_t auto_partial; /* Flags to enable auto partial computations */ +} Mif_Info_t; + + + +extern Mif_Info_t g_mif_info; + + +#endif /* MIF */ diff --git a/src/include/mifcmdat.h b/src/include/mifcmdat.h new file mode 100755 index 000000000..ea877455d --- /dev/null +++ b/src/include/mifcmdat.h @@ -0,0 +1,373 @@ +#ifndef MIFCMDAT +#define MIFCMDAT + +/* =========================================================================== +FILE MIFcmdat.h + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the data structure definitions used by + code model and the associated MIF package. + + A special preprocessor (cmpp) is used on models written by a + user to turn items like INPUT() into the appropriate structure + reference. + +INTERFACES + + None. + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + + +#include "miftypes.h" + + +/* ************************************************************************** */ + + +/* + * Pointers into matrix for a voltage input, voltage output partial + */ + +typedef struct Mif_E_Ptr_s { + + double *branch_poscntl; /* Branch row, positive controlling column */ + double *branch_negcntl; /* Branch row, negative controlling column */ + +} Mif_E_Ptr_t; + + + +/* + * Pointers into matrix for a current input, current output partial + */ + +typedef struct Mif_F_Ptr_s { + + double *pos_ibranchcntl; /* Positive row, controlling branch column */ + double *neg_ibranchcntl; /* Negative row, controlling branch column */ + +} Mif_F_Ptr_t; + + + +/* + * Pointers into matrix for a voltage input, current output partial + */ + +typedef struct Mif_G_Ptr_s { + + double *pos_poscntl; /* Positive row, positive controlling column */ + double *pos_negcntl; /* Positive row, negative controlling column */ + double *neg_poscntl; /* Negative row, positive controlling column */ + double *neg_negcntl; /* Negative row, negative controlling column */ + +} Mif_G_Ptr_t; + + +/* + * Pointers into matrix for a current input, voltage output partial + */ + +typedef struct Mif_H_Ptr_s { + + double *branch_ibranchcntl; /* Branch row, controlling branch column */ + +} Mif_H_Ptr_t; + + + + +/* + * Matrix pointers associated with a particular port (of a particular type) + */ + + +typedef union Mif_Port_Ptr_u { + + Mif_E_Ptr_t e; /* Pointers for voltage input, voltage output */ + Mif_F_Ptr_t f; /* Pointers for current input, current output */ + Mif_G_Ptr_t g; /* Pointers for voltage input, current output */ + Mif_H_Ptr_t h; /* Pointers for current input, voltage output */ + +} Mif_Port_Ptr_t; + + + +/* + * Array of matrix data pointers for particular ports in a connection + */ + +typedef struct Mif_Conn_Ptr_s { + + Mif_Port_Ptr_t *port; /* Data for a particular port */ + +} Mif_Conn_Ptr_t; + + + +/* + * Row numbers and matrix entry pointers for loading the matrix and RHS with + * data appropriate for the particular output port and input ports. + */ + +typedef struct Mif_Smp_Ptr_s { + + /* Data at this level is for this connection. The Mif_Conn_Ptr_t */ + /* subtree is used only if this connection is an output. It supplies */ + /* the matrix pointers required for loading the partials from each */ + /* input. */ + + /* node connection equation numbers */ + int pos_node; /* Row associated with positive node */ + int neg_node; /* Row associated with negative node */ + + /* V source branch equation numbers */ + int branch; /* Row associated with V output branch */ + int ibranch; /* Row associated with I input branch */ + + /* matrix pointers for V source output */ + double *pos_branch; /* Positive node row, branch column */ + double *neg_branch; /* Negative node row, branch column */ + double *branch_pos; /* Branch row, positive node column */ + double *branch_neg; /* Branch row, negative node column */ + + /* matrix pointers for the zero-valued V source associated with an I input */ + double *pos_ibranch; /* Positive node row, branch column */ + double *neg_ibranch; /* Negative node row, branch column */ + double *ibranch_pos; /* Branch row, positive node column */ + double *ibranch_neg; /* Branch row, negative node column */ + + /* array of pointer info required for putting partials into the matrix */ + Mif_Conn_Ptr_t *input; /* Matrix pointers associated with inputs */ + +} Mif_Smp_Ptr_t; + + + + +/* ******************************************************************** */ + + + +/* + * Partial derivatives wrt ports of a particular input connection + */ + +typedef struct Mif_Partial_s { + + double *port; /* Partial wrt this port */ + +} Mif_Partial_t; + + +/* + * AC gains wrt ports of a particular input connection + */ + +typedef struct Mif_AC_Gain_s { + + Mif_Complex_t *port; /* AC gain wrt this port */ + +} Mif_AC_Gain_t; + + +/* + * Data used to access information in event struct in CKTcircuit struct ckt + */ + +typedef struct { + int node_index; /* Index of node in event-driven structures */ + int output_subindex; /* Subindex of output on node */ + int port_index; /* Index of port in event-driven structures */ + int output_index; /* Index of output in event-driven structures */ +} Mif_Evt_Data_t; + + +/* + * Information about individual port(s) of a connection. + */ + +typedef struct Mif_Port_Data_s { + + Mif_Port_Type_t type; /* Port type - e.g. MIF_VOLTAGE, ... */ + char *type_str; /* Port type in string form */ + char *pos_node_str; /* Positive node identifier */ + char *neg_node_str; /* Negative node identifier */ + char *vsource_str; /* Voltage source identifier */ + + Mif_Boolean_t is_null; /* Set to true if null in SPICE deck */ + Mif_Value_t input; /* The input value */ + Mif_Value_t output; /* The output value */ + Mif_Partial_t *partial; /* Partials for this port wrt inputs */ + Mif_AC_Gain_t *ac_gain; /* AC gains for this port wrt inputs */ + int old_input; /* Index into CKTstate for old input */ + + Mif_Boolean_t invert; /* True if state should be inverted */ + Mif_Boolean_t changed; /* A new output has been assigned */ + double load; /* Load factor output to this port */ + double total_load; /* Total load for this port */ + double delay; /* Digital delay for this output port */ + char *msg; /* Message string output to port */ + + Mif_Smp_Ptr_t smp_data; /* Pointers used to load matrix/rhs */ + Mif_Evt_Data_t evt_data; /* Data used to access evt struct */ + + double nominal_output; /* Saved output when doing auto partial */ + +} Mif_Port_Data_t; + + +/* ******************************************************************** */ + +/* + * Information in MIFinstance struct used by cm_.. support functions. + */ + + +typedef struct Mif_State_s { /* for cm_analog_alloc() */ + + int tag; /* Tag identifying this particular state */ + int index; /* Index into ckt->CKTstate[i] vector */ + int doubles; /* Number of doubles allocated for this state */ + int bytes; /* Actual number of bytes requested by cm_analog_alloc() */ + +} Mif_State_t; + + +typedef struct Mif_Intgr_s { /* for cm_analog_integrate() */ + + int byte_index; /* Byte offset into state array */ + +} Mif_Intgr_t; + + +typedef struct Mif_Conv_s { /* for cm_analog_converge() */ + + int byte_index; /* Byte offset into state array */ + double last_value; /* Value at last iteration */ + +} Mif_Conv_t; + + + +/* ******************************************************************** */ + + + +/* + * Information about the circuit in which this model is simulating. + */ + +typedef struct Mif_Circ_Data_s { + + Mif_Boolean_t init; /* True if first call to model - a setup pass */ + Mif_Analysis_t anal_type; /* Current analysis type */ + Mif_Boolean_t anal_init; /* True if first call in this analysis type */ + Mif_Call_Type_t call_type; /* Analog or event type call */ + double time; /* Current analysis time */ + double frequency; /* Current analysis frequency */ + double temperature; /* Current analysis temperature */ + double t[8]; /* History of last 8 analysis times t[0]=time */ + +} Mif_Circ_Data_t; + + + +/* + * The structure associated with a named "connection" on the model. + */ + +typedef struct Mif_Conn_Data_s { + + char *name; /* Name of this connection - currently unused */ + char *description; /* Description of this connection - unused */ + Mif_Boolean_t is_null; /* Set to true if null in SPICE deck */ + Mif_Boolean_t is_input; /* Set to true if connection is an input */ + Mif_Boolean_t is_output; /* Set to true if connection is an output */ + int size; /* The size of an array (1 if scalar) */ + Mif_Port_Data_t **port; /* Pointer(s) to port(s) for this connection */ + +} Mif_Conn_Data_t; + + + +/* + * Values for model parameters + */ + +typedef struct Mif_Param_Data_s { + + Mif_Boolean_t is_null; /* True if no value given on .model card */ + int size; /* Size of array (1 if scalar) */ + Mif_Value_t *element; /* Value of parameter(s) */ + +} Mif_Param_Data_t; + + + + +/* + * Values for instance variables + */ + +typedef struct Mif_Inst_Var_Data_s { + + int size; /* Size of array (1 if scalar) */ + Mif_Value_t *element; /* Value of instance variables(s) */ + +} Mif_Inst_Var_Data_t; + + + + +/* ************************************************************************* */ + + + +/* + * HERE IT IS!!! + * The top level data structure passed to code models. + */ + +typedef struct Mif_Private_s { + + Mif_Circ_Data_t circuit; /* Information about the circuit */ + int num_conn; /* Number of connections on this model */ + Mif_Conn_Data_t **conn; /* Information about each connection */ + int num_param; /* Number of parameters on this model */ + Mif_Param_Data_t **param; /* Information about each parameter */ + int num_inst_var; /* Number of instance variables */ + Mif_Inst_Var_Data_t **inst_var; /* Information about each inst variable */ + +} Mif_Private_t; + + + +#endif /* MIFCMDAT */ diff --git a/src/include/mifdefs.h b/src/include/mifdefs.h new file mode 100755 index 000000000..51daf991e --- /dev/null +++ b/src/include/mifdefs.h @@ -0,0 +1,111 @@ +#ifndef MIFDEFS +#define MIFDEFS + +/* =========================================================================== +FILE MIFdefs.h + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains (augmented) SPICE 3C1 compatible typedefs for use + with code models. These typedefs define the data structures that are + used internally to describe instances and models in the circuit + description linked lists. + +INTERFACES + + None. + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + + +#include "mifcmdat.h" +#include "ifsim.h" + + +/* The per-instance data structure */ + +typedef struct sMIFinstance { + + struct sMIFmodel *MIFmodPtr; /* backpointer to model */ + struct sMIFinstance *MIFnextInstance; /* pointer to next instance of current model */ + IFuid MIFname; /* pointer to character string naming this instance */ + + int num_conn; /* number of connections on the code model */ + Mif_Conn_Data_t **conn; /* array of data structures for each connection */ + + int num_inst_var; /* number of instance variables on the code model */ + Mif_Inst_Var_Data_t **inst_var; /* array of structs for each instance var */ + + int num_param; /* number of parameters on the code model */ + Mif_Param_Data_t **param; /* array of structs for each parameter */ + + int num_state; /* Number of state tags used for this inst */ + Mif_State_t *state; /* Info about states */ + + int num_intgr; /* Number of integrals */ + Mif_Intgr_t *intgr; /* Info for integrals */ + + int num_conv; /* Number of things to be converged */ + Mif_Conv_t *conv; /* Info for convergence things */ + + Mif_Boolean_t initialized; /* True if model called once already */ + + Mif_Boolean_t analog; /* true if this inst is analog or hybrid type */ + Mif_Boolean_t event_driven; /* true if this inst is event-driven or hybrid type */ + + int inst_index; /* Index into inst_table in evt struct in ckt */ + +} MIFinstance ; + + + +/* The per model data structure */ + +typedef struct sMIFmodel { + + int MIFmodType; /* type index of this device type */ + struct sMIFmodel *MIFnextModel; /* pointer to next possible model in linked list */ + MIFinstance *MIFinstances; /* pointer to list of instances that have this model */ + IFuid MIFmodName; /* pointer to character string naming this model */ + + int num_param; /* number of parameters on the code model */ + Mif_Param_Data_t **param; /* array of structs for each parameter */ + + Mif_Boolean_t analog; /* true if this model is analog or hybrid type */ + Mif_Boolean_t event_driven; /* true if this model is event-driven or hybrid type */ + +} MIFmodel; + + + +/* NOTE: There are no device parameter tags, since the ask, mAsk, ... */ +/* functions for code models work out of the generic code model structure */ + + + +#endif /* MIFDEFS */ diff --git a/src/include/mifparse.h b/src/include/mifparse.h new file mode 100755 index 000000000..fbfc19944 --- /dev/null +++ b/src/include/mifparse.h @@ -0,0 +1,120 @@ +#ifndef MIFPARSE +#define MIFPARSE + +/* =========================================================================== +FILE MIFparse.h + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the information structure definitions used by the + code model parser to check for valid connections and parameters. + + Structures of these types are created by the code model preprocessor + (cmpp) from the user created ifspec.ifs file. + +INTERFACES + + None. + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + + +#include "miftypes.h" + + +/* + * Information about a connection used by the parser to error check input + */ + + +typedef struct Mif_Conn_Info_s { + + char *name; /* Name of this connection */ + char *description; /* Description of this connection */ + Mif_Dir_t direction; /* Is this connection an input, output, or both? */ + Mif_Port_Type_t default_port_type; /* The default port type */ + char *default_type; /* The default type in string form */ + int num_allowed_types; /* The size of the allowed type arrays */ + Mif_Port_Type_t *allowed_type; /* The allowed types */ + char **allowed_type_str; /* The allowed types in string form */ + Mif_Boolean_t is_array; /* True if connection is an array */ + Mif_Boolean_t has_lower_bound; /* True if there is an array size lower bound */ + int lower_bound; /* Array size lower bound */ + Mif_Boolean_t has_upper_bound; /* True if there is an array size upper bound */ + int upper_bound; /* Array size upper bound */ + Mif_Boolean_t null_allowed; /* True if null is allowed for this connection */ + +} Mif_Conn_Info_t; + + + + +/* + * Information about a parameter used by the parser to error check input + */ + +typedef struct Mif_Param_Info_s { + + char *name; /* Name of this parameter */ + char *description; /* Description of this parameter */ + Mif_Data_Type_t type; /* Is this a real, boolean, string, ... */ + Mif_Boolean_t has_default; /* True if there is a default value */ + Mif_Parse_Value_t default_value; /* The default value */ + Mif_Boolean_t has_lower_limit; /* True if there is a lower limit */ + Mif_Parse_Value_t lower_limit; /* The lower limit for this parameter */ + Mif_Boolean_t has_upper_limit; /* True if there is a upper limit */ + Mif_Parse_Value_t upper_limit; /* The upper limit for this parameter */ + Mif_Boolean_t is_array; /* True if parameter is an array */ + Mif_Boolean_t has_conn_ref; /* True if parameter is associated with a connector */ + int conn_ref; /* The subscript of the associated connector */ + Mif_Boolean_t has_lower_bound; /* True if there is an array size lower bound */ + int lower_bound; /* Array size lower bound */ + Mif_Boolean_t has_upper_bound; /* True if there is an array size upper bound */ + int upper_bound; /* Array size upper bound */ + Mif_Boolean_t null_allowed; /* True if null is allowed for this parameter */ + +} Mif_Param_Info_t; + + + + +/* + * Information about an instance parameter used by the parser to error check input + */ + +typedef struct Mif_Inst_Var_Info_s { + + char *name; /* Name of this instance var */ + char *description; /* Description of this instance var */ + Mif_Data_Type_t type; /* Is this a real, boolean, string, ... */ + Mif_Boolean_t is_array; /* True if instance var is an array */ + +} Mif_Inst_Var_Info_t; + + +#endif /* MIFPARSE */ diff --git a/src/include/mifproto.h b/src/include/mifproto.h new file mode 100755 index 000000000..924cbed5f --- /dev/null +++ b/src/include/mifproto.h @@ -0,0 +1,157 @@ +#ifndef MIFPROTO +#define MIFPROTO + +/* =========================================================================== +FILE MIFproto.h + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains ANSI C function prototypes for functions in the + MIF package. + +INTERFACES + + None. + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + + + +#include "ifsim.h" +#include "inpdefs.h" +#include "smpdefs.h" +#include "cktdefs.h" +#include "miftypes.h" + + + +extern void MIF_INP2A( + void *ckt, /* circuit structure to put mod/inst structs in */ + INPtables *tab, /* symbol table for node names, etc. */ + card *current /* the card we are to parse */ +); + + +extern char * MIFgetMod( + void *ckt, + char *name, + INPmodel **model, + INPtables *tab +); + + +extern IFvalue * MIFgetValue( + void *ckt, + char **line, + int type, + INPtables *tab, + char **err +); + + +extern int MIFsetup( + SMPmatrix *matrix, + GENmodel *inModel, + CKTcircuit *ckt, + int *state +); + +extern int MIFload( + GENmodel *inModel, + CKTcircuit *ckt +); + + +extern int MIFmParam( + int param_index, + IFvalue *value, + GENmodel *inModel +); + +extern int MIFask( + CKTcircuit *ckt, + GENinstance *inst, + int param_index, + IFvalue *value, + IFvalue *select +); + +extern int MIFmAsk( + CKTcircuit *ckt, + GENmodel *inModel, + int param_index, + IFvalue *value +); + +extern int MIFtrunc( + GENmodel *inModel, + CKTcircuit *ckt, + double *timeStep +); + +extern int MIFconvTest( + GENmodel *inModel, + CKTcircuit *ckt +); + +extern int MIFdelete( + GENmodel *inModel, + IFuid name, + GENinstance **inst +); + +extern int MIFmDelete( + GENmodel **inModel, + IFuid modname, + GENmodel *model +); + +extern void MIFdestroy( + GENmodel **inModel +); + +extern char *MIFgettok( + char **s +); + + +extern char *MIFget_token( + char **s, + Mif_Token_Type_t *type +); + + +extern Mif_Cntl_Src_Type_t MIFget_cntl_src_type( + Mif_Port_Type_t in_port_type, + Mif_Port_Type_t out_port_type +); + +extern char *MIFcopy(char *); + + +#endif /* MIFPROTO */ diff --git a/src/include/miftypes.h b/src/include/miftypes.h new file mode 100755 index 000000000..95c5ab5a6 --- /dev/null +++ b/src/include/miftypes.h @@ -0,0 +1,226 @@ +#ifndef MIFTYPES +#define MIFTYPES + +/* =========================================================================== +FILE MIFtypes.h + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains typedefs shared by several header files in + the MIF package. + +INTERFACES + + None. + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + + + + +/* ***************************************************************************** */ + + +typedef int Mif_Boolean_t; + +#define MIF_FALSE 0 +#define MIF_TRUE 1 + + +typedef int Mif_Status_t; + +#define MIF_OK 0 +#define MIF_ERROR 1 + +/* +typedef enum { + MIF_OK, + MIF_ERROR, +} Mif_Status_t; +*/ + + +/* ***************************************************************************** */ + + +/* + * The type of call to a code model - analog or event-driven + */ + +typedef enum { + MIF_ANALOG, /* Analog call */ + MIF_EVENT_DRIVEN, /* Event-driven call */ +} Mif_Call_Type_t; + + + +/* + * Analysis type enumerations + */ + +typedef enum { + MIF_DC, /* A DC or DCOP analysis */ + MIF_AC, /* A swept AC analysis */ + MIF_TRAN, /* A transient analysis */ +} Mif_Analysis_t; + + + +/* + * Port type enumerations + */ + +typedef enum { + MIF_VOLTAGE, /* v - Single-ended voltage */ + MIF_DIFF_VOLTAGE, /* vd - Differential voltage */ + MIF_CURRENT, /* i - Single-ended current */ + MIF_DIFF_CURRENT, /* id - Differential current */ + MIF_VSOURCE_CURRENT, /* vnam - Voltage source current */ + MIF_CONDUCTANCE, /* g - Single-ended VCIS */ + MIF_DIFF_CONDUCTANCE, /* gd - Differential VCIS */ + MIF_RESISTANCE, /* h - Single-ended ICVS */ + MIF_DIFF_RESISTANCE, /* hd - Differential ICVS */ + MIF_DIGITAL, /* d - Digital */ + MIF_USER_DEFINED, /* - Any user defined type */ +} Mif_Port_Type_t; + + + +/* + * The direction of a connector + */ + +typedef enum { + MIF_IN, /* Input only */ + MIF_OUT, /* Output only */ + MIF_INOUT, /* Input and output (e.g. g or h type) */ +} Mif_Dir_t; + + + +/* + * The type of a parameter + */ + +typedef enum { + + MIF_BOOLEAN, + MIF_INTEGER, + MIF_REAL, + MIF_COMPLEX, + MIF_STRING, + +} Mif_Data_Type_t; + + + +/* + * The type of a token + */ + +typedef enum { + + MIF_LARRAY_TOK, + MIF_RARRAY_TOK, + MIF_LCOMPLEX_TOK, + MIF_RCOMPLEX_TOK, + MIF_PERCENT_TOK, + MIF_TILDE_TOK, + MIF_STRING_TOK, + MIF_NULL_TOK, + MIF_NO_TOK, + +} Mif_Token_Type_t; + + + +/* + * Type of controlled source + */ + +typedef enum { + MIF_VCVS, + MIF_VCIS, + MIF_ICVS, + MIF_ICIS, +} Mif_Cntl_Src_Type_t; + + +/* ***************************************************************************** */ + + +/* + * Complex numbers + */ + +typedef struct { + + double real; + double imag; + +} Mif_Complex_t; + + + +/* + * Values of different types used by the load, ... routines + */ + +typedef union { + + Mif_Boolean_t bvalue; /* For digital node value */ + int ivalue; /* For integer parameters */ + double rvalue; /* For spice node values and real parameters */ + Mif_Complex_t cvalue; /* For complex parameters */ + char *svalue; /* For string parameters */ + void *pvalue; /* For user defined nodes */ + +} Mif_Value_t; + + + + +/* + * Values of different types used by the parser. Note that this is a structure + * instead of a union because we need to do initializations in the ifspec.c files for + * the models and unions cannot be initialized in any useful way in C + * + */ + +typedef struct { + + Mif_Boolean_t bvalue; /* For boolean values */ + int ivalue; /* For integer values */ + double rvalue; /* For real values */ + Mif_Complex_t cvalue; /* For complex values */ + char *svalue; /* For string values */ + +} Mif_Parse_Value_t; + + +#endif /* MIFTYPES */ diff --git a/src/include/multi_line.h b/src/include/multi_line.h new file mode 100644 index 000000000..7edf9dbab --- /dev/null +++ b/src/include/multi_line.h @@ -0,0 +1,66 @@ +/* + * project.h + * + * Diagonalization by Successive Rotations Method + * (The Jacobi Method) + * + * Date: October 4, 1991 + * + * Author: Shen Lin + * + * Copyright (C) University of California, Berkeley + * + */ + +/************************************************************ + * + * Macros + * + ************************************************************/ + +#ifndef MAX +#define MAX(x, y) ((x) > (y) ? (x) : (y)) +#endif +#ifndef MIN +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#endif +#ifndef ABS +#define ABS(x) ((x) >= 0 ? (x) : (-(x))) +#endif +#ifndef SGN +#define SGN(x) ((x) >= 0 ? (1.0) : (-1.0)) +#endif + +/************************************************************ + * + * Defines + * + ************************************************************/ + +#define MAX_DIM 16 +#define Title "Diagonalization of a Symmetric matrix A (A = S^-1 D S)\n" +#define Left_deg 7 /* should be greater than or equal to 6 */ +#define Right_deg 2 + + +/************************************************************ + * + * Data Structure Definitions + * + ************************************************************/ + +typedef struct linked_list_of_max_entry{ + struct linked_list_of_max_entry *next; + int row, col; + float value; +} MAXE, *MAXE_PTR; + +typedef struct { + double *Poly[MAX_DIM]; + double C_0[MAX_DIM]; +} Mult_Out; + +typedef struct { + double *Poly; + double C_0; +} Single_Out; 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/plot.h b/src/include/plot.h new file mode 100644 index 000000000..b718fa14a --- /dev/null +++ b/src/include/plot.h @@ -0,0 +1,26 @@ +#ifndef _PLOT_H +#define _PLOT_H + +#include "wordlist.h" +#include "bool.h" +#include "dvec.h" + +/* The information for a particular set of vectors that come from one + * plot. */ +struct plot { + char *pl_title; /* The title card. */ + char *pl_date; /* Date. */ + char *pl_name; /* The plot name. */ + char *pl_typename; /* Tran1, op2, etc. */ + struct dvec *pl_dvecs; /* The data vectors in this plot. */ + struct dvec *pl_scale; /* The "scale" for the rest of the vectors. */ + struct plot *pl_next; /* List of plots. */ + wordlist *pl_commands; /* Commands to execute for this plot. */ + struct variable *pl_env; /* The 'environment' for this plot. */ + char *pl_ccom; /* The ccom struct for this plot. */ + bool pl_written; /* Some or all of the vecs have been saved. */ + int pl_ndims; /* Number of dimensions */ +} ; + + +#endif diff --git a/src/include/pnode.h b/src/include/pnode.h new file mode 100644 index 000000000..d965b588a --- /dev/null +++ b/src/include/pnode.h @@ -0,0 +1,14 @@ +#ifndef _PNODE_H +#define _PNODE_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. */ +} ; + +#endif 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/sim.h b/src/include/sim.h new file mode 100644 index 000000000..67c5f1400 --- /dev/null +++ b/src/include/sim.h @@ -0,0 +1,19 @@ +#ifndef _SIM_H +#define _SIM_H + +enum simulation_types { + SV_NOTYPE, + SV_TIME, + SV_FREQUENCY, + SV_VOLTAGE, + SV_CURRENT, + SV_OUTPUT_N_DENS, + SV_OUTPUT_NOISE, + SV_INPUT_N_DENS, + SV_INPUT_NOISE, + SV_POLE, + SV_ZERO, + SV_SPARAM +}; + +#endif 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/swec.h b/src/include/swec.h new file mode 100644 index 000000000..532741dfb --- /dev/null +++ b/src/include/swec.h @@ -0,0 +1,396 @@ +/* + * project.h + * + * Timing Simulator (ESWEC) + * + * Date: October 5, 1990 + * + * Author: Shen Lin + * + * Copyright (C) University of California, Berkeley + * + */ +#ifndef _SWEC_H_ +#define _SWEC_H_ + +/************************************************************ + * + * Defines + * + ************************************************************/ + +#define MainTitle " Timing Simulator\n" +#define MAXDEVICE 4 +#define MAXMOS 31500 /* suggested value */ +#define MAXDD 256 /* suggested value */ +#define MAXVCCS 128 /* suggested value */ +#define MAXTIME 1000000 +#define MAXNODE 136 + +#define TAB_SIZE 8192 /* originally 2048 */ +#define NUM_STEPS_PER_MICRON 10 /* 0.1 micron is the smallest step */ +#define MAX_FET_SIZE 80 /* largest fet in microns */ +#define Vol_Step 1.0e-3 /* voltage resolution */ +#define SCL 1000.0 /* voltage scaler (1V/3mv) */ +#define MAX_CP_TX_LINES 4 /* max number of coupled lines in + a multiconductor line system */ + +/************************************************************ + * + * Macro + * + ************************************************************/ +#ifndef MAX +#define MAX(x, y) ((x) > (y) ? (x) : (y)) +#endif +#ifndef MIN +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#endif +#ifndef ABS +#define ABS(x) ((x) >= 0 ? (x) : (-(x))) +#endif + +/************************************************************ + * + * Data Structure Definitions + * + ************************************************************/ + +typedef struct reglist REGLIST; +typedef struct node NODE; +typedef struct mosfet MOSFET; +typedef struct emosfet EMOSFET; +typedef struct diode DIODE; +typedef struct ediode EDIODE; +typedef struct vccs VCCS; +typedef struct evccs EVCCS; +typedef struct i_cap I_CAP; +typedef struct ei_cap EI_CAP; +typedef struct resistor RESISTOR; +typedef struct eresistor ERESISTOR; +typedef struct rline RLINE; +typedef struct erline ERLINE; +typedef struct txline TXLine; +typedef struct etxline ETXLine; +typedef struct cpline CPLine; +typedef struct ecpline ECPLine; +typedef struct bqueue BQUEUE; +typedef struct pqueue PQUEUE; +typedef struct ms_device MS_DEVICE; +typedef struct bp_device BP_DEVICE; +typedef struct dd_device DD_DEVICE; + +struct mosfet{ + int type; /* 1 : NMOS, 2 : PMOS */ + MS_DEVICE *device; /* NULL if the nominal device model */ + NODE *out_node; + NODE *in_node; + float Cs, Cd; + MOSFET *nx; + int time; /* instantaneous information */ + float voltage, dvg; /* instantaneous information */ + float vgN_1; /* gate voltage at previous event point */ + float G; /* effective conductance at t(n) */ + float effective; /* W over effective L */ + int tabW; /* width in ns/um */ + REGLIST *region; /* region associated with this mos */ + /* NULL if driven by the node of the same region */ +}; + +struct diode{ + float Is; /* saturation current */ + float Vj; /* junction potential */ + double G; + NODE *in_node; + NODE *out_node; + DIODE *nx; +}; + +struct vccs{ + float Is; /* saturation current */ + NODE *in_node; + NODE *out_node; + NODE *pcv_node; + NODE *ncv_node; + DIODE *nx; +}; + +typedef struct { + char name[10]; /* device name */ + int type; /* 1 : NMOS, 2 : PMOS */ + int device_id; /* device id */ +} DEVICENAME; + +struct ms_device{ + char name[10]; + int used; /* device used in circuit flag */ + float rho; /* device vsat denom param */ + float alpha; /* device vsat denom vgg param */ + float vt; /* device zero bias threshold voltage in mv*/ + float gamma; /* device backgate bias vt param */ + float fermi; /* device fermi potential in mv */ + float theta; /* device backgate bias vt width param */ + float mu; /* device vt width param */ + float eta; /* device saturation slope */ + float eta5; /* eta - 0.5 */ + int pzld; /* positive lambda */ + float lambda; /* channel-length modulation */ + float kp; /* device conductance parameter */ + float cgs0; /* gate-source overlap capacitance + per meter channel width */ + float cgd0; /* gate-drain overlap capacitance + per meter channel width */ + float cox; /* oxide-field capacitance + per square meter of gate area */ + float cjsw; /* zero-biased junction sidewall capacitace + per meter of junction perimeter */ + float cj0; /* zero-biased junction bottom capacitace + per square meter of junction area */ + float keq; /* abrupt junction parameter */ + + float ld; /* lateral diffusion */ + float *thresh; + float *sat; + float *dsat; + float *body; + float *gammod; +}; + +struct bp_device{ + char name[10]; + int type; /* 1 : NPN; 2 : PNP */ + float rc; /* collector resistance */ + float re; /* emitter resistance */ + float rb; /* zero bias base resistance */ + float Is; /* transport saturation current */ + float Af; /* ideal maximum forward alpha */ + float Ar; /* ideal maximum reverse alpha */ + float Vje; /* B-E built-in potential */ + float Vjc; /* B-C built-in potential */ +}; + +struct dd_device{ + char name[10]; + float Is; /* saturation current */ + float rs; /* ohmic resistance */ + float Vj; /* junction potential */ +}; + +typedef struct linked_lists_of_Bpoint{ + struct linked_lists_of_Bpoint *next; + int time; + float voltage; + float slope; +} BPOINT, *BPOINTPTR; + +typedef struct linked_lists_of_nodeName{ + char id[24]; + struct linked_lists_of_nodeName *left, *right; + NODE *nd; +} NDname, *NDnamePt; + +struct node { + NDnamePt name; + EMOSFET *mptr; /* pointer to head of src/drn MOSFET list */ + EMOSFET *gptr; /* pointer to head of gate MOSFET list */ + EI_CAP *cptr; /* pointer to head of internodal cap list */ + ERESISTOR *rptr; /* pointer to head of internodal resistor list */ + ERLINE *rlptr; /* pointer to head of internodal TX line list */ + ETXLine *tptr; /* pointer to head of transmission line list */ + ECPLine *cplptr; /* pointer to head of coupled lines list */ + EDIODE *ddptr; /* pointer to head of diode list */ + EVCCS *vccsptr; /* pointer to head of VCCS list */ + EVCCS *cvccsptr;/* pointer to head of controlled VCCS list */ + NODE *next; /* pointer to next node */ + REGLIST *region; /* region associated with this node */ + NODE *base_ptr; /* group src/drn nodes into region */ + /* charles 2,2 1/18/93 + float V; + float dv; voltage at t(n-1) and slope at t(n) + */ + double V; + double dv; + float CL; /* grounded capacitance in F */ + double gsum; /*^ sum of the equivalent conductance */ + double cgsum; /*^ sum of the constant conductance */ + double is; /*^ equivalent Is */ + int tag; /* -2 : Vdd, -3 : Vss, -1 : initial value */ + int flag; /*^ flag to show some features of the node */ + PQUEUE *qptr; /*^ pointer to the entry in the queue or waiting list */ + FILE *ofile; /* output file for the signal at this node */ + /* NULL if not for print */ + int dvtag; +}; + +struct reglist{ + REGLIST *rnxt; /* pointer to next region */ + NODE *nlist; /* node list */ + MOSFET *mos; + I_CAP *cap; + RESISTOR *res; + TXLine *txl; + CPLine *cpl; + struct linked_lists_of_Bpoint *Bpoint; /* break points at primary inputs */ + struct linked_lists_of_Bpoint *head; /* header of the break points at primary inputs */ + int eTime; /* time when this region previously evaluated */ + int DCvalue; + /* 1, 0, 2 : unknown, 3 : unchangeable 1, 4 : unchangeable 0 */ + BQUEUE *prediction; +}; + + +struct bqueue{ + int key; /* time for the event to be fired, or DC weight */ + BQUEUE *left; + BQUEUE *right; + BQUEUE *pred; + BQUEUE *pool; + REGLIST *region; /* region id */ +}; + +struct pqueue { + NODE *node; + PQUEUE *next; + PQUEUE *prev; +}; + +struct i_cap { + NODE *in_node; + NODE *out_node; + float cap; + I_CAP *nx; +}; + +struct resistor { + NODE *in_node; + NODE *out_node; + float g; /* conductance */ + int ifF; /* whether floating */ + float g1; /* conductance for floating resistor */ + RESISTOR *nx; +}; + +struct rline { + NODE *in_node; + NODE *out_node; + float g; /* conductance */ + RLINE *nx; +}; + +typedef struct linked_lists_of_vi_txl{ + struct linked_lists_of_vi_txl *next; + struct linked_lists_of_vi_txl *pool; + int time; + /* charles 2,2 + float v_i, v_o; + float i_i, i_o; + */ + double v_i, v_o; + double i_i, i_o; +} VI_list_txl; + +typedef struct linked_lists_of_vi{ + struct linked_lists_of_vi *next; + struct linked_lists_of_vi *pool; + int time; + float v_i[MAX_CP_TX_LINES], v_o[MAX_CP_TX_LINES]; + float i_i[MAX_CP_TX_LINES], i_o[MAX_CP_TX_LINES]; +} VI_list; + +typedef struct { + double c, x; + double cnv_i, cnv_o; +} TERM; + +typedef struct { + int ifImg; + double aten; + TERM tm[3]; +} TMS; + +struct cpline { + int noL; + int ext; + float ratio[MAX_CP_TX_LINES]; + float taul[MAX_CP_TX_LINES]; + TMS *h1t[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + TMS *h2t[MAX_CP_TX_LINES][MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + TMS *h3t[MAX_CP_TX_LINES][MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double h1C[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double h2C[MAX_CP_TX_LINES][MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double h3C[MAX_CP_TX_LINES][MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double h1e[MAX_CP_TX_LINES][MAX_CP_TX_LINES][3]; + NODE *in_node[MAX_CP_TX_LINES]; + NODE *out_node[MAX_CP_TX_LINES]; + int tag_i[MAX_CP_TX_LINES], tag_o[MAX_CP_TX_LINES]; + CPLine *nx; + struct linked_lists_of_vi *vi_head; + struct linked_lists_of_vi *vi_tail; + float dc1[MAX_CP_TX_LINES], dc2[MAX_CP_TX_LINES]; +}; + +struct txline { + int lsl; /* 1 if the line is lossless, otherwise 0 */ + int ext; /* a flag, set if time step is greater than tau */ + float ratio; + float taul; + double sqtCdL; + double h2_aten; + double h3_aten; + double h1C; + double h1e[3]; + int ifImg; + NODE *in_node; + NODE *out_node; + int tag_i, tag_o; + TERM h1_term[3]; + TERM h2_term[3]; + TERM h3_term[6]; + TXLine *nx; + struct linked_lists_of_vi_txl *vi_head; + struct linked_lists_of_vi_txl *vi_tail; + float dc1, dc2; + int newtp; /* flag indicating new time point */ +}; + +struct evccs { + VCCS *vccs; + EVCCS *link; +}; + +struct ediode { + DIODE *dd; + EDIODE *link; +}; + +struct emosfet { + MOSFET *mos; + EMOSFET *link; +}; + +struct ei_cap { + I_CAP *cap; + EI_CAP *link; +}; + +struct eresistor { + RESISTOR *res; + ERESISTOR *link; +}; + +struct erline { + RLINE *rl; + ERLINE *link; +}; + +struct etxline { + TXLine *line; + ETXLine *link; +}; + +struct ecpline { + CPLine *line; + ECPLine *link; +}; + +#endif diff --git a/src/include/tclspice.h b/src/include/tclspice.h new file mode 100755 index 000000000..e25e1363d --- /dev/null +++ b/src/include/tclspice.h @@ -0,0 +1,33 @@ +/*Include file to allow spice to export certain data */ +#ifndef TCLSPICE_H +#define TCLSPICE_H + +extern int steps_completed; +extern void blt_init(void *run); +extern void blt_add(int index,double value); +extern void blt_relink(int index, void* v); +extern void blt_lockvec(int index); + +/* For things to do per loop */ +int Tcl_ExecutePerLoop(); + +/* For tk ploting */ +extern int sp_Tk_Init(void); +#include +extern int sp_Tk_NewViewport(GRAPH *graph); +extern int sp_Tk_Close(void); +extern int sp_Tk_Clear(void); +extern int sp_Tk_DrawLine(int x1, int y1, int x2, int y2); +extern int sp_Tk_Arc(int x0, int y0, int radius, double theta1, double theta2); +extern int sp_Tk_Text(char *text, int x, int y); +extern int sp_Tk_DefineColor(int colorid, double red, double green, double blue); +extern int sp_Tk_DefineLinestyle(int linestyleid, int mask); +extern int sp_Tk_SetLinestyle(int linestyleid); +extern int sp_Tk_SetColor(int colorid); +extern int sp_Tk_Update(void); + +/* The blt callback method */ +#include +extern int blt_plot(struct dvec *y,struct dvec *x); + +#endif diff --git a/src/include/terminal.h b/src/include/terminal.h new file mode 100644 index 000000000..554c69fb5 --- /dev/null +++ b/src/include/terminal.h @@ -0,0 +1 @@ +#include "../misc/terminal.h" 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/include/wordlist.h b/src/include/wordlist.h new file mode 100644 index 000000000..49191784b --- /dev/null +++ b/src/include/wordlist.h @@ -0,0 +1,36 @@ +#ifndef _WORDLIST_H +#define _WORDLIST_H + + +/* Doubly linked lists of words. */ +struct wordlist { + char *wl_word; + struct wordlist *wl_next; + struct wordlist *wl_prev; +} ; + +typedef struct wordlist wordlist; + +int wl_length(wordlist *wlist); +void wl_free(wordlist *wlist); +wordlist * wl_copy(wordlist *wlist); +wordlist * wl_splice(wordlist *elt, wordlist *list); +void wl_print(wordlist *wlist, FILE *fp); +wordlist * wl_build(char **v); +char ** wl_mkvec(wordlist *wl); +wordlist * wl_append(wordlist *wlist, wordlist *nwl); +wordlist * wl_reverse(wordlist *wl); +char * wl_flatten(wordlist *wl); +wordlist * wl_nthelem(int i, wordlist *wl); +void wl_sort(wordlist *wl); +wordlist * wl_range(wordlist *wl, int low, int up); + + +/* 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) + + +#endif 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/cmath.h b/src/maths/cmaths/cmath.h new file mode 100644 index 000000000..fdecf1e9d --- /dev/null +++ b/src/maths/cmaths/cmath.h @@ -0,0 +1,7 @@ +#ifndef _CMATH_H +#define _CMATH_H + +#define alloc_c(len) ((complex *) tmalloc((len) * sizeof (complex))) +#define alloc_d(len) ((double *) tmalloc((len) * sizeof (double))) + +#endif 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/cmaths/test_cx_j.c b/src/maths/cmaths/test_cx_j.c new file mode 100644 index 000000000..c84d606ad --- /dev/null +++ b/src/maths/cmaths/test_cx_j.c @@ -0,0 +1,34 @@ +#include + +#include +#include +#include +#include + +#include "cmath.h" +#include "cmath1.h" + +FILE *cp_err; + +int +main(void) +{ + complex *c = NULL; + complex *d = NULL; + short int t1; + short int t2; + int n1; + int n2; + + cp_err = stderr; + n1 = 1; + t1 = VF_COMPLEX; + c = alloc_c(n1); + realpart(&c[0]) = .0; + imagpart(&c[0]) = 1.0; + d = (complex *) cx_j((void *) c, t1, n1, &n2, &t2); + if (realpart(&d[0]) == -1 && imagpart(&d[0]) == 0) + return 0; + else + return 1; +} diff --git a/src/maths/cmaths/test_cx_mag.c b/src/maths/cmaths/test_cx_mag.c new file mode 100644 index 000000000..16e19e297 --- /dev/null +++ b/src/maths/cmaths/test_cx_mag.c @@ -0,0 +1,34 @@ +#include + +#include +#include +#include +#include + +#include "cmath.h" +#include "cmath1.h" + +FILE *cp_err; + +int +main(void) +{ + complex *c = NULL; + double *d = NULL; + short int t1; + short int t2; + int n1; + int n2; + + cp_err = stderr; + n1 = 1; + t1 = VF_COMPLEX; + c = alloc_c(n1); + realpart(&c[0]) = .0; + imagpart(&c[0]) = 1.0; + d = (double *) cx_mag((void *) c, t1, n1, &n2, &t2); + if (d[0] == 1) + return 0; + else + return 1; +} diff --git a/src/maths/cmaths/test_cx_ph.c b/src/maths/cmaths/test_cx_ph.c new file mode 100644 index 000000000..ce2f31d41 --- /dev/null +++ b/src/maths/cmaths/test_cx_ph.c @@ -0,0 +1,37 @@ +#include +#include +#include + +#include +#include +#include +#include + +#include "cmath.h" +#include "cmath1.h" + +FILE *cp_err; + +int +main(void) +{ + complex *c = NULL; + double *d = NULL; + short int t1; + short int t2; + int n1; + int n2; + double eps = DBL_EPSILON; + + cp_err = stderr; + n1 = 1; + t1 = VF_COMPLEX; + c = alloc_c(n1); + realpart(&c[0]) = .0; + imagpart(&c[0]) = 1.0; + d = (double *) cx_ph((void *) c, t1, n1, &n2, &t2); + if (M_PI/2 - eps < d[0] && d[0] < M_PI/2 + eps) + return 0; + else + return 1; +} diff --git a/src/maths/deriv/Makefile.am b/src/maths/deriv/Makefile.am new file mode 100644 index 000000000..260e76133 --- /dev/null +++ b/src/maths/deriv/Makefile.am @@ -0,0 +1,23 @@ +## Process this file with automake to produce Makefile.in + +noinst_LIBRARIES = libderiv.a + +libderiv_a_SOURCES = \ + atander.c \ + cosderiv.c \ + cubeder.c \ + divderiv.c \ + equalder.c \ + expderiv.c \ + invderiv.c \ + multder.c \ + plusder.c \ + powderiv.c \ + sqrtder.c \ + tanderiv.c \ + timesder.c + + + +INCLUDES = -I$(top_srcdir)/src/include +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/maths/deriv/atander.c b/src/maths/deriv/atander.c new file mode 100644 index 000000000..e850004c2 --- /dev/null +++ b/src/maths/deriv/atander.c @@ -0,0 +1,80 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1989 Jaijeet S. Roychowdhury +**********/ + +#include "ngspice.h" +#include "distodef.h" +#include "suffix.h" + +/* + * AtanDeriv computes the partial derivatives of the arctangent + * function where the argument to the atan function is itself a + * function of three variables p, q, and r. + */ + +void AtanDeriv(Dderivs *new, Dderivs *old) +{ + + Dderivs temp; + + EqualDeriv(&temp, old); + + new->value = atan( temp.value); + new->d1_p = temp.d1_p / (1 + temp.value * temp.value); + new->d1_q = temp.d1_q / (1 + temp.value * temp.value); + new->d1_r = temp.d1_r / (1 + temp.value * temp.value); + new->d2_p2 = temp.d2_p2 / (1 + temp.value * temp.value) - 2 * + temp.value * new->d1_p * new->d1_p; + new->d2_q2 = temp.d2_q2 / (1 + temp.value * temp.value) - 2 * + temp.value * new->d1_q * new->d1_q; + new->d2_r2 = temp.d2_r2 / (1 + temp.value * temp.value) - 2 * + temp.value * new->d1_r * new->d1_r; + new->d2_pq = temp.d2_pq / (1 + temp.value * temp.value) - 2 * + temp.value * new->d1_p * new->d1_q; + new->d2_qr = temp.d2_qr / (1 + temp.value * temp.value) - 2 * + temp.value * new->d1_q * new->d1_r; + new->d2_pr = temp.d2_pr / (1 + temp.value * temp.value) - 2 * + temp.value * new->d1_p * new->d1_r; + new->d3_p3 = (temp.d3_p3 - temp.d2_p2 * new->d1_p * 2 * + temp.value) / (1 + temp.value * temp.value) - 2 * + (new->d1_p * new->d1_p * temp.d1_p + temp.value * + ( new->d2_p2 * new->d1_p + new->d2_p2 * new->d1_p)); + + new->d3_q3 = (temp.d3_q3 - temp.d2_q2 * new->d1_q * 2 * + temp.value) / (1 + temp.value * temp.value) - 2 * + (new->d1_q * new->d1_q * temp.d1_q + temp.value * + ( new->d2_q2 * new->d1_q + new->d2_q2 * new->d1_q)); + new->d3_r3 = (temp.d3_r3 - temp.d2_r2 * new->d1_r * 2 * + temp.value) / (1 + temp.value * temp.value) - 2 * + (new->d1_r * new->d1_r * temp.d1_r + temp.value * + ( new->d2_r2 * new->d1_r + new->d2_r2 * new->d1_r)); + new->d3_p2r = (temp.d3_p2r - temp.d2_p2 * new->d1_r * 2 * + temp.value) / (1 + temp.value * temp.value) - 2 * + (new->d1_p * new->d1_p * temp.d1_r + temp.value * + ( new->d2_pr * new->d1_p + new->d2_pr * new->d1_p)); + new->d3_p2q = (temp.d3_p2q - temp.d2_p2 * new->d1_q * 2 * + temp.value) / (1 + temp.value * temp.value) - 2 * + (new->d1_p * new->d1_p * temp.d1_q + temp.value * + ( new->d2_pq * new->d1_p + new->d2_pq * new->d1_p)); + new->d3_q2r = (temp.d3_q2r - temp.d2_q2 * new->d1_r * 2 * + temp.value) / (1 + temp.value * temp.value) - 2 * + (new->d1_q * new->d1_q * temp.d1_r + temp.value * + ( new->d2_qr * new->d1_q + new->d2_qr * new->d1_q)); + new->d3_pq2 = (temp.d3_pq2 - temp.d2_q2 * new->d1_p * 2 * + temp.value) / (1 + temp.value * temp.value) - 2 * + (new->d1_q * new->d1_q * temp.d1_p + temp.value * + ( new->d2_pq * new->d1_q + new->d2_pq * new->d1_q)); + new->d3_pr2 = (temp.d3_pr2 - temp.d2_r2 * new->d1_p * 2 * + temp.value) / (1 + temp.value * temp.value) - 2 * + (new->d1_r * new->d1_r * temp.d1_p + temp.value * + ( new->d2_pr * new->d1_r + new->d2_pr * new->d1_r)); + new->d3_qr2 = (temp.d3_qr2 - temp.d2_r2 * new->d1_q * 2 * + temp.value) / (1 + temp.value * temp.value) - 2 * + (new->d1_r * new->d1_r * temp.d1_q + temp.value * + ( new->d2_qr * new->d1_r + new->d2_qr * new->d1_r)); + new->d3_pqr = (temp.d3_pqr - temp.d2_pq * new->d1_r * 2 * + temp.value) / (1 + temp.value * temp.value) - 2 * + (new->d1_p * new->d1_q * temp.d1_r + temp.value * + ( new->d2_pr * new->d1_q + new->d2_qr * new->d1_p)); +} diff --git a/src/maths/deriv/cosderiv.c b/src/maths/deriv/cosderiv.c new file mode 100644 index 000000000..1c9752619 --- /dev/null +++ b/src/maths/deriv/cosderiv.c @@ -0,0 +1,87 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1989 Jaijeet S. Roychowdhury +**********/ + +#include "ngspice.h" +#include "distodef.h" +#include "suffix.h" + +/* + * CosDeriv computes the partial derivatives of the cosine + * function where the argument to the function is itself a + * function of three variables p, q, and r. + */ + +void +CosDeriv(Dderivs *new, Dderivs *old) +{ + + Dderivs temp; + + EqualDeriv(&temp, old); + + new->value = cos (temp.value); + new->d1_p = - sin(temp.value)*temp.d1_p; + new->d1_q = - sin(temp.value)*temp.d1_q; + new->d1_r = - sin(temp.value)*temp.d1_r; + new->d2_p2 = -(cos(temp.value)*temp.d1_p*temp.d1_p + + sin(temp.value)*temp.d2_p2); + new->d2_q2 = -(cos(temp.value)*temp.d1_q*temp.d1_q + + sin(temp.value)*temp.d2_q2); + new->d2_r2 = -(cos(temp.value)*temp.d1_r*temp.d1_r + + sin(temp.value)*temp.d2_r2); + new->d2_pq = -(cos(temp.value)*temp.d1_p*temp.d1_q + + sin(temp.value)*temp.d2_pq); + new->d2_qr = -(cos(temp.value)*temp.d1_q*temp.d1_r + + sin(temp.value)*temp.d2_qr); + new->d2_pr = -(cos(temp.value)*temp.d1_p*temp.d1_r + + sin(temp.value)*temp.d2_pr); + new->d3_p3 = -(sin(temp.value)*(temp.d3_p3 - temp.d1_p*temp.d1_p*temp.d1_p) + + cos(temp.value)*(temp.d1_p*temp.d2_p2 + + temp.d1_p*temp.d2_p2 + + temp.d1_p*temp.d2_p2)); + new->d3_q3 = -(sin(temp.value)*(temp.d3_q3 - temp.d1_q*temp.d1_q*temp.d1_q) + + cos(temp.value)*(temp.d1_q*temp.d2_q2 + + temp.d1_q*temp.d2_q2 + + temp.d1_q*temp.d2_q2)); + new->d3_r3 = -(sin(temp.value)*(temp.d3_r3 - temp.d1_r*temp.d1_r*temp.d1_r) + + cos(temp.value)*(temp.d1_r*temp.d2_r2 + + temp.d1_r*temp.d2_r2 + + temp.d1_r*temp.d2_r2)); + new->d3_p2r = -(sin(temp.value)*(temp.d3_p2r - + temp.d1_r*temp.d1_p*temp.d1_p) + + cos(temp.value)*(temp.d1_p*temp.d2_pr + + temp.d1_p*temp.d2_pr + + temp.d1_r*temp.d2_p2)); + new->d3_p2q = -(sin(temp.value)*(temp.d3_p2q - + temp.d1_q*temp.d1_p*temp.d1_p) + + cos(temp.value)*(temp.d1_p*temp.d2_pq + + temp.d1_p*temp.d2_pq + + temp.d1_q*temp.d2_p2)); + new->d3_q2r = -(sin(temp.value)*(temp.d3_q2r - + temp.d1_r*temp.d1_q*temp.d1_q) + + cos(temp.value)*(temp.d1_q*temp.d2_qr + + temp.d1_q*temp.d2_qr + + temp.d1_r*temp.d2_q2)); + new->d3_pq2 = -(sin(temp.value)*(temp.d3_pq2 - + temp.d1_p*temp.d1_q*temp.d1_q) + + cos(temp.value)*(temp.d1_q*temp.d2_pq + + temp.d1_q*temp.d2_pq + + temp.d1_p*temp.d2_q2)); + new->d3_pr2 = -(sin(temp.value)*(temp.d3_pr2 - + temp.d1_p*temp.d1_r*temp.d1_r) + + cos(temp.value)*(temp.d1_r*temp.d2_pr + + temp.d1_r*temp.d2_pr + + temp.d1_p*temp.d2_r2)); + new->d3_qr2 = -(sin(temp.value)*(temp.d3_qr2 - + temp.d1_q*temp.d1_r*temp.d1_r) + + cos(temp.value)*(temp.d1_r*temp.d2_qr + + temp.d1_r*temp.d2_qr + + temp.d1_q*temp.d2_r2)); + new->d3_pqr = -(sin(temp.value)*(temp.d3_pqr - + temp.d1_r*temp.d1_p*temp.d1_q) + + cos(temp.value)*(temp.d1_q*temp.d2_pr + + temp.d1_p*temp.d2_qr + + temp.d1_r*temp.d2_pq)); +} diff --git a/src/maths/deriv/cubeder.c b/src/maths/deriv/cubeder.c new file mode 100644 index 000000000..97c35fb3d --- /dev/null +++ b/src/maths/deriv/cubeder.c @@ -0,0 +1,89 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1989 Jaijeet S. Roychowdhury +**********/ + +#include "ngspice.h" +#include "distodef.h" +#include "suffix.h" + +/* + * CubeDeriv computes the partial derivatives of the cube + * function where the argument to the function is itself a + * function of three variables p, q, and r. + */ + +void +CubeDeriv(Dderivs *new, Dderivs *old) +{ + Dderivs temp; + + EqualDeriv(&temp, old); + + new->value = temp.value * temp.value * temp.value; + new->d1_p = 3*temp.value*temp.value*temp.d1_p; + new->d1_q = 3*temp.value*temp.value*temp.d1_q; + new->d1_r = 3*temp.value*temp.value*temp.d1_r; + new->d2_p2 = 3*(2*temp.value*temp.d1_p*temp.d1_p + + temp.value*temp.value*temp.d2_p2); + new->d2_q2 = 3*(2*temp.value*temp.d1_q*temp.d1_q + + temp.value*temp.value*temp.d2_q2); + new->d2_r2 = 3*(2*temp.value*temp.d1_r*temp.d1_r + + temp.value*temp.value*temp.d2_r2); + new->d2_pq = 3*(2*temp.value*temp.d1_p*temp.d1_q + + temp.value*temp.value*temp.d2_pq); + new->d2_qr = 3*(2*temp.value*temp.d1_q*temp.d1_r + + temp.value*temp.value*temp.d2_qr); + new->d2_pr = 3*(2*temp.value*temp.d1_p*temp.d1_r + + temp.value*temp.value*temp.d2_pr); + new->d3_p3 = 3*(2*(temp.d1_p*temp.d1_p*temp.d1_p + + temp.value*(temp.d2_p2*temp.d1_p + + temp.d2_p2*temp.d1_p + + temp.d2_p2*temp.d1_p)) + + temp.value*temp.value*temp.d3_p3); + new->d3_q3 = 3*(2*(temp.d1_q*temp.d1_q*temp.d1_q + + temp.value*(temp.d2_q2*temp.d1_q + + temp.d2_q2*temp.d1_q + + temp.d2_q2*temp.d1_q)) + + temp.value*temp.value*temp.d3_q3); + new->d3_r3 = 3*(2*(temp.d1_r*temp.d1_r*temp.d1_r + + temp.value*(temp.d2_r2*temp.d1_r + + temp.d2_r2*temp.d1_r + + temp.d2_r2*temp.d1_r)) + + temp.value*temp.value*temp.d3_r3); + new->d3_p2r = 3*(2*(temp.d1_p*temp.d1_p*temp.d1_r + + temp.value*(temp.d2_p2*temp.d1_r + + temp.d2_pr*temp.d1_p + + temp.d2_pr*temp.d1_p)) + + temp.value*temp.value*temp.d3_p2r); + new->d3_p2q = 3*(2*(temp.d1_p*temp.d1_p*temp.d1_q + + temp.value*(temp.d2_p2*temp.d1_q + + temp.d2_pq*temp.d1_p + + temp.d2_pq*temp.d1_p)) + + temp.value*temp.value*temp.d3_p2q); + new->d3_q2r = 3*(2*(temp.d1_q*temp.d1_q*temp.d1_r + + temp.value*(temp.d2_q2*temp.d1_r + + temp.d2_qr*temp.d1_q + + temp.d2_qr*temp.d1_q)) + + temp.value*temp.value*temp.d3_q2r); + new->d3_pq2 = 3*(2*(temp.d1_q*temp.d1_q*temp.d1_p + + temp.value*(temp.d2_q2*temp.d1_p + + temp.d2_pq*temp.d1_q + + temp.d2_pq*temp.d1_q)) + + temp.value*temp.value*temp.d3_pq2); + new->d3_pr2 = 3*(2*(temp.d1_r*temp.d1_r*temp.d1_p + + temp.value*(temp.d2_r2*temp.d1_p + + temp.d2_pr*temp.d1_r + + temp.d2_pr*temp.d1_r)) + + temp.value*temp.value*temp.d3_pr2); + new->d3_qr2 = 3*(2*(temp.d1_r*temp.d1_r*temp.d1_q + + temp.value*(temp.d2_r2*temp.d1_q + + temp.d2_qr*temp.d1_r + + temp.d2_qr*temp.d1_r)) + + temp.value*temp.value*temp.d3_qr2); + new->d3_pqr = 3*(2*(temp.d1_p*temp.d1_q*temp.d1_r + + temp.value*(temp.d2_pq*temp.d1_r + + temp.d2_qr*temp.d1_p + + temp.d2_pr*temp.d1_q)) + + temp.value*temp.value*temp.d3_pqr); +} diff --git a/src/maths/deriv/divderiv.c b/src/maths/deriv/divderiv.c new file mode 100644 index 000000000..bf1f394db --- /dev/null +++ b/src/maths/deriv/divderiv.c @@ -0,0 +1,134 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1989 Jaijeet S. Roychowdhury +**********/ + +#include "ngspice.h" +#include "distodef.h" +#include "suffix.h" + +/* + * DivDeriv computes the partial derivatives of the division + * function where the arguments to the function are + * functions of three variables p, q, and r. + */ + +void +DivDeriv(Dderivs *new, Dderivs *old1, Dderivs *old2) +{ + + Dderivs num, den; + + EqualDeriv(&num, old1); + EqualDeriv(&den, old2); + + new->value = num.value / den.value; + new->d1_p = (num.d1_p - num.value * den.d1_p / den.value) / den.value; + new->d1_q = (num.d1_q - num.value * den.d1_q / den.value) / den.value; + new->d1_r = (num.d1_r - num.value * den.d1_r / den.value) / den.value; + new->d2_p2 = (num.d2_p2 - den.d1_p * new->d1_p + - new->value * den.d2_p2 + + (den.d1_p * (new->value * den.d1_p - num.d1_p) + / den.value)) / den.value; + new->d2_q2 = (num.d2_q2 - den.d1_q * new->d1_q + - new->value * den.d2_q2 + + (den.d1_q * (new->value * den.d1_q - num.d1_q) + / den.value)) / den.value; + new->d2_r2 = (num.d2_r2 - den.d1_r * new->d1_r - new->value * + den.d2_r2 + den.d1_r * (new->value * den.d1_r - + num.d1_r) / den.value) / + den.value; + new->d2_pq = (num.d2_pq - den.d1_q * new->d1_p - new->value * + den.d2_pq + den.d1_p * (new->value * den.d1_q - + num.d1_q) / den.value) / + den.value; + new->d2_qr = (num.d2_qr - den.d1_r * new->d1_q - new->value * + den.d2_qr + den.d1_q * (new->value * den.d1_r - + num.d1_r) / den.value) / + den.value; + new->d2_pr = (num.d2_pr - den.d1_r * new->d1_p - new->value * + den.d2_pr + den.d1_p * (new->value * den.d1_r - + num.d1_r) / den.value) / + den.value; + new->d3_p3 = (-den.d1_p * new->d2_p2 + num.d3_p3 -den.d2_p2 * + new->d1_p - den.d1_p * new->d2_p2 - new->d1_p * + den.d2_p2 - new->value * den.d3_p3 + + (den.d1_p * (new->d1_p * den.d1_p + + new->value * den.d2_p2 - + num.d2_p2) + + (new->value * den.d1_p - num.d1_p) * + (den.d2_p2 - den.d1_p * den.d1_p / den.value)) + / den.value) / den.value; + new->d3_q3 = (-den.d1_q * new->d2_q2 + num.d3_q3 -den.d2_q2 * + new->d1_q - den.d1_q * new->d2_q2 - new->d1_q * + den.d2_q2 - new->value * den.d3_q3 + + (den.d1_q * (new->d1_q * den.d1_q + new->value * + den.d2_q2 - num.d2_q2) + + (new->value * den.d1_q - num.d1_q) * + (den.d2_q2 - den.d1_q * den.d1_q / den.value)) / + den.value) / den.value; + new->d3_r3 = (-den.d1_r * new->d2_r2 + num.d3_r3 -den.d2_r2 * + new->d1_r - den.d1_r * new->d2_r2 - new->d1_r * + den.d2_r2 - new->value * den.d3_r3 + + (den.d1_r * (new->d1_r * den.d1_r + new->value * + den.d2_r2 - num.d2_r2) + + (new->value * den.d1_r - num.d1_r) * + (den.d2_r2 - den.d1_r * den.d1_r / den.value)) / + den.value) / den.value; + new->d3_p2r = (-den.d1_r * new->d2_p2 + num.d3_p2r -den.d2_pr * + new->d1_p - den.d1_p * new->d2_pr - new->d1_r * + den.d2_p2 - new->value * den.d3_p2r + + (den.d1_p * (new->d1_r * den.d1_p + new->value * + den.d2_pr - num.d2_pr) + + (new->value * den.d1_p - num.d1_p) * + (den.d2_pr - den.d1_p * den.d1_r / den.value)) + / den.value) / den.value; + new->d3_p2q = (-den.d1_q * new->d2_p2 + num.d3_p2q -den.d2_pq * + new->d1_p - den.d1_p * new->d2_pq - new->d1_q * + den.d2_p2 - new->value * den.d3_p2q + + (den.d1_p * (new->d1_q * den.d1_p + new->value * + den.d2_pq - num.d2_pq) + + (new->value * den.d1_p - num.d1_p) * + (den.d2_pq - den.d1_p * den.d1_q / den.value)) / + den.value) / den.value; + new->d3_q2r = (-den.d1_r * new->d2_q2 + num.d3_q2r -den.d2_qr * + new->d1_q - den.d1_q * new->d2_qr - new->d1_r * + den.d2_q2 - new->value * den.d3_q2r + + (den.d1_q * (new->d1_r * den.d1_q + new->value * + den.d2_qr - num.d2_qr) + + (new->value * den.d1_q - num.d1_q) * + (den.d2_qr - den.d1_q * den.d1_r / den.value)) / + den.value) / den.value; + new->d3_pq2 = (-den.d1_p * new->d2_q2 + num.d3_pq2 -den.d2_pq * + new->d1_q - den.d1_q * new->d2_pq - new->d1_p * + den.d2_q2 - new->value * den.d3_pq2 + + (den.d1_q * (new->d1_p * den.d1_q + new->value * + den.d2_pq - num.d2_pq) + + (new->value * den.d1_q - num.d1_q) * + (den.d2_pq - den.d1_q * den.d1_p / den.value)) / + den.value) / den.value; + new->d3_pr2 = (-den.d1_p * new->d2_r2 + num.d3_pr2 -den.d2_pr * + new->d1_r - den.d1_r * new->d2_pr - new->d1_p * + den.d2_r2 - new->value * den.d3_pr2 + + (den.d1_r * (new->d1_p * den.d1_r + new->value * + den.d2_pr - num.d2_pr) + + (new->value * den.d1_r - num.d1_r) * + (den.d2_pr - den.d1_r * den.d1_p / den.value)) / + den.value) / den.value; + new->d3_qr2 = (-den.d1_q * new->d2_r2 + num.d3_qr2 -den.d2_qr * + new->d1_r - den.d1_r * new->d2_qr - new->d1_q * + den.d2_r2 - new->value * den.d3_qr2 + + (den.d1_r * (new->d1_q * den.d1_r + new->value * + den.d2_qr - num.d2_qr) + + (new->value * den.d1_r - num.d1_r) * + (den.d2_qr - den.d1_r * den.d1_q / den.value)) / + den.value) / den.value; + new->d3_pqr = (-den.d1_r * new->d2_pq + num.d3_pqr -den.d2_qr * + new->d1_p - den.d1_q * new->d2_pr - new->d1_r * + den.d2_pq - new->value * den.d3_pqr + + (den.d1_p * (new->d1_r * den.d1_q + new->value * + den.d2_qr - num.d2_qr) + + (new->value * den.d1_q - num.d1_q) * + (den.d2_pr - den.d1_p * den.d1_r / den.value)) / + den.value) / den.value; +} diff --git a/src/maths/deriv/equalder.c b/src/maths/deriv/equalder.c new file mode 100644 index 000000000..e0274d29c --- /dev/null +++ b/src/maths/deriv/equalder.c @@ -0,0 +1,38 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1989 Jaijeet S. Roychowdhury +**********/ + +#include "ngspice.h" +#include "distodef.h" +#include "suffix.h" + +/* + * EqualDeriv equates partial derivatives. + */ + +void +EqualDeriv(Dderivs *new, Dderivs *old) +{ + +new->value = old->value; +new->d1_p = old->d1_p; +new->d1_q = old->d1_q; +new->d1_r = old->d1_r; +new->d2_p2 = old->d2_p2 ; +new->d2_q2 = old->d2_q2 ; +new->d2_r2 = old->d2_r2 ; +new->d2_pq = old->d2_pq ; +new->d2_qr = old->d2_qr ; +new->d2_pr = old->d2_pr ; +new->d3_p3 = old->d3_p3 ; +new->d3_q3 = old->d3_q3 ; +new->d3_r3 = old->d3_r3 ; +new->d3_p2r = old->d3_p2r ; +new->d3_p2q = old->d3_p2q ; +new->d3_q2r = old->d3_q2r ; +new->d3_pq2 = old->d3_pq2 ; +new->d3_pr2 = old->d3_pr2 ; +new->d3_qr2 = old->d3_qr2 ; +new->d3_pqr = old->d3_pqr ; +} diff --git a/src/maths/deriv/expderiv.c b/src/maths/deriv/expderiv.c new file mode 100644 index 000000000..239312c5b --- /dev/null +++ b/src/maths/deriv/expderiv.c @@ -0,0 +1,64 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1989 Jaijeet S. Roychowdhury +**********/ + +#include "ngspice.h" +#include "distodef.h" +#include "suffix.h" + +/* + * ExpDeriv computes the partial derivatives of the exponential + * function where the argument to the function is itself a + * function of three variables p, q, and r. + */ + +void +ExpDeriv(Dderivs *new, Dderivs *old) +{ + + Dderivs temp; + + EqualDeriv(&temp, old); + new->value = exp(temp.value); + new->d1_p = new->value*temp.d1_p; + new->d1_q = new->value*temp.d1_q; + new->d1_r = new->value*temp.d1_r; + new->d2_p2 = new->value*temp.d2_p2 + temp.d1_p*new->d1_p; + new->d2_q2 = new->value*temp.d2_q2 + temp.d1_q*new->d1_q; + new->d2_r2 = new->value*temp.d2_r2 + temp.d1_r*new->d1_r; + new->d2_pq = new->value*temp.d2_pq + temp.d1_p*new->d1_q; + new->d2_qr = new->value*temp.d2_qr + temp.d1_q*new->d1_r; + new->d2_pr = new->value*temp.d2_pr + temp.d1_p*new->d1_r; + new->d3_p3 = new->value*temp.d3_p3 + temp.d2_p2*new->d1_p + + temp.d2_p2*new->d1_p + + new->d2_p2*temp.d1_p; + new->d3_q3 = new->value*temp.d3_q3 + temp.d2_q2*new->d1_q + + temp.d2_q2*new->d1_q + + new->d2_q2*temp.d1_q; + new->d3_r3 = new->value*temp.d3_r3 + temp.d2_r2*new->d1_r + + temp.d2_r2*new->d1_r + + new->d2_r2*temp.d1_r; + new->d3_p2r = new->value*temp.d3_p2r + temp.d2_p2*new->d1_r + + temp.d2_pr*new->d1_p + + new->d2_pr*temp.d1_p; + new->d3_p2q = new->value*temp.d3_p2q + temp.d2_p2*new->d1_q + + temp.d2_pq*new->d1_p + + new->d2_pq*temp.d1_p; + new->d3_q2r = new->value*temp.d3_q2r + temp.d2_q2*new->d1_r + + temp.d2_qr*new->d1_q + + new->d2_qr*temp.d1_q; + new->d3_pq2 = new->value*temp.d3_pq2 + temp.d2_q2*new->d1_p + + temp.d2_pq*new->d1_q + + new->d2_pq*temp.d1_q; + new->d3_pr2 = new->value*temp.d3_pr2 + temp.d2_r2*new->d1_p + + temp.d2_pr*new->d1_r + + new->d2_pr*temp.d1_r; + new->d3_qr2 = new->value*temp.d3_qr2 + temp.d2_r2*new->d1_q + + temp.d2_qr*new->d1_r + + new->d2_qr*temp.d1_r; + new->d3_pqr = new->value*temp.d3_pqr + temp.d2_pq*new->d1_r + + temp.d2_pr*new->d1_q + + new->d2_qr*temp.d1_p; + +} diff --git a/src/maths/deriv/invderiv.c b/src/maths/deriv/invderiv.c new file mode 100644 index 000000000..06d9872c9 --- /dev/null +++ b/src/maths/deriv/invderiv.c @@ -0,0 +1,64 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1989 Jaijeet S. Roychowdhury +**********/ + +#include "ngspice.h" +#include "distodef.h" +#include "suffix.h" + +/* + * InvDeriv computes the partial derivatives of the 1/x + * function where the argument to the function is itself a + * function of three variables p, q, and r. + */ + +void +InvDeriv(Dderivs *new, Dderivs *old) +{ + Dderivs temp; + + EqualDeriv(&temp, old); + + new->value = 1/temp.value; + new->d1_p = -new->value*new->value*temp.d1_p; + new->d1_q = -new->value*new->value*temp.d1_q; + new->d1_r = -new->value*new->value*temp.d1_r; + new->d2_p2 = -new->value*(2*new->d1_p*temp.d1_p + new->value*temp.d2_p2); + new->d2_q2 = -new->value*(2*new->d1_q*temp.d1_q + new->value*temp.d2_q2); + new->d2_r2 = -new->value*(2*new->d1_r*temp.d1_r + new->value*temp.d2_r2); + new->d2_pq = -new->value*(2*new->d1_q*temp.d1_p + new->value*temp.d2_pq); + new->d2_qr = -new->value*(2*new->d1_r*temp.d1_q + new->value*temp.d2_qr); + new->d2_pr = -new->value*(2*new->d1_r*temp.d1_p + new->value*temp.d2_pr); + new->d3_p3 = -(2*(temp.d1_p*new->d1_p*new->d1_p + new->value*( + new->d2_p2*temp.d1_p + new->d1_p*temp.d2_p2 + + new->d1_p*temp.d2_p2)) + new->value*new->value*temp.d3_p3); + new->d3_q3 = -(2*(temp.d1_q*new->d1_q*new->d1_q + new->value*( + new->d2_q2*temp.d1_q + new->d1_q*temp.d2_q2 + + new->d1_q*temp.d2_q2)) + new->value*new->value*temp.d3_q3); + new->d3_r3 = -(2*(temp.d1_r*new->d1_r*new->d1_r + new->value*( + new->d2_r2*temp.d1_r + new->d1_r*temp.d2_r2 + + new->d1_r*temp.d2_r2)) + new->value*new->value*temp.d3_r3); + new->d3_p2r = -(2*(temp.d1_p*new->d1_p*new->d1_r + new->value*( + new->d2_pr*temp.d1_p + new->d1_p*temp.d2_pr + + new->d1_r*temp.d2_p2)) + new->value*new->value*temp.d3_p2r); + new->d3_p2q = -(2*(temp.d1_p*new->d1_p*new->d1_q + new->value*( + new->d2_pq*temp.d1_p + new->d1_p*temp.d2_pq + + new->d1_q*temp.d2_p2)) + new->value*new->value*temp.d3_p2q); + new->d3_q2r = -(2*(temp.d1_q*new->d1_q*new->d1_r + new->value*( + new->d2_qr*temp.d1_q + new->d1_q*temp.d2_qr + + new->d1_r*temp.d2_q2)) + new->value*new->value*temp.d3_q2r); + new->d3_pq2 = -(2*(temp.d1_q*new->d1_q*new->d1_p + new->value*( + new->d2_pq*temp.d1_q + new->d1_q*temp.d2_pq + + new->d1_p*temp.d2_q2)) + new->value*new->value*temp.d3_pq2); + new->d3_pr2 = -(2*(temp.d1_r*new->d1_r*new->d1_p + new->value*( + new->d2_pr*temp.d1_r + new->d1_r*temp.d2_pr + + new->d1_p*temp.d2_r2)) + new->value*new->value*temp.d3_pr2); + new->d3_qr2 = -(2*(temp.d1_r*new->d1_r*new->d1_q + new->value*( + new->d2_qr*temp.d1_r + new->d1_r*temp.d2_qr + + new->d1_q*temp.d2_r2)) + new->value*new->value*temp.d3_qr2); + new->d3_pqr = -(2*(temp.d1_p*new->d1_q*new->d1_r + new->value*( + new->d2_qr*temp.d1_p + new->d1_q*temp.d2_pr + + new->d1_r*temp.d2_pq)) + new->value*new->value*temp.d3_pqr); + +} diff --git a/src/maths/deriv/multder.c b/src/maths/deriv/multder.c new file mode 100644 index 000000000..68a8d5a60 --- /dev/null +++ b/src/maths/deriv/multder.c @@ -0,0 +1,81 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1989 Jaijeet S. Roychowdhury +**********/ + +#include "ngspice.h" +#include "distodef.h" +#include "suffix.h" + +/* + * MultDeriv computes the partial derivatives of the multiplication + * function where the arguments to the function are + * functions of three variables p, q, and r. + */ + +void +MultDeriv(Dderivs *new, Dderivs *old1, Dderivs *old2) +{ + Dderivs temp1, temp2; + + EqualDeriv(&temp1, old1); + EqualDeriv(&temp2, old2); + + new->value = temp1.value * temp2.value; + new->d1_p = temp1.d1_p*temp2.value + temp1.value*temp2.d1_p; + new->d1_q = temp1.d1_q*temp2.value + temp1.value*temp2.d1_q; + new->d1_r = temp1.d1_r*temp2.value + temp1.value*temp2.d1_r; + new->d2_p2 = temp1.d2_p2*temp2.value + temp1.d1_p*temp2.d1_p + + temp1.d1_p*temp2.d1_p + temp1.value*temp2.d2_p2; + new->d2_q2 = temp1.d2_q2*temp2.value + temp1.d1_q*temp2.d1_q + + temp1.d1_q*temp2.d1_q + temp1.value*temp2.d2_q2; + new->d2_r2 = temp1.d2_r2*temp2.value + temp1.d1_r*temp2.d1_r + + temp1.d1_r*temp2.d1_r + temp1.value*temp2.d2_r2; + new->d2_pq = temp1.d2_pq*temp2.value + temp1.d1_p*temp2.d1_q + + temp1.d1_q*temp2.d1_p + temp1.value*temp2.d2_pq; + new->d2_qr = temp1.d2_qr*temp2.value + temp1.d1_q*temp2.d1_r + + temp1.d1_r*temp2.d1_q + temp1.value*temp2.d2_qr; + new->d2_pr = temp1.d2_pr*temp2.value + temp1.d1_p*temp2.d1_r + + temp1.d1_r*temp2.d1_p + temp1.value*temp2.d2_pr; + new->d3_p3 = temp1.d3_p3*temp2.value + temp1.d2_p2*temp2.d1_p + + temp1.d2_p2*temp2.d1_p + temp2.d2_p2*temp1.d1_p + + temp2.d2_p2*temp1.d1_p + temp1.d2_p2*temp2.d1_p + + temp2.d2_p2*temp1.d1_p + temp1.value*temp2.d3_p3; + + new->d3_q3 = temp1.d3_q3*temp2.value + temp1.d2_q2*temp2.d1_q + + temp1.d2_q2*temp2.d1_q + temp2.d2_q2*temp1.d1_q + + temp2.d2_q2*temp1.d1_q + temp1.d2_q2*temp2.d1_q + + temp2.d2_q2*temp1.d1_q + temp1.value*temp2.d3_q3; + new->d3_r3 = temp1.d3_r3*temp2.value + temp1.d2_r2*temp2.d1_r + + temp1.d2_r2*temp2.d1_r + temp2.d2_r2*temp1.d1_r + + temp2.d2_r2*temp1.d1_r + temp1.d2_r2*temp2.d1_r + + temp2.d2_r2*temp1.d1_r + temp1.value*temp2.d3_r3; + new->d3_p2r = temp1.d3_p2r*temp2.value + temp1.d2_p2*temp2.d1_r + + temp1.d2_pr*temp2.d1_p + temp2.d2_p2*temp1.d1_r + + temp2.d2_pr*temp1.d1_p + temp1.d2_pr*temp2.d1_p + + temp2.d2_pr*temp1.d1_p + temp1.value*temp2.d3_p2r; + new->d3_p2q = temp1.d3_p2q*temp2.value + temp1.d2_p2*temp2.d1_q + + temp1.d2_pq*temp2.d1_p + temp2.d2_p2*temp1.d1_q + + temp2.d2_pq*temp1.d1_p + temp1.d2_pq*temp2.d1_p + + temp2.d2_pq*temp1.d1_p + temp1.value*temp2.d3_p2q; + new->d3_q2r = temp1.d3_q2r*temp2.value + temp1.d2_q2*temp2.d1_r + + temp1.d2_qr*temp2.d1_q + temp2.d2_q2*temp1.d1_r + + temp2.d2_qr*temp1.d1_q + temp1.d2_qr*temp2.d1_q + + temp2.d2_qr*temp1.d1_q + temp1.value*temp2.d3_q2r; + new->d3_pq2 = temp1.d3_pq2*temp2.value + temp1.d2_q2*temp2.d1_p + + temp1.d2_pq*temp2.d1_q + temp2.d2_q2*temp1.d1_p + + temp2.d2_pq*temp1.d1_q + temp1.d2_pq*temp2.d1_q + + temp2.d2_pq*temp1.d1_q + temp1.value*temp2.d3_pq2; + new->d3_pr2 = temp1.d3_pr2*temp2.value + temp1.d2_r2*temp2.d1_p + + temp1.d2_pr*temp2.d1_r + temp2.d2_r2*temp1.d1_p + + temp2.d2_pr*temp1.d1_r + temp1.d2_pr*temp2.d1_r + + temp2.d2_pr*temp1.d1_r + temp1.value*temp2.d3_pr2; + new->d3_qr2 = temp1.d3_qr2*temp2.value + temp1.d2_r2*temp2.d1_q + + temp1.d2_qr*temp2.d1_r + temp2.d2_r2*temp1.d1_q + + temp2.d2_qr*temp1.d1_r + temp1.d2_qr*temp2.d1_r + + temp2.d2_qr*temp1.d1_r + temp1.value*temp2.d3_qr2; + new->d3_pqr = temp1.d3_pqr*temp2.value + temp1.d2_pq*temp2.d1_r + + temp1.d2_pr*temp2.d1_q + temp2.d2_pq*temp1.d1_r + + temp2.d2_qr*temp1.d1_p + temp1.d2_qr*temp2.d1_p + + temp2.d2_pr*temp1.d1_q + temp1.value*temp2.d3_pqr; +} diff --git a/src/maths/deriv/plusder.c b/src/maths/deriv/plusder.c new file mode 100644 index 000000000..5c03a4d73 --- /dev/null +++ b/src/maths/deriv/plusder.c @@ -0,0 +1,39 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1989 Jaijeet S. Roychowdhury +**********/ + +#include "ngspice.h" +#include "distodef.h" +#include "suffix.h" + +/* + * PlusDeriv computes the partial derivatives of the addition + * function where the arguments to the function are + * functions of three variables p, q, and r. + */ + +void +PlusDeriv(Dderivs *new, Dderivs *old1, Dderivs *old2) +{ + new->value = old1->value + old2->value; + new->d1_p = old1->d1_p + old2->d1_p; + new->d1_q = old1->d1_q + old2->d1_q; + new->d1_r = old1->d1_r + old2->d1_r; + new->d2_p2 = old1->d2_p2 + old2->d2_p2; + new->d2_q2 = old1->d2_q2 + old2->d2_q2; + new->d2_r2 = old1->d2_r2 + old2->d2_r2; + new->d2_pq = old1->d2_pq + old2->d2_pq; + new->d2_qr = old1->d2_qr + old2->d2_qr; + new->d2_pr = old1->d2_pr + old2->d2_pr; + new->d3_p3 = old1->d3_p3 + old2->d3_p3; + new->d3_q3 = old1->d3_q3 + old2->d3_q3; + new->d3_r3 = old1->d3_r3 + old2->d3_r3; + new->d3_p2r = old1->d3_p2r + old2->d3_p2r; + new->d3_p2q = old1->d3_p2q + old2->d3_p2q; + new->d3_q2r = old1->d3_q2r + old2->d3_q2r; + new->d3_pq2 = old1->d3_pq2 + old2->d3_pq2; + new->d3_pr2 = old1->d3_pr2 + old2->d3_pr2; + new->d3_qr2 = old1->d3_qr2 + old2->d3_qr2; + new->d3_pqr = old1->d3_pqr + old2->d3_pqr; +} diff --git a/src/maths/deriv/powderiv.c b/src/maths/deriv/powderiv.c new file mode 100644 index 000000000..054054af0 --- /dev/null +++ b/src/maths/deriv/powderiv.c @@ -0,0 +1,81 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1989 Jaijeet S. Roychowdhury +**********/ + +#include "ngspice.h" +#include "distodef.h" +#include "suffix.h" + +/* + * PowDeriv computes the partial derivatives of the x^^m + * function where the argument to the function is itself a + * function of three variables p, q, and r. m is a constant. + */ + +void +PowDeriv(Dderivs *new, Dderivs *old, double emm) +{ + Dderivs temp; + + EqualDeriv(&temp, old); + + new->value = pow(temp.value, emm); + new->d1_p = emm * new->value / temp.value * temp.d1_p; + new->d1_q = emm * new->value / temp.value * temp.d1_q; + new->d1_r = emm * new->value / temp.value * temp.d1_r; + new->d2_p2 = emm * new->value / temp.value * + ((emm-1) / temp.value * temp.d1_p * temp.d1_p + temp.d2_p2); + new->d2_q2 = emm * new->value / temp.value * + ((emm-1) / temp.value * temp.d1_q * temp.d1_q + temp.d2_q2); + new->d2_r2 = emm * new->value / temp.value * + ((emm-1) / temp.value * temp.d1_r * temp.d1_r + temp.d2_r2); + new->d2_pq = emm * new->value / temp.value * + ((emm-1) / temp.value * temp.d1_p * temp.d1_q + temp.d2_pq); + new->d2_qr = emm * new->value / temp.value * + ((emm-1) / temp.value * temp.d1_q * temp.d1_r + temp.d2_qr); + new->d2_pr = emm * new->value / temp.value * + ((emm-1) / temp.value * temp.d1_p * temp.d1_r + temp.d2_pr); + new->d3_p3 = emm * (emm-1) * new->value / (temp.value * temp.value) * + ((emm-2) / temp.value * temp.d1_p * + temp.d1_p * temp.d1_p + temp.d1_p * temp.d2_p2 + temp.d1_p * + temp.d2_p2 + temp.d1_p * temp.d2_p2) + emm * new->value / + temp.value * temp.d3_p3; + new->d3_q3 = emm * (emm-1) * new->value / (temp.value * temp.value) * + ((emm-2) / temp.value * temp.d1_q * + temp.d1_q * temp.d1_q + temp.d1_q * temp.d2_q2 + temp.d1_q * + temp.d2_q2 + temp.d1_q * temp.d2_q2) + emm * new->value / + temp.value * temp.d3_q3; + new->d3_r3 = emm * (emm-1) * new->value / (temp.value * temp.value) * + ((emm-2) / temp.value * temp.d1_r *temp.d1_r * temp.d1_r + + temp.d1_r * temp.d2_r2 + temp.d1_r * temp.d2_r2 + temp.d1_r * + temp.d2_r2) + emm * new->value / temp.value * temp.d3_r3; + new->d3_p2r = emm * (emm-1) * new->value / (temp.value * temp.value) * + ((emm-2) / temp.value * temp.d1_p * temp.d1_p * temp.d1_r + + temp.d1_p * temp.d2_pr + temp.d1_p * temp.d2_pr + temp.d1_r * + temp.d2_p2) + emm * new->value / temp.value * temp.d3_p2r; + new->d3_p2q = emm * (emm-1) * new->value / (temp.value * temp.value) * + ((emm-2) / temp.value * temp.d1_p * temp.d1_p * temp.d1_q + + temp.d1_p * temp.d2_pq + temp.d1_p * temp.d2_pq + temp.d1_q * + temp.d2_p2) + emm * new->value / temp.value * temp.d3_p2q; + new->d3_q2r = emm * (emm-1) * new->value / (temp.value * temp.value) * + ((emm-2) / temp.value * temp.d1_q * temp.d1_q * temp.d1_r + + temp.d1_q * temp.d2_qr + temp.d1_q * temp.d2_qr + temp.d1_r * + temp.d2_q2) + emm * new->value / temp.value * temp.d3_q2r; + new->d3_pq2 = emm * (emm-1) * new->value / (temp.value * temp.value) * + ((emm-2) / temp.value * temp.d1_q * temp.d1_q * temp.d1_p + + temp.d1_q * temp.d2_pq + temp.d1_q * temp.d2_pq + temp.d1_p * + temp.d2_q2) + emm * new->value / temp.value * temp.d3_pq2; + new->d3_pr2 = emm * (emm-1) * new->value / (temp.value * temp.value) * + ((emm-2) / temp.value * temp.d1_r * temp.d1_r * temp.d1_p + + temp.d1_r * temp.d2_pr + temp.d1_r * temp.d2_pr + temp.d1_p * + temp.d2_r2) + emm * new->value / temp.value * temp.d3_pr2; + new->d3_qr2 = emm * (emm-1) * new->value / (temp.value * temp.value) * + ((emm-2) / temp.value * temp.d1_r * temp.d1_r * temp.d1_q + + temp.d1_r * temp.d2_qr + temp.d1_r * temp.d2_qr + temp.d1_q * + temp.d2_r2) + emm * new->value / temp.value * temp.d3_qr2; + new->d3_pqr = emm * (emm-1) * new->value / (temp.value * temp.value) * + ((emm-2) / temp.value * temp.d1_p * temp.d1_q * temp.d1_r + + temp.d1_p * temp.d2_qr + temp.d1_q * temp.d2_pr + temp.d1_r * + temp.d2_pq) + emm * new->value / temp.value * temp.d3_pqr; +} diff --git a/src/maths/deriv/sqrtder.c b/src/maths/deriv/sqrtder.c new file mode 100644 index 000000000..663f62993 --- /dev/null +++ b/src/maths/deriv/sqrtder.c @@ -0,0 +1,122 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1989 Jaijeet S. Roychowdhury +**********/ + +#include "ngspice.h" +#include "distodef.h" +#include "suffix.h" + +/* + * SqrtDeriv computes the partial derivatives of the sqrt + * function where the argument to the function is itself a + * function of three variables p, q, and r. + */ + +void +SqrtDeriv(Dderivs *new, Dderivs *old) +{ + + Dderivs temp; + + EqualDeriv(&temp, old); + new->value = sqrt(temp.value); + if (temp.value == 0.0) + { + new->d1_p = 0.0; + new->d1_q = 0.0; + new->d1_r = 0.0; + new->d2_p2 = 0.0; + new->d2_q2 = 0.0; + new->d2_r2 = 0.0; + new->d2_pq = 0.0; + new->d2_qr = 0.0; + new->d2_pr = 0.0; + new->d3_p3 = 0.0; + new->d3_q3 = 0.0; + new->d3_r3 = 0.0; + new->d3_p2r = 0.0; + new->d3_p2q = 0.0; + new->d3_q2r = 0.0; + new->d3_pq2 = 0.0; + new->d3_pr2 = 0.0; + new->d3_qr2 = 0.0; + new->d3_pqr = 0.0; + } else { + new->d1_p = 0.5*temp.d1_p/new->value; + new->d1_q = 0.5*temp.d1_q/new->value; + new->d1_r = 0.5*temp.d1_r/new->value; + new->d2_p2 = 0.5/new->value * (temp.d2_p2 - 0.5 * temp.d1_p * + temp.d1_p/ temp.value); + new->d2_q2 = 0.5/new->value*(temp.d2_q2 -0.5 * temp.d1_q * + temp.d1_q/ temp.value); + new->d2_r2 = 0.5/new->value*(temp.d2_r2 -0.5 * temp.d1_r * + temp.d1_r/ temp.value); + new->d2_pq = 0.5/new->value*(temp.d2_pq -0.5 * temp.d1_p * + temp.d1_q/ temp.value); + new->d2_qr = 0.5/new->value*(temp.d2_qr -0.5 * temp.d1_q * + temp.d1_r/ temp.value); + new->d2_pr = 0.5/new->value*(temp.d2_pr -0.5 * temp.d1_p * + temp.d1_r/ temp.value); + new->d3_p3 = 0.5 * + (temp.d3_p3 / new->value - 0.5 / (temp.value*new->value) * + (-1.5 / temp.value * temp.d1_p * temp.d1_p * temp.d1_p + + temp.d1_p*temp.d2_p2 + + temp.d1_p*temp.d2_p2 + + temp.d1_p*temp.d2_p2)); + new->d3_q3 = 0.5 * + (temp.d3_q3 / new->value - 0.5 / (temp.value*new->value) * + (-1.5 / temp.value * temp.d1_q * temp.d1_q * temp.d1_q + + temp.d1_q*temp.d2_q2 + + temp.d1_q*temp.d2_q2 + + temp.d1_q* temp.d2_q2)); + new->d3_r3 = 0.5 * + (temp.d3_r3 / new->value - 0.5 / (temp.value*new->value) * + (-1.5 / temp.value * temp.d1_r * temp.d1_r * temp.d1_r + + temp.d1_r*temp.d2_r2 + + temp.d1_r*temp.d2_r2 + + temp.d1_r* temp.d2_r2)); + new->d3_p2r = 0.5 * + (temp.d3_p2r / new->value - 0.5 / (temp.value*new->value) * + (-1.5 / temp.value * temp.d1_p * temp.d1_p * temp.d1_r + + temp.d1_p * temp.d2_pr + + temp.d1_p * temp.d2_pr + + temp.d1_r * temp.d2_p2)); + new->d3_p2q = 0.5 * + (temp.d3_p2q / new->value - 0.5 / (temp.value * new->value) * + (-1.5/temp.value*temp.d1_p*temp.d1_p*temp.d1_q + + temp.d1_p * temp.d2_pq + + temp.d1_p * temp.d2_pq + + temp.d1_q * temp.d2_p2)); + new->d3_q2r = 0.5 * + (temp.d3_q2r / new->value - 0.5 / (temp.value * new->value) * + (-1.5 / temp.value * temp.d1_q * temp.d1_q * temp.d1_r + + temp.d1_q*temp.d2_qr + + temp.d1_q*temp.d2_qr + + temp.d1_r* temp.d2_q2)); + new->d3_pq2 = 0.5 * + (temp.d3_pq2 / new->value - 0.5 / (temp.value * new->value) * + (-1.5 / temp.value * temp.d1_q * temp.d1_q * temp.d1_p + + temp.d1_q*temp.d2_pq + + temp.d1_q*temp.d2_pq + + temp.d1_p* temp.d2_q2)); + new->d3_pr2 = 0.5 * + (temp.d3_pr2 / new->value - 0.5 / (temp.value * new->value) * + (-1.5/temp.value * temp.d1_r * temp.d1_r * temp.d1_p + + temp.d1_r*temp.d2_pr + + temp.d1_r*temp.d2_pr + + temp.d1_p* temp.d2_r2)); + new->d3_qr2 = 0.5 * + (temp.d3_qr2 / new->value - 0.5 / (temp.value * new->value) * + (-1.5/temp.value * temp.d1_r * temp.d1_r * temp.d1_q + + temp.d1_r*temp.d2_qr + + temp.d1_r*temp.d2_qr + + temp.d1_q* temp.d2_r2)); + new->d3_pqr = 0.5 * + (temp.d3_pqr / new->value - 0.5 / (temp.value * new->value) * + (-1.5/temp.value * temp.d1_p * temp.d1_q * temp.d1_r + + temp.d1_p*temp.d2_qr + + temp.d1_q*temp.d2_pr + + temp.d1_r* temp.d2_pq)); + } +} diff --git a/src/maths/deriv/tanderiv.c b/src/maths/deriv/tanderiv.c new file mode 100644 index 000000000..fec1f78b4 --- /dev/null +++ b/src/maths/deriv/tanderiv.c @@ -0,0 +1,64 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1989 Jaijeet S. Roychowdhury +**********/ + +#include "ngspice.h" +#include "distodef.h" +#include "suffix.h" + +/* + * TanDeriv computes the partial derivatives of the tangent + * function where the argument to the function is itself a + * function of three variables p, q, and r. + */ + +void TanDeriv(new, old) +Dderivs *new, *old; +{ + +Dderivs temp; + +EqualDeriv(&temp, old); +new->value = tan(temp.value); + +new->d1_p = (1 + new->value*new->value)*temp.d1_p; +new->d1_q = (1 + new->value*new->value)*temp.d1_q; +new->d1_r = (1 + new->value*new->value)*temp.d1_r; +new->d2_p2 = (1 + new->value*new->value)*temp.d2_p2 + 2*new->value*temp.d1_p*new->d1_p; +new->d2_q2 = (1 + new->value*new->value)*temp.d2_q2 + 2*new->value*temp.d1_q*new->d1_q; +new->d2_r2 = (1 + new->value*new->value)*temp.d2_r2 + 2*new->value*temp.d1_r*new->d1_r; +new->d2_pq = (1 + new->value*new->value)*temp.d2_pq + 2*new->value*temp.d1_p*new->d1_q; +new->d2_qr = (1 + new->value*new->value)*temp.d2_qr + 2*new->value*temp.d1_q*new->d1_r; +new->d2_pr = (1 + new->value*new->value)*temp.d2_pr + 2*new->value*temp.d1_p*new->d1_r; +new->d3_p3 = (1 + new->value*new->value)*temp.d3_p3 +2*( new->value*( + temp.d2_p2*new->d1_p + temp.d2_p2*new->d1_p + new->d2_p2* + temp.d1_p) + temp.d1_p*new->d1_p*new->d1_p); +new->d3_q3 = (1 + new->value*new->value)*temp.d3_q3 +2*( new->value*( + temp.d2_q2*new->d1_q + temp.d2_q2*new->d1_q + new->d2_q2* + temp.d1_q) + temp.d1_q*new->d1_q*new->d1_q); +new->d3_r3 = (1 + new->value*new->value)*temp.d3_r3 +2*( new->value*( + temp.d2_r2*new->d1_r + temp.d2_r2*new->d1_r + new->d2_r2* + temp.d1_r) + temp.d1_r*new->d1_r*new->d1_r); +new->d3_p2r = (1 + new->value*new->value)*temp.d3_p2r +2*( new->value*( + temp.d2_p2*new->d1_r + temp.d2_pr*new->d1_p + new->d2_pr* + temp.d1_p) + temp.d1_p*new->d1_p*new->d1_r); +new->d3_p2q = (1 + new->value*new->value)*temp.d3_p2q +2*( new->value*( + temp.d2_p2*new->d1_q + temp.d2_pq*new->d1_p + new->d2_pq* + temp.d1_p) + temp.d1_p*new->d1_p*new->d1_q); +new->d3_q2r = (1 + new->value*new->value)*temp.d3_q2r +2*( new->value*( + temp.d2_q2*new->d1_r + temp.d2_qr*new->d1_q + new->d2_qr* + temp.d1_q) + temp.d1_q*new->d1_q*new->d1_r); +new->d3_pq2 = (1 + new->value*new->value)*temp.d3_pq2 +2*( new->value*( + temp.d2_q2*new->d1_p + temp.d2_pq*new->d1_q + new->d2_pq* + temp.d1_q) + temp.d1_q*new->d1_q*new->d1_p); +new->d3_pr2 = (1 + new->value*new->value)*temp.d3_pr2 +2*( new->value*( + temp.d2_r2*new->d1_p + temp.d2_pr*new->d1_r + new->d2_pr* + temp.d1_r) + temp.d1_r*new->d1_r*new->d1_p); +new->d3_qr2 = (1 + new->value*new->value)*temp.d3_qr2 +2*( new->value*( + temp.d2_r2*new->d1_q + temp.d2_qr*new->d1_r + new->d2_qr* + temp.d1_r) + temp.d1_r*new->d1_r*new->d1_q); +new->d3_pqr = (1 + new->value*new->value)*temp.d3_pqr +2*( new->value*( + temp.d2_pq*new->d1_r + temp.d2_pr*new->d1_q + new->d2_qr* + temp.d1_p) + temp.d1_p*new->d1_q*new->d1_r); + } diff --git a/src/maths/deriv/timesder.c b/src/maths/deriv/timesder.c new file mode 100644 index 000000000..b5ca429ab --- /dev/null +++ b/src/maths/deriv/timesder.c @@ -0,0 +1,39 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1989 Jaijeet S. Roychowdhury +**********/ + +#include "ngspice.h" +#include "distodef.h" +#include "suffix.h" + +/* + * TimesDeriv computes the partial derivatives of the x*k + * function where the argument to the function is itself a + * function of three variables p, q, and r. k is a constant. + */ + +void +TimesDeriv(Dderivs *new, Dderivs *old, double k) +{ + new->value = k* old->value; + new->d1_p = k*old->d1_p; + new->d1_q = k*old->d1_q; + new->d1_r = k*old->d1_r; + new->d2_p2 = k*old->d2_p2; + new->d2_q2 = k*old->d2_q2; + new->d2_r2 = k*old->d2_r2; + new->d2_pq = k*old->d2_pq; + new->d2_qr = k*old->d2_qr; + new->d2_pr = k*old->d2_pr; + new->d3_p3 = k*old->d3_p3; + new->d3_q3 = k*old->d3_q3; + new->d3_r3 = k*old->d3_r3; + new->d3_p2r = k*old->d3_p2r; + new->d3_p2q = k*old->d3_p2q; + new->d3_q2r = k*old->d3_q2r; + new->d3_pq2 = k*old->d3_pq2; + new->d3_pr2 = k*old->d3_pr2; + new->d3_qr2 = k*old->d3_qr2; + new->d3_pqr = k*old->d3_pqr; +} 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/poly/ChangeLog b/src/maths/poly/ChangeLog new file mode 100644 index 000000000..da8056de2 --- /dev/null +++ b/src/maths/poly/ChangeLog @@ -0,0 +1,5 @@ +2000-10-13 Arno W. Peters + + * polyfit.c: Input matrix got overwritten too soon, leading to NaN + results for Fourier Analysis. Fix due to Daniele Gordini. + diff --git a/src/maths/poly/Makefile.am b/src/maths/poly/Makefile.am new file mode 100644 index 000000000..bdff80280 --- /dev/null +++ b/src/maths/poly/Makefile.am @@ -0,0 +1,18 @@ +## Process this file with automake to produce Makefile.in + +noinst_LIBRARIES = libpoly.a + +libpoly_a_SOURCES = \ + interpolate.c \ + interpolate.h \ + polyfit.c \ + polyfit.h \ + polyderiv.c \ + polyderiv.h \ + polyeval.c \ + polyeval.h + + +INCLUDES = -I$(top_srcdir)/src/include + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/maths/poly/interpolate.c b/src/maths/poly/interpolate.c new file mode 100644 index 000000000..b9482125f --- /dev/null +++ b/src/maths/poly/interpolate.c @@ -0,0 +1,122 @@ +#include +#include +#include + +#include "interpolate.h" +#include "polyeval.h" +#include "polyfit.h" + +/* 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); +} + + +/* 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. + */ +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); +} diff --git a/src/maths/poly/interpolate.h b/src/maths/poly/interpolate.h new file mode 100644 index 000000000..f39fd88ff --- /dev/null +++ b/src/maths/poly/interpolate.h @@ -0,0 +1,8 @@ +#ifndef _INTERPOLATE_H +#define _INTERPOLATE_H + +#include + +bool ft_interpolate(double *data, double *ndata, double *oscale, int olen, double *nscale, int nlen, int degree); + +#endif diff --git a/src/maths/poly/polyderiv.c b/src/maths/poly/polyderiv.c new file mode 100644 index 000000000..80666a38e --- /dev/null +++ b/src/maths/poly/polyderiv.c @@ -0,0 +1,11 @@ +#include "polyderiv.h" + +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/maths/poly/polyderiv.h b/src/maths/poly/polyderiv.h new file mode 100644 index 000000000..a0a275edf --- /dev/null +++ b/src/maths/poly/polyderiv.h @@ -0,0 +1,6 @@ +#ifndef _POLYDERIV_H +#define _POLYDERIV_H + +void ft_polyderiv(double *coeffs, int degree); + +#endif diff --git a/src/maths/poly/polyeval.c b/src/maths/poly/polyeval.c new file mode 100644 index 000000000..0860cbe03 --- /dev/null +++ b/src/maths/poly/polyeval.c @@ -0,0 +1,20 @@ +#include "polyeval.h" + +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; +} diff --git a/src/maths/poly/polyeval.h b/src/maths/poly/polyeval.h new file mode 100644 index 000000000..1ed9c8074 --- /dev/null +++ b/src/maths/poly/polyeval.h @@ -0,0 +1,6 @@ +#ifndef _POLYEVAL_H +#define _POLYEVAL_H + +double ft_peval(double x, double *coeffs, int degree); + +#endif diff --git a/src/maths/poly/polyfit.c b/src/maths/poly/polyfit.c new file mode 100644 index 000000000..86e2e98a0 --- /dev/null +++ b/src/maths/poly/polyfit.c @@ -0,0 +1,120 @@ +#include +#include + +#ifdef HAVE_STRING_H +#include +#endif +#include "polyfit.h" +#include "polyeval.h" + +/* 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 tmallocs for each call. */ +bool +ft_polyfit(double *xdata, double *ydata, double *result, + int degree, double *scratch) +{ + double *mat1 = scratch; + int l, k, j, i; + int n = degree + 1; + double *mat2 = scratch + n * n; /* XXX These guys are hacks! */ + double d; + + memset((char *) result, 0, n * sizeof(double)); + memset((char *) mat1, 0, n * n * sizeof (double)); + memcpy((char *) mat2, (char *) ydata, 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; + } + /* 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); +} diff --git a/src/maths/poly/polyfit.h b/src/maths/poly/polyfit.h new file mode 100644 index 000000000..e27cf3c49 --- /dev/null +++ b/src/maths/poly/polyfit.h @@ -0,0 +1,9 @@ +#ifndef _POLYFIT_H +#define _POLYFIT_H + +#include + +bool ft_polyfit(double *xdata, double *ydata, double *result, + int degree, double *scratch); + +#endif 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/spconfig.h b/src/maths/sparse/spconfig.h new file mode 100644 index 000000000..c2e2bc11f --- /dev/null +++ b/src/maths/sparse/spconfig.h @@ -0,0 +1,406 @@ +/* + * CONFIGURATION MACRO DEFINITIONS for sparse matrix routines + * + * Author: Advising professor: + * Kenneth S. Kundert Alberto Sangiovanni-Vincentelli + * U.C. Berkeley + * + * This file contains macros for the sparse matrix routines that are used + * to define the personality of the routines. The user is expected to + * modify this file to maximize the performance of the routines with + * his/her matrices. + * + * 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. + */ + + +/* + * Revision and copyright information. + * + * Copyright (c) 1985,86,87,88,89,90 + * by Kenneth S. Kundert and the University of California. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the copyright notices appear in all copies and + * supporting documentation and that the authors and the University of + * California are properly credited. The authors and the University of + * California make no representations as to the suitability of this + * software for any purpose. It is provided `as is', without express + * or implied warranty. + * + * $Date$ + * $Revision$ + */ + + +#ifndef spCONFIG_DEFS +#define spCONFIG_DEFS + + + + +#ifdef spINSIDE_SPARSE +/* + * OPTIONS + * + * These are compiler options. Set each option to one to compile that + * section of the code. If a feature is not desired, set the macro + * to NO. Recommendations are given in brackets, [ignore them]. + * + * >>> Option descriptions: + * Arithmetic Precision + * The precision of the arithmetic used by Sparse can be set by + * changing changing the spREAL macro. This macro is + * contained in the file spMatrix.h. It is strongly suggested to + * used double precision with circuit simulators. Note that + * because C always performs arithmetic operations in double + * precision, the only benefit to using single precision is that + * less storage is required. There is often a noticeable speed + * penalty when using single precision. Sparse internally refers + * to a spREAL as a RealNumber. + * EXPANDABLE + * Setting this compiler flag true (1) makes the matrix + * expandable before it has been factored. If the matrix is + * expandable, then if an element is added that would be + * considered out of bounds in the current matrix, the size of + * the matrix is increased to hold that element. As a result, + * the size of the matrix need not be known before the matrix is + * built. The matrix can be allocated with size zero and + * expanded. + * TRANSLATE + * This option allows the set of external row and column numbers + * to be non-packed. In other words, the row and column numbers + * do not have to be contiguous. The priced paid for this + * flexibility is that when TRANSLATE is set true, the time + * required to initially build the matrix will be greater because + * the external row and column number must be translated into + * internal equivalents. This translation brings about other + * benefits though. First, the spGetElement() and + * spGetAdmittance() routines may be used after the matrix has + * been factored. Further, elements, and even rows and columns, + * may be added to the matrix, and row and columns may be deleted + * from the matrix, after it has been factored. Note that when + * the set of row and column number is not a packed set, neither + * are the RHS and Solution vectors. Thus the size of these + * vectors must be at least as large as the external size, which + * is the value of the largest given row or column numbers. + * INITIALIZE + * Causes the spInitialize(), spGetInitInfo(), and + * spInstallInitInfo() routines to be compiled. These routines + * allow the user to store and read one pointer in each nonzero + * element in the matrix. spInitialize() then calls a user + * specified function for each structural nonzero in the matrix, + * and includes this pointer as well as the external row and + * column numbers as arguments. This allows the user to write + * custom matrix initialization routines. + * DIAGONAL_PIVOTING + * Many matrices, and in particular node- and modified-node + * admittance matrices, tend to be nearly symmetric and nearly + * diagonally dominant. For these matrices, it is a good idea to + * select pivots from the diagonal. With this option enabled, + * this is exactly what happens, though if no satisfactory pivot + * can be found on the diagonal, an off-diagonal pivot will be + * used. If this option is disabled, Sparse does not + * preferentially search the diagonal. Because of this, Sparse + * has a wider variety of pivot candidates available, and so + * presumably fewer fill-ins will be created. However, the + * initial pivot selection process will take considerably longer. + * If working with node admittance matrices, or other matrices + * with a strong diagonal, it is probably best to use + * DIAGONAL_PIVOTING for two reasons. First, accuracy will be + * better because pivots will be chosen from the large diagonal + * elements, thus reducing the chance of growth. Second, a near + * optimal ordering will be chosen quickly. If the class of + * matrices you are working with does not have a strong diagonal, + * do not use DIAGONAL_PIVOTING, but consider using a larger + * threshold. When DIAGONAL_PIVOTING is turned off, the following + * options and constants are not used: MODIFIED_MARKOWITZ, + * MAX_MARKOWITZ_TIES, and TIES_MULTIPLIER. + * MODIFIED_MARKOWITZ + * This specifies that the modified Markowitz method of pivot + * selection is to be used. The modified Markowitz method differs + * from standard Markowitz in two ways. First, under modified + * Markowitz, the search for a pivot can be terminated early if a + * adequate (in terms of sparsity) pivot candidate is found. + * Thus, when using modified Markowitz, the initial factorization + * can be faster, but at the expense of a suboptimal pivoting + * order that may slow subsequent factorizations. The second + * difference is in the way modified Markowitz breaks Markowitz + * ties. When two or more elements are pivot candidates and they + * all have the same Markowitz product, then the tie is broken by + * choosing the element that is best numerically. The numerically + * best element is the one with the largest ratio of its magnitude + * to the magnitude of the largest element in the same column, + * excluding itself. The modified Markowitz method results in + * marginally better accuracy. This option is most appropriate + * for use when working with very large matrices where the initial + * factor time represents an unacceptable burden. [NO] + * DELETE + * This specifies that the spDeleteRowAndCol() routine + * should be compiled. Note that for this routine to be + * compiled, both DELETE and TRANSLATE should be set true. + * STRIP + * This specifies that the spStripFills() routine should be compiled. + * MODIFIED_NODAL + * This specifies that the routine that preorders modified node + * admittance matrices should be compiled. This routine results + * in greater speed and accuracy if used with this type of + * matrix. + * QUAD_ELEMENT + * This specifies that the routines that allow four related + * elements to be entered into the matrix at once should be + * compiled. These elements are usually related to an + * admittance. The routines affected by QUAD_ELEMENT are the + * spGetAdmittance, spGetQuad and spGetOnes routines. + * TRANSPOSE + * This specifies that the routines that solve the matrix as if + * it was transposed should be compiled. These routines are + * useful when performing sensitivity analysis using the adjoint + * method. + * SCALING + * This specifies that the routine that performs scaling on the + * matrix should be complied. Scaling is not strongly + * supported. The routine to scale the matrix is provided, but + * no routines are provided to scale and descale the RHS and + * Solution vectors. It is suggested that if scaling is desired, + * it only be preformed when the pivot order is being chosen [in + * spOrderAndFactor()]. This is the only time scaling has + * an effect. The scaling may then either be removed from the + * solution by the user or the scaled factors may simply be + * thrown away. [NO] + * DOCUMENTATION + * This specifies that routines that are used to document the + * matrix, such as spPrint() and spFileMatrix(), should be + * compiled. + * DETERMINANT + * This specifies that the routine spDeterminant() should be complied. + * STABILITY + * This specifies that spLargestElement() and spRoundoff() should + * be compiled. These routines are used to check the stability (and + * hence the quality of the pivoting) of the factorization by + * computing a bound on the size of the element is the matrix E = + * A - LU. If this bound is very high after applying + * spOrderAndFactor(), then the pivot threshold should be raised. + * If the bound increases greatly after using spFactor(), then the + * matrix should probably be reordered. + * CONDITION + * This specifies that spCondition() and spNorm(), the code that + * computes a good estimate of the condition number of the matrix, + * should be compiled. + * PSEUDOCONDITION + * This specifies that spPseudoCondition(), the code that computes + * a crude and easily fooled indicator of ill-conditioning in the + * matrix, should be compiled. + * MULTIPLICATION + * This specifies that the routines to multiply the unfactored + * matrix by a vector should be compiled. + * DEBUG + * This specifies that additional error checking will be compiled. + * The type of error checked are those that are common when the + * matrix routines are first integrated into a user's program. Once + * the routines have been integrated in and are running smoothly, this + * option should be turned off. + */ + +/* Begin options. */ +#define EXPANDABLE YES +#define TRANSLATE YES +#define INITIALIZE NO +#define DIAGONAL_PIVOTING YES +#define MODIFIED_MARKOWITZ NO +#define DELETE NO +#define STRIP NO +#define MODIFIED_NODAL YES +#define QUAD_ELEMENT NO +#define TRANSPOSE YES +#define SCALING NO +#define DOCUMENTATION YES +#define MULTIPLICATION YES +#define DETERMINANT YES +#define DETERMINANT2 YES +#define STABILITY NO +#define CONDITION NO +#define PSEUDOCONDITION NO +#ifdef HAS_MINDATA +# define DEBUG NO +#else +# define DEBUG YES +#endif + +/* + * The following options affect Sparse exports and so are exported as a + * side effect. For this reason they use the `sp' prefix. The boolean + * constants YES an NO are not defined in spMatrix.h to avoid conflicts + * with user code, so use 0 for NO and 1 for YES. + */ + + + + +/* + * MATRIX CONSTANTS + * + * These constants are used throughout the sparse matrix routines. They + * should be set to suit the type of matrix being solved. Recommendations + * are given in brackets. + * + * Some terminology should be defined. The Markowitz row count is the number + * of non-zero elements in a row excluding the one being considered as pivot. + * There is one Markowitz row count for every row. The Markowitz column + * is defined similarly for columns. The Markowitz product for an element + * is the product of its row and column counts. It is a measure of how much + * work would be required on the next step of the factorization if that + * element were chosen to be pivot. A small Markowitz product is desirable. + * + * >>> Constants descriptions: + * DEFAULT_THRESHOLD + * The relative threshold used if the user enters an invalid + * threshold. Also the threshold used by spFactor() when + * calling spOrderAndFactor(). The default threshold should + * not be less than or equal to zero nor larger than one. [0.001] + * DIAG_PIVOTING_AS_DEFAULT + * This indicates whether spOrderAndFactor() should use diagonal + * pivoting as default. This issue only arises when + * spOrderAndFactor() is called from spFactor(). + * SPACE_FOR_ELEMENTS + * This number multiplied by the size of the matrix equals the number + * of elements for which memory is initially allocated in + * spCreate(). [6] + * SPACE_FOR_FILL_INS + * This number multiplied by the size of the matrix equals the number + * of elements for which memory is initially allocated and specifically + * reserved for fill-ins in spCreate(). [4] + * ELEMENTS_PER_ALLOCATION + * The number of matrix elements requested from the tmalloc utility on + * each call to it. Setting this value greater than 1 reduces the + * amount of overhead spent in this system call. On a virtual memory + * machine, its good to allocate slightly less than a page worth of + * elements at a time (or some multiple thereof). + * [For the VAX, for real only use 41, otherwise use 31] + * MINIMUM_ALLOCATED_SIZE + * The minimum allocated size of a matrix. Note that this does not + * limit the minimum size of a matrix. This just prevents having to + * resize a matrix many times if the matrix is expandable, large and + * allocated with an estimated size of zero. This number should not + * be less than one. + * EXPANSION_FACTOR + * The amount the allocated size of the matrix is increased when it + * is expanded. + * MAX_MARKOWITZ_TIES + * This number is used for two slightly different things, both of which + * relate to the search for the best pivot. First, it is the maximum + * number of elements that are Markowitz tied that will be sifted + * through when trying to find the one that is numerically the best. + * Second, it creates an upper bound on how large a Markowitz product + * can be before it eliminates the possibility of early termination + * of the pivot search. In other words, if the product of the smallest + * Markowitz product yet found and TIES_MULTIPLIER is greater than + * MAX_MARKOWITZ_TIES, then no early termination takes place. + * Set MAX_MARKOWITZ_TIES to some small value if no early termination of + * the pivot search is desired. An array of RealNumbers is allocated + * of size MAX_MARKOWITZ_TIES so it must be positive and shouldn't + * be too large. Active when MODIFIED_MARKOWITZ is 1 (true). [100] + * TIES_MULTIPLIER + * Specifies the number of Markowitz ties that are allowed to occur + * before the search for the pivot is terminated early. Set to some + * large value if no early termination of the pivot search is desired. + * This number is multiplied times the Markowitz product to determine + * how many ties are required for early termination. This means that + * more elements will be searched before early termination if a large + * number of fill-ins could be created by accepting what is currently + * considered the best choice for the pivot. Active when + * MODIFIED_MARKOWITZ is 1 (true). Setting this number to zero + * effectively eliminates all pivoting, which should be avoided. + * This number must be positive. TIES_MULTIPLIER is also used when + * diagonal pivoting breaks down. [5] + * DEFAULT_PARTITION + * Which partition mode is used by spPartition() as default. + * Possibilities include + * spDIRECT_PARTITION -- each row used direct addressing, best for + * a few relatively dense matrices. + * spINDIRECT_PARTITION -- each row used indirect addressing, best + * for a few very sparse matrices. + * spAUTO_PARTITION -- direct or indirect addressing is chosen on + * a row-by-row basis, carries a large overhead, but speeds up + * both dense and sparse matrices, best if there is a large + * number of matrices that can use the same ordering. + */ + +/* Begin constants. */ +#define DEFAULT_THRESHOLD 1.0e-3 +#define DIAG_PIVOTING_AS_DEFAULT YES +#define SPACE_FOR_ELEMENTS 6 +#define SPACE_FOR_FILL_INS 4 +#define ELEMENTS_PER_ALLOCATION 31 +#define MINIMUM_ALLOCATED_SIZE 6 +#define EXPANSION_FACTOR 1.5 +#define MAX_MARKOWITZ_TIES 100 +#define TIES_MULTIPLIER 5 +#define DEFAULT_PARTITION spAUTO_PARTITION + + + + + + +/* + * PRINTER WIDTH + * + * This macro characterize the printer for the spPrint() routine. + * + * >>> Macros: + * PRINTER_WIDTH + * The number of characters per page width. Set to 80 for terminal, + * 132 for line printer. + */ + +/* Begin printer constants. */ +#define PRINTER_WIDTH 80 + + + + + + +/* + * MACHINE CONSTANTS + * + * These numbers must be updated when the program is ported to a new machine. + */ + +/* Begin machine constants. */ + +/* + * Grab from Spice include files + */ + +#include "ngspice.h" +#define MACHINE_RESOLUTION DBL_EPSILON +#define LARGEST_REAL DBL_MAX +#define SMALLEST_REAL DBL_MIN +#define LARGEST_SHORT_INTEGER SHRT_MAX +#define LARGEST_LONG_INTEGER LONG_MAX + + +/* + * ANNOTATION + * + * This macro changes the amount of annotation produced by the matrix + * routines. The annotation is used as a debugging aid. Change the number + * associated with ANNOTATE to change the amount of annotation produced by + * the program. + */ + +/* Begin annotation definitions. */ +#define ANNOTATE NONE + +#define NONE 0 +#define ON_STRANGE_BEHAVIOR 1 +#define FULL 2 + +#endif /* spINSIDE_SPARSE */ +#endif /* spCONFIG_DEFS */ 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/getopt.c b/src/misc/getopt.c new file mode 100644 index 000000000..964189d2d --- /dev/null +++ b/src/misc/getopt.c @@ -0,0 +1,748 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +#define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifndef __STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +#include +#endif /* GNU C library. */ + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg = NULL; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* XXX 1003.2 says this must be 1 before any call. */ +int optind = 0; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return EOF with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +#include +#define my_index strchr +#else + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +char *getenv (); + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +#ifndef __STDC__ +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +#endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +static const char * +_getopt_initialize (optstring) + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind = 1; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns `EOF'. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + optarg = NULL; + + if (optind == 0) + optstring = _getopt_initialize (optstring); + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc + && (argv[optind][0] != '-' || argv[optind][1] == '\0')) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return EOF; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) + { + if (ordering == REQUIRE_ORDER) + return EOF; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if (nameend - nextchar == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, "%s: option `%s' is ambiguous\n", + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[optind - 1][0], pfound->name); + } + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, "%s: option `%s' requires an argument\n", + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, "%s: unrecognized option `--%s'\n", + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, "%s: unrecognized option `%c%s'\n", + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (opterr) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); + else + fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c); + } + optopt = c; + return '?'; + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: option requires an argument -- %c\n", + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == EOF) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/src/misc/getopt.h b/src/misc/getopt.h new file mode 100644 index 000000000..45541f5ac --- /dev/null +++ b/src/misc/getopt.h @@ -0,0 +1,129 @@ +/* Declarations for getopt. + Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _GETOPT_H +#define _GETOPT_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +#if __STDC__ + const char *name; +#else + char *name; +#endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +#if __STDC__ +#if defined(__GNU_LIBRARY__) +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int argc, char *const *argv, const char *shortopts); +#else /* not __GNU_LIBRARY__ */ +extern int getopt (); +#endif /* not __GNU_LIBRARY__ */ +extern int getopt_long (int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); +#else /* not __STDC__ */ +extern int getopt (); +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +#endif /* not __STDC__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* _GETOPT_H */ diff --git a/src/misc/getopt1.c b/src/misc/getopt1.c new file mode 100644 index 000000000..725c653bb --- /dev/null +++ b/src/misc/getopt1.c @@ -0,0 +1,180 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "getopt.h" + +#ifndef __STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include +#else +char *getenv (); +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* _LIBC or not __GNU_LIBRARY__. */ + +#ifdef TEST + +#include + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == EOF) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ 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/stringutil.h b/src/misc/stringutil.h new file mode 100644 index 000000000..350c2fdd3 --- /dev/null +++ b/src/misc/stringutil.h @@ -0,0 +1,33 @@ +/************* + * Header file for string.c + * 1999 E. Rouat + ************/ + +#ifndef STRING_H_INCLUDED +#define STRING_H_INCLUDED + +int prefix(register char *p, register char *s); +char * copy(char *str); +int substring(register char *sub, register char *str); +void appendc(char *s, char c); +int scannum(char *str); +int cieq(register char *p, register char *s); +int ciprefix(register char *p, register char *s); +void strtolower(char *str); +char * gettok(char **s); + +#if !defined(HAVE_INDEX) && !defined(HAVE_STRCHR) + +char * index(register char *s, register char c); +char * rindex(register char *s,register char c ); + +#endif /* !defined(HAVE_INDEX) && !defined(HAVE_STRCHR) */ + +#ifndef HAVE_BCOPY + +void bcopy(register char *from, register char *to, register int num); +int bzero(register char *ptr, register int num); + +#endif /* HAVE_BCOPY */ + +#endif diff --git a/src/misc/terminal.c b/src/misc/terminal.c new file mode 100644 index 000000000..e69de29bb diff --git a/src/misc/terminal.h b/src/misc/terminal.h new file mode 100644 index 000000000..e69de29bb 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/misc/wlist.c b/src/misc/wlist.c new file mode 100644 index 000000000..f52be138e --- /dev/null +++ b/src/misc/wlist.c @@ -0,0 +1,295 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* Wordlist manipulation stuff. */ + +#include +#include +#include +#include + + +/* Determine the length of a word list. */ +int +wl_length(wordlist *wlist) +{ + int i = 0; + wordlist *wl; + + for (wl = wlist; wl; wl = wl->wl_next) + i++; + return (i); +} + + +/* Free the storage used by a word list. */ +void +wl_free(wordlist *wlist) +{ + wordlist *wl, *nw; + + for (wl = wlist; wl; wl = nw) { + nw = wl->wl_next; + tfree(wl->wl_word); + tfree(wl); + } + return; +} + + +/* Copy a wordlist and the words. */ +wordlist * +wl_copy(wordlist *wlist) +{ + wordlist *wl, *nwl = NULL, *w = NULL; + + for (wl = wlist; wl; wl = wl->wl_next) { + if (nwl == NULL) { + nwl = w = alloc(struct wordlist); + w->wl_prev = NULL; + w->wl_next = NULL; + } else { + w->wl_next = alloc(struct wordlist); + w->wl_next->wl_prev = w; + w = w->wl_next; + w->wl_next = NULL; + } + w->wl_word = copy(wl->wl_word); + } + return (nwl); +} + + +/* Substitute a wordlist for one element of a wordlist, and return a + * pointer to the last element of the inserted list. */ +wordlist * +wl_splice(wordlist *elt, wordlist *list) +{ + + if (list) + list->wl_prev = elt->wl_prev; + if (elt->wl_prev) + elt->wl_prev->wl_next = list; + if (list) { + while (list->wl_next) + list = list->wl_next; + list->wl_next = elt->wl_next; + } + if (elt->wl_next) + elt->wl_next->wl_prev = list; + tfree(elt->wl_word); + tfree(elt); + return (list); +} + + + +static void +printword(char *string, FILE *fp) +{ + char *s; + + if (string) + for (s = string; *s; s++) + putc((strip(*s)), fp); + return; +} + + +/* Print a word list. (No \n at the end...) */ +void +wl_print(wordlist *wlist, FILE *fp) +{ + wordlist *wl; + + for (wl = wlist; wl; wl = wl->wl_next) { + printword(wl->wl_word, fp); + if (wl->wl_next) + putc(' ', fp); + } + return; +} + + +/* Turn an array of char *'s into a wordlist. */ +wordlist * +wl_build(char **v) +{ + wordlist *wlist = NULL; + wordlist *wl = NULL; + wordlist *cwl; + + while (*v) { + cwl = alloc(struct wordlist); + cwl->wl_prev = wl; + if (wl) + wl->wl_next = cwl; + else { + wlist = cwl; + cwl->wl_next = NULL; + } + cwl->wl_word = copy(*v); + wl = cwl; + v++; + } + return (wlist); +} + +char ** +wl_mkvec(wordlist *wl) +{ + int len, i; + char **v; + + len = wl_length(wl); + v = (char **) tmalloc((len + 1) * sizeof (char **)); + for (i = 0; i < len; i++) { + v[i] = copy(wl->wl_word); + wl = wl->wl_next; + } + v[i] = NULL; + return (v); +} + + +/* Nconc two wordlists together. */ +wordlist * +wl_append(wordlist *wlist, wordlist *nwl) +{ + wordlist *wl; + if (wlist == NULL) + return (nwl); + if (nwl == NULL) + return (wlist); + for (wl = wlist; wl->wl_next; wl = wl->wl_next); + wl->wl_next = nwl; + nwl->wl_prev = wl; + return (wlist); +} + + +/* Reverse a word list. */ +wordlist * +wl_reverse(wordlist *wl) +{ + wordlist *w, *t; + + for (w = wl; ; w = t) { + t = w->wl_next; + w->wl_next = w->wl_prev; + w->wl_prev = t; + if (t == NULL) + break; + } + return (w); +} + + +/* Convert a wordlist into a string. */ +char * +wl_flatten(wordlist *wl) +{ + char *buf; + wordlist *tw; + int i = 0; + + for (tw = wl; tw; tw = tw->wl_next) + i += strlen(tw->wl_word) + 1; + buf = tmalloc(i + 1); + *buf = 0; + + while (wl != NULL) { + (void) strcat(buf, wl->wl_word); + if (wl->wl_next) + (void) strcat(buf, " "); + wl = wl->wl_next; + } + return (buf); +} + + +/* Return the nth element of a wordlist, or the last one if n is too + * big. Numbering starts at 0... */ +wordlist * +wl_nthelem(int i, wordlist *wl) +{ + wordlist *ww = wl; + + while ((i-- > 0) && ww->wl_next) + ww = ww->wl_next; + return (ww); +} + + + +static int +wlcomp(const void *a, const void *b) +{ + char **s = (char **) a; + char **t = (char **) b; + return (strcmp(*s, *t)); +} + + +void +wl_sort(wordlist *wl) +{ + int i = 0; + wordlist *ww = wl; + char **stuff; + + for (i = 0; ww; i++) + ww = ww->wl_next; + if (i < 2) + return; + stuff = (char **) tmalloc(i * sizeof (char *)); + for (i = 0, ww = wl; ww; i++, ww = ww->wl_next) + stuff[i] = ww->wl_word; + qsort((char *) stuff, i, sizeof (char *), wlcomp); + for (i = 0, ww = wl; ww; i++, ww = ww->wl_next) + ww->wl_word = stuff[i]; + tfree(stuff); + return; +} + + +/* Return a range of wordlist elements... */ +wordlist * +wl_range(wordlist *wl, int low, int up) +{ + int i; + wordlist *tt; + bool rev = FALSE; + + if (low > up) { + i = up; + up = low; + low = i; + rev = TRUE; + } + up -= low; + while (wl && (low > 0)) { + tt = wl->wl_next; + tfree(wl->wl_word); + tfree(wl); + wl = tt; + if (wl) + wl->wl_prev = NULL; + low--; + } + tt = wl; + while (tt && (up > 0)) { + tt = tt->wl_next; + up--; + } + if (tt && tt->wl_next) { + wl_free(tt->wl_next); + tt->wl_next = NULL; + } + if (rev) + wl = wl_reverse(wl); + return (wl); +} + diff --git a/src/nghelp.c b/src/nghelp.c new file mode 100644 index 000000000..1fdc3b195 --- /dev/null +++ b/src/nghelp.c @@ -0,0 +1,114 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* + * The main routine for the help system in stand-alone mode. + */ + +#include +#include "ngspice.h" +#include "cpdefs.h" +#include "hlpdefs.h" + +#include "frontend/variable.h" + +#ifndef X_DISPLAY_MISSING +Widget toplevel; +#endif + +FILE *cp_in, *cp_out, *cp_err; +char *Spice_Exec_Dir = NGSPICEBINDIR; +char *Spice_Lib_Dir = NGSPICEDATADIR; +char *Def_Editor = "vi"; +int AsciiRawFile = 0; + +char *Bug_Addr = ""; +char *Spice_Host = ""; +char *Spiced_Log = ""; + +/* dummy declaration so CP.a doesn't pull in lexical.o and other objects */ +bool cp_interactive = FALSE; + +char *hlp_filelist[] = { "ngspice", 0 }; + +int +main(int ac, char **av) +{ + wordlist *wl = NULL; + +#ifndef X_DISPLAY_MISSING + char *displayname; + /* grrr, Xtk forced contortions */ + char *argv[2]; + int argc = 2; + char buf[512]; +#endif + + ivars( ); + + cp_in = stdin; + cp_out = stdout; + cp_err = stderr; + +#ifndef X_DISPLAY_MISSING + + if (cp_getvar("display", VT_STRING, buf)) { + displayname = buf; + } else if (!(displayname = getenv("DISPLAY"))) { + fprintf(stderr, "Can't open X display."); + goto out; + } + + argv[0] = "nutmeg"; + argv[1] = displayname; + /* initialize X toolkit */ + toplevel = XtInitialize("nutmeg", "Nutmeg", NULL, 0, &argc, argv); + +#endif + +out: + if (ac > 1) + wl = wl_build(av + 1); + hlp_main(Help_Path, wl); + +#ifndef X_DISPLAY_MISSING + if (hlp_usex) { + printf("Hit control-C when done.\n"); /* sigh */ + XtMainLoop(); + } +#endif + + exit(EXIT_NORMAL); +} + +void +fatal(char *s) +{ + fprintf(stderr, "fatal error: %s\n", s); + exit(1); +} + +/* There is a conflict witj another cp_printword in cp/quote.c +static void +cp_printword(s) + char *s; +{ + printf("%s", s); + return; +} + +*/ + +bool +cp_getvar(char *n, int t, void *r) +{ + return (FALSE); +} + +char * +cp_tildexpand(char *s) +{ + return tilde_expand(s); +} diff --git a/src/ngmultidec.c b/src/ngmultidec.c new file mode 100644 index 000000000..b8e8e0744 --- /dev/null +++ b/src/ngmultidec.c @@ -0,0 +1,420 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1990 Jaijeet Roychowdury +**********/ + +#include "ngspice.h" +#include +#include +#include "spmatrix.h" + +#define THRSH 0.01 +#define ABS_THRSH 0 +#define DIAG_PIVOTING 1 + +#undef DEBUG_LEVEL1 + + +extern void usage(); +extern void comments(); +extern double phi(); + +int + main (argc, argv) + int argc; + char **argv; +{ + int ch; + int errflg=0,i,j; + double l,c,ctot,r=0.0,g=0.0,k=0.0,lm=0.0,cm=0.0,len; + unsigned gotl=0,gotc=0,gotr=0,gotg=0,gotk=0,gotcm=0,gotlen=0; + unsigned gotname=0, gotnum=0; + char *name; + double **matrix, **inverse; + double *tpeigenvalues, *gammaj; + char *options; + int num, node; + char **pname, *s; + int use_opt; + char *optarg; + + pname = argv; + argv++; + argc--; + + ch = 0; + while (argc > 0) { + s = *argv++; + argc--; + while ((ch = *s++)) { + if (*s) + optarg = s; + else if (argc) + optarg = *argv; + else + optarg = NULL; + use_opt = 0; + + switch (ch) { + case 'o': + name = (char *) tmalloc((unsigned) (strlen(optarg)*sizeof(char))); + (void) strcpy(name,optarg); + gotname=1; + use_opt = 1; + break; + case 'l': + sscanf(optarg,"%lf",&l); + gotl=1; + use_opt = 1; + break; + case 'c': + sscanf(optarg,"%lf",&c); + gotc=1; + use_opt = 1; + break; + case 'r': + sscanf(optarg,"%lf",&r); + use_opt = 1; + gotr=1; + break; + case 'g': + sscanf(optarg,"%lf",&g); + use_opt = 1; + gotg=1; + break; + case 'k': + sscanf(optarg,"%lf",&k); + use_opt = 1; + gotk=1; + break; + case 'x': + sscanf(optarg,"%lf",&cm); + use_opt = 1; + gotcm=1; + break; + case 'L': + sscanf(optarg,"%lf",&len); + use_opt = 1; + gotlen=1; + break; + case 'n': + sscanf(optarg,"%d",&num); + use_opt = 1; + gotnum=1; + break; + case 'u': + usage(pname); + exit(1); + break; + case '-': + break; + default: + usage(pname); + exit(2); + break; + } + if (use_opt) { + if (optarg == s) + s += strlen(s); + else if (optarg) { + argc--; + argv++; + } + } + } + } + + if (errflg) { + usage(argv); + exit (2); + } + + if (gotl + gotc + gotname + gotnum + gotlen < 5) { + fprintf(stderr,"l, c, model_name, number_of_conductors and length must be specified.\n"); + fprintf(stderr,"%s -u for details.\n",pname[0]); + fflush(stdout); + exit(1); + } + + if ( (k<0.0?-k:k) >=1.0 ) { + fprintf(stderr,"Error: |k| must be less than 1.0\n"); + fflush(stderr); + exit(1); + } + + if (num == 1) { + fprintf(stdout,"* single conductor line\n"); + fflush(stdout); + exit(1); + } + + lm = l*k; + switch(num) { + + case 1: ctot = c; break; + case 2: ctot = c + cm; break; + default: ctot = c + 2*cm; break; + } + + comments(r,l,g,c,ctot,cm,lm,k,name,num,len); + + matrix = (double **) tmalloc((unsigned) (sizeof(double*)*(num+1))); + inverse = (double **) tmalloc((unsigned) (sizeof(double*)*(num+1))); + tpeigenvalues = (double *) tmalloc((unsigned) (sizeof(double)*(num+1))); + + for (i=1;i<=num;i++) { + matrix[i] = (double *) tmalloc((unsigned) (sizeof(double)*(num+1))); + inverse[i] = (double *) tmalloc((unsigned) (sizeof(double)*(num+1))); + } + + for (i=1;i<=num;i++) { + tpeigenvalues[i] = -2.0 * cos(M_PI*i/(num+1)); + } + + for (i=1;i<=num;i++) { + for (j=1;j<=num;j++) { + matrix[i][j] = phi(i-1,tpeigenvalues[j]); + } + } + gammaj = (double *) tmalloc((unsigned) (sizeof(double)*(num+1))); + + for (j=1;j<=num;j++) { + gammaj[j] = 0.0; + for (i=1;i<=num;i++) { + gammaj[j] += matrix[i][j] * matrix[i][j]; + } + gammaj[j] = sqrt(gammaj[j]); + } + + for (j=1;j<=num;j++) { + for (i=1;i<=num; i++) { + matrix[i][j] /= gammaj[j]; + } + } + + tfree(gammaj); + + /* matrix = M set up */ + + { + char *othermatrix; + double *rhs, *solution; + double *irhs, *isolution; + int errflg, err, singular_row, singular_col; + double *elptr; + + rhs = (double *) tmalloc((unsigned) (sizeof(double)*(num+1))); + irhs = (double *) tmalloc((unsigned) (sizeof(double)*(num+1))); + solution = (double *) tmalloc((unsigned) (sizeof(double)*(num+1))); + isolution = (double *) tmalloc((unsigned) (sizeof(double)*(num+1))); + + othermatrix = spCreate(num,0,&errflg); + + for (i=1;i<=num;i++) { + for (j=1; j<=num; j++) { + elptr = spGetElement(othermatrix,i,j); + *elptr = matrix[i][j]; + } + } + +#ifdef DEBUG_LEVEL1 + (void) spPrint(othermatrix,0,1,0); +#endif + + for (i=1;i<=num;i++) rhs[i] = 0.0; + rhs[1]=1.0; + + err = + spOrderAndFactor(othermatrix,rhs,THRSH,ABS_THRSH,DIAG_PIVOTING); + + spErrorMessage(othermatrix,stderr,NULL); + + switch(err) { + + case spNO_MEMORY: + fprintf(stderr,"No memory in spOrderAndFactor\n"); + fflush(stderr); + exit(1); + case spSINGULAR: + (void) + spWhereSingular(othermatrix,&singular_row,&singular_col); + fprintf(stderr,"Singular matrix: problem in row %d and col %d\n", singular_row, singular_col); + fflush(stderr); + exit(1); + default: break; + } + + for (i=1;i<=num;i++) { + for (j=1;j<=num;j++) { + rhs[j] = (j==i?1.0:0.0); + irhs[j] = 0.0; + } + (void) spSolveTransposed(othermatrix,rhs,solution, irhs, isolution); + for (j=1;j<=num;j++) { + inverse[i][j] = solution[j]; + } + } + + tfree(rhs); + tfree(solution); + } + + /* inverse = M^{-1} set up */ + + fprintf(stdout,"\n"); + fprintf(stdout,"* Lossy line models\n"); + + options = (char *) tmalloc((unsigned) 256); + (void) strcpy(options,"rel=1.2 nocontrol"); + for (i=1;i<=num;i++) { + fprintf(stdout,".model mod%d_%s ltra %s r=%0.12g l=%0.12g g=%0.12g c=%0.12g len=%0.12g\n", + i,name,options,r,l+tpeigenvalues[i]*lm,g,ctot-tpeigenvalues[i]*cm,len); + /*i,name,options,r,l+tpeigenvalues[i]*lm,g,ctot+tpeigenvalues[i]*cm,len);*/ + } + + + fprintf(stdout,"\n"); + fprintf(stdout,"* subcircuit m_%s - modal transformation network for %s\n",name,name); + fprintf(stdout,".subckt m_%s", name); + for (i=1;i<= 2*num; i++) { + fprintf(stdout," %d",i); + } + fprintf(stdout,"\n"); + for (j=1;j<=num;j++) fprintf(stdout,"v%d %d 0 0v\n",j,j+2*num); + + for (j=1;j<=num;j++) { + for (i=1; i<=num; i++) { + fprintf(stdout,"f%d 0 %d v%d %0.12g\n", + (j-1)*num+i,num+j,i,inverse[j][i]); + } + } + + node = 3*num+1; + for (j=1;j<=num;j++) { + fprintf(stdout,"e%d %d %d %d 0 %0.12g\n", (j-1)*num+1, + node, 2*num+j, num+1, matrix[j][1]); + node++; + for (i=2; i -c\n",argv[0]); +fprintf(stderr," -r -g \n"); +fprintf(stderr," -k \n"); +fprintf(stderr," -x -o \n"); +fprintf(stderr," -n -L -u\n"); +fprintf(stderr,"Example: %s -n4 -l9e-9 -c20e-12 -r5.3 -x5e-12 -k0.7 -otest -L5.4\n\n",argv[0]); + +fprintf(stderr,"See \"Efficient Transient Simulation of Lossy Interconnect\",\n"); +fprintf(stderr,"J.S. Roychowdhury and D.O. Pederson, Proc. DAC 91 for details\n"); +fprintf(stderr,"\n"); +fflush(stderr); +} + +void +comments(r,l,g,c,ctot,cm,lm,k,name,num,len) +double r,l,g,c,ctot,cm,lm,k,len; +char *name; +int num; +{ + +fprintf(stdout,"* Subcircuit %s\n",name); +fprintf(stdout,"* %s is a subcircuit that models a %d-conductor transmission line with\n",name,num); +fprintf(stdout,"* the following parameters: l=%g, c=%g, r=%g, g=%g,\n",l,c,r,g); +fprintf(stdout,"* inductive_coeff_of_coupling k=%g, inter-line capacitance cm=%g,\n",k,cm); +fprintf(stdout,"* length=%g. Derived parameters are: lm=%g, ctot=%g.\n",len,lm,ctot); +fprintf(stdout,"* \n"); +fprintf(stdout,"* It is important to note that the model is a simplified one - the\n"); +fprintf(stdout,"* following assumptions are made: 1. The self-inductance l, the\n"); +fprintf(stdout,"* self-capacitance ctot (note: not c), the series resistance r and the\n"); +fprintf(stdout,"* parallel capacitance g are the same for all lines, and 2. Each line\n"); +fprintf(stdout,"* is coupled only to the two lines adjacent to it, with the same\n"); +fprintf(stdout,"* coupling parameters cm and lm. The first assumption implies that edge\n"); +fprintf(stdout,"* effects have to be neglected. The utility of these assumptions is\n"); +fprintf(stdout,"* that they make the sL+R and sC+G matrices symmetric, tridiagonal and\n"); +fprintf(stdout,"* Toeplitz, with useful consequences (see \"Efficient Transient\n"); +fprintf(stdout,"* Simulation of Lossy Interconnect\", by J.S. Roychowdhury and\n"); +fprintf(stdout,"* D.O Pederson, Proc. DAC 91).\n\n"); +fprintf(stdout,"* It may be noted that a symmetric two-conductor line is\n"); +fprintf(stdout,"* represented accurately by this model.\n\n"); +fprintf(stdout,"* Subckt node convention:\n"); +fprintf(stdout,"* \n"); +fprintf(stdout,"* |--------------------------|\n"); +fprintf(stdout,"* 1-----| |-----n+1\n"); +fprintf(stdout,"* 2-----| |-----n+2\n"); +fprintf(stdout,"* : | n-wire multiconductor | :\n"); +fprintf(stdout,"* : | line | :\n"); +fprintf(stdout,"* n-1-----|(node 0=common gnd plane) |-----2n-1\n"); +fprintf(stdout,"* n-----| |-----2n\n"); +fprintf(stdout,"* |--------------------------|\n\n"); +fflush(stdout); +} + +double +phi(i,arg) + int i; + double arg; +{ + double rval; + + switch (i) { + + case 0: + rval = 1.0; + break; + case 1: + rval = arg; + break; + default: + rval = arg*phi(i-1,arg) - phi(i-2,arg); + } + return rval; +} diff --git a/src/ngnutmeg.c b/src/ngnutmeg.c new file mode 100644 index 000000000..51b90b6df --- /dev/null +++ b/src/ngnutmeg.c @@ -0,0 +1,64 @@ +/* Configuration file for nutmeg */ +#include + +#include "conf.h" + + +/* + * Devices + */ + +#define DEVICES_USED "" +#define ANALYSES_USED "" + +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +**********/ + +#include "ngspice.h" + +#define CONFIG +#include +#include "ifsim.h" +#include "suffix.h" + +IFsimulator SIMinfo = { + "nutmeg", /* my name */ + "data analysis and manipulation program", /* more about me */ + Spice_Version, /* my version */ + NULL, /* newCircuit function */ + NULL, /* deleteCircuit function */ + NULL, /* newNode function */ /* NEEDED */ + NULL, /* groundNode function */ + NULL, /* bindNode function */ + NULL, /* findNode function */ /* NEEDED */ + NULL, /* instToNode function */ /* NEEDED */ + NULL, /* setNodeParm function */ /* NEEDED */ + NULL, /* askNodeQuest function */ /* NEEDED */ + NULL, /* deleteNode function */ /* NEEDED */ + NULL, /* newInstance function */ + NULL, /* setInstanceParm function */ + NULL, /* askInstanceQuest function */ + NULL, /* findInstance funciton */ + NULL, /* deleteInstance function */ /* to be added later */ + NULL, /* newModel function */ + NULL, /* setModelParm function */ + NULL, /* askModelQuest function */ + NULL, /* findModel function */ + NULL, /* deleteModel function */ /* to be added later */ + NULL, /* newTask function */ + NULL, /* newAnalysis function */ + NULL, /* setAnalysisParm function */ + NULL, /* askAnalysisQeust function */ + NULL, /* findAnalysis function */ + NULL, /* findTask function */ + NULL, /* deleteTask function */ + NULL, /* doAnalyses function */ + NULL, /* non-convergence message function */ + 0, + NULL, + 0, + NULL, + 0, + NULL, +}; diff --git a/src/ngproc2mod.c b/src/ngproc2mod.c new file mode 100644 index 000000000..a49992cc8 --- /dev/null +++ b/src/ngproc2mod.c @@ -0,0 +1,339 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +**********/ +/* convert .process file to set of .model cards */ + +#include +#include "ngspice.h" +#include +#include "inpdefs.h" +#include "suffix.h" + + +void exit(); + +#ifdef __STDC__ +void getdata(double*,int,int); +#else /* stdc */ +void getdata(); +#endif /* stdc */ + +typedef struct snmod { + struct snmod *nnext; + char *nname; + double nparms[69]; +} nmod; +typedef struct spmod { + struct spmod *pnext; + char *pname; + double pparms[69]; +} pmod; +typedef struct sdmod { + struct sdmod *dnext; + char *dname; + double dparms[10]; +} dmod; +typedef struct symod { + struct symod *ynext; + char *yname; + double yparms[10]; +} ymod; +typedef struct smmod { + struct smmod *mnext; + char *mname; + double mparms[10]; +} mmod; + +FILE *m = NULL; +FILE *p = NULL; +char *dataline; + + +int +main(void) { + char *typeline; + char *prname; + nmod *nlist=NULL,*ncur; + pmod *plist=NULL,*pcur; + dmod *dlist=NULL,*dcur; + ymod *ylist=NULL,*ycur; + mmod *mlist=NULL,*mcur; + char *filename; + + + filename = (char *)tmalloc(1024); + typeline = (char *)tmalloc(1024); + dataline = (char *)tmalloc(1024); + + while(p == NULL) { + printf("name of process file (input): "); + if(scanf("%s",filename)!=1) { + printf("error reading process file name\n"); + exit(1); + } + p = fopen(filename,"r"); + if(p==NULL) { + printf("can't open %s:",filename); + perror(""); + } + } + while(m == NULL) { + printf("name of .model file (output): "); + if(scanf("%s",filename)!=1) { + printf("error reading model file name\n"); + exit(1); + } + m = fopen(filename,"w"); + if(m==NULL) { + printf("can't open %s:",filename); + perror(""); + } + } + printf("process name : "); + if(scanf("%s",filename)!=1) { + printf("error reading process name\n"); + exit(1); + } + prname = filename; + if(fgets(typeline,1023,p)==NULL) { + printf("error reading input description line\n"); + exit(1); + } + INPcaseFix(typeline); + while(1) { + while(*typeline == ' ' || *typeline == '\t' || *typeline == ',' || + *typeline == '\n' ) { + typeline ++; + } + if(*typeline == 0) break; + if(strncmp("nm",typeline,2) == 0) { + ncur = (nmod *)tmalloc(sizeof(nmod)); + ncur->nnext = NULL; + ncur->nname = typeline; + *(typeline+3) = (char)NULL; + typeline += 4; + getdata(ncur->nparms,69,3); + ncur->nnext = nlist; + nlist = ncur; + } else if(strncmp("pm",typeline,2) == 0) { + pcur = (pmod *)tmalloc(sizeof(pmod)); + pcur->pnext = NULL; + pcur->pname = typeline; + *(typeline+3) = (char)NULL; + typeline += 4; + getdata(pcur->pparms,69,3); + pcur->pnext = plist; + plist = pcur; + } else if(strncmp("py",typeline,2) == 0) { + ycur = (ymod *)tmalloc(sizeof(ymod)); + ycur->ynext = NULL; + ycur->yname = typeline; + *(typeline+3) = (char)NULL; + typeline += 4; + getdata(ycur->yparms,10,5); + ycur->ynext = ylist; + ylist = ycur; + } else if(strncmp("du",typeline,2) == 0) { + dcur = (dmod *)tmalloc(sizeof(dmod)); + dcur->dnext = NULL; + dcur->dname = typeline; + *(typeline+3) = (char)NULL; + typeline += 4; + getdata(dcur->dparms,10,5); + dcur->dnext = dlist; + dlist = dcur; + } else if(strncmp("ml",typeline,2) == 0) { + mcur = (mmod *)tmalloc(sizeof(mmod)); + mcur->mnext = NULL; + mcur->mname = typeline; + *(typeline+3) = (char)NULL; + typeline += 4; + getdata(mcur->mparms,10,5); + mcur->mnext = mlist; + mlist = mcur; + } else { + printf(" illegal header line in process file: run terminated\n"); + printf(" error occurred while parsing %s\n",typeline); + exit(1); + } + } + for(dcur=dlist;dcur;dcur=dcur->dnext) { + fprintf(m,".model %s_%s r rsh = %g defw = %g narrow = %g\n", + prname,dcur->dname,dcur->dparms[0],dcur->dparms[8],dcur->dparms[9]); + fprintf(m,".model %s_%s c cj = %g cjsw = %g defw = %g narrow = %g\n", + prname,dcur->dname,dcur->dparms[1],dcur->dparms[2],dcur->dparms[8], + dcur->dparms[9]); + } + for(ycur=ylist;ycur;ycur=ycur->ynext) { + fprintf(m,".model %s_%s r rsh = %g defw = %g narrow = %g\n", + prname,ycur->yname,ycur->yparms[0],ycur->yparms[8],ycur->yparms[9]); + fprintf(m,".model %s_%s c cj = %g cjsw = %g defw = %g narrow = %g\n", + prname,ycur->yname,ycur->yparms[1],ycur->yparms[2],ycur->yparms[8], + ycur->yparms[9]); + } + for(mcur=mlist;mcur;mcur=mcur->mnext) { + fprintf(m,".model %s_%s r rsh = %g defw = %g narrow = %g\n", + prname,mcur->mname,mcur->mparms[0],mcur->mparms[8],mcur->mparms[9]); + fprintf(m,".model %s_%s c cj = %g cjsw = %g defw = %g narrow = %g\n", + prname,mcur->mname,mcur->mparms[1],mcur->mparms[2],mcur->mparms[8], + mcur->mparms[9]); + } + for(pcur=plist;pcur;pcur=pcur->pnext) { + for(dcur=dlist;dcur;dcur=dcur->dnext) { + fprintf(m,".model %s_%s_%s pmos level=4\n",prname,pcur->pname, + dcur->dname); + fprintf(m,"+ vfb = %g lvfb = %g wvfb = %g\n", + pcur->pparms[0],pcur->pparms[1],pcur->pparms[2]); + fprintf(m,"+ phi = %g lphi = %g wphi = %g\n", + pcur->pparms[3],pcur->pparms[4],pcur->pparms[5]); + fprintf(m,"+ k1 = %g lk1 = %g wk1 = %g\n", + pcur->pparms[6],pcur->pparms[7],pcur->pparms[8]); + fprintf(m,"+ k2 = %g lk2 = %g wk2 = %g\n", + pcur->pparms[9],pcur->pparms[10],pcur->pparms[11]); + fprintf(m,"+ eta = %g leta = %g weta = %g\n", + pcur->pparms[12],pcur->pparms[13],pcur->pparms[14]); + fprintf(m,"+ muz = %g dl = %g dw = %g\n", + pcur->pparms[15],pcur->pparms[16],pcur->pparms[17]); + fprintf(m,"+ u0 = %g lu0 = %g wu0 = %g\n", + pcur->pparms[18],pcur->pparms[19],pcur->pparms[20]); + fprintf(m,"+ u1 = %g lu1 = %g wu1 = %g\n", + pcur->pparms[21],pcur->pparms[22],pcur->pparms[23]); + fprintf(m,"+ x2mz = %g lx2mz = %g wx2mz = %g\n", + pcur->pparms[24],pcur->pparms[25],pcur->pparms[26]); + fprintf(m,"+ x2e = %g lx2e = %g wx2e = %g\n", + pcur->pparms[27],pcur->pparms[28],pcur->pparms[29]); + fprintf(m,"+ x3e = %g lx3e = %g wx3e = %g\n", + pcur->pparms[30],pcur->pparms[31],pcur->pparms[32]); + fprintf(m,"+ x2u0 = %g lx2u0 = %g wx2u0 = %g\n", + pcur->pparms[33],pcur->pparms[34],pcur->pparms[35]); + fprintf(m,"+ x2u1 = %g lx2u1 = %g wx2u1 = %g\n", + pcur->pparms[36],pcur->pparms[37],pcur->pparms[38]); + fprintf(m,"+ mus = %g lmus = %g wmus = %g\n", + pcur->pparms[39],pcur->pparms[40],pcur->pparms[41]); + fprintf(m,"+ x2ms = %g lx2ms = %g wx2ms = %g\n", + pcur->pparms[42],pcur->pparms[43],pcur->pparms[44]); + fprintf(m,"+ x3ms = %g lx3ms = %g wx3ms = %g\n", + pcur->pparms[45],pcur->pparms[46],pcur->pparms[47]); + fprintf(m,"+ x3u1 = %g lx3u1 = %g wx3u1 = %g\n", + pcur->pparms[48],pcur->pparms[49],pcur->pparms[50]); + fprintf(m,"+ tox = %g temp = %g vdd = %g\n", + pcur->pparms[51],pcur->pparms[52],pcur->pparms[53]); + fprintf(m,"+ cgdo = %g cgso = %g cgbo = %g\n", + pcur->pparms[54],pcur->pparms[55],pcur->pparms[56]); + fprintf(m,"+ xpart = %g \n", + pcur->pparms[57]); + fprintf(m,"+ n0 = %g ln0 = %g wn0 = %g\n", + pcur->pparms[60],pcur->pparms[61],pcur->pparms[62]); + fprintf(m,"+ nb = %g lnb = %g wnb = %g\n", + pcur->pparms[63],pcur->pparms[64],pcur->pparms[65]); + fprintf(m,"+ nd = %g lnd = %g wnd = %g\n", + pcur->pparms[66],pcur->pparms[67],pcur->pparms[68]); + fprintf(m,"+ rsh = %g cj = %g cjsw = %g\n", + dcur->dparms[0], dcur->dparms[1], dcur->dparms[2]); + fprintf(m,"+ js = %g pb = %g pbsw = %g\n", + dcur->dparms[3], dcur->dparms[4], dcur->dparms[5]); + fprintf(m,"+ mj = %g mjsw = %g wdf = %g\n", + dcur->dparms[6], dcur->dparms[7], dcur->dparms[8]); + fprintf(m,"+ dell = %g\n", + dcur->dparms[9]); + } + } + for(ncur=nlist;ncur;ncur=ncur->nnext) { + for(dcur=dlist;dcur;dcur=dcur->dnext) { + fprintf(m,".model %s_%s_%s nmos level=4\n",prname,ncur->nname, + dcur->dname); + fprintf(m,"+ vfb = %g lvfb = %g wvfb = %g\n", + ncur->nparms[0],ncur->nparms[1],ncur->nparms[2]); + fprintf(m,"+ phi = %g lphi = %g wphi = %g\n", + ncur->nparms[3],ncur->nparms[4],ncur->nparms[5]); + fprintf(m,"+ k1 = %g lk1 = %g wk1 = %g\n", + ncur->nparms[6],ncur->nparms[7],ncur->nparms[8]); + fprintf(m,"+ k2 = %g lk2 = %g wk2 = %g\n", + ncur->nparms[9],ncur->nparms[10],ncur->nparms[11]); + fprintf(m,"+ eta = %g leta = %g weta = %g\n", + ncur->nparms[12],ncur->nparms[13],ncur->nparms[14]); + fprintf(m,"+ muz = %g dl = %g dw = %g\n", + ncur->nparms[15],ncur->nparms[16],ncur->nparms[17]); + fprintf(m,"+ u0 = %g lu0 = %g wu0 = %g\n", + ncur->nparms[18],ncur->nparms[19],ncur->nparms[20]); + fprintf(m,"+ u1 = %g lu1 = %g wu1 = %g\n", + ncur->nparms[21],ncur->nparms[22],ncur->nparms[23]); + fprintf(m,"+ x2mz = %g lx2mz = %g wx2mz = %g\n", + ncur->nparms[24],ncur->nparms[25],ncur->nparms[26]); + fprintf(m,"+ x2e = %g lx2e = %g wx2e = %g\n", + ncur->nparms[27],ncur->nparms[28],ncur->nparms[29]); + fprintf(m,"+ x3e = %g lx3e = %g wx3e = %g\n", + ncur->nparms[30],ncur->nparms[31],ncur->nparms[32]); + fprintf(m,"+ x2u0 = %g lx2u0 = %g wx2u0 = %g\n", + ncur->nparms[33],ncur->nparms[34],ncur->nparms[35]); + fprintf(m,"+ x2u1 = %g lx2u1 = %g wx2u1 = %g\n", + ncur->nparms[36],ncur->nparms[37],ncur->nparms[38]); + fprintf(m,"+ mus = %g lmus = %g wmus = %g\n", + ncur->nparms[39],ncur->nparms[40],ncur->nparms[41]); + fprintf(m,"+ x2ms = %g lx2ms = %g wx2ms = %g\n", + ncur->nparms[42],ncur->nparms[43],ncur->nparms[44]); + fprintf(m,"+ x3ms = %g lx3ms = %g wx3ms = %g\n", + ncur->nparms[45],ncur->nparms[46],ncur->nparms[47]); + fprintf(m,"+ x3u1 = %g lx3u1 = %g wx3u1 = %g\n", + ncur->nparms[48],ncur->nparms[49],ncur->nparms[50]); + fprintf(m,"+ tox = %g temp = %g vdd = %g\n", + ncur->nparms[51],ncur->nparms[52],ncur->nparms[53]); + fprintf(m,"+ cgdo = %g cgso = %g cgbo = %g\n", + ncur->nparms[54],ncur->nparms[55],ncur->nparms[56]); + fprintf(m,"+ xpart = %g \n", + ncur->nparms[57]); + fprintf(m,"+ n0 = %g ln0 = %g wn0 = %g\n", + ncur->nparms[60],ncur->nparms[61],ncur->nparms[62]); + fprintf(m,"+ nb = %g lnb = %g wnb = %g\n", + ncur->nparms[63],ncur->nparms[64],ncur->nparms[65]); + fprintf(m,"+ nd = %g lnd = %g wnd = %g\n", + ncur->nparms[66],ncur->nparms[67],ncur->nparms[68]); + fprintf(m,"+ rsh = %g cj = %g cjsw = %g\n", + dcur->dparms[0], dcur->dparms[1], dcur->dparms[2]); + fprintf(m,"+ js = %g pb = %g pbsw = %g\n", + dcur->dparms[3], dcur->dparms[4], dcur->dparms[5]); + fprintf(m,"+ mj = %g mjsw = %g wdf = %g\n", + dcur->dparms[6], dcur->dparms[7], dcur->dparms[8]); + fprintf(m,"+ dell = %g\n", + dcur->dparms[9]); + } + } + return EXIT_NORMAL; +} + +void +getdata(vals,count,width) + double vals[]; + int count; + int width; /* maximum number of values to accept per line */ +{ + int i; + int error; + int start; + char *c; + + do { + if(fgets(dataline,1023,p)==NULL) { + printf("premature end of file getting input data line\n"); + exit(1); + } + start=0; + } while (*dataline == '*') ; + c = dataline; + for(i=0;iwidth)) { /* end of line, so read another one */ + do { + if(fgets(dataline,1023,p)==NULL) { + printf("premature end of file reading input data line \n"); + exit(1); + } + start=0; + } while (*dataline == '*') ; + c = dataline; + goto retry; + } + } +} diff --git a/src/ngsconvert.c b/src/ngsconvert.c new file mode 100644 index 000000000..ae43df9c8 --- /dev/null +++ b/src/ngsconvert.c @@ -0,0 +1,454 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* + * Main routine for sconvert. + */ + +#include "ngspice.h" +#include + +#include +#include +#include +#include +#include "suffix.h" + +FILE *cp_in = NULL; +FILE *cp_out = NULL; +FILE *cp_err = NULL; +FILE *cp_curin = NULL; +FILE *cp_curout = NULL; +FILE *cp_curerr = NULL; +int cp_maxhistlength; +bool cp_debug = FALSE; +char cp_chars[128]; +bool cp_nocc = TRUE; +bool ft_parsedb = FALSE; +struct circ *ft_curckt = NULL; + +char *cp_program = "sconvert"; + +/* doesn't get used, but some unused routine in some file references it */ +char out_pbuf[BSIZE_SP]; + + +#define tfread(ptr, siz, nit, fp) if (fread((char *) (ptr), (siz), \ + (nit), (fp)) != (nit)) { \ + fprintf(cp_err, "Error: unexpected EOF\n"); \ + return (NULL); } + +#define tfwrite(ptr, siz, nit, fp) if (fwrite((char *) (ptr), (siz), \ + (nit), (fp)) != (nit)) { \ + fprintf(cp_err, "Write error\n"); \ + return; } + + +void +Input(REQUEST *request, RESPONSE *response) +{ + switch (request->option) { + case char_option: + response->reply.ch = inchar(request->fp); + response->option = request->option; + break; + default: + /* just ignore, since we don't want a million error messages */ + response->option = error_option; + break; + } + return; +} + + +static char * +fixdate(char *date) +{ + char buf[20]; + int i; + + (void) strcpy(buf, date); + for (i = 17; i > 8; i--) + buf[i] = buf[i - 1]; + buf[8] = ' '; + buf[18] = '\0'; + return (copy(buf)); +} + + +static struct plot * +oldread(char *name) +{ + struct plot *pl; + char buf[BSIZE_SP]; + struct dvec *v, *end = NULL; + short nv; /* # vars */ + long np; /* # points/var. */ + long i, j; + short a; /* The magic number. */ + float f1, f2; + FILE *fp; + + if (!(fp = fopen(name, "r"))) { + perror(name); + return (NULL); + } + pl = alloc(struct plot); + tfread(buf, 1, 80, fp); + buf[80] = '\0'; + for (i = strlen(buf) - 1; (i > 1) && (buf[i] == ' '); i--) + ; + buf[i + 1] = '\0'; + pl->pl_title = copy(buf); + + tfread(buf, 1, 16, fp); + buf[16] = '\0'; + pl->pl_date = copy(fixdate(buf)); + + tfread(&nv, sizeof (short), 1, fp); + + tfread(&a, sizeof (short), 1, fp); + if (a != 4) + fprintf(cp_err, "Warning: magic number 4 is wrong...\n"); + + for (i = 0; i < nv; i++) { + v = alloc(struct dvec); + if (end) + end->v_next = v; + else + pl->pl_scale = pl->pl_dvecs = v; + end = v; + tfread(buf, 1, 8, fp); + buf[8] = '\0'; + v->v_name = copy(buf); + } + for (v = pl->pl_dvecs; v; v = v->v_next) { + tfread(&a, sizeof (short), 1, fp); + v->v_type = a; + } + + /* If the first output variable is type FREQ then there is complex + * data, otherwise the data is real. + */ + i = pl->pl_dvecs->v_type; + if ((i == SV_FREQUENCY) || (i == SV_POLE) || (i == SV_ZERO)) + for (v = pl->pl_dvecs; v; v = v->v_next) + v->v_flags |= VF_COMPLEX; + else + for (v = pl->pl_dvecs; v; v = v->v_next) + v->v_flags |= VF_REAL; + + /* Check the node indices -- this shouldn't be a problem ever. */ + for (i = 0; i < nv; i++) { + tfread(&a, sizeof(short), 1, fp); + if (a != i + 1) + fprintf(cp_err, "Warning: output %d should be %ld\n", + a, i); + } + tfread(buf, 1, 24, fp); + buf[24] = '\0'; + pl->pl_name = copy(buf); + /* Now to figure out how many points of data there are left in + * the file. + */ + i = ftell(fp); + (void) fseek(fp, (long) 0, 2); + j = ftell(fp); + (void) fseek(fp, i, 0); + i = j - i; + if (i % 8) { /* Data points are always 8 bytes... */ + fprintf(cp_err, "Error: alignment error in data\n"); + (void) fclose(fp); + return (NULL); + } + i = i / 8; + if (i % nv) { + fprintf(cp_err, "Error: alignment error in data\n"); + (void) fclose(fp); + return (NULL); + } + np = i / nv; + + for (v = pl->pl_dvecs; v; v = v->v_next) { + v->v_length = np; + if (isreal(v)) { + v->v_realdata = (double *) tmalloc(sizeof (double) + * np); + } else { + v->v_compdata = (complex *) tmalloc(sizeof (complex) + * np); + } + } + for (i = 0; i < np; i++) { + /* Read in the output vector for point i. If the type is + * complex it will be float and we want double. + */ + for (v = pl->pl_dvecs; v; v = v->v_next) { + if (v->v_flags & VF_REAL) { + tfread(&v->v_realdata[i], sizeof (double), + 1, fp); + } else { + tfread(&f1, sizeof (float), 1, fp); + tfread(&f2, sizeof (float), 1, fp); + realpart(&v->v_compdata[i]) = f1; + imagpart(&v->v_compdata[i]) = f2; + } + } + } + (void) fclose(fp); + return (pl); +} + + +static void +oldwrite(char *name, bool app, struct plot *pl) +{ + short four = 4, k; + struct dvec *v; + float f1, f2, zero = 0.0; + char buf[80]; + int i, j, tp = VF_REAL, numpts = 0, numvecs = 0; + FILE *fp; + + if (!(fp = fopen(name, app ? "a" : "w"))) { + perror(name); + return; + } + + for (v = pl->pl_dvecs; v; v = v->v_next) { + if (v->v_length > numpts) + numpts = v->v_length; + numvecs++; + if (iscomplex(v)) + tp = VF_COMPLEX; + } + + /* This may not be a good idea... */ + if (tp == VF_COMPLEX) + pl->pl_scale->v_type = SV_FREQUENCY; + + for (i = 0; i < 80; i++) + buf[i] = ' '; + for (i = 0; i < 80; i++) + if (pl->pl_title[i] == '\0') + break; + else + buf[i] = pl->pl_title[i]; + tfwrite(buf, 1, 80, fp); + + for (i = 0; i < 80; i++) + buf[i] = ' '; + for (i = 0; i < 16; i++) + if (pl->pl_date[i] == '\0') + break; + else + buf[i] = pl->pl_date[i]; + tfwrite(buf, 1, 16, fp); + + tfwrite(&numvecs, sizeof (short), 1, fp); + tfwrite(&four, sizeof (short), 1, fp); + + for (v = pl->pl_dvecs; v; v = v->v_next) { + for (j = 0; j < 80; j++) + buf[j] = ' '; + for (j = 0; j < 8; j++) + if (v->v_name[j] == '\0') + break; + else + buf[j] = v->v_name[j]; + tfwrite(buf, 1, 8, fp); + } + + for (v = pl->pl_dvecs; v; v = v->v_next) { + j = (short) v->v_type; + tfwrite(&j, sizeof (short), 1, fp); + } + + for (k = 1; k < numvecs + 1; k++) + tfwrite(&k, sizeof (short), 1, fp); + for (j = 0; j < 80; j++) + buf[j] = ' '; + for (j = 0; j < 24; j++) + if (pl->pl_name[j] == '\0') + break; + else + buf[j] = pl->pl_name[j]; + tfwrite(buf, 1, 24, fp); + for (i = 0; i < numpts; i++) { + for (v = pl->pl_dvecs; v; v = v->v_next) { + if ((tp == VF_REAL) && isreal(v)) { + if (i < v->v_length) { + tfwrite(&v->v_realdata[i], sizeof (double), 1, fp); + } else { + tfwrite(&v->v_realdata[v->v_length - 1], sizeof (double), 1, fp); + } + } else if ((tp == VF_REAL) && iscomplex(v)) { + if (i < v->v_length) + f1 = realpart(&v->v_compdata[i]); + else + f1 = realpart(&v->v_compdata[v-> v_length - 1]); + tfwrite(&f1, sizeof (double), 1, fp); + } else if ((tp == VF_COMPLEX) && isreal(v)) { + if (i < v->v_length) + f1 = v->v_realdata[i]; + else + f1 = v->v_realdata[v->v_length - 1]; + tfwrite(&f1, sizeof (float), 1, fp); + tfwrite(&zero, sizeof (float), 1, fp); + } else if ((tp == VF_COMPLEX) && iscomplex(v)) { + if (i < v->v_length) { + f1 = realpart(&v->v_compdata[i]); + f2 = imagpart(&v->v_compdata[i]); + } else { + f1 = realpart(&v->v_compdata[v-> v_length - 1]); + f2 = imagpart(&v->v_compdata[v-> v_length - 1]); + } + tfwrite(&f1, sizeof (float), 1, fp); + tfwrite(&f2, sizeof (float), 1, fp); + } + } + } + + (void) fclose(fp); + return; +} + + +int +main(int ac, char **av) +{ + char *sf, *af; + char buf[BSIZE_SP]; + char t, f; + struct plot *pl; + int i; + char *infile = NULL; + char *outfile = NULL; + FILE *fp; + cp_in = stdin; + cp_out = stdout; + cp_err = stderr; + cp_curin = stdin; + cp_curout = stdout; + cp_curerr = stderr; + + switch (ac) { + case 5: + sf = av[2]; + af = av[4]; + f = *av[1]; + t = *av[3]; + break; + + case 3: + f = *av[1]; + t = *av[2]; + /* This is a pain, but there is no choice */ + sf = infile = smktemp("scin"); + af = outfile = smktemp("scout"); + if (!(fp = fopen(infile, "w"))) { + perror(infile); + exit(EXIT_BAD); + } + while ((i = fread(buf, 1, sizeof(buf), stdin))) + (void) fwrite(buf, 1, i, fp); + (void) fclose(fp); + break; + + case 1: printf("Input file: "); + (void) fflush(stdout); + (void) fgets(buf, BSIZE_SP, stdin); + sf = copy(buf); + printf("Input type: "); + (void) fflush(stdout); + (void) fgets(buf, BSIZE_SP, stdin); + f = buf[0]; + printf("Output file: "); + (void) fflush(stdout); + (void) fgets(buf, BSIZE_SP, stdin); + af = copy(buf); + printf("Output type: "); + (void) fflush(stdout); + (void) fgets(buf, BSIZE_SP, stdin); + t = buf[0]; + break; + default: + fprintf(cp_err, + "Usage: %s fromtype fromfile totype tofile,\n", + cp_program); + fprintf(cp_err, "\twhere types are o, b, or a\n"); + fprintf(cp_err, + "\tor, %s fromtype totype, used as a filter.\n", + cp_program); + exit(EXIT_BAD); + } + switch(f) { + case 'o' : + pl = oldread(sf); + break; + + case 'b' : + case 'a' : + pl = raw_read(sf); + break; + + default: + fprintf(cp_err, "Types are o, a, or b\n"); + exit(EXIT_BAD); + } + if (!pl) + exit(EXIT_BAD); + + switch(t) { + case 'o' : + oldwrite(af, FALSE, pl); + break; + + case 'b' : + raw_write(af, pl, FALSE, TRUE); + break; + + case 'a' : + raw_write(af, pl, FALSE, FALSE); + break; + + default: + fprintf(cp_err, "Types are o, a, or b\n"); + exit(EXIT_BAD); + } + if (ac == 3) { + /* Gotta finish this stuff up */ + if (!(fp = fopen(outfile, "r"))) { + perror(outfile); + exit(EXIT_BAD); + } + while ((i = fread(buf, 1, sizeof(buf), fp))) + (void) fwrite(buf, 1, i, stdout); + (void) fclose(fp); + (void) unlink(infile); + (void) unlink(outfile); + } + exit(EXIT_NORMAL); +} + +void cp_pushcontrol(void) { } +void cp_popcontrol(void) { } +void out_init(void) { } +void cp_doquit(void) { exit(0); } +void cp_usrvars(struct variable **v1, struct variable **v2) { return; } +int cp_evloop(char *s) { return (0); } +void cp_ccon(bool o) { } +char *if_errstring(int c) { return ("error"); } +#ifndef out_printf +void out_printf(char *fmt, int args) { } +#endif +void out_send(char *string) {} +struct variable * cp_enqvar(char *word) { return (NULL); } +struct dvec *vec_get(char *word) { return (NULL); } +void cp_ccom(wordlist *w, char *b, bool e) { return; } +int cp_usrset(struct variable *v, bool i) { return(US_OK); } + +int disptype; +void XtDispatchEvent(char *pev) { } 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 5036ddd30..6cda8a5f9 100644 Binary files a/src/ngspice.idx and b/src/ngspice.idx differ diff --git a/src/ngspice.txt b/src/ngspice.txt index f54c3b931..83cdc5395 100644 --- a/src/ngspice.txt +++ b/src/ngspice.txt @@ -7,14 +7,14 @@ TEXT: H TEXT: H TEXT: H TEXT: H -SUBTOPIC: SPICE:INTRODUCTION -SUBTOPIC: SPICE:CIRCUIT DESCRIPTION -SUBTOPIC: SPICE:CIRCUIT ELEMENTS AND MODELS -SUBTOPIC: SPICE:ANALYSES AND OUTPUT CONTROL -SUBTOPIC: SPICE:INTERACTIVE INTERPRETER -SUBTOPIC: SPICE:BIBLIOGRAPHY -SUBTOPIC: SPICE:APPENDIX A -SUBTOPIC: SPICE:APPENDIX B +SUBTOPIC: NGSPICE:INTRODUCTION +SUBTOPIC: NGSPICE:CIRCUIT DESCRIPTION +SUBTOPIC: NGSPICE:CIRCUIT ELEMENTS AND MODELS +SUBTOPIC: NGSPICE:ANALYSES AND OUTPUT CONTROL +SUBTOPIC: NGSPICE:INTERACTIVE INTERPRETER +SUBTOPIC: NGSPICE:BIBLIOGRAPHY +SUBTOPIC: NGSPICE:APPENDIX A +SUBTOPIC: NGSPICE:APPENDIX B SUBJECT: INTRODUCTION TITLE: INTRODUCTION TEXT: H @@ -56,22 +56,22 @@ TEXT: H and MOS4 include second-order effects such as channel-length TEXT: H modulation, subthreshold conduction, scattering-limited TEXT: H velocity saturation, small-size effects, and charge- TEXT: H controlled capacitances. -SUBTOPIC: SPICE:TYPES OF ANALYSIS -SUBTOPIC: SPICE:ANALYSIS AT DIFFERENT TEMPERATURES -SUBTOPIC: SPICE:CONVERGENCE +SUBTOPIC: NGSPICE:TYPES OF ANALYSIS +SUBTOPIC: NGSPICE:ANALYSIS AT DIFFERENT TEMPERATURES +SUBTOPIC: NGSPICE:CONVERGENCE SUBJECT: TYPES OF ANALYSIS TITLE: TYPES OF ANALYSIS TEXT: H TEXT: H _1._1. _T_Y_P_E_S _O_F _A_N_A_L_Y_S_I_S TEXT: H -SUBTOPIC: SPICE:DC Analysis -SUBTOPIC: SPICE:AC SmallSignal Analysis -SUBTOPIC: SPICE:Transient Analysis -SUBTOPIC: SPICE:PoleZero Analysis -SUBTOPIC: SPICE:SmallSignal Distortion Analysis -SUBTOPIC: SPICE:Sensitivity Analysis -SUBTOPIC: SPICE:Noise Analysis +SUBTOPIC: NGSPICE:DC Analysis +SUBTOPIC: NGSPICE:AC SmallSignal Analysis +SUBTOPIC: NGSPICE:Transient Analysis +SUBTOPIC: NGSPICE:PoleZero Analysis +SUBTOPIC: NGSPICE:SmallSignal Distortion Analysis +SUBTOPIC: NGSPICE:Sensitivity Analysis +SUBTOPIC: NGSPICE:Noise Analysis SUBJECT: DC Analysis TITLE: DC Analysis @@ -431,11 +431,11 @@ SUBJECT: CIRCUIT DESCRIPTION TITLE: CIRCUIT DESCRIPTION TEXT: H TEXT: H _2. _C_I_R_C_U_I_T _D_E_S_C_R_I_P_T_I_O_N -SUBTOPIC: SPICE:GENERAL STRUCTURE AND CONVENTIONS -SUBTOPIC: SPICE:TITLE LINE COMMENT LINES AND .END LINE -SUBTOPIC: SPICE:DEVICE MODELS -SUBTOPIC: SPICE:SUBCIRCUITS -SUBTOPIC: SPICE:COMBINING FILES +SUBTOPIC: NGSPICE:GENERAL STRUCTURE AND CONVENTIONS +SUBTOPIC: NGSPICE:TITLE LINE COMMENT LINES AND .END LINE +SUBTOPIC: NGSPICE:DEVICE MODELS +SUBTOPIC: NGSPICE:SUBCIRCUITS +SUBTOPIC: NGSPICE:COMBINING FILES SUBJECT: GENERAL STRUCTURE AND CONVENTIONS TITLE: GENERAL STRUCTURE AND CONVENTIONS @@ -515,9 +515,9 @@ TITLE: TITLE LINE, COMMENT LINES AND .END LINE TEXT: H TEXT: H _2._2. _T_I_T_L_E _L_I_N_E, _C_O_M_M_E_N_T _L_I_N_E_S _A_N_D ._E_N_D _L_I_N_E TEXT: H -SUBTOPIC: SPICE:Title Line -SUBTOPIC: SPICE:.END Line -SUBTOPIC: SPICE:Comments +SUBTOPIC: NGSPICE:Title Line +SUBTOPIC: NGSPICE:.END Line +SUBTOPIC: NGSPICE:Comments SUBJECT: Title Line TITLE: Title Line @@ -658,9 +658,9 @@ TEXT: H subcircuits, and subcircuits may contain other subcircuits. TEXT: H An example of subcircuit usage is given in Appendix A. TEXT: H TEXT: H -SUBTOPIC: SPICE:.SUBCKT Line -SUBTOPIC: SPICE:.ENDS Line -SUBTOPIC: SPICE:Subcircuit Calls +SUBTOPIC: NGSPICE:.SUBCKT Line +SUBTOPIC: NGSPICE:.ENDS Line +SUBTOPIC: NGSPICE:Subcircuit Calls SUBJECT: .SUBCKT Line TITLE: .SUBCKT Line @@ -783,26 +783,26 @@ TEXT: H makes the input easier to understand. With respect to TEXT: H branch voltages and currents, SPICE uniformly uses the asso- TEXT: H ciated reference convention (current flows in the direction TEXT: H of voltage drop). -SUBTOPIC: SPICE:ELEMENTARY DEVICES -SUBTOPIC: SPICE:VOLTAGE AND CURRENT SOURCES -SUBTOPIC: SPICE:TRANSMISSION LINES -SUBTOPIC: SPICE:TRANSISTORS AND DIODES +SUBTOPIC: NGSPICE:ELEMENTARY DEVICES +SUBTOPIC: NGSPICE:VOLTAGE AND CURRENT SOURCES +SUBTOPIC: NGSPICE:TRANSMISSION LINES +SUBTOPIC: NGSPICE:TRANSISTORS AND DIODES SUBJECT: ELEMENTARY DEVICES TITLE: ELEMENTARY DEVICES TEXT: H TEXT: H _3._1. _E_L_E_M_E_N_T_A_R_Y _D_E_V_I_C_E_S TEXT: H -SUBTOPIC: SPICE:Resistors -SUBTOPIC: SPICE:Semiconductor Resistors -SUBTOPIC: SPICE:Semiconductor Resistor Model -SUBTOPIC: SPICE:Capacitors -SUBTOPIC: SPICE:Semiconductor Capacitors -SUBTOPIC: SPICE:Semiconductor Capacitor Model -SUBTOPIC: SPICE:Inductors -SUBTOPIC: SPICE:Coupled Inductors -SUBTOPIC: SPICE:Switches -SUBTOPIC: SPICE:Switch Model +SUBTOPIC: NGSPICE:Resistors +SUBTOPIC: NGSPICE:Semiconductor Resistors +SUBTOPIC: NGSPICE:Semiconductor Resistor Model +SUBTOPIC: NGSPICE:Capacitors +SUBTOPIC: NGSPICE:Semiconductor Capacitors +SUBTOPIC: NGSPICE:Semiconductor Capacitor Model +SUBTOPIC: NGSPICE:Inductors +SUBTOPIC: NGSPICE:Coupled Inductors +SUBTOPIC: NGSPICE:Switches +SUBTOPIC: NGSPICE:Switch Model SUBJECT: Resistors TITLE: Resistors @@ -1153,9 +1153,9 @@ TITLE: VOLTAGE AND CURRENT SOURCES TEXT: H TEXT: H _3._2. _V_O_L_T_A_G_E _A_N_D _C_U_R_R_E_N_T _S_O_U_R_C_E_S TEXT: H -SUBTOPIC: SPICE:Independent Sources -SUBTOPIC: SPICE:Linear Dependent Sources -SUBTOPIC: SPICE:Nonlinear Dependent Sources +SUBTOPIC: NGSPICE:Independent Sources +SUBTOPIC: NGSPICE:Linear Dependent Sources +SUBTOPIC: NGSPICE:Nonlinear Dependent Sources SUBJECT: Independent Sources TITLE: Independent Sources @@ -1228,11 +1228,11 @@ TEXT: H assumed. (TSTEP is the printing increment and TSTOP is the TEXT: H final time (see the .TRAN control line for explanation)). TEXT: H TEXT: H -SUBTOPIC: SPICE:Pulse -SUBTOPIC: SPICE:Sinusoidal -SUBTOPIC: SPICE:Exponential -SUBTOPIC: SPICE:PieceWise Linear -SUBTOPIC: SPICE:SingleFrequency FM +SUBTOPIC: NGSPICE:Pulse +SUBTOPIC: NGSPICE:Sinusoidal +SUBTOPIC: NGSPICE:Exponential +SUBTOPIC: NGSPICE:PieceWise Linear +SUBTOPIC: NGSPICE:SingleFrequency FM SUBJECT: Pulse TITLE: Pulse @@ -1469,10 +1469,10 @@ TEXT: H respectively. TEXT: H TEXT: H TEXT: H -SUBTOPIC: SPICE:Linear VoltageControlled Current Sources -SUBTOPIC: SPICE:Linear VoltageControlled Voltage Sources -SUBTOPIC: SPICE:Linear CurrentControlled Current Sources -SUBTOPIC: SPICE:Linear CurrentControlled Voltage Sources +SUBTOPIC: NGSPICE:Linear VoltageControlled Current Sources +SUBTOPIC: NGSPICE:Linear VoltageControlled Voltage Sources +SUBTOPIC: NGSPICE:Linear CurrentControlled Current Sources +SUBTOPIC: NGSPICE:Linear CurrentControlled Voltage Sources SUBJECT: Linear VoltageControlled Current Sources TITLE: Linear Voltage-Controlled Current Sources @@ -1671,11 +1671,11 @@ TITLE: TRANSMISSION LINES TEXT: H TEXT: H _3._3. _T_R_A_N_S_M_I_S_S_I_O_N _L_I_N_E_S TEXT: H -SUBTOPIC: SPICE:Lossless Transmission Lines -SUBTOPIC: SPICE:Lossy Transmission Lines -SUBTOPIC: SPICE:Lossy Transmission Line Model -SUBTOPIC: SPICE:Uniform Distributed RC Lines -SUBTOPIC: SPICE:Uniform Distributed RC Model +SUBTOPIC: NGSPICE:Lossless Transmission Lines +SUBTOPIC: NGSPICE:Lossy Transmission Lines +SUBTOPIC: NGSPICE:Lossy Transmission Line Model +SUBTOPIC: NGSPICE:Uniform Distributed RC Lines +SUBTOPIC: NGSPICE:Uniform Distributed RC Model SUBJECT: Lossless Transmission Lines TITLE: Lossless Transmission Lines @@ -1961,16 +1961,16 @@ TEXT: H trol line for a detailed explanation of initial conditions. TEXT: H TEXT: H TEXT: H -SUBTOPIC: SPICE:Junction Diodes -SUBTOPIC: SPICE:Diode Model -SUBTOPIC: SPICE:Bipolar Junction Transistors -SUBTOPIC: SPICE:BJT Models -SUBTOPIC: SPICE:Junction FieldEffect Transistors -SUBTOPIC: SPICE:JFET Models -SUBTOPIC: SPICE:MOSFETs -SUBTOPIC: SPICE:MOSFET Models -SUBTOPIC: SPICE:MESFETs -SUBTOPIC: SPICE:MESFET Models +SUBTOPIC: NGSPICE:Junction Diodes +SUBTOPIC: NGSPICE:Diode Model +SUBTOPIC: NGSPICE:Bipolar Junction Transistors +SUBTOPIC: NGSPICE:BJT Models +SUBTOPIC: NGSPICE:Junction FieldEffect Transistors +SUBTOPIC: NGSPICE:JFET Models +SUBTOPIC: NGSPICE:MOSFETs +SUBTOPIC: NGSPICE:MOSFET Models +SUBTOPIC: NGSPICE:MESFETs +SUBTOPIC: NGSPICE:MESFET Models SUBJECT: Junction Diodes TITLE: Junction Diodes @@ -2702,10 +2702,10 @@ TEXT: H the .PRINT, .PLOT, and .FOUR control lines, described next. TEXT: H .PLOT, .PRINT, and .FOUR lines are meant for compatibility TEXT: H with Spice2. TEXT: H -SUBTOPIC: SPICE:SIMULATOR VARIABLES -SUBTOPIC: SPICE:INITIAL CONDITIONS -SUBTOPIC: SPICE:ANALYSES -SUBTOPIC: SPICE:BATCH OUTPUT +SUBTOPIC: NGSPICE:SIMULATOR VARIABLES +SUBTOPIC: NGSPICE:INITIAL CONDITIONS +SUBTOPIC: NGSPICE:ANALYSES +SUBTOPIC: NGSPICE:BATCH OUTPUT SUBJECT: SIMULATOR VARIABLES TITLE: SIMULATOR VARIABLES (.OPTIONS) @@ -2829,8 +2829,8 @@ TITLE: INITIAL CONDITIONS TEXT: H TEXT: H _4._2. _I_N_I_T_I_A_L _C_O_N_D_I_T_I_O_N_S TEXT: H -SUBTOPIC: SPICE:.NODESET -SUBTOPIC: SPICE:.IC +SUBTOPIC: NGSPICE:.NODESET +SUBTOPIC: NGSPICE:.IC SUBJECT: .NODESET TITLE: .NODESET: Specify Initial Node Voltage Guesses @@ -2911,15 +2911,15 @@ TEXT: H TEXT: H _4._3. _A_N_A_L_Y_S_E_S TEXT: H TEXT: H -SUBTOPIC: SPICE:.AC -SUBTOPIC: SPICE:.DC -SUBTOPIC: SPICE:.DISTO -SUBTOPIC: SPICE:.NOISE -SUBTOPIC: SPICE:.OP -SUBTOPIC: SPICE:.PZ -SUBTOPIC: SPICE:.SENS -SUBTOPIC: SPICE:.TF -SUBTOPIC: SPICE:.TRAN +SUBTOPIC: NGSPICE:.AC +SUBTOPIC: NGSPICE:.DC +SUBTOPIC: NGSPICE:.DISTO +SUBTOPIC: NGSPICE:.NOISE +SUBTOPIC: NGSPICE:.OP +SUBTOPIC: NGSPICE:.PZ +SUBTOPIC: NGSPICE:.SENS +SUBTOPIC: NGSPICE:.TF +SUBTOPIC: NGSPICE:.TRAN SUBJECT: .AC TITLE: .AC: Small-Signal AC Analysis @@ -3326,10 +3326,10 @@ TEXT: H TEXT: H _4._4. _B_A_T_C_H _O_U_T_P_U_T TEXT: H TEXT: H -SUBTOPIC: SPICE:.SAVE Lines -SUBTOPIC: SPICE:.PRINT Lines -SUBTOPIC: SPICE:.PLOT Lines -SUBTOPIC: SPICE:.FOUR +SUBTOPIC: NGSPICE:.SAVE Lines +SUBTOPIC: NGSPICE:.PRINT Lines +SUBTOPIC: NGSPICE:.PLOT Lines +SUBTOPIC: NGSPICE:.FOUR SUBJECT: .SAVE Lines TITLE: .SAVE Lines @@ -3607,13 +3607,13 @@ TEXT: H loaded into nutmeg. If the file is in binary format, it may TEXT: H be only partially completed (useful for examining Spice2 TEXT: H output before the simulation is finished). One file may TEXT: H contain any number of data sets from different analyses. -SUBTOPIC: SPICE:EXPRESSIONS FUNCTIONS AND CONSTANTS -SUBTOPIC: SPICE:COMMAND INTERPRETATION -SUBTOPIC: SPICE:COMMANDS -SUBTOPIC: SPICE:CONTROL STRUCTURES -SUBTOPIC: SPICE:VARIABLES -SUBTOPIC: SPICE:MISCELLANEOUS -SUBTOPIC: SPICE:BUGS +SUBTOPIC: NGSPICE:EXPRESSIONS FUNCTIONS AND CONSTANTS +SUBTOPIC: NGSPICE:COMMAND INTERPRETATION +SUBTOPIC: NGSPICE:COMMANDS +SUBTOPIC: NGSPICE:CONTROL STRUCTURES +SUBTOPIC: NGSPICE:VARIABLES +SUBTOPIC: NGSPICE:MISCELLANEOUS +SUBTOPIC: NGSPICE:BUGS SUBJECT: EXPRESSIONS FUNCTIONS AND CONSTANTS TITLE: EXPRESSIONS, FUNCTIONS, AND CONSTANTS @@ -3824,67 +3824,67 @@ TEXT: H TEXT: H _5._3. _C_O_M_M_A_N_D_S TEXT: H TEXT: H -SUBTOPIC: SPICE:Ac -SUBTOPIC: SPICE:Alias -SUBTOPIC: SPICE:Alter -SUBTOPIC: SPICE:Asciiplot -SUBTOPIC: SPICE:Aspice -SUBTOPIC: SPICE:Bug -SUBTOPIC: SPICE:Cd -SUBTOPIC: SPICE:Destroy -SUBTOPIC: SPICE:Dc -SUBTOPIC: SPICE:Define -SUBTOPIC: SPICE:Delete -SUBTOPIC: SPICE:Diff -SUBTOPIC: SPICE:Display -SUBTOPIC: SPICE:Echo -SUBTOPIC: SPICE:Edit -SUBTOPIC: SPICE:Fourier -SUBTOPIC: SPICE:Hardcopy -SUBTOPIC: SPICE:Help -SUBTOPIC: SPICE:History -SUBTOPIC: SPICE:Iplot -SUBTOPIC: SPICE:Jobs -SUBTOPIC: SPICE:Let -SUBTOPIC: SPICE:Linearize -SUBTOPIC: SPICE:Listing -SUBTOPIC: SPICE:Load -SUBTOPIC: SPICE:Op -SUBTOPIC: SPICE:Plot -SUBTOPIC: SPICE:Print -SUBTOPIC: SPICE:Quit -SUBTOPIC: SPICE:Rehash -SUBTOPIC: SPICE:Reset -SUBTOPIC: SPICE:Reshape -SUBTOPIC: SPICE:Resume -SUBTOPIC: SPICE:Rspice -SUBTOPIC: SPICE:Run -SUBTOPIC: SPICE:Rusage -SUBTOPIC: SPICE:Save -SUBTOPIC: SPICE:Sens -SUBTOPIC: SPICE:Set -SUBTOPIC: SPICE:Setcirc -SUBTOPIC: SPICE:Setplot -SUBTOPIC: SPICE:Settype -SUBTOPIC: SPICE:Shell -SUBTOPIC: SPICE:Shift -SUBTOPIC: SPICE:Show -SUBTOPIC: SPICE:Showmod -SUBTOPIC: SPICE:Source -SUBTOPIC: SPICE:Status -SUBTOPIC: SPICE:Step -SUBTOPIC: SPICE:Stop -SUBTOPIC: SPICE:Tf -SUBTOPIC: SPICE:Trace -SUBTOPIC: SPICE:Tran -SUBTOPIC: SPICE:Transpose -SUBTOPIC: SPICE:Unalias -SUBTOPIC: SPICE:Undefine -SUBTOPIC: SPICE:Unset -SUBTOPIC: SPICE:Version -SUBTOPIC: SPICE:Where -SUBTOPIC: SPICE:Write -SUBTOPIC: SPICE:Xgraph +SUBTOPIC: NGSPICE:Ac +SUBTOPIC: NGSPICE:Alias +SUBTOPIC: NGSPICE:Alter +SUBTOPIC: NGSPICE:Asciiplot +SUBTOPIC: NGSPICE:Aspice +SUBTOPIC: NGSPICE:Bug +SUBTOPIC: NGSPICE:Cd +SUBTOPIC: NGSPICE:Destroy +SUBTOPIC: NGSPICE:Dc +SUBTOPIC: NGSPICE:Define +SUBTOPIC: NGSPICE:Delete +SUBTOPIC: NGSPICE:Diff +SUBTOPIC: NGSPICE:Display +SUBTOPIC: NGSPICE:Echo +SUBTOPIC: NGSPICE:Edit +SUBTOPIC: NGSPICE:Fourier +SUBTOPIC: NGSPICE:Hardcopy +SUBTOPIC: NGSPICE:Help +SUBTOPIC: NGSPICE:History +SUBTOPIC: NGSPICE:Iplot +SUBTOPIC: NGSPICE:Jobs +SUBTOPIC: NGSPICE:Let +SUBTOPIC: NGSPICE:Linearize +SUBTOPIC: NGSPICE:Listing +SUBTOPIC: NGSPICE:Load +SUBTOPIC: NGSPICE:Op +SUBTOPIC: NGSPICE:Plot +SUBTOPIC: NGSPICE:Print +SUBTOPIC: NGSPICE:Quit +SUBTOPIC: NGSPICE:Rehash +SUBTOPIC: NGSPICE:Reset +SUBTOPIC: NGSPICE:Reshape +SUBTOPIC: NGSPICE:Resume +SUBTOPIC: NGSPICE:Rspice +SUBTOPIC: NGSPICE:Run +SUBTOPIC: NGSPICE:Rusage +SUBTOPIC: NGSPICE:Save +SUBTOPIC: NGSPICE:Sens +SUBTOPIC: NGSPICE:Set +SUBTOPIC: NGSPICE:Setcirc +SUBTOPIC: NGSPICE:Setplot +SUBTOPIC: NGSPICE:Settype +SUBTOPIC: NGSPICE:Shell +SUBTOPIC: NGSPICE:Shift +SUBTOPIC: NGSPICE:Show +SUBTOPIC: NGSPICE:Showmod +SUBTOPIC: NGSPICE:Source +SUBTOPIC: NGSPICE:Status +SUBTOPIC: NGSPICE:Step +SUBTOPIC: NGSPICE:Stop +SUBTOPIC: NGSPICE:Tf +SUBTOPIC: NGSPICE:Trace +SUBTOPIC: NGSPICE:Tran +SUBTOPIC: NGSPICE:Transpose +SUBTOPIC: NGSPICE:Unalias +SUBTOPIC: NGSPICE:Undefine +SUBTOPIC: NGSPICE:Unset +SUBTOPIC: NGSPICE:Version +SUBTOPIC: NGSPICE:Where +SUBTOPIC: NGSPICE:Write +SUBTOPIC: NGSPICE:Xgraph SUBJECT: Ac TITLE: Ac*: Perform an AC, small-signal frequency response analysis @@ -4670,12 +4670,19 @@ TEXT: H traced or plotted (see below) it is also saved. For TEXT: H backward compatibility, if there are no save commands TEXT: H given, all outputs are saved. TEXT: H -TEXT: H When the keyword "all" appears in the save command, -TEXT: H all default values (node voltages and voltage source -TEXT: H currents) are saved in addition to any other values -TEXT: H listed. -TEXT: H -TEXT: H +TEXT: H When the keyword "all" or the keyword "allv", appears in +TEXT: H the save command, all node voltages, voltage source +TEXT: H currents and inductor currents are saved in addition to +TEXT: H any other values listed. If the keyword "alli" appears +TEXT: H in the save command, all devices currents are saved. +TEXT: H +TEXT: H Note: the current implementation saves only the currents +TEXT: H of devices which have internal nodes, i.e. MOSFETs +TEXT: H with non zero RD and RS; BJTs with non-zero RC, RB +TEXT: H and RE; DIODEs with non-zero RS; etc. Resistor and +TEXT: H capacitor currents are not saved with this option. +TEXT: H These deficiencies will be addressed in a later +TEXT: H revision. SUBJECT: Sens TITLE: Sens*: Run a sensitivity analysis @@ -5196,15 +5203,15 @@ TEXT: H TEXT: H _5._4. _C_O_N_T_R_O_L _S_T_R_U_C_T_U_R_E_S TEXT: H TEXT: H -SUBTOPIC: SPICE:While End -SUBTOPIC: SPICE:Repeat End -SUBTOPIC: SPICE:Dowhile End -SUBTOPIC: SPICE:Foreach End -SUBTOPIC: SPICE:If Then Else -SUBTOPIC: SPICE:Label -SUBTOPIC: SPICE:Goto -SUBTOPIC: SPICE:Continue -SUBTOPIC: SPICE:Break +SUBTOPIC: NGSPICE:While End +SUBTOPIC: NGSPICE:Repeat End +SUBTOPIC: NGSPICE:Dowhile End +SUBTOPIC: NGSPICE:Foreach End +SUBTOPIC: NGSPICE:If Then Else +SUBTOPIC: NGSPICE:Label +SUBTOPIC: NGSPICE:Goto +SUBTOPIC: NGSPICE:Continue +SUBTOPIC: NGSPICE:Break SUBJECT: While End TITLE: While - End @@ -5873,11 +5880,11 @@ TEXT: H TEXT: H _A. _A_P_P_E_N_D_I_X _A: _E_X_A_M_P_L_E _C_I_R_C_U_I_T_S TEXT: H TEXT: H -SUBTOPIC: SPICE:Circuit 1 -SUBTOPIC: SPICE:Circuit 2 -SUBTOPIC: SPICE:Circuit 3 -SUBTOPIC: SPICE:Circuit 4 -SUBTOPIC: SPICE:Circuit 5 +SUBTOPIC: NGSPICE:Circuit 1 +SUBTOPIC: NGSPICE:Circuit 2 +SUBTOPIC: NGSPICE:Circuit 3 +SUBTOPIC: NGSPICE:Circuit 4 +SUBTOPIC: NGSPICE:Circuit 5 SUBJECT: Circuit 1 TITLE: Circuit 1: Differential Pair @@ -6128,32 +6135,32 @@ TEXT: H Please note that these tables do not provide the TEXT: H detailed information available about the parameters provided TEXT: H in the section on each device and model, but are provided as TEXT: H a quick reference guide. -SUBTOPIC: SPICE:URC -SUBTOPIC: SPICE:ASRC -SUBTOPIC: SPICE:BJT -SUBTOPIC: SPICE:BSIM1 -SUBTOPIC: SPICE:BSIM2 -SUBTOPIC: SPICE:Capacitor -SUBTOPIC: SPICE:CCCS -SUBTOPIC: SPICE:CCVS -SUBTOPIC: SPICE:CSwitch -SUBTOPIC: SPICE:Diode -SUBTOPIC: SPICE:Inductor -SUBTOPIC: SPICE:mutual -SUBTOPIC: SPICE:Isource -SUBTOPIC: SPICE:JFET -SUBTOPIC: SPICE:LTRA -SUBTOPIC: SPICE:MES -SUBTOPIC: SPICE:Mos1 -SUBTOPIC: SPICE:Mos2 -SUBTOPIC: SPICE:Mos3 -SUBTOPIC: SPICE:Mos6 -SUBTOPIC: SPICE:Resistor -SUBTOPIC: SPICE:Switch -SUBTOPIC: SPICE:Tranline -SUBTOPIC: SPICE:VCCS -SUBTOPIC: SPICE:VCVS -SUBTOPIC: SPICE:Vsource +SUBTOPIC: NGSPICE:URC +SUBTOPIC: NGSPICE:ASRC +SUBTOPIC: NGSPICE:BJT +SUBTOPIC: NGSPICE:BSIM1 +SUBTOPIC: NGSPICE:BSIM2 +SUBTOPIC: NGSPICE:Capacitor +SUBTOPIC: NGSPICE:CCCS +SUBTOPIC: NGSPICE:CCVS +SUBTOPIC: NGSPICE:CSwitch +SUBTOPIC: NGSPICE:Diode +SUBTOPIC: NGSPICE:Inductor +SUBTOPIC: NGSPICE:mutual +SUBTOPIC: NGSPICE:Isource +SUBTOPIC: NGSPICE:JFET +SUBTOPIC: NGSPICE:LTRA +SUBTOPIC: NGSPICE:MES +SUBTOPIC: NGSPICE:Mos1 +SUBTOPIC: NGSPICE:Mos2 +SUBTOPIC: NGSPICE:Mos3 +SUBTOPIC: NGSPICE:Mos6 +SUBTOPIC: NGSPICE:Resistor +SUBTOPIC: NGSPICE:Switch +SUBTOPIC: NGSPICE:Tranline +SUBTOPIC: NGSPICE:VCCS +SUBTOPIC: NGSPICE:VCVS +SUBTOPIC: NGSPICE:Vsource SUBJECT: URC TITLE: URC: Uniform R.C. line diff --git a/src/pkgIndex.tcl.in b/src/pkgIndex.tcl.in new file mode 100755 index 000000000..a7b2b00b0 --- /dev/null +++ b/src/pkgIndex.tcl.in @@ -0,0 +1,3028 @@ +#Tcl package index file, version 0.1 +#Tcl package index file, version %VERSION% +set ::spicewishversion "0.1" + + + +#set ::plot_background \#004040 +set ::plot_background white + +proc Loadspice { version dir } { + + package require BLT + + package require tclreadline + + package require Tclx ;# for bsearch + + set suffix [info sharedlibextension] + + set library spice${suffix} + + + global tcl_platform + if { $tcl_platform(platform) == "unix" } { + set library [file join $dir lib${library}] + } + load $library spice + + blt::vector create ::spice::X_Data + blt::vector create ::spice::Y_Data + + namespace eval spice { + namespace export ac help save alias history sens alter altermod iplot setcirc asciiplot jobs setplot aspice setscale bg let settype linearize shell bug listing shift show cdump maxstep showmod compose newhelp noise spec cross oldhelp spice dc op spice_data define spice_header deftype plot state delete plot_datapoints status delta plot_date step plot_get_value stop diff plot_name strcmp display plot_nvars tf disto plot_title dowhile plot_variables tran dump print transpose echo pz tutorial edit quit unalias else rehash undefine end repeat unlet reset fourier reshape version spicetoblt resume where get_output rspice get_param run write goto running xgraph hardcopy rusage steps_completed blt_vnum codemodel halt + + } + + # Callback functions for the plot command + # Warning: if any of these functions return an error then + # spice will probably segfault as tcl/tk will overflow somewhere + # Note: color is actually spelt COLOUR, which looks much better + # Note: they don't work in namespace so have to make global + + proc spice_gr_NewViewport { } { + set width 1000 + set height 400 + set fontwidth 12 + set fontheight 24 + canvas .c -width $width -height $height -background white + pack .c + return "$width $height $fontwidth $fontheight" + } + proc spice_gr_Close { } { + } + proc spice_gr_Clear { } { + } + proc spice_gr_DrawLine { x1 y1 x2 y2 } { + puts "draw" + .c create line [expr $x1 + 25] [expr 375 - $y1] [expr $x2 + 25] [expr 375 - $y2] + } + proc spice_gr_Arc { x0 y0 radius theta1 theta2 } { + .c create arc [expr $x0 - $radius + 25] [expr 375 - $y0 - $radius] \ + [expr $x1 + $radius + 25 ] [expr 375 - $y1 + $radius] \ + -start $theta1 -extent $theta2 + } + proc spice_gr_Text {text x y} { + .c create text [expr $x + 25] [expr 375 - $y] -text $text + } + + proc spice_gr_SetLinestyle {linestyleid} { + puts "SetLinestyle $linestyleid" + } + proc spice_gr_SetColor {colorid } { + puts "SetColor $colorid $color" + } + + proc spice_gr_Update { } { + } + + + # These seem to never be called /* + proc spice_gr_DefineColor {colorid red green blue} { + puts "DefineColor $colorid $red $green $blue" + } + proc spice_gr_DefineLinestyle {linestyleid mask} { + puts "DefineLinestyle $linestyleid $mask" + } + + + ::tclreadline::readline customcompleter "plot_command_readline_completer" ;#- see routine above + +} + + +#------------------------------------------------ +# nutmeg extensions (eqivalent functions to nutmeg) +# (requires readline, + + +#toplevel counters +set ::toplevel_count 1 + +#Colour schemes. +# - Colours allocated on a rotating colour sheme ::trace_index_counter counts the traces issued +# -OR- if a particular hash exists for a trace, this is used + +set ::linecolour(default) "grey" +set ::linecolour(0) "red" +set ::linecolour(1) "blue" +set ::linecolour(2) "orange" +set ::linecolour(3) "green" +set ::linecolour(4) "magenta" +set ::linecolour(5) "brown" + + + +#-alternate line dashes +set ::dashlist(default) "" ;#- solid by default +set ::dashlist(0) "2 2"; #- fine dots +set ::dashlist(1) "5 5"; #- large dahes +set ::dashlist(2) "10 2"; #- large dahes, small gap +set ::dashlist(3) "2 10"; #- +set ::dashlist(4) "3 1 2"; #- +set ::dashlist(5) "20 5"; #- + +#-------------------------------------------------------------------------------------------------------------------------------------- +proc q { } { exit } + +#--------------------------------------------------------------------------------------------------------------------------------------- +proc run { } { spice::run } + +#--------------------------------------------------------------------------------------------------------------------------------------- +# plot command, replacement of nutmeg's plot command, mapped onto +# the new code + +proc plot { args } { + + global disp_zoom_level disp_dx + + #make a new toplevel + set tl [toplevel ".tclspice$::toplevel_count"] + wm title $tl "tclspice plot #$::toplevel_count" + set .tclspice$::toplevel_count.dx 0 + set disp_dx 0 + set gr_n ".tclspice$::toplevel_count" + + # create drop down menu + pack [ frame .tclspice$::toplevel_count.f ] -side top -fill both + + # create trace and place slot info bar - bottom + pack [ frame .tclspice$::toplevel_count.tracePlaceInfoBar -background grey ] -side bottom -fill x + + # create frame for graph & trace and place + pack [frame $tl.scope ] -side bottom -expand 1 -fill both + pack [ frame $tl.scope.tp -background grey ] -side left -fill both + + # create blt graph + set ::graph_to_use [blt::graph $tl.scope.g -width 1000 -height 200] ;#- .g + $::graph_to_use grid configure -hide no -dashes { 4 4 } ;#- Add a grid + $::graph_to_use crosshairs on ;# -crosshairs + pack $::graph_to_use -expand 1 -fill both -side right ;#- show it + + #graph axis config + $::graph_to_use axis configure x \ + -command graph_Y_axis_callback \ + -subdivisions 2 + + # graph legend config + $::graph_to_use legend configure -activerelief raised + + # graph legend active on button 3 + $::graph_to_use legend bind all { %W legend activate [%W legend get current] } + $::graph_to_use legend bind all { %W legend deactivate [%W legend get current]} + + # creates the drag and drop packet for each of the plots in the legend + blt::drag&drop source $::graph_to_use -packagecmd {make_package %t %W } -button 1 + set token [blt::drag&drop token $::graph_to_use -activebackground blue ] + pack [ label $token.label -text "" ] + + # highlights the nearest traces to the cursors legend + $::graph_to_use element bind all { + %W legend activate [%W element get current] + TracePlace_set_scale_y2 %W [%W element get current] + } + $::graph_to_use element bind all { %W legend deactivate [%W element get current] } + + + # zoom controls + #set ::zoom_selected($tl.scope.g) 0 + #bind $tl { set ::zoom_selected(%W) 1 ; puts "zoom on $::zoom_selected(%W)" } + #bind $tl { set ::zoom_selected(%W) 0 ; puts "zoom off $::zoom_selected(%W)"} + + # zoom controls + ZoomStack $::graph_to_use Shift-Button-1 Shift-Button-3 + + + #make a bindng for mouse motion etc + # bind $::graph_to_use { tclspice_button_handler 1 %W %x %y } + # bind $::graph_to_use { tclspice_button_handler 2 %W %x %y } + bind $::graph_to_use { tclspice_button_handler 3 %W %x %y } + bind $::graph_to_use { tclspice_motion_handler %W %x %y } + + + # button 2 pop up menu + bind $::graph_to_use { + tclspice_button_handler 2 %W %x %y + } + + # + $::graph_to_use legend bind all { %W legend activate [%W legend get current] } + $::graph_to_use legend bind all { %W legend deactivate [%W legend get current]} + + set ::trace_place_selected($tl.scope.g) 0 + + # -- menu [ options ] + pack [ menubutton .tclspice$::toplevel_count.f.options -text "options" -menu .tclspice$::toplevel_count.f.options.m ] -side left + set options_menu [menu .tclspice$::toplevel_count.f.options.m -tearoff 0] + $options_menu add command -label "rename graph" -command "entry_selection_box .tclspice$::toplevel_count graph" + $options_menu add command -label "clear graph" -command "spice_gr_cleargraph $tl.scope.g" + $options_menu add command -label "save to postscript" -command "entry_selection_box .tclspice$::toplevel_count save_to_postscript" + $options_menu add checkbutton -label "Trace Place" -onvalue 1 -offvalue 0 -variable ::trace_place_selected($tl.scope.g) -command "TracePlace $tl" + $options_menu add command -label "close" -command { exit } + + # -- menu [ traces ] + pack [ menubutton .tclspice$::toplevel_count.f.traces -text "traces" -menu .tclspice$::toplevel_count.f.traces.m ] -side left + set traces_menu [menu .tclspice$::toplevel_count.f.traces.m -tearoff 0 ] + $traces_menu add command -label "Add/remove traces" -command "trace_selection_box update $tl.scope.g" + $traces_menu add cascade -label "Remove trace" -menu $traces_menu.remove_plot + $traces_menu add command -label "Update traces" -command "spice_update_traces $tl.scope.g" + menu $traces_menu.remove_plot -tearoff 0 -postcommand "create_remove_plot_menu $tl $traces_menu" + + + #------------------------------------------------------------------------------------------------------------- + proc create_remove_plot_menu {tl traces_menu } { + $traces_menu.remove_plot delete 0 last ;# - clear the old list + # add the current traces + + # repalce the traces in alphabetical order + set trace_list [ lsort -dictionary [$tl.scope.g element names] ] + + foreach trace $trace_list { + $traces_menu.remove_plot add command -label $trace -command "$tl.scope.g element delete $trace" + } + } + #-------------------------------------------------------------------------------------------------------------- + + + set ::graph_dx($tl) 0.00000000000000 + set ::graph_dy($tl) 0.00000000000000 + set ::graph_x1($tl) 0.00000000000000 + set ::graph_y1($tl) 0.00000000000000 + set ::graph_x2($tl) 0.00000000000000 + set ::graph_y2($tl) 0.00000000000000 + + # measurements + pack [ label $tl.f.dyv -textvariable graph_dy($tl) -background "lightgrey" -width 16 ] -side right + pack [ label $tl.f.dy -text "dy :" -background "lightgrey" ] -side right + bind $tl.f.dyv { regexp {(.[0-9A-z]+)} %W temp; puts "dy : $::graph_dy($temp)"} + + pack [ label $tl.f.dxv -textvariable graph_dx($tl) -background "grey" -width 16 ] -side right + pack [ label $tl.f.dx -text "dx : " -background "grey" ] -side right + bind $tl.f.dxv { regexp {(.[0-9A-z]+)} %W temp; puts "dx : $::graph_dx($temp)"} + + pack [ label $tl.f.y2v -textvariable graph_y2($tl) -background "lightgrey" -width 16 ] -side right + pack [ label $tl.f.y2 -text "y2 :" -background "lightgrey"] -side right + bind $tl.f.y2v { regexp {(.[0-9A-z]+)} %W temp; puts "y2 : $::graph_y2($temp)"} + + pack [ label $tl.f.y1v -textvariable graph_y1($tl) -background "grey" -width 16] -side right + pack [ label $tl.f.y1 -text "y1 :" -background "grey" ] -side right + bind $tl.f.y1v { regexp {(.[0-9A-z]+)} %W temp; puts "y1 : $::graph_y1($temp)"} + + pack [ label $tl.f.x2v -textvariable graph_x2($tl) -background "lightgrey" -width 16 ] -side right + pack [ label $tl.f.x2 -text "x2 :" -background "lightgrey" ] -side right + bind $tl.f.x2v { regexp {(.[0-9A-z]+)} %W temp; puts "x2 : $::graph_x2($temp)"} + + pack [ label $tl.f.x1v -textvariable graph_x1($tl) -background "grey" -width 16 ] -side right + pack [ label $tl.f.x1 -text "x1 :" -background "grey" ] -side right + bind $tl.f.x1v { regexp {(.[0-9A-z]+)} %W temp; puts "x1 : $::graph_x1($temp)"} + + + # clear out old stuff + spice_gr_cleargraph $::graph_to_use ;#- zap the old text and re-initialise the + + add_traces $::graph_to_use $args + + #save the plot line in a variable so it can be run again - e.g. when gui restarted + set "::${::graph_to_use}_plotlist" [subst $args] ;#- expand as argument + ## no good becasue traces can be added and removed + # XXXXXXXXXx + + # used to speed up y2axis, not recalcing the same slot twice + set ::trace_place_y2axis_slot($::graph_to_use) "" + set ::trace_place_y2axis_zoom($::graph_to_use) "" + + incr ::toplevel_count ;#- move to next toplevel + +} + +#--------------------------------------------------------------------------------------------------------------------------- + +proc spice_update_traces { graph { mode "" } { trace_list ""} } { + + # -- mode -- + # - "remove" - removes traces in list from scope + # - "add" - add traces in list to scope + # - "update" - replaces the traces displayed with given list + # - "" - just update the current traces in the graph + + + set scope_trace_list [ $graph element names ] + + # traces are been 'added' or 'removed' + if { ( $trace_list != "") && ($mode != "") } { + + if { $mode == "remove" } { + foreach trace $trace_list { + if { [ $graph element exists $trace ] } { $graph element delete $trace } + } + } + + if { $mode == "add" } { + foreach trace $trace_list { + if { [ $graph element exists $trace ] == 0 } { $graph element create $trace } + } + } + + # new scope list + set scope_trace_list [ $graph element names ] + + if { $mode == "update" } { + # this just replaces the plot list with list passed + set scope_trace_list { } + set scope_trace_list $trace_list + } + + } + + # removes all the traces + foreach trace [ $graph element names ] { $graph element delete $trace } + + # repalce the traces in alphabetical order + set trace_list [ lsort -dictionary $scope_trace_list ] + + foreach trace $trace_list { $graph element create $trace } + + #----------------------------------------------------------------- + proc spice_trace_list_position { graph trace } { + + set trace_list [ lsort -dictionary [ $graph element names ] ] + set list_position [lsearch $trace_list $trace] + + if { $list_position == -1 } { return -1 } + + return $list_position + } + #----------------------------------------------------------------- + + # colour selection not correct + + # delete all the old vectors - replace with new values + foreach vector_name [ blt::vector names ::$graph\_trace_* ] { blt::vector destroy $vector_name } + + # retrieves the time vector + blt::vector create _time + spice::spicetoblt time _time 0 [ expr \$::spice::steps_completed - 1] + + set index 0 + foreach trace_name [ $graph element names ] { + + # if a saved trace that has been pre run + if { [ regexp {_OLD} $trace_name ] } { + + set saved_plots_file [ open "$::spicefilename.gui_plots.tcl" "r"] + set trace_name_old "$trace_name\_OLD" + gets $saved_plots_file string + + while { [eof $saved_plots_file ] == 0} { + if { [ regexp $trace_name $string] } { + foreach xy { x y } { + + set start [ string first " : " $string ] + set string [ string range $string [ expr $start + 3 ] end ] + + if { $xy == "x" } { _time set "$string "} + if { $xy == "y" } { + blt::vector create _vector + _vector set "$string" + } + gets $saved_plots_file string + } + } + gets $saved_plots_file string + } + + close $saved_plots_file + + set symbol "" + + } else { + + # get the new trace values + blt::vector create _vector + spice::spicetoblt $trace_name _vector 0 [ expr \$::spice::steps_completed - 1] + + set symbol "circle" + } + + #create an element on the graph called $Yname using the X and Y vectors + #-choose colour etc + if { [info exists ::linecolour($trace_name)] } { + set colour $::linecolour($trace_name) ;#- if specific colour assigned to the trace + } elseif { [info exists ::linecolour($index)] } { + set colour $::linecolour($index) ;#- if within number of traces + } else { + + # set colour $::linecolour(default) + # creates a random colour + set randred [format "%03x" [expr {int (rand() * 4095)}]] + set randgreen [format "%03x" [expr {int (rand() * 4095)}]] + set randblue [format "%03x" [expr {int (rand() * 4095)}]] + set colour "#$randred$randgreen$randblue" + } + + set ::linecolour($trace_name) $colour ;# saves the traces colour + + $graph element configure $trace_name \ + -ydata "$_vector(:)" \ + -xdata "$_time(:)" \ + -symbol $symbol \ + -linewidth 2 \ + -pixels 3 \ + -color $colour + + blt::vector create $graph\_trace_Y[ spice_trace_list_position $graph $trace_name ] + blt::vector create $graph\_trace_X[ spice_trace_list_position $graph $trace_name ] + + _time dup $graph\_trace_X[ spice_trace_list_position $graph $trace_name ] + _vector dup $graph\_trace_Y[ spice_trace_list_position $graph $trace_name ] + + blt::vector destroy _vector + + incr index + } + + # update the trace and place grid + TracePlace_update $graph + +} + +#----------------------------------------------------------------------------------------------------------------------------- +# creates temp vectors for 'trace' + +proc spice_return_trace_vectors { graph trace } { + + # delete any old temp value created by this procedure + foreach vector [ blt::vector names temp_vector_* ] { blt::vector destroy $vector } + + # valid trace + if { [ $graph element exists $trace ] != 1 } { return -1 } + + set list_position [ spice_trace_list_position $graph $trace ] + + $graph\_trace_X$list_position dup temp_vector_X + $graph\_trace_Y$list_position dup temp_vector_Y + + return 1 + +} + +#------------------------------------------------------------------------------------------------------------------ +# called from pop up menu, when mouse over active trace + +proc TracePlace_remove_trace_from_slot { window } { + + # called from pop up menu when mouse over a trace on the screen "remove a1_x1_y0" + + regexp {(.[0-9A-z]+)} $window window_clean + set graph "$window_clean.scope.g" + set tracePlace_w "$window_clean.scope.tp.ft.tracePlaceGrid" + + # exits if none of the legends are active + if { [$graph legend activate] == "" } { return } + + # exits if trace and place is not active + if { $::trace_place_selected($graph) == 0 } { return } + + # get the current trace + set trace [ $graph legend activate ] + + set slot_col -1 + + # runs through all the slot lists and removes trace + for {set col_cnt 0 } {$col_cnt <= $::columns} {incr col_cnt } { + for {set row_cnt 0} { $row_cnt <= [ expr (pow(2, $col_cnt) -1) ] } {incr row_cnt } { + + if { [ lcontain $::slot_trace_list($tracePlace_w.f_$col_cnt\_$row_cnt.b) $trace ] } { + + set slot_col $col_cnt + set slot_row $row_cnt + + set string_start [ string first $trace $::slot_trace_list($tracePlace_w.f_$col_cnt\_$row_cnt.b) ] + set string_finish [ expr $string_start + [ string length $trace ] - 1] + set ::slot_trace_list($tracePlace_w.f_$col_cnt\_$row_cnt.b) [ string replace $::slot_trace_list($tracePlace_w.f_$col_cnt\_$row_cnt.b) $string_start $string_finish "" ] + + } + } + } + + # exits if trace is not in any list + if { $slot_col == -1 } { return } + + # removes the trace from scope , drops the legend relief + $graph element configure $trace -labelrelief flat + $graph element configure $trace -hide 1 + + # removes trace from traceplace info bar bottom + if { [$window_clean.tracePlaceInfoBar.fakeGraph element exists $trace ] } { $window_clean.tracePlaceInfoBar.fakeGraph element delete $trace } + + # update the slots canvas markers + TracePlace_update_slot_canvas_markers $tracePlace_w $slot_col $slot_row +} + +#------------------------------------------------------------------------------------------------------------- +# creates a drag and drop package + +proc make_package {token graph { args ""} } { + + regexp {(.[0-9A-z]+)} $graph scope_name + set scope_name "$scope_name.scope.g" + + + # exits if trace and place is not active + if { $::trace_place_selected($scope_name) == 0 } { return } + + # case where a trace place slot is selected - for all slots traces to be moved to another slot + if { $args == "tracePlaceGrid" } { + set list $::slot_trace_list($graph) + set list_length [llength $list] + + if { $list_length == 0 } { return } + + if { $list_length == 1 } { + + # removes all the " " at the end of the string + while { [ string range $list [ expr [ string length $list] -1] [ expr [ string length $list] -1] ] == " " } { + set list [ string range $list 0 [ expr [ string length $list] - 2] ] + } + + # removes all the " " at the start of the string + while { [ string range $list 0 0 ] == " " } { + set list [ string range $list 1 [ expr [ string length $list] - 1] ] + } + + $token.label configure -text $list -background [ $scope_name element cget $list -color ] -height 1 + + } else { + # more than one trace in the box + $token.label configure -text "Traces" -background green -height 1 + } + return [list $list] + } + + # exits if none of the legends are active + if { [$graph legend activate] == "" } { return } + + $token.label configure -text [$graph legend activate] -background [ $scope_name element cget [$graph legend activate ] -color ] -height 1 + + return [ $graph legend activate ] +} + + +#------------------------------------------------------------------------------------ +#BOTH buttons 1 & 2 +proc tclspice_button_handler { button widget x y } { + + #get realcoords from pix + set xreal [$widget axis invtransform x $x] + set yreal [$widget axis invtransform y $y] + + # pop up box for markers + if {$button == 2} { + pop_up_menu $widget $x $y + } + +} + + +#-------------------------------------------------------------------------------------- +# +proc add_traces { graph args } { + + regexp {(.[0-9A-z]+)} $graph window_name + set graph_w "$window_name.scope.g" + + while { [ string range $args 0 0 ] == "\{" } { + set args [ string range $args 1 [ expr [ string length $args] - 1] ] + } + + while { [ string range $args [ expr [ string length $args] - 1] [ expr [ string length $args] - 1] ] == "\}" } { + set args [ string range $args 0 [ expr [ string length $args] - 2] ] + } + + puts "list add : $args" + + # blt plots need re work so that there are more than 6 colours then grey + # spice::bltplot $args + spice_update_traces $graph_w add $args + +} + + + +#----------------------------------------------------------------------------------------- + +proc update_traces { widget trace_list } { + spice_update_traces $widget update $trace_list +} + +#----------------------------------------------------------------------------------------------- +proc remove_traces {widget trace } { + spice_update_traces $widget remove $args +} + +#----------------------------------------------------------------------------------------------------- +set ::pop_up_menu "normal_mode" +set ::disp_zoom_level 0 + +#------------------------------------------------------------------------------------------------------- +# creates the pop up menu + +proc pop_up_menu { widget x y } { + global disp_zoom_level + + regexp {(.[0-9A-z]+)} $widget window_name + + # returns if not over trace + if { [ $window_name.scope.g legend activate] == "" } { return } + + set xreal $x + set yreal $y + + catch {destroy .markerEntry } ;# destroy old entry box + catch {destroy .m} ;# destroy old pop up + menu .m -tearoff 0 + + .m add command -label "Remove [ $window_name.scope.g legend activate]" -command "TracePlace_remove_trace_from_slot $window_name" + + .m add command -label "scale" -command "TracePlace_set_scale_y2 $window_name.scope.g [ $window_name.scope.g legend activate]" + + .m add command -label "triggerpoints" + + scan [wm geometry $window_name ] "%dx%d+%d+%d" width height xpos ypos + set info_bar_y [ winfo height $window_name.f ] + set trace_place_offset_x [ winfo x $window_name.scope.g ] + + tk_popup .m [expr $xpos + $x + $trace_place_offset_x] [expr $ypos + $y + $info_bar_y + $info_bar_y] "" + +} + +#------------------------------------------------------------------------------------------------------------------------ +# set up the y axis when using trace and place +# + +proc TracePlace_set_scale_y2 {graph { trace ""}} { + + # makes sure that a trace is passed + if { $trace == "" } { puts "no trace passed" ; return } + + # exits if trace and place is not active + if { $::trace_place_selected($graph) == 0 } { return } + + regexp {(.[0-9A-z]+)} $graph window_clean + set tracePlace_w "$window_clean.scope.tp.ft.tracePlaceGrid" + + # searches to which list the trace is from + set slot_col -1 + for {set col_cnt 0 } {$col_cnt <= $::columns} {incr col_cnt } { + for {set row_cnt 0} { $row_cnt <= [ expr (pow(2, $col_cnt) -1) ] } {incr row_cnt } { + if { [ lcontain $::slot_trace_list($tracePlace_w.f_$col_cnt\_$row_cnt.b) $trace ] } { + set slot_col $col_cnt + set slot_row $row_cnt + } + } + } + if { $slot_col == -1 } { return } + + # global variable that keeps track of which slot the scale is based on + # should speed up cutting out the resizeing below + + if { ($::trace_place_y2axis_slot($window_clean.scope.g) == "$slot_col\_$slot_row") + && + ($::trace_place_y2axis_zoom($window_clean.scope.g) == "[ $graph yaxis cget -min ]_[ $graph yaxis cget -max ]") } { return } + + set ::trace_place_y2axis_slot($window_clean.scope.g) "$slot_col\_$slot_row" + # set ::trace_place_y2axis_zoom($window_clean.scope.g) "$yaxis_min_$yaxis_max" + + + # calculates maximum and minimum value of trace + set trace_max_value 0 + set trace_min_value 0 + + # runs through all traces on screen within the slot to find make + foreach trace_m $::slot_trace_list($tracePlace_w.f_$slot_col\_$slot_row.b) { + + # trace is not displayed on screen + if { [ $window_clean.scope.g element cget $trace_m -hide ] == 1 } { continue } + + spice_return_trace_vectors $window_clean.scope.g $trace_m + + #$window_clean.scope.g_$trace_m dup temp + #set data_list_length [$window_clean.scope.g_$trace_m length] + set data_list_length [temp_vector_Y length] + + for { set i 0 } { $i < $data_list_length } { incr i } { + + if { [ temp_vector_Y index $i ] > $trace_max_value } { set trace_max_value [ temp_vector_Y index $i ] } + if { [ temp_vector_Y index $i ] < $trace_min_value } { set trace_min_value [ temp_vector_Y index $i ] } + } + + } + + # $window_clean.scope.g_$trace dup temp + # set data_list_length [$window_clean.scope.g_$trace length] + # needed ??????????????? + spice_return_trace_vectors $window_clean.scope.g $trace + set data_list_length [temp_vector_Y length] + + # slots start and finish position + set dimensions [ TracePlace_slot_dimension $graph $slot_col $slot_row ] + set slot_start_position [lindex $dimensions 0] + set slot_finish_position [lindex $dimensions 1] + + # displays second axis + $graph y2axis configure -hide 0 + + set yaxis_min [ $graph yaxis cget -min ] + set yaxis_max [ $graph yaxis cget -max ] + + # calculates the axis scale + #if { $trace_min_value < 0 } { set temp_min [ expr $trace_min_value * -1 ] } else { set temp_min $trace_min_value } + set trace_min_value $trace_min_value + set scale_factor [ expr ( $trace_max_value - $trace_min_value) / ( $slot_finish_position - $slot_start_position )] + if { $trace_min_value == 0 } { set trace_min_value 0.000001 } + set scale_min [ expr $trace_min_value - ( $slot_start_position * $scale_factor)] + set scale_max [ expr $trace_max_value + ( (100 - $slot_finish_position ) * $scale_factor) ] + + $graph y2axis configure -min $scale_min -max $scale_max + + # need to take into consideration also when zoomed in + set yaxis_min [ $graph yaxis cget -min ] + set yaxis_max [ $graph yaxis cget -max ] + + # zoom level 1:1 + if { [ expr int ($yaxis_max - $yaxis_min) ] ==100 } { return } + + set ::trace_place_y2axis_zoom($window_clean.scope.g) "$yaxis_min\_$yaxis_max" + + set y2axis_min [ $graph y2axis cget -min ] + set y2axis_max [ $graph y2axis cget -max ] + set scale_factor [ expr 100 / ( $y2axis_max - $y2axis_min ) ] + set scale_min [ expr $y2axis_min + ( $yaxis_min / $scale_factor )] + set scale_max [ expr $y2axis_min + ( $yaxis_max / $scale_factor ) ] + + $graph y2axis configure -min $scale_min -max $scale_max + +} +#----------------------------------------------------------------------------------------------------- +# creates a widget to enter names 'rename graph' & 'name of postscript file' + +proc entry_selection_box {window_name mode {xreal "" } {yreal ""} } { + + scan [wm geometry $window_name ] "%dx%d+%d+%d" width height xpos ypos + catch {destroy .markerEntry } + toplevel .markerEntry + wm geometry .markerEntry 300x70+[expr $xpos + ($width / 2 ) - 150]+[expr $ypos + ($height /2) - 35] ;# position in centre + + set ::temp_window_name $window_name + + #----- + if {$mode == "graph" } { + + wm title .markerEntry "Rename Graph" + + pack [ label .markerEntry.l -text "Enter text:" ] -fill x + pack [ entry .markerEntry.e -textvariable ::marker_entry_text -background white ] -fill x + set ::marker_entry_text [wm title $window_name] + + pack [ button .markerEntry.b -text "OK" -command {wm title $::temp_window_name $marker_entry_text ; catch {destroy .markerEntry } } ] + + bind .markerEntry.e {wm title $::temp_window_name $marker_entry_text ; catch {destroy .markerEntry } } + + focus -force .markerEntry.e + } + + #----- + if {$mode == "save_to_postscript" } { + + wm title .markerEntry "Save to postscript" + + pack [ label .markerEntry.l -text "Enter file name:" ] -fill x + pack [ entry .markerEntry.e -textvariable ::marker_entry_text -background white ] -fill x + set ::marker_entry_text "temp.ps" + + pack [ button .markerEntry.b -text "OK" -command { postscript_bw $::temp_window_name.scope.g $marker_entry_text ; catch {destroy .markerEntry } } ] + + bind .markerEntry.e { postscript_bw $::temp_window_name.g $marker_entry_text ; catch {destroy .markerEntry } } + focus -force .markerEntry.e + } + +} + +#----------------------------------------------------------------------------------------------- + +proc tclspice_motion_handler { widget x y } { + + # puts $widget + # puts $x + # puts $y + # puts [$widget axis invtransform x $x] + # [%W axis invtransform x %x] +} + +#----------------------------------------------------------------------------------------------------------- +#blt calls this back when doing the ticks --- replace the floating value with an engineering value +proc graph_Y_axis_callback { widget value } { + return [ float_eng_spice $value] +} + +#------------------------------------------------------------------------------------------------------------- + + +######################################################################## +# Postscript +# +######################################################################## + +#Changes to b/w, removes marker points etc +proc postscript_bw { graph_name filename } { + + #make bw with dashes instead of colours + postscript_make_bw $graph_name + postscript_add_dashes $graph_name + + #postscript + $graph_name postscript output $filename + + foreach trace_bw [ $graph_name element names ] { + $graph_name line configure $trace_bw -symbol {} ;#- turn off symbols + $graph_name line configure $trace_bw -color black ;#- turn to black + } +} + +#---------------------------------------------------------------------------------------------- +#replaces colours with black + +proc postscript_make_bw { graph_name } { + + foreach trace_bw [ $graph_name element names ] { + $graph_name line configure $trace_bw -symbol {} ;#- turn off symbols + $graph_name line configure $trace_bw -color black ;#- turn to black + } +} + +#--------------------------------------------------------------------------------------------------- +#replaces colours with dashes + +proc postscript_add_dashes { graph_name } { + + set tracecnt 0 + + #scan through traces on the graph + foreach trace_bw [ $graph_name element names ] { + + #-dashlist etc - either a specific one, or the incremental one + if { [info exists ::dashlist($trace_bw)] } { + set dashes $::dashlist($trace_bw) ;#- if specific dash assigned to the trace + } elseif { [info exists ::dashlist($tracecnt)] } { + set dashes $::dashlist($tracecnt) ;#- if within number of traces + } else { set dashes $::dashlist(default) } + + $graph_name line configure $trace_bw -dashes $dashes + + incr tracecnt + } +} + + + + + +#-------------------------------------------------------------------------------------------------------- +#Routine to clear out the graph ready for re-plotting +proc spice_gr_cleargraph { graph_name } { + + global disp_zoom_level + set ::trace_index_counter 0 ;#- clear the count + + # returns graph to zoom 1:1 + if {$disp_zoom_level >0} { + Zoom1:1 $graph_name + } + + #remove old traces + foreach trace_to_zap [ $graph_name element names ] { + $graph_name element delete $trace_to_zap + } + + #remove old markers + foreach trace_to_zap [ $graph_name marker names ] { + $graph_name marker delete $trace_to_zap + } + + # remove vectors associated with traces + +} + +#----------------------------------------------------------------------------------------------------- + +# spice::bltplot callback handler --- comes here with each pair of vectors, can +# +# On entry:- +# +# ::graph_to_use - is the destination blt::graph - set before issuing the spice::bltplot command +# ::linecolour("tracename") - hash for colour lookup e.g linecolour(A0) might be red +# +# ?name - name of trace +# ?type - type e.g. voltage current time +# ?units - e.g. amp second +# +# ::spice::X_data - X axis data - for this pair of values +# ::spice::Y_data - Y axis data +# +# On return:- +# +# global blt vectors "::${graph_to_use}_X0...?" has the trace number in for X, similar for Y. +# e.g. ::.g_Y0 etc exist +# +# global list of spice vectors "::${graph_to_use}_plotlist gets e.g. Q0 Q1 etc on it +# - used to do re-plot when gui restored +# +# blt graph $::graph_to_use will have elements of the names of the Y trace of spice + + + +# not used +proc spice_gr_Plot { Xname Xtype Xunits Yname Ytype Yunits } { + + puts "$Xname $Xtype $Xunits $Yname $Ytype $Yunits " + + #set vector names + set xvect_name "::${::graph_to_use}_X$::trace_index_counter" + set yvect_name "::${::graph_to_use}_Y$::trace_index_counter" + + + #copy global to new vectors + #- creates e.g. ::vect_time for time + blt::vector create $xvect_name + $xvect_name set $::spice::X_Data(:) + + #- creates e.g. ::vect_a0 for a0 + blt::vector create $yvect_name + $yvect_name set $::spice::Y_Data(:) + + #create an element on the graph called $Yname using the X and Y vectors + #-choose colour etc + if { [info exists ::linecolour($Yname)] } { + set colour $::linecolour($Yname) ;#- if specific colour assigned to the trace + } elseif { [info exists ::linecolour($::trace_index_counter)] } { + set colour $::linecolour($::trace_index_counter) ;#- if within number of traces + } else { + # set colour $::linecolour(default) + + # creates a random colour + set randred [format "%03x" [expr {int (rand() * 4095)}]] + set randgreen [format "%03x" [expr {int (rand() * 4095)}]] + set randblue [format "%03x" [expr {int (rand() * 4095)}]] + set colour "#$randred$randgreen$randblue" + } + + #-add line + $::graph_to_use element create $Yname -xdata "$xvect_name" -ydata "$yvect_name" \ + -symbol "circle" \ + -linewidth 2 \ + -pixels 3 + + $::graph_to_use line configure $Yname -color $colour + + #-move to next colour + incr ::trace_index_counter +} + +#------------------------------------------------------------------------------------------------------------ +#handler for tclreadline - does command completion for finding the plot traces +# -see main code where this is set + +proc plot_command_readline_completer { word start end line } { + + set match {} ;#- no match found yet + set shortest_string_len 1000 ;#- will always get shorter + set matches 0 ;#- totaliser for matches + + #check for "plot" command line + if { [ regexp {\s+plot} " $line " ] } { + #found plot near the start of the line + + #check if punter is asking for a variable + if { $start >= 5 } { + + #-find the last item typed so far + set arglist [split $line " "] + set lastarg [lindex $arglist end] + + #-search against the possible spice variables + set possibility_list {} + + set varlist [spice::plot_variables 0] ;#- get current spice traces + + foreach possibility $varlist { + #check for exact match + if {$lastarg == $possibility} { + set possibility_list $possibility + break + } + + #check for close match + if { [string match "${lastarg}*" $possibility] } { + lappend possibility_list $possibility ;#- add to list + incr matches ;#-add another match + #update shortest len + if { [string length $possibility] < $shortest_string_len } { + set shortest_string_len [string length $possibility] + } + } + } + + #check for exact match + if { $lastarg == $possibility } { set match $lastarg } else { set match "" } + + #for multiple matches, find the longest common bit of string to return readline style + #-loop for each character + set done 0 + for {set charindex 0} { $charindex < $shortest_string_len } { incr charindex } { + + #-get char from one string + set char [string index [lindex $possibility_list 0] $charindex] + + #check in each of other strings for same character + for {set cnt 1} {$cnt < $matches} {incr cnt} { + + set char_alt [string index [lindex $possibility_list $cnt] $charindex] + + if {$char != $char_alt } { + #found a mismatch, so exit now + set done 1 + break + } + if { $done == 1} { break } + } + if { $done == 1} { break } + } + + #return the longest common portion which matches + set common_bit [string range [lindex $possibility_list 0] 0 [expr $charindex-1] ] + + #sort the return values into alphabetic order + set possibility_list [lsort -dictionary $possibility_list] + + #return parameters for the readline + return [list $common_bit $possibility_list] ;# + + } ;#- end of if starting at the right place + + } ;#- end of if got plot in the line + + ::tclreadline::ScriptCompleter $word $start $end $line +} + +#---------------------------------------------------------------------------------------------------- + +#Eng units stuff +set ::significant_digits 4 ;#- mininum signficant digits to show - might show more e.g. 125 will be shown no matter what + +#lookup hashes +set ::table_eng_float_MSC(T) 1e+12 +set ::table_eng_float_MSC(G) 1e+9 +set ::table_eng_float_MSC(M) 1e+6 +set ::table_eng_float_MSC(K) 1e+3 +set ::table_eng_float_MSC(\n) 1; # Will need to change? +set ::table_eng_float_MSC(m) 1e-3 +set ::table_eng_float_MSC(u) 1e-6 +set ::table_eng_float_MSC(\u03BC) 1e-6 +set ::table_eng_float_MSC(n) 1e-9 +set ::table_eng_float_MSC(p) 1e-12 +set ::table_eng_float_MSC(f) 1e-15 +set ::table_eng_float_MSC(a) 1e-18 + +#inverse hash +set ::table_float_eng_MSC(1e+12)" T" +set ::table_float_eng_MSC(1e+9) " G" +set ::table_float_eng_MSC(1e+6) " M" +set ::table_float_eng_MSC(1e+3) " K" +set ::table_float_eng_MSC(1) " " +set ::table_float_eng_MSC(1e-3) " m" +set ::table_float_eng_MSC(1e-6) " \u03BC" +set ::table_float_eng_MSC(1e-9) " n" +set ::table_float_eng_MSC(1e-12) " p" +set ::table_float_eng_MSC(1e-15) " f" +set ::table_float_eng_MSC(1e-18) " a" + +#----------------------------------------------------------------------------------------------------------- +# Returns best abbreviated number from a real input +proc float_eng_spice {num {forceunit ""} } { + + #On entry, forceunit can be u,p whatever as an option to force the result + # into that unit rather than the best one + # Or, can be "1" + + + #30/5/02 - force the unit and return no decimal places if force is on + if { $forceunit != "" } { + + if { $forceunit == "1" } { + + return [format %.0f $num ] ;#- just return the number + } else { + #-fixed suffix + set multiplier $::table_eng_float_MSC($forceunit) ;#- look up number from the suffix + } + + if { $forceunit == "u" } { set forceunit "\u03BC" } ;#- use the nicer u figure + + #zero decimal places + set returnval "[format %.0f [expr $num / $multiplier]] $forceunit"; + return $returnval + } + #end 30/5/02 + + #Normal operation... + + set indexes [lsort -real -decreasing "[array names ::table_float_eng_MSC]"] + + set out {}; # If no suffix found, return number as is + + if "$num != 0" { + foreach index $indexes { + + set newnum "[expr {$num / $index}]" + set whole 0 + set fraction 0; # In case of integer input + + # regexp {^(\d+)} $newnum whole; # Messy! + # Uses stupid variable to save having to do two regexp's + regexp {^(\d+)\.*(\d*)} $newnum stupid whole fraction + + if {[expr {[string match {*e*} $newnum] == 0}] && \ + [expr {$whole >0 }] } { + set suf "$::table_float_eng_MSC($index)" + + #work out how many decimal places to show - fixed to 4 significant digits + set decimal_length_to_show [ expr ( ($::significant_digits - 1 ) - [ string length $whole ] ) ] + if { $decimal_length_to_show >= 0 } { + + if { $fraction == "" } { + set newnm $whole + } else { + #need some decimal places to give the resolution required + set newnum "$whole.[string range $fraction 0 [ expr ($decimal_length_to_show)] ]" + } + + } else { + #no decimal places + set newnum $whole ;#- just use the whole, no decimals + } + + set out "$newnum$suf" + return "$out" + break + } else { + #puts "[expr {fmod($newnum,1)}] is not big enough" + } + } + } + if {[string equal $out {}]} { + #puts {Appropriate suffix not found} + return $num + } +} + + +#------------------------------------------------------------------------------------------------------------ + +set ::spice_run 0 ;#- not yet run +set ::spicefilename "" ;#- complete name of spice file + +#------------------------------------------------------------------------------------------------------------- +#Initialises the gui +proc spice_init_gui { spicefile } { + + #load spice file if given + if { $spicefile != "" } { + + # test if 'spicefile' is a project + if { [regexp {.swp} $spicefile] } { + + # unpacks the project + project_open $spicefile + + # generates list of project files + set file_list [ project_file_list $spicefile ] + + for { set i 0 } { $i < [ llength $file_list ] } { incr i } { + + set file_name [ lrange $file_list $i $i ] + + # searches for the circuit file + if { [ string range $file_name end-3 end] == ".cir" } { + set ::spicefilename $file_name ;#- save name + } + } + + # no spice file found + if { $::spicefilename == ""} { error "no spice file found in project"} + + + + } else { + + set ::spicefilename $spicefile ;#- save name + } + + spice::source $::spicefilename + wm title . "spicewish - $spicefile" + } + + #pack the gui + pack [ frame .control_butts] -side left -anchor n + + pack [ button .control_butts.b_stop -text "STOP " -command { spice::stop }] -fill x + + pack [ button .control_butts.b_go -text "GO" -command { + if { $spice_run == 0 } { + spice::bg run + set spice_run 1 ;#- has now run once, so next time resume + } else { spice::bg resume } + }] -fill x + + pack [ button .control_butts.b_plot -text "Plot" -command "trace_selection_box"] -fill x + + # pack [ button .control_butts.b_savegui -text "Savegui" -command { save_all_nutmeg_windows }] -fill x + + # pack [ button .control_butts.b_restgui -text "Restorgui" -command { restore_all_nutmeg_windows } ] -fill x + + pack [ button .control_butts.b_notes -text "Edit" -command {edit_window } ] -fill x + + pack [ button .control_butts.b_saveProject -text "Save Pro" -command { project_save $::spicefilename }] -fill x + + pack [ button .control_butts.b_quit -text "Quit" -command { exit }] -fill x + + # replots scopes if opening a project file + if { [regexp {.swp} $spicefile] } { restore_all_nutmeg_windows } + +} + +###################################################################### +# editing - spice file - project notes +# +###################################################################### + +proc edit_window { } { + + if { [ winfo exists .edit] } { + pack .edit + } else { + + pack [ frame .edit ] -expand 1 -fill both + blt::tabnotebook .edit.tnb + + set count 0 + foreach tab { "spice_file" "project_notes"} { + + .edit.tnb insert end -text [ string totitle $tab ] + .edit.tnb configure -tearoff 0 + + pack [ frame .edit.tnb.$tab ] -expand 1 -fill both + .edit.tnb tab configure $count -window .edit.tnb.$tab -fill both + + pack [ frame .edit.tnb.$tab.buttons ] -side bottom + + if { $tab == "spice_file" } { + set ::text_search 0 + set ::text_string "" + pack [ entry .edit.tnb.$tab.buttons.search_entry -background white -textvariable ::text_string] -side left + pack [ checkbutton .edit.tnb.$tab.buttons.search_select -variable ::text_search -command edit_text_search ] -side left + } + + pack [ button .edit.tnb.$tab.buttons.b_cancel -text "Close" -command "pack forget .edit"] -side left + pack [ button .edit.tnb.$tab.buttons.b_save -text "Save" -command "save_file_from_text .edit.tnb.$tab.text $tab"] -side left + + if { $tab == "spice_file" } { + pack [ button .edit.tnb.$tab.buttons.b_reRun -text "Re Run" -command reRun ] -side left + } + + #----------------------------------------------- + proc reRun { } { + + save_all_nutmeg_windows reRun + spice::halt + spice::stop + spice::reset + spice::source $::spicefilename + + after 100 + + set ::spice_run 0 + restore_all_nutmeg_windows + } + #------------------------------------------------ + + pack [ scrollbar .edit.tnb.$tab.scroll -command ".edit.tnb.$tab.text yview" ] -side right -fill y + pack [ text .edit.tnb.$tab.text -background white -yscrollcommand ".edit.tnb.$tab.scroll set"] -expand 1 -fill both ;# pack last due top resizing + + + # load the text file + if { $tab == "spice_file" } { + load_file_to_text .edit.tnb.$tab.text $::spicefilename + .edit.tnb.$tab.text configure -background LemonChiffon + edit_highlight_spicevariables .edit.tnb.$tab.text + } + + if { $tab == "project_notes" } { + load_file_to_text .edit.tnb.$tab.text $::spicefilename.project_notes.txt + } + + incr count + } + pack .edit.tnb -fill both -expand 1 + } +} + +#------------------------------------------------------------------------------------------------------ +# saves text widget to file +proc save_file_from_text { w tab } { + + if {$tab == "project_notes" } {set filename "$::spicefilename.project_notes.txt" } + if {$tab == "spice_file" } {set filename "$::spicefilename" } + + # saves text window to .txt file + set data [$w get 1.0 {end -1c}] + set fileid [open $filename w] + puts -nonewline $fileid $data + close $fileid +} + +#----------------------------------------------------------------------------------------------------------- +# loads files into a text widget +proc load_file_to_text {w file} { + + # test if file exsists + if { [ file exists $file ] == 0 } { return } + + set f [open $file] + $w delete 1.0 end + while {![eof $f]} { $w insert end [read $f 10000] } + close $f +} + +#------------------------------------------------------------------------------------ +# highlight text in entry field + +proc edit_text_search { } { + + set w ".edit.tnb.spice_file.text" + + if { $::text_search == 0 } { + $w tag delete search + return + } + + $w tag remove search 0.0 end + if {$::text_string == ""} { return } + set cur 1.0 + while 1 { + set cur [$w search -count length $::text_string $cur end] + if {$cur == ""} { break } + + $w tag add search $cur "$cur + $length char" + set cur [$w index "$cur + $length char"] + + $w tag configure search -foreground white + $w tag configure search -background red + } +} + +#------------------------------------------------------------------------------------------- +# searches through the text highlighting 'strings' with passed 'colour' + +proc text_search {w string colour} { + + # string passes the starting character eg "c" for capacitors + + set tag $string + $w tag remove search 0.0 end + + if {$string == ""} { return } + + set start 1.0 + while 1 { + set start [$w search -count length $string $start end] + if {$start != "" } { + + # returns the position of the next " " + set finish [$w search -count length " " $start [expr $start + 1 ]] + + if {( $start == "") || ($finish =="")} { + break + + } else { + + # ad call + # doesn't seem to work for the L becuase they go overf two lines this crashes this + # need to test if the start anf finish are on the same line + + regexp {([0-9]+).([0-9]+)} $finish finish_match finish_row finish_col + + set valid 1 + + # if start character not at start of line + + regexp {([0-9]+).([0-9]+)} $start start_match start_row start_col + + if { $start_match == $start } { + if { $start_col != 0 } { + + if { [ $w get "$start_row.[ expr $start_col - 1]" ] != " " } { set valid 0 } + } + } + + # test that start and finish are on the same line + if { $start_row != $finish_row } { set valid 0 } + + if { $valid == 1 } { + # set text passed colour between + $w tag add $tag $start $finish + $w tag configure $tag -foreground $colour + } + } + + + } else { break } + + + # error trap + # previous character must == "" // beging of line f + + set start [$w index "$start + $length char"] + + } +} + +#-------------------------------------------------------------------------------------- + +proc edit_highlight_spicevariables { w } { + text_search $w L blue + text_search $w V red + text_search $w R green + +} + +#-------------------------------------------------------------------------------------- + +########################################################################### +# selecting traces +# +########################################################################### + +proc trace_selection_box { {args ""} {graph_name "" } } { + + + regexp {(.[0-9A-z]+)} $graph_name window_name + #set scope_name "$scope_name.scope.g" + + # error if spice not been run + if { $::spice_run == 0 } { + set error_mesage [tk_messageBox -message "Simulation not run" -type okcancel -icon error -parent . ] + return + } + + catch {destroy .trace_selection_box } + toplevel .trace_selection_box + wm title .trace_selection_box "Select Traces" + + blt::tabnotebook .trace_selection_box.tnb + pack .trace_selection_box.tnb -fill both + + set count 0 + foreach tabs { voltage current } { + + .trace_selection_box.tnb insert end -text [ string totitle $tabs] + .trace_selection_box.tnb configure -tearoff 0 + + frame .trace_selection_box.tnb.$tabs + + .trace_selection_box.tnb tab configure $count -window .trace_selection_box.tnb.$tabs + + pack [ frame .trace_selection_box.tnb.$tabs.f ] + + eval "blt::hierbox .trace_selection_box.tnb.$tabs.f.hierbox -hideroot true \ + -yscrollcommand {.trace_selection_box.tnb.$tabs.f.vert set} -xscrollcommand {.trace_selection_box.tnb.$tabs.f.vert set} -background white" + + eval "scrollbar .trace_selection_box.tnb.$tabs.f.vert -orient vertical -command {.trace_selection_box.tnb.$tabs.f.hierbox yview} -width 20 " + + .trace_selection_box.tnb.$tabs.f.hierbox insert 1 $tabs -labelfont {times 10} + .trace_selection_box.tnb.$tabs.f.hierbox toggle 1 + + pack .trace_selection_box.tnb.$tabs.f.hierbox -side left + pack .trace_selection_box.tnb.$tabs.f.vert -side left -fill y + + # bind button 1/2 to move through the tabs + .trace_selection_box.tnb.$tabs.f.hierbox bind all { .trace_selection_box.tnb select left } + .trace_selection_box.tnb.$tabs.f.hierbox bind all { .trace_selection_box.tnb select right } + + # bind button 1 to the select the traces from the list + .trace_selection_box.tnb.$tabs.f.hierbox bind all { + set hierbox_path %W + set _index [ $hierbox_path index current] + + if { [ $hierbox_path entry cget $_index -labelfont] == {times 10}} { + $hierbox_path entry configure $_index -labelfont {times 12 bold} + } else { + $hierbox_path entry configure $_index -labelfont {times 10} + } + } + + # load all the traces + foreach trace [spice::spice_data] { + if {[lindex $trace 1] == $tabs} { + + # traces from spice + .trace_selection_box.tnb.$tabs.f.hierbox insert -at 1 end [lindex $trace 0] -labelfont {times 10} + + # saved plots + if { ( $args == "update" ) || ($graph_name != "" ) } { + if { [ info exists ::OLD_plotList($window_name)] } { + set temp "[lindex $trace 0]\_OLD" + if { [lcontain $::OLD_plotList($window_name) $temp ] } { + .trace_selection_box.tnb.$tabs.f.hierbox insert -at 1 end $temp -labelfont {times 10} + } + } + } + + } + } + + + + if { ( $args == "update" ) || ($graph_name != "" ) } { + # updating the traces from an existing scope + set pre_selected [$graph_name element names] + foreach trace $pre_selected { + + # Nasty and slow -quick fix + for {set i 0} { $i < [ .trace_selection_box.tnb.$tabs.f.hierbox index end ] } {incr i} { + if { [ .trace_selection_box.tnb.$tabs.f.hierbox entry cget $i -label ] == $trace } { + .trace_selection_box.tnb.$tabs.f.hierbox entry configure $i -labelfont {times 12 bold} + } + } + } + + pack [button .trace_selection_box.tnb.$tabs.b -text "Update" -command "load_plots_from_selection_box update $graph_name " ] -fill x + } else { + pack [button .trace_selection_box.tnb.$tabs.b -text "Plot" -command "load_plots_from_selection_box normal" ] -fill x + } + + incr count + } +} + +#----------------------------------------------------------------------------------------------------------------- +proc load_plots_from_selection_box {mode { graph_name "" } } { + + set list {} + foreach tabs { voltage current } { + for {set i 0} { $i < [ .trace_selection_box.tnb.$tabs.f.hierbox index end ] } {incr i} { + + if {[ .trace_selection_box.tnb.$tabs.f.hierbox entry cget $i -labelfont] == {times 12 bold}} { + lappend list [.trace_selection_box.tnb.$tabs.f.hierbox get $i ] + } + } + } + + # error no traces seleted + if { [ llength $list ] == 0 } { + set temp [tk_messageBox -message "No traces seleted" -type okcancel -icon error -parent .trace_selection_box] + if {$temp == "cancel" } { destroy .trace_selection_box } + return + } + + # stops spice if running + if { [spice::running] } { spice::stop } + + if {$mode == "normal" } { + # creates a new plot + plot $list + } + if {$mode == "update" } { + # updates the exsisting plots + update_traces $graph_name $list + } + + destroy .trace_selection_box +} + +#--------------------------------------------------------------------------------------------------------- +#set version "0.2.5" +#set libdir "/usr/lib" +set version "%VERSION%" +set libdir "%LIB_DIR%" + +package ifneeded spice $version [list Loadspice $version $libdir] + +#----------------------------------------------------------------------------------------------------------------- +# window management routines + +proc save_all_nutmeg_windows { { mode ""} } { + + # mode ?? + # - reRun - re runs the simulation saving the current traces vectors, and plotting them against the re run simulation + # - save - simply saves all the current traces vectors to redisplay later + + + #open file ???.cir.gui_settings.tcl + set fh_settings [open "${::spicefilename}.gui_settings.tcl" w] + puts $fh_settings "\# tclspice gui settings file - evaluated by tcl to restore the previous 'nutmeg' session" + + # simulation steps + puts $fh_settings "\# saved_plots_sim_steps $spice::steps_completed " + + puts $fh_settings "\# spicewish version : $::spicewishversion" + + #save all window positions as tcl statements + foreach winname [all_nutmeg_toplevels] { + + puts $fh_settings "\n\n\#DATA FOR WINDOW $winname" + + #get toplevelnum + regexp {.tclspice([0-9]+)} $winname match toplevelnum + + #save to restore the toplevel counter + puts $fh_settings "set ::toplevel_count \$::toplevel_count " + + # don't save traces with "_OLD" + + # at moment saving the curent none _OLD traces, and making _OLD plot for that trace + # this re work if to save graph with out the re plots + set trace_list [ .tclspice$toplevelnum\.scope.g element names ] + set clean_trace_list {} + + foreach trace $trace_list { + puts " trace : $trace" + + if { $mode == "reRun" } { + if { [ regexp {_OLD} $trace ] != 1 } { + lappend clean_trace_list $trace + lappend clean_trace_list $trace\_OLD + } + } + + if {$mode == "save" } { + lappend clean_trace_list $trace + } + + } + puts $fh_settings "plot { $clean_trace_list }" + + # save the old plot list to a global variable, so that it can be read when the trace selection box is loaded + set OLD_plotList { } + foreach trace $clean_trace_list { + if { [ regexp {_OLD} $trace ] } { + lappend OLD_plotList $trace + } + } + + puts $fh_settings "set ::OLD_plotList(.tclspice\[expr \$::toplevel_count - 1\]) { $OLD_plotList } " + + # save title of graph + set graph_name [wm title $winname] + + if { $mode == "reRun" } { + if { [regexp {rerun([0-9]+)} $graph_name match rerun_value] == 1 } { + set reRun_number [ expr $rerun_value + 1] + set start [ string first " - " $graph_name ] + set graph_name [ string range $graph_name [ expr $start + 3] end ] + set graph_name "rerun$reRun_number - $graph_name " + } else { + set reRun_number 1 + set graph_name "rerun$reRun_number - $graph_name " + } + } + + # use [expr \$::toplevel_count - 1\] because procedure plot increments the toplevel_count at the end + + puts $fh_settings "wm title .tclspice\[expr \$::toplevel_count - 1\] \" $graph_name\"" + + # save the measurment + puts $fh_settings "set ::graph_dx(.tclspice\[expr \$::toplevel_count - 1\]) $::graph_dx(.tclspice$toplevelnum)" + puts $fh_settings "set ::graph_dy(.tclspice\[expr \$::toplevel_count - 1\]) $::graph_dy(.tclspice$toplevelnum)" + puts $fh_settings "set ::graph_x1(.tclspice\[expr \$::toplevel_count - 1\]) $::graph_x1(.tclspice$toplevelnum)" + puts $fh_settings "set ::graph_y1(.tclspice\[expr \$::toplevel_count - 1\]) $::graph_y1(.tclspice$toplevelnum)" + puts $fh_settings "set ::graph_x2(.tclspice\[expr \$::toplevel_count - 1\]) $::graph_x2(.tclspice$toplevelnum)" + puts $fh_settings "set ::graph_y2(.tclspice\[expr \$::toplevel_count - 1\]) $::graph_y2(.tclspice$toplevelnum)" + + # save trace place suff + puts $fh_settings "" + puts $fh_settings "set ::trace_place_selected(.tclspice\[expr \$::toplevel_count - 1\]\.scope.g) $::trace_place_selected(.tclspice$toplevelnum\.scope.g) " + + # not quite right because if trace place turned on then off again values not saved to file + + # if trace place been used + if { $::trace_place_selected(.tclspice$toplevelnum\.scope.g) } { + + puts $fh_settings "TracePlace .tclspice\[expr \$::toplevel_count - 1\]" + + # save the list of traces for each slot + for {set col_cnt 0 } {$col_cnt <= $::columns} {incr col_cnt } { + for {set row_cnt 0} { $row_cnt <= [ expr (pow(2, $col_cnt) -1) ] } {incr row_cnt } { + if { $::slot_trace_list(.tclspice$toplevelnum\.scope.tp.ft.tracePlaceGrid.f_$col_cnt\_$row_cnt.b) != "" } { + puts $fh_settings "set ::slot_trace_list(.tclspice\[expr \$::toplevel_count - 1\]\.scope.tp.ft.tracePlaceGrid.f_$col_cnt\_$row_cnt\.b) \"$::slot_trace_list(.tclspice$toplevelnum\.scope.tp.ft.tracePlaceGrid.f_$col_cnt\_$row_cnt.b)\" " + } + } + } + + + # saves the dimensions of each slot + for {set row_cnt 0} { $row_cnt <= [ expr (pow(2, $col_cnt) -1) ] } {incr row_cnt } { + puts $fh_settings "\grid rowconfigure .tclspice\[expr \$::toplevel_count - 1\]\.scope.tp.ft.tracePlaceGrid $row_cnt -minsize [grid rowconfigure .tclspice$toplevelnum\.scope.tp.ft.tracePlaceGrid $row_cnt -minsize ] " + } + + # enables the selected slot + set slot_location [ TracePlace_active_slot .tclspice$toplevelnum\.scope.tp.ft.tracePlaceGrid ] + if { $slot_location != "" } { + puts $fh_settings "\TracePlace_selected_slot .tclspice\[expr \$::toplevel_count - 1\]\.scope.tp.ft.tracePlaceGrid.f_[lindex $slot_location 0]\_[lindex $slot_location 1].b " + } + } + + # saves the geometry of the window + set geom [winfo geometry $winname] + puts $fh_settings "wm geometry .tclspice\[expr \$::toplevel_count - 1\] $geom" + + # save all the markers + set markerlist [$winname.scope.g marker names] + foreach marker $markerlist { + puts $fh_settings ".tclspice\[expr \$::toplevel_count - 1\].scope.g marker create text -name $marker \ + -coords \{ [$winname.scope.g marker cget $marker -coords]\} \ + -text \"[$winname.scope.g marker cget $marker -text]\" \ + -anchor [$winname.scope.g marker cget $marker -anchor] \ + -background [$winname.scope.g marker cget $marker -background]" + } + + # set up a list of traces append here - rest of routine needs to be after + set index 0 + set tracelist [$winname.scope.g element names] + foreach trace $tracelist { + + if { [regexp {_OLD} $trace ] } { continue } ;# - first time simulation re run + + spice_return_trace_vectors .tclspice$toplevelnum\.scope.g $trace + + blt::vector create saved_plot_X$index + blt::vector create saved_plot_Y$index + + saved_plot_X$index set temp_vector_X + saved_plot_Y$index set temp_vector_Y + + incr index + } + + # need this to be after loop for all graphs + # writing same things opening the file twice + + set fh_oldplot [open "${::spicefilename}.gui_plots.tcl" w] + + #save all the current traces from graph to _OLD + set tracelist [$winname.scope.g element names] + set index 0 + foreach trace $tracelist { + + if { [regexp {_OLD} $trace ] } { continue } ;# - first time simulation re run + + puts $fh_oldplot " " + + blt::vector create tempSaveX + blt::vector create tempSaveY + + tempSaveX set saved_plot_X$index + tempSaveY set saved_plot_Y$index + + puts $fh_oldplot "#$trace\_OLD_X : $tempSaveX(:) " + puts $fh_oldplot "#$trace\_OLD_Y : $tempSaveY(:) " + + blt::vector destroy tempSaveX + blt::vector destroy tempSaveY + + blt::vector destroy saved_plot_X$index + blt::vector destroy saved_plot_Y$index + + incr index + } + } + close $fh_settings + close $fh_oldplot +} + +#-------------------------------------------------------------------------------------------------- + + +#------------------------------------------------------------------------------------------------------ +# creates a progress bar + +proc progress_bar { w {value "" } } { + + if {$value == ""} { + pack [canvas $w -width 100 -height 15 -relief sunken] + $w create rectangle 1 1 5 15 -fill green -tags {bar} + } else { + $w coords bar 1 1 $value 15 + } +} + +#------------------------------------------------------------------------------------------------ +# proc passed number of setps to run before halting + +proc spice_run_steps {pre_run_steps { progressBar "" } } { + + # starts spice + if {$::spice_run == 1} { + if { [$spice::steps_completed] > $pre_run_steps } { return } + spice::bg resume + } else { + set ::spice_run 1 + spice::bg run + } + + # progress bar + if {$progressBar != "" } { + + # check if already packed + if {[ winfo exists .control_butts.progressBar] } { + pack .control_butts.progressBar + progress_bar .control_butts.progressBar.bar 5 + + } else { + pack [frame .control_butts.progressBar ] + pack [label .control_butts.progressBar.label -text "re simulating"] + progress_bar .control_butts.progressBar.bar + update + } + } + + set time 0 + + while { $time < $pre_run_steps } { + sleep 1 + set time $spice::steps_completed + if {$progressBar != "" } { progress_bar .control_butts.progressBar.bar [ expr (($time + 0.001) / $pre_run_steps) * 100 ] } + update + } + spice::halt + pack forget .control_butts.progressBar + +} + +#-------------------------------------------------------------------------------------------------------- +# loads all the scopes that are saved to file + +proc restore_all_nutmeg_windows { } { + + # previous simulations run time + set sim_time [open "${::spicefilename}.gui_settings.tcl" r] + gets $sim_time re_simulation_time + gets $sim_time re_simulation_time + close $sim_time + regexp { ([0-9\.\-e]+)} $re_simulation_time re_simulation_time + + # kills all exsisting scope windows + foreach window [ all_nutmeg_toplevels ] { + destroy $window + + # need to kill vectors as well + } + + spice_run_steps $re_simulation_time progress + + # spice_run_untill $re_simulation_time progress + + source "${::spicefilename}.gui_settings.tcl" + source "${::spicefilename}.gui_plots.tcl" + +} + +#------------------------------------------------------------------------------------------- +#- returns all the "tclspice??" toplevel window names + +proc all_nutmeg_toplevels { } { + + set returnlist "" + + foreach winname [winfo children .] { + + if { [ regexp {.tclspice[0-9]+} $winname ] } { + #found nutmeg type toplevel + lappend returnlist $winname + } + } + + return $returnlist +} + +#--------------------------------------------------------------------------------------------------------------- + +########################################################################## +# zoom controls +# +# Filched from the BLT Demos. May re-write for speed +########################################################################## + +proc y_axis_control { start finish window } { + global zoomInfo + + regexp {.tclspice([0-9]+)} $window match toplevelnum + set graph ".tclspice$toplevelnum\.scope.g" + + Zoom1:1 $graph no_label + + # saves current settings + set cmd {} + foreach margin { xaxis yaxis x2axis y2axis } { + foreach axis [$graph $margin use] { + set min [$graph axis cget $axis -min] + set max [$graph axis cget $axis -max] + set c [list $graph axis configure $axis -min $min -max $max] + append cmd "$c\n" + } + } + set zoomInfo($graph,stack) [linsert $zoomInfo($graph,stack) 0 $cmd] + + set Y_limits [ $graph axis limits y ] + set Y_limits_bot [lindex $Y_limits 0] + set Y_limits_top [lindex $Y_limits 1] + + if { $Y_limits_bot < 0 } { + set Y_limits_bot_t [ expr ( $Y_limits_bot * -1) ] + } else { + set Y_limits_bot_t $Y_limits_bot + } + + set scale [ expr ( $Y_limits_top + $Y_limits_bot_t ) /100.0] + + $graph yaxis configure -min [ expr $Y_limits_bot + ($start * $scale) ] + $graph yaxis configure -max [ expr $Y_limits_bot + ($finish * $scale) ] +} + +#--------------------- + +proc InitStack { graph } { + + global zoomInfo + set zoomInfo($graph,interval) 100 + set zoomInfo($graph,afterId) 0 + set zoomInfo($graph,A,x) {} + set zoomInfo($graph,A,y) {} + set zoomInfo($graph,B,x) {} + set zoomInfo($graph,B,y) {} + set zoomInfo($graph,stack) {} + set zoomInfo($graph,corner) A +} + +#-------------------- +proc ZoomStack { graph {start "ButtonPress-1"} {reset "ButtonRelease-3"} } { + + global zoomInfo zoomMod + + InitStack $graph + + if { [info exists zoomMod] } { + set modifier $zoomMod + } else { + set modifier "" + } + bind bltZoomGraph <${modifier}${start}> { + SetZoomPoint %W %x %y + } + + bind bltZoomGraph <${modifier}${reset}> { + if { [%W inside %x %y] } { + ResetZoom %W + } + } + AddBindTag $graph bltZoomGraph +} + +#-------------------- +proc DestroyZoomTitle { graph } { + global zoomInfo + + if { $zoomInfo($graph,corner) == "A" } { + catch { $graph marker delete "zoomTitle" } + } +} + +#-------------------- +proc Zoom1:1 { graph {noTitle ""}} { + global zoomInfo disp_zoom_level + + $graph axis configure x -min {} -max {} + $graph axis configure y -min {} -max {} + $graph axis configure x2 -min {} -max {} + $graph axis configure x2 -min {} -max {} + InitStack $graph + set disp_zoom_level 0 + if { $noTitle == "" } {ZoomTitleLast $graph } + update + if { $noTitle == "" } { after 2000 "DestroyZoomTitle $graph" } +} + +#-------------------- +proc PopZoom { graph } { + global zoomInfo disp_zoom_level + + set zoomStack $zoomInfo($graph,stack) + + if { [llength $zoomStack] > 0 } { + set cmd [lindex $zoomStack 0] + set zoomInfo($graph,stack) [lrange $zoomStack 1 end] + eval $cmd + ZoomTitleLast $graph +# busy hold $graph + update + after 2000 "DestroyZoomTitle $graph" +# busy release $graph + } else { + catch { $graph marker delete "zoomTitle" } + + } + set disp_zoom_level [expr [llength $zoomInfo($graph,stack)] ] +} + +# Push the old axis limits on the stack and set the new ones + +#----------------------------------------------------------------------- + +proc PushZoom { graph } { + global zoomInfo disp_zoom_level + + eval $graph marker delete [$graph marker names "zoom*"] + if { [info exists zoomInfo($graph,afterId)] } { + after cancel $zoomInfo($graph,afterId) + } + + set x1 $zoomInfo($graph,A,x) + set y1 $zoomInfo($graph,A,y) + set x2 $zoomInfo($graph,B,x) + set y2 $zoomInfo($graph,B,y) + + if { ($x1 == $x2) || ($y1 == $y2) } { + # No delta, revert to start + return + } + + # saves current settings + set cmd {} + foreach margin { xaxis yaxis x2axis y2axis } { + + foreach axis [$graph $margin use] { + set min [$graph axis cget $axis -min] + set max [$graph axis cget $axis -max] + set c [list $graph axis configure $axis -min $min -max $max] + append cmd "$c\n" + } + } + set zoomInfo($graph,stack) [linsert $zoomInfo($graph,stack) 0 $cmd] + + # busy hold $graph + # This update lets the busy cursor take effect. + update + + foreach margin { xaxis x2axis } { + foreach axis [$graph $margin use] { + set min [$graph axis invtransform $axis $x1] + set max [$graph axis invtransform $axis $x2] + if { $min > $max } { + $graph axis configure $axis -min $max -max $min + } else { + $graph axis configure $axis -min $min -max $max + } + } + } + foreach margin { yaxis y2axis } { + foreach axis [$graph $margin use] { + set min [$graph axis invtransform $axis $y1] + set max [$graph axis invtransform $axis $y2] + if { $min > $max } { + $graph axis configure $axis -min $max -max $min + } else { + $graph axis configure $axis -min $min -max $max + } + } + } + # This "update" forces the graph to be redrawn + set disp_zoom_level [expr [llength $zoomInfo($graph,stack)] ] + update + + # busy release $graph +} + +#-------------------- + +# +# This routine terminates either an existing zoom, or pops back to +# the previous zoom level (if no zoom is in progress). +# + +#-------------------- +proc ResetZoom { graph } { + global zoomInfo + + if { ![info exists zoomInfo($graph,corner)] } { + InitStack $graph + } + eval $graph marker delete [$graph marker names "zoom*"] + + if { $zoomInfo($graph,corner) == "A" } { + # Reset the whole axis + PopZoom $graph + + + } else { + global zoomMod + + if { [info exists zoomMod] } { + set modifier $zoomMod + } else { + set modifier "Any-" + } + set zoomInfo($graph,corner) A + bind $graph <${modifier}Motion> { } + } +} + +#-------------------- + +option add *zoomTitle.font -*-helvetica-medium-R-*-*-18-*-*-*-*-*-*-* +option add *zoomTitle.shadow yellow4 +option add *zoomTitle.foreground yellow1 +option add *zoomTitle.coords "-Inf Inf" + +#-------------------- +proc ZoomTitleNext { graph } { + global zoomInfo disp_zoom_level + set level [expr [llength $zoomInfo($graph,stack)] + 1] + + if { [$graph cget -invertxy] } { + set coords "-Inf -Inf" + } else { + set coords "-Inf Inf" + } + $graph marker create text -name "zoomTitle" -text "Zoom #$level" \ + -coords $coords -bindtags "" -anchor nw +} + +#-------------------- +proc ZoomTitleLast { graph } { + global zoomInfo + + set level [llength $zoomInfo($graph,stack)] + if { $level > 0 } { + $graph marker create text -name "zoomTitle" -anchor nw \ + -text "Zoom #$level" + } + if { $level == 0 } { + $graph marker create text -name "zoomTitle" -anchor nw \ + -text "Zoom 1:1" + } +} + +#-------------------- +proc SetZoomPoint { graph x y } { + global zoomInfo zoomMod + if { ![info exists zoomInfo($graph,corner)] } { + InitStack $graph + } + GetCoords $graph $x $y $zoomInfo($graph,corner) + if { [info exists zoomMod] } { + set modifier $zoomMod + } else { + set modifier "Any-" + } + if { $zoomInfo($graph,corner) == "A" } { + if { ![$graph inside $x $y] } { + return + } + # First corner selected, start watching motion events + + #MarkPoint $graph A + ZoomTitleNext $graph + + bind $graph <${modifier}Motion> { + GetCoords %W %x %y B + #MarkPoint $graph B + Box %W + } + set zoomInfo($graph,corner) B + } else { + # Delete the modal binding + bind $graph <${modifier}Motion> { } + PushZoom $graph + set zoomInfo($graph,corner) A + } +} + +#-------------------- + +option add *zoomOutline.dashes 4 +option add *zoomTitle.anchor nw +option add *zoomOutline.lineWidth 2 +option add *zoomOutline.xor yes + +#-------------------- +proc MarchingAnts { graph offset } { + global zoomInfo + + incr offset + if { [$graph marker exists zoomOutline] } { + $graph marker configure zoomOutline -dashoffset $offset + set interval $zoomInfo($graph,interval) + set id [after $interval [list MarchingAnts $graph $offset]] + set zoomInfo($graph,afterId) $id + } +} + +#-------------------- +proc GetCoords { graph x y index } { + global zoomInfo + if { [$graph cget -invertxy] } { + set zoomInfo($graph,$index,x) $y + set zoomInfo($graph,$index,y) $x + + } else { + set zoomInfo($graph,$index,x) $x + set zoomInfo($graph,$index,y) $y + } +} + +#-------------------- +proc AddBindTag { graph name } { + set oldtags [bindtags $graph] + if { [lsearch $oldtags $name] < 0 } { + bindtags $graph [concat $name $oldtags] + } +} + +#-------------------- +proc Box { graph } { + global zoomInfo + + # select which yaxis to take the measurments + # !!!!!!!!!!!!!! need a global variable for when the trace place is selected but returned to normal graph + if { $::trace_place_selected($graph) } { + # trace place grid active + set m_yaxis "y2axis" + } else { + set m_yaxis "yaxis" + } + + + if { $zoomInfo($graph,A,x) > $zoomInfo($graph,B,x) } { + set x1 [$graph xaxis invtransform $zoomInfo($graph,B,x)] + set y1 [$graph yaxis invtransform $zoomInfo($graph,B,y)] + set x2 [$graph xaxis invtransform $zoomInfo($graph,A,x)] + set y2 [$graph yaxis invtransform $zoomInfo($graph,A,y)] + + set my1 [$graph $m_yaxis invtransform $zoomInfo($graph,B,y)] + set my2 [$graph $m_yaxis invtransform $zoomInfo($graph,A,y)] + + } else { + set x1 [$graph xaxis invtransform $zoomInfo($graph,A,x)] + set y1 [$graph yaxis invtransform $zoomInfo($graph,A,y)] + set x2 [$graph xaxis invtransform $zoomInfo($graph,B,x)] + set y2 [$graph yaxis invtransform $zoomInfo($graph,B,y)] + + set my1 [$graph $m_yaxis invtransform $zoomInfo($graph,A,y)] + set my2 [$graph $m_yaxis invtransform $zoomInfo($graph,B,y)] + } + set coords { $x1 $y1 $x2 $y1 $x2 $y2 $x1 $y2 $x1 $y1 } + if { [$graph marker exists "zoomOutline"] } { + $graph marker configure "zoomOutline" -coords $coords + } else { + set X [lindex [$graph xaxis use] 0] + set Y [lindex [$graph yaxis use] 0] + $graph marker create line -coords $coords -name "zoomOutline" \ + -mapx $X -mapy $Y + set interval $zoomInfo($graph,interval) + set id [after $interval [list MarchingAnts $graph 0]] + set zoomInfo($graph,afterId) $id + } + + regexp {(.[0-9A-z]+)} $graph window_name + set ::graph_dx($window_name) [expr ($x2 - $x1)] + set ::graph_dy($window_name) [expr ($my2 - $my1)] + set ::graph_x1($window_name) $x1 + set ::graph_y1($window_name) $my1 + set ::graph_x2($window_name) $x2 + set ::graph_y2($window_name) $my2 +} + +### End of software theft + + + +########################################################################## +# trace and place +# +# +########################################################################## + + +# procedure that calls traceplace form menu pass the %w +# then calls procedure active button if this is passed a value then this one will become active + +#------------------------------------------------------------------------------------------ +# returns to normal graph from trace place grid + +proc NormalGraph { window } { + + # un packs the trace and place widget + pack forget $window.scope.tp.l + pack forget $window.scope.tp.ft + $window.scope.tp configure -width 1 + + # un packs the trace and place information bar at bottom + pack forget $window.tracePlaceInfoBar.fakeGraph + pack forget $window.tracePlaceInfoBar.legends + $window.tracePlaceInfoBar configure -height 1 + + # turns off all the legenfs relief + foreach trace [ $window.scope.g element names ] { + $window.scope.g element configure $trace -labelrelief flat + $window.scope.g element configure $trace -hide 0 + } + + $window.scope.g yaxis configure -min "" -max "" -hide 0 + $window.scope.g y2axis configure -hide 1 + + # turn off the + spice_update_traces $window.scope.g + +} + +#----------------------------------------------------------------------------------------------------------------- +# creates the trace and place grid +# re packs if already created + +proc TracePlace { window } { + global columns rows max_traces_per_slot total_hei desired_width desired_height + + # unpacks the trace place grid + if {$::trace_place_selected($window.scope.g) != 1} { + NormalGraph $window + $window.scope.g y2axis configure -hide 1 + $window.scope.g yaxis configure -hide 0 + return + } + + set window_clean $window + set window "$window\.scope.tp" + $window_clean.scope.g yaxis configure -hide 1 + $window_clean.scope.g y2axis configure -hide 0 + #trace place info bar , bottom. if already created once, then just re pack + if { [ winfo exists $window\.l ] == 1 } { + + # re packs the trace and place slots widget + pack $window\.l -side bottom -fill both + pack $window\.ft -side top -expand 1 -fill y + + # re packs the trace and place information bar at bottom + pack $window_clean.tracePlaceInfoBar.fakeGraph -side left + pack $window_clean.tracePlaceInfoBar.legends -side left + + # refreshes tarce and place grid + TracePlace_update $window_clean + + return + } + + + #---- + #-------- + # construction in progress + + # creates a fake graph that is never seen, so that its legend can be used for the trace and place information bar + set fakeGraph_w [ blt::graph $window_clean.tracePlaceInfoBar.fakeGraph ] + $fakeGraph_w configure -height 20 -width 20 -plotrelief flat + $fakeGraph_w xaxis configure -hide 1 + $fakeGraph_w yaxis configure -hide 1 + $fakeGraph_w legend configure -position $window_clean.tracePlaceInfoBar.legends -columns 1 + + pack $fakeGraph_w -side left + pack $window_clean.tracePlaceInfoBar.legends -side left + + # graph legend active on button 3 + $fakeGraph_w legend bind all { %W legend activate [%W legend get current] } + $fakeGraph_w legend bind all { %W legend deactivate [%W legend get current]} + + # creates the drag and drop packet for each of the plots in the trace place info bar + blt::drag&drop source $window_clean.tracePlaceInfoBar.legends -packagecmd {make_package %t %W } -button 1 + set token [blt::drag&drop token $window_clean.tracePlaceInfoBar.legends -activebackground blue ] + pack [ label $token.label -text "" ] + + $window_clean.tracePlaceInfoBar.fakeGraph element create "" -symbol "" + + #---------- + #------- + + set columns 3 ;#- will give 2^rows of total choices for trace positons. + set rows [expr pow(2, $columns) ] ;# -this many rows (see above) + set min_row_hei 1 ; #- cant click a single element smaller than this (but still can get smaller than this is squashed) + set max_traces_per_slot 8 + + + #- call procedure to get the wm height of the graph + #- wm geometry .tclspice 1 + #- perform scan to get height - minus 24 for title plus fotter included padding of graph?? + #- set desired height to this + + # global columns rows + pack [ label $window.l -text "" -borderwidth 4 ] -side bottom -fill both + pack [ frame $window.ft -width 50 ] -side top -expand 1 -fill y + pack [ frame $window.ft.tracePlaceGrid -borderwidth 4 ] -side left -expand 1 -fill y + + + # set desired_height 70 + # set desired_width 20 ; #-initial width of the panel - can still dynamically resize the width + + scan [winfo geometry $window.ft.tracePlaceGrid ] "%dx%d+%d+%d" desired_width desired_height xpos ypos + set total_hei [expr int( ( $desired_height / $rows)* $rows )] + + set window "$window.ft.tracePlaceGrid" + set ::window $window + + for {set columns_cnt 0 } {$columns_cnt <= $columns} {incr columns_cnt } { + + set row_span_holder [ expr pow(2, $columns) / pow(2, $columns_cnt) ] + set row_span_holder [ expr int($row_span_holder) ] + + for {set row_cnt 0} { $row_cnt <= [ expr (pow(2, $columns_cnt) - 1) ] } {incr row_cnt } { + + # set slotnum [ slotnum_FROM_column_gridrow $columns_cnt $row_cnt $row_span_holder] + set slotnum [ expr int (int ( [expr $row_cnt* $row_span_holder] / [expr pow(2, ($columns - $columns_cnt)) ]) + [expr int (pow(2, $columns_cnt))]) ] + + # create a frame for each slot to hold the button and the canvas + set slot_frame [ frame $window.f_$columns_cnt\_$row_cnt ] + + + # creates button/slot + set button_path [button $window.f_$columns_cnt\_$row_cnt.b -padx 3 -pady 0 -activebackground lightgrey -command "TracePlace_selected_slot $window.f_$columns_cnt\_$row_cnt.b "] + + # creates a clean trace list, for all the traces associated with that slot + set ::slot_trace_list($button_path) {} + + # sets button to be a target for drag and drop packet + # - when active adds trace to slots list + blt::drag&drop target $button_path handler string { + append ::slot_trace_list(%W) "%v " + TracePlace_selected_slot %W update + } + + + # creates a drag drop packet so that all the slots traces can be moved + blt::drag&drop source $button_path -packagecmd { make_package %t %W tracePlaceGrid } -button 1 + set token2 [blt::drag&drop token $button_path -activebackground blue ] + pack [ label $token2.label -text "" ] + + + # button bindings + bind $button_path { regexp {(.[0-9A-z]+)} %W temp; TracePlace_wheel_move up $temp.scope.tp.ft.tracePlaceGrid} + bind $button_path { regexp {(.[0-9A-z]+)} %W temp; TracePlace_wheel_move up $temp.scope.tp.ft.tracePlaceGrid } + bind $button_path { regexp {(.[0-9A-z]+)} %W temp; TracePlace_wheel_move "down" $temp.scope.tp.ft.tracePlaceGrid } + bind $button_path { regexp {(.[0-9A-z]+)} %W temp; TracePlace_wheel_move "down" $temp.scope.tp.ft.tracePlaceGrid } + + + # create a canvas in slot to display included traces + set canvas_path [ canvas $window.f_$columns_cnt\_$row_cnt.c -background grey -width 2 -height 10 ] + + grid configure $window.f_$columns_cnt\_$row_cnt -row [ expr $row_cnt * $row_span_holder ] -column [ expr ($columns - $columns_cnt) * $max_traces_per_slot ] -sticky "nsew" -rowspan $row_span_holder + + # packs the button into the slots frame on + pack $button_path -side right -fill both -expand 1 + + # packs the canvas into the slot + pack $canvas_path -side left -fill y + + grid columnconfigure $window [expr $columns_cnt * $max_traces_per_slot] -weight 1 + grid rowconfigure $window $row_cnt -weight 1 + } + } + + # can not set the default size here because winfo can not detect the size of gid widget because of delay on creation + + + # Fill in all row sizes to the default + for {set rows_cnt 0 } { $rows_cnt < $rows } { incr rows_cnt} { + set row_heights($rows_cnt) 10 ;#[expr $total_hei / $rows] + grid rowconfigure $window $rows_cnt -minsize $row_heights($rows_cnt) + } + + # error when the trace is first made scales out of the window size + # but if resize window stays within limits + scan [wm geometry $window_clean ] "%dx%d+%d+%d" width total_hei xpos ypos + wm geometry $window_clean "[expr $width+1]x$total_hei\+$xpos\+$ypos" + +} + +#------------------------------------------------------------------------------------------------------------------ +# refereshes the trace and place grid + +proc TracePlace_update { window } { + + # updates all the traces + # called when the traces on screen are updated added / removed + + # retrieve the name of the fake graph + regexp {(.[0-9A-z]+)} $window window_clean + set graph_w "$window_clean.scope.g" + set tracePlace_w "$window_clean.scope.tp.ft.tracePlaceGrid" + + # returns if trace place grid not active + if { $::trace_place_selected($graph_w) == 0 } { return } + + set slot [TracePlace_active_slot $tracePlace_w ] + if { $slot == "" } { return } + + TracePlace_selected_slot $tracePlace_w\.f_[lindex $slot 0]\_[lindex $slot 1]\.b + +} + + +#---------------------------------------------------------------------------------------------------------- +# + +proc TracePlace_selected_slot { window {args ""} } { + + # retrieve the name of the fake graph + regexp {(.[0-9A-z]+)} $window window_clean + set fakeGraph_w "$window_clean.tracePlaceInfoBar.fakeGraph" + set tracePlace_w "$window_clean.scope.tp.ft.tracePlaceGrid" + + regexp {Grid.f_([0-9]+)_([0-9]+)} $window match active_col active_row + + set dropped_slot_row $active_row + set dropped_slot_col $active_col + + # highlight the selected button green turn the previously selected button back to grey + for {set columns_cnt 0 } {$columns_cnt <= $::columns} {incr columns_cnt } { + for {set row_cnt 0} { $row_cnt <= [ expr (pow(2, $columns_cnt) -1) ] } {incr row_cnt } { + + if { [$tracePlace_w.f_$columns_cnt\_$row_cnt.b cget -background] == "green" } { + + # case where a packet is been dropped on a slot that is not active, so exits not displaying list + if { ($args == "update") && + ( ($active_col != $columns_cnt) || ($active_row != $row_cnt)) } { + + # case where packet is moved from current slot to another, need to redisplay new slot list + set active_col $columns_cnt + set active_row $row_cnt + continue + } + + # turns off the highlight 'green' colour + $tracePlace_w.f_$columns_cnt\_$row_cnt.b configure -background \#dcdcdc -activebackground lightgrey + continue + } + + } + } + + + # search through all the other slot lists to make sure that the traces are not duplicated + # - error trapping when a trace is moved from one slot to another + # - restores the slot to its default colour + for {set columns_cnt 0 } {$columns_cnt <= $::columns} {incr columns_cnt } { + for {set row_cnt 0} { $row_cnt <= [ expr (pow(2, $columns_cnt) -1) ] } {incr row_cnt } { + + # returns all the slots to there default grey colours + $tracePlace_w.f_$columns_cnt\_$row_cnt.b configure -background \#dcdcdc -activebackground lightgrey + + # continues if current slot + if { ($dropped_slot_row == $row_cnt) && ($dropped_slot_col == $columns_cnt) } { continue } + foreach trace $::slot_trace_list($tracePlace_w.f_$dropped_slot_col\_$dropped_slot_row.b) { + + if { [ lcontain $::slot_trace_list($tracePlace_w.f_$columns_cnt\_$row_cnt.b) $trace ] } { + + # -- nasty hack just need command that delete element form a string--- + set cleanList {} + foreach list $::slot_trace_list($tracePlace_w.f_$columns_cnt\_$row_cnt.b) { + if { $trace != $list } { append cleanList "$list "} + } + set ::slot_trace_list($tracePlace_w.f_$columns_cnt\_$row_cnt.b) {} + set ::slot_trace_list($tracePlace_w.f_$columns_cnt\_$row_cnt.b) $cleanList + #------------------------------------------------------------------------------------------ + } + } + + } + } + + # highlights all the decendants of the selected slot blue, produces list of slots + set activated_slots_list { } + set tr $active_row + for {set col_cnt 0 } {$col_cnt <= [ expr $::columns - $active_col] } {incr col_cnt } { + for {set row_cnt 0} { $row_cnt <= [ expr (pow(2, $col_cnt) -1) ] } {incr row_cnt } { + + append activated_slots_list "[ expr $col_cnt + $active_col]\_[ expr $tr + $row_cnt ] " + $tracePlace_w.f_[ expr $col_cnt + $active_col]\_[ expr $tr + $row_cnt ].b configure -background lightblue -activebackground lightgrey + } + set tr [ expr $tr * 2 ] + } + + # highlights the selected slot green + $tracePlace_w.f_$active_col\_$active_row.b configure -background green -activebackground lightgreen + + # re packs the trace and place information bar at bottom, just incase previously forget + pack $window_clean.tracePlaceInfoBar.fakeGraph -side left + pack $window_clean.tracePlaceInfoBar.legends -side left + + # clears the trace and place list at bottom of screen + foreach trace_to_zap [ $fakeGraph_w element names ] { $fakeGraph_w element delete $trace_to_zap } + + # makes sure that all the real legend labels reliefs are flat + # hides all the traces on the scope + foreach trace [ $window_clean.scope.g element names ] { + $window_clean.scope.g element configure $trace -labelrelief flat + $window_clean.scope.g element configure $trace -hide 1 + } + + + # display the slots list of selected traces at the bottom of screen, and in the real graphs legend + set clean_trace_list {} + foreach trace $::slot_trace_list($tracePlace_w.f_$active_col\_$active_row.b) { + + # makes sure that the trace has not been removed from the real graph + if { [$window_clean.scope.g element exists $trace] == 0 } { continue } + + # makes sure that there is no dupliaction of traces in the list + if { [$fakeGraph_w element exists $trace] } { continue } + + # add the trace to the list at the bottom of the screen + $fakeGraph_w element create $trace -color [$window_clean.scope.g element cget $trace -color ] + + # highlight by relief in real legend + $window_clean.scope.g element configure $trace -labelrelief raised + + append clean_trace_list "$trace " + } + + # saves the cleaned up plot list + set ::slot_trace_list($tracePlace_w.f_$active_col\_$active_row.b) {} + set ::slot_trace_list($tracePlace_w.f_$active_col\_$active_row.b) $clean_trace_list + + + # if no traces in the slot list, puts a blank plot due to packing/update problems with fake graph legend + if { [ llength $::slot_trace_list($tracePlace_w.f_$active_col\_$active_row.b)] == 0 } {$fakeGraph_w element create "" -symbol ""} + + + + # hides all the traces on the scope + # foreach scope_trace [ $window_clean.scope.g element names ] { $window_clean.scope.g element configure $scope_trace -hide 1} + + + # loops through all the activated slots and displays there traces + # resizes the traces so that they are relative to there slots size and position + foreach activated_slot $activated_slots_list { + + regexp {([0-9]+)_([0-9]+)} $activated_slot match activated_slot_col activated_slot_row + set active_row $activated_slot_row + set active_col $activated_slot_col + + # resets the y axis to 0 -100 and hides the scale + $window_clean.scope.g axis configure y -min 0 -max 100 ;#-hide 1 ;# - set up the y axis + # should only call above if list length > 1 + + # displays traces within slots plot list on scope, and rasies it legend + set max 0 + set min 0 + foreach scope_trace [ $window_clean.scope.g element names ] { + if { [ lcontain $::slot_trace_list($tracePlace_w.f_$active_col\_$active_row.b) "$scope_trace" ]} { + + $window_clean.scope.g element configure $scope_trace -labelrelief raised + $window_clean.scope.g element configure $scope_trace -hide 0 + + spice_return_trace_vectors $window_clean.scope.g $scope_trace + + set data_list_length [ temp_vector_Y length ] + for { set i 0 } { $i < $data_list_length } { incr i } { + if { [ temp_vector_Y index $i ] > $max } { set max [ temp_vector_Y index $i ] } + if { [ temp_vector_Y index $i ] < $min } { set min [ temp_vector_Y index $i ] } + } + } + } + + + foreach scope_trace [ $window_clean.scope.g element names ] { + if { [ lcontain $::slot_trace_list($tracePlace_w.f_$active_col\_$active_row.b) "$scope_trace" ]} { + + spice_return_trace_vectors $window_clean.scope.g $scope_trace + set data_list_length [ temp_vector_Y length ] + set scale_factor [ expr 100 / ($max - $min ) ] + + if { $min < 0 } { + set offset [ expr $min * -1 ] + } else { + set offset 0 + } + + # retrives the size of the selected slot + set dimensions [ TracePlace_slot_dimension $window $active_col $active_row ] + set slot_start_position [lindex $dimensions 0] + set slot_finish_position [lindex $dimensions 1] + set slot_scale_factor [ expr 100 / (($slot_finish_position) - ( $slot_start_position)) ] + + for { set i 0 } { $i < $data_list_length } { incr i } { + + #scales against 0 -100 + temp_vector_Y index $i [ expr ( [ temp_vector_Y index $i ] * $scale_factor) ] + + # offset traces < 0 + temp_vector_Y index $i [ expr [ temp_vector_Y index $i ] + ( $offset * $scale_factor )] + + # scales against the slot dimensions + temp_vector_Y index $i [ expr ( [temp_vector_Y index $i] / $slot_scale_factor ) + $slot_start_position ] + + } + + temp_vector_Y dup temp2 + $window_clean.scope.g element configure $scope_trace -ydata $temp2(:) + } + } + } + + # runs through all the slots and draws markers into the canvases + for {set col_cnt 0 } {$col_cnt <= $::columns} {incr col_cnt } { + for {set row_cnt 0} { $row_cnt <= [ expr (pow(2, $col_cnt) -1) ] } {incr row_cnt } { + TracePlace_update_slot_canvas_markers $tracePlace_w $col_cnt $row_cnt + } + } + +} + +#-------------------------------------------------------------------------------------------------------------------------------------- + +proc TracePlace_update_slot_canvas_markers { tracePlace_w col_cnt row_cnt } { + + regexp {(.[0-9A-z]+)} $tracePlace_w window_clean + + # clean old markers + $tracePlace_w.f_$col_cnt\_$row_cnt.c delete tracePlaceMarker + + # length of list + set list_length [ llength $::slot_trace_list($tracePlace_w.f_$col_cnt\_$row_cnt.b)] + + # the height of the column + set slot_height [ winfo height $tracePlace_w.f_$col_cnt\_$row_cnt.c ] + + if { $list_length == 0 } { + set rectangle_height $slot_height + } else { + set rectangle_height [expr $slot_height / $list_length ] + } + + # run through the list display ing rectanlgles + set rect_start_y 0 + set rect_finish_y 0 + + foreach scope_trace $::slot_trace_list($tracePlace_w.f_$col_cnt\_$row_cnt.b) { + set rect_finish_y [expr $rect_finish_y + $rectangle_height ] + # places retcangle on canvas + $tracePlace_w.f_$col_cnt\_$row_cnt.c create rectangle 0 $rect_start_y 10 $rect_finish_y -tags tracePlaceMarker -fill [ $window_clean.scope.g element cget $scope_trace -color ] + set rect_start_y [expr $rect_start_y + $rectangle_height ] + } +} + + +#---------------------------------------------------------------------------------------------------------------------------------- +# returns the start and finish dimensions for a given slot on trace and place + +proc TracePlace_slot_dimension { window active_col active_row } { + + regexp {(.[0-9A-z]+)} $window window_clean + set fakeGraph_w "$window_clean.tracePlaceInfoBar.fakeGraph" + set tracePlace_w "$window_clean.scope.tp.ft.tracePlaceGrid" + + set grid_info [grid info $tracePlace_w.f_$active_col\_0] + + set count 0 + set temp_row 0 + set calc_height 0 + set row_span_value 0 + + # loops down the row calculating the size of each slot + for {set rows_cnt [expr ( int ($::rows) / [lindex $grid_info 9]) - 1 ] } { $rows_cnt >= 0 } { set rows_cnt [expr $rows_cnt - 1]} { + # retrieves the configs of the slot + set rows_cnt [ expr int($rows_cnt) ] + set grid_info [grid info $tracePlace_w.f_$active_col\_$rows_cnt] + + # save the start height of the selected slot + if { $count == $active_row } { set temp_finish $row_span_value} ;# start + + # calculates the size of the slot + for {set row_span_cnt $temp_row } {$row_span_cnt < ( [lindex $grid_info 9] + $temp_row )} {incr row_span_cnt } { + set row_span_value [expr $row_span_value + [grid rowconfigure $tracePlace_w $row_span_cnt -minsize ] ] + } + set temp_row $row_span_cnt + set calc_height $row_span_value + incr count + + # save the finish height of the selected slot + if { $count == [ expr $active_row + 1 ]} { set temp_start $row_span_value} ;# finish + } + + return "[expr 100 - ( $temp_start / [expr $calc_height /100.0] ) ] [expr 100 - ( $temp_finish / [expr $calc_height /100.0] ) ]" +} + + +#--------------------------------------------------------------------------------------------------------------------------------- +proc TracePlace_active_button {window } { + global columns + + # detects which button is active, and returns its grid position + for {set columns_cnt 0 } {$columns_cnt <= $columns} {incr columns_cnt } { + for {set row_cnt 0} { $row_cnt <= [ expr (pow(2, $columns_cnt) -1) ] } {incr row_cnt } { + + if { [$window.f_$columns_cnt\_$row_cnt.b cget -state] == "active" } { + return "$columns_cnt $row_cnt" + } + } + } +} + +#---------------------------------------------------------------------------------------------------------------------------------- +proc TracePlace_active_slot {window } { + global columns + + # detects which button is active, and returns its grid position + for {set columns_cnt 0 } {$columns_cnt <= $columns} {incr columns_cnt } { + for {set row_cnt 0} { $row_cnt <= [ expr (pow(2, $columns_cnt) -1) ] } {incr row_cnt } { + + if { [$window.f_$columns_cnt\_$row_cnt.b cget -background] == "green" } { + return "$columns_cnt $row_cnt" + } + } + } +} + +#---------------------------------------------------------------------------------------------------------------------------------- + +set ::trace_place_update_time 500 + +#---------------------------------------------------------------------------------------------------------------------------------- +# resizes the slot on the the trace and place grid + +proc TracePlace_wheel_move { direction window } { + global columns min_row_hei total_hei rows + + # update the scope traces after "trace_place_update_delay" , the delay is reset each time this proc is called + foreach after_script [ after info ] {after cancel $after_script } ; # kills all the afters that are active + + set ::delayed_update_widget $window + + after $::trace_place_update_time { + set slot_location [ TracePlace_active_slot $::delayed_update_widget ] + if { $slot_location != "" } { TracePlace_selected_slot $::delayed_update_widget.f_[lindex $slot_location 0]\_[lindex $slot_location 1].b update } ;# update if there is an active (green) slot + } + + scan [winfo geometry $window ] "%dx%d+%d+%d" width total_hei xpos ypos + + # detects which button is active + set button_location [ TracePlace_active_button $window] + set col_cnt [lindex $button_location 0] + set row_cnt [lindex $button_location 1] + + set grid_info [grid info $window.f_$col_cnt\_$row_cnt] + set col_info [lindex $grid_info 3] + set row_span_info [lindex $grid_info 9] + set row_info [lindex $grid_info 5] + + # stores current slot sizes + for {set rows_cnt 0 } { $rows_cnt < $rows } { incr rows_cnt} { + set row_heights($rows_cnt) [ grid rowconfigure $window $rows_cnt -minsize ] + if {$row_heights($rows_cnt) < 10} {set row_heights($rows_cnt) 10} + } + + set allocated_height 0 + + # increases / decreases selected slots + for { set rows_cnt $row_info} {$rows_cnt < [expr ($row_info + $row_span_info) ] } {incr rows_cnt } { + + set valholder $row_heights($rows_cnt) + + if {$direction == "up" } { + set valholder [expr $valholder * 1.1] ;#- scale up + } else { + set valholder [expr $valholder / 1.1] ;#- scale down + } + + set row_heights_holder($rows_cnt) $valholder ; #- store back in working holder + set allocated_height [expr $allocated_height + $valholder] ; #- add the height + } + + # Return if this would exceed the screen size limit by itself (even without makeing all the other rows 0 height) + if {$allocated_height >= $total_hei } {puts "hit limit $allocated_height"; return } + + # recalculates the slots sizes + for {set rows_cnt_outer 0 } { $rows_cnt_outer < $rows} {incr rows_cnt_outer } { + + if { [catch {set temp $row_heights_holder($rows_cnt_outer)} ] } { + + # Find unallocated heights total (i.e. the total of the elements not yet decided) + set unallocated_height 0 + set allocated_height 0 + + for { set rows_cnt 0 } { $rows_cnt < $rows } { incr rows_cnt} { + if { [catch {set temp $row_heights_holder($rows_cnt)} ] } { + set unallocated_height [ expr $unallocated_height + $row_heights($rows_cnt) ] + } else { + set allocated_height [ expr $allocated_height + $row_heights_holder($rows_cnt) ] + # case where a slot has been given a value above + } + } + set scale_to_apply [ expr ($total_hei - $allocated_height) / $unallocated_height ] + set row_heights_holder($rows_cnt_outer) [expr ( $row_heights($rows_cnt_outer) * $scale_to_apply) ] + } + } + + + # if the first row + # need to be if all the rows are less than the miniumum allowed then set to minimum + if { ( $row_info == 0 ) } { + # loop through all the rows checking if they have all dropped below the minumum + set temp 0 + for { set temp_cnt 0 } { $temp_cnt < $rows } { incr temp_cnt } { + if { $row_heights_holder($temp_cnt) < [expr $total_hei / $rows ] } { incr temp } + } + if { $temp == $rows } { + for { set temp_cnt 0 } { $temp_cnt < $rows } { incr temp_cnt } { + set row_heights_holder($temp_cnt) [expr $total_hei / $rows ] + } + } + } + + # reapply's the new slot sizes + for {set rows_cnt_outer 0 } { $rows_cnt_outer < $rows} {incr rows_cnt_outer } { + grid rowconfigure $window $rows_cnt_outer -minsize $row_heights_holder($rows_cnt_outer) + } + +} + + + + + +################################################################### +# saving project +# +################################################################### + +set ::saved_projects_extension "swp" + +proc project_save { project_name } { + + save_all_nutmeg_windows save + + # creates list of project files + set file_list [ glob $project_name* ] + + set clean_file_list {} + + # run's through the list to clean up un needed files + for { set i 0 } { $i < [ llength $file_list ] } { incr i } { + + set file [ lrange $file_list $i $i ] + + # removes any tar balls + if { [ regexp {.tar.gz} $file ] == 1 } { continue } ; + + # removes any project extension + if { [ regexp {.swp} $file ] == 1 } { continue } ; + + # removes any saved files + if { [ regexp {~} $file ] == 1 } { continue } ; + + append clean_file_list "$file " + } + + # delete's if project already exsists + if { [ file exists $project_name.$::saved_projects_extension ] } {puts ""; puts "deleted old project"; file delete -force $project_name.$::saved_projects_extension } + + # saving file + if { [ system tar -zcf $project_name.$::saved_projects_extension $clean_file_list] == 0 } { + puts " " + puts "project \" $project_name.$::saved_projects_extension \" saved " + foreach file $file_list { + puts "-- $file" + } + puts "" + } +} + +#--------------------------------------------------------------------------------------------------------------- +# untars the project +proc project_open { project_name } { + + if { [ system tar -zxf $project_name ] == 0 } { puts "project '$project_name' opened ok " } +} + +#-------------------------------------------------------------------------------------------- +# returns contents list of the project file + +proc project_file_list { project_name } { + + return [ exec tar tzf $project_name ] +} diff --git a/src/setplot b/src/setplot new file mode 100644 index 000000000..38ca0da15 --- /dev/null +++ b/src/setplot @@ -0,0 +1,64 @@ +* set the current working plot +.control + +begin + unset resp + if $argc + set resp = $argv[1] + else + if $?plots = 0 + echo Error: there aren\'t any plots currently loaded. + goto bottom + else + if $#plots = 0 + echo Error: there aren\'t any plots currently loaded. + goto bottom + end + end + + if $?resp = 0 + set oldplot = $curplot + echo ' Type the name of the desired plot:' + echo '' + echo ' new New plot' + foreach pl $plots + set curplot = $pl + strcmp i $pl $oldplot + if $i = 0 + echo "Current $pl $curplottitle ({$curplotname})" + else + echo " $pl $curplottitle ({$curplotname})" + end + end + set curplot = $oldplot + echo -n '? ' + set resp = $< + end + end + + + strcmp i $resp "" + if $i = 0 + goto bottom + end + + strcmp i $resp new + if $i = 0 + set curplot = new + goto bottom + end + + foreach pl $plots + strcmp i $resp $pl + if $i = 0 + set curplot = $pl + goto bottom + end + end + + echo Error: no such plot name $resp + + label bottom + + unset resp i pl newflag oldplot +end diff --git a/src/spectrum b/src/spectrum new file mode 100644 index 000000000..eafb0d09e --- /dev/null +++ b/src/spectrum @@ -0,0 +1,83 @@ +* Fourier Series Function for SPICE +.control + begin + if ($argc lt 4) + echo Error: Too few arguments. + echo ' 'Spectrum produces a plot containing a fourier series transformation of + echo ' 'the specified vectors + echo usage: spectrum startfreq stop step vec [[vec] ...] + goto bottom + end + + if ( time eq time ) + foreach vec $argv[4-len] + if ( $vec eq $vec ) + else + goto bottom + end + end + else + echo ' 'Spectrum can not work without a time vector from a transient analysis. + goto bottom + end + + set dt=$curplot + set title=$curplottitle + set curplot=new + set scratch=$curplot + let span={$dt}.time[length({$dt}.time)-1]-{$dt}.time[0] + if ($argv[3] gt 0.999/span) + let fpoints= ( $argv[2] - $argv[1] ) / $argv[3] +1 + if (fpoints < 2) + echo frequency start stop or step not correctly specified + goto cleanup + end + else + echo Error: time span is not long enough for a step frequency of $argv[3] Hz + goto cleanup + end + let lent = length({$dt}.time) + set lent = "$&lent" + let nyquist = {$lent}/2/span + if ($argv[2] gt nyquist) + echo Error: The nyquist limit is exceeded, try a frequency less than "$&nyquist" Hz + goto cleanup + end + set fpoints="$&fpoints" + set curplot=new + set spec=$curplot + set curplottitle=$title + set curplotname='Spectrum Analysis' + let frequency=vector( $fpoints )*$argv[3] + dowhile frequency[1] < ( $argv[1] + 1e-9 ) + let frequency = frequency + $argv[3] + end + foreach vec $argv[4-len] + let $vec = vector( $fpoints ) + j(vector( $fpoints )) + reshape $vec [{$fpoints}] + end + set curplot=$scratch + let npers=1 + let test = span-2/$argv[3] + 1e-9 + while test > 0 + let npers = npers + 1 + let test = test-1/$argv[3] + end + let ircle = 2*pi*max(-1,({$dt}.time-{$dt}.time[{$lent}-1])*{$argv[3]}/npers) + let win = 1 - cos(ircle) + let ircle = npers*ircle + let circle = ircle * ({$spec}.frequency[0]/$argv[3] - 1) + let k=vector( $fpoints ) + foreach k "$&k" + let circle = circle + ircle + foreach vec $argv[4-len] + let tmp = win*{$dt}.{$vec} + let {$spec}.{$vec}[{$k}] = 2*(mean(cos(circle)*tmp),mean(sin(circle)*tmp)) + end + end + + label cleanup + destroy $scratch + unset fpoints dt scratch spec vec k title lent + label bottom + end diff --git a/src/spicelib/ChangeLog b/src/spicelib/ChangeLog new file mode 100644 index 000000000..0edb202ec --- /dev/null +++ b/src/spicelib/ChangeLog @@ -0,0 +1,22 @@ +2000-07-25 Arno W. Peters + + * src/spicelib/devices/README: Moved to src/spicelib/README. + + * src/spicelib/Makefile.am, src/spicelib/devices/Makefile.am: + Files affected by the move. + + * src/spicelib/devices/parser/*: Moved all files to + src/spicelib/parser. + + * configure.in, src/Makefile.am, src/spicelib/Makefile.am, + src/spicelib/devices/Makefile.am: Files affected by the move. + +2000-07-24 Arno W. Peters + + * src/spicelib/devices/analysis/*: Moved all files to + src/spicelib/analysis. + + * configure.in, src/spicelib/Makefile.am, + src/spicelib/Makefile.am, src/spicelib/devices/Makefile.am: Files + affected by the move. + diff --git a/src/spicelib/Makefile.am b/src/spicelib/Makefile.am new file mode 100644 index 000000000..986b84cef --- /dev/null +++ b/src/spicelib/Makefile.am @@ -0,0 +1,7 @@ +# Process this file with automake + +EXTRA_DIST = README + +SUBDIRS = analysis parser devices + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/README b/src/spicelib/README new file mode 100644 index 000000000..cc95a763d --- /dev/null +++ b/src/spicelib/README @@ -0,0 +1,3 @@ +The Spice Library. + +It takes a circuit description and builds a simulator from it. diff --git a/src/spicelib/analysis/ChangeLog b/src/spicelib/analysis/ChangeLog new file mode 100644 index 000000000..9f9f7f543 --- /dev/null +++ b/src/spicelib/analysis/ChangeLog @@ -0,0 +1,83 @@ +2001-01-23 Paolo Nenzi + + * noisean.c: patched the code with the new one + in the bsim4.1.0 distribution. The new noisean.c + put some code between #ifdef INT_NOISE. + +2000-01-21 Paolo Nenzi + + * cktsgen.c: corrected a bug that caused segfault on sensitivity + analysis. + +2000-07-28 Arno W. Peters + + * cktpzstr.c: Reversed a patch that went in between ng-spice-0.2 + and ng-spice-0.3 that eliminated the following warnings: 'suggest + parentheses around && within ||'. The parenthesis were not placed + correctly, leading to incorrect behaviour of the pole-zero + analysis. + +2000-05-22 Paolo Nenzi + + * cktpzstr.c, cktsens.c: Applied Widlok patches. + +2000-04-04 Paolo Nenzi + + * noisean.c: Merged the previous code with the new one included in + bsim4 distribution. This code originated from Weidong Lu + (bsim group). + +1999-12-20 Paolo Nenzi + * noisean.c: + Bug: The ac noise analysis in Spice3f4 has a serious bug. In + interactive mode it fails to reproduce frequency dependence known + to exist. In batch (Spice2) mode, it works only if a corresponding + ac analysis has been run first. + Fix: This bug is fixed by providing a call to CKTload() in + noisean.c as shown by the source code patch which is attached below. + + +1999-09-08 Emmanuel Rouat + + * ckt.h: created (and included in Makefile.am) + +1999-09-07 Arno + + * cktpzstr.c: reformatted and corrected(?) complex if condition. + +1999-08-28 Emmanuel Rouat + + * Removed all #includes of misc.h and util.h (now in spice.h) + +1999-08-27 Paolo Nenzi + + * Removed GENERIC and #include "suffix.h" from all the files. + GENERIC has been replaced by void. ANSIfied all functions with + protoize. + +1999-08-26 Paolo Nenzi + + * cktacct.c: added #include "spmatrix.h" to avoid implicit declaration + warning at compile time. + + * dctran.c: ansified and substituted void with void. + * tranasq.c: same as before. + * traninit.c: same as before. + * transetp.c: same as before. + + +1999-08-08 Emmanuel Rouat + + * Removed all HAS_SHORTMACRO and HAS_FLATINCLUDES code in directory + + * cktdest.c (and other files): changed HAS_SENSE2 in WANT_SENSE2 + +1999-08-04 Paolo Nenzi + + * changed dctrcurv.c: added code for temperature sweeps and + resistance sweeps. Now you can execute .dc temp + to do a temp sweep, temp is the keyword for temp + sweeps (The code comes from a patch supplied by Serban-Mihai + Popescu . To do a resitance sweep just + insert resistor name to the .cd line:.dc vin -5 5 1 rin 100 1000 10. + Resistance and temperature sweeps can be nested. diff --git a/src/spicelib/analysis/Makefile.am b/src/spicelib/analysis/Makefile.am new file mode 100644 index 000000000..d828f2b24 --- /dev/null +++ b/src/spicelib/analysis/Makefile.am @@ -0,0 +1,104 @@ +## Process this file with automake to produce Makefile.in + +noinst_LIBRARIES = libckt.a + +libckt_a_SOURCES = \ + acan.c \ + acaskq.c \ + acsetp.c \ + analysis.c \ + analysis.h \ + cktacct.c \ + cktacdum.c \ + cktaskaq.c \ + cktasknq.c \ + cktbkdum.c \ + cktclrbk.c \ + cktdelt.c \ + cktdest.c \ + cktdisto.c \ + cktdlti.c \ + cktdltm.c \ + cktdltn.c \ + cktdojob.c \ + cktdump.c \ + cktncdump.c \ + cktfbran.c \ + cktfnda.c \ + cktfndm.c \ + cktfnode.c \ + cktftask.c \ + cktgrnd.c \ + ckti2nod.c \ + cktic.c \ + cktlnkeq.c \ + cktload.c \ + cktmapn.c \ + cktmask.c \ + cktmcrt.c \ + cktmkcur.c \ + cktmknod.c \ + cktmkvol.c \ + cktmpar.c \ + cktnames.c \ + cktnewan.c \ + cktneweq.c \ + cktnewn.c \ + cktnodn.c \ + cktnoise.c \ + cktntask.c \ + cktnum2n.c \ + cktop.c \ + cktparam.c \ + cktpartn.c \ + cktpmnam.c \ + cktpname.c \ + cktpzld.c \ + cktpzset.c \ + cktpzstr.c \ + cktsens.c \ + cktsetap.c \ + cktsetbk.c \ + cktsetnp.c \ + cktsetup.c \ + cktsgen.c \ + cktsopt.c \ + ckttemp.c \ + cktterr.c \ + ckttroub.c \ + ckttrunc.c \ + ckttyplk.c \ + daskq.c \ + dcoaskq.c \ + dcop.c \ + dcosetp.c \ + dctaskq.c \ + dctran.c \ + dctrcurv.c \ + dctsetp.c \ + distoan.c \ + dkerproc.c \ + dloadfns.c \ + dsetparm.c \ + naskq.c \ + nevalsrc.c \ + ninteg.c \ + noisean.c \ + nsetparm.c \ + pzan.c \ + pzaskq.c \ + pzsetp.c \ + sensaskq.c \ + senssetp.c \ + tfanal.c \ + tfaskq.c \ + tfsetp.c \ + tranaskq.c \ + traninit.c \ + transetp.c \ + cluster.c \ + ckt.h + + +INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/analysis/acan.c b/src/spicelib/analysis/acan.c new file mode 100644 index 000000000..02ea0cf51 --- /dev/null +++ b/src/spicelib/analysis/acan.c @@ -0,0 +1,417 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified 2001: AlansFixes +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "acdefs.h" +#include "devdefs.h" +#include "sperror.h" + +#ifdef XSPICE +/* gtri - add - wbk - 12/19/90 - Add headers */ +#include "mif.h" +#include "evtproto.h" +#include "ipctiein.h" +/* gtri - end - wbk */ +#endif + +int +ACan(CKTcircuit *ckt, int restart) +{ + + double freq; + double freqTol; /* tolerence parameter for finding final frequency */ + double startdTime; + double startsTime; + double startlTime; + double startcTime; + double startkTime; + double startTime; + int error; + int numNames; + IFuid *nameList; + IFuid freqUid; + static void *acPlot=NULL; + void *plot=NULL; + +/* gtri - add - wbk - 12/19/90 - Add IPC stuff and anal_init and anal_type */ +#ifdef XSPICE + /* Tell the beginPlot routine what mode we're in */ + g_ipc.anal_type = IPC_ANAL_AC; + + /* Tell the code models what mode we're in */ + g_mif_info.circuit.anal_type = MIF_DC; + + g_mif_info.circuit.anal_init = MIF_TRUE; +#endif +/* gtri - end - wbk */ + + if(((ACAN*)ckt->CKTcurJob)->ACsaveFreq == 0 || restart) { + /* start at beginning */ + + if (((ACAN*)ckt->CKTcurJob)->ACnumberSteps < 1) + ((ACAN*)ckt->CKTcurJob)->ACnumberSteps = 1; + + switch(((ACAN*)ckt->CKTcurJob)->ACstepType) { + + case DECADE: + ((ACAN*)ckt->CKTcurJob)->ACfreqDelta = + exp(log(10.0)/((ACAN*)ckt->CKTcurJob)->ACnumberSteps); + break; + case OCTAVE: + ((ACAN*)ckt->CKTcurJob)->ACfreqDelta = + exp(log(2.0)/((ACAN*)ckt->CKTcurJob)->ACnumberSteps); + break; + case LINEAR: + if (((ACAN*)ckt->CKTcurJob)->ACnumberSteps-1 > 1) + ((ACAN*)ckt->CKTcurJob)->ACfreqDelta = + (((ACAN*)ckt->CKTcurJob)->ACstopFreq - + ((ACAN*)ckt->CKTcurJob)->ACstartFreq)/ + (((ACAN*)ckt->CKTcurJob)->ACnumberSteps-1); + else + /* Patch from: Richard McRoberts + * This patch is for a rather pathological case: + * a linear step with only one point */ + ((ACAN*)ckt->CKTcurJob)->ACfreqDelta = 0; + break; + default: + return(E_BADPARM); + } +#ifdef XSPICE +/* gtri - begin - wbk - Call EVTop if event-driven instances exist */ + if(ckt->evt->counts.num_insts == 0) { + /* If no event-driven instances, do what SPICE normally does */ + error = CKTop(ckt, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, + ckt->CKTdcMaxIter); + if(error) return(error); + } + else { + /* Else, use new DCOP algorithm */ + error = EVTop(ckt, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, + ckt->CKTdcMaxIter, + MIF_TRUE); + EVTdump(ckt, IPC_ANAL_DCOP, 0.0); + EVTop_save(ckt, MIF_TRUE, 0.0); + if(error) + return(error); + } +/* gtri - end - wbk - Call EVTop if event-driven instances exist */ +#else + error = CKTop(ckt, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, + ckt->CKTdcMaxIter); + if(error){ + fprintf(stdout,"\nAC operating point failed -\n"); + CKTncDump(ckt); + return(error); + } +#endif + +#ifdef XSPICE +/* gtri - add - wbk - 12/19/90 - Add IPC stuff */ + + /* Send the operating point results for Mspice compatibility */ + if(g_ipc.enabled) + { + /* Call CKTnames to get names of nodes/branches used by BeginPlot */ + /* Probably should free nameList after this block since called again... */ + error = CKTnames(ckt,&numNames,&nameList); + if(error) return(error); + + /* We have to do a beginPlot here since the data to return is */ + /* different for the DCOP than it is for the AC analysis. Moreover */ + /* the begin plot has not even been done yet at this point... */ + (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,(void*)ckt->CKTcurJob, + ckt->CKTcurJob->JOBname,(IFuid)NULL,IF_REAL,numNames,nameList, + IF_REAL,&acPlot); + + + ipc_send_dcop_prefix(); + CKTdump(ckt,(double)0,acPlot); + ipc_send_dcop_suffix(); + + (*(SPfrontEnd->OUTendPlot))(acPlot); + } + +/* gtri - end - wbk */ +#endif + + ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG; + error = CKTload(ckt); + if(error) return(error); + + error = CKTnames(ckt,&numNames,&nameList); + if(error) return(error); + + if (ckt->CKTkeepOpInfo) { + /* Dump operating point. */ + error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob, "AC Operating Point", + (IFuid)NULL,IF_REAL,numNames,nameList, IF_REAL,&plot); + if(error) return(error); + CKTdump(ckt,(double)0,plot); + (*(SPfrontEnd->OUTendPlot))(plot); + plot = NULL; + } + + (*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL, + "frequency", UID_OTHER,(void **)NULL); + error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob, + ckt->CKTcurJob->JOBname,freqUid,IF_REAL,numNames,nameList, + IF_COMPLEX,&acPlot); + if(error) return(error); + + if (((ACAN*)ckt->CKTcurJob)->ACstepType != LINEAR) { + (*(SPfrontEnd->OUTattributes))((void *)acPlot,NULL, + OUT_SCALE_LOG, NULL); + } + freq = ((ACAN*)ckt->CKTcurJob)->ACstartFreq; + + } else { /* continue previous analysis */ + freq = ((ACAN*)ckt->CKTcurJob)->ACsaveFreq; + ((ACAN*)ckt->CKTcurJob)->ACsaveFreq = 0; /* clear the 'old' frequency */ + /* fix resume? saj*/ + error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob, + ckt->CKTcurJob->JOBname,freqUid,IF_REAL,numNames,nameList, + IF_COMPLEX,&acPlot); + /* saj*/ + } + switch(((ACAN*)ckt->CKTcurJob)->ACstepType) { + case DECADE: + case OCTAVE: + freqTol = ((ACAN*)ckt->CKTcurJob)->ACfreqDelta * + ((ACAN*)ckt->CKTcurJob)->ACstopFreq * ckt->CKTreltol; + break; + case LINEAR: + freqTol = ((ACAN*)ckt->CKTcurJob)->ACfreqDelta * ckt->CKTreltol; + break; + default: + return(E_BADPARM); + } + +/* gtri - add - wbk - 12/19/90 - Set anal_init and anal_type */ +#ifdef XSPICE + g_mif_info.circuit.anal_init = MIF_TRUE; + + /* Tell the code models what mode we're in */ + g_mif_info.circuit.anal_type = MIF_AC; +#endif +/* gtri - end - wbk */ + + startTime = SPfrontEnd->IFseconds(); + startdTime = ckt->CKTstat->STATdecompTime; + startsTime = ckt->CKTstat->STATsolveTime; + startlTime = ckt->CKTstat->STATloadTime; + startcTime = ckt->CKTstat->STATcombineTime; + startkTime = ckt->CKTstat->STATsyncTime; + while(freq <= ((ACAN*)ckt->CKTcurJob)->ACstopFreq+freqTol) { + + if( (*(SPfrontEnd->IFpauseTest))() ) { + /* user asked us to pause via an interrupt */ + ((ACAN*)ckt->CKTcurJob)->ACsaveFreq = freq; + return(E_PAUSE); + } + ckt->CKTomega = 2.0 * M_PI *freq; + ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODEAC; + + error = NIacIter(ckt); + if (error) { + ckt->CKTcurrentAnalysis = DOING_AC; + ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime; + ckt->CKTstat->STATacDecompTime += ckt->CKTstat->STATdecompTime - + startdTime; + ckt->CKTstat->STATacSolveTime += ckt->CKTstat->STATsolveTime - + startsTime; + ckt->CKTstat->STATacLoadTime += ckt->CKTstat->STATloadTime - + startlTime; + ckt->CKTstat->STATacCombTime += ckt->CKTstat->STATcombineTime - + startcTime; + ckt->CKTstat->STATacSyncTime += ckt->CKTstat->STATsyncTime - + startkTime; + return(error); + } + + + +#ifdef WANT_SENSE2 + if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&ACSEN) ){ + + save = ckt->CKTmode; + ckt->CKTmode=(ckt->CKTmode&MODEUIC)|MODEDCOP|MODEINITSMSIG; + save1 = ckt->CKTsenInfo->SENmode; + ckt->CKTsenInfo->SENmode = ACSEN; + if(freq == ((ACAN*)ckt->CKTcurJob)->ACstartFreq){ + ckt->CKTsenInfo->SENacpertflag = 1; + } + else{ + ckt->CKTsenInfo->SENacpertflag = 0; + } + if(error = CKTsenAC(ckt)) return (error); + ckt->CKTmode = save; + ckt->CKTsenInfo->SENmode = save1; + } +#endif +/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */ +#ifdef XSPICE + if(g_ipc.enabled) + ipc_send_data_prefix(freq); + + error = CKTacDump(ckt,freq,acPlot); + + if(g_ipc.enabled) + ipc_send_data_suffix(); + +/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */ +#else + error = CKTacDump(ckt,freq,acPlot); +#endif + if (error) { + ckt->CKTcurrentAnalysis = DOING_AC; + ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime; + ckt->CKTstat->STATacDecompTime += ckt->CKTstat->STATdecompTime - + startdTime; + ckt->CKTstat->STATacSolveTime += ckt->CKTstat->STATsolveTime - + startsTime; + ckt->CKTstat->STATacLoadTime += ckt->CKTstat->STATloadTime - + startlTime; + ckt->CKTstat->STATacCombTime += ckt->CKTstat->STATcombineTime - + startcTime; + ckt->CKTstat->STATacSyncTime += ckt->CKTstat->STATsyncTime - + startkTime; + return(error); + } + /* increment frequency */ + + switch(((ACAN*)ckt->CKTcurJob)->ACstepType) { + case DECADE: + case OCTAVE: + freq *= ((ACAN*)ckt->CKTcurJob)->ACfreqDelta; + if(((ACAN*)ckt->CKTcurJob)->ACfreqDelta==1) goto endsweep; + break; + case LINEAR: + freq += ((ACAN*)ckt->CKTcurJob)->ACfreqDelta; + if(((ACAN*)ckt->CKTcurJob)->ACfreqDelta==0) goto endsweep; + break; + default: + return(E_INTERN); + } + } +endsweep: + (*(SPfrontEnd->OUTendPlot))(acPlot); + acPlot = NULL; + ckt->CKTcurrentAnalysis = 0; + ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime; + ckt->CKTstat->STATacDecompTime += ckt->CKTstat->STATdecompTime - + startdTime; + ckt->CKTstat->STATacSolveTime += ckt->CKTstat->STATsolveTime - + startsTime; + ckt->CKTstat->STATacLoadTime += ckt->CKTstat->STATloadTime - + startlTime; + ckt->CKTstat->STATacCombTime += ckt->CKTstat->STATcombineTime - + startcTime; + ckt->CKTstat->STATacSyncTime += ckt->CKTstat->STATsyncTime - + startkTime; + return(0); +} + + + /* CKTacLoad(ckt) + * this is a driver program to iterate through all the various + * ac load functions provided for the circuit elements in the + * given circuit + */ + + +int +CKTacLoad(CKTcircuit *ckt) +{ + extern SPICEdev **DEVices; + int i; + int size; + int error; +#ifdef PARALLEL_ARCH + long type = MT_ACLOAD, length = 1; +#endif /* PARALLEL_ARCH */ + double startTime; + + startTime = SPfrontEnd->IFseconds(); + size = SMPmatSize(ckt->CKTmatrix); + for (i=0;i<=size;i++) { + *(ckt->CKTrhs+i)=0; + *(ckt->CKTirhs+i)=0; + } + SMPcClear(ckt->CKTmatrix); + + for (i=0;iCKThead[i] != NULL) ){ + error = (*((*DEVices[i]).DEVacLoad))(ckt->CKThead[i],ckt); +#ifdef PARALLEL_ARCH + if (error) goto combine; +#else + if(error) return(error); +#endif /* PARALLEL_ARCH */ + } + } + +#ifdef XSPICE + /* gtri - begin - Put resistors to ground at all nodes. */ + /* Value of resistor is set by new "rshunt" option. */ + + if(ckt->enh->rshunt_data.enabled) { + for(i = 0; i < ckt->enh->rshunt_data.num_nodes; i++) { + *(ckt->enh->rshunt_data.diag[i]) += + ckt->enh->rshunt_data.gshunt; + } + } + + /* gtri - end - Put resistors to ground at all nodes */ + + + + /* gtri - add - wbk - 11/26/90 - reset the MIF init flags */ + + /* init is set by CKTinit and should be true only for first load call */ + g_mif_info.circuit.init = MIF_FALSE; + + /* anal_init is set by CKTdoJob and is true for first call */ + /* of a particular analysis type */ + g_mif_info.circuit.anal_init = MIF_FALSE; + + /* gtri - end - wbk - 11/26/90 */ +#endif + + +#ifdef PARALLEL_ARCH +combine: + ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds() - startTime; + startTime = SPfrontEnd->IFseconds(); + /* See if any of the DEVload functions bailed. If not, proceed. */ + IGOP_( &type, &error, &length, "max" ); + ckt->CKTstat->STATsyncTime += SPfrontEnd->IFseconds() - startTime; + if (error == OK) { + startTime = SPfrontEnd->IFseconds(); + SMPcCombine( ckt->CKTmatrix, ckt->CKTrhs, ckt->CKTrhsSpare, + ckt->CKTirhs, ckt->CKTirhsSpare ); + ckt->CKTstat->STATcombineTime += SPfrontEnd->IFseconds() - startTime; + return(OK); + } else { + return(error); + } +#else + ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds() - startTime; + return(OK); +#endif /* PARALLEL_ARCH */ + + +} diff --git a/src/spicelib/analysis/acaskq.c b/src/spicelib/analysis/acaskq.c new file mode 100644 index 000000000..cf2136187 --- /dev/null +++ b/src/spicelib/analysis/acaskq.c @@ -0,0 +1,63 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "acdefs.h" +#include "cktdefs.h" + + +/* ARGSUSED */ +int +ACaskQuest(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + switch(which) { + + case AC_START: + value->rValue = ((ACAN*)anal)->ACstartFreq; + break; + + case AC_STOP: + value->rValue = ((ACAN*)anal)->ACstopFreq ; + break; + + case AC_STEPS: + value->iValue = ((ACAN*)anal)->ACnumberSteps; + break; + + case AC_DEC: + if(((ACAN*)anal)->ACstepType == DECADE) { + value->iValue=1; + } else { + value->iValue=0; + } + break; + + case AC_OCT: + if(((ACAN*)anal)->ACstepType == OCTAVE) { + value->iValue=1; + } else { + value->iValue=0; + } + break; + + case AC_LIN: + if(((ACAN*)anal)->ACstepType == LINEAR) { + value->iValue=1; + } else { + value->iValue=0; + } + break; + + default: + return(E_BADPARM); + } + return(OK); +} + diff --git a/src/spicelib/analysis/acsetp.c b/src/spicelib/analysis/acsetp.c new file mode 100644 index 000000000..23e12de43 --- /dev/null +++ b/src/spicelib/analysis/acsetp.c @@ -0,0 +1,107 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include + +#include "ifsim.h" +#include "iferrmsg.h" +#include "acdefs.h" +#include "cktdefs.h" + +#include "analysis.h" + +/* ARGSUSED */ +int +ACsetParm(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + switch(which) { + + case AC_START: + if (value->rValue <= 0.0) { + errMsg = copy("Frequency of 0 is invalid for AC start"); + ((ACAN*)anal)->ACstartFreq = 1.0; + return(E_PARMVAL); + } + + ((ACAN*)anal)->ACstartFreq = value->rValue; + break; + + case AC_STOP: + if (value->rValue <= 0.0) { + errMsg = copy("Frequency of 0 is invalid for AC stop"); + ((ACAN*)anal)->ACstartFreq = 1.0; + return(E_PARMVAL); + } + + ((ACAN*)anal)->ACstopFreq = value->rValue; + break; + + case AC_STEPS: + ((ACAN*)anal)->ACnumberSteps = value->iValue; + break; + + case AC_DEC: + if(value->iValue) { + ((ACAN*)anal)->ACstepType = DECADE; + } else { + if( ((ACAN*)anal)->ACstepType == DECADE) { + ((ACAN*)anal)->ACstepType = 0; + } + } + break; + + case AC_OCT: + if(value->iValue) { + ((ACAN*)anal)->ACstepType = OCTAVE; + } else { + if( ((ACAN*)anal)->ACstepType == OCTAVE) { + ((ACAN*)anal)->ACstepType = 0; + } + } + break; + + case AC_LIN: + if(value->iValue) { + ((ACAN*)anal)->ACstepType = LINEAR; + } else { + if( ((ACAN*)anal)->ACstepType == LINEAR) { + ((ACAN*)anal)->ACstepType = 0; + } + } + break; + + default: + return(E_BADPARM); + } + return(OK); +} + + +static IFparm ACparms[] = { + { "start", AC_START, IF_SET|IF_ASK|IF_REAL, "starting frequency" }, + { "stop", AC_STOP, IF_SET|IF_ASK|IF_REAL, "ending frequency" }, + { "numsteps", AC_STEPS,IF_SET|IF_ASK|IF_INTEGER, "number of frequencies"}, + { "dec", AC_DEC, IF_SET|IF_FLAG, "step by decades" }, + { "oct", AC_OCT, IF_SET|IF_FLAG, "step by octaves" }, + { "lin", AC_LIN, IF_SET|IF_FLAG, "step linearly" } +}; + +SPICEanalysis ACinfo = { + { + "AC", + "A.C. Small signal analysis", + + sizeof(ACparms)/sizeof(IFparm), + ACparms + }, + sizeof(ACAN), + FREQUENCYDOMAIN, + 1, + ACsetParm, + ACaskQuest, + NULL, + ACan +}; diff --git a/src/spicelib/analysis/analysis.c b/src/spicelib/analysis/analysis.c new file mode 100644 index 000000000..219c3cb30 --- /dev/null +++ b/src/spicelib/analysis/analysis.c @@ -0,0 +1,55 @@ +#include +#include + +#include +#include + +#include "analysis.h" + +extern SPICEanalysis *analInfo[]; +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, +}; + + +char *spice_analysis_get_name(int index) +{ + return analInfo[index]->public.name; +} + +char *spice_analysis_get_description(int index) +{ + return analInfo[index]->public.description; +} + +int spice_num_analysis(void) +{ + return sizeof(analInfo)/sizeof(SPICEanalysis*); +} + + +SPICEanalysis **spice_analysis_ptr(void) +{ + return (SPICEanalysis **) analInfo; +} diff --git a/src/spicelib/analysis/analysis.h b/src/spicelib/analysis/analysis.h new file mode 100644 index 000000000..9b9271e00 --- /dev/null +++ b/src/spicelib/analysis/analysis.h @@ -0,0 +1,21 @@ +#ifndef _ANALYSIS_H +#define _ANALYSIS_H + +typedef struct { + IFanalysis public; + int size; + int domain; + int do_ic; + int (*(setParm))(CKTcircuit *ckt, void *anal, int which, IFvalue *value); + int (*(askQuest))(CKTcircuit *ckt, void *anal, int which, IFvalue *value); + int (*an_init)(CKTcircuit *ckt, JOB *job); + int (*an_func)(CKTcircuit *ckt, int restart); +} SPICEanalysis; + + +char *spice_analysis_get_name(int index); +char *spice_analysis_get_description(int index); +int spice_num_analysis(void); +SPICEanalysis **spice_analysis_ptr(void); + +#endif diff --git a/src/spicelib/analysis/ckt.h b/src/spicelib/analysis/ckt.h new file mode 100644 index 000000000..301002e9e --- /dev/null +++ b/src/spicelib/analysis/ckt.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 1985 Thomas L. Quarles + * Modified 1999 Paolo Nenzi - Removed non STDC definitions + * Kept only prototypes (structs defined in struct.h) ER + */ + + +#ifndef CKT_H_INCLUDED +#define CKT_H_INCLUDED + + +/* function prototypes */ + +int ACan( CKTcircuit *, int ); +int ACaskQuest( CKTcircuit *, void *, int , IFvalue *); +int ACsetParm( CKTcircuit *, void *, int , IFvalue *); +int CKTacDump( CKTcircuit *, double , void *); +int CKTacLoad( CKTcircuit *); +int CKTaccept( CKTcircuit *); +int CKTacct( CKTcircuit *, void *, int , IFvalue *); +int CKTask( void *, void *, int , IFvalue *, IFvalue *); +int CKTaskAnalQ( void *, void *, int , IFvalue *, IFvalue *); +int CKTaskNodQst( void *, void *, int , IFvalue *, IFvalue *); +int CKTbindNode( void *, void *, int , void *); +void CKTbreakDump( CKTcircuit *); +int CKTclrBreak( CKTcircuit *); +int CKTconvTest( CKTcircuit *); +int CKTcrtElt( void *, void *, void **, IFuid ); +int CKTdelTask( void *, void *); +int CKTdestroy( void *); +int CKTdltAnal( void *, void *, void *); +int CKTdltInst( void *, void *); +int CKTdltMod( void *, void *); +int CKTdltNod( void *, void *); +int CKTdoJob( void *, int , void *); +void CKTdump( CKTcircuit *, double, void *); +int CKTfndAnal( void *, int *, void **, IFuid , void *, IFuid ); +int CKTfndBranch( CKTcircuit *, IFuid); +int CKTfndDev( void *, int *, void **, IFuid , void *, IFuid ); +int CKTfndMod( void *, int *, void **, IFuid ); +int CKTfndNode( void *, void **, IFuid ); +int CKTfndTask( void *, void **, IFuid ); +int CKTground( void *, void **, IFuid ); +int CKTic( CKTcircuit *); +int CKTinit( void **); +int CKTinst2Node( void *, void *, int , void **, IFuid *); +int CKTlinkEq(CKTcircuit*,CKTnode*); +int CKTload( CKTcircuit *); +int CKTmapNode( void *, void **, IFuid ); +int CKTmkCur( CKTcircuit *, CKTnode **, IFuid , char *); +int CKTmkNode(CKTcircuit*,CKTnode**); +int CKTmkVolt( CKTcircuit *, CKTnode **, IFuid , char *); +int CKTmodAsk( void *, void *, int , IFvalue *, IFvalue *); +int CKTmodCrt( void *, int , void **, IFuid ); +int CKTmodParam( void *, void *, int , IFvalue *, IFvalue *); +int CKTnames(CKTcircuit *, int *, IFuid **); +int CKTnewAnal( void *, int , IFuid , void **, void *); +int CKTnewEq( void *, void **, IFuid ); +int CKTnewNode( void *, void **, IFuid ); +int CKTnewTask( void *, void **, IFuid ); +IFuid CKTnodName( CKTcircuit *, int ); +void CKTnodOut( CKTcircuit *); +CKTnode * CKTnum2nod( CKTcircuit *, int ); +int CKTop(CKTcircuit *, long, long, int ); +int CKTpModName( char *, IFvalue *, CKTcircuit *, int , IFuid , GENmodel **); +int CKTpName( char *, IFvalue *, CKTcircuit *, int , char *, GENinstance **); +int CKTparam( void *, void *, int , IFvalue *, IFvalue *); +int CKTpzFindZeros( CKTcircuit *, PZtrial **, int * ); +int CKTpzLoad( CKTcircuit *, SPcomplex * ); +int CKTpzSetup( CKTcircuit *, int); +int CKTsenAC( CKTcircuit *); +int CKTsenComp( CKTcircuit *); +int CKTsenDCtran( CKTcircuit *); +int CKTsenLoad( CKTcircuit *); +void CKTsenPrint( CKTcircuit *); +int CKTsenSetup( CKTcircuit *); +int CKTsenUpdate( CKTcircuit *); +int CKTsetAnalPm( void *, void *, int , IFvalue *, IFvalue *); +int CKTsetBreak( CKTcircuit *, double ); +int CKTsetNodPm( void *, void *, int , IFvalue *, IFvalue *); +int CKTsetOpt( void *, void *, int , IFvalue *); +int CKTsetup( CKTcircuit *); +int CKTunsetup(CKTcircuit *ckt); +int CKTtemp( CKTcircuit *); +char *CKTtrouble(void *, char *); +void CKTterr( int , CKTcircuit *, double *); +int CKTtrunc( CKTcircuit *, double *); +int CKTtypelook( char *); +int DCOaskQuest( CKTcircuit *, void *, int , IFvalue *); +int DCOsetParm( CKTcircuit *, void *, int , IFvalue *); +int DCTaskQuest( CKTcircuit *, void *, int , IFvalue *); +int DCTsetParm( CKTcircuit *, void *, int , IFvalue *); +int DCop( CKTcircuit *); +int DCtrCurv( CKTcircuit *, int ); +int DCtran( CKTcircuit *, int ); +int DISTOan(CKTcircuit *, int); +int NOISEan(CKTcircuit *, int); +int PZan( CKTcircuit *, int ); +int PZinit( CKTcircuit * ); +int PZpost( CKTcircuit * ); +int PZaskQuest( CKTcircuit *, void *, int , IFvalue *); +int PZsetParm( CKTcircuit *, void *, int , IFvalue *); +int SENaskQuest( CKTcircuit *, void *, int , IFvalue *); +void SENdestroy( SENstruct *); +int SENsetParm( CKTcircuit *, void *, int , IFvalue *); +int SENstartup( CKTcircuit *); +int SPIinit( IFfrontEnd *, IFsimulator **); +char * SPerror( int ); +int TFanal( CKTcircuit *, int ); +int TFaskQuest( CKTcircuit *, void *, int , IFvalue *); +int TFsetParm( CKTcircuit *, void *, int , IFvalue *); +int TRANaskQuest( CKTcircuit *, void *, int , IFvalue *); +int TRANsetParm( CKTcircuit *, void *, int , IFvalue *); +int TRANinit(CKTcircuit *, JOB *); +int NIacIter( CKTcircuit * ); +int NIcomCof( CKTcircuit * ); +int NIconvTest(CKTcircuit * ); +void NIdestroy(CKTcircuit * ); +int NIinit( CKTcircuit * ); +int NIintegrate( CKTcircuit *, double *, double *, double , int ); +int NIiter( CKTcircuit * , int ); +int NIpzMuller(PZtrial **, PZtrial *); +int NIpzComplex(PZtrial **, PZtrial *); +int NIpzSym(PZtrial **, PZtrial *); +int NIpzSym2(PZtrial **, PZtrial *); +int NIreinit( CKTcircuit *); +int NIsenReinit( CKTcircuit *); +IFfrontEnd *SPfrontEnd; + +#endif /*CKT*/ diff --git a/src/spicelib/analysis/cktacct.c b/src/spicelib/analysis/cktacct.c new file mode 100644 index 000000000..3c83d6565 --- /dev/null +++ b/src/spicelib/analysis/cktacct.c @@ -0,0 +1,142 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* + * CKTacct + * get the specified accounting item into 'value' in the + * given circuit 'ckt'. + */ + +#include "ngspice.h" +#include "const.h" +#include "optdefs.h" +#include "ifsim.h" +#include +#include "cktdefs.h" +#include "spmatrix.h" + + + +/* ARGSUSED */ +int +CKTacct(CKTcircuit *ckt, void *anal, int which, IFvalue *val) +{ + switch(which) { + + case OPT_EQNS: + val->iValue = ckt->CKTmaxEqNum; + break; + case OPT_ORIGNZ: + if ( ckt->CKTmatrix != NULL ) { + val->iValue = spOriginalCount((char *)ckt->CKTmatrix); + } else { + val->iValue = 0; + } + break; + case OPT_FILLNZ: + if ( ckt->CKTmatrix != NULL ) { + val->iValue = spFillinCount((char *)ckt->CKTmatrix); + } else { + val->iValue = 0; + } + break; + case OPT_TOTALNZ: + if ( ckt->CKTmatrix != NULL ) { + val->iValue = spElementCount((char *)ckt->CKTmatrix); + } else { + val->iValue = 0; + } + break; + case OPT_ITERS: + val->iValue = ckt->CKTstat->STATnumIter; + break; + case OPT_TRANIT: + val->iValue = ckt->CKTstat->STATtranIter; + break; + case OPT_TRANCURITER: + val->iValue = ckt->CKTstat->STATnumIter - ckt->CKTstat->STAToldIter; + break; + case OPT_TRANPTS: + val->iValue = ckt->CKTstat->STATtimePts; + break; + case OPT_TRANACCPT: + val->iValue = ckt->CKTstat->STATaccepted; + break; + case OPT_TRANRJCT: + val->iValue = ckt->CKTstat->STATrejected; + break; + case OPT_TOTANALTIME: + val->rValue = ckt->CKTstat->STATtotAnalTime; + break; + case OPT_TRANTIME: + val->rValue = ckt->CKTstat->STATtranTime; + break; + case OPT_ACTIME: + val->rValue = ckt->CKTstat->STATacTime; + break; + case OPT_LOADTIME: + val->rValue = ckt->CKTstat->STATloadTime; + break; + case OPT_SYNCTIME: + val->rValue = ckt->CKTstat->STATsyncTime; + break; + case OPT_COMBTIME: + val->rValue = ckt->CKTstat->STATcombineTime; + break; + case OPT_REORDTIME: + val->rValue = ckt->CKTstat->STATreorderTime; + break; + case OPT_DECOMP: + val->rValue = ckt->CKTstat->STATdecompTime; + break; + case OPT_SOLVE: + val->rValue = ckt->CKTstat->STATsolveTime; + break; + case OPT_TRANLOAD: + val->rValue = ckt->CKTstat->STATtranLoadTime; + break; + case OPT_TRANSYNC: + val->rValue = ckt->CKTstat->STATtranSyncTime; + break; + case OPT_TRANCOMB: + val->rValue = ckt->CKTstat->STATtranCombTime; + break; + case OPT_TRANDECOMP: + val->rValue = ckt->CKTstat->STATtranDecompTime; + break; + case OPT_TRANSOLVE: + val->rValue = ckt->CKTstat->STATtranSolveTime; + break; + case OPT_TRANTRUNC: + val->rValue = ckt->CKTstat->STATtranTruncTime; + break; + case OPT_ACLOAD: + val->rValue = ckt->CKTstat->STATacLoadTime; + break; + case OPT_ACSYNC: + val->rValue = ckt->CKTstat->STATacSyncTime; + break; + case OPT_ACCOMB: + val->rValue = ckt->CKTstat->STATacCombTime; + break; + case OPT_ACDECOMP: + val->rValue = ckt->CKTstat->STATacDecompTime; + break; + case OPT_ACSOLVE: + val->rValue = ckt->CKTstat->STATacSolveTime; + break; + case OPT_TEMP: + val->rValue = ckt->CKTtemp - CONSTCtoK; + break; + case OPT_TNOM: + val->rValue = ckt->CKTnomTemp - CONSTCtoK; + break; + default: + return(-1); + } + return(0); +} diff --git a/src/spicelib/analysis/cktacdum.c b/src/spicelib/analysis/cktacdum.c new file mode 100644 index 000000000..041382c78 --- /dev/null +++ b/src/spicelib/analysis/cktacdum.c @@ -0,0 +1,43 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* CKTacDump(ckt,freq,file) + * this is a simple program to dump the complex rhs vector + * into the rawfile. + */ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "iferrmsg.h" +#include "ifsim.h" + + + +int +CKTacDump(CKTcircuit *ckt, double freq, void *plot) +{ + double *rhsold; + double *irhsold; + int i; + IFcomplex *data; + IFvalue freqData; + IFvalue valueData; + + rhsold = ckt->CKTrhsOld; + irhsold = ckt->CKTirhsOld; + freqData.rValue = freq; + valueData.v.numValue = ckt->CKTmaxEqNum-1; + data = (IFcomplex *) MALLOC((ckt->CKTmaxEqNum-1)*sizeof(IFcomplex)); + valueData.v.vec.cVec = data; + for (i=0;iCKTmaxEqNum-1;i++) { + data[i].real = rhsold[i+1]; + data[i].imag = irhsold[i+1]; + } + (*(SPfrontEnd->OUTpData))(plot,&freqData,&valueData); + FREE(data); + return(OK); +} diff --git a/src/spicelib/analysis/cktaskaq.c b/src/spicelib/analysis/cktaskaq.c new file mode 100644 index 000000000..dbeb8690c --- /dev/null +++ b/src/spicelib/analysis/cktaskaq.c @@ -0,0 +1,26 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "tskdefs.h" +#include "jobdefs.h" +#include "cktdefs.h" +#include "ifsim.h" +#include "iferrmsg.h" + +#include "analysis.h" + +extern SPICEanalysis *analInfo[]; + +/* ARGSUSED */ +int +CKTaskAnalQ(void *ckt, void *analPtr, int parm, IFvalue *value, IFvalue *selector) +{ + int type = ((JOB *)analPtr)->JOBtype; + + if((analInfo[type]->askQuest) == NULL) return(E_BADPARM); + return( (*(analInfo[type]->askQuest))((CKTcircuit*)ckt,analPtr,parm,value)); +} diff --git a/src/spicelib/analysis/cktasknq.c b/src/spicelib/analysis/cktasknq.c new file mode 100644 index 000000000..ad568521f --- /dev/null +++ b/src/spicelib/analysis/cktasknq.c @@ -0,0 +1,43 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* + *CKTaskNodQst + * + * ask about a parameter on a node. + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "cktdefs.h" + + + +/* ARGSUSED */ +int +CKTaskNodQst(void *ckt, void *node, int parm, IFvalue *value, IFvalue *selector) +{ + if(!node) return(E_BADPARM); + switch(parm) { + + case PARM_NS: + value->rValue = ((CKTnode *)node)->nodeset; + break; + + case PARM_IC: + value->rValue = ((CKTnode *)node)->ic; + break; + + case PARM_NODETYPE: + value->iValue = ((CKTnode *)node)->type; + break; + + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/analysis/cktbkdum.c b/src/spicelib/analysis/cktbkdum.c new file mode 100644 index 000000000..41df6e80d --- /dev/null +++ b/src/spicelib/analysis/cktbkdum.c @@ -0,0 +1,25 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* CKTbreakDump(ckt) - dump the breakpoint table associated with + * the given circuit + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" + + + +void +CKTbreakDump(CKTcircuit *ckt) +{ + int i; + for(i=0;iCKTbreakSize;i++) { + (void)printf("breakpoint table entry %d is %g\n",i,*(ckt->CKTbreaks+i)); + } +} diff --git a/src/spicelib/analysis/cktclrbk.c b/src/spicelib/analysis/cktclrbk.c new file mode 100644 index 000000000..7d224bf6e --- /dev/null +++ b/src/spicelib/analysis/cktclrbk.c @@ -0,0 +1,39 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* CKTclrBreak(ckt) + * delete the first time from the breakpoint table for the given circuit + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "sperror.h" + + + +int +CKTclrBreak(CKTcircuit *ckt) +{ + double *tmp; + int j; + + if(ckt->CKTbreakSize >2) { + tmp = (double *)MALLOC((ckt->CKTbreakSize-1)*sizeof(double)); + if(tmp == (double *)NULL) return(E_NOMEM); + for(j=1;jCKTbreakSize;j++) { + *(tmp+j-1) = *(ckt->CKTbreaks+j); + } + FREE(ckt->CKTbreaks); + ckt->CKTbreakSize--; + ckt->CKTbreaks=tmp; + } else { + *(ckt->CKTbreaks)= *(ckt->CKTbreaks+1); + *(ckt->CKTbreaks+1) = ckt->CKTfinalTime; + } + return(OK); +} diff --git a/src/spicelib/analysis/cktdelt.c b/src/spicelib/analysis/cktdelt.c new file mode 100644 index 000000000..baa39e850 --- /dev/null +++ b/src/spicelib/analysis/cktdelt.c @@ -0,0 +1,27 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "tskdefs.h" +#include "jobdefs.h" +#include "ifsim.h" +#include "iferrmsg.h" + + +/* ARGSUSED */ +int +CKTdelTask(void *ckt, void *task) +{ + JOB *job; + JOB *old=NULL; + for(job = ((TSKtask*)task)->jobs; job; job=job->JOBnextJob){ + if(old) FREE(old); + old=job; + } + if(old)FREE(old); + FREE(task); + return(OK); +} diff --git a/src/spicelib/analysis/cktdest.c b/src/spicelib/analysis/cktdest.c new file mode 100644 index 000000000..3e87fee42 --- /dev/null +++ b/src/spicelib/analysis/cktdest.c @@ -0,0 +1,62 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* CKTdestroy(ckt) + * this is a driver program to iterate through all the various + * destroy functions provided for the circuit elements in the + * given circuit + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "devdefs.h" +#include "ifsim.h" +#include "sperror.h" + + +extern SPICEdev **DEVices; + + +int +CKTdestroy(void *inCkt) +{ + CKTcircuit *ckt = (CKTcircuit *)inCkt; + int i; + CKTnode *node; + CKTnode *nnode; + + +#ifdef WANT_SENSE2 + if(ckt->CKTsenInfo){ + if(ckt->CKTrhsOp) FREE(ckt->CKTrhsOp); + if(ckt->CKTsenRhs) FREE(ckt->CKTsenRhs); + if(ckt->CKTseniRhs) FREE(ckt->CKTseniRhs); + SENdestroy(ckt->CKTsenInfo); + } +#endif + + for (i=0;iCKThead[i] != NULL) ){ + (*((*DEVices[i]).DEVdestroy))(&(ckt->CKThead[i])); + } + } + for(i=0;i<=ckt->CKTmaxOrder+1;i++){ + FREE(ckt->CKTstates[i]); + } + if(ckt->CKTmatrix) SMPdestroy(ckt->CKTmatrix); + if(ckt->CKTbreaks) FREE(ckt->CKTbreaks); + for(node = ckt->CKTnodes; node; ) { + nnode = node->next; + FREE(node); + node = nnode; + } + ckt->CKTnodes = (CKTnode *)NULL; + ckt->CKTlastNode = (CKTnode *)NULL; + FREE(ckt); + return(OK); +} diff --git a/src/spicelib/analysis/cktdisto.c b/src/spicelib/analysis/cktdisto.c new file mode 100644 index 000000000..71f45c42d --- /dev/null +++ b/src/spicelib/analysis/cktdisto.c @@ -0,0 +1,176 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Jaijeet S Roychowdhury +**********/ + +/* + * CKTdisto (ckt, mode) + */ + + +#include "ngspice.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "vsrc/vsrcdefs.h" +#include "isrc/isrcdefs.h" +#include "iferrmsg.h" +#include "distodef.h" +#include "sperror.h" +#include + + +int +CKTdisto (CKTcircuit *ckt, int mode) +{ + extern SPICEdev **DEVices; + DISTOAN* cv = (DISTOAN*) (ckt->CKTcurJob); + int i; + int error=0; + int size; + + switch(mode) { + + case D_SETUP: + + for (i=0;iCKThead[i] != NULL) ){ + error = (*((*DEVices[i]).DEVdisto))(mode,ckt->CKThead[i],ckt); + if(error) return(error); + } + } + break; + + case D_TWOF1: + case D_THRF1: + case D_F1PF2: + case D_F1MF2: + case D_2F1MF2: + + size = SMPmatSize(ckt->CKTmatrix); + for (i=1; i<=size; i++) + { + ckt->CKTrhs[i] = 0.0; + ckt->CKTirhs[i] = 0.0; + } + + for (i=0;iCKThead[i] != NULL) ){ + error = (*((*DEVices[i]).DEVdisto))(mode,ckt->CKThead[i],ckt); + if(error) return(error); + } + } + break; + + case D_RHSF1: + + cv->Df2given = 0; /* will change if any F2 source is found */ + + case D_RHSF2: + + + +{ + int vcode; + int icode; + double mag=0.0; + double phase=0.0; + int size; + + size = SMPmatSize(ckt->CKTmatrix); + for (i=0;i<=size;i++) { + *(ckt->CKTrhs+i)=0; + *(ckt->CKTirhs+i)=0; + } + + vcode = CKTtypelook("Vsource"); + icode = CKTtypelook("Isource"); + + + if(vcode >= 0) { + /* voltage sources are in this version, so use them */ + VSRCinstance *here; + VSRCmodel *model; + for(model = (VSRCmodel *)ckt->CKThead[vcode];model != NULL; + model=model->VSRCnextModel){ + for(here=model->VSRCinstances;here!=NULL; + here=here->VSRCnextInstance) { + +/* check if the source has a distortion input*/ + +if (here->VSRCdGiven) { + if (here->VSRCdF2given) cv->Df2given = 1; + if ((here->VSRCdF1given) && (mode == D_RHSF1)) { + + mag = here->VSRCdF1mag; + phase = here->VSRCdF1phase; +} +else if ((here->VSRCdF2given) && (mode == D_RHSF2)) { + + mag = here->VSRCdF2mag; + phase = here->VSRCdF2phase; +} +if (((here->VSRCdF1given) && (mode == D_RHSF1)) || + ((here->VSRCdF2given) && (mode == D_RHSF2))) { + + *(ckt->CKTrhs + here->VSRCbranch) = 0.5*mag* cos(M_PI*phase/180.0); + *(ckt->CKTirhs + here->VSRCbranch) = 0.5*mag*sin(M_PI*phase/180.0); +} + + + } + } + } + } + if(icode >= 0 ) { + /* current sources are in this version, so use them */ + ISRCinstance *here; + ISRCmodel *model; + + for(model= (ISRCmodel *)ckt->CKThead[icode];model != NULL; + model=model->ISRCnextModel){ + for(here=model->ISRCinstances;here!=NULL; + here=here->ISRCnextInstance) { + +/* check if the source has a distortion input*/ + +if (here->ISRCdGiven) { + if (here->ISRCdF2given) cv->Df2given = 1; + if ((here->ISRCdF1given) && (mode == D_RHSF1)) { + + mag = here->ISRCdF1mag; + phase = here->ISRCdF1phase; +} +else if ((here->ISRCdF2given) && (mode == D_RHSF2)) { + + mag = here->ISRCdF2mag; + phase = here->ISRCdF2phase; +} +if (((here->ISRCdF1given) && (mode == D_RHSF1)) || + ((here->ISRCdF2given) && (mode == D_RHSF2))) { + + *(ckt->CKTrhs + here->ISRCposNode) = - 0.5 * mag + * cos(M_PI*phase/180.0); + *(ckt->CKTrhs + here->ISRCnegNode) = 0.5 * mag * cos( + M_PI*phase/180.0); + *(ckt->CKTirhs + here->ISRCposNode) = - 0.5 * mag * sin( + M_PI*phase/180.0); + *(ckt->CKTirhs + here->ISRCnegNode) = 0.5 * mag * sin( + M_PI*phase/180.0); +} + } + } + } + } +} +error = 0; +break; + + default: + + error = E_BADPARM; + break; + } + + return(error); + +} diff --git a/src/spicelib/analysis/cktdlti.c b/src/spicelib/analysis/cktdlti.c new file mode 100644 index 000000000..ac07253c8 --- /dev/null +++ b/src/spicelib/analysis/cktdlti.c @@ -0,0 +1,25 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* CKTdltInst + * delete the specified instance - not yet supported in spice + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "ifsim.h" +#include "sperror.h" + + + +/* ARGSUSED */ +int +CKTdltInst(void *ckt, void *instance) +{ + return(E_UNSUPP); +} diff --git a/src/spicelib/analysis/cktdltm.c b/src/spicelib/analysis/cktdltm.c new file mode 100644 index 000000000..17e763da6 --- /dev/null +++ b/src/spicelib/analysis/cktdltm.c @@ -0,0 +1,45 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +/* CKTdltMod + * delete the specified model - not yet supported in spice + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "ifsim.h" +#include "sperror.h" + + + +/* ARGSUSED */ +int +CKTdltMod(void *cktp, void *modPtr) +{ + CKTcircuit *ckt = (CKTcircuit *) cktp; + GENmodel *m = (GENmodel *) modPtr, *mod, **prevp; + GENinstance *h, *next_i; + int error; + + prevp = &ckt->CKThead[m->GENmodType]; + for (mod = *prevp; m && mod != m; mod = mod->GENnextModel) + prevp = &mod->GENnextModel; + + if (!mod) + return OK; + + *prevp = m->GENnextModel; + + for (h = m->GENinstances; h; h = next_i) { + next_i = h->GENnextInstance; + error = (*(SPfrontEnd->IFdelUid))((void *)ckt,h->GENname, + UID_INSTANCE); + tfree(h); + } + error = (*(SPfrontEnd->IFdelUid))((void *)ckt,m->GENmodName, UID_MODEL); + tfree(m); + return(OK); +} diff --git a/src/spicelib/analysis/cktdltn.c b/src/spicelib/analysis/cktdltn.c new file mode 100644 index 000000000..c76e2ff30 --- /dev/null +++ b/src/spicelib/analysis/cktdltn.c @@ -0,0 +1,59 @@ +/********** +Copyright 1992 Regents of the University of California. All rights reserved. +**********/ + +/* CKTdltNod +*/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "ifsim.h" +#include "sperror.h" + +int CKTdltNNum(void *cktp, int num); + +/* ARGSUSED */ +int +CKTdltNod(void *ckt, void *node) +{ + return CKTdltNNum(ckt, ((CKTnode *) node)->number); +} + +int +CKTdltNNum(void *cktp, int num) +{ + CKTcircuit *ckt = (CKTcircuit *) cktp; + CKTnode *n, *prev, *node, *sprev; + int error; + + prev = NULL; + node = NULL; + sprev = NULL; + + for (n = ckt->CKTnodes; n; n = n->next) { + if (n->number == num) { + node = n; + sprev = prev; + } + prev = n; + } + + if (!node) + return OK; + + ckt->CKTmaxEqNum -= 1; + + if (!sprev) { + ckt->CKTnodes = node->next; + } else { + sprev->next = node->next; + } + if (node == ckt->CKTlastNode) + ckt->CKTlastNode = sprev; + + error = (*(SPfrontEnd->IFdelUid))((void *)ckt,node->name, UID_SIGNAL); + tfree(node); + + return error; +} diff --git a/src/spicelib/analysis/cktdojob.c b/src/spicelib/analysis/cktdojob.c new file mode 100644 index 000000000..71e2857f4 --- /dev/null +++ b/src/spicelib/analysis/cktdojob.c @@ -0,0 +1,177 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes +**********/ + +#include "ngspice.h" +#include "cktdefs.h" +#include +#include "sperror.h" +#include "trandefs.h" + +#include "analysis.h" + +#ifdef XSPICE +/* gtri - add - wbk - 11/26/90 - add include for MIF and EVT global data */ +#include "mif.h" +#include "evtproto.h" +/* gtri - end - wbk - 11/26/90 */ +#endif + +extern SPICEanalysis *analInfo[]; + +int +CKTdoJob(void *inCkt, int reset, void *inTask) +{ + CKTcircuit *ckt = (CKTcircuit *)inCkt; + TSKtask *task = (TSKtask *)inTask; + JOB *job; + double startTime; + int error, i, error2; + int ANALmaxnum; + +#ifdef WANT_SENSE2 + int senflag; + static int sens_num = -1; + + /* Sensitivity is special */ + if (sens_num < 0) { + for (i = 0; i < ANALmaxnum; i++) + if (!strcmp("SENS2", analInfo[i]->public.name)) + break; + sens_num = i; + } +#endif + + ANALmaxnum = spice_num_analysis(); + + startTime = (*(SPfrontEnd->IFseconds))( ); + + ckt->CKTtemp = task->TSKtemp; + ckt->CKTnomTemp = task->TSKnomTemp; + ckt->CKTmaxOrder = task->TSKmaxOrder; + ckt->CKTintegrateMethod = task->TSKintegrateMethod; + ckt->CKTbypass = task->TSKbypass; + ckt->CKTdcMaxIter = task->TSKdcMaxIter; + ckt->CKTdcTrcvMaxIter = task->TSKdcTrcvMaxIter; + ckt->CKTtranMaxIter = task->TSKtranMaxIter; + ckt->CKTnumSrcSteps = task->TSKnumSrcSteps; + ckt->CKTnumGminSteps = task->TSKnumGminSteps; + ckt->CKTgminFactor = task->TSKgminFactor; + ckt->CKTminBreak = task->TSKminBreak; + ckt->CKTabstol = task->TSKabstol; + ckt->CKTpivotAbsTol = task->TSKpivotAbsTol; + ckt->CKTpivotRelTol = task->TSKpivotRelTol; + ckt->CKTreltol = task->TSKreltol; + ckt->CKTchgtol = task->TSKchgtol; + ckt->CKTvoltTol = task->TSKvoltTol; + ckt->CKTgmin = task->TSKgmin; + ckt->CKTgshunt = task->TSKgshunt; + ckt->CKTdelmin = task->TSKdelmin; + ckt->CKTtrtol = task->TSKtrtol; + ckt->CKTdefaultMosM = task->TSKdefaultMosM; + ckt->CKTdefaultMosL = task->TSKdefaultMosL; + ckt->CKTdefaultMosW = task->TSKdefaultMosW; + ckt->CKTdefaultMosAD = task->TSKdefaultMosAD; + ckt->CKTdefaultMosAS = task->TSKdefaultMosAS; + ckt->CKTfixLimit = task->TSKfixLimit; + ckt->CKTnoOpIter = task->TSKnoOpIter; + ckt->CKTtryToCompact = task->TSKtryToCompact; + ckt->CKTbadMos3 = task->TSKbadMos3; + ckt->CKTkeepOpInfo = task->TSKkeepOpInfo; + ckt->CKTcopyNodesets = task->TSKcopyNodesets; + ckt->CKTnodeDamping = task->TSKnodeDamping; + ckt->CKTabsDv = task->TSKabsDv; + ckt->CKTrelDv = task->TSKrelDv; + ckt->CKTtroubleNode = 0; + ckt->CKTtroubleElt = NULL; +#ifdef NEWTRUNC + ckt->CKTlteReltol = task->TSKlteReltol; + ckt->CKTlteAbstol = task->TSKlteAbstol; +#endif /* NEWTRUNC */ + +printf("Doing analysis at TEMP = %f and TNOM = %f\n", + ckt->CKTtemp, ckt->CKTnomTemp); + error = 0; + + if (reset) { + + ckt->CKTdelta = 0.0; + ckt->CKTtime = 0.0; + ckt->CKTcurrentAnalysis = 0; + +#ifdef WANT_SENSE2 + senflag = 0; + if (sens_num < ANALmaxnum) + for (job = task->jobs; !error && job; job = job->JOBnextJob) { + if (job->JOBtype == sens_num) { + senflag = 1; + ckt->CKTcurJob = job; + ckt->CKTsenInfo = (SENstruct *) job; + error = (*(analInfo[sens_num]->an_func))(ckt, reset); + } + } + + if (ckt->CKTsenInfo && (!senflag || error)) + FREE(ckt->CKTsenInfo); +#endif + + /* normal reset */ + if (!error) + error = CKTunsetup(ckt); + if (!error) + error = CKTsetup(ckt); + if (!error) + error = CKTtemp(ckt); + if (error) + return error; + } + + error2 = OK; + + /* Analysis order is important */ + for (i = 0; i < ANALmaxnum; i++) { + +#ifdef WANT_SENSE2 + if (i == sens_num) + continue; +#endif + + for (job = task->jobs; job; job = job->JOBnextJob) { + if (job->JOBtype == i) { + ckt->CKTcurJob=job; + error = OK; + if (analInfo[i]->an_init) + error = (*(analInfo[i]->an_init))(ckt, job); + if (!error && analInfo[i]->do_ic) + error = CKTic(ckt); + if (!error){ +#ifdef XSPICE + /* gtri - begin - 6/10/91 - wbk - Setup event-driven data */ + error = EVTsetup(ckt); + if(error) { + ckt->CKTstat->STATtotAnalTime += + (*(SPfrontEnd->IFseconds))()-startTime; + return(error); + } + /* gtri - end - 6/10/91 - wbk - Setup event-driven data */ +#endif + error = (*(analInfo[i]->an_func))(ckt, reset); + } + if (error) + error2 = error; + } + } + } + + ckt->CKTstat->STATtotAnalTime += (*(SPfrontEnd->IFseconds))( ) - startTime; + +#ifdef WANT_SENSE2 + if (ckt->CKTsenInfo) + SENdestroy(ckt->CKTsenInfo); +#endif + + return(error2); +} + diff --git a/src/spicelib/analysis/cktdump.c b/src/spicelib/analysis/cktdump.c new file mode 100644 index 000000000..3009428ac --- /dev/null +++ b/src/spicelib/analysis/cktdump.c @@ -0,0 +1,29 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* CKTdump(ckt) + * this is a simple program to dump the rhs vector to stdout + */ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" + + + +void +CKTdump(CKTcircuit *ckt, double ref, void *plot) +{ + IFvalue refData; + IFvalue valData; + + refData.rValue = ref; + valData.v.numValue = ckt->CKTmaxEqNum-1; + valData.v.vec.rVec = ckt->CKTrhsOld+1; + (*(SPfrontEnd->OUTpData))(plot,&refData,&valData); +} diff --git a/src/spicelib/analysis/cktfbran.c b/src/spicelib/analysis/cktfbran.c new file mode 100644 index 000000000..518462be7 --- /dev/null +++ b/src/spicelib/analysis/cktfbran.c @@ -0,0 +1,35 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* CKTfndBranch(ckt,name) + * this is a driver program to iterate through all the various + * findBranch functions provided for the circuit elements in the + * given circuit + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "devdefs.h" + + + +int +CKTfndBranch(CKTcircuit *ckt, IFuid name) +{ + extern SPICEdev **DEVices; + int i; + int j; + + for (i=0;iCKThead[i] != NULL) { + j = (*((*DEVices[i]).DEVfindBranch))(ckt,ckt->CKThead[i],name); + if(j != 0) return(j); + } + } + return(0); +} diff --git a/src/spicelib/analysis/cktfnda.c b/src/spicelib/analysis/cktfnda.c new file mode 100644 index 000000000..5e23e4544 --- /dev/null +++ b/src/spicelib/analysis/cktfnda.c @@ -0,0 +1,36 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* CKTfndAnal + * find the given Analysis given its name and return the Analysis pointer + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "jobdefs.h" +#include "tskdefs.h" +#include "sperror.h" +#include "cktdefs.h" + + + +/* ARGSUSED */ +int +CKTfndAnal(void *ckt, int *analIndex, void **anal, IFuid name, void *inTask, IFuid taskName) +{ + TSKtask *task = (TSKtask *)inTask; + JOB *here; + + for (here = ((TSKtask *)task)->jobs;here;here = here->JOBnextJob) { + if(strcmp(here->JOBname,name)==0) { + if(anal) *anal = (void *)here; + return(OK); + } + } + return(E_NOTFOUND); +} diff --git a/src/spicelib/analysis/cktfndm.c b/src/spicelib/analysis/cktfndm.c new file mode 100644 index 000000000..adee2262b --- /dev/null +++ b/src/spicelib/analysis/cktfndm.c @@ -0,0 +1,53 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "ifsim.h" +#include "sperror.h" + + + +int +CKTfndMod(void *ckt, int *type, void **modfast, IFuid modname) +{ + GENmodel *mods; + + if(modfast != NULL && *(GENmodel **)modfast != NULL) { + /* already have modfast, so nothing to do */ + if(type) *type = (*(GENmodel **)modfast)->GENmodType; + return(OK); + } + if(*type >=0 && *type < DEVmaxnum) { + /* have device type, need to find model */ + /* look through all models */ + for(mods=((CKTcircuit *)ckt)->CKThead[*type]; mods != NULL ; + mods = mods->GENnextModel) { + if(mods->GENmodName == modname) { + *modfast = (char *)mods; + return(OK); + } + } + return(E_NOMOD); + } else if(*type == -1) { + /* look through all types (UGH - worst case - take forever) */ + for(*type = 0;*type CKThead[*type];mods!=NULL; + mods = mods->GENnextModel) { + if(mods->GENmodName == modname) { + *modfast = (char *)mods; + return(OK); + } + } + } + *type = -1; + return(E_NOMOD); + } else return(E_BADPARM); +} diff --git a/src/spicelib/analysis/cktfnode.c b/src/spicelib/analysis/cktfnode.c new file mode 100644 index 000000000..b8b9082fe --- /dev/null +++ b/src/spicelib/analysis/cktfnode.c @@ -0,0 +1,33 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* CKTfndNode + * find the given node given its name and return the node pointer + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "sperror.h" +#include "cktdefs.h" + + + +/* ARGSUSED */ +int +CKTfndNode(void *ckt, void **node, IFuid name) +{ + CKTnode *here; + + for (here = ((CKTcircuit *)ckt)->CKTnodes; here; here = here->next) { + if(here->name == name) { + if(node) *node = (char *)here; + return(OK); + } + } + return(E_NOTFOUND); +} diff --git a/src/spicelib/analysis/cktftask.c b/src/spicelib/analysis/cktftask.c new file mode 100644 index 000000000..d5186845b --- /dev/null +++ b/src/spicelib/analysis/cktftask.c @@ -0,0 +1,25 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* CKTfndTask + * find the specified task - not yet supported in spice + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "ifsim.h" +#include "sperror.h" + + + +/* ARGSUSED */ +int +CKTfndTask(void *ckt, void **taskPtr, IFuid taskName) +{ + return(E_UNSUPP); +} diff --git a/src/spicelib/analysis/cktgrnd.c b/src/spicelib/analysis/cktgrnd.c new file mode 100644 index 000000000..6c838ab9e --- /dev/null +++ b/src/spicelib/analysis/cktgrnd.c @@ -0,0 +1,46 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* CKTground(ckt,node) + * specify the node to be the ground node of the given circuit + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "ifsim.h" +#include "sperror.h" + + + +int +CKTground(void *inCkt, void **node, IFuid name) +{ + CKTcircuit *ckt = (CKTcircuit *)inCkt; + + if(ckt->CKTnodes) { + if(ckt->CKTnodes->name) { + /*already exists - keep old name, but return it */ + if(node)*node = (char *)ckt->CKTnodes; + return(E_EXISTS); + } + ckt->CKTnodes->name = name; + ckt->CKTnodes->type = SP_VOLTAGE; + ckt->CKTnodes->number = 0; + } else { + ckt->CKTnodes = (CKTnode *)MALLOC(sizeof(CKTnode)); + if(ckt->CKTnodes == NULL) return(E_NOMEM); + ckt->CKTnodes->name = name; + ckt->CKTnodes->type = SP_VOLTAGE; + ckt->CKTnodes->number = 0; + ckt->CKTnodes->next = (CKTnode *)NULL; + ckt->CKTlastNode = ckt->CKTnodes; + } + if(node)*node = (char *)ckt->CKTnodes; + return(OK); + +} diff --git a/src/spicelib/analysis/ckti2nod.c b/src/spicelib/analysis/ckti2nod.c new file mode 100644 index 000000000..3adef7552 --- /dev/null +++ b/src/spicelib/analysis/ckti2nod.c @@ -0,0 +1,66 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* CKTinst2Node + * get the name and node pointer for a node given a device it is + * bound to and the terminal of the device. + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "sperror.h" +#include "cktdefs.h" +#include "gendefs.h" +#include "devdefs.h" + + + +extern SPICEdev **DEVices; + +int +CKTinst2Node(void *ckt, void *instPtr, int terminal, void **node, IFuid *nodeName) +{ + int nodenum; + int type; + CKTnode *here; + + type = ((GENinstance *)instPtr)->GENmodPtr->GENmodType; + + if(*((*DEVices[type]).DEVpublic.terms) >= terminal && terminal >0 ) { + switch(terminal) { + default: return(E_NOTERM); + case 1: + nodenum = ((GENinstance *)instPtr)->GENnode1; + break; + case 2: + nodenum = ((GENinstance *)instPtr)->GENnode2; + break; + case 3: + nodenum = ((GENinstance *)instPtr)->GENnode3; + break; + case 4: + nodenum = ((GENinstance *)instPtr)->GENnode4; + break; + case 5: + nodenum = ((GENinstance *)instPtr)->GENnode5; + break; + } + /* ok, now we know its number, so we just have to find it.*/ + for(here = ((CKTcircuit*)ckt)->CKTnodes;here;here = here->next) { + if(here->number == nodenum) { + /* found it */ + *node = (void*) here; + *nodeName = here->name; + return(OK); + } + } + return(E_NOTFOUND); + } else { + return(E_NOTERM); + } +} diff --git a/src/spicelib/analysis/cktic.c b/src/spicelib/analysis/cktic.c new file mode 100644 index 000000000..8fbb70c66 --- /dev/null +++ b/src/spicelib/analysis/cktic.c @@ -0,0 +1,59 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "smpdefs.h" +#include "sperror.h" +#include "devdefs.h" + + + + +extern SPICEdev **DEVices; + + +int +CKTic(CKTcircuit *ckt) +{ + int error; + int size; + int i; + CKTnode *node; + + size = SMPmatSize(ckt->CKTmatrix); + for (i=0;i<=size;i++) { + *(ckt->CKTrhs+i)=0; + } + + for(node = ckt->CKTnodes;node != NULL; node = node->next) { + if(node->nsGiven) { + node->ptr = SMPmakeElt(ckt->CKTmatrix,node->number,node->number); + if(node->ptr == (double *)NULL) return(E_NOMEM); + ckt->CKThadNodeset = 1; + *(ckt->CKTrhs+node->number) = node->nodeset; + } + if(node->icGiven) { + if(! ( node->ptr)) { + node->ptr = SMPmakeElt(ckt->CKTmatrix,node->number, + node->number); + if(node->ptr == (double *)NULL) return(E_NOMEM); + } + *(ckt->CKTrhs+node->number) = node->ic; + } + } + + if(ckt->CKTmode & MODEUIC) { + for (i=0;iCKThead[i] != NULL) ){ + error = (*((*DEVices[i]).DEVsetic))(ckt->CKThead[i],ckt); + if(error) return(error); + } + } + } + + return(OK); +} diff --git a/src/spicelib/analysis/cktlnkeq.c b/src/spicelib/analysis/cktlnkeq.c new file mode 100644 index 000000000..ae9f65286 --- /dev/null +++ b/src/spicelib/analysis/cktlnkeq.c @@ -0,0 +1,36 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* + *CKTlinkEq + * Link an already allocated node into the necessary structure + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "smpdefs.h" +#include "cktdefs.h" + + +int +CKTlinkEq(CKTcircuit *ckt, CKTnode *node) +{ + if(!(ckt->CKTnodes)) { /* starting the list - allocate both ground and 1 */ + ckt->CKTnodes = (CKTnode *) MALLOC(sizeof(CKTnode)); + if(ckt->CKTnodes == (CKTnode *)NULL) return(E_NOMEM); + ckt->CKTnodes->name = (char *)NULL; + ckt->CKTnodes->type = SP_VOLTAGE; + ckt->CKTnodes->number = 0; + ckt->CKTlastNode = ckt->CKTnodes; + } + if(node == (CKTnode *)NULL) return(E_BADPARM); + ckt->CKTlastNode->next = node; + ckt->CKTlastNode = ckt->CKTlastNode->next; + ckt->CKTlastNode->number = ckt->CKTmaxEqNum++; + ckt->CKTlastNode->next = (CKTnode *)NULL; + return(OK); +} diff --git a/src/spicelib/analysis/cktload.c b/src/spicelib/analysis/cktload.c new file mode 100644 index 000000000..e86bec724 --- /dev/null +++ b/src/spicelib/analysis/cktload.c @@ -0,0 +1,217 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes +**********/ +/* + */ + + /* CKTload(ckt) + * this is a driver program to iterate through all the various + * load functions provided for the circuit elements in the + * given circuit + */ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "sperror.h" + +#ifdef XSPICE +/* gtri - add - wbk - 11/26/90 - add include for MIF global data */ +#include "mif.h" +/* gtri - end - wbk - 11/26/90 */ +#endif + +static int ZeroNoncurRow(SMPmatrix *matrix, CKTnode *nodes, int rownum); + +int +CKTload(CKTcircuit *ckt) +{ + extern SPICEdev **DEVices; + int i; + int size; + double startTime; + CKTnode *node; + int error; +#ifdef PARALLEL_ARCH + int ibuf[2]; + long type = MT_LOAD, length = 2; +#endif /* PARALLEL_ARCH */ +#ifdef STEPDEBUG + int noncon; +#endif /* STEPDEBUG */ + +#ifdef XSPICE + /* gtri - begin - Put resistors to ground at all nodes */ + /* SMPmatrix *matrix; maschmann : deleted , because unused */ + + double gshunt; + int num_nodes; + + /* gtri - begin - Put resistors to ground at all nodes */ +#endif + + startTime = (*(SPfrontEnd->IFseconds))(); + size = SMPmatSize(ckt->CKTmatrix); + for (i=0;i<=size;i++) { + *(ckt->CKTrhs+i)=0; + } + SMPclear(ckt->CKTmatrix); +#ifdef STEPDEBUG + noncon = ckt->CKTnoncon; +#endif /* STEPDEBUG */ + + for (i=0;iCKThead[i] != NULL) ){ + error = (*((*DEVices[i]).DEVload))(ckt->CKThead[i],ckt); + if (ckt->CKTnoncon) + ckt->CKTtroubleNode = 0; +#ifdef STEPDEBUG + if(noncon != ckt->CKTnoncon) { + printf("device type %s nonconvergence\n", + (*DEVices[i]).DEVpublic.name); + noncon = ckt->CKTnoncon; + } +#endif /* STEPDEBUG */ +#ifdef PARALLEL_ARCH + if (error) goto combine; +#else + if(error) return(error); +#endif /* PARALLEL_ARCH */ + } + } + + /* gtri - add - wbk - 11/26/90 - reset the MIF init flags */ +#ifdef XSPICE + /* init is set by CKTinit and should be true only for first load call */ + g_mif_info.circuit.init = MIF_FALSE; + + /* anal_init is set by CKTdoJob and is true for first call */ + /* of a particular analysis type */ + g_mif_info.circuit.anal_init = MIF_FALSE; + + /* gtri - end - wbk - 11/26/90 */ + + /* gtri - begin - Put resistors to ground at all nodes. */ + /* Value of resistor is set by new "rshunt" option. */ + + if(ckt->enh->rshunt_data.enabled) { + gshunt = ckt->enh->rshunt_data.gshunt; + num_nodes = ckt->enh->rshunt_data.num_nodes; + for(i = 0; i < num_nodes; i++) { + *(ckt->enh->rshunt_data.diag[i]) += gshunt; + } + } +#endif + /* gtri - end - Put resistors to ground at all nodes */ + + + if(ckt->CKTmode & MODEDC) { + /* consider doing nodeset & ic assignments */ + if(ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) { + /* do nodesets */ + for(node=ckt->CKTnodes;node;node=node->next) { + if(node->nsGiven) { + if (ZeroNoncurRow(ckt->CKTmatrix, ckt->CKTnodes, + node->number)) + { + *(ckt->CKTrhs+node->number) = 1.0e10 * node->nodeset * + ckt->CKTsrcFact; + *(node->ptr) = 1e10; + } else { + *(ckt->CKTrhs+node->number) = node->nodeset * + ckt->CKTsrcFact; + *(node->ptr) = 1; + } + /* DAG: Original CIDER fix. If above fix doesn't work, + * revert to this. + */ + /* + *(ckt->CKTrhs+node->number) += 1.0e10 * node->nodeset; + *(node->ptr) += 1.0e10; + */ + } + } + } + if( (ckt->CKTmode & MODETRANOP) && (!(ckt->CKTmode & MODEUIC))) { + for(node=ckt->CKTnodes;node;node=node->next) { + if(node->icGiven) { + if (ZeroNoncurRow(ckt->CKTmatrix, ckt->CKTnodes, + node->number)) + { + /* Original code: + *(ckt->CKTrhs+node->number) += 1.0e10 * node->ic; + */ + *(ckt->CKTrhs+node->number) = 1.0e10 * node->ic * + ckt->CKTsrcFact; + *(node->ptr) += 1.0e10; + } else { + /* Original code: + *(ckt->CKTrhs+node->number) = node->ic; + */ + *(ckt->CKTrhs+node->number) = node->ic*ckt->CKTsrcFact; /* AlansFixes */ + *(node->ptr) = 1; + } + /* DAG: Original CIDER fix. If above fix doesn't work, + * revert to this. + */ + /* + *(ckt->CKTrhs+node->number) += 1.0e10 * node->ic; + *(node->ptr) += 1.0e10; + */ + } + } + } + } + /* SMPprint(ckt->CKTmatrix, stdout); if you want to debug, this is a + good place to start ... */ + +#ifdef PARALLEL_ARCH +combine: + ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds() - startTime; + startTime = SPfrontEnd->IFseconds(); + /* See if any of the DEVload functions bailed. If not, proceed. */ + ibuf[0] = error; + ibuf[1] = ckt->CKTnoncon; + IGOP_( &type, ibuf, &length, "+" ); + ckt->CKTnoncon = ibuf[1]; + ckt->CKTstat->STATsyncTime += SPfrontEnd->IFseconds() - startTime; + if (ibuf[0] == OK) { + startTime = SPfrontEnd->IFseconds(); + SMPcombine( ckt->CKTmatrix, ckt->CKTrhs, ckt->CKTrhsSpare ); + ckt->CKTstat->STATcombineTime += SPfrontEnd->IFseconds() - startTime; + return(OK); + } else { + if ( ibuf[0] != error ) { + error = E_MULTIERR; + } + return(error); + } +#else + ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds()-startTime; + return(OK); +#endif /* PARALLEL_ARCH */ +} + +static int +ZeroNoncurRow(SMPmatrix *matrix, CKTnode *nodes, int rownum) +{ + CKTnode *n; + double *x; + int currents; + + currents = 0; + for (n = nodes; n; n = n->next) { + x = (double *) SMPfindElt(matrix, rownum, n->number, 0); + if (x) { + if (n->type == SP_CURRENT) + currents = 1; + else + *x = 0.0; + } + } + return currents; +} diff --git a/src/spicelib/analysis/cktmapn.c b/src/spicelib/analysis/cktmapn.c new file mode 100644 index 000000000..e01131dde --- /dev/null +++ b/src/spicelib/analysis/cktmapn.c @@ -0,0 +1,51 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* CKTmapNode(ckt,node) + * map the given node to the compact node numbering set of the + * specified circuit + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "sperror.h" +#include "cktdefs.h" + + + +/* ARGSUSED */ +int +CKTmapNode(void *ckt, void **node, IFuid name) +{ + CKTnode *here; + int error; + IFuid uid; + CKTnode *mynode; + + for (here = ((CKTcircuit *)ckt)->CKTnodes; here; here = here->next) { + if(here->name == name) { + if(node) *node = (char *)here; + return(E_EXISTS); + } + } + /* not found, so must be a new one */ + error = CKTmkNode((CKTcircuit*)ckt,&mynode); /*allocate the node*/ + if(error) return(error); + error = (*(SPfrontEnd->IFnewUid))((void *)ckt, + &uid, + (IFuid) NULL, + name, + UID_SIGNAL, + (void**)mynode); /* get a uid for it */ + if(error) return(error); + mynode->name = uid; /* set the info we have */ + mynode->type = SP_VOLTAGE; + error = CKTlinkEq((CKTcircuit*)ckt,mynode); /* and link it in */ + if(node) *node = (void *)mynode; /* and finally, return it */ + return(OK); +} diff --git a/src/spicelib/analysis/cktmask.c b/src/spicelib/analysis/cktmask.c new file mode 100644 index 000000000..d2659037e --- /dev/null +++ b/src/spicelib/analysis/cktmask.c @@ -0,0 +1,32 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* CKTmodAsk + * Ask questions about a specified device. + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "ifsim.h" +#include "devdefs.h" +#include "sperror.h" + + +extern SPICEdev **DEVices; + + + +/* ARGSUSED */ +int +CKTmodAsk(void *ckt, void *modfast, int which, IFvalue *value, IFvalue *selector) +{ + int type = ((GENmodel *)modfast)->GENmodType; + if((*DEVices[type]).DEVmodAsk) { + return( (*((*DEVices[type]).DEVmodAsk)) ((CKTcircuit *)ckt, + (GENmodel *)modfast,which,value) ); + } + return(E_BADPARM); +} diff --git a/src/spicelib/analysis/cktmcrt.c b/src/spicelib/analysis/cktmcrt.c new file mode 100644 index 000000000..abe7a9ea2 --- /dev/null +++ b/src/spicelib/analysis/cktmcrt.c @@ -0,0 +1,45 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* CKTmodCrt(type,name,ckt,fast) + * Create a device model of the specified type, with the given name + * in the named circuit. + */ + +#include "ngspice.h" +#include +#include "devdefs.h" +#include "cktdefs.h" +#include "sperror.h" + + + +int +CKTmodCrt(void *ckt, int type, void **modfast, IFuid name) +{ + extern SPICEdev **DEVices; + GENmodel *mymodfast = NULL; + int error; + + error = CKTfndMod(ckt,&type,(void**)&mymodfast,name); + if(error == E_NOMOD) { + mymodfast = (GENmodel *)MALLOC(*DEVices[type]->DEVmodSize); + if(mymodfast == (GENmodel *)NULL) return(E_NOMEM); + mymodfast->GENmodType = type; + mymodfast->GENmodName = name; + mymodfast->GENnextModel =(GENmodel *)((CKTcircuit *)ckt)->CKThead[type]; + ((CKTcircuit *)ckt)->CKThead[type]=(GENmodel *)mymodfast; + if(modfast) *modfast=(void *)mymodfast; + return(OK); + } else if (error==0) { + if(modfast) *modfast=(void *)mymodfast; + return(E_EXISTS); + } else { + return(error); + } + /*NOTREACHED*/ +} diff --git a/src/spicelib/analysis/cktmkcur.c b/src/spicelib/analysis/cktmkcur.c new file mode 100644 index 000000000..1c5d4b834 --- /dev/null +++ b/src/spicelib/analysis/cktmkcur.c @@ -0,0 +1,45 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* CKTmkCur + * make the given name a 'node' of type current in the + * specified circuit + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "sperror.h" +#include "cktdefs.h" + + + +/* ARGSUSED */ +int +CKTmkCur(CKTcircuit *ckt, CKTnode **node, IFuid basename, char *suffix) +{ + IFuid uid; + int error; + CKTnode *mynode; + CKTnode *checknode; + + error = CKTmkNode(ckt,&mynode); + if(error) return(error); + checknode = mynode; + error = (*(SPfrontEnd->IFnewUid))((void *)ckt,&uid,basename, + suffix,UID_SIGNAL,(void**)&checknode); + if(error) { + FREE(mynode); + if(node) *node = checknode; + return(error); + } + mynode->name = uid; + mynode->type = SP_CURRENT; + if(node) *node = mynode; + error = CKTlinkEq(ckt,mynode); + return(error); +} diff --git a/src/spicelib/analysis/cktmknod.c b/src/spicelib/analysis/cktmknod.c new file mode 100644 index 000000000..ac916fab5 --- /dev/null +++ b/src/spicelib/analysis/cktmknod.c @@ -0,0 +1,32 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* + *CKTmkNode(ckt,node) + * Tentatively allocate a new circuit equation structure + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "smpdefs.h" +#include "cktdefs.h" + + +/* ARGSUSED */ +int +CKTmkNode(CKTcircuit *ckt, CKTnode **node) +{ + CKTnode *mynode; + + mynode = (CKTnode *)MALLOC(sizeof(CKTnode)); + if(mynode == (CKTnode *)NULL) return(E_NOMEM); + mynode->next = (CKTnode *)NULL; + mynode->name = (IFuid) 0; + + if(node) *node = mynode; + return(OK); +} diff --git a/src/spicelib/analysis/cktmkvol.c b/src/spicelib/analysis/cktmkvol.c new file mode 100644 index 000000000..72b15484c --- /dev/null +++ b/src/spicelib/analysis/cktmkvol.c @@ -0,0 +1,43 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +/* CKTmkVolt + * make the given name a 'node' of type current in the + * specified circuit + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "sperror.h" +#include "cktdefs.h" + + + +/* ARGSUSED */ +int +CKTmkVolt(CKTcircuit *ckt, CKTnode **node, IFuid basename, char *suffix) +{ + IFuid uid; + int error; + CKTnode *mynode; + CKTnode *checknode; + + error = CKTmkNode(ckt,&mynode); + if(error) return(error); + checknode = mynode; + error = (*(SPfrontEnd->IFnewUid))((void *)ckt,&uid,basename, + suffix,UID_SIGNAL,(void**)&checknode); + if(error) { + FREE(mynode); + if(node) *node = checknode; + return(error); + } + mynode->name = uid; + mynode->type = SP_VOLTAGE; + if(node) *node = mynode; + error = CKTlinkEq(ckt,mynode); + return(error); +} diff --git a/src/spicelib/analysis/cktmpar.c b/src/spicelib/analysis/cktmpar.c new file mode 100644 index 000000000..192aadbe1 --- /dev/null +++ b/src/spicelib/analysis/cktmpar.c @@ -0,0 +1,35 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* CKTmodParam + * attach the given parameter to the specified model in the given circuit + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "ifsim.h" +#include "devdefs.h" +#include "sperror.h" + + + +extern SPICEdev **DEVices; + + + +/* ARGSUSED */ +int +CKTmodParam(void *ckt, void *modfast, int param, IFvalue *val, IFvalue *selector) +{ + int type = ((GENmodel *)modfast)->GENmodType; + + if (((*DEVices[type]).DEVmodParam)) { + return(((*((*DEVices[type]).DEVmodParam)) (param,val, + (GENmodel *)modfast))); + } else { + return(E_BADPARM); + } +} diff --git a/src/spicelib/analysis/cktnames.c b/src/spicelib/analysis/cktnames.c new file mode 100644 index 000000000..d3faa336b --- /dev/null +++ b/src/spicelib/analysis/cktnames.c @@ -0,0 +1,45 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + + /* + * CKTnames(ckt) + * output information on all circuit nodes/equations + * + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "ifsim.h" +#include "iferrmsg.h" + + +int +CKTnames(CKTcircuit *ckt, int *numNames, IFuid **nameList) +{ + CKTnode *here; + int i; + *numNames = ckt->CKTmaxEqNum-1; + *nameList = (IFuid *)MALLOC(*numNames * sizeof(IFuid )); + if ((*nameList) == (IFuid *)NULL) return(E_NOMEM); + i=0; + for (here = ckt->CKTnodes->next; here; here = here->next) { + *((*nameList)+i++) = here->name; + } + return(OK); +} + +int +CKTdnames(CKTcircuit *ckt) +{ + CKTnode *here; + int i; + + i=0; + for (here = ckt->CKTnodes->next; here; here = here->next) { + printf("%03d: %s\n", here->number, (char *)here->name); + } + return(OK); +} diff --git a/src/spicelib/analysis/cktncdump.c b/src/spicelib/analysis/cktncdump.c new file mode 100644 index 000000000..4ff075b43 --- /dev/null +++ b/src/spicelib/analysis/cktncdump.c @@ -0,0 +1,44 @@ +/********** +Copyright 1999 AG inc. All rights reserved. +Author: 1999 Alan Gillespie +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "suffix.h" + +void +CKTncDump(ckt) + CKTcircuit *ckt; +{ + CKTnode *node; + double new, old, tol; + int i=1; + + fprintf(stdout,"\n"); + fprintf(stdout,"Last Node Voltages\n"); + fprintf(stdout,"------------------\n\n"); + fprintf(stdout,"%-30s %20s %20s\n", "Node", "Last Voltage", "Previous Iter"); + fprintf(stdout,"%-30s %20s %20s\n", "----", "------------", "-------------"); + for(node=ckt->CKTnodes->next;node;node=node->next) { + if (strstr(node->name, "#branch") || !strstr(node->name, "#")) { + new = *((ckt->CKTrhsOld) + i ) ; + old = *((ckt->CKTrhs) + i ) ; + fprintf(stdout,"%-30s %20g %20g", node->name, new, old); + if(node->type == 3) { + tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) + + ckt->CKTvoltTol; + } else { + tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) + + ckt->CKTabstol; + } + if (fabs(new-old) >tol ) { + fprintf(stdout," *"); + } + fprintf(stdout,"\n"); + }; + i++; + }; + fprintf(stdout,"\n"); +} diff --git a/src/spicelib/analysis/cktnewan.c b/src/spicelib/analysis/cktnewan.c new file mode 100644 index 000000000..d8900884e --- /dev/null +++ b/src/spicelib/analysis/cktnewan.c @@ -0,0 +1,37 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include + +#include "tskdefs.h" +#include "jobdefs.h" +#include "ifsim.h" +#include "iferrmsg.h" +#include + +#include "analysis.h" + +extern SPICEanalysis *analInfo[]; + +/* ARGSUSED */ +int +CKTnewAnal(void *ckt, int type, IFuid name, void **analPtr, void *taskPtr) +{ + if(type==0) { + /* special case for analysis type 0 == option card */ + *analPtr=taskPtr; /* pointer to the task itself */ + (*(JOB **)analPtr)->JOBname = name; + (*(JOB **)analPtr)->JOBtype = type; + return(OK); /* doesn't need to be created */ + } + *analPtr = (void *)MALLOC(analInfo[type]->size); + if(*analPtr==NULL) return(E_NOMEM); + (*(JOB **)analPtr)->JOBname = name; + (*(JOB **)analPtr)->JOBtype = type; + (*(JOB **)analPtr)->JOBnextJob = ((TSKtask *)taskPtr)->jobs; + ((TSKtask *)taskPtr)->jobs = (JOB *)*analPtr; + return(OK); +} diff --git a/src/spicelib/analysis/cktneweq.c b/src/spicelib/analysis/cktneweq.c new file mode 100644 index 000000000..0e597dd72 --- /dev/null +++ b/src/spicelib/analysis/cktneweq.c @@ -0,0 +1,38 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* + *CKTnewEq(ckt,node,name) + * Allocate a new circuit equation number (returned) in the specified + * circuit to contain a new equation or node + * returns -1 for failure to allocate a node number + * + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "smpdefs.h" +#include "cktdefs.h" + + +int +CKTnewEq(void *inCkt, void **node, IFuid name) +{ + CKTnode *mynode; + CKTcircuit *ckt = (CKTcircuit *)inCkt; + int error; + + error = CKTmkNode(ckt,&mynode); + if(error) return(error); + + if(node) *node = (void *)mynode; + mynode->name = name; + + error = CKTlinkEq(ckt,mynode); + + return(error); +} diff --git a/src/spicelib/analysis/cktnewn.c b/src/spicelib/analysis/cktnewn.c new file mode 100644 index 000000000..450dcf760 --- /dev/null +++ b/src/spicelib/analysis/cktnewn.c @@ -0,0 +1,45 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* + *CKTnewNode(ckt,node,name) + * Allocate a new circuit equation number (returned) in the specified + * circuit to contain a new equation or node + * returns -1 for failure to allocate a node number + * + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "smpdefs.h" +#include "cktdefs.h" + + +/* should just call CKTnewEQ and set node type afterwards */ +int +CKTnewNode(void *inCkt, void **node, IFuid name) +{ + CKTcircuit *ckt = (CKTcircuit *)inCkt; + if(!(ckt->CKTnodes)) { /* starting the list - allocate both ground and 1 */ + ckt->CKTnodes = (CKTnode *) MALLOC(sizeof(CKTnode)); + if(ckt->CKTnodes == (CKTnode *)NULL) return(E_NOMEM); + ckt->CKTnodes->name = (char *)NULL; + ckt->CKTnodes->type = SP_VOLTAGE; + ckt->CKTnodes->number = 0; + ckt->CKTlastNode = ckt->CKTnodes; + } + ckt->CKTlastNode->next = (CKTnode *)MALLOC(sizeof(CKTnode)); + if(ckt->CKTlastNode->next == (CKTnode *)NULL) return(E_NOMEM); + ckt->CKTlastNode = ckt->CKTlastNode->next; + ckt->CKTlastNode->name = name; + ckt->CKTlastNode->number = ckt->CKTmaxEqNum++; + ckt->CKTlastNode->type = SP_VOLTAGE; + ckt->CKTlastNode->next = (CKTnode *)NULL; + + if(node) *node = (void *)ckt->CKTlastNode; + return(OK); +} diff --git a/src/spicelib/analysis/cktnodn.c b/src/spicelib/analysis/cktnodn.c new file mode 100644 index 000000000..95cf75f0d --- /dev/null +++ b/src/spicelib/analysis/cktnodn.c @@ -0,0 +1,33 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* + *CKTnodName(ckt) + * output information on all circuit nodes/equations + * + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" + + + +IFuid +CKTnodName(CKTcircuit *ckt, int nodenum) +{ + CKTnode *here; + + for(here = ckt->CKTnodes;here; here = here->next) { + if(here->number == nodenum) { + /* found it */ + return(here->name); + } + } + /* doesn't exist - do something */ + return("UNKNOWN NODE"); +} diff --git a/src/spicelib/analysis/cktnoise.c b/src/spicelib/analysis/cktnoise.c new file mode 100644 index 000000000..bc6e92b60 --- /dev/null +++ b/src/spicelib/analysis/cktnoise.c @@ -0,0 +1,139 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Gary W. Ng +**********/ + +/* + * CKTnoise (ckt, mode, operation, data) + * + * This routine is responsible for naming and evaluating all of the + * noise sources in the circuit. It uses a series of subroutines to + * name and evaluate the sources associated with each model, and then + * it evaluates the noise for the entire circuit. + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "devdefs.h" +#include "iferrmsg.h" +#include "noisedef.h" +#include "sperror.h" + + +int +CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data) +{ + double outNdens; + int i; + extern SPICEdev **DEVices; + IFvalue outData; /* output variable (points to list of outputs)*/ + IFvalue refVal; /* reference variable (always 0)*/ + int error; + + outNdens = 0.0; + + /* let each device decide how many and what type of noise sources it has */ + + for (i=0; i < DEVmaxnum; i++) { + if ( ((*DEVices[i]).DEVnoise != NULL) && (ckt->CKThead[i] != NULL) ) { + error = (*((*DEVices[i]).DEVnoise))(mode,operation,ckt->CKThead[i], + ckt,data, &outNdens); + if (error) return (error); + } + } + + switch (operation) { + + case N_OPEN: + + /* take care of the noise for the circuit as a whole */ + + switch (mode) { + + case N_DENS: + + data->namelist = (IFuid *)trealloc((char *)data->namelist, + (data->numPlots + 1)*sizeof(IFuid)); + + (*(SPfrontEnd->IFnewUid))(ckt, &(data->namelist[data->numPlots++]), + (IFuid)NULL,"onoise_spectrum",UID_OTHER,(void **)NULL); + + data->namelist = (IFuid *)trealloc((char *)data->namelist, + (data->numPlots + 1)*sizeof(IFuid)); + + (*(SPfrontEnd->IFnewUid))(ckt, &(data->namelist[data->numPlots++]), + (IFuid)NULL,"inoise_spectrum",UID_OTHER,(void **)NULL); + + /* we've added two more plots */ + + data->outpVector = + (double *)MALLOC(data->numPlots * sizeof(double)); + break; + + case INT_NOIZ: + + data->namelist = (IFuid *)trealloc((char *)data->namelist, + (data->numPlots + 1)*sizeof(IFuid)); + (*(SPfrontEnd->IFnewUid))(ckt, &(data->namelist[data->numPlots++]), + (IFuid)NULL,"onoise_total",UID_OTHER,(void **)NULL); + + data->namelist = (IFuid *)trealloc((char *)data->namelist, + (data->numPlots + 1)*sizeof(IFuid)); + (*(SPfrontEnd->IFnewUid))(ckt, &(data->namelist[data->numPlots++]), + (IFuid)NULL,"inoise_total",UID_OTHER,(void **)NULL); + /* we've added two more plots */ + + data->outpVector = + (double *) MALLOC(data->numPlots * sizeof(double)); + break; + + default: + return (E_INTERN); + } + + break; + + case N_CALC: + + switch (mode) { + + case N_DENS: + if ((((NOISEAN*)ckt->CKTcurJob)->NStpsSm == 0) + || data->prtSummary) + { + data->outpVector[data->outNumber++] = outNdens; + data->outpVector[data->outNumber++] = + (outNdens * data->GainSqInv); + + refVal.rValue = data->freq; /* the reference is the freq */ + outData.v.numValue = data->outNumber; /* vector number */ + outData.v.vec.rVec = data->outpVector; /* vector of outputs */ + (*(SPfrontEnd->OUTpData))(data->NplotPtr,&refVal,&outData); + } + break; + + case INT_NOIZ: + data->outpVector[data->outNumber++] = data->outNoiz; + data->outpVector[data->outNumber++] = data->inNoise; + outData.v.vec.rVec = data->outpVector; /* vector of outputs */ + outData.v.numValue = data->outNumber; /* vector number */ + (*(SPfrontEnd->OUTpData))(data->NplotPtr,&refVal,&outData); + break; + + default: + return (E_INTERN); + } + break; + + case N_CLOSE: + (*(SPfrontEnd->OUTendPlot))(data->NplotPtr); + FREE(data->namelist); + FREE(data->outpVector); + break; + + default: + return (E_INTERN); + } + return (OK); +} diff --git a/src/spicelib/analysis/cktntask.c b/src/spicelib/analysis/cktntask.c new file mode 100644 index 000000000..8a06aed4a --- /dev/null +++ b/src/spicelib/analysis/cktntask.c @@ -0,0 +1,65 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "tskdefs.h" +#include "ifsim.h" +#include "cktdefs.h" +#include "iferrmsg.h" + + +/* ARGSUSED */ +int +CKTnewTask(void *ckt, void **taskPtr, IFuid taskName) +{ + TSKtask *tsk; + + *taskPtr = (void *)MALLOC(sizeof(TSKtask)); + if(*taskPtr==NULL) return(E_NOMEM); + tsk = *(TSKtask **)taskPtr; + tsk->TSKname = taskName; + tsk->TSKgmin = 1e-12; + tsk->TSKgshunt = 0; + tsk->TSKabstol = 1e-12; + tsk->TSKreltol = 1e-3; + tsk->TSKchgtol = 1e-14; + tsk->TSKvoltTol = 1e-6; +#ifdef NEWTRUNC + tsk->TSKlteReltol = 1e-3; + tsk->TSKlteAbstol = 1e-6; +#endif /* NEWTRUNC */ + tsk->TSKtrtol = 7; + tsk->TSKbypass = 0; + tsk->TSKtranMaxIter = 10; + tsk->TSKdcMaxIter = 100; + tsk->TSKdcTrcvMaxIter = 50; + tsk->TSKintegrateMethod = TRAPEZOIDAL; + tsk->TSKmaxOrder = 2; + tsk->TSKnumSrcSteps = 1; + tsk->TSKnumGminSteps = 1; + tsk->TSKgminFactor = 10; + tsk->TSKpivotAbsTol = 1e-13; + tsk->TSKpivotRelTol = 1e-3; + tsk->TSKtemp = 300.15; + tsk->TSKnomTemp = 300.15; + tsk->TSKdefaultMosM = 1; + tsk->TSKdefaultMosL = 1e-4; + tsk->TSKdefaultMosW = 1e-4; + tsk->TSKdefaultMosAD = 0; + tsk->TSKdefaultMosAS = 0; + tsk->TSKnoOpIter=0; + tsk->TSKtryToCompact=0; + tsk->TSKbadMos3=0; + tsk->TSKkeepOpInfo=0; + tsk->TSKcopyNodesets=0; + tsk->TSKnodeDamping=0; + tsk->TSKabsDv=0.5; + tsk->TSKrelDv=2.0; + return(OK); +} diff --git a/src/spicelib/analysis/cktnum2n.c b/src/spicelib/analysis/cktnum2n.c new file mode 100644 index 000000000..4869e7677 --- /dev/null +++ b/src/spicelib/analysis/cktnum2n.c @@ -0,0 +1,32 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* CKTnum2nod + * find the given node given its name and return the node pointer + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "sperror.h" +#include "cktdefs.h" + + + +/* ARGSUSED */ +CKTnode * +CKTnum2nod(CKTcircuit *ckt, int node) +{ + CKTnode *here; + + for (here = ((CKTcircuit *)ckt)->CKTnodes; here; here = here->next) { + if(here->number == node) { + return(here); + } + } + return((CKTnode *)NULL); +} diff --git a/src/spicelib/analysis/cktop.c b/src/spicelib/analysis/cktop.c new file mode 100644 index 000000000..f318a8a5c --- /dev/null +++ b/src/spicelib/analysis/cktop.c @@ -0,0 +1,394 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "devdefs.h" +#include "sperror.h" + + +int +CKTop(CKTcircuit *ckt, long int firstmode, long int continuemode, int iterlim) +{ + int converged; + int i; + CKTnode *n; + double raise, ConvFact, NumNodes; + double *OldRhsOld, *OldCKTstate0; + int iters; + + ckt->CKTmode = firstmode; + if(!ckt->CKTnoOpIter) { + converged = NIiter(ckt,iterlim); + } else { + converged = 1; /* the 'go directly to gmin stepping' option */ + } + if(converged != 0) { + /* no convergence on the first try, so we do something else */ + /* first, check if we should try gmin stepping */ + /* note that no path out of this code allows ckt->CKTdiagGmin to be + * anything but 0.000000000 + */ + + if(ckt->CKTnumGminSteps ==1) { + + double OldGmin, gtarget, factor; + int success, failed; + + ckt->CKTmode = firstmode; + (*(SPfrontEnd->IFerror))(ERR_INFO, + "trying dynamic Gmin stepping",(IFuid *)NULL); + NumNodes=0; + for (n = ckt->CKTnodes; n; n = n->next) { + NumNodes++; + }; + OldRhsOld=(double *)MALLOC((NumNodes+1)*sizeof(double)); + OldCKTstate0=(double *) + MALLOC((ckt->CKTnumStates+1)*sizeof(double)); + for (n = ckt->CKTnodes; n; n = n->next) { + *(ckt->CKTrhsOld+n->number)=0; + }; + for(i=0;iCKTnumStates;i++) { + *(ckt->CKTstate0+i) = 0; + }; + factor = ckt->CKTgminFactor; + OldGmin = 1e-2; + ckt->CKTdiagGmin = OldGmin / factor; + gtarget = MAX(ckt->CKTgmin,ckt->CKTgshunt); + success = failed = 0; + + while ( (!success) && (!failed) ) { + fprintf(stderr, "\rTrying gmin = %12.4E ", ckt->CKTdiagGmin); + ckt->CKTnoncon =1; + iters = ckt->CKTstat->STATnumIter; + converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter); + iters = (ckt->CKTstat->STATnumIter)-iters; + if(converged == 0) { + ckt->CKTmode=continuemode; + (*(SPfrontEnd->IFerror))(ERR_INFO, + "One successful Gmin step",(IFuid *)NULL); + if (ckt->CKTdiagGmin <= gtarget) { + success = 1; + } else { + i=0; + for (n = ckt->CKTnodes; n; n = n->next) { + OldRhsOld[i]=*(ckt->CKTrhsOld+n->number); + i++; + }; + for(i=0;iCKTnumStates;i++) { + *(OldCKTstate0+i) = *(ckt->CKTstate0+i); + }; + if (iters <= (ckt->CKTdcTrcvMaxIter/4)) { + factor *= sqrt(factor); + if (factor > ckt->CKTgminFactor) + factor = ckt->CKTgminFactor; + }; + if (iters > (3*ckt->CKTdcTrcvMaxIter/4)) { + factor = sqrt(factor); + }; + OldGmin = ckt->CKTdiagGmin; + if ((ckt->CKTdiagGmin) < (factor*gtarget)) { + factor = ckt->CKTdiagGmin / gtarget; + ckt->CKTdiagGmin = gtarget; + } else { + ckt->CKTdiagGmin /= factor; + }; + }; + } else { + if (factor < 1.00005) { + failed = 1; + (*(SPfrontEnd->IFerror))(ERR_WARNING, + "last gmin step failed",(IFuid *)NULL); + } else { + factor=sqrt(sqrt(factor)); + ckt->CKTdiagGmin = OldGmin / factor; + i=0; + for (n = ckt->CKTnodes; n; n = n->next) { + *(ckt->CKTrhsOld+n->number)=OldRhsOld[i]; + i++; + }; + for(i=0;iCKTnumStates;i++) { + *(ckt->CKTstate0+i) = *(OldCKTstate0+i); + }; + }; + } + } + ckt->CKTdiagGmin=ckt->CKTgshunt; + FREE(OldRhsOld); + FREE(OldCKTstate0); + converged = NIiter(ckt,iterlim); + if (converged!=0) { + (*(SPfrontEnd->IFerror))(ERR_WARNING, + "dynamic gmin stepping failed",(IFuid *)NULL); + } else { + (*(SPfrontEnd->IFerror))(ERR_INFO, + "Dynamic gmin stepping completed",(IFuid *)NULL); + return(0); + }; + + } else if(ckt->CKTnumGminSteps >1) { + + ckt->CKTmode = firstmode; + (*(SPfrontEnd->IFerror))(ERR_INFO, + "starting Gmin stepping",(IFuid *)NULL); + + if (ckt->CKTgshunt==0) { + ckt->CKTdiagGmin = ckt->CKTgmin; + } else { + ckt->CKTdiagGmin = ckt->CKTgshunt; + }; + + + for(i=0;iCKTnumGminSteps;i++) { + ckt->CKTdiagGmin *= ckt->CKTgminFactor; + + + } + for(i=0;i<=ckt->CKTnumGminSteps;i++) { + fprintf(stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin); + ckt->CKTnoncon =1; + converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter); + if(converged != 0) { + ckt->CKTdiagGmin = ckt->CKTgshunt; + + (*(SPfrontEnd->IFerror))(ERR_WARNING, + "Gmin step failed",(IFuid *)NULL); + break; + } + ckt->CKTdiagGmin /= ckt->CKTgminFactor; + ckt->CKTmode=continuemode; + (*(SPfrontEnd->IFerror))(ERR_INFO, + "One successful Gmin step",(IFuid *)NULL); + } + ckt->CKTdiagGmin = ckt->CKTgshunt; + converged = NIiter(ckt,iterlim); + if(converged == 0) { + (*(SPfrontEnd->IFerror))(ERR_INFO, + "Gmin stepping completed",(IFuid *)NULL); + return(0); + } + (*(SPfrontEnd->IFerror))(ERR_WARNING, + "Gmin stepping failed",(IFuid *)NULL); + + } + /* now, we'll try source stepping - we scale the sources + * to 0, converge, then start stepping them up until they + * are at their normal values + * + * note that no path out of this code allows ckt->CKTsrcFact to be + * anything but 1.000000000 + */ + + + if(ckt->CKTnumSrcSteps >=1) { + ckt->CKTmode = firstmode; + (*(SPfrontEnd->IFerror))(ERR_INFO, + "starting source stepping",(IFuid *)NULL); + if(ckt->CKTnumSrcSteps==1) { + ckt->CKTsrcFact=0; raise=0.001; ConvFact=0; + NumNodes=0; + for (n = ckt->CKTnodes; n; n = n->next) { + NumNodes++; + }; + OldRhsOld=(double *)MALLOC((NumNodes+1)*sizeof(double)); + OldCKTstate0=(double *) + MALLOC((ckt->CKTnumStates+1)*sizeof(double)); + for (n = ckt->CKTnodes; n; n = n->next) { + *(ckt->CKTrhsOld+n->number)=0; + }; + for(i=0;iCKTnumStates;i++) { + *(ckt->CKTstate0+i) = 0; + }; + +/* First, try a straight solution with all sources at zero */ + + fprintf(stderr, "\rSupplies reduced to %8.4f%% ", + ckt->CKTsrcFact*100); + converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter); + +/* If this doesn't work, try gmin stepping as well for the first solution */ + + if(converged != 0) { + fprintf(stderr, "\n"); + if (ckt->CKTgshunt<=0) { + ckt->CKTdiagGmin = ckt->CKTgmin; + } else { + ckt->CKTdiagGmin = ckt->CKTgshunt; + }; + for(i=0;i<10;i++) { + ckt->CKTdiagGmin *= 10; + } + for(i=0;i<=10;i++) { + fprintf(stderr, "Trying gmin = %12.4E ", + ckt->CKTdiagGmin); + ckt->CKTnoncon =1; + converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter); + if(converged != 0) { + ckt->CKTdiagGmin = ckt->CKTgshunt; + (*(SPfrontEnd->IFerror))(ERR_WARNING, + "Gmin step failed",(IFuid *)NULL); + break; + } + + ckt->CKTdiagGmin /= 10; + ckt->CKTmode=continuemode; + (*(SPfrontEnd->IFerror))(ERR_INFO, + "One successful Gmin step",(IFuid *)NULL); + } + ckt->CKTdiagGmin = ckt->CKTgshunt; + }; + +/* If we've got convergence, then try stepping up the sources */ + + if(converged == 0) { + i=0; + for (n = ckt->CKTnodes; n; n = n->next) { + OldRhsOld[i]=*(ckt->CKTrhsOld+n->number); + i++; + }; + for(i=0;iCKTnumStates;i++) { + *(OldCKTstate0+i) = *(ckt->CKTstate0+i); + }; + (*(SPfrontEnd->IFerror))(ERR_INFO, + "One successful source step",(IFuid *)NULL); + ckt->CKTsrcFact=ConvFact+raise; + }; + + if(converged == 0) do { + fprintf(stderr, "\rSupplies reduced to %8.4f%% ", + ckt->CKTsrcFact*100); + + iters = ckt->CKTstat->STATnumIter; + converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter); + iters = (ckt->CKTstat->STATnumIter)-iters; + + ckt->CKTmode = continuemode; + if (converged == 0) { + ConvFact=ckt->CKTsrcFact; + i=0; + for (n = ckt->CKTnodes; n; n = n->next) { + OldRhsOld[i]=*(ckt->CKTrhsOld+n->number); + i++; + }; + for(i=0;iCKTnumStates;i++) { + *(OldCKTstate0+i) = *(ckt->CKTstate0+i); + }; + (*(SPfrontEnd->IFerror))(ERR_INFO, + "One successful source step",(IFuid *)NULL); + ckt->CKTsrcFact=ConvFact+raise; + if (iters <= (ckt->CKTdcTrcvMaxIter/4)) { + raise=raise*1.5; + }; + if (iters > (3*ckt->CKTdcTrcvMaxIter/4)) { + raise=raise*0.5; + }; +/* if (raise>0.01) raise=0.01; */ + } else { + if ((ckt->CKTsrcFact-ConvFact)<1e-8) break; + raise=raise/10; + if (raise>0.01) raise=0.01; + ckt->CKTsrcFact=ConvFact; + i=0; + for (n = ckt->CKTnodes; n; n = n->next) { + *(ckt->CKTrhsOld+n->number)=OldRhsOld[i]; + i++; + }; + for(i=0;iCKTnumStates;i++) { + *(ckt->CKTstate0+i) = *(OldCKTstate0+i); + }; + }; + if ((ckt->CKTsrcFact)>1) ckt->CKTsrcFact=1; + } while ((raise>=1e-7) && (ConvFact<1)); + + FREE(OldRhsOld); + FREE(OldCKTstate0); + ckt->CKTsrcFact = 1; + if (ConvFact!=1) { + ckt->CKTsrcFact = 1; + ckt->CKTcurrentAnalysis = DOING_TRAN; + (*(SPfrontEnd->IFerror))(ERR_WARNING, + "source stepping failed",(IFuid *)NULL); + return(E_ITERLIM); + } else { + (*(SPfrontEnd->IFerror))(ERR_INFO, + "Source stepping completed",(IFuid *)NULL); + return(0); + }; + } else { + for(i=0;i<=ckt->CKTnumSrcSteps;i++) { + ckt->CKTsrcFact = ((double)i)/((double)ckt->CKTnumSrcSteps); + converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter); + ckt->CKTmode = continuemode; + if(converged != 0) { + ckt->CKTsrcFact = 1; + ckt->CKTcurrentAnalysis = DOING_TRAN; + (*(SPfrontEnd->IFerror))(ERR_WARNING, + "source stepping failed",(IFuid *)NULL); + return(converged); + } + (*(SPfrontEnd->IFerror))(ERR_INFO, + "One successful source step",(IFuid *)NULL); + } + (*(SPfrontEnd->IFerror))(ERR_INFO, + "Source stepping completed",(IFuid *)NULL); + ckt->CKTsrcFact = 1; + return(0); + }; + } else { + return(converged); + } + } + return(0); +} + +/* CKTconvTest(ckt) + * this is a driver program to iterate through all the various + * convTest functions provided for the circuit elements in the + * given circuit + */ + +int +CKTconvTest(CKTcircuit *ckt) +{ + extern SPICEdev **DEVices; + int i; + int error = OK; +#ifdef PARALLEL_ARCH + int ibuf[2]; + long type = MT_CONV, length = 2; +#endif /* PARALLEL_ARCH */ + + for (i=0;iCKThead[i] != NULL)) { + error = (*((*DEVices[i]).DEVconvTest))(ckt->CKThead[i],ckt); + } +#ifdef PARALLEL_ARCH + if (error || ckt->CKTnoncon) goto combine; +#else + if (error) return(error); + if (ckt->CKTnoncon) { + /* printf("convTest: device %s failed\n", + (*DEVices[i]).DEVpublic.name); */ + return(OK); + } +#endif /* PARALLEL_ARCH */ + } +#ifdef PARALLEL_ARCH +combine: + /* See if any of the DEVconvTest functions bailed. If not, proceed. */ + ibuf[0] = error; + ibuf[1] = ckt->CKTnoncon; + IGOP_( &type, ibuf, &length, "+" ); + ckt->CKTnoncon = ibuf[1]; + if ( ibuf[0] != error ) { + error = E_MULTIERR; + } + return (error); +#else + return(OK); +#endif /* PARALLEL_ARCH */ +} diff --git a/src/spicelib/analysis/cktparam.c b/src/spicelib/analysis/cktparam.c new file mode 100644 index 000000000..b77e57daa --- /dev/null +++ b/src/spicelib/analysis/cktparam.c @@ -0,0 +1,34 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* CKTparam + * attach the given parameter to the specified device in the given circuit + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "ifsim.h" +#include "devdefs.h" +#include "sperror.h" + + + +extern SPICEdev **DEVices; + + +/* ARGSUSED */ +int +CKTparam(void *ckt, void *fast, int param, IFvalue *val, IFvalue *selector) +{ + int type; + GENinstance *myfast = (GENinstance *)fast; + type = myfast->GENmodPtr->GENmodType; + if(((*DEVices[type]).DEVparam)) { + return(((*((*DEVices[type]).DEVparam)) (param,val,myfast,selector))); + } else { + return(E_BADPARM); + } +} diff --git a/src/spicelib/analysis/cktpartn.c b/src/spicelib/analysis/cktpartn.c new file mode 100644 index 000000000..0310b0af9 --- /dev/null +++ b/src/spicelib/analysis/cktpartn.c @@ -0,0 +1,50 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1992 David A. Gates, UC Berkeley CADgroup +**********/ + + /* CKTpartition(ckt) + * this labels each instance of a circuit as belonging to a + * particular processor in a multiprocessor computer. + */ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "const.h" +#include "devdefs.h" +#include "sperror.h" + + + + +extern SPICEdev **DEVices; +#ifdef XSPICE +extern int *DEVicesfl; +#endif + +int +CKTpartition(CKTcircuit *ckt) +{ + int i, instNum = 0; + GENmodel *model; + GENinstance *inst; + + for (i=0;iCKThead[i] != NULL +#ifdef XSPICE +&& DEVicesfl[i] == 0 +#endif +) { + for (model = ckt->CKThead[i]; model; model = model->GENnextModel) { + for (inst = model->GENinstances; inst; + inst = inst->GENnextInstance) { + inst->GENowner = instNum % ARCHsize; + instNum++; + } + } + } + } + return(OK); +} diff --git a/src/spicelib/analysis/cktpmnam.c b/src/spicelib/analysis/cktpmnam.c new file mode 100644 index 000000000..6c8d35518 --- /dev/null +++ b/src/spicelib/analysis/cktpmnam.c @@ -0,0 +1,51 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +/* + * CKTpModName() + * + * Take a parameter by Name and set it on the specified model + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "devdefs.h" +#include "cktdefs.h" +#include "gendefs.h" +#include "sperror.h" + + + +extern SPICEdev **DEVices; + +/* ARGSUSED */ +int +CKTpModName(char *parm, IFvalue *val, CKTcircuit *ckt, int type, IFuid name, GENmodel **modfast) + /* the name of the parameter to set */ + /* the parameter union containing the value to set */ + /* the circuit this model is a member of */ + /* the device type code to the model being parsed */ + /* the name of the model being parsed */ + /* direct pointer to model being parsed */ + +{ + int error; /* int to store evaluate error return codes in */ + int i; + + for(i=0;i<(*(*DEVices[type]).DEVpublic.numModelParms);i++) { + if(strcmp(parm,((*DEVices[type]).DEVpublic.modelParms[i].keyword))==0){ + error = CKTmodParam((void *)ckt,(void *)*modfast, + (*DEVices[type]).DEVpublic.modelParms[i].id,val, + (IFvalue*)NULL); + if(error) return(error); + break; + } + } + if(i==(*(*DEVices[type]).DEVpublic.numModelParms)) { + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/analysis/cktpname.c b/src/spicelib/analysis/cktpname.c new file mode 100644 index 000000000..6be5178c3 --- /dev/null +++ b/src/spicelib/analysis/cktpname.c @@ -0,0 +1,55 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* + * CKTpName() + * + * Take a parameter by Name and set it on the specified device + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "devdefs.h" +#include "cktdefs.h" +#include "gendefs.h" +#include "sperror.h" + + + +extern SPICEdev **DEVices; + + +/* ARGSUSED */ +int +CKTpName(char *parm, IFvalue *val, CKTcircuit *ckt, int dev, char *name, GENinstance **fast) + /* the name of the parameter to set */ + /* the parameter union containing the value to set */ + /* the circuit this device is a member of */ + /* the device type code to the device being parsed */ + /* the name of the device being parsed */ + /* direct pointer to device being parsed */ + +{ + int error; /* int to store evaluate error return codes in */ + int i; + + for(i=0;i<(*(*DEVices[dev]).DEVpublic.numInstanceParms);i++) { + if(strcmp(parm, + ((*DEVices[dev]).DEVpublic.instanceParms[i].keyword))==0) { + error = CKTparam((void*)ckt,(void *)*fast, + (*DEVices[dev]).DEVpublic.instanceParms[i].id,val, + (IFvalue *)NULL); + if(error) return(error); + break; + } + } + if(i==(*(*DEVices[dev]).DEVpublic.numInstanceParms)) { + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/analysis/cktpzld.c b/src/spicelib/analysis/cktpzld.c new file mode 100644 index 000000000..090561166 --- /dev/null +++ b/src/spicelib/analysis/cktpzld.c @@ -0,0 +1,72 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +**********/ + +#include "ngspice.h" +#include +#include "pzdefs.h" +#include "smpdefs.h" +#include "cktdefs.h" +#include "complex.h" +#include "devdefs.h" +#include "sperror.h" + + +extern SPICEdev **DEVices; + + +int +CKTpzLoad(CKTcircuit *ckt, SPcomplex *s) +{ + PZAN *pzan = (PZAN *) (ckt->CKTcurJob); + int error; + int i; +#ifdef PARALLEL_ARCH + long type = MT_PZLOAD, length = 1; +#endif /* PARALLEL_ARCH */ + + for (i = 0; i <= SMPmatSize(ckt->CKTmatrix); i++) { + ckt->CKTrhs[i] = 0.0; + ckt->CKTirhs[i] = 0.0; + } + + SMPcClear(ckt->CKTmatrix); + for (i = 0; i < DEVmaxnum; i++) { + if (DEVices[i]->DEVpzLoad != NULL && ckt->CKThead[i] != NULL) { + error = (*DEVices[i]->DEVpzLoad)(ckt->CKThead[i], ckt, s); +#ifdef PARALLEL_ARCH + if (error) goto combine; +#else + if(error) return(error); +#endif /* PARALLEL_ARCH */ + } + } +#ifdef PARALLEL_ARCH +combine: + /* See if any of the DEVload functions bailed. If not, proceed. */ + IGOP_( &type, &error, &length, "max" ); + if (error == OK) { + SMPcCombine(ckt->CKTmatrix, ckt->CKTrhs, ckt->CKTrhsSpare, + ckt->CKTirhs, ckt->CKTirhsSpare ); + } else { + return(error); + } +#endif /* PARALLEL_ARCH */ + + if (pzan->PZbalance_col && pzan->PZsolution_col) { + SMPcAddCol(ckt->CKTmatrix, pzan->PZbalance_col, pzan->PZsolution_col); + /* AC sources ?? XXX */ + } + + if (pzan->PZsolution_col) { + SMPcZeroCol(ckt->CKTmatrix, pzan->PZsolution_col); + } + + /* Driving function (current source) */ + if (pzan->PZdrive_pptr) + *pzan->PZdrive_pptr = 1.0; + if (pzan->PZdrive_nptr) + *pzan->PZdrive_nptr = -1.0; + + return(OK); +} diff --git a/src/spicelib/analysis/cktpzset.c b/src/spicelib/analysis/cktpzset.c new file mode 100644 index 000000000..c091fce54 --- /dev/null +++ b/src/spicelib/analysis/cktpzset.c @@ -0,0 +1,100 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +**********/ + +/* CKTpzSetup(ckt) + * iterate through all the various + * pzSetup functions provided for the circuit elements in the + * given circuit, setup ... + */ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "sperror.h" + + +int +CKTpzSetup(CKTcircuit *ckt, int type) +{ + extern SPICEdev **DEVices; + PZAN *pzan = (PZAN *) ckt->CKTcurJob; + SMPmatrix *matrix; + int error; + int i, temp, solution_col, balance_col; + int input_pos, input_neg, output_pos, output_neg; + + NIdestroy(ckt); + error = NIinit(ckt); + if (error) + return(error); + matrix = ckt->CKTmatrix; + + /* Really awful . . . */ + ckt->CKTnumStates = 0; + + for (i = 0; i < DEVmaxnum; i++) { + if (DEVices[i]->DEVpzSetup != NULL && ckt->CKThead[i] != NULL) { + error = (*DEVices[i]->DEVpzSetup)(matrix, ckt->CKThead[i], + ckt, &ckt->CKTnumStates); + if (error != OK) + return(error); + } + } + + solution_col = 0; + balance_col = 0; + + input_pos = pzan->PZin_pos; + input_neg = pzan->PZin_neg; + + if (type == PZ_DO_ZEROS) { + /* Vo/Ii in Y */ + output_pos = pzan->PZout_pos; + output_neg = pzan->PZout_neg; + } else if (pzan->PZinput_type == PZ_IN_VOL) { + /* Vi/Ii in Y */ + output_pos = pzan->PZin_pos; + output_neg = pzan->PZin_neg; + } else { + /* Denominator */ + output_pos = 0; + output_neg = 0; + input_pos = 0; + input_neg = 0; + } + + if (output_pos) { + solution_col = output_pos; + if (output_neg) + balance_col = output_neg; + } else { + solution_col = output_neg; + temp = input_pos; + input_pos = input_neg; + input_neg = temp; + } + + if (input_pos) + pzan->PZdrive_pptr = SMPmakeElt(matrix, input_pos, solution_col); + else + pzan->PZdrive_pptr = NULL; + + if (input_neg) + pzan->PZdrive_nptr = SMPmakeElt(matrix, input_neg, solution_col); + else + pzan->PZdrive_nptr = NULL; + + pzan->PZsolution_col = solution_col; + pzan->PZbalance_col = balance_col; + + pzan->PZnumswaps = 1; + + error = NIreinit(ckt); + if (error) + return(error); + + return OK; +} diff --git a/src/spicelib/analysis/cktpzstr.c b/src/spicelib/analysis/cktpzstr.c new file mode 100644 index 000000000..e725b6a9b --- /dev/null +++ b/src/spicelib/analysis/cktpzstr.c @@ -0,0 +1,1200 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +**********/ + +/* + * A variant on the "zeroin" method. This is a bit convoluted. + */ + +#include "ngspice.h" +#include +#include "pzdefs.h" +#include "complex.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "sperror.h" + + +#ifdef PZDEBUG +# ifndef notdef +# define DEBUG(N) if (Debug >= (unsigned) (N)) +static unsigned int Debug = 1; +# else +# define DEBUG(N) if (0) +# endif +#endif + +/* static function definitions */ + +static int CKTpzStrat(PZtrial **set); +static int CKTpzStep(int strat, PZtrial **set); +static int CKTpzRunTrial(CKTcircuit *ckt, PZtrial **new_trialp, PZtrial **set); +static int CKTpzVerify(PZtrial **set, PZtrial *new_trial); +static void clear_trials(int mode); +static void check_flat(PZtrial *a, PZtrial *b); +void CKTpzUpdateSet(PZtrial **set, PZtrial *new); +void zaddeq(double *a, int *amag, double x, int xmag, double y, int ymag); +void CKTpzReset(PZtrial **set); + + +#ifdef PZDEBUG +static void show_trial( ); +#endif + +#define NITER_LIM 200 + +#define SHIFT_LEFT 2 +#define SHIFT_RIGHT 3 +#define SKIP_LEFT 4 +#define SKIP_RIGHT 5 +#define INIT 6 + +#define GUESS 7 +#define SPLIT_LEFT 8 +#define SPLIT_RIGHT 9 + +#define MULLER 10 +#define SYM 11 +#define SYM2 12 +#define COMPLEX_INIT 13 +#define COMPLEX_GUESS 14 +#define QUIT 15 + +#define NEAR_LEFT 4 +#define MID_LEFT 5 +#define FAR_LEFT 6 +#define NEAR_RIGHT 7 +#define FAR_RIGHT 8 +#define MID_RIGHT 9 + +#ifdef PZDEBUG +static char *snames[ ] = { + "none", + "none", + "shift left", + "shift right", + "skip left", + "skip right", + "init", + "guess", + "split left", + "split right", + "Muller", + "sym 1", + "sym 2", + "complex_init", + "complex_guess", + "quit", + "none" + }; +#endif + +#define sgn(X) ((X) < 0 ? -1 : (X) == 0 ? 0 : 1) + +#define ISAROOT 2 +#define ISAREPEAT 4 +#define ISANABERRATION 8 +#define ISAMINIMA 16 + +extern double NIpzK; +extern int NIpzK_mag; + +int CKTpzTrapped; + +static int NZeros, NFlat, Max_Zeros; +static PZtrial *ZeroTrial, *Trials; +static int Seq_Num; +static double Guess_Param; +static double High_Guess, Low_Guess; +static int Last_Move, Consec_Moves; +static int NIter, NTrials; +static int Aberr_Num; + +int PZeval(int strat, PZtrial **set, PZtrial **new_trial_p); +static PZtrial *pzseek(PZtrial *t, int dir); +static int alter(PZtrial *new, PZtrial *nearto, double abstol, double reltol); + +int +CKTpzFindZeros(CKTcircuit *ckt, PZtrial **rootinfo, int *rootcount) +{ + PZtrial *new_trial; + PZtrial *neighborhood[3]; + int strat; + int error; + char ebuf[513]; + + NIpzK = 0.0; + NIpzK_mag = 0; + High_Guess = -1.0; + Low_Guess = 1.0; + ZeroTrial = 0; + Trials = 0; + NZeros = 0; + NFlat = 0; + Max_Zeros = SMPmatSize(ckt->CKTmatrix); + NIter = 0; + error = OK; + CKTpzTrapped = 0; + Aberr_Num = 0; + NTrials = 0; + ckt->CKTniState |= NIPZSHOULDREORDER; /* Initial for LU fill-ins */ + + Seq_Num = 1; + + CKTpzReset(neighborhood); + + do { + + while ((strat = CKTpzStrat(neighborhood)) < GUESS && !CKTpzTrapped) + if (!CKTpzStep(strat, neighborhood)) { + strat = GUESS; +#ifdef PZDEBUG + DEBUG(1) fprintf(stderr, "\t\tGuess\n"); +#endif + break; + } + + NIter += 1; + + /* Evaluate current strategy */ + error = PZeval(strat, neighborhood, &new_trial); + if (error != OK) + return error; + + error = CKTpzRunTrial(ckt, &new_trial, neighborhood); + if (error != OK) + return error; + + if (new_trial->flags & ISAROOT) { + if (CKTpzVerify(neighborhood, new_trial)) { + NIter = 0; + CKTpzReset(neighborhood); + } else + /* XXX Verify fails ?!? */ + CKTpzUpdateSet(neighborhood, new_trial); + } else if (new_trial->flags & ISANABERRATION) { + CKTpzReset(neighborhood); + Aberr_Num += 1; + tfree(new_trial); + } else if (new_trial->flags & ISAMINIMA) { + neighborhood[0] = NULL; + neighborhood[1] = new_trial; + neighborhood[2] = NULL; + } else { + CKTpzUpdateSet(neighborhood, new_trial); /* Replace a value */ + } + + if ((*(SPfrontEnd->IFpauseTest))( )) { + sprintf(ebuf, + "Pole-Zero analysis interrupted; %d trials, %d roots\n", + Seq_Num, NZeros); + (*(SPfrontEnd->IFerror))(ERR_WARNING, ebuf, 0); + error = E_PAUSE; + break; + } + } while (High_Guess - Low_Guess < 1e40 + && NZeros < Max_Zeros + && NIter < NITER_LIM && Aberr_Num < 3 + && High_Guess - Low_Guess < 1e35 /* XXX Should use mach const */ + && (!neighborhood[0] || !neighborhood[2] || CKTpzTrapped + || neighborhood[2]->s.real - neighborhood[0]->s.real < 1e22)); + /* XXX ZZZ */ + +#ifdef PZDEBUG + DEBUG(1) fprintf(stderr, + "Finished: NFlat %d, NZeros: %d, NTrials %d, Guess %g to %g, aber %d\n", + NFlat, NZeros, NTrials, Low_Guess, High_Guess, Aberr_Num); +#endif + + if (NZeros >= Seq_Num - 1) { + /* Short */ + clear_trials(ISAROOT); + *rootinfo = NULL; + *rootcount = 0; + ERROR(E_SHORT, "The input signal is shorted on the way to the output"); + } else + clear_trials(0); + + *rootinfo = Trials; + *rootcount = NZeros; + + if (Aberr_Num > 2) { + sprintf(ebuf, + "Pole-zero converging to numerical aberrations; giving up after %d trials", + Seq_Num); + (*(SPfrontEnd->IFerror))(ERR_WARNING, ebuf, 0); + } + + if (NIter >= NITER_LIM) { + sprintf(ebuf, + "Pole-zero iteration limit reached; giving up after %d trials", + Seq_Num); + (*(SPfrontEnd->IFerror))(ERR_WARNING, ebuf, 0); + } + + return error; +} + +/* PZeval: evaluate an estimation function (given by 'strat') for the next + guess (returned in a PZtrial) */ + +/* XXX ZZZ */ +int +PZeval(int strat, PZtrial **set, PZtrial **new_trial_p) +{ + int error; + PZtrial *new_trial; + + new_trial = NEW(PZtrial); + new_trial->multiplicity = 0; + new_trial->count = 0; + new_trial->seq_num = Seq_Num++; + + switch (strat) { + case GUESS: + if (High_Guess < Low_Guess) + Guess_Param = 0.0; + else if (Guess_Param > 0.0) { + if (High_Guess > 0.0) + Guess_Param = High_Guess * 10.0; + else + Guess_Param = 1.0; + } else { + if (Low_Guess < 0.0) + Guess_Param = Low_Guess * 10.0; + else + Guess_Param = -1.0; + } + if (Guess_Param > High_Guess) + High_Guess = Guess_Param; + if (Guess_Param < Low_Guess) + Low_Guess = Guess_Param; + new_trial->s.real = Guess_Param; + if (set[1]) + new_trial->s.imag = set[1]->s.imag; + else + new_trial->s.imag = 0.0; + error = OK; + break; + + case SYM: + case SYM2: + error = NIpzSym(set, new_trial); + + if (CKTpzTrapped == 1) { + if (new_trial->s.real < set[0]->s.real + || new_trial->s.real > set[1]->s.real) { +#ifdef PZDEBUG + DEBUG(1) fprintf(stderr, + "FIXED UP BAD Strat: %s (%d) was (%.15g,%.15g)\n", + snames[strat], CKTpzTrapped, + new_trial->s.real, new_trial->s.imag); +#endif + new_trial->s.real = (set[0]->s.real + set[1]->s.real) / 2.0; + } + } else if (CKTpzTrapped == 2) { + if (new_trial->s.real < set[1]->s.real + || new_trial->s.real > set[2]->s.real) { +#ifdef PZDEBUG + DEBUG(1) fprintf(stderr, + "FIXED UP BAD Strat: %s (%d) was (%.15g,%.15g)\n", + snames[strat], CKTpzTrapped, + new_trial->s.real, new_trial->s.imag); +#endif + new_trial->s.real = (set[1]->s.real + set[2]->s.real) / 2.0; + } + } else if (CKTpzTrapped == 3) { + if (new_trial->s.real <= set[0]->s.real + || (new_trial->s.real == set[1]->s.real + && new_trial->s.imag == set[1]->s.imag) + || new_trial->s.real >= set[2]->s.real) { +#ifdef PZDEBUG + DEBUG(1) + fprintf(stderr, + "FIXED UP BAD Strat: %s (%d), was (%.15g %.15g)\n", + snames[strat], CKTpzTrapped, + new_trial->s.real, new_trial->s.imag); +#endif + new_trial->s.real = (set[0]->s.real + set[2]->s.real) / 2.0; + if (new_trial->s.real == set[1]->s.real) { +#ifdef PZDEBUG + DEBUG(1) + fprintf(stderr, "Still off!"); +#endif + if (Last_Move == MID_LEFT || Last_Move == NEAR_RIGHT) + new_trial->s.real = (set[0]->s.real + set[1]->s.real) + / 2.0; + else + new_trial->s.real = (set[1]->s.real + set[2]->s.real) + / 2.0; + } + } + } + + break; + + case COMPLEX_INIT: + /* Not automatic */ +#ifdef PZDEBUG + DEBUG(1) fprintf(stderr, "\tPZ minima at: %-30g %d\n", + NIpzK, NIpzK_mag); +#endif + + new_trial->s.real = set[1]->s.real; + + /* NIpzK is a good idea, but the value gets trashed + * due to the numerics when zooming in on a minima. + * The key is to know when to stop taking new values for NIpzK + * (which I don't). For now I take the first value indicated + * by the NIpzSym2 routine. A "hack". + */ + + if (NIpzK != 0.0 && NIpzK_mag > -10) { + while (NIpzK_mag > 0) { + NIpzK *= 2.0; + NIpzK_mag -= 1; + } + while (NIpzK_mag < 0) { + NIpzK /= 2.0; + NIpzK_mag += 1; + } + new_trial->s.imag = NIpzK; + } else + new_trial->s.imag = 10000.0; + + /* + * Reset NIpzK so the same value doesn't get used again. + */ + + NIpzK = 0.0; + NIpzK_mag = 0; + error = OK; + break; + + case COMPLEX_GUESS: + if (!set[2]) { + new_trial->s.real = set[0]->s.real; + new_trial->s.imag = 1.0e8; + } else { + new_trial->s.real = set[0]->s.real; + new_trial->s.imag = 1.0e12; + } + error = OK; + break; + + case MULLER: + error = NIpzMuller(set, new_trial); + break; + + case SPLIT_LEFT: + new_trial->s.real = (set[0]->s.real + 2 * set[1]->s.real) / 3.0; + error = OK; + break; + + case SPLIT_RIGHT: + new_trial->s.real = (set[2]->s.real + 2 * set[1]->s.real) / 3.0; + error = OK; + break; + + default: + ERROR(E_PANIC, "Step type unkown"); + break; + } + + *new_trial_p = new_trial; + return error; +} + +/* CKTpzStrat: given three points, determine a good direction or method for + guessing the next zero */ + +/* XXX ZZZ what is a strategy for complex hunting? */ +int CKTpzStrat(PZtrial **set) +{ + int suggestion; + double a, b; + int a_mag, b_mag; + double k1, k2; + int new_trap; + + new_trap = 0; + + if (set[1] && (set[1]->flags & ISAMINIMA)) { + suggestion = COMPLEX_INIT; + } else if (set[0] && set[0]->s.imag != 0.0) { + if (!set[1] || !set[2]) + suggestion = COMPLEX_GUESS; + else + suggestion = MULLER; + } else if (!set[0] || !set[1] || !set[2]) { + suggestion = INIT; + } else { + if (sgn(set[0]->f_def.real) != sgn(set[1]->f_def.real)) { + /* Zero crossing between s[0] and s[1] */ + new_trap = 1; + suggestion = SYM2; + } else if (sgn(set[1]->f_def.real) != sgn(set[2]->f_def.real)) { + /* Zero crossing between s[1] and s[2] */ + new_trap = 2; + suggestion = SYM2; + } else { + + zaddeq(&a, &a_mag, set[1]->f_def.real, set[1]->mag_def, + -set[0]->f_def.real, set[0]->mag_def); + zaddeq(&b, &b_mag, set[2]->f_def.real, set[2]->mag_def, + -set[1]->f_def.real, set[1]->mag_def); + + if (!CKTpzTrapped) { + + k1 = set[1]->s.real - set[0]->s.real; + k2 = set[2]->s.real - set[1]->s.real; + if (a_mag + 10 < set[0]->mag_def + && a_mag + 10 < set[1]->mag_def + && b_mag + 10 < set[1]->mag_def + && b_mag + 10 < set[2]->mag_def) { + if (k1 > k2) + suggestion = SKIP_RIGHT; + else + suggestion = SKIP_LEFT; + } else if (sgn(a) != -sgn(b)) { + if (a == 0.0) + suggestion = SKIP_LEFT; + else if (b == 0.0) + suggestion = SKIP_RIGHT; + else if (sgn(a) == sgn(set[1]->f_def.real)) + suggestion = SHIFT_LEFT; + else + suggestion = SHIFT_RIGHT; + } else if (sgn(a) == -sgn(set[1]->f_def.real)) { + new_trap = 3; + /* minima in magnitude above the x axis */ + /* Search for exact mag. minima, look for complex pair */ + suggestion = SYM; + } else if (k1 > k2) + suggestion = SKIP_RIGHT; + else + suggestion = SKIP_LEFT; + } else { + new_trap = 3; /* still */ + /* XXX ? Are these tests needed or is SYM safe all the time? */ + if (sgn(a) != sgn(b)) { + /* minima in magnitude */ + /* Search for exact mag. minima, look for complex pair */ + suggestion = SYM; + } else if (a_mag > b_mag || (a_mag == b_mag + && fabs(a) > fabs(b))) + suggestion = SPLIT_LEFT; + else + suggestion = SPLIT_RIGHT; + } + } + if (Consec_Moves >= 3 && CKTpzTrapped == new_trap) { + new_trap = CKTpzTrapped; + if (Last_Move == MID_LEFT || Last_Move == NEAR_RIGHT) + suggestion = SPLIT_LEFT; + else if (Last_Move == MID_RIGHT || Last_Move == NEAR_LEFT) + suggestion = SPLIT_RIGHT; + else + abort( ); /* XXX */ + Consec_Moves = 0; + } + } + + CKTpzTrapped = new_trap; +#ifdef PZDEBUG + DEBUG(1) { + if (set[0] && set[1] && set[2]) + fprintf(stderr, "given %.15g %.15g / %.15g %.15g / %.15g %.15g\n", + set[0]->s.real, set[0]->s.imag, set[1]->s.real, set[1]->s.imag, + set[2]->s.real, set[2]->s.imag); + fprintf(stderr, "suggestion(%d/%d/%d | %d): %s\n", + NFlat, NZeros, Max_Zeros, CKTpzTrapped, snames[suggestion]); + } +#endif + return suggestion; +} + +/* CKTpzRunTrial: eval the function at a given 's', fold in deflation */ + +int +CKTpzRunTrial(CKTcircuit *ckt, PZtrial **new_trialp, PZtrial **set) +{ + PZtrial *match, *base, *new_trial; + PZtrial *p, *prev; + SPcomplex def_frac, diff_frac; + double reltol, abstol; + int def_mag, diff_mag, error; + int i; + int pretest, shifted, was_shifted; + int repeat; + + new_trial = *new_trialp; + + if (new_trial->s.imag < 0.0) + new_trial->s.imag *= -1.0; + + /* Insert the trial into the list of Trials, while calculating + the deflation factor from previous zeros */ + + pretest = 0; + shifted = 0; + repeat = 0; + + do { + + def_mag = 0; + def_frac.real = 1.0; + def_frac.imag = 0.0; + was_shifted = shifted; + shifted = 0; + + prev = NULL; + base = NULL; + match = NULL; + + for (p = Trials; p != NULL; p = p->next) { + + C_SUBEQ(diff_frac,p->s,new_trial->s); + + if (diff_frac.real < 0.0 + || (diff_frac.real == 0.0 && diff_frac.imag < 0.0)) { + prev = p; + if (p->flags & ISAMINIMA) + base = p; + } + + if (p->flags & ISAROOT) { + abstol = 1e-5; + reltol = 1e-6; + } else { + abstol = 1e-20; + reltol = 1e-12; + } + + if (diff_frac.imag == 0.0 && + fabs(diff_frac.real) / (fabs(p->s.real) + abstol/reltol) + < reltol) { + +#ifdef PZDEBUG + DEBUG(1) { + fprintf(stderr, + "diff_frac.real = %10g, p->s = %10g, nt = %10g\n", + diff_frac.real, p->s.real, new_trial->s.real); + fprintf(stderr, "ab=%g,rel=%g\n", abstol, reltol); + } +#endif + if (was_shifted || p->count >= 3 + || !alter(new_trial, set[1], abstol, reltol)) { + /* assume either a root or minima */ + p->count = 0; + pretest = 1; + break; + } else + p->count += 1; /* try to shift */ + + shifted = 1; /* Re-calculate deflation */ + break; + + } else { + if (!CKTpzTrapped) + p->count = 0; + if (p->flags & ISAROOT) { + diff_mag = 0; + C_NORM(diff_frac,diff_mag); + if (diff_frac.imag != 0.0) { + C_MAG2(diff_frac); + diff_mag *= 2; + } + C_NORM(diff_frac,diff_mag); + + for (i = p->multiplicity; i > 0; i--) { + C_MUL(def_frac,diff_frac); + def_mag += diff_mag; + C_NORM(def_frac,def_mag); + } + } else if (!match) + match = p; + } + } + + } while (shifted); + + if (pretest) { + +#ifdef PZDEBUG + DEBUG(1) fprintf(stderr, "Pre-test taken\n"); + + /* XXX Should catch the double-zero right off + * if K is 0.0 + * instead of forcing a re-converge */ + DEBUG(1) { + fprintf(stderr, "NIpzK == %g, mag = %d\n", NIpzK, NIpzK_mag); + fprintf(stderr, "over at %.30g %.30g (new %.30g %.30g, %x)\n", + p->s.real, p->s.imag, new_trial->s.real, new_trial->s.imag, + p->flags); + } +#endif + if (!(p->flags & ISAROOT) && CKTpzTrapped == 3 + && NIpzK != 0.0 && NIpzK_mag > -10) { +#ifdef notdef + if (p->flags & ISAROOT) { + /* Ugh! muller doesn't work right */ + new_trial->flags = ISAMINIMA; + new_trial->s.imag = scalb(NIpzK, (int) (NIpzK_mag / 2)); + pretest = 0; + } else { +#endif + p->flags |= ISAMINIMA; + tfree(new_trial); + *new_trialp = p; + repeat = 1; + } else if (p->flags & ISAROOT) { +#ifdef PZDEBUG + DEBUG(1) fprintf(stderr, "Repeat at %.30g %.30g\n", + p->s.real, p->s.imag); +#endif + *new_trialp = p; + p->flags |= ISAREPEAT; + p->multiplicity += 1; + repeat = 1; + } else { + /* Regular zero, as precise as we can get it */ + error = E_SINGULAR; + } + + } + + if (!repeat) { + if (!pretest) { + /* Run the trial */ + ckt->CKTniState |= NIPZSHOULDREORDER; /* XXX */ + if (!(ckt->CKTniState & NIPZSHOULDREORDER)) { + CKTpzLoad(ckt, &new_trial->s); +#ifdef PZDEBUG + DEBUG(3) { + printf("Original:\n"); + SMPprint(ckt->CKTmatrix, stdout); + } +#endif + error = SMPcLUfac(ckt->CKTmatrix, ckt->CKTpivotAbsTol); + if (error == E_SINGULAR) { +#ifdef PZDEBUG + DEBUG(1) printf("Needs reordering\n"); +#endif + ckt->CKTniState |= NIPZSHOULDREORDER; + } else if (error != OK) + return error; + } + if (ckt->CKTniState & NIPZSHOULDREORDER) { + CKTpzLoad(ckt, &new_trial->s); + error = SMPcReorder(ckt->CKTmatrix, 1.0e-30, + 0.0 /* 0.1 Piv. Rel. */, + &(((PZAN *) ckt->CKTcurJob)->PZnumswaps)); + } + + if (error != E_SINGULAR) { + ckt->CKTniState &= ~NIPZSHOULDREORDER; +#ifdef PZDEBUG + DEBUG(3) { + printf("Factored:\n"); + SMPprint(ckt->CKTmatrix, stdout); + } +#endif + error = SMPcDProd(ckt->CKTmatrix, &new_trial->f_raw, + &new_trial->mag_raw); + } + } + + if (error == E_SINGULAR || (new_trial->f_raw.real == 0.0 + && new_trial->f_raw.imag == 0.0)) { + new_trial->f_raw.real = 0.0; + new_trial->f_raw.imag = 0.0; + new_trial->mag_raw = 0; + new_trial->f_def.real = 0.0; + new_trial->f_def.imag = 0.0; + new_trial->mag_def = 0; + new_trial->flags = ISAROOT; + /*printf("SMP Det: Singular\n");*/ + } else if (error != OK) + return error; + else { + + /* PZnumswaps is either 0 or 1 */ + new_trial->f_raw.real *= ((PZAN *) ckt->CKTcurJob)->PZnumswaps; + new_trial->f_raw.imag *= ((PZAN *) ckt->CKTcurJob)->PZnumswaps; + /* + printf("SMP Det: (%g,%g)^%d\n", new_trial->f_raw.real, + new_trial->f_raw.imag, new_trial->mag_raw); + */ + + new_trial->f_def.real = new_trial->f_raw.real; + new_trial->f_def.imag = new_trial->f_raw.imag; + new_trial->mag_def = new_trial->mag_raw; + + C_DIV(new_trial->f_def,def_frac); + new_trial->mag_def -= def_mag; + C_NORM(new_trial->f_def,new_trial->mag_def); + } + + /* Link into the rest of the list */ + if (prev) { + new_trial->next = prev->next; + if (prev->next) + prev->next->prev = new_trial; + prev->next = new_trial; + } else { + if (Trials) + Trials->prev = new_trial; + else + ZeroTrial = new_trial; + new_trial->next = Trials; + Trials = new_trial; + } + new_trial->prev = prev; + + NTrials += 1; + + if (!(new_trial->flags & ISAROOT)) { + if (match) + check_flat(match, new_trial); + else + NFlat = 1; + } + } + +#ifdef PZDEBUG + show_trial(new_trial, '*'); +#endif + + return OK; +} + +/* Process a zero; inc. zero count, deflate other trials */ + +int +CKTpzVerify(PZtrial **set, PZtrial *new_trial) +{ + PZtrial *next; + int diff_mag; + SPcomplex diff_frac; + double tdiff; + + PZtrial *t, *prev; + + NZeros += 1; + if (new_trial->s.imag != 0.0) + NZeros += 1; + NFlat = 0; + + if (new_trial->multiplicity == 0) { + new_trial->flags |= ISAROOT; + new_trial->multiplicity = 1; + } + + prev = NULL; + + for (t = Trials; t; t = next) { + + next = t->next; + + if (t->flags & ISAROOT) { + prev = t; + /* Don't need to bother */ + continue; + } + + C_SUBEQ(diff_frac,new_trial->s,t->s); + if (new_trial->s.imag != 0.0) + C_MAG2(diff_frac); + + tdiff = diff_frac.real; + /* Note that Verify is called for each time the root is found, so + * multiplicity is not significant + */ + if (diff_frac.real != 0.0) { + diff_mag = 0; + C_NORM(diff_frac,diff_mag); + diff_mag *= -1; + C_DIV(t->f_def,diff_frac); + C_NORM(t->f_def,diff_mag); + t->mag_def += diff_mag; + } + + if (t->s.imag != 0.0 + || fabs(tdiff) / (fabs(new_trial->s.real) + 200) < 0.005) { + if (prev) + prev->next = t->next; + if (t->next) + t->next->prev = prev; + NTrials -= 1; +#ifdef PZDEBUG + show_trial(t, '-'); +#endif + if (t == ZeroTrial) { + if (t->next) + ZeroTrial = t->next; + else if (t->prev) + ZeroTrial = t->prev; + else + ZeroTrial = NULL; + } + if (t == Trials) { + Trials = t->next; + } + tfree(t); + } else { + + if (prev) + check_flat(prev, t); + else + NFlat = 1; + + if (t->flags & ISAMINIMA) + t->flags &= ~ISAMINIMA; + + prev = t; +#ifdef PZDEBUG + show_trial(t, '+'); +#endif + } + + } + + return 1; /* always ok */ +} + +/* pzseek: search the trial list (given a starting point) for the first + * non-zero entry; direction: -1 for prev, 1 for next, 0 for next + * -or- first. Also, sets "Guess_Param" at the next reasonable + * value to guess at if the search falls of the end of the list + */ + +static PZtrial * +pzseek(PZtrial *t, int dir) +{ + Guess_Param = dir; + if (t == NULL) + return NULL; + + if (dir == 0 && !(t->flags & ISAROOT) && !(t->flags & ISAMINIMA)) + return t; + + do { + if (dir >= 0) + t = t->next; + else + t = t->prev; + } while (t && ((t->flags & ISAROOT) || (t->flags & ISAMINIMA))); + + return t; +} + +static void +clear_trials(int mode) +{ + PZtrial *t, *next, *prev; + + prev = NULL; + + for (t = Trials; t; t = next) { + next = t->next; + if (mode || !(t->flags & ISAROOT)) { + tfree(t); + } else { + if (prev) + prev->next = t; + else + Trials = t; + t->prev = prev; + prev = t; + } + } + + if (prev) + prev->next = NULL; + else + Trials = NULL; +} + +void +CKTpzUpdateSet(PZtrial **set, PZtrial *new) +{ + int this_move; + + this_move = 0; + + if (new->s.imag != 0.0) { + set[2] = set[1]; + set[1] = set[0]; + set[0] = new; + } else if (!set[1]) + set[1] = new; + else if (!set[2] && new->s.real > set[1]->s.real) { + set[2] = new; + } else if (!set[0]) { + set[0] = new; + } else if (new->flags & ISAMINIMA) { + set[1] = new; + } else if (new->s.real < set[0]->s.real) { + set[2] = set[1]; + set[1] = set[0]; + set[0] = new; + this_move = FAR_LEFT; + } else if (new->s.real < set[1]->s.real) { + if (!CKTpzTrapped || new->mag_def < set[1]->mag_def + || (new->mag_def == set[1]->mag_def + && fabs(new->f_def.real) < fabs(set[1]->f_def.real))) { + /* Really should check signs, not just compare fabs( ) */ + set[2] = set[1]; /* XXX = set[2]->prev :: possible opt */ + set[1] = new; + this_move = MID_LEFT; + } else { + set[0] = new; + this_move = NEAR_LEFT; + } + } else if (new->s.real < set[2]->s.real) { + if (!CKTpzTrapped || new->mag_def < set[1]->mag_def + || (new->mag_def == set[1]->mag_def + && fabs(new->f_def.real) < fabs(set[1]->f_def.real))) { + /* Really should check signs, not just compare fabs( ) */ + set[0] = set[1]; + set[1] = new; + this_move = MID_RIGHT; + } else { + set[2] = new; + this_move = NEAR_RIGHT; + } + } else { + set[0] = set[1]; + set[1] = set[2]; + set[2] = new; + this_move = FAR_RIGHT; + } + + if (CKTpzTrapped && this_move == Last_Move) + Consec_Moves += 1; + else + Consec_Moves = 0; + Last_Move = this_move; +} + +void +zaddeq(double *a, int *amag, double x, int xmag, double y, int ymag) +{ + /* Balance magnitudes . . . */ + if (xmag > ymag) { + *amag = xmag; + if (xmag > 50 + ymag) + y = 0.0; + else + for (xmag -= ymag; xmag > 0; xmag--) + y /= 2.0; + } else { + *amag = ymag; + if (ymag > 50 + xmag) + x = 0.0; + else + for (ymag -= xmag; ymag > 0; ymag--) + x /= 2.0; + } + + *a = x + y; + if (*a == 0.0) + *amag = 0; + else { + while (fabs(*a) > 1.0) { + *a /= 2.0; + *amag += 1; + } + while (fabs(*a) < 0.5) { + *a *= 2.0; + *amag -= 1; + } + } +} + +#ifdef PZDEBUG +static void +show_trial(new_trial, x) + PZtrial *new_trial; + char x; +{ + DEBUG(1) fprintf(stderr, "%c (%3d/%3d) %.15g %.15g :: %.30g %.30g %d\n", x, + NIter, new_trial->seq_num, new_trial->s.real, new_trial->s.imag, + new_trial->f_def.real, new_trial->f_def.imag, new_trial->mag_def); + DEBUG(1) + if (new_trial->flags & ISANABERRATION) { + fprintf(stderr, "*** numerical aberration ***\n"); + } +} +#endif + +static void +check_flat(PZtrial *a, PZtrial *b) +{ + int diff_mag; + SPcomplex diff_frac; + double mult; + + diff_mag = a->mag_def - b->mag_def; + if (abs(diff_mag) <= 1) { + if (diff_mag == 1) + mult = 2.0; + else if (diff_mag == -1) + mult = 0.5; + else + mult = 1.0; + C_SUBEQ(diff_frac, mult * a->f_def, b->f_def); + C_MAG2(diff_frac); + if (diff_frac.real < 1.0e-20) + NFlat += 1; + } + /* XXX else NFlat = ?????? */ +} + +/* XXX ZZZ */ +int +CKTpzStep(int strat, PZtrial **set) +{ + switch (strat) { + case INIT: + if (!set[1]) { + set[1] = pzseek(ZeroTrial, 0); + } else if (!set[2]) + set[2] = pzseek(set[1], 1); + else if (!set[0]) + set[0] = pzseek(set[1], -1); + break; + + case SKIP_LEFT: + set[0] = pzseek(set[0], -1); + break; + + case SKIP_RIGHT: + set[2] = pzseek(set[2], 1); + break; + + case SHIFT_LEFT: + set[2] = set[1]; + set[1] = set[0]; + set[0] = pzseek(set[0], -1); + break; + + case SHIFT_RIGHT: + set[0] = set[1]; + set[1] = set[2]; + set[2] = pzseek(set[2], 1); + break; + + } + if (!set[0] || !set[1] || !set[2]) + return 0; + else + return 1; +} + +void +CKTpzReset(PZtrial **set) +{ + CKTpzTrapped = 0; + Consec_Moves = 0; + + set[1] = pzseek(ZeroTrial, 0); + if (set[1] != NULL) { + set[0] = pzseek(set[1], -1); + set[2] = pzseek(set[1], 1); + } else { + set[0] = NULL; + set[2] = NULL; + } +} + +static int +alter(PZtrial *new, PZtrial *nearto, double abstol, double reltol) +{ + double p1, p2; + +#ifdef PZDEBUG + DEBUG(1) { + fprintf(stderr, "ALTER from: %.30g %.30g\n", + new->s.real, new->s.imag); + if (nearto->prev) + fprintf(stderr, "nt->prev %g\n", nearto->prev->s.real); + if (nearto->next) + fprintf(stderr, "nt->next %g\n", nearto->next->s.real); + } +#endif + + if (CKTpzTrapped != 2) { +#ifdef PZDEBUG + DEBUG(1) fprintf(stderr, "not 2\n"); +#endif + p1 = nearto->s.real; + if (nearto->flags & ISAROOT) + p1 -= 1e-6 * nearto->s.real + 1e-5; + if (nearto->prev) { + p1 += nearto->prev->s.real; +#ifdef PZDEBUG + DEBUG(1) fprintf(stderr, "p1 %g\n", p1); +#endif + } else + p1 -= 10.0 * (fabs(p1) + 1.0); + + p1 /= 2.0; + } else + p1 = nearto->s.real; + + if (CKTpzTrapped != 1) { +#ifdef PZDEBUG + DEBUG(1) fprintf(stderr, "not 1\n"); +#endif + p2 = nearto->s.real; + if (nearto->flags & ISAROOT) + p2 += 1e-6 * nearto->s.real + 1e-5; /* XXX Would rather use pow(2)*/ + if (nearto->next) { + p2 += nearto->next->s.real; +#ifdef PZDEBUG + DEBUG(1) fprintf(stderr, "p2 %g\n", p2); +#endif + } else + p2 += 10.0 * (fabs(p2)+ 1.0); + + p2 /= 2.0; + } else + p2 = nearto->s.real; + + if ((nearto->prev && + fabs(p1 - nearto->prev->s.real) / + fabs(nearto->prev->s.real) + abstol/reltol < reltol) + || + (nearto->next && + fabs(p2 - nearto->next->s.real) / + fabs(nearto->next->s.real) + abstol/reltol < reltol)) { + +#ifdef PZDEBUG + DEBUG(1) + fprintf(stderr, "Bailed out\n"); +#endif + + return 0; + } + + if (CKTpzTrapped != 2 && nearto->s.real - p1 > p2 - nearto->s.real) { +#ifdef PZDEBUG + DEBUG(1) fprintf(stderr, "take p1\n"); +#endif + new->s.real = p1; + } else { +#ifdef PZDEBUG + DEBUG(1) fprintf(stderr, "take p2\n"); +#endif + new->s.real = p2; + } + +#ifdef PZDEBUG + DEBUG(1) fprintf(stderr, "ALTER to : %.30g %.30g\n", + new->s.real, new->s.imag); +#endif + return 1; + +} diff --git a/src/spicelib/analysis/cktsens.c b/src/spicelib/analysis/cktsens.c new file mode 100644 index 000000000..ec6331147 --- /dev/null +++ b/src/spicelib/analysis/cktsens.c @@ -0,0 +1,792 @@ +/********** +Copyright 1991 Regents of the University of California. All rights reserved. +Modified: 2000 AlanFixes +**********/ + +#include "ngspice.h" +#include "ifsim.h" +#include "sperror.h" +#include "spmatrix.h" +#include "gendefs.h" +#include "devdefs.h" +#include "cktdefs.h" +#include "smpdefs.h" +#include "sensdefs.h" +#include "sensgen.h" + +/* #define ASDEBUG */ +#ifdef ASDEBUG +#define DEBUG(X) if ((X) < Sens_Debug) +int Sens_Debug = 0; +char SF1[] = "res"; +char SF2[] = "dc"; +char SF3[] = "bf"; +#endif + +char *Sfilter = NULL; +double Sens_Delta = 0.000001; +double Sens_Abs_Delta = 0.000001; + +static int sens_setp(sgen *sg, CKTcircuit *ckt, IFvalue *val); +static int sens_load(sgen *sg, CKTcircuit *ckt, int is_dc); +static int sens_temp(sgen *sg, CKTcircuit *ckt); +static int count_steps(int type, double low, double high, int steps, double *stepsize); +static double inc_freq(double freq, int type, double step_size); + +extern SPICEdev **DEVices; + + +/* + * Procedure: + * + * Determine operating point (call CKTop) + * + * For each frequency point: + * (for AC) call NIacIter to get base node voltages + * For each element/parameter in the test list: + * construct the perturbation matrix + * Solve for the sensitivities: + * delta_E = Y^-1 (delta_Y E - delta_I) + * save results + */ + +static int error; +int sens_sens(CKTcircuit *ckt, int restart) +{ + SENS_AN *sen_info = ((SENS_AN *) ckt->CKTcurJob); + static int size; + static double *delta_I, *delta_iI, + *delta_I_delta_Y, *delta_iI_delta_Y; + sgen *sg; + static double freq; + static int nfreqs; + static int i; + static SMPmatrix *delta_Y = NULL, *Y; + static double step_size; + double *E, *iE; + IFvalue value, nvalue; + double *output_values; + IFcomplex *output_cvalues; + double delta_var; + int (*fn)( ); + static int is_dc; + int k, j, n; + int num_vars, branch_eq; + char *sen_data=NULL; + char namebuf[513]; + IFuid *output_names, freq_name; + int bypass; + int type; + +#ifndef notdef +#ifdef notdef + for (sg = sgen_init(ckt, 0); sg; sgen_next(&sg)) { + if (sg->is_instparam) + printf("%s:%s:%s -> param %s\n", + DEVices[sg->dev]->DEVpublic.name, + sg->model->GENmodName, + sg->instance->GENname, + sg->ptable[sg->param].keyword); + else + printf("%s:%s:%s -> mparam %s\n", + DEVices[sg->dev]->DEVpublic.name, + sg->model->GENmodName, + sg->instance->GENname, + sg->ptable[sg->param].keyword); + } +#endif +#ifdef ASDEBUG + DEBUG(1) + printf(">>> restart : %d\n", restart); +#endif + + /* get to work */ + + restart = 1; + if (restart) { + + freq = 0.0; + is_dc = (sen_info->step_type == SENS_DC); + nfreqs = count_steps(sen_info->step_type, sen_info->start_freq, + sen_info->stop_freq, sen_info->n_freq_steps, + &step_size); + + if (!is_dc) + freq = sen_info->start_freq; + + error = CKTop(ckt, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, + ckt->CKTdcMaxIter); + +#ifdef notdef + ckt->CKTmode = (ckt->CKTmode & MODEUIC) + | MODEDCOP | MODEINITSMSIG; +#endif + if (error) + return error; + + size = spGetSize(ckt->CKTmatrix, 1); + + /* Create the perturbation matrix */ + delta_Y = spCreate(size, 1, &error); + if (error) + return error; + + size += 1; + + /* Create an extra rhs */ + delta_I = NEWN(double, size); + delta_iI = NEWN(double, size); + + delta_I_delta_Y = NEWN(double, size); + delta_iI_delta_Y = NEWN(double, size); + + + num_vars = 0; + for (sg = sgen_init(ckt, is_dc); sg; sgen_next(&sg)) { + num_vars += 1; + } + + if (!num_vars) + return OK; /* XXXX Should be E_ something */ + + k = 0; + output_names = NEWN(IFuid, num_vars); + for (sg = sgen_init(ckt, is_dc); sg; sgen_next(&sg)) { + if (!sg->is_instparam) { + sprintf(namebuf, "%s:%s", + sg->instance->GENname, + sg->ptable[sg->param].keyword); + } else if ((sg->ptable[sg->param].dataType + & IF_PRINCIPAL) && sg->is_principle == 1) + { + sprintf(namebuf, "%s", sg->instance->GENname); + } else { + sprintf(namebuf, "%s_%s", + sg->instance->GENname, + sg->ptable[sg->param].keyword); + } + + (*SPfrontEnd->IFnewUid)((void *) ckt, + output_names + k, NULL, + namebuf, UID_OTHER, NULL); + k += 1; + } + + if (is_dc) { + type = IF_REAL; + freq_name = NULL; + } else { + type = IF_COMPLEX; + (*SPfrontEnd->IFnewUid)((void *) ckt, + &freq_name, NULL, + "frequency", UID_OTHER, NULL); + } + + error = (*SPfrontEnd->OUTpBeginPlot)((void *) ckt, + (void *) ckt->CKTcurJob, + ckt->CKTcurJob->JOBname, freq_name, IF_REAL, num_vars, + output_names, type, (void **) &sen_data); + if (error) + return error; + + FREE(output_names); + if (is_dc) { + output_values = NEWN(double, num_vars); + output_cvalues = NULL; + } else { + output_values = NULL; + output_cvalues = NEWN(IFcomplex, num_vars); + if (sen_info->step_type != SENS_LINEAR) + (*(SPfrontEnd->OUTattributes))((void *)sen_data, + NULL, OUT_SCALE_LOG, NULL); + + } + + } else { + /*XXX Restore saved state */ + } + +#ifdef ASDEBUG + DEBUG(1) + printf("start: %f, num: %d, dc: %d\n", freq, nfreqs, is_dc); +#endif + + if (!sen_info->output_volt) + branch_eq = CKTfndBranch(ckt, sen_info->output_src); + bypass = ckt->CKTbypass; + ckt->CKTbypass = 0; + + /* The unknown vector of node voltages overwrites rhs */ + E = ckt->CKTrhs; + iE = ckt->CKTirhs; + ckt->CKTrhsOld = E; + ckt->CKTirhsOld = iE; + Y = ckt->CKTmatrix; +#ifdef ASDEBUG + DEBUG(1) { + printf("Operating point:\n"); + for (i = 0; i < size; i++) + printf(" E [%d] = %20.15g\n", i, E[i]); + } +#endif + +#ifdef notdef + for (j = 0; j <= ckt->CKTmaxOrder + 1; j++) { + save_states[j] = ckt->CKTstates[j]; + ckt->CKTstates[j] = NULL; + } +#endif + + for (i = 0; i < nfreqs; i++) { + /* XXX handle restart */ + + n = 0; + + if ((*SPfrontEnd->IFpauseTest)( )) { + /* XXX Save State */ + return E_PAUSE; + } + + for (j = 0; j < size; j++) { + delta_I[j] = 0.0; + delta_iI[j] = 0.0; + } + + if (freq != 0.0) { + ckt->CKTrhs = E; + ckt->CKTirhs = iE; + ckt->CKTmatrix = Y; + + /* This generates Y in LU form */ + ckt->CKTomega = 2.0 * M_PI * freq; + + /* Yes, all this has to be re-done */ + /* XXX Free old states */ + error = CKTunsetup(ckt); + if (error) + return error; + + /* XXX ckt->CKTmatrix = Y; */ + + error = CKTsetup(ckt); + if (error) + return error; + + E = ckt->CKTrhs; + iE = ckt->CKTirhs; + Y = ckt->CKTmatrix; +#ifdef notdef + for (j = 0; j <= ckt->CKTmaxOrder + 1; j++) { + /* XXX Free new states */ + ckt->CKTstates[j] = save_states[j]; + } +#endif + error = CKTtemp(ckt); + if (error) + return error; + error = CKTload(ckt); /* INITSMSIGS */ + if (error) + return error; + error = NIacIter(ckt); + if (error) + return error; + +#ifdef notdef + /* XXX Why? */ + for (j = 0; j <= ckt->CKTmaxOrder + 1; j++) { + ckt->CKTstates[j] = NULL; + } +#endif + + } + + /* Use a different vector & matrix */ + ckt->CKTrhs = delta_I; + ckt->CKTirhs = delta_iI; + ckt->CKTmatrix = delta_Y; + + /* calc. effect of each param */ + for (sg = sgen_init(ckt, is_dc /* sen_info->plist */); + sg; sgen_next(&sg)) + { + +#ifdef ASDEBUG + DEBUG(2) { + printf("E/iE: %x/%x; delta_I/iI: %x/%x\n", + E, iE, delta_I, delta_iI); + printf("cktrhs/irhs: %x/%x\n", + ckt->CKTrhs, ckt->CKTirhs); + + if (sg->is_instparam) + printf("%s:%s:%s -> param %s\n", + DEVices[sg->dev]->DEVpublic.name, + sg->model->GENmodName, + sg->instance->GENname, + sg->ptable[sg->param].keyword); + else + printf("%s:%s:%s -> mparam %s\n", + DEVices[sg->dev]->DEVpublic.name, + sg->model->GENmodName, + sg->instance->GENname, + sg->ptable[sg->param].keyword); + } +#endif + + spClear(delta_Y); + + for (j = 0; j < size; j++) { + delta_I[j] = 0.0; + delta_iI[j] = 0.0; + } + + /* ? should this just call CKTsetup + * ? but then CKThead would have to get fiddled with */ + + ckt->CKTnumStates = sg->istate; + + fn = DEVices[sg->dev]->DEVsetup; + if (fn) + (*fn)(delta_Y, sg->model, ckt, + /* XXXX insert old state base here ?? */ + &ckt->CKTnumStates); + + /* ? CKTsetup would call NIreinit instead */ + ckt->CKTniState = NISHOULDREORDER | NIACSHOULDREORDER; + + /* XXX instead of calling temp here, just swap + * back to the original states */ + (void) sens_temp(sg, ckt); + + /* XXX Leave original E until here!! so that temp reads + * the right node voltages */ + + if (sens_load(sg, ckt, is_dc)) { + if (error && error != E_BADPARM) + return error; /* XXX */ + continue; + } + + /* Alter the parameter */ + +#ifdef ASDEBUG + DEBUG(1) printf("Original value: %g\n", sg->value); +#endif + +#ifdef ASDEBUG + DEBUG(2) { + printf("Effect of device:\n"); + spPrint(delta_Y, 0, 1, 1); + printf("LHS:\n"); + for (j = 0; j < size; j++) + printf("%d: %g, %g\n", j, + delta_I[j], delta_iI[j]); + } +#endif + + if (sg->value != 0.0) + delta_var = sg->value * Sens_Delta; + else + delta_var = Sens_Abs_Delta; + + nvalue.rValue = sg->value + delta_var; + +#ifdef ASDEBUG + DEBUG(1) + printf("New value: %g\n", nvalue.rValue); +#endif + + sens_setp(sg, ckt, &nvalue); + if (error && error != E_BADPARM) + return error; + + spConstMult(delta_Y, -1.0); + for (j = 0; j < size; j++) { + delta_I[j] *= -1.0; + delta_iI[j] *= -1.0; + } + +#ifdef ASDEBUG + DEBUG(2) { + printf("Effect of negating matrix:\n"); + spPrint(delta_Y, 0, 1, 1); + for (j = 0; j < size; j++) + printf("%d: %g, %g\n", j, + delta_I[j], delta_iI[j]); + } +#endif + + /* XXX swap back to temp states ?? Naw ... */ + (void) sens_temp(sg, ckt); + +#ifdef ASDEBUG + DEBUG(1) { + if (sens_getp(sg, ckt, &value)) { + continue; + } + + printf("New value in device: %g\n", + value.rValue); + } +#endif + + sens_load(sg, ckt, is_dc); + +#ifdef ASDEBUG + DEBUG(2) { + printf("Effect of changing the parameter:\n"); + spPrint(delta_Y, 0, 1, 1); + for (j = 0; j < size; j++) + printf("%d: %g, %g\n", j, + delta_I[j], delta_iI[j]); + } +#endif + /* Set the perturbed variable back to it's + * original value + */ + + value.rValue = sg->value; + sens_setp(sg, ckt, &value); + (void) sens_temp(sg, ckt); /* XXX is this necessary? */ + + /* Back to business . . . */ + +#ifdef ASDEBUG + DEBUG(2) + for (j = 0; j < size; j++) + printf(" E [%d] = %20.15g\n", + j, E[j]); +#endif + + /* delta_Y E */ + spMultiply(delta_Y, delta_I_delta_Y, E, + delta_iI_delta_Y, iE); + +#ifdef ASDEBUG + DEBUG(2) + for (j = 0; j < size; j++) + printf("delta_Y * E [%d] = %20.15g\n", + j, delta_I_delta_Y[j]); +#endif + + /* delta_I - delta_Y E */ + for (j = 0; j < size; j++) { + delta_I[j] -= delta_I_delta_Y[j]; + delta_iI[j] -= delta_iI_delta_Y[j]; + } + +#ifdef ASDEBUG + DEBUG(2) { + printf(">>> Y:\n"); + spPrint(Y, 0, 1, 1); + for (j = 0; j < size; j++) + printf("%d: %g, %g\n", j, + delta_I[j], delta_iI[j]); + } +#endif + /* Solve; Y already factored */ + spSolve(Y, delta_I, delta_I, delta_iI, delta_iI); + +#ifdef ASDEBUG + DEBUG(2) { + for (j = 1; j < size; j++) { + + if (sg->is_instparam) + printf("%d/%s.%s = %g, %g\n", + j, + sg->instance->GENname, + sg->ptable[sg->param].keyword, + delta_I[j], delta_iI[j]); + else + printf("%d/%s:%s = %g, %g\n", + j, + sg->instance->GENname, + sg->ptable[sg->param].keyword, + delta_I[j], delta_iI[j]); + + } + } +#endif + + /* delta_I is now equal to delta_E */ + + if (is_dc) { + if (sen_info->output_volt) + output_values[n] = delta_I + [sen_info->output_pos->number] + - delta_I + [sen_info->output_neg->number]; + else { + output_values[n] = delta_I[branch_eq]; + } + output_values[n] /= delta_var; + } else { + if (sen_info->output_volt) { + output_cvalues[n].real = delta_I + [sen_info->output_pos->number] + - delta_I + [sen_info->output_neg->number]; + output_cvalues[n].imag = delta_iI + [sen_info->output_pos->number] + - delta_iI + [sen_info->output_neg->number]; + } else { + output_cvalues[n].real = + delta_I[branch_eq]; + output_cvalues[n].imag = + delta_iI[branch_eq]; + } + output_cvalues[n].real /= delta_var; + output_cvalues[n].imag /= delta_var; + } + + n += 1; + + } + + if (is_dc) + nvalue.v.vec.rVec = output_values; + else + nvalue.v.vec.cVec = output_cvalues; + + value.rValue = freq; + + (*(SPfrontEnd->OUTpData))(sen_data, &value, &nvalue); + + freq = inc_freq(freq, sen_info->step_type, step_size); + + } + + (*SPfrontEnd->OUTendPlot)((void *) sen_data); + + if (is_dc) { + FREE(output_values); /* XXX free various vectors */ + } else { + FREE(output_cvalues); /* XXX free various vectors */ + } + + spDestroy(delta_Y); + FREE(delta_I); + FREE(delta_iI); + + ckt->CKTrhs = E; + ckt->CKTirhs = iE; + ckt->CKTmatrix = Y; + ckt->CKTbypass = bypass; + +#ifdef notdef + for (j = 0; j <= ckt->CKTmaxOrder + 1; j++) { + if (ckt->CKTstates[j]) + FREE(ckt->CKTstates[j]); + ckt->CKTstates[j] = save_states[j]; + } +#endif +#endif + + return OK; +} + +double +inc_freq(double freq, int type, double step_size) +{ + if (type != LINEAR) + freq *= step_size; + else + freq += step_size; + + return freq; +} + +double +next_freq(int type, double freq, double stepsize) +{ + double s; + + switch (type) { + case SENS_DC: + s = 0; + break; + + case SENS_LINEAR: + s = freq + stepsize; + break; + + case SENS_DECADE: + case SENS_OCTAVE: + s = freq * stepsize; + break; + } + return s; +} + +int +count_steps(int type, double low, double high, int steps, double *stepsize) +{ + double s; + int n; + + if (steps < 1) + steps = 1; + + switch (type) { + default: + case SENS_DC: + n = 0; + s = 0; + break; + + case SENS_LINEAR: + n = steps; + s = (high - low) / steps; + break; + + case SENS_DECADE: + if (low <= 0.0) + low = 1e-3; + if (high <= low) + high = 10.0 * low; + n = steps * log10(high/low) + 1.01; + s = pow(10.0, 1.0 / steps); + break; + + case SENS_OCTAVE: + if (low <= 0.0) + low = 1e-3; + if (high <= low) + high = 2.0 * low; + n = steps * log(high/low) / M_LOG2E + 1.01; + s = pow(2.0, 1.0 / steps); + break; + } + + if (n <= 0) + n = 1; + + *stepsize = s; + return n; +} + +static int +sens_load(sgen *sg, CKTcircuit *ckt, int is_dc) +{ + int (*fn)( ); + + error = 0; + + if (!is_dc) + fn = DEVices[sg->dev]->DEVacLoad; + else + fn = DEVices[sg->dev]->DEVload; + + if (fn) + error = (*fn)(sg->model, ckt); + else + return 1; + + return error; +} + + +static int +sens_temp(sgen *sg, CKTcircuit *ckt) +{ + int (*fn)( ); + + error = 0; + + fn = DEVices[sg->dev]->DEVtemperature; + + if (fn) + error = (*fn)(sg->model, ckt); + else + return 1; + + return error; +} + +/* Get parameter value */ +int +sens_getp(sgen *sg, CKTcircuit *ckt, IFvalue *val) +{ + int (*fn)( ); + int pid; + + error = 0; + + if (sg->is_instparam) { + fn = DEVices[sg->dev]->DEVask; + pid = DEVices[sg->dev]->DEVpublic.instanceParms[sg->param].id; + if (fn) + error = (*fn)(ckt, sg->instance, pid, val, NULL); + else + return 1; + } else { + fn = DEVices[sg->dev]->DEVmodAsk; + pid = DEVices[sg->dev]->DEVpublic.modelParms[sg->param].id; + if (fn) + error = (*fn)(ckt, sg->model, pid, val, NULL); + else + return 1; + } + + if (error) { + if (sg->is_instparam) + printf("GET ERROR: %s:%s:%s -> param %s (%d)\n", + DEVices[sg->dev]->DEVpublic.name, + sg->model->GENmodName, + sg->instance->GENname, + sg->ptable[sg->param].keyword, pid); + else + printf("GET ERROR: %s:%s:%s -> mparam %s (%d)\n", + DEVices[sg->dev]->DEVpublic.name, + sg->model->GENmodName, + sg->instance->GENname, + sg->ptable[sg->param].keyword, pid); + } + + return error; +} + +/* Get parameter value */ +int +sens_setp(sgen *sg, CKTcircuit *ckt, IFvalue *val) +{ + int (*fn)( ); + int pid; + + error = 0; + + if (sg->is_instparam) { + fn = DEVices[sg->dev]->DEVparam; + pid = DEVices[sg->dev]->DEVpublic.instanceParms[sg->param].id; + if (fn) + error = (*fn)(pid, val, sg->instance, NULL); + else + return 1; + } else { + fn = DEVices[sg->dev]->DEVmodParam; + pid = DEVices[sg->dev]->DEVpublic.modelParms[sg->param].id; + if (fn) + error = (*fn)(pid, val, sg->model); + else + return 1; + } + + if (error) { + if (sg->is_instparam) + printf("SET ERROR: %s:%s:%s -> param %s (%d)\n", + DEVices[sg->dev]->DEVpublic.name, + sg->model->GENmodName, + sg->instance->GENname, + sg->ptable[sg->param].keyword, pid); + else + printf("SET ERROR: %s:%s:%s -> mparam %s (%d)\n", + DEVices[sg->dev]->DEVpublic.name, + sg->model->GENmodName, + sg->instance->GENname, + sg->ptable[sg->param].keyword, pid); + } + + return error; +} diff --git a/src/spicelib/analysis/cktsetap.c b/src/spicelib/analysis/cktsetap.c new file mode 100644 index 000000000..b6f9d75fc --- /dev/null +++ b/src/spicelib/analysis/cktsetap.c @@ -0,0 +1,25 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "tskdefs.h" +#include "jobdefs.h" +#include "ifsim.h" +#include "iferrmsg.h" +#include "cktdefs.h" + +#include "analysis.h" + +extern SPICEanalysis *analInfo[]; + +/* ARGSUSED */ +int +CKTsetAnalPm(void *ckt, void *analPtr, int parm, IFvalue *value, IFvalue *selector) +{ + int type = ((JOB *)analPtr)->JOBtype; + if((analInfo[type]->setParm)==NULL) return(E_BADPARM); + return( (*(analInfo[type]->setParm))(ckt,analPtr,parm,value) ); +} diff --git a/src/spicelib/analysis/cktsetbk.c b/src/spicelib/analysis/cktsetbk.c new file mode 100644 index 000000000..ec93909cc --- /dev/null +++ b/src/spicelib/analysis/cktsetbk.c @@ -0,0 +1,69 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* CKTsetBreak(ckt,time) + * add the given time to the breakpoint table for the given circuit + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "ifsim.h" +#include "sperror.h" + + + +int +CKTsetBreak(CKTcircuit *ckt, double time) +{ + double *tmp; + int i,j; + + if(ckt->CKTtime > time) { + (*(SPfrontEnd->IFerror))(ERR_PANIC,"breakpoint in the past - HELP!", + (IFuid *)NULL); + return(E_INTERN); + } + for(i=0;iCKTbreakSize;i++) { + if(*(ckt->CKTbreaks+i)>time) { /* passed */ + if((*(ckt->CKTbreaks+i)-time) <= ckt->CKTminBreak) { + /* very close together - take earlier point */ + *(ckt->CKTbreaks+i) = time; + return(OK); + } + if(time-*(ckt->CKTbreaks+i-1) <= ckt->CKTminBreak) { + /* very close together, but after, so skip */ + return(OK); + } + /* fits in middle - new array & insert */ + tmp = (double *)MALLOC((ckt->CKTbreakSize+1)*sizeof(double)); + if(tmp == (double *)NULL) return(E_NOMEM); + for(j=0;jCKTbreaks+j); + } + *(tmp+i)=time; + for(j=i;jCKTbreakSize;j++) { + *(tmp+j+1) = *(ckt->CKTbreaks+j); + } + FREE(ckt->CKTbreaks); + ckt->CKTbreakSize++; + ckt->CKTbreaks=tmp; + return(OK); + } + } + /* never found it - beyond end of time - extend out idea of time */ + if(time-ckt->CKTbreaks[ckt->CKTbreakSize-1]<=ckt->CKTminBreak) { + /* very close tegether - keep earlier, throw out new point */ + return(OK); + } + /* fits at end - grow array & add on */ + ckt->CKTbreaks = (double *)REALLOC(ckt->CKTbreaks, + (ckt->CKTbreakSize+1)*sizeof(double)); + ckt->CKTbreakSize++; + ckt->CKTbreaks[ckt->CKTbreakSize-1]=time; + return(OK); +} diff --git a/src/spicelib/analysis/cktsetnp.c b/src/spicelib/analysis/cktsetnp.c new file mode 100644 index 000000000..db4c86010 --- /dev/null +++ b/src/spicelib/analysis/cktsetnp.c @@ -0,0 +1,45 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* + *CKTsetNodPm + * + * set a parameter on a node. + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "cktdefs.h" + + + +/* ARGSUSED */ +int +CKTsetNodPm(void *ckt, void *node, int parm, IFvalue *value, IFvalue *selector) +{ + if(!node) return(E_BADPARM); + switch(parm) { + + case PARM_NS: + ((CKTnode *)node)->nodeset = value->rValue; + ((CKTnode *)node)->nsGiven = 1; + break; + + case PARM_IC: + ((CKTnode *)node)->ic = value->rValue; + ((CKTnode *)node)->icGiven = 1; + break; + + case PARM_NODETYPE: + ((CKTnode *)node)->type = value->iValue; + break; + + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/analysis/cktsetup.c b/src/spicelib/analysis/cktsetup.c new file mode 100644 index 000000000..d5f05c021 --- /dev/null +++ b/src/spicelib/analysis/cktsetup.c @@ -0,0 +1,149 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* CKTsetup(ckt) + * this is a driver program to iterate through all the various + * setup functions provided for the circuit elements in the + * given circuit + */ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "sperror.h" + + + +#define CKALLOC(var,size,type) \ + if(size && (!(var =(type *)MALLOC((size)*sizeof(type))))){\ + return(E_NOMEM);\ +} + +extern SPICEdev **DEVices; + + +int +CKTsetup(CKTcircuit *ckt) +{ + int i; + int error; +#ifdef XSPICE + /* gtri - begin - Setup for adding rshunt option resistors */ + CKTnode *node; + int num_nodes; + /* gtri - end - Setup for adding rshunt option resistors */ +#endif + SMPmatrix *matrix; + ckt->CKTnumStates=0; + +#ifdef WANT_SENSE2 + if(ckt->CKTsenInfo){ + if (error = CKTsenSetup(ckt)) return(error); + } +#endif + + if (ckt->CKTisSetup) + return E_NOCHANGE; + + CKTpartition(ckt); + + error = NIinit(ckt); + if (error) return(error); + ckt->CKTisSetup = 1; + + matrix = ckt->CKTmatrix; + + for (i=0;iCKThead[i] != NULL) ){ + error = (*((*DEVices[i]).DEVsetup))(matrix,ckt->CKThead[i],ckt, + &ckt->CKTnumStates); + if(error) return(error); + } + } + for(i=0;i<=ckt->CKTmaxOrder+1;i++) { + CKALLOC(ckt->CKTstates[i],ckt->CKTnumStates,double); + } +#ifdef WANT_SENSE2 + if(ckt->CKTsenInfo){ + /* to allocate memory to sensitivity structures if + * it is not done before */ + + error = NIsenReinit(ckt); + if(error) return(error); + } +#endif + if(ckt->CKTniState & NIUNINITIALIZED) { + error = NIreinit(ckt); + if(error) return(error); + } +#ifdef XSPICE + /* gtri - begin - Setup for adding rshunt option resistors */ + + if(ckt->enh->rshunt_data.enabled) { + + /* Count number of voltage nodes in circuit */ + for(num_nodes = 0, node = ckt->CKTnodes; node; node = node->next) + if((node->type == NODE_VOLTAGE) && (node->number != 0)) + num_nodes++; + + /* Allocate space for the matrix diagonal data */ + if(num_nodes > 0) { + ckt->enh->rshunt_data.diag = + (double **) MALLOC(num_nodes * sizeof(double *)); + } + + /* Set the number of nodes in the rshunt data */ + ckt->enh->rshunt_data.num_nodes = num_nodes; + + /* Get/create matrix diagonal entry following what RESsetup does */ + for(i = 0, node = ckt->CKTnodes; node; node = node->next) { + if((node->type == NODE_VOLTAGE) && (node->number != 0)) { + ckt->enh->rshunt_data.diag[i] = + SMPmakeElt(matrix,node->number,node->number); + i++; + } + } + + } + + /* gtri - end - Setup for adding rshunt option resistors */ +#endif + return(OK); +} + +int +CKTunsetup(CKTcircuit *ckt) +{ + int i, error, e2; + + error = OK; + if (!ckt->CKTisSetup) + return OK; + + for(i=0;i<=ckt->CKTmaxOrder+1;i++) { + tfree(ckt->CKTstates[i]); + } + + for (i=0;iCKThead[i] != NULL) ){ + e2 = (*((*DEVices[i]).DEVunsetup))(ckt->CKThead[i],ckt); + if (!error && e2) + error = e2; + } + } + ckt->CKTisSetup = 0; + if(error) return(error); + + NIdestroy(ckt); + /* + if (ckt->CKTmatrix) + SMPdestroy(ckt->CKTmatrix); + ckt->CKTmatrix = NULL; + */ + + return OK; +} diff --git a/src/spicelib/analysis/cktsgen.c b/src/spicelib/analysis/cktsgen.c new file mode 100644 index 000000000..a208a559b --- /dev/null +++ b/src/spicelib/analysis/cktsgen.c @@ -0,0 +1,252 @@ +/********** +Copyright 1991 Regents of the University of California. All rights reserved. +**********/ + +#include "ngspice.h" +#include "gendefs.h" +#include "devdefs.h" +#include "cktdefs.h" +#include "ifsim.h" +#include "sensgen.h" +#include + +extern SPICEdev **DEVices; + + /* XXX */ +extern char *Sfilter; + +sgen * +sgen_init(CKTcircuit *ckt, int is_dc) +{ + sgen *sg; + + sg = NEW(sgen); + sg->param = 99999; + sg->is_instparam = 0; + sg->dev = -1; + sg->istate = 0; + sg->ckt = ckt; + sg->devlist = ckt->CKThead; + sg->instance = sg->first_instance = sg->next_instance = NULL; + sg->model = sg->next_model = NULL; + sg->ptable = NULL; + sg->is_dc = is_dc; + sg->is_principle = 0; + sg->is_q = 0; + sg->is_zerook = 0; + sg->value = 0.0; + + sgen_next(&sg); /* get the ball rolling XXX check return val? */ + + return sg; +} + +int +sgen_next(sgen **xsg) +{ + sgen *sg = *xsg; + int good, done; + int i; + + done = 0; + i = sg->dev; + + do { + if (sg->instance) { + if (sg->ptable) { + do { + sg->param += 1; + } while (sg->param < sg->max_param + && !set_param(sg)); + } else { + sg->max_param = -1; + } + + if (sg->param < sg->max_param) { + done = 1; + } else if (!sg->is_instparam) { + /* Try instance parameters now */ + sg->is_instparam = 1; + sg->param = -1; + sg->max_param = + *DEVices[i]->DEVpublic.numInstanceParms; + sg->ptable = + DEVices[i]->DEVpublic.instanceParms; + } else { + sg->is_principle = 0; + sg->instance->GENnextInstance = + sg->next_instance; + sg->instance->GENstate = sg->istate; + sg->instance = NULL; + } + + } else if (sg->model) { + + /* Find the first/next good instance for this model */ + for (good = 0; !good && sg->next_instance; + good = set_inst(sg)) + { + sg->instance = sg->next_instance; + sg->next_instance = + sg->instance->GENnextInstance; + } + + + if (good) { + sg->is_principle = 0; + sg->istate = sg->instance->GENstate; + sg->instance->GENnextInstance = NULL; + sg->model->GENinstances = sg->instance; + if (DEVices[i]->DEVpublic.modelParms) { + sg->max_param = + *DEVices[i]->DEVpublic. + numModelParms; + sg->ptable = + DEVices[i]->DEVpublic. + modelParms; + } else { + sg->ptable = NULL; + } + sg->param = -1; + sg->is_instparam = 0; + } else { + /* No good instances of this model */ + sg->model->GENinstances = sg->first_instance; + sg->model->GENnextModel = sg->next_model; + sg->model = NULL; + } + + } else if (i >= 0) { + + /* Find the first/next good model for this device */ + for (good = 0; !good && sg->next_model; + good = set_model(sg)) + { + sg->model = sg->next_model; + sg->next_model = sg->model->GENnextModel; + } + + if (good) { + sg->model->GENnextModel = NULL; + sg->devlist[i] = sg->model; + if (DEVices[i]->DEVpublic.modelParms) { + sg->max_param = + *DEVices[i]->DEVpublic. + numModelParms; + sg->ptable = + DEVices[i]->DEVpublic. + modelParms; + } else { + sg->ptable = NULL; + } + sg->next_instance = sg->first_instance + = sg->model->GENinstances; + } else { + /* No more good models for this device */ + sg->devlist[i] = sg->first_model; + i = -1; /* Try the next good device */ + } + + } else if (i < DEVmaxnum && sg->dev < DEVmaxnum) { + + /* Find the next good device in this circuit */ + + do + sg->dev++; + while (sg->dev < DEVmaxnum && sg->devlist[sg->dev] + && !set_dev(sg)); + + i = sg->dev; + + if (i >= DEVmaxnum) /* PN: Segafult if not = */ + done = 1; + sg->first_model = sg->next_model = sg->devlist[i]; + + } else { + done = 1; + } + + } while (!done); + + if (sg->dev >= DEVmaxnum) { + FREE(sg); + *xsg = NULL; + } + return 1; +} + +int set_inst(sgen *sg) +{ + return 1; +} + +int set_model(sgen *sg) +{ + return 1; +} + +int set_dev(sgen *sg) +{ + return 1; +} + +int set_param(sgen *sg) +{ + IFvalue ifval; + + if (!sg->ptable[sg->param].keyword) + return 0; + if (Sfilter && strncmp(sg->ptable[sg->param].keyword, Sfilter, + strlen(Sfilter))) + return 0; + if ((sg->ptable[sg->param].dataType & + (IF_SET|IF_ASK|IF_REAL|IF_VECTOR|IF_REDUNDANT|IF_NONSENSE)) + != (IF_SET|IF_ASK|IF_REAL)) + return 0; + if (sg->is_dc && + (sg->ptable[sg->param].dataType & (IF_AC | IF_AC_ONLY))) + return 0; + if ((sg->ptable[sg->param].dataType & IF_CHKQUERY) && !sg->is_q) + return 0; + + if (sens_getp(sg, sg->ckt, &ifval)) + return 0; + + if (fabs(ifval.rValue) < 1e-30) { + if (sg->ptable[sg->param].dataType & IF_SETQUERY) + sg->is_q = 0; + + if (!sg->is_zerook + && !(sg->ptable[sg->param].dataType & IF_PRINCIPAL)) + return 0; + + } else if (sg->ptable[sg->param].dataType & (IF_SETQUERY|IF_ORQUERY)) + sg->is_q = 1; + + if (sg->ptable[sg->param].dataType & IF_PRINCIPAL) + sg->is_principle += 1; + + sg->value = ifval.rValue; + + return 1; +} + +#ifdef notdef +sgen_suspend(sg) + sgen *sg; +{ + sg->devlist[sg->dev] = sg->first_model; + sg->model->GENnextModel = sg->next_model; + sg->instance->GENnextInstance = sg->next_instance; + sg->model->GENinstances = sg->first_instance; +} + +sgen_restore(sg) + sgen *sg; +{ + sg->devlist[sg->dev] = sg->model; + sg->model->GENnextModel = NULL; + sg->instance->GENnextInstance = NULL; + sg->model->GENinstances = sg->instance; +} +#endif diff --git a/src/spicelib/analysis/cktsopt.c b/src/spicelib/analysis/cktsopt.c new file mode 100644 index 000000000..3a963bf53 --- /dev/null +++ b/src/spicelib/analysis/cktsopt.c @@ -0,0 +1,323 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes +**********/ + + /* + * CKTsetOpt(ckt,opt,value) + * set the specified 'opt' to have value 'value' in the + * given circuit 'ckt'. + */ + +#include "ngspice.h" +#include +#include "const.h" +#include "optdefs.h" +#include "tskdefs.h" +#include "ifsim.h" +#include "cktdefs.h" +#include "sperror.h" + +#include "analysis.h" + +#ifdef XSPICE +/* gtri - begin - wbk - add includes */ +#include "mif.h" +/* gtri - end - wbk - add includes */ +#endif + +/* ARGSUSED */ +int +CKTsetOpt(void *ckt, void *anal, int opt, IFvalue *val) +{ + TSKtask *task = (TSKtask *)anal; + + switch(opt) { + + case OPT_NOOPITER: + task->TSKnoOpIter = val->iValue; + break; + case OPT_GMIN: + task->TSKgmin = val->rValue; + break; + case OPT_GSHUNT: + task->TSKgshunt = val->rValue; + break; + case OPT_RELTOL: + task->TSKreltol = val->rValue; + break; + case OPT_ABSTOL: + task->TSKabstol = val->rValue; + break; + case OPT_VNTOL: + task->TSKvoltTol = val->rValue; + break; + case OPT_TRTOL: + task->TSKtrtol = val->rValue; + break; + case OPT_CHGTOL: + task->TSKchgtol = val->rValue; + break; + case OPT_PIVTOL: + task->TSKpivotAbsTol = val->rValue; + break; + case OPT_PIVREL: + task->TSKpivotRelTol = val->rValue; + break; + case OPT_TNOM: + task->TSKnomTemp = val->rValue + CONSTCtoK; /* Centegrade to Kelvin */ + break; + case OPT_TEMP: + task->TSKtemp = val->rValue + CONSTCtoK; /* Centegrade to Kelvin */ + break; + case OPT_ITL1: + task->TSKdcMaxIter = val->iValue; + break; + case OPT_ITL2: + task->TSKdcTrcvMaxIter = val->iValue; + break; + case OPT_ITL3: + break; + case OPT_ITL4: + task->TSKtranMaxIter = val->iValue; + break; + case OPT_ITL5: + break; + case OPT_SRCSTEPS: + task->TSKnumSrcSteps = val->iValue; + break; + case OPT_GMINSTEPS: + task->TSKnumGminSteps = val->iValue; + break; + case OPT_GMINFACT: + task->TSKgminFactor = val->rValue; + break; + case OPT_DEFM: + task->TSKdefaultMosM = val->rValue; + break; + case OPT_DEFL: + task->TSKdefaultMosL = val->rValue; + break; + case OPT_DEFW: + task->TSKdefaultMosW = val->rValue; + break; + case OPT_DEFAD: + task->TSKdefaultMosAD = val->rValue; + break; + case OPT_DEFAS: + task->TSKdefaultMosAD = val->rValue; + break; + case OPT_BYPASS: + task->TSKbypass = val->iValue; + break; + case OPT_MAXORD: + task->TSKmaxOrder = val->iValue; + break; + case OPT_OLDLIMIT: + task->TSKfixLimit = val->iValue; + break; + case OPT_MINBREAK: + task->TSKminBreak = val->rValue; + break; + case OPT_METHOD: + if(strncmp(val->sValue,"trap", 4)==0) + task->TSKintegrateMethod=TRAPEZOIDAL; + else if (strcmp(val->sValue,"gear")==0) + task->TSKintegrateMethod=GEAR; + else return(E_METHOD); + break; + case OPT_TRYTOCOMPACT: + task->TSKtryToCompact = val->iValue; + break; + case OPT_BADMOS3: + task->TSKbadMos3 = val->iValue; + break; + case OPT_KEEPOPINFO: + task->TSKkeepOpInfo = val->iValue; + break; + case OPT_COPYNODESETS: + task->TSKcopyNodesets = val->iValue; + break; + case OPT_NODEDAMPING: + task->TSKnodeDamping = val->iValue; + break; + case OPT_ABSDV: + task->TSKabsDv = val->rValue; + break; + case OPT_RELDV: + task->TSKrelDv = val->rValue; + break; +/* gtri - begin - wbk - add new options */ +#ifdef XSPICE + case OPT_EVT_MAX_OP_ALTER: + ((CKTcircuit *) ckt)->evt->limits.max_op_alternations = val->iValue; + break; + + case OPT_EVT_MAX_EVT_PASSES: + ((CKTcircuit *) ckt)->evt->limits.max_event_passes = val->iValue; + break; + + case OPT_ENH_NOOPALTER: + ((CKTcircuit *) ckt)->evt->options.op_alternate = MIF_FALSE; + break; + + case OPT_ENH_RAMPTIME: + ((CKTcircuit *) ckt)->enh->ramp.ramptime = val->rValue; + break; + + case OPT_ENH_CONV_LIMIT: + ((CKTcircuit *) ckt)->enh->conv_limit.enabled = MIF_TRUE; + break; + + case OPT_ENH_CONV_STEP: + ((CKTcircuit *) ckt)->enh->conv_limit.step = val->rValue; + ((CKTcircuit *) ckt)->enh->conv_limit.enabled = MIF_TRUE; + break; + + case OPT_ENH_CONV_ABS_STEP: + ((CKTcircuit *) ckt)->enh->conv_limit.abs_step = val->rValue; + ((CKTcircuit *) ckt)->enh->conv_limit.enabled = MIF_TRUE; + break; + + case OPT_MIF_AUTO_PARTIAL: + g_mif_info.auto_partial.global = MIF_TRUE; + break; + + case OPT_ENH_RSHUNT: + if(val->rValue > 1.0e-30) { + ((CKTcircuit *) ckt)->enh->rshunt_data.enabled = MIF_TRUE; + ((CKTcircuit *) ckt)->enh->rshunt_data.gshunt = 1.0 / val->rValue; + } + else { + printf("WARNING - Rshunt option too small. Ignored.\n"); + } + break; +#endif +/* gtri - end - wbk - add new options */ + default: + return(-1); + } + return(0); +} +static IFparm OPTtbl[] = { +#ifdef XSPICE +/* gtri - begin - wbk - add new options */ + { "maxopalter", OPT_EVT_MAX_OP_ALTER, IF_SET|IF_INTEGER, "Maximum analog/event alternations in DCOP" }, + { "maxevtiter", OPT_EVT_MAX_EVT_PASSES, IF_SET|IF_INTEGER, "Maximum event iterations at analysis point" }, + { "noopalter", OPT_ENH_NOOPALTER, IF_SET|IF_FLAG, "Do not do analog/event alternation in DCOP" }, + { "ramptime", OPT_ENH_RAMPTIME, IF_SET|IF_REAL, "Transient analysis supply ramping time" }, + { "convlimit", OPT_ENH_CONV_LIMIT, IF_SET|IF_FLAG, "Enable convergence assistance on code models" }, + { "convstep", OPT_ENH_CONV_STEP, IF_SET|IF_REAL, "Fractional step allowed by code model inputs between iterations" }, + { "convabsstep", OPT_ENH_CONV_ABS_STEP, IF_SET|IF_REAL, "Absolute step allowed by code model inputs between iterations" }, + { "autopartial", OPT_MIF_AUTO_PARTIAL, IF_SET|IF_FLAG, "Use auto-partial computation for all models" }, + { "rshunt", OPT_ENH_RSHUNT, IF_SET|IF_REAL, "Shunt resistance from analog nodes to ground" }, +/* gtri - end - wbk - add new options */ +#endif + { "noopiter", OPT_NOOPITER,IF_SET|IF_FLAG,"Go directly to gmin stepping" }, + { "gmin", OPT_GMIN,IF_SET|IF_REAL,"Minimum conductance" }, + { "gshunt", OPT_GSHUNT,IF_SET|IF_REAL,"Shunt conductance" }, + { "reltol", OPT_RELTOL,IF_SET|IF_REAL ,"Relative error tolerence"}, + { "abstol", OPT_ABSTOL,IF_SET|IF_REAL,"Absolute error tolerence" }, + { "vntol", OPT_VNTOL,IF_SET|IF_REAL,"Voltage error tolerence" }, + { "trtol", OPT_TRTOL,IF_SET|IF_REAL,"Truncation error overestimation factor" }, + { "chgtol", OPT_CHGTOL,IF_SET|IF_REAL, "Charge error tolerence" }, + { "pivtol", OPT_PIVTOL,IF_SET|IF_REAL, "Minimum acceptable pivot" }, + { "pivrel", OPT_PIVREL,IF_SET|IF_REAL, "Minimum acceptable ratio of pivot" }, + { "tnom", OPT_TNOM,IF_SET|IF_ASK|IF_REAL, "Nominal temperature" }, + { "temp", OPT_TEMP,IF_SET|IF_ASK|IF_REAL, "Operating temperature" }, + { "itl1", OPT_ITL1,IF_SET|IF_INTEGER,"DC iteration limit" }, + { "itl2", OPT_ITL2,IF_SET|IF_INTEGER,"DC transfer curve iteration limit" }, + { "itl3", OPT_ITL3, IF_INTEGER,"Lower transient iteration limit"}, + { "itl4", OPT_ITL4,IF_SET|IF_INTEGER,"Upper transient iteration limit" }, + { "itl5", OPT_ITL5, IF_INTEGER,"Total transient iteration limit"}, + { "itl6", OPT_SRCSTEPS, IF_SET|IF_INTEGER,"number of source steps"}, + { "srcsteps", OPT_SRCSTEPS, IF_SET|IF_INTEGER,"number of source steps"}, + { "gminsteps", OPT_GMINSTEPS, IF_SET|IF_INTEGER,"number of Gmin steps"}, + { "gminfactor", OPT_GMINFACT, IF_SET|IF_REAL,"factor per Gmin step"}, + { "acct", 0, IF_FLAG ,"Print accounting"}, + { "list", 0, IF_FLAG, "Print a listing" }, + { "nomod", 0, IF_FLAG, "Don't print a model summary" }, + { "nopage", 0, IF_FLAG, "Don't insert page breaks" }, + { "node", 0, IF_FLAG,"Print a node connection summary" }, + { "opts", 0, IF_FLAG, "Print a list of the options" }, + { "oldlimit", OPT_OLDLIMIT, IF_SET|IF_FLAG, "use SPICE2 MOSfet limiting" }, + { "numdgt", 0, IF_INTEGER, "Set number of digits printed"}, + { "cptime", 0, IF_REAL, "Total cpu time in seconds" }, + { "limtim", 0, IF_INTEGER, "Time to reserve for output" }, + { "limpts", 0,IF_INTEGER,"Maximum points per analysis"}, + { "lvlcod", 0, IF_INTEGER,"Generate machine code" }, + { "lvltim", 0, IF_INTEGER,"Type of timestep control" }, + { "method", OPT_METHOD, IF_SET|IF_STRING,"Integration method" }, + { "maxord", OPT_MAXORD, IF_SET|IF_INTEGER,"Maximum integration order" }, + { "defm", OPT_DEFM,IF_SET|IF_REAL,"Default MOSfet Multiplier" }, + { "defl", OPT_DEFL,IF_SET|IF_REAL,"Default MOSfet length" }, + { "defw", OPT_DEFW,IF_SET|IF_REAL,"Default MOSfet width" }, + { "minbreak", OPT_MINBREAK,IF_SET|IF_REAL,"Minimum time between breakpoints" }, + { "defad", OPT_DEFAD,IF_SET|IF_REAL,"Default MOSfet area of drain" }, + { "defas", OPT_DEFAS,IF_SET|IF_REAL,"Default MOSfet area of source" }, + { "bypass",OPT_BYPASS,IF_SET|IF_INTEGER,"Allow bypass of unchanging elements"}, + { "totiter", OPT_ITERS, IF_ASK|IF_INTEGER,"Total iterations" }, + { "traniter", OPT_TRANIT, IF_ASK|IF_INTEGER ,"Transient iterations"}, + { "equations", OPT_EQNS, IF_ASK|IF_INTEGER,"Circuit Equations" }, + { "originalnz", OPT_ORIGNZ, IF_ASK|IF_INTEGER,"Circuit original non-zeroes" }, + { "fillinnz", OPT_FILLNZ, IF_ASK|IF_INTEGER,"Circuit fill-in non-zeroes" }, + { "totalnz", OPT_TOTALNZ, IF_ASK|IF_INTEGER,"Circuit total non-zeroes" }, + { "tranpoints", OPT_TRANPTS, IF_ASK|IF_INTEGER,"Transient timepoints" }, + { "accept", OPT_TRANACCPT, IF_ASK|IF_INTEGER,"Accepted timepoints" }, + { "rejected", OPT_TRANRJCT, IF_ASK|IF_INTEGER,"Rejected timepoints" }, + { "time", OPT_TOTANALTIME, IF_ASK|IF_REAL,"Total analysis time" }, + { "loadtime", OPT_LOADTIME, IF_ASK|IF_REAL,"Matrix load time" }, + { "synctime", OPT_SYNCTIME, IF_ASK|IF_REAL,"Matrix synchronize time" }, + { "combinetime", OPT_COMBTIME, IF_ASK|IF_REAL,"Matrix combine time" }, + { "reordertime", OPT_REORDTIME, IF_ASK|IF_REAL,"Matrix reorder time" }, + { "factortime", OPT_DECOMP, IF_ASK|IF_REAL,"Matrix factor time" }, + { "solvetime", OPT_SOLVE, IF_ASK|IF_REAL,"Matrix solve time" }, + { "trantime", OPT_TRANTIME, IF_ASK|IF_REAL,"Transient analysis time" }, + { "tranloadtime", OPT_TRANLOAD, IF_ASK|IF_REAL,"Transient load time" }, + { "transynctime", OPT_TRANSYNC, IF_ASK|IF_REAL,"Transient sync time" }, + { "trancombinetime", OPT_TRANCOMB, IF_ASK|IF_REAL,"Transient combine time" }, + { "tranfactortime", OPT_TRANDECOMP,IF_ASK|IF_REAL,"Transient factor time" }, + { "transolvetime", OPT_TRANSOLVE, IF_ASK|IF_REAL,"Transient solve time" }, + { "trantrunctime", OPT_TRANTRUNC, IF_ASK|IF_REAL,"Transient trunc time" }, + { "trancuriters", OPT_TRANCURITER, IF_ASK|IF_INTEGER, + "Transient iters per point" }, + { "actime", OPT_ACTIME, IF_ASK|IF_REAL,"AC analysis time" }, + { "acloadtime", OPT_ACLOAD, IF_ASK|IF_REAL,"AC load time" }, + { "acsynctime", OPT_ACSYNC, IF_ASK|IF_REAL,"AC sync time" }, + { "accombinetime", OPT_ACCOMB, IF_ASK|IF_REAL,"AC combine time" }, + { "acfactortime", OPT_ACDECOMP,IF_ASK|IF_REAL,"AC factor time" }, + { "acsolvetime", OPT_ACSOLVE, IF_ASK|IF_REAL,"AC solve time" }, + { "trytocompact", OPT_TRYTOCOMPACT, IF_SET|IF_FLAG, + "Try compaction for LTRA lines" }, + { "badmos3", OPT_BADMOS3, IF_SET|IF_FLAG, + "use old mos3 model (discontinuous with respect to kappa)" }, + { "keepopinfo", OPT_KEEPOPINFO, IF_SET|IF_FLAG, + "Record operating point for each small-signal analysis" }, + { "copynodesets", OPT_COPYNODESETS, IF_SET|IF_FLAG, + "Copy nodesets from device terminals to internal nodes" }, + { "nodedamping", OPT_NODEDAMPING, IF_SET|IF_FLAG, + "Limit iteration to iteration node voltage change" }, + { "absdv", OPT_ABSDV, IF_SET|IF_REAL, + "Maximum absolute iter-iter node voltage change" }, + { "reldv", OPT_RELDV, IF_SET|IF_REAL, + "Maximum relative iter-iter node voltage change" } +}; + +int OPTcount = sizeof(OPTtbl)/sizeof(IFparm); + +SPICEanalysis OPTinfo = { + { + "options", + "Task option selection", + sizeof(OPTtbl)/sizeof(IFparm), + OPTtbl + }, + 0, /* no size associated with options */ + NODOMAIN, + 0, + CKTsetOpt, + CKTacct, + NULL, + NULL +}; diff --git a/src/spicelib/analysis/ckttemp.c b/src/spicelib/analysis/ckttemp.c new file mode 100644 index 000000000..a21877ce0 --- /dev/null +++ b/src/spicelib/analysis/ckttemp.c @@ -0,0 +1,42 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* CKTtemp(ckt) + * this is a driver program to iterate through all the various + * temperature dependency functions provided for the circuit + * elements in the given circuit + */ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "const.h" +#include "devdefs.h" +#include "sperror.h" + + + +extern SPICEdev **DEVices; + + + +int +CKTtemp(CKTcircuit *ckt) +{ + int error; + int i; + + ckt->CKTvt = CONSTKoverQ * ckt->CKTtemp; + + for (i=0;iCKThead[i] != NULL) ){ + error = (*((*DEVices[i]).DEVtemperature))(ckt->CKThead[i],ckt); + if(error) return(error); + } + } + return(OK); +} diff --git a/src/spicelib/analysis/cktterr.c b/src/spicelib/analysis/cktterr.c new file mode 100644 index 000000000..611c413de --- /dev/null +++ b/src/spicelib/analysis/cktterr.c @@ -0,0 +1,79 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" + + + +#define ccap (qcap+1) + +void +CKTterr(int qcap, CKTcircuit *ckt, double *timeStep) +{ + double volttol; + double chargetol; + double tol; + double del; + double diff[8]; + double deltmp[8]; + double factor; + int i; + int j; + static double gearCoeff[] = { + .5, + .2222222222, + .1363636364, + .096, + .07299270073, + .05830903790 + }; + static double trapCoeff[] = { + .5, + .08333333333 + }; + + volttol = ckt->CKTabstol + ckt->CKTreltol * + MAX( fabs(*(ckt->CKTstate0+ccap)), fabs(*(ckt->CKTstate1+ccap))); + + chargetol = MAX(fabs(*(ckt->CKTstate0 +qcap)),fabs(*(ckt->CKTstate1+qcap))); + chargetol = ckt->CKTreltol * MAX(chargetol,ckt->CKTchgtol)/ckt->CKTdelta; + tol = MAX(volttol,chargetol); + /* now divided differences */ + for(i=ckt->CKTorder+1;i>=0;i--) { + diff[i] = *(ckt->CKTstates[i] + qcap); + } + for(i=0 ; i <= ckt->CKTorder ; i++) { + deltmp[i] = ckt->CKTdeltaOld[i]; + } + j = ckt->CKTorder; + while(1) { + for(i=0;i <= j;i++) { + diff[i] = (diff[i] - diff[i+1])/deltmp[i]; + } + if (--j < 0) break; + for(i=0;i <= j;i++) { + deltmp[i] = deltmp[i+1] + ckt->CKTdeltaOld[i]; + } + } + switch(ckt->CKTintegrateMethod) { + case GEAR: + factor = gearCoeff[ckt->CKTorder-1]; + break; + + case TRAPEZOIDAL: + factor = trapCoeff[ckt->CKTorder - 1] ; + break; + } + del = ckt->CKTtrtol * tol/MAX(ckt->CKTabstol,factor * fabs(diff[0])); + if(ckt->CKTorder == 2) { + del = sqrt(del); + } else if (ckt->CKTorder > 2) { + del = exp(log(del)/ckt->CKTorder); + } + *timeStep = MIN(*timeStep,del); + return; +} diff --git a/src/spicelib/analysis/ckttroub.c b/src/spicelib/analysis/ckttroub.c new file mode 100644 index 000000000..dfa892731 --- /dev/null +++ b/src/spicelib/analysis/ckttroub.c @@ -0,0 +1,99 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +**********/ + +#include "ngspice.h" +#include +#include "trandefs.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "vsrc/vsrcdefs.h" +#include "isrc/isrcdefs.h" +#include "jobdefs.h" + +#include "analysis.h" + +extern SPICEdev **DEVices; + + +extern SPICEanalysis *analInfo[]; + +char * +CKTtrouble(void *cktp, char *optmsg) +{ + CKTcircuit *ckt = (CKTcircuit *) cktp; + char msg_buf[513]; + char *emsg; + TRCV *cv; + int vcode, icode; + char *msg_p; + SPICEanalysis *an; + int i; + + if (!ckt || !ckt->CKTcurJob) + return NULL; + + an = analInfo[ckt->CKTcurJob->JOBtype]; + + if (optmsg && *optmsg) { + sprintf(msg_buf, "%s: %s; ", an->public.name, optmsg); + } else { + sprintf(msg_buf, "%s: ", an->public.name); + } + + msg_p = msg_buf + strlen(msg_buf); + + switch (an->domain) { + case TIMEDOMAIN: + if (ckt->CKTtime == 0.0) + sprintf(msg_p, "initial timepoint: "); + else + sprintf(msg_p, "time = %g, timestep = %g: ", ckt->CKTtime, + ckt->CKTdelta); + break; + + case FREQUENCYDOMAIN: + sprintf(msg_p, "frequency = %g: ", ckt->CKTomega / (2.0 * M_PI)); + break; + + case SWEEPDOMAIN: + cv = (TRCV*) ckt->CKTcurJob; + vcode = CKTtypelook("Vsource"); + icode = CKTtypelook("Isource"); + + for (i = 0; i <= cv->TRCVnestLevel; i++) { + msg_p += strlen(msg_p); + if(cv->TRCVvType[i]==vcode) { /* voltage source */ + sprintf(msg_p, " %s = %g: ", cv->TRCVvName[i], + ((VSRCinstance*)(cv->TRCVvElt[i]))->VSRCdcValue); + } else { + sprintf(msg_p, " %s = %g: ", cv->TRCVvName[i], + ((ISRCinstance*)(cv->TRCVvElt[i]))->ISRCdcValue); + } + } + break; + + case NODOMAIN: + default: + break; + } + + msg_p += strlen(msg_p); + + if (ckt->CKTtroubleNode) { + sprintf(msg_p, "trouble with node \"%s\"\n", + CKTnodName(ckt, ckt->CKTtroubleNode)); + } else if (ckt->CKTtroubleElt) { + /* "-" for dop */ + sprintf(msg_p, "trouble with %s-instance %s\n", + ckt->CKTtroubleElt->GENmodPtr->GENmodName, + ckt->CKTtroubleElt->GENname); + } else { + sprintf(msg_p, "cause unrecorded.\n"); + } + + emsg = MALLOC(strlen(msg_buf)+1); + strcpy(emsg,msg_buf); + + return emsg; +} diff --git a/src/spicelib/analysis/ckttrunc.c b/src/spicelib/analysis/ckttrunc.c new file mode 100644 index 000000000..23ef03afa --- /dev/null +++ b/src/spicelib/analysis/ckttrunc.c @@ -0,0 +1,202 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* CKTtrunc(ckt) + * this is a driver program to iterate through all the various + * truncation error functions provided for the circuit elements in the + * given circuit + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "smpdefs.h" +#include "devdefs.h" +#include "sperror.h" + + + +extern SPICEdev **DEVices; + + +int +CKTtrunc(CKTcircuit *ckt, double *timeStep) +{ +#ifndef NEWTRUNC + int i; + double timetemp; +#ifdef PARALLEL_ARCH + long type = MT_TRUNC, length = 1; +#endif /* PARALLEL_ARCH */ +#ifdef STEPDEBUG + double debugtemp; +#endif /* STEPDEBUG */ + double startTime; + int error = OK; + + startTime = SPfrontEnd->IFseconds(); + + timetemp = HUGE; + for (i=0;iCKThead[i] != NULL) { +#ifdef STEPDEBUG + debugtemp = timetemp; +#endif /* STEPDEBUG */ + error = (*((*DEVices[i]).DEVtrunc))(ckt->CKThead[i],ckt,&timetemp); + if(error) { + ckt->CKTstat->STATtranTruncTime += SPfrontEnd->IFseconds() + - startTime; + return(error); + } +#ifdef STEPDEBUG + if(debugtemp != timetemp) { + printf("timestep cut by device type %s from %g to %g\n", + (*DEVices[i]).DEVpublic.name, debugtemp,timetemp); + } +#endif /* STEPDEBUG */ + } + } + *timeStep = MIN(2 * *timeStep,timetemp); + +#ifdef PARALLEL_ARCH + DGOP_( &type, timeStep, &length, "min" ); +#endif /* PARALLEL_ARCH */ + + ckt->CKTstat->STATtranTruncTime += SPfrontEnd->IFseconds() - startTime; + return(OK); +#else /* NEWTRUNC */ + int i; + CKTnode *node; + double timetemp; + double tmp; + double diff; + double tol; + double startTime; + int size; + + startTime = (*(SPfrontEnd->IFseconds))(); + + timetemp = HUGE; + size = SMPmatSize(ckt->CKTmatrix); +#ifdef STEPDEBUG + printf("at time %g, delta %g\n",ckt->CKTtime,ckt->CKTdeltaOld[0]); +#endif STEPDEBUG + node = ckt->CKTnodes; + switch(ckt->CKTintegrateMethod) { + + case TRAPEZOIDAL: + switch(ckt->CKTorder) { + case 1: + for(i=1;iCKTrhs[i]),fabs(ckt->CKTpred[i]))* + ckt->CKTlteReltol+ckt->CKTlteAbstol; + node = node->next; + if(node->type!= 3) continue; + diff = ckt->CKTrhs[i]-ckt->CKTpred[i]; +#ifdef STEPDEBUG + printf("%s: cor=%g, pred=%g ",node->name, + ckt->CKTrhs[i],ckt->CKTpred[i]); +#endif + if(diff != 0) { + tmp = ckt->CKTtrtol * tol * 2 /diff; + tmp = ckt->CKTdeltaOld[0]*sqrt(fabs(tmp)); + timetemp = MIN(timetemp,tmp); +#ifdef STEPDEBUG + printf("tol = %g, diff = %g, h->%g\n",tol,diff,tmp); +#endif + } else { +#ifdef STEPDEBUG + printf("diff is 0\n"); +#endif + } + } + break; + case 2: + for(i=1;iCKTrhs[i]),fabs(ckt->CKTpred[i]))* + ckt->CKTlteReltol+ckt->CKTlteAbstol; + node = node->next; + if(node->type!= 3) continue; + diff = ckt->CKTrhs[i]-ckt->CKTpred[i]; +#ifdef STEPDEBUG + printf("%s: cor=%g, pred=%g ",node->name,ckt->CKTrhs[i], + ckt->CKTpred[i]); +#endif + if(diff != 0) { + tmp = ckt->CKTdeltaOld[0]*ckt->CKTtrtol * tol * 3 * + (ckt->CKTdeltaOld[0]+ckt->CKTdeltaOld[1])/diff; + tmp = fabs(tmp); + timetemp = MIN(timetemp,tmp); +#ifdef STEPDEBUG + printf("tol = %g, diff = %g, h->%g\n",tol,diff,tmp); +#endif + } else { +#ifdef STEPDEBUG + printf("diff is 0\n"); +#endif + } + } + break; + default: + return(E_ORDER); + break; + + } + break; + + case GEAR: { + double delsum=0; + for(i=0;i<=ckt->CKTorder;i++) { + delsum += ckt->CKTdeltaOld[i]; + } + for(i=1;inext; + if(node->type!= 3) continue; + tol = MAX( fabs(ckt->CKTrhs[i]),fabs(ckt->CKTpred[i]))* + ckt->CKTlteReltol+ckt->CKTlteAbstol; + diff = (ckt->CKTrhs[i]-ckt->CKTpred[i]); +#ifdef STEPDEBUG + printf("%s: cor=%g, pred=%g ",node->name,ckt->CKTrhs[i], + ckt->CKTpred[i]); +#endif + if(diff != 0) { + tmp = tol*ckt->CKTtrtol*delsum/(diff*ckt->CKTdelta); + tmp = fabs(tmp); + switch(ckt->CKTorder) { + case 0: + break; + case 1: + tmp = sqrt(tmp); + break; + default: + tmp = exp(log(tmp)/(ckt->CKTorder+1)); + break; + } + tmp *= ckt->CKTdelta; + timetemp = MIN(timetemp,tmp); +#ifdef STEPDEBUG + printf("tol = %g, diff = %g, h->%g\n",tol,diff,tmp); +#endif + } else { +#ifdef STEPDEBUG + printf("diff is 0\n"); +#endif + } + } + } + break; + + default: + return(E_METHOD); + + } + *timeStep = MIN(2 * *timeStep,timetemp); +#ifdef PARALLEL_ARCH + DGOP_( &type, timeStep, &length, "min" ); +#endif /* PARALLEL_ARCH */ + ckt->CKTstat->STATtranTruncTime += SPfrontEnd->IFseconds() - startTime; + return(OK); +#endif /* NEWTRUNC */ +} diff --git a/src/spicelib/analysis/ckttyplk.c b/src/spicelib/analysis/ckttyplk.c new file mode 100644 index 000000000..9177cc9dc --- /dev/null +++ b/src/spicelib/analysis/ckttyplk.c @@ -0,0 +1,31 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +/* look up the 'type' in the device description struct and return the + * appropriate strchr for the device found, or -1 for not found + */ + +#include "ngspice.h" +#include "cktdefs.h" +#include "devdefs.h" + + + +extern SPICEdev **DEVices; + +int +CKTtypelook(char *type) +{ + + int i; + for(i=0;i +#ifdef CLUSTER +#include +#include "cluster.h" +#include +#include + +/* Misc stuff */ +#include +#include + +/*Network stuff*/ +#include +#include +#include +#include +#include + + +struct input_pipe { + /*the names of the local and remote nodes*/ + char remote[32]; + char local[32]; + int fd; + FILE *stream; + /* the data recieved */ + double time; + double data; + /*resistance of this link*/ + double res; + /* The value controled */ + double *currentPtr; + /*The output it is linked to*/ + struct output_pipe *link; + struct input_pipe *next; +}; + +struct output_pipe { + int fd; + FILE *stream; + /*the names of the local and remote nodes*/ + char local[32]; + char remote[32]; + /* The index of the local node value in the ckt->CKTrhsOld array */ + int outIndex; + /*Last values sent*/ + double time,data; + struct input_pipe *link; + struct output_pipe *next; +}; + +static double lastTimeSent=0; + +static int time_sock=0; +static FILE *time_outfile=NULL; +static FILE *time_infile=NULL; + +static struct input_pipe* input_pipes=NULL; +static struct output_pipe* output_pipes=NULL; + +/* sets up deamon which waits for connections + *and sets up input pipes as it recieves them */ +static void *start_listener(void *); + +/* Setup the output pipes*/ +static int setup_output(CKTcircuit *ckt); +static int setup_input(CKTcircuit *ckt); +static int setup_time(); + +int CLUsetup(CKTcircuit *ckt){ + pthread_t tid; + struct input_pipe *curr; + int i, connections=0; + GENmodel *mod; + GENinstance *inst; + + /* count the number of connections expected */ + i = INPtypelook("Isource"); + for(mod = (GENmodel *)ckt->CKThead[i]; + mod != NULL; + mod = mod->GENnextModel) + for (inst = mod->GENinstances; + inst != NULL; + inst = inst->GENnextInstance) + if(strncmp("ipcx",inst->GENname,4) == 0) + connections++; + + /* allocate the input connections */ + for(i=0;inext = input_pipes; + else + curr->next = NULL; + input_pipes = curr; + } + + pthread_create(&tid,NULL,start_listener,(void *)&connections); + setup_output(ckt); + pthread_join(tid,NULL); + setup_input(ckt); + setup_time(); + return 0; +} + +#include "../devices/isrc/isrcdefs.h" +/*Connect to remote machine and find the data*/ +static int setup_output(CKTcircuit *ckt){ + int type; + GENmodel *mod; + GENinstance *inst; + char hostname[64]; + + lastTimeSent = 0; + type = INPtypelook("Isource"); + + for(mod = (GENmodel *)ckt->CKThead[type]; + mod != NULL; + mod = mod->GENnextModel) + + for (inst = mod->GENinstances; + inst != NULL; + inst = inst->GENnextInstance) + + if(strncmp("ipcx",inst->GENname,4) == 0){ + ISRCinstance *isrc = (ISRCinstance *)inst; + CKTnode *node; + struct output_pipe *curr; + struct sockaddr_in address; + struct hostent *host=NULL; + int sock,nodeNum,i; + + /*Create the struct*/ + curr = (struct output_pipe *)tmalloc(sizeof(struct output_pipe)); + if(output_pipes) + curr->next = output_pipes; + else + curr->next = NULL; + output_pipes = curr; + + /* The node names */ + strcpy(curr->local,CKTnodName(ckt,isrc->ISRCnegNode));/*weird*/ + strcpy(curr->remote,isrc->ISRCname); + + /* extract remote node number */ + nodeNum = /*Xcoord*/(curr->remote[4] - '0') * CLUSTER_WIDTH + + /*Ycoord*/(curr->remote[9] - '0'); + sprintf(hostname,"n%d."DOMAIN_NAME,nodeNum); + + /* network stuff */ + host = gethostbyname(hostname); + if(!host){ + printf("Host not found in setup_output\n"); + exit(0); + } + + if((sock = socket(PF_INET,SOCK_STREAM,0)) < 0){ + printf("Socket open in setup_output\n"); + exit(0); + } + + address.sin_family = AF_INET; + address.sin_port = htons(PORT); + memcpy(&address.sin_addr,host->h_addr_list[0], + sizeof(address.sin_addr)); + + printf("connecting to %s ...... ",hostname); + fflush(stdout); + + while(connect(sock,(struct sockaddr *)&address,sizeof(address))){ + usleep(500);/*wait for the sever to start*/ + } + + printf("connected\n"); + + curr->fd = sock; + + /* send stuff */ + /* buffer */ + i = (strlen(curr->remote) + strlen(curr->local) + 2)*sizeof(char); + setsockopt(sock,SOL_SOCKET,SO_SNDBUF,&i,sizeof(i)); + + curr->stream = fdopen(curr->fd,"w"); + + fwrite(curr->remote,sizeof(char),strlen(curr->remote),curr->stream); + fputc('\0',curr->stream); + fwrite(curr->local,sizeof(char),strlen(curr->local),curr->stream); + fputc('\0',curr->stream); + fflush(curr->stream); + + /* buffer, what is done per time point */ + i = sizeof(double)*2; + setsockopt(sock,SOL_SOCKET,SO_SNDBUF,&i,sizeof(i)); + + /* find the index in ckt->rhsOld which contains the local node */ + i = 0; + for(node = ckt->CKTnodes->next;node;node = node->next){ + i++; + if(strcmp(node->name,curr->local)==0){ + curr->outIndex = i; + goto next; + } + } + printf("Local node %s not found\n",curr->local); + exit(0); + next: + + } + return 0; +} + +/*Processes the connections recieved by start_listener*/ +static int setup_input(CKTcircuit *ckt){ + int type; + GENmodel *mod; + GENinstance *inst; + struct input_pipe *input; + type = INPtypelook("Isource"); + + for(input = input_pipes;input;input = input->next){ + int i; + + input->stream = fdopen(input->fd,"r"); + + /*Get the local and remote node names*/ + i=0; + do { + while(fread(&input->local[i],sizeof(char),1,input->stream) != 1); + }while(input->local[i++] != '\0'); + + i=0; + do { + while(fread(&input->remote[i],sizeof(char),1,input->stream) != 1); + }while(input->remote[i++] != '\0'); + + /* initilise */ + input->time = -1; + + /*Find the Isource to control*/ + for(mod = (GENmodel *)ckt->CKThead[type]; + mod != NULL; + mod = mod->GENnextModel) + + for (inst = mod->GENinstances; + inst != NULL; + inst = inst->GENnextInstance) + + if(strcmp(input->remote,&inst->GENname[11]) == 0){ + + ISRCinstance *isrc = (ISRCinstance *)inst; + input->res = isrc->ISRCdcValue; + isrc->ISRCdcValue = 0; + input->currentPtr = &isrc->ISRCdcValue; + goto next; + } + /* We get here if no Isource matches */ + printf("Current source %s not found\n",input->remote); + exit(0); + + next: + + /* Now find the corresponding output */ + { + struct output_pipe *output; + for(output = output_pipes;output;output = output->next) + if(strcmp(&input->local[11],output->local)==0){ + input->link = output; + output->link = input; + goto next2; + } + printf("Parent to %s not found\n",&input->local[11]); + exit(0); + next2: + } + } + return 0; +} + +/* This starts a server and waits for connections, number given by argument*/ +static void *start_listener(void *v){ + int *connections = (int *)v; + int count=0; + struct sockaddr_in address; + int sock, conn,i; + size_t addrLength = sizeof(struct sockaddr_in); + struct input_pipe *curr; + + if((sock = socket(PF_INET,SOCK_STREAM,0)) < 0){ + printf("socket in start_listener\n"); + exit(0); + } + + /* Allow reuse of the socket */ + i = 1; + setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i)); + + /* port, inferface ..*/ + address.sin_family = AF_INET; + address.sin_port = htons(PORT); + memset(&address.sin_addr,0,sizeof(address.sin_addr)); + + if(bind(sock, (struct sockaddr *)&address,sizeof(address))){ + printf("bind in start_listener\n"); + exit(0); + } + if(listen(sock,5)){ + printf("listen in start_listener\n"); + exit(0); + } + + /* Loop till recieved all connections */ + curr = input_pipes; + while (count < *connections){ + if((conn = accept(sock, (struct sockaddr *)&address,&addrLength)) < 0){ + printf("accept in start_listener\n"); + exit(0); + } + + curr->fd = conn; + /* will fill rest of structure later in setup_input*/ + count ++; + curr = curr->next; + } + + close(sock); + + return NULL; +} + +/*Writes data to remote computer*/ +int CLUoutput(CKTcircuit *ckt){ + struct output_pipe *output; + lastTimeSent = ckt->CKTtime; + for(output = output_pipes; + output; + output = output->next){ + output->time = ckt->CKTtime; + output->data = ckt->CKTrhsOld[output->outIndex]; + fwrite(&output->time,sizeof(double),1,output->stream); + fwrite(&output->data, + sizeof(double),1,output->stream); + fflush(output->stream); + } + return 0; +} + +/*Maniputates the local circuit based on the links*/ +int CLUinput(CKTcircuit *ckt){ + struct input_pipe *input; + double tmp; + for(input= input_pipes;input;input = input->next){ + /*recieve data till we get a good time point*/ + while (input->time < lastTimeSent){ + while(fread(&input->time, sizeof(double), 1, input->stream) != 1){} + while(fread(&input->data, sizeof(double), 1, input->stream) != 1){} + } + tmp = (input->link->data - input->data) / input->res; + + /*dampen out large currents*/ + if(tmp > 0) + *input->currentPtr = 0.2 * (1 - exp(-tmp/0.2)); + else + *input->currentPtr = -0.2 * (1 - exp(tmp/0.2)); + + /*GND is the posNode, local node is the negNode*/ + } + return 0; +} + +static int setup_time(){ + struct sockaddr_in address; + struct hostent *host=NULL; + char *hostname = TIME_HOST; + int sock,i; + + /* network stuff */ + host = gethostbyname(hostname); + if(!host){ + printf("Host not found in setup_time\n"); + exit(0); + } + if((sock = socket(PF_INET,SOCK_STREAM,0)) < 0){ + printf("Socket open in setup_time\n"); + exit(0); + } + + i = sizeof(double)*2; + setsockopt(sock,SOL_SOCKET,SO_SNDBUF ,&i,sizeof(i)); + + address.sin_family = AF_INET; + address.sin_port = htons(TIME_PORT); + memcpy(&address.sin_addr,host->h_addr_list[0], + sizeof(address.sin_addr)); + + + while(connect(sock,(struct sockaddr *)&address,sizeof(address))){ + usleep(500);/*wait for the sever to start*/ + } + time_sock=sock; + time_outfile=fdopen(sock,"w"); + time_infile=fdopen(sock,"r"); + + return 0; +} + + +int CLUsync(double time,double *delta, int error){ + double tmp; + if(error) + tmp = *delta * (-1); + else + tmp = *delta; + fwrite(&time,sizeof(double),1,time_outfile); + fwrite(&tmp,sizeof(double),1,time_outfile); + fflush(time_outfile); + while(fread(&tmp,sizeof(double),1,time_infile) != 1); + if(tmp < 0){ + *delta = -tmp; + return 0; + } else { + *delta = tmp; + return 1; + } +} +#endif diff --git a/src/spicelib/analysis/daskq.c b/src/spicelib/analysis/daskq.c new file mode 100644 index 000000000..7433fad71 --- /dev/null +++ b/src/spicelib/analysis/daskq.c @@ -0,0 +1,63 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Jaijeet S Roychowdhury +**********/ + + +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "cktdefs.h" +#include "distodef.h" + + +/* ARGSUSED */ +int +DaskQuest(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + switch(which) { + + case D_START: + value->rValue = ((DISTOAN*)anal)->DstartF1; + break; + + case D_STOP: + value->rValue = ((DISTOAN*)anal)->DstopF1 ; + break; + + case D_STEPS: + value->iValue = ((DISTOAN*)anal)->DnumSteps; + break; + + case D_DEC: + if(((DISTOAN*)anal)->DstepType == DECADE) { + value->iValue=1; + } else { + value->iValue=0; + } + break; + + case D_OCT: + if(((DISTOAN*)anal)->DstepType == OCTAVE) { + value->iValue=1; + } else { + value->iValue=0; + } + break; + + case D_LIN: + if(((DISTOAN*)anal)->DstepType == LINEAR) { + value->iValue=1; + } else { + value->iValue=0; + } + break; + + case D_F2OVRF1: + value->rValue = ((DISTOAN*)anal)->Df2ovrF1; + break; + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/analysis/dcoaskq.c b/src/spicelib/analysis/dcoaskq.c new file mode 100644 index 000000000..67fd67c83 --- /dev/null +++ b/src/spicelib/analysis/dcoaskq.c @@ -0,0 +1,20 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "opdefs.h" +#include "cktdefs.h" + + +/* ARGSUSED */ +int +DCOaskQuest(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + return(E_BADPARM); +} + diff --git a/src/spicelib/analysis/dcop.c b/src/spicelib/analysis/dcop.c new file mode 100644 index 000000000..73088abfe --- /dev/null +++ b/src/spicelib/analysis/dcop.c @@ -0,0 +1,106 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "sperror.h" +#include "ifsim.h" + + +int +DCop(CKTcircuit *ckt) +{ + int CKTload(CKTcircuit *ckt); + int converged; + int error; + IFuid *nameList; + int numNames; + void *plot=NULL; + + error = CKTnames(ckt,&numNames,&nameList); + if(error) return(error); + error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob, ckt->CKTcurJob->JOBname, + (IFuid)NULL,IF_REAL,numNames,nameList, IF_REAL,&plot); + if(error) return(error); + + converged = CKTop(ckt, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, + ckt->CKTdcMaxIter); + if(converged != 0) { + fprintf(stdout,"\nDC solution failed -\n"); + CKTncDump(ckt); +/* + CKTnode *node; + double new, old, tol; + int i=1; + + fprintf(stdout,"\nDC solution failed -\n\n"); + fprintf(stdout,"Last Node Voltages\n"); + fprintf(stdout,"------------------\n\n"); + fprintf(stdout,"%-30s %20s %20s\n", "Node", "Last Voltage", + "Previous Iter"); + fprintf(stdout,"%-30s %20s %20s\n", "----", "------------", + "-------------"); + for(node=ckt->CKTnodes->next;node;node=node->next) { + if (strstr(node->name, "#branch") || !strstr(node->name, "#")) { + new = *((ckt->CKTrhsOld) + i ) ; + old = *((ckt->CKTrhs) + i ) ; + fprintf(stdout,"%-30s %20g %20g", node->name, new, old); + if(node->type == 3) { + tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) + + ckt->CKTvoltTol; + } else { + tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) + + ckt->CKTabstol; + } + if (fabs(new-old) >tol ) { + fprintf(stdout," *"); + } + fprintf(stdout,"\n"); + }; + i++; + }; + fprintf(stdout,"\n"); + (*(SPfrontEnd->OUTendPlot))(plot); */ + + return(converged); + }; + + ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG; + + +#ifdef WANT_SENSE2 + if(ckt->CKTsenInfo && ((ckt->CKTsenInfo->SENmode&DCSEN) || + (ckt->CKTsenInfo->SENmode&ACSEN)) ){ +#ifdef SENSDEBUG + printf("\nDC Operating Point Sensitivity Results\n\n"); + CKTsenPrint(ckt); +#endif /* SENSDEBUG */ + senmode = ckt->CKTsenInfo->SENmode; + save = ckt->CKTmode; + ckt->CKTsenInfo->SENmode = DCSEN; + size = SMPmatSize(ckt->CKTmatrix); + for(i = 1; i<=size ; i++){ + *(ckt->CKTrhsOp + i) = *(ckt->CKTrhsOld + i); + } + if(error = CKTsenDCtran(ckt)) return(error); + ckt->CKTmode = save; + ckt->CKTsenInfo->SENmode = senmode; + + } +#endif + converged = CKTload(ckt); + if(converged == 0) { + CKTdump(ckt,(double)0,plot); + } else { + fprintf(stderr,"error: circuit reload failed.\n"); + }; + (*(SPfrontEnd->OUTendPlot))(plot); + return(converged); +} diff --git a/src/spicelib/analysis/dcosetp.c b/src/spicelib/analysis/dcosetp.c new file mode 100644 index 000000000..bcf174223 --- /dev/null +++ b/src/spicelib/analysis/dcosetp.c @@ -0,0 +1,44 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "cktdefs.h" +#include "opdefs.h" + + +#include "analysis.h" + +/* ARGSUSED */ +int +DCOsetParm(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + switch(which) { + + default: + break; + } + return(E_BADPARM); +} + + +SPICEanalysis DCOinfo = { + { + "OP", + "D.C. Operating point analysis", + + 0, + NULL, + }, + sizeof(OP), + NODOMAIN, + 1, + DCOsetParm, + DCOaskQuest, + NULL, + DCop +}; diff --git a/src/spicelib/analysis/dctaskq.c b/src/spicelib/analysis/dctaskq.c new file mode 100644 index 000000000..9748a61bf --- /dev/null +++ b/src/spicelib/analysis/dctaskq.c @@ -0,0 +1,26 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "trcvdefs.h" +#include "cktdefs.h" + + +/* ARGSUSED */ +int +DCTaskQuest(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + switch(which) { + + default: + break; + } + /* NOTREACHED */ /* TEMPORARY until cases get added */ + return(E_BADPARM); +} + diff --git a/src/spicelib/analysis/dctran.c b/src/spicelib/analysis/dctran.c new file mode 100644 index 000000000..da6ed292e --- /dev/null +++ b/src/spicelib/analysis/dctran.c @@ -0,0 +1,852 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes +**********/ + +/* subroutine to do DC TRANSIENT analysis + --- ONLY, unlike spice2 routine with the same name! */ + +#include +#include +#include +#include +#include + +#ifdef XSPICE +/* gtri - add - wbk - Add headers */ +#include "miftypes.h" +/* gtri - end - wbk - Add headers */ + +/* gtri - add - wbk - Add headers */ +#include "evt.h" +#include "mif.h" +#include "evtproto.h" +#include "ipctiein.h" +/* gtri - end - wbk - Add headers */ +#endif + +#ifdef CLUSTER +#include "cluster.h" +#endif + + +int +DCtran(CKTcircuit *ckt, + int restart) /* forced restart flag */ +{ + int i; + double olddelta; + double delta; + double new; + double *temp; + double startdTime; + double startsTime; + double startlTime; + double startcTime; + double startkTime; + double startTime; + int startIters; + int converged; + int firsttime; + int error; +#ifdef WANT_SENSE2 +#ifdef SENSDEBUG + FILE *outsen; +#endif /* SENSDEBUG */ +#endif + int save_order; + long save_mode; + IFuid timeUid; + IFuid *nameList; + int numNames; + double maxstepsize=0.0; + int ltra_num; + CKTnode *node; +#ifdef PARALLEL_ARCH + long type = MT_TRANAN, length = 1; +#endif /* PARALLEL_ARCH */ +#ifdef XSPICE +/* gtri - add - wbk - 12/19/90 - Add IPC stuff */ + Ipc_Boolean_t ipc_firsttime = IPC_TRUE; + Ipc_Boolean_t ipc_secondtime = IPC_FALSE; + Ipc_Boolean_t ipc_delta_cut = IPC_FALSE; + double ipc_last_time = 0.0; + double ipc_last_delta = 0.0; +/* gtri - end - wbk - 12/19/90 - Add IPC stuff */ +#endif +#ifdef CLUSTER + int redostep; +#endif + if(restart || ckt->CKTtime == 0) { + delta=MIN(ckt->CKTfinalTime/200,ckt->CKTstep)/10; + + /* begin LTRA code addition */ + if (ckt->CKTtimePoints != NULL) + FREE(ckt->CKTtimePoints); + + if (ckt->CKTstep >= ckt->CKTmaxStep) + maxstepsize = ckt->CKTstep; + else + maxstepsize = ckt->CKTmaxStep; + + ckt->CKTsizeIncr = 10; + ckt->CKTtimeIndex = -1; /* before the DC soln has been stored */ + ckt->CKTtimeListSize = ckt->CKTfinalTime / maxstepsize + 0.5; + ltra_num = CKTtypelook("LTRA"); + if (ltra_num >= 0 && ckt->CKThead[ltra_num] != NULL) + ckt->CKTtimePoints = NEWN(double, ckt->CKTtimeListSize); + /* end LTRA code addition */ + + if(ckt->CKTbreaks) FREE(ckt->CKTbreaks); + ckt->CKTbreaks=(double *)MALLOC(2*sizeof(double)); + if(ckt->CKTbreaks == (double *)NULL) return(E_NOMEM); + *(ckt->CKTbreaks)=0; + *(ckt->CKTbreaks+1)=ckt->CKTfinalTime; + ckt->CKTbreakSize=2; + if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5; +#ifdef XSPICE +/* gtri - add - wbk - 12/19/90 - Add IPC stuff and set anal_init and anal_type */ + + /* Tell the beginPlot routine what mode we're in */ + g_ipc.anal_type = IPC_ANAL_TRAN; + + /* Tell the code models what mode we're in */ + g_mif_info.circuit.anal_type = MIF_DC; + + g_mif_info.circuit.anal_init = MIF_TRUE; + +/* gtri - end - wbk */ +#endif + error = CKTnames(ckt,&numNames,&nameList); + if(error) return(error); + (*(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) return(error); + + ckt->CKTtime = 0; + ckt->CKTdelta = 0; + ckt->CKTbreak=1; + firsttime = 1; + save_mode = (ckt->CKTmode&MODEUIC)|MODETRANOP | MODEINITJCT; + save_order = ckt->CKTorder; +#ifdef XSPICE +/* gtri - begin - wbk - set a breakpoint at end of supply ramping time */ + /* must do this after CKTtime set to 0 above */ + if(ckt->enh->ramp.ramptime > 0.0) + CKTsetBreak(ckt, ckt->enh->ramp.ramptime); +/* gtri - end - wbk - set a breakpoint at end of supply ramping time */ + +/* gtri - begin - wbk - Call EVTop if event-driven instances exist */ + if(ckt->evt->counts.num_insts != 0){ + /* use new DCOP algorithm */ + converged = EVTop(ckt, + (ckt->CKTmode & MODEUIC) | MODETRANOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITFLOAT, + ckt->CKTdcMaxIter, + MIF_TRUE); + EVTdump(ckt, IPC_ANAL_DCOP, 0.0); + + EVTop_save(ckt, MIF_FALSE, 0.0); + + /* gtri - end - wbk - Call EVTop if event-driven instances exist */ + } else +#endif + converged = CKTop(ckt, + (ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITJCT, + (ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITFLOAT, + ckt->CKTdcMaxIter); + + if(converged != 0) { + fprintf(stdout,"\nTransient solution failed -\n"); + CKTncDump(ckt); + /* CKTnode *node; + double new, old, tol; + int i=1; + + fprintf(stdout,"\nTransient solution failed -\n\n"); + fprintf(stdout,"Last Node Voltages\n"); + fprintf(stdout,"------------------\n\n"); + fprintf(stdout,"%-30s %20s %20s\n", "Node", "Last Voltage", + "Previous Iter"); + fprintf(stdout,"%-30s %20s %20s\n", "----", "------------", + "-------------"); + for(node=ckt->CKTnodes->next;node;node=node->next) { + if (strstr(node->name, "#branch") || !strstr(node->name, "#")) { + new = *((ckt->CKTrhsOld) + i ) ; + old = *((ckt->CKTrhs) + i ) ; + fprintf(stdout,"%-30s %20g %20g", node->name, new, old); + if(node->type == 3) { + tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) + + ckt->CKTvoltTol; + } else { + tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) + + ckt->CKTabstol; + } + if (fabs(new-old) >tol ) { + fprintf(stdout," *"); + } + fprintf(stdout,"\n"); + }; + i++; + } */ + } else { + fprintf(stdout,"\nInitial Transient Solution\n"); + fprintf(stdout,"--------------------------\n\n"); + fprintf(stdout,"%-30s %15s\n", "Node", "Voltage"); + fprintf(stdout,"%-30s %15s\n", "----", "-------"); + for(node=ckt->CKTnodes->next;node;node=node->next) { + if (strstr(node->name, "#branch") || !strstr(node->name, "#")) + fprintf(stdout,"%-30s %15g\n", node->name, + *(ckt->CKTrhsOld+node->number)); + }; + }; + fprintf(stdout,"\n"); + fflush(stdout); + if(converged != 0) return(converged); +#ifdef XSPICE +/* gtri - add - wbk - 12/19/90 - Add IPC stuff */ + + /* Send the operating point results for Mspice compatibility */ + if(g_ipc.enabled) { + ipc_send_dcop_prefix(); + CKTdump(ckt,(double)0,(((TRANan*)ckt->CKTcurJob)->TRANplot)); + ipc_send_dcop_suffix(); + } + +/* gtri - end - wbk */ + + +/* gtri - add - wbk - 12/19/90 - set anal_init and anal_type */ + + g_mif_info.circuit.anal_init = MIF_TRUE; + + /* Tell the code models what mode we're in */ + g_mif_info.circuit.anal_type = MIF_TRAN; + +/* gtri - end - wbk */ + +/* gtri - begin - wbk - Add Breakpoint stuff */ + + /* Initialize the temporary breakpoint variables to infinity */ + g_mif_info.breakpoint.current = 1.0e30; + g_mif_info.breakpoint.last = 1.0e30; + +/* gtri - end - wbk - Add Breakpoint stuff */ +#endif + ckt->CKTstat->STATtimePts ++; + ckt->CKTorder=1; + for(i=0;i<7;i++) { + ckt->CKTdeltaOld[i]=ckt->CKTmaxStep; + } + ckt->CKTdelta = delta; +#ifdef STEPDEBUG + (void)printf("delta initialized to %g\n",ckt->CKTdelta); +#endif + ckt->CKTsaveDelta = ckt->CKTfinalTime/50; + +#ifdef WANT_SENSE2 + if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){ +#ifdef SENSDEBUG + printf("\nTransient Sensitivity Results\n\n"); + CKTsenPrint(ckt); +#endif /* SENSDEBUG */ + save = ckt->CKTsenInfo->SENmode; + ckt->CKTsenInfo->SENmode = TRANSEN; + save1 = ckt->CKTmode; + save2 = ckt->CKTorder; + ckt->CKTmode = save_mode; + ckt->CKTorder = save_order; + if(error = CKTsenDCtran(ckt)) return(error); + ckt->CKTmode = save1; + ckt->CKTorder = save2; + } +#endif + + ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN; + /* modeinittran set here */ + ckt->CKTag[0]=ckt->CKTag[1]=0; + bcopy((char *)ckt->CKTstate0,(char *)ckt->CKTstate1, + ckt->CKTnumStates*sizeof(double)); + +#ifdef WANT_SENSE2 + if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){ + size = SMPmatSize(ckt->CKTmatrix); + for(i = 1; i<=size ; i++) + *(ckt->CKTrhsOp + i) = *(ckt->CKTrhsOld + i); + } +#endif + + startTime=(*(SPfrontEnd->IFseconds))(); + startIters = ckt->CKTstat->STATnumIter; + startdTime = ckt->CKTstat->STATdecompTime; + startsTime = ckt->CKTstat->STATsolveTime; + startlTime = ckt->CKTstat->STATloadTime; + startcTime = ckt->CKTstat->STATcombineTime; + startkTime = ckt->CKTstat->STATsyncTime; +#ifdef CLUSTER + CLUsetup(ckt); +#endif + } else { + /*saj As traninit resets CKTmode */ + ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITPRED; + /* saj */ + startTime=(*(SPfrontEnd->IFseconds))(); + startIters = ckt->CKTstat->STATnumIter; + startdTime = ckt->CKTstat->STATdecompTime; + startsTime = ckt->CKTstat->STATsolveTime; + startlTime = ckt->CKTstat->STATloadTime; + startcTime = ckt->CKTstat->STATcombineTime; + startkTime = ckt->CKTstat->STATsyncTime; + if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5; + firsttime=0; + /* To get rawfile working saj*/ + error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, (void*)ckt->CKTcurJob, + ckt->CKTcurJob->JOBname,timeUid,IF_REAL,666,nameList, + 666,&(((TRANan*)ckt->CKTcurJob)->TRANplot));/*magic 666 nums as flags */ + if(error) { + fprintf(stderr, "Couldn't relink rawfile\n"); + return error; + } + /*end saj*/ + goto resume; + } + +/* 650 */ +nextTime: + + /* begin LTRA code addition */ + if (ckt->CKTtimePoints) { + ckt->CKTtimeIndex++; + if (ckt->CKTtimeIndex >= ckt->CKTtimeListSize) { + /* need more space */ + int need; + need = 0.5 + (ckt->CKTfinalTime - ckt->CKTtime) / maxstepsize; + if (need < ckt->CKTsizeIncr) + need = ckt->CKTsizeIncr; + ckt->CKTtimeListSize += need; + ckt->CKTtimePoints = (double *) REALLOC( (char *) + ckt->CKTtimePoints, sizeof(double) * ckt->CKTtimeListSize); + ckt->CKTsizeIncr *= 1.4; + } + *(ckt->CKTtimePoints + ckt->CKTtimeIndex) = ckt->CKTtime; + } + /* end LTRA code addition */ + + error = CKTaccept(ckt); + /* check if current breakpoint is outdated; if so, clear */ + if (ckt->CKTtime > *(ckt->CKTbreaks)) CKTclrBreak(ckt); + +/* + * Breakpoint handling scheme: + * When a timepoint t is accepted (by CKTaccept), clear all previous + * breakpoints, because they will never be needed again. + * + * t may itself be a breakpoint, or indistinguishably close. DON'T + * clear t itself; recognise it as a breakpoint and act accordingly + * + * if t is not a breakpoint, limit the timestep so that the next + * breakpoint is not crossed + */ + +#ifdef STEPDEBUG + printf("Delta %g accepted at time %g\n",ckt->CKTdelta,ckt->CKTtime); + fflush(stdout); +#endif /* STEPDEBUG */ + ckt->CKTstat->STATaccepted ++; + ckt->CKTbreak=0; + /* XXX Error will cause single process to bail. */ + if(error) { + ckt->CKTcurrentAnalysis = DOING_TRAN; + ckt->CKTstat->STATtranTime += (*(SPfrontEnd->IFseconds))()-startTime; + ckt->CKTstat->STATtranIter += ckt->CKTstat->STATnumIter - startIters; + ckt->CKTstat->STATtranDecompTime += ckt->CKTstat->STATdecompTime - + startdTime; + ckt->CKTstat->STATtranSolveTime += ckt->CKTstat->STATsolveTime - + startsTime; + ckt->CKTstat->STATtranLoadTime += ckt->CKTstat->STATloadTime - + startlTime; + ckt->CKTstat->STATtranCombTime += ckt->CKTstat->STATcombineTime - + startcTime; + ckt->CKTstat->STATtranSyncTime += ckt->CKTstat->STATsyncTime - + startkTime; + return(error); + } +#ifdef XSPICE +/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */ + + if(g_ipc.enabled) { + + /* Send event-driven results */ + EVTdump(ckt, IPC_ANAL_TRAN, 0.0); + + /* Then follow with analog results... */ + + /* Test to see if delta was cut by a breakpoint, */ + /* a non-convergence, or a too large truncation error */ + if(ipc_firsttime) + ipc_delta_cut = IPC_FALSE; + else if(ckt->CKTtime < (ipc_last_time + (0.999 * ipc_last_delta))) + ipc_delta_cut = IPC_TRUE; + else + ipc_delta_cut = IPC_FALSE; + + /* Record the data required to check for delta cuts */ + ipc_last_time = ckt->CKTtime; + ipc_last_delta = MIN(ckt->CKTdelta, ckt->CKTmaxStep); + + /* Send results data if time since last dump is greater */ + /* than 'mintime', or if first or second timepoints, */ + /* or if delta was cut */ + if( (ckt->CKTtime >= (g_ipc.mintime + g_ipc.last_time)) || + ipc_firsttime || ipc_secondtime || ipc_delta_cut ) { + + ipc_send_data_prefix(ckt->CKTtime); + CKTdump(ckt,ckt->CKTtime, + (((TRANan*)ckt->CKTcurJob)->TRANplot)); + ipc_send_data_suffix(); + + if(ipc_firsttime) { + ipc_firsttime = IPC_FALSE; + ipc_secondtime = IPC_TRUE; + } + else if(ipc_secondtime) + ipc_secondtime = IPC_FALSE; + + g_ipc.last_time = ckt->CKTtime; + } + } + else +/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */ +#endif +#ifdef CLUSTER + CLUoutput(ckt); +#endif + if(ckt->CKTtime >= ckt->CKTinitTime) CKTdump(ckt,ckt->CKTtime, + (((TRANan*)ckt->CKTcurJob)->TRANplot)); +#ifdef XSPICE +/* gtri - begin - wbk - Update event queues/data for accepted timepoint */ + + /* Note: this must be done AFTER sending results to SI so it can't */ + /* go next to CKTaccept() above */ + if(ckt->evt->counts.num_insts > 0) + EVTaccept(ckt, ckt->CKTtime); +/* gtri - end - wbk - Update event queues/data for accepted timepoint */ +#endif + ckt->CKTstat->STAToldIter = ckt->CKTstat->STATnumIter; + if(fabs(ckt->CKTtime - ckt->CKTfinalTime) < ckt->CKTminBreak) { + /*printf(" done: time is %g, final time is %g, and tol is %g\n",*/ + /*ckt->CKTtime,ckt->CKTfinalTime,ckt->CKTminBreak);*/ + (*(SPfrontEnd->OUTendPlot))( (((TRANan*)ckt->CKTcurJob)->TRANplot)); + ckt->CKTcurrentAnalysis = 0; + ckt->CKTstat->STATtranTime += (*(SPfrontEnd->IFseconds))()-startTime; + ckt->CKTstat->STATtranIter += ckt->CKTstat->STATnumIter - startIters; + ckt->CKTstat->STATtranDecompTime += ckt->CKTstat->STATdecompTime - + startdTime; + ckt->CKTstat->STATtranSolveTime += ckt->CKTstat->STATsolveTime - + startsTime; + ckt->CKTstat->STATtranLoadTime += ckt->CKTstat->STATloadTime - + startlTime; + ckt->CKTstat->STATtranCombTime += ckt->CKTstat->STATcombineTime - + startcTime; + ckt->CKTstat->STATtranSyncTime += ckt->CKTstat->STATsyncTime - + startkTime; +#ifdef WANT_SENSE2 + if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){ + ckt->CKTsenInfo->SENmode = save; +#ifdef SENSDEBUG + fclose(outsen); +#endif /* SENSDEBUG */ + } +#endif + return(OK); + } + if( (*(SPfrontEnd->IFpauseTest))() ) { + /* user requested pause... */ + ckt->CKTcurrentAnalysis = DOING_TRAN; + ckt->CKTstat->STATtranTime += (*(SPfrontEnd->IFseconds))()-startTime; + ckt->CKTstat->STATtranIter += ckt->CKTstat->STATnumIter - startIters; + ckt->CKTstat->STATtranDecompTime += ckt->CKTstat->STATdecompTime - + startdTime; + ckt->CKTstat->STATtranSolveTime += ckt->CKTstat->STATsolveTime - + startsTime; + ckt->CKTstat->STATtranLoadTime += ckt->CKTstat->STATloadTime - + startlTime; + ckt->CKTstat->STATtranCombTime += ckt->CKTstat->STATcombineTime - + startcTime; + ckt->CKTstat->STATtranSyncTime += ckt->CKTstat->STATsyncTime - + startkTime; + return(E_PAUSE); + } +resume: +#ifdef STEPDEBUG + if( (ckt->CKTdelta <= ckt->CKTfinalTime/50) && + (ckt->CKTdelta <= ckt->CKTmaxStep)) { + ; + } else { + if(ckt->CKTfinalTime/50CKTmaxStep) { + (void)printf("limited by Tstop/50\n"); + } else { + (void)printf("limited by Tmax\n"); + } + } +#endif + ckt->CKTdelta = + MIN(ckt->CKTdelta,ckt->CKTmaxStep); + /* are we at a breakpoint, or indistinguishably close? */ + if ((ckt->CKTtime == *(ckt->CKTbreaks)) || (*(ckt->CKTbreaks) - + (ckt->CKTtime) <= ckt->CKTdelmin)) { + /* first timepoint after a breakpoint - cut integration order */ + /* and limit timestep to .1 times minimum of time to next breakpoint, + * and previous timestep + */ + ckt->CKTorder = 1; +#ifdef STEPDEBUG + if( (ckt->CKTdelta >.1* ckt->CKTsaveDelta) || + (ckt->CKTdelta > .1*(*(ckt->CKTbreaks+1)-*(ckt->CKTbreaks))) ) { + if(ckt->CKTsaveDelta < (*(ckt->CKTbreaks+1)-*(ckt->CKTbreaks))) { + (void)printf("limited by pre-breakpoint delta\n"); + } else { + (void)printf("limited by next breakpoint\n"); + } + } +#endif + + ckt->CKTdelta = MIN(ckt->CKTdelta, .1 * MIN(ckt->CKTsaveDelta, + *(ckt->CKTbreaks+1)-*(ckt->CKTbreaks))); + + if(firsttime) { + ckt->CKTdelta /= 10; +#ifdef STEPDEBUG + (void)printf("delta cut for initial timepoint\n"); +#endif + } + + /* don't want to get below delmin for no reason */ + ckt->CKTdelta = MAX(ckt->CKTdelta, ckt->CKTdelmin*2.0); + } + else if(ckt->CKTtime + ckt->CKTdelta >= *(ckt->CKTbreaks)) { + ckt->CKTsaveDelta = ckt->CKTdelta; + ckt->CKTdelta = *(ckt->CKTbreaks) - ckt->CKTtime; +#ifdef STEPDEBUG + (void)printf("delta cut to %g to hit breakpoint\n",ckt->CKTdelta); + fflush(stdout); +#endif + ckt->CKTbreak = 1; /* why? the current pt. is not a bkpt. */ + } +#ifdef CLUSTER + if(!CLUsync(ckt->CKTtime,&ckt->CKTdelta,0)){ + printf("Sync error!\n"); + exit(0); + } +#endif +#ifdef PARALLEL_ARCH + DGOP_( &type, &(ckt->CKTdelta), &length, "min" ); +#endif /* PARALLEL_ARCH */ +#ifdef XSPICE +/* gtri - begin - wbk - Do event solution */ + + if(ckt->evt->counts.num_insts > 0) { + + /* if time = 0 and op_alternate was specified as false during */ + /* dcop analysis, call any changed instances to let them */ + /* post their outputs with their associated delays */ + if((ckt->CKTtime == 0.0) && (! ckt->evt->options.op_alternate)) + EVTiter(ckt); + + /* while there are events on the queue with event time <= next */ + /* projected analog time, process them */ + while((g_mif_info.circuit.evt_step = EVTnext_time(ckt)) + <= (ckt->CKTtime + ckt->CKTdelta)) { + + /* Initialize temp analog bkpt to infinity */ + g_mif_info.breakpoint.current = 1e30; + + /* Pull items off queue and process them */ + EVTdequeue(ckt, g_mif_info.circuit.evt_step); + EVTiter(ckt); + + /* If any instances have forced an earlier */ + /* next analog time, cut the delta */ + if(*(ckt->CKTbreaks) < g_mif_info.breakpoint.current) + if(*(ckt->CKTbreaks) > (ckt->CKTtime + ckt->CKTminBreak)) + g_mif_info.breakpoint.current = *(ckt->CKTbreaks); + if(g_mif_info.breakpoint.current < (ckt->CKTtime + ckt->CKTdelta)) { + /* Breakpoint must be > last accepted timepoint */ + /* and >= current event time */ + if(g_mif_info.breakpoint.current > (ckt->CKTtime + ckt->CKTminBreak) + && (g_mif_info.breakpoint.current >= g_mif_info.circuit.evt_step)) { + ckt->CKTsaveDelta = ckt->CKTdelta; + ckt->CKTdelta = g_mif_info.breakpoint.current - ckt->CKTtime; + g_mif_info.breakpoint.last = ckt->CKTtime + ckt->CKTdelta; + } + } + + } /* end while next event time <= next analog time */ + } /* end if there are event instances */ + +/* gtri - end - wbk - Do event solution */ +#endif + for(i=5;i>=0;i--) { + ckt->CKTdeltaOld[i+1]=ckt->CKTdeltaOld[i]; + } + ckt->CKTdeltaOld[0]=ckt->CKTdelta; + + temp = ckt->CKTstates[ckt->CKTmaxOrder+1]; + for(i=ckt->CKTmaxOrder;i>=0;i--) { + ckt->CKTstates[i+1] = ckt->CKTstates[i]; + } + ckt->CKTstates[0] = temp; + +/* 600 */ + while (1) { +#ifdef CLUSTER + redostep = 1; +#endif +#ifdef XSPICE +/* gtri - add - wbk - 4/17/91 - Fix Berkeley bug */ +/* This is needed here to allow CAPask to output currents */ +/* during Transient analysis. A grep for CKTcurrentAnalysis */ +/* indicates that it should not hurt anything else ... */ + + ckt->CKTcurrentAnalysis = DOING_TRAN; + +/* gtri - end - wbk - 4/17/91 - Fix Berkeley bug */ +#endif + olddelta=ckt->CKTdelta; + /* time abort? */ + ckt->CKTtime += ckt->CKTdelta; +#ifdef CLUSTER + CLUinput(ckt); +#endif + ckt->CKTdeltaOld[0]=ckt->CKTdelta; + NIcomCof(ckt); +#ifdef PREDICTOR + error = NIpred(ckt); +#endif /* PREDICTOR */ + save_mode = ckt->CKTmode; + save_order = ckt->CKTorder; +#ifdef XSPICE +/* gtri - begin - wbk - Add Breakpoint stuff */ + + /* Initialize temporary breakpoint to infinity */ + g_mif_info.breakpoint.current = 1.0e30; + +/* gtri - end - wbk - Add Breakpoint stuff */ + + +/* gtri - begin - wbk - add convergence problem reporting flags */ + /* delta is forced to equal delmin on last attempt near line 650 */ + if(ckt->CKTdelta <= ckt->CKTdelmin) + ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE; + else + ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE; +/* gtri - begin - wbk - add convergence problem reporting flags */ + + + +/* gtri - begin - wbk - Call all hybrids */ + +/* gtri - begin - wbk - Set evt_step */ + + if(ckt->evt->counts.num_insts > 0) { + g_mif_info.circuit.evt_step = ckt->CKTtime; + } +/* gtri - end - wbk - Set evt_step */ +#endif + + converged = NIiter(ckt,ckt->CKTtranMaxIter); + +#ifdef XSPICE + if(ckt->evt->counts.num_insts > 0) + { + g_mif_info.circuit.evt_step = ckt->CKTtime; + EVTcall_hybrids(ckt); + } +/* gtri - end - wbk - Call all hybrids */ + +#endif + ckt->CKTstat->STATtimePts ++; + ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITPRED; + if(firsttime) { + for(i=0;iCKTnumStates;i++) { + *(ckt->CKTstate2+i) = *(ckt->CKTstate1+i); + *(ckt->CKTstate3+i) = *(ckt->CKTstate1+i); + } + } + if(converged != 0) { +#ifndef CLUSTER + ckt->CKTtime = ckt->CKTtime -ckt->CKTdelta; + ckt->CKTstat->STATrejected ++; +#endif + ckt->CKTdelta = ckt->CKTdelta/8; +#ifdef STEPDEBUG + (void)printf("delta cut to %g for non-convergance\n",ckt->CKTdelta); + fflush(stdout); +#endif + if(firsttime) { + ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN; + } + ckt->CKTorder = 1; + } else { + if (firsttime) { +#ifdef WANT_SENSE2 + if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){ + save1 = ckt->CKTmode; + save2 = ckt->CKTorder; + ckt->CKTmode = save_mode; + ckt->CKTorder = save_order; + if(error = CKTsenDCtran(ckt)) return(error); + ckt->CKTmode = save1; + ckt->CKTorder = save2; + } +#endif + firsttime =0; +#ifndef CLUSTER + goto nextTime; /* no check on + * first time point + */ +#else + redostep = 0; + goto chkStep; +#endif + } + new = ckt->CKTdelta; + error = CKTtrunc(ckt,&new); + if(error) { + ckt->CKTcurrentAnalysis = DOING_TRAN; + ckt->CKTstat->STATtranTime += + (*(SPfrontEnd->IFseconds))()-startTime; + ckt->CKTstat->STATtranIter += + ckt->CKTstat->STATnumIter - startIters; + ckt->CKTstat->STATtranDecompTime += ckt->CKTstat->STATdecompTime + - startdTime; + ckt->CKTstat->STATtranSolveTime += ckt->CKTstat->STATsolveTime + - startsTime; + ckt->CKTstat->STATtranLoadTime += ckt->CKTstat->STATloadTime + - startlTime; + ckt->CKTstat->STATtranCombTime += ckt->CKTstat->STATcombineTime + - startcTime; + ckt->CKTstat->STATtranSyncTime += ckt->CKTstat->STATsyncTime + - startkTime; + return(error); + } + if(new>.9 * ckt->CKTdelta) { + if(ckt->CKTorder == 1) { + new = ckt->CKTdelta; + ckt->CKTorder = 2; + error = CKTtrunc(ckt,&new); + if(error) { + ckt->CKTcurrentAnalysis = DOING_TRAN; + ckt->CKTstat->STATtranTime += + (*(SPfrontEnd->IFseconds))()-startTime; + ckt->CKTstat->STATtranIter += + ckt->CKTstat->STATnumIter - startIters; + ckt->CKTstat->STATtranDecompTime += + ckt->CKTstat->STATdecompTime - startdTime; + ckt->CKTstat->STATtranSolveTime += + ckt->CKTstat->STATsolveTime - startsTime; + ckt->CKTstat->STATtranLoadTime += + ckt->CKTstat->STATloadTime - startlTime; + ckt->CKTstat->STATtranCombTime += + ckt->CKTstat->STATcombineTime - startcTime; + ckt->CKTstat->STATtranSyncTime += + ckt->CKTstat->STATsyncTime - startkTime; + return(error); + } + if(new <= 1.05 * ckt->CKTdelta) { + ckt->CKTorder = 1; + } + } + /* time point OK - 630*/ + ckt->CKTdelta = new; +#ifdef STEPDEBUG + (void)printf( + "delta set to truncation error result: %g. Point accepted\n", + ckt->CKTdelta); + fflush(stdout); +#endif +#ifdef WANT_SENSE2 + if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){ + save1 = ckt->CKTmode; + save2 = ckt->CKTorder; + ckt->CKTmode = save_mode; + ckt->CKTorder = save_order; + if(error = CKTsenDCtran(ckt)) return(error); + ckt->CKTmode = save1; + ckt->CKTorder = save2; + } +#endif +#ifndef CLUSTER + /* go to 650 - trapezoidal */ + goto nextTime; +#else + redostep = 0; + goto chkStep; +#endif + } else { +#ifndef CLUSTER + ckt->CKTtime = ckt->CKTtime -ckt->CKTdelta; + ckt->CKTstat->STATrejected ++; +#endif + ckt->CKTdelta = new; +#ifdef STEPDEBUG + (void)printf( + "delta set to truncation error result:point rejected\n"); +#endif + } + } +#ifdef PARALLEL_ARCH + DGOP_( &type, &(ckt->CKTdelta), &length, "min" ); +#endif /* PARALLEL_ARCH */ + + if (ckt->CKTdelta <= ckt->CKTdelmin) { + if (olddelta > ckt->CKTdelmin) { + ckt->CKTdelta = ckt->CKTdelmin; +#ifdef STEPDEBUG + (void)printf("delta at delmin\n"); +#endif + } else { + ckt->CKTcurrentAnalysis = DOING_TRAN; + ckt->CKTstat->STATtranTime += + (*(SPfrontEnd->IFseconds))()-startTime; + ckt->CKTstat->STATtranIter += + ckt->CKTstat->STATnumIter - startIters; + ckt->CKTstat->STATtranDecompTime += + ckt->CKTstat->STATdecompTime - startdTime; + ckt->CKTstat->STATtranSolveTime += + ckt->CKTstat->STATsolveTime - startsTime; + ckt->CKTstat->STATtranLoadTime += + ckt->CKTstat->STATloadTime - startlTime; + ckt->CKTstat->STATtranCombTime += + ckt->CKTstat->STATcombineTime - startcTime; + ckt->CKTstat->STATtranSyncTime += + ckt->CKTstat->STATsyncTime - startkTime; + errMsg = CKTtrouble((void *) ckt, "Timestep too small"); + return(E_TIMESTEP); + } + } +#ifdef XSPICE +/* gtri - begin - wbk - Do event backup */ + + if(ckt->evt->counts.num_insts > 0) + EVTbackup(ckt, ckt->CKTtime + ckt->CKTdelta); + +/* gtri - end - wbk - Do event backup */ +#endif +#ifdef CLUSTER + chkStep: + if(CLUsync(ckt->CKTtime,&ckt->CKTdelta,redostep)){ + goto nextTime; + } else { + ckt->CKTtime -= olddelta; + ckt->CKTstat->STATrejected ++; + } +#endif + } + /* NOTREACHED */ +} diff --git a/src/spicelib/analysis/dctrcurv.c b/src/spicelib/analysis/dctrcurv.c new file mode 100644 index 000000000..cbc92dc3b --- /dev/null +++ b/src/spicelib/analysis/dctrcurv.c @@ -0,0 +1,411 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: 1999 Paolo Nenzi +**********/ + +#include "ngspice.h" +#include + +#include "vsrc/vsrcdefs.h" +#include "isrc/isrcdefs.h" +#include "res/resdefs.h" + +#include "cktdefs.h" +#include "const.h" +#include "sperror.h" + +#include +extern SPICEdev **DEVices; + +int +DCtrCurv(CKTcircuit *ckt, int restart) + + /* forced restart flag */ +{ + TRCV* cv = (TRCV*)ckt->CKTcurJob; /* Where we get the job to do */ + int i; + double *temp; + int converged; + int rcode; + int vcode; + int icode; + int j; + int error; + IFuid varUid; + IFuid *nameList; + int numNames; + int firstTime=1; + static void *plot=NULL; + +#ifdef WANT_SENSE2 +#ifdef SENSDEBUG + if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&DCSEN) ){ + printf("\nDC Sensitivity Results\n\n"); + CKTsenPrint(ckt); + } +#endif /* SENSDEBUG */ +#endif + + + rcode = CKTtypelook("Resistor"); + vcode = CKTtypelook("Vsource"); + icode = CKTtypelook("Isource"); + if(!restart && cv->TRCVnestState >= 0) { + /* continuing */ + i = cv->TRCVnestState; + /* resume to work? saj*/ + error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob, ckt->CKTcurJob->JOBname, + varUid,IF_REAL,666,nameList, 666,&plot); + goto resume; + } + ckt->CKTtime = 0; + ckt->CKTdelta = cv->TRCVvStep[0]; + ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCTRANCURVE | MODEINITJCT ; + ckt->CKTorder=1; + + + /* Save the state of the circuit */ + for(i=0;i<7;i++) { + ckt->CKTdeltaOld[i]=ckt->CKTdelta; + } + + for(i=0;i<=cv->TRCVnestLevel;i++) { + if(rcode >= 0) { + /* resistances are in this version, so use them */ + RESinstance *here; + RESmodel *model; + + for(model = (RESmodel *)ckt->CKThead[rcode];model != NULL; + model=model->RESnextModel){ + for(here=model->RESinstances;here!=NULL; + here=here->RESnextInstance) { + if(here->RESname == cv->TRCVvName[i]) { + cv->TRCVvElt[i] = (GENinstance *)here; + cv->TRCVvSave[i] = here->RESresist; + cv->TRCVgSave[i] = here->RESresGiven; + cv->TRCVvType[i] = rcode; + here->RESresist = cv->TRCVvStart[i]; + here->RESresGiven = 1; + printf("** Resistor sweep is highly alpha code\n**Results may not be accurate.\n"); + goto found; + } + } + } + } + if(vcode >= 0) { + /* voltage sources are in this version, so use them */ + VSRCinstance *here; + VSRCmodel *model; + + for(model = (VSRCmodel *)ckt->CKThead[vcode];model != NULL; + model=model->VSRCnextModel){ + for(here=model->VSRCinstances;here!=NULL; + here=here->VSRCnextInstance) { + if(here->VSRCname == cv->TRCVvName[i]) { + cv->TRCVvElt[i] = (GENinstance *)here; + cv->TRCVvSave[i] = here->VSRCdcValue; + cv->TRCVgSave[i] = here->VSRCdcGiven; + cv->TRCVvType[i] = vcode; + here->VSRCdcValue = cv->TRCVvStart[i]; + here->VSRCdcGiven = 1; + goto found; + } + } + } + } + if(icode >= 0 ) { + /* current sources are in this version, so use them */ + ISRCinstance *here; + ISRCmodel *model; + + for(model= (ISRCmodel *)ckt->CKThead[icode];model != NULL; + model=model->ISRCnextModel){ + for(here=model->ISRCinstances;here!=NULL; + here=here->ISRCnextInstance) { + if(here->ISRCname == cv->TRCVvName[i]) { + cv->TRCVvElt[i] = (GENinstance *)here; + cv->TRCVvSave[i] = here->ISRCdcValue; + cv->TRCVgSave[i] = here->ISRCdcGiven; + cv->TRCVvType[i] = icode; + here->ISRCdcValue = cv->TRCVvStart[i]; + here->ISRCdcGiven = 1; + goto found; + } + } + } + } + + if(!strcmp(cv->TRCVvName[i], "temp")) + { + cv->TRCVvSave[i]=ckt->CKTtemp; /* Saves the old circuit temperature */ + cv->TRCVvType[i]=TEMP_CODE; /* Set the sweep type code */ + ckt->CKTtemp = cv->TRCVvStart[i] + CONSTCtoK; /* Set the new circuit temp */ + printf("Temperature sweep is alpha code\nresults may not be accurate\n"); + goto found; + } + + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "DCtrCurv: source / resistor %s not in circuit", &(cv->TRCVvName[i])); + return(E_NODEV); + +found:; + } + + i--; /* PN: This seems to do nothing ??? */ + + error = CKTnames(ckt,&numNames,&nameList); + if(error) return(error); + + if (cv->TRCVvType[i]==vcode) + (*(SPfrontEnd->IFnewUid))((void *)ckt,&varUid,(IFuid )NULL, + "v-sweep", UID_OTHER, (void **)NULL); + else if (cv->TRCVvType[i]==icode) + (*(SPfrontEnd->IFnewUid))((void *)ckt,&varUid,(IFuid )NULL, + "i-sweep", UID_OTHER, (void **)NULL); + else if (cv->TRCVvType[i]==TEMP_CODE) + (*(SPfrontEnd->IFnewUid))((void *)ckt,&varUid,(IFuid )NULL, + "temp-sweep", UID_OTHER, (void **)NULL); + /* PN Resistance Sweep */ + else if (cv->TRCVvType[i]==rcode) + (*(SPfrontEnd->IFnewUid))((void *)ckt,&varUid,(IFuid )NULL, + "res-sweep", UID_OTHER, (void **)NULL); + else + (*(SPfrontEnd->IFnewUid))((void *)ckt,&varUid,(IFuid )NULL, + "?-sweep", UID_OTHER, (void **)NULL); + + error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob, ckt->CKTcurJob->JOBname, + varUid,IF_REAL,numNames,nameList, IF_REAL,&plot); + + if(error) return(error); + /* now have finished the initialization - can start doing hard part */ + + i = 0; + +resume: + + for(;;) { + + if(cv->TRCVvType[i]==vcode) { /* voltage source */ + if((((VSRCinstance*)(cv->TRCVvElt[i]))->VSRCdcValue)* + SIGN(1.,cv->TRCVvStep[i]) - + SIGN(1.,cv->TRCVvStep[i]) * cv->TRCVvStop[i] > + 0.5 * fabs(cv->TRCVvStep[i])) + { + i++ ; + firstTime=1; + ckt->CKTmode = (ckt->CKTmode & MODEUIC) | + MODEDCTRANCURVE | MODEINITJCT ; + if (i > cv->TRCVnestLevel ) break ; + goto nextstep; + } + } else if(cv->TRCVvType[i]==icode) { /* current source */ + if((((ISRCinstance*)(cv->TRCVvElt[i]))->ISRCdcValue)* + SIGN(1.,cv->TRCVvStep[i]) - + SIGN(1.,cv->TRCVvStep[i]) * cv->TRCVvStop[i] > + 0.5 * fabs(cv->TRCVvStep[i])) + { + i++ ; + firstTime=1; + ckt->CKTmode = (ckt->CKTmode & MODEUIC) | + MODEDCTRANCURVE | MODEINITJCT ; + if (i > cv->TRCVnestLevel ) break ; + goto nextstep; + } + + } else if(cv->TRCVvType[i]==rcode) { /* resistance */ + if((((RESinstance*)(cv->TRCVvElt[i]))->RESresist)* + SIGN(1.,cv->TRCVvStep[i]) - + SIGN(1.,cv->TRCVvStep[i]) * cv->TRCVvStop[i] > + 0.5 * fabs(cv->TRCVvStep[i])) + { + i++ ; + firstTime=1; + ckt->CKTmode = (ckt->CKTmode & MODEUIC) | + MODEDCTRANCURVE | MODEINITJCT ; + if (i > cv->TRCVnestLevel ) break ; + goto nextstep; + } + } else if(cv->TRCVvType[i]==TEMP_CODE) { /* temp sweep */ + if(((ckt->CKTtemp) - CONSTCtoK) * SIGN(1.,cv->TRCVvStep[i]) - + SIGN(1.,cv->TRCVvStep[i]) * cv->TRCVvStop[i] > + 0.5 * fabs(cv->TRCVvStep[i])) + { + i++ ; + firstTime=1; + ckt->CKTmode = (ckt->CKTmode & MODEUIC) | + MODEDCTRANCURVE | MODEINITJCT ; + if (i > cv->TRCVnestLevel ) break ; + goto nextstep; + + } + + } /* else not possible */ + while (i > 0) { + /* init(i); */ + i--; + if(cv->TRCVvType[i]==vcode) { /* voltage source */ + ((VSRCinstance *)(cv->TRCVvElt[i]))->VSRCdcValue = + cv->TRCVvStart[i]; + + } else if(cv->TRCVvType[i]==icode) { /* current source */ + ((ISRCinstance *)(cv->TRCVvElt[i]))->ISRCdcValue = + cv->TRCVvStart[i]; + + } else if(cv->TRCVvType[i]==TEMP_CODE) { + ckt->CKTtemp = cv->TRCVvStart[i] + CONSTCtoK; + CKTtemp(ckt); + + } else if(cv->TRCVvType[i]==rcode) { + ((RESinstance *)(cv->TRCVvElt[i]))->RESresist = + cv->TRCVvStart[i]; + ((RESinstance *)(cv->TRCVvElt[i]))->RESconduct = + 1/(((RESinstance *)(cv->TRCVvElt[i]))->RESresist); + /* Note: changing the resistance does nothing */ + /* changing the conductance 1/r instead */ + DEVices[rcode]->DEVload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt); + + + } /* else not possible */ + } + + /* Rotate state vectors. */ + temp = ckt->CKTstates[ckt->CKTmaxOrder+1]; + for(j=ckt->CKTmaxOrder;j>=0;j--) { + ckt->CKTstates[j+1] = ckt->CKTstates[j]; + } + ckt->CKTstate0 = temp; + + /* do operation */ + converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter); + if(converged != 0) { + converged = CKTop(ckt, + (ckt->CKTmode&MODEUIC)|MODEDCTRANCURVE | MODEINITJCT, + (ckt->CKTmode&MODEUIC)|MODEDCTRANCURVE | MODEINITFLOAT, + ckt->CKTdcMaxIter); + if(converged != 0) { + return(converged); + } + } + ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODEDCTRANCURVE | MODEINITPRED ; + if(cv->TRCVvType[0] == vcode) { + ckt->CKTtime = ((VSRCinstance *)(cv->TRCVvElt[i])) + ->VSRCdcValue ; + } else if(cv->TRCVvType[0] == icode) { + ckt->CKTtime = ((ISRCinstance *)(cv->TRCVvElt[i])) + ->ISRCdcValue ; + } else if(cv->TRCVvType[0] == rcode) { + ckt->CKTtime = ((RESinstance *)(cv->TRCVvElt[i])) + ->RESresist; + } + /* PN Temp sweep */ + else + { + ckt->CKTtime = ckt->CKTtemp - CONSTCtoK ; + } +#ifdef WANT_SENSE2 +/* + if(!ckt->CKTsenInfo) printf("sensitivity structure does not exist\n"); + */ + if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&DCSEN) ){ + int senmode; + +#ifdef SENSDEBUG + if(cv->TRCVvType[i]==vcode) { /* voltage source */ + printf("Voltage Source Value : %.5e V\n", + ((VSRCinstance*) (cv->TRCVvElt[i]))->VSRCdcValue); + } + if(cv->TRCVvType[i]==icode) { /* current source */ + printf("Current Source Value : %.5e A\n", + ((ISRCinstance*)(cv->TRCVvElt[i]))->ISRCdcValue); + } + if(cv->TRCVvType[i]==rcode) { /* resistance */ + printf("Current Resistance Value : %.5e Ohm\n", + ((RESinstance*)(cv->TRCVvElt[i]->GENmodPtr))->RESresist); + } + if(cv->TRCVvType[i]==TEMP_CODE) { /* Temperature */ + printf("Current Circuit Temperature : %.5e C\n", + ckt-CKTtime - CONSTCtoK); + } + +#endif /* SENSDEBUG */ + + senmode = ckt->CKTsenInfo->SENmode; + save = ckt->CKTmode; + ckt->CKTsenInfo->SENmode = DCSEN; + if(error = CKTsenDCtran(ckt)) return (error); + ckt->CKTmode = save; + ckt->CKTsenInfo->SENmode = senmode; + + } +#endif + + + CKTdump(ckt,ckt->CKTtime,plot); + if(firstTime) { + firstTime=0; + bcopy((char *)ckt->CKTstate0,(char *)ckt->CKTstate1, + ckt->CKTnumStates*sizeof(double)); + } + +nextstep:; + if(cv->TRCVvType[i]==vcode) { /* voltage source */ + ((VSRCinstance*)(cv->TRCVvElt[i]))->VSRCdcValue += + cv->TRCVvStep[i]; + } else if(cv->TRCVvType[i]==icode) { /* current source */ + ((ISRCinstance*)(cv->TRCVvElt[i]))->ISRCdcValue += + cv->TRCVvStep[i]; + } else if(cv->TRCVvType[i]==rcode) { /* resistance */ + ((RESinstance*)(cv->TRCVvElt[i]))->RESresist += + cv->TRCVvStep[i]; + /* This code should update resistance and conductance */ + ((RESinstance*)(cv->TRCVvElt[i]))->RESconduct = + 1/(((RESinstance*)(cv->TRCVvElt[i]))->RESresist); + DEVices[rcode]->DEVload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt); + } + /* PN Temp Sweep - serban */ + else if (cv->TRCVvType[i]==TEMP_CODE) + { + ckt->CKTtemp += cv->TRCVvStep[i]; + CKTtemp(ckt); + } /* else not possible */ + + if( (*(SPfrontEnd->IFpauseTest))() ) { + /* user asked us to pause, so save state */ + cv->TRCVnestState = i; + return(E_PAUSE); + } + } + + /* all done, lets put everything back */ + + for(i=0;i<=cv->TRCVnestLevel;i++) { + if(cv->TRCVvType[i] == vcode) { /* voltage source */ + ((VSRCinstance*)(cv->TRCVvElt[i]))->VSRCdcValue = + cv->TRCVvSave[i]; + ((VSRCinstance*)(cv->TRCVvElt[i]))->VSRCdcGiven = cv->TRCVgSave[i]; + } else if(cv->TRCVvType[i] == icode) /*current source */ { + ((ISRCinstance*)(cv->TRCVvElt[i]))->ISRCdcValue = + cv->TRCVvSave[i]; + ((ISRCinstance*)(cv->TRCVvElt[i]))->ISRCdcGiven = cv->TRCVgSave[i]; + } else if(cv->TRCVvType[i] == rcode) /* Resistance */ { + ((RESinstance*)(cv->TRCVvElt[i]))->RESresist = + cv->TRCVvSave[i]; + /* We restore both resistance and conductance */ + ((RESinstance*)(cv->TRCVvElt[i]))->RESconduct = + 1/(((RESinstance*)(cv->TRCVvElt[i]))->RESresist); + + ((RESinstance*)(cv->TRCVvElt[i]))->RESresGiven = cv->TRCVgSave[i]; + DEVices[rcode]->DEVload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt); + } + else if(cv->TRCVvType[i] == TEMP_CODE) { + ckt->CKTtemp = cv->TRCVvSave[i]; + CKTtemp(ckt); + } /* else not possible */ + } + (*(SPfrontEnd->OUTendPlot))(plot); + + return(OK); +} diff --git a/src/spicelib/analysis/dctsetp.c b/src/spicelib/analysis/dctsetp.c new file mode 100644 index 000000000..a596e9445 --- /dev/null +++ b/src/spicelib/analysis/dctsetp.c @@ -0,0 +1,117 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "trcvdefs.h" +#include "cktdefs.h" + +#include "analysis.h" + +/* ARGSUSED */ +int +DCTsetParm(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + TRCV* cv= (TRCV*)anal; + switch(which) { + + case DCT_START1: + cv->TRCVvStart[0] = value->rValue; + cv->TRCVnestLevel = MAX(0,cv->TRCVnestLevel); + cv->TRCVset[0]=TRUE; + break; + + case DCT_STOP1: + cv->TRCVvStop[0] = value->rValue; + cv->TRCVnestLevel = MAX(0,cv->TRCVnestLevel); + cv->TRCVset[0]=TRUE; + break; + + case DCT_STEP1: + cv->TRCVvStep[0] = value->rValue; + cv->TRCVnestLevel = MAX(0,cv->TRCVnestLevel); + cv->TRCVset[0]=TRUE; + break; + + case DCT_START2: + cv->TRCVvStart[1] = value->rValue; + cv->TRCVnestLevel = MAX(1,cv->TRCVnestLevel); + cv->TRCVset[1]=TRUE; + break; + + case DCT_STOP2: + cv->TRCVvStop[1] = value->rValue; + cv->TRCVnestLevel = MAX(1,cv->TRCVnestLevel); + cv->TRCVset[1]=TRUE; + break; + + case DCT_STEP2: + cv->TRCVvStep[1] = value->rValue; + cv->TRCVnestLevel = MAX(1,cv->TRCVnestLevel); + cv->TRCVset[1]=TRUE; + break; + + case DCT_NAME1: + cv->TRCVvName[0] = value->uValue; + cv->TRCVnestLevel = MAX(0,cv->TRCVnestLevel); + cv->TRCVset[0]=TRUE; + break; + + case DCT_NAME2: + cv->TRCVvName[1] = value->uValue; + cv->TRCVnestLevel = MAX(1,cv->TRCVnestLevel); + cv->TRCVset[1]=TRUE; + break; + + case DCT_TYPE1: + cv->TRCVvType[0] = value->iValue; + cv->TRCVnestLevel = MAX(0,cv->TRCVnestLevel); + cv->TRCVset[0]=TRUE; + break; + + case DCT_TYPE2: + cv->TRCVvType[1] = value->iValue; + cv->TRCVnestLevel = MAX(1,cv->TRCVnestLevel); + cv->TRCVset[1]=TRUE; + break; + + default: + return(E_BADPARM); + } + return(OK); +} + + +static IFparm DCTparms[] = { + { "start1", DCT_START1, IF_SET|IF_REAL, "starting voltage/current"}, + { "stop1", DCT_STOP1, IF_SET|IF_REAL, "ending voltage/current" }, + { "step1", DCT_STEP1, IF_SET|IF_REAL, "voltage/current step" }, + { "start2", DCT_START2, IF_SET|IF_REAL, "starting voltage/current"}, + { "stop2", DCT_STOP2, IF_SET|IF_REAL, "ending voltage/current" }, + { "step2", DCT_STEP2, IF_SET|IF_REAL, "voltage/current step" }, + { "name1", DCT_NAME1, IF_SET|IF_INSTANCE, "name of source to step" }, + { "name2", DCT_NAME2, IF_SET|IF_INSTANCE, "name of source to step" }, + { "type1", DCT_TYPE1, IF_SET|IF_INTEGER, "type of source to step" }, + { "type2", DCT_TYPE2, IF_SET|IF_INTEGER, "type of source to step" } +}; + +SPICEanalysis DCTinfo = { + { + "DC", + "D.C. Transfer curve analysis", + + sizeof(DCTparms)/sizeof(IFparm), + DCTparms + }, + sizeof(TRCV), + SWEEPDOMAIN, + 1, + DCTsetParm, + DCTaskQuest, + NULL, + DCtrCurv +}; diff --git a/src/spicelib/analysis/distoan.c b/src/spicelib/analysis/distoan.c new file mode 100644 index 000000000..a14b015b9 --- /dev/null +++ b/src/spicelib/analysis/distoan.c @@ -0,0 +1,674 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Jaijeet S Roychowdhury +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "distodef.h" +#include "sperror.h" + + +void +DISswap(double **a, double **b) +{ +double *c; + +c = *a; +*a = *b; +*b = c; +} + +void +DmemAlloc(double **a, int size) +{ +*a = (double *) MALLOC( sizeof(double) * size + 1); +} + + + +void +DstorAlloc(double ***header, int size) +{ +*header = (double **) MALLOC( sizeof(double *)*size); +} + + +#ifdef STDC +extern int CKTdisto(CKTcircuit*, int); +extern int DkerProc(int,double*,double*,int,DISTOan*); +#else +extern int CKTdisto(CKTcircuit *ckt, int mode); +extern int DkerProc(int type, double *rPtr, double *iPtr, int size, DISTOAN *job); +#endif + + +int +DISTOan(CKTcircuit *ckt, int restart) +{ + + double freq; + static double freqTol; /* tolerence parameter for finding final frequency */ + static int NoOfPoints; + static int size; + static int displacement; + int error; + int i; + int numNames; + IFuid *nameList; + IFuid freqUid; + void *acPlot=NULL; + DISTOAN* job = (DISTOAN *) (ckt->CKTcurJob); + static char *nof2src = "No source with f2 distortion input"; +#ifdef DISTODEBUG + double time,time1; +#endif + + + /* start at beginning */ + +#ifdef D_DBG_BLOCKTIMES +time1 = (*(SPfrontEnd->IFseconds))(); +#endif + switch(job->DstepType) { + + case DECADE: + job->DfreqDelta = + exp(log(10.0)/job->DnumSteps); + freqTol = job->DfreqDelta * + job->DstopF1 * ckt->CKTreltol; + NoOfPoints = 1 + floor ((job->DnumSteps) / log(10.0) * log((job->DstopF1+freqTol)/(job->DstartF1))); + break; + case OCTAVE: + job->DfreqDelta = + exp(log(2.0)/job->DnumSteps); + freqTol = job->DfreqDelta * + job->DstopF1 * ckt->CKTreltol; + NoOfPoints = 1 + floor ((job->DnumSteps) / log(2.0) * log((job->DstopF1+freqTol)/(job->DstartF1))); + break; + case LINEAR: + job->DfreqDelta = + (job->DstopF1 - + job->DstartF1)/ + (job->DnumSteps+1); + freqTol = job->DfreqDelta * ckt->CKTreltol; + NoOfPoints = job->DnumSteps+1+ floor(freqTol/(job->DfreqDelta)); + break; + default: + return(E_BADPARM); + } + + error = CKTop(ckt, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, + ckt->CKTdcMaxIter); + if(error) return(error); + + ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG; + error = CKTload(ckt); + if(error) return(error); + + error = CKTnames(ckt,&numNames,&nameList); + if(error) return(error); + + if (ckt->CKTkeepOpInfo) { + /* Dump operating point. */ + error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob, "Distortion Operating Point", + (IFuid)NULL,IF_REAL,numNames,nameList, IF_REAL,&acPlot); + if(error) return(error); + CKTdump(ckt,(double)0,acPlot); + (*(SPfrontEnd->OUTendPlot))(acPlot); + acPlot = NULL; + } + +#ifdef D_DBG_BLOCKTIMES +time1 = (*(SPfrontEnd->IFseconds))() - time1; +printf("Time for initial work (including op. pt.): %g seconds \n", time1); +#endif + +#ifdef D_DBG_BLOCKTIMES +time1 = (*(SPfrontEnd->IFseconds))(); +#endif + error = CKTdisto(ckt,D_SETUP); +#ifdef D_DBG_BLOCKTIMES +time1 = (*(SPfrontEnd->IFseconds))() - time1; +printf("Time outside D_SETUP: %g seconds \n", time1); +#endif + if (error) return(error); + + displacement = 0; + +#ifdef D_DBG_BLOCKTIMES +time1 = (*(SPfrontEnd->IFseconds))(); +#endif + freq = job->DstartF1; + if (job->Df2wanted) { + /* + omegadelta = 2.0 * M_PI * freq *(1. - job->Df2ovrF1); + */ + /* keeping f2 const to be compatible with spectre */ + job->Domega2 = 2.0 * M_PI * freq * job->Df2ovrF1; + } + DstorAlloc( &(job->r1H1stor),NoOfPoints+2); + DstorAlloc( &(job->r2H11stor),NoOfPoints+2); + DstorAlloc( &(job->i1H1stor),NoOfPoints+2); + DstorAlloc( &(job->i2H11stor),NoOfPoints+2); + size = SMPmatSize(ckt->CKTmatrix); + if (! job->r1H1ptr) + { + DmemAlloc( &(job->r1H1ptr) , size+2); + if (! job->r1H1ptr) return (E_NOMEM); + } + + if (! job->r2H11ptr) + { + DmemAlloc( &(job->r2H11ptr) , size+2); + if (! job->r2H11ptr) return (E_NOMEM); + } + if (! job->i1H1ptr) + { + DmemAlloc( &(job->i1H1ptr) , size+2); + if (! job->i1H1ptr) return (E_NOMEM); + } + + if (! job->i2H11ptr) + { + DmemAlloc( &(job->i2H11ptr) , size+2); + if (! job->i2H11ptr) return (E_NOMEM); + } + + if (! (job->Df2wanted)) + { + DstorAlloc( &(job->r3H11stor),NoOfPoints+2); + DstorAlloc( &(job->i3H11stor),NoOfPoints+2); + if (! job->r3H11ptr) + { + DmemAlloc( &(job->r3H11ptr) , size+2); + if (! job->r3H11ptr) return (E_NOMEM); + } + if (! job->i3H11ptr) + { + DmemAlloc( &(job->i3H11ptr) , size+2); + if (! job->i3H11ptr) return (E_NOMEM); + } + } else { + DstorAlloc ( &(job->r1H2stor),NoOfPoints+2); + DstorAlloc ( &(job->i1H2stor),NoOfPoints+2); + DstorAlloc ( &(job->r2H12stor),NoOfPoints+2); + DstorAlloc ( &(job->i2H12stor),NoOfPoints+2); + DstorAlloc ( &(job->r2H1m2stor),NoOfPoints+2); + DstorAlloc ( &(job->i2H1m2stor),NoOfPoints+2); + DstorAlloc ( &(job->r3H1m2stor),NoOfPoints+2); + DstorAlloc ( &(job->i3H1m2stor),NoOfPoints+2); + if (! job->r1H2ptr) + { + DmemAlloc( &(job->r1H2ptr) , size+2); + if (! job->r1H2ptr) return (E_NOMEM); + } + + if (! job->r2H12ptr) + { + DmemAlloc( &(job->r2H12ptr) , size+2); + if (! job->r2H12ptr) return (E_NOMEM); + } + + if (! job->r2H1m2ptr) + { + DmemAlloc( &(job->r2H1m2ptr) , size+2); + if (! job->r2H1m2ptr) return (E_NOMEM); + } + + if (! job->r3H1m2ptr) + { + DmemAlloc( &(job->r3H1m2ptr) , size+2); + if (! job->r3H1m2ptr) return (E_NOMEM); + } + if (! job->i1H2ptr) + { + DmemAlloc( &(job->i1H2ptr) , size+2); + if (! job->i1H2ptr) return (E_NOMEM); + } + + if (! job->i2H12ptr) + { + DmemAlloc( &(job->i2H12ptr) , size+2); + if (! job->i2H12ptr) return (E_NOMEM); + } + + if (! job->i2H1m2ptr) + { + DmemAlloc( &(job->i2H1m2ptr) , size+2); + if (! job->i2H1m2ptr) return (E_NOMEM); + } + + if (! job->i3H1m2ptr) + { + DmemAlloc( &(job->i3H1m2ptr) , size+2); + if (! job->i3H1m2ptr) return (E_NOMEM); + } +} + +#ifdef D_DBG_BLOCKTIMES +time1 = (*(SPfrontEnd->IFseconds))() - time1; +printf("Time for other setup (storage allocation etc.): %g seconds \n", time1); +#endif + + + +#ifdef D_DBG_BLOCKTIMES +time1 = (*(SPfrontEnd->IFseconds))(); +#endif + while(freq <= job->DstopF1+freqTol) { + +/* + if( (*(SPfrontEnd->IFpauseTest))() ) { + job->DsaveF1 = freq; + return(E_PAUSE); + } + */ + ckt->CKTomega = 2.0 * M_PI *freq; + job->Domega1 = ckt->CKTomega; + ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODEAC; +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + error = CKTacLoad(ckt); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time for CKTacLoad: %g seconds \n", time); +#endif + if (error) return(error); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + error = CKTdisto(ckt,D_RHSF1); /* sets up the RHS vector + for all inputs corresponding to F1 */ +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time outside DISTO_RHSFIX: %g seconds \n", time); +#endif + if (error) return(error); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + error = NIdIter(ckt); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time for NIdIter: %g seconds \n", time); +#endif + if (error) return(error); + DISswap(&(ckt->CKTrhsOld),&(job->r1H1ptr)); + DISswap(&(ckt->CKTirhsOld),&(job->i1H1ptr)); + + ckt->CKTomega *= 2; + error = CKTacLoad(ckt); + if (error) return(error); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + error = CKTdisto(ckt,D_TWOF1); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time outside D_TWOF1: %g seconds \n", time); +#endif + if (error) return(error); + error = NIdIter(ckt); + if (error) return(error); + DISswap(&(ckt->CKTrhsOld),&(job->r2H11ptr)); + DISswap(&(ckt->CKTirhsOld),&(job->i2H11ptr)); + + if (! (job->Df2wanted )) + { + + + ckt->CKTomega = 3 * job->Domega1; + error = CKTacLoad(ckt); + if (error) return(error); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + error = CKTdisto(ckt,D_THRF1); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time outside D_THRF1: %g seconds \n", time); +#endif + if (error) return(error); + error = NIdIter(ckt); + if (error) return(error); + DISswap(&(ckt->CKTrhsOld),&(job->r3H11ptr)); + DISswap(&(ckt->CKTirhsOld),&(job->i3H11ptr)); + + + } + else if (job->Df2given) + { + + + /* + ckt->CKTomega = job->Domega1 - omegadelta; + job->Domega2 = ckt->CKTomega; + */ + ckt->CKTomega = job->Domega2; + error = CKTacLoad(ckt); + if (error) return(error); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + error = CKTdisto(ckt,D_RHSF2); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time outside DISTO_RHSFIX: %g seconds \n", time); +#endif + if (error) return(error); + error = NIdIter(ckt); + if (error) return(error); + DISswap(&(ckt->CKTrhsOld),&(job->r1H2ptr)); + DISswap(&(ckt->CKTirhsOld),&(job->i1H2ptr)); + + + ckt->CKTomega = job->Domega1 + + job->Domega2; + error = CKTacLoad(ckt); + if (error) return(error); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + error = CKTdisto(ckt,D_F1PF2); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time outside D_F1PF2: %g seconds \n", time); +#endif + if (error) return(error); + error = NIdIter(ckt); + if (error) return(error); + DISswap(&(ckt->CKTrhsOld),&(job->r2H12ptr)); + DISswap(&(ckt->CKTirhsOld),&(job->i2H12ptr)); + + + + ckt->CKTomega = job->Domega1 - + job->Domega2; + error = CKTacLoad(ckt); + if (error) return(error); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + error = CKTdisto(ckt,D_F1MF2); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time outside D_F1MF2: %g seconds \n", time); +#endif + if (error) return(error); + error = NIdIter(ckt); + if (error) return(error); + DISswap(&(ckt->CKTrhsOld),&(job->r2H1m2ptr)); + DISswap(&(ckt->CKTirhsOld),&(job->i2H1m2ptr)); + + + ckt->CKTomega = 2*job->Domega1 - + job->Domega2; + error = CKTacLoad(ckt); + if (error) return(error); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + error = CKTdisto(ckt,D_2F1MF2); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time outside D_2F1MF2: %g seconds \n", time); +#endif + if (error) return(error); + error = NIdIter(ckt); + if (error) return(error); + DISswap(&(ckt->CKTrhsOld),&(job->r3H1m2ptr)); + DISswap(&(ckt->CKTirhsOld),&(job->i3H1m2ptr)); + + + } + else + { + errMsg = MALLOC(strlen(nof2src)+1); + strcpy(errMsg,nof2src); + return(E_NOF2SRC); + } + + + + + DmemAlloc( &(job->r1H1stor[displacement]),size); + DISswap(&(job->r1H1stor[displacement]),&(job->r1H1ptr)); + job->r1H1stor[displacement][0]=freq; + DmemAlloc( &(job->r2H11stor[displacement]),size); + DISswap(&(job->r2H11stor[displacement]),&((job->r2H11ptr))); + job->r2H11stor[displacement][0]=freq; + DmemAlloc( &(job->i1H1stor[displacement]),size); + DISswap(&(job->i1H1stor[displacement]),&((job->i1H1ptr))); + job->i1H1stor[displacement][0]=0.0; + DmemAlloc( &(job->i2H11stor[displacement]),size); + DISswap(&(job->i2H11stor[displacement]),&((job->i2H11ptr))); + job->i2H11stor[displacement][0]=0.0; + if (! (job->Df2wanted)) + { + DmemAlloc( &(job->r3H11stor[displacement]),size); + DISswap(&(job->r3H11stor[displacement]),&((job->r3H11ptr))); + job->r3H11stor[displacement][0]=freq; + DmemAlloc( &(job->i3H11stor[displacement]),size); + DISswap(&(job->i3H11stor[displacement]),&((job->i3H11ptr))); + job->i3H11stor[displacement][0]=0.0; + } else { + DmemAlloc( &(job->r1H2stor[displacement]),size); + DISswap(&(job->r1H2stor[displacement]),&((job->r1H2ptr))); + job->r1H2stor[displacement][0]=freq; + DmemAlloc( &(job->r2H12stor[displacement]),size); + DISswap(&(job->r2H12stor[displacement]),&((job->r2H12ptr))); + job->r2H12stor[displacement][0]=freq; + DmemAlloc( &(job->r2H1m2stor[displacement]),size); + DISswap(&(job->r2H1m2stor[displacement]),&((job->r2H1m2ptr))); + job->r2H1m2stor[displacement][0]=freq; + DmemAlloc( &(job->r3H1m2stor[displacement]),size); + DISswap(&(job->r3H1m2stor[displacement]),&((job->r3H1m2ptr))); + job->r3H1m2stor[displacement][0]=freq; + + DmemAlloc( &(job->i1H2stor[displacement]),size); + DISswap(&(job->i1H2stor[displacement]),&((job->i1H2ptr))); + job->i1H2stor[displacement][0]=0.0; + DmemAlloc( &(job->i2H12stor[displacement]),size); + DISswap(&(job->i2H12stor[displacement]),&((job->i2H12ptr))); + job->i2H12stor[displacement][0]=0.0; + DmemAlloc( &(job->i2H1m2stor[displacement]),size); + DISswap(&(job->i2H1m2stor[displacement]),&((job->i2H1m2ptr))); + job->i2H1m2stor[displacement][0]=0.0; + DmemAlloc( &(job->i3H1m2stor[displacement]),size); + DISswap(&(job->i3H1m2stor[displacement]),&((job->i3H1m2ptr))); + job->i3H1m2stor[displacement][0]=0.0; + } + displacement++; + + + + switch(job->DstepType) { + case DECADE: + case OCTAVE: + freq *= job->DfreqDelta; + if(job->DfreqDelta==1) goto endsweep; + break; + case LINEAR: + freq += job->DfreqDelta; + if(job->DfreqDelta==0) goto endsweep; + break; + default: + return(E_INTERN); + } + } +#ifdef D_DBG_BLOCKTIMES +time1 = (*(SPfrontEnd->IFseconds))() - time1; +printf("Time inside frequency loop: %g seconds \n", time1); +#endif + +endsweep: + + + /* output routines to process the H's and output actual ckt variable + values */ +#ifdef D_DBG_BLOCKTIMES +time1 = (*(SPfrontEnd->IFseconds))(); +#endif + + + + if (! job->Df2wanted) { + error = CKTnames(ckt,&numNames,&nameList); + if(error) return(error); + (*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL, + "frequency", UID_OTHER,(void **)NULL); + (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob,"DISTORTION - 2nd harmonic", + freqUid,IF_REAL, numNames,nameList,IF_COMPLEX,&acPlot); + if (job->DstepType != LINEAR) { + (*(SPfrontEnd->OUTattributes))((void *)acPlot,NULL, + OUT_SCALE_LOG, NULL); + } + for (i=0; i< displacement ; i++) + { + DkerProc(D_TWOF1,*(job->r2H11stor + i), + *(job->i2H11stor + i), + size, job); + ckt->CKTrhsOld = *((job->r2H11stor) + i); + ckt->CKTirhsOld = *((job->i2H11stor) + i); + error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot); + if(error) return(error); + } + (*(SPfrontEnd->OUTendPlot))(acPlot); + acPlot = NULL; + + error = CKTnames(ckt,&numNames,&nameList); + if(error) return(error); + (*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL, + "frequency", UID_OTHER,(void **)NULL); + (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob,"DISTORTION - 3rd harmonic",freqUid,IF_REAL, + numNames,nameList,IF_COMPLEX,&acPlot); + for (i=0; i< displacement ; i++) + { + DkerProc(D_THRF1,*(job->r3H11stor + i), + *(job->i3H11stor + i), + size, job); + ckt->CKTrhsOld = *((job->r3H11stor) + i); + ckt->CKTirhsOld = *((job->i3H11stor) + i); + error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot); + } + (*(SPfrontEnd->OUTendPlot))(acPlot); + acPlot = NULL; + + } else { + + + error = CKTnames(ckt,&numNames,&nameList); + if(error) return(error); + (*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL, + "frequency", UID_OTHER,(void **)NULL); + (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob,"DISTORTION - IM: f1+f2",freqUid,IF_REAL, + numNames,nameList,IF_COMPLEX,&acPlot); + for (i=0; i< displacement ; i++) + { + DkerProc(D_F1PF2,*(job->r2H12stor + i), + *(job->i2H12stor + i), + size, job); + ckt->CKTrhsOld = *((job->r2H12stor) + i); + ckt->CKTirhsOld = *((job->i2H12stor) + i); + error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot); + if(error) return(error); + } + (*(SPfrontEnd->OUTendPlot))(acPlot); + acPlot = NULL; + + error = CKTnames(ckt,&numNames,&nameList); + if(error) return(error); + (*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL, + "frequency", UID_OTHER,(void **)NULL); + (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob,"DISTORTION - IM: f1-f2",freqUid,IF_REAL, + numNames,nameList,IF_COMPLEX,&acPlot); + for (i=0; i< displacement ; i++) + { + DkerProc(D_F1MF2, + *(job->r2H1m2stor + i), + *(job->i2H1m2stor + i), + size, job); + ckt->CKTrhsOld = *((job->r2H1m2stor) + i); + ckt->CKTirhsOld = *((job->i2H1m2stor) + i); + error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot); + if(error) return(error); + } + (*(SPfrontEnd->OUTendPlot))(acPlot); + acPlot = NULL; + + error = CKTnames(ckt,&numNames,&nameList); + if(error) return(error); + (*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL, + "frequency", UID_OTHER,(void **)NULL); + (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob,"DISTORTION - IM: 2f1-f2",freqUid,IF_REAL, + numNames,nameList,IF_COMPLEX,&acPlot); + for (i=0; i< displacement ; i++) + { + DkerProc(D_2F1MF2, + *(job->r3H1m2stor + i), + *(job->i3H1m2stor + i), + size, job); + ckt->CKTrhsOld = *((job->r3H1m2stor) + i); + ckt->CKTirhsOld = *((job->i3H1m2stor) + i); + error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot); + if(error) return(error); + } + (*(SPfrontEnd->OUTendPlot))(acPlot); + acPlot = NULL; + + } +FREE(job->r1H1ptr); +FREE(job->i1H1ptr); +FREE(job->r2H11ptr); +FREE(job->i2H11ptr); + +FREE(job->r1H1stor); +FREE(job->i1H1stor); +FREE(job->r2H11stor); +FREE(job->i2H11stor); + + if (! (job->Df2wanted)) + { +FREE(job->r3H11ptr); +FREE(job->i3H11ptr); + +FREE(job->i3H11stor); +FREE(job->r3H11stor); +} +else { + +FREE(job->r2H1m2ptr); +FREE(job->r3H1m2ptr); +FREE(job->r1H2ptr); +FREE(job->i1H2ptr); +FREE(job->r2H12ptr); +FREE(job->i2H12ptr); +FREE(job->i2H1m2ptr); +FREE(job->i3H1m2ptr); + +FREE(job->r1H2stor); +FREE(job->r2H12stor); +FREE(job->r2H1m2stor); +FREE(job->r3H1m2stor); +FREE(job->i1H2stor); +FREE(job->i2H12stor); +FREE(job->i2H1m2stor); +FREE(job->i3H1m2stor); + } +#ifdef D_DBG_BLOCKTIMES +time1 = (*(SPfrontEnd->IFseconds))() - time1; +printf("Time for output and deallocation: %g seconds \n", time1); +#endif + return(OK); +} diff --git a/src/spicelib/analysis/dkerproc.c b/src/spicelib/analysis/dkerproc.c new file mode 100644 index 000000000..887769338 --- /dev/null +++ b/src/spicelib/analysis/dkerproc.c @@ -0,0 +1,102 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Jaijeet S Roychowdhury +**********/ + +#include "ngspice.h" +#include "cktdefs.h" +#include "sperror.h" +#include "distodef.h" + + +int +DkerProc(int type, double *rPtr, double *iPtr, int size, DISTOAN *job) +{ +int i; + +switch(type) { + + case D_F1: + + + for (i=1;i<=size;i++) + { + iPtr[i] *= 2.0; /* convert to sinusoid amplitude */ + rPtr[i] *= 2.0; + } + + break; + + case D_F2: + + + for (i=1;i<=size;i++) + { + rPtr[i] *= 2.0; + iPtr[i] *= 2.0; + } + + break; + + case D_TWOF1: + + + for (i=1;i<=size;i++) + { + iPtr[i] *= 2.0; + rPtr[i] *= 2.0; + } + + break; + + case D_THRF1: + + + for (i=1;i<=size;i++) + { + iPtr[i] *= 2.0; + rPtr[i] *= 2.0; + } + + break; + + case D_F1PF2: + + + for (i=1;i<=size;i++) + { + iPtr[i] *= 4.0; + rPtr[i] *= 4.0; + } + + break; + + case D_F1MF2: + + + for (i=1;i<=size;i++) + { + iPtr[i] *= 4.0; + rPtr[i] *= 4.0; + } + + break; + + case D_2F1MF2: + + for (i=1;i<=size;i++) + { + iPtr[i] *= 6.0; + rPtr[i] *= 6.0; + } + + break; + + default: + + return(E_BADPARM); + +} + +return(OK); +} diff --git a/src/spicelib/analysis/dloadfns.c b/src/spicelib/analysis/dloadfns.c new file mode 100644 index 000000000..e404a214d --- /dev/null +++ b/src/spicelib/analysis/dloadfns.c @@ -0,0 +1,673 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Jaijeet S Roychowdhury +**********/ + +#include "ngspice.h" +#include "distodef.h" + + +/* + * all subFns are local to this file so they need not be renamed to + * the awful 7 letter standard; however, for reasons of uniformity, + * they are being renamed, losing all readability in the process. + * the renaming convention is as follows: + * example: 3v3F1m2 + * 3v => 3 variable term xyz + * 2F1m2 => Two F1 minus F2 + * therefore the old name would be : S3v3F1minusF2 + * for the imaginary sub functions, the v is replaced by an i + * + */ +double +S2v2F1(double cxy, double r1h1x, double i1h1x, double r1h1y, double i1h1y) + + /* 5 arguments */ + +{ +return(cxy*(r1h1x*r1h1y - i1h1x*i1h1y)); +} + +double +S2i2F1(double cxy, double r1h1x, double i1h1x, double r1h1y, double i1h1y) + + /* 5 arguments */ + +{ +return(cxy*(r1h1x*i1h1y + i1h1x*r1h1y)); +} + +double +S2v3F1(double cxy, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r2h11x, double i2h11x, double r2h11y, double i2h11y) + + /* 9 arguments */ + + +{ +return(cxy*(r1h1x*r2h11y - i1h1x*i2h11y + r1h1y*r2h11x - i1h1y* + i2h11x)); +} + + +double +S2i3F1(double cxy, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r2h11x, double i2h11x, double r2h11y, double i2h11y) + + /* 9 arguments */ + + +{ +return(cxy*(r1h1x*i2h11y + i1h1x*r2h11y + r1h1y*i2h11x + i1h1y* + r2h11x)); +} + +double +S2vF12(double cxy, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h2x, double i1h2x, double r1h2y, double i1h2y) + + /* 9 arguments */ + + +{ +return(cxy*(r1h1x*r1h2y - i1h1x*i1h2y + r1h1y*r1h2x - i1h1y*i1h2x)); +} + +double +S2iF12(double cxy, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h2x, double i1h2x, double r1h2y, double i1h2y) + + /* 9 arguments */ + + +{ +return(cxy*(r1h1x*i1h2y + i1h1x*r1h2y + r1h1y*i1h2x + i1h1y*r1h2x)); +} + +double +S2v2F12(double cxy, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h2x, double i1h2x, double r1h2y, double i1h2y, double r2h11x, double i2h11x, double r2h11y, double i2h11y, double h2f1f2x, double ih2f1f2x, double h2f1f2y, double ih2f1f2y) + + /* 17 arguments */ + + + + +{ +return ( cxy * ( + 2*(r1h1x*h2f1f2y - i1h1x*ih2f1f2y + +r1h1y*h2f1f2x - i1h1y*ih2f1f2x) + + r1h2x*r2h11y - i1h2x*i2h11y + + r1h2y*r2h11x - i1h2y*i2h11x + )); +} + +double +S2i2F12(double cxy, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h2x, double i1h2x, double r1h2y, double i1h2y, double r2h11x, double i2h11x, double r2h11y, double i2h11y, double h2f1f2x, double ih2f1f2x, double h2f1f2y, double ih2f1f2y) + + /* 17 arguments */ + + + + +{ +return ( cxy * ( + 2*(r1h1x*ih2f1f2y + i1h1x*h2f1f2y + +r1h1y*ih2f1f2x + i1h1y*h2f1f2x) + + r1h2x*i2h11y + i1h2x*r2h11y + + r1h2y*i2h11x + i1h2y*r2h11x + )); +} + +double +S3v3F1(double cxyz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z) + + /* 7 arguments */ + + +{ +return( cxyz * ( + (r1h1x*r1h1y - i1h1x*i1h1y)*r1h1z - (i1h1x*r1h1y + r1h1x*i1h1y)*i1h1z + )); +} + +double +S3i3F1(double cxyz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z) + + /* 7 arguments */ + + +{ +return( cxyz * ( + (r1h1x*r1h1y - i1h1x*i1h1y)*i1h1z + (i1h1x*r1h1y + r1h1x*i1h1y)*r1h1z + )); +} + +double +S3v2F12(double cxyz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z, double r1h2x, double i1h2x, double r1h2y, double i1h2y, double r1h2z, double i1h2z) + + /* 13 arguments */ + + + +{ +return ( cxyz * ( + (r1h1x*r1h1y - i1h1x*i1h1y)*r1h2z - (i1h1x*r1h1y + r1h1x*i1h1y)*i1h2z + + + (r1h1x*r1h1z - i1h1x*i1h1z)*r1h2y - (i1h1x*r1h1z + r1h1x*i1h1z)*i1h2y + + + (r1h1z*r1h1y - i1h1z*i1h1y)*r1h2x - (i1h1z*r1h1y + r1h1z*i1h1y)*i1h2x + )); +} + +double +S3i2F12(double cxyz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z, double r1h2x, double i1h2x, double r1h2y, double i1h2y, double r1h2z, double i1h2z) + + /* 13 arguments */ + + + +{ +return ( cxyz * ( + (r1h1x*r1h1y - i1h1x*i1h1y)*i1h2z + (i1h1x*r1h1y + r1h1x*i1h1y)*r1h2z + + + (r1h1x*r1h1z - i1h1x*i1h1z)*i1h2y + (i1h1x*r1h1z + r1h1x*i1h1z)*r1h2y + + + (r1h1z*r1h1y - i1h1z*i1h1y)*i1h2x + (i1h1z*r1h1y + r1h1z*i1h1y)*r1h2x + )); +} + + /* the load functions */ + /* also renamed... */ +double +DFn2F1(double cxx, double cyy, double czz, double cxy, double cyz, double cxz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z) + + /* 12 variables */ + + +{ +double temp; + + temp = S2v2F1(cxx,r1h1x,i1h1x,r1h1x,i1h1x) + + S2v2F1(cyy,r1h1y,i1h1y,r1h1y,i1h1y) + + S2v2F1(czz,r1h1z,i1h1z,r1h1z,i1h1z) + + S2v2F1(cxy,r1h1x,i1h1x,r1h1y,i1h1y) + + S2v2F1(cyz,r1h1y,i1h1y,r1h1z,i1h1z) + + S2v2F1(cxz,r1h1x,i1h1x,r1h1z,i1h1z); + + return(temp); +} + +double +DFi2F1(double cxx, double cyy, double czz, double cxy, double cyz, double cxz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z) + + /* 12 variables */ + + +{ +double temp; + + temp = S2i2F1(cxx,r1h1x,i1h1x,r1h1x,i1h1x) + + S2i2F1(cyy,r1h1y,i1h1y,r1h1y,i1h1y) + + S2i2F1(czz,r1h1z,i1h1z,r1h1z,i1h1z) + + S2i2F1(cxy,r1h1x,i1h1x,r1h1y,i1h1y) + + S2i2F1(cyz,r1h1y,i1h1y,r1h1z,i1h1z) + + S2i2F1(cxz,r1h1x,i1h1x,r1h1z,i1h1z); + + return(temp); +} + +double +DFn3F1(double cxx, double cyy, double czz, double cxy, double cyz, double cxz, double cxxx, double cyyy, double czzz, double cxxy, double cxxz, double cxyy, double cyyz, double cxzz, double cyzz, double cxyz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z, double r2h11x, double i2h11x, double r2h11y, double i2h11y, double r2h11z, double i2h11z) + /* 28 args - 16 + 6 + 6 */ + + + +{ +double temp; + + temp = S2v3F1(cxx,r1h1x,i1h1x,r1h1x,i1h1x,r2h11x,i2h11x,r2h11x,i2h11x) + +S2v3F1(cyy,r1h1y,i1h1y,r1h1y,i1h1y,r2h11y,i2h11y,r2h11y,i2h11y) + +S2v3F1(czz,r1h1z,i1h1z,r1h1z,i1h1z,r2h11z,i2h11z,r2h11z,i2h11z); + temp += + S2v3F1(cxy,r1h1x,i1h1x,r1h1y,i1h1y,r2h11x,i2h11x,r2h11y,i2h11y) + +S2v3F1(cyz,r1h1y,i1h1y,r1h1z,i1h1z,r2h11y,i2h11y,r2h11z,i2h11z) + +S2v3F1(cxz,r1h1x,i1h1x,r1h1z,i1h1z,r2h11x,i2h11x,r2h11z,i2h11z) + +S3v3F1(cxxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h1x,i1h1x); + temp += + S3v3F1(cyyy,r1h1y,i1h1y,r1h1y,i1h1y,r1h1y,i1h1y) + +S3v3F1(czzz,r1h1z,i1h1z,r1h1z,i1h1z,r1h1z,i1h1z) + +S3v3F1(cxxy,r1h1x,i1h1x,r1h1x,i1h1x,r1h1y,i1h1y) + +S3v3F1(cxxz,r1h1x,i1h1x,r1h1x,i1h1x,r1h1z,i1h1z) + +S3v3F1(cxyy,r1h1x,i1h1x,r1h1y,i1h1y,r1h1y,i1h1y); + temp += + S3v3F1(cyyz,r1h1y,i1h1y,r1h1y,i1h1y,r1h1z,i1h1z) + +S3v3F1(cxzz,r1h1x,i1h1x,r1h1z,i1h1z,r1h1z,i1h1z) + +S3v3F1(cyzz,r1h1y,i1h1y,r1h1z,i1h1z,r1h1z,i1h1z) + +S3v3F1(cxyz,r1h1x,i1h1x,r1h1y,i1h1y,r1h1z,i1h1z); + + return(temp); +} + +double +DFi3F1(double cxx, double cyy, double czz, double cxy, double cyz, double cxz, double cxxx, double cyyy, double czzz, double cxxy, double cxxz, double cxyy, double cyyz, double cxzz, double cyzz, double cxyz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z, double r2h11x, double i2h11x, double r2h11y, double i2h11y, double r2h11z, double i2h11z) + /* 28 args - 10 + 6 + 6 */ + + + +{ +double temp; + + temp = S2i3F1(cxx,r1h1x,i1h1x,r1h1x,i1h1x,r2h11x,i2h11x,r2h11x,i2h11x) + +S2i3F1(cyy,r1h1y,i1h1y,r1h1y,i1h1y,r2h11y,i2h11y,r2h11y,i2h11y) + +S2i3F1(czz,r1h1z,i1h1z,r1h1z,i1h1z,r2h11z,i2h11z,r2h11z,i2h11z) + +S2i3F1(cxy,r1h1x,i1h1x,r1h1y,i1h1y,r2h11x,i2h11x,r2h11y,i2h11y); + temp += + S2i3F1(cyz,r1h1y,i1h1y,r1h1z,i1h1z,r2h11y,i2h11y,r2h11z,i2h11z) + +S2i3F1(cxz,r1h1x,i1h1x,r1h1z,i1h1z,r2h11x,i2h11x,r2h11z,i2h11z) + +S3i3F1(cxxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h1x,i1h1x) + +S3i3F1(cyyy,r1h1y,i1h1y,r1h1y,i1h1y,r1h1y,i1h1y); + temp += + S3i3F1(czzz,r1h1z,i1h1z,r1h1z,i1h1z,r1h1z,i1h1z) + +S3i3F1(cxxy,r1h1x,i1h1x,r1h1x,i1h1x,r1h1y,i1h1y) + +S3i3F1(cxxz,r1h1x,i1h1x,r1h1x,i1h1x,r1h1z,i1h1z) + +S3i3F1(cxyy,r1h1x,i1h1x,r1h1y,i1h1y,r1h1y,i1h1y); + temp += + S3i3F1(cyyz,r1h1y,i1h1y,r1h1y,i1h1y,r1h1z,i1h1z) + +S3i3F1(cxzz,r1h1x,i1h1x,r1h1z,i1h1z,r1h1z,i1h1z) + +S3i3F1(cyzz,r1h1y,i1h1y,r1h1z,i1h1z,r1h1z,i1h1z) + +S3i3F1(cxyz,r1h1x,i1h1x,r1h1y,i1h1y,r1h1z,i1h1z); + + return(temp); +} + +double +DFnF12(double cxx, double cyy, double czz, double cxy, double cyz, double cxz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z, double r1h2x, double i1h2x, double r1h2y, double i1h2y, double r1h2z, double i1h2z) + + /* 18 args - 6 + 6 + 6 */ + + + +{ +double temp; + + temp = S2vF12(cxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h2x,i1h2x,r1h2x,i1h2x) + +S2vF12(cyy,r1h1y,i1h1y,r1h1y,i1h1y,r1h2y,i1h2y,r1h2y,i1h2y) + +S2vF12(czz,r1h1z,i1h1z,r1h1z,i1h1z,r1h2z,i1h2z,r1h2z,i1h2z); + temp += + S2vF12(cxy,r1h1x,i1h1x,r1h1y,i1h1y,r1h2x,i1h2x,r1h2y,i1h2y) + +S2vF12(cyz,r1h1y,i1h1y,r1h1z,i1h1z,r1h2y,i1h2y,r1h2z,i1h2z) + +S2vF12(cxz,r1h1x,i1h1x,r1h1z,i1h1z,r1h2x,i1h2x,r1h2z,i1h2z); + + return(0.5*temp); +} + +double +DFiF12(double cxx, double cyy, double czz, double cxy, double cyz, double cxz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z, double r1h2x, double i1h2x, double r1h2y, double i1h2y, double r1h2z, double i1h2z) + + /* 18 args - 6 + 6 + 6 */ + + + +{ +double temp; + + temp = S2iF12(cxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h2x,i1h2x,r1h2x,i1h2x) + +S2iF12(cyy,r1h1y,i1h1y,r1h1y,i1h1y,r1h2y,i1h2y,r1h2y,i1h2y) + +S2iF12(czz,r1h1z,i1h1z,r1h1z,i1h1z,r1h2z,i1h2z,r1h2z,i1h2z); + temp += + S2iF12(cxy,r1h1x,i1h1x,r1h1y,i1h1y,r1h2x,i1h2x,r1h2y,i1h2y) + +S2iF12(cyz,r1h1y,i1h1y,r1h1z,i1h1z,r1h2y,i1h2y,r1h2z,i1h2z) + +S2iF12(cxz,r1h1x,i1h1x,r1h1z,i1h1z,r1h2x,i1h2x,r1h2z,i1h2z); + + return(temp*0.5); /* divided by two to scale down */ +} + +double +DFn2F12(DpassStr *p) + + /* 40 vars - 16 + 6 + 6 + 6 + 6 */ +/* + * a structure because a standard C compiler can handle only + * 32 variables. + * + */ +{ +double temp; + + temp = S2v2F12(p->cxx,p->r1h1x,p->i1h1x, + p->r1h1x,p->i1h1x, + p->r1h2x,p->i1h2x, + p->r1h2x,p->i1h2x, + p->r2h11x,p->i2h11x, + p->r2h11x,p->i2h11x, + p->h2f1f2x,p->ih2f1f2x, + p->h2f1f2x,p->ih2f1f2x); + temp += + S2v2F12(p->cyy,p->r1h1y,p->i1h1y, + p->r1h1y,p->i1h1y, + p->r1h2y,p->i1h2y, + p->r1h2y,p->i1h2y, + p->r2h11y,p->i2h11y, + p->r2h11y,p->i2h11y, + p->h2f1f2y,p->ih2f1f2y, + p->h2f1f2y,p->ih2f1f2y); + temp += + S2v2F12(p->czz,p->r1h1z,p->i1h1z, + p->r1h1z,p->i1h1z, + p->r1h2z,p->i1h2z, + p->r1h2z,p->i1h2z, + p->r2h11z,p->i2h11z, + p->r2h11z,p->i2h11z, + p->h2f1f2z,p->ih2f1f2z, + p->h2f1f2z,p->ih2f1f2z); + temp += + S2v2F12(p->cxy,p->r1h1x,p->i1h1x, + p->r1h1y,p->i1h1y, + p->r1h2x,p->i1h2x, + p->r1h2y,p->i1h2y, + p->r2h11x,p->i2h11x, + p->r2h11y,p->i2h11y, + p->h2f1f2x,p->ih2f1f2x, + p->h2f1f2y,p->ih2f1f2y); + temp += + S2v2F12(p->cyz,p->r1h1y,p->i1h1y, + p->r1h1z,p->i1h1z, + p->r1h2y,p->i1h2y, + p->r1h2z,p->i1h2z, + p->r2h11y,p->i2h11y, + p->r2h11z,p->i2h11z, + p->h2f1f2y,p->ih2f1f2y, + p->h2f1f2z,p->ih2f1f2z); + temp += + S2v2F12(p->cxz,p->r1h1x,p->i1h1x, + p->r1h1z,p->i1h1z, + p->r1h2x,p->i1h2x, + p->r1h2z,p->i1h2z, + p->r2h11x,p->i2h11x, + p->r2h11z,p->i2h11z, + p->h2f1f2x,p->ih2f1f2x, + p->h2f1f2z,p->ih2f1f2z); + temp += + S3v2F12(p->cxxx,p->r1h1x, + p->i1h1x,p->r1h1x,p->i1h1x,p->r1h1x,p->i1h1x, + p->r1h2x,p->i1h2x, + p->r1h2x,p->i1h2x,p->r1h2x,p->i1h2x) + +S3v2F12(p->cyyy,p->r1h1y, + p->i1h1y,p->r1h1y,p->i1h1y,p->r1h1y,p->i1h1y, + p->r1h2y,p->i1h2y, + p->r1h2y,p->i1h2y,p->r1h2y,p->i1h2y); + temp += + S3v2F12(p->czzz,p->r1h1z, + p->i1h1z,p->r1h1z,p->i1h1z,p->r1h1z,p->i1h1z, + p->r1h2z,p->i1h2z, + p->r1h2z,p->i1h2z,p->r1h2z,p->i1h2z) + +S3v2F12(p->cxxy,p->r1h1x, + p->i1h1x,p->r1h1x,p->i1h1x,p->r1h1y,p->i1h1y, + p->r1h2x,p->i1h2x, + p->r1h2x,p->i1h2x,p->r1h2y,p->i1h2y); + temp += + S3v2F12(p->cxxz,p->r1h1x, + p->i1h1x,p->r1h1x,p->i1h1x,p->r1h1z,p->i1h1z, + p->r1h2x,p->i1h2x, + p->r1h2x,p->i1h2x,p->r1h2z,p->i1h2z) + +S3v2F12(p->cxyy,p->r1h1x, + p->i1h1x,p->r1h1y,p->i1h1y,p->r1h1y,p->i1h1y, + p->r1h2x,p->i1h2x, + p->r1h2y,p->i1h2y,p->r1h2y,p->i1h2y); + temp += + S3v2F12(p->cyyz,p->r1h1y, + p->i1h1y,p->r1h1y,p->i1h1y,p->r1h1z,p->i1h1z, + p->r1h2y,p->i1h2y, + p->r1h2y,p->i1h2y,p->r1h2z,p->i1h2z) + +S3v2F12(p->cxzz,p->r1h1x, + p->i1h1x,p->r1h1z,p->i1h1z,p->r1h1z,p->i1h1z, + p->r1h2x,p->i1h2x, + p->r1h2z,p->i1h2z,p->r1h2z,p->i1h2z); + temp += + S3v2F12(p->cyzz,p->r1h1y, + p->i1h1y,p->r1h1z,p->i1h1z,p->r1h1z,p->i1h1z, + p->r1h2y,p->i1h2y, + p->r1h2z,p->i1h2z,p->r1h2z,p->i1h2z) + +S3v2F12(p->cxyz,p->r1h1x, + p->i1h1x,p->r1h1y,p->i1h1y,p->r1h1z,p->i1h1z, + p->r1h2x,p->i1h2x, + p->r1h2y,p->i1h2y,p->r1h2z,p->i1h2z); + + return(temp/3.); /* divided by 3 to get kernel (otherwise we get 3*kernel) */ +} + +double +DFi2F12(DpassStr *p) + + /* 40 vars - 16 + 6 + 6 + 6 + 6 */ +{ +double temp; + + temp = S2i2F12(p->cxx,p->r1h1x,p->i1h1x, + p->r1h1x,p->i1h1x, + p->r1h2x,p->i1h2x, + p->r1h2x,p->i1h2x, + p->r2h11x,p->i2h11x, + p->r2h11x,p->i2h11x, + p->h2f1f2x,p->ih2f1f2x, + p->h2f1f2x,p->ih2f1f2x); + temp += + S2i2F12(p->cyy,p->r1h1y,p->i1h1y, + p->r1h1y,p->i1h1y, + p->r1h2y,p->i1h2y, + p->r1h2y,p->i1h2y, + p->r2h11y,p->i2h11y, + p->r2h11y,p->i2h11y, + p->h2f1f2y,p->ih2f1f2y, + p->h2f1f2y,p->ih2f1f2y); + temp += + S2i2F12(p->czz,p->r1h1z,p->i1h1z, + p->r1h1z,p->i1h1z, + p->r1h2z,p->i1h2z, + p->r1h2z,p->i1h2z, + p->r2h11z,p->i2h11z, + p->r2h11z,p->i2h11z, + p->h2f1f2z,p->ih2f1f2z, + p->h2f1f2z,p->ih2f1f2z); + temp += + S2i2F12(p->cxy,p->r1h1x,p->i1h1x, + p->r1h1y,p->i1h1y, + p->r1h2x,p->i1h2x, + p->r1h2y,p->i1h2y, + p->r2h11x,p->i2h11x, + p->r2h11y,p->i2h11y, + p->h2f1f2x,p->ih2f1f2x, + p->h2f1f2y,p->ih2f1f2y); + temp += + S2i2F12(p->cyz,p->r1h1y,p->i1h1y, + p->r1h1z,p->i1h1z, + p->r1h2y,p->i1h2y, + p->r1h2z,p->i1h2z, + p->r2h11y,p->i2h11y, + p->r2h11z,p->i2h11z, + p->h2f1f2y,p->ih2f1f2y, + p->h2f1f2z,p->ih2f1f2z); + temp += + S2i2F12(p->cxz,p->r1h1x,p->i1h1x, + p->r1h1z,p->i1h1z, + p->r1h2x,p->i1h2x, + p->r1h2z,p->i1h2z, + p->r2h11x,p->i2h11x, + p->r2h11z,p->i2h11z, + p->h2f1f2x,p->ih2f1f2x, + p->h2f1f2z,p->ih2f1f2z); + temp += + S3i2F12(p->cxxx,p->r1h1x, + p->i1h1x,p->r1h1x,p->i1h1x,p->r1h1x,p->i1h1x, + p->r1h2x,p->i1h2x, + p->r1h2x,p->i1h2x,p->r1h2x,p->i1h2x); + temp += + S3i2F12(p->cyyy,p->r1h1y, + p->i1h1y,p->r1h1y,p->i1h1y,p->r1h1y,p->i1h1y, + p->r1h2y,p->i1h2y, + p->r1h2y,p->i1h2y,p->r1h2y,p->i1h2y) + +S3i2F12(p->czzz,p->r1h1z, + p->i1h1z,p->r1h1z,p->i1h1z,p->r1h1z,p->i1h1z, + p->r1h2z,p->i1h2z, + p->r1h2z,p->i1h2z,p->r1h2z,p->i1h2z); + temp += + S3i2F12(p->cxxy,p->r1h1x, + p->i1h1x,p->r1h1x,p->i1h1x,p->r1h1y,p->i1h1y, + p->r1h2x,p->i1h2x, + p->r1h2x,p->i1h2x,p->r1h2y,p->i1h2y) + +S3i2F12(p->cxxz,p->r1h1x, + p->i1h1x,p->r1h1x,p->i1h1x,p->r1h1z,p->i1h1z, + p->r1h2x,p->i1h2x, + p->r1h2x,p->i1h2x,p->r1h2z,p->i1h2z); + temp += + S3i2F12(p->cxyy,p->r1h1x, + p->i1h1x,p->r1h1y,p->i1h1y,p->r1h1y,p->i1h1y, + p->r1h2x,p->i1h2x, + p->r1h2y,p->i1h2y,p->r1h2y,p->i1h2y) + +S3i2F12(p->cyyz,p->r1h1y, + p->i1h1y,p->r1h1y,p->i1h1y,p->r1h1z,p->i1h1z, + p->r1h2y,p->i1h2y, + p->r1h2y,p->i1h2y,p->r1h2z,p->i1h2z); + temp += + S3i2F12(p->cxzz,p->r1h1x, + p->i1h1x,p->r1h1z,p->i1h1z,p->r1h1z,p->i1h1z, + p->r1h2x,p->i1h2x, + p->r1h2z,p->i1h2z,p->r1h2z,p->i1h2z); + temp += S3i2F12(p->cyzz,p->r1h1y, + p->i1h1y,p->r1h1z,p->i1h1z,p->r1h1z,p->i1h1z, + p->r1h2y,p->i1h2y, + p->r1h2z,p->i1h2z,p->r1h2z,p->i1h2z) + +S3i2F12(p->cxyz,p->r1h1x, + p->i1h1x,p->r1h1y,p->i1h1y,p->r1h1z,p->i1h1z, + p->r1h2x,p->i1h2x, + p->r1h2y,p->i1h2y,p->r1h2z,p->i1h2z); + + return(temp/3.); /* divided by 3 to get kernel (otherwise we get 3*kernel) */ +} + +double +D1n2F1(double cxx, double r1h1x, double i1h1x) + + /* 12 variables */ + + +{ +double temp; + + temp = S2v2F1(cxx,r1h1x,i1h1x,r1h1x,i1h1x); + + return(temp); +} + +double +D1n3F1(double cxx, double cxxx, double r1h1x, double i1h1x, double r2h11x, double i2h11x) +{ +double temp; + + temp = S2v3F1(cxx,r1h1x,i1h1x,r1h1x,i1h1x,r2h11x,i2h11x,r2h11x,i2h11x) + +S3v3F1(cxxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h1x,i1h1x); + + return(temp); +} + + +double +D1nF12(double cxx, double r1h1x, double i1h1x, double r1h2x, double i1h2x) + + /* 18 args - 6 + 6 + 6 */ + + + +{ +double temp; + + temp = S2vF12(cxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h2x,i1h2x,r1h2x,i1h2x); + + return(0.5*temp); +} + + +double +D1n2F12(double cxx, double cxxx, double r1h1x, double i1h1x, double r1h2x, double i1h2x, double r2h11x, double i2h11x, double h2f1f2x, double ih2f1f2x) + + /* 40 vars - 16 + 6 + 6 + 6 + 6 */ + + + + + +{ +double temp; + + temp = S2v2F12(cxx,r1h1x,i1h1x,r1h1x,i1h1x, + r1h2x,i1h2x,r1h2x,i1h2x, + r2h11x,i2h11x,r2h11x,i2h11x, + h2f1f2x,ih2f1f2x,h2f1f2x,ih2f1f2x) + +S3v2F12(cxxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h1x,i1h1x, + r1h2x,i1h2x,r1h2x,i1h2x,r1h2x,i1h2x); + + return(temp/3.); /* divided by 3 to get kernel (otherwise we get 3*kernel) */ +} + + +double +D1i2F1(double cxx, double r1h1x, double i1h1x) + + /* 12 variables */ + + +{ +double temp; + + temp = S2i2F1(cxx,r1h1x,i1h1x,r1h1x,i1h1x); + + return(temp); +} + + +double +D1i3F1(double cxx, double cxxx, double r1h1x, double i1h1x, double r2h11x, double i2h11x) +{ +double temp; + + temp = S2i3F1(cxx,r1h1x,i1h1x,r1h1x,i1h1x,r2h11x,i2h11x,r2h11x,i2h11x) + +S3i3F1(cxxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h1x,i1h1x); + + return(temp); +} + + +double +D1iF12(double cxx, double r1h1x, double i1h1x, double r1h2x, double i1h2x) + + /* 18 args - 6 + 6 + 6 */ + + + +{ +double temp; + + temp = S2iF12(cxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h2x,i1h2x,r1h2x,i1h2x); + + return(0.5*temp); +} + + +double +D1i2F12(double cxx, double cxxx, double r1h1x, double i1h1x, double r1h2x, double i1h2x, double r2h11x, double i2h11x, double h2f1f2x, double ih2f1f2x) + + /* 40 vars - 16 + 6 + 6 + 6 + 6 */ + + + + + +{ +double temp; + + temp = S2i2F12(cxx,r1h1x,i1h1x,r1h1x,i1h1x, + r1h2x,i1h2x,r1h2x,i1h2x, + r2h11x,i2h11x,r2h11x,i2h11x, + h2f1f2x,ih2f1f2x,h2f1f2x,ih2f1f2x) + +S3i2F12(cxxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h1x,i1h1x, + r1h2x,i1h2x,r1h2x,i1h2x,r1h2x,i1h2x); + + return(temp/3.); /* divided by 3 to get kernel (otherwise we get 3*kernel) */ +} + diff --git a/src/spicelib/analysis/dsetparm.c b/src/spicelib/analysis/dsetparm.c new file mode 100644 index 000000000..e04d21ed5 --- /dev/null +++ b/src/spicelib/analysis/dsetparm.c @@ -0,0 +1,94 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Jaijeet S Roychowdhury +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "cktdefs.h" +#include "distodef.h" + +#include "analysis.h" + +/* ARGSUSED */ +int +DsetParm(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + switch(which) { + + case D_START: + if (value->rValue <= 0.0) { + errMsg = copy("Frequency of 0 is invalid"); + ((DISTOAN*)anal)->DstartF1 = 1.0; + return(E_PARMVAL); + } + + ((DISTOAN*)anal)->DstartF1 = value->rValue; + break; + + case D_STOP: + if (value->rValue <= 0.0) { + errMsg = copy("Frequency of 0 is invalid"); + ((DISTOAN*)anal)->DstartF1 = 1.0; + return(E_PARMVAL); + } + + ((DISTOAN*)anal)->DstopF1 = value->rValue; + break; + + case D_STEPS: + ((DISTOAN*)anal)->DnumSteps = value->iValue; + break; + + case D_DEC: + ((DISTOAN*)anal)->DstepType = DECADE; + break; + + case D_OCT: + ((DISTOAN*)anal)->DstepType = OCTAVE; + break; + + case D_LIN: + ((DISTOAN*)anal)->DstepType = LINEAR; + break; + + case D_F2OVRF1: + ((DISTOAN*)anal)->Df2ovrF1 = value->rValue; + ((DISTOAN*)anal)->Df2wanted = 1; + break; + + default: + return(E_BADPARM); + } + return(OK); +} + + +static IFparm Dparms[] = { + { "start", D_START, IF_SET|IF_REAL, "starting frequency" }, + { "stop", D_STOP, IF_SET|IF_REAL, "ending frequency" }, + { "numsteps", D_STEPS, IF_SET|IF_INTEGER, "number of frequencies" }, + { "dec", D_DEC, IF_SET|IF_FLAG, "step by decades" }, + { "oct", D_OCT, IF_SET|IF_FLAG, "step by octaves" }, + { "lin", D_LIN, IF_SET|IF_FLAG, "step linearly" }, + { "f2overf1", D_F2OVRF1, IF_SET|IF_REAL, "ratio of F2 to F1" }, +}; + +SPICEanalysis DISTOinfo = { + { + "DISTO", + "Small signal distortion analysis", + + sizeof(Dparms)/sizeof(IFparm), + Dparms + }, + sizeof(DISTOAN), + FREQUENCYDOMAIN, + 1, + DsetParm, + DaskQuest, + NULL, + DISTOan +}; diff --git a/src/spicelib/analysis/naskq.c b/src/spicelib/analysis/naskq.c new file mode 100644 index 000000000..9138819b7 --- /dev/null +++ b/src/spicelib/analysis/naskq.c @@ -0,0 +1,76 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Gary W. Ng +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "ifsim.h" +#include "iferrmsg.h" +#include "noisedef.h" + + +int +NaskQuest(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + switch(which) { + + case N_OUTPUT: + value->nValue = ((NOISEAN*)anal)->output; + break; + + case N_OUTREF: + value->nValue = ((NOISEAN*)anal)->outputRef; + break; + + case N_INPUT: + value->uValue = ((NOISEAN*)anal)->input; + break; + + case N_DEC: + if(((NOISEAN*)anal)->NstpType == DECADE) { + value->iValue=1; + } else { + value->iValue=0; + } + break; + + case N_OCT: + if(((NOISEAN*)anal)->NstpType == OCTAVE) { + value->iValue=1; + } else { + value->iValue=0; + } + break; + + case N_LIN: + if(((NOISEAN*)anal)->NstpType == LINEAR) { + value->iValue=1; + } else { + value->iValue=0; + } + break; + + case N_STEPS: + value->iValue = ((NOISEAN*)anal)->NnumSteps; + break; + + case N_START: + value->rValue = ((NOISEAN*)anal)->NstartFreq; + break; + + case N_STOP: + value->rValue = ((NOISEAN*)anal)->NstopFreq; + break; + + case N_PTSPERSUM: + value->iValue = ((NOISEAN*)anal)->NStpsSm; + break; + + default: + return(E_BADPARM); + } + return(OK); +} + diff --git a/src/spicelib/analysis/nevalsrc.c b/src/spicelib/analysis/nevalsrc.c new file mode 100644 index 000000000..14fb6d952 --- /dev/null +++ b/src/spicelib/analysis/nevalsrc.c @@ -0,0 +1,51 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Gary W. Ng +**********/ + +/* + * NevalSrc (noise, lnNoise, ckt, type, node1, node2, param) + * This routine evaluates the noise due to different physical + * phenomena. This includes the "shot" noise associated with dc + * currents in semiconductors and the "thermal" noise associated with + * resistance. Although semiconductors also display "flicker" (1/f) + * noise, the lack of a unified model requires us to handle it on a + * "case by case" basis. What we CAN provide, though, is the noise + * gain associated with the 1/f source. + */ + + +#include "ngspice.h" +#include "cktdefs.h" +#include "const.h" +#include "noisedef.h" + + +void +NevalSrc (double *noise, double *lnNoise, CKTcircuit *ckt, int type, int node1, int node2, double param) +{ + double realVal; + double imagVal; + double gain; + + realVal = *((ckt->CKTrhs) + node1) - *((ckt->CKTrhs) + node2); + imagVal = *((ckt->CKTirhs) + node1) - *((ckt->CKTirhs) + node2); + gain = (realVal*realVal) + (imagVal*imagVal); + switch (type) { + + case SHOTNOISE: + *noise = gain * 2 * CHARGE * fabs(param); /* param is the dc current in a semiconductor */ + *lnNoise = log( MAX(*noise,N_MINLOG) ); + break; + + case THERMNOISE: + *noise = gain * 4 * CONSTboltz * ckt->CKTtemp * param; /* param is the conductance of a resistor */ + *lnNoise = log( MAX(*noise,N_MINLOG) ); + break; + + case N_GAIN: + *noise = gain; + break; + + } +} diff --git a/src/spicelib/analysis/ninteg.c b/src/spicelib/analysis/ninteg.c new file mode 100644 index 000000000..4eeccab80 --- /dev/null +++ b/src/spicelib/analysis/ninteg.c @@ -0,0 +1,45 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Gary W. Ng +**********/ + +/* + * Nintegrate.c (noizDens, lnNdens, lnNlstDens, data) + * + * This subroutine evaluates the integral of the function + * + * EXPONENT + * NOISE = a * (FREQUENCY) + * + * given two points from the curve. If EXPONENT is relatively close + * to 0, the noise is simply multiplied by the change in frequency. + * If it isn't, a more complicated expression must be used. Note that + * EXPONENT = -1 gives a different equation than EXPONENT <> -1. + * Hence, the reason for the constant 'N_INTUSELOG'. + */ + +#include +#include "ngspice.h" +#include "noisedef.h" + + +double +Nintegrate (double noizDens, double lnNdens, double lnNlstDens, Ndata *data) +{ + double exponent; + double a; + + exponent = (lnNdens - lnNlstDens) / data->delLnFreq; + if ( fabs(exponent) < N_INTFTHRESH ) { + return (noizDens * data->delFreq); + } else { + a = exp(lnNdens - exponent*data->lnFreq); + exponent += 1.0; + if (fabs(exponent) < N_INTUSELOG) { + return (a * (data->lnFreq - data->lnLastFreq)); + } else { + return (a * ((exp(exponent * data->lnFreq) - exp(exponent * data->lnLastFreq)) / + exponent)); + } + } +} diff --git a/src/spicelib/analysis/noisean.c b/src/spicelib/analysis/noisean.c new file mode 100644 index 000000000..45bbd6f06 --- /dev/null +++ b/src/spicelib/analysis/noisean.c @@ -0,0 +1,295 @@ +/* Patch to noisean.c by Richard D. McRoberts. + * Patched with modifications from Weidong Liu (2000) + * Patched with modifications ftom Weidong Liu + * in bsim4.1.0 code + */ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Gary W. Ng +Modified: 2001 AlansFixes +**********/ + +#include "ngspice.h" +#include +#include "acdefs.h" +#include "cktdefs.h" +#include "iferrmsg.h" +#include "noisedef.h" +#include "sperror.h" +#include "vsrc/vsrcdefs.h" +#include "isrc/isrcdefs.h" + +extern int CKTnoise( CKTcircuit *, int, int, Ndata * ); + + +int +NOISEan (CKTcircuit *ckt, int restart) +{ + Ndata *data; + double realVal; + double imagVal; + int error; + int posOutNode; + int negOutNode; + int code; + int step; + IFuid freqUid; + char *inst; + double freqTol; /* tolerence parameter for finding final frequency; hack */ + + NOISEAN *job = (NOISEAN*) (ckt->CKTcurJob); + static char *noacinput = "noise input source has no AC value"; + + posOutNode = ((CKTnode*) (job->output))->number; + negOutNode = ((CKTnode*) (job->outputRef))->number; + + /* see if the source specified is AC */ + inst = NULL; + code = CKTtypelook("Vsource"); + if (code != -1) { + error = CKTfndDev((void *)ckt,&code,(void **)&inst, + job->input, (void *)NULL, (IFuid)NULL); + if (!error && !((VSRCinstance *)inst)->VSRCacGiven) { + errMsg = MALLOC(strlen(noacinput)+1); + strcpy(errMsg,noacinput); + return (E_NOACINPUT); + } + } + + code = CKTtypelook("Isource"); + if (code != -1 && inst==NULL) { + error = CKTfndDev((void *)ckt,&code, (void **)&inst, + job->input, (void *)NULL,(IFuid)NULL); + if (error) { + /* XXX ??? */ + (*(SPfrontEnd->IFerror))(ERR_WARNING, + "Noise input source %s not in circuit", + &job->input); + return (E_NOTFOUND); + } + if (!((ISRCinstance *)inst)->ISRCacGiven) { + errMsg = MALLOC(strlen(noacinput)+1); + strcpy(errMsg,noacinput); + return (E_NOACINPUT); + } + } + + if ( (job->NsavFstp == 0) || restart) { + switch (job->NstpType) { + + + case DECADE: + job->NfreqDelta = exp(log(10.0)/ + job->NnumSteps); + break; + + case OCTAVE: + job->NfreqDelta = exp(log(2.0)/ + job->NnumSteps); + break; + + case LINEAR: + job->NfreqDelta = (job->NstopFreq - + job->NstartFreq)/ + (job->NnumSteps+1); + break; + + default: + return(E_BADPARM); + } + + /* error = DCop(ckt); */ + error = CKTop(ckt, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, + ckt->CKTdcMaxIter); + + if (error) return(error); + + /* Patch to noisean.c by Richard D. McRoberts. */ + ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG; + error = CKTload(ckt); + if(error) return(error); + + data = (Ndata*)MALLOC(sizeof(Ndata)); + step = 0; + data->freq = job->NstartFreq; + data->outNoiz = 0.0; + data->inNoise = 0.0; + + /* the current front-end needs the namelist to be fully + declared before an OUTpBeginplot */ + + (*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL, + "frequency", UID_OTHER,(void **)NULL); + + data->numPlots = 0; /* we don't have any plots yet */ + error = CKTnoise(ckt,N_DENS,N_OPEN,data); + if (error) return(error); + + /* + * all names in the namelist have been declared. now start the + * plot + */ + + error = (*(SPfrontEnd->OUTpBeginPlot))(ckt,(void *)(ckt->CKTcurJob), + "Noise Spectral Density Curves - (V^2 or A^2)/Hz", + freqUid,IF_REAL,data->numPlots,data->namelist,IF_REAL, + &(data->NplotPtr)); + if (error) return(error); + + if (job->NstpType != LINEAR) { + (*(SPfrontEnd->OUTattributes))((void *)data->NplotPtr,NULL, + OUT_SCALE_LOG, NULL); + } + + } else { /* we must have paused before. pick up where we left off */ + step = job->NsavFstp; + switch (job->NstpType) { + + case DECADE: + case OCTAVE: + data->freq = job->NstartFreq * exp (step * + log (job->NfreqDelta)); + break; + + case LINEAR: + data->freq = job->NstartFreq + step * + job->NfreqDelta; + break; + + default: + return(E_BADPARM); + + } + job->NsavFstp = 0; + data->outNoiz = job->NsavOnoise; + data->inNoise = job->NsavInoise; + /* saj resume rawfile fix*/ + error = (*(SPfrontEnd->OUTpBeginPlot))(ckt,(void *)(ckt->CKTcurJob), + "Noise Spectral Density Curves - (V^2 or A^2)/Hz", + freqUid,IF_REAL,666,data->namelist,666, + &(data->NplotPtr)); + /*saj*/ + } + + switch (job->NstpType) { + case DECADE: + case OCTAVE: + freqTol = job->NfreqDelta * job->NstopFreq * ckt->CKTreltol; + break; + case LINEAR: + freqTol = job->NfreqDelta * ckt->CKTreltol; + break; + default: + return(E_BADPARM); + } + + data->lstFreq = data->freq; + + /* do the noise analysis over all frequencies */ + + while (data->freq <= job->NstopFreq + freqTol) { + if( (*(SPfrontEnd->IFpauseTest))() ) { + job->NsavFstp = step; /* save our results */ + job->NsavOnoise = data->outNoiz; /* up until now */ + job->NsavInoise = data->inNoise; + return (E_PAUSE); + } + ckt->CKTomega = 2.0 * M_PI * data->freq; + ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEAC; + + /* + * solve the original AC system to get the transfer + * function between the input and output + */ + + NIacIter(ckt); + realVal = *((ckt->CKTrhsOld) + posOutNode) + - *((ckt->CKTrhsOld) + negOutNode); + imagVal = *((ckt->CKTirhsOld) + posOutNode) + - *((ckt->CKTirhsOld) + negOutNode); + data->GainSqInv = 1.0 / MAX(((realVal*realVal) + + (imagVal*imagVal)),N_MINGAIN); + data->lnGainInv = log(data->GainSqInv); + + /* set up a block of "common" data so we don't have to + * recalculate it for every device + */ + + data->delFreq = data->freq - data->lstFreq; + data->lnFreq = log(MAX(data->freq,N_MINLOG)); + data->lnLastFreq = log(MAX(data->lstFreq,N_MINLOG)); + data->delLnFreq = data->lnFreq - data->lnLastFreq; + + if ((job->NStpsSm != 0) && ((step % (job->NStpsSm)) == 0)) { + data->prtSummary = TRUE; + } else { + data->prtSummary = FALSE; + } + + /* + data->outNumber = 1; + */ + + data->outNumber = 0; + /* the frequency will NOT be stored in array[0] as before; instead, + * it will be given in refVal.rValue (see later) + */ + + NInzIter(ckt,posOutNode,negOutNode); /* solve the adjoint system */ + + /* now we use the adjoint system to calculate the noise + * contributions of each generator in the circuit + */ + + error = CKTnoise(ckt,N_DENS,N_CALC,data); + if (error) return(error); + data->lstFreq = data->freq; + + /* update the frequency */ + + switch (job->NstpType) { + + case DECADE: + case OCTAVE: + data->freq *= job->NfreqDelta; + break; + + case LINEAR: + data->freq += job->NfreqDelta; + break; + + default: + return(E_INTERN); + } + step++; + } + + error = CKTnoise(ckt,N_DENS,N_CLOSE,data); + if (error) return(error); + +#ifdef INT_NOISE + data->numPlots = 0; + data->outNumber = 0; + + if (job->NstartFreq != job->NstopFreq) { + error = CKTnoise(ckt,INT_NOIZ,N_OPEN,data); + + if (error) return(error); + + (*(SPfrontEnd->OUTpBeginPlot))(ckt,(void *)(ckt->CKTcurJob), + "Integrated Noise - V^2 or A^2", + (IFuid)NULL,(int)0,data->numPlots,data->namelist,IF_REAL, + &(data->NplotPtr)); + + error = CKTnoise(ckt,INT_NOIZ,N_CALC,data); + if (error) return(error); + + error = CKTnoise(ckt,INT_NOIZ,N_CLOSE,data); + if (error) return(error); + } +#endif + + FREE(data); + return(OK); +} diff --git a/src/spicelib/analysis/nsetparm.c b/src/spicelib/analysis/nsetparm.c new file mode 100644 index 000000000..0e6ef3f7c --- /dev/null +++ b/src/spicelib/analysis/nsetparm.c @@ -0,0 +1,107 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Gary W. Ng +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "ifsim.h" +#include "iferrmsg.h" +#include "noisedef.h" + +#include "analysis.h" + +int +NsetParm(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + switch(which) { + + case N_OUTPUT: + ((NOISEAN*)anal)->output = value->nValue; + break; + + case N_OUTREF: + ((NOISEAN*)anal)->outputRef = value->nValue; + break; + + case N_INPUT: + ((NOISEAN*)anal)->input = value->uValue; + break; + + case N_DEC: + ((NOISEAN*)anal)->NstpType = DECADE; + break; + + case N_OCT: + ((NOISEAN*)anal)->NstpType = OCTAVE; + break; + + case N_LIN: + ((NOISEAN*)anal)->NstpType = LINEAR; + break; + + case N_STEPS: + ((NOISEAN*)anal)->NnumSteps = value->iValue; + break; + + case N_START: + if (value->rValue <= 0.0) { + errMsg = copy("Frequency of 0 is invalid"); + ((NOISEAN*)anal)->NstartFreq = 1.0; + return(E_PARMVAL); + } + + ((NOISEAN*)anal)->NstartFreq = value->rValue; + break; + + case N_STOP: + if (value->rValue <= 0.0) { + errMsg = copy("Frequency of 0 is invalid"); + ((NOISEAN*)anal)->NstartFreq = 1.0; + return(E_PARMVAL); + } + + ((NOISEAN*)anal)->NstopFreq = value->rValue; + break; + + case N_PTSPERSUM: + ((NOISEAN*)anal)->NStpsSm = value->iValue; + break; + + default: + return(E_BADPARM); + } + return(OK); +} + + +static IFparm Nparms[] = { + { "output", N_OUTPUT, IF_SET|IF_STRING, "output noise summation node" }, + { "outputref", N_OUTREF, IF_SET|IF_STRING, "output noise reference node" }, + { "input", N_INPUT, IF_SET|IF_STRING, "input noise source" }, + { "dec", N_DEC, IF_SET|IF_FLAG, "step by decades" }, + { "oct", N_OCT, IF_SET|IF_FLAG, "step by octaves" }, + { "lin", N_LIN, IF_SET|IF_FLAG, "step linearly" }, + { "numsteps", N_STEPS, IF_SET|IF_INTEGER, "number of frequencies" }, + { "start", N_START, IF_SET|IF_REAL, "starting frequency" }, + { "stop", N_STOP, IF_SET|IF_REAL, "ending frequency" }, + { "ptspersum", N_PTSPERSUM, IF_SET|IF_INTEGER, "frequency points per summary report" } +}; + +SPICEanalysis NOISEinfo = { + { + "NOISE", + "Noise analysis", + + sizeof(Nparms)/sizeof(IFparm), + Nparms + }, + sizeof(NOISEAN), + FREQUENCYDOMAIN, + 1, + NsetParm, + NaskQuest, + NULL, + NOISEan +}; diff --git a/src/spicelib/analysis/pzan.c b/src/spicelib/analysis/pzan.c new file mode 100644 index 000000000..1a2e5ebd8 --- /dev/null +++ b/src/spicelib/analysis/pzan.c @@ -0,0 +1,197 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +**********/ + +#include "ngspice.h" +#include +#include "complex.h" +#include "cktdefs.h" +#include "smpdefs.h" +#include "pzdefs.h" +#include "trandefs.h" /* only to get the 'mode' definitions */ +#include "sperror.h" + + +#define DEBUG if (0) + +/* ARGSUSED */ +int +PZan(CKTcircuit *ckt, int reset) +{ + PZAN *pzan = (PZAN *) ckt->CKTcurJob; + int error; + int numNames; + IFuid *nameList; + void *plot = NULL; + + error = PZinit(ckt); + if (error != OK) return error; + + /* Calculate small signal parameters at the operating point */ + error = CKTop(ckt, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, + ckt->CKTdcMaxIter); + if (error) + return(error); + + ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG; + error = CKTload(ckt); /* Make sure that all small signal params are + * set */ + if (error) + return(error); + + if (ckt->CKTkeepOpInfo) { + /* Dump operating point. */ + error = CKTnames(ckt,&numNames,&nameList); + if(error) return(error); + error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt, + (void*)ckt->CKTcurJob, "Distortion Operating Point", + (IFuid)NULL,IF_REAL,numNames,nameList, IF_REAL,&plot); + if(error) return(error); + CKTdump(ckt,(double)0,plot); + (*(SPfrontEnd->OUTendPlot))(plot); + } + + if (pzan->PZwhich & PZ_DO_POLES) { + error = CKTpzSetup(ckt, PZ_DO_POLES); + if (error != OK) + return error; + error = CKTpzFindZeros(ckt, &pzan->PZpoleList, &pzan->PZnPoles); + if (error != OK) + return(error); + } + + if (pzan->PZwhich & PZ_DO_ZEROS) { + error = CKTpzSetup(ckt, PZ_DO_ZEROS); + if (error != OK) + return error; + error = CKTpzFindZeros(ckt, &pzan->PZzeroList, &pzan->PZnZeros); + if (error != OK) + return(error); + } + + return PZpost(ckt); +} + +/* + * Perform error checking + */ + +int +PZinit(CKTcircuit *ckt) +{ + PZAN *pzan = (PZAN *) ckt->CKTcurJob; + int i; + + i = CKTtypelook("transmission line"); + if (i == -1) { + i = CKTtypelook("Tranline"); + if (i == -1) + i = CKTtypelook("LTRA"); + } + if (i != -1 && ckt->CKThead[i] != NULL) + ERROR(E_XMISSIONLINE, "Transmission lines not supported") + + pzan->PZpoleList = (PZtrial *) NULL; + pzan->PZzeroList = (PZtrial *) NULL; + pzan->PZnPoles = 0; + pzan->PZnZeros = 0; + + if (pzan->PZin_pos == pzan->PZin_neg) + ERROR(E_SHORT, "Input is shorted") + + if (pzan->PZout_pos == pzan->PZout_neg) + ERROR(E_SHORT, "Output is shorted") + + if (pzan->PZin_pos == pzan->PZout_pos + && pzan->PZin_neg == pzan->PZout_neg + && pzan->PZinput_type == PZ_IN_VOL) + ERROR(E_INISOUT, "Transfer function is unity") + else if (pzan->PZin_pos == pzan->PZout_neg + && pzan->PZin_neg == pzan->PZout_pos + && pzan->PZinput_type == PZ_IN_VOL) + ERROR(E_INISOUT, "Transfer function is -1") + + return(OK); +} + +/* + * PZpost Post-processing of the pole-zero analysis results + */ + +int +PZpost(CKTcircuit *ckt) +{ + PZAN *pzan = (PZAN *) ckt->CKTcurJob; + void *pzPlotPtr = NULL; /* the plot pointer for front end */ + IFcomplex *out_list; + IFvalue outData; /* output variable (points to out_list) */ + IFuid *namelist; + PZtrial *root; + char name[50]; + int i, j; + + namelist = (IFuid *) MALLOC((pzan->PZnPoles + + pzan->PZnZeros)*sizeof(IFuid)); + out_list = (IFcomplex *)MALLOC((pzan->PZnPoles + + pzan->PZnZeros)*sizeof(IFcomplex)); + + j = 0; + for (i = 0; i < pzan->PZnPoles; i++) { + sprintf(name, "pole(%-u)", i+1); + (*(SPfrontEnd->IFnewUid))(ckt,&(namelist[j++]),(IFuid)NULL, + name,UID_OTHER,(void **)NULL); + } + for (i = 0; i < pzan->PZnZeros; i++) { + sprintf(name, "zero(%-u)", i+1); + (*(SPfrontEnd->IFnewUid))(ckt,&(namelist[j++]),(IFuid)NULL, + name,UID_OTHER,(void **)NULL); + } + + (*SPfrontEnd->OUTpBeginPlot)(ckt, (void *)pzan, pzan->JOBname, + (IFuid)NULL, (int)0, pzan->PZnPoles + pzan->PZnZeros, namelist, + IF_COMPLEX, &pzPlotPtr); + + j = 0; + if (pzan->PZnPoles > 0) { + for (root = pzan->PZpoleList; root != NULL; root = root->next) { + for (i = 0; i < root->multiplicity; i++) { + out_list[j].real = root->s.real; + out_list[j].imag = root->s.imag; + j += 1; + if (root->s.imag != 0.0) { + out_list[j].real = root->s.real; + out_list[j].imag = -root->s.imag; + j += 1; + } + } + DEBUG printf("LIST pole: (%g,%g) x %d\n", + root->s.real, root->s.imag, root->multiplicity); + } + } + + if (pzan->PZnZeros > 0) { + for (root = pzan->PZzeroList; root != NULL; root = root->next) { + for (i = 0; i < root->multiplicity; i++) { + out_list[j].real = root->s.real; + out_list[j].imag = root->s.imag; + j += 1; + if (root->s.imag != 0.0) { + out_list[j].real = root->s.real; + out_list[j].imag = -root->s.imag; + j += 1; + } + } + DEBUG printf("LIST zero: (%g,%g) x %d\n", + root->s.real, root->s.imag, root->multiplicity); + } + } + + outData.v.numValue = pzan->PZnPoles + pzan->PZnZeros; + outData.v.vec.cVec = out_list; + + (*SPfrontEnd->OUTpData)(pzPlotPtr, (IFvalue *) 0, &outData); + (*(SPfrontEnd->OUTendPlot))(pzPlotPtr); + + return(OK); +} diff --git a/src/spicelib/analysis/pzaskq.c b/src/spicelib/analysis/pzaskq.c new file mode 100644 index 000000000..c1f41c42d --- /dev/null +++ b/src/spicelib/analysis/pzaskq.c @@ -0,0 +1,80 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "pzdefs.h" +#include "cktdefs.h" + + +/* ARGSUSED */ +int +PZaskQuest(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + switch(which) { + + case PZ_NODEI: + value->nValue = (IFnode)CKTnum2nod(ckt,((PZAN*)anal)->PZin_pos); + break; + + case PZ_NODEG: + value->nValue = (IFnode)CKTnum2nod(ckt,((PZAN*)anal)->PZin_neg); + break; + + case PZ_NODEJ: + value->nValue = (IFnode)CKTnum2nod(ckt,((PZAN*)anal)->PZout_pos); + break; + + case PZ_NODEK: + value->nValue = (IFnode)CKTnum2nod(ckt,((PZAN*)anal)->PZout_neg); + break; + + case PZ_V: + if( ((PZAN*)anal)->PZinput_type == PZ_IN_VOL) { + value->iValue=1; + } else { + value->iValue=0; + } + break; + + case PZ_I: + if( ((PZAN*)anal)->PZinput_type == PZ_IN_CUR) { + value->iValue=1; + } else { + value->iValue=0; + } + break; + + case PZ_POL: + if( ((PZAN*)anal)->PZwhich == PZ_DO_POLES) { + value->iValue=1; + } else { + value->iValue=0; + } + break; + + case PZ_ZER: + if( ((PZAN*)anal)->PZwhich == PZ_DO_ZEROS) { + value->iValue=1; + } else { + value->iValue=0; + } + break; + + case PZ_PZ: + if( ((PZAN*)anal)->PZwhich == (PZ_DO_POLES | PZ_DO_ZEROS)) { + value->iValue=1; + } else { + value->iValue=0; + } + break; + + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/analysis/pzsetp.c b/src/spicelib/analysis/pzsetp.c new file mode 100644 index 000000000..6b1e95e6a --- /dev/null +++ b/src/spicelib/analysis/pzsetp.c @@ -0,0 +1,101 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "pzdefs.h" +#include "cktdefs.h" + +#include "analysis.h" + +/* ARGSUSED */ +int +PZsetParm(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + switch(which) { + + case PZ_NODEI: + ((PZAN*)anal)->PZin_pos = ((CKTnode*)value->nValue)->number; + break; + + case PZ_NODEG: + ((PZAN*)anal)->PZin_neg = ((CKTnode*)value->nValue)->number; + break; + + case PZ_NODEJ: + ((PZAN*)anal)->PZout_pos = ((CKTnode*)value->nValue)->number; + break; + + case PZ_NODEK: + ((PZAN*)anal)->PZout_neg = ((CKTnode*)value->nValue)->number; + break; + + case PZ_V: + if(value->iValue) { + ((PZAN*)anal)->PZinput_type = PZ_IN_VOL; + } + break; + + case PZ_I: + if(value->iValue) { + ((PZAN*)anal)->PZinput_type = PZ_IN_CUR; + } + break; + + case PZ_POL: + if(value->iValue) { + ((PZAN*)anal)->PZwhich = PZ_DO_POLES; + } + break; + + case PZ_ZER: + if(value->iValue) { + ((PZAN*)anal)->PZwhich = PZ_DO_ZEROS; + } + break; + + case PZ_PZ: + if(value->iValue) { + ((PZAN*)anal)->PZwhich = PZ_DO_POLES | PZ_DO_ZEROS; + } + break; + + default: + return(E_BADPARM); + } + return(OK); +} + + +static IFparm PZparms[] = { + { "nodei", PZ_NODEI, IF_SET|IF_ASK|IF_NODE, "" }, + { "nodeg", PZ_NODEG, IF_SET|IF_ASK|IF_NODE, "" }, + { "nodej", PZ_NODEJ, IF_SET|IF_ASK|IF_NODE, "" }, + { "nodek", PZ_NODEK, IF_SET|IF_ASK|IF_NODE, "" }, + { "vol", PZ_V, IF_SET|IF_ASK|IF_FLAG, "" }, + { "cur", PZ_I, IF_SET|IF_ASK|IF_FLAG, "" }, + { "pol", PZ_POL, IF_SET|IF_ASK|IF_FLAG, "" }, + { "zer", PZ_ZER, IF_SET|IF_ASK|IF_FLAG, "" }, + { "pz", PZ_PZ, IF_SET|IF_ASK|IF_FLAG, "" } +}; + +SPICEanalysis PZinfo = { + { + "PZ", + "pole-zero analysis", + + sizeof(PZparms)/sizeof(IFparm), + PZparms + }, + sizeof(PZAN), + NODOMAIN, + 1, + PZsetParm, + PZaskQuest, + NULL, + PZan +}; diff --git a/src/spicelib/analysis/sensaskq.c b/src/spicelib/analysis/sensaskq.c new file mode 100644 index 000000000..6cf457c8e --- /dev/null +++ b/src/spicelib/analysis/sensaskq.c @@ -0,0 +1,53 @@ +/********** +Copyright 1991 Regents of the University of California. All rights reserved. +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "cktdefs.h" +#include "sensdefs.h" + + +/* ARGSUSED */ +int +SENSask(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + SENS_AN *sinfo = (SENS_AN *) anal; + + switch (which) { + + case SENS_START: + value->rValue = sinfo->start_freq; + break; + + case SENS_STOP: + value->rValue = sinfo->stop_freq; + break; + + case SENS_STEPS: + value->iValue = sinfo->n_freq_steps; + break; + + case SENS_DEC: + case SENS_OCT: + case SENS_LIN: + case SENS_DC: + value->iValue = sinfo->step_type == which; + break; + + case SENS_DEFTOL: + sinfo->deftol = value->rValue; + break; + + case SENS_DEFPERTURB: + value->rValue = sinfo->defperturb; + break; + + default: + return(E_BADPARM); + } + return(OK); +} + diff --git a/src/spicelib/analysis/senssetp.c b/src/spicelib/analysis/senssetp.c new file mode 100644 index 000000000..cf5ee8a21 --- /dev/null +++ b/src/spicelib/analysis/senssetp.c @@ -0,0 +1,119 @@ +/********** +Copyright 1991 Regents of the University of California. All rights reserved. +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "cktdefs.h" +#include "sensdefs.h" + +#include "analysis.h" + +/* ARGSUSED */ +int +SENSsetParam(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + SENS_AN *sinfo = (SENS_AN *) anal; + + switch(which) { + + case SENS_POS: + sinfo->output_pos = (CKTnode *) value->nValue; + sinfo->output_neg = NULL; + sinfo->output_volt = 1; + sinfo->step_type = SENS_DC; + break; + + case SENS_NEG: + sinfo->output_neg = (CKTnode *) value->nValue; + break; + + case SENS_SRC: + sinfo->output_src = value->uValue; + sinfo->output_volt = 0; + sinfo->step_type = SENS_DC; + break; + + case SENS_NAME: + sinfo->output_name = value->sValue; + break; + + case SENS_START: + sinfo->start_freq = value->rValue; + break; + + case SENS_STOP: + sinfo->stop_freq = value->rValue; + break; + + case SENS_STEPS: + sinfo->n_freq_steps = value->iValue; + break; + + case SENS_DEC: + sinfo->step_type = SENS_DECADE; + break; + + case SENS_OCT: + sinfo->step_type = SENS_OCTAVE; + break; + + case SENS_LIN: + sinfo->step_type = SENS_LINEAR; + break; + + case SENS_DC: + sinfo->step_type = SENS_DC; + break; + + case SENS_DEFTOL: + sinfo->deftol = value->rValue; + break; + + case SENS_DEFPERTURB: + sinfo->defperturb = value->rValue; + break; + + default: + return(E_BADPARM); + } + return(OK); +} + + +static IFparm SENSparms[] = { + /* TF like parameters */ + { "outpos", SENS_POS, IF_SET|IF_ASK|IF_NODE, "output positive node" }, + { "outneg", SENS_NEG, IF_SET|IF_ASK|IF_NODE, "output negative node" }, + { "outsrc", SENS_SRC, IF_SET|IF_ASK|IF_INSTANCE, "output current" }, + { "outname", SENS_NAME, IF_SET|IF_ASK|IF_STRING, + "Name of output variable" }, + + /* AC parameters */ + { "start", SENS_START, IF_SET|IF_ASK|IF_REAL, "starting frequency" }, + { "stop", SENS_STOP, IF_SET|IF_ASK|IF_REAL, "ending frequency" }, + { "numsteps", SENS_STEPS,IF_SET|IF_ASK|IF_INTEGER, + "number of frequencies"}, + { "dec", SENS_DEC, IF_SET|IF_FLAG, "step by decades" }, + { "oct", SENS_OCT, IF_SET|IF_FLAG, "step by octaves" }, + { "lin", SENS_LIN, IF_SET|IF_FLAG, "step linearly" }, + { "dc", SENS_DC, IF_SET|IF_FLAG, "analysis at DC" }, +}; + +SPICEanalysis SENSinfo = { + { + "SENS", + "Sensitivity analysis", + sizeof(SENSparms)/sizeof(IFparm), + SENSparms + }, + sizeof(SENS_AN), + FREQUENCYDOMAIN, + 1, + SENSsetParam, + SENSask, + NULL, + sens_sens +}; diff --git a/src/spicelib/analysis/tfanal.c b/src/spicelib/analysis/tfanal.c new file mode 100644 index 000000000..24b27681f --- /dev/null +++ b/src/spicelib/analysis/tfanal.c @@ -0,0 +1,176 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +/* subroutine to do DC Transfer Function analysis */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "ifsim.h" +#include "sperror.h" +#include "smpdefs.h" +#include "tfdefs.h" + + +/* ARGSUSED */ +int +TFanal(CKTcircuit *ckt, int restart) + + /* forced restart flag */ +{ + int size; + int insrc,outsrc; + double outputs[3]; + IFvalue outdata; /* structure for output data vector, will point to + * outputs vector above */ + IFvalue refval; /* structure for 'reference' value (not used here) */ + int error; + int converged; + int i; + void *plotptr = NULL; /* pointer to out plot */ + void *ptr = NULL; + IFuid uids[3]; + int Itype; + int Vtype; + char *name; +#define tfuid (uids[0]) /* unique id for the transfer function output */ +#define inuid (uids[1]) /* unique id for the transfer function input imp. */ +#define outuid (uids[2]) /* unique id for the transfer function out. imp. */ + + + /* first, find the operating point */ + converged = CKTop(ckt, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, + ckt->CKTdcMaxIter); + + Itype = CKTtypelook("Isource"); + Vtype = CKTtypelook("Vsource"); + if(Itype != -1) { + error = CKTfndDev((void*)ckt,&Itype,&ptr, + ((TFan*)ckt->CKTcurJob)->TFinSrc, (void *)NULL,(IFuid)NULL); + if(error ==0) { + ((TFan*)ckt->CKTcurJob)->TFinIsI = 1; + ((TFan*)ckt->CKTcurJob)->TFinIsV = 0; + } else { + ptr = NULL; + } + } + + if( (Vtype != -1) && (ptr==NULL) ) { + error = CKTfndDev((void*)ckt,&Vtype,&ptr, + ((TFan*)ckt->CKTcurJob)->TFinSrc, (void *)NULL, + (IFuid)NULL); + ((TFan*)ckt->CKTcurJob)->TFinIsV = 1; + ((TFan*)ckt->CKTcurJob)->TFinIsI = 0; + if(error !=0) { + (*(SPfrontEnd->IFerror))(ERR_WARNING, + "Transfer function source %s not in circuit", + &(((TFan*)ckt->CKTcurJob)->TFinSrc)); + ((TFan*)ckt->CKTcurJob)->TFinIsV = 0; + return(E_NOTFOUND); + } + } + + size = SMPmatSize(ckt->CKTmatrix); + for(i=0;i<=size;i++) { + ckt->CKTrhs[i] = 0; + } + + if(((TFan*)ckt->CKTcurJob)->TFinIsI) { + ckt->CKTrhs[((GENinstance*)ptr)->GENnode1] -= 1; + ckt->CKTrhs[((GENinstance*)ptr)->GENnode2] += 1; + } else { + insrc = CKTfndBranch(ckt,((TFan*)ckt->CKTcurJob)->TFinSrc); + ckt->CKTrhs[insrc] += 1; + } + + + SMPsolve(ckt->CKTmatrix,ckt->CKTrhs,ckt->CKTrhsSpare); + ckt->CKTrhs[0]=0; + + /* make a UID for the transfer function output */ + (*(SPfrontEnd->IFnewUid))(ckt,&tfuid,(IFuid)NULL,"Transfer_function", + UID_OTHER,(void **)NULL); + + /* make a UID for the input impedance */ + (*(SPfrontEnd->IFnewUid))(ckt,&inuid,((TFan*)ckt->CKTcurJob)->TFinSrc, + "Input_impedance", UID_OTHER,(void **)NULL); + + /* make a UID for the output impedance */ + if(((TFan*)ckt->CKTcurJob)->TFoutIsI) { + (*(SPfrontEnd->IFnewUid))(ckt,&outuid,((TFan*)ckt->CKTcurJob)->TFoutSrc + ,"Output_impedance", UID_OTHER,(void **)NULL); + } else { + name = (char *) + MALLOC(sizeof(char)*(strlen(((TFan*)ckt->CKTcurJob)->TFoutName)+22)); + (void)sprintf(name,"output_impedance_at_%s", + ((TFan*)ckt->CKTcurJob)->TFoutName); + (*(SPfrontEnd->IFnewUid))(ckt,&outuid,(IFuid)NULL, + name, UID_OTHER,(void **)NULL); + } + + error = (*(SPfrontEnd->OUTpBeginPlot))(ckt,(void *)(ckt->CKTcurJob), + ((TFan*)(ckt->CKTcurJob))->JOBname,(IFuid)NULL,(int)0,3, + uids,IF_REAL,&plotptr); + if(error) return(error); + + /*find transfer function */ + if(((TFan*)ckt->CKTcurJob)->TFoutIsV) { + outputs[0] = ckt->CKTrhs[((TFan*)ckt->CKTcurJob)->TFoutPos->number] - + ckt->CKTrhs[((TFan*)ckt->CKTcurJob)->TFoutNeg->number] ; + } else { + outsrc = CKTfndBranch(ckt,((TFan*)ckt->CKTcurJob)->TFoutSrc); + outputs[0] = ckt->CKTrhs[outsrc]; + } + + /* now for input resistance */ + if(((TFan*)ckt->CKTcurJob)->TFinIsI) { + outputs[1] = ckt->CKTrhs[((GENinstance*)ptr)->GENnode2] - + ckt->CKTrhs[((GENinstance*)ptr)->GENnode1]; + } else { + if(fabs(ckt->CKTrhs[insrc])<1e-20) { + outputs[1]=1e20; + } else { + outputs[1] = -1/ckt->CKTrhs[insrc]; + } + } + + if(((TFan*)ckt->CKTcurJob)->TFoutIsI && + (((TFan*)ckt->CKTcurJob)->TFoutSrc == + ((TFan*)ckt->CKTcurJob)->TFinSrc)) { + outputs[2]=outputs[1]; + goto done; + /* no need to compute output resistance when it is the same as + the input */ + } + /* now for output resistance */ + for(i=0;i<=size;i++) { + ckt->CKTrhs[i] = 0; + } + if(((TFan*)ckt->CKTcurJob)->TFoutIsV) { + ckt->CKTrhs[((TFan*)ckt->CKTcurJob)->TFoutPos->number] -= 1; + ckt->CKTrhs[((TFan*)ckt->CKTcurJob)->TFoutNeg->number] += 1; + } else { + ckt->CKTrhs[outsrc] += 1; + } + SMPsolve(ckt->CKTmatrix,ckt->CKTrhs,ckt->CKTrhsSpare); + ckt->CKTrhs[0]=0; + if(((TFan*)ckt->CKTcurJob)->TFoutIsV) { + outputs[2]= ckt->CKTrhs[((TFan*)ckt->CKTcurJob)->TFoutNeg->number] - + ckt->CKTrhs[((TFan*)ckt->CKTcurJob)->TFoutPos->number]; + } else { + outputs[2] = 1/MAX(1e-20,ckt->CKTrhs[outsrc]); + } +done: + outdata.v.numValue=3; + outdata.v.vec.rVec=outputs; + refval.rValue = 0; + (*(SPfrontEnd->OUTpData))(plotptr,&refval,&outdata); + (*(SPfrontEnd->OUTendPlot))(plotptr); + return(OK); +} + + diff --git a/src/spicelib/analysis/tfaskq.c b/src/spicelib/analysis/tfaskq.c new file mode 100644 index 000000000..1a51786e2 --- /dev/null +++ b/src/spicelib/analysis/tfaskq.c @@ -0,0 +1,25 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "trcvdefs.h" +#include "cktdefs.h" + + +/* ARGSUSED */ +int +TFaskQuest(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + switch(which) { + + default: + break; + } + return(E_BADPARM); +} + diff --git a/src/spicelib/analysis/tfsetp.c b/src/spicelib/analysis/tfsetp.c new file mode 100644 index 000000000..2d8952e72 --- /dev/null +++ b/src/spicelib/analysis/tfsetp.c @@ -0,0 +1,73 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "tfdefs.h" +#include "cktdefs.h" + +#include "analysis.h" + +/* ARGSUSED */ +int +TFsetParm(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + switch(which) { + + case TF_OUTPOS: + ((TFan *)anal)->TFoutPos = (CKTnode *)value->nValue; + ((TFan *)anal)->TFoutIsV = TRUE; + ((TFan *)anal)->TFoutIsI = FALSE; + break; + case TF_OUTNEG: + ((TFan *)anal)->TFoutNeg = (CKTnode *)value->nValue; + ((TFan *)anal)->TFoutIsV = TRUE; + ((TFan *)anal)->TFoutIsI = FALSE; + break; + case TF_OUTNAME: + ((TFan *)anal)->TFoutName = value->sValue; + break; + case TF_OUTSRC: + ((TFan *)anal)->TFoutSrc = value->uValue; + ((TFan *)anal)->TFoutIsV = FALSE; + ((TFan *)anal)->TFoutIsI = TRUE; + break; + case TF_INSRC: + ((TFan *)anal)->TFinSrc = value->uValue; + break; + + default: + return(E_BADPARM); + } + return(OK); +} + + +static IFparm TFparms[] = { + { "outpos", TF_OUTPOS, IF_SET|IF_NODE, "Positive output node" }, + { "outneg", TF_OUTNEG, IF_SET|IF_NODE, "Negative output node" }, + { "outname", TF_OUTNAME, IF_SET|IF_STRING,"Name of output variable"}, + { "outsrc", TF_OUTSRC, IF_SET|IF_INSTANCE, "Output source" }, + { "insrc", TF_INSRC, IF_SET|IF_INSTANCE, "Input source" } +}; + +SPICEanalysis TFinfo = { + { + "TF", + "transfer function analysis", + + sizeof(TFparms)/sizeof(IFparm), + TFparms + }, + sizeof(TFan), + NODOMAIN, + 0, + TFsetParm, + TFaskQuest, + NULL, + TFanal +}; diff --git a/src/spicelib/analysis/tranaskq.c b/src/spicelib/analysis/tranaskq.c new file mode 100644 index 000000000..2f2bd7b2c --- /dev/null +++ b/src/spicelib/analysis/tranaskq.c @@ -0,0 +1,45 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "trandefs.h" +#include "cktdefs.h" + +/* ARGSUSED */ +int +TRANaskQuest(CKTcircuit *ckt, void *anal, int which,IFvalue *value) +{ + switch(which) { + + case TRAN_TSTOP: + value->rValue = ((TRANan *)anal)->TRANfinalTime; + break; + case TRAN_TSTEP: + value->rValue = ((TRANan *)anal)->TRANstep; + break; + case TRAN_TSTART: + value->rValue = ((TRANan *)anal)->TRANinitTime; + break; + case TRAN_TMAX: + value->rValue = ((TRANan *)anal)->TRANmaxStep; + break; + case TRAN_UIC: + if(((TRANan *)anal)->TRANmode & MODEUIC) { + value->iValue = 1; + } else { + value->iValue = 0; + } + break; + + + default: + return(E_BADPARM); + } + return(OK); +} + diff --git a/src/spicelib/analysis/traninit.c b/src/spicelib/analysis/traninit.c new file mode 100644 index 000000000..77dacba0d --- /dev/null +++ b/src/spicelib/analysis/traninit.c @@ -0,0 +1,45 @@ +/********** +Copyright 1991 Regents of the University of California. All rights reserved. +Modified: 2000 AlansFixes +**********/ + +#include "ngspice.h" +#include "cktdefs.h" +#include "trandefs.h" +#include "iferrmsg.h" + +/* + * this used to be in setup, but we need it here now + * (must be done after mode is set as below) + */ + +int TRANinit(CKTcircuit *ckt, JOB *job) +{ + ckt->CKTfinalTime = ((TRANan*)job)->TRANfinalTime; + ckt->CKTstep = ((TRANan*)job)->TRANstep; + ckt->CKTinitTime = ((TRANan*)job)->TRANinitTime; + ckt->CKTmaxStep = ((TRANan*)job)->TRANmaxStep; + + + + /* The following code has been taken from macspice 3f4 (A. Wilson) + in the file traninit.new.c - Seems interesting */ + if(ckt->CKTmaxStep == 0) + { + if (ckt->CKTstep < ( ckt->CKTfinalTime - ckt->CKTinitTime )/50.0) + { + ckt->CKTmaxStep = ckt->CKTstep; + } + else + { + ckt->CKTmaxStep = ( ckt->CKTfinalTime - ckt->CKTinitTime )/50.0; + } +} + + + + ckt->CKTdelmin = 1e-11*ckt->CKTmaxStep; /* XXX */ + ckt->CKTmode = ((TRANan*)job)->TRANmode; + + return OK; +} diff --git a/src/spicelib/analysis/transetp.c b/src/spicelib/analysis/transetp.c new file mode 100644 index 000000000..a911bb268 --- /dev/null +++ b/src/spicelib/analysis/transetp.c @@ -0,0 +1,84 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "trandefs.h" +#include "cktdefs.h" + +#include "analysis.h" + +/* ARGSUSED */ +int +TRANsetParm(CKTcircuit *ckt, void *anal, int which, IFvalue *value) +{ + switch(which) { + + case TRAN_TSTOP: + if (value->rValue <= 0.0) { + errMsg = copy("TST0P is invalid, must be greater than zero."); + ((TRANan *)anal)->TRANfinalTime = 1.0; + return(E_PARMVAL); + } + ((TRANan *)anal)->TRANfinalTime = value->rValue; + break; + case TRAN_TSTEP: + if (value->rValue <= 0.0) { + errMsg = copy( "TSTEP is invalid, must be greater than zero." ); + ((TRANan *)anal)->TRANstep = 1.0; + return(E_PARMVAL); + } + ((TRANan *)anal)->TRANstep = value->rValue; + break; + case TRAN_TSTART: + if (value->rValue >= ((TRANan *)anal)->TRANfinalTime ) { + errMsg = copy("TSTART is invalid, must be less than TSTOP."); + ((TRANan *)anal)->TRANinitTime = 0.0; + return(E_PARMVAL); + } + ((TRANan *)anal)->TRANinitTime = value->rValue; + break; + case TRAN_TMAX: + ((TRANan *)anal)->TRANmaxStep = value->rValue; + break; + case TRAN_UIC: + if(value->iValue) { + ((TRANan *)anal)->TRANmode |= MODEUIC; + } + break; + + default: + return(E_BADPARM); + } + return(OK); +} + + +static IFparm TRANparms[] = { + { "tstart", TRAN_TSTART, IF_SET|IF_REAL, "starting time" }, + { "tstop", TRAN_TSTOP, IF_SET|IF_REAL, "ending time" }, + { "tstep", TRAN_TSTEP, IF_SET|IF_REAL, "time step" }, + { "tmax", TRAN_TMAX, IF_SET|IF_REAL, "maximum time step" }, + { "uic", TRAN_UIC, IF_SET|IF_FLAG, "use initial conditions" }, +}; + +SPICEanalysis TRANinfo = { + { + "TRAN", + "Transient analysis", + + sizeof(TRANparms)/sizeof(IFparm), + TRANparms + }, + sizeof(TRANan), + TIMEDOMAIN, + 1, + TRANsetParm, + TRANaskQuest, + TRANinit, + DCtran +}; diff --git a/src/spicelib/devices/ChangeLog b/src/spicelib/devices/ChangeLog index 566a103f8..0e1975836 100644 --- a/src/spicelib/devices/ChangeLog +++ b/src/spicelib/devices/ChangeLog @@ -1,3 +1,67 @@ +2000-08-28 Arno W. Peters + + * 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/asrcinit.c b/src/spicelib/devices/asrc/asrcinit.c new file mode 100644 index 000000000..85abf9816 --- /dev/null +++ b/src/spicelib/devices/asrc/asrcinit.c @@ -0,0 +1,64 @@ +#include + +#include + +#include "asrcitf.h" +#include "asrcext.h" +#include "asrcinit.h" + + +SPICEdev ASRCinfo = { + { + "ASRC", + "Arbitrary Source ", + + &ASRCnSize, + &ASRCnSize, + ASRCnames, + + &ASRCpTSize, + ASRCpTable, + + 0, + NULL, + DEV_DEFAULT + }, + + DEVparam : ASRCparam, + DEVmodParam : NULL, + DEVload : ASRCload, + DEVsetup : ASRCsetup, + DEVunsetup : ASRCunsetup, + DEVpzSetup : ASRCsetup, + DEVtemperature: NULL, + DEVtrunc : NULL, + DEVfindBranch : ASRCfindBr, + DEVacLoad : ASRCacLoad, /* ac and normal load functions NOT identical */ + DEVaccept : NULL, + DEVdestroy : ASRCdestroy, + DEVmodDelete : ASRCmDelete, + DEVdelete : ASRCdelete, + DEVsetic : NULL, + DEVask : ASRCask, + DEVmodAsk : NULL, + DEVpzLoad : ASRCpzLoad, + DEVconvTest : ASRCconvTest, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, /* DISTO */ + DEVnoise : NULL, /* NOISE */ + + DEVinstSize : &ASRCiSize, + DEVmodSize : &ASRCmSize +}; + + +SPICEdev * +get_asrc_info(void) +{ + return &ASRCinfo; +} diff --git a/src/spicelib/devices/asrc/asrcinit.h b/src/spicelib/devices/asrc/asrcinit.h new file mode 100644 index 000000000..ec57e40a5 --- /dev/null +++ b/src/spicelib/devices/asrc/asrcinit.h @@ -0,0 +1,11 @@ +#ifndef _ASRCINIT_H +#define _ASRCINIT_H + +extern IFparm ASRCpTable[ ]; +extern char *ASRCnames[ ]; +extern int ASRCpTSize; +extern int ASRCnSize; +extern int ASRCiSize; +extern int ASRCmSize; + +#endif 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/bjtinit.c b/src/spicelib/devices/bjt/bjtinit.c new file mode 100644 index 000000000..ffd8ecca3 --- /dev/null +++ b/src/spicelib/devices/bjt/bjtinit.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "bjtitf.h" +#include "bjtext.h" +#include "bjtinit.h" + + +SPICEdev BJTinfo = { + { + "BJT", + "Bipolar Junction Transistor", + + &BJTnSize, + &BJTnSize, + BJTnames, + + &BJTpTSize, + BJTpTable, + + &BJTmPTSize, + BJTmPTable, + DEV_DEFAULT + }, + + DEVparam : BJTparam, + DEVmodParam : BJTmParam, + DEVload : BJTload, + DEVsetup : BJTsetup, + DEVunsetup : BJTunsetup, + DEVpzSetup : BJTsetup, + DEVtemperature: BJTtemp, + DEVtrunc : BJTtrunc, + DEVfindBranch : NULL, + DEVacLoad : BJTacLoad, + DEVaccept : NULL, + DEVdestroy : BJTdestroy, + DEVmodDelete : BJTmDelete, + DEVdelete : BJTdelete, + DEVsetic : BJTgetic, + DEVask : BJTask, + DEVmodAsk : BJTmAsk, + DEVpzLoad : BJTpzLoad, + DEVconvTest : BJTconvTest, + DEVsenSetup : BJTsSetup, + DEVsenLoad : BJTsLoad, + DEVsenUpdate : BJTsUpdate, + DEVsenAcLoad : BJTsAcLoad, + DEVsenPrint : BJTsPrint, + DEVsenTrunc : NULL, + DEVdisto : BJTdisto, + DEVnoise : BJTnoise, + + DEVinstSize : &BJTiSize, + DEVmodSize : &BJTmSize + +}; + + +SPICEdev * +get_bjt_info(void) +{ + return &BJTinfo; +} diff --git a/src/spicelib/devices/bjt/bjtinit.h b/src/spicelib/devices/bjt/bjtinit.h new file mode 100644 index 000000000..e70f99915 --- /dev/null +++ b/src/spicelib/devices/bjt/bjtinit.h @@ -0,0 +1,13 @@ +#ifndef _BJTINIT_H +#define _BJTINIT_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; + +#endif 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/bsim1init.c b/src/spicelib/devices/bsim1/bsim1init.c new file mode 100644 index 000000000..2a23bc028 --- /dev/null +++ b/src/spicelib/devices/bsim1/bsim1init.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "bsim1itf.h" +#include "bsim1ext.h" +#include "bsim1init.h" + + +SPICEdev B1info = { + { + "BSIM1", + "Berkeley Short Channel IGFET Model", + + &B1nSize, + &B1nSize, + B1names, + + &B1pTSize, + B1pTable, + + &B1mPTSize, + B1mPTable, + DEV_DEFAULT + }, + + DEVparam : B1param, + DEVmodParam : B1mParam, + DEVload : B1load, + DEVsetup : B1setup, + DEVunsetup : B1unsetup, + DEVpzSetup : B1setup, + DEVtemperature: B1temp, + DEVtrunc : B1trunc, + DEVfindBranch : NULL, + DEVacLoad : B1acLoad, + DEVaccept : NULL, + DEVdestroy : B1destroy, + DEVmodDelete : B1mDelete, + DEVdelete : B1delete, + DEVsetic : B1getic, + DEVask : B1ask, + DEVmodAsk : B1mAsk, + DEVpzLoad : B1pzLoad, + DEVconvTest : B1convTest, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : B1disto, + DEVnoise : NULL, /* NOISE */ + + DEVinstSize : &B1iSize, + DEVmodSize : &B1mSize + +}; + + +SPICEdev * +get_bsim1_info(void) +{ + return &B1info; +} diff --git a/src/spicelib/devices/bsim1/bsim1init.h b/src/spicelib/devices/bsim1/bsim1init.h new file mode 100644 index 000000000..c3a971a3a --- /dev/null +++ b/src/spicelib/devices/bsim1/bsim1init.h @@ -0,0 +1,13 @@ +#ifndef _BSIM1INIT_H +#define _BSIM1INIT_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; + +#endif 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/bsim2init.c b/src/spicelib/devices/bsim2/bsim2init.c new file mode 100644 index 000000000..92c44dc35 --- /dev/null +++ b/src/spicelib/devices/bsim2/bsim2init.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "bsim2itf.h" +#include "bsim2ext.h" +#include "bsim2init.h" + + +SPICEdev B2info = { + { + "BSIM2", + "Berkeley Short Channel IGFET Model", + + &B2nSize, + &B2nSize, + B2names, + + &B2pTSize, + B2pTable, + + &B2mPTSize, + B2mPTable, + DEV_DEFAULT + }, + + DEVparam : B2param, + DEVmodParam : B2mParam, + DEVload : B2load, + DEVsetup : B2setup, + DEVunsetup : B2unsetup, + DEVpzSetup : B2setup, + DEVtemperature: B2temp, + DEVtrunc : B2trunc, + DEVfindBranch : NULL, + DEVacLoad : B2acLoad, + DEVaccept : NULL, + DEVdestroy : B2destroy, + DEVmodDelete : B2mDelete, + DEVdelete : B2delete, + DEVsetic : B2getic, + DEVask : B2ask, + DEVmodAsk : B2mAsk, + DEVpzLoad : B2pzLoad, + DEVconvTest : B2convTest, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, + DEVnoise : NULL, + + DEVinstSize : &B2iSize, + DEVmodSize : &B2mSize + +}; + + +SPICEdev * +get_bsim2_info(void) +{ + return &B2info; +} diff --git a/src/spicelib/devices/bsim2/bsim2init.h b/src/spicelib/devices/bsim2/bsim2init.h new file mode 100644 index 000000000..f34e036b6 --- /dev/null +++ b/src/spicelib/devices/bsim2/bsim2init.h @@ -0,0 +1,13 @@ +#ifndef _BSIM2INIT_H +#define _BSIM2INIT_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; + +#endif 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 b407910c2..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 8c999e456..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 961ace403..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 51cb4118c..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 b15609a8e..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 b2dea97a4..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 68e26ada7..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 4d568cf5b..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 e446eeda3..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 0776f1313..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 3d4d535d1..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 897a0dc7b..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 29dc6bd00..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 888664a72..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 cb5554309..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 0f17a2aa5..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 9d48f0f0a..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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 4aa5588ce..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 2000-04-27 20:03:59 pnenzi - Initial revision - - 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/bsim3init.c b/src/spicelib/devices/bsim3/bsim3init.c new file mode 100644 index 000000000..9afd8ee9f --- /dev/null +++ b/src/spicelib/devices/bsim3/bsim3init.c @@ -0,0 +1,64 @@ +#include + +#include + +#include "bsim3itf.h" +#include "bsim3ext.h" +#include "bsim3init.h" + + +SPICEdev BSIM3info = { + { "BSIM3", + "Berkeley Short Channel IGFET Model Version-3", + + &BSIM3nSize, + &BSIM3nSize, + BSIM3names, + + &BSIM3pTSize, + BSIM3pTable, + + &BSIM3mPTSize, + BSIM3mPTable, + DEV_DEFAULT + }, + + DEVparam : BSIM3param, + DEVmodParam : BSIM3mParam, + DEVload : BSIM3load, + DEVsetup : BSIM3setup, + DEVunsetup : BSIM3unsetup, + DEVpzSetup : BSIM3setup, + DEVtemperature: BSIM3temp, + DEVtrunc : BSIM3trunc, + DEVfindBranch : NULL, + DEVacLoad : BSIM3acLoad, + DEVaccept : NULL, + DEVdestroy : BSIM3destroy, + DEVmodDelete : BSIM3mDelete, + DEVdelete : BSIM3delete, + DEVsetic : BSIM3getic, + DEVask : BSIM3ask, + DEVmodAsk : BSIM3mAsk, + DEVpzLoad : BSIM3pzLoad, + DEVconvTest : BSIM3convTest, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, + DEVnoise : BSIM3noise, + + DEVinstSize : &BSIM3iSize, + DEVmodSize : &BSIM3mSize + +}; + + +SPICEdev * +get_bsim3_info(void) +{ + return &BSIM3info; +} diff --git a/src/spicelib/devices/bsim3/bsim3init.h b/src/spicelib/devices/bsim3/bsim3init.h new file mode 100644 index 000000000..09305bdee --- /dev/null +++ b/src/spicelib/devices/bsim3/bsim3init.h @@ -0,0 +1,13 @@ +#ifndef _BSIM3INIT_H +#define _BSIM3INIT_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; + +#endif 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/bsim3soi_dd/Makefile.am b/src/spicelib/devices/bsim3soi_dd/Makefile.am new file mode 100644 index 000000000..7dd8b444c --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/Makefile.am @@ -0,0 +1,34 @@ +## Process this file with automake to produce Makefile.in + +pkglib_LTLIBRARIES = libbsim3soidd.la + +libbsim3soidd_la_SOURCES = \ + b3soidd.c \ + b3soiddacld.c \ + b3soiddask.c \ + b3soiddcheck.c \ + b3soiddcvtest.c \ + b3soidddel.c \ + b3soidddest.c \ + b3soiddgetic.c \ + b3soiddld.c \ + b3soiddmask.c \ + b3soiddmdel.c \ + b3soiddmpar.c \ + b3soiddnoi.c \ + b3soiddpar.c \ + b3soiddpzld.c \ + b3soiddset.c \ + b3soiddtemp.c \ + b3soiddtrunc.c \ + b3soidddef.h \ + b3soiddext.h \ + b3soiddinit.c \ + b3soiddinit.h \ + b3soidditf.h + + + +INCLUDES = -I$(top_srcdir)/src/include + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/bsim3soi_dd/b3soidd.c b/src/spicelib/devices/bsim3soi_dd/b3soidd.c new file mode 100644 index 000000000..9b064a70a --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soidd.c @@ -0,0 +1,479 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soidd.c 98/5/01 +Modified by Wei Jin 99/9/27 +**********/ + + +#include "ngspice.h" +#include +#include "devdefs.h" +#include "b3soidddef.h" +#include "suffix.h" + +IFparm B3SOIDDpTable[] = { /* parameters */ +IOP( "l", B3SOIDD_L, IF_REAL , "Length"), +IOP( "w", B3SOIDD_W, IF_REAL , "Width"), +IOP( "ad", B3SOIDD_AD, IF_REAL , "Drain area"), +IOP( "as", B3SOIDD_AS, IF_REAL , "Source area"), +IOP( "pd", B3SOIDD_PD, IF_REAL , "Drain perimeter"), +IOP( "ps", B3SOIDD_PS, IF_REAL , "Source perimeter"), +IOP( "nrd", B3SOIDD_NRD, IF_REAL , "Number of squares in drain"), +IOP( "nrs", B3SOIDD_NRS, IF_REAL , "Number of squares in source"), +IOP( "off", B3SOIDD_OFF, IF_FLAG , "Device is initially off"), +IP( "ic", B3SOIDD_IC, IF_REALVEC , "Vector of DS,GS,BS initial voltages"), +OP( "gmbs", B3SOIDD_GMBS, IF_REAL, "Gmb"), +OP( "gm", B3SOIDD_GM, IF_REAL, "Gm"), +OP( "gm/ids", B3SOIDD_GMID, IF_REAL, "Gm/Ids"), +OP( "gds", B3SOIDD_GDS, IF_REAL, "Gds"), +OP( "vdsat", B3SOIDD_VDSAT, IF_REAL, "Vdsat"), +OP( "vth", B3SOIDD_VON, IF_REAL, "Vth"), +OP( "ids", B3SOIDD_CD, IF_REAL, "Ids"), +OP( "vbs", B3SOIDD_VBS, IF_REAL, "Vbs"), +OP( "vgs", B3SOIDD_VGS, IF_REAL, "Vgs"), +OP( "vds", B3SOIDD_VDS, IF_REAL, "Vds"), +OP( "ves", B3SOIDD_VES, IF_REAL, "Ves"), +IOP( "bjtoff", B3SOIDD_BJTOFF, IF_INTEGER, "BJT on/off flag"), +IOP( "debug", B3SOIDD_DEBUG, IF_INTEGER, "BJT on/off flag"), +IOP( "rth0", B3SOIDD_RTH0, IF_REAL, "Instance Thermal Resistance"), +IOP( "cth0", B3SOIDD_CTH0, IF_REAL, "Instance Thermal Capacitance"), +IOP( "nrb", B3SOIDD_NRB, IF_REAL, "Number of squares in body"), +}; + +IFparm B3SOIDDmPTable[] = { /* model parameters */ +IOP( "capmod", B3SOIDD_MOD_CAPMOD, IF_INTEGER, "Capacitance model selector"), +IOP( "mobmod", B3SOIDD_MOD_MOBMOD, IF_INTEGER, "Mobility model selector"), +IOP( "noimod", B3SOIDD_MOD_NOIMOD, IF_INTEGER, "Noise model selector"), +IOP( "paramchk", B3SOIDD_MOD_PARAMCHK, IF_INTEGER, "Model parameter checking selector"), +IOP( "binunit", B3SOIDD_MOD_BINUNIT, IF_INTEGER, "Bin unit selector"), +IOP( "version", B3SOIDD_MOD_VERSION, IF_REAL, " parameter for model version"), +IOP( "tox", B3SOIDD_MOD_TOX, IF_REAL, "Gate oxide thickness in meters"), + +IOP( "cdsc", B3SOIDD_MOD_CDSC, IF_REAL, "Drain/Source and channel coupling capacitance"), +IOP( "cdscb", B3SOIDD_MOD_CDSCB, IF_REAL, "Body-bias dependence of cdsc"), +IOP( "cdscd", B3SOIDD_MOD_CDSCD, IF_REAL, "Drain-bias dependence of cdsc"), +IOP( "cit", B3SOIDD_MOD_CIT, IF_REAL, "Interface state capacitance"), +IOP( "nfactor", B3SOIDD_MOD_NFACTOR, IF_REAL, "Subthreshold swing Coefficient"), +IOP( "vsat", B3SOIDD_MOD_VSAT, IF_REAL, "Saturation velocity at tnom"), +IOP( "at", B3SOIDD_MOD_AT, IF_REAL, "Temperature coefficient of vsat"), +IOP( "a0", B3SOIDD_MOD_A0, IF_REAL, "Non-uniform depletion width effect coefficient."), +IOP( "ags", B3SOIDD_MOD_AGS, IF_REAL, "Gate bias coefficient of Abulk."), +IOP( "a1", B3SOIDD_MOD_A1, IF_REAL, "Non-saturation effect coefficient"), +IOP( "a2", B3SOIDD_MOD_A2, IF_REAL, "Non-saturation effect coefficient"), +IOP( "keta", B3SOIDD_MOD_KETA, IF_REAL, "Body-bias coefficient of non-uniform depletion width effect."), +IOP( "nsub", B3SOIDD_MOD_NSUB, IF_REAL, "Substrate doping concentration with polarity"), +IOP( "nch", B3SOIDD_MOD_NPEAK, IF_REAL, "Channel doping concentration"), +IOP( "ngate", B3SOIDD_MOD_NGATE, IF_REAL, "Poly-gate doping concentration"), +IOP( "gamma1", B3SOIDD_MOD_GAMMA1, IF_REAL, "Vth body coefficient"), +IOP( "gamma2", B3SOIDD_MOD_GAMMA2, IF_REAL, "Vth body coefficient"), +IOP( "vbx", B3SOIDD_MOD_VBX, IF_REAL, "Vth transition body Voltage"), +IOP( "vbm", B3SOIDD_MOD_VBM, IF_REAL, "Maximum body voltage"), + +IOP( "xt", B3SOIDD_MOD_XT, IF_REAL, "Doping depth"), +IOP( "k1", B3SOIDD_MOD_K1, IF_REAL, "Bulk effect coefficient 1"), +IOP( "kt1", B3SOIDD_MOD_KT1, IF_REAL, "Temperature coefficient of Vth"), +IOP( "kt1l", B3SOIDD_MOD_KT1L, IF_REAL, "Temperature coefficient of Vth"), +IOP( "kt2", B3SOIDD_MOD_KT2, IF_REAL, "Body-coefficient of kt1"), +IOP( "k2", B3SOIDD_MOD_K2, IF_REAL, "Bulk effect coefficient 2"), +IOP( "k3", B3SOIDD_MOD_K3, IF_REAL, "Narrow width effect coefficient"), +IOP( "k3b", B3SOIDD_MOD_K3B, IF_REAL, "Body effect coefficient of k3"), +IOP( "w0", B3SOIDD_MOD_W0, IF_REAL, "Narrow width effect parameter"), +IOP( "nlx", B3SOIDD_MOD_NLX, IF_REAL, "Lateral non-uniform doping effect"), +IOP( "dvt0", B3SOIDD_MOD_DVT0, IF_REAL, "Short channel effect coeff. 0"), +IOP( "dvt1", B3SOIDD_MOD_DVT1, IF_REAL, "Short channel effect coeff. 1"), +IOP( "dvt2", B3SOIDD_MOD_DVT2, IF_REAL, "Short channel effect coeff. 2"), +IOP( "dvt0w", B3SOIDD_MOD_DVT0W, IF_REAL, "Narrow Width coeff. 0"), +IOP( "dvt1w", B3SOIDD_MOD_DVT1W, IF_REAL, "Narrow Width effect coeff. 1"), +IOP( "dvt2w", B3SOIDD_MOD_DVT2W, IF_REAL, "Narrow Width effect coeff. 2"), +IOP( "drout", B3SOIDD_MOD_DROUT, IF_REAL, "DIBL coefficient of output resistance"), +IOP( "dsub", B3SOIDD_MOD_DSUB, IF_REAL, "DIBL coefficient in the subthreshold region"), +IOP( "vth0", B3SOIDD_MOD_VTH0, IF_REAL,"Threshold voltage"), +IOP( "vtho", B3SOIDD_MOD_VTH0, IF_REAL,"Threshold voltage"), +IOP( "ua", B3SOIDD_MOD_UA, IF_REAL, "Linear gate dependence of mobility"), +IOP( "ua1", B3SOIDD_MOD_UA1, IF_REAL, "Temperature coefficient of ua"), +IOP( "ub", B3SOIDD_MOD_UB, IF_REAL, "Quadratic gate dependence of mobility"), +IOP( "ub1", B3SOIDD_MOD_UB1, IF_REAL, "Temperature coefficient of ub"), +IOP( "uc", B3SOIDD_MOD_UC, IF_REAL, "Body-bias dependence of mobility"), +IOP( "uc1", B3SOIDD_MOD_UC1, IF_REAL, "Temperature coefficient of uc"), +IOP( "u0", B3SOIDD_MOD_U0, IF_REAL, "Low-field mobility at Tnom"), +IOP( "ute", B3SOIDD_MOD_UTE, IF_REAL, "Temperature coefficient of mobility"), +IOP( "voff", B3SOIDD_MOD_VOFF, IF_REAL, "Threshold voltage offset"), +IOP( "tnom", B3SOIDD_MOD_TNOM, IF_REAL, "Parameter measurement temperature"), +IOP( "cgso", B3SOIDD_MOD_CGSO, IF_REAL, "Gate-source overlap capacitance per width"), +IOP( "cgdo", B3SOIDD_MOD_CGDO, IF_REAL, "Gate-drain overlap capacitance per width"), +IOP( "cgeo", B3SOIDD_MOD_CGEO, IF_REAL, "Gate-substrate overlap capacitance"), +IOP( "xpart", B3SOIDD_MOD_XPART, IF_REAL, "Channel charge partitioning"), +IOP( "delta", B3SOIDD_MOD_DELTA, IF_REAL, "Effective Vds parameter"), +IOP( "rsh", B3SOIDD_MOD_RSH, IF_REAL, "Source-drain sheet resistance"), +IOP( "rdsw", B3SOIDD_MOD_RDSW, IF_REAL, "Source-drain resistance per width"), + +IOP( "prwg", B3SOIDD_MOD_PRWG, IF_REAL, "Gate-bias effect on parasitic resistance "), +IOP( "prwb", B3SOIDD_MOD_PRWB, IF_REAL, "Body-effect on parasitic resistance "), + +IOP( "prt", B3SOIDD_MOD_PRT, IF_REAL, "Temperature coefficient of parasitic resistance "), +IOP( "eta0", B3SOIDD_MOD_ETA0, IF_REAL, "Subthreshold region DIBL coefficient"), +IOP( "etab", B3SOIDD_MOD_ETAB, IF_REAL, "Subthreshold region DIBL coefficient"), +IOP( "pclm", B3SOIDD_MOD_PCLM, IF_REAL, "Channel length modulation Coefficient"), +IOP( "pdiblc1", B3SOIDD_MOD_PDIBL1, IF_REAL, "Drain-induced barrier lowering coefficient"), +IOP( "pdiblc2", B3SOIDD_MOD_PDIBL2, IF_REAL, "Drain-induced barrier lowering coefficient"), +IOP( "pdiblcb", B3SOIDD_MOD_PDIBLB, IF_REAL, "Body-effect on drain-induced barrier lowering"), + +IOP( "pvag", B3SOIDD_MOD_PVAG, IF_REAL, "Gate dependence of output resistance parameter"), + +IOP( "shmod", B3SOIDD_MOD_SHMOD, IF_INTEGER, "Self heating mode selector"), +IOP( "tbox", B3SOIDD_MOD_TBOX, IF_REAL, "Back gate oxide thickness in meters"), +IOP( "tsi", B3SOIDD_MOD_TSI, IF_REAL, "Silicon-on-insulator thickness in meters"), +IOP( "xj", B3SOIDD_MOD_XJ, IF_REAL, "Junction Depth"), +IOP( "kb1", B3SOIDD_MOD_KB1, IF_REAL, "Backgate coupling coefficient at strong inversion"), +IOP( "kb3", B3SOIDD_MOD_KB3, IF_REAL, "Backgate coupling coefficient at subthreshold"), +IOP( "dvbd0", B3SOIDD_MOD_DVBD0, IF_REAL, "First coefficient of short-channel effect on Vbs0t"), +IOP( "dvbd1", B3SOIDD_MOD_DVBD1, IF_REAL, "Second coefficient of short-channel effect on Vbs0t"), +IOP( "vbsa", B3SOIDD_MOD_VBSA, IF_REAL, "Vbs0t offset voltage"), +IOP( "delp", B3SOIDD_MOD_DELP, IF_REAL, "Offset constant for limiting Vbseff to Phis"), +IOP( "rbody", B3SOIDD_MOD_RBODY, IF_REAL, "Intrinsic body contact sheet resistance"), +IOP( "rbsh", B3SOIDD_MOD_RBSH, IF_REAL, "Extrinsic body contact sheet resistance"), +IOP( "adice0", B3SOIDD_MOD_ADICE0, IF_REAL, "DICE constant for bulk charge effect"), +IOP( "abp", B3SOIDD_MOD_ABP, IF_REAL, "Gate bias coefficient for Xcsat calculation"), +IOP( "mxc", B3SOIDD_MOD_MXC, IF_REAL, "A smoothing parameter for Xcsat calculation"), +IOP( "rth0", B3SOIDD_MOD_RTH0, IF_REAL, "Self-heating thermal resistance"), +IOP( "cth0", B3SOIDD_MOD_CTH0, IF_REAL, "Self-heating thermal capacitance"), +IOP( "aii", B3SOIDD_MOD_AII, IF_REAL, "1st Vdsatii parameter"), +IOP( "bii", B3SOIDD_MOD_BII, IF_REAL, "2nd Vdsatii parameter"), +IOP( "cii", B3SOIDD_MOD_CII, IF_REAL, "3rd Vdsatii parameter"), +IOP( "dii", B3SOIDD_MOD_DII, IF_REAL, "4th Vdsatii parameter"), +IOP( "ngidl", B3SOIDD_MOD_NGIDL, IF_REAL, "GIDL first parameter"), +IOP( "agidl", B3SOIDD_MOD_AGIDL, IF_REAL, "GIDL second parameter"), +IOP( "bgidl", B3SOIDD_MOD_BGIDL, IF_REAL, "GIDL third parameter"), +IOP( "ndiode", B3SOIDD_MOD_NDIODE, IF_REAL, "Diode non-ideality factor"), +IOP( "ntun", B3SOIDD_MOD_NTUN, IF_REAL, "Reverse tunneling non-ideality factor"), +IOP( "isbjt", B3SOIDD_MOD_ISBJT, IF_REAL, "BJT emitter injection constant"), +IOP( "isdif", B3SOIDD_MOD_ISDIF, IF_REAL, "Body to S/D injection constant"), +IOP( "isrec", B3SOIDD_MOD_ISREC, IF_REAL, "Recombination in depletion constant"), +IOP( "istun", B3SOIDD_MOD_ISTUN, IF_REAL, "Tunneling diode constant"), +IOP( "xbjt", B3SOIDD_MOD_XBJT, IF_REAL, "Temperature coefficient for Isbjt"), +IOP( "xdif", B3SOIDD_MOD_XBJT, IF_REAL, "Temperature coefficient for Isdif"), +IOP( "xrec", B3SOIDD_MOD_XREC, IF_REAL, "Temperature coefficient for Isrec"), +IOP( "xtun", B3SOIDD_MOD_XTUN, IF_REAL, "Temperature coefficient for Istun"), +IOP( "edl", B3SOIDD_MOD_EDL, IF_REAL, "Electron diffusion length"), +IOP( "kbjt1", B3SOIDD_MOD_KBJT1, IF_REAL, "Vds dependency on BJT base width"), +IOP( "tt", B3SOIDD_MOD_TT, IF_REAL, "Diffusion capacitance transit time coefficient"), +IOP( "vsdth", B3SOIDD_MOD_VSDTH, IF_REAL, "Source/Drain diffusion threshold voltage"), +IOP( "vsdfb", B3SOIDD_MOD_VSDFB, IF_REAL, "Source/Drain diffusion flatband voltage"), +IOP( "csdmin", B3SOIDD_MOD_CSDMIN, IF_REAL, "Source/Drain diffusion bottom minimum capacitance"), +IOP( "asd", B3SOIDD_MOD_ASD, IF_REAL, "Source/Drain diffusion smoothing parameter"), + +IOP( "pbswg", B3SOIDD_MOD_PBSWG, IF_REAL, "Source/drain (gate side) sidewall junction capacitance built in potential"), +IOP( "mjswg", B3SOIDD_MOD_MJSWG, IF_REAL, "Source/drain (gate side) sidewall junction capacitance grading coefficient"), + +IOP( "cjswg", B3SOIDD_MOD_CJSWG, IF_REAL, "Source/drain (gate side) sidewall junction capacitance per unit width"), +IOP( "csdesw", B3SOIDD_MOD_CSDESW, IF_REAL, "Source/drain sidewall fringing constant"), +IOP( "lint", B3SOIDD_MOD_LINT, IF_REAL, "Length reduction parameter"), +IOP( "ll", B3SOIDD_MOD_LL, IF_REAL, "Length reduction parameter"), +IOP( "lln", B3SOIDD_MOD_LLN, IF_REAL, "Length reduction parameter"), +IOP( "lw", B3SOIDD_MOD_LW, IF_REAL, "Length reduction parameter"), +IOP( "lwn", B3SOIDD_MOD_LWN, IF_REAL, "Length reduction parameter"), +IOP( "lwl", B3SOIDD_MOD_LWL, IF_REAL, "Length reduction parameter"), + +IOP( "wr", B3SOIDD_MOD_WR, IF_REAL, "Width dependence of rds"), +IOP( "wint", B3SOIDD_MOD_WINT, IF_REAL, "Width reduction parameter"), +IOP( "dwg", B3SOIDD_MOD_DWG, IF_REAL, "Width reduction parameter"), +IOP( "dwb", B3SOIDD_MOD_DWB, IF_REAL, "Width reduction parameter"), + +IOP( "wl", B3SOIDD_MOD_WL, IF_REAL, "Width reduction parameter"), +IOP( "wln", B3SOIDD_MOD_WLN, IF_REAL, "Width reduction parameter"), +IOP( "ww", B3SOIDD_MOD_WW, IF_REAL, "Width reduction parameter"), +IOP( "wwn", B3SOIDD_MOD_WWN, IF_REAL, "Width reduction parameter"), +IOP( "wwl", B3SOIDD_MOD_WWL, IF_REAL, "Width reduction parameter"), + +IOP( "b0", B3SOIDD_MOD_B0, IF_REAL, "Abulk narrow width parameter"), +IOP( "b1", B3SOIDD_MOD_B1, IF_REAL, "Abulk narrow width parameter"), + +IOP( "cgsl", B3SOIDD_MOD_CGSL, IF_REAL, "New C-V model parameter"), +IOP( "cgdl", B3SOIDD_MOD_CGDL, IF_REAL, "New C-V model parameter"), +IOP( "ckappa", B3SOIDD_MOD_CKAPPA, IF_REAL, "New C-V model parameter"), +IOP( "cf", B3SOIDD_MOD_CF, IF_REAL, "Fringe capacitance parameter"), +IOP( "clc", B3SOIDD_MOD_CLC, IF_REAL, "Vdsat parameter for C-V model"), +IOP( "cle", B3SOIDD_MOD_CLE, IF_REAL, "Vdsat parameter for C-V model"), +IOP( "dwc", B3SOIDD_MOD_DWC, IF_REAL, "Delta W for C-V model"), +IOP( "dlc", B3SOIDD_MOD_DLC, IF_REAL, "Delta L for C-V model"), + +IOP( "alpha0", B3SOIDD_MOD_ALPHA0, IF_REAL, "substrate current model parameter"), +IOP( "alpha1", B3SOIDD_MOD_ALPHA1, IF_REAL, "substrate current model parameter"), +IOP( "beta0", B3SOIDD_MOD_BETA0, IF_REAL, "substrate current model parameter"), + +IOP( "noia", B3SOIDD_MOD_NOIA, IF_REAL, "Flicker noise parameter"), +IOP( "noib", B3SOIDD_MOD_NOIB, IF_REAL, "Flicker noise parameter"), +IOP( "noic", B3SOIDD_MOD_NOIC, IF_REAL, "Flicker noise parameter"), +IOP( "em", B3SOIDD_MOD_EM, IF_REAL, "Flicker noise parameter"), +IOP( "ef", B3SOIDD_MOD_EF, IF_REAL, "Flicker noise frequency exponent"), +IOP( "af", B3SOIDD_MOD_AF, IF_REAL, "Flicker noise exponent"), +IOP( "kf", B3SOIDD_MOD_KF, IF_REAL, "Flicker noise coefficient"), +IOP( "noif", B3SOIDD_MOD_NOIF, IF_REAL, "Floating body excess noise ideality factor"), + +/* Added for binning - START */ +/* Length Dependence */ +IOP( "lnch", B3SOIDD_MOD_LNPEAK, IF_REAL, "Length dependence of nch"), +IOP( "lnsub", B3SOIDD_MOD_LNSUB, IF_REAL, "Length dependence of nsub"), +IOP( "lngate", B3SOIDD_MOD_LNGATE, IF_REAL, "Length dependence of ngate"), +IOP( "lvth0", B3SOIDD_MOD_LVTH0, IF_REAL,"Length dependence of vto"), +IOP( "lk1", B3SOIDD_MOD_LK1, IF_REAL, "Length dependence of k1"), +IOP( "lk2", B3SOIDD_MOD_LK2, IF_REAL, "Length dependence of k2"), +IOP( "lk3", B3SOIDD_MOD_LK3, IF_REAL, "Length dependence of k3"), +IOP( "lk3b", B3SOIDD_MOD_LK3B, IF_REAL, "Length dependence of k3b"), +IOP( "lvbsa", B3SOIDD_MOD_LVBSA, IF_REAL, "Length dependence of vbsa"), +IOP( "ldelp", B3SOIDD_MOD_LDELP, IF_REAL, "Length dependence of delp"), +IOP( "lkb1", B3SOIDD_MOD_LKB1, IF_REAL, "Length dependence of kb1"), +IOP( "lkb3", B3SOIDD_MOD_LKB3, IF_REAL, "Length dependence of kb3"), +IOP( "ldvbd0", B3SOIDD_MOD_LDVBD0, IF_REAL, "Length dependence of dvbd0"), +IOP( "ldvbd1", B3SOIDD_MOD_LDVBD1, IF_REAL, "Length dependence of dvbd1"), +IOP( "lw0", B3SOIDD_MOD_LW0, IF_REAL, "Length dependence of w0"), +IOP( "lnlx", B3SOIDD_MOD_LNLX, IF_REAL, "Length dependence of nlx"), +IOP( "ldvt0", B3SOIDD_MOD_LDVT0, IF_REAL, "Length dependence of dvt0"), +IOP( "ldvt1", B3SOIDD_MOD_LDVT1, IF_REAL, "Length dependence of dvt1"), +IOP( "ldvt2", B3SOIDD_MOD_LDVT2, IF_REAL, "Length dependence of dvt2"), +IOP( "ldvt0w", B3SOIDD_MOD_LDVT0W, IF_REAL, "Length dependence of dvt0w"), +IOP( "ldvt1w", B3SOIDD_MOD_LDVT1W, IF_REAL, "Length dependence of dvt1w"), +IOP( "ldvt2w", B3SOIDD_MOD_LDVT2W, IF_REAL, "Length dependence of dvt2w"), +IOP( "lu0", B3SOIDD_MOD_LU0, IF_REAL, "Length dependence of u0"), +IOP( "lua", B3SOIDD_MOD_LUA, IF_REAL, "Length dependence of ua"), +IOP( "lub", B3SOIDD_MOD_LUB, IF_REAL, "Length dependence of ub"), +IOP( "luc", B3SOIDD_MOD_LUC, IF_REAL, "Length dependence of uc"), +IOP( "lvsat", B3SOIDD_MOD_LVSAT, IF_REAL, "Length dependence of vsat"), +IOP( "la0", B3SOIDD_MOD_LA0, IF_REAL, "Length dependence of a0"), +IOP( "lags", B3SOIDD_MOD_LAGS, IF_REAL, "Length dependence of ags"), +IOP( "lb0", B3SOIDD_MOD_LB0, IF_REAL, "Length dependence of b0"), +IOP( "lb1", B3SOIDD_MOD_LB1, IF_REAL, "Length dependence of b1"), +IOP( "lketa", B3SOIDD_MOD_LKETA, IF_REAL, "Length dependence of keta"), +IOP( "labp", B3SOIDD_MOD_LABP, IF_REAL, "Length dependence of abp"), +IOP( "lmxc", B3SOIDD_MOD_LMXC, IF_REAL, "Length dependence of mxc"), +IOP( "ladice0", B3SOIDD_MOD_LADICE0, IF_REAL, "Length dependence of adice0"), +IOP( "la1", B3SOIDD_MOD_LA1, IF_REAL, "Length dependence of a1"), +IOP( "la2", B3SOIDD_MOD_LA2, IF_REAL, "Length dependence of a2"), +IOP( "lrdsw", B3SOIDD_MOD_LRDSW, IF_REAL, "Length dependence of rdsw "), +IOP( "lprwb", B3SOIDD_MOD_LPRWB, IF_REAL, "Length dependence of prwb "), +IOP( "lprwg", B3SOIDD_MOD_LPRWG, IF_REAL, "Length dependence of prwg "), +IOP( "lwr", B3SOIDD_MOD_LWR, IF_REAL, "Length dependence of wr"), +IOP( "lnfactor", B3SOIDD_MOD_LNFACTOR, IF_REAL, "Length dependence of nfactor"), +IOP( "ldwg", B3SOIDD_MOD_LDWG, IF_REAL, "Length dependence of dwg"), +IOP( "ldwb", B3SOIDD_MOD_LDWB, IF_REAL, "Length dependence of dwb"), +IOP( "lvoff", B3SOIDD_MOD_LVOFF, IF_REAL, "Length dependence of voff"), +IOP( "leta0", B3SOIDD_MOD_LETA0, IF_REAL, "Length dependence of eta0"), +IOP( "letab", B3SOIDD_MOD_LETAB, IF_REAL, "Length dependence of etab"), +IOP( "ldsub", B3SOIDD_MOD_LDSUB, IF_REAL, "Length dependence of dsub"), +IOP( "lcit", B3SOIDD_MOD_LCIT, IF_REAL, "Length dependence of cit"), +IOP( "lcdsc", B3SOIDD_MOD_LCDSC, IF_REAL, "Length dependence of cdsc"), +IOP( "lcdscb", B3SOIDD_MOD_LCDSCB, IF_REAL, "Length dependence of cdscb"), +IOP( "lcdscd", B3SOIDD_MOD_LCDSCD, IF_REAL, "Length dependence of cdscd"), +IOP( "lpclm", B3SOIDD_MOD_LPCLM, IF_REAL, "Length dependence of pclm"), +IOP( "lpdiblc1", B3SOIDD_MOD_LPDIBL1, IF_REAL, "Length dependence of pdiblc1"), +IOP( "lpdiblc2", B3SOIDD_MOD_LPDIBL2, IF_REAL, "Length dependence of pdiblc2"), +IOP( "lpdiblcb", B3SOIDD_MOD_LPDIBLB, IF_REAL, "Length dependence of pdiblcb"), +IOP( "ldrout", B3SOIDD_MOD_LDROUT, IF_REAL, "Length dependence of drout"), +IOP( "lpvag", B3SOIDD_MOD_LPVAG, IF_REAL, "Length dependence of pvag"), +IOP( "ldelta", B3SOIDD_MOD_LDELTA, IF_REAL, "Length dependence of delta"), +IOP( "laii", B3SOIDD_MOD_LAII, IF_REAL, "Length dependence of aii"), +IOP( "lbii", B3SOIDD_MOD_LBII, IF_REAL, "Length dependence of bii"), +IOP( "lcii", B3SOIDD_MOD_LCII, IF_REAL, "Length dependence of cii"), +IOP( "ldii", B3SOIDD_MOD_LDII, IF_REAL, "Length dependence of dii"), +IOP( "lalpha0", B3SOIDD_MOD_LALPHA0, IF_REAL, "Length dependence of alpha0"), +IOP( "lalpha1", B3SOIDD_MOD_LALPHA1, IF_REAL, "Length dependence of alpha1"), +IOP( "lbeta0", B3SOIDD_MOD_LBETA0, IF_REAL, "Length dependence of beta0"), +IOP( "lagidl", B3SOIDD_MOD_LAGIDL, IF_REAL, "Length dependence of agidl"), +IOP( "lbgidl", B3SOIDD_MOD_LBGIDL, IF_REAL, "Length dependence of bgidl"), +IOP( "lngidl", B3SOIDD_MOD_LNGIDL, IF_REAL, "Length dependence of ngidl"), +IOP( "lntun", B3SOIDD_MOD_LNTUN, IF_REAL, "Length dependence of ntun"), +IOP( "lndiode", B3SOIDD_MOD_LNDIODE, IF_REAL, "Length dependence of ndiode"), +IOP( "lisbjt", B3SOIDD_MOD_LISBJT, IF_REAL, "Length dependence of isbjt"), +IOP( "lisdif", B3SOIDD_MOD_LISDIF, IF_REAL, "Length dependence of isdif"), +IOP( "lisrec", B3SOIDD_MOD_LISREC, IF_REAL, "Length dependence of isrec"), +IOP( "listun", B3SOIDD_MOD_LISTUN, IF_REAL, "Length dependence of istun"), +IOP( "ledl", B3SOIDD_MOD_LEDL, IF_REAL, "Length dependence of edl"), +IOP( "lkbjt1", B3SOIDD_MOD_LKBJT1, IF_REAL, "Length dependence of kbjt1"), +IOP( "lvsdfb", B3SOIDD_MOD_LVSDFB, IF_REAL, "Length dependence of vsdfb"), +IOP( "lvsdth", B3SOIDD_MOD_LVSDTH, IF_REAL, "Length dependence of vsdth"), +/* Width Dependence */ +IOP( "wnch", B3SOIDD_MOD_WNPEAK, IF_REAL, "Width dependence of nch"), +IOP( "wnsub", B3SOIDD_MOD_WNSUB, IF_REAL, "Width dependence of nsub"), +IOP( "wngate", B3SOIDD_MOD_WNGATE, IF_REAL, "Width dependence of ngate"), +IOP( "wvth0", B3SOIDD_MOD_WVTH0, IF_REAL,"Width dependence of vto"), +IOP( "wk1", B3SOIDD_MOD_WK1, IF_REAL, "Width dependence of k1"), +IOP( "wk2", B3SOIDD_MOD_WK2, IF_REAL, "Width dependence of k2"), +IOP( "wk3", B3SOIDD_MOD_WK3, IF_REAL, "Width dependence of k3"), +IOP( "wk3b", B3SOIDD_MOD_WK3B, IF_REAL, "Width dependence of k3b"), +IOP( "wvbsa", B3SOIDD_MOD_WVBSA, IF_REAL, "Width dependence of vbsa"), +IOP( "wdelp", B3SOIDD_MOD_WDELP, IF_REAL, "Width dependence of delp"), +IOP( "wkb1", B3SOIDD_MOD_WKB1, IF_REAL, "Width dependence of kb1"), +IOP( "wkb3", B3SOIDD_MOD_WKB3, IF_REAL, "Width dependence of kb3"), +IOP( "wdvbd0", B3SOIDD_MOD_WDVBD0, IF_REAL, "Width dependence of dvbd0"), +IOP( "wdvbd1", B3SOIDD_MOD_WDVBD1, IF_REAL, "Width dependence of dvbd1"), +IOP( "ww0", B3SOIDD_MOD_WW0, IF_REAL, "Width dependence of w0"), +IOP( "wnlx", B3SOIDD_MOD_WNLX, IF_REAL, "Width dependence of nlx"), +IOP( "wdvt0", B3SOIDD_MOD_WDVT0, IF_REAL, "Width dependence of dvt0"), +IOP( "wdvt1", B3SOIDD_MOD_WDVT1, IF_REAL, "Width dependence of dvt1"), +IOP( "wdvt2", B3SOIDD_MOD_WDVT2, IF_REAL, "Width dependence of dvt2"), +IOP( "wdvt0w", B3SOIDD_MOD_WDVT0W, IF_REAL, "Width dependence of dvt0w"), +IOP( "wdvt1w", B3SOIDD_MOD_WDVT1W, IF_REAL, "Width dependence of dvt1w"), +IOP( "wdvt2w", B3SOIDD_MOD_WDVT2W, IF_REAL, "Width dependence of dvt2w"), +IOP( "wu0", B3SOIDD_MOD_WU0, IF_REAL, "Width dependence of u0"), +IOP( "wua", B3SOIDD_MOD_WUA, IF_REAL, "Width dependence of ua"), +IOP( "wub", B3SOIDD_MOD_WUB, IF_REAL, "Width dependence of ub"), +IOP( "wuc", B3SOIDD_MOD_WUC, IF_REAL, "Width dependence of uc"), +IOP( "wvsat", B3SOIDD_MOD_WVSAT, IF_REAL, "Width dependence of vsat"), +IOP( "wa0", B3SOIDD_MOD_WA0, IF_REAL, "Width dependence of a0"), +IOP( "wags", B3SOIDD_MOD_WAGS, IF_REAL, "Width dependence of ags"), +IOP( "wb0", B3SOIDD_MOD_WB0, IF_REAL, "Width dependence of b0"), +IOP( "wb1", B3SOIDD_MOD_WB1, IF_REAL, "Width dependence of b1"), +IOP( "wketa", B3SOIDD_MOD_WKETA, IF_REAL, "Width dependence of keta"), +IOP( "wabp", B3SOIDD_MOD_WABP, IF_REAL, "Width dependence of abp"), +IOP( "wmxc", B3SOIDD_MOD_WMXC, IF_REAL, "Width dependence of mxc"), +IOP( "wadice0", B3SOIDD_MOD_WADICE0, IF_REAL, "Width dependence of adice0"), +IOP( "wa1", B3SOIDD_MOD_WA1, IF_REAL, "Width dependence of a1"), +IOP( "wa2", B3SOIDD_MOD_WA2, IF_REAL, "Width dependence of a2"), +IOP( "wrdsw", B3SOIDD_MOD_WRDSW, IF_REAL, "Width dependence of rdsw "), +IOP( "wprwb", B3SOIDD_MOD_WPRWB, IF_REAL, "Width dependence of prwb "), +IOP( "wprwg", B3SOIDD_MOD_WPRWG, IF_REAL, "Width dependence of prwg "), +IOP( "wwr", B3SOIDD_MOD_WWR, IF_REAL, "Width dependence of wr"), +IOP( "wnfactor", B3SOIDD_MOD_WNFACTOR, IF_REAL, "Width dependence of nfactor"), +IOP( "wdwg", B3SOIDD_MOD_WDWG, IF_REAL, "Width dependence of dwg"), +IOP( "wdwb", B3SOIDD_MOD_WDWB, IF_REAL, "Width dependence of dwb"), +IOP( "wvoff", B3SOIDD_MOD_WVOFF, IF_REAL, "Width dependence of voff"), +IOP( "weta0", B3SOIDD_MOD_WETA0, IF_REAL, "Width dependence of eta0"), +IOP( "wetab", B3SOIDD_MOD_WETAB, IF_REAL, "Width dependence of etab"), +IOP( "wdsub", B3SOIDD_MOD_WDSUB, IF_REAL, "Width dependence of dsub"), +IOP( "wcit", B3SOIDD_MOD_WCIT, IF_REAL, "Width dependence of cit"), +IOP( "wcdsc", B3SOIDD_MOD_WCDSC, IF_REAL, "Width dependence of cdsc"), +IOP( "wcdscb", B3SOIDD_MOD_WCDSCB, IF_REAL, "Width dependence of cdscb"), +IOP( "wcdscd", B3SOIDD_MOD_WCDSCD, IF_REAL, "Width dependence of cdscd"), +IOP( "wpclm", B3SOIDD_MOD_WPCLM, IF_REAL, "Width dependence of pclm"), +IOP( "wpdiblc1", B3SOIDD_MOD_WPDIBL1, IF_REAL, "Width dependence of pdiblc1"), +IOP( "wpdiblc2", B3SOIDD_MOD_WPDIBL2, IF_REAL, "Width dependence of pdiblc2"), +IOP( "wpdiblcb", B3SOIDD_MOD_WPDIBLB, IF_REAL, "Width dependence of pdiblcb"), +IOP( "wdrout", B3SOIDD_MOD_WDROUT, IF_REAL, "Width dependence of drout"), +IOP( "wpvag", B3SOIDD_MOD_WPVAG, IF_REAL, "Width dependence of pvag"), +IOP( "wdelta", B3SOIDD_MOD_WDELTA, IF_REAL, "Width dependence of delta"), +IOP( "waii", B3SOIDD_MOD_WAII, IF_REAL, "Width dependence of aii"), +IOP( "wbii", B3SOIDD_MOD_WBII, IF_REAL, "Width dependence of bii"), +IOP( "wcii", B3SOIDD_MOD_WCII, IF_REAL, "Width dependence of cii"), +IOP( "wdii", B3SOIDD_MOD_WDII, IF_REAL, "Width dependence of dii"), +IOP( "walpha0", B3SOIDD_MOD_WALPHA0, IF_REAL, "Width dependence of alpha0"), +IOP( "walpha1", B3SOIDD_MOD_WALPHA1, IF_REAL, "Width dependence of alpha1"), +IOP( "wbeta0", B3SOIDD_MOD_WBETA0, IF_REAL, "Width dependence of beta0"), +IOP( "wagidl", B3SOIDD_MOD_WAGIDL, IF_REAL, "Width dependence of agidl"), +IOP( "wbgidl", B3SOIDD_MOD_WBGIDL, IF_REAL, "Width dependence of bgidl"), +IOP( "wngidl", B3SOIDD_MOD_WNGIDL, IF_REAL, "Width dependence of ngidl"), +IOP( "wntun", B3SOIDD_MOD_WNTUN, IF_REAL, "Width dependence of ntun"), +IOP( "wndiode", B3SOIDD_MOD_WNDIODE, IF_REAL, "Width dependence of ndiode"), +IOP( "wisbjt", B3SOIDD_MOD_WISBJT, IF_REAL, "Width dependence of isbjt"), +IOP( "wisdif", B3SOIDD_MOD_WISDIF, IF_REAL, "Width dependence of isdif"), +IOP( "wisrec", B3SOIDD_MOD_WISREC, IF_REAL, "Width dependence of isrec"), +IOP( "wistun", B3SOIDD_MOD_WISTUN, IF_REAL, "Width dependence of istun"), +IOP( "wedl", B3SOIDD_MOD_WEDL, IF_REAL, "Width dependence of edl"), +IOP( "wkbjt1", B3SOIDD_MOD_WKBJT1, IF_REAL, "Width dependence of kbjt1"), +IOP( "wvsdfb", B3SOIDD_MOD_WVSDFB, IF_REAL, "Width dependence of vsdfb"), +IOP( "wvsdth", B3SOIDD_MOD_WVSDTH, IF_REAL, "Width dependence of vsdth"), +/* Cross-term Dependence */ +IOP( "pnch", B3SOIDD_MOD_PNPEAK, IF_REAL, "Cross-term dependence of nch"), +IOP( "pnsub", B3SOIDD_MOD_PNSUB, IF_REAL, "Cross-term dependence of nsub"), +IOP( "pngate", B3SOIDD_MOD_PNGATE, IF_REAL, "Cross-term dependence of ngate"), +IOP( "pvth0", B3SOIDD_MOD_PVTH0, IF_REAL,"Cross-term dependence of vto"), +IOP( "pk1", B3SOIDD_MOD_PK1, IF_REAL, "Cross-term dependence of k1"), +IOP( "pk2", B3SOIDD_MOD_PK2, IF_REAL, "Cross-term dependence of k2"), +IOP( "pk3", B3SOIDD_MOD_PK3, IF_REAL, "Cross-term dependence of k3"), +IOP( "pk3b", B3SOIDD_MOD_PK3B, IF_REAL, "Cross-term dependence of k3b"), +IOP( "pvbsa", B3SOIDD_MOD_PVBSA, IF_REAL, "Cross-term dependence of vbsa"), +IOP( "pdelp", B3SOIDD_MOD_PDELP, IF_REAL, "Cross-term dependence of delp"), +IOP( "pkb1", B3SOIDD_MOD_PKB1, IF_REAL, "Cross-term dependence of kb1"), +IOP( "pkb3", B3SOIDD_MOD_PKB3, IF_REAL, "Cross-term dependence of kb3"), +IOP( "pdvbd0", B3SOIDD_MOD_PDVBD0, IF_REAL, "Cross-term dependence of dvbd0"), +IOP( "pdvbd1", B3SOIDD_MOD_PDVBD1, IF_REAL, "Cross-term dependence of dvbd1"), +IOP( "pw0", B3SOIDD_MOD_PW0, IF_REAL, "Cross-term dependence of w0"), +IOP( "pnlx", B3SOIDD_MOD_PNLX, IF_REAL, "Cross-term dependence of nlx"), +IOP( "pdvt0", B3SOIDD_MOD_PDVT0, IF_REAL, "Cross-term dependence of dvt0"), +IOP( "pdvt1", B3SOIDD_MOD_PDVT1, IF_REAL, "Cross-term dependence of dvt1"), +IOP( "pdvt2", B3SOIDD_MOD_PDVT2, IF_REAL, "Cross-term dependence of dvt2"), +IOP( "pdvt0w", B3SOIDD_MOD_PDVT0W, IF_REAL, "Cross-term dependence of dvt0w"), +IOP( "pdvt1w", B3SOIDD_MOD_PDVT1W, IF_REAL, "Cross-term dependence of dvt1w"), +IOP( "pdvt2w", B3SOIDD_MOD_PDVT2W, IF_REAL, "Cross-term dependence of dvt2w"), +IOP( "pu0", B3SOIDD_MOD_PU0, IF_REAL, "Cross-term dependence of u0"), +IOP( "pua", B3SOIDD_MOD_PUA, IF_REAL, "Cross-term dependence of ua"), +IOP( "pub", B3SOIDD_MOD_PUB, IF_REAL, "Cross-term dependence of ub"), +IOP( "puc", B3SOIDD_MOD_PUC, IF_REAL, "Cross-term dependence of uc"), +IOP( "pvsat", B3SOIDD_MOD_PVSAT, IF_REAL, "Cross-term dependence of vsat"), +IOP( "pa0", B3SOIDD_MOD_PA0, IF_REAL, "Cross-term dependence of a0"), +IOP( "pags", B3SOIDD_MOD_PAGS, IF_REAL, "Cross-term dependence of ags"), +IOP( "pb0", B3SOIDD_MOD_PB0, IF_REAL, "Cross-term dependence of b0"), +IOP( "pb1", B3SOIDD_MOD_PB1, IF_REAL, "Cross-term dependence of b1"), +IOP( "pketa", B3SOIDD_MOD_PKETA, IF_REAL, "Cross-term dependence of keta"), +IOP( "pabp", B3SOIDD_MOD_PABP, IF_REAL, "Cross-term dependence of abp"), +IOP( "pmxc", B3SOIDD_MOD_PMXC, IF_REAL, "Cross-term dependence of mxc"), +IOP( "padice0", B3SOIDD_MOD_PADICE0, IF_REAL, "Cross-term dependence of adice0"), +IOP( "pa1", B3SOIDD_MOD_PA1, IF_REAL, "Cross-term dependence of a1"), +IOP( "pa2", B3SOIDD_MOD_PA2, IF_REAL, "Cross-term dependence of a2"), +IOP( "prdsw", B3SOIDD_MOD_PRDSW, IF_REAL, "Cross-term dependence of rdsw "), +IOP( "pprwb", B3SOIDD_MOD_PPRWB, IF_REAL, "Cross-term dependence of prwb "), +IOP( "pprwg", B3SOIDD_MOD_PPRWG, IF_REAL, "Cross-term dependence of prwg "), +IOP( "pwr", B3SOIDD_MOD_PWR, IF_REAL, "Cross-term dependence of wr"), +IOP( "pnfactor", B3SOIDD_MOD_PNFACTOR, IF_REAL, "Cross-term dependence of nfactor"), +IOP( "pdwg", B3SOIDD_MOD_PDWG, IF_REAL, "Cross-term dependence of dwg"), +IOP( "pdwb", B3SOIDD_MOD_PDWB, IF_REAL, "Cross-term dependence of dwb"), +IOP( "pvoff", B3SOIDD_MOD_PVOFF, IF_REAL, "Cross-term dependence of voff"), +IOP( "peta0", B3SOIDD_MOD_PETA0, IF_REAL, "Cross-term dependence of eta0"), +IOP( "petab", B3SOIDD_MOD_PETAB, IF_REAL, "Cross-term dependence of etab"), +IOP( "pdsub", B3SOIDD_MOD_PDSUB, IF_REAL, "Cross-term dependence of dsub"), +IOP( "pcit", B3SOIDD_MOD_PCIT, IF_REAL, "Cross-term dependence of cit"), +IOP( "pcdsc", B3SOIDD_MOD_PCDSC, IF_REAL, "Cross-term dependence of cdsc"), +IOP( "pcdscb", B3SOIDD_MOD_PCDSCB, IF_REAL, "Cross-term dependence of cdscb"), +IOP( "pcdscd", B3SOIDD_MOD_PCDSCD, IF_REAL, "Cross-term dependence of cdscd"), +IOP( "ppclm", B3SOIDD_MOD_PPCLM, IF_REAL, "Cross-term dependence of pclm"), +IOP( "ppdiblc1", B3SOIDD_MOD_PPDIBL1, IF_REAL, "Cross-term dependence of pdiblc1"), +IOP( "ppdiblc2", B3SOIDD_MOD_PPDIBL2, IF_REAL, "Cross-term dependence of pdiblc2"), +IOP( "ppdiblcb", B3SOIDD_MOD_PPDIBLB, IF_REAL, "Cross-term dependence of pdiblcb"), +IOP( "pdrout", B3SOIDD_MOD_PDROUT, IF_REAL, "Cross-term dependence of drout"), +IOP( "ppvag", B3SOIDD_MOD_PPVAG, IF_REAL, "Cross-term dependence of pvag"), +IOP( "pdelta", B3SOIDD_MOD_PDELTA, IF_REAL, "Cross-term dependence of delta"), +IOP( "paii", B3SOIDD_MOD_PAII, IF_REAL, "Cross-term dependence of aii"), +IOP( "pbii", B3SOIDD_MOD_PBII, IF_REAL, "Cross-term dependence of bii"), +IOP( "pcii", B3SOIDD_MOD_PCII, IF_REAL, "Cross-term dependence of cii"), +IOP( "pdii", B3SOIDD_MOD_PDII, IF_REAL, "Cross-term dependence of dii"), +IOP( "palpha0", B3SOIDD_MOD_PALPHA0, IF_REAL, "Cross-term dependence of alpha0"), +IOP( "palpha1", B3SOIDD_MOD_PALPHA1, IF_REAL, "Cross-term dependence of alpha1"), +IOP( "pbeta0", B3SOIDD_MOD_PBETA0, IF_REAL, "Cross-term dependence of beta0"), +IOP( "pagidl", B3SOIDD_MOD_PAGIDL, IF_REAL, "Cross-term dependence of agidl"), +IOP( "pbgidl", B3SOIDD_MOD_PBGIDL, IF_REAL, "Cross-term dependence of bgidl"), +IOP( "pngidl", B3SOIDD_MOD_PNGIDL, IF_REAL, "Cross-term dependence of ngidl"), +IOP( "pntun", B3SOIDD_MOD_PNTUN, IF_REAL, "Cross-term dependence of ntun"), +IOP( "pndiode", B3SOIDD_MOD_PNDIODE, IF_REAL, "Cross-term dependence of ndiode"), +IOP( "pisbjt", B3SOIDD_MOD_PISBJT, IF_REAL, "Cross-term dependence of isbjt"), +IOP( "pisdif", B3SOIDD_MOD_PISDIF, IF_REAL, "Cross-term dependence of isdif"), +IOP( "pisrec", B3SOIDD_MOD_PISREC, IF_REAL, "Cross-term dependence of isrec"), +IOP( "pistun", B3SOIDD_MOD_PISTUN, IF_REAL, "Cross-term dependence of istun"), +IOP( "pedl", B3SOIDD_MOD_PEDL, IF_REAL, "Cross-term dependence of edl"), +IOP( "pkbjt1", B3SOIDD_MOD_PKBJT1, IF_REAL, "Cross-term dependence of kbjt1"), +IOP( "pvsdfb", B3SOIDD_MOD_PVSDFB, IF_REAL, "Cross-term dependence of vsdfb"), +IOP( "pvsdth", B3SOIDD_MOD_PVSDTH, IF_REAL, "Cross-term dependence of vsdth"), +/* Added for binning - END */ + +IP( "nmos", B3SOIDD_MOD_NMOS, IF_FLAG, "Flag to indicate NMOS"), +IP( "pmos", B3SOIDD_MOD_PMOS, IF_FLAG, "Flag to indicate PMOS"), +}; + +char *B3SOIDDnames[] = { + "Drain", + "Gate", + "Source", + "Backgate", + "", + "Body", + "Temp", + "Charge", +}; + +int B3SOIDDnSize = NUMELEMS(B3SOIDDnames); +int B3SOIDDpTSize = NUMELEMS(B3SOIDDpTable); +int B3SOIDDmPTSize = NUMELEMS(B3SOIDDmPTable); +int B3SOIDDiSize = sizeof(B3SOIDDinstance); +int B3SOIDDmSize = sizeof(B3SOIDDmodel); + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddacld.c b/src/spicelib/devices/bsim3soi_dd/b3soiddacld.c new file mode 100644 index 000000000..6b18858e1 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddacld.c @@ -0,0 +1,462 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddacld.c 98/5/01 +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "b3soidddef.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIDDacLoad(inModel,ckt) +GENmodel *inModel; +register CKTcircuit *ckt; +{ +register B3SOIDDmodel *model = (B3SOIDDmodel*)inModel; +register B3SOIDDinstance *here; +register int selfheat; +double xcggb, xcgdb, xcgsb, xcgeb, xcgT; +double xcdgb, xcddb, xcdsb, xcdeb, xcdT; +double xcsgb, xcsdb, xcssb, xcseb, xcsT; +double xcbgb, xcbdb, xcbsb, xcbeb, xcbT; +double xcegb, xcedb, xcesb, xceeb, xceT; +double gdpr, gspr, gds; +double cggb, cgdb, cgsb, cgeb, cgT; +double cdgb, cddb, cdsb, cdeb, cdT; +double cbgb, cbdb, cbsb, cbeb, cbT; +double cegb, cedb, cesb, ceeb, ceT; +double GSoverlapCap, GDoverlapCap, GEoverlapCap, FwdSum, RevSum, Gm, Gmbs, Gme, GmT; +double omega; +double dxpart, sxpart; +double gbbg, gbbdp, gbbb, gbbe, gbbp, gbbsp, gbbT; +double gddpg, gddpdp, gddpsp, gddpb, gddpe, gddpT; +double gsspg, gsspdp, gsspsp, gsspb, gsspe, gsspT; +double gppg, gppdp, gppb, gppe, gppp, gppsp, gppT; +double xcTt, cTt, gcTt, gTtt, gTtg, gTtb, gTte, gTtdp, gTtsp; + +double Dum1, Dum2, Dum3, Dum4, Dum5; +FILE *fpdebug; + + omega = ckt->CKTomega; + for (; model != NULL; model = model->B3SOIDDnextModel) + { + + for (here = model->B3SOIDDinstances; here!= NULL; + here = here->B3SOIDDnextInstance) + { + selfheat = (model->B3SOIDDshMod == 1) && (here->B3SOIDDrth0 != 0.0); + if (here->B3SOIDDdebugMod > 2) + { + fpdebug = fopen("b3soiDDac.log", "a"); + fprintf(fpdebug, ".......omega=%.5e\n", omega); + } + if (here->B3SOIDDmode >= 0) + { Gm = here->B3SOIDDgm; + Gmbs = here->B3SOIDDgmbs; + Gme = here->B3SOIDDgme; + GmT = model->B3SOIDDtype * here->B3SOIDDgmT; + FwdSum = Gm + Gmbs + Gme; + RevSum = 0.0; + + cbgb = here->B3SOIDDcbgb; + cbsb = here->B3SOIDDcbsb; + cbdb = here->B3SOIDDcbdb; + cbeb = here->B3SOIDDcbeb; + cbT = model->B3SOIDDtype * here->B3SOIDDcbT; + + cegb = here->B3SOIDDcegb; + cesb = here->B3SOIDDcesb; + cedb = here->B3SOIDDcedb; + ceeb = here->B3SOIDDceeb; + ceT = model->B3SOIDDtype * here->B3SOIDDceT; + + cggb = here->B3SOIDDcggb; + cgsb = here->B3SOIDDcgsb; + cgdb = here->B3SOIDDcgdb; + cgeb = here->B3SOIDDcgeb; + cgT = model->B3SOIDDtype * here->B3SOIDDcgT; + + cdgb = here->B3SOIDDcdgb; + cdsb = here->B3SOIDDcdsb; + cddb = here->B3SOIDDcddb; + cdeb = here->B3SOIDDcdeb; + cdT = model->B3SOIDDtype * here->B3SOIDDcdT; + + cTt = here->pParam->B3SOIDDcth; + + gbbg = -here->B3SOIDDgbgs; + gbbdp = -here->B3SOIDDgbds; + gbbb = -here->B3SOIDDgbbs; + gbbe = -here->B3SOIDDgbes; + gbbp = -here->B3SOIDDgbps; + gbbT = -model->B3SOIDDtype * here->B3SOIDDgbT; + gbbsp = - ( gbbg + gbbdp + gbbb + gbbe + gbbp); + + gddpg = -here->B3SOIDDgjdg; + gddpdp = -here->B3SOIDDgjdd; + gddpb = -here->B3SOIDDgjdb; + gddpe = -here->B3SOIDDgjde; + gddpT = -model->B3SOIDDtype * here->B3SOIDDgjdT; + gddpsp = - ( gddpg + gddpdp + gddpb + gddpe); + + gsspg = -here->B3SOIDDgjsg; + gsspdp = -here->B3SOIDDgjsd; + gsspb = -here->B3SOIDDgjsb; + gsspe = 0.0; + gsspT = -model->B3SOIDDtype * here->B3SOIDDgjsT; + gsspsp = - (gsspg + gsspdp + gsspb + gsspe); + + gppg = -here->B3SOIDDgbpgs; + gppdp = -here->B3SOIDDgbpds; + gppb = -here->B3SOIDDgbpbs; + gppe = -here->B3SOIDDgbpes; + gppp = -here->B3SOIDDgbpps; + gppT = -model->B3SOIDDtype * here->B3SOIDDgbpT; + gppsp = - (gppg + gppdp + gppb + gppe + gppp); + + gTtg = here->B3SOIDDgtempg; + gTtb = here->B3SOIDDgtempb; + gTte = here->B3SOIDDgtempe; + gTtdp = here->B3SOIDDgtempd; + gTtt = here->B3SOIDDgtempT; + gTtsp = - (gTtg + gTtb + gTte + gTtdp); + + sxpart = 0.6; + dxpart = 0.4; + + } + else + { Gm = -here->B3SOIDDgm; + Gmbs = -here->B3SOIDDgmbs; + Gme = -here->B3SOIDDgme; + GmT = -model->B3SOIDDtype * here->B3SOIDDgmT; + FwdSum = 0.0; + RevSum = -Gm - Gmbs - Gme; + + cdgb = - (here->B3SOIDDcdgb + here->B3SOIDDcggb + here->B3SOIDDcbgb + + here->B3SOIDDcegb); + cdsb = - (here->B3SOIDDcddb + here->B3SOIDDcgdb + here->B3SOIDDcbdb + + here->B3SOIDDcedb); + cddb = - (here->B3SOIDDcdsb + here->B3SOIDDcgsb + here->B3SOIDDcbsb + + here->B3SOIDDcesb); + cdeb = - (here->B3SOIDDcdeb + here->B3SOIDDcgeb + here->B3SOIDDcbeb + + here->B3SOIDDceeb); + cdT = - model->B3SOIDDtype * (here->B3SOIDDcgT + here->B3SOIDDcbT + + here->B3SOIDDcdT + here->B3SOIDDceT); + + cegb = here->B3SOIDDcegb; + cesb = here->B3SOIDDcedb; + cedb = here->B3SOIDDcesb; + ceeb = here->B3SOIDDceeb; + ceT = model->B3SOIDDtype * here->B3SOIDDceT; + + cggb = here->B3SOIDDcggb; + cgsb = here->B3SOIDDcgdb; + cgdb = here->B3SOIDDcgsb; + cgeb = here->B3SOIDDcgeb; + cgT = model->B3SOIDDtype * here->B3SOIDDcgT; + + cbgb = here->B3SOIDDcbgb; + cbsb = here->B3SOIDDcbdb; + cbdb = here->B3SOIDDcbsb; + cbeb = here->B3SOIDDcbeb; + cbT = model->B3SOIDDtype * here->B3SOIDDcbT; + + cTt = here->pParam->B3SOIDDcth; + + gbbg = -here->B3SOIDDgbgs; + gbbb = -here->B3SOIDDgbbs; + gbbe = -here->B3SOIDDgbes; + gbbp = -here->B3SOIDDgbps; + gbbsp = -here->B3SOIDDgbds; + gbbT = -model->B3SOIDDtype * here->B3SOIDDgbT; + gbbdp = - ( gbbg + gbbsp + gbbb + gbbe + gbbp); + + gddpg = -here->B3SOIDDgjsg; + gddpsp = -here->B3SOIDDgjsd; + gddpb = -here->B3SOIDDgjsb; + gddpe = 0.0; + gddpT = -model->B3SOIDDtype * here->B3SOIDDgjsT; + gddpdp = - (gddpg + gddpsp + gddpb + gddpe); + + gsspg = -here->B3SOIDDgjdg; + gsspsp = -here->B3SOIDDgjdd; + gsspb = -here->B3SOIDDgjdb; + gsspe = -here->B3SOIDDgjde; + gsspT = -model->B3SOIDDtype * here->B3SOIDDgjdT; + gsspdp = - ( gsspg + gsspsp + gsspb + gsspe); + + gppg = -here->B3SOIDDgbpgs; + gppsp = -here->B3SOIDDgbpds; + gppb = -here->B3SOIDDgbpbs; + gppe = -here->B3SOIDDgbpes; + gppp = -here->B3SOIDDgbpps; + gppT = -model->B3SOIDDtype * here->B3SOIDDgbpT; + gppdp = - (gppg + gppsp + gppb + gppe + gppp); + + gTtt = here->B3SOIDDgtempT; + gTtg = here->B3SOIDDgtempg; + gTtb = here->B3SOIDDgtempb; + gTte = here->B3SOIDDgtempe; + gTtdp = here->B3SOIDDgtempd; + gTtsp = - (gTtt + gTtg + gTtb + gTte + gTtdp); + + gTtg = here->B3SOIDDgtempg; + gTtb = here->B3SOIDDgtempb; + gTte = here->B3SOIDDgtempe; + gTtsp = here->B3SOIDDgtempd; + gTtt = here->B3SOIDDgtempT; + gTtdp = - (gTtg + gTtb + gTte + gTtsp); + + sxpart = 0.6; + sxpart = 0.4; + dxpart = 0.6; + } + + gdpr=here->B3SOIDDdrainConductance; + gspr=here->B3SOIDDsourceConductance; + gds= here->B3SOIDDgds; + + GSoverlapCap = here->B3SOIDDcgso; + GDoverlapCap = here->B3SOIDDcgdo; + GEoverlapCap = here->pParam->B3SOIDDcgeo; + + xcegb = (cegb - GEoverlapCap) * omega; + xcedb = cedb * omega; + xcesb = cesb * omega; + xceeb = (ceeb + GEoverlapCap) * omega; + xceT = ceT * omega; + + xcggb = (cggb + GDoverlapCap + GSoverlapCap + GEoverlapCap) + * omega; + xcgdb = (cgdb - GDoverlapCap ) * omega; + xcgsb = (cgsb - GSoverlapCap) * omega; + xcgeb = (cgeb - GEoverlapCap) * omega; + xcgT = cgT * omega; + + xcdgb = (cdgb - GDoverlapCap) * omega; + xcddb = (cddb + GDoverlapCap) * omega; + xcdsb = cdsb * omega; + xcdeb = cdeb * omega; + xcdT = cdT * omega; + + xcsgb = -(cggb + cbgb + cdgb + cegb + GSoverlapCap) * omega; + xcsdb = -(cgdb + cbdb + cddb + cedb) * omega; + xcssb = (GSoverlapCap - (cgsb + cbsb + cdsb + cesb)) * omega; + xcseb = -(cgeb + cbeb + cdeb + ceeb) * omega; + xcsT = -(cgT + cbT + cdT + ceT) * omega; + + xcbgb = cbgb * omega; + xcbdb = cbdb * omega; + xcbsb = cbsb * omega; + xcbeb = cbeb * omega; + xcbT = cbT * omega; + + xcTt = cTt * omega; + + *(here->B3SOIDDEgPtr +1) += xcegb; + *(here->B3SOIDDEdpPtr +1) += xcedb; + *(here->B3SOIDDEspPtr +1) += xcesb; + *(here->B3SOIDDGePtr +1) += xcgeb; + *(here->B3SOIDDDPePtr +1) += xcdeb; + *(here->B3SOIDDSPePtr +1) += xcseb; + + *(here->B3SOIDDEePtr +1) += xceeb; + + *(here->B3SOIDDGgPtr +1) += xcggb; + *(here->B3SOIDDGdpPtr +1) += xcgdb; + *(here->B3SOIDDGspPtr +1) += xcgsb; + + *(here->B3SOIDDDPgPtr +1) += xcdgb; + *(here->B3SOIDDDPdpPtr +1) += xcddb; + *(here->B3SOIDDDPspPtr +1) += xcdsb; + + *(here->B3SOIDDSPgPtr +1) += xcsgb; + *(here->B3SOIDDSPdpPtr +1) += xcsdb; + *(here->B3SOIDDSPspPtr +1) += xcssb; + + *(here->B3SOIDDBePtr +1) += xcbeb; + *(here->B3SOIDDBgPtr +1) += xcbgb; + *(here->B3SOIDDBdpPtr +1) += xcbdb; + *(here->B3SOIDDBspPtr +1) += xcbsb; + + *(here->B3SOIDDEbPtr +1) -= xcegb + xcedb + xcesb + xceeb; + *(here->B3SOIDDGbPtr +1) -= xcggb + xcgdb + xcgsb + xcgeb; + *(here->B3SOIDDDPbPtr +1) -= xcdgb + xcddb + xcdsb + xcdeb; + *(here->B3SOIDDSPbPtr +1) -= xcsgb + xcsdb + xcssb + xcseb; + *(here->B3SOIDDBbPtr +1) -= xcbgb + xcbdb + xcbsb + xcbeb; + + if (selfheat) + { + *(here->B3SOIDDTemptempPtr + 1) += xcTt; + *(here->B3SOIDDDPtempPtr + 1) += xcdT; + *(here->B3SOIDDSPtempPtr + 1) += xcsT; + *(here->B3SOIDDBtempPtr + 1) += xcbT; + *(here->B3SOIDDEtempPtr + 1) += xceT; + *(here->B3SOIDDGtempPtr + 1) += xcgT; + } + + +if (here->B3SOIDDdebugMod > 3) +{ +fprintf(fpdebug, "Cbg+Cbs+Cbe = %.5e; Cbd = %.5e;\n", +(xcbgb+xcbsb+xcbeb)/omega, xcbdb/omega); +fprintf(fpdebug, "gbs = %.5e; gbd = %.5e\n", gbbsp, gbbdp); + + + fprintf(fpdebug, "AC condunctance...\n"); + fprintf(fpdebug, "Eg=%.5e; Edp=%.5e; Esp=%.5e;\nEb=%.5e; Ee=%.5e\n", +xcegb, xcedb, xcesb, -(xcegb+xcedb+xcesb+xceeb), xceeb); + fprintf(fpdebug, "Gg=%.5e; Gdp=%.5e; Gsp=%.5e;\nGb=%.5e; Ge=%.5e\n", +xcggb, xcgdb, xcgsb, -(xcggb+xcgdb+xcgsb+xcgeb), xcgeb); + fprintf(fpdebug, "Bg=%.5e; Bdp=%.5e; Bsp=%.5e;\nBb=%.5e; Be=%.5e\n", +xcbgb, xcbdb, xcbsb, -(xcbgb+xcbdb+xcbsb+xcbeb), xcbeb); + fprintf(fpdebug, "DPg=%.5e; DPdp=%.5e; DPsp=%.5e;\nDPb=%.5e; DPe=%.5e\n", +xcdgb, xcddb, xcdsb, -(xcdgb+xcddb+xcdsb+xcdeb), xcdeb); + fprintf(fpdebug, "SPg=%.5e; SPdp=%.5e; SPsp=%.5e;\nSPb=%.5e; SPe=%.5e\n", +xcsgb, xcsdb, xcssb, -(xcsgb+xcsdb+xcssb+xcseb), xcseb); +} + + + + *(here->B3SOIDDEgPtr) += 0.0; + *(here->B3SOIDDEdpPtr) += 0.0; + *(here->B3SOIDDEspPtr) += 0.0; + *(here->B3SOIDDGePtr) -= 0.0; + *(here->B3SOIDDDPePtr) += Gme + gddpe; + *(here->B3SOIDDSPePtr) += gsspe - Gme; + + *(here->B3SOIDDEePtr) += 0.0; + + *(here->B3SOIDDDPgPtr) += Gm + gddpg; + *(here->B3SOIDDDPdpPtr) += gdpr + gds + gddpdp + RevSum ; + *(here->B3SOIDDDPspPtr) -= gds + FwdSum - gddpsp; + *(here->B3SOIDDDPdPtr) -= gdpr; + + *(here->B3SOIDDSPgPtr) -= Gm - gsspg; + *(here->B3SOIDDSPdpPtr) -= gds + RevSum - gsspdp; + *(here->B3SOIDDSPspPtr) += gspr + gds + FwdSum + gsspsp; + *(here->B3SOIDDSPsPtr) -= gspr; + + *(here->B3SOIDDBePtr) += gbbe; + *(here->B3SOIDDBgPtr) += gbbg; + *(here->B3SOIDDBdpPtr) += gbbdp; + *(here->B3SOIDDBspPtr) += gbbsp; + *(here->B3SOIDDBbPtr) += gbbb; + *(here->B3SOIDDEbPtr) += 0.0; + *(here->B3SOIDDSPbPtr) -= Gmbs - gsspb; + *(here->B3SOIDDDPbPtr) -= (-gddpb - Gmbs); + + if (selfheat) + { + *(here->B3SOIDDDPtempPtr) += GmT + gddpT; + *(here->B3SOIDDSPtempPtr) += -GmT + gsspT; + *(here->B3SOIDDBtempPtr) += gbbT; + if (here->B3SOIDDbodyMod == 1) { + (*(here->B3SOIDDPtempPtr) += gppT); + } + + *(here->B3SOIDDTemptempPtr) += gTtt + 1/here->pParam->B3SOIDDrth; + *(here->B3SOIDDTempgPtr) += gTtg; + *(here->B3SOIDDTempbPtr) += gTtb; + *(here->B3SOIDDTempePtr) += gTte; + *(here->B3SOIDDTempdpPtr) += gTtdp; + *(here->B3SOIDDTempspPtr) += gTtsp; + } + +if (here->B3SOIDDdebugMod > 3) +{ + fprintf(fpdebug, "Static condunctance...\n"); + fprintf(fpdebug, "Gg=%.5e; Gdp=%.5e; Gsp=%.5e;\nGb=%.5e; Ge=%.5e\n", + *(here->B3SOIDDGgPtr), *(here->B3SOIDDGdpPtr), + *(here->B3SOIDDGspPtr), *(here->B3SOIDDGbPtr), + *(here->B3SOIDDGePtr)); + fprintf(fpdebug, "DPg=%.5e; DPdp=%.5e; DPsp=%.5e;\nDPb=%.5e; DPe=%.5e\n", + *(here->B3SOIDDDPgPtr), *(here->B3SOIDDDPdpPtr), + *(here->B3SOIDDDPspPtr), *(here->B3SOIDDDPbPtr), + *(here->B3SOIDDDPePtr)); + fprintf(fpdebug, "SPg=%.5e; SPdp=%.5e; SPsp=%.5e;\nSPb=%.5e; SPe=%.5e\n", + *(here->B3SOIDDSPgPtr), *(here->B3SOIDDSPdpPtr), + *(here->B3SOIDDSPspPtr), *(here->B3SOIDDSPbPtr), + *(here->B3SOIDDSPePtr)); + fprintf(fpdebug, "Bg=%.5e; Bdp=%.5e; Bsp=%.5e;\nBb=%.5e; Be=%.5e\n", +gbbg, gbbdp, gbbsp, gbbb, gbbe); +} + + *(here->B3SOIDDDdPtr) += gdpr; + *(here->B3SOIDDDdpPtr) -= gdpr; + *(here->B3SOIDDSsPtr) += gspr; + *(here->B3SOIDDSspPtr) -= gspr; + + + if (here->B3SOIDDbodyMod == 1) { + (*(here->B3SOIDDBpPtr) -= gppp); + (*(here->B3SOIDDPbPtr) += gppb); + (*(here->B3SOIDDPpPtr) += gppp); + (*(here->B3SOIDDPgPtr) += gppg); + (*(here->B3SOIDDPdpPtr) += gppdp); + (*(here->B3SOIDDPspPtr) += gppsp); + (*(here->B3SOIDDPePtr) += gppe); + } + if (here->B3SOIDDdebugMod > 1) + { + *(here->B3SOIDDVbsPtr) += 1; + *(here->B3SOIDDIdsPtr) += 1; + *(here->B3SOIDDIcPtr) += 1; + *(here->B3SOIDDIbsPtr) += 1; + *(here->B3SOIDDIbdPtr) += 1; + *(here->B3SOIDDIiiPtr) += 1; + *(here->B3SOIDDIgidlPtr) += 1; + *(here->B3SOIDDItunPtr) += 1; + *(here->B3SOIDDIbpPtr) += 1; + *(here->B3SOIDDAbeffPtr) += 1; + *(here->B3SOIDDVbs0effPtr) += 1; + *(here->B3SOIDDVbseffPtr) += 1; + *(here->B3SOIDDXcPtr) += 1; + *(here->B3SOIDDCbgPtr) += 1; + *(here->B3SOIDDCbbPtr) += 1; + *(here->B3SOIDDCbdPtr) += 1; + *(here->B3SOIDDqbPtr) += 1; + *(here->B3SOIDDQbfPtr) += 1; + *(here->B3SOIDDQjsPtr) += 1; + *(here->B3SOIDDQjdPtr) += 1; + + /* clean up last */ + *(here->B3SOIDDGmPtr) += 1; + *(here->B3SOIDDGmbsPtr) += 1; + *(here->B3SOIDDGdsPtr) += 1; + *(here->B3SOIDDGmePtr) += 1; + *(here->B3SOIDDVbs0teffPtr) += 1; + *(here->B3SOIDDVgsteffPtr) += 1; + *(here->B3SOIDDCbePtr) += 1; + *(here->B3SOIDDVthPtr) += 1; + *(here->B3SOIDDXcsatPtr) += 1; + *(here->B3SOIDDVdscvPtr) += 1; + *(here->B3SOIDDVcscvPtr) += 1; + *(here->B3SOIDDQaccPtr) += 1; + *(here->B3SOIDDQsub0Ptr) += 1; + *(here->B3SOIDDQsubs1Ptr) += 1; + *(here->B3SOIDDQsubs2Ptr) += 1; + *(here->B3SOIDDqgPtr) += 1; + *(here->B3SOIDDqdPtr) += 1; + *(here->B3SOIDDqePtr) += 1; + *(here->B3SOIDDDum1Ptr) += 1; + *(here->B3SOIDDDum2Ptr) += 1; + *(here->B3SOIDDDum3Ptr) += 1; + *(here->B3SOIDDDum4Ptr) += 1; + *(here->B3SOIDDDum5Ptr) += 1; + } + + if (here->B3SOIDDdebugMod > 2) + fclose(fpdebug); + } + } + return(OK); +} + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddask.c b/src/spicelib/devices/bsim3soi_dd/b3soiddask.c new file mode 100644 index 000000000..b3bd25047 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddask.c @@ -0,0 +1,215 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiask.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "ifsim.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "b3soidddef.h" +#include "sperror.h" +#include "suffix.h" + +int +B3SOIDDask(ckt,inst,which,value,select) +CKTcircuit *ckt; +GENinstance *inst; +int which; +IFvalue *value; +IFvalue *select; +{ +B3SOIDDinstance *here = (B3SOIDDinstance*)inst; + + switch(which) + { case B3SOIDD_L: + value->rValue = here->B3SOIDDl; + return(OK); + case B3SOIDD_W: + value->rValue = here->B3SOIDDw; + return(OK); + case B3SOIDD_AS: + value->rValue = here->B3SOIDDsourceArea; + return(OK); + case B3SOIDD_AD: + value->rValue = here->B3SOIDDdrainArea; + return(OK); + case B3SOIDD_PS: + value->rValue = here->B3SOIDDsourcePerimeter; + return(OK); + case B3SOIDD_PD: + value->rValue = here->B3SOIDDdrainPerimeter; + return(OK); + case B3SOIDD_NRS: + value->rValue = here->B3SOIDDsourceSquares; + return(OK); + case B3SOIDD_NRD: + value->rValue = here->B3SOIDDdrainSquares; + return(OK); + case B3SOIDD_OFF: + value->rValue = here->B3SOIDDoff; + return(OK); + case B3SOIDD_BJTOFF: + value->iValue = here->B3SOIDDbjtoff; + return(OK); + case B3SOIDD_RTH0: + value->rValue = here->B3SOIDDrth0; + return(OK); + case B3SOIDD_CTH0: + value->rValue = here->B3SOIDDcth0; + return(OK); + case B3SOIDD_NRB: + value->rValue = here->B3SOIDDbodySquares; + return(OK); + case B3SOIDD_IC_VBS: + value->rValue = here->B3SOIDDicVBS; + return(OK); + case B3SOIDD_IC_VDS: + value->rValue = here->B3SOIDDicVDS; + return(OK); + case B3SOIDD_IC_VGS: + value->rValue = here->B3SOIDDicVGS; + return(OK); + case B3SOIDD_IC_VES: + value->rValue = here->B3SOIDDicVES; + return(OK); + case B3SOIDD_IC_VPS: + value->rValue = here->B3SOIDDicVPS; + return(OK); + case B3SOIDD_DNODE: + value->iValue = here->B3SOIDDdNode; + return(OK); + case B3SOIDD_GNODE: + value->iValue = here->B3SOIDDgNode; + return(OK); + case B3SOIDD_SNODE: + value->iValue = here->B3SOIDDsNode; + return(OK); + case B3SOIDD_BNODE: + value->iValue = here->B3SOIDDbNode; + return(OK); + case B3SOIDD_ENODE: + value->iValue = here->B3SOIDDeNode; + return(OK); + case B3SOIDD_DNODEPRIME: + value->iValue = here->B3SOIDDdNodePrime; + return(OK); + case B3SOIDD_SNODEPRIME: + value->iValue = here->B3SOIDDsNodePrime; + return(OK); + case B3SOIDD_SOURCECONDUCT: + value->rValue = here->B3SOIDDsourceConductance; + return(OK); + case B3SOIDD_DRAINCONDUCT: + value->rValue = here->B3SOIDDdrainConductance; + return(OK); + case B3SOIDD_VBD: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDvbd); + return(OK); + case B3SOIDD_VBS: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDvbs); + return(OK); + case B3SOIDD_VGS: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDvgs); + return(OK); + case B3SOIDD_VES: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDves); + return(OK); + case B3SOIDD_VDS: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDvds); + return(OK); + case B3SOIDD_CD: + value->rValue = here->B3SOIDDcd; + return(OK); + case B3SOIDD_CBS: + value->rValue = here->B3SOIDDcjs; + return(OK); + case B3SOIDD_CBD: + value->rValue = here->B3SOIDDcjd; + return(OK); + case B3SOIDD_GM: + value->rValue = here->B3SOIDDgm; + return(OK); + case B3SOIDD_GMID: + value->rValue = here->B3SOIDDgm/here->B3SOIDDcd; + return(OK); + case B3SOIDD_GDS: + value->rValue = here->B3SOIDDgds; + return(OK); + case B3SOIDD_GMBS: + value->rValue = here->B3SOIDDgmbs; + return(OK); + case B3SOIDD_GBD: + value->rValue = here->B3SOIDDgjdb; + return(OK); + case B3SOIDD_GBS: + value->rValue = here->B3SOIDDgjsb; + return(OK); + case B3SOIDD_QB: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDqb); + return(OK); + case B3SOIDD_CQB: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDcqb); + return(OK); + case B3SOIDD_QG: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDqg); + return(OK); + case B3SOIDD_CQG: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDcqg); + return(OK); + case B3SOIDD_QD: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDqd); + return(OK); + case B3SOIDD_CQD: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDcqd); + return(OK); + case B3SOIDD_CGG: + value->rValue = here->B3SOIDDcggb; + return(OK); + case B3SOIDD_CGD: + value->rValue = here->B3SOIDDcgdb; + return(OK); + case B3SOIDD_CGS: + value->rValue = here->B3SOIDDcgsb; + return(OK); + case B3SOIDD_CDG: + value->rValue = here->B3SOIDDcdgb; + return(OK); + case B3SOIDD_CDD: + value->rValue = here->B3SOIDDcddb; + return(OK); + case B3SOIDD_CDS: + value->rValue = here->B3SOIDDcdsb; + return(OK); + case B3SOIDD_CBG: + value->rValue = here->B3SOIDDcbgb; + return(OK); + case B3SOIDD_CBDB: + value->rValue = here->B3SOIDDcbdb; + return(OK); + case B3SOIDD_CBSB: + value->rValue = here->B3SOIDDcbsb; + return(OK); + case B3SOIDD_VON: + value->rValue = here->B3SOIDDvon; + return(OK); + case B3SOIDD_VDSAT: + value->rValue = here->B3SOIDDvdsat; + return(OK); + case B3SOIDD_QBS: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDqbs); + return(OK); + case B3SOIDD_QBD: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDqbd); + return(OK); + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddcheck.c b/src/spicelib/devices/bsim3soi_dd/b3soiddcheck.c new file mode 100644 index 000000000..74c5b7099 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddcheck.c @@ -0,0 +1,504 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddcheck.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "b3soidddef.h" +#include "trandefs.h" +#include "const.h" +#include "sperror.h" +#include "devdefs.h" +#include "suffix.h" + +int +B3SOIDDcheckModel(model, here, ckt) +register B3SOIDDmodel *model; +register B3SOIDDinstance *here; +CKTcircuit *ckt; +{ +struct b3soiddSizeDependParam *pParam; +int Fatal_Flag = 0; +FILE *fplog; + + if ((fplog = fopen("b3soiddv1check.log", "w")) != NULL) + { pParam = here->pParam; + fprintf(fplog, "B3SOIDDV3 Parameter Check\n"); + fprintf(fplog, "Model = %s\n", model->B3SOIDDmodName); + fprintf(fplog, "W = %g, L = %g\n", here->B3SOIDDw, here->B3SOIDDl); + + + if (pParam->B3SOIDDnlx < -pParam->B3SOIDDleff) + { fprintf(fplog, "Fatal: Nlx = %g is less than -Leff.\n", + pParam->B3SOIDDnlx); + printf("Fatal: Nlx = %g is less than -Leff.\n", + pParam->B3SOIDDnlx); + Fatal_Flag = 1; + } + + if (model->B3SOIDDtox <= 0.0) + { fprintf(fplog, "Fatal: Tox = %g is not positive.\n", + model->B3SOIDDtox); + printf("Fatal: Tox = %g is not positive.\n", model->B3SOIDDtox); + Fatal_Flag = 1; + } + + if (model->B3SOIDDtbox <= 0.0) + { fprintf(fplog, "Fatal: Tbox = %g is not positive.\n", + model->B3SOIDDtbox); + printf("Fatal: Tbox = %g is not positive.\n", model->B3SOIDDtbox); + Fatal_Flag = 1; + } + + if (pParam->B3SOIDDnpeak <= 0.0) + { fprintf(fplog, "Fatal: Nch = %g is not positive.\n", + pParam->B3SOIDDnpeak); + printf("Fatal: Nch = %g is not positive.\n", + pParam->B3SOIDDnpeak); + Fatal_Flag = 1; + } + if (pParam->B3SOIDDngate < 0.0) + { fprintf(fplog, "Fatal: Ngate = %g is not positive.\n", + pParam->B3SOIDDngate); + printf("Fatal: Ngate = %g Ngate is not positive.\n", + pParam->B3SOIDDngate); + Fatal_Flag = 1; + } + if (pParam->B3SOIDDngate > 1.e25) + { fprintf(fplog, "Fatal: Ngate = %g is too high.\n", + pParam->B3SOIDDngate); + printf("Fatal: Ngate = %g Ngate is too high\n", + pParam->B3SOIDDngate); + Fatal_Flag = 1; + } + + if (model->B3SOIDDdvbd1 < 0.0) + { fprintf(fplog, "Fatal: Dvbd1 = %g is negative.\n", + model->B3SOIDDdvbd1); + printf("Fatal: Dvbd1 = %g is negative.\n", model->B3SOIDDdvbd1); + Fatal_Flag = 1; + } + + if (pParam->B3SOIDDdvt1 < 0.0) + { fprintf(fplog, "Fatal: Dvt1 = %g is negative.\n", + pParam->B3SOIDDdvt1); + printf("Fatal: Dvt1 = %g is negative.\n", pParam->B3SOIDDdvt1); + Fatal_Flag = 1; + } + + if (pParam->B3SOIDDdvt1w < 0.0) + { fprintf(fplog, "Fatal: Dvt1w = %g is negative.\n", + pParam->B3SOIDDdvt1w); + printf("Fatal: Dvt1w = %g is negative.\n", pParam->B3SOIDDdvt1w); + Fatal_Flag = 1; + } + + if (pParam->B3SOIDDw0 == -pParam->B3SOIDDweff) + { fprintf(fplog, "Fatal: (W0 + Weff) = 0 cauing divided-by-zero.\n"); + printf("Fatal: (W0 + Weff) = 0 cauing divided-by-zero.\n"); + Fatal_Flag = 1; + } + + if (pParam->B3SOIDDdsub < 0.0) + { fprintf(fplog, "Fatal: Dsub = %g is negative.\n", pParam->B3SOIDDdsub); + printf("Fatal: Dsub = %g is negative.\n", pParam->B3SOIDDdsub); + Fatal_Flag = 1; + } + if (pParam->B3SOIDDb1 == -pParam->B3SOIDDweff) + { fprintf(fplog, "Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n"); + printf("Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n"); + Fatal_Flag = 1; + } + if (pParam->B3SOIDDu0temp <= 0.0) + { fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", pParam->B3SOIDDu0temp); + printf("Fatal: u0 at current temperature = %g is not positive.\n", + pParam->B3SOIDDu0temp); + Fatal_Flag = 1; + } + +/* Check delta parameter */ + if (pParam->B3SOIDDdelta < 0.0) + { fprintf(fplog, "Fatal: Delta = %g is less than zero.\n", + pParam->B3SOIDDdelta); + printf("Fatal: Delta = %g is less than zero.\n", pParam->B3SOIDDdelta); + Fatal_Flag = 1; + } + + if (pParam->B3SOIDDvsattemp <= 0.0) + { fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", pParam->B3SOIDDvsattemp); + printf("Fatal: Vsat at current temperature = %g is not positive.\n", + pParam->B3SOIDDvsattemp); + Fatal_Flag = 1; + } +/* Check Rout parameters */ + if (pParam->B3SOIDDpclm <= 0.0) + { fprintf(fplog, "Fatal: Pclm = %g is not positive.\n", pParam->B3SOIDDpclm); + printf("Fatal: Pclm = %g is not positive.\n", pParam->B3SOIDDpclm); + Fatal_Flag = 1; + } + + if (pParam->B3SOIDDdrout < 0.0) + { fprintf(fplog, "Fatal: Drout = %g is negative.\n", pParam->B3SOIDDdrout); + printf("Fatal: Drout = %g is negative.\n", pParam->B3SOIDDdrout); + Fatal_Flag = 1; + } + if ( model->B3SOIDDunitLengthGateSidewallJctCap > 0.0) + { + if (here->B3SOIDDdrainPerimeter < pParam->B3SOIDDweff) + { fprintf(fplog, "Warning: Pd = %g is less than W.\n", + here->B3SOIDDdrainPerimeter); + printf("Warning: Pd = %g is less than W.\n", + here->B3SOIDDdrainPerimeter); + here->B3SOIDDdrainPerimeter =pParam->B3SOIDDweff; + } + if (here->B3SOIDDsourcePerimeter < pParam->B3SOIDDweff) + { fprintf(fplog, "Warning: Ps = %g is less than W.\n", + here->B3SOIDDsourcePerimeter); + printf("Warning: Ps = %g is less than W.\n", + here->B3SOIDDsourcePerimeter); + here->B3SOIDDsourcePerimeter =pParam->B3SOIDDweff; + } + } +/* Check capacitance parameters */ + if (pParam->B3SOIDDclc < 0.0) + { fprintf(fplog, "Fatal: Clc = %g is negative.\n", pParam->B3SOIDDclc); + printf("Fatal: Clc = %g is negative.\n", pParam->B3SOIDDclc); + Fatal_Flag = 1; + } + if (model->B3SOIDDparamChk ==1) + { +/* Check L and W parameters */ + if (pParam->B3SOIDDleff <= 5.0e-8) + { fprintf(fplog, "Warning: Leff = %g may be too small.\n", + pParam->B3SOIDDleff); + printf("Warning: Leff = %g may be too small.\n", + pParam->B3SOIDDleff); + } + + if (pParam->B3SOIDDleffCV <= 5.0e-8) + { fprintf(fplog, "Warning: Leff for CV = %g may be too small.\n", + pParam->B3SOIDDleffCV); + printf("Warning: Leff for CV = %g may be too small.\n", + pParam->B3SOIDDleffCV); + } + + if (pParam->B3SOIDDweff <= 1.0e-7) + { fprintf(fplog, "Warning: Weff = %g may be too small.\n", + pParam->B3SOIDDweff); + printf("Warning: Weff = %g may be too small.\n", + pParam->B3SOIDDweff); + } + + if (pParam->B3SOIDDweffCV <= 1.0e-7) + { fprintf(fplog, "Warning: Weff for CV = %g may be too small.\n", + pParam->B3SOIDDweffCV); + printf("Warning: Weff for CV = %g may be too small.\n", + pParam->B3SOIDDweffCV); + } + +/* Check threshold voltage parameters */ + if (pParam->B3SOIDDnlx < 0.0) + { fprintf(fplog, "Warning: Nlx = %g is negative.\n", pParam->B3SOIDDnlx); + printf("Warning: Nlx = %g is negative.\n", pParam->B3SOIDDnlx); + } + if (model->B3SOIDDtox < 1.0e-9) + { fprintf(fplog, "Warning: Tox = %g is less than 10A.\n", + model->B3SOIDDtox); + printf("Warning: Tox = %g is less than 10A.\n", model->B3SOIDDtox); + } + + if (pParam->B3SOIDDnpeak <= 1.0e15) + { fprintf(fplog, "Warning: Nch = %g may be too small.\n", + pParam->B3SOIDDnpeak); + printf("Warning: Nch = %g may be too small.\n", + pParam->B3SOIDDnpeak); + } + else if (pParam->B3SOIDDnpeak >= 1.0e21) + { fprintf(fplog, "Warning: Nch = %g may be too large.\n", + pParam->B3SOIDDnpeak); + printf("Warning: Nch = %g may be too large.\n", + pParam->B3SOIDDnpeak); + } + + if (fabs(pParam->B3SOIDDnsub) >= 1.0e21) + { fprintf(fplog, "Warning: Nsub = %g may be too large.\n", + pParam->B3SOIDDnsub); + printf("Warning: Nsub = %g may be too large.\n", + pParam->B3SOIDDnsub); + } + + if ((pParam->B3SOIDDngate > 0.0) && + (pParam->B3SOIDDngate <= 1.e18)) + { fprintf(fplog, "Warning: Ngate = %g is less than 1.E18cm^-3.\n", + pParam->B3SOIDDngate); + printf("Warning: Ngate = %g is less than 1.E18cm^-3.\n", + pParam->B3SOIDDngate); + } + + if (model->B3SOIDDdvbd0 < 0.0) + { fprintf(fplog, "Warning: Dvbd0 = %g is negative.\n", + model->B3SOIDDdvbd0); + printf("Warning: Dvbd0 = %g is negative.\n", model->B3SOIDDdvbd0); + } + + if (pParam->B3SOIDDdvt0 < 0.0) + { fprintf(fplog, "Warning: Dvt0 = %g is negative.\n", + pParam->B3SOIDDdvt0); + printf("Warning: Dvt0 = %g is negative.\n", pParam->B3SOIDDdvt0); + } + + if (fabs(1.0e-6 / (pParam->B3SOIDDw0 + pParam->B3SOIDDweff)) > 10.0) + { fprintf(fplog, "Warning: (W0 + Weff) may be too small.\n"); + printf("Warning: (W0 + Weff) may be too small.\n"); + } + +/* Check subthreshold parameters */ + if (pParam->B3SOIDDnfactor < 0.0) + { fprintf(fplog, "Warning: Nfactor = %g is negative.\n", + pParam->B3SOIDDnfactor); + printf("Warning: Nfactor = %g is negative.\n", pParam->B3SOIDDnfactor); + } + if (model->B3SOIDDkb3 < 0.0) + { fprintf(fplog, "Warning: Kb3 = %g is negative.\n", + model->B3SOIDDkb3); + printf("Warning: Kb3 = %g is negative.\n", model->B3SOIDDkb3); + } + + if (pParam->B3SOIDDcdsc < 0.0) + { fprintf(fplog, "Warning: Cdsc = %g is negative.\n", + pParam->B3SOIDDcdsc); + printf("Warning: Cdsc = %g is negative.\n", pParam->B3SOIDDcdsc); + } + if (pParam->B3SOIDDcdscd < 0.0) + { fprintf(fplog, "Warning: Cdscd = %g is negative.\n", + pParam->B3SOIDDcdscd); + printf("Warning: Cdscd = %g is negative.\n", pParam->B3SOIDDcdscd); + } +/* Check DIBL parameters */ + if (pParam->B3SOIDDeta0 < 0.0) + { fprintf(fplog, "Warning: Eta0 = %g is negative.\n", + pParam->B3SOIDDeta0); + printf("Warning: Eta0 = %g is negative.\n", pParam->B3SOIDDeta0); + } + +/* Check Abulk parameters */ + if (fabs(1.0e-6 / (pParam->B3SOIDDb1 + pParam->B3SOIDDweff)) > 10.0) + { fprintf(fplog, "Warning: (B1 + Weff) may be too small.\n"); + printf("Warning: (B1 + Weff) may be too small.\n"); + } + + if (model->B3SOIDDadice0 > 1.0) + { fprintf(fplog, "Warning: Adice0 = %g should be smaller than 1.\n", + model->B3SOIDDadice0); + printf("Warning: Adice0 = %g should be smaller than 1.\n", model->B3SOIDDadice0); + } + + if (model->B3SOIDDabp < 0.2) + { fprintf(fplog, "Warning: Abp = %g is too small.\n", + model->B3SOIDDabp); + printf("Warning: Abp = %g is too small.\n", model->B3SOIDDabp); + } + + if ((model->B3SOIDDmxc < -1.0) || (model->B3SOIDDmxc > 1.0)) + { fprintf(fplog, "Warning: Mxc = %g should be within (-1, 1).\n", + model->B3SOIDDmxc); + printf("Warning: Mxc = %g should be within (-1, 1).\n", model->B3SOIDDmxc); + } + +/* Check Saturation parameters */ + if (pParam->B3SOIDDa2 < 0.01) + { fprintf(fplog, "Warning: A2 = %g is too small. Set to 0.01.\n", pParam->B3SOIDDa2); + printf("Warning: A2 = %g is too small. Set to 0.01.\n", + pParam->B3SOIDDa2); + pParam->B3SOIDDa2 = 0.01; + } + else if (pParam->B3SOIDDa2 > 1.0) + { fprintf(fplog, "Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n", + pParam->B3SOIDDa2); + printf("Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n", + pParam->B3SOIDDa2); + pParam->B3SOIDDa2 = 1.0; + pParam->B3SOIDDa1 = 0.0; + + } + + if (pParam->B3SOIDDrdsw < 0.0) + { fprintf(fplog, "Warning: Rdsw = %g is negative. Set to zero.\n", + pParam->B3SOIDDrdsw); + printf("Warning: Rdsw = %g is negative. Set to zero.\n", + pParam->B3SOIDDrdsw); + pParam->B3SOIDDrdsw = 0.0; + pParam->B3SOIDDrds0 = 0.0; + } + else if ((pParam->B3SOIDDrds0 > 0.0) && (pParam->B3SOIDDrds0 < 0.001)) + { fprintf(fplog, "Warning: Rds at current temperature = %g is less than 0.001 ohm. Set to zero.\n", + pParam->B3SOIDDrds0); + printf("Warning: Rds at current temperature = %g is less than 0.001 ohm. Set to zero.\n", + pParam->B3SOIDDrds0); + pParam->B3SOIDDrds0 = 0.0; + } + if (pParam->B3SOIDDvsattemp < 1.0e3) + { fprintf(fplog, "Warning: Vsat at current temperature = %g may be too small.\n", pParam->B3SOIDDvsattemp); + printf("Warning: Vsat at current temperature = %g may be too small.\n", pParam->B3SOIDDvsattemp); + } + + if (pParam->B3SOIDDpdibl1 < 0.0) + { fprintf(fplog, "Warning: Pdibl1 = %g is negative.\n", + pParam->B3SOIDDpdibl1); + printf("Warning: Pdibl1 = %g is negative.\n", pParam->B3SOIDDpdibl1); + } + if (pParam->B3SOIDDpdibl2 < 0.0) + { fprintf(fplog, "Warning: Pdibl2 = %g is negative.\n", + pParam->B3SOIDDpdibl2); + printf("Warning: Pdibl2 = %g is negative.\n", pParam->B3SOIDDpdibl2); + } +/* Check overlap capacitance parameters */ + if (model->B3SOIDDcgdo < 0.0) + { fprintf(fplog, "Warning: cgdo = %g is negative. Set to zero.\n", model->B3SOIDDcgdo); + printf("Warning: cgdo = %g is negative. Set to zero.\n", model->B3SOIDDcgdo); + model->B3SOIDDcgdo = 0.0; + } + if (model->B3SOIDDcgso < 0.0) + { fprintf(fplog, "Warning: cgso = %g is negative. Set to zero.\n", model->B3SOIDDcgso); + printf("Warning: cgso = %g is negative. Set to zero.\n", model->B3SOIDDcgso); + model->B3SOIDDcgso = 0.0; + } + if (model->B3SOIDDcgeo < 0.0) + { fprintf(fplog, "Warning: cgeo = %g is negative. Set to zero.\n", model->B3SOIDDcgeo); + printf("Warning: cgeo = %g is negative. Set to zero.\n", model->B3SOIDDcgeo); + model->B3SOIDDcgeo = 0.0; + } + + if (model->B3SOIDDntun < 0.0) + { fprintf(fplog, "Warning: Ntun = %g is negative.\n", + model->B3SOIDDntun); + printf("Warning: Ntun = %g is negative.\n", model->B3SOIDDntun); + } + + if (model->B3SOIDDndiode < 0.0) + { fprintf(fplog, "Warning: Ndiode = %g is negative.\n", + model->B3SOIDDndiode); + printf("Warning: Ndiode = %g is negative.\n", model->B3SOIDDndiode); + } + + if (model->B3SOIDDisbjt < 0.0) + { fprintf(fplog, "Warning: Isbjt = %g is negative.\n", + model->B3SOIDDisbjt); + printf("Warning: Isbjt = %g is negative.\n", model->B3SOIDDisbjt); + } + + if (model->B3SOIDDisdif < 0.0) + { fprintf(fplog, "Warning: Isdif = %g is negative.\n", + model->B3SOIDDisdif); + printf("Warning: Isdif = %g is negative.\n", model->B3SOIDDisdif); + } + + if (model->B3SOIDDisrec < 0.0) + { fprintf(fplog, "Warning: Isrec = %g is negative.\n", + model->B3SOIDDisrec); + printf("Warning: Isrec = %g is negative.\n", model->B3SOIDDisrec); + } + + if (model->B3SOIDDistun < 0.0) + { fprintf(fplog, "Warning: Istun = %g is negative.\n", + model->B3SOIDDistun); + printf("Warning: Istun = %g is negative.\n", model->B3SOIDDistun); + } + + if (model->B3SOIDDedl < 0.0) + { fprintf(fplog, "Warning: Edl = %g is negative.\n", + model->B3SOIDDedl); + printf("Warning: Edl = %g is negative.\n", model->B3SOIDDedl); + } + + if (model->B3SOIDDkbjt1 < 0.0) + { fprintf(fplog, "Warning: Kbjt1 = %g is negative.\n", + model->B3SOIDDkbjt1); + printf("Warning: kbjt1 = %g is negative.\n", model->B3SOIDDkbjt1); + } + + if (model->B3SOIDDtt < 0.0) + { fprintf(fplog, "Warning: Tt = %g is negative.\n", + model->B3SOIDDtt); + printf("Warning: Tt = %g is negative.\n", model->B3SOIDDtt); + } + + if (model->B3SOIDDcsdmin < 0.0) + { fprintf(fplog, "Warning: Csdmin = %g is negative.\n", + model->B3SOIDDcsdmin); + printf("Warning: Csdmin = %g is negative.\n", model->B3SOIDDcsdmin); + } + + if (model->B3SOIDDcsdesw < 0.0) + { fprintf(fplog, "Warning: Csdesw = %g is negative.\n", + model->B3SOIDDcsdesw); + printf("Warning: Csdesw = %g is negative.\n", model->B3SOIDDcsdesw); + } + + if ((model->B3SOIDDasd < 0.0) || (model->B3SOIDDmxc > 1.0)) + { fprintf(fplog, "Warning: Asd = %g should be within (0, 1).\n", + model->B3SOIDDasd); + printf("Warning: Asd = %g should be within (0, 1).\n", model->B3SOIDDasd); + } + + if (model->B3SOIDDrth0 < 0.0) + { fprintf(fplog, "Warning: Rth0 = %g is negative.\n", + model->B3SOIDDrth0); + printf("Warning: Rth0 = %g is negative.\n", model->B3SOIDDrth0); + } + + if (model->B3SOIDDcth0 < 0.0) + { fprintf(fplog, "Warning: Cth0 = %g is negative.\n", + model->B3SOIDDcth0); + printf("Warning: Cth0 = %g is negative.\n", model->B3SOIDDcth0); + } + + if (model->B3SOIDDrbody < 0.0) + { fprintf(fplog, "Warning: Rbody = %g is negative.\n", + model->B3SOIDDrbody); + printf("Warning: Rbody = %g is negative.\n", model->B3SOIDDrbody); + } + + if (model->B3SOIDDrbsh < 0.0) + { fprintf(fplog, "Warning: Rbsh = %g is negative.\n", + model->B3SOIDDrbsh); + printf("Warning: Rbsh = %g is negative.\n", model->B3SOIDDrbsh); + } + + if (model->B3SOIDDxj > model->B3SOIDDtsi) + { fprintf(fplog, "Warning: Xj = %g is thicker than Tsi = %g.\n", + model->B3SOIDDxj, model->B3SOIDDtsi); + printf("Warning: Xj = %g is thicker than Tsi = %g.\n", + model->B3SOIDDxj, model->B3SOIDDtsi); + } + + if (model->B3SOIDDcapMod < 2) + { fprintf(fplog, "Warning: capMod < 2 is not supported by BSIM3SOI.\n"); + printf("Warning: Warning: capMod < 2 is not supported by BSIM3SOI.\n"); + } + + if (model->B3SOIDDcii > 2.0) + { fprintf(fplog, "Warning: Cii = %g is larger than 2.0.\n", model->B3SOIDDcii); + printf("Warning: Cii = %g is larger than 2.0.\n", model->B3SOIDDcii); + } + + if (model->B3SOIDDdii > 1.5) + { fprintf(fplog, "Warning: Dii = %g is larger than 1.5.\n", model->B3SOIDDcii); + printf("Warning: Dii = %g is too larger than 1.5.\n", model->B3SOIDDcii); + } + + }/* loop for the parameter check for warning messages */ + fclose(fplog); + } + else + { fprintf(stderr, "Warning: Can't open log file. Parameter checking skipped.\n"); + } + + return(Fatal_Flag); +} + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddcvtest.c b/src/spicelib/devices/bsim3soi_dd/b3soiddcvtest.c new file mode 100644 index 000000000..7fc6e818c --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddcvtest.c @@ -0,0 +1,90 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddcvtest.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "b3soidddef.h" +#include "trandefs.h" +#include "const.h" +#include "devdefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIDDconvTest(inModel,ckt) +GENmodel *inModel; +register CKTcircuit *ckt; +{ +register B3SOIDDmodel *model = (B3SOIDDmodel*)inModel; +register B3SOIDDinstance *here; +double delvbd, delvbs, delvds, delvgd, delvgs, vbd, vbs, vds; +double cbd, cbhat, cbs, cd, cdhat, tol, vgd, vgdo, vgs; + + /* loop through all the B3SOIDD device models */ + for (; model != NULL; model = model->B3SOIDDnextModel) + { /* loop through all the instances of the model */ + for (here = model->B3SOIDDinstances; here != NULL ; + here=here->B3SOIDDnextInstance) + { vbs = model->B3SOIDDtype + * (*(ckt->CKTrhsOld+here->B3SOIDDbNode) + - *(ckt->CKTrhsOld+here->B3SOIDDsNodePrime)); + vgs = model->B3SOIDDtype + * (*(ckt->CKTrhsOld+here->B3SOIDDgNode) + - *(ckt->CKTrhsOld+here->B3SOIDDsNodePrime)); + vds = model->B3SOIDDtype + * (*(ckt->CKTrhsOld+here->B3SOIDDdNodePrime) + - *(ckt->CKTrhsOld+here->B3SOIDDsNodePrime)); + vbd = vbs - vds; + vgd = vgs - vds; + vgdo = *(ckt->CKTstate0 + here->B3SOIDDvgs) + - *(ckt->CKTstate0 + here->B3SOIDDvds); + delvbs = vbs - *(ckt->CKTstate0 + here->B3SOIDDvbs); + delvbd = vbd - *(ckt->CKTstate0 + here->B3SOIDDvbd); + delvgs = vgs - *(ckt->CKTstate0 + here->B3SOIDDvgs); + delvds = vds - *(ckt->CKTstate0 + here->B3SOIDDvds); + delvgd = vgd-vgdo; + + cd = here->B3SOIDDcd; + if (here->B3SOIDDmode >= 0) + { cdhat = cd - here->B3SOIDDgjdb * delvbd + + here->B3SOIDDgmbs * delvbs + here->B3SOIDDgm * delvgs + + here->B3SOIDDgds * delvds; + } + else + { cdhat = cd - (here->B3SOIDDgjdb - here->B3SOIDDgmbs) * delvbd + - here->B3SOIDDgm * delvgd + here->B3SOIDDgds * delvds; + } + + /* + * check convergence + */ + if ((here->B3SOIDDoff == 0) || (!(ckt->CKTmode & MODEINITFIX))) + { tol = ckt->CKTreltol * MAX(fabs(cdhat), fabs(cd)) + + ckt->CKTabstol; + if (fabs(cdhat - cd) >= tol) + { ckt->CKTnoncon++; + return(OK); + } + cbs = here->B3SOIDDcjs; + cbd = here->B3SOIDDcjd; + cbhat = cbs + cbd + here->B3SOIDDgjdb * delvbd + + here->B3SOIDDgjsb * delvbs; + tol = ckt->CKTreltol * MAX(fabs(cbhat), fabs(cbs + cbd)) + + ckt->CKTabstol; + if (fabs(cbhat - (cbs + cbd)) > tol) + { ckt->CKTnoncon++; + return(OK); + } + } + } + } + return(OK); +} + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soidddef.h b/src/spicelib/devices/bsim3soi_dd/b3soidddef.h new file mode 100644 index 000000000..3dcc46c6b --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soidddef.h @@ -0,0 +1,1991 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung +Modified by Pin Su, Wei Jin 99/9/27 +File: b3soidddef.h +**********/ + +#ifndef B3SOIDD +#define B3SOIDD + +#define SOICODE +/* #define BULKCODE */ + +#include "ifsim.h" +#include "gendefs.h" +#include "cktdefs.h" +#include "complex.h" +#include "noisedef.h" + +typedef struct sB3SOIDDinstance +{ + struct sB3SOIDDmodel *B3SOIDDmodPtr; + struct sB3SOIDDinstance *B3SOIDDnextInstance; + IFuid B3SOIDDname; + int B3SOIDDstates; /* index into state table for this device */ + int B3SOIFDowner; + int B3SOIDDdNode; + int B3SOIDDgNode; + int B3SOIDDsNode; + int B3SOIDDeNode; + int B3SOIDDbNode; + int B3SOIDDtempNode; + int B3SOIDDpNode; + int B3SOIDDdNodePrime; + int B3SOIDDsNodePrime; + + int B3SOIDDvbsNode; + /* for Debug */ + int B3SOIDDidsNode; + int B3SOIDDicNode; + int B3SOIDDibsNode; + int B3SOIDDibdNode; + int B3SOIDDiiiNode; + int B3SOIDDigidlNode; + int B3SOIDDitunNode; + int B3SOIDDibpNode; + int B3SOIDDabeffNode; + int B3SOIDDvbs0effNode; + int B3SOIDDvbseffNode; + int B3SOIDDxcNode; + int B3SOIDDcbbNode; + int B3SOIDDcbdNode; + int B3SOIDDcbeNode; + int B3SOIDDcbgNode; + int B3SOIDDqbNode; + int B3SOIDDqbfNode; + int B3SOIDDqjsNode; + int B3SOIDDqjdNode; + +/* clean up last */ + int B3SOIDDgmNode; + int B3SOIDDgmbsNode; + int B3SOIDDgdsNode; + int B3SOIDDgmeNode; + int B3SOIDDqgNode; + int B3SOIDDqdNode; + int B3SOIDDqeNode; + int B3SOIDDiterations; + int B3SOIDDvbs0teffNode; + int B3SOIDDvthNode; + int B3SOIDDvgsteffNode; + int B3SOIDDxcsatNode; + int B3SOIDDqaccNode; + int B3SOIDDqsub0Node; + int B3SOIDDqsubs1Node; + int B3SOIDDqsubs2Node; + int B3SOIDDvcscvNode; + int B3SOIDDvdscvNode; + int B3SOIDDdum1Node; + int B3SOIDDdum2Node; + int B3SOIDDdum3Node; + int B3SOIDDdum4Node; + int B3SOIDDdum5Node; +/* end clean up last */ + + double B3SOIDDphi; + double B3SOIDDvtm; + double B3SOIDDni; + double B3SOIDDueff; + double B3SOIDDthetavth; + double B3SOIDDvon; + double B3SOIDDvbsdio; + double B3SOIDDvdsat; + double B3SOIDDcgdo; + double B3SOIDDcgso; + double B3SOIDDcgeo; + + double B3SOIDDids; + double B3SOIDDic; + double B3SOIDDibs; + double B3SOIDDibd; + double B3SOIDDiii; + double B3SOIDDigidl; + double B3SOIDDitun; + double B3SOIDDibp; + double B3SOIDDabeff; + double B3SOIDDvbs0eff; + double B3SOIDDvbseff; + double B3SOIDDxc; + double B3SOIDDcbg; + double B3SOIDDcbb; + double B3SOIDDcbd; + double B3SOIDDqb; + double B3SOIDDqbf; + double B3SOIDDqjs; + double B3SOIDDqjd; + double B3SOIDDminIsub; + int B3SOIDDfloat; + +/* clean up last */ + double B3SOIDDdum1; + double B3SOIDDdum2; + double B3SOIDDdum3; + double B3SOIDDdum4; + double B3SOIDDdum5; +/* end clean up last */ + + double B3SOIDDl; + double B3SOIDDw; + double B3SOIDDdrainArea; + double B3SOIDDsourceArea; + double B3SOIDDdrainSquares; + double B3SOIDDsourceSquares; + double B3SOIDDdrainPerimeter; + double B3SOIDDsourcePerimeter; + double B3SOIDDsourceConductance; + double B3SOIDDdrainConductance; + + double B3SOIDDicVBS; + double B3SOIDDicVDS; + double B3SOIDDicVGS; + double B3SOIDDicVES; + double B3SOIDDicVPS; + int B3SOIDDbjtoff; + int B3SOIDDbodyMod; + int B3SOIDDdebugMod; + double B3SOIDDrth0; + double B3SOIDDcth0; + double B3SOIDDbodySquares; + double B3SOIDDrbodyext; + + double B3SOIDDcsbox; + double B3SOIDDcdbox; + double B3SOIDDcsmin; + double B3SOIDDcdmin; + double B3SOIDDst4; + double B3SOIDDdt4; + + int B3SOIDDoff; + int B3SOIDDmode; + + /* OP point */ + double B3SOIDDqinv; + double B3SOIDDcd; + double B3SOIDDcjs; + double B3SOIDDcjd; + double B3SOIDDcbody; + double B3SOIDDcbodcon; + double B3SOIDDcth; + double B3SOIDDcsubstrate; + + double B3SOIDDgm; + double B3SOIDDgme; + double B3SOIDDcb; + double B3SOIDDcdrain; + double B3SOIDDgds; + double B3SOIDDgmbs; + double B3SOIDDgmT; + + double B3SOIDDgbbs; + double B3SOIDDgbgs; + double B3SOIDDgbds; + double B3SOIDDgbes; + double B3SOIDDgbps; + double B3SOIDDgbT; + + double B3SOIDDgjsd; + double B3SOIDDgjsb; + double B3SOIDDgjsg; + double B3SOIDDgjsT; + + double B3SOIDDgjdb; + double B3SOIDDgjdd; + double B3SOIDDgjdg; + double B3SOIDDgjde; + double B3SOIDDgjdT; + + double B3SOIDDgbpbs; + double B3SOIDDgbpgs; + double B3SOIDDgbpds; + double B3SOIDDgbpes; + double B3SOIDDgbpps; + double B3SOIDDgbpT; + + double B3SOIDDgtempb; + double B3SOIDDgtempg; + double B3SOIDDgtempd; + double B3SOIDDgtempe; + double B3SOIDDgtempT; + + double B3SOIDDcggb; + double B3SOIDDcgdb; + double B3SOIDDcbs; /* XXX PN */ + double B3SOIDDcgsb; + double B3SOIDDcgeb; + double B3SOIDDcgT; + + double B3SOIDDcbgb; + double B3SOIDDcbdb; + double B3SOIDDcbsb; + double B3SOIDDcbeb; + double B3SOIDDcbT; + + double B3SOIDDcdgb; + double B3SOIDDcddb; + double B3SOIDDcdsb; + double B3SOIDDcdeb; + double B3SOIDDcdT; + + double B3SOIDDcegb; + double B3SOIDDcedb; + double B3SOIDDcesb; + double B3SOIDDceeb; + double B3SOIDDceT; + + double B3SOIDDqse; + double B3SOIDDgcse; + double B3SOIDDqde; + double B3SOIDDgcde; + + struct b3soiddSizeDependParam *pParam; + + unsigned B3SOIDDlGiven :1; + unsigned B3SOIDDwGiven :1; + unsigned B3SOIDDdrainAreaGiven :1; + unsigned B3SOIDDsourceAreaGiven :1; + unsigned B3SOIDDdrainSquaresGiven :1; + unsigned B3SOIDDsourceSquaresGiven :1; + unsigned B3SOIDDdrainPerimeterGiven :1; + unsigned B3SOIDDsourcePerimeterGiven :1; + unsigned B3SOIDDdNodePrimeSet :1; + unsigned B3SOIDDsNodePrimeSet :1; + unsigned B3SOIDDicVBSGiven :1; + unsigned B3SOIDDicVDSGiven :1; + unsigned B3SOIDDicVGSGiven :1; + unsigned B3SOIDDicVESGiven :1; + unsigned B3SOIDDicVPSGiven :1; + unsigned B3SOIDDbjtoffGiven :1; + unsigned B3SOIDDdebugModGiven :1; + unsigned B3SOIDDrth0Given :1; + unsigned B3SOIDDcth0Given :1; + unsigned B3SOIDDbodySquaresGiven :1; + unsigned B3SOIDDoffGiven :1; + + double *B3SOIDDEePtr; + double *B3SOIDDEbPtr; + double *B3SOIDDBePtr; + double *B3SOIDDEgPtr; + double *B3SOIDDEdpPtr; + double *B3SOIDDEspPtr; + double *B3SOIDDTemptempPtr; + double *B3SOIDDTempdpPtr; + double *B3SOIDDTempspPtr; + double *B3SOIDDTempgPtr; + double *B3SOIDDTempbPtr; + double *B3SOIDDTempePtr; + double *B3SOIDDGtempPtr; + double *B3SOIDDDPtempPtr; + double *B3SOIDDSPtempPtr; + double *B3SOIDDEtempPtr; + double *B3SOIDDBtempPtr; + double *B3SOIDDPtempPtr; + double *B3SOIDDBpPtr; + double *B3SOIDDPbPtr; + double *B3SOIDDPpPtr; + double *B3SOIDDPgPtr; + double *B3SOIDDPdpPtr; + double *B3SOIDDPspPtr; + double *B3SOIDDPePtr; + double *B3SOIDDDPePtr; + double *B3SOIDDSPePtr; + double *B3SOIDDGePtr; + double *B3SOIDDDdPtr; + double *B3SOIDDGgPtr; + double *B3SOIDDSsPtr; + double *B3SOIDDBbPtr; + double *B3SOIDDDPdpPtr; + double *B3SOIDDSPspPtr; + double *B3SOIDDDdpPtr; + double *B3SOIDDGbPtr; + double *B3SOIDDGdpPtr; + double *B3SOIDDGspPtr; + double *B3SOIDDSspPtr; + double *B3SOIDDBdpPtr; + double *B3SOIDDBspPtr; + double *B3SOIDDDPspPtr; + double *B3SOIDDDPdPtr; + double *B3SOIDDBgPtr; + double *B3SOIDDDPgPtr; + double *B3SOIDDSPgPtr; + double *B3SOIDDSPsPtr; + double *B3SOIDDDPbPtr; + double *B3SOIDDSPbPtr; + double *B3SOIDDSPdpPtr; + + double *B3SOIDDVbsPtr; + /* Debug */ + double *B3SOIDDIdsPtr; + double *B3SOIDDIcPtr; + double *B3SOIDDIbsPtr; + double *B3SOIDDIbdPtr; + double *B3SOIDDIiiPtr; + double *B3SOIDDIgidlPtr; + double *B3SOIDDItunPtr; + double *B3SOIDDIbpPtr; + double *B3SOIDDAbeffPtr; + double *B3SOIDDVbs0effPtr; + double *B3SOIDDVbseffPtr; + double *B3SOIDDXcPtr; + double *B3SOIDDCbbPtr; + double *B3SOIDDCbdPtr; + double *B3SOIDDCbgPtr; + double *B3SOIDDqbPtr; + double *B3SOIDDQbfPtr; + double *B3SOIDDQjsPtr; + double *B3SOIDDQjdPtr; + + /* clean up last */ + double *B3SOIDDGmPtr; + double *B3SOIDDGmbsPtr; + double *B3SOIDDGdsPtr; + double *B3SOIDDGmePtr; + double *B3SOIDDVbs0teffPtr; + double *B3SOIDDVthPtr; + double *B3SOIDDVgsteffPtr; + double *B3SOIDDXcsatPtr; + double *B3SOIDDQaccPtr; + double *B3SOIDDQsub0Ptr; + double *B3SOIDDQsubs1Ptr; + double *B3SOIDDQsubs2Ptr; + double *B3SOIDDVdscvPtr; + double *B3SOIDDVcscvPtr; + double *B3SOIDDCbePtr; + double *B3SOIDDqgPtr; + double *B3SOIDDqdPtr; + double *B3SOIDDqePtr; + double *B3SOIDDDum1Ptr; + double *B3SOIDDDum2Ptr; + double *B3SOIDDDum3Ptr; + double *B3SOIDDDum4Ptr; + double *B3SOIDDDum5Ptr; + /* End clean up last */ + +#define B3SOIDDvbd B3SOIDDstates+ 0 +#define B3SOIDDvbs B3SOIDDstates+ 1 +#define B3SOIDDvgs B3SOIDDstates+ 2 +#define B3SOIDDvds B3SOIDDstates+ 3 +#define B3SOIDDves B3SOIDDstates+ 4 +#define B3SOIDDvps B3SOIDDstates+ 5 + +#define B3SOIDDvg B3SOIDDstates+ 6 +#define B3SOIDDvd B3SOIDDstates+ 7 +#define B3SOIDDvs B3SOIDDstates+ 8 +#define B3SOIDDvp B3SOIDDstates+ 9 +#define B3SOIDDve B3SOIDDstates+ 10 +#define B3SOIDDdeltemp B3SOIDDstates+ 11 + +#define B3SOIDDqb B3SOIDDstates+ 12 +#define B3SOIDDcqb B3SOIDDstates+ 13 +#define B3SOIDDqg B3SOIDDstates+ 14 +#define B3SOIDDcqg B3SOIDDstates+ 15 +#define B3SOIDDqd B3SOIDDstates+ 16 +#define B3SOIDDcqd B3SOIDDstates+ 17 +#define B3SOIDDqe B3SOIDDstates+ 18 +#define B3SOIDDcqe B3SOIDDstates+ 19 + +#define B3SOIDDqbs B3SOIDDstates+ 20 +#define B3SOIDDqbd B3SOIDDstates+ 21 +#define B3SOIDDqbe B3SOIDDstates+ 22 + +#define B3SOIDDqth B3SOIDDstates+ 23 +#define B3SOIDDcqth B3SOIDDstates+ 24 + +#define B3SOIDDnumStates 25 + + +/* indices to the array of B3SOIDD NOISE SOURCES */ + +#define B3SOIDDRDNOIZ 0 +#define B3SOIDDRSNOIZ 1 +#define B3SOIDDIDNOIZ 2 +#define B3SOIDDFLNOIZ 3 +#define B3SOIDDFBNOIZ 4 +#define B3SOIDDTOTNOIZ 5 + +#define B3SOIDDNSRCS 6 /* the number of MOSFET(3) noise sources */ + +#ifndef NONOISE + double B3SOIDDnVar[NSTATVARS][B3SOIDDNSRCS]; +#else /* NONOISE */ + double **B3SOIDDnVar; +#endif /* NONOISE */ + +} B3SOIDDinstance ; + +struct b3soiddSizeDependParam +{ + double Width; + double Length; + double Rth0; + double Cth0; + + double B3SOIDDcdsc; + double B3SOIDDcdscb; + double B3SOIDDcdscd; + double B3SOIDDcit; + double B3SOIDDnfactor; + double B3SOIDDvsat; + double B3SOIDDat; + double B3SOIDDa0; + double B3SOIDDags; + double B3SOIDDa1; + double B3SOIDDa2; + double B3SOIDDketa; + double B3SOIDDnpeak; + double B3SOIDDnsub; + double B3SOIDDngate; + double B3SOIDDgamma1; + double B3SOIDDgamma2; + double B3SOIDDvbx; + double B3SOIDDvbi; + double B3SOIDDvbm; + double B3SOIDDvbsc; + double B3SOIDDxt; + double B3SOIDDphi; + double B3SOIDDlitl; + double B3SOIDDk1; + double B3SOIDDkt1; + double B3SOIDDkt1l; + double B3SOIDDkt2; + double B3SOIDDk2; + double B3SOIDDk3; + double B3SOIDDk3b; + double B3SOIDDw0; + double B3SOIDDnlx; + double B3SOIDDdvt0; + double B3SOIDDdvt1; + double B3SOIDDdvt2; + double B3SOIDDdvt0w; + double B3SOIDDdvt1w; + double B3SOIDDdvt2w; + double B3SOIDDdrout; + double B3SOIDDdsub; + double B3SOIDDvth0; + double B3SOIDDua; + double B3SOIDDua1; + double B3SOIDDub; + double B3SOIDDub1; + double B3SOIDDuc; + double B3SOIDDuc1; + double B3SOIDDu0; + double B3SOIDDute; + double B3SOIDDvoff; + double B3SOIDDvfb; + double B3SOIDDuatemp; + double B3SOIDDubtemp; + double B3SOIDDuctemp; + double B3SOIDDrbody; + double B3SOIDDrth; + double B3SOIDDcth; + double B3SOIDDrds0denom; + double B3SOIDDvfbb; + double B3SOIDDjbjt; + double B3SOIDDjdif; + double B3SOIDDjrec; + double B3SOIDDjtun; + double B3SOIDDcsesw; + double B3SOIDDcdesw; + + /* Added */ + double B3SOIDDsdt1; + double B3SOIDDst2; + double B3SOIDDst3; + double B3SOIDDdt2; + double B3SOIDDdt3; + /* Added */ + + double B3SOIDDdelta; + double B3SOIDDrdsw; + double B3SOIDDrds0; + double B3SOIDDprwg; + double B3SOIDDprwb; + double B3SOIDDprt; + double B3SOIDDeta0; + double B3SOIDDetab; + double B3SOIDDpclm; + double B3SOIDDpdibl1; + double B3SOIDDpdibl2; + double B3SOIDDpdiblb; + double B3SOIDDpvag; + double B3SOIDDwr; + double B3SOIDDdwg; + double B3SOIDDdwb; + double B3SOIDDb0; + double B3SOIDDb1; + double B3SOIDDalpha0; + double B3SOIDDalpha1; + double B3SOIDDbeta0; + + + /* CV model */ + double B3SOIDDcgsl; + double B3SOIDDcgdl; + double B3SOIDDckappa; + double B3SOIDDcf; + double B3SOIDDclc; + double B3SOIDDcle; + +/* Added for binning - START0 */ + double B3SOIDDvbsa; + double B3SOIDDdelp; + double B3SOIDDkb1; + double B3SOIDDkb3; + double B3SOIDDdvbd0; + double B3SOIDDdvbd1; + double B3SOIDDabp; + double B3SOIDDmxc; + double B3SOIDDadice0; + double B3SOIDDaii; + double B3SOIDDbii; + double B3SOIDDcii; + double B3SOIDDdii; + double B3SOIDDagidl; + double B3SOIDDbgidl; + double B3SOIDDngidl; + double B3SOIDDntun; + double B3SOIDDndiode; + double B3SOIDDisbjt; + double B3SOIDDisdif; + double B3SOIDDisrec; + double B3SOIDDistun; + double B3SOIDDedl; + double B3SOIDDkbjt1; + double B3SOIDDvsdfb; + double B3SOIDDvsdth; +/* Added for binning - END0 */ + +/* Pre-calculated constants */ + + double B3SOIDDdw; + double B3SOIDDdl; + double B3SOIDDleff; + double B3SOIDDweff; + + double B3SOIDDdwc; + double B3SOIDDdlc; + double B3SOIDDleffCV; + double B3SOIDDweffCV; + double B3SOIDDabulkCVfactor; + double B3SOIDDcgso; + double B3SOIDDcgdo; + double B3SOIDDcgeo; + + double B3SOIDDu0temp; + double B3SOIDDvsattemp; + double B3SOIDDsqrtPhi; + double B3SOIDDphis3; + double B3SOIDDXdep0; + double B3SOIDDsqrtXdep0; + double B3SOIDDtheta0vb0; + double B3SOIDDthetaRout; + + double B3SOIDDcof1; + double B3SOIDDcof2; + double B3SOIDDcof3; + double B3SOIDDcof4; + double B3SOIDDcdep0; + struct b3soiddSizeDependParam *pNext; +}; + + +typedef struct sB3SOIDDmodel +{ + int B3SOIDDmodType; + struct sB3SOIDDmodel *B3SOIDDnextModel; + B3SOIDDinstance *B3SOIDDinstances; + IFuid B3SOIDDmodName; + int B3SOIDDtype; + + int B3SOIDDmobMod; + int B3SOIDDcapMod; + int B3SOIDDnoiMod; + int B3SOIDDshMod; + int B3SOIDDbinUnit; + int B3SOIDDparamChk; + double B3SOIDDversion; + double B3SOIDDtox; + double B3SOIDDcdsc; + double B3SOIDDcdscb; + double B3SOIDDcdscd; + double B3SOIDDcit; + double B3SOIDDnfactor; + double B3SOIDDvsat; + double B3SOIDDat; + double B3SOIDDa0; + double B3SOIDDags; + double B3SOIDDa1; + double B3SOIDDa2; + double B3SOIDDketa; + double B3SOIDDnsub; + double B3SOIDDnpeak; + double B3SOIDDngate; + double B3SOIDDgamma1; + double B3SOIDDgamma2; + double B3SOIDDvbx; + double B3SOIDDvbm; + double B3SOIDDxt; + double B3SOIDDk1; + double B3SOIDDkt1; + double B3SOIDDkt1l; + double B3SOIDDkt2; + double B3SOIDDk2; + double B3SOIDDk3; + double B3SOIDDk3b; + double B3SOIDDw0; + double B3SOIDDnlx; + double B3SOIDDdvt0; + double B3SOIDDdvt1; + double B3SOIDDdvt2; + double B3SOIDDdvt0w; + double B3SOIDDdvt1w; + double B3SOIDDdvt2w; + double B3SOIDDdrout; + double B3SOIDDdsub; + double B3SOIDDvth0; + double B3SOIDDua; + double B3SOIDDua1; + double B3SOIDDub; + double B3SOIDDub1; + double B3SOIDDuc; + double B3SOIDDuc1; + double B3SOIDDu0; + double B3SOIDDute; + double B3SOIDDvoff; + double B3SOIDDdelta; + double B3SOIDDrdsw; + double B3SOIDDprwg; + double B3SOIDDprwb; + double B3SOIDDprt; + double B3SOIDDeta0; + double B3SOIDDetab; + double B3SOIDDpclm; + double B3SOIDDpdibl1; + double B3SOIDDpdibl2; + double B3SOIDDpdiblb; + double B3SOIDDpvag; + double B3SOIDDwr; + double B3SOIDDdwg; + double B3SOIDDdwb; + double B3SOIDDb0; + double B3SOIDDb1; + double B3SOIDDalpha0; + double B3SOIDDalpha1; + double B3SOIDDbeta0; + double B3SOIDDtbox; + double B3SOIDDtsi; + double B3SOIDDxj; + double B3SOIDDkb1; + double B3SOIDDkb3; + double B3SOIDDdvbd0; + double B3SOIDDdvbd1; + double B3SOIDDvbsa; + double B3SOIDDdelp; + double B3SOIDDrbody; + double B3SOIDDrbsh; + double B3SOIDDadice0; + double B3SOIDDabp; + double B3SOIDDmxc; + double B3SOIDDrth0; + double B3SOIDDcth0; + double B3SOIDDaii; + double B3SOIDDbii; + double B3SOIDDcii; + double B3SOIDDdii; + double B3SOIDDngidl; + double B3SOIDDagidl; + double B3SOIDDbgidl; + double B3SOIDDndiode; + double B3SOIDDntun; + double B3SOIDDisbjt; + double B3SOIDDisdif; + double B3SOIDDisrec; + double B3SOIDDistun; + double B3SOIDDxbjt; + double B3SOIDDxdif; + double B3SOIDDxrec; + double B3SOIDDxtun; + double B3SOIDDedl; + double B3SOIDDkbjt1; + double B3SOIDDtt; + double B3SOIDDvsdfb; + double B3SOIDDvsdth; + double B3SOIDDcsdmin; + double B3SOIDDasd; + + /* CV model */ + double B3SOIDDcgsl; + double B3SOIDDcgdl; + double B3SOIDDckappa; + double B3SOIDDcf; + double B3SOIDDclc; + double B3SOIDDcle; + double B3SOIDDdwc; + double B3SOIDDdlc; + + double B3SOIDDtnom; + double B3SOIDDcgso; + double B3SOIDDcgdo; + double B3SOIDDcgeo; + + double B3SOIDDxpart; + double B3SOIDDcFringOut; + double B3SOIDDcFringMax; + + double B3SOIDDsheetResistance; + double B3SOIDDbodyJctGateSideGradingCoeff; + double B3SOIDDGatesidewallJctPotential; + double B3SOIDDunitLengthGateSidewallJctCap; + double B3SOIDDcsdesw; + + double B3SOIDDLint; + double B3SOIDDLl; + double B3SOIDDLln; + double B3SOIDDLw; + double B3SOIDDLwn; + double B3SOIDDLwl; + double B3SOIDDLmin; + double B3SOIDDLmax; + + double B3SOIDDWint; + double B3SOIDDWl; + double B3SOIDDWln; + double B3SOIDDWw; + double B3SOIDDWwn; + double B3SOIDDWwl; + double B3SOIDDWmin; + double B3SOIDDWmax; + +/* Added for binning - START1 */ + /* Length Dependence */ + double B3SOIDDlnpeak; + double B3SOIDDlnsub; + double B3SOIDDlngate; + double B3SOIDDlvth0; + double B3SOIDDlk1; + double B3SOIDDlk2; + double B3SOIDDlk3; + double B3SOIDDlk3b; + double B3SOIDDlvbsa; + double B3SOIDDldelp; + double B3SOIDDlkb1; + double B3SOIDDlkb3; + double B3SOIDDldvbd0; + double B3SOIDDldvbd1; + double B3SOIDDlw0; + double B3SOIDDlnlx; + double B3SOIDDldvt0; + double B3SOIDDldvt1; + double B3SOIDDldvt2; + double B3SOIDDldvt0w; + double B3SOIDDldvt1w; + double B3SOIDDldvt2w; + double B3SOIDDlu0; + double B3SOIDDlua; + double B3SOIDDlub; + double B3SOIDDluc; + double B3SOIDDlvsat; + double B3SOIDDla0; + double B3SOIDDlags; + double B3SOIDDlb0; + double B3SOIDDlb1; + double B3SOIDDlketa; + double B3SOIDDlabp; + double B3SOIDDlmxc; + double B3SOIDDladice0; + double B3SOIDDla1; + double B3SOIDDla2; + double B3SOIDDlrdsw; + double B3SOIDDlprwb; + double B3SOIDDlprwg; + double B3SOIDDlwr; + double B3SOIDDlnfactor; + double B3SOIDDldwg; + double B3SOIDDldwb; + double B3SOIDDlvoff; + double B3SOIDDleta0; + double B3SOIDDletab; + double B3SOIDDldsub; + double B3SOIDDlcit; + double B3SOIDDlcdsc; + double B3SOIDDlcdscb; + double B3SOIDDlcdscd; + double B3SOIDDlpclm; + double B3SOIDDlpdibl1; + double B3SOIDDlpdibl2; + double B3SOIDDlpdiblb; + double B3SOIDDldrout; + double B3SOIDDlpvag; + double B3SOIDDldelta; + double B3SOIDDlaii; + double B3SOIDDlbii; + double B3SOIDDlcii; + double B3SOIDDldii; + double B3SOIDDlalpha0; + double B3SOIDDlalpha1; + double B3SOIDDlbeta0; + double B3SOIDDlagidl; + double B3SOIDDlbgidl; + double B3SOIDDlngidl; + double B3SOIDDlntun; + double B3SOIDDlndiode; + double B3SOIDDlisbjt; + double B3SOIDDlisdif; + double B3SOIDDlisrec; + double B3SOIDDlistun; + double B3SOIDDledl; + double B3SOIDDlkbjt1; + /* CV model */ + double B3SOIDDlvsdfb; + double B3SOIDDlvsdth; + + /* Width Dependence */ + double B3SOIDDwnpeak; + double B3SOIDDwnsub; + double B3SOIDDwngate; + double B3SOIDDwvth0; + double B3SOIDDwk1; + double B3SOIDDwk2; + double B3SOIDDwk3; + double B3SOIDDwk3b; + double B3SOIDDwvbsa; + double B3SOIDDwdelp; + double B3SOIDDwkb1; + double B3SOIDDwkb3; + double B3SOIDDwdvbd0; + double B3SOIDDwdvbd1; + double B3SOIDDww0; + double B3SOIDDwnlx; + double B3SOIDDwdvt0; + double B3SOIDDwdvt1; + double B3SOIDDwdvt2; + double B3SOIDDwdvt0w; + double B3SOIDDwdvt1w; + double B3SOIDDwdvt2w; + double B3SOIDDwu0; + double B3SOIDDwua; + double B3SOIDDwub; + double B3SOIDDwuc; + double B3SOIDDwvsat; + double B3SOIDDwa0; + double B3SOIDDwags; + double B3SOIDDwb0; + double B3SOIDDwb1; + double B3SOIDDwketa; + double B3SOIDDwabp; + double B3SOIDDwmxc; + double B3SOIDDwadice0; + double B3SOIDDwa1; + double B3SOIDDwa2; + double B3SOIDDwrdsw; + double B3SOIDDwprwb; + double B3SOIDDwprwg; + double B3SOIDDwwr; + double B3SOIDDwnfactor; + double B3SOIDDwdwg; + double B3SOIDDwdwb; + double B3SOIDDwvoff; + double B3SOIDDweta0; + double B3SOIDDwetab; + double B3SOIDDwdsub; + double B3SOIDDwcit; + double B3SOIDDwcdsc; + double B3SOIDDwcdscb; + double B3SOIDDwcdscd; + double B3SOIDDwpclm; + double B3SOIDDwpdibl1; + double B3SOIDDwpdibl2; + double B3SOIDDwpdiblb; + double B3SOIDDwdrout; + double B3SOIDDwpvag; + double B3SOIDDwdelta; + double B3SOIDDwaii; + double B3SOIDDwbii; + double B3SOIDDwcii; + double B3SOIDDwdii; + double B3SOIDDwalpha0; + double B3SOIDDwalpha1; + double B3SOIDDwbeta0; + double B3SOIDDwagidl; + double B3SOIDDwbgidl; + double B3SOIDDwngidl; + double B3SOIDDwntun; + double B3SOIDDwndiode; + double B3SOIDDwisbjt; + double B3SOIDDwisdif; + double B3SOIDDwisrec; + double B3SOIDDwistun; + double B3SOIDDwedl; + double B3SOIDDwkbjt1; + /* CV model */ + double B3SOIDDwvsdfb; + double B3SOIDDwvsdth; + + /* Cross-term Dependence */ + double B3SOIDDpnpeak; + double B3SOIDDpnsub; + double B3SOIDDpngate; + double B3SOIDDpvth0; + double B3SOIDDpk1; + double B3SOIDDpk2; + double B3SOIDDpk3; + double B3SOIDDpk3b; + double B3SOIDDpvbsa; + double B3SOIDDpdelp; + double B3SOIDDpkb1; + double B3SOIDDpkb3; + double B3SOIDDpdvbd0; + double B3SOIDDpdvbd1; + double B3SOIDDpw0; + double B3SOIDDpnlx; + double B3SOIDDpdvt0; + double B3SOIDDpdvt1; + double B3SOIDDpdvt2; + double B3SOIDDpdvt0w; + double B3SOIDDpdvt1w; + double B3SOIDDpdvt2w; + double B3SOIDDpu0; + double B3SOIDDpua; + double B3SOIDDpub; + double B3SOIDDpuc; + double B3SOIDDpvsat; + double B3SOIDDpa0; + double B3SOIDDpags; + double B3SOIDDpb0; + double B3SOIDDpb1; + double B3SOIDDpketa; + double B3SOIDDpabp; + double B3SOIDDpmxc; + double B3SOIDDpadice0; + double B3SOIDDpa1; + double B3SOIDDpa2; + double B3SOIDDprdsw; + double B3SOIDDpprwb; + double B3SOIDDpprwg; + double B3SOIDDpwr; + double B3SOIDDpnfactor; + double B3SOIDDpdwg; + double B3SOIDDpdwb; + double B3SOIDDpvoff; + double B3SOIDDpeta0; + double B3SOIDDpetab; + double B3SOIDDpdsub; + double B3SOIDDpcit; + double B3SOIDDpcdsc; + double B3SOIDDpcdscb; + double B3SOIDDpcdscd; + double B3SOIDDppclm; + double B3SOIDDppdibl1; + double B3SOIDDppdibl2; + double B3SOIDDppdiblb; + double B3SOIDDpdrout; + double B3SOIDDppvag; + double B3SOIDDpdelta; + double B3SOIDDpaii; + double B3SOIDDpbii; + double B3SOIDDpcii; + double B3SOIDDpdii; + double B3SOIDDpalpha0; + double B3SOIDDpalpha1; + double B3SOIDDpbeta0; + double B3SOIDDpagidl; + double B3SOIDDpbgidl; + double B3SOIDDpngidl; + double B3SOIDDpntun; + double B3SOIDDpndiode; + double B3SOIDDpisbjt; + double B3SOIDDpisdif; + double B3SOIDDpisrec; + double B3SOIDDpistun; + double B3SOIDDpedl; + double B3SOIDDpkbjt1; + /* CV model */ + double B3SOIDDpvsdfb; + double B3SOIDDpvsdth; +/* Added for binning - END1 */ + +/* Pre-calculated constants */ + double B3SOIDDcbox; + double B3SOIDDcsi; + double B3SOIDDcsieff; + double B3SOIDDcoxt; + double B3SOIDDcboxt; + double B3SOIDDcsit; + double B3SOIDDnfb; + double B3SOIDDadice; + double B3SOIDDqsi; + double B3SOIDDqsieff; + double B3SOIDDeg0; + + /* MCJ: move to size-dependent param. */ + double B3SOIDDvtm; + double B3SOIDDcox; + double B3SOIDDcof1; + double B3SOIDDcof2; + double B3SOIDDcof3; + double B3SOIDDcof4; + double B3SOIDDvcrit; + double B3SOIDDfactor1; + + double B3SOIDDoxideTrapDensityA; + double B3SOIDDoxideTrapDensityB; + double B3SOIDDoxideTrapDensityC; + double B3SOIDDem; + double B3SOIDDef; + double B3SOIDDaf; + double B3SOIDDkf; + double B3SOIDDnoif; + + struct b3soiddSizeDependParam *pSizeDependParamKnot; + + /* Flags */ + + unsigned B3SOIDDtboxGiven:1; + unsigned B3SOIDDtsiGiven :1; + unsigned B3SOIDDxjGiven :1; + unsigned B3SOIDDkb1Given :1; + unsigned B3SOIDDkb3Given :1; + unsigned B3SOIDDdvbd0Given :1; + unsigned B3SOIDDdvbd1Given :1; + unsigned B3SOIDDvbsaGiven :1; + unsigned B3SOIDDdelpGiven :1; + unsigned B3SOIDDrbodyGiven :1; + unsigned B3SOIDDrbshGiven :1; + unsigned B3SOIDDadice0Given :1; + unsigned B3SOIDDabpGiven :1; + unsigned B3SOIDDmxcGiven :1; + unsigned B3SOIDDrth0Given :1; + unsigned B3SOIDDcth0Given :1; + unsigned B3SOIDDaiiGiven :1; + unsigned B3SOIDDbiiGiven :1; + unsigned B3SOIDDciiGiven :1; + unsigned B3SOIDDdiiGiven :1; + unsigned B3SOIDDngidlGiven :1; + unsigned B3SOIDDagidlGiven :1; + unsigned B3SOIDDbgidlGiven :1; + unsigned B3SOIDDndiodeGiven :1; + unsigned B3SOIDDntunGiven :1; + unsigned B3SOIDDisbjtGiven :1; + unsigned B3SOIDDisdifGiven :1; + unsigned B3SOIDDisrecGiven :1; + unsigned B3SOIDDistunGiven :1; + unsigned B3SOIDDxbjtGiven :1; + unsigned B3SOIDDxdifGiven :1; + unsigned B3SOIDDxrecGiven :1; + unsigned B3SOIDDxtunGiven :1; + unsigned B3SOIDDedlGiven :1; + unsigned B3SOIDDkbjt1Given :1; + unsigned B3SOIDDttGiven :1; + unsigned B3SOIDDvsdfbGiven :1; + unsigned B3SOIDDvsdthGiven :1; + unsigned B3SOIDDasdGiven :1; + unsigned B3SOIDDcsdminGiven :1; + + unsigned B3SOIDDmobModGiven :1; + unsigned B3SOIDDbinUnitGiven :1; + unsigned B3SOIDDcapModGiven :1; + unsigned B3SOIDDparamChkGiven :1; + unsigned B3SOIDDnoiModGiven :1; + unsigned B3SOIDDshModGiven :1; + unsigned B3SOIDDtypeGiven :1; + unsigned B3SOIDDtoxGiven :1; + unsigned B3SOIDDversionGiven :1; + + unsigned B3SOIDDcdscGiven :1; + unsigned B3SOIDDcdscbGiven :1; + unsigned B3SOIDDcdscdGiven :1; + unsigned B3SOIDDcitGiven :1; + unsigned B3SOIDDnfactorGiven :1; + unsigned B3SOIDDvsatGiven :1; + unsigned B3SOIDDatGiven :1; + unsigned B3SOIDDa0Given :1; + unsigned B3SOIDDagsGiven :1; + unsigned B3SOIDDa1Given :1; + unsigned B3SOIDDa2Given :1; + unsigned B3SOIDDketaGiven :1; + unsigned B3SOIDDnsubGiven :1; + unsigned B3SOIDDnpeakGiven :1; + unsigned B3SOIDDngateGiven :1; + unsigned B3SOIDDgamma1Given :1; + unsigned B3SOIDDgamma2Given :1; + unsigned B3SOIDDvbxGiven :1; + unsigned B3SOIDDvbmGiven :1; + unsigned B3SOIDDxtGiven :1; + unsigned B3SOIDDk1Given :1; + unsigned B3SOIDDkt1Given :1; + unsigned B3SOIDDkt1lGiven :1; + unsigned B3SOIDDkt2Given :1; + unsigned B3SOIDDk2Given :1; + unsigned B3SOIDDk3Given :1; + unsigned B3SOIDDk3bGiven :1; + unsigned B3SOIDDw0Given :1; + unsigned B3SOIDDnlxGiven :1; + unsigned B3SOIDDdvt0Given :1; + unsigned B3SOIDDdvt1Given :1; + unsigned B3SOIDDdvt2Given :1; + unsigned B3SOIDDdvt0wGiven :1; + unsigned B3SOIDDdvt1wGiven :1; + unsigned B3SOIDDdvt2wGiven :1; + unsigned B3SOIDDdroutGiven :1; + unsigned B3SOIDDdsubGiven :1; + unsigned B3SOIDDvth0Given :1; + unsigned B3SOIDDuaGiven :1; + unsigned B3SOIDDua1Given :1; + unsigned B3SOIDDubGiven :1; + unsigned B3SOIDDub1Given :1; + unsigned B3SOIDDucGiven :1; + unsigned B3SOIDDuc1Given :1; + unsigned B3SOIDDu0Given :1; + unsigned B3SOIDDuteGiven :1; + unsigned B3SOIDDvoffGiven :1; + unsigned B3SOIDDrdswGiven :1; + unsigned B3SOIDDprwgGiven :1; + unsigned B3SOIDDprwbGiven :1; + unsigned B3SOIDDprtGiven :1; + unsigned B3SOIDDeta0Given :1; + unsigned B3SOIDDetabGiven :1; + unsigned B3SOIDDpclmGiven :1; + unsigned B3SOIDDpdibl1Given :1; + unsigned B3SOIDDpdibl2Given :1; + unsigned B3SOIDDpdiblbGiven :1; + unsigned B3SOIDDpvagGiven :1; + unsigned B3SOIDDdeltaGiven :1; + unsigned B3SOIDDwrGiven :1; + unsigned B3SOIDDdwgGiven :1; + unsigned B3SOIDDdwbGiven :1; + unsigned B3SOIDDb0Given :1; + unsigned B3SOIDDb1Given :1; + unsigned B3SOIDDalpha0Given :1; + unsigned B3SOIDDalpha1Given :1; + unsigned B3SOIDDbeta0Given :1; + + /* CV model */ + unsigned B3SOIDDcgslGiven :1; + unsigned B3SOIDDcgdlGiven :1; + unsigned B3SOIDDckappaGiven :1; + unsigned B3SOIDDcfGiven :1; + unsigned B3SOIDDclcGiven :1; + unsigned B3SOIDDcleGiven :1; + unsigned B3SOIDDdwcGiven :1; + unsigned B3SOIDDdlcGiven :1; + +/* Added for binning - START2 */ + /* Length Dependence */ + unsigned B3SOIDDlnpeakGiven :1; + unsigned B3SOIDDlnsubGiven :1; + unsigned B3SOIDDlngateGiven :1; + unsigned B3SOIDDlvth0Given :1; + unsigned B3SOIDDlk1Given :1; + unsigned B3SOIDDlk2Given :1; + unsigned B3SOIDDlk3Given :1; + unsigned B3SOIDDlk3bGiven :1; + unsigned B3SOIDDlvbsaGiven :1; + unsigned B3SOIDDldelpGiven :1; + unsigned B3SOIDDlkb1Given :1; + unsigned B3SOIDDlkb3Given :1; + unsigned B3SOIDDldvbd0Given :1; + unsigned B3SOIDDldvbd1Given :1; + unsigned B3SOIDDlw0Given :1; + unsigned B3SOIDDlnlxGiven :1; + unsigned B3SOIDDldvt0Given :1; + unsigned B3SOIDDldvt1Given :1; + unsigned B3SOIDDldvt2Given :1; + unsigned B3SOIDDldvt0wGiven :1; + unsigned B3SOIDDldvt1wGiven :1; + unsigned B3SOIDDldvt2wGiven :1; + unsigned B3SOIDDlu0Given :1; + unsigned B3SOIDDluaGiven :1; + unsigned B3SOIDDlubGiven :1; + unsigned B3SOIDDlucGiven :1; + unsigned B3SOIDDlvsatGiven :1; + unsigned B3SOIDDla0Given :1; + unsigned B3SOIDDlagsGiven :1; + unsigned B3SOIDDlb0Given :1; + unsigned B3SOIDDlb1Given :1; + unsigned B3SOIDDlketaGiven :1; + unsigned B3SOIDDlabpGiven :1; + unsigned B3SOIDDlmxcGiven :1; + unsigned B3SOIDDladice0Given :1; + unsigned B3SOIDDla1Given :1; + unsigned B3SOIDDla2Given :1; + unsigned B3SOIDDlrdswGiven :1; + unsigned B3SOIDDlprwbGiven :1; + unsigned B3SOIDDlprwgGiven :1; + unsigned B3SOIDDlwrGiven :1; + unsigned B3SOIDDlnfactorGiven :1; + unsigned B3SOIDDldwgGiven :1; + unsigned B3SOIDDldwbGiven :1; + unsigned B3SOIDDlvoffGiven :1; + unsigned B3SOIDDleta0Given :1; + unsigned B3SOIDDletabGiven :1; + unsigned B3SOIDDldsubGiven :1; + unsigned B3SOIDDlcitGiven :1; + unsigned B3SOIDDlcdscGiven :1; + unsigned B3SOIDDlcdscbGiven :1; + unsigned B3SOIDDlcdscdGiven :1; + unsigned B3SOIDDlpclmGiven :1; + unsigned B3SOIDDlpdibl1Given :1; + unsigned B3SOIDDlpdibl2Given :1; + unsigned B3SOIDDlpdiblbGiven :1; + unsigned B3SOIDDldroutGiven :1; + unsigned B3SOIDDlpvagGiven :1; + unsigned B3SOIDDldeltaGiven :1; + unsigned B3SOIDDlaiiGiven :1; + unsigned B3SOIDDlbiiGiven :1; + unsigned B3SOIDDlciiGiven :1; + unsigned B3SOIDDldiiGiven :1; + unsigned B3SOIDDlalpha0Given :1; + unsigned B3SOIDDlalpha1Given :1; + unsigned B3SOIDDlbeta0Given :1; + unsigned B3SOIDDlagidlGiven :1; + unsigned B3SOIDDlbgidlGiven :1; + unsigned B3SOIDDlngidlGiven :1; + unsigned B3SOIDDlntunGiven :1; + unsigned B3SOIDDlndiodeGiven :1; + unsigned B3SOIDDlisbjtGiven :1; + unsigned B3SOIDDlisdifGiven :1; + unsigned B3SOIDDlisrecGiven :1; + unsigned B3SOIDDlistunGiven :1; + unsigned B3SOIDDledlGiven :1; + unsigned B3SOIDDlkbjt1Given :1; + /* CV model */ + unsigned B3SOIDDlvsdfbGiven :1; + unsigned B3SOIDDlvsdthGiven :1; + + /* Width Dependence */ + unsigned B3SOIDDwnpeakGiven :1; + unsigned B3SOIDDwnsubGiven :1; + unsigned B3SOIDDwngateGiven :1; + unsigned B3SOIDDwvth0Given :1; + unsigned B3SOIDDwk1Given :1; + unsigned B3SOIDDwk2Given :1; + unsigned B3SOIDDwk3Given :1; + unsigned B3SOIDDwk3bGiven :1; + unsigned B3SOIDDwvbsaGiven :1; + unsigned B3SOIDDwdelpGiven :1; + unsigned B3SOIDDwkb1Given :1; + unsigned B3SOIDDwkb3Given :1; + unsigned B3SOIDDwdvbd0Given :1; + unsigned B3SOIDDwdvbd1Given :1; + unsigned B3SOIDDww0Given :1; + unsigned B3SOIDDwnlxGiven :1; + unsigned B3SOIDDwdvt0Given :1; + unsigned B3SOIDDwdvt1Given :1; + unsigned B3SOIDDwdvt2Given :1; + unsigned B3SOIDDwdvt0wGiven :1; + unsigned B3SOIDDwdvt1wGiven :1; + unsigned B3SOIDDwdvt2wGiven :1; + unsigned B3SOIDDwu0Given :1; + unsigned B3SOIDDwuaGiven :1; + unsigned B3SOIDDwubGiven :1; + unsigned B3SOIDDwucGiven :1; + unsigned B3SOIDDwvsatGiven :1; + unsigned B3SOIDDwa0Given :1; + unsigned B3SOIDDwagsGiven :1; + unsigned B3SOIDDwb0Given :1; + unsigned B3SOIDDwb1Given :1; + unsigned B3SOIDDwketaGiven :1; + unsigned B3SOIDDwabpGiven :1; + unsigned B3SOIDDwmxcGiven :1; + unsigned B3SOIDDwadice0Given :1; + unsigned B3SOIDDwa1Given :1; + unsigned B3SOIDDwa2Given :1; + unsigned B3SOIDDwrdswGiven :1; + unsigned B3SOIDDwprwbGiven :1; + unsigned B3SOIDDwprwgGiven :1; + unsigned B3SOIDDwwrGiven :1; + unsigned B3SOIDDwnfactorGiven :1; + unsigned B3SOIDDwdwgGiven :1; + unsigned B3SOIDDwdwbGiven :1; + unsigned B3SOIDDwvoffGiven :1; + unsigned B3SOIDDweta0Given :1; + unsigned B3SOIDDwetabGiven :1; + unsigned B3SOIDDwdsubGiven :1; + unsigned B3SOIDDwcitGiven :1; + unsigned B3SOIDDwcdscGiven :1; + unsigned B3SOIDDwcdscbGiven :1; + unsigned B3SOIDDwcdscdGiven :1; + unsigned B3SOIDDwpclmGiven :1; + unsigned B3SOIDDwpdibl1Given :1; + unsigned B3SOIDDwpdibl2Given :1; + unsigned B3SOIDDwpdiblbGiven :1; + unsigned B3SOIDDwdroutGiven :1; + unsigned B3SOIDDwpvagGiven :1; + unsigned B3SOIDDwdeltaGiven :1; + unsigned B3SOIDDwaiiGiven :1; + unsigned B3SOIDDwbiiGiven :1; + unsigned B3SOIDDwciiGiven :1; + unsigned B3SOIDDwdiiGiven :1; + unsigned B3SOIDDwalpha0Given :1; + unsigned B3SOIDDwalpha1Given :1; + unsigned B3SOIDDwbeta0Given :1; + unsigned B3SOIDDwagidlGiven :1; + unsigned B3SOIDDwbgidlGiven :1; + unsigned B3SOIDDwngidlGiven :1; + unsigned B3SOIDDwntunGiven :1; + unsigned B3SOIDDwndiodeGiven :1; + unsigned B3SOIDDwisbjtGiven :1; + unsigned B3SOIDDwisdifGiven :1; + unsigned B3SOIDDwisrecGiven :1; + unsigned B3SOIDDwistunGiven :1; + unsigned B3SOIDDwedlGiven :1; + unsigned B3SOIDDwkbjt1Given :1; + /* CV model */ + unsigned B3SOIDDwvsdfbGiven :1; + unsigned B3SOIDDwvsdthGiven :1; + + /* Cross-term Dependence */ + unsigned B3SOIDDpnpeakGiven :1; + unsigned B3SOIDDpnsubGiven :1; + unsigned B3SOIDDpngateGiven :1; + unsigned B3SOIDDpvth0Given :1; + unsigned B3SOIDDpk1Given :1; + unsigned B3SOIDDpk2Given :1; + unsigned B3SOIDDpk3Given :1; + unsigned B3SOIDDpk3bGiven :1; + unsigned B3SOIDDpvbsaGiven :1; + unsigned B3SOIDDpdelpGiven :1; + unsigned B3SOIDDpkb1Given :1; + unsigned B3SOIDDpkb3Given :1; + unsigned B3SOIDDpdvbd0Given :1; + unsigned B3SOIDDpdvbd1Given :1; + unsigned B3SOIDDpw0Given :1; + unsigned B3SOIDDpnlxGiven :1; + unsigned B3SOIDDpdvt0Given :1; + unsigned B3SOIDDpdvt1Given :1; + unsigned B3SOIDDpdvt2Given :1; + unsigned B3SOIDDpdvt0wGiven :1; + unsigned B3SOIDDpdvt1wGiven :1; + unsigned B3SOIDDpdvt2wGiven :1; + unsigned B3SOIDDpu0Given :1; + unsigned B3SOIDDpuaGiven :1; + unsigned B3SOIDDpubGiven :1; + unsigned B3SOIDDpucGiven :1; + unsigned B3SOIDDpvsatGiven :1; + unsigned B3SOIDDpa0Given :1; + unsigned B3SOIDDpagsGiven :1; + unsigned B3SOIDDpb0Given :1; + unsigned B3SOIDDpb1Given :1; + unsigned B3SOIDDpketaGiven :1; + unsigned B3SOIDDpabpGiven :1; + unsigned B3SOIDDpmxcGiven :1; + unsigned B3SOIDDpadice0Given :1; + unsigned B3SOIDDpa1Given :1; + unsigned B3SOIDDpa2Given :1; + unsigned B3SOIDDprdswGiven :1; + unsigned B3SOIDDpprwbGiven :1; + unsigned B3SOIDDpprwgGiven :1; + unsigned B3SOIDDpwrGiven :1; + unsigned B3SOIDDpnfactorGiven :1; + unsigned B3SOIDDpdwgGiven :1; + unsigned B3SOIDDpdwbGiven :1; + unsigned B3SOIDDpvoffGiven :1; + unsigned B3SOIDDpeta0Given :1; + unsigned B3SOIDDpetabGiven :1; + unsigned B3SOIDDpdsubGiven :1; + unsigned B3SOIDDpcitGiven :1; + unsigned B3SOIDDpcdscGiven :1; + unsigned B3SOIDDpcdscbGiven :1; + unsigned B3SOIDDpcdscdGiven :1; + unsigned B3SOIDDppclmGiven :1; + unsigned B3SOIDDppdibl1Given :1; + unsigned B3SOIDDppdibl2Given :1; + unsigned B3SOIDDppdiblbGiven :1; + unsigned B3SOIDDpdroutGiven :1; + unsigned B3SOIDDppvagGiven :1; + unsigned B3SOIDDpdeltaGiven :1; + unsigned B3SOIDDpaiiGiven :1; + unsigned B3SOIDDpbiiGiven :1; + unsigned B3SOIDDpciiGiven :1; + unsigned B3SOIDDpdiiGiven :1; + unsigned B3SOIDDpalpha0Given :1; + unsigned B3SOIDDpalpha1Given :1; + unsigned B3SOIDDpbeta0Given :1; + unsigned B3SOIDDpagidlGiven :1; + unsigned B3SOIDDpbgidlGiven :1; + unsigned B3SOIDDpngidlGiven :1; + unsigned B3SOIDDpntunGiven :1; + unsigned B3SOIDDpndiodeGiven :1; + unsigned B3SOIDDpisbjtGiven :1; + unsigned B3SOIDDpisdifGiven :1; + unsigned B3SOIDDpisrecGiven :1; + unsigned B3SOIDDpistunGiven :1; + unsigned B3SOIDDpedlGiven :1; + unsigned B3SOIDDpkbjt1Given :1; + /* CV model */ + unsigned B3SOIDDpvsdfbGiven :1; + unsigned B3SOIDDpvsdthGiven :1; +/* Added for binning - END2 */ + + unsigned B3SOIDDuseFringeGiven :1; + + unsigned B3SOIDDtnomGiven :1; + unsigned B3SOIDDcgsoGiven :1; + unsigned B3SOIDDcgdoGiven :1; + unsigned B3SOIDDcgeoGiven :1; + unsigned B3SOIDDxpartGiven :1; + unsigned B3SOIDDsheetResistanceGiven :1; + unsigned B3SOIDDGatesidewallJctPotentialGiven :1; + unsigned B3SOIDDbodyJctGateSideGradingCoeffGiven :1; + unsigned B3SOIDDunitLengthGateSidewallJctCapGiven :1; + unsigned B3SOIDDcsdeswGiven :1; + + unsigned B3SOIDDoxideTrapDensityAGiven :1; + unsigned B3SOIDDoxideTrapDensityBGiven :1; + unsigned B3SOIDDoxideTrapDensityCGiven :1; + unsigned B3SOIDDemGiven :1; + unsigned B3SOIDDefGiven :1; + unsigned B3SOIDDafGiven :1; + unsigned B3SOIDDkfGiven :1; + unsigned B3SOIDDnoifGiven :1; + + unsigned B3SOIDDLintGiven :1; + unsigned B3SOIDDLlGiven :1; + unsigned B3SOIDDLlnGiven :1; + unsigned B3SOIDDLwGiven :1; + unsigned B3SOIDDLwnGiven :1; + unsigned B3SOIDDLwlGiven :1; + unsigned B3SOIDDLminGiven :1; + unsigned B3SOIDDLmaxGiven :1; + + unsigned B3SOIDDWintGiven :1; + unsigned B3SOIDDWlGiven :1; + unsigned B3SOIDDWlnGiven :1; + unsigned B3SOIDDWwGiven :1; + unsigned B3SOIDDWwnGiven :1; + unsigned B3SOIDDWwlGiven :1; + unsigned B3SOIDDWminGiven :1; + unsigned B3SOIDDWmaxGiven :1; + +} B3SOIDDmodel; + + +#ifndef NMOS +#define NMOS 1 +#define PMOS -1 +#endif /*NMOS*/ + + +/* device parameters */ +#define B3SOIDD_W 1 +#define B3SOIDD_L 2 +#define B3SOIDD_AS 3 +#define B3SOIDD_AD 4 +#define B3SOIDD_PS 5 +#define B3SOIDD_PD 6 +#define B3SOIDD_NRS 7 +#define B3SOIDD_NRD 8 +#define B3SOIDD_OFF 9 +#define B3SOIDD_IC_VBS 10 +#define B3SOIDD_IC_VDS 11 +#define B3SOIDD_IC_VGS 12 +#define B3SOIDD_IC_VES 13 +#define B3SOIDD_IC_VPS 14 +#define B3SOIDD_BJTOFF 15 +#define B3SOIDD_RTH0 16 +#define B3SOIDD_CTH0 17 +#define B3SOIDD_NRB 18 +#define B3SOIDD_IC 19 +#define B3SOIDD_NQSMOD 20 +#define B3SOIDD_DEBUG 21 + +/* model parameters */ +#define B3SOIDD_MOD_CAPMOD 101 +#define B3SOIDD_MOD_NQSMOD 102 +#define B3SOIDD_MOD_MOBMOD 103 +#define B3SOIDD_MOD_NOIMOD 104 +#define B3SOIDD_MOD_SHMOD 105 +#define B3SOIDD_MOD_DDMOD 106 + +#define B3SOIDD_MOD_TOX 107 + + + +#define B3SOIDD_MOD_CDSC 108 +#define B3SOIDD_MOD_CDSCB 109 +#define B3SOIDD_MOD_CIT 110 +#define B3SOIDD_MOD_NFACTOR 111 +#define B3SOIDD_MOD_XJ 112 +#define B3SOIDD_MOD_VSAT 113 +#define B3SOIDD_MOD_AT 114 +#define B3SOIDD_MOD_A0 115 +#define B3SOIDD_MOD_A1 116 +#define B3SOIDD_MOD_A2 117 +#define B3SOIDD_MOD_KETA 118 +#define B3SOIDD_MOD_NSUB 119 +#define B3SOIDD_MOD_NPEAK 120 +#define B3SOIDD_MOD_NGATE 121 +#define B3SOIDD_MOD_GAMMA1 122 +#define B3SOIDD_MOD_GAMMA2 123 +#define B3SOIDD_MOD_VBX 124 +#define B3SOIDD_MOD_BINUNIT 125 + +#define B3SOIDD_MOD_VBM 126 + +#define B3SOIDD_MOD_XT 127 +#define B3SOIDD_MOD_K1 129 +#define B3SOIDD_MOD_KT1 130 +#define B3SOIDD_MOD_KT1L 131 +#define B3SOIDD_MOD_K2 132 +#define B3SOIDD_MOD_KT2 133 +#define B3SOIDD_MOD_K3 134 +#define B3SOIDD_MOD_K3B 135 +#define B3SOIDD_MOD_W0 136 +#define B3SOIDD_MOD_NLX 137 + +#define B3SOIDD_MOD_DVT0 138 +#define B3SOIDD_MOD_DVT1 139 +#define B3SOIDD_MOD_DVT2 140 + +#define B3SOIDD_MOD_DVT0W 141 +#define B3SOIDD_MOD_DVT1W 142 +#define B3SOIDD_MOD_DVT2W 143 + +#define B3SOIDD_MOD_DROUT 144 +#define B3SOIDD_MOD_DSUB 145 +#define B3SOIDD_MOD_VTH0 146 +#define B3SOIDD_MOD_UA 147 +#define B3SOIDD_MOD_UA1 148 +#define B3SOIDD_MOD_UB 149 +#define B3SOIDD_MOD_UB1 150 +#define B3SOIDD_MOD_UC 151 +#define B3SOIDD_MOD_UC1 152 +#define B3SOIDD_MOD_U0 153 +#define B3SOIDD_MOD_UTE 154 +#define B3SOIDD_MOD_VOFF 155 +#define B3SOIDD_MOD_DELTA 156 +#define B3SOIDD_MOD_RDSW 157 +#define B3SOIDD_MOD_PRT 158 +#define B3SOIDD_MOD_LDD 159 +#define B3SOIDD_MOD_ETA 160 +#define B3SOIDD_MOD_ETA0 161 +#define B3SOIDD_MOD_ETAB 162 +#define B3SOIDD_MOD_PCLM 163 +#define B3SOIDD_MOD_PDIBL1 164 +#define B3SOIDD_MOD_PDIBL2 165 +#define B3SOIDD_MOD_PSCBE1 166 +#define B3SOIDD_MOD_PSCBE2 167 +#define B3SOIDD_MOD_PVAG 168 +#define B3SOIDD_MOD_WR 169 +#define B3SOIDD_MOD_DWG 170 +#define B3SOIDD_MOD_DWB 171 +#define B3SOIDD_MOD_B0 172 +#define B3SOIDD_MOD_B1 173 +#define B3SOIDD_MOD_ALPHA0 174 +#define B3SOIDD_MOD_BETA0 175 +#define B3SOIDD_MOD_PDIBLB 178 + +#define B3SOIDD_MOD_PRWG 179 +#define B3SOIDD_MOD_PRWB 180 + +#define B3SOIDD_MOD_CDSCD 181 +#define B3SOIDD_MOD_AGS 182 + +#define B3SOIDD_MOD_FRINGE 184 +#define B3SOIDD_MOD_CGSL 186 +#define B3SOIDD_MOD_CGDL 187 +#define B3SOIDD_MOD_CKAPPA 188 +#define B3SOIDD_MOD_CF 189 +#define B3SOIDD_MOD_CLC 190 +#define B3SOIDD_MOD_CLE 191 +#define B3SOIDD_MOD_PARAMCHK 192 +#define B3SOIDD_MOD_VERSION 193 + +#define B3SOIDD_MOD_TBOX 195 +#define B3SOIDD_MOD_TSI 196 +#define B3SOIDD_MOD_KB1 197 +#define B3SOIDD_MOD_KB3 198 +#define B3SOIDD_MOD_DVBD0 199 +#define B3SOIDD_MOD_DVBD1 200 +#define B3SOIDD_MOD_DELP 201 +#define B3SOIDD_MOD_VBSA 202 +#define B3SOIDD_MOD_RBODY 204 +#define B3SOIDD_MOD_ADICE0 205 +#define B3SOIDD_MOD_ABP 206 +#define B3SOIDD_MOD_MXC 207 +#define B3SOIDD_MOD_RTH0 208 +#define B3SOIDD_MOD_CTH0 209 +#define B3SOIDD_MOD_AII 210 +#define B3SOIDD_MOD_BII 211 +#define B3SOIDD_MOD_CII 212 +#define B3SOIDD_MOD_DII 213 +#define B3SOIDD_MOD_ALPHA1 214 +#define B3SOIDD_MOD_NGIDL 215 +#define B3SOIDD_MOD_AGIDL 216 +#define B3SOIDD_MOD_BGIDL 217 +#define B3SOIDD_MOD_NDIODE 218 +#define B3SOIDD_MOD_LDIOF 219 +#define B3SOIDD_MOD_LDIOR 220 +#define B3SOIDD_MOD_NTUN 221 +#define B3SOIDD_MOD_ISBJT 222 +#define B3SOIDD_MOD_ISDIF 223 +#define B3SOIDD_MOD_ISREC 224 +#define B3SOIDD_MOD_ISTUN 225 +#define B3SOIDD_MOD_XBJT 226 +#define B3SOIDD_MOD_XDIF 227 +#define B3SOIDD_MOD_XREC 228 +#define B3SOIDD_MOD_XTUN 229 +#define B3SOIDD_MOD_EDL 230 +#define B3SOIDD_MOD_KBJT1 231 +#define B3SOIDD_MOD_TT 232 +#define B3SOIDD_MOD_VSDTH 233 +#define B3SOIDD_MOD_VSDFB 234 +#define B3SOIDD_MOD_ASD 235 +#define B3SOIDD_MOD_CSDMIN 236 +#define B3SOIDD_MOD_RBSH 237 + +/* Added for binning - START3 */ +/* Length dependence */ +#define B3SOIDD_MOD_LNPEAK 301 +#define B3SOIDD_MOD_LNSUB 302 +#define B3SOIDD_MOD_LNGATE 303 +#define B3SOIDD_MOD_LVTH0 304 +#define B3SOIDD_MOD_LK1 305 +#define B3SOIDD_MOD_LK2 306 +#define B3SOIDD_MOD_LK3 307 +#define B3SOIDD_MOD_LK3B 308 +#define B3SOIDD_MOD_LVBSA 309 +#define B3SOIDD_MOD_LDELP 310 +#define B3SOIDD_MOD_LKB1 311 +#define B3SOIDD_MOD_LKB3 312 +#define B3SOIDD_MOD_LDVBD0 313 +#define B3SOIDD_MOD_LDVBD1 314 +#define B3SOIDD_MOD_LW0 315 +#define B3SOIDD_MOD_LNLX 316 +#define B3SOIDD_MOD_LDVT0 317 +#define B3SOIDD_MOD_LDVT1 318 +#define B3SOIDD_MOD_LDVT2 319 +#define B3SOIDD_MOD_LDVT0W 320 +#define B3SOIDD_MOD_LDVT1W 321 +#define B3SOIDD_MOD_LDVT2W 322 +#define B3SOIDD_MOD_LU0 323 +#define B3SOIDD_MOD_LUA 324 +#define B3SOIDD_MOD_LUB 325 +#define B3SOIDD_MOD_LUC 326 +#define B3SOIDD_MOD_LVSAT 327 +#define B3SOIDD_MOD_LA0 328 +#define B3SOIDD_MOD_LAGS 329 +#define B3SOIDD_MOD_LB0 330 +#define B3SOIDD_MOD_LB1 331 +#define B3SOIDD_MOD_LKETA 332 +#define B3SOIDD_MOD_LABP 333 +#define B3SOIDD_MOD_LMXC 334 +#define B3SOIDD_MOD_LADICE0 335 +#define B3SOIDD_MOD_LA1 336 +#define B3SOIDD_MOD_LA2 337 +#define B3SOIDD_MOD_LRDSW 338 +#define B3SOIDD_MOD_LPRWB 339 +#define B3SOIDD_MOD_LPRWG 340 +#define B3SOIDD_MOD_LWR 341 +#define B3SOIDD_MOD_LNFACTOR 342 +#define B3SOIDD_MOD_LDWG 343 +#define B3SOIDD_MOD_LDWB 344 +#define B3SOIDD_MOD_LVOFF 345 +#define B3SOIDD_MOD_LETA0 346 +#define B3SOIDD_MOD_LETAB 347 +#define B3SOIDD_MOD_LDSUB 348 +#define B3SOIDD_MOD_LCIT 349 +#define B3SOIDD_MOD_LCDSC 350 +#define B3SOIDD_MOD_LCDSCB 351 +#define B3SOIDD_MOD_LCDSCD 352 +#define B3SOIDD_MOD_LPCLM 353 +#define B3SOIDD_MOD_LPDIBL1 354 +#define B3SOIDD_MOD_LPDIBL2 355 +#define B3SOIDD_MOD_LPDIBLB 356 +#define B3SOIDD_MOD_LDROUT 357 +#define B3SOIDD_MOD_LPVAG 358 +#define B3SOIDD_MOD_LDELTA 359 +#define B3SOIDD_MOD_LAII 360 +#define B3SOIDD_MOD_LBII 361 +#define B3SOIDD_MOD_LCII 362 +#define B3SOIDD_MOD_LDII 363 +#define B3SOIDD_MOD_LALPHA0 364 +#define B3SOIDD_MOD_LALPHA1 365 +#define B3SOIDD_MOD_LBETA0 366 +#define B3SOIDD_MOD_LAGIDL 367 +#define B3SOIDD_MOD_LBGIDL 368 +#define B3SOIDD_MOD_LNGIDL 369 +#define B3SOIDD_MOD_LNTUN 370 +#define B3SOIDD_MOD_LNDIODE 371 +#define B3SOIDD_MOD_LISBJT 372 +#define B3SOIDD_MOD_LISDIF 373 +#define B3SOIDD_MOD_LISREC 374 +#define B3SOIDD_MOD_LISTUN 375 +#define B3SOIDD_MOD_LEDL 376 +#define B3SOIDD_MOD_LKBJT1 377 +#define B3SOIDD_MOD_LVSDFB 378 +#define B3SOIDD_MOD_LVSDTH 379 + +/* Width dependence */ +#define B3SOIDD_MOD_WNPEAK 401 +#define B3SOIDD_MOD_WNSUB 402 +#define B3SOIDD_MOD_WNGATE 403 +#define B3SOIDD_MOD_WVTH0 404 +#define B3SOIDD_MOD_WK1 405 +#define B3SOIDD_MOD_WK2 406 +#define B3SOIDD_MOD_WK3 407 +#define B3SOIDD_MOD_WK3B 408 +#define B3SOIDD_MOD_WVBSA 409 +#define B3SOIDD_MOD_WDELP 410 +#define B3SOIDD_MOD_WKB1 411 +#define B3SOIDD_MOD_WKB3 412 +#define B3SOIDD_MOD_WDVBD0 413 +#define B3SOIDD_MOD_WDVBD1 414 +#define B3SOIDD_MOD_WW0 415 +#define B3SOIDD_MOD_WNLX 416 +#define B3SOIDD_MOD_WDVT0 417 +#define B3SOIDD_MOD_WDVT1 418 +#define B3SOIDD_MOD_WDVT2 419 +#define B3SOIDD_MOD_WDVT0W 420 +#define B3SOIDD_MOD_WDVT1W 421 +#define B3SOIDD_MOD_WDVT2W 422 +#define B3SOIDD_MOD_WU0 423 +#define B3SOIDD_MOD_WUA 424 +#define B3SOIDD_MOD_WUB 425 +#define B3SOIDD_MOD_WUC 426 +#define B3SOIDD_MOD_WVSAT 427 +#define B3SOIDD_MOD_WA0 428 +#define B3SOIDD_MOD_WAGS 429 +#define B3SOIDD_MOD_WB0 430 +#define B3SOIDD_MOD_WB1 431 +#define B3SOIDD_MOD_WKETA 432 +#define B3SOIDD_MOD_WABP 433 +#define B3SOIDD_MOD_WMXC 434 +#define B3SOIDD_MOD_WADICE0 435 +#define B3SOIDD_MOD_WA1 436 +#define B3SOIDD_MOD_WA2 437 +#define B3SOIDD_MOD_WRDSW 438 +#define B3SOIDD_MOD_WPRWB 439 +#define B3SOIDD_MOD_WPRWG 440 +#define B3SOIDD_MOD_WWR 441 +#define B3SOIDD_MOD_WNFACTOR 442 +#define B3SOIDD_MOD_WDWG 443 +#define B3SOIDD_MOD_WDWB 444 +#define B3SOIDD_MOD_WVOFF 445 +#define B3SOIDD_MOD_WETA0 446 +#define B3SOIDD_MOD_WETAB 447 +#define B3SOIDD_MOD_WDSUB 448 +#define B3SOIDD_MOD_WCIT 449 +#define B3SOIDD_MOD_WCDSC 450 +#define B3SOIDD_MOD_WCDSCB 451 +#define B3SOIDD_MOD_WCDSCD 452 +#define B3SOIDD_MOD_WPCLM 453 +#define B3SOIDD_MOD_WPDIBL1 454 +#define B3SOIDD_MOD_WPDIBL2 455 +#define B3SOIDD_MOD_WPDIBLB 456 +#define B3SOIDD_MOD_WDROUT 457 +#define B3SOIDD_MOD_WPVAG 458 +#define B3SOIDD_MOD_WDELTA 459 +#define B3SOIDD_MOD_WAII 460 +#define B3SOIDD_MOD_WBII 461 +#define B3SOIDD_MOD_WCII 462 +#define B3SOIDD_MOD_WDII 463 +#define B3SOIDD_MOD_WALPHA0 464 +#define B3SOIDD_MOD_WALPHA1 465 +#define B3SOIDD_MOD_WBETA0 466 +#define B3SOIDD_MOD_WAGIDL 467 +#define B3SOIDD_MOD_WBGIDL 468 +#define B3SOIDD_MOD_WNGIDL 469 +#define B3SOIDD_MOD_WNTUN 470 +#define B3SOIDD_MOD_WNDIODE 471 +#define B3SOIDD_MOD_WISBJT 472 +#define B3SOIDD_MOD_WISDIF 473 +#define B3SOIDD_MOD_WISREC 474 +#define B3SOIDD_MOD_WISTUN 475 +#define B3SOIDD_MOD_WEDL 476 +#define B3SOIDD_MOD_WKBJT1 477 +#define B3SOIDD_MOD_WVSDFB 478 +#define B3SOIDD_MOD_WVSDTH 479 + +/* Cross-term dependence */ +#define B3SOIDD_MOD_PNPEAK 501 +#define B3SOIDD_MOD_PNSUB 502 +#define B3SOIDD_MOD_PNGATE 503 +#define B3SOIDD_MOD_PVTH0 504 +#define B3SOIDD_MOD_PK1 505 +#define B3SOIDD_MOD_PK2 506 +#define B3SOIDD_MOD_PK3 507 +#define B3SOIDD_MOD_PK3B 508 +#define B3SOIDD_MOD_PVBSA 509 +#define B3SOIDD_MOD_PDELP 510 +#define B3SOIDD_MOD_PKB1 511 +#define B3SOIDD_MOD_PKB3 512 +#define B3SOIDD_MOD_PDVBD0 513 +#define B3SOIDD_MOD_PDVBD1 514 +#define B3SOIDD_MOD_PW0 515 +#define B3SOIDD_MOD_PNLX 516 +#define B3SOIDD_MOD_PDVT0 517 +#define B3SOIDD_MOD_PDVT1 518 +#define B3SOIDD_MOD_PDVT2 519 +#define B3SOIDD_MOD_PDVT0W 520 +#define B3SOIDD_MOD_PDVT1W 521 +#define B3SOIDD_MOD_PDVT2W 522 +#define B3SOIDD_MOD_PU0 523 +#define B3SOIDD_MOD_PUA 524 +#define B3SOIDD_MOD_PUB 525 +#define B3SOIDD_MOD_PUC 526 +#define B3SOIDD_MOD_PVSAT 527 +#define B3SOIDD_MOD_PA0 528 +#define B3SOIDD_MOD_PAGS 529 +#define B3SOIDD_MOD_PB0 530 +#define B3SOIDD_MOD_PB1 531 +#define B3SOIDD_MOD_PKETA 532 +#define B3SOIDD_MOD_PABP 533 +#define B3SOIDD_MOD_PMXC 534 +#define B3SOIDD_MOD_PADICE0 535 +#define B3SOIDD_MOD_PA1 536 +#define B3SOIDD_MOD_PA2 537 +#define B3SOIDD_MOD_PRDSW 538 +#define B3SOIDD_MOD_PPRWB 539 +#define B3SOIDD_MOD_PPRWG 540 +#define B3SOIDD_MOD_PWR 541 +#define B3SOIDD_MOD_PNFACTOR 542 +#define B3SOIDD_MOD_PDWG 543 +#define B3SOIDD_MOD_PDWB 544 +#define B3SOIDD_MOD_PVOFF 545 +#define B3SOIDD_MOD_PETA0 546 +#define B3SOIDD_MOD_PETAB 547 +#define B3SOIDD_MOD_PDSUB 548 +#define B3SOIDD_MOD_PCIT 549 +#define B3SOIDD_MOD_PCDSC 550 +#define B3SOIDD_MOD_PCDSCB 551 +#define B3SOIDD_MOD_PCDSCD 552 +#define B3SOIDD_MOD_PPCLM 553 +#define B3SOIDD_MOD_PPDIBL1 554 +#define B3SOIDD_MOD_PPDIBL2 555 +#define B3SOIDD_MOD_PPDIBLB 556 +#define B3SOIDD_MOD_PDROUT 557 +#define B3SOIDD_MOD_PPVAG 558 +#define B3SOIDD_MOD_PDELTA 559 +#define B3SOIDD_MOD_PAII 560 +#define B3SOIDD_MOD_PBII 561 +#define B3SOIDD_MOD_PCII 562 +#define B3SOIDD_MOD_PDII 563 +#define B3SOIDD_MOD_PALPHA0 564 +#define B3SOIDD_MOD_PALPHA1 565 +#define B3SOIDD_MOD_PBETA0 566 +#define B3SOIDD_MOD_PAGIDL 567 +#define B3SOIDD_MOD_PBGIDL 568 +#define B3SOIDD_MOD_PNGIDL 569 +#define B3SOIDD_MOD_PNTUN 570 +#define B3SOIDD_MOD_PNDIODE 571 +#define B3SOIDD_MOD_PISBJT 572 +#define B3SOIDD_MOD_PISDIF 573 +#define B3SOIDD_MOD_PISREC 574 +#define B3SOIDD_MOD_PISTUN 575 +#define B3SOIDD_MOD_PEDL 576 +#define B3SOIDD_MOD_PKBJT1 577 +#define B3SOIDD_MOD_PVSDFB 578 +#define B3SOIDD_MOD_PVSDTH 579 +/* Added for binning - END3 */ + +#define B3SOIDD_MOD_TNOM 701 +#define B3SOIDD_MOD_CGSO 702 +#define B3SOIDD_MOD_CGDO 703 +#define B3SOIDD_MOD_CGEO 704 +#define B3SOIDD_MOD_XPART 705 + +#define B3SOIDD_MOD_RSH 706 +#define B3SOIDD_MOD_NMOS 814 +#define B3SOIDD_MOD_PMOS 815 + +#define B3SOIDD_MOD_NOIA 816 +#define B3SOIDD_MOD_NOIB 817 +#define B3SOIDD_MOD_NOIC 818 + +#define B3SOIDD_MOD_LINT 819 +#define B3SOIDD_MOD_LL 820 +#define B3SOIDD_MOD_LLN 821 +#define B3SOIDD_MOD_LW 822 +#define B3SOIDD_MOD_LWN 823 +#define B3SOIDD_MOD_LWL 824 + +#define B3SOIDD_MOD_WINT 827 +#define B3SOIDD_MOD_WL 828 +#define B3SOIDD_MOD_WLN 829 +#define B3SOIDD_MOD_WW 830 +#define B3SOIDD_MOD_WWN 831 +#define B3SOIDD_MOD_WWL 832 + +#define B3SOIDD_MOD_DWC 835 +#define B3SOIDD_MOD_DLC 836 + +#define B3SOIDD_MOD_EM 837 +#define B3SOIDD_MOD_EF 838 +#define B3SOIDD_MOD_AF 839 +#define B3SOIDD_MOD_KF 840 +#define B3SOIDD_MOD_NOIF 841 + + +#define B3SOIDD_MOD_PBSWG 843 +#define B3SOIDD_MOD_MJSWG 844 +#define B3SOIDD_MOD_CJSWG 845 +#define B3SOIDD_MOD_CSDESW 846 + +/* device questions */ +#define B3SOIDD_DNODE 901 +#define B3SOIDD_GNODE 902 +#define B3SOIDD_SNODE 903 +#define B3SOIDD_BNODE 904 +#define B3SOIDD_ENODE 905 +#define B3SOIDD_DNODEPRIME 906 +#define B3SOIDD_SNODEPRIME 907 +#define B3SOIDD_VBD 908 +#define B3SOIDD_VBS 909 +#define B3SOIDD_VGS 910 +#define B3SOIDD_VES 911 +#define B3SOIDD_VDS 912 +#define B3SOIDD_CD 913 +#define B3SOIDD_CBS 914 +#define B3SOIDD_CBD 915 +#define B3SOIDD_GM 916 +#define B3SOIDD_GDS 917 +#define B3SOIDD_GMBS 918 +#define B3SOIDD_GBD 919 +#define B3SOIDD_GBS 920 +#define B3SOIDD_QB 921 +#define B3SOIDD_CQB 922 +#define B3SOIDD_QG 923 +#define B3SOIDD_CQG 924 +#define B3SOIDD_QD 925 +#define B3SOIDD_CQD 926 +#define B3SOIDD_CGG 927 +#define B3SOIDD_CGD 928 +#define B3SOIDD_CGS 929 +#define B3SOIDD_CBG 930 +#define B3SOIDD_CAPBD 931 +#define B3SOIDD_CQBD 932 +#define B3SOIDD_CAPBS 933 +#define B3SOIDD_CQBS 934 +#define B3SOIDD_CDG 935 +#define B3SOIDD_CDD 936 +#define B3SOIDD_CDS 937 +#define B3SOIDD_VON 938 +#define B3SOIDD_VDSAT 939 +#define B3SOIDD_QBS 940 +#define B3SOIDD_QBD 941 +#define B3SOIDD_SOURCECONDUCT 942 +#define B3SOIDD_DRAINCONDUCT 943 +#define B3SOIDD_CBDB 944 +#define B3SOIDD_CBSB 945 +#define B3SOIDD_GMID 946 + + +#include "b3soiddext.h" + +#ifdef __STDC__ +extern void B3SOIDDevaluate(double,double,double,B3SOIDDinstance*,B3SOIDDmodel*, + double*,double*,double*, double*, double*, double*, double*, + double*, double*, double*, double*, double*, double*, double*, + double*, double*, double*, double*, CKTcircuit*); +extern int B3SOIDDdebug(B3SOIDDmodel*, B3SOIDDinstance*, CKTcircuit*, int); +extern int B3SOIDDcheckModel(B3SOIDDmodel*, B3SOIDDinstance*, CKTcircuit*); +#else /* stdc */ +extern void B3SOIDDevaluate(); +extern int B3SOIDDdebug(); +extern int B3SOIDDcheckModel(); +#endif /* stdc */ + +#endif /*B3SOIDD*/ + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soidddel.c b/src/spicelib/devices/bsim3soi_dd/b3soidddel.c new file mode 100644 index 000000000..d002acaf8 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soidddel.c @@ -0,0 +1,41 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soidddel.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "b3soidddef.h" +#include "sperror.h" +#include "gendefs.h" +#include "suffix.h" + + +int +B3SOIDDdelete(inModel,name,inInst) +GENmodel *inModel; +IFuid name; +GENinstance **inInst; +{ +B3SOIDDinstance **fast = (B3SOIDDinstance**)inInst; +B3SOIDDmodel *model = (B3SOIDDmodel*)inModel; +B3SOIDDinstance **prev = NULL; +B3SOIDDinstance *here; + + for (; model ; model = model->B3SOIDDnextModel) + { prev = &(model->B3SOIDDinstances); + for (here = *prev; here ; here = *prev) + { if (here->B3SOIDDname == name || (fast && here==*fast)) + { *prev= here->B3SOIDDnextInstance; + FREE(here); + return(OK); + } + prev = &(here->B3SOIDDnextInstance); + } + } + return(E_NODEV); +} + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soidddest.c b/src/spicelib/devices/bsim3soi_dd/b3soidddest.c new file mode 100644 index 000000000..107d9107d --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soidddest.c @@ -0,0 +1,39 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soidddest.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "b3soidddef.h" +#include "suffix.h" + +void +B3SOIDDdestroy(inModel) +GENmodel **inModel; +{ +B3SOIDDmodel **model = (B3SOIDDmodel**)inModel; +B3SOIDDinstance *here; +B3SOIDDinstance *prev = NULL; +B3SOIDDmodel *mod = *model; +B3SOIDDmodel *oldmod = NULL; + + for (; mod ; mod = mod->B3SOIDDnextModel) + { if(oldmod) FREE(oldmod); + oldmod = mod; + prev = (B3SOIDDinstance *)NULL; + for (here = mod->B3SOIDDinstances; here; here = here->B3SOIDDnextInstance) + { if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + } + if(oldmod) FREE(oldmod); + *model = NULL; + return; +} + + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddext.h b/src/spicelib/devices/bsim3soi_dd/b3soiddext.h new file mode 100644 index 000000000..915515f73 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddext.h @@ -0,0 +1,54 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung +File: b3soiddext.h +**********/ + + +#ifdef __STDC__ +extern int B3SOIDDacLoad(GENmodel *,CKTcircuit*); +extern int B3SOIDDask(CKTcircuit *,GENinstance*,int,IFvalue*,IFvalue*); +extern int B3SOIDDconvTest(GENmodel *,CKTcircuit*); +extern int B3SOIDDdelete(GENmodel*,IFuid,GENinstance**); +extern void B3SOIDDdestroy(GENmodel**); +extern int B3SOIDDgetic(GENmodel*,CKTcircuit*); +extern int B3SOIDDload(GENmodel*,CKTcircuit*); +extern int B3SOIDDmAsk(CKTcircuit*,GENmodel *,int, IFvalue*); +extern int B3SOIDDmDelete(GENmodel**,IFuid,GENmodel*); +extern int B3SOIDDmParam(int,IFvalue*,GENmodel*); +extern void B3SOIDDmosCap(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*, + double*); +extern int B3SOIDDparam(int,IFvalue*,GENinstance*,IFvalue*); +extern int B3SOIDDpzLoad(GENmodel*,CKTcircuit*,SPcomplex*); +extern int B3SOIDDsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); +extern int B3SOIDDtemp(GENmodel*,CKTcircuit*); +extern int B3SOIDDtrunc(GENmodel*,CKTcircuit*,double*); +extern int B3SOIDDnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); +extern int B3SOIDDunsetup(GENmodel*,CKTcircuit*); + +#else /* stdc */ +extern int B3SOIDDacLoad(); +extern int B3SOIDDdelete(); +extern void B3SOIDDdestroy(); +extern int B3SOIDDgetic(); +extern int B3SOIDDload(); +extern int B3SOIDDmDelete(); +extern int B3SOIDDask(); +extern int B3SOIDDmAsk(); +extern int B3SOIDDconvTest(); +extern int B3SOIDDtemp(); +extern int B3SOIDDmParam(); +extern void B3SOIDDmosCap(); +extern int B3SOIDDparam(); +extern int B3SOIDDpzLoad(); +extern int B3SOIDDsetup(); +extern int B3SOIDDtrunc(); +extern int B3SOIDDnoise(); +extern int B3SOIDDunsetup(); + +#endif /* stdc */ + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddgetic.c b/src/spicelib/devices/bsim3soi_dd/b3soiddgetic.c new file mode 100644 index 000000000..d3b549910 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddgetic.c @@ -0,0 +1,51 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddgetic.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "b3soidddef.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIDDgetic(inModel,ckt) +GENmodel *inModel; +CKTcircuit *ckt; +{ +B3SOIDDmodel *model = (B3SOIDDmodel*)inModel; +B3SOIDDinstance *here; + + for (; model ; model = model->B3SOIDDnextModel) + { for (here = model->B3SOIDDinstances; here; here = here->B3SOIDDnextInstance) + { if(!here->B3SOIDDicVBSGiven) + { here->B3SOIDDicVBS = *(ckt->CKTrhs + here->B3SOIDDbNode) + - *(ckt->CKTrhs + here->B3SOIDDsNode); + } + if (!here->B3SOIDDicVDSGiven) + { here->B3SOIDDicVDS = *(ckt->CKTrhs + here->B3SOIDDdNode) + - *(ckt->CKTrhs + here->B3SOIDDsNode); + } + if (!here->B3SOIDDicVGSGiven) + { here->B3SOIDDicVGS = *(ckt->CKTrhs + here->B3SOIDDgNode) + - *(ckt->CKTrhs + here->B3SOIDDsNode); + } + if (!here->B3SOIDDicVESGiven) + { here->B3SOIDDicVES = *(ckt->CKTrhs + here->B3SOIDDeNode) + - *(ckt->CKTrhs + here->B3SOIDDsNode); + } + if (!here->B3SOIDDicVPSGiven) + { here->B3SOIDDicVPS = *(ckt->CKTrhs + here->B3SOIDDpNode) + - *(ckt->CKTrhs + here->B3SOIDDsNode); + } + } + } + return(OK); +} + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddinit.c b/src/spicelib/devices/bsim3soi_dd/b3soiddinit.c new file mode 100644 index 000000000..f88fe5149 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddinit.c @@ -0,0 +1,62 @@ +#include + +#include + +#include "b3soidditf.h" +#include "b3soiddext.h" +#include "b3soiddinit.h" + +SPICEdev B3SOIDDinfo = { + { "B3SOIDD", + "Berkeley SOI MOSFET (DD) model version 1.0", + + &B3SOIDDnSize, + &B3SOIDDnSize, + B3SOIDDnames, + + &B3SOIDDpTSize, + B3SOIDDpTable, + + &B3SOIDDmPTSize, + B3SOIDDmPTable, + DEV_DEFAULT} + , + +DEVparam: B3SOIDDparam, +DEVmodParam: B3SOIDDmParam, +DEVload: B3SOIDDload, +DEVsetup: B3SOIDDsetup, +DEVunsetup: B3SOIDDunsetup, +DEVpzSetup: B3SOIDDsetup, +DEVtemperature:B3SOIDDtemp, +DEVtrunc: B3SOIDDtrunc, +DEVfindBranch: NULL, +DEVacLoad: B3SOIDDacLoad, +DEVaccept: NULL, +DEVdestroy: B3SOIDDdestroy, +DEVmodDelete: B3SOIDDmDelete, +DEVdelete: B3SOIDDdelete, +DEVsetic: B3SOIDDgetic, +DEVask: B3SOIDDask, +DEVmodAsk: B3SOIDDmAsk, +DEVpzLoad: B3SOIDDpzLoad, +DEVconvTest: B3SOIDDconvTest, +DEVsenSetup: NULL, +DEVsenLoad: NULL, +DEVsenUpdate: NULL, +DEVsenAcLoad: NULL, +DEVsenPrint: NULL, +DEVsenTrunc: NULL, +DEVdisto: NULL, +DEVnoise: B3SOIDDnoise, +DEVinstSize: &B3SOIDDiSize, +DEVmodSize: &B3SOIDDmSize +}; + +SPICEdev * +get_bsim3soidd_info (void) +{ + return &B3SOIDDinfo; +} + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddinit.h b/src/spicelib/devices/bsim3soi_dd/b3soiddinit.h new file mode 100644 index 000000000..c6644262f --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddinit.h @@ -0,0 +1,13 @@ +#ifndef _B3SOIDDINIT_H +#define _B3SOIDDINIT_H + +extern IFparm B3SOIDDpTable[]; +extern IFparm B3SOIDDmPTable[]; +extern char *B3SOIDDnames[]; +extern int B3SOIDDpTSize; +extern int B3SOIDDmPTSize; +extern int B3SOIDDnSize; +extern int B3SOIDDiSize; +extern int B3SOIDDmSize; + +#endif diff --git a/src/spicelib/devices/bsim3soi_dd/b3soidditf.h b/src/spicelib/devices/bsim3soi_dd/b3soidditf.h new file mode 100644 index 000000000..cb7ee9faf --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soidditf.h @@ -0,0 +1,14 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung +File: b3soidditf.h +**********/ + +#ifndef DEV_B3SOIDD +#define DEV_B3SOIDD + +#include "b3soiddext.h" + +SPICEdev *get_bsim3soidd_info (void); + +#endif diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddld.c b/src/spicelib/devices/bsim3soi_dd/b3soiddld.c new file mode 100644 index 000000000..f121e3abc --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddld.c @@ -0,0 +1,4457 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +Modified by Pin Su, Wei Jin 99/9/27 +File: b3soiddld.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "b3soidddef.h" +#include "trandefs.h" +#include "const.h" +#include "sperror.h" +#include "devdefs.h" +#include "suffix.h" + +#define MAX_EXP 5.834617425e14 +#define MIN_EXP 1.713908431e-15 +#define EXP_THRESHOLD 34.0 +#define EPSOX 3.453133e-11 +#define EPSSI 1.03594e-10 +#define Charge_q 1.60219e-19 +#define KboQ 8.617087e-5 /* Kb / q */ +#define Eg300 1.115 /* energy gap at 300K */ +#define DELTA_1 0.02 +#define DELTA_2 0.02 +#define DELTA_3 0.02 +#define DELTA_4 0.02 +#define DELT_Vbs0eff 0.02 +#define DELT_Vbsmos 0.005 +#define DELT_Vbseff 0.005 +#define DELT_Xcsat 0.2 +#define DELT_Vbs0dio 1e-7 +#define DELTA_VFB 0.02 +#define DELTA_Vcscv 0.0004 +#define DELT_Vbsdio 0.01 +#define CONST_2OV3 0.6666666666 +#define OFF_Vbsdio 2e-2 +#define OFF_Vbs0_dio 2.02e-2 +#define QEX_FACT 20 + + + /* B3SOIDDSmartVbs(Vbs, Old, here, check) + * Smart Vbs guess. + */ + +double +B3SOIDDSmartVbs(New, Old, here, ckt, check) + double New, Old; + B3SOIDDinstance *here; + CKTcircuit *ckt; + int *check; +{ + double T0, T1, del; + + /* only do it for floating body and DC */ + if (here->B3SOIDDfloat && (ckt->CKTmode & (MODEDC | MODEDCOP))) + { + /* Vbs cannot be negative in DC */ + if (New < 0.0) New = 0.0; + } + return(New); +} + + + /* B3SOIDDlimit(vnew,vold) + * limits the per-iteration change of any absolute voltage value + */ + +double +B3SOIDDlimit(vnew, vold, limit, check) + double vnew; + double vold; + double limit; + int *check; +{ + double T0, T1; + + if (isnan (vnew) || isnan (vold)) + { + fprintf(stderr, "Alberto says: YOU TURKEY! The limiting function received NaN.\n"); + fprintf(stderr, "New prediction returns to 0.0!\n"); + vnew = 0.0; + *check = 1; + } + T0 = vnew - vold; + T1 = fabs(T0); + if (T1 > limit) { + if (T0 > 0.0) + vnew = vold + limit; + else + vnew = vold - limit; + *check = 1; + } + return vnew; +} + + + +int +B3SOIDDload(inModel,ckt) +GENmodel *inModel; +register CKTcircuit *ckt; +{ +register B3SOIDDmodel *model = (B3SOIDDmodel*)inModel; +register B3SOIDDinstance *here; +register int selfheat; + +double SourceSatCurrent, DrainSatCurrent, Gmin; +double ag0, qgd, qgs, qgb, von, cbhat, VgstNVt, ExpVgst; +double cdhat, cdreq, ceqbd, ceqbs, ceqqb, ceqqd, ceqqg, ceq, geq; +double evbd, evbs, arg, sarg; +double delvbd, delvbs, delvds, delvgd, delvgs; +double Vfbeff, dVfbeff_dVg, dVfbeff_dVd, dVfbeff_dVb, V3, V4; +double tol, PhiB, PhiBSW, MJ, MJSW, PhiBSWG, MJSWG; +double gcgdb, gcggb, gcgsb, gcgeb, gcgT; +double gcsdb, gcsgb, gcssb, gcseb, gcsT; +double gcddb, gcdgb, gcdsb, gcdeb, gcdT; +double gcbdb, gcbgb, gcbsb, gcbeb, gcbT; +double gcedb, gcegb, gcesb, gceeb, gceT; +double gcTt, gTtg, gTtb, gTte, gTtdp, gTtt, gTtsp; +double vbd, vbs, vds, vgb, vgd, vgs, vgdo, xfact; +double vg, vd, vs, vp, ve, vb; +double Vds, Vgs, Vbs, Gmbs, FwdSum, RevSum; +double Vgs_eff, Vfb, dVfb_dVb, dVfb_dVd, dVfb_dT; +double Phis, dPhis_dVb, sqrtPhis, dsqrtPhis_dVb, Vth, dVth_dVb, dVth_dVd, dVth_dT; +double Vgst, dVgst_dVg, dVgst_dVb, dVgs_eff_dVg, Nvtm; +double Vgdt, Vgsaddvth, Vgsaddvth2, Vgsaddvth1o3, n, dn_dVb, Vtm; +double ExpArg, V0; +double ueff, dueff_dVg, dueff_dVd, dueff_dVb, dueff_dT; +double Esat, dEsat_dVg, dEsat_dVd, dEsat_dVb, Vdsat, Vdsat0; +double EsatL, dEsatL_dVg, dEsatL_dVd, dEsatL_dVb, dEsatL_dT; +double dVdsat_dVg, dVdsat_dVb, dVdsat_dVd, dVdsat_dT, Vasat, dAlphaz_dVg, dAlphaz_dVb; +double dVasat_dVg, dVasat_dVb, dVasat_dVd, dVasat_dT; +double Va, Va2, dVa_dVd, dVa_dVg, dVa_dVb, dVa_dT; +double Vbseff, dVbseff_dVb, VbseffCV, dVbseffCV_dVb; +double One_Third_CoxWL, Two_Third_CoxWL, Alphaz, CoxWL; +double dVgdt_dVg, dVgdt_dVd, dVgdt_dVb; +double T0, dT0_dVg, dT0_dVd, dT0_dVb, dT0_dVc, dT0_dVe, dT0_dVrg, dT0_dT; +double T1, dT1_dVg, dT1_dVd, dT1_dVb, dT1_dVc, dT1_dVe, dT1_dT; +double T2, dT2_dVg, dT2_dVd, dT2_dVb, dT2_dVc, dT2_dVe, dT2_dT; +double T3, dT3_dVg, dT3_dVd, dT3_dVb, dT3_dVc, dT3_dVe, dT3_dT; +double T4, dT4_dVg, dT4_dVd, dT4_dVb, dT4_dVc, dT4_dVe, dT4_dT; +double T5, dT5_dVg, dT5_dVd, dT5_dVb, dT5_dVc, dT5_dVe, dT5_dT; +double T6, dT6_dVg, dT6_dVd, dT6_dVb, dT6_dVc, dT6_dVe, dT6_dT; +double T7, dT7_dVg, dT7_dVd, dT7_dVb; +double T8, dT8_dVg, dT8_dVd, dT8_dVb, dT8_dVc, dT8_dVe, dT8_dVrg; +double T9, dT9_dVg, dT9_dVd, dT9_dVb, dT9_dVc, dT9_dVe, dT9_dVrg; +double T10, dT10_dVg, dT10_dVb, dT10_dVd; +double T11, T12; +double tmp, Abulk, dAbulk_dVb, Abulk0, dAbulk0_dVb; +double T100, T101; +double VACLM, dVACLM_dVg, dVACLM_dVd, dVACLM_dVb, dVACLM_dT; +double VADIBL, dVADIBL_dVg, dVADIBL_dVd, dVADIBL_dVb, dVADIBL_dT; +double VAHCE, dVAHCE_dVg, dVAHCE_dVd, dVAHCE_dVb; +double Xdep, dXdep_dVb, lt1, dlt1_dVb, ltw, dltw_dVb; +double Delt_vth, dDelt_vth_dVb, dDelt_vth_dT; +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 tempv, a1; + +double Vgsteff, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb, dVgsteff_dVe, dVgsteff_dT; +double Vdseff, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb, dVdseff_dT; +double VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb; +double diffVds, diffVdsCV; +double dAbulk_dVg, dn_dVd ; +double beta, dbeta_dVg, dbeta_dVd, dbeta_dVb, dbeta_dT; +double gche, dgche_dVg, dgche_dVd, dgche_dVb, dgche_dT; +double fgche1, dfgche1_dVg, dfgche1_dVd, dfgche1_dVb, dfgche1_dT; +double fgche2, dfgche2_dVg, dfgche2_dVd, dfgche2_dVb, dfgche2_dT; +double Idl, dIdl_dVg, dIdl_dVd, dIdl_dVb, dIdl_dT; +double Ids, Gm, Gds, Gmb; +double CoxWovL; +double Rds, dRds_dVg, dRds_dVb, dRds_dT, WVCox, WVCoxRds; +double Vgst2Vtm, dVgst2Vtm_dT, VdsatCV, dVdsatCV_dVd, dVdsatCV_dVg, dVdsatCV_dVb; +double Leff, Weff, dWeff_dVg, dWeff_dVb; +double AbulkCV, dAbulkCV_dVb; +double qgdo, qgso, cgdo, cgso; + +double dxpart, sxpart; + +struct b3soiddSizeDependParam *pParam; +int ByPass, Check, ChargeComputationNeeded, J, error, I; +double junk[50]; + +double gbbsp, gbbdp, gbbg, gbbb, gbbe, gbbp, gbbT; +double gddpsp, gddpdp, gddpg, gddpb, gddpe, gddpT; +double gsspsp, gsspdp, gsspg, gsspb, gsspe, gsspT; +double Gbpbs, Gbpgs, Gbpds, Gbpes, Gbpps, GbpT; +double vse, vde, ves, ved, veb, vge, delves, vedo, delved; +double vps, vpd, Vps, delvps; +double Vbd, Ves, Vesfb, sqrtXdep, DeltVthtemp, dDeltVthtemp_dT; +double Vbp, dVbp_dVp, dVbp_dVb, dVbp_dVg, dVbp_dVd, dVbp_dVe, dVbp_dT; +double Vpsdio, dVpsdio_dVg, dVpsdio_dVd, dVpsdio_dVe, dVpsdio_dVp, dVpsdio_dT; +double DeltVthw, dDeltVthw_dVb, dDeltVthw_dT; +double dVbseff_dVd, dVbseff_dVe, dVbseff_dT; +double dVdsat_dVc, dVasat_dVc, dVACLM_dVc, dVADIBL_dVc, dVa_dVc; +double dfgche1_dVc, dfgche2_dVc, dgche_dVc, dVdseff_dVc, dIdl_dVc; +double Gm0, Gds0, Gmb0, GmT0, Gmc, Gme, GmT, dVbseff_dVg; +double dDIBL_Sft_dVb, BjtA, dBjtA_dVd; +double diffVdsii ; +double Idgidl, Gdgidld, Gdgidlg, Isgidl, Gsgidlg; +double Gjsd, Gjss, Gjsb, GjsT, Gjdd, Gjdb, GjdT; +double Ibp, Iii, Giid, Giig, Giib, Giie, GiiT, Gcd, Gcb, GcT, ceqbody, ceqbodcon; +double gppg, gppdp, gppb, gppe, gppp, gppsp, gppT; +double delTemp, deldelTemp, Temp; +double ceqth, ceqqth; +double K1, WL; +double qjs, gcjsbs, gcjsT; +double qjd, gcjdbs, gcjdds, gcjdT; +double qge; +double ceqqe; +double ni, Eg, Cbox, Nfb, CboxWL; +double cjsbs; +double Qbf0, Qsicv, dVfbeff_dVrg, Cbe ; +double qinv, qgate, qbody, qdrn, qsrc, qsub, cqgate, cqbody, cqdrn, cqsub, cqtemp; +double Cgg, Cgd, Cgs, Cgb, Cge, Cdg, Cdd, Cds, Cdb, Qg, Qd; +double Csg, Csd, Css, Csb, Cse, Cbg, Cbd, Cbs, Cbb, Qs, Qb; +double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Csg1, Csd1, Csb1; +double Vbs0t, dVbs0t_dT ; +double Vbs0 ,dVbs0_dVe, dVbs0_dT; +double Vbs0eff ,dVbs0eff_dVg ,dVbs0eff_dVd ,dVbs0eff_dVe, dVbs0eff_dT; +double Vbs0teff,dVbs0teff_dVg ,dVbs0teff_dVd, dVbs0teff_dVe, dVbs0teff_dT; +double Vbsdio, dVbsdio_dVg, dVbsdio_dVd, dVbsdio_dVe, dVbsdio_dVb, dVbsdio_dT; +double Vbseff0; +double Vthfd ,dVthfd_dVd ,dVthfd_dVe, dVthfd_dT; +double Vbs0mos ,dVbs0mos_dVe, dVbs0mos_dT; +double Vbsmos ,dVbsmos_dVg ,dVbsmos_dVb ,dVbsmos_dVd, dVbsmos_dVe, dVbsmos_dT; +double Abeff ,dAbeff_dVg ,dAbeff_dVb, dAbeff_dVc; +double Vcs ,dVcs_dVg ,dVcs_dVb ,dVcs_dVd ,dVcs_dVe, dVcs_dT; +double Xcsat ,dXcsat_dVg ,dXcsat_dVb, dXcsat_dVc; +double Vdsatii ,dVdsatii_dVg ,dVdsatii_dVd, dVdsatii_dVb, dVdsatii_dT; +double Vdseffii ,dVdseffii_dVg ,dVdseffii_dVd, dVdseffii_dVb, dVdseffii_dT; +double VcsCV ,dVcsCV_dVg ,dVcsCV_dVb ,dVcsCV_dVd ,dVcsCV_dVc ,dVcsCV_dVe; +double VdsCV ,dVdsCV_dVg ,dVdsCV_dVb ,dVdsCV_dVd ,dVdsCV_dVc; +double Phisc ,dPhisc_dVg ,dPhisc_dVb ,dPhisc_dVd, dPhisc_dVc; +double Phisd ,dPhisd_dVg ,dPhisd_dVb ,dPhisd_dVd, dPhisd_dVc; +double sqrtPhisc ,dsqrtPhisc_dVg ,dsqrtPhisc_dVb; +double sqrtPhisd ,dsqrtPhisd_dVg ,dsqrtPhisd_dVb; +double Xc ,dXc_dVg ,dXc_dVb ,dXc_dVd ,dXc_dVc; +double Ibjt ,dIbjt_dVb ,dIbjt_dVd ,dIbjt_dT; +double Ibs1 ,dIbs1_dVb ,dIbs1_dT; +double Ibs2 ,dIbs2_dVb ,dIbs2_dT; +double Ibs3 ,dIbs3_dVb ,dIbs3_dVd, dIbs3_dT; +double Ibs4 ,dIbs4_dVb ,dIbs4_dT; +double Ibd1 ,dIbd1_dVb ,dIbd1_dVd ,dIbd1_dT; +double Ibd2 ,dIbd2_dVb ,dIbd2_dVd ,dIbd2_dT; +double Ibd3 ,dIbd3_dVb ,dIbd3_dVd ,dIbd3_dT; +double Ibd4 ,dIbd4_dVb ,dIbd4_dVd ,dIbd4_dT; +double ExpVbs1, dExpVbs1_dVb, dExpVbs1_dT; +double ExpVbs2, dExpVbs2_dVb, dExpVbs2_dT; +double ExpVbs4, dExpVbs4_dVb, dExpVbs4_dT; +double ExpVbd1, dExpVbd1_dVb, dExpVbd1_dT; +double ExpVbd2, dExpVbd2_dVb, dExpVbd2_dT; +double ExpVbd4, dExpVbd4_dVb, dExpVbd4_dT; +double WTsi, NVtm1, NVtm2; +double Ic ,dIc_dVb ,dIc_dVd; +double Ibs ,dIbs_dVb ,dIbs_dVd ,dIbs_dVe; +double Ibd ,dIbd_dVb; +double Nomi ,dNomi_dVg ,dNomi_dVb ,dNomi_dVd ,dNomi_dVc; +double Denomi ,dDenomi_dVg ,dDenomi_dVd ,dDenomi_dVb ,dDenomi_dVc, dDenomi_dT; +double Qbf ,dQbf_dVg ,dQbf_dVb ,dQbf_dVd ,dQbf_dVc ,dQbf_dVe; +double Qsubs1 ,dQsubs1_dVg ,dQsubs1_dVb ,dQsubs1_dVd ,dQsubs1_dVc ,dQsubs1_dVe; +double Qsubs2 ,dQsubs2_dVg ,dQsubs2_dVb ,dQsubs2_dVd ,dQsubs2_dVc ,dQsubs2_dVe; +double Qsub0 ,dQsub0_dVg ,dQsub0_dVb ,dQsub0_dVd ; +double Qac0 ,dQac0_dVb ,dQac0_dVd; +double Qdep0 ,dQdep0_dVb; +double Qe1 , dQe1_dVg ,dQe1_dVb, dQe1_dVd, dQe1_dVe, dQe1_dT; +double Ce1g ,Ce1b ,Ce1d ,Ce1e, Ce1T; +double Ce2g ,Ce2b ,Ce2d ,Ce2e, Ce2T; +double Qe2 , dQe2_dVg ,dQe2_dVb, dQe2_dVd, dQe2_dVe, dQe2_dT; +double dQbf_dVrg, dQac0_dVrg, dQsub0_dVrg; +double dQsubs1_dVrg, dQsubs2_dVrg, dQbf0_dVe, dQbf0_dT; + +/* for self-heating */ +double vbi, vfbb, phi, sqrtPhi, Xdep0, jbjt, jdif, jrec, jtun, u0temp, vsattemp; +double rds0, ua, ub, uc; +double dvbi_dT, dvfbb_dT, djbjt_dT, djdif_dT, djrec_dT, djtun_dT, du0temp_dT; +double dvsattemp_dT, drds0_dT, dua_dT, dub_dT, duc_dT, dni_dT, dVtm_dT; +double dVfbeff_dT, dQac0_dT, dQsub0_dT, dQbf_dT, dVdsCV_dT, dPhisd_dT; +double dNomi_dT,dXc_dT,dQsubs1_dT,dQsubs2_dT, dVcsCV_dT, dPhisc_dT, dQsicv_dT; +double CbT, CsT, CgT, CeT; + +double Qex, dQex_dVg, dQex_dVb, dQex_dVd, dQex_dVe, dQex_dT; + +/* clean up last */ +FILE *fpdebug; +/* end clean up */ +int nandetect; +static int nanfound = 0; +char nanmessage [12]; + + + +for (; model != NULL; model = model->B3SOIDDnextModel) +{ for (here = model->B3SOIDDinstances; here != NULL; + here = here->B3SOIDDnextInstance) + { Check = 0; + ByPass = 0; + selfheat = (model->B3SOIDDshMod == 1) && (here->B3SOIDDrth0 != 0.0); + pParam = here->pParam; + + if (here->B3SOIDDdebugMod > 3) + { + if (model->B3SOIDDtype > 0) + fpdebug = fopen("b3soiddn.log", "a"); + else + fpdebug = fopen("b3soiddp.log", "a"); + + fprintf(fpdebug, "******* Time : %.5e ******* Device: %s Iteration: %d\n", + ckt->CKTtime, here->B3SOIDDname, here->B3SOIDDiterations); + } + + if ((ckt->CKTmode & MODEINITSMSIG)) + { vbs = *(ckt->CKTstate0 + here->B3SOIDDvbs); + vgs = *(ckt->CKTstate0 + here->B3SOIDDvgs); + ves = *(ckt->CKTstate0 + here->B3SOIDDves); + vps = *(ckt->CKTstate0 + here->B3SOIDDvps); + vds = *(ckt->CKTstate0 + here->B3SOIDDvds); + delTemp = *(ckt->CKTstate0 + here->B3SOIDDdeltemp); + + vg = *(ckt->CKTrhsOld + here->B3SOIDDgNode); + vd = *(ckt->CKTrhsOld + here->B3SOIDDdNodePrime); + vs = *(ckt->CKTrhsOld + here->B3SOIDDsNodePrime); + vp = *(ckt->CKTrhsOld + here->B3SOIDDpNode); + ve = *(ckt->CKTrhsOld + here->B3SOIDDeNode); + vb = *(ckt->CKTrhsOld + here->B3SOIDDbNode); + + if (here->B3SOIDDdebugMod > 2) + { + fprintf(fpdebug, "... INIT SMSIG ...\n"); + } + if (here->B3SOIDDdebugMod > 0) + { + fprintf(stderr,"DC op. point converge with %d iterations\n"); + } + } + else if ((ckt->CKTmode & MODEINITTRAN)) + { vbs = *(ckt->CKTstate1 + here->B3SOIDDvbs); + vgs = *(ckt->CKTstate1 + here->B3SOIDDvgs); + ves = *(ckt->CKTstate1 + here->B3SOIDDves); + vps = *(ckt->CKTstate1 + here->B3SOIDDvps); + vds = *(ckt->CKTstate1 + here->B3SOIDDvds); + delTemp = *(ckt->CKTstate1 + here->B3SOIDDdeltemp); + + vg = *(ckt->CKTrhsOld + here->B3SOIDDgNode); + vd = *(ckt->CKTrhsOld + here->B3SOIDDdNodePrime); + vs = *(ckt->CKTrhsOld + here->B3SOIDDsNodePrime); + vp = *(ckt->CKTrhsOld + here->B3SOIDDpNode); + ve = *(ckt->CKTrhsOld + here->B3SOIDDeNode); + vb = *(ckt->CKTrhsOld + here->B3SOIDDbNode); + + if (here->B3SOIDDdebugMod > 2) + { + fprintf(fpdebug, "... Init Transient ....\n"); + } + if (here->B3SOIDDdebugMod > 0) + { + fprintf(stderr, "Transient operation point converge with %d iterations\n", +here->B3SOIDDiterations); + } + here->B3SOIDDiterations = 0; + } + else if ((ckt->CKTmode & MODEINITJCT) && !here->B3SOIDDoff) + { vds = model->B3SOIDDtype * here->B3SOIDDicVDS; + vgs = model->B3SOIDDtype * here->B3SOIDDicVGS; + ves = model->B3SOIDDtype * here->B3SOIDDicVES; + vbs = model->B3SOIDDtype * here->B3SOIDDicVBS; + vps = model->B3SOIDDtype * here->B3SOIDDicVPS; + + vg = vd = vs = vp = ve = 0.0; + + here->B3SOIDDiterations = 0; /* initialize iteration number */ + + delTemp = 0.0; + here->B3SOIDDphi = pParam->B3SOIDDphi; + + + if (here->B3SOIDDdebugMod > 2) + fprintf(fpdebug, "... INIT JCT ...\n"); + + if ((vds == 0.0) && (vgs == 0.0) && (vbs == 0.0) && + ((ckt->CKTmode & (MODETRAN | MODEAC|MODEDCOP | + MODEDCTRANCURVE)) || (!(ckt->CKTmode & MODEUIC)))) + { vbs = 0.0; + vgs = model->B3SOIDDtype*0.1 + pParam->B3SOIDDvth0; + vds = 0.0; + ves = 0.0; + vps = 0.0; + } + } + else if ((ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) && + (here->B3SOIDDoff)) + { delTemp = vps = vbs = vgs = vds = ves = 0.0; + vg = vd = vs = vp = ve = 0.0; + here->B3SOIDDiterations = 0; /* initialize iteration number */ + } + else + { +#ifndef PREDICTOR + if ((ckt->CKTmode & MODEINITPRED)) + { xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1]; + *(ckt->CKTstate0 + here->B3SOIDDvbs) = + *(ckt->CKTstate1 + here->B3SOIDDvbs); + vbs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDvbs)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDvbs))); + *(ckt->CKTstate0 + here->B3SOIDDvgs) = + *(ckt->CKTstate1 + here->B3SOIDDvgs); + vgs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDvgs)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDvgs))); + *(ckt->CKTstate0 + here->B3SOIDDves) = + *(ckt->CKTstate1 + here->B3SOIDDves); + ves = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDves)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDves))); + *(ckt->CKTstate0 + here->B3SOIDDvps) = + *(ckt->CKTstate1 + here->B3SOIDDvps); + vps = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDvps)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDvps))); + *(ckt->CKTstate0 + here->B3SOIDDvds) = + *(ckt->CKTstate1 + here->B3SOIDDvds); + vds = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDvds)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDvds))); + *(ckt->CKTstate0 + here->B3SOIDDvbd) = + *(ckt->CKTstate0 + here->B3SOIDDvbs) + - *(ckt->CKTstate0 + here->B3SOIDDvds); + + *(ckt->CKTstate0 + here->B3SOIDDvg) = *(ckt->CKTstate1 + here->B3SOIDDvg); + *(ckt->CKTstate0 + here->B3SOIDDvd) = *(ckt->CKTstate1 + here->B3SOIDDvd); + *(ckt->CKTstate0 + here->B3SOIDDvs) = *(ckt->CKTstate1 + here->B3SOIDDvs); + *(ckt->CKTstate0 + here->B3SOIDDvp) = *(ckt->CKTstate1 + here->B3SOIDDvp); + *(ckt->CKTstate0 + here->B3SOIDDve) = *(ckt->CKTstate1 + here->B3SOIDDve); + + /* Only predict ve */ + ve = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDve)) + + - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDve))); + /* Then update vg, vs, vb, vd, vp base on ve */ + vs = ve - model->B3SOIDDtype * ves; + vg = model->B3SOIDDtype * vgs + vs; + vd = model->B3SOIDDtype * vds + vs; + vb = model->B3SOIDDtype * vbs + vs; + vp = model->B3SOIDDtype * vps + vs; + + delTemp = (1.0 + xfact)* (*(ckt->CKTstate1 + + here->B3SOIDDdeltemp))-(xfact * (*(ckt->CKTstate2 + + here->B3SOIDDdeltemp))); + + if (selfheat) + { + here->B3SOIDDphi = 2.0 * here->B3SOIDDvtm + * log (pParam->B3SOIDDnpeak / + here->B3SOIDDni); + } + + if (here->B3SOIDDdebugMod > 0) + { + fprintf(stderr, "Time = %.6e converge with %d iterations\n", ckt->CKTtime, here->B3SOIDDiterations); + } + if (here->B3SOIDDdebugMod > 2) + { + fprintf(fpdebug, "... PREDICTOR calculation ....\n"); + } + here->B3SOIDDiterations = 0; + } + else + { +#endif /* PREDICTOR */ + + vg = B3SOIDDlimit(*(ckt->CKTrhsOld + here->B3SOIDDgNode), + *(ckt->CKTstate0 + here->B3SOIDDvg), 3.0, &Check); + vd = B3SOIDDlimit(*(ckt->CKTrhsOld + here->B3SOIDDdNodePrime), + *(ckt->CKTstate0 + here->B3SOIDDvd), 3.0, &Check); + vs = B3SOIDDlimit(*(ckt->CKTrhsOld + here->B3SOIDDsNodePrime), + *(ckt->CKTstate0 + here->B3SOIDDvs), 3.0, &Check); + vp = B3SOIDDlimit(*(ckt->CKTrhsOld + here->B3SOIDDpNode), + *(ckt->CKTstate0 + here->B3SOIDDvp), 3.0, &Check); + ve = B3SOIDDlimit(*(ckt->CKTrhsOld + here->B3SOIDDeNode), + *(ckt->CKTstate0 + here->B3SOIDDve), 3.0, &Check); + delTemp = *(ckt->CKTrhsOld + here->B3SOIDDtempNode); + + vbs = model->B3SOIDDtype * (*(ckt->CKTrhsOld+here->B3SOIDDbNode) + - *(ckt->CKTrhsOld+here->B3SOIDDsNodePrime)); + + vps = model->B3SOIDDtype * (vp - vs); + vgs = model->B3SOIDDtype * (vg - vs); + ves = model->B3SOIDDtype * (ve - vs); + vds = model->B3SOIDDtype * (vd - vs); + + if (here->B3SOIDDdebugMod > 2) + { + fprintf(fpdebug, "... DC calculation ....\n"); +fprintf(fpdebug, "Vg = %.10f; Vb = %.10f; Vs = %.10f\n", + *(ckt->CKTrhsOld + here->B3SOIDDgNode), + *(ckt->CKTrhsOld + here->B3SOIDDbNode), + *(ckt->CKTrhsOld + here->B3SOIDDsNode)); +fprintf(fpdebug, "Vd = %.10f; Vsp = %.10f; Vdp = %.10f\n", + *(ckt->CKTrhsOld + here->B3SOIDDdNode), + *(ckt->CKTrhsOld + here->B3SOIDDsNodePrime), + *(ckt->CKTrhsOld + here->B3SOIDDdNodePrime)); +fprintf(fpdebug, "Ve = %.10f; Vp = %.10f; delTemp = %.10f\n", + *(ckt->CKTrhsOld + here->B3SOIDDeNode), + *(ckt->CKTrhsOld + here->B3SOIDDpNode), + *(ckt->CKTrhsOld + here->B3SOIDDtempNode)); + + } + +#ifndef PREDICTOR + } +#endif /* PREDICTOR */ + + vbd = vbs - vds; + vgd = vgs - vds; + ved = ves - vds; + vgdo = *(ckt->CKTstate0 + here->B3SOIDDvgs) + - *(ckt->CKTstate0 + here->B3SOIDDvds); + vedo = *(ckt->CKTstate0 + here->B3SOIDDves) + - *(ckt->CKTstate0 + here->B3SOIDDvds); + delvbs = vbs - *(ckt->CKTstate0 + here->B3SOIDDvbs); + delvbd = vbd - *(ckt->CKTstate0 + here->B3SOIDDvbd); + delvgs = vgs - *(ckt->CKTstate0 + here->B3SOIDDvgs); + delves = ves - *(ckt->CKTstate0 + here->B3SOIDDves); + delvps = vps - *(ckt->CKTstate0 + here->B3SOIDDvps); + deldelTemp = delTemp - *(ckt->CKTstate0 + here->B3SOIDDdeltemp); + delvds = vds - *(ckt->CKTstate0 + here->B3SOIDDvds); + delvgd = vgd - vgdo; + delved = ved - vedo; + + if (here->B3SOIDDmode >= 0) + { + cdhat = here->B3SOIDDcd + (here->B3SOIDDgm-here->B3SOIDDgjdg) * delvgs + + (here->B3SOIDDgds - here->B3SOIDDgjdd) * delvds + + (here->B3SOIDDgmbs - here->B3SOIDDgjdb) * delvbs + + (here->B3SOIDDgme - here->B3SOIDDgjde) * delves + + (here->B3SOIDDgmT - here->B3SOIDDgjdT) * deldelTemp; + } + else + { + cdhat = here->B3SOIDDcd + (here->B3SOIDDgm-here->B3SOIDDgjdg) * delvgd + - (here->B3SOIDDgds - here->B3SOIDDgjdd) * delvds + + (here->B3SOIDDgmbs - here->B3SOIDDgjdb) * delvbd + + (here->B3SOIDDgme - here->B3SOIDDgjde) * delved + + (here->B3SOIDDgmT - here->B3SOIDDgjdT) * deldelTemp; + + } + cbhat = here->B3SOIDDcb + here->B3SOIDDgbgs * delvgs + + here->B3SOIDDgbbs * delvbs + here->B3SOIDDgbds * delvds + + here->B3SOIDDgbes * delves + here->B3SOIDDgbps * delvps + + here->B3SOIDDgbT * deldelTemp; + +#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 + */ + + if (here->B3SOIDDdebugMod > 3) + { +fprintf(fpdebug, "Convergent Criteria : vbs %d vds %d vgs %d ves %d vps %d temp %d\n", + ((fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs), + fabs(*(ckt->CKTstate0+here->B3SOIDDvbs))) + ckt->CKTvoltTol))) ? 1 : 0, + ((fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), + fabs(*(ckt->CKTstate0+here->B3SOIDDvds))) + ckt->CKTvoltTol))) ? 1 : 0, + ((fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs), + fabs(*(ckt->CKTstate0+here->B3SOIDDvgs))) + ckt->CKTvoltTol))) ? 1 : 0, + ((fabs(delves) < (ckt->CKTreltol * MAX(fabs(ves), + fabs(*(ckt->CKTstate0+here->B3SOIDDves))) + ckt->CKTvoltTol))) ? 1 : 0, + ((fabs(delvps) < (ckt->CKTreltol * MAX(fabs(vps), + fabs(*(ckt->CKTstate0+here->B3SOIDDvps))) + ckt->CKTvoltTol))) ? 1 : 0, + ((fabs(deldelTemp) < (ckt->CKTreltol * MAX(fabs(delTemp), + fabs(*(ckt->CKTstate0+here->B3SOIDDdeltemp))) + ckt->CKTvoltTol*1e4))) ? 1 : 0); +fprintf(fpdebug, "delCd %.4e, delCb %.4e\n", fabs(cdhat - here->B3SOIDDcd) , + fabs(cbhat - here->B3SOIDDcb)); + + } + if ((!(ckt->CKTmode & MODEINITPRED)) && (ckt->CKTbypass) && Check == 0) + if ((fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs), + fabs(*(ckt->CKTstate0+here->B3SOIDDvbs))) + ckt->CKTvoltTol)) ) + if ((fabs(delvbd) < (ckt->CKTreltol * MAX(fabs(vbd), + fabs(*(ckt->CKTstate0+here->B3SOIDDvbd))) + ckt->CKTvoltTol)) ) + if ((fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs), + fabs(*(ckt->CKTstate0+here->B3SOIDDvgs))) + ckt->CKTvoltTol))) + if ((fabs(delves) < (ckt->CKTreltol * MAX(fabs(ves), + fabs(*(ckt->CKTstate0+here->B3SOIDDves))) + ckt->CKTvoltTol))) + if ( (here->B3SOIDDbodyMod == 0) || (here->B3SOIDDbodyMod == 2) || + (fabs(delvps) < (ckt->CKTreltol * MAX(fabs(vps), + fabs(*(ckt->CKTstate0+here->B3SOIDDvps))) + ckt->CKTvoltTol)) ) + if ( (here->B3SOIDDtempNode == 0) || + (fabs(deldelTemp) < (ckt->CKTreltol * MAX(fabs(delTemp), + fabs(*(ckt->CKTstate0+here->B3SOIDDdeltemp))) + + ckt->CKTvoltTol*1e4))) + if ((fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), + fabs(*(ckt->CKTstate0+here->B3SOIDDvds))) + ckt->CKTvoltTol))) + if ((fabs(cdhat - here->B3SOIDDcd) < ckt->CKTreltol + * MAX(fabs(cdhat),fabs(here->B3SOIDDcd)) + ckt->CKTabstol)) + if ((fabs(cbhat - here->B3SOIDDcb) < ckt->CKTreltol + * MAX(fabs(cbhat),fabs(here->B3SOIDDcb)) + ckt->CKTabstol) ) + { /* bypass code */ + vbs = *(ckt->CKTstate0 + here->B3SOIDDvbs); + vbd = *(ckt->CKTstate0 + here->B3SOIDDvbd); + vgs = *(ckt->CKTstate0 + here->B3SOIDDvgs); + ves = *(ckt->CKTstate0 + here->B3SOIDDves); + vps = *(ckt->CKTstate0 + here->B3SOIDDvps); + vds = *(ckt->CKTstate0 + here->B3SOIDDvds); + delTemp = *(ckt->CKTstate0 + here->B3SOIDDdeltemp); + + /* calculate Vds for temperature conductance calculation + in bypass (used later when filling Temp node matrix) */ + Vds = here->B3SOIDDmode > 0 ? vds : -vds; + + vgd = vgs - vds; + vgb = vgs - vbs; + veb = ves - vbs; + + if (here->B3SOIDDdebugMod > 2) + { +fprintf(stderr, "Bypass for %s...\n", here->B3SOIDDname); + fprintf(fpdebug, "... By pass ....\n"); + fprintf(fpdebug, "vgs=%.4f, vds=%.4f, vbs=%.4f, ", + vgs, vds, vbs); + fprintf(fpdebug, "ves=%.4f, vps=%.4f\n", ves, vps); + } + if ((ckt->CKTmode & (MODETRAN | MODEAC)) || + ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) + { ByPass = 1; + goto line755; + } + else + { goto line850; + } + } + + +#endif /*NOBYPASS*/ + von = here->B3SOIDDvon; + + if ((here->B3SOIDDdebugMod > 1) || (here->B3SOIDDdebugMod == -1)) + { + here->B3SOIDDdum1 = here->B3SOIDDdum2 = here->B3SOIDDdum3 = 0.0; + here->B3SOIDDdum4 = here->B3SOIDDdum5 = 0.0; + Qac0 = Qsub0 = Qsubs1 = Qsubs2 = Qbf = Qe1 = Qe2 = 0.0; + qjs = qjd = Cbg = Cbb = Cbd = Cbe = Xc = qdrn = qgate = 0.0; + qbody = qsub = 0.0; + } + + if (here->B3SOIDDdebugMod > 2) { + fprintf(fpdebug, "Limited : vgs = %.8f\n", vgs); + fprintf(fpdebug, "Limited : vds = %.8f\n", vds); + } + + if (*(ckt->CKTstate0 + here->B3SOIDDvds) >= 0.0) + T0 = *(ckt->CKTstate0 + here->B3SOIDDvbs); + else + T0 = *(ckt->CKTstate0 + here->B3SOIDDvbd); + + if (here->B3SOIDDdebugMod > 2) + fprintf(fpdebug, "Before lim : vbs = %.8f, after = ", T0); + + if (vds >= 0.0) + { + vbs = B3SOIDDlimit(vbs, T0, 0.2, &Check); + vbs = B3SOIDDSmartVbs(vbs, T0, here, ckt, &Check); + vbd = vbs - vds; + vb = model->B3SOIDDtype * vbs + vs; + if (here->B3SOIDDdebugMod > 2) + fprintf(fpdebug, "%.8f\n", vbs); + } else + { + vbd = B3SOIDDlimit(vbd, T0, 0.2, &Check); + vbd = B3SOIDDSmartVbs(vbd, T0, here, ckt, &Check); + vbs = vbd + vds; + vb = model->B3SOIDDtype * vbs + vd; + if (here->B3SOIDDdebugMod > 2) + fprintf(fpdebug, "%.8f\n", vbd); + } + + delTemp =B3SOIDDlimit(delTemp, *(ckt->CKTstate0 + here->B3SOIDDdeltemp),5.0,&Check); + + } + +/* Calculate temperature dependent values for self-heating effect */ + Temp = delTemp + ckt->CKTtemp; +/* for debugging + Temp = ckt->CKTtemp; + selfheat = 1; + if (here->B3SOIDDname[1] == '2') + { + Temp += 0.01; + } */ + TempRatio = Temp / model->B3SOIDDtnom; + + if (selfheat) { + Vtm = KboQ * Temp; + + T0 = 1108.0 + Temp; + T5 = Temp * Temp; + Eg = 1.16 - 7.02e-4 * T5 / T0; + T1 = ((7.02e-4 * T5) - T0 * (14.04e-4 * Temp)) / T0 / T0; + /* T1 = dEg / dT */ + + T2 = 1.9230584e-4; /* T2 = 1 / 300.15^(3/2) */ + T5 = sqrt(Temp); + T3 = 1.45e10 * Temp * T5 * T2; + T4 = exp(21.5565981 - Eg / (2.0 * Vtm)); + ni = T3 * T4; + dni_dT = 2.175e10 * T2 * T5 * T4 + T3 * T4 * + (-Vtm * T1 + Eg * KboQ) / (2.0 * Vtm * Vtm); + + T0 = log(1.0e20 * pParam->B3SOIDDnpeak / (ni * ni)); + vbi = Vtm * T0; + dvbi_dT = KboQ * T0 + Vtm * (-2.0 * dni_dT / ni); + + if (pParam->B3SOIDDnsub > 0) { + T0 = log(pParam->B3SOIDDnpeak / pParam->B3SOIDDnsub); + vfbb = -model->B3SOIDDtype * Vtm*T0; + dvfbb_dT = -model->B3SOIDDtype * KboQ*T0; + } + else { + T0 = log(-pParam->B3SOIDDnpeak*pParam->B3SOIDDnsub/ni/ni); + vfbb = -model->B3SOIDDtype * Vtm*T0; + dvfbb_dT = -model->B3SOIDDtype * + (KboQ * T0 + Vtm * 2.0 * dni_dT / ni); + } + +/* phi = 2.0 * Vtm * log(pParam->B3SOIDDnpeak / ni); */ + phi = here->B3SOIDDphi; + sqrtPhi = sqrt(phi); + Xdep0 = sqrt(2.0 * EPSSI / (Charge_q + * pParam->B3SOIDDnpeak * 1.0e6)) + * sqrtPhi; + /* Save the values below for phi calculation in B3SOIDDaccept() */ + here->B3SOIDDvtm = Vtm; + here->B3SOIDDni = ni; + + /* Use dTx_dVe variables to act as dTx_dT variables */ + + T8 = 1 / model->B3SOIDDtnom; + T7 = model->B3SOIDDxbjt / pParam->B3SOIDDndiode; + T0 = pow(TempRatio, T7); + dT0_dVe = T7 * pow(TempRatio, T7 - 1.0) * T8; + + T7 = model->B3SOIDDxdif / pParam->B3SOIDDndiode; + T1 = pow(TempRatio, T7); + dT1_dVe = T7 * pow(TempRatio, T7 - 1.0) * T8; + + T7 = model->B3SOIDDxrec / pParam->B3SOIDDndiode / 2.0; + T2 = pow(TempRatio, T7); + dT2_dVe = T7 * pow(TempRatio, T7 - 1.0) * T8; + + T3 = TempRatio - 1.0; + T4 = Eg300 / pParam->B3SOIDDndiode / Vtm * T3; + dT4_dVe = Eg300 / pParam->B3SOIDDndiode / Vtm / Vtm * + (Vtm * T8 - T3 * KboQ); + T5 = exp(T4); + dT5_dVe = dT4_dVe * T5; + T6 = sqrt(T5); + dT6_dVe = 0.5 / T6 * dT5_dVe; + + jbjt = pParam->B3SOIDDisbjt * T0 * T5; + jdif = pParam->B3SOIDDisdif * T1 * T5; + jrec = pParam->B3SOIDDisrec * T2 * T6; + djbjt_dT = pParam->B3SOIDDisbjt * (T0 * dT5_dVe + T5 * dT0_dVe); + djdif_dT = pParam->B3SOIDDisdif * (T1 * dT5_dVe + T5 * dT1_dVe); + djrec_dT = pParam->B3SOIDDisrec * (T2 * dT6_dVe + T6 * dT2_dVe); + + T7 = model->B3SOIDDxtun / pParam->B3SOIDDntun; + T0 = pow(TempRatio, T7); + jtun = model->B3SOIDDistun * T0; + djtun_dT = model->B3SOIDDistun * T7 * pow(TempRatio, T7 - 1.0) * T8; + + u0temp = pParam->B3SOIDDu0 * pow(TempRatio, pParam->B3SOIDDute); + du0temp_dT = pParam->B3SOIDDu0 * pParam->B3SOIDDute * + pow(TempRatio, pParam->B3SOIDDute - 1.0) * T8; + + vsattemp = pParam->B3SOIDDvsat - pParam->B3SOIDDat * T3; + dvsattemp_dT = -pParam->B3SOIDDat * T8; + + rds0 = (pParam->B3SOIDDrdsw + pParam->B3SOIDDprt + * T3) / pParam->B3SOIDDrds0denom; + drds0_dT = pParam->B3SOIDDprt / pParam->B3SOIDDrds0denom * T8; + + ua = pParam->B3SOIDDuatemp + pParam->B3SOIDDua1 * T3; + ub = pParam->B3SOIDDubtemp + pParam->B3SOIDDub1 * T3; + uc = pParam->B3SOIDDuctemp + pParam->B3SOIDDuc1 * T3; + dua_dT = pParam->B3SOIDDua1 * T8; + dub_dT = pParam->B3SOIDDub1 * T8; + duc_dT = pParam->B3SOIDDuc1 * T8; + } + else { + vbi = pParam->B3SOIDDvbi; + vfbb = pParam->B3SOIDDvfbb; + phi = pParam->B3SOIDDphi; + sqrtPhi = pParam->B3SOIDDsqrtPhi; + Xdep0 = pParam->B3SOIDDXdep0; + jbjt = pParam->B3SOIDDjbjt; + jdif = pParam->B3SOIDDjdif; + jrec = pParam->B3SOIDDjrec; + jtun = pParam->B3SOIDDjtun; + u0temp = pParam->B3SOIDDu0temp; + vsattemp = pParam->B3SOIDDvsattemp; + rds0 = pParam->B3SOIDDrds0; + ua = pParam->B3SOIDDua; + ub = pParam->B3SOIDDub; + uc = pParam->B3SOIDDuc; + dni_dT = dvbi_dT = dvfbb_dT = djbjt_dT = djdif_dT = 0.0; + djrec_dT = djtun_dT = du0temp_dT = dvsattemp_dT = 0.0; + drds0_dT = dua_dT = dub_dT = duc_dT = 0.0; + } + + /* TempRatio used for Vth and mobility */ + if (selfheat) { + TempRatio = Temp / model->B3SOIDDtnom - 1.0; + } + else { + TempRatio = ckt->CKTtemp / model->B3SOIDDtnom - 1.0; + } + + /* determine DC current and derivatives */ + vbd = vbs - vds; + vgd = vgs - vds; + vgb = vgs - vbs; + ved = ves - vds; + veb = ves - vbs; + vge = vgs - ves; + vpd = vps - vds; + + + if (vds >= 0.0) + { /* normal mode */ + here->B3SOIDDmode = 1; + Vds = vds; + Vgs = vgs; + Vbs = vbs; + Vbd = vbd; + Ves = ves; + Vps = vps; + } + else + { /* inverse mode */ + here->B3SOIDDmode = -1; + Vds = -vds; + Vgs = vgd; + Vbs = vbd; + Vbd = vbs; + Ves = ved; + Vps = vpd; + } + + + if (here->B3SOIDDdebugMod > 2) + { + fprintf(fpdebug, "Vgs=%.4f, Vds=%.4f, Vbs=%.4f, ", + Vgs, Vds, Vbs); + fprintf(fpdebug, "Ves=%.4f, Vps=%.4f, Temp=%.1f\n", + Ves, Vps, Temp); + } + + Vesfb = Ves - vfbb; + Cbox = model->B3SOIDDcbox; + K1 = pParam->B3SOIDDk1; + + ChargeComputationNeeded = + ((ckt->CKTmode & (MODEAC | MODETRAN | MODEINITSMSIG)) || + ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) + ? 1 : 0; + + if (here->B3SOIDDdebugMod == -1) + ChargeComputationNeeded = 1; + + + + +/* Poly Gate Si Depletion Effect */ + T0 = pParam->B3SOIDDvfb + phi; + if ((pParam->B3SOIDDngate > 1.e18) && (pParam->B3SOIDDngate < 1.e25) + && (Vgs > T0)) + /* added to avoid the problem caused by ngate */ + { T1 = 1.0e6 * Charge_q * EPSSI * pParam->B3SOIDDngate + / (model->B3SOIDDcox * model->B3SOIDDcox); + T4 = sqrt(1.0 + 2.0 * (Vgs - T0) / T1); + T2 = T1 * (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; + } + + + Leff = pParam->B3SOIDDleff; + + if (selfheat) { + Vtm = KboQ * Temp; + dVtm_dT = KboQ; + } + else { + Vtm = model->B3SOIDDvtm; + dVtm_dT = 0.0; + } + + V0 = vbi - phi; + +/* Prepare Vbs0t */ + T0 = -pParam->B3SOIDDdvbd1 * pParam->B3SOIDDleff / pParam->B3SOIDDlitl; + T1 = pParam->B3SOIDDdvbd0 * (exp(0.5*T0) + 2*exp(T0)); + T2 = T1 * (vbi - phi); + T3 = 0.5 * model->B3SOIDDqsi / model->B3SOIDDcsi; + Vbs0t = phi - T3 + pParam->B3SOIDDvbsa + T2; + if (selfheat) + dVbs0t_dT = T1 * dvbi_dT; + else + dVbs0t_dT = 0.0; + +/* Prepare Vbs0 */ + T0 = 1 + model->B3SOIDDcsieff / Cbox; + T1 = pParam->B3SOIDDkb1 / T0; + T2 = T1 * (Vbs0t - Vesfb); + + /* T6 is Vbs0 before limiting */ + T6 = Vbs0t - T2; + dT6_dVe = T1; + if (selfheat) + dT6_dT = dVbs0t_dT - T1 * (dVbs0t_dT + dvfbb_dT); + else + dT6_dT = 0.0; + + /* limit Vbs0 to below phi */ + T1 = phi - pParam->B3SOIDDdelp; + T2 = T1 - T6 - DELT_Vbseff; + T3 = sqrt(T2 * T2 + 4.0 * DELT_Vbseff); + Vbs0 = T1 - 0.5 * (T2 + T3); + T4 = 0.5 * (1 + T2/T3); + dVbs0_dVe = T4 * dT6_dVe; + if (selfheat) dVbs0_dT = T4 * dT6_dT; + else dVbs0_dT = 0.0; + + T1 = Vbs0t - Vbs0 - DELT_Vbsmos; + T2 = sqrt(T1 * T1 + DELT_Vbsmos * DELT_Vbsmos); + T3 = 0.5 * (T1 + T2); + T4 = T3 * model->B3SOIDDcsieff / model->B3SOIDDqsieff; + Vbs0mos = Vbs0 - 0.5 * T3 * T4; + T5 = 0.5 * T4 * (1 + T1 / T2); + dVbs0mos_dVe = dVbs0_dVe * (1 + T5); + if (selfheat) + dVbs0mos_dT = dVbs0_dT - (dVbs0t_dT - dVbs0_dT) * T5; + else + dVbs0mos_dT = 0.0; + +/* Prepare Vthfd - treat Vbs0mos as if it were independent variable Vb */ + Phis = phi - Vbs0mos; + dPhis_dVb = -1; + sqrtPhis = sqrt(Phis); + dsqrtPhis_dVb = -0.5 / sqrtPhis; + Xdep = Xdep0 * sqrtPhis / sqrtPhi; + dXdep_dVb = (Xdep0 / sqrtPhi) + * dsqrtPhis_dVb; + sqrtXdep = sqrt(Xdep); + + T0 = pParam->B3SOIDDdvt2 * Vbs0mos; + if (T0 >= - 0.5) + { T1 = 1.0 + T0; + T2 = pParam->B3SOIDDdvt2; + } + else /* Added to avoid any discontinuity problems caused by dvt2*/ + { T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = pParam->B3SOIDDdvt2 * T4 * T4; + } + lt1 = model->B3SOIDDfactor1 * sqrtXdep * T1; + dlt1_dVb = model->B3SOIDDfactor1 * (0.5 / sqrtXdep * T1 * dXdep_dVb + + sqrtXdep * T2); + + T0 = pParam->B3SOIDDdvt2w * Vbs0mos; + if (T0 >= - 0.5) + { T1 = 1.0 + T0; + T2 = pParam->B3SOIDDdvt2w; + } + else /* Added to avoid any discontinuity problems caused by + dvt2w */ + { T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = pParam->B3SOIDDdvt2w * T4 * T4; + } + ltw= model->B3SOIDDfactor1 * sqrtXdep * T1; + dltw_dVb = model->B3SOIDDfactor1 * (0.5 / sqrtXdep * T1 * dXdep_dVb + + sqrtXdep * T2); + + T0 = -0.5 * pParam->B3SOIDDdvt1 * Leff / lt1; + if (T0 > -EXP_THRESHOLD) + { T1 = exp(T0); + dT1_dVb = -T0 / lt1 * T1 * dlt1_dVb; + Theta0 = T1 * (1.0 + 2.0 * T1); + dTheta0_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { T1 = MIN_EXP; + Theta0 = T1 * (1.0 + 2.0 * T1); + dTheta0_dVb = 0.0; + } + here->B3SOIDDthetavth = pParam->B3SOIDDdvt0 * Theta0; + Delt_vth = here->B3SOIDDthetavth * V0; + dDelt_vth_dVb = pParam->B3SOIDDdvt0 * dTheta0_dVb * V0; + if (selfheat) dDelt_vth_dT = here->B3SOIDDthetavth * dvbi_dT; + else dDelt_vth_dT = 0.0; + + T0 = -0.5*pParam->B3SOIDDdvt1w * pParam->B3SOIDDweff*Leff/ltw; + if (T0 > -EXP_THRESHOLD) + { T1 = exp(T0); + T2 = T1 * (1.0 + 2.0 * T1); + dT1_dVb = -T0 / ltw * T1 * dltw_dVb; + dT2_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { T1 = MIN_EXP; + T2 = T1 * (1.0 + 2.0 * T1); + dT2_dVb = 0.0; + } + T0 = pParam->B3SOIDDdvt0w * T2; + DeltVthw = T0 * V0; + dDeltVthw_dVb = pParam->B3SOIDDdvt0w * dT2_dVb * V0; + if (selfheat) dDeltVthw_dT = T0 * dvbi_dT; + else dDeltVthw_dT = 0.0; + + T0 = sqrt(1.0 + pParam->B3SOIDDnlx / Leff); + T1 = (pParam->B3SOIDDkt1 + pParam->B3SOIDDkt1l / Leff + + pParam->B3SOIDDkt2 * Vbs0mos); + DeltVthtemp = pParam->B3SOIDDk1 * (T0 - 1.0) * sqrtPhi + T1 * TempRatio; + if (selfheat) dDeltVthtemp_dT = T1 / model->B3SOIDDtnom; + else dDeltVthtemp_dT = 0.0; + + tmp2 = model->B3SOIDDtox * phi + / (pParam->B3SOIDDweff + pParam->B3SOIDDw0); + + T3 = pParam->B3SOIDDeta0 + pParam->B3SOIDDetab * Vbs0mos; + if (T3 < 1.0e-4) /* avoid discontinuity problems caused by etab */ + { T9 = 1.0 / (3.0 - 2.0e4 * T3); + T3 = (2.0e-4 - T3) * T9; + T4 = T9 * T9 * pParam->B3SOIDDetab; + dT3_dVb = T4; + } + else + { + dT3_dVb = pParam->B3SOIDDetab; + } + DIBL_Sft = T3 * pParam->B3SOIDDtheta0vb0 * Vds; + dDIBL_Sft_dVd = T3 * pParam->B3SOIDDtheta0vb0; + dDIBL_Sft_dVb = pParam->B3SOIDDtheta0vb0 * Vds * dT3_dVb; + + Vthfd = model->B3SOIDDtype * pParam->B3SOIDDvth0 + pParam->B3SOIDDk1 + * (sqrtPhis - sqrtPhi) - pParam->B3SOIDDk2 + * Vbs0mos-Delt_vth-DeltVthw +(pParam->B3SOIDDk3 +pParam->B3SOIDDk3b + * Vbs0mos) * tmp2 + DeltVthtemp - DIBL_Sft; + + T6 = pParam->B3SOIDDk3b * tmp2 - pParam->B3SOIDDk2 + + pParam->B3SOIDDkt2 * TempRatio; + dVthfd_dVd = -dDIBL_Sft_dVd; + T7 = pParam->B3SOIDDk1 * dsqrtPhis_dVb + - dDelt_vth_dVb - dDeltVthw_dVb + + T6 - dDIBL_Sft_dVb; + dVthfd_dVe = T7 * dVbs0mos_dVe; + if (selfheat) + dVthfd_dT = dDeltVthtemp_dT - dDelt_vth_dT - dDeltVthw_dT + + T7 * dVbs0mos_dT; + else + dVthfd_dT = 0.0; + +/* Effective Vbs0 and Vbs0t for all Vgs */ + T1 = Vthfd - Vgs_eff - DELT_Vbs0eff; + T2 = sqrt(T1 * T1 + DELT_Vbs0eff * DELT_Vbs0eff ); + + Vbs0teff = Vbs0t - 0.5 * (T1 + T2); + dVbs0teff_dVg = 0.5 * (1 + T1/T2) * dVgs_eff_dVg; + dVbs0teff_dVd = - 0.5 * (1 + T1 / T2) * dVthfd_dVd; + dVbs0teff_dVe = - 0.5 * (1 + T1 / T2) * dVthfd_dVe; + if (selfheat) + dVbs0teff_dT = dVbs0t_dT - 0.5 * (1 + T1 / T2) * dVthfd_dT; + else + dVbs0teff_dT = 0.0; + + /* Calculate nfb */ + T3 = 1 / (K1 * K1); + T4 = pParam->B3SOIDDkb3 * Cbox / model->B3SOIDDcox; + T8 = sqrt(phi - Vbs0mos); + T5 = sqrt(1 + 4 * T3 * (phi + K1 * T8 - Vbs0mos)); + T6 = 1 + T4 * T5; + Nfb = model->B3SOIDDnfb = 1 / T6; + T7 = 2 * T3 * T4 * Nfb * Nfb / T5 * (0.5 * K1 / T8 + 1); + Vbs0eff = Vbs0 - Nfb * 0.5 * (T1 + T2); + dVbs0eff_dVg = Nfb * 0.5 * (1 + T1/T2) * dVgs_eff_dVg; + dVbs0eff_dVd = - Nfb * 0.5 * (1 + T1 / T2) * dVthfd_dVd; + dVbs0eff_dVe = dVbs0_dVe - Nfb * 0.5 * (1 + T1 / T2) + * dVthfd_dVe - T7 * 0.5 * (T1 + T2) * dVbs0mos_dVe; + if (selfheat) + dVbs0eff_dT = dVbs0_dT - Nfb * 0.5 * (1 + T1 / T2) + * dVthfd_dT - T7 * 0.5 * (T1 + T2) * dVbs0mos_dT; + else + dVbs0eff_dT = 0.0; + +/* Simple check of Vbs */ +/* Prepare Vbsdio */ + T1 = Vbs - (Vbs0eff + OFF_Vbsdio) - DELT_Vbsdio; + T2 = sqrt(T1*T1 + DELT_Vbsdio * DELT_Vbsdio); + T3 = 0.5 * (1 + T1/T2); + + Vbsdio = Vbs0eff + OFF_Vbsdio + 0.5 * (T1 + T2); + dVbsdio_dVg = (1 - T3) * dVbs0eff_dVg; + dVbsdio_dVd = (1 - T3) * dVbs0eff_dVd; + dVbsdio_dVe = (1 - T3) * dVbs0eff_dVe; + if (selfheat) dVbsdio_dT = (1 - T3) * dVbs0eff_dT; + else dVbsdio_dT = 0.0; + dVbsdio_dVb = T3; + +/* Prepare Vbseff */ + T1 = Vbs0teff - Vbsdio - DELT_Vbsmos; + T2 = sqrt(T1 * T1 + DELT_Vbsmos * DELT_Vbsmos); + T3 = 0.5 * (T1 + T2); + T5 = 0.5 * (1 + T1/T2); + dT3_dVg = T5 * (dVbs0teff_dVg - dVbsdio_dVg); + dT3_dVd = T5 * (dVbs0teff_dVd - dVbsdio_dVd); + dT3_dVb = - T5 * dVbsdio_dVb; + dT3_dVe = T5 * (dVbs0teff_dVe - dVbsdio_dVe); + if (selfheat) dT3_dT = T5 * (dVbs0teff_dT - dVbsdio_dT); + else dT3_dT = 0.0; + T4 = T3 * model->B3SOIDDcsieff / model->B3SOIDDqsieff; + + Vbsmos = Vbsdio - 0.5 * T3 * T4; + dVbsmos_dVg = dVbsdio_dVg - T4 * dT3_dVg; + dVbsmos_dVd = dVbsdio_dVd - T4 * dT3_dVd; + dVbsmos_dVb = dVbsdio_dVb - T4 * dT3_dVb; + dVbsmos_dVe = dVbsdio_dVe - T4 * dT3_dVe; + if (selfheat) dVbsmos_dT = dVbsdio_dT - T4 * dT3_dT; + else dVbsmos_dT = 0.0; + +/* Prepare Vcs */ + Vcs = Vbsdio - Vbs0eff; + dVcs_dVb = dVbsdio_dVb; + dVcs_dVg = dVbsdio_dVg - dVbs0eff_dVg; + dVcs_dVd = dVbsdio_dVd - dVbs0eff_dVd; + dVcs_dVe = dVbsdio_dVe - dVbs0eff_dVe; + dVcs_dT = dVbsdio_dT - dVbs0eff_dT; + +/* Check Vps */ + /* Note : if Vps is less Vbs0eff => non-physical */ + T1 = Vps - Vbs0eff + DELT_Vbs0dio; + T2 = sqrt(T1 * T1 + DELT_Vbs0dio * DELT_Vbs0dio); + T3 = 0.5 * (1 + T1/T2); + Vpsdio = Vbs0eff + 0.5 * (T1 + T2); + dVpsdio_dVg = (1 - T3) * dVbs0eff_dVg; + dVpsdio_dVd = (1 - T3) * dVbs0eff_dVd; + dVpsdio_dVe = (1 - T3) * dVbs0eff_dVe; + if (selfheat) dVpsdio_dT = (1 - T3) * dVbs0eff_dT; + else dVpsdio_dT = 0.0; + dVpsdio_dVp = T3; + Vbp = Vbsdio - Vpsdio; + dVbp_dVb = dVbsdio_dVb; + dVbp_dVg = dVbsdio_dVg - dVpsdio_dVg; + dVbp_dVd = dVbsdio_dVd - dVpsdio_dVd; + dVbp_dVe = dVbsdio_dVe - dVpsdio_dVe; + dVbp_dT = dVbsdio_dT - dVpsdio_dT; + dVbp_dVp = - dVpsdio_dVp; + + here->B3SOIDDvbsdio = Vbsdio; + here->B3SOIDDvbs0eff = Vbs0eff; + + T1 = phi - pParam->B3SOIDDdelp; + T2 = T1 - Vbsmos - DELT_Vbseff; + T3 = sqrt(T2 * T2 + 4.0 * DELT_Vbseff * T1); + Vbseff = T1 - 0.5 * (T2 + T3); + T4 = 0.5 * (1 + T2/T3); + dVbseff_dVg = T4 * dVbsmos_dVg; + dVbseff_dVd = T4 * dVbsmos_dVd; + dVbseff_dVb = T4 * dVbsmos_dVb; + dVbseff_dVe = T4 * dVbsmos_dVe; + if (selfheat) dVbseff_dT = T4 * dVbsmos_dT; + else dVbseff_dT = 0.0; + + here->B3SOIDDvbseff = Vbseff; + + Phis = phi - Vbseff; + dPhis_dVb = -1; + sqrtPhis = sqrt(Phis); + dsqrtPhis_dVb = -0.5 / sqrtPhis ; + + Xdep = Xdep0 * sqrtPhis / sqrtPhi; + dXdep_dVb = (Xdep0 / sqrtPhi) + * dsqrtPhis_dVb; + +/* Vth Calculation */ + T3 = sqrt(Xdep); + + T0 = pParam->B3SOIDDdvt2 * Vbseff; + if (T0 >= - 0.5) + { T1 = 1.0 + T0; + T2 = pParam->B3SOIDDdvt2 ; + } + else /* Added to avoid any discontinuity problems caused by dvt2 */ + { T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = pParam->B3SOIDDdvt2 * T4 * T4 ; + } + lt1 = model->B3SOIDDfactor1 * T3 * T1; + dlt1_dVb =model->B3SOIDDfactor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2); + + T0 = pParam->B3SOIDDdvt2w * Vbseff; + if (T0 >= - 0.5) + { T1 = 1.0 + T0; + T2 = pParam->B3SOIDDdvt2w ; + } + else /* Added to avoid any discontinuity problems caused by dvt2w */ + { T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = pParam->B3SOIDDdvt2w * T4 * T4 ; + } + ltw= model->B3SOIDDfactor1 * T3 * T1; + dltw_dVb=model->B3SOIDDfactor1*(0.5 / T3 * T1 * dXdep_dVb + T3 * T2); + + T0 = -0.5 * pParam->B3SOIDDdvt1 * Leff / lt1; + if (T0 > -EXP_THRESHOLD) + { T1 = exp(T0); + Theta0 = T1 * (1.0 + 2.0 * T1); + dT1_dVb = -T0 / lt1 * T1 * dlt1_dVb; + dTheta0_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { T1 = MIN_EXP; + Theta0 = T1 * (1.0 + 2.0 * T1); + dTheta0_dVb = 0.0; + } + + here->B3SOIDDthetavth = pParam->B3SOIDDdvt0 * Theta0; + Delt_vth = here->B3SOIDDthetavth * V0; + dDelt_vth_dVb = pParam->B3SOIDDdvt0 * dTheta0_dVb * V0; + if (selfheat) dDelt_vth_dT = here->B3SOIDDthetavth * dvbi_dT; + else dDelt_vth_dT = 0.0; + + T0 = -0.5 * pParam->B3SOIDDdvt1w * pParam->B3SOIDDweff * Leff / ltw; + if (T0 > -EXP_THRESHOLD) + { T1 = exp(T0); + T2 = T1 * (1.0 + 2.0 * T1); + dT1_dVb = -T0 / ltw * T1 * dltw_dVb; + dT2_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { T1 = MIN_EXP; + T2 = T1 * (1.0 + 2.0 * T1); + dT2_dVb = 0.0; + } + + T0 = pParam->B3SOIDDdvt0w * T2; + DeltVthw = T0 * V0; + dDeltVthw_dVb = pParam->B3SOIDDdvt0w * dT2_dVb * V0; + if (selfheat) dDeltVthw_dT = T0 * dvbi_dT; + else dDeltVthw_dT = 0.0; + + T0 = sqrt(1.0 + pParam->B3SOIDDnlx / Leff); + T1 = (pParam->B3SOIDDkt1 + pParam->B3SOIDDkt1l / Leff + + pParam->B3SOIDDkt2 * Vbseff); + DeltVthtemp = pParam->B3SOIDDk1 * (T0 - 1.0) * sqrtPhi + T1 * TempRatio; + if (selfheat) + dDeltVthtemp_dT = T1 / model->B3SOIDDtnom; + else + dDeltVthtemp_dT = 0.0; + + tmp2 = model->B3SOIDDtox * phi + / (pParam->B3SOIDDweff + pParam->B3SOIDDw0); + + T3 = pParam->B3SOIDDeta0 + pParam->B3SOIDDetab * Vbseff; + if (T3 < 1.0e-4) /* avoid discontinuity problems caused by etab */ + { T9 = 1.0 / (3.0 - 2.0e4 * T3); + T3 = (2.0e-4 - T3) * T9; + T4 = T9 * T9 * pParam->B3SOIDDetab; + dT3_dVb = T4 ; + } + else + { + dT3_dVb = pParam->B3SOIDDetab ; + } + DIBL_Sft = T3 * pParam->B3SOIDDtheta0vb0 * Vds; + dDIBL_Sft_dVd = pParam->B3SOIDDtheta0vb0 * T3; + dDIBL_Sft_dVb = pParam->B3SOIDDtheta0vb0 * Vds * dT3_dVb; + + Vth = model->B3SOIDDtype * pParam->B3SOIDDvth0 + pParam->B3SOIDDk1 + * (sqrtPhis - sqrtPhi) - pParam->B3SOIDDk2 + * Vbseff- Delt_vth - DeltVthw +(pParam->B3SOIDDk3 + pParam->B3SOIDDk3b + * Vbseff) * tmp2 + DeltVthtemp - DIBL_Sft; + + here->B3SOIDDvon = Vth; + + T6 = pParam->B3SOIDDk3b * tmp2 - pParam->B3SOIDDk2 + + pParam->B3SOIDDkt2 * TempRatio; + dVth_dVb = pParam->B3SOIDDk1 * dsqrtPhis_dVb + - dDelt_vth_dVb - dDeltVthw_dVb + + T6 - dDIBL_Sft_dVb; /* this is actually dVth_dVbseff */ + dVth_dVd = -dDIBL_Sft_dVd; + if (selfheat) dVth_dT = dDeltVthtemp_dT - dDelt_vth_dT - dDeltVthw_dT; + else dVth_dT = 0.0; + +/* Calculate n */ + T2 = pParam->B3SOIDDnfactor * EPSSI / Xdep; + dT2_dVb = - T2 / Xdep * dXdep_dVb; + + T3 = pParam->B3SOIDDcdsc + pParam->B3SOIDDcdscb * Vbseff + + pParam->B3SOIDDcdscd * Vds; + dT3_dVb = pParam->B3SOIDDcdscb; + dT3_dVd = pParam->B3SOIDDcdscd; + + T4 = (T2 + T3 * Theta0 + pParam->B3SOIDDcit) / model->B3SOIDDcox; + dT4_dVb = (dT2_dVb + Theta0 * dT3_dVb + dTheta0_dVb * T3) + / model->B3SOIDDcox; + dT4_dVd = Theta0 * dT3_dVd / model->B3SOIDDcox; + + if (T4 >= -0.5) + { n = 1.0 + T4; + dn_dVb = dT4_dVb; + dn_dVd = dT4_dVd; + } + else + /* avoid discontinuity problems caused by T4 */ + { T0 = 1.0 / (3.0 + 8.0 * T4); + n = (1.0 + 3.0 * T4) * T0; + T0 *= T0; + dn_dVb = T0 * dT4_dVb; + dn_dVd = T0 * dT4_dVd; + } + +/* Effective Vgst (Vgsteff) Calculation */ + + Vgst = Vgs_eff - Vth; + + T10 = 2.0 * n * Vtm; + VgstNVt = Vgst / T10; + ExpArg = (2.0 * pParam->B3SOIDDvoff - Vgst) / T10; + + /* MCJ: Very small Vgst */ + if (VgstNVt > EXP_THRESHOLD) + { Vgsteff = Vgst; + /* T0 is dVgsteff_dVbseff */ + T0 = -dVth_dVb; + dVgsteff_dVg = dVgs_eff_dVg + T0 * dVbseff_dVg; + dVgsteff_dVd = -dVth_dVd + T0 * dVbseff_dVd; + dVgsteff_dVb = T0 * dVbseff_dVb; + dVgsteff_dVe = T0 * dVbseff_dVe; + if (selfheat) + dVgsteff_dT = -dVth_dT + T0 * dVbseff_dT; + else + dVgsteff_dT = 0.0; + } + else if (ExpArg > EXP_THRESHOLD) + { T0 = (Vgst - pParam->B3SOIDDvoff) / (n * Vtm); + ExpVgst = exp(T0); + Vgsteff = Vtm * pParam->B3SOIDDcdep0 / model->B3SOIDDcox * ExpVgst; + T3 = Vgsteff / (n * Vtm) ; + /* T1 is dVgsteff_dVbseff */ + T1 = -T3 * (dVth_dVb + T0 * Vtm * dn_dVb); + dVgsteff_dVg = T3 * dVgs_eff_dVg + T1 * dVbseff_dVg; + dVgsteff_dVd = -T3 * (dVth_dVd + T0 * Vtm * dn_dVd) + T1 * dVbseff_dVd; + dVgsteff_dVe = T1 * dVbseff_dVe; + dVgsteff_dVb = T1 * dVbseff_dVb; + if (selfheat) + dVgsteff_dT = -T3 * (dVth_dT + T0 * dVtm_dT * n) + + Vgsteff / Temp + T1 * dVbseff_dT; + else + dVgsteff_dT = 0.0; + } + else + { ExpVgst = exp(VgstNVt); + T1 = T10 * log(1.0 + ExpVgst); + dT1_dVg = ExpVgst / (1.0 + ExpVgst); + dT1_dVb = -dT1_dVg * (dVth_dVb + Vgst / n * dn_dVb) + + T1 / n * dn_dVb; + dT1_dVd = -dT1_dVg * (dVth_dVd + Vgst / n * dn_dVd) + + T1 / n * dn_dVd; + T3 = (1.0 / Temp); + if (selfheat) + dT1_dT = -dT1_dVg * (dVth_dT + Vgst * T3) + T1 * T3; + else + dT1_dT = 0.0; + + dT2_dVg = -model->B3SOIDDcox / (Vtm * pParam->B3SOIDDcdep0) + * exp(ExpArg); + T2 = 1.0 - T10 * dT2_dVg; + dT2_dVd = -dT2_dVg * (dVth_dVd - 2.0 * Vtm * ExpArg * dn_dVd) + + (T2 - 1.0) / n * dn_dVd; + dT2_dVb = -dT2_dVg * (dVth_dVb - 2.0 * Vtm * ExpArg * dn_dVb) + + (T2 - 1.0) / n * dn_dVb; + if (selfheat) + dT2_dT = -dT2_dVg * (dVth_dT - ExpArg * T10 * T3); + else + dT2_dT = 0.0; + + Vgsteff = T1 / T2; + T3 = T2 * T2; + /* T4 is dVgsteff_dVbseff */ + T4 = (T2 * dT1_dVb - T1 * dT2_dVb) / T3; + dVgsteff_dVb = T4 * dVbseff_dVb; + dVgsteff_dVe = T4 * dVbseff_dVe; + dVgsteff_dVg = (T2 * dT1_dVg - T1 * dT2_dVg) / T3 * dVgs_eff_dVg + + T4 * dVbseff_dVg; + dVgsteff_dVd = (T2 * dT1_dVd - T1 * dT2_dVd) / T3 + T4 * dVbseff_dVd; + if (selfheat) + dVgsteff_dT = (T2 * dT1_dT - T1 * dT2_dT) / T3 + T4 * dVbseff_dT; + else + dVgsteff_dT = 0.0; + } + Vgst2Vtm = Vgsteff + 2.0 * Vtm; + if (selfheat) dVgst2Vtm_dT = 2.0 * dVtm_dT; + else dVgst2Vtm_dT = 0.0; + +/* Calculate Effective Channel Geometry */ + T9 = sqrtPhis - sqrtPhi; + Weff = pParam->B3SOIDDweff - 2.0 * (pParam->B3SOIDDdwg * Vgsteff + + pParam->B3SOIDDdwb * T9); + dWeff_dVg = -2.0 * pParam->B3SOIDDdwg; + dWeff_dVb = -2.0 * pParam->B3SOIDDdwb * dsqrtPhis_dVb; + + if (Weff < 2.0e-8) /* to avoid the discontinuity problem due to Weff*/ + { T0 = 1.0 / (6.0e-8 - 2.0 * Weff); + Weff = 2.0e-8 * (4.0e-8 - Weff) * T0; + T0 *= T0 * 4.0e-16; + dWeff_dVg *= T0; + dWeff_dVb *= T0; + } + + T0 = pParam->B3SOIDDprwg * Vgsteff + pParam->B3SOIDDprwb * T9; + if (T0 >= -0.9) + { Rds = rds0 * (1.0 + T0); + dRds_dVg = rds0 * pParam->B3SOIDDprwg; + dRds_dVb = rds0 * pParam->B3SOIDDprwb * dsqrtPhis_dVb; + if (selfheat) dRds_dT = (1.0 + T0) * drds0_dT; + else dRds_dT = 0.0; + } + else + /* to avoid the discontinuity problem due to prwg and prwb*/ + { T1 = 1.0 / (17.0 + 20.0 * T0); + Rds = rds0 * (0.8 + T0) * T1; + T1 *= T1; + dRds_dVg = rds0 * pParam->B3SOIDDprwg * T1; + dRds_dVb = rds0 * pParam->B3SOIDDprwb * dsqrtPhis_dVb + * T1; + if (selfheat) dRds_dT = (0.8 + T0) * T1 * drds0_dT; + else dRds_dT = 0.0; + } + +/* Calculate Abulk */ + if (pParam->B3SOIDDa0 == 0.0) + { + Abulk0 = Abulk = dAbulk0_dVb = dAbulk_dVg = dAbulk_dVb = 0.0; + } + else + { + T1 = 0.5 * pParam->B3SOIDDk1 / sqrtPhi; + T9 = sqrt(model->B3SOIDDxj * Xdep); + tmp1 = Leff + 2.0 * T9; + T5 = Leff / tmp1; + tmp2 = pParam->B3SOIDDa0 * T5; + tmp3 = pParam->B3SOIDDweff + pParam->B3SOIDDb1; + tmp4 = pParam->B3SOIDDb0 / tmp3; + T2 = tmp2 + tmp4; + dT2_dVb = -T9 * tmp2 / tmp1 / Xdep * dXdep_dVb; + T6 = T5 * T5; + T7 = T5 * T6; + + Abulk0 = T1 * T2; + dAbulk0_dVb = T1 * dT2_dVb; + + T8 = pParam->B3SOIDDags * pParam->B3SOIDDa0 * T7; + dAbulk_dVg = -T1 * T8; + Abulk = Abulk0 + dAbulk_dVg * Vgsteff; + + dAbulk_dVb = dAbulk0_dVb - T8 * Vgsteff * 3.0 * T1 * dT2_dVb + / tmp2; + } + + if (Abulk0 < 0.01) + { + T9 = 1.0 / (3.0 - 200.0 * Abulk0); + Abulk0 = (0.02 - Abulk0) * T9; + dAbulk0_dVb *= T9 * T9; + } + + if (Abulk < 0.01) + { + T9 = 1.0 / (3.0 - 200.0 * Abulk); + Abulk = (0.02 - Abulk) * T9; + dAbulk_dVb *= T9 * T9; + } + + T2 = pParam->B3SOIDDketa * Vbseff; + if (T2 >= -0.9) + { T0 = 1.0 / (1.0 + T2); + dT0_dVb = -pParam->B3SOIDDketa * T0 * T0 ; + } + else + /* added to avoid the problems caused by Keta */ + { T1 = 1.0 / (0.8 + T2); + T0 = (17.0 + 20.0 * T2) * T1; + dT0_dVb = -pParam->B3SOIDDketa * T1 * T1 ; + } + dAbulk_dVg *= T0; + dAbulk_dVb = dAbulk_dVb * T0 + Abulk * dT0_dVb; + dAbulk0_dVb = dAbulk0_dVb * T0 + Abulk0 * dT0_dVb; + Abulk *= T0; + Abulk0 *= T0; + + Abulk += 1; + Abulk0 += 1; + +/* Prepare Abeff */ + T0 = pParam->B3SOIDDabp * Vgst2Vtm; + T1 = 1 - Vcs / T0 - DELT_Xcsat; + T2 = sqrt(T1 * T1 + DELT_Xcsat * DELT_Xcsat); + T3 = 1 - 0.5 * (T1 + T2); + T5 = -0.5 * (1 + T1 / T2); + dT1_dVg = Vcs / Vgst2Vtm / T0; + dT3_dVg = T5 * dT1_dVg; + dT1_dVc = - 1 / T0; + dT3_dVc = T5 * dT1_dVc; + + Xcsat = pParam->B3SOIDDmxc * T3 * T3 + (1 - pParam->B3SOIDDmxc)*T3; + T4 = 2 * pParam->B3SOIDDmxc * T3 + (1 - pParam->B3SOIDDmxc); + dXcsat_dVg = T4 * dT3_dVg; + dXcsat_dVc = T4 * dT3_dVc; + + Abeff = Xcsat * Abulk + (1 - Xcsat) * model->B3SOIDDadice; + T0 = Xcsat * dAbulk_dVg + Abulk * dXcsat_dVg; + dAbeff_dVg = T0 - model->B3SOIDDadice * dXcsat_dVg; + dAbeff_dVb = Xcsat * dAbulk_dVb; + dAbeff_dVc = (Abulk - model->B3SOIDDadice) * dXcsat_dVc; + here->B3SOIDDabeff = Abeff; + +/* Mobility calculation */ + if (model->B3SOIDDmobMod == 1) + { T0 = Vgsteff + Vth + Vth; + T2 = ua + uc * Vbseff; + T3 = T0 / model->B3SOIDDtox; + T5 = T3 * (T2 + ub * T3); + dDenomi_dVg = (T2 + 2.0 * ub * T3) / model->B3SOIDDtox; + dDenomi_dVd = dDenomi_dVg * 2 * dVth_dVd; + dDenomi_dVb = dDenomi_dVg * 2 * dVth_dVb + uc * T3 ; + if (selfheat) + dDenomi_dT = dDenomi_dVg * 2 * dVth_dT + + (dua_dT + Vbseff * duc_dT + + dub_dT * T3 ) * T3; + else + dDenomi_dT = 0.0; + } + else if (model->B3SOIDDmobMod == 2) + { T5 = Vgsteff / model->B3SOIDDtox * (ua + + uc * Vbseff + ub * Vgsteff + / model->B3SOIDDtox); + dDenomi_dVg = (ua + uc * Vbseff + + 2.0 * ub * Vgsteff / model->B3SOIDDtox) + / model->B3SOIDDtox; + dDenomi_dVd = 0.0; + dDenomi_dVb = Vgsteff * uc / model->B3SOIDDtox ; + if (selfheat) + dDenomi_dT = Vgsteff / model->B3SOIDDtox + * (dua_dT + Vbseff * duc_dT + dub_dT + * Vgsteff / model->B3SOIDDtox); + else + dDenomi_dT = 0.0; + } + else /* mobMod == 3 */ + { T0 = Vgsteff + Vth + Vth; + T2 = 1.0 + uc * Vbseff; + T3 = T0 / model->B3SOIDDtox; + T4 = T3 * (ua + ub * T3); + T5 = T4 * T2; + dDenomi_dVg = (ua + 2.0 * ub * T3) * T2 + / model->B3SOIDDtox; + dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd; + dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + + uc * T4 ; + if (selfheat) + dDenomi_dT = dDenomi_dVg * 2.0 * dVth_dT + + (dua_dT + dub_dT * T3) * T3 * T2 + + T4 * Vbseff * duc_dT; + else + dDenomi_dT = 0.0; + } + + if (T5 >= -0.8) + { Denomi = 1.0 + T5; + } + else /* Added to avoid the discontinuity problem caused by ua and ub*/ + { T9 = 1.0 / (7.0 + 10.0 * T5); + Denomi = (0.6 + T5) * T9; + T9 *= T9; + dDenomi_dVg *= T9; + dDenomi_dVd *= T9; + dDenomi_dVb *= T9; + if (selfheat) dDenomi_dT *= T9; + else dDenomi_dT = 0.0; + } + + here->B3SOIDDueff = ueff = u0temp / Denomi; + T9 = -ueff / Denomi; + dueff_dVg = T9 * dDenomi_dVg; + dueff_dVd = T9 * dDenomi_dVd; + dueff_dVb = T9 * dDenomi_dVb; + if (selfheat) dueff_dT = T9 * dDenomi_dT + du0temp_dT / Denomi; + else dueff_dT = 0.0; + +/* Saturation Drain Voltage Vdsat */ + WVCox = Weff * vsattemp * model->B3SOIDDcox; + WVCoxRds = WVCox * Rds; + +/* dWVCoxRds_dT = WVCox * dRds_dT + + Weff * model->B3SOIDDcox * Rds * dvsattemp_dT; */ + + Esat = 2.0 * vsattemp / ueff; + EsatL = Esat * Leff; + T0 = -EsatL /ueff; + dEsatL_dVg = T0 * dueff_dVg; + dEsatL_dVd = T0 * dueff_dVd; + dEsatL_dVb = T0 * dueff_dVb; + if (selfheat) + dEsatL_dT = T0 * dueff_dT + EsatL / vsattemp * dvsattemp_dT; + else + dEsatL_dT = 0.0; + + /* Sqrt() */ + a1 = pParam->B3SOIDDa1; + if (a1 == 0.0) + { Lambda = pParam->B3SOIDDa2; + dLambda_dVg = 0.0; + } + else if (a1 > 0.0) +/* Added to avoid the discontinuity problem caused by a1 and a2 (Lambda) */ + { T0 = 1.0 - pParam->B3SOIDDa2; + T1 = T0 - pParam->B3SOIDDa1 * Vgsteff - 0.0001; + T2 = sqrt(T1 * T1 + 0.0004 * T0); + Lambda = pParam->B3SOIDDa2 + T0 - 0.5 * (T1 + T2); + dLambda_dVg = 0.5 * pParam->B3SOIDDa1 * (1.0 + T1 / T2); + } + else + { T1 = pParam->B3SOIDDa2 + pParam->B3SOIDDa1 * Vgsteff - 0.0001; + T2 = sqrt(T1 * T1 + 0.0004 * pParam->B3SOIDDa2); + Lambda = 0.5 * (T1 + T2); + dLambda_dVg = 0.5 * pParam->B3SOIDDa1 * (1.0 + T1 / T2); + } + + if (Rds > 0) + { tmp2 = dRds_dVg / Rds + dWeff_dVg / Weff; + tmp3 = dRds_dVb / Rds + dWeff_dVb / Weff; + } + else + { tmp2 = dWeff_dVg / Weff; + tmp3 = dWeff_dVb / Weff; + } + if ((Rds == 0.0) && (Lambda == 1.0)) + { T0 = 1.0 / (Abeff * EsatL + Vgst2Vtm); + tmp1 = 0.0; + T1 = T0 * T0; + T2 = Vgst2Vtm * T0; + T3 = EsatL * Vgst2Vtm; + Vdsat = T3 * T0; + + dT0_dVg = -(Abeff * dEsatL_dVg + EsatL * dAbeff_dVg + 1.0) * T1; + dT0_dVd = -(Abeff * dEsatL_dVd) * T1; + dT0_dVb = -(Abeff * dEsatL_dVb + EsatL * dAbeff_dVb) * T1; + dT0_dVc = -(EsatL * dAbeff_dVc) * T1; + if (selfheat) + dT0_dT = -(Abeff * dEsatL_dT + dVgst2Vtm_dT) * T1; + else dT0_dT = 0.0; + + dVdsat_dVg = T3 * dT0_dVg + T2 * dEsatL_dVg + EsatL * T0; + dVdsat_dVd = T3 * dT0_dVd + T2 * dEsatL_dVd; + dVdsat_dVb = T3 * dT0_dVb + T2 * dEsatL_dVb; + dVdsat_dVc = T3 * dT0_dVc; + if (selfheat) + dVdsat_dT = T3 * dT0_dT + T2 * dEsatL_dT + + EsatL * T0 * dVgst2Vtm_dT; + else dVdsat_dT = 0.0; + } + else + { tmp1 = dLambda_dVg / (Lambda * Lambda); + T9 = Abeff * WVCoxRds; + T8 = Abeff * T9; + T7 = Vgst2Vtm * T9; + T6 = Vgst2Vtm * WVCoxRds; + T0 = 2.0 * Abeff * (T9 - 1.0 + 1.0 / Lambda); + dT0_dVg = 2.0 * (T8 * tmp2 - Abeff * tmp1 + + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbeff_dVg); +/* dT0_dVb = 2.0 * (T8 * tmp3 this is equivalent to one below, but simpler + + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbeff_dVg); */ + dT0_dVb = 2.0 * (T8 * (2.0 / Abeff * dAbeff_dVb + tmp3) + + (1.0 / Lambda - 1.0) * dAbeff_dVb); + dT0_dVd = 0.0; + dT0_dVc = 4.0 * T9 * dAbeff_dVc; + + if (selfheat) + { + tmp4 = dRds_dT / Rds + dvsattemp_dT / vsattemp; + dT0_dT = 2.0 * T8 * tmp4; + } else tmp4 = dT0_dT = 0.0; + + T1 = Vgst2Vtm * (2.0 / Lambda - 1.0) + Abeff * EsatL + 3.0 * T7; + + dT1_dVg = (2.0 / Lambda - 1.0) - 2.0 * Vgst2Vtm * tmp1 + + Abeff * dEsatL_dVg + EsatL * dAbeff_dVg + 3.0 * (T9 + + T7 * tmp2 + T6 * dAbeff_dVg); + dT1_dVb = Abeff * dEsatL_dVb + EsatL * dAbeff_dVb + + 3.0 * (T6 * dAbeff_dVb + T7 * tmp3); + dT1_dVd = Abeff * dEsatL_dVd; + dT1_dVc = EsatL * dAbeff_dVc + 3.0 * T6 * dAbeff_dVc; + + if (selfheat) + { + tmp4 += dVgst2Vtm_dT / Vgst2Vtm; + dT1_dT = (2.0 / Lambda - 1.0) * dVgst2Vtm_dT + + Abeff * dEsatL_dT + 3.0 * T7 * tmp4; + } else dT1_dT = 0.0; + + T2 = Vgst2Vtm * (EsatL + 2.0 * T6); + dT2_dVg = EsatL + Vgst2Vtm * dEsatL_dVg + + T6 * (4.0 + 2.0 * Vgst2Vtm * tmp2); + dT2_dVb = Vgst2Vtm * (dEsatL_dVb + 2.0 * T6 * tmp3); + dT2_dVd = Vgst2Vtm * dEsatL_dVd; + if (selfheat) + dT2_dT = Vgst2Vtm * dEsatL_dT + EsatL * dVgst2Vtm_dT + + 2.0 * T6 * (dVgst2Vtm_dT + Vgst2Vtm * tmp4); + else + dT2_dT = 0.0; + + T3 = sqrt(T1 * T1 - 2.0 * T0 * T2); + Vdsat = (T1 - T3) / T0; + + dVdsat_dVg = (dT1_dVg - (T1 * dT1_dVg - dT0_dVg * T2 + - T0 * dT2_dVg) / T3 - Vdsat * dT0_dVg) / T0; + dVdsat_dVb = (dT1_dVb - (T1 * dT1_dVb - dT0_dVb * T2 + - T0 * dT2_dVb) / T3 - Vdsat * dT0_dVb) / T0; + dVdsat_dVd = (dT1_dVd - (T1 * dT1_dVd - T0 * dT2_dVd) / T3) / T0; + dVdsat_dVc = (dT1_dVc - (T1 * dT1_dVc - dT0_dVc * T2) / T3 + - Vdsat * dT0_dVc) / T0; + if (selfheat) + dVdsat_dT = (dT1_dT - (T1 * dT1_dT - dT0_dT * T2 + - T0 * dT2_dT) / T3 - Vdsat * dT0_dT) / T0; + else dVdsat_dT = 0.0; + } + here->B3SOIDDvdsat = Vdsat; + +/* Vdsatii for impact ionization */ + if (pParam->B3SOIDDaii > 0.0) + { + if (pParam->B3SOIDDcii != 0.0) + { + T0 = pParam->B3SOIDDcii / sqrt(3.0) + pParam->B3SOIDDdii; + /* Hard limit Vds to T0 => T4 i.e. limit T0 to 3.0 */ + T1 = Vds - T0 - 0.1; + T2 = sqrt(T1 * T1 + 0.4); + T3 = T0 + 0.5 * (T1 + T2); + dT3_dVd = 0.5 * (1.0 + T1/T2); + + T4 = T3 - pParam->B3SOIDDdii; + T5 = pParam->B3SOIDDcii / T4; + T0 = T5 * T5; + dT0_dVd = - 2 * T0 / T4 * dT3_dVd; + } else + { + T0 = dT0_dVd = 0.0; + } + T0 += 1.0; + + T3 = pParam->B3SOIDDaii + pParam->B3SOIDDbii / Leff; + T4 = 1.0 / (T0 * Vgsteff + T3 * EsatL); + T5 = -T4 * T4; + T6 = Vgsteff * T4; + T7 = EsatL * Vgsteff; + Vdsatii = T7 * T4; + + dT4_dVg = T5 * (T0 + T3 * dEsatL_dVg); + dT4_dVb = T5 * T3 * dEsatL_dVb; + dT4_dVd = T5 * (Vgsteff * dT0_dVd + T3 * dEsatL_dVd); + + if (selfheat) dT4_dT = T5 * (T3 * dEsatL_dT); + else dT4_dT = 0.0; + + T8 = T4 * Vgsteff; + dVdsatii_dVg = T7 * dT4_dVg + T4 * (EsatL + Vgsteff * dEsatL_dVg); + dVdsatii_dVb = T7 * dT4_dVb + T8 * dEsatL_dVb; + dVdsatii_dVd = T7 * dT4_dVd + T8 * dEsatL_dVd; + if (selfheat) dVdsatii_dT = T7 * dT4_dT + T8 * dEsatL_dT; + else dVdsatii_dT = 0.0; + } else + { + Vdsatii = Vdsat; + dVdsatii_dVg = dVdsat_dVg; + dVdsatii_dVb = dVdsat_dVb; + dVdsatii_dVd = dVdsat_dVd; + dVdsatii_dT = dVdsat_dT; + } + +/* Effective Vds (Vdseff) Calculation */ + T1 = Vdsat - Vds - pParam->B3SOIDDdelta; + dT1_dVg = dVdsat_dVg; + dT1_dVd = dVdsat_dVd - 1.0; + dT1_dVb = dVdsat_dVb; + dT1_dVc = dVdsat_dVc; + dT1_dT = dVdsat_dT; + + T2 = sqrt(T1 * T1 + 4.0 * pParam->B3SOIDDdelta * Vdsat); + T0 = T1 / T2; + T3 = 2.0 * pParam->B3SOIDDdelta / T2; + dT2_dVg = T0 * dT1_dVg + T3 * dVdsat_dVg; + dT2_dVd = T0 * dT1_dVd + T3 * dVdsat_dVd; + dT2_dVb = T0 * dT1_dVb + T3 * dVdsat_dVb; + dT2_dVc = T0 * dT1_dVc + T3 * dVdsat_dVc; + if (selfheat) + dT2_dT = T0 * dT1_dT + T3 * dVdsat_dT; + else dT2_dT = 0.0; + + Vdseff = Vdsat - 0.5 * (T1 + T2); + dVdseff_dVg = dVdsat_dVg - 0.5 * (dT1_dVg + dT2_dVg); + dVdseff_dVd = dVdsat_dVd - 0.5 * (dT1_dVd + dT2_dVd); + dVdseff_dVb = dVdsat_dVb - 0.5 * (dT1_dVb + dT2_dVb); + dVdseff_dVc = dVdsat_dVc - 0.5 * (dT1_dVc + dT2_dVc); + if (selfheat) + dVdseff_dT = dVdsat_dT - 0.5 * (dT1_dT + dT2_dT); + else dVdseff_dT = 0.0; + + if (Vdseff > Vds) + Vdseff = Vds; /* This code is added to fixed the problem + caused by computer precision when + Vds is very close to Vdseff. */ + diffVds = Vds - Vdseff; + +/* Effective Vdsii for Iii calculation */ + T1 = Vdsatii - Vds - pParam->B3SOIDDdelta; + + T2 = sqrt(T1 * T1 + 4.0 * pParam->B3SOIDDdelta * Vdsatii); + T0 = T1 / T2; + T3 = 2.0 * pParam->B3SOIDDdelta / T2; + T4 = T0 + T3; + dT2_dVg = T4 * dVdsatii_dVg; + dT2_dVd = T4 * dVdsatii_dVd - T0; + dT2_dVb = T4 * dVdsatii_dVb; + if (selfheat) dT2_dT = T4*dVdsatii_dT; + else dT2_dT = 0.0; + + Vdseffii = Vdsatii - 0.5 * (T1 + T2); + dVdseffii_dVg = 0.5 * (dVdsatii_dVg - dT2_dVg); + dVdseffii_dVd = 0.5 * (dVdsatii_dVd - dT2_dVd + 1.0); + dVdseffii_dVb = 0.5 * (dVdsatii_dVb - dT2_dVb); + if (selfheat) + dVdseffii_dT = 0.5 * (dVdsatii_dT - dT2_dT); + else dVdseffii_dT = 0.0; + diffVdsii = Vds - Vdseffii; + +/* Calculate VAsat */ + tmp4 = 1.0 - 0.5 * Abeff * Vdsat / Vgst2Vtm; + T9 = WVCoxRds * Vgsteff; + T8 = T9 / Vgst2Vtm; + T0 = EsatL + Vdsat + 2.0 * T9 * tmp4; + + T7 = 2.0 * WVCoxRds * tmp4; + dT0_dVg = dEsatL_dVg + dVdsat_dVg + T7 * (1.0 + tmp2 * Vgsteff) + - T8 * (Abeff * dVdsat_dVg - Abeff * Vdsat / Vgst2Vtm + + Vdsat * dAbeff_dVg); + + dT0_dVb = dEsatL_dVb + dVdsat_dVb + T7 * tmp3 * Vgsteff + - T8 * (dAbeff_dVb * Vdsat + Abeff * dVdsat_dVb); + dT0_dVd = dEsatL_dVd + dVdsat_dVd - T8 * Abeff * dVdsat_dVd; + dT0_dVc = dVdsat_dVc - T8 * (Abeff * dVdsat_dVc + Vdsat * dAbeff_dVc); + + if (selfheat) + { + tmp4 = dRds_dT / Rds + dvsattemp_dT / vsattemp; + dT0_dT = dEsatL_dT + dVdsat_dT + T7 * tmp4 * Vgsteff + - T8 * (Abeff * dVdsat_dT - Abeff * Vdsat * dVgst2Vtm_dT + / Vgst2Vtm); + } else + dT0_dT = 0.0; + + T9 = WVCoxRds * Abeff; + T1 = 2.0 / Lambda - 1.0 + T9; + dT1_dVg = -2.0 * tmp1 + WVCoxRds * (Abeff * tmp2 + dAbeff_dVg); + dT1_dVb = dAbeff_dVb * WVCoxRds + T9 * tmp3; + dT1_dVc = dAbeff_dVc * WVCoxRds; + if (selfheat) + dT1_dT = T9 * tmp4; + else + dT1_dT = 0.0; + + Vasat = T0 / T1; + dVasat_dVg = (dT0_dVg - Vasat * dT1_dVg) / T1; + dVasat_dVb = (dT0_dVb - Vasat * dT1_dVb) / T1; + dVasat_dVd = dT0_dVd / T1; + dVasat_dVc = (dT0_dVc - Vasat * dT1_dVc) / T1; + if (selfheat) dVasat_dT = (dT0_dT - Vasat * dT1_dT) / T1; + else dVasat_dT = 0.0; + +/* Calculate VACLM */ + if ((pParam->B3SOIDDpclm > 0.0) && (diffVds > 1.0e-10)) + { T0 = 1.0 / (pParam->B3SOIDDpclm * Abeff * pParam->B3SOIDDlitl); + dT0_dVb = -T0 / Abeff * dAbeff_dVb; + dT0_dVg = -T0 / Abeff * dAbeff_dVg; + dT0_dVc = -T0 / Abeff * dAbeff_dVc; + + T2 = Vgsteff / EsatL; + T1 = Leff * (Abeff + T2); + dT1_dVg = Leff * ((1.0 - T2 * dEsatL_dVg) / EsatL + dAbeff_dVg); + dT1_dVb = Leff * (dAbeff_dVb - T2 * dEsatL_dVb / EsatL); + dT1_dVd = -T2 * dEsatL_dVd / Esat; + dT1_dVc = Leff * dAbeff_dVc; + if (selfheat) dT1_dT = -T2 * dEsatL_dT / Esat; + else dT1_dT = 0.0; + + T9 = T0 * T1; + VACLM = T9 * diffVds; + dVACLM_dVg = T0 * dT1_dVg * diffVds - T9 * dVdseff_dVg + + T1 * diffVds * dT0_dVg; + dVACLM_dVb = (dT0_dVb * T1 + T0 * dT1_dVb) * diffVds + - T9 * dVdseff_dVb; + dVACLM_dVd = T0 * dT1_dVd * diffVds + T9 * (1.0 - dVdseff_dVd); + dVACLM_dVc = (T1 * dT0_dVc + T0 * dT1_dVc) * diffVds + - T9 * dVdseff_dVc; + if (selfheat) + dVACLM_dT = T0 * dT1_dT * diffVds - T9 * dVdseff_dT; + else dVACLM_dT = 0.0; + + } + else + { VACLM = MAX_EXP; + dVACLM_dVd = dVACLM_dVg = dVACLM_dVb = dVACLM_dVc = dVACLM_dT = 0.0; + } + + +/* Calculate VADIBL */ + if (pParam->B3SOIDDthetaRout > 0.0) + { T8 = Abeff * Vdsat; + T0 = Vgst2Vtm * T8; + T1 = Vgst2Vtm + T8; + dT0_dVg = Vgst2Vtm * Abeff * dVdsat_dVg + T8 + + Vgst2Vtm * Vdsat * dAbeff_dVg; + dT1_dVg = 1.0 + Abeff * dVdsat_dVg + Vdsat * dAbeff_dVg; + dT1_dVb = dAbeff_dVb * Vdsat + Abeff * dVdsat_dVb; + dT0_dVb = Vgst2Vtm * dT1_dVb; + dT1_dVd = Abeff * dVdsat_dVd; + dT0_dVd = Vgst2Vtm * dT1_dVd; + dT1_dVc = (Abeff * dVdsat_dVc + Vdsat * dAbeff_dVc); + dT0_dVc = Vgst2Vtm * dT1_dVc; + if (selfheat) + { + dT0_dT = dVgst2Vtm_dT * T8 + Abeff * Vgst2Vtm * dVdsat_dT; + dT1_dT = dVgst2Vtm_dT + Abeff * dVdsat_dT; + } else + dT0_dT = dT1_dT = 0.0; + + T9 = T1 * T1; + T2 = pParam->B3SOIDDthetaRout; + VADIBL = (Vgst2Vtm - T0 / T1) / T2; + dVADIBL_dVg = (1.0 - dT0_dVg / T1 + T0 * dT1_dVg / T9) / T2; + dVADIBL_dVb = (-dT0_dVb / T1 + T0 * dT1_dVb / T9) / T2; + dVADIBL_dVd = (-dT0_dVd / T1 + T0 * dT1_dVd / T9) / T2; + dVADIBL_dVc = (-dT0_dVc / T1 + T0 * dT1_dVc / T9) / T2; + if (selfheat) + dVADIBL_dT = (dVgst2Vtm_dT - dT0_dT/T1 + T0*dT1_dT/T9) / T2; + else dVADIBL_dT = 0.0; + + T7 = pParam->B3SOIDDpdiblb * Vbseff; + if (T7 >= -0.9) + { T3 = 1.0 / (1.0 + T7); + VADIBL *= T3; + dVADIBL_dVg *= T3; + dVADIBL_dVb = (dVADIBL_dVb - VADIBL * pParam->B3SOIDDpdiblb) + * T3; + dVADIBL_dVd *= T3; + dVADIBL_dVc *= T3; + if (selfheat) dVADIBL_dT *= T3; + else dVADIBL_dT = 0.0; + } + else +/* Added to avoid the discontinuity problem caused by pdiblcb */ + { T4 = 1.0 / (0.8 + T7); + T3 = (17.0 + 20.0 * T7) * T4; + dVADIBL_dVg *= T3; + dVADIBL_dVb = dVADIBL_dVb * T3 + - VADIBL * pParam->B3SOIDDpdiblb * T4 * T4; + dVADIBL_dVd *= T3; + dVADIBL_dVc *= T3; + if (selfheat) dVADIBL_dT *= T3; + else dVADIBL_dT = 0.0; + VADIBL *= T3; + } + } + else + { VADIBL = MAX_EXP; + dVADIBL_dVd = dVADIBL_dVg = dVADIBL_dVb = dVADIBL_dVc + = dVADIBL_dT = 0.0; + } + +/* Calculate VA */ + + T8 = pParam->B3SOIDDpvag / EsatL; + T9 = T8 * Vgsteff; + if (T9 > -0.9) + { T0 = 1.0 + T9; + dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL); + dT0_dVb = -T9 * dEsatL_dVb / EsatL; + dT0_dVd = -T9 * dEsatL_dVd / EsatL; + if (selfheat) + dT0_dT = -T9 * dEsatL_dT / EsatL; + else + dT0_dT = 0.0; + } + else /* Added to avoid the discontinuity problems caused by pvag */ + { T1 = 1.0 / (17.0 + 20.0 * T9); + T0 = (0.8 + T9) * T1; + T1 *= T1; + dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL) * T1; + + T9 *= T1 / EsatL; + dT0_dVb = -T9 * dEsatL_dVb; + dT0_dVd = -T9 * dEsatL_dVd; + if (selfheat) + dT0_dT = -T9 * dEsatL_dT; + else + dT0_dT = 0.0; + } + + tmp1 = VACLM * VACLM; + tmp2 = VADIBL * VADIBL; + tmp3 = VACLM + VADIBL; + + T1 = VACLM * VADIBL / tmp3; + tmp3 *= tmp3; + dT1_dVg = (tmp1 * dVADIBL_dVg + tmp2 * dVACLM_dVg) / tmp3; + dT1_dVd = (tmp1 * dVADIBL_dVd + tmp2 * dVACLM_dVd) / tmp3; + dT1_dVb = (tmp1 * dVADIBL_dVb + tmp2 * dVACLM_dVb) / tmp3; + dT1_dVc = (tmp1 * dVADIBL_dVc + tmp2 * dVACLM_dVc) / tmp3; + if (selfheat) + dT1_dT = (tmp1 * dVADIBL_dT + tmp2 * dVACLM_dT ) / tmp3; + else dT1_dT = 0.0; + + Va = Vasat + T0 * T1; + dVa_dVg = dVasat_dVg + T1 * dT0_dVg + T0 * dT1_dVg; + dVa_dVd = dVasat_dVd + T1 * dT0_dVd + T0 * dT1_dVd; + dVa_dVb = dVasat_dVb + T1 * dT0_dVb + T0 * dT1_dVb; + dVa_dVc = dVasat_dVc + T0 * dT1_dVc; + if (selfheat) + dVa_dT = dVasat_dT + T1 * dT0_dT + T0 * dT1_dT; + else dVa_dT = 0.0; + +/* Calculate Ids */ + CoxWovL = model->B3SOIDDcox * Weff / Leff; + beta = ueff * CoxWovL; + dbeta_dVg = CoxWovL * dueff_dVg + beta * dWeff_dVg / Weff; + dbeta_dVd = CoxWovL * dueff_dVd; + dbeta_dVb = CoxWovL * dueff_dVb + beta * dWeff_dVb / Weff; + if (selfheat) dbeta_dT = CoxWovL * dueff_dT; + else dbeta_dT = 0.0; + + T0 = 1.0 - 0.5 * Abeff * Vdseff / Vgst2Vtm; + dT0_dVg = -0.5 * (Abeff * dVdseff_dVg + - Abeff * Vdseff / Vgst2Vtm + Vdseff * dAbeff_dVg) / Vgst2Vtm; + dT0_dVd = -0.5 * Abeff * dVdseff_dVd / Vgst2Vtm; + dT0_dVb = -0.5 * (Abeff * dVdseff_dVb + dAbeff_dVb * Vdseff) + / Vgst2Vtm; + dT0_dVc = -0.5 * (Abeff * dVdseff_dVc + dAbeff_dVc * Vdseff) + / Vgst2Vtm; + if (selfheat) + dT0_dT = -0.5 * (Abeff * dVdseff_dT + - Abeff * Vdseff / Vgst2Vtm * dVgst2Vtm_dT) + / Vgst2Vtm; + else dT0_dT = 0.0; + + fgche1 = Vgsteff * T0; + dfgche1_dVg = Vgsteff * dT0_dVg + T0; + dfgche1_dVd = Vgsteff * dT0_dVd; + dfgche1_dVb = Vgsteff * dT0_dVb; + dfgche1_dVc = Vgsteff * dT0_dVc; + if (selfheat) dfgche1_dT = Vgsteff * dT0_dT; + else dfgche1_dT = 0.0; + + T9 = Vdseff / EsatL; + fgche2 = 1.0 + T9; + dfgche2_dVg = (dVdseff_dVg - T9 * dEsatL_dVg) / EsatL; + dfgche2_dVd = (dVdseff_dVd - T9 * dEsatL_dVd) / EsatL; + dfgche2_dVb = (dVdseff_dVb - T9 * dEsatL_dVb) / EsatL; + dfgche2_dVc = (dVdseff_dVc) / EsatL; + if (selfheat) dfgche2_dT = (dVdseff_dT - T9 * dEsatL_dT) / EsatL; + else dfgche2_dT = 0.0; + + gche = beta * fgche1 / fgche2; + dgche_dVg = (beta * dfgche1_dVg + fgche1 * dbeta_dVg + - gche * dfgche2_dVg) / fgche2; + dgche_dVd = (beta * dfgche1_dVd + fgche1 * dbeta_dVd + - gche * dfgche2_dVd) / fgche2; + dgche_dVb = (beta * dfgche1_dVb + fgche1 * dbeta_dVb + - gche * dfgche2_dVb) / fgche2; + dgche_dVc = (beta * dfgche1_dVc - gche * dfgche2_dVc) / fgche2; + if (selfheat) + dgche_dT = (beta * dfgche1_dT + fgche1 * dbeta_dT + - gche * dfgche2_dT) / fgche2; + else dgche_dT = 0.0; + + T0 = 1.0 + gche * Rds; + T9 = Vdseff / T0; + Idl = gche * T9; + +/* Whoa, these formulas for the derivatives of Idl are convoluted, but I + verified them to be correct */ + + dIdl_dVg = (gche * dVdseff_dVg + T9 * dgche_dVg) / T0 + - Idl * gche / T0 * dRds_dVg ; + dIdl_dVd = (gche * dVdseff_dVd + T9 * dgche_dVd) / T0; + dIdl_dVb = (gche * dVdseff_dVb + T9 * dgche_dVb + - Idl * dRds_dVb * gche) / T0; + dIdl_dVc = (gche * dVdseff_dVc + T9 * dgche_dVc) / T0; + if (selfheat) + dIdl_dT = (gche * dVdseff_dT + T9 * dgche_dT + - Idl * dRds_dT * gche) / T0; + else dIdl_dT = 0.0; + + T9 = diffVds / Va; + T0 = 1.0 + T9; + here->B3SOIDDids = Ids = Idl * T0; + + Gm0 = T0 * dIdl_dVg - Idl * (dVdseff_dVg + T9 * dVa_dVg) / Va; + Gds0 = T0 * dIdl_dVd + Idl * (1.0 - dVdseff_dVd + - T9 * dVa_dVd) / Va; + Gmb0 = T0 * dIdl_dVb - Idl * (dVdseff_dVb + T9 * dVa_dVb) / Va; + Gmc = T0 * dIdl_dVc - Idl * (dVdseff_dVc + T9 * dVa_dVc) / Va; + if (selfheat) + GmT0 = T0 * dIdl_dT - Idl * (dVdseff_dT + T9 * dVa_dT) / Va; + else GmT0 = 0.0; + +/* This includes all dependencies from Vgsteff, Vbseff, Vcs */ + Gm = Gm0 * dVgsteff_dVg + Gmb0 * dVbseff_dVg + Gmc * dVcs_dVg; + Gmb = Gm0 * dVgsteff_dVb + Gmb0 * dVbseff_dVb + Gmc * dVcs_dVb; + Gds = Gm0 * dVgsteff_dVd + Gmb0 * dVbseff_dVd + Gmc * dVcs_dVd + Gds0; + Gme = Gm0 * dVgsteff_dVe + Gmb0 * dVbseff_dVe + Gmc * dVcs_dVe; + if (selfheat) + GmT = Gm0 * dVgsteff_dT + Gmb0 * dVbseff_dT + Gmc * dVcs_dT + GmT0; + else GmT = 0.0; + +/* calculate substrate current Iii */ + T2 = pParam->B3SOIDDalpha1 + pParam->B3SOIDDalpha0 / Leff; + if ((T2 <= 0.0) || (pParam->B3SOIDDbeta0 <= 0.0)) + { Giig = Giib = Giid = Giie = GiiT = 0.0; + here->B3SOIDDiii = Iii = 0.0; + } + else + { + T5 = pParam->B3SOIDDbeta0; + if (diffVdsii > T5 / EXP_THRESHOLD) + { + T0 = -T5 / diffVdsii; + T10 = T0 / diffVdsii; + dT0_dVg = T10 * dVdseffii_dVg; + T1 = T2 * diffVdsii * exp(T0); + + T3 = T1 / diffVdsii * (T0 - 1.0); + dT1_dVg = T1 * (dT0_dVg - dVdseffii_dVg / diffVdsii); + dT1_dVd = -T3 * (1.0 - dVdseffii_dVd); + dT1_dVb = T3 * dVdseffii_dVb; + if (selfheat) dT1_dT = T3 * dVdseffii_dT; + else dT1_dT = 0.0; + } + else + { T3 = T2 * MIN_EXP; + T1 = T3 * diffVdsii; + dT1_dVg = -T3 * dVdseffii_dVg; + dT1_dVd = T3 * (1.0 - dVdseffii_dVd); + dT1_dVb = -T3 * dVdseffii_dVb; + if (selfheat) dT1_dT = -T3 * dVdseffii_dT; + else dT1_dT = 0.0; + } + + here->B3SOIDDiii = Iii = T1 * Ids; + + T2 = T1 * Gm0 + Ids * dT1_dVg; + T3 = T1 * Gds0 + Ids * dT1_dVd; + T4 = T1 * Gmb0 + Ids * dT1_dVb; + T5 = T1 * Gmc; + if (selfheat) T6 = T1 * GmT0 + Ids * dT1_dT; + else T6 = 0.0; + + Giig = T2 * dVgsteff_dVg + T4 * dVbseff_dVg + T5 * dVcs_dVg; + Giib = T2 * dVgsteff_dVb + T4 * dVbseff_dVb + T5 * dVcs_dVb; + Giid = T2 * dVgsteff_dVd + T4 * dVbseff_dVd + T5 * dVcs_dVd + T3; + Giie = T2 * dVgsteff_dVe + T4 * dVbseff_dVe + T5 * dVcs_dVe; + if (selfheat) + GiiT = T2 * dVgsteff_dT + T4 * dVbseff_dT + T5 * dVcs_dT + T6; + else + GiiT = 0.0; + } + +/* calculate GIDL current */ + T0 = 3 * model->B3SOIDDtox; + /* For drain side */ + T1 = (Vds - Vgs_eff - pParam->B3SOIDDngidl) / T0; + if ((pParam->B3SOIDDagidl <= 0.0) || (pParam->B3SOIDDbgidl <= 0.0) || + (T1 <= 0.0)) + { Idgidl = Gdgidld = Gdgidlg = 0.0; + } + else { + dT1_dVd = 1 / T0; + dT1_dVg = - dT1_dVd * dVgs_eff_dVg; + T2 = pParam->B3SOIDDbgidl / T1; + if (T2 < EXP_THRESHOLD) + { + Idgidl = pParam->B3SOIDDweff * pParam->B3SOIDDagidl * T1 * exp(-T2); + T3 = Idgidl / T1 * (T2 + 1); + Gdgidld = T3 * dT1_dVd; + Gdgidlg = T3 * dT1_dVg; + } else + { + T3 = pParam->B3SOIDDweff * pParam->B3SOIDDagidl * MIN_EXP; + Idgidl = T3 * T1 ; + Gdgidld = T3 * dT1_dVd; + Gdgidlg = T3 * dT1_dVg; + } + } + here->B3SOIDDigidl = Idgidl; + + /* For source side */ + T1 = (- Vgs_eff - pParam->B3SOIDDngidl) / T0; + if ((pParam->B3SOIDDagidl <= 0.0) || (pParam->B3SOIDDbgidl <= 0.0) + || (T1 <= 0.0)) + { Isgidl = Gsgidlg = 0; + } + else + { + dT1_dVg = - dVgs_eff_dVg / T0; + T2 = pParam->B3SOIDDbgidl / T1; + if (T2 < EXP_THRESHOLD) + { + Isgidl = pParam->B3SOIDDweff * pParam->B3SOIDDagidl * T1 * exp(-T2); + T3 = Isgidl / T1 * (T2 + 1); + Gsgidlg = T3 * dT1_dVg; + } else + { + T3 = pParam->B3SOIDDweff * pParam->B3SOIDDagidl * MIN_EXP; + Isgidl = T3 * T1 ; + Gsgidlg = T3 * dT1_dVg; + } + } + +/* calculate diode and BJT current */ + + WTsi = pParam->B3SOIDDweff * model->B3SOIDDtsi; + NVtm1 = Vtm * pParam->B3SOIDDndiode; + NVtm2 = Vtm * pParam->B3SOIDDntun; + + /* Create exponents first */ + T0 = Vbs / NVtm1; + if (T0 < 30) + { + ExpVbs1 = exp(T0); + dExpVbs1_dVb = ExpVbs1 / NVtm1; + if (selfheat) dExpVbs1_dT = - T0 * ExpVbs1 / Temp; + } else + { + T1 = 1.0686e13; /* exp(30) */ + dExpVbs1_dVb = T1 / NVtm1; + ExpVbs1 = dExpVbs1_dVb * Vbs - 29.0 * T1; + if (selfheat) dExpVbs1_dT = - dExpVbs1_dVb * Vbs / Temp; + } + + T0 = Vbd / NVtm1; + if (T0 < 30) + { + ExpVbd1 = exp(T0); + dExpVbd1_dVb = ExpVbd1 / NVtm1; + if (selfheat) dExpVbd1_dT = - T0 * ExpVbd1 / Temp; + } else + { + T1 = 1.0686e13; /* exp(30) */ + dExpVbd1_dVb = T1 / NVtm1; + ExpVbd1 = dExpVbd1_dVb * Vbd - 29.0 * T1; + if (selfheat) dExpVbd1_dT = - dExpVbd1_dVb * Vbd / Temp; + } + + if (jtun > 0.0) + { + T0 = -Vbs / NVtm2; + if (T0 < 30) + { + ExpVbs4 = exp(T0); + dExpVbs4_dVb = - ExpVbs4 / NVtm2; + if (selfheat) dExpVbs4_dT = - T0 * ExpVbs4 / Temp; + } else + { + T1 = 1.0686e13; /* exp(30) */ + dExpVbs4_dVb = - T1 / NVtm2; + ExpVbs4 = dExpVbs4_dVb * Vbs - 29.0 * T1; + if (selfheat) dExpVbs4_dT = - dExpVbs4_dVb * Vbs / Temp; + } + + T0 = -Vbd / NVtm2; + if (T0 < 30) + { + ExpVbd4 = exp(T0); + dExpVbd4_dVb = - ExpVbd4 / NVtm2; + if (selfheat) dExpVbd4_dT = - T0 * ExpVbd4 / Temp; + } else + { + T1 = 1.0686e13; /* exp(30) */ + dExpVbd4_dVb = - T1 / NVtm2; + ExpVbd4 = dExpVbd4_dVb * Vbd - 29.0 * T1; + if (selfheat) dExpVbd4_dT = - dExpVbd4_dVb * Vbd / Temp; + } + } + + /* Ibs1 / Ibd1 */ + if (jdif == 0.0) + { + Ibs1 = dIbs1_dVb = dIbs1_dT = 0.0; + Ibd1 = dIbd1_dVd = dIbd1_dVb = dIbd1_dT = 0.0; + } + else + { + T5 = WTsi * jdif; + Ibs1 = T5 * (ExpVbs1 - 1.0); + dIbs1_dVb = T5 * dExpVbs1_dVb; + if (selfheat) + dIbs1_dT = Ibs1 / jdif * djdif_dT + T5 * dExpVbs1_dT; + + Ibd1 = T5 * (ExpVbd1 - 1.0); + dIbd1_dVb = T5 * dExpVbd1_dVb; + dIbd1_dVd = -dIbd1_dVb; + if (selfheat) + dIbd1_dT = Ibd1 / jdif * djdif_dT + T5 * dExpVbd1_dT; + } + + /* Ibs2 */ + if (jrec == 0.0) + { + Ibs2 = dIbs2_dVb = dIbs2_dT = 0.0; + Ibd2 = dIbd2_dVb = dIbd2_dVd = dIbd2_dT = 0.0; + } + else + { + ExpVbs2 = sqrt(ExpVbs1); + if (ExpVbs2 > 1e-20) + { + dExpVbs2_dVb = 0.5 / ExpVbs2 * dExpVbs1_dVb; + if (selfheat) dExpVbs2_dT = 0.5 / ExpVbs2 * dExpVbs1_dT; + } + else + { + dExpVbs2_dVb = dExpVbs2_dT = 0.0; + } + + ExpVbd2 = sqrt(ExpVbd1); + if (ExpVbd2 > 1e-20) + { + dExpVbd2_dVb = 0.5 / ExpVbd2 * dExpVbd1_dVb; + if (selfheat) dExpVbd2_dT = 0.5 / ExpVbd2 * dExpVbd1_dT; + } + else + { + dExpVbd2_dVb = dExpVbd2_dT = 0.0; + } + + T8 = WTsi * jrec; + T9 = 0.5 * T8 / NVtm1; + Ibs2 = T8 * (ExpVbs2 - 1.0); + dIbs2_dVb = T8 * dExpVbs2_dVb; + if (selfheat) + dIbs2_dT = Ibs2 / jrec * djrec_dT + T8 * dExpVbs2_dT; + + T8 = WTsi * jrec; + T9 = 0.5 * T8 / NVtm1; + Ibd2 = T8 * (ExpVbd2 - 1.0); + dIbd2_dVb = T8 * dExpVbd2_dVb; + dIbd2_dVd = -dIbd2_dVb; + if (selfheat) + dIbd2_dT = Ibd2 / jrec * djrec_dT + T8 * dExpVbd2_dT; + } + + /* Ibjt */ + if ((here->B3SOIDDbjtoff == 1) || (Vds == 0.0) || + (jbjt == 0.0)) + { + Ibs3 = dIbs3_dVb = dIbs3_dVd = dIbs3_dT = 0.0; + Ibd3 = dIbd3_dVb = dIbd3_dVd = dIbd3_dT = 0.0; + here->B3SOIDDic = Ic = Gcd = Gcb = GcT = 0.0; + } + else { + T0 = Leff - pParam->B3SOIDDkbjt1 * Vds; + T1 = T0 / pParam->B3SOIDDedl; + dT1_dVd = - pParam->B3SOIDDkbjt1 / pParam->B3SOIDDedl; + if (T1 < 1e-3) /* Limit to 1/2e4 */ + { T2 = 1.0 / (3.0 - 2.0e3 * T1); + T1 = (2.0e-3 - T1) * T2; + dT1_dVd *= T2 * T2; + } else if (T1 > 1.0) + { T1 = 1.0; + dT1_dVd = 0.0; + } + BjtA = 1 - 0.5 * T1 * T1; + dBjtA_dVd = - T1 * dT1_dVd; + + T5 = WTsi * jbjt; + Ibjt = T5 * (ExpVbs1 - ExpVbd1); + dIbjt_dVb = T5 * (dExpVbs1_dVb - dExpVbd1_dVb); + dIbjt_dVd = T5 * dExpVbd1_dVb; + if (selfheat) + dIbjt_dT = T5 * (dExpVbs1_dT - dExpVbd1_dT) + + Ibjt / jbjt * djbjt_dT; + + T3 = (1.0 - BjtA) * T5; + T4 = - T5 * dBjtA_dVd; + Ibs3 = T3 * ExpVbs1; + dIbs3_dVb = T3 * dExpVbs1_dVb; + dIbs3_dVd = T4 * ExpVbs1; + if (selfheat) dIbs3_dT = Ibs3 / jbjt * djbjt_dT + T3 * dExpVbs1_dT; + + Ibd3 = T3 * ExpVbd1; + dIbd3_dVb = T3 * dExpVbd1_dVb; + dIbd3_dVd = T4 * ExpVbd1 - dIbd3_dVb; + if (selfheat) dIbd3_dT = Ibd3 / jbjt * djbjt_dT + T3 * dExpVbd1_dT; + + here->B3SOIDDic = Ic = Ibjt - Ibs3 + Ibd3; + Gcd = dIbjt_dVd - dIbs3_dVd + dIbd3_dVd; + Gcb = dIbjt_dVb - dIbs3_dVb + dIbd3_dVb; + if (selfheat) GcT = dIbjt_dT - dIbs3_dT + dIbd3_dT; + else GcT = 0.0; + } + + if (jtun == 0.0) + { + Ibs4 = dIbs4_dVb = dIbs4_dT = 0.0; + Ibd4 = dIbd4_dVb = dIbd4_dVd = dIbd4_dT = 0.0; + } + else + { + T5 = WTsi * jtun; + Ibs4 = T5 * (1.0 - ExpVbs4); + dIbs4_dVb = - T5 * dExpVbs4_dVb; + if (selfheat) + dIbs4_dT = Ibs4 / jtun * djtun_dT - T5 * dExpVbs4_dT; + + Ibd4 = T5 * (1.0 - ExpVbd4); + dIbd4_dVb = - T5 * dExpVbd4_dVb; + dIbd4_dVd = -dIbd4_dVb; + if (selfheat) + dIbd4_dT = Ibd4 / jtun * djtun_dT - T5 * dExpVbd4_dT; + } + +here->B3SOIDDdum1 = Ibs3 + Ibd4; +here->B3SOIDDdum2 = Ibs1; +here->B3SOIDDdum3 = Ibjt; +here->B3SOIDDdum4 = Ic; + + here->B3SOIDDitun = - Ibd3 - Ibd4; + here->B3SOIDDibs = Ibs = Ibs1 + Ibs2 + Ibs3 + Ibs4; + here->B3SOIDDibd = Ibd = Ibd1 + Ibd2 + Ibd3 + Ibd4; + + Gjsb = dIbs1_dVb + dIbs2_dVb + dIbs3_dVb + dIbs4_dVb; + Gjsd = dIbs3_dVd; + if (selfheat) GjsT = dIbs1_dT + dIbs2_dT + dIbs3_dT + dIbs4_dT; + else GjsT = 0.0; + + Gjdb = dIbd1_dVb + dIbd2_dVb + dIbd3_dVb + dIbd4_dVb; + Gjdd = dIbd1_dVd + dIbd2_dVd + dIbd3_dVd + dIbd4_dVd; + if (selfheat) GjdT = dIbd1_dT + dIbd2_dT + dIbd3_dT + dIbd4_dT; + else GjdT = 0.0; + + + /* Current through body resistor */ + /* Current going out is +ve */ + if ((here->B3SOIDDbodyMod == 0) || (here->B3SOIDDbodyMod == 2)) + { + Ibp = Gbpbs = Gbpgs = Gbpds = Gbpes = Gbpps = GbpT = 0.0; + } + else { /* here->B3SOIDDbodyMod == 1 */ + if (pParam->B3SOIDDrbody < 1e-30) + { + if (here->B3SOIDDrbodyext <= 1e-30) + T0 = 1.0 / 1e-30; + else + T0 = 1.0 / here->B3SOIDDrbodyext; + Ibp = Vbp * T0; + Gbpbs = T0 * dVbp_dVb; + Gbpps = T0 * dVbp_dVp; + Gbpgs = T0 * dVbp_dVg; + Gbpds = T0 * dVbp_dVd; + Gbpes = 0.0; + if (selfheat) GbpT = T0 * dVbp_dT; + else GbpT = 0.0; + } else + { T0 = 1.0 / pParam->B3SOIDDrbody; + if (Vbp >= 0.0) + { + T1 = sqrt(Vcs); + T3 = T1 * T0; + T5 = 1.0 + here->B3SOIDDrbodyext * T3; + T6 = T3 / T5; + T2 = 0.5 * T0 / T1; + T7 = T2 / (T5 * T5); + Ibp = Vbp * T6; + + /* Whoa, again these derivatives are convoluted, but correct */ + + Gbpbs = T6 * dVbp_dVb + Vbp * T7 * dVcs_dVb; + Gbpps = T6 * dVbp_dVp; + Gbpgs = T6 * dVbp_dVg + Vbp * T7 * dVcs_dVg; + Gbpds = T6 * dVbp_dVg + Vbp * T7 * dVcs_dVd; + Gbpes = T6 * dVbp_dVg + Vbp * T7 * dVcs_dVe; + if (selfheat) + GbpT = T6 * dVbp_dT + Vbp * T7 * dVcs_dT; + else GbpT = 0.0; + + } else + { + T1 = sqrt(Vpsdio - Vbs0eff); + T3 = T1 * T0; + T5 = 1.0 + here->B3SOIDDrbodyext * T3; + T6 = T3 / T5; + T2 = 0.5 * T0 / T1; + Ibp = Vbp * T6; + T7 = T2 / (T5 * T5); + Gbpbs = T6 * dVbp_dVb; + Gbpps = T6 * dVbp_dVp + Vbp * T7 * dVpsdio_dVp; + Gbpgs = Vbp * T7 * (dVpsdio_dVg - dVbs0eff_dVg); + Gbpds = Vbp * T7 * (dVpsdio_dVd - dVbs0eff_dVd); + Gbpes = Vbp * T7 * (dVpsdio_dVe - dVbs0eff_dVe); + if (selfheat) + GbpT = Vbp * T7 * (dVpsdio_dT - dVbs0eff_dT); + else GbpT = 0.0; + } + } + } + + here->B3SOIDDibp = Ibp; + here->B3SOIDDgbpbs = Gbpbs; + here->B3SOIDDgbpgs = Gbpgs; + here->B3SOIDDgbpds = Gbpds; + here->B3SOIDDgbpes = Gbpes; + here->B3SOIDDgbpps = Gbpps; + if (selfheat) + here->B3SOIDDgbpT = GbpT; + else { + GbpT = 0.0; + here->B3SOIDDgbpT = 0.0; + } + here->B3SOIDDcbodcon = Ibp - (Gbpbs * Vbs + Gbpgs * Vgs + + Gbpds * Vds + Gbpes * Ves + Gbpps * Vps + + GbpT * delTemp); + + /* Current going out of drainprime node into the drain of device */ + /* "node" means the SPICE circuit node */ + + here->B3SOIDDcdrain = Ids + Ic; + here->B3SOIDDcd = Ids + Ic - Ibd + Iii + Idgidl; + here->B3SOIDDcb = Ibs + Ibd + Ibp - Iii - Idgidl - Isgidl; + + here->B3SOIDDgds = Gds + Gcd; + here->B3SOIDDgm = Gm; + here->B3SOIDDgmbs = Gmb + Gcb; + here->B3SOIDDgme = Gme; + if (selfheat) + here->B3SOIDDgmT = GmT + GcT; + else + here->B3SOIDDgmT = 0.0; + + /* note that sign is switched because power flows out + of device into the temperature node. + Currently ommit self-heating due to bipolar current + because it can cause convergence problem*/ + + here->B3SOIDDgtempg = -Gm * Vds; + here->B3SOIDDgtempb = -Gmb * Vds; + here->B3SOIDDgtempe = -Gme * Vds; + here->B3SOIDDgtempT = -GmT * Vds; + here->B3SOIDDgtempd = -Gds * Vds - Ids; + here->B3SOIDDcth = - Ids * Vds - model->B3SOIDDtype * + (here->B3SOIDDgtempg * Vgs + here->B3SOIDDgtempb * Vbs + + here->B3SOIDDgtempe * Ves + here->B3SOIDDgtempd * Vds) + - here->B3SOIDDgtempT * delTemp; + + /* Body current which flows into drainprime node from the drain of device */ + + here->B3SOIDDgjdb = Gjdb - Giib; + here->B3SOIDDgjdd = Gjdd - (Giid + Gdgidld); + here->B3SOIDDgjdg = - (Giig + Gdgidlg); + here->B3SOIDDgjde = - Giie; + if (selfheat) here->B3SOIDDgjdT = GjdT - GiiT; + else here->B3SOIDDgjdT = 0.0; + here->B3SOIDDcjd = Ibd - Iii - Idgidl - here->B3SOIDDminIsub/2 + - (here->B3SOIDDgjdb * Vbs + here->B3SOIDDgjdd * Vds + + here->B3SOIDDgjdg * Vgs + here->B3SOIDDgjde * Ves + + here->B3SOIDDgjdT * delTemp); + + /* Body current which flows into sourceprime node from the source of device */ + + here->B3SOIDDgjsb = Gjsb; + here->B3SOIDDgjsd = Gjsd; + here->B3SOIDDgjsg = - Gsgidlg; + if (selfheat) here->B3SOIDDgjsT = GjsT; + else here->B3SOIDDgjsT = 0.0; + here->B3SOIDDcjs = Ibs - Isgidl - here->B3SOIDDminIsub/2 + - (here->B3SOIDDgjsb * Vbs + here->B3SOIDDgjsd * Vds + + here->B3SOIDDgjsg * Vgs + here->B3SOIDDgjsT * delTemp); + + /* Current flowing into body node */ + + here->B3SOIDDgbbs = Giib - Gjsb - Gjdb - Gbpbs; + here->B3SOIDDgbgs = Giig + Gdgidlg + Gsgidlg - Gbpgs; + here->B3SOIDDgbds = Giid + Gdgidld - Gjsd - Gjdd - Gbpds; + here->B3SOIDDgbes = Giie - Gbpes; + here->B3SOIDDgbps = - Gbpps; + if (selfheat) here->B3SOIDDgbT = GiiT - GjsT - GjdT - GbpT; + else here->B3SOIDDgbT = 0.0; + here->B3SOIDDcbody = Iii + Idgidl + Isgidl - Ibs - Ibd - Ibp + here->B3SOIDDminIsub + - (here->B3SOIDDgbbs * Vbs + here->B3SOIDDgbgs * Vgs + + here->B3SOIDDgbds * Vds + here->B3SOIDDgbps * Vps + + here->B3SOIDDgbes * Ves + here->B3SOIDDgbT * delTemp); + + /* Calculate Qinv for Noise analysis */ + + T1 = Vgsteff * (1.0 - 0.5 * Abeff * Vdseff / Vgst2Vtm); + here->B3SOIDDqinv = -model->B3SOIDDcox * pParam->B3SOIDDweff * Leff * T1; + + /* Begin CV (charge) model */ + + if ((model->B3SOIDDxpart < 0) || (!ChargeComputationNeeded)) + { qgate = qdrn = qsrc = qbody = 0.0; + here->B3SOIDDcggb = here->B3SOIDDcgsb = here->B3SOIDDcgdb = 0.0; + here->B3SOIDDcdgb = here->B3SOIDDcdsb = here->B3SOIDDcddb = 0.0; + here->B3SOIDDcbgb = here->B3SOIDDcbsb = here->B3SOIDDcbdb = 0.0; + goto finished; + } + else + { + CoxWL = model->B3SOIDDcox * pParam->B3SOIDDweffCV + * pParam->B3SOIDDleffCV; + + /* By using this Vgsteff,cv, discontinuity in moderate + inversion charges can be avoid. However, in capMod=3, + Vdsat from IV is used. The dVdsat_dVg is referred to + the IV Vgsteff and therefore induces error in the charges + derivatives. Fortunately, Vgsteff,iv and Vgsteff,cv are + different only in subthreshold where Qsubs is neglectible. + So the errors in derivatives is not a serious problem */ + + if ((VgstNVt > -EXP_THRESHOLD) && (VgstNVt < EXP_THRESHOLD)) + { ExpVgst *= ExpVgst; + Vgsteff = n * Vtm * log(1.0 + ExpVgst); + T0 = ExpVgst / (1.0 + ExpVgst); + T1 = -T0 * (dVth_dVb + Vgst / n * dn_dVb) + Vgsteff / n * dn_dVb; + dVgsteff_dVd = -T0 * (dVth_dVd + Vgst / n * dn_dVd) + + Vgsteff / n * dn_dVd + T1 * dVbseff_dVd; + dVgsteff_dVg = T0 * dVgs_eff_dVg + T1 * dVbseff_dVg; + dVgsteff_dVb = T1 * dVbseff_dVb; + dVgsteff_dVe = T1 * dVbseff_dVe; + if (selfheat) + dVgsteff_dT = -T0 * (dVth_dT + Vgst / Temp) + Vgsteff / Temp + + T1 * dVbseff_dT; + else dVgsteff_dT = 0.0; + } + + Vfb = Vth - phi - pParam->B3SOIDDk1 * sqrtPhis; + + dVfb_dVb = dVth_dVb - pParam->B3SOIDDk1 * dsqrtPhis_dVb; + dVfb_dVd = dVth_dVd; + dVfb_dT = dVth_dT; + + if ((model->B3SOIDDcapMod == 2) || (model->B3SOIDDcapMod == 3)) + { + /* Necessary because charge behaviour very strange at + Vgsteff = 0 */ + Vgsteff += 1e-4; + + /* Something common in capMod 2 and 3 */ + V3 = Vfb - Vgs_eff + Vbseff - DELTA_3; + if (Vfb <= 0.0) + { T0 = sqrt(V3 * V3 - 4.0 * DELTA_3 * Vfb); + T2 = -DELTA_3 / T0; + } + else + { T0 = sqrt(V3 * V3 + 4.0 * DELTA_3 * Vfb); + T2 = DELTA_3 / T0; + } + + T1 = 0.5 * (1.0 + V3 / T0); + Vfbeff = Vfb - 0.5 * (V3 + T0); + dVfbeff_dVd = (1.0 - T1 - T2) * dVfb_dVd; + dVfbeff_dVb = (1.0 - T1 - T2) * dVfb_dVb - T1; + dVfbeff_dVrg = T1 * dVgs_eff_dVg; + if (selfheat) dVfbeff_dT = (1.0 - T1 - T2) * dVfb_dT; + else dVfbeff_dT = 0.0; + + Qac0 = -CoxWL * (Vfbeff - Vfb); + dQac0_dVrg = -CoxWL * dVfbeff_dVrg; + dQac0_dVd = -CoxWL * (dVfbeff_dVd - dVfb_dVd); + dQac0_dVb = -CoxWL * (dVfbeff_dVb - dVfb_dVb); + if (selfheat) dQac0_dT = -CoxWL * (dVfbeff_dT - dVfb_dT); + else dQac0_dT = 0.0; + + T0 = 0.5 * K1; + T3 = Vgs_eff - Vfbeff - Vbseff - Vgsteff; + if (pParam->B3SOIDDk1 == 0.0) + { T1 = 0.0; + T2 = 0.0; + } + else if (T3 < 0.0) + { T1 = T0 + T3 / pParam->B3SOIDDk1; + T2 = CoxWL; + } + else + { T1 = sqrt(T0 * T0 + T3); + T2 = CoxWL * T0 / T1; + } + + Qsub0 = CoxWL * K1 * (T0 - T1); + + dQsub0_dVrg = T2 * (dVfbeff_dVrg - dVgs_eff_dVg); + dQsub0_dVg = T2; + dQsub0_dVd = T2 * dVfbeff_dVd; + dQsub0_dVb = T2 * (dVfbeff_dVb + 1); + if (selfheat) dQsub0_dT = T2 * dVfbeff_dT; + else dQsub0_dT = 0.0; + + One_Third_CoxWL = CoxWL / 3.0; + Two_Third_CoxWL = 2.0 * One_Third_CoxWL; + AbulkCV = Abulk0 * pParam->B3SOIDDabulkCVfactor; + dAbulkCV_dVb = pParam->B3SOIDDabulkCVfactor * dAbulk0_dVb; + + /* This is actually capMod=2 calculation */ + VdsatCV = Vgsteff / AbulkCV; + dVdsatCV_dVg = 1.0 / AbulkCV; + dVdsatCV_dVb = -VdsatCV * dAbulkCV_dVb / AbulkCV; + VdsatCV += 1e-5; + + V4 = VdsatCV - Vds - DELTA_4; + T0 = sqrt(V4 * V4 + 4.0 * DELTA_4 * VdsatCV); + VdseffCV = VdsatCV - 0.5 * (V4 + T0); + T1 = 0.5 * (1.0 + V4 / T0); + T2 = DELTA_4 / T0; + T3 = (1.0 - T1 - T2) / AbulkCV; + dVdseffCV_dVg = T3; + dVdseffCV_dVd = T1; + dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb; + + if (model->B3SOIDDcapMod == 2) + { + /* VdsCV Make it compatible with capMod 3 */ + VdsCV = VdseffCV; + dVdsCV_dVg = dVdseffCV_dVg; + dVdsCV_dVd = dVdseffCV_dVd; + dVdsCV_dVb = dVdseffCV_dVb; + dVdsCV_dVc = 0.0; + + /* This is good for Xc calculation */ + VdsCV += 1e-5; + if (VdsCV > (VdsatCV-1e-7)) VdsCV=VdsatCV-1e-7; + + /* VcsCV calculation */ + T1 = VdsCV - Vcs - VdsCV * VdsCV * DELTA_Vcscv; + T5 = 2 * DELTA_Vcscv; + T2 = sqrt(T1 * T1 + T5 * VdsCV * VdsCV); + + dT1_dVb = dVdsCV_dVb * (1.0 - 2.0 * VdsCV * DELTA_Vcscv); + dT2_dVb = (T1 * dT1_dVb + T5 * VdsCV * dVdsCV_dVb)/T2; + + dT1_dVd = dVdsCV_dVd * (1.0 - 2.0 * VdsCV * DELTA_Vcscv); + dT2_dVd = (T1 * dT1_dVd + T5 * VdsCV * dVdsCV_dVd)/ T2; + + dT1_dVg = dVdsCV_dVg * (1.0 - 2.0 * VdsCV * DELTA_Vcscv) ; + dT2_dVg = (T1 * dT1_dVg + T5 * VdsCV * dVdsCV_dVg)/T2; + + dT1_dVc = -1; + dT2_dVc = T1 * dT1_dVc / T2; + + VcsCV = Vcs + 0.5 * (T1 - T2); + + dVcsCV_dVb = 0.5 * (dT1_dVb - dT2_dVb); + dVcsCV_dVg = 0.5 * (dT1_dVg - dT2_dVg); + dVcsCV_dVd = 0.5 * (dT1_dVd - dT2_dVd); + dVcsCV_dVc = 1.0 + 0.5 * (dT1_dVc - dT2_dVc); + + if (VcsCV < 0.0) VcsCV = 0.0; + else if (VcsCV > VdsCV) VcsCV = VdsCV; + + /* Xc calculation */ + T3 = 2 * VdsatCV - VcsCV; + T4 = 2 * VdsatCV - VdsCV; + dT4_dVg = 2 * dVdsatCV_dVg - dVdsCV_dVg; + dT4_dVd = - dVdsCV_dVd; + dT4_dVb = 2 * dVdsatCV_dVb - dVdsCV_dVb; + T0 = T3 * VcsCV; + T1 = T4 * VdsCV; + Xc = T0 / T1; + + dT0_dVb = VcsCV * (2 * dVdsatCV_dVb - dVcsCV_dVb) + + T3 * dVcsCV_dVb; + dT0_dVg = VcsCV * (2 * dVdsatCV_dVg - dVcsCV_dVg) + + T3 * dVcsCV_dVg; + dT0_dVd = 2 * dVcsCV_dVd * (VdsatCV - VcsCV); + dT0_dVc = 2 * dVcsCV_dVc * (VdsatCV - VcsCV); + + dT1_dVb = VdsCV * dT4_dVb + T4 * dVdsCV_dVb; + dT1_dVg = VdsCV * dT4_dVg + T4 * dVdsCV_dVg; + dT1_dVd = dVdsCV_dVd * T4 + VdsCV * dT4_dVd; + T3 = T1 * T1; + + dXc_dVb = (dT0_dVb - dT1_dVb * Xc) / T1; + dXc_dVg = (dT0_dVg - dT1_dVg * Xc) / T1; + dXc_dVd = (dT0_dVd - dT1_dVd * Xc) / T1; + dXc_dVc = dT0_dVc / T1; + + T0 = AbulkCV * VcsCV; + dT0_dVb = dAbulkCV_dVb * VcsCV + dVcsCV_dVb * AbulkCV; + dT0_dVg = dVcsCV_dVg * AbulkCV; + dT0_dVd = AbulkCV * dVcsCV_dVd; + dT0_dVc = AbulkCV * dVcsCV_dVc; + + T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1e-20); + dT1_dVb = -6.0 * dT0_dVb; + dT1_dVg = 12.0 * (1.0 - 0.5 * dT0_dVg); + dT1_dVd = -6.0 * dT0_dVd; + dT1_dVc = -6.0 * dT0_dVc; + + T2 = VcsCV / T1; + T4 = T1 * T1; + dT2_dVb = ( dVcsCV_dVb * T1 - dT1_dVb * VcsCV ) / T4; + dT2_dVg = ( dVcsCV_dVg * T1 - dT1_dVg * VcsCV ) / T4; + dT2_dVd = ( dVcsCV_dVd * T1 - dT1_dVd * VcsCV ) / T4; + dT2_dVc = ( dVcsCV_dVc * T1 - dT1_dVc * VcsCV ) / T4; + + T3 = T0 * T2; + dT3_dVb = dT0_dVb * T2 + dT2_dVb * T0; + dT3_dVg = dT0_dVg * T2 + dT2_dVg * T0; + dT3_dVd = dT0_dVd * T2 + dT2_dVd * T0; + dT3_dVc = dT0_dVc * T2 + dT2_dVc * T0; + + T4 = 1.0 - AbulkCV; + dT4_dVb = - dAbulkCV_dVb; + + T5 = 0.5 * VcsCV - T3; + dT5_dVb = 0.5 * dVcsCV_dVb - dT3_dVb; + dT5_dVg = 0.5 * dVcsCV_dVg - dT3_dVg; + dT5_dVd = 0.5 * dVcsCV_dVd - dT3_dVd; + dT5_dVc = 0.5 * dVcsCV_dVc - dT3_dVc; + + T6 = T4 * T5 * CoxWL; + T7 = CoxWL * Xc; + + Qsubs1 = CoxWL * Xc * T4 * T5; + dQsubs1_dVb = T6 * dXc_dVb + T7 * ( T4*dT5_dVb + dT4_dVb*T5 ); + dQsubs1_dVg = T6 * dXc_dVg + T7 * T4 * dT5_dVg; + dQsubs1_dVd = T6 * dXc_dVd + T7 * T4 * dT5_dVd; + dQsubs1_dVc = T6 * dXc_dVc + T7 * T4 * dT5_dVc; + + Qsubs2 = -CoxWL * (1-Xc) * (AbulkCV - 1.0) * Vcs; + + T2 = CoxWL * (AbulkCV - 1.0) * Vcs; + dQsubs2_dVb = T2 * dXc_dVb - CoxWL * (1-Xc) * Vcs * dAbulkCV_dVb; + dQsubs2_dVg = T2 * dXc_dVg; + dQsubs2_dVd = T2 * dXc_dVd; + dQsubs2_dVc = T2 * dXc_dVc - CoxWL * (1-Xc) * (AbulkCV - 1.0); + + Qbf = Qac0 + Qsub0 + Qsubs1 + Qsubs2; + dQbf_dVrg = dQac0_dVrg + dQsub0_dVrg; + dQbf_dVg = dQsub0_dVg + dQsubs1_dVg + dQsubs2_dVg; + dQbf_dVd = dQac0_dVd + dQsub0_dVd + dQsubs1_dVd + + dQsubs2_dVd; + dQbf_dVb = dQac0_dVb + dQsub0_dVb + dQsubs1_dVb + + dQsubs2_dVb; + dQbf_dVc = dQsubs1_dVc + dQsubs2_dVc; + dQbf_dVe = 0.0; + if (selfheat) dQbf_dT = dQac0_dT + dQsub0_dT; + else dQbf_dT = 0.0; + } /* End of if (capMod == 2) */ + else if (model->B3SOIDDcapMod == 3) + { + /* Front gate strong inversion depletion charge */ + /* VdssatCV calculation */ + + T1 = Vgsteff + K1*sqrtPhis + 0.5*K1*K1; + T2 = Vgsteff + K1*sqrtPhis + Phis + 0.25*K1*K1; + + dT1_dVb = K1*dsqrtPhis_dVb; + dT2_dVb = dT1_dVb + dPhis_dVb; + dT1_dVg = dT2_dVg = 1; + + /* Note VdsatCV is redefined in capMod = 3 */ + VdsatCV = T1 - K1*sqrt(T2); + + dVdsatCV_dVb = dT1_dVb - K1/2/sqrt(T2)*dT2_dVb; + dVdsatCV_dVg = dT1_dVg - K1/2/sqrt(T2)*dT2_dVg; + + T1 = VdsatCV - Vdsat; + dT1_dVg = dVdsatCV_dVg - dVdsat_dVg; + dT1_dVb = dVdsatCV_dVb - dVdsat_dVb; + dT1_dVd = - dVdsat_dVd; + dT1_dVc = - dVdsat_dVc; + dT1_dT = - dVdsat_dT; + + if (!(T1 == 0.0)) + { T3 = -0.5 * Vdsat / T1; /* Vdsmax */ + T2 = T3 * Vdsat; + T4 = T2 + T1 * T3 * T3; /* fmax */ + if ((Vdseff > T2) && (T1 < 0)) + { + VdsCV = T4; + T5 = -0.5 / (T1 * T1); + dT3_dVg = T5 * (T1 * dVdsat_dVg - Vdsat * dT1_dVg); + dT3_dVb = T5 * (T1 * dVdsat_dVb - Vdsat * dT1_dVb); + dT3_dVd = T5 * (T1 * dVdsat_dVd - Vdsat * dT1_dVd); + dT3_dVc = T5 * (T1 * dVdsat_dVc - Vdsat * dT1_dVc); + if (selfheat) + dT3_dT=T5 * (T1 * dVdsat_dT - Vdsat * dT1_dT); + else dT3_dT=0.0; + + dVdsCV_dVd = T3 * dVdsat_dVd + Vdsat * dT3_dVd + + T3 * (2 * T1 * dT3_dVd + T3 * dT1_dVd); + dVdsCV_dVg = T3 * dVdsat_dVg + Vdsat * dT3_dVg + + T3 * (2 * T1 * dT3_dVg + T3 * dT1_dVg); + dVdsCV_dVb = T3 * dVdsat_dVb + Vdsat * dT3_dVb + + T3 * (2 * T1 * dT3_dVb + T3 * dT1_dVb); + dVdsCV_dVc = T3 * dVdsat_dVc + Vdsat * dT3_dVc + + T3 * (2 * T1 * dT3_dVc + T3 * dT1_dVc); + if (selfheat) + dVdsCV_dT = T3 * dVdsat_dT + Vdsat * dT3_dT + + T3 * (2 * T1 * dT3_dT + T3 * dT1_dT ); + else dVdsCV_dT = 0.0; + } else + { T5 = Vdseff / Vdsat; + T6 = T5 * T5; + T7 = 2 * T1 * T5 / Vdsat; + T8 = T7 / Vdsat; + VdsCV = Vdseff + T1 * T6; + dVdsCV_dVd = dVdseff_dVd + T8 * + ( Vdsat * dVdseff_dVd + - Vdseff * dVdsat_dVd) + + T6 * dT1_dVd; + dVdsCV_dVb = dVdseff_dVb + T8 * ( Vdsat * + dVdseff_dVb - Vdseff * dVdsat_dVb) + + T6 * dT1_dVb; + dVdsCV_dVg = dVdseff_dVg + T8 * + ( Vdsat * dVdseff_dVg + - Vdseff * dVdsat_dVg) + + T6 * dT1_dVg; + dVdsCV_dVc = dVdseff_dVc + T8 * + ( Vdsat * dVdseff_dVc + - Vdseff * dVdsat_dVc) + + T6 * dT1_dVc; + if (selfheat) + dVdsCV_dT = dVdseff_dT + T8 * + ( Vdsat * dVdseff_dT + - Vdseff * dVdsat_dT ) + + T6 * dT1_dT ; + else dVdsCV_dT = 0.0; + } + } else + { VdsCV = Vdseff; + dVdsCV_dVb = dVdseff_dVb; + dVdsCV_dVd = dVdseff_dVd; + dVdsCV_dVg = dVdseff_dVg; + dVdsCV_dVc = dVdseff_dVc; + dVdsCV_dT = dVdseff_dT; + } + if (VdsCV < 0.0) VdsCV = 0.0; + VdsCV += 1e-4; + + if (VdsCV > (VdsatCV - 1e-7)) + { + VdsCV = VdsatCV - 1e-7; + } + Phisd = Phis + VdsCV; + dPhisd_dVb = dPhis_dVb + dVdsCV_dVb; + dPhisd_dVd = dVdsCV_dVd; + dPhisd_dVg = dVdsCV_dVg; + dPhisd_dVc = dVdsCV_dVc; + dPhisd_dT = dVdsCV_dT; + sqrtPhisd = sqrt(Phisd); + + /* Qdep0 - Depletion charge at Vgs=Vth */ + T10 = CoxWL * K1; + Qdep0 = T10 * sqrtPhis; + dQdep0_dVb = T10 * dsqrtPhis_dVb; + + /* VcsCV calculation */ + T1 = VdsCV - Vcs - VdsCV * VdsCV * DELTA_Vcscv; + T5 = 2 * DELTA_Vcscv; + T2 = sqrt(T1 * T1 + T5 * VdsCV * VdsCV); + + dT1_dVb = dVdsCV_dVb * (1.0 - 2.0 * VdsCV * DELTA_Vcscv); + dT2_dVb = (T1 * dT1_dVb + T5 * VdsCV * dVdsCV_dVb)/T2; + + dT1_dVd = dVdsCV_dVd * (1.0 - 2.0 * VdsCV * DELTA_Vcscv); + dT2_dVd = (T1 * dT1_dVd + T5 * VdsCV * dVdsCV_dVd)/ T2; + + dT1_dVg = dVdsCV_dVg * (1.0 - 2.0 * VdsCV * DELTA_Vcscv) ; + dT2_dVg = (T1 * dT1_dVg + T5 * VdsCV * dVdsCV_dVg)/T2; + + dT1_dVc = dVdsCV_dVc * (1.0 - 2.0 * VdsCV * DELTA_Vcscv) - 1; + dT2_dVc = (T1 * dT1_dVc + T5 * VdsCV * dVdsCV_dVc)/T2; + + if (selfheat) + { + dT1_dT = dVdsCV_dT * (1.0 - 2.0 * VdsCV * DELTA_Vcscv); + dT2_dT = (T1 * dT1_dT + T5 * VdsCV * dVdsCV_dT )/ T2; + } else dT1_dT = dT2_dT = 0.0; + + VcsCV = Vcs + 0.5*(T1 - T2); + + dVcsCV_dVb = 0.5 * (dT1_dVb - dT2_dVb); + dVcsCV_dVg = 0.5 * (dT1_dVg - dT2_dVg); + dVcsCV_dVd = 0.5 * (dT1_dVd - dT2_dVd); + dVcsCV_dVc = 1 + 0.5 * (dT1_dVc - dT2_dVc); + if (selfheat) + dVcsCV_dT = 0.5 * (dT1_dT - dT2_dT); + else dVcsCV_dT = 0.0; + + Phisc = Phis + VcsCV; + dPhisc_dVb = dPhis_dVb + dVcsCV_dVb; + dPhisc_dVd = dVcsCV_dVd; + dPhisc_dVg = dVcsCV_dVg; + dPhisc_dVc = dVcsCV_dVc; + dPhisc_dT = dVcsCV_dT; + sqrtPhisc = sqrt(Phisc); + + /* Xc calculation */ + T1 = Vgsteff + K1*sqrtPhis - 0.5*VdsCV; + T2 = CONST_2OV3*K1*(Phisd*sqrtPhisd - Phis*sqrtPhis); + T3 = Vgsteff + K1*sqrtPhis - 0.5*VcsCV; + T4 = CONST_2OV3*K1*(Phisc*sqrtPhisc - Phis*sqrtPhis); + T5 = T1*VdsCV - T2; + T6 = T3*VcsCV - T4; + Xc = T6/T5; + + dT1_dVb = K1*dsqrtPhis_dVb - 0.5*dVdsCV_dVb; + dT2_dVb = K1*(sqrtPhisd*dPhisd_dVb - sqrtPhis*dPhis_dVb); + dT3_dVb = K1*dsqrtPhis_dVb - 0.5*dVcsCV_dVb; + dT4_dVb = K1*(sqrtPhisc*dPhisc_dVb - sqrtPhis*dPhis_dVb); + + dT1_dVd = - 0.5*dVdsCV_dVd; + dT2_dVd = K1 * (sqrtPhisd*dPhisd_dVd); + dT3_dVd = - 0.5*dVcsCV_dVd; + dT4_dVd = K1 * (sqrtPhisc*dPhisc_dVd); + + dT1_dVg = 1 - 0.5*dVdsCV_dVg; + dT2_dVg = K1 * (sqrtPhisd*dPhisd_dVg); + dT3_dVg = 1 - 0.5*dVcsCV_dVg; + dT4_dVg = K1 * (sqrtPhisc*dPhisc_dVg); + + dT1_dVc = - 0.5*dVdsCV_dVc; + dT2_dVc = K1 * (sqrtPhisd*dPhisd_dVc); + dT3_dVc = - 0.5*dVcsCV_dVc; + dT4_dVc = K1 * (sqrtPhisc*dPhisc_dVc); + + if (selfheat) + { + dT1_dT = - 0.5*dVdsCV_dT; + dT2_dT = K1 * (sqrtPhisd*dPhisd_dT); + dT3_dT = - 0.5*dVcsCV_dT; + dT4_dT = K1 * (sqrtPhisc*dPhisc_dT); + } else dT1_dT = dT2_dT = dT3_dT = dT4_dT = 0.0; + + dT5_dVb = T1 * dVdsCV_dVb + VdsCV * dT1_dVb - dT2_dVb; + dT6_dVb = T3 * dVcsCV_dVb + VcsCV * dT3_dVb - dT4_dVb; + + dT5_dVd = T1 * dVdsCV_dVd + VdsCV * dT1_dVd - dT2_dVd; + dT6_dVd = T3 * dVcsCV_dVd + VcsCV * dT3_dVd - dT4_dVd; + + dT5_dVg = T1 * dVdsCV_dVg + VdsCV * dT1_dVg - dT2_dVg; + dT6_dVg = T3 * dVcsCV_dVg + VcsCV * dT3_dVg - dT4_dVg; + + dT5_dVc = T1 * dVdsCV_dVc + VdsCV * dT1_dVc - dT2_dVc; + dT6_dVc = T3 * dVcsCV_dVc + VcsCV * dT3_dVc - dT4_dVc; + + if (selfheat) + { + dT5_dT = T1 * dVdsCV_dT + VdsCV * dT1_dT - dT2_dT; + dT6_dT = T3 * dVcsCV_dT + VcsCV * dT3_dT - dT4_dT; + } else dT5_dT = dT6_dT = 0.0; + + dXc_dVb = (dT6_dVb - T6/T5 * dT5_dVb) / T5; + dXc_dVd = (dT6_dVd - T6/T5 * dT5_dVd) / T5; + dXc_dVg = (dT6_dVg - T6/T5 * dT5_dVg) / T5; + dXc_dVc = (dT6_dVc - T6/T5 * dT5_dVc) / T5; + if (selfheat) + dXc_dT = (dT6_dT - T6/T5 * dT5_dT ) / T5; + else dXc_dT = 0.0; + + T10 = Phis * sqrtPhis ; + T5 = Phisc * sqrtPhisc; + T0 = T5 - T10; + T1 = Vgsteff + K1*sqrtPhis + Phis; + T2 = Phisc*T5 - Phis*T10; + T3 = K1*VcsCV*(Phis + 0.5*VcsCV); + + dT0_dVb = 1.5 *(sqrtPhisc*dPhisc_dVb-sqrtPhis*dPhis_dVb); + dT1_dVb = (0.5*K1/sqrtPhis + 1) * dPhis_dVb; + dT2_dVb = 2.5 * (T5 * dPhisc_dVb - T10 * dPhis_dVb); + dT3_dVb = K1 * ( VcsCV * (dPhis_dVb + 0.5 * dVcsCV_dVb) + + dVcsCV_dVb * (Phis + 0.5*VcsCV)); + + dT0_dVd = 1.5 * sqrtPhisc * dPhisc_dVd; + dT1_dVd = 0; + dT2_dVd = 2.5 * T5 * dPhisc_dVd; + dT3_dVd = K1 * (Phis + VcsCV) * dVcsCV_dVd; + + dT0_dVg = 1.5 * sqrtPhisc * dPhisc_dVg; + dT1_dVg = 1; + dT2_dVg = 2.5 * T5 * dPhisc_dVg; + dT3_dVg = K1 * (VcsCV * 0.5 * dVcsCV_dVg + + dVcsCV_dVg * (Phis + 0.5*VcsCV)); + + dT0_dVc = 1.5 * sqrtPhisc * dPhisc_dVc; + dT1_dVc = 0.0; + dT2_dVc = 2.5 * T5 * dPhisc_dVc; + dT3_dVc = K1 * (VcsCV * 0.5 * dVcsCV_dVc + + dVcsCV_dVc * (Phis + 0.5*VcsCV)); + + if (selfheat) + { + dT0_dT = 1.5 * sqrtPhisc * dPhisc_dT; + dT1_dT = 0; + dT2_dT = 2.5 * T5 * dPhisc_dT; + dT3_dT = K1 * (Phis + VcsCV) * dVcsCV_dT; + } else dT0_dT = dT1_dT = dT2_dT = dT3_dT = 0.0; + + Nomi = K1*(CONST_2OV3*T1*T0 - 0.4*T2 - T3); + + dNomi_dVb = K1*(CONST_2OV3 * (T1 * dT0_dVb + T0*dT1_dVb) + - 0.4 * dT2_dVb - dT3_dVb); + dNomi_dVd = K1*(CONST_2OV3 * (T1 * dT0_dVd + T0*dT1_dVd) + - 0.4 * dT2_dVd - dT3_dVd); + dNomi_dVg = K1*(CONST_2OV3 * (T1 * dT0_dVg + T0*dT1_dVg) + - 0.4 * dT2_dVg - dT3_dVg); + dNomi_dVc = K1*(CONST_2OV3 * (T1 * dT0_dVc + T0*dT1_dVc) + - 0.4 * dT2_dVc - dT3_dVc); + if (selfheat) + dNomi_dT = K1*(CONST_2OV3 * (T1 * dT0_dT + T0*dT1_dT ) + - 0.4 * dT2_dT - dT3_dT ); + else + dNomi_dT = 0.0; + + T4 = Vgsteff + K1*sqrtPhis - 0.5*VdsCV; + T5 = CONST_2OV3*K1*(Phisd*sqrtPhisd - T10); + + dT4_dVb = K1 * dsqrtPhis_dVb - 0.5*dVdsCV_dVb; + dT5_dVb = K1*(sqrtPhisd*dPhisd_dVb - sqrtPhis*dPhis_dVb); + + dT4_dVd = - 0.5*dVdsCV_dVd; + dT5_dVd = K1*( sqrtPhisd * dPhisd_dVd); + + dT4_dVg = 1 - 0.5 * dVdsCV_dVg; + dT5_dVg = K1* sqrtPhisd * dPhisd_dVg; + + dT4_dVc = - 0.5 * dVdsCV_dVc; + dT5_dVc = K1* sqrtPhisd * dPhisd_dVc; + + if (selfheat) + { + dT4_dT = - 0.5 * dVdsCV_dT; + dT5_dT = K1* sqrtPhisd * dPhisd_dT; + } else dT4_dT = dT5_dT = 0.0; + + Denomi = T4*VdsCV - T5; + + dDenomi_dVb = VdsCV*dT4_dVb + T4*dVdsCV_dVb - dT5_dVb; + dDenomi_dVd = VdsCV*dT4_dVd + T4*dVdsCV_dVd - dT5_dVd; + dDenomi_dVg = VdsCV*dT4_dVg + T4*dVdsCV_dVg - dT5_dVg; + dDenomi_dVc = VdsCV*dT4_dVc + T4*dVdsCV_dVc - dT5_dVc; + if (selfheat) + dDenomi_dT = VdsCV*dT4_dT + T4*dVdsCV_dT - dT5_dT; + else dDenomi_dT = 0.0; + + T6 = -CoxWL / Denomi; + Qsubs1 = T6 * Nomi; + dQsubs1_dVb = T6*(dNomi_dVb - Nomi / Denomi*dDenomi_dVb); + dQsubs1_dVg = T6*(dNomi_dVg - Nomi / Denomi*dDenomi_dVg); + dQsubs1_dVd = T6*(dNomi_dVd - Nomi / Denomi*dDenomi_dVd); + dQsubs1_dVc = T6*(dNomi_dVc - Nomi / Denomi*dDenomi_dVc); + if (selfheat) + dQsubs1_dT = T6*(dNomi_dT - Nomi / Denomi*dDenomi_dT ); + else dQsubs1_dT = 0.0; + + T6 = sqrt(1e-4 + phi - Vbs0eff); + T7 = K1 * CoxWL; + T8 = 1 - Xc; + T10 = T7 * T6; + T11 = T7 * T8 * 0.5 / T6; + Qsubs2 = -T10 * T8 ; + dQsubs2_dVg = T10 * dXc_dVg; + dQsubs2_dVb = T10 * dXc_dVb; + dQsubs2_dVd = T10 * dXc_dVd + T11 * dVbs0eff_dVd; + dQsubs2_dVc = T10 * dXc_dVc; + dQsubs2_dVe = T11 * dVbs0eff_dVe; + dQsubs2_dVrg = T11 * dVbs0eff_dVg; + if (selfheat) + dQsubs2_dT = T10 * dXc_dT + T11 * dVbs0eff_dT; + else dQsubs2_dT = 0.0; + + Qbf = Qac0 + Qsub0 + Qsubs1 + Qsubs2 + Qdep0; + dQbf_dVrg = dQac0_dVrg + dQsub0_dVrg + dQsubs2_dVrg; + dQbf_dVg = dQsub0_dVg + dQsubs1_dVg + dQsubs2_dVg ; + dQbf_dVd = dQac0_dVd + dQsub0_dVd + dQsubs1_dVd + + dQsubs2_dVd; + dQbf_dVb = dQac0_dVb + dQsub0_dVb + dQsubs1_dVb + + dQsubs2_dVb + dQdep0_dVb; + dQbf_dVc = dQsubs1_dVc + dQsubs2_dVc; + dQbf_dVe = dQsubs2_dVe; + if (selfheat) + dQbf_dT = dQac0_dT + dQsub0_dT + dQsubs1_dT + dQsubs2_dT; + else dQbf_dT = 0.0; + } /* End of if capMod == 3 */ + + /* Something common in both capMod 2 or 3 */ + + /* Backgate charge */ + CboxWL = pParam->B3SOIDDkb3 * Cbox * pParam->B3SOIDDweffCV + * pParam->B3SOIDDleffCV; + T0 = 0.5 * K1; + T2 = sqrt(phi - Vbs0t); + T3 = phi + K1 * T2 - Vbs0t; + T4 = sqrt(T0 * T0 + T3); + Qsicv = K1 * CoxWL * ( T0 - T4); + T6 = CoxWL * T0 / T4 * (1 + T0 / T2); + if (selfheat) dQsicv_dT = T6 * dVbs0t_dT; + else dQsicv_dT = 0.0; + + T2 = sqrt(phi - Vbs0mos); + T3 = phi + K1 * T2 - Vbs0mos; + T4 = sqrt(T0 * T0 + T3); + Qbf0 = K1 * CoxWL * ( T0 - T4); + T6 = CoxWL * T0 / T4 * (1 + T0 / T2); + dQbf0_dVe = T6 * dVbs0mos_dVe; + if (selfheat) dQbf0_dT = T6 * dVbs0mos_dT; + else dQbf0_dT = 0.0; + + T5 = -CboxWL * (Vbsdio - Vbs0); + T6 = CboxWL * Xc; + Qe1 = -Qsicv + Qbf0 + T5 * Xc; + dQe1_dVg = T5 * (dXc_dVg * dVgsteff_dVg + dXc_dVb * dVbseff_dVg + + dXc_dVc * dVcs_dVg) - T6 * dVbsdio_dVg; + dQe1_dVb = T5 * (dXc_dVg * dVgsteff_dVb + dXc_dVb * dVbseff_dVb + + dXc_dVc * dVcs_dVb) - T6 * dVbsdio_dVb; + dQe1_dVd = T5 * (dXc_dVg * dVgsteff_dVd + dXc_dVb * dVbseff_dVd + + dXc_dVc * dVcs_dVd + dXc_dVd) - T6 * dVbsdio_dVd; + dQe1_dVe = dQbf0_dVe + T6 * (dVbs0_dVe - dVbsdio_dVe); + if (selfheat) + dQe1_dT = -dQsicv_dT + dQbf0_dT + + T5 * (dXc_dVg * dVgsteff_dT + dXc_dVb * dVbseff_dT + + dXc_dVc * dVcs_dT + dXc_dT ) + + T6 * (dVbs0_dT - dVbsdio_dT); + else dQe1_dT = 0.0; + + T2 = -model->B3SOIDDcboxt * pParam->B3SOIDDweffCV + * pParam->B3SOIDDleffCV; + T3 = T2 * 0.5 * (1 - Xc); + T4 = T2 * 0.5 * (VdsCV - VcsCV); + Qe2 = T2 * 0.5 * (1 - Xc) * (VdsCV - VcsCV); + + /* T10 - dVgsteff, T11 - dVbseff, T12 - dVcs */ + T10 = T3 * (dVdsCV_dVg - dVcsCV_dVg) - T4 * dXc_dVg; + T11 = T3 * (dVdsCV_dVb - dVcsCV_dVb) - T4 * dXc_dVb; + T12 = T3 * (dVdsCV_dVc - dVcsCV_dVc) - T4 * dXc_dVc; + dQe2_dVg = T10 * dVgsteff_dVg + T11 * dVbseff_dVg + T12 * dVcs_dVg; + dQe2_dVb = T10 * dVgsteff_dVb + T11 * dVbseff_dVb + T12 * dVcs_dVb; + dQe2_dVd = T10 * dVgsteff_dVd + T11 * dVbseff_dVd + T12 * dVcs_dVd + + T3 * (dVdsCV_dVd - dVcsCV_dVd) - T4 * dXc_dVd; + dQe2_dVe = T10 * dVgsteff_dVe + T11 * dVbseff_dVe + T12 * dVcs_dVe; + if (selfheat) + dQe2_dT = T10 * dVgsteff_dT + T11 * dVbseff_dT + T12 * dVcs_dT + + T3 * (dVdsCV_dT - dVcsCV_dT ) - T4 * dXc_dT; + else dQe2_dT = 0.0; + + /* This transform all the dependency on Vgsteff, Vbseff, + Vcs into real ones */ + Cbg = dQbf_dVrg + dQbf_dVg * dVgsteff_dVg + + dQbf_dVb * dVbseff_dVg + dQbf_dVc * dVcs_dVg; + Cbb = dQbf_dVg * dVgsteff_dVb + dQbf_dVb * dVbseff_dVb + + dQbf_dVc * dVcs_dVb; + Cbd = dQbf_dVg * dVgsteff_dVd + dQbf_dVb * dVbseff_dVd + + dQbf_dVc * dVcs_dVd + dQbf_dVd; + Cbe = dQbf_dVg * dVgsteff_dVe + dQbf_dVb * dVbseff_dVe + + dQbf_dVc * dVcs_dVe + dQbf_dVe; + if (selfheat) + CbT = dQbf_dVg * dVgsteff_dT + dQbf_dVb * dVbseff_dT + + dQbf_dVc * dVcs_dT + dQbf_dT; + else CbT = 0.0; + + Ce1g = dQe1_dVg; + Ce1b = dQe1_dVb; + Ce1d = dQe1_dVd; + Ce1e = dQe1_dVe; + Ce1T = dQe1_dT; + + Ce2g = dQe2_dVg; + Ce2b = dQe2_dVb; + Ce2d = dQe2_dVd; + Ce2e = dQe2_dVe; + Ce2T = dQe2_dT; + + /* Total inversion charge */ + T0 = AbulkCV * VdseffCV; + T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1e-20); + T2 = VdseffCV / T1; + T3 = T0 * T2; + + T4 = (1.0 - 12.0 * T2 * T2 * AbulkCV); + T5 = (6.0 * T0 * (4.0 * Vgsteff - T0) / (T1 * T1) - 0.5); + T6 = 12.0 * T2 * T2 * Vgsteff; + + qinv = CoxWL * (Vgsteff - 0.5 * VdseffCV + T3); + Cgg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); + Cgd1 = CoxWL * T5 * dVdseffCV_dVd; + Cgb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb); + + /* Inversion charge partitioning into S / D */ + if (model->B3SOIDDxpart > 0.5) + { /* 0/100 Charge partition model */ + T1 = T1 + T1; + qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 + - T0 * T0 / T1); + T7 = (4.0 * Vgsteff - T0) / (T1 * T1); + T4 = -(0.5 + 24.0 * T0 * T0 / (T1 * T1)); + T5 = -(0.25 * AbulkCV - 12.0 * AbulkCV * T0 * T7); + T6 = -(0.25 * VdseffCV - 12.0 * T0 * VdseffCV * T7); + Csg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); + Csd1 = CoxWL * T5 * dVdseffCV_dVd; + Csb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb); + + } + else if (model->B3SOIDDxpart < 0.5) + { /* 40/60 Charge partition model */ + T1 = T1 / 12.0; + T2 = 0.5 * CoxWL / (T1 * T1); + T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff + * (Vgsteff - 4.0 * T0 / 3.0)) + - 2.0 * T0 * T0 * T0 / 15.0; + qsrc = -T2 * T3; + T7 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0) + + 0.4 * T0 * T0; + T4 = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0 + * Vgsteff - 8.0 * T0 / 3.0) + + 2.0 * T0 * T0 / 3.0); + T5 = (qsrc / T1 + T2 * T7) * AbulkCV; + T6 = (qsrc / T1 * VdseffCV + T2 * T7 * VdseffCV); + Csg1 = T4 + T5 * dVdseffCV_dVg; + Csd1 = T5 * dVdseffCV_dVd; + Csb1 = T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb; + } + else + { /* 50/50 Charge partition model */ + qsrc = - 0.5 * qinv; + Csg1 = - 0.5 * Cgg1; + Csb1 = - 0.5 * Cgb1; + Csd1 = - 0.5 * Cgd1; + } + + Csg = Csg1 * dVgsteff_dVg + Csb1 * dVbseff_dVg; + Csd = Csd1 + Csg1 * dVgsteff_dVd + Csb1 * dVbseff_dVd; + Csb = Csg1 * dVgsteff_dVb + Csb1 * dVbseff_dVb; + Cse = Csg1 * dVgsteff_dVe + Csb1 * dVbseff_dVe; + if (selfheat) + CsT = Csg1 * dVgsteff_dT + Csb1 * dVbseff_dT; + else CsT = 0.0; + + T0 = QEX_FACT * K1 * CoxWL; + Qex = T0 * (Vbs - Vbsdio); + dQex_dVg = - T0 * dVbsdio_dVg; + dQex_dVb = T0 * (1 - dVbsdio_dVb); + dQex_dVd = - T0 * dVbsdio_dVd; + dQex_dVe = - T0 * dVbsdio_dVe; + if (selfheat) dQex_dT = - T0 * dVbsdio_dT; + else dQex_dT = 0.0; + + qgate = qinv - (Qbf + Qe2); + qbody = (Qbf - Qe1 + Qex); + qsub = Qe1 + Qe2 - Qex; + qdrn = -(qinv + qsrc); + + Cgg = (Cgg1 * dVgsteff_dVg + Cgb1 * dVbseff_dVg) - Cbg ; + Cgd = (Cgd1 + Cgg1 * dVgsteff_dVd + Cgb1 * dVbseff_dVd)-Cbd; + Cgb = (Cgb1 * dVbseff_dVb + Cgg1 * dVgsteff_dVb) - Cbb; + Cge = (Cgg1 * dVgsteff_dVe + Cgb1 * dVbseff_dVe) - Cbe; + if (selfheat) + CgT = (Cgg1 * dVgsteff_dT + Cgb1 * dVbseff_dT ) - CbT; + else CgT = 0.0; + + here->B3SOIDDcggb = Cgg - Ce2g; + here->B3SOIDDcgsb = - (Cgg + Cgd + Cgb + Cge) + + (Ce2g + Ce2d + Ce2b + Ce2e); + here->B3SOIDDcgdb = Cgd - Ce2d; + here->B3SOIDDcgeb = Cge - Ce2e; + here->B3SOIDDcgT = CgT - Ce2T; + + here->B3SOIDDcbgb = Cbg - Ce1g + dQex_dVg; + here->B3SOIDDcbsb = -(Cbg + Cbd + Cbb + Cbe) + + (Ce1g + Ce1d + Ce1b + Ce1e) + - (dQex_dVg + dQex_dVd + dQex_dVb + dQex_dVe); + here->B3SOIDDcbdb = Cbd - Ce1d + dQex_dVd; + here->B3SOIDDcbeb = Cbe - Ce1e + dQex_dVe; + here->B3SOIDDcbT = CbT - Ce1T + dQex_dT; + + here->B3SOIDDcegb = Ce1g + Ce2g - dQex_dVg; + here->B3SOIDDcesb = -(Ce1g + Ce1d + Ce1b + Ce1e) + -(Ce2g + Ce2d + Ce2b + Ce2e) + +(dQex_dVg + dQex_dVd + dQex_dVb + dQex_dVe); + here->B3SOIDDcedb = Ce1d + Ce2d - dQex_dVd; + here->B3SOIDDceeb = Ce1e + Ce2e - dQex_dVe; + here->B3SOIDDceT = Ce1T + Ce2T - dQex_dT; + + here->B3SOIDDcdgb = -(Cgg + Cbg + Csg); + here->B3SOIDDcddb = -(Cgd + Cbd + Csd); + here->B3SOIDDcdeb = -(Cge + Cbe + Cse); + here->B3SOIDDcdT = -(CgT + CbT + CsT); + here->B3SOIDDcdsb = (Cgg + Cgd + Cgb + Cge + + Cbg + Cbd + Cbb + Cbe + + Csg + Csd + Csb + Cse); + + } /* End of if capMod == 2 or capMod ==3 */ + } + + finished: /* returning Values to Calling Routine */ + /* + * COMPUTE EQUIVALENT DRAIN CURRENT SOURCE + */ + if (ChargeComputationNeeded) + { + /* Intrinsic S/D junction charge */ + PhiBSWG = model->B3SOIDDGatesidewallJctPotential; + MJSWG = model->B3SOIDDbodyJctGateSideGradingCoeff; + cjsbs = model->B3SOIDDunitLengthGateSidewallJctCap + * pParam->B3SOIDDweff * model->B3SOIDDtsi / 1e-7; + if (Vbs < 0.0) + { arg = 1.0 - Vbs / PhiBSWG; + if (MJSWG == 0.5) + dT3_dVb = 1.0 / sqrt(arg); + else + dT3_dVb = exp(-MJSWG * log(arg)); + T3 = (1.0 - arg * dT3_dVb) * PhiBSWG / (1.0 - MJSWG); + } + else + { T3 = Vbs * ( 1 + 0.5 * MJSWG * Vbs / PhiBSWG); + dT3_dVb = 1 + MJSWG * Vbs / PhiBSWG; + } + + qjs = cjsbs * T3 + model->B3SOIDDtt * Ibs1; + gcjsbs = cjsbs * dT3_dVb + model->B3SOIDDtt * dIbs1_dVb; + if (selfheat) gcjsT = model->B3SOIDDtt * dIbs1_dT; + else gcjsT = 0.0; + + if (Vbd < 0.0) + { arg = 1.0 - Vbd / PhiBSWG; + if (MJSWG == 0.5) + dT3_dVb = 1.0 / sqrt(arg); + else + dT3_dVb = exp(-MJSWG * log(arg)); + T3 = (1.0 - arg * dT3_dVb) * PhiBSWG / (1.0 - MJSWG); + } + else + { T3 = Vbd * ( 1 + 0.5 * MJSWG * Vbd / PhiBSWG); + dT3_dVb = 1 + MJSWG * Vbd / PhiBSWG; + } + dT3_dVd = - dT3_dVb; + + qjd = cjsbs * T3 + model->B3SOIDDtt * Ibd1; + gcjdbs = cjsbs * dT3_dVb + model->B3SOIDDtt * dIbd1_dVb; + gcjdds = cjsbs * dT3_dVd + model->B3SOIDDtt * dIbd1_dVd; + if (selfheat) gcjdT = model->B3SOIDDtt * dIbd1_dT; + else gcjdT = 0.0; + + qdrn -= qjd; + qbody += (qjs + qjd); + qsrc = -(qgate + qbody + qdrn + qsub); + + /* Update the conductance */ + here->B3SOIDDcddb -= gcjdds; + here->B3SOIDDcdT -= gcjdT; + here->B3SOIDDcdsb += gcjdds + gcjdbs; + + here->B3SOIDDcbdb += (gcjdds); + here->B3SOIDDcbT += (gcjdT + gcjsT); + here->B3SOIDDcbsb -= (gcjdds + gcjdbs + gcjsbs); + + /* Extrinsic Bottom S/D to substrate charge */ + T10 = -model->B3SOIDDtype * ves; + /* T10 is vse without type conversion */ + if ( ((pParam->B3SOIDDnsub > 0) && (model->B3SOIDDtype > 0)) || + ((pParam->B3SOIDDnsub < 0) && (model->B3SOIDDtype < 0)) ) + { + if (T10 < pParam->B3SOIDDvsdfb) + { here->B3SOIDDqse = here->B3SOIDDcsbox * (T10 - pParam->B3SOIDDvsdfb); + here->B3SOIDDgcse = here->B3SOIDDcsbox; + } + else if (T10 < pParam->B3SOIDDsdt1) + { T0 = T10 - pParam->B3SOIDDvsdfb; + T1 = T0 * T0; + here->B3SOIDDqse = T0 * (here->B3SOIDDcsbox - + pParam->B3SOIDDst2 / 3 * T1) ; + here->B3SOIDDgcse = here->B3SOIDDcsbox - pParam->B3SOIDDst2 * T1; + } + else if (T10 < pParam->B3SOIDDvsdth) + { T0 = T10 - pParam->B3SOIDDvsdth; + T1 = T0 * T0; + here->B3SOIDDqse = here->B3SOIDDcsmin * T10 + here->B3SOIDDst4 + + pParam->B3SOIDDst3 / 3 * T0 * T1; + here->B3SOIDDgcse = here->B3SOIDDcsmin + pParam->B3SOIDDst3 * T1; + } + else + { here->B3SOIDDqse = here->B3SOIDDcsmin * T10 + here->B3SOIDDst4; + here->B3SOIDDgcse = here->B3SOIDDcsmin; + } + } else + { + if (T10 < pParam->B3SOIDDvsdth) + { here->B3SOIDDqse = here->B3SOIDDcsmin * (T10 - pParam->B3SOIDDvsdth); + here->B3SOIDDgcse = here->B3SOIDDcsmin; + } + else if (T10 < pParam->B3SOIDDsdt1) + { T0 = T10 - pParam->B3SOIDDvsdth; + T1 = T0 * T0; + here->B3SOIDDqse = T0 * (here->B3SOIDDcsmin - pParam->B3SOIDDst2 / 3 * T1) ; + here->B3SOIDDgcse = here->B3SOIDDcsmin - pParam->B3SOIDDst2 * T1; + } + else if (T10 < pParam->B3SOIDDvsdfb) + { T0 = T10 - pParam->B3SOIDDvsdfb; + T1 = T0 * T0; + here->B3SOIDDqse = here->B3SOIDDcsbox * T10 + here->B3SOIDDst4 + + pParam->B3SOIDDst3 / 3 * T0 * T1; + here->B3SOIDDgcse = here->B3SOIDDcsbox + pParam->B3SOIDDst3 * T1; + } + else + { here->B3SOIDDqse = here->B3SOIDDcsbox * T10 + here->B3SOIDDst4; + here->B3SOIDDgcse = here->B3SOIDDcsbox; + } + } + + /* T11 is vde without type conversion */ + T11 = model->B3SOIDDtype * (vds - ves); + if ( ((pParam->B3SOIDDnsub > 0) && (model->B3SOIDDtype > 0)) || + ((pParam->B3SOIDDnsub < 0) && (model->B3SOIDDtype < 0)) ) + { + if (T11 < pParam->B3SOIDDvsdfb) + { here->B3SOIDDqde = here->B3SOIDDcdbox * (T11 - pParam->B3SOIDDvsdfb); + here->B3SOIDDgcde = here->B3SOIDDcdbox; + } + else if (T11 < pParam->B3SOIDDsdt1) + { T0 = T11 - pParam->B3SOIDDvsdfb; + T1 = T0 * T0; + here->B3SOIDDqde = T0 * (here->B3SOIDDcdbox - pParam->B3SOIDDdt2 / 3 * T1) ; + here->B3SOIDDgcde = here->B3SOIDDcdbox - pParam->B3SOIDDdt2 * T1; + } + else if (T11 < pParam->B3SOIDDvsdth) + { T0 = T11 - pParam->B3SOIDDvsdth; + T1 = T0 * T0; + here->B3SOIDDqde = here->B3SOIDDcdmin * T11 + here->B3SOIDDdt4 + + pParam->B3SOIDDdt3 / 3 * T0 * T1; + here->B3SOIDDgcde = here->B3SOIDDcdmin + pParam->B3SOIDDdt3 * T1; + } + else + { here->B3SOIDDqde = here->B3SOIDDcdmin * T11 + here->B3SOIDDdt4; + here->B3SOIDDgcde = here->B3SOIDDcdmin; + } + } else + { + if (T11 < pParam->B3SOIDDvsdth) + { here->B3SOIDDqde = here->B3SOIDDcdmin * (T11 - pParam->B3SOIDDvsdth); + here->B3SOIDDgcde = here->B3SOIDDcdmin; + } + else if (T11 < pParam->B3SOIDDsdt1) + { T0 = T11 - pParam->B3SOIDDvsdth; + T1 = T0 * T0; + here->B3SOIDDqde = T0 * (here->B3SOIDDcdmin - pParam->B3SOIDDdt2 / 3 * T1) ; + here->B3SOIDDgcde = here->B3SOIDDcdmin - pParam->B3SOIDDdt2 * T1; + } + else if (T11 < pParam->B3SOIDDvsdfb) + { T0 = T11 - pParam->B3SOIDDvsdfb; + T1 = T0 * T0; + here->B3SOIDDqde = here->B3SOIDDcdbox * T11 + here->B3SOIDDdt4 + + pParam->B3SOIDDdt3 / 3 * T0 * T1; + here->B3SOIDDgcde = here->B3SOIDDcdbox + pParam->B3SOIDDdt3 * T1; + } + else + { here->B3SOIDDqde = here->B3SOIDDcdbox * T11 + here->B3SOIDDdt4; + here->B3SOIDDgcde = here->B3SOIDDcdbox; + } + } + + /* Extrinsic : Sidewall fringing S/D charge */ + here->B3SOIDDqse += pParam->B3SOIDDcsesw * T10; + here->B3SOIDDgcse += pParam->B3SOIDDcsesw; + here->B3SOIDDqde += pParam->B3SOIDDcdesw * T11; + here->B3SOIDDgcde += pParam->B3SOIDDcdesw; + + /* All charge are mutliplied with type at the end, but qse and qde + have true polarity => so pre-mutliplied with type */ + here->B3SOIDDqse *= model->B3SOIDDtype; + here->B3SOIDDqde *= model->B3SOIDDtype; + } + + here->B3SOIDDxc = Xc; + here->B3SOIDDcbb = Cbb; + here->B3SOIDDcbd = Cbd; + here->B3SOIDDcbg = Cbg; + here->B3SOIDDqbf = Qbf; + here->B3SOIDDqjs = qjs; + here->B3SOIDDqjd = qjd; + + if (here->B3SOIDDdebugMod == -1) + ChargeComputationNeeded = 0; + + /* + * check convergence + */ + if ((here->B3SOIDDoff == 0) || (!(ckt->CKTmode & MODEINITFIX))) + { if (Check == 1) + { ckt->CKTnoncon++; +if (here->B3SOIDDdebugMod > 2) + fprintf(fpdebug, "Check is on, noncon=%d\n", ckt->CKTnoncon++); + } + } + + *(ckt->CKTstate0 + here->B3SOIDDvg) = vg; + *(ckt->CKTstate0 + here->B3SOIDDvd) = vd; + *(ckt->CKTstate0 + here->B3SOIDDvs) = vs; + *(ckt->CKTstate0 + here->B3SOIDDvp) = vp; + *(ckt->CKTstate0 + here->B3SOIDDve) = ve; + + *(ckt->CKTstate0 + here->B3SOIDDvbs) = vbs; + *(ckt->CKTstate0 + here->B3SOIDDvbd) = vbd; + *(ckt->CKTstate0 + here->B3SOIDDvgs) = vgs; + *(ckt->CKTstate0 + here->B3SOIDDvds) = vds; + *(ckt->CKTstate0 + here->B3SOIDDves) = ves; + *(ckt->CKTstate0 + here->B3SOIDDvps) = vps; + *(ckt->CKTstate0 + here->B3SOIDDdeltemp) = delTemp; + + /* bulk and channel charge plus overlaps */ + + if (!ChargeComputationNeeded) + goto line850; + + line755: + ag0 = ckt->CKTag[0]; + + T0 = vgd + DELTA_1; + T1 = sqrt(T0 * T0 + 4.0 * DELTA_1); + T2 = 0.5 * (T0 - T1); + + T3 = pParam->B3SOIDDweffCV * pParam->B3SOIDDcgdl; + T4 = sqrt(1.0 - 4.0 * T2 / pParam->B3SOIDDckappa); + cgdo = pParam->B3SOIDDcgdo + T3 - T3 * (1.0 - 1.0 / T4) + * (0.5 - 0.5 * T0 / T1); + qgdo = (pParam->B3SOIDDcgdo + T3) * vgd - T3 * (T2 + + 0.5 * pParam->B3SOIDDckappa * (T4 - 1.0)); + + T0 = vgs + DELTA_1; + T1 = sqrt(T0 * T0 + 4.0 * DELTA_1); + T2 = 0.5 * (T0 - T1); + T3 = pParam->B3SOIDDweffCV * pParam->B3SOIDDcgsl; + T4 = sqrt(1.0 - 4.0 * T2 / pParam->B3SOIDDckappa); + cgso = pParam->B3SOIDDcgso + T3 - T3 * (1.0 - 1.0 / T4) + * (0.5 - 0.5 * T0 / T1); + qgso = (pParam->B3SOIDDcgso + T3) * vgs - T3 * (T2 + + 0.5 * pParam->B3SOIDDckappa * (T4 - 1.0)); + + + if (here->B3SOIDDmode > 0) + { gcdgb = (here->B3SOIDDcdgb - cgdo) * ag0; + gcddb = (here->B3SOIDDcddb + cgdo + here->B3SOIDDgcde) * ag0; + gcdsb = here->B3SOIDDcdsb * ag0; + gcdeb = (here->B3SOIDDcdeb - here->B3SOIDDgcde) * ag0; + gcdT = model->B3SOIDDtype * here->B3SOIDDcdT * ag0; + + gcsgb = -(here->B3SOIDDcggb + here->B3SOIDDcbgb + here->B3SOIDDcdgb + + here->B3SOIDDcegb + cgso) * ag0; + gcsdb = -(here->B3SOIDDcgdb + here->B3SOIDDcbdb + here->B3SOIDDcddb + + here->B3SOIDDcedb) * ag0; + gcssb = (cgso + here->B3SOIDDgcse - (here->B3SOIDDcgsb + here->B3SOIDDcbsb + + here->B3SOIDDcdsb + here->B3SOIDDcesb)) * ag0; + gcseb = -(here->B3SOIDDgcse + here->B3SOIDDcgeb + here->B3SOIDDcbeb + here->B3SOIDDcdeb + + here->B3SOIDDceeb) * ag0; + gcsT = - model->B3SOIDDtype * (here->B3SOIDDcgT + here->B3SOIDDcbT + here->B3SOIDDcdT + + here->B3SOIDDceT) * ag0; + + gcggb = (here->B3SOIDDcggb + cgdo + cgso + pParam->B3SOIDDcgeo) * ag0; + gcgdb = (here->B3SOIDDcgdb - cgdo) * ag0; + gcgsb = (here->B3SOIDDcgsb - cgso) * ag0; + gcgeb = (here->B3SOIDDcgeb - pParam->B3SOIDDcgeo) * ag0; + gcgT = model->B3SOIDDtype * here->B3SOIDDcgT * ag0; + + gcbgb = here->B3SOIDDcbgb * ag0; + gcbdb = here->B3SOIDDcbdb * ag0; + gcbsb = here->B3SOIDDcbsb * ag0; + gcbeb = here->B3SOIDDcbeb * ag0; + gcbT = model->B3SOIDDtype * here->B3SOIDDcbT * ag0; + + gcegb = (here->B3SOIDDcegb - pParam->B3SOIDDcgeo) * ag0; + gcedb = (here->B3SOIDDcedb - here->B3SOIDDgcde) * ag0; + gcesb = (here->B3SOIDDcesb - here->B3SOIDDgcse) * ag0; + gceeb = (here->B3SOIDDgcse + here->B3SOIDDgcde + + here->B3SOIDDceeb + pParam->B3SOIDDcgeo) * ag0; + + gceT = model->B3SOIDDtype * here->B3SOIDDceT * ag0; + + gcTt = pParam->B3SOIDDcth * ag0; + + sxpart = 0.6; + dxpart = 0.4; + + /* Lump the overlap capacitance and S/D parasitics */ + qgd = qgdo; + qgs = qgso; + qge = pParam->B3SOIDDcgeo * vge; + qgate += qgd + qgs + qge; + qdrn += here->B3SOIDDqde - qgd; + qsub -= qge + here->B3SOIDDqse + here->B3SOIDDqde; + qsrc = -(qgate + qbody + qdrn + qsub); + } + else + { gcsgb = (here->B3SOIDDcdgb - cgso) * ag0; + gcssb = (here->B3SOIDDcddb + cgso + here->B3SOIDDgcse) * ag0; + gcsdb = here->B3SOIDDcdsb * ag0; + gcseb = (here->B3SOIDDcdeb - here->B3SOIDDgcse) * ag0; + gcsT = model->B3SOIDDtype * here->B3SOIDDcdT * ag0; + + gcdgb = -(here->B3SOIDDcggb + here->B3SOIDDcbgb + here->B3SOIDDcdgb + + here->B3SOIDDcegb + cgdo) * ag0; + gcdsb = -(here->B3SOIDDcgdb + here->B3SOIDDcbdb + here->B3SOIDDcddb + + here->B3SOIDDcedb) * ag0; + gcddb = (cgdo + here->B3SOIDDgcde - (here->B3SOIDDcgsb + here->B3SOIDDcbsb + + here->B3SOIDDcdsb + here->B3SOIDDcesb)) * ag0; + gcdeb = -(here->B3SOIDDgcde + here->B3SOIDDcgeb + here->B3SOIDDcbeb + here->B3SOIDDcdeb + + here->B3SOIDDceeb) * ag0; + gcdT = - model->B3SOIDDtype * (here->B3SOIDDcgT + here->B3SOIDDcbT + + here->B3SOIDDcdT + here->B3SOIDDceT) * ag0; + + gcggb = (here->B3SOIDDcggb + cgdo + cgso + pParam->B3SOIDDcgeo) * ag0; + gcgsb = (here->B3SOIDDcgdb - cgso) * ag0; + gcgdb = (here->B3SOIDDcgsb - cgdo) * ag0; + gcgeb = (here->B3SOIDDcgeb - pParam->B3SOIDDcgeo) * ag0; + gcgT = model->B3SOIDDtype * here->B3SOIDDcgT * ag0; + + gcbgb = here->B3SOIDDcbgb * ag0; + gcbsb = here->B3SOIDDcbdb * ag0; + gcbdb = here->B3SOIDDcbsb * ag0; + gcbeb = here->B3SOIDDcbeb * ag0; + gcbT = model->B3SOIDDtype * here->B3SOIDDcbT * ag0; + + gcegb = (here->B3SOIDDcegb - pParam->B3SOIDDcgeo) * ag0; + gcesb = (here->B3SOIDDcedb - here->B3SOIDDgcse) * ag0; + gcedb = (here->B3SOIDDcesb - here->B3SOIDDgcde) * ag0; + gceeb = (here->B3SOIDDceeb + pParam->B3SOIDDcgeo + + here->B3SOIDDgcse + here->B3SOIDDgcde) * ag0; + gceT = model->B3SOIDDtype * here->B3SOIDDceT * ag0; + + gcTt = pParam->B3SOIDDcth * ag0; + + dxpart = 0.6; + sxpart = 0.4; + + /* Lump the overlap capacitance */ + qgd = qgdo; + qgs = qgso; + qge = pParam->B3SOIDDcgeo * vge; + qgate += qgd + qgs + qge; + qsrc = qdrn - qgs + here->B3SOIDDqse; + qsub -= qge + here->B3SOIDDqse + here->B3SOIDDqde; + qdrn = -(qgate + qbody + qsrc + qsub); + } + + here->B3SOIDDcgdo = cgdo; + here->B3SOIDDcgso = cgso; + + if (ByPass) goto line860; + + *(ckt->CKTstate0 + here->B3SOIDDqe) = qsub; + *(ckt->CKTstate0 + here->B3SOIDDqg) = qgate; + *(ckt->CKTstate0 + here->B3SOIDDqd) = qdrn; + *(ckt->CKTstate0 + here->B3SOIDDqb) = qbody; + if ((model->B3SOIDDshMod == 1) && (here->B3SOIDDrth0!=0.0)) + *(ckt->CKTstate0 + here->B3SOIDDqth) = pParam->B3SOIDDcth * delTemp; + + + /* store small signal parameters */ + if (ckt->CKTmode & MODEINITSMSIG) + { goto line1000; + } + if (!ChargeComputationNeeded) + goto line850; + + + if (ckt->CKTmode & MODEINITTRAN) + { *(ckt->CKTstate1 + here->B3SOIDDqb) = + *(ckt->CKTstate0 + here->B3SOIDDqb); + *(ckt->CKTstate1 + here->B3SOIDDqg) = + *(ckt->CKTstate0 + here->B3SOIDDqg); + *(ckt->CKTstate1 + here->B3SOIDDqd) = + *(ckt->CKTstate0 + here->B3SOIDDqd); + *(ckt->CKTstate1 + here->B3SOIDDqe) = + *(ckt->CKTstate0 + here->B3SOIDDqe); + *(ckt->CKTstate1 + here->B3SOIDDqth) = + *(ckt->CKTstate0 + here->B3SOIDDqth); + } + + error = NIintegrate(ckt, &geq, &ceq,0.0,here->B3SOIDDqb); + if (error) return(error); + error = NIintegrate(ckt, &geq, &ceq, 0.0, here->B3SOIDDqg); + if (error) return(error); + error = NIintegrate(ckt,&geq, &ceq, 0.0, here->B3SOIDDqd); + if (error) return(error); + error = NIintegrate(ckt,&geq, &ceq, 0.0, here->B3SOIDDqe); + if (error) return(error); + if ((model->B3SOIDDshMod == 1) && (here->B3SOIDDrth0!=0.0)) + { + error = NIintegrate(ckt, &geq, &ceq, 0.0, here->B3SOIDDqth); + if (error) return (error); + } + + goto line860; + + line850: + /* initialize to zero charge conductance and current */ + ceqqe = ceqqg = ceqqb = ceqqd = ceqqth= 0.0; + + gcdgb = gcddb = gcdsb = gcdeb = gcdT = 0.0; + gcsgb = gcsdb = gcssb = gcseb = gcsT = 0.0; + gcggb = gcgdb = gcgsb = gcgeb = gcgT = 0.0; + gcbgb = gcbdb = gcbsb = gcbeb = gcbT = 0.0; + gcegb = gcedb = gceeb = gcesb = gceT = 0.0; + gcTt = 0.0; + + sxpart = (1.0 - (dxpart = (here->B3SOIDDmode > 0) ? 0.4 : 0.6)); + + goto line900; + + line860: + /* evaluate equivalent charge current */ + + cqgate = *(ckt->CKTstate0 + here->B3SOIDDcqg); + cqbody = *(ckt->CKTstate0 + here->B3SOIDDcqb); + cqdrn = *(ckt->CKTstate0 + here->B3SOIDDcqd); + cqsub = *(ckt->CKTstate0 + here->B3SOIDDcqe); + cqtemp = *(ckt->CKTstate0 + here->B3SOIDDcqth); + + here->B3SOIDDcb += cqbody; + here->B3SOIDDcd += cqdrn; + + ceqqg = cqgate - gcggb * vgb + gcgdb * vbd + gcgsb * vbs + - gcgeb * veb - gcgT * delTemp; + ceqqb = cqbody - gcbgb * vgb + gcbdb * vbd + gcbsb * vbs + - gcbeb * veb - gcbT * delTemp; + ceqqd = cqdrn - gcdgb * vgb + gcddb * vbd + gcdsb * vbs + - gcdeb * veb - gcdT * delTemp; + ceqqe = cqsub - gcegb * vgb + gcedb * vbd + gcesb * vbs + - gceeb * veb - gceT * delTemp;; + ceqqth = cqtemp - gcTt * delTemp; + + if (ckt->CKTmode & MODEINITTRAN) + { *(ckt->CKTstate1 + here->B3SOIDDcqe) = + *(ckt->CKTstate0 + here->B3SOIDDcqe); + *(ckt->CKTstate1 + here->B3SOIDDcqb) = + *(ckt->CKTstate0 + here->B3SOIDDcqb); + *(ckt->CKTstate1 + here->B3SOIDDcqg) = + *(ckt->CKTstate0 + here->B3SOIDDcqg); + *(ckt->CKTstate1 + here->B3SOIDDcqd) = + *(ckt->CKTstate0 + here->B3SOIDDcqd); + *(ckt->CKTstate1 + here->B3SOIDDcqth) = + *(ckt->CKTstate0 + here->B3SOIDDcqth); + } + + /* + * load current vector + */ + line900: + + if (here->B3SOIDDmode >= 0) + { Gm = here->B3SOIDDgm; + Gmbs = here->B3SOIDDgmbs; + Gme = here->B3SOIDDgme; + GmT = model->B3SOIDDtype * here->B3SOIDDgmT; + FwdSum = Gm + Gmbs + Gme; + RevSum = 0.0; + cdreq = model->B3SOIDDtype * (here->B3SOIDDcdrain - here->B3SOIDDgds * vds + - Gm * vgs - Gmbs * vbs - Gme * ves - GmT * delTemp); + /* ceqbs now is compatible with cdreq, ie. going in is +ve */ + /* Equivalent current source from the diode */ + ceqbs = here->B3SOIDDcjs; + ceqbd = here->B3SOIDDcjd; + /* Current going in is +ve */ + ceqbody = -here->B3SOIDDcbody; + ceqth = here->B3SOIDDcth; + ceqbodcon = here->B3SOIDDcbodcon; + + gbbg = -here->B3SOIDDgbgs; + gbbdp = -here->B3SOIDDgbds; + gbbb = -here->B3SOIDDgbbs; + gbbe = -here->B3SOIDDgbes; + gbbp = -here->B3SOIDDgbps; + gbbT = -model->B3SOIDDtype * here->B3SOIDDgbT; + gbbsp = - ( gbbg + gbbdp + gbbb + gbbe + gbbp); + + gddpg = -here->B3SOIDDgjdg; + gddpdp = -here->B3SOIDDgjdd; + gddpb = -here->B3SOIDDgjdb; + gddpe = -here->B3SOIDDgjde; + gddpT = -model->B3SOIDDtype * here->B3SOIDDgjdT; + gddpsp = - ( gddpg + gddpdp + gddpb + gddpe); + + gsspg = -here->B3SOIDDgjsg; + gsspdp = -here->B3SOIDDgjsd; + gsspb = -here->B3SOIDDgjsb; + gsspe = 0.0; + gsspT = -model->B3SOIDDtype * here->B3SOIDDgjsT; + gsspsp = - (gsspg + gsspdp + gsspb + gsspe); + + gppg = -here->B3SOIDDgbpgs; + gppdp = -here->B3SOIDDgbpds; + gppb = -here->B3SOIDDgbpbs; + gppe = -here->B3SOIDDgbpes; + gppp = -here->B3SOIDDgbpps; + gppT = -model->B3SOIDDtype * here->B3SOIDDgbpT; + gppsp = - (gppg + gppdp + gppb + gppe + gppp); + + gTtg = here->B3SOIDDgtempg; + gTtb = here->B3SOIDDgtempb; + gTte = here->B3SOIDDgtempe; + gTtdp = here->B3SOIDDgtempd; + gTtt = here->B3SOIDDgtempT; + gTtsp = - (gTtg + gTtb + gTte + gTtdp); + } + else + { Gm = -here->B3SOIDDgm; + Gmbs = -here->B3SOIDDgmbs; + Gme = -here->B3SOIDDgme; + GmT = -model->B3SOIDDtype * here->B3SOIDDgmT; + FwdSum = 0.0; + RevSum = -(Gm + Gmbs + Gme); + cdreq = -model->B3SOIDDtype * (here->B3SOIDDcdrain + here->B3SOIDDgds*vds + + Gm * vgd + Gmbs * vbd + Gme * (ves - vds) + GmT * delTemp); + ceqbs = here->B3SOIDDcjd; + ceqbd = here->B3SOIDDcjs; + /* Current going in is +ve */ + ceqbody = -here->B3SOIDDcbody; + ceqth = here->B3SOIDDcth; + ceqbodcon = here->B3SOIDDcbodcon; + + gbbg = -here->B3SOIDDgbgs; + gbbb = -here->B3SOIDDgbbs; + gbbe = -here->B3SOIDDgbes; + gbbp = -here->B3SOIDDgbps; + gbbsp = -here->B3SOIDDgbds; + gbbT = -model->B3SOIDDtype * here->B3SOIDDgbT; + gbbdp = - ( gbbg + gbbsp + gbbb + gbbe + gbbp); + + gddpg = -here->B3SOIDDgjsg; + gddpsp = -here->B3SOIDDgjsd; + gddpb = -here->B3SOIDDgjsb; + gddpe = 0.0; + gddpT = -model->B3SOIDDtype * here->B3SOIDDgjsT; + gddpdp = - (gddpg + gddpsp + gddpb + gddpe); + + gsspg = -here->B3SOIDDgjdg; + gsspsp = -here->B3SOIDDgjdd; + gsspb = -here->B3SOIDDgjdb; + gsspe = -here->B3SOIDDgjde; + gsspT = -model->B3SOIDDtype * here->B3SOIDDgjdT; + gsspdp = - ( gsspg + gsspsp + gsspb + gsspe); + + gppg = -here->B3SOIDDgbpgs; + gppsp = -here->B3SOIDDgbpds; + gppb = -here->B3SOIDDgbpbs; + gppe = -here->B3SOIDDgbpes; + gppp = -here->B3SOIDDgbpps; + gppT = -model->B3SOIDDtype * here->B3SOIDDgbpT; + gppdp = - (gppg + gppsp + gppb + gppe + gppp); + + gTtg = here->B3SOIDDgtempg; + gTtb = here->B3SOIDDgtempb; + gTte = here->B3SOIDDgtempe; + gTtsp = here->B3SOIDDgtempd; + gTtt = here->B3SOIDDgtempT; + gTtdp = - (gTtg + gTtb + gTte + gTtsp); + } + + if (model->B3SOIDDtype > 0) + { + ceqqg = ceqqg; + ceqqb = ceqqb; + ceqqe = ceqqe; + ceqqd = ceqqd; + } + else + { + ceqbodcon = -ceqbodcon; + ceqbody = -ceqbody; + ceqbs = -ceqbs; + ceqbd = -ceqbd; + ceqqg = -ceqqg; + ceqqb = -ceqqb; + ceqqd = -ceqqd; + ceqqe = -ceqqe; + } + + (*(ckt->CKTrhs + here->B3SOIDDbNode) -=(ceqbody+ceqqb)); + + (*(ckt->CKTrhs + here->B3SOIDDgNode) -= ceqqg); + (*(ckt->CKTrhs + here->B3SOIDDdNodePrime) += (ceqbd - cdreq - ceqqd)); + (*(ckt->CKTrhs + here->B3SOIDDsNodePrime) += (cdreq + ceqbs + ceqqg + + ceqqb + ceqqd + ceqqe)); + (*(ckt->CKTrhs + here->B3SOIDDeNode) -= ceqqe); + + if (here->B3SOIDDbodyMod == 1) { + (*(ckt->CKTrhs + here->B3SOIDDpNode) += ceqbodcon); + } + + if (selfheat) { + (*(ckt->CKTrhs + here->B3SOIDDtempNode) -= ceqth + ceqqth); + } + + + + if ((here->B3SOIDDdebugMod > 1) || (here->B3SOIDDdebugMod == -1)) + { + *(ckt->CKTrhs + here->B3SOIDDvbsNode) = here->B3SOIDDvbsdio; + *(ckt->CKTrhs + here->B3SOIDDidsNode) = here->B3SOIDDids; + *(ckt->CKTrhs + here->B3SOIDDicNode) = here->B3SOIDDic; + *(ckt->CKTrhs + here->B3SOIDDibsNode) = here->B3SOIDDibs; + *(ckt->CKTrhs + here->B3SOIDDibdNode) = here->B3SOIDDibd; + *(ckt->CKTrhs + here->B3SOIDDiiiNode) = here->B3SOIDDiii; + *(ckt->CKTrhs + here->B3SOIDDigidlNode) = here->B3SOIDDigidl; + *(ckt->CKTrhs + here->B3SOIDDitunNode) = here->B3SOIDDitun; + *(ckt->CKTrhs + here->B3SOIDDibpNode) = here->B3SOIDDibp; + *(ckt->CKTrhs + here->B3SOIDDabeffNode) = here->B3SOIDDabeff; + *(ckt->CKTrhs + here->B3SOIDDvbs0effNode) = here->B3SOIDDvbs0eff; + *(ckt->CKTrhs + here->B3SOIDDvbseffNode) = here->B3SOIDDvbseff; + *(ckt->CKTrhs + here->B3SOIDDxcNode) = here->B3SOIDDxc; + *(ckt->CKTrhs + here->B3SOIDDcbbNode) = here->B3SOIDDcbb; + *(ckt->CKTrhs + here->B3SOIDDcbdNode) = here->B3SOIDDcbd; + *(ckt->CKTrhs + here->B3SOIDDcbgNode) = here->B3SOIDDcbg; + *(ckt->CKTrhs + here->B3SOIDDqbfNode) = here->B3SOIDDqbf; + *(ckt->CKTrhs + here->B3SOIDDqjsNode) = here->B3SOIDDqjs; + *(ckt->CKTrhs + here->B3SOIDDqjdNode) = here->B3SOIDDqjd; + + /* clean up last */ + *(ckt->CKTrhs + here->B3SOIDDgmNode) = Gm; + *(ckt->CKTrhs + here->B3SOIDDgmbsNode) = Gmbs; + *(ckt->CKTrhs + here->B3SOIDDgdsNode) = Gds; + *(ckt->CKTrhs + here->B3SOIDDgmeNode) = Gme; + *(ckt->CKTrhs + here->B3SOIDDqdNode) = qdrn; + *(ckt->CKTrhs + here->B3SOIDDcbeNode) = Cbe; + *(ckt->CKTrhs + here->B3SOIDDvbs0teffNode) = Vbs0teff; + *(ckt->CKTrhs + here->B3SOIDDvthNode) = here->B3SOIDDvon; + *(ckt->CKTrhs + here->B3SOIDDvgsteffNode) = Vgsteff; + *(ckt->CKTrhs + here->B3SOIDDxcsatNode) = Xcsat; + *(ckt->CKTrhs + here->B3SOIDDqaccNode) = -Qac0; + *(ckt->CKTrhs + here->B3SOIDDqsub0Node) = Qsub0; + *(ckt->CKTrhs + here->B3SOIDDqsubs1Node) = Qsubs1; + *(ckt->CKTrhs + here->B3SOIDDqsubs2Node) = Qsubs2; + *(ckt->CKTrhs + here->B3SOIDDvdscvNode) = VdsCV; + *(ckt->CKTrhs + here->B3SOIDDvcscvNode) = VcsCV; + *(ckt->CKTrhs + here->B3SOIDDqgNode) = qgate; + *(ckt->CKTrhs + here->B3SOIDDqbNode) = qbody; + *(ckt->CKTrhs + here->B3SOIDDqeNode) = qsub; + *(ckt->CKTrhs + here->B3SOIDDdum1Node) = here->B3SOIDDdum1; + *(ckt->CKTrhs + here->B3SOIDDdum2Node) = here->B3SOIDDdum2; + *(ckt->CKTrhs + here->B3SOIDDdum3Node) = here->B3SOIDDdum3; + *(ckt->CKTrhs + here->B3SOIDDdum4Node) = here->B3SOIDDdum4; + *(ckt->CKTrhs + here->B3SOIDDdum5Node) = here->B3SOIDDdum5; + /* end clean up last */ + } + + + /* + * load y matrix + */ + (*(here->B3SOIDDEgPtr) += gcegb); + (*(here->B3SOIDDEdpPtr) += gcedb); + (*(here->B3SOIDDEspPtr) += gcesb); + (*(here->B3SOIDDGePtr) += gcgeb); + (*(here->B3SOIDDDPePtr) += Gme + gddpe + gcdeb); + (*(here->B3SOIDDSPePtr) += gsspe - Gme + gcseb); + + Gmin = ckt->CKTgmin * 1e-6; + (*(here->B3SOIDDEbPtr) -= gcegb + gcedb + gcesb + gceeb); + (*(here->B3SOIDDGbPtr) -= gcggb + gcgdb + gcgsb + gcgeb); + (*(here->B3SOIDDDPbPtr) -= (-gddpb - Gmbs + gcdgb + gcddb + gcdeb + gcdsb)); + (*(here->B3SOIDDSPbPtr) -= (-gsspb + Gmbs + gcsgb + gcsdb + gcseb + gcssb)); + (*(here->B3SOIDDBePtr) += gbbe + gcbeb); + (*(here->B3SOIDDBgPtr) += gcbgb + gbbg); + (*(here->B3SOIDDBdpPtr) += gcbdb + gbbdp ); + (*(here->B3SOIDDBspPtr) += gcbsb + gbbsp - Gmin); + (*(here->B3SOIDDBbPtr) += gbbb - gcbgb - gcbdb - gcbsb - gcbeb + Gmin) ; + + (*(here->B3SOIDDEePtr) += gceeb); + + (*(here->B3SOIDDGgPtr) += gcggb + ckt->CKTgmin); + (*(here->B3SOIDDGdpPtr) += gcgdb - ckt->CKTgmin); + (*(here->B3SOIDDGspPtr) += gcgsb ); + + (*(here->B3SOIDDDPgPtr) += (Gm + gcdgb) + gddpg - ckt->CKTgmin); + (*(here->B3SOIDDDPdpPtr) += (here->B3SOIDDdrainConductance + + here->B3SOIDDgds + gddpdp + + RevSum + gcddb) + ckt->CKTgmin); + (*(here->B3SOIDDDPspPtr) -= (-gddpsp + here->B3SOIDDgds + FwdSum - gcdsb)); + + (*(here->B3SOIDDDPdPtr) -= here->B3SOIDDdrainConductance); + + (*(here->B3SOIDDSPgPtr) += gcsgb - Gm + gsspg ); + (*(here->B3SOIDDSPdpPtr) -= (here->B3SOIDDgds - gsspdp + RevSum - gcsdb)); + (*(here->B3SOIDDSPspPtr) += (here->B3SOIDDsourceConductance + + here->B3SOIDDgds + gsspsp + + FwdSum + gcssb)); + (*(here->B3SOIDDSPsPtr) -= here->B3SOIDDsourceConductance); + + + (*(here->B3SOIDDDdPtr) += here->B3SOIDDdrainConductance); + (*(here->B3SOIDDDdpPtr) -= here->B3SOIDDdrainConductance); + + + (*(here->B3SOIDDSsPtr) += here->B3SOIDDsourceConductance); + (*(here->B3SOIDDSspPtr) -= here->B3SOIDDsourceConductance); + + if (here->B3SOIDDbodyMod == 1) { + (*(here->B3SOIDDBpPtr) -= gppp); + (*(here->B3SOIDDPbPtr) += gppb); + (*(here->B3SOIDDPpPtr) += gppp); + (*(here->B3SOIDDPgPtr) += gppg); + (*(here->B3SOIDDPdpPtr) += gppdp); + (*(here->B3SOIDDPspPtr) += gppsp); + (*(here->B3SOIDDPePtr) += gppe); + } + + if (selfheat) + { + (*(here->B3SOIDDDPtempPtr) += GmT + gddpT + gcdT); + (*(here->B3SOIDDSPtempPtr) += -GmT + gsspT + gcsT); + (*(here->B3SOIDDBtempPtr) += gbbT + gcbT); + (*(here->B3SOIDDEtempPtr) += gceT); + (*(here->B3SOIDDGtempPtr) += gcgT); + if (here->B3SOIDDbodyMod == 1) { + (*(here->B3SOIDDPtempPtr) += gppT); + } + (*(here->B3SOIDDTemptempPtr) += gTtt + 1/pParam->B3SOIDDrth + gcTt); + (*(here->B3SOIDDTempgPtr) += gTtg); + (*(here->B3SOIDDTempbPtr) += gTtb); + (*(here->B3SOIDDTempePtr) += gTte); + (*(here->B3SOIDDTempdpPtr) += gTtdp); + (*(here->B3SOIDDTempspPtr) += gTtsp); + } + + if ((here->B3SOIDDdebugMod > 1) || (here->B3SOIDDdebugMod == -1)) + { + *(here->B3SOIDDVbsPtr) += 1; + *(here->B3SOIDDIdsPtr) += 1; + *(here->B3SOIDDIcPtr) += 1; + *(here->B3SOIDDIbsPtr) += 1; + *(here->B3SOIDDIbdPtr) += 1; + *(here->B3SOIDDIiiPtr) += 1; + *(here->B3SOIDDIgidlPtr) += 1; + *(here->B3SOIDDItunPtr) += 1; + *(here->B3SOIDDIbpPtr) += 1; + *(here->B3SOIDDAbeffPtr) += 1; + *(here->B3SOIDDVbs0effPtr) += 1; + *(here->B3SOIDDVbseffPtr) += 1; + *(here->B3SOIDDXcPtr) += 1; + *(here->B3SOIDDCbgPtr) += 1; + *(here->B3SOIDDCbbPtr) += 1; + *(here->B3SOIDDCbdPtr) += 1; + *(here->B3SOIDDqbPtr) += 1; + *(here->B3SOIDDQbfPtr) += 1; + *(here->B3SOIDDQjsPtr) += 1; + *(here->B3SOIDDQjdPtr) += 1; + + /* clean up last */ + *(here->B3SOIDDGmPtr) += 1; + *(here->B3SOIDDGmbsPtr) += 1; + *(here->B3SOIDDGdsPtr) += 1; + *(here->B3SOIDDGmePtr) += 1; + *(here->B3SOIDDVbs0teffPtr) += 1; + *(here->B3SOIDDVgsteffPtr) += 1; + *(here->B3SOIDDCbePtr) += 1; + *(here->B3SOIDDVthPtr) += 1; + *(here->B3SOIDDXcsatPtr) += 1; + *(here->B3SOIDDVdscvPtr) += 1; + *(here->B3SOIDDVcscvPtr) += 1; + *(here->B3SOIDDQaccPtr) += 1; + *(here->B3SOIDDQsub0Ptr) += 1; + *(here->B3SOIDDQsubs1Ptr) += 1; + *(here->B3SOIDDQsubs2Ptr) += 1; + *(here->B3SOIDDqgPtr) += 1; + *(here->B3SOIDDqdPtr) += 1; + *(here->B3SOIDDqePtr) += 1; + *(here->B3SOIDDDum1Ptr) += 1; + *(here->B3SOIDDDum2Ptr) += 1; + *(here->B3SOIDDDum3Ptr) += 1; + *(here->B3SOIDDDum4Ptr) += 1; + *(here->B3SOIDDDum5Ptr) += 1; + /* end clean up last */ + } + + line1000: ; + +/* Here NaN will be detected in any conductance or equivalent current. Note + that nandetect is initialized within the "if" statements */ + + if (nandetect = isnan (*(here->B3SOIDDGbPtr))) + { strcpy (nanmessage, "GbPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDEbPtr))) + { strcpy (nanmessage, "EbPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDDPbPtr))) + { strcpy (nanmessage, "DPbPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDSPbPtr))) + { strcpy (nanmessage, "SPbPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDBbPtr))) + { strcpy (nanmessage, "BbPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDBgPtr))) + { strcpy (nanmessage, "BgPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDBePtr))) + { strcpy (nanmessage, "BePtr"); } + else if (nandetect = isnan (*(here->B3SOIDDBdpPtr))) + { strcpy (nanmessage, "BdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDBspPtr))) + { strcpy (nanmessage, "BspPtr"); } + + if (nandetect = isnan (*(here->B3SOIDDGgPtr))) + { strcpy (nanmessage, "GgPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDGdpPtr))) + { strcpy (nanmessage, "GdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDGspPtr))) + { strcpy (nanmessage, "GspPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDDPgPtr))) + { strcpy (nanmessage, "DPgPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDDPdpPtr))) + { strcpy (nanmessage, "DPdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDDPspPtr))) + { strcpy (nanmessage, "DPspPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDSPgPtr))) + { strcpy (nanmessage, "SPgPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDSPdpPtr))) + { strcpy (nanmessage, "SPdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDSPspPtr))) + { strcpy (nanmessage, "SPspPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDEePtr))) + { strcpy (nanmessage, "EePtr"); } + + /* At this point, nandetect = 0 if none of the + conductances checked so far are NaN */ + + if (nandetect == 0) + { + if (nandetect = isnan (*(here->B3SOIDDEgPtr))) + { strcpy (nanmessage, "EgPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDEdpPtr))) + { strcpy (nanmessage, "EdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDEspPtr))) + { strcpy (nanmessage, "EspPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDGePtr))) + { strcpy (nanmessage, "GePtr"); } + else if (nandetect = isnan (*(here->B3SOIDDDPePtr))) + { strcpy (nanmessage, "DPePtr"); } + else if (nandetect = isnan (*(here->B3SOIDDSPePtr))) + { strcpy (nanmessage, "SPePtr"); } } + + /* Now check if self-heating caused NaN if nothing else + has so far (check tempnode current also) */ + + if (selfheat && nandetect == 0) + { + if (nandetect = isnan (*(here->B3SOIDDTemptempPtr))) + { strcpy (nanmessage, "TemptempPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDTempgPtr))) + { strcpy (nanmessage, "TempgPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDTempbPtr))) + { strcpy (nanmessage, "TempbPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDTempePtr))) + { strcpy (nanmessage, "TempePtr"); } + else if (nandetect = isnan (*(here->B3SOIDDTempdpPtr))) + { strcpy (nanmessage, "TempdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDTempspPtr))) + { strcpy (nanmessage, "TempspPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDGtempPtr))) + { strcpy (nanmessage, "GtempPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDDPtempPtr))) + { strcpy (nanmessage, "DPtempPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDSPtempPtr))) + { strcpy (nanmessage, "SPtempPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDEtempPtr))) + { strcpy (nanmessage, "EtempPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDBtempPtr))) + { strcpy (nanmessage, "BtempPtr"); } + else if (nandetect = isnan (*(ckt->CKTrhs + here->B3SOIDDtempNode))) + { strcpy (nanmessage, "tempNode"); } + } + + /* Lastly, check all equivalent currents (tempnode is + checked above */ + + if (nandetect == 0) + { + if (nandetect = isnan (*(ckt->CKTrhs + + here->B3SOIDDgNode))) + { strcpy (nanmessage, "gNode"); } + else if (nandetect = isnan (*(ckt->CKTrhs + + here->B3SOIDDbNode))) + { strcpy (nanmessage, "bNode"); } + else if (nandetect = isnan (*(ckt->CKTrhs + + here->B3SOIDDdNodePrime))) + { strcpy (nanmessage, "dpNode"); } + else if (nandetect = isnan (*(ckt->CKTrhs + + here->B3SOIDDsNodePrime))) + { strcpy (nanmessage, "spNode"); } + else if (nandetect = isnan (*(ckt->CKTrhs + + here->B3SOIDDeNode))) + { strcpy (nanmessage, "eNode"); } + } + + /* Now print error message if NaN detected. Note that + error will only be printed once (the first time it is + encountered) each time SPICE is run since nanfound is + static variable */ + + if (nanfound == 0 && nandetect) + { + fprintf(stderr, "Alberto says: YOU TURKEY! %s is NaN for instance %s at time %g!\n", nanmessage, here->B3SOIDDname, ckt->CKTtime); + nanfound = nandetect; + fprintf(stderr, " The program exit!\n"); + exit(-1); + } + + if (here->B3SOIDDdebugMod > 2) + { + fprintf(fpdebug, "Ids = %.4e, Ic = %.4e, cqdrn = %.4e, gmin=%.3e\n", + Ids, Ic, cqdrn, ckt->CKTgmin); + fprintf(fpdebug, "Iii = %.4e, Idgidl = %.4e, Ibs = %.14e\n", + Iii, Idgidl, Ibs); + fprintf(fpdebug, "Ibd = %.4e, Ibp = %.4e\n", Ibd, Ibp); + fprintf(fpdebug, "qbody = %.5e, qbf = %.5e, qbe = %.5e\n", + qbody, Qbf, -(Qe1+Qe2)); + fprintf(fpdebug, "qbs = %.5e, qbd = %.5e\n", qjs, qjd); + fprintf(fpdebug, "qdrn = %.5e, qinv = %.5e\n", qdrn, qinv); + + + + +/* I am trying to debug the convergence problems here by printing out + the entire Jacobian and equivalent current matrix */ + + + if (here->B3SOIDDdebugMod > 4) { + fprintf(fpdebug, "Ibtot = %.6e;\t Cbtot = %.6e;\n", Ibs+Ibp+Ibd-Iii-Idgidl-Isgidl, cqbody); + fprintf(fpdebug, "ceqg = %.6e;\t ceqb = %.6e;\t ceqdp = %.6e;\t ceqsp = %.6e;\n", + *(ckt->CKTrhs + here->B3SOIDDgNode), + *(ckt->CKTrhs + here->B3SOIDDbNode), + *(ckt->CKTrhs + here->B3SOIDDdNodePrime), + *(ckt->CKTrhs + here->B3SOIDDsNodePrime)); + fprintf(fpdebug, "ceqe = %.6e;\t ceqp = %.6e;\t ceqth = %.6e;\n", + *(ckt->CKTrhs + here->B3SOIDDeNode), + *(ckt->CKTrhs + here->B3SOIDDpNode), + *(ckt->CKTrhs + here->B3SOIDDtempNode)); + + fprintf(fpdebug, "Eg = %.5e;\t Edp = %.5e;\t Esp = %.5e;\t Eb = %.5e;\n", + *(here->B3SOIDDEgPtr), *(here->B3SOIDDEdpPtr), *(here->B3SOIDDEspPtr), + *(here->B3SOIDDEbPtr)); + fprintf(fpdebug, "Ee = %.5e;\t Gg = %.5e;\t Gdp = %.5e;\t Gsp = %.5e;\n", + *(here->B3SOIDDEePtr), + *(here->B3SOIDDGgPtr), + *(here->B3SOIDDGdpPtr), + *(here->B3SOIDDGspPtr)); + fprintf(fpdebug, "Gb = %.5e;\t Ge = %.5e;\t DPg = %.5e;\t DPdp = %.5e;\n", + *(here->B3SOIDDGbPtr), + *(here->B3SOIDDGePtr), + *(here->B3SOIDDDPgPtr), + *(here->B3SOIDDDPdpPtr)); + fprintf(fpdebug, "DPsp = %.5e;\t DPb = %.5e;\t DPe = %.5e;\t\n", + *(here->B3SOIDDDPspPtr), + *(here->B3SOIDDDPbPtr), + *(here->B3SOIDDDPePtr)); + fprintf(fpdebug, "DPd = %.5e;\t SPg = %.5e;\t SPdp = %.5e;\t SPsp = %.5e;\n", + *(here->B3SOIDDDPdPtr), + *(here->B3SOIDDSPgPtr), + *(here->B3SOIDDSPdpPtr), + *(here->B3SOIDDSPspPtr)); + fprintf(fpdebug, "SPb = %.5e;\t SPe = %.5e;\t SPs = %.5e;\n", + *(here->B3SOIDDSPbPtr), + *(here->B3SOIDDSPePtr), + *(here->B3SOIDDSPsPtr)); + fprintf(fpdebug, "Dd = %.5e;\t Ddp = %.5e;\t Ss = %.5e;\t Ssp = %.5e;\n", + *(here->B3SOIDDDdPtr), + *(here->B3SOIDDDdpPtr), + *(here->B3SOIDDSsPtr), + *(here->B3SOIDDSspPtr)); + fprintf(fpdebug, "Bg = %.5e;\t Bdp = %.5e;\t Bsp = %.5e;\t Bb = %.5e;\n", + *(here->B3SOIDDBgPtr), + *(here->B3SOIDDBdpPtr), + *(here->B3SOIDDBspPtr), + *(here->B3SOIDDBbPtr)); + fprintf(fpdebug, "Be = %.5e;\t Btot = %.5e;\t DPtot = %.5e;\n", + *(here->B3SOIDDBePtr), + *(here->B3SOIDDBgPtr) + *(here->B3SOIDDBdpPtr) + + *(here->B3SOIDDBspPtr) + *(here->B3SOIDDBbPtr) + + *(here->B3SOIDDBePtr), + *(here->B3SOIDDDPePtr) + + *(here->B3SOIDDDPgPtr) + *(here->B3SOIDDDPdpPtr) + + *(here->B3SOIDDDPspPtr) + *(here->B3SOIDDDPbPtr)); + if (selfheat) { + fprintf (fpdebug, "DPtemp = %.5e;\t SPtemp = %.5e;\t Btemp = %.5e;\n", + *(here->B3SOIDDDPtempPtr), *(here->B3SOIDDSPtempPtr), + *(here->B3SOIDDBtempPtr)); + fprintf (fpdebug, "Gtemp = %.5e;\t Etemp = %.5e;\n", + *(here->B3SOIDDGtempPtr), *(here->B3SOIDDEtempPtr)); + fprintf (fpdebug, "Tempg = %.5e;\t Tempdp = %.5e;\t Tempsp = %.5e;\t Tempb = %.5e;\n", + *(here->B3SOIDDTempgPtr), *(here->B3SOIDDTempdpPtr), + *(here->B3SOIDDTempspPtr), *(here->B3SOIDDTempbPtr)); + fprintf (fpdebug, "Tempe = %.5e;\t TempT = %.5e;\t Temptot = %.5e;\n", + *(here->B3SOIDDTempePtr), *(here->B3SOIDDTemptempPtr), + *(here->B3SOIDDTempgPtr) + *(here->B3SOIDDTempdpPtr) + + *(here->B3SOIDDTempspPtr)+ *(here->B3SOIDDTempbPtr) + + *(here->B3SOIDDTempePtr)); + } + + if (here->B3SOIDDbodyMod == 1) + { + fprintf(fpdebug, "ceqbodcon=%.5e;\t", ceqbodcon); + fprintf(fpdebug, "Bp = %.5e;\t Pb = %.5e;\t Pp = %.5e;\n", -gppp, gppb, gppp); + fprintf(fpdebug, "Pg=%.5e;\t Pdp=%.5e;\t Psp=%.5e;\t Pe=%.5e;\n", + gppg, gppdp, gppsp, gppe); + } +} + + if (here->B3SOIDDdebugMod > 3) + { + fprintf(fpdebug, "Vth = %.4f, Vbs0eff = %.8f, Vdsat = %.4f\n", + Vth, Vbs0eff, Vdsat); + fprintf(fpdebug, "ueff = %g, Vgsteff = %.4f, Vdseff = %.4f\n", + ueff, Vgsteff, Vdseff); + fprintf(fpdebug, "Vthfd = %.4f, Vbs0mos = %.4f, Vbs0 = %.4f\n", + Vthfd, Vbs0mos, Vbs0); + fprintf(fpdebug, "Vbs0t = %.4f, Vbsdio = %.8f\n", + Vbs0t, Vbsdio); + } + + fclose(fpdebug); + } + + here->B3SOIDDiterations++; /* increment the iteration counter */ + + } /* End of Mosfet Instance */ +} /* End of Model Instance */ + + +return(OK); +} + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddmask.c b/src/spicelib/devices/bsim3soi_dd/b3soiddmask.c new file mode 100644 index 000000000..840895396 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddmask.c @@ -0,0 +1,1207 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +Modified by Wei Jin 99/9/27 +File: b3soiddmask.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "b3soidddef.h" +#include "sperror.h" +#include "suffix.h" + +int +B3SOIDDmAsk(ckt,inst,which,value) +CKTcircuit *ckt; +GENmodel *inst; +int which; +IFvalue *value; +{ + B3SOIDDmodel *model = (B3SOIDDmodel *)inst; + switch(which) + { case B3SOIDD_MOD_MOBMOD: + value->iValue = model->B3SOIDDmobMod; + return(OK); + case B3SOIDD_MOD_PARAMCHK: + value->iValue = model->B3SOIDDparamChk; + return(OK); + case B3SOIDD_MOD_BINUNIT: + value->iValue = model->B3SOIDDbinUnit; + return(OK); + case B3SOIDD_MOD_CAPMOD: + value->iValue = model->B3SOIDDcapMod; + return(OK); + case B3SOIDD_MOD_SHMOD: + value->iValue = model->B3SOIDDshMod; + return(OK); + case B3SOIDD_MOD_NOIMOD: + value->iValue = model->B3SOIDDnoiMod; + return(OK); + case B3SOIDD_MOD_VERSION : + value->rValue = model->B3SOIDDversion; + return(OK); + case B3SOIDD_MOD_TOX : + value->rValue = model->B3SOIDDtox; + return(OK); + case B3SOIDD_MOD_CDSC : + value->rValue = model->B3SOIDDcdsc; + return(OK); + case B3SOIDD_MOD_CDSCB : + value->rValue = model->B3SOIDDcdscb; + return(OK); + + case B3SOIDD_MOD_CDSCD : + value->rValue = model->B3SOIDDcdscd; + return(OK); + + case B3SOIDD_MOD_CIT : + value->rValue = model->B3SOIDDcit; + return(OK); + case B3SOIDD_MOD_NFACTOR : + value->rValue = model->B3SOIDDnfactor; + return(OK); + case B3SOIDD_MOD_VSAT: + value->rValue = model->B3SOIDDvsat; + return(OK); + case B3SOIDD_MOD_AT: + value->rValue = model->B3SOIDDat; + return(OK); + case B3SOIDD_MOD_A0: + value->rValue = model->B3SOIDDa0; + return(OK); + + case B3SOIDD_MOD_AGS: + value->rValue = model->B3SOIDDags; + return(OK); + + case B3SOIDD_MOD_A1: + value->rValue = model->B3SOIDDa1; + return(OK); + case B3SOIDD_MOD_A2: + value->rValue = model->B3SOIDDa2; + return(OK); + case B3SOIDD_MOD_KETA: + value->rValue = model->B3SOIDDketa; + return(OK); + case B3SOIDD_MOD_NSUB: + value->rValue = model->B3SOIDDnsub; + return(OK); + case B3SOIDD_MOD_NPEAK: + value->rValue = model->B3SOIDDnpeak; + return(OK); + case B3SOIDD_MOD_NGATE: + value->rValue = model->B3SOIDDngate; + return(OK); + case B3SOIDD_MOD_GAMMA1: + value->rValue = model->B3SOIDDgamma1; + return(OK); + case B3SOIDD_MOD_GAMMA2: + value->rValue = model->B3SOIDDgamma2; + return(OK); + case B3SOIDD_MOD_VBX: + value->rValue = model->B3SOIDDvbx; + return(OK); + case B3SOIDD_MOD_VBM: + value->rValue = model->B3SOIDDvbm; + return(OK); + case B3SOIDD_MOD_XT: + value->rValue = model->B3SOIDDxt; + return(OK); + case B3SOIDD_MOD_K1: + value->rValue = model->B3SOIDDk1; + return(OK); + case B3SOIDD_MOD_KT1: + value->rValue = model->B3SOIDDkt1; + return(OK); + case B3SOIDD_MOD_KT1L: + value->rValue = model->B3SOIDDkt1l; + return(OK); + case B3SOIDD_MOD_KT2 : + value->rValue = model->B3SOIDDkt2; + return(OK); + case B3SOIDD_MOD_K2 : + value->rValue = model->B3SOIDDk2; + return(OK); + case B3SOIDD_MOD_K3: + value->rValue = model->B3SOIDDk3; + return(OK); + case B3SOIDD_MOD_K3B: + value->rValue = model->B3SOIDDk3b; + return(OK); + case B3SOIDD_MOD_W0: + value->rValue = model->B3SOIDDw0; + return(OK); + case B3SOIDD_MOD_NLX: + value->rValue = model->B3SOIDDnlx; + return(OK); + case B3SOIDD_MOD_DVT0 : + value->rValue = model->B3SOIDDdvt0; + return(OK); + case B3SOIDD_MOD_DVT1 : + value->rValue = model->B3SOIDDdvt1; + return(OK); + case B3SOIDD_MOD_DVT2 : + value->rValue = model->B3SOIDDdvt2; + return(OK); + case B3SOIDD_MOD_DVT0W : + value->rValue = model->B3SOIDDdvt0w; + return(OK); + case B3SOIDD_MOD_DVT1W : + value->rValue = model->B3SOIDDdvt1w; + return(OK); + case B3SOIDD_MOD_DVT2W : + value->rValue = model->B3SOIDDdvt2w; + return(OK); + case B3SOIDD_MOD_DROUT : + value->rValue = model->B3SOIDDdrout; + return(OK); + case B3SOIDD_MOD_DSUB : + value->rValue = model->B3SOIDDdsub; + return(OK); + case B3SOIDD_MOD_VTH0: + value->rValue = model->B3SOIDDvth0; + return(OK); + case B3SOIDD_MOD_UA: + value->rValue = model->B3SOIDDua; + return(OK); + case B3SOIDD_MOD_UA1: + value->rValue = model->B3SOIDDua1; + return(OK); + case B3SOIDD_MOD_UB: + value->rValue = model->B3SOIDDub; + return(OK); + case B3SOIDD_MOD_UB1: + value->rValue = model->B3SOIDDub1; + return(OK); + case B3SOIDD_MOD_UC: + value->rValue = model->B3SOIDDuc; + return(OK); + case B3SOIDD_MOD_UC1: + value->rValue = model->B3SOIDDuc1; + return(OK); + case B3SOIDD_MOD_U0: + value->rValue = model->B3SOIDDu0; + return(OK); + case B3SOIDD_MOD_UTE: + value->rValue = model->B3SOIDDute; + return(OK); + case B3SOIDD_MOD_VOFF: + value->rValue = model->B3SOIDDvoff; + return(OK); + case B3SOIDD_MOD_DELTA: + value->rValue = model->B3SOIDDdelta; + return(OK); + case B3SOIDD_MOD_RDSW: + value->rValue = model->B3SOIDDrdsw; + return(OK); + case B3SOIDD_MOD_PRWG: + value->rValue = model->B3SOIDDprwg; + return(OK); + case B3SOIDD_MOD_PRWB: + value->rValue = model->B3SOIDDprwb; + return(OK); + case B3SOIDD_MOD_PRT: + value->rValue = model->B3SOIDDprt; + return(OK); + case B3SOIDD_MOD_ETA0: + value->rValue = model->B3SOIDDeta0; + return(OK); + case B3SOIDD_MOD_ETAB: + value->rValue = model->B3SOIDDetab; + return(OK); + case B3SOIDD_MOD_PCLM: + value->rValue = model->B3SOIDDpclm; + return(OK); + case B3SOIDD_MOD_PDIBL1: + value->rValue = model->B3SOIDDpdibl1; + return(OK); + case B3SOIDD_MOD_PDIBL2: + value->rValue = model->B3SOIDDpdibl2; + return(OK); + case B3SOIDD_MOD_PDIBLB: + value->rValue = model->B3SOIDDpdiblb; + return(OK); + case B3SOIDD_MOD_PVAG: + value->rValue = model->B3SOIDDpvag; + return(OK); + case B3SOIDD_MOD_WR: + value->rValue = model->B3SOIDDwr; + return(OK); + case B3SOIDD_MOD_DWG: + value->rValue = model->B3SOIDDdwg; + return(OK); + case B3SOIDD_MOD_DWB: + value->rValue = model->B3SOIDDdwb; + return(OK); + case B3SOIDD_MOD_B0: + value->rValue = model->B3SOIDDb0; + return(OK); + case B3SOIDD_MOD_B1: + value->rValue = model->B3SOIDDb1; + return(OK); + case B3SOIDD_MOD_ALPHA0: + value->rValue = model->B3SOIDDalpha0; + return(OK); + case B3SOIDD_MOD_ALPHA1: + value->rValue = model->B3SOIDDalpha1; + return(OK); + case B3SOIDD_MOD_BETA0: + value->rValue = model->B3SOIDDbeta0; + return(OK); + + case B3SOIDD_MOD_CGSL: + value->rValue = model->B3SOIDDcgsl; + return(OK); + case B3SOIDD_MOD_CGDL: + value->rValue = model->B3SOIDDcgdl; + return(OK); + case B3SOIDD_MOD_CKAPPA: + value->rValue = model->B3SOIDDckappa; + return(OK); + case B3SOIDD_MOD_CF: + value->rValue = model->B3SOIDDcf; + return(OK); + case B3SOIDD_MOD_CLC: + value->rValue = model->B3SOIDDclc; + return(OK); + case B3SOIDD_MOD_CLE: + value->rValue = model->B3SOIDDcle; + return(OK); + case B3SOIDD_MOD_DWC: + value->rValue = model->B3SOIDDdwc; + return(OK); + case B3SOIDD_MOD_DLC: + value->rValue = model->B3SOIDDdlc; + return(OK); + + case B3SOIDD_MOD_TBOX: + value->rValue = model->B3SOIDDtbox; + return(OK); + case B3SOIDD_MOD_TSI: + value->rValue = model->B3SOIDDtsi; + return(OK); + case B3SOIDD_MOD_KB1: + value->rValue = model->B3SOIDDkb1; + return(OK); + case B3SOIDD_MOD_KB3: + value->rValue = model->B3SOIDDkb3; + return(OK); + case B3SOIDD_MOD_DVBD0: + value->rValue = model->B3SOIDDdvbd0; + return(OK); + case B3SOIDD_MOD_DVBD1: + value->rValue = model->B3SOIDDdvbd1; + return(OK); + case B3SOIDD_MOD_DELP: + value->rValue = model->B3SOIDDdelp; + return(OK); + case B3SOIDD_MOD_VBSA: + value->rValue = model->B3SOIDDvbsa; + return(OK); + case B3SOIDD_MOD_RBODY: + value->rValue = model->B3SOIDDrbody; + return(OK); + case B3SOIDD_MOD_RBSH: + value->rValue = model->B3SOIDDrbsh; + return(OK); + case B3SOIDD_MOD_ADICE0: + value->rValue = model->B3SOIDDadice0; + return(OK); + case B3SOIDD_MOD_ABP: + value->rValue = model->B3SOIDDabp; + return(OK); + case B3SOIDD_MOD_MXC: + value->rValue = model->B3SOIDDmxc; + return(OK); + case B3SOIDD_MOD_RTH0: + value->rValue = model->B3SOIDDrth0; + return(OK); + case B3SOIDD_MOD_CTH0: + value->rValue = model->B3SOIDDcth0; + return(OK); + case B3SOIDD_MOD_AII: + value->rValue = model->B3SOIDDaii; + return(OK); + case B3SOIDD_MOD_BII: + value->rValue = model->B3SOIDDbii; + return(OK); + case B3SOIDD_MOD_CII: + value->rValue = model->B3SOIDDcii; + return(OK); + case B3SOIDD_MOD_DII: + value->rValue = model->B3SOIDDdii; + return(OK); + case B3SOIDD_MOD_NDIODE: + value->rValue = model->B3SOIDDndiode; + return(OK); + case B3SOIDD_MOD_NTUN: + value->rValue = model->B3SOIDDntun; + return(OK); + case B3SOIDD_MOD_ISBJT: + value->rValue = model->B3SOIDDisbjt; + return(OK); + case B3SOIDD_MOD_ISDIF: + value->rValue = model->B3SOIDDisdif; + return(OK); + case B3SOIDD_MOD_ISREC: + value->rValue = model->B3SOIDDisrec; + return(OK); + case B3SOIDD_MOD_ISTUN: + value->rValue = model->B3SOIDDistun; + return(OK); + case B3SOIDD_MOD_XBJT: + value->rValue = model->B3SOIDDxbjt; + return(OK); + case B3SOIDD_MOD_XREC: + value->rValue = model->B3SOIDDxrec; + return(OK); + case B3SOIDD_MOD_XTUN: + value->rValue = model->B3SOIDDxtun; + return(OK); + case B3SOIDD_MOD_EDL: + value->rValue = model->B3SOIDDedl; + return(OK); + case B3SOIDD_MOD_KBJT1: + value->rValue = model->B3SOIDDkbjt1; + return(OK); + case B3SOIDD_MOD_TT: + value->rValue = model->B3SOIDDtt; + return(OK); + case B3SOIDD_MOD_VSDTH: + value->rValue = model->B3SOIDDvsdth; + return(OK); + case B3SOIDD_MOD_VSDFB: + value->rValue = model->B3SOIDDvsdfb; + return(OK); + case B3SOIDD_MOD_CSDMIN: + value->rValue = model->B3SOIDDcsdmin; + return(OK); + case B3SOIDD_MOD_ASD: + value->rValue = model->B3SOIDDasd; + return(OK); + + case B3SOIDD_MOD_TNOM : + value->rValue = model->B3SOIDDtnom; + return(OK); + case B3SOIDD_MOD_CGSO: + value->rValue = model->B3SOIDDcgso; + return(OK); + case B3SOIDD_MOD_CGDO: + value->rValue = model->B3SOIDDcgdo; + return(OK); + case B3SOIDD_MOD_CGEO: + value->rValue = model->B3SOIDDcgeo; + return(OK); + case B3SOIDD_MOD_XPART: + value->rValue = model->B3SOIDDxpart; + return(OK); + case B3SOIDD_MOD_RSH: + value->rValue = model->B3SOIDDsheetResistance; + return(OK); + case B3SOIDD_MOD_PBSWG: + value->rValue = model->B3SOIDDGatesidewallJctPotential; + return(OK); + case B3SOIDD_MOD_MJSWG: + value->rValue = model->B3SOIDDbodyJctGateSideGradingCoeff; + return(OK); + case B3SOIDD_MOD_CJSWG: + value->rValue = model->B3SOIDDunitLengthGateSidewallJctCap; + return(OK); + case B3SOIDD_MOD_CSDESW: + value->rValue = model->B3SOIDDcsdesw; + return(OK); + case B3SOIDD_MOD_LINT: + value->rValue = model->B3SOIDDLint; + return(OK); + case B3SOIDD_MOD_LL: + value->rValue = model->B3SOIDDLl; + return(OK); + case B3SOIDD_MOD_LLN: + value->rValue = model->B3SOIDDLln; + return(OK); + case B3SOIDD_MOD_LW: + value->rValue = model->B3SOIDDLw; + return(OK); + case B3SOIDD_MOD_LWN: + value->rValue = model->B3SOIDDLwn; + return(OK); + case B3SOIDD_MOD_LWL: + value->rValue = model->B3SOIDDLwl; + return(OK); + case B3SOIDD_MOD_WINT: + value->rValue = model->B3SOIDDWint; + return(OK); + case B3SOIDD_MOD_WL: + value->rValue = model->B3SOIDDWl; + return(OK); + case B3SOIDD_MOD_WLN: + value->rValue = model->B3SOIDDWln; + return(OK); + case B3SOIDD_MOD_WW: + value->rValue = model->B3SOIDDWw; + return(OK); + case B3SOIDD_MOD_WWN: + value->rValue = model->B3SOIDDWwn; + return(OK); + case B3SOIDD_MOD_WWL: + value->rValue = model->B3SOIDDWwl; + return(OK); + case B3SOIDD_MOD_NOIA: + value->rValue = model->B3SOIDDoxideTrapDensityA; + return(OK); + case B3SOIDD_MOD_NOIB: + value->rValue = model->B3SOIDDoxideTrapDensityB; + return(OK); + case B3SOIDD_MOD_NOIC: + value->rValue = model->B3SOIDDoxideTrapDensityC; + return(OK); + case B3SOIDD_MOD_NOIF: + value->rValue = model->B3SOIDDnoif; + return(OK); + case B3SOIDD_MOD_EM: + value->rValue = model->B3SOIDDem; + return(OK); + case B3SOIDD_MOD_EF: + value->rValue = model->B3SOIDDef; + return(OK); + case B3SOIDD_MOD_AF: + value->rValue = model->B3SOIDDaf; + return(OK); + case B3SOIDD_MOD_KF: + value->rValue = model->B3SOIDDkf; + return(OK); + +/* Added for binning - START */ + /* Length Dependence */ + case B3SOIDD_MOD_LNPEAK: + value->rValue = model->B3SOIDDlnpeak; + return(OK); + case B3SOIDD_MOD_LNSUB: + value->rValue = model->B3SOIDDlnsub; + return(OK); + case B3SOIDD_MOD_LNGATE: + value->rValue = model->B3SOIDDlngate; + return(OK); + case B3SOIDD_MOD_LVTH0: + value->rValue = model->B3SOIDDlvth0; + return(OK); + case B3SOIDD_MOD_LK1: + value->rValue = model->B3SOIDDlk1; + return(OK); + case B3SOIDD_MOD_LK2: + value->rValue = model->B3SOIDDlk2; + return(OK); + case B3SOIDD_MOD_LK3: + value->rValue = model->B3SOIDDlk3; + return(OK); + case B3SOIDD_MOD_LK3B: + value->rValue = model->B3SOIDDlk3b; + return(OK); + case B3SOIDD_MOD_LVBSA: + value->rValue = model->B3SOIDDlvbsa; + return(OK); + case B3SOIDD_MOD_LDELP: + value->rValue = model->B3SOIDDldelp; + return(OK); + case B3SOIDD_MOD_LKB1: + value->rValue = model->B3SOIDDlkb1; + return(OK); + case B3SOIDD_MOD_LKB3: + value->rValue = model->B3SOIDDlkb3; + return(OK); + case B3SOIDD_MOD_LDVBD0: + value->rValue = model->B3SOIDDdvbd0; + return(OK); + case B3SOIDD_MOD_LDVBD1: + value->rValue = model->B3SOIDDdvbd1; + return(OK); + case B3SOIDD_MOD_LW0: + value->rValue = model->B3SOIDDlw0; + return(OK); + case B3SOIDD_MOD_LNLX: + value->rValue = model->B3SOIDDlnlx; + return(OK); + case B3SOIDD_MOD_LDVT0 : + value->rValue = model->B3SOIDDldvt0; + return(OK); + case B3SOIDD_MOD_LDVT1 : + value->rValue = model->B3SOIDDldvt1; + return(OK); + case B3SOIDD_MOD_LDVT2 : + value->rValue = model->B3SOIDDldvt2; + return(OK); + case B3SOIDD_MOD_LDVT0W : + value->rValue = model->B3SOIDDldvt0w; + return(OK); + case B3SOIDD_MOD_LDVT1W : + value->rValue = model->B3SOIDDldvt1w; + return(OK); + case B3SOIDD_MOD_LDVT2W : + value->rValue = model->B3SOIDDldvt2w; + return(OK); + case B3SOIDD_MOD_LU0: + value->rValue = model->B3SOIDDlu0; + return(OK); + case B3SOIDD_MOD_LUA: + value->rValue = model->B3SOIDDlua; + return(OK); + case B3SOIDD_MOD_LUB: + value->rValue = model->B3SOIDDlub; + return(OK); + case B3SOIDD_MOD_LUC: + value->rValue = model->B3SOIDDluc; + return(OK); + case B3SOIDD_MOD_LVSAT: + value->rValue = model->B3SOIDDlvsat; + return(OK); + case B3SOIDD_MOD_LA0: + value->rValue = model->B3SOIDDla0; + return(OK); + case B3SOIDD_MOD_LAGS: + value->rValue = model->B3SOIDDlags; + return(OK); + case B3SOIDD_MOD_LB0: + value->rValue = model->B3SOIDDlb0; + return(OK); + case B3SOIDD_MOD_LB1: + value->rValue = model->B3SOIDDlb1; + return(OK); + case B3SOIDD_MOD_LKETA: + value->rValue = model->B3SOIDDlketa; + return(OK); + case B3SOIDD_MOD_LABP: + value->rValue = model->B3SOIDDlabp; + return(OK); + case B3SOIDD_MOD_LMXC: + value->rValue = model->B3SOIDDlmxc; + return(OK); + case B3SOIDD_MOD_LADICE0: + value->rValue = model->B3SOIDDladice0; + return(OK); + case B3SOIDD_MOD_LA1: + value->rValue = model->B3SOIDDla1; + return(OK); + case B3SOIDD_MOD_LA2: + value->rValue = model->B3SOIDDla2; + return(OK); + case B3SOIDD_MOD_LRDSW: + value->rValue = model->B3SOIDDlrdsw; + return(OK); + case B3SOIDD_MOD_LPRWB: + value->rValue = model->B3SOIDDlprwb; + return(OK); + case B3SOIDD_MOD_LPRWG: + value->rValue = model->B3SOIDDlprwg; + return(OK); + case B3SOIDD_MOD_LWR: + value->rValue = model->B3SOIDDlwr; + return(OK); + case B3SOIDD_MOD_LNFACTOR : + value->rValue = model->B3SOIDDlnfactor; + return(OK); + case B3SOIDD_MOD_LDWG: + value->rValue = model->B3SOIDDldwg; + return(OK); + case B3SOIDD_MOD_LDWB: + value->rValue = model->B3SOIDDldwb; + return(OK); + case B3SOIDD_MOD_LVOFF: + value->rValue = model->B3SOIDDlvoff; + return(OK); + case B3SOIDD_MOD_LETA0: + value->rValue = model->B3SOIDDleta0; + return(OK); + case B3SOIDD_MOD_LETAB: + value->rValue = model->B3SOIDDletab; + return(OK); + case B3SOIDD_MOD_LDSUB : + value->rValue = model->B3SOIDDldsub; + return(OK); + case B3SOIDD_MOD_LCIT : + value->rValue = model->B3SOIDDlcit; + return(OK); + case B3SOIDD_MOD_LCDSC : + value->rValue = model->B3SOIDDlcdsc; + return(OK); + case B3SOIDD_MOD_LCDSCB : + value->rValue = model->B3SOIDDlcdscb; + return(OK); + case B3SOIDD_MOD_LCDSCD : + value->rValue = model->B3SOIDDlcdscd; + return(OK); + case B3SOIDD_MOD_LPCLM: + value->rValue = model->B3SOIDDlpclm; + return(OK); + case B3SOIDD_MOD_LPDIBL1: + value->rValue = model->B3SOIDDlpdibl1; + return(OK); + case B3SOIDD_MOD_LPDIBL2: + value->rValue = model->B3SOIDDlpdibl2; + return(OK); + case B3SOIDD_MOD_LPDIBLB: + value->rValue = model->B3SOIDDlpdiblb; + return(OK); + case B3SOIDD_MOD_LDROUT : + value->rValue = model->B3SOIDDldrout; + return(OK); + case B3SOIDD_MOD_LPVAG: + value->rValue = model->B3SOIDDlpvag; + return(OK); + case B3SOIDD_MOD_LDELTA: + value->rValue = model->B3SOIDDldelta; + return(OK); + case B3SOIDD_MOD_LAII: + value->rValue = model->B3SOIDDlaii; + return(OK); + case B3SOIDD_MOD_LBII: + value->rValue = model->B3SOIDDlbii; + return(OK); + case B3SOIDD_MOD_LCII: + value->rValue = model->B3SOIDDlcii; + return(OK); + case B3SOIDD_MOD_LDII: + value->rValue = model->B3SOIDDldii; + return(OK); + case B3SOIDD_MOD_LALPHA0: + value->rValue = model->B3SOIDDlalpha0; + return(OK); + case B3SOIDD_MOD_LALPHA1: + value->rValue = model->B3SOIDDlalpha1; + return(OK); + case B3SOIDD_MOD_LBETA0: + value->rValue = model->B3SOIDDlbeta0; + return(OK); + case B3SOIDD_MOD_LAGIDL: + value->rValue = model->B3SOIDDlagidl; + return(OK); + case B3SOIDD_MOD_LBGIDL: + value->rValue = model->B3SOIDDlbgidl; + return(OK); + case B3SOIDD_MOD_LNGIDL: + value->rValue = model->B3SOIDDlngidl; + return(OK); + case B3SOIDD_MOD_LNTUN: + value->rValue = model->B3SOIDDlntun; + return(OK); + case B3SOIDD_MOD_LNDIODE: + value->rValue = model->B3SOIDDlndiode; + return(OK); + case B3SOIDD_MOD_LISBJT: + value->rValue = model->B3SOIDDlisbjt; + return(OK); + case B3SOIDD_MOD_LISDIF: + value->rValue = model->B3SOIDDlisdif; + return(OK); + case B3SOIDD_MOD_LISREC: + value->rValue = model->B3SOIDDlisrec; + return(OK); + case B3SOIDD_MOD_LISTUN: + value->rValue = model->B3SOIDDlistun; + return(OK); + case B3SOIDD_MOD_LEDL: + value->rValue = model->B3SOIDDledl; + return(OK); + case B3SOIDD_MOD_LKBJT1: + value->rValue = model->B3SOIDDlkbjt1; + return(OK); + /* CV Model */ + case B3SOIDD_MOD_LVSDFB: + value->rValue = model->B3SOIDDlvsdfb; + return(OK); + case B3SOIDD_MOD_LVSDTH: + value->rValue = model->B3SOIDDlvsdth; + return(OK); + /* Width Dependence */ + case B3SOIDD_MOD_WNPEAK: + value->rValue = model->B3SOIDDwnpeak; + return(OK); + case B3SOIDD_MOD_WNSUB: + value->rValue = model->B3SOIDDwnsub; + return(OK); + case B3SOIDD_MOD_WNGATE: + value->rValue = model->B3SOIDDwngate; + return(OK); + case B3SOIDD_MOD_WVTH0: + value->rValue = model->B3SOIDDwvth0; + return(OK); + case B3SOIDD_MOD_WK1: + value->rValue = model->B3SOIDDwk1; + return(OK); + case B3SOIDD_MOD_WK2: + value->rValue = model->B3SOIDDwk2; + return(OK); + case B3SOIDD_MOD_WK3: + value->rValue = model->B3SOIDDwk3; + return(OK); + case B3SOIDD_MOD_WK3B: + value->rValue = model->B3SOIDDwk3b; + return(OK); + case B3SOIDD_MOD_WVBSA: + value->rValue = model->B3SOIDDwvbsa; + return(OK); + case B3SOIDD_MOD_WDELP: + value->rValue = model->B3SOIDDwdelp; + return(OK); + case B3SOIDD_MOD_WKB1: + value->rValue = model->B3SOIDDwkb1; + return(OK); + case B3SOIDD_MOD_WKB3: + value->rValue = model->B3SOIDDwkb3; + return(OK); + case B3SOIDD_MOD_WDVBD0: + value->rValue = model->B3SOIDDdvbd0; + return(OK); + case B3SOIDD_MOD_WDVBD1: + value->rValue = model->B3SOIDDdvbd1; + return(OK); + case B3SOIDD_MOD_WW0: + value->rValue = model->B3SOIDDww0; + return(OK); + case B3SOIDD_MOD_WNLX: + value->rValue = model->B3SOIDDwnlx; + return(OK); + case B3SOIDD_MOD_WDVT0 : + value->rValue = model->B3SOIDDwdvt0; + return(OK); + case B3SOIDD_MOD_WDVT1 : + value->rValue = model->B3SOIDDwdvt1; + return(OK); + case B3SOIDD_MOD_WDVT2 : + value->rValue = model->B3SOIDDwdvt2; + return(OK); + case B3SOIDD_MOD_WDVT0W : + value->rValue = model->B3SOIDDwdvt0w; + return(OK); + case B3SOIDD_MOD_WDVT1W : + value->rValue = model->B3SOIDDwdvt1w; + return(OK); + case B3SOIDD_MOD_WDVT2W : + value->rValue = model->B3SOIDDwdvt2w; + return(OK); + case B3SOIDD_MOD_WU0: + value->rValue = model->B3SOIDDwu0; + return(OK); + case B3SOIDD_MOD_WUA: + value->rValue = model->B3SOIDDwua; + return(OK); + case B3SOIDD_MOD_WUB: + value->rValue = model->B3SOIDDwub; + return(OK); + case B3SOIDD_MOD_WUC: + value->rValue = model->B3SOIDDwuc; + return(OK); + case B3SOIDD_MOD_WVSAT: + value->rValue = model->B3SOIDDwvsat; + return(OK); + case B3SOIDD_MOD_WA0: + value->rValue = model->B3SOIDDwa0; + return(OK); + case B3SOIDD_MOD_WAGS: + value->rValue = model->B3SOIDDwags; + return(OK); + case B3SOIDD_MOD_WB0: + value->rValue = model->B3SOIDDwb0; + return(OK); + case B3SOIDD_MOD_WB1: + value->rValue = model->B3SOIDDwb1; + return(OK); + case B3SOIDD_MOD_WKETA: + value->rValue = model->B3SOIDDwketa; + return(OK); + case B3SOIDD_MOD_WABP: + value->rValue = model->B3SOIDDwabp; + return(OK); + case B3SOIDD_MOD_WMXC: + value->rValue = model->B3SOIDDwmxc; + return(OK); + case B3SOIDD_MOD_WADICE0: + value->rValue = model->B3SOIDDwadice0; + return(OK); + case B3SOIDD_MOD_WA1: + value->rValue = model->B3SOIDDwa1; + return(OK); + case B3SOIDD_MOD_WA2: + value->rValue = model->B3SOIDDwa2; + return(OK); + case B3SOIDD_MOD_WRDSW: + value->rValue = model->B3SOIDDwrdsw; + return(OK); + case B3SOIDD_MOD_WPRWB: + value->rValue = model->B3SOIDDwprwb; + return(OK); + case B3SOIDD_MOD_WPRWG: + value->rValue = model->B3SOIDDwprwg; + return(OK); + case B3SOIDD_MOD_WWR: + value->rValue = model->B3SOIDDwwr; + return(OK); + case B3SOIDD_MOD_WNFACTOR : + value->rValue = model->B3SOIDDwnfactor; + return(OK); + case B3SOIDD_MOD_WDWG: + value->rValue = model->B3SOIDDwdwg; + return(OK); + case B3SOIDD_MOD_WDWB: + value->rValue = model->B3SOIDDwdwb; + return(OK); + case B3SOIDD_MOD_WVOFF: + value->rValue = model->B3SOIDDwvoff; + return(OK); + case B3SOIDD_MOD_WETA0: + value->rValue = model->B3SOIDDweta0; + return(OK); + case B3SOIDD_MOD_WETAB: + value->rValue = model->B3SOIDDwetab; + return(OK); + case B3SOIDD_MOD_WDSUB : + value->rValue = model->B3SOIDDwdsub; + return(OK); + case B3SOIDD_MOD_WCIT : + value->rValue = model->B3SOIDDwcit; + return(OK); + case B3SOIDD_MOD_WCDSC : + value->rValue = model->B3SOIDDwcdsc; + return(OK); + case B3SOIDD_MOD_WCDSCB : + value->rValue = model->B3SOIDDwcdscb; + return(OK); + case B3SOIDD_MOD_WCDSCD : + value->rValue = model->B3SOIDDwcdscd; + return(OK); + case B3SOIDD_MOD_WPCLM: + value->rValue = model->B3SOIDDwpclm; + return(OK); + case B3SOIDD_MOD_WPDIBL1: + value->rValue = model->B3SOIDDwpdibl1; + return(OK); + case B3SOIDD_MOD_WPDIBL2: + value->rValue = model->B3SOIDDwpdibl2; + return(OK); + case B3SOIDD_MOD_WPDIBLB: + value->rValue = model->B3SOIDDwpdiblb; + return(OK); + case B3SOIDD_MOD_WDROUT : + value->rValue = model->B3SOIDDwdrout; + return(OK); + case B3SOIDD_MOD_WPVAG: + value->rValue = model->B3SOIDDwpvag; + return(OK); + case B3SOIDD_MOD_WDELTA: + value->rValue = model->B3SOIDDwdelta; + return(OK); + case B3SOIDD_MOD_WAII: + value->rValue = model->B3SOIDDwaii; + return(OK); + case B3SOIDD_MOD_WBII: + value->rValue = model->B3SOIDDwbii; + return(OK); + case B3SOIDD_MOD_WCII: + value->rValue = model->B3SOIDDwcii; + return(OK); + case B3SOIDD_MOD_WDII: + value->rValue = model->B3SOIDDwdii; + return(OK); + case B3SOIDD_MOD_WALPHA0: + value->rValue = model->B3SOIDDwalpha0; + return(OK); + case B3SOIDD_MOD_WALPHA1: + value->rValue = model->B3SOIDDwalpha1; + return(OK); + case B3SOIDD_MOD_WBETA0: + value->rValue = model->B3SOIDDwbeta0; + return(OK); + case B3SOIDD_MOD_WAGIDL: + value->rValue = model->B3SOIDDwagidl; + return(OK); + case B3SOIDD_MOD_WBGIDL: + value->rValue = model->B3SOIDDwbgidl; + return(OK); + case B3SOIDD_MOD_WNGIDL: + value->rValue = model->B3SOIDDwngidl; + return(OK); + case B3SOIDD_MOD_WNTUN: + value->rValue = model->B3SOIDDwntun; + return(OK); + case B3SOIDD_MOD_WNDIODE: + value->rValue = model->B3SOIDDwndiode; + return(OK); + case B3SOIDD_MOD_WISBJT: + value->rValue = model->B3SOIDDwisbjt; + return(OK); + case B3SOIDD_MOD_WISDIF: + value->rValue = model->B3SOIDDwisdif; + return(OK); + case B3SOIDD_MOD_WISREC: + value->rValue = model->B3SOIDDwisrec; + return(OK); + case B3SOIDD_MOD_WISTUN: + value->rValue = model->B3SOIDDwistun; + return(OK); + case B3SOIDD_MOD_WEDL: + value->rValue = model->B3SOIDDwedl; + return(OK); + case B3SOIDD_MOD_WKBJT1: + value->rValue = model->B3SOIDDwkbjt1; + return(OK); + /* CV Model */ + case B3SOIDD_MOD_WVSDFB: + value->rValue = model->B3SOIDDwvsdfb; + return(OK); + case B3SOIDD_MOD_WVSDTH: + value->rValue = model->B3SOIDDwvsdth; + return(OK); + /* Cross-term Dependence */ + case B3SOIDD_MOD_PNPEAK: + value->rValue = model->B3SOIDDpnpeak; + return(OK); + case B3SOIDD_MOD_PNSUB: + value->rValue = model->B3SOIDDpnsub; + return(OK); + case B3SOIDD_MOD_PNGATE: + value->rValue = model->B3SOIDDpngate; + return(OK); + case B3SOIDD_MOD_PVTH0: + value->rValue = model->B3SOIDDpvth0; + return(OK); + case B3SOIDD_MOD_PK1: + value->rValue = model->B3SOIDDpk1; + return(OK); + case B3SOIDD_MOD_PK2: + value->rValue = model->B3SOIDDpk2; + return(OK); + case B3SOIDD_MOD_PK3: + value->rValue = model->B3SOIDDpk3; + return(OK); + case B3SOIDD_MOD_PK3B: + value->rValue = model->B3SOIDDpk3b; + return(OK); + case B3SOIDD_MOD_PVBSA: + value->rValue = model->B3SOIDDpvbsa; + return(OK); + case B3SOIDD_MOD_PDELP: + value->rValue = model->B3SOIDDpdelp; + return(OK); + case B3SOIDD_MOD_PKB1: + value->rValue = model->B3SOIDDpkb1; + return(OK); + case B3SOIDD_MOD_PKB3: + value->rValue = model->B3SOIDDpkb3; + return(OK); + case B3SOIDD_MOD_PDVBD0: + value->rValue = model->B3SOIDDdvbd0; + return(OK); + case B3SOIDD_MOD_PDVBD1: + value->rValue = model->B3SOIDDdvbd1; + return(OK); + case B3SOIDD_MOD_PW0: + value->rValue = model->B3SOIDDpw0; + return(OK); + case B3SOIDD_MOD_PNLX: + value->rValue = model->B3SOIDDpnlx; + return(OK); + case B3SOIDD_MOD_PDVT0 : + value->rValue = model->B3SOIDDpdvt0; + return(OK); + case B3SOIDD_MOD_PDVT1 : + value->rValue = model->B3SOIDDpdvt1; + return(OK); + case B3SOIDD_MOD_PDVT2 : + value->rValue = model->B3SOIDDpdvt2; + return(OK); + case B3SOIDD_MOD_PDVT0W : + value->rValue = model->B3SOIDDpdvt0w; + return(OK); + case B3SOIDD_MOD_PDVT1W : + value->rValue = model->B3SOIDDpdvt1w; + return(OK); + case B3SOIDD_MOD_PDVT2W : + value->rValue = model->B3SOIDDpdvt2w; + return(OK); + case B3SOIDD_MOD_PU0: + value->rValue = model->B3SOIDDpu0; + return(OK); + case B3SOIDD_MOD_PUA: + value->rValue = model->B3SOIDDpua; + return(OK); + case B3SOIDD_MOD_PUB: + value->rValue = model->B3SOIDDpub; + return(OK); + case B3SOIDD_MOD_PUC: + value->rValue = model->B3SOIDDpuc; + return(OK); + case B3SOIDD_MOD_PVSAT: + value->rValue = model->B3SOIDDpvsat; + return(OK); + case B3SOIDD_MOD_PA0: + value->rValue = model->B3SOIDDpa0; + return(OK); + case B3SOIDD_MOD_PAGS: + value->rValue = model->B3SOIDDpags; + return(OK); + case B3SOIDD_MOD_PB0: + value->rValue = model->B3SOIDDpb0; + return(OK); + case B3SOIDD_MOD_PB1: + value->rValue = model->B3SOIDDpb1; + return(OK); + case B3SOIDD_MOD_PKETA: + value->rValue = model->B3SOIDDpketa; + return(OK); + case B3SOIDD_MOD_PABP: + value->rValue = model->B3SOIDDpabp; + return(OK); + case B3SOIDD_MOD_PMXC: + value->rValue = model->B3SOIDDpmxc; + return(OK); + case B3SOIDD_MOD_PADICE0: + value->rValue = model->B3SOIDDpadice0; + return(OK); + case B3SOIDD_MOD_PA1: + value->rValue = model->B3SOIDDpa1; + return(OK); + case B3SOIDD_MOD_PA2: + value->rValue = model->B3SOIDDpa2; + return(OK); + case B3SOIDD_MOD_PRDSW: + value->rValue = model->B3SOIDDprdsw; + return(OK); + case B3SOIDD_MOD_PPRWB: + value->rValue = model->B3SOIDDpprwb; + return(OK); + case B3SOIDD_MOD_PPRWG: + value->rValue = model->B3SOIDDpprwg; + return(OK); + case B3SOIDD_MOD_PWR: + value->rValue = model->B3SOIDDpwr; + return(OK); + case B3SOIDD_MOD_PNFACTOR : + value->rValue = model->B3SOIDDpnfactor; + return(OK); + case B3SOIDD_MOD_PDWG: + value->rValue = model->B3SOIDDpdwg; + return(OK); + case B3SOIDD_MOD_PDWB: + value->rValue = model->B3SOIDDpdwb; + return(OK); + case B3SOIDD_MOD_PVOFF: + value->rValue = model->B3SOIDDpvoff; + return(OK); + case B3SOIDD_MOD_PETA0: + value->rValue = model->B3SOIDDpeta0; + return(OK); + case B3SOIDD_MOD_PETAB: + value->rValue = model->B3SOIDDpetab; + return(OK); + case B3SOIDD_MOD_PDSUB : + value->rValue = model->B3SOIDDpdsub; + return(OK); + case B3SOIDD_MOD_PCIT : + value->rValue = model->B3SOIDDpcit; + return(OK); + case B3SOIDD_MOD_PCDSC : + value->rValue = model->B3SOIDDpcdsc; + return(OK); + case B3SOIDD_MOD_PCDSCB : + value->rValue = model->B3SOIDDpcdscb; + return(OK); + case B3SOIDD_MOD_PCDSCD : + value->rValue = model->B3SOIDDpcdscd; + return(OK); + case B3SOIDD_MOD_PPCLM: + value->rValue = model->B3SOIDDppclm; + return(OK); + case B3SOIDD_MOD_PPDIBL1: + value->rValue = model->B3SOIDDppdibl1; + return(OK); + case B3SOIDD_MOD_PPDIBL2: + value->rValue = model->B3SOIDDppdibl2; + return(OK); + case B3SOIDD_MOD_PPDIBLB: + value->rValue = model->B3SOIDDppdiblb; + return(OK); + case B3SOIDD_MOD_PDROUT : + value->rValue = model->B3SOIDDpdrout; + return(OK); + case B3SOIDD_MOD_PPVAG: + value->rValue = model->B3SOIDDppvag; + return(OK); + case B3SOIDD_MOD_PDELTA: + value->rValue = model->B3SOIDDpdelta; + return(OK); + case B3SOIDD_MOD_PAII: + value->rValue = model->B3SOIDDpaii; + return(OK); + case B3SOIDD_MOD_PBII: + value->rValue = model->B3SOIDDpbii; + return(OK); + case B3SOIDD_MOD_PCII: + value->rValue = model->B3SOIDDpcii; + return(OK); + case B3SOIDD_MOD_PDII: + value->rValue = model->B3SOIDDpdii; + return(OK); + case B3SOIDD_MOD_PALPHA0: + value->rValue = model->B3SOIDDpalpha0; + return(OK); + case B3SOIDD_MOD_PALPHA1: + value->rValue = model->B3SOIDDpalpha1; + return(OK); + case B3SOIDD_MOD_PBETA0: + value->rValue = model->B3SOIDDpbeta0; + return(OK); + case B3SOIDD_MOD_PAGIDL: + value->rValue = model->B3SOIDDpagidl; + return(OK); + case B3SOIDD_MOD_PBGIDL: + value->rValue = model->B3SOIDDpbgidl; + return(OK); + case B3SOIDD_MOD_PNGIDL: + value->rValue = model->B3SOIDDpngidl; + return(OK); + case B3SOIDD_MOD_PNTUN: + value->rValue = model->B3SOIDDpntun; + return(OK); + case B3SOIDD_MOD_PNDIODE: + value->rValue = model->B3SOIDDpndiode; + return(OK); + case B3SOIDD_MOD_PISBJT: + value->rValue = model->B3SOIDDpisbjt; + return(OK); + case B3SOIDD_MOD_PISDIF: + value->rValue = model->B3SOIDDpisdif; + return(OK); + case B3SOIDD_MOD_PISREC: + value->rValue = model->B3SOIDDpisrec; + return(OK); + case B3SOIDD_MOD_PISTUN: + value->rValue = model->B3SOIDDpistun; + return(OK); + case B3SOIDD_MOD_PEDL: + value->rValue = model->B3SOIDDpedl; + return(OK); + case B3SOIDD_MOD_PKBJT1: + value->rValue = model->B3SOIDDpkbjt1; + return(OK); + /* CV Model */ + case B3SOIDD_MOD_PVSDFB: + value->rValue = model->B3SOIDDpvsdfb; + return(OK); + case B3SOIDD_MOD_PVSDTH: + value->rValue = model->B3SOIDDpvsdth; + return(OK); +/* Added for binning - END */ + + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} + + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddmdel.c b/src/spicelib/devices/bsim3soi_dd/b3soiddmdel.c new file mode 100644 index 000000000..7cd06dbe6 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddmdel.c @@ -0,0 +1,48 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddmdel.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "b3soidddef.h" +#include "sperror.h" +#include "suffix.h" + +int +B3SOIDDmDelete(inModel,modname,kill) +GENmodel **inModel; +IFuid modname; +GENmodel *kill; +{ +B3SOIDDmodel **model = (B3SOIDDmodel**)inModel; +B3SOIDDmodel *modfast = (B3SOIDDmodel*)kill; +B3SOIDDinstance *here; +B3SOIDDinstance *prev = NULL; +B3SOIDDmodel **oldmod; + + oldmod = model; + for (; *model ; model = &((*model)->B3SOIDDnextModel)) + { if ((*model)->B3SOIDDmodName == modname || + (modfast && *model == modfast)) + goto delgot; + oldmod = model; + } + return(E_NOMOD); + +delgot: + *oldmod = (*model)->B3SOIDDnextModel; /* cut deleted device out of list */ + for (here = (*model)->B3SOIDDinstances; here; here = here->B3SOIDDnextInstance) + { if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + FREE(*model); + return(OK); +} + + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddmpar.c b/src/spicelib/devices/bsim3soi_dd/b3soiddmpar.c new file mode 100644 index 000000000..85f4b6797 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddmpar.c @@ -0,0 +1,1625 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +Modified by Wei Jin 99/9/27 +File: b3soiddmpar.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "b3soidddef.h" +#include "ifsim.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIDDmParam(param,value,inMod) +int param; +IFvalue *value; +GENmodel *inMod; +{ + B3SOIDDmodel *mod = (B3SOIDDmodel*)inMod; + switch(param) + { + + case B3SOIDD_MOD_MOBMOD : + mod->B3SOIDDmobMod = value->iValue; + mod->B3SOIDDmobModGiven = TRUE; + break; + case B3SOIDD_MOD_BINUNIT : + mod->B3SOIDDbinUnit = value->iValue; + mod->B3SOIDDbinUnitGiven = TRUE; + break; + case B3SOIDD_MOD_PARAMCHK : + mod->B3SOIDDparamChk = value->iValue; + mod->B3SOIDDparamChkGiven = TRUE; + break; + case B3SOIDD_MOD_CAPMOD : + mod->B3SOIDDcapMod = value->iValue; + mod->B3SOIDDcapModGiven = TRUE; + break; + case B3SOIDD_MOD_SHMOD : + mod->B3SOIDDshMod = value->iValue; + mod->B3SOIDDshModGiven = TRUE; + break; + case B3SOIDD_MOD_NOIMOD : + mod->B3SOIDDnoiMod = value->iValue; + mod->B3SOIDDnoiModGiven = TRUE; + break; + case B3SOIDD_MOD_VERSION : + mod->B3SOIDDversion = value->rValue; + mod->B3SOIDDversionGiven = TRUE; + break; + case B3SOIDD_MOD_TOX : + mod->B3SOIDDtox = value->rValue; + mod->B3SOIDDtoxGiven = TRUE; + break; + + case B3SOIDD_MOD_CDSC : + mod->B3SOIDDcdsc = value->rValue; + mod->B3SOIDDcdscGiven = TRUE; + break; + case B3SOIDD_MOD_CDSCB : + mod->B3SOIDDcdscb = value->rValue; + mod->B3SOIDDcdscbGiven = TRUE; + break; + + case B3SOIDD_MOD_CDSCD : + mod->B3SOIDDcdscd = value->rValue; + mod->B3SOIDDcdscdGiven = TRUE; + break; + + case B3SOIDD_MOD_CIT : + mod->B3SOIDDcit = value->rValue; + mod->B3SOIDDcitGiven = TRUE; + break; + case B3SOIDD_MOD_NFACTOR : + mod->B3SOIDDnfactor = value->rValue; + mod->B3SOIDDnfactorGiven = TRUE; + break; + case B3SOIDD_MOD_VSAT: + mod->B3SOIDDvsat = value->rValue; + mod->B3SOIDDvsatGiven = TRUE; + break; + case B3SOIDD_MOD_A0: + mod->B3SOIDDa0 = value->rValue; + mod->B3SOIDDa0Given = TRUE; + break; + + case B3SOIDD_MOD_AGS: + mod->B3SOIDDags= value->rValue; + mod->B3SOIDDagsGiven = TRUE; + break; + + case B3SOIDD_MOD_A1: + mod->B3SOIDDa1 = value->rValue; + mod->B3SOIDDa1Given = TRUE; + break; + case B3SOIDD_MOD_A2: + mod->B3SOIDDa2 = value->rValue; + mod->B3SOIDDa2Given = TRUE; + break; + case B3SOIDD_MOD_AT: + mod->B3SOIDDat = value->rValue; + mod->B3SOIDDatGiven = TRUE; + break; + case B3SOIDD_MOD_KETA: + mod->B3SOIDDketa = value->rValue; + mod->B3SOIDDketaGiven = TRUE; + break; + case B3SOIDD_MOD_NSUB: + mod->B3SOIDDnsub = value->rValue; + mod->B3SOIDDnsubGiven = TRUE; + break; + case B3SOIDD_MOD_NPEAK: + mod->B3SOIDDnpeak = value->rValue; + mod->B3SOIDDnpeakGiven = TRUE; + if (mod->B3SOIDDnpeak > 1.0e20) + mod->B3SOIDDnpeak *= 1.0e-6; + break; + case B3SOIDD_MOD_NGATE: + mod->B3SOIDDngate = value->rValue; + mod->B3SOIDDngateGiven = TRUE; + if (mod->B3SOIDDngate > 1.0e23) + mod->B3SOIDDngate *= 1.0e-6; + break; + case B3SOIDD_MOD_GAMMA1: + mod->B3SOIDDgamma1 = value->rValue; + mod->B3SOIDDgamma1Given = TRUE; + break; + case B3SOIDD_MOD_GAMMA2: + mod->B3SOIDDgamma2 = value->rValue; + mod->B3SOIDDgamma2Given = TRUE; + break; + case B3SOIDD_MOD_VBX: + mod->B3SOIDDvbx = value->rValue; + mod->B3SOIDDvbxGiven = TRUE; + break; + case B3SOIDD_MOD_VBM: + mod->B3SOIDDvbm = value->rValue; + mod->B3SOIDDvbmGiven = TRUE; + break; + case B3SOIDD_MOD_XT: + mod->B3SOIDDxt = value->rValue; + mod->B3SOIDDxtGiven = TRUE; + break; + case B3SOIDD_MOD_K1: + mod->B3SOIDDk1 = value->rValue; + mod->B3SOIDDk1Given = TRUE; + break; + case B3SOIDD_MOD_KT1: + mod->B3SOIDDkt1 = value->rValue; + mod->B3SOIDDkt1Given = TRUE; + break; + case B3SOIDD_MOD_KT1L: + mod->B3SOIDDkt1l = value->rValue; + mod->B3SOIDDkt1lGiven = TRUE; + break; + case B3SOIDD_MOD_KT2: + mod->B3SOIDDkt2 = value->rValue; + mod->B3SOIDDkt2Given = TRUE; + break; + case B3SOIDD_MOD_K2: + mod->B3SOIDDk2 = value->rValue; + mod->B3SOIDDk2Given = TRUE; + break; + case B3SOIDD_MOD_K3: + mod->B3SOIDDk3 = value->rValue; + mod->B3SOIDDk3Given = TRUE; + break; + case B3SOIDD_MOD_K3B: + mod->B3SOIDDk3b = value->rValue; + mod->B3SOIDDk3bGiven = TRUE; + break; + case B3SOIDD_MOD_NLX: + mod->B3SOIDDnlx = value->rValue; + mod->B3SOIDDnlxGiven = TRUE; + break; + case B3SOIDD_MOD_W0: + mod->B3SOIDDw0 = value->rValue; + mod->B3SOIDDw0Given = TRUE; + break; + case B3SOIDD_MOD_DVT0: + mod->B3SOIDDdvt0 = value->rValue; + mod->B3SOIDDdvt0Given = TRUE; + break; + case B3SOIDD_MOD_DVT1: + mod->B3SOIDDdvt1 = value->rValue; + mod->B3SOIDDdvt1Given = TRUE; + break; + case B3SOIDD_MOD_DVT2: + mod->B3SOIDDdvt2 = value->rValue; + mod->B3SOIDDdvt2Given = TRUE; + break; + case B3SOIDD_MOD_DVT0W: + mod->B3SOIDDdvt0w = value->rValue; + mod->B3SOIDDdvt0wGiven = TRUE; + break; + case B3SOIDD_MOD_DVT1W: + mod->B3SOIDDdvt1w = value->rValue; + mod->B3SOIDDdvt1wGiven = TRUE; + break; + case B3SOIDD_MOD_DVT2W: + mod->B3SOIDDdvt2w = value->rValue; + mod->B3SOIDDdvt2wGiven = TRUE; + break; + case B3SOIDD_MOD_DROUT: + mod->B3SOIDDdrout = value->rValue; + mod->B3SOIDDdroutGiven = TRUE; + break; + case B3SOIDD_MOD_DSUB: + mod->B3SOIDDdsub = value->rValue; + mod->B3SOIDDdsubGiven = TRUE; + break; + case B3SOIDD_MOD_VTH0: + mod->B3SOIDDvth0 = value->rValue; + mod->B3SOIDDvth0Given = TRUE; + break; + case B3SOIDD_MOD_UA: + mod->B3SOIDDua = value->rValue; + mod->B3SOIDDuaGiven = TRUE; + break; + case B3SOIDD_MOD_UA1: + mod->B3SOIDDua1 = value->rValue; + mod->B3SOIDDua1Given = TRUE; + break; + case B3SOIDD_MOD_UB: + mod->B3SOIDDub = value->rValue; + mod->B3SOIDDubGiven = TRUE; + break; + case B3SOIDD_MOD_UB1: + mod->B3SOIDDub1 = value->rValue; + mod->B3SOIDDub1Given = TRUE; + break; + case B3SOIDD_MOD_UC: + mod->B3SOIDDuc = value->rValue; + mod->B3SOIDDucGiven = TRUE; + break; + case B3SOIDD_MOD_UC1: + mod->B3SOIDDuc1 = value->rValue; + mod->B3SOIDDuc1Given = TRUE; + break; + case B3SOIDD_MOD_U0 : + mod->B3SOIDDu0 = value->rValue; + mod->B3SOIDDu0Given = TRUE; + break; + case B3SOIDD_MOD_UTE : + mod->B3SOIDDute = value->rValue; + mod->B3SOIDDuteGiven = TRUE; + break; + case B3SOIDD_MOD_VOFF: + mod->B3SOIDDvoff = value->rValue; + mod->B3SOIDDvoffGiven = TRUE; + break; + case B3SOIDD_MOD_DELTA : + mod->B3SOIDDdelta = value->rValue; + mod->B3SOIDDdeltaGiven = TRUE; + break; + case B3SOIDD_MOD_RDSW: + mod->B3SOIDDrdsw = value->rValue; + mod->B3SOIDDrdswGiven = TRUE; + break; + case B3SOIDD_MOD_PRWG: + mod->B3SOIDDprwg = value->rValue; + mod->B3SOIDDprwgGiven = TRUE; + break; + case B3SOIDD_MOD_PRWB: + mod->B3SOIDDprwb = value->rValue; + mod->B3SOIDDprwbGiven = TRUE; + break; + case B3SOIDD_MOD_PRT: + mod->B3SOIDDprt = value->rValue; + mod->B3SOIDDprtGiven = TRUE; + break; + case B3SOIDD_MOD_ETA0: + mod->B3SOIDDeta0 = value->rValue; + mod->B3SOIDDeta0Given = TRUE; + break; + case B3SOIDD_MOD_ETAB: + mod->B3SOIDDetab = value->rValue; + mod->B3SOIDDetabGiven = TRUE; + break; + case B3SOIDD_MOD_PCLM: + mod->B3SOIDDpclm = value->rValue; + mod->B3SOIDDpclmGiven = TRUE; + break; + case B3SOIDD_MOD_PDIBL1: + mod->B3SOIDDpdibl1 = value->rValue; + mod->B3SOIDDpdibl1Given = TRUE; + break; + case B3SOIDD_MOD_PDIBL2: + mod->B3SOIDDpdibl2 = value->rValue; + mod->B3SOIDDpdibl2Given = TRUE; + break; + case B3SOIDD_MOD_PDIBLB: + mod->B3SOIDDpdiblb = value->rValue; + mod->B3SOIDDpdiblbGiven = TRUE; + break; + case B3SOIDD_MOD_PVAG: + mod->B3SOIDDpvag = value->rValue; + mod->B3SOIDDpvagGiven = TRUE; + break; + case B3SOIDD_MOD_WR : + mod->B3SOIDDwr = value->rValue; + mod->B3SOIDDwrGiven = TRUE; + break; + case B3SOIDD_MOD_DWG : + mod->B3SOIDDdwg = value->rValue; + mod->B3SOIDDdwgGiven = TRUE; + break; + case B3SOIDD_MOD_DWB : + mod->B3SOIDDdwb = value->rValue; + mod->B3SOIDDdwbGiven = TRUE; + break; + case B3SOIDD_MOD_B0 : + mod->B3SOIDDb0 = value->rValue; + mod->B3SOIDDb0Given = TRUE; + break; + case B3SOIDD_MOD_B1 : + mod->B3SOIDDb1 = value->rValue; + mod->B3SOIDDb1Given = TRUE; + break; + case B3SOIDD_MOD_ALPHA0 : + mod->B3SOIDDalpha0 = value->rValue; + mod->B3SOIDDalpha0Given = TRUE; + break; + case B3SOIDD_MOD_ALPHA1 : + mod->B3SOIDDalpha1 = value->rValue; + mod->B3SOIDDalpha1Given = TRUE; + break; + case B3SOIDD_MOD_BETA0 : + mod->B3SOIDDbeta0 = value->rValue; + mod->B3SOIDDbeta0Given = TRUE; + break; + + case B3SOIDD_MOD_CGSL : + mod->B3SOIDDcgsl = value->rValue; + mod->B3SOIDDcgslGiven = TRUE; + break; + case B3SOIDD_MOD_CGDL : + mod->B3SOIDDcgdl = value->rValue; + mod->B3SOIDDcgdlGiven = TRUE; + break; + case B3SOIDD_MOD_CKAPPA : + mod->B3SOIDDckappa = value->rValue; + mod->B3SOIDDckappaGiven = TRUE; + break; + case B3SOIDD_MOD_CF : + mod->B3SOIDDcf = value->rValue; + mod->B3SOIDDcfGiven = TRUE; + break; + case B3SOIDD_MOD_CLC : + mod->B3SOIDDclc = value->rValue; + mod->B3SOIDDclcGiven = TRUE; + break; + case B3SOIDD_MOD_CLE : + mod->B3SOIDDcle = value->rValue; + mod->B3SOIDDcleGiven = TRUE; + break; + case B3SOIDD_MOD_DWC : + mod->B3SOIDDdwc = value->rValue; + mod->B3SOIDDdwcGiven = TRUE; + break; + case B3SOIDD_MOD_DLC : + mod->B3SOIDDdlc = value->rValue; + mod->B3SOIDDdlcGiven = TRUE; + break; + case B3SOIDD_MOD_TBOX : + mod->B3SOIDDtbox = value->rValue; + mod->B3SOIDDtboxGiven = TRUE; + break; + case B3SOIDD_MOD_TSI : + mod->B3SOIDDtsi = value->rValue; + mod->B3SOIDDtsiGiven = TRUE; + break; + case B3SOIDD_MOD_XJ : + mod->B3SOIDDxj = value->rValue; + mod->B3SOIDDxjGiven = TRUE; + break; + case B3SOIDD_MOD_KB1 : + mod->B3SOIDDkb1 = value->rValue; + mod->B3SOIDDkb1Given = TRUE; + break; + case B3SOIDD_MOD_KB3 : + mod->B3SOIDDkb3 = value->rValue; + mod->B3SOIDDkb3Given = TRUE; + break; + case B3SOIDD_MOD_DVBD0 : + mod->B3SOIDDdvbd0 = value->rValue; + mod->B3SOIDDdvbd0Given = TRUE; + break; + case B3SOIDD_MOD_DVBD1 : + mod->B3SOIDDdvbd1 = value->rValue; + mod->B3SOIDDdvbd1Given = TRUE; + break; + case B3SOIDD_MOD_DELP : + mod->B3SOIDDdelp = value->rValue; + mod->B3SOIDDdelpGiven = TRUE; + break; + case B3SOIDD_MOD_VBSA : + mod->B3SOIDDvbsa = value->rValue; + mod->B3SOIDDvbsaGiven = TRUE; + break; + case B3SOIDD_MOD_RBODY : + mod->B3SOIDDrbody = value->rValue; + mod->B3SOIDDrbodyGiven = TRUE; + break; + case B3SOIDD_MOD_RBSH : + mod->B3SOIDDrbsh = value->rValue; + mod->B3SOIDDrbshGiven = TRUE; + break; + case B3SOIDD_MOD_ADICE0 : + mod->B3SOIDDadice0 = value->rValue; + mod->B3SOIDDadice0Given = TRUE; + break; + case B3SOIDD_MOD_ABP : + mod->B3SOIDDabp = value->rValue; + mod->B3SOIDDabpGiven = TRUE; + break; + case B3SOIDD_MOD_MXC : + mod->B3SOIDDmxc = value->rValue; + mod->B3SOIDDmxcGiven = TRUE; + break; + case B3SOIDD_MOD_RTH0 : + mod->B3SOIDDrth0 = value->rValue; + mod->B3SOIDDrth0Given = TRUE; + break; + case B3SOIDD_MOD_CTH0 : + mod->B3SOIDDcth0 = value->rValue; + mod->B3SOIDDcth0Given = TRUE; + break; + case B3SOIDD_MOD_AII : + mod->B3SOIDDaii = value->rValue; + mod->B3SOIDDaiiGiven = TRUE; + break; + case B3SOIDD_MOD_BII : + mod->B3SOIDDbii = value->rValue; + mod->B3SOIDDbiiGiven = TRUE; + break; + case B3SOIDD_MOD_CII : + mod->B3SOIDDcii = value->rValue; + mod->B3SOIDDciiGiven = TRUE; + break; + case B3SOIDD_MOD_DII : + mod->B3SOIDDdii = value->rValue; + mod->B3SOIDDdiiGiven = TRUE; + break; + case B3SOIDD_MOD_NGIDL : + mod->B3SOIDDngidl = value->rValue; + mod->B3SOIDDngidlGiven = TRUE; + break; + case B3SOIDD_MOD_AGIDL : + mod->B3SOIDDagidl = value->rValue; + mod->B3SOIDDagidlGiven = TRUE; + break; + case B3SOIDD_MOD_BGIDL : + mod->B3SOIDDbgidl = value->rValue; + mod->B3SOIDDbgidlGiven = TRUE; + break; + case B3SOIDD_MOD_NDIODE : + mod->B3SOIDDndiode = value->rValue; + mod->B3SOIDDndiodeGiven = TRUE; + break; + case B3SOIDD_MOD_NTUN : + mod->B3SOIDDntun = value->rValue; + mod->B3SOIDDntunGiven = TRUE; + break; + case B3SOIDD_MOD_ISBJT : + mod->B3SOIDDisbjt = value->rValue; + mod->B3SOIDDisbjtGiven = TRUE; + break; + case B3SOIDD_MOD_ISDIF : + mod->B3SOIDDisdif = value->rValue; + mod->B3SOIDDisdifGiven = TRUE; + break; + case B3SOIDD_MOD_ISREC : + mod->B3SOIDDisrec = value->rValue; + mod->B3SOIDDisrecGiven = TRUE; + break; + case B3SOIDD_MOD_ISTUN : + mod->B3SOIDDistun = value->rValue; + mod->B3SOIDDistunGiven = TRUE; + break; + case B3SOIDD_MOD_XBJT : + mod->B3SOIDDxbjt = value->rValue; + mod->B3SOIDDxbjtGiven = TRUE; + break; + case B3SOIDD_MOD_XREC : + mod->B3SOIDDxrec = value->rValue; + mod->B3SOIDDxrecGiven = TRUE; + break; + case B3SOIDD_MOD_XTUN : + mod->B3SOIDDxtun = value->rValue; + mod->B3SOIDDxtunGiven = TRUE; + break; + case B3SOIDD_MOD_EDL : + mod->B3SOIDDedl = value->rValue; + mod->B3SOIDDedlGiven = TRUE; + break; + case B3SOIDD_MOD_KBJT1 : + mod->B3SOIDDkbjt1 = value->rValue; + mod->B3SOIDDkbjt1Given = TRUE; + break; + case B3SOIDD_MOD_TT : + mod->B3SOIDDtt = value->rValue; + mod->B3SOIDDttGiven = TRUE; + break; + case B3SOIDD_MOD_VSDTH : + mod->B3SOIDDvsdth = value->rValue; + mod->B3SOIDDvsdthGiven = TRUE; + break; + case B3SOIDD_MOD_VSDFB : + mod->B3SOIDDvsdfb = value->rValue; + mod->B3SOIDDvsdfbGiven = TRUE; + break; + case B3SOIDD_MOD_CSDMIN : + mod->B3SOIDDcsdmin = value->rValue; + mod->B3SOIDDcsdminGiven = TRUE; + break; + case B3SOIDD_MOD_ASD : + mod->B3SOIDDasd = value->rValue; + mod->B3SOIDDasdGiven = TRUE; + break; + + + case B3SOIDD_MOD_TNOM : + mod->B3SOIDDtnom = value->rValue + 273.15; + mod->B3SOIDDtnomGiven = TRUE; + break; + case B3SOIDD_MOD_CGSO : + mod->B3SOIDDcgso = value->rValue; + mod->B3SOIDDcgsoGiven = TRUE; + break; + case B3SOIDD_MOD_CGDO : + mod->B3SOIDDcgdo = value->rValue; + mod->B3SOIDDcgdoGiven = TRUE; + break; + case B3SOIDD_MOD_CGEO : + mod->B3SOIDDcgeo = value->rValue; + mod->B3SOIDDcgeoGiven = TRUE; + break; + case B3SOIDD_MOD_XPART : + mod->B3SOIDDxpart = value->rValue; + mod->B3SOIDDxpartGiven = TRUE; + break; + case B3SOIDD_MOD_RSH : + mod->B3SOIDDsheetResistance = value->rValue; + mod->B3SOIDDsheetResistanceGiven = TRUE; + break; + case B3SOIDD_MOD_PBSWG : + mod->B3SOIDDGatesidewallJctPotential = value->rValue; + mod->B3SOIDDGatesidewallJctPotentialGiven = TRUE; + break; + case B3SOIDD_MOD_MJSWG : + mod->B3SOIDDbodyJctGateSideGradingCoeff = value->rValue; + mod->B3SOIDDbodyJctGateSideGradingCoeffGiven = TRUE; + break; + case B3SOIDD_MOD_CJSWG : + mod->B3SOIDDunitLengthGateSidewallJctCap = value->rValue; + mod->B3SOIDDunitLengthGateSidewallJctCapGiven = TRUE; + break; + case B3SOIDD_MOD_CSDESW : + mod->B3SOIDDcsdesw = value->rValue; + mod->B3SOIDDcsdeswGiven = TRUE; + break; + case B3SOIDD_MOD_LINT : + mod->B3SOIDDLint = value->rValue; + mod->B3SOIDDLintGiven = TRUE; + break; + case B3SOIDD_MOD_LL : + mod->B3SOIDDLl = value->rValue; + mod->B3SOIDDLlGiven = TRUE; + break; + case B3SOIDD_MOD_LLN : + mod->B3SOIDDLln = value->rValue; + mod->B3SOIDDLlnGiven = TRUE; + break; + case B3SOIDD_MOD_LW : + mod->B3SOIDDLw = value->rValue; + mod->B3SOIDDLwGiven = TRUE; + break; + case B3SOIDD_MOD_LWN : + mod->B3SOIDDLwn = value->rValue; + mod->B3SOIDDLwnGiven = TRUE; + break; + case B3SOIDD_MOD_LWL : + mod->B3SOIDDLwl = value->rValue; + mod->B3SOIDDLwlGiven = TRUE; + break; + case B3SOIDD_MOD_WINT : + mod->B3SOIDDWint = value->rValue; + mod->B3SOIDDWintGiven = TRUE; + break; + case B3SOIDD_MOD_WL : + mod->B3SOIDDWl = value->rValue; + mod->B3SOIDDWlGiven = TRUE; + break; + case B3SOIDD_MOD_WLN : + mod->B3SOIDDWln = value->rValue; + mod->B3SOIDDWlnGiven = TRUE; + break; + case B3SOIDD_MOD_WW : + mod->B3SOIDDWw = value->rValue; + mod->B3SOIDDWwGiven = TRUE; + break; + case B3SOIDD_MOD_WWN : + mod->B3SOIDDWwn = value->rValue; + mod->B3SOIDDWwnGiven = TRUE; + break; + case B3SOIDD_MOD_WWL : + mod->B3SOIDDWwl = value->rValue; + mod->B3SOIDDWwlGiven = TRUE; + break; + + case B3SOIDD_MOD_NOIA : + mod->B3SOIDDoxideTrapDensityA = value->rValue; + mod->B3SOIDDoxideTrapDensityAGiven = TRUE; + break; + case B3SOIDD_MOD_NOIB : + mod->B3SOIDDoxideTrapDensityB = value->rValue; + mod->B3SOIDDoxideTrapDensityBGiven = TRUE; + break; + case B3SOIDD_MOD_NOIC : + mod->B3SOIDDoxideTrapDensityC = value->rValue; + mod->B3SOIDDoxideTrapDensityCGiven = TRUE; + break; + case B3SOIDD_MOD_NOIF : + mod->B3SOIDDnoif = value->rValue; + mod->B3SOIDDnoifGiven = TRUE; + break; + case B3SOIDD_MOD_EM : + mod->B3SOIDDem = value->rValue; + mod->B3SOIDDemGiven = TRUE; + break; + case B3SOIDD_MOD_EF : + mod->B3SOIDDef = value->rValue; + mod->B3SOIDDefGiven = TRUE; + break; + case B3SOIDD_MOD_AF : + mod->B3SOIDDaf = value->rValue; + mod->B3SOIDDafGiven = TRUE; + break; + case B3SOIDD_MOD_KF : + mod->B3SOIDDkf = value->rValue; + mod->B3SOIDDkfGiven = TRUE; + break; + +/* Added for binning - START */ + /* Length Dependence */ + case B3SOIDD_MOD_LNPEAK: + mod->B3SOIDDlnpeak = value->rValue; + mod->B3SOIDDlnpeakGiven = TRUE; + break; + case B3SOIDD_MOD_LNSUB: + mod->B3SOIDDlnsub = value->rValue; + mod->B3SOIDDlnsubGiven = TRUE; + break; + case B3SOIDD_MOD_LNGATE: + mod->B3SOIDDlngate = value->rValue; + mod->B3SOIDDlngateGiven = TRUE; + break; + case B3SOIDD_MOD_LVTH0: + mod->B3SOIDDlvth0 = value->rValue; + mod->B3SOIDDlvth0Given = TRUE; + break; + case B3SOIDD_MOD_LK1: + mod->B3SOIDDlk1 = value->rValue; + mod->B3SOIDDlk1Given = TRUE; + break; + case B3SOIDD_MOD_LK2: + mod->B3SOIDDlk2 = value->rValue; + mod->B3SOIDDlk2Given = TRUE; + break; + case B3SOIDD_MOD_LK3: + mod->B3SOIDDlk3 = value->rValue; + mod->B3SOIDDlk3Given = TRUE; + break; + case B3SOIDD_MOD_LK3B: + mod->B3SOIDDlk3b = value->rValue; + mod->B3SOIDDlk3bGiven = TRUE; + break; + case B3SOIDD_MOD_LVBSA: + mod->B3SOIDDlvbsa = value->rValue; + mod->B3SOIDDlvbsaGiven = TRUE; + break; + case B3SOIDD_MOD_LDELP: + mod->B3SOIDDldelp = value->rValue; + mod->B3SOIDDldelpGiven = TRUE; + break; + case B3SOIDD_MOD_LKB1 : + mod->B3SOIDDlkb1 = value->rValue; + mod->B3SOIDDlkb1Given = TRUE; + break; + case B3SOIDD_MOD_LKB3 : + mod->B3SOIDDlkb3 = value->rValue; + mod->B3SOIDDlkb3Given = TRUE; + break; + case B3SOIDD_MOD_LDVBD0 : + mod->B3SOIDDldvbd0 = value->rValue; + mod->B3SOIDDldvbd0Given = TRUE; + break; + case B3SOIDD_MOD_LDVBD1 : + mod->B3SOIDDldvbd1 = value->rValue; + mod->B3SOIDDldvbd1Given = TRUE; + break; + case B3SOIDD_MOD_LW0: + mod->B3SOIDDlw0 = value->rValue; + mod->B3SOIDDlw0Given = TRUE; + break; + case B3SOIDD_MOD_LNLX: + mod->B3SOIDDlnlx = value->rValue; + mod->B3SOIDDlnlxGiven = TRUE; + break; + case B3SOIDD_MOD_LDVT0: + mod->B3SOIDDldvt0 = value->rValue; + mod->B3SOIDDldvt0Given = TRUE; + break; + case B3SOIDD_MOD_LDVT1: + mod->B3SOIDDldvt1 = value->rValue; + mod->B3SOIDDldvt1Given = TRUE; + break; + case B3SOIDD_MOD_LDVT2: + mod->B3SOIDDldvt2 = value->rValue; + mod->B3SOIDDldvt2Given = TRUE; + break; + case B3SOIDD_MOD_LDVT0W: + mod->B3SOIDDldvt0w = value->rValue; + mod->B3SOIDDldvt0wGiven = TRUE; + break; + case B3SOIDD_MOD_LDVT1W: + mod->B3SOIDDldvt1w = value->rValue; + mod->B3SOIDDldvt1wGiven = TRUE; + break; + case B3SOIDD_MOD_LDVT2W: + mod->B3SOIDDldvt2w = value->rValue; + mod->B3SOIDDldvt2wGiven = TRUE; + break; + case B3SOIDD_MOD_LU0 : + mod->B3SOIDDlu0 = value->rValue; + mod->B3SOIDDlu0Given = TRUE; + break; + case B3SOIDD_MOD_LUA: + mod->B3SOIDDlua = value->rValue; + mod->B3SOIDDluaGiven = TRUE; + break; + case B3SOIDD_MOD_LUB: + mod->B3SOIDDlub = value->rValue; + mod->B3SOIDDlubGiven = TRUE; + break; + case B3SOIDD_MOD_LUC: + mod->B3SOIDDluc = value->rValue; + mod->B3SOIDDlucGiven = TRUE; + break; + case B3SOIDD_MOD_LVSAT: + mod->B3SOIDDlvsat = value->rValue; + mod->B3SOIDDlvsatGiven = TRUE; + break; + case B3SOIDD_MOD_LA0: + mod->B3SOIDDla0 = value->rValue; + mod->B3SOIDDla0Given = TRUE; + break; + case B3SOIDD_MOD_LAGS: + mod->B3SOIDDlags= value->rValue; + mod->B3SOIDDlagsGiven = TRUE; + break; + case B3SOIDD_MOD_LB0 : + mod->B3SOIDDlb0 = value->rValue; + mod->B3SOIDDlb0Given = TRUE; + break; + case B3SOIDD_MOD_LB1 : + mod->B3SOIDDlb1 = value->rValue; + mod->B3SOIDDlb1Given = TRUE; + break; + case B3SOIDD_MOD_LKETA: + mod->B3SOIDDlketa = value->rValue; + mod->B3SOIDDlketaGiven = TRUE; + break; + case B3SOIDD_MOD_LABP: + mod->B3SOIDDlabp = value->rValue; + mod->B3SOIDDlabpGiven = TRUE; + break; + case B3SOIDD_MOD_LMXC: + mod->B3SOIDDlmxc = value->rValue; + mod->B3SOIDDlmxcGiven = TRUE; + break; + case B3SOIDD_MOD_LADICE0: + mod->B3SOIDDladice0 = value->rValue; + mod->B3SOIDDladice0Given = TRUE; + break; + case B3SOIDD_MOD_LA1: + mod->B3SOIDDla1 = value->rValue; + mod->B3SOIDDla1Given = TRUE; + break; + case B3SOIDD_MOD_LA2: + mod->B3SOIDDla2 = value->rValue; + mod->B3SOIDDla2Given = TRUE; + break; + case B3SOIDD_MOD_LRDSW: + mod->B3SOIDDlrdsw = value->rValue; + mod->B3SOIDDlrdswGiven = TRUE; + break; + case B3SOIDD_MOD_LPRWB: + mod->B3SOIDDlprwb = value->rValue; + mod->B3SOIDDlprwbGiven = TRUE; + break; + case B3SOIDD_MOD_LPRWG: + mod->B3SOIDDlprwg = value->rValue; + mod->B3SOIDDlprwgGiven = TRUE; + break; + case B3SOIDD_MOD_LWR : + mod->B3SOIDDlwr = value->rValue; + mod->B3SOIDDlwrGiven = TRUE; + break; + case B3SOIDD_MOD_LNFACTOR : + mod->B3SOIDDlnfactor = value->rValue; + mod->B3SOIDDlnfactorGiven = TRUE; + break; + case B3SOIDD_MOD_LDWG : + mod->B3SOIDDldwg = value->rValue; + mod->B3SOIDDldwgGiven = TRUE; + break; + case B3SOIDD_MOD_LDWB : + mod->B3SOIDDldwb = value->rValue; + mod->B3SOIDDldwbGiven = TRUE; + break; + case B3SOIDD_MOD_LVOFF: + mod->B3SOIDDlvoff = value->rValue; + mod->B3SOIDDlvoffGiven = TRUE; + break; + case B3SOIDD_MOD_LETA0: + mod->B3SOIDDleta0 = value->rValue; + mod->B3SOIDDleta0Given = TRUE; + break; + case B3SOIDD_MOD_LETAB: + mod->B3SOIDDletab = value->rValue; + mod->B3SOIDDletabGiven = TRUE; + break; + case B3SOIDD_MOD_LDSUB: + mod->B3SOIDDldsub = value->rValue; + mod->B3SOIDDldsubGiven = TRUE; + break; + case B3SOIDD_MOD_LCIT : + mod->B3SOIDDlcit = value->rValue; + mod->B3SOIDDlcitGiven = TRUE; + break; + case B3SOIDD_MOD_LCDSC : + mod->B3SOIDDlcdsc = value->rValue; + mod->B3SOIDDlcdscGiven = TRUE; + break; + case B3SOIDD_MOD_LCDSCB : + mod->B3SOIDDlcdscb = value->rValue; + mod->B3SOIDDlcdscbGiven = TRUE; + break; + case B3SOIDD_MOD_LCDSCD : + mod->B3SOIDDlcdscd = value->rValue; + mod->B3SOIDDlcdscdGiven = TRUE; + break; + case B3SOIDD_MOD_LPCLM: + mod->B3SOIDDlpclm = value->rValue; + mod->B3SOIDDlpclmGiven = TRUE; + break; + case B3SOIDD_MOD_LPDIBL1: + mod->B3SOIDDlpdibl1 = value->rValue; + mod->B3SOIDDlpdibl1Given = TRUE; + break; + case B3SOIDD_MOD_LPDIBL2: + mod->B3SOIDDlpdibl2 = value->rValue; + mod->B3SOIDDlpdibl2Given = TRUE; + break; + case B3SOIDD_MOD_LPDIBLB: + mod->B3SOIDDlpdiblb = value->rValue; + mod->B3SOIDDlpdiblbGiven = TRUE; + break; + case B3SOIDD_MOD_LDROUT: + mod->B3SOIDDldrout = value->rValue; + mod->B3SOIDDldroutGiven = TRUE; + break; + case B3SOIDD_MOD_LPVAG: + mod->B3SOIDDlpvag = value->rValue; + mod->B3SOIDDlpvagGiven = TRUE; + break; + case B3SOIDD_MOD_LDELTA : + mod->B3SOIDDldelta = value->rValue; + mod->B3SOIDDldeltaGiven = TRUE; + break; + case B3SOIDD_MOD_LAII : + mod->B3SOIDDlaii = value->rValue; + mod->B3SOIDDlaiiGiven = TRUE; + break; + case B3SOIDD_MOD_LBII : + mod->B3SOIDDlbii = value->rValue; + mod->B3SOIDDlbiiGiven = TRUE; + break; + case B3SOIDD_MOD_LCII : + mod->B3SOIDDlcii = value->rValue; + mod->B3SOIDDlciiGiven = TRUE; + break; + case B3SOIDD_MOD_LDII : + mod->B3SOIDDldii = value->rValue; + mod->B3SOIDDldiiGiven = TRUE; + break; + case B3SOIDD_MOD_LALPHA0 : + mod->B3SOIDDlalpha0 = value->rValue; + mod->B3SOIDDlalpha0Given = TRUE; + break; + case B3SOIDD_MOD_LALPHA1 : + mod->B3SOIDDlalpha1 = value->rValue; + mod->B3SOIDDlalpha1Given = TRUE; + break; + case B3SOIDD_MOD_LBETA0 : + mod->B3SOIDDlbeta0 = value->rValue; + mod->B3SOIDDlbeta0Given = TRUE; + break; + case B3SOIDD_MOD_LAGIDL : + mod->B3SOIDDlagidl = value->rValue; + mod->B3SOIDDlagidlGiven = TRUE; + break; + case B3SOIDD_MOD_LBGIDL : + mod->B3SOIDDlbgidl = value->rValue; + mod->B3SOIDDlbgidlGiven = TRUE; + break; + case B3SOIDD_MOD_LNGIDL : + mod->B3SOIDDlngidl = value->rValue; + mod->B3SOIDDlngidlGiven = TRUE; + break; + case B3SOIDD_MOD_LNTUN : + mod->B3SOIDDlntun = value->rValue; + mod->B3SOIDDlntunGiven = TRUE; + break; + case B3SOIDD_MOD_LNDIODE : + mod->B3SOIDDlndiode = value->rValue; + mod->B3SOIDDlndiodeGiven = TRUE; + break; + case B3SOIDD_MOD_LISBJT : + mod->B3SOIDDlisbjt = value->rValue; + mod->B3SOIDDlisbjtGiven = TRUE; + break; + case B3SOIDD_MOD_LISDIF : + mod->B3SOIDDlisdif = value->rValue; + mod->B3SOIDDlisdifGiven = TRUE; + break; + case B3SOIDD_MOD_LISREC : + mod->B3SOIDDlisrec = value->rValue; + mod->B3SOIDDlisrecGiven = TRUE; + break; + case B3SOIDD_MOD_LISTUN : + mod->B3SOIDDlistun = value->rValue; + mod->B3SOIDDlistunGiven = TRUE; + break; + case B3SOIDD_MOD_LEDL : + mod->B3SOIDDledl = value->rValue; + mod->B3SOIDDledlGiven = TRUE; + break; + case B3SOIDD_MOD_LKBJT1 : + mod->B3SOIDDlkbjt1 = value->rValue; + mod->B3SOIDDlkbjt1Given = TRUE; + break; + /* CV Model */ + case B3SOIDD_MOD_LVSDFB : + mod->B3SOIDDlvsdfb = value->rValue; + mod->B3SOIDDlvsdfbGiven = TRUE; + break; + case B3SOIDD_MOD_LVSDTH : + mod->B3SOIDDlvsdth = value->rValue; + mod->B3SOIDDlvsdthGiven = TRUE; + break; + /* Width Dependence */ + case B3SOIDD_MOD_WNPEAK: + mod->B3SOIDDwnpeak = value->rValue; + mod->B3SOIDDwnpeakGiven = TRUE; + break; + case B3SOIDD_MOD_WNSUB: + mod->B3SOIDDwnsub = value->rValue; + mod->B3SOIDDwnsubGiven = TRUE; + break; + case B3SOIDD_MOD_WNGATE: + mod->B3SOIDDwngate = value->rValue; + mod->B3SOIDDwngateGiven = TRUE; + break; + case B3SOIDD_MOD_WVTH0: + mod->B3SOIDDwvth0 = value->rValue; + mod->B3SOIDDwvth0Given = TRUE; + break; + case B3SOIDD_MOD_WK1: + mod->B3SOIDDwk1 = value->rValue; + mod->B3SOIDDwk1Given = TRUE; + break; + case B3SOIDD_MOD_WK2: + mod->B3SOIDDwk2 = value->rValue; + mod->B3SOIDDwk2Given = TRUE; + break; + case B3SOIDD_MOD_WK3: + mod->B3SOIDDwk3 = value->rValue; + mod->B3SOIDDwk3Given = TRUE; + break; + case B3SOIDD_MOD_WK3B: + mod->B3SOIDDwk3b = value->rValue; + mod->B3SOIDDwk3bGiven = TRUE; + break; + case B3SOIDD_MOD_WVBSA: + mod->B3SOIDDwvbsa = value->rValue; + mod->B3SOIDDwvbsaGiven = TRUE; + break; + case B3SOIDD_MOD_WDELP: + mod->B3SOIDDwdelp = value->rValue; + mod->B3SOIDDwdelpGiven = TRUE; + break; + case B3SOIDD_MOD_WKB1 : + mod->B3SOIDDwkb1 = value->rValue; + mod->B3SOIDDwkb1Given = TRUE; + break; + case B3SOIDD_MOD_WKB3 : + mod->B3SOIDDwkb3 = value->rValue; + mod->B3SOIDDwkb3Given = TRUE; + break; + case B3SOIDD_MOD_WDVBD0 : + mod->B3SOIDDwdvbd0 = value->rValue; + mod->B3SOIDDwdvbd0Given = TRUE; + break; + case B3SOIDD_MOD_WDVBD1 : + mod->B3SOIDDwdvbd1 = value->rValue; + mod->B3SOIDDwdvbd1Given = TRUE; + break; + case B3SOIDD_MOD_WW0: + mod->B3SOIDDww0 = value->rValue; + mod->B3SOIDDww0Given = TRUE; + break; + case B3SOIDD_MOD_WNLX: + mod->B3SOIDDwnlx = value->rValue; + mod->B3SOIDDwnlxGiven = TRUE; + break; + case B3SOIDD_MOD_WDVT0: + mod->B3SOIDDwdvt0 = value->rValue; + mod->B3SOIDDwdvt0Given = TRUE; + break; + case B3SOIDD_MOD_WDVT1: + mod->B3SOIDDwdvt1 = value->rValue; + mod->B3SOIDDwdvt1Given = TRUE; + break; + case B3SOIDD_MOD_WDVT2: + mod->B3SOIDDwdvt2 = value->rValue; + mod->B3SOIDDwdvt2Given = TRUE; + break; + case B3SOIDD_MOD_WDVT0W: + mod->B3SOIDDwdvt0w = value->rValue; + mod->B3SOIDDwdvt0wGiven = TRUE; + break; + case B3SOIDD_MOD_WDVT1W: + mod->B3SOIDDwdvt1w = value->rValue; + mod->B3SOIDDwdvt1wGiven = TRUE; + break; + case B3SOIDD_MOD_WDVT2W: + mod->B3SOIDDwdvt2w = value->rValue; + mod->B3SOIDDwdvt2wGiven = TRUE; + break; + case B3SOIDD_MOD_WU0 : + mod->B3SOIDDwu0 = value->rValue; + mod->B3SOIDDwu0Given = TRUE; + break; + case B3SOIDD_MOD_WUA: + mod->B3SOIDDwua = value->rValue; + mod->B3SOIDDwuaGiven = TRUE; + break; + case B3SOIDD_MOD_WUB: + mod->B3SOIDDwub = value->rValue; + mod->B3SOIDDwubGiven = TRUE; + break; + case B3SOIDD_MOD_WUC: + mod->B3SOIDDwuc = value->rValue; + mod->B3SOIDDwucGiven = TRUE; + break; + case B3SOIDD_MOD_WVSAT: + mod->B3SOIDDwvsat = value->rValue; + mod->B3SOIDDwvsatGiven = TRUE; + break; + case B3SOIDD_MOD_WA0: + mod->B3SOIDDwa0 = value->rValue; + mod->B3SOIDDwa0Given = TRUE; + break; + case B3SOIDD_MOD_WAGS: + mod->B3SOIDDwags= value->rValue; + mod->B3SOIDDwagsGiven = TRUE; + break; + case B3SOIDD_MOD_WB0 : + mod->B3SOIDDwb0 = value->rValue; + mod->B3SOIDDwb0Given = TRUE; + break; + case B3SOIDD_MOD_WB1 : + mod->B3SOIDDwb1 = value->rValue; + mod->B3SOIDDwb1Given = TRUE; + break; + case B3SOIDD_MOD_WKETA: + mod->B3SOIDDwketa = value->rValue; + mod->B3SOIDDwketaGiven = TRUE; + break; + case B3SOIDD_MOD_WABP: + mod->B3SOIDDwabp = value->rValue; + mod->B3SOIDDwabpGiven = TRUE; + break; + case B3SOIDD_MOD_WMXC: + mod->B3SOIDDwmxc = value->rValue; + mod->B3SOIDDwmxcGiven = TRUE; + break; + case B3SOIDD_MOD_WADICE0: + mod->B3SOIDDwadice0 = value->rValue; + mod->B3SOIDDwadice0Given = TRUE; + break; + case B3SOIDD_MOD_WA1: + mod->B3SOIDDwa1 = value->rValue; + mod->B3SOIDDwa1Given = TRUE; + break; + case B3SOIDD_MOD_WA2: + mod->B3SOIDDwa2 = value->rValue; + mod->B3SOIDDwa2Given = TRUE; + break; + case B3SOIDD_MOD_WRDSW: + mod->B3SOIDDwrdsw = value->rValue; + mod->B3SOIDDwrdswGiven = TRUE; + break; + case B3SOIDD_MOD_WPRWB: + mod->B3SOIDDwprwb = value->rValue; + mod->B3SOIDDwprwbGiven = TRUE; + break; + case B3SOIDD_MOD_WPRWG: + mod->B3SOIDDwprwg = value->rValue; + mod->B3SOIDDwprwgGiven = TRUE; + break; + case B3SOIDD_MOD_WWR : + mod->B3SOIDDwwr = value->rValue; + mod->B3SOIDDwwrGiven = TRUE; + break; + case B3SOIDD_MOD_WNFACTOR : + mod->B3SOIDDwnfactor = value->rValue; + mod->B3SOIDDwnfactorGiven = TRUE; + break; + case B3SOIDD_MOD_WDWG : + mod->B3SOIDDwdwg = value->rValue; + mod->B3SOIDDwdwgGiven = TRUE; + break; + case B3SOIDD_MOD_WDWB : + mod->B3SOIDDwdwb = value->rValue; + mod->B3SOIDDwdwbGiven = TRUE; + break; + case B3SOIDD_MOD_WVOFF: + mod->B3SOIDDwvoff = value->rValue; + mod->B3SOIDDwvoffGiven = TRUE; + break; + case B3SOIDD_MOD_WETA0: + mod->B3SOIDDweta0 = value->rValue; + mod->B3SOIDDweta0Given = TRUE; + break; + case B3SOIDD_MOD_WETAB: + mod->B3SOIDDwetab = value->rValue; + mod->B3SOIDDwetabGiven = TRUE; + break; + case B3SOIDD_MOD_WDSUB: + mod->B3SOIDDwdsub = value->rValue; + mod->B3SOIDDwdsubGiven = TRUE; + break; + case B3SOIDD_MOD_WCIT : + mod->B3SOIDDwcit = value->rValue; + mod->B3SOIDDwcitGiven = TRUE; + break; + case B3SOIDD_MOD_WCDSC : + mod->B3SOIDDwcdsc = value->rValue; + mod->B3SOIDDwcdscGiven = TRUE; + break; + case B3SOIDD_MOD_WCDSCB : + mod->B3SOIDDwcdscb = value->rValue; + mod->B3SOIDDwcdscbGiven = TRUE; + break; + case B3SOIDD_MOD_WCDSCD : + mod->B3SOIDDwcdscd = value->rValue; + mod->B3SOIDDwcdscdGiven = TRUE; + break; + case B3SOIDD_MOD_WPCLM: + mod->B3SOIDDwpclm = value->rValue; + mod->B3SOIDDwpclmGiven = TRUE; + break; + case B3SOIDD_MOD_WPDIBL1: + mod->B3SOIDDwpdibl1 = value->rValue; + mod->B3SOIDDwpdibl1Given = TRUE; + break; + case B3SOIDD_MOD_WPDIBL2: + mod->B3SOIDDwpdibl2 = value->rValue; + mod->B3SOIDDwpdibl2Given = TRUE; + break; + case B3SOIDD_MOD_WPDIBLB: + mod->B3SOIDDwpdiblb = value->rValue; + mod->B3SOIDDwpdiblbGiven = TRUE; + break; + case B3SOIDD_MOD_WDROUT: + mod->B3SOIDDwdrout = value->rValue; + mod->B3SOIDDwdroutGiven = TRUE; + break; + case B3SOIDD_MOD_WPVAG: + mod->B3SOIDDwpvag = value->rValue; + mod->B3SOIDDwpvagGiven = TRUE; + break; + case B3SOIDD_MOD_WDELTA : + mod->B3SOIDDwdelta = value->rValue; + mod->B3SOIDDwdeltaGiven = TRUE; + break; + case B3SOIDD_MOD_WAII : + mod->B3SOIDDwaii = value->rValue; + mod->B3SOIDDwaiiGiven = TRUE; + break; + case B3SOIDD_MOD_WBII : + mod->B3SOIDDwbii = value->rValue; + mod->B3SOIDDwbiiGiven = TRUE; + break; + case B3SOIDD_MOD_WCII : + mod->B3SOIDDwcii = value->rValue; + mod->B3SOIDDwciiGiven = TRUE; + break; + case B3SOIDD_MOD_WDII : + mod->B3SOIDDwdii = value->rValue; + mod->B3SOIDDwdiiGiven = TRUE; + break; + case B3SOIDD_MOD_WALPHA0 : + mod->B3SOIDDwalpha0 = value->rValue; + mod->B3SOIDDwalpha0Given = TRUE; + break; + case B3SOIDD_MOD_WALPHA1 : + mod->B3SOIDDwalpha1 = value->rValue; + mod->B3SOIDDwalpha1Given = TRUE; + break; + case B3SOIDD_MOD_WBETA0 : + mod->B3SOIDDwbeta0 = value->rValue; + mod->B3SOIDDwbeta0Given = TRUE; + break; + case B3SOIDD_MOD_WAGIDL : + mod->B3SOIDDwagidl = value->rValue; + mod->B3SOIDDwagidlGiven = TRUE; + break; + case B3SOIDD_MOD_WBGIDL : + mod->B3SOIDDwbgidl = value->rValue; + mod->B3SOIDDwbgidlGiven = TRUE; + break; + case B3SOIDD_MOD_WNGIDL : + mod->B3SOIDDwngidl = value->rValue; + mod->B3SOIDDwngidlGiven = TRUE; + break; + case B3SOIDD_MOD_WNTUN : + mod->B3SOIDDwntun = value->rValue; + mod->B3SOIDDwntunGiven = TRUE; + break; + case B3SOIDD_MOD_WNDIODE : + mod->B3SOIDDwndiode = value->rValue; + mod->B3SOIDDwndiodeGiven = TRUE; + break; + case B3SOIDD_MOD_WISBJT : + mod->B3SOIDDwisbjt = value->rValue; + mod->B3SOIDDwisbjtGiven = TRUE; + break; + case B3SOIDD_MOD_WISDIF : + mod->B3SOIDDwisdif = value->rValue; + mod->B3SOIDDwisdifGiven = TRUE; + break; + case B3SOIDD_MOD_WISREC : + mod->B3SOIDDwisrec = value->rValue; + mod->B3SOIDDwisrecGiven = TRUE; + break; + case B3SOIDD_MOD_WISTUN : + mod->B3SOIDDwistun = value->rValue; + mod->B3SOIDDwistunGiven = TRUE; + break; + case B3SOIDD_MOD_WEDL : + mod->B3SOIDDwedl = value->rValue; + mod->B3SOIDDwedlGiven = TRUE; + break; + case B3SOIDD_MOD_WKBJT1 : + mod->B3SOIDDwkbjt1 = value->rValue; + mod->B3SOIDDwkbjt1Given = TRUE; + break; + /* CV Model */ + case B3SOIDD_MOD_WVSDFB : + mod->B3SOIDDwvsdfb = value->rValue; + mod->B3SOIDDwvsdfbGiven = TRUE; + break; + case B3SOIDD_MOD_WVSDTH : + mod->B3SOIDDwvsdth = value->rValue; + mod->B3SOIDDwvsdthGiven = TRUE; + break; + /* Cross-term Dependence */ + case B3SOIDD_MOD_PNPEAK: + mod->B3SOIDDpnpeak = value->rValue; + mod->B3SOIDDpnpeakGiven = TRUE; + break; + case B3SOIDD_MOD_PNSUB: + mod->B3SOIDDpnsub = value->rValue; + mod->B3SOIDDpnsubGiven = TRUE; + break; + case B3SOIDD_MOD_PNGATE: + mod->B3SOIDDpngate = value->rValue; + mod->B3SOIDDpngateGiven = TRUE; + break; + case B3SOIDD_MOD_PVTH0: + mod->B3SOIDDpvth0 = value->rValue; + mod->B3SOIDDpvth0Given = TRUE; + break; + case B3SOIDD_MOD_PK1: + mod->B3SOIDDpk1 = value->rValue; + mod->B3SOIDDpk1Given = TRUE; + break; + case B3SOIDD_MOD_PK2: + mod->B3SOIDDpk2 = value->rValue; + mod->B3SOIDDpk2Given = TRUE; + break; + case B3SOIDD_MOD_PK3: + mod->B3SOIDDpk3 = value->rValue; + mod->B3SOIDDpk3Given = TRUE; + break; + case B3SOIDD_MOD_PK3B: + mod->B3SOIDDpk3b = value->rValue; + mod->B3SOIDDpk3bGiven = TRUE; + break; + case B3SOIDD_MOD_PVBSA: + mod->B3SOIDDpvbsa = value->rValue; + mod->B3SOIDDpvbsaGiven = TRUE; + break; + case B3SOIDD_MOD_PDELP: + mod->B3SOIDDpdelp = value->rValue; + mod->B3SOIDDpdelpGiven = TRUE; + break; + case B3SOIDD_MOD_PKB1 : + mod->B3SOIDDpkb1 = value->rValue; + mod->B3SOIDDpkb1Given = TRUE; + break; + case B3SOIDD_MOD_PKB3 : + mod->B3SOIDDpkb3 = value->rValue; + mod->B3SOIDDpkb3Given = TRUE; + break; + case B3SOIDD_MOD_PDVBD0 : + mod->B3SOIDDpdvbd0 = value->rValue; + mod->B3SOIDDpdvbd0Given = TRUE; + break; + case B3SOIDD_MOD_PDVBD1 : + mod->B3SOIDDpdvbd1 = value->rValue; + mod->B3SOIDDpdvbd1Given = TRUE; + break; + case B3SOIDD_MOD_PW0: + mod->B3SOIDDpw0 = value->rValue; + mod->B3SOIDDpw0Given = TRUE; + break; + case B3SOIDD_MOD_PNLX: + mod->B3SOIDDpnlx = value->rValue; + mod->B3SOIDDpnlxGiven = TRUE; + break; + case B3SOIDD_MOD_PDVT0: + mod->B3SOIDDpdvt0 = value->rValue; + mod->B3SOIDDpdvt0Given = TRUE; + break; + case B3SOIDD_MOD_PDVT1: + mod->B3SOIDDpdvt1 = value->rValue; + mod->B3SOIDDpdvt1Given = TRUE; + break; + case B3SOIDD_MOD_PDVT2: + mod->B3SOIDDpdvt2 = value->rValue; + mod->B3SOIDDpdvt2Given = TRUE; + break; + case B3SOIDD_MOD_PDVT0W: + mod->B3SOIDDpdvt0w = value->rValue; + mod->B3SOIDDpdvt0wGiven = TRUE; + break; + case B3SOIDD_MOD_PDVT1W: + mod->B3SOIDDpdvt1w = value->rValue; + mod->B3SOIDDpdvt1wGiven = TRUE; + break; + case B3SOIDD_MOD_PDVT2W: + mod->B3SOIDDpdvt2w = value->rValue; + mod->B3SOIDDpdvt2wGiven = TRUE; + break; + case B3SOIDD_MOD_PU0 : + mod->B3SOIDDpu0 = value->rValue; + mod->B3SOIDDpu0Given = TRUE; + break; + case B3SOIDD_MOD_PUA: + mod->B3SOIDDpua = value->rValue; + mod->B3SOIDDpuaGiven = TRUE; + break; + case B3SOIDD_MOD_PUB: + mod->B3SOIDDpub = value->rValue; + mod->B3SOIDDpubGiven = TRUE; + break; + case B3SOIDD_MOD_PUC: + mod->B3SOIDDpuc = value->rValue; + mod->B3SOIDDpucGiven = TRUE; + break; + case B3SOIDD_MOD_PVSAT: + mod->B3SOIDDpvsat = value->rValue; + mod->B3SOIDDpvsatGiven = TRUE; + break; + case B3SOIDD_MOD_PA0: + mod->B3SOIDDpa0 = value->rValue; + mod->B3SOIDDpa0Given = TRUE; + break; + case B3SOIDD_MOD_PAGS: + mod->B3SOIDDpags= value->rValue; + mod->B3SOIDDpagsGiven = TRUE; + break; + case B3SOIDD_MOD_PB0 : + mod->B3SOIDDpb0 = value->rValue; + mod->B3SOIDDpb0Given = TRUE; + break; + case B3SOIDD_MOD_PB1 : + mod->B3SOIDDpb1 = value->rValue; + mod->B3SOIDDpb1Given = TRUE; + break; + case B3SOIDD_MOD_PKETA: + mod->B3SOIDDpketa = value->rValue; + mod->B3SOIDDpketaGiven = TRUE; + break; + case B3SOIDD_MOD_PABP: + mod->B3SOIDDpabp = value->rValue; + mod->B3SOIDDpabpGiven = TRUE; + break; + case B3SOIDD_MOD_PMXC: + mod->B3SOIDDpmxc = value->rValue; + mod->B3SOIDDpmxcGiven = TRUE; + break; + case B3SOIDD_MOD_PADICE0: + mod->B3SOIDDpadice0 = value->rValue; + mod->B3SOIDDpadice0Given = TRUE; + break; + case B3SOIDD_MOD_PA1: + mod->B3SOIDDpa1 = value->rValue; + mod->B3SOIDDpa1Given = TRUE; + break; + case B3SOIDD_MOD_PA2: + mod->B3SOIDDpa2 = value->rValue; + mod->B3SOIDDpa2Given = TRUE; + break; + case B3SOIDD_MOD_PRDSW: + mod->B3SOIDDprdsw = value->rValue; + mod->B3SOIDDprdswGiven = TRUE; + break; + case B3SOIDD_MOD_PPRWB: + mod->B3SOIDDpprwb = value->rValue; + mod->B3SOIDDpprwbGiven = TRUE; + break; + case B3SOIDD_MOD_PPRWG: + mod->B3SOIDDpprwg = value->rValue; + mod->B3SOIDDpprwgGiven = TRUE; + break; + case B3SOIDD_MOD_PWR : + mod->B3SOIDDpwr = value->rValue; + mod->B3SOIDDpwrGiven = TRUE; + break; + case B3SOIDD_MOD_PNFACTOR : + mod->B3SOIDDpnfactor = value->rValue; + mod->B3SOIDDpnfactorGiven = TRUE; + break; + case B3SOIDD_MOD_PDWG : + mod->B3SOIDDpdwg = value->rValue; + mod->B3SOIDDpdwgGiven = TRUE; + break; + case B3SOIDD_MOD_PDWB : + mod->B3SOIDDpdwb = value->rValue; + mod->B3SOIDDpdwbGiven = TRUE; + break; + case B3SOIDD_MOD_PVOFF: + mod->B3SOIDDpvoff = value->rValue; + mod->B3SOIDDpvoffGiven = TRUE; + break; + case B3SOIDD_MOD_PETA0: + mod->B3SOIDDpeta0 = value->rValue; + mod->B3SOIDDpeta0Given = TRUE; + break; + case B3SOIDD_MOD_PETAB: + mod->B3SOIDDpetab = value->rValue; + mod->B3SOIDDpetabGiven = TRUE; + break; + case B3SOIDD_MOD_PDSUB: + mod->B3SOIDDpdsub = value->rValue; + mod->B3SOIDDpdsubGiven = TRUE; + break; + case B3SOIDD_MOD_PCIT : + mod->B3SOIDDpcit = value->rValue; + mod->B3SOIDDpcitGiven = TRUE; + break; + case B3SOIDD_MOD_PCDSC : + mod->B3SOIDDpcdsc = value->rValue; + mod->B3SOIDDpcdscGiven = TRUE; + break; + case B3SOIDD_MOD_PCDSCB : + mod->B3SOIDDpcdscb = value->rValue; + mod->B3SOIDDpcdscbGiven = TRUE; + break; + case B3SOIDD_MOD_PCDSCD : + mod->B3SOIDDpcdscd = value->rValue; + mod->B3SOIDDpcdscdGiven = TRUE; + break; + case B3SOIDD_MOD_PPCLM: + mod->B3SOIDDppclm = value->rValue; + mod->B3SOIDDppclmGiven = TRUE; + break; + case B3SOIDD_MOD_PPDIBL1: + mod->B3SOIDDppdibl1 = value->rValue; + mod->B3SOIDDppdibl1Given = TRUE; + break; + case B3SOIDD_MOD_PPDIBL2: + mod->B3SOIDDppdibl2 = value->rValue; + mod->B3SOIDDppdibl2Given = TRUE; + break; + case B3SOIDD_MOD_PPDIBLB: + mod->B3SOIDDppdiblb = value->rValue; + mod->B3SOIDDppdiblbGiven = TRUE; + break; + case B3SOIDD_MOD_PDROUT: + mod->B3SOIDDpdrout = value->rValue; + mod->B3SOIDDpdroutGiven = TRUE; + break; + case B3SOIDD_MOD_PPVAG: + mod->B3SOIDDppvag = value->rValue; + mod->B3SOIDDppvagGiven = TRUE; + break; + case B3SOIDD_MOD_PDELTA : + mod->B3SOIDDpdelta = value->rValue; + mod->B3SOIDDpdeltaGiven = TRUE; + break; + case B3SOIDD_MOD_PAII : + mod->B3SOIDDpaii = value->rValue; + mod->B3SOIDDpaiiGiven = TRUE; + break; + case B3SOIDD_MOD_PBII : + mod->B3SOIDDpbii = value->rValue; + mod->B3SOIDDpbiiGiven = TRUE; + break; + case B3SOIDD_MOD_PCII : + mod->B3SOIDDpcii = value->rValue; + mod->B3SOIDDpciiGiven = TRUE; + break; + case B3SOIDD_MOD_PDII : + mod->B3SOIDDpdii = value->rValue; + mod->B3SOIDDpdiiGiven = TRUE; + break; + case B3SOIDD_MOD_PALPHA0 : + mod->B3SOIDDpalpha0 = value->rValue; + mod->B3SOIDDpalpha0Given = TRUE; + break; + case B3SOIDD_MOD_PALPHA1 : + mod->B3SOIDDpalpha1 = value->rValue; + mod->B3SOIDDpalpha1Given = TRUE; + break; + case B3SOIDD_MOD_PBETA0 : + mod->B3SOIDDpbeta0 = value->rValue; + mod->B3SOIDDpbeta0Given = TRUE; + break; + case B3SOIDD_MOD_PAGIDL : + mod->B3SOIDDpagidl = value->rValue; + mod->B3SOIDDpagidlGiven = TRUE; + break; + case B3SOIDD_MOD_PBGIDL : + mod->B3SOIDDpbgidl = value->rValue; + mod->B3SOIDDpbgidlGiven = TRUE; + break; + case B3SOIDD_MOD_PNGIDL : + mod->B3SOIDDpngidl = value->rValue; + mod->B3SOIDDpngidlGiven = TRUE; + break; + case B3SOIDD_MOD_PNTUN : + mod->B3SOIDDpntun = value->rValue; + mod->B3SOIDDpntunGiven = TRUE; + break; + case B3SOIDD_MOD_PNDIODE : + mod->B3SOIDDpndiode = value->rValue; + mod->B3SOIDDpndiodeGiven = TRUE; + break; + case B3SOIDD_MOD_PISBJT : + mod->B3SOIDDpisbjt = value->rValue; + mod->B3SOIDDpisbjtGiven = TRUE; + break; + case B3SOIDD_MOD_PISDIF : + mod->B3SOIDDpisdif = value->rValue; + mod->B3SOIDDpisdifGiven = TRUE; + break; + case B3SOIDD_MOD_PISREC : + mod->B3SOIDDpisrec = value->rValue; + mod->B3SOIDDpisrecGiven = TRUE; + break; + case B3SOIDD_MOD_PISTUN : + mod->B3SOIDDpistun = value->rValue; + mod->B3SOIDDpistunGiven = TRUE; + break; + case B3SOIDD_MOD_PEDL : + mod->B3SOIDDpedl = value->rValue; + mod->B3SOIDDpedlGiven = TRUE; + break; + case B3SOIDD_MOD_PKBJT1 : + mod->B3SOIDDpkbjt1 = value->rValue; + mod->B3SOIDDpkbjt1Given = TRUE; + break; + /* CV Model */ + case B3SOIDD_MOD_PVSDFB : + mod->B3SOIDDpvsdfb = value->rValue; + mod->B3SOIDDpvsdfbGiven = TRUE; + break; + case B3SOIDD_MOD_PVSDTH : + mod->B3SOIDDpvsdth = value->rValue; + mod->B3SOIDDpvsdthGiven = TRUE; + break; +/* Added for binning - END */ + + case B3SOIDD_MOD_NMOS : + if(value->iValue) { + mod->B3SOIDDtype = 1; + mod->B3SOIDDtypeGiven = TRUE; + } + break; + case B3SOIDD_MOD_PMOS : + if(value->iValue) { + mod->B3SOIDDtype = - 1; + mod->B3SOIDDtypeGiven = TRUE; + } + break; + default: + return(E_BADPARM); + } + return(OK); +} + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddnoi.c b/src/spicelib/devices/bsim3soi_dd/b3soiddnoi.c new file mode 100644 index 000000000..6e4826bb1 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddnoi.c @@ -0,0 +1,395 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddnoi.c 98/5/01 +**********/ + +#include "ngspice.h" +#include +#include +#include "b3soidddef.h" +#include "cktdefs.h" +#include "iferrmsg.h" +#include "noisedef.h" +#include "suffix.h" +#include "const.h" /* jwan */ + +/* + * B3SOIDDnoise (mode, operation, firstModel, ckt, data, OnDens) + * This routine names and evaluates all of the noise sources + * associated with MOSFET's. It starts with the model *firstModel and + * traverses all of its insts. It then proceeds to any other models + * on the linked list. The total output noise density generated by + * all of the MOSFET's is summed with the variable "OnDens". + */ + +/* + Channel thermal and flicker noises are calculated based on the value + of model->B3SOIDDnoiMod. + If model->B3SOIDDnoiMod = 1, + Channel thermal noise = SPICE2 model + Flicker noise = SPICE2 model + If model->B3SOIDDnoiMod = 2, + Channel thermal noise = B3SOIDD model + Flicker noise = B3SOIDD model + If model->B3SOIDDnoiMod = 3, + Channel thermal noise = SPICE2 model + Flicker noise = B3SOIDD model + If model->B3SOIDDnoiMod = 4, + Channel thermal noise = B3SOIDD model + Flicker noise = SPICE2 model + */ + +extern void NevalSrc(); +extern double Nintegrate(); + +double +B3SOIDDStrongInversionNoiseEval(vgs, vds, model, here, freq, temp) +double vgs, vds, freq, temp; +B3SOIDDmodel *model; +B3SOIDDinstance *here; +{ +struct b3soiddSizeDependParam *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 req, ceq; + + pParam = here->pParam; + cd = fabs(here->B3SOIDDcd); + if (vds > here->B3SOIDDvdsat) + { esat = 2.0 * pParam->B3SOIDDvsattemp / here->B3SOIDDueff; + T0 = ((((vds - here->B3SOIDDvdsat) / pParam->B3SOIDDlitl) + model->B3SOIDDem) + / esat); + DelClm = pParam->B3SOIDDlitl * log (MAX(T0, N_MINLOG)); + } + else + DelClm = 0.0; + EffFreq = pow(freq, model->B3SOIDDef); + T1 = CHARGE * CHARGE * 8.62e-5 * cd * temp * here->B3SOIDDueff; + T2 = 1.0e8 * EffFreq * model->B3SOIDDcox + * pParam->B3SOIDDleff * pParam->B3SOIDDleff; + Vgst = vgs - here->B3SOIDDvon; + N0 = model->B3SOIDDcox * Vgst / CHARGE; + if (N0 < 0.0) + N0 = 0.0; + Nl = model->B3SOIDDcox * (Vgst - MIN(vds, here->B3SOIDDvdsat)) / CHARGE; + if (Nl < 0.0) + Nl = 0.0; + + T3 = model->B3SOIDDoxideTrapDensityA + * log(MAX(((N0 + 2.0e14) / (Nl + 2.0e14)), N_MINLOG)); + T4 = model->B3SOIDDoxideTrapDensityB * (N0 - Nl); + T5 = model->B3SOIDDoxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl); + + T6 = 8.62e-5 * temp * cd * cd; + T7 = 1.0e8 * EffFreq * pParam->B3SOIDDleff + * pParam->B3SOIDDleff * pParam->B3SOIDDweff; + T8 = model->B3SOIDDoxideTrapDensityA + model->B3SOIDDoxideTrapDensityB * Nl + + model->B3SOIDDoxideTrapDensityC * Nl * Nl; + T9 = (Nl + 2.0e14) * (Nl + 2.0e14); + + Ssi = T1 / T2 * (T3 + T4 + T5) + T6 / T7 * DelClm * T8 / T9; + + return Ssi; +} + +int +B3SOIDDnoise (mode, operation, inModel, ckt, data, OnDens) +int mode, operation; +GENmodel *inModel; +CKTcircuit *ckt; +register Ndata *data; +double *OnDens; +{ +register B3SOIDDmodel *model = (B3SOIDDmodel *)inModel; +register B3SOIDDinstance *here; +struct b3soiddSizeDependParam *pParam; +char name[N_MXVLNTH]; +double tempOnoise; +double tempInoise; +double noizDens[B3SOIDDNSRCS]; +double lnNdens[B3SOIDDNSRCS]; + +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; + +int error, i; + + /* define the names of the noise sources */ + static char *B3SOIDDnNames[B3SOIDDNSRCS] = + { /* Note that we have to keep the order */ + ".rd", /* noise due to rd */ + /* consistent with the index definitions */ + ".rs", /* noise due to rs */ + /* in B3SOIDDdefs.h */ + ".id", /* noise due to id */ + ".1overf", /* flicker (1/f) noise */ + ".fb", /* noise due to floating body */ + "" /* total transistor noise */ + }; + + for (; model != NULL; model = model->B3SOIDDnextModel) + { for (here = model->B3SOIDDinstances; here != NULL; + here = here->B3SOIDDnextInstance) + { pParam = here->pParam; + switch (operation) + { case N_OPEN: + /* see if we have to to produce a summary report */ + /* if so, name all the noise generators */ + + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) + { switch (mode) + { case N_DENS: + for (i = 0; i < B3SOIDDNSRCS; i++) + { (void) sprintf(name, "onoise.%s%s", + here->B3SOIDDname, + B3SOIDDnNames[i]); + data->namelist = (IFuid *) trealloc( + (char *) data->namelist, + (data->numPlots + 1) + * sizeof(IFuid)); + if (!data->namelist) + return(E_NOMEM); + (*(SPfrontEnd->IFnewUid)) (ckt, + &(data->namelist[data->numPlots++]), + (IFuid) NULL, name, UID_OTHER, + (void **) NULL); + /* we've added one more plot */ + } + break; + case INT_NOIZ: + for (i = 0; i < B3SOIDDNSRCS; i++) + { (void) sprintf(name, "onoise_total.%s%s", + here->B3SOIDDname, + B3SOIDDnNames[i]); + data->namelist = (IFuid *) trealloc( + (char *) data->namelist, + (data->numPlots + 1) + * sizeof(IFuid)); + if (!data->namelist) + return(E_NOMEM); + (*(SPfrontEnd->IFnewUid)) (ckt, + &(data->namelist[data->numPlots++]), + (IFuid) NULL, name, UID_OTHER, + (void **) NULL); + /* we've added one more plot */ + + (void) sprintf(name, "inoise_total.%s%s", + here->B3SOIDDname, + B3SOIDDnNames[i]); + data->namelist = (IFuid *) trealloc( + (char *) data->namelist, + (data->numPlots + 1) + * sizeof(IFuid)); + if (!data->namelist) + return(E_NOMEM); + (*(SPfrontEnd->IFnewUid)) (ckt, + &(data->namelist[data->numPlots++]), + (IFuid) NULL, name, UID_OTHER, + (void **)NULL); + /* we've added one more plot */ + } + break; + } + } + break; + case N_CALC: + switch (mode) + { case N_DENS: + NevalSrc(&noizDens[B3SOIDDRDNOIZ], + &lnNdens[B3SOIDDRDNOIZ], ckt, THERMNOISE, + here->B3SOIDDdNodePrime, here->B3SOIDDdNode, + here->B3SOIDDdrainConductance); + + NevalSrc(&noizDens[B3SOIDDRSNOIZ], + &lnNdens[B3SOIDDRSNOIZ], ckt, THERMNOISE, + here->B3SOIDDsNodePrime, here->B3SOIDDsNode, + here->B3SOIDDsourceConductance); + + switch( model->B3SOIDDnoiMod ) + { case 1: + case 3: + NevalSrc(&noizDens[B3SOIDDIDNOIZ], + &lnNdens[B3SOIDDIDNOIZ], ckt, + THERMNOISE, here->B3SOIDDdNodePrime, + here->B3SOIDDsNodePrime, + (2.0 / 3.0 * fabs(here->B3SOIDDgm + + here->B3SOIDDgds + + here->B3SOIDDgmbs))); + break; + case 2: + case 4: + NevalSrc(&noizDens[B3SOIDDIDNOIZ], + &lnNdens[B3SOIDDIDNOIZ], ckt, + THERMNOISE, here->B3SOIDDdNodePrime, + here->B3SOIDDsNodePrime, + (here->B3SOIDDueff + * fabs(here->B3SOIDDqinv + / (pParam->B3SOIDDleff + * pParam->B3SOIDDleff)))); + break; + } + NevalSrc(&noizDens[B3SOIDDFLNOIZ], (double*) NULL, + ckt, N_GAIN, here->B3SOIDDdNodePrime, + here->B3SOIDDsNodePrime, (double) 0.0); + + switch( model->B3SOIDDnoiMod ) + { case 1: + case 4: + noizDens[B3SOIDDFLNOIZ] *= model->B3SOIDDkf + * exp(model->B3SOIDDaf + * log(MAX(fabs(here->B3SOIDDcd), + N_MINLOG))) + / (pow(data->freq, model->B3SOIDDef) + * pParam->B3SOIDDleff + * pParam->B3SOIDDleff + * model->B3SOIDDcox); + break; + case 2: + case 3: + vgs = *(ckt->CKTstates[0] + here->B3SOIDDvgs); + vds = *(ckt->CKTstates[0] + here->B3SOIDDvds); + if (vds < 0.0) + { vds = -vds; + vgs = vgs + vds; + } + if (vgs >= here->B3SOIDDvon + 0.1) + { Ssi = B3SOIDDStrongInversionNoiseEval(vgs, + vds, model, here, data->freq, + ckt->CKTtemp); + noizDens[B3SOIDDFLNOIZ] *= Ssi; + } + else + { pParam = here->pParam; + T10 = model->B3SOIDDoxideTrapDensityA + * 8.62e-5 * ckt->CKTtemp; + T11 = pParam->B3SOIDDweff + * pParam->B3SOIDDleff + * pow(data->freq, model->B3SOIDDef) + * 4.0e36; + Swi = T10 / T11 * here->B3SOIDDcd + * here->B3SOIDDcd; + Slimit = B3SOIDDStrongInversionNoiseEval( + here->B3SOIDDvon + 0.1, vds, model, + here, data->freq, ckt->CKTtemp); + T1 = Swi + Slimit; + if (T1 > 0.0) + noizDens[B3SOIDDFLNOIZ] *= (Slimit + * Swi) / T1; + else + noizDens[B3SOIDDFLNOIZ] *= 0.0; + } + break; + } + + lnNdens[B3SOIDDFLNOIZ] = + log(MAX(noizDens[B3SOIDDFLNOIZ], N_MINLOG)); + + /* Low frequency excess noise due to FBE */ + NevalSrc(&noizDens[B3SOIDDFBNOIZ], &lnNdens[B3SOIDDFBNOIZ], + ckt, SHOTNOISE, here->B3SOIDDsNodePrime, + here->B3SOIDDbNode, + 2.0 * model->B3SOIDDnoif * here->B3SOIDDibs); + + noizDens[B3SOIDDTOTNOIZ] = noizDens[B3SOIDDRDNOIZ] + + noizDens[B3SOIDDRSNOIZ] + + noizDens[B3SOIDDIDNOIZ] + + noizDens[B3SOIDDFLNOIZ] + + noizDens[B3SOIDDFBNOIZ]; + lnNdens[B3SOIDDTOTNOIZ] = + log(MAX(noizDens[B3SOIDDTOTNOIZ], N_MINLOG)); + + *OnDens += noizDens[B3SOIDDTOTNOIZ]; + + if (data->delFreq == 0.0) + { /* if we haven't done any previous + integration, we need to initialize our + "history" variables. + */ + + for (i = 0; i < B3SOIDDNSRCS; i++) + { here->B3SOIDDnVar[LNLSTDENS][i] = + lnNdens[i]; + } + + /* clear out our integration variables + if it's the first pass + */ + if (data->freq == + ((NOISEAN*) ckt->CKTcurJob)->NstartFreq) + { for (i = 0; i < B3SOIDDNSRCS; i++) + { here->B3SOIDDnVar[OUTNOIZ][i] = 0.0; + here->B3SOIDDnVar[INNOIZ][i] = 0.0; + } + } + } + else + { /* data->delFreq != 0.0, + we have to integrate. + */ + for (i = 0; i < B3SOIDDNSRCS; i++) + { if (i != B3SOIDDTOTNOIZ) + { tempOnoise = Nintegrate(noizDens[i], + lnNdens[i], + here->B3SOIDDnVar[LNLSTDENS][i], + data); + tempInoise = Nintegrate(noizDens[i] + * data->GainSqInv, lnNdens[i] + + data->lnGainInv, + here->B3SOIDDnVar[LNLSTDENS][i] + + data->lnGainInv, data); + here->B3SOIDDnVar[LNLSTDENS][i] = + lnNdens[i]; + data->outNoiz += tempOnoise; + data->inNoise += tempInoise; + if (((NOISEAN*) + ckt->CKTcurJob)->NStpsSm != 0) + { here->B3SOIDDnVar[OUTNOIZ][i] + += tempOnoise; + here->B3SOIDDnVar[OUTNOIZ][B3SOIDDTOTNOIZ] + += tempOnoise; + here->B3SOIDDnVar[INNOIZ][i] + += tempInoise; + here->B3SOIDDnVar[INNOIZ][B3SOIDDTOTNOIZ] + += tempInoise; + } + } + } + } + if (data->prtSummary) + { for (i = 0; i < B3SOIDDNSRCS; i++) + { /* print a summary report */ + data->outpVector[data->outNumber++] + = noizDens[i]; + } + } + break; + case INT_NOIZ: + /* already calculated, just output */ + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) + { for (i = 0; i < B3SOIDDNSRCS; i++) + { data->outpVector[data->outNumber++] + = here->B3SOIDDnVar[OUTNOIZ][i]; + data->outpVector[data->outNumber++] + = here->B3SOIDDnVar[INNOIZ][i]; + } + } + break; + } + break; + case N_CLOSE: + /* do nothing, the main calling routine will close */ + return (OK); + break; /* the plots */ + } /* switch (operation) */ + } /* for here */ + } /* for model */ + + return(OK); +} + + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddpar.c b/src/spicelib/devices/bsim3soi_dd/b3soiddpar.c new file mode 100644 index 000000000..cf514fca5 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddpar.c @@ -0,0 +1,128 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddpar.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "b3soidddef.h" +#include "sperror.h" +#include "suffix.h" + +int +B3SOIDDparam(param,value,inst,select) +int param; +IFvalue *value; +GENinstance *inst; +IFvalue *select; +{ + B3SOIDDinstance *here = (B3SOIDDinstance*)inst; + switch(param) + { case B3SOIDD_W: + here->B3SOIDDw = value->rValue; + here->B3SOIDDwGiven = TRUE; + break; + case B3SOIDD_L: + here->B3SOIDDl = value->rValue; + here->B3SOIDDlGiven = TRUE; + break; + case B3SOIDD_AS: + here->B3SOIDDsourceArea = value->rValue; + here->B3SOIDDsourceAreaGiven = TRUE; + break; + case B3SOIDD_AD: + here->B3SOIDDdrainArea = value->rValue; + here->B3SOIDDdrainAreaGiven = TRUE; + break; + case B3SOIDD_PS: + here->B3SOIDDsourcePerimeter = value->rValue; + here->B3SOIDDsourcePerimeterGiven = TRUE; + break; + case B3SOIDD_PD: + here->B3SOIDDdrainPerimeter = value->rValue; + here->B3SOIDDdrainPerimeterGiven = TRUE; + break; + case B3SOIDD_NRS: + here->B3SOIDDsourceSquares = value->rValue; + here->B3SOIDDsourceSquaresGiven = TRUE; + break; + case B3SOIDD_NRD: + here->B3SOIDDdrainSquares = value->rValue; + here->B3SOIDDdrainSquaresGiven = TRUE; + break; + case B3SOIDD_OFF: + here->B3SOIDDoff = value->iValue; + break; + case B3SOIDD_IC_VBS: + here->B3SOIDDicVBS = value->rValue; + here->B3SOIDDicVBSGiven = TRUE; + break; + case B3SOIDD_IC_VDS: + here->B3SOIDDicVDS = value->rValue; + here->B3SOIDDicVDSGiven = TRUE; + break; + case B3SOIDD_IC_VGS: + here->B3SOIDDicVGS = value->rValue; + here->B3SOIDDicVGSGiven = TRUE; + break; + case B3SOIDD_IC_VES: + here->B3SOIDDicVES = value->rValue; + here->B3SOIDDicVESGiven = TRUE; + break; + case B3SOIDD_IC_VPS: + here->B3SOIDDicVPS = value->rValue; + here->B3SOIDDicVPSGiven = TRUE; + break; + case B3SOIDD_BJTOFF: + here->B3SOIDDbjtoff = value->iValue; + here->B3SOIDDbjtoffGiven= TRUE; + break; + case B3SOIDD_DEBUG: + here->B3SOIDDdebugMod = value->iValue; + here->B3SOIDDdebugModGiven= TRUE; + break; + case B3SOIDD_RTH0: + here->B3SOIDDrth0= value->rValue; + here->B3SOIDDrth0Given = TRUE; + break; + case B3SOIDD_CTH0: + here->B3SOIDDcth0= value->rValue; + here->B3SOIDDcth0Given = TRUE; + break; + case B3SOIDD_NRB: + here->B3SOIDDbodySquares = value->rValue; + here->B3SOIDDbodySquaresGiven = TRUE; + break; + case B3SOIDD_IC: + switch(value->v.numValue){ + case 5: + here->B3SOIDDicVPS = *(value->v.vec.rVec+4); + here->B3SOIDDicVPSGiven = TRUE; + case 4: + here->B3SOIDDicVES = *(value->v.vec.rVec+3); + here->B3SOIDDicVESGiven = TRUE; + case 3: + here->B3SOIDDicVBS = *(value->v.vec.rVec+2); + here->B3SOIDDicVBSGiven = TRUE; + case 2: + here->B3SOIDDicVGS = *(value->v.vec.rVec+1); + here->B3SOIDDicVGSGiven = TRUE; + case 1: + here->B3SOIDDicVDS = *(value->v.vec.rVec); + here->B3SOIDDicVDSGiven = TRUE; + break; + default: + return(E_BADPARM); + } + break; + default: + return(E_BADPARM); + } + return(OK); +} + + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddpzld.c b/src/spicelib/devices/bsim3soi_dd/b3soiddpzld.c new file mode 100644 index 000000000..a545828ed --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddpzld.c @@ -0,0 +1,153 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddpzld.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "complex.h" +#include "sperror.h" +#include "b3soidddef.h" +#include "suffix.h" + +int +B3SOIDDpzLoad(inModel,ckt,s) +GENmodel *inModel; +register CKTcircuit *ckt; +register SPcomplex *s; +{ +register B3SOIDDmodel *model = (B3SOIDDmodel*)inModel; +register B3SOIDDinstance *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; +double GSoverlapCap, GDoverlapCap, GBoverlapCap; +double FwdSum, RevSum, Gm, Gmbs; + + for (; model != NULL; model = model->B3SOIDDnextModel) + { for (here = model->B3SOIDDinstances; here!= NULL; + here = here->B3SOIDDnextInstance) + { + if (here->B3SOIDDmode >= 0) + { Gm = here->B3SOIDDgm; + Gmbs = here->B3SOIDDgmbs; + FwdSum = Gm + Gmbs; + RevSum = 0.0; + cggb = here->B3SOIDDcggb; + cgsb = here->B3SOIDDcgsb; + cgdb = here->B3SOIDDcgdb; + + cbgb = here->B3SOIDDcbgb; + cbsb = here->B3SOIDDcbsb; + cbdb = here->B3SOIDDcbdb; + + cdgb = here->B3SOIDDcdgb; + cdsb = here->B3SOIDDcdsb; + cddb = here->B3SOIDDcddb; + } + else + { Gm = -here->B3SOIDDgm; + Gmbs = -here->B3SOIDDgmbs; + FwdSum = 0.0; + RevSum = -Gm - Gmbs; + cggb = here->B3SOIDDcggb; + cgsb = here->B3SOIDDcgdb; + cgdb = here->B3SOIDDcgsb; + + cbgb = here->B3SOIDDcbgb; + cbsb = here->B3SOIDDcbdb; + cbdb = here->B3SOIDDcbsb; + + cdgb = -(here->B3SOIDDcdgb + cggb + cbgb); + cdsb = -(here->B3SOIDDcddb + cgsb + cbsb); + cddb = -(here->B3SOIDDcdsb + cgdb + cbdb); + } + gdpr=here->B3SOIDDdrainConductance; + gspr=here->B3SOIDDsourceConductance; + gds= here->B3SOIDDgds; + gbd= here->B3SOIDDgjdb; + gbs= here->B3SOIDDgjsb; +#ifdef BULKCODE + capbd= here->B3SOIDDcapbd; + capbs= here->B3SOIDDcapbs; +#endif + GSoverlapCap = here->B3SOIDDcgso; + GDoverlapCap = here->B3SOIDDcgdo; +#ifdef BULKCODE + GBoverlapCap = here->pParam->B3SOIDDcgbo; +#endif + + xcdgb = (cdgb - GDoverlapCap); + xcddb = (cddb + capbd + GDoverlapCap); + xcdsb = cdsb; + xcsgb = -(cggb + cbgb + cdgb + GSoverlapCap); + xcsdb = -(cgdb + cbdb + cddb); + xcssb = (capbs + GSoverlapCap - (cgsb+cbsb+cdsb)); + xcggb = (cggb + GDoverlapCap + GSoverlapCap + GBoverlapCap); + xcgdb = (cgdb - GDoverlapCap); + xcgsb = (cgsb - GSoverlapCap); + xcbgb = (cbgb - GBoverlapCap); + xcbdb = (cbdb - capbd); + xcbsb = (cbsb - capbs); + + + *(here->B3SOIDDGgPtr ) += xcggb * s->real; + *(here->B3SOIDDGgPtr +1) += xcggb * s->imag; + *(here->B3SOIDDBbPtr ) += (-xcbgb-xcbdb-xcbsb) * s->real; + *(here->B3SOIDDBbPtr +1) += (-xcbgb-xcbdb-xcbsb) * s->imag; + *(here->B3SOIDDDPdpPtr ) += xcddb * s->real; + *(here->B3SOIDDDPdpPtr +1) += xcddb * s->imag; + *(here->B3SOIDDSPspPtr ) += xcssb * s->real; + *(here->B3SOIDDSPspPtr +1) += xcssb * s->imag; + *(here->B3SOIDDGbPtr ) += (-xcggb-xcgdb-xcgsb) * s->real; + *(here->B3SOIDDGbPtr +1) += (-xcggb-xcgdb-xcgsb) * s->imag; + *(here->B3SOIDDGdpPtr ) += xcgdb * s->real; + *(here->B3SOIDDGdpPtr +1) += xcgdb * s->imag; + *(here->B3SOIDDGspPtr ) += xcgsb * s->real; + *(here->B3SOIDDGspPtr +1) += xcgsb * s->imag; + *(here->B3SOIDDBgPtr ) += xcbgb * s->real; + *(here->B3SOIDDBgPtr +1) += xcbgb * s->imag; + *(here->B3SOIDDBdpPtr ) += xcbdb * s->real; + *(here->B3SOIDDBdpPtr +1) += xcbdb * s->imag; + *(here->B3SOIDDBspPtr ) += xcbsb * s->real; + *(here->B3SOIDDBspPtr +1) += xcbsb * s->imag; + *(here->B3SOIDDDPgPtr ) += xcdgb * s->real; + *(here->B3SOIDDDPgPtr +1) += xcdgb * s->imag; + *(here->B3SOIDDDPbPtr ) += (-xcdgb-xcddb-xcdsb) * s->real; + *(here->B3SOIDDDPbPtr +1) += (-xcdgb-xcddb-xcdsb) * s->imag; + *(here->B3SOIDDDPspPtr ) += xcdsb * s->real; + *(here->B3SOIDDDPspPtr +1) += xcdsb * s->imag; + *(here->B3SOIDDSPgPtr ) += xcsgb * s->real; + *(here->B3SOIDDSPgPtr +1) += xcsgb * s->imag; + *(here->B3SOIDDSPbPtr ) += (-xcsgb-xcsdb-xcssb) * s->real; + *(here->B3SOIDDSPbPtr +1) += (-xcsgb-xcsdb-xcssb) * s->imag; + *(here->B3SOIDDSPdpPtr ) += xcsdb * s->real; + *(here->B3SOIDDSPdpPtr +1) += xcsdb * s->imag; + *(here->B3SOIDDDdPtr) += gdpr; + *(here->B3SOIDDSsPtr) += gspr; + *(here->B3SOIDDBbPtr) += gbd+gbs; + *(here->B3SOIDDDPdpPtr) += gdpr+gds+gbd+RevSum; + *(here->B3SOIDDSPspPtr) += gspr+gds+gbs+FwdSum; + *(here->B3SOIDDDdpPtr) -= gdpr; + *(here->B3SOIDDSspPtr) -= gspr; + *(here->B3SOIDDBdpPtr) -= gbd; + *(here->B3SOIDDBspPtr) -= gbs; + *(here->B3SOIDDDPdPtr) -= gdpr; + *(here->B3SOIDDDPgPtr) += Gm; + *(here->B3SOIDDDPbPtr) -= gbd - Gmbs; + *(here->B3SOIDDDPspPtr) -= gds + FwdSum; + *(here->B3SOIDDSPgPtr) -= Gm; + *(here->B3SOIDDSPsPtr) -= gspr; + *(here->B3SOIDDSPbPtr) -= gbs + Gmbs; + *(here->B3SOIDDSPdpPtr) -= gds + RevSum; + + } + } + return(OK); +} + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddset.c b/src/spicelib/devices/bsim3soi_dd/b3soiddset.c new file mode 100644 index 000000000..5e032490d --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddset.c @@ -0,0 +1,1353 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +Modified by Pin Su, Wei Jin 99/9/27 +File: b3soiddset.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "b3soidddef.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + +#define MAX_EXP 5.834617425e14 +#define MIN_EXP 1.713908431e-15 +#define EXP_THRESHOLD 34.0 +#define SMOOTHFACTOR 0.1 +#define EPSOX 3.453133e-11 +#define EPSSI 1.03594e-10 +#define PI 3.141592654 +#define Charge_q 1.60219e-19 +#define Meter2Micron 1.0e6 + +int +B3SOIDDsetup(matrix,inModel,ckt,states) +register SMPmatrix *matrix; +register GENmodel *inModel; +register CKTcircuit *ckt; +int *states; +{ +register B3SOIDDmodel *model = (B3SOIDDmodel*)inModel; +register B3SOIDDinstance *here; +int error; +CKTnode *tmp; + +double tmp1, tmp2; +double nfb0, Cboxt; +int itmp1; + + /* loop through all the B3SOIDD device models */ + for( ; model != NULL; model = model->B3SOIDDnextModel ) + { +/* Default value Processing for B3SOIDD MOSFET Models */ + + if (!model->B3SOIDDtypeGiven) + model->B3SOIDDtype = NMOS; + if (!model->B3SOIDDmobModGiven) + model->B3SOIDDmobMod = 1; + if (!model->B3SOIDDbinUnitGiven) + model->B3SOIDDbinUnit = 1; + if (!model->B3SOIDDparamChkGiven) + model->B3SOIDDparamChk = 0; + if (!model->B3SOIDDcapModGiven) + model->B3SOIDDcapMod = 2; + if (!model->B3SOIDDnoiModGiven) + model->B3SOIDDnoiMod = 1; + if (!model->B3SOIDDshModGiven) + model->B3SOIDDshMod = 0; + if (!model->B3SOIDDversionGiven) + model->B3SOIDDversion = 2.0; + if (!model->B3SOIDDtoxGiven) + model->B3SOIDDtox = 100.0e-10; + model->B3SOIDDcox = 3.453133e-11 / model->B3SOIDDtox; + + if (!model->B3SOIDDcdscGiven) + model->B3SOIDDcdsc = 2.4e-4; /* unit Q/V/m^2 */ + if (!model->B3SOIDDcdscbGiven) + model->B3SOIDDcdscb = 0.0; /* unit Q/V/m^2 */ + if (!model->B3SOIDDcdscdGiven) + model->B3SOIDDcdscd = 0.0; /* unit Q/V/m^2 */ + if (!model->B3SOIDDcitGiven) + model->B3SOIDDcit = 0.0; /* unit Q/V/m^2 */ + if (!model->B3SOIDDnfactorGiven) + model->B3SOIDDnfactor = 1; + if (!model->B3SOIDDvsatGiven) + model->B3SOIDDvsat = 8.0e4; /* unit m/s */ + if (!model->B3SOIDDatGiven) + model->B3SOIDDat = 3.3e4; /* unit m/s */ + if (!model->B3SOIDDa0Given) + model->B3SOIDDa0 = 1.0; + if (!model->B3SOIDDagsGiven) + model->B3SOIDDags = 0.0; + if (!model->B3SOIDDa1Given) + model->B3SOIDDa1 = 0.0; + if (!model->B3SOIDDa2Given) + model->B3SOIDDa2 = 1.0; + if (!model->B3SOIDDketaGiven) + model->B3SOIDDketa = -0.6; /* unit / V */ + if (!model->B3SOIDDnsubGiven) + model->B3SOIDDnsub = 6.0e16; /* unit 1/cm3 */ + if (!model->B3SOIDDnpeakGiven) + model->B3SOIDDnpeak = 1.7e17; /* unit 1/cm3 */ + if (!model->B3SOIDDngateGiven) + model->B3SOIDDngate = 0; /* unit 1/cm3 */ + if (!model->B3SOIDDvbmGiven) + model->B3SOIDDvbm = -3.0; + if (!model->B3SOIDDxtGiven) + model->B3SOIDDxt = 1.55e-7; + if (!model->B3SOIDDkt1Given) + model->B3SOIDDkt1 = -0.11; /* unit V */ + if (!model->B3SOIDDkt1lGiven) + model->B3SOIDDkt1l = 0.0; /* unit V*m */ + if (!model->B3SOIDDkt2Given) + model->B3SOIDDkt2 = 0.022; /* No unit */ + if (!model->B3SOIDDk3Given) + model->B3SOIDDk3 = 0.0; + if (!model->B3SOIDDk3bGiven) + model->B3SOIDDk3b = 0.0; + if (!model->B3SOIDDw0Given) + model->B3SOIDDw0 = 2.5e-6; + if (!model->B3SOIDDnlxGiven) + model->B3SOIDDnlx = 1.74e-7; + if (!model->B3SOIDDdvt0Given) + model->B3SOIDDdvt0 = 2.2; + if (!model->B3SOIDDdvt1Given) + model->B3SOIDDdvt1 = 0.53; + if (!model->B3SOIDDdvt2Given) + model->B3SOIDDdvt2 = -0.032; /* unit 1 / V */ + + if (!model->B3SOIDDdvt0wGiven) + model->B3SOIDDdvt0w = 0.0; + if (!model->B3SOIDDdvt1wGiven) + model->B3SOIDDdvt1w = 5.3e6; + if (!model->B3SOIDDdvt2wGiven) + model->B3SOIDDdvt2w = -0.032; + + if (!model->B3SOIDDdroutGiven) + model->B3SOIDDdrout = 0.56; + if (!model->B3SOIDDdsubGiven) + model->B3SOIDDdsub = model->B3SOIDDdrout; + if (!model->B3SOIDDvth0Given) + model->B3SOIDDvth0 = (model->B3SOIDDtype == NMOS) ? 0.7 : -0.7; + if (!model->B3SOIDDuaGiven) + model->B3SOIDDua = 2.25e-9; /* unit m/V */ + if (!model->B3SOIDDua1Given) + model->B3SOIDDua1 = 4.31e-9; /* unit m/V */ + if (!model->B3SOIDDubGiven) + model->B3SOIDDub = 5.87e-19; /* unit (m/V)**2 */ + if (!model->B3SOIDDub1Given) + model->B3SOIDDub1 = -7.61e-18; /* unit (m/V)**2 */ + if (!model->B3SOIDDucGiven) + model->B3SOIDDuc = (model->B3SOIDDmobMod == 3) ? -0.0465 : -0.0465e-9; + if (!model->B3SOIDDuc1Given) + model->B3SOIDDuc1 = (model->B3SOIDDmobMod == 3) ? -0.056 : -0.056e-9; + if (!model->B3SOIDDu0Given) + model->B3SOIDDu0 = (model->B3SOIDDtype == NMOS) ? 0.067 : 0.025; + if (!model->B3SOIDDuteGiven) + model->B3SOIDDute = -1.5; + if (!model->B3SOIDDvoffGiven) + model->B3SOIDDvoff = -0.08; + if (!model->B3SOIDDdeltaGiven) + model->B3SOIDDdelta = 0.01; + if (!model->B3SOIDDrdswGiven) + model->B3SOIDDrdsw = 100; + if (!model->B3SOIDDprwgGiven) + model->B3SOIDDprwg = 0.0; /* unit 1/V */ + if (!model->B3SOIDDprwbGiven) + model->B3SOIDDprwb = 0.0; + if (!model->B3SOIDDprtGiven) + if (!model->B3SOIDDprtGiven) + model->B3SOIDDprt = 0.0; + if (!model->B3SOIDDeta0Given) + model->B3SOIDDeta0 = 0.08; /* no unit */ + if (!model->B3SOIDDetabGiven) + model->B3SOIDDetab = -0.07; /* unit 1/V */ + if (!model->B3SOIDDpclmGiven) + model->B3SOIDDpclm = 1.3; /* no unit */ + if (!model->B3SOIDDpdibl1Given) + model->B3SOIDDpdibl1 = .39; /* no unit */ + if (!model->B3SOIDDpdibl2Given) + model->B3SOIDDpdibl2 = 0.0086; /* no unit */ + if (!model->B3SOIDDpdiblbGiven) + model->B3SOIDDpdiblb = 0.0; /* 1/V */ + if (!model->B3SOIDDpvagGiven) + model->B3SOIDDpvag = 0.0; + if (!model->B3SOIDDwrGiven) + model->B3SOIDDwr = 1.0; + if (!model->B3SOIDDdwgGiven) + model->B3SOIDDdwg = 0.0; + if (!model->B3SOIDDdwbGiven) + model->B3SOIDDdwb = 0.0; + if (!model->B3SOIDDb0Given) + model->B3SOIDDb0 = 0.0; + if (!model->B3SOIDDb1Given) + model->B3SOIDDb1 = 0.0; + if (!model->B3SOIDDalpha0Given) + model->B3SOIDDalpha0 = 0.0; + if (!model->B3SOIDDalpha1Given) + model->B3SOIDDalpha1 = 1.0; + if (!model->B3SOIDDbeta0Given) + model->B3SOIDDbeta0 = 30.0; + + if (!model->B3SOIDDcgslGiven) + model->B3SOIDDcgsl = 0.0; + if (!model->B3SOIDDcgdlGiven) + model->B3SOIDDcgdl = 0.0; + if (!model->B3SOIDDckappaGiven) + model->B3SOIDDckappa = 0.6; + if (!model->B3SOIDDclcGiven) + model->B3SOIDDclc = 0.1e-7; + if (!model->B3SOIDDcleGiven) + model->B3SOIDDcle = 0.0; + if (!model->B3SOIDDtboxGiven) + model->B3SOIDDtbox = 3e-7; + if (!model->B3SOIDDtsiGiven) + model->B3SOIDDtsi = 1e-7; + if (!model->B3SOIDDxjGiven) + model->B3SOIDDxj = model->B3SOIDDtsi; + if (!model->B3SOIDDkb1Given) + model->B3SOIDDkb1 = 1; + if (!model->B3SOIDDkb3Given) + model->B3SOIDDkb3 = 1; + if (!model->B3SOIDDdvbd0Given) + model->B3SOIDDdvbd0 = 0.0; + if (!model->B3SOIDDdvbd1Given) + model->B3SOIDDdvbd1 = 0.0; + if (!model->B3SOIDDvbsaGiven) + model->B3SOIDDvbsa = 0.0; + if (!model->B3SOIDDdelpGiven) + model->B3SOIDDdelp = 0.02; + if (!model->B3SOIDDrbodyGiven) + model->B3SOIDDrbody = 0.0; + if (!model->B3SOIDDrbshGiven) + model->B3SOIDDrbsh = 0.0; + if (!model->B3SOIDDadice0Given) + model->B3SOIDDadice0 = 1; + if (!model->B3SOIDDabpGiven) + model->B3SOIDDabp = 1; + if (!model->B3SOIDDmxcGiven) + model->B3SOIDDmxc = -0.9; + if (!model->B3SOIDDrth0Given) + model->B3SOIDDrth0 = 0; + if (!model->B3SOIDDcth0Given) + model->B3SOIDDcth0 = 0; + + if (!model->B3SOIDDaiiGiven) + model->B3SOIDDaii = 0.0; + if (!model->B3SOIDDbiiGiven) + model->B3SOIDDbii = 0.0; + if (!model->B3SOIDDciiGiven) + model->B3SOIDDcii = 0.0; + if (!model->B3SOIDDdiiGiven) + model->B3SOIDDdii = -1.0; + if (!model->B3SOIDDagidlGiven) + model->B3SOIDDagidl = 0.0; + if (!model->B3SOIDDbgidlGiven) + model->B3SOIDDbgidl = 0.0; + if (!model->B3SOIDDngidlGiven) + model->B3SOIDDngidl = 1.2; + if (!model->B3SOIDDndiodeGiven) + model->B3SOIDDndiode = 1.0; + if (!model->B3SOIDDntunGiven) + model->B3SOIDDntun = 10.0; + if (!model->B3SOIDDisbjtGiven) + model->B3SOIDDisbjt = 1e-6; + if (!model->B3SOIDDisdifGiven) + model->B3SOIDDisdif = 0.0; + if (!model->B3SOIDDisrecGiven) + model->B3SOIDDisrec = 1e-5; + if (!model->B3SOIDDistunGiven) + model->B3SOIDDistun = 0.0; + if (!model->B3SOIDDxbjtGiven) + model->B3SOIDDxbjt = 2; + if (!model->B3SOIDDxdifGiven) + model->B3SOIDDxdif = 2; + if (!model->B3SOIDDxrecGiven) + model->B3SOIDDxrec = 20; + if (!model->B3SOIDDxtunGiven) + model->B3SOIDDxtun = 0; + if (!model->B3SOIDDedlGiven) + model->B3SOIDDedl = 2e-6; + if (!model->B3SOIDDkbjt1Given) + model->B3SOIDDkbjt1 = 0; + if (!model->B3SOIDDttGiven) + model->B3SOIDDtt = 1e-12; + if (!model->B3SOIDDasdGiven) + model->B3SOIDDasd = 0.3; + + /* unit degree celcius */ + if (!model->B3SOIDDtnomGiven) + model->B3SOIDDtnom = ckt->CKTnomTemp; + if (!model->B3SOIDDLintGiven) + model->B3SOIDDLint = 0.0; + if (!model->B3SOIDDLlGiven) + model->B3SOIDDLl = 0.0; + if (!model->B3SOIDDLlnGiven) + model->B3SOIDDLln = 1.0; + if (!model->B3SOIDDLwGiven) + model->B3SOIDDLw = 0.0; + if (!model->B3SOIDDLwnGiven) + model->B3SOIDDLwn = 1.0; + if (!model->B3SOIDDLwlGiven) + model->B3SOIDDLwl = 0.0; + if (!model->B3SOIDDLminGiven) + model->B3SOIDDLmin = 0.0; + if (!model->B3SOIDDLmaxGiven) + model->B3SOIDDLmax = 1.0; + if (!model->B3SOIDDWintGiven) + model->B3SOIDDWint = 0.0; + if (!model->B3SOIDDWlGiven) + model->B3SOIDDWl = 0.0; + if (!model->B3SOIDDWlnGiven) + model->B3SOIDDWln = 1.0; + if (!model->B3SOIDDWwGiven) + model->B3SOIDDWw = 0.0; + if (!model->B3SOIDDWwnGiven) + model->B3SOIDDWwn = 1.0; + if (!model->B3SOIDDWwlGiven) + model->B3SOIDDWwl = 0.0; + if (!model->B3SOIDDWminGiven) + model->B3SOIDDWmin = 0.0; + if (!model->B3SOIDDWmaxGiven) + model->B3SOIDDWmax = 1.0; + if (!model->B3SOIDDdwcGiven) + model->B3SOIDDdwc = model->B3SOIDDWint; + if (!model->B3SOIDDdlcGiven) + model->B3SOIDDdlc = model->B3SOIDDLint; + +/* Added for binning - START */ + /* Length dependence */ + if (!model->B3SOIDDlnpeakGiven) + model->B3SOIDDlnpeak = 0.0; + if (!model->B3SOIDDlnsubGiven) + model->B3SOIDDlnsub = 0.0; + if (!model->B3SOIDDlngateGiven) + model->B3SOIDDlngate = 0.0; + if (!model->B3SOIDDlvth0Given) + model->B3SOIDDlvth0 = 0.0; + if (!model->B3SOIDDlk1Given) + model->B3SOIDDlk1 = 0.0; + if (!model->B3SOIDDlk2Given) + model->B3SOIDDlk2 = 0.0; + if (!model->B3SOIDDlk3Given) + model->B3SOIDDlk3 = 0.0; + if (!model->B3SOIDDlk3bGiven) + model->B3SOIDDlk3b = 0.0; + if (!model->B3SOIDDlvbsaGiven) + model->B3SOIDDlvbsa = 0.0; + if (!model->B3SOIDDldelpGiven) + model->B3SOIDDldelp = 0.0; + if (!model->B3SOIDDlkb1Given) + model->B3SOIDDlkb1 = 0.0; + if (!model->B3SOIDDlkb3Given) + model->B3SOIDDlkb3 = 1.0; + if (!model->B3SOIDDldvbd0Given) + model->B3SOIDDldvbd0 = 1.0; + if (!model->B3SOIDDldvbd1Given) + model->B3SOIDDldvbd1 = 1.0; + if (!model->B3SOIDDlw0Given) + model->B3SOIDDlw0 = 0.0; + if (!model->B3SOIDDlnlxGiven) + model->B3SOIDDlnlx = 0.0; + if (!model->B3SOIDDldvt0Given) + model->B3SOIDDldvt0 = 0.0; + if (!model->B3SOIDDldvt1Given) + model->B3SOIDDldvt1 = 0.0; + if (!model->B3SOIDDldvt2Given) + model->B3SOIDDldvt2 = 0.0; + if (!model->B3SOIDDldvt0wGiven) + model->B3SOIDDldvt0w = 0.0; + if (!model->B3SOIDDldvt1wGiven) + model->B3SOIDDldvt1w = 0.0; + if (!model->B3SOIDDldvt2wGiven) + model->B3SOIDDldvt2w = 0.0; + if (!model->B3SOIDDlu0Given) + model->B3SOIDDlu0 = 0.0; + if (!model->B3SOIDDluaGiven) + model->B3SOIDDlua = 0.0; + if (!model->B3SOIDDlubGiven) + model->B3SOIDDlub = 0.0; + if (!model->B3SOIDDlucGiven) + model->B3SOIDDluc = 0.0; + if (!model->B3SOIDDlvsatGiven) + model->B3SOIDDlvsat = 0.0; + if (!model->B3SOIDDla0Given) + model->B3SOIDDla0 = 0.0; + if (!model->B3SOIDDlagsGiven) + model->B3SOIDDlags = 0.0; + if (!model->B3SOIDDlb0Given) + model->B3SOIDDlb0 = 0.0; + if (!model->B3SOIDDlb1Given) + model->B3SOIDDlb1 = 0.0; + if (!model->B3SOIDDlketaGiven) + model->B3SOIDDlketa = 0.0; + if (!model->B3SOIDDlabpGiven) + model->B3SOIDDlabp = 0.0; + if (!model->B3SOIDDlmxcGiven) + model->B3SOIDDlmxc = 0.0; + if (!model->B3SOIDDladice0Given) + model->B3SOIDDladice0 = 0.0; + if (!model->B3SOIDDla1Given) + model->B3SOIDDla1 = 0.0; + if (!model->B3SOIDDla2Given) + model->B3SOIDDla2 = 0.0; + if (!model->B3SOIDDlrdswGiven) + model->B3SOIDDlrdsw = 0.0; + if (!model->B3SOIDDlprwbGiven) + model->B3SOIDDlprwb = 0.0; + if (!model->B3SOIDDlprwgGiven) + model->B3SOIDDlprwg = 0.0; + if (!model->B3SOIDDlwrGiven) + model->B3SOIDDlwr = 0.0; + if (!model->B3SOIDDlnfactorGiven) + model->B3SOIDDlnfactor = 0.0; + if (!model->B3SOIDDldwgGiven) + model->B3SOIDDldwg = 0.0; + if (!model->B3SOIDDldwbGiven) + model->B3SOIDDldwb = 0.0; + if (!model->B3SOIDDlvoffGiven) + model->B3SOIDDlvoff = 0.0; + if (!model->B3SOIDDleta0Given) + model->B3SOIDDleta0 = 0.0; + if (!model->B3SOIDDletabGiven) + model->B3SOIDDletab = 0.0; + if (!model->B3SOIDDldsubGiven) + model->B3SOIDDldsub = 0.0; + if (!model->B3SOIDDlcitGiven) + model->B3SOIDDlcit = 0.0; + if (!model->B3SOIDDlcdscGiven) + model->B3SOIDDlcdsc = 0.0; + if (!model->B3SOIDDlcdscbGiven) + model->B3SOIDDlcdscb = 0.0; + if (!model->B3SOIDDlcdscdGiven) + model->B3SOIDDlcdscd = 0.0; + if (!model->B3SOIDDlpclmGiven) + model->B3SOIDDlpclm = 0.0; + if (!model->B3SOIDDlpdibl1Given) + model->B3SOIDDlpdibl1 = 0.0; + if (!model->B3SOIDDlpdibl2Given) + model->B3SOIDDlpdibl2 = 0.0; + if (!model->B3SOIDDlpdiblbGiven) + model->B3SOIDDlpdiblb = 0.0; + if (!model->B3SOIDDldroutGiven) + model->B3SOIDDldrout = 0.0; + if (!model->B3SOIDDlpvagGiven) + model->B3SOIDDlpvag = 0.0; + if (!model->B3SOIDDldeltaGiven) + model->B3SOIDDldelta = 0.0; + if (!model->B3SOIDDlaiiGiven) + model->B3SOIDDlaii = 0.0; + if (!model->B3SOIDDlbiiGiven) + model->B3SOIDDlbii = 0.0; + if (!model->B3SOIDDlciiGiven) + model->B3SOIDDlcii = 0.0; + if (!model->B3SOIDDldiiGiven) + model->B3SOIDDldii = 0.0; + if (!model->B3SOIDDlalpha0Given) + model->B3SOIDDlalpha0 = 0.0; + if (!model->B3SOIDDlalpha1Given) + model->B3SOIDDlalpha1 = 0.0; + if (!model->B3SOIDDlbeta0Given) + model->B3SOIDDlbeta0 = 0.0; + if (!model->B3SOIDDlagidlGiven) + model->B3SOIDDlagidl = 0.0; + if (!model->B3SOIDDlbgidlGiven) + model->B3SOIDDlbgidl = 0.0; + if (!model->B3SOIDDlngidlGiven) + model->B3SOIDDlngidl = 0.0; + if (!model->B3SOIDDlntunGiven) + model->B3SOIDDlntun = 0.0; + if (!model->B3SOIDDlndiodeGiven) + model->B3SOIDDlndiode = 0.0; + if (!model->B3SOIDDlisbjtGiven) + model->B3SOIDDlisbjt = 0.0; + if (!model->B3SOIDDlisdifGiven) + model->B3SOIDDlisdif = 0.0; + if (!model->B3SOIDDlisrecGiven) + model->B3SOIDDlisrec = 0.0; + if (!model->B3SOIDDlistunGiven) + model->B3SOIDDlistun = 0.0; + if (!model->B3SOIDDledlGiven) + model->B3SOIDDledl = 0.0; + if (!model->B3SOIDDlkbjt1Given) + model->B3SOIDDlkbjt1 = 0.0; + /* CV Model */ + if (!model->B3SOIDDlvsdfbGiven) + model->B3SOIDDlvsdfb = 0.0; + if (!model->B3SOIDDlvsdthGiven) + model->B3SOIDDlvsdth = 0.0; + /* Width dependence */ + if (!model->B3SOIDDwnpeakGiven) + model->B3SOIDDwnpeak = 0.0; + if (!model->B3SOIDDwnsubGiven) + model->B3SOIDDwnsub = 0.0; + if (!model->B3SOIDDwngateGiven) + model->B3SOIDDwngate = 0.0; + if (!model->B3SOIDDwvth0Given) + model->B3SOIDDwvth0 = 0.0; + if (!model->B3SOIDDwk1Given) + model->B3SOIDDwk1 = 0.0; + if (!model->B3SOIDDwk2Given) + model->B3SOIDDwk2 = 0.0; + if (!model->B3SOIDDwk3Given) + model->B3SOIDDwk3 = 0.0; + if (!model->B3SOIDDwk3bGiven) + model->B3SOIDDwk3b = 0.0; + if (!model->B3SOIDDwvbsaGiven) + model->B3SOIDDwvbsa = 0.0; + if (!model->B3SOIDDwdelpGiven) + model->B3SOIDDwdelp = 0.0; + if (!model->B3SOIDDwkb1Given) + model->B3SOIDDwkb1 = 0.0; + if (!model->B3SOIDDwkb3Given) + model->B3SOIDDwkb3 = 1.0; + if (!model->B3SOIDDwdvbd0Given) + model->B3SOIDDwdvbd0 = 1.0; + if (!model->B3SOIDDwdvbd1Given) + model->B3SOIDDwdvbd1 = 1.0; + if (!model->B3SOIDDww0Given) + model->B3SOIDDww0 = 0.0; + if (!model->B3SOIDDwnlxGiven) + model->B3SOIDDwnlx = 0.0; + if (!model->B3SOIDDwdvt0Given) + model->B3SOIDDwdvt0 = 0.0; + if (!model->B3SOIDDwdvt1Given) + model->B3SOIDDwdvt1 = 0.0; + if (!model->B3SOIDDwdvt2Given) + model->B3SOIDDwdvt2 = 0.0; + if (!model->B3SOIDDwdvt0wGiven) + model->B3SOIDDwdvt0w = 0.0; + if (!model->B3SOIDDwdvt1wGiven) + model->B3SOIDDwdvt1w = 0.0; + if (!model->B3SOIDDwdvt2wGiven) + model->B3SOIDDwdvt2w = 0.0; + if (!model->B3SOIDDwu0Given) + model->B3SOIDDwu0 = 0.0; + if (!model->B3SOIDDwuaGiven) + model->B3SOIDDwua = 0.0; + if (!model->B3SOIDDwubGiven) + model->B3SOIDDwub = 0.0; + if (!model->B3SOIDDwucGiven) + model->B3SOIDDwuc = 0.0; + if (!model->B3SOIDDwvsatGiven) + model->B3SOIDDwvsat = 0.0; + if (!model->B3SOIDDwa0Given) + model->B3SOIDDwa0 = 0.0; + if (!model->B3SOIDDwagsGiven) + model->B3SOIDDwags = 0.0; + if (!model->B3SOIDDwb0Given) + model->B3SOIDDwb0 = 0.0; + if (!model->B3SOIDDwb1Given) + model->B3SOIDDwb1 = 0.0; + if (!model->B3SOIDDwketaGiven) + model->B3SOIDDwketa = 0.0; + if (!model->B3SOIDDwabpGiven) + model->B3SOIDDwabp = 0.0; + if (!model->B3SOIDDwmxcGiven) + model->B3SOIDDwmxc = 0.0; + if (!model->B3SOIDDwadice0Given) + model->B3SOIDDwadice0 = 0.0; + if (!model->B3SOIDDwa1Given) + model->B3SOIDDwa1 = 0.0; + if (!model->B3SOIDDwa2Given) + model->B3SOIDDwa2 = 0.0; + if (!model->B3SOIDDwrdswGiven) + model->B3SOIDDwrdsw = 0.0; + if (!model->B3SOIDDwprwbGiven) + model->B3SOIDDwprwb = 0.0; + if (!model->B3SOIDDwprwgGiven) + model->B3SOIDDwprwg = 0.0; + if (!model->B3SOIDDwwrGiven) + model->B3SOIDDwwr = 0.0; + if (!model->B3SOIDDwnfactorGiven) + model->B3SOIDDwnfactor = 0.0; + if (!model->B3SOIDDwdwgGiven) + model->B3SOIDDwdwg = 0.0; + if (!model->B3SOIDDwdwbGiven) + model->B3SOIDDwdwb = 0.0; + if (!model->B3SOIDDwvoffGiven) + model->B3SOIDDwvoff = 0.0; + if (!model->B3SOIDDweta0Given) + model->B3SOIDDweta0 = 0.0; + if (!model->B3SOIDDwetabGiven) + model->B3SOIDDwetab = 0.0; + if (!model->B3SOIDDwdsubGiven) + model->B3SOIDDwdsub = 0.0; + if (!model->B3SOIDDwcitGiven) + model->B3SOIDDwcit = 0.0; + if (!model->B3SOIDDwcdscGiven) + model->B3SOIDDwcdsc = 0.0; + if (!model->B3SOIDDwcdscbGiven) + model->B3SOIDDwcdscb = 0.0; + if (!model->B3SOIDDwcdscdGiven) + model->B3SOIDDwcdscd = 0.0; + if (!model->B3SOIDDwpclmGiven) + model->B3SOIDDwpclm = 0.0; + if (!model->B3SOIDDwpdibl1Given) + model->B3SOIDDwpdibl1 = 0.0; + if (!model->B3SOIDDwpdibl2Given) + model->B3SOIDDwpdibl2 = 0.0; + if (!model->B3SOIDDwpdiblbGiven) + model->B3SOIDDwpdiblb = 0.0; + if (!model->B3SOIDDwdroutGiven) + model->B3SOIDDwdrout = 0.0; + if (!model->B3SOIDDwpvagGiven) + model->B3SOIDDwpvag = 0.0; + if (!model->B3SOIDDwdeltaGiven) + model->B3SOIDDwdelta = 0.0; + if (!model->B3SOIDDwaiiGiven) + model->B3SOIDDwaii = 0.0; + if (!model->B3SOIDDwbiiGiven) + model->B3SOIDDwbii = 0.0; + if (!model->B3SOIDDwciiGiven) + model->B3SOIDDwcii = 0.0; + if (!model->B3SOIDDwdiiGiven) + model->B3SOIDDwdii = 0.0; + if (!model->B3SOIDDwalpha0Given) + model->B3SOIDDwalpha0 = 0.0; + if (!model->B3SOIDDwalpha1Given) + model->B3SOIDDwalpha1 = 0.0; + if (!model->B3SOIDDwbeta0Given) + model->B3SOIDDwbeta0 = 0.0; + if (!model->B3SOIDDwagidlGiven) + model->B3SOIDDwagidl = 0.0; + if (!model->B3SOIDDwbgidlGiven) + model->B3SOIDDwbgidl = 0.0; + if (!model->B3SOIDDwngidlGiven) + model->B3SOIDDwngidl = 0.0; + if (!model->B3SOIDDwntunGiven) + model->B3SOIDDwntun = 0.0; + if (!model->B3SOIDDwndiodeGiven) + model->B3SOIDDwndiode = 0.0; + if (!model->B3SOIDDwisbjtGiven) + model->B3SOIDDwisbjt = 0.0; + if (!model->B3SOIDDwisdifGiven) + model->B3SOIDDwisdif = 0.0; + if (!model->B3SOIDDwisrecGiven) + model->B3SOIDDwisrec = 0.0; + if (!model->B3SOIDDwistunGiven) + model->B3SOIDDwistun = 0.0; + if (!model->B3SOIDDwedlGiven) + model->B3SOIDDwedl = 0.0; + if (!model->B3SOIDDwkbjt1Given) + model->B3SOIDDwkbjt1 = 0.0; + /* CV Model */ + if (!model->B3SOIDDwvsdfbGiven) + model->B3SOIDDwvsdfb = 0.0; + if (!model->B3SOIDDwvsdthGiven) + model->B3SOIDDwvsdth = 0.0; + /* Cross-term dependence */ + if (!model->B3SOIDDpnpeakGiven) + model->B3SOIDDpnpeak = 0.0; + if (!model->B3SOIDDpnsubGiven) + model->B3SOIDDpnsub = 0.0; + if (!model->B3SOIDDpngateGiven) + model->B3SOIDDpngate = 0.0; + if (!model->B3SOIDDpvth0Given) + model->B3SOIDDpvth0 = 0.0; + if (!model->B3SOIDDpk1Given) + model->B3SOIDDpk1 = 0.0; + if (!model->B3SOIDDpk2Given) + model->B3SOIDDpk2 = 0.0; + if (!model->B3SOIDDpk3Given) + model->B3SOIDDpk3 = 0.0; + if (!model->B3SOIDDpk3bGiven) + model->B3SOIDDpk3b = 0.0; + if (!model->B3SOIDDpvbsaGiven) + model->B3SOIDDpvbsa = 0.0; + if (!model->B3SOIDDpdelpGiven) + model->B3SOIDDpdelp = 0.0; + if (!model->B3SOIDDpkb1Given) + model->B3SOIDDpkb1 = 0.0; + if (!model->B3SOIDDpkb3Given) + model->B3SOIDDpkb3 = 1.0; + if (!model->B3SOIDDpdvbd0Given) + model->B3SOIDDpdvbd0 = 1.0; + if (!model->B3SOIDDpdvbd1Given) + model->B3SOIDDpdvbd1 = 1.0; + if (!model->B3SOIDDpw0Given) + model->B3SOIDDpw0 = 0.0; + if (!model->B3SOIDDpnlxGiven) + model->B3SOIDDpnlx = 0.0; + if (!model->B3SOIDDpdvt0Given) + model->B3SOIDDpdvt0 = 0.0; + if (!model->B3SOIDDpdvt1Given) + model->B3SOIDDpdvt1 = 0.0; + if (!model->B3SOIDDpdvt2Given) + model->B3SOIDDpdvt2 = 0.0; + if (!model->B3SOIDDpdvt0wGiven) + model->B3SOIDDpdvt0w = 0.0; + if (!model->B3SOIDDpdvt1wGiven) + model->B3SOIDDpdvt1w = 0.0; + if (!model->B3SOIDDpdvt2wGiven) + model->B3SOIDDpdvt2w = 0.0; + if (!model->B3SOIDDpu0Given) + model->B3SOIDDpu0 = 0.0; + if (!model->B3SOIDDpuaGiven) + model->B3SOIDDpua = 0.0; + if (!model->B3SOIDDpubGiven) + model->B3SOIDDpub = 0.0; + if (!model->B3SOIDDpucGiven) + model->B3SOIDDpuc = 0.0; + if (!model->B3SOIDDpvsatGiven) + model->B3SOIDDpvsat = 0.0; + if (!model->B3SOIDDpa0Given) + model->B3SOIDDpa0 = 0.0; + if (!model->B3SOIDDpagsGiven) + model->B3SOIDDpags = 0.0; + if (!model->B3SOIDDpb0Given) + model->B3SOIDDpb0 = 0.0; + if (!model->B3SOIDDpb1Given) + model->B3SOIDDpb1 = 0.0; + if (!model->B3SOIDDpketaGiven) + model->B3SOIDDpketa = 0.0; + if (!model->B3SOIDDpabpGiven) + model->B3SOIDDpabp = 0.0; + if (!model->B3SOIDDpmxcGiven) + model->B3SOIDDpmxc = 0.0; + if (!model->B3SOIDDpadice0Given) + model->B3SOIDDpadice0 = 0.0; + if (!model->B3SOIDDpa1Given) + model->B3SOIDDpa1 = 0.0; + if (!model->B3SOIDDpa2Given) + model->B3SOIDDpa2 = 0.0; + if (!model->B3SOIDDprdswGiven) + model->B3SOIDDprdsw = 0.0; + if (!model->B3SOIDDpprwbGiven) + model->B3SOIDDpprwb = 0.0; + if (!model->B3SOIDDpprwgGiven) + model->B3SOIDDpprwg = 0.0; + if (!model->B3SOIDDpwrGiven) + model->B3SOIDDpwr = 0.0; + if (!model->B3SOIDDpnfactorGiven) + model->B3SOIDDpnfactor = 0.0; + if (!model->B3SOIDDpdwgGiven) + model->B3SOIDDpdwg = 0.0; + if (!model->B3SOIDDpdwbGiven) + model->B3SOIDDpdwb = 0.0; + if (!model->B3SOIDDpvoffGiven) + model->B3SOIDDpvoff = 0.0; + if (!model->B3SOIDDpeta0Given) + model->B3SOIDDpeta0 = 0.0; + if (!model->B3SOIDDpetabGiven) + model->B3SOIDDpetab = 0.0; + if (!model->B3SOIDDpdsubGiven) + model->B3SOIDDpdsub = 0.0; + if (!model->B3SOIDDpcitGiven) + model->B3SOIDDpcit = 0.0; + if (!model->B3SOIDDpcdscGiven) + model->B3SOIDDpcdsc = 0.0; + if (!model->B3SOIDDpcdscbGiven) + model->B3SOIDDpcdscb = 0.0; + if (!model->B3SOIDDpcdscdGiven) + model->B3SOIDDpcdscd = 0.0; + if (!model->B3SOIDDppclmGiven) + model->B3SOIDDppclm = 0.0; + if (!model->B3SOIDDppdibl1Given) + model->B3SOIDDppdibl1 = 0.0; + if (!model->B3SOIDDppdibl2Given) + model->B3SOIDDppdibl2 = 0.0; + if (!model->B3SOIDDppdiblbGiven) + model->B3SOIDDppdiblb = 0.0; + if (!model->B3SOIDDpdroutGiven) + model->B3SOIDDpdrout = 0.0; + if (!model->B3SOIDDppvagGiven) + model->B3SOIDDppvag = 0.0; + if (!model->B3SOIDDpdeltaGiven) + model->B3SOIDDpdelta = 0.0; + if (!model->B3SOIDDpaiiGiven) + model->B3SOIDDpaii = 0.0; + if (!model->B3SOIDDpbiiGiven) + model->B3SOIDDpbii = 0.0; + if (!model->B3SOIDDpciiGiven) + model->B3SOIDDpcii = 0.0; + if (!model->B3SOIDDpdiiGiven) + model->B3SOIDDpdii = 0.0; + if (!model->B3SOIDDpalpha0Given) + model->B3SOIDDpalpha0 = 0.0; + if (!model->B3SOIDDpalpha1Given) + model->B3SOIDDpalpha1 = 0.0; + if (!model->B3SOIDDpbeta0Given) + model->B3SOIDDpbeta0 = 0.0; + if (!model->B3SOIDDpagidlGiven) + model->B3SOIDDpagidl = 0.0; + if (!model->B3SOIDDpbgidlGiven) + model->B3SOIDDpbgidl = 0.0; + if (!model->B3SOIDDpngidlGiven) + model->B3SOIDDpngidl = 0.0; + if (!model->B3SOIDDpntunGiven) + model->B3SOIDDpntun = 0.0; + if (!model->B3SOIDDpndiodeGiven) + model->B3SOIDDpndiode = 0.0; + if (!model->B3SOIDDpisbjtGiven) + model->B3SOIDDpisbjt = 0.0; + if (!model->B3SOIDDpisdifGiven) + model->B3SOIDDpisdif = 0.0; + if (!model->B3SOIDDpisrecGiven) + model->B3SOIDDpisrec = 0.0; + if (!model->B3SOIDDpistunGiven) + model->B3SOIDDpistun = 0.0; + if (!model->B3SOIDDpedlGiven) + model->B3SOIDDpedl = 0.0; + if (!model->B3SOIDDpkbjt1Given) + model->B3SOIDDpkbjt1 = 0.0; + /* CV Model */ + if (!model->B3SOIDDpvsdfbGiven) + model->B3SOIDDpvsdfb = 0.0; + if (!model->B3SOIDDpvsdthGiven) + model->B3SOIDDpvsdth = 0.0; +/* Added for binning - END */ + + if (!model->B3SOIDDcfGiven) + model->B3SOIDDcf = 2.0 * EPSOX / PI + * log(1.0 + 0.4e-6 / model->B3SOIDDtox); + if (!model->B3SOIDDcgdoGiven) + { if (model->B3SOIDDdlcGiven && (model->B3SOIDDdlc > 0.0)) + { model->B3SOIDDcgdo = model->B3SOIDDdlc * model->B3SOIDDcox + - model->B3SOIDDcgdl ; + } + else + model->B3SOIDDcgdo = 0.6 * model->B3SOIDDxj * model->B3SOIDDcox; + } + if (!model->B3SOIDDcgsoGiven) + { if (model->B3SOIDDdlcGiven && (model->B3SOIDDdlc > 0.0)) + { model->B3SOIDDcgso = model->B3SOIDDdlc * model->B3SOIDDcox + - model->B3SOIDDcgsl ; + } + else + model->B3SOIDDcgso = 0.6 * model->B3SOIDDxj * model->B3SOIDDcox; + } + + if (!model->B3SOIDDcgeoGiven) + { model->B3SOIDDcgeo = 0.0; + } + if (!model->B3SOIDDxpartGiven) + model->B3SOIDDxpart = 0.0; + if (!model->B3SOIDDsheetResistanceGiven) + model->B3SOIDDsheetResistance = 0.0; + if (!model->B3SOIDDcsdeswGiven) + model->B3SOIDDcsdesw = 0.0; + if (!model->B3SOIDDunitLengthGateSidewallJctCapGiven) + model->B3SOIDDunitLengthGateSidewallJctCap = 1e-10; + if (!model->B3SOIDDGatesidewallJctPotentialGiven) + model->B3SOIDDGatesidewallJctPotential = 0.7; + if (!model->B3SOIDDbodyJctGateSideGradingCoeffGiven) + model->B3SOIDDbodyJctGateSideGradingCoeff = 0.5; + if (!model->B3SOIDDoxideTrapDensityAGiven) + { if (model->B3SOIDDtype == NMOS) + model->B3SOIDDoxideTrapDensityA = 1e20; + else + model->B3SOIDDoxideTrapDensityA=9.9e18; + } + if (!model->B3SOIDDoxideTrapDensityBGiven) + { if (model->B3SOIDDtype == NMOS) + model->B3SOIDDoxideTrapDensityB = 5e4; + else + model->B3SOIDDoxideTrapDensityB = 2.4e3; + } + if (!model->B3SOIDDoxideTrapDensityCGiven) + { if (model->B3SOIDDtype == NMOS) + model->B3SOIDDoxideTrapDensityC = -1.4e-12; + else + model->B3SOIDDoxideTrapDensityC = 1.4e-12; + + } + if (!model->B3SOIDDemGiven) + model->B3SOIDDem = 4.1e7; /* V/m */ + if (!model->B3SOIDDefGiven) + model->B3SOIDDef = 1.0; + if (!model->B3SOIDDafGiven) + model->B3SOIDDaf = 1.0; + if (!model->B3SOIDDkfGiven) + model->B3SOIDDkf = 0.0; + if (!model->B3SOIDDnoifGiven) + model->B3SOIDDnoif = 1.0; + + /* loop through all the instances of the model */ + for (here = model->B3SOIDDinstances; here != NULL ; + here=here->B3SOIDDnextInstance) + { /* allocate a chunk of the state vector */ + here->B3SOIDDstates = *states; + *states += B3SOIDDnumStates; + /* perform the parameter defaulting */ + if (!here->B3SOIDDdrainAreaGiven) + here->B3SOIDDdrainArea = 0.0; + if (!here->B3SOIDDdrainPerimeterGiven) + here->B3SOIDDdrainPerimeter = 0.0; + if (!here->B3SOIDDdrainSquaresGiven) + here->B3SOIDDdrainSquares = 1.0; + if (!here->B3SOIDDicVBSGiven) + here->B3SOIDDicVBS = 0; + if (!here->B3SOIDDicVDSGiven) + here->B3SOIDDicVDS = 0; + if (!here->B3SOIDDicVGSGiven) + here->B3SOIDDicVGS = 0; + if (!here->B3SOIDDicVESGiven) + here->B3SOIDDicVES = 0; + if (!here->B3SOIDDicVPSGiven) + here->B3SOIDDicVPS = 0; + if (!here->B3SOIDDbjtoffGiven) + here->B3SOIDDbjtoff = 0; + if (!here->B3SOIDDdebugModGiven) + here->B3SOIDDdebugMod = 0; + if (!here->B3SOIDDrth0Given) + here->B3SOIDDrth0 = model->B3SOIDDrth0; + if (!here->B3SOIDDcth0Given) + here->B3SOIDDcth0 = model->B3SOIDDcth0; + if (!here->B3SOIDDbodySquaresGiven) + here->B3SOIDDbodySquares = 1.0; + if (!here->B3SOIDDlGiven) + here->B3SOIDDl = 5e-6; + if (!here->B3SOIDDsourceAreaGiven) + here->B3SOIDDsourceArea = 0; + if (!here->B3SOIDDsourcePerimeterGiven) + here->B3SOIDDsourcePerimeter = 0; + if (!here->B3SOIDDsourceSquaresGiven) + here->B3SOIDDsourceSquares = 1; + if (!here->B3SOIDDwGiven) + here->B3SOIDDw = 5e-6; + if (!here->B3SOIDDoffGiven) + here->B3SOIDDoff = 0; + + /* process drain series resistance */ + if ((model->B3SOIDDsheetResistance > 0.0) && + (here->B3SOIDDdrainSquares > 0.0 ) && + (here->B3SOIDDdNodePrime == 0)) + { error = CKTmkVolt(ckt,&tmp,here->B3SOIDDname,"drain"); + if(error) return(error); + here->B3SOIDDdNodePrime = tmp->number; + } + else + { here->B3SOIDDdNodePrime = here->B3SOIDDdNode; + } + + /* process source series resistance */ + if ((model->B3SOIDDsheetResistance > 0.0) && + (here->B3SOIDDsourceSquares > 0.0 ) && + (here->B3SOIDDsNodePrime == 0)) + { error = CKTmkVolt(ckt,&tmp,here->B3SOIDDname,"source"); + if(error) return(error); + here->B3SOIDDsNodePrime = tmp->number; + } + else + { here->B3SOIDDsNodePrime = here->B3SOIDDsNode; + } + + /* process effective silicon film thickness */ + model->B3SOIDDcbox = 3.453133e-11 / model->B3SOIDDtbox; + model->B3SOIDDcsi = 1.03594e-10 / model->B3SOIDDtsi; + Cboxt = model->B3SOIDDcbox * model->B3SOIDDcsi / (model->B3SOIDDcbox + model->B3SOIDDcsi); + model->B3SOIDDqsi = Charge_q*model->B3SOIDDnpeak*1e6*model->B3SOIDDtsi; + /* Tsieff */ + tmp1 = 2.0 * EPSSI * model->B3SOIDDvbsa / Charge_q + / (1e6*model->B3SOIDDnpeak); + tmp2 = model->B3SOIDDtsi * model->B3SOIDDtsi; + if (tmp2 < tmp1) + { + fprintf(stderr, "vbsa = %.3f is too large for this tsi = %.3e and is automatically set to zero\n", model->B3SOIDDvbsa, model->B3SOIDDtsi); + model->B3SOIDDcsieff = model->B3SOIDDcsi; + model->B3SOIDDqsieff = model->B3SOIDDqsi; + } + else + { + tmp1 = sqrt(model->B3SOIDDtsi * model->B3SOIDDtsi - + 2.0 * EPSSI * model->B3SOIDDvbsa / Charge_q / + (1e6*model->B3SOIDDnpeak)); + model->B3SOIDDcsieff = 1.03594e-10 / tmp1; + model->B3SOIDDqsieff = Charge_q*model->B3SOIDDnpeak*1e6*tmp1; + } + model->B3SOIDDcsit = 1/(1/model->B3SOIDDcox + 1/model->B3SOIDDcsieff); + model->B3SOIDDcboxt = 1/(1/model->B3SOIDDcbox + 1/model->B3SOIDDcsieff); + nfb0 = 1/(1 + model->B3SOIDDcbox / model->B3SOIDDcsit); + model->B3SOIDDnfb = model->B3SOIDDkb3 * nfb0; + model->B3SOIDDadice = model->B3SOIDDadice0 / ( 1 + Cboxt / model->B3SOIDDcox); + + here->B3SOIDDfloat = 0; + if (here->B3SOIDDbNode == -1) + /* no body contact but bNode to be created for SPICE iteration */ + { error = CKTmkVolt(ckt,&tmp,here->B3SOIDDname,"Body"); + if(error) return(error); + here->B3SOIDDbNode = tmp->number; + here->B3SOIDDpNode = 0; + here->B3SOIDDfloat = 1; + here->B3SOIDDbodyMod = 0; + } + else /* if body tied */ + { /* ideal body tie */ + if ((model->B3SOIDDrbody == 0.0) && (model->B3SOIDDrbsh == 0.0)) + { + here->B3SOIDDbodyMod = 2; + /* pNode is not used in this case */ + } + else { + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Body"); + if(error) return(error); + here->B3SOIDDbodyMod = 1; + here->B3SOIDDpNode = here->B3SOIDDbNode; + here->B3SOIDDbNode = tmp->number; + } + } + + if ((model->B3SOIDDshMod == 1) && (here->B3SOIDDrth0!=0)) + { + error = CKTmkVolt(ckt,&tmp,here->B3SOIDDname,"Temp"); + if(error) return(error); + here->B3SOIDDtempNode = tmp->number; + + } else { + here->B3SOIDDtempNode = 0; + } + +/* here for debugging purpose only */ + if ((here->B3SOIDDdebugMod > 1) || (here->B3SOIDDdebugMod == -1)) + { + /* The real Vbs value */ + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Vbs"); + if(error) return(error); + here->B3SOIDDvbsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Ids"); + if(error) return(error); + here->B3SOIDDidsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Ic"); + if(error) return(error); + here->B3SOIDDicNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Ibs"); + if(error) return(error); + here->B3SOIDDibsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Ibd"); + if(error) return(error); + here->B3SOIDDibdNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Iii"); + if(error) return(error); + here->B3SOIDDiiiNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Igidl"); + if(error) return(error); + here->B3SOIDDigidlNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Itun"); + if(error) return(error); + here->B3SOIDDitunNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Ibp"); + if(error) return(error); + here->B3SOIDDibpNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Abeff"); + if(error) return(error); + here->B3SOIDDabeffNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Vbs0eff"); + if(error) return(error); + here->B3SOIDDvbs0effNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Vbseff"); + if(error) return(error); + here->B3SOIDDvbseffNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Xc"); + if(error) return(error); + here->B3SOIDDxcNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Cbb"); + if(error) return(error); + here->B3SOIDDcbbNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Cbd"); + if(error) return(error); + here->B3SOIDDcbdNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Cbg"); + if(error) return(error); + here->B3SOIDDcbgNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qbody"); + if(error) return(error); + here->B3SOIDDqbNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qbf"); + if(error) return(error); + here->B3SOIDDqbfNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qjs"); + if(error) return(error); + here->B3SOIDDqjsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qjd"); + if(error) return(error); + here->B3SOIDDqjdNode = tmp->number; + + /* clean up last */ + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Gm"); + if(error) return(error); + here->B3SOIDDgmNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Gmbs"); + if(error) return(error); + here->B3SOIDDgmbsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Gds"); + if(error) return(error); + here->B3SOIDDgdsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Gme"); + if(error) return(error); + here->B3SOIDDgmeNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Vbs0teff"); + if(error) return(error); + here->B3SOIDDvbs0teffNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Vth"); + if(error) return(error); + here->B3SOIDDvthNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Vgsteff"); + if(error) return(error); + here->B3SOIDDvgsteffNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Xcsat"); + if(error) return(error); + here->B3SOIDDxcsatNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qac0"); + if(error) return(error); + here->B3SOIDDqaccNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qsub0"); + if(error) return(error); + here->B3SOIDDqsub0Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qsubs1"); + if(error) return(error); + here->B3SOIDDqsubs1Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qsubs2"); + if(error) return(error); + here->B3SOIDDqsubs2Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qsub"); + if(error) return(error); + here->B3SOIDDqeNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qdrn"); + if(error) return(error); + here->B3SOIDDqdNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qgate"); + if(error) return(error); + here->B3SOIDDqgNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Vdscv"); + if(error) return(error); + here->B3SOIDDvdscvNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Vcscv"); + if(error) return(error); + here->B3SOIDDvcscvNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Cbe"); + if(error) return(error); + here->B3SOIDDcbeNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Dum1"); + if(error) return(error); + here->B3SOIDDdum1Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Dum2"); + if(error) return(error); + here->B3SOIDDdum2Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Dum3"); + if(error) return(error); + here->B3SOIDDdum3Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Dum4"); + if(error) return(error); + here->B3SOIDDdum4Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Dum5"); + if(error) return(error); + here->B3SOIDDdum5Node = tmp->number; + } + + /* set Sparse Matrix Pointers */ + +/* macro to make elements with built in test for out of memory */ +#define TSTALLOC(ptr,first,second) \ +if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ + return(E_NOMEM);\ +} + + + if ((model->B3SOIDDshMod == 1) && (here->B3SOIDDrth0!=0.0)) { + TSTALLOC(B3SOIDDTemptempPtr, B3SOIDDtempNode, B3SOIDDtempNode) + TSTALLOC(B3SOIDDTempdpPtr, B3SOIDDtempNode, B3SOIDDdNodePrime) + TSTALLOC(B3SOIDDTempspPtr, B3SOIDDtempNode, B3SOIDDsNodePrime) + TSTALLOC(B3SOIDDTempgPtr, B3SOIDDtempNode, B3SOIDDgNode) + TSTALLOC(B3SOIDDTempbPtr, B3SOIDDtempNode, B3SOIDDbNode) + TSTALLOC(B3SOIDDTempePtr, B3SOIDDtempNode, B3SOIDDeNode) + + TSTALLOC(B3SOIDDGtempPtr, B3SOIDDgNode, B3SOIDDtempNode) + TSTALLOC(B3SOIDDDPtempPtr, B3SOIDDdNodePrime, B3SOIDDtempNode) + TSTALLOC(B3SOIDDSPtempPtr, B3SOIDDsNodePrime, B3SOIDDtempNode) + TSTALLOC(B3SOIDDEtempPtr, B3SOIDDeNode, B3SOIDDtempNode) + TSTALLOC(B3SOIDDBtempPtr, B3SOIDDbNode, B3SOIDDtempNode) + + if (here->B3SOIDDbodyMod == 1) { + TSTALLOC(B3SOIDDPtempPtr, B3SOIDDpNode, B3SOIDDtempNode) + } + } + if (here->B3SOIDDbodyMod == 2) { + /* Don't create any Jacobian entry for pNode */ + } + else if (here->B3SOIDDbodyMod == 1) { + TSTALLOC(B3SOIDDBpPtr, B3SOIDDbNode, B3SOIDDpNode) + TSTALLOC(B3SOIDDPbPtr, B3SOIDDpNode, B3SOIDDbNode) + TSTALLOC(B3SOIDDPpPtr, B3SOIDDpNode, B3SOIDDpNode) + TSTALLOC(B3SOIDDPgPtr, B3SOIDDpNode, B3SOIDDgNode) + TSTALLOC(B3SOIDDPdpPtr, B3SOIDDpNode, B3SOIDDdNodePrime) + TSTALLOC(B3SOIDDPspPtr, B3SOIDDpNode, B3SOIDDsNodePrime) + TSTALLOC(B3SOIDDPePtr, B3SOIDDpNode, B3SOIDDeNode) + } + + TSTALLOC(B3SOIDDEgPtr, B3SOIDDeNode, B3SOIDDgNode) + TSTALLOC(B3SOIDDEdpPtr, B3SOIDDeNode, B3SOIDDdNodePrime) + TSTALLOC(B3SOIDDEspPtr, B3SOIDDeNode, B3SOIDDsNodePrime) + TSTALLOC(B3SOIDDGePtr, B3SOIDDgNode, B3SOIDDeNode) + TSTALLOC(B3SOIDDDPePtr, B3SOIDDdNodePrime, B3SOIDDeNode) + TSTALLOC(B3SOIDDSPePtr, B3SOIDDsNodePrime, B3SOIDDeNode) + + TSTALLOC(B3SOIDDEbPtr, B3SOIDDeNode, B3SOIDDbNode) + TSTALLOC(B3SOIDDGbPtr, B3SOIDDgNode, B3SOIDDbNode) + TSTALLOC(B3SOIDDDPbPtr, B3SOIDDdNodePrime, B3SOIDDbNode) + TSTALLOC(B3SOIDDSPbPtr, B3SOIDDsNodePrime, B3SOIDDbNode) + TSTALLOC(B3SOIDDBePtr, B3SOIDDbNode, B3SOIDDeNode) + TSTALLOC(B3SOIDDBgPtr, B3SOIDDbNode, B3SOIDDgNode) + TSTALLOC(B3SOIDDBdpPtr, B3SOIDDbNode, B3SOIDDdNodePrime) + TSTALLOC(B3SOIDDBspPtr, B3SOIDDbNode, B3SOIDDsNodePrime) + TSTALLOC(B3SOIDDBbPtr, B3SOIDDbNode, B3SOIDDbNode) + + TSTALLOC(B3SOIDDEbPtr, B3SOIDDeNode, B3SOIDDbNode) + TSTALLOC(B3SOIDDEePtr, B3SOIDDeNode, B3SOIDDeNode) + + TSTALLOC(B3SOIDDGgPtr, B3SOIDDgNode, B3SOIDDgNode) + TSTALLOC(B3SOIDDGdpPtr, B3SOIDDgNode, B3SOIDDdNodePrime) + TSTALLOC(B3SOIDDGspPtr, B3SOIDDgNode, B3SOIDDsNodePrime) + + TSTALLOC(B3SOIDDDPgPtr, B3SOIDDdNodePrime, B3SOIDDgNode) + TSTALLOC(B3SOIDDDPdpPtr, B3SOIDDdNodePrime, B3SOIDDdNodePrime) + TSTALLOC(B3SOIDDDPspPtr, B3SOIDDdNodePrime, B3SOIDDsNodePrime) + TSTALLOC(B3SOIDDDPdPtr, B3SOIDDdNodePrime, B3SOIDDdNode) + + TSTALLOC(B3SOIDDSPgPtr, B3SOIDDsNodePrime, B3SOIDDgNode) + TSTALLOC(B3SOIDDSPdpPtr, B3SOIDDsNodePrime, B3SOIDDdNodePrime) + TSTALLOC(B3SOIDDSPspPtr, B3SOIDDsNodePrime, B3SOIDDsNodePrime) + TSTALLOC(B3SOIDDSPsPtr, B3SOIDDsNodePrime, B3SOIDDsNode) + + TSTALLOC(B3SOIDDDdPtr, B3SOIDDdNode, B3SOIDDdNode) + TSTALLOC(B3SOIDDDdpPtr, B3SOIDDdNode, B3SOIDDdNodePrime) + + TSTALLOC(B3SOIDDSsPtr, B3SOIDDsNode, B3SOIDDsNode) + TSTALLOC(B3SOIDDSspPtr, B3SOIDDsNode, B3SOIDDsNodePrime) + +/* here for debugging purpose only */ + if ((here->B3SOIDDdebugMod > 1) || (here->B3SOIDDdebugMod == -1)) + { + TSTALLOC(B3SOIDDVbsPtr, B3SOIDDvbsNode, B3SOIDDvbsNode) + TSTALLOC(B3SOIDDIdsPtr, B3SOIDDidsNode, B3SOIDDidsNode) + TSTALLOC(B3SOIDDIcPtr, B3SOIDDicNode, B3SOIDDicNode) + TSTALLOC(B3SOIDDIbsPtr, B3SOIDDibsNode, B3SOIDDibsNode) + TSTALLOC(B3SOIDDIbdPtr, B3SOIDDibdNode, B3SOIDDibdNode) + TSTALLOC(B3SOIDDIiiPtr, B3SOIDDiiiNode, B3SOIDDiiiNode) + TSTALLOC(B3SOIDDIgidlPtr, B3SOIDDigidlNode, B3SOIDDigidlNode) + TSTALLOC(B3SOIDDItunPtr, B3SOIDDitunNode, B3SOIDDitunNode) + TSTALLOC(B3SOIDDIbpPtr, B3SOIDDibpNode, B3SOIDDibpNode) + TSTALLOC(B3SOIDDAbeffPtr, B3SOIDDabeffNode, B3SOIDDabeffNode) + TSTALLOC(B3SOIDDVbs0effPtr, B3SOIDDvbs0effNode, B3SOIDDvbs0effNode) + TSTALLOC(B3SOIDDVbseffPtr, B3SOIDDvbseffNode, B3SOIDDvbseffNode) + TSTALLOC(B3SOIDDXcPtr, B3SOIDDxcNode, B3SOIDDxcNode) + TSTALLOC(B3SOIDDCbbPtr, B3SOIDDcbbNode, B3SOIDDcbbNode) + TSTALLOC(B3SOIDDCbdPtr, B3SOIDDcbdNode, B3SOIDDcbdNode) + TSTALLOC(B3SOIDDCbgPtr, B3SOIDDcbgNode, B3SOIDDcbgNode) + TSTALLOC(B3SOIDDqbPtr, B3SOIDDqbNode, B3SOIDDqbNode) + TSTALLOC(B3SOIDDQbfPtr, B3SOIDDqbfNode, B3SOIDDqbfNode) + TSTALLOC(B3SOIDDQjsPtr, B3SOIDDqjsNode, B3SOIDDqjsNode) + TSTALLOC(B3SOIDDQjdPtr, B3SOIDDqjdNode, B3SOIDDqjdNode) + + /* clean up last */ + TSTALLOC(B3SOIDDGmPtr, B3SOIDDgmNode, B3SOIDDgmNode) + TSTALLOC(B3SOIDDGmbsPtr, B3SOIDDgmbsNode, B3SOIDDgmbsNode) + TSTALLOC(B3SOIDDGdsPtr, B3SOIDDgdsNode, B3SOIDDgdsNode) + TSTALLOC(B3SOIDDGmePtr, B3SOIDDgmeNode, B3SOIDDgmeNode) + TSTALLOC(B3SOIDDVbs0teffPtr, B3SOIDDvbs0teffNode, B3SOIDDvbs0teffNode) + TSTALLOC(B3SOIDDVthPtr, B3SOIDDvthNode, B3SOIDDvthNode) + TSTALLOC(B3SOIDDVgsteffPtr, B3SOIDDvgsteffNode, B3SOIDDvgsteffNode) + TSTALLOC(B3SOIDDXcsatPtr, B3SOIDDxcsatNode, B3SOIDDxcsatNode) + TSTALLOC(B3SOIDDVcscvPtr, B3SOIDDvcscvNode, B3SOIDDvcscvNode) + TSTALLOC(B3SOIDDVdscvPtr, B3SOIDDvdscvNode, B3SOIDDvdscvNode) + TSTALLOC(B3SOIDDCbePtr, B3SOIDDcbeNode, B3SOIDDcbeNode) + TSTALLOC(B3SOIDDDum1Ptr, B3SOIDDdum1Node, B3SOIDDdum1Node) + TSTALLOC(B3SOIDDDum2Ptr, B3SOIDDdum2Node, B3SOIDDdum2Node) + TSTALLOC(B3SOIDDDum3Ptr, B3SOIDDdum3Node, B3SOIDDdum3Node) + TSTALLOC(B3SOIDDDum4Ptr, B3SOIDDdum4Node, B3SOIDDdum4Node) + TSTALLOC(B3SOIDDDum5Ptr, B3SOIDDdum5Node, B3SOIDDdum5Node) + TSTALLOC(B3SOIDDQaccPtr, B3SOIDDqaccNode, B3SOIDDqaccNode) + TSTALLOC(B3SOIDDQsub0Ptr, B3SOIDDqsub0Node, B3SOIDDqsub0Node) + TSTALLOC(B3SOIDDQsubs1Ptr, B3SOIDDqsubs1Node, B3SOIDDqsubs1Node) + TSTALLOC(B3SOIDDQsubs2Ptr, B3SOIDDqsubs2Node, B3SOIDDqsubs2Node) + TSTALLOC(B3SOIDDqePtr, B3SOIDDqeNode, B3SOIDDqeNode) + TSTALLOC(B3SOIDDqdPtr, B3SOIDDqdNode, B3SOIDDqdNode) + TSTALLOC(B3SOIDDqgPtr, B3SOIDDqgNode, B3SOIDDqgNode) + } + + } + } + return(OK); +} + +int +B3SOIDDunsetup(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ +#ifndef HAS_BATCHSIM + B3SOIDDmodel *model; + B3SOIDDinstance *here; + + for (model = (B3SOIDDmodel *)inModel; model != NULL; + model = model->B3SOIDDnextModel) + { + for (here = model->B3SOIDDinstances; here != NULL; + here=here->B3SOIDDnextInstance) + { + if (here->B3SOIDDdNodePrime + && here->B3SOIDDdNodePrime != here->B3SOIDDdNode) + { + CKTdltNNum(ckt, here->B3SOIDDdNodePrime); + here->B3SOIDDdNodePrime = 0; + } + if (here->B3SOIDDsNodePrime + && here->B3SOIDDsNodePrime != here->B3SOIDDsNode) + { + CKTdltNNum(ckt, here->B3SOIDDsNodePrime); + here->B3SOIDDsNodePrime = 0; + } + } + } +#endif + return OK; +} + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddtemp.c b/src/spicelib/devices/bsim3soi_dd/b3soiddtemp.c new file mode 100644 index 000000000..c197af59d --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddtemp.c @@ -0,0 +1,816 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +Modified by Pin Su, Wei Jin 99/9/27 +File: b3soiddtemp.c 98/5/01 +**********/ + +/* Lmin, Lmax, Wmin, Wmax */ + +#include "ngspice.h" +#include +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "b3soidddef.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + +#define Kb 1.3806226e-23 +#define KboQ 8.617087e-5 /* Kb / q where q = 1.60219e-19 */ +#define EPSOX 3.453133e-11 +#define EPSSI 1.03594e-10 +#define PI 3.141592654 +#define MAX_EXP 5.834617425e14 +#define MIN_EXP 1.713908431e-15 +#define EXP_THRESHOLD 34.0 +#define Charge_q 1.60219e-19 + + +/* ARGSUSED */ +int +B3SOIDDtemp(inModel,ckt) +GENmodel *inModel; +CKTcircuit *ckt; +{ +register B3SOIDDmodel *model = (B3SOIDDmodel*) inModel; +register B3SOIDDinstance *here; +struct b3soiddSizeDependParam *pSizeDependParamKnot, *pLastKnot, *pParam; +double tmp, tmp1, tmp2, Eg, Eg0, ni, T0, T1, T2, T3, T4, T5, T6, Ldrn, Wdrn; +double Temp, TRatio, Inv_L, Inv_W, Inv_LW, Dw, Dl, Vtm0, Tnom; +double SDphi, SDgamma; +int Size_Not_Found; + + /* loop through all the B3SOIDD device models */ + for (; model != NULL; model = model->B3SOIDDnextModel) + { Temp = ckt->CKTtemp; + if (model->B3SOIDDGatesidewallJctPotential < 0.1) + model->B3SOIDDGatesidewallJctPotential = 0.1; + model->pSizeDependParamKnot = NULL; + pLastKnot = NULL; + + Tnom = model->B3SOIDDtnom; + TRatio = Temp / Tnom; + + model->B3SOIDDvcrit = CONSTvt0 * log(CONSTvt0 / (CONSTroot2 * 1.0e-14)); + model->B3SOIDDfactor1 = sqrt(EPSSI / EPSOX * model->B3SOIDDtox); + + Vtm0 = KboQ * Tnom; + Eg0 = 1.16 - 7.02e-4 * Tnom * Tnom / (Tnom + 1108.0); + model->B3SOIDDeg0 = Eg0; + model->B3SOIDDvtm = KboQ * Temp; + + Eg = 1.16 - 7.02e-4 * Temp * Temp / (Temp + 1108.0); + /* ni is in cm^-3 */ + ni = 1.45e10 * (Temp / 300.15) * sqrt(Temp / 300.15) + * exp(21.5565981 - Eg / (2.0 * model->B3SOIDDvtm)); + + + /* loop through all the instances of the model */ + /* MCJ: Length and Width not initialized */ + for (here = model->B3SOIDDinstances; here != NULL; + here = here->B3SOIDDnextInstance) + { + here->B3SOIDDrbodyext = here->B3SOIDDbodySquares * + model->B3SOIDDrbsh; + pSizeDependParamKnot = model->pSizeDependParamKnot; + Size_Not_Found = 1; + while ((pSizeDependParamKnot != NULL) && Size_Not_Found) + { if ((here->B3SOIDDl == pSizeDependParamKnot->Length) + && (here->B3SOIDDw == pSizeDependParamKnot->Width) + && (here->B3SOIDDrth0 == pSizeDependParamKnot->Rth0) + && (here->B3SOIDDcth0 == pSizeDependParamKnot->Cth0)) + { Size_Not_Found = 0; + here->pParam = pSizeDependParamKnot; + } + else + { pLastKnot = pSizeDependParamKnot; + pSizeDependParamKnot = pSizeDependParamKnot->pNext; + } + } + + if (Size_Not_Found) + { pParam = (struct b3soiddSizeDependParam *)malloc( + sizeof(struct b3soiddSizeDependParam)); + if (pLastKnot == NULL) + model->pSizeDependParamKnot = pParam; + else + pLastKnot->pNext = pParam; + pParam->pNext = NULL; + here->pParam = pParam; + + Ldrn = here->B3SOIDDl; + Wdrn = here->B3SOIDDw; + pParam->Length = Ldrn; + pParam->Width = Wdrn; + pParam->Rth0 = here->B3SOIDDrth0; + pParam->Cth0 = here->B3SOIDDcth0; + + T0 = pow(Ldrn, model->B3SOIDDLln); + T1 = pow(Wdrn, model->B3SOIDDLwn); + tmp1 = model->B3SOIDDLl / T0 + model->B3SOIDDLw / T1 + + model->B3SOIDDLwl / (T0 * T1); + pParam->B3SOIDDdl = model->B3SOIDDLint + tmp1; + pParam->B3SOIDDdlc = model->B3SOIDDdlc + tmp1; + + T2 = pow(Ldrn, model->B3SOIDDWln); + T3 = pow(Wdrn, model->B3SOIDDWwn); + tmp2 = model->B3SOIDDWl / T2 + model->B3SOIDDWw / T3 + + model->B3SOIDDWwl / (T2 * T3); + pParam->B3SOIDDdw = model->B3SOIDDWint + tmp2; + pParam->B3SOIDDdwc = model->B3SOIDDdwc + tmp2; + + pParam->B3SOIDDleff = here->B3SOIDDl - 2.0 * pParam->B3SOIDDdl; + if (pParam->B3SOIDDleff <= 0.0) + { IFuid namarray[2]; + namarray[0] = model->B3SOIDDmodName; + namarray[1] = here->B3SOIDDname; + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "B3SOIDD: mosfet %s, model %s: Effective channel length <= 0", + namarray); + return(E_BADPARM); + } + + pParam->B3SOIDDweff = here->B3SOIDDw - 2.0 * pParam->B3SOIDDdw; + if (pParam->B3SOIDDweff <= 0.0) + { IFuid namarray[2]; + namarray[0] = model->B3SOIDDmodName; + namarray[1] = here->B3SOIDDname; + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "B3SOIDD: mosfet %s, model %s: Effective channel width <= 0", + namarray); + return(E_BADPARM); + } + + pParam->B3SOIDDleffCV = here->B3SOIDDl - 2.0 * pParam->B3SOIDDdlc; + if (pParam->B3SOIDDleffCV <= 0.0) + { IFuid namarray[2]; + namarray[0] = model->B3SOIDDmodName; + namarray[1] = here->B3SOIDDname; + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "B3SOIDD: mosfet %s, model %s: Effective channel length for C-V <= 0", + namarray); + return(E_BADPARM); + } + + pParam->B3SOIDDweffCV = here->B3SOIDDw - 2.0 * pParam->B3SOIDDdwc; + if (pParam->B3SOIDDweffCV <= 0.0) + { IFuid namarray[2]; + namarray[0] = model->B3SOIDDmodName; + namarray[1] = here->B3SOIDDname; + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "B3SOIDD: mosfet %s, model %s: Effective channel width for C-V <= 0", + namarray); + return(E_BADPARM); + } + + /* Not binned - START */ + pParam->B3SOIDDat = model->B3SOIDDat; + pParam->B3SOIDDgamma1 = model->B3SOIDDgamma1; + pParam->B3SOIDDgamma2 = model->B3SOIDDgamma2; + pParam->B3SOIDDvbx = model->B3SOIDDvbx; + pParam->B3SOIDDvbm = model->B3SOIDDvbm; + pParam->B3SOIDDxt = model->B3SOIDDxt; + pParam->B3SOIDDkt1 = model->B3SOIDDkt1; + pParam->B3SOIDDkt1l = model->B3SOIDDkt1l; + pParam->B3SOIDDkt2 = model->B3SOIDDkt2; + pParam->B3SOIDDua1 = model->B3SOIDDua1; + pParam->B3SOIDDub1 = model->B3SOIDDub1; + pParam->B3SOIDDuc1 = model->B3SOIDDuc1; + pParam->B3SOIDDute = model->B3SOIDDute; + pParam->B3SOIDDprt = model->B3SOIDDprt; + /* Not binned - END */ + + /* CV model */ + pParam->B3SOIDDcgsl = model->B3SOIDDcgsl; + pParam->B3SOIDDcgdl = model->B3SOIDDcgdl; + pParam->B3SOIDDckappa = model->B3SOIDDckappa; + pParam->B3SOIDDcf = model->B3SOIDDcf; + pParam->B3SOIDDclc = model->B3SOIDDclc; + pParam->B3SOIDDcle = model->B3SOIDDcle; + + pParam->B3SOIDDabulkCVfactor = pow(1.0+(pParam->B3SOIDDclc + / pParam->B3SOIDDleff), + pParam->B3SOIDDcle); + +/* Added for binning - START */ + if (model->B3SOIDDbinUnit == 1) + { Inv_L = 1.0e-6 / pParam->B3SOIDDleff; + Inv_W = 1.0e-6 / pParam->B3SOIDDweff; + Inv_LW = 1.0e-12 / (pParam->B3SOIDDleff + * pParam->B3SOIDDweff); + } + else + { Inv_L = 1.0 / pParam->B3SOIDDleff; + Inv_W = 1.0 / pParam->B3SOIDDweff; + Inv_LW = 1.0 / (pParam->B3SOIDDleff + * pParam->B3SOIDDweff); + } + pParam->B3SOIDDnpeak = model->B3SOIDDnpeak + + model->B3SOIDDlnpeak * Inv_L + + model->B3SOIDDwnpeak * Inv_W + + model->B3SOIDDpnpeak * Inv_LW; + pParam->B3SOIDDnsub = model->B3SOIDDnsub + + model->B3SOIDDlnsub * Inv_L + + model->B3SOIDDwnsub * Inv_W + + model->B3SOIDDpnsub * Inv_LW; + pParam->B3SOIDDngate = model->B3SOIDDngate + + model->B3SOIDDlngate * Inv_L + + model->B3SOIDDwngate * Inv_W + + model->B3SOIDDpngate * Inv_LW; + pParam->B3SOIDDvth0 = model->B3SOIDDvth0 + + model->B3SOIDDlvth0 * Inv_L + + model->B3SOIDDwvth0 * Inv_W + + model->B3SOIDDpvth0 * Inv_LW; + pParam->B3SOIDDk1 = model->B3SOIDDk1 + + model->B3SOIDDlk1 * Inv_L + + model->B3SOIDDwk1 * Inv_W + + model->B3SOIDDpk1 * Inv_LW; + pParam->B3SOIDDk2 = model->B3SOIDDk2 + + model->B3SOIDDlk2 * Inv_L + + model->B3SOIDDwk2 * Inv_W + + model->B3SOIDDpk2 * Inv_LW; + pParam->B3SOIDDk3 = model->B3SOIDDk3 + + model->B3SOIDDlk3 * Inv_L + + model->B3SOIDDwk3 * Inv_W + + model->B3SOIDDpk3 * Inv_LW; + pParam->B3SOIDDk3b = model->B3SOIDDk3b + + model->B3SOIDDlk3b * Inv_L + + model->B3SOIDDwk3b * Inv_W + + model->B3SOIDDpk3b * Inv_LW; + pParam->B3SOIDDvbsa = model->B3SOIDDvbsa + + model->B3SOIDDlvbsa * Inv_L + + model->B3SOIDDwvbsa * Inv_W + + model->B3SOIDDpvbsa * Inv_LW; + pParam->B3SOIDDdelp = model->B3SOIDDdelp + + model->B3SOIDDldelp * Inv_L + + model->B3SOIDDwdelp * Inv_W + + model->B3SOIDDpdelp * Inv_LW; + pParam->B3SOIDDkb1 = model->B3SOIDDkb1 + + model->B3SOIDDlkb1 * Inv_L + + model->B3SOIDDwkb1 * Inv_W + + model->B3SOIDDpkb1 * Inv_LW; + pParam->B3SOIDDkb3 = model->B3SOIDDkb3 + + model->B3SOIDDlkb3 * Inv_L + + model->B3SOIDDwkb3 * Inv_W + + model->B3SOIDDpkb3 * Inv_LW; + pParam->B3SOIDDdvbd0 = model->B3SOIDDdvbd0 + + model->B3SOIDDldvbd0 * Inv_L + + model->B3SOIDDwdvbd0 * Inv_W + + model->B3SOIDDpdvbd0 * Inv_LW; + pParam->B3SOIDDdvbd1 = model->B3SOIDDdvbd1 + + model->B3SOIDDldvbd1 * Inv_L + + model->B3SOIDDwdvbd1 * Inv_W + + model->B3SOIDDpdvbd1 * Inv_LW; + pParam->B3SOIDDw0 = model->B3SOIDDw0 + + model->B3SOIDDlw0 * Inv_L + + model->B3SOIDDww0 * Inv_W + + model->B3SOIDDpw0 * Inv_LW; + pParam->B3SOIDDnlx = model->B3SOIDDnlx + + model->B3SOIDDlnlx * Inv_L + + model->B3SOIDDwnlx * Inv_W + + model->B3SOIDDpnlx * Inv_LW; + pParam->B3SOIDDdvt0 = model->B3SOIDDdvt0 + + model->B3SOIDDldvt0 * Inv_L + + model->B3SOIDDwdvt0 * Inv_W + + model->B3SOIDDpdvt0 * Inv_LW; + pParam->B3SOIDDdvt1 = model->B3SOIDDdvt1 + + model->B3SOIDDldvt1 * Inv_L + + model->B3SOIDDwdvt1 * Inv_W + + model->B3SOIDDpdvt1 * Inv_LW; + pParam->B3SOIDDdvt2 = model->B3SOIDDdvt2 + + model->B3SOIDDldvt2 * Inv_L + + model->B3SOIDDwdvt2 * Inv_W + + model->B3SOIDDpdvt2 * Inv_LW; + pParam->B3SOIDDdvt0w = model->B3SOIDDdvt0w + + model->B3SOIDDldvt0w * Inv_L + + model->B3SOIDDwdvt0w * Inv_W + + model->B3SOIDDpdvt0w * Inv_LW; + pParam->B3SOIDDdvt1w = model->B3SOIDDdvt1w + + model->B3SOIDDldvt1w * Inv_L + + model->B3SOIDDwdvt1w * Inv_W + + model->B3SOIDDpdvt1w * Inv_LW; + pParam->B3SOIDDdvt2w = model->B3SOIDDdvt2w + + model->B3SOIDDldvt2w * Inv_L + + model->B3SOIDDwdvt2w * Inv_W + + model->B3SOIDDpdvt2w * Inv_LW; + pParam->B3SOIDDu0 = model->B3SOIDDu0 + + model->B3SOIDDlu0 * Inv_L + + model->B3SOIDDwu0 * Inv_W + + model->B3SOIDDpu0 * Inv_LW; + pParam->B3SOIDDua = model->B3SOIDDua + + model->B3SOIDDlua * Inv_L + + model->B3SOIDDwua * Inv_W + + model->B3SOIDDpua * Inv_LW; + pParam->B3SOIDDub = model->B3SOIDDub + + model->B3SOIDDlub * Inv_L + + model->B3SOIDDwub * Inv_W + + model->B3SOIDDpub * Inv_LW; + pParam->B3SOIDDuc = model->B3SOIDDuc + + model->B3SOIDDluc * Inv_L + + model->B3SOIDDwuc * Inv_W + + model->B3SOIDDpuc * Inv_LW; + pParam->B3SOIDDvsat = model->B3SOIDDvsat + + model->B3SOIDDlvsat * Inv_L + + model->B3SOIDDwvsat * Inv_W + + model->B3SOIDDpvsat * Inv_LW; + pParam->B3SOIDDa0 = model->B3SOIDDa0 + + model->B3SOIDDla0 * Inv_L + + model->B3SOIDDwa0 * Inv_W + + model->B3SOIDDpa0 * Inv_LW; + pParam->B3SOIDDags = model->B3SOIDDags + + model->B3SOIDDlags * Inv_L + + model->B3SOIDDwags * Inv_W + + model->B3SOIDDpags * Inv_LW; + pParam->B3SOIDDb0 = model->B3SOIDDb0 + + model->B3SOIDDlb0 * Inv_L + + model->B3SOIDDwb0 * Inv_W + + model->B3SOIDDpb0 * Inv_LW; + pParam->B3SOIDDb1 = model->B3SOIDDb1 + + model->B3SOIDDlb1 * Inv_L + + model->B3SOIDDwb1 * Inv_W + + model->B3SOIDDpb1 * Inv_LW; + pParam->B3SOIDDketa = model->B3SOIDDketa + + model->B3SOIDDlketa * Inv_L + + model->B3SOIDDwketa * Inv_W + + model->B3SOIDDpketa * Inv_LW; + pParam->B3SOIDDabp = model->B3SOIDDabp + + model->B3SOIDDlabp * Inv_L + + model->B3SOIDDwabp * Inv_W + + model->B3SOIDDpabp * Inv_LW; + pParam->B3SOIDDmxc = model->B3SOIDDmxc + + model->B3SOIDDlmxc * Inv_L + + model->B3SOIDDwmxc * Inv_W + + model->B3SOIDDpmxc * Inv_LW; + pParam->B3SOIDDadice0 = model->B3SOIDDadice0 + + model->B3SOIDDladice0 * Inv_L + + model->B3SOIDDwadice0 * Inv_W + + model->B3SOIDDpadice0 * Inv_LW; + pParam->B3SOIDDa1 = model->B3SOIDDa1 + + model->B3SOIDDla1 * Inv_L + + model->B3SOIDDwa1 * Inv_W + + model->B3SOIDDpa1 * Inv_LW; + pParam->B3SOIDDa2 = model->B3SOIDDa2 + + model->B3SOIDDla2 * Inv_L + + model->B3SOIDDwa2 * Inv_W + + model->B3SOIDDpa2 * Inv_LW; + pParam->B3SOIDDrdsw = model->B3SOIDDrdsw + + model->B3SOIDDlrdsw * Inv_L + + model->B3SOIDDwrdsw * Inv_W + + model->B3SOIDDprdsw * Inv_LW; + pParam->B3SOIDDprwb = model->B3SOIDDprwb + + model->B3SOIDDlprwb * Inv_L + + model->B3SOIDDwprwb * Inv_W + + model->B3SOIDDpprwb * Inv_LW; + pParam->B3SOIDDprwg = model->B3SOIDDprwg + + model->B3SOIDDlprwg * Inv_L + + model->B3SOIDDwprwg * Inv_W + + model->B3SOIDDpprwg * Inv_LW; + pParam->B3SOIDDwr = model->B3SOIDDwr + + model->B3SOIDDlwr * Inv_L + + model->B3SOIDDwwr * Inv_W + + model->B3SOIDDpwr * Inv_LW; + pParam->B3SOIDDnfactor = model->B3SOIDDnfactor + + model->B3SOIDDlnfactor * Inv_L + + model->B3SOIDDwnfactor * Inv_W + + model->B3SOIDDpnfactor * Inv_LW; + pParam->B3SOIDDdwg = model->B3SOIDDdwg + + model->B3SOIDDldwg * Inv_L + + model->B3SOIDDwdwg * Inv_W + + model->B3SOIDDpdwg * Inv_LW; + pParam->B3SOIDDdwb = model->B3SOIDDdwb + + model->B3SOIDDldwb * Inv_L + + model->B3SOIDDwdwb * Inv_W + + model->B3SOIDDpdwb * Inv_LW; + pParam->B3SOIDDvoff = model->B3SOIDDvoff + + model->B3SOIDDlvoff * Inv_L + + model->B3SOIDDwvoff * Inv_W + + model->B3SOIDDpvoff * Inv_LW; + pParam->B3SOIDDeta0 = model->B3SOIDDeta0 + + model->B3SOIDDleta0 * Inv_L + + model->B3SOIDDweta0 * Inv_W + + model->B3SOIDDpeta0 * Inv_LW; + pParam->B3SOIDDetab = model->B3SOIDDetab + + model->B3SOIDDletab * Inv_L + + model->B3SOIDDwetab * Inv_W + + model->B3SOIDDpetab * Inv_LW; + pParam->B3SOIDDdsub = model->B3SOIDDdsub + + model->B3SOIDDldsub * Inv_L + + model->B3SOIDDwdsub * Inv_W + + model->B3SOIDDpdsub * Inv_LW; + pParam->B3SOIDDcit = model->B3SOIDDcit + + model->B3SOIDDlcit * Inv_L + + model->B3SOIDDwcit * Inv_W + + model->B3SOIDDpcit * Inv_LW; + pParam->B3SOIDDcdsc = model->B3SOIDDcdsc + + model->B3SOIDDlcdsc * Inv_L + + model->B3SOIDDwcdsc * Inv_W + + model->B3SOIDDpcdsc * Inv_LW; + pParam->B3SOIDDcdscb = model->B3SOIDDcdscb + + model->B3SOIDDlcdscb * Inv_L + + model->B3SOIDDwcdscb * Inv_W + + model->B3SOIDDpcdscb * Inv_LW; + pParam->B3SOIDDcdscd = model->B3SOIDDcdscd + + model->B3SOIDDlcdscd * Inv_L + + model->B3SOIDDwcdscd * Inv_W + + model->B3SOIDDpcdscd * Inv_LW; + pParam->B3SOIDDpclm = model->B3SOIDDpclm + + model->B3SOIDDlpclm * Inv_L + + model->B3SOIDDwpclm * Inv_W + + model->B3SOIDDppclm * Inv_LW; + pParam->B3SOIDDpdibl1 = model->B3SOIDDpdibl1 + + model->B3SOIDDlpdibl1 * Inv_L + + model->B3SOIDDwpdibl1 * Inv_W + + model->B3SOIDDppdibl1 * Inv_LW; + pParam->B3SOIDDpdibl2 = model->B3SOIDDpdibl2 + + model->B3SOIDDlpdibl2 * Inv_L + + model->B3SOIDDwpdibl2 * Inv_W + + model->B3SOIDDppdibl2 * Inv_LW; + pParam->B3SOIDDpdiblb = model->B3SOIDDpdiblb + + model->B3SOIDDlpdiblb * Inv_L + + model->B3SOIDDwpdiblb * Inv_W + + model->B3SOIDDppdiblb * Inv_LW; + pParam->B3SOIDDdrout = model->B3SOIDDdrout + + model->B3SOIDDldrout * Inv_L + + model->B3SOIDDwdrout * Inv_W + + model->B3SOIDDpdrout * Inv_LW; + pParam->B3SOIDDpvag = model->B3SOIDDpvag + + model->B3SOIDDlpvag * Inv_L + + model->B3SOIDDwpvag * Inv_W + + model->B3SOIDDppvag * Inv_LW; + pParam->B3SOIDDdelta = model->B3SOIDDdelta + + model->B3SOIDDldelta * Inv_L + + model->B3SOIDDwdelta * Inv_W + + model->B3SOIDDpdelta * Inv_LW; + pParam->B3SOIDDaii = model->B3SOIDDaii + + model->B3SOIDDlaii * Inv_L + + model->B3SOIDDwaii * Inv_W + + model->B3SOIDDpaii * Inv_LW; + pParam->B3SOIDDbii = model->B3SOIDDbii + + model->B3SOIDDlbii * Inv_L + + model->B3SOIDDwbii * Inv_W + + model->B3SOIDDpbii * Inv_LW; + pParam->B3SOIDDcii = model->B3SOIDDcii + + model->B3SOIDDlcii * Inv_L + + model->B3SOIDDwcii * Inv_W + + model->B3SOIDDpcii * Inv_LW; + pParam->B3SOIDDdii = model->B3SOIDDdii + + model->B3SOIDDldii * Inv_L + + model->B3SOIDDwdii * Inv_W + + model->B3SOIDDpdii * Inv_LW; + pParam->B3SOIDDalpha0 = model->B3SOIDDalpha0 + + model->B3SOIDDlalpha0 * Inv_L + + model->B3SOIDDwalpha0 * Inv_W + + model->B3SOIDDpalpha0 * Inv_LW; + pParam->B3SOIDDalpha1 = model->B3SOIDDalpha1 + + model->B3SOIDDlalpha1 * Inv_L + + model->B3SOIDDwalpha1 * Inv_W + + model->B3SOIDDpalpha1 * Inv_LW; + pParam->B3SOIDDbeta0 = model->B3SOIDDbeta0 + + model->B3SOIDDlbeta0 * Inv_L + + model->B3SOIDDwbeta0 * Inv_W + + model->B3SOIDDpbeta0 * Inv_LW; + pParam->B3SOIDDagidl = model->B3SOIDDagidl + + model->B3SOIDDlagidl * Inv_L + + model->B3SOIDDwagidl * Inv_W + + model->B3SOIDDpagidl * Inv_LW; + pParam->B3SOIDDbgidl = model->B3SOIDDbgidl + + model->B3SOIDDlbgidl * Inv_L + + model->B3SOIDDwbgidl * Inv_W + + model->B3SOIDDpbgidl * Inv_LW; + pParam->B3SOIDDngidl = model->B3SOIDDngidl + + model->B3SOIDDlngidl * Inv_L + + model->B3SOIDDwngidl * Inv_W + + model->B3SOIDDpngidl * Inv_LW; + pParam->B3SOIDDntun = model->B3SOIDDntun + + model->B3SOIDDlntun * Inv_L + + model->B3SOIDDwntun * Inv_W + + model->B3SOIDDpntun * Inv_LW; + pParam->B3SOIDDndiode = model->B3SOIDDndiode + + model->B3SOIDDlndiode * Inv_L + + model->B3SOIDDwndiode * Inv_W + + model->B3SOIDDpndiode * Inv_LW; + pParam->B3SOIDDisbjt = model->B3SOIDDisbjt + + model->B3SOIDDlisbjt * Inv_L + + model->B3SOIDDwisbjt * Inv_W + + model->B3SOIDDpisbjt * Inv_LW; + pParam->B3SOIDDisdif = model->B3SOIDDisdif + + model->B3SOIDDlisdif * Inv_L + + model->B3SOIDDwisdif * Inv_W + + model->B3SOIDDpisdif * Inv_LW; + pParam->B3SOIDDisrec = model->B3SOIDDisrec + + model->B3SOIDDlisrec * Inv_L + + model->B3SOIDDwisrec * Inv_W + + model->B3SOIDDpisrec * Inv_LW; + pParam->B3SOIDDistun = model->B3SOIDDistun + + model->B3SOIDDlistun * Inv_L + + model->B3SOIDDwistun * Inv_W + + model->B3SOIDDpistun * Inv_LW; + pParam->B3SOIDDedl = model->B3SOIDDedl + + model->B3SOIDDledl * Inv_L + + model->B3SOIDDwedl * Inv_W + + model->B3SOIDDpedl * Inv_LW; + pParam->B3SOIDDkbjt1 = model->B3SOIDDkbjt1 + + model->B3SOIDDlkbjt1 * Inv_L + + model->B3SOIDDwkbjt1 * Inv_W + + model->B3SOIDDpkbjt1 * Inv_LW; + /* CV model */ + pParam->B3SOIDDvsdfb = model->B3SOIDDvsdfb + + model->B3SOIDDlvsdfb * Inv_L + + model->B3SOIDDwvsdfb * Inv_W + + model->B3SOIDDpvsdfb * Inv_LW; + pParam->B3SOIDDvsdth = model->B3SOIDDvsdth + + model->B3SOIDDlvsdth * Inv_L + + model->B3SOIDDwvsdth * Inv_W + + model->B3SOIDDpvsdth * Inv_LW; +/* Added for binning - END */ + + T0 = (TRatio - 1.0); + + pParam->B3SOIDDuatemp = pParam->B3SOIDDua; /* save ua, ub, and uc for b3soild.c */ + pParam->B3SOIDDubtemp = pParam->B3SOIDDub; + pParam->B3SOIDDuctemp = pParam->B3SOIDDuc; + pParam->B3SOIDDrds0denom = pow(pParam->B3SOIDDweff * 1E6, pParam->B3SOIDDwr); + pParam->B3SOIDDrth = here->B3SOIDDrth0 * sqrt(model->B3SOIDDtbox + / model->B3SOIDDtsi) / pParam->B3SOIDDweff; + pParam->B3SOIDDcth = here->B3SOIDDcth0 * model->B3SOIDDtsi; + pParam->B3SOIDDrbody = model->B3SOIDDrbody * + pParam->B3SOIDDweff / pParam->B3SOIDDleff; + pParam->B3SOIDDua = pParam->B3SOIDDua + pParam->B3SOIDDua1 * T0; + pParam->B3SOIDDub = pParam->B3SOIDDub + pParam->B3SOIDDub1 * T0; + pParam->B3SOIDDuc = pParam->B3SOIDDuc + pParam->B3SOIDDuc1 * T0; + if (pParam->B3SOIDDu0 > 1.0) + pParam->B3SOIDDu0 = pParam->B3SOIDDu0 / 1.0e4; + + pParam->B3SOIDDu0temp = pParam->B3SOIDDu0 + * pow(TRatio, pParam->B3SOIDDute); + pParam->B3SOIDDvsattemp = pParam->B3SOIDDvsat - pParam->B3SOIDDat + * T0; + pParam->B3SOIDDrds0 = (pParam->B3SOIDDrdsw + pParam->B3SOIDDprt * T0) + / pow(pParam->B3SOIDDweff * 1E6, pParam->B3SOIDDwr); + + if (B3SOIDDcheckModel(model, here, ckt)) + { IFuid namarray[2]; + namarray[0] = model->B3SOIDDmodName; + namarray[1] = here->B3SOIDDname; + (*(SPfrontEnd->IFerror)) (ERR_FATAL, "Fatal error(s) detected during B3SOIDDV3 parameter checking for %s in model %s", namarray); + return(E_BADPARM); + } + + + pParam->B3SOIDDcgdo = (model->B3SOIDDcgdo + pParam->B3SOIDDcf) + * pParam->B3SOIDDweffCV; + pParam->B3SOIDDcgso = (model->B3SOIDDcgso + pParam->B3SOIDDcf) + * pParam->B3SOIDDweffCV; + pParam->B3SOIDDcgeo = model->B3SOIDDcgeo + * pParam->B3SOIDDleffCV; + + + if (!model->B3SOIDDnpeakGiven && model->B3SOIDDgamma1Given) + { T0 = pParam->B3SOIDDgamma1 * model->B3SOIDDcox; + pParam->B3SOIDDnpeak = 3.021E22 * T0 * T0; + } + + T0 = pow(TRatio, model->B3SOIDDxbjt / pParam->B3SOIDDndiode); + T1 = pow(TRatio, model->B3SOIDDxdif / pParam->B3SOIDDndiode); + T2 = pow(TRatio, model->B3SOIDDxrec / pParam->B3SOIDDndiode / 2); + T4 = -Eg0 / pParam->B3SOIDDndiode / model->B3SOIDDvtm * (1 - TRatio); + T5 = exp(T4); + T6 = sqrt(T5); + pParam->B3SOIDDjbjt = pParam->B3SOIDDisbjt * T0 * T5; + pParam->B3SOIDDjdif = pParam->B3SOIDDisdif * T1 * T5; + pParam->B3SOIDDjrec = pParam->B3SOIDDisrec * T2 * T6; + T0 = pow(TRatio, model->B3SOIDDxtun / pParam->B3SOIDDntun); + pParam->B3SOIDDjtun = pParam->B3SOIDDistun * T0 ; + + if (pParam->B3SOIDDnsub > 0) + pParam->B3SOIDDvfbb = -model->B3SOIDDtype * model->B3SOIDDvtm * + log(pParam->B3SOIDDnpeak/ pParam->B3SOIDDnsub); + else + pParam->B3SOIDDvfbb = -model->B3SOIDDtype * model->B3SOIDDvtm * + log(-pParam->B3SOIDDnpeak* pParam->B3SOIDDnsub/ni/ni); + + if (!model->B3SOIDDvsdfbGiven) + { + if (pParam->B3SOIDDnsub > 0) + pParam->B3SOIDDvsdfb = -model->B3SOIDDtype * (model->B3SOIDDvtm*log(1e20 * + pParam->B3SOIDDnsub / ni /ni) - 0.3); + else if (pParam->B3SOIDDnsub < 0) + pParam->B3SOIDDvsdfb = -model->B3SOIDDtype * (model->B3SOIDDvtm*log(-1e20 / + pParam->B3SOIDDnsub) + 0.3); + } + + /* Phi & Gamma */ + SDphi = 2.0*model->B3SOIDDvtm*log(fabs(pParam->B3SOIDDnsub) / ni); + SDgamma = 5.753e-12 * sqrt(fabs(pParam->B3SOIDDnsub)) / model->B3SOIDDcbox; + + if (!model->B3SOIDDvsdthGiven) + { + if ( ((pParam->B3SOIDDnsub > 0) && (model->B3SOIDDtype > 0)) || + ((pParam->B3SOIDDnsub < 0) && (model->B3SOIDDtype < 0)) ) + pParam->B3SOIDDvsdth = pParam->B3SOIDDvsdfb + SDphi + + SDgamma * sqrt(SDphi); + else + pParam->B3SOIDDvsdth = pParam->B3SOIDDvsdfb - SDphi - + SDgamma * sqrt(SDphi); + } + if (!model->B3SOIDDcsdminGiven) + { + /* Cdmin */ + tmp = sqrt(2.0 * EPSSI * SDphi / (Charge_q * + fabs(pParam->B3SOIDDnsub) * 1.0e6)); + tmp1 = EPSSI / tmp; + model->B3SOIDDcsdmin = tmp1 * model->B3SOIDDcbox / + (tmp1 + model->B3SOIDDcbox); + } + + + T0 = model->B3SOIDDcsdesw * log(1 + model->B3SOIDDtsi / + model->B3SOIDDtbox); + T1 = here->B3SOIDDsourcePerimeter - pParam->B3SOIDDweff; + if (T1 > 0.0) + pParam->B3SOIDDcsesw = T0 * T1; + else + pParam->B3SOIDDcsesw = 0.0; + T1 = here->B3SOIDDdrainPerimeter - pParam->B3SOIDDweff; + if (T1 > 0.0) + pParam->B3SOIDDcdesw = T0 * T1; + else + pParam->B3SOIDDcdesw = 0.0; + + pParam->B3SOIDDphi = 2.0 * model->B3SOIDDvtm + * log(pParam->B3SOIDDnpeak / ni); + + pParam->B3SOIDDsqrtPhi = sqrt(pParam->B3SOIDDphi); + pParam->B3SOIDDphis3 = pParam->B3SOIDDsqrtPhi * pParam->B3SOIDDphi; + + pParam->B3SOIDDXdep0 = sqrt(2.0 * EPSSI / (Charge_q + * pParam->B3SOIDDnpeak * 1.0e6)) + * pParam->B3SOIDDsqrtPhi; + pParam->B3SOIDDsqrtXdep0 = sqrt(pParam->B3SOIDDXdep0); + pParam->B3SOIDDlitl = sqrt(3.0 * model->B3SOIDDxj + * model->B3SOIDDtox); + pParam->B3SOIDDvbi = model->B3SOIDDvtm * log(1.0e20 + * pParam->B3SOIDDnpeak / (ni * ni)); + pParam->B3SOIDDcdep0 = sqrt(Charge_q * EPSSI + * pParam->B3SOIDDnpeak * 1.0e6 / 2.0 + / pParam->B3SOIDDphi); + + if (model->B3SOIDDk1Given || model->B3SOIDDk2Given) + { if (!model->B3SOIDDk1Given) + { fprintf(stdout, "Warning: k1 should be specified with k2.\n"); + pParam->B3SOIDDk1 = 0.53; + } + if (!model->B3SOIDDk2Given) + { fprintf(stdout, "Warning: k2 should be specified with k1.\n"); + pParam->B3SOIDDk2 = -0.0186; + } + if (model->B3SOIDDxtGiven) + fprintf(stdout, "Warning: xt is ignored because k1 or k2 is given.\n"); + if (model->B3SOIDDvbxGiven) + fprintf(stdout, "Warning: vbx is ignored because k1 or k2 is given.\n"); + if (model->B3SOIDDvbmGiven) + fprintf(stdout, "Warning: vbm is ignored because k1 or k2 is given.\n"); + if (model->B3SOIDDgamma1Given) + fprintf(stdout, "Warning: gamma1 is ignored because k1 or k2 is given.\n"); + if (model->B3SOIDDgamma2Given) + fprintf(stdout, "Warning: gamma2 is ignored because k1 or k2 is given.\n"); + } + else + { if (!model->B3SOIDDvbxGiven) + pParam->B3SOIDDvbx = pParam->B3SOIDDphi - 7.7348e-4 + * pParam->B3SOIDDnpeak + * pParam->B3SOIDDxt * pParam->B3SOIDDxt; + if (pParam->B3SOIDDvbx > 0.0) + pParam->B3SOIDDvbx = -pParam->B3SOIDDvbx; + if (pParam->B3SOIDDvbm > 0.0) + pParam->B3SOIDDvbm = -pParam->B3SOIDDvbm; + + if (!model->B3SOIDDgamma1Given) + pParam->B3SOIDDgamma1 = 5.753e-12 + * sqrt(pParam->B3SOIDDnpeak) + / model->B3SOIDDcox; + if (!model->B3SOIDDgamma2Given) + pParam->B3SOIDDgamma2 = 5.753e-12 + * sqrt(pParam->B3SOIDDnsub) + / model->B3SOIDDcox; + + T0 = pParam->B3SOIDDgamma1 - pParam->B3SOIDDgamma2; + T1 = sqrt(pParam->B3SOIDDphi - pParam->B3SOIDDvbx) + - pParam->B3SOIDDsqrtPhi; + T2 = sqrt(pParam->B3SOIDDphi * (pParam->B3SOIDDphi + - pParam->B3SOIDDvbm)) - pParam->B3SOIDDphi; + pParam->B3SOIDDk2 = T0 * T1 / (2.0 * T2 + pParam->B3SOIDDvbm); + pParam->B3SOIDDk1 = pParam->B3SOIDDgamma2 - 2.0 + * pParam->B3SOIDDk2 * sqrt(pParam->B3SOIDDphi + - pParam->B3SOIDDvbm); + } + + if (pParam->B3SOIDDk2 < 0.0) + { T0 = 0.5 * pParam->B3SOIDDk1 / pParam->B3SOIDDk2; + pParam->B3SOIDDvbsc = 0.9 * (pParam->B3SOIDDphi - T0 * T0); + if (pParam->B3SOIDDvbsc > -3.0) + pParam->B3SOIDDvbsc = -3.0; + else if (pParam->B3SOIDDvbsc < -30.0) + pParam->B3SOIDDvbsc = -30.0; + } + else + { pParam->B3SOIDDvbsc = -30.0; + } + if (pParam->B3SOIDDvbsc > pParam->B3SOIDDvbm) + pParam->B3SOIDDvbsc = pParam->B3SOIDDvbm; + + if (model->B3SOIDDvth0Given) + { pParam->B3SOIDDvfb = model->B3SOIDDtype * pParam->B3SOIDDvth0 + - pParam->B3SOIDDphi - pParam->B3SOIDDk1 + * pParam->B3SOIDDsqrtPhi; + } + else + { pParam->B3SOIDDvfb = -1.0; + pParam->B3SOIDDvth0 = model->B3SOIDDtype * (pParam->B3SOIDDvfb + + pParam->B3SOIDDphi + pParam->B3SOIDDk1 + * pParam->B3SOIDDsqrtPhi); + } + T1 = sqrt(EPSSI / EPSOX * model->B3SOIDDtox + * pParam->B3SOIDDXdep0); + T0 = exp(-0.5 * pParam->B3SOIDDdsub * pParam->B3SOIDDleff / T1); + pParam->B3SOIDDtheta0vb0 = (T0 + 2.0 * T0 * T0); + + T0 = exp(-0.5 * pParam->B3SOIDDdrout * pParam->B3SOIDDleff / T1); + T2 = (T0 + 2.0 * T0 * T0); + pParam->B3SOIDDthetaRout = pParam->B3SOIDDpdibl1 * T2 + + pParam->B3SOIDDpdibl2; + + here->B3SOIDDminIsub = 5.0e-2 * pParam->B3SOIDDweff * model->B3SOIDDtsi + * MAX(pParam->B3SOIDDisdif, pParam->B3SOIDDisrec); + } + + here->B3SOIDDcsbox = model->B3SOIDDcbox*here->B3SOIDDsourceArea; + here->B3SOIDDcsmin = model->B3SOIDDcsdmin*here->B3SOIDDsourceArea; + here->B3SOIDDcdbox = model->B3SOIDDcbox*here->B3SOIDDdrainArea; + here->B3SOIDDcdmin = model->B3SOIDDcsdmin*here->B3SOIDDdrainArea; + + if ( ((pParam->B3SOIDDnsub > 0) && (model->B3SOIDDtype > 0)) || + ((pParam->B3SOIDDnsub < 0) && (model->B3SOIDDtype < 0)) ) + { + T0 = pParam->B3SOIDDvsdth - pParam->B3SOIDDvsdfb; + pParam->B3SOIDDsdt1 = pParam->B3SOIDDvsdfb + model->B3SOIDDasd * T0; + T1 = here->B3SOIDDcsbox - here->B3SOIDDcsmin; + T2 = T1 / T0 / T0; + pParam->B3SOIDDst2 = T2 / model->B3SOIDDasd; + pParam->B3SOIDDst3 = T2 /( 1 - model->B3SOIDDasd); + here->B3SOIDDst4 = T0 * T1 * (1 + model->B3SOIDDasd) / 3 + - here->B3SOIDDcsmin * pParam->B3SOIDDvsdfb; + + T1 = here->B3SOIDDcdbox - here->B3SOIDDcdmin; + T2 = T1 / T0 / T0; + pParam->B3SOIDDdt2 = T2 / model->B3SOIDDasd; + pParam->B3SOIDDdt3 = T2 /( 1 - model->B3SOIDDasd); + here->B3SOIDDdt4 = T0 * T1 * (1 + model->B3SOIDDasd) / 3 + - here->B3SOIDDcdmin * pParam->B3SOIDDvsdfb; + } else + { + T0 = pParam->B3SOIDDvsdfb - pParam->B3SOIDDvsdth; + pParam->B3SOIDDsdt1 = pParam->B3SOIDDvsdth + model->B3SOIDDasd * T0; + T1 = here->B3SOIDDcsmin - here->B3SOIDDcsbox; + T2 = T1 / T0 / T0; + pParam->B3SOIDDst2 = T2 / model->B3SOIDDasd; + pParam->B3SOIDDst3 = T2 /( 1 - model->B3SOIDDasd); + here->B3SOIDDst4 = T0 * T1 * (1 + model->B3SOIDDasd) / 3 + - here->B3SOIDDcsbox * pParam->B3SOIDDvsdth; + + T1 = here->B3SOIDDcdmin - here->B3SOIDDcdbox; + T2 = T1 / T0 / T0; + pParam->B3SOIDDdt2 = T2 / model->B3SOIDDasd; + pParam->B3SOIDDdt3 = T2 /( 1 - model->B3SOIDDasd); + here->B3SOIDDdt4 = T0 * T1 * (1 + model->B3SOIDDasd) / 3 + - here->B3SOIDDcdbox * pParam->B3SOIDDvsdth; + } + + here->B3SOIDDphi = pParam->B3SOIDDphi; + /* process source/drain series resistance */ + here->B3SOIDDdrainConductance = model->B3SOIDDsheetResistance + * here->B3SOIDDdrainSquares; + if (here->B3SOIDDdrainConductance > 0.0) + here->B3SOIDDdrainConductance = 1.0 + / here->B3SOIDDdrainConductance; + else + here->B3SOIDDdrainConductance = 0.0; + + here->B3SOIDDsourceConductance = model->B3SOIDDsheetResistance + * here->B3SOIDDsourceSquares; + if (here->B3SOIDDsourceConductance > 0.0) + here->B3SOIDDsourceConductance = 1.0 + / here->B3SOIDDsourceConductance; + else + here->B3SOIDDsourceConductance = 0.0; + here->B3SOIDDcgso = pParam->B3SOIDDcgso; + here->B3SOIDDcgdo = pParam->B3SOIDDcgdo; + + } + } + return(OK); +} + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddtrunc.c b/src/spicelib/devices/bsim3soi_dd/b3soiddtrunc.c new file mode 100644 index 000000000..916cdedf5 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddtrunc.c @@ -0,0 +1,52 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddtrunc.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "b3soidddef.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIDDtrunc(inModel,ckt,timeStep) +GENmodel *inModel; +register CKTcircuit *ckt; +double *timeStep; +{ +register B3SOIDDmodel *model = (B3SOIDDmodel*)inModel; +register B3SOIDDinstance *here; + +#ifdef STEPDEBUG + double debugtemp; +#endif /* STEPDEBUG */ + + for (; model != NULL; model = model->B3SOIDDnextModel) + { for (here = model->B3SOIDDinstances; here != NULL; + here = here->B3SOIDDnextInstance) + { +#ifdef STEPDEBUG + debugtemp = *timeStep; +#endif /* STEPDEBUG */ + CKTterr(here->B3SOIDDqb,ckt,timeStep); + CKTterr(here->B3SOIDDqg,ckt,timeStep); + CKTterr(here->B3SOIDDqd,ckt,timeStep); +#ifdef STEPDEBUG + if(debugtemp != *timeStep) + { printf("device %s reduces step from %g to %g\n", + here->B3SOIDDname,debugtemp,*timeStep); + } +#endif /* STEPDEBUG */ + } + } + return(OK); +} + + + diff --git a/src/spicelib/devices/bsim3soi_fd/Makefile.am b/src/spicelib/devices/bsim3soi_fd/Makefile.am new file mode 100644 index 000000000..bc6b3a2f1 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/Makefile.am @@ -0,0 +1,34 @@ +## Process this file with automake to produce Makefile.in + +pkglib_LTLIBRARIES = libbsim3soifd.la + +libbsim3soifd_la_SOURCES = \ + b3soifd.c \ + b3soifdacld.c \ + b3soifdask.c \ + b3soifdcheck.c \ + b3soifdcvtest.c \ + b3soifddel.c \ + b3soifddest.c \ + b3soifdgetic.c \ + b3soifdld.c \ + b3soifdmask.c \ + b3soifdmdel.c \ + b3soifdmpar.c \ + b3soifdnoi.c \ + b3soifdpar.c \ + b3soifdpzld.c \ + b3soifdset.c \ + b3soifdtemp.c \ + b3soifdtrunc.c \ + b3soifddef.h \ + b3soifdext.h \ + b3soifdinit.c \ + b3soifdinit.h \ + b3soifditf.h + + + +INCLUDES = -I$(top_srcdir)/src/include + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifd.c b/src/spicelib/devices/bsim3soi_fd/b3soifd.c new file mode 100644 index 000000000..f8af18ce3 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifd.c @@ -0,0 +1,479 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +Modified by Wei Jin 99/9/27 +File: b3soifd.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "devdefs.h" +#include "b3soifddef.h" +#include "suffix.h" + +IFparm B3SOIFDpTable[] = { /* parameters */ +IOP( "l", B3SOIFD_L, IF_REAL , "Length"), +IOP( "w", B3SOIFD_W, IF_REAL , "Width"), +IOP( "ad", B3SOIFD_AD, IF_REAL , "Drain area"), +IOP( "as", B3SOIFD_AS, IF_REAL , "Source area"), +IOP( "pd", B3SOIFD_PD, IF_REAL , "Drain perimeter"), +IOP( "ps", B3SOIFD_PS, IF_REAL , "Source perimeter"), +IOP( "nrd", B3SOIFD_NRD, IF_REAL , "Number of squares in drain"), +IOP( "nrs", B3SOIFD_NRS, IF_REAL , "Number of squares in source"), +IOP( "off", B3SOIFD_OFF, IF_FLAG , "Device is initially off"), +IP( "ic", B3SOIFD_IC, IF_REALVEC , "Vector of DS,GS,BS initial voltages"), +OP( "gmbs", B3SOIFD_GMBS, IF_REAL, "Gmb"), +OP( "gm", B3SOIFD_GM, IF_REAL, "Gm"), +OP( "gm/ids", B3SOIFD_GMID, IF_REAL, "Gm/Ids"), +OP( "gds", B3SOIFD_GDS, IF_REAL, "Gds"), +OP( "vdsat", B3SOIFD_VDSAT, IF_REAL, "Vdsat"), +OP( "vth", B3SOIFD_VON, IF_REAL, "Vth"), +OP( "ids", B3SOIFD_CD, IF_REAL, "Ids"), +OP( "vbs", B3SOIFD_VBS, IF_REAL, "Vbs"), +OP( "vgs", B3SOIFD_VGS, IF_REAL, "Vgs"), +OP( "vds", B3SOIFD_VDS, IF_REAL, "Vds"), +OP( "ves", B3SOIFD_VES, IF_REAL, "Ves"), +IOP( "bjtoff", B3SOIFD_BJTOFF, IF_INTEGER, "BJT on/off flag"), +IOP( "debug", B3SOIFD_DEBUG, IF_INTEGER, "BJT on/off flag"), +IOP( "rth0", B3SOIFD_RTH0, IF_REAL, "Instance Thermal Resistance"), +IOP( "cth0", B3SOIFD_CTH0, IF_REAL, "Instance Thermal Capacitance"), +IOP( "nrb", B3SOIFD_NRB, IF_REAL, "Number of squares in body"), +}; + +IFparm B3SOIFDmPTable[] = { /* model parameters */ +IOP( "capmod", B3SOIFD_MOD_CAPMOD, IF_INTEGER, "Capacitance model selector"), +IOP( "mobmod", B3SOIFD_MOD_MOBMOD, IF_INTEGER, "Mobility model selector"), +IOP( "noimod", B3SOIFD_MOD_NOIMOD, IF_INTEGER, "Noise model selector"), +IOP( "paramchk", B3SOIFD_MOD_PARAMCHK, IF_INTEGER, "Model parameter checking selector"), +IOP( "binunit", B3SOIFD_MOD_BINUNIT, IF_INTEGER, "Bin unit selector"), +IOP( "version", B3SOIFD_MOD_VERSION, IF_REAL, " parameter for model version"), +IOP( "tox", B3SOIFD_MOD_TOX, IF_REAL, "Gate oxide thickness in meters"), + +IOP( "cdsc", B3SOIFD_MOD_CDSC, IF_REAL, "Drain/Source and channel coupling capacitance"), +IOP( "cdscb", B3SOIFD_MOD_CDSCB, IF_REAL, "Body-bias dependence of cdsc"), +IOP( "cdscd", B3SOIFD_MOD_CDSCD, IF_REAL, "Drain-bias dependence of cdsc"), +IOP( "cit", B3SOIFD_MOD_CIT, IF_REAL, "Interface state capacitance"), +IOP( "nfactor", B3SOIFD_MOD_NFACTOR, IF_REAL, "Subthreshold swing Coefficient"), +IOP( "vsat", B3SOIFD_MOD_VSAT, IF_REAL, "Saturation velocity at tnom"), +IOP( "at", B3SOIFD_MOD_AT, IF_REAL, "Temperature coefficient of vsat"), +IOP( "a0", B3SOIFD_MOD_A0, IF_REAL, "Non-uniform depletion width effect coefficient."), +IOP( "ags", B3SOIFD_MOD_AGS, IF_REAL, "Gate bias coefficient of Abulk."), +IOP( "a1", B3SOIFD_MOD_A1, IF_REAL, "Non-saturation effect coefficient"), +IOP( "a2", B3SOIFD_MOD_A2, IF_REAL, "Non-saturation effect coefficient"), +IOP( "keta", B3SOIFD_MOD_KETA, IF_REAL, "Body-bias coefficient of non-uniform depletion width effect."), +IOP( "nsub", B3SOIFD_MOD_NSUB, IF_REAL, "Substrate doping concentration with polarity"), +IOP( "nch", B3SOIFD_MOD_NPEAK, IF_REAL, "Channel doping concentration"), +IOP( "ngate", B3SOIFD_MOD_NGATE, IF_REAL, "Poly-gate doping concentration"), +IOP( "gamma1", B3SOIFD_MOD_GAMMA1, IF_REAL, "Vth body coefficient"), +IOP( "gamma2", B3SOIFD_MOD_GAMMA2, IF_REAL, "Vth body coefficient"), +IOP( "vbx", B3SOIFD_MOD_VBX, IF_REAL, "Vth transition body Voltage"), +IOP( "vbm", B3SOIFD_MOD_VBM, IF_REAL, "Maximum body voltage"), + +IOP( "xt", B3SOIFD_MOD_XT, IF_REAL, "Doping depth"), +IOP( "k1", B3SOIFD_MOD_K1, IF_REAL, "Bulk effect coefficient 1"), +IOP( "kt1", B3SOIFD_MOD_KT1, IF_REAL, "Temperature coefficient of Vth"), +IOP( "kt1l", B3SOIFD_MOD_KT1L, IF_REAL, "Temperature coefficient of Vth"), +IOP( "kt2", B3SOIFD_MOD_KT2, IF_REAL, "Body-coefficient of kt1"), +IOP( "k2", B3SOIFD_MOD_K2, IF_REAL, "Bulk effect coefficient 2"), +IOP( "k3", B3SOIFD_MOD_K3, IF_REAL, "Narrow width effect coefficient"), +IOP( "k3b", B3SOIFD_MOD_K3B, IF_REAL, "Body effect coefficient of k3"), +IOP( "w0", B3SOIFD_MOD_W0, IF_REAL, "Narrow width effect parameter"), +IOP( "nlx", B3SOIFD_MOD_NLX, IF_REAL, "Lateral non-uniform doping effect"), +IOP( "dvt0", B3SOIFD_MOD_DVT0, IF_REAL, "Short channel effect coeff. 0"), +IOP( "dvt1", B3SOIFD_MOD_DVT1, IF_REAL, "Short channel effect coeff. 1"), +IOP( "dvt2", B3SOIFD_MOD_DVT2, IF_REAL, "Short channel effect coeff. 2"), +IOP( "dvt0w", B3SOIFD_MOD_DVT0W, IF_REAL, "Narrow Width coeff. 0"), +IOP( "dvt1w", B3SOIFD_MOD_DVT1W, IF_REAL, "Narrow Width effect coeff. 1"), +IOP( "dvt2w", B3SOIFD_MOD_DVT2W, IF_REAL, "Narrow Width effect coeff. 2"), +IOP( "drout", B3SOIFD_MOD_DROUT, IF_REAL, "DIBL coefficient of output resistance"), +IOP( "dsub", B3SOIFD_MOD_DSUB, IF_REAL, "DIBL coefficient in the subthreshold region"), +IOP( "vth0", B3SOIFD_MOD_VTH0, IF_REAL,"Threshold voltage"), +IOP( "vtho", B3SOIFD_MOD_VTH0, IF_REAL,"Threshold voltage"), +IOP( "ua", B3SOIFD_MOD_UA, IF_REAL, "Linear gate dependence of mobility"), +IOP( "ua1", B3SOIFD_MOD_UA1, IF_REAL, "Temperature coefficient of ua"), +IOP( "ub", B3SOIFD_MOD_UB, IF_REAL, "Quadratic gate dependence of mobility"), +IOP( "ub1", B3SOIFD_MOD_UB1, IF_REAL, "Temperature coefficient of ub"), +IOP( "uc", B3SOIFD_MOD_UC, IF_REAL, "Body-bias dependence of mobility"), +IOP( "uc1", B3SOIFD_MOD_UC1, IF_REAL, "Temperature coefficient of uc"), +IOP( "u0", B3SOIFD_MOD_U0, IF_REAL, "Low-field mobility at Tnom"), +IOP( "ute", B3SOIFD_MOD_UTE, IF_REAL, "Temperature coefficient of mobility"), +IOP( "voff", B3SOIFD_MOD_VOFF, IF_REAL, "Threshold voltage offset"), +IOP( "tnom", B3SOIFD_MOD_TNOM, IF_REAL, "Parameter measurement temperature"), +IOP( "cgso", B3SOIFD_MOD_CGSO, IF_REAL, "Gate-source overlap capacitance per width"), +IOP( "cgdo", B3SOIFD_MOD_CGDO, IF_REAL, "Gate-drain overlap capacitance per width"), +IOP( "cgeo", B3SOIFD_MOD_CGEO, IF_REAL, "Gate-substrate overlap capacitance"), +IOP( "xpart", B3SOIFD_MOD_XPART, IF_REAL, "Channel charge partitioning"), +IOP( "delta", B3SOIFD_MOD_DELTA, IF_REAL, "Effective Vds parameter"), +IOP( "rsh", B3SOIFD_MOD_RSH, IF_REAL, "Source-drain sheet resistance"), +IOP( "rdsw", B3SOIFD_MOD_RDSW, IF_REAL, "Source-drain resistance per width"), + +IOP( "prwg", B3SOIFD_MOD_PRWG, IF_REAL, "Gate-bias effect on parasitic resistance "), +IOP( "prwb", B3SOIFD_MOD_PRWB, IF_REAL, "Body-effect on parasitic resistance "), + +IOP( "prt", B3SOIFD_MOD_PRT, IF_REAL, "Temperature coefficient of parasitic resistance "), +IOP( "eta0", B3SOIFD_MOD_ETA0, IF_REAL, "Subthreshold region DIBL coefficient"), +IOP( "etab", B3SOIFD_MOD_ETAB, IF_REAL, "Subthreshold region DIBL coefficient"), +IOP( "pclm", B3SOIFD_MOD_PCLM, IF_REAL, "Channel length modulation Coefficient"), +IOP( "pdiblc1", B3SOIFD_MOD_PDIBL1, IF_REAL, "Drain-induced barrier lowering coefficient"), +IOP( "pdiblc2", B3SOIFD_MOD_PDIBL2, IF_REAL, "Drain-induced barrier lowering coefficient"), +IOP( "pdiblcb", B3SOIFD_MOD_PDIBLB, IF_REAL, "Body-effect on drain-induced barrier lowering"), + +IOP( "pvag", B3SOIFD_MOD_PVAG, IF_REAL, "Gate dependence of output resistance parameter"), + +IOP( "shmod", B3SOIFD_MOD_SHMOD, IF_INTEGER, "Self heating mode selector"), +IOP( "tbox", B3SOIFD_MOD_TBOX, IF_REAL, "Back gate oxide thickness in meters"), +IOP( "tsi", B3SOIFD_MOD_TSI, IF_REAL, "Silicon-on-insulator thickness in meters"), +IOP( "xj", B3SOIFD_MOD_XJ, IF_REAL, "Junction Depth"), +IOP( "kb1", B3SOIFD_MOD_KB1, IF_REAL, "Backgate coupling coefficient at strong inversion"), +IOP( "kb3", B3SOIFD_MOD_KB3, IF_REAL, "Backgate coupling coefficient at subthreshold"), +IOP( "dvbd0", B3SOIFD_MOD_DVBD0, IF_REAL, "First coefficient of short-channel effect on Vbs0t"), +IOP( "dvbd1", B3SOIFD_MOD_DVBD1, IF_REAL, "Second coefficient of short-channel effect on Vbs0t"), +IOP( "vbsa", B3SOIFD_MOD_VBSA, IF_REAL, "Vbs0t offset voltage"), +IOP( "delp", B3SOIFD_MOD_DELP, IF_REAL, "Offset constant for limiting Vbseff to Phis"), +IOP( "rbody", B3SOIFD_MOD_RBODY, IF_REAL, "Intrinsic body contact sheet resistance"), +IOP( "rbsh", B3SOIFD_MOD_RBSH, IF_REAL, "Extrinsic body contact sheet resistance"), +IOP( "adice0", B3SOIFD_MOD_ADICE0, IF_REAL, "DICE constant for bulk charge effect"), +IOP( "abp", B3SOIFD_MOD_ABP, IF_REAL, "Gate bias coefficient for Xcsat calculation"), +IOP( "mxc", B3SOIFD_MOD_MXC, IF_REAL, "A smoothing parameter for Xcsat calculation"), +IOP( "rth0", B3SOIFD_MOD_RTH0, IF_REAL, "Self-heating thermal resistance"), +IOP( "cth0", B3SOIFD_MOD_CTH0, IF_REAL, "Self-heating thermal capacitance"), +IOP( "aii", B3SOIFD_MOD_AII, IF_REAL, "1st Vdsatii parameter"), +IOP( "bii", B3SOIFD_MOD_BII, IF_REAL, "2nd Vdsatii parameter"), +IOP( "cii", B3SOIFD_MOD_CII, IF_REAL, "3rd Vdsatii parameter"), +IOP( "dii", B3SOIFD_MOD_DII, IF_REAL, "4th Vdsatii parameter"), +IOP( "ngidl", B3SOIFD_MOD_NGIDL, IF_REAL, "GIDL first parameter"), +IOP( "agidl", B3SOIFD_MOD_AGIDL, IF_REAL, "GIDL second parameter"), +IOP( "bgidl", B3SOIFD_MOD_BGIDL, IF_REAL, "GIDL third parameter"), +IOP( "ndiode", B3SOIFD_MOD_NDIODE, IF_REAL, "Diode non-ideality factor"), +IOP( "ntun", B3SOIFD_MOD_NTUN, IF_REAL, "Reverse tunneling non-ideality factor"), +IOP( "isbjt", B3SOIFD_MOD_ISBJT, IF_REAL, "BJT emitter injection constant"), +IOP( "isdif", B3SOIFD_MOD_ISDIF, IF_REAL, "Body to S/D injection constant"), +IOP( "isrec", B3SOIFD_MOD_ISREC, IF_REAL, "Recombination in depletion constant"), +IOP( "istun", B3SOIFD_MOD_ISTUN, IF_REAL, "Tunneling diode constant"), +IOP( "xbjt", B3SOIFD_MOD_XBJT, IF_REAL, "Temperature coefficient for Isbjt"), +IOP( "xdif", B3SOIFD_MOD_XBJT, IF_REAL, "Temperature coefficient for Isdif"), +IOP( "xrec", B3SOIFD_MOD_XREC, IF_REAL, "Temperature coefficient for Isrec"), +IOP( "xtun", B3SOIFD_MOD_XTUN, IF_REAL, "Temperature coefficient for Istun"), +IOP( "edl", B3SOIFD_MOD_EDL, IF_REAL, "Electron diffusion length"), +IOP( "kbjt1", B3SOIFD_MOD_KBJT1, IF_REAL, "Vds dependency on BJT base width"), +IOP( "tt", B3SOIFD_MOD_TT, IF_REAL, "Diffusion capacitance transit time coefficient"), +IOP( "vsdth", B3SOIFD_MOD_VSDTH, IF_REAL, "Source/Drain diffusion threshold voltage"), +IOP( "vsdfb", B3SOIFD_MOD_VSDFB, IF_REAL, "Source/Drain diffusion flatband voltage"), +IOP( "csdmin", B3SOIFD_MOD_CSDMIN, IF_REAL, "Source/Drain diffusion bottom minimum capacitance"), +IOP( "asd", B3SOIFD_MOD_ASD, IF_REAL, "Source/Drain diffusion smoothing parameter"), + +IOP( "pbswg", B3SOIFD_MOD_PBSWG, IF_REAL, "Source/drain (gate side) sidewall junction capacitance built in potential"), +IOP( "mjswg", B3SOIFD_MOD_MJSWG, IF_REAL, "Source/drain (gate side) sidewall junction capacitance grading coefficient"), + +IOP( "cjswg", B3SOIFD_MOD_CJSWG, IF_REAL, "Source/drain (gate side) sidewall junction capacitance per unit width"), +IOP( "csdesw", B3SOIFD_MOD_CSDESW, IF_REAL, "Source/drain sidewall fringing constant"), +IOP( "lint", B3SOIFD_MOD_LINT, IF_REAL, "Length reduction parameter"), +IOP( "ll", B3SOIFD_MOD_LL, IF_REAL, "Length reduction parameter"), +IOP( "lln", B3SOIFD_MOD_LLN, IF_REAL, "Length reduction parameter"), +IOP( "lw", B3SOIFD_MOD_LW, IF_REAL, "Length reduction parameter"), +IOP( "lwn", B3SOIFD_MOD_LWN, IF_REAL, "Length reduction parameter"), +IOP( "lwl", B3SOIFD_MOD_LWL, IF_REAL, "Length reduction parameter"), + +IOP( "wr", B3SOIFD_MOD_WR, IF_REAL, "Width dependence of rds"), +IOP( "wint", B3SOIFD_MOD_WINT, IF_REAL, "Width reduction parameter"), +IOP( "dwg", B3SOIFD_MOD_DWG, IF_REAL, "Width reduction parameter"), +IOP( "dwb", B3SOIFD_MOD_DWB, IF_REAL, "Width reduction parameter"), + +IOP( "wl", B3SOIFD_MOD_WL, IF_REAL, "Width reduction parameter"), +IOP( "wln", B3SOIFD_MOD_WLN, IF_REAL, "Width reduction parameter"), +IOP( "ww", B3SOIFD_MOD_WW, IF_REAL, "Width reduction parameter"), +IOP( "wwn", B3SOIFD_MOD_WWN, IF_REAL, "Width reduction parameter"), +IOP( "wwl", B3SOIFD_MOD_WWL, IF_REAL, "Width reduction parameter"), + +IOP( "b0", B3SOIFD_MOD_B0, IF_REAL, "Abulk narrow width parameter"), +IOP( "b1", B3SOIFD_MOD_B1, IF_REAL, "Abulk narrow width parameter"), + +IOP( "cgsl", B3SOIFD_MOD_CGSL, IF_REAL, "New C-V model parameter"), +IOP( "cgdl", B3SOIFD_MOD_CGDL, IF_REAL, "New C-V model parameter"), +IOP( "ckappa", B3SOIFD_MOD_CKAPPA, IF_REAL, "New C-V model parameter"), +IOP( "cf", B3SOIFD_MOD_CF, IF_REAL, "Fringe capacitance parameter"), +IOP( "clc", B3SOIFD_MOD_CLC, IF_REAL, "Vdsat parameter for C-V model"), +IOP( "cle", B3SOIFD_MOD_CLE, IF_REAL, "Vdsat parameter for C-V model"), +IOP( "dwc", B3SOIFD_MOD_DWC, IF_REAL, "Delta W for C-V model"), +IOP( "dlc", B3SOIFD_MOD_DLC, IF_REAL, "Delta L for C-V model"), + +IOP( "alpha0", B3SOIFD_MOD_ALPHA0, IF_REAL, "substrate current model parameter"), +IOP( "alpha1", B3SOIFD_MOD_ALPHA1, IF_REAL, "substrate current model parameter"), +IOP( "beta0", B3SOIFD_MOD_BETA0, IF_REAL, "substrate current model parameter"), + +IOP( "noia", B3SOIFD_MOD_NOIA, IF_REAL, "Flicker noise parameter"), +IOP( "noib", B3SOIFD_MOD_NOIB, IF_REAL, "Flicker noise parameter"), +IOP( "noic", B3SOIFD_MOD_NOIC, IF_REAL, "Flicker noise parameter"), +IOP( "em", B3SOIFD_MOD_EM, IF_REAL, "Flicker noise parameter"), +IOP( "ef", B3SOIFD_MOD_EF, IF_REAL, "Flicker noise frequency exponent"), +IOP( "af", B3SOIFD_MOD_AF, IF_REAL, "Flicker noise exponent"), +IOP( "kf", B3SOIFD_MOD_KF, IF_REAL, "Flicker noise coefficient"), +IOP( "noif", B3SOIFD_MOD_NOIF, IF_REAL, "Floating body excess noise ideality factor"), + +/* Added for binning - START */ +/* Length Dependence */ +IOP( "lnch", B3SOIFD_MOD_LNPEAK, IF_REAL, "Length dependence of nch"), +IOP( "lnsub", B3SOIFD_MOD_LNSUB, IF_REAL, "Length dependence of nsub"), +IOP( "lngate", B3SOIFD_MOD_LNGATE, IF_REAL, "Length dependence of ngate"), +IOP( "lvth0", B3SOIFD_MOD_LVTH0, IF_REAL,"Length dependence of vto"), +IOP( "lk1", B3SOIFD_MOD_LK1, IF_REAL, "Length dependence of k1"), +IOP( "lk2", B3SOIFD_MOD_LK2, IF_REAL, "Length dependence of k2"), +IOP( "lk3", B3SOIFD_MOD_LK3, IF_REAL, "Length dependence of k3"), +IOP( "lk3b", B3SOIFD_MOD_LK3B, IF_REAL, "Length dependence of k3b"), +IOP( "lvbsa", B3SOIFD_MOD_LVBSA, IF_REAL, "Length dependence of vbsa"), +IOP( "ldelp", B3SOIFD_MOD_LDELP, IF_REAL, "Length dependence of delp"), +IOP( "lkb1", B3SOIFD_MOD_LKB1, IF_REAL, "Length dependence of kb1"), +IOP( "lkb3", B3SOIFD_MOD_LKB3, IF_REAL, "Length dependence of kb3"), +IOP( "ldvbd0", B3SOIFD_MOD_LDVBD0, IF_REAL, "Length dependence of dvbd0"), +IOP( "ldvbd1", B3SOIFD_MOD_LDVBD1, IF_REAL, "Length dependence of dvbd1"), +IOP( "lw0", B3SOIFD_MOD_LW0, IF_REAL, "Length dependence of w0"), +IOP( "lnlx", B3SOIFD_MOD_LNLX, IF_REAL, "Length dependence of nlx"), +IOP( "ldvt0", B3SOIFD_MOD_LDVT0, IF_REAL, "Length dependence of dvt0"), +IOP( "ldvt1", B3SOIFD_MOD_LDVT1, IF_REAL, "Length dependence of dvt1"), +IOP( "ldvt2", B3SOIFD_MOD_LDVT2, IF_REAL, "Length dependence of dvt2"), +IOP( "ldvt0w", B3SOIFD_MOD_LDVT0W, IF_REAL, "Length dependence of dvt0w"), +IOP( "ldvt1w", B3SOIFD_MOD_LDVT1W, IF_REAL, "Length dependence of dvt1w"), +IOP( "ldvt2w", B3SOIFD_MOD_LDVT2W, IF_REAL, "Length dependence of dvt2w"), +IOP( "lu0", B3SOIFD_MOD_LU0, IF_REAL, "Length dependence of u0"), +IOP( "lua", B3SOIFD_MOD_LUA, IF_REAL, "Length dependence of ua"), +IOP( "lub", B3SOIFD_MOD_LUB, IF_REAL, "Length dependence of ub"), +IOP( "luc", B3SOIFD_MOD_LUC, IF_REAL, "Length dependence of uc"), +IOP( "lvsat", B3SOIFD_MOD_LVSAT, IF_REAL, "Length dependence of vsat"), +IOP( "la0", B3SOIFD_MOD_LA0, IF_REAL, "Length dependence of a0"), +IOP( "lags", B3SOIFD_MOD_LAGS, IF_REAL, "Length dependence of ags"), +IOP( "lb0", B3SOIFD_MOD_LB0, IF_REAL, "Length dependence of b0"), +IOP( "lb1", B3SOIFD_MOD_LB1, IF_REAL, "Length dependence of b1"), +IOP( "lketa", B3SOIFD_MOD_LKETA, IF_REAL, "Length dependence of keta"), +IOP( "labp", B3SOIFD_MOD_LABP, IF_REAL, "Length dependence of abp"), +IOP( "lmxc", B3SOIFD_MOD_LMXC, IF_REAL, "Length dependence of mxc"), +IOP( "ladice0", B3SOIFD_MOD_LADICE0, IF_REAL, "Length dependence of adice0"), +IOP( "la1", B3SOIFD_MOD_LA1, IF_REAL, "Length dependence of a1"), +IOP( "la2", B3SOIFD_MOD_LA2, IF_REAL, "Length dependence of a2"), +IOP( "lrdsw", B3SOIFD_MOD_LRDSW, IF_REAL, "Length dependence of rdsw "), +IOP( "lprwb", B3SOIFD_MOD_LPRWB, IF_REAL, "Length dependence of prwb "), +IOP( "lprwg", B3SOIFD_MOD_LPRWG, IF_REAL, "Length dependence of prwg "), +IOP( "lwr", B3SOIFD_MOD_LWR, IF_REAL, "Length dependence of wr"), +IOP( "lnfactor", B3SOIFD_MOD_LNFACTOR, IF_REAL, "Length dependence of nfactor"), +IOP( "ldwg", B3SOIFD_MOD_LDWG, IF_REAL, "Length dependence of dwg"), +IOP( "ldwb", B3SOIFD_MOD_LDWB, IF_REAL, "Length dependence of dwb"), +IOP( "lvoff", B3SOIFD_MOD_LVOFF, IF_REAL, "Length dependence of voff"), +IOP( "leta0", B3SOIFD_MOD_LETA0, IF_REAL, "Length dependence of eta0"), +IOP( "letab", B3SOIFD_MOD_LETAB, IF_REAL, "Length dependence of etab"), +IOP( "ldsub", B3SOIFD_MOD_LDSUB, IF_REAL, "Length dependence of dsub"), +IOP( "lcit", B3SOIFD_MOD_LCIT, IF_REAL, "Length dependence of cit"), +IOP( "lcdsc", B3SOIFD_MOD_LCDSC, IF_REAL, "Length dependence of cdsc"), +IOP( "lcdscb", B3SOIFD_MOD_LCDSCB, IF_REAL, "Length dependence of cdscb"), +IOP( "lcdscd", B3SOIFD_MOD_LCDSCD, IF_REAL, "Length dependence of cdscd"), +IOP( "lpclm", B3SOIFD_MOD_LPCLM, IF_REAL, "Length dependence of pclm"), +IOP( "lpdiblc1", B3SOIFD_MOD_LPDIBL1, IF_REAL, "Length dependence of pdiblc1"), +IOP( "lpdiblc2", B3SOIFD_MOD_LPDIBL2, IF_REAL, "Length dependence of pdiblc2"), +IOP( "lpdiblcb", B3SOIFD_MOD_LPDIBLB, IF_REAL, "Length dependence of pdiblcb"), +IOP( "ldrout", B3SOIFD_MOD_LDROUT, IF_REAL, "Length dependence of drout"), +IOP( "lpvag", B3SOIFD_MOD_LPVAG, IF_REAL, "Length dependence of pvag"), +IOP( "ldelta", B3SOIFD_MOD_LDELTA, IF_REAL, "Length dependence of delta"), +IOP( "laii", B3SOIFD_MOD_LAII, IF_REAL, "Length dependence of aii"), +IOP( "lbii", B3SOIFD_MOD_LBII, IF_REAL, "Length dependence of bii"), +IOP( "lcii", B3SOIFD_MOD_LCII, IF_REAL, "Length dependence of cii"), +IOP( "ldii", B3SOIFD_MOD_LDII, IF_REAL, "Length dependence of dii"), +IOP( "lalpha0", B3SOIFD_MOD_LALPHA0, IF_REAL, "Length dependence of alpha0"), +IOP( "lalpha1", B3SOIFD_MOD_LALPHA1, IF_REAL, "Length dependence of alpha1"), +IOP( "lbeta0", B3SOIFD_MOD_LBETA0, IF_REAL, "Length dependence of beta0"), +IOP( "lagidl", B3SOIFD_MOD_LAGIDL, IF_REAL, "Length dependence of agidl"), +IOP( "lbgidl", B3SOIFD_MOD_LBGIDL, IF_REAL, "Length dependence of bgidl"), +IOP( "lngidl", B3SOIFD_MOD_LNGIDL, IF_REAL, "Length dependence of ngidl"), +IOP( "lntun", B3SOIFD_MOD_LNTUN, IF_REAL, "Length dependence of ntun"), +IOP( "lndiode", B3SOIFD_MOD_LNDIODE, IF_REAL, "Length dependence of ndiode"), +IOP( "lisbjt", B3SOIFD_MOD_LISBJT, IF_REAL, "Length dependence of isbjt"), +IOP( "lisdif", B3SOIFD_MOD_LISDIF, IF_REAL, "Length dependence of isdif"), +IOP( "lisrec", B3SOIFD_MOD_LISREC, IF_REAL, "Length dependence of isrec"), +IOP( "listun", B3SOIFD_MOD_LISTUN, IF_REAL, "Length dependence of istun"), +IOP( "ledl", B3SOIFD_MOD_LEDL, IF_REAL, "Length dependence of edl"), +IOP( "lkbjt1", B3SOIFD_MOD_LKBJT1, IF_REAL, "Length dependence of kbjt1"), +IOP( "lvsdfb", B3SOIFD_MOD_LVSDFB, IF_REAL, "Length dependence of vsdfb"), +IOP( "lvsdth", B3SOIFD_MOD_LVSDTH, IF_REAL, "Length dependence of vsdth"), +/* Width Dependence */ +IOP( "wnch", B3SOIFD_MOD_WNPEAK, IF_REAL, "Width dependence of nch"), +IOP( "wnsub", B3SOIFD_MOD_WNSUB, IF_REAL, "Width dependence of nsub"), +IOP( "wngate", B3SOIFD_MOD_WNGATE, IF_REAL, "Width dependence of ngate"), +IOP( "wvth0", B3SOIFD_MOD_WVTH0, IF_REAL,"Width dependence of vto"), +IOP( "wk1", B3SOIFD_MOD_WK1, IF_REAL, "Width dependence of k1"), +IOP( "wk2", B3SOIFD_MOD_WK2, IF_REAL, "Width dependence of k2"), +IOP( "wk3", B3SOIFD_MOD_WK3, IF_REAL, "Width dependence of k3"), +IOP( "wk3b", B3SOIFD_MOD_WK3B, IF_REAL, "Width dependence of k3b"), +IOP( "wvbsa", B3SOIFD_MOD_WVBSA, IF_REAL, "Width dependence of vbsa"), +IOP( "wdelp", B3SOIFD_MOD_WDELP, IF_REAL, "Width dependence of delp"), +IOP( "wkb1", B3SOIFD_MOD_WKB1, IF_REAL, "Width dependence of kb1"), +IOP( "wkb3", B3SOIFD_MOD_WKB3, IF_REAL, "Width dependence of kb3"), +IOP( "wdvbd0", B3SOIFD_MOD_WDVBD0, IF_REAL, "Width dependence of dvbd0"), +IOP( "wdvbd1", B3SOIFD_MOD_WDVBD1, IF_REAL, "Width dependence of dvbd1"), +IOP( "ww0", B3SOIFD_MOD_WW0, IF_REAL, "Width dependence of w0"), +IOP( "wnlx", B3SOIFD_MOD_WNLX, IF_REAL, "Width dependence of nlx"), +IOP( "wdvt0", B3SOIFD_MOD_WDVT0, IF_REAL, "Width dependence of dvt0"), +IOP( "wdvt1", B3SOIFD_MOD_WDVT1, IF_REAL, "Width dependence of dvt1"), +IOP( "wdvt2", B3SOIFD_MOD_WDVT2, IF_REAL, "Width dependence of dvt2"), +IOP( "wdvt0w", B3SOIFD_MOD_WDVT0W, IF_REAL, "Width dependence of dvt0w"), +IOP( "wdvt1w", B3SOIFD_MOD_WDVT1W, IF_REAL, "Width dependence of dvt1w"), +IOP( "wdvt2w", B3SOIFD_MOD_WDVT2W, IF_REAL, "Width dependence of dvt2w"), +IOP( "wu0", B3SOIFD_MOD_WU0, IF_REAL, "Width dependence of u0"), +IOP( "wua", B3SOIFD_MOD_WUA, IF_REAL, "Width dependence of ua"), +IOP( "wub", B3SOIFD_MOD_WUB, IF_REAL, "Width dependence of ub"), +IOP( "wuc", B3SOIFD_MOD_WUC, IF_REAL, "Width dependence of uc"), +IOP( "wvsat", B3SOIFD_MOD_WVSAT, IF_REAL, "Width dependence of vsat"), +IOP( "wa0", B3SOIFD_MOD_WA0, IF_REAL, "Width dependence of a0"), +IOP( "wags", B3SOIFD_MOD_WAGS, IF_REAL, "Width dependence of ags"), +IOP( "wb0", B3SOIFD_MOD_WB0, IF_REAL, "Width dependence of b0"), +IOP( "wb1", B3SOIFD_MOD_WB1, IF_REAL, "Width dependence of b1"), +IOP( "wketa", B3SOIFD_MOD_WKETA, IF_REAL, "Width dependence of keta"), +IOP( "wabp", B3SOIFD_MOD_WABP, IF_REAL, "Width dependence of abp"), +IOP( "wmxc", B3SOIFD_MOD_WMXC, IF_REAL, "Width dependence of mxc"), +IOP( "wadice0", B3SOIFD_MOD_WADICE0, IF_REAL, "Width dependence of adice0"), +IOP( "wa1", B3SOIFD_MOD_WA1, IF_REAL, "Width dependence of a1"), +IOP( "wa2", B3SOIFD_MOD_WA2, IF_REAL, "Width dependence of a2"), +IOP( "wrdsw", B3SOIFD_MOD_WRDSW, IF_REAL, "Width dependence of rdsw "), +IOP( "wprwb", B3SOIFD_MOD_WPRWB, IF_REAL, "Width dependence of prwb "), +IOP( "wprwg", B3SOIFD_MOD_WPRWG, IF_REAL, "Width dependence of prwg "), +IOP( "wwr", B3SOIFD_MOD_WWR, IF_REAL, "Width dependence of wr"), +IOP( "wnfactor", B3SOIFD_MOD_WNFACTOR, IF_REAL, "Width dependence of nfactor"), +IOP( "wdwg", B3SOIFD_MOD_WDWG, IF_REAL, "Width dependence of dwg"), +IOP( "wdwb", B3SOIFD_MOD_WDWB, IF_REAL, "Width dependence of dwb"), +IOP( "wvoff", B3SOIFD_MOD_WVOFF, IF_REAL, "Width dependence of voff"), +IOP( "weta0", B3SOIFD_MOD_WETA0, IF_REAL, "Width dependence of eta0"), +IOP( "wetab", B3SOIFD_MOD_WETAB, IF_REAL, "Width dependence of etab"), +IOP( "wdsub", B3SOIFD_MOD_WDSUB, IF_REAL, "Width dependence of dsub"), +IOP( "wcit", B3SOIFD_MOD_WCIT, IF_REAL, "Width dependence of cit"), +IOP( "wcdsc", B3SOIFD_MOD_WCDSC, IF_REAL, "Width dependence of cdsc"), +IOP( "wcdscb", B3SOIFD_MOD_WCDSCB, IF_REAL, "Width dependence of cdscb"), +IOP( "wcdscd", B3SOIFD_MOD_WCDSCD, IF_REAL, "Width dependence of cdscd"), +IOP( "wpclm", B3SOIFD_MOD_WPCLM, IF_REAL, "Width dependence of pclm"), +IOP( "wpdiblc1", B3SOIFD_MOD_WPDIBL1, IF_REAL, "Width dependence of pdiblc1"), +IOP( "wpdiblc2", B3SOIFD_MOD_WPDIBL2, IF_REAL, "Width dependence of pdiblc2"), +IOP( "wpdiblcb", B3SOIFD_MOD_WPDIBLB, IF_REAL, "Width dependence of pdiblcb"), +IOP( "wdrout", B3SOIFD_MOD_WDROUT, IF_REAL, "Width dependence of drout"), +IOP( "wpvag", B3SOIFD_MOD_WPVAG, IF_REAL, "Width dependence of pvag"), +IOP( "wdelta", B3SOIFD_MOD_WDELTA, IF_REAL, "Width dependence of delta"), +IOP( "waii", B3SOIFD_MOD_WAII, IF_REAL, "Width dependence of aii"), +IOP( "wbii", B3SOIFD_MOD_WBII, IF_REAL, "Width dependence of bii"), +IOP( "wcii", B3SOIFD_MOD_WCII, IF_REAL, "Width dependence of cii"), +IOP( "wdii", B3SOIFD_MOD_WDII, IF_REAL, "Width dependence of dii"), +IOP( "walpha0", B3SOIFD_MOD_WALPHA0, IF_REAL, "Width dependence of alpha0"), +IOP( "walpha1", B3SOIFD_MOD_WALPHA1, IF_REAL, "Width dependence of alpha1"), +IOP( "wbeta0", B3SOIFD_MOD_WBETA0, IF_REAL, "Width dependence of beta0"), +IOP( "wagidl", B3SOIFD_MOD_WAGIDL, IF_REAL, "Width dependence of agidl"), +IOP( "wbgidl", B3SOIFD_MOD_WBGIDL, IF_REAL, "Width dependence of bgidl"), +IOP( "wngidl", B3SOIFD_MOD_WNGIDL, IF_REAL, "Width dependence of ngidl"), +IOP( "wntun", B3SOIFD_MOD_WNTUN, IF_REAL, "Width dependence of ntun"), +IOP( "wndiode", B3SOIFD_MOD_WNDIODE, IF_REAL, "Width dependence of ndiode"), +IOP( "wisbjt", B3SOIFD_MOD_WISBJT, IF_REAL, "Width dependence of isbjt"), +IOP( "wisdif", B3SOIFD_MOD_WISDIF, IF_REAL, "Width dependence of isdif"), +IOP( "wisrec", B3SOIFD_MOD_WISREC, IF_REAL, "Width dependence of isrec"), +IOP( "wistun", B3SOIFD_MOD_WISTUN, IF_REAL, "Width dependence of istun"), +IOP( "wedl", B3SOIFD_MOD_WEDL, IF_REAL, "Width dependence of edl"), +IOP( "wkbjt1", B3SOIFD_MOD_WKBJT1, IF_REAL, "Width dependence of kbjt1"), +IOP( "wvsdfb", B3SOIFD_MOD_WVSDFB, IF_REAL, "Width dependence of vsdfb"), +IOP( "wvsdth", B3SOIFD_MOD_WVSDTH, IF_REAL, "Width dependence of vsdth"), +/* Cross-term Dependence */ +IOP( "pnch", B3SOIFD_MOD_PNPEAK, IF_REAL, "Cross-term dependence of nch"), +IOP( "pnsub", B3SOIFD_MOD_PNSUB, IF_REAL, "Cross-term dependence of nsub"), +IOP( "pngate", B3SOIFD_MOD_PNGATE, IF_REAL, "Cross-term dependence of ngate"), +IOP( "pvth0", B3SOIFD_MOD_PVTH0, IF_REAL,"Cross-term dependence of vto"), +IOP( "pk1", B3SOIFD_MOD_PK1, IF_REAL, "Cross-term dependence of k1"), +IOP( "pk2", B3SOIFD_MOD_PK2, IF_REAL, "Cross-term dependence of k2"), +IOP( "pk3", B3SOIFD_MOD_PK3, IF_REAL, "Cross-term dependence of k3"), +IOP( "pk3b", B3SOIFD_MOD_PK3B, IF_REAL, "Cross-term dependence of k3b"), +IOP( "pvbsa", B3SOIFD_MOD_PVBSA, IF_REAL, "Cross-term dependence of vbsa"), +IOP( "pdelp", B3SOIFD_MOD_PDELP, IF_REAL, "Cross-term dependence of delp"), +IOP( "pkb1", B3SOIFD_MOD_PKB1, IF_REAL, "Cross-term dependence of kb1"), +IOP( "pkb3", B3SOIFD_MOD_PKB3, IF_REAL, "Cross-term dependence of kb3"), +IOP( "pdvbd0", B3SOIFD_MOD_PDVBD0, IF_REAL, "Cross-term dependence of dvbd0"), +IOP( "pdvbd1", B3SOIFD_MOD_PDVBD1, IF_REAL, "Cross-term dependence of dvbd1"), +IOP( "pw0", B3SOIFD_MOD_PW0, IF_REAL, "Cross-term dependence of w0"), +IOP( "pnlx", B3SOIFD_MOD_PNLX, IF_REAL, "Cross-term dependence of nlx"), +IOP( "pdvt0", B3SOIFD_MOD_PDVT0, IF_REAL, "Cross-term dependence of dvt0"), +IOP( "pdvt1", B3SOIFD_MOD_PDVT1, IF_REAL, "Cross-term dependence of dvt1"), +IOP( "pdvt2", B3SOIFD_MOD_PDVT2, IF_REAL, "Cross-term dependence of dvt2"), +IOP( "pdvt0w", B3SOIFD_MOD_PDVT0W, IF_REAL, "Cross-term dependence of dvt0w"), +IOP( "pdvt1w", B3SOIFD_MOD_PDVT1W, IF_REAL, "Cross-term dependence of dvt1w"), +IOP( "pdvt2w", B3SOIFD_MOD_PDVT2W, IF_REAL, "Cross-term dependence of dvt2w"), +IOP( "pu0", B3SOIFD_MOD_PU0, IF_REAL, "Cross-term dependence of u0"), +IOP( "pua", B3SOIFD_MOD_PUA, IF_REAL, "Cross-term dependence of ua"), +IOP( "pub", B3SOIFD_MOD_PUB, IF_REAL, "Cross-term dependence of ub"), +IOP( "puc", B3SOIFD_MOD_PUC, IF_REAL, "Cross-term dependence of uc"), +IOP( "pvsat", B3SOIFD_MOD_PVSAT, IF_REAL, "Cross-term dependence of vsat"), +IOP( "pa0", B3SOIFD_MOD_PA0, IF_REAL, "Cross-term dependence of a0"), +IOP( "pags", B3SOIFD_MOD_PAGS, IF_REAL, "Cross-term dependence of ags"), +IOP( "pb0", B3SOIFD_MOD_PB0, IF_REAL, "Cross-term dependence of b0"), +IOP( "pb1", B3SOIFD_MOD_PB1, IF_REAL, "Cross-term dependence of b1"), +IOP( "pketa", B3SOIFD_MOD_PKETA, IF_REAL, "Cross-term dependence of keta"), +IOP( "pabp", B3SOIFD_MOD_PABP, IF_REAL, "Cross-term dependence of abp"), +IOP( "pmxc", B3SOIFD_MOD_PMXC, IF_REAL, "Cross-term dependence of mxc"), +IOP( "padice0", B3SOIFD_MOD_PADICE0, IF_REAL, "Cross-term dependence of adice0"), +IOP( "pa1", B3SOIFD_MOD_PA1, IF_REAL, "Cross-term dependence of a1"), +IOP( "pa2", B3SOIFD_MOD_PA2, IF_REAL, "Cross-term dependence of a2"), +IOP( "prdsw", B3SOIFD_MOD_PRDSW, IF_REAL, "Cross-term dependence of rdsw "), +IOP( "pprwb", B3SOIFD_MOD_PPRWB, IF_REAL, "Cross-term dependence of prwb "), +IOP( "pprwg", B3SOIFD_MOD_PPRWG, IF_REAL, "Cross-term dependence of prwg "), +IOP( "pwr", B3SOIFD_MOD_PWR, IF_REAL, "Cross-term dependence of wr"), +IOP( "pnfactor", B3SOIFD_MOD_PNFACTOR, IF_REAL, "Cross-term dependence of nfactor"), +IOP( "pdwg", B3SOIFD_MOD_PDWG, IF_REAL, "Cross-term dependence of dwg"), +IOP( "pdwb", B3SOIFD_MOD_PDWB, IF_REAL, "Cross-term dependence of dwb"), +IOP( "pvoff", B3SOIFD_MOD_PVOFF, IF_REAL, "Cross-term dependence of voff"), +IOP( "peta0", B3SOIFD_MOD_PETA0, IF_REAL, "Cross-term dependence of eta0"), +IOP( "petab", B3SOIFD_MOD_PETAB, IF_REAL, "Cross-term dependence of etab"), +IOP( "pdsub", B3SOIFD_MOD_PDSUB, IF_REAL, "Cross-term dependence of dsub"), +IOP( "pcit", B3SOIFD_MOD_PCIT, IF_REAL, "Cross-term dependence of cit"), +IOP( "pcdsc", B3SOIFD_MOD_PCDSC, IF_REAL, "Cross-term dependence of cdsc"), +IOP( "pcdscb", B3SOIFD_MOD_PCDSCB, IF_REAL, "Cross-term dependence of cdscb"), +IOP( "pcdscd", B3SOIFD_MOD_PCDSCD, IF_REAL, "Cross-term dependence of cdscd"), +IOP( "ppclm", B3SOIFD_MOD_PPCLM, IF_REAL, "Cross-term dependence of pclm"), +IOP( "ppdiblc1", B3SOIFD_MOD_PPDIBL1, IF_REAL, "Cross-term dependence of pdiblc1"), +IOP( "ppdiblc2", B3SOIFD_MOD_PPDIBL2, IF_REAL, "Cross-term dependence of pdiblc2"), +IOP( "ppdiblcb", B3SOIFD_MOD_PPDIBLB, IF_REAL, "Cross-term dependence of pdiblcb"), +IOP( "pdrout", B3SOIFD_MOD_PDROUT, IF_REAL, "Cross-term dependence of drout"), +IOP( "ppvag", B3SOIFD_MOD_PPVAG, IF_REAL, "Cross-term dependence of pvag"), +IOP( "pdelta", B3SOIFD_MOD_PDELTA, IF_REAL, "Cross-term dependence of delta"), +IOP( "paii", B3SOIFD_MOD_PAII, IF_REAL, "Cross-term dependence of aii"), +IOP( "pbii", B3SOIFD_MOD_PBII, IF_REAL, "Cross-term dependence of bii"), +IOP( "pcii", B3SOIFD_MOD_PCII, IF_REAL, "Cross-term dependence of cii"), +IOP( "pdii", B3SOIFD_MOD_PDII, IF_REAL, "Cross-term dependence of dii"), +IOP( "palpha0", B3SOIFD_MOD_PALPHA0, IF_REAL, "Cross-term dependence of alpha0"), +IOP( "palpha1", B3SOIFD_MOD_PALPHA1, IF_REAL, "Cross-term dependence of alpha1"), +IOP( "pbeta0", B3SOIFD_MOD_PBETA0, IF_REAL, "Cross-term dependence of beta0"), +IOP( "pagidl", B3SOIFD_MOD_PAGIDL, IF_REAL, "Cross-term dependence of agidl"), +IOP( "pbgidl", B3SOIFD_MOD_PBGIDL, IF_REAL, "Cross-term dependence of bgidl"), +IOP( "pngidl", B3SOIFD_MOD_PNGIDL, IF_REAL, "Cross-term dependence of ngidl"), +IOP( "pntun", B3SOIFD_MOD_PNTUN, IF_REAL, "Cross-term dependence of ntun"), +IOP( "pndiode", B3SOIFD_MOD_PNDIODE, IF_REAL, "Cross-term dependence of ndiode"), +IOP( "pisbjt", B3SOIFD_MOD_PISBJT, IF_REAL, "Cross-term dependence of isbjt"), +IOP( "pisdif", B3SOIFD_MOD_PISDIF, IF_REAL, "Cross-term dependence of isdif"), +IOP( "pisrec", B3SOIFD_MOD_PISREC, IF_REAL, "Cross-term dependence of isrec"), +IOP( "pistun", B3SOIFD_MOD_PISTUN, IF_REAL, "Cross-term dependence of istun"), +IOP( "pedl", B3SOIFD_MOD_PEDL, IF_REAL, "Cross-term dependence of edl"), +IOP( "pkbjt1", B3SOIFD_MOD_PKBJT1, IF_REAL, "Cross-term dependence of kbjt1"), +IOP( "pvsdfb", B3SOIFD_MOD_PVSDFB, IF_REAL, "Cross-term dependence of vsdfb"), +IOP( "pvsdth", B3SOIFD_MOD_PVSDTH, IF_REAL, "Cross-term dependence of vsdth"), +/* Added for binning - END */ + +IP( "nmos", B3SOIFD_MOD_NMOS, IF_FLAG, "Flag to indicate NMOS"), +IP( "pmos", B3SOIFD_MOD_PMOS, IF_FLAG, "Flag to indicate PMOS"), +}; + +char *B3SOIFDnames[] = { + "Drain", + "Gate", + "Source", + "Backgate", + "", + "Body", + "Temp", + "Charge", +}; + +int B3SOIFDnSize = NUMELEMS(B3SOIFDnames); +int B3SOIFDpTSize = NUMELEMS(B3SOIFDpTable); +int B3SOIFDmPTSize = NUMELEMS(B3SOIFDmPTable); +int B3SOIFDiSize = sizeof(B3SOIFDinstance); +int B3SOIFDmSize = sizeof(B3SOIFDmodel); + + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdacld.c b/src/spicelib/devices/bsim3soi_fd/b3soifdacld.c new file mode 100644 index 000000000..789353247 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdacld.c @@ -0,0 +1,443 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +Modified by Pin Su 99/9/27 +File: b3soifdacld.c 98/5/01 +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "b3soifddef.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIFDacLoad(inModel,ckt) +GENmodel *inModel; + CKTcircuit *ckt; +{ + B3SOIFDmodel *model = (B3SOIFDmodel*)inModel; + B3SOIFDinstance *here; + int selfheat; +double xcggb, xcgdb, xcgsb, xcgeb, xcgT; +double xcdgb, xcddb, xcdsb, xcdeb, xcdT; +double xcsgb, xcsdb, xcssb, xcseb, xcsT; +double xcbgb, xcbdb, xcbsb, xcbeb, xcbT; +double xcegb, xcedb, xcesb, xceeb, xceT; +double gdpr, gspr, gds; +double cggb, cgdb, cgsb, cgeb, cgT; +double cdgb, cddb, cdsb, cdeb, cdT; +double cbgb, cbdb, cbsb, cbeb, cbT; +double cegb, cedb, cesb, ceeb, ceT; +double GSoverlapCap, GDoverlapCap, GEoverlapCap, FwdSum, RevSum, Gm, Gmbs, Gme, GmT; +double omega; +double dxpart, sxpart; +double gbbg, gbbdp, gbbb, gbbe, gbbp, gbbsp, gbbT; +double gddpg, gddpdp, gddpsp, gddpb, gddpe, gddpT; +double gsspg, gsspdp, gsspsp, gsspb, gsspe, gsspT; +double gppg, gppdp, gppb, gppe, gppp, gppsp, gppT; +double xcTt, cTt, gcTt, gTtt, gTtg, gTtb, gTte, gTtdp, gTtsp; + +double Dum1, Dum2, Dum3, Dum4, Dum5; +FILE *fpdebug; + + omega = ckt->CKTomega; + for (; model != NULL; model = model->B3SOIFDnextModel) + { + + for (here = model->B3SOIFDinstances; here!= NULL; + here = here->B3SOIFDnextInstance) + { + selfheat = (model->B3SOIFDshMod == 1) && (here->B3SOIFDrth0 != 0.0); + if (here->B3SOIFDdebugMod > 2) + { + fpdebug = fopen("b3soifdac.log", "a"); + fprintf(fpdebug, ".......omega=%.5e\n", omega); + } + if (here->B3SOIFDmode >= 0) + { Gm = here->B3SOIFDgm; + Gmbs = here->B3SOIFDgmbs; + Gme = here->B3SOIFDgme; + GmT = model->B3SOIFDtype * here->B3SOIFDgmT; + FwdSum = Gm + Gmbs + Gme; + RevSum = 0.0; + + cbgb = here->B3SOIFDcbgb; + cbsb = here->B3SOIFDcbsb; + cbdb = here->B3SOIFDcbdb; + cbeb = here->B3SOIFDcbeb; + cbT = model->B3SOIFDtype * here->B3SOIFDcbT; + + cegb = here->B3SOIFDcegb; + cesb = here->B3SOIFDcesb; + cedb = here->B3SOIFDcedb; + ceeb = here->B3SOIFDceeb; + ceT = model->B3SOIFDtype * here->B3SOIFDceT; + + cggb = here->B3SOIFDcggb; + cgsb = here->B3SOIFDcgsb; + cgdb = here->B3SOIFDcgdb; + cgeb = here->B3SOIFDcgeb; + cgT = model->B3SOIFDtype * here->B3SOIFDcgT; + + cdgb = here->B3SOIFDcdgb; + cdsb = here->B3SOIFDcdsb; + cddb = here->B3SOIFDcddb; + cdeb = here->B3SOIFDcdeb; + cdT = model->B3SOIFDtype * here->B3SOIFDcdT; + + cTt = here->pParam->B3SOIFDcth; + + gbbg = -here->B3SOIFDgbgs; + gbbdp = -here->B3SOIFDgbds; + gbbb = -here->B3SOIFDgbbs; + gbbe = -here->B3SOIFDgbes; + gbbp = -here->B3SOIFDgbps; + gbbT = -model->B3SOIFDtype * here->B3SOIFDgbT; + gbbsp = - ( gbbg + gbbdp + gbbb + gbbe + gbbp); + + gddpg = -here->B3SOIFDgjdg; + gddpdp = -here->B3SOIFDgjdd; + gddpb = -here->B3SOIFDgjdb; + gddpe = -here->B3SOIFDgjde; + gddpT = -model->B3SOIFDtype * here->B3SOIFDgjdT; + gddpsp = - ( gddpg + gddpdp + gddpb + gddpe); + + gsspg = -here->B3SOIFDgjsg; + gsspdp = -here->B3SOIFDgjsd; + gsspb = -here->B3SOIFDgjsb; + gsspe = 0.0; + gsspT = -model->B3SOIFDtype * here->B3SOIFDgjsT; + gsspsp = - (gsspg + gsspdp + gsspb + gsspe); + + gppg = -here->B3SOIFDgbpgs; + gppdp = -here->B3SOIFDgbpds; + gppb = -here->B3SOIFDgbpbs; + gppe = -here->B3SOIFDgbpes; + gppp = -here->B3SOIFDgbpps; + gppT = -model->B3SOIFDtype * here->B3SOIFDgbpT; + gppsp = - (gppg + gppdp + gppb + gppe + gppp); + + gTtg = here->B3SOIFDgtempg; + gTtb = here->B3SOIFDgtempb; + gTte = here->B3SOIFDgtempe; + gTtdp = here->B3SOIFDgtempd; + gTtt = here->B3SOIFDgtempT; + gTtsp = - (gTtg + gTtb + gTte + gTtdp); + + sxpart = 0.6; + dxpart = 0.4; + + } + else + { Gm = -here->B3SOIFDgm; + Gmbs = -here->B3SOIFDgmbs; + Gme = -here->B3SOIFDgme; + GmT = -model->B3SOIFDtype * here->B3SOIFDgmT; + FwdSum = 0.0; + RevSum = -Gm - Gmbs - Gme; + + cdgb = - (here->B3SOIFDcdgb + here->B3SOIFDcggb + here->B3SOIFDcbgb + + here->B3SOIFDcegb); + cdsb = - (here->B3SOIFDcddb + here->B3SOIFDcgdb + here->B3SOIFDcbdb + + here->B3SOIFDcedb); + cddb = - (here->B3SOIFDcdsb + here->B3SOIFDcgsb + here->B3SOIFDcbsb + + here->B3SOIFDcesb); + cdeb = - (here->B3SOIFDcdeb + here->B3SOIFDcgeb + here->B3SOIFDcbeb + + here->B3SOIFDceeb); + cdT = - model->B3SOIFDtype * (here->B3SOIFDcgT + here->B3SOIFDcbT + + here->B3SOIFDcdT + here->B3SOIFDceT); + + cegb = here->B3SOIFDcegb; + cesb = here->B3SOIFDcedb; + cedb = here->B3SOIFDcesb; + ceeb = here->B3SOIFDceeb; + ceT = model->B3SOIFDtype * here->B3SOIFDceT; + + cggb = here->B3SOIFDcggb; + cgsb = here->B3SOIFDcgdb; + cgdb = here->B3SOIFDcgsb; + cgeb = here->B3SOIFDcgeb; + cgT = model->B3SOIFDtype * here->B3SOIFDcgT; + + cbgb = here->B3SOIFDcbgb; + cbsb = here->B3SOIFDcbdb; + cbdb = here->B3SOIFDcbsb; + cbeb = here->B3SOIFDcbeb; + cbT = model->B3SOIFDtype * here->B3SOIFDcbT; + + cTt = here->pParam->B3SOIFDcth; + + gbbg = -here->B3SOIFDgbgs; + gbbb = -here->B3SOIFDgbbs; + gbbe = -here->B3SOIFDgbes; + gbbp = -here->B3SOIFDgbps; + gbbsp = -here->B3SOIFDgbds; + gbbT = -model->B3SOIFDtype * here->B3SOIFDgbT; + gbbdp = - ( gbbg + gbbsp + gbbb + gbbe + gbbp); + + gddpg = -here->B3SOIFDgjsg; + gddpsp = -here->B3SOIFDgjsd; + gddpb = -here->B3SOIFDgjsb; + gddpe = 0.0; + gddpT = -model->B3SOIFDtype * here->B3SOIFDgjsT; + gddpdp = - (gddpg + gddpsp + gddpb + gddpe); + + gsspg = -here->B3SOIFDgjdg; + gsspsp = -here->B3SOIFDgjdd; + gsspb = -here->B3SOIFDgjdb; + gsspe = -here->B3SOIFDgjde; + gsspT = -model->B3SOIFDtype * here->B3SOIFDgjdT; + gsspdp = - ( gsspg + gsspsp + gsspb + gsspe); + + gppg = -here->B3SOIFDgbpgs; + gppsp = -here->B3SOIFDgbpds; + gppb = -here->B3SOIFDgbpbs; + gppe = -here->B3SOIFDgbpes; + gppp = -here->B3SOIFDgbpps; + gppT = -model->B3SOIFDtype * here->B3SOIFDgbpT; + gppdp = - (gppg + gppsp + gppb + gppe + gppp); + + gTtt = here->B3SOIFDgtempT; + gTtg = here->B3SOIFDgtempg; + gTtb = here->B3SOIFDgtempb; + gTte = here->B3SOIFDgtempe; + gTtdp = here->B3SOIFDgtempd; + gTtsp = - (gTtt + gTtg + gTtb + gTte + gTtdp); + + gTtg = here->B3SOIFDgtempg; + gTtb = here->B3SOIFDgtempb; + gTte = here->B3SOIFDgtempe; + gTtsp = here->B3SOIFDgtempd; + gTtt = here->B3SOIFDgtempT; + gTtdp = - (gTtg + gTtb + gTte + gTtsp); + + sxpart = 0.6; + sxpart = 0.4; + dxpart = 0.6; + } + + gdpr=here->B3SOIFDdrainConductance; + gspr=here->B3SOIFDsourceConductance; + gds= here->B3SOIFDgds; + + GSoverlapCap = here->B3SOIFDcgso; + GDoverlapCap = here->B3SOIFDcgdo; + GEoverlapCap = here->pParam->B3SOIFDcgeo; + + xcegb = (cegb - GEoverlapCap) * omega; + xcedb = cedb * omega; + xcesb = cesb * omega; + xceeb = (ceeb + GEoverlapCap) * omega; + xceT = ceT * omega; + + xcggb = (cggb + GDoverlapCap + GSoverlapCap + GEoverlapCap) + * omega; + xcgdb = (cgdb - GDoverlapCap ) * omega; + xcgsb = (cgsb - GSoverlapCap) * omega; + xcgeb = (cgeb - GEoverlapCap) * omega; + xcgT = cgT * omega; + + xcdgb = (cdgb - GDoverlapCap) * omega; + xcddb = (cddb + GDoverlapCap) * omega; + xcdsb = cdsb * omega; + xcdeb = cdeb * omega; + xcdT = cdT * omega; + + xcsgb = -(cggb + cbgb + cdgb + cegb + GSoverlapCap) * omega; + xcsdb = -(cgdb + cbdb + cddb + cedb) * omega; + xcssb = (GSoverlapCap - (cgsb + cbsb + cdsb + cesb)) * omega; + xcseb = -(cgeb + cbeb + cdeb + ceeb) * omega; + xcsT = -(cgT + cbT + cdT + ceT) * omega; + + xcbgb = cbgb * omega; + xcbdb = cbdb * omega; + xcbsb = cbsb * omega; + xcbeb = cbeb * omega; + xcbT = cbT * omega; + + xcTt = cTt * omega; + + *(here->B3SOIFDEgPtr +1) += xcegb; + *(here->B3SOIFDEdpPtr +1) += xcedb; + *(here->B3SOIFDEspPtr +1) += xcesb; + *(here->B3SOIFDGePtr +1) += xcgeb; + *(here->B3SOIFDDPePtr +1) += xcdeb; + *(here->B3SOIFDSPePtr +1) += xcseb; + + *(here->B3SOIFDEePtr +1) += xceeb; + + *(here->B3SOIFDGgPtr +1) += xcggb; + *(here->B3SOIFDGdpPtr +1) += xcgdb; + *(here->B3SOIFDGspPtr +1) += xcgsb; + + *(here->B3SOIFDDPgPtr +1) += xcdgb; + *(here->B3SOIFDDPdpPtr +1) += xcddb; + *(here->B3SOIFDDPspPtr +1) += xcdsb; + + *(here->B3SOIFDSPgPtr +1) += xcsgb; + *(here->B3SOIFDSPdpPtr +1) += xcsdb; + *(here->B3SOIFDSPspPtr +1) += xcssb; + + if (selfheat) + { + *(here->B3SOIFDTemptempPtr + 1) += xcTt; + *(here->B3SOIFDDPtempPtr + 1) += xcdT; + *(here->B3SOIFDSPtempPtr + 1) += xcsT; + *(here->B3SOIFDBtempPtr + 1) += xcbT; + *(here->B3SOIFDEtempPtr + 1) += xceT; + *(here->B3SOIFDGtempPtr + 1) += xcgT; + } + + +if (here->B3SOIFDdebugMod > 3) +{ +fprintf(fpdebug, "Cbg+Cbs+Cbe = %.5e; Cbd = %.5e;\n", +(xcbgb+xcbsb+xcbeb)/omega, xcbdb/omega); +fprintf(fpdebug, "gbs = %.5e; gbd = %.5e\n", gbbsp, gbbdp); + + + fprintf(fpdebug, "AC condunctance...\n"); + fprintf(fpdebug, "Eg=%.5e; Edp=%.5e; Esp=%.5e;\nEb=%.5e; Ee=%.5e\n", +xcegb, xcedb, xcesb, -(xcegb+xcedb+xcesb+xceeb), xceeb); + fprintf(fpdebug, "Gg=%.5e; Gdp=%.5e; Gsp=%.5e;\nGb=%.5e; Ge=%.5e\n", +xcggb, xcgdb, xcgsb, -(xcggb+xcgdb+xcgsb+xcgeb), xcgeb); + fprintf(fpdebug, "Bg=%.5e; Bdp=%.5e; Bsp=%.5e;\nBb=%.5e; Be=%.5e\n", +xcbgb, xcbdb, xcbsb, -(xcbgb+xcbdb+xcbsb+xcbeb), xcbeb); + fprintf(fpdebug, "DPg=%.5e; DPdp=%.5e; DPsp=%.5e;\nDPb=%.5e; DPe=%.5e\n", +xcdgb, xcddb, xcdsb, -(xcdgb+xcddb+xcdsb+xcdeb), xcdeb); + fprintf(fpdebug, "SPg=%.5e; SPdp=%.5e; SPsp=%.5e;\nSPb=%.5e; SPe=%.5e\n", +xcsgb, xcsdb, xcssb, -(xcsgb+xcsdb+xcssb+xcseb), xcseb); +} + + + + *(here->B3SOIFDEgPtr) += 0.0; + *(here->B3SOIFDEdpPtr) += 0.0; + *(here->B3SOIFDEspPtr) += 0.0; + *(here->B3SOIFDGePtr) -= 0.0; + *(here->B3SOIFDDPePtr) += Gme + gddpe; + *(here->B3SOIFDSPePtr) += gsspe - Gme; + + *(here->B3SOIFDEePtr) += 0.0; + + *(here->B3SOIFDDPgPtr) += Gm + gddpg; + *(here->B3SOIFDDPdpPtr) += gdpr + gds + gddpdp + RevSum ; + *(here->B3SOIFDDPspPtr) -= gds + FwdSum - gddpsp; + *(here->B3SOIFDDPdPtr) -= gdpr; + + *(here->B3SOIFDSPgPtr) -= Gm - gsspg; + *(here->B3SOIFDSPdpPtr) -= gds + RevSum - gsspdp; + *(here->B3SOIFDSPspPtr) += gspr + gds + FwdSum + gsspsp; + *(here->B3SOIFDSPsPtr) -= gspr; + + if (selfheat) + { + *(here->B3SOIFDDPtempPtr) += GmT + gddpT; + *(here->B3SOIFDSPtempPtr) += -GmT + gsspT; + *(here->B3SOIFDBtempPtr) += gbbT; + if (here->B3SOIFDbodyMod == 1) { + (*(here->B3SOIFDPtempPtr) += gppT); + } + + *(here->B3SOIFDTemptempPtr) += gTtt + 1/here->pParam->B3SOIFDrth; + *(here->B3SOIFDTempgPtr) += gTtg; + *(here->B3SOIFDTempbPtr) += gTtb; + *(here->B3SOIFDTempePtr) += gTte; + *(here->B3SOIFDTempdpPtr) += gTtdp; + *(here->B3SOIFDTempspPtr) += gTtsp; + } + +if (here->B3SOIFDdebugMod > 3) +{ + fprintf(fpdebug, "Static condunctance...\n"); + fprintf(fpdebug, "Gg=%.5e; Gdp=%.5e; Gsp=%.5e;\nGb=%.5e; Ge=%.5e\n", + *(here->B3SOIFDGgPtr), *(here->B3SOIFDGdpPtr), + *(here->B3SOIFDGspPtr), *(here->B3SOIFDGbPtr), + *(here->B3SOIFDGePtr)); + fprintf(fpdebug, "DPg=%.5e; DPdp=%.5e; DPsp=%.5e;\nDPb=%.5e; DPe=%.5e\n", + *(here->B3SOIFDDPgPtr), *(here->B3SOIFDDPdpPtr), + *(here->B3SOIFDDPspPtr), *(here->B3SOIFDDPbPtr), + *(here->B3SOIFDDPePtr)); + fprintf(fpdebug, "SPg=%.5e; SPdp=%.5e; SPsp=%.5e;\nSPb=%.5e; SPe=%.5e\n", + *(here->B3SOIFDSPgPtr), *(here->B3SOIFDSPdpPtr), + *(here->B3SOIFDSPspPtr), *(here->B3SOIFDSPbPtr), + *(here->B3SOIFDSPePtr)); + fprintf(fpdebug, "Bg=%.5e; Bdp=%.5e; Bsp=%.5e;\nBb=%.5e; Be=%.5e\n", +gbbg, gbbdp, gbbsp, gbbb, gbbe); +} + + *(here->B3SOIFDDdPtr) += gdpr; + *(here->B3SOIFDDdpPtr) -= gdpr; + *(here->B3SOIFDSsPtr) += gspr; + *(here->B3SOIFDSspPtr) -= gspr; + + + if (here->B3SOIFDbodyMod == 1) { + (*(here->B3SOIFDBpPtr) -= gppp); + (*(here->B3SOIFDPbPtr) += gppb); + (*(here->B3SOIFDPpPtr) += gppp); + (*(here->B3SOIFDPgPtr) += gppg); + (*(here->B3SOIFDPdpPtr) += gppdp); + (*(here->B3SOIFDPspPtr) += gppsp); + (*(here->B3SOIFDPePtr) += gppe); + } + if (here->B3SOIFDdebugMod > 1) + { + *(here->B3SOIFDVbsPtr) += 1; + *(here->B3SOIFDIdsPtr) += 1; + *(here->B3SOIFDIcPtr) += 1; + *(here->B3SOIFDIbsPtr) += 1; + *(here->B3SOIFDIbdPtr) += 1; + *(here->B3SOIFDIiiPtr) += 1; + *(here->B3SOIFDIgidlPtr) += 1; + *(here->B3SOIFDItunPtr) += 1; + *(here->B3SOIFDIbpPtr) += 1; + *(here->B3SOIFDAbeffPtr) += 1; + *(here->B3SOIFDVbs0effPtr) += 1; + *(here->B3SOIFDVbseffPtr) += 1; + *(here->B3SOIFDXcPtr) += 1; + *(here->B3SOIFDCbgPtr) += 1; + *(here->B3SOIFDCbbPtr) += 1; + *(here->B3SOIFDCbdPtr) += 1; + *(here->B3SOIFDqbPtr) += 1; + *(here->B3SOIFDQbfPtr) += 1; + *(here->B3SOIFDQjsPtr) += 1; + *(here->B3SOIFDQjdPtr) += 1; + + /* clean up last */ + *(here->B3SOIFDGmPtr) += 1; + *(here->B3SOIFDGmbsPtr) += 1; + *(here->B3SOIFDGdsPtr) += 1; + *(here->B3SOIFDGmePtr) += 1; + *(here->B3SOIFDVbs0teffPtr) += 1; + *(here->B3SOIFDVgsteffPtr) += 1; + *(here->B3SOIFDCbePtr) += 1; + *(here->B3SOIFDVthPtr) += 1; + *(here->B3SOIFDXcsatPtr) += 1; + *(here->B3SOIFDVdscvPtr) += 1; + *(here->B3SOIFDVcscvPtr) += 1; + *(here->B3SOIFDQaccPtr) += 1; + *(here->B3SOIFDQsub0Ptr) += 1; + *(here->B3SOIFDQsubs1Ptr) += 1; + *(here->B3SOIFDQsubs2Ptr) += 1; + *(here->B3SOIFDqgPtr) += 1; + *(here->B3SOIFDqdPtr) += 1; + *(here->B3SOIFDqePtr) += 1; + *(here->B3SOIFDDum1Ptr) += 1; + *(here->B3SOIFDDum2Ptr) += 1; + *(here->B3SOIFDDum3Ptr) += 1; + *(here->B3SOIFDDum4Ptr) += 1; + *(here->B3SOIFDDum5Ptr) += 1; + } + + if (here->B3SOIFDdebugMod > 2) + fclose(fpdebug); + } + } + return(OK); +} + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdask.c b/src/spicelib/devices/bsim3soi_fd/b3soifdask.c new file mode 100644 index 000000000..7434cb37c --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdask.c @@ -0,0 +1,214 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soifdask.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "ifsim.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "b3soifddef.h" +#include "sperror.h" +#include "suffix.h" + +int +B3SOIFDask(ckt,inst,which,value,select) +CKTcircuit *ckt; +GENinstance *inst; +int which; +IFvalue *value; +IFvalue *select; +{ +B3SOIFDinstance *here = (B3SOIFDinstance*)inst; + + switch(which) + { case B3SOIFD_L: + value->rValue = here->B3SOIFDl; + return(OK); + case B3SOIFD_W: + value->rValue = here->B3SOIFDw; + return(OK); + case B3SOIFD_AS: + value->rValue = here->B3SOIFDsourceArea; + return(OK); + case B3SOIFD_AD: + value->rValue = here->B3SOIFDdrainArea; + return(OK); + case B3SOIFD_PS: + value->rValue = here->B3SOIFDsourcePerimeter; + return(OK); + case B3SOIFD_PD: + value->rValue = here->B3SOIFDdrainPerimeter; + return(OK); + case B3SOIFD_NRS: + value->rValue = here->B3SOIFDsourceSquares; + return(OK); + case B3SOIFD_NRD: + value->rValue = here->B3SOIFDdrainSquares; + return(OK); + case B3SOIFD_OFF: + value->rValue = here->B3SOIFDoff; + return(OK); + case B3SOIFD_BJTOFF: + value->iValue = here->B3SOIFDbjtoff; + return(OK); + case B3SOIFD_RTH0: + value->rValue = here->B3SOIFDrth0; + return(OK); + case B3SOIFD_CTH0: + value->rValue = here->B3SOIFDcth0; + return(OK); + case B3SOIFD_NRB: + value->rValue = here->B3SOIFDbodySquares; + return(OK); + case B3SOIFD_IC_VBS: + value->rValue = here->B3SOIFDicVBS; + return(OK); + case B3SOIFD_IC_VDS: + value->rValue = here->B3SOIFDicVDS; + return(OK); + case B3SOIFD_IC_VGS: + value->rValue = here->B3SOIFDicVGS; + return(OK); + case B3SOIFD_IC_VES: + value->rValue = here->B3SOIFDicVES; + return(OK); + case B3SOIFD_IC_VPS: + value->rValue = here->B3SOIFDicVPS; + return(OK); + case B3SOIFD_DNODE: + value->iValue = here->B3SOIFDdNode; + return(OK); + case B3SOIFD_GNODE: + value->iValue = here->B3SOIFDgNode; + return(OK); + case B3SOIFD_SNODE: + value->iValue = here->B3SOIFDsNode; + return(OK); + case B3SOIFD_BNODE: + value->iValue = here->B3SOIFDbNode; + return(OK); + case B3SOIFD_ENODE: + value->iValue = here->B3SOIFDeNode; + return(OK); + case B3SOIFD_DNODEPRIME: + value->iValue = here->B3SOIFDdNodePrime; + return(OK); + case B3SOIFD_SNODEPRIME: + value->iValue = here->B3SOIFDsNodePrime; + return(OK); + case B3SOIFD_SOURCECONDUCT: + value->rValue = here->B3SOIFDsourceConductance; + return(OK); + case B3SOIFD_DRAINCONDUCT: + value->rValue = here->B3SOIFDdrainConductance; + return(OK); + case B3SOIFD_VBD: + value->rValue = *(ckt->CKTstate0 + here->B3SOIFDvbd); + return(OK); + case B3SOIFD_VBS: + value->rValue = *(ckt->CKTstate0 + here->B3SOIFDvbs); + return(OK); + case B3SOIFD_VGS: + value->rValue = *(ckt->CKTstate0 + here->B3SOIFDvgs); + return(OK); + case B3SOIFD_VES: + value->rValue = *(ckt->CKTstate0 + here->B3SOIFDves); + return(OK); + case B3SOIFD_VDS: + value->rValue = *(ckt->CKTstate0 + here->B3SOIFDvds); + return(OK); + case B3SOIFD_CD: + value->rValue = here->B3SOIFDcd; + return(OK); + case B3SOIFD_CBS: + value->rValue = here->B3SOIFDcjs; + return(OK); + case B3SOIFD_CBD: + value->rValue = here->B3SOIFDcjd; + return(OK); + case B3SOIFD_GM: + value->rValue = here->B3SOIFDgm; + return(OK); + case B3SOIFD_GMID: + value->rValue = here->B3SOIFDgm/here->B3SOIFDcd; + return(OK); + case B3SOIFD_GDS: + value->rValue = here->B3SOIFDgds; + return(OK); + case B3SOIFD_GMBS: + value->rValue = here->B3SOIFDgmbs; + return(OK); + case B3SOIFD_GBD: + value->rValue = here->B3SOIFDgjdb; + return(OK); + case B3SOIFD_GBS: + value->rValue = here->B3SOIFDgjsb; + return(OK); + case B3SOIFD_QB: + value->rValue = *(ckt->CKTstate0 + here->B3SOIFDqb); + return(OK); + case B3SOIFD_CQB: + value->rValue = *(ckt->CKTstate0 + here->B3SOIFDcqb); + return(OK); + case B3SOIFD_QG: + value->rValue = *(ckt->CKTstate0 + here->B3SOIFDqg); + return(OK); + case B3SOIFD_CQG: + value->rValue = *(ckt->CKTstate0 + here->B3SOIFDcqg); + return(OK); + case B3SOIFD_QD: + value->rValue = *(ckt->CKTstate0 + here->B3SOIFDqd); + return(OK); + case B3SOIFD_CQD: + value->rValue = *(ckt->CKTstate0 + here->B3SOIFDcqd); + return(OK); + case B3SOIFD_CGG: + value->rValue = here->B3SOIFDcggb; + return(OK); + case B3SOIFD_CGD: + value->rValue = here->B3SOIFDcgdb; + return(OK); + case B3SOIFD_CGS: + value->rValue = here->B3SOIFDcgsb; + return(OK); + case B3SOIFD_CDG: + value->rValue = here->B3SOIFDcdgb; + return(OK); + case B3SOIFD_CDD: + value->rValue = here->B3SOIFDcddb; + return(OK); + case B3SOIFD_CDS: + value->rValue = here->B3SOIFDcdsb; + return(OK); + case B3SOIFD_CBG: + value->rValue = here->B3SOIFDcbgb; + return(OK); + case B3SOIFD_CBDB: + value->rValue = here->B3SOIFDcbdb; + return(OK); + case B3SOIFD_CBSB: + value->rValue = here->B3SOIFDcbsb; + return(OK); + case B3SOIFD_VON: + value->rValue = here->B3SOIFDvon; + return(OK); + case B3SOIFD_VDSAT: + value->rValue = here->B3SOIFDvdsat; + return(OK); + case B3SOIFD_QBS: + value->rValue = *(ckt->CKTstate0 + here->B3SOIFDqbs); + return(OK); + case B3SOIFD_QBD: + value->rValue = *(ckt->CKTstate0 + here->B3SOIFDqbd); + return(OK); + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdcheck.c b/src/spicelib/devices/bsim3soi_fd/b3soifdcheck.c new file mode 100644 index 000000000..c0e1a2a4f --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdcheck.c @@ -0,0 +1,504 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soifdcheck.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "b3soifddef.h" +#include "trandefs.h" +#include "const.h" +#include "sperror.h" +#include "devdefs.h" +#include "suffix.h" + +int +B3SOIFDcheckModel(model, here, ckt) + B3SOIFDmodel *model; + B3SOIFDinstance *here; +CKTcircuit *ckt; +{ +struct b3soifdSizeDependParam *pParam; +int Fatal_Flag = 0; +FILE *fplog; + + if ((fplog = fopen("b3soifdv1check.log", "w")) != NULL) + { pParam = here->pParam; + fprintf(fplog, "B3SOIFDV3 Parameter Check\n"); + fprintf(fplog, "Model = %s\n", model->B3SOIFDmodName); + fprintf(fplog, "W = %g, L = %g\n", here->B3SOIFDw, here->B3SOIFDl); + + + if (pParam->B3SOIFDnlx < -pParam->B3SOIFDleff) + { fprintf(fplog, "Fatal: Nlx = %g is less than -Leff.\n", + pParam->B3SOIFDnlx); + printf("Fatal: Nlx = %g is less than -Leff.\n", + pParam->B3SOIFDnlx); + Fatal_Flag = 1; + } + + if (model->B3SOIFDtox <= 0.0) + { fprintf(fplog, "Fatal: Tox = %g is not positive.\n", + model->B3SOIFDtox); + printf("Fatal: Tox = %g is not positive.\n", model->B3SOIFDtox); + Fatal_Flag = 1; + } + + if (model->B3SOIFDtbox <= 0.0) + { fprintf(fplog, "Fatal: Tbox = %g is not positive.\n", + model->B3SOIFDtbox); + printf("Fatal: Tbox = %g is not positive.\n", model->B3SOIFDtbox); + Fatal_Flag = 1; + } + + if (pParam->B3SOIFDnpeak <= 0.0) + { fprintf(fplog, "Fatal: Nch = %g is not positive.\n", + pParam->B3SOIFDnpeak); + printf("Fatal: Nch = %g is not positive.\n", + pParam->B3SOIFDnpeak); + Fatal_Flag = 1; + } + if (pParam->B3SOIFDngate < 0.0) + { fprintf(fplog, "Fatal: Ngate = %g is not positive.\n", + pParam->B3SOIFDngate); + printf("Fatal: Ngate = %g Ngate is not positive.\n", + pParam->B3SOIFDngate); + Fatal_Flag = 1; + } + if (pParam->B3SOIFDngate > 1.e25) + { fprintf(fplog, "Fatal: Ngate = %g is too high.\n", + pParam->B3SOIFDngate); + printf("Fatal: Ngate = %g Ngate is too high\n", + pParam->B3SOIFDngate); + Fatal_Flag = 1; + } + + if (model->B3SOIFDdvbd1 < 0.0) + { fprintf(fplog, "Fatal: Dvbd1 = %g is negative.\n", + model->B3SOIFDdvbd1); + printf("Fatal: Dvbd1 = %g is negative.\n", model->B3SOIFDdvbd1); + Fatal_Flag = 1; + } + + if (pParam->B3SOIFDdvt1 < 0.0) + { fprintf(fplog, "Fatal: Dvt1 = %g is negative.\n", + pParam->B3SOIFDdvt1); + printf("Fatal: Dvt1 = %g is negative.\n", pParam->B3SOIFDdvt1); + Fatal_Flag = 1; + } + + if (pParam->B3SOIFDdvt1w < 0.0) + { fprintf(fplog, "Fatal: Dvt1w = %g is negative.\n", + pParam->B3SOIFDdvt1w); + printf("Fatal: Dvt1w = %g is negative.\n", pParam->B3SOIFDdvt1w); + Fatal_Flag = 1; + } + + if (pParam->B3SOIFDw0 == -pParam->B3SOIFDweff) + { fprintf(fplog, "Fatal: (W0 + Weff) = 0 cauing divided-by-zero.\n"); + printf("Fatal: (W0 + Weff) = 0 cauing divided-by-zero.\n"); + Fatal_Flag = 1; + } + + if (pParam->B3SOIFDdsub < 0.0) + { fprintf(fplog, "Fatal: Dsub = %g is negative.\n", pParam->B3SOIFDdsub); + printf("Fatal: Dsub = %g is negative.\n", pParam->B3SOIFDdsub); + Fatal_Flag = 1; + } + if (pParam->B3SOIFDb1 == -pParam->B3SOIFDweff) + { fprintf(fplog, "Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n"); + printf("Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n"); + Fatal_Flag = 1; + } + if (pParam->B3SOIFDu0temp <= 0.0) + { fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", pParam->B3SOIFDu0temp); + printf("Fatal: u0 at current temperature = %g is not positive.\n", + pParam->B3SOIFDu0temp); + Fatal_Flag = 1; + } + +/* Check delta parameter */ + if (pParam->B3SOIFDdelta < 0.0) + { fprintf(fplog, "Fatal: Delta = %g is less than zero.\n", + pParam->B3SOIFDdelta); + printf("Fatal: Delta = %g is less than zero.\n", pParam->B3SOIFDdelta); + Fatal_Flag = 1; + } + + if (pParam->B3SOIFDvsattemp <= 0.0) + { fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", pParam->B3SOIFDvsattemp); + printf("Fatal: Vsat at current temperature = %g is not positive.\n", + pParam->B3SOIFDvsattemp); + Fatal_Flag = 1; + } +/* Check Rout parameters */ + if (pParam->B3SOIFDpclm <= 0.0) + { fprintf(fplog, "Fatal: Pclm = %g is not positive.\n", pParam->B3SOIFDpclm); + printf("Fatal: Pclm = %g is not positive.\n", pParam->B3SOIFDpclm); + Fatal_Flag = 1; + } + + if (pParam->B3SOIFDdrout < 0.0) + { fprintf(fplog, "Fatal: Drout = %g is negative.\n", pParam->B3SOIFDdrout); + printf("Fatal: Drout = %g is negative.\n", pParam->B3SOIFDdrout); + Fatal_Flag = 1; + } + if ( model->B3SOIFDunitLengthGateSidewallJctCap > 0.0) + { + if (here->B3SOIFDdrainPerimeter < pParam->B3SOIFDweff) + { fprintf(fplog, "Warning: Pd = %g is less than W.\n", + here->B3SOIFDdrainPerimeter); + printf("Warning: Pd = %g is less than W.\n", + here->B3SOIFDdrainPerimeter); + here->B3SOIFDdrainPerimeter =pParam->B3SOIFDweff; + } + if (here->B3SOIFDsourcePerimeter < pParam->B3SOIFDweff) + { fprintf(fplog, "Warning: Ps = %g is less than W.\n", + here->B3SOIFDsourcePerimeter); + printf("Warning: Ps = %g is less than W.\n", + here->B3SOIFDsourcePerimeter); + here->B3SOIFDsourcePerimeter =pParam->B3SOIFDweff; + } + } +/* Check capacitance parameters */ + if (pParam->B3SOIFDclc < 0.0) + { fprintf(fplog, "Fatal: Clc = %g is negative.\n", pParam->B3SOIFDclc); + printf("Fatal: Clc = %g is negative.\n", pParam->B3SOIFDclc); + Fatal_Flag = 1; + } + if (model->B3SOIFDparamChk ==1) + { +/* Check L and W parameters */ + if (pParam->B3SOIFDleff <= 5.0e-8) + { fprintf(fplog, "Warning: Leff = %g may be too small.\n", + pParam->B3SOIFDleff); + printf("Warning: Leff = %g may be too small.\n", + pParam->B3SOIFDleff); + } + + if (pParam->B3SOIFDleffCV <= 5.0e-8) + { fprintf(fplog, "Warning: Leff for CV = %g may be too small.\n", + pParam->B3SOIFDleffCV); + printf("Warning: Leff for CV = %g may be too small.\n", + pParam->B3SOIFDleffCV); + } + + if (pParam->B3SOIFDweff <= 1.0e-7) + { fprintf(fplog, "Warning: Weff = %g may be too small.\n", + pParam->B3SOIFDweff); + printf("Warning: Weff = %g may be too small.\n", + pParam->B3SOIFDweff); + } + + if (pParam->B3SOIFDweffCV <= 1.0e-7) + { fprintf(fplog, "Warning: Weff for CV = %g may be too small.\n", + pParam->B3SOIFDweffCV); + printf("Warning: Weff for CV = %g may be too small.\n", + pParam->B3SOIFDweffCV); + } + +/* Check threshold voltage parameters */ + if (pParam->B3SOIFDnlx < 0.0) + { fprintf(fplog, "Warning: Nlx = %g is negative.\n", pParam->B3SOIFDnlx); + printf("Warning: Nlx = %g is negative.\n", pParam->B3SOIFDnlx); + } + if (model->B3SOIFDtox < 1.0e-9) + { fprintf(fplog, "Warning: Tox = %g is less than 10A.\n", + model->B3SOIFDtox); + printf("Warning: Tox = %g is less than 10A.\n", model->B3SOIFDtox); + } + + if (pParam->B3SOIFDnpeak <= 1.0e15) + { fprintf(fplog, "Warning: Nch = %g may be too small.\n", + pParam->B3SOIFDnpeak); + printf("Warning: Nch = %g may be too small.\n", + pParam->B3SOIFDnpeak); + } + else if (pParam->B3SOIFDnpeak >= 1.0e21) + { fprintf(fplog, "Warning: Nch = %g may be too large.\n", + pParam->B3SOIFDnpeak); + printf("Warning: Nch = %g may be too large.\n", + pParam->B3SOIFDnpeak); + } + + if (fabs(pParam->B3SOIFDnsub) >= 1.0e21) + { fprintf(fplog, "Warning: Nsub = %g may be too large.\n", + pParam->B3SOIFDnsub); + printf("Warning: Nsub = %g may be too large.\n", + pParam->B3SOIFDnsub); + } + + if ((pParam->B3SOIFDngate > 0.0) && + (pParam->B3SOIFDngate <= 1.e18)) + { fprintf(fplog, "Warning: Ngate = %g is less than 1.E18cm^-3.\n", + pParam->B3SOIFDngate); + printf("Warning: Ngate = %g is less than 1.E18cm^-3.\n", + pParam->B3SOIFDngate); + } + + if (model->B3SOIFDdvbd0 < 0.0) + { fprintf(fplog, "Warning: Dvbd0 = %g is negative.\n", + model->B3SOIFDdvbd0); + printf("Warning: Dvbd0 = %g is negative.\n", model->B3SOIFDdvbd0); + } + + if (pParam->B3SOIFDdvt0 < 0.0) + { fprintf(fplog, "Warning: Dvt0 = %g is negative.\n", + pParam->B3SOIFDdvt0); + printf("Warning: Dvt0 = %g is negative.\n", pParam->B3SOIFDdvt0); + } + + if (fabs(1.0e-6 / (pParam->B3SOIFDw0 + pParam->B3SOIFDweff)) > 10.0) + { fprintf(fplog, "Warning: (W0 + Weff) may be too small.\n"); + printf("Warning: (W0 + Weff) may be too small.\n"); + } + +/* Check subthreshold parameters */ + if (pParam->B3SOIFDnfactor < 0.0) + { fprintf(fplog, "Warning: Nfactor = %g is negative.\n", + pParam->B3SOIFDnfactor); + printf("Warning: Nfactor = %g is negative.\n", pParam->B3SOIFDnfactor); + } + if (model->B3SOIFDkb3 < 0.0) + { fprintf(fplog, "Warning: Kb3 = %g is negative.\n", + model->B3SOIFDkb3); + printf("Warning: Kb3 = %g is negative.\n", model->B3SOIFDkb3); + } + + if (pParam->B3SOIFDcdsc < 0.0) + { fprintf(fplog, "Warning: Cdsc = %g is negative.\n", + pParam->B3SOIFDcdsc); + printf("Warning: Cdsc = %g is negative.\n", pParam->B3SOIFDcdsc); + } + if (pParam->B3SOIFDcdscd < 0.0) + { fprintf(fplog, "Warning: Cdscd = %g is negative.\n", + pParam->B3SOIFDcdscd); + printf("Warning: Cdscd = %g is negative.\n", pParam->B3SOIFDcdscd); + } +/* Check DIBL parameters */ + if (pParam->B3SOIFDeta0 < 0.0) + { fprintf(fplog, "Warning: Eta0 = %g is negative.\n", + pParam->B3SOIFDeta0); + printf("Warning: Eta0 = %g is negative.\n", pParam->B3SOIFDeta0); + } + +/* Check Abulk parameters */ + if (fabs(1.0e-6 / (pParam->B3SOIFDb1 + pParam->B3SOIFDweff)) > 10.0) + { fprintf(fplog, "Warning: (B1 + Weff) may be too small.\n"); + printf("Warning: (B1 + Weff) may be too small.\n"); + } + + if (model->B3SOIFDadice0 > 1.0) + { fprintf(fplog, "Warning: Adice0 = %g should be smaller than 1.\n", + model->B3SOIFDadice0); + printf("Warning: Adice0 = %g should be smaller than 1.\n", model->B3SOIFDadice0); + } + + if (model->B3SOIFDabp < 0.2) + { fprintf(fplog, "Warning: Abp = %g is too small.\n", + model->B3SOIFDabp); + printf("Warning: Abp = %g is too small.\n", model->B3SOIFDabp); + } + + if ((model->B3SOIFDmxc < -1.0) || (model->B3SOIFDmxc > 1.0)) + { fprintf(fplog, "Warning: Mxc = %g should be within (-1, 1).\n", + model->B3SOIFDmxc); + printf("Warning: Mxc = %g should be within (-1, 1).\n", model->B3SOIFDmxc); + } + +/* Check Saturation parameters */ + if (pParam->B3SOIFDa2 < 0.01) + { fprintf(fplog, "Warning: A2 = %g is too small. Set to 0.01.\n", pParam->B3SOIFDa2); + printf("Warning: A2 = %g is too small. Set to 0.01.\n", + pParam->B3SOIFDa2); + pParam->B3SOIFDa2 = 0.01; + } + else if (pParam->B3SOIFDa2 > 1.0) + { fprintf(fplog, "Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n", + pParam->B3SOIFDa2); + printf("Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n", + pParam->B3SOIFDa2); + pParam->B3SOIFDa2 = 1.0; + pParam->B3SOIFDa1 = 0.0; + + } + + if (pParam->B3SOIFDrdsw < 0.0) + { fprintf(fplog, "Warning: Rdsw = %g is negative. Set to zero.\n", + pParam->B3SOIFDrdsw); + printf("Warning: Rdsw = %g is negative. Set to zero.\n", + pParam->B3SOIFDrdsw); + pParam->B3SOIFDrdsw = 0.0; + pParam->B3SOIFDrds0 = 0.0; + } + else if ((pParam->B3SOIFDrds0 > 0.0) && (pParam->B3SOIFDrds0 < 0.001)) + { fprintf(fplog, "Warning: Rds at current temperature = %g is less than 0.001 ohm. Set to zero.\n", + pParam->B3SOIFDrds0); + printf("Warning: Rds at current temperature = %g is less than 0.001 ohm. Set to zero.\n", + pParam->B3SOIFDrds0); + pParam->B3SOIFDrds0 = 0.0; + } + if (pParam->B3SOIFDvsattemp < 1.0e3) + { fprintf(fplog, "Warning: Vsat at current temperature = %g may be too small.\n", pParam->B3SOIFDvsattemp); + printf("Warning: Vsat at current temperature = %g may be too small.\n", pParam->B3SOIFDvsattemp); + } + + if (pParam->B3SOIFDpdibl1 < 0.0) + { fprintf(fplog, "Warning: Pdibl1 = %g is negative.\n", + pParam->B3SOIFDpdibl1); + printf("Warning: Pdibl1 = %g is negative.\n", pParam->B3SOIFDpdibl1); + } + if (pParam->B3SOIFDpdibl2 < 0.0) + { fprintf(fplog, "Warning: Pdibl2 = %g is negative.\n", + pParam->B3SOIFDpdibl2); + printf("Warning: Pdibl2 = %g is negative.\n", pParam->B3SOIFDpdibl2); + } +/* Check overlap capacitance parameters */ + if (model->B3SOIFDcgdo < 0.0) + { fprintf(fplog, "Warning: cgdo = %g is negative. Set to zero.\n", model->B3SOIFDcgdo); + printf("Warning: cgdo = %g is negative. Set to zero.\n", model->B3SOIFDcgdo); + model->B3SOIFDcgdo = 0.0; + } + if (model->B3SOIFDcgso < 0.0) + { fprintf(fplog, "Warning: cgso = %g is negative. Set to zero.\n", model->B3SOIFDcgso); + printf("Warning: cgso = %g is negative. Set to zero.\n", model->B3SOIFDcgso); + model->B3SOIFDcgso = 0.0; + } + if (model->B3SOIFDcgeo < 0.0) + { fprintf(fplog, "Warning: cgeo = %g is negative. Set to zero.\n", model->B3SOIFDcgeo); + printf("Warning: cgeo = %g is negative. Set to zero.\n", model->B3SOIFDcgeo); + model->B3SOIFDcgeo = 0.0; + } + + if (model->B3SOIFDntun < 0.0) + { fprintf(fplog, "Warning: Ntun = %g is negative.\n", + model->B3SOIFDntun); + printf("Warning: Ntun = %g is negative.\n", model->B3SOIFDntun); + } + + if (model->B3SOIFDndiode < 0.0) + { fprintf(fplog, "Warning: Ndiode = %g is negative.\n", + model->B3SOIFDndiode); + printf("Warning: Ndiode = %g is negative.\n", model->B3SOIFDndiode); + } + + if (model->B3SOIFDisbjt < 0.0) + { fprintf(fplog, "Warning: Isbjt = %g is negative.\n", + model->B3SOIFDisbjt); + printf("Warning: Isbjt = %g is negative.\n", model->B3SOIFDisbjt); + } + + if (model->B3SOIFDisdif < 0.0) + { fprintf(fplog, "Warning: Isdif = %g is negative.\n", + model->B3SOIFDisdif); + printf("Warning: Isdif = %g is negative.\n", model->B3SOIFDisdif); + } + + if (model->B3SOIFDisrec < 0.0) + { fprintf(fplog, "Warning: Isrec = %g is negative.\n", + model->B3SOIFDisrec); + printf("Warning: Isrec = %g is negative.\n", model->B3SOIFDisrec); + } + + if (model->B3SOIFDistun < 0.0) + { fprintf(fplog, "Warning: Istun = %g is negative.\n", + model->B3SOIFDistun); + printf("Warning: Istun = %g is negative.\n", model->B3SOIFDistun); + } + + if (model->B3SOIFDedl < 0.0) + { fprintf(fplog, "Warning: Edl = %g is negative.\n", + model->B3SOIFDedl); + printf("Warning: Edl = %g is negative.\n", model->B3SOIFDedl); + } + + if (model->B3SOIFDkbjt1 < 0.0) + { fprintf(fplog, "Warning: Kbjt1 = %g is negative.\n", + model->B3SOIFDkbjt1); + printf("Warning: kbjt1 = %g is negative.\n", model->B3SOIFDkbjt1); + } + + if (model->B3SOIFDtt < 0.0) + { fprintf(fplog, "Warning: Tt = %g is negative.\n", + model->B3SOIFDtt); + printf("Warning: Tt = %g is negative.\n", model->B3SOIFDtt); + } + + if (model->B3SOIFDcsdmin < 0.0) + { fprintf(fplog, "Warning: Csdmin = %g is negative.\n", + model->B3SOIFDcsdmin); + printf("Warning: Csdmin = %g is negative.\n", model->B3SOIFDcsdmin); + } + + if (model->B3SOIFDcsdesw < 0.0) + { fprintf(fplog, "Warning: Csdesw = %g is negative.\n", + model->B3SOIFDcsdesw); + printf("Warning: Csdesw = %g is negative.\n", model->B3SOIFDcsdesw); + } + + if ((model->B3SOIFDasd < 0.0) || (model->B3SOIFDmxc > 1.0)) + { fprintf(fplog, "Warning: Asd = %g should be within (0, 1).\n", + model->B3SOIFDasd); + printf("Warning: Asd = %g should be within (0, 1).\n", model->B3SOIFDasd); + } + + if (model->B3SOIFDrth0 < 0.0) + { fprintf(fplog, "Warning: Rth0 = %g is negative.\n", + model->B3SOIFDrth0); + printf("Warning: Rth0 = %g is negative.\n", model->B3SOIFDrth0); + } + + if (model->B3SOIFDcth0 < 0.0) + { fprintf(fplog, "Warning: Cth0 = %g is negative.\n", + model->B3SOIFDcth0); + printf("Warning: Cth0 = %g is negative.\n", model->B3SOIFDcth0); + } + + if (model->B3SOIFDrbody < 0.0) + { fprintf(fplog, "Warning: Rbody = %g is negative.\n", + model->B3SOIFDrbody); + printf("Warning: Rbody = %g is negative.\n", model->B3SOIFDrbody); + } + + if (model->B3SOIFDrbsh < 0.0) + { fprintf(fplog, "Warning: Rbsh = %g is negative.\n", + model->B3SOIFDrbsh); + printf("Warning: Rbsh = %g is negative.\n", model->B3SOIFDrbsh); + } + + if (model->B3SOIFDxj > model->B3SOIFDtsi) + { fprintf(fplog, "Warning: Xj = %g is thicker than Tsi = %g.\n", + model->B3SOIFDxj, model->B3SOIFDtsi); + printf("Warning: Xj = %g is thicker than Tsi = %g.\n", + model->B3SOIFDxj, model->B3SOIFDtsi); + } + + if (model->B3SOIFDcapMod < 2) + { fprintf(fplog, "Warning: capMod < 2 is not supported by BSIM3SOI.\n"); + printf("Warning: Warning: capMod < 2 is not supported by BSIM3SOI.\n"); + } + + if (model->B3SOIFDcii > 2.0) + { fprintf(fplog, "Warning: Cii = %g is larger than 2.0.\n", model->B3SOIFDcii); + printf("Warning: Cii = %g is larger than 2.0.\n", model->B3SOIFDcii); + } + + if (model->B3SOIFDdii > 1.5) + { fprintf(fplog, "Warning: Dii = %g is larger than 1.5.\n", model->B3SOIFDcii); + printf("Warning: Dii = %g is too larger than 1.5.\n", model->B3SOIFDcii); + } + + }/* loop for the parameter check for warning messages */ + fclose(fplog); + } + else + { fprintf(stderr, "Warning: Can't open log file. Parameter checking skipped.\n"); + } + + return(Fatal_Flag); +} + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdcvtest.c b/src/spicelib/devices/bsim3soi_fd/b3soifdcvtest.c new file mode 100644 index 000000000..a815ad015 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdcvtest.c @@ -0,0 +1,90 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soifdcvtest.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "b3soifddef.h" +#include "trandefs.h" +#include "const.h" +#include "devdefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIFDconvTest(inModel,ckt) +GENmodel *inModel; + CKTcircuit *ckt; +{ + B3SOIFDmodel *model = (B3SOIFDmodel*)inModel; + B3SOIFDinstance *here; +double delvbd, delvbs, delvds, delvgd, delvgs, vbd, vbs, vds; +double cbd, cbhat, cbs, cd, cdhat, tol, vgd, vgdo, vgs; + + /* loop through all the B3SOIFD device models */ + for (; model != NULL; model = model->B3SOIFDnextModel) + { /* loop through all the instances of the model */ + for (here = model->B3SOIFDinstances; here != NULL ; + here=here->B3SOIFDnextInstance) + { vbs = model->B3SOIFDtype + * (*(ckt->CKTrhsOld+here->B3SOIFDbNode) + - *(ckt->CKTrhsOld+here->B3SOIFDsNodePrime)); + vgs = model->B3SOIFDtype + * (*(ckt->CKTrhsOld+here->B3SOIFDgNode) + - *(ckt->CKTrhsOld+here->B3SOIFDsNodePrime)); + vds = model->B3SOIFDtype + * (*(ckt->CKTrhsOld+here->B3SOIFDdNodePrime) + - *(ckt->CKTrhsOld+here->B3SOIFDsNodePrime)); + vbd = vbs - vds; + vgd = vgs - vds; + vgdo = *(ckt->CKTstate0 + here->B3SOIFDvgs) + - *(ckt->CKTstate0 + here->B3SOIFDvds); + delvbs = vbs - *(ckt->CKTstate0 + here->B3SOIFDvbs); + delvbd = vbd - *(ckt->CKTstate0 + here->B3SOIFDvbd); + delvgs = vgs - *(ckt->CKTstate0 + here->B3SOIFDvgs); + delvds = vds - *(ckt->CKTstate0 + here->B3SOIFDvds); + delvgd = vgd-vgdo; + + cd = here->B3SOIFDcd; + if (here->B3SOIFDmode >= 0) + { cdhat = cd - here->B3SOIFDgjdb * delvbd + + here->B3SOIFDgmbs * delvbs + here->B3SOIFDgm * delvgs + + here->B3SOIFDgds * delvds; + } + else + { cdhat = cd - (here->B3SOIFDgjdb - here->B3SOIFDgmbs) * delvbd + - here->B3SOIFDgm * delvgd + here->B3SOIFDgds * delvds; + } + + /* + * check convergence + */ + if ((here->B3SOIFDoff == 0) || (!(ckt->CKTmode & MODEINITFIX))) + { tol = ckt->CKTreltol * MAX(fabs(cdhat), fabs(cd)) + + ckt->CKTabstol; + if (fabs(cdhat - cd) >= tol) + { ckt->CKTnoncon++; + return(OK); + } + cbs = here->B3SOIFDcjs; + cbd = here->B3SOIFDcjd; + cbhat = cbs + cbd + here->B3SOIFDgjdb * delvbd + + here->B3SOIFDgjsb * delvbs; + tol = ckt->CKTreltol * MAX(fabs(cbhat), fabs(cbs + cbd)) + + ckt->CKTabstol; + if (fabs(cbhat - (cbs + cbd)) > tol) + { ckt->CKTnoncon++; + return(OK); + } + } + } + } + return(OK); +} + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifddef.h b/src/spicelib/devices/bsim3soi_fd/b3soifddef.h new file mode 100644 index 000000000..465db27b7 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifddef.h @@ -0,0 +1,1990 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung +Modified by Pin Su, Wei Jin 99/9/27 +File: b3soifddef.h +**********/ + +#ifndef B3SOIFD +#define B3SOIFD + +#define SOICODE +/* #define BULKCODE */ + +#include "ifsim.h" +#include "gendefs.h" +#include "cktdefs.h" +#include "complex.h" +#include "noisedef.h" + +typedef struct sB3SOIFDinstance +{ + struct sB3SOIFDmodel *B3SOIFDmodPtr; + struct sB3SOIFDinstance *B3SOIFDnextInstance; + IFuid B3SOIFDname; + int B3SOIFDstates; /* index into state table for this device */ + int B3SOIPDowner; + int B3SOIFDdNode; + int B3SOIFDgNode; + int B3SOIFDsNode; + int B3SOIFDeNode; + int B3SOIFDbNode; + int B3SOIFDtempNode; + int B3SOIFDpNode; + int B3SOIFDdNodePrime; + int B3SOIFDsNodePrime; + + int B3SOIFDvbsNode; + /* for Debug */ + int B3SOIFDidsNode; + int B3SOIFDicNode; + int B3SOIFDibsNode; + int B3SOIFDibdNode; + int B3SOIFDiiiNode; + int B3SOIFDigidlNode; + int B3SOIFDitunNode; + int B3SOIFDibpNode; + int B3SOIFDabeffNode; + int B3SOIFDvbs0effNode; + int B3SOIFDvbseffNode; + int B3SOIFDxcNode; + int B3SOIFDcbbNode; + int B3SOIFDcbdNode; + int B3SOIFDcbeNode; + int B3SOIFDcbgNode; + int B3SOIFDqbNode; + int B3SOIFDqbfNode; + int B3SOIFDqjsNode; + int B3SOIFDqjdNode; + +/* clean up last */ + int B3SOIFDgmNode; + int B3SOIFDgmbsNode; + int B3SOIFDgdsNode; + int B3SOIFDgmeNode; + int B3SOIFDqgNode; + int B3SOIFDqdNode; + int B3SOIFDqeNode; + int B3SOIFDiterations; + int B3SOIFDvbs0teffNode; + int B3SOIFDvthNode; + int B3SOIFDvgsteffNode; + int B3SOIFDxcsatNode; + int B3SOIFDqaccNode; + int B3SOIFDqsub0Node; + int B3SOIFDqsubs1Node; + int B3SOIFDqsubs2Node; + int B3SOIFDvcscvNode; + int B3SOIFDvdscvNode; + int B3SOIFDdum1Node; + int B3SOIFDdum2Node; + int B3SOIFDdum3Node; + int B3SOIFDdum4Node; + int B3SOIFDdum5Node; +/* end clean up last */ + + double B3SOIFDphi; + double B3SOIFDvtm; + double B3SOIFDni; + double B3SOIFDueff; + double B3SOIFDthetavth; + double B3SOIFDvon; + double B3SOIFDvbsdio; + double B3SOIFDvdsat; + double B3SOIFDcgdo; + double B3SOIFDcgso; + double B3SOIFDcgeo; + + double B3SOIFDids; + double B3SOIFDic; + double B3SOIFDibs; + double B3SOIFDibd; + double B3SOIFDiii; + double B3SOIFDigidl; + double B3SOIFDitun; + double B3SOIFDibp; + double B3SOIFDabeff; + double B3SOIFDvbs0eff; + double B3SOIFDvbseff; + double B3SOIFDxc; + double B3SOIFDcbg; + double B3SOIFDcbb; + double B3SOIFDcbd; + double B3SOIFDqb; + double B3SOIFDqbf; + double B3SOIFDqjs; + double B3SOIFDqjd; + double B3SOIFDminIsub; + int B3SOIFDfloat; + +/* clean up last */ + double B3SOIFDdum1; + double B3SOIFDdum2; + double B3SOIFDdum3; + double B3SOIFDdum4; + double B3SOIFDdum5; +/* end clean up last */ + + double B3SOIFDl; + double B3SOIFDw; + double B3SOIFDdrainArea; + double B3SOIFDsourceArea; + double B3SOIFDdrainSquares; + double B3SOIFDsourceSquares; + double B3SOIFDdrainPerimeter; + double B3SOIFDsourcePerimeter; + double B3SOIFDsourceConductance; + double B3SOIFDdrainConductance; + + double B3SOIFDicVBS; + double B3SOIFDicVDS; + double B3SOIFDicVGS; + double B3SOIFDicVES; + double B3SOIFDicVPS; + int B3SOIFDbjtoff; + int B3SOIFDbodyMod; + int B3SOIFDdebugMod; + double B3SOIFDrth0; + double B3SOIFDcth0; + double B3SOIFDbodySquares; + double B3SOIFDrbodyext; + + double B3SOIFDcsbox; + double B3SOIFDcdbox; + double B3SOIFDcsmin; + double B3SOIFDcdmin; + double B3SOIFDst4; + double B3SOIFDdt4; + + int B3SOIFDoff; + int B3SOIFDmode; + + /* OP point */ + double B3SOIFDqinv; + double B3SOIFDcd; + double B3SOIFDcjs; + double B3SOIFDcjd; + double B3SOIFDcbody; + double B3SOIFDcbodcon; + double B3SOIFDcth; + double B3SOIFDcsubstrate; + + double B3SOIFDgm; + double B3SOIFDgme; + double B3SOIFDcb; + double B3SOIFDcdrain; + double B3SOIFDgds; + double B3SOIFDgmbs; + double B3SOIFDgmT; + + double B3SOIFDgbbs; + double B3SOIFDgbgs; + double B3SOIFDgbds; + double B3SOIFDgbes; + double B3SOIFDgbps; + double B3SOIFDgbT; + + double B3SOIFDgjsd; + double B3SOIFDgjsb; + double B3SOIFDgjsg; + double B3SOIFDgjsT; + + double B3SOIFDgjdb; + double B3SOIFDgjdd; + double B3SOIFDgjdg; + double B3SOIFDgjde; + double B3SOIFDgjdT; + + double B3SOIFDgbpbs; + double B3SOIFDgbpgs; + double B3SOIFDgbpds; + double B3SOIFDgbpes; + double B3SOIFDgbpps; + double B3SOIFDgbpT; + + double B3SOIFDgtempb; + double B3SOIFDgtempg; + double B3SOIFDgtempd; + double B3SOIFDgtempe; + double B3SOIFDgtempT; + + double B3SOIFDcggb; + double B3SOIFDcgdb; + double B3SOIFDcgsb; + double B3SOIFDcgeb; + double B3SOIFDcgT; + + double B3SOIFDcbgb; + double B3SOIFDcbdb; + double B3SOIFDcbs; /* XXX PN */ + double B3SOIFDcbsb; + double B3SOIFDcbeb; + double B3SOIFDcbT; + + double B3SOIFDcdgb; + double B3SOIFDcddb; + double B3SOIFDcdsb; + double B3SOIFDcdeb; + double B3SOIFDcdT; + + double B3SOIFDcegb; + double B3SOIFDcedb; + double B3SOIFDcesb; + double B3SOIFDceeb; + double B3SOIFDceT; + + double B3SOIFDqse; + double B3SOIFDgcse; + double B3SOIFDqde; + double B3SOIFDgcde; + + struct b3soifdSizeDependParam *pParam; + + unsigned B3SOIFDlGiven :1; + unsigned B3SOIFDwGiven :1; + unsigned B3SOIFDdrainAreaGiven :1; + unsigned B3SOIFDsourceAreaGiven :1; + unsigned B3SOIFDdrainSquaresGiven :1; + unsigned B3SOIFDsourceSquaresGiven :1; + unsigned B3SOIFDdrainPerimeterGiven :1; + unsigned B3SOIFDsourcePerimeterGiven :1; + unsigned B3SOIFDdNodePrimeSet :1; + unsigned B3SOIFDsNodePrimeSet :1; + unsigned B3SOIFDicVBSGiven :1; + unsigned B3SOIFDicVDSGiven :1; + unsigned B3SOIFDicVGSGiven :1; + unsigned B3SOIFDicVESGiven :1; + unsigned B3SOIFDicVPSGiven :1; + unsigned B3SOIFDbjtoffGiven :1; + unsigned B3SOIFDdebugModGiven :1; + unsigned B3SOIFDrth0Given :1; + unsigned B3SOIFDcth0Given :1; + unsigned B3SOIFDbodySquaresGiven :1; + unsigned B3SOIFDoffGiven :1; + + double *B3SOIFDEePtr; + double *B3SOIFDEbPtr; + double *B3SOIFDBePtr; + double *B3SOIFDEgPtr; + double *B3SOIFDEdpPtr; + double *B3SOIFDEspPtr; + double *B3SOIFDTemptempPtr; + double *B3SOIFDTempdpPtr; + double *B3SOIFDTempspPtr; + double *B3SOIFDTempgPtr; + double *B3SOIFDTempbPtr; + double *B3SOIFDTempePtr; + double *B3SOIFDGtempPtr; + double *B3SOIFDDPtempPtr; + double *B3SOIFDSPtempPtr; + double *B3SOIFDEtempPtr; + double *B3SOIFDBtempPtr; + double *B3SOIFDPtempPtr; + double *B3SOIFDBpPtr; + double *B3SOIFDPbPtr; + double *B3SOIFDPpPtr; + double *B3SOIFDPgPtr; + double *B3SOIFDPdpPtr; + double *B3SOIFDPspPtr; + double *B3SOIFDPePtr; + double *B3SOIFDDPePtr; + double *B3SOIFDSPePtr; + double *B3SOIFDGePtr; + double *B3SOIFDDdPtr; + double *B3SOIFDGgPtr; + double *B3SOIFDSsPtr; + double *B3SOIFDBbPtr; + double *B3SOIFDDPdpPtr; + double *B3SOIFDSPspPtr; + double *B3SOIFDDdpPtr; + double *B3SOIFDGbPtr; + double *B3SOIFDGdpPtr; + double *B3SOIFDGspPtr; + double *B3SOIFDSspPtr; + double *B3SOIFDBdpPtr; + double *B3SOIFDBspPtr; + double *B3SOIFDDPspPtr; + double *B3SOIFDDPdPtr; + double *B3SOIFDBgPtr; + double *B3SOIFDDPgPtr; + double *B3SOIFDSPgPtr; + double *B3SOIFDSPsPtr; + double *B3SOIFDDPbPtr; + double *B3SOIFDSPbPtr; + double *B3SOIFDSPdpPtr; + + double *B3SOIFDVbsPtr; + /* Debug */ + double *B3SOIFDIdsPtr; + double *B3SOIFDIcPtr; + double *B3SOIFDIbsPtr; + double *B3SOIFDIbdPtr; + double *B3SOIFDIiiPtr; + double *B3SOIFDIgidlPtr; + double *B3SOIFDItunPtr; + double *B3SOIFDIbpPtr; + double *B3SOIFDAbeffPtr; + double *B3SOIFDVbs0effPtr; + double *B3SOIFDVbseffPtr; + double *B3SOIFDXcPtr; + double *B3SOIFDCbbPtr; + double *B3SOIFDCbdPtr; + double *B3SOIFDCbgPtr; + double *B3SOIFDqbPtr; + double *B3SOIFDQbfPtr; + double *B3SOIFDQjsPtr; + double *B3SOIFDQjdPtr; + + /* clean up last */ + double *B3SOIFDGmPtr; + double *B3SOIFDGmbsPtr; + double *B3SOIFDGdsPtr; + double *B3SOIFDGmePtr; + double *B3SOIFDVbs0teffPtr; + double *B3SOIFDVthPtr; + double *B3SOIFDVgsteffPtr; + double *B3SOIFDXcsatPtr; + double *B3SOIFDQaccPtr; + double *B3SOIFDQsub0Ptr; + double *B3SOIFDQsubs1Ptr; + double *B3SOIFDQsubs2Ptr; + double *B3SOIFDVdscvPtr; + double *B3SOIFDVcscvPtr; + double *B3SOIFDCbePtr; + double *B3SOIFDqgPtr; + double *B3SOIFDqdPtr; + double *B3SOIFDqePtr; + double *B3SOIFDDum1Ptr; + double *B3SOIFDDum2Ptr; + double *B3SOIFDDum3Ptr; + double *B3SOIFDDum4Ptr; + double *B3SOIFDDum5Ptr; + /* End clean up last */ + +#define B3SOIFDvbd B3SOIFDstates+ 0 +#define B3SOIFDvbs B3SOIFDstates+ 1 +#define B3SOIFDvgs B3SOIFDstates+ 2 +#define B3SOIFDvds B3SOIFDstates+ 3 +#define B3SOIFDves B3SOIFDstates+ 4 +#define B3SOIFDvps B3SOIFDstates+ 5 + +#define B3SOIFDvg B3SOIFDstates+ 6 +#define B3SOIFDvd B3SOIFDstates+ 7 +#define B3SOIFDvs B3SOIFDstates+ 8 +#define B3SOIFDvp B3SOIFDstates+ 9 +#define B3SOIFDve B3SOIFDstates+ 10 +#define B3SOIFDdeltemp B3SOIFDstates+ 11 + +#define B3SOIFDqb B3SOIFDstates+ 12 +#define B3SOIFDcqb B3SOIFDstates+ 13 +#define B3SOIFDqg B3SOIFDstates+ 14 +#define B3SOIFDcqg B3SOIFDstates+ 15 +#define B3SOIFDqd B3SOIFDstates+ 16 +#define B3SOIFDcqd B3SOIFDstates+ 17 +#define B3SOIFDqe B3SOIFDstates+ 18 +#define B3SOIFDcqe B3SOIFDstates+ 19 + +#define B3SOIFDqbs B3SOIFDstates+ 20 +#define B3SOIFDqbd B3SOIFDstates+ 21 +#define B3SOIFDqbe B3SOIFDstates+ 22 + +#define B3SOIFDqth B3SOIFDstates+ 23 +#define B3SOIFDcqth B3SOIFDstates+ 24 + +#define B3SOIFDnumStates 25 + + +/* indices to the array of B3SOIFD NOISE SOURCES */ + +#define B3SOIFDRDNOIZ 0 +#define B3SOIFDRSNOIZ 1 +#define B3SOIFDIDNOIZ 2 +#define B3SOIFDFLNOIZ 3 +#define B3SOIFDFBNOIZ 4 +#define B3SOIFDTOTNOIZ 5 + +#define B3SOIFDNSRCS 6 /* the number of MOSFET(3) noise sources */ + +#ifndef NONOISE + double B3SOIFDnVar[NSTATVARS][B3SOIFDNSRCS]; +#else /* NONOISE */ + double **B3SOIFDnVar; +#endif /* NONOISE */ + +} B3SOIFDinstance ; + +struct b3soifdSizeDependParam +{ + double Width; + double Length; + double Rth0; + double Cth0; + + double B3SOIFDcdsc; + double B3SOIFDcdscb; + double B3SOIFDcdscd; + double B3SOIFDcit; + double B3SOIFDnfactor; + double B3SOIFDvsat; + double B3SOIFDat; + double B3SOIFDa0; + double B3SOIFDags; + double B3SOIFDa1; + double B3SOIFDa2; + double B3SOIFDketa; + double B3SOIFDnpeak; + double B3SOIFDnsub; + double B3SOIFDngate; + double B3SOIFDgamma1; + double B3SOIFDgamma2; + double B3SOIFDvbx; + double B3SOIFDvbi; + double B3SOIFDvbm; + double B3SOIFDvbsc; + double B3SOIFDxt; + double B3SOIFDphi; + double B3SOIFDlitl; + double B3SOIFDk1; + double B3SOIFDkt1; + double B3SOIFDkt1l; + double B3SOIFDkt2; + double B3SOIFDk2; + double B3SOIFDk3; + double B3SOIFDk3b; + double B3SOIFDw0; + double B3SOIFDnlx; + double B3SOIFDdvt0; + double B3SOIFDdvt1; + double B3SOIFDdvt2; + double B3SOIFDdvt0w; + double B3SOIFDdvt1w; + double B3SOIFDdvt2w; + double B3SOIFDdrout; + double B3SOIFDdsub; + double B3SOIFDvth0; + double B3SOIFDua; + double B3SOIFDua1; + double B3SOIFDub; + double B3SOIFDub1; + double B3SOIFDuc; + double B3SOIFDuc1; + double B3SOIFDu0; + double B3SOIFDute; + double B3SOIFDvoff; + double B3SOIFDvfb; + double B3SOIFDuatemp; + double B3SOIFDubtemp; + double B3SOIFDuctemp; + double B3SOIFDrbody; + double B3SOIFDrth; + double B3SOIFDcth; + double B3SOIFDrds0denom; + double B3SOIFDvfbb; + double B3SOIFDjbjt; + double B3SOIFDjdif; + double B3SOIFDjrec; + double B3SOIFDjtun; + double B3SOIFDcsesw; + double B3SOIFDcdesw; + + /* Added */ + double B3SOIFDsdt1; + double B3SOIFDst2; + double B3SOIFDst3; + double B3SOIFDdt2; + double B3SOIFDdt3; + /* Added */ + + double B3SOIFDdelta; + double B3SOIFDrdsw; + double B3SOIFDrds0; + double B3SOIFDprwg; + double B3SOIFDprwb; + double B3SOIFDprt; + double B3SOIFDeta0; + double B3SOIFDetab; + double B3SOIFDpclm; + double B3SOIFDpdibl1; + double B3SOIFDpdibl2; + double B3SOIFDpdiblb; + double B3SOIFDpvag; + double B3SOIFDwr; + double B3SOIFDdwg; + double B3SOIFDdwb; + double B3SOIFDb0; + double B3SOIFDb1; + double B3SOIFDalpha0; + double B3SOIFDalpha1; + double B3SOIFDbeta0; + + + /* CV model */ + double B3SOIFDcgsl; + double B3SOIFDcgdl; + double B3SOIFDckappa; + double B3SOIFDcf; + double B3SOIFDclc; + double B3SOIFDcle; + +/* Added for binning - START0 */ + double B3SOIFDvbsa; + double B3SOIFDdelp; + double B3SOIFDkb1; + double B3SOIFDkb3; + double B3SOIFDdvbd0; + double B3SOIFDdvbd1; + double B3SOIFDabp; + double B3SOIFDmxc; + double B3SOIFDadice0; + double B3SOIFDaii; + double B3SOIFDbii; + double B3SOIFDcii; + double B3SOIFDdii; + double B3SOIFDagidl; + double B3SOIFDbgidl; + double B3SOIFDngidl; + double B3SOIFDntun; + double B3SOIFDndiode; + double B3SOIFDisbjt; + double B3SOIFDisdif; + double B3SOIFDisrec; + double B3SOIFDistun; + double B3SOIFDedl; + double B3SOIFDkbjt1; + double B3SOIFDvsdfb; + double B3SOIFDvsdth; +/* Added for binning - END0 */ + +/* Pre-calculated constants */ + + double B3SOIFDdw; + double B3SOIFDdl; + double B3SOIFDleff; + double B3SOIFDweff; + + double B3SOIFDdwc; + double B3SOIFDdlc; + double B3SOIFDleffCV; + double B3SOIFDweffCV; + double B3SOIFDabulkCVfactor; + double B3SOIFDcgso; + double B3SOIFDcgdo; + double B3SOIFDcgeo; + + double B3SOIFDu0temp; + double B3SOIFDvsattemp; + double B3SOIFDsqrtPhi; + double B3SOIFDphis3; + double B3SOIFDXdep0; + double B3SOIFDsqrtXdep0; + double B3SOIFDtheta0vb0; + double B3SOIFDthetaRout; + + double B3SOIFDcof1; + double B3SOIFDcof2; + double B3SOIFDcof3; + double B3SOIFDcof4; + double B3SOIFDcdep0; + struct b3soifdSizeDependParam *pNext; +}; + + +typedef struct sB3SOIFDmodel +{ + int B3SOIFDmodType; + struct sB3SOIFDmodel *B3SOIFDnextModel; + B3SOIFDinstance *B3SOIFDinstances; + IFuid B3SOIFDmodName; + int B3SOIFDtype; + + int B3SOIFDmobMod; + int B3SOIFDcapMod; + int B3SOIFDnoiMod; + int B3SOIFDshMod; + int B3SOIFDbinUnit; + int B3SOIFDparamChk; + double B3SOIFDversion; + double B3SOIFDtox; + double B3SOIFDcdsc; + double B3SOIFDcdscb; + double B3SOIFDcdscd; + double B3SOIFDcit; + double B3SOIFDnfactor; + double B3SOIFDvsat; + double B3SOIFDat; + double B3SOIFDa0; + double B3SOIFDags; + double B3SOIFDa1; + double B3SOIFDa2; + double B3SOIFDketa; + double B3SOIFDnsub; + double B3SOIFDnpeak; + double B3SOIFDngate; + double B3SOIFDgamma1; + double B3SOIFDgamma2; + double B3SOIFDvbx; + double B3SOIFDvbm; + double B3SOIFDxt; + double B3SOIFDk1; + double B3SOIFDkt1; + double B3SOIFDkt1l; + double B3SOIFDkt2; + double B3SOIFDk2; + double B3SOIFDk3; + double B3SOIFDk3b; + double B3SOIFDw0; + double B3SOIFDnlx; + double B3SOIFDdvt0; + double B3SOIFDdvt1; + double B3SOIFDdvt2; + double B3SOIFDdvt0w; + double B3SOIFDdvt1w; + double B3SOIFDdvt2w; + double B3SOIFDdrout; + double B3SOIFDdsub; + double B3SOIFDvth0; + double B3SOIFDua; + double B3SOIFDua1; + double B3SOIFDub; + double B3SOIFDub1; + double B3SOIFDuc; + double B3SOIFDuc1; + double B3SOIFDu0; + double B3SOIFDute; + double B3SOIFDvoff; + double B3SOIFDdelta; + double B3SOIFDrdsw; + double B3SOIFDprwg; + double B3SOIFDprwb; + double B3SOIFDprt; + double B3SOIFDeta0; + double B3SOIFDetab; + double B3SOIFDpclm; + double B3SOIFDpdibl1; + double B3SOIFDpdibl2; + double B3SOIFDpdiblb; + double B3SOIFDpvag; + double B3SOIFDwr; + double B3SOIFDdwg; + double B3SOIFDdwb; + double B3SOIFDb0; + double B3SOIFDb1; + double B3SOIFDalpha0; + double B3SOIFDalpha1; + double B3SOIFDbeta0; + double B3SOIFDtbox; + double B3SOIFDtsi; + double B3SOIFDxj; + double B3SOIFDkb1; + double B3SOIFDkb3; + double B3SOIFDdvbd0; + double B3SOIFDdvbd1; + double B3SOIFDvbsa; + double B3SOIFDdelp; + double B3SOIFDrbody; + double B3SOIFDrbsh; + double B3SOIFDadice0; + double B3SOIFDabp; + double B3SOIFDmxc; + double B3SOIFDrth0; + double B3SOIFDcth0; + double B3SOIFDaii; + double B3SOIFDbii; + double B3SOIFDcii; + double B3SOIFDdii; + double B3SOIFDngidl; + double B3SOIFDagidl; + double B3SOIFDbgidl; + double B3SOIFDndiode; + double B3SOIFDntun; + double B3SOIFDisbjt; + double B3SOIFDisdif; + double B3SOIFDisrec; + double B3SOIFDistun; + double B3SOIFDxbjt; + double B3SOIFDxdif; + double B3SOIFDxrec; + double B3SOIFDxtun; + double B3SOIFDedl; + double B3SOIFDkbjt1; + double B3SOIFDtt; + double B3SOIFDvsdfb; + double B3SOIFDvsdth; + double B3SOIFDcsdmin; + double B3SOIFDasd; + + /* CV model */ + double B3SOIFDcgsl; + double B3SOIFDcgdl; + double B3SOIFDckappa; + double B3SOIFDcf; + double B3SOIFDclc; + double B3SOIFDcle; + double B3SOIFDdwc; + double B3SOIFDdlc; + + double B3SOIFDtnom; + double B3SOIFDcgso; + double B3SOIFDcgdo; + double B3SOIFDcgeo; + double B3SOIFDxpart; + double B3SOIFDcFringOut; + double B3SOIFDcFringMax; + + double B3SOIFDsheetResistance; + double B3SOIFDbodyJctGateSideGradingCoeff; + double B3SOIFDGatesidewallJctPotential; + double B3SOIFDunitLengthGateSidewallJctCap; + double B3SOIFDcsdesw; + + double B3SOIFDLint; + double B3SOIFDLl; + double B3SOIFDLln; + double B3SOIFDLw; + double B3SOIFDLwn; + double B3SOIFDLwl; + double B3SOIFDLmin; + double B3SOIFDLmax; + + double B3SOIFDWint; + double B3SOIFDWl; + double B3SOIFDWln; + double B3SOIFDWw; + double B3SOIFDWwn; + double B3SOIFDWwl; + double B3SOIFDWmin; + double B3SOIFDWmax; + +/* Added for binning - START1 */ + /* Length Dependence */ + double B3SOIFDlnpeak; + double B3SOIFDlnsub; + double B3SOIFDlngate; + double B3SOIFDlvth0; + double B3SOIFDlk1; + double B3SOIFDlk2; + double B3SOIFDlk3; + double B3SOIFDlk3b; + double B3SOIFDlvbsa; + double B3SOIFDldelp; + double B3SOIFDlkb1; + double B3SOIFDlkb3; + double B3SOIFDldvbd0; + double B3SOIFDldvbd1; + double B3SOIFDlw0; + double B3SOIFDlnlx; + double B3SOIFDldvt0; + double B3SOIFDldvt1; + double B3SOIFDldvt2; + double B3SOIFDldvt0w; + double B3SOIFDldvt1w; + double B3SOIFDldvt2w; + double B3SOIFDlu0; + double B3SOIFDlua; + double B3SOIFDlub; + double B3SOIFDluc; + double B3SOIFDlvsat; + double B3SOIFDla0; + double B3SOIFDlags; + double B3SOIFDlb0; + double B3SOIFDlb1; + double B3SOIFDlketa; + double B3SOIFDlabp; + double B3SOIFDlmxc; + double B3SOIFDladice0; + double B3SOIFDla1; + double B3SOIFDla2; + double B3SOIFDlrdsw; + double B3SOIFDlprwb; + double B3SOIFDlprwg; + double B3SOIFDlwr; + double B3SOIFDlnfactor; + double B3SOIFDldwg; + double B3SOIFDldwb; + double B3SOIFDlvoff; + double B3SOIFDleta0; + double B3SOIFDletab; + double B3SOIFDldsub; + double B3SOIFDlcit; + double B3SOIFDlcdsc; + double B3SOIFDlcdscb; + double B3SOIFDlcdscd; + double B3SOIFDlpclm; + double B3SOIFDlpdibl1; + double B3SOIFDlpdibl2; + double B3SOIFDlpdiblb; + double B3SOIFDldrout; + double B3SOIFDlpvag; + double B3SOIFDldelta; + double B3SOIFDlaii; + double B3SOIFDlbii; + double B3SOIFDlcii; + double B3SOIFDldii; + double B3SOIFDlalpha0; + double B3SOIFDlalpha1; + double B3SOIFDlbeta0; + double B3SOIFDlagidl; + double B3SOIFDlbgidl; + double B3SOIFDlngidl; + double B3SOIFDlntun; + double B3SOIFDlndiode; + double B3SOIFDlisbjt; + double B3SOIFDlisdif; + double B3SOIFDlisrec; + double B3SOIFDlistun; + double B3SOIFDledl; + double B3SOIFDlkbjt1; + /* CV model */ + double B3SOIFDlvsdfb; + double B3SOIFDlvsdth; + + /* Width Dependence */ + double B3SOIFDwnpeak; + double B3SOIFDwnsub; + double B3SOIFDwngate; + double B3SOIFDwvth0; + double B3SOIFDwk1; + double B3SOIFDwk2; + double B3SOIFDwk3; + double B3SOIFDwk3b; + double B3SOIFDwvbsa; + double B3SOIFDwdelp; + double B3SOIFDwkb1; + double B3SOIFDwkb3; + double B3SOIFDwdvbd0; + double B3SOIFDwdvbd1; + double B3SOIFDww0; + double B3SOIFDwnlx; + double B3SOIFDwdvt0; + double B3SOIFDwdvt1; + double B3SOIFDwdvt2; + double B3SOIFDwdvt0w; + double B3SOIFDwdvt1w; + double B3SOIFDwdvt2w; + double B3SOIFDwu0; + double B3SOIFDwua; + double B3SOIFDwub; + double B3SOIFDwuc; + double B3SOIFDwvsat; + double B3SOIFDwa0; + double B3SOIFDwags; + double B3SOIFDwb0; + double B3SOIFDwb1; + double B3SOIFDwketa; + double B3SOIFDwabp; + double B3SOIFDwmxc; + double B3SOIFDwadice0; + double B3SOIFDwa1; + double B3SOIFDwa2; + double B3SOIFDwrdsw; + double B3SOIFDwprwb; + double B3SOIFDwprwg; + double B3SOIFDwwr; + double B3SOIFDwnfactor; + double B3SOIFDwdwg; + double B3SOIFDwdwb; + double B3SOIFDwvoff; + double B3SOIFDweta0; + double B3SOIFDwetab; + double B3SOIFDwdsub; + double B3SOIFDwcit; + double B3SOIFDwcdsc; + double B3SOIFDwcdscb; + double B3SOIFDwcdscd; + double B3SOIFDwpclm; + double B3SOIFDwpdibl1; + double B3SOIFDwpdibl2; + double B3SOIFDwpdiblb; + double B3SOIFDwdrout; + double B3SOIFDwpvag; + double B3SOIFDwdelta; + double B3SOIFDwaii; + double B3SOIFDwbii; + double B3SOIFDwcii; + double B3SOIFDwdii; + double B3SOIFDwalpha0; + double B3SOIFDwalpha1; + double B3SOIFDwbeta0; + double B3SOIFDwagidl; + double B3SOIFDwbgidl; + double B3SOIFDwngidl; + double B3SOIFDwntun; + double B3SOIFDwndiode; + double B3SOIFDwisbjt; + double B3SOIFDwisdif; + double B3SOIFDwisrec; + double B3SOIFDwistun; + double B3SOIFDwedl; + double B3SOIFDwkbjt1; + /* CV model */ + double B3SOIFDwvsdfb; + double B3SOIFDwvsdth; + + /* Cross-term Dependence */ + double B3SOIFDpnpeak; + double B3SOIFDpnsub; + double B3SOIFDpngate; + double B3SOIFDpvth0; + double B3SOIFDpk1; + double B3SOIFDpk2; + double B3SOIFDpk3; + double B3SOIFDpk3b; + double B3SOIFDpvbsa; + double B3SOIFDpdelp; + double B3SOIFDpkb1; + double B3SOIFDpkb3; + double B3SOIFDpdvbd0; + double B3SOIFDpdvbd1; + double B3SOIFDpw0; + double B3SOIFDpnlx; + double B3SOIFDpdvt0; + double B3SOIFDpdvt1; + double B3SOIFDpdvt2; + double B3SOIFDpdvt0w; + double B3SOIFDpdvt1w; + double B3SOIFDpdvt2w; + double B3SOIFDpu0; + double B3SOIFDpua; + double B3SOIFDpub; + double B3SOIFDpuc; + double B3SOIFDpvsat; + double B3SOIFDpa0; + double B3SOIFDpags; + double B3SOIFDpb0; + double B3SOIFDpb1; + double B3SOIFDpketa; + double B3SOIFDpabp; + double B3SOIFDpmxc; + double B3SOIFDpadice0; + double B3SOIFDpa1; + double B3SOIFDpa2; + double B3SOIFDprdsw; + double B3SOIFDpprwb; + double B3SOIFDpprwg; + double B3SOIFDpwr; + double B3SOIFDpnfactor; + double B3SOIFDpdwg; + double B3SOIFDpdwb; + double B3SOIFDpvoff; + double B3SOIFDpeta0; + double B3SOIFDpetab; + double B3SOIFDpdsub; + double B3SOIFDpcit; + double B3SOIFDpcdsc; + double B3SOIFDpcdscb; + double B3SOIFDpcdscd; + double B3SOIFDppclm; + double B3SOIFDppdibl1; + double B3SOIFDppdibl2; + double B3SOIFDppdiblb; + double B3SOIFDpdrout; + double B3SOIFDppvag; + double B3SOIFDpdelta; + double B3SOIFDpaii; + double B3SOIFDpbii; + double B3SOIFDpcii; + double B3SOIFDpdii; + double B3SOIFDpalpha0; + double B3SOIFDpalpha1; + double B3SOIFDpbeta0; + double B3SOIFDpagidl; + double B3SOIFDpbgidl; + double B3SOIFDpngidl; + double B3SOIFDpntun; + double B3SOIFDpndiode; + double B3SOIFDpisbjt; + double B3SOIFDpisdif; + double B3SOIFDpisrec; + double B3SOIFDpistun; + double B3SOIFDpedl; + double B3SOIFDpkbjt1; + /* CV model */ + double B3SOIFDpvsdfb; + double B3SOIFDpvsdth; +/* Added for binning - END1 */ + +/* Pre-calculated constants */ + double B3SOIFDcbox; + double B3SOIFDcsi; + double B3SOIFDcsieff; + double B3SOIFDcoxt; + double B3SOIFDcboxt; + double B3SOIFDcsit; + double B3SOIFDnfb; + double B3SOIFDadice; + double B3SOIFDqsi; + double B3SOIFDqsieff; + double B3SOIFDeg0; + + /* MCJ: move to size-dependent param. */ + double B3SOIFDvtm; + double B3SOIFDcox; + double B3SOIFDcof1; + double B3SOIFDcof2; + double B3SOIFDcof3; + double B3SOIFDcof4; + double B3SOIFDvcrit; + double B3SOIFDfactor1; + + double B3SOIFDoxideTrapDensityA; + double B3SOIFDoxideTrapDensityB; + double B3SOIFDoxideTrapDensityC; + double B3SOIFDem; + double B3SOIFDef; + double B3SOIFDaf; + double B3SOIFDkf; + double B3SOIFDnoif; + + struct b3soifdSizeDependParam *pSizeDependParamKnot; + + /* Flags */ + + unsigned B3SOIFDtboxGiven:1; + unsigned B3SOIFDtsiGiven :1; + unsigned B3SOIFDxjGiven :1; + unsigned B3SOIFDkb1Given :1; + unsigned B3SOIFDkb3Given :1; + unsigned B3SOIFDdvbd0Given :1; + unsigned B3SOIFDdvbd1Given :1; + unsigned B3SOIFDvbsaGiven :1; + unsigned B3SOIFDdelpGiven :1; + unsigned B3SOIFDrbodyGiven :1; + unsigned B3SOIFDrbshGiven :1; + unsigned B3SOIFDadice0Given :1; + unsigned B3SOIFDabpGiven :1; + unsigned B3SOIFDmxcGiven :1; + unsigned B3SOIFDrth0Given :1; + unsigned B3SOIFDcth0Given :1; + unsigned B3SOIFDaiiGiven :1; + unsigned B3SOIFDbiiGiven :1; + unsigned B3SOIFDciiGiven :1; + unsigned B3SOIFDdiiGiven :1; + unsigned B3SOIFDngidlGiven :1; + unsigned B3SOIFDagidlGiven :1; + unsigned B3SOIFDbgidlGiven :1; + unsigned B3SOIFDndiodeGiven :1; + unsigned B3SOIFDntunGiven :1; + unsigned B3SOIFDisbjtGiven :1; + unsigned B3SOIFDisdifGiven :1; + unsigned B3SOIFDisrecGiven :1; + unsigned B3SOIFDistunGiven :1; + unsigned B3SOIFDxbjtGiven :1; + unsigned B3SOIFDxdifGiven :1; + unsigned B3SOIFDxrecGiven :1; + unsigned B3SOIFDxtunGiven :1; + unsigned B3SOIFDedlGiven :1; + unsigned B3SOIFDkbjt1Given :1; + unsigned B3SOIFDttGiven :1; + unsigned B3SOIFDvsdfbGiven :1; + unsigned B3SOIFDvsdthGiven :1; + unsigned B3SOIFDasdGiven :1; + unsigned B3SOIFDcsdminGiven :1; + + unsigned B3SOIFDmobModGiven :1; + unsigned B3SOIFDbinUnitGiven :1; + unsigned B3SOIFDcapModGiven :1; + unsigned B3SOIFDparamChkGiven :1; + unsigned B3SOIFDnoiModGiven :1; + unsigned B3SOIFDshModGiven :1; + unsigned B3SOIFDtypeGiven :1; + unsigned B3SOIFDtoxGiven :1; + unsigned B3SOIFDversionGiven :1; + + unsigned B3SOIFDcdscGiven :1; + unsigned B3SOIFDcdscbGiven :1; + unsigned B3SOIFDcdscdGiven :1; + unsigned B3SOIFDcitGiven :1; + unsigned B3SOIFDnfactorGiven :1; + unsigned B3SOIFDvsatGiven :1; + unsigned B3SOIFDatGiven :1; + unsigned B3SOIFDa0Given :1; + unsigned B3SOIFDagsGiven :1; + unsigned B3SOIFDa1Given :1; + unsigned B3SOIFDa2Given :1; + unsigned B3SOIFDketaGiven :1; + unsigned B3SOIFDnsubGiven :1; + unsigned B3SOIFDnpeakGiven :1; + unsigned B3SOIFDngateGiven :1; + unsigned B3SOIFDgamma1Given :1; + unsigned B3SOIFDgamma2Given :1; + unsigned B3SOIFDvbxGiven :1; + unsigned B3SOIFDvbmGiven :1; + unsigned B3SOIFDxtGiven :1; + unsigned B3SOIFDk1Given :1; + unsigned B3SOIFDkt1Given :1; + unsigned B3SOIFDkt1lGiven :1; + unsigned B3SOIFDkt2Given :1; + unsigned B3SOIFDk2Given :1; + unsigned B3SOIFDk3Given :1; + unsigned B3SOIFDk3bGiven :1; + unsigned B3SOIFDw0Given :1; + unsigned B3SOIFDnlxGiven :1; + unsigned B3SOIFDdvt0Given :1; + unsigned B3SOIFDdvt1Given :1; + unsigned B3SOIFDdvt2Given :1; + unsigned B3SOIFDdvt0wGiven :1; + unsigned B3SOIFDdvt1wGiven :1; + unsigned B3SOIFDdvt2wGiven :1; + unsigned B3SOIFDdroutGiven :1; + unsigned B3SOIFDdsubGiven :1; + unsigned B3SOIFDvth0Given :1; + unsigned B3SOIFDuaGiven :1; + unsigned B3SOIFDua1Given :1; + unsigned B3SOIFDubGiven :1; + unsigned B3SOIFDub1Given :1; + unsigned B3SOIFDucGiven :1; + unsigned B3SOIFDuc1Given :1; + unsigned B3SOIFDu0Given :1; + unsigned B3SOIFDuteGiven :1; + unsigned B3SOIFDvoffGiven :1; + unsigned B3SOIFDrdswGiven :1; + unsigned B3SOIFDprwgGiven :1; + unsigned B3SOIFDprwbGiven :1; + unsigned B3SOIFDprtGiven :1; + unsigned B3SOIFDeta0Given :1; + unsigned B3SOIFDetabGiven :1; + unsigned B3SOIFDpclmGiven :1; + unsigned B3SOIFDpdibl1Given :1; + unsigned B3SOIFDpdibl2Given :1; + unsigned B3SOIFDpdiblbGiven :1; + unsigned B3SOIFDpvagGiven :1; + unsigned B3SOIFDdeltaGiven :1; + unsigned B3SOIFDwrGiven :1; + unsigned B3SOIFDdwgGiven :1; + unsigned B3SOIFDdwbGiven :1; + unsigned B3SOIFDb0Given :1; + unsigned B3SOIFDb1Given :1; + unsigned B3SOIFDalpha0Given :1; + unsigned B3SOIFDalpha1Given :1; + unsigned B3SOIFDbeta0Given :1; + + /* CV model */ + unsigned B3SOIFDcgslGiven :1; + unsigned B3SOIFDcgdlGiven :1; + unsigned B3SOIFDckappaGiven :1; + unsigned B3SOIFDcfGiven :1; + unsigned B3SOIFDclcGiven :1; + unsigned B3SOIFDcleGiven :1; + unsigned B3SOIFDdwcGiven :1; + unsigned B3SOIFDdlcGiven :1; + +/* Added for binning - START2 */ + /* Length Dependence */ + unsigned B3SOIFDlnpeakGiven :1; + unsigned B3SOIFDlnsubGiven :1; + unsigned B3SOIFDlngateGiven :1; + unsigned B3SOIFDlvth0Given :1; + unsigned B3SOIFDlk1Given :1; + unsigned B3SOIFDlk2Given :1; + unsigned B3SOIFDlk3Given :1; + unsigned B3SOIFDlk3bGiven :1; + unsigned B3SOIFDlvbsaGiven :1; + unsigned B3SOIFDldelpGiven :1; + unsigned B3SOIFDlkb1Given :1; + unsigned B3SOIFDlkb3Given :1; + unsigned B3SOIFDldvbd0Given :1; + unsigned B3SOIFDldvbd1Given :1; + unsigned B3SOIFDlw0Given :1; + unsigned B3SOIFDlnlxGiven :1; + unsigned B3SOIFDldvt0Given :1; + unsigned B3SOIFDldvt1Given :1; + unsigned B3SOIFDldvt2Given :1; + unsigned B3SOIFDldvt0wGiven :1; + unsigned B3SOIFDldvt1wGiven :1; + unsigned B3SOIFDldvt2wGiven :1; + unsigned B3SOIFDlu0Given :1; + unsigned B3SOIFDluaGiven :1; + unsigned B3SOIFDlubGiven :1; + unsigned B3SOIFDlucGiven :1; + unsigned B3SOIFDlvsatGiven :1; + unsigned B3SOIFDla0Given :1; + unsigned B3SOIFDlagsGiven :1; + unsigned B3SOIFDlb0Given :1; + unsigned B3SOIFDlb1Given :1; + unsigned B3SOIFDlketaGiven :1; + unsigned B3SOIFDlabpGiven :1; + unsigned B3SOIFDlmxcGiven :1; + unsigned B3SOIFDladice0Given :1; + unsigned B3SOIFDla1Given :1; + unsigned B3SOIFDla2Given :1; + unsigned B3SOIFDlrdswGiven :1; + unsigned B3SOIFDlprwbGiven :1; + unsigned B3SOIFDlprwgGiven :1; + unsigned B3SOIFDlwrGiven :1; + unsigned B3SOIFDlnfactorGiven :1; + unsigned B3SOIFDldwgGiven :1; + unsigned B3SOIFDldwbGiven :1; + unsigned B3SOIFDlvoffGiven :1; + unsigned B3SOIFDleta0Given :1; + unsigned B3SOIFDletabGiven :1; + unsigned B3SOIFDldsubGiven :1; + unsigned B3SOIFDlcitGiven :1; + unsigned B3SOIFDlcdscGiven :1; + unsigned B3SOIFDlcdscbGiven :1; + unsigned B3SOIFDlcdscdGiven :1; + unsigned B3SOIFDlpclmGiven :1; + unsigned B3SOIFDlpdibl1Given :1; + unsigned B3SOIFDlpdibl2Given :1; + unsigned B3SOIFDlpdiblbGiven :1; + unsigned B3SOIFDldroutGiven :1; + unsigned B3SOIFDlpvagGiven :1; + unsigned B3SOIFDldeltaGiven :1; + unsigned B3SOIFDlaiiGiven :1; + unsigned B3SOIFDlbiiGiven :1; + unsigned B3SOIFDlciiGiven :1; + unsigned B3SOIFDldiiGiven :1; + unsigned B3SOIFDlalpha0Given :1; + unsigned B3SOIFDlalpha1Given :1; + unsigned B3SOIFDlbeta0Given :1; + unsigned B3SOIFDlagidlGiven :1; + unsigned B3SOIFDlbgidlGiven :1; + unsigned B3SOIFDlngidlGiven :1; + unsigned B3SOIFDlntunGiven :1; + unsigned B3SOIFDlndiodeGiven :1; + unsigned B3SOIFDlisbjtGiven :1; + unsigned B3SOIFDlisdifGiven :1; + unsigned B3SOIFDlisrecGiven :1; + unsigned B3SOIFDlistunGiven :1; + unsigned B3SOIFDledlGiven :1; + unsigned B3SOIFDlkbjt1Given :1; + /* CV model */ + unsigned B3SOIFDlvsdfbGiven :1; + unsigned B3SOIFDlvsdthGiven :1; + + /* Width Dependence */ + unsigned B3SOIFDwnpeakGiven :1; + unsigned B3SOIFDwnsubGiven :1; + unsigned B3SOIFDwngateGiven :1; + unsigned B3SOIFDwvth0Given :1; + unsigned B3SOIFDwk1Given :1; + unsigned B3SOIFDwk2Given :1; + unsigned B3SOIFDwk3Given :1; + unsigned B3SOIFDwk3bGiven :1; + unsigned B3SOIFDwvbsaGiven :1; + unsigned B3SOIFDwdelpGiven :1; + unsigned B3SOIFDwkb1Given :1; + unsigned B3SOIFDwkb3Given :1; + unsigned B3SOIFDwdvbd0Given :1; + unsigned B3SOIFDwdvbd1Given :1; + unsigned B3SOIFDww0Given :1; + unsigned B3SOIFDwnlxGiven :1; + unsigned B3SOIFDwdvt0Given :1; + unsigned B3SOIFDwdvt1Given :1; + unsigned B3SOIFDwdvt2Given :1; + unsigned B3SOIFDwdvt0wGiven :1; + unsigned B3SOIFDwdvt1wGiven :1; + unsigned B3SOIFDwdvt2wGiven :1; + unsigned B3SOIFDwu0Given :1; + unsigned B3SOIFDwuaGiven :1; + unsigned B3SOIFDwubGiven :1; + unsigned B3SOIFDwucGiven :1; + unsigned B3SOIFDwvsatGiven :1; + unsigned B3SOIFDwa0Given :1; + unsigned B3SOIFDwagsGiven :1; + unsigned B3SOIFDwb0Given :1; + unsigned B3SOIFDwb1Given :1; + unsigned B3SOIFDwketaGiven :1; + unsigned B3SOIFDwabpGiven :1; + unsigned B3SOIFDwmxcGiven :1; + unsigned B3SOIFDwadice0Given :1; + unsigned B3SOIFDwa1Given :1; + unsigned B3SOIFDwa2Given :1; + unsigned B3SOIFDwrdswGiven :1; + unsigned B3SOIFDwprwbGiven :1; + unsigned B3SOIFDwprwgGiven :1; + unsigned B3SOIFDwwrGiven :1; + unsigned B3SOIFDwnfactorGiven :1; + unsigned B3SOIFDwdwgGiven :1; + unsigned B3SOIFDwdwbGiven :1; + unsigned B3SOIFDwvoffGiven :1; + unsigned B3SOIFDweta0Given :1; + unsigned B3SOIFDwetabGiven :1; + unsigned B3SOIFDwdsubGiven :1; + unsigned B3SOIFDwcitGiven :1; + unsigned B3SOIFDwcdscGiven :1; + unsigned B3SOIFDwcdscbGiven :1; + unsigned B3SOIFDwcdscdGiven :1; + unsigned B3SOIFDwpclmGiven :1; + unsigned B3SOIFDwpdibl1Given :1; + unsigned B3SOIFDwpdibl2Given :1; + unsigned B3SOIFDwpdiblbGiven :1; + unsigned B3SOIFDwdroutGiven :1; + unsigned B3SOIFDwpvagGiven :1; + unsigned B3SOIFDwdeltaGiven :1; + unsigned B3SOIFDwaiiGiven :1; + unsigned B3SOIFDwbiiGiven :1; + unsigned B3SOIFDwciiGiven :1; + unsigned B3SOIFDwdiiGiven :1; + unsigned B3SOIFDwalpha0Given :1; + unsigned B3SOIFDwalpha1Given :1; + unsigned B3SOIFDwbeta0Given :1; + unsigned B3SOIFDwagidlGiven :1; + unsigned B3SOIFDwbgidlGiven :1; + unsigned B3SOIFDwngidlGiven :1; + unsigned B3SOIFDwntunGiven :1; + unsigned B3SOIFDwndiodeGiven :1; + unsigned B3SOIFDwisbjtGiven :1; + unsigned B3SOIFDwisdifGiven :1; + unsigned B3SOIFDwisrecGiven :1; + unsigned B3SOIFDwistunGiven :1; + unsigned B3SOIFDwedlGiven :1; + unsigned B3SOIFDwkbjt1Given :1; + /* CV model */ + unsigned B3SOIFDwvsdfbGiven :1; + unsigned B3SOIFDwvsdthGiven :1; + + /* Cross-term Dependence */ + unsigned B3SOIFDpnpeakGiven :1; + unsigned B3SOIFDpnsubGiven :1; + unsigned B3SOIFDpngateGiven :1; + unsigned B3SOIFDpvth0Given :1; + unsigned B3SOIFDpk1Given :1; + unsigned B3SOIFDpk2Given :1; + unsigned B3SOIFDpk3Given :1; + unsigned B3SOIFDpk3bGiven :1; + unsigned B3SOIFDpvbsaGiven :1; + unsigned B3SOIFDpdelpGiven :1; + unsigned B3SOIFDpkb1Given :1; + unsigned B3SOIFDpkb3Given :1; + unsigned B3SOIFDpdvbd0Given :1; + unsigned B3SOIFDpdvbd1Given :1; + unsigned B3SOIFDpw0Given :1; + unsigned B3SOIFDpnlxGiven :1; + unsigned B3SOIFDpdvt0Given :1; + unsigned B3SOIFDpdvt1Given :1; + unsigned B3SOIFDpdvt2Given :1; + unsigned B3SOIFDpdvt0wGiven :1; + unsigned B3SOIFDpdvt1wGiven :1; + unsigned B3SOIFDpdvt2wGiven :1; + unsigned B3SOIFDpu0Given :1; + unsigned B3SOIFDpuaGiven :1; + unsigned B3SOIFDpubGiven :1; + unsigned B3SOIFDpucGiven :1; + unsigned B3SOIFDpvsatGiven :1; + unsigned B3SOIFDpa0Given :1; + unsigned B3SOIFDpagsGiven :1; + unsigned B3SOIFDpb0Given :1; + unsigned B3SOIFDpb1Given :1; + unsigned B3SOIFDpketaGiven :1; + unsigned B3SOIFDpabpGiven :1; + unsigned B3SOIFDpmxcGiven :1; + unsigned B3SOIFDpadice0Given :1; + unsigned B3SOIFDpa1Given :1; + unsigned B3SOIFDpa2Given :1; + unsigned B3SOIFDprdswGiven :1; + unsigned B3SOIFDpprwbGiven :1; + unsigned B3SOIFDpprwgGiven :1; + unsigned B3SOIFDpwrGiven :1; + unsigned B3SOIFDpnfactorGiven :1; + unsigned B3SOIFDpdwgGiven :1; + unsigned B3SOIFDpdwbGiven :1; + unsigned B3SOIFDpvoffGiven :1; + unsigned B3SOIFDpeta0Given :1; + unsigned B3SOIFDpetabGiven :1; + unsigned B3SOIFDpdsubGiven :1; + unsigned B3SOIFDpcitGiven :1; + unsigned B3SOIFDpcdscGiven :1; + unsigned B3SOIFDpcdscbGiven :1; + unsigned B3SOIFDpcdscdGiven :1; + unsigned B3SOIFDppclmGiven :1; + unsigned B3SOIFDppdibl1Given :1; + unsigned B3SOIFDppdibl2Given :1; + unsigned B3SOIFDppdiblbGiven :1; + unsigned B3SOIFDpdroutGiven :1; + unsigned B3SOIFDppvagGiven :1; + unsigned B3SOIFDpdeltaGiven :1; + unsigned B3SOIFDpaiiGiven :1; + unsigned B3SOIFDpbiiGiven :1; + unsigned B3SOIFDpciiGiven :1; + unsigned B3SOIFDpdiiGiven :1; + unsigned B3SOIFDpalpha0Given :1; + unsigned B3SOIFDpalpha1Given :1; + unsigned B3SOIFDpbeta0Given :1; + unsigned B3SOIFDpagidlGiven :1; + unsigned B3SOIFDpbgidlGiven :1; + unsigned B3SOIFDpngidlGiven :1; + unsigned B3SOIFDpntunGiven :1; + unsigned B3SOIFDpndiodeGiven :1; + unsigned B3SOIFDpisbjtGiven :1; + unsigned B3SOIFDpisdifGiven :1; + unsigned B3SOIFDpisrecGiven :1; + unsigned B3SOIFDpistunGiven :1; + unsigned B3SOIFDpedlGiven :1; + unsigned B3SOIFDpkbjt1Given :1; + /* CV model */ + unsigned B3SOIFDpvsdfbGiven :1; + unsigned B3SOIFDpvsdthGiven :1; +/* Added for binning - END2 */ + + unsigned B3SOIFDuseFringeGiven :1; + + unsigned B3SOIFDtnomGiven :1; + unsigned B3SOIFDcgsoGiven :1; + unsigned B3SOIFDcgdoGiven :1; + unsigned B3SOIFDcgeoGiven :1; + unsigned B3SOIFDxpartGiven :1; + unsigned B3SOIFDsheetResistanceGiven :1; + unsigned B3SOIFDGatesidewallJctPotentialGiven :1; + unsigned B3SOIFDbodyJctGateSideGradingCoeffGiven :1; + unsigned B3SOIFDunitLengthGateSidewallJctCapGiven :1; + unsigned B3SOIFDcsdeswGiven :1; + + unsigned B3SOIFDoxideTrapDensityAGiven :1; + unsigned B3SOIFDoxideTrapDensityBGiven :1; + unsigned B3SOIFDoxideTrapDensityCGiven :1; + unsigned B3SOIFDemGiven :1; + unsigned B3SOIFDefGiven :1; + unsigned B3SOIFDafGiven :1; + unsigned B3SOIFDkfGiven :1; + unsigned B3SOIFDnoifGiven :1; + + unsigned B3SOIFDLintGiven :1; + unsigned B3SOIFDLlGiven :1; + unsigned B3SOIFDLlnGiven :1; + unsigned B3SOIFDLwGiven :1; + unsigned B3SOIFDLwnGiven :1; + unsigned B3SOIFDLwlGiven :1; + unsigned B3SOIFDLminGiven :1; + unsigned B3SOIFDLmaxGiven :1; + + unsigned B3SOIFDWintGiven :1; + unsigned B3SOIFDWlGiven :1; + unsigned B3SOIFDWlnGiven :1; + unsigned B3SOIFDWwGiven :1; + unsigned B3SOIFDWwnGiven :1; + unsigned B3SOIFDWwlGiven :1; + unsigned B3SOIFDWminGiven :1; + unsigned B3SOIFDWmaxGiven :1; + +} B3SOIFDmodel; + + +#ifndef NMOS +#define NMOS 1 +#define PMOS -1 +#endif /*NMOS*/ + + +/* device parameters */ +#define B3SOIFD_W 1 +#define B3SOIFD_L 2 +#define B3SOIFD_AS 3 +#define B3SOIFD_AD 4 +#define B3SOIFD_PS 5 +#define B3SOIFD_PD 6 +#define B3SOIFD_NRS 7 +#define B3SOIFD_NRD 8 +#define B3SOIFD_OFF 9 +#define B3SOIFD_IC_VBS 10 +#define B3SOIFD_IC_VDS 11 +#define B3SOIFD_IC_VGS 12 +#define B3SOIFD_IC_VES 13 +#define B3SOIFD_IC_VPS 14 +#define B3SOIFD_BJTOFF 15 +#define B3SOIFD_RTH0 16 +#define B3SOIFD_CTH0 17 +#define B3SOIFD_NRB 18 +#define B3SOIFD_IC 19 +#define B3SOIFD_NQSMOD 20 +#define B3SOIFD_DEBUG 21 + +/* model parameters */ +#define B3SOIFD_MOD_CAPMOD 101 +#define B3SOIFD_MOD_NQSMOD 102 +#define B3SOIFD_MOD_MOBMOD 103 +#define B3SOIFD_MOD_NOIMOD 104 +#define B3SOIFD_MOD_SHMOD 105 +#define B3SOIFD_MOD_DDMOD 106 + +#define B3SOIFD_MOD_TOX 107 + + + +#define B3SOIFD_MOD_CDSC 108 +#define B3SOIFD_MOD_CDSCB 109 +#define B3SOIFD_MOD_CIT 110 +#define B3SOIFD_MOD_NFACTOR 111 +#define B3SOIFD_MOD_XJ 112 +#define B3SOIFD_MOD_VSAT 113 +#define B3SOIFD_MOD_AT 114 +#define B3SOIFD_MOD_A0 115 +#define B3SOIFD_MOD_A1 116 +#define B3SOIFD_MOD_A2 117 +#define B3SOIFD_MOD_KETA 118 +#define B3SOIFD_MOD_NSUB 119 +#define B3SOIFD_MOD_NPEAK 120 +#define B3SOIFD_MOD_NGATE 121 +#define B3SOIFD_MOD_GAMMA1 122 +#define B3SOIFD_MOD_GAMMA2 123 +#define B3SOIFD_MOD_VBX 124 +#define B3SOIFD_MOD_BINUNIT 125 + +#define B3SOIFD_MOD_VBM 126 + +#define B3SOIFD_MOD_XT 127 +#define B3SOIFD_MOD_K1 129 +#define B3SOIFD_MOD_KT1 130 +#define B3SOIFD_MOD_KT1L 131 +#define B3SOIFD_MOD_K2 132 +#define B3SOIFD_MOD_KT2 133 +#define B3SOIFD_MOD_K3 134 +#define B3SOIFD_MOD_K3B 135 +#define B3SOIFD_MOD_W0 136 +#define B3SOIFD_MOD_NLX 137 + +#define B3SOIFD_MOD_DVT0 138 +#define B3SOIFD_MOD_DVT1 139 +#define B3SOIFD_MOD_DVT2 140 + +#define B3SOIFD_MOD_DVT0W 141 +#define B3SOIFD_MOD_DVT1W 142 +#define B3SOIFD_MOD_DVT2W 143 + +#define B3SOIFD_MOD_DROUT 144 +#define B3SOIFD_MOD_DSUB 145 +#define B3SOIFD_MOD_VTH0 146 +#define B3SOIFD_MOD_UA 147 +#define B3SOIFD_MOD_UA1 148 +#define B3SOIFD_MOD_UB 149 +#define B3SOIFD_MOD_UB1 150 +#define B3SOIFD_MOD_UC 151 +#define B3SOIFD_MOD_UC1 152 +#define B3SOIFD_MOD_U0 153 +#define B3SOIFD_MOD_UTE 154 +#define B3SOIFD_MOD_VOFF 155 +#define B3SOIFD_MOD_DELTA 156 +#define B3SOIFD_MOD_RDSW 157 +#define B3SOIFD_MOD_PRT 158 +#define B3SOIFD_MOD_LDD 159 +#define B3SOIFD_MOD_ETA 160 +#define B3SOIFD_MOD_ETA0 161 +#define B3SOIFD_MOD_ETAB 162 +#define B3SOIFD_MOD_PCLM 163 +#define B3SOIFD_MOD_PDIBL1 164 +#define B3SOIFD_MOD_PDIBL2 165 +#define B3SOIFD_MOD_PSCBE1 166 +#define B3SOIFD_MOD_PSCBE2 167 +#define B3SOIFD_MOD_PVAG 168 +#define B3SOIFD_MOD_WR 169 +#define B3SOIFD_MOD_DWG 170 +#define B3SOIFD_MOD_DWB 171 +#define B3SOIFD_MOD_B0 172 +#define B3SOIFD_MOD_B1 173 +#define B3SOIFD_MOD_ALPHA0 174 +#define B3SOIFD_MOD_BETA0 175 +#define B3SOIFD_MOD_PDIBLB 178 + +#define B3SOIFD_MOD_PRWG 179 +#define B3SOIFD_MOD_PRWB 180 + +#define B3SOIFD_MOD_CDSCD 181 +#define B3SOIFD_MOD_AGS 182 + +#define B3SOIFD_MOD_FRINGE 184 +#define B3SOIFD_MOD_CGSL 186 +#define B3SOIFD_MOD_CGDL 187 +#define B3SOIFD_MOD_CKAPPA 188 +#define B3SOIFD_MOD_CF 189 +#define B3SOIFD_MOD_CLC 190 +#define B3SOIFD_MOD_CLE 191 +#define B3SOIFD_MOD_PARAMCHK 192 +#define B3SOIFD_MOD_VERSION 193 + +#define B3SOIFD_MOD_TBOX 195 +#define B3SOIFD_MOD_TSI 196 +#define B3SOIFD_MOD_KB1 197 +#define B3SOIFD_MOD_KB3 198 +#define B3SOIFD_MOD_DVBD0 199 +#define B3SOIFD_MOD_DVBD1 200 +#define B3SOIFD_MOD_DELP 201 +#define B3SOIFD_MOD_VBSA 202 +#define B3SOIFD_MOD_RBODY 204 +#define B3SOIFD_MOD_ADICE0 205 +#define B3SOIFD_MOD_ABP 206 +#define B3SOIFD_MOD_MXC 207 +#define B3SOIFD_MOD_RTH0 208 +#define B3SOIFD_MOD_CTH0 209 +#define B3SOIFD_MOD_AII 210 +#define B3SOIFD_MOD_BII 211 +#define B3SOIFD_MOD_CII 212 +#define B3SOIFD_MOD_DII 213 +#define B3SOIFD_MOD_ALPHA1 214 +#define B3SOIFD_MOD_NGIDL 215 +#define B3SOIFD_MOD_AGIDL 216 +#define B3SOIFD_MOD_BGIDL 217 +#define B3SOIFD_MOD_NDIODE 218 +#define B3SOIFD_MOD_LDIOF 219 +#define B3SOIFD_MOD_LDIOR 220 +#define B3SOIFD_MOD_NTUN 221 +#define B3SOIFD_MOD_ISBJT 222 +#define B3SOIFD_MOD_ISDIF 223 +#define B3SOIFD_MOD_ISREC 224 +#define B3SOIFD_MOD_ISTUN 225 +#define B3SOIFD_MOD_XBJT 226 +#define B3SOIFD_MOD_XDIF 227 +#define B3SOIFD_MOD_XREC 228 +#define B3SOIFD_MOD_XTUN 229 +#define B3SOIFD_MOD_EDL 230 +#define B3SOIFD_MOD_KBJT1 231 +#define B3SOIFD_MOD_TT 232 +#define B3SOIFD_MOD_VSDTH 233 +#define B3SOIFD_MOD_VSDFB 234 +#define B3SOIFD_MOD_ASD 235 +#define B3SOIFD_MOD_CSDMIN 236 +#define B3SOIFD_MOD_RBSH 237 + +/* Added for binning - START3 */ +/* Length dependence */ +#define B3SOIFD_MOD_LNPEAK 301 +#define B3SOIFD_MOD_LNSUB 302 +#define B3SOIFD_MOD_LNGATE 303 +#define B3SOIFD_MOD_LVTH0 304 +#define B3SOIFD_MOD_LK1 305 +#define B3SOIFD_MOD_LK2 306 +#define B3SOIFD_MOD_LK3 307 +#define B3SOIFD_MOD_LK3B 308 +#define B3SOIFD_MOD_LVBSA 309 +#define B3SOIFD_MOD_LDELP 310 +#define B3SOIFD_MOD_LKB1 311 +#define B3SOIFD_MOD_LKB3 312 +#define B3SOIFD_MOD_LDVBD0 313 +#define B3SOIFD_MOD_LDVBD1 314 +#define B3SOIFD_MOD_LW0 315 +#define B3SOIFD_MOD_LNLX 316 +#define B3SOIFD_MOD_LDVT0 317 +#define B3SOIFD_MOD_LDVT1 318 +#define B3SOIFD_MOD_LDVT2 319 +#define B3SOIFD_MOD_LDVT0W 320 +#define B3SOIFD_MOD_LDVT1W 321 +#define B3SOIFD_MOD_LDVT2W 322 +#define B3SOIFD_MOD_LU0 323 +#define B3SOIFD_MOD_LUA 324 +#define B3SOIFD_MOD_LUB 325 +#define B3SOIFD_MOD_LUC 326 +#define B3SOIFD_MOD_LVSAT 327 +#define B3SOIFD_MOD_LA0 328 +#define B3SOIFD_MOD_LAGS 329 +#define B3SOIFD_MOD_LB0 330 +#define B3SOIFD_MOD_LB1 331 +#define B3SOIFD_MOD_LKETA 332 +#define B3SOIFD_MOD_LABP 333 +#define B3SOIFD_MOD_LMXC 334 +#define B3SOIFD_MOD_LADICE0 335 +#define B3SOIFD_MOD_LA1 336 +#define B3SOIFD_MOD_LA2 337 +#define B3SOIFD_MOD_LRDSW 338 +#define B3SOIFD_MOD_LPRWB 339 +#define B3SOIFD_MOD_LPRWG 340 +#define B3SOIFD_MOD_LWR 341 +#define B3SOIFD_MOD_LNFACTOR 342 +#define B3SOIFD_MOD_LDWG 343 +#define B3SOIFD_MOD_LDWB 344 +#define B3SOIFD_MOD_LVOFF 345 +#define B3SOIFD_MOD_LETA0 346 +#define B3SOIFD_MOD_LETAB 347 +#define B3SOIFD_MOD_LDSUB 348 +#define B3SOIFD_MOD_LCIT 349 +#define B3SOIFD_MOD_LCDSC 350 +#define B3SOIFD_MOD_LCDSCB 351 +#define B3SOIFD_MOD_LCDSCD 352 +#define B3SOIFD_MOD_LPCLM 353 +#define B3SOIFD_MOD_LPDIBL1 354 +#define B3SOIFD_MOD_LPDIBL2 355 +#define B3SOIFD_MOD_LPDIBLB 356 +#define B3SOIFD_MOD_LDROUT 357 +#define B3SOIFD_MOD_LPVAG 358 +#define B3SOIFD_MOD_LDELTA 359 +#define B3SOIFD_MOD_LAII 360 +#define B3SOIFD_MOD_LBII 361 +#define B3SOIFD_MOD_LCII 362 +#define B3SOIFD_MOD_LDII 363 +#define B3SOIFD_MOD_LALPHA0 364 +#define B3SOIFD_MOD_LALPHA1 365 +#define B3SOIFD_MOD_LBETA0 366 +#define B3SOIFD_MOD_LAGIDL 367 +#define B3SOIFD_MOD_LBGIDL 368 +#define B3SOIFD_MOD_LNGIDL 369 +#define B3SOIFD_MOD_LNTUN 370 +#define B3SOIFD_MOD_LNDIODE 371 +#define B3SOIFD_MOD_LISBJT 372 +#define B3SOIFD_MOD_LISDIF 373 +#define B3SOIFD_MOD_LISREC 374 +#define B3SOIFD_MOD_LISTUN 375 +#define B3SOIFD_MOD_LEDL 376 +#define B3SOIFD_MOD_LKBJT1 377 +#define B3SOIFD_MOD_LVSDFB 378 +#define B3SOIFD_MOD_LVSDTH 379 + +/* Width dependence */ +#define B3SOIFD_MOD_WNPEAK 401 +#define B3SOIFD_MOD_WNSUB 402 +#define B3SOIFD_MOD_WNGATE 403 +#define B3SOIFD_MOD_WVTH0 404 +#define B3SOIFD_MOD_WK1 405 +#define B3SOIFD_MOD_WK2 406 +#define B3SOIFD_MOD_WK3 407 +#define B3SOIFD_MOD_WK3B 408 +#define B3SOIFD_MOD_WVBSA 409 +#define B3SOIFD_MOD_WDELP 410 +#define B3SOIFD_MOD_WKB1 411 +#define B3SOIFD_MOD_WKB3 412 +#define B3SOIFD_MOD_WDVBD0 413 +#define B3SOIFD_MOD_WDVBD1 414 +#define B3SOIFD_MOD_WW0 415 +#define B3SOIFD_MOD_WNLX 416 +#define B3SOIFD_MOD_WDVT0 417 +#define B3SOIFD_MOD_WDVT1 418 +#define B3SOIFD_MOD_WDVT2 419 +#define B3SOIFD_MOD_WDVT0W 420 +#define B3SOIFD_MOD_WDVT1W 421 +#define B3SOIFD_MOD_WDVT2W 422 +#define B3SOIFD_MOD_WU0 423 +#define B3SOIFD_MOD_WUA 424 +#define B3SOIFD_MOD_WUB 425 +#define B3SOIFD_MOD_WUC 426 +#define B3SOIFD_MOD_WVSAT 427 +#define B3SOIFD_MOD_WA0 428 +#define B3SOIFD_MOD_WAGS 429 +#define B3SOIFD_MOD_WB0 430 +#define B3SOIFD_MOD_WB1 431 +#define B3SOIFD_MOD_WKETA 432 +#define B3SOIFD_MOD_WABP 433 +#define B3SOIFD_MOD_WMXC 434 +#define B3SOIFD_MOD_WADICE0 435 +#define B3SOIFD_MOD_WA1 436 +#define B3SOIFD_MOD_WA2 437 +#define B3SOIFD_MOD_WRDSW 438 +#define B3SOIFD_MOD_WPRWB 439 +#define B3SOIFD_MOD_WPRWG 440 +#define B3SOIFD_MOD_WWR 441 +#define B3SOIFD_MOD_WNFACTOR 442 +#define B3SOIFD_MOD_WDWG 443 +#define B3SOIFD_MOD_WDWB 444 +#define B3SOIFD_MOD_WVOFF 445 +#define B3SOIFD_MOD_WETA0 446 +#define B3SOIFD_MOD_WETAB 447 +#define B3SOIFD_MOD_WDSUB 448 +#define B3SOIFD_MOD_WCIT 449 +#define B3SOIFD_MOD_WCDSC 450 +#define B3SOIFD_MOD_WCDSCB 451 +#define B3SOIFD_MOD_WCDSCD 452 +#define B3SOIFD_MOD_WPCLM 453 +#define B3SOIFD_MOD_WPDIBL1 454 +#define B3SOIFD_MOD_WPDIBL2 455 +#define B3SOIFD_MOD_WPDIBLB 456 +#define B3SOIFD_MOD_WDROUT 457 +#define B3SOIFD_MOD_WPVAG 458 +#define B3SOIFD_MOD_WDELTA 459 +#define B3SOIFD_MOD_WAII 460 +#define B3SOIFD_MOD_WBII 461 +#define B3SOIFD_MOD_WCII 462 +#define B3SOIFD_MOD_WDII 463 +#define B3SOIFD_MOD_WALPHA0 464 +#define B3SOIFD_MOD_WALPHA1 465 +#define B3SOIFD_MOD_WBETA0 466 +#define B3SOIFD_MOD_WAGIDL 467 +#define B3SOIFD_MOD_WBGIDL 468 +#define B3SOIFD_MOD_WNGIDL 469 +#define B3SOIFD_MOD_WNTUN 470 +#define B3SOIFD_MOD_WNDIODE 471 +#define B3SOIFD_MOD_WISBJT 472 +#define B3SOIFD_MOD_WISDIF 473 +#define B3SOIFD_MOD_WISREC 474 +#define B3SOIFD_MOD_WISTUN 475 +#define B3SOIFD_MOD_WEDL 476 +#define B3SOIFD_MOD_WKBJT1 477 +#define B3SOIFD_MOD_WVSDFB 478 +#define B3SOIFD_MOD_WVSDTH 479 + +/* Cross-term dependence */ +#define B3SOIFD_MOD_PNPEAK 501 +#define B3SOIFD_MOD_PNSUB 502 +#define B3SOIFD_MOD_PNGATE 503 +#define B3SOIFD_MOD_PVTH0 504 +#define B3SOIFD_MOD_PK1 505 +#define B3SOIFD_MOD_PK2 506 +#define B3SOIFD_MOD_PK3 507 +#define B3SOIFD_MOD_PK3B 508 +#define B3SOIFD_MOD_PVBSA 509 +#define B3SOIFD_MOD_PDELP 510 +#define B3SOIFD_MOD_PKB1 511 +#define B3SOIFD_MOD_PKB3 512 +#define B3SOIFD_MOD_PDVBD0 513 +#define B3SOIFD_MOD_PDVBD1 514 +#define B3SOIFD_MOD_PW0 515 +#define B3SOIFD_MOD_PNLX 516 +#define B3SOIFD_MOD_PDVT0 517 +#define B3SOIFD_MOD_PDVT1 518 +#define B3SOIFD_MOD_PDVT2 519 +#define B3SOIFD_MOD_PDVT0W 520 +#define B3SOIFD_MOD_PDVT1W 521 +#define B3SOIFD_MOD_PDVT2W 522 +#define B3SOIFD_MOD_PU0 523 +#define B3SOIFD_MOD_PUA 524 +#define B3SOIFD_MOD_PUB 525 +#define B3SOIFD_MOD_PUC 526 +#define B3SOIFD_MOD_PVSAT 527 +#define B3SOIFD_MOD_PA0 528 +#define B3SOIFD_MOD_PAGS 529 +#define B3SOIFD_MOD_PB0 530 +#define B3SOIFD_MOD_PB1 531 +#define B3SOIFD_MOD_PKETA 532 +#define B3SOIFD_MOD_PABP 533 +#define B3SOIFD_MOD_PMXC 534 +#define B3SOIFD_MOD_PADICE0 535 +#define B3SOIFD_MOD_PA1 536 +#define B3SOIFD_MOD_PA2 537 +#define B3SOIFD_MOD_PRDSW 538 +#define B3SOIFD_MOD_PPRWB 539 +#define B3SOIFD_MOD_PPRWG 540 +#define B3SOIFD_MOD_PWR 541 +#define B3SOIFD_MOD_PNFACTOR 542 +#define B3SOIFD_MOD_PDWG 543 +#define B3SOIFD_MOD_PDWB 544 +#define B3SOIFD_MOD_PVOFF 545 +#define B3SOIFD_MOD_PETA0 546 +#define B3SOIFD_MOD_PETAB 547 +#define B3SOIFD_MOD_PDSUB 548 +#define B3SOIFD_MOD_PCIT 549 +#define B3SOIFD_MOD_PCDSC 550 +#define B3SOIFD_MOD_PCDSCB 551 +#define B3SOIFD_MOD_PCDSCD 552 +#define B3SOIFD_MOD_PPCLM 553 +#define B3SOIFD_MOD_PPDIBL1 554 +#define B3SOIFD_MOD_PPDIBL2 555 +#define B3SOIFD_MOD_PPDIBLB 556 +#define B3SOIFD_MOD_PDROUT 557 +#define B3SOIFD_MOD_PPVAG 558 +#define B3SOIFD_MOD_PDELTA 559 +#define B3SOIFD_MOD_PAII 560 +#define B3SOIFD_MOD_PBII 561 +#define B3SOIFD_MOD_PCII 562 +#define B3SOIFD_MOD_PDII 563 +#define B3SOIFD_MOD_PALPHA0 564 +#define B3SOIFD_MOD_PALPHA1 565 +#define B3SOIFD_MOD_PBETA0 566 +#define B3SOIFD_MOD_PAGIDL 567 +#define B3SOIFD_MOD_PBGIDL 568 +#define B3SOIFD_MOD_PNGIDL 569 +#define B3SOIFD_MOD_PNTUN 570 +#define B3SOIFD_MOD_PNDIODE 571 +#define B3SOIFD_MOD_PISBJT 572 +#define B3SOIFD_MOD_PISDIF 573 +#define B3SOIFD_MOD_PISREC 574 +#define B3SOIFD_MOD_PISTUN 575 +#define B3SOIFD_MOD_PEDL 576 +#define B3SOIFD_MOD_PKBJT1 577 +#define B3SOIFD_MOD_PVSDFB 578 +#define B3SOIFD_MOD_PVSDTH 579 +/* Added for binning - END3 */ + +#define B3SOIFD_MOD_TNOM 701 +#define B3SOIFD_MOD_CGSO 702 +#define B3SOIFD_MOD_CGDO 703 +#define B3SOIFD_MOD_CGEO 704 +#define B3SOIFD_MOD_XPART 705 + +#define B3SOIFD_MOD_RSH 706 +#define B3SOIFD_MOD_NMOS 814 +#define B3SOIFD_MOD_PMOS 815 + +#define B3SOIFD_MOD_NOIA 816 +#define B3SOIFD_MOD_NOIB 817 +#define B3SOIFD_MOD_NOIC 818 + +#define B3SOIFD_MOD_LINT 819 +#define B3SOIFD_MOD_LL 820 +#define B3SOIFD_MOD_LLN 821 +#define B3SOIFD_MOD_LW 822 +#define B3SOIFD_MOD_LWN 823 +#define B3SOIFD_MOD_LWL 824 + +#define B3SOIFD_MOD_WINT 827 +#define B3SOIFD_MOD_WL 828 +#define B3SOIFD_MOD_WLN 829 +#define B3SOIFD_MOD_WW 830 +#define B3SOIFD_MOD_WWN 831 +#define B3SOIFD_MOD_WWL 832 + +#define B3SOIFD_MOD_DWC 835 +#define B3SOIFD_MOD_DLC 836 + +#define B3SOIFD_MOD_EM 837 +#define B3SOIFD_MOD_EF 838 +#define B3SOIFD_MOD_AF 839 +#define B3SOIFD_MOD_KF 840 +#define B3SOIFD_MOD_NOIF 841 + + +#define B3SOIFD_MOD_PBSWG 843 +#define B3SOIFD_MOD_MJSWG 844 +#define B3SOIFD_MOD_CJSWG 845 +#define B3SOIFD_MOD_CSDESW 846 + +/* device questions */ +#define B3SOIFD_DNODE 901 +#define B3SOIFD_GNODE 902 +#define B3SOIFD_SNODE 903 +#define B3SOIFD_BNODE 904 +#define B3SOIFD_ENODE 905 +#define B3SOIFD_DNODEPRIME 906 +#define B3SOIFD_SNODEPRIME 907 +#define B3SOIFD_VBD 908 +#define B3SOIFD_VBS 909 +#define B3SOIFD_VGS 910 +#define B3SOIFD_VES 911 +#define B3SOIFD_VDS 912 +#define B3SOIFD_CD 913 +#define B3SOIFD_CBS 914 +#define B3SOIFD_CBD 915 +#define B3SOIFD_GM 916 +#define B3SOIFD_GDS 917 +#define B3SOIFD_GMBS 918 +#define B3SOIFD_GBD 919 +#define B3SOIFD_GBS 920 +#define B3SOIFD_QB 921 +#define B3SOIFD_CQB 922 +#define B3SOIFD_QG 923 +#define B3SOIFD_CQG 924 +#define B3SOIFD_QD 925 +#define B3SOIFD_CQD 926 +#define B3SOIFD_CGG 927 +#define B3SOIFD_CGD 928 +#define B3SOIFD_CGS 929 +#define B3SOIFD_CBG 930 +#define B3SOIFD_CAPBD 931 +#define B3SOIFD_CQBD 932 +#define B3SOIFD_CAPBS 933 +#define B3SOIFD_CQBS 934 +#define B3SOIFD_CDG 935 +#define B3SOIFD_CDD 936 +#define B3SOIFD_CDS 937 +#define B3SOIFD_VON 938 +#define B3SOIFD_VDSAT 939 +#define B3SOIFD_QBS 940 +#define B3SOIFD_QBD 941 +#define B3SOIFD_SOURCECONDUCT 942 +#define B3SOIFD_DRAINCONDUCT 943 +#define B3SOIFD_CBDB 944 +#define B3SOIFD_CBSB 945 +#define B3SOIFD_GMID 946 + + +#include "b3soifdext.h" + +#ifdef __STDC__ +extern void B3SOIFDevaluate(double,double,double,B3SOIFDinstance*,B3SOIFDmodel*, + double*,double*,double*, double*, double*, double*, double*, + double*, double*, double*, double*, double*, double*, double*, + double*, double*, double*, double*, CKTcircuit*); +extern int B3SOIFDdebug(B3SOIFDmodel*, B3SOIFDinstance*, CKTcircuit*, int); +extern int B3SOIFDcheckModel(B3SOIFDmodel*, B3SOIFDinstance*, CKTcircuit*); +#else /* stdc */ +extern void B3SOIFDevaluate(); +extern int B3SOIFDdebug(); +extern int B3SOIFDcheckModel(); +#endif /* stdc */ + +#endif /*B3SOIFD*/ + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifddel.c b/src/spicelib/devices/bsim3soi_fd/b3soifddel.c new file mode 100644 index 000000000..1bd685757 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifddel.c @@ -0,0 +1,41 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soifddel.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "b3soifddef.h" +#include "sperror.h" +#include "gendefs.h" +#include "suffix.h" + + +int +B3SOIFDdelete(inModel,name,inInst) +GENmodel *inModel; +IFuid name; +GENinstance **inInst; +{ +B3SOIFDinstance **fast = (B3SOIFDinstance**)inInst; +B3SOIFDmodel *model = (B3SOIFDmodel*)inModel; +B3SOIFDinstance **prev = NULL; +B3SOIFDinstance *here; + + for (; model ; model = model->B3SOIFDnextModel) + { prev = &(model->B3SOIFDinstances); + for (here = *prev; here ; here = *prev) + { if (here->B3SOIFDname == name || (fast && here==*fast)) + { *prev= here->B3SOIFDnextInstance; + FREE(here); + return(OK); + } + prev = &(here->B3SOIFDnextInstance); + } + } + return(E_NODEV); +} + + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifddest.c b/src/spicelib/devices/bsim3soi_fd/b3soifddest.c new file mode 100644 index 000000000..5e70e5c36 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifddest.c @@ -0,0 +1,39 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soifddest.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "b3soifddef.h" +#include "suffix.h" + +void +B3SOIFDdestroy(inModel) +GENmodel **inModel; +{ +B3SOIFDmodel **model = (B3SOIFDmodel**)inModel; +B3SOIFDinstance *here; +B3SOIFDinstance *prev = NULL; +B3SOIFDmodel *mod = *model; +B3SOIFDmodel *oldmod = NULL; + + for (; mod ; mod = mod->B3SOIFDnextModel) + { if(oldmod) FREE(oldmod); + oldmod = mod; + prev = (B3SOIFDinstance *)NULL; + for (here = mod->B3SOIFDinstances; here; here = here->B3SOIFDnextInstance) + { if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + } + if(oldmod) FREE(oldmod); + *model = NULL; + return; +} + + + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdext.h b/src/spicelib/devices/bsim3soi_fd/b3soifdext.h new file mode 100644 index 000000000..14c807421 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdext.h @@ -0,0 +1,53 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung +File: b3soifdext.h +**********/ + +#ifdef __STDC__ +extern int B3SOIFDacLoad(GENmodel *,CKTcircuit*); +extern int B3SOIFDask(CKTcircuit *,GENinstance*,int,IFvalue*,IFvalue*); +extern int B3SOIFDconvTest(GENmodel *,CKTcircuit*); +extern int B3SOIFDdelete(GENmodel*,IFuid,GENinstance**); +extern void B3SOIFDdestroy(GENmodel**); +extern int B3SOIFDgetic(GENmodel*,CKTcircuit*); +extern int B3SOIFDload(GENmodel*,CKTcircuit*); +extern int B3SOIFDmAsk(CKTcircuit*,GENmodel *,int, IFvalue*); +extern int B3SOIFDmDelete(GENmodel**,IFuid,GENmodel*); +extern int B3SOIFDmParam(int,IFvalue*,GENmodel*); +extern void B3SOIFDmosCap(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*, + double*); +extern int B3SOIFDparam(int,IFvalue*,GENinstance*,IFvalue*); +extern int B3SOIFDpzLoad(GENmodel*,CKTcircuit*,SPcomplex*); +extern int B3SOIFDsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); +extern int B3SOIFDtemp(GENmodel*,CKTcircuit*); +extern int B3SOIFDtrunc(GENmodel*,CKTcircuit*,double*); +extern int B3SOIFDnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); +extern int B3SOIFDunsetup(GENmodel*,CKTcircuit*); + +#else /* stdc */ +extern int B3SOIFDacLoad(); +extern int B3SOIFDdelete(); +extern void B3SOIFDdestroy(); +extern int B3SOIFDgetic(); +extern int B3SOIFDload(); +extern int B3SOIFDmDelete(); +extern int B3SOIFDask(); +extern int B3SOIFDmAsk(); +extern int B3SOIFDconvTest(); +extern int B3SOIFDtemp(); +extern int B3SOIFDmParam(); +extern void B3SOIFDmosCap(); +extern int B3SOIFDparam(); +extern int B3SOIFDpzLoad(); +extern int B3SOIFDsetup(); +extern int B3SOIFDtrunc(); +extern int B3SOIFDnoise(); +extern int B3SOIFDunsetup(); + +#endif /* stdc */ + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdgetic.c b/src/spicelib/devices/bsim3soi_fd/b3soifdgetic.c new file mode 100644 index 000000000..34214f86e --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdgetic.c @@ -0,0 +1,51 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soifdgetic.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "b3soifddef.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIFDgetic(inModel,ckt) +GENmodel *inModel; +CKTcircuit *ckt; +{ +B3SOIFDmodel *model = (B3SOIFDmodel*)inModel; +B3SOIFDinstance *here; + + for (; model ; model = model->B3SOIFDnextModel) + { for (here = model->B3SOIFDinstances; here; here = here->B3SOIFDnextInstance) + { if(!here->B3SOIFDicVBSGiven) + { here->B3SOIFDicVBS = *(ckt->CKTrhs + here->B3SOIFDbNode) + - *(ckt->CKTrhs + here->B3SOIFDsNode); + } + if (!here->B3SOIFDicVDSGiven) + { here->B3SOIFDicVDS = *(ckt->CKTrhs + here->B3SOIFDdNode) + - *(ckt->CKTrhs + here->B3SOIFDsNode); + } + if (!here->B3SOIFDicVGSGiven) + { here->B3SOIFDicVGS = *(ckt->CKTrhs + here->B3SOIFDgNode) + - *(ckt->CKTrhs + here->B3SOIFDsNode); + } + if (!here->B3SOIFDicVESGiven) + { here->B3SOIFDicVES = *(ckt->CKTrhs + here->B3SOIFDeNode) + - *(ckt->CKTrhs + here->B3SOIFDsNode); + } + if (!here->B3SOIFDicVPSGiven) + { here->B3SOIFDicVPS = *(ckt->CKTrhs + here->B3SOIFDpNode) + - *(ckt->CKTrhs + here->B3SOIFDsNode); + } + } + } + return(OK); +} + + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdinit.c b/src/spicelib/devices/bsim3soi_fd/b3soifdinit.c new file mode 100644 index 000000000..fe82c2624 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdinit.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "b3soifditf.h" +#include "b3soifdext.h" +#include "b3soifdinit.h" + +SPICEdev B3SOIFDinfo = { + { "B3SOIFD", + "Berkeley SOI MOSFET (FD) model version 1.0", + + &B3SOIFDnSize, + &B3SOIFDnSize, + B3SOIFDnames, + + &B3SOIFDpTSize, + B3SOIFDpTable, + + &B3SOIFDmPTSize, + B3SOIFDmPTable, + DEV_DEFAULT} + , + +DEVparam: B3SOIFDparam, +DEVmodParam: B3SOIFDmParam, +DEVload: B3SOIFDload, +DEVsetup: B3SOIFDsetup, +DEVunsetup: B3SOIFDunsetup, +DEVpzSetup: B3SOIFDsetup, +DEVtemperature:B3SOIFDtemp, +DEVtrunc: B3SOIFDtrunc, +DEVfindBranch: NULL, +DEVacLoad: B3SOIFDacLoad, +DEVaccept: NULL, +DEVdestroy: B3SOIFDdestroy, +DEVmodDelete: B3SOIFDmDelete, +DEVdelete: B3SOIFDdelete, +DEVsetic: B3SOIFDgetic, +DEVask: B3SOIFDask, +DEVmodAsk: B3SOIFDmAsk, +DEVpzLoad: B3SOIFDpzLoad, +DEVconvTest: B3SOIFDconvTest, +DEVsenSetup: NULL, +DEVsenLoad: NULL, +DEVsenUpdate: NULL, +DEVsenAcLoad: NULL, +DEVsenPrint: NULL, +DEVsenTrunc: NULL, +DEVdisto: NULL, +DEVnoise: B3SOIFDnoise, +DEVinstSize: &B3SOIFDiSize, +DEVmodSize: &B3SOIFDmSize +}; + + + + + + +SPICEdev * +get_bsim3soifd_info (void) +{ + return &B3SOIFDinfo; +} diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdinit.h b/src/spicelib/devices/bsim3soi_fd/b3soifdinit.h new file mode 100644 index 000000000..f7e7cdb54 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdinit.h @@ -0,0 +1,13 @@ +#ifndef _B3SOIFDINIT_H +#define _B3SOIFDINIT_H + +extern IFparm B3SOIFDpTable[]; +extern IFparm B3SOIFDmPTable[]; +extern char *B3SOIFDnames[]; +extern int B3SOIFDpTSize; +extern int B3SOIFDmPTSize; +extern int B3SOIFDnSize; +extern int B3SOIFDiSize; +extern int B3SOIFDmSize; + +#endif diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifditf.h b/src/spicelib/devices/bsim3soi_fd/b3soifditf.h new file mode 100644 index 000000000..5c4f4f2d0 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifditf.h @@ -0,0 +1,14 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung +File: b3soifditf.h +**********/ +#ifndef DEV_B3SOIFD +#define DEV_B3SOIFD + +#include "b3soifdext.h" + +SPICEdev *get_bsim3soifd_info (void); + +#endif + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdld.c b/src/spicelib/devices/bsim3soi_fd/b3soifdld.c new file mode 100644 index 000000000..886ccb629 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdld.c @@ -0,0 +1,3575 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +Modified by Pin Su, Wei Jin 99/9/27 +File: b3soifdld.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "b3soifddef.h" +#include "trandefs.h" +#include "const.h" +#include "sperror.h" +#include "devdefs.h" +#include "suffix.h" + +#define MAX_EXP 5.834617425e14 +#define MIN_EXP 1.713908431e-15 +#define EXP_THRESHOLD 34.0 +#define EPSOX 3.453133e-11 +#define EPSSI 1.03594e-10 +#define Charge_q 1.60219e-19 +#define KboQ 8.617087e-5 /* Kb / q */ +#define Eg300 1.115 /* energy gap at 300K */ +#define DELTA_1 0.02 +#define DELTA_2 0.02 +#define DELTA_3 0.02 +#define DELTA_4 0.02 +#define DELT_Vbs0eff 0.02 +#define DELT_Vbsmos 0.005 +#define DELT_Vbseff 0.005 +#define DELT_Xcsat 0.2 +#define DELT_Vbs0dio 1e-7 +#define DELTA_VFB 0.02 +#define DELTA_Vcscv 0.0004 +#define DELT_Vbsdio 0.01 +#define CONST_2OV3 0.6666666666 +#define OFF_Vbsdio 2e-2 +#define OFF_Vbs0_dio 2.02e-2 +#define QEX_FACT 20 + + + /* B3SOIFDSmartVbs(Vbs, Old, here, check) + * Smart Vbs guess. + */ + +double +B3SOIFDSmartVbs(New, Old, here, ckt, check) + double New, Old; + B3SOIFDinstance *here; + CKTcircuit *ckt; + int *check; +{ + double T0, T1, del; + + /* only do it for floating body and DC */ + if (here->B3SOIFDfloat && (ckt->CKTmode & (MODEDC | MODEDCOP))) + { + /* Vbs cannot be negative in DC */ + if (New < 0.0) New = 0.0; + } + return(New); +} + + + /* B3SOIFDlimit(vnew,vold) + * limits the per-iteration change of any absolute voltage value + */ + +double +B3SOIFDlimit(vnew, vold, limit, check) + double vnew; + double vold; + double limit; + int *check; +{ + double T0, T1; + + if (isnan (vnew) || isnan (vold)) + { + fprintf(stderr, "Alberto says: YOU TURKEY! The limiting function received NaN.\n"); + fprintf(stderr, "New prediction returns to 0.0!\n"); + vnew = 0.0; + *check = 1; + } + T0 = vnew - vold; + T1 = fabs(T0); + if (T1 > limit) { + if (T0 > 0.0) + vnew = vold + limit; + else + vnew = vold - limit; + *check = 1; + } + return vnew; +} + + + +int +B3SOIFDload(inModel,ckt) +GENmodel *inModel; + CKTcircuit *ckt; +{ + B3SOIFDmodel *model = (B3SOIFDmodel*)inModel; + B3SOIFDinstance *here; + int selfheat; + +double SourceSatCurrent, DrainSatCurrent, Gmin; +double ag0, qgd, qgs, qgb, von, cbhat, VgstNVt, ExpVgst; +double cdhat, cdreq, ceqbd, ceqbs, ceqqb, ceqqd, ceqqg, ceq, geq; +double evbd, evbs, arg, sarg; +double delvbd, delvbs, delvds, delvgd, delvgs; +double Vfbeff, dVfbeff_dVg, dVfbeff_dVd, dVfbeff_dVb, V3, V4; +double tol, PhiB, PhiBSW, MJ, MJSW, PhiBSWG, MJSWG; +double gcgdb, gcggb, gcgsb, gcgeb, gcgT; +double gcsdb, gcsgb, gcssb, gcseb, gcsT; +double gcddb, gcdgb, gcdsb, gcdeb, gcdT; +double gcbdb, gcbgb, gcbsb, gcbeb, gcbT; +double gcedb, gcegb, gcesb, gceeb, gceT; +double gcTt, gTtg, gTtb, gTte, gTtdp, gTtt, gTtsp; +double vbd, vbs, vds, vgb, vgd, vgs, vgdo, xfact; +double vg, vd, vs, vp, ve, vb; +double Vds, Vgs, Vbs, Gmbs, FwdSum, RevSum; +double Vgs_eff, Vfb, dVfb_dVb, dVfb_dVd, dVfb_dT; +double Phis, dPhis_dVb, sqrtPhis, dsqrtPhis_dVb, Vth, dVth_dVb, dVth_dVd, dVth_dT; +double Vgst, dVgst_dVg, dVgst_dVb, dVgs_eff_dVg, Nvtm; +double Vgdt, Vgsaddvth, Vgsaddvth2, Vgsaddvth1o3, n, dn_dVb, Vtm; +double ExpArg, V0; +double ueff, dueff_dVg, dueff_dVd, dueff_dVb, dueff_dT; +double Esat, dEsat_dVg, dEsat_dVd, dEsat_dVb, Vdsat, Vdsat0; +double EsatL, dEsatL_dVg, dEsatL_dVd, dEsatL_dVb, dEsatL_dT; +double dVdsat_dVg, dVdsat_dVb, dVdsat_dVd, dVdsat_dT, Vasat, dAlphaz_dVg, dAlphaz_dVb; +double dVasat_dVg, dVasat_dVb, dVasat_dVd, dVasat_dT; +double Va, Va2, dVa_dVd, dVa_dVg, dVa_dVb, dVa_dT; +double Vbseff, dVbseff_dVb, VbseffCV, dVbseffCV_dVb; +double One_Third_CoxWL, Two_Third_CoxWL, Alphaz, CoxWL; +double dVgdt_dVg, dVgdt_dVd, dVgdt_dVb; +double T0, dT0_dVg, dT0_dVd, dT0_dVb, dT0_dVc, dT0_dVe, dT0_dVrg, dT0_dT; +double T1, dT1_dVg, dT1_dVd, dT1_dVb, dT1_dVc, dT1_dVe, dT1_dT; +double T2, dT2_dVg, dT2_dVd, dT2_dVb, dT2_dVc, dT2_dVe, dT2_dT; +double T3, dT3_dVg, dT3_dVd, dT3_dVb, dT3_dVc, dT3_dVe, dT3_dT; +double T4, dT4_dVg, dT4_dVd, dT4_dVb, dT4_dVc, dT4_dVe, dT4_dT; +double T5, dT5_dVg, dT5_dVd, dT5_dVb, dT5_dVc, dT5_dVe, dT5_dT; +double T6, dT6_dVg, dT6_dVd, dT6_dVb, dT6_dVc, dT6_dVe, dT6_dT; +double T7, dT7_dVg, dT7_dVd, dT7_dVb; +double T8, dT8_dVg, dT8_dVd, dT8_dVb, dT8_dVc, dT8_dVe, dT8_dVrg; +double T9, dT9_dVg, dT9_dVd, dT9_dVb, dT9_dVc, dT9_dVe, dT9_dVrg; +double T10, dT10_dVg, dT10_dVb, dT10_dVd; +double T11, T12; +double tmp, Abulk, dAbulk_dVb, Abulk0, dAbulk0_dVb; +double T100, T101; +double VACLM, dVACLM_dVg, dVACLM_dVd, dVACLM_dVb, dVACLM_dT; +double VADIBL, dVADIBL_dVg, dVADIBL_dVd, dVADIBL_dVb, dVADIBL_dT; +double VAHCE, dVAHCE_dVg, dVAHCE_dVd, dVAHCE_dVb; +double Xdep, dXdep_dVb, lt1, dlt1_dVb, ltw, dltw_dVb; +double Delt_vth, dDelt_vth_dVb, dDelt_vth_dT; +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 tempv, a1; + +double Vgsteff, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb, dVgsteff_dVe, dVgsteff_dT; +double Vdseff, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb, dVdseff_dT; +double VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb; +double diffVds, diffVdsCV; +double dAbulk_dVg, dn_dVd ; +double beta, dbeta_dVg, dbeta_dVd, dbeta_dVb, dbeta_dT; +double gche, dgche_dVg, dgche_dVd, dgche_dVb, dgche_dT; +double fgche1, dfgche1_dVg, dfgche1_dVd, dfgche1_dVb, dfgche1_dT; +double fgche2, dfgche2_dVg, dfgche2_dVd, dfgche2_dVb, dfgche2_dT; +double Idl, dIdl_dVg, dIdl_dVd, dIdl_dVb, dIdl_dT; +double Ids, Gm, Gds, Gmb; +double CoxWovL; +double Rds, dRds_dVg, dRds_dVb, dRds_dT, WVCox, WVCoxRds; +double Vgst2Vtm, dVgst2Vtm_dT, VdsatCV, dVdsatCV_dVd, dVdsatCV_dVg, dVdsatCV_dVb; +double Leff, Weff, dWeff_dVg, dWeff_dVb; +double AbulkCV, dAbulkCV_dVb; +double qgdo, qgso, cgdo, cgso; + +double dxpart, sxpart; + +struct b3soifdSizeDependParam *pParam; +int ByPass, Check, ChargeComputationNeeded, J, error, I; +double junk[50]; + +double gbbsp, gbbdp, gbbg, gbbb, gbbe, gbbp, gbbT; +double gddpsp, gddpdp, gddpg, gddpb, gddpe, gddpT; +double gsspsp, gsspdp, gsspg, gsspb, gsspe, gsspT; +double Gbpbs, Gbpgs, Gbpds, Gbpes, Gbpps, GbpT; +double vse, vde, ves, ved, veb, vge, delves, vedo, delved; +double vps, vpd, Vps, delvps; +double Vbd, Ves, Vesfb, sqrtXdep, DeltVthtemp, dDeltVthtemp_dT; +double Vbp, dVbp_dVp, dVbp_dVb, dVbp_dVg, dVbp_dVd, dVbp_dVe, dVbp_dT; +double Vpsdio, dVpsdio_dVg, dVpsdio_dVd, dVpsdio_dVe, dVpsdio_dVp, dVpsdio_dT; +double DeltVthw, dDeltVthw_dVb, dDeltVthw_dT; +double dVbseff_dVd, dVbseff_dVe, dVbseff_dT; +double dVdsat_dVc, dVasat_dVc, dVACLM_dVc, dVADIBL_dVc, dVa_dVc; +double dfgche1_dVc, dfgche2_dVc, dgche_dVc, dVdseff_dVc, dIdl_dVc; +double Gm0, Gds0, Gmb0, GmT0, Gmc, Gme, GmT, dVbseff_dVg; +double dDIBL_Sft_dVb, BjtA, dBjtA_dVd; +double diffVdsii ; +double Idgidl, Gdgidld, Gdgidlg, Isgidl, Gsgidlg; +double Gjsd, Gjss, Gjsb, GjsT, Gjdd, Gjdb, GjdT; +double Ibp, Iii, Giid, Giig, Giib, Giie, GiiT, Gcd, Gcb, GcT, ceqbody, ceqbodcon; +double gppg, gppdp, gppb, gppe, gppp, gppsp, gppT; +double delTemp, deldelTemp, Temp; +double ceqth, ceqqth; +double K1, WL; +double qjs, gcjsbs, gcjsT; +double qjd, gcjdbs, gcjdds, gcjdT; +double qge; +double ceqqe; +double ni, Eg, Cbox, Nfb, CboxWL; +double cjsbs; +double Qbf0, Qsicv, dVfbeff_dVrg, Cbe ; +double qinv, qgate, qbody, qdrn, qsrc, qsub, cqgate, cqbody, cqdrn, cqsub, cqtemp; +double Cgg, Cgd, Cgs, Cgb, Cge, Cdg, Cdd, Cds, Cdb, Qg, Qd; +double Csg, Csd, Css, Csb, Cse, Cbg, Cbd, Cbs, Cbb, Qs, Qb; +double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Csg1, Csd1, Csb1; +double Vbs0t, dVbs0t_dT ; +double Vbs0 ,dVbs0_dVe, dVbs0_dT; +double Vbs0eff ,dVbs0eff_dVg ,dVbs0eff_dVd ,dVbs0eff_dVe, dVbs0eff_dT; +double Vbs0teff,dVbs0teff_dVg ,dVbs0teff_dVd, dVbs0teff_dVe, dVbs0teff_dT; +double Vbsdio, dVbsdio_dVg, dVbsdio_dVd, dVbsdio_dVe, dVbsdio_dVb, dVbsdio_dT; +double Vbseff0; +double Vthfd ,dVthfd_dVd ,dVthfd_dVe, dVthfd_dT; +double Vbs0mos ,dVbs0mos_dVe, dVbs0mos_dT; +double Vbsmos ,dVbsmos_dVg ,dVbsmos_dVb ,dVbsmos_dVd, dVbsmos_dVe, dVbsmos_dT; +double Abeff ,dAbeff_dVg ,dAbeff_dVb, dAbeff_dVc; +double Vcs ,dVcs_dVg ,dVcs_dVb ,dVcs_dVd ,dVcs_dVe, dVcs_dT; +double Xcsat ,dXcsat_dVg ,dXcsat_dVb, dXcsat_dVc; +double Vdsatii ,dVdsatii_dVg ,dVdsatii_dVd, dVdsatii_dVb, dVdsatii_dT; +double Vdseffii ,dVdseffii_dVg ,dVdseffii_dVd, dVdseffii_dVb, dVdseffii_dT; +double VcsCV ,dVcsCV_dVg ,dVcsCV_dVb ,dVcsCV_dVd ,dVcsCV_dVc ,dVcsCV_dVe; +double VdsCV ,dVdsCV_dVg ,dVdsCV_dVb ,dVdsCV_dVd ,dVdsCV_dVc; +double Phisc ,dPhisc_dVg ,dPhisc_dVb ,dPhisc_dVd, dPhisc_dVc; +double Phisd ,dPhisd_dVg ,dPhisd_dVb ,dPhisd_dVd, dPhisd_dVc; +double sqrtPhisc ,dsqrtPhisc_dVg ,dsqrtPhisc_dVb; +double sqrtPhisd ,dsqrtPhisd_dVg ,dsqrtPhisd_dVb; +double Xc ,dXc_dVg ,dXc_dVb ,dXc_dVd ,dXc_dVc; +double Ibjt ,dIbjt_dVb ,dIbjt_dVd ,dIbjt_dT; +double Ibs1 ,dIbs1_dVb ,dIbs1_dT; +double Ibs2 ,dIbs2_dVb ,dIbs2_dT; +double Ibs3 ,dIbs3_dVb ,dIbs3_dVd, dIbs3_dT; +double Ibs4 ,dIbs4_dVb ,dIbs4_dT; +double Ibd1 ,dIbd1_dVb ,dIbd1_dVd ,dIbd1_dT; +double Ibd2 ,dIbd2_dVb ,dIbd2_dVd ,dIbd2_dT; +double Ibd3 ,dIbd3_dVb ,dIbd3_dVd ,dIbd3_dT; +double Ibd4 ,dIbd4_dVb ,dIbd4_dVd ,dIbd4_dT; +double ExpVbs1, dExpVbs1_dVb, dExpVbs1_dT; +double ExpVbs2, dExpVbs2_dVb, dExpVbs2_dT; +double ExpVbs4, dExpVbs4_dVb, dExpVbs4_dT; +double ExpVbd1, dExpVbd1_dVb, dExpVbd1_dT; +double ExpVbd2, dExpVbd2_dVb, dExpVbd2_dT; +double ExpVbd4, dExpVbd4_dVb, dExpVbd4_dT; +double WTsi, NVtm1, NVtm2; +double Ic ,dIc_dVb ,dIc_dVd; +double Ibs ,dIbs_dVb ,dIbs_dVd ,dIbs_dVe; +double Ibd ,dIbd_dVb; +double Nomi ,dNomi_dVg ,dNomi_dVb ,dNomi_dVd ,dNomi_dVc; +double Denomi ,dDenomi_dVg ,dDenomi_dVd ,dDenomi_dVb ,dDenomi_dVc, dDenomi_dT; +double Qbf ,dQbf_dVg ,dQbf_dVb ,dQbf_dVd ,dQbf_dVc ,dQbf_dVe; +double Qsubs1 ,dQsubs1_dVg ,dQsubs1_dVb ,dQsubs1_dVd ,dQsubs1_dVc ,dQsubs1_dVe; +double Qsubs2 ,dQsubs2_dVg ,dQsubs2_dVb ,dQsubs2_dVd ,dQsubs2_dVc ,dQsubs2_dVe; +double Qsub0 ,dQsub0_dVg ,dQsub0_dVb ,dQsub0_dVd ; +double Qac0 ,dQac0_dVb ,dQac0_dVd; +double Qdep0 ,dQdep0_dVb; +double Qe1 , dQe1_dVg ,dQe1_dVb, dQe1_dVd, dQe1_dVe, dQe1_dT; +double Ce1g ,Ce1b ,Ce1d ,Ce1e, Ce1T; +double Ce2g ,Ce2b ,Ce2d ,Ce2e, Ce2T; +double Qe2 , dQe2_dVg ,dQe2_dVb, dQe2_dVd, dQe2_dVe, dQe2_dT; +double dQbf_dVrg, dQac0_dVrg, dQsub0_dVrg; +double dQsubs1_dVrg, dQsubs2_dVrg, dQbf0_dVe, dQbf0_dT; + +/* for self-heating */ +double vbi, vfbb, phi, sqrtPhi, Xdep0, jbjt, jdif, jrec, jtun, u0temp, vsattemp; +double rds0, ua, ub, uc; +double dvbi_dT, dvfbb_dT, djbjt_dT, djdif_dT, djrec_dT, djtun_dT, du0temp_dT; +double dvsattemp_dT, drds0_dT, dua_dT, dub_dT, duc_dT, dni_dT, dVtm_dT; +double dVfbeff_dT, dQac0_dT, dQsub0_dT, dQbf_dT, dVdsCV_dT, dPhisd_dT; +double dNomi_dT,dXc_dT,dQsubs1_dT,dQsubs2_dT, dVcsCV_dT, dPhisc_dT, dQsicv_dT; +double CbT, CsT, CgT, CeT; + +double Qex, dQex_dVg, dQex_dVb, dQex_dVd, dQex_dVe, dQex_dT; + +/* clean up last */ +FILE *fpdebug; +/* end clean up */ +int nandetect; +static int nanfound = 0; +char nanmessage [12]; + + + +for (; model != NULL; model = model->B3SOIFDnextModel) +{ for (here = model->B3SOIFDinstances; here != NULL; + here = here->B3SOIFDnextInstance) + { Check = 0; + ByPass = 0; + selfheat = (model->B3SOIFDshMod == 1) && (here->B3SOIFDrth0 != 0.0); + pParam = here->pParam; + + if (here->B3SOIFDdebugMod > 3) + { + if (model->B3SOIFDtype > 0) + fpdebug = fopen("b3soifdn.log", "a"); + else + fpdebug = fopen("b3soifdp.log", "a"); + + fprintf(fpdebug, "******* Time : %.5e ******* Device: %s Iteration: %d\n", + ckt->CKTtime, here->B3SOIFDname, here->B3SOIFDiterations); + } + + if ((ckt->CKTmode & MODEINITSMSIG)) + { vbs = *(ckt->CKTstate0 + here->B3SOIFDvbs); + vgs = *(ckt->CKTstate0 + here->B3SOIFDvgs); + ves = *(ckt->CKTstate0 + here->B3SOIFDves); + vps = *(ckt->CKTstate0 + here->B3SOIFDvps); + vds = *(ckt->CKTstate0 + here->B3SOIFDvds); + delTemp = *(ckt->CKTstate0 + here->B3SOIFDdeltemp); + + vg = *(ckt->CKTrhsOld + here->B3SOIFDgNode); + vd = *(ckt->CKTrhsOld + here->B3SOIFDdNodePrime); + vs = *(ckt->CKTrhsOld + here->B3SOIFDsNodePrime); + vp = *(ckt->CKTrhsOld + here->B3SOIFDpNode); + ve = *(ckt->CKTrhsOld + here->B3SOIFDeNode); + vb = *(ckt->CKTrhsOld + here->B3SOIFDbNode); + + if (here->B3SOIFDdebugMod > 2) + { + fprintf(fpdebug, "... INIT SMSIG ...\n"); + } + if (here->B3SOIFDdebugMod > 0) + { + fprintf(stderr,"DC op. point converge with %d iterations\n"); + } + } + else if ((ckt->CKTmode & MODEINITTRAN)) + { vbs = *(ckt->CKTstate1 + here->B3SOIFDvbs); + vgs = *(ckt->CKTstate1 + here->B3SOIFDvgs); + ves = *(ckt->CKTstate1 + here->B3SOIFDves); + vps = *(ckt->CKTstate1 + here->B3SOIFDvps); + vds = *(ckt->CKTstate1 + here->B3SOIFDvds); + delTemp = *(ckt->CKTstate1 + here->B3SOIFDdeltemp); + + vg = *(ckt->CKTrhsOld + here->B3SOIFDgNode); + vd = *(ckt->CKTrhsOld + here->B3SOIFDdNodePrime); + vs = *(ckt->CKTrhsOld + here->B3SOIFDsNodePrime); + vp = *(ckt->CKTrhsOld + here->B3SOIFDpNode); + ve = *(ckt->CKTrhsOld + here->B3SOIFDeNode); + vb = *(ckt->CKTrhsOld + here->B3SOIFDbNode); + + if (here->B3SOIFDdebugMod > 2) + { + fprintf(fpdebug, "... Init Transient ....\n"); + } + if (here->B3SOIFDdebugMod > 0) + { + fprintf(stderr, "Transient operation point converge with %d iterations\n", +here->B3SOIFDiterations); + } + here->B3SOIFDiterations = 0; + } + else if ((ckt->CKTmode & MODEINITJCT) && !here->B3SOIFDoff) + { vds = model->B3SOIFDtype * here->B3SOIFDicVDS; + vgs = model->B3SOIFDtype * here->B3SOIFDicVGS; + ves = model->B3SOIFDtype * here->B3SOIFDicVES; + vbs = model->B3SOIFDtype * here->B3SOIFDicVBS; + vps = model->B3SOIFDtype * here->B3SOIFDicVPS; + + vg = vd = vs = vp = ve = 0.0; + + here->B3SOIFDiterations = 0; /* initialize iteration number */ + + delTemp = 0.0; + here->B3SOIFDphi = pParam->B3SOIFDphi; + + + if (here->B3SOIFDdebugMod > 2) + fprintf(fpdebug, "... INIT JCT ...\n"); + + if ((vds == 0.0) && (vgs == 0.0) && (vbs == 0.0) && + ((ckt->CKTmode & (MODETRAN | MODEAC|MODEDCOP | + MODEDCTRANCURVE)) || (!(ckt->CKTmode & MODEUIC)))) + { vbs = 0.0; + vgs = model->B3SOIFDtype*0.1 + pParam->B3SOIFDvth0; + vds = 0.0; + ves = 0.0; + vps = 0.0; + } + } + else if ((ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) && + (here->B3SOIFDoff)) + { delTemp = vps = vbs = vgs = vds = ves = 0.0; + vg = vd = vs = vp = ve = 0.0; + here->B3SOIFDiterations = 0; /* initialize iteration number */ + } + else + { +#ifndef PREDICTOR + if ((ckt->CKTmode & MODEINITPRED)) + { xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1]; + *(ckt->CKTstate0 + here->B3SOIFDvbs) = + *(ckt->CKTstate1 + here->B3SOIFDvbs); + vbs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIFDvbs)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIFDvbs))); + *(ckt->CKTstate0 + here->B3SOIFDvgs) = + *(ckt->CKTstate1 + here->B3SOIFDvgs); + vgs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIFDvgs)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIFDvgs))); + *(ckt->CKTstate0 + here->B3SOIFDves) = + *(ckt->CKTstate1 + here->B3SOIFDves); + ves = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIFDves)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIFDves))); + *(ckt->CKTstate0 + here->B3SOIFDvps) = + *(ckt->CKTstate1 + here->B3SOIFDvps); + vps = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIFDvps)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIFDvps))); + *(ckt->CKTstate0 + here->B3SOIFDvds) = + *(ckt->CKTstate1 + here->B3SOIFDvds); + vds = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIFDvds)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIFDvds))); + *(ckt->CKTstate0 + here->B3SOIFDvbd) = + *(ckt->CKTstate0 + here->B3SOIFDvbs) + - *(ckt->CKTstate0 + here->B3SOIFDvds); + + *(ckt->CKTstate0 + here->B3SOIFDvg) = *(ckt->CKTstate1 + here->B3SOIFDvg); + *(ckt->CKTstate0 + here->B3SOIFDvd) = *(ckt->CKTstate1 + here->B3SOIFDvd); + *(ckt->CKTstate0 + here->B3SOIFDvs) = *(ckt->CKTstate1 + here->B3SOIFDvs); + *(ckt->CKTstate0 + here->B3SOIFDvp) = *(ckt->CKTstate1 + here->B3SOIFDvp); + *(ckt->CKTstate0 + here->B3SOIFDve) = *(ckt->CKTstate1 + here->B3SOIFDve); + + /* Only predict ve */ + ve = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIFDve)) + + - (xfact * (*(ckt->CKTstate2 + here->B3SOIFDve))); + /* Then update vg, vs, vb, vd, vp base on ve */ + vs = ve - model->B3SOIFDtype * ves; + vg = model->B3SOIFDtype * vgs + vs; + vd = model->B3SOIFDtype * vds + vs; + vb = model->B3SOIFDtype * vbs + vs; + vp = model->B3SOIFDtype * vps + vs; + + delTemp = (1.0 + xfact)* (*(ckt->CKTstate1 + + here->B3SOIFDdeltemp))-(xfact * (*(ckt->CKTstate2 + + here->B3SOIFDdeltemp))); + + if (selfheat) + { + here->B3SOIFDphi = 2.0 * here->B3SOIFDvtm + * log (pParam->B3SOIFDnpeak / + here->B3SOIFDni); + } + + if (here->B3SOIFDdebugMod > 0) + { + fprintf(stderr, "Time = %.6e converge with %d iterations\n", ckt->CKTtime, here->B3SOIFDiterations); + } + if (here->B3SOIFDdebugMod > 2) + { + fprintf(fpdebug, "... PREDICTOR calculation ....\n"); + } + here->B3SOIFDiterations = 0; + } + else + { +#endif /* PREDICTOR */ + + vg = B3SOIFDlimit(*(ckt->CKTrhsOld + here->B3SOIFDgNode), + *(ckt->CKTstate0 + here->B3SOIFDvg), 3.0, &Check); + vd = B3SOIFDlimit(*(ckt->CKTrhsOld + here->B3SOIFDdNodePrime), + *(ckt->CKTstate0 + here->B3SOIFDvd), 3.0, &Check); + vs = B3SOIFDlimit(*(ckt->CKTrhsOld + here->B3SOIFDsNodePrime), + *(ckt->CKTstate0 + here->B3SOIFDvs), 3.0, &Check); + vp = B3SOIFDlimit(*(ckt->CKTrhsOld + here->B3SOIFDpNode), + *(ckt->CKTstate0 + here->B3SOIFDvp), 3.0, &Check); + ve = B3SOIFDlimit(*(ckt->CKTrhsOld + here->B3SOIFDeNode), + *(ckt->CKTstate0 + here->B3SOIFDve), 3.0, &Check); + delTemp = *(ckt->CKTrhsOld + here->B3SOIFDtempNode); + + vbs = model->B3SOIFDtype * (*(ckt->CKTrhsOld+here->B3SOIFDbNode) + - *(ckt->CKTrhsOld+here->B3SOIFDsNodePrime)); + + vps = model->B3SOIFDtype * (vp - vs); + vgs = model->B3SOIFDtype * (vg - vs); + ves = model->B3SOIFDtype * (ve - vs); + vds = model->B3SOIFDtype * (vd - vs); + + if (here->B3SOIFDdebugMod > 2) + { + fprintf(fpdebug, "... DC calculation ....\n"); +fprintf(fpdebug, "Vg = %.10f; Vb = %.10f; Vs = %.10f\n", + *(ckt->CKTrhsOld + here->B3SOIFDgNode), + *(ckt->CKTrhsOld + here->B3SOIFDbNode), + *(ckt->CKTrhsOld + here->B3SOIFDsNode)); +fprintf(fpdebug, "Vd = %.10f; Vsp = %.10f; Vdp = %.10f\n", + *(ckt->CKTrhsOld + here->B3SOIFDdNode), + *(ckt->CKTrhsOld + here->B3SOIFDsNodePrime), + *(ckt->CKTrhsOld + here->B3SOIFDdNodePrime)); +fprintf(fpdebug, "Ve = %.10f; Vp = %.10f; delTemp = %.10f\n", + *(ckt->CKTrhsOld + here->B3SOIFDeNode), + *(ckt->CKTrhsOld + here->B3SOIFDpNode), + *(ckt->CKTrhsOld + here->B3SOIFDtempNode)); + + } + +#ifndef PREDICTOR + } +#endif /* PREDICTOR */ + + vbd = vbs - vds; + vgd = vgs - vds; + ved = ves - vds; + vgdo = *(ckt->CKTstate0 + here->B3SOIFDvgs) + - *(ckt->CKTstate0 + here->B3SOIFDvds); + vedo = *(ckt->CKTstate0 + here->B3SOIFDves) + - *(ckt->CKTstate0 + here->B3SOIFDvds); + delvbs = vbs - *(ckt->CKTstate0 + here->B3SOIFDvbs); + delvbd = vbd - *(ckt->CKTstate0 + here->B3SOIFDvbd); + delvgs = vgs - *(ckt->CKTstate0 + here->B3SOIFDvgs); + delves = ves - *(ckt->CKTstate0 + here->B3SOIFDves); + delvps = vps - *(ckt->CKTstate0 + here->B3SOIFDvps); + deldelTemp = delTemp - *(ckt->CKTstate0 + here->B3SOIFDdeltemp); + delvds = vds - *(ckt->CKTstate0 + here->B3SOIFDvds); + delvgd = vgd - vgdo; + delved = ved - vedo; + + if (here->B3SOIFDmode >= 0) + { + cdhat = here->B3SOIFDcd + (here->B3SOIFDgm-here->B3SOIFDgjdg) * delvgs + + (here->B3SOIFDgds - here->B3SOIFDgjdd) * delvds + + (here->B3SOIFDgmbs - here->B3SOIFDgjdb) * delvbs + + (here->B3SOIFDgme - here->B3SOIFDgjde) * delves + + (here->B3SOIFDgmT - here->B3SOIFDgjdT) * deldelTemp; + } + else + { + cdhat = here->B3SOIFDcd + (here->B3SOIFDgm-here->B3SOIFDgjdg) * delvgd + - (here->B3SOIFDgds - here->B3SOIFDgjdd) * delvds + + (here->B3SOIFDgmbs - here->B3SOIFDgjdb) * delvbd + + (here->B3SOIFDgme - here->B3SOIFDgjde) * delved + + (here->B3SOIFDgmT - here->B3SOIFDgjdT) * deldelTemp; + + } + cbhat = here->B3SOIFDcb + here->B3SOIFDgbgs * delvgs + + here->B3SOIFDgbbs * delvbs + here->B3SOIFDgbds * delvds + + here->B3SOIFDgbes * delves + here->B3SOIFDgbps * delvps + + here->B3SOIFDgbT * deldelTemp; + +#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 + */ + + if (here->B3SOIFDdebugMod > 3) + { +fprintf(fpdebug, "Convergent Criteria : vbs %d vds %d vgs %d ves %d vps %d temp %d\n", + ((fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs), + fabs(*(ckt->CKTstate0+here->B3SOIFDvbs))) + ckt->CKTvoltTol))) ? 1 : 0, + ((fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), + fabs(*(ckt->CKTstate0+here->B3SOIFDvds))) + ckt->CKTvoltTol))) ? 1 : 0, + ((fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs), + fabs(*(ckt->CKTstate0+here->B3SOIFDvgs))) + ckt->CKTvoltTol))) ? 1 : 0, + ((fabs(delves) < (ckt->CKTreltol * MAX(fabs(ves), + fabs(*(ckt->CKTstate0+here->B3SOIFDves))) + ckt->CKTvoltTol))) ? 1 : 0, + ((fabs(delvps) < (ckt->CKTreltol * MAX(fabs(vps), + fabs(*(ckt->CKTstate0+here->B3SOIFDvps))) + ckt->CKTvoltTol))) ? 1 : 0, + ((fabs(deldelTemp) < (ckt->CKTreltol * MAX(fabs(delTemp), + fabs(*(ckt->CKTstate0+here->B3SOIFDdeltemp))) + ckt->CKTvoltTol*1e4))) ? 1 : 0); +fprintf(fpdebug, "delCd %.4e, delCb %.4e\n", fabs(cdhat - here->B3SOIFDcd) , + fabs(cbhat - here->B3SOIFDcb)); + + } + if ((!(ckt->CKTmode & MODEINITPRED)) && (ckt->CKTbypass) && Check == 0) + if ((fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs), + fabs(*(ckt->CKTstate0+here->B3SOIFDvbs))) + ckt->CKTvoltTol)) ) + if ((fabs(delvbd) < (ckt->CKTreltol * MAX(fabs(vbd), + fabs(*(ckt->CKTstate0+here->B3SOIFDvbd))) + ckt->CKTvoltTol)) ) + if ((fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs), + fabs(*(ckt->CKTstate0+here->B3SOIFDvgs))) + ckt->CKTvoltTol))) + if ((fabs(delves) < (ckt->CKTreltol * MAX(fabs(ves), + fabs(*(ckt->CKTstate0+here->B3SOIFDves))) + ckt->CKTvoltTol))) + if ( (here->B3SOIFDbodyMod == 0) || (here->B3SOIFDbodyMod == 2) || + (fabs(delvps) < (ckt->CKTreltol * MAX(fabs(vps), + fabs(*(ckt->CKTstate0+here->B3SOIFDvps))) + ckt->CKTvoltTol)) ) + if ( (here->B3SOIFDtempNode == 0) || + (fabs(deldelTemp) < (ckt->CKTreltol * MAX(fabs(delTemp), + fabs(*(ckt->CKTstate0+here->B3SOIFDdeltemp))) + + ckt->CKTvoltTol*1e4))) + if ((fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), + fabs(*(ckt->CKTstate0+here->B3SOIFDvds))) + ckt->CKTvoltTol))) + if ((fabs(cdhat - here->B3SOIFDcd) < ckt->CKTreltol + * MAX(fabs(cdhat),fabs(here->B3SOIFDcd)) + ckt->CKTabstol)) + if ((fabs(cbhat - here->B3SOIFDcb) < ckt->CKTreltol + * MAX(fabs(cbhat),fabs(here->B3SOIFDcb)) + ckt->CKTabstol) ) + { /* bypass code */ + vbs = *(ckt->CKTstate0 + here->B3SOIFDvbs); + vbd = *(ckt->CKTstate0 + here->B3SOIFDvbd); + vgs = *(ckt->CKTstate0 + here->B3SOIFDvgs); + ves = *(ckt->CKTstate0 + here->B3SOIFDves); + vps = *(ckt->CKTstate0 + here->B3SOIFDvps); + vds = *(ckt->CKTstate0 + here->B3SOIFDvds); + delTemp = *(ckt->CKTstate0 + here->B3SOIFDdeltemp); + + /* calculate Vds for temperature conductance calculation + in bypass (used later when filling Temp node matrix) */ + Vds = here->B3SOIFDmode > 0 ? vds : -vds; + + vgd = vgs - vds; + vgb = vgs - vbs; + veb = ves - vbs; + + if (here->B3SOIFDdebugMod > 2) + { +fprintf(stderr, "Bypass for %s...\n", here->B3SOIFDname); + fprintf(fpdebug, "... By pass ....\n"); + fprintf(fpdebug, "vgs=%.4f, vds=%.4f, vbs=%.4f, ", + vgs, vds, vbs); + fprintf(fpdebug, "ves=%.4f, vps=%.4f\n", ves, vps); + } + if ((ckt->CKTmode & (MODETRAN | MODEAC)) || + ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) + { ByPass = 1; + goto line755; + } + else + { goto line850; + } + } + + +#endif /*NOBYPASS*/ + von = here->B3SOIFDvon; + + if ((here->B3SOIFDdebugMod > 1) || (here->B3SOIFDdebugMod == -1)) + { + here->B3SOIFDdum1 = here->B3SOIFDdum2 = here->B3SOIFDdum3 = 0.0; + here->B3SOIFDdum4 = here->B3SOIFDdum5 = 0.0; + Qac0 = Qsub0 = Qsubs1 = Qsubs2 = Qbf = Qe1 = Qe2 = 0.0; + qjs = qjd = Cbg = Cbb = Cbd = Cbe = Xc = qdrn = qgate = 0.0; + qbody = qsub = 0.0; + } + + if (here->B3SOIFDdebugMod > 2) { + fprintf(fpdebug, "Limited : vgs = %.8f\n", vgs); + fprintf(fpdebug, "Limited : vds = %.8f\n", vds); + } + + if (*(ckt->CKTstate0 + here->B3SOIFDvds) >= 0.0) + T0 = *(ckt->CKTstate0 + here->B3SOIFDvbs); + else + T0 = *(ckt->CKTstate0 + here->B3SOIFDvbd); + + if (here->B3SOIFDdebugMod > 2) + fprintf(fpdebug, "Before lim : vbs = %.8f, after = ", T0); + + if (vds >= 0.0) + { + vbs = B3SOIFDlimit(vbs, T0, 0.2, &Check); + vbs = B3SOIFDSmartVbs(vbs, T0, here, ckt, &Check); + vbd = vbs - vds; + vb = model->B3SOIFDtype * vbs + vs; + if (here->B3SOIFDdebugMod > 2) + fprintf(fpdebug, "%.8f\n", vbs); + } else + { + vbd = B3SOIFDlimit(vbd, T0, 0.2, &Check); + vbd = B3SOIFDSmartVbs(vbd, T0, here, ckt, &Check); + vbs = vbd + vds; + vb = model->B3SOIFDtype * vbs + vd; + if (here->B3SOIFDdebugMod > 2) + fprintf(fpdebug, "%.8f\n", vbd); + } + + delTemp =B3SOIFDlimit(delTemp, *(ckt->CKTstate0 + here->B3SOIFDdeltemp),5.0,&Check); + + } + +/* Calculate temperature dependent values for self-heating effect */ + Temp = delTemp + ckt->CKTtemp; +/* for debugging + Temp = ckt->CKTtemp; + selfheat = 1; + if (here->B3SOIFDname[1] == '2') + { + Temp += 0.01; + } */ + TempRatio = Temp / model->B3SOIFDtnom; + + if (selfheat) { + Vtm = KboQ * Temp; + + T0 = 1108.0 + Temp; + T5 = Temp * Temp; + Eg = 1.16 - 7.02e-4 * T5 / T0; + T1 = ((7.02e-4 * T5) - T0 * (14.04e-4 * Temp)) / T0 / T0; + /* T1 = dEg / dT */ + + T2 = 1.9230584e-4; /* T2 = 1 / 300.15^(3/2) */ + T5 = sqrt(Temp); + T3 = 1.45e10 * Temp * T5 * T2; + T4 = exp(21.5565981 - Eg / (2.0 * Vtm)); + ni = T3 * T4; + dni_dT = 2.175e10 * T2 * T5 * T4 + T3 * T4 * + (-Vtm * T1 + Eg * KboQ) / (2.0 * Vtm * Vtm); + + T0 = log(1.0e20 * pParam->B3SOIFDnpeak / (ni * ni)); + vbi = Vtm * T0; + dvbi_dT = KboQ * T0 + Vtm * (-2.0 * dni_dT / ni); + + if (pParam->B3SOIFDnsub > 0) { + T0 = log(pParam->B3SOIFDnpeak / pParam->B3SOIFDnsub); + vfbb = -model->B3SOIFDtype * Vtm*T0; + dvfbb_dT = -model->B3SOIFDtype * KboQ*T0; + } + else { + T0 = log(-pParam->B3SOIFDnpeak*pParam->B3SOIFDnsub/ni/ni); + vfbb = -model->B3SOIFDtype * Vtm*T0; + dvfbb_dT = -model->B3SOIFDtype * + (KboQ * T0 + Vtm * 2.0 * dni_dT / ni); + } + +/* phi = 2.0 * Vtm * log(pParam->B3SOIFDnpeak / ni); */ + phi = here->B3SOIFDphi; + sqrtPhi = sqrt(phi); + Xdep0 = sqrt(2.0 * EPSSI / (Charge_q + * pParam->B3SOIFDnpeak * 1.0e6)) + * sqrtPhi; + /* Save the values below for phi calculation in B3SOIFDaccept() */ + here->B3SOIFDvtm = Vtm; + here->B3SOIFDni = ni; + + /* Use dTx_dVe variables to act as dTx_dT variables */ + + T8 = 1 / model->B3SOIFDtnom; + T7 = model->B3SOIFDxbjt / pParam->B3SOIFDndiode; + T0 = pow(TempRatio, T7); + dT0_dVe = T7 * pow(TempRatio, T7 - 1.0) * T8; + + T7 = model->B3SOIFDxdif / pParam->B3SOIFDndiode; + T1 = pow(TempRatio, T7); + dT1_dVe = T7 * pow(TempRatio, T7 - 1.0) * T8; + + T7 = model->B3SOIFDxrec / pParam->B3SOIFDndiode / 2.0; + T2 = pow(TempRatio, T7); + dT2_dVe = T7 * pow(TempRatio, T7 - 1.0) * T8; + + T3 = TempRatio - 1.0; + T4 = Eg300 / pParam->B3SOIFDndiode / Vtm * T3; + dT4_dVe = Eg300 / pParam->B3SOIFDndiode / Vtm / Vtm * + (Vtm * T8 - T3 * KboQ); + T5 = exp(T4); + dT5_dVe = dT4_dVe * T5; + T6 = sqrt(T5); + dT6_dVe = 0.5 / T6 * dT5_dVe; + + jbjt = pParam->B3SOIFDisbjt * T0 * T5; + jdif = pParam->B3SOIFDisdif * T1 * T5; + jrec = pParam->B3SOIFDisrec * T2 * T6; + djbjt_dT = pParam->B3SOIFDisbjt * (T0 * dT5_dVe + T5 * dT0_dVe); + djdif_dT = pParam->B3SOIFDisdif * (T1 * dT5_dVe + T5 * dT1_dVe); + djrec_dT = pParam->B3SOIFDisrec * (T2 * dT6_dVe + T6 * dT2_dVe); + + T7 = model->B3SOIFDxtun / pParam->B3SOIFDntun; + T0 = pow(TempRatio, T7); + jtun = pParam->B3SOIFDistun * T0; + djtun_dT = pParam->B3SOIFDistun * T7 * pow(TempRatio, T7 - 1.0) * T8; + + u0temp = pParam->B3SOIFDu0 * pow(TempRatio, pParam->B3SOIFDute); + du0temp_dT = pParam->B3SOIFDu0 * pParam->B3SOIFDute * + pow(TempRatio, pParam->B3SOIFDute - 1.0) * T8; + + vsattemp = pParam->B3SOIFDvsat - pParam->B3SOIFDat * T3; + dvsattemp_dT = -pParam->B3SOIFDat * T8; + + rds0 = (pParam->B3SOIFDrdsw + pParam->B3SOIFDprt + * T3) / pParam->B3SOIFDrds0denom; + drds0_dT = pParam->B3SOIFDprt / pParam->B3SOIFDrds0denom * T8; + + ua = pParam->B3SOIFDuatemp + pParam->B3SOIFDua1 * T3; + ub = pParam->B3SOIFDubtemp + pParam->B3SOIFDub1 * T3; + uc = pParam->B3SOIFDuctemp + pParam->B3SOIFDuc1 * T3; + dua_dT = pParam->B3SOIFDua1 * T8; + dub_dT = pParam->B3SOIFDub1 * T8; + duc_dT = pParam->B3SOIFDuc1 * T8; + } + else { + vbi = pParam->B3SOIFDvbi; + vfbb = pParam->B3SOIFDvfbb; + phi = pParam->B3SOIFDphi; + sqrtPhi = pParam->B3SOIFDsqrtPhi; + Xdep0 = pParam->B3SOIFDXdep0; + jbjt = pParam->B3SOIFDjbjt; + jdif = pParam->B3SOIFDjdif; + jrec = pParam->B3SOIFDjrec; + jtun = pParam->B3SOIFDjtun; + u0temp = pParam->B3SOIFDu0temp; + vsattemp = pParam->B3SOIFDvsattemp; + rds0 = pParam->B3SOIFDrds0; + ua = pParam->B3SOIFDua; + ub = pParam->B3SOIFDub; + uc = pParam->B3SOIFDuc; + dni_dT = dvbi_dT = dvfbb_dT = djbjt_dT = djdif_dT = 0.0; + djrec_dT = djtun_dT = du0temp_dT = dvsattemp_dT = 0.0; + drds0_dT = dua_dT = dub_dT = duc_dT = 0.0; + } + + /* TempRatio used for Vth and mobility */ + if (selfheat) { + TempRatio = Temp / model->B3SOIFDtnom - 1.0; + } + else { + TempRatio = ckt->CKTtemp / model->B3SOIFDtnom - 1.0; + } + + /* determine DC current and derivatives */ + vbd = vbs - vds; + vgd = vgs - vds; + vgb = vgs - vbs; + ved = ves - vds; + veb = ves - vbs; + vge = vgs - ves; + vpd = vps - vds; + + + if (vds >= 0.0) + { /* normal mode */ + here->B3SOIFDmode = 1; + Vds = vds; + Vgs = vgs; + Vbs = vbs; + Vbd = vbd; + Ves = ves; + Vps = vps; + } + else + { /* inverse mode */ + here->B3SOIFDmode = -1; + Vds = -vds; + Vgs = vgd; + Vbs = vbd; + Vbd = vbs; + Ves = ved; + Vps = vpd; + } + + + if (here->B3SOIFDdebugMod > 2) + { + fprintf(fpdebug, "Vgs=%.4f, Vds=%.4f, Vbs=%.4f, ", + Vgs, Vds, Vbs); + fprintf(fpdebug, "Ves=%.4f, Vps=%.4f, Temp=%.1f\n", + Ves, Vps, Temp); + } + + Vesfb = Ves - vfbb; + Cbox = model->B3SOIFDcbox; + K1 = pParam->B3SOIFDk1; + + ChargeComputationNeeded = + ((ckt->CKTmode & (MODEAC | MODETRAN | MODEINITSMSIG)) || + ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) + ? 1 : 0; + + if (here->B3SOIFDdebugMod == -1) + ChargeComputationNeeded = 1; + + + + +/* Poly Gate Si Depletion Effect */ + T0 = pParam->B3SOIFDvfb + phi; + if ((pParam->B3SOIFDngate > 1.e18) && (pParam->B3SOIFDngate < 1.e25) + && (Vgs > T0)) + /* added to avoid the problem caused by ngate */ + { T1 = 1.0e6 * Charge_q * EPSSI * pParam->B3SOIFDngate + / (model->B3SOIFDcox * model->B3SOIFDcox); + T4 = sqrt(1.0 + 2.0 * (Vgs - T0) / T1); + T2 = T1 * (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; + } + + + Leff = pParam->B3SOIFDleff; + + if (selfheat) { + Vtm = KboQ * Temp; + dVtm_dT = KboQ; + } + else { + Vtm = model->B3SOIFDvtm; + dVtm_dT = 0.0; + } + + V0 = vbi - phi; + +/* Prepare Vbs0t */ + T0 = -pParam->B3SOIFDdvbd1 * pParam->B3SOIFDleff / pParam->B3SOIFDlitl; + T1 = pParam->B3SOIFDdvbd0 * (exp(0.5*T0) + 2*exp(T0)); + T2 = T1 * (vbi - phi); + T3 = 0.5 * model->B3SOIFDqsi / model->B3SOIFDcsi; + Vbs0t = phi - T3 + pParam->B3SOIFDvbsa + T2; + if (selfheat) + dVbs0t_dT = T1 * dvbi_dT; + else + dVbs0t_dT = 0.0; + +/* Prepare Vbs0 */ + T0 = 1 + model->B3SOIFDcsieff / Cbox; + T1 = pParam->B3SOIFDkb1 / T0; + T2 = T1 * (Vbs0t - Vesfb); + + /* T6 is Vbs0 before limiting */ + T6 = Vbs0t - T2; + dT6_dVe = T1; + if (selfheat) + dT6_dT = dVbs0t_dT - T1 * (dVbs0t_dT + dvfbb_dT); + else + dT6_dT = 0.0; + + /* limit Vbs0 to below phi */ + T1 = phi - pParam->B3SOIFDdelp; + T2 = T1 - T6 - DELT_Vbseff; + T3 = sqrt(T2 * T2 + 4.0 * DELT_Vbseff); + Vbs0 = T1 - 0.5 * (T2 + T3); + T4 = 0.5 * (1 + T2/T3); + dVbs0_dVe = T4 * dT6_dVe; + if (selfheat) dVbs0_dT = T4 * dT6_dT; + else dVbs0_dT = 0.0; + + T1 = Vbs0t - Vbs0 - DELT_Vbsmos; + T2 = sqrt(T1 * T1 + DELT_Vbsmos * DELT_Vbsmos); + T3 = 0.5 * (T1 + T2); + T4 = T3 * model->B3SOIFDcsieff / model->B3SOIFDqsieff; + Vbs0mos = Vbs0 - 0.5 * T3 * T4; + T5 = 0.5 * T4 * (1 + T1 / T2); + dVbs0mos_dVe = dVbs0_dVe * (1 + T5); + if (selfheat) + dVbs0mos_dT = dVbs0_dT - (dVbs0t_dT - dVbs0_dT) * T5; + else + dVbs0mos_dT = 0.0; + +/* Prepare Vthfd - treat Vbs0mos as if it were independent variable Vb */ + Phis = phi - Vbs0mos; + dPhis_dVb = -1; + sqrtPhis = sqrt(Phis); + dsqrtPhis_dVb = -0.5 / sqrtPhis; + Xdep = Xdep0 * sqrtPhis / sqrtPhi; + dXdep_dVb = (Xdep0 / sqrtPhi) + * dsqrtPhis_dVb; + sqrtXdep = sqrt(Xdep); + + T0 = pParam->B3SOIFDdvt2 * Vbs0mos; + if (T0 >= - 0.5) + { T1 = 1.0 + T0; + T2 = pParam->B3SOIFDdvt2; + } + else /* Added to avoid any discontinuity problems caused by dvt2*/ + { T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = pParam->B3SOIFDdvt2 * T4 * T4; + } + lt1 = model->B3SOIFDfactor1 * sqrtXdep * T1; + dlt1_dVb = model->B3SOIFDfactor1 * (0.5 / sqrtXdep * T1 * dXdep_dVb + + sqrtXdep * T2); + + T0 = pParam->B3SOIFDdvt2w * Vbs0mos; + if (T0 >= - 0.5) + { T1 = 1.0 + T0; + T2 = pParam->B3SOIFDdvt2w; + } + else /* Added to avoid any discontinuity problems caused by + dvt2w */ + { T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = pParam->B3SOIFDdvt2w * T4 * T4; + } + ltw= model->B3SOIFDfactor1 * sqrtXdep * T1; + dltw_dVb = model->B3SOIFDfactor1 * (0.5 / sqrtXdep * T1 * dXdep_dVb + + sqrtXdep * T2); + + T0 = -0.5 * pParam->B3SOIFDdvt1 * Leff / lt1; + if (T0 > -EXP_THRESHOLD) + { T1 = exp(T0); + dT1_dVb = -T0 / lt1 * T1 * dlt1_dVb; + Theta0 = T1 * (1.0 + 2.0 * T1); + dTheta0_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { T1 = MIN_EXP; + Theta0 = T1 * (1.0 + 2.0 * T1); + dTheta0_dVb = 0.0; + } + here->B3SOIFDthetavth = pParam->B3SOIFDdvt0 * Theta0; + Delt_vth = here->B3SOIFDthetavth * V0; + dDelt_vth_dVb = pParam->B3SOIFDdvt0 * dTheta0_dVb * V0; + if (selfheat) dDelt_vth_dT = here->B3SOIFDthetavth * dvbi_dT; + else dDelt_vth_dT = 0.0; + + T0 = -0.5*pParam->B3SOIFDdvt1w * pParam->B3SOIFDweff*Leff/ltw; + if (T0 > -EXP_THRESHOLD) + { T1 = exp(T0); + T2 = T1 * (1.0 + 2.0 * T1); + dT1_dVb = -T0 / ltw * T1 * dltw_dVb; + dT2_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { T1 = MIN_EXP; + T2 = T1 * (1.0 + 2.0 * T1); + dT2_dVb = 0.0; + } + T0 = pParam->B3SOIFDdvt0w * T2; + DeltVthw = T0 * V0; + dDeltVthw_dVb = pParam->B3SOIFDdvt0w * dT2_dVb * V0; + if (selfheat) dDeltVthw_dT = T0 * dvbi_dT; + else dDeltVthw_dT = 0.0; + + T0 = sqrt(1.0 + pParam->B3SOIFDnlx / Leff); + T1 = (pParam->B3SOIFDkt1 + pParam->B3SOIFDkt1l / Leff + + pParam->B3SOIFDkt2 * Vbs0mos); + DeltVthtemp = pParam->B3SOIFDk1 * (T0 - 1.0) * sqrtPhi + T1 * TempRatio; + if (selfheat) dDeltVthtemp_dT = T1 / model->B3SOIFDtnom; + else dDeltVthtemp_dT = 0.0; + + tmp2 = model->B3SOIFDtox * phi + / (pParam->B3SOIFDweff + pParam->B3SOIFDw0); + + T3 = pParam->B3SOIFDeta0 + pParam->B3SOIFDetab * Vbs0mos; + if (T3 < 1.0e-4) /* avoid discontinuity problems caused by etab */ + { T9 = 1.0 / (3.0 - 2.0e4 * T3); + T3 = (2.0e-4 - T3) * T9; + T4 = T9 * T9 * pParam->B3SOIFDetab; + dT3_dVb = T4; + } + else + { + dT3_dVb = pParam->B3SOIFDetab; + } + DIBL_Sft = T3 * pParam->B3SOIFDtheta0vb0 * Vds; + dDIBL_Sft_dVd = T3 * pParam->B3SOIFDtheta0vb0; + dDIBL_Sft_dVb = pParam->B3SOIFDtheta0vb0 * Vds * dT3_dVb; + + Vthfd = model->B3SOIFDtype * pParam->B3SOIFDvth0 + pParam->B3SOIFDk1 + * (sqrtPhis - sqrtPhi) - pParam->B3SOIFDk2 + * Vbs0mos-Delt_vth-DeltVthw +(pParam->B3SOIFDk3 +pParam->B3SOIFDk3b + * Vbs0mos) * tmp2 + DeltVthtemp - DIBL_Sft; + + T6 = pParam->B3SOIFDk3b * tmp2 - pParam->B3SOIFDk2 + + pParam->B3SOIFDkt2 * TempRatio; + dVthfd_dVd = -dDIBL_Sft_dVd; + T7 = pParam->B3SOIFDk1 * dsqrtPhis_dVb + - dDelt_vth_dVb - dDeltVthw_dVb + + T6 - dDIBL_Sft_dVb; + dVthfd_dVe = T7 * dVbs0mos_dVe; + if (selfheat) + dVthfd_dT = dDeltVthtemp_dT - dDelt_vth_dT - dDeltVthw_dT + + T7 * dVbs0mos_dT; + else + dVthfd_dT = 0.0; + +/* Effective Vbs0 and Vbs0t for all Vgs */ + T1 = Vthfd - Vgs_eff - DELT_Vbs0eff; + T2 = sqrt(T1 * T1 + DELT_Vbs0eff * DELT_Vbs0eff ); + + Vbs0teff = Vbs0t - 0.5 * (T1 + T2); + dVbs0teff_dVg = 0.5 * (1 + T1/T2) * dVgs_eff_dVg; + dVbs0teff_dVd = - 0.5 * (1 + T1 / T2) * dVthfd_dVd; + dVbs0teff_dVe = - 0.5 * (1 + T1 / T2) * dVthfd_dVe; + if (selfheat) + dVbs0teff_dT = dVbs0t_dT - 0.5 * (1 + T1 / T2) * dVthfd_dT; + else + dVbs0teff_dT = 0.0; + + /* Calculate nfb */ + T3 = 1 / (K1 * K1); + T4 = pParam->B3SOIFDkb3 * Cbox / model->B3SOIFDcox; + T8 = sqrt(phi - Vbs0mos); + T5 = sqrt(1 + 4 * T3 * (phi + K1 * T8 - Vbs0mos)); + T6 = 1 + T4 * T5; + Nfb = model->B3SOIFDnfb = 1 / T6; + T7 = 2 * T3 * T4 * Nfb * Nfb / T5 * (0.5 * K1 / T8 + 1); + Vbs0eff = Vbs0 - Nfb * 0.5 * (T1 + T2); + dVbs0eff_dVg = Nfb * 0.5 * (1 + T1/T2) * dVgs_eff_dVg; + dVbs0eff_dVd = - Nfb * 0.5 * (1 + T1 / T2) * dVthfd_dVd; + dVbs0eff_dVe = dVbs0_dVe - Nfb * 0.5 * (1 + T1 / T2) + * dVthfd_dVe - T7 * 0.5 * (T1 + T2) * dVbs0mos_dVe; + if (selfheat) + dVbs0eff_dT = dVbs0_dT - Nfb * 0.5 * (1 + T1 / T2) + * dVthfd_dT - T7 * 0.5 * (T1 + T2) * dVbs0mos_dT; + else + dVbs0eff_dT = 0.0; + +/* Simple check of Vbs */ +/* Prepare Vbsdio */ + Vbs = Vbsdio = Vbs0eff; + dVbsdio_dVg = dVbs0eff_dVg; + dVbsdio_dVd = dVbs0eff_dVd; + dVbsdio_dVe = dVbs0eff_dVe; + dVbsdio_dT = dVbs0eff_dT; + dVbsdio_dVb = 0.0; + +/* Prepare Vbseff */ + T1 = Vbs0teff - Vbsdio - DELT_Vbsmos; + T2 = sqrt(T1 * T1 + DELT_Vbsmos * DELT_Vbsmos); + T3 = 0.5 * (T1 + T2); + T5 = 0.5 * (1 + T1/T2); + dT3_dVg = T5 * (dVbs0teff_dVg - dVbsdio_dVg); + dT3_dVd = T5 * (dVbs0teff_dVd - dVbsdio_dVd); + dT3_dVb = - T5 * dVbsdio_dVb; + dT3_dVe = T5 * (dVbs0teff_dVe - dVbsdio_dVe); + if (selfheat) dT3_dT = T5 * (dVbs0teff_dT - dVbsdio_dT); + else dT3_dT = 0.0; + T4 = T3 * model->B3SOIFDcsieff / model->B3SOIFDqsieff; + + Vbsmos = Vbsdio - 0.5 * T3 * T4; + dVbsmos_dVg = dVbsdio_dVg - T4 * dT3_dVg; + dVbsmos_dVd = dVbsdio_dVd - T4 * dT3_dVd; + dVbsmos_dVb = dVbsdio_dVb - T4 * dT3_dVb; + dVbsmos_dVe = dVbsdio_dVe - T4 * dT3_dVe; + if (selfheat) dVbsmos_dT = dVbsdio_dT - T4 * dT3_dT; + else dVbsmos_dT = 0.0; + +/* Prepare Vcs */ + Vcs = Vbsdio - Vbs0eff; + dVcs_dVb = dVbsdio_dVb; + dVcs_dVg = dVbsdio_dVg - dVbs0eff_dVg; + dVcs_dVd = dVbsdio_dVd - dVbs0eff_dVd; + dVcs_dVe = dVbsdio_dVe - dVbs0eff_dVe; + dVcs_dT = dVbsdio_dT - dVbs0eff_dT; + +/* Check Vps */ + /* Note : if Vps is less Vbs0eff => non-physical */ + T1 = Vps - Vbs0eff + DELT_Vbs0dio; + T2 = sqrt(T1 * T1 + DELT_Vbs0dio * DELT_Vbs0dio); + T3 = 0.5 * (1 + T1/T2); + Vpsdio = Vbs0eff + 0.5 * (T1 + T2); + dVpsdio_dVg = (1 - T3) * dVbs0eff_dVg; + dVpsdio_dVd = (1 - T3) * dVbs0eff_dVd; + dVpsdio_dVe = (1 - T3) * dVbs0eff_dVe; + if (selfheat) dVpsdio_dT = (1 - T3) * dVbs0eff_dT; + else dVpsdio_dT = 0.0; + dVpsdio_dVp = T3; + Vbp = Vbsdio - Vpsdio; + dVbp_dVb = dVbsdio_dVb; + dVbp_dVg = dVbsdio_dVg - dVpsdio_dVg; + dVbp_dVd = dVbsdio_dVd - dVpsdio_dVd; + dVbp_dVe = dVbsdio_dVe - dVpsdio_dVe; + dVbp_dT = dVbsdio_dT - dVpsdio_dT; + dVbp_dVp = - dVpsdio_dVp; + + here->B3SOIFDvbsdio = Vbsdio; + here->B3SOIFDvbs0eff = Vbs0eff; + + T1 = phi - pParam->B3SOIFDdelp; + T2 = T1 - Vbsmos - DELT_Vbseff; + T3 = sqrt(T2 * T2 + 4.0 * DELT_Vbseff * T1); + Vbseff = T1 - 0.5 * (T2 + T3); + T4 = 0.5 * (1 + T2/T3); + dVbseff_dVg = T4 * dVbsmos_dVg; + dVbseff_dVd = T4 * dVbsmos_dVd; + dVbseff_dVb = T4 * dVbsmos_dVb; + dVbseff_dVe = T4 * dVbsmos_dVe; + if (selfheat) dVbseff_dT = T4 * dVbsmos_dT; + else dVbseff_dT = 0.0; + + here->B3SOIFDvbseff = Vbseff; + + Phis = phi - Vbseff; + dPhis_dVb = -1; + sqrtPhis = sqrt(Phis); + dsqrtPhis_dVb = -0.5 / sqrtPhis ; + + Xdep = Xdep0 * sqrtPhis / sqrtPhi; + dXdep_dVb = (Xdep0 / sqrtPhi) + * dsqrtPhis_dVb; + +/* Vth Calculation */ + T3 = sqrt(Xdep); + + T0 = pParam->B3SOIFDdvt2 * Vbseff; + if (T0 >= - 0.5) + { T1 = 1.0 + T0; + T2 = pParam->B3SOIFDdvt2 ; + } + else /* Added to avoid any discontinuity problems caused by dvt2 */ + { T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = pParam->B3SOIFDdvt2 * T4 * T4 ; + } + lt1 = model->B3SOIFDfactor1 * T3 * T1; + dlt1_dVb =model->B3SOIFDfactor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2); + + T0 = pParam->B3SOIFDdvt2w * Vbseff; + if (T0 >= - 0.5) + { T1 = 1.0 + T0; + T2 = pParam->B3SOIFDdvt2w ; + } + else /* Added to avoid any discontinuity problems caused by dvt2w */ + { T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = pParam->B3SOIFDdvt2w * T4 * T4 ; + } + ltw= model->B3SOIFDfactor1 * T3 * T1; + dltw_dVb=model->B3SOIFDfactor1*(0.5 / T3 * T1 * dXdep_dVb + T3 * T2); + + T0 = -0.5 * pParam->B3SOIFDdvt1 * Leff / lt1; + if (T0 > -EXP_THRESHOLD) + { T1 = exp(T0); + Theta0 = T1 * (1.0 + 2.0 * T1); + dT1_dVb = -T0 / lt1 * T1 * dlt1_dVb; + dTheta0_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { T1 = MIN_EXP; + Theta0 = T1 * (1.0 + 2.0 * T1); + dTheta0_dVb = 0.0; + } + + here->B3SOIFDthetavth = pParam->B3SOIFDdvt0 * Theta0; + Delt_vth = here->B3SOIFDthetavth * V0; + dDelt_vth_dVb = pParam->B3SOIFDdvt0 * dTheta0_dVb * V0; + if (selfheat) dDelt_vth_dT = here->B3SOIFDthetavth * dvbi_dT; + else dDelt_vth_dT = 0.0; + + T0 = -0.5 * pParam->B3SOIFDdvt1w * pParam->B3SOIFDweff * Leff / ltw; + if (T0 > -EXP_THRESHOLD) + { T1 = exp(T0); + T2 = T1 * (1.0 + 2.0 * T1); + dT1_dVb = -T0 / ltw * T1 * dltw_dVb; + dT2_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { T1 = MIN_EXP; + T2 = T1 * (1.0 + 2.0 * T1); + dT2_dVb = 0.0; + } + + T0 = pParam->B3SOIFDdvt0w * T2; + DeltVthw = T0 * V0; + dDeltVthw_dVb = pParam->B3SOIFDdvt0w * dT2_dVb * V0; + if (selfheat) dDeltVthw_dT = T0 * dvbi_dT; + else dDeltVthw_dT = 0.0; + + T0 = sqrt(1.0 + pParam->B3SOIFDnlx / Leff); + T1 = (pParam->B3SOIFDkt1 + pParam->B3SOIFDkt1l / Leff + + pParam->B3SOIFDkt2 * Vbseff); + DeltVthtemp = pParam->B3SOIFDk1 * (T0 - 1.0) * sqrtPhi + T1 * TempRatio; + if (selfheat) + dDeltVthtemp_dT = T1 / model->B3SOIFDtnom; + else + dDeltVthtemp_dT = 0.0; + + tmp2 = model->B3SOIFDtox * phi + / (pParam->B3SOIFDweff + pParam->B3SOIFDw0); + + T3 = pParam->B3SOIFDeta0 + pParam->B3SOIFDetab * Vbseff; + if (T3 < 1.0e-4) /* avoid discontinuity problems caused by etab */ + { T9 = 1.0 / (3.0 - 2.0e4 * T3); + T3 = (2.0e-4 - T3) * T9; + T4 = T9 * T9 * pParam->B3SOIFDetab; + dT3_dVb = T4 ; + } + else + { + dT3_dVb = pParam->B3SOIFDetab ; + } + DIBL_Sft = T3 * pParam->B3SOIFDtheta0vb0 * Vds; + dDIBL_Sft_dVd = pParam->B3SOIFDtheta0vb0 * T3; + dDIBL_Sft_dVb = pParam->B3SOIFDtheta0vb0 * Vds * dT3_dVb; + + Vth = model->B3SOIFDtype * pParam->B3SOIFDvth0 + pParam->B3SOIFDk1 + * (sqrtPhis - sqrtPhi) - pParam->B3SOIFDk2 + * Vbseff- Delt_vth - DeltVthw +(pParam->B3SOIFDk3 + pParam->B3SOIFDk3b + * Vbseff) * tmp2 + DeltVthtemp - DIBL_Sft; + + here->B3SOIFDvon = Vth; + + T6 = pParam->B3SOIFDk3b * tmp2 - pParam->B3SOIFDk2 + + pParam->B3SOIFDkt2 * TempRatio; + dVth_dVb = pParam->B3SOIFDk1 * dsqrtPhis_dVb + - dDelt_vth_dVb - dDeltVthw_dVb + + T6 - dDIBL_Sft_dVb; /* this is actually dVth_dVbseff */ + dVth_dVd = -dDIBL_Sft_dVd; + if (selfheat) dVth_dT = dDeltVthtemp_dT - dDelt_vth_dT - dDeltVthw_dT; + else dVth_dT = 0.0; + +/* Calculate n */ + T2 = pParam->B3SOIFDnfactor * EPSSI / Xdep; + dT2_dVb = - T2 / Xdep * dXdep_dVb; + + T3 = pParam->B3SOIFDcdsc + pParam->B3SOIFDcdscb * Vbseff + + pParam->B3SOIFDcdscd * Vds; + dT3_dVb = pParam->B3SOIFDcdscb; + dT3_dVd = pParam->B3SOIFDcdscd; + + T4 = (T2 + T3 * Theta0 + pParam->B3SOIFDcit) / model->B3SOIFDcox; + dT4_dVb = (dT2_dVb + Theta0 * dT3_dVb + dTheta0_dVb * T3) + / model->B3SOIFDcox; + dT4_dVd = Theta0 * dT3_dVd / model->B3SOIFDcox; + + if (T4 >= -0.5) + { n = 1.0 + T4; + dn_dVb = dT4_dVb; + dn_dVd = dT4_dVd; + } + else + /* avoid discontinuity problems caused by T4 */ + { T0 = 1.0 / (3.0 + 8.0 * T4); + n = (1.0 + 3.0 * T4) * T0; + T0 *= T0; + dn_dVb = T0 * dT4_dVb; + dn_dVd = T0 * dT4_dVd; + } + +/* Effective Vgst (Vgsteff) Calculation */ + + Vgst = Vgs_eff - Vth; + + T10 = 2.0 * n * Vtm; + VgstNVt = Vgst / T10; + ExpArg = (2.0 * pParam->B3SOIFDvoff - Vgst) / T10; + + /* MCJ: Very small Vgst */ + if (VgstNVt > EXP_THRESHOLD) + { Vgsteff = Vgst; + /* T0 is dVgsteff_dVbseff */ + T0 = -dVth_dVb; + dVgsteff_dVg = dVgs_eff_dVg + T0 * dVbseff_dVg; + dVgsteff_dVd = -dVth_dVd + T0 * dVbseff_dVd; + dVgsteff_dVb = T0 * dVbseff_dVb; + dVgsteff_dVe = T0 * dVbseff_dVe; + if (selfheat) + dVgsteff_dT = -dVth_dT + T0 * dVbseff_dT; + else + dVgsteff_dT = 0.0; + } + else if (ExpArg > EXP_THRESHOLD) + { T0 = (Vgst - pParam->B3SOIFDvoff) / (n * Vtm); + ExpVgst = exp(T0); + Vgsteff = Vtm * pParam->B3SOIFDcdep0 / model->B3SOIFDcox * ExpVgst; + T3 = Vgsteff / (n * Vtm) ; + /* T1 is dVgsteff_dVbseff */ + T1 = -T3 * (dVth_dVb + T0 * Vtm * dn_dVb); + dVgsteff_dVg = T3 * dVgs_eff_dVg + T1 * dVbseff_dVg; + dVgsteff_dVd = -T3 * (dVth_dVd + T0 * Vtm * dn_dVd) + T1 * dVbseff_dVd; + dVgsteff_dVe = T1 * dVbseff_dVe; + dVgsteff_dVb = T1 * dVbseff_dVb; + if (selfheat) + dVgsteff_dT = -T3 * (dVth_dT + T0 * dVtm_dT * n) + + Vgsteff / Temp + T1 * dVbseff_dT; + else + dVgsteff_dT = 0.0; + } + else + { ExpVgst = exp(VgstNVt); + T1 = T10 * log(1.0 + ExpVgst); + dT1_dVg = ExpVgst / (1.0 + ExpVgst); + dT1_dVb = -dT1_dVg * (dVth_dVb + Vgst / n * dn_dVb) + + T1 / n * dn_dVb; + dT1_dVd = -dT1_dVg * (dVth_dVd + Vgst / n * dn_dVd) + + T1 / n * dn_dVd; + T3 = (1.0 / Temp); + if (selfheat) + dT1_dT = -dT1_dVg * (dVth_dT + Vgst * T3) + T1 * T3; + else + dT1_dT = 0.0; + + dT2_dVg = -model->B3SOIFDcox / (Vtm * pParam->B3SOIFDcdep0) + * exp(ExpArg); + T2 = 1.0 - T10 * dT2_dVg; + dT2_dVd = -dT2_dVg * (dVth_dVd - 2.0 * Vtm * ExpArg * dn_dVd) + + (T2 - 1.0) / n * dn_dVd; + dT2_dVb = -dT2_dVg * (dVth_dVb - 2.0 * Vtm * ExpArg * dn_dVb) + + (T2 - 1.0) / n * dn_dVb; + if (selfheat) + dT2_dT = -dT2_dVg * (dVth_dT - ExpArg * T10 * T3); + else + dT2_dT = 0.0; + + Vgsteff = T1 / T2; + T3 = T2 * T2; + /* T4 is dVgsteff_dVbseff */ + T4 = (T2 * dT1_dVb - T1 * dT2_dVb) / T3; + dVgsteff_dVb = T4 * dVbseff_dVb; + dVgsteff_dVe = T4 * dVbseff_dVe; + dVgsteff_dVg = (T2 * dT1_dVg - T1 * dT2_dVg) / T3 * dVgs_eff_dVg + + T4 * dVbseff_dVg; + dVgsteff_dVd = (T2 * dT1_dVd - T1 * dT2_dVd) / T3 + T4 * dVbseff_dVd; + if (selfheat) + dVgsteff_dT = (T2 * dT1_dT - T1 * dT2_dT) / T3 + T4 * dVbseff_dT; + else + dVgsteff_dT = 0.0; + } + Vgst2Vtm = Vgsteff + 2.0 * Vtm; + if (selfheat) dVgst2Vtm_dT = 2.0 * dVtm_dT; + else dVgst2Vtm_dT = 0.0; + +/* Calculate Effective Channel Geometry */ + T9 = sqrtPhis - sqrtPhi; + Weff = pParam->B3SOIFDweff - 2.0 * (pParam->B3SOIFDdwg * Vgsteff + + pParam->B3SOIFDdwb * T9); + dWeff_dVg = -2.0 * pParam->B3SOIFDdwg; + dWeff_dVb = -2.0 * pParam->B3SOIFDdwb * dsqrtPhis_dVb; + + if (Weff < 2.0e-8) /* to avoid the discontinuity problem due to Weff*/ + { T0 = 1.0 / (6.0e-8 - 2.0 * Weff); + Weff = 2.0e-8 * (4.0e-8 - Weff) * T0; + T0 *= T0 * 4.0e-16; + dWeff_dVg *= T0; + dWeff_dVb *= T0; + } + + T0 = pParam->B3SOIFDprwg * Vgsteff + pParam->B3SOIFDprwb * T9; + if (T0 >= -0.9) + { Rds = rds0 * (1.0 + T0); + dRds_dVg = rds0 * pParam->B3SOIFDprwg; + dRds_dVb = rds0 * pParam->B3SOIFDprwb * dsqrtPhis_dVb; + if (selfheat) dRds_dT = (1.0 + T0) * drds0_dT; + else dRds_dT = 0.0; + } + else + /* to avoid the discontinuity problem due to prwg and prwb*/ + { T1 = 1.0 / (17.0 + 20.0 * T0); + Rds = rds0 * (0.8 + T0) * T1; + T1 *= T1; + dRds_dVg = rds0 * pParam->B3SOIFDprwg * T1; + dRds_dVb = rds0 * pParam->B3SOIFDprwb * dsqrtPhis_dVb + * T1; + if (selfheat) dRds_dT = (0.8 + T0) * T1 * drds0_dT; + else dRds_dT = 0.0; + } + +/* Calculate Abulk */ + if (pParam->B3SOIFDa0 == 0.0) + { + Abulk0 = Abulk = dAbulk0_dVb = dAbulk_dVg = dAbulk_dVb = 0.0; + } + else + { + T1 = 0.5 * pParam->B3SOIFDk1 / sqrtPhi; + T9 = sqrt(model->B3SOIFDxj * Xdep); + tmp1 = Leff + 2.0 * T9; + T5 = Leff / tmp1; + tmp2 = pParam->B3SOIFDa0 * T5; + tmp3 = pParam->B3SOIFDweff + pParam->B3SOIFDb1; + tmp4 = pParam->B3SOIFDb0 / tmp3; + T2 = tmp2 + tmp4; + dT2_dVb = -T9 * tmp2 / tmp1 / Xdep * dXdep_dVb; + T6 = T5 * T5; + T7 = T5 * T6; + + Abulk0 = T1 * T2; + dAbulk0_dVb = T1 * dT2_dVb; + + T8 = pParam->B3SOIFDags * pParam->B3SOIFDa0 * T7; + dAbulk_dVg = -T1 * T8; + Abulk = Abulk0 + dAbulk_dVg * Vgsteff; + + dAbulk_dVb = dAbulk0_dVb - T8 * Vgsteff * 3.0 * T1 * dT2_dVb + / tmp2; + } + + if (Abulk0 < 0.01) + { + T9 = 1.0 / (3.0 - 200.0 * Abulk0); + Abulk0 = (0.02 - Abulk0) * T9; + dAbulk0_dVb *= T9 * T9; + } + + if (Abulk < 0.01) + { + T9 = 1.0 / (3.0 - 200.0 * Abulk); + Abulk = (0.02 - Abulk) * T9; + dAbulk_dVb *= T9 * T9; + } + + T2 = pParam->B3SOIFDketa * Vbseff; + if (T2 >= -0.9) + { T0 = 1.0 / (1.0 + T2); + dT0_dVb = -pParam->B3SOIFDketa * T0 * T0 ; + } + else + /* added to avoid the problems caused by Keta */ + { T1 = 1.0 / (0.8 + T2); + T0 = (17.0 + 20.0 * T2) * T1; + dT0_dVb = -pParam->B3SOIFDketa * T1 * T1 ; + } + dAbulk_dVg *= T0; + dAbulk_dVb = dAbulk_dVb * T0 + Abulk * dT0_dVb; + dAbulk0_dVb = dAbulk0_dVb * T0 + Abulk0 * dT0_dVb; + Abulk *= T0; + Abulk0 *= T0; + + Abulk += 1; + Abulk0 += 1; + +/* Prepare Abeff */ + T0 = pParam->B3SOIFDabp * Vgst2Vtm; + T1 = 1 - Vcs / T0 - DELT_Xcsat; + T2 = sqrt(T1 * T1 + DELT_Xcsat * DELT_Xcsat); + T3 = 1 - 0.5 * (T1 + T2); + T5 = -0.5 * (1 + T1 / T2); + dT1_dVg = Vcs / Vgst2Vtm / T0; + dT3_dVg = T5 * dT1_dVg; + dT1_dVc = - 1 / T0; + dT3_dVc = T5 * dT1_dVc; + + Xcsat = pParam->B3SOIFDmxc * T3 * T3 + (1 - pParam->B3SOIFDmxc)*T3; + T4 = 2 * pParam->B3SOIFDmxc * T3 + (1 - pParam->B3SOIFDmxc); + dXcsat_dVg = T4 * dT3_dVg; + dXcsat_dVc = T4 * dT3_dVc; + + Abeff = Xcsat * Abulk + (1 - Xcsat) * model->B3SOIFDadice; + T0 = Xcsat * dAbulk_dVg + Abulk * dXcsat_dVg; + dAbeff_dVg = T0 - model->B3SOIFDadice * dXcsat_dVg; + dAbeff_dVb = Xcsat * dAbulk_dVb; + dAbeff_dVc = (Abulk - model->B3SOIFDadice) * dXcsat_dVc; + here->B3SOIFDabeff = Abeff; + +/* Mobility calculation */ + if (model->B3SOIFDmobMod == 1) + { T0 = Vgsteff + Vth + Vth; + T2 = ua + uc * Vbseff; + T3 = T0 / model->B3SOIFDtox; + T5 = T3 * (T2 + ub * T3); + dDenomi_dVg = (T2 + 2.0 * ub * T3) / model->B3SOIFDtox; + dDenomi_dVd = dDenomi_dVg * 2 * dVth_dVd; + dDenomi_dVb = dDenomi_dVg * 2 * dVth_dVb + uc * T3 ; + if (selfheat) + dDenomi_dT = dDenomi_dVg * 2 * dVth_dT + + (dua_dT + Vbseff * duc_dT + + dub_dT * T3 ) * T3; + else + dDenomi_dT = 0.0; + } + else if (model->B3SOIFDmobMod == 2) + { T5 = Vgsteff / model->B3SOIFDtox * (ua + + uc * Vbseff + ub * Vgsteff + / model->B3SOIFDtox); + dDenomi_dVg = (ua + uc * Vbseff + + 2.0 * ub * Vgsteff / model->B3SOIFDtox) + / model->B3SOIFDtox; + dDenomi_dVd = 0.0; + dDenomi_dVb = Vgsteff * uc / model->B3SOIFDtox ; + if (selfheat) + dDenomi_dT = Vgsteff / model->B3SOIFDtox + * (dua_dT + Vbseff * duc_dT + dub_dT + * Vgsteff / model->B3SOIFDtox); + else + dDenomi_dT = 0.0; + } + else /* mobMod == 3 */ + { T0 = Vgsteff + Vth + Vth; + T2 = 1.0 + uc * Vbseff; + T3 = T0 / model->B3SOIFDtox; + T4 = T3 * (ua + ub * T3); + T5 = T4 * T2; + dDenomi_dVg = (ua + 2.0 * ub * T3) * T2 + / model->B3SOIFDtox; + dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd; + dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + + uc * T4 ; + if (selfheat) + dDenomi_dT = dDenomi_dVg * 2.0 * dVth_dT + + (dua_dT + dub_dT * T3) * T3 * T2 + + T4 * Vbseff * duc_dT; + else + dDenomi_dT = 0.0; + } + + if (T5 >= -0.8) + { Denomi = 1.0 + T5; + } + else /* Added to avoid the discontinuity problem caused by ua and ub*/ + { T9 = 1.0 / (7.0 + 10.0 * T5); + Denomi = (0.6 + T5) * T9; + T9 *= T9; + dDenomi_dVg *= T9; + dDenomi_dVd *= T9; + dDenomi_dVb *= T9; + if (selfheat) dDenomi_dT *= T9; + else dDenomi_dT = 0.0; + } + + here->B3SOIFDueff = ueff = u0temp / Denomi; + T9 = -ueff / Denomi; + dueff_dVg = T9 * dDenomi_dVg; + dueff_dVd = T9 * dDenomi_dVd; + dueff_dVb = T9 * dDenomi_dVb; + if (selfheat) dueff_dT = T9 * dDenomi_dT + du0temp_dT / Denomi; + else dueff_dT = 0.0; + +/* Saturation Drain Voltage Vdsat */ + WVCox = Weff * vsattemp * model->B3SOIFDcox; + WVCoxRds = WVCox * Rds; + +/* dWVCoxRds_dT = WVCox * dRds_dT + + Weff * model->B3SOIFDcox * Rds * dvsattemp_dT; */ + + Esat = 2.0 * vsattemp / ueff; + EsatL = Esat * Leff; + T0 = -EsatL /ueff; + dEsatL_dVg = T0 * dueff_dVg; + dEsatL_dVd = T0 * dueff_dVd; + dEsatL_dVb = T0 * dueff_dVb; + if (selfheat) + dEsatL_dT = T0 * dueff_dT + EsatL / vsattemp * dvsattemp_dT; + else + dEsatL_dT = 0.0; + + /* Sqrt() */ + a1 = pParam->B3SOIFDa1; + if (a1 == 0.0) + { Lambda = pParam->B3SOIFDa2; + dLambda_dVg = 0.0; + } + else if (a1 > 0.0) +/* Added to avoid the discontinuity problem caused by a1 and a2 (Lambda) */ + { T0 = 1.0 - pParam->B3SOIFDa2; + T1 = T0 - pParam->B3SOIFDa1 * Vgsteff - 0.0001; + T2 = sqrt(T1 * T1 + 0.0004 * T0); + Lambda = pParam->B3SOIFDa2 + T0 - 0.5 * (T1 + T2); + dLambda_dVg = 0.5 * pParam->B3SOIFDa1 * (1.0 + T1 / T2); + } + else + { T1 = pParam->B3SOIFDa2 + pParam->B3SOIFDa1 * Vgsteff - 0.0001; + T2 = sqrt(T1 * T1 + 0.0004 * pParam->B3SOIFDa2); + Lambda = 0.5 * (T1 + T2); + dLambda_dVg = 0.5 * pParam->B3SOIFDa1 * (1.0 + T1 / T2); + } + + if (Rds > 0) + { tmp2 = dRds_dVg / Rds + dWeff_dVg / Weff; + tmp3 = dRds_dVb / Rds + dWeff_dVb / Weff; + } + else + { tmp2 = dWeff_dVg / Weff; + tmp3 = dWeff_dVb / Weff; + } + if ((Rds == 0.0) && (Lambda == 1.0)) + { T0 = 1.0 / (Abeff * EsatL + Vgst2Vtm); + tmp1 = 0.0; + T1 = T0 * T0; + T2 = Vgst2Vtm * T0; + T3 = EsatL * Vgst2Vtm; + Vdsat = T3 * T0; + + dT0_dVg = -(Abeff * dEsatL_dVg + EsatL * dAbeff_dVg + 1.0) * T1; + dT0_dVd = -(Abeff * dEsatL_dVd) * T1; + dT0_dVb = -(Abeff * dEsatL_dVb + EsatL * dAbeff_dVb) * T1; + dT0_dVc = 0.0; + if (selfheat) + dT0_dT = -(Abeff * dEsatL_dT + dVgst2Vtm_dT) * T1; + else dT0_dT = 0.0; + + dVdsat_dVg = T3 * dT0_dVg + T2 * dEsatL_dVg + EsatL * T0; + dVdsat_dVd = T3 * dT0_dVd + T2 * dEsatL_dVd; + dVdsat_dVb = T3 * dT0_dVb + T2 * dEsatL_dVb; + dVdsat_dVc = 0.0; + if (selfheat) + dVdsat_dT = T3 * dT0_dT + T2 * dEsatL_dT + + EsatL * T0 * dVgst2Vtm_dT; + else dVdsat_dT = 0.0; + } + else + { tmp1 = dLambda_dVg / (Lambda * Lambda); + T9 = Abeff * WVCoxRds; + T8 = Abeff * T9; + T7 = Vgst2Vtm * T9; + T6 = Vgst2Vtm * WVCoxRds; + T0 = 2.0 * Abeff * (T9 - 1.0 + 1.0 / Lambda); + dT0_dVg = 2.0 * (T8 * tmp2 - Abeff * tmp1 + + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbeff_dVg); +/* dT0_dVb = 2.0 * (T8 * tmp3 this is equivalent to one below, but simpler + + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbeff_dVg); */ + dT0_dVb = 2.0 * (T8 * (2.0 / Abeff * dAbeff_dVb + tmp3) + + (1.0 / Lambda - 1.0) * dAbeff_dVb); + dT0_dVd = 0.0; + dT0_dVc = 0.0; + + if (selfheat) + { + tmp4 = dRds_dT / Rds + dvsattemp_dT / vsattemp; + dT0_dT = 2.0 * T8 * tmp4; + } else tmp4 = dT0_dT = 0.0; + + T1 = Vgst2Vtm * (2.0 / Lambda - 1.0) + Abeff * EsatL + 3.0 * T7; + + dT1_dVg = (2.0 / Lambda - 1.0) - 2.0 * Vgst2Vtm * tmp1 + + Abeff * dEsatL_dVg + EsatL * dAbeff_dVg + 3.0 * (T9 + + T7 * tmp2 + T6 * dAbeff_dVg); + dT1_dVb = Abeff * dEsatL_dVb + EsatL * dAbeff_dVb + + 3.0 * (T6 * dAbeff_dVb + T7 * tmp3); + dT1_dVd = Abeff * dEsatL_dVd; + dT1_dVc = 0.0; + + + if (selfheat) + { + tmp4 += dVgst2Vtm_dT / Vgst2Vtm; + dT1_dT = (2.0 / Lambda - 1.0) * dVgst2Vtm_dT + + Abeff * dEsatL_dT + 3.0 * T7 * tmp4; + } else dT1_dT = 0.0; + + T2 = Vgst2Vtm * (EsatL + 2.0 * T6); + dT2_dVg = EsatL + Vgst2Vtm * dEsatL_dVg + + T6 * (4.0 + 2.0 * Vgst2Vtm * tmp2); + dT2_dVb = Vgst2Vtm * (dEsatL_dVb + 2.0 * T6 * tmp3); + dT2_dVd = Vgst2Vtm * dEsatL_dVd; + if (selfheat) + dT2_dT = Vgst2Vtm * dEsatL_dT + EsatL * dVgst2Vtm_dT + + 2.0 * T6 * (dVgst2Vtm_dT + Vgst2Vtm * tmp4); + else + dT2_dT = 0.0; + + T3 = sqrt(T1 * T1 - 2.0 * T0 * T2); + Vdsat = (T1 - T3) / T0; + + dVdsat_dVg = (dT1_dVg - (T1 * dT1_dVg - dT0_dVg * T2 + - T0 * dT2_dVg) / T3 - Vdsat * dT0_dVg) / T0; + dVdsat_dVb = (dT1_dVb - (T1 * dT1_dVb - dT0_dVb * T2 + - T0 * dT2_dVb) / T3 - Vdsat * dT0_dVb) / T0; + dVdsat_dVd = (dT1_dVd - (T1 * dT1_dVd - T0 * dT2_dVd) / T3) / T0; + dVdsat_dVc = 0.0; + if (selfheat) + dVdsat_dT = (dT1_dT - (T1 * dT1_dT - dT0_dT * T2 + - T0 * dT2_dT) / T3 - Vdsat * dT0_dT) / T0; + else dVdsat_dT = 0.0; + } + here->B3SOIFDvdsat = Vdsat; + +/* Vdsatii for impact ionization */ + if (pParam->B3SOIFDaii > 0.0) + { + if (pParam->B3SOIFDcii != 0.0) + { + T0 = pParam->B3SOIFDcii / sqrt(3.0) + pParam->B3SOIFDdii; + /* Hard limit Vds to T0 => T4 i.e. limit T0 to 3.0 */ + T1 = Vds - T0 - 0.1; + T2 = sqrt(T1 * T1 + 0.4); + T3 = T0 + 0.5 * (T1 + T2); + dT3_dVd = 0.5 * (1.0 + T1/T2); + + T4 = T3 - pParam->B3SOIFDdii; + T5 = pParam->B3SOIFDcii / T4; + T0 = T5 * T5; + dT0_dVd = - 2 * T0 / T4 * dT3_dVd; + } else + { + T0 = dT0_dVd = 0.0; + } + T0 += 1.0; + + T3 = pParam->B3SOIFDaii + pParam->B3SOIFDbii / Leff; + T4 = 1.0 / (T0 * Vgsteff + T3 * EsatL); + T5 = -T4 * T4; + T6 = Vgsteff * T4; + T7 = EsatL * Vgsteff; + Vdsatii = T7 * T4; + + dT4_dVg = T5 * (T0 + T3 * dEsatL_dVg); + dT4_dVb = T5 * T3 * dEsatL_dVb; + dT4_dVd = T5 * (Vgsteff * dT0_dVd + T3 * dEsatL_dVd); + + if (selfheat) dT4_dT = T5 * (T3 * dEsatL_dT); + else dT4_dT = 0.0; + + T8 = T4 * Vgsteff; + dVdsatii_dVg = T7 * dT4_dVg + T4 * (EsatL + Vgsteff * dEsatL_dVg); + dVdsatii_dVb = T7 * dT4_dVb + T8 * dEsatL_dVb; + dVdsatii_dVd = T7 * dT4_dVd + T8 * dEsatL_dVd; + if (selfheat) dVdsatii_dT = T7 * dT4_dT + T8 * dEsatL_dT; + else dVdsatii_dT = 0.0; + } else + { + Vdsatii = Vdsat; + dVdsatii_dVg = dVdsat_dVg; + dVdsatii_dVb = dVdsat_dVb; + dVdsatii_dVd = dVdsat_dVd; + dVdsatii_dT = dVdsat_dT; + } + +/* Effective Vds (Vdseff) Calculation */ + T1 = Vdsat - Vds - pParam->B3SOIFDdelta; + dT1_dVg = dVdsat_dVg; + dT1_dVd = dVdsat_dVd - 1.0; + dT1_dVb = dVdsat_dVb; + dT1_dVc = dVdsat_dVc; + dT1_dT = dVdsat_dT; + + T2 = sqrt(T1 * T1 + 4.0 * pParam->B3SOIFDdelta * Vdsat); + T0 = T1 / T2; + T3 = 2.0 * pParam->B3SOIFDdelta / T2; + dT2_dVg = T0 * dT1_dVg + T3 * dVdsat_dVg; + dT2_dVd = T0 * dT1_dVd + T3 * dVdsat_dVd; + dT2_dVb = T0 * dT1_dVb + T3 * dVdsat_dVb; + dT2_dVc = 0.0; + if (selfheat) + dT2_dT = T0 * dT1_dT + T3 * dVdsat_dT; + else dT2_dT = 0.0; + + Vdseff = Vdsat - 0.5 * (T1 + T2); + dVdseff_dVg = dVdsat_dVg - 0.5 * (dT1_dVg + dT2_dVg); + dVdseff_dVd = dVdsat_dVd - 0.5 * (dT1_dVd + dT2_dVd); + dVdseff_dVb = dVdsat_dVb - 0.5 * (dT1_dVb + dT2_dVb); + dVdseff_dVc = 0.0; + if (selfheat) + dVdseff_dT = dVdsat_dT - 0.5 * (dT1_dT + dT2_dT); + else dVdseff_dT = 0.0; + + if (Vdseff > Vds) + Vdseff = Vds; /* This code is added to fixed the problem + caused by computer precision when + Vds is very close to Vdseff. */ + diffVds = Vds - Vdseff; + +/* Effective Vdsii for Iii calculation */ + T1 = Vdsatii - Vds - pParam->B3SOIFDdelta; + + T2 = sqrt(T1 * T1 + 4.0 * pParam->B3SOIFDdelta * Vdsatii); + T0 = T1 / T2; + T3 = 2.0 * pParam->B3SOIFDdelta / T2; + T4 = T0 + T3; + dT2_dVg = T4 * dVdsatii_dVg; + dT2_dVd = T4 * dVdsatii_dVd - T0; + dT2_dVb = T4 * dVdsatii_dVb; + if (selfheat) dT2_dT = T4*dVdsatii_dT; + else dT2_dT = 0.0; + + Vdseffii = Vdsatii - 0.5 * (T1 + T2); + dVdseffii_dVg = 0.5 * (dVdsatii_dVg - dT2_dVg); + dVdseffii_dVd = 0.5 * (dVdsatii_dVd - dT2_dVd + 1.0); + dVdseffii_dVb = 0.5 * (dVdsatii_dVb - dT2_dVb); + if (selfheat) + dVdseffii_dT = 0.5 * (dVdsatii_dT - dT2_dT); + else dVdseffii_dT = 0.0; + diffVdsii = Vds - Vdseffii; + +/* Calculate VAsat */ + tmp4 = 1.0 - 0.5 * Abeff * Vdsat / Vgst2Vtm; + T9 = WVCoxRds * Vgsteff; + T8 = T9 / Vgst2Vtm; + T0 = EsatL + Vdsat + 2.0 * T9 * tmp4; + + T7 = 2.0 * WVCoxRds * tmp4; + dT0_dVg = dEsatL_dVg + dVdsat_dVg + T7 * (1.0 + tmp2 * Vgsteff) + - T8 * (Abeff * dVdsat_dVg - Abeff * Vdsat / Vgst2Vtm + + Vdsat * dAbeff_dVg); + + dT0_dVb = dEsatL_dVb + dVdsat_dVb + T7 * tmp3 * Vgsteff + - T8 * (dAbeff_dVb * Vdsat + Abeff * dVdsat_dVb); + dT0_dVd = dEsatL_dVd + dVdsat_dVd - T8 * Abeff * dVdsat_dVd; + dT0_dVc = 0.0; + + if (selfheat) + { + tmp4 = dRds_dT / Rds + dvsattemp_dT / vsattemp; + dT0_dT = dEsatL_dT + dVdsat_dT + T7 * tmp4 * Vgsteff + - T8 * (Abeff * dVdsat_dT - Abeff * Vdsat * dVgst2Vtm_dT + / Vgst2Vtm); + } else + dT0_dT = 0.0; + + T9 = WVCoxRds * Abeff; + T1 = 2.0 / Lambda - 1.0 + T9; + dT1_dVg = -2.0 * tmp1 + WVCoxRds * (Abeff * tmp2 + dAbeff_dVg); + dT1_dVb = dAbeff_dVb * WVCoxRds + T9 * tmp3; + dT1_dVc = 0.0; + if (selfheat) + dT1_dT = T9 * tmp4; + else + dT1_dT = 0.0; + + Vasat = T0 / T1; + dVasat_dVg = (dT0_dVg - Vasat * dT1_dVg) / T1; + dVasat_dVb = (dT0_dVb - Vasat * dT1_dVb) / T1; + dVasat_dVd = dT0_dVd / T1; + dVasat_dVc = 0.0; + if (selfheat) dVasat_dT = (dT0_dT - Vasat * dT1_dT) / T1; + else dVasat_dT = 0.0; + +/* Calculate VACLM */ + if ((pParam->B3SOIFDpclm > 0.0) && (diffVds > 1.0e-10)) + { T0 = 1.0 / (pParam->B3SOIFDpclm * Abeff * pParam->B3SOIFDlitl); + dT0_dVb = -T0 / Abeff * dAbeff_dVb; + dT0_dVg = -T0 / Abeff * dAbeff_dVg; + dT0_dVc = 0.0; + + T2 = Vgsteff / EsatL; + T1 = Leff * (Abeff + T2); + dT1_dVg = Leff * ((1.0 - T2 * dEsatL_dVg) / EsatL + dAbeff_dVg); + dT1_dVb = Leff * (dAbeff_dVb - T2 * dEsatL_dVb / EsatL); + dT1_dVd = -T2 * dEsatL_dVd / Esat; + dT1_dVc = 0.0; + if (selfheat) dT1_dT = -T2 * dEsatL_dT / Esat; + else dT1_dT = 0.0; + + T9 = T0 * T1; + VACLM = T9 * diffVds; + dVACLM_dVg = T0 * dT1_dVg * diffVds - T9 * dVdseff_dVg + + T1 * diffVds * dT0_dVg; + dVACLM_dVb = (dT0_dVb * T1 + T0 * dT1_dVb) * diffVds + - T9 * dVdseff_dVb; + dVACLM_dVd = T0 * dT1_dVd * diffVds + T9 * (1.0 - dVdseff_dVd); + dVACLM_dVc = 0.0; + if (selfheat) + dVACLM_dT = T0 * dT1_dT * diffVds - T9 * dVdseff_dT; + else dVACLM_dT = 0.0; + + } + else + { VACLM = MAX_EXP; + dVACLM_dVd = dVACLM_dVg = dVACLM_dVb = dVACLM_dVc = dVACLM_dT = 0.0; + } + + +/* Calculate VADIBL */ + if (pParam->B3SOIFDthetaRout > 0.0) + { T8 = Abeff * Vdsat; + T0 = Vgst2Vtm * T8; + T1 = Vgst2Vtm + T8; + dT0_dVg = Vgst2Vtm * Abeff * dVdsat_dVg + T8 + + Vgst2Vtm * Vdsat * dAbeff_dVg; + dT1_dVg = 1.0 + Abeff * dVdsat_dVg + Vdsat * dAbeff_dVg; + dT1_dVb = dAbeff_dVb * Vdsat + Abeff * dVdsat_dVb; + dT0_dVb = Vgst2Vtm * dT1_dVb; + dT1_dVd = Abeff * dVdsat_dVd; + dT0_dVd = Vgst2Vtm * dT1_dVd; + dT0_dVc = dT1_dVc = 0.0; + if (selfheat) + { + dT0_dT = dVgst2Vtm_dT * T8 + Abeff * Vgst2Vtm * dVdsat_dT; + dT1_dT = dVgst2Vtm_dT + Abeff * dVdsat_dT; + } else + dT0_dT = dT1_dT = 0.0; + + T9 = T1 * T1; + T2 = pParam->B3SOIFDthetaRout; + VADIBL = (Vgst2Vtm - T0 / T1) / T2; + dVADIBL_dVg = (1.0 - dT0_dVg / T1 + T0 * dT1_dVg / T9) / T2; + dVADIBL_dVb = (-dT0_dVb / T1 + T0 * dT1_dVb / T9) / T2; + dVADIBL_dVd = (-dT0_dVd / T1 + T0 * dT1_dVd / T9) / T2; + dVADIBL_dVc = 0.0; + if (selfheat) + dVADIBL_dT = (dVgst2Vtm_dT - dT0_dT/T1 + T0*dT1_dT/T9) / T2; + else dVADIBL_dT = 0.0; + + T7 = pParam->B3SOIFDpdiblb * Vbseff; + if (T7 >= -0.9) + { T3 = 1.0 / (1.0 + T7); + VADIBL *= T3; + dVADIBL_dVg *= T3; + dVADIBL_dVb = (dVADIBL_dVb - VADIBL * pParam->B3SOIFDpdiblb) + * T3; + dVADIBL_dVd *= T3; + dVADIBL_dVc *= T3; + if (selfheat) dVADIBL_dT *= T3; + else dVADIBL_dT = 0.0; + } + else +/* Added to avoid the discontinuity problem caused by pdiblcb */ + { T4 = 1.0 / (0.8 + T7); + T3 = (17.0 + 20.0 * T7) * T4; + dVADIBL_dVg *= T3; + dVADIBL_dVb = dVADIBL_dVb * T3 + - VADIBL * pParam->B3SOIFDpdiblb * T4 * T4; + dVADIBL_dVd *= T3; + dVADIBL_dVc *= T3; + if (selfheat) dVADIBL_dT *= T3; + else dVADIBL_dT = 0.0; + VADIBL *= T3; + } + } + else + { VADIBL = MAX_EXP; + dVADIBL_dVd = dVADIBL_dVg = dVADIBL_dVb = dVADIBL_dVc + = dVADIBL_dT = 0.0; + } + +/* Calculate VA */ + + T8 = pParam->B3SOIFDpvag / EsatL; + T9 = T8 * Vgsteff; + if (T9 > -0.9) + { T0 = 1.0 + T9; + dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL); + dT0_dVb = -T9 * dEsatL_dVb / EsatL; + dT0_dVd = -T9 * dEsatL_dVd / EsatL; + if (selfheat) + dT0_dT = -T9 * dEsatL_dT / EsatL; + else + dT0_dT = 0.0; + } + else /* Added to avoid the discontinuity problems caused by pvag */ + { T1 = 1.0 / (17.0 + 20.0 * T9); + T0 = (0.8 + T9) * T1; + T1 *= T1; + dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL) * T1; + + T9 *= T1 / EsatL; + dT0_dVb = -T9 * dEsatL_dVb; + dT0_dVd = -T9 * dEsatL_dVd; + if (selfheat) + dT0_dT = -T9 * dEsatL_dT; + else + dT0_dT = 0.0; + } + + tmp1 = VACLM * VACLM; + tmp2 = VADIBL * VADIBL; + tmp3 = VACLM + VADIBL; + + T1 = VACLM * VADIBL / tmp3; + tmp3 *= tmp3; + dT1_dVg = (tmp1 * dVADIBL_dVg + tmp2 * dVACLM_dVg) / tmp3; + dT1_dVd = (tmp1 * dVADIBL_dVd + tmp2 * dVACLM_dVd) / tmp3; + dT1_dVb = (tmp1 * dVADIBL_dVb + tmp2 * dVACLM_dVb) / tmp3; + dT1_dVc = 0.0; + if (selfheat) + dT1_dT = (tmp1 * dVADIBL_dT + tmp2 * dVACLM_dT ) / tmp3; + else dT1_dT = 0.0; + + Va = Vasat + T0 * T1; + dVa_dVg = dVasat_dVg + T1 * dT0_dVg + T0 * dT1_dVg; + dVa_dVd = dVasat_dVd + T1 * dT0_dVd + T0 * dT1_dVd; + dVa_dVb = dVasat_dVb + T1 * dT0_dVb + T0 * dT1_dVb; + dVa_dVc = 0.0; + if (selfheat) + dVa_dT = dVasat_dT + T1 * dT0_dT + T0 * dT1_dT; + else dVa_dT = 0.0; + +/* Calculate Ids */ + CoxWovL = model->B3SOIFDcox * Weff / Leff; + beta = ueff * CoxWovL; + dbeta_dVg = CoxWovL * dueff_dVg + beta * dWeff_dVg / Weff; + dbeta_dVd = CoxWovL * dueff_dVd; + dbeta_dVb = CoxWovL * dueff_dVb + beta * dWeff_dVb / Weff; + if (selfheat) dbeta_dT = CoxWovL * dueff_dT; + else dbeta_dT = 0.0; + + T0 = 1.0 - 0.5 * Abeff * Vdseff / Vgst2Vtm; + dT0_dVg = -0.5 * (Abeff * dVdseff_dVg + - Abeff * Vdseff / Vgst2Vtm + Vdseff * dAbeff_dVg) / Vgst2Vtm; + dT0_dVd = -0.5 * Abeff * dVdseff_dVd / Vgst2Vtm; + dT0_dVb = -0.5 * (Abeff * dVdseff_dVb + dAbeff_dVb * Vdseff) + / Vgst2Vtm; + dT0_dVc = 0.0; + if (selfheat) + dT0_dT = -0.5 * (Abeff * dVdseff_dT + - Abeff * Vdseff / Vgst2Vtm * dVgst2Vtm_dT) + / Vgst2Vtm; + else dT0_dT = 0.0; + + fgche1 = Vgsteff * T0; + dfgche1_dVg = Vgsteff * dT0_dVg + T0; + dfgche1_dVd = Vgsteff * dT0_dVd; + dfgche1_dVb = Vgsteff * dT0_dVb; + dfgche1_dVc = 0.0; + if (selfheat) dfgche1_dT = Vgsteff * dT0_dT; + else dfgche1_dT = 0.0; + + T9 = Vdseff / EsatL; + fgche2 = 1.0 + T9; + dfgche2_dVg = (dVdseff_dVg - T9 * dEsatL_dVg) / EsatL; + dfgche2_dVd = (dVdseff_dVd - T9 * dEsatL_dVd) / EsatL; + dfgche2_dVb = (dVdseff_dVb - T9 * dEsatL_dVb) / EsatL; + dfgche2_dVc = 0.0; + if (selfheat) dfgche2_dT = (dVdseff_dT - T9 * dEsatL_dT) / EsatL; + else dfgche2_dT = 0.0; + + gche = beta * fgche1 / fgche2; + dgche_dVg = (beta * dfgche1_dVg + fgche1 * dbeta_dVg + - gche * dfgche2_dVg) / fgche2; + dgche_dVd = (beta * dfgche1_dVd + fgche1 * dbeta_dVd + - gche * dfgche2_dVd) / fgche2; + dgche_dVb = (beta * dfgche1_dVb + fgche1 * dbeta_dVb + - gche * dfgche2_dVb) / fgche2; + dgche_dVc = 0.0; + if (selfheat) + dgche_dT = (beta * dfgche1_dT + fgche1 * dbeta_dT + - gche * dfgche2_dT) / fgche2; + else dgche_dT = 0.0; + + T0 = 1.0 + gche * Rds; + T9 = Vdseff / T0; + Idl = gche * T9; + +/* Whoa, these formulas for the derivatives of Idl are convoluted, but I + verified them to be correct */ + + dIdl_dVg = (gche * dVdseff_dVg + T9 * dgche_dVg) / T0 + - Idl * gche / T0 * dRds_dVg ; + dIdl_dVd = (gche * dVdseff_dVd + T9 * dgche_dVd) / T0; + dIdl_dVb = (gche * dVdseff_dVb + T9 * dgche_dVb + - Idl * dRds_dVb * gche) / T0; + dIdl_dVc = 0.0; + if (selfheat) + dIdl_dT = (gche * dVdseff_dT + T9 * dgche_dT + - Idl * dRds_dT * gche) / T0; + else dIdl_dT = 0.0; + + T9 = diffVds / Va; + T0 = 1.0 + T9; + here->B3SOIFDids = Ids = Idl * T0; + + Gm0 = T0 * dIdl_dVg - Idl * (dVdseff_dVg + T9 * dVa_dVg) / Va; + Gds0 = T0 * dIdl_dVd + Idl * (1.0 - dVdseff_dVd + - T9 * dVa_dVd) / Va; + Gmb0 = T0 * dIdl_dVb - Idl * (dVdseff_dVb + T9 * dVa_dVb) / Va; + Gmc = 0.0; + if (selfheat) + GmT0 = T0 * dIdl_dT - Idl * (dVdseff_dT + T9 * dVa_dT) / Va; + else GmT0 = 0.0; + +/* This includes all dependencies from Vgsteff, Vbseff, Vcs */ + + Gm = Gm0 * dVgsteff_dVg + Gmb0 * dVbseff_dVg + Gmc * dVcs_dVg; + Gmb = Gm0 * dVgsteff_dVb + Gmb0 * dVbseff_dVb + Gmc * dVcs_dVb; + Gds = Gm0 * dVgsteff_dVd + Gmb0 * dVbseff_dVd + Gmc * dVcs_dVd + Gds0; + Gme = Gm0 * dVgsteff_dVe + Gmb0 * dVbseff_dVe + Gmc * dVcs_dVe; + if (selfheat) + GmT = Gm0 * dVgsteff_dT + Gmb0 * dVbseff_dT + Gmc * dVcs_dT + GmT0; + else GmT = 0.0; + + +/* calculate substrate current Iii */ + + Giig = Giib = Giid = Giie = GiiT = 0.0; + here->B3SOIFDiii = Iii = 0.0; + + Idgidl = Gdgidld = Gdgidlg = 0.0; + Isgidl = Gsgidlg = 0; + + here->B3SOIFDibs = Ibs = 0.0; + here->B3SOIFDibd = Ibd = 0.0; + here->B3SOIFDic = Ic = 0.0; + + Gjsb = Gjsd = GjsT = 0.0; + Gjdb = Gjdd = GjdT = 0.0; + Gcd = Gcb = GcT = 0.0; + + here->B3SOIFDibp = Ibp = 0.0; + here->B3SOIFDgbpbs = here->B3SOIFDgbpgs = here->B3SOIFDgbpds = 0.0; + here->B3SOIFDgbpes = here->B3SOIFDgbpps = here->B3SOIFDgbpT = here->B3SOIFDcbodcon = 0.0; + Gbpbs = Gbpgs = Gbpds = Gbpes = Gbpps = GbpT = 0.0; + + /* Current going out of drainprime node into the drain of device */ + /* "node" means the SPICE circuit node */ + + here->B3SOIFDcdrain = Ids + Ic; + here->B3SOIFDcd = Ids + Ic - Ibd + Iii + Idgidl; + here->B3SOIFDcb = Ibs + Ibd + Ibp - Iii - Idgidl - Isgidl; + + here->B3SOIFDgds = Gds + Gcd; + here->B3SOIFDgm = Gm; + here->B3SOIFDgmbs = Gmb + Gcb; + here->B3SOIFDgme = Gme; + if (selfheat) + here->B3SOIFDgmT = GmT + GcT; + else + here->B3SOIFDgmT = 0.0; + + /* note that sign is switched because power flows out + of device into the temperature node. + Currently ommit self-heating due to bipolar current + because it can cause convergence problem*/ + + here->B3SOIFDgtempg = -Gm * Vds; + here->B3SOIFDgtempb = -Gmb * Vds; + here->B3SOIFDgtempe = -Gme * Vds; + here->B3SOIFDgtempT = -GmT * Vds; + here->B3SOIFDgtempd = -Gds * Vds - Ids; + here->B3SOIFDcth = - Ids * Vds - model->B3SOIFDtype * + (here->B3SOIFDgtempg * Vgs + here->B3SOIFDgtempb * Vbs + + here->B3SOIFDgtempe * Ves + here->B3SOIFDgtempd * Vds) + - here->B3SOIFDgtempT * delTemp; + + /* Body current which flows into drainprime node from the drain of device */ + + here->B3SOIFDgjdb = Gjdb - Giib; + here->B3SOIFDgjdd = Gjdd - (Giid + Gdgidld); + here->B3SOIFDgjdg = - (Giig + Gdgidlg); + here->B3SOIFDgjde = - Giie; + if (selfheat) here->B3SOIFDgjdT = GjdT - GiiT; + else here->B3SOIFDgjdT = 0.0; + here->B3SOIFDcjd = Ibd - Iii - Idgidl - here->B3SOIFDminIsub/2 + - (here->B3SOIFDgjdb * Vbs + here->B3SOIFDgjdd * Vds + + here->B3SOIFDgjdg * Vgs + here->B3SOIFDgjde * Ves + + here->B3SOIFDgjdT * delTemp); + + /* Body current which flows into sourceprime node from the source of device */ + + here->B3SOIFDgjsb = Gjsb; + here->B3SOIFDgjsd = Gjsd; + here->B3SOIFDgjsg = - Gsgidlg; + if (selfheat) here->B3SOIFDgjsT = GjsT; + else here->B3SOIFDgjsT = 0.0; + here->B3SOIFDcjs = Ibs - Isgidl - here->B3SOIFDminIsub/2 + - (here->B3SOIFDgjsb * Vbs + here->B3SOIFDgjsd * Vds + + here->B3SOIFDgjsg * Vgs + here->B3SOIFDgjsT * delTemp); + + /* Current flowing into body node */ + + here->B3SOIFDgbbs = Giib - Gjsb - Gjdb - Gbpbs; + here->B3SOIFDgbgs = Giig + Gdgidlg + Gsgidlg - Gbpgs; + here->B3SOIFDgbds = Giid + Gdgidld - Gjsd - Gjdd - Gbpds; + here->B3SOIFDgbes = Giie - Gbpes; + here->B3SOIFDgbps = - Gbpps; + if (selfheat) here->B3SOIFDgbT = GiiT - GjsT - GjdT - GbpT; + else here->B3SOIFDgbT = 0.0; + here->B3SOIFDcbody = Iii + Idgidl + Isgidl - Ibs - Ibd - Ibp + here->B3SOIFDminIsub + - (here->B3SOIFDgbbs * Vbs + here->B3SOIFDgbgs * Vgs + + here->B3SOIFDgbds * Vds + here->B3SOIFDgbps * Vps + + here->B3SOIFDgbes * Ves + here->B3SOIFDgbT * delTemp); + + /* Calculate Qinv for Noise analysis */ + + T1 = Vgsteff * (1.0 - 0.5 * Abeff * Vdseff / Vgst2Vtm); + here->B3SOIFDqinv = -model->B3SOIFDcox * pParam->B3SOIFDweff * Leff * T1; + + /* Begin CV (charge) model */ + + if ((model->B3SOIFDxpart < 0) || (!ChargeComputationNeeded)) + { qgate = qdrn = qsrc = qbody = 0.0; + here->B3SOIFDcggb = here->B3SOIFDcgsb = here->B3SOIFDcgdb = 0.0; + here->B3SOIFDcdgb = here->B3SOIFDcdsb = here->B3SOIFDcddb = 0.0; + here->B3SOIFDcbgb = here->B3SOIFDcbsb = here->B3SOIFDcbdb = 0.0; + goto finished; + } + else + { + CoxWL = model->B3SOIFDcox * pParam->B3SOIFDweffCV + * pParam->B3SOIFDleffCV; + + /* By using this Vgsteff,cv, discontinuity in moderate + inversion charges can be avoid. However, in capMod=3, + Vdsat from IV is used. The dVdsat_dVg is referred to + the IV Vgsteff and therefore induces error in the charges + derivatives. Fortunately, Vgsteff,iv and Vgsteff,cv are + different only in subthreshold where Qsubs is neglectible. + So the errors in derivatives is not a serious problem */ + + if ((VgstNVt > -EXP_THRESHOLD) && (VgstNVt < EXP_THRESHOLD)) + { ExpVgst *= ExpVgst; + Vgsteff = n * Vtm * log(1.0 + ExpVgst); + T0 = ExpVgst / (1.0 + ExpVgst); + T1 = -T0 * (dVth_dVb + Vgst / n * dn_dVb) + Vgsteff / n * dn_dVb; + dVgsteff_dVd = -T0 * (dVth_dVd + Vgst / n * dn_dVd) + + Vgsteff / n * dn_dVd + T1 * dVbseff_dVd; + dVgsteff_dVg = T0 * dVgs_eff_dVg + T1 * dVbseff_dVg; + dVgsteff_dVb = T1 * dVbseff_dVb; + dVgsteff_dVe = T1 * dVbseff_dVe; + if (selfheat) + dVgsteff_dT = -T0 * (dVth_dT + Vgst / Temp) + Vgsteff / Temp + + T1 * dVbseff_dT; + else dVgsteff_dT = 0.0; + } + + Vfb = Vth - phi - pParam->B3SOIFDk1 * sqrtPhis; + + dVfb_dVb = dVth_dVb - pParam->B3SOIFDk1 * dsqrtPhis_dVb; + dVfb_dVd = dVth_dVd; + dVfb_dT = dVth_dT; + + if ((model->B3SOIFDcapMod == 2) || (model->B3SOIFDcapMod == 3)) + { + /* Necessary because charge behaviour very strange at + Vgsteff = 0 */ + Vgsteff += 1e-4; + + /* Something common in capMod 2 and 3 */ + V3 = Vfb - Vgs_eff + Vbseff - DELTA_3; + if (Vfb <= 0.0) + { T0 = sqrt(V3 * V3 - 4.0 * DELTA_3 * Vfb); + T2 = -DELTA_3 / T0; + } + else + { T0 = sqrt(V3 * V3 + 4.0 * DELTA_3 * Vfb); + T2 = DELTA_3 / T0; + } + + T1 = 0.5 * (1.0 + V3 / T0); + Vfbeff = Vfb - 0.5 * (V3 + T0); + dVfbeff_dVd = (1.0 - T1 - T2) * dVfb_dVd; + dVfbeff_dVb = (1.0 - T1 - T2) * dVfb_dVb - T1; + dVfbeff_dVrg = T1 * dVgs_eff_dVg; + if (selfheat) dVfbeff_dT = (1.0 - T1 - T2) * dVfb_dT; + else dVfbeff_dT = 0.0; + + Qac0 = -CoxWL * (Vfbeff - Vfb); + dQac0_dVrg = -CoxWL * dVfbeff_dVrg; + dQac0_dVd = -CoxWL * (dVfbeff_dVd - dVfb_dVd); + dQac0_dVb = -CoxWL * (dVfbeff_dVb - dVfb_dVb); + if (selfheat) dQac0_dT = -CoxWL * (dVfbeff_dT - dVfb_dT); + else dQac0_dT = 0.0; + + T0 = 0.5 * K1; + T3 = Vgs_eff - Vfbeff - Vbseff - Vgsteff; + if (pParam->B3SOIFDk1 == 0.0) + { T1 = 0.0; + T2 = 0.0; + } + else if (T3 < 0.0) + { T1 = T0 + T3 / pParam->B3SOIFDk1; + T2 = CoxWL; + } + else + { T1 = sqrt(T0 * T0 + T3); + T2 = CoxWL * T0 / T1; + } + + Qsub0 = CoxWL * K1 * (T0 - T1); + + dQsub0_dVrg = T2 * (dVfbeff_dVrg - dVgs_eff_dVg); + dQsub0_dVg = T2; + dQsub0_dVd = T2 * dVfbeff_dVd; + dQsub0_dVb = T2 * (dVfbeff_dVb + 1); + if (selfheat) dQsub0_dT = T2 * dVfbeff_dT; + else dQsub0_dT = 0.0; + + One_Third_CoxWL = CoxWL / 3.0; + Two_Third_CoxWL = 2.0 * One_Third_CoxWL; + AbulkCV = Abulk0 * pParam->B3SOIFDabulkCVfactor; + dAbulkCV_dVb = pParam->B3SOIFDabulkCVfactor * dAbulk0_dVb; + + /* This is actually capMod=2 calculation */ + VdsatCV = Vgsteff / AbulkCV; + dVdsatCV_dVg = 1.0 / AbulkCV; + dVdsatCV_dVb = -VdsatCV * dAbulkCV_dVb / AbulkCV; + VdsatCV += 1e-5; + + V4 = VdsatCV - Vds - DELTA_4; + T0 = sqrt(V4 * V4 + 4.0 * DELTA_4 * VdsatCV); + VdseffCV = VdsatCV - 0.5 * (V4 + T0); + T1 = 0.5 * (1.0 + V4 / T0); + T2 = DELTA_4 / T0; + T3 = (1.0 - T1 - T2) / AbulkCV; + dVdseffCV_dVg = T3; + dVdseffCV_dVd = T1; + dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb; + + if (model->B3SOIFDcapMod == 2) + { + /* VdsCV Make it compatible with capMod 3 */ + VdsCV = VdseffCV; + dVdsCV_dVg = dVdseffCV_dVg; + dVdsCV_dVd = dVdseffCV_dVd; + dVdsCV_dVb = dVdseffCV_dVb; + } + else if (model->B3SOIFDcapMod == 3) + { + /* Front gate strong inversion depletion charge */ + /* VdssatCV calculation */ + + T1 = Vgsteff + K1*sqrtPhis + 0.5*K1*K1; + T2 = Vgsteff + K1*sqrtPhis + Phis + 0.25*K1*K1; + + dT1_dVb = K1*dsqrtPhis_dVb; + dT2_dVb = dT1_dVb + dPhis_dVb; + dT1_dVg = dT2_dVg = 1; + + /* Note VdsatCV is redefined in capMod = 3 */ + VdsatCV = T1 - K1*sqrt(T2); + + dVdsatCV_dVb = dT1_dVb - K1/2/sqrt(T2)*dT2_dVb; + dVdsatCV_dVg = dT1_dVg - K1/2/sqrt(T2)*dT2_dVg; + + T1 = VdsatCV - Vdsat; + dT1_dVg = dVdsatCV_dVg - dVdsat_dVg; + dT1_dVb = dVdsatCV_dVb - dVdsat_dVb; + dT1_dVd = - dVdsat_dVd; + dT1_dVc = - dVdsat_dVc; + dT1_dT = - dVdsat_dT; + + if (!(T1 == 0.0)) + { T3 = -0.5 * Vdsat / T1; /* Vdsmax */ + T2 = T3 * Vdsat; + T4 = T2 + T1 * T3 * T3; /* fmax */ + if ((Vdseff > T2) && (T1 < 0)) + { + VdsCV = T4; + T5 = -0.5 / (T1 * T1); + dT3_dVg = T5 * (T1 * dVdsat_dVg - Vdsat * dT1_dVg); + dT3_dVb = T5 * (T1 * dVdsat_dVb - Vdsat * dT1_dVb); + dT3_dVd = T5 * (T1 * dVdsat_dVd - Vdsat * dT1_dVd); + dT3_dVc=0.0; + if (selfheat) + dT3_dT=T5 * (T1 * dVdsat_dT - Vdsat * dT1_dT); + else dT3_dT=0.0; + + dVdsCV_dVd = T3 * dVdsat_dVd + Vdsat * dT3_dVd + + T3 * (2 * T1 * dT3_dVd + T3 * dT1_dVd); + dVdsCV_dVg = T3 * dVdsat_dVg + Vdsat * dT3_dVg + + T3 * (2 * T1 * dT3_dVg + T3 * dT1_dVg); + dVdsCV_dVb = T3 * dVdsat_dVb + Vdsat * dT3_dVb + + T3 * (2 * T1 * dT3_dVb + T3 * dT1_dVb); + dVdsCV_dVc = 0.0; + if (selfheat) + dVdsCV_dT = T3 * dVdsat_dT + Vdsat * dT3_dT + + T3 * (2 * T1 * dT3_dT + T3 * dT1_dT ); + else dVdsCV_dT = 0.0; + } else + { T5 = Vdseff / Vdsat; + T6 = T5 * T5; + T7 = 2 * T1 * T5 / Vdsat; + T8 = T7 / Vdsat; + VdsCV = Vdseff + T1 * T6; + dVdsCV_dVd = dVdseff_dVd + T8 * + ( Vdsat * dVdseff_dVd + - Vdseff * dVdsat_dVd) + + T6 * dT1_dVd; + dVdsCV_dVb = dVdseff_dVb + T8 * ( Vdsat * + dVdseff_dVb - Vdseff * dVdsat_dVb) + + T6 * dT1_dVb; + dVdsCV_dVg = dVdseff_dVg + T8 * + ( Vdsat * dVdseff_dVg + - Vdseff * dVdsat_dVg) + + T6 * dT1_dVg; + dVdsCV_dVc = 0.0; + if (selfheat) + dVdsCV_dT = dVdseff_dT + T8 * + ( Vdsat * dVdseff_dT + - Vdseff * dVdsat_dT ) + + T6 * dT1_dT ; + else dVdsCV_dT = 0.0; + } + } else + { VdsCV = Vdseff; + dVdsCV_dVb = dVdseff_dVb; + dVdsCV_dVd = dVdseff_dVd; + dVdsCV_dVg = dVdseff_dVg; + dVdsCV_dVc = dVdseff_dVc; + dVdsCV_dT = dVdseff_dT; + } + if (VdsCV < 0.0) VdsCV = 0.0; + VdsCV += 1e-4; + + if (VdsCV > (VdsatCV - 1e-7)) + { + VdsCV = VdsatCV - 1e-7; + } + Phisd = Phis + VdsCV; + dPhisd_dVb = dPhis_dVb + dVdsCV_dVb; + dPhisd_dVd = dVdsCV_dVd; + dPhisd_dVg = dVdsCV_dVg; + dPhisd_dVc = dVdsCV_dVc; + dPhisd_dT = dVdsCV_dT; + sqrtPhisd = sqrt(Phisd); + + /* Qdep0 - Depletion charge at Vgs=Vth */ + T10 = CoxWL * K1; + Qdep0 = T10 * sqrtPhis; + dQdep0_dVb = T10 * dsqrtPhis_dVb; + } /* End of if capMod == 3 */ + + /* Something common in both capMod 2 or 3 */ + + /* Backgate charge */ + CboxWL = pParam->B3SOIFDkb3 * Cbox * pParam->B3SOIFDweffCV + * pParam->B3SOIFDleffCV; + Cbg = Cbb = Cbd = Cbe = CbT = 0.0; + Ce2g = Ce2b = Ce2d = Ce2e = Ce2T = 0.0; + Qbf = Qe2 = 0.0; + + T2 = - 0.5 * model->B3SOIFDcboxt * pParam->B3SOIFDweffCV + * pParam->B3SOIFDleffCV; + Qe1 = T2 * VdsCV - CboxWL * (Vbs0eff - Vesfb); + Ce1g = T2 * (dVdsCV_dVg * dVgsteff_dVg + dVdsCV_dVb * dVbseff_dVg + + dVdsCV_dVc * dVcs_dVg) - CboxWL * dVbs0eff_dVg; + Ce1d = T2 * (dVdsCV_dVg * dVgsteff_dVd + dVdsCV_dVb * dVbseff_dVd + + dVdsCV_dVc * dVcs_dVd + dVdsCV_dVd) + - CboxWL * dVbs0eff_dVd; + Ce1b = 0.0; + Ce1e = T2 * (dVdsCV_dVg * dVgsteff_dVe + dVdsCV_dVb * dVbseff_dVe + + dVdsCV_dVc * dVcs_dVe) + - CboxWL * (dVbs0eff_dVe - 1.0); + if (selfheat) + Ce1T = T2 * (dVdsCV_dVg * dVgsteff_dT + dVdsCV_dVb * dVbseff_dT + + dVdsCV_dVc * dVcs_dT + dVdsCV_dT) + - CboxWL * (dVbs0eff_dT + dvfbb_dT); + else Ce1T = 0.0; + + /* Total inversion charge */ + T0 = AbulkCV * VdseffCV; + T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1e-20); + T2 = VdseffCV / T1; + T3 = T0 * T2; + + T4 = (1.0 - 12.0 * T2 * T2 * AbulkCV); + T5 = (6.0 * T0 * (4.0 * Vgsteff - T0) / (T1 * T1) - 0.5); + T6 = 12.0 * T2 * T2 * Vgsteff; + + qinv = CoxWL * (Vgsteff - 0.5 * VdseffCV + T3); + Cgg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); + Cgd1 = CoxWL * T5 * dVdseffCV_dVd; + Cgb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb); + + /* Inversion charge partitioning into S / D */ + if (model->B3SOIFDxpart > 0.5) + { /* 0/100 Charge partition model */ + T1 = T1 + T1; + qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 + - T0 * T0 / T1); + T7 = (4.0 * Vgsteff - T0) / (T1 * T1); + T4 = -(0.5 + 24.0 * T0 * T0 / (T1 * T1)); + T5 = -(0.25 * AbulkCV - 12.0 * AbulkCV * T0 * T7); + T6 = -(0.25 * VdseffCV - 12.0 * T0 * VdseffCV * T7); + Csg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); + Csd1 = CoxWL * T5 * dVdseffCV_dVd; + Csb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb); + + } + else if (model->B3SOIFDxpart < 0.5) + { /* 40/60 Charge partition model */ + T1 = T1 / 12.0; + T2 = 0.5 * CoxWL / (T1 * T1); + T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff + * (Vgsteff - 4.0 * T0 / 3.0)) + - 2.0 * T0 * T0 * T0 / 15.0; + qsrc = -T2 * T3; + T7 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0) + + 0.4 * T0 * T0; + T4 = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0 + * Vgsteff - 8.0 * T0 / 3.0) + + 2.0 * T0 * T0 / 3.0); + T5 = (qsrc / T1 + T2 * T7) * AbulkCV; + T6 = (qsrc / T1 * VdseffCV + T2 * T7 * VdseffCV); + Csg1 = T4 + T5 * dVdseffCV_dVg; + Csd1 = T5 * dVdseffCV_dVd; + Csb1 = T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb; + } + else + { /* 50/50 Charge partition model */ + qsrc = - 0.5 * qinv; + Csg1 = - 0.5 * Cgg1; + Csb1 = - 0.5 * Cgb1; + Csd1 = - 0.5 * Cgd1; + } + + Csg = Csg1 * dVgsteff_dVg + Csb1 * dVbseff_dVg; + Csd = Csd1 + Csg1 * dVgsteff_dVd + Csb1 * dVbseff_dVd; + Csb = Csg1 * dVgsteff_dVb + Csb1 * dVbseff_dVb; + Cse = Csg1 * dVgsteff_dVe + Csb1 * dVbseff_dVe; + if (selfheat) + CsT = Csg1 * dVgsteff_dT + Csb1 * dVbseff_dT; + else CsT = 0.0; + + Qex=dQex_dVg=dQex_dVb=dQex_dVd=dQex_dVe=dQex_dT=0.0; + + qgate = qinv - (Qbf + Qe2); + qbody = (Qbf - Qe1 + Qex); + qsub = Qe1 + Qe2 - Qex; + qdrn = -(qinv + qsrc); + + Cgg = (Cgg1 * dVgsteff_dVg + Cgb1 * dVbseff_dVg) - Cbg ; + Cgd = (Cgd1 + Cgg1 * dVgsteff_dVd + Cgb1 * dVbseff_dVd)-Cbd; + Cgb = (Cgb1 * dVbseff_dVb + Cgg1 * dVgsteff_dVb) - Cbb; + Cge = (Cgg1 * dVgsteff_dVe + Cgb1 * dVbseff_dVe) - Cbe; + if (selfheat) + CgT = (Cgg1 * dVgsteff_dT + Cgb1 * dVbseff_dT ) - CbT; + else CgT = 0.0; + + here->B3SOIFDcggb = Cgg - Ce2g; + here->B3SOIFDcgsb = - (Cgg + Cgd + Cgb + Cge) + + (Ce2g + Ce2d + Ce2b + Ce2e); + here->B3SOIFDcgdb = Cgd - Ce2d; + here->B3SOIFDcgeb = Cge - Ce2e; + here->B3SOIFDcgT = CgT - Ce2T; + + here->B3SOIFDcbgb = Cbg - Ce1g + dQex_dVg; + here->B3SOIFDcbsb = -(Cbg + Cbd + Cbb + Cbe) + + (Ce1g + Ce1d + Ce1b + Ce1e) + - (dQex_dVg + dQex_dVd + dQex_dVb + dQex_dVe); + here->B3SOIFDcbdb = Cbd - Ce1d + dQex_dVd; + here->B3SOIFDcbeb = Cbe - Ce1e + dQex_dVe; + here->B3SOIFDcbT = CbT - Ce1T + dQex_dT; + + here->B3SOIFDcegb = Ce1g + Ce2g - dQex_dVg; + here->B3SOIFDcesb = -(Ce1g + Ce1d + Ce1b + Ce1e) + -(Ce2g + Ce2d + Ce2b + Ce2e) + +(dQex_dVg + dQex_dVd + dQex_dVb + dQex_dVe); + here->B3SOIFDcedb = Ce1d + Ce2d - dQex_dVd; + here->B3SOIFDceeb = Ce1e + Ce2e - dQex_dVe; + here->B3SOIFDceT = Ce1T + Ce2T - dQex_dT; + + here->B3SOIFDcdgb = -(Cgg + Cbg + Csg); + here->B3SOIFDcddb = -(Cgd + Cbd + Csd); + here->B3SOIFDcdeb = -(Cge + Cbe + Cse); + here->B3SOIFDcdT = -(CgT + CbT + CsT); + here->B3SOIFDcdsb = (Cgg + Cgd + Cgb + Cge + + Cbg + Cbd + Cbb + Cbe + + Csg + Csd + Csb + Cse); + + } /* End of if capMod == 2 or capMod ==3 */ + } + + finished: /* returning Values to Calling Routine */ + /* + * COMPUTE EQUIVALENT DRAIN CURRENT SOURCE + */ + if (ChargeComputationNeeded) + { + qjs = qjd = 0.0; + gcjdds = gcjdbs = gcjdT = 0.0; + gcjsbs = gcjsT = 0.0; + + qdrn -= qjd; + qbody += (qjs + qjd); + qsrc = -(qgate + qbody + qdrn + qsub); + + /* Update the conductance */ + here->B3SOIFDcddb -= gcjdds; + here->B3SOIFDcdT -= gcjdT; + here->B3SOIFDcdsb += gcjdds + gcjdbs; + + here->B3SOIFDcbdb += (gcjdds); + here->B3SOIFDcbT += (gcjdT + gcjsT); + here->B3SOIFDcbsb -= (gcjdds + gcjdbs + gcjsbs); + + /* Extrinsic Bottom S/D to substrate charge */ + T10 = -model->B3SOIFDtype * ves; + /* T10 is vse without type conversion */ + if ( ((pParam->B3SOIFDnsub > 0) && (model->B3SOIFDtype > 0)) || + ((pParam->B3SOIFDnsub < 0) && (model->B3SOIFDtype < 0)) ) + { + if (T10 < pParam->B3SOIFDvsdfb) + { here->B3SOIFDqse = here->B3SOIFDcsbox * (T10 - pParam->B3SOIFDvsdfb); + here->B3SOIFDgcse = here->B3SOIFDcsbox; + } + else if (T10 < pParam->B3SOIFDsdt1) + { T0 = T10 - pParam->B3SOIFDvsdfb; + T1 = T0 * T0; + here->B3SOIFDqse = T0 * (here->B3SOIFDcsbox - + pParam->B3SOIFDst2 / 3 * T1) ; + here->B3SOIFDgcse = here->B3SOIFDcsbox - pParam->B3SOIFDst2 * T1; + } + else if (T10 < pParam->B3SOIFDvsdth) + { T0 = T10 - pParam->B3SOIFDvsdth; + T1 = T0 * T0; + here->B3SOIFDqse = here->B3SOIFDcsmin * T10 + here->B3SOIFDst4 + + pParam->B3SOIFDst3 / 3 * T0 * T1; + here->B3SOIFDgcse = here->B3SOIFDcsmin + pParam->B3SOIFDst3 * T1; + } + else + { here->B3SOIFDqse = here->B3SOIFDcsmin * T10 + here->B3SOIFDst4; + here->B3SOIFDgcse = here->B3SOIFDcsmin; + } + } else + { + if (T10 < pParam->B3SOIFDvsdth) + { here->B3SOIFDqse = here->B3SOIFDcsmin * (T10 - pParam->B3SOIFDvsdth); + here->B3SOIFDgcse = here->B3SOIFDcsmin; + } + else if (T10 < pParam->B3SOIFDsdt1) + { T0 = T10 - pParam->B3SOIFDvsdth; + T1 = T0 * T0; + here->B3SOIFDqse = T0 * (here->B3SOIFDcsmin - pParam->B3SOIFDst2 / 3 * T1) ; + here->B3SOIFDgcse = here->B3SOIFDcsmin - pParam->B3SOIFDst2 * T1; + } + else if (T10 < pParam->B3SOIFDvsdfb) + { T0 = T10 - pParam->B3SOIFDvsdfb; + T1 = T0 * T0; + here->B3SOIFDqse = here->B3SOIFDcsbox * T10 + here->B3SOIFDst4 + + pParam->B3SOIFDst3 / 3 * T0 * T1; + here->B3SOIFDgcse = here->B3SOIFDcsbox + pParam->B3SOIFDst3 * T1; + } + else + { here->B3SOIFDqse = here->B3SOIFDcsbox * T10 + here->B3SOIFDst4; + here->B3SOIFDgcse = here->B3SOIFDcsbox; + } + } + + /* T11 is vde without type conversion */ + T11 = model->B3SOIFDtype * (vds - ves); + if ( ((pParam->B3SOIFDnsub > 0) && (model->B3SOIFDtype > 0)) || + ((pParam->B3SOIFDnsub < 0) && (model->B3SOIFDtype < 0)) ) + { + if (T11 < pParam->B3SOIFDvsdfb) + { here->B3SOIFDqde = here->B3SOIFDcdbox * (T11 - pParam->B3SOIFDvsdfb); + here->B3SOIFDgcde = here->B3SOIFDcdbox; + } + else if (T11 < pParam->B3SOIFDsdt1) + { T0 = T11 - pParam->B3SOIFDvsdfb; + T1 = T0 * T0; + here->B3SOIFDqde = T0 * (here->B3SOIFDcdbox - pParam->B3SOIFDdt2 / 3 * T1) ; + here->B3SOIFDgcde = here->B3SOIFDcdbox - pParam->B3SOIFDdt2 * T1; + } + else if (T11 < pParam->B3SOIFDvsdth) + { T0 = T11 - pParam->B3SOIFDvsdth; + T1 = T0 * T0; + here->B3SOIFDqde = here->B3SOIFDcdmin * T11 + here->B3SOIFDdt4 + + pParam->B3SOIFDdt3 / 3 * T0 * T1; + here->B3SOIFDgcde = here->B3SOIFDcdmin + pParam->B3SOIFDdt3 * T1; + } + else + { here->B3SOIFDqde = here->B3SOIFDcdmin * T11 + here->B3SOIFDdt4; + here->B3SOIFDgcde = here->B3SOIFDcdmin; + } + } else + { + if (T11 < pParam->B3SOIFDvsdth) + { here->B3SOIFDqde = here->B3SOIFDcdmin * (T11 - pParam->B3SOIFDvsdth); + here->B3SOIFDgcde = here->B3SOIFDcdmin; + } + else if (T11 < pParam->B3SOIFDsdt1) + { T0 = T11 - pParam->B3SOIFDvsdth; + T1 = T0 * T0; + here->B3SOIFDqde = T0 * (here->B3SOIFDcdmin - pParam->B3SOIFDdt2 / 3 * T1) ; + here->B3SOIFDgcde = here->B3SOIFDcdmin - pParam->B3SOIFDdt2 * T1; + } + else if (T11 < pParam->B3SOIFDvsdfb) + { T0 = T11 - pParam->B3SOIFDvsdfb; + T1 = T0 * T0; + here->B3SOIFDqde = here->B3SOIFDcdbox * T11 + here->B3SOIFDdt4 + + pParam->B3SOIFDdt3 / 3 * T0 * T1; + here->B3SOIFDgcde = here->B3SOIFDcdbox + pParam->B3SOIFDdt3 * T1; + } + else + { here->B3SOIFDqde = here->B3SOIFDcdbox * T11 + here->B3SOIFDdt4; + here->B3SOIFDgcde = here->B3SOIFDcdbox; + } + } + + /* Extrinsic : Sidewall fringing S/D charge */ + here->B3SOIFDqse += pParam->B3SOIFDcsesw * T10; + here->B3SOIFDgcse += pParam->B3SOIFDcsesw; + here->B3SOIFDqde += pParam->B3SOIFDcdesw * T11; + here->B3SOIFDgcde += pParam->B3SOIFDcdesw; + + /* All charge are mutliplied with type at the end, but qse and qde + have true polarity => so pre-mutliplied with type */ + here->B3SOIFDqse *= model->B3SOIFDtype; + here->B3SOIFDqde *= model->B3SOIFDtype; + } + + here->B3SOIFDxc = Xc; + here->B3SOIFDcbb = Cbb; + here->B3SOIFDcbd = Cbd; + here->B3SOIFDcbg = Cbg; + here->B3SOIFDqbf = Qbf; + here->B3SOIFDqjs = qjs; + here->B3SOIFDqjd = qjd; + + if (here->B3SOIFDdebugMod == -1) + ChargeComputationNeeded = 0; + + /* + * check convergence + */ + if ((here->B3SOIFDoff == 0) || (!(ckt->CKTmode & MODEINITFIX))) + { if (Check == 1) + { ckt->CKTnoncon++; +if (here->B3SOIFDdebugMod > 2) + fprintf(fpdebug, "Check is on, noncon=%d\n", ckt->CKTnoncon++); + } + } + + *(ckt->CKTstate0 + here->B3SOIFDvg) = vg; + *(ckt->CKTstate0 + here->B3SOIFDvd) = vd; + *(ckt->CKTstate0 + here->B3SOIFDvs) = vs; + *(ckt->CKTstate0 + here->B3SOIFDvp) = vp; + *(ckt->CKTstate0 + here->B3SOIFDve) = ve; + + *(ckt->CKTstate0 + here->B3SOIFDvbs) = vbs; + *(ckt->CKTstate0 + here->B3SOIFDvbd) = vbd; + *(ckt->CKTstate0 + here->B3SOIFDvgs) = vgs; + *(ckt->CKTstate0 + here->B3SOIFDvds) = vds; + *(ckt->CKTstate0 + here->B3SOIFDves) = ves; + *(ckt->CKTstate0 + here->B3SOIFDvps) = vps; + *(ckt->CKTstate0 + here->B3SOIFDdeltemp) = delTemp; + + /* bulk and channel charge plus overlaps */ + + if (!ChargeComputationNeeded) + goto line850; + + line755: + ag0 = ckt->CKTag[0]; + + T0 = vgd + DELTA_1; + T1 = sqrt(T0 * T0 + 4.0 * DELTA_1); + T2 = 0.5 * (T0 - T1); + + T3 = pParam->B3SOIFDweffCV * pParam->B3SOIFDcgdl; + T4 = sqrt(1.0 - 4.0 * T2 / pParam->B3SOIFDckappa); + cgdo = pParam->B3SOIFDcgdo + T3 - T3 * (1.0 - 1.0 / T4) + * (0.5 - 0.5 * T0 / T1); + qgdo = (pParam->B3SOIFDcgdo + T3) * vgd - T3 * (T2 + + 0.5 * pParam->B3SOIFDckappa * (T4 - 1.0)); + + T0 = vgs + DELTA_1; + T1 = sqrt(T0 * T0 + 4.0 * DELTA_1); + T2 = 0.5 * (T0 - T1); + T3 = pParam->B3SOIFDweffCV * pParam->B3SOIFDcgsl; + T4 = sqrt(1.0 - 4.0 * T2 / pParam->B3SOIFDckappa); + cgso = pParam->B3SOIFDcgso + T3 - T3 * (1.0 - 1.0 / T4) + * (0.5 - 0.5 * T0 / T1); + qgso = (pParam->B3SOIFDcgso + T3) * vgs - T3 * (T2 + + 0.5 * pParam->B3SOIFDckappa * (T4 - 1.0)); + + + if (here->B3SOIFDmode > 0) + { gcdgb = (here->B3SOIFDcdgb - cgdo) * ag0; + gcddb = (here->B3SOIFDcddb + cgdo + here->B3SOIFDgcde) * ag0; + gcdsb = here->B3SOIFDcdsb * ag0; + gcdeb = (here->B3SOIFDcdeb - here->B3SOIFDgcde) * ag0; + gcdT = model->B3SOIFDtype * here->B3SOIFDcdT * ag0; + + gcsgb = -(here->B3SOIFDcggb + here->B3SOIFDcbgb + here->B3SOIFDcdgb + + here->B3SOIFDcegb + cgso) * ag0; + gcsdb = -(here->B3SOIFDcgdb + here->B3SOIFDcbdb + here->B3SOIFDcddb + + here->B3SOIFDcedb) * ag0; + gcssb = (cgso + here->B3SOIFDgcse - (here->B3SOIFDcgsb + here->B3SOIFDcbsb + + here->B3SOIFDcdsb + here->B3SOIFDcesb)) * ag0; + gcseb = -(here->B3SOIFDgcse + here->B3SOIFDcgeb + here->B3SOIFDcbeb + here->B3SOIFDcdeb + + here->B3SOIFDceeb) * ag0; + gcsT = - model->B3SOIFDtype * (here->B3SOIFDcgT + here->B3SOIFDcbT + here->B3SOIFDcdT + + here->B3SOIFDceT) * ag0; + + gcggb = (here->B3SOIFDcggb + cgdo + cgso + pParam->B3SOIFDcgeo) * ag0; + gcgdb = (here->B3SOIFDcgdb - cgdo) * ag0; + gcgsb = (here->B3SOIFDcgsb - cgso) * ag0; + gcgeb = (here->B3SOIFDcgeb - pParam->B3SOIFDcgeo) * ag0; + gcgT = model->B3SOIFDtype * here->B3SOIFDcgT * ag0; + + gcbgb = here->B3SOIFDcbgb * ag0; + gcbdb = here->B3SOIFDcbdb * ag0; + gcbsb = here->B3SOIFDcbsb * ag0; + gcbeb = here->B3SOIFDcbeb * ag0; + gcbT = model->B3SOIFDtype * here->B3SOIFDcbT * ag0; + + gcegb = (here->B3SOIFDcegb - pParam->B3SOIFDcgeo) * ag0; + gcedb = (here->B3SOIFDcedb - here->B3SOIFDgcde) * ag0; + gcesb = (here->B3SOIFDcesb - here->B3SOIFDgcse) * ag0; + gceeb = (here->B3SOIFDgcse + here->B3SOIFDgcde + + here->B3SOIFDceeb + pParam->B3SOIFDcgeo) * ag0; + + gceT = model->B3SOIFDtype * here->B3SOIFDceT * ag0; + + gcTt = pParam->B3SOIFDcth * ag0; + + sxpart = 0.6; + dxpart = 0.4; + + /* Lump the overlap capacitance and S/D parasitics */ + qgd = qgdo; + qgs = qgso; + qge = pParam->B3SOIFDcgeo * vge; + qgate += qgd + qgs + qge; + qdrn += here->B3SOIFDqde - qgd; + qsub -= qge + here->B3SOIFDqse + here->B3SOIFDqde; + qsrc = -(qgate + qbody + qdrn + qsub); + } + else + { gcsgb = (here->B3SOIFDcdgb - cgso) * ag0; + gcssb = (here->B3SOIFDcddb + cgso + here->B3SOIFDgcse) * ag0; + gcsdb = here->B3SOIFDcdsb * ag0; + gcseb = (here->B3SOIFDcdeb - here->B3SOIFDgcse) * ag0; + gcsT = model->B3SOIFDtype * here->B3SOIFDcdT * ag0; + + gcdgb = -(here->B3SOIFDcggb + here->B3SOIFDcbgb + here->B3SOIFDcdgb + + here->B3SOIFDcegb + cgdo) * ag0; + gcdsb = -(here->B3SOIFDcgdb + here->B3SOIFDcbdb + here->B3SOIFDcddb + + here->B3SOIFDcedb) * ag0; + gcddb = (cgdo + here->B3SOIFDgcde - (here->B3SOIFDcgsb + here->B3SOIFDcbsb + + here->B3SOIFDcdsb + here->B3SOIFDcesb)) * ag0; + gcdeb = -(here->B3SOIFDgcde + here->B3SOIFDcgeb + here->B3SOIFDcbeb + here->B3SOIFDcdeb + + here->B3SOIFDceeb) * ag0; + gcdT = - model->B3SOIFDtype * (here->B3SOIFDcgT + here->B3SOIFDcbT + + here->B3SOIFDcdT + here->B3SOIFDceT) * ag0; + + gcggb = (here->B3SOIFDcggb + cgdo + cgso + pParam->B3SOIFDcgeo) * ag0; + gcgsb = (here->B3SOIFDcgdb - cgso) * ag0; + gcgdb = (here->B3SOIFDcgsb - cgdo) * ag0; + gcgeb = (here->B3SOIFDcgeb - pParam->B3SOIFDcgeo) * ag0; + gcgT = model->B3SOIFDtype * here->B3SOIFDcgT * ag0; + + gcbgb = here->B3SOIFDcbgb * ag0; + gcbsb = here->B3SOIFDcbdb * ag0; + gcbdb = here->B3SOIFDcbsb * ag0; + gcbeb = here->B3SOIFDcbeb * ag0; + gcbT = model->B3SOIFDtype * here->B3SOIFDcbT * ag0; + + gcegb = (here->B3SOIFDcegb - pParam->B3SOIFDcgeo) * ag0; + gcesb = (here->B3SOIFDcedb - here->B3SOIFDgcse) * ag0; + gcedb = (here->B3SOIFDcesb - here->B3SOIFDgcde) * ag0; + gceeb = (here->B3SOIFDceeb + pParam->B3SOIFDcgeo + + here->B3SOIFDgcse + here->B3SOIFDgcde) * ag0; + gceT = model->B3SOIFDtype * here->B3SOIFDceT * ag0; + + gcTt = pParam->B3SOIFDcth * ag0; + + dxpart = 0.6; + sxpart = 0.4; + + /* Lump the overlap capacitance */ + qgd = qgdo; + qgs = qgso; + qge = pParam->B3SOIFDcgeo * vge; + qgate += qgd + qgs + qge; + qsrc = qdrn - qgs + here->B3SOIFDqse; + qsub -= qge + here->B3SOIFDqse + here->B3SOIFDqde; + qdrn = -(qgate + qbody + qsrc + qsub); + } + + here->B3SOIFDcgdo = cgdo; + here->B3SOIFDcgso = cgso; + + if (ByPass) goto line860; + + *(ckt->CKTstate0 + here->B3SOIFDqe) = qsub; + *(ckt->CKTstate0 + here->B3SOIFDqg) = qgate; + *(ckt->CKTstate0 + here->B3SOIFDqd) = qdrn; + *(ckt->CKTstate0 + here->B3SOIFDqb) = qbody; + if ((model->B3SOIFDshMod == 1) && (here->B3SOIFDrth0!=0.0)) + *(ckt->CKTstate0 + here->B3SOIFDqth) = pParam->B3SOIFDcth * delTemp; + + + /* store small signal parameters */ + if (ckt->CKTmode & MODEINITSMSIG) + { goto line1000; + } + if (!ChargeComputationNeeded) + goto line850; + + + if (ckt->CKTmode & MODEINITTRAN) + { *(ckt->CKTstate1 + here->B3SOIFDqb) = + *(ckt->CKTstate0 + here->B3SOIFDqb); + *(ckt->CKTstate1 + here->B3SOIFDqg) = + *(ckt->CKTstate0 + here->B3SOIFDqg); + *(ckt->CKTstate1 + here->B3SOIFDqd) = + *(ckt->CKTstate0 + here->B3SOIFDqd); + *(ckt->CKTstate1 + here->B3SOIFDqe) = + *(ckt->CKTstate0 + here->B3SOIFDqe); + *(ckt->CKTstate1 + here->B3SOIFDqth) = + *(ckt->CKTstate0 + here->B3SOIFDqth); + } + + error = NIintegrate(ckt, &geq, &ceq,0.0,here->B3SOIFDqb); + if (error) return(error); + error = NIintegrate(ckt, &geq, &ceq, 0.0, here->B3SOIFDqg); + if (error) return(error); + error = NIintegrate(ckt,&geq, &ceq, 0.0, here->B3SOIFDqd); + if (error) return(error); + error = NIintegrate(ckt,&geq, &ceq, 0.0, here->B3SOIFDqe); + if (error) return(error); + if ((model->B3SOIFDshMod == 1) && (here->B3SOIFDrth0!=0.0)) + { + error = NIintegrate(ckt, &geq, &ceq, 0.0, here->B3SOIFDqth); + if (error) return (error); + } + + goto line860; + + line850: + /* initialize to zero charge conductance and current */ + ceqqe = ceqqg = ceqqb = ceqqd = ceqqth= 0.0; + + gcdgb = gcddb = gcdsb = gcdeb = gcdT = 0.0; + gcsgb = gcsdb = gcssb = gcseb = gcsT = 0.0; + gcggb = gcgdb = gcgsb = gcgeb = gcgT = 0.0; + gcbgb = gcbdb = gcbsb = gcbeb = gcbT = 0.0; + gcegb = gcedb = gceeb = gcesb = gceT = 0.0; + gcTt = 0.0; + + sxpart = (1.0 - (dxpart = (here->B3SOIFDmode > 0) ? 0.4 : 0.6)); + + goto line900; + + line860: + /* evaluate equivalent charge current */ + + cqgate = *(ckt->CKTstate0 + here->B3SOIFDcqg); + cqbody = *(ckt->CKTstate0 + here->B3SOIFDcqb); + cqdrn = *(ckt->CKTstate0 + here->B3SOIFDcqd); + cqsub = *(ckt->CKTstate0 + here->B3SOIFDcqe); + cqtemp = *(ckt->CKTstate0 + here->B3SOIFDcqth); + + here->B3SOIFDcb += cqbody; + here->B3SOIFDcd += cqdrn; + + ceqqg = cqgate - gcggb * vgb + gcgdb * vbd + gcgsb * vbs + - gcgeb * veb - gcgT * delTemp; + ceqqb = cqbody - gcbgb * vgb + gcbdb * vbd + gcbsb * vbs + - gcbeb * veb - gcbT * delTemp; + ceqqd = cqdrn - gcdgb * vgb + gcddb * vbd + gcdsb * vbs + - gcdeb * veb - gcdT * delTemp; + ceqqe = cqsub - gcegb * vgb + gcedb * vbd + gcesb * vbs + - gceeb * veb - gceT * delTemp;; + ceqqth = cqtemp - gcTt * delTemp; + + if (ckt->CKTmode & MODEINITTRAN) + { *(ckt->CKTstate1 + here->B3SOIFDcqe) = + *(ckt->CKTstate0 + here->B3SOIFDcqe); + *(ckt->CKTstate1 + here->B3SOIFDcqb) = + *(ckt->CKTstate0 + here->B3SOIFDcqb); + *(ckt->CKTstate1 + here->B3SOIFDcqg) = + *(ckt->CKTstate0 + here->B3SOIFDcqg); + *(ckt->CKTstate1 + here->B3SOIFDcqd) = + *(ckt->CKTstate0 + here->B3SOIFDcqd); + *(ckt->CKTstate1 + here->B3SOIFDcqth) = + *(ckt->CKTstate0 + here->B3SOIFDcqth); + } + + /* + * load current vector + */ + line900: + + if (here->B3SOIFDmode >= 0) + { Gm = here->B3SOIFDgm; + Gmbs = here->B3SOIFDgmbs; + Gme = here->B3SOIFDgme; + GmT = model->B3SOIFDtype * here->B3SOIFDgmT; + FwdSum = Gm + Gmbs + Gme; + RevSum = 0.0; + cdreq = model->B3SOIFDtype * (here->B3SOIFDcdrain - here->B3SOIFDgds * vds + - Gm * vgs - Gmbs * vbs - Gme * ves - GmT * delTemp); + /* ceqbs now is compatible with cdreq, ie. going in is +ve */ + /* Equivalent current source from the diode */ + ceqbs = here->B3SOIFDcjs; + ceqbd = here->B3SOIFDcjd; + /* Current going in is +ve */ + ceqbody = -here->B3SOIFDcbody; + ceqth = here->B3SOIFDcth; + ceqbodcon = here->B3SOIFDcbodcon; + + gbbg = -here->B3SOIFDgbgs; + gbbdp = -here->B3SOIFDgbds; + gbbb = -here->B3SOIFDgbbs; + gbbe = -here->B3SOIFDgbes; + gbbp = -here->B3SOIFDgbps; + gbbT = -model->B3SOIFDtype * here->B3SOIFDgbT; + gbbsp = - ( gbbg + gbbdp + gbbb + gbbe + gbbp); + + gddpg = -here->B3SOIFDgjdg; + gddpdp = -here->B3SOIFDgjdd; + gddpb = -here->B3SOIFDgjdb; + gddpe = -here->B3SOIFDgjde; + gddpT = -model->B3SOIFDtype * here->B3SOIFDgjdT; + gddpsp = - ( gddpg + gddpdp + gddpb + gddpe); + + gsspg = -here->B3SOIFDgjsg; + gsspdp = -here->B3SOIFDgjsd; + gsspb = -here->B3SOIFDgjsb; + gsspe = 0.0; + gsspT = -model->B3SOIFDtype * here->B3SOIFDgjsT; + gsspsp = - (gsspg + gsspdp + gsspb + gsspe); + + gppg = -here->B3SOIFDgbpgs; + gppdp = -here->B3SOIFDgbpds; + gppb = -here->B3SOIFDgbpbs; + gppe = -here->B3SOIFDgbpes; + gppp = -here->B3SOIFDgbpps; + gppT = -model->B3SOIFDtype * here->B3SOIFDgbpT; + gppsp = - (gppg + gppdp + gppb + gppe + gppp); + + gTtg = here->B3SOIFDgtempg; + gTtb = here->B3SOIFDgtempb; + gTte = here->B3SOIFDgtempe; + gTtdp = here->B3SOIFDgtempd; + gTtt = here->B3SOIFDgtempT; + gTtsp = - (gTtg + gTtb + gTte + gTtdp); + } + else + { Gm = -here->B3SOIFDgm; + Gmbs = -here->B3SOIFDgmbs; + Gme = -here->B3SOIFDgme; + GmT = -model->B3SOIFDtype * here->B3SOIFDgmT; + FwdSum = 0.0; + RevSum = -(Gm + Gmbs + Gme); + cdreq = -model->B3SOIFDtype * (here->B3SOIFDcdrain + here->B3SOIFDgds*vds + + Gm * vgd + Gmbs * vbd + Gme * (ves - vds) + GmT * delTemp); + ceqbs = here->B3SOIFDcjd; + ceqbd = here->B3SOIFDcjs; + /* Current going in is +ve */ + ceqbody = -here->B3SOIFDcbody; + ceqth = here->B3SOIFDcth; + ceqbodcon = here->B3SOIFDcbodcon; + + gbbg = -here->B3SOIFDgbgs; + gbbb = -here->B3SOIFDgbbs; + gbbe = -here->B3SOIFDgbes; + gbbp = -here->B3SOIFDgbps; + gbbsp = -here->B3SOIFDgbds; + gbbT = -model->B3SOIFDtype * here->B3SOIFDgbT; + gbbdp = - ( gbbg + gbbsp + gbbb + gbbe + gbbp); + + gddpg = -here->B3SOIFDgjsg; + gddpsp = -here->B3SOIFDgjsd; + gddpb = -here->B3SOIFDgjsb; + gddpe = 0.0; + gddpT = -model->B3SOIFDtype * here->B3SOIFDgjsT; + gddpdp = - (gddpg + gddpsp + gddpb + gddpe); + + gsspg = -here->B3SOIFDgjdg; + gsspsp = -here->B3SOIFDgjdd; + gsspb = -here->B3SOIFDgjdb; + gsspe = -here->B3SOIFDgjde; + gsspT = -model->B3SOIFDtype * here->B3SOIFDgjdT; + gsspdp = - ( gsspg + gsspsp + gsspb + gsspe); + + gppg = -here->B3SOIFDgbpgs; + gppsp = -here->B3SOIFDgbpds; + gppb = -here->B3SOIFDgbpbs; + gppe = -here->B3SOIFDgbpes; + gppp = -here->B3SOIFDgbpps; + gppT = -model->B3SOIFDtype * here->B3SOIFDgbpT; + gppdp = - (gppg + gppsp + gppb + gppe + gppp); + + gTtg = here->B3SOIFDgtempg; + gTtb = here->B3SOIFDgtempb; + gTte = here->B3SOIFDgtempe; + gTtsp = here->B3SOIFDgtempd; + gTtt = here->B3SOIFDgtempT; + gTtdp = - (gTtg + gTtb + gTte + gTtsp); + } + + if (model->B3SOIFDtype > 0) + { + ceqqg = ceqqg; + ceqqb = ceqqb; + ceqqe = ceqqe; + ceqqd = ceqqd; + } + else + { + ceqbodcon = -ceqbodcon; + ceqbody = -ceqbody; + ceqbs = -ceqbs; + ceqbd = -ceqbd; + ceqqg = -ceqqg; + ceqqb = -ceqqb; + ceqqd = -ceqqd; + ceqqe = -ceqqe; + } + + (*(ckt->CKTrhs + here->B3SOIFDgNode) -= ceqqg); + (*(ckt->CKTrhs + here->B3SOIFDdNodePrime) += (ceqbd - cdreq - ceqqd)); + (*(ckt->CKTrhs + here->B3SOIFDsNodePrime) += (cdreq + ceqbs + ceqqg + + ceqqb + ceqqd + ceqqe)); + (*(ckt->CKTrhs + here->B3SOIFDeNode) -= ceqqe); + + if (here->B3SOIFDbodyMod == 1) { + (*(ckt->CKTrhs + here->B3SOIFDpNode) += ceqbodcon); + } + + if (selfheat) { + (*(ckt->CKTrhs + here->B3SOIFDtempNode) -= ceqth + ceqqth); + } + + + + if ((here->B3SOIFDdebugMod > 1) || (here->B3SOIFDdebugMod == -1)) + { + *(ckt->CKTrhs + here->B3SOIFDvbsNode) = here->B3SOIFDvbsdio; + *(ckt->CKTrhs + here->B3SOIFDidsNode) = here->B3SOIFDids; + *(ckt->CKTrhs + here->B3SOIFDicNode) = here->B3SOIFDic; + *(ckt->CKTrhs + here->B3SOIFDibsNode) = here->B3SOIFDibs; + *(ckt->CKTrhs + here->B3SOIFDibdNode) = here->B3SOIFDibd; + *(ckt->CKTrhs + here->B3SOIFDiiiNode) = here->B3SOIFDiii; + *(ckt->CKTrhs + here->B3SOIFDigidlNode) = here->B3SOIFDigidl; + *(ckt->CKTrhs + here->B3SOIFDitunNode) = here->B3SOIFDitun; + *(ckt->CKTrhs + here->B3SOIFDibpNode) = here->B3SOIFDibp; + *(ckt->CKTrhs + here->B3SOIFDabeffNode) = here->B3SOIFDabeff; + *(ckt->CKTrhs + here->B3SOIFDvbs0effNode) = here->B3SOIFDvbs0eff; + *(ckt->CKTrhs + here->B3SOIFDvbseffNode) = here->B3SOIFDvbseff; + *(ckt->CKTrhs + here->B3SOIFDxcNode) = here->B3SOIFDxc; + *(ckt->CKTrhs + here->B3SOIFDcbbNode) = here->B3SOIFDcbb; + *(ckt->CKTrhs + here->B3SOIFDcbdNode) = here->B3SOIFDcbd; + *(ckt->CKTrhs + here->B3SOIFDcbgNode) = here->B3SOIFDcbg; + *(ckt->CKTrhs + here->B3SOIFDqbfNode) = here->B3SOIFDqbf; + *(ckt->CKTrhs + here->B3SOIFDqjsNode) = here->B3SOIFDqjs; + *(ckt->CKTrhs + here->B3SOIFDqjdNode) = here->B3SOIFDqjd; + + /* clean up last */ + *(ckt->CKTrhs + here->B3SOIFDgmNode) = Gm; + *(ckt->CKTrhs + here->B3SOIFDgmbsNode) = Gmbs; + *(ckt->CKTrhs + here->B3SOIFDgdsNode) = Gds; + *(ckt->CKTrhs + here->B3SOIFDgmeNode) = Gme; + *(ckt->CKTrhs + here->B3SOIFDqdNode) = qdrn; + *(ckt->CKTrhs + here->B3SOIFDcbeNode) = Cbe; + *(ckt->CKTrhs + here->B3SOIFDvbs0teffNode) = Vbs0teff; + *(ckt->CKTrhs + here->B3SOIFDvthNode) = here->B3SOIFDvon; + *(ckt->CKTrhs + here->B3SOIFDvgsteffNode) = Vgsteff; + *(ckt->CKTrhs + here->B3SOIFDxcsatNode) = Xcsat; + *(ckt->CKTrhs + here->B3SOIFDqaccNode) = -Qac0; + *(ckt->CKTrhs + here->B3SOIFDqsub0Node) = Qsub0; + *(ckt->CKTrhs + here->B3SOIFDqsubs1Node) = Qsubs1; + *(ckt->CKTrhs + here->B3SOIFDqsubs2Node) = Qsubs2; + *(ckt->CKTrhs + here->B3SOIFDvdscvNode) = VdsCV; + *(ckt->CKTrhs + here->B3SOIFDvcscvNode) = VcsCV; + *(ckt->CKTrhs + here->B3SOIFDqgNode) = qgate; + *(ckt->CKTrhs + here->B3SOIFDqbNode) = qbody; + *(ckt->CKTrhs + here->B3SOIFDqeNode) = qsub; + *(ckt->CKTrhs + here->B3SOIFDdum1Node) = here->B3SOIFDdum1; + *(ckt->CKTrhs + here->B3SOIFDdum2Node) = here->B3SOIFDdum2; + *(ckt->CKTrhs + here->B3SOIFDdum3Node) = here->B3SOIFDdum3; + *(ckt->CKTrhs + here->B3SOIFDdum4Node) = here->B3SOIFDdum4; + *(ckt->CKTrhs + here->B3SOIFDdum5Node) = here->B3SOIFDdum5; + /* end clean up last */ + } + + + /* + * load y matrix + */ + (*(here->B3SOIFDEgPtr) += gcegb); + (*(here->B3SOIFDEdpPtr) += gcedb); + (*(here->B3SOIFDEspPtr) += gcesb); + (*(here->B3SOIFDGePtr) += gcgeb); + (*(here->B3SOIFDDPePtr) += Gme + gddpe + gcdeb); + (*(here->B3SOIFDSPePtr) += gsspe - Gme + gcseb); + + (*(here->B3SOIFDEePtr) += gceeb); + + (*(here->B3SOIFDGgPtr) += gcggb + ckt->CKTgmin); + (*(here->B3SOIFDGdpPtr) += gcgdb - ckt->CKTgmin); + (*(here->B3SOIFDGspPtr) += gcgsb ); + + (*(here->B3SOIFDDPgPtr) += (Gm + gcdgb) + gddpg - ckt->CKTgmin); + (*(here->B3SOIFDDPdpPtr) += (here->B3SOIFDdrainConductance + + here->B3SOIFDgds + gddpdp + + RevSum + gcddb) + ckt->CKTgmin); + (*(here->B3SOIFDDPspPtr) -= (-gddpsp + here->B3SOIFDgds + FwdSum - gcdsb)); + + (*(here->B3SOIFDDPdPtr) -= here->B3SOIFDdrainConductance); + + (*(here->B3SOIFDSPgPtr) += gcsgb - Gm + gsspg ); + (*(here->B3SOIFDSPdpPtr) -= (here->B3SOIFDgds - gsspdp + RevSum - gcsdb)); + (*(here->B3SOIFDSPspPtr) += (here->B3SOIFDsourceConductance + + here->B3SOIFDgds + gsspsp + + FwdSum + gcssb)); + (*(here->B3SOIFDSPsPtr) -= here->B3SOIFDsourceConductance); + + + (*(here->B3SOIFDDdPtr) += here->B3SOIFDdrainConductance); + (*(here->B3SOIFDDdpPtr) -= here->B3SOIFDdrainConductance); + + + (*(here->B3SOIFDSsPtr) += here->B3SOIFDsourceConductance); + (*(here->B3SOIFDSspPtr) -= here->B3SOIFDsourceConductance); + + if (here->B3SOIFDbodyMod == 1) { + (*(here->B3SOIFDBpPtr) -= gppp); + (*(here->B3SOIFDPbPtr) += gppb); + (*(here->B3SOIFDPpPtr) += gppp); + (*(here->B3SOIFDPgPtr) += gppg); + (*(here->B3SOIFDPdpPtr) += gppdp); + (*(here->B3SOIFDPspPtr) += gppsp); + (*(here->B3SOIFDPePtr) += gppe); + } + + if (selfheat) + { + (*(here->B3SOIFDDPtempPtr) += GmT + gddpT + gcdT); + (*(here->B3SOIFDSPtempPtr) += -GmT + gsspT + gcsT); + (*(here->B3SOIFDBtempPtr) += gbbT + gcbT); + (*(here->B3SOIFDEtempPtr) += gceT); + (*(here->B3SOIFDGtempPtr) += gcgT); + if (here->B3SOIFDbodyMod == 1) { + (*(here->B3SOIFDPtempPtr) += gppT); + } + (*(here->B3SOIFDTemptempPtr) += gTtt + 1/pParam->B3SOIFDrth + gcTt); + (*(here->B3SOIFDTempgPtr) += gTtg); + (*(here->B3SOIFDTempbPtr) += gTtb); + (*(here->B3SOIFDTempePtr) += gTte); + (*(here->B3SOIFDTempdpPtr) += gTtdp); + (*(here->B3SOIFDTempspPtr) += gTtsp); + } + + if ((here->B3SOIFDdebugMod > 1) || (here->B3SOIFDdebugMod == -1)) + { + *(here->B3SOIFDVbsPtr) += 1; + *(here->B3SOIFDIdsPtr) += 1; + *(here->B3SOIFDIcPtr) += 1; + *(here->B3SOIFDIbsPtr) += 1; + *(here->B3SOIFDIbdPtr) += 1; + *(here->B3SOIFDIiiPtr) += 1; + *(here->B3SOIFDIgidlPtr) += 1; + *(here->B3SOIFDItunPtr) += 1; + *(here->B3SOIFDIbpPtr) += 1; + *(here->B3SOIFDAbeffPtr) += 1; + *(here->B3SOIFDVbs0effPtr) += 1; + *(here->B3SOIFDVbseffPtr) += 1; + *(here->B3SOIFDXcPtr) += 1; + *(here->B3SOIFDCbgPtr) += 1; + *(here->B3SOIFDCbbPtr) += 1; + *(here->B3SOIFDCbdPtr) += 1; + *(here->B3SOIFDqbPtr) += 1; + *(here->B3SOIFDQbfPtr) += 1; + *(here->B3SOIFDQjsPtr) += 1; + *(here->B3SOIFDQjdPtr) += 1; + + /* clean up last */ + *(here->B3SOIFDGmPtr) += 1; + *(here->B3SOIFDGmbsPtr) += 1; + *(here->B3SOIFDGdsPtr) += 1; + *(here->B3SOIFDGmePtr) += 1; + *(here->B3SOIFDVbs0teffPtr) += 1; + *(here->B3SOIFDVgsteffPtr) += 1; + *(here->B3SOIFDCbePtr) += 1; + *(here->B3SOIFDVthPtr) += 1; + *(here->B3SOIFDXcsatPtr) += 1; + *(here->B3SOIFDVdscvPtr) += 1; + *(here->B3SOIFDVcscvPtr) += 1; + *(here->B3SOIFDQaccPtr) += 1; + *(here->B3SOIFDQsub0Ptr) += 1; + *(here->B3SOIFDQsubs1Ptr) += 1; + *(here->B3SOIFDQsubs2Ptr) += 1; + *(here->B3SOIFDqgPtr) += 1; + *(here->B3SOIFDqdPtr) += 1; + *(here->B3SOIFDqePtr) += 1; + *(here->B3SOIFDDum1Ptr) += 1; + *(here->B3SOIFDDum2Ptr) += 1; + *(here->B3SOIFDDum3Ptr) += 1; + *(here->B3SOIFDDum4Ptr) += 1; + *(here->B3SOIFDDum5Ptr) += 1; + /* end clean up last */ + } + + line1000: ; + +/* Here NaN will be detected in any conductance or equivalent current. Note + that nandetect is initialized within the "if" statements */ + + if (nandetect = isnan (*(here->B3SOIFDGgPtr))) + { strcpy (nanmessage, "GgPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDGdpPtr))) + { strcpy (nanmessage, "GdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDGspPtr))) + { strcpy (nanmessage, "GspPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDDPgPtr))) + { strcpy (nanmessage, "DPgPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDDPdpPtr))) + { strcpy (nanmessage, "DPdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDDPspPtr))) + { strcpy (nanmessage, "DPspPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDSPgPtr))) + { strcpy (nanmessage, "SPgPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDSPdpPtr))) + { strcpy (nanmessage, "SPdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDSPspPtr))) + { strcpy (nanmessage, "SPspPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDEePtr))) + { strcpy (nanmessage, "EePtr"); } + + /* At this point, nandetect = 0 if none of the + conductances checked so far are NaN */ + + if (nandetect == 0) + { + if (nandetect = isnan (*(here->B3SOIFDEgPtr))) + { strcpy (nanmessage, "EgPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDEdpPtr))) + { strcpy (nanmessage, "EdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDEspPtr))) + { strcpy (nanmessage, "EspPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDGePtr))) + { strcpy (nanmessage, "GePtr"); } + else if (nandetect = isnan (*(here->B3SOIFDDPePtr))) + { strcpy (nanmessage, "DPePtr"); } + else if (nandetect = isnan (*(here->B3SOIFDSPePtr))) + { strcpy (nanmessage, "SPePtr"); } } + + /* Now check if self-heating caused NaN if nothing else + has so far (check tempnode current also) */ + + if (selfheat && nandetect == 0) + { + if (nandetect = isnan (*(here->B3SOIFDTemptempPtr))) + { strcpy (nanmessage, "TemptempPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDTempgPtr))) + { strcpy (nanmessage, "TempgPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDTempbPtr))) + { strcpy (nanmessage, "TempbPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDTempePtr))) + { strcpy (nanmessage, "TempePtr"); } + else if (nandetect = isnan (*(here->B3SOIFDTempdpPtr))) + { strcpy (nanmessage, "TempdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDTempspPtr))) + { strcpy (nanmessage, "TempspPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDGtempPtr))) + { strcpy (nanmessage, "GtempPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDDPtempPtr))) + { strcpy (nanmessage, "DPtempPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDSPtempPtr))) + { strcpy (nanmessage, "SPtempPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDEtempPtr))) + { strcpy (nanmessage, "EtempPtr"); } + else if (nandetect = isnan (*(here->B3SOIFDBtempPtr))) + { strcpy (nanmessage, "BtempPtr"); } + else if (nandetect = isnan (*(ckt->CKTrhs + here->B3SOIFDtempNode))) + { strcpy (nanmessage, "tempNode"); } + } + + /* Lastly, check all equivalent currents (tempnode is + checked above */ + + if (nandetect == 0) + { + if (nandetect = isnan (*(ckt->CKTrhs + + here->B3SOIFDgNode))) + { strcpy (nanmessage, "gNode"); } + else if (nandetect = isnan (*(ckt->CKTrhs + + here->B3SOIFDbNode))) + { strcpy (nanmessage, "bNode"); } + else if (nandetect = isnan (*(ckt->CKTrhs + + here->B3SOIFDdNodePrime))) + { strcpy (nanmessage, "dpNode"); } + else if (nandetect = isnan (*(ckt->CKTrhs + + here->B3SOIFDsNodePrime))) + { strcpy (nanmessage, "spNode"); } + else if (nandetect = isnan (*(ckt->CKTrhs + + here->B3SOIFDeNode))) + { strcpy (nanmessage, "eNode"); } + } + + /* Now print error message if NaN detected. Note that + error will only be printed once (the first time it is + encountered) each time SPICE is run since nanfound is + static variable */ + + if (nanfound == 0 && nandetect) + { + fprintf(stderr, "Alberto says: YOU TURKEY! %s is NaN for instance %s at time %g!\n", nanmessage, here->B3SOIFDname, ckt->CKTtime); + nanfound = nandetect; + fprintf(stderr, " The program exit!\n"); + exit(-1); + } + + if (here->B3SOIFDdebugMod > 2) + { + fprintf(fpdebug, "Ids = %.4e, Ic = %.4e, cqdrn = %.4e, gmin=%.3e\n", + Ids, Ic, cqdrn, ckt->CKTgmin); + fprintf(fpdebug, "Iii = %.4e, Idgidl = %.4e, Ibs = %.14e\n", + Iii, Idgidl, Ibs); + fprintf(fpdebug, "Ibd = %.4e, Ibp = %.4e\n", Ibd, Ibp); + fprintf(fpdebug, "qbody = %.5e, qbf = %.5e, qbe = %.5e\n", + qbody, Qbf, -(Qe1+Qe2)); + fprintf(fpdebug, "qbs = %.5e, qbd = %.5e\n", qjs, qjd); + fprintf(fpdebug, "qdrn = %.5e, qinv = %.5e\n", qdrn, qinv); + + + + +/* I am trying to debug the convergence problems here by printing out + the entire Jacobian and equivalent current matrix */ + + if (here->B3SOIFDdebugMod > 4) { + fprintf(fpdebug, "Ibtot = %.6e;\t Cbtot = %.6e;\n", Ibs+Ibp+Ibd-Iii-Idgidl-Isgidl, cqbody); + fprintf(fpdebug, "ceqg = %.6e;\t ceqb = %.6e;\t ceqdp = %.6e;\t ceqsp = %.6e;\n", + *(ckt->CKTrhs + here->B3SOIFDgNode), + *(ckt->CKTrhs + here->B3SOIFDbNode), + *(ckt->CKTrhs + here->B3SOIFDdNodePrime), + *(ckt->CKTrhs + here->B3SOIFDsNodePrime)); + fprintf(fpdebug, "ceqe = %.6e;\t ceqp = %.6e;\t ceqth = %.6e;\n", + *(ckt->CKTrhs + here->B3SOIFDeNode), + *(ckt->CKTrhs + here->B3SOIFDpNode), + *(ckt->CKTrhs + here->B3SOIFDtempNode)); + + fprintf(fpdebug, "Eg = %.5e;\t Edp = %.5e;\t Esp = %.5e;\t Eb = %.5e;\n", + *(here->B3SOIFDEgPtr), + *(here->B3SOIFDEdpPtr), + *(here->B3SOIFDEspPtr), + *(here->B3SOIFDEbPtr)); + fprintf(fpdebug, "Ee = %.5e;\t Gg = %.5e;\t Gdp = %.5e;\t Gsp = %.5e;\n", + *(here->B3SOIFDEePtr), + *(here->B3SOIFDGgPtr), + *(here->B3SOIFDGdpPtr), + *(here->B3SOIFDGspPtr)); + fprintf(fpdebug, "Gb = %.5e;\t Ge = %.5e;\t DPg = %.5e;\t DPdp = %.5e;\n", + *(here->B3SOIFDGbPtr), + *(here->B3SOIFDGePtr), + *(here->B3SOIFDDPgPtr), + *(here->B3SOIFDDPdpPtr)); + fprintf(fpdebug, "DPsp = %.5e;\t DPb = %.5e;\t DPe = %.5e;\t\n", + *(here->B3SOIFDDPspPtr), + *(here->B3SOIFDDPbPtr), + *(here->B3SOIFDDPePtr)); + fprintf(fpdebug, "DPd = %.5e;\t SPg = %.5e;\t SPdp = %.5e;\t SPsp = %.5e;\n", + *(here->B3SOIFDDPdPtr), + *(here->B3SOIFDSPgPtr), + *(here->B3SOIFDSPdpPtr), + *(here->B3SOIFDSPspPtr)); + fprintf(fpdebug, "SPb = %.5e;\t SPe = %.5e;\t SPs = %.5e;\n", + *(here->B3SOIFDSPbPtr), + *(here->B3SOIFDSPePtr), + *(here->B3SOIFDSPsPtr)); + fprintf(fpdebug, "Dd = %.5e;\t Ddp = %.5e;\t Ss = %.5e;\t Ssp = %.5e;\n", + *(here->B3SOIFDDdPtr), + *(here->B3SOIFDDdpPtr), + *(here->B3SOIFDSsPtr), + *(here->B3SOIFDSspPtr)); + fprintf(fpdebug, "Bg = %.5e;\t Bdp = %.5e;\t Bsp = %.5e;\t Bb = %.5e;\n", + *(here->B3SOIFDBgPtr), + *(here->B3SOIFDBdpPtr), + *(here->B3SOIFDBspPtr), + *(here->B3SOIFDBbPtr)); + fprintf(fpdebug, "Be = %.5e;\t Btot = %.5e;\t DPtot = %.5e;\n", + *(here->B3SOIFDBePtr), + *(here->B3SOIFDBgPtr) + *(here->B3SOIFDBdpPtr) + + *(here->B3SOIFDBspPtr) + *(here->B3SOIFDBbPtr) + + *(here->B3SOIFDBePtr), + *(here->B3SOIFDDPePtr) + + *(here->B3SOIFDDPgPtr) + *(here->B3SOIFDDPdpPtr) + + *(here->B3SOIFDDPspPtr) + *(here->B3SOIFDDPbPtr)); + + if (selfheat) { + fprintf (fpdebug, "DPtemp = %.5e;\t SPtemp = %.5e;\t Btemp = %.5e;\n", + *(here->B3SOIFDDPtempPtr), *(here->B3SOIFDSPtempPtr), + *(here->B3SOIFDBtempPtr)); + fprintf (fpdebug, "Gtemp = %.5e;\t Etemp = %.5e;\n", + *(here->B3SOIFDGtempPtr), *(here->B3SOIFDEtempPtr)); + fprintf (fpdebug, "Tempg = %.5e;\t Tempdp = %.5e;\t Tempsp = %.5e;\t Tempb = %.5e;\n", + *(here->B3SOIFDTempgPtr), *(here->B3SOIFDTempdpPtr), + *(here->B3SOIFDTempspPtr), *(here->B3SOIFDTempbPtr)); + fprintf (fpdebug, "Tempe = %.5e;\t TempT = %.5e;\t Temptot = %.5e;\n", + *(here->B3SOIFDTempePtr), *(here->B3SOIFDTemptempPtr), + *(here->B3SOIFDTempgPtr) + *(here->B3SOIFDTempdpPtr) + + *(here->B3SOIFDTempspPtr)+ *(here->B3SOIFDTempbPtr) + + *(here->B3SOIFDTempePtr)); + } + + if (here->B3SOIFDbodyMod == 1) + { + fprintf(fpdebug, "ceqbodcon=%.5e;\t", ceqbodcon); + fprintf(fpdebug, "Bp = %.5e;\t Pb = %.5e;\t Pp = %.5e;\n", -gppp, gppb, gppp); + fprintf(fpdebug, "Pg=%.5e;\t Pdp=%.5e;\t Psp=%.5e;\t Pe=%.5e;\n", + gppg, gppdp, gppsp, gppe); + } +} + + if (here->B3SOIFDdebugMod > 3) + { + fprintf(fpdebug, "Vth = %.4f, Vbs0eff = %.8f, Vdsat = %.4f\n", + Vth, Vbs0eff, Vdsat); + fprintf(fpdebug, "ueff = %g, Vgsteff = %.4f, Vdseff = %.4f\n", + ueff, Vgsteff, Vdseff); + fprintf(fpdebug, "Vthfd = %.4f, Vbs0mos = %.4f, Vbs0 = %.4f\n", + Vthfd, Vbs0mos, Vbs0); + fprintf(fpdebug, "Vbs0t = %.4f, Vbsdio = %.8f\n", + Vbs0t, Vbsdio); + } + + fclose(fpdebug); + } + + here->B3SOIFDiterations++; /* increment the iteration counter */ + + } /* End of Mosfet Instance */ +} /* End of Model Instance */ + + +return(OK); +} + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdmask.c b/src/spicelib/devices/bsim3soi_fd/b3soifdmask.c new file mode 100644 index 000000000..c88d7b159 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdmask.c @@ -0,0 +1,1207 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soifdmask.c 98/5/01 +Modified by Wei Jin 99/9/27 +**********/ + + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "b3soifddef.h" +#include "sperror.h" +#include "suffix.h" + +int +B3SOIFDmAsk(ckt,inst,which,value) +CKTcircuit *ckt; +GENmodel *inst; +int which; +IFvalue *value; +{ + B3SOIFDmodel *model = (B3SOIFDmodel *)inst; + switch(which) + { case B3SOIFD_MOD_MOBMOD: + value->iValue = model->B3SOIFDmobMod; + return(OK); + case B3SOIFD_MOD_PARAMCHK: + value->iValue = model->B3SOIFDparamChk; + return(OK); + case B3SOIFD_MOD_BINUNIT: + value->iValue = model->B3SOIFDbinUnit; + return(OK); + case B3SOIFD_MOD_CAPMOD: + value->iValue = model->B3SOIFDcapMod; + return(OK); + case B3SOIFD_MOD_SHMOD: + value->iValue = model->B3SOIFDshMod; + return(OK); + case B3SOIFD_MOD_NOIMOD: + value->iValue = model->B3SOIFDnoiMod; + return(OK); + case B3SOIFD_MOD_VERSION : + value->rValue = model->B3SOIFDversion; + return(OK); + case B3SOIFD_MOD_TOX : + value->rValue = model->B3SOIFDtox; + return(OK); + case B3SOIFD_MOD_CDSC : + value->rValue = model->B3SOIFDcdsc; + return(OK); + case B3SOIFD_MOD_CDSCB : + value->rValue = model->B3SOIFDcdscb; + return(OK); + + case B3SOIFD_MOD_CDSCD : + value->rValue = model->B3SOIFDcdscd; + return(OK); + + case B3SOIFD_MOD_CIT : + value->rValue = model->B3SOIFDcit; + return(OK); + case B3SOIFD_MOD_NFACTOR : + value->rValue = model->B3SOIFDnfactor; + return(OK); + case B3SOIFD_MOD_VSAT: + value->rValue = model->B3SOIFDvsat; + return(OK); + case B3SOIFD_MOD_AT: + value->rValue = model->B3SOIFDat; + return(OK); + case B3SOIFD_MOD_A0: + value->rValue = model->B3SOIFDa0; + return(OK); + + case B3SOIFD_MOD_AGS: + value->rValue = model->B3SOIFDags; + return(OK); + + case B3SOIFD_MOD_A1: + value->rValue = model->B3SOIFDa1; + return(OK); + case B3SOIFD_MOD_A2: + value->rValue = model->B3SOIFDa2; + return(OK); + case B3SOIFD_MOD_KETA: + value->rValue = model->B3SOIFDketa; + return(OK); + case B3SOIFD_MOD_NSUB: + value->rValue = model->B3SOIFDnsub; + return(OK); + case B3SOIFD_MOD_NPEAK: + value->rValue = model->B3SOIFDnpeak; + return(OK); + case B3SOIFD_MOD_NGATE: + value->rValue = model->B3SOIFDngate; + return(OK); + case B3SOIFD_MOD_GAMMA1: + value->rValue = model->B3SOIFDgamma1; + return(OK); + case B3SOIFD_MOD_GAMMA2: + value->rValue = model->B3SOIFDgamma2; + return(OK); + case B3SOIFD_MOD_VBX: + value->rValue = model->B3SOIFDvbx; + return(OK); + case B3SOIFD_MOD_VBM: + value->rValue = model->B3SOIFDvbm; + return(OK); + case B3SOIFD_MOD_XT: + value->rValue = model->B3SOIFDxt; + return(OK); + case B3SOIFD_MOD_K1: + value->rValue = model->B3SOIFDk1; + return(OK); + case B3SOIFD_MOD_KT1: + value->rValue = model->B3SOIFDkt1; + return(OK); + case B3SOIFD_MOD_KT1L: + value->rValue = model->B3SOIFDkt1l; + return(OK); + case B3SOIFD_MOD_KT2 : + value->rValue = model->B3SOIFDkt2; + return(OK); + case B3SOIFD_MOD_K2 : + value->rValue = model->B3SOIFDk2; + return(OK); + case B3SOIFD_MOD_K3: + value->rValue = model->B3SOIFDk3; + return(OK); + case B3SOIFD_MOD_K3B: + value->rValue = model->B3SOIFDk3b; + return(OK); + case B3SOIFD_MOD_W0: + value->rValue = model->B3SOIFDw0; + return(OK); + case B3SOIFD_MOD_NLX: + value->rValue = model->B3SOIFDnlx; + return(OK); + case B3SOIFD_MOD_DVT0 : + value->rValue = model->B3SOIFDdvt0; + return(OK); + case B3SOIFD_MOD_DVT1 : + value->rValue = model->B3SOIFDdvt1; + return(OK); + case B3SOIFD_MOD_DVT2 : + value->rValue = model->B3SOIFDdvt2; + return(OK); + case B3SOIFD_MOD_DVT0W : + value->rValue = model->B3SOIFDdvt0w; + return(OK); + case B3SOIFD_MOD_DVT1W : + value->rValue = model->B3SOIFDdvt1w; + return(OK); + case B3SOIFD_MOD_DVT2W : + value->rValue = model->B3SOIFDdvt2w; + return(OK); + case B3SOIFD_MOD_DROUT : + value->rValue = model->B3SOIFDdrout; + return(OK); + case B3SOIFD_MOD_DSUB : + value->rValue = model->B3SOIFDdsub; + return(OK); + case B3SOIFD_MOD_VTH0: + value->rValue = model->B3SOIFDvth0; + return(OK); + case B3SOIFD_MOD_UA: + value->rValue = model->B3SOIFDua; + return(OK); + case B3SOIFD_MOD_UA1: + value->rValue = model->B3SOIFDua1; + return(OK); + case B3SOIFD_MOD_UB: + value->rValue = model->B3SOIFDub; + return(OK); + case B3SOIFD_MOD_UB1: + value->rValue = model->B3SOIFDub1; + return(OK); + case B3SOIFD_MOD_UC: + value->rValue = model->B3SOIFDuc; + return(OK); + case B3SOIFD_MOD_UC1: + value->rValue = model->B3SOIFDuc1; + return(OK); + case B3SOIFD_MOD_U0: + value->rValue = model->B3SOIFDu0; + return(OK); + case B3SOIFD_MOD_UTE: + value->rValue = model->B3SOIFDute; + return(OK); + case B3SOIFD_MOD_VOFF: + value->rValue = model->B3SOIFDvoff; + return(OK); + case B3SOIFD_MOD_DELTA: + value->rValue = model->B3SOIFDdelta; + return(OK); + case B3SOIFD_MOD_RDSW: + value->rValue = model->B3SOIFDrdsw; + return(OK); + case B3SOIFD_MOD_PRWG: + value->rValue = model->B3SOIFDprwg; + return(OK); + case B3SOIFD_MOD_PRWB: + value->rValue = model->B3SOIFDprwb; + return(OK); + case B3SOIFD_MOD_PRT: + value->rValue = model->B3SOIFDprt; + return(OK); + case B3SOIFD_MOD_ETA0: + value->rValue = model->B3SOIFDeta0; + return(OK); + case B3SOIFD_MOD_ETAB: + value->rValue = model->B3SOIFDetab; + return(OK); + case B3SOIFD_MOD_PCLM: + value->rValue = model->B3SOIFDpclm; + return(OK); + case B3SOIFD_MOD_PDIBL1: + value->rValue = model->B3SOIFDpdibl1; + return(OK); + case B3SOIFD_MOD_PDIBL2: + value->rValue = model->B3SOIFDpdibl2; + return(OK); + case B3SOIFD_MOD_PDIBLB: + value->rValue = model->B3SOIFDpdiblb; + return(OK); + case B3SOIFD_MOD_PVAG: + value->rValue = model->B3SOIFDpvag; + return(OK); + case B3SOIFD_MOD_WR: + value->rValue = model->B3SOIFDwr; + return(OK); + case B3SOIFD_MOD_DWG: + value->rValue = model->B3SOIFDdwg; + return(OK); + case B3SOIFD_MOD_DWB: + value->rValue = model->B3SOIFDdwb; + return(OK); + case B3SOIFD_MOD_B0: + value->rValue = model->B3SOIFDb0; + return(OK); + case B3SOIFD_MOD_B1: + value->rValue = model->B3SOIFDb1; + return(OK); + case B3SOIFD_MOD_ALPHA0: + value->rValue = model->B3SOIFDalpha0; + return(OK); + case B3SOIFD_MOD_ALPHA1: + value->rValue = model->B3SOIFDalpha1; + return(OK); + case B3SOIFD_MOD_BETA0: + value->rValue = model->B3SOIFDbeta0; + return(OK); + + case B3SOIFD_MOD_CGSL: + value->rValue = model->B3SOIFDcgsl; + return(OK); + case B3SOIFD_MOD_CGDL: + value->rValue = model->B3SOIFDcgdl; + return(OK); + case B3SOIFD_MOD_CKAPPA: + value->rValue = model->B3SOIFDckappa; + return(OK); + case B3SOIFD_MOD_CF: + value->rValue = model->B3SOIFDcf; + return(OK); + case B3SOIFD_MOD_CLC: + value->rValue = model->B3SOIFDclc; + return(OK); + case B3SOIFD_MOD_CLE: + value->rValue = model->B3SOIFDcle; + return(OK); + case B3SOIFD_MOD_DWC: + value->rValue = model->B3SOIFDdwc; + return(OK); + case B3SOIFD_MOD_DLC: + value->rValue = model->B3SOIFDdlc; + return(OK); + + case B3SOIFD_MOD_TBOX: + value->rValue = model->B3SOIFDtbox; + return(OK); + case B3SOIFD_MOD_TSI: + value->rValue = model->B3SOIFDtsi; + return(OK); + case B3SOIFD_MOD_KB1: + value->rValue = model->B3SOIFDkb1; + return(OK); + case B3SOIFD_MOD_KB3: + value->rValue = model->B3SOIFDkb3; + return(OK); + case B3SOIFD_MOD_DVBD0: + value->rValue = model->B3SOIFDdvbd0; + return(OK); + case B3SOIFD_MOD_DVBD1: + value->rValue = model->B3SOIFDdvbd1; + return(OK); + case B3SOIFD_MOD_DELP: + value->rValue = model->B3SOIFDdelp; + return(OK); + case B3SOIFD_MOD_VBSA: + value->rValue = model->B3SOIFDvbsa; + return(OK); + case B3SOIFD_MOD_RBODY: + value->rValue = model->B3SOIFDrbody; + return(OK); + case B3SOIFD_MOD_RBSH: + value->rValue = model->B3SOIFDrbsh; + return(OK); + case B3SOIFD_MOD_ADICE0: + value->rValue = model->B3SOIFDadice0; + return(OK); + case B3SOIFD_MOD_ABP: + value->rValue = model->B3SOIFDabp; + return(OK); + case B3SOIFD_MOD_MXC: + value->rValue = model->B3SOIFDmxc; + return(OK); + case B3SOIFD_MOD_RTH0: + value->rValue = model->B3SOIFDrth0; + return(OK); + case B3SOIFD_MOD_CTH0: + value->rValue = model->B3SOIFDcth0; + return(OK); + case B3SOIFD_MOD_AII: + value->rValue = model->B3SOIFDaii; + return(OK); + case B3SOIFD_MOD_BII: + value->rValue = model->B3SOIFDbii; + return(OK); + case B3SOIFD_MOD_CII: + value->rValue = model->B3SOIFDcii; + return(OK); + case B3SOIFD_MOD_DII: + value->rValue = model->B3SOIFDdii; + return(OK); + case B3SOIFD_MOD_NDIODE: + value->rValue = model->B3SOIFDndiode; + return(OK); + case B3SOIFD_MOD_NTUN: + value->rValue = model->B3SOIFDntun; + return(OK); + case B3SOIFD_MOD_ISBJT: + value->rValue = model->B3SOIFDisbjt; + return(OK); + case B3SOIFD_MOD_ISDIF: + value->rValue = model->B3SOIFDisdif; + return(OK); + case B3SOIFD_MOD_ISREC: + value->rValue = model->B3SOIFDisrec; + return(OK); + case B3SOIFD_MOD_ISTUN: + value->rValue = model->B3SOIFDistun; + return(OK); + case B3SOIFD_MOD_XBJT: + value->rValue = model->B3SOIFDxbjt; + return(OK); + case B3SOIFD_MOD_XREC: + value->rValue = model->B3SOIFDxrec; + return(OK); + case B3SOIFD_MOD_XTUN: + value->rValue = model->B3SOIFDxtun; + return(OK); + case B3SOIFD_MOD_EDL: + value->rValue = model->B3SOIFDedl; + return(OK); + case B3SOIFD_MOD_KBJT1: + value->rValue = model->B3SOIFDkbjt1; + return(OK); + case B3SOIFD_MOD_TT: + value->rValue = model->B3SOIFDtt; + return(OK); + case B3SOIFD_MOD_VSDTH: + value->rValue = model->B3SOIFDvsdth; + return(OK); + case B3SOIFD_MOD_VSDFB: + value->rValue = model->B3SOIFDvsdfb; + return(OK); + case B3SOIFD_MOD_CSDMIN: + value->rValue = model->B3SOIFDcsdmin; + return(OK); + case B3SOIFD_MOD_ASD: + value->rValue = model->B3SOIFDasd; + return(OK); + + case B3SOIFD_MOD_TNOM : + value->rValue = model->B3SOIFDtnom; + return(OK); + case B3SOIFD_MOD_CGSO: + value->rValue = model->B3SOIFDcgso; + return(OK); + case B3SOIFD_MOD_CGDO: + value->rValue = model->B3SOIFDcgdo; + return(OK); + case B3SOIFD_MOD_CGEO: + value->rValue = model->B3SOIFDcgeo; + return(OK); + case B3SOIFD_MOD_XPART: + value->rValue = model->B3SOIFDxpart; + return(OK); + case B3SOIFD_MOD_RSH: + value->rValue = model->B3SOIFDsheetResistance; + return(OK); + case B3SOIFD_MOD_PBSWG: + value->rValue = model->B3SOIFDGatesidewallJctPotential; + return(OK); + case B3SOIFD_MOD_MJSWG: + value->rValue = model->B3SOIFDbodyJctGateSideGradingCoeff; + return(OK); + case B3SOIFD_MOD_CJSWG: + value->rValue = model->B3SOIFDunitLengthGateSidewallJctCap; + return(OK); + case B3SOIFD_MOD_CSDESW: + value->rValue = model->B3SOIFDcsdesw; + return(OK); + case B3SOIFD_MOD_LINT: + value->rValue = model->B3SOIFDLint; + return(OK); + case B3SOIFD_MOD_LL: + value->rValue = model->B3SOIFDLl; + return(OK); + case B3SOIFD_MOD_LLN: + value->rValue = model->B3SOIFDLln; + return(OK); + case B3SOIFD_MOD_LW: + value->rValue = model->B3SOIFDLw; + return(OK); + case B3SOIFD_MOD_LWN: + value->rValue = model->B3SOIFDLwn; + return(OK); + case B3SOIFD_MOD_LWL: + value->rValue = model->B3SOIFDLwl; + return(OK); + case B3SOIFD_MOD_WINT: + value->rValue = model->B3SOIFDWint; + return(OK); + case B3SOIFD_MOD_WL: + value->rValue = model->B3SOIFDWl; + return(OK); + case B3SOIFD_MOD_WLN: + value->rValue = model->B3SOIFDWln; + return(OK); + case B3SOIFD_MOD_WW: + value->rValue = model->B3SOIFDWw; + return(OK); + case B3SOIFD_MOD_WWN: + value->rValue = model->B3SOIFDWwn; + return(OK); + case B3SOIFD_MOD_WWL: + value->rValue = model->B3SOIFDWwl; + return(OK); + case B3SOIFD_MOD_NOIA: + value->rValue = model->B3SOIFDoxideTrapDensityA; + return(OK); + case B3SOIFD_MOD_NOIB: + value->rValue = model->B3SOIFDoxideTrapDensityB; + return(OK); + case B3SOIFD_MOD_NOIC: + value->rValue = model->B3SOIFDoxideTrapDensityC; + return(OK); + case B3SOIFD_MOD_NOIF: + value->rValue = model->B3SOIFDnoif; + return(OK); + case B3SOIFD_MOD_EM: + value->rValue = model->B3SOIFDem; + return(OK); + case B3SOIFD_MOD_EF: + value->rValue = model->B3SOIFDef; + return(OK); + case B3SOIFD_MOD_AF: + value->rValue = model->B3SOIFDaf; + return(OK); + case B3SOIFD_MOD_KF: + value->rValue = model->B3SOIFDkf; + return(OK); + +/* Added for binning - START */ + /* Length Dependence */ + case B3SOIFD_MOD_LNPEAK: + value->rValue = model->B3SOIFDlnpeak; + return(OK); + case B3SOIFD_MOD_LNSUB: + value->rValue = model->B3SOIFDlnsub; + return(OK); + case B3SOIFD_MOD_LNGATE: + value->rValue = model->B3SOIFDlngate; + return(OK); + case B3SOIFD_MOD_LVTH0: + value->rValue = model->B3SOIFDlvth0; + return(OK); + case B3SOIFD_MOD_LK1: + value->rValue = model->B3SOIFDlk1; + return(OK); + case B3SOIFD_MOD_LK2: + value->rValue = model->B3SOIFDlk2; + return(OK); + case B3SOIFD_MOD_LK3: + value->rValue = model->B3SOIFDlk3; + return(OK); + case B3SOIFD_MOD_LK3B: + value->rValue = model->B3SOIFDlk3b; + return(OK); + case B3SOIFD_MOD_LVBSA: + value->rValue = model->B3SOIFDlvbsa; + return(OK); + case B3SOIFD_MOD_LDELP: + value->rValue = model->B3SOIFDldelp; + return(OK); + case B3SOIFD_MOD_LKB1: + value->rValue = model->B3SOIFDlkb1; + return(OK); + case B3SOIFD_MOD_LKB3: + value->rValue = model->B3SOIFDlkb3; + return(OK); + case B3SOIFD_MOD_LDVBD0: + value->rValue = model->B3SOIFDdvbd0; + return(OK); + case B3SOIFD_MOD_LDVBD1: + value->rValue = model->B3SOIFDdvbd1; + return(OK); + case B3SOIFD_MOD_LW0: + value->rValue = model->B3SOIFDlw0; + return(OK); + case B3SOIFD_MOD_LNLX: + value->rValue = model->B3SOIFDlnlx; + return(OK); + case B3SOIFD_MOD_LDVT0 : + value->rValue = model->B3SOIFDldvt0; + return(OK); + case B3SOIFD_MOD_LDVT1 : + value->rValue = model->B3SOIFDldvt1; + return(OK); + case B3SOIFD_MOD_LDVT2 : + value->rValue = model->B3SOIFDldvt2; + return(OK); + case B3SOIFD_MOD_LDVT0W : + value->rValue = model->B3SOIFDldvt0w; + return(OK); + case B3SOIFD_MOD_LDVT1W : + value->rValue = model->B3SOIFDldvt1w; + return(OK); + case B3SOIFD_MOD_LDVT2W : + value->rValue = model->B3SOIFDldvt2w; + return(OK); + case B3SOIFD_MOD_LU0: + value->rValue = model->B3SOIFDlu0; + return(OK); + case B3SOIFD_MOD_LUA: + value->rValue = model->B3SOIFDlua; + return(OK); + case B3SOIFD_MOD_LUB: + value->rValue = model->B3SOIFDlub; + return(OK); + case B3SOIFD_MOD_LUC: + value->rValue = model->B3SOIFDluc; + return(OK); + case B3SOIFD_MOD_LVSAT: + value->rValue = model->B3SOIFDlvsat; + return(OK); + case B3SOIFD_MOD_LA0: + value->rValue = model->B3SOIFDla0; + return(OK); + case B3SOIFD_MOD_LAGS: + value->rValue = model->B3SOIFDlags; + return(OK); + case B3SOIFD_MOD_LB0: + value->rValue = model->B3SOIFDlb0; + return(OK); + case B3SOIFD_MOD_LB1: + value->rValue = model->B3SOIFDlb1; + return(OK); + case B3SOIFD_MOD_LKETA: + value->rValue = model->B3SOIFDlketa; + return(OK); + case B3SOIFD_MOD_LABP: + value->rValue = model->B3SOIFDlabp; + return(OK); + case B3SOIFD_MOD_LMXC: + value->rValue = model->B3SOIFDlmxc; + return(OK); + case B3SOIFD_MOD_LADICE0: + value->rValue = model->B3SOIFDladice0; + return(OK); + case B3SOIFD_MOD_LA1: + value->rValue = model->B3SOIFDla1; + return(OK); + case B3SOIFD_MOD_LA2: + value->rValue = model->B3SOIFDla2; + return(OK); + case B3SOIFD_MOD_LRDSW: + value->rValue = model->B3SOIFDlrdsw; + return(OK); + case B3SOIFD_MOD_LPRWB: + value->rValue = model->B3SOIFDlprwb; + return(OK); + case B3SOIFD_MOD_LPRWG: + value->rValue = model->B3SOIFDlprwg; + return(OK); + case B3SOIFD_MOD_LWR: + value->rValue = model->B3SOIFDlwr; + return(OK); + case B3SOIFD_MOD_LNFACTOR : + value->rValue = model->B3SOIFDlnfactor; + return(OK); + case B3SOIFD_MOD_LDWG: + value->rValue = model->B3SOIFDldwg; + return(OK); + case B3SOIFD_MOD_LDWB: + value->rValue = model->B3SOIFDldwb; + return(OK); + case B3SOIFD_MOD_LVOFF: + value->rValue = model->B3SOIFDlvoff; + return(OK); + case B3SOIFD_MOD_LETA0: + value->rValue = model->B3SOIFDleta0; + return(OK); + case B3SOIFD_MOD_LETAB: + value->rValue = model->B3SOIFDletab; + return(OK); + case B3SOIFD_MOD_LDSUB : + value->rValue = model->B3SOIFDldsub; + return(OK); + case B3SOIFD_MOD_LCIT : + value->rValue = model->B3SOIFDlcit; + return(OK); + case B3SOIFD_MOD_LCDSC : + value->rValue = model->B3SOIFDlcdsc; + return(OK); + case B3SOIFD_MOD_LCDSCB : + value->rValue = model->B3SOIFDlcdscb; + return(OK); + case B3SOIFD_MOD_LCDSCD : + value->rValue = model->B3SOIFDlcdscd; + return(OK); + case B3SOIFD_MOD_LPCLM: + value->rValue = model->B3SOIFDlpclm; + return(OK); + case B3SOIFD_MOD_LPDIBL1: + value->rValue = model->B3SOIFDlpdibl1; + return(OK); + case B3SOIFD_MOD_LPDIBL2: + value->rValue = model->B3SOIFDlpdibl2; + return(OK); + case B3SOIFD_MOD_LPDIBLB: + value->rValue = model->B3SOIFDlpdiblb; + return(OK); + case B3SOIFD_MOD_LDROUT : + value->rValue = model->B3SOIFDldrout; + return(OK); + case B3SOIFD_MOD_LPVAG: + value->rValue = model->B3SOIFDlpvag; + return(OK); + case B3SOIFD_MOD_LDELTA: + value->rValue = model->B3SOIFDldelta; + return(OK); + case B3SOIFD_MOD_LAII: + value->rValue = model->B3SOIFDlaii; + return(OK); + case B3SOIFD_MOD_LBII: + value->rValue = model->B3SOIFDlbii; + return(OK); + case B3SOIFD_MOD_LCII: + value->rValue = model->B3SOIFDlcii; + return(OK); + case B3SOIFD_MOD_LDII: + value->rValue = model->B3SOIFDldii; + return(OK); + case B3SOIFD_MOD_LALPHA0: + value->rValue = model->B3SOIFDlalpha0; + return(OK); + case B3SOIFD_MOD_LALPHA1: + value->rValue = model->B3SOIFDlalpha1; + return(OK); + case B3SOIFD_MOD_LBETA0: + value->rValue = model->B3SOIFDlbeta0; + return(OK); + case B3SOIFD_MOD_LAGIDL: + value->rValue = model->B3SOIFDlagidl; + return(OK); + case B3SOIFD_MOD_LBGIDL: + value->rValue = model->B3SOIFDlbgidl; + return(OK); + case B3SOIFD_MOD_LNGIDL: + value->rValue = model->B3SOIFDlngidl; + return(OK); + case B3SOIFD_MOD_LNTUN: + value->rValue = model->B3SOIFDlntun; + return(OK); + case B3SOIFD_MOD_LNDIODE: + value->rValue = model->B3SOIFDlndiode; + return(OK); + case B3SOIFD_MOD_LISBJT: + value->rValue = model->B3SOIFDlisbjt; + return(OK); + case B3SOIFD_MOD_LISDIF: + value->rValue = model->B3SOIFDlisdif; + return(OK); + case B3SOIFD_MOD_LISREC: + value->rValue = model->B3SOIFDlisrec; + return(OK); + case B3SOIFD_MOD_LISTUN: + value->rValue = model->B3SOIFDlistun; + return(OK); + case B3SOIFD_MOD_LEDL: + value->rValue = model->B3SOIFDledl; + return(OK); + case B3SOIFD_MOD_LKBJT1: + value->rValue = model->B3SOIFDlkbjt1; + return(OK); + /* CV Model */ + case B3SOIFD_MOD_LVSDFB: + value->rValue = model->B3SOIFDlvsdfb; + return(OK); + case B3SOIFD_MOD_LVSDTH: + value->rValue = model->B3SOIFDlvsdth; + return(OK); + /* Width Dependence */ + case B3SOIFD_MOD_WNPEAK: + value->rValue = model->B3SOIFDwnpeak; + return(OK); + case B3SOIFD_MOD_WNSUB: + value->rValue = model->B3SOIFDwnsub; + return(OK); + case B3SOIFD_MOD_WNGATE: + value->rValue = model->B3SOIFDwngate; + return(OK); + case B3SOIFD_MOD_WVTH0: + value->rValue = model->B3SOIFDwvth0; + return(OK); + case B3SOIFD_MOD_WK1: + value->rValue = model->B3SOIFDwk1; + return(OK); + case B3SOIFD_MOD_WK2: + value->rValue = model->B3SOIFDwk2; + return(OK); + case B3SOIFD_MOD_WK3: + value->rValue = model->B3SOIFDwk3; + return(OK); + case B3SOIFD_MOD_WK3B: + value->rValue = model->B3SOIFDwk3b; + return(OK); + case B3SOIFD_MOD_WVBSA: + value->rValue = model->B3SOIFDwvbsa; + return(OK); + case B3SOIFD_MOD_WDELP: + value->rValue = model->B3SOIFDwdelp; + return(OK); + case B3SOIFD_MOD_WKB1: + value->rValue = model->B3SOIFDwkb1; + return(OK); + case B3SOIFD_MOD_WKB3: + value->rValue = model->B3SOIFDwkb3; + return(OK); + case B3SOIFD_MOD_WDVBD0: + value->rValue = model->B3SOIFDdvbd0; + return(OK); + case B3SOIFD_MOD_WDVBD1: + value->rValue = model->B3SOIFDdvbd1; + return(OK); + case B3SOIFD_MOD_WW0: + value->rValue = model->B3SOIFDww0; + return(OK); + case B3SOIFD_MOD_WNLX: + value->rValue = model->B3SOIFDwnlx; + return(OK); + case B3SOIFD_MOD_WDVT0 : + value->rValue = model->B3SOIFDwdvt0; + return(OK); + case B3SOIFD_MOD_WDVT1 : + value->rValue = model->B3SOIFDwdvt1; + return(OK); + case B3SOIFD_MOD_WDVT2 : + value->rValue = model->B3SOIFDwdvt2; + return(OK); + case B3SOIFD_MOD_WDVT0W : + value->rValue = model->B3SOIFDwdvt0w; + return(OK); + case B3SOIFD_MOD_WDVT1W : + value->rValue = model->B3SOIFDwdvt1w; + return(OK); + case B3SOIFD_MOD_WDVT2W : + value->rValue = model->B3SOIFDwdvt2w; + return(OK); + case B3SOIFD_MOD_WU0: + value->rValue = model->B3SOIFDwu0; + return(OK); + case B3SOIFD_MOD_WUA: + value->rValue = model->B3SOIFDwua; + return(OK); + case B3SOIFD_MOD_WUB: + value->rValue = model->B3SOIFDwub; + return(OK); + case B3SOIFD_MOD_WUC: + value->rValue = model->B3SOIFDwuc; + return(OK); + case B3SOIFD_MOD_WVSAT: + value->rValue = model->B3SOIFDwvsat; + return(OK); + case B3SOIFD_MOD_WA0: + value->rValue = model->B3SOIFDwa0; + return(OK); + case B3SOIFD_MOD_WAGS: + value->rValue = model->B3SOIFDwags; + return(OK); + case B3SOIFD_MOD_WB0: + value->rValue = model->B3SOIFDwb0; + return(OK); + case B3SOIFD_MOD_WB1: + value->rValue = model->B3SOIFDwb1; + return(OK); + case B3SOIFD_MOD_WKETA: + value->rValue = model->B3SOIFDwketa; + return(OK); + case B3SOIFD_MOD_WABP: + value->rValue = model->B3SOIFDwabp; + return(OK); + case B3SOIFD_MOD_WMXC: + value->rValue = model->B3SOIFDwmxc; + return(OK); + case B3SOIFD_MOD_WADICE0: + value->rValue = model->B3SOIFDwadice0; + return(OK); + case B3SOIFD_MOD_WA1: + value->rValue = model->B3SOIFDwa1; + return(OK); + case B3SOIFD_MOD_WA2: + value->rValue = model->B3SOIFDwa2; + return(OK); + case B3SOIFD_MOD_WRDSW: + value->rValue = model->B3SOIFDwrdsw; + return(OK); + case B3SOIFD_MOD_WPRWB: + value->rValue = model->B3SOIFDwprwb; + return(OK); + case B3SOIFD_MOD_WPRWG: + value->rValue = model->B3SOIFDwprwg; + return(OK); + case B3SOIFD_MOD_WWR: + value->rValue = model->B3SOIFDwwr; + return(OK); + case B3SOIFD_MOD_WNFACTOR : + value->rValue = model->B3SOIFDwnfactor; + return(OK); + case B3SOIFD_MOD_WDWG: + value->rValue = model->B3SOIFDwdwg; + return(OK); + case B3SOIFD_MOD_WDWB: + value->rValue = model->B3SOIFDwdwb; + return(OK); + case B3SOIFD_MOD_WVOFF: + value->rValue = model->B3SOIFDwvoff; + return(OK); + case B3SOIFD_MOD_WETA0: + value->rValue = model->B3SOIFDweta0; + return(OK); + case B3SOIFD_MOD_WETAB: + value->rValue = model->B3SOIFDwetab; + return(OK); + case B3SOIFD_MOD_WDSUB : + value->rValue = model->B3SOIFDwdsub; + return(OK); + case B3SOIFD_MOD_WCIT : + value->rValue = model->B3SOIFDwcit; + return(OK); + case B3SOIFD_MOD_WCDSC : + value->rValue = model->B3SOIFDwcdsc; + return(OK); + case B3SOIFD_MOD_WCDSCB : + value->rValue = model->B3SOIFDwcdscb; + return(OK); + case B3SOIFD_MOD_WCDSCD : + value->rValue = model->B3SOIFDwcdscd; + return(OK); + case B3SOIFD_MOD_WPCLM: + value->rValue = model->B3SOIFDwpclm; + return(OK); + case B3SOIFD_MOD_WPDIBL1: + value->rValue = model->B3SOIFDwpdibl1; + return(OK); + case B3SOIFD_MOD_WPDIBL2: + value->rValue = model->B3SOIFDwpdibl2; + return(OK); + case B3SOIFD_MOD_WPDIBLB: + value->rValue = model->B3SOIFDwpdiblb; + return(OK); + case B3SOIFD_MOD_WDROUT : + value->rValue = model->B3SOIFDwdrout; + return(OK); + case B3SOIFD_MOD_WPVAG: + value->rValue = model->B3SOIFDwpvag; + return(OK); + case B3SOIFD_MOD_WDELTA: + value->rValue = model->B3SOIFDwdelta; + return(OK); + case B3SOIFD_MOD_WAII: + value->rValue = model->B3SOIFDwaii; + return(OK); + case B3SOIFD_MOD_WBII: + value->rValue = model->B3SOIFDwbii; + return(OK); + case B3SOIFD_MOD_WCII: + value->rValue = model->B3SOIFDwcii; + return(OK); + case B3SOIFD_MOD_WDII: + value->rValue = model->B3SOIFDwdii; + return(OK); + case B3SOIFD_MOD_WALPHA0: + value->rValue = model->B3SOIFDwalpha0; + return(OK); + case B3SOIFD_MOD_WALPHA1: + value->rValue = model->B3SOIFDwalpha1; + return(OK); + case B3SOIFD_MOD_WBETA0: + value->rValue = model->B3SOIFDwbeta0; + return(OK); + case B3SOIFD_MOD_WAGIDL: + value->rValue = model->B3SOIFDwagidl; + return(OK); + case B3SOIFD_MOD_WBGIDL: + value->rValue = model->B3SOIFDwbgidl; + return(OK); + case B3SOIFD_MOD_WNGIDL: + value->rValue = model->B3SOIFDwngidl; + return(OK); + case B3SOIFD_MOD_WNTUN: + value->rValue = model->B3SOIFDwntun; + return(OK); + case B3SOIFD_MOD_WNDIODE: + value->rValue = model->B3SOIFDwndiode; + return(OK); + case B3SOIFD_MOD_WISBJT: + value->rValue = model->B3SOIFDwisbjt; + return(OK); + case B3SOIFD_MOD_WISDIF: + value->rValue = model->B3SOIFDwisdif; + return(OK); + case B3SOIFD_MOD_WISREC: + value->rValue = model->B3SOIFDwisrec; + return(OK); + case B3SOIFD_MOD_WISTUN: + value->rValue = model->B3SOIFDwistun; + return(OK); + case B3SOIFD_MOD_WEDL: + value->rValue = model->B3SOIFDwedl; + return(OK); + case B3SOIFD_MOD_WKBJT1: + value->rValue = model->B3SOIFDwkbjt1; + return(OK); + /* CV Model */ + case B3SOIFD_MOD_WVSDFB: + value->rValue = model->B3SOIFDwvsdfb; + return(OK); + case B3SOIFD_MOD_WVSDTH: + value->rValue = model->B3SOIFDwvsdth; + return(OK); + /* Cross-term Dependence */ + case B3SOIFD_MOD_PNPEAK: + value->rValue = model->B3SOIFDpnpeak; + return(OK); + case B3SOIFD_MOD_PNSUB: + value->rValue = model->B3SOIFDpnsub; + return(OK); + case B3SOIFD_MOD_PNGATE: + value->rValue = model->B3SOIFDpngate; + return(OK); + case B3SOIFD_MOD_PVTH0: + value->rValue = model->B3SOIFDpvth0; + return(OK); + case B3SOIFD_MOD_PK1: + value->rValue = model->B3SOIFDpk1; + return(OK); + case B3SOIFD_MOD_PK2: + value->rValue = model->B3SOIFDpk2; + return(OK); + case B3SOIFD_MOD_PK3: + value->rValue = model->B3SOIFDpk3; + return(OK); + case B3SOIFD_MOD_PK3B: + value->rValue = model->B3SOIFDpk3b; + return(OK); + case B3SOIFD_MOD_PVBSA: + value->rValue = model->B3SOIFDpvbsa; + return(OK); + case B3SOIFD_MOD_PDELP: + value->rValue = model->B3SOIFDpdelp; + return(OK); + case B3SOIFD_MOD_PKB1: + value->rValue = model->B3SOIFDpkb1; + return(OK); + case B3SOIFD_MOD_PKB3: + value->rValue = model->B3SOIFDpkb3; + return(OK); + case B3SOIFD_MOD_PDVBD0: + value->rValue = model->B3SOIFDdvbd0; + return(OK); + case B3SOIFD_MOD_PDVBD1: + value->rValue = model->B3SOIFDdvbd1; + return(OK); + case B3SOIFD_MOD_PW0: + value->rValue = model->B3SOIFDpw0; + return(OK); + case B3SOIFD_MOD_PNLX: + value->rValue = model->B3SOIFDpnlx; + return(OK); + case B3SOIFD_MOD_PDVT0 : + value->rValue = model->B3SOIFDpdvt0; + return(OK); + case B3SOIFD_MOD_PDVT1 : + value->rValue = model->B3SOIFDpdvt1; + return(OK); + case B3SOIFD_MOD_PDVT2 : + value->rValue = model->B3SOIFDpdvt2; + return(OK); + case B3SOIFD_MOD_PDVT0W : + value->rValue = model->B3SOIFDpdvt0w; + return(OK); + case B3SOIFD_MOD_PDVT1W : + value->rValue = model->B3SOIFDpdvt1w; + return(OK); + case B3SOIFD_MOD_PDVT2W : + value->rValue = model->B3SOIFDpdvt2w; + return(OK); + case B3SOIFD_MOD_PU0: + value->rValue = model->B3SOIFDpu0; + return(OK); + case B3SOIFD_MOD_PUA: + value->rValue = model->B3SOIFDpua; + return(OK); + case B3SOIFD_MOD_PUB: + value->rValue = model->B3SOIFDpub; + return(OK); + case B3SOIFD_MOD_PUC: + value->rValue = model->B3SOIFDpuc; + return(OK); + case B3SOIFD_MOD_PVSAT: + value->rValue = model->B3SOIFDpvsat; + return(OK); + case B3SOIFD_MOD_PA0: + value->rValue = model->B3SOIFDpa0; + return(OK); + case B3SOIFD_MOD_PAGS: + value->rValue = model->B3SOIFDpags; + return(OK); + case B3SOIFD_MOD_PB0: + value->rValue = model->B3SOIFDpb0; + return(OK); + case B3SOIFD_MOD_PB1: + value->rValue = model->B3SOIFDpb1; + return(OK); + case B3SOIFD_MOD_PKETA: + value->rValue = model->B3SOIFDpketa; + return(OK); + case B3SOIFD_MOD_PABP: + value->rValue = model->B3SOIFDpabp; + return(OK); + case B3SOIFD_MOD_PMXC: + value->rValue = model->B3SOIFDpmxc; + return(OK); + case B3SOIFD_MOD_PADICE0: + value->rValue = model->B3SOIFDpadice0; + return(OK); + case B3SOIFD_MOD_PA1: + value->rValue = model->B3SOIFDpa1; + return(OK); + case B3SOIFD_MOD_PA2: + value->rValue = model->B3SOIFDpa2; + return(OK); + case B3SOIFD_MOD_PRDSW: + value->rValue = model->B3SOIFDprdsw; + return(OK); + case B3SOIFD_MOD_PPRWB: + value->rValue = model->B3SOIFDpprwb; + return(OK); + case B3SOIFD_MOD_PPRWG: + value->rValue = model->B3SOIFDpprwg; + return(OK); + case B3SOIFD_MOD_PWR: + value->rValue = model->B3SOIFDpwr; + return(OK); + case B3SOIFD_MOD_PNFACTOR : + value->rValue = model->B3SOIFDpnfactor; + return(OK); + case B3SOIFD_MOD_PDWG: + value->rValue = model->B3SOIFDpdwg; + return(OK); + case B3SOIFD_MOD_PDWB: + value->rValue = model->B3SOIFDpdwb; + return(OK); + case B3SOIFD_MOD_PVOFF: + value->rValue = model->B3SOIFDpvoff; + return(OK); + case B3SOIFD_MOD_PETA0: + value->rValue = model->B3SOIFDpeta0; + return(OK); + case B3SOIFD_MOD_PETAB: + value->rValue = model->B3SOIFDpetab; + return(OK); + case B3SOIFD_MOD_PDSUB : + value->rValue = model->B3SOIFDpdsub; + return(OK); + case B3SOIFD_MOD_PCIT : + value->rValue = model->B3SOIFDpcit; + return(OK); + case B3SOIFD_MOD_PCDSC : + value->rValue = model->B3SOIFDpcdsc; + return(OK); + case B3SOIFD_MOD_PCDSCB : + value->rValue = model->B3SOIFDpcdscb; + return(OK); + case B3SOIFD_MOD_PCDSCD : + value->rValue = model->B3SOIFDpcdscd; + return(OK); + case B3SOIFD_MOD_PPCLM: + value->rValue = model->B3SOIFDppclm; + return(OK); + case B3SOIFD_MOD_PPDIBL1: + value->rValue = model->B3SOIFDppdibl1; + return(OK); + case B3SOIFD_MOD_PPDIBL2: + value->rValue = model->B3SOIFDppdibl2; + return(OK); + case B3SOIFD_MOD_PPDIBLB: + value->rValue = model->B3SOIFDppdiblb; + return(OK); + case B3SOIFD_MOD_PDROUT : + value->rValue = model->B3SOIFDpdrout; + return(OK); + case B3SOIFD_MOD_PPVAG: + value->rValue = model->B3SOIFDppvag; + return(OK); + case B3SOIFD_MOD_PDELTA: + value->rValue = model->B3SOIFDpdelta; + return(OK); + case B3SOIFD_MOD_PAII: + value->rValue = model->B3SOIFDpaii; + return(OK); + case B3SOIFD_MOD_PBII: + value->rValue = model->B3SOIFDpbii; + return(OK); + case B3SOIFD_MOD_PCII: + value->rValue = model->B3SOIFDpcii; + return(OK); + case B3SOIFD_MOD_PDII: + value->rValue = model->B3SOIFDpdii; + return(OK); + case B3SOIFD_MOD_PALPHA0: + value->rValue = model->B3SOIFDpalpha0; + return(OK); + case B3SOIFD_MOD_PALPHA1: + value->rValue = model->B3SOIFDpalpha1; + return(OK); + case B3SOIFD_MOD_PBETA0: + value->rValue = model->B3SOIFDpbeta0; + return(OK); + case B3SOIFD_MOD_PAGIDL: + value->rValue = model->B3SOIFDpagidl; + return(OK); + case B3SOIFD_MOD_PBGIDL: + value->rValue = model->B3SOIFDpbgidl; + return(OK); + case B3SOIFD_MOD_PNGIDL: + value->rValue = model->B3SOIFDpngidl; + return(OK); + case B3SOIFD_MOD_PNTUN: + value->rValue = model->B3SOIFDpntun; + return(OK); + case B3SOIFD_MOD_PNDIODE: + value->rValue = model->B3SOIFDpndiode; + return(OK); + case B3SOIFD_MOD_PISBJT: + value->rValue = model->B3SOIFDpisbjt; + return(OK); + case B3SOIFD_MOD_PISDIF: + value->rValue = model->B3SOIFDpisdif; + return(OK); + case B3SOIFD_MOD_PISREC: + value->rValue = model->B3SOIFDpisrec; + return(OK); + case B3SOIFD_MOD_PISTUN: + value->rValue = model->B3SOIFDpistun; + return(OK); + case B3SOIFD_MOD_PEDL: + value->rValue = model->B3SOIFDpedl; + return(OK); + case B3SOIFD_MOD_PKBJT1: + value->rValue = model->B3SOIFDpkbjt1; + return(OK); + /* CV Model */ + case B3SOIFD_MOD_PVSDFB: + value->rValue = model->B3SOIFDpvsdfb; + return(OK); + case B3SOIFD_MOD_PVSDTH: + value->rValue = model->B3SOIFDpvsdth; + return(OK); +/* Added for binning - END */ + + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} + + + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdmdel.c b/src/spicelib/devices/bsim3soi_fd/b3soifdmdel.c new file mode 100644 index 000000000..d22d884d9 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdmdel.c @@ -0,0 +1,47 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soifdmdel.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "b3soifddef.h" +#include "sperror.h" +#include "suffix.h" + +int +B3SOIFDmDelete(inModel,modname,kill) +GENmodel **inModel; +IFuid modname; +GENmodel *kill; +{ +B3SOIFDmodel **model = (B3SOIFDmodel**)inModel; +B3SOIFDmodel *modfast = (B3SOIFDmodel*)kill; +B3SOIFDinstance *here; +B3SOIFDinstance *prev = NULL; +B3SOIFDmodel **oldmod; + + oldmod = model; + for (; *model ; model = &((*model)->B3SOIFDnextModel)) + { if ((*model)->B3SOIFDmodName == modname || + (modfast && *model == modfast)) + goto delgot; + oldmod = model; + } + return(E_NOMOD); + +delgot: + *oldmod = (*model)->B3SOIFDnextModel; /* cut deleted device out of list */ + for (here = (*model)->B3SOIFDinstances; here; here = here->B3SOIFDnextInstance) + { if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + FREE(*model); + return(OK); +} + + + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdmpar.c b/src/spicelib/devices/bsim3soi_fd/b3soifdmpar.c new file mode 100644 index 000000000..f195aefe2 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdmpar.c @@ -0,0 +1,1625 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soifdmpar.c 98/5/01 +Modified by Wei Jin 99/9/27 +**********/ + + +#include "ngspice.h" +#include +#include "b3soifddef.h" +#include "ifsim.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIFDmParam(param,value,inMod) +int param; +IFvalue *value; +GENmodel *inMod; +{ + B3SOIFDmodel *mod = (B3SOIFDmodel*)inMod; + switch(param) + { + + case B3SOIFD_MOD_MOBMOD : + mod->B3SOIFDmobMod = value->iValue; + mod->B3SOIFDmobModGiven = TRUE; + break; + case B3SOIFD_MOD_BINUNIT : + mod->B3SOIFDbinUnit = value->iValue; + mod->B3SOIFDbinUnitGiven = TRUE; + break; + case B3SOIFD_MOD_PARAMCHK : + mod->B3SOIFDparamChk = value->iValue; + mod->B3SOIFDparamChkGiven = TRUE; + break; + case B3SOIFD_MOD_CAPMOD : + mod->B3SOIFDcapMod = value->iValue; + mod->B3SOIFDcapModGiven = TRUE; + break; + case B3SOIFD_MOD_SHMOD : + mod->B3SOIFDshMod = value->iValue; + mod->B3SOIFDshModGiven = TRUE; + break; + case B3SOIFD_MOD_NOIMOD : + mod->B3SOIFDnoiMod = value->iValue; + mod->B3SOIFDnoiModGiven = TRUE; + break; + case B3SOIFD_MOD_VERSION : + mod->B3SOIFDversion = value->rValue; + mod->B3SOIFDversionGiven = TRUE; + break; + case B3SOIFD_MOD_TOX : + mod->B3SOIFDtox = value->rValue; + mod->B3SOIFDtoxGiven = TRUE; + break; + + case B3SOIFD_MOD_CDSC : + mod->B3SOIFDcdsc = value->rValue; + mod->B3SOIFDcdscGiven = TRUE; + break; + case B3SOIFD_MOD_CDSCB : + mod->B3SOIFDcdscb = value->rValue; + mod->B3SOIFDcdscbGiven = TRUE; + break; + + case B3SOIFD_MOD_CDSCD : + mod->B3SOIFDcdscd = value->rValue; + mod->B3SOIFDcdscdGiven = TRUE; + break; + + case B3SOIFD_MOD_CIT : + mod->B3SOIFDcit = value->rValue; + mod->B3SOIFDcitGiven = TRUE; + break; + case B3SOIFD_MOD_NFACTOR : + mod->B3SOIFDnfactor = value->rValue; + mod->B3SOIFDnfactorGiven = TRUE; + break; + case B3SOIFD_MOD_VSAT: + mod->B3SOIFDvsat = value->rValue; + mod->B3SOIFDvsatGiven = TRUE; + break; + case B3SOIFD_MOD_A0: + mod->B3SOIFDa0 = value->rValue; + mod->B3SOIFDa0Given = TRUE; + break; + + case B3SOIFD_MOD_AGS: + mod->B3SOIFDags= value->rValue; + mod->B3SOIFDagsGiven = TRUE; + break; + + case B3SOIFD_MOD_A1: + mod->B3SOIFDa1 = value->rValue; + mod->B3SOIFDa1Given = TRUE; + break; + case B3SOIFD_MOD_A2: + mod->B3SOIFDa2 = value->rValue; + mod->B3SOIFDa2Given = TRUE; + break; + case B3SOIFD_MOD_AT: + mod->B3SOIFDat = value->rValue; + mod->B3SOIFDatGiven = TRUE; + break; + case B3SOIFD_MOD_KETA: + mod->B3SOIFDketa = value->rValue; + mod->B3SOIFDketaGiven = TRUE; + break; + case B3SOIFD_MOD_NSUB: + mod->B3SOIFDnsub = value->rValue; + mod->B3SOIFDnsubGiven = TRUE; + break; + case B3SOIFD_MOD_NPEAK: + mod->B3SOIFDnpeak = value->rValue; + mod->B3SOIFDnpeakGiven = TRUE; + if (mod->B3SOIFDnpeak > 1.0e20) + mod->B3SOIFDnpeak *= 1.0e-6; + break; + case B3SOIFD_MOD_NGATE: + mod->B3SOIFDngate = value->rValue; + mod->B3SOIFDngateGiven = TRUE; + if (mod->B3SOIFDngate > 1.0e23) + mod->B3SOIFDngate *= 1.0e-6; + break; + case B3SOIFD_MOD_GAMMA1: + mod->B3SOIFDgamma1 = value->rValue; + mod->B3SOIFDgamma1Given = TRUE; + break; + case B3SOIFD_MOD_GAMMA2: + mod->B3SOIFDgamma2 = value->rValue; + mod->B3SOIFDgamma2Given = TRUE; + break; + case B3SOIFD_MOD_VBX: + mod->B3SOIFDvbx = value->rValue; + mod->B3SOIFDvbxGiven = TRUE; + break; + case B3SOIFD_MOD_VBM: + mod->B3SOIFDvbm = value->rValue; + mod->B3SOIFDvbmGiven = TRUE; + break; + case B3SOIFD_MOD_XT: + mod->B3SOIFDxt = value->rValue; + mod->B3SOIFDxtGiven = TRUE; + break; + case B3SOIFD_MOD_K1: + mod->B3SOIFDk1 = value->rValue; + mod->B3SOIFDk1Given = TRUE; + break; + case B3SOIFD_MOD_KT1: + mod->B3SOIFDkt1 = value->rValue; + mod->B3SOIFDkt1Given = TRUE; + break; + case B3SOIFD_MOD_KT1L: + mod->B3SOIFDkt1l = value->rValue; + mod->B3SOIFDkt1lGiven = TRUE; + break; + case B3SOIFD_MOD_KT2: + mod->B3SOIFDkt2 = value->rValue; + mod->B3SOIFDkt2Given = TRUE; + break; + case B3SOIFD_MOD_K2: + mod->B3SOIFDk2 = value->rValue; + mod->B3SOIFDk2Given = TRUE; + break; + case B3SOIFD_MOD_K3: + mod->B3SOIFDk3 = value->rValue; + mod->B3SOIFDk3Given = TRUE; + break; + case B3SOIFD_MOD_K3B: + mod->B3SOIFDk3b = value->rValue; + mod->B3SOIFDk3bGiven = TRUE; + break; + case B3SOIFD_MOD_NLX: + mod->B3SOIFDnlx = value->rValue; + mod->B3SOIFDnlxGiven = TRUE; + break; + case B3SOIFD_MOD_W0: + mod->B3SOIFDw0 = value->rValue; + mod->B3SOIFDw0Given = TRUE; + break; + case B3SOIFD_MOD_DVT0: + mod->B3SOIFDdvt0 = value->rValue; + mod->B3SOIFDdvt0Given = TRUE; + break; + case B3SOIFD_MOD_DVT1: + mod->B3SOIFDdvt1 = value->rValue; + mod->B3SOIFDdvt1Given = TRUE; + break; + case B3SOIFD_MOD_DVT2: + mod->B3SOIFDdvt2 = value->rValue; + mod->B3SOIFDdvt2Given = TRUE; + break; + case B3SOIFD_MOD_DVT0W: + mod->B3SOIFDdvt0w = value->rValue; + mod->B3SOIFDdvt0wGiven = TRUE; + break; + case B3SOIFD_MOD_DVT1W: + mod->B3SOIFDdvt1w = value->rValue; + mod->B3SOIFDdvt1wGiven = TRUE; + break; + case B3SOIFD_MOD_DVT2W: + mod->B3SOIFDdvt2w = value->rValue; + mod->B3SOIFDdvt2wGiven = TRUE; + break; + case B3SOIFD_MOD_DROUT: + mod->B3SOIFDdrout = value->rValue; + mod->B3SOIFDdroutGiven = TRUE; + break; + case B3SOIFD_MOD_DSUB: + mod->B3SOIFDdsub = value->rValue; + mod->B3SOIFDdsubGiven = TRUE; + break; + case B3SOIFD_MOD_VTH0: + mod->B3SOIFDvth0 = value->rValue; + mod->B3SOIFDvth0Given = TRUE; + break; + case B3SOIFD_MOD_UA: + mod->B3SOIFDua = value->rValue; + mod->B3SOIFDuaGiven = TRUE; + break; + case B3SOIFD_MOD_UA1: + mod->B3SOIFDua1 = value->rValue; + mod->B3SOIFDua1Given = TRUE; + break; + case B3SOIFD_MOD_UB: + mod->B3SOIFDub = value->rValue; + mod->B3SOIFDubGiven = TRUE; + break; + case B3SOIFD_MOD_UB1: + mod->B3SOIFDub1 = value->rValue; + mod->B3SOIFDub1Given = TRUE; + break; + case B3SOIFD_MOD_UC: + mod->B3SOIFDuc = value->rValue; + mod->B3SOIFDucGiven = TRUE; + break; + case B3SOIFD_MOD_UC1: + mod->B3SOIFDuc1 = value->rValue; + mod->B3SOIFDuc1Given = TRUE; + break; + case B3SOIFD_MOD_U0 : + mod->B3SOIFDu0 = value->rValue; + mod->B3SOIFDu0Given = TRUE; + break; + case B3SOIFD_MOD_UTE : + mod->B3SOIFDute = value->rValue; + mod->B3SOIFDuteGiven = TRUE; + break; + case B3SOIFD_MOD_VOFF: + mod->B3SOIFDvoff = value->rValue; + mod->B3SOIFDvoffGiven = TRUE; + break; + case B3SOIFD_MOD_DELTA : + mod->B3SOIFDdelta = value->rValue; + mod->B3SOIFDdeltaGiven = TRUE; + break; + case B3SOIFD_MOD_RDSW: + mod->B3SOIFDrdsw = value->rValue; + mod->B3SOIFDrdswGiven = TRUE; + break; + case B3SOIFD_MOD_PRWG: + mod->B3SOIFDprwg = value->rValue; + mod->B3SOIFDprwgGiven = TRUE; + break; + case B3SOIFD_MOD_PRWB: + mod->B3SOIFDprwb = value->rValue; + mod->B3SOIFDprwbGiven = TRUE; + break; + case B3SOIFD_MOD_PRT: + mod->B3SOIFDprt = value->rValue; + mod->B3SOIFDprtGiven = TRUE; + break; + case B3SOIFD_MOD_ETA0: + mod->B3SOIFDeta0 = value->rValue; + mod->B3SOIFDeta0Given = TRUE; + break; + case B3SOIFD_MOD_ETAB: + mod->B3SOIFDetab = value->rValue; + mod->B3SOIFDetabGiven = TRUE; + break; + case B3SOIFD_MOD_PCLM: + mod->B3SOIFDpclm = value->rValue; + mod->B3SOIFDpclmGiven = TRUE; + break; + case B3SOIFD_MOD_PDIBL1: + mod->B3SOIFDpdibl1 = value->rValue; + mod->B3SOIFDpdibl1Given = TRUE; + break; + case B3SOIFD_MOD_PDIBL2: + mod->B3SOIFDpdibl2 = value->rValue; + mod->B3SOIFDpdibl2Given = TRUE; + break; + case B3SOIFD_MOD_PDIBLB: + mod->B3SOIFDpdiblb = value->rValue; + mod->B3SOIFDpdiblbGiven = TRUE; + break; + case B3SOIFD_MOD_PVAG: + mod->B3SOIFDpvag = value->rValue; + mod->B3SOIFDpvagGiven = TRUE; + break; + case B3SOIFD_MOD_WR : + mod->B3SOIFDwr = value->rValue; + mod->B3SOIFDwrGiven = TRUE; + break; + case B3SOIFD_MOD_DWG : + mod->B3SOIFDdwg = value->rValue; + mod->B3SOIFDdwgGiven = TRUE; + break; + case B3SOIFD_MOD_DWB : + mod->B3SOIFDdwb = value->rValue; + mod->B3SOIFDdwbGiven = TRUE; + break; + case B3SOIFD_MOD_B0 : + mod->B3SOIFDb0 = value->rValue; + mod->B3SOIFDb0Given = TRUE; + break; + case B3SOIFD_MOD_B1 : + mod->B3SOIFDb1 = value->rValue; + mod->B3SOIFDb1Given = TRUE; + break; + case B3SOIFD_MOD_ALPHA0 : + mod->B3SOIFDalpha0 = value->rValue; + mod->B3SOIFDalpha0Given = TRUE; + break; + case B3SOIFD_MOD_ALPHA1 : + mod->B3SOIFDalpha1 = value->rValue; + mod->B3SOIFDalpha1Given = TRUE; + break; + case B3SOIFD_MOD_BETA0 : + mod->B3SOIFDbeta0 = value->rValue; + mod->B3SOIFDbeta0Given = TRUE; + break; + + case B3SOIFD_MOD_CGSL : + mod->B3SOIFDcgsl = value->rValue; + mod->B3SOIFDcgslGiven = TRUE; + break; + case B3SOIFD_MOD_CGDL : + mod->B3SOIFDcgdl = value->rValue; + mod->B3SOIFDcgdlGiven = TRUE; + break; + case B3SOIFD_MOD_CKAPPA : + mod->B3SOIFDckappa = value->rValue; + mod->B3SOIFDckappaGiven = TRUE; + break; + case B3SOIFD_MOD_CF : + mod->B3SOIFDcf = value->rValue; + mod->B3SOIFDcfGiven = TRUE; + break; + case B3SOIFD_MOD_CLC : + mod->B3SOIFDclc = value->rValue; + mod->B3SOIFDclcGiven = TRUE; + break; + case B3SOIFD_MOD_CLE : + mod->B3SOIFDcle = value->rValue; + mod->B3SOIFDcleGiven = TRUE; + break; + case B3SOIFD_MOD_DWC : + mod->B3SOIFDdwc = value->rValue; + mod->B3SOIFDdwcGiven = TRUE; + break; + case B3SOIFD_MOD_DLC : + mod->B3SOIFDdlc = value->rValue; + mod->B3SOIFDdlcGiven = TRUE; + break; + case B3SOIFD_MOD_TBOX : + mod->B3SOIFDtbox = value->rValue; + mod->B3SOIFDtboxGiven = TRUE; + break; + case B3SOIFD_MOD_TSI : + mod->B3SOIFDtsi = value->rValue; + mod->B3SOIFDtsiGiven = TRUE; + break; + case B3SOIFD_MOD_XJ : + mod->B3SOIFDxj = value->rValue; + mod->B3SOIFDxjGiven = TRUE; + break; + case B3SOIFD_MOD_KB1 : + mod->B3SOIFDkb1 = value->rValue; + mod->B3SOIFDkb1Given = TRUE; + break; + case B3SOIFD_MOD_KB3 : + mod->B3SOIFDkb3 = value->rValue; + mod->B3SOIFDkb3Given = TRUE; + break; + case B3SOIFD_MOD_DVBD0 : + mod->B3SOIFDdvbd0 = value->rValue; + mod->B3SOIFDdvbd0Given = TRUE; + break; + case B3SOIFD_MOD_DVBD1 : + mod->B3SOIFDdvbd1 = value->rValue; + mod->B3SOIFDdvbd1Given = TRUE; + break; + case B3SOIFD_MOD_DELP : + mod->B3SOIFDdelp = value->rValue; + mod->B3SOIFDdelpGiven = TRUE; + break; + case B3SOIFD_MOD_VBSA : + mod->B3SOIFDvbsa = value->rValue; + mod->B3SOIFDvbsaGiven = TRUE; + break; + case B3SOIFD_MOD_RBODY : + mod->B3SOIFDrbody = value->rValue; + mod->B3SOIFDrbodyGiven = TRUE; + break; + case B3SOIFD_MOD_RBSH : + mod->B3SOIFDrbsh = value->rValue; + mod->B3SOIFDrbshGiven = TRUE; + break; + case B3SOIFD_MOD_ADICE0 : + mod->B3SOIFDadice0 = value->rValue; + mod->B3SOIFDadice0Given = TRUE; + break; + case B3SOIFD_MOD_ABP : + mod->B3SOIFDabp = value->rValue; + mod->B3SOIFDabpGiven = TRUE; + break; + case B3SOIFD_MOD_MXC : + mod->B3SOIFDmxc = value->rValue; + mod->B3SOIFDmxcGiven = TRUE; + break; + case B3SOIFD_MOD_RTH0 : + mod->B3SOIFDrth0 = value->rValue; + mod->B3SOIFDrth0Given = TRUE; + break; + case B3SOIFD_MOD_CTH0 : + mod->B3SOIFDcth0 = value->rValue; + mod->B3SOIFDcth0Given = TRUE; + break; + case B3SOIFD_MOD_AII : + mod->B3SOIFDaii = value->rValue; + mod->B3SOIFDaiiGiven = TRUE; + break; + case B3SOIFD_MOD_BII : + mod->B3SOIFDbii = value->rValue; + mod->B3SOIFDbiiGiven = TRUE; + break; + case B3SOIFD_MOD_CII : + mod->B3SOIFDcii = value->rValue; + mod->B3SOIFDciiGiven = TRUE; + break; + case B3SOIFD_MOD_DII : + mod->B3SOIFDdii = value->rValue; + mod->B3SOIFDdiiGiven = TRUE; + break; + case B3SOIFD_MOD_NGIDL : + mod->B3SOIFDngidl = value->rValue; + mod->B3SOIFDngidlGiven = TRUE; + break; + case B3SOIFD_MOD_AGIDL : + mod->B3SOIFDagidl = value->rValue; + mod->B3SOIFDagidlGiven = TRUE; + break; + case B3SOIFD_MOD_BGIDL : + mod->B3SOIFDbgidl = value->rValue; + mod->B3SOIFDbgidlGiven = TRUE; + break; + case B3SOIFD_MOD_NDIODE : + mod->B3SOIFDndiode = value->rValue; + mod->B3SOIFDndiodeGiven = TRUE; + break; + case B3SOIFD_MOD_NTUN : + mod->B3SOIFDntun = value->rValue; + mod->B3SOIFDntunGiven = TRUE; + break; + case B3SOIFD_MOD_ISBJT : + mod->B3SOIFDisbjt = value->rValue; + mod->B3SOIFDisbjtGiven = TRUE; + break; + case B3SOIFD_MOD_ISDIF : + mod->B3SOIFDisdif = value->rValue; + mod->B3SOIFDisdifGiven = TRUE; + break; + case B3SOIFD_MOD_ISREC : + mod->B3SOIFDisrec = value->rValue; + mod->B3SOIFDisrecGiven = TRUE; + break; + case B3SOIFD_MOD_ISTUN : + mod->B3SOIFDistun = value->rValue; + mod->B3SOIFDistunGiven = TRUE; + break; + case B3SOIFD_MOD_XBJT : + mod->B3SOIFDxbjt = value->rValue; + mod->B3SOIFDxbjtGiven = TRUE; + break; + case B3SOIFD_MOD_XREC : + mod->B3SOIFDxrec = value->rValue; + mod->B3SOIFDxrecGiven = TRUE; + break; + case B3SOIFD_MOD_XTUN : + mod->B3SOIFDxtun = value->rValue; + mod->B3SOIFDxtunGiven = TRUE; + break; + case B3SOIFD_MOD_EDL : + mod->B3SOIFDedl = value->rValue; + mod->B3SOIFDedlGiven = TRUE; + break; + case B3SOIFD_MOD_KBJT1 : + mod->B3SOIFDkbjt1 = value->rValue; + mod->B3SOIFDkbjt1Given = TRUE; + break; + case B3SOIFD_MOD_TT : + mod->B3SOIFDtt = value->rValue; + mod->B3SOIFDttGiven = TRUE; + break; + case B3SOIFD_MOD_VSDTH : + mod->B3SOIFDvsdth = value->rValue; + mod->B3SOIFDvsdthGiven = TRUE; + break; + case B3SOIFD_MOD_VSDFB : + mod->B3SOIFDvsdfb = value->rValue; + mod->B3SOIFDvsdfbGiven = TRUE; + break; + case B3SOIFD_MOD_CSDMIN : + mod->B3SOIFDcsdmin = value->rValue; + mod->B3SOIFDcsdminGiven = TRUE; + break; + case B3SOIFD_MOD_ASD : + mod->B3SOIFDasd = value->rValue; + mod->B3SOIFDasdGiven = TRUE; + break; + + + case B3SOIFD_MOD_TNOM : + mod->B3SOIFDtnom = value->rValue + 273.15; + mod->B3SOIFDtnomGiven = TRUE; + break; + case B3SOIFD_MOD_CGSO : + mod->B3SOIFDcgso = value->rValue; + mod->B3SOIFDcgsoGiven = TRUE; + break; + case B3SOIFD_MOD_CGDO : + mod->B3SOIFDcgdo = value->rValue; + mod->B3SOIFDcgdoGiven = TRUE; + break; + case B3SOIFD_MOD_CGEO : + mod->B3SOIFDcgeo = value->rValue; + mod->B3SOIFDcgeoGiven = TRUE; + break; + case B3SOIFD_MOD_XPART : + mod->B3SOIFDxpart = value->rValue; + mod->B3SOIFDxpartGiven = TRUE; + break; + case B3SOIFD_MOD_RSH : + mod->B3SOIFDsheetResistance = value->rValue; + mod->B3SOIFDsheetResistanceGiven = TRUE; + break; + case B3SOIFD_MOD_PBSWG : + mod->B3SOIFDGatesidewallJctPotential = value->rValue; + mod->B3SOIFDGatesidewallJctPotentialGiven = TRUE; + break; + case B3SOIFD_MOD_MJSWG : + mod->B3SOIFDbodyJctGateSideGradingCoeff = value->rValue; + mod->B3SOIFDbodyJctGateSideGradingCoeffGiven = TRUE; + break; + case B3SOIFD_MOD_CJSWG : + mod->B3SOIFDunitLengthGateSidewallJctCap = value->rValue; + mod->B3SOIFDunitLengthGateSidewallJctCapGiven = TRUE; + break; + case B3SOIFD_MOD_CSDESW : + mod->B3SOIFDcsdesw = value->rValue; + mod->B3SOIFDcsdeswGiven = TRUE; + break; + case B3SOIFD_MOD_LINT : + mod->B3SOIFDLint = value->rValue; + mod->B3SOIFDLintGiven = TRUE; + break; + case B3SOIFD_MOD_LL : + mod->B3SOIFDLl = value->rValue; + mod->B3SOIFDLlGiven = TRUE; + break; + case B3SOIFD_MOD_LLN : + mod->B3SOIFDLln = value->rValue; + mod->B3SOIFDLlnGiven = TRUE; + break; + case B3SOIFD_MOD_LW : + mod->B3SOIFDLw = value->rValue; + mod->B3SOIFDLwGiven = TRUE; + break; + case B3SOIFD_MOD_LWN : + mod->B3SOIFDLwn = value->rValue; + mod->B3SOIFDLwnGiven = TRUE; + break; + case B3SOIFD_MOD_LWL : + mod->B3SOIFDLwl = value->rValue; + mod->B3SOIFDLwlGiven = TRUE; + break; + case B3SOIFD_MOD_WINT : + mod->B3SOIFDWint = value->rValue; + mod->B3SOIFDWintGiven = TRUE; + break; + case B3SOIFD_MOD_WL : + mod->B3SOIFDWl = value->rValue; + mod->B3SOIFDWlGiven = TRUE; + break; + case B3SOIFD_MOD_WLN : + mod->B3SOIFDWln = value->rValue; + mod->B3SOIFDWlnGiven = TRUE; + break; + case B3SOIFD_MOD_WW : + mod->B3SOIFDWw = value->rValue; + mod->B3SOIFDWwGiven = TRUE; + break; + case B3SOIFD_MOD_WWN : + mod->B3SOIFDWwn = value->rValue; + mod->B3SOIFDWwnGiven = TRUE; + break; + case B3SOIFD_MOD_WWL : + mod->B3SOIFDWwl = value->rValue; + mod->B3SOIFDWwlGiven = TRUE; + break; + + case B3SOIFD_MOD_NOIA : + mod->B3SOIFDoxideTrapDensityA = value->rValue; + mod->B3SOIFDoxideTrapDensityAGiven = TRUE; + break; + case B3SOIFD_MOD_NOIB : + mod->B3SOIFDoxideTrapDensityB = value->rValue; + mod->B3SOIFDoxideTrapDensityBGiven = TRUE; + break; + case B3SOIFD_MOD_NOIC : + mod->B3SOIFDoxideTrapDensityC = value->rValue; + mod->B3SOIFDoxideTrapDensityCGiven = TRUE; + break; + case B3SOIFD_MOD_NOIF : + mod->B3SOIFDnoif = value->rValue; + mod->B3SOIFDnoifGiven = TRUE; + break; + case B3SOIFD_MOD_EM : + mod->B3SOIFDem = value->rValue; + mod->B3SOIFDemGiven = TRUE; + break; + case B3SOIFD_MOD_EF : + mod->B3SOIFDef = value->rValue; + mod->B3SOIFDefGiven = TRUE; + break; + case B3SOIFD_MOD_AF : + mod->B3SOIFDaf = value->rValue; + mod->B3SOIFDafGiven = TRUE; + break; + case B3SOIFD_MOD_KF : + mod->B3SOIFDkf = value->rValue; + mod->B3SOIFDkfGiven = TRUE; + break; + +/* Added for binning - START */ + /* Length Dependence */ + case B3SOIFD_MOD_LNPEAK: + mod->B3SOIFDlnpeak = value->rValue; + mod->B3SOIFDlnpeakGiven = TRUE; + break; + case B3SOIFD_MOD_LNSUB: + mod->B3SOIFDlnsub = value->rValue; + mod->B3SOIFDlnsubGiven = TRUE; + break; + case B3SOIFD_MOD_LNGATE: + mod->B3SOIFDlngate = value->rValue; + mod->B3SOIFDlngateGiven = TRUE; + break; + case B3SOIFD_MOD_LVTH0: + mod->B3SOIFDlvth0 = value->rValue; + mod->B3SOIFDlvth0Given = TRUE; + break; + case B3SOIFD_MOD_LK1: + mod->B3SOIFDlk1 = value->rValue; + mod->B3SOIFDlk1Given = TRUE; + break; + case B3SOIFD_MOD_LK2: + mod->B3SOIFDlk2 = value->rValue; + mod->B3SOIFDlk2Given = TRUE; + break; + case B3SOIFD_MOD_LK3: + mod->B3SOIFDlk3 = value->rValue; + mod->B3SOIFDlk3Given = TRUE; + break; + case B3SOIFD_MOD_LK3B: + mod->B3SOIFDlk3b = value->rValue; + mod->B3SOIFDlk3bGiven = TRUE; + break; + case B3SOIFD_MOD_LVBSA: + mod->B3SOIFDlvbsa = value->rValue; + mod->B3SOIFDlvbsaGiven = TRUE; + break; + case B3SOIFD_MOD_LDELP: + mod->B3SOIFDldelp = value->rValue; + mod->B3SOIFDldelpGiven = TRUE; + break; + case B3SOIFD_MOD_LKB1 : + mod->B3SOIFDlkb1 = value->rValue; + mod->B3SOIFDlkb1Given = TRUE; + break; + case B3SOIFD_MOD_LKB3 : + mod->B3SOIFDlkb3 = value->rValue; + mod->B3SOIFDlkb3Given = TRUE; + break; + case B3SOIFD_MOD_LDVBD0 : + mod->B3SOIFDldvbd0 = value->rValue; + mod->B3SOIFDldvbd0Given = TRUE; + break; + case B3SOIFD_MOD_LDVBD1 : + mod->B3SOIFDldvbd1 = value->rValue; + mod->B3SOIFDldvbd1Given = TRUE; + break; + case B3SOIFD_MOD_LW0: + mod->B3SOIFDlw0 = value->rValue; + mod->B3SOIFDlw0Given = TRUE; + break; + case B3SOIFD_MOD_LNLX: + mod->B3SOIFDlnlx = value->rValue; + mod->B3SOIFDlnlxGiven = TRUE; + break; + case B3SOIFD_MOD_LDVT0: + mod->B3SOIFDldvt0 = value->rValue; + mod->B3SOIFDldvt0Given = TRUE; + break; + case B3SOIFD_MOD_LDVT1: + mod->B3SOIFDldvt1 = value->rValue; + mod->B3SOIFDldvt1Given = TRUE; + break; + case B3SOIFD_MOD_LDVT2: + mod->B3SOIFDldvt2 = value->rValue; + mod->B3SOIFDldvt2Given = TRUE; + break; + case B3SOIFD_MOD_LDVT0W: + mod->B3SOIFDldvt0w = value->rValue; + mod->B3SOIFDldvt0wGiven = TRUE; + break; + case B3SOIFD_MOD_LDVT1W: + mod->B3SOIFDldvt1w = value->rValue; + mod->B3SOIFDldvt1wGiven = TRUE; + break; + case B3SOIFD_MOD_LDVT2W: + mod->B3SOIFDldvt2w = value->rValue; + mod->B3SOIFDldvt2wGiven = TRUE; + break; + case B3SOIFD_MOD_LU0 : + mod->B3SOIFDlu0 = value->rValue; + mod->B3SOIFDlu0Given = TRUE; + break; + case B3SOIFD_MOD_LUA: + mod->B3SOIFDlua = value->rValue; + mod->B3SOIFDluaGiven = TRUE; + break; + case B3SOIFD_MOD_LUB: + mod->B3SOIFDlub = value->rValue; + mod->B3SOIFDlubGiven = TRUE; + break; + case B3SOIFD_MOD_LUC: + mod->B3SOIFDluc = value->rValue; + mod->B3SOIFDlucGiven = TRUE; + break; + case B3SOIFD_MOD_LVSAT: + mod->B3SOIFDlvsat = value->rValue; + mod->B3SOIFDlvsatGiven = TRUE; + break; + case B3SOIFD_MOD_LA0: + mod->B3SOIFDla0 = value->rValue; + mod->B3SOIFDla0Given = TRUE; + break; + case B3SOIFD_MOD_LAGS: + mod->B3SOIFDlags= value->rValue; + mod->B3SOIFDlagsGiven = TRUE; + break; + case B3SOIFD_MOD_LB0 : + mod->B3SOIFDlb0 = value->rValue; + mod->B3SOIFDlb0Given = TRUE; + break; + case B3SOIFD_MOD_LB1 : + mod->B3SOIFDlb1 = value->rValue; + mod->B3SOIFDlb1Given = TRUE; + break; + case B3SOIFD_MOD_LKETA: + mod->B3SOIFDlketa = value->rValue; + mod->B3SOIFDlketaGiven = TRUE; + break; + case B3SOIFD_MOD_LABP: + mod->B3SOIFDlabp = value->rValue; + mod->B3SOIFDlabpGiven = TRUE; + break; + case B3SOIFD_MOD_LMXC: + mod->B3SOIFDlmxc = value->rValue; + mod->B3SOIFDlmxcGiven = TRUE; + break; + case B3SOIFD_MOD_LADICE0: + mod->B3SOIFDladice0 = value->rValue; + mod->B3SOIFDladice0Given = TRUE; + break; + case B3SOIFD_MOD_LA1: + mod->B3SOIFDla1 = value->rValue; + mod->B3SOIFDla1Given = TRUE; + break; + case B3SOIFD_MOD_LA2: + mod->B3SOIFDla2 = value->rValue; + mod->B3SOIFDla2Given = TRUE; + break; + case B3SOIFD_MOD_LRDSW: + mod->B3SOIFDlrdsw = value->rValue; + mod->B3SOIFDlrdswGiven = TRUE; + break; + case B3SOIFD_MOD_LPRWB: + mod->B3SOIFDlprwb = value->rValue; + mod->B3SOIFDlprwbGiven = TRUE; + break; + case B3SOIFD_MOD_LPRWG: + mod->B3SOIFDlprwg = value->rValue; + mod->B3SOIFDlprwgGiven = TRUE; + break; + case B3SOIFD_MOD_LWR : + mod->B3SOIFDlwr = value->rValue; + mod->B3SOIFDlwrGiven = TRUE; + break; + case B3SOIFD_MOD_LNFACTOR : + mod->B3SOIFDlnfactor = value->rValue; + mod->B3SOIFDlnfactorGiven = TRUE; + break; + case B3SOIFD_MOD_LDWG : + mod->B3SOIFDldwg = value->rValue; + mod->B3SOIFDldwgGiven = TRUE; + break; + case B3SOIFD_MOD_LDWB : + mod->B3SOIFDldwb = value->rValue; + mod->B3SOIFDldwbGiven = TRUE; + break; + case B3SOIFD_MOD_LVOFF: + mod->B3SOIFDlvoff = value->rValue; + mod->B3SOIFDlvoffGiven = TRUE; + break; + case B3SOIFD_MOD_LETA0: + mod->B3SOIFDleta0 = value->rValue; + mod->B3SOIFDleta0Given = TRUE; + break; + case B3SOIFD_MOD_LETAB: + mod->B3SOIFDletab = value->rValue; + mod->B3SOIFDletabGiven = TRUE; + break; + case B3SOIFD_MOD_LDSUB: + mod->B3SOIFDldsub = value->rValue; + mod->B3SOIFDldsubGiven = TRUE; + break; + case B3SOIFD_MOD_LCIT : + mod->B3SOIFDlcit = value->rValue; + mod->B3SOIFDlcitGiven = TRUE; + break; + case B3SOIFD_MOD_LCDSC : + mod->B3SOIFDlcdsc = value->rValue; + mod->B3SOIFDlcdscGiven = TRUE; + break; + case B3SOIFD_MOD_LCDSCB : + mod->B3SOIFDlcdscb = value->rValue; + mod->B3SOIFDlcdscbGiven = TRUE; + break; + case B3SOIFD_MOD_LCDSCD : + mod->B3SOIFDlcdscd = value->rValue; + mod->B3SOIFDlcdscdGiven = TRUE; + break; + case B3SOIFD_MOD_LPCLM: + mod->B3SOIFDlpclm = value->rValue; + mod->B3SOIFDlpclmGiven = TRUE; + break; + case B3SOIFD_MOD_LPDIBL1: + mod->B3SOIFDlpdibl1 = value->rValue; + mod->B3SOIFDlpdibl1Given = TRUE; + break; + case B3SOIFD_MOD_LPDIBL2: + mod->B3SOIFDlpdibl2 = value->rValue; + mod->B3SOIFDlpdibl2Given = TRUE; + break; + case B3SOIFD_MOD_LPDIBLB: + mod->B3SOIFDlpdiblb = value->rValue; + mod->B3SOIFDlpdiblbGiven = TRUE; + break; + case B3SOIFD_MOD_LDROUT: + mod->B3SOIFDldrout = value->rValue; + mod->B3SOIFDldroutGiven = TRUE; + break; + case B3SOIFD_MOD_LPVAG: + mod->B3SOIFDlpvag = value->rValue; + mod->B3SOIFDlpvagGiven = TRUE; + break; + case B3SOIFD_MOD_LDELTA : + mod->B3SOIFDldelta = value->rValue; + mod->B3SOIFDldeltaGiven = TRUE; + break; + case B3SOIFD_MOD_LAII : + mod->B3SOIFDlaii = value->rValue; + mod->B3SOIFDlaiiGiven = TRUE; + break; + case B3SOIFD_MOD_LBII : + mod->B3SOIFDlbii = value->rValue; + mod->B3SOIFDlbiiGiven = TRUE; + break; + case B3SOIFD_MOD_LCII : + mod->B3SOIFDlcii = value->rValue; + mod->B3SOIFDlciiGiven = TRUE; + break; + case B3SOIFD_MOD_LDII : + mod->B3SOIFDldii = value->rValue; + mod->B3SOIFDldiiGiven = TRUE; + break; + case B3SOIFD_MOD_LALPHA0 : + mod->B3SOIFDlalpha0 = value->rValue; + mod->B3SOIFDlalpha0Given = TRUE; + break; + case B3SOIFD_MOD_LALPHA1 : + mod->B3SOIFDlalpha1 = value->rValue; + mod->B3SOIFDlalpha1Given = TRUE; + break; + case B3SOIFD_MOD_LBETA0 : + mod->B3SOIFDlbeta0 = value->rValue; + mod->B3SOIFDlbeta0Given = TRUE; + break; + case B3SOIFD_MOD_LAGIDL : + mod->B3SOIFDlagidl = value->rValue; + mod->B3SOIFDlagidlGiven = TRUE; + break; + case B3SOIFD_MOD_LBGIDL : + mod->B3SOIFDlbgidl = value->rValue; + mod->B3SOIFDlbgidlGiven = TRUE; + break; + case B3SOIFD_MOD_LNGIDL : + mod->B3SOIFDlngidl = value->rValue; + mod->B3SOIFDlngidlGiven = TRUE; + break; + case B3SOIFD_MOD_LNTUN : + mod->B3SOIFDlntun = value->rValue; + mod->B3SOIFDlntunGiven = TRUE; + break; + case B3SOIFD_MOD_LNDIODE : + mod->B3SOIFDlndiode = value->rValue; + mod->B3SOIFDlndiodeGiven = TRUE; + break; + case B3SOIFD_MOD_LISBJT : + mod->B3SOIFDlisbjt = value->rValue; + mod->B3SOIFDlisbjtGiven = TRUE; + break; + case B3SOIFD_MOD_LISDIF : + mod->B3SOIFDlisdif = value->rValue; + mod->B3SOIFDlisdifGiven = TRUE; + break; + case B3SOIFD_MOD_LISREC : + mod->B3SOIFDlisrec = value->rValue; + mod->B3SOIFDlisrecGiven = TRUE; + break; + case B3SOIFD_MOD_LISTUN : + mod->B3SOIFDlistun = value->rValue; + mod->B3SOIFDlistunGiven = TRUE; + break; + case B3SOIFD_MOD_LEDL : + mod->B3SOIFDledl = value->rValue; + mod->B3SOIFDledlGiven = TRUE; + break; + case B3SOIFD_MOD_LKBJT1 : + mod->B3SOIFDlkbjt1 = value->rValue; + mod->B3SOIFDlkbjt1Given = TRUE; + break; + /* CV Model */ + case B3SOIFD_MOD_LVSDFB : + mod->B3SOIFDlvsdfb = value->rValue; + mod->B3SOIFDlvsdfbGiven = TRUE; + break; + case B3SOIFD_MOD_LVSDTH : + mod->B3SOIFDlvsdth = value->rValue; + mod->B3SOIFDlvsdthGiven = TRUE; + break; + /* Width Dependence */ + case B3SOIFD_MOD_WNPEAK: + mod->B3SOIFDwnpeak = value->rValue; + mod->B3SOIFDwnpeakGiven = TRUE; + break; + case B3SOIFD_MOD_WNSUB: + mod->B3SOIFDwnsub = value->rValue; + mod->B3SOIFDwnsubGiven = TRUE; + break; + case B3SOIFD_MOD_WNGATE: + mod->B3SOIFDwngate = value->rValue; + mod->B3SOIFDwngateGiven = TRUE; + break; + case B3SOIFD_MOD_WVTH0: + mod->B3SOIFDwvth0 = value->rValue; + mod->B3SOIFDwvth0Given = TRUE; + break; + case B3SOIFD_MOD_WK1: + mod->B3SOIFDwk1 = value->rValue; + mod->B3SOIFDwk1Given = TRUE; + break; + case B3SOIFD_MOD_WK2: + mod->B3SOIFDwk2 = value->rValue; + mod->B3SOIFDwk2Given = TRUE; + break; + case B3SOIFD_MOD_WK3: + mod->B3SOIFDwk3 = value->rValue; + mod->B3SOIFDwk3Given = TRUE; + break; + case B3SOIFD_MOD_WK3B: + mod->B3SOIFDwk3b = value->rValue; + mod->B3SOIFDwk3bGiven = TRUE; + break; + case B3SOIFD_MOD_WVBSA: + mod->B3SOIFDwvbsa = value->rValue; + mod->B3SOIFDwvbsaGiven = TRUE; + break; + case B3SOIFD_MOD_WDELP: + mod->B3SOIFDwdelp = value->rValue; + mod->B3SOIFDwdelpGiven = TRUE; + break; + case B3SOIFD_MOD_WKB1 : + mod->B3SOIFDwkb1 = value->rValue; + mod->B3SOIFDwkb1Given = TRUE; + break; + case B3SOIFD_MOD_WKB3 : + mod->B3SOIFDwkb3 = value->rValue; + mod->B3SOIFDwkb3Given = TRUE; + break; + case B3SOIFD_MOD_WDVBD0 : + mod->B3SOIFDwdvbd0 = value->rValue; + mod->B3SOIFDwdvbd0Given = TRUE; + break; + case B3SOIFD_MOD_WDVBD1 : + mod->B3SOIFDwdvbd1 = value->rValue; + mod->B3SOIFDwdvbd1Given = TRUE; + break; + case B3SOIFD_MOD_WW0: + mod->B3SOIFDww0 = value->rValue; + mod->B3SOIFDww0Given = TRUE; + break; + case B3SOIFD_MOD_WNLX: + mod->B3SOIFDwnlx = value->rValue; + mod->B3SOIFDwnlxGiven = TRUE; + break; + case B3SOIFD_MOD_WDVT0: + mod->B3SOIFDwdvt0 = value->rValue; + mod->B3SOIFDwdvt0Given = TRUE; + break; + case B3SOIFD_MOD_WDVT1: + mod->B3SOIFDwdvt1 = value->rValue; + mod->B3SOIFDwdvt1Given = TRUE; + break; + case B3SOIFD_MOD_WDVT2: + mod->B3SOIFDwdvt2 = value->rValue; + mod->B3SOIFDwdvt2Given = TRUE; + break; + case B3SOIFD_MOD_WDVT0W: + mod->B3SOIFDwdvt0w = value->rValue; + mod->B3SOIFDwdvt0wGiven = TRUE; + break; + case B3SOIFD_MOD_WDVT1W: + mod->B3SOIFDwdvt1w = value->rValue; + mod->B3SOIFDwdvt1wGiven = TRUE; + break; + case B3SOIFD_MOD_WDVT2W: + mod->B3SOIFDwdvt2w = value->rValue; + mod->B3SOIFDwdvt2wGiven = TRUE; + break; + case B3SOIFD_MOD_WU0 : + mod->B3SOIFDwu0 = value->rValue; + mod->B3SOIFDwu0Given = TRUE; + break; + case B3SOIFD_MOD_WUA: + mod->B3SOIFDwua = value->rValue; + mod->B3SOIFDwuaGiven = TRUE; + break; + case B3SOIFD_MOD_WUB: + mod->B3SOIFDwub = value->rValue; + mod->B3SOIFDwubGiven = TRUE; + break; + case B3SOIFD_MOD_WUC: + mod->B3SOIFDwuc = value->rValue; + mod->B3SOIFDwucGiven = TRUE; + break; + case B3SOIFD_MOD_WVSAT: + mod->B3SOIFDwvsat = value->rValue; + mod->B3SOIFDwvsatGiven = TRUE; + break; + case B3SOIFD_MOD_WA0: + mod->B3SOIFDwa0 = value->rValue; + mod->B3SOIFDwa0Given = TRUE; + break; + case B3SOIFD_MOD_WAGS: + mod->B3SOIFDwags= value->rValue; + mod->B3SOIFDwagsGiven = TRUE; + break; + case B3SOIFD_MOD_WB0 : + mod->B3SOIFDwb0 = value->rValue; + mod->B3SOIFDwb0Given = TRUE; + break; + case B3SOIFD_MOD_WB1 : + mod->B3SOIFDwb1 = value->rValue; + mod->B3SOIFDwb1Given = TRUE; + break; + case B3SOIFD_MOD_WKETA: + mod->B3SOIFDwketa = value->rValue; + mod->B3SOIFDwketaGiven = TRUE; + break; + case B3SOIFD_MOD_WABP: + mod->B3SOIFDwabp = value->rValue; + mod->B3SOIFDwabpGiven = TRUE; + break; + case B3SOIFD_MOD_WMXC: + mod->B3SOIFDwmxc = value->rValue; + mod->B3SOIFDwmxcGiven = TRUE; + break; + case B3SOIFD_MOD_WADICE0: + mod->B3SOIFDwadice0 = value->rValue; + mod->B3SOIFDwadice0Given = TRUE; + break; + case B3SOIFD_MOD_WA1: + mod->B3SOIFDwa1 = value->rValue; + mod->B3SOIFDwa1Given = TRUE; + break; + case B3SOIFD_MOD_WA2: + mod->B3SOIFDwa2 = value->rValue; + mod->B3SOIFDwa2Given = TRUE; + break; + case B3SOIFD_MOD_WRDSW: + mod->B3SOIFDwrdsw = value->rValue; + mod->B3SOIFDwrdswGiven = TRUE; + break; + case B3SOIFD_MOD_WPRWB: + mod->B3SOIFDwprwb = value->rValue; + mod->B3SOIFDwprwbGiven = TRUE; + break; + case B3SOIFD_MOD_WPRWG: + mod->B3SOIFDwprwg = value->rValue; + mod->B3SOIFDwprwgGiven = TRUE; + break; + case B3SOIFD_MOD_WWR : + mod->B3SOIFDwwr = value->rValue; + mod->B3SOIFDwwrGiven = TRUE; + break; + case B3SOIFD_MOD_WNFACTOR : + mod->B3SOIFDwnfactor = value->rValue; + mod->B3SOIFDwnfactorGiven = TRUE; + break; + case B3SOIFD_MOD_WDWG : + mod->B3SOIFDwdwg = value->rValue; + mod->B3SOIFDwdwgGiven = TRUE; + break; + case B3SOIFD_MOD_WDWB : + mod->B3SOIFDwdwb = value->rValue; + mod->B3SOIFDwdwbGiven = TRUE; + break; + case B3SOIFD_MOD_WVOFF: + mod->B3SOIFDwvoff = value->rValue; + mod->B3SOIFDwvoffGiven = TRUE; + break; + case B3SOIFD_MOD_WETA0: + mod->B3SOIFDweta0 = value->rValue; + mod->B3SOIFDweta0Given = TRUE; + break; + case B3SOIFD_MOD_WETAB: + mod->B3SOIFDwetab = value->rValue; + mod->B3SOIFDwetabGiven = TRUE; + break; + case B3SOIFD_MOD_WDSUB: + mod->B3SOIFDwdsub = value->rValue; + mod->B3SOIFDwdsubGiven = TRUE; + break; + case B3SOIFD_MOD_WCIT : + mod->B3SOIFDwcit = value->rValue; + mod->B3SOIFDwcitGiven = TRUE; + break; + case B3SOIFD_MOD_WCDSC : + mod->B3SOIFDwcdsc = value->rValue; + mod->B3SOIFDwcdscGiven = TRUE; + break; + case B3SOIFD_MOD_WCDSCB : + mod->B3SOIFDwcdscb = value->rValue; + mod->B3SOIFDwcdscbGiven = TRUE; + break; + case B3SOIFD_MOD_WCDSCD : + mod->B3SOIFDwcdscd = value->rValue; + mod->B3SOIFDwcdscdGiven = TRUE; + break; + case B3SOIFD_MOD_WPCLM: + mod->B3SOIFDwpclm = value->rValue; + mod->B3SOIFDwpclmGiven = TRUE; + break; + case B3SOIFD_MOD_WPDIBL1: + mod->B3SOIFDwpdibl1 = value->rValue; + mod->B3SOIFDwpdibl1Given = TRUE; + break; + case B3SOIFD_MOD_WPDIBL2: + mod->B3SOIFDwpdibl2 = value->rValue; + mod->B3SOIFDwpdibl2Given = TRUE; + break; + case B3SOIFD_MOD_WPDIBLB: + mod->B3SOIFDwpdiblb = value->rValue; + mod->B3SOIFDwpdiblbGiven = TRUE; + break; + case B3SOIFD_MOD_WDROUT: + mod->B3SOIFDwdrout = value->rValue; + mod->B3SOIFDwdroutGiven = TRUE; + break; + case B3SOIFD_MOD_WPVAG: + mod->B3SOIFDwpvag = value->rValue; + mod->B3SOIFDwpvagGiven = TRUE; + break; + case B3SOIFD_MOD_WDELTA : + mod->B3SOIFDwdelta = value->rValue; + mod->B3SOIFDwdeltaGiven = TRUE; + break; + case B3SOIFD_MOD_WAII : + mod->B3SOIFDwaii = value->rValue; + mod->B3SOIFDwaiiGiven = TRUE; + break; + case B3SOIFD_MOD_WBII : + mod->B3SOIFDwbii = value->rValue; + mod->B3SOIFDwbiiGiven = TRUE; + break; + case B3SOIFD_MOD_WCII : + mod->B3SOIFDwcii = value->rValue; + mod->B3SOIFDwciiGiven = TRUE; + break; + case B3SOIFD_MOD_WDII : + mod->B3SOIFDwdii = value->rValue; + mod->B3SOIFDwdiiGiven = TRUE; + break; + case B3SOIFD_MOD_WALPHA0 : + mod->B3SOIFDwalpha0 = value->rValue; + mod->B3SOIFDwalpha0Given = TRUE; + break; + case B3SOIFD_MOD_WALPHA1 : + mod->B3SOIFDwalpha1 = value->rValue; + mod->B3SOIFDwalpha1Given = TRUE; + break; + case B3SOIFD_MOD_WBETA0 : + mod->B3SOIFDwbeta0 = value->rValue; + mod->B3SOIFDwbeta0Given = TRUE; + break; + case B3SOIFD_MOD_WAGIDL : + mod->B3SOIFDwagidl = value->rValue; + mod->B3SOIFDwagidlGiven = TRUE; + break; + case B3SOIFD_MOD_WBGIDL : + mod->B3SOIFDwbgidl = value->rValue; + mod->B3SOIFDwbgidlGiven = TRUE; + break; + case B3SOIFD_MOD_WNGIDL : + mod->B3SOIFDwngidl = value->rValue; + mod->B3SOIFDwngidlGiven = TRUE; + break; + case B3SOIFD_MOD_WNTUN : + mod->B3SOIFDwntun = value->rValue; + mod->B3SOIFDwntunGiven = TRUE; + break; + case B3SOIFD_MOD_WNDIODE : + mod->B3SOIFDwndiode = value->rValue; + mod->B3SOIFDwndiodeGiven = TRUE; + break; + case B3SOIFD_MOD_WISBJT : + mod->B3SOIFDwisbjt = value->rValue; + mod->B3SOIFDwisbjtGiven = TRUE; + break; + case B3SOIFD_MOD_WISDIF : + mod->B3SOIFDwisdif = value->rValue; + mod->B3SOIFDwisdifGiven = TRUE; + break; + case B3SOIFD_MOD_WISREC : + mod->B3SOIFDwisrec = value->rValue; + mod->B3SOIFDwisrecGiven = TRUE; + break; + case B3SOIFD_MOD_WISTUN : + mod->B3SOIFDwistun = value->rValue; + mod->B3SOIFDwistunGiven = TRUE; + break; + case B3SOIFD_MOD_WEDL : + mod->B3SOIFDwedl = value->rValue; + mod->B3SOIFDwedlGiven = TRUE; + break; + case B3SOIFD_MOD_WKBJT1 : + mod->B3SOIFDwkbjt1 = value->rValue; + mod->B3SOIFDwkbjt1Given = TRUE; + break; + /* CV Model */ + case B3SOIFD_MOD_WVSDFB : + mod->B3SOIFDwvsdfb = value->rValue; + mod->B3SOIFDwvsdfbGiven = TRUE; + break; + case B3SOIFD_MOD_WVSDTH : + mod->B3SOIFDwvsdth = value->rValue; + mod->B3SOIFDwvsdthGiven = TRUE; + break; + /* Cross-term Dependence */ + case B3SOIFD_MOD_PNPEAK: + mod->B3SOIFDpnpeak = value->rValue; + mod->B3SOIFDpnpeakGiven = TRUE; + break; + case B3SOIFD_MOD_PNSUB: + mod->B3SOIFDpnsub = value->rValue; + mod->B3SOIFDpnsubGiven = TRUE; + break; + case B3SOIFD_MOD_PNGATE: + mod->B3SOIFDpngate = value->rValue; + mod->B3SOIFDpngateGiven = TRUE; + break; + case B3SOIFD_MOD_PVTH0: + mod->B3SOIFDpvth0 = value->rValue; + mod->B3SOIFDpvth0Given = TRUE; + break; + case B3SOIFD_MOD_PK1: + mod->B3SOIFDpk1 = value->rValue; + mod->B3SOIFDpk1Given = TRUE; + break; + case B3SOIFD_MOD_PK2: + mod->B3SOIFDpk2 = value->rValue; + mod->B3SOIFDpk2Given = TRUE; + break; + case B3SOIFD_MOD_PK3: + mod->B3SOIFDpk3 = value->rValue; + mod->B3SOIFDpk3Given = TRUE; + break; + case B3SOIFD_MOD_PK3B: + mod->B3SOIFDpk3b = value->rValue; + mod->B3SOIFDpk3bGiven = TRUE; + break; + case B3SOIFD_MOD_PVBSA: + mod->B3SOIFDpvbsa = value->rValue; + mod->B3SOIFDpvbsaGiven = TRUE; + break; + case B3SOIFD_MOD_PDELP: + mod->B3SOIFDpdelp = value->rValue; + mod->B3SOIFDpdelpGiven = TRUE; + break; + case B3SOIFD_MOD_PKB1 : + mod->B3SOIFDpkb1 = value->rValue; + mod->B3SOIFDpkb1Given = TRUE; + break; + case B3SOIFD_MOD_PKB3 : + mod->B3SOIFDpkb3 = value->rValue; + mod->B3SOIFDpkb3Given = TRUE; + break; + case B3SOIFD_MOD_PDVBD0 : + mod->B3SOIFDpdvbd0 = value->rValue; + mod->B3SOIFDpdvbd0Given = TRUE; + break; + case B3SOIFD_MOD_PDVBD1 : + mod->B3SOIFDpdvbd1 = value->rValue; + mod->B3SOIFDpdvbd1Given = TRUE; + break; + case B3SOIFD_MOD_PW0: + mod->B3SOIFDpw0 = value->rValue; + mod->B3SOIFDpw0Given = TRUE; + break; + case B3SOIFD_MOD_PNLX: + mod->B3SOIFDpnlx = value->rValue; + mod->B3SOIFDpnlxGiven = TRUE; + break; + case B3SOIFD_MOD_PDVT0: + mod->B3SOIFDpdvt0 = value->rValue; + mod->B3SOIFDpdvt0Given = TRUE; + break; + case B3SOIFD_MOD_PDVT1: + mod->B3SOIFDpdvt1 = value->rValue; + mod->B3SOIFDpdvt1Given = TRUE; + break; + case B3SOIFD_MOD_PDVT2: + mod->B3SOIFDpdvt2 = value->rValue; + mod->B3SOIFDpdvt2Given = TRUE; + break; + case B3SOIFD_MOD_PDVT0W: + mod->B3SOIFDpdvt0w = value->rValue; + mod->B3SOIFDpdvt0wGiven = TRUE; + break; + case B3SOIFD_MOD_PDVT1W: + mod->B3SOIFDpdvt1w = value->rValue; + mod->B3SOIFDpdvt1wGiven = TRUE; + break; + case B3SOIFD_MOD_PDVT2W: + mod->B3SOIFDpdvt2w = value->rValue; + mod->B3SOIFDpdvt2wGiven = TRUE; + break; + case B3SOIFD_MOD_PU0 : + mod->B3SOIFDpu0 = value->rValue; + mod->B3SOIFDpu0Given = TRUE; + break; + case B3SOIFD_MOD_PUA: + mod->B3SOIFDpua = value->rValue; + mod->B3SOIFDpuaGiven = TRUE; + break; + case B3SOIFD_MOD_PUB: + mod->B3SOIFDpub = value->rValue; + mod->B3SOIFDpubGiven = TRUE; + break; + case B3SOIFD_MOD_PUC: + mod->B3SOIFDpuc = value->rValue; + mod->B3SOIFDpucGiven = TRUE; + break; + case B3SOIFD_MOD_PVSAT: + mod->B3SOIFDpvsat = value->rValue; + mod->B3SOIFDpvsatGiven = TRUE; + break; + case B3SOIFD_MOD_PA0: + mod->B3SOIFDpa0 = value->rValue; + mod->B3SOIFDpa0Given = TRUE; + break; + case B3SOIFD_MOD_PAGS: + mod->B3SOIFDpags= value->rValue; + mod->B3SOIFDpagsGiven = TRUE; + break; + case B3SOIFD_MOD_PB0 : + mod->B3SOIFDpb0 = value->rValue; + mod->B3SOIFDpb0Given = TRUE; + break; + case B3SOIFD_MOD_PB1 : + mod->B3SOIFDpb1 = value->rValue; + mod->B3SOIFDpb1Given = TRUE; + break; + case B3SOIFD_MOD_PKETA: + mod->B3SOIFDpketa = value->rValue; + mod->B3SOIFDpketaGiven = TRUE; + break; + case B3SOIFD_MOD_PABP: + mod->B3SOIFDpabp = value->rValue; + mod->B3SOIFDpabpGiven = TRUE; + break; + case B3SOIFD_MOD_PMXC: + mod->B3SOIFDpmxc = value->rValue; + mod->B3SOIFDpmxcGiven = TRUE; + break; + case B3SOIFD_MOD_PADICE0: + mod->B3SOIFDpadice0 = value->rValue; + mod->B3SOIFDpadice0Given = TRUE; + break; + case B3SOIFD_MOD_PA1: + mod->B3SOIFDpa1 = value->rValue; + mod->B3SOIFDpa1Given = TRUE; + break; + case B3SOIFD_MOD_PA2: + mod->B3SOIFDpa2 = value->rValue; + mod->B3SOIFDpa2Given = TRUE; + break; + case B3SOIFD_MOD_PRDSW: + mod->B3SOIFDprdsw = value->rValue; + mod->B3SOIFDprdswGiven = TRUE; + break; + case B3SOIFD_MOD_PPRWB: + mod->B3SOIFDpprwb = value->rValue; + mod->B3SOIFDpprwbGiven = TRUE; + break; + case B3SOIFD_MOD_PPRWG: + mod->B3SOIFDpprwg = value->rValue; + mod->B3SOIFDpprwgGiven = TRUE; + break; + case B3SOIFD_MOD_PWR : + mod->B3SOIFDpwr = value->rValue; + mod->B3SOIFDpwrGiven = TRUE; + break; + case B3SOIFD_MOD_PNFACTOR : + mod->B3SOIFDpnfactor = value->rValue; + mod->B3SOIFDpnfactorGiven = TRUE; + break; + case B3SOIFD_MOD_PDWG : + mod->B3SOIFDpdwg = value->rValue; + mod->B3SOIFDpdwgGiven = TRUE; + break; + case B3SOIFD_MOD_PDWB : + mod->B3SOIFDpdwb = value->rValue; + mod->B3SOIFDpdwbGiven = TRUE; + break; + case B3SOIFD_MOD_PVOFF: + mod->B3SOIFDpvoff = value->rValue; + mod->B3SOIFDpvoffGiven = TRUE; + break; + case B3SOIFD_MOD_PETA0: + mod->B3SOIFDpeta0 = value->rValue; + mod->B3SOIFDpeta0Given = TRUE; + break; + case B3SOIFD_MOD_PETAB: + mod->B3SOIFDpetab = value->rValue; + mod->B3SOIFDpetabGiven = TRUE; + break; + case B3SOIFD_MOD_PDSUB: + mod->B3SOIFDpdsub = value->rValue; + mod->B3SOIFDpdsubGiven = TRUE; + break; + case B3SOIFD_MOD_PCIT : + mod->B3SOIFDpcit = value->rValue; + mod->B3SOIFDpcitGiven = TRUE; + break; + case B3SOIFD_MOD_PCDSC : + mod->B3SOIFDpcdsc = value->rValue; + mod->B3SOIFDpcdscGiven = TRUE; + break; + case B3SOIFD_MOD_PCDSCB : + mod->B3SOIFDpcdscb = value->rValue; + mod->B3SOIFDpcdscbGiven = TRUE; + break; + case B3SOIFD_MOD_PCDSCD : + mod->B3SOIFDpcdscd = value->rValue; + mod->B3SOIFDpcdscdGiven = TRUE; + break; + case B3SOIFD_MOD_PPCLM: + mod->B3SOIFDppclm = value->rValue; + mod->B3SOIFDppclmGiven = TRUE; + break; + case B3SOIFD_MOD_PPDIBL1: + mod->B3SOIFDppdibl1 = value->rValue; + mod->B3SOIFDppdibl1Given = TRUE; + break; + case B3SOIFD_MOD_PPDIBL2: + mod->B3SOIFDppdibl2 = value->rValue; + mod->B3SOIFDppdibl2Given = TRUE; + break; + case B3SOIFD_MOD_PPDIBLB: + mod->B3SOIFDppdiblb = value->rValue; + mod->B3SOIFDppdiblbGiven = TRUE; + break; + case B3SOIFD_MOD_PDROUT: + mod->B3SOIFDpdrout = value->rValue; + mod->B3SOIFDpdroutGiven = TRUE; + break; + case B3SOIFD_MOD_PPVAG: + mod->B3SOIFDppvag = value->rValue; + mod->B3SOIFDppvagGiven = TRUE; + break; + case B3SOIFD_MOD_PDELTA : + mod->B3SOIFDpdelta = value->rValue; + mod->B3SOIFDpdeltaGiven = TRUE; + break; + case B3SOIFD_MOD_PAII : + mod->B3SOIFDpaii = value->rValue; + mod->B3SOIFDpaiiGiven = TRUE; + break; + case B3SOIFD_MOD_PBII : + mod->B3SOIFDpbii = value->rValue; + mod->B3SOIFDpbiiGiven = TRUE; + break; + case B3SOIFD_MOD_PCII : + mod->B3SOIFDpcii = value->rValue; + mod->B3SOIFDpciiGiven = TRUE; + break; + case B3SOIFD_MOD_PDII : + mod->B3SOIFDpdii = value->rValue; + mod->B3SOIFDpdiiGiven = TRUE; + break; + case B3SOIFD_MOD_PALPHA0 : + mod->B3SOIFDpalpha0 = value->rValue; + mod->B3SOIFDpalpha0Given = TRUE; + break; + case B3SOIFD_MOD_PALPHA1 : + mod->B3SOIFDpalpha1 = value->rValue; + mod->B3SOIFDpalpha1Given = TRUE; + break; + case B3SOIFD_MOD_PBETA0 : + mod->B3SOIFDpbeta0 = value->rValue; + mod->B3SOIFDpbeta0Given = TRUE; + break; + case B3SOIFD_MOD_PAGIDL : + mod->B3SOIFDpagidl = value->rValue; + mod->B3SOIFDpagidlGiven = TRUE; + break; + case B3SOIFD_MOD_PBGIDL : + mod->B3SOIFDpbgidl = value->rValue; + mod->B3SOIFDpbgidlGiven = TRUE; + break; + case B3SOIFD_MOD_PNGIDL : + mod->B3SOIFDpngidl = value->rValue; + mod->B3SOIFDpngidlGiven = TRUE; + break; + case B3SOIFD_MOD_PNTUN : + mod->B3SOIFDpntun = value->rValue; + mod->B3SOIFDpntunGiven = TRUE; + break; + case B3SOIFD_MOD_PNDIODE : + mod->B3SOIFDpndiode = value->rValue; + mod->B3SOIFDpndiodeGiven = TRUE; + break; + case B3SOIFD_MOD_PISBJT : + mod->B3SOIFDpisbjt = value->rValue; + mod->B3SOIFDpisbjtGiven = TRUE; + break; + case B3SOIFD_MOD_PISDIF : + mod->B3SOIFDpisdif = value->rValue; + mod->B3SOIFDpisdifGiven = TRUE; + break; + case B3SOIFD_MOD_PISREC : + mod->B3SOIFDpisrec = value->rValue; + mod->B3SOIFDpisrecGiven = TRUE; + break; + case B3SOIFD_MOD_PISTUN : + mod->B3SOIFDpistun = value->rValue; + mod->B3SOIFDpistunGiven = TRUE; + break; + case B3SOIFD_MOD_PEDL : + mod->B3SOIFDpedl = value->rValue; + mod->B3SOIFDpedlGiven = TRUE; + break; + case B3SOIFD_MOD_PKBJT1 : + mod->B3SOIFDpkbjt1 = value->rValue; + mod->B3SOIFDpkbjt1Given = TRUE; + break; + /* CV Model */ + case B3SOIFD_MOD_PVSDFB : + mod->B3SOIFDpvsdfb = value->rValue; + mod->B3SOIFDpvsdfbGiven = TRUE; + break; + case B3SOIFD_MOD_PVSDTH : + mod->B3SOIFDpvsdth = value->rValue; + mod->B3SOIFDpvsdthGiven = TRUE; + break; +/* Added for binning - END */ + + case B3SOIFD_MOD_NMOS : + if(value->iValue) { + mod->B3SOIFDtype = 1; + mod->B3SOIFDtypeGiven = TRUE; + } + break; + case B3SOIFD_MOD_PMOS : + if(value->iValue) { + mod->B3SOIFDtype = - 1; + mod->B3SOIFDtypeGiven = TRUE; + } + break; + default: + return(E_BADPARM); + } + return(OK); +} + + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdnoi.c b/src/spicelib/devices/bsim3soi_fd/b3soifdnoi.c new file mode 100644 index 000000000..a9ab768fa --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdnoi.c @@ -0,0 +1,392 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soifdnoi.c 98/5/01 +**********/ + +#include "ngspice.h" +#include +#include +#include "b3soifddef.h" +#include "cktdefs.h" +#include "iferrmsg.h" +#include "noisedef.h" +#include "suffix.h" +#include "const.h" /* jwan */ + +/* + * B3SOIFDnoise (mode, operation, firstModel, ckt, data, OnDens) + * This routine names and evaluates all of the noise sources + * associated with MOSFET's. It starts with the model *firstModel and + * traverses all of its insts. It then proceeds to any other models + * on the linked list. The total output noise density generated by + * all of the MOSFET's is summed with the variable "OnDens". + */ + +/* + Channel thermal and flicker noises are calculated based on the value + of model->B3SOIFDnoiMod. + If model->B3SOIFDnoiMod = 1, + Channel thermal noise = SPICE2 model + Flicker noise = SPICE2 model + If model->B3SOIFDnoiMod = 2, + Channel thermal noise = B3SOIFD model + Flicker noise = B3SOIFD model + If model->B3SOIFDnoiMod = 3, + Channel thermal noise = SPICE2 model + Flicker noise = B3SOIFD model + If model->B3SOIFDnoiMod = 4, + Channel thermal noise = B3SOIFD model + Flicker noise = SPICE2 model + */ + +extern void NevalSrc(); +extern double Nintegrate(); + +double +B3SOIFDStrongInversionNoiseEval(vgs, vds, model, here, freq, temp) +double vgs, vds, freq, temp; +B3SOIFDmodel *model; +B3SOIFDinstance *here; +{ +struct b3soifdSizeDependParam *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 req, ceq; + + pParam = here->pParam; + cd = fabs(here->B3SOIFDcd); + if (vds > here->B3SOIFDvdsat) + { esat = 2.0 * pParam->B3SOIFDvsattemp / here->B3SOIFDueff; + T0 = ((((vds - here->B3SOIFDvdsat) / pParam->B3SOIFDlitl) + model->B3SOIFDem) + / esat); + DelClm = pParam->B3SOIFDlitl * log (MAX(T0, N_MINLOG)); + } + else + DelClm = 0.0; + EffFreq = pow(freq, model->B3SOIFDef); + T1 = CHARGE * CHARGE * 8.62e-5 * cd * temp * here->B3SOIFDueff; + T2 = 1.0e8 * EffFreq * model->B3SOIFDcox + * pParam->B3SOIFDleff * pParam->B3SOIFDleff; + Vgst = vgs - here->B3SOIFDvon; + N0 = model->B3SOIFDcox * Vgst / CHARGE; + if (N0 < 0.0) + N0 = 0.0; + Nl = model->B3SOIFDcox * (Vgst - MIN(vds, here->B3SOIFDvdsat)) / CHARGE; + if (Nl < 0.0) + Nl = 0.0; + + T3 = model->B3SOIFDoxideTrapDensityA + * log(MAX(((N0 + 2.0e14) / (Nl + 2.0e14)), N_MINLOG)); + T4 = model->B3SOIFDoxideTrapDensityB * (N0 - Nl); + T5 = model->B3SOIFDoxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl); + + T6 = 8.62e-5 * temp * cd * cd; + T7 = 1.0e8 * EffFreq * pParam->B3SOIFDleff + * pParam->B3SOIFDleff * pParam->B3SOIFDweff; + T8 = model->B3SOIFDoxideTrapDensityA + model->B3SOIFDoxideTrapDensityB * Nl + + model->B3SOIFDoxideTrapDensityC * Nl * Nl; + T9 = (Nl + 2.0e14) * (Nl + 2.0e14); + + Ssi = T1 / T2 * (T3 + T4 + T5) + T6 / T7 * DelClm * T8 / T9; + + return Ssi; +} + +int +B3SOIFDnoise (mode, operation, inModel, ckt, data, OnDens) +int mode, operation; +GENmodel *inModel; +CKTcircuit *ckt; + Ndata *data; +double *OnDens; +{ + B3SOIFDmodel *model = (B3SOIFDmodel *)inModel; + B3SOIFDinstance *here; +struct b3soifdSizeDependParam *pParam; +char name[N_MXVLNTH]; +double tempOnoise; +double tempInoise; +double noizDens[B3SOIFDNSRCS]; +double lnNdens[B3SOIFDNSRCS]; + +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; + +int error, i; + + /* define the names of the noise sources */ + static char *B3SOIFDnNames[B3SOIFDNSRCS] = + { /* Note that we have to keep the order */ + ".rd", /* noise due to rd */ + /* consistent with the index definitions */ + ".rs", /* noise due to rs */ + /* in B3SOIFDdefs.h */ + ".id", /* noise due to id */ + ".1overf", /* flicker (1/f) noise */ + ".fb", /* noise due to floating body */ + "" /* total transistor noise */ + }; + + for (; model != NULL; model = model->B3SOIFDnextModel) + { for (here = model->B3SOIFDinstances; here != NULL; + here = here->B3SOIFDnextInstance) + { pParam = here->pParam; + switch (operation) + { case N_OPEN: + /* see if we have to to produce a summary report */ + /* if so, name all the noise generators */ + + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) + { switch (mode) + { case N_DENS: + for (i = 0; i < B3SOIFDNSRCS; i++) + { (void) sprintf(name, "onoise.%s%s", + here->B3SOIFDname, + B3SOIFDnNames[i]); + data->namelist = (IFuid *) trealloc( + (char *) data->namelist, + (data->numPlots + 1) + * sizeof(IFuid)); + if (!data->namelist) + return(E_NOMEM); + (*(SPfrontEnd->IFnewUid)) (ckt, + &(data->namelist[data->numPlots++]), + (IFuid) NULL, name, UID_OTHER, + (void **) NULL); + /* we've added one more plot */ + } + break; + case INT_NOIZ: + for (i = 0; i < B3SOIFDNSRCS; i++) + { (void) sprintf(name, "onoise_total.%s%s", + here->B3SOIFDname, + B3SOIFDnNames[i]); + data->namelist = (IFuid *) trealloc( + (char *) data->namelist, + (data->numPlots + 1) + * sizeof(IFuid)); + if (!data->namelist) + return(E_NOMEM); + (*(SPfrontEnd->IFnewUid)) (ckt, + &(data->namelist[data->numPlots++]), + (IFuid) NULL, name, UID_OTHER, + (void **) NULL); + /* we've added one more plot */ + + (void) sprintf(name, "inoise_total.%s%s", + here->B3SOIFDname, + B3SOIFDnNames[i]); + data->namelist = (IFuid *) trealloc( + (char *) data->namelist, + (data->numPlots + 1) + * sizeof(IFuid)); + if (!data->namelist) + return(E_NOMEM); + (*(SPfrontEnd->IFnewUid)) (ckt, + &(data->namelist[data->numPlots++]), + (IFuid) NULL, name, UID_OTHER, + (void **)NULL); + /* we've added one more plot */ + } + break; + } + } + break; + case N_CALC: + switch (mode) + { case N_DENS: + NevalSrc(&noizDens[B3SOIFDRDNOIZ], + &lnNdens[B3SOIFDRDNOIZ], ckt, THERMNOISE, + here->B3SOIFDdNodePrime, here->B3SOIFDdNode, + here->B3SOIFDdrainConductance); + + NevalSrc(&noizDens[B3SOIFDRSNOIZ], + &lnNdens[B3SOIFDRSNOIZ], ckt, THERMNOISE, + here->B3SOIFDsNodePrime, here->B3SOIFDsNode, + here->B3SOIFDsourceConductance); + + switch( model->B3SOIFDnoiMod ) + { case 1: + case 3: + NevalSrc(&noizDens[B3SOIFDIDNOIZ], + &lnNdens[B3SOIFDIDNOIZ], ckt, + THERMNOISE, here->B3SOIFDdNodePrime, + here->B3SOIFDsNodePrime, + (2.0 / 3.0 * fabs(here->B3SOIFDgm + + here->B3SOIFDgds + + here->B3SOIFDgmbs))); + break; + case 2: + case 4: + NevalSrc(&noizDens[B3SOIFDIDNOIZ], + &lnNdens[B3SOIFDIDNOIZ], ckt, + THERMNOISE, here->B3SOIFDdNodePrime, + here->B3SOIFDsNodePrime, + (here->B3SOIFDueff + * fabs(here->B3SOIFDqinv + / (pParam->B3SOIFDleff + * pParam->B3SOIFDleff)))); + break; + } + NevalSrc(&noizDens[B3SOIFDFLNOIZ], (double*) NULL, + ckt, N_GAIN, here->B3SOIFDdNodePrime, + here->B3SOIFDsNodePrime, (double) 0.0); + + switch( model->B3SOIFDnoiMod ) + { case 1: + case 4: + noizDens[B3SOIFDFLNOIZ] *= model->B3SOIFDkf + * exp(model->B3SOIFDaf + * log(MAX(fabs(here->B3SOIFDcd), + N_MINLOG))) + / (pow(data->freq, model->B3SOIFDef) + * pParam->B3SOIFDleff + * pParam->B3SOIFDleff + * model->B3SOIFDcox); + break; + case 2: + case 3: + vgs = *(ckt->CKTstates[0] + here->B3SOIFDvgs); + vds = *(ckt->CKTstates[0] + here->B3SOIFDvds); + if (vds < 0.0) + { vds = -vds; + vgs = vgs + vds; + } + if (vgs >= here->B3SOIFDvon + 0.1) + { Ssi = B3SOIFDStrongInversionNoiseEval(vgs, + vds, model, here, data->freq, + ckt->CKTtemp); + noizDens[B3SOIFDFLNOIZ] *= Ssi; + } + else + { pParam = here->pParam; + T10 = model->B3SOIFDoxideTrapDensityA + * 8.62e-5 * ckt->CKTtemp; + T11 = pParam->B3SOIFDweff + * pParam->B3SOIFDleff + * pow(data->freq, model->B3SOIFDef) + * 4.0e36; + Swi = T10 / T11 * here->B3SOIFDcd + * here->B3SOIFDcd; + Slimit = B3SOIFDStrongInversionNoiseEval( + here->B3SOIFDvon + 0.1, vds, model, + here, data->freq, ckt->CKTtemp); + T1 = Swi + Slimit; + if (T1 > 0.0) + noizDens[B3SOIFDFLNOIZ] *= (Slimit + * Swi) / T1; + else + noizDens[B3SOIFDFLNOIZ] *= 0.0; + } + break; + } + + lnNdens[B3SOIFDFLNOIZ] = + log(MAX(noizDens[B3SOIFDFLNOIZ], N_MINLOG)); + + /* Low frequency excess noise due to FBE */ + noizDens[B3SOIFDFBNOIZ] = 0.0; + + noizDens[B3SOIFDTOTNOIZ] = noizDens[B3SOIFDRDNOIZ] + + noizDens[B3SOIFDRSNOIZ] + + noizDens[B3SOIFDIDNOIZ] + + noizDens[B3SOIFDFLNOIZ] + + noizDens[B3SOIFDFBNOIZ]; + lnNdens[B3SOIFDTOTNOIZ] = + log(MAX(noizDens[B3SOIFDTOTNOIZ], N_MINLOG)); + + *OnDens += noizDens[B3SOIFDTOTNOIZ]; + + if (data->delFreq == 0.0) + { /* if we haven't done any previous + integration, we need to initialize our + "history" variables. + */ + + for (i = 0; i < B3SOIFDNSRCS; i++) + { here->B3SOIFDnVar[LNLSTDENS][i] = + lnNdens[i]; + } + + /* clear out our integration variables + if it's the first pass + */ + if (data->freq == + ((NOISEAN*) ckt->CKTcurJob)->NstartFreq) + { for (i = 0; i < B3SOIFDNSRCS; i++) + { here->B3SOIFDnVar[OUTNOIZ][i] = 0.0; + here->B3SOIFDnVar[INNOIZ][i] = 0.0; + } + } + } + else + { /* data->delFreq != 0.0, + we have to integrate. + */ + for (i = 0; i < B3SOIFDNSRCS; i++) + { if (i != B3SOIFDTOTNOIZ) + { tempOnoise = Nintegrate(noizDens[i], + lnNdens[i], + here->B3SOIFDnVar[LNLSTDENS][i], + data); + tempInoise = Nintegrate(noizDens[i] + * data->GainSqInv, lnNdens[i] + + data->lnGainInv, + here->B3SOIFDnVar[LNLSTDENS][i] + + data->lnGainInv, data); + here->B3SOIFDnVar[LNLSTDENS][i] = + lnNdens[i]; + data->outNoiz += tempOnoise; + data->inNoise += tempInoise; + if (((NOISEAN*) + ckt->CKTcurJob)->NStpsSm != 0) + { here->B3SOIFDnVar[OUTNOIZ][i] + += tempOnoise; + here->B3SOIFDnVar[OUTNOIZ][B3SOIFDTOTNOIZ] + += tempOnoise; + here->B3SOIFDnVar[INNOIZ][i] + += tempInoise; + here->B3SOIFDnVar[INNOIZ][B3SOIFDTOTNOIZ] + += tempInoise; + } + } + } + } + if (data->prtSummary) + { for (i = 0; i < B3SOIFDNSRCS; i++) + { /* print a summary report */ + data->outpVector[data->outNumber++] + = noizDens[i]; + } + } + break; + case INT_NOIZ: + /* already calculated, just output */ + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) + { for (i = 0; i < B3SOIFDNSRCS; i++) + { data->outpVector[data->outNumber++] + = here->B3SOIFDnVar[OUTNOIZ][i]; + data->outpVector[data->outNumber++] + = here->B3SOIFDnVar[INNOIZ][i]; + } + } + break; + } + break; + case N_CLOSE: + /* do nothing, the main calling routine will close */ + return (OK); + break; /* the plots */ + } /* switch (operation) */ + } /* for here */ + } /* for model */ + + return(OK); +} + + + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdpar.c b/src/spicelib/devices/bsim3soi_fd/b3soifdpar.c new file mode 100644 index 000000000..e6e7fd743 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdpar.c @@ -0,0 +1,128 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soifdpar.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "b3soifddef.h" +#include "sperror.h" +#include "suffix.h" + +int +B3SOIFDparam(param,value,inst,select) +int param; +IFvalue *value; +GENinstance *inst; +IFvalue *select; +{ + B3SOIFDinstance *here = (B3SOIFDinstance*)inst; + switch(param) + { case B3SOIFD_W: + here->B3SOIFDw = value->rValue; + here->B3SOIFDwGiven = TRUE; + break; + case B3SOIFD_L: + here->B3SOIFDl = value->rValue; + here->B3SOIFDlGiven = TRUE; + break; + case B3SOIFD_AS: + here->B3SOIFDsourceArea = value->rValue; + here->B3SOIFDsourceAreaGiven = TRUE; + break; + case B3SOIFD_AD: + here->B3SOIFDdrainArea = value->rValue; + here->B3SOIFDdrainAreaGiven = TRUE; + break; + case B3SOIFD_PS: + here->B3SOIFDsourcePerimeter = value->rValue; + here->B3SOIFDsourcePerimeterGiven = TRUE; + break; + case B3SOIFD_PD: + here->B3SOIFDdrainPerimeter = value->rValue; + here->B3SOIFDdrainPerimeterGiven = TRUE; + break; + case B3SOIFD_NRS: + here->B3SOIFDsourceSquares = value->rValue; + here->B3SOIFDsourceSquaresGiven = TRUE; + break; + case B3SOIFD_NRD: + here->B3SOIFDdrainSquares = value->rValue; + here->B3SOIFDdrainSquaresGiven = TRUE; + break; + case B3SOIFD_OFF: + here->B3SOIFDoff = value->iValue; + break; + case B3SOIFD_IC_VBS: + here->B3SOIFDicVBS = value->rValue; + here->B3SOIFDicVBSGiven = TRUE; + break; + case B3SOIFD_IC_VDS: + here->B3SOIFDicVDS = value->rValue; + here->B3SOIFDicVDSGiven = TRUE; + break; + case B3SOIFD_IC_VGS: + here->B3SOIFDicVGS = value->rValue; + here->B3SOIFDicVGSGiven = TRUE; + break; + case B3SOIFD_IC_VES: + here->B3SOIFDicVES = value->rValue; + here->B3SOIFDicVESGiven = TRUE; + break; + case B3SOIFD_IC_VPS: + here->B3SOIFDicVPS = value->rValue; + here->B3SOIFDicVPSGiven = TRUE; + break; + case B3SOIFD_BJTOFF: + here->B3SOIFDbjtoff = value->iValue; + here->B3SOIFDbjtoffGiven= TRUE; + break; + case B3SOIFD_DEBUG: + here->B3SOIFDdebugMod = value->iValue; + here->B3SOIFDdebugModGiven= TRUE; + break; + case B3SOIFD_RTH0: + here->B3SOIFDrth0= value->rValue; + here->B3SOIFDrth0Given = TRUE; + break; + case B3SOIFD_CTH0: + here->B3SOIFDcth0= value->rValue; + here->B3SOIFDcth0Given = TRUE; + break; + case B3SOIFD_NRB: + here->B3SOIFDbodySquares = value->rValue; + here->B3SOIFDbodySquaresGiven = TRUE; + break; + case B3SOIFD_IC: + switch(value->v.numValue){ + case 5: + here->B3SOIFDicVPS = *(value->v.vec.rVec+4); + here->B3SOIFDicVPSGiven = TRUE; + case 4: + here->B3SOIFDicVES = *(value->v.vec.rVec+3); + here->B3SOIFDicVESGiven = TRUE; + case 3: + here->B3SOIFDicVBS = *(value->v.vec.rVec+2); + here->B3SOIFDicVBSGiven = TRUE; + case 2: + here->B3SOIFDicVGS = *(value->v.vec.rVec+1); + here->B3SOIFDicVGSGiven = TRUE; + case 1: + here->B3SOIFDicVDS = *(value->v.vec.rVec); + here->B3SOIFDicVDSGiven = TRUE; + break; + default: + return(E_BADPARM); + } + break; + default: + return(E_BADPARM); + } + return(OK); +} + + + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdpzld.c b/src/spicelib/devices/bsim3soi_fd/b3soifdpzld.c new file mode 100644 index 000000000..adb51620a --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdpzld.c @@ -0,0 +1,152 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soifdpzld.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "complex.h" +#include "sperror.h" +#include "b3soifddef.h" +#include "suffix.h" + +int +B3SOIFDpzLoad(inModel,ckt,s) +GENmodel *inModel; + CKTcircuit *ckt; + SPcomplex *s; +{ + B3SOIFDmodel *model = (B3SOIFDmodel*)inModel; + B3SOIFDinstance *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; +double GSoverlapCap, GDoverlapCap, GBoverlapCap; +double FwdSum, RevSum, Gm, Gmbs; + + for (; model != NULL; model = model->B3SOIFDnextModel) + { for (here = model->B3SOIFDinstances; here!= NULL; + here = here->B3SOIFDnextInstance) + { + if (here->B3SOIFDmode >= 0) + { Gm = here->B3SOIFDgm; + Gmbs = here->B3SOIFDgmbs; + FwdSum = Gm + Gmbs; + RevSum = 0.0; + cggb = here->B3SOIFDcggb; + cgsb = here->B3SOIFDcgsb; + cgdb = here->B3SOIFDcgdb; + + cbgb = here->B3SOIFDcbgb; + cbsb = here->B3SOIFDcbsb; + cbdb = here->B3SOIFDcbdb; + + cdgb = here->B3SOIFDcdgb; + cdsb = here->B3SOIFDcdsb; + cddb = here->B3SOIFDcddb; + } + else + { Gm = -here->B3SOIFDgm; + Gmbs = -here->B3SOIFDgmbs; + FwdSum = 0.0; + RevSum = -Gm - Gmbs; + cggb = here->B3SOIFDcggb; + cgsb = here->B3SOIFDcgdb; + cgdb = here->B3SOIFDcgsb; + + cbgb = here->B3SOIFDcbgb; + cbsb = here->B3SOIFDcbdb; + cbdb = here->B3SOIFDcbsb; + + cdgb = -(here->B3SOIFDcdgb + cggb + cbgb); + cdsb = -(here->B3SOIFDcddb + cgsb + cbsb); + cddb = -(here->B3SOIFDcdsb + cgdb + cbdb); + } + gdpr=here->B3SOIFDdrainConductance; + gspr=here->B3SOIFDsourceConductance; + gds= here->B3SOIFDgds; + gbd= here->B3SOIFDgjdb; + gbs= here->B3SOIFDgjsb; +#ifdef BULKCODE + capbd= here->B3SOIFDcapbd; + capbs= here->B3SOIFDcapbs; +#endif + GSoverlapCap = here->B3SOIFDcgso; + GDoverlapCap = here->B3SOIFDcgdo; +#ifdef BULKCODE + GBoverlapCap = here->pParam->B3SOIFDcgbo; +#endif + + xcdgb = (cdgb - GDoverlapCap); + xcddb = (cddb + capbd + GDoverlapCap); + xcdsb = cdsb; + xcsgb = -(cggb + cbgb + cdgb + GSoverlapCap); + xcsdb = -(cgdb + cbdb + cddb); + xcssb = (capbs + GSoverlapCap - (cgsb+cbsb+cdsb)); + xcggb = (cggb + GDoverlapCap + GSoverlapCap + GBoverlapCap); + xcgdb = (cgdb - GDoverlapCap); + xcgsb = (cgsb - GSoverlapCap); + xcbgb = (cbgb - GBoverlapCap); + xcbdb = (cbdb - capbd); + xcbsb = (cbsb - capbs); + + + *(here->B3SOIFDGgPtr ) += xcggb * s->real; + *(here->B3SOIFDGgPtr +1) += xcggb * s->imag; + *(here->B3SOIFDBbPtr ) += (-xcbgb-xcbdb-xcbsb) * s->real; + *(here->B3SOIFDBbPtr +1) += (-xcbgb-xcbdb-xcbsb) * s->imag; + *(here->B3SOIFDDPdpPtr ) += xcddb * s->real; + *(here->B3SOIFDDPdpPtr +1) += xcddb * s->imag; + *(here->B3SOIFDSPspPtr ) += xcssb * s->real; + *(here->B3SOIFDSPspPtr +1) += xcssb * s->imag; + *(here->B3SOIFDGbPtr ) += (-xcggb-xcgdb-xcgsb) * s->real; + *(here->B3SOIFDGbPtr +1) += (-xcggb-xcgdb-xcgsb) * s->imag; + *(here->B3SOIFDGdpPtr ) += xcgdb * s->real; + *(here->B3SOIFDGdpPtr +1) += xcgdb * s->imag; + *(here->B3SOIFDGspPtr ) += xcgsb * s->real; + *(here->B3SOIFDGspPtr +1) += xcgsb * s->imag; + *(here->B3SOIFDBgPtr ) += xcbgb * s->real; + *(here->B3SOIFDBgPtr +1) += xcbgb * s->imag; + *(here->B3SOIFDBdpPtr ) += xcbdb * s->real; + *(here->B3SOIFDBdpPtr +1) += xcbdb * s->imag; + *(here->B3SOIFDBspPtr ) += xcbsb * s->real; + *(here->B3SOIFDBspPtr +1) += xcbsb * s->imag; + *(here->B3SOIFDDPgPtr ) += xcdgb * s->real; + *(here->B3SOIFDDPgPtr +1) += xcdgb * s->imag; + *(here->B3SOIFDDPbPtr ) += (-xcdgb-xcddb-xcdsb) * s->real; + *(here->B3SOIFDDPbPtr +1) += (-xcdgb-xcddb-xcdsb) * s->imag; + *(here->B3SOIFDDPspPtr ) += xcdsb * s->real; + *(here->B3SOIFDDPspPtr +1) += xcdsb * s->imag; + *(here->B3SOIFDSPgPtr ) += xcsgb * s->real; + *(here->B3SOIFDSPgPtr +1) += xcsgb * s->imag; + *(here->B3SOIFDSPbPtr ) += (-xcsgb-xcsdb-xcssb) * s->real; + *(here->B3SOIFDSPbPtr +1) += (-xcsgb-xcsdb-xcssb) * s->imag; + *(here->B3SOIFDSPdpPtr ) += xcsdb * s->real; + *(here->B3SOIFDSPdpPtr +1) += xcsdb * s->imag; + *(here->B3SOIFDDdPtr) += gdpr; + *(here->B3SOIFDSsPtr) += gspr; + *(here->B3SOIFDBbPtr) += gbd+gbs; + *(here->B3SOIFDDPdpPtr) += gdpr+gds+gbd+RevSum; + *(here->B3SOIFDSPspPtr) += gspr+gds+gbs+FwdSum; + *(here->B3SOIFDDdpPtr) -= gdpr; + *(here->B3SOIFDSspPtr) -= gspr; + *(here->B3SOIFDBdpPtr) -= gbd; + *(here->B3SOIFDBspPtr) -= gbs; + *(here->B3SOIFDDPdPtr) -= gdpr; + *(here->B3SOIFDDPgPtr) += Gm; + *(here->B3SOIFDDPbPtr) -= gbd - Gmbs; + *(here->B3SOIFDDPspPtr) -= gds + FwdSum; + *(here->B3SOIFDSPgPtr) -= Gm; + *(here->B3SOIFDSPsPtr) -= gspr; + *(here->B3SOIFDSPbPtr) -= gbs + Gmbs; + *(here->B3SOIFDSPdpPtr) -= gds + RevSum; + + } + } + return(OK); +} + + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdset.c b/src/spicelib/devices/bsim3soi_fd/b3soifdset.c new file mode 100644 index 000000000..24343abb5 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdset.c @@ -0,0 +1,1341 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soifdset.c 98/5/01 +Modified by Pin Su, Wei Jin 99/9/27 +**********/ + + +#include "ngspice.h" +#include +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "b3soifddef.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + +#define MAX_EXP 5.834617425e14 +#define MIN_EXP 1.713908431e-15 +#define EXP_THRESHOLD 34.0 +#define SMOOTHFACTOR 0.1 +#define EPSOX 3.453133e-11 +#define EPSSI 1.03594e-10 +#define PI 3.141592654 +#define Charge_q 1.60219e-19 +#define Meter2Micron 1.0e6 + +int +B3SOIFDsetup(matrix,inModel,ckt,states) + SMPmatrix *matrix; + GENmodel *inModel; + CKTcircuit *ckt; +int *states; +{ + B3SOIFDmodel *model = (B3SOIFDmodel*)inModel; + B3SOIFDinstance *here; +int error; +CKTnode *tmp; + +double tmp1, tmp2; +double nfb0, Cboxt; +int itmp1; + + /* loop through all the B3SOIFD device models */ + for( ; model != NULL; model = model->B3SOIFDnextModel ) + { +/* Default value Processing for B3SOIFD MOSFET Models */ + + if (!model->B3SOIFDtypeGiven) + model->B3SOIFDtype = NMOS; + if (!model->B3SOIFDmobModGiven) + model->B3SOIFDmobMod = 1; + if (!model->B3SOIFDbinUnitGiven) + model->B3SOIFDbinUnit = 1; + if (!model->B3SOIFDparamChkGiven) + model->B3SOIFDparamChk = 0; + if (!model->B3SOIFDcapModGiven) + model->B3SOIFDcapMod = 2; + if (!model->B3SOIFDnoiModGiven) + model->B3SOIFDnoiMod = 1; + if (!model->B3SOIFDshModGiven) + model->B3SOIFDshMod = 0; + if (!model->B3SOIFDversionGiven) + model->B3SOIFDversion = 2.0; + if (!model->B3SOIFDtoxGiven) + model->B3SOIFDtox = 100.0e-10; + model->B3SOIFDcox = 3.453133e-11 / model->B3SOIFDtox; + + if (!model->B3SOIFDcdscGiven) + model->B3SOIFDcdsc = 2.4e-4; /* unit Q/V/m^2 */ + if (!model->B3SOIFDcdscbGiven) + model->B3SOIFDcdscb = 0.0; /* unit Q/V/m^2 */ + if (!model->B3SOIFDcdscdGiven) + model->B3SOIFDcdscd = 0.0; /* unit Q/V/m^2 */ + if (!model->B3SOIFDcitGiven) + model->B3SOIFDcit = 0.0; /* unit Q/V/m^2 */ + if (!model->B3SOIFDnfactorGiven) + model->B3SOIFDnfactor = 1; + if (!model->B3SOIFDvsatGiven) + model->B3SOIFDvsat = 8.0e4; /* unit m/s */ + if (!model->B3SOIFDatGiven) + model->B3SOIFDat = 3.3e4; /* unit m/s */ + if (!model->B3SOIFDa0Given) + model->B3SOIFDa0 = 1.0; + if (!model->B3SOIFDagsGiven) + model->B3SOIFDags = 0.0; + if (!model->B3SOIFDa1Given) + model->B3SOIFDa1 = 0.0; + if (!model->B3SOIFDa2Given) + model->B3SOIFDa2 = 1.0; + if (!model->B3SOIFDketaGiven) + model->B3SOIFDketa = -0.6; /* unit / V */ + if (!model->B3SOIFDnsubGiven) + model->B3SOIFDnsub = 6.0e16; /* unit 1/cm3 */ + if (!model->B3SOIFDnpeakGiven) + model->B3SOIFDnpeak = 1.7e17; /* unit 1/cm3 */ + if (!model->B3SOIFDngateGiven) + model->B3SOIFDngate = 0; /* unit 1/cm3 */ + if (!model->B3SOIFDvbmGiven) + model->B3SOIFDvbm = -3.0; + if (!model->B3SOIFDxtGiven) + model->B3SOIFDxt = 1.55e-7; + if (!model->B3SOIFDkt1Given) + model->B3SOIFDkt1 = -0.11; /* unit V */ + if (!model->B3SOIFDkt1lGiven) + model->B3SOIFDkt1l = 0.0; /* unit V*m */ + if (!model->B3SOIFDkt2Given) + model->B3SOIFDkt2 = 0.022; /* No unit */ + if (!model->B3SOIFDk3Given) + model->B3SOIFDk3 = 0.0; + if (!model->B3SOIFDk3bGiven) + model->B3SOIFDk3b = 0.0; + if (!model->B3SOIFDw0Given) + model->B3SOIFDw0 = 2.5e-6; + if (!model->B3SOIFDnlxGiven) + model->B3SOIFDnlx = 1.74e-7; + if (!model->B3SOIFDdvt0Given) + model->B3SOIFDdvt0 = 2.2; + if (!model->B3SOIFDdvt1Given) + model->B3SOIFDdvt1 = 0.53; + if (!model->B3SOIFDdvt2Given) + model->B3SOIFDdvt2 = -0.032; /* unit 1 / V */ + + if (!model->B3SOIFDdvt0wGiven) + model->B3SOIFDdvt0w = 0.0; + if (!model->B3SOIFDdvt1wGiven) + model->B3SOIFDdvt1w = 5.3e6; + if (!model->B3SOIFDdvt2wGiven) + model->B3SOIFDdvt2w = -0.032; + + if (!model->B3SOIFDdroutGiven) + model->B3SOIFDdrout = 0.56; + if (!model->B3SOIFDdsubGiven) + model->B3SOIFDdsub = model->B3SOIFDdrout; + if (!model->B3SOIFDvth0Given) + model->B3SOIFDvth0 = (model->B3SOIFDtype == NMOS) ? 0.7 : -0.7; + if (!model->B3SOIFDuaGiven) + model->B3SOIFDua = 2.25e-9; /* unit m/V */ + if (!model->B3SOIFDua1Given) + model->B3SOIFDua1 = 4.31e-9; /* unit m/V */ + if (!model->B3SOIFDubGiven) + model->B3SOIFDub = 5.87e-19; /* unit (m/V)**2 */ + if (!model->B3SOIFDub1Given) + model->B3SOIFDub1 = -7.61e-18; /* unit (m/V)**2 */ + if (!model->B3SOIFDucGiven) + model->B3SOIFDuc = (model->B3SOIFDmobMod == 3) ? -0.0465 : -0.0465e-9; + if (!model->B3SOIFDuc1Given) + model->B3SOIFDuc1 = (model->B3SOIFDmobMod == 3) ? -0.056 : -0.056e-9; + if (!model->B3SOIFDu0Given) + model->B3SOIFDu0 = (model->B3SOIFDtype == NMOS) ? 0.067 : 0.025; + if (!model->B3SOIFDuteGiven) + model->B3SOIFDute = -1.5; + if (!model->B3SOIFDvoffGiven) + model->B3SOIFDvoff = -0.08; + if (!model->B3SOIFDdeltaGiven) + model->B3SOIFDdelta = 0.01; + if (!model->B3SOIFDrdswGiven) + model->B3SOIFDrdsw = 100; + if (!model->B3SOIFDprwgGiven) + model->B3SOIFDprwg = 0.0; /* unit 1/V */ + if (!model->B3SOIFDprwbGiven) + model->B3SOIFDprwb = 0.0; + if (!model->B3SOIFDprtGiven) + if (!model->B3SOIFDprtGiven) + model->B3SOIFDprt = 0.0; + if (!model->B3SOIFDeta0Given) + model->B3SOIFDeta0 = 0.08; /* no unit */ + if (!model->B3SOIFDetabGiven) + model->B3SOIFDetab = -0.07; /* unit 1/V */ + if (!model->B3SOIFDpclmGiven) + model->B3SOIFDpclm = 1.3; /* no unit */ + if (!model->B3SOIFDpdibl1Given) + model->B3SOIFDpdibl1 = .39; /* no unit */ + if (!model->B3SOIFDpdibl2Given) + model->B3SOIFDpdibl2 = 0.0086; /* no unit */ + if (!model->B3SOIFDpdiblbGiven) + model->B3SOIFDpdiblb = 0.0; /* 1/V */ + if (!model->B3SOIFDpvagGiven) + model->B3SOIFDpvag = 0.0; + if (!model->B3SOIFDwrGiven) + model->B3SOIFDwr = 1.0; + if (!model->B3SOIFDdwgGiven) + model->B3SOIFDdwg = 0.0; + if (!model->B3SOIFDdwbGiven) + model->B3SOIFDdwb = 0.0; + if (!model->B3SOIFDb0Given) + model->B3SOIFDb0 = 0.0; + if (!model->B3SOIFDb1Given) + model->B3SOIFDb1 = 0.0; + if (!model->B3SOIFDalpha0Given) + model->B3SOIFDalpha0 = 0.0; + if (!model->B3SOIFDalpha1Given) + model->B3SOIFDalpha1 = 1.0; + if (!model->B3SOIFDbeta0Given) + model->B3SOIFDbeta0 = 30.0; + + if (!model->B3SOIFDcgslGiven) + model->B3SOIFDcgsl = 0.0; + if (!model->B3SOIFDcgdlGiven) + model->B3SOIFDcgdl = 0.0; + if (!model->B3SOIFDckappaGiven) + model->B3SOIFDckappa = 0.6; + if (!model->B3SOIFDclcGiven) + model->B3SOIFDclc = 0.1e-7; + if (!model->B3SOIFDcleGiven) + model->B3SOIFDcle = 0.0; + if (!model->B3SOIFDtboxGiven) + model->B3SOIFDtbox = 3e-7; + if (!model->B3SOIFDtsiGiven) + model->B3SOIFDtsi = 1e-7; + if (!model->B3SOIFDxjGiven) + model->B3SOIFDxj = model->B3SOIFDtsi; + if (!model->B3SOIFDkb1Given) + model->B3SOIFDkb1 = 1; + if (!model->B3SOIFDkb3Given) + model->B3SOIFDkb3 = 1; + if (!model->B3SOIFDdvbd0Given) + model->B3SOIFDdvbd0 = 0.0; + if (!model->B3SOIFDdvbd1Given) + model->B3SOIFDdvbd1 = 0.0; + if (!model->B3SOIFDvbsaGiven) + model->B3SOIFDvbsa = 0.0; + if (!model->B3SOIFDdelpGiven) + model->B3SOIFDdelp = 0.02; + if (!model->B3SOIFDrbodyGiven) + model->B3SOIFDrbody = 0.0; + if (!model->B3SOIFDrbshGiven) + model->B3SOIFDrbsh = 0.0; + if (!model->B3SOIFDadice0Given) + model->B3SOIFDadice0 = 1; + if (!model->B3SOIFDabpGiven) + model->B3SOIFDabp = 1; + if (!model->B3SOIFDmxcGiven) + model->B3SOIFDmxc = -0.9; + if (!model->B3SOIFDrth0Given) + model->B3SOIFDrth0 = 0; + + if (!model->B3SOIFDcth0Given) + model->B3SOIFDcth0 =0; + + if (!model->B3SOIFDaiiGiven) + model->B3SOIFDaii = 0.0; + if (!model->B3SOIFDbiiGiven) + model->B3SOIFDbii = 0.0; + if (!model->B3SOIFDciiGiven) + model->B3SOIFDcii = 0.0; + if (!model->B3SOIFDdiiGiven) + model->B3SOIFDdii = -1.0; + if (!model->B3SOIFDagidlGiven) + model->B3SOIFDagidl = 0.0; + if (!model->B3SOIFDbgidlGiven) + model->B3SOIFDbgidl = 0.0; + if (!model->B3SOIFDngidlGiven) + model->B3SOIFDngidl = 1.2; + if (!model->B3SOIFDndiodeGiven) + model->B3SOIFDndiode = 1.0; + if (!model->B3SOIFDntunGiven) + model->B3SOIFDntun = 10.0; + if (!model->B3SOIFDisbjtGiven) + model->B3SOIFDisbjt = 1e-6; + if (!model->B3SOIFDisdifGiven) + model->B3SOIFDisdif = 0.0; + if (!model->B3SOIFDisrecGiven) + model->B3SOIFDisrec = 1e-5; + if (!model->B3SOIFDistunGiven) + model->B3SOIFDistun = 0.0; + if (!model->B3SOIFDxbjtGiven) + model->B3SOIFDxbjt = 2; + if (!model->B3SOIFDxdifGiven) + model->B3SOIFDxdif = 2; + if (!model->B3SOIFDxrecGiven) + model->B3SOIFDxrec = 20; + if (!model->B3SOIFDxtunGiven) + model->B3SOIFDxtun = 0; + if (!model->B3SOIFDedlGiven) + model->B3SOIFDedl = 2e-6; + if (!model->B3SOIFDkbjt1Given) + model->B3SOIFDkbjt1 = 0; + if (!model->B3SOIFDttGiven) + model->B3SOIFDtt = 1e-12; + if (!model->B3SOIFDasdGiven) + model->B3SOIFDasd = 0.3; + + /* unit degree celcius */ + if (!model->B3SOIFDtnomGiven) + model->B3SOIFDtnom = ckt->CKTnomTemp; + if (!model->B3SOIFDLintGiven) + model->B3SOIFDLint = 0.0; + if (!model->B3SOIFDLlGiven) + model->B3SOIFDLl = 0.0; + if (!model->B3SOIFDLlnGiven) + model->B3SOIFDLln = 1.0; + if (!model->B3SOIFDLwGiven) + model->B3SOIFDLw = 0.0; + if (!model->B3SOIFDLwnGiven) + model->B3SOIFDLwn = 1.0; + if (!model->B3SOIFDLwlGiven) + model->B3SOIFDLwl = 0.0; + if (!model->B3SOIFDLminGiven) + model->B3SOIFDLmin = 0.0; + if (!model->B3SOIFDLmaxGiven) + model->B3SOIFDLmax = 1.0; + if (!model->B3SOIFDWintGiven) + model->B3SOIFDWint = 0.0; + if (!model->B3SOIFDWlGiven) + model->B3SOIFDWl = 0.0; + if (!model->B3SOIFDWlnGiven) + model->B3SOIFDWln = 1.0; + if (!model->B3SOIFDWwGiven) + model->B3SOIFDWw = 0.0; + if (!model->B3SOIFDWwnGiven) + model->B3SOIFDWwn = 1.0; + if (!model->B3SOIFDWwlGiven) + model->B3SOIFDWwl = 0.0; + if (!model->B3SOIFDWminGiven) + model->B3SOIFDWmin = 0.0; + if (!model->B3SOIFDWmaxGiven) + model->B3SOIFDWmax = 1.0; + if (!model->B3SOIFDdwcGiven) + model->B3SOIFDdwc = model->B3SOIFDWint; + if (!model->B3SOIFDdlcGiven) + model->B3SOIFDdlc = model->B3SOIFDLint; + +/* Added for binning - START */ + /* Length dependence */ + if (!model->B3SOIFDlnpeakGiven) + model->B3SOIFDlnpeak = 0.0; + if (!model->B3SOIFDlnsubGiven) + model->B3SOIFDlnsub = 0.0; + if (!model->B3SOIFDlngateGiven) + model->B3SOIFDlngate = 0.0; + if (!model->B3SOIFDlvth0Given) + model->B3SOIFDlvth0 = 0.0; + if (!model->B3SOIFDlk1Given) + model->B3SOIFDlk1 = 0.0; + if (!model->B3SOIFDlk2Given) + model->B3SOIFDlk2 = 0.0; + if (!model->B3SOIFDlk3Given) + model->B3SOIFDlk3 = 0.0; + if (!model->B3SOIFDlk3bGiven) + model->B3SOIFDlk3b = 0.0; + if (!model->B3SOIFDlvbsaGiven) + model->B3SOIFDlvbsa = 0.0; + if (!model->B3SOIFDldelpGiven) + model->B3SOIFDldelp = 0.0; + if (!model->B3SOIFDlkb1Given) + model->B3SOIFDlkb1 = 0.0; + if (!model->B3SOIFDlkb3Given) + model->B3SOIFDlkb3 = 1.0; + if (!model->B3SOIFDldvbd0Given) + model->B3SOIFDldvbd0 = 1.0; + if (!model->B3SOIFDldvbd1Given) + model->B3SOIFDldvbd1 = 1.0; + if (!model->B3SOIFDlw0Given) + model->B3SOIFDlw0 = 0.0; + if (!model->B3SOIFDlnlxGiven) + model->B3SOIFDlnlx = 0.0; + if (!model->B3SOIFDldvt0Given) + model->B3SOIFDldvt0 = 0.0; + if (!model->B3SOIFDldvt1Given) + model->B3SOIFDldvt1 = 0.0; + if (!model->B3SOIFDldvt2Given) + model->B3SOIFDldvt2 = 0.0; + if (!model->B3SOIFDldvt0wGiven) + model->B3SOIFDldvt0w = 0.0; + if (!model->B3SOIFDldvt1wGiven) + model->B3SOIFDldvt1w = 0.0; + if (!model->B3SOIFDldvt2wGiven) + model->B3SOIFDldvt2w = 0.0; + if (!model->B3SOIFDlu0Given) + model->B3SOIFDlu0 = 0.0; + if (!model->B3SOIFDluaGiven) + model->B3SOIFDlua = 0.0; + if (!model->B3SOIFDlubGiven) + model->B3SOIFDlub = 0.0; + if (!model->B3SOIFDlucGiven) + model->B3SOIFDluc = 0.0; + if (!model->B3SOIFDlvsatGiven) + model->B3SOIFDlvsat = 0.0; + if (!model->B3SOIFDla0Given) + model->B3SOIFDla0 = 0.0; + if (!model->B3SOIFDlagsGiven) + model->B3SOIFDlags = 0.0; + if (!model->B3SOIFDlb0Given) + model->B3SOIFDlb0 = 0.0; + if (!model->B3SOIFDlb1Given) + model->B3SOIFDlb1 = 0.0; + if (!model->B3SOIFDlketaGiven) + model->B3SOIFDlketa = 0.0; + if (!model->B3SOIFDlabpGiven) + model->B3SOIFDlabp = 0.0; + if (!model->B3SOIFDlmxcGiven) + model->B3SOIFDlmxc = 0.0; + if (!model->B3SOIFDladice0Given) + model->B3SOIFDladice0 = 0.0; + if (!model->B3SOIFDla1Given) + model->B3SOIFDla1 = 0.0; + if (!model->B3SOIFDla2Given) + model->B3SOIFDla2 = 0.0; + if (!model->B3SOIFDlrdswGiven) + model->B3SOIFDlrdsw = 0.0; + if (!model->B3SOIFDlprwbGiven) + model->B3SOIFDlprwb = 0.0; + if (!model->B3SOIFDlprwgGiven) + model->B3SOIFDlprwg = 0.0; + if (!model->B3SOIFDlwrGiven) + model->B3SOIFDlwr = 0.0; + if (!model->B3SOIFDlnfactorGiven) + model->B3SOIFDlnfactor = 0.0; + if (!model->B3SOIFDldwgGiven) + model->B3SOIFDldwg = 0.0; + if (!model->B3SOIFDldwbGiven) + model->B3SOIFDldwb = 0.0; + if (!model->B3SOIFDlvoffGiven) + model->B3SOIFDlvoff = 0.0; + if (!model->B3SOIFDleta0Given) + model->B3SOIFDleta0 = 0.0; + if (!model->B3SOIFDletabGiven) + model->B3SOIFDletab = 0.0; + if (!model->B3SOIFDldsubGiven) + model->B3SOIFDldsub = 0.0; + if (!model->B3SOIFDlcitGiven) + model->B3SOIFDlcit = 0.0; + if (!model->B3SOIFDlcdscGiven) + model->B3SOIFDlcdsc = 0.0; + if (!model->B3SOIFDlcdscbGiven) + model->B3SOIFDlcdscb = 0.0; + if (!model->B3SOIFDlcdscdGiven) + model->B3SOIFDlcdscd = 0.0; + if (!model->B3SOIFDlpclmGiven) + model->B3SOIFDlpclm = 0.0; + if (!model->B3SOIFDlpdibl1Given) + model->B3SOIFDlpdibl1 = 0.0; + if (!model->B3SOIFDlpdibl2Given) + model->B3SOIFDlpdibl2 = 0.0; + if (!model->B3SOIFDlpdiblbGiven) + model->B3SOIFDlpdiblb = 0.0; + if (!model->B3SOIFDldroutGiven) + model->B3SOIFDldrout = 0.0; + if (!model->B3SOIFDlpvagGiven) + model->B3SOIFDlpvag = 0.0; + if (!model->B3SOIFDldeltaGiven) + model->B3SOIFDldelta = 0.0; + if (!model->B3SOIFDlaiiGiven) + model->B3SOIFDlaii = 0.0; + if (!model->B3SOIFDlbiiGiven) + model->B3SOIFDlbii = 0.0; + if (!model->B3SOIFDlciiGiven) + model->B3SOIFDlcii = 0.0; + if (!model->B3SOIFDldiiGiven) + model->B3SOIFDldii = 0.0; + if (!model->B3SOIFDlalpha0Given) + model->B3SOIFDlalpha0 = 0.0; + if (!model->B3SOIFDlalpha1Given) + model->B3SOIFDlalpha1 = 0.0; + if (!model->B3SOIFDlbeta0Given) + model->B3SOIFDlbeta0 = 0.0; + if (!model->B3SOIFDlagidlGiven) + model->B3SOIFDlagidl = 0.0; + if (!model->B3SOIFDlbgidlGiven) + model->B3SOIFDlbgidl = 0.0; + if (!model->B3SOIFDlngidlGiven) + model->B3SOIFDlngidl = 0.0; + if (!model->B3SOIFDlntunGiven) + model->B3SOIFDlntun = 0.0; + if (!model->B3SOIFDlndiodeGiven) + model->B3SOIFDlndiode = 0.0; + if (!model->B3SOIFDlisbjtGiven) + model->B3SOIFDlisbjt = 0.0; + if (!model->B3SOIFDlisdifGiven) + model->B3SOIFDlisdif = 0.0; + if (!model->B3SOIFDlisrecGiven) + model->B3SOIFDlisrec = 0.0; + if (!model->B3SOIFDlistunGiven) + model->B3SOIFDlistun = 0.0; + if (!model->B3SOIFDledlGiven) + model->B3SOIFDledl = 0.0; + if (!model->B3SOIFDlkbjt1Given) + model->B3SOIFDlkbjt1 = 0.0; + /* CV Model */ + if (!model->B3SOIFDlvsdfbGiven) + model->B3SOIFDlvsdfb = 0.0; + if (!model->B3SOIFDlvsdthGiven) + model->B3SOIFDlvsdth = 0.0; + /* Width dependence */ + if (!model->B3SOIFDwnpeakGiven) + model->B3SOIFDwnpeak = 0.0; + if (!model->B3SOIFDwnsubGiven) + model->B3SOIFDwnsub = 0.0; + if (!model->B3SOIFDwngateGiven) + model->B3SOIFDwngate = 0.0; + if (!model->B3SOIFDwvth0Given) + model->B3SOIFDwvth0 = 0.0; + if (!model->B3SOIFDwk1Given) + model->B3SOIFDwk1 = 0.0; + if (!model->B3SOIFDwk2Given) + model->B3SOIFDwk2 = 0.0; + if (!model->B3SOIFDwk3Given) + model->B3SOIFDwk3 = 0.0; + if (!model->B3SOIFDwk3bGiven) + model->B3SOIFDwk3b = 0.0; + if (!model->B3SOIFDwvbsaGiven) + model->B3SOIFDwvbsa = 0.0; + if (!model->B3SOIFDwdelpGiven) + model->B3SOIFDwdelp = 0.0; + if (!model->B3SOIFDwkb1Given) + model->B3SOIFDwkb1 = 0.0; + if (!model->B3SOIFDwkb3Given) + model->B3SOIFDwkb3 = 1.0; + if (!model->B3SOIFDwdvbd0Given) + model->B3SOIFDwdvbd0 = 1.0; + if (!model->B3SOIFDwdvbd1Given) + model->B3SOIFDwdvbd1 = 1.0; + if (!model->B3SOIFDww0Given) + model->B3SOIFDww0 = 0.0; + if (!model->B3SOIFDwnlxGiven) + model->B3SOIFDwnlx = 0.0; + if (!model->B3SOIFDwdvt0Given) + model->B3SOIFDwdvt0 = 0.0; + if (!model->B3SOIFDwdvt1Given) + model->B3SOIFDwdvt1 = 0.0; + if (!model->B3SOIFDwdvt2Given) + model->B3SOIFDwdvt2 = 0.0; + if (!model->B3SOIFDwdvt0wGiven) + model->B3SOIFDwdvt0w = 0.0; + if (!model->B3SOIFDwdvt1wGiven) + model->B3SOIFDwdvt1w = 0.0; + if (!model->B3SOIFDwdvt2wGiven) + model->B3SOIFDwdvt2w = 0.0; + if (!model->B3SOIFDwu0Given) + model->B3SOIFDwu0 = 0.0; + if (!model->B3SOIFDwuaGiven) + model->B3SOIFDwua = 0.0; + if (!model->B3SOIFDwubGiven) + model->B3SOIFDwub = 0.0; + if (!model->B3SOIFDwucGiven) + model->B3SOIFDwuc = 0.0; + if (!model->B3SOIFDwvsatGiven) + model->B3SOIFDwvsat = 0.0; + if (!model->B3SOIFDwa0Given) + model->B3SOIFDwa0 = 0.0; + if (!model->B3SOIFDwagsGiven) + model->B3SOIFDwags = 0.0; + if (!model->B3SOIFDwb0Given) + model->B3SOIFDwb0 = 0.0; + if (!model->B3SOIFDwb1Given) + model->B3SOIFDwb1 = 0.0; + if (!model->B3SOIFDwketaGiven) + model->B3SOIFDwketa = 0.0; + if (!model->B3SOIFDwabpGiven) + model->B3SOIFDwabp = 0.0; + if (!model->B3SOIFDwmxcGiven) + model->B3SOIFDwmxc = 0.0; + if (!model->B3SOIFDwadice0Given) + model->B3SOIFDwadice0 = 0.0; + if (!model->B3SOIFDwa1Given) + model->B3SOIFDwa1 = 0.0; + if (!model->B3SOIFDwa2Given) + model->B3SOIFDwa2 = 0.0; + if (!model->B3SOIFDwrdswGiven) + model->B3SOIFDwrdsw = 0.0; + if (!model->B3SOIFDwprwbGiven) + model->B3SOIFDwprwb = 0.0; + if (!model->B3SOIFDwprwgGiven) + model->B3SOIFDwprwg = 0.0; + if (!model->B3SOIFDwwrGiven) + model->B3SOIFDwwr = 0.0; + if (!model->B3SOIFDwnfactorGiven) + model->B3SOIFDwnfactor = 0.0; + if (!model->B3SOIFDwdwgGiven) + model->B3SOIFDwdwg = 0.0; + if (!model->B3SOIFDwdwbGiven) + model->B3SOIFDwdwb = 0.0; + if (!model->B3SOIFDwvoffGiven) + model->B3SOIFDwvoff = 0.0; + if (!model->B3SOIFDweta0Given) + model->B3SOIFDweta0 = 0.0; + if (!model->B3SOIFDwetabGiven) + model->B3SOIFDwetab = 0.0; + if (!model->B3SOIFDwdsubGiven) + model->B3SOIFDwdsub = 0.0; + if (!model->B3SOIFDwcitGiven) + model->B3SOIFDwcit = 0.0; + if (!model->B3SOIFDwcdscGiven) + model->B3SOIFDwcdsc = 0.0; + if (!model->B3SOIFDwcdscbGiven) + model->B3SOIFDwcdscb = 0.0; + if (!model->B3SOIFDwcdscdGiven) + model->B3SOIFDwcdscd = 0.0; + if (!model->B3SOIFDwpclmGiven) + model->B3SOIFDwpclm = 0.0; + if (!model->B3SOIFDwpdibl1Given) + model->B3SOIFDwpdibl1 = 0.0; + if (!model->B3SOIFDwpdibl2Given) + model->B3SOIFDwpdibl2 = 0.0; + if (!model->B3SOIFDwpdiblbGiven) + model->B3SOIFDwpdiblb = 0.0; + if (!model->B3SOIFDwdroutGiven) + model->B3SOIFDwdrout = 0.0; + if (!model->B3SOIFDwpvagGiven) + model->B3SOIFDwpvag = 0.0; + if (!model->B3SOIFDwdeltaGiven) + model->B3SOIFDwdelta = 0.0; + if (!model->B3SOIFDwaiiGiven) + model->B3SOIFDwaii = 0.0; + if (!model->B3SOIFDwbiiGiven) + model->B3SOIFDwbii = 0.0; + if (!model->B3SOIFDwciiGiven) + model->B3SOIFDwcii = 0.0; + if (!model->B3SOIFDwdiiGiven) + model->B3SOIFDwdii = 0.0; + if (!model->B3SOIFDwalpha0Given) + model->B3SOIFDwalpha0 = 0.0; + if (!model->B3SOIFDwalpha1Given) + model->B3SOIFDwalpha1 = 0.0; + if (!model->B3SOIFDwbeta0Given) + model->B3SOIFDwbeta0 = 0.0; + if (!model->B3SOIFDwagidlGiven) + model->B3SOIFDwagidl = 0.0; + if (!model->B3SOIFDwbgidlGiven) + model->B3SOIFDwbgidl = 0.0; + if (!model->B3SOIFDwngidlGiven) + model->B3SOIFDwngidl = 0.0; + if (!model->B3SOIFDwntunGiven) + model->B3SOIFDwntun = 0.0; + if (!model->B3SOIFDwndiodeGiven) + model->B3SOIFDwndiode = 0.0; + if (!model->B3SOIFDwisbjtGiven) + model->B3SOIFDwisbjt = 0.0; + if (!model->B3SOIFDwisdifGiven) + model->B3SOIFDwisdif = 0.0; + if (!model->B3SOIFDwisrecGiven) + model->B3SOIFDwisrec = 0.0; + if (!model->B3SOIFDwistunGiven) + model->B3SOIFDwistun = 0.0; + if (!model->B3SOIFDwedlGiven) + model->B3SOIFDwedl = 0.0; + if (!model->B3SOIFDwkbjt1Given) + model->B3SOIFDwkbjt1 = 0.0; + /* CV Model */ + if (!model->B3SOIFDwvsdfbGiven) + model->B3SOIFDwvsdfb = 0.0; + if (!model->B3SOIFDwvsdthGiven) + model->B3SOIFDwvsdth = 0.0; + /* Cross-term dependence */ + if (!model->B3SOIFDpnpeakGiven) + model->B3SOIFDpnpeak = 0.0; + if (!model->B3SOIFDpnsubGiven) + model->B3SOIFDpnsub = 0.0; + if (!model->B3SOIFDpngateGiven) + model->B3SOIFDpngate = 0.0; + if (!model->B3SOIFDpvth0Given) + model->B3SOIFDpvth0 = 0.0; + if (!model->B3SOIFDpk1Given) + model->B3SOIFDpk1 = 0.0; + if (!model->B3SOIFDpk2Given) + model->B3SOIFDpk2 = 0.0; + if (!model->B3SOIFDpk3Given) + model->B3SOIFDpk3 = 0.0; + if (!model->B3SOIFDpk3bGiven) + model->B3SOIFDpk3b = 0.0; + if (!model->B3SOIFDpvbsaGiven) + model->B3SOIFDpvbsa = 0.0; + if (!model->B3SOIFDpdelpGiven) + model->B3SOIFDpdelp = 0.0; + if (!model->B3SOIFDpkb1Given) + model->B3SOIFDpkb1 = 0.0; + if (!model->B3SOIFDpkb3Given) + model->B3SOIFDpkb3 = 1.0; + if (!model->B3SOIFDpdvbd0Given) + model->B3SOIFDpdvbd0 = 1.0; + if (!model->B3SOIFDpdvbd1Given) + model->B3SOIFDpdvbd1 = 1.0; + if (!model->B3SOIFDpw0Given) + model->B3SOIFDpw0 = 0.0; + if (!model->B3SOIFDpnlxGiven) + model->B3SOIFDpnlx = 0.0; + if (!model->B3SOIFDpdvt0Given) + model->B3SOIFDpdvt0 = 0.0; + if (!model->B3SOIFDpdvt1Given) + model->B3SOIFDpdvt1 = 0.0; + if (!model->B3SOIFDpdvt2Given) + model->B3SOIFDpdvt2 = 0.0; + if (!model->B3SOIFDpdvt0wGiven) + model->B3SOIFDpdvt0w = 0.0; + if (!model->B3SOIFDpdvt1wGiven) + model->B3SOIFDpdvt1w = 0.0; + if (!model->B3SOIFDpdvt2wGiven) + model->B3SOIFDpdvt2w = 0.0; + if (!model->B3SOIFDpu0Given) + model->B3SOIFDpu0 = 0.0; + if (!model->B3SOIFDpuaGiven) + model->B3SOIFDpua = 0.0; + if (!model->B3SOIFDpubGiven) + model->B3SOIFDpub = 0.0; + if (!model->B3SOIFDpucGiven) + model->B3SOIFDpuc = 0.0; + if (!model->B3SOIFDpvsatGiven) + model->B3SOIFDpvsat = 0.0; + if (!model->B3SOIFDpa0Given) + model->B3SOIFDpa0 = 0.0; + if (!model->B3SOIFDpagsGiven) + model->B3SOIFDpags = 0.0; + if (!model->B3SOIFDpb0Given) + model->B3SOIFDpb0 = 0.0; + if (!model->B3SOIFDpb1Given) + model->B3SOIFDpb1 = 0.0; + if (!model->B3SOIFDpketaGiven) + model->B3SOIFDpketa = 0.0; + if (!model->B3SOIFDpabpGiven) + model->B3SOIFDpabp = 0.0; + if (!model->B3SOIFDpmxcGiven) + model->B3SOIFDpmxc = 0.0; + if (!model->B3SOIFDpadice0Given) + model->B3SOIFDpadice0 = 0.0; + if (!model->B3SOIFDpa1Given) + model->B3SOIFDpa1 = 0.0; + if (!model->B3SOIFDpa2Given) + model->B3SOIFDpa2 = 0.0; + if (!model->B3SOIFDprdswGiven) + model->B3SOIFDprdsw = 0.0; + if (!model->B3SOIFDpprwbGiven) + model->B3SOIFDpprwb = 0.0; + if (!model->B3SOIFDpprwgGiven) + model->B3SOIFDpprwg = 0.0; + if (!model->B3SOIFDpwrGiven) + model->B3SOIFDpwr = 0.0; + if (!model->B3SOIFDpnfactorGiven) + model->B3SOIFDpnfactor = 0.0; + if (!model->B3SOIFDpdwgGiven) + model->B3SOIFDpdwg = 0.0; + if (!model->B3SOIFDpdwbGiven) + model->B3SOIFDpdwb = 0.0; + if (!model->B3SOIFDpvoffGiven) + model->B3SOIFDpvoff = 0.0; + if (!model->B3SOIFDpeta0Given) + model->B3SOIFDpeta0 = 0.0; + if (!model->B3SOIFDpetabGiven) + model->B3SOIFDpetab = 0.0; + if (!model->B3SOIFDpdsubGiven) + model->B3SOIFDpdsub = 0.0; + if (!model->B3SOIFDpcitGiven) + model->B3SOIFDpcit = 0.0; + if (!model->B3SOIFDpcdscGiven) + model->B3SOIFDpcdsc = 0.0; + if (!model->B3SOIFDpcdscbGiven) + model->B3SOIFDpcdscb = 0.0; + if (!model->B3SOIFDpcdscdGiven) + model->B3SOIFDpcdscd = 0.0; + if (!model->B3SOIFDppclmGiven) + model->B3SOIFDppclm = 0.0; + if (!model->B3SOIFDppdibl1Given) + model->B3SOIFDppdibl1 = 0.0; + if (!model->B3SOIFDppdibl2Given) + model->B3SOIFDppdibl2 = 0.0; + if (!model->B3SOIFDppdiblbGiven) + model->B3SOIFDppdiblb = 0.0; + if (!model->B3SOIFDpdroutGiven) + model->B3SOIFDpdrout = 0.0; + if (!model->B3SOIFDppvagGiven) + model->B3SOIFDppvag = 0.0; + if (!model->B3SOIFDpdeltaGiven) + model->B3SOIFDpdelta = 0.0; + if (!model->B3SOIFDpaiiGiven) + model->B3SOIFDpaii = 0.0; + if (!model->B3SOIFDpbiiGiven) + model->B3SOIFDpbii = 0.0; + if (!model->B3SOIFDpciiGiven) + model->B3SOIFDpcii = 0.0; + if (!model->B3SOIFDpdiiGiven) + model->B3SOIFDpdii = 0.0; + if (!model->B3SOIFDpalpha0Given) + model->B3SOIFDpalpha0 = 0.0; + if (!model->B3SOIFDpalpha1Given) + model->B3SOIFDpalpha1 = 0.0; + if (!model->B3SOIFDpbeta0Given) + model->B3SOIFDpbeta0 = 0.0; + if (!model->B3SOIFDpagidlGiven) + model->B3SOIFDpagidl = 0.0; + if (!model->B3SOIFDpbgidlGiven) + model->B3SOIFDpbgidl = 0.0; + if (!model->B3SOIFDpngidlGiven) + model->B3SOIFDpngidl = 0.0; + if (!model->B3SOIFDpntunGiven) + model->B3SOIFDpntun = 0.0; + if (!model->B3SOIFDpndiodeGiven) + model->B3SOIFDpndiode = 0.0; + if (!model->B3SOIFDpisbjtGiven) + model->B3SOIFDpisbjt = 0.0; + if (!model->B3SOIFDpisdifGiven) + model->B3SOIFDpisdif = 0.0; + if (!model->B3SOIFDpisrecGiven) + model->B3SOIFDpisrec = 0.0; + if (!model->B3SOIFDpistunGiven) + model->B3SOIFDpistun = 0.0; + if (!model->B3SOIFDpedlGiven) + model->B3SOIFDpedl = 0.0; + if (!model->B3SOIFDpkbjt1Given) + model->B3SOIFDpkbjt1 = 0.0; + /* CV Model */ + if (!model->B3SOIFDpvsdfbGiven) + model->B3SOIFDpvsdfb = 0.0; + if (!model->B3SOIFDpvsdthGiven) + model->B3SOIFDpvsdth = 0.0; +/* Added for binning - END */ + + if (!model->B3SOIFDcfGiven) + model->B3SOIFDcf = 2.0 * EPSOX / PI + * log(1.0 + 0.4e-6 / model->B3SOIFDtox); + if (!model->B3SOIFDcgdoGiven) + { if (model->B3SOIFDdlcGiven && (model->B3SOIFDdlc > 0.0)) + { model->B3SOIFDcgdo = model->B3SOIFDdlc * model->B3SOIFDcox + - model->B3SOIFDcgdl ; + } + else + model->B3SOIFDcgdo = 0.6 * model->B3SOIFDxj * model->B3SOIFDcox; + } + if (!model->B3SOIFDcgsoGiven) + { if (model->B3SOIFDdlcGiven && (model->B3SOIFDdlc > 0.0)) + { model->B3SOIFDcgso = model->B3SOIFDdlc * model->B3SOIFDcox + - model->B3SOIFDcgsl ; + } + else + model->B3SOIFDcgso = 0.6 * model->B3SOIFDxj * model->B3SOIFDcox; + } + + if (!model->B3SOIFDcgeoGiven) + { model->B3SOIFDcgeo = 0.0; + } + if (!model->B3SOIFDxpartGiven) + model->B3SOIFDxpart = 0.0; + if (!model->B3SOIFDsheetResistanceGiven) + model->B3SOIFDsheetResistance = 0.0; + if (!model->B3SOIFDcsdeswGiven) + model->B3SOIFDcsdesw = 0.0; + if (!model->B3SOIFDunitLengthGateSidewallJctCapGiven) + model->B3SOIFDunitLengthGateSidewallJctCap = 1e-10; + if (!model->B3SOIFDGatesidewallJctPotentialGiven) + model->B3SOIFDGatesidewallJctPotential = 0.7; + if (!model->B3SOIFDbodyJctGateSideGradingCoeffGiven) + model->B3SOIFDbodyJctGateSideGradingCoeff = 0.5; + if (!model->B3SOIFDoxideTrapDensityAGiven) + { if (model->B3SOIFDtype == NMOS) + model->B3SOIFDoxideTrapDensityA = 1e20; + else + model->B3SOIFDoxideTrapDensityA=9.9e18; + } + if (!model->B3SOIFDoxideTrapDensityBGiven) + { if (model->B3SOIFDtype == NMOS) + model->B3SOIFDoxideTrapDensityB = 5e4; + else + model->B3SOIFDoxideTrapDensityB = 2.4e3; + } + if (!model->B3SOIFDoxideTrapDensityCGiven) + { if (model->B3SOIFDtype == NMOS) + model->B3SOIFDoxideTrapDensityC = -1.4e-12; + else + model->B3SOIFDoxideTrapDensityC = 1.4e-12; + + } + if (!model->B3SOIFDemGiven) + model->B3SOIFDem = 4.1e7; /* V/m */ + if (!model->B3SOIFDefGiven) + model->B3SOIFDef = 1.0; + if (!model->B3SOIFDafGiven) + model->B3SOIFDaf = 1.0; + if (!model->B3SOIFDkfGiven) + model->B3SOIFDkf = 0.0; + if (!model->B3SOIFDnoifGiven) + model->B3SOIFDnoif = 1.0; + + /* loop through all the instances of the model */ + for (here = model->B3SOIFDinstances; here != NULL ; + here=here->B3SOIFDnextInstance) + { /* allocate a chunk of the state vector */ + here->B3SOIFDstates = *states; + *states += B3SOIFDnumStates; + /* perform the parameter defaulting */ + if (!here->B3SOIFDdrainAreaGiven) + here->B3SOIFDdrainArea = 0.0; + if (!here->B3SOIFDdrainPerimeterGiven) + here->B3SOIFDdrainPerimeter = 0.0; + if (!here->B3SOIFDdrainSquaresGiven) + here->B3SOIFDdrainSquares = 1.0; + if (!here->B3SOIFDicVBSGiven) + here->B3SOIFDicVBS = 0; + if (!here->B3SOIFDicVDSGiven) + here->B3SOIFDicVDS = 0; + if (!here->B3SOIFDicVGSGiven) + here->B3SOIFDicVGS = 0; + if (!here->B3SOIFDicVESGiven) + here->B3SOIFDicVES = 0; + if (!here->B3SOIFDicVPSGiven) + here->B3SOIFDicVPS = 0; + if (!here->B3SOIFDbjtoffGiven) + here->B3SOIFDbjtoff = 0; + if (!here->B3SOIFDdebugModGiven) + here->B3SOIFDdebugMod = 0; + if (!here->B3SOIFDrth0Given) + here->B3SOIFDrth0 = model->B3SOIFDrth0; + if (!here->B3SOIFDcth0Given) + here->B3SOIFDcth0 = model->B3SOIFDcth0; + if (!here->B3SOIFDbodySquaresGiven) + here->B3SOIFDbodySquares = 1.0; + if (!here->B3SOIFDlGiven) + here->B3SOIFDl = 5e-6; + if (!here->B3SOIFDsourceAreaGiven) + here->B3SOIFDsourceArea = 0; + if (!here->B3SOIFDsourcePerimeterGiven) + here->B3SOIFDsourcePerimeter = 0; + if (!here->B3SOIFDsourceSquaresGiven) + here->B3SOIFDsourceSquares = 1; + if (!here->B3SOIFDwGiven) + here->B3SOIFDw = 5e-6; + + if (!here->B3SOIFDoffGiven) + here->B3SOIFDoff = 0; + + + /* process drain series resistance */ + if ((model->B3SOIFDsheetResistance > 0.0) && + (here->B3SOIFDdrainSquares > 0.0 ) && + (here->B3SOIFDdNodePrime == 0)) + { error = CKTmkVolt(ckt,&tmp,here->B3SOIFDname,"drain"); + if(error) return(error); + here->B3SOIFDdNodePrime = tmp->number; + } + else + { here->B3SOIFDdNodePrime = here->B3SOIFDdNode; + } + + /* process source series resistance */ + if ((model->B3SOIFDsheetResistance > 0.0) && + (here->B3SOIFDsourceSquares > 0.0 ) && + (here->B3SOIFDsNodePrime == 0)) + { error = CKTmkVolt(ckt,&tmp,here->B3SOIFDname,"source"); + if(error) return(error); + here->B3SOIFDsNodePrime = tmp->number; + } + else + { here->B3SOIFDsNodePrime = here->B3SOIFDsNode; + } + + /* process effective silicon film thickness */ + model->B3SOIFDcbox = 3.453133e-11 / model->B3SOIFDtbox; + model->B3SOIFDcsi = 1.03594e-10 / model->B3SOIFDtsi; + Cboxt = model->B3SOIFDcbox * model->B3SOIFDcsi / (model->B3SOIFDcbox + model->B3SOIFDcsi); + model->B3SOIFDqsi = Charge_q*model->B3SOIFDnpeak*1e6*model->B3SOIFDtsi; + /* Tsieff */ + tmp1 = 2.0 * EPSSI * model->B3SOIFDvbsa / Charge_q + / (1e6*model->B3SOIFDnpeak); + tmp2 = model->B3SOIFDtsi * model->B3SOIFDtsi; + if (tmp2 < tmp1) + { + fprintf(stderr, "vbsa = %.3f is too large for this tsi = %.3e and is automatically set to zero\n", model->B3SOIFDvbsa, model->B3SOIFDtsi); + model->B3SOIFDcsieff = model->B3SOIFDcsi; + model->B3SOIFDqsieff = model->B3SOIFDqsi; + } + else + { + tmp1 = sqrt(model->B3SOIFDtsi * model->B3SOIFDtsi - + 2.0 * EPSSI * model->B3SOIFDvbsa / Charge_q / + (1e6*model->B3SOIFDnpeak)); + model->B3SOIFDcsieff = 1.03594e-10 / tmp1; + model->B3SOIFDqsieff = Charge_q*model->B3SOIFDnpeak*1e6*tmp1; + } + model->B3SOIFDcsit = 1/(1/model->B3SOIFDcox + 1/model->B3SOIFDcsieff); + model->B3SOIFDcboxt = 1/(1/model->B3SOIFDcbox + 1/model->B3SOIFDcsieff); + nfb0 = 1/(1 + model->B3SOIFDcbox / model->B3SOIFDcsit); + model->B3SOIFDnfb = model->B3SOIFDkb3 * nfb0; + model->B3SOIFDadice = model->B3SOIFDadice0 / ( 1 + Cboxt / model->B3SOIFDcox); + + here->B3SOIFDfloat = 0; + if (here->B3SOIFDbNode == -1) + /* no internal body node is needed for SPICE iteration */ + { here->B3SOIFDbNode = here->B3SOIFDpNode = 0; + here->B3SOIFDbodyMod = 0; + } + else /* body tied */ + { if ((model->B3SOIFDrbody == 0.0) && (model->B3SOIFDrbsh == 0.0)) + { /* ideal body tie */ + here->B3SOIFDbodyMod = 2; + /* pNode is not used in this case */ + } + else { + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Body"); + if(error) return(error); + here->B3SOIFDbodyMod = 1; + here->B3SOIFDpNode = here->B3SOIFDbNode; + here->B3SOIFDbNode = tmp->number; + } + } + + if ((model->B3SOIFDshMod == 1) && (here->B3SOIFDrth0!=0)) + { + error = CKTmkVolt(ckt,&tmp,here->B3SOIFDname,"Temp"); + if(error) return(error); + here->B3SOIFDtempNode = tmp->number; + + } else { + here->B3SOIFDtempNode = 0; + } + +/* here for debugging purpose only */ + if ((here->B3SOIFDdebugMod > 1) || (here->B3SOIFDdebugMod == -1)) + { + /* The real Vbs value */ + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Vbs"); + if(error) return(error); + here->B3SOIFDvbsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Ids"); + if(error) return(error); + here->B3SOIFDidsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Ic"); + if(error) return(error); + here->B3SOIFDicNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Ibs"); + if(error) return(error); + here->B3SOIFDibsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Ibd"); + if(error) return(error); + here->B3SOIFDibdNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Iii"); + if(error) return(error); + here->B3SOIFDiiiNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Igidl"); + if(error) return(error); + here->B3SOIFDigidlNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Itun"); + if(error) return(error); + here->B3SOIFDitunNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Ibp"); + if(error) return(error); + here->B3SOIFDibpNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Abeff"); + if(error) return(error); + here->B3SOIFDabeffNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Vbs0eff"); + if(error) return(error); + here->B3SOIFDvbs0effNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Vbseff"); + if(error) return(error); + here->B3SOIFDvbseffNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Xc"); + if(error) return(error); + here->B3SOIFDxcNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Cbb"); + if(error) return(error); + here->B3SOIFDcbbNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Cbd"); + if(error) return(error); + here->B3SOIFDcbdNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Cbg"); + if(error) return(error); + here->B3SOIFDcbgNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Qbody"); + if(error) return(error); + here->B3SOIFDqbNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Qbf"); + if(error) return(error); + here->B3SOIFDqbfNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Qjs"); + if(error) return(error); + here->B3SOIFDqjsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Qjd"); + if(error) return(error); + here->B3SOIFDqjdNode = tmp->number; + + /* clean up last */ + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Gm"); + if(error) return(error); + here->B3SOIFDgmNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Gmbs"); + if(error) return(error); + here->B3SOIFDgmbsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Gds"); + if(error) return(error); + here->B3SOIFDgdsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Gme"); + if(error) return(error); + here->B3SOIFDgmeNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Vbs0teff"); + if(error) return(error); + here->B3SOIFDvbs0teffNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Vth"); + if(error) return(error); + here->B3SOIFDvthNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Vgsteff"); + if(error) return(error); + here->B3SOIFDvgsteffNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Xcsat"); + if(error) return(error); + here->B3SOIFDxcsatNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Qac0"); + if(error) return(error); + here->B3SOIFDqaccNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Qsub0"); + if(error) return(error); + here->B3SOIFDqsub0Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Qsubs1"); + if(error) return(error); + here->B3SOIFDqsubs1Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Qsubs2"); + if(error) return(error); + here->B3SOIFDqsubs2Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Qsub"); + if(error) return(error); + here->B3SOIFDqeNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Qdrn"); + if(error) return(error); + here->B3SOIFDqdNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Qgate"); + if(error) return(error); + here->B3SOIFDqgNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Vdscv"); + if(error) return(error); + here->B3SOIFDvdscvNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Vcscv"); + if(error) return(error); + here->B3SOIFDvcscvNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Cbe"); + if(error) return(error); + here->B3SOIFDcbeNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Dum1"); + if(error) return(error); + here->B3SOIFDdum1Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Dum2"); + if(error) return(error); + here->B3SOIFDdum2Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Dum3"); + if(error) return(error); + here->B3SOIFDdum3Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Dum4"); + if(error) return(error); + here->B3SOIFDdum4Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIFDname, "Dum5"); + if(error) return(error); + here->B3SOIFDdum5Node = tmp->number; + } + + /* set Sparse Matrix Pointers */ + +/* macro to make elements with built in test for out of memory */ +#define TSTALLOC(ptr,first,second) \ +if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ + return(E_NOMEM);\ +} + + + if ((model->B3SOIFDshMod == 1) && (here->B3SOIFDrth0!=0.0)) { + TSTALLOC(B3SOIFDTemptempPtr, B3SOIFDtempNode, B3SOIFDtempNode) + TSTALLOC(B3SOIFDTempdpPtr, B3SOIFDtempNode, B3SOIFDdNodePrime) + TSTALLOC(B3SOIFDTempspPtr, B3SOIFDtempNode, B3SOIFDsNodePrime) + TSTALLOC(B3SOIFDTempgPtr, B3SOIFDtempNode, B3SOIFDgNode) + TSTALLOC(B3SOIFDTempbPtr, B3SOIFDtempNode, B3SOIFDbNode) + TSTALLOC(B3SOIFDTempePtr, B3SOIFDtempNode, B3SOIFDeNode) + + TSTALLOC(B3SOIFDGtempPtr, B3SOIFDgNode, B3SOIFDtempNode) + TSTALLOC(B3SOIFDDPtempPtr, B3SOIFDdNodePrime, B3SOIFDtempNode) + TSTALLOC(B3SOIFDSPtempPtr, B3SOIFDsNodePrime, B3SOIFDtempNode) + TSTALLOC(B3SOIFDEtempPtr, B3SOIFDeNode, B3SOIFDtempNode) + TSTALLOC(B3SOIFDBtempPtr, B3SOIFDbNode, B3SOIFDtempNode) + + if (here->B3SOIFDbodyMod == 1) { + TSTALLOC(B3SOIFDPtempPtr, B3SOIFDpNode, B3SOIFDtempNode) + } + } + if (here->B3SOIFDbodyMod == 2) { + /* Don't create any Jacobian entry for pNode */ + } + else if (here->B3SOIFDbodyMod == 1) { + TSTALLOC(B3SOIFDBpPtr, B3SOIFDbNode, B3SOIFDpNode) + TSTALLOC(B3SOIFDPbPtr, B3SOIFDpNode, B3SOIFDbNode) + TSTALLOC(B3SOIFDPpPtr, B3SOIFDpNode, B3SOIFDpNode) + TSTALLOC(B3SOIFDPgPtr, B3SOIFDpNode, B3SOIFDgNode) + TSTALLOC(B3SOIFDPdpPtr, B3SOIFDpNode, B3SOIFDdNodePrime) + TSTALLOC(B3SOIFDPspPtr, B3SOIFDpNode, B3SOIFDsNodePrime) + TSTALLOC(B3SOIFDPePtr, B3SOIFDpNode, B3SOIFDeNode) + } + + TSTALLOC(B3SOIFDEgPtr, B3SOIFDeNode, B3SOIFDgNode) + TSTALLOC(B3SOIFDEdpPtr, B3SOIFDeNode, B3SOIFDdNodePrime) + TSTALLOC(B3SOIFDEspPtr, B3SOIFDeNode, B3SOIFDsNodePrime) + TSTALLOC(B3SOIFDGePtr, B3SOIFDgNode, B3SOIFDeNode) + TSTALLOC(B3SOIFDDPePtr, B3SOIFDdNodePrime, B3SOIFDeNode) + TSTALLOC(B3SOIFDSPePtr, B3SOIFDsNodePrime, B3SOIFDeNode) + + TSTALLOC(B3SOIFDEbPtr, B3SOIFDeNode, B3SOIFDbNode) + TSTALLOC(B3SOIFDEePtr, B3SOIFDeNode, B3SOIFDeNode) + + TSTALLOC(B3SOIFDGgPtr, B3SOIFDgNode, B3SOIFDgNode) + TSTALLOC(B3SOIFDGdpPtr, B3SOIFDgNode, B3SOIFDdNodePrime) + TSTALLOC(B3SOIFDGspPtr, B3SOIFDgNode, B3SOIFDsNodePrime) + + TSTALLOC(B3SOIFDDPgPtr, B3SOIFDdNodePrime, B3SOIFDgNode) + TSTALLOC(B3SOIFDDPdpPtr, B3SOIFDdNodePrime, B3SOIFDdNodePrime) + TSTALLOC(B3SOIFDDPspPtr, B3SOIFDdNodePrime, B3SOIFDsNodePrime) + TSTALLOC(B3SOIFDDPdPtr, B3SOIFDdNodePrime, B3SOIFDdNode) + + TSTALLOC(B3SOIFDSPgPtr, B3SOIFDsNodePrime, B3SOIFDgNode) + TSTALLOC(B3SOIFDSPdpPtr, B3SOIFDsNodePrime, B3SOIFDdNodePrime) + TSTALLOC(B3SOIFDSPspPtr, B3SOIFDsNodePrime, B3SOIFDsNodePrime) + TSTALLOC(B3SOIFDSPsPtr, B3SOIFDsNodePrime, B3SOIFDsNode) + + TSTALLOC(B3SOIFDDdPtr, B3SOIFDdNode, B3SOIFDdNode) + TSTALLOC(B3SOIFDDdpPtr, B3SOIFDdNode, B3SOIFDdNodePrime) + + TSTALLOC(B3SOIFDSsPtr, B3SOIFDsNode, B3SOIFDsNode) + TSTALLOC(B3SOIFDSspPtr, B3SOIFDsNode, B3SOIFDsNodePrime) + +/* here for debugging purpose only */ + if ((here->B3SOIFDdebugMod > 1) || (here->B3SOIFDdebugMod == -1)) + { + TSTALLOC(B3SOIFDVbsPtr, B3SOIFDvbsNode, B3SOIFDvbsNode) + TSTALLOC(B3SOIFDIdsPtr, B3SOIFDidsNode, B3SOIFDidsNode) + TSTALLOC(B3SOIFDIcPtr, B3SOIFDicNode, B3SOIFDicNode) + TSTALLOC(B3SOIFDIbsPtr, B3SOIFDibsNode, B3SOIFDibsNode) + TSTALLOC(B3SOIFDIbdPtr, B3SOIFDibdNode, B3SOIFDibdNode) + TSTALLOC(B3SOIFDIiiPtr, B3SOIFDiiiNode, B3SOIFDiiiNode) + TSTALLOC(B3SOIFDIgidlPtr, B3SOIFDigidlNode, B3SOIFDigidlNode) + TSTALLOC(B3SOIFDItunPtr, B3SOIFDitunNode, B3SOIFDitunNode) + TSTALLOC(B3SOIFDIbpPtr, B3SOIFDibpNode, B3SOIFDibpNode) + TSTALLOC(B3SOIFDAbeffPtr, B3SOIFDabeffNode, B3SOIFDabeffNode) + TSTALLOC(B3SOIFDVbs0effPtr, B3SOIFDvbs0effNode, B3SOIFDvbs0effNode) + TSTALLOC(B3SOIFDVbseffPtr, B3SOIFDvbseffNode, B3SOIFDvbseffNode) + TSTALLOC(B3SOIFDXcPtr, B3SOIFDxcNode, B3SOIFDxcNode) + TSTALLOC(B3SOIFDCbbPtr, B3SOIFDcbbNode, B3SOIFDcbbNode) + TSTALLOC(B3SOIFDCbdPtr, B3SOIFDcbdNode, B3SOIFDcbdNode) + TSTALLOC(B3SOIFDCbgPtr, B3SOIFDcbgNode, B3SOIFDcbgNode) + TSTALLOC(B3SOIFDqbPtr, B3SOIFDqbNode, B3SOIFDqbNode) + TSTALLOC(B3SOIFDQbfPtr, B3SOIFDqbfNode, B3SOIFDqbfNode) + TSTALLOC(B3SOIFDQjsPtr, B3SOIFDqjsNode, B3SOIFDqjsNode) + TSTALLOC(B3SOIFDQjdPtr, B3SOIFDqjdNode, B3SOIFDqjdNode) + + /* clean up last */ + TSTALLOC(B3SOIFDGmPtr, B3SOIFDgmNode, B3SOIFDgmNode) + TSTALLOC(B3SOIFDGmbsPtr, B3SOIFDgmbsNode, B3SOIFDgmbsNode) + TSTALLOC(B3SOIFDGdsPtr, B3SOIFDgdsNode, B3SOIFDgdsNode) + TSTALLOC(B3SOIFDGmePtr, B3SOIFDgmeNode, B3SOIFDgmeNode) + TSTALLOC(B3SOIFDVbs0teffPtr, B3SOIFDvbs0teffNode, B3SOIFDvbs0teffNode) + TSTALLOC(B3SOIFDVthPtr, B3SOIFDvthNode, B3SOIFDvthNode) + TSTALLOC(B3SOIFDVgsteffPtr, B3SOIFDvgsteffNode, B3SOIFDvgsteffNode) + TSTALLOC(B3SOIFDXcsatPtr, B3SOIFDxcsatNode, B3SOIFDxcsatNode) + TSTALLOC(B3SOIFDVcscvPtr, B3SOIFDvcscvNode, B3SOIFDvcscvNode) + TSTALLOC(B3SOIFDVdscvPtr, B3SOIFDvdscvNode, B3SOIFDvdscvNode) + TSTALLOC(B3SOIFDCbePtr, B3SOIFDcbeNode, B3SOIFDcbeNode) + TSTALLOC(B3SOIFDDum1Ptr, B3SOIFDdum1Node, B3SOIFDdum1Node) + TSTALLOC(B3SOIFDDum2Ptr, B3SOIFDdum2Node, B3SOIFDdum2Node) + TSTALLOC(B3SOIFDDum3Ptr, B3SOIFDdum3Node, B3SOIFDdum3Node) + TSTALLOC(B3SOIFDDum4Ptr, B3SOIFDdum4Node, B3SOIFDdum4Node) + TSTALLOC(B3SOIFDDum5Ptr, B3SOIFDdum5Node, B3SOIFDdum5Node) + TSTALLOC(B3SOIFDQaccPtr, B3SOIFDqaccNode, B3SOIFDqaccNode) + TSTALLOC(B3SOIFDQsub0Ptr, B3SOIFDqsub0Node, B3SOIFDqsub0Node) + TSTALLOC(B3SOIFDQsubs1Ptr, B3SOIFDqsubs1Node, B3SOIFDqsubs1Node) + TSTALLOC(B3SOIFDQsubs2Ptr, B3SOIFDqsubs2Node, B3SOIFDqsubs2Node) + TSTALLOC(B3SOIFDqePtr, B3SOIFDqeNode, B3SOIFDqeNode) + TSTALLOC(B3SOIFDqdPtr, B3SOIFDqdNode, B3SOIFDqdNode) + TSTALLOC(B3SOIFDqgPtr, B3SOIFDqgNode, B3SOIFDqgNode) + } + + } + } + return(OK); +} + +int +B3SOIFDunsetup(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ +#ifndef HAS_BATCHSIM + B3SOIFDmodel *model; + B3SOIFDinstance *here; + + for (model = (B3SOIFDmodel *)inModel; model != NULL; + model = model->B3SOIFDnextModel) + { + for (here = model->B3SOIFDinstances; here != NULL; + here=here->B3SOIFDnextInstance) + { + if (here->B3SOIFDdNodePrime + && here->B3SOIFDdNodePrime != here->B3SOIFDdNode) + { + CKTdltNNum(ckt, here->B3SOIFDdNodePrime); + here->B3SOIFDdNodePrime = 0; + } + if (here->B3SOIFDsNodePrime + && here->B3SOIFDsNodePrime != here->B3SOIFDsNode) + { + CKTdltNNum(ckt, here->B3SOIFDsNodePrime); + here->B3SOIFDsNodePrime = 0; + } + } + } +#endif + return OK; +} + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdtemp.c b/src/spicelib/devices/bsim3soi_fd/b3soifdtemp.c new file mode 100644 index 000000000..e055ba8c1 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdtemp.c @@ -0,0 +1,815 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soifdtemp.c 98/5/01 +Modified by Pin Su, Wei Jin 99/9/27 +**********/ + +/* Lmin, Lmax, Wmin, Wmax */ + +#include "ngspice.h" +#include +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "b3soifddef.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + +#define Kb 1.3806226e-23 +#define KboQ 8.617087e-5 /* Kb / q where q = 1.60219e-19 */ +#define EPSOX 3.453133e-11 +#define EPSSI 1.03594e-10 +#define PI 3.141592654 +#define MAX_EXP 5.834617425e14 +#define MIN_EXP 1.713908431e-15 +#define EXP_THRESHOLD 34.0 +#define Charge_q 1.60219e-19 + + +/* ARGSUSED */ +int +B3SOIFDtemp(inModel,ckt) +GENmodel *inModel; +CKTcircuit *ckt; +{ + B3SOIFDmodel *model = (B3SOIFDmodel*) inModel; + B3SOIFDinstance *here; +struct b3soifdSizeDependParam *pSizeDependParamKnot, *pLastKnot, *pParam; +double tmp, tmp1, tmp2, Eg, Eg0, ni, T0, T1, T2, T3, T4, T5, T6, Ldrn, Wdrn; +double Temp, TRatio, Inv_L, Inv_W, Inv_LW, Dw, Dl, Vtm0, Tnom; +double SDphi, SDgamma; +int Size_Not_Found; + + /* loop through all the B3SOIFD device models */ + for (; model != NULL; model = model->B3SOIFDnextModel) + { Temp = ckt->CKTtemp; + if (model->B3SOIFDGatesidewallJctPotential < 0.1) + model->B3SOIFDGatesidewallJctPotential = 0.1; + model->pSizeDependParamKnot = NULL; + pLastKnot = NULL; + + Tnom = model->B3SOIFDtnom; + TRatio = Temp / Tnom; + + model->B3SOIFDvcrit = CONSTvt0 * log(CONSTvt0 / (CONSTroot2 * 1.0e-14)); + model->B3SOIFDfactor1 = sqrt(EPSSI / EPSOX * model->B3SOIFDtox); + + Vtm0 = KboQ * Tnom; + Eg0 = 1.16 - 7.02e-4 * Tnom * Tnom / (Tnom + 1108.0); + model->B3SOIFDeg0 = Eg0; + model->B3SOIFDvtm = KboQ * Temp; + + Eg = 1.16 - 7.02e-4 * Temp * Temp / (Temp + 1108.0); + /* ni is in cm^-3 */ + ni = 1.45e10 * (Temp / 300.15) * sqrt(Temp / 300.15) + * exp(21.5565981 - Eg / (2.0 * model->B3SOIFDvtm)); + + + /* loop through all the instances of the model */ + /* MCJ: Length and Width not initialized */ + for (here = model->B3SOIFDinstances; here != NULL; + here = here->B3SOIFDnextInstance) + { + here->B3SOIFDrbodyext = here->B3SOIFDbodySquares * + model->B3SOIFDrbsh; + pSizeDependParamKnot = model->pSizeDependParamKnot; + Size_Not_Found = 1; + while ((pSizeDependParamKnot != NULL) && Size_Not_Found) + { if ((here->B3SOIFDl == pSizeDependParamKnot->Length) + && (here->B3SOIFDw == pSizeDependParamKnot->Width) + && (here->B3SOIFDrth0 == pSizeDependParamKnot->Rth0) + && (here->B3SOIFDcth0 == pSizeDependParamKnot->Cth0)) + { Size_Not_Found = 0; + here->pParam = pSizeDependParamKnot; + } + else + { pLastKnot = pSizeDependParamKnot; + pSizeDependParamKnot = pSizeDependParamKnot->pNext; + } + } + + if (Size_Not_Found) + { pParam = (struct b3soifdSizeDependParam *)malloc( + sizeof(struct b3soifdSizeDependParam)); + if (pLastKnot == NULL) + model->pSizeDependParamKnot = pParam; + else + pLastKnot->pNext = pParam; + pParam->pNext = NULL; + here->pParam = pParam; + + Ldrn = here->B3SOIFDl; + Wdrn = here->B3SOIFDw; + pParam->Length = Ldrn; + pParam->Width = Wdrn; + pParam->Rth0 = here->B3SOIFDrth0; + pParam->Cth0 = here->B3SOIFDcth0; + + T0 = pow(Ldrn, model->B3SOIFDLln); + T1 = pow(Wdrn, model->B3SOIFDLwn); + tmp1 = model->B3SOIFDLl / T0 + model->B3SOIFDLw / T1 + + model->B3SOIFDLwl / (T0 * T1); + pParam->B3SOIFDdl = model->B3SOIFDLint + tmp1; + pParam->B3SOIFDdlc = model->B3SOIFDdlc + tmp1; + + T2 = pow(Ldrn, model->B3SOIFDWln); + T3 = pow(Wdrn, model->B3SOIFDWwn); + tmp2 = model->B3SOIFDWl / T2 + model->B3SOIFDWw / T3 + + model->B3SOIFDWwl / (T2 * T3); + pParam->B3SOIFDdw = model->B3SOIFDWint + tmp2; + pParam->B3SOIFDdwc = model->B3SOIFDdwc + tmp2; + + pParam->B3SOIFDleff = here->B3SOIFDl - 2.0 * pParam->B3SOIFDdl; + if (pParam->B3SOIFDleff <= 0.0) + { IFuid namarray[2]; + namarray[0] = model->B3SOIFDmodName; + namarray[1] = here->B3SOIFDname; + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "B3SOIFD: mosfet %s, model %s: Effective channel length <= 0", + namarray); + return(E_BADPARM); + } + + pParam->B3SOIFDweff = here->B3SOIFDw - 2.0 * pParam->B3SOIFDdw; + if (pParam->B3SOIFDweff <= 0.0) + { IFuid namarray[2]; + namarray[0] = model->B3SOIFDmodName; + namarray[1] = here->B3SOIFDname; + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "B3SOIFD: mosfet %s, model %s: Effective channel width <= 0", + namarray); + return(E_BADPARM); + } + + pParam->B3SOIFDleffCV = here->B3SOIFDl - 2.0 * pParam->B3SOIFDdlc; + if (pParam->B3SOIFDleffCV <= 0.0) + { IFuid namarray[2]; + namarray[0] = model->B3SOIFDmodName; + namarray[1] = here->B3SOIFDname; + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "B3SOIFD: mosfet %s, model %s: Effective channel length for C-V <= 0", + namarray); + return(E_BADPARM); + } + + pParam->B3SOIFDweffCV = here->B3SOIFDw - 2.0 * pParam->B3SOIFDdwc; + if (pParam->B3SOIFDweffCV <= 0.0) + { IFuid namarray[2]; + namarray[0] = model->B3SOIFDmodName; + namarray[1] = here->B3SOIFDname; + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "B3SOIFD: mosfet %s, model %s: Effective channel width for C-V <= 0", + namarray); + return(E_BADPARM); + } + + /* Not binned - START */ + pParam->B3SOIFDat = model->B3SOIFDat; + pParam->B3SOIFDgamma1 = model->B3SOIFDgamma1; + pParam->B3SOIFDgamma2 = model->B3SOIFDgamma2; + pParam->B3SOIFDvbx = model->B3SOIFDvbx; + pParam->B3SOIFDvbm = model->B3SOIFDvbm; + pParam->B3SOIFDxt = model->B3SOIFDxt; + pParam->B3SOIFDkt1 = model->B3SOIFDkt1; + pParam->B3SOIFDkt1l = model->B3SOIFDkt1l; + pParam->B3SOIFDkt2 = model->B3SOIFDkt2; + pParam->B3SOIFDua1 = model->B3SOIFDua1; + pParam->B3SOIFDub1 = model->B3SOIFDub1; + pParam->B3SOIFDuc1 = model->B3SOIFDuc1; + pParam->B3SOIFDute = model->B3SOIFDute; + pParam->B3SOIFDprt = model->B3SOIFDprt; + /* Not binned - END */ + + /* CV model */ + pParam->B3SOIFDcgsl = model->B3SOIFDcgsl; + pParam->B3SOIFDcgdl = model->B3SOIFDcgdl; + pParam->B3SOIFDckappa = model->B3SOIFDckappa; + pParam->B3SOIFDcf = model->B3SOIFDcf; + pParam->B3SOIFDclc = model->B3SOIFDclc; + pParam->B3SOIFDcle = model->B3SOIFDcle; + + pParam->B3SOIFDabulkCVfactor = pow(1.0+(pParam->B3SOIFDclc + / pParam->B3SOIFDleff), + pParam->B3SOIFDcle); + +/* Added for binning - START */ + if (model->B3SOIFDbinUnit == 1) + { Inv_L = 1.0e-6 / pParam->B3SOIFDleff; + Inv_W = 1.0e-6 / pParam->B3SOIFDweff; + Inv_LW = 1.0e-12 / (pParam->B3SOIFDleff + * pParam->B3SOIFDweff); + } + else + { Inv_L = 1.0 / pParam->B3SOIFDleff; + Inv_W = 1.0 / pParam->B3SOIFDweff; + Inv_LW = 1.0 / (pParam->B3SOIFDleff + * pParam->B3SOIFDweff); + } + pParam->B3SOIFDnpeak = model->B3SOIFDnpeak + + model->B3SOIFDlnpeak * Inv_L + + model->B3SOIFDwnpeak * Inv_W + + model->B3SOIFDpnpeak * Inv_LW; + pParam->B3SOIFDnsub = model->B3SOIFDnsub + + model->B3SOIFDlnsub * Inv_L + + model->B3SOIFDwnsub * Inv_W + + model->B3SOIFDpnsub * Inv_LW; + pParam->B3SOIFDngate = model->B3SOIFDngate + + model->B3SOIFDlngate * Inv_L + + model->B3SOIFDwngate * Inv_W + + model->B3SOIFDpngate * Inv_LW; + pParam->B3SOIFDvth0 = model->B3SOIFDvth0 + + model->B3SOIFDlvth0 * Inv_L + + model->B3SOIFDwvth0 * Inv_W + + model->B3SOIFDpvth0 * Inv_LW; + pParam->B3SOIFDk1 = model->B3SOIFDk1 + + model->B3SOIFDlk1 * Inv_L + + model->B3SOIFDwk1 * Inv_W + + model->B3SOIFDpk1 * Inv_LW; + pParam->B3SOIFDk2 = model->B3SOIFDk2 + + model->B3SOIFDlk2 * Inv_L + + model->B3SOIFDwk2 * Inv_W + + model->B3SOIFDpk2 * Inv_LW; + pParam->B3SOIFDk3 = model->B3SOIFDk3 + + model->B3SOIFDlk3 * Inv_L + + model->B3SOIFDwk3 * Inv_W + + model->B3SOIFDpk3 * Inv_LW; + pParam->B3SOIFDk3b = model->B3SOIFDk3b + + model->B3SOIFDlk3b * Inv_L + + model->B3SOIFDwk3b * Inv_W + + model->B3SOIFDpk3b * Inv_LW; + pParam->B3SOIFDvbsa = model->B3SOIFDvbsa + + model->B3SOIFDlvbsa * Inv_L + + model->B3SOIFDwvbsa * Inv_W + + model->B3SOIFDpvbsa * Inv_LW; + pParam->B3SOIFDdelp = model->B3SOIFDdelp + + model->B3SOIFDldelp * Inv_L + + model->B3SOIFDwdelp * Inv_W + + model->B3SOIFDpdelp * Inv_LW; + pParam->B3SOIFDkb1 = model->B3SOIFDkb1 + + model->B3SOIFDlkb1 * Inv_L + + model->B3SOIFDwkb1 * Inv_W + + model->B3SOIFDpkb1 * Inv_LW; + pParam->B3SOIFDkb3 = model->B3SOIFDkb3 + + model->B3SOIFDlkb3 * Inv_L + + model->B3SOIFDwkb3 * Inv_W + + model->B3SOIFDpkb3 * Inv_LW; + pParam->B3SOIFDdvbd0 = model->B3SOIFDdvbd0 + + model->B3SOIFDldvbd0 * Inv_L + + model->B3SOIFDwdvbd0 * Inv_W + + model->B3SOIFDpdvbd0 * Inv_LW; + pParam->B3SOIFDdvbd1 = model->B3SOIFDdvbd1 + + model->B3SOIFDldvbd1 * Inv_L + + model->B3SOIFDwdvbd1 * Inv_W + + model->B3SOIFDpdvbd1 * Inv_LW; + pParam->B3SOIFDw0 = model->B3SOIFDw0 + + model->B3SOIFDlw0 * Inv_L + + model->B3SOIFDww0 * Inv_W + + model->B3SOIFDpw0 * Inv_LW; + pParam->B3SOIFDnlx = model->B3SOIFDnlx + + model->B3SOIFDlnlx * Inv_L + + model->B3SOIFDwnlx * Inv_W + + model->B3SOIFDpnlx * Inv_LW; + pParam->B3SOIFDdvt0 = model->B3SOIFDdvt0 + + model->B3SOIFDldvt0 * Inv_L + + model->B3SOIFDwdvt0 * Inv_W + + model->B3SOIFDpdvt0 * Inv_LW; + pParam->B3SOIFDdvt1 = model->B3SOIFDdvt1 + + model->B3SOIFDldvt1 * Inv_L + + model->B3SOIFDwdvt1 * Inv_W + + model->B3SOIFDpdvt1 * Inv_LW; + pParam->B3SOIFDdvt2 = model->B3SOIFDdvt2 + + model->B3SOIFDldvt2 * Inv_L + + model->B3SOIFDwdvt2 * Inv_W + + model->B3SOIFDpdvt2 * Inv_LW; + pParam->B3SOIFDdvt0w = model->B3SOIFDdvt0w + + model->B3SOIFDldvt0w * Inv_L + + model->B3SOIFDwdvt0w * Inv_W + + model->B3SOIFDpdvt0w * Inv_LW; + pParam->B3SOIFDdvt1w = model->B3SOIFDdvt1w + + model->B3SOIFDldvt1w * Inv_L + + model->B3SOIFDwdvt1w * Inv_W + + model->B3SOIFDpdvt1w * Inv_LW; + pParam->B3SOIFDdvt2w = model->B3SOIFDdvt2w + + model->B3SOIFDldvt2w * Inv_L + + model->B3SOIFDwdvt2w * Inv_W + + model->B3SOIFDpdvt2w * Inv_LW; + pParam->B3SOIFDu0 = model->B3SOIFDu0 + + model->B3SOIFDlu0 * Inv_L + + model->B3SOIFDwu0 * Inv_W + + model->B3SOIFDpu0 * Inv_LW; + pParam->B3SOIFDua = model->B3SOIFDua + + model->B3SOIFDlua * Inv_L + + model->B3SOIFDwua * Inv_W + + model->B3SOIFDpua * Inv_LW; + pParam->B3SOIFDub = model->B3SOIFDub + + model->B3SOIFDlub * Inv_L + + model->B3SOIFDwub * Inv_W + + model->B3SOIFDpub * Inv_LW; + pParam->B3SOIFDuc = model->B3SOIFDuc + + model->B3SOIFDluc * Inv_L + + model->B3SOIFDwuc * Inv_W + + model->B3SOIFDpuc * Inv_LW; + pParam->B3SOIFDvsat = model->B3SOIFDvsat + + model->B3SOIFDlvsat * Inv_L + + model->B3SOIFDwvsat * Inv_W + + model->B3SOIFDpvsat * Inv_LW; + pParam->B3SOIFDa0 = model->B3SOIFDa0 + + model->B3SOIFDla0 * Inv_L + + model->B3SOIFDwa0 * Inv_W + + model->B3SOIFDpa0 * Inv_LW; + pParam->B3SOIFDags = model->B3SOIFDags + + model->B3SOIFDlags * Inv_L + + model->B3SOIFDwags * Inv_W + + model->B3SOIFDpags * Inv_LW; + pParam->B3SOIFDb0 = model->B3SOIFDb0 + + model->B3SOIFDlb0 * Inv_L + + model->B3SOIFDwb0 * Inv_W + + model->B3SOIFDpb0 * Inv_LW; + pParam->B3SOIFDb1 = model->B3SOIFDb1 + + model->B3SOIFDlb1 * Inv_L + + model->B3SOIFDwb1 * Inv_W + + model->B3SOIFDpb1 * Inv_LW; + pParam->B3SOIFDketa = model->B3SOIFDketa + + model->B3SOIFDlketa * Inv_L + + model->B3SOIFDwketa * Inv_W + + model->B3SOIFDpketa * Inv_LW; + pParam->B3SOIFDabp = model->B3SOIFDabp + + model->B3SOIFDlabp * Inv_L + + model->B3SOIFDwabp * Inv_W + + model->B3SOIFDpabp * Inv_LW; + pParam->B3SOIFDmxc = model->B3SOIFDmxc + + model->B3SOIFDlmxc * Inv_L + + model->B3SOIFDwmxc * Inv_W + + model->B3SOIFDpmxc * Inv_LW; + pParam->B3SOIFDadice0 = model->B3SOIFDadice0 + + model->B3SOIFDladice0 * Inv_L + + model->B3SOIFDwadice0 * Inv_W + + model->B3SOIFDpadice0 * Inv_LW; + pParam->B3SOIFDa1 = model->B3SOIFDa1 + + model->B3SOIFDla1 * Inv_L + + model->B3SOIFDwa1 * Inv_W + + model->B3SOIFDpa1 * Inv_LW; + pParam->B3SOIFDa2 = model->B3SOIFDa2 + + model->B3SOIFDla2 * Inv_L + + model->B3SOIFDwa2 * Inv_W + + model->B3SOIFDpa2 * Inv_LW; + pParam->B3SOIFDrdsw = model->B3SOIFDrdsw + + model->B3SOIFDlrdsw * Inv_L + + model->B3SOIFDwrdsw * Inv_W + + model->B3SOIFDprdsw * Inv_LW; + pParam->B3SOIFDprwb = model->B3SOIFDprwb + + model->B3SOIFDlprwb * Inv_L + + model->B3SOIFDwprwb * Inv_W + + model->B3SOIFDpprwb * Inv_LW; + pParam->B3SOIFDprwg = model->B3SOIFDprwg + + model->B3SOIFDlprwg * Inv_L + + model->B3SOIFDwprwg * Inv_W + + model->B3SOIFDpprwg * Inv_LW; + pParam->B3SOIFDwr = model->B3SOIFDwr + + model->B3SOIFDlwr * Inv_L + + model->B3SOIFDwwr * Inv_W + + model->B3SOIFDpwr * Inv_LW; + pParam->B3SOIFDnfactor = model->B3SOIFDnfactor + + model->B3SOIFDlnfactor * Inv_L + + model->B3SOIFDwnfactor * Inv_W + + model->B3SOIFDpnfactor * Inv_LW; + pParam->B3SOIFDdwg = model->B3SOIFDdwg + + model->B3SOIFDldwg * Inv_L + + model->B3SOIFDwdwg * Inv_W + + model->B3SOIFDpdwg * Inv_LW; + pParam->B3SOIFDdwb = model->B3SOIFDdwb + + model->B3SOIFDldwb * Inv_L + + model->B3SOIFDwdwb * Inv_W + + model->B3SOIFDpdwb * Inv_LW; + pParam->B3SOIFDvoff = model->B3SOIFDvoff + + model->B3SOIFDlvoff * Inv_L + + model->B3SOIFDwvoff * Inv_W + + model->B3SOIFDpvoff * Inv_LW; + pParam->B3SOIFDeta0 = model->B3SOIFDeta0 + + model->B3SOIFDleta0 * Inv_L + + model->B3SOIFDweta0 * Inv_W + + model->B3SOIFDpeta0 * Inv_LW; + pParam->B3SOIFDetab = model->B3SOIFDetab + + model->B3SOIFDletab * Inv_L + + model->B3SOIFDwetab * Inv_W + + model->B3SOIFDpetab * Inv_LW; + pParam->B3SOIFDdsub = model->B3SOIFDdsub + + model->B3SOIFDldsub * Inv_L + + model->B3SOIFDwdsub * Inv_W + + model->B3SOIFDpdsub * Inv_LW; + pParam->B3SOIFDcit = model->B3SOIFDcit + + model->B3SOIFDlcit * Inv_L + + model->B3SOIFDwcit * Inv_W + + model->B3SOIFDpcit * Inv_LW; + pParam->B3SOIFDcdsc = model->B3SOIFDcdsc + + model->B3SOIFDlcdsc * Inv_L + + model->B3SOIFDwcdsc * Inv_W + + model->B3SOIFDpcdsc * Inv_LW; + pParam->B3SOIFDcdscb = model->B3SOIFDcdscb + + model->B3SOIFDlcdscb * Inv_L + + model->B3SOIFDwcdscb * Inv_W + + model->B3SOIFDpcdscb * Inv_LW; + pParam->B3SOIFDcdscd = model->B3SOIFDcdscd + + model->B3SOIFDlcdscd * Inv_L + + model->B3SOIFDwcdscd * Inv_W + + model->B3SOIFDpcdscd * Inv_LW; + pParam->B3SOIFDpclm = model->B3SOIFDpclm + + model->B3SOIFDlpclm * Inv_L + + model->B3SOIFDwpclm * Inv_W + + model->B3SOIFDppclm * Inv_LW; + pParam->B3SOIFDpdibl1 = model->B3SOIFDpdibl1 + + model->B3SOIFDlpdibl1 * Inv_L + + model->B3SOIFDwpdibl1 * Inv_W + + model->B3SOIFDppdibl1 * Inv_LW; + pParam->B3SOIFDpdibl2 = model->B3SOIFDpdibl2 + + model->B3SOIFDlpdibl2 * Inv_L + + model->B3SOIFDwpdibl2 * Inv_W + + model->B3SOIFDppdibl2 * Inv_LW; + pParam->B3SOIFDpdiblb = model->B3SOIFDpdiblb + + model->B3SOIFDlpdiblb * Inv_L + + model->B3SOIFDwpdiblb * Inv_W + + model->B3SOIFDppdiblb * Inv_LW; + pParam->B3SOIFDdrout = model->B3SOIFDdrout + + model->B3SOIFDldrout * Inv_L + + model->B3SOIFDwdrout * Inv_W + + model->B3SOIFDpdrout * Inv_LW; + pParam->B3SOIFDpvag = model->B3SOIFDpvag + + model->B3SOIFDlpvag * Inv_L + + model->B3SOIFDwpvag * Inv_W + + model->B3SOIFDppvag * Inv_LW; + pParam->B3SOIFDdelta = model->B3SOIFDdelta + + model->B3SOIFDldelta * Inv_L + + model->B3SOIFDwdelta * Inv_W + + model->B3SOIFDpdelta * Inv_LW; + pParam->B3SOIFDaii = model->B3SOIFDaii + + model->B3SOIFDlaii * Inv_L + + model->B3SOIFDwaii * Inv_W + + model->B3SOIFDpaii * Inv_LW; + pParam->B3SOIFDbii = model->B3SOIFDbii + + model->B3SOIFDlbii * Inv_L + + model->B3SOIFDwbii * Inv_W + + model->B3SOIFDpbii * Inv_LW; + pParam->B3SOIFDcii = model->B3SOIFDcii + + model->B3SOIFDlcii * Inv_L + + model->B3SOIFDwcii * Inv_W + + model->B3SOIFDpcii * Inv_LW; + pParam->B3SOIFDdii = model->B3SOIFDdii + + model->B3SOIFDldii * Inv_L + + model->B3SOIFDwdii * Inv_W + + model->B3SOIFDpdii * Inv_LW; + pParam->B3SOIFDalpha0 = model->B3SOIFDalpha0 + + model->B3SOIFDlalpha0 * Inv_L + + model->B3SOIFDwalpha0 * Inv_W + + model->B3SOIFDpalpha0 * Inv_LW; + pParam->B3SOIFDalpha1 = model->B3SOIFDalpha1 + + model->B3SOIFDlalpha1 * Inv_L + + model->B3SOIFDwalpha1 * Inv_W + + model->B3SOIFDpalpha1 * Inv_LW; + pParam->B3SOIFDbeta0 = model->B3SOIFDbeta0 + + model->B3SOIFDlbeta0 * Inv_L + + model->B3SOIFDwbeta0 * Inv_W + + model->B3SOIFDpbeta0 * Inv_LW; + pParam->B3SOIFDagidl = model->B3SOIFDagidl + + model->B3SOIFDlagidl * Inv_L + + model->B3SOIFDwagidl * Inv_W + + model->B3SOIFDpagidl * Inv_LW; + pParam->B3SOIFDbgidl = model->B3SOIFDbgidl + + model->B3SOIFDlbgidl * Inv_L + + model->B3SOIFDwbgidl * Inv_W + + model->B3SOIFDpbgidl * Inv_LW; + pParam->B3SOIFDngidl = model->B3SOIFDngidl + + model->B3SOIFDlngidl * Inv_L + + model->B3SOIFDwngidl * Inv_W + + model->B3SOIFDpngidl * Inv_LW; + pParam->B3SOIFDntun = model->B3SOIFDntun + + model->B3SOIFDlntun * Inv_L + + model->B3SOIFDwntun * Inv_W + + model->B3SOIFDpntun * Inv_LW; + pParam->B3SOIFDndiode = model->B3SOIFDndiode + + model->B3SOIFDlndiode * Inv_L + + model->B3SOIFDwndiode * Inv_W + + model->B3SOIFDpndiode * Inv_LW; + pParam->B3SOIFDisbjt = model->B3SOIFDisbjt + + model->B3SOIFDlisbjt * Inv_L + + model->B3SOIFDwisbjt * Inv_W + + model->B3SOIFDpisbjt * Inv_LW; + pParam->B3SOIFDisdif = model->B3SOIFDisdif + + model->B3SOIFDlisdif * Inv_L + + model->B3SOIFDwisdif * Inv_W + + model->B3SOIFDpisdif * Inv_LW; + pParam->B3SOIFDisrec = model->B3SOIFDisrec + + model->B3SOIFDlisrec * Inv_L + + model->B3SOIFDwisrec * Inv_W + + model->B3SOIFDpisrec * Inv_LW; + pParam->B3SOIFDistun = model->B3SOIFDistun + + model->B3SOIFDlistun * Inv_L + + model->B3SOIFDwistun * Inv_W + + model->B3SOIFDpistun * Inv_LW; + pParam->B3SOIFDedl = model->B3SOIFDedl + + model->B3SOIFDledl * Inv_L + + model->B3SOIFDwedl * Inv_W + + model->B3SOIFDpedl * Inv_LW; + pParam->B3SOIFDkbjt1 = model->B3SOIFDkbjt1 + + model->B3SOIFDlkbjt1 * Inv_L + + model->B3SOIFDwkbjt1 * Inv_W + + model->B3SOIFDpkbjt1 * Inv_LW; + /* CV model */ + pParam->B3SOIFDvsdfb = model->B3SOIFDvsdfb + + model->B3SOIFDlvsdfb * Inv_L + + model->B3SOIFDwvsdfb * Inv_W + + model->B3SOIFDpvsdfb * Inv_LW; + pParam->B3SOIFDvsdth = model->B3SOIFDvsdth + + model->B3SOIFDlvsdth * Inv_L + + model->B3SOIFDwvsdth * Inv_W + + model->B3SOIFDpvsdth * Inv_LW; +/* Added for binning - END */ + + T0 = (TRatio - 1.0); + + pParam->B3SOIFDuatemp = pParam->B3SOIFDua; /* save ua, ub, and uc for b3soifdld.c */ + pParam->B3SOIFDubtemp = pParam->B3SOIFDub; + pParam->B3SOIFDuctemp = pParam->B3SOIFDuc; + pParam->B3SOIFDrds0denom = pow(pParam->B3SOIFDweff * 1E6, pParam->B3SOIFDwr); + pParam->B3SOIFDrth = here->B3SOIFDrth0 * sqrt(model->B3SOIFDtbox + / model->B3SOIFDtsi) / pParam->B3SOIFDweff; + pParam->B3SOIFDcth = here->B3SOIFDcth0 * model->B3SOIFDtsi; + pParam->B3SOIFDrbody = model->B3SOIFDrbody * + pParam->B3SOIFDweff / pParam->B3SOIFDleff; + pParam->B3SOIFDua = pParam->B3SOIFDua + pParam->B3SOIFDua1 * T0; + pParam->B3SOIFDub = pParam->B3SOIFDub + pParam->B3SOIFDub1 * T0; + pParam->B3SOIFDuc = pParam->B3SOIFDuc + pParam->B3SOIFDuc1 * T0; + if (pParam->B3SOIFDu0 > 1.0) + pParam->B3SOIFDu0 = pParam->B3SOIFDu0 / 1.0e4; + + pParam->B3SOIFDu0temp = pParam->B3SOIFDu0 + * pow(TRatio, pParam->B3SOIFDute); + pParam->B3SOIFDvsattemp = pParam->B3SOIFDvsat - pParam->B3SOIFDat + * T0; + pParam->B3SOIFDrds0 = (pParam->B3SOIFDrdsw + pParam->B3SOIFDprt * T0) + / pow(pParam->B3SOIFDweff * 1E6, pParam->B3SOIFDwr); + + if (B3SOIFDcheckModel(model, here, ckt)) + { IFuid namarray[2]; + namarray[0] = model->B3SOIFDmodName; + namarray[1] = here->B3SOIFDname; + (*(SPfrontEnd->IFerror)) (ERR_FATAL, "Fatal error(s) detected during B3SOIFDV3 parameter checking for %s in model %s", namarray); + return(E_BADPARM); + } + + + pParam->B3SOIFDcgdo = (model->B3SOIFDcgdo + pParam->B3SOIFDcf) + * pParam->B3SOIFDweffCV; + pParam->B3SOIFDcgso = (model->B3SOIFDcgso + pParam->B3SOIFDcf) + * pParam->B3SOIFDweffCV; + + + pParam->B3SOIFDcgeo = model->B3SOIFDcgeo * pParam->B3SOIFDleffCV; + + + if (!model->B3SOIFDnpeakGiven && model->B3SOIFDgamma1Given) + { T0 = pParam->B3SOIFDgamma1 * model->B3SOIFDcox; + pParam->B3SOIFDnpeak = 3.021E22 * T0 * T0; + } + + T0 = pow(TRatio, model->B3SOIFDxbjt / pParam->B3SOIFDndiode); + T1 = pow(TRatio, model->B3SOIFDxdif / pParam->B3SOIFDndiode); + T2 = pow(TRatio, model->B3SOIFDxrec / pParam->B3SOIFDndiode / 2); + T4 = -Eg0 / pParam->B3SOIFDndiode / model->B3SOIFDvtm * (1 - TRatio); + T5 = exp(T4); + T6 = sqrt(T5); + pParam->B3SOIFDjbjt = pParam->B3SOIFDisbjt * T0 * T5; + pParam->B3SOIFDjdif = pParam->B3SOIFDisdif * T1 * T5; + pParam->B3SOIFDjrec = pParam->B3SOIFDisrec * T2 * T6; + T0 = pow(TRatio, model->B3SOIFDxtun / pParam->B3SOIFDntun); + pParam->B3SOIFDjtun = pParam->B3SOIFDistun * T0 ; + + if (pParam->B3SOIFDnsub > 0) + pParam->B3SOIFDvfbb = -model->B3SOIFDtype * model->B3SOIFDvtm * + log(pParam->B3SOIFDnpeak/ pParam->B3SOIFDnsub); + else + pParam->B3SOIFDvfbb = -model->B3SOIFDtype * model->B3SOIFDvtm * + log(-pParam->B3SOIFDnpeak* pParam->B3SOIFDnsub/ni/ni); + + if (!model->B3SOIFDvsdfbGiven) + { + if (pParam->B3SOIFDnsub > 0) + pParam->B3SOIFDvsdfb = -model->B3SOIFDtype * (model->B3SOIFDvtm*log(1e20 * + pParam->B3SOIFDnsub / ni /ni) - 0.3); + else if (pParam->B3SOIFDnsub < 0) + pParam->B3SOIFDvsdfb = -model->B3SOIFDtype * (model->B3SOIFDvtm*log(-1e20 / + pParam->B3SOIFDnsub) + 0.3); + } + + /* Phi & Gamma */ + SDphi = 2.0*model->B3SOIFDvtm*log(fabs(pParam->B3SOIFDnsub) / ni); + SDgamma = 5.753e-12 * sqrt(fabs(pParam->B3SOIFDnsub)) / model->B3SOIFDcbox; + + if (!model->B3SOIFDvsdthGiven) + { + if ( ((pParam->B3SOIFDnsub > 0) && (model->B3SOIFDtype > 0)) || + ((pParam->B3SOIFDnsub < 0) && (model->B3SOIFDtype < 0)) ) + pParam->B3SOIFDvsdth = pParam->B3SOIFDvsdfb + SDphi + + SDgamma * sqrt(SDphi); + else + pParam->B3SOIFDvsdth = pParam->B3SOIFDvsdfb - SDphi - + SDgamma * sqrt(SDphi); + } + if (!model->B3SOIFDcsdminGiven) + { + /* Cdmin */ + tmp = sqrt(2.0 * EPSSI * SDphi / (Charge_q * + fabs(pParam->B3SOIFDnsub) * 1.0e6)); + tmp1 = EPSSI / tmp; + model->B3SOIFDcsdmin = tmp1 * model->B3SOIFDcbox / + (tmp1 + model->B3SOIFDcbox); + } + + T0 = model->B3SOIFDcsdesw * log(1 + model->B3SOIFDtsi / + model->B3SOIFDtbox); + T1 = here->B3SOIFDsourcePerimeter - pParam->B3SOIFDweff; + if (T1 > 0.0) + pParam->B3SOIFDcsesw = T0 * T1; + else + pParam->B3SOIFDcsesw = 0.0; + T1 = here->B3SOIFDdrainPerimeter - pParam->B3SOIFDweff; + if (T1 > 0.0) + pParam->B3SOIFDcdesw = T0 * T1; + else + pParam->B3SOIFDcdesw = 0.0; + + pParam->B3SOIFDphi = 2.0 * model->B3SOIFDvtm + * log(pParam->B3SOIFDnpeak / ni); + + pParam->B3SOIFDsqrtPhi = sqrt(pParam->B3SOIFDphi); + pParam->B3SOIFDphis3 = pParam->B3SOIFDsqrtPhi * pParam->B3SOIFDphi; + + pParam->B3SOIFDXdep0 = sqrt(2.0 * EPSSI / (Charge_q + * pParam->B3SOIFDnpeak * 1.0e6)) + * pParam->B3SOIFDsqrtPhi; + pParam->B3SOIFDsqrtXdep0 = sqrt(pParam->B3SOIFDXdep0); + pParam->B3SOIFDlitl = sqrt(3.0 * model->B3SOIFDxj + * model->B3SOIFDtox); + pParam->B3SOIFDvbi = model->B3SOIFDvtm * log(1.0e20 + * pParam->B3SOIFDnpeak / (ni * ni)); + pParam->B3SOIFDcdep0 = sqrt(Charge_q * EPSSI + * pParam->B3SOIFDnpeak * 1.0e6 / 2.0 + / pParam->B3SOIFDphi); + + if (model->B3SOIFDk1Given || model->B3SOIFDk2Given) + { if (!model->B3SOIFDk1Given) + { fprintf(stdout, "Warning: k1 should be specified with k2.\n"); + pParam->B3SOIFDk1 = 0.53; + } + if (!model->B3SOIFDk2Given) + { fprintf(stdout, "Warning: k2 should be specified with k1.\n"); + pParam->B3SOIFDk2 = -0.0186; + } + if (model->B3SOIFDxtGiven) + fprintf(stdout, "Warning: xt is ignored because k1 or k2 is given.\n"); + if (model->B3SOIFDvbxGiven) + fprintf(stdout, "Warning: vbx is ignored because k1 or k2 is given.\n"); + if (model->B3SOIFDvbmGiven) + fprintf(stdout, "Warning: vbm is ignored because k1 or k2 is given.\n"); + if (model->B3SOIFDgamma1Given) + fprintf(stdout, "Warning: gamma1 is ignored because k1 or k2 is given.\n"); + if (model->B3SOIFDgamma2Given) + fprintf(stdout, "Warning: gamma2 is ignored because k1 or k2 is given.\n"); + } + else + { if (!model->B3SOIFDvbxGiven) + pParam->B3SOIFDvbx = pParam->B3SOIFDphi - 7.7348e-4 + * pParam->B3SOIFDnpeak + * pParam->B3SOIFDxt * pParam->B3SOIFDxt; + if (pParam->B3SOIFDvbx > 0.0) + pParam->B3SOIFDvbx = -pParam->B3SOIFDvbx; + if (pParam->B3SOIFDvbm > 0.0) + pParam->B3SOIFDvbm = -pParam->B3SOIFDvbm; + + if (!model->B3SOIFDgamma1Given) + pParam->B3SOIFDgamma1 = 5.753e-12 + * sqrt(pParam->B3SOIFDnpeak) + / model->B3SOIFDcox; + if (!model->B3SOIFDgamma2Given) + pParam->B3SOIFDgamma2 = 5.753e-12 + * sqrt(pParam->B3SOIFDnsub) + / model->B3SOIFDcox; + + T0 = pParam->B3SOIFDgamma1 - pParam->B3SOIFDgamma2; + T1 = sqrt(pParam->B3SOIFDphi - pParam->B3SOIFDvbx) + - pParam->B3SOIFDsqrtPhi; + T2 = sqrt(pParam->B3SOIFDphi * (pParam->B3SOIFDphi + - pParam->B3SOIFDvbm)) - pParam->B3SOIFDphi; + pParam->B3SOIFDk2 = T0 * T1 / (2.0 * T2 + pParam->B3SOIFDvbm); + pParam->B3SOIFDk1 = pParam->B3SOIFDgamma2 - 2.0 + * pParam->B3SOIFDk2 * sqrt(pParam->B3SOIFDphi + - pParam->B3SOIFDvbm); + } + + if (pParam->B3SOIFDk2 < 0.0) + { T0 = 0.5 * pParam->B3SOIFDk1 / pParam->B3SOIFDk2; + pParam->B3SOIFDvbsc = 0.9 * (pParam->B3SOIFDphi - T0 * T0); + if (pParam->B3SOIFDvbsc > -3.0) + pParam->B3SOIFDvbsc = -3.0; + else if (pParam->B3SOIFDvbsc < -30.0) + pParam->B3SOIFDvbsc = -30.0; + } + else + { pParam->B3SOIFDvbsc = -30.0; + } + if (pParam->B3SOIFDvbsc > pParam->B3SOIFDvbm) + pParam->B3SOIFDvbsc = pParam->B3SOIFDvbm; + + if (model->B3SOIFDvth0Given) + { pParam->B3SOIFDvfb = model->B3SOIFDtype * pParam->B3SOIFDvth0 + - pParam->B3SOIFDphi - pParam->B3SOIFDk1 + * pParam->B3SOIFDsqrtPhi; + } + else + { pParam->B3SOIFDvfb = -1.0; + pParam->B3SOIFDvth0 = model->B3SOIFDtype * (pParam->B3SOIFDvfb + + pParam->B3SOIFDphi + pParam->B3SOIFDk1 + * pParam->B3SOIFDsqrtPhi); + } + T1 = sqrt(EPSSI / EPSOX * model->B3SOIFDtox + * pParam->B3SOIFDXdep0); + T0 = exp(-0.5 * pParam->B3SOIFDdsub * pParam->B3SOIFDleff / T1); + pParam->B3SOIFDtheta0vb0 = (T0 + 2.0 * T0 * T0); + + T0 = exp(-0.5 * pParam->B3SOIFDdrout * pParam->B3SOIFDleff / T1); + T2 = (T0 + 2.0 * T0 * T0); + pParam->B3SOIFDthetaRout = pParam->B3SOIFDpdibl1 * T2 + + pParam->B3SOIFDpdibl2; + + here->B3SOIFDminIsub = 5.0e-2 * pParam->B3SOIFDweff * model->B3SOIFDtsi + * MAX(pParam->B3SOIFDisdif, pParam->B3SOIFDisrec); + } + + here->B3SOIFDcsbox = model->B3SOIFDcbox*here->B3SOIFDsourceArea; + here->B3SOIFDcsmin = model->B3SOIFDcsdmin*here->B3SOIFDsourceArea; + here->B3SOIFDcdbox = model->B3SOIFDcbox*here->B3SOIFDdrainArea; + here->B3SOIFDcdmin = model->B3SOIFDcsdmin*here->B3SOIFDdrainArea; + + if ( ((pParam->B3SOIFDnsub > 0) && (model->B3SOIFDtype > 0)) || + ((pParam->B3SOIFDnsub < 0) && (model->B3SOIFDtype < 0)) ) + { + T0 = pParam->B3SOIFDvsdth - pParam->B3SOIFDvsdfb; + pParam->B3SOIFDsdt1 = pParam->B3SOIFDvsdfb + model->B3SOIFDasd * T0; + T1 = here->B3SOIFDcsbox - here->B3SOIFDcsmin; + T2 = T1 / T0 / T0; + pParam->B3SOIFDst2 = T2 / model->B3SOIFDasd; + pParam->B3SOIFDst3 = T2 /( 1 - model->B3SOIFDasd); + here->B3SOIFDst4 = T0 * T1 * (1 + model->B3SOIFDasd) / 3 + - here->B3SOIFDcsmin * pParam->B3SOIFDvsdfb; + + T1 = here->B3SOIFDcdbox - here->B3SOIFDcdmin; + T2 = T1 / T0 / T0; + pParam->B3SOIFDdt2 = T2 / model->B3SOIFDasd; + pParam->B3SOIFDdt3 = T2 /( 1 - model->B3SOIFDasd); + here->B3SOIFDdt4 = T0 * T1 * (1 + model->B3SOIFDasd) / 3 + - here->B3SOIFDcdmin * pParam->B3SOIFDvsdfb; + } else + { + T0 = pParam->B3SOIFDvsdfb - pParam->B3SOIFDvsdth; + pParam->B3SOIFDsdt1 = pParam->B3SOIFDvsdth + model->B3SOIFDasd * T0; + T1 = here->B3SOIFDcsmin - here->B3SOIFDcsbox; + T2 = T1 / T0 / T0; + pParam->B3SOIFDst2 = T2 / model->B3SOIFDasd; + pParam->B3SOIFDst3 = T2 /( 1 - model->B3SOIFDasd); + here->B3SOIFDst4 = T0 * T1 * (1 + model->B3SOIFDasd) / 3 + - here->B3SOIFDcsbox * pParam->B3SOIFDvsdth; + + T1 = here->B3SOIFDcdmin - here->B3SOIFDcdbox; + T2 = T1 / T0 / T0; + pParam->B3SOIFDdt2 = T2 / model->B3SOIFDasd; + pParam->B3SOIFDdt3 = T2 /( 1 - model->B3SOIFDasd); + here->B3SOIFDdt4 = T0 * T1 * (1 + model->B3SOIFDasd) / 3 + - here->B3SOIFDcdbox * pParam->B3SOIFDvsdth; + } + + here->B3SOIFDphi = pParam->B3SOIFDphi; + /* process source/drain series resistance */ + here->B3SOIFDdrainConductance = model->B3SOIFDsheetResistance + * here->B3SOIFDdrainSquares; + if (here->B3SOIFDdrainConductance > 0.0) + here->B3SOIFDdrainConductance = 1.0 + / here->B3SOIFDdrainConductance; + else + here->B3SOIFDdrainConductance = 0.0; + + here->B3SOIFDsourceConductance = model->B3SOIFDsheetResistance + * here->B3SOIFDsourceSquares; + if (here->B3SOIFDsourceConductance > 0.0) + here->B3SOIFDsourceConductance = 1.0 + / here->B3SOIFDsourceConductance; + else + here->B3SOIFDsourceConductance = 0.0; + here->B3SOIFDcgso = pParam->B3SOIFDcgso; + here->B3SOIFDcgdo = pParam->B3SOIFDcgdo; + + } + } + return(OK); +} + diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdtrunc.c b/src/spicelib/devices/bsim3soi_fd/b3soifdtrunc.c new file mode 100644 index 000000000..a357f97e5 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdtrunc.c @@ -0,0 +1,52 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soifdtrunc.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "b3soifddef.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIFDtrunc(inModel,ckt,timeStep) +GENmodel *inModel; + CKTcircuit *ckt; +double *timeStep; +{ + B3SOIFDmodel *model = (B3SOIFDmodel*)inModel; + B3SOIFDinstance *here; + +#ifdef STEPDEBUG + double debugtemp; +#endif /* STEPDEBUG */ + + for (; model != NULL; model = model->B3SOIFDnextModel) + { for (here = model->B3SOIFDinstances; here != NULL; + here = here->B3SOIFDnextInstance) + { +#ifdef STEPDEBUG + debugtemp = *timeStep; +#endif /* STEPDEBUG */ + CKTterr(here->B3SOIFDqb,ckt,timeStep); + CKTterr(here->B3SOIFDqg,ckt,timeStep); + CKTterr(here->B3SOIFDqd,ckt,timeStep); +#ifdef STEPDEBUG + if(debugtemp != *timeStep) + { printf("device %s reduces step from %g to %g\n", + here->B3SOIFDname,debugtemp,*timeStep); + } +#endif /* STEPDEBUG */ + } + } + return(OK); +} + + + diff --git a/src/spicelib/devices/bsim3soi_pd/ChangeLog b/src/spicelib/devices/bsim3soi_pd/ChangeLog new file mode 100644 index 000000000..684410234 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/ChangeLog @@ -0,0 +1,4 @@ +2000-11-14 Paolo Nenzi + + * Initial release + diff --git a/src/spicelib/devices/bsim3soi_pd/Makefile.am b/src/spicelib/devices/bsim3soi_pd/Makefile.am new file mode 100644 index 000000000..23ff43e8a --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/Makefile.am @@ -0,0 +1,34 @@ +## Process this file with automake to produce Makefile.in + +pkglib_LTLIBRARIES = libbsim3soipd.la + +libbsim3soipd_la_SOURCES = \ + b3soipd.c \ + b3soipdacld.c \ + b3soipdask.c \ + b3soipdcheck.c \ + b3soipdcvtest.c \ + b3soipddel.c \ + b3soipddest.c \ + b3soipdgetic.c \ + b3soipdld.c \ + b3soipdmask.c \ + b3soipdmdel.c \ + b3soipdmpar.c \ + b3soipdnoi.c \ + b3soipdpar.c \ + b3soipdpzld.c \ + b3soipdset.c \ + b3soipdtemp.c \ + b3soipdtrunc.c \ + b3soipddef.h \ + b3soipdext.h \ + b3soipdinit.c \ + b3soipdinit.h \ + b3soipditf.h + + + +INCLUDES = -I$(top_srcdir)/src/include + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipd.c b/src/spicelib/devices/bsim3soi_pd/b3soipd.c new file mode 100644 index 000000000..7fef7faa8 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipd.c @@ -0,0 +1,730 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipd.c 98/5/01 +Modified by Pin Su and Jan Feng 99/2/15 +Modified by Pin Su 99/4/30 +Modified by Wei Jin 99/9/27 +Modified by Pin Su 00/3/1 +**********/ + + +#include "ngspice.h" +#include +#include "devdefs.h" +#include "b3soipddef.h" +#include "suffix.h" + +IFparm B3SOIPDpTable[] = { /* parameters */ + IOP ("l", B3SOIPD_L, IF_REAL, "Length"), + IOP ("w", B3SOIPD_W, IF_REAL, "Width"), + IOP ("ad", B3SOIPD_AD, IF_REAL, "Drain area"), + IOP ("as", B3SOIPD_AS, IF_REAL, "Source area"), + IOP ("pd", B3SOIPD_PD, IF_REAL, "Drain perimeter"), + IOP ("ps", B3SOIPD_PS, IF_REAL, "Source perimeter"), + IOP ("nrd", B3SOIPD_NRD, IF_REAL, "Number of squares in drain"), + IOP ("nrs", B3SOIPD_NRS, IF_REAL, "Number of squares in source"), + IOP ("off", B3SOIPD_OFF, IF_FLAG, "Device is initially off"), + IP ("ic", B3SOIPD_IC, IF_REALVEC, "Vector of DS,GS,BS initial voltages"), + OP ("gmbs", B3SOIPD_GMBS, IF_REAL, "Gmb"), + OP ("gm", B3SOIPD_GM, IF_REAL, "Gm"), + OP ("gm/ids", B3SOIPD_GMID, IF_REAL, "Gm/Ids"), + OP ("gds", B3SOIPD_GDS, IF_REAL, "Gds"), + OP ("vdsat", B3SOIPD_VDSAT, IF_REAL, "Vdsat"), + OP ("vth", B3SOIPD_VON, IF_REAL, "Vth"), + OP ("ids", B3SOIPD_CD, IF_REAL, "Ids"), + OP ("vbs", B3SOIPD_VBS, IF_REAL, "Vbs"), + OP ("vgs", B3SOIPD_VGS, IF_REAL, "Vgs"), + OP ("vds", B3SOIPD_VDS, IF_REAL, "Vds"), + OP ("ves", B3SOIPD_VES, IF_REAL, "Ves"), + IOP ("bjtoff", B3SOIPD_BJTOFF, IF_INTEGER, "BJT on/off flag"), + IOP ("debug", B3SOIPD_DEBUG, IF_INTEGER, "BJT on/off flag"), + IOP ("rth0", B3SOIPD_RTH0, IF_REAL, "Instance Thermal Resistance"), + IOP ("cth0", B3SOIPD_CTH0, IF_REAL, "Instance Thermal Capacitance"), + IOP ("nrb", B3SOIPD_NRB, IF_REAL, "Number of squares in body"), + + +/* v2.0 release */ + IOP ("nbc", B3SOIPD_NBC, IF_REAL, "Number of body contact isolation edge"), + IOP ("nseg", B3SOIPD_NSEG, IF_REAL, + "Number segments for width partitioning"), + IOP ("pdbcp", B3SOIPD_PDBCP, IF_REAL, + "Perimeter length for bc parasitics at drain side"), + IOP ("psbcp", B3SOIPD_PSBCP, IF_REAL, + "Perimeter length for bc parasitics at source side"), + IOP ("agbcp", B3SOIPD_AGBCP, IF_REAL, + "Gate to body overlap area for bc parasitics"), + IOP ("aebcp", B3SOIPD_AEBCP, IF_REAL, + "Substrate to body overlap area for bc prasitics"), + IOP ("vbsusr", B3SOIPD_VBSUSR, IF_REAL, "Vbs specified by user"), + IOP ("tnodeout", B3SOIPD_TNODEOUT, IF_FLAG, + "Flag indicating external temp node") +}; + +IFparm B3SOIPDmPTable[] = { /* model parameters */ + IOP ("capmod", B3SOIPD_MOD_CAPMOD, IF_INTEGER, + "Capacitance model selector"), + IOP ("mobmod", B3SOIPD_MOD_MOBMOD, IF_INTEGER, "Mobility model selector"), + IOP ("noimod", B3SOIPD_MOD_NOIMOD, IF_INTEGER, "Noise model selector"), + IOP ("paramchk", B3SOIPD_MOD_PARAMCHK, IF_INTEGER, + "Model parameter checking selector"), + IOP ("binunit", B3SOIPD_MOD_BINUNIT, IF_INTEGER, "Bin unit selector"), + IOP ("version", B3SOIPD_MOD_VERSION, IF_REAL, + " parameter for model version"), + IOP ("tox", B3SOIPD_MOD_TOX, IF_REAL, "Gate oxide thickness in meters"), + + IOP ("cdsc", B3SOIPD_MOD_CDSC, IF_REAL, + "Drain/Source and channel coupling capacitance"), + IOP ("cdscb", B3SOIPD_MOD_CDSCB, IF_REAL, "Body-bias dependence of cdsc"), + IOP ("cdscd", B3SOIPD_MOD_CDSCD, IF_REAL, "Drain-bias dependence of cdsc"), + IOP ("cit", B3SOIPD_MOD_CIT, IF_REAL, "Interface state capacitance"), + IOP ("nfactor", B3SOIPD_MOD_NFACTOR, IF_REAL, + "Subthreshold swing Coefficient"), + IOP ("vsat", B3SOIPD_MOD_VSAT, IF_REAL, "Saturation velocity at tnom"), + IOP ("at", B3SOIPD_MOD_AT, IF_REAL, "Temperature coefficient of vsat"), + IOP ("a0", B3SOIPD_MOD_A0, IF_REAL, + "Non-uniform depletion width effect coefficient."), + IOP ("ags", B3SOIPD_MOD_AGS, IF_REAL, "Gate bias coefficient of Abulk."), + IOP ("a1", B3SOIPD_MOD_A1, IF_REAL, "Non-saturation effect coefficient"), + IOP ("a2", B3SOIPD_MOD_A2, IF_REAL, "Non-saturation effect coefficient"), + IOP ("keta", B3SOIPD_MOD_KETA, IF_REAL, + "Body-bias coefficient of non-uniform depletion width effect."), + IOP ("nsub", B3SOIPD_MOD_NSUB, IF_REAL, + "Substrate doping concentration with polarity"), + IOP ("nch", B3SOIPD_MOD_NPEAK, IF_REAL, "Channel doping concentration"), + IOP ("ngate", B3SOIPD_MOD_NGATE, IF_REAL, "Poly-gate doping concentration"), + IOP ("gamma1", B3SOIPD_MOD_GAMMA1, IF_REAL, "Vth body coefficient"), + IOP ("gamma2", B3SOIPD_MOD_GAMMA2, IF_REAL, "Vth body coefficient"), + IOP ("vbx", B3SOIPD_MOD_VBX, IF_REAL, "Vth transition body Voltage"), + IOP ("vbm", B3SOIPD_MOD_VBM, IF_REAL, "Maximum body voltage"), + + IOP ("xt", B3SOIPD_MOD_XT, IF_REAL, "Doping depth"), + IOP ("k1", B3SOIPD_MOD_K1, IF_REAL, "Bulk effect coefficient 1"), + IOP ("kt1", B3SOIPD_MOD_KT1, IF_REAL, "Temperature coefficient of Vth"), + IOP ("kt1l", B3SOIPD_MOD_KT1L, IF_REAL, "Temperature coefficient of Vth"), + IOP ("kt2", B3SOIPD_MOD_KT2, IF_REAL, "Body-coefficient of kt1"), + IOP ("k2", B3SOIPD_MOD_K2, IF_REAL, "Bulk effect coefficient 2"), + IOP ("k3", B3SOIPD_MOD_K3, IF_REAL, "Narrow width effect coefficient"), + IOP ("k3b", B3SOIPD_MOD_K3B, IF_REAL, "Body effect coefficient of k3"), + IOP ("w0", B3SOIPD_MOD_W0, IF_REAL, "Narrow width effect parameter"), + IOP ("nlx", B3SOIPD_MOD_NLX, IF_REAL, "Lateral non-uniform doping effect"), + IOP ("dvt0", B3SOIPD_MOD_DVT0, IF_REAL, "Short channel effect coeff. 0"), + IOP ("dvt1", B3SOIPD_MOD_DVT1, IF_REAL, "Short channel effect coeff. 1"), + IOP ("dvt2", B3SOIPD_MOD_DVT2, IF_REAL, "Short channel effect coeff. 2"), + IOP ("dvt0w", B3SOIPD_MOD_DVT0W, IF_REAL, "Narrow Width coeff. 0"), + IOP ("dvt1w", B3SOIPD_MOD_DVT1W, IF_REAL, "Narrow Width effect coeff. 1"), + IOP ("dvt2w", B3SOIPD_MOD_DVT2W, IF_REAL, "Narrow Width effect coeff. 2"), + IOP ("drout", B3SOIPD_MOD_DROUT, IF_REAL, + "DIBL coefficient of output resistance"), + IOP ("dsub", B3SOIPD_MOD_DSUB, IF_REAL, + "DIBL coefficient in the subthreshold region"), + IOP ("vth0", B3SOIPD_MOD_VTH0, IF_REAL, "Threshold voltage"), + IOP ("vtho", B3SOIPD_MOD_VTH0, IF_REAL, "Threshold voltage"), + IOP ("ua", B3SOIPD_MOD_UA, IF_REAL, "Linear gate dependence of mobility"), + IOP ("ua1", B3SOIPD_MOD_UA1, IF_REAL, "Temperature coefficient of ua"), + IOP ("ub", B3SOIPD_MOD_UB, IF_REAL, + "Quadratic gate dependence of mobility"), + IOP ("ub1", B3SOIPD_MOD_UB1, IF_REAL, "Temperature coefficient of ub"), + IOP ("uc", B3SOIPD_MOD_UC, IF_REAL, "Body-bias dependence of mobility"), + IOP ("uc1", B3SOIPD_MOD_UC1, IF_REAL, "Temperature coefficient of uc"), + IOP ("u0", B3SOIPD_MOD_U0, IF_REAL, "Low-field mobility at Tnom"), + IOP ("ute", B3SOIPD_MOD_UTE, IF_REAL, + "Temperature coefficient of mobility"), + IOP ("voff", B3SOIPD_MOD_VOFF, IF_REAL, "Threshold voltage offset"), + IOP ("tnom", B3SOIPD_MOD_TNOM, IF_REAL, + "Parameter measurement temperature"), + IOP ("cgso", B3SOIPD_MOD_CGSO, IF_REAL, + "Gate-source overlap capacitance per width"), + IOP ("cgdo", B3SOIPD_MOD_CGDO, IF_REAL, + "Gate-drain overlap capacitance per width"), + IOP ("xpart", B3SOIPD_MOD_XPART, IF_REAL, "Channel charge partitioning"), + IOP ("delta", B3SOIPD_MOD_DELTA, IF_REAL, "Effective Vds parameter"), + IOP ("rsh", B3SOIPD_MOD_RSH, IF_REAL, "Source-drain sheet resistance"), + IOP ("rdsw", B3SOIPD_MOD_RDSW, IF_REAL, + "Source-drain resistance per width"), + + IOP ("prwg", B3SOIPD_MOD_PRWG, IF_REAL, + "Gate-bias effect on parasitic resistance "), + IOP ("prwb", B3SOIPD_MOD_PRWB, IF_REAL, + "Body-effect on parasitic resistance "), + + IOP ("prt", B3SOIPD_MOD_PRT, IF_REAL, + "Temperature coefficient of parasitic resistance "), + IOP ("eta0", B3SOIPD_MOD_ETA0, IF_REAL, + "Subthreshold region DIBL coefficient"), + IOP ("etab", B3SOIPD_MOD_ETAB, IF_REAL, + "Subthreshold region DIBL coefficient"), + IOP ("pclm", B3SOIPD_MOD_PCLM, IF_REAL, + "Channel length modulation Coefficient"), + IOP ("pdiblc1", B3SOIPD_MOD_PDIBL1, IF_REAL, + "Drain-induced barrier lowering coefficient"), + IOP ("pdiblc2", B3SOIPD_MOD_PDIBL2, IF_REAL, + "Drain-induced barrier lowering coefficient"), + IOP ("pdiblcb", B3SOIPD_MOD_PDIBLB, IF_REAL, + "Body-effect on drain-induced barrier lowering"), + + IOP ("pvag", B3SOIPD_MOD_PVAG, IF_REAL, + "Gate dependence of output resistance parameter"), + + IOP ("shmod", B3SOIPD_MOD_SHMOD, IF_INTEGER, "Self heating mode selector"), + IOP ("ddmod", B3SOIPD_MOD_DDMOD, IF_INTEGER, + "Dynamic depletion mode selector"), + IOP ("tbox", B3SOIPD_MOD_TBOX, IF_REAL, + "Back gate oxide thickness in meters"), + IOP ("tsi", B3SOIPD_MOD_TSI, IF_REAL, + "Silicon-on-insulator thickness in meters"), + IOP ("xj", B3SOIPD_MOD_XJ, IF_REAL, "Junction Depth"), + IOP ("rth0", B3SOIPD_MOD_RTH0, IF_REAL, "Self-heating thermal resistance"), + IOP ("cth0", B3SOIPD_MOD_CTH0, IF_REAL, "Self-heating thermal capacitance"), + IOP ("ngidl", B3SOIPD_MOD_NGIDL, IF_REAL, "GIDL first parameter"), + IOP ("agidl", B3SOIPD_MOD_AGIDL, IF_REAL, "GIDL second parameter"), + IOP ("bgidl", B3SOIPD_MOD_BGIDL, IF_REAL, "GIDL third parameter"), + IOP ("ndiode", B3SOIPD_MOD_NDIODE, IF_REAL, "Diode non-ideality factor"), + IOP ("xbjt", B3SOIPD_MOD_XBJT, IF_REAL, + "Temperature coefficient for Isbjt"), + + IOP ("xdif", B3SOIPD_MOD_XDIF, IF_REAL, + "Temperature coefficient for Isdif"), + + IOP ("xrec", B3SOIPD_MOD_XREC, IF_REAL, + "Temperature coefficient for Isrec"), + IOP ("xtun", B3SOIPD_MOD_XTUN, IF_REAL, + "Temperature coefficient for Istun"), + + IOP ("pbswg", B3SOIPD_MOD_PBSWG, IF_REAL, + "Source/drain (gate side) sidewall junction capacitance built in potential"), + IOP ("mjswg", B3SOIPD_MOD_MJSWG, IF_REAL, + "Source/drain (gate side) sidewall junction capacitance grading coefficient"), + + IOP ("cjswg", B3SOIPD_MOD_CJSWG, IF_REAL, + "Source/drain (gate side) sidewall junction capacitance per unit width"), + IOP ("lint", B3SOIPD_MOD_LINT, IF_REAL, "Length reduction parameter"), + IOP ("ll", B3SOIPD_MOD_LL, IF_REAL, "Length reduction parameter"), + IOP ("lln", B3SOIPD_MOD_LLN, IF_REAL, "Length reduction parameter"), + IOP ("lw", B3SOIPD_MOD_LW, IF_REAL, "Length reduction parameter"), + IOP ("lwn", B3SOIPD_MOD_LWN, IF_REAL, "Length reduction parameter"), + IOP ("lwl", B3SOIPD_MOD_LWL, IF_REAL, "Length reduction parameter"), + + IOP ("wr", B3SOIPD_MOD_WR, IF_REAL, "Width dependence of rds"), + IOP ("wint", B3SOIPD_MOD_WINT, IF_REAL, "Width reduction parameter"), + IOP ("dwg", B3SOIPD_MOD_DWG, IF_REAL, "Width reduction parameter"), + IOP ("dwb", B3SOIPD_MOD_DWB, IF_REAL, "Width reduction parameter"), + + IOP ("wl", B3SOIPD_MOD_WL, IF_REAL, "Width reduction parameter"), + IOP ("wln", B3SOIPD_MOD_WLN, IF_REAL, "Width reduction parameter"), + IOP ("ww", B3SOIPD_MOD_WW, IF_REAL, "Width reduction parameter"), + IOP ("wwn", B3SOIPD_MOD_WWN, IF_REAL, "Width reduction parameter"), + IOP ("wwl", B3SOIPD_MOD_WWL, IF_REAL, "Width reduction parameter"), + + IOP ("b0", B3SOIPD_MOD_B0, IF_REAL, "Abulk narrow width parameter"), + IOP ("b1", B3SOIPD_MOD_B1, IF_REAL, "Abulk narrow width parameter"), + + IOP ("cgsl", B3SOIPD_MOD_CGSL, IF_REAL, "New C-V model parameter"), + IOP ("cgdl", B3SOIPD_MOD_CGDL, IF_REAL, "New C-V model parameter"), + IOP ("ckappa", B3SOIPD_MOD_CKAPPA, IF_REAL, "New C-V model parameter"), + IOP ("cf", B3SOIPD_MOD_CF, IF_REAL, "Fringe capacitance parameter"), + IOP ("clc", B3SOIPD_MOD_CLC, IF_REAL, "Vdsat parameter for C-V model"), + IOP ("cle", B3SOIPD_MOD_CLE, IF_REAL, "Vdsat parameter for C-V model"), + IOP ("dwc", B3SOIPD_MOD_DWC, IF_REAL, "Delta W for C-V model"), + IOP ("dlc", B3SOIPD_MOD_DLC, IF_REAL, "Delta L for C-V model"), + + IOP ("alpha0", B3SOIPD_MOD_ALPHA0, IF_REAL, + "substrate current model parameter"), + + IOP ("noia", B3SOIPD_MOD_NOIA, IF_REAL, "Flicker noise parameter"), + IOP ("noib", B3SOIPD_MOD_NOIB, IF_REAL, "Flicker noise parameter"), + IOP ("noic", B3SOIPD_MOD_NOIC, IF_REAL, "Flicker noise parameter"), + IOP ("em", B3SOIPD_MOD_EM, IF_REAL, "Flicker noise parameter"), + IOP ("ef", B3SOIPD_MOD_EF, IF_REAL, "Flicker noise frequency exponent"), + IOP ("af", B3SOIPD_MOD_AF, IF_REAL, "Flicker noise exponent"), + IOP ("kf", B3SOIPD_MOD_KF, IF_REAL, "Flicker noise coefficient"), + IOP ("noif", B3SOIPD_MOD_NOIF, IF_REAL, + "Floating body excess noise ideality factor"), + + +/* v2.0 release */ + IOP ("k1w1", B3SOIPD_MOD_K1W1, IF_REAL, + "First Body effect width dependent parameter"), + IOP ("k1w2", B3SOIPD_MOD_K1W2, IF_REAL, + "Second Boby effect width dependent parameter"), + IOP ("ketas", B3SOIPD_MOD_KETAS, IF_REAL, + "Surface potential adjustment for bulk charge effect"), + IOP ("dwbc", B3SOIPD_MOD_DWBC, IF_REAL, + "Width offset for body contact isolation edge"), + IOP ("beta0", B3SOIPD_MOD_BETA0, IF_REAL, + "First Vds dependent parameter of impact ionizition current"), + IOP ("beta1", B3SOIPD_MOD_BETA1, IF_REAL, + "Second Vds dependent parameter of impact ionizition current"), + IOP ("beta2", B3SOIPD_MOD_BETA2, IF_REAL, + "Third Vds dependent parameter of impact ionizition current"), + IOP ("vdsatii0", B3SOIPD_MOD_VDSATII0, IF_REAL, + "Nominal drain saturation voltage at threshold for impact ionizition current"), + IOP ("tii", B3SOIPD_MOD_TII, IF_REAL, + "Temperature dependent parameter for impact ionizition"), + IOP ("lii", B3SOIPD_MOD_LII, IF_REAL, + "Channel length dependent parameter at threshold for impact ionizition current"), + IOP ("sii0", B3SOIPD_MOD_SII0, IF_REAL, + "First Vgs dependent parameter for impact ionizition current"), + IOP ("sii1", B3SOIPD_MOD_SII1, IF_REAL, + "Second Vgs dependent parameter for impact ionizition current"), + IOP ("sii2", B3SOIPD_MOD_SII2, IF_REAL, + "Third Vgs dependent parameter for impact ionizition current"), + IOP ("siid", B3SOIPD_MOD_SIID, IF_REAL, + "Vds dependent parameter of drain saturation voltage for impact ionizition current"), + IOP ("fbjtii", B3SOIPD_MOD_FBJTII, IF_REAL, + "Fraction of bipolar current affecting the impact ionization"), + IOP ("esatii", B3SOIPD_MOD_ESATII, IF_REAL, + "Saturation electric field for impact ionization"), + IOP ("ntun", B3SOIPD_MOD_NTUN, IF_REAL, + "Reverse tunneling non-ideality factor"), + IOP ("nrecf0", B3SOIPD_MOD_NRECF0, IF_REAL, + "Recombination non-ideality factor at forward bias"), + IOP ("nrecr0", B3SOIPD_MOD_NRECR0, IF_REAL, + "Recombination non-ideality factor at reversed bias"), + IOP ("isbjt", B3SOIPD_MOD_ISBJT, IF_REAL, + "BJT injection saturation current"), + IOP ("isdif", B3SOIPD_MOD_ISDIF, IF_REAL, + "Body to source/drain injection saturation current"), + IOP ("isrec", B3SOIPD_MOD_ISREC, IF_REAL, + "Recombination in depletion saturation current"), + IOP ("istun", B3SOIPD_MOD_ISTUN, IF_REAL, + "Reverse tunneling saturation current"), + IOP ("ln", B3SOIPD_MOD_LN, IF_REAL, "Electron/hole diffusion length"), + IOP ("vrec0", B3SOIPD_MOD_VREC0, IF_REAL, + "Voltage dependent parameter for recombination current"), + IOP ("vtun0", B3SOIPD_MOD_VTUN0, IF_REAL, + "Voltage dependent parameter for tunneling current"), + IOP ("nbjt", B3SOIPD_MOD_NBJT, IF_REAL, + "Power coefficient of channel length dependency for bipolar current"), + IOP ("lbjt0", B3SOIPD_MOD_LBJT0, IF_REAL, + "Refferenc channel length for bipolar cuurent"), + IOP ("ldif0", B3SOIPD_MOD_LDIF0, IF_REAL, + "Channel-length dependency coefficient of diffusion cap"), + IOP ("vabjt", B3SOIPD_MOD_VABJT, IF_REAL, + "Early voltage for bipolar current"), + IOP ("aely", B3SOIPD_MOD_AELY, IF_REAL, + "Channel length dependency of early voltage for bipolar cuurent"), + IOP ("ahli", B3SOIPD_MOD_AHLI, IF_REAL, + "High level injection parameter for bipolar current"), + IOP ("rbody", B3SOIPD_MOD_RBODY, IF_REAL, + "Intrinsic body contact sheet resistance"), + IOP ("rbsh", B3SOIPD_MOD_RBSH, IF_REAL, + "Extrinsic body contact sheet resistance"), + IOP ("cgeo", B3SOIPD_MOD_CGEO, IF_REAL, + "Gate substrate overlap capacitance per unit channel length"), + IOP ("tt", B3SOIPD_MOD_TT, IF_REAL, + "Diffusion capacitance transit time coefficient"), + IOP ("ndif", B3SOIPD_MOD_NDIF, IF_REAL, + "Power coefficient of channel length dependency for diffusion capacitance"), + IOP ("vsdfb", B3SOIPD_MOD_VSDFB, IF_REAL, + "Source/drain bottom diffusion capacitance flatband voltage"), + IOP ("vsdth", B3SOIPD_MOD_VSDTH, IF_REAL, + "Source/drain bottom diffusion capacitance threshold voltage"), + IOP ("csdmin", B3SOIPD_MOD_CSDMIN, IF_REAL, + "Source/drain bottom diffusion minimum capacitance"), + IOP ("asd", B3SOIPD_MOD_ASD, IF_REAL, + "Source/drain bottom diffusion smoothing parameter"), + IOP ("csdesw", B3SOIPD_MOD_CSDESW, IF_REAL, + "Source/drain sidewall fringing capacitance per unit length"), + IOP ("ntrecf", B3SOIPD_MOD_NTRECF, IF_REAL, + "Temperature coefficient for Nrecf"), + IOP ("ntrecr", B3SOIPD_MOD_NTRECR, IF_REAL, + "Temperature coefficient for Nrecr"), + IOP ("dlcb", B3SOIPD_MOD_DLCB, IF_REAL, + "Length offset fitting parameter for body charge"), + IOP ("fbody", B3SOIPD_MOD_FBODY, IF_REAL, "Scaling factor for body charge"), + IOP ("tcjswg", B3SOIPD_MOD_TCJSWG, IF_REAL, + "Temperature coefficient of Cjswg"), + IOP ("tpbswg", B3SOIPD_MOD_TPBSWG, IF_REAL, + "Temperature coefficient of Pbswg"), + IOP ("acde", B3SOIPD_MOD_ACDE, IF_REAL, + "Exponential coefficient for charge thickness in capMod=3 for accumulation and depletion regions"), + IOP ("moin", B3SOIPD_MOD_MOIN, IF_REAL, + "Coefficient for the gate-bias dependent surface potential"), + IOP ("delvt", B3SOIPD_MOD_DELVT, IF_REAL, + "Threshold voltage adjust for CV"), + IOP ("kb1", B3SOIPD_MOD_KB1, IF_REAL, + "Coefficient of Vbs0 dependency on Ves"), + IOP ("dlbg", B3SOIPD_MOD_DLBG, IF_REAL, + "Length offset fitting parameter for backgate charge"), + + +/* v2.2 release */ + IOP ("igmod", B3SOIPD_MOD_IGMOD, IF_INTEGER, "gate current model selector"), + IOP ("toxqm", B3SOIPD_MOD_TOXQM, IF_REAL, + "effective oxide thickness considering quantum effect"), + IOP ("wth0", B3SOIPD_MOD_WTH0, IF_REAL, + "Minimum width for thermal resistance calculation"), + IOP ("rhalo", B3SOIPD_MOD_RHALO, IF_REAL, "body halo sheet resistance"), + IOP ("ntox", B3SOIPD_MOD_NTOX, IF_REAL, "power term of gate current"), + IOP ("toxref", B3SOIPD_MOD_TOXREF, IF_REAL, "target oxide thickness"), + IOP ("ebg", B3SOIPD_MOD_EBG, IF_REAL, + "effective bandgap in gate current calcula."), + IOP ("nevb", B3SOIPD_MOD_NEVB, IF_REAL, + "valence-band electron non-ideality factor"), + IOP ("alphagb1", B3SOIPD_MOD_ALPHAGB1, IF_REAL, + "First Vox dependent parameter for gate curent in inversion"), + IOP ("betagb1", B3SOIPD_MOD_BETAGB1, IF_REAL, + "Second Vox dependent parameter for gate currnt in inversion"), + IOP ("vgb1", B3SOIPD_MOD_VGB1, IF_REAL, + "Third Vox dependent parameter for gate current in inversion"), + IOP ("necb", B3SOIPD_MOD_NECB, IF_REAL, + "conduction-band electron non-ideality factor"), + IOP ("alphagb2", B3SOIPD_MOD_ALPHAGB2, IF_REAL, + "First Vox dependent parameter for gate current in accumulation"), + IOP ("betagb2", B3SOIPD_MOD_BETAGB2, IF_REAL, + "Second Vox dependent parameter for gate current in accumulation"), + IOP ("vgb2", B3SOIPD_MOD_VGB2, IF_REAL, + "Third Vox dependent parameter for gate current in accumulation"), + IOP ("voxh", B3SOIPD_MOD_VOXH, IF_REAL, + "the limit of Vox in gate current calculation"), + IOP ("deltavox", B3SOIPD_MOD_DELTAVOX, IF_REAL, + "the smoothing parameter in the Vox smoothing function"), + + +/* Added for binning - START */ +/* Length Dependence */ + IOP ("lnch", B3SOIPD_MOD_LNPEAK, IF_REAL, "Length dependence of nch"), + IOP ("lnsub", B3SOIPD_MOD_LNSUB, IF_REAL, "Length dependence of nsub"), + IOP ("lngate", B3SOIPD_MOD_LNGATE, IF_REAL, "Length dependence of ngate"), + IOP ("lvth0", B3SOIPD_MOD_LVTH0, IF_REAL, "Length dependence of vto"), + IOP ("lk1", B3SOIPD_MOD_LK1, IF_REAL, "Length dependence of k1"), + IOP ("lk1w1", B3SOIPD_MOD_LK1W1, IF_REAL, "Length dependence of k1w1"), + IOP ("lk1w2", B3SOIPD_MOD_LK1W2, IF_REAL, "Length dependence of k1w2"), + IOP ("lk2", B3SOIPD_MOD_LK2, IF_REAL, "Length dependence of k2"), + IOP ("lk3", B3SOIPD_MOD_LK3, IF_REAL, "Length dependence of k3"), + IOP ("lk3b", B3SOIPD_MOD_LK3B, IF_REAL, "Length dependence of k3b"), + IOP ("lkb1", B3SOIPD_MOD_LKB1, IF_REAL, "Length dependence of kb1"), + IOP ("lw0", B3SOIPD_MOD_LW0, IF_REAL, "Length dependence of w0"), + IOP ("lnlx", B3SOIPD_MOD_LNLX, IF_REAL, "Length dependence of nlx"), + IOP ("ldvt0", B3SOIPD_MOD_LDVT0, IF_REAL, "Length dependence of dvt0"), + IOP ("ldvt1", B3SOIPD_MOD_LDVT1, IF_REAL, "Length dependence of dvt1"), + IOP ("ldvt2", B3SOIPD_MOD_LDVT2, IF_REAL, "Length dependence of dvt2"), + IOP ("ldvt0w", B3SOIPD_MOD_LDVT0W, IF_REAL, "Length dependence of dvt0w"), + IOP ("ldvt1w", B3SOIPD_MOD_LDVT1W, IF_REAL, "Length dependence of dvt1w"), + IOP ("ldvt2w", B3SOIPD_MOD_LDVT2W, IF_REAL, "Length dependence of dvt2w"), + IOP ("lu0", B3SOIPD_MOD_LU0, IF_REAL, "Length dependence of u0"), + IOP ("lua", B3SOIPD_MOD_LUA, IF_REAL, "Length dependence of ua"), + IOP ("lub", B3SOIPD_MOD_LUB, IF_REAL, "Length dependence of ub"), + IOP ("luc", B3SOIPD_MOD_LUC, IF_REAL, "Length dependence of uc"), + IOP ("lvsat", B3SOIPD_MOD_LVSAT, IF_REAL, "Length dependence of vsat"), + IOP ("la0", B3SOIPD_MOD_LA0, IF_REAL, "Length dependence of a0"), + IOP ("lags", B3SOIPD_MOD_LAGS, IF_REAL, "Length dependence of ags"), + IOP ("lb0", B3SOIPD_MOD_LB0, IF_REAL, "Length dependence of b0"), + IOP ("lb1", B3SOIPD_MOD_LB1, IF_REAL, "Length dependence of b1"), + IOP ("lketa", B3SOIPD_MOD_LKETA, IF_REAL, "Length dependence of keta"), + IOP ("lketas", B3SOIPD_MOD_LKETAS, IF_REAL, "Length dependence of ketas"), + IOP ("la1", B3SOIPD_MOD_LA1, IF_REAL, "Length dependence of a1"), + IOP ("la2", B3SOIPD_MOD_LA2, IF_REAL, "Length dependence of a2"), + IOP ("lrdsw", B3SOIPD_MOD_LRDSW, IF_REAL, "Length dependence of rdsw "), + IOP ("lprwb", B3SOIPD_MOD_LPRWB, IF_REAL, "Length dependence of prwb "), + IOP ("lprwg", B3SOIPD_MOD_LPRWG, IF_REAL, "Length dependence of prwg "), + IOP ("lwr", B3SOIPD_MOD_LWR, IF_REAL, "Length dependence of wr"), + IOP ("lnfactor", B3SOIPD_MOD_LNFACTOR, IF_REAL, + "Length dependence of nfactor"), + IOP ("ldwg", B3SOIPD_MOD_LDWG, IF_REAL, "Length dependence of dwg"), + IOP ("ldwb", B3SOIPD_MOD_LDWB, IF_REAL, "Length dependence of dwb"), + IOP ("lvoff", B3SOIPD_MOD_LVOFF, IF_REAL, "Length dependence of voff"), + IOP ("leta0", B3SOIPD_MOD_LETA0, IF_REAL, "Length dependence of eta0"), + IOP ("letab", B3SOIPD_MOD_LETAB, IF_REAL, "Length dependence of etab"), + IOP ("ldsub", B3SOIPD_MOD_LDSUB, IF_REAL, "Length dependence of dsub"), + IOP ("lcit", B3SOIPD_MOD_LCIT, IF_REAL, "Length dependence of cit"), + IOP ("lcdsc", B3SOIPD_MOD_LCDSC, IF_REAL, "Length dependence of cdsc"), + IOP ("lcdscb", B3SOIPD_MOD_LCDSCB, IF_REAL, "Length dependence of cdscb"), + IOP ("lcdscd", B3SOIPD_MOD_LCDSCD, IF_REAL, "Length dependence of cdscd"), + IOP ("lpclm", B3SOIPD_MOD_LPCLM, IF_REAL, "Length dependence of pclm"), + IOP ("lpdiblc1", B3SOIPD_MOD_LPDIBL1, IF_REAL, + "Length dependence of pdiblc1"), + IOP ("lpdiblc2", B3SOIPD_MOD_LPDIBL2, IF_REAL, + "Length dependence of pdiblc2"), + IOP ("lpdiblcb", B3SOIPD_MOD_LPDIBLB, IF_REAL, + "Length dependence of pdiblcb"), + IOP ("ldrout", B3SOIPD_MOD_LDROUT, IF_REAL, "Length dependence of drout"), + IOP ("lpvag", B3SOIPD_MOD_LPVAG, IF_REAL, "Length dependence of pvag"), + IOP ("ldelta", B3SOIPD_MOD_LDELTA, IF_REAL, "Length dependence of delta"), + IOP ("lalpha0", B3SOIPD_MOD_LALPHA0, IF_REAL, + "Length dependence of alpha0"), + IOP ("lfbjtii", B3SOIPD_MOD_LFBJTII, IF_REAL, + "Length dependence of fbjtii"), + IOP ("lbeta0", B3SOIPD_MOD_LBETA0, IF_REAL, "Length dependence of beta0"), + IOP ("lbeta1", B3SOIPD_MOD_LBETA1, IF_REAL, "Length dependence of beta1"), + IOP ("lbeta2", B3SOIPD_MOD_LBETA2, IF_REAL, "Length dependence of beta2"), + IOP ("lvdsatii0", B3SOIPD_MOD_LVDSATII0, IF_REAL, + "Length dependence of vdsatii0"), + IOP ("llii", B3SOIPD_MOD_LLII, IF_REAL, "Length dependence of lii"), + IOP ("lesatii", B3SOIPD_MOD_LESATII, IF_REAL, + "Length dependence of esatii"), + IOP ("lsii0", B3SOIPD_MOD_LSII0, IF_REAL, "Length dependence of sii0"), + IOP ("lsii1", B3SOIPD_MOD_LSII1, IF_REAL, "Length dependence of sii1"), + IOP ("lsii2", B3SOIPD_MOD_LSII2, IF_REAL, "Length dependence of sii2"), + IOP ("lsiid", B3SOIPD_MOD_LSIID, IF_REAL, "Length dependence of siid"), + IOP ("lagidl", B3SOIPD_MOD_LAGIDL, IF_REAL, "Length dependence of agidl"), + IOP ("lbgidl", B3SOIPD_MOD_LBGIDL, IF_REAL, "Length dependence of bgidl"), + IOP ("lngidl", B3SOIPD_MOD_LNGIDL, IF_REAL, "Length dependence of ngidl"), + IOP ("lntun", B3SOIPD_MOD_LNTUN, IF_REAL, "Length dependence of ntun"), + IOP ("lndiode", B3SOIPD_MOD_LNDIODE, IF_REAL, + "Length dependence of ndiode"), + IOP ("lnrecf0", B3SOIPD_MOD_LNRECF0, IF_REAL, + "Length dependence of nrecf0"), + IOP ("lnrecr0", B3SOIPD_MOD_LNRECR0, IF_REAL, + "Length dependence of nrecr0"), + IOP ("lisbjt", B3SOIPD_MOD_LISBJT, IF_REAL, "Length dependence of isbjt"), + IOP ("lisdif", B3SOIPD_MOD_LISDIF, IF_REAL, "Length dependence of isdif"), + IOP ("lisrec", B3SOIPD_MOD_LISREC, IF_REAL, "Length dependence of isrec"), + IOP ("listun", B3SOIPD_MOD_LISTUN, IF_REAL, "Length dependence of istun"), + IOP ("lvrec0", B3SOIPD_MOD_LVREC0, IF_REAL, "Length dependence of vrec0"), + IOP ("lvtun0", B3SOIPD_MOD_LVTUN0, IF_REAL, "Length dependence of vtun0"), + IOP ("lnbjt", B3SOIPD_MOD_LNBJT, IF_REAL, "Length dependence of nbjt"), + IOP ("llbjt0", B3SOIPD_MOD_LLBJT0, IF_REAL, "Length dependence of lbjt0"), + IOP ("lvabjt", B3SOIPD_MOD_LVABJT, IF_REAL, "Length dependence of vabjt"), + IOP ("laely", B3SOIPD_MOD_LAELY, IF_REAL, "Length dependence of aely"), + IOP ("lahli", B3SOIPD_MOD_LAHLI, IF_REAL, "Length dependence of ahli"), + IOP ("lvsdfb", B3SOIPD_MOD_LVSDFB, IF_REAL, "Length dependence of vsdfb"), + IOP ("lvsdth", B3SOIPD_MOD_LVSDTH, IF_REAL, "Length dependence of vsdth"), + IOP ("ldelvt", B3SOIPD_MOD_LDELVT, IF_REAL, "Length dependence of delvt"), + IOP ("lacde", B3SOIPD_MOD_LACDE, IF_REAL, "Length dependence of acde"), + IOP ("lmoin", B3SOIPD_MOD_LMOIN, IF_REAL, "Length dependence of amoin"), +/* Width Dependence */ + IOP ("wnch", B3SOIPD_MOD_WNPEAK, IF_REAL, "Width dependence of nch"), + IOP ("wnsub", B3SOIPD_MOD_WNSUB, IF_REAL, "Width dependence of nsub"), + IOP ("wngate", B3SOIPD_MOD_WNGATE, IF_REAL, "Width dependence of ngate"), + IOP ("wvth0", B3SOIPD_MOD_WVTH0, IF_REAL, "Width dependence of vto"), + IOP ("wk1", B3SOIPD_MOD_WK1, IF_REAL, "Width dependence of k1"), + IOP ("wk1w1", B3SOIPD_MOD_WK1W1, IF_REAL, "Width dependence of k1w1"), + IOP ("wk1w2", B3SOIPD_MOD_WK1W2, IF_REAL, "Width dependence of k1w2"), + IOP ("wk2", B3SOIPD_MOD_WK2, IF_REAL, "Width dependence of k2"), + IOP ("wk3", B3SOIPD_MOD_WK3, IF_REAL, "Width dependence of k3"), + IOP ("wk3b", B3SOIPD_MOD_WK3B, IF_REAL, "Width dependence of k3b"), + IOP ("wkb1", B3SOIPD_MOD_WKB1, IF_REAL, "Width dependence of kb1"), + IOP ("ww0", B3SOIPD_MOD_WW0, IF_REAL, "Width dependence of w0"), + IOP ("wnlx", B3SOIPD_MOD_WNLX, IF_REAL, "Width dependence of nlx"), + IOP ("wdvt0", B3SOIPD_MOD_WDVT0, IF_REAL, "Width dependence of dvt0"), + IOP ("wdvt1", B3SOIPD_MOD_WDVT1, IF_REAL, "Width dependence of dvt1"), + IOP ("wdvt2", B3SOIPD_MOD_WDVT2, IF_REAL, "Width dependence of dvt2"), + IOP ("wdvt0w", B3SOIPD_MOD_WDVT0W, IF_REAL, "Width dependence of dvt0w"), + IOP ("wdvt1w", B3SOIPD_MOD_WDVT1W, IF_REAL, "Width dependence of dvt1w"), + IOP ("wdvt2w", B3SOIPD_MOD_WDVT2W, IF_REAL, "Width dependence of dvt2w"), + IOP ("wu0", B3SOIPD_MOD_WU0, IF_REAL, "Width dependence of u0"), + IOP ("wua", B3SOIPD_MOD_WUA, IF_REAL, "Width dependence of ua"), + IOP ("wub", B3SOIPD_MOD_WUB, IF_REAL, "Width dependence of ub"), + IOP ("wuc", B3SOIPD_MOD_WUC, IF_REAL, "Width dependence of uc"), + IOP ("wvsat", B3SOIPD_MOD_WVSAT, IF_REAL, "Width dependence of vsat"), + IOP ("wa0", B3SOIPD_MOD_WA0, IF_REAL, "Width dependence of a0"), + IOP ("wags", B3SOIPD_MOD_WAGS, IF_REAL, "Width dependence of ags"), + IOP ("wb0", B3SOIPD_MOD_WB0, IF_REAL, "Width dependence of b0"), + IOP ("wb1", B3SOIPD_MOD_WB1, IF_REAL, "Width dependence of b1"), + IOP ("wketa", B3SOIPD_MOD_WKETA, IF_REAL, "Width dependence of keta"), + IOP ("wketas", B3SOIPD_MOD_WKETAS, IF_REAL, "Width dependence of ketas"), + IOP ("wa1", B3SOIPD_MOD_WA1, IF_REAL, "Width dependence of a1"), + IOP ("wa2", B3SOIPD_MOD_WA2, IF_REAL, "Width dependence of a2"), + IOP ("wrdsw", B3SOIPD_MOD_WRDSW, IF_REAL, "Width dependence of rdsw "), + IOP ("wprwb", B3SOIPD_MOD_WPRWB, IF_REAL, "Width dependence of prwb "), + IOP ("wprwg", B3SOIPD_MOD_WPRWG, IF_REAL, "Width dependence of prwg "), + IOP ("wwr", B3SOIPD_MOD_WWR, IF_REAL, "Width dependence of wr"), + IOP ("wnfactor", B3SOIPD_MOD_WNFACTOR, IF_REAL, + "Width dependence of nfactor"), + IOP ("wdwg", B3SOIPD_MOD_WDWG, IF_REAL, "Width dependence of dwg"), + IOP ("wdwb", B3SOIPD_MOD_WDWB, IF_REAL, "Width dependence of dwb"), + IOP ("wvoff", B3SOIPD_MOD_WVOFF, IF_REAL, "Width dependence of voff"), + IOP ("weta0", B3SOIPD_MOD_WETA0, IF_REAL, "Width dependence of eta0"), + IOP ("wetab", B3SOIPD_MOD_WETAB, IF_REAL, "Width dependence of etab"), + IOP ("wdsub", B3SOIPD_MOD_WDSUB, IF_REAL, "Width dependence of dsub"), + IOP ("wcit", B3SOIPD_MOD_WCIT, IF_REAL, "Width dependence of cit"), + IOP ("wcdsc", B3SOIPD_MOD_WCDSC, IF_REAL, "Width dependence of cdsc"), + IOP ("wcdscb", B3SOIPD_MOD_WCDSCB, IF_REAL, "Width dependence of cdscb"), + IOP ("wcdscd", B3SOIPD_MOD_WCDSCD, IF_REAL, "Width dependence of cdscd"), + IOP ("wpclm", B3SOIPD_MOD_WPCLM, IF_REAL, "Width dependence of pclm"), + IOP ("wpdiblc1", B3SOIPD_MOD_WPDIBL1, IF_REAL, + "Width dependence of pdiblc1"), + IOP ("wpdiblc2", B3SOIPD_MOD_WPDIBL2, IF_REAL, + "Width dependence of pdiblc2"), + IOP ("wpdiblcb", B3SOIPD_MOD_WPDIBLB, IF_REAL, + "Width dependence of pdiblcb"), + IOP ("wdrout", B3SOIPD_MOD_WDROUT, IF_REAL, "Width dependence of drout"), + IOP ("wpvag", B3SOIPD_MOD_WPVAG, IF_REAL, "Width dependence of pvag"), + IOP ("wdelta", B3SOIPD_MOD_WDELTA, IF_REAL, "Width dependence of delta"), + IOP ("walpha0", B3SOIPD_MOD_WALPHA0, IF_REAL, "Width dependence of alpha0"), + IOP ("wfbjtii", B3SOIPD_MOD_WFBJTII, IF_REAL, "Width dependence of fbjtii"), + IOP ("wbeta0", B3SOIPD_MOD_WBETA0, IF_REAL, "Width dependence of beta0"), + IOP ("wbeta1", B3SOIPD_MOD_WBETA1, IF_REAL, "Width dependence of beta1"), + IOP ("wbeta2", B3SOIPD_MOD_WBETA2, IF_REAL, "Width dependence of beta2"), + IOP ("wvdsatii0", B3SOIPD_MOD_WVDSATII0, IF_REAL, + "Width dependence of vdsatii0"), + IOP ("wlii", B3SOIPD_MOD_WLII, IF_REAL, "Width dependence of lii"), + IOP ("wesatii", B3SOIPD_MOD_WESATII, IF_REAL, "Width dependence of esatii"), + IOP ("wsii0", B3SOIPD_MOD_WSII0, IF_REAL, "Width dependence of sii0"), + IOP ("wsii1", B3SOIPD_MOD_WSII1, IF_REAL, "Width dependence of sii1"), + IOP ("wsii2", B3SOIPD_MOD_WSII2, IF_REAL, "Width dependence of sii2"), + IOP ("wsiid", B3SOIPD_MOD_WSIID, IF_REAL, "Width dependence of siid"), + IOP ("wagidl", B3SOIPD_MOD_WAGIDL, IF_REAL, "Width dependence of agidl"), + IOP ("wbgidl", B3SOIPD_MOD_WBGIDL, IF_REAL, "Width dependence of bgidl"), + IOP ("wngidl", B3SOIPD_MOD_WNGIDL, IF_REAL, "Width dependence of ngidl"), + IOP ("wntun", B3SOIPD_MOD_WNTUN, IF_REAL, "Width dependence of ntun"), + IOP ("wndiode", B3SOIPD_MOD_WNDIODE, IF_REAL, "Width dependence of ndiode"), + IOP ("wnrecf0", B3SOIPD_MOD_WNRECF0, IF_REAL, "Width dependence of nrecf0"), + IOP ("wnrecr0", B3SOIPD_MOD_WNRECR0, IF_REAL, "Width dependence of nrecr0"), + IOP ("wisbjt", B3SOIPD_MOD_WISBJT, IF_REAL, "Width dependence of isbjt"), + IOP ("wisdif", B3SOIPD_MOD_WISDIF, IF_REAL, "Width dependence of isdif"), + IOP ("wisrec", B3SOIPD_MOD_WISREC, IF_REAL, "Width dependence of isrec"), + IOP ("wistun", B3SOIPD_MOD_WISTUN, IF_REAL, "Width dependence of istun"), + IOP ("wvrec0", B3SOIPD_MOD_WVREC0, IF_REAL, "Width dependence of vrec0"), + IOP ("wvtun0", B3SOIPD_MOD_WVTUN0, IF_REAL, "Width dependence of vtun0"), + IOP ("wnbjt", B3SOIPD_MOD_WNBJT, IF_REAL, "Width dependence of nbjt"), + IOP ("wlbjt0", B3SOIPD_MOD_WLBJT0, IF_REAL, "Width dependence of lbjt0"), + IOP ("wvabjt", B3SOIPD_MOD_WVABJT, IF_REAL, "Width dependence of vabjt"), + IOP ("waely", B3SOIPD_MOD_WAELY, IF_REAL, "Width dependence of aely"), + IOP ("wahli", B3SOIPD_MOD_WAHLI, IF_REAL, "Width dependence of ahli"), + IOP ("wvsdfb", B3SOIPD_MOD_WVSDFB, IF_REAL, "Width dependence of vsdfb"), + IOP ("wvsdth", B3SOIPD_MOD_WVSDTH, IF_REAL, "Width dependence of vsdth"), + IOP ("wdelvt", B3SOIPD_MOD_WDELVT, IF_REAL, "Width dependence of delvt"), + IOP ("wacde", B3SOIPD_MOD_WACDE, IF_REAL, "Width dependence of acde"), + IOP ("wmoin", B3SOIPD_MOD_WMOIN, IF_REAL, "Width dependence of amoin"), +/* Cross-term Dependence */ + IOP ("pnch", B3SOIPD_MOD_PNPEAK, IF_REAL, "Cross-term dependence of nch"), + IOP ("pnsub", B3SOIPD_MOD_PNSUB, IF_REAL, "Cross-term dependence of nsub"), + IOP ("pngate", B3SOIPD_MOD_PNGATE, IF_REAL, + "Cross-term dependence of ngate"), + IOP ("pvth0", B3SOIPD_MOD_PVTH0, IF_REAL, "Cross-term dependence of vto"), + IOP ("pk1", B3SOIPD_MOD_PK1, IF_REAL, "Cross-term dependence of k1"), + IOP ("pk1w1", B3SOIPD_MOD_PK1W1, IF_REAL, "Cross-term dependence of k1w1"), + IOP ("pk1w2", B3SOIPD_MOD_PK1W2, IF_REAL, "Cross-term dependence of k1w2"), + IOP ("pk2", B3SOIPD_MOD_PK2, IF_REAL, "Cross-term dependence of k2"), + IOP ("pk3", B3SOIPD_MOD_PK3, IF_REAL, "Cross-term dependence of k3"), + IOP ("pk3b", B3SOIPD_MOD_PK3B, IF_REAL, "Cross-term dependence of k3b"), + IOP ("pkb1", B3SOIPD_MOD_PKB1, IF_REAL, "Cross-term dependence of kb1"), + IOP ("pw0", B3SOIPD_MOD_PW0, IF_REAL, "Cross-term dependence of w0"), + IOP ("pnlx", B3SOIPD_MOD_PNLX, IF_REAL, "Cross-term dependence of nlx"), + IOP ("pdvt0", B3SOIPD_MOD_PDVT0, IF_REAL, "Cross-term dependence of dvt0"), + IOP ("pdvt1", B3SOIPD_MOD_PDVT1, IF_REAL, "Cross-term dependence of dvt1"), + IOP ("pdvt2", B3SOIPD_MOD_PDVT2, IF_REAL, "Cross-term dependence of dvt2"), + IOP ("pdvt0w", B3SOIPD_MOD_PDVT0W, IF_REAL, + "Cross-term dependence of dvt0w"), + IOP ("pdvt1w", B3SOIPD_MOD_PDVT1W, IF_REAL, + "Cross-term dependence of dvt1w"), + IOP ("pdvt2w", B3SOIPD_MOD_PDVT2W, IF_REAL, + "Cross-term dependence of dvt2w"), + IOP ("pu0", B3SOIPD_MOD_PU0, IF_REAL, "Cross-term dependence of u0"), + IOP ("pua", B3SOIPD_MOD_PUA, IF_REAL, "Cross-term dependence of ua"), + IOP ("pub", B3SOIPD_MOD_PUB, IF_REAL, "Cross-term dependence of ub"), + IOP ("puc", B3SOIPD_MOD_PUC, IF_REAL, "Cross-term dependence of uc"), + IOP ("pvsat", B3SOIPD_MOD_PVSAT, IF_REAL, "Cross-term dependence of vsat"), + IOP ("pa0", B3SOIPD_MOD_PA0, IF_REAL, "Cross-term dependence of a0"), + IOP ("pags", B3SOIPD_MOD_PAGS, IF_REAL, "Cross-term dependence of ags"), + IOP ("pb0", B3SOIPD_MOD_PB0, IF_REAL, "Cross-term dependence of b0"), + IOP ("pb1", B3SOIPD_MOD_PB1, IF_REAL, "Cross-term dependence of b1"), + IOP ("pketa", B3SOIPD_MOD_PKETA, IF_REAL, "Cross-term dependence of keta"), + IOP ("pketas", B3SOIPD_MOD_PKETAS, IF_REAL, + "Cross-term dependence of ketas"), + IOP ("pa1", B3SOIPD_MOD_PA1, IF_REAL, "Cross-term dependence of a1"), + IOP ("pa2", B3SOIPD_MOD_PA2, IF_REAL, "Cross-term dependence of a2"), + IOP ("prdsw", B3SOIPD_MOD_PRDSW, IF_REAL, "Cross-term dependence of rdsw "), + IOP ("pprwb", B3SOIPD_MOD_PPRWB, IF_REAL, "Cross-term dependence of prwb "), + IOP ("pprwg", B3SOIPD_MOD_PPRWG, IF_REAL, "Cross-term dependence of prwg "), + IOP ("pwr", B3SOIPD_MOD_PWR, IF_REAL, "Cross-term dependence of wr"), + IOP ("pnfactor", B3SOIPD_MOD_PNFACTOR, IF_REAL, + "Cross-term dependence of nfactor"), + IOP ("pdwg", B3SOIPD_MOD_PDWG, IF_REAL, "Cross-term dependence of dwg"), + IOP ("pdwb", B3SOIPD_MOD_PDWB, IF_REAL, "Cross-term dependence of dwb"), + IOP ("pvoff", B3SOIPD_MOD_PVOFF, IF_REAL, "Cross-term dependence of voff"), + IOP ("peta0", B3SOIPD_MOD_PETA0, IF_REAL, "Cross-term dependence of eta0"), + IOP ("petab", B3SOIPD_MOD_PETAB, IF_REAL, "Cross-term dependence of etab"), + IOP ("pdsub", B3SOIPD_MOD_PDSUB, IF_REAL, "Cross-term dependence of dsub"), + IOP ("pcit", B3SOIPD_MOD_PCIT, IF_REAL, "Cross-term dependence of cit"), + IOP ("pcdsc", B3SOIPD_MOD_PCDSC, IF_REAL, "Cross-term dependence of cdsc"), + IOP ("pcdscb", B3SOIPD_MOD_PCDSCB, IF_REAL, + "Cross-term dependence of cdscb"), + IOP ("pcdscd", B3SOIPD_MOD_PCDSCD, IF_REAL, + "Cross-term dependence of cdscd"), + IOP ("ppclm", B3SOIPD_MOD_PPCLM, IF_REAL, "Cross-term dependence of pclm"), + IOP ("ppdiblc1", B3SOIPD_MOD_PPDIBL1, IF_REAL, + "Cross-term dependence of pdiblc1"), + IOP ("ppdiblc2", B3SOIPD_MOD_PPDIBL2, IF_REAL, + "Cross-term dependence of pdiblc2"), + IOP ("ppdiblcb", B3SOIPD_MOD_PPDIBLB, IF_REAL, + "Cross-term dependence of pdiblcb"), + IOP ("pdrout", B3SOIPD_MOD_PDROUT, IF_REAL, + "Cross-term dependence of drout"), + IOP ("ppvag", B3SOIPD_MOD_PPVAG, IF_REAL, "Cross-term dependence of pvag"), + IOP ("pdelta", B3SOIPD_MOD_PDELTA, IF_REAL, + "Cross-term dependence of delta"), + IOP ("palpha0", B3SOIPD_MOD_PALPHA0, IF_REAL, + "Cross-term dependence of alpha0"), + IOP ("pfbjtii", B3SOIPD_MOD_PFBJTII, IF_REAL, + "Cross-term dependence of fbjtii"), + IOP ("pbeta0", B3SOIPD_MOD_PBETA0, IF_REAL, + "Cross-term dependence of beta0"), + IOP ("pbeta1", B3SOIPD_MOD_PBETA1, IF_REAL, + "Cross-term dependence of beta1"), + IOP ("pbeta2", B3SOIPD_MOD_PBETA2, IF_REAL, + "Cross-term dependence of beta2"), + IOP ("pvdsatii0", B3SOIPD_MOD_PVDSATII0, IF_REAL, + "Cross-term dependence of vdsatii0"), + IOP ("plii", B3SOIPD_MOD_PLII, IF_REAL, "Cross-term dependence of lii"), + IOP ("pesatii", B3SOIPD_MOD_PESATII, IF_REAL, + "Cross-term dependence of esatii"), + IOP ("psii0", B3SOIPD_MOD_PSII0, IF_REAL, "Cross-term dependence of sii0"), + IOP ("psii1", B3SOIPD_MOD_PSII1, IF_REAL, "Cross-term dependence of sii1"), + IOP ("psii2", B3SOIPD_MOD_PSII2, IF_REAL, "Cross-term dependence of sii2"), + IOP ("psiid", B3SOIPD_MOD_PSIID, IF_REAL, "Cross-term dependence of siid"), + IOP ("pagidl", B3SOIPD_MOD_PAGIDL, IF_REAL, + "Cross-term dependence of agidl"), + IOP ("pbgidl", B3SOIPD_MOD_PBGIDL, IF_REAL, + "Cross-term dependence of bgidl"), + IOP ("pngidl", B3SOIPD_MOD_PNGIDL, IF_REAL, + "Cross-term dependence of ngidl"), + IOP ("pntun", B3SOIPD_MOD_PNTUN, IF_REAL, "Cross-term dependence of ntun"), + IOP ("pndiode", B3SOIPD_MOD_PNDIODE, IF_REAL, + "Cross-term dependence of ndiode"), + IOP ("pnrecf0", B3SOIPD_MOD_PNRECF0, IF_REAL, + "Cross-term dependence of nrecf0"), + IOP ("pnrecr0", B3SOIPD_MOD_PNRECR0, IF_REAL, + "Cross-term dependence of nrecr0"), + IOP ("pisbjt", B3SOIPD_MOD_PISBJT, IF_REAL, + "Cross-term dependence of isbjt"), + IOP ("pisdif", B3SOIPD_MOD_PISDIF, IF_REAL, + "Cross-term dependence of isdif"), + IOP ("pisrec", B3SOIPD_MOD_PISREC, IF_REAL, + "Cross-term dependence of isrec"), + IOP ("pistun", B3SOIPD_MOD_PISTUN, IF_REAL, + "Cross-term dependence of istun"), + IOP ("pvrec0", B3SOIPD_MOD_PVREC0, IF_REAL, + "Cross-term dependence of vrec0"), + IOP ("pvtun0", B3SOIPD_MOD_PVTUN0, IF_REAL, + "Cross-term dependence of vtun0"), + IOP ("pnbjt", B3SOIPD_MOD_PNBJT, IF_REAL, "Cross-term dependence of nbjt"), + IOP ("plbjt0", B3SOIPD_MOD_PLBJT0, IF_REAL, + "Cross-term dependence of lbjt0"), + IOP ("pvabjt", B3SOIPD_MOD_PVABJT, IF_REAL, + "Cross-term dependence of vabjt"), + IOP ("paely", B3SOIPD_MOD_PAELY, IF_REAL, "Cross-term dependence of aely"), + IOP ("pahli", B3SOIPD_MOD_PAHLI, IF_REAL, "Cross-term dependence of ahli"), + IOP ("pvsdfb", B3SOIPD_MOD_PVSDFB, IF_REAL, + "Cross-term dependence of vsdfb"), + IOP ("pvsdth", B3SOIPD_MOD_PVSDTH, IF_REAL, + "Cross-term dependence of vsdth"), + IOP ("pdelvt", B3SOIPD_MOD_PDELVT, IF_REAL, + "Cross-term dependence of delvt"), + IOP ("pacde", B3SOIPD_MOD_PACDE, IF_REAL, "Cross-term dependence of acde"), + IOP ("pmoin", B3SOIPD_MOD_PMOIN, IF_REAL, "Cross-term dependence of amoin"), +/* Added for binning - END */ + + IP ("nmos", B3SOIPD_MOD_NMOS, IF_FLAG, "Flag to indicate NMOS"), + IP ("pmos", B3SOIPD_MOD_PMOS, IF_FLAG, "Flag to indicate PMOS"), +}; + +char *B3SOIPDnames[] = { + "Drain", + "Gate", + "Source", + "Backgate", + "", + "Body", + "Temp", + "Charge", +}; + +int B3SOIPDnSize = NUMELEMS (B3SOIPDnames); +int B3SOIPDpTSize = NUMELEMS (B3SOIPDpTable); +int B3SOIPDmPTSize = NUMELEMS (B3SOIPDmPTable); +int B3SOIPDiSize = sizeof (B3SOIPDinstance); +int B3SOIPDmSize = sizeof (B3SOIPDmodel); diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdacld.c b/src/spicelib/devices/bsim3soi_pd/b3soipdacld.c new file mode 100644 index 000000000..35c78ab62 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdacld.c @@ -0,0 +1,358 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipdacld.c 98/5/01 +Modified by Pin Su 99/4/30 +Modified by Pin Su 99/9/27 +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "b3soipddef.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIPDacLoad (inModel, ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + B3SOIPDmodel *model = (B3SOIPDmodel *) inModel; + B3SOIPDinstance *here; + int selfheat; + double xcggb, xcgdb, xcgsb, xcgeb, xcgT; + double xcdgb, xcddb, xcdsb, xcdeb, xcdT; + double xcsgb, xcsdb, xcssb, xcseb, xcsT; + double xcbgb, xcbdb, xcbsb, xcbeb, xcbT; + double xcegb, xceeb, xceT; + double gdpr, gspr, gds; + double cggb, cgdb, cgsb, cgT; + double cdgb, cddb, cdsb, cdeb, cdT; + double cbgb, cbdb, cbsb, cbeb, cbT; + double ceeb, ceT; + double GSoverlapCap, GDoverlapCap, GEoverlapCap, FwdSum, RevSum, Gm, Gmbs, + GmT; + double omega; + double dxpart, sxpart; + double gbbg, gbbdp, gbbb, gbbp, gbbsp, gbbT; + double gddpg, gddpdp, gddpsp, gddpb, gddpT; + double gsspg, gsspdp, gsspsp, gsspb, gsspT; + double gppdp, gppb, gppp, gppT; + double xcTt, cTt, gcTt, gTtt, gTtg, gTtb, gTtdp, gTtsp; + double EDextrinsicCap, ESextrinsicCap; + double xcedb, xcesb; + + + omega = ckt->CKTomega; + for (; model != NULL; model = model->B3SOIPDnextModel) + { + + for (here = model->B3SOIPDinstances; here != NULL; + here = here->B3SOIPDnextInstance) + { + selfheat = (model->B3SOIPDshMod == 1) && (here->B3SOIPDrth0 != 0.0); + if (here->B3SOIPDmode >= 0) + { + Gm = here->B3SOIPDgm; + Gmbs = here->B3SOIPDgmbs; + GmT = model->B3SOIPDtype * here->B3SOIPDgmT; + FwdSum = Gm + Gmbs; + RevSum = 0.0; + + cbgb = here->B3SOIPDcbgb; + cbsb = here->B3SOIPDcbsb; + cbdb = here->B3SOIPDcbdb; + cbeb = here->B3SOIPDcbeb; + cbT = model->B3SOIPDtype * here->B3SOIPDcbT; + + ceeb = here->B3SOIPDceeb; + ceT = model->B3SOIPDtype * here->B3SOIPDceT; + + cggb = here->B3SOIPDcggb; + cgsb = here->B3SOIPDcgsb; + cgdb = here->B3SOIPDcgdb; + cgT = model->B3SOIPDtype * here->B3SOIPDcgT; + + cdgb = here->B3SOIPDcdgb; + cdsb = here->B3SOIPDcdsb; + cddb = here->B3SOIPDcddb; + cdeb = here->B3SOIPDcdeb; + cdT = model->B3SOIPDtype * here->B3SOIPDcdT; + + cTt = here->pParam->B3SOIPDcth; + + gbbg = -here->B3SOIPDgbgs; + gbbdp = -here->B3SOIPDgbds; + gbbb = -here->B3SOIPDgbbs; + gbbp = -here->B3SOIPDgbps; + gbbT = -model->B3SOIPDtype * here->B3SOIPDgbT; + gbbsp = -(gbbg + gbbdp + gbbb + gbbp); + + gddpg = -here->B3SOIPDgjdg; + gddpdp = -here->B3SOIPDgjdd; + gddpb = -here->B3SOIPDgjdb; + gddpT = -model->B3SOIPDtype * here->B3SOIPDgjdT; + gddpsp = -(gddpg + gddpdp + gddpb); + + gsspg = -here->B3SOIPDgjsg; + gsspdp = -here->B3SOIPDgjsd; + gsspb = -here->B3SOIPDgjsb; + gsspT = -model->B3SOIPDtype * here->B3SOIPDgjsT; + gsspsp = -(gsspg + gsspdp + gsspb); + + gppdp = 0; + gppb = -here->B3SOIPDgbpbs; + gppp = -here->B3SOIPDgbpps; + gppT = -model->B3SOIPDtype * here->B3SOIPDgbpT; + + gTtg = here->B3SOIPDgtempg; + gTtb = here->B3SOIPDgtempb; + gTtdp = here->B3SOIPDgtempd; + gTtt = here->B3SOIPDgtempT; + gTtsp = -(gTtg + gTtb + gTtdp); + + sxpart = 0.6; + dxpart = 0.4; + + } + else + { + Gm = -here->B3SOIPDgm; + Gmbs = -here->B3SOIPDgmbs; + GmT = -model->B3SOIPDtype * here->B3SOIPDgmT; + FwdSum = 0.0; + RevSum = -Gm - Gmbs; + + cdgb = + -(here->B3SOIPDcdgb + here->B3SOIPDcggb + here->B3SOIPDcbgb); + cdsb = + -(here->B3SOIPDcddb + here->B3SOIPDcgdb + here->B3SOIPDcbdb); + cddb = + -(here->B3SOIPDcdsb + here->B3SOIPDcgsb + here->B3SOIPDcbsb); + cdeb = + -(here->B3SOIPDcdeb + here->B3SOIPDcbeb + here->B3SOIPDceeb); + cdT = + -model->B3SOIPDtype * (here->B3SOIPDcgT + here->B3SOIPDcbT + + here->B3SOIPDcdT + here->B3SOIPDceT); + + ceeb = here->B3SOIPDceeb; + ceT = model->B3SOIPDtype * here->B3SOIPDceT; + + cggb = here->B3SOIPDcggb; + cgsb = here->B3SOIPDcgdb; + cgdb = here->B3SOIPDcgsb; + cgT = model->B3SOIPDtype * here->B3SOIPDcgT; + + cbgb = here->B3SOIPDcbgb; + cbsb = here->B3SOIPDcbdb; + cbdb = here->B3SOIPDcbsb; + cbeb = here->B3SOIPDcbeb; + cbT = model->B3SOIPDtype * here->B3SOIPDcbT; + + cTt = here->pParam->B3SOIPDcth; + + gbbg = -here->B3SOIPDgbgs; + gbbb = -here->B3SOIPDgbbs; + gbbp = -here->B3SOIPDgbps; + gbbsp = -here->B3SOIPDgbds; + gbbT = -model->B3SOIPDtype * here->B3SOIPDgbT; + gbbdp = -(gbbg + gbbsp + gbbb + gbbp); + + gddpg = -here->B3SOIPDgjsg; + gddpsp = -here->B3SOIPDgjsd; + gddpb = -here->B3SOIPDgjsb; + gddpT = -model->B3SOIPDtype * here->B3SOIPDgjsT; + gddpdp = -(gddpg + gddpsp + gddpb); + + gsspg = -here->B3SOIPDgjdg; + gsspsp = -here->B3SOIPDgjdd; + gsspb = -here->B3SOIPDgjdb; + gsspT = -model->B3SOIPDtype * here->B3SOIPDgjdT; + gsspdp = -(gsspg + gsspsp + gsspb); + + gppb = -here->B3SOIPDgbpbs; + gppp = -here->B3SOIPDgbpps; + gppT = -model->B3SOIPDtype * here->B3SOIPDgbpT; + gppdp = -(gppb + gppp); + + gTtt = here->B3SOIPDgtempT; + gTtg = here->B3SOIPDgtempg; + gTtb = here->B3SOIPDgtempb; + gTtdp = here->B3SOIPDgtempd; + gTtsp = -(gTtt + gTtg + gTtb + gTtdp); + + gTtg = here->B3SOIPDgtempg; + gTtb = here->B3SOIPDgtempb; + gTtsp = here->B3SOIPDgtempd; + gTtt = here->B3SOIPDgtempT; + gTtdp = -(gTtg + gTtb + gTtsp); + + sxpart = 0.6; + sxpart = 0.4; + dxpart = 0.6; + } + + gdpr = here->B3SOIPDdrainConductance; + gspr = here->B3SOIPDsourceConductance; + gds = here->B3SOIPDgds; + + GSoverlapCap = here->B3SOIPDcgso; + GDoverlapCap = here->B3SOIPDcgdo; + GEoverlapCap = here->pParam->B3SOIPDcgeo; + + EDextrinsicCap = here->B3SOIPDgcde; + ESextrinsicCap = here->B3SOIPDgcse; + xcedb = -EDextrinsicCap * omega; + xcdeb = (cdeb - EDextrinsicCap) * omega; + xcddb = (cddb + GDoverlapCap + EDextrinsicCap) * omega; + xceeb = + (ceeb + GEoverlapCap + EDextrinsicCap + ESextrinsicCap) * omega; + xcesb = -ESextrinsicCap * omega; + xcssb = + (GSoverlapCap + ESextrinsicCap - (cgsb + cbsb + cdsb)) * omega; + + xcseb = -(cbeb + cdeb + ceeb + ESextrinsicCap) * omega; + + xcegb = (-GEoverlapCap) * omega; + xceT = ceT * omega; + xcggb = (cggb + GDoverlapCap + GSoverlapCap + GEoverlapCap) * omega; + xcgdb = (cgdb - GDoverlapCap) * omega; + xcgsb = (cgsb - GSoverlapCap) * omega; + xcgeb = (-GEoverlapCap) * omega; + xcgT = cgT * omega; + + xcdgb = (cdgb - GDoverlapCap) * omega; + xcdsb = cdsb * omega; + xcdT = cdT * omega; + + xcsgb = -(cggb + cbgb + cdgb + GSoverlapCap) * omega; + xcsdb = -(cgdb + cbdb + cddb) * omega; + xcsT = -(cgT + cbT + cdT + ceT) * omega; + + xcbgb = cbgb * omega; + xcbdb = cbdb * omega; + xcbsb = cbsb * omega; + xcbeb = cbeb * omega; + xcbT = cbT * omega; + + xcTt = cTt * omega; + + *(here->B3SOIPDEdpPtr + 1) += xcedb; + *(here->B3SOIPDEspPtr + 1) += xcesb; + *(here->B3SOIPDDPePtr + 1) += xcdeb; + *(here->B3SOIPDSPePtr + 1) += xcseb; + *(here->B3SOIPDEgPtr + 1) += xcegb; + *(here->B3SOIPDGePtr + 1) += xcgeb; + + *(here->B3SOIPDEePtr + 1) += xceeb; + + *(here->B3SOIPDGgPtr + 1) += xcggb; + *(here->B3SOIPDGdpPtr + 1) += xcgdb; + *(here->B3SOIPDGspPtr + 1) += xcgsb; + + *(here->B3SOIPDDPgPtr + 1) += xcdgb; + *(here->B3SOIPDDPdpPtr + 1) += xcddb; + *(here->B3SOIPDDPspPtr + 1) += xcdsb; + + *(here->B3SOIPDSPgPtr + 1) += xcsgb; + *(here->B3SOIPDSPdpPtr + 1) += xcsdb; + *(here->B3SOIPDSPspPtr + 1) += xcssb; + + *(here->B3SOIPDBePtr + 1) += xcbeb; + *(here->B3SOIPDBgPtr + 1) += xcbgb; + *(here->B3SOIPDBdpPtr + 1) += xcbdb; + *(here->B3SOIPDBspPtr + 1) += xcbsb; + + *(here->B3SOIPDEbPtr + 1) -= xcegb + xceeb + xcedb + xcesb; + + *(here->B3SOIPDGbPtr + 1) -= xcggb + xcgdb + xcgsb + xcgeb; + *(here->B3SOIPDDPbPtr + 1) -= xcdgb + xcddb + xcdsb + xcdeb; + *(here->B3SOIPDSPbPtr + 1) -= xcsgb + xcsdb + xcssb + xcseb; + *(here->B3SOIPDBbPtr + 1) -= xcbgb + xcbdb + xcbsb + xcbeb; + + if (selfheat) + { + *(here->B3SOIPDTemptempPtr + 1) += xcTt; + *(here->B3SOIPDDPtempPtr + 1) += xcdT; + *(here->B3SOIPDSPtempPtr + 1) += xcsT; + *(here->B3SOIPDBtempPtr + 1) += xcbT; + *(here->B3SOIPDEtempPtr + 1) += xceT; + *(here->B3SOIPDGtempPtr + 1) += xcgT; + } + + + + *(here->B3SOIPDEePtr) += 0.0; + + *(here->B3SOIPDDPgPtr) += Gm + gddpg; + *(here->B3SOIPDDPdpPtr) += gdpr + gds + gddpdp + RevSum; + *(here->B3SOIPDDPspPtr) -= gds + FwdSum - gddpsp; + *(here->B3SOIPDDPdPtr) -= gdpr; + + *(here->B3SOIPDSPgPtr) -= Gm - gsspg; + *(here->B3SOIPDSPdpPtr) -= gds + RevSum - gsspdp; + *(here->B3SOIPDSPspPtr) += gspr + gds + FwdSum + gsspsp; + *(here->B3SOIPDSPsPtr) -= gspr; + + *(here->B3SOIPDBePtr) += 0; + *(here->B3SOIPDBgPtr) += gbbg; + *(here->B3SOIPDBdpPtr) += gbbdp; + *(here->B3SOIPDBspPtr) += gbbsp; + *(here->B3SOIPDBbPtr) += gbbb; + *(here->B3SOIPDEbPtr) += 0.0; + *(here->B3SOIPDSPbPtr) -= Gmbs - gsspb; + *(here->B3SOIPDDPbPtr) -= (-gddpb - Gmbs); + + if (selfheat) + { + *(here->B3SOIPDDPtempPtr) += GmT + gddpT; + *(here->B3SOIPDSPtempPtr) += -GmT + gsspT; + *(here->B3SOIPDBtempPtr) += gbbT; + + *(here->B3SOIPDTemptempPtr) += + gTtt + 1 / here->pParam->B3SOIPDrth; + *(here->B3SOIPDTempgPtr) += gTtg; + *(here->B3SOIPDTempbPtr) += gTtb; + *(here->B3SOIPDTempdpPtr) += gTtdp; + *(here->B3SOIPDTempspPtr) += gTtsp; + } + + + *(here->B3SOIPDDdPtr) += gdpr; + *(here->B3SOIPDDdpPtr) -= gdpr; + *(here->B3SOIPDSsPtr) += gspr; + *(here->B3SOIPDSspPtr) -= gspr; + + + if (here->B3SOIPDbodyMod == 1) + { + (*(here->B3SOIPDBpPtr) -= gppp); + (*(here->B3SOIPDPbPtr) += gppb); + (*(here->B3SOIPDPpPtr) += gppp); + } + if (here->B3SOIPDdebugMod != 0) + { + *(here->B3SOIPDVbsPtr) += 1; + *(here->B3SOIPDIdsPtr) += 1; + *(here->B3SOIPDIcPtr) += 1; + *(here->B3SOIPDIbsPtr) += 1; + *(here->B3SOIPDIbdPtr) += 1; + *(here->B3SOIPDIiiPtr) += 1; + *(here->B3SOIPDIgidlPtr) += 1; + *(here->B3SOIPDItunPtr) += 1; + *(here->B3SOIPDIbpPtr) += 1; + *(here->B3SOIPDCbgPtr) += 1; + *(here->B3SOIPDCbbPtr) += 1; + *(here->B3SOIPDCbdPtr) += 1; + *(here->B3SOIPDQbfPtr) += 1; + *(here->B3SOIPDQjsPtr) += 1; + *(here->B3SOIPDQjdPtr) += 1; + + } + + } + } + return (OK); +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdask.c b/src/spicelib/devices/bsim3soi_pd/b3soipdask.c new file mode 100644 index 000000000..21e466787 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdask.c @@ -0,0 +1,244 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipdask.c 98/5/01 +Modified by Pin Su 99/4/30 +**********/ + + +#include "ngspice.h" +#include +#include +#include "ifsim.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "b3soipddef.h" +#include "sperror.h" +#include "suffix.h" + +int +B3SOIPDask (ckt, inst, which, value, select) + CKTcircuit *ckt; + GENinstance *inst; + int which; + IFvalue *value; + IFvalue *select; +{ + B3SOIPDinstance *here = (B3SOIPDinstance *) inst; + + switch (which) + { + case B3SOIPD_L: + value->rValue = here->B3SOIPDl; + return (OK); + case B3SOIPD_W: + value->rValue = here->B3SOIPDw; + return (OK); + case B3SOIPD_AS: + value->rValue = here->B3SOIPDsourceArea; + return (OK); + case B3SOIPD_AD: + value->rValue = here->B3SOIPDdrainArea; + return (OK); + case B3SOIPD_PS: + value->rValue = here->B3SOIPDsourcePerimeter; + return (OK); + case B3SOIPD_PD: + value->rValue = here->B3SOIPDdrainPerimeter; + return (OK); + case B3SOIPD_NRS: + value->rValue = here->B3SOIPDsourceSquares; + return (OK); + case B3SOIPD_NRD: + value->rValue = here->B3SOIPDdrainSquares; + return (OK); + case B3SOIPD_OFF: + value->iValue = here->B3SOIPDoff; + return (OK); + case B3SOIPD_BJTOFF: + value->iValue = here->B3SOIPDbjtoff; + return (OK); + case B3SOIPD_RTH0: + value->rValue = here->B3SOIPDrth0; + return (OK); + case B3SOIPD_CTH0: + value->rValue = here->B3SOIPDcth0; + return (OK); + case B3SOIPD_NRB: + value->rValue = here->B3SOIPDbodySquares; + return (OK); + + +/* v2.0 release */ + case B3SOIPD_NBC: + value->rValue = here->B3SOIPDnbc; + return (OK); + case B3SOIPD_NSEG: + value->rValue = here->B3SOIPDnseg; + return (OK); + case B3SOIPD_PDBCP: + value->rValue = here->B3SOIPDpdbcp; + return (OK); + case B3SOIPD_PSBCP: + value->rValue = here->B3SOIPDpsbcp; + return (OK); + case B3SOIPD_AGBCP: + value->rValue = here->B3SOIPDagbcp; + return (OK); + case B3SOIPD_AEBCP: + value->rValue = here->B3SOIPDaebcp; + return (OK); + case B3SOIPD_VBSUSR: + value->rValue = here->B3SOIPDvbsusr; + return (OK); + case B3SOIPD_TNODEOUT: + value->iValue = here->B3SOIPDtnodeout; + return (OK); + + + case B3SOIPD_IC_VBS: + value->rValue = here->B3SOIPDicVBS; + return (OK); + case B3SOIPD_IC_VDS: + value->rValue = here->B3SOIPDicVDS; + return (OK); + case B3SOIPD_IC_VGS: + value->rValue = here->B3SOIPDicVGS; + return (OK); + case B3SOIPD_IC_VES: + value->rValue = here->B3SOIPDicVES; + return (OK); + case B3SOIPD_IC_VPS: + value->rValue = here->B3SOIPDicVPS; + return (OK); + case B3SOIPD_DNODE: + value->iValue = here->B3SOIPDdNode; + return (OK); + case B3SOIPD_GNODE: + value->iValue = here->B3SOIPDgNode; + return (OK); + case B3SOIPD_SNODE: + value->iValue = here->B3SOIPDsNode; + return (OK); + case B3SOIPD_BNODE: + value->iValue = here->B3SOIPDbNode; + return (OK); + case B3SOIPD_ENODE: + value->iValue = here->B3SOIPDeNode; + return (OK); + case B3SOIPD_DNODEPRIME: + value->iValue = here->B3SOIPDdNodePrime; + return (OK); + case B3SOIPD_SNODEPRIME: + value->iValue = here->B3SOIPDsNodePrime; + return (OK); + case B3SOIPD_SOURCECONDUCT: + value->rValue = here->B3SOIPDsourceConductance; + return (OK); + case B3SOIPD_DRAINCONDUCT: + value->rValue = here->B3SOIPDdrainConductance; + return (OK); + case B3SOIPD_VBD: + value->rValue = *(ckt->CKTstate0 + here->B3SOIPDvbd); + return (OK); + case B3SOIPD_VBS: + value->rValue = *(ckt->CKTstate0 + here->B3SOIPDvbs); + return (OK); + case B3SOIPD_VGS: + value->rValue = *(ckt->CKTstate0 + here->B3SOIPDvgs); + return (OK); + case B3SOIPD_VES: + value->rValue = *(ckt->CKTstate0 + here->B3SOIPDves); + return (OK); + case B3SOIPD_VDS: + value->rValue = *(ckt->CKTstate0 + here->B3SOIPDvds); + return (OK); + case B3SOIPD_CD: + value->rValue = here->B3SOIPDcd; + return (OK); + case B3SOIPD_CBS: + value->rValue = here->B3SOIPDcjs; + return (OK); + case B3SOIPD_CBD: + value->rValue = here->B3SOIPDcjd; + return (OK); + case B3SOIPD_GM: + value->rValue = here->B3SOIPDgm; + return (OK); + case B3SOIPD_GMID: + value->rValue = here->B3SOIPDgm / here->B3SOIPDcd; + return (OK); + case B3SOIPD_GDS: + value->rValue = here->B3SOIPDgds; + return (OK); + case B3SOIPD_GMBS: + value->rValue = here->B3SOIPDgmbs; + return (OK); + case B3SOIPD_GBD: + value->rValue = here->B3SOIPDgjdb; + return (OK); + case B3SOIPD_GBS: + value->rValue = here->B3SOIPDgjsb; + return (OK); + case B3SOIPD_QB: + value->rValue = *(ckt->CKTstate0 + here->B3SOIPDqb); + return (OK); + case B3SOIPD_CQB: + value->rValue = *(ckt->CKTstate0 + here->B3SOIPDcqb); + return (OK); + case B3SOIPD_QG: + value->rValue = *(ckt->CKTstate0 + here->B3SOIPDqg); + return (OK); + case B3SOIPD_CQG: + value->rValue = *(ckt->CKTstate0 + here->B3SOIPDcqg); + return (OK); + case B3SOIPD_QD: + value->rValue = *(ckt->CKTstate0 + here->B3SOIPDqd); + return (OK); + case B3SOIPD_CQD: + value->rValue = *(ckt->CKTstate0 + here->B3SOIPDcqd); + return (OK); + case B3SOIPD_CGG: + value->rValue = here->B3SOIPDcggb; + return (OK); + case B3SOIPD_CGD: + value->rValue = here->B3SOIPDcgdb; + return (OK); + case B3SOIPD_CGS: + value->rValue = here->B3SOIPDcgsb; + return (OK); + case B3SOIPD_CDG: + value->rValue = here->B3SOIPDcdgb; + return (OK); + case B3SOIPD_CDD: + value->rValue = here->B3SOIPDcddb; + return (OK); + case B3SOIPD_CDS: + value->rValue = here->B3SOIPDcdsb; + return (OK); + case B3SOIPD_CBG: + value->rValue = here->B3SOIPDcbgb; + return (OK); + case B3SOIPD_CBDB: + value->rValue = here->B3SOIPDcbdb; + return (OK); + case B3SOIPD_CBSB: + value->rValue = here->B3SOIPDcbsb; + return (OK); + case B3SOIPD_VON: + value->rValue = here->B3SOIPDvon; + return (OK); + case B3SOIPD_VDSAT: + value->rValue = here->B3SOIPDvdsat; + return (OK); + case B3SOIPD_QBS: + value->rValue = *(ckt->CKTstate0 + here->B3SOIPDqbs); + return (OK); + case B3SOIPD_QBD: + value->rValue = *(ckt->CKTstate0 + here->B3SOIPDqbd); + return (OK); + default: + return (E_BADPARM); + } + /* NOTREACHED */ +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdcheck.c b/src/spicelib/devices/bsim3soi_pd/b3soipdcheck.c new file mode 100644 index 000000000..2681ad40a --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdcheck.c @@ -0,0 +1,913 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipdcheck.c 98/5/01 +Modified by Pin Su and Jan Feng 99/2/15 +Modified by Pin Su 99/4/30 +Modified by Pin Su 00/3/1 +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "b3soipddef.h" +#include "trandefs.h" +#include "const.h" +#include "sperror.h" +#include "devdefs.h" +#include "suffix.h" + +int +B3SOIPDcheckModel (model, here, ckt) + B3SOIPDmodel *model; + B3SOIPDinstance *here; + CKTcircuit *ckt; +{ + struct b3soipdSizeDependParam *pParam; + int Fatal_Flag = 0; + FILE *fplog; + + if ((fplog = fopen ("b3soipdv1check.log", "w")) != NULL) + { + pParam = here->pParam; + fprintf (fplog, "B3SOIPDV3 Parameter Check\n"); + fprintf (fplog, "Model = %s\n", model->B3SOIPDmodName); + fprintf (fplog, "W = %g, L = %g\n", here->B3SOIPDw, here->B3SOIPDl); + + + if (pParam->B3SOIPDnlx < -pParam->B3SOIPDleff) + { + fprintf (fplog, "Fatal: Nlx = %g is less than -Leff.\n", + pParam->B3SOIPDnlx); + printf ("Fatal: Nlx = %g is less than -Leff.\n", + pParam->B3SOIPDnlx); + Fatal_Flag = 1; + } + + if (model->B3SOIPDtox <= 0.0) + { + fprintf (fplog, "Fatal: Tox = %g is not positive.\n", + model->B3SOIPDtox); + printf ("Fatal: Tox = %g is not positive.\n", model->B3SOIPDtox); + Fatal_Flag = 1; + } + + if (model->B3SOIPDtbox <= 0.0) + { + fprintf (fplog, "Fatal: Tbox = %g is not positive.\n", + model->B3SOIPDtbox); + printf ("Fatal: Tbox = %g is not positive.\n", model->B3SOIPDtbox); + Fatal_Flag = 1; + } + + if (pParam->B3SOIPDnpeak <= 0.0) + { + fprintf (fplog, "Fatal: Nch = %g is not positive.\n", + pParam->B3SOIPDnpeak); + printf ("Fatal: Nch = %g is not positive.\n", pParam->B3SOIPDnpeak); + Fatal_Flag = 1; + } + if (pParam->B3SOIPDngate < 0.0) + { + fprintf (fplog, "Fatal: Ngate = %g is not positive.\n", + pParam->B3SOIPDngate); + printf ("Fatal: Ngate = %g Ngate is not positive.\n", + pParam->B3SOIPDngate); + Fatal_Flag = 1; + } + if (pParam->B3SOIPDngate > 1.e25) + { + fprintf (fplog, "Fatal: Ngate = %g is too high.\n", + pParam->B3SOIPDngate); + printf ("Fatal: Ngate = %g Ngate is too high\n", + pParam->B3SOIPDngate); + Fatal_Flag = 1; + } + + if (pParam->B3SOIPDdvt1 < 0.0) + { + fprintf (fplog, "Fatal: Dvt1 = %g is negative.\n", + pParam->B3SOIPDdvt1); + printf ("Fatal: Dvt1 = %g is negative.\n", pParam->B3SOIPDdvt1); + Fatal_Flag = 1; + } + + if (pParam->B3SOIPDdvt1w < 0.0) + { + fprintf (fplog, "Fatal: Dvt1w = %g is negative.\n", + pParam->B3SOIPDdvt1w); + printf ("Fatal: Dvt1w = %g is negative.\n", pParam->B3SOIPDdvt1w); + Fatal_Flag = 1; + } + + if (pParam->B3SOIPDw0 == -pParam->B3SOIPDweff) + { + fprintf (fplog, "Fatal: (W0 + Weff) = 0 cauing divided-by-zero.\n"); + printf ("Fatal: (W0 + Weff) = 0 cauing divided-by-zero.\n"); + Fatal_Flag = 1; + } + + if (pParam->B3SOIPDdsub < 0.0) + { + fprintf (fplog, "Fatal: Dsub = %g is negative.\n", + pParam->B3SOIPDdsub); + printf ("Fatal: Dsub = %g is negative.\n", pParam->B3SOIPDdsub); + Fatal_Flag = 1; + } + if (pParam->B3SOIPDb1 == -pParam->B3SOIPDweff) + { + fprintf (fplog, + "Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n"); + printf ("Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n"); + Fatal_Flag = 1; + } + if (pParam->B3SOIPDu0temp <= 0.0) + { + fprintf (fplog, + "Fatal: u0 at current temperature = %g is not positive.\n", + pParam->B3SOIPDu0temp); + printf ("Fatal: u0 at current temperature = %g is not positive.\n", + pParam->B3SOIPDu0temp); + Fatal_Flag = 1; + } + +/* Check delta parameter */ + if (pParam->B3SOIPDdelta < 0.0) + { + fprintf (fplog, "Fatal: Delta = %g is less than zero.\n", + pParam->B3SOIPDdelta); + printf ("Fatal: Delta = %g is less than zero.\n", + pParam->B3SOIPDdelta); + Fatal_Flag = 1; + } + + if (pParam->B3SOIPDvsattemp <= 0.0) + { + fprintf (fplog, + "Fatal: Vsat at current temperature = %g is not positive.\n", + pParam->B3SOIPDvsattemp); + printf + ("Fatal: Vsat at current temperature = %g is not positive.\n", + pParam->B3SOIPDvsattemp); + Fatal_Flag = 1; + } +/* Check Rout parameters */ + if (pParam->B3SOIPDpclm <= 0.0) + { + fprintf (fplog, "Fatal: Pclm = %g is not positive.\n", + pParam->B3SOIPDpclm); + printf ("Fatal: Pclm = %g is not positive.\n", pParam->B3SOIPDpclm); + Fatal_Flag = 1; + } + + if (pParam->B3SOIPDdrout < 0.0) + { + fprintf (fplog, "Fatal: Drout = %g is negative.\n", + pParam->B3SOIPDdrout); + printf ("Fatal: Drout = %g is negative.\n", pParam->B3SOIPDdrout); + Fatal_Flag = 1; + } + if (model->B3SOIPDunitLengthGateSidewallJctCap > 0.0) + { + if (here->B3SOIPDdrainPerimeter < pParam->B3SOIPDweff) + { + fprintf (fplog, "Warning: Pd = %g is less than W.\n", + here->B3SOIPDdrainPerimeter); + printf ("Warning: Pd = %g is less than W.\n", + here->B3SOIPDdrainPerimeter); + here->B3SOIPDdrainPerimeter = pParam->B3SOIPDweff; + } + if (here->B3SOIPDsourcePerimeter < pParam->B3SOIPDweff) + { + fprintf (fplog, "Warning: Ps = %g is less than W.\n", + here->B3SOIPDsourcePerimeter); + printf ("Warning: Ps = %g is less than W.\n", + here->B3SOIPDsourcePerimeter); + here->B3SOIPDsourcePerimeter = pParam->B3SOIPDweff; + } + } +/* Check capacitance parameters */ + if (pParam->B3SOIPDclc < 0.0) + { + fprintf (fplog, "Fatal: Clc = %g is negative.\n", + pParam->B3SOIPDclc); + printf ("Fatal: Clc = %g is negative.\n", pParam->B3SOIPDclc); + Fatal_Flag = 1; + } + if (model->B3SOIPDparamChk == 1) + { +/* Check L and W parameters */ + if (pParam->B3SOIPDleff <= 5.0e-8) + { + fprintf (fplog, "Warning: Leff = %g may be too small.\n", + pParam->B3SOIPDleff); + printf ("Warning: Leff = %g may be too small.\n", + pParam->B3SOIPDleff); + } + + if (pParam->B3SOIPDleffCV <= 5.0e-8) + { + fprintf (fplog, "Warning: Leff for CV = %g may be too small.\n", + pParam->B3SOIPDleffCV); + printf ("Warning: Leff for CV = %g may be too small.\n", + pParam->B3SOIPDleffCV); + } + + if (pParam->B3SOIPDweff <= 1.0e-7) + { + fprintf (fplog, "Warning: Weff = %g may be too small.\n", + pParam->B3SOIPDweff); + printf ("Warning: Weff = %g may be too small.\n", + pParam->B3SOIPDweff); + } + + if (pParam->B3SOIPDweffCV <= 1.0e-7) + { + fprintf (fplog, "Warning: Weff for CV = %g may be too small.\n", + pParam->B3SOIPDweffCV); + printf ("Warning: Weff for CV = %g may be too small.\n", + pParam->B3SOIPDweffCV); + } + +/* Check threshold voltage parameters */ + if (pParam->B3SOIPDnlx < 0.0) + { + fprintf (fplog, "Warning: Nlx = %g is negative.\n", + pParam->B3SOIPDnlx); + printf ("Warning: Nlx = %g is negative.\n", pParam->B3SOIPDnlx); + } + if (model->B3SOIPDtox < 1.0e-9) + { + fprintf (fplog, "Warning: Tox = %g is less than 10A.\n", + model->B3SOIPDtox); + printf ("Warning: Tox = %g is less than 10A.\n", + model->B3SOIPDtox); + } + + if (pParam->B3SOIPDnpeak <= 1.0e15) + { + fprintf (fplog, "Warning: Nch = %g may be too small.\n", + pParam->B3SOIPDnpeak); + printf ("Warning: Nch = %g may be too small.\n", + pParam->B3SOIPDnpeak); + } + else if (pParam->B3SOIPDnpeak >= 1.0e21) + { + fprintf (fplog, "Warning: Nch = %g may be too large.\n", + pParam->B3SOIPDnpeak); + printf ("Warning: Nch = %g may be too large.\n", + pParam->B3SOIPDnpeak); + } + + if (fabs (pParam->B3SOIPDnsub) >= 1.0e21) + { + fprintf (fplog, "Warning: Nsub = %g may be too large.\n", + pParam->B3SOIPDnsub); + printf ("Warning: Nsub = %g may be too large.\n", + pParam->B3SOIPDnsub); + } + + if ((pParam->B3SOIPDngate > 0.0) && (pParam->B3SOIPDngate <= 1.e18)) + { + fprintf (fplog, + "Warning: Ngate = %g is less than 1.E18cm^-3.\n", + pParam->B3SOIPDngate); + printf ("Warning: Ngate = %g is less than 1.E18cm^-3.\n", + pParam->B3SOIPDngate); + } + + if (pParam->B3SOIPDdvt0 < 0.0) + { + fprintf (fplog, "Warning: Dvt0 = %g is negative.\n", + pParam->B3SOIPDdvt0); + printf ("Warning: Dvt0 = %g is negative.\n", + pParam->B3SOIPDdvt0); + } + + if (fabs (1.0e-6 / (pParam->B3SOIPDw0 + pParam->B3SOIPDweff)) > + 10.0) + { + fprintf (fplog, "Warning: (W0 + Weff) may be too small.\n"); + printf ("Warning: (W0 + Weff) may be too small.\n"); + } + +/* Check subthreshold parameters */ + if (pParam->B3SOIPDnfactor < 0.0) + { + fprintf (fplog, "Warning: Nfactor = %g is negative.\n", + pParam->B3SOIPDnfactor); + printf ("Warning: Nfactor = %g is negative.\n", + pParam->B3SOIPDnfactor); + } + if (pParam->B3SOIPDcdsc < 0.0) + { + fprintf (fplog, "Warning: Cdsc = %g is negative.\n", + pParam->B3SOIPDcdsc); + printf ("Warning: Cdsc = %g is negative.\n", + pParam->B3SOIPDcdsc); + } + if (pParam->B3SOIPDcdscd < 0.0) + { + fprintf (fplog, "Warning: Cdscd = %g is negative.\n", + pParam->B3SOIPDcdscd); + printf ("Warning: Cdscd = %g is negative.\n", + pParam->B3SOIPDcdscd); + } +/* Check DIBL parameters */ + if (pParam->B3SOIPDeta0 < 0.0) + { + fprintf (fplog, "Warning: Eta0 = %g is negative.\n", + pParam->B3SOIPDeta0); + printf ("Warning: Eta0 = %g is negative.\n", + pParam->B3SOIPDeta0); + } + +/* Check Abulk parameters */ + if (fabs (1.0e-6 / (pParam->B3SOIPDb1 + pParam->B3SOIPDweff)) > + 10.0) + { + fprintf (fplog, "Warning: (B1 + Weff) may be too small.\n"); + printf ("Warning: (B1 + Weff) may be too small.\n"); + } + +/* Check Saturation parameters */ + if (pParam->B3SOIPDa2 < 0.01) + { + fprintf (fplog, "Warning: A2 = %g is too small. Set to 0.01.\n", + pParam->B3SOIPDa2); + printf ("Warning: A2 = %g is too small. Set to 0.01.\n", + pParam->B3SOIPDa2); + pParam->B3SOIPDa2 = 0.01; + } + else if (pParam->B3SOIPDa2 > 1.0) + { + fprintf (fplog, + "Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n", + pParam->B3SOIPDa2); + printf + ("Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n", + pParam->B3SOIPDa2); + pParam->B3SOIPDa2 = 1.0; + pParam->B3SOIPDa1 = 0.0; + + } + + if (pParam->B3SOIPDrdsw < 0.0) + { + fprintf (fplog, + "Warning: Rdsw = %g is negative. Set to zero.\n", + pParam->B3SOIPDrdsw); + printf ("Warning: Rdsw = %g is negative. Set to zero.\n", + pParam->B3SOIPDrdsw); + pParam->B3SOIPDrdsw = 0.0; + pParam->B3SOIPDrds0 = 0.0; + } + else if ((pParam->B3SOIPDrds0 > 0.0) + && (pParam->B3SOIPDrds0 < 0.001)) + { + fprintf (fplog, + "Warning: Rds at current temperature = %g is less than 0.001 ohm. Set to zero.\n", + pParam->B3SOIPDrds0); + printf + ("Warning: Rds at current temperature = %g is less than 0.001 ohm. Set to zero.\n", + pParam->B3SOIPDrds0); + pParam->B3SOIPDrds0 = 0.0; + } + if (pParam->B3SOIPDvsattemp < 1.0e3) + { + fprintf (fplog, + "Warning: Vsat at current temperature = %g may be too small.\n", + pParam->B3SOIPDvsattemp); + printf + ("Warning: Vsat at current temperature = %g may be too small.\n", + pParam->B3SOIPDvsattemp); + } + + if (pParam->B3SOIPDpdibl1 < 0.0) + { + fprintf (fplog, "Warning: Pdibl1 = %g is negative.\n", + pParam->B3SOIPDpdibl1); + printf ("Warning: Pdibl1 = %g is negative.\n", + pParam->B3SOIPDpdibl1); + } + if (pParam->B3SOIPDpdibl2 < 0.0) + { + fprintf (fplog, "Warning: Pdibl2 = %g is negative.\n", + pParam->B3SOIPDpdibl2); + printf ("Warning: Pdibl2 = %g is negative.\n", + pParam->B3SOIPDpdibl2); + } +/* Check overlap capacitance parameters */ + if (model->B3SOIPDcgdo < 0.0) + { + fprintf (fplog, + "Warning: cgdo = %g is negative. Set to zero.\n", + model->B3SOIPDcgdo); + printf ("Warning: cgdo = %g is negative. Set to zero.\n", + model->B3SOIPDcgdo); + model->B3SOIPDcgdo = 0.0; + } + if (model->B3SOIPDcgso < 0.0) + { + fprintf (fplog, + "Warning: cgso = %g is negative. Set to zero.\n", + model->B3SOIPDcgso); + printf ("Warning: cgso = %g is negative. Set to zero.\n", + model->B3SOIPDcgso); + model->B3SOIPDcgso = 0.0; + } + if (model->B3SOIPDcgeo < 0.0) + { + fprintf (fplog, + "Warning: cgeo = %g is negative. Set to zero.\n", + model->B3SOIPDcgeo); + printf ("Warning: cgeo = %g is negative. Set to zero.\n", + model->B3SOIPDcgeo); + model->B3SOIPDcgeo = 0.0; + } + + if (model->B3SOIPDntun < 0.0) + { + fprintf (fplog, "Warning: Ntun = %g is negative.\n", + model->B3SOIPDntun); + printf ("Warning: Ntun = %g is negative.\n", + model->B3SOIPDntun); + } + + if (model->B3SOIPDndiode < 0.0) + { + fprintf (fplog, "Warning: Ndiode = %g is negative.\n", + model->B3SOIPDndiode); + printf ("Warning: Ndiode = %g is negative.\n", + model->B3SOIPDndiode); + } + + if (model->B3SOIPDisbjt < 0.0) + { + fprintf (fplog, "Warning: Isbjt = %g is negative.\n", + model->B3SOIPDisbjt); + printf ("Warning: Isbjt = %g is negative.\n", + model->B3SOIPDisbjt); + } + + if (model->B3SOIPDisdif < 0.0) + { + fprintf (fplog, "Warning: Isdif = %g is negative.\n", + model->B3SOIPDisdif); + printf ("Warning: Isdif = %g is negative.\n", + model->B3SOIPDisdif); + } + + if (model->B3SOIPDisrec < 0.0) + { + fprintf (fplog, "Warning: Isrec = %g is negative.\n", + model->B3SOIPDisrec); + printf ("Warning: Isrec = %g is negative.\n", + model->B3SOIPDisrec); + } + + if (model->B3SOIPDistun < 0.0) + { + fprintf (fplog, "Warning: Istun = %g is negative.\n", + model->B3SOIPDistun); + printf ("Warning: Istun = %g is negative.\n", + model->B3SOIPDistun); + } + + if (model->B3SOIPDtt < 0.0) + { + fprintf (fplog, "Warning: Tt = %g is negative.\n", + model->B3SOIPDtt); + printf ("Warning: Tt = %g is negative.\n", model->B3SOIPDtt); + } + + if (model->B3SOIPDcsdmin < 0.0) + { + fprintf (fplog, "Warning: Csdmin = %g is negative.\n", + model->B3SOIPDcsdmin); + printf ("Warning: Csdmin = %g is negative.\n", + model->B3SOIPDcsdmin); + } + + if (model->B3SOIPDcsdesw < 0.0) + { + fprintf (fplog, "Warning: Csdesw = %g is negative.\n", + model->B3SOIPDcsdesw); + printf ("Warning: Csdesw = %g is negative.\n", + model->B3SOIPDcsdesw); + } + + if (model->B3SOIPDasd < 0.0) + { + fprintf (fplog, "Warning: Asd = %g should be within (0, 1).\n", + model->B3SOIPDasd); + printf ("Warning: Asd = %g should be within (0, 1).\n", + model->B3SOIPDasd); + } + + if (model->B3SOIPDrth0 < 0.0) + { + fprintf (fplog, "Warning: Rth0 = %g is negative.\n", + model->B3SOIPDrth0); + printf ("Warning: Rth0 = %g is negative.\n", + model->B3SOIPDrth0); + } + + if (model->B3SOIPDcth0 < 0.0) + { + fprintf (fplog, "Warning: Cth0 = %g is negative.\n", + model->B3SOIPDcth0); + printf ("Warning: Cth0 = %g is negative.\n", + model->B3SOIPDcth0); + } + + if (model->B3SOIPDrbody < 0.0) + { + fprintf (fplog, "Warning: Rbody = %g is negative.\n", + model->B3SOIPDrbody); + printf ("Warning: Rbody = %g is negative.\n", + model->B3SOIPDrbody); + } + + if (model->B3SOIPDrbsh < 0.0) + { + fprintf (fplog, "Warning: Rbsh = %g is negative.\n", + model->B3SOIPDrbsh); + printf ("Warning: Rbsh = %g is negative.\n", + model->B3SOIPDrbsh); + } + + +/* v2.2 release */ + if (model->B3SOIPDwth0 < 0.0) + { + fprintf (fplog, "Warning: WTH0 = %g is negative.\n", + model->B3SOIPDwth0); + printf ("Warning: Wth0 = %g is negative.\n", + model->B3SOIPDwth0); + } + if (model->B3SOIPDrhalo < 0.0) + { + fprintf (fplog, "Warning: RHALO = %g is negative.\n", + model->B3SOIPDrhalo); + printf ("Warning: Rhalo = %g is negative.\n", + model->B3SOIPDrhalo); + } + if (model->B3SOIPDntox < 0.0) + { + fprintf (fplog, "Warning: NTOX = %g is negative.\n", + model->B3SOIPDntox); + printf ("Warning: Ntox = %g is negative.\n", + model->B3SOIPDntox); + } + if (model->B3SOIPDtoxref < 0.0) + { + fprintf (fplog, "Warning: TOXREF = %g is negative.\n", + model->B3SOIPDtoxref); + printf ("Warning: Toxref = %g is negative.\n", + model->B3SOIPDtoxref); + Fatal_Flag = 1; + } + if (model->B3SOIPDebg < 0.0) + { + fprintf (fplog, "Warning: EBG = %g is negative.\n", + model->B3SOIPDebg); + printf ("Warning: Ebg = %g is negative.\n", model->B3SOIPDebg); + } + if (model->B3SOIPDnevb < 0.0) + { + fprintf (fplog, "Warning: NEVB = %g is negative.\n", + model->B3SOIPDnevb); + printf ("Warning: Nevb = %g is negative.\n", + model->B3SOIPDnevb); + } + if (model->B3SOIPDalphaGB1 < 0.0) + { + fprintf (fplog, "Warning: ALPHAGB1 = %g is negative.\n", + model->B3SOIPDalphaGB1); + printf ("Warning: AlphaGB1 = %g is negative.\n", + model->B3SOIPDalphaGB1); + } + if (model->B3SOIPDbetaGB1 < 0.0) + { + fprintf (fplog, "Warning: BETAGB1 = %g is negative.\n", + model->B3SOIPDbetaGB1); + printf ("Warning: BetaGB1 = %g is negative.\n", + model->B3SOIPDbetaGB1); + } + if (model->B3SOIPDvgb1 < 0.0) + { + fprintf (fplog, "Warning: VGB1 = %g is negative.\n", + model->B3SOIPDvgb1); + printf ("Warning: Vgb1 = %g is negative.\n", + model->B3SOIPDvgb1); + } + if (model->B3SOIPDnecb < 0.0) + { + fprintf (fplog, "Warning: NECB = %g is negative.\n", + model->B3SOIPDnecb); + printf ("Warning: Necb = %g is negative.\n", + model->B3SOIPDnecb); + } + if (model->B3SOIPDalphaGB2 < 0.0) + { + fprintf (fplog, "Warning: ALPHAGB2 = %g is negative.\n", + model->B3SOIPDalphaGB2); + printf ("Warning: AlphaGB2 = %g is negative.\n", + model->B3SOIPDalphaGB2); + } + if (model->B3SOIPDbetaGB2 < 0.0) + { + fprintf (fplog, "Warning: BETAGB2 = %g is negative.\n", + model->B3SOIPDbetaGB2); + printf ("Warning: BetaGB2 = %g is negative.\n", + model->B3SOIPDbetaGB2); + } + if (model->B3SOIPDvgb2 < 0.0) + { + fprintf (fplog, "Warning: VGB2 = %g is negative.\n", + model->B3SOIPDvgb2); + printf ("Warning: Vgb2 = %g is negative.\n", + model->B3SOIPDvgb2); + } + if (model->B3SOIPDtoxqm <= 0.0) + { + fprintf (fplog, "Fatal: Toxqm = %g is not positive.\n", + model->B3SOIPDtoxqm); + printf ("Fatal: Toxqm = %g is not positive.\n", + model->B3SOIPDtoxqm); + Fatal_Flag = 1; + } + if (model->B3SOIPDvoxh < 0.0) + { + fprintf (fplog, "Warning: Voxh = %g is negative.\n", + model->B3SOIPDvoxh); + printf ("Warning: Voxh = %g is negative.\n", + model->B3SOIPDvoxh); + } + if (model->B3SOIPDdeltavox <= 0.0) + { + fprintf (fplog, "Fatal: Deltavox = %g is not positive.\n", + model->B3SOIPDdeltavox); + printf ("Fatal: Deltavox = %g is not positive.\n", + model->B3SOIPDdeltavox); + } + + +/* v2.0 release */ + if (model->B3SOIPDk1w1 < 0.0) + { + fprintf (fplog, "Warning: K1W1 = %g is negative.\n", + model->B3SOIPDk1w1); + printf ("Warning: K1w1 = %g is negative.\n", + model->B3SOIPDk1w1); + } + if (model->B3SOIPDk1w2 < 0.0) + { + fprintf (fplog, "Warning: K1W2 = %g is negative.\n", + model->B3SOIPDk1w2); + printf ("Warning: K1w2 = %g is negative.\n", + model->B3SOIPDk1w2); + } + if (model->B3SOIPDketas < 0.0) + { + fprintf (fplog, "Warning: KETAS = %g is negative.\n", + model->B3SOIPDketas); + printf ("Warning: Ketas = %g is negative.\n", + model->B3SOIPDketas); + } + if (model->B3SOIPDdwbc < 0.0) + { + fprintf (fplog, "Warning: DWBC = %g is negative.\n", + model->B3SOIPDdwbc); + printf ("Warning: Dwbc = %g is negative.\n", + model->B3SOIPDdwbc); + } + if (model->B3SOIPDbeta0 < 0.0) + { + fprintf (fplog, "Warning: BETA0 = %g is negative.\n", + model->B3SOIPDbeta0); + printf ("Warning: Beta0 = %g is negative.\n", + model->B3SOIPDbeta0); + } + if (model->B3SOIPDbeta1 < 0.0) + { + fprintf (fplog, "Warning: BETA1 = %g is negative.\n", + model->B3SOIPDbeta1); + printf ("Warning: Beta1 = %g is negative.\n", + model->B3SOIPDbeta1); + } + if (model->B3SOIPDbeta2 < 0.0) + { + fprintf (fplog, "Warning: BETA2 = %g is negative.\n", + model->B3SOIPDbeta2); + printf ("Warning: Beta2 = %g is negative.\n", + model->B3SOIPDbeta2); + } + if (model->B3SOIPDtii < 0.0) + { + fprintf (fplog, "Warning: TII = %g is negative.\n", + model->B3SOIPDtii); + printf ("Warning: Tii = %g is negative.\n", model->B3SOIPDtii); + } + if (model->B3SOIPDlii < 0.0) + { + fprintf (fplog, "Warning: LII = %g is negative.\n", + model->B3SOIPDlii); + printf ("Warning: Lii = %g is negative.\n", model->B3SOIPDlii); + } + if (model->B3SOIPDsii1 < 0.0) + { + fprintf (fplog, "Warning: SII1 = %g is negative.\n", + model->B3SOIPDsii1); + printf ("Warning: Sii1 = %g is negative.\n", + model->B3SOIPDsii1); + } + if (model->B3SOIPDsii2 < 0.0) + { + fprintf (fplog, "Warning: SII2 = %g is negative.\n", + model->B3SOIPDsii2); + printf ("Warning: Sii2 = %g is negative.\n", + model->B3SOIPDsii1); + } + if (model->B3SOIPDsiid < 0.0) + { + fprintf (fplog, "Warning: SIID = %g is negative.\n", + model->B3SOIPDsiid); + printf ("Warning: Siid = %g is negative.\n", + model->B3SOIPDsiid); + } + if (model->B3SOIPDfbjtii < 0.0) + { + fprintf (fplog, "Warning: FBJTII = %g is negative.\n", + model->B3SOIPDfbjtii); + printf ("Warning: fbjtii = %g is negative.\n", + model->B3SOIPDfbjtii); + } + if (model->B3SOIPDvrec0 < 0.0) + { + fprintf (fplog, "Warning: VREC0 = %g is negative.\n", + model->B3SOIPDvrec0); + printf ("Warning: Vrec0 = %g is negative.\n", + model->B3SOIPDvrec0); + } + if (model->B3SOIPDvtun0 < 0.0) + { + fprintf (fplog, "Warning: VTUN0 = %g is negative.\n", + model->B3SOIPDvtun0); + printf ("Warning: Vtun0 = %g is negative.\n", + model->B3SOIPDvtun0); + } + if (model->B3SOIPDnbjt < 0.0) + { + fprintf (fplog, "Warning: NBJT = %g is negative.\n", + model->B3SOIPDnbjt); + printf ("Warning: Nbjt = %g is negative.\n", + model->B3SOIPDnbjt); + } + if (model->B3SOIPDaely < 0.0) + { + fprintf (fplog, "Warning: AELY = %g is negative.\n", + model->B3SOIPDaely); + printf ("Warning: Aely = %g is negative.\n", + model->B3SOIPDaely); + } + if (model->B3SOIPDahli < 0.0) + { + fprintf (fplog, "Warning: AHLI = %g is negative.\n", + model->B3SOIPDahli); + printf ("Warning: Ahli = %g is negative.\n", + model->B3SOIPDahli); + } + if (model->B3SOIPDrbody < 0.0) + { + fprintf (fplog, "Warning: RBODY = %g is negative.\n", + model->B3SOIPDrbody); + printf ("Warning: Rbody = %g is negative.\n", + model->B3SOIPDrbody); + } + if (model->B3SOIPDrbsh < 0.0) + { + fprintf (fplog, "Warning: RBSH = %g is negative.\n", + model->B3SOIPDrbsh); + printf ("Warning: Rbsh = %g is negative.\n", + model->B3SOIPDrbsh); + } + if (model->B3SOIPDntrecf < 0.0) + { + fprintf (fplog, "Warning: NTRECF = %g is negative.\n", + model->B3SOIPDntrecf); + printf ("Warning: Ntrecf = %g is negative.\n", + model->B3SOIPDntrecf); + } + if (model->B3SOIPDntrecr < 0.0) + { + fprintf (fplog, "Warning: NTRECR = %g is negative.\n", + model->B3SOIPDntrecr); + printf ("Warning: Ntrecr = %g is negative.\n", + model->B3SOIPDntrecr); + } + if (model->B3SOIPDndif < 0.0) + { + fprintf (fplog, "Warning: NDIF = %g is negative.\n", + model->B3SOIPDndif); + printf ("Warning: Ndif = %g is negative.\n", + model->B3SOIPDndif); + } + if (model->B3SOIPDtcjswg < 0.0) + { + fprintf (fplog, "Warning: TCJSWG = %g is negative.\n", + model->B3SOIPDtcjswg); + printf ("Warning: Tcjswg = %g is negative.\n", + model->B3SOIPDtcjswg); + } + if (model->B3SOIPDtpbswg < 0.0) + { + fprintf (fplog, "Warning: TPBSWG = %g is negative.\n", + model->B3SOIPDtpbswg); + printf ("Warning: Tpbswg = %g is negative.\n", + model->B3SOIPDtpbswg); + } + if ((model->B3SOIPDacde < 0.4) || (model->B3SOIPDacde > 1.6)) + { + fprintf (fplog, "Warning: ACDE = %g is out of range.\n", + model->B3SOIPDacde); + printf ("Warning: Acde = %g is out of range.\n", + model->B3SOIPDacde); + } + if ((model->B3SOIPDmoin < 5.0) || (model->B3SOIPDmoin > 25.0)) + { + fprintf (fplog, "Warning: MOIN = %g is out of range.\n", + model->B3SOIPDmoin); + printf ("Warning: Moin = %g is out of range.\n", + model->B3SOIPDmoin); + } + if (model->B3SOIPDdlbg < 0.0) + { + fprintf (fplog, "Warning: DLBG = %g is negative.\n", + model->B3SOIPDdlbg); + printf ("Warning: dlbg = %g is negative.\n", + model->B3SOIPDdlbg); + } + + + if (model->B3SOIPDagidl < 0.0) + { + fprintf (fplog, "Warning: AGIDL = %g is negative.\n", + model->B3SOIPDagidl); + printf ("Warning: Agidl = %g is negative.\n", + model->B3SOIPDagidl); + } + if (model->B3SOIPDbgidl < 0.0) + { + fprintf (fplog, "Warning: BGIDL = %g is negative.\n", + model->B3SOIPDbgidl); + printf ("Warning: Bgidl = %g is negative.\n", + model->B3SOIPDbgidl); + } + if (model->B3SOIPDngidl < 0.0) + { + fprintf (fplog, "Warning: NGIDL = %g is negative.\n", + model->B3SOIPDngidl); + printf ("Warning: Ngidl = %g is negative.\n", + model->B3SOIPDngidl); + } + if (model->B3SOIPDesatii < 0.0) + { + fprintf (fplog, + "Warning: Esatii = %g should be within positive.\n", + model->B3SOIPDesatii); + printf ("Warning: Esatii = %g should be within (0, 1).\n", + model->B3SOIPDesatii); + } + + + if (model->B3SOIPDxj > model->B3SOIPDtsi) + { + fprintf (fplog, "Warning: Xj = %g is thicker than Tsi = %g.\n", + model->B3SOIPDxj, model->B3SOIPDtsi); + printf ("Warning: Xj = %g is thicker than Tsi = %g.\n", + model->B3SOIPDxj, model->B3SOIPDtsi); + } + + if (model->B3SOIPDcapMod < 2) + { + fprintf (fplog, + "Warning: capMod < 2 is not supported by BSIM3SOI.\n"); + printf + ("Warning: Warning: capMod < 2 is not supported by BSIM3SOI.\n"); + } + + } /* loop for the parameter check for warning messages */ + fclose (fplog); + } + else + { + fprintf (stderr, + "Warning: Can't open log file. Parameter checking skipped.\n"); + } + + return (Fatal_Flag); +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdcvtest.c b/src/spicelib/devices/bsim3soi_pd/b3soipdcvtest.c new file mode 100644 index 000000000..c07ea73f0 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdcvtest.c @@ -0,0 +1,95 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipdcvtest.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "b3soipddef.h" +#include "trandefs.h" +#include "const.h" +#include "devdefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIPDconvTest (inModel, ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + B3SOIPDmodel *model = (B3SOIPDmodel *) inModel; + B3SOIPDinstance *here; + double delvbd, delvbs, delvds, delvgd, delvgs, vbd, vbs, vds; + double cbd, cbhat, cbs, cd, cdhat, tol, vgd, vgdo, vgs; + + /* loop through all the B3SOIPD device models */ + for (; model != NULL; model = model->B3SOIPDnextModel) + { /* loop through all the instances of the model */ + for (here = model->B3SOIPDinstances; here != NULL; + here = here->B3SOIPDnextInstance) + { + vbs = model->B3SOIPDtype + * (*(ckt->CKTrhsOld + here->B3SOIPDbNode) + - *(ckt->CKTrhsOld + here->B3SOIPDsNodePrime)); + vgs = model->B3SOIPDtype + * (*(ckt->CKTrhsOld + here->B3SOIPDgNode) + - *(ckt->CKTrhsOld + here->B3SOIPDsNodePrime)); + vds = model->B3SOIPDtype + * (*(ckt->CKTrhsOld + here->B3SOIPDdNodePrime) + - *(ckt->CKTrhsOld + here->B3SOIPDsNodePrime)); + vbd = vbs - vds; + vgd = vgs - vds; + vgdo = *(ckt->CKTstate0 + here->B3SOIPDvgs) + - *(ckt->CKTstate0 + here->B3SOIPDvds); + delvbs = vbs - *(ckt->CKTstate0 + here->B3SOIPDvbs); + delvbd = vbd - *(ckt->CKTstate0 + here->B3SOIPDvbd); + delvgs = vgs - *(ckt->CKTstate0 + here->B3SOIPDvgs); + delvds = vds - *(ckt->CKTstate0 + here->B3SOIPDvds); + delvgd = vgd - vgdo; + + cd = here->B3SOIPDcd; + if (here->B3SOIPDmode >= 0) + { + cdhat = cd - here->B3SOIPDgjdb * delvbd + + here->B3SOIPDgmbs * delvbs + here->B3SOIPDgm * delvgs + + here->B3SOIPDgds * delvds; + } + else + { + cdhat = cd - (here->B3SOIPDgjdb - here->B3SOIPDgmbs) * delvbd + - here->B3SOIPDgm * delvgd + here->B3SOIPDgds * delvds; + } + + /* + * check convergence + */ + if ((here->B3SOIPDoff == 0) || (!(ckt->CKTmode & MODEINITFIX))) + { + tol = ckt->CKTreltol * MAX (fabs (cdhat), fabs (cd)) + + ckt->CKTabstol; + if (fabs (cdhat - cd) >= tol) + { + ckt->CKTnoncon++; + return (OK); + } + cbs = here->B3SOIPDcjs; + cbd = here->B3SOIPDcjd; + cbhat = cbs + cbd + here->B3SOIPDgjdb * delvbd + + here->B3SOIPDgjsb * delvbs; + tol = ckt->CKTreltol * MAX (fabs (cbhat), fabs (cbs + cbd)) + + ckt->CKTabstol; + if (fabs (cbhat - (cbs + cbd)) > tol) + { + ckt->CKTnoncon++; + return (OK); + } + } + } + } + return (OK); +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipddef.h b/src/spicelib/devices/bsim3soi_pd/b3soipddef.h new file mode 100644 index 000000000..608e967d9 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipddef.h @@ -0,0 +1,2185 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung +File: b3soipddef.h +Modified by Pin Su and Jan Feng 99/2/15 +Modified by Pin Su 99/4/30 +Modified by Pin Su and Wei Jin 99/9/27 +Modified by Pin Su 00/3/1 +**********/ + +#ifndef B3SOIPD +#define B3SOIPD + +#define SOICODE +/* #define BULKCODE */ + +#include "ifsim.h" +#include "gendefs.h" +#include "cktdefs.h" +#include "complex.h" +#include "noisedef.h" + +typedef struct sB3SOIPDinstance +{ + struct sB3SOIPDmodel *B3SOIPDmodPtr; + struct sB3SOIPDinstance *B3SOIPDnextInstance; + IFuid B3SOIPDname; + int B3SOIPDstates; /* index into state table for this device */ + int B3SOIPDowner; + int B3SOIPDdNode; + int B3SOIPDgNode; + int B3SOIPDsNode; + int B3SOIPDeNode; + int B3SOIPDpNode; + int B3SOIPDbNode; + int B3SOIPDtempNode; + int B3SOIPDdNodePrime; + int B3SOIPDsNodePrime; + + int B3SOIPDvbsNode; + /* for Debug */ + int B3SOIPDidsNode; + int B3SOIPDicNode; + int B3SOIPDibsNode; + int B3SOIPDibdNode; + int B3SOIPDiiiNode; + int B3SOIPDigNode; + int B3SOIPDgiggNode; + int B3SOIPDgigdNode; + int B3SOIPDgigbNode; + int B3SOIPDigidlNode; + int B3SOIPDitunNode; + int B3SOIPDibpNode; + int B3SOIPDcbbNode; + int B3SOIPDcbdNode; + int B3SOIPDcbgNode; + + int B3SOIPDqbfNode; + int B3SOIPDqjsNode; + int B3SOIPDqjdNode; + + + double B3SOIPDphi; + double B3SOIPDvtm; + double B3SOIPDni; + double B3SOIPDueff; + double B3SOIPDthetavth; + double B3SOIPDvon; + double B3SOIPDvdsat; + double B3SOIPDcgdo; + double B3SOIPDcgso; + double B3SOIPDcgeo; + + double B3SOIPDids; + double B3SOIPDic; + double B3SOIPDibs; + double B3SOIPDibd; + double B3SOIPDiii; + double B3SOIPDig; + double B3SOIPDgigg; + double B3SOIPDgigd; + double B3SOIPDgigb; + double B3SOIPDigidl; + double B3SOIPDitun; + double B3SOIPDibp; + double B3SOIPDabeff; + double B3SOIPDvbseff; + double B3SOIPDcbg; + double B3SOIPDcbb; + double B3SOIPDcbs; /* XXX PN */ + double B3SOIPDcbd; + double B3SOIPDqb; + double B3SOIPDqbf; + double B3SOIPDqjs; + double B3SOIPDqjd; + int B3SOIPDfloat; + + + double B3SOIPDl; + double B3SOIPDw; + double B3SOIPDdrainArea; + double B3SOIPDsourceArea; + double B3SOIPDdrainSquares; + double B3SOIPDsourceSquares; + double B3SOIPDdrainPerimeter; + double B3SOIPDsourcePerimeter; + double B3SOIPDsourceConductance; + double B3SOIPDdrainConductance; + + double B3SOIPDicVBS; + double B3SOIPDicVDS; + double B3SOIPDicVGS; + double B3SOIPDicVES; + double B3SOIPDicVPS; + int B3SOIPDbjtoff; + int B3SOIPDbodyMod; + int B3SOIPDdebugMod; + double B3SOIPDrth0; + double B3SOIPDcth0; + double B3SOIPDbodySquares; + double B3SOIPDrbodyext; + + +/* v2.0 release */ + double B3SOIPDnbc; + double B3SOIPDnseg; + double B3SOIPDpdbcp; + double B3SOIPDpsbcp; + double B3SOIPDagbcp; + double B3SOIPDaebcp; + double B3SOIPDvbsusr; + int B3SOIPDtnodeout; + +/* Deleted from pParam and moved to here */ + double B3SOIPDcsbox; + double B3SOIPDcdbox; + double B3SOIPDcsmin; + double B3SOIPDcdmin; + double B3SOIPDst4; + double B3SOIPDdt4; + + int B3SOIPDoff; + int B3SOIPDmode; + + /* OP point */ + double B3SOIPDqinv; + double B3SOIPDcd; + double B3SOIPDcjs; + double B3SOIPDcjd; + double B3SOIPDcbody; +/* v2.2 release */ + double B3SOIPDcgate; + double B3SOIPDgigs; + double B3SOIPDgigT; + + double B3SOIPDcbodcon; + double B3SOIPDcth; + double B3SOIPDcsubstrate; + + double B3SOIPDgm; + double B3SOIPDcb; + double B3SOIPDcdrain; + double B3SOIPDgds; + double B3SOIPDgmbs; + double B3SOIPDgmT; + + double B3SOIPDgbbs; + double B3SOIPDgbgs; + double B3SOIPDgbds; + double B3SOIPDgbps; + double B3SOIPDgbT; + + double B3SOIPDgjsd; + double B3SOIPDgjsb; + double B3SOIPDgjsg; + double B3SOIPDgjsT; + + double B3SOIPDgjdb; + double B3SOIPDgjdd; + double B3SOIPDgjdg; + double B3SOIPDgjdT; + + double B3SOIPDgbpbs; + double B3SOIPDgbpps; + double B3SOIPDgbpT; + + double B3SOIPDgtempb; + double B3SOIPDgtempg; + double B3SOIPDgtempd; + double B3SOIPDgtempT; + + double B3SOIPDcggb; + double B3SOIPDcgdb; + double B3SOIPDcgsb; + double B3SOIPDcgT; + + double B3SOIPDcbgb; + double B3SOIPDcbdb; + double B3SOIPDcbsb; + double B3SOIPDcbeb; + double B3SOIPDcbT; + + double B3SOIPDcdgb; + double B3SOIPDcddb; + double B3SOIPDcdsb; + double B3SOIPDcdeb; + double B3SOIPDcdT; + + double B3SOIPDceeb; + double B3SOIPDceT; + + double B3SOIPDqse; + double B3SOIPDgcse; + double B3SOIPDqde; + double B3SOIPDgcde; + + struct b3soipdSizeDependParam *pParam; + + unsigned B3SOIPDlGiven:1; + unsigned B3SOIPDwGiven:1; + unsigned B3SOIPDdrainAreaGiven:1; + unsigned B3SOIPDsourceAreaGiven:1; + unsigned B3SOIPDdrainSquaresGiven:1; + unsigned B3SOIPDsourceSquaresGiven:1; + unsigned B3SOIPDdrainPerimeterGiven:1; + unsigned B3SOIPDsourcePerimeterGiven:1; + unsigned B3SOIPDdNodePrimeSet:1; + unsigned B3SOIPDsNodePrimeSet:1; + unsigned B3SOIPDicVBSGiven:1; + unsigned B3SOIPDicVDSGiven:1; + unsigned B3SOIPDicVGSGiven:1; + unsigned B3SOIPDicVESGiven:1; + unsigned B3SOIPDicVPSGiven:1; + unsigned B3SOIPDbjtoffGiven:1; + unsigned B3SOIPDdebugModGiven:1; + unsigned B3SOIPDrth0Given:1; + unsigned B3SOIPDcth0Given:1; + unsigned B3SOIPDbodySquaresGiven:1; + + +/* v2.0 release */ + unsigned B3SOIPDnbcGiven:1; + unsigned B3SOIPDnsegGiven:1; + unsigned B3SOIPDpdbcpGiven:1; + unsigned B3SOIPDpsbcpGiven:1; + unsigned B3SOIPDagbcpGiven:1; + unsigned B3SOIPDaebcpGiven:1; + unsigned B3SOIPDvbsusrGiven:1; + unsigned B3SOIPDtnodeoutGiven:1; + unsigned B3SOIPDoffGiven:1; + + double *B3SOIPDGePtr; + double *B3SOIPDDPePtr; + double *B3SOIPDSPePtr; + + double *B3SOIPDEePtr; + double *B3SOIPDEbPtr; + double *B3SOIPDBePtr; + double *B3SOIPDEgPtr; + double *B3SOIPDEdpPtr; + double *B3SOIPDEspPtr; + double *B3SOIPDTemptempPtr; + double *B3SOIPDTempdpPtr; + double *B3SOIPDTempspPtr; + double *B3SOIPDTempgPtr; + double *B3SOIPDTempbPtr; + double *B3SOIPDGtempPtr; + double *B3SOIPDDPtempPtr; + double *B3SOIPDSPtempPtr; + double *B3SOIPDEtempPtr; + double *B3SOIPDBtempPtr; + double *B3SOIPDPtempPtr; + double *B3SOIPDBpPtr; + double *B3SOIPDPbPtr; + double *B3SOIPDPpPtr; + double *B3SOIPDDdPtr; + double *B3SOIPDGgPtr; + double *B3SOIPDSsPtr; + double *B3SOIPDBbPtr; + double *B3SOIPDDPdpPtr; + double *B3SOIPDSPspPtr; + double *B3SOIPDDdpPtr; + double *B3SOIPDGbPtr; + double *B3SOIPDGdpPtr; + double *B3SOIPDGspPtr; + double *B3SOIPDSspPtr; + double *B3SOIPDBdpPtr; + double *B3SOIPDBspPtr; + double *B3SOIPDDPspPtr; + double *B3SOIPDDPdPtr; + double *B3SOIPDBgPtr; + double *B3SOIPDDPgPtr; + double *B3SOIPDSPgPtr; + double *B3SOIPDSPsPtr; + double *B3SOIPDDPbPtr; + double *B3SOIPDSPbPtr; + double *B3SOIPDSPdpPtr; + + double *B3SOIPDVbsPtr; + /* Debug */ + double *B3SOIPDIdsPtr; + double *B3SOIPDIcPtr; + double *B3SOIPDIbsPtr; + double *B3SOIPDIbdPtr; + double *B3SOIPDIiiPtr; + double *B3SOIPDIgPtr; + double *B3SOIPDGiggPtr; + double *B3SOIPDGigdPtr; + double *B3SOIPDGigbPtr; + double *B3SOIPDIgidlPtr; + double *B3SOIPDItunPtr; + double *B3SOIPDIbpPtr; + double *B3SOIPDCbbPtr; + double *B3SOIPDCbdPtr; + double *B3SOIPDCbgPtr; + double *B3SOIPDqbPtr; + double *B3SOIPDQbfPtr; + double *B3SOIPDQjsPtr; + double *B3SOIPDQjdPtr; + + + +#define B3SOIPDvbd B3SOIPDstates+ 0 +#define B3SOIPDvbs B3SOIPDstates+ 1 +#define B3SOIPDvgs B3SOIPDstates+ 2 +#define B3SOIPDvds B3SOIPDstates+ 3 +#define B3SOIPDves B3SOIPDstates+ 4 +#define B3SOIPDvps B3SOIPDstates+ 5 + +#define B3SOIPDvg B3SOIPDstates+ 6 +#define B3SOIPDvd B3SOIPDstates+ 7 +#define B3SOIPDvs B3SOIPDstates+ 8 +#define B3SOIPDvp B3SOIPDstates+ 9 +#define B3SOIPDve B3SOIPDstates+ 10 +#define B3SOIPDdeltemp B3SOIPDstates+ 11 + +#define B3SOIPDqb B3SOIPDstates+ 12 +#define B3SOIPDcqb B3SOIPDstates+ 13 +#define B3SOIPDqg B3SOIPDstates+ 14 +#define B3SOIPDcqg B3SOIPDstates+ 15 +#define B3SOIPDqd B3SOIPDstates+ 16 +#define B3SOIPDcqd B3SOIPDstates+ 17 +#define B3SOIPDqe B3SOIPDstates+ 18 +#define B3SOIPDcqe B3SOIPDstates+ 19 + +#define B3SOIPDqbs B3SOIPDstates+ 20 +#define B3SOIPDqbd B3SOIPDstates+ 21 +#define B3SOIPDqbe B3SOIPDstates+ 22 + +#define B3SOIPDqth B3SOIPDstates+ 23 +#define B3SOIPDcqth B3SOIPDstates+ 24 + +#define B3SOIPDnumStates 25 + + +/* indices to the array of B3SOIPD NOISE SOURCES */ + +#define B3SOIPDRDNOIZ 0 +#define B3SOIPDRSNOIZ 1 +#define B3SOIPDIDNOIZ 2 +#define B3SOIPDFLNOIZ 3 +#define B3SOIPDFBNOIZ 4 +#define B3SOIPDTOTNOIZ 5 + +#define B3SOIPDNSRCS 6 /* the number of MOSFET(3) noise sources */ + +#ifndef NONOISE + double B3SOIPDnVar[NSTATVARS][B3SOIPDNSRCS]; +#else /* NONOISE */ + double **B3SOIPDnVar; +#endif /* NONOISE */ + +} +B3SOIPDinstance; + +struct b3soipdSizeDependParam +{ + double Width; + double Length; + double Rth0; + double Cth0; + + double B3SOIPDcdsc; + double B3SOIPDcdscb; + double B3SOIPDcdscd; + double B3SOIPDcit; + double B3SOIPDnfactor; + double B3SOIPDvsat; + double B3SOIPDat; + double B3SOIPDa0; + double B3SOIPDags; + double B3SOIPDa1; + double B3SOIPDa2; + double B3SOIPDketa; + double B3SOIPDnpeak; + double B3SOIPDnsub; + double B3SOIPDngate; + double B3SOIPDgamma1; + double B3SOIPDgamma2; + double B3SOIPDvbx; + double B3SOIPDvbi; + double B3SOIPDvbm; + double B3SOIPDvbsc; + double B3SOIPDxt; + double B3SOIPDphi; + double B3SOIPDlitl; + double B3SOIPDk1; + double B3SOIPDkt1; + double B3SOIPDkt1l; + double B3SOIPDkt2; + double B3SOIPDk2; + double B3SOIPDk3; + double B3SOIPDk3b; + double B3SOIPDw0; + double B3SOIPDnlx; + double B3SOIPDdvt0; + double B3SOIPDdvt1; + double B3SOIPDdvt2; + double B3SOIPDdvt0w; + double B3SOIPDdvt1w; + double B3SOIPDdvt2w; + double B3SOIPDdrout; + double B3SOIPDdsub; + double B3SOIPDvth0; + double B3SOIPDua; + double B3SOIPDua1; + double B3SOIPDub; + double B3SOIPDub1; + double B3SOIPDuc; + double B3SOIPDuc1; + double B3SOIPDu0; + double B3SOIPDute; + double B3SOIPDvoff; + double B3SOIPDvfb; + double B3SOIPDuatemp; + double B3SOIPDubtemp; + double B3SOIPDuctemp; + double B3SOIPDrbody; + double B3SOIPDrth; + double B3SOIPDcth; + double B3SOIPDrds0denom; + double B3SOIPDvfbb; + double B3SOIPDjbjt; + double B3SOIPDjdif; + double B3SOIPDjrec; + double B3SOIPDjtun; + double B3SOIPDcsesw; + double B3SOIPDcdesw; + double B3SOIPDsdt1; + double B3SOIPDst2; + double B3SOIPDst3; + double B3SOIPDdt2; + double B3SOIPDdt3; + double B3SOIPDdelta; + double B3SOIPDrdsw; + double B3SOIPDrds0; + double B3SOIPDprwg; + double B3SOIPDprwb; + double B3SOIPDprt; + double B3SOIPDeta0; + double B3SOIPDetab; + double B3SOIPDpclm; + double B3SOIPDpdibl1; + double B3SOIPDpdibl2; + double B3SOIPDpdiblb; + double B3SOIPDpvag; + double B3SOIPDwr; + double B3SOIPDdwg; + double B3SOIPDdwb; + double B3SOIPDb0; + double B3SOIPDb1; + double B3SOIPDalpha0; + double B3SOIPDbeta0; + + + /* CV model */ + double B3SOIPDcgsl; + double B3SOIPDcgdl; + double B3SOIPDckappa; + double B3SOIPDcf; + double B3SOIPDclc; + double B3SOIPDcle; + +/* Added for binning - START0 */ + double B3SOIPDkb1; + double B3SOIPDk1w1; + double B3SOIPDk1w2; + double B3SOIPDketas; + double B3SOIPDfbjtii; + double B3SOIPDbeta1; + double B3SOIPDbeta2; + double B3SOIPDvdsatii0; + double B3SOIPDlii; + double B3SOIPDesatii; + double B3SOIPDsii0; + double B3SOIPDsii1; + double B3SOIPDsii2; + double B3SOIPDsiid; + double B3SOIPDagidl; + double B3SOIPDbgidl; + double B3SOIPDngidl; + double B3SOIPDntun; + double B3SOIPDndiode; + double B3SOIPDnrecf0; + double B3SOIPDnrecr0; + double B3SOIPDisbjt; + double B3SOIPDisdif; + double B3SOIPDisrec; + double B3SOIPDistun; + double B3SOIPDvrec0; + double B3SOIPDvtun0; + double B3SOIPDnbjt; + double B3SOIPDlbjt0; + double B3SOIPDvabjt; + double B3SOIPDaely; + double B3SOIPDvsdfb; + double B3SOIPDvsdth; + double B3SOIPDdelvt; +/* Added by binning - END0 */ + +/* Pre-calculated constants */ + + double B3SOIPDdw; + double B3SOIPDdl; + double B3SOIPDleff; + double B3SOIPDweff; + + double B3SOIPDdwc; + double B3SOIPDdlc; + double B3SOIPDleffCV; + double B3SOIPDweffCV; + double B3SOIPDabulkCVfactor; + double B3SOIPDcgso; + double B3SOIPDcgdo; + double B3SOIPDcgeo; + + double B3SOIPDu0temp; + double B3SOIPDvsattemp; + double B3SOIPDsqrtPhi; + double B3SOIPDphis3; + double B3SOIPDXdep0; + double B3SOIPDsqrtXdep0; + double B3SOIPDtheta0vb0; + double B3SOIPDthetaRout; + + +/* v2.2 release */ + double B3SOIPDoxideRatio; + + +/* v2.0 release */ + double B3SOIPDk1eff; + double B3SOIPDwdios; + double B3SOIPDwdiod; + double B3SOIPDwdiodCV; + double B3SOIPDwdiosCV; + double B3SOIPDarfabjt; + double B3SOIPDlratio; + double B3SOIPDlratiodif; + double B3SOIPDvearly; + double B3SOIPDahli; + double B3SOIPDvfbzb; + double B3SOIPDldeb; + double B3SOIPDacde; + double B3SOIPDmoin; + double B3SOIPDleffCVb; + double B3SOIPDleffCVbg; + + double B3SOIPDcof1; + double B3SOIPDcof2; + double B3SOIPDcof3; + double B3SOIPDcof4; + double B3SOIPDcdep0; + struct b3soipdSizeDependParam *pNext; +}; + + +typedef struct sB3SOIPDmodel +{ + int B3SOIPDmodType; + struct sB3SOIPDmodel *B3SOIPDnextModel; + B3SOIPDinstance *B3SOIPDinstances; + IFuid B3SOIPDmodName; + int B3SOIPDtype; + + int B3SOIPDmobMod; + int B3SOIPDcapMod; + int B3SOIPDnoiMod; + int B3SOIPDshMod; + int B3SOIPDbinUnit; + int B3SOIPDparamChk; + double B3SOIPDversion; + double B3SOIPDtox; + double B3SOIPDcdsc; + double B3SOIPDcdscb; + double B3SOIPDcdscd; + double B3SOIPDcit; + double B3SOIPDnfactor; + double B3SOIPDvsat; + double B3SOIPDat; + double B3SOIPDa0; + double B3SOIPDags; + double B3SOIPDa1; + double B3SOIPDa2; + double B3SOIPDketa; + double B3SOIPDnsub; + double B3SOIPDnpeak; + double B3SOIPDngate; + double B3SOIPDgamma1; + double B3SOIPDgamma2; + double B3SOIPDvbx; + double B3SOIPDvbm; + double B3SOIPDxt; + double B3SOIPDk1; + double B3SOIPDkt1; + double B3SOIPDkt1l; + double B3SOIPDkt2; + double B3SOIPDk2; + double B3SOIPDk3; + double B3SOIPDk3b; + double B3SOIPDw0; + double B3SOIPDnlx; + double B3SOIPDdvt0; + double B3SOIPDdvt1; + double B3SOIPDdvt2; + double B3SOIPDdvt0w; + double B3SOIPDdvt1w; + double B3SOIPDdvt2w; + double B3SOIPDdrout; + double B3SOIPDdsub; + double B3SOIPDvth0; + double B3SOIPDua; + double B3SOIPDua1; + double B3SOIPDub; + double B3SOIPDub1; + double B3SOIPDuc; + double B3SOIPDuc1; + double B3SOIPDu0; + double B3SOIPDute; + double B3SOIPDvoff; + double B3SOIPDdelta; + double B3SOIPDrdsw; + double B3SOIPDprwg; + double B3SOIPDprwb; + double B3SOIPDprt; + double B3SOIPDeta0; + double B3SOIPDetab; + double B3SOIPDpclm; + double B3SOIPDpdibl1; + double B3SOIPDpdibl2; + double B3SOIPDpdiblb; + double B3SOIPDpvag; + double B3SOIPDwr; + double B3SOIPDdwg; + double B3SOIPDdwb; + double B3SOIPDb0; + double B3SOIPDb1; + double B3SOIPDalpha0; + double B3SOIPDtbox; + double B3SOIPDtsi; + double B3SOIPDxj; + double B3SOIPDkb1; + double B3SOIPDrth0; + double B3SOIPDcth0; + double B3SOIPDngidl; + double B3SOIPDagidl; + double B3SOIPDbgidl; + double B3SOIPDndiode; + double B3SOIPDistun; + double B3SOIPDxbjt; + double B3SOIPDxdif; + double B3SOIPDxrec; + double B3SOIPDxtun; + + +/* v2.2 release */ + double B3SOIPDwth0; + double B3SOIPDrhalo; + double B3SOIPDntox; + double B3SOIPDtoxref; + double B3SOIPDebg; + double B3SOIPDnevb; + double B3SOIPDalphaGB1; + double B3SOIPDbetaGB1; + double B3SOIPDvgb1; + double B3SOIPDnecb; + double B3SOIPDalphaGB2; + double B3SOIPDbetaGB2; + double B3SOIPDvgb2; + double B3SOIPDtoxqm; + double B3SOIPDvoxh; + double B3SOIPDdeltavox; + int B3SOIPDigMod; + + +/* v2.0 release */ + double B3SOIPDk1w1; + double B3SOIPDk1w2; + double B3SOIPDketas; + double B3SOIPDdwbc; + double B3SOIPDbeta0; + double B3SOIPDbeta1; + double B3SOIPDbeta2; + double B3SOIPDvdsatii0; + double B3SOIPDtii; + double B3SOIPDlii; + double B3SOIPDsii0; + double B3SOIPDsii1; + double B3SOIPDsii2; + double B3SOIPDsiid; + double B3SOIPDfbjtii; + double B3SOIPDesatii; + double B3SOIPDntun; + double B3SOIPDnrecf0; + double B3SOIPDnrecr0; + double B3SOIPDisbjt; + double B3SOIPDisdif; + double B3SOIPDisrec; + double B3SOIPDln; + double B3SOIPDvrec0; + double B3SOIPDvtun0; + double B3SOIPDnbjt; + double B3SOIPDlbjt0; + double B3SOIPDldif0; + double B3SOIPDvabjt; + double B3SOIPDaely; + double B3SOIPDahli; + double B3SOIPDrbody; + double B3SOIPDrbsh; + double B3SOIPDtt; + double B3SOIPDndif; + double B3SOIPDvsdfb; + double B3SOIPDvsdth; + double B3SOIPDcsdmin; + double B3SOIPDasd; + double B3SOIPDntrecf; + double B3SOIPDntrecr; + double B3SOIPDdlcb; + double B3SOIPDfbody; + double B3SOIPDtcjswg; + double B3SOIPDtpbswg; + double B3SOIPDacde; + double B3SOIPDmoin; + double B3SOIPDdelvt; + double B3SOIPDdlbg; + + /* CV model */ + double B3SOIPDcgsl; + double B3SOIPDcgdl; + double B3SOIPDckappa; + double B3SOIPDcf; + double B3SOIPDclc; + double B3SOIPDcle; + double B3SOIPDdwc; + double B3SOIPDdlc; + + double B3SOIPDtnom; + double B3SOIPDcgso; + double B3SOIPDcgdo; + double B3SOIPDcgeo; + double B3SOIPDxpart; + double B3SOIPDcFringOut; + double B3SOIPDcFringMax; + + double B3SOIPDsheetResistance; + double B3SOIPDbodyJctGateSideGradingCoeff; + double B3SOIPDGatesidewallJctPotential; + double B3SOIPDunitLengthGateSidewallJctCap; + double B3SOIPDcsdesw; + + double B3SOIPDLint; + double B3SOIPDLl; + double B3SOIPDLln; + double B3SOIPDLw; + double B3SOIPDLwn; + double B3SOIPDLwl; + double B3SOIPDLmin; + double B3SOIPDLmax; + + double B3SOIPDWint; + double B3SOIPDWl; + double B3SOIPDWln; + double B3SOIPDWw; + double B3SOIPDWwn; + double B3SOIPDWwl; + double B3SOIPDWmin; + double B3SOIPDWmax; + +/* Added for binning - START1 */ + /* Length Dependence */ + double B3SOIPDlnpeak; + double B3SOIPDlnsub; + double B3SOIPDlngate; + double B3SOIPDlvth0; + double B3SOIPDlk1; + double B3SOIPDlk1w1; + double B3SOIPDlk1w2; + double B3SOIPDlk2; + double B3SOIPDlk3; + double B3SOIPDlk3b; + double B3SOIPDlkb1; + double B3SOIPDlw0; + double B3SOIPDlnlx; + double B3SOIPDldvt0; + double B3SOIPDldvt1; + double B3SOIPDldvt2; + double B3SOIPDldvt0w; + double B3SOIPDldvt1w; + double B3SOIPDldvt2w; + double B3SOIPDlu0; + double B3SOIPDlua; + double B3SOIPDlub; + double B3SOIPDluc; + double B3SOIPDlvsat; + double B3SOIPDla0; + double B3SOIPDlags; + double B3SOIPDlb0; + double B3SOIPDlb1; + double B3SOIPDlketa; + double B3SOIPDlketas; + double B3SOIPDla1; + double B3SOIPDla2; + double B3SOIPDlrdsw; + double B3SOIPDlprwb; + double B3SOIPDlprwg; + double B3SOIPDlwr; + double B3SOIPDlnfactor; + double B3SOIPDldwg; + double B3SOIPDldwb; + double B3SOIPDlvoff; + double B3SOIPDleta0; + double B3SOIPDletab; + double B3SOIPDldsub; + double B3SOIPDlcit; + double B3SOIPDlcdsc; + double B3SOIPDlcdscb; + double B3SOIPDlcdscd; + double B3SOIPDlpclm; + double B3SOIPDlpdibl1; + double B3SOIPDlpdibl2; + double B3SOIPDlpdiblb; + double B3SOIPDldrout; + double B3SOIPDlpvag; + double B3SOIPDldelta; + double B3SOIPDlalpha0; + double B3SOIPDlfbjtii; + double B3SOIPDlbeta0; + double B3SOIPDlbeta1; + double B3SOIPDlbeta2; + double B3SOIPDlvdsatii0; + double B3SOIPDllii; + double B3SOIPDlesatii; + double B3SOIPDlsii0; + double B3SOIPDlsii1; + double B3SOIPDlsii2; + double B3SOIPDlsiid; + double B3SOIPDlagidl; + double B3SOIPDlbgidl; + double B3SOIPDlngidl; + double B3SOIPDlntun; + double B3SOIPDlndiode; + double B3SOIPDlnrecf0; + double B3SOIPDlnrecr0; + double B3SOIPDlisbjt; + double B3SOIPDlisdif; + double B3SOIPDlisrec; + double B3SOIPDlistun; + double B3SOIPDlvrec0; + double B3SOIPDlvtun0; + double B3SOIPDlnbjt; + double B3SOIPDllbjt0; + double B3SOIPDlvabjt; + double B3SOIPDlaely; + double B3SOIPDlahli; + /* CV model */ + double B3SOIPDlvsdfb; + double B3SOIPDlvsdth; + double B3SOIPDldelvt; + double B3SOIPDlacde; + double B3SOIPDlmoin; + + /* Width Dependence */ + double B3SOIPDwnpeak; + double B3SOIPDwnsub; + double B3SOIPDwngate; + double B3SOIPDwvth0; + double B3SOIPDwk1; + double B3SOIPDwk1w1; + double B3SOIPDwk1w2; + double B3SOIPDwk2; + double B3SOIPDwk3; + double B3SOIPDwk3b; + double B3SOIPDwkb1; + double B3SOIPDww0; + double B3SOIPDwnlx; + double B3SOIPDwdvt0; + double B3SOIPDwdvt1; + double B3SOIPDwdvt2; + double B3SOIPDwdvt0w; + double B3SOIPDwdvt1w; + double B3SOIPDwdvt2w; + double B3SOIPDwu0; + double B3SOIPDwua; + double B3SOIPDwub; + double B3SOIPDwuc; + double B3SOIPDwvsat; + double B3SOIPDwa0; + double B3SOIPDwags; + double B3SOIPDwb0; + double B3SOIPDwb1; + double B3SOIPDwketa; + double B3SOIPDwketas; + double B3SOIPDwa1; + double B3SOIPDwa2; + double B3SOIPDwrdsw; + double B3SOIPDwprwb; + double B3SOIPDwprwg; + double B3SOIPDwwr; + double B3SOIPDwnfactor; + double B3SOIPDwdwg; + double B3SOIPDwdwb; + double B3SOIPDwvoff; + double B3SOIPDweta0; + double B3SOIPDwetab; + double B3SOIPDwdsub; + double B3SOIPDwcit; + double B3SOIPDwcdsc; + double B3SOIPDwcdscb; + double B3SOIPDwcdscd; + double B3SOIPDwpclm; + double B3SOIPDwpdibl1; + double B3SOIPDwpdibl2; + double B3SOIPDwpdiblb; + double B3SOIPDwdrout; + double B3SOIPDwpvag; + double B3SOIPDwdelta; + double B3SOIPDwalpha0; + double B3SOIPDwfbjtii; + double B3SOIPDwbeta0; + double B3SOIPDwbeta1; + double B3SOIPDwbeta2; + double B3SOIPDwvdsatii0; + double B3SOIPDwlii; + double B3SOIPDwesatii; + double B3SOIPDwsii0; + double B3SOIPDwsii1; + double B3SOIPDwsii2; + double B3SOIPDwsiid; + double B3SOIPDwagidl; + double B3SOIPDwbgidl; + double B3SOIPDwngidl; + double B3SOIPDwntun; + double B3SOIPDwndiode; + double B3SOIPDwnrecf0; + double B3SOIPDwnrecr0; + double B3SOIPDwisbjt; + double B3SOIPDwisdif; + double B3SOIPDwisrec; + double B3SOIPDwistun; + double B3SOIPDwvrec0; + double B3SOIPDwvtun0; + double B3SOIPDwnbjt; + double B3SOIPDwlbjt0; + double B3SOIPDwvabjt; + double B3SOIPDwaely; + double B3SOIPDwahli; + /* CV model */ + double B3SOIPDwvsdfb; + double B3SOIPDwvsdth; + double B3SOIPDwdelvt; + double B3SOIPDwacde; + double B3SOIPDwmoin; + + /* Cross-term Dependence */ + double B3SOIPDpnpeak; + double B3SOIPDpnsub; + double B3SOIPDpngate; + double B3SOIPDpvth0; + double B3SOIPDpk1; + double B3SOIPDpk1w1; + double B3SOIPDpk1w2; + double B3SOIPDpk2; + double B3SOIPDpk3; + double B3SOIPDpk3b; + double B3SOIPDpkb1; + double B3SOIPDpw0; + double B3SOIPDpnlx; + double B3SOIPDpdvt0; + double B3SOIPDpdvt1; + double B3SOIPDpdvt2; + double B3SOIPDpdvt0w; + double B3SOIPDpdvt1w; + double B3SOIPDpdvt2w; + double B3SOIPDpu0; + double B3SOIPDpua; + double B3SOIPDpub; + double B3SOIPDpuc; + double B3SOIPDpvsat; + double B3SOIPDpa0; + double B3SOIPDpags; + double B3SOIPDpb0; + double B3SOIPDpb1; + double B3SOIPDpketa; + double B3SOIPDpketas; + double B3SOIPDpa1; + double B3SOIPDpa2; + double B3SOIPDprdsw; + double B3SOIPDpprwb; + double B3SOIPDpprwg; + double B3SOIPDpwr; + double B3SOIPDpnfactor; + double B3SOIPDpdwg; + double B3SOIPDpdwb; + double B3SOIPDpvoff; + double B3SOIPDpeta0; + double B3SOIPDpetab; + double B3SOIPDpdsub; + double B3SOIPDpcit; + double B3SOIPDpcdsc; + double B3SOIPDpcdscb; + double B3SOIPDpcdscd; + double B3SOIPDppclm; + double B3SOIPDppdibl1; + double B3SOIPDppdibl2; + double B3SOIPDppdiblb; + double B3SOIPDpdrout; + double B3SOIPDppvag; + double B3SOIPDpdelta; + double B3SOIPDpalpha0; + double B3SOIPDpfbjtii; + double B3SOIPDpbeta0; + double B3SOIPDpbeta1; + double B3SOIPDpbeta2; + double B3SOIPDpvdsatii0; + double B3SOIPDplii; + double B3SOIPDpesatii; + double B3SOIPDpsii0; + double B3SOIPDpsii1; + double B3SOIPDpsii2; + double B3SOIPDpsiid; + double B3SOIPDpagidl; + double B3SOIPDpbgidl; + double B3SOIPDpngidl; + double B3SOIPDpntun; + double B3SOIPDpndiode; + double B3SOIPDpnrecf0; + double B3SOIPDpnrecr0; + double B3SOIPDpisbjt; + double B3SOIPDpisdif; + double B3SOIPDpisrec; + double B3SOIPDpistun; + double B3SOIPDpvrec0; + double B3SOIPDpvtun0; + double B3SOIPDpnbjt; + double B3SOIPDplbjt0; + double B3SOIPDpvabjt; + double B3SOIPDpaely; + double B3SOIPDpahli; + /* CV model */ + double B3SOIPDpvsdfb; + double B3SOIPDpvsdth; + double B3SOIPDpdelvt; + double B3SOIPDpacde; + double B3SOIPDpmoin; +/* Added for binning - END1 */ + +/* Pre-calculated constants */ + double B3SOIPDcbox; + double B3SOIPDcsi; + double B3SOIPDcsieff; + double B3SOIPDcoxt; + double B3SOIPDnfb; + double B3SOIPDadice; + double B3SOIPDqsi; + double B3SOIPDqsieff; + double B3SOIPDeg0; + + /* MCJ: move to size-dependent param. */ + double B3SOIPDvtm; + double B3SOIPDcox; + double B3SOIPDcof1; + double B3SOIPDcof2; + double B3SOIPDcof3; + double B3SOIPDcof4; + double B3SOIPDvcrit; + double B3SOIPDfactor1; + + double B3SOIPDoxideTrapDensityA; + double B3SOIPDoxideTrapDensityB; + double B3SOIPDoxideTrapDensityC; + double B3SOIPDem; + double B3SOIPDef; + double B3SOIPDaf; + double B3SOIPDkf; + double B3SOIPDnoif; + + struct b3soipdSizeDependParam *pSizeDependParamKnot; + + /* Flags */ + + unsigned B3SOIPDtboxGiven:1; + unsigned B3SOIPDtsiGiven:1; + unsigned B3SOIPDxjGiven:1; + unsigned B3SOIPDkb1Given:1; + unsigned B3SOIPDrth0Given:1; + unsigned B3SOIPDcth0Given:1; + unsigned B3SOIPDngidlGiven:1; + unsigned B3SOIPDagidlGiven:1; + unsigned B3SOIPDbgidlGiven:1; + unsigned B3SOIPDndiodeGiven:1; + unsigned B3SOIPDxbjtGiven:1; + unsigned B3SOIPDxdifGiven:1; + unsigned B3SOIPDxrecGiven:1; + unsigned B3SOIPDxtunGiven:1; + unsigned B3SOIPDttGiven:1; + unsigned B3SOIPDvsdfbGiven:1; + unsigned B3SOIPDvsdthGiven:1; + unsigned B3SOIPDasdGiven:1; + unsigned B3SOIPDcsdminGiven:1; + + unsigned B3SOIPDmobModGiven:1; + unsigned B3SOIPDbinUnitGiven:1; + unsigned B3SOIPDcapModGiven:1; + unsigned B3SOIPDparamChkGiven:1; + unsigned B3SOIPDnoiModGiven:1; + unsigned B3SOIPDshModGiven:1; + unsigned B3SOIPDtypeGiven:1; + unsigned B3SOIPDtoxGiven:1; + unsigned B3SOIPDversionGiven:1; + + unsigned B3SOIPDcdscGiven:1; + unsigned B3SOIPDcdscbGiven:1; + unsigned B3SOIPDcdscdGiven:1; + unsigned B3SOIPDcitGiven:1; + unsigned B3SOIPDnfactorGiven:1; + unsigned B3SOIPDvsatGiven:1; + unsigned B3SOIPDatGiven:1; + unsigned B3SOIPDa0Given:1; + unsigned B3SOIPDagsGiven:1; + unsigned B3SOIPDa1Given:1; + unsigned B3SOIPDa2Given:1; + unsigned B3SOIPDketaGiven:1; + unsigned B3SOIPDnsubGiven:1; + unsigned B3SOIPDnpeakGiven:1; + unsigned B3SOIPDngateGiven:1; + unsigned B3SOIPDgamma1Given:1; + unsigned B3SOIPDgamma2Given:1; + unsigned B3SOIPDvbxGiven:1; + unsigned B3SOIPDvbmGiven:1; + unsigned B3SOIPDxtGiven:1; + unsigned B3SOIPDk1Given:1; + unsigned B3SOIPDkt1Given:1; + unsigned B3SOIPDkt1lGiven:1; + unsigned B3SOIPDkt2Given:1; + unsigned B3SOIPDk2Given:1; + unsigned B3SOIPDk3Given:1; + unsigned B3SOIPDk3bGiven:1; + unsigned B3SOIPDw0Given:1; + unsigned B3SOIPDnlxGiven:1; + unsigned B3SOIPDdvt0Given:1; + unsigned B3SOIPDdvt1Given:1; + unsigned B3SOIPDdvt2Given:1; + unsigned B3SOIPDdvt0wGiven:1; + unsigned B3SOIPDdvt1wGiven:1; + unsigned B3SOIPDdvt2wGiven:1; + unsigned B3SOIPDdroutGiven:1; + unsigned B3SOIPDdsubGiven:1; + unsigned B3SOIPDvth0Given:1; + unsigned B3SOIPDuaGiven:1; + unsigned B3SOIPDua1Given:1; + unsigned B3SOIPDubGiven:1; + unsigned B3SOIPDub1Given:1; + unsigned B3SOIPDucGiven:1; + unsigned B3SOIPDuc1Given:1; + unsigned B3SOIPDu0Given:1; + unsigned B3SOIPDuteGiven:1; + unsigned B3SOIPDvoffGiven:1; + unsigned B3SOIPDrdswGiven:1; + unsigned B3SOIPDprwgGiven:1; + unsigned B3SOIPDprwbGiven:1; + unsigned B3SOIPDprtGiven:1; + unsigned B3SOIPDeta0Given:1; + unsigned B3SOIPDetabGiven:1; + unsigned B3SOIPDpclmGiven:1; + unsigned B3SOIPDpdibl1Given:1; + unsigned B3SOIPDpdibl2Given:1; + unsigned B3SOIPDpdiblbGiven:1; + unsigned B3SOIPDpvagGiven:1; + unsigned B3SOIPDdeltaGiven:1; + unsigned B3SOIPDwrGiven:1; + unsigned B3SOIPDdwgGiven:1; + unsigned B3SOIPDdwbGiven:1; + unsigned B3SOIPDb0Given:1; + unsigned B3SOIPDb1Given:1; + unsigned B3SOIPDalpha0Given:1; + + +/* v2.2 release */ + unsigned B3SOIPDwth0Given:1; + unsigned B3SOIPDrhaloGiven:1; + unsigned B3SOIPDntoxGiven:1; + unsigned B3SOIPDtoxrefGiven:1; + unsigned B3SOIPDebgGiven:1; + unsigned B3SOIPDnevbGiven:1; + unsigned B3SOIPDalphaGB1Given:1; + unsigned B3SOIPDbetaGB1Given:1; + unsigned B3SOIPDvgb1Given:1; + unsigned B3SOIPDnecbGiven:1; + unsigned B3SOIPDalphaGB2Given:1; + unsigned B3SOIPDbetaGB2Given:1; + unsigned B3SOIPDvgb2Given:1; + unsigned B3SOIPDtoxqmGiven:1; + unsigned B3SOIPDigModGiven:1; + unsigned B3SOIPDvoxhGiven:1; + unsigned B3SOIPDdeltavoxGiven:1; + + +/* v2.0 release */ + unsigned B3SOIPDk1w1Given:1; + unsigned B3SOIPDk1w2Given:1; + unsigned B3SOIPDketasGiven:1; + unsigned B3SOIPDdwbcGiven:1; + unsigned B3SOIPDbeta0Given:1; + unsigned B3SOIPDbeta1Given:1; + unsigned B3SOIPDbeta2Given:1; + unsigned B3SOIPDvdsatii0Given:1; + unsigned B3SOIPDtiiGiven:1; + unsigned B3SOIPDliiGiven:1; + unsigned B3SOIPDsii0Given:1; + unsigned B3SOIPDsii1Given:1; + unsigned B3SOIPDsii2Given:1; + unsigned B3SOIPDsiidGiven:1; + unsigned B3SOIPDfbjtiiGiven:1; + unsigned B3SOIPDesatiiGiven:1; + unsigned B3SOIPDntunGiven:1; + unsigned B3SOIPDnrecf0Given:1; + unsigned B3SOIPDnrecr0Given:1; + unsigned B3SOIPDisbjtGiven:1; + unsigned B3SOIPDisdifGiven:1; + unsigned B3SOIPDisrecGiven:1; + unsigned B3SOIPDistunGiven:1; + unsigned B3SOIPDlnGiven:1; + unsigned B3SOIPDvrec0Given:1; + unsigned B3SOIPDvtun0Given:1; + unsigned B3SOIPDnbjtGiven:1; + unsigned B3SOIPDlbjt0Given:1; + unsigned B3SOIPDldif0Given:1; + unsigned B3SOIPDvabjtGiven:1; + unsigned B3SOIPDaelyGiven:1; + unsigned B3SOIPDahliGiven:1; + unsigned B3SOIPDrbodyGiven:1; + unsigned B3SOIPDrbshGiven:1; + unsigned B3SOIPDndifGiven:1; + unsigned B3SOIPDntrecfGiven:1; + unsigned B3SOIPDntrecrGiven:1; + unsigned B3SOIPDdlcbGiven:1; + unsigned B3SOIPDfbodyGiven:1; + unsigned B3SOIPDtcjswgGiven:1; + unsigned B3SOIPDtpbswgGiven:1; + unsigned B3SOIPDacdeGiven:1; + unsigned B3SOIPDmoinGiven:1; + unsigned B3SOIPDdelvtGiven:1; + unsigned B3SOIPDdlbgGiven:1; + + + /* CV model */ + unsigned B3SOIPDcgslGiven:1; + unsigned B3SOIPDcgdlGiven:1; + unsigned B3SOIPDckappaGiven:1; + unsigned B3SOIPDcfGiven:1; + unsigned B3SOIPDclcGiven:1; + unsigned B3SOIPDcleGiven:1; + unsigned B3SOIPDdwcGiven:1; + unsigned B3SOIPDdlcGiven:1; + +/* Added for binning - START2 */ + /* Length Dependence */ + unsigned B3SOIPDlnpeakGiven:1; + unsigned B3SOIPDlnsubGiven:1; + unsigned B3SOIPDlngateGiven:1; + unsigned B3SOIPDlvth0Given:1; + unsigned B3SOIPDlk1Given:1; + unsigned B3SOIPDlk1w1Given:1; + unsigned B3SOIPDlk1w2Given:1; + unsigned B3SOIPDlk2Given:1; + unsigned B3SOIPDlk3Given:1; + unsigned B3SOIPDlk3bGiven:1; + unsigned B3SOIPDlkb1Given:1; + unsigned B3SOIPDlw0Given:1; + unsigned B3SOIPDlnlxGiven:1; + unsigned B3SOIPDldvt0Given:1; + unsigned B3SOIPDldvt1Given:1; + unsigned B3SOIPDldvt2Given:1; + unsigned B3SOIPDldvt0wGiven:1; + unsigned B3SOIPDldvt1wGiven:1; + unsigned B3SOIPDldvt2wGiven:1; + unsigned B3SOIPDlu0Given:1; + unsigned B3SOIPDluaGiven:1; + unsigned B3SOIPDlubGiven:1; + unsigned B3SOIPDlucGiven:1; + unsigned B3SOIPDlvsatGiven:1; + unsigned B3SOIPDla0Given:1; + unsigned B3SOIPDlagsGiven:1; + unsigned B3SOIPDlb0Given:1; + unsigned B3SOIPDlb1Given:1; + unsigned B3SOIPDlketaGiven:1; + unsigned B3SOIPDlketasGiven:1; + unsigned B3SOIPDla1Given:1; + unsigned B3SOIPDla2Given:1; + unsigned B3SOIPDlrdswGiven:1; + unsigned B3SOIPDlprwbGiven:1; + unsigned B3SOIPDlprwgGiven:1; + unsigned B3SOIPDlwrGiven:1; + unsigned B3SOIPDlnfactorGiven:1; + unsigned B3SOIPDldwgGiven:1; + unsigned B3SOIPDldwbGiven:1; + unsigned B3SOIPDlvoffGiven:1; + unsigned B3SOIPDleta0Given:1; + unsigned B3SOIPDletabGiven:1; + unsigned B3SOIPDldsubGiven:1; + unsigned B3SOIPDlcitGiven:1; + unsigned B3SOIPDlcdscGiven:1; + unsigned B3SOIPDlcdscbGiven:1; + unsigned B3SOIPDlcdscdGiven:1; + unsigned B3SOIPDlpclmGiven:1; + unsigned B3SOIPDlpdibl1Given:1; + unsigned B3SOIPDlpdibl2Given:1; + unsigned B3SOIPDlpdiblbGiven:1; + unsigned B3SOIPDldroutGiven:1; + unsigned B3SOIPDlpvagGiven:1; + unsigned B3SOIPDldeltaGiven:1; + unsigned B3SOIPDlalpha0Given:1; + unsigned B3SOIPDlfbjtiiGiven:1; + unsigned B3SOIPDlbeta0Given:1; + unsigned B3SOIPDlbeta1Given:1; + unsigned B3SOIPDlbeta2Given:1; + unsigned B3SOIPDlvdsatii0Given:1; + unsigned B3SOIPDlliiGiven:1; + unsigned B3SOIPDlesatiiGiven:1; + unsigned B3SOIPDlsii0Given:1; + unsigned B3SOIPDlsii1Given:1; + unsigned B3SOIPDlsii2Given:1; + unsigned B3SOIPDlsiidGiven:1; + unsigned B3SOIPDlagidlGiven:1; + unsigned B3SOIPDlbgidlGiven:1; + unsigned B3SOIPDlngidlGiven:1; + unsigned B3SOIPDlntunGiven:1; + unsigned B3SOIPDlndiodeGiven:1; + unsigned B3SOIPDlnrecf0Given:1; + unsigned B3SOIPDlnrecr0Given:1; + unsigned B3SOIPDlisbjtGiven:1; + unsigned B3SOIPDlisdifGiven:1; + unsigned B3SOIPDlisrecGiven:1; + unsigned B3SOIPDlistunGiven:1; + unsigned B3SOIPDlvrec0Given:1; + unsigned B3SOIPDlvtun0Given:1; + unsigned B3SOIPDlnbjtGiven:1; + unsigned B3SOIPDllbjt0Given:1; + unsigned B3SOIPDlvabjtGiven:1; + unsigned B3SOIPDlaelyGiven:1; + unsigned B3SOIPDlahliGiven:1; + /* CV model */ + unsigned B3SOIPDlvsdfbGiven:1; + unsigned B3SOIPDlvsdthGiven:1; + unsigned B3SOIPDldelvtGiven:1; + unsigned B3SOIPDlacdeGiven:1; + unsigned B3SOIPDlmoinGiven:1; + + /* Width Dependence */ + unsigned B3SOIPDwnpeakGiven:1; + unsigned B3SOIPDwnsubGiven:1; + unsigned B3SOIPDwngateGiven:1; + unsigned B3SOIPDwvth0Given:1; + unsigned B3SOIPDwk1Given:1; + unsigned B3SOIPDwk1w1Given:1; + unsigned B3SOIPDwk1w2Given:1; + unsigned B3SOIPDwk2Given:1; + unsigned B3SOIPDwk3Given:1; + unsigned B3SOIPDwk3bGiven:1; + unsigned B3SOIPDwkb1Given:1; + unsigned B3SOIPDww0Given:1; + unsigned B3SOIPDwnlxGiven:1; + unsigned B3SOIPDwdvt0Given:1; + unsigned B3SOIPDwdvt1Given:1; + unsigned B3SOIPDwdvt2Given:1; + unsigned B3SOIPDwdvt0wGiven:1; + unsigned B3SOIPDwdvt1wGiven:1; + unsigned B3SOIPDwdvt2wGiven:1; + unsigned B3SOIPDwu0Given:1; + unsigned B3SOIPDwuaGiven:1; + unsigned B3SOIPDwubGiven:1; + unsigned B3SOIPDwucGiven:1; + unsigned B3SOIPDwvsatGiven:1; + unsigned B3SOIPDwa0Given:1; + unsigned B3SOIPDwagsGiven:1; + unsigned B3SOIPDwb0Given:1; + unsigned B3SOIPDwb1Given:1; + unsigned B3SOIPDwketaGiven:1; + unsigned B3SOIPDwketasGiven:1; + unsigned B3SOIPDwa1Given:1; + unsigned B3SOIPDwa2Given:1; + unsigned B3SOIPDwrdswGiven:1; + unsigned B3SOIPDwprwbGiven:1; + unsigned B3SOIPDwprwgGiven:1; + unsigned B3SOIPDwwrGiven:1; + unsigned B3SOIPDwnfactorGiven:1; + unsigned B3SOIPDwdwgGiven:1; + unsigned B3SOIPDwdwbGiven:1; + unsigned B3SOIPDwvoffGiven:1; + unsigned B3SOIPDweta0Given:1; + unsigned B3SOIPDwetabGiven:1; + unsigned B3SOIPDwdsubGiven:1; + unsigned B3SOIPDwcitGiven:1; + unsigned B3SOIPDwcdscGiven:1; + unsigned B3SOIPDwcdscbGiven:1; + unsigned B3SOIPDwcdscdGiven:1; + unsigned B3SOIPDwpclmGiven:1; + unsigned B3SOIPDwpdibl1Given:1; + unsigned B3SOIPDwpdibl2Given:1; + unsigned B3SOIPDwpdiblbGiven:1; + unsigned B3SOIPDwdroutGiven:1; + unsigned B3SOIPDwpvagGiven:1; + unsigned B3SOIPDwdeltaGiven:1; + unsigned B3SOIPDwalpha0Given:1; + unsigned B3SOIPDwfbjtiiGiven:1; + unsigned B3SOIPDwbeta0Given:1; + unsigned B3SOIPDwbeta1Given:1; + unsigned B3SOIPDwbeta2Given:1; + unsigned B3SOIPDwvdsatii0Given:1; + unsigned B3SOIPDwliiGiven:1; + unsigned B3SOIPDwesatiiGiven:1; + unsigned B3SOIPDwsii0Given:1; + unsigned B3SOIPDwsii1Given:1; + unsigned B3SOIPDwsii2Given:1; + unsigned B3SOIPDwsiidGiven:1; + unsigned B3SOIPDwagidlGiven:1; + unsigned B3SOIPDwbgidlGiven:1; + unsigned B3SOIPDwngidlGiven:1; + unsigned B3SOIPDwntunGiven:1; + unsigned B3SOIPDwndiodeGiven:1; + unsigned B3SOIPDwnrecf0Given:1; + unsigned B3SOIPDwnrecr0Given:1; + unsigned B3SOIPDwisbjtGiven:1; + unsigned B3SOIPDwisdifGiven:1; + unsigned B3SOIPDwisrecGiven:1; + unsigned B3SOIPDwistunGiven:1; + unsigned B3SOIPDwvrec0Given:1; + unsigned B3SOIPDwvtun0Given:1; + unsigned B3SOIPDwnbjtGiven:1; + unsigned B3SOIPDwlbjt0Given:1; + unsigned B3SOIPDwvabjtGiven:1; + unsigned B3SOIPDwaelyGiven:1; + unsigned B3SOIPDwahliGiven:1; + /* CV model */ + unsigned B3SOIPDwvsdfbGiven:1; + unsigned B3SOIPDwvsdthGiven:1; + unsigned B3SOIPDwdelvtGiven:1; + unsigned B3SOIPDwacdeGiven:1; + unsigned B3SOIPDwmoinGiven:1; + + /* Cross-term Dependence */ + unsigned B3SOIPDpnpeakGiven:1; + unsigned B3SOIPDpnsubGiven:1; + unsigned B3SOIPDpngateGiven:1; + unsigned B3SOIPDpvth0Given:1; + unsigned B3SOIPDpk1Given:1; + unsigned B3SOIPDpk1w1Given:1; + unsigned B3SOIPDpk1w2Given:1; + unsigned B3SOIPDpk2Given:1; + unsigned B3SOIPDpk3Given:1; + unsigned B3SOIPDpk3bGiven:1; + unsigned B3SOIPDpkb1Given:1; + unsigned B3SOIPDpw0Given:1; + unsigned B3SOIPDpnlxGiven:1; + unsigned B3SOIPDpdvt0Given:1; + unsigned B3SOIPDpdvt1Given:1; + unsigned B3SOIPDpdvt2Given:1; + unsigned B3SOIPDpdvt0wGiven:1; + unsigned B3SOIPDpdvt1wGiven:1; + unsigned B3SOIPDpdvt2wGiven:1; + unsigned B3SOIPDpu0Given:1; + unsigned B3SOIPDpuaGiven:1; + unsigned B3SOIPDpubGiven:1; + unsigned B3SOIPDpucGiven:1; + unsigned B3SOIPDpvsatGiven:1; + unsigned B3SOIPDpa0Given:1; + unsigned B3SOIPDpagsGiven:1; + unsigned B3SOIPDpb0Given:1; + unsigned B3SOIPDpb1Given:1; + unsigned B3SOIPDpketaGiven:1; + unsigned B3SOIPDpketasGiven:1; + unsigned B3SOIPDpa1Given:1; + unsigned B3SOIPDpa2Given:1; + unsigned B3SOIPDprdswGiven:1; + unsigned B3SOIPDpprwbGiven:1; + unsigned B3SOIPDpprwgGiven:1; + unsigned B3SOIPDpwrGiven:1; + unsigned B3SOIPDpnfactorGiven:1; + unsigned B3SOIPDpdwgGiven:1; + unsigned B3SOIPDpdwbGiven:1; + unsigned B3SOIPDpvoffGiven:1; + unsigned B3SOIPDpeta0Given:1; + unsigned B3SOIPDpetabGiven:1; + unsigned B3SOIPDpdsubGiven:1; + unsigned B3SOIPDpcitGiven:1; + unsigned B3SOIPDpcdscGiven:1; + unsigned B3SOIPDpcdscbGiven:1; + unsigned B3SOIPDpcdscdGiven:1; + unsigned B3SOIPDppclmGiven:1; + unsigned B3SOIPDppdibl1Given:1; + unsigned B3SOIPDppdibl2Given:1; + unsigned B3SOIPDppdiblbGiven:1; + unsigned B3SOIPDpdroutGiven:1; + unsigned B3SOIPDppvagGiven:1; + unsigned B3SOIPDpdeltaGiven:1; + unsigned B3SOIPDpalpha0Given:1; + unsigned B3SOIPDpfbjtiiGiven:1; + unsigned B3SOIPDpbeta0Given:1; + unsigned B3SOIPDpbeta1Given:1; + unsigned B3SOIPDpbeta2Given:1; + unsigned B3SOIPDpvdsatii0Given:1; + unsigned B3SOIPDpliiGiven:1; + unsigned B3SOIPDpesatiiGiven:1; + unsigned B3SOIPDpsii0Given:1; + unsigned B3SOIPDpsii1Given:1; + unsigned B3SOIPDpsii2Given:1; + unsigned B3SOIPDpsiidGiven:1; + unsigned B3SOIPDpagidlGiven:1; + unsigned B3SOIPDpbgidlGiven:1; + unsigned B3SOIPDpngidlGiven:1; + unsigned B3SOIPDpntunGiven:1; + unsigned B3SOIPDpndiodeGiven:1; + unsigned B3SOIPDpnrecf0Given:1; + unsigned B3SOIPDpnrecr0Given:1; + unsigned B3SOIPDpisbjtGiven:1; + unsigned B3SOIPDpisdifGiven:1; + unsigned B3SOIPDpisrecGiven:1; + unsigned B3SOIPDpistunGiven:1; + unsigned B3SOIPDpvrec0Given:1; + unsigned B3SOIPDpvtun0Given:1; + unsigned B3SOIPDpnbjtGiven:1; + unsigned B3SOIPDplbjt0Given:1; + unsigned B3SOIPDpvabjtGiven:1; + unsigned B3SOIPDpaelyGiven:1; + unsigned B3SOIPDpahliGiven:1; + /* CV model */ + unsigned B3SOIPDpvsdfbGiven:1; + unsigned B3SOIPDpvsdthGiven:1; + unsigned B3SOIPDpdelvtGiven:1; + unsigned B3SOIPDpacdeGiven:1; + unsigned B3SOIPDpmoinGiven:1; +/* Added for binning - END2 */ + + unsigned B3SOIPDuseFringeGiven:1; + + unsigned B3SOIPDtnomGiven:1; + unsigned B3SOIPDcgsoGiven:1; + unsigned B3SOIPDcgdoGiven:1; + unsigned B3SOIPDcgeoGiven:1; + unsigned B3SOIPDxpartGiven:1; + unsigned B3SOIPDsheetResistanceGiven:1; + unsigned B3SOIPDGatesidewallJctPotentialGiven:1; + unsigned B3SOIPDbodyJctGateSideGradingCoeffGiven:1; + unsigned B3SOIPDunitLengthGateSidewallJctCapGiven:1; + unsigned B3SOIPDcsdeswGiven:1; + + unsigned B3SOIPDoxideTrapDensityAGiven:1; + unsigned B3SOIPDoxideTrapDensityBGiven:1; + unsigned B3SOIPDoxideTrapDensityCGiven:1; + unsigned B3SOIPDemGiven:1; + unsigned B3SOIPDefGiven:1; + unsigned B3SOIPDafGiven:1; + unsigned B3SOIPDkfGiven:1; + unsigned B3SOIPDnoifGiven:1; + + unsigned B3SOIPDLintGiven:1; + unsigned B3SOIPDLlGiven:1; + unsigned B3SOIPDLlnGiven:1; + unsigned B3SOIPDLwGiven:1; + unsigned B3SOIPDLwnGiven:1; + unsigned B3SOIPDLwlGiven:1; + unsigned B3SOIPDLminGiven:1; + unsigned B3SOIPDLmaxGiven:1; + + unsigned B3SOIPDWintGiven:1; + unsigned B3SOIPDWlGiven:1; + unsigned B3SOIPDWlnGiven:1; + unsigned B3SOIPDWwGiven:1; + unsigned B3SOIPDWwnGiven:1; + unsigned B3SOIPDWwlGiven:1; + unsigned B3SOIPDWminGiven:1; + unsigned B3SOIPDWmaxGiven:1; + +} +B3SOIPDmodel; + + +#ifndef NMOS +#define NMOS 1 +#define PMOS -1 +#endif /*NMOS*/ +/* device parameters */ +#define B3SOIPD_W 1 +#define B3SOIPD_L 2 +#define B3SOIPD_AS 3 +#define B3SOIPD_AD 4 +#define B3SOIPD_PS 5 +#define B3SOIPD_PD 6 +#define B3SOIPD_NRS 7 +#define B3SOIPD_NRD 8 +#define B3SOIPD_OFF 9 +#define B3SOIPD_IC_VBS 10 +#define B3SOIPD_IC_VDS 11 +#define B3SOIPD_IC_VGS 12 +#define B3SOIPD_IC_VES 13 +#define B3SOIPD_IC_VPS 14 +#define B3SOIPD_BJTOFF 15 +#define B3SOIPD_RTH0 16 +#define B3SOIPD_CTH0 17 +#define B3SOIPD_NRB 18 +#define B3SOIPD_IC 19 +#define B3SOIPD_NQSMOD 20 +#define B3SOIPD_DEBUG 21 +/* v2.0 release */ +#define B3SOIPD_NBC 22 +#define B3SOIPD_NSEG 23 +#define B3SOIPD_PDBCP 24 +#define B3SOIPD_PSBCP 25 +#define B3SOIPD_AGBCP 26 +#define B3SOIPD_AEBCP 27 +#define B3SOIPD_VBSUSR 28 +#define B3SOIPD_TNODEOUT 29 +/* model parameters */ +#define B3SOIPD_MOD_CAPMOD 101 +#define B3SOIPD_MOD_NQSMOD 102 +#define B3SOIPD_MOD_MOBMOD 103 +#define B3SOIPD_MOD_NOIMOD 104 +#define B3SOIPD_MOD_SHMOD 105 +#define B3SOIPD_MOD_DDMOD 106 +#define B3SOIPD_MOD_TOX 107 +#define B3SOIPD_MOD_CDSC 108 +#define B3SOIPD_MOD_CDSCB 109 +#define B3SOIPD_MOD_CIT 110 +#define B3SOIPD_MOD_NFACTOR 111 +#define B3SOIPD_MOD_XJ 112 +#define B3SOIPD_MOD_VSAT 113 +#define B3SOIPD_MOD_AT 114 +#define B3SOIPD_MOD_A0 115 +#define B3SOIPD_MOD_A1 116 +#define B3SOIPD_MOD_A2 117 +#define B3SOIPD_MOD_KETA 118 +#define B3SOIPD_MOD_NSUB 119 +#define B3SOIPD_MOD_NPEAK 120 +#define B3SOIPD_MOD_NGATE 121 +#define B3SOIPD_MOD_GAMMA1 122 +#define B3SOIPD_MOD_GAMMA2 123 +#define B3SOIPD_MOD_VBX 124 +#define B3SOIPD_MOD_BINUNIT 125 +#define B3SOIPD_MOD_VBM 126 +#define B3SOIPD_MOD_XT 127 +#define B3SOIPD_MOD_K1 129 +#define B3SOIPD_MOD_KT1 130 +#define B3SOIPD_MOD_KT1L 131 +#define B3SOIPD_MOD_K2 132 +#define B3SOIPD_MOD_KT2 133 +#define B3SOIPD_MOD_K3 134 +#define B3SOIPD_MOD_K3B 135 +#define B3SOIPD_MOD_W0 136 +#define B3SOIPD_MOD_NLX 137 +#define B3SOIPD_MOD_DVT0 138 +#define B3SOIPD_MOD_DVT1 139 +#define B3SOIPD_MOD_DVT2 140 +#define B3SOIPD_MOD_DVT0W 141 +#define B3SOIPD_MOD_DVT1W 142 +#define B3SOIPD_MOD_DVT2W 143 +#define B3SOIPD_MOD_DROUT 144 +#define B3SOIPD_MOD_DSUB 145 +#define B3SOIPD_MOD_VTH0 146 +#define B3SOIPD_MOD_UA 147 +#define B3SOIPD_MOD_UA1 148 +#define B3SOIPD_MOD_UB 149 +#define B3SOIPD_MOD_UB1 150 +#define B3SOIPD_MOD_UC 151 +#define B3SOIPD_MOD_UC1 152 +#define B3SOIPD_MOD_U0 153 +#define B3SOIPD_MOD_UTE 154 +#define B3SOIPD_MOD_VOFF 155 +#define B3SOIPD_MOD_DELTA 156 +#define B3SOIPD_MOD_RDSW 157 +#define B3SOIPD_MOD_PRT 158 +#define B3SOIPD_MOD_LDD 159 +#define B3SOIPD_MOD_ETA 160 +#define B3SOIPD_MOD_ETA0 161 +#define B3SOIPD_MOD_ETAB 162 +#define B3SOIPD_MOD_PCLM 163 +#define B3SOIPD_MOD_PDIBL1 164 +#define B3SOIPD_MOD_PDIBL2 165 +#define B3SOIPD_MOD_PSCBE1 166 +#define B3SOIPD_MOD_PSCBE2 167 +#define B3SOIPD_MOD_PVAG 168 +#define B3SOIPD_MOD_WR 169 +#define B3SOIPD_MOD_DWG 170 +#define B3SOIPD_MOD_DWB 171 +#define B3SOIPD_MOD_B0 172 +#define B3SOIPD_MOD_B1 173 +#define B3SOIPD_MOD_ALPHA0 174 +#define B3SOIPD_MOD_PDIBLB 178 +#define B3SOIPD_MOD_PRWG 179 +#define B3SOIPD_MOD_PRWB 180 +#define B3SOIPD_MOD_CDSCD 181 +#define B3SOIPD_MOD_AGS 182 +#define B3SOIPD_MOD_FRINGE 184 +#define B3SOIPD_MOD_CGSL 186 +#define B3SOIPD_MOD_CGDL 187 +#define B3SOIPD_MOD_CKAPPA 188 +#define B3SOIPD_MOD_CF 189 +#define B3SOIPD_MOD_CLC 190 +#define B3SOIPD_MOD_CLE 191 +#define B3SOIPD_MOD_PARAMCHK 192 +#define B3SOIPD_MOD_VERSION 193 +#define B3SOIPD_MOD_TBOX 195 +#define B3SOIPD_MOD_TSI 196 +#define B3SOIPD_MOD_KB1 197 +#define B3SOIPD_MOD_KB3 198 +#define B3SOIPD_MOD_DVBD0 199 +#define B3SOIPD_MOD_DVBD1 200 +#define B3SOIPD_MOD_DELP 201 +#define B3SOIPD_MOD_VBSA 202 +#define B3SOIPD_MOD_RBODY 204 +#define B3SOIPD_MOD_ADICE0 205 +#define B3SOIPD_MOD_ABP 206 +#define B3SOIPD_MOD_MXC 207 +#define B3SOIPD_MOD_RTH0 208 +#define B3SOIPD_MOD_CTH0 209 +#define B3SOIPD_MOD_ALPHA1 214 +#define B3SOIPD_MOD_NGIDL 215 +#define B3SOIPD_MOD_AGIDL 216 +#define B3SOIPD_MOD_BGIDL 217 +#define B3SOIPD_MOD_NDIODE 218 +#define B3SOIPD_MOD_LDIOF 219 +#define B3SOIPD_MOD_LDIOR 220 +#define B3SOIPD_MOD_NTUN 221 +#define B3SOIPD_MOD_ISBJT 222 +#define B3SOIPD_MOD_ISDIF 223 +#define B3SOIPD_MOD_ISREC 224 +#define B3SOIPD_MOD_ISTUN 225 +#define B3SOIPD_MOD_XBJT 226 +#define B3SOIPD_MOD_XDIF 227 +#define B3SOIPD_MOD_XREC 228 +#define B3SOIPD_MOD_XTUN 229 +#define B3SOIPD_MOD_TT 232 +#define B3SOIPD_MOD_VSDTH 233 +#define B3SOIPD_MOD_VSDFB 234 +#define B3SOIPD_MOD_ASD 235 +#define B3SOIPD_MOD_CSDMIN 236 +#define B3SOIPD_MOD_RBSH 237 +#define B3SOIPD_MOD_ESATII 238 +/* v2.0 release */ +#define B3SOIPD_MOD_K1W1 239 +#define B3SOIPD_MOD_K1W2 240 +#define B3SOIPD_MOD_KETAS 241 +#define B3SOIPD_MOD_DWBC 242 +#define B3SOIPD_MOD_BETA0 243 +#define B3SOIPD_MOD_BETA1 244 +#define B3SOIPD_MOD_BETA2 245 +#define B3SOIPD_MOD_VDSATII0 246 +#define B3SOIPD_MOD_TII 247 +#define B3SOIPD_MOD_LII 248 +#define B3SOIPD_MOD_SII0 249 +#define B3SOIPD_MOD_SII1 250 +#define B3SOIPD_MOD_SII2 251 +#define B3SOIPD_MOD_SIID 252 +#define B3SOIPD_MOD_FBJTII 253 +#define B3SOIPD_MOD_NRECF0 255 +#define B3SOIPD_MOD_NRECR0 256 +#define B3SOIPD_MOD_LN 257 +#define B3SOIPD_MOD_VREC0 258 +#define B3SOIPD_MOD_VTUN0 259 +#define B3SOIPD_MOD_NBJT 260 +#define B3SOIPD_MOD_LBJT0 261 +#define B3SOIPD_MOD_VABJT 262 +#define B3SOIPD_MOD_AELY 263 +#define B3SOIPD_MOD_AHLI 264 +#define B3SOIPD_MOD_NTRECF 265 +#define B3SOIPD_MOD_NTRECR 266 +#define B3SOIPD_MOD_DLCB 267 +#define B3SOIPD_MOD_FBODY 268 +#define B3SOIPD_MOD_NDIF 269 +#define B3SOIPD_MOD_TCJSWG 270 +#define B3SOIPD_MOD_TPBSWG 271 +#define B3SOIPD_MOD_ACDE 272 +#define B3SOIPD_MOD_MOIN 273 +#define B3SOIPD_MOD_DELVT 274 +#define B3SOIPD_MOD_DLBG 275 +#define B3SOIPD_MOD_LDIF0 276 +/* v2.2 release */ +#define B3SOIPD_MOD_WTH0 277 +#define B3SOIPD_MOD_RHALO 278 +#define B3SOIPD_MOD_NTOX 279 +#define B3SOIPD_MOD_TOXREF 280 +#define B3SOIPD_MOD_EBG 281 +#define B3SOIPD_MOD_NEVB 282 +#define B3SOIPD_MOD_ALPHAGB1 283 +#define B3SOIPD_MOD_BETAGB1 284 +#define B3SOIPD_MOD_VGB1 285 +#define B3SOIPD_MOD_NECB 286 +#define B3SOIPD_MOD_ALPHAGB2 287 +#define B3SOIPD_MOD_BETAGB2 288 +#define B3SOIPD_MOD_VGB2 289 +#define B3SOIPD_MOD_TOXQM 290 +#define B3SOIPD_MOD_IGMOD 291 +#define B3SOIPD_MOD_VOXH 292 +#define B3SOIPD_MOD_DELTAVOX 293 +/* Added for binning - START3 */ +/* Length dependence */ +#define B3SOIPD_MOD_LNPEAK 301 +#define B3SOIPD_MOD_LNSUB 302 +#define B3SOIPD_MOD_LNGATE 303 +#define B3SOIPD_MOD_LVTH0 304 +#define B3SOIPD_MOD_LK1 305 +#define B3SOIPD_MOD_LK1W1 306 +#define B3SOIPD_MOD_LK1W2 307 +#define B3SOIPD_MOD_LK2 308 +#define B3SOIPD_MOD_LK3 309 +#define B3SOIPD_MOD_LK3B 310 +#define B3SOIPD_MOD_LKB1 311 +#define B3SOIPD_MOD_LW0 312 +#define B3SOIPD_MOD_LNLX 313 +#define B3SOIPD_MOD_LDVT0 314 +#define B3SOIPD_MOD_LDVT1 315 +#define B3SOIPD_MOD_LDVT2 316 +#define B3SOIPD_MOD_LDVT0W 317 +#define B3SOIPD_MOD_LDVT1W 318 +#define B3SOIPD_MOD_LDVT2W 319 +#define B3SOIPD_MOD_LU0 320 +#define B3SOIPD_MOD_LUA 321 +#define B3SOIPD_MOD_LUB 322 +#define B3SOIPD_MOD_LUC 323 +#define B3SOIPD_MOD_LVSAT 324 +#define B3SOIPD_MOD_LA0 325 +#define B3SOIPD_MOD_LAGS 326 +#define B3SOIPD_MOD_LB0 327 +#define B3SOIPD_MOD_LB1 328 +#define B3SOIPD_MOD_LKETA 329 +#define B3SOIPD_MOD_LKETAS 330 +#define B3SOIPD_MOD_LA1 331 +#define B3SOIPD_MOD_LA2 332 +#define B3SOIPD_MOD_LRDSW 333 +#define B3SOIPD_MOD_LPRWB 334 +#define B3SOIPD_MOD_LPRWG 335 +#define B3SOIPD_MOD_LWR 336 +#define B3SOIPD_MOD_LNFACTOR 337 +#define B3SOIPD_MOD_LDWG 338 +#define B3SOIPD_MOD_LDWB 339 +#define B3SOIPD_MOD_LVOFF 340 +#define B3SOIPD_MOD_LETA0 341 +#define B3SOIPD_MOD_LETAB 342 +#define B3SOIPD_MOD_LDSUB 343 +#define B3SOIPD_MOD_LCIT 344 +#define B3SOIPD_MOD_LCDSC 345 +#define B3SOIPD_MOD_LCDSCB 346 +#define B3SOIPD_MOD_LCDSCD 347 +#define B3SOIPD_MOD_LPCLM 348 +#define B3SOIPD_MOD_LPDIBL1 349 +#define B3SOIPD_MOD_LPDIBL2 350 +#define B3SOIPD_MOD_LPDIBLB 351 +#define B3SOIPD_MOD_LDROUT 352 +#define B3SOIPD_MOD_LPVAG 353 +#define B3SOIPD_MOD_LDELTA 354 +#define B3SOIPD_MOD_LALPHA0 355 +#define B3SOIPD_MOD_LFBJTII 356 +#define B3SOIPD_MOD_LBETA0 357 +#define B3SOIPD_MOD_LBETA1 358 +#define B3SOIPD_MOD_LBETA2 359 +#define B3SOIPD_MOD_LVDSATII0 360 +#define B3SOIPD_MOD_LLII 361 +#define B3SOIPD_MOD_LESATII 362 +#define B3SOIPD_MOD_LSII0 363 +#define B3SOIPD_MOD_LSII1 364 +#define B3SOIPD_MOD_LSII2 365 +#define B3SOIPD_MOD_LSIID 366 +#define B3SOIPD_MOD_LAGIDL 367 +#define B3SOIPD_MOD_LBGIDL 368 +#define B3SOIPD_MOD_LNGIDL 369 +#define B3SOIPD_MOD_LNTUN 370 +#define B3SOIPD_MOD_LNDIODE 371 +#define B3SOIPD_MOD_LNRECF0 372 +#define B3SOIPD_MOD_LNRECR0 373 +#define B3SOIPD_MOD_LISBJT 374 +#define B3SOIPD_MOD_LISDIF 375 +#define B3SOIPD_MOD_LISREC 376 +#define B3SOIPD_MOD_LISTUN 377 +#define B3SOIPD_MOD_LVREC0 378 +#define B3SOIPD_MOD_LVTUN0 379 +#define B3SOIPD_MOD_LNBJT 380 +#define B3SOIPD_MOD_LLBJT0 381 +#define B3SOIPD_MOD_LVABJT 382 +#define B3SOIPD_MOD_LAELY 383 +#define B3SOIPD_MOD_LAHLI 384 +#define B3SOIPD_MOD_LVSDFB 385 +#define B3SOIPD_MOD_LVSDTH 386 +#define B3SOIPD_MOD_LDELVT 387 +#define B3SOIPD_MOD_LACDE 388 +#define B3SOIPD_MOD_LMOIN 389 +/* Width dependence */ +#define B3SOIPD_MOD_WNPEAK 401 +#define B3SOIPD_MOD_WNSUB 402 +#define B3SOIPD_MOD_WNGATE 403 +#define B3SOIPD_MOD_WVTH0 404 +#define B3SOIPD_MOD_WK1 405 +#define B3SOIPD_MOD_WK1W1 406 +#define B3SOIPD_MOD_WK1W2 407 +#define B3SOIPD_MOD_WK2 408 +#define B3SOIPD_MOD_WK3 409 +#define B3SOIPD_MOD_WK3B 410 +#define B3SOIPD_MOD_WKB1 411 +#define B3SOIPD_MOD_WW0 412 +#define B3SOIPD_MOD_WNLX 413 +#define B3SOIPD_MOD_WDVT0 414 +#define B3SOIPD_MOD_WDVT1 415 +#define B3SOIPD_MOD_WDVT2 416 +#define B3SOIPD_MOD_WDVT0W 417 +#define B3SOIPD_MOD_WDVT1W 418 +#define B3SOIPD_MOD_WDVT2W 419 +#define B3SOIPD_MOD_WU0 420 +#define B3SOIPD_MOD_WUA 421 +#define B3SOIPD_MOD_WUB 422 +#define B3SOIPD_MOD_WUC 423 +#define B3SOIPD_MOD_WVSAT 424 +#define B3SOIPD_MOD_WA0 425 +#define B3SOIPD_MOD_WAGS 426 +#define B3SOIPD_MOD_WB0 427 +#define B3SOIPD_MOD_WB1 428 +#define B3SOIPD_MOD_WKETA 429 +#define B3SOIPD_MOD_WKETAS 430 +#define B3SOIPD_MOD_WA1 431 +#define B3SOIPD_MOD_WA2 432 +#define B3SOIPD_MOD_WRDSW 433 +#define B3SOIPD_MOD_WPRWB 434 +#define B3SOIPD_MOD_WPRWG 435 +#define B3SOIPD_MOD_WWR 436 +#define B3SOIPD_MOD_WNFACTOR 437 +#define B3SOIPD_MOD_WDWG 438 +#define B3SOIPD_MOD_WDWB 439 +#define B3SOIPD_MOD_WVOFF 440 +#define B3SOIPD_MOD_WETA0 441 +#define B3SOIPD_MOD_WETAB 442 +#define B3SOIPD_MOD_WDSUB 443 +#define B3SOIPD_MOD_WCIT 444 +#define B3SOIPD_MOD_WCDSC 445 +#define B3SOIPD_MOD_WCDSCB 446 +#define B3SOIPD_MOD_WCDSCD 447 +#define B3SOIPD_MOD_WPCLM 448 +#define B3SOIPD_MOD_WPDIBL1 449 +#define B3SOIPD_MOD_WPDIBL2 450 +#define B3SOIPD_MOD_WPDIBLB 451 +#define B3SOIPD_MOD_WDROUT 452 +#define B3SOIPD_MOD_WPVAG 453 +#define B3SOIPD_MOD_WDELTA 454 +#define B3SOIPD_MOD_WALPHA0 455 +#define B3SOIPD_MOD_WFBJTII 456 +#define B3SOIPD_MOD_WBETA0 457 +#define B3SOIPD_MOD_WBETA1 458 +#define B3SOIPD_MOD_WBETA2 459 +#define B3SOIPD_MOD_WVDSATII0 460 +#define B3SOIPD_MOD_WLII 461 +#define B3SOIPD_MOD_WESATII 462 +#define B3SOIPD_MOD_WSII0 463 +#define B3SOIPD_MOD_WSII1 464 +#define B3SOIPD_MOD_WSII2 465 +#define B3SOIPD_MOD_WSIID 466 +#define B3SOIPD_MOD_WAGIDL 467 +#define B3SOIPD_MOD_WBGIDL 468 +#define B3SOIPD_MOD_WNGIDL 469 +#define B3SOIPD_MOD_WNTUN 470 +#define B3SOIPD_MOD_WNDIODE 471 +#define B3SOIPD_MOD_WNRECF0 472 +#define B3SOIPD_MOD_WNRECR0 473 +#define B3SOIPD_MOD_WISBJT 474 +#define B3SOIPD_MOD_WISDIF 475 +#define B3SOIPD_MOD_WISREC 476 +#define B3SOIPD_MOD_WISTUN 477 +#define B3SOIPD_MOD_WVREC0 478 +#define B3SOIPD_MOD_WVTUN0 479 +#define B3SOIPD_MOD_WNBJT 480 +#define B3SOIPD_MOD_WLBJT0 481 +#define B3SOIPD_MOD_WVABJT 482 +#define B3SOIPD_MOD_WAELY 483 +#define B3SOIPD_MOD_WAHLI 484 +#define B3SOIPD_MOD_WVSDFB 485 +#define B3SOIPD_MOD_WVSDTH 486 +#define B3SOIPD_MOD_WDELVT 487 +#define B3SOIPD_MOD_WACDE 488 +#define B3SOIPD_MOD_WMOIN 489 +/* Cross-term dependence */ +#define B3SOIPD_MOD_PNPEAK 501 +#define B3SOIPD_MOD_PNSUB 502 +#define B3SOIPD_MOD_PNGATE 503 +#define B3SOIPD_MOD_PVTH0 504 +#define B3SOIPD_MOD_PK1 505 +#define B3SOIPD_MOD_PK1W1 506 +#define B3SOIPD_MOD_PK1W2 507 +#define B3SOIPD_MOD_PK2 508 +#define B3SOIPD_MOD_PK3 509 +#define B3SOIPD_MOD_PK3B 510 +#define B3SOIPD_MOD_PKB1 511 +#define B3SOIPD_MOD_PW0 512 +#define B3SOIPD_MOD_PNLX 513 +#define B3SOIPD_MOD_PDVT0 514 +#define B3SOIPD_MOD_PDVT1 515 +#define B3SOIPD_MOD_PDVT2 516 +#define B3SOIPD_MOD_PDVT0W 517 +#define B3SOIPD_MOD_PDVT1W 518 +#define B3SOIPD_MOD_PDVT2W 519 +#define B3SOIPD_MOD_PU0 520 +#define B3SOIPD_MOD_PUA 521 +#define B3SOIPD_MOD_PUB 522 +#define B3SOIPD_MOD_PUC 523 +#define B3SOIPD_MOD_PVSAT 524 +#define B3SOIPD_MOD_PA0 525 +#define B3SOIPD_MOD_PAGS 526 +#define B3SOIPD_MOD_PB0 527 +#define B3SOIPD_MOD_PB1 528 +#define B3SOIPD_MOD_PKETA 529 +#define B3SOIPD_MOD_PKETAS 530 +#define B3SOIPD_MOD_PA1 531 +#define B3SOIPD_MOD_PA2 532 +#define B3SOIPD_MOD_PRDSW 533 +#define B3SOIPD_MOD_PPRWB 534 +#define B3SOIPD_MOD_PPRWG 535 +#define B3SOIPD_MOD_PWR 536 +#define B3SOIPD_MOD_PNFACTOR 537 +#define B3SOIPD_MOD_PDWG 538 +#define B3SOIPD_MOD_PDWB 539 +#define B3SOIPD_MOD_PVOFF 540 +#define B3SOIPD_MOD_PETA0 541 +#define B3SOIPD_MOD_PETAB 542 +#define B3SOIPD_MOD_PDSUB 543 +#define B3SOIPD_MOD_PCIT 544 +#define B3SOIPD_MOD_PCDSC 545 +#define B3SOIPD_MOD_PCDSCB 546 +#define B3SOIPD_MOD_PCDSCD 547 +#define B3SOIPD_MOD_PPCLM 548 +#define B3SOIPD_MOD_PPDIBL1 549 +#define B3SOIPD_MOD_PPDIBL2 550 +#define B3SOIPD_MOD_PPDIBLB 551 +#define B3SOIPD_MOD_PDROUT 552 +#define B3SOIPD_MOD_PPVAG 553 +#define B3SOIPD_MOD_PDELTA 554 +#define B3SOIPD_MOD_PALPHA0 555 +#define B3SOIPD_MOD_PFBJTII 556 +#define B3SOIPD_MOD_PBETA0 557 +#define B3SOIPD_MOD_PBETA1 558 +#define B3SOIPD_MOD_PBETA2 559 +#define B3SOIPD_MOD_PVDSATII0 560 +#define B3SOIPD_MOD_PLII 561 +#define B3SOIPD_MOD_PESATII 562 +#define B3SOIPD_MOD_PSII0 563 +#define B3SOIPD_MOD_PSII1 564 +#define B3SOIPD_MOD_PSII2 565 +#define B3SOIPD_MOD_PSIID 566 +#define B3SOIPD_MOD_PAGIDL 567 +#define B3SOIPD_MOD_PBGIDL 568 +#define B3SOIPD_MOD_PNGIDL 569 +#define B3SOIPD_MOD_PNTUN 570 +#define B3SOIPD_MOD_PNDIODE 571 +#define B3SOIPD_MOD_PNRECF0 572 +#define B3SOIPD_MOD_PNRECR0 573 +#define B3SOIPD_MOD_PISBJT 574 +#define B3SOIPD_MOD_PISDIF 575 +#define B3SOIPD_MOD_PISREC 576 +#define B3SOIPD_MOD_PISTUN 577 +#define B3SOIPD_MOD_PVREC0 578 +#define B3SOIPD_MOD_PVTUN0 579 +#define B3SOIPD_MOD_PNBJT 580 +#define B3SOIPD_MOD_PLBJT0 581 +#define B3SOIPD_MOD_PVABJT 582 +#define B3SOIPD_MOD_PAELY 583 +#define B3SOIPD_MOD_PAHLI 584 +#define B3SOIPD_MOD_PVSDFB 585 +#define B3SOIPD_MOD_PVSDTH 586 +#define B3SOIPD_MOD_PDELVT 587 +#define B3SOIPD_MOD_PACDE 588 +#define B3SOIPD_MOD_PMOIN 589 +/* Added for binning - END3 */ +#define B3SOIPD_MOD_TNOM 701 +#define B3SOIPD_MOD_CGSO 702 +#define B3SOIPD_MOD_CGDO 703 +#define B3SOIPD_MOD_CGEO 704 +#define B3SOIPD_MOD_XPART 705 +#define B3SOIPD_MOD_RSH 706 +#define B3SOIPD_MOD_NMOS 814 +#define B3SOIPD_MOD_PMOS 815 +#define B3SOIPD_MOD_NOIA 816 +#define B3SOIPD_MOD_NOIB 817 +#define B3SOIPD_MOD_NOIC 818 +#define B3SOIPD_MOD_LINT 819 +#define B3SOIPD_MOD_LL 820 +#define B3SOIPD_MOD_LLN 821 +#define B3SOIPD_MOD_LW 822 +#define B3SOIPD_MOD_LWN 823 +#define B3SOIPD_MOD_LWL 824 +#define B3SOIPD_MOD_WINT 827 +#define B3SOIPD_MOD_WL 828 +#define B3SOIPD_MOD_WLN 829 +#define B3SOIPD_MOD_WW 830 +#define B3SOIPD_MOD_WWN 831 +#define B3SOIPD_MOD_WWL 832 +#define B3SOIPD_MOD_DWC 835 +#define B3SOIPD_MOD_DLC 836 +#define B3SOIPD_MOD_EM 837 +#define B3SOIPD_MOD_EF 838 +#define B3SOIPD_MOD_AF 839 +#define B3SOIPD_MOD_KF 840 +#define B3SOIPD_MOD_NOIF 841 +#define B3SOIPD_MOD_PBSWG 843 +#define B3SOIPD_MOD_MJSWG 844 +#define B3SOIPD_MOD_CJSWG 845 +#define B3SOIPD_MOD_CSDESW 846 +/* device questions */ +#define B3SOIPD_DNODE 901 +#define B3SOIPD_GNODE 902 +#define B3SOIPD_SNODE 903 +#define B3SOIPD_BNODE 904 +#define B3SOIPD_ENODE 905 +#define B3SOIPD_DNODEPRIME 906 +#define B3SOIPD_SNODEPRIME 907 +#define B3SOIPD_VBD 908 +#define B3SOIPD_VBS 909 +#define B3SOIPD_VGS 910 +#define B3SOIPD_VES 911 +#define B3SOIPD_VDS 912 +#define B3SOIPD_CD 913 +#define B3SOIPD_CBS 914 +#define B3SOIPD_CBD 915 +#define B3SOIPD_GM 916 +#define B3SOIPD_GDS 917 +#define B3SOIPD_GMBS 918 +#define B3SOIPD_GBD 919 +#define B3SOIPD_GBS 920 +#define B3SOIPD_QB 921 +#define B3SOIPD_CQB 922 +#define B3SOIPD_QG 923 +#define B3SOIPD_CQG 924 +#define B3SOIPD_QD 925 +#define B3SOIPD_CQD 926 +#define B3SOIPD_CGG 927 +#define B3SOIPD_CGD 928 +#define B3SOIPD_CGS 929 +#define B3SOIPD_CBG 930 +#define B3SOIPD_CAPBD 931 +#define B3SOIPD_CQBD 932 +#define B3SOIPD_CAPBS 933 +#define B3SOIPD_CQBS 934 +#define B3SOIPD_CDG 935 +#define B3SOIPD_CDD 936 +#define B3SOIPD_CDS 937 +#define B3SOIPD_VON 938 +#define B3SOIPD_VDSAT 939 +#define B3SOIPD_QBS 940 +#define B3SOIPD_QBD 941 +#define B3SOIPD_SOURCECONDUCT 942 +#define B3SOIPD_DRAINCONDUCT 943 +#define B3SOIPD_CBDB 944 +#define B3SOIPD_CBSB 945 +#define B3SOIPD_GMID 946 +#include "b3soipdext.h" +#ifdef __STDC__ +extern void B3SOIPDevaluate (double, double, double, B3SOIPDinstance *, + B3SOIPDmodel *, double *, double *, double *, + double *, double *, double *, double *, double *, + double *, double *, double *, double *, double *, + double *, double *, double *, double *, double *, + CKTcircuit *); +extern int B3SOIPDdebug (B3SOIPDmodel *, B3SOIPDinstance *, CKTcircuit *, + int); +extern int B3SOIPDcheckModel (B3SOIPDmodel *, B3SOIPDinstance *, + CKTcircuit *); +#else /* stdc */ +extern void B3SOIPDevaluate (); +extern int B3SOIPDdebug (); +extern int B3SOIPDcheckModel (); +#endif /* stdc */ + +#endif /*B3SOIPD */ diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipddel.c b/src/spicelib/devices/bsim3soi_pd/b3soipddel.c new file mode 100644 index 000000000..4d646cbc6 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipddel.c @@ -0,0 +1,42 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipddel.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "b3soipddef.h" +#include "sperror.h" +#include "gendefs.h" +#include "suffix.h" + + +int +B3SOIPDdelete (inModel, name, inInst) + GENmodel *inModel; + IFuid name; + GENinstance **inInst; +{ + B3SOIPDinstance **fast = (B3SOIPDinstance **) inInst; + B3SOIPDmodel *model = (B3SOIPDmodel *) inModel; + B3SOIPDinstance **prev = NULL; + B3SOIPDinstance *here; + + for (; model; model = model->B3SOIPDnextModel) + { + prev = &(model->B3SOIPDinstances); + for (here = *prev; here; here = *prev) + { + if (here->B3SOIPDname == name || (fast && here == *fast)) + { + *prev = here->B3SOIPDnextInstance; + FREE (here); + return (OK); + } + prev = &(here->B3SOIPDnextInstance); + } + } + return (E_NODEV); +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipddest.c b/src/spicelib/devices/bsim3soi_pd/b3soipddest.c new file mode 100644 index 000000000..47ea96a96 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipddest.c @@ -0,0 +1,43 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipddest.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "b3soipddef.h" +#include "suffix.h" + +void +B3SOIPDdestroy (inModel) + GENmodel **inModel; +{ + B3SOIPDmodel **model = (B3SOIPDmodel **) inModel; + B3SOIPDinstance *here; + B3SOIPDinstance *prev = NULL; + B3SOIPDmodel *mod = *model; + B3SOIPDmodel *oldmod = NULL; + + for (; mod; mod = mod->B3SOIPDnextModel) + { + if (oldmod) + FREE (oldmod); + oldmod = mod; + prev = (B3SOIPDinstance *) NULL; + for (here = mod->B3SOIPDinstances; here; + here = here->B3SOIPDnextInstance) + { + if (prev) + FREE (prev); + prev = here; + } + if (prev) + FREE (prev); + } + if (oldmod) + FREE (oldmod); + *model = NULL; + return; +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdext.h b/src/spicelib/devices/bsim3soi_pd/b3soipdext.h new file mode 100644 index 000000000..874bff3cf --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdext.h @@ -0,0 +1,55 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung +File: b3soipdext.h +**********/ + +#ifdef __STDC__ +extern int B3SOIPDacLoad (GENmodel *, CKTcircuit *); +extern int B3SOIPDask (CKTcircuit *, GENinstance *, int, IFvalue *, + IFvalue *); +extern int B3SOIPDconvTest (GENmodel *, CKTcircuit *); +extern int B3SOIPDdelete (GENmodel *, IFuid, GENinstance **); +extern void B3SOIPDdestroy (GENmodel **); +extern int B3SOIPDgetic (GENmodel *, CKTcircuit *); +extern int B3SOIPDload (GENmodel *, CKTcircuit *); +extern int B3SOIPDmAsk (CKTcircuit *, GENmodel *, int, IFvalue *); +extern int B3SOIPDmDelete (GENmodel **, IFuid, GENmodel *); +extern int B3SOIPDmParam (int, IFvalue *, GENmodel *); +extern void B3SOIPDmosCap (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 *, double *); +extern int B3SOIPDparam (int, IFvalue *, GENinstance *, IFvalue *); +extern int B3SOIPDpzLoad (GENmodel *, CKTcircuit *, SPcomplex *); +extern int B3SOIPDsetup (SMPmatrix *, GENmodel *, CKTcircuit *, int *); +extern int B3SOIPDtemp (GENmodel *, CKTcircuit *); +extern int B3SOIPDtrunc (GENmodel *, CKTcircuit *, double *); +extern int B3SOIPDnoise (int, int, GENmodel *, CKTcircuit *, Ndata *, + double *); +extern int B3SOIPDunsetup (GENmodel *, CKTcircuit *); + +#else /* stdc */ +extern int B3SOIPDacLoad (); +extern int B3SOIPDdelete (); +extern void B3SOIPDdestroy (); +extern int B3SOIPDgetic (); +extern int B3SOIPDload (); +extern int B3SOIPDmDelete (); +extern int B3SOIPDask (); +extern int B3SOIPDmAsk (); +extern int B3SOIPDconvTest (); +extern int B3SOIPDtemp (); +extern int B3SOIPDmParam (); +extern void B3SOIPDmosCap (); +extern int B3SOIPDparam (); +extern int B3SOIPDpzLoad (); +extern int B3SOIPDsetup (); +extern int B3SOIPDtrunc (); +extern int B3SOIPDnoise (); +extern int B3SOIPDunsetup (); + +#endif /* stdc */ diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdgetic.c b/src/spicelib/devices/bsim3soi_pd/b3soipdgetic.c new file mode 100644 index 000000000..56df0e12f --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdgetic.c @@ -0,0 +1,57 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipdgetic.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "b3soipddef.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIPDgetic (inModel, ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + B3SOIPDmodel *model = (B3SOIPDmodel *) inModel; + B3SOIPDinstance *here; + + for (; model; model = model->B3SOIPDnextModel) + { + for (here = model->B3SOIPDinstances; here; + here = here->B3SOIPDnextInstance) + { + if (!here->B3SOIPDicVBSGiven) + { + here->B3SOIPDicVBS = *(ckt->CKTrhs + here->B3SOIPDbNode) + - *(ckt->CKTrhs + here->B3SOIPDsNode); + } + if (!here->B3SOIPDicVDSGiven) + { + here->B3SOIPDicVDS = *(ckt->CKTrhs + here->B3SOIPDdNode) + - *(ckt->CKTrhs + here->B3SOIPDsNode); + } + if (!here->B3SOIPDicVGSGiven) + { + here->B3SOIPDicVGS = *(ckt->CKTrhs + here->B3SOIPDgNode) + - *(ckt->CKTrhs + here->B3SOIPDsNode); + } + if (!here->B3SOIPDicVESGiven) + { + here->B3SOIPDicVES = *(ckt->CKTrhs + here->B3SOIPDeNode) + - *(ckt->CKTrhs + here->B3SOIPDsNode); + } + if (!here->B3SOIPDicVPSGiven) + { + here->B3SOIPDicVPS = *(ckt->CKTrhs + here->B3SOIPDpNode) + - *(ckt->CKTrhs + here->B3SOIPDsNode); + } + } + } + return (OK); +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdinit.c b/src/spicelib/devices/bsim3soi_pd/b3soipdinit.c new file mode 100644 index 000000000..3c8d65916 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdinit.c @@ -0,0 +1,62 @@ +#include + +#include + +#include "b3soipditf.h" +#include "b3soipdext.h" +#include "b3soipdinit.h" + + +SPICEdev B3SOIPDinfo = { + {"B3SOIPD", + "Berkeley SOI (PD) MOSFET model version 2.0", + + &B3SOIPDnSize, + &B3SOIPDnSize, + B3SOIPDnames, + + &B3SOIPDpTSize, + B3SOIPDpTable, + + &B3SOIPDmPTSize, + B3SOIPDmPTable, + DEV_DEFAULT} + , + +DEVparam:B3SOIPDparam, +DEVmodParam:B3SOIPDmParam, +DEVload:B3SOIPDload, +DEVsetup:B3SOIPDsetup, +DEVunsetup:B3SOIPDunsetup, +DEVpzSetup:B3SOIPDsetup, +DEVtemperature:B3SOIPDtemp, +DEVtrunc:B3SOIPDtrunc, +DEVfindBranch:NULL, +DEVacLoad:B3SOIPDacLoad, +DEVaccept:NULL, +DEVdestroy:B3SOIPDdestroy, +DEVmodDelete:B3SOIPDmDelete, +DEVdelete:B3SOIPDdelete, +DEVsetic:B3SOIPDgetic, +DEVask:B3SOIPDask, +DEVmodAsk:B3SOIPDmAsk, +DEVpzLoad:B3SOIPDpzLoad, +DEVconvTest:B3SOIPDconvTest, +DEVsenSetup:NULL, +DEVsenLoad:NULL, +DEVsenUpdate:NULL, +DEVsenAcLoad:NULL, +DEVsenPrint:NULL, +DEVsenTrunc:NULL, +DEVdisto:NULL, +DEVnoise:B3SOIPDnoise, + +DEVinstSize:&B3SOIPDiSize, +DEVmodSize:&B3SOIPDmSize +}; + +SPICEdev * +get_bsim3soipd_info (void) +{ + return &B3SOIPDinfo; +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdinit.h b/src/spicelib/devices/bsim3soi_pd/b3soipdinit.h new file mode 100644 index 000000000..2a487074e --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdinit.h @@ -0,0 +1,13 @@ +#ifndef _B3SOIPDINIT_H +#define _B3SOIPDINIT_H + +extern IFparm B3SOIPDpTable[]; +extern IFparm B3SOIPDmPTable[]; +extern char *B3SOIPDnames[]; +extern int B3SOIPDpTSize; +extern int B3SOIPDmPTSize; +extern int B3SOIPDnSize; +extern int B3SOIPDiSize; +extern int B3SOIPDmSize; + +#endif diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipditf.h b/src/spicelib/devices/bsim3soi_pd/b3soipditf.h new file mode 100644 index 000000000..2d2c6a987 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipditf.h @@ -0,0 +1,13 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung +File: b3soipditf.h +**********/ +#ifndef DEV_B3SOIPD +#define DEV_B3SOIPD + +#include "b3soipdext.h" + +SPICEdev *get_bsim3soipd_info (void); + +#endif diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdld.c b/src/spicelib/devices/bsim3soi_pd/b3soipdld.c new file mode 100644 index 000000000..d766d2381 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdld.c @@ -0,0 +1,4636 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipdld.c 98/5/01 +Modified by Pin Su, Weidong Liu and Jan Feng 99/2/15 +Modified by Pin Su 99/4/30 +Modified by Pin Su, Wei Jin 99/9/27 +Modified by Pin Su 00/3/1 +Modified by Pin Su 00/8/15 +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "b3soipddef.h" +#include "trandefs.h" +#include "const.h" +#include "sperror.h" +#include "devdefs.h" +#include "suffix.h" + +#define EPSOX 3.453133e-11 +#define EPSSI 1.03594e-10 +#define Charge_q 1.60219e-19 +#define KboQ 8.617087e-5 /* Kb / q */ +#define Eg300 1.115 /* energy gap at 300K */ +#define DELTA_1 0.02 +#define DELTA_2 0.02 +#define DELTA_3 0.02 +/* Original is 0.02, for matching IBM model, change to 0.08 */ +#define DELTA_3_SOI 0.08 +#define DELTA_4 0.02 +#define DELT_Vbseff 0.005 +#define DELTA_VFB 0.02 +#define CONST_2OV3 0.6666666666 + +#define MAX_EXPL 2.688117142e+43 +#define MIN_EXPL 3.720075976e-44 +#define EXPL_THRESHOLD 100.0 +#define DEXP(A,B,C) { \ + if (A > EXPL_THRESHOLD) { \ + B = MAX_EXPL*(1.0+(A)-EXPL_THRESHOLD); \ + C = MAX_EXPL; \ + } else if (A < -EXPL_THRESHOLD) { \ + B = MIN_EXPL; \ + C = 0; \ + } else { \ + B = exp(A); \ + C = B; \ + } \ + } + +#define FLOG(A) fabs(A) + 1e-14 + + + /* B3SOIPDlimit(vnew,vold) + * limits the per-iteration change of any absolute voltage value + */ + +double +B3SOIPDlimit (vnew, vold, limit, check) + double vnew; + double vold; + double limit; + int *check; +{ + double T0, T1; + + if (isnan (vnew) || isnan (vold)) + { + fprintf (stderr, + "Alberto says: YOU TURKEY! The limiting function received NaN.\n"); + fprintf (stderr, "New prediction returns to 0.0!\n"); + vnew = 0.0; + *check = 1; + } + T0 = vnew - vold; + T1 = fabs (T0); + if (T1 > limit) + { + if (T0 > 0.0) + vnew = vold + limit; + else + vnew = vold - limit; + *check = 1; + } + return vnew; +} + + + +int +B3SOIPDload (inModel, ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + B3SOIPDmodel *model = (B3SOIPDmodel *) inModel; + B3SOIPDinstance *here; + int selfheat; + + double SourceSatCurrent, DrainSatCurrent, Gmin; + double ag0, qgd, qgs, qgb, von, cbhat, VgstNVt, ExpVgst; + double cdhat, cdreq, ceqbd, ceqbs, ceqqb, ceqqd, ceqqg, ceq, geq; + double evbd, evbs, arg, sarg; + double delvbd, delvbs, delvds, delvgd, delvgs; + double Vfbeff, dVfbeff_dVg, dVfbeff_dVd, dVfbeff_dVb, V3, V4; + double tol, PhiB, PhiBSWG, MJSWG; + double gcgdb, gcggb, gcgsb, gcgeb, gcgT; + double gcsdb, gcsgb, gcssb, gcseb, gcsT; + double gcddb, gcdgb, gcdsb, gcdeb, gcdT; + double gcbdb, gcbgb, gcbsb, gcbeb, gcbT; + double gcedb, gcegb, gcesb, gceeb, gceT; + double gcTt, gTtg, gTtb, gTtdp, gTtt, gTtsp; + double vbd, vbs, vds, vgb, vgd, vgs, vgdo, xfact; + double vg, vd, vs, vp, ve, vb; + double Vds, Vgs, Vbs, Gmbs, FwdSum, RevSum; + double Vgs_eff, Vfb, dVfb_dVb, dVfb_dVd, dVfb_dT; + double Phis, dPhis_dVb, sqrtPhis, dsqrtPhis_dVb, Vth, dVth_dVb, dVth_dVd, + dVth_dT; + double Vgst, dVgst_dVg, dVgst_dVb, dVgs_eff_dVg, Nvtm; + double Vgdt, Vgsaddvth, Vgsaddvth2, Vgsaddvth1o3, n, dn_dVb, Vtm; + double ExpArg, V0; + double ueff, dueff_dVg, dueff_dVd, dueff_dVb, dueff_dT; + double Esat, dEsat_dVg, dEsat_dVd, dEsat_dVb, Vdsat, Vdsat0; + double EsatL, dEsatL_dVg, dEsatL_dVd, dEsatL_dVb, dEsatL_dT; + double dVdsat_dVg, dVdsat_dVb, dVdsat_dVd, dVdsat_dT, Vasat, dAlphaz_dVg, + dAlphaz_dVb; + double dVasat_dVg, dVasat_dVb, dVasat_dVd, dVasat_dT; + double Va, Va2, dVa_dVd, dVa_dVg, dVa_dVb, dVa_dT; + double Vbseff, dVbseff_dVb; + double Alphaz, CoxWL; + double dVgdt_dVg, dVgdt_dVd, dVgdt_dVb; + double T0, dT0_dVg, dT0_dVd, dT0_dVb, dT0_dVrg, dT0_dT; + double T1, dT1_dVg, dT1_dVd, dT1_dVb, dT1_dT; + double T2, dT2_dVg, dT2_dVd, dT2_dVb, dT2_dT; + double T3, dT3_dVg, dT3_dVd, dT3_dVb, dT3_dT; + double T4, dT4_dVg, dT4_dVd, dT4_dVb, dT4_dT; + double T5, dT5_dVg, dT5_dVd, dT5_dVb, dT5_dT; + double T6, dT6_dVg, dT6_dVd, dT6_dVb, dT6_dT; + double T7, dT7_dVg, dT7_dVd, dT7_dVb; + double T8, dT8_dVg, dT8_dVd, dT8_dVb, dT8_dVrg; + double T9, dT9_dVg, dT9_dVd, dT9_dVb, dT9_dVrg; + double T10, dT10_dVg, dT10_dVb, dT10_dVd; + double T11, T12; + double tmp, Abulk, dAbulk_dVb, Abulk0, dAbulk0_dVb; + double T100, T101; + double VACLM, dVACLM_dVg, dVACLM_dVd, dVACLM_dVb, dVACLM_dT; + double VADIBL, dVADIBL_dVg, dVADIBL_dVd, dVADIBL_dVb, dVADIBL_dT; + double VAHCE, dVAHCE_dVg, dVAHCE_dVd, dVAHCE_dVb; + double Xdep, dXdep_dVb, lt1, dlt1_dVb, ltw, dltw_dVb; + double Delt_vth, dDelt_vth_dVb, dDelt_vth_dT; + 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 tempv, a1; + + double Vgsteff, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb, dVgsteff_dT; + double Vdseff, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb, dVdseff_dT; + double VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb; + double diffVds, diffVdsCV; + double dAbulk_dVg, dn_dVd; + double beta, dbeta_dVg, dbeta_dVd, dbeta_dVb, dbeta_dT; + double gche, dgche_dVg, dgche_dVd, dgche_dVb, dgche_dT; + double fgche1, dfgche1_dVg, dfgche1_dVd, dfgche1_dVb, dfgche1_dT; + double fgche2, dfgche2_dVg, dfgche2_dVd, dfgche2_dVb, dfgche2_dT; + double Idl, dIdl_dVg, dIdl_dVd, dIdl_dVb, dIdl_dT; + double Ids, Gm, Gds, Gmb; + double CoxWovL; + double Rds, dRds_dVg, dRds_dVb, dRds_dT, WVCox, WVCoxRds; + double Vgst2Vtm, dVgst2Vtm_dT, VdsatCV, dVdsatCV_dVd, dVdsatCV_dVg, + dVdsatCV_dVb; + double Leff, Weff, dWeff_dVg, dWeff_dVb; + double AbulkCV, dAbulkCV_dVb; + double qgdo, qgso, cgdo, cgso; + + double dxpart, sxpart; + + struct b3soipdSizeDependParam *pParam; + int ByPass, Check, ChargeComputationNeeded, J, error, I; + double junk[50]; + + double gbbsp, gbbdp, gbbg, gbbb, gbbp, gbbT; + double gddpsp, gddpdp, gddpg, gddpb, gddpT; + double gsspsp, gsspdp, gsspg, gsspb, gsspT; + double Gbpbs, Gbpps; + double vse, vde, ves, ved, veb, vge, delves, vedo, delved; + double vps, vpd, Vps, delvps; + double Vbd, Ves, Vesfb, sqrtXdep, DeltVthtemp, dDeltVthtemp_dT; + double Vbp, dVbp_dVb; + double DeltVthw, dDeltVthw_dVb, dDeltVthw_dT; + double Gm0, Gds0, Gmb0, GmT0, Gmc, GmT; + double dDIBL_Sft_dVb; + double diffVdsii; + double Idgidl, Gdgidld, Gdgidlg, Isgidl, Gsgidlg; + double Gjsd, Gjss, Gjsb, GjsT, Gjdd, Gjdb, GjdT; + double Ibp, Iii, Giid, Giig, Giib, GiiT, Gcd, Gcb, GcT, ceqbody, ceqbodcon; + double gppb, gppp, gppT; + double delTemp, deldelTemp, Temp; + double ceqth, ceqqth; + double K1, WL; + double qjs, gcjsbs, gcjsT; + double qjd, gcjdbs, gcjdds, gcjdT; + double qge; + double ceqqe; + double ni, Eg, Cbox, Nfb, CboxWL; + double cjsbs; + double dVfbeff_dVrg; + double qinv, qgate, qbody, qdrn, qsrc, qsub, cqgate, cqbody, cqdrn, cqsub, + cqtemp; + 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; + double Vbseff0; + double Vdsatii, dVdsatii_dVg, dVdsatii_dVd, dVdsatii_dVb, dVdsatii_dT; + double Ibjt, dIbjt_dVb, dIbjt_dVd, dIbjt_dT; + double Ibs1, dIbs1_dVb, dIbs1_dT; + double Ibs2, dIbs2_dVb, dIbs2_dT; + double Ibs3, dIbs3_dVb, dIbs3_dVd, dIbs3_dT; + double Ibs4, dIbs4_dVb, dIbs4_dT; + double Ibd1, dIbd1_dVb, dIbd1_dVd, dIbd1_dT; + double Ibd2, dIbd2_dVb, dIbd2_dVd, dIbd2_dT; + double Ibd3, dIbd3_dVb, dIbd3_dVd, dIbd3_dT; + double Ibd4, dIbd4_dVb, dIbd4_dVd, dIbd4_dT; + double ExpVbs1, dExpVbs1_dVb, dExpVbs1_dT; + double ExpVbs2, dExpVbs2_dVb, dExpVbs2_dT; + double ExpVbs4, dExpVbs4_dVb, dExpVbs4_dT; + double ExpVbd1, dExpVbd1_dVb, dExpVbd1_dT; + double ExpVbd2, dExpVbd2_dVb, dExpVbd2_dT; + double ExpVbd4, dExpVbd4_dVb, dExpVbd4_dT; + double WTsi, NVtm1, NVtm2; + double Ic, dIc_dVb, dIc_dVd; + double Ibs, dIbs_dVb, dIbs_dVd; + double Ibd, dIbd_dVb; + double Denomi, dDenomi_dVg, dDenomi_dVd, dDenomi_dVb, dDenomi_dT; + double Qsub0, dQsub0_dVg, dQsub0_dVb, dQsub0_dVd; + double Qac0, dQac0_dVb, dQac0_dVd; + double Qdep0, dQdep0_dVb; + double Qe1, dQe1_dVb, dQe1_dVe, dQe1_dT; + double Ce1b, Ce1e, Ce1T; + double dQac0_dVrg, dQsub0_dVrg; + +/* for self-heating */ + double vbi, vfbb, phi, sqrtPhi, Xdep0, jbjt, jdif, jrec, jtun, u0temp, + vsattemp; + double rds0, ua, ub, uc; + double dvbi_dT, dvfbb_dT, djbjt_dT, djdif_dT, djrec_dT, djtun_dT, + du0temp_dT; + double dvsattemp_dT, drds0_dT, dua_dT, dub_dT, duc_dT, dni_dT, dVtm_dT; + double dVfbeff_dT, dQac0_dT, dQsub0_dT; + double CbT, CsT, CgT, CeT; + + +/* v2.0 release */ + double Vbsh, dVbsh_dVb; + double sqrtPhisExt, dsqrtPhisExt_dVb; + double T13, T14; + double dT11_dVb, dT13_dVb, dT14_dVb; + double dVgst_dVd; + double Vdsatii0, dVdsatii0_dT; + double VgsStep, dVgsStep_dT, Ratio, dRatio_dVg, dRatio_dVb, dRatio_dVd, + dRatio_dT, dTempRatio_dT; + double Vdiff, dVdiff_dVg, dVdiff_dVb, dVdiff_dVd, dVdiff_dT; + double dNVtm1_dT, dNVtm2_dT; + double NVtmf, NVtmr, dNVtmf_dT, dNVtmr_dT; + double TempRatioMinus1; + double Ahli, dAhli_dT; + double WsTsi, WdTsi; + double dPhiBSWG_dT, dcjsbs_dT, darg_dT, ddT3_dVb_dT; + double dT7_dT, dT0_dT7, dT1_dT7, dT2_dT7; + double CoxWLb, CoxWLcenb; + double ExpVbsNVtm, dExpVbsNVtm_dVb, dExpVbsNVtm_dT; + double ExpVbdNVtm, dExpVbdNVtm_dVb, dExpVbdNVtm_dVd, dExpVbdNVtm_dT; + double Ien, dIen_dT, Iendif, dIendif_dT; + double Ibsdif, dIbsdif_dVb, dIbsdif_dT; + double Ibddif, dIbddif_dVb, dIbddif_dVd, dIbddif_dT; + double Ehlis, dEhlis_dVb, dEhlis_dT; + double EhlisFactor, dEhlisFactor_dVb, dEhlisFactor_dT; + double Ehlid, dEhlid_dVb, dEhlid_dVd, dEhlid_dT; + double EhlidFactor, dEhlidFactor_dVb, dEhlidFactor_dVd, dEhlidFactor_dT; + double E2ndFactor, dE2ndFactor_dVb, dE2ndFactor_dVd, dE2ndFactor_dT; + double dT10_dT, dT11_dT, DioMax; + double cjdbs, dcjdbs_dT; + double wdios, wdiod, wdiosCV, wdiodCV; + +/* for capMod3 */ + double Cox, Tox, Tcen, dTcen_dVg, dTcen_dVb, LINK, Ccen, Coxeff, + dCoxeff_dVg, dCoxeff_dVb; + double CoxWLcen, QovCox, dQac0_dVg, DeltaPhi, dDeltaPhi_dVg, dDeltaPhi_dVd, + dDeltaPhi_dVb; + double dTcen_dVd, dTcen_dT, dCoxeff_dVd, dCoxeff_dT, dCoxWLcenb_dT, qinoi, + qbulk; + double T3zb, lt1zb, ltwzb, Theta0zb; + double Delt_vthzb, dDelt_vthzb_dT; + double DeltVthwzb, dDeltVthwzb_dT; + double DeltVthtempzb, dDeltVthtempzb_dT; + double Vthzb, dVthzb_dT, Vfbzb, dVfbzb_dT; + + +/* v2.2 release */ + double Vgb, dVgb_dVg, dVgb_dVb, Vox, dVox_dVg, dVox_dVd, dVox_dVb; + double OxideRatio, Vaux, dVaux_dVg, dVaux_dVd, dVaux_dVb; + double Igb, dIgb_dVg, dIgb_dVd, dIgb_dVb; + double ceqgate; + double dT0_dVox, Voxeff, dVoxeff_dVox; + double dVox_dT, dVaux_dT, dIgb_dT; + double Voxacc, dVoxacc_dVg, dVoxacc_dVd, dVoxacc_dVb, dVoxacc_dT; + double Voxdepinv, dVoxdepinv_dVg, dVoxdepinv_dVb, dVoxdepinv_dVd, + dVoxdepinv_dT; + double Igb1, dIgb1_dVg, dIgb1_dVd, dIgb1_dVb, dIgb1_dT; + double Igb2, dIgb2_dVg, dIgb2_dVd, dIgb2_dVb, dIgb2_dT; + double gigs, gigd, gigb, gigg; + double gigT; + + + for (; model != NULL; model = model->B3SOIPDnextModel) + { + for (here = model->B3SOIPDinstances; here != NULL; + here = here->B3SOIPDnextInstance) + { + Check = 0; + ByPass = 0; + selfheat = (model->B3SOIPDshMod == 1) && (here->B3SOIPDrth0 != 0.0); + pParam = here->pParam; + + + if ((ckt->CKTmode & MODEINITSMSIG)) + { + vs = *(ckt->CKTrhsOld + here->B3SOIPDsNodePrime); + if (!here->B3SOIPDvbsusrGiven) + { + vbs = *(ckt->CKTstate0 + here->B3SOIPDvbs); + vb = *(ckt->CKTrhsOld + here->B3SOIPDbNode); + } + else + { + vbs = here->B3SOIPDvbsusr; + vb = here->B3SOIPDvbsusr + vs; + } + vgs = *(ckt->CKTstate0 + here->B3SOIPDvgs); + ves = *(ckt->CKTstate0 + here->B3SOIPDves); + vps = *(ckt->CKTstate0 + here->B3SOIPDvps); + vds = *(ckt->CKTstate0 + here->B3SOIPDvds); + delTemp = *(ckt->CKTstate0 + here->B3SOIPDdeltemp); + + vg = *(ckt->CKTrhsOld + here->B3SOIPDgNode); + vd = *(ckt->CKTrhsOld + here->B3SOIPDdNodePrime); + vp = *(ckt->CKTrhsOld + here->B3SOIPDpNode); + ve = *(ckt->CKTrhsOld + here->B3SOIPDeNode); + + } + else if ((ckt->CKTmode & MODEINITTRAN)) + { + vs = *(ckt->CKTrhsOld + here->B3SOIPDsNodePrime); + if (!here->B3SOIPDvbsusrGiven) + { + vbs = *(ckt->CKTstate1 + here->B3SOIPDvbs); + vb = *(ckt->CKTrhsOld + here->B3SOIPDbNode); + } + else + { + vbs = here->B3SOIPDvbsusr; + vb = here->B3SOIPDvbsusr + vs; + } + vgs = *(ckt->CKTstate1 + here->B3SOIPDvgs); + ves = *(ckt->CKTstate1 + here->B3SOIPDves); + vps = *(ckt->CKTstate1 + here->B3SOIPDvps); + vds = *(ckt->CKTstate1 + here->B3SOIPDvds); + delTemp = *(ckt->CKTstate1 + here->B3SOIPDdeltemp); + + vg = *(ckt->CKTrhsOld + here->B3SOIPDgNode); + vd = *(ckt->CKTrhsOld + here->B3SOIPDdNodePrime); + vp = *(ckt->CKTrhsOld + here->B3SOIPDpNode); + ve = *(ckt->CKTrhsOld + here->B3SOIPDeNode); + + } + else if ((ckt->CKTmode & MODEINITJCT) && !here->B3SOIPDoff) + { + vds = model->B3SOIPDtype * here->B3SOIPDicVDS; + vgs = model->B3SOIPDtype * here->B3SOIPDicVGS; + ves = model->B3SOIPDtype * here->B3SOIPDicVES; + vbs = model->B3SOIPDtype * here->B3SOIPDicVBS; + vps = model->B3SOIPDtype * here->B3SOIPDicVPS; + + vg = vd = vs = vp = ve = 0.0; + + + delTemp = 0.0; + here->B3SOIPDphi = pParam->B3SOIPDphi; + + + + if ((vds == 0.0) && (vgs == 0.0) && (vbs == 0.0) && + ((ckt->CKTmode & (MODETRAN | MODEAC | MODEDCOP | + MODEDCTRANCURVE)) + || (!(ckt->CKTmode & MODEUIC)))) + { + vbs = 0.0; + vgs = model->B3SOIPDtype * 0.1 + pParam->B3SOIPDvth0; + vds = 0.0; + ves = 0.0; + vps = 0.0; + } + } + else if ((ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) && + (here->B3SOIPDoff)) + { + delTemp = vps = vbs = vgs = vds = ves = 0.0; + vg = vd = vs = vp = ve = 0.0; + } + else + { +#ifndef PREDICTOR + if ((ckt->CKTmode & MODEINITPRED)) + { + xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1]; + *(ckt->CKTstate0 + here->B3SOIPDvbs) = + *(ckt->CKTstate1 + here->B3SOIPDvbs); + vbs = (1.0 + xfact) * (*(ckt->CKTstate1 + here->B3SOIPDvbs)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIPDvbs))); + *(ckt->CKTstate0 + here->B3SOIPDvgs) = + *(ckt->CKTstate1 + here->B3SOIPDvgs); + vgs = (1.0 + xfact) * (*(ckt->CKTstate1 + here->B3SOIPDvgs)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIPDvgs))); + *(ckt->CKTstate0 + here->B3SOIPDves) = + *(ckt->CKTstate1 + here->B3SOIPDves); + ves = (1.0 + xfact) * (*(ckt->CKTstate1 + here->B3SOIPDves)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIPDves))); + *(ckt->CKTstate0 + here->B3SOIPDvps) = + *(ckt->CKTstate1 + here->B3SOIPDvps); + vps = (1.0 + xfact) * (*(ckt->CKTstate1 + here->B3SOIPDvps)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIPDvps))); + *(ckt->CKTstate0 + here->B3SOIPDvds) = + *(ckt->CKTstate1 + here->B3SOIPDvds); + vds = (1.0 + xfact) * (*(ckt->CKTstate1 + here->B3SOIPDvds)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIPDvds))); + *(ckt->CKTstate0 + here->B3SOIPDvbd) = + *(ckt->CKTstate0 + here->B3SOIPDvbs) + - *(ckt->CKTstate0 + here->B3SOIPDvds); + + *(ckt->CKTstate0 + here->B3SOIPDvg) = + *(ckt->CKTstate1 + here->B3SOIPDvg); + *(ckt->CKTstate0 + here->B3SOIPDvd) = + *(ckt->CKTstate1 + here->B3SOIPDvd); + *(ckt->CKTstate0 + here->B3SOIPDvs) = + *(ckt->CKTstate1 + here->B3SOIPDvs); + *(ckt->CKTstate0 + here->B3SOIPDvp) = + *(ckt->CKTstate1 + here->B3SOIPDvp); + *(ckt->CKTstate0 + here->B3SOIPDve) = + *(ckt->CKTstate1 + here->B3SOIPDve); + + /* Only predict ve */ + ve = (1.0 + xfact) * (*(ckt->CKTstate1 + here->B3SOIPDve)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIPDve))); + /* Then update vg, vs, vb, vd, vp base on ve */ + vs = ve - model->B3SOIPDtype * ves; + vg = model->B3SOIPDtype * vgs + vs; + vd = model->B3SOIPDtype * vds + vs; + vb = model->B3SOIPDtype * vbs + vs; + vp = model->B3SOIPDtype * vps + vs; + + delTemp = (1.0 + xfact) * (*(ckt->CKTstate1 + + here->B3SOIPDdeltemp)) - + (xfact * (*(ckt->CKTstate2 + here->B3SOIPDdeltemp))); + + if (selfheat) + { + here->B3SOIPDphi = 2.0 * here->B3SOIPDvtm + * log (pParam->B3SOIPDnpeak / here->B3SOIPDni); + } + + } + else + { +#endif /* PREDICTOR */ + + vg = B3SOIPDlimit (*(ckt->CKTrhsOld + here->B3SOIPDgNode), + *(ckt->CKTstate0 + here->B3SOIPDvg), 3.0, + &Check); + vd = + B3SOIPDlimit (*(ckt->CKTrhsOld + here->B3SOIPDdNodePrime), + *(ckt->CKTstate0 + here->B3SOIPDvd), 3.0, + &Check); + vs = + B3SOIPDlimit (*(ckt->CKTrhsOld + here->B3SOIPDsNodePrime), + *(ckt->CKTstate0 + here->B3SOIPDvs), 3.0, + &Check); + vp = + B3SOIPDlimit (*(ckt->CKTrhsOld + here->B3SOIPDpNode), + *(ckt->CKTstate0 + here->B3SOIPDvp), 3.0, + &Check); + ve = + B3SOIPDlimit (*(ckt->CKTrhsOld + here->B3SOIPDeNode), + *(ckt->CKTstate0 + here->B3SOIPDve), 3.0, + &Check); + delTemp = *(ckt->CKTrhsOld + here->B3SOIPDtempNode); + + vbs = + model->B3SOIPDtype * + (*(ckt->CKTrhsOld + here->B3SOIPDbNode) - + *(ckt->CKTrhsOld + here->B3SOIPDsNodePrime)); + + vps = model->B3SOIPDtype * (vp - vs); + vgs = model->B3SOIPDtype * (vg - vs); + ves = model->B3SOIPDtype * (ve - vs); + vds = model->B3SOIPDtype * (vd - vs); + + +#ifndef PREDICTOR + } +#endif /* PREDICTOR */ + + vbd = vbs - vds; + vgd = vgs - vds; + ved = ves - vds; + vgdo = *(ckt->CKTstate0 + here->B3SOIPDvgs) + - *(ckt->CKTstate0 + here->B3SOIPDvds); + vedo = *(ckt->CKTstate0 + here->B3SOIPDves) + - *(ckt->CKTstate0 + here->B3SOIPDvds); + delvbs = vbs - *(ckt->CKTstate0 + here->B3SOIPDvbs); + delvbd = vbd - *(ckt->CKTstate0 + here->B3SOIPDvbd); + delvgs = vgs - *(ckt->CKTstate0 + here->B3SOIPDvgs); + delves = ves - *(ckt->CKTstate0 + here->B3SOIPDves); + delvps = vps - *(ckt->CKTstate0 + here->B3SOIPDvps); + deldelTemp = delTemp - *(ckt->CKTstate0 + here->B3SOIPDdeltemp); + delvds = vds - *(ckt->CKTstate0 + here->B3SOIPDvds); + delvgd = vgd - vgdo; + delved = ved - vedo; + + if (here->B3SOIPDmode >= 0) + { + cdhat = + here->B3SOIPDcd + (here->B3SOIPDgm - + here->B3SOIPDgjdg) * delvgs + + (here->B3SOIPDgds - here->B3SOIPDgjdd) * delvds + + (here->B3SOIPDgmbs - here->B3SOIPDgjdb) * delvbs + + (here->B3SOIPDgmT - here->B3SOIPDgjdT) * deldelTemp; + } + else + { + cdhat = + here->B3SOIPDcd + (here->B3SOIPDgm - + here->B3SOIPDgjdg) * delvgd - + (here->B3SOIPDgds - here->B3SOIPDgjdd) * delvds + + (here->B3SOIPDgmbs - here->B3SOIPDgjdb) * delvbd + + (here->B3SOIPDgmT - here->B3SOIPDgjdT) * deldelTemp; + + } + cbhat = here->B3SOIPDcb + here->B3SOIPDgbgs * delvgs + + here->B3SOIPDgbbs * delvbs + + here->B3SOIPDgbds * delvds + + here->B3SOIPDgbps * delvps + here->B3SOIPDgbT * deldelTemp; + +#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 + */ + + if ((!(ckt->CKTmode & MODEINITPRED)) && (ckt->CKTbypass) + && Check == 0) + if ( + (fabs (delvbs) < + (ckt->CKTreltol * + MAX (fabs (vbs), + fabs (*(ckt->CKTstate0 + here->B3SOIPDvbs))) + + ckt->CKTvoltTol))) + if ( + (fabs (delvbd) < + (ckt->CKTreltol * + MAX (fabs (vbd), + fabs (*(ckt->CKTstate0 + here->B3SOIPDvbd))) + + ckt->CKTvoltTol))) + if ( + (fabs (delvgs) < + (ckt->CKTreltol * + MAX (fabs (vgs), + fabs (*(ckt->CKTstate0 + here->B3SOIPDvgs))) + + ckt->CKTvoltTol))) + if ( + (fabs (delves) < + (ckt->CKTreltol * + MAX (fabs (ves), + fabs (*(ckt->CKTstate0 + here->B3SOIPDves))) + + ckt->CKTvoltTol))) + if ((here->B3SOIPDbodyMod == 0) + || (here->B3SOIPDbodyMod == 2) + || (fabs (delvps) < + (ckt->CKTreltol * + MAX (fabs (vps), + fabs (* + (ckt->CKTstate0 + + here->B3SOIPDvps))) + + ckt->CKTvoltTol))) + if ((here->B3SOIPDtempNode == 0) + || (fabs (deldelTemp) < + (ckt->CKTreltol * + MAX (fabs (delTemp), + fabs (* + (ckt->CKTstate0 + + here->B3SOIPDdeltemp))) + + ckt->CKTvoltTol * 1e4))) + if ( + (fabs (delvds) < + (ckt->CKTreltol * + MAX (fabs (vds), + fabs (* + (ckt->CKTstate0 + + here->B3SOIPDvds))) + + ckt->CKTvoltTol))) + if ( + (fabs (cdhat - here->B3SOIPDcd) < + ckt->CKTreltol * MAX (fabs (cdhat), + fabs (here-> + B3SOIPDcd)) + + ckt->CKTabstol)) + if ( + (fabs (cbhat - here->B3SOIPDcb) < + ckt->CKTreltol * MAX (fabs (cbhat), + fabs (here-> + B3SOIPDcb)) + + ckt->CKTabstol)) + { /* bypass code */ + vbs = + *(ckt->CKTstate0 + here->B3SOIPDvbs); + vbd = + *(ckt->CKTstate0 + here->B3SOIPDvbd); + vgs = + *(ckt->CKTstate0 + here->B3SOIPDvgs); + ves = + *(ckt->CKTstate0 + here->B3SOIPDves); + vps = + *(ckt->CKTstate0 + here->B3SOIPDvps); + vds = + *(ckt->CKTstate0 + here->B3SOIPDvds); + delTemp = + *(ckt->CKTstate0 + + here->B3SOIPDdeltemp); + + /* calculate Vds for temperature conductance calculation + in bypass (used later when filling Temp node matrix) */ + Vds = here->B3SOIPDmode > 0 ? vds : -vds; + + vgd = vgs - vds; + vgb = vgs - vbs; + veb = ves - vbs; + + if ((ckt->CKTmode & (MODETRAN | MODEAC)) + || ((ckt->CKTmode & MODETRANOP) + && (ckt->CKTmode & MODEUIC))) + { + ByPass = 1; + goto line755; + } + else + { + goto line850; + } + } + + +#endif /*NOBYPASS*/ + von = here->B3SOIPDvon; + + + if (*(ckt->CKTstate0 + here->B3SOIPDvds) >= 0.0) + T0 = *(ckt->CKTstate0 + here->B3SOIPDvbs); + else + T0 = *(ckt->CKTstate0 + here->B3SOIPDvbd); + + + if (vds >= 0.0) + { + vbs = B3SOIPDlimit (vbs, T0, 0.2, &Check); + vbd = vbs - vds; + vb = model->B3SOIPDtype * vbs + vs; + } + else + { + vbd = B3SOIPDlimit (vbd, T0, 0.2, &Check); + vbs = vbd + vds; + vb = model->B3SOIPDtype * vbs + vd; + } + + delTemp = + B3SOIPDlimit (delTemp, + *(ckt->CKTstate0 + here->B3SOIPDdeltemp), 5.0, + &Check); + + } + +/* Calculate temperature dependent values for self-heating effect */ + Temp = delTemp + ckt->CKTtemp; + dTempRatio_dT = 1 / model->B3SOIPDtnom; + TempRatio = Temp * dTempRatio_dT; + + if (selfheat) + { + Vtm = KboQ * Temp; + + T0 = 1108.0 + Temp; + T5 = Temp * Temp; + Eg = 1.16 - 7.02e-4 * T5 / T0; + T1 = ((7.02e-4 * T5) - T0 * (14.04e-4 * Temp)) / T0 / T0; + /* T1 = dEg / dT */ + + T2 = 1.9230584e-4; /* T2 = 1 / 300.15^(3/2) */ + T5 = sqrt (Temp); + T3 = 1.45e10 * Temp * T5 * T2; + T4 = exp (21.5565981 - Eg / (2.0 * Vtm)); + ni = T3 * T4; + dni_dT = 2.175e10 * T2 * T5 * T4 + T3 * T4 * + (-Vtm * T1 + Eg * KboQ) / (2.0 * Vtm * Vtm); + + T0 = log (1.0e20 * pParam->B3SOIPDnpeak / (ni * ni)); + vbi = Vtm * T0; + dvbi_dT = KboQ * T0 + Vtm * (-2.0 * dni_dT / ni); + + if (pParam->B3SOIPDnsub > 0) + { + T0 = log (pParam->B3SOIPDnpeak / pParam->B3SOIPDnsub); + vfbb = -model->B3SOIPDtype * Vtm * T0; + dvfbb_dT = -model->B3SOIPDtype * KboQ * T0; + } + else + { + T0 = + log (-pParam->B3SOIPDnpeak * pParam->B3SOIPDnsub / ni / + ni); + vfbb = -model->B3SOIPDtype * Vtm * T0; + dvfbb_dT = -model->B3SOIPDtype * + (KboQ * T0 - Vtm * 2.0 * dni_dT / ni); + } + +/* phi = 2.0 * Vtm * log(pParam->B3SOIPDnpeak / ni); */ + phi = here->B3SOIPDphi; + sqrtPhi = sqrt (phi); + Xdep0 = sqrt (2.0 * EPSSI / (Charge_q + * pParam->B3SOIPDnpeak * 1.0e6)) + * sqrtPhi; + /* Save the values below for phi calculation in B3SOIPDaccept() */ + here->B3SOIPDvtm = Vtm; + here->B3SOIPDni = ni; + + T3 = TempRatio - 1.0; + T8 = 1 / model->B3SOIPDtnom; + T4 = Eg300 / Vtm * T3; + dT4_dT = Eg300 / Vtm / Vtm * (Vtm * T8 - T3 * KboQ); + + T7 = model->B3SOIPDxbjt * T4 / pParam->B3SOIPDndiode; + dT7_dT = model->B3SOIPDxbjt * dT4_dT / pParam->B3SOIPDndiode; + DEXP (T7, T0, dT0_dT7); + dT0_dT = dT0_dT7 * dT7_dT; + + if (model->B3SOIPDxbjt == model->B3SOIPDxdif) + { + T1 = T0; + dT1_dT = dT0_dT; + } + else + { + T7 = model->B3SOIPDxdif * T4 / pParam->B3SOIPDndiode; + dT7_dT = + model->B3SOIPDxdif * dT4_dT / pParam->B3SOIPDndiode; + DEXP (T7, T1, dT1_dT7); + dT1_dT = dT1_dT7 * dT7_dT; + } + + T7 = model->B3SOIPDxrec * T4 / pParam->B3SOIPDnrecf0; + dT7_dT = model->B3SOIPDxrec * dT4_dT / pParam->B3SOIPDnrecf0; + DEXP (T7, T2, dT2_dT7); + dT2_dT = dT2_dT7 * dT7_dT; + + /* high level injection */ + Ahli = pParam->B3SOIPDahli * T0; + dAhli_dT = pParam->B3SOIPDahli * dT0_dT; + + jbjt = pParam->B3SOIPDisbjt * T0; + jdif = pParam->B3SOIPDisdif * T1; + jrec = pParam->B3SOIPDisrec * T2; + djbjt_dT = pParam->B3SOIPDisbjt * dT0_dT; + djdif_dT = pParam->B3SOIPDisdif * dT1_dT; + djrec_dT = pParam->B3SOIPDisrec * dT2_dT; + + T7 = model->B3SOIPDxtun * T3; + dT7_dT = model->B3SOIPDxtun * T8; + DEXP (T7, T0, dT0_dT7); + dT0_dT = dT0_dT7 * dT7_dT; + jtun = pParam->B3SOIPDistun * T0; + djtun_dT = pParam->B3SOIPDistun * dT0_dT; + + u0temp = + pParam->B3SOIPDu0 * pow (TempRatio, pParam->B3SOIPDute); + du0temp_dT = + pParam->B3SOIPDu0 * pParam->B3SOIPDute * pow (TempRatio, + pParam-> + B3SOIPDute - + 1.0) * T8; + + vsattemp = pParam->B3SOIPDvsat - pParam->B3SOIPDat * T3; + dvsattemp_dT = -pParam->B3SOIPDat * T8; + + rds0 = (pParam->B3SOIPDrdsw + pParam->B3SOIPDprt + * T3) / pParam->B3SOIPDrds0denom; + drds0_dT = pParam->B3SOIPDprt / pParam->B3SOIPDrds0denom * T8; + + ua = pParam->B3SOIPDuatemp + pParam->B3SOIPDua1 * T3; + ub = pParam->B3SOIPDubtemp + pParam->B3SOIPDub1 * T3; + uc = pParam->B3SOIPDuctemp + pParam->B3SOIPDuc1 * T3; + dua_dT = pParam->B3SOIPDua1 * T8; + dub_dT = pParam->B3SOIPDub1 * T8; + duc_dT = pParam->B3SOIPDuc1 * T8; + } + else + { + vbi = pParam->B3SOIPDvbi; + vfbb = pParam->B3SOIPDvfbb; + phi = pParam->B3SOIPDphi; + sqrtPhi = pParam->B3SOIPDsqrtPhi; + Xdep0 = pParam->B3SOIPDXdep0; + jbjt = pParam->B3SOIPDjbjt; + jdif = pParam->B3SOIPDjdif; + jrec = pParam->B3SOIPDjrec; + jtun = pParam->B3SOIPDjtun; + Ahli = pParam->B3SOIPDahli; + u0temp = pParam->B3SOIPDu0temp; + vsattemp = pParam->B3SOIPDvsattemp; + rds0 = pParam->B3SOIPDrds0; + ua = pParam->B3SOIPDua; + ub = pParam->B3SOIPDub; + uc = pParam->B3SOIPDuc; + dni_dT = dvbi_dT = dvfbb_dT = djbjt_dT = djdif_dT = 0.0; + djrec_dT = djtun_dT = du0temp_dT = dvsattemp_dT = 0.0; + drds0_dT = dua_dT = dub_dT = duc_dT = 0.0; + dAhli_dT = 0; + } + + /* TempRatio used for Vth and mobility */ + if (selfheat) + { + TempRatioMinus1 = Temp / model->B3SOIPDtnom - 1.0; + } + else + { + TempRatioMinus1 = ckt->CKTtemp / model->B3SOIPDtnom - 1.0; + } + + /* determine DC current and derivatives */ + vbd = vbs - vds; + vgd = vgs - vds; + vgb = vgs - vbs; + ved = ves - vds; + veb = ves - vbs; + vge = vgs - ves; + vpd = vps - vds; + + + if (vds >= 0.0) + { /* normal mode */ + here->B3SOIPDmode = 1; + Vds = vds; + Vgs = vgs; + Vbs = vbs; + Vbd = vbd; + Ves = ves; + Vps = vps; + + wdios = pParam->B3SOIPDwdios; + wdiod = pParam->B3SOIPDwdiod; + wdiosCV = pParam->B3SOIPDwdiosCV; + wdiodCV = pParam->B3SOIPDwdiodCV; + + } + else + { /* inverse mode */ + here->B3SOIPDmode = -1; + Vds = -vds; + Vgs = vgd; + Vbs = vbd; + Vbd = vbs; + Ves = ved; + Vps = vpd; + + wdios = pParam->B3SOIPDwdiod; + wdiod = pParam->B3SOIPDwdios; + wdiosCV = pParam->B3SOIPDwdiodCV; + wdiodCV = pParam->B3SOIPDwdiosCV; + + } + + Vesfb = Ves - vfbb; + Cbox = model->B3SOIPDcbox; + K1 = pParam->B3SOIPDk1eff; + + ChargeComputationNeeded = + ((ckt->CKTmode & (MODEAC | MODETRAN | MODEINITSMSIG)) || + ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) + ? 1 : 0; + + if (here->B3SOIPDdebugMod < 0) + ChargeComputationNeeded = 1; + + + + +/* Poly Gate Si Depletion Effect */ + T0 = pParam->B3SOIPDvfb + phi; + if ((pParam->B3SOIPDngate > 1.e18) && (pParam->B3SOIPDngate < 1.e25) + && (Vgs > T0)) + /* added to avoid the problem caused by ngate */ + { + T1 = 1.0e6 * Charge_q * EPSSI * pParam->B3SOIPDngate + / (model->B3SOIPDcox * model->B3SOIPDcox); + T4 = sqrt (1.0 + 2.0 * (Vgs - T0) / T1); + T2 = T1 * (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; + } + + + Leff = pParam->B3SOIPDleff; + + if (selfheat) + { + Vtm = KboQ * Temp; + dVtm_dT = KboQ; + } + else + { + Vtm = model->B3SOIPDvtm; + dVtm_dT = 0.0; + } + + V0 = vbi - phi; + + Vbp = Vbs - Vps; + dVbp_dVb = 1; + + + /* T2 is Vbs limited above Vbsc=-5 */ + T0 = Vbs + 5 - 0.001; + T1 = sqrt (T0 * T0 - 0.004 * (-5)); + T2 = (-5) + 0.5 * (T0 + T1); + dT2_dVb = 0.5 * (1.0 + T0 / T1); + + /* Vbsh is T2 limited below 1.5 */ + T0 = 1.5; + T1 = T0 - T2 - 0.002; + T3 = sqrt (T1 * T1 + 0.008 * T0); + Vbsh = T0 - 0.5 * (T1 + T3); + dVbsh_dVb = 0.5 * (1.0 + T1 / T3) * dT2_dVb; + + /* Vbseff is Vbsh limited to 0.95*phi */ + T0 = 0.95 * phi; + T1 = T0 - Vbsh - 0.002; + T2 = sqrt (T1 * T1 + 0.008 * T0); + Vbseff = T0 - 0.5 * (T1 + T2); + dVbseff_dVb = 0.5 * (1.0 + T1 / T2) * dVbsh_dVb; + here->B3SOIPDvbseff = Vbs; + + /* Below all the variables refer to Vbseff */ + if (dVbseff_dVb < 1e-20) + { + dVbseff_dVb = 1e-20; + dVbsh_dVb *= 1e20; + } + else + dVbsh_dVb /= dVbseff_dVb; + + Phis = phi - Vbseff; + dPhis_dVb = -1; + sqrtPhis = sqrt (Phis); + dsqrtPhis_dVb = -0.5 / sqrtPhis; + + Xdep = Xdep0 * sqrtPhis / sqrtPhi; + dXdep_dVb = (Xdep0 / sqrtPhi) * dsqrtPhis_dVb; + +/* Vth Calculation */ + T3 = sqrt (Xdep); + + T0 = pParam->B3SOIPDdvt2 * Vbseff; + if (T0 >= -0.5) + { + T1 = 1.0 + T0; + T2 = pParam->B3SOIPDdvt2; + } + else /* Added to avoid any discontinuity problems caused by dvt2 */ + { + T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = pParam->B3SOIPDdvt2 * T4 * T4; + } + lt1 = model->B3SOIPDfactor1 * T3 * T1; + dlt1_dVb = + model->B3SOIPDfactor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2); + + T0 = pParam->B3SOIPDdvt2w * Vbseff; + if (T0 >= -0.5) + { + T1 = 1.0 + T0; + T2 = pParam->B3SOIPDdvt2w; + } + else /* Added to avoid any discontinuity problems caused by dvt2w */ + { + T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = pParam->B3SOIPDdvt2w * T4 * T4; + } + ltw = model->B3SOIPDfactor1 * T3 * T1; + dltw_dVb = + model->B3SOIPDfactor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2); + + T0 = -0.5 * pParam->B3SOIPDdvt1 * Leff / lt1; + if (T0 > -EXPL_THRESHOLD) + { + T1 = exp (T0); + Theta0 = T1 * (1.0 + 2.0 * T1); + dT1_dVb = -T0 / lt1 * T1 * dlt1_dVb; + dTheta0_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { + T1 = MIN_EXPL; + Theta0 = T1 * (1.0 + 2.0 * T1); + dTheta0_dVb = 0.0; + } + + here->B3SOIPDthetavth = pParam->B3SOIPDdvt0 * Theta0; + Delt_vth = here->B3SOIPDthetavth * V0; + dDelt_vth_dVb = pParam->B3SOIPDdvt0 * dTheta0_dVb * V0; + if (selfheat) + dDelt_vth_dT = here->B3SOIPDthetavth * dvbi_dT; + else + dDelt_vth_dT = 0.0; + + T0 = -0.5 * pParam->B3SOIPDdvt1w * pParam->B3SOIPDweff * Leff / ltw; + if (T0 > -EXPL_THRESHOLD) + { + T1 = exp (T0); + T2 = T1 * (1.0 + 2.0 * T1); + dT1_dVb = -T0 / ltw * T1 * dltw_dVb; + dT2_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { + T1 = MIN_EXPL; + T2 = T1 * (1.0 + 2.0 * T1); + dT2_dVb = 0.0; + } + + T0 = pParam->B3SOIPDdvt0w * T2; + DeltVthw = T0 * V0; + dDeltVthw_dVb = pParam->B3SOIPDdvt0w * dT2_dVb * V0; + if (selfheat) + dDeltVthw_dT = T0 * dvbi_dT; + else + dDeltVthw_dT = 0.0; + + T0 = sqrt (1.0 + pParam->B3SOIPDnlx / Leff); + T1 = (pParam->B3SOIPDkt1 + pParam->B3SOIPDkt1l / Leff + + pParam->B3SOIPDkt2 * Vbseff); + DeltVthtemp = + pParam->B3SOIPDk1eff * (T0 - 1.0) * sqrtPhi + + T1 * TempRatioMinus1; + if (selfheat) + dDeltVthtemp_dT = T1 / model->B3SOIPDtnom; + else + dDeltVthtemp_dT = 0.0; + + tmp2 = model->B3SOIPDtox * phi + / (pParam->B3SOIPDweff + pParam->B3SOIPDw0); + + T3 = pParam->B3SOIPDeta0 + pParam->B3SOIPDetab * Vbseff; + if (T3 < 1.0e-4) /* avoid discontinuity problems caused by etab */ + { + T9 = 1.0 / (3.0 - 2.0e4 * T3); + T3 = (2.0e-4 - T3) * T9; + T4 = T9 * T9 * pParam->B3SOIPDetab; + dT3_dVb = T4; + } + else + { + dT3_dVb = pParam->B3SOIPDetab; + } + DIBL_Sft = T3 * pParam->B3SOIPDtheta0vb0 * Vds; + dDIBL_Sft_dVd = pParam->B3SOIPDtheta0vb0 * T3; + dDIBL_Sft_dVb = pParam->B3SOIPDtheta0vb0 * Vds * dT3_dVb; + + T9 = 2.2361 / sqrtPhi; + sqrtPhisExt = sqrtPhis - T9 * (Vbsh - Vbseff); + dsqrtPhisExt_dVb = dsqrtPhis_dVb - T9 * (dVbsh_dVb - 1); + + Vth = + model->B3SOIPDtype * pParam->B3SOIPDvth0 + + pParam->B3SOIPDk1eff * (sqrtPhisExt - sqrtPhi) - + pParam->B3SOIPDk2 * Vbseff - Delt_vth - DeltVthw + + (pParam->B3SOIPDk3 + pParam->B3SOIPDk3b * Vbseff) * tmp2 + + DeltVthtemp - DIBL_Sft; + here->B3SOIPDvon = Vth; + + T6 = pParam->B3SOIPDk3b * tmp2 - pParam->B3SOIPDk2 + + pParam->B3SOIPDkt2 * TempRatioMinus1; + dVth_dVb = pParam->B3SOIPDk1eff * dsqrtPhisExt_dVb + - dDelt_vth_dVb - dDeltVthw_dVb + T6 - dDIBL_Sft_dVb; + /* this is actually dVth_dVbseff */ + + dVth_dVd = -dDIBL_Sft_dVd; + if (selfheat) + dVth_dT = dDeltVthtemp_dT - dDelt_vth_dT - dDeltVthw_dT; + else + dVth_dT = 0.0; + + /* dVthzb_dT calculation */ + if ((model->B3SOIPDcapMod == 3) && (selfheat == 1)) + { + T3zb = sqrt (Xdep0); + ltwzb = lt1zb = model->B3SOIPDfactor1 * T3zb; + + T0 = -0.5 * pParam->B3SOIPDdvt1 * Leff / lt1zb; + if (T0 > -EXPL_THRESHOLD) + { + T1 = exp (T0); + Theta0zb = T1 * (1.0 + 2.0 * T1); + } + else + { + T1 = MIN_EXPL; + Theta0zb = T1 * (1.0 + 2.0 * T1); + } + Delt_vthzb = pParam->B3SOIPDdvt0 * Theta0zb * V0; + dDelt_vthzb_dT = pParam->B3SOIPDdvt0 * Theta0zb * dvbi_dT; + + T0 = + -0.5 * pParam->B3SOIPDdvt1w * pParam->B3SOIPDweff * Leff / + ltwzb; + if (T0 > -EXPL_THRESHOLD) + { + T1 = exp (T0); + T2 = T1 * (1.0 + 2.0 * T1); + } + else + { + T1 = MIN_EXPL; + T2 = T1 * (1.0 + 2.0 * T1); + } + T0 = pParam->B3SOIPDdvt0w * T2; + DeltVthwzb = T0 * V0; + dDeltVthwzb_dT = T0 * dvbi_dT; + + T0 = sqrt (1.0 + pParam->B3SOIPDnlx / Leff); + T1 = (pParam->B3SOIPDkt1 + pParam->B3SOIPDkt1l / Leff); + DeltVthtempzb = pParam->B3SOIPDk1eff * (T0 - 1.0) * sqrtPhi + + T1 * TempRatioMinus1; + dDeltVthtempzb_dT = T1 / model->B3SOIPDtnom; + + Vthzb = model->B3SOIPDtype * pParam->B3SOIPDvth0 + - Delt_vthzb - DeltVthwzb + pParam->B3SOIPDk3 * tmp2 + + DeltVthtempzb; + dVthzb_dT = dDeltVthtempzb_dT - dDelt_vthzb_dT - dDeltVthwzb_dT; + } + +/* Calculate n */ + T2 = pParam->B3SOIPDnfactor * EPSSI / Xdep; + dT2_dVb = -T2 / Xdep * dXdep_dVb; + + T3 = pParam->B3SOIPDcdsc + pParam->B3SOIPDcdscb * Vbseff + + pParam->B3SOIPDcdscd * Vds; + dT3_dVb = pParam->B3SOIPDcdscb; + dT3_dVd = pParam->B3SOIPDcdscd; + + T4 = (T2 + T3 * Theta0 + pParam->B3SOIPDcit) / model->B3SOIPDcox; + dT4_dVb = (dT2_dVb + Theta0 * dT3_dVb + dTheta0_dVb * T3) + / model->B3SOIPDcox; + dT4_dVd = Theta0 * dT3_dVd / model->B3SOIPDcox; + + if (T4 >= -0.5) + { + n = 1.0 + T4; + dn_dVb = dT4_dVb; + dn_dVd = dT4_dVd; + } + else + /* avoid discontinuity problems caused by T4 */ + { + T0 = 1.0 / (3.0 + 8.0 * T4); + n = (1.0 + 3.0 * T4) * T0; + T0 *= T0; + dn_dVb = T0 * dT4_dVb; + dn_dVd = T0 * dT4_dVd; + } + +/* Effective Vgst (Vgsteff) Calculation */ + + Vgst = Vgs_eff - Vth; + dVgst_dVg = dVgs_eff_dVg; + dVgst_dVd = -dVth_dVd; + dVgst_dVb = -dVth_dVb; + + T10 = 2.0 * n * Vtm; + VgstNVt = Vgst / T10; + ExpArg = (2.0 * pParam->B3SOIPDvoff - Vgst) / T10; + + /* MCJ: Very small Vgst */ + if (VgstNVt > EXPL_THRESHOLD) + { + Vgsteff = Vgst; + /* T0 is dVgsteff_dVbseff */ + T0 = -dVth_dVb; + dVgsteff_dVg = dVgs_eff_dVg; + dVgsteff_dVd = -dVth_dVd; + dVgsteff_dVb = T0 * dVbseff_dVb; + if (selfheat) + dVgsteff_dT = -dVth_dT; + else + dVgsteff_dT = 0.0; + } + else if (ExpArg > EXPL_THRESHOLD) + { + T0 = (Vgst - pParam->B3SOIPDvoff) / (n * Vtm); + ExpVgst = exp (T0); + Vgsteff = + Vtm * pParam->B3SOIPDcdep0 / model->B3SOIPDcox * ExpVgst; + T3 = Vgsteff / (n * Vtm); + /* T1 is dVgsteff_dVbseff */ + T1 = -T3 * (dVth_dVb + T0 * Vtm * dn_dVb); + dVgsteff_dVg = T3 * dVgs_eff_dVg; + dVgsteff_dVd = -T3 * (dVth_dVd + T0 * Vtm * dn_dVd); + dVgsteff_dVb = T1 * dVbseff_dVb; + if (selfheat) + dVgsteff_dT = -T3 * (dVth_dT + T0 * dVtm_dT * n) + + Vgsteff / Temp; + else + dVgsteff_dT = 0.0; + } + else + { + ExpVgst = exp (VgstNVt); + T1 = T10 * log (1.0 + ExpVgst); + dT1_dVg = ExpVgst / (1.0 + ExpVgst); + dT1_dVb = -dT1_dVg * (dVth_dVb + Vgst / n * dn_dVb) + + T1 / n * dn_dVb; + dT1_dVd = -dT1_dVg * (dVth_dVd + Vgst / n * dn_dVd) + + T1 / n * dn_dVd; + T3 = (1.0 / Temp); + if (selfheat) + dT1_dT = -dT1_dVg * (dVth_dT + Vgst * T3) + T1 * T3; + else + dT1_dT = 0.0; + + dT2_dVg = -model->B3SOIPDcox / (Vtm * pParam->B3SOIPDcdep0) + * exp (ExpArg); + T2 = 1.0 - T10 * dT2_dVg; + dT2_dVd = -dT2_dVg * (dVth_dVd - 2.0 * Vtm * ExpArg * dn_dVd) + + (T2 - 1.0) / n * dn_dVd; + dT2_dVb = -dT2_dVg * (dVth_dVb - 2.0 * Vtm * ExpArg * dn_dVb) + + (T2 - 1.0) / n * dn_dVb; + if (selfheat) + dT2_dT = -dT2_dVg * (dVth_dT - ExpArg * T10 * T3); + else + dT2_dT = 0.0; + + Vgsteff = T1 / T2; + T3 = T2 * T2; + /* T4 is dVgsteff_dVbseff */ + T4 = (T2 * dT1_dVb - T1 * dT2_dVb) / T3; + dVgsteff_dVb = T4 * dVbseff_dVb; + dVgsteff_dVg = + (T2 * dT1_dVg - T1 * dT2_dVg) / T3 * dVgs_eff_dVg; + dVgsteff_dVd = (T2 * dT1_dVd - T1 * dT2_dVd) / T3; + if (selfheat) + dVgsteff_dT = (T2 * dT1_dT - T1 * dT2_dT) / T3; + else + dVgsteff_dT = 0.0; + } + Vgst2Vtm = Vgsteff + 2.0 * Vtm; + if (selfheat) + dVgst2Vtm_dT = 2.0 * dVtm_dT; + else + dVgst2Vtm_dT = 0.0; + +/* Calculate Effective Channel Geometry */ + T9 = sqrtPhis - sqrtPhi; + Weff = + pParam->B3SOIPDweff - (2.0 - + here->B3SOIPDnbc) * (pParam->B3SOIPDdwg * + Vgsteff + + pParam->B3SOIPDdwb * + T9); + dWeff_dVg = -(2.0 - here->B3SOIPDnbc) * pParam->B3SOIPDdwg; + dWeff_dVb = + -(2.0 - here->B3SOIPDnbc) * pParam->B3SOIPDdwb * dsqrtPhis_dVb; + + if (Weff < 2.0e-8) /* to avoid the discontinuity problem due to Weff */ + { + T0 = 1.0 / (6.0e-8 - 2.0 * Weff); + Weff = 2.0e-8 * (4.0e-8 - Weff) * T0; + T0 *= T0 * 4.0e-16; + dWeff_dVg *= T0; + dWeff_dVb *= T0; + } + + T0 = pParam->B3SOIPDprwg * Vgsteff + pParam->B3SOIPDprwb * T9; + if (T0 >= -0.9) + { + Rds = rds0 * (1.0 + T0); + dRds_dVg = rds0 * pParam->B3SOIPDprwg; + dRds_dVb = rds0 * pParam->B3SOIPDprwb * dsqrtPhis_dVb; + + if (selfheat && (Rds != 0.0)) + dRds_dT = (1.0 + T0) * drds0_dT; + else + dRds_dT = 0.0; + + } + else + /* to avoid the discontinuity problem due to prwg and prwb */ + { + T1 = 1.0 / (17.0 + 20.0 * T0); + Rds = rds0 * (0.8 + T0) * T1; + T1 *= T1; + dRds_dVg = rds0 * pParam->B3SOIPDprwg * T1; + dRds_dVb = rds0 * pParam->B3SOIPDprwb * dsqrtPhis_dVb * T1; + + if (selfheat && (Rds != 0.0)) + dRds_dT = (0.8 + T0) * T1 * drds0_dT; + else + dRds_dT = 0.0; + + } + +/* Calculate Abulk */ + if (pParam->B3SOIPDa0 == 0.0) + { + + Abulk0 = Abulk = 1.0; + + dAbulk0_dVb = dAbulk_dVg = dAbulk_dVb = 0.0; + } + else + { + T10 = pParam->B3SOIPDketa * Vbsh; + if (T10 >= -0.9) + { + T11 = 1.0 / (1.0 + T10); + dT11_dVb = -pParam->B3SOIPDketa * T11 * T11 * dVbsh_dVb; + } + else + { /* added to avoid the problems caused by Keta */ + T12 = 1.0 / (0.8 + T10); + T11 = (17.0 + 20.0 * T10) * T12; + dT11_dVb = -pParam->B3SOIPDketa * T12 * T12 * dVbsh_dVb; + } + + T10 = pParam->B3SOIPDphi + pParam->B3SOIPDketas; + T13 = (Vbsh * T11) / T10; + dT13_dVb = (Vbsh * dT11_dVb + T11 * dVbsh_dVb) / T10; + + /* limit 1/sqrt(1-T13) to 6, starting at T13=0.96 */ + if (T13 < 0.96) + { + T14 = 1 / sqrt (1 - T13); + T10 = 0.5 * T14 / (1 - T13); + dT14_dVb = T10 * dT13_dVb; + } + else + { + T11 = 1.0 / (1.0 - 1.043406 * T13); + T14 = (6.00167 - 6.26044 * T13) * T11; + T10 = 0.001742 * T11 * T11; + dT14_dVb = T10 * dT13_dVb; + } + + T10 = 0.5 * pParam->B3SOIPDk1eff + / sqrt (pParam->B3SOIPDphi + pParam->B3SOIPDketas); + T1 = T10 * T14; + dT1_dVb = T10 * dT14_dVb; + + T9 = sqrt (model->B3SOIPDxj * Xdep); + tmp1 = Leff + 2.0 * T9; + T5 = Leff / tmp1; + tmp2 = pParam->B3SOIPDa0 * T5; + tmp3 = pParam->B3SOIPDweff + pParam->B3SOIPDb1; + tmp4 = pParam->B3SOIPDb0 / tmp3; + T2 = tmp2 + tmp4; + dT2_dVb = -T9 * tmp2 / tmp1 / Xdep * dXdep_dVb; + T6 = T5 * T5; + T7 = T5 * T6; + + Abulk0 = 1 + T1 * T2; + dAbulk0_dVb = T1 * dT2_dVb + T2 * dT1_dVb; + + T8 = pParam->B3SOIPDags * pParam->B3SOIPDa0 * T7; + dAbulk_dVg = -T1 * T8; + Abulk = Abulk0 + dAbulk_dVg * Vgsteff; + + dAbulk_dVb = dAbulk0_dVb + - T8 * Vgsteff * (dT1_dVb + 3.0 * T1 * dT2_dVb / tmp2); + } + + if (Abulk0 < 0.01) + { + T9 = 1.0 / (3.0 - 200.0 * Abulk0); + Abulk0 = (0.02 - Abulk0) * T9; + dAbulk0_dVb *= T9 * T9; + } + + if (Abulk < 0.01) + { + T9 = 1.0 / (3.0 - 200.0 * Abulk); + Abulk = (0.02 - Abulk) * T9; + dAbulk_dVb *= T9 * T9; + } + +/* Mobility calculation */ + if (model->B3SOIPDmobMod == 1) + { + T0 = Vgsteff + Vth + Vth; + T2 = ua + uc * Vbseff; + T3 = T0 / model->B3SOIPDtox; + T5 = T3 * (T2 + ub * T3); + dDenomi_dVg = (T2 + 2.0 * ub * T3) / model->B3SOIPDtox; + dDenomi_dVd = dDenomi_dVg * 2 * dVth_dVd; + dDenomi_dVb = dDenomi_dVg * 2 * dVth_dVb + uc * T3; + if (selfheat) + dDenomi_dT = dDenomi_dVg * 2 * dVth_dT + + (dua_dT + Vbseff * duc_dT + dub_dT * T3) * T3; + else + dDenomi_dT = 0.0; + } + else if (model->B3SOIPDmobMod == 2) + { + T5 = Vgsteff / model->B3SOIPDtox * (ua + + uc * Vbseff + ub * Vgsteff + / model->B3SOIPDtox); + dDenomi_dVg = (ua + uc * Vbseff + + 2.0 * ub * Vgsteff / model->B3SOIPDtox) + / model->B3SOIPDtox; + dDenomi_dVd = 0.0; + dDenomi_dVb = Vgsteff * uc / model->B3SOIPDtox; + if (selfheat) + dDenomi_dT = Vgsteff / model->B3SOIPDtox + * (dua_dT + Vbseff * duc_dT + dub_dT + * Vgsteff / model->B3SOIPDtox); + else + dDenomi_dT = 0.0; + } + else /* mobMod == 3 */ + { + T0 = Vgsteff + Vth + Vth; + T2 = 1.0 + uc * Vbseff; + T3 = T0 / model->B3SOIPDtox; + T4 = T3 * (ua + ub * T3); + T5 = T4 * T2; + dDenomi_dVg = (ua + 2.0 * ub * T3) * T2 / model->B3SOIPDtox; + dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd; + dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + uc * T4; + if (selfheat) + dDenomi_dT = dDenomi_dVg * 2.0 * dVth_dT + + (dua_dT + dub_dT * T3) * T3 * T2 + T4 * Vbseff * duc_dT; + else + dDenomi_dT = 0.0; + } + + if (T5 >= -0.8) + { + Denomi = 1.0 + T5; + } + else /* Added to avoid the discontinuity problem caused by ua and ub */ + { + T9 = 1.0 / (7.0 + 10.0 * T5); + Denomi = (0.6 + T5) * T9; + T9 *= T9; + dDenomi_dVg *= T9; + dDenomi_dVd *= T9; + dDenomi_dVb *= T9; + if (selfheat) + dDenomi_dT *= T9; + else + dDenomi_dT = 0.0; + } + + here->B3SOIPDueff = ueff = u0temp / Denomi; + T9 = -ueff / Denomi; + dueff_dVg = T9 * dDenomi_dVg; + dueff_dVd = T9 * dDenomi_dVd; + dueff_dVb = T9 * dDenomi_dVb; + if (selfheat) + dueff_dT = T9 * dDenomi_dT + du0temp_dT / Denomi; + else + dueff_dT = 0.0; + +/* Saturation Drain Voltage Vdsat */ + WVCox = Weff * vsattemp * model->B3SOIPDcox; + WVCoxRds = WVCox * Rds; + +/* dWVCoxRds_dT = WVCox * dRds_dT + + Weff * model->B3SOIPDcox * Rds * dvsattemp_dT; */ + + Esat = 2.0 * vsattemp / ueff; + EsatL = Esat * Leff; + T0 = -EsatL / ueff; + dEsatL_dVg = T0 * dueff_dVg; + dEsatL_dVd = T0 * dueff_dVd; + dEsatL_dVb = T0 * dueff_dVb; + if (selfheat) + dEsatL_dT = T0 * dueff_dT + EsatL / vsattemp * dvsattemp_dT; + else + dEsatL_dT = 0.0; + + /* Sqrt() */ + a1 = pParam->B3SOIPDa1; + if (a1 == 0.0) + { + Lambda = pParam->B3SOIPDa2; + dLambda_dVg = 0.0; + } + else if (a1 > 0.0) +/* Added to avoid the discontinuity problem caused by a1 and a2 (Lambda) */ + { + T0 = 1.0 - pParam->B3SOIPDa2; + T1 = T0 - pParam->B3SOIPDa1 * Vgsteff - 0.0001; + T2 = sqrt (T1 * T1 + 0.0004 * T0); + Lambda = pParam->B3SOIPDa2 + T0 - 0.5 * (T1 + T2); + dLambda_dVg = 0.5 * pParam->B3SOIPDa1 * (1.0 + T1 / T2); + } + else + { + T1 = pParam->B3SOIPDa2 + pParam->B3SOIPDa1 * Vgsteff - 0.0001; + T2 = sqrt (T1 * T1 + 0.0004 * pParam->B3SOIPDa2); + Lambda = 0.5 * (T1 + T2); + dLambda_dVg = 0.5 * pParam->B3SOIPDa1 * (1.0 + T1 / T2); + } + + if (Rds > 0) + { + tmp2 = dRds_dVg / Rds + dWeff_dVg / Weff; + tmp3 = dRds_dVb / Rds + dWeff_dVb / Weff; + } + else + { + tmp2 = dWeff_dVg / Weff; + tmp3 = dWeff_dVb / Weff; + } + if ((Rds == 0.0) && (Lambda == 1.0)) + { + T0 = 1.0 / (Abulk * EsatL + Vgst2Vtm); + tmp1 = 0.0; + T1 = T0 * T0; + T2 = Vgst2Vtm * T0; + T3 = EsatL * Vgst2Vtm; + Vdsat = T3 * T0; + + dT0_dVg = -(Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 1.0) * T1; + dT0_dVd = -(Abulk * dEsatL_dVd) * T1; + dT0_dVb = -(Abulk * dEsatL_dVb + EsatL * dAbulk_dVb) * T1; + if (selfheat) + dT0_dT = -(Abulk * dEsatL_dT + dVgst2Vtm_dT) * T1; + else + dT0_dT = 0.0; + + dVdsat_dVg = T3 * dT0_dVg + T2 * dEsatL_dVg + EsatL * T0; + dVdsat_dVd = T3 * dT0_dVd + T2 * dEsatL_dVd; + dVdsat_dVb = T3 * dT0_dVb + T2 * dEsatL_dVb; + if (selfheat) + dVdsat_dT = T3 * dT0_dT + T2 * dEsatL_dT + + EsatL * T0 * dVgst2Vtm_dT; + else + dVdsat_dT = 0.0; + } + else + { + tmp1 = dLambda_dVg / (Lambda * Lambda); + T9 = Abulk * WVCoxRds; + T8 = Abulk * T9; + T7 = Vgst2Vtm * T9; + T6 = Vgst2Vtm * WVCoxRds; + T0 = 2.0 * Abulk * (T9 - 1.0 + 1.0 / Lambda); + dT0_dVg = 2.0 * (T8 * tmp2 - Abulk * tmp1 + + (2.0 * T9 + 1.0 / Lambda - + 1.0) * dAbulk_dVg); +/* dT0_dVb = 2.0 * (T8 * tmp3 this is equivalent to one below, but simpler + + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbulk_dVg); */ + dT0_dVb = 2.0 * (T8 * (2.0 / Abulk * dAbulk_dVb + tmp3) + + (1.0 / Lambda - 1.0) * dAbulk_dVb); + dT0_dVd = 0.0; + + if (selfheat) + { + + if (Rds != 0.0) + tmp4 = dRds_dT / Rds + dvsattemp_dT / vsattemp; + else + tmp4 = dvsattemp_dT / vsattemp; + + dT0_dT = 2.0 * T8 * tmp4; + } + else + tmp4 = dT0_dT = 0.0; + + T1 = Vgst2Vtm * (2.0 / Lambda - 1.0) + Abulk * EsatL + 3.0 * T7; + + dT1_dVg = (2.0 / Lambda - 1.0) - 2.0 * Vgst2Vtm * tmp1 + + Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 3.0 * (T9 + + + T7 * tmp2 + + T6 * + dAbulk_dVg); + dT1_dVb = + Abulk * dEsatL_dVb + EsatL * dAbulk_dVb + + 3.0 * (T6 * dAbulk_dVb + T7 * tmp3); + dT1_dVd = Abulk * dEsatL_dVd; + + + if (selfheat) + { + tmp4 += dVgst2Vtm_dT / Vgst2Vtm; + dT1_dT = (2.0 / Lambda - 1.0) * dVgst2Vtm_dT + + Abulk * dEsatL_dT + 3.0 * T7 * tmp4; + } + else + dT1_dT = 0.0; + + T2 = Vgst2Vtm * (EsatL + 2.0 * T6); + dT2_dVg = EsatL + Vgst2Vtm * dEsatL_dVg + + T6 * (4.0 + 2.0 * Vgst2Vtm * tmp2); + dT2_dVb = Vgst2Vtm * (dEsatL_dVb + 2.0 * T6 * tmp3); + dT2_dVd = Vgst2Vtm * dEsatL_dVd; + if (selfheat) + dT2_dT = Vgst2Vtm * dEsatL_dT + EsatL * dVgst2Vtm_dT + + 2.0 * T6 * (dVgst2Vtm_dT + Vgst2Vtm * tmp4); + else + dT2_dT = 0.0; + + T3 = sqrt (T1 * T1 - 2.0 * T0 * T2); + Vdsat = (T1 - T3) / T0; + + dVdsat_dVg = (dT1_dVg - (T1 * dT1_dVg - dT0_dVg * T2 + - T0 * dT2_dVg) / T3 - + Vdsat * dT0_dVg) / T0; + dVdsat_dVb = + (dT1_dVb - (T1 * dT1_dVb - dT0_dVb * T2 - T0 * dT2_dVb) / T3 - + Vdsat * dT0_dVb) / T0; + dVdsat_dVd = + (dT1_dVd - (T1 * dT1_dVd - T0 * dT2_dVd) / T3) / T0; + if (selfheat) + dVdsat_dT = (dT1_dT - (T1 * dT1_dT - dT0_dT * T2 + - T0 * dT2_dT) / T3 - + Vdsat * dT0_dT) / T0; + else + dVdsat_dT = 0.0; + } + here->B3SOIPDvdsat = Vdsat; + + +/* Effective Vds (Vdseff) Calculation */ + T1 = Vdsat - Vds - pParam->B3SOIPDdelta; + dT1_dVg = dVdsat_dVg; + dT1_dVd = dVdsat_dVd - 1.0; + dT1_dVb = dVdsat_dVb; + dT1_dT = dVdsat_dT; + + T2 = sqrt (T1 * T1 + 4.0 * pParam->B3SOIPDdelta * Vdsat); + T0 = T1 / T2; + T3 = 2.0 * pParam->B3SOIPDdelta / T2; + dT2_dVg = T0 * dT1_dVg + T3 * dVdsat_dVg; + dT2_dVd = T0 * dT1_dVd + T3 * dVdsat_dVd; + dT2_dVb = T0 * dT1_dVb + T3 * dVdsat_dVb; + if (selfheat) + dT2_dT = T0 * dT1_dT + T3 * dVdsat_dT; + else + dT2_dT = 0.0; + + Vdseff = Vdsat - 0.5 * (T1 + T2); + dVdseff_dVg = dVdsat_dVg - 0.5 * (dT1_dVg + dT2_dVg); + dVdseff_dVd = dVdsat_dVd - 0.5 * (dT1_dVd + dT2_dVd); + dVdseff_dVb = dVdsat_dVb - 0.5 * (dT1_dVb + dT2_dVb); + if (selfheat) + dVdseff_dT = dVdsat_dT - 0.5 * (dT1_dT + dT2_dT); + else + dVdseff_dT = 0.0; + + if (Vdseff > Vds) + Vdseff = Vds; /* This code is added to fixed the problem + caused by computer precision when + Vds is very close to Vdseff. */ + diffVds = Vds - Vdseff; + + +/* Calculate VAsat */ + tmp4 = 1.0 - 0.5 * Abulk * Vdsat / Vgst2Vtm; + T9 = WVCoxRds * Vgsteff; + T8 = T9 / Vgst2Vtm; + T0 = EsatL + Vdsat + 2.0 * T9 * tmp4; + + T7 = 2.0 * WVCoxRds * tmp4; + dT0_dVg = dEsatL_dVg + dVdsat_dVg + T7 * (1.0 + tmp2 * Vgsteff) + - T8 * (Abulk * dVdsat_dVg - Abulk * Vdsat / Vgst2Vtm + + Vdsat * dAbulk_dVg); + + dT0_dVb = dEsatL_dVb + dVdsat_dVb + T7 * tmp3 * Vgsteff + - T8 * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb); + dT0_dVd = dEsatL_dVd + dVdsat_dVd - T8 * Abulk * dVdsat_dVd; + + if (selfheat) + { + + if (Rds != 0.0) + tmp4 = dRds_dT / Rds + dvsattemp_dT / vsattemp; + else + tmp4 = dvsattemp_dT / vsattemp; + + dT0_dT = dEsatL_dT + dVdsat_dT + T7 * tmp4 * Vgsteff + - T8 * (Abulk * dVdsat_dT - Abulk * Vdsat * dVgst2Vtm_dT + / Vgst2Vtm); + } + else + dT0_dT = 0.0; + + T9 = WVCoxRds * Abulk; + T1 = 2.0 / Lambda - 1.0 + T9; + dT1_dVg = -2.0 * tmp1 + WVCoxRds * (Abulk * tmp2 + dAbulk_dVg); + dT1_dVb = dAbulk_dVb * WVCoxRds + T9 * tmp3; + if (selfheat) + dT1_dT = T9 * tmp4; + else + dT1_dT = 0.0; + + Vasat = T0 / T1; + dVasat_dVg = (dT0_dVg - Vasat * dT1_dVg) / T1; + dVasat_dVb = (dT0_dVb - Vasat * dT1_dVb) / T1; + dVasat_dVd = dT0_dVd / T1; + if (selfheat) + dVasat_dT = (dT0_dT - Vasat * dT1_dT) / T1; + else + dVasat_dT = 0.0; + +/* Calculate VACLM */ + if ((pParam->B3SOIPDpclm > 0.0) && (diffVds > 1.0e-10)) + { + T0 = 1.0 / (pParam->B3SOIPDpclm * Abulk * pParam->B3SOIPDlitl); + dT0_dVb = -T0 / Abulk * dAbulk_dVb; + dT0_dVg = -T0 / Abulk * dAbulk_dVg; + + T2 = Vgsteff / EsatL; + T1 = Leff * (Abulk + T2); + dT1_dVg = Leff * ((1.0 - T2 * dEsatL_dVg) / EsatL + dAbulk_dVg); + dT1_dVb = Leff * (dAbulk_dVb - T2 * dEsatL_dVb / EsatL); + dT1_dVd = -T2 * dEsatL_dVd / Esat; + if (selfheat) + dT1_dT = -T2 * dEsatL_dT / Esat; + else + dT1_dT = 0.0; + + T9 = T0 * T1; + VACLM = T9 * diffVds; + dVACLM_dVg = T0 * dT1_dVg * diffVds - T9 * dVdseff_dVg + + T1 * diffVds * dT0_dVg; + dVACLM_dVb = (dT0_dVb * T1 + T0 * dT1_dVb) * diffVds + - T9 * dVdseff_dVb; + dVACLM_dVd = T0 * dT1_dVd * diffVds + T9 * (1.0 - dVdseff_dVd); + if (selfheat) + dVACLM_dT = T0 * dT1_dT * diffVds - T9 * dVdseff_dT; + else + dVACLM_dT = 0.0; + + } + else + { + VACLM = MAX_EXPL; + dVACLM_dVd = dVACLM_dVg = dVACLM_dVb = dVACLM_dT = 0.0; + } + + +/* Calculate VADIBL */ + if (pParam->B3SOIPDthetaRout > 0.0) + { + T8 = Abulk * Vdsat; + T0 = Vgst2Vtm * T8; + T1 = Vgst2Vtm + T8; + dT0_dVg = Vgst2Vtm * Abulk * dVdsat_dVg + T8 + + Vgst2Vtm * Vdsat * dAbulk_dVg; + dT1_dVg = 1.0 + Abulk * dVdsat_dVg + Vdsat * dAbulk_dVg; + dT1_dVb = dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb; + dT0_dVb = Vgst2Vtm * dT1_dVb; + dT1_dVd = Abulk * dVdsat_dVd; + dT0_dVd = Vgst2Vtm * dT1_dVd; + if (selfheat) + { + dT0_dT = dVgst2Vtm_dT * T8 + Abulk * Vgst2Vtm * dVdsat_dT; + dT1_dT = dVgst2Vtm_dT + Abulk * dVdsat_dT; + } + else + dT0_dT = dT1_dT = 0.0; + + T9 = T1 * T1; + T2 = pParam->B3SOIPDthetaRout; + VADIBL = (Vgst2Vtm - T0 / T1) / T2; + dVADIBL_dVg = (1.0 - dT0_dVg / T1 + T0 * dT1_dVg / T9) / T2; + dVADIBL_dVb = (-dT0_dVb / T1 + T0 * dT1_dVb / T9) / T2; + dVADIBL_dVd = (-dT0_dVd / T1 + T0 * dT1_dVd / T9) / T2; + if (selfheat) + dVADIBL_dT = + (dVgst2Vtm_dT - dT0_dT / T1 + T0 * dT1_dT / T9) / T2; + else + dVADIBL_dT = 0.0; + + T7 = pParam->B3SOIPDpdiblb * Vbseff; + if (T7 >= -0.9) + { + T3 = 1.0 / (1.0 + T7); + VADIBL *= T3; + dVADIBL_dVg *= T3; + dVADIBL_dVb = (dVADIBL_dVb - VADIBL * pParam->B3SOIPDpdiblb) + * T3; + dVADIBL_dVd *= T3; + if (selfheat) + dVADIBL_dT *= T3; + else + dVADIBL_dT = 0.0; + } + else +/* Added to avoid the discontinuity problem caused by pdiblcb */ + { + T4 = 1.0 / (0.8 + T7); + T3 = (17.0 + 20.0 * T7) * T4; + dVADIBL_dVg *= T3; + dVADIBL_dVb = dVADIBL_dVb * T3 + - VADIBL * pParam->B3SOIPDpdiblb * T4 * T4; + dVADIBL_dVd *= T3; + if (selfheat) + dVADIBL_dT *= T3; + else + dVADIBL_dT = 0.0; + VADIBL *= T3; + } + } + else + { + VADIBL = MAX_EXPL; + dVADIBL_dVd = dVADIBL_dVg = dVADIBL_dVb = dVADIBL_dT = 0.0; + } + +/* Calculate VA */ + + T8 = pParam->B3SOIPDpvag / EsatL; + T9 = T8 * Vgsteff; + if (T9 > -0.9) + { + T0 = 1.0 + T9; + dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL); + dT0_dVb = -T9 * dEsatL_dVb / EsatL; + dT0_dVd = -T9 * dEsatL_dVd / EsatL; + if (selfheat) + dT0_dT = -T9 * dEsatL_dT / EsatL; + else + dT0_dT = 0.0; + } + else /* Added to avoid the discontinuity problems caused by pvag */ + { + T1 = 1.0 / (17.0 + 20.0 * T9); + T0 = (0.8 + T9) * T1; + T1 *= T1; + dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL) * T1; + + T9 *= T1 / EsatL; + dT0_dVb = -T9 * dEsatL_dVb; + dT0_dVd = -T9 * dEsatL_dVd; + if (selfheat) + dT0_dT = -T9 * dEsatL_dT; + else + dT0_dT = 0.0; + } + + tmp1 = VACLM * VACLM; + tmp2 = VADIBL * VADIBL; + tmp3 = VACLM + VADIBL; + + T1 = VACLM * VADIBL / tmp3; + tmp3 *= tmp3; + dT1_dVg = (tmp1 * dVADIBL_dVg + tmp2 * dVACLM_dVg) / tmp3; + dT1_dVd = (tmp1 * dVADIBL_dVd + tmp2 * dVACLM_dVd) / tmp3; + dT1_dVb = (tmp1 * dVADIBL_dVb + tmp2 * dVACLM_dVb) / tmp3; + if (selfheat) + dT1_dT = (tmp1 * dVADIBL_dT + tmp2 * dVACLM_dT) / tmp3; + else + dT1_dT = 0.0; + + Va = Vasat + T0 * T1; + dVa_dVg = dVasat_dVg + T1 * dT0_dVg + T0 * dT1_dVg; + dVa_dVd = dVasat_dVd + T1 * dT0_dVd + T0 * dT1_dVd; + dVa_dVb = dVasat_dVb + T1 * dT0_dVb + T0 * dT1_dVb; + if (selfheat) + dVa_dT = dVasat_dT + T1 * dT0_dT + T0 * dT1_dT; + else + dVa_dT = 0.0; + +/* Calculate Ids */ + CoxWovL = model->B3SOIPDcox * Weff / Leff; + beta = ueff * CoxWovL; + dbeta_dVg = CoxWovL * dueff_dVg + beta * dWeff_dVg / Weff; + dbeta_dVd = CoxWovL * dueff_dVd; + dbeta_dVb = CoxWovL * dueff_dVb + beta * dWeff_dVb / Weff; + if (selfheat) + dbeta_dT = CoxWovL * dueff_dT; + else + dbeta_dT = 0.0; + + T0 = 1.0 - 0.5 * Abulk * Vdseff / Vgst2Vtm; + dT0_dVg = -0.5 * (Abulk * dVdseff_dVg + - Abulk * Vdseff / Vgst2Vtm + + Vdseff * dAbulk_dVg) / Vgst2Vtm; + dT0_dVd = -0.5 * Abulk * dVdseff_dVd / Vgst2Vtm; + dT0_dVb = -0.5 * (Abulk * dVdseff_dVb + dAbulk_dVb * Vdseff) + / Vgst2Vtm; + if (selfheat) + dT0_dT = -0.5 * (Abulk * dVdseff_dT + - Abulk * Vdseff / Vgst2Vtm * dVgst2Vtm_dT) + / Vgst2Vtm; + else + dT0_dT = 0.0; + + fgche1 = Vgsteff * T0; + dfgche1_dVg = Vgsteff * dT0_dVg + T0; + dfgche1_dVd = Vgsteff * dT0_dVd; + dfgche1_dVb = Vgsteff * dT0_dVb; + if (selfheat) + dfgche1_dT = Vgsteff * dT0_dT; + else + dfgche1_dT = 0.0; + + T9 = Vdseff / EsatL; + fgche2 = 1.0 + T9; + dfgche2_dVg = (dVdseff_dVg - T9 * dEsatL_dVg) / EsatL; + dfgche2_dVd = (dVdseff_dVd - T9 * dEsatL_dVd) / EsatL; + dfgche2_dVb = (dVdseff_dVb - T9 * dEsatL_dVb) / EsatL; + if (selfheat) + dfgche2_dT = (dVdseff_dT - T9 * dEsatL_dT) / EsatL; + else + dfgche2_dT = 0.0; + + gche = beta * fgche1 / fgche2; + dgche_dVg = (beta * dfgche1_dVg + fgche1 * dbeta_dVg + - gche * dfgche2_dVg) / fgche2; + dgche_dVd = (beta * dfgche1_dVd + fgche1 * dbeta_dVd + - gche * dfgche2_dVd) / fgche2; + dgche_dVb = (beta * dfgche1_dVb + fgche1 * dbeta_dVb + - gche * dfgche2_dVb) / fgche2; + if (selfheat) + dgche_dT = (beta * dfgche1_dT + fgche1 * dbeta_dT + - gche * dfgche2_dT) / fgche2; + else + dgche_dT = 0.0; + + T0 = 1.0 + gche * Rds; + T9 = Vdseff / T0; + Idl = gche * T9; + +/* Whoa, these formulas for the derivatives of Idl are convoluted, but I + verified them to be correct */ + + dIdl_dVg = (gche * dVdseff_dVg + T9 * dgche_dVg) / T0 + - Idl * gche / T0 * dRds_dVg; + dIdl_dVd = (gche * dVdseff_dVd + T9 * dgche_dVd) / T0; + dIdl_dVb = (gche * dVdseff_dVb + T9 * dgche_dVb + - Idl * dRds_dVb * gche) / T0; + if (selfheat) + dIdl_dT = (gche * dVdseff_dT + T9 * dgche_dT + - Idl * dRds_dT * gche) / T0; + else + dIdl_dT = 0.0; + + T9 = diffVds / Va; + T0 = 1.0 + T9; + here->B3SOIPDids = Ids = Idl * T0 / here->B3SOIPDnseg; + + Gm0 = T0 * dIdl_dVg - Idl * (dVdseff_dVg + T9 * dVa_dVg) / Va; + Gds0 = T0 * dIdl_dVd + Idl * (1.0 - dVdseff_dVd + - T9 * dVa_dVd) / Va; + Gmb0 = T0 * dIdl_dVb - Idl * (dVdseff_dVb + T9 * dVa_dVb) / Va; + Gmc = 0.0; + if (selfheat) + GmT0 = T0 * dIdl_dT - Idl * (dVdseff_dT + T9 * dVa_dT) / Va; + else + GmT0 = 0.0; + +/* This includes all dependencies from Vgsteff, Vbseff */ + + Gm = Gm0 * dVgsteff_dVg / here->B3SOIPDnseg; + Gmb = (Gm0 * dVgsteff_dVb + Gmb0 * dVbseff_dVb) / here->B3SOIPDnseg; + Gds = (Gm0 * dVgsteff_dVd + Gds0) / here->B3SOIPDnseg; + if (selfheat) + GmT = (Gm0 * dVgsteff_dT + GmT0) / here->B3SOIPDnseg; + else + GmT = 0.0; + +/* calculate GIDL current */ + T0 = 3 * model->B3SOIPDtox; + /* For drain side */ + T1 = (Vds - Vgs_eff - pParam->B3SOIPDngidl) / T0; + if ((pParam->B3SOIPDagidl <= 0.0) || (pParam->B3SOIPDbgidl <= 0.0) + || (T1 <= 0.0)) + { + Idgidl = Gdgidld = Gdgidlg = 0.0; + } + else + { + dT1_dVd = 1 / T0; + dT1_dVg = -dT1_dVd * dVgs_eff_dVg; + T2 = pParam->B3SOIPDbgidl / T1; + if (T2 < EXPL_THRESHOLD) + { + Idgidl = wdiod * pParam->B3SOIPDagidl * T1 * exp (-T2); + T3 = Idgidl / T1 * (T2 + 1); + Gdgidld = T3 * dT1_dVd; + Gdgidlg = T3 * dT1_dVg; + } + else + { + T3 = wdiod * pParam->B3SOIPDagidl * MIN_EXPL; + Idgidl = T3 * T1; + Gdgidld = T3 * dT1_dVd; + Gdgidlg = T3 * dT1_dVg; + } + } + here->B3SOIPDigidl = Idgidl; + + /* For source side */ + T1 = (-Vgs_eff - pParam->B3SOIPDngidl) / T0; + if ((pParam->B3SOIPDagidl <= 0.0) || (pParam->B3SOIPDbgidl <= 0.0) + || (T1 <= 0.0)) + { + Isgidl = Gsgidlg = 0; + } + else + { + dT1_dVg = -dVgs_eff_dVg / T0; + T2 = pParam->B3SOIPDbgidl / T1; + if (T2 < EXPL_THRESHOLD) + { + Isgidl = wdios * pParam->B3SOIPDagidl * T1 * exp (-T2); + T3 = Isgidl / T1 * (T2 + 1); + Gsgidlg = T3 * dT1_dVg; + } + else + { + T3 = wdios * pParam->B3SOIPDagidl * MIN_EXPL; + Isgidl = T3 * T1; + Gsgidlg = T3 * dT1_dVg; + } + } + +/* calculate diode and BJT current */ + WsTsi = wdios * model->B3SOIPDtsi; + WdTsi = wdiod * model->B3SOIPDtsi; + + NVtm1 = Vtm * pParam->B3SOIPDndiode; + if (selfheat) + dNVtm1_dT = pParam->B3SOIPDndiode * dVtm_dT; + else + dNVtm1_dT = 0; + + T0 = Vbs / NVtm1; + dT0_dVb = 1.0 / NVtm1; + if (selfheat) + dT0_dT = -Vbs / NVtm1 / NVtm1 * dNVtm1_dT; + else + dT0_dT = 0; + DEXP (T0, ExpVbsNVtm, T1); + dExpVbsNVtm_dVb = T1 * dT0_dVb; + if (selfheat) + dExpVbsNVtm_dT = T1 * dT0_dT; + else + dExpVbsNVtm_dT = 0; + + T0 = Vbd / NVtm1; + dT0_dVb = 1.0 / NVtm1; + dT0_dVd = -dT0_dVb; + if (selfheat) + dT0_dT = -Vbd / NVtm1 / NVtm1 * dNVtm1_dT; + else + dT0_dT = 0; + DEXP (T0, ExpVbdNVtm, T1); + dExpVbdNVtm_dVb = T1 * dT0_dVb; + dExpVbdNVtm_dVd = -dExpVbdNVtm_dVb; + if (selfheat) + dExpVbdNVtm_dT = T1 * dT0_dT; + else + dExpVbdNVtm_dT = 0; + + /* Ibs1 / Ibd1 : diffusion current */ + if (jdif == 0) + { + Ibs1 = dIbs1_dVb = dIbs1_dT = Ibd1 = dIbd1_dVb = dIbd1_dVd = + dIbd1_dT = 0; + } + else + { + T0 = WsTsi * jdif; + if (selfheat) + dT0_dT = WsTsi * djdif_dT; + else + dT0_dT = 0; + Ibs1 = T0 * (ExpVbsNVtm - 1); + dIbs1_dVb = T0 * dExpVbsNVtm_dVb; + if (selfheat) + dIbs1_dT = T0 * dExpVbsNVtm_dT + (ExpVbsNVtm - 1) * dT0_dT; + else + dIbs1_dT = 0; + + T0 = WdTsi * jdif; + if (selfheat) + dT0_dT = WdTsi * djdif_dT; + else + dT0_dT = 0; + Ibd1 = T0 * (ExpVbdNVtm - 1); + dIbd1_dVb = T0 * dExpVbdNVtm_dVb; + dIbd1_dVd = -dIbd1_dVb; + if (selfheat) + dIbd1_dT = T0 * dExpVbdNVtm_dT + (ExpVbdNVtm - 1) * dT0_dT; + else + dIbd1_dT = 0; + } + + /* Ibs2:recombination/trap-assisted tunneling current */ + NVtmf = 0.026 * pParam->B3SOIPDnrecf0 + * (1 + model->B3SOIPDntrecf * (TempRatio - 1)); + NVtmr = 0.026 * model->B3SOIPDnrecr0 + * (1 + model->B3SOIPDntrecr * (TempRatio - 1)); + if (selfheat) + { + dNVtmf_dT = pParam->B3SOIPDnrecf0 * 0.026 + * model->B3SOIPDntrecf * dTempRatio_dT; + dNVtmr_dT = model->B3SOIPDnrecr0 * 0.026 + * model->B3SOIPDntrecr * dTempRatio_dT; + } + else + dNVtmf_dT = dNVtmr_dT = 0; + + if (jrec == 0) + { + Ibs2 = dIbs2_dVb = dIbs2_dT = 0; + Ibd2 = dIbd2_dVb = dIbd2_dVd = dIbd2_dT = 0; + } + else + { + /* forward bias */ + T0 = Vbs / NVtmf; + DEXP (T0, T10, T2); + T4 = 1 / NVtmf; + dT10_dVb = T4 * T2; + if (selfheat) + dT10_dT = -T4 * T2 * Vbs / NVtmf * dNVtmf_dT; + else + dT10_dT = 0.0; + + /* reverse bias */ + if ((pParam->B3SOIPDvrec0 - Vbs) < 1e-3) + { + T11 = -1.0; + dT11_dVb = dT11_dT = 0; + } + else + { + T1 = 1 / (pParam->B3SOIPDvrec0 - Vbs); + T0 = -Vbs / NVtmr * pParam->B3SOIPDvrec0 * T1; + dT0_dVb = + -pParam->B3SOIPDvrec0 / NVtmr * (T1 + Vbs * T1 * T1); + if (selfheat) + dT0_dT = -T0 / NVtmr * dNVtmr_dT; + else + dT0_dT = 0; + + DEXP (T0, T11, T2); + T11 = -T11; + dT11_dVb = -T2 * dT0_dVb; + if (selfheat) + dT11_dT = -T2 * dT0_dT; + else + dT11_dT = 0; + } + T3 = WsTsi * jrec; + Ibs2 = T3 * (T10 + T11); + dIbs2_dVb = T3 * (dT10_dVb + dT11_dVb); + if (selfheat) + dIbs2_dT = + T3 * (dT10_dT + dT11_dT) + WsTsi * (T10 + T11) * djrec_dT; + else + dIbs2_dT = 0; + + /* Ibd2 */ + T0 = Vbd / NVtmf; + DEXP (T0, T10, T2); + T4 = 1 / NVtmf; + dT10_dVb = T4 * T2; + if (selfheat) + dT10_dT = -T4 * T2 * Vbd / NVtmf * dNVtmf_dT; + else + dT10_dT = 0.0; + + if ((pParam->B3SOIPDvrec0 - Vbd) < 1e-3) + { + T11 = -1.0; + dT11_dVb = dT11_dT = 0; + } + else + { + T1 = 1 / (pParam->B3SOIPDvrec0 - Vbd); + T0 = -Vbd / NVtmr * pParam->B3SOIPDvrec0 * T1; + dT0_dVb = + -pParam->B3SOIPDvrec0 / NVtmr * (T1 + Vbd * T1 * T1); + if (selfheat) + dT0_dT = -T0 / NVtmr * dNVtmr_dT; + else + dT0_dT = 0; + DEXP (T0, T11, T2); + T11 = -T11; + dT11_dVb = -T2 * dT0_dVb; + if (selfheat) + dT11_dT = -T2 * dT0_dT; + else + dT11_dT = 0; + } + T3 = WdTsi * jrec; + Ibd2 = T3 * (T10 + T11); + dIbd2_dVb = T3 * (dT10_dVb + dT11_dVb); + dIbd2_dVd = -dIbd2_dVb; + if (selfheat) + dIbd2_dT = + T3 * (dT10_dT + dT11_dT) + WdTsi * (T10 + T11) * djrec_dT; + else + dIbd2_dT = 0; + } + + /* Ibs3/Ibd3: recombination current in neutral body */ + WTsi = pParam->B3SOIPDweff / here->B3SOIPDnseg * model->B3SOIPDtsi; + if (jbjt == 0.0) + { + Ibs3 = dIbs3_dVb = dIbs3_dVd = dIbs3_dT = 0.0; + Ibd3 = dIbd3_dVb = dIbd3_dVd = dIbd3_dT = 0.0; + Ibsdif = dIbsdif_dVb = dIbsdif_dT = 0; + Ibddif = dIbddif_dVb = dIbddif_dVd = dIbddif_dT = 0; + here->B3SOIPDic = Ic = Gcd = Gcb = GcT = 0.0; + } + else + { + Ien = WTsi * jbjt * pParam->B3SOIPDlratio; + if (selfheat) + dIen_dT = WTsi * djbjt_dT * pParam->B3SOIPDlratio; + else + dIen_dT = 0; + + /* high level injection of source side */ + if ((Ehlis = Ahli * (ExpVbsNVtm - 1)) < 1e-5) + { + Ehlis = dEhlis_dVb = dEhlis_dT = 0; + EhlisFactor = 1; + dEhlisFactor_dVb = dEhlisFactor_dT = 0; + } + else + { + dEhlis_dVb = Ahli * dExpVbsNVtm_dVb; + if (selfheat) + dEhlis_dT = + Ahli * dExpVbsNVtm_dT + (ExpVbsNVtm - 1) * dAhli_dT; + else + dEhlis_dT = 0; + EhlisFactor = 1.0 / sqrt (1 + Ehlis); + T0 = -0.5 * EhlisFactor / (1 + Ehlis); + dEhlisFactor_dVb = T0 * dEhlis_dVb; + if (selfheat) + dEhlisFactor_dT = T0 * dEhlis_dT; + else + dEhlisFactor_dT = 0; + } + + /* high level injection of drain side */ + if ((Ehlid = Ahli * (ExpVbdNVtm - 1)) < 1e-5) + { + Ehlid = dEhlid_dVb = dEhlid_dVd = dEhlid_dT = 0; + EhlidFactor = 1; + dEhlidFactor_dVb = dEhlidFactor_dVd = dEhlidFactor_dT = 0; + } + else + { + dEhlid_dVb = Ahli * dExpVbdNVtm_dVb; + dEhlid_dVd = -dEhlid_dVb; + if (selfheat) + dEhlid_dT = + Ahli * dExpVbdNVtm_dT + (ExpVbdNVtm - 1) * dAhli_dT; + else + dEhlid_dT = 0; + EhlidFactor = 1.0 / sqrt (1 + Ehlid); + T0 = -0.5 * EhlidFactor / (1 + Ehlid); + dEhlidFactor_dVb = T0 * dEhlid_dVb; + dEhlidFactor_dVd = -dEhlidFactor_dVb; + if (selfheat) + dEhlidFactor_dT = T0 * dEhlid_dT; + else + dEhlidFactor_dT = 0; + } + + if ((T0 = (1 - pParam->B3SOIPDarfabjt)) < 1e-2) + { + Ibs3 = dIbs3_dVb = dIbs3_dT = 0; + + dIbs3_dVd = 0; + + Ibd3 = dIbd3_dVb = dIbd3_dVd = dIbd3_dT = 0; + } + else + { + T1 = T0 * Ien; + if (selfheat) + dT1_dT = T0 * dIen_dT; + else + dT1_dT = 0; + + Ibs3 = T1 * (ExpVbsNVtm - 1) * EhlisFactor; + dIbs3_dVb = T1 * (dExpVbsNVtm_dVb * EhlisFactor + + (ExpVbsNVtm - 1) * dEhlisFactor_dVb); + dIbs3_dVd = 0; + if (selfheat) + dIbs3_dT = dT1_dT * (ExpVbsNVtm - 1) * EhlisFactor + + T1 * (dExpVbsNVtm_dT * EhlisFactor + + (ExpVbsNVtm - 1) * dEhlisFactor_dT); + else + dIbs3_dT = 0.0; + + Ibd3 = T1 * (ExpVbdNVtm - 1) * EhlidFactor; + dIbd3_dVb = T1 * (dExpVbdNVtm_dVb * EhlidFactor + + (ExpVbdNVtm - 1) * dEhlidFactor_dVb); + dIbd3_dVd = -dIbd3_dVb; + if (selfheat) + dIbd3_dT = dT1_dT * (ExpVbdNVtm - 1) * EhlidFactor + + T1 * (dExpVbdNVtm_dT * EhlidFactor + + (ExpVbdNVtm - 1) * dEhlidFactor_dT); + else + dIbd3_dT = 0.0; + } + + /* effective diffusion current for capacitance calcu. */ + Iendif = WTsi * jbjt * pParam->B3SOIPDlratiodif; + if (selfheat) + dIendif_dT = WTsi * djbjt_dT * pParam->B3SOIPDlratiodif; + else + dIendif_dT = 0; + + Ibsdif = Iendif * (ExpVbsNVtm - 1) * EhlisFactor; + dIbsdif_dVb = Iendif * (dExpVbsNVtm_dVb * EhlisFactor + + (ExpVbsNVtm - 1) * dEhlisFactor_dVb); + if (selfheat) + dIbsdif_dT = dIendif_dT * (ExpVbsNVtm - 1) * EhlisFactor + + Iendif * (dExpVbsNVtm_dT * EhlisFactor + + (ExpVbsNVtm - 1) * dEhlisFactor_dT); + else + dIbsdif_dT = 0; + + Ibddif = Iendif * (ExpVbdNVtm - 1) * EhlidFactor; + dIbddif_dVb = Iendif * (dExpVbdNVtm_dVb * EhlidFactor + + (ExpVbdNVtm - 1) * dEhlidFactor_dVb); + dIbddif_dVd = -dIbddif_dVb; + if (selfheat) + dIbddif_dT = dIendif_dT * (ExpVbdNVtm - 1) * EhlidFactor + + Iendif * (dExpVbdNVtm_dT * EhlidFactor + + (ExpVbdNVtm - 1) * dEhlidFactor_dT); + else + dIbddif_dT = 0; + + /* Ic: Bjt collector current */ + if ((here->B3SOIPDbjtoff == 1) || (Vds == 0.0)) + { + here->B3SOIPDic = Ic = Gcd = Gcb = GcT = 0.0; + } + else + { + /* second order effects */ + T0 = 1 + (Vbs + Vbd) / pParam->B3SOIPDvearly; + dT0_dVb = 2.0 / pParam->B3SOIPDvearly; + dT0_dVd = -1.0 / pParam->B3SOIPDvearly; + + T1 = Ehlis + Ehlid; + dT1_dVb = dEhlis_dVb + dEhlid_dVb; + dT1_dVd = dEhlid_dVd; + if (selfheat) + dT1_dT = dEhlis_dT + dEhlid_dT; + else + dT1_dT = 0; + + T3 = sqrt (T0 * T0 + 4 * T1); + dT3_dVb = 0.5 / T3 * (2 * T0 * dT0_dVb + 4 * dT1_dVb); + dT3_dVd = 0.5 / T3 * (2 * T0 * dT0_dVd + 4 * dT1_dVd); + if (selfheat) + dT3_dT = 2 * dT1_dT / T3; + else + dT3_dT = 0; + + T2 = (T0 + T3) / 2.0; + dT2_dVb = (dT0_dVb + dT3_dVb) / 2.0; + dT2_dVd = (dT0_dVd + dT3_dVd) / 2.0; + if (selfheat) + dT2_dT = dT3_dT / 2.0; + else + dT2_dT = 0; + + if (T2 < .1) + { + E2ndFactor = 10.0; + dE2ndFactor_dVb = dE2ndFactor_dVd = dE2ndFactor_dT = 0; + } + + else + { + E2ndFactor = 1.0 / T2; + dE2ndFactor_dVb = -E2ndFactor / T2 * dT2_dVb; + dE2ndFactor_dVd = -E2ndFactor / T2 * dT2_dVd; + if (selfheat) + dE2ndFactor_dT = -E2ndFactor / T2 * dT2_dT; + else + dE2ndFactor_dT = 0; + } + + T0 = pParam->B3SOIPDarfabjt * Ien; + if (selfheat) + dT0_dT = pParam->B3SOIPDarfabjt * dIen_dT; + else + dT0_dT = 0; + here->B3SOIPDic = Ic + = T0 * (ExpVbsNVtm - ExpVbdNVtm) * E2ndFactor; + Gcb = dIc_dVb + = T0 * ((dExpVbsNVtm_dVb - dExpVbdNVtm_dVb) * E2ndFactor + + (ExpVbsNVtm - ExpVbdNVtm) * dE2ndFactor_dVb); + Gcd = dIc_dVd + = T0 * (-dExpVbdNVtm_dVd * E2ndFactor + + (ExpVbsNVtm - ExpVbdNVtm) * dE2ndFactor_dVd); + if (selfheat) + GcT = T0 * (dExpVbsNVtm_dT - dExpVbdNVtm_dT) * E2ndFactor + + dT0_dT * (ExpVbsNVtm - ExpVbdNVtm) * E2ndFactor + + T0 * (ExpVbsNVtm - ExpVbdNVtm) * dE2ndFactor_dT; + else + GcT = 0; + } + } + + /* Ibs4/Ibd4 : tunneling */ + NVtm2 = 0.026 * pParam->B3SOIPDntun; + if (jtun == 0) + { + Ibs4 = Ibd4 = dIbs4_dVb = dIbs4_dT = dIbd4_dVb = dIbd4_dVd = + dIbd4_dT = 0; + } + else + { + if ((pParam->B3SOIPDvtun0 - Vbs) < 1e-3) + Ibs4 = dIbs4_dVb = dIbs4_dT = 0; + else + { + T1 = 1 / (pParam->B3SOIPDvtun0 - Vbs); + T0 = -Vbs / NVtm2 * pParam->B3SOIPDvtun0 * T1; + dT0_dVb = + -pParam->B3SOIPDvtun0 / NVtm2 * (T1 + Vbs * T1 * T1); + + DEXP (T0, T1, T2); + T3 = WsTsi * jtun; + Ibs4 = T3 * (1 - T1); + dIbs4_dVb = -T3 * T2 * dT0_dVb; + if (selfheat) + dIbs4_dT = (1 - T1) * WsTsi * djtun_dT; + else + dIbs4_dT = 0; + } + + if ((pParam->B3SOIPDvtun0 - Vbd) < 1e-3) + { + Ibd4 = dIbd4_dVb = dIbd4_dT = 0; + + dIbd4_dVd = 0; + + } + else + { + T1 = 1 / (pParam->B3SOIPDvtun0 - Vbd); + T0 = -Vbd / NVtm2 * pParam->B3SOIPDvtun0 * T1; + dT0_dVb = + -pParam->B3SOIPDvtun0 / NVtm2 * (T1 + Vbd * T1 * T1); + + DEXP (T0, T1, T2); + T3 = WdTsi * jtun; + Ibd4 = T3 * (1 - T1); + dIbd4_dVb = -T3 * T2 * dT0_dVb; + + dIbd4_dVd = -dIbd4_dVb; + + if (selfheat) + dIbd4_dT = (1 - T1) * WdTsi * djtun_dT; + else + dIbd4_dT = 0; + } + } + + here->B3SOIPDitun = -Ibd3 - Ibd4; + here->B3SOIPDibs = Ibs = Ibs1 + Ibs2 + Ibs3 + Ibs4; + here->B3SOIPDibd = Ibd = Ibd1 + Ibd2 + Ibd3 + Ibd4; + + Gjsb = dIbs1_dVb + dIbs2_dVb + dIbs3_dVb + dIbs4_dVb; + Gjsd = dIbs3_dVd; + if (selfheat) + GjsT = dIbs1_dT + dIbs2_dT + dIbs3_dT + dIbs4_dT; + else + GjsT = 0.0; + + Gjdb = dIbd1_dVb + dIbd2_dVb + dIbd3_dVb + dIbd4_dVb; + Gjdd = dIbd1_dVd + dIbd2_dVd + dIbd3_dVd + dIbd4_dVd; + if (selfheat) + GjdT = dIbd1_dT + dIbd2_dT + dIbd3_dT + dIbd4_dT; + else + GjdT = 0.0; + + +/* v2.2: calculate gate-tunneling-to-body current */ + + if (model->B3SOIPDigMod >= 1) + { + Vgb = Vgs_eff - Vbs; + dVgb_dVg = dVgs_eff_dVg; + dVgb_dVb = -1; + + /* Calculate Vox first */ + Vfb = + model->B3SOIPDtype * pParam->B3SOIPDvth0 - phi - + pParam->B3SOIPDk1eff * sqrtPhi; + + T3 = Vfb - Vgs_eff + Vbs - DELTA_3; + dT3_dVg = -dVgs_eff_dVg; + dT3_dVd = 0; + dT3_dVb = 1; + + if (Vfb <= 0.0) + { + T0 = sqrt (T3 * T3 - 4.0 * DELTA_3 * Vfb); + dT0_dVg = 1.0 / (2.0 * T0) * 2.0 * T3 * dT3_dVg; + dT0_dVb = 0.5 * (1.0 / T0) * 2.0 * T3 * dT3_dVb; + } + else + { + T0 = sqrt (T3 * T3 + 4.0 * DELTA_3 * Vfb); + dT0_dVg = 1.0 / (2.0 * T0) * 2.0 * T3 * dT3_dVg; + dT0_dVb = 0.5 * (1.0 / T0) * 2.0 * T3 * dT3_dVb; + } + + Vfbeff = Vfb - 0.5 * (T3 + T0); + dVfbeff_dVg = -0.5 * (dT3_dVg + dT0_dVg); + dVfbeff_dVb = -0.5 * (dT3_dVb + dT0_dVb); + + Voxacc = Vfb - Vfbeff; + dVoxacc_dVg = -dVfbeff_dVg; + dVoxacc_dVd = 0.0; + dVoxacc_dVb = -dVfbeff_dVb; + if (Voxacc < 0.0) + Voxacc = dVoxacc_dVg = dVoxacc_dVb = 0.0; + + T0 = Vgs_eff - Vgsteff - Vfbeff - Vbseff; + dT0_dVg = dVgs_eff_dVg - dVgsteff_dVg - dVfbeff_dVg; + dT0_dVd = -dVgsteff_dVd; + dT0_dVb = -dVgsteff_dVb - dVfbeff_dVb - dVbseff_dVb; + if (selfheat) + dT0_dT = -dVgsteff_dT; + + if (pParam->B3SOIPDk1eff == 0.0) + { + Voxdepinv = dVoxdepinv_dVg = dVoxdepinv_dVd = dVoxdepinv_dVb + = dVoxdepinv_dT = 0.0; + } + else + { + if (T0 < 0.0) + { + T1 = T0 / pParam->B3SOIPDk1eff; + dT1_dVg = dT0_dVg / pParam->B3SOIPDk1eff; + dT1_dVd = dT0_dVd / pParam->B3SOIPDk1eff; + dT1_dVb = dT0_dVb / pParam->B3SOIPDk1eff; + if (selfheat) + dT1_dT = dT0_dT / pParam->B3SOIPDk1eff; + } + else + { + T1 = pParam->B3SOIPDk1eff / 2 * (-1 + sqrt (1 + + 4 * T0 / + pParam-> + B3SOIPDk1eff + / + pParam-> + B3SOIPDk1eff)); + T2 = + pParam->B3SOIPDk1eff / 2 * 0.5 / sqrt (1 + + 4 * T0 / + pParam-> + B3SOIPDk1eff / + pParam-> + B3SOIPDk1eff) * + 4 / pParam->B3SOIPDk1eff / pParam->B3SOIPDk1eff; + dT1_dVg = T2 * dT0_dVg; + dT1_dVd = T2 * dT0_dVd; + dT1_dVb = T2 * dT0_dVb; + if (selfheat) + dT1_dT = T2 * dT0_dT; + } + + Voxdepinv = Vgs_eff - (T1 * T1 + Vbs) - Vfb; + dVoxdepinv_dVg = dVgs_eff_dVg - (2.0 * T1 * dT1_dVg); + dVoxdepinv_dVd = -(2.0 * T1 * dT1_dVd); + dVoxdepinv_dVb = -(2.0 * T1 * dT1_dVb + 1); + if (selfheat) + dVoxdepinv_dT = -(2.0 * T1 * dT1_dT); + } + + + OxideRatio = pParam->B3SOIPDoxideRatio; + + Vox = Voxdepinv; + /* Voxeff is Vox limited below Voxh */ + T0 = model->B3SOIPDvoxh; + T1 = T0 - Vox - model->B3SOIPDdeltavox; + T3 = sqrt (T1 * T1 + 4 * model->B3SOIPDdeltavox * T0); + Voxeff = T0 - 0.5 * (T1 + T3); + dVoxeff_dVox = 0.5 * (1.0 + T1 / T3); + + Vox = Voxeff; + dVox_dVg = dVoxdepinv_dVg * dVoxeff_dVox; + dVox_dVd = dVoxdepinv_dVd * dVoxeff_dVox; + dVox_dVb = dVoxdepinv_dVb * dVoxeff_dVox; + dVox_dT = dVoxdepinv_dT * dVoxeff_dVox; + + + T0 = (Vox - model->B3SOIPDebg) / model->B3SOIPDnevb / Vtm; + if (selfheat) + dT0_dT = + (dVox_dT / Vtm - + (Vox - + model->B3SOIPDebg) / Vtm / Vtm * dVtm_dT) / + model->B3SOIPDnevb; + + DEXP (T0, T1, T2); /* T1=exp(T0), T2=dT1_dT0 */ + if (selfheat) + dT1_dT = T2 * dT0_dT; + + Vaux = model->B3SOIPDnevb * Vtm * log (1 + T1); + dVaux_dVg = T2 / (1 + T1) * dVox_dVg; + dVaux_dVd = T2 / (1 + T1) * dVox_dVd; + dVaux_dVb = T2 / (1 + T1) * dVox_dVb; + if (selfheat) + dVaux_dT = model->B3SOIPDnevb * (dVtm_dT * log (1 + T1) + + Vtm * dT1_dT / (1 + T1)); + + if (model->B3SOIPDvgb1 != 0) + { + T0 = 1 - Vox / model->B3SOIPDvgb1; + dT0_dVox = -1.0 / model->B3SOIPDvgb1; + if (selfheat) + dT0_dT = -dVox_dT / model->B3SOIPDvgb1; + } + else + { + T0 = 1; + dT0_dVox = dT0_dT = 0.0; + } + + if (T0 < 0.01) + { + T0 = 0.01; + dT0_dVox = dT0_dT = 0.0; + } + + T1 = Leff * Weff * 3.7622e-7 * OxideRatio; + T2 = -3.1051e10 * model->B3SOIPDtoxqm; + T3 = model->B3SOIPDalphaGB1; + T4 = model->B3SOIPDbetaGB1; + + T6 = T2 * (T3 - T4 * Vox) / T0; + if (selfheat) + dT6_dT = -T2 * T4 * dVox_dT / T0 - T6 / T0 * dT0_dT; + + DEXP (T6, T5, T7); /* T5=exp(T6), T7=dT5_dT6 */ + dT5_dVg = + -T7 * dVox_dVg * T2 / T0 * (T4 + + (T3 - T4 * Vox) / T0 * dT0_dVox); + dT5_dVd = + -T7 * dVox_dVd * T2 / T0 * (T4 + + (T3 - T4 * Vox) / T0 * dT0_dVox); + dT5_dVb = + -T7 * dVox_dVb * T2 / T0 * (T4 + + (T3 - T4 * Vox) / T0 * dT0_dVox); + if (selfheat) + dT5_dT = T7 * dT6_dT; + + Igb1 = T1 * Vgb * Vaux * T5; + dIgb1_dVg = T1 * (Vgb * Vaux * dT5_dVg + dVgb_dVg * Vaux * T5 + + Vgb * T5 * dVaux_dVg); + dIgb1_dVd = T1 * (Vgb * Vaux * dT5_dVd + Vgb * T5 * dVaux_dVd); + dIgb1_dVb = T1 * (Vgb * Vaux * dT5_dVb + dVgb_dVb * Vaux * T5 + + Vgb * T5 * dVaux_dVb); + if (selfheat) + dIgb1_dT = T1 * Vgb * (Vaux * dT5_dT + T5 * dVaux_dT); + else + dIgb1_dT = 0.0; + + + Vox = Voxacc; + /* Voxeff is Vox limited below Voxh */ + T0 = model->B3SOIPDvoxh; + T1 = T0 - Vox - model->B3SOIPDdeltavox; + T3 = sqrt (T1 * T1 + 4 * model->B3SOIPDdeltavox * T0); + Voxeff = T0 - 0.5 * (T1 + T3); + dVoxeff_dVox = 0.5 * (1.0 + T1 / T3); + + Vox = Voxeff; + dVox_dVg = dVoxacc_dVg * dVoxeff_dVox; + dVox_dVd = dVoxacc_dVd * dVoxeff_dVox; + dVox_dVb = dVoxacc_dVb * dVoxeff_dVox; + dVox_dT = 0; + + T0 = (-Vgb + (Vfb)) / model->B3SOIPDnecb / Vtm; + if (selfheat) + dT0_dT = -T0 / Vtm * dVtm_dT; + + DEXP (T0, T1, T2); /* T1=exp(T0), T2=dT1_dT0 */ + if (selfheat) + dT1_dT = T2 * dT0_dT; + + Vaux = model->B3SOIPDnecb * Vtm * log (1 + T1); + dVaux_dVg = -T2 / (1 + T1); + dVaux_dVd = 0; + dVaux_dVb = -dVaux_dVg; + if (selfheat) + dVaux_dT = model->B3SOIPDnecb * (dVtm_dT * log (1 + T1) + + Vtm * dT1_dT / (1 + T1)); + + if (model->B3SOIPDvgb2 != 0) + { + T0 = 1 - Vox / model->B3SOIPDvgb2; + dT0_dVox = -1.0 / model->B3SOIPDvgb2; + if (selfheat) + dT0_dT = -dVox_dT / model->B3SOIPDvgb2; + } + else + { + T0 = 1; + dT0_dVox = dT0_dT = 0.0; + } + + if (T0 < 0.01) + { + T0 = 0.01; + dT0_dVox = dT0_dT = 0.0; + } + + T1 = Leff * Weff * 4.9758e-7 * OxideRatio; + T2 = -2.357e10 * model->B3SOIPDtoxqm; + T3 = model->B3SOIPDalphaGB2; + T4 = model->B3SOIPDbetaGB2; + + T6 = T2 * (T3 - T4 * Vox) / T0; + if (selfheat) + dT6_dT = -T2 * T4 * dVox_dT / T0 - T6 / T0 * dT0_dT; + + DEXP (T6, T5, T7); /* T5=exp(T6), T7=dT5_dT6 */ + dT5_dVg = + -T7 * dVox_dVg * T2 / T0 * (T4 + + (T3 - T4 * Vox) / T0 * dT0_dVox); + dT5_dVd = + -T7 * dVox_dVd * T2 / T0 * (T4 + + (T3 - T4 * Vox) / T0 * dT0_dVox); + dT5_dVb = + -T7 * dVox_dVb * T2 / T0 * (T4 + + (T3 - T4 * Vox) / T0 * dT0_dVox); + if (selfheat) + dT5_dT = T7 * dT6_dT; + + Igb2 = T1 * Vgb * Vaux * T5; + dIgb2_dVg = T1 * (Vgb * Vaux * dT5_dVg + dVgb_dVg * Vaux * T5 + + Vgb * T5 * dVaux_dVg); + dIgb2_dVd = T1 * (Vgb * Vaux * dT5_dVd + Vgb * T5 * dVaux_dVd); + dIgb2_dVb = T1 * (Vgb * Vaux * dT5_dVb + dVgb_dVb * Vaux * T5 + + Vgb * T5 * dVaux_dVb); + if (selfheat) + dIgb2_dT = T1 * Vgb * (Vaux * dT5_dT + T5 * dVaux_dT); + else + dIgb2_dT = 0.0; + + + Igb = Igb1 + Igb2; + /* Igb1 dominates in inversion region, while Igb2 doninates in accumulation */ + dIgb_dVg = dIgb1_dVg + dIgb2_dVg; + dIgb_dVd = dIgb1_dVd + dIgb2_dVd; + dIgb_dVb = dIgb1_dVb + dIgb2_dVb; + dIgb_dT = dIgb1_dT + dIgb2_dT; + + } + else + { + Igb = 0.0; + dIgb_dVg = 0.0; + dIgb_dVd = 0.0; + dIgb_dVb = 0.0; + dIgb_dT = 0.0; + } + + here->B3SOIPDig = Igb; + here->B3SOIPDgigg = dIgb_dVg; + here->B3SOIPDgigd = dIgb_dVd; + here->B3SOIPDgigb = dIgb_dVb; + here->B3SOIPDgigs = -(dIgb_dVg + dIgb_dVd + dIgb_dVb); + here->B3SOIPDgigT = dIgb_dT; +/* end of v2.2 gate current */ + + + +/* calculate substrate current Iii */ + + if (pParam->B3SOIPDalpha0 <= 0.0) + { + Giig = Giib = Giid = GiiT = 0.0; + here->B3SOIPDiii = Iii = 0.0; + } + else + { + Vdsatii0 = + pParam->B3SOIPDvdsatii0 * (1 + + model->B3SOIPDtii * (TempRatio - + 1.0)) - + pParam->B3SOIPDlii / Leff; + if (selfheat) + dVdsatii0_dT = + pParam->B3SOIPDvdsatii0 * model->B3SOIPDtii * dTempRatio_dT; + else + dVdsatii0_dT = 0; + + /* Calculate VgsStep */ + T0 = pParam->B3SOIPDesatii * Leff; + T1 = pParam->B3SOIPDsii0 * T0 / (1.0 + T0); + + T0 = 1 / (1 + pParam->B3SOIPDsii1 * Vgsteff); + if (selfheat) + dT0_dT = -pParam->B3SOIPDsii1 * T0 * T0 * dVgsteff_dT; + else + dT0_dT = 0; + T3 = T0 + pParam->B3SOIPDsii2; + T4 = Vgst * pParam->B3SOIPDsii1 * T0 * T0; + T2 = Vgst * T3; + dT2_dVg = T3 * dVgst_dVg - T4 * dVgsteff_dVg; + dT2_dVb = T3 * dVgst_dVb * dVbseff_dVb - T4 * dVgsteff_dVb; + dT2_dVd = T3 * dVgst_dVd - T4 * dVgsteff_dVd; + if (selfheat) + dT2_dT = -dVth_dT * T3 + Vgst * dT0_dT; + else + dT2_dT = 0; + + T3 = 1 / (1 + pParam->B3SOIPDsiid * Vds); + dT3_dVd = -pParam->B3SOIPDsiid * T3 * T3; + + VgsStep = T1 * T2 * T3; + if (selfheat) + dVgsStep_dT = T1 * T3 * dT2_dT; + else + dVgsStep_dT = 0; + Vdsatii = Vdsatii0 + VgsStep; + Vdiff = Vds - Vdsatii; + dVdiff_dVg = -T1 * T3 * dT2_dVg; + dVdiff_dVb = -T1 * T3 * dT2_dVb; + dVdiff_dVd = 1.0 - T1 * (T3 * dT2_dVd + T2 * dT3_dVd); + if (selfheat) + dVdiff_dT = -(dVdsatii0_dT + dVgsStep_dT); + else + dVdiff_dT = 0; + + T0 = pParam->B3SOIPDbeta2 + pParam->B3SOIPDbeta1 * Vdiff + + pParam->B3SOIPDbeta0 * Vdiff * Vdiff; + if (T0 < 1e-5) + { + T0 = 1e-5; + dT0_dVg = dT0_dVd = dT0_dVb = dT0_dT = 0.0; + } + else + { + T1 = + pParam->B3SOIPDbeta1 + 2 * pParam->B3SOIPDbeta0 * Vdiff; + dT0_dVg = T1 * dVdiff_dVg; + dT0_dVb = T1 * dVdiff_dVb; + dT0_dVd = T1 * dVdiff_dVd; + if (selfheat) + dT0_dT = T1 * dVdiff_dT; + else + dT0_dT = 0; + } + + if ((T0 < Vdiff / EXPL_THRESHOLD) && (Vdiff > 0.0)) + { + Ratio = pParam->B3SOIPDalpha0 * MAX_EXPL; + dRatio_dVg = dRatio_dVb = dRatio_dVd = dRatio_dT = 0.0; + } + else if ((T0 < -Vdiff / EXPL_THRESHOLD) && (Vdiff < 0.0)) + { + Ratio = pParam->B3SOIPDalpha0 * MIN_EXPL; + dRatio_dVg = dRatio_dVb = dRatio_dVd = dRatio_dT = 0.0; + } + else + { + Ratio = pParam->B3SOIPDalpha0 * exp (Vdiff / T0); + T1 = Ratio / T0 / T0; + dRatio_dVg = T1 * (T0 * dVdiff_dVg - Vdiff * dT0_dVg); + dRatio_dVb = T1 * (T0 * dVdiff_dVb - Vdiff * dT0_dVb); + dRatio_dVd = T1 * (T0 * dVdiff_dVd - Vdiff * dT0_dVd); + if (selfheat) + dRatio_dT = T1 * (T0 * dVdiff_dT - Vdiff * dT0_dT); + else + dRatio_dT = 0; + } + + /* Avoid too high ratio */ + if (Ratio > 10.0) + { + Ratio = 10.0; + dRatio_dVg = dRatio_dVb = dRatio_dVd = dRatio_dT = 0.0; + } + + T0 = Ids + pParam->B3SOIPDfbjtii * Ic; + here->B3SOIPDiii = Iii = Ratio * T0; + Giig = Ratio * Gm + T0 * dRatio_dVg; + Giib = Ratio * (Gmb + pParam->B3SOIPDfbjtii * Gcb) + + T0 * dRatio_dVb; + Giid = Ratio * (Gds + pParam->B3SOIPDfbjtii * Gcd) + + T0 * dRatio_dVd; + + if (selfheat) + GiiT = Ratio * (GmT + pParam->B3SOIPDfbjtii * GcT) + + T0 * dRatio_dT; + else + GiiT = 0.0; + + } + + /* Current through body resistor */ + /* Current going out is +ve */ + if ((here->B3SOIPDbodyMod == 0) || (here->B3SOIPDbodyMod == 2)) + { + Ibp = Gbpbs = Gbpps = 0.0; + } + else + { /* here->B3SOIPDbodyMod == 1 */ + if (pParam->B3SOIPDrbody < 1e-30) + { + if (here->B3SOIPDrbodyext <= 1e-30) + T0 = 1.0 / 1e-30; + else + T0 = 1.0 / here->B3SOIPDrbodyext; + Ibp = Vbp * T0; + Gbpbs = T0 * dVbp_dVb; + Gbpps = -T0 * dVbp_dVb; + } + else + { + Gbpbs = + 1.0 / (pParam->B3SOIPDrbody + here->B3SOIPDrbodyext); + Ibp = Vbp * Gbpbs; + Gbpps = -Gbpbs; + } + } + + here->B3SOIPDibp = Ibp; + here->B3SOIPDgbpbs = Gbpbs; + here->B3SOIPDgbpps = Gbpps; + here->B3SOIPDgbpT = 0.0; + here->B3SOIPDcbodcon = Ibp - (Gbpbs * Vbs + Gbpps * Vps); + + + + /* Current going out of drainprime node into the drain of device */ + /* "node" means the SPICE circuit node */ + + here->B3SOIPDcdrain = Ids + Ic; + here->B3SOIPDcd = Ids + Ic - Ibd + Iii + Idgidl; + here->B3SOIPDcb = Ibs + Ibd + Ibp - Iii - Idgidl - Isgidl - Igb; + + here->B3SOIPDgds = Gds + Gcd; + here->B3SOIPDgm = Gm; + here->B3SOIPDgmbs = Gmb + Gcb; + if (selfheat) + here->B3SOIPDgmT = GmT + GcT; + else + here->B3SOIPDgmT = 0.0; + + /* note that sign is switched because power flows out + of device into the temperature node. + Currently ommit self-heating due to bipolar current + because it can cause convergence problem */ + + here->B3SOIPDgtempg = -Gm * Vds; + here->B3SOIPDgtempb = -Gmb * Vds; + here->B3SOIPDgtempT = -GmT * Vds; + here->B3SOIPDgtempd = -Gds * Vds - Ids; + here->B3SOIPDcth = -Ids * Vds - model->B3SOIPDtype * + (here->B3SOIPDgtempg * Vgs + here->B3SOIPDgtempb * Vbs + + here->B3SOIPDgtempd * Vds) - here->B3SOIPDgtempT * delTemp; + + /* Body current which flows into drainprime node from the drain of device */ + + here->B3SOIPDgjdb = Gjdb - Giib; + here->B3SOIPDgjdd = Gjdd - (Giid + Gdgidld); + here->B3SOIPDgjdg = -(Giig + Gdgidlg); + if (selfheat) + here->B3SOIPDgjdT = GjdT - GiiT; + else + here->B3SOIPDgjdT = 0.0; + here->B3SOIPDcjd = Ibd - Iii - Idgidl + - (here->B3SOIPDgjdb * Vbs + here->B3SOIPDgjdd * Vds + + here->B3SOIPDgjdg * Vgs + here->B3SOIPDgjdT * delTemp); + + /* Body current which flows into sourceprime node from the source of device */ + + here->B3SOIPDgjsb = Gjsb; + here->B3SOIPDgjsd = Gjsd; + here->B3SOIPDgjsg = -Gsgidlg; + if (selfheat) + here->B3SOIPDgjsT = GjsT; + else + here->B3SOIPDgjsT = 0.0; + here->B3SOIPDcjs = Ibs - Isgidl + - (here->B3SOIPDgjsb * Vbs + here->B3SOIPDgjsd * Vds + + here->B3SOIPDgjsg * Vgs + here->B3SOIPDgjsT * delTemp); + + /* Current flowing into body node */ + + here->B3SOIPDgbbs = Giib - Gjsb - Gjdb - Gbpbs; + here->B3SOIPDgbgs = Giig + Gdgidlg + Gsgidlg; + here->B3SOIPDgbds = Giid + Gdgidld - Gjsd - Gjdd; + here->B3SOIPDgbps = -Gbpps; + if (selfheat) + here->B3SOIPDgbT = GiiT - GjsT - GjdT; + else + here->B3SOIPDgbT = 0.0; + + + here->B3SOIPDcbody = Iii + Idgidl + Isgidl - Ibs - Ibd - Ibp + Igb + - ((here->B3SOIPDgbbs + dIgb_dVb) * Vbs + + (here->B3SOIPDgbgs + dIgb_dVg) * Vgs + + (here->B3SOIPDgbds + dIgb_dVd) * Vds + + here->B3SOIPDgbps * Vps + + (here->B3SOIPDgbT + dIgb_dT) * delTemp); + + + here->B3SOIPDcgate = Igb + - (dIgb_dVb * Vbs + dIgb_dVg * Vgs + dIgb_dVd * Vds + + dIgb_dT * delTemp); + + + /* Calculate Qinv for Noise analysis */ + + T1 = Vgsteff * (1.0 - 0.5 * Abulk * Vdseff / Vgst2Vtm); + here->B3SOIPDqinv = + -model->B3SOIPDcox * pParam->B3SOIPDweff * Leff * T1; + + + /* Begin CV (charge) model */ + + if ((model->B3SOIPDxpart < 0) || (!ChargeComputationNeeded)) + { + qgate = qdrn = qsrc = qbody = 0.0; + here->B3SOIPDcggb = here->B3SOIPDcgsb = here->B3SOIPDcgdb = 0.0; + here->B3SOIPDcdgb = here->B3SOIPDcdsb = here->B3SOIPDcddb = 0.0; + here->B3SOIPDcbgb = here->B3SOIPDcbsb = here->B3SOIPDcbdb = 0.0; + goto finished; + } + else + { + CoxWL = + model->B3SOIPDcox * (pParam->B3SOIPDweffCV / + here->B3SOIPDnseg * + pParam->B3SOIPDleffCV + + here->B3SOIPDagbcp); + CoxWLb = + model->B3SOIPDfbody * model->B3SOIPDcox * + (pParam->B3SOIPDweffCV / here->B3SOIPDnseg * + pParam->B3SOIPDleffCVb + here->B3SOIPDagbcp); + + /* By using this Vgsteff,cv, discontinuity in moderate + inversion charges can be avoid. */ + + if ((VgstNVt > -EXPL_THRESHOLD) && (VgstNVt < EXPL_THRESHOLD)) + { + ExpVgst *= ExpVgst; + ExpVgst *= exp (-(pParam->B3SOIPDdelvt / (n * Vtm))); + Vgsteff = n * Vtm * log (1.0 + ExpVgst); + T0 = ExpVgst / (1.0 + ExpVgst); + T1 = + -T0 * (dVth_dVb + Vgst / n * dn_dVb) + + Vgsteff / n * dn_dVb; + dVgsteff_dVd = + -T0 * (dVth_dVd + Vgst / n * dn_dVd) + + Vgsteff / n * dn_dVd; + dVgsteff_dVg = T0 * dVgs_eff_dVg; + dVgsteff_dVb = T1 * dVbseff_dVb; + if (selfheat) + dVgsteff_dT = + -T0 * (dVth_dT + (Vgst - pParam->B3SOIPDdelvt) / Temp) + + Vgsteff / Temp; + else + dVgsteff_dT = 0.0; + } + + if (model->B3SOIPDcapMod == 2) + { + Vfb = + Vth - phi - pParam->B3SOIPDk1eff * sqrtPhis + + pParam->B3SOIPDdelvt; + dVfb_dVb = dVth_dVb - pParam->B3SOIPDk1eff * dsqrtPhis_dVb; + dVfb_dVd = dVth_dVd; + dVfb_dT = dVth_dT; + + V3 = Vfb - Vgs_eff + Vbseff - DELTA_3_SOI; + if (Vfb <= 0.0) + { + T0 = sqrt (V3 * V3 - 4.0 * DELTA_3_SOI * Vfb); + T2 = -DELTA_3_SOI / T0; + } + else + { + T0 = sqrt (V3 * V3 + 4.0 * DELTA_3_SOI * Vfb); + T2 = DELTA_3_SOI / T0; + } + + T1 = 0.5 * (1.0 + V3 / T0); + Vfbeff = Vfb - 0.5 * (V3 + T0); + dVfbeff_dVd = (1.0 - T1 - T2) * dVfb_dVd; + dVfbeff_dVb = (1.0 - T1 - T2) * dVfb_dVb - T1; + dVfbeff_dVrg = T1 * dVgs_eff_dVg; + if (selfheat) + dVfbeff_dT = (1.0 - T1 - T2) * dVfb_dT; + else + dVfbeff_dT = 0.0; + + Qac0 = CoxWLb * (Vfbeff - Vfb); + dQac0_dVrg = CoxWLb * dVfbeff_dVrg; + dQac0_dVd = CoxWLb * (dVfbeff_dVd - dVfb_dVd); + dQac0_dVb = CoxWLb * (dVfbeff_dVb - dVfb_dVb); + if (selfheat) + dQac0_dT = CoxWLb * (dVfbeff_dT - dVfb_dT); + else + dQac0_dT = 0.0; + + T0 = 0.5 * K1; + T3 = Vgs_eff - Vfbeff - Vbseff - Vgsteff; + if (pParam->B3SOIPDk1eff == 0.0) + { + T1 = 0.0; + T2 = 0.0; + } + else if (T3 < 0.0) + { + T1 = T0 + T3 / pParam->B3SOIPDk1eff; + T2 = CoxWLb; + } + else + { + T1 = sqrt (T0 * T0 + T3); + T2 = CoxWLb * T0 / T1; + } + + Qsub0 = CoxWLb * K1 * (T1 - T0); + dQsub0_dVrg = T2 * (dVgs_eff_dVg - dVfbeff_dVrg); + dQsub0_dVg = -T2; + dQsub0_dVd = -T2 * dVfbeff_dVd; + dQsub0_dVb = -T2 * (dVfbeff_dVb + 1); + if (selfheat) + dQsub0_dT = -T2 * dVfbeff_dT; + else + dQsub0_dT = 0.0; + + AbulkCV = Abulk0 * pParam->B3SOIPDabulkCVfactor; + dAbulkCV_dVb = pParam->B3SOIPDabulkCVfactor * dAbulk0_dVb; + + VdsatCV = Vgsteff / AbulkCV; + dVdsatCV_dVg = 1.0 / AbulkCV; + dVdsatCV_dVb = -VdsatCV * dAbulkCV_dVb / AbulkCV; + + V4 = VdsatCV - Vds - DELTA_4; + T0 = sqrt (V4 * V4 + 4.0 * DELTA_4 * VdsatCV); + VdseffCV = VdsatCV - 0.5 * (V4 + T0); + T1 = 0.5 * (1.0 + V4 / T0); + T2 = DELTA_4 / T0; + T3 = (1.0 - T1 - T2) / AbulkCV; + dVdseffCV_dVg = T3; + dVdseffCV_dVd = T1; + dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb; + + T0 = AbulkCV * VdseffCV; + T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1e-20); + T2 = VdseffCV / T1; + T3 = T0 * T2; + T4 = (1.0 - 12.0 * T2 * T2 * AbulkCV); + T5 = (6.0 * T0 * (4.0 * Vgsteff - T0) / (T1 * T1) - 0.5); + T6 = 12.0 * T2 * T2 * Vgsteff; + + T7 = 1.0 - AbulkCV; + qbulk = CoxWLb * T7 * (0.5 * VdseffCV - T3); + T4 = -T7 * (T4 - 1.0); + T5 = -T7 * T5; + T6 = -(T7 * T6 + (0.5 * VdseffCV - T3)); + + Cbg1 = CoxWLb * (T4 + T5 * dVdseffCV_dVg); + Cbd1 = CoxWLb * T5 * dVdseffCV_dVd; + Cbb1 = CoxWLb * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb); + + /* Total inversion charge */ + T0 = AbulkCV * VdseffCV; + T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1e-20); + T2 = VdseffCV / T1; + T3 = T0 * T2; + + T4 = (1.0 - 12.0 * T2 * T2 * AbulkCV); + T5 = (6.0 * T0 * (4.0 * Vgsteff - T0) / (T1 * T1) - 0.5); + T6 = 12.0 * T2 * T2 * Vgsteff; + + qinv = CoxWL * (Vgsteff - 0.5 * VdseffCV + T3); + Cgg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); + Cgd1 = CoxWL * T5 * dVdseffCV_dVd; + Cgb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb); + + /* Inversion charge partitioning into S / D */ + if (model->B3SOIPDxpart > 0.5) + { /* 0/100 Charge partition model */ + T1 = T1 + T1; + qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 + - T0 * T0 / T1); + T7 = (4.0 * Vgsteff - T0) / (T1 * T1); + T4 = -(0.5 + 24.0 * T0 * T0 / (T1 * T1)); + T5 = -(0.25 * AbulkCV - 12.0 * AbulkCV * T0 * T7); + T6 = -(0.25 * VdseffCV - 12.0 * T0 * VdseffCV * T7); + Csg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); + Csd1 = CoxWL * T5 * dVdseffCV_dVd; + Csb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb); + + } + else if (model->B3SOIPDxpart < 0.5) + { /* 40/60 Charge partition model */ + T1 = T1 / 12.0; + T2 = 0.5 * CoxWL / (T1 * T1); + T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff + * (Vgsteff - 4.0 * T0 / 3.0)) + - 2.0 * T0 * T0 * T0 / 15.0; + qsrc = -T2 * T3; + T7 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0) + + 0.4 * T0 * T0; + T4 = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0 + * Vgsteff - + 8.0 * T0 / + 3.0) + + 2.0 * T0 * T0 / 3.0); + T5 = (qsrc / T1 + T2 * T7) * AbulkCV; + T6 = (qsrc / T1 * VdseffCV + T2 * T7 * VdseffCV); + Csg1 = T4 + T5 * dVdseffCV_dVg; + Csd1 = T5 * dVdseffCV_dVd; + Csb1 = T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb; + } + else + { /* 50/50 Charge partition model */ + qsrc = -0.5 * (qinv + qbulk); + Csg1 = -0.5 * (Cgg1 + Cbg1); + Csb1 = -0.5 * (Cgb1 + Cbb1); + Csd1 = -0.5 * (Cgd1 + Cbd1); + } + + /* Backgate charge */ + CboxWL = pParam->B3SOIPDkb1 * model->B3SOIPDfbody * Cbox + * (pParam->B3SOIPDweffCV / here->B3SOIPDnseg + * pParam->B3SOIPDleffCVbg + here->B3SOIPDaebcp); + Qe1 = CboxWL * (Vesfb - Vbs); + dQe1_dVb = -CboxWL; + dQe1_dVe = CboxWL; + if (selfheat) + dQe1_dT = -CboxWL * dvfbb_dT; + else + dQe1_dT = 0; + + qgate = qinv + Qac0 + Qsub0; + qbody = (qbulk - Qac0 - Qsub0 - Qe1); + qsub = Qe1; + qdrn = -(qgate + qsrc + qbody + qsub); + + /* This transform all the dependency on Vgsteff, Vbseff + into real ones */ + Ce1b = dQe1_dVb; + Ce1e = dQe1_dVe; + + Csg = Csg1 * dVgsteff_dVg; + Csd = Csd1 + Csg1 * dVgsteff_dVd; + Csb = Csg1 * dVgsteff_dVb + Csb1 * dVbseff_dVb; + if (selfheat) + CsT = Csg1 * dVgsteff_dT; + else + CsT = 0.0; + + Cgg = (Cgg1 + dQsub0_dVg) * dVgsteff_dVg + + dQac0_dVrg + dQsub0_dVrg; + Cgd = (Cgg1 + dQsub0_dVg) * dVgsteff_dVd + Cgd1 + + dQac0_dVd + dQsub0_dVd; + Cgb = (Cgg1 + dQsub0_dVg) * dVgsteff_dVb + + (Cgb1 + dQsub0_dVb + dQac0_dVb) * dVbseff_dVb; + if (selfheat) + CgT = (Cgg1 + dQsub0_dVg) * dVgsteff_dT + + dQac0_dT + dQsub0_dT; + else + CgT = 0.0; + + Cbg = (Cbg1 - dQsub0_dVg) * dVgsteff_dVg + - dQac0_dVrg - dQsub0_dVrg; + Cbd = (Cbg1 - dQsub0_dVg) * dVgsteff_dVd + Cbd1 + - dQac0_dVd - dQsub0_dVd; + Cbb = (Cbg1 - dQsub0_dVg) * dVgsteff_dVb - dQe1_dVb + + (Cbb1 - dQsub0_dVb - dQac0_dVb) * dVbseff_dVb; + if (selfheat) + CbT = (Cbg1 - dQsub0_dVg) * dVgsteff_dT + - dQac0_dT - dQsub0_dT - dQe1_dT; + else + CbT = 0.0; + + here->B3SOIPDcggb = Cgg; + here->B3SOIPDcgsb = -(Cgg + Cgd + Cgb); + here->B3SOIPDcgdb = Cgd; + here->B3SOIPDcgT = CgT; + + here->B3SOIPDcbgb = Cbg; + here->B3SOIPDcbsb = -(Cbg + Cbd + Cbb) + Ce1e; + here->B3SOIPDcbdb = Cbd; + here->B3SOIPDcbeb = -Ce1e; + here->B3SOIPDcbT = CbT; + + here->B3SOIPDceeb = Ce1e; + here->B3SOIPDceT = dQe1_dT; + + here->B3SOIPDcdgb = -(Cgg + Cbg + Csg); + here->B3SOIPDcddb = -(Cgd + Cbd + Csd); + here->B3SOIPDcdeb = 0; + here->B3SOIPDcdT = -(CgT + CbT + CsT) - dQe1_dT; + here->B3SOIPDcdsb = (Cgg + Cgd + Cgb + + Cbg + Cbd + Cbb + + Csg + Csd + Csb) + Ce1b; + } /* End of if capMod == 2 */ + + else if (model->B3SOIPDcapMod == 3) + { + dVgsteff_dVb /= dVbseff_dVb; + + if (selfheat) + { + Vfbzb = Vthzb - phi - pParam->B3SOIPDk1eff * sqrtPhi + + pParam->B3SOIPDdelvt; + dVfbzb_dT = dVthzb_dT; + } + else + { + Vfbzb = pParam->B3SOIPDvfbzb + pParam->B3SOIPDdelvt; + dVfbzb_dT = 0; + } + + V3 = Vfbzb - Vgs_eff + Vbseff - DELTA_3; + if (Vfbzb <= 0.0) + { + T0 = sqrt (V3 * V3 - 4.0 * DELTA_3 * Vfbzb); + T2 = -DELTA_3 / T0; + } + else + { + T0 = sqrt (V3 * V3 + 4.0 * DELTA_3 * Vfbzb); + T2 = DELTA_3 / T0; + } + + T1 = 0.5 * (1.0 + V3 / T0); + Vfbeff = Vfbzb - 0.5 * (V3 + T0); + dVfbeff_dVg = T1 * dVgs_eff_dVg; + dVfbeff_dVb = -T1; + if (selfheat) + dVfbeff_dT = (1.0 - T1 - T2) * dVfbzb_dT; + else + dVfbeff_dT = 0.0; + + Cox = model->B3SOIPDcox; + Tox = 1.0e8 * model->B3SOIPDtox; + T0 = (Vgs_eff - Vbseff - Vfbzb) / Tox; + dT0_dVg = dVgs_eff_dVg / Tox; + dT0_dVb = -1.0 / Tox; + + tmp = T0 * pParam->B3SOIPDacde; + if ((-EXPL_THRESHOLD < tmp) && (tmp < EXPL_THRESHOLD)) + { + Tcen = pParam->B3SOIPDldeb * exp (tmp); + dTcen_dVg = pParam->B3SOIPDacde * Tcen; + dTcen_dVb = dTcen_dVg * dT0_dVb; + dTcen_dVg *= dT0_dVg; + if (selfheat) + dTcen_dT = + -Tcen * pParam->B3SOIPDacde * dVfbzb_dT / Tox; + else + dTcen_dT = 0; + } + else if (tmp <= -EXPL_THRESHOLD) + { + Tcen = pParam->B3SOIPDldeb * MIN_EXPL; + dTcen_dVg = dTcen_dVb = dTcen_dT = 0.0; + } + else + { + Tcen = pParam->B3SOIPDldeb * MAX_EXPL; + dTcen_dVg = dTcen_dVb = dTcen_dT = 0.0; + } + + LINK = 1.0e-3 * model->B3SOIPDtox; + V3 = pParam->B3SOIPDldeb - Tcen - LINK; + V4 = sqrt (V3 * V3 + 4.0 * LINK * pParam->B3SOIPDldeb); + Tcen = pParam->B3SOIPDldeb - 0.5 * (V3 + V4); + T1 = 0.5 * (1.0 + V3 / V4); + dTcen_dVg *= T1; + dTcen_dVb *= T1; + if (selfheat) + dTcen_dT *= T1; + else + dTcen_dT = 0; + + Ccen = EPSSI / Tcen; + T2 = Cox / (Cox + Ccen); + Coxeff = T2 * Ccen; + T3 = -Ccen / Tcen; + dCoxeff_dVg = T2 * T2 * T3; + dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb; + dCoxeff_dVg *= dTcen_dVg; + if (selfheat) + dCoxeff_dT = T3 * dTcen_dT * (T2 - Coxeff / (Cox + Ccen)); + else + dCoxeff_dT = 0; + CoxWLcenb = CoxWLb * Coxeff / Cox; + if (selfheat) + dCoxWLcenb_dT = CoxWLb * dCoxeff_dT / Cox; + else + dCoxWLcenb_dT = 0; + + Qac0 = CoxWLcenb * (Vfbeff - Vfbzb); + QovCox = Qac0 / Coxeff; + dQac0_dVg = CoxWLcenb * dVfbeff_dVg + QovCox * dCoxeff_dVg; + dQac0_dVb = CoxWLcenb * dVfbeff_dVb + QovCox * dCoxeff_dVb; + if (selfheat) + dQac0_dT = CoxWLcenb * (dVfbeff_dT - dVfbzb_dT) + + dCoxWLcenb_dT * (Vfbeff - Vfbzb); + else + dQac0_dT = 0.0; + + T0 = 0.5 * pParam->B3SOIPDk1eff; + T3 = Vgs_eff - Vfbeff - Vbseff - Vgsteff; + if (pParam->B3SOIPDk1eff == 0.0) + { + T1 = 0.0; + T2 = 0.0; + } + else if (T3 < 0.0) + { + T1 = T0 + T3 / pParam->B3SOIPDk1eff; + T2 = CoxWLcenb; + } + else + { + T1 = sqrt (T0 * T0 + T3); + T2 = CoxWLcenb * T0 / T1; + } + + Qsub0 = CoxWLcenb * pParam->B3SOIPDk1eff * (T1 - T0); + QovCox = Qsub0 / Coxeff; + dQsub0_dVg = + T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg) + + QovCox * dCoxeff_dVg; + dQsub0_dVd = -T2 * dVgsteff_dVd; + dQsub0_dVb = -T2 * (dVfbeff_dVb + 1 + dVgsteff_dVb) + + QovCox * dCoxeff_dVb; + if (selfheat) + dQsub0_dT = -T2 * (dVfbeff_dT + dVgsteff_dT) + + dCoxWLcenb_dT * pParam->B3SOIPDk1eff * (T1 - T0); + else + dQsub0_dT = 0.0; + + /* Gate-bias dependent delta Phis begins */ + if (pParam->B3SOIPDk1eff <= 0.0) + { + Denomi = 0.25 * pParam->B3SOIPDmoin * Vtm; + T0 = 0.5 * pParam->B3SOIPDsqrtPhi; + } + else + { + Denomi = pParam->B3SOIPDmoin * Vtm + * pParam->B3SOIPDk1eff * pParam->B3SOIPDk1eff; + T0 = pParam->B3SOIPDk1eff * pParam->B3SOIPDsqrtPhi; + } + T1 = 2.0 * T0 + Vgsteff; + + DeltaPhi = Vtm * log (1.0 + T1 * Vgsteff / Denomi); + dDeltaPhi_dVg = + 2.0 * Vtm * (T1 - T0) / (Denomi + T1 * Vgsteff); + dDeltaPhi_dVd = dDeltaPhi_dVg * dVgsteff_dVd; + dDeltaPhi_dVb = dDeltaPhi_dVg * dVgsteff_dVb; + /* End of delta Phis */ + + T3 = 4.0 * (Vth - Vfbzb - phi); + Tox += Tox; + if ((T0 = (Vgsteff + T3) / Tox) > 1e-20) + { + tmp = exp (0.7 * log (T0)); + T1 = 1.0 + tmp; + T2 = 0.7 * tmp / (T0 * Tox); + Tcen = 1.9e-9 / T1; + dTcen_dVg = -1.9e-9 * T2 / T1 / T1; + dTcen_dVd = dTcen_dVg * (4.0 * dVth_dVd + dVgsteff_dVd); + dTcen_dVb = dTcen_dVg * (4.0 * dVth_dVb + dVgsteff_dVb); + dTcen_dVg *= dVgsteff_dVg; + if (selfheat) + dTcen_dT = -Tcen * T2 / T1 + * (4.0 * (dVth_dT - dVfbzb_dT) + dVgsteff_dT); + else + dTcen_dT = 0; + } + else + { + T0 = 1e-20; + tmp = exp (0.7 * log (T0)); + T1 = 1.0 + tmp; + T2 = 0.7 * tmp / (T0 * Tox); + Tcen = 1.9e-9 / T1; + dTcen_dVg = 0; + dTcen_dVd = 0; + dTcen_dVb = 0; + dTcen_dT = 0; + } + + Ccen = EPSSI / Tcen; + T0 = Cox / (Cox + Ccen); + Coxeff = T0 * Ccen; + T1 = -Ccen / Tcen; + dCoxeff_dVg = T0 * T0 * T1; + dCoxeff_dVd = dCoxeff_dVg * dTcen_dVd; + dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb; + dCoxeff_dVg *= dTcen_dVg; + if (selfheat) + dCoxeff_dT = T1 * dTcen_dT * (T0 - Coxeff / (Cox + Ccen)); + else + dCoxeff_dT = 0; + CoxWLcen = CoxWL * Coxeff / Cox; + CoxWLcenb = CoxWLb * Coxeff / Cox; + + AbulkCV = Abulk0 * pParam->B3SOIPDabulkCVfactor; + dAbulkCV_dVb = pParam->B3SOIPDabulkCVfactor * dAbulk0_dVb; + VdsatCV = (Vgsteff - DeltaPhi) / AbulkCV; + V4 = VdsatCV - Vds - DELTA_4; + T0 = sqrt (V4 * V4 + 4.0 * DELTA_4 * VdsatCV); + VdseffCV = VdsatCV - 0.5 * (V4 + T0); + T1 = 0.5 * (1.0 + V4 / T0); + T2 = DELTA_4 / T0; + T3 = (1.0 - T1 - T2) / AbulkCV; + T4 = T3 * (1.0 - dDeltaPhi_dVg); + dVdseffCV_dVg = T4; + dVdseffCV_dVd = T1; + dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb; + + T0 = AbulkCV * VdseffCV; + T1 = Vgsteff - DeltaPhi; + T2 = 12.0 * (T1 - 0.5 * T0 + 1.0e-20); + T3 = T0 / T2; + T4 = 1.0 - 12.0 * T3 * T3; + T5 = + AbulkCV * (6.0 * T0 * (4.0 * T1 - T0) / (T2 * T2) - 0.5); + T6 = T5 * VdseffCV / AbulkCV; + + qinv = qgate = qinoi = CoxWLcen * (T1 - T0 * (0.5 - T3)); + QovCox = qgate / Coxeff; + Cgg1 = CoxWLcen * (T4 * (1.0 - dDeltaPhi_dVg) + + T5 * dVdseffCV_dVg); + Cgd1 = CoxWLcen * T5 * dVdseffCV_dVd + Cgg1 + * dVgsteff_dVd + QovCox * dCoxeff_dVd; + Cgb1 = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + + Cgg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb; + Cgg1 = Cgg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg; + + T7 = 1.0 - AbulkCV; + T8 = T2 * T2; + T9 = 12.0 * T7 * T0 * T0 / (T8 * AbulkCV); + T10 = T9 * (1.0 - dDeltaPhi_dVg); + T11 = -T7 * T5 / AbulkCV; + T12 = -(T9 * T1 / AbulkCV + VdseffCV * (0.5 - T0 / T2)); + + qbulk = + CoxWLcenb * T7 * (0.5 * VdseffCV - T0 * VdseffCV / T2); + QovCox = qbulk / Coxeff; + Cbg1 = CoxWLcenb * (T10 + T11 * dVdseffCV_dVg); + Cbd1 = CoxWLcenb * T11 * dVdseffCV_dVd + Cbg1 + * dVgsteff_dVd + QovCox * dCoxeff_dVd; + Cbb1 = + CoxWLcenb * (T11 * dVdseffCV_dVb + T12 * dAbulkCV_dVb) + + Cbg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb; + Cbg1 = Cbg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg; + + if (model->B3SOIPDxpart > 0.5) + { /* 0/100 partition */ + qsrc = -CoxWLcen * (T1 / 2.0 + T0 / 4.0 + - 0.5 * T0 * T0 / T2); + QovCox = qsrc / Coxeff; + T2 += T2; + T3 = T2 * T2; + T7 = -(0.25 - 12.0 * T0 * (4.0 * T1 - T0) / T3); + T4 = + -(0.5 + 24.0 * T0 * T0 / T3) * (1.0 - dDeltaPhi_dVg); + T5 = T7 * AbulkCV; + T6 = T7 * VdseffCV; + + Csg = CoxWLcen * (T4 + T5 * dVdseffCV_dVg); + Csd = CoxWLcen * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd + + QovCox * dCoxeff_dVd; + Csb = + CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + + Csg * dVgsteff_dVb + QovCox * dCoxeff_dVb; + Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg; + } + else if (model->B3SOIPDxpart < 0.5) + { /* 40/60 partition */ + T2 = T2 / 12.0; + T3 = 0.5 * CoxWLcen / (T2 * T2); + T4 = T1 * (2.0 * T0 * T0 / 3.0 + T1 * (T1 - 4.0 + * T0 / 3.0)) - + 2.0 * T0 * T0 * T0 / 15.0; + qsrc = -T3 * T4; + QovCox = qsrc / Coxeff; + T8 = 4.0 / 3.0 * T1 * (T1 - T0) + 0.4 * T0 * T0; + T5 = -2.0 * qsrc / T2 - T3 * (T1 * (3.0 * T1 - 8.0 + * T0 / 3.0) + + 2.0 * T0 * T0 / 3.0); + T6 = AbulkCV * (qsrc / T2 + T3 * T8); + T7 = T6 * VdseffCV / AbulkCV; + + Csg = T5 * (1.0 - dDeltaPhi_dVg) + T6 * dVdseffCV_dVg; + Csd = Csg * dVgsteff_dVd + T6 * dVdseffCV_dVd + + QovCox * dCoxeff_dVd; + Csb = Csg * dVgsteff_dVb + T6 * dVdseffCV_dVb + + T7 * dAbulkCV_dVb + QovCox * dCoxeff_dVb; + Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg; + } + else + { /* 50/50 partition */ + qsrc = -0.5 * qgate; + Csg = -0.5 * Cgg1; + Csd = -0.5 * Cgd1; + Csb = -0.5 * Cgb1; + } + + /* Backgate charge */ + CboxWL = pParam->B3SOIPDkb1 * model->B3SOIPDfbody * Cbox + * (pParam->B3SOIPDweffCV / here->B3SOIPDnseg + * pParam->B3SOIPDleffCVbg + here->B3SOIPDaebcp); + Qe1 = CboxWL * (Vesfb - Vbs); + Ce1b = dQe1_dVb = -CboxWL; + Ce1e = dQe1_dVe = CboxWL; + if (selfheat) + Ce1T = dQe1_dT = -CboxWL * dvfbb_dT; + else + Ce1T = dQe1_dT = 0.0; + + qgate += Qac0 + Qsub0 - qbulk; + qbody = qbulk - Qac0 - Qsub0 - Qe1; + qsub = Qe1; + qdrn = -(qgate + qbody + qsub + qsrc); + + Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg; + Cbd = Cbd1 - dQsub0_dVd; + Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb - Ce1b / dVbseff_dVb; + if (selfheat) + CbT = Cbg1 * dVgsteff_dT - dQac0_dT - dQsub0_dT - dQe1_dT; + else + CbT = 0.0; + + Cgg = Cgg1 - Cbg; + Cgd = Cgd1 - Cbd; + Cgb = Cgb1 - Cbb - Ce1b / dVbseff_dVb; + if (selfheat) + CgT = Cgg1 * dVgsteff_dT + dQac0_dT + dQsub0_dT; + else + CgT = 0.0; + + Cgb *= dVbseff_dVb; + Cbb *= dVbseff_dVb; + Csb *= dVbseff_dVb; + if (selfheat) + CsT = Csg * dVgsteff_dT; + else + CsT = 0.0; + + here->B3SOIPDcggb = Cgg; + here->B3SOIPDcgsb = -(Cgg + Cgd + Cgb); + here->B3SOIPDcgdb = Cgd; + here->B3SOIPDcgT = CgT; + + here->B3SOIPDcbgb = Cbg; + here->B3SOIPDcbsb = -(Cbg + Cbd + Cbb) + Ce1e; + here->B3SOIPDcbdb = Cbd; + here->B3SOIPDcbeb = -Ce1e; + here->B3SOIPDcbT = CbT; + + here->B3SOIPDceT = Ce1T; + here->B3SOIPDceeb = Ce1e; + + here->B3SOIPDcdgb = -(Cgg + Cbg + Csg); + here->B3SOIPDcddb = -(Cgd + Cbd + Csd); + here->B3SOIPDcdeb = 0; + here->B3SOIPDcdT = -(CgT + CbT + CsT) - Ce1T; + here->B3SOIPDcdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + + Csg + Csd + Csb) + Ce1b; + here->B3SOIPDqinv = -qinoi; + + } /* End of if capMod ==3 */ + } + + + finished: /* returning Values to Calling Routine */ + /* + * COMPUTE EQUIVALENT DRAIN CURRENT SOURCE + */ + if (ChargeComputationNeeded) + { + /* Intrinsic S/D junction charge */ + PhiBSWG = model->B3SOIPDGatesidewallJctPotential; + dPhiBSWG_dT = -model->B3SOIPDtpbswg; + PhiBSWG += dPhiBSWG_dT * (Temp - model->B3SOIPDtnom); + MJSWG = model->B3SOIPDbodyJctGateSideGradingCoeff; + + cjsbs = model->B3SOIPDunitLengthGateSidewallJctCap + * wdiosCV * model->B3SOIPDtsi / 1e-7; + dcjsbs_dT = cjsbs * model->B3SOIPDtcjswg; + cjsbs += dcjsbs_dT * (Temp - model->B3SOIPDtnom); + + cjdbs = model->B3SOIPDunitLengthGateSidewallJctCap + * wdiodCV * model->B3SOIPDtsi / 1e-7; + dcjdbs_dT = cjdbs * model->B3SOIPDtcjswg; + cjdbs += dcjdbs_dT * (Temp - model->B3SOIPDtnom); + + DioMax = 0.9 * (PhiBSWG); + + arg = 1.0 - (Vbs > DioMax ? DioMax : Vbs) / PhiBSWG; + + if (selfheat) + darg_dT = (1 - arg) / PhiBSWG * dPhiBSWG_dT; + + if (MJSWG == 0.5) + { + dT3_dVb = 1.0 / sqrt (arg); + + if (selfheat) + ddT3_dVb_dT = -0.5 * dT3_dVb / arg * darg_dT; + } + else + { + dT3_dVb = exp (-MJSWG * log (arg)); + + if (selfheat) + ddT3_dVb_dT = -MJSWG * dT3_dVb / arg * darg_dT; + } + T3 = (1.0 - arg * dT3_dVb) * PhiBSWG / (1.0 - MJSWG); + + if (selfheat) + dT3_dT = (1.0 - arg * dT3_dVb) * dPhiBSWG_dT / (1.0 - MJSWG) + - (arg * ddT3_dVb_dT + darg_dT * dT3_dVb) * PhiBSWG / (1.0 - + MJSWG); + + if (Vbs > DioMax) + T3 += dT3_dVb * (Vbs - DioMax); + + qjs = cjsbs * T3 + model->B3SOIPDtt * Ibsdif; + gcjsbs = cjsbs * dT3_dVb + model->B3SOIPDtt * dIbsdif_dVb; + + if (selfheat) + gcjsT = + model->B3SOIPDtt * dIbsdif_dT + dcjsbs_dT * T3 + + dT3_dT * cjsbs; + else + gcjsT = 0.0; + + + arg = 1.0 - (Vbd > DioMax ? DioMax : Vbd) / PhiBSWG; + + if (selfheat) + darg_dT = (1 - arg) / PhiBSWG * dPhiBSWG_dT; + + if (MJSWG == 0.5) + { + dT3_dVb = 1.0 / sqrt (arg); + + if (selfheat) + ddT3_dVb_dT = -0.5 * dT3_dVb / arg * darg_dT; + } + else + { + dT3_dVb = exp (-MJSWG * log (arg)); + + if (selfheat) + ddT3_dVb_dT = -MJSWG * dT3_dVb / arg * darg_dT; + } + T3 = (1.0 - arg * dT3_dVb) * PhiBSWG / (1.0 - MJSWG); + + if (selfheat) + dT3_dT = (1.0 - arg * dT3_dVb) * dPhiBSWG_dT / (1.0 - MJSWG) + - (arg * ddT3_dVb_dT + darg_dT * dT3_dVb) * PhiBSWG / (1.0 - + MJSWG); + + if (Vbd > DioMax) + T3 += dT3_dVb * (Vbd - DioMax); + + dT3_dVd = -dT3_dVb; + + qjd = cjdbs * T3 + model->B3SOIPDtt * Ibddif; + gcjdbs = cjdbs * dT3_dVb + model->B3SOIPDtt * dIbddif_dVb; + gcjdds = cjdbs * dT3_dVd + model->B3SOIPDtt * dIbddif_dVd; + + if (selfheat) + gcjdT = + model->B3SOIPDtt * dIbddif_dT + dcjdbs_dT * T3 + + dT3_dT * cjdbs; + else + gcjdT = 0.0; + + + qdrn -= qjd; + qbody += (qjs + qjd); + qsrc = -(qgate + qbody + qdrn + qsub); + + /* Update the conductance */ + here->B3SOIPDcddb -= gcjdds; + here->B3SOIPDcdT -= gcjdT; + here->B3SOIPDcdsb += gcjdds + gcjdbs; + + here->B3SOIPDcbdb += (gcjdds); + here->B3SOIPDcbT += (gcjdT + gcjsT); + here->B3SOIPDcbsb -= (gcjdds + gcjdbs + gcjsbs); + + + /* Extrinsic Bottom S/D to substrate charge */ + T10 = -model->B3SOIPDtype * ves; + /* T10 is vse without type conversion */ + T11 = model->B3SOIPDtype * (vds - ves); + /* T11 is vde without type conversion */ + + if (model->B3SOIPDcsdmin != 0.0) + { + if (((pParam->B3SOIPDnsub > 0) && (model->B3SOIPDtype > 0)) + || ((pParam->B3SOIPDnsub < 0) + && (model->B3SOIPDtype < 0))) + { + if (T10 < pParam->B3SOIPDvsdfb) + { + here->B3SOIPDqse = + here->B3SOIPDcsbox * (T10 - pParam->B3SOIPDvsdfb); + here->B3SOIPDgcse = here->B3SOIPDcsbox; + } + else if (T10 < pParam->B3SOIPDsdt1) + { + T0 = T10 - pParam->B3SOIPDvsdfb; + T1 = T0 * T0; + here->B3SOIPDqse = T0 * (here->B3SOIPDcsbox - + pParam->B3SOIPDst2 / 3 * + T1); + here->B3SOIPDgcse = + here->B3SOIPDcsbox - pParam->B3SOIPDst2 * T1; + } + else if (T10 < pParam->B3SOIPDvsdth) + { + T0 = T10 - pParam->B3SOIPDvsdth; + T1 = T0 * T0; + here->B3SOIPDqse = + here->B3SOIPDcsmin * T10 + here->B3SOIPDst4 + + pParam->B3SOIPDst3 / 3 * T0 * T1; + here->B3SOIPDgcse = + here->B3SOIPDcsmin + pParam->B3SOIPDst3 * T1; + } + else + { + here->B3SOIPDqse = + here->B3SOIPDcsmin * T10 + here->B3SOIPDst4; + here->B3SOIPDgcse = here->B3SOIPDcsmin; + } + } + else + { + if (T10 < pParam->B3SOIPDvsdth) + { + here->B3SOIPDqse = + here->B3SOIPDcsmin * (T10 - pParam->B3SOIPDvsdth); + here->B3SOIPDgcse = here->B3SOIPDcsmin; + } + else if (T10 < pParam->B3SOIPDsdt1) + { + T0 = T10 - pParam->B3SOIPDvsdth; + T1 = T0 * T0; + here->B3SOIPDqse = + T0 * (here->B3SOIPDcsmin - + pParam->B3SOIPDst2 / 3 * T1); + here->B3SOIPDgcse = + here->B3SOIPDcsmin - pParam->B3SOIPDst2 * T1; + } + else if (T10 < pParam->B3SOIPDvsdfb) + { + T0 = T10 - pParam->B3SOIPDvsdfb; + T1 = T0 * T0; + here->B3SOIPDqse = + here->B3SOIPDcsbox * T10 + here->B3SOIPDst4 + + pParam->B3SOIPDst3 / 3 * T0 * T1; + here->B3SOIPDgcse = + here->B3SOIPDcsbox + pParam->B3SOIPDst3 * T1; + } + else + { + here->B3SOIPDqse = + here->B3SOIPDcsbox * T10 + here->B3SOIPDst4; + here->B3SOIPDgcse = here->B3SOIPDcsbox; + } + } + + if (((pParam->B3SOIPDnsub > 0) && (model->B3SOIPDtype > 0)) + || ((pParam->B3SOIPDnsub < 0) + && (model->B3SOIPDtype < 0))) + { + if (T11 < pParam->B3SOIPDvsdfb) + { + here->B3SOIPDqde = + here->B3SOIPDcdbox * (T11 - pParam->B3SOIPDvsdfb); + here->B3SOIPDgcde = here->B3SOIPDcdbox; + } + else if (T11 < pParam->B3SOIPDsdt1) + { + T0 = T11 - pParam->B3SOIPDvsdfb; + T1 = T0 * T0; + here->B3SOIPDqde = + T0 * (here->B3SOIPDcdbox - + pParam->B3SOIPDdt2 / 3 * T1); + here->B3SOIPDgcde = + here->B3SOIPDcdbox - pParam->B3SOIPDdt2 * T1; + } + else if (T11 < pParam->B3SOIPDvsdth) + { + T0 = T11 - pParam->B3SOIPDvsdth; + T1 = T0 * T0; + here->B3SOIPDqde = + here->B3SOIPDcdmin * T11 + here->B3SOIPDdt4 + + pParam->B3SOIPDdt3 / 3 * T0 * T1; + here->B3SOIPDgcde = + here->B3SOIPDcdmin + pParam->B3SOIPDdt3 * T1; + } + else + { + here->B3SOIPDqde = + here->B3SOIPDcdmin * T11 + here->B3SOIPDdt4; + here->B3SOIPDgcde = here->B3SOIPDcdmin; + } + } + else + { + if (T11 < pParam->B3SOIPDvsdth) + { + here->B3SOIPDqde = + here->B3SOIPDcdmin * (T11 - pParam->B3SOIPDvsdth); + here->B3SOIPDgcde = here->B3SOIPDcdmin; + } + else if (T11 < pParam->B3SOIPDsdt1) + { + T0 = T11 - pParam->B3SOIPDvsdth; + T1 = T0 * T0; + here->B3SOIPDqde = + T0 * (here->B3SOIPDcdmin - + pParam->B3SOIPDdt2 / 3 * T1); + here->B3SOIPDgcde = + here->B3SOIPDcdmin - pParam->B3SOIPDdt2 * T1; + } + else if (T11 < pParam->B3SOIPDvsdfb) + { + T0 = T11 - pParam->B3SOIPDvsdfb; + T1 = T0 * T0; + here->B3SOIPDqde = + here->B3SOIPDcdbox * T11 + here->B3SOIPDdt4 + + pParam->B3SOIPDdt3 / 3 * T0 * T1; + here->B3SOIPDgcde = + here->B3SOIPDcdbox + pParam->B3SOIPDdt3 * T1; + } + else + { + here->B3SOIPDqde = + here->B3SOIPDcdbox * T11 + here->B3SOIPDdt4; + here->B3SOIPDgcde = here->B3SOIPDcdbox; + } + } + } + else + { + here->B3SOIPDqse = here->B3SOIPDcsbox * T10; + here->B3SOIPDgcse = here->B3SOIPDcsbox; + here->B3SOIPDqde = here->B3SOIPDcdbox * T11; + here->B3SOIPDgcde = here->B3SOIPDcdbox; + } + + /* Extrinsic : Sidewall fringing S/D charge */ + here->B3SOIPDqse += pParam->B3SOIPDcsesw * T10; + here->B3SOIPDgcse += pParam->B3SOIPDcsesw; + here->B3SOIPDqde += pParam->B3SOIPDcdesw * T11; + here->B3SOIPDgcde += pParam->B3SOIPDcdesw; + + /* All charge are mutliplied with type at the end, but qse and qde + have true polarity => so pre-mutliplied with type */ + here->B3SOIPDqse *= model->B3SOIPDtype; + here->B3SOIPDqde *= model->B3SOIPDtype; + } + + + here->B3SOIPDcbb = Cbb; + here->B3SOIPDcbd = Cbd; + here->B3SOIPDcbg = Cbg; + here->B3SOIPDqbf = -Qsub0 - Qac0; + here->B3SOIPDqjs = qjs; + here->B3SOIPDqjd = qjd; + + /* + * check convergence + */ + if ((here->B3SOIPDoff == 0) || (!(ckt->CKTmode & MODEINITFIX))) + { + if (Check == 1) + { + ckt->CKTnoncon++; + } + } + + *(ckt->CKTstate0 + here->B3SOIPDvg) = vg; + *(ckt->CKTstate0 + here->B3SOIPDvd) = vd; + *(ckt->CKTstate0 + here->B3SOIPDvs) = vs; + *(ckt->CKTstate0 + here->B3SOIPDvp) = vp; + *(ckt->CKTstate0 + here->B3SOIPDve) = ve; + + *(ckt->CKTstate0 + here->B3SOIPDvbs) = vbs; + *(ckt->CKTstate0 + here->B3SOIPDvbd) = vbd; + *(ckt->CKTstate0 + here->B3SOIPDvgs) = vgs; + *(ckt->CKTstate0 + here->B3SOIPDvds) = vds; + *(ckt->CKTstate0 + here->B3SOIPDves) = ves; + *(ckt->CKTstate0 + here->B3SOIPDvps) = vps; + *(ckt->CKTstate0 + here->B3SOIPDdeltemp) = delTemp; + + /* bulk and channel charge plus overlaps */ + + if (!ChargeComputationNeeded) + goto line850; + + line755: + ag0 = ckt->CKTag[0]; + + T0 = vgd + DELTA_1; + T1 = sqrt (T0 * T0 + 4.0 * DELTA_1); + T2 = 0.5 * (T0 - T1); + + T3 = wdiodCV * pParam->B3SOIPDcgdl; + T4 = sqrt (1.0 - 4.0 * T2 / pParam->B3SOIPDckappa); + cgdo = pParam->B3SOIPDcgdo + T3 - T3 * (1.0 - 1.0 / T4) + * (0.5 - 0.5 * T0 / T1); + qgdo = (pParam->B3SOIPDcgdo + T3) * vgd - T3 * (T2 + + + 0.5 * + pParam-> + B3SOIPDckappa * + (T4 - 1.0)); + + T0 = vgs + DELTA_1; + T1 = sqrt (T0 * T0 + 4.0 * DELTA_1); + T2 = 0.5 * (T0 - T1); + T3 = wdiosCV * pParam->B3SOIPDcgsl; + T4 = sqrt (1.0 - 4.0 * T2 / pParam->B3SOIPDckappa); + cgso = pParam->B3SOIPDcgso + T3 - T3 * (1.0 - 1.0 / T4) + * (0.5 - 0.5 * T0 / T1); + qgso = (pParam->B3SOIPDcgso + T3) * vgs - T3 * (T2 + + + 0.5 * + pParam-> + B3SOIPDckappa * + (T4 - 1.0)); + + + + if (here->B3SOIPDdebugMod < 0) + goto line850; + + + if (here->B3SOIPDmode > 0) + { + gcdgb = (here->B3SOIPDcdgb - cgdo) * ag0; + gcddb = (here->B3SOIPDcddb + cgdo + here->B3SOIPDgcde) * ag0; + gcdsb = here->B3SOIPDcdsb * ag0; + gcdeb = (here->B3SOIPDcdeb - here->B3SOIPDgcde) * ag0; + gcdT = model->B3SOIPDtype * here->B3SOIPDcdT * ag0; + + gcsgb = + -(here->B3SOIPDcggb + here->B3SOIPDcbgb + here->B3SOIPDcdgb + + cgso) * ag0; + gcsdb = + -(here->B3SOIPDcgdb + here->B3SOIPDcbdb + + here->B3SOIPDcddb) * ag0; + gcssb = + (cgso + here->B3SOIPDgcse - + (here->B3SOIPDcgsb + here->B3SOIPDcbsb + + here->B3SOIPDcdsb)) * ag0; + gcseb = + -(here->B3SOIPDgcse + here->B3SOIPDcbeb + here->B3SOIPDcdeb + + here->B3SOIPDceeb) * ag0; + gcsT = + -model->B3SOIPDtype * (here->B3SOIPDcgT + here->B3SOIPDcbT + + here->B3SOIPDcdT + + here->B3SOIPDceT) * ag0; + + gcggb = + (here->B3SOIPDcggb + cgdo + cgso + pParam->B3SOIPDcgeo) * ag0; + gcgdb = (here->B3SOIPDcgdb - cgdo) * ag0; + gcgsb = (here->B3SOIPDcgsb - cgso) * ag0; + gcgeb = (-pParam->B3SOIPDcgeo) * ag0; + gcgT = model->B3SOIPDtype * here->B3SOIPDcgT * ag0; + + gcbgb = here->B3SOIPDcbgb * ag0; + gcbdb = here->B3SOIPDcbdb * ag0; + gcbsb = here->B3SOIPDcbsb * ag0; + gcbeb = here->B3SOIPDcbeb * ag0; + gcbT = model->B3SOIPDtype * here->B3SOIPDcbT * ag0; + + gcegb = (-pParam->B3SOIPDcgeo) * ag0; + gcedb = (-here->B3SOIPDgcde) * ag0; + gcesb = (-here->B3SOIPDgcse) * ag0; + gceeb = (here->B3SOIPDgcse + here->B3SOIPDgcde + + here->B3SOIPDceeb + pParam->B3SOIPDcgeo) * ag0; + + gceT = model->B3SOIPDtype * here->B3SOIPDceT * ag0; + + gcTt = pParam->B3SOIPDcth * ag0; + + sxpart = 0.6; + dxpart = 0.4; + + /* Lump the overlap capacitance and S/D parasitics */ + qgd = qgdo; + qgs = qgso; + qge = pParam->B3SOIPDcgeo * vge; + qgate += qgd + qgs + qge; + qdrn += here->B3SOIPDqde - qgd; + qsub -= qge + here->B3SOIPDqse + here->B3SOIPDqde; + qsrc = -(qgate + qbody + qdrn + qsub); + } + else + { + gcsgb = (here->B3SOIPDcdgb - cgso) * ag0; + gcssb = (here->B3SOIPDcddb + cgso + here->B3SOIPDgcse) * ag0; + gcsdb = here->B3SOIPDcdsb * ag0; + gcseb = (here->B3SOIPDcdeb - here->B3SOIPDgcse) * ag0; + gcsT = model->B3SOIPDtype * here->B3SOIPDcdT * ag0; + + gcdgb = + -(here->B3SOIPDcggb + here->B3SOIPDcbgb + here->B3SOIPDcdgb + + cgdo) * ag0; + gcdsb = + -(here->B3SOIPDcgdb + here->B3SOIPDcbdb + + here->B3SOIPDcddb) * ag0; + gcddb = + (cgdo + here->B3SOIPDgcde - + (here->B3SOIPDcgsb + here->B3SOIPDcbsb + + here->B3SOIPDcdsb)) * ag0; + gcdeb = + -(here->B3SOIPDgcde + here->B3SOIPDcbeb + here->B3SOIPDcdeb + + here->B3SOIPDceeb) * ag0; + gcdT = + -model->B3SOIPDtype * (here->B3SOIPDcgT + here->B3SOIPDcbT + + here->B3SOIPDcdT + + here->B3SOIPDceT) * ag0; + + gcggb = + (here->B3SOIPDcggb + cgdo + cgso + pParam->B3SOIPDcgeo) * ag0; + gcgsb = (here->B3SOIPDcgdb - cgso) * ag0; + gcgdb = (here->B3SOIPDcgsb - cgdo) * ag0; + gcgeb = (-pParam->B3SOIPDcgeo) * ag0; + gcgT = model->B3SOIPDtype * here->B3SOIPDcgT * ag0; + + gcbgb = here->B3SOIPDcbgb * ag0; + gcbsb = here->B3SOIPDcbdb * ag0; + gcbdb = here->B3SOIPDcbsb * ag0; + gcbeb = here->B3SOIPDcbeb * ag0; + gcbT = model->B3SOIPDtype * here->B3SOIPDcbT * ag0; + + gcegb = (-pParam->B3SOIPDcgeo) * ag0; + gcesb = (-here->B3SOIPDgcse) * ag0; + gcedb = (-here->B3SOIPDgcde) * ag0; + gceeb = (here->B3SOIPDceeb + pParam->B3SOIPDcgeo + + here->B3SOIPDgcse + here->B3SOIPDgcde) * ag0; + gceT = model->B3SOIPDtype * here->B3SOIPDceT * ag0; + + gcTt = pParam->B3SOIPDcth * ag0; + + dxpart = 0.6; + sxpart = 0.4; + + /* Lump the overlap capacitance */ + qgd = qgdo; + qgs = qgso; + qge = pParam->B3SOIPDcgeo * vge; + qgate += qgd + qgs + qge; + qsrc = qdrn - qgs + here->B3SOIPDqse; + qsub -= qge + here->B3SOIPDqse + here->B3SOIPDqde; + qdrn = -(qgate + qbody + qsrc + qsub); + } + + here->B3SOIPDcgdo = cgdo; + here->B3SOIPDcgso = cgso; + + if (ByPass) + goto line860; + + *(ckt->CKTstate0 + here->B3SOIPDqe) = qsub; + *(ckt->CKTstate0 + here->B3SOIPDqg) = qgate; + *(ckt->CKTstate0 + here->B3SOIPDqd) = qdrn; + *(ckt->CKTstate0 + here->B3SOIPDqb) = qbody; + if ((model->B3SOIPDshMod == 1) && (here->B3SOIPDrth0 != 0.0)) + *(ckt->CKTstate0 + here->B3SOIPDqth) = + pParam->B3SOIPDcth * delTemp; + + + /* store small signal parameters */ + if (ckt->CKTmode & MODEINITSMSIG) + { + goto line1000; + } + if (!ChargeComputationNeeded) + goto line850; + + + if (ckt->CKTmode & MODEINITTRAN) + { + *(ckt->CKTstate1 + here->B3SOIPDqb) = + *(ckt->CKTstate0 + here->B3SOIPDqb); + *(ckt->CKTstate1 + here->B3SOIPDqg) = + *(ckt->CKTstate0 + here->B3SOIPDqg); + *(ckt->CKTstate1 + here->B3SOIPDqd) = + *(ckt->CKTstate0 + here->B3SOIPDqd); + *(ckt->CKTstate1 + here->B3SOIPDqe) = + *(ckt->CKTstate0 + here->B3SOIPDqe); + *(ckt->CKTstate1 + here->B3SOIPDqth) = + *(ckt->CKTstate0 + here->B3SOIPDqth); + } + + error = NIintegrate (ckt, &geq, &ceq, 0.0, here->B3SOIPDqb); + if (error) + return (error); + error = NIintegrate (ckt, &geq, &ceq, 0.0, here->B3SOIPDqg); + if (error) + return (error); + error = NIintegrate (ckt, &geq, &ceq, 0.0, here->B3SOIPDqd); + if (error) + return (error); + error = NIintegrate (ckt, &geq, &ceq, 0.0, here->B3SOIPDqe); + if (error) + return (error); + if ((model->B3SOIPDshMod == 1) && (here->B3SOIPDrth0 != 0.0)) + { + error = NIintegrate (ckt, &geq, &ceq, 0.0, here->B3SOIPDqth); + if (error) + return (error); + } + + goto line860; + + line850: + /* initialize to zero charge conductance and current */ + ceqqe = ceqqg = ceqqb = ceqqd = ceqqth = 0.0; + + gcdgb = gcddb = gcdsb = gcdeb = gcdT = 0.0; + gcsgb = gcsdb = gcssb = gcseb = gcsT = 0.0; + gcggb = gcgdb = gcgsb = gcgeb = gcgT = 0.0; + gcbgb = gcbdb = gcbsb = gcbeb = gcbT = 0.0; + gcegb = gcedb = gceeb = gcesb = gceT = 0.0; + gcTt = 0.0; + + sxpart = (1.0 - (dxpart = (here->B3SOIPDmode > 0) ? 0.4 : 0.6)); + + goto line900; + + line860: + /* evaluate equivalent charge current */ + + cqgate = *(ckt->CKTstate0 + here->B3SOIPDcqg); + cqbody = *(ckt->CKTstate0 + here->B3SOIPDcqb); + cqdrn = *(ckt->CKTstate0 + here->B3SOIPDcqd); + cqsub = *(ckt->CKTstate0 + here->B3SOIPDcqe); + cqtemp = *(ckt->CKTstate0 + here->B3SOIPDcqth); + + here->B3SOIPDcb += cqbody; + here->B3SOIPDcd += cqdrn; + + ceqqg = cqgate - gcggb * vgb + gcgdb * vbd + gcgsb * vbs + - gcgeb * veb - gcgT * delTemp; + ceqqb = cqbody - gcbgb * vgb + gcbdb * vbd + gcbsb * vbs + - gcbeb * veb - gcbT * delTemp; + ceqqd = cqdrn - gcdgb * vgb + gcddb * vbd + gcdsb * vbs + - gcdeb * veb - gcdT * delTemp; + ceqqe = cqsub - gcegb * vgb + gcedb * vbd + gcesb * vbs + - gceeb * veb - gceT * delTemp;; + ceqqth = cqtemp - gcTt * delTemp; + + if (ckt->CKTmode & MODEINITTRAN) + { + *(ckt->CKTstate1 + here->B3SOIPDcqe) = + *(ckt->CKTstate0 + here->B3SOIPDcqe); + *(ckt->CKTstate1 + here->B3SOIPDcqb) = + *(ckt->CKTstate0 + here->B3SOIPDcqb); + *(ckt->CKTstate1 + here->B3SOIPDcqg) = + *(ckt->CKTstate0 + here->B3SOIPDcqg); + *(ckt->CKTstate1 + here->B3SOIPDcqd) = + *(ckt->CKTstate0 + here->B3SOIPDcqd); + *(ckt->CKTstate1 + here->B3SOIPDcqth) = + *(ckt->CKTstate0 + here->B3SOIPDcqth); + } + + /* + * load current vector + */ + line900: + + if (here->B3SOIPDmode >= 0) + { + Gm = here->B3SOIPDgm; + Gmbs = here->B3SOIPDgmbs; + GmT = model->B3SOIPDtype * here->B3SOIPDgmT; + FwdSum = Gm + Gmbs; + RevSum = 0.0; + cdreq = + model->B3SOIPDtype * (here->B3SOIPDcdrain - + here->B3SOIPDgds * vds - Gm * vgs - + Gmbs * vbs - GmT * delTemp); + /* ceqbs now is compatible with cdreq, ie. going in is +ve */ + /* Equivalent current source from the diode */ + ceqbs = here->B3SOIPDcjs; + ceqbd = here->B3SOIPDcjd; + /* Current going in is +ve */ + ceqbody = -here->B3SOIPDcbody; + + + ceqgate = here->B3SOIPDcgate; + gigg = here->B3SOIPDgigg; + gigb = here->B3SOIPDgigb; + gigs = here->B3SOIPDgigs; + gigd = here->B3SOIPDgigd; + gigT = model->B3SOIPDtype * here->B3SOIPDgigT; + + ceqth = here->B3SOIPDcth; + ceqbodcon = here->B3SOIPDcbodcon; + + gbbg = -here->B3SOIPDgbgs; + gbbdp = -here->B3SOIPDgbds; + gbbb = -here->B3SOIPDgbbs; + gbbp = -here->B3SOIPDgbps; + gbbT = -model->B3SOIPDtype * here->B3SOIPDgbT; + gbbsp = -(gbbg + gbbdp + gbbb + gbbp); + + gddpg = -here->B3SOIPDgjdg; + gddpdp = -here->B3SOIPDgjdd; + gddpb = -here->B3SOIPDgjdb; + gddpT = -model->B3SOIPDtype * here->B3SOIPDgjdT; + gddpsp = -(gddpg + gddpdp + gddpb); + + gsspg = -here->B3SOIPDgjsg; + gsspdp = -here->B3SOIPDgjsd; + gsspb = -here->B3SOIPDgjsb; + gsspT = -model->B3SOIPDtype * here->B3SOIPDgjsT; + gsspsp = -(gsspg + gsspdp + gsspb); + + gppb = -here->B3SOIPDgbpbs; + gppp = -here->B3SOIPDgbpps; + gppT = -model->B3SOIPDtype * here->B3SOIPDgbpT; + + gTtg = here->B3SOIPDgtempg; + gTtb = here->B3SOIPDgtempb; + gTtdp = here->B3SOIPDgtempd; + gTtt = here->B3SOIPDgtempT; + gTtsp = -(gTtg + gTtb + gTtdp); + } + else + { + Gm = -here->B3SOIPDgm; + Gmbs = -here->B3SOIPDgmbs; + GmT = -model->B3SOIPDtype * here->B3SOIPDgmT; + FwdSum = 0.0; + RevSum = -(Gm + Gmbs); + cdreq = + -model->B3SOIPDtype * (here->B3SOIPDcdrain + + here->B3SOIPDgds * vds + Gm * vgd + + Gmbs * vbd + GmT * delTemp); + ceqbs = here->B3SOIPDcjd; + ceqbd = here->B3SOIPDcjs; + /* Current going in is +ve */ + ceqbody = -here->B3SOIPDcbody; + + + ceqgate = here->B3SOIPDcgate; + gigg = here->B3SOIPDgigg; + gigb = here->B3SOIPDgigb; + gigs = here->B3SOIPDgigd; + gigd = here->B3SOIPDgigs; + gigT = model->B3SOIPDtype * here->B3SOIPDgigT; + + ceqth = here->B3SOIPDcth; + ceqbodcon = here->B3SOIPDcbodcon; + + gbbg = -here->B3SOIPDgbgs; + gbbb = -here->B3SOIPDgbbs; + gbbp = -here->B3SOIPDgbps; + gbbsp = -here->B3SOIPDgbds; + gbbT = -model->B3SOIPDtype * here->B3SOIPDgbT; + gbbdp = -(gbbg + gbbsp + gbbb + gbbp); + + gddpg = -here->B3SOIPDgjsg; + gddpsp = -here->B3SOIPDgjsd; + gddpb = -here->B3SOIPDgjsb; + gddpT = -model->B3SOIPDtype * here->B3SOIPDgjsT; + gddpdp = -(gddpg + gddpsp + gddpb); + + gsspg = -here->B3SOIPDgjdg; + gsspsp = -here->B3SOIPDgjdd; + gsspb = -here->B3SOIPDgjdb; + gsspT = -model->B3SOIPDtype * here->B3SOIPDgjdT; + gsspdp = -(gsspg + gsspsp + gsspb); + + gppb = -here->B3SOIPDgbpbs; + gppp = -here->B3SOIPDgbpps; + gppT = -model->B3SOIPDtype * here->B3SOIPDgbpT; + + gTtg = here->B3SOIPDgtempg; + gTtb = here->B3SOIPDgtempb; + gTtsp = here->B3SOIPDgtempd; + gTtt = here->B3SOIPDgtempT; + gTtdp = -(gTtg + gTtb + gTtsp); + } + + if (model->B3SOIPDtype > 0) + { + ceqqg = ceqqg; + ceqqb = ceqqb; + ceqqe = ceqqe; + ceqqd = ceqqd; + } + else + { + ceqbodcon = -ceqbodcon; + ceqbody = -ceqbody; + ceqgate = -ceqgate; + ceqbs = -ceqbs; + ceqbd = -ceqbd; + ceqqg = -ceqqg; + ceqqb = -ceqqb; + ceqqd = -ceqqd; + ceqqe = -ceqqe; + } + + (*(ckt->CKTrhs + here->B3SOIPDbNode) -= (ceqbody + ceqqb)); + + (*(ckt->CKTrhs + here->B3SOIPDgNode) -= (ceqgate + ceqqg)); + (*(ckt->CKTrhs + here->B3SOIPDdNodePrime) += (ceqbd - cdreq - ceqqd)); + (*(ckt->CKTrhs + here->B3SOIPDsNodePrime) += (cdreq + ceqbs + ceqqg + + ceqqb + ceqqd + + ceqqe)); + (*(ckt->CKTrhs + here->B3SOIPDeNode) -= ceqqe); + + if (here->B3SOIPDbodyMod == 1) + { + (*(ckt->CKTrhs + here->B3SOIPDpNode) += ceqbodcon); + } + + if (selfheat) + { + (*(ckt->CKTrhs + here->B3SOIPDtempNode) -= ceqth + ceqqth); + } + + + + if (here->B3SOIPDdebugMod != 0) + { + *(ckt->CKTrhs + here->B3SOIPDvbsNode) = here->B3SOIPDvbseff; + *(ckt->CKTrhs + here->B3SOIPDidsNode) = FLOG (here->B3SOIPDids); + *(ckt->CKTrhs + here->B3SOIPDicNode) = FLOG (here->B3SOIPDic); + *(ckt->CKTrhs + here->B3SOIPDibsNode) = FLOG (here->B3SOIPDibs); + *(ckt->CKTrhs + here->B3SOIPDibdNode) = FLOG (here->B3SOIPDibd); + *(ckt->CKTrhs + here->B3SOIPDiiiNode) = FLOG (here->B3SOIPDiii); + *(ckt->CKTrhs + here->B3SOIPDigNode) = here->B3SOIPDig; + *(ckt->CKTrhs + here->B3SOIPDgiggNode) = here->B3SOIPDgigg; + *(ckt->CKTrhs + here->B3SOIPDgigdNode) = here->B3SOIPDgigd; + *(ckt->CKTrhs + here->B3SOIPDgigbNode) = here->B3SOIPDgigb; + *(ckt->CKTrhs + here->B3SOIPDigidlNode) = here->B3SOIPDigidl; + *(ckt->CKTrhs + here->B3SOIPDitunNode) = here->B3SOIPDitun; + *(ckt->CKTrhs + here->B3SOIPDibpNode) = here->B3SOIPDibp; + *(ckt->CKTrhs + here->B3SOIPDcbbNode) = here->B3SOIPDcbb; + *(ckt->CKTrhs + here->B3SOIPDcbdNode) = here->B3SOIPDcbd; + *(ckt->CKTrhs + here->B3SOIPDcbgNode) = here->B3SOIPDcbg; + *(ckt->CKTrhs + here->B3SOIPDqbfNode) = here->B3SOIPDqbf; + *(ckt->CKTrhs + here->B3SOIPDqjsNode) = here->B3SOIPDqjs; + *(ckt->CKTrhs + here->B3SOIPDqjdNode) = here->B3SOIPDqjd; + } + + + /* + * load y matrix + */ + Gmin = ckt->CKTgmin * 1e-6; + + *(here->B3SOIPDEdpPtr) += gcedb; + *(here->B3SOIPDEspPtr) += gcesb; + *(here->B3SOIPDDPePtr) += gcdeb; + *(here->B3SOIPDSPePtr) += gcseb; + *(here->B3SOIPDEgPtr) += gcegb; + *(here->B3SOIPDGePtr) += gcgeb; + + (*(here->B3SOIPDEbPtr) -= gcegb + gcedb + gcesb + gceeb); + (*(here->B3SOIPDGbPtr) -= -gigb + gcggb + gcgdb + gcgsb + gcgeb); + (*(here->B3SOIPDDPbPtr) -= (-gddpb - Gmbs + gcdgb + gcddb + gcdeb + gcdsb)); + + + (*(here->B3SOIPDSPbPtr) -= + (-gsspb + Gmbs + gcsgb + gcsdb + gcseb + gcssb)) + Gmin; + + + (*(here->B3SOIPDBePtr) += gcbeb); + (*(here->B3SOIPDBgPtr) += -gigg + gcbgb + gbbg); + (*(here->B3SOIPDBdpPtr) += -gigd + gcbdb + gbbdp); + (*(here->B3SOIPDBspPtr) += gcbsb + gbbsp - Gmin - gigs); + + (*(here->B3SOIPDBbPtr) += + -gigb + gbbb - gcbgb - gcbdb - gcbsb - gcbeb + Gmin); + (*(here->B3SOIPDEePtr) += gceeb); + + (*(here->B3SOIPDGgPtr) += gigg + gcggb + ckt->CKTgmin); + (*(here->B3SOIPDGdpPtr) += gigd + gcgdb - ckt->CKTgmin); + (*(here->B3SOIPDGspPtr) += gcgsb + gigs); + + (*(here->B3SOIPDDPgPtr) += (Gm + gcdgb) + gddpg - ckt->CKTgmin); + (*(here->B3SOIPDDPdpPtr) += (here->B3SOIPDdrainConductance + + here->B3SOIPDgds + gddpdp + + RevSum + gcddb) + ckt->CKTgmin); + (*(here->B3SOIPDDPspPtr) -= (-gddpsp + here->B3SOIPDgds + FwdSum - gcdsb)); + + (*(here->B3SOIPDDPdPtr) -= here->B3SOIPDdrainConductance); + + (*(here->B3SOIPDSPgPtr) += gcsgb - Gm + gsspg); + (*(here->B3SOIPDSPdpPtr) -= (here->B3SOIPDgds - gsspdp + RevSum - gcsdb)); + + (*(here->B3SOIPDSPspPtr) += (here->B3SOIPDsourceConductance + + here->B3SOIPDgds + gsspsp + + FwdSum + gcssb)) + Gmin; + + + (*(here->B3SOIPDSPsPtr) -= here->B3SOIPDsourceConductance); + + + (*(here->B3SOIPDDdPtr) += here->B3SOIPDdrainConductance); + (*(here->B3SOIPDDdpPtr) -= here->B3SOIPDdrainConductance); + + + (*(here->B3SOIPDSsPtr) += here->B3SOIPDsourceConductance); + (*(here->B3SOIPDSspPtr) -= here->B3SOIPDsourceConductance); + + if (here->B3SOIPDbodyMod == 1) + { + (*(here->B3SOIPDBpPtr) -= gppp); + (*(here->B3SOIPDPbPtr) += gppb); + (*(here->B3SOIPDPpPtr) += gppp); + } + + if (selfheat) + { + (*(here->B3SOIPDDPtempPtr) += GmT + gddpT + gcdT); + (*(here->B3SOIPDSPtempPtr) += -GmT + gsspT + gcsT); + (*(here->B3SOIPDBtempPtr) += gbbT + gcbT - gigT); + (*(here->B3SOIPDEtempPtr) += gceT); + (*(here->B3SOIPDGtempPtr) += gcgT + gigT); + (*(here->B3SOIPDTemptempPtr) += gTtt + 1 / pParam->B3SOIPDrth + gcTt); + (*(here->B3SOIPDTempgPtr) += gTtg); + (*(here->B3SOIPDTempbPtr) += gTtb); + (*(here->B3SOIPDTempdpPtr) += gTtdp); + (*(here->B3SOIPDTempspPtr) += gTtsp); + } + + if (here->B3SOIPDdebugMod != 0) + { + *(here->B3SOIPDVbsPtr) += 1; + *(here->B3SOIPDIdsPtr) += 1; + *(here->B3SOIPDIcPtr) += 1; + *(here->B3SOIPDIbsPtr) += 1; + *(here->B3SOIPDIbdPtr) += 1; + *(here->B3SOIPDIiiPtr) += 1; + *(here->B3SOIPDIgPtr) += 1; + *(here->B3SOIPDGiggPtr) += 1; + *(here->B3SOIPDGigdPtr) += 1; + *(here->B3SOIPDGigbPtr) += 1; + *(here->B3SOIPDIgidlPtr) += 1; + *(here->B3SOIPDItunPtr) += 1; + *(here->B3SOIPDIbpPtr) += 1; + *(here->B3SOIPDCbgPtr) += 1; + *(here->B3SOIPDCbbPtr) += 1; + *(here->B3SOIPDCbdPtr) += 1; + *(here->B3SOIPDQbfPtr) += 1; + *(here->B3SOIPDQjsPtr) += 1; + *(here->B3SOIPDQjdPtr) += 1; + + } + + line1000:; + + + } /* End of Mosfet Instance */ + } /* End of Model Instance */ + + + return (OK); +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdmask.c b/src/spicelib/devices/bsim3soi_pd/b3soipdmask.c new file mode 100644 index 000000000..28e9032f0 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdmask.c @@ -0,0 +1,1438 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipdmask.c 98/5/01 +Modified by Pin Su and Jan Feng 99/2/15 +Modified by Pin Su 99/4/30 +Modified by Wei Jin 99/9/27 +Modified by Pin Su 00/3/1 +**********/ + + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "b3soipddef.h" +#include "sperror.h" +#include "suffix.h" + +int +B3SOIPDmAsk (ckt, inst, which, value) + CKTcircuit *ckt; + GENmodel *inst; + int which; + IFvalue *value; +{ + B3SOIPDmodel *model = (B3SOIPDmodel *) inst; + switch (which) + { + case B3SOIPD_MOD_MOBMOD: + value->iValue = model->B3SOIPDmobMod; + return (OK); + case B3SOIPD_MOD_PARAMCHK: + value->iValue = model->B3SOIPDparamChk; + return (OK); + case B3SOIPD_MOD_BINUNIT: + value->iValue = model->B3SOIPDbinUnit; + return (OK); + case B3SOIPD_MOD_CAPMOD: + value->iValue = model->B3SOIPDcapMod; + return (OK); + case B3SOIPD_MOD_SHMOD: + value->iValue = model->B3SOIPDshMod; + return (OK); + case B3SOIPD_MOD_NOIMOD: + value->iValue = model->B3SOIPDnoiMod; + return (OK); + case B3SOIPD_MOD_VERSION: + value->rValue = model->B3SOIPDversion; + return (OK); + case B3SOIPD_MOD_TOX: + value->rValue = model->B3SOIPDtox; + return (OK); + case B3SOIPD_MOD_CDSC: + value->rValue = model->B3SOIPDcdsc; + return (OK); + case B3SOIPD_MOD_CDSCB: + value->rValue = model->B3SOIPDcdscb; + return (OK); + + case B3SOIPD_MOD_CDSCD: + value->rValue = model->B3SOIPDcdscd; + return (OK); + + case B3SOIPD_MOD_CIT: + value->rValue = model->B3SOIPDcit; + return (OK); + case B3SOIPD_MOD_NFACTOR: + value->rValue = model->B3SOIPDnfactor; + return (OK); + case B3SOIPD_MOD_VSAT: + value->rValue = model->B3SOIPDvsat; + return (OK); + case B3SOIPD_MOD_AT: + value->rValue = model->B3SOIPDat; + return (OK); + case B3SOIPD_MOD_A0: + value->rValue = model->B3SOIPDa0; + return (OK); + + case B3SOIPD_MOD_AGS: + value->rValue = model->B3SOIPDags; + return (OK); + + case B3SOIPD_MOD_A1: + value->rValue = model->B3SOIPDa1; + return (OK); + case B3SOIPD_MOD_A2: + value->rValue = model->B3SOIPDa2; + return (OK); + case B3SOIPD_MOD_KETA: + value->rValue = model->B3SOIPDketa; + return (OK); + case B3SOIPD_MOD_NSUB: + value->rValue = model->B3SOIPDnsub; + return (OK); + case B3SOIPD_MOD_NPEAK: + value->rValue = model->B3SOIPDnpeak; + return (OK); + case B3SOIPD_MOD_NGATE: + value->rValue = model->B3SOIPDngate; + return (OK); + case B3SOIPD_MOD_GAMMA1: + value->rValue = model->B3SOIPDgamma1; + return (OK); + case B3SOIPD_MOD_GAMMA2: + value->rValue = model->B3SOIPDgamma2; + return (OK); + case B3SOIPD_MOD_VBX: + value->rValue = model->B3SOIPDvbx; + return (OK); + case B3SOIPD_MOD_VBM: + value->rValue = model->B3SOIPDvbm; + return (OK); + case B3SOIPD_MOD_XT: + value->rValue = model->B3SOIPDxt; + return (OK); + case B3SOIPD_MOD_K1: + value->rValue = model->B3SOIPDk1; + return (OK); + case B3SOIPD_MOD_KT1: + value->rValue = model->B3SOIPDkt1; + return (OK); + case B3SOIPD_MOD_KT1L: + value->rValue = model->B3SOIPDkt1l; + return (OK); + case B3SOIPD_MOD_KT2: + value->rValue = model->B3SOIPDkt2; + return (OK); + case B3SOIPD_MOD_K2: + value->rValue = model->B3SOIPDk2; + return (OK); + case B3SOIPD_MOD_K3: + value->rValue = model->B3SOIPDk3; + return (OK); + case B3SOIPD_MOD_K3B: + value->rValue = model->B3SOIPDk3b; + return (OK); + case B3SOIPD_MOD_W0: + value->rValue = model->B3SOIPDw0; + return (OK); + case B3SOIPD_MOD_NLX: + value->rValue = model->B3SOIPDnlx; + return (OK); + case B3SOIPD_MOD_DVT0: + value->rValue = model->B3SOIPDdvt0; + return (OK); + case B3SOIPD_MOD_DVT1: + value->rValue = model->B3SOIPDdvt1; + return (OK); + case B3SOIPD_MOD_DVT2: + value->rValue = model->B3SOIPDdvt2; + return (OK); + case B3SOIPD_MOD_DVT0W: + value->rValue = model->B3SOIPDdvt0w; + return (OK); + case B3SOIPD_MOD_DVT1W: + value->rValue = model->B3SOIPDdvt1w; + return (OK); + case B3SOIPD_MOD_DVT2W: + value->rValue = model->B3SOIPDdvt2w; + return (OK); + case B3SOIPD_MOD_DROUT: + value->rValue = model->B3SOIPDdrout; + return (OK); + case B3SOIPD_MOD_DSUB: + value->rValue = model->B3SOIPDdsub; + return (OK); + case B3SOIPD_MOD_VTH0: + value->rValue = model->B3SOIPDvth0; + return (OK); + case B3SOIPD_MOD_UA: + value->rValue = model->B3SOIPDua; + return (OK); + case B3SOIPD_MOD_UA1: + value->rValue = model->B3SOIPDua1; + return (OK); + case B3SOIPD_MOD_UB: + value->rValue = model->B3SOIPDub; + return (OK); + case B3SOIPD_MOD_UB1: + value->rValue = model->B3SOIPDub1; + return (OK); + case B3SOIPD_MOD_UC: + value->rValue = model->B3SOIPDuc; + return (OK); + case B3SOIPD_MOD_UC1: + value->rValue = model->B3SOIPDuc1; + return (OK); + case B3SOIPD_MOD_U0: + value->rValue = model->B3SOIPDu0; + return (OK); + case B3SOIPD_MOD_UTE: + value->rValue = model->B3SOIPDute; + return (OK); + case B3SOIPD_MOD_VOFF: + value->rValue = model->B3SOIPDvoff; + return (OK); + case B3SOIPD_MOD_DELTA: + value->rValue = model->B3SOIPDdelta; + return (OK); + case B3SOIPD_MOD_RDSW: + value->rValue = model->B3SOIPDrdsw; + return (OK); + case B3SOIPD_MOD_PRWG: + value->rValue = model->B3SOIPDprwg; + return (OK); + case B3SOIPD_MOD_PRWB: + value->rValue = model->B3SOIPDprwb; + return (OK); + case B3SOIPD_MOD_PRT: + value->rValue = model->B3SOIPDprt; + return (OK); + case B3SOIPD_MOD_ETA0: + value->rValue = model->B3SOIPDeta0; + return (OK); + case B3SOIPD_MOD_ETAB: + value->rValue = model->B3SOIPDetab; + return (OK); + case B3SOIPD_MOD_PCLM: + value->rValue = model->B3SOIPDpclm; + return (OK); + case B3SOIPD_MOD_PDIBL1: + value->rValue = model->B3SOIPDpdibl1; + return (OK); + case B3SOIPD_MOD_PDIBL2: + value->rValue = model->B3SOIPDpdibl2; + return (OK); + case B3SOIPD_MOD_PDIBLB: + value->rValue = model->B3SOIPDpdiblb; + return (OK); + case B3SOIPD_MOD_PVAG: + value->rValue = model->B3SOIPDpvag; + return (OK); + case B3SOIPD_MOD_WR: + value->rValue = model->B3SOIPDwr; + return (OK); + case B3SOIPD_MOD_DWG: + value->rValue = model->B3SOIPDdwg; + return (OK); + case B3SOIPD_MOD_DWB: + value->rValue = model->B3SOIPDdwb; + return (OK); + case B3SOIPD_MOD_B0: + value->rValue = model->B3SOIPDb0; + return (OK); + case B3SOIPD_MOD_B1: + value->rValue = model->B3SOIPDb1; + return (OK); + case B3SOIPD_MOD_ALPHA0: + value->rValue = model->B3SOIPDalpha0; + return (OK); + + case B3SOIPD_MOD_CGSL: + value->rValue = model->B3SOIPDcgsl; + return (OK); + case B3SOIPD_MOD_CGDL: + value->rValue = model->B3SOIPDcgdl; + return (OK); + case B3SOIPD_MOD_CKAPPA: + value->rValue = model->B3SOIPDckappa; + return (OK); + case B3SOIPD_MOD_CF: + value->rValue = model->B3SOIPDcf; + return (OK); + case B3SOIPD_MOD_CLC: + value->rValue = model->B3SOIPDclc; + return (OK); + case B3SOIPD_MOD_CLE: + value->rValue = model->B3SOIPDcle; + return (OK); + case B3SOIPD_MOD_DWC: + value->rValue = model->B3SOIPDdwc; + return (OK); + case B3SOIPD_MOD_DLC: + value->rValue = model->B3SOIPDdlc; + return (OK); + + case B3SOIPD_MOD_TBOX: + value->rValue = model->B3SOIPDtbox; + return (OK); + case B3SOIPD_MOD_TSI: + value->rValue = model->B3SOIPDtsi; + return (OK); + case B3SOIPD_MOD_RTH0: + value->rValue = model->B3SOIPDrth0; + return (OK); + case B3SOIPD_MOD_CTH0: + value->rValue = model->B3SOIPDcth0; + return (OK); + case B3SOIPD_MOD_NDIODE: + value->rValue = model->B3SOIPDndiode; + return (OK); + case B3SOIPD_MOD_XBJT: + value->rValue = model->B3SOIPDxbjt; + return (OK); + + case B3SOIPD_MOD_XDIF: + value->rValue = model->B3SOIPDxdif; + return (OK); + + case B3SOIPD_MOD_XREC: + value->rValue = model->B3SOIPDxrec; + return (OK); + case B3SOIPD_MOD_XTUN: + value->rValue = model->B3SOIPDxtun; + return (OK); + case B3SOIPD_MOD_TT: + value->rValue = model->B3SOIPDtt; + return (OK); + case B3SOIPD_MOD_VSDTH: + value->rValue = model->B3SOIPDvsdth; + return (OK); + case B3SOIPD_MOD_VSDFB: + value->rValue = model->B3SOIPDvsdfb; + return (OK); + case B3SOIPD_MOD_CSDMIN: + value->rValue = model->B3SOIPDcsdmin; + return (OK); + case B3SOIPD_MOD_ASD: + value->rValue = model->B3SOIPDasd; + return (OK); + + case B3SOIPD_MOD_TNOM: + value->rValue = model->B3SOIPDtnom; + return (OK); + case B3SOIPD_MOD_CGSO: + value->rValue = model->B3SOIPDcgso; + return (OK); + case B3SOIPD_MOD_CGDO: + value->rValue = model->B3SOIPDcgdo; + return (OK); + case B3SOIPD_MOD_CGEO: + value->rValue = model->B3SOIPDcgeo; + return (OK); + case B3SOIPD_MOD_XPART: + value->rValue = model->B3SOIPDxpart; + return (OK); + case B3SOIPD_MOD_RSH: + value->rValue = model->B3SOIPDsheetResistance; + return (OK); + case B3SOIPD_MOD_PBSWG: + value->rValue = model->B3SOIPDGatesidewallJctPotential; + return (OK); + case B3SOIPD_MOD_MJSWG: + value->rValue = model->B3SOIPDbodyJctGateSideGradingCoeff; + return (OK); + case B3SOIPD_MOD_CJSWG: + value->rValue = model->B3SOIPDunitLengthGateSidewallJctCap; + return (OK); + case B3SOIPD_MOD_CSDESW: + value->rValue = model->B3SOIPDcsdesw; + return (OK); + case B3SOIPD_MOD_LINT: + value->rValue = model->B3SOIPDLint; + return (OK); + case B3SOIPD_MOD_LL: + value->rValue = model->B3SOIPDLl; + return (OK); + case B3SOIPD_MOD_LLN: + value->rValue = model->B3SOIPDLln; + return (OK); + case B3SOIPD_MOD_LW: + value->rValue = model->B3SOIPDLw; + return (OK); + case B3SOIPD_MOD_LWN: + value->rValue = model->B3SOIPDLwn; + return (OK); + case B3SOIPD_MOD_LWL: + value->rValue = model->B3SOIPDLwl; + return (OK); + case B3SOIPD_MOD_WINT: + value->rValue = model->B3SOIPDWint; + return (OK); + case B3SOIPD_MOD_WL: + value->rValue = model->B3SOIPDWl; + return (OK); + case B3SOIPD_MOD_WLN: + value->rValue = model->B3SOIPDWln; + return (OK); + case B3SOIPD_MOD_WW: + value->rValue = model->B3SOIPDWw; + return (OK); + case B3SOIPD_MOD_WWN: + value->rValue = model->B3SOIPDWwn; + return (OK); + case B3SOIPD_MOD_WWL: + value->rValue = model->B3SOIPDWwl; + return (OK); + case B3SOIPD_MOD_NOIA: + value->rValue = model->B3SOIPDoxideTrapDensityA; + return (OK); + case B3SOIPD_MOD_NOIB: + value->rValue = model->B3SOIPDoxideTrapDensityB; + return (OK); + case B3SOIPD_MOD_NOIC: + value->rValue = model->B3SOIPDoxideTrapDensityC; + return (OK); + case B3SOIPD_MOD_NOIF: + value->rValue = model->B3SOIPDnoif; + return (OK); + case B3SOIPD_MOD_EM: + value->rValue = model->B3SOIPDem; + return (OK); + case B3SOIPD_MOD_EF: + value->rValue = model->B3SOIPDef; + return (OK); + case B3SOIPD_MOD_AF: + value->rValue = model->B3SOIPDaf; + return (OK); + case B3SOIPD_MOD_KF: + value->rValue = model->B3SOIPDkf; + return (OK); + + +/* v2.0 release */ + case B3SOIPD_MOD_K1W1: + value->rValue = model->B3SOIPDk1w1; + return (OK); + case B3SOIPD_MOD_K1W2: + value->rValue = model->B3SOIPDk1w2; + return (OK); + case B3SOIPD_MOD_KETAS: + value->rValue = model->B3SOIPDketas; + return (OK); + case B3SOIPD_MOD_DWBC: + value->rValue = model->B3SOIPDdwbc; + return (OK); + case B3SOIPD_MOD_BETA0: + value->rValue = model->B3SOIPDbeta0; + return (OK); + case B3SOIPD_MOD_BETA1: + value->rValue = model->B3SOIPDbeta1; + return (OK); + case B3SOIPD_MOD_BETA2: + value->rValue = model->B3SOIPDbeta2; + return (OK); + case B3SOIPD_MOD_VDSATII0: + value->rValue = model->B3SOIPDvdsatii0; + return (OK); + case B3SOIPD_MOD_TII: + value->rValue = model->B3SOIPDtii; + return (OK); + case B3SOIPD_MOD_LII: + value->rValue = model->B3SOIPDlii; + return (OK); + case B3SOIPD_MOD_SII0: + value->rValue = model->B3SOIPDsii0; + return (OK); + case B3SOIPD_MOD_SII1: + value->rValue = model->B3SOIPDsii1; + return (OK); + case B3SOIPD_MOD_SII2: + value->rValue = model->B3SOIPDsii2; + return (OK); + case B3SOIPD_MOD_SIID: + value->rValue = model->B3SOIPDsiid; + return (OK); + case B3SOIPD_MOD_FBJTII: + value->rValue = model->B3SOIPDfbjtii; + return (OK); + case B3SOIPD_MOD_ESATII: + value->rValue = model->B3SOIPDesatii; + return (OK); + case B3SOIPD_MOD_NTUN: + value->rValue = model->B3SOIPDntun; + return (OK); + case B3SOIPD_MOD_NRECF0: + value->rValue = model->B3SOIPDnrecf0; + return (OK); + case B3SOIPD_MOD_NRECR0: + value->rValue = model->B3SOIPDnrecr0; + return (OK); + case B3SOIPD_MOD_ISBJT: + value->rValue = model->B3SOIPDisbjt; + return (OK); + case B3SOIPD_MOD_ISDIF: + value->rValue = model->B3SOIPDisdif; + return (OK); + case B3SOIPD_MOD_ISREC: + value->rValue = model->B3SOIPDisrec; + return (OK); + case B3SOIPD_MOD_ISTUN: + value->rValue = model->B3SOIPDistun; + return (OK); + case B3SOIPD_MOD_LN: + value->rValue = model->B3SOIPDln; + return (OK); + case B3SOIPD_MOD_VREC0: + value->rValue = model->B3SOIPDvrec0; + return (OK); + case B3SOIPD_MOD_VTUN0: + value->rValue = model->B3SOIPDvtun0; + return (OK); + case B3SOIPD_MOD_NBJT: + value->rValue = model->B3SOIPDnbjt; + return (OK); + case B3SOIPD_MOD_LBJT0: + value->rValue = model->B3SOIPDlbjt0; + return (OK); + case B3SOIPD_MOD_LDIF0: + value->rValue = model->B3SOIPDldif0; + return (OK); + case B3SOIPD_MOD_VABJT: + value->rValue = model->B3SOIPDvabjt; + return (OK); + case B3SOIPD_MOD_AELY: + value->rValue = model->B3SOIPDaely; + return (OK); + case B3SOIPD_MOD_AHLI: + value->rValue = model->B3SOIPDahli; + return (OK); + case B3SOIPD_MOD_RBODY: + value->rValue = model->B3SOIPDrbody; + return (OK); + case B3SOIPD_MOD_RBSH: + value->rValue = model->B3SOIPDrbsh; + return (OK); + case B3SOIPD_MOD_NTRECF: + value->rValue = model->B3SOIPDntrecf; + return (OK); + case B3SOIPD_MOD_NTRECR: + value->rValue = model->B3SOIPDntrecr; + return (OK); + case B3SOIPD_MOD_NDIF: + value->rValue = model->B3SOIPDndif; + return (OK); + case B3SOIPD_MOD_DLCB: + value->rValue = model->B3SOIPDdlcb; + return (OK); + case B3SOIPD_MOD_FBODY: + value->rValue = model->B3SOIPDfbody; + return (OK); + case B3SOIPD_MOD_TCJSWG: + value->rValue = model->B3SOIPDtcjswg; + return (OK); + case B3SOIPD_MOD_TPBSWG: + value->rValue = model->B3SOIPDtpbswg; + return (OK); + case B3SOIPD_MOD_ACDE: + value->rValue = model->B3SOIPDacde; + return (OK); + case B3SOIPD_MOD_MOIN: + value->rValue = model->B3SOIPDmoin; + return (OK); + case B3SOIPD_MOD_DELVT: + value->rValue = model->B3SOIPDdelvt; + return (OK); + case B3SOIPD_MOD_KB1: + value->rValue = model->B3SOIPDkb1; + return (OK); + case B3SOIPD_MOD_DLBG: + value->rValue = model->B3SOIPDdlbg; + return (OK); + + case B3SOIPD_MOD_NGIDL: + value->rValue = model->B3SOIPDngidl; + return (OK); + case B3SOIPD_MOD_AGIDL: + value->rValue = model->B3SOIPDagidl; + return (OK); + case B3SOIPD_MOD_BGIDL: + value->rValue = model->B3SOIPDbgidl; + return (OK); + + +/* v2.2 release */ + case B3SOIPD_MOD_WTH0: + value->rValue = model->B3SOIPDwth0; + return (OK); + case B3SOIPD_MOD_RHALO: + value->rValue = model->B3SOIPDrhalo; + return (OK); + case B3SOIPD_MOD_NTOX: + value->rValue = model->B3SOIPDntox; + return (OK); + case B3SOIPD_MOD_TOXREF: + value->rValue = model->B3SOIPDtoxref; + return (OK); + case B3SOIPD_MOD_EBG: + value->rValue = model->B3SOIPDebg; + return (OK); + case B3SOIPD_MOD_NEVB: + value->rValue = model->B3SOIPDnevb; + return (OK); + case B3SOIPD_MOD_ALPHAGB1: + value->rValue = model->B3SOIPDalphaGB1; + return (OK); + case B3SOIPD_MOD_BETAGB1: + value->rValue = model->B3SOIPDbetaGB1; + return (OK); + case B3SOIPD_MOD_VGB1: + value->rValue = model->B3SOIPDvgb1; + return (OK); + case B3SOIPD_MOD_NECB: + value->rValue = model->B3SOIPDnecb; + return (OK); + case B3SOIPD_MOD_ALPHAGB2: + value->rValue = model->B3SOIPDalphaGB2; + return (OK); + case B3SOIPD_MOD_BETAGB2: + value->rValue = model->B3SOIPDbetaGB2; + return (OK); + case B3SOIPD_MOD_VGB2: + value->rValue = model->B3SOIPDvgb2; + return (OK); + case B3SOIPD_MOD_TOXQM: + value->rValue = model->B3SOIPDtoxqm; + return (OK); + case B3SOIPD_MOD_VOXH: + value->rValue = model->B3SOIPDvoxh; + return (OK); + case B3SOIPD_MOD_DELTAVOX: + value->rValue = model->B3SOIPDdeltavox; + return (OK); + case B3SOIPD_MOD_IGMOD: + value->iValue = model->B3SOIPDigMod; + return (OK); + + +/* Added for binning - START */ + /* Length Dependence */ + case B3SOIPD_MOD_LNPEAK: + value->rValue = model->B3SOIPDlnpeak; + return (OK); + case B3SOIPD_MOD_LNSUB: + value->rValue = model->B3SOIPDlnsub; + return (OK); + case B3SOIPD_MOD_LNGATE: + value->rValue = model->B3SOIPDlngate; + return (OK); + case B3SOIPD_MOD_LVTH0: + value->rValue = model->B3SOIPDlvth0; + return (OK); + case B3SOIPD_MOD_LK1: + value->rValue = model->B3SOIPDlk1; + return (OK); + case B3SOIPD_MOD_LK1W1: + value->rValue = model->B3SOIPDlk1w1; + return (OK); + case B3SOIPD_MOD_LK1W2: + value->rValue = model->B3SOIPDlk1w2; + return (OK); + case B3SOIPD_MOD_LK2: + value->rValue = model->B3SOIPDlk2; + return (OK); + case B3SOIPD_MOD_LK3: + value->rValue = model->B3SOIPDlk3; + return (OK); + case B3SOIPD_MOD_LK3B: + value->rValue = model->B3SOIPDlk3b; + return (OK); + case B3SOIPD_MOD_LKB1: + value->rValue = model->B3SOIPDlkb1; + return (OK); + case B3SOIPD_MOD_LW0: + value->rValue = model->B3SOIPDlw0; + return (OK); + case B3SOIPD_MOD_LNLX: + value->rValue = model->B3SOIPDlnlx; + return (OK); + case B3SOIPD_MOD_LDVT0: + value->rValue = model->B3SOIPDldvt0; + return (OK); + case B3SOIPD_MOD_LDVT1: + value->rValue = model->B3SOIPDldvt1; + return (OK); + case B3SOIPD_MOD_LDVT2: + value->rValue = model->B3SOIPDldvt2; + return (OK); + case B3SOIPD_MOD_LDVT0W: + value->rValue = model->B3SOIPDldvt0w; + return (OK); + case B3SOIPD_MOD_LDVT1W: + value->rValue = model->B3SOIPDldvt1w; + return (OK); + case B3SOIPD_MOD_LDVT2W: + value->rValue = model->B3SOIPDldvt2w; + return (OK); + case B3SOIPD_MOD_LU0: + value->rValue = model->B3SOIPDlu0; + return (OK); + case B3SOIPD_MOD_LUA: + value->rValue = model->B3SOIPDlua; + return (OK); + case B3SOIPD_MOD_LUB: + value->rValue = model->B3SOIPDlub; + return (OK); + case B3SOIPD_MOD_LUC: + value->rValue = model->B3SOIPDluc; + return (OK); + case B3SOIPD_MOD_LVSAT: + value->rValue = model->B3SOIPDlvsat; + return (OK); + case B3SOIPD_MOD_LA0: + value->rValue = model->B3SOIPDla0; + return (OK); + case B3SOIPD_MOD_LAGS: + value->rValue = model->B3SOIPDlags; + return (OK); + case B3SOIPD_MOD_LB0: + value->rValue = model->B3SOIPDlb0; + return (OK); + case B3SOIPD_MOD_LB1: + value->rValue = model->B3SOIPDlb1; + return (OK); + case B3SOIPD_MOD_LKETA: + value->rValue = model->B3SOIPDlketa; + return (OK); + case B3SOIPD_MOD_LKETAS: + value->rValue = model->B3SOIPDlketas; + return (OK); + case B3SOIPD_MOD_LA1: + value->rValue = model->B3SOIPDla1; + return (OK); + case B3SOIPD_MOD_LA2: + value->rValue = model->B3SOIPDla2; + return (OK); + case B3SOIPD_MOD_LRDSW: + value->rValue = model->B3SOIPDlrdsw; + return (OK); + case B3SOIPD_MOD_LPRWB: + value->rValue = model->B3SOIPDlprwb; + return (OK); + case B3SOIPD_MOD_LPRWG: + value->rValue = model->B3SOIPDlprwg; + return (OK); + case B3SOIPD_MOD_LWR: + value->rValue = model->B3SOIPDlwr; + return (OK); + case B3SOIPD_MOD_LNFACTOR: + value->rValue = model->B3SOIPDlnfactor; + return (OK); + case B3SOIPD_MOD_LDWG: + value->rValue = model->B3SOIPDldwg; + return (OK); + case B3SOIPD_MOD_LDWB: + value->rValue = model->B3SOIPDldwb; + return (OK); + case B3SOIPD_MOD_LVOFF: + value->rValue = model->B3SOIPDlvoff; + return (OK); + case B3SOIPD_MOD_LETA0: + value->rValue = model->B3SOIPDleta0; + return (OK); + case B3SOIPD_MOD_LETAB: + value->rValue = model->B3SOIPDletab; + return (OK); + case B3SOIPD_MOD_LDSUB: + value->rValue = model->B3SOIPDldsub; + return (OK); + case B3SOIPD_MOD_LCIT: + value->rValue = model->B3SOIPDlcit; + return (OK); + case B3SOIPD_MOD_LCDSC: + value->rValue = model->B3SOIPDlcdsc; + return (OK); + case B3SOIPD_MOD_LCDSCB: + value->rValue = model->B3SOIPDlcdscb; + return (OK); + case B3SOIPD_MOD_LCDSCD: + value->rValue = model->B3SOIPDlcdscd; + return (OK); + case B3SOIPD_MOD_LPCLM: + value->rValue = model->B3SOIPDlpclm; + return (OK); + case B3SOIPD_MOD_LPDIBL1: + value->rValue = model->B3SOIPDlpdibl1; + return (OK); + case B3SOIPD_MOD_LPDIBL2: + value->rValue = model->B3SOIPDlpdibl2; + return (OK); + case B3SOIPD_MOD_LPDIBLB: + value->rValue = model->B3SOIPDlpdiblb; + return (OK); + case B3SOIPD_MOD_LDROUT: + value->rValue = model->B3SOIPDldrout; + return (OK); + case B3SOIPD_MOD_LPVAG: + value->rValue = model->B3SOIPDlpvag; + return (OK); + case B3SOIPD_MOD_LDELTA: + value->rValue = model->B3SOIPDldelta; + return (OK); + case B3SOIPD_MOD_LALPHA0: + value->rValue = model->B3SOIPDlalpha0; + return (OK); + case B3SOIPD_MOD_LFBJTII: + value->rValue = model->B3SOIPDlfbjtii; + return (OK); + case B3SOIPD_MOD_LBETA0: + value->rValue = model->B3SOIPDlbeta0; + return (OK); + case B3SOIPD_MOD_LBETA1: + value->rValue = model->B3SOIPDlbeta1; + return (OK); + case B3SOIPD_MOD_LBETA2: + value->rValue = model->B3SOIPDlbeta2; + return (OK); + case B3SOIPD_MOD_LVDSATII0: + value->rValue = model->B3SOIPDlvdsatii0; + return (OK); + case B3SOIPD_MOD_LLII: + value->rValue = model->B3SOIPDllii; + return (OK); + case B3SOIPD_MOD_LESATII: + value->rValue = model->B3SOIPDlesatii; + return (OK); + case B3SOIPD_MOD_LSII0: + value->rValue = model->B3SOIPDlsii0; + return (OK); + case B3SOIPD_MOD_LSII1: + value->rValue = model->B3SOIPDlsii1; + return (OK); + case B3SOIPD_MOD_LSII2: + value->rValue = model->B3SOIPDlsii2; + return (OK); + case B3SOIPD_MOD_LSIID: + value->rValue = model->B3SOIPDlsiid; + return (OK); + case B3SOIPD_MOD_LAGIDL: + value->rValue = model->B3SOIPDlagidl; + return (OK); + case B3SOIPD_MOD_LBGIDL: + value->rValue = model->B3SOIPDlbgidl; + return (OK); + case B3SOIPD_MOD_LNGIDL: + value->rValue = model->B3SOIPDlngidl; + return (OK); + case B3SOIPD_MOD_LNTUN: + value->rValue = model->B3SOIPDlntun; + return (OK); + case B3SOIPD_MOD_LNDIODE: + value->rValue = model->B3SOIPDlndiode; + return (OK); + case B3SOIPD_MOD_LNRECF0: + value->rValue = model->B3SOIPDlnrecf0; + return (OK); + case B3SOIPD_MOD_LNRECR0: + value->rValue = model->B3SOIPDlnrecr0; + return (OK); + case B3SOIPD_MOD_LISBJT: + value->rValue = model->B3SOIPDlisbjt; + return (OK); + case B3SOIPD_MOD_LISDIF: + value->rValue = model->B3SOIPDlisdif; + return (OK); + case B3SOIPD_MOD_LISREC: + value->rValue = model->B3SOIPDlisrec; + return (OK); + case B3SOIPD_MOD_LISTUN: + value->rValue = model->B3SOIPDlistun; + return (OK); + case B3SOIPD_MOD_LVREC0: + value->rValue = model->B3SOIPDlvrec0; + return (OK); + case B3SOIPD_MOD_LVTUN0: + value->rValue = model->B3SOIPDlvtun0; + return (OK); + case B3SOIPD_MOD_LNBJT: + value->rValue = model->B3SOIPDlnbjt; + return (OK); + case B3SOIPD_MOD_LLBJT0: + value->rValue = model->B3SOIPDllbjt0; + return (OK); + case B3SOIPD_MOD_LVABJT: + value->rValue = model->B3SOIPDlvabjt; + return (OK); + case B3SOIPD_MOD_LAELY: + value->rValue = model->B3SOIPDlaely; + return (OK); + case B3SOIPD_MOD_LAHLI: + value->rValue = model->B3SOIPDlahli; + return (OK); + /* CV Model */ + case B3SOIPD_MOD_LVSDFB: + value->rValue = model->B3SOIPDlvsdfb; + return (OK); + case B3SOIPD_MOD_LVSDTH: + value->rValue = model->B3SOIPDlvsdth; + return (OK); + case B3SOIPD_MOD_LDELVT: + value->rValue = model->B3SOIPDldelvt; + return (OK); + case B3SOIPD_MOD_LACDE: + value->rValue = model->B3SOIPDlacde; + return (OK); + case B3SOIPD_MOD_LMOIN: + value->rValue = model->B3SOIPDlmoin; + return (OK); + + /* Width Dependence */ + case B3SOIPD_MOD_WNPEAK: + value->rValue = model->B3SOIPDwnpeak; + return (OK); + case B3SOIPD_MOD_WNSUB: + value->rValue = model->B3SOIPDwnsub; + return (OK); + case B3SOIPD_MOD_WNGATE: + value->rValue = model->B3SOIPDwngate; + return (OK); + case B3SOIPD_MOD_WVTH0: + value->rValue = model->B3SOIPDwvth0; + return (OK); + case B3SOIPD_MOD_WK1: + value->rValue = model->B3SOIPDwk1; + return (OK); + case B3SOIPD_MOD_WK1W1: + value->rValue = model->B3SOIPDwk1w1; + return (OK); + case B3SOIPD_MOD_WK1W2: + value->rValue = model->B3SOIPDwk1w2; + return (OK); + case B3SOIPD_MOD_WK2: + value->rValue = model->B3SOIPDwk2; + return (OK); + case B3SOIPD_MOD_WK3: + value->rValue = model->B3SOIPDwk3; + return (OK); + case B3SOIPD_MOD_WK3B: + value->rValue = model->B3SOIPDwk3b; + return (OK); + case B3SOIPD_MOD_WKB1: + value->rValue = model->B3SOIPDwkb1; + return (OK); + case B3SOIPD_MOD_WW0: + value->rValue = model->B3SOIPDww0; + return (OK); + case B3SOIPD_MOD_WNLX: + value->rValue = model->B3SOIPDwnlx; + return (OK); + case B3SOIPD_MOD_WDVT0: + value->rValue = model->B3SOIPDwdvt0; + return (OK); + case B3SOIPD_MOD_WDVT1: + value->rValue = model->B3SOIPDwdvt1; + return (OK); + case B3SOIPD_MOD_WDVT2: + value->rValue = model->B3SOIPDwdvt2; + return (OK); + case B3SOIPD_MOD_WDVT0W: + value->rValue = model->B3SOIPDwdvt0w; + return (OK); + case B3SOIPD_MOD_WDVT1W: + value->rValue = model->B3SOIPDwdvt1w; + return (OK); + case B3SOIPD_MOD_WDVT2W: + value->rValue = model->B3SOIPDwdvt2w; + return (OK); + case B3SOIPD_MOD_WU0: + value->rValue = model->B3SOIPDwu0; + return (OK); + case B3SOIPD_MOD_WUA: + value->rValue = model->B3SOIPDwua; + return (OK); + case B3SOIPD_MOD_WUB: + value->rValue = model->B3SOIPDwub; + return (OK); + case B3SOIPD_MOD_WUC: + value->rValue = model->B3SOIPDwuc; + return (OK); + case B3SOIPD_MOD_WVSAT: + value->rValue = model->B3SOIPDwvsat; + return (OK); + case B3SOIPD_MOD_WA0: + value->rValue = model->B3SOIPDwa0; + return (OK); + case B3SOIPD_MOD_WAGS: + value->rValue = model->B3SOIPDwags; + return (OK); + case B3SOIPD_MOD_WB0: + value->rValue = model->B3SOIPDwb0; + return (OK); + case B3SOIPD_MOD_WB1: + value->rValue = model->B3SOIPDwb1; + return (OK); + case B3SOIPD_MOD_WKETA: + value->rValue = model->B3SOIPDwketa; + return (OK); + case B3SOIPD_MOD_WKETAS: + value->rValue = model->B3SOIPDwketas; + return (OK); + case B3SOIPD_MOD_WA1: + value->rValue = model->B3SOIPDwa1; + return (OK); + case B3SOIPD_MOD_WA2: + value->rValue = model->B3SOIPDwa2; + return (OK); + case B3SOIPD_MOD_WRDSW: + value->rValue = model->B3SOIPDwrdsw; + return (OK); + case B3SOIPD_MOD_WPRWB: + value->rValue = model->B3SOIPDwprwb; + return (OK); + case B3SOIPD_MOD_WPRWG: + value->rValue = model->B3SOIPDwprwg; + return (OK); + case B3SOIPD_MOD_WWR: + value->rValue = model->B3SOIPDwwr; + return (OK); + case B3SOIPD_MOD_WNFACTOR: + value->rValue = model->B3SOIPDwnfactor; + return (OK); + case B3SOIPD_MOD_WDWG: + value->rValue = model->B3SOIPDwdwg; + return (OK); + case B3SOIPD_MOD_WDWB: + value->rValue = model->B3SOIPDwdwb; + return (OK); + case B3SOIPD_MOD_WVOFF: + value->rValue = model->B3SOIPDwvoff; + return (OK); + case B3SOIPD_MOD_WETA0: + value->rValue = model->B3SOIPDweta0; + return (OK); + case B3SOIPD_MOD_WETAB: + value->rValue = model->B3SOIPDwetab; + return (OK); + case B3SOIPD_MOD_WDSUB: + value->rValue = model->B3SOIPDwdsub; + return (OK); + case B3SOIPD_MOD_WCIT: + value->rValue = model->B3SOIPDwcit; + return (OK); + case B3SOIPD_MOD_WCDSC: + value->rValue = model->B3SOIPDwcdsc; + return (OK); + case B3SOIPD_MOD_WCDSCB: + value->rValue = model->B3SOIPDwcdscb; + return (OK); + case B3SOIPD_MOD_WCDSCD: + value->rValue = model->B3SOIPDwcdscd; + return (OK); + case B3SOIPD_MOD_WPCLM: + value->rValue = model->B3SOIPDwpclm; + return (OK); + case B3SOIPD_MOD_WPDIBL1: + value->rValue = model->B3SOIPDwpdibl1; + return (OK); + case B3SOIPD_MOD_WPDIBL2: + value->rValue = model->B3SOIPDwpdibl2; + return (OK); + case B3SOIPD_MOD_WPDIBLB: + value->rValue = model->B3SOIPDwpdiblb; + return (OK); + case B3SOIPD_MOD_WDROUT: + value->rValue = model->B3SOIPDwdrout; + return (OK); + case B3SOIPD_MOD_WPVAG: + value->rValue = model->B3SOIPDwpvag; + return (OK); + case B3SOIPD_MOD_WDELTA: + value->rValue = model->B3SOIPDwdelta; + return (OK); + case B3SOIPD_MOD_WALPHA0: + value->rValue = model->B3SOIPDwalpha0; + return (OK); + case B3SOIPD_MOD_WFBJTII: + value->rValue = model->B3SOIPDwfbjtii; + return (OK); + case B3SOIPD_MOD_WBETA0: + value->rValue = model->B3SOIPDwbeta0; + return (OK); + case B3SOIPD_MOD_WBETA1: + value->rValue = model->B3SOIPDwbeta1; + return (OK); + case B3SOIPD_MOD_WBETA2: + value->rValue = model->B3SOIPDwbeta2; + return (OK); + case B3SOIPD_MOD_WVDSATII0: + value->rValue = model->B3SOIPDwvdsatii0; + return (OK); + case B3SOIPD_MOD_WLII: + value->rValue = model->B3SOIPDwlii; + return (OK); + case B3SOIPD_MOD_WESATII: + value->rValue = model->B3SOIPDwesatii; + return (OK); + case B3SOIPD_MOD_WSII0: + value->rValue = model->B3SOIPDwsii0; + return (OK); + case B3SOIPD_MOD_WSII1: + value->rValue = model->B3SOIPDwsii1; + return (OK); + case B3SOIPD_MOD_WSII2: + value->rValue = model->B3SOIPDwsii2; + return (OK); + case B3SOIPD_MOD_WSIID: + value->rValue = model->B3SOIPDwsiid; + return (OK); + case B3SOIPD_MOD_WAGIDL: + value->rValue = model->B3SOIPDwagidl; + return (OK); + case B3SOIPD_MOD_WBGIDL: + value->rValue = model->B3SOIPDwbgidl; + return (OK); + case B3SOIPD_MOD_WNGIDL: + value->rValue = model->B3SOIPDwngidl; + return (OK); + case B3SOIPD_MOD_WNTUN: + value->rValue = model->B3SOIPDwntun; + return (OK); + case B3SOIPD_MOD_WNDIODE: + value->rValue = model->B3SOIPDwndiode; + return (OK); + case B3SOIPD_MOD_WNRECF0: + value->rValue = model->B3SOIPDwnrecf0; + return (OK); + case B3SOIPD_MOD_WNRECR0: + value->rValue = model->B3SOIPDwnrecr0; + return (OK); + case B3SOIPD_MOD_WISBJT: + value->rValue = model->B3SOIPDwisbjt; + return (OK); + case B3SOIPD_MOD_WISDIF: + value->rValue = model->B3SOIPDwisdif; + return (OK); + case B3SOIPD_MOD_WISREC: + value->rValue = model->B3SOIPDwisrec; + return (OK); + case B3SOIPD_MOD_WISTUN: + value->rValue = model->B3SOIPDwistun; + return (OK); + case B3SOIPD_MOD_WVREC0: + value->rValue = model->B3SOIPDwvrec0; + return (OK); + case B3SOIPD_MOD_WVTUN0: + value->rValue = model->B3SOIPDwvtun0; + return (OK); + case B3SOIPD_MOD_WNBJT: + value->rValue = model->B3SOIPDwnbjt; + return (OK); + case B3SOIPD_MOD_WLBJT0: + value->rValue = model->B3SOIPDwlbjt0; + return (OK); + case B3SOIPD_MOD_WVABJT: + value->rValue = model->B3SOIPDwvabjt; + return (OK); + case B3SOIPD_MOD_WAELY: + value->rValue = model->B3SOIPDwaely; + return (OK); + case B3SOIPD_MOD_WAHLI: + value->rValue = model->B3SOIPDwahli; + return (OK); + /* CV Model */ + case B3SOIPD_MOD_WVSDFB: + value->rValue = model->B3SOIPDwvsdfb; + return (OK); + case B3SOIPD_MOD_WVSDTH: + value->rValue = model->B3SOIPDwvsdth; + return (OK); + case B3SOIPD_MOD_WDELVT: + value->rValue = model->B3SOIPDwdelvt; + return (OK); + case B3SOIPD_MOD_WACDE: + value->rValue = model->B3SOIPDwacde; + return (OK); + case B3SOIPD_MOD_WMOIN: + value->rValue = model->B3SOIPDwmoin; + return (OK); + + /* Cross-term Dependence */ + case B3SOIPD_MOD_PNPEAK: + value->rValue = model->B3SOIPDpnpeak; + return (OK); + case B3SOIPD_MOD_PNSUB: + value->rValue = model->B3SOIPDpnsub; + return (OK); + case B3SOIPD_MOD_PNGATE: + value->rValue = model->B3SOIPDpngate; + return (OK); + case B3SOIPD_MOD_PVTH0: + value->rValue = model->B3SOIPDpvth0; + return (OK); + case B3SOIPD_MOD_PK1: + value->rValue = model->B3SOIPDpk1; + return (OK); + case B3SOIPD_MOD_PK1W1: + value->rValue = model->B3SOIPDpk1w1; + return (OK); + case B3SOIPD_MOD_PK1W2: + value->rValue = model->B3SOIPDpk1w2; + return (OK); + case B3SOIPD_MOD_PK2: + value->rValue = model->B3SOIPDpk2; + return (OK); + case B3SOIPD_MOD_PK3: + value->rValue = model->B3SOIPDpk3; + return (OK); + case B3SOIPD_MOD_PK3B: + value->rValue = model->B3SOIPDpk3b; + return (OK); + case B3SOIPD_MOD_PKB1: + value->rValue = model->B3SOIPDpkb1; + return (OK); + case B3SOIPD_MOD_PW0: + value->rValue = model->B3SOIPDpw0; + return (OK); + case B3SOIPD_MOD_PNLX: + value->rValue = model->B3SOIPDpnlx; + return (OK); + case B3SOIPD_MOD_PDVT0: + value->rValue = model->B3SOIPDpdvt0; + return (OK); + case B3SOIPD_MOD_PDVT1: + value->rValue = model->B3SOIPDpdvt1; + return (OK); + case B3SOIPD_MOD_PDVT2: + value->rValue = model->B3SOIPDpdvt2; + return (OK); + case B3SOIPD_MOD_PDVT0W: + value->rValue = model->B3SOIPDpdvt0w; + return (OK); + case B3SOIPD_MOD_PDVT1W: + value->rValue = model->B3SOIPDpdvt1w; + return (OK); + case B3SOIPD_MOD_PDVT2W: + value->rValue = model->B3SOIPDpdvt2w; + return (OK); + case B3SOIPD_MOD_PU0: + value->rValue = model->B3SOIPDpu0; + return (OK); + case B3SOIPD_MOD_PUA: + value->rValue = model->B3SOIPDpua; + return (OK); + case B3SOIPD_MOD_PUB: + value->rValue = model->B3SOIPDpub; + return (OK); + case B3SOIPD_MOD_PUC: + value->rValue = model->B3SOIPDpuc; + return (OK); + case B3SOIPD_MOD_PVSAT: + value->rValue = model->B3SOIPDpvsat; + return (OK); + case B3SOIPD_MOD_PA0: + value->rValue = model->B3SOIPDpa0; + return (OK); + case B3SOIPD_MOD_PAGS: + value->rValue = model->B3SOIPDpags; + return (OK); + case B3SOIPD_MOD_PB0: + value->rValue = model->B3SOIPDpb0; + return (OK); + case B3SOIPD_MOD_PB1: + value->rValue = model->B3SOIPDpb1; + return (OK); + case B3SOIPD_MOD_PKETA: + value->rValue = model->B3SOIPDpketa; + return (OK); + case B3SOIPD_MOD_PKETAS: + value->rValue = model->B3SOIPDpketas; + return (OK); + case B3SOIPD_MOD_PA1: + value->rValue = model->B3SOIPDpa1; + return (OK); + case B3SOIPD_MOD_PA2: + value->rValue = model->B3SOIPDpa2; + return (OK); + case B3SOIPD_MOD_PRDSW: + value->rValue = model->B3SOIPDprdsw; + return (OK); + case B3SOIPD_MOD_PPRWB: + value->rValue = model->B3SOIPDpprwb; + return (OK); + case B3SOIPD_MOD_PPRWG: + value->rValue = model->B3SOIPDpprwg; + return (OK); + case B3SOIPD_MOD_PWR: + value->rValue = model->B3SOIPDpwr; + return (OK); + case B3SOIPD_MOD_PNFACTOR: + value->rValue = model->B3SOIPDpnfactor; + return (OK); + case B3SOIPD_MOD_PDWG: + value->rValue = model->B3SOIPDpdwg; + return (OK); + case B3SOIPD_MOD_PDWB: + value->rValue = model->B3SOIPDpdwb; + return (OK); + case B3SOIPD_MOD_PVOFF: + value->rValue = model->B3SOIPDpvoff; + return (OK); + case B3SOIPD_MOD_PETA0: + value->rValue = model->B3SOIPDpeta0; + return (OK); + case B3SOIPD_MOD_PETAB: + value->rValue = model->B3SOIPDpetab; + return (OK); + case B3SOIPD_MOD_PDSUB: + value->rValue = model->B3SOIPDpdsub; + return (OK); + case B3SOIPD_MOD_PCIT: + value->rValue = model->B3SOIPDpcit; + return (OK); + case B3SOIPD_MOD_PCDSC: + value->rValue = model->B3SOIPDpcdsc; + return (OK); + case B3SOIPD_MOD_PCDSCB: + value->rValue = model->B3SOIPDpcdscb; + return (OK); + case B3SOIPD_MOD_PCDSCD: + value->rValue = model->B3SOIPDpcdscd; + return (OK); + case B3SOIPD_MOD_PPCLM: + value->rValue = model->B3SOIPDppclm; + return (OK); + case B3SOIPD_MOD_PPDIBL1: + value->rValue = model->B3SOIPDppdibl1; + return (OK); + case B3SOIPD_MOD_PPDIBL2: + value->rValue = model->B3SOIPDppdibl2; + return (OK); + case B3SOIPD_MOD_PPDIBLB: + value->rValue = model->B3SOIPDppdiblb; + return (OK); + case B3SOIPD_MOD_PDROUT: + value->rValue = model->B3SOIPDpdrout; + return (OK); + case B3SOIPD_MOD_PPVAG: + value->rValue = model->B3SOIPDppvag; + return (OK); + case B3SOIPD_MOD_PDELTA: + value->rValue = model->B3SOIPDpdelta; + return (OK); + case B3SOIPD_MOD_PALPHA0: + value->rValue = model->B3SOIPDpalpha0; + return (OK); + case B3SOIPD_MOD_PFBJTII: + value->rValue = model->B3SOIPDpfbjtii; + return (OK); + case B3SOIPD_MOD_PBETA0: + value->rValue = model->B3SOIPDpbeta0; + return (OK); + case B3SOIPD_MOD_PBETA1: + value->rValue = model->B3SOIPDpbeta1; + return (OK); + case B3SOIPD_MOD_PBETA2: + value->rValue = model->B3SOIPDpbeta2; + return (OK); + case B3SOIPD_MOD_PVDSATII0: + value->rValue = model->B3SOIPDpvdsatii0; + return (OK); + case B3SOIPD_MOD_PLII: + value->rValue = model->B3SOIPDplii; + return (OK); + case B3SOIPD_MOD_PESATII: + value->rValue = model->B3SOIPDpesatii; + return (OK); + case B3SOIPD_MOD_PSII0: + value->rValue = model->B3SOIPDpsii0; + return (OK); + case B3SOIPD_MOD_PSII1: + value->rValue = model->B3SOIPDpsii1; + return (OK); + case B3SOIPD_MOD_PSII2: + value->rValue = model->B3SOIPDpsii2; + return (OK); + case B3SOIPD_MOD_PSIID: + value->rValue = model->B3SOIPDpsiid; + return (OK); + case B3SOIPD_MOD_PAGIDL: + value->rValue = model->B3SOIPDpagidl; + return (OK); + case B3SOIPD_MOD_PBGIDL: + value->rValue = model->B3SOIPDpbgidl; + return (OK); + case B3SOIPD_MOD_PNGIDL: + value->rValue = model->B3SOIPDpngidl; + return (OK); + case B3SOIPD_MOD_PNTUN: + value->rValue = model->B3SOIPDpntun; + return (OK); + case B3SOIPD_MOD_PNDIODE: + value->rValue = model->B3SOIPDpndiode; + return (OK); + case B3SOIPD_MOD_PNRECF0: + value->rValue = model->B3SOIPDpnrecf0; + return (OK); + case B3SOIPD_MOD_PNRECR0: + value->rValue = model->B3SOIPDpnrecr0; + return (OK); + case B3SOIPD_MOD_PISBJT: + value->rValue = model->B3SOIPDpisbjt; + return (OK); + case B3SOIPD_MOD_PISDIF: + value->rValue = model->B3SOIPDpisdif; + return (OK); + case B3SOIPD_MOD_PISREC: + value->rValue = model->B3SOIPDpisrec; + return (OK); + case B3SOIPD_MOD_PISTUN: + value->rValue = model->B3SOIPDpistun; + return (OK); + case B3SOIPD_MOD_PVREC0: + value->rValue = model->B3SOIPDpvrec0; + return (OK); + case B3SOIPD_MOD_PVTUN0: + value->rValue = model->B3SOIPDpvtun0; + return (OK); + case B3SOIPD_MOD_PNBJT: + value->rValue = model->B3SOIPDpnbjt; + return (OK); + case B3SOIPD_MOD_PLBJT0: + value->rValue = model->B3SOIPDplbjt0; + return (OK); + case B3SOIPD_MOD_PVABJT: + value->rValue = model->B3SOIPDpvabjt; + return (OK); + case B3SOIPD_MOD_PAELY: + value->rValue = model->B3SOIPDpaely; + return (OK); + case B3SOIPD_MOD_PAHLI: + value->rValue = model->B3SOIPDpahli; + return (OK); + /* CV Model */ + case B3SOIPD_MOD_PVSDFB: + value->rValue = model->B3SOIPDpvsdfb; + return (OK); + case B3SOIPD_MOD_PVSDTH: + value->rValue = model->B3SOIPDpvsdth; + return (OK); + case B3SOIPD_MOD_PDELVT: + value->rValue = model->B3SOIPDpdelvt; + return (OK); + case B3SOIPD_MOD_PACDE: + value->rValue = model->B3SOIPDpacde; + return (OK); + case B3SOIPD_MOD_PMOIN: + value->rValue = model->B3SOIPDpmoin; + return (OK); +/* Added for binning - END */ + + default: + return (E_BADPARM); + } + /* NOTREACHED */ +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdmdel.c b/src/spicelib/devices/bsim3soi_pd/b3soipdmdel.c new file mode 100644 index 000000000..8e4b62c43 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdmdel.c @@ -0,0 +1,49 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipdmdel.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "b3soipddef.h" +#include "sperror.h" +#include "suffix.h" + +int +B3SOIPDmDelete (inModel, modname, kill) + GENmodel **inModel; + IFuid modname; + GENmodel *kill; +{ + B3SOIPDmodel **model = (B3SOIPDmodel **) inModel; + B3SOIPDmodel *modfast = (B3SOIPDmodel *) kill; + B3SOIPDinstance *here; + B3SOIPDinstance *prev = NULL; + B3SOIPDmodel **oldmod; + + oldmod = model; + for (; *model; model = &((*model)->B3SOIPDnextModel)) + { + if ((*model)->B3SOIPDmodName == modname || + (modfast && *model == modfast)) + goto delgot; + oldmod = model; + } + return (E_NOMOD); + +delgot: + *oldmod = (*model)->B3SOIPDnextModel; /* cut deleted device out of list */ + for (here = (*model)->B3SOIPDinstances; here; + here = here->B3SOIPDnextInstance) + { + if (prev) + FREE (prev); + prev = here; + } + if (prev) + FREE (prev); + FREE (*model); + return (OK); +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdmpar.c b/src/spicelib/devices/bsim3soi_pd/b3soipdmpar.c new file mode 100644 index 000000000..6913d7665 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdmpar.c @@ -0,0 +1,1917 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipdmpar.c 98/5/01 +Modified by Pin Su and Jan Feng 99/2/15 +Modified by Pin Su 99/4/30 +Modified by Wei Jin 99/9/27 +Modified by Pin Su 00/3/1 +**********/ + + +#include "ngspice.h" +#include +#include "b3soipddef.h" +#include "ifsim.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIPDmParam (param, value, inMod) + int param; + IFvalue *value; + GENmodel *inMod; +{ + B3SOIPDmodel *mod = (B3SOIPDmodel *) inMod; + switch (param) + { + + case B3SOIPD_MOD_MOBMOD: + mod->B3SOIPDmobMod = value->iValue; + mod->B3SOIPDmobModGiven = TRUE; + break; + case B3SOIPD_MOD_BINUNIT: + mod->B3SOIPDbinUnit = value->iValue; + mod->B3SOIPDbinUnitGiven = TRUE; + break; + case B3SOIPD_MOD_PARAMCHK: + mod->B3SOIPDparamChk = value->iValue; + mod->B3SOIPDparamChkGiven = TRUE; + break; + case B3SOIPD_MOD_CAPMOD: + mod->B3SOIPDcapMod = value->iValue; + mod->B3SOIPDcapModGiven = TRUE; + break; + case B3SOIPD_MOD_SHMOD: + mod->B3SOIPDshMod = value->iValue; + mod->B3SOIPDshModGiven = TRUE; + break; + case B3SOIPD_MOD_NOIMOD: + mod->B3SOIPDnoiMod = value->iValue; + mod->B3SOIPDnoiModGiven = TRUE; + break; + case B3SOIPD_MOD_VERSION: + mod->B3SOIPDversion = value->rValue; + mod->B3SOIPDversionGiven = TRUE; + break; + case B3SOIPD_MOD_TOX: + mod->B3SOIPDtox = value->rValue; + mod->B3SOIPDtoxGiven = TRUE; + break; + + case B3SOIPD_MOD_CDSC: + mod->B3SOIPDcdsc = value->rValue; + mod->B3SOIPDcdscGiven = TRUE; + break; + case B3SOIPD_MOD_CDSCB: + mod->B3SOIPDcdscb = value->rValue; + mod->B3SOIPDcdscbGiven = TRUE; + break; + + case B3SOIPD_MOD_CDSCD: + mod->B3SOIPDcdscd = value->rValue; + mod->B3SOIPDcdscdGiven = TRUE; + break; + + case B3SOIPD_MOD_CIT: + mod->B3SOIPDcit = value->rValue; + mod->B3SOIPDcitGiven = TRUE; + break; + case B3SOIPD_MOD_NFACTOR: + mod->B3SOIPDnfactor = value->rValue; + mod->B3SOIPDnfactorGiven = TRUE; + break; + case B3SOIPD_MOD_VSAT: + mod->B3SOIPDvsat = value->rValue; + mod->B3SOIPDvsatGiven = TRUE; + break; + case B3SOIPD_MOD_A0: + mod->B3SOIPDa0 = value->rValue; + mod->B3SOIPDa0Given = TRUE; + break; + + case B3SOIPD_MOD_AGS: + mod->B3SOIPDags = value->rValue; + mod->B3SOIPDagsGiven = TRUE; + break; + + case B3SOIPD_MOD_A1: + mod->B3SOIPDa1 = value->rValue; + mod->B3SOIPDa1Given = TRUE; + break; + case B3SOIPD_MOD_A2: + mod->B3SOIPDa2 = value->rValue; + mod->B3SOIPDa2Given = TRUE; + break; + case B3SOIPD_MOD_AT: + mod->B3SOIPDat = value->rValue; + mod->B3SOIPDatGiven = TRUE; + break; + case B3SOIPD_MOD_KETA: + mod->B3SOIPDketa = value->rValue; + mod->B3SOIPDketaGiven = TRUE; + break; + case B3SOIPD_MOD_NSUB: + mod->B3SOIPDnsub = value->rValue; + mod->B3SOIPDnsubGiven = TRUE; + break; + case B3SOIPD_MOD_NPEAK: + mod->B3SOIPDnpeak = value->rValue; + mod->B3SOIPDnpeakGiven = TRUE; + if (mod->B3SOIPDnpeak > 1.0e20) + mod->B3SOIPDnpeak *= 1.0e-6; + break; + case B3SOIPD_MOD_NGATE: + mod->B3SOIPDngate = value->rValue; + mod->B3SOIPDngateGiven = TRUE; + if (mod->B3SOIPDngate > 1.0e23) + mod->B3SOIPDngate *= 1.0e-6; + break; + case B3SOIPD_MOD_GAMMA1: + mod->B3SOIPDgamma1 = value->rValue; + mod->B3SOIPDgamma1Given = TRUE; + break; + case B3SOIPD_MOD_GAMMA2: + mod->B3SOIPDgamma2 = value->rValue; + mod->B3SOIPDgamma2Given = TRUE; + break; + case B3SOIPD_MOD_VBX: + mod->B3SOIPDvbx = value->rValue; + mod->B3SOIPDvbxGiven = TRUE; + break; + case B3SOIPD_MOD_VBM: + mod->B3SOIPDvbm = value->rValue; + mod->B3SOIPDvbmGiven = TRUE; + break; + case B3SOIPD_MOD_XT: + mod->B3SOIPDxt = value->rValue; + mod->B3SOIPDxtGiven = TRUE; + break; + case B3SOIPD_MOD_K1: + mod->B3SOIPDk1 = value->rValue; + mod->B3SOIPDk1Given = TRUE; + break; + case B3SOIPD_MOD_KT1: + mod->B3SOIPDkt1 = value->rValue; + mod->B3SOIPDkt1Given = TRUE; + break; + case B3SOIPD_MOD_KT1L: + mod->B3SOIPDkt1l = value->rValue; + mod->B3SOIPDkt1lGiven = TRUE; + break; + case B3SOIPD_MOD_KT2: + mod->B3SOIPDkt2 = value->rValue; + mod->B3SOIPDkt2Given = TRUE; + break; + case B3SOIPD_MOD_K2: + mod->B3SOIPDk2 = value->rValue; + mod->B3SOIPDk2Given = TRUE; + break; + case B3SOIPD_MOD_K3: + mod->B3SOIPDk3 = value->rValue; + mod->B3SOIPDk3Given = TRUE; + break; + case B3SOIPD_MOD_K3B: + mod->B3SOIPDk3b = value->rValue; + mod->B3SOIPDk3bGiven = TRUE; + break; + case B3SOIPD_MOD_NLX: + mod->B3SOIPDnlx = value->rValue; + mod->B3SOIPDnlxGiven = TRUE; + break; + case B3SOIPD_MOD_W0: + mod->B3SOIPDw0 = value->rValue; + mod->B3SOIPDw0Given = TRUE; + break; + case B3SOIPD_MOD_DVT0: + mod->B3SOIPDdvt0 = value->rValue; + mod->B3SOIPDdvt0Given = TRUE; + break; + case B3SOIPD_MOD_DVT1: + mod->B3SOIPDdvt1 = value->rValue; + mod->B3SOIPDdvt1Given = TRUE; + break; + case B3SOIPD_MOD_DVT2: + mod->B3SOIPDdvt2 = value->rValue; + mod->B3SOIPDdvt2Given = TRUE; + break; + case B3SOIPD_MOD_DVT0W: + mod->B3SOIPDdvt0w = value->rValue; + mod->B3SOIPDdvt0wGiven = TRUE; + break; + case B3SOIPD_MOD_DVT1W: + mod->B3SOIPDdvt1w = value->rValue; + mod->B3SOIPDdvt1wGiven = TRUE; + break; + case B3SOIPD_MOD_DVT2W: + mod->B3SOIPDdvt2w = value->rValue; + mod->B3SOIPDdvt2wGiven = TRUE; + break; + case B3SOIPD_MOD_DROUT: + mod->B3SOIPDdrout = value->rValue; + mod->B3SOIPDdroutGiven = TRUE; + break; + case B3SOIPD_MOD_DSUB: + mod->B3SOIPDdsub = value->rValue; + mod->B3SOIPDdsubGiven = TRUE; + break; + case B3SOIPD_MOD_VTH0: + mod->B3SOIPDvth0 = value->rValue; + mod->B3SOIPDvth0Given = TRUE; + break; + case B3SOIPD_MOD_UA: + mod->B3SOIPDua = value->rValue; + mod->B3SOIPDuaGiven = TRUE; + break; + case B3SOIPD_MOD_UA1: + mod->B3SOIPDua1 = value->rValue; + mod->B3SOIPDua1Given = TRUE; + break; + case B3SOIPD_MOD_UB: + mod->B3SOIPDub = value->rValue; + mod->B3SOIPDubGiven = TRUE; + break; + case B3SOIPD_MOD_UB1: + mod->B3SOIPDub1 = value->rValue; + mod->B3SOIPDub1Given = TRUE; + break; + case B3SOIPD_MOD_UC: + mod->B3SOIPDuc = value->rValue; + mod->B3SOIPDucGiven = TRUE; + break; + case B3SOIPD_MOD_UC1: + mod->B3SOIPDuc1 = value->rValue; + mod->B3SOIPDuc1Given = TRUE; + break; + case B3SOIPD_MOD_U0: + mod->B3SOIPDu0 = value->rValue; + mod->B3SOIPDu0Given = TRUE; + break; + case B3SOIPD_MOD_UTE: + mod->B3SOIPDute = value->rValue; + mod->B3SOIPDuteGiven = TRUE; + break; + case B3SOIPD_MOD_VOFF: + mod->B3SOIPDvoff = value->rValue; + mod->B3SOIPDvoffGiven = TRUE; + break; + case B3SOIPD_MOD_DELTA: + mod->B3SOIPDdelta = value->rValue; + mod->B3SOIPDdeltaGiven = TRUE; + break; + case B3SOIPD_MOD_RDSW: + mod->B3SOIPDrdsw = value->rValue; + mod->B3SOIPDrdswGiven = TRUE; + break; + case B3SOIPD_MOD_PRWG: + mod->B3SOIPDprwg = value->rValue; + mod->B3SOIPDprwgGiven = TRUE; + break; + case B3SOIPD_MOD_PRWB: + mod->B3SOIPDprwb = value->rValue; + mod->B3SOIPDprwbGiven = TRUE; + break; + case B3SOIPD_MOD_PRT: + mod->B3SOIPDprt = value->rValue; + mod->B3SOIPDprtGiven = TRUE; + break; + case B3SOIPD_MOD_ETA0: + mod->B3SOIPDeta0 = value->rValue; + mod->B3SOIPDeta0Given = TRUE; + break; + case B3SOIPD_MOD_ETAB: + mod->B3SOIPDetab = value->rValue; + mod->B3SOIPDetabGiven = TRUE; + break; + case B3SOIPD_MOD_PCLM: + mod->B3SOIPDpclm = value->rValue; + mod->B3SOIPDpclmGiven = TRUE; + break; + case B3SOIPD_MOD_PDIBL1: + mod->B3SOIPDpdibl1 = value->rValue; + mod->B3SOIPDpdibl1Given = TRUE; + break; + case B3SOIPD_MOD_PDIBL2: + mod->B3SOIPDpdibl2 = value->rValue; + mod->B3SOIPDpdibl2Given = TRUE; + break; + case B3SOIPD_MOD_PDIBLB: + mod->B3SOIPDpdiblb = value->rValue; + mod->B3SOIPDpdiblbGiven = TRUE; + break; + case B3SOIPD_MOD_PVAG: + mod->B3SOIPDpvag = value->rValue; + mod->B3SOIPDpvagGiven = TRUE; + break; + case B3SOIPD_MOD_WR: + mod->B3SOIPDwr = value->rValue; + mod->B3SOIPDwrGiven = TRUE; + break; + case B3SOIPD_MOD_DWG: + mod->B3SOIPDdwg = value->rValue; + mod->B3SOIPDdwgGiven = TRUE; + break; + case B3SOIPD_MOD_DWB: + mod->B3SOIPDdwb = value->rValue; + mod->B3SOIPDdwbGiven = TRUE; + break; + case B3SOIPD_MOD_B0: + mod->B3SOIPDb0 = value->rValue; + mod->B3SOIPDb0Given = TRUE; + break; + case B3SOIPD_MOD_B1: + mod->B3SOIPDb1 = value->rValue; + mod->B3SOIPDb1Given = TRUE; + break; + case B3SOIPD_MOD_ALPHA0: + mod->B3SOIPDalpha0 = value->rValue; + mod->B3SOIPDalpha0Given = TRUE; + break; + + case B3SOIPD_MOD_CGSL: + mod->B3SOIPDcgsl = value->rValue; + mod->B3SOIPDcgslGiven = TRUE; + break; + case B3SOIPD_MOD_CGDL: + mod->B3SOIPDcgdl = value->rValue; + mod->B3SOIPDcgdlGiven = TRUE; + break; + case B3SOIPD_MOD_CKAPPA: + mod->B3SOIPDckappa = value->rValue; + mod->B3SOIPDckappaGiven = TRUE; + break; + case B3SOIPD_MOD_CF: + mod->B3SOIPDcf = value->rValue; + mod->B3SOIPDcfGiven = TRUE; + break; + case B3SOIPD_MOD_CLC: + mod->B3SOIPDclc = value->rValue; + mod->B3SOIPDclcGiven = TRUE; + break; + case B3SOIPD_MOD_CLE: + mod->B3SOIPDcle = value->rValue; + mod->B3SOIPDcleGiven = TRUE; + break; + case B3SOIPD_MOD_DWC: + mod->B3SOIPDdwc = value->rValue; + mod->B3SOIPDdwcGiven = TRUE; + break; + case B3SOIPD_MOD_DLC: + mod->B3SOIPDdlc = value->rValue; + mod->B3SOIPDdlcGiven = TRUE; + break; + case B3SOIPD_MOD_TBOX: + mod->B3SOIPDtbox = value->rValue; + mod->B3SOIPDtboxGiven = TRUE; + break; + case B3SOIPD_MOD_TSI: + mod->B3SOIPDtsi = value->rValue; + mod->B3SOIPDtsiGiven = TRUE; + break; + case B3SOIPD_MOD_XJ: + mod->B3SOIPDxj = value->rValue; + mod->B3SOIPDxjGiven = TRUE; + break; + case B3SOIPD_MOD_RBODY: + mod->B3SOIPDrbody = value->rValue; + mod->B3SOIPDrbodyGiven = TRUE; + break; + case B3SOIPD_MOD_RBSH: + mod->B3SOIPDrbsh = value->rValue; + mod->B3SOIPDrbshGiven = TRUE; + break; + case B3SOIPD_MOD_RTH0: + mod->B3SOIPDrth0 = value->rValue; + mod->B3SOIPDrth0Given = TRUE; + break; + case B3SOIPD_MOD_CTH0: + mod->B3SOIPDcth0 = value->rValue; + mod->B3SOIPDcth0Given = TRUE; + break; + case B3SOIPD_MOD_NGIDL: + mod->B3SOIPDngidl = value->rValue; + mod->B3SOIPDngidlGiven = TRUE; + break; + case B3SOIPD_MOD_AGIDL: + mod->B3SOIPDagidl = value->rValue; + mod->B3SOIPDagidlGiven = TRUE; + break; + case B3SOIPD_MOD_BGIDL: + mod->B3SOIPDbgidl = value->rValue; + mod->B3SOIPDbgidlGiven = TRUE; + break; + case B3SOIPD_MOD_NDIODE: + mod->B3SOIPDndiode = value->rValue; + mod->B3SOIPDndiodeGiven = TRUE; + break; + case B3SOIPD_MOD_XBJT: + mod->B3SOIPDxbjt = value->rValue; + mod->B3SOIPDxbjtGiven = TRUE; + break; + + case B3SOIPD_MOD_XDIF: + mod->B3SOIPDxdif = value->rValue; + mod->B3SOIPDxdifGiven = TRUE; + break; + + case B3SOIPD_MOD_XREC: + mod->B3SOIPDxrec = value->rValue; + mod->B3SOIPDxrecGiven = TRUE; + break; + case B3SOIPD_MOD_XTUN: + mod->B3SOIPDxtun = value->rValue; + mod->B3SOIPDxtunGiven = TRUE; + break; + case B3SOIPD_MOD_TT: + mod->B3SOIPDtt = value->rValue; + mod->B3SOIPDttGiven = TRUE; + break; + case B3SOIPD_MOD_VSDTH: + mod->B3SOIPDvsdth = value->rValue; + mod->B3SOIPDvsdthGiven = TRUE; + break; + case B3SOIPD_MOD_VSDFB: + mod->B3SOIPDvsdfb = value->rValue; + mod->B3SOIPDvsdfbGiven = TRUE; + break; + case B3SOIPD_MOD_CSDMIN: + mod->B3SOIPDcsdmin = value->rValue; + mod->B3SOIPDcsdminGiven = TRUE; + break; + case B3SOIPD_MOD_ASD: + mod->B3SOIPDasd = value->rValue; + mod->B3SOIPDasdGiven = TRUE; + break; + + + case B3SOIPD_MOD_TNOM: + mod->B3SOIPDtnom = value->rValue + 273.15; + mod->B3SOIPDtnomGiven = TRUE; + break; + case B3SOIPD_MOD_CGSO: + mod->B3SOIPDcgso = value->rValue; + mod->B3SOIPDcgsoGiven = TRUE; + break; + case B3SOIPD_MOD_CGDO: + mod->B3SOIPDcgdo = value->rValue; + mod->B3SOIPDcgdoGiven = TRUE; + break; + case B3SOIPD_MOD_CGEO: + mod->B3SOIPDcgeo = value->rValue; + mod->B3SOIPDcgeoGiven = TRUE; + break; + case B3SOIPD_MOD_XPART: + mod->B3SOIPDxpart = value->rValue; + mod->B3SOIPDxpartGiven = TRUE; + break; + case B3SOIPD_MOD_RSH: + mod->B3SOIPDsheetResistance = value->rValue; + mod->B3SOIPDsheetResistanceGiven = TRUE; + break; + case B3SOIPD_MOD_PBSWG: + mod->B3SOIPDGatesidewallJctPotential = value->rValue; + mod->B3SOIPDGatesidewallJctPotentialGiven = TRUE; + break; + case B3SOIPD_MOD_MJSWG: + mod->B3SOIPDbodyJctGateSideGradingCoeff = value->rValue; + mod->B3SOIPDbodyJctGateSideGradingCoeffGiven = TRUE; + break; + case B3SOIPD_MOD_CJSWG: + mod->B3SOIPDunitLengthGateSidewallJctCap = value->rValue; + mod->B3SOIPDunitLengthGateSidewallJctCapGiven = TRUE; + break; + case B3SOIPD_MOD_CSDESW: + mod->B3SOIPDcsdesw = value->rValue; + mod->B3SOIPDcsdeswGiven = TRUE; + break; + case B3SOIPD_MOD_LINT: + mod->B3SOIPDLint = value->rValue; + mod->B3SOIPDLintGiven = TRUE; + break; + case B3SOIPD_MOD_LL: + mod->B3SOIPDLl = value->rValue; + mod->B3SOIPDLlGiven = TRUE; + break; + case B3SOIPD_MOD_LLN: + mod->B3SOIPDLln = value->rValue; + mod->B3SOIPDLlnGiven = TRUE; + break; + case B3SOIPD_MOD_LW: + mod->B3SOIPDLw = value->rValue; + mod->B3SOIPDLwGiven = TRUE; + break; + case B3SOIPD_MOD_LWN: + mod->B3SOIPDLwn = value->rValue; + mod->B3SOIPDLwnGiven = TRUE; + break; + case B3SOIPD_MOD_LWL: + mod->B3SOIPDLwl = value->rValue; + mod->B3SOIPDLwlGiven = TRUE; + break; + case B3SOIPD_MOD_WINT: + mod->B3SOIPDWint = value->rValue; + mod->B3SOIPDWintGiven = TRUE; + break; + case B3SOIPD_MOD_WL: + mod->B3SOIPDWl = value->rValue; + mod->B3SOIPDWlGiven = TRUE; + break; + case B3SOIPD_MOD_WLN: + mod->B3SOIPDWln = value->rValue; + mod->B3SOIPDWlnGiven = TRUE; + break; + case B3SOIPD_MOD_WW: + mod->B3SOIPDWw = value->rValue; + mod->B3SOIPDWwGiven = TRUE; + break; + case B3SOIPD_MOD_WWN: + mod->B3SOIPDWwn = value->rValue; + mod->B3SOIPDWwnGiven = TRUE; + break; + case B3SOIPD_MOD_WWL: + mod->B3SOIPDWwl = value->rValue; + mod->B3SOIPDWwlGiven = TRUE; + break; + + case B3SOIPD_MOD_NOIA: + mod->B3SOIPDoxideTrapDensityA = value->rValue; + mod->B3SOIPDoxideTrapDensityAGiven = TRUE; + break; + case B3SOIPD_MOD_NOIB: + mod->B3SOIPDoxideTrapDensityB = value->rValue; + mod->B3SOIPDoxideTrapDensityBGiven = TRUE; + break; + case B3SOIPD_MOD_NOIC: + mod->B3SOIPDoxideTrapDensityC = value->rValue; + mod->B3SOIPDoxideTrapDensityCGiven = TRUE; + break; + case B3SOIPD_MOD_NOIF: + mod->B3SOIPDnoif = value->rValue; + mod->B3SOIPDnoifGiven = TRUE; + break; + case B3SOIPD_MOD_EM: + mod->B3SOIPDem = value->rValue; + mod->B3SOIPDemGiven = TRUE; + break; + case B3SOIPD_MOD_EF: + mod->B3SOIPDef = value->rValue; + mod->B3SOIPDefGiven = TRUE; + break; + case B3SOIPD_MOD_AF: + mod->B3SOIPDaf = value->rValue; + mod->B3SOIPDafGiven = TRUE; + break; + case B3SOIPD_MOD_KF: + mod->B3SOIPDkf = value->rValue; + mod->B3SOIPDkfGiven = TRUE; + break; + + +/* v2.2 release */ + case B3SOIPD_MOD_WTH0: + mod->B3SOIPDwth0 = value->rValue; + mod->B3SOIPDwth0Given = TRUE; + break; + case B3SOIPD_MOD_RHALO: + mod->B3SOIPDrhalo = value->rValue; + mod->B3SOIPDrhaloGiven = TRUE; + break; + case B3SOIPD_MOD_NTOX: + mod->B3SOIPDntox = value->rValue; + mod->B3SOIPDntoxGiven = TRUE; + break; + case B3SOIPD_MOD_TOXREF: + mod->B3SOIPDtoxref = value->rValue; + mod->B3SOIPDtoxrefGiven = TRUE; + break; + case B3SOIPD_MOD_EBG: + mod->B3SOIPDebg = value->rValue; + mod->B3SOIPDebgGiven = TRUE; + break; + case B3SOIPD_MOD_NEVB: + mod->B3SOIPDnevb = value->rValue; + mod->B3SOIPDnevbGiven = TRUE; + break; + case B3SOIPD_MOD_ALPHAGB1: + mod->B3SOIPDalphaGB1 = value->rValue; + mod->B3SOIPDalphaGB1Given = TRUE; + break; + case B3SOIPD_MOD_BETAGB1: + mod->B3SOIPDbetaGB1 = value->rValue; + mod->B3SOIPDbetaGB1Given = TRUE; + break; + case B3SOIPD_MOD_VGB1: + mod->B3SOIPDvgb1 = value->rValue; + mod->B3SOIPDvgb1Given = TRUE; + break; + case B3SOIPD_MOD_NECB: + mod->B3SOIPDnecb = value->rValue; + mod->B3SOIPDnecbGiven = TRUE; + break; + case B3SOIPD_MOD_ALPHAGB2: + mod->B3SOIPDalphaGB2 = value->rValue; + mod->B3SOIPDalphaGB2Given = TRUE; + break; + case B3SOIPD_MOD_BETAGB2: + mod->B3SOIPDbetaGB2 = value->rValue; + mod->B3SOIPDbetaGB2Given = TRUE; + break; + case B3SOIPD_MOD_VGB2: + mod->B3SOIPDvgb2 = value->rValue; + mod->B3SOIPDvgb2Given = TRUE; + break; + case B3SOIPD_MOD_TOXQM: + mod->B3SOIPDtoxqm = value->rValue; + mod->B3SOIPDtoxqmGiven = TRUE; + break; + case B3SOIPD_MOD_VOXH: + mod->B3SOIPDvoxh = value->rValue; + mod->B3SOIPDvoxhGiven = TRUE; + break; + case B3SOIPD_MOD_DELTAVOX: + mod->B3SOIPDdeltavox = value->rValue; + mod->B3SOIPDdeltavoxGiven = TRUE; + break; + case B3SOIPD_MOD_IGMOD: + mod->B3SOIPDigMod = value->iValue; + mod->B3SOIPDigModGiven = TRUE; + break; + + +/* v2.0 release */ + case B3SOIPD_MOD_K1W1: + mod->B3SOIPDk1w1 = value->rValue; + mod->B3SOIPDk1w1Given = TRUE; + break; + case B3SOIPD_MOD_K1W2: + mod->B3SOIPDk1w2 = value->rValue; + mod->B3SOIPDk1w2Given = TRUE; + break; + case B3SOIPD_MOD_KETAS: + mod->B3SOIPDketas = value->rValue; + mod->B3SOIPDketasGiven = TRUE; + break; + case B3SOIPD_MOD_DWBC: + mod->B3SOIPDdwbc = value->rValue; + mod->B3SOIPDdwbcGiven = TRUE; + break; + case B3SOIPD_MOD_BETA0: + mod->B3SOIPDbeta0 = value->rValue; + mod->B3SOIPDbeta0Given = TRUE; + break; + case B3SOIPD_MOD_BETA1: + mod->B3SOIPDbeta1 = value->rValue; + mod->B3SOIPDbeta1Given = TRUE; + break; + case B3SOIPD_MOD_BETA2: + mod->B3SOIPDbeta2 = value->rValue; + mod->B3SOIPDbeta2Given = TRUE; + break; + case B3SOIPD_MOD_VDSATII0: + mod->B3SOIPDvdsatii0 = value->rValue; + mod->B3SOIPDvdsatii0Given = TRUE; + break; + case B3SOIPD_MOD_TII: + mod->B3SOIPDtii = value->rValue; + mod->B3SOIPDtiiGiven = TRUE; + break; + case B3SOIPD_MOD_LII: + mod->B3SOIPDlii = value->rValue; + mod->B3SOIPDliiGiven = TRUE; + break; + case B3SOIPD_MOD_SII0: + mod->B3SOIPDsii0 = value->rValue; + mod->B3SOIPDsii0Given = TRUE; + break; + case B3SOIPD_MOD_SII1: + mod->B3SOIPDsii1 = value->rValue; + mod->B3SOIPDsii1Given = TRUE; + break; + case B3SOIPD_MOD_SII2: + mod->B3SOIPDsii2 = value->rValue; + mod->B3SOIPDsii2Given = TRUE; + break; + case B3SOIPD_MOD_SIID: + mod->B3SOIPDsiid = value->rValue; + mod->B3SOIPDsiidGiven = TRUE; + break; + case B3SOIPD_MOD_FBJTII: + mod->B3SOIPDfbjtii = value->rValue; + mod->B3SOIPDfbjtiiGiven = TRUE; + break; + case B3SOIPD_MOD_ESATII: + mod->B3SOIPDesatii = value->rValue; + mod->B3SOIPDesatiiGiven = TRUE; + break; + case B3SOIPD_MOD_NTUN: + mod->B3SOIPDntun = value->rValue; + mod->B3SOIPDntunGiven = TRUE; + break; + case B3SOIPD_MOD_NRECF0: + mod->B3SOIPDnrecf0 = value->rValue; + mod->B3SOIPDnrecf0Given = TRUE; + break; + case B3SOIPD_MOD_NRECR0: + mod->B3SOIPDnrecr0 = value->rValue; + mod->B3SOIPDnrecr0Given = TRUE; + break; + case B3SOIPD_MOD_ISBJT: + mod->B3SOIPDisbjt = value->rValue; + mod->B3SOIPDisbjtGiven = TRUE; + break; + case B3SOIPD_MOD_ISDIF: + mod->B3SOIPDisdif = value->rValue; + mod->B3SOIPDisdifGiven = TRUE; + break; + case B3SOIPD_MOD_ISREC: + mod->B3SOIPDisrec = value->rValue; + mod->B3SOIPDisrecGiven = TRUE; + break; + case B3SOIPD_MOD_ISTUN: + mod->B3SOIPDistun = value->rValue; + mod->B3SOIPDistunGiven = TRUE; + break; + case B3SOIPD_MOD_LN: + mod->B3SOIPDln = value->rValue; + mod->B3SOIPDlnGiven = TRUE; + break; + case B3SOIPD_MOD_VREC0: + mod->B3SOIPDvrec0 = value->rValue; + mod->B3SOIPDvrec0Given = TRUE; + break; + case B3SOIPD_MOD_VTUN0: + mod->B3SOIPDvtun0 = value->rValue; + mod->B3SOIPDvtun0Given = TRUE; + break; + case B3SOIPD_MOD_NBJT: + mod->B3SOIPDnbjt = value->rValue; + mod->B3SOIPDnbjtGiven = TRUE; + break; + case B3SOIPD_MOD_LBJT0: + mod->B3SOIPDlbjt0 = value->rValue; + mod->B3SOIPDlbjt0Given = TRUE; + break; + case B3SOIPD_MOD_LDIF0: + mod->B3SOIPDldif0 = value->rValue; + mod->B3SOIPDldif0Given = TRUE; + break; + case B3SOIPD_MOD_VABJT: + mod->B3SOIPDvabjt = value->rValue; + mod->B3SOIPDvabjtGiven = TRUE; + break; + case B3SOIPD_MOD_AELY: + mod->B3SOIPDaely = value->rValue; + mod->B3SOIPDaelyGiven = TRUE; + break; + case B3SOIPD_MOD_AHLI: + mod->B3SOIPDahli = value->rValue; + mod->B3SOIPDahliGiven = TRUE; + break; + case B3SOIPD_MOD_NDIF: + mod->B3SOIPDndif = value->rValue; + mod->B3SOIPDndifGiven = TRUE; + break; + case B3SOIPD_MOD_NTRECF: + mod->B3SOIPDntrecf = value->rValue; + mod->B3SOIPDntrecfGiven = TRUE; + break; + case B3SOIPD_MOD_NTRECR: + mod->B3SOIPDntrecr = value->rValue; + mod->B3SOIPDntrecrGiven = TRUE; + break; + case B3SOIPD_MOD_DLCB: + mod->B3SOIPDdlcb = value->rValue; + mod->B3SOIPDdlcbGiven = TRUE; + break; + case B3SOIPD_MOD_FBODY: + mod->B3SOIPDfbody = value->rValue; + mod->B3SOIPDfbodyGiven = TRUE; + break; + case B3SOIPD_MOD_TCJSWG: + mod->B3SOIPDtcjswg = value->rValue; + mod->B3SOIPDtcjswgGiven = TRUE; + break; + case B3SOIPD_MOD_TPBSWG: + mod->B3SOIPDtpbswg = value->rValue; + mod->B3SOIPDtpbswgGiven = TRUE; + break; + case B3SOIPD_MOD_ACDE: + mod->B3SOIPDacde = value->rValue; + mod->B3SOIPDacdeGiven = TRUE; + break; + case B3SOIPD_MOD_MOIN: + mod->B3SOIPDmoin = value->rValue; + mod->B3SOIPDmoinGiven = TRUE; + break; + case B3SOIPD_MOD_DELVT: + mod->B3SOIPDdelvt = value->rValue; + mod->B3SOIPDdelvtGiven = TRUE; + break; + case B3SOIPD_MOD_KB1: + mod->B3SOIPDkb1 = value->rValue; + mod->B3SOIPDkb1Given = TRUE; + break; + case B3SOIPD_MOD_DLBG: + mod->B3SOIPDdlbg = value->rValue; + mod->B3SOIPDdlbgGiven = TRUE; + break; + +/* Added for binning - START */ + /* Length Dependence */ + case B3SOIPD_MOD_LNPEAK: + mod->B3SOIPDlnpeak = value->rValue; + mod->B3SOIPDlnpeakGiven = TRUE; + break; + case B3SOIPD_MOD_LNSUB: + mod->B3SOIPDlnsub = value->rValue; + mod->B3SOIPDlnsubGiven = TRUE; + break; + case B3SOIPD_MOD_LNGATE: + mod->B3SOIPDlngate = value->rValue; + mod->B3SOIPDlngateGiven = TRUE; + break; + case B3SOIPD_MOD_LVTH0: + mod->B3SOIPDlvth0 = value->rValue; + mod->B3SOIPDlvth0Given = TRUE; + break; + case B3SOIPD_MOD_LK1: + mod->B3SOIPDlk1 = value->rValue; + mod->B3SOIPDlk1Given = TRUE; + break; + case B3SOIPD_MOD_LK1W1: + mod->B3SOIPDlk1w1 = value->rValue; + mod->B3SOIPDlk1w1Given = TRUE; + break; + case B3SOIPD_MOD_LK1W2: + mod->B3SOIPDlk1w2 = value->rValue; + mod->B3SOIPDlk1w2Given = TRUE; + break; + case B3SOIPD_MOD_LK2: + mod->B3SOIPDlk2 = value->rValue; + mod->B3SOIPDlk2Given = TRUE; + break; + case B3SOIPD_MOD_LK3: + mod->B3SOIPDlk3 = value->rValue; + mod->B3SOIPDlk3Given = TRUE; + break; + case B3SOIPD_MOD_LK3B: + mod->B3SOIPDlk3b = value->rValue; + mod->B3SOIPDlk3bGiven = TRUE; + break; + case B3SOIPD_MOD_LKB1: + mod->B3SOIPDlkb1 = value->rValue; + mod->B3SOIPDlkb1Given = TRUE; + break; + case B3SOIPD_MOD_LW0: + mod->B3SOIPDlw0 = value->rValue; + mod->B3SOIPDlw0Given = TRUE; + break; + case B3SOIPD_MOD_LNLX: + mod->B3SOIPDlnlx = value->rValue; + mod->B3SOIPDlnlxGiven = TRUE; + break; + case B3SOIPD_MOD_LDVT0: + mod->B3SOIPDldvt0 = value->rValue; + mod->B3SOIPDldvt0Given = TRUE; + break; + case B3SOIPD_MOD_LDVT1: + mod->B3SOIPDldvt1 = value->rValue; + mod->B3SOIPDldvt1Given = TRUE; + break; + case B3SOIPD_MOD_LDVT2: + mod->B3SOIPDldvt2 = value->rValue; + mod->B3SOIPDldvt2Given = TRUE; + break; + case B3SOIPD_MOD_LDVT0W: + mod->B3SOIPDldvt0w = value->rValue; + mod->B3SOIPDldvt0wGiven = TRUE; + break; + case B3SOIPD_MOD_LDVT1W: + mod->B3SOIPDldvt1w = value->rValue; + mod->B3SOIPDldvt1wGiven = TRUE; + break; + case B3SOIPD_MOD_LDVT2W: + mod->B3SOIPDldvt2w = value->rValue; + mod->B3SOIPDldvt2wGiven = TRUE; + break; + case B3SOIPD_MOD_LU0: + mod->B3SOIPDlu0 = value->rValue; + mod->B3SOIPDlu0Given = TRUE; + break; + case B3SOIPD_MOD_LUA: + mod->B3SOIPDlua = value->rValue; + mod->B3SOIPDluaGiven = TRUE; + break; + case B3SOIPD_MOD_LUB: + mod->B3SOIPDlub = value->rValue; + mod->B3SOIPDlubGiven = TRUE; + break; + case B3SOIPD_MOD_LUC: + mod->B3SOIPDluc = value->rValue; + mod->B3SOIPDlucGiven = TRUE; + break; + case B3SOIPD_MOD_LVSAT: + mod->B3SOIPDlvsat = value->rValue; + mod->B3SOIPDlvsatGiven = TRUE; + break; + case B3SOIPD_MOD_LA0: + mod->B3SOIPDla0 = value->rValue; + mod->B3SOIPDla0Given = TRUE; + break; + case B3SOIPD_MOD_LAGS: + mod->B3SOIPDlags = value->rValue; + mod->B3SOIPDlagsGiven = TRUE; + break; + case B3SOIPD_MOD_LB0: + mod->B3SOIPDlb0 = value->rValue; + mod->B3SOIPDlb0Given = TRUE; + break; + case B3SOIPD_MOD_LB1: + mod->B3SOIPDlb1 = value->rValue; + mod->B3SOIPDlb1Given = TRUE; + break; + case B3SOIPD_MOD_LKETA: + mod->B3SOIPDlketa = value->rValue; + mod->B3SOIPDlketaGiven = TRUE; + break; + case B3SOIPD_MOD_LKETAS: + mod->B3SOIPDlketas = value->rValue; + mod->B3SOIPDlketasGiven = TRUE; + break; + case B3SOIPD_MOD_LA1: + mod->B3SOIPDla1 = value->rValue; + mod->B3SOIPDla1Given = TRUE; + break; + case B3SOIPD_MOD_LA2: + mod->B3SOIPDla2 = value->rValue; + mod->B3SOIPDla2Given = TRUE; + break; + case B3SOIPD_MOD_LRDSW: + mod->B3SOIPDlrdsw = value->rValue; + mod->B3SOIPDlrdswGiven = TRUE; + break; + case B3SOIPD_MOD_LPRWB: + mod->B3SOIPDlprwb = value->rValue; + mod->B3SOIPDlprwbGiven = TRUE; + break; + case B3SOIPD_MOD_LPRWG: + mod->B3SOIPDlprwg = value->rValue; + mod->B3SOIPDlprwgGiven = TRUE; + break; + case B3SOIPD_MOD_LWR: + mod->B3SOIPDlwr = value->rValue; + mod->B3SOIPDlwrGiven = TRUE; + break; + case B3SOIPD_MOD_LNFACTOR: + mod->B3SOIPDlnfactor = value->rValue; + mod->B3SOIPDlnfactorGiven = TRUE; + break; + case B3SOIPD_MOD_LDWG: + mod->B3SOIPDldwg = value->rValue; + mod->B3SOIPDldwgGiven = TRUE; + break; + case B3SOIPD_MOD_LDWB: + mod->B3SOIPDldwb = value->rValue; + mod->B3SOIPDldwbGiven = TRUE; + break; + case B3SOIPD_MOD_LVOFF: + mod->B3SOIPDlvoff = value->rValue; + mod->B3SOIPDlvoffGiven = TRUE; + break; + case B3SOIPD_MOD_LETA0: + mod->B3SOIPDleta0 = value->rValue; + mod->B3SOIPDleta0Given = TRUE; + break; + case B3SOIPD_MOD_LETAB: + mod->B3SOIPDletab = value->rValue; + mod->B3SOIPDletabGiven = TRUE; + break; + case B3SOIPD_MOD_LDSUB: + mod->B3SOIPDldsub = value->rValue; + mod->B3SOIPDldsubGiven = TRUE; + break; + case B3SOIPD_MOD_LCIT: + mod->B3SOIPDlcit = value->rValue; + mod->B3SOIPDlcitGiven = TRUE; + break; + case B3SOIPD_MOD_LCDSC: + mod->B3SOIPDlcdsc = value->rValue; + mod->B3SOIPDlcdscGiven = TRUE; + break; + case B3SOIPD_MOD_LCDSCB: + mod->B3SOIPDlcdscb = value->rValue; + mod->B3SOIPDlcdscbGiven = TRUE; + break; + case B3SOIPD_MOD_LCDSCD: + mod->B3SOIPDlcdscd = value->rValue; + mod->B3SOIPDlcdscdGiven = TRUE; + break; + case B3SOIPD_MOD_LPCLM: + mod->B3SOIPDlpclm = value->rValue; + mod->B3SOIPDlpclmGiven = TRUE; + break; + case B3SOIPD_MOD_LPDIBL1: + mod->B3SOIPDlpdibl1 = value->rValue; + mod->B3SOIPDlpdibl1Given = TRUE; + break; + case B3SOIPD_MOD_LPDIBL2: + mod->B3SOIPDlpdibl2 = value->rValue; + mod->B3SOIPDlpdibl2Given = TRUE; + break; + case B3SOIPD_MOD_LPDIBLB: + mod->B3SOIPDlpdiblb = value->rValue; + mod->B3SOIPDlpdiblbGiven = TRUE; + break; + case B3SOIPD_MOD_LDROUT: + mod->B3SOIPDldrout = value->rValue; + mod->B3SOIPDldroutGiven = TRUE; + break; + case B3SOIPD_MOD_LPVAG: + mod->B3SOIPDlpvag = value->rValue; + mod->B3SOIPDlpvagGiven = TRUE; + break; + case B3SOIPD_MOD_LDELTA: + mod->B3SOIPDldelta = value->rValue; + mod->B3SOIPDldeltaGiven = TRUE; + break; + case B3SOIPD_MOD_LALPHA0: + mod->B3SOIPDlalpha0 = value->rValue; + mod->B3SOIPDlalpha0Given = TRUE; + break; + case B3SOIPD_MOD_LFBJTII: + mod->B3SOIPDlfbjtii = value->rValue; + mod->B3SOIPDlfbjtiiGiven = TRUE; + break; + case B3SOIPD_MOD_LBETA0: + mod->B3SOIPDlbeta0 = value->rValue; + mod->B3SOIPDlbeta0Given = TRUE; + break; + case B3SOIPD_MOD_LBETA1: + mod->B3SOIPDlbeta1 = value->rValue; + mod->B3SOIPDlbeta1Given = TRUE; + break; + case B3SOIPD_MOD_LBETA2: + mod->B3SOIPDlbeta2 = value->rValue; + mod->B3SOIPDlbeta2Given = TRUE; + break; + case B3SOIPD_MOD_LVDSATII0: + mod->B3SOIPDlvdsatii0 = value->rValue; + mod->B3SOIPDlvdsatii0Given = TRUE; + break; + case B3SOIPD_MOD_LLII: + mod->B3SOIPDllii = value->rValue; + mod->B3SOIPDlliiGiven = TRUE; + break; + case B3SOIPD_MOD_LESATII: + mod->B3SOIPDlesatii = value->rValue; + mod->B3SOIPDlesatiiGiven = TRUE; + break; + case B3SOIPD_MOD_LSII0: + mod->B3SOIPDlsii0 = value->rValue; + mod->B3SOIPDlsii0Given = TRUE; + break; + case B3SOIPD_MOD_LSII1: + mod->B3SOIPDlsii1 = value->rValue; + mod->B3SOIPDlsii1Given = TRUE; + break; + case B3SOIPD_MOD_LSII2: + mod->B3SOIPDlsii2 = value->rValue; + mod->B3SOIPDlsii2Given = TRUE; + break; + case B3SOIPD_MOD_LSIID: + mod->B3SOIPDlsiid = value->rValue; + mod->B3SOIPDlsiidGiven = TRUE; + break; + case B3SOIPD_MOD_LAGIDL: + mod->B3SOIPDlagidl = value->rValue; + mod->B3SOIPDlagidlGiven = TRUE; + break; + case B3SOIPD_MOD_LBGIDL: + mod->B3SOIPDlbgidl = value->rValue; + mod->B3SOIPDlbgidlGiven = TRUE; + break; + case B3SOIPD_MOD_LNGIDL: + mod->B3SOIPDlngidl = value->rValue; + mod->B3SOIPDlngidlGiven = TRUE; + break; + case B3SOIPD_MOD_LNTUN: + mod->B3SOIPDlntun = value->rValue; + mod->B3SOIPDlntunGiven = TRUE; + break; + case B3SOIPD_MOD_LNDIODE: + mod->B3SOIPDlndiode = value->rValue; + mod->B3SOIPDlndiodeGiven = TRUE; + break; + case B3SOIPD_MOD_LNRECF0: + mod->B3SOIPDlnrecf0 = value->rValue; + mod->B3SOIPDlnrecf0Given = TRUE; + break; + case B3SOIPD_MOD_LNRECR0: + mod->B3SOIPDlnrecr0 = value->rValue; + mod->B3SOIPDlnrecr0Given = TRUE; + break; + case B3SOIPD_MOD_LISBJT: + mod->B3SOIPDlisbjt = value->rValue; + mod->B3SOIPDlisbjtGiven = TRUE; + break; + case B3SOIPD_MOD_LISDIF: + mod->B3SOIPDlisdif = value->rValue; + mod->B3SOIPDlisdifGiven = TRUE; + break; + case B3SOIPD_MOD_LISREC: + mod->B3SOIPDlisrec = value->rValue; + mod->B3SOIPDlisrecGiven = TRUE; + break; + case B3SOIPD_MOD_LISTUN: + mod->B3SOIPDlistun = value->rValue; + mod->B3SOIPDlistunGiven = TRUE; + break; + case B3SOIPD_MOD_LVREC0: + mod->B3SOIPDlvrec0 = value->rValue; + mod->B3SOIPDlvrec0Given = TRUE; + break; + case B3SOIPD_MOD_LVTUN0: + mod->B3SOIPDlvtun0 = value->rValue; + mod->B3SOIPDlvtun0Given = TRUE; + break; + case B3SOIPD_MOD_LNBJT: + mod->B3SOIPDlnbjt = value->rValue; + mod->B3SOIPDlnbjtGiven = TRUE; + break; + case B3SOIPD_MOD_LLBJT0: + mod->B3SOIPDllbjt0 = value->rValue; + mod->B3SOIPDllbjt0Given = TRUE; + break; + case B3SOIPD_MOD_LVABJT: + mod->B3SOIPDlvabjt = value->rValue; + mod->B3SOIPDlvabjtGiven = TRUE; + break; + case B3SOIPD_MOD_LAELY: + mod->B3SOIPDlaely = value->rValue; + mod->B3SOIPDlaelyGiven = TRUE; + break; + case B3SOIPD_MOD_LAHLI: + mod->B3SOIPDlahli = value->rValue; + mod->B3SOIPDlahliGiven = TRUE; + break; + /* CV Model */ + case B3SOIPD_MOD_LVSDFB: + mod->B3SOIPDlvsdfb = value->rValue; + mod->B3SOIPDlvsdfbGiven = TRUE; + break; + case B3SOIPD_MOD_LVSDTH: + mod->B3SOIPDlvsdth = value->rValue; + mod->B3SOIPDlvsdthGiven = TRUE; + break; + case B3SOIPD_MOD_LDELVT: + mod->B3SOIPDldelvt = value->rValue; + mod->B3SOIPDldelvtGiven = TRUE; + break; + case B3SOIPD_MOD_LACDE: + mod->B3SOIPDlacde = value->rValue; + mod->B3SOIPDlacdeGiven = TRUE; + break; + case B3SOIPD_MOD_LMOIN: + mod->B3SOIPDlmoin = value->rValue; + mod->B3SOIPDlmoinGiven = TRUE; + break; + + /* Width Dependence */ + case B3SOIPD_MOD_WNPEAK: + mod->B3SOIPDwnpeak = value->rValue; + mod->B3SOIPDwnpeakGiven = TRUE; + break; + case B3SOIPD_MOD_WNSUB: + mod->B3SOIPDwnsub = value->rValue; + mod->B3SOIPDwnsubGiven = TRUE; + break; + case B3SOIPD_MOD_WNGATE: + mod->B3SOIPDwngate = value->rValue; + mod->B3SOIPDwngateGiven = TRUE; + break; + case B3SOIPD_MOD_WVTH0: + mod->B3SOIPDwvth0 = value->rValue; + mod->B3SOIPDwvth0Given = TRUE; + break; + case B3SOIPD_MOD_WK1: + mod->B3SOIPDwk1 = value->rValue; + mod->B3SOIPDwk1Given = TRUE; + break; + case B3SOIPD_MOD_WK1W1: + mod->B3SOIPDwk1w1 = value->rValue; + mod->B3SOIPDwk1w1Given = TRUE; + break; + case B3SOIPD_MOD_WK1W2: + mod->B3SOIPDwk1w2 = value->rValue; + mod->B3SOIPDwk1w2Given = TRUE; + break; + case B3SOIPD_MOD_WK2: + mod->B3SOIPDwk2 = value->rValue; + mod->B3SOIPDwk2Given = TRUE; + break; + case B3SOIPD_MOD_WK3: + mod->B3SOIPDwk3 = value->rValue; + mod->B3SOIPDwk3Given = TRUE; + break; + case B3SOIPD_MOD_WK3B: + mod->B3SOIPDwk3b = value->rValue; + mod->B3SOIPDwk3bGiven = TRUE; + break; + case B3SOIPD_MOD_WKB1: + mod->B3SOIPDwkb1 = value->rValue; + mod->B3SOIPDwkb1Given = TRUE; + break; + case B3SOIPD_MOD_WW0: + mod->B3SOIPDww0 = value->rValue; + mod->B3SOIPDww0Given = TRUE; + break; + case B3SOIPD_MOD_WNLX: + mod->B3SOIPDwnlx = value->rValue; + mod->B3SOIPDwnlxGiven = TRUE; + break; + case B3SOIPD_MOD_WDVT0: + mod->B3SOIPDwdvt0 = value->rValue; + mod->B3SOIPDwdvt0Given = TRUE; + break; + case B3SOIPD_MOD_WDVT1: + mod->B3SOIPDwdvt1 = value->rValue; + mod->B3SOIPDwdvt1Given = TRUE; + break; + case B3SOIPD_MOD_WDVT2: + mod->B3SOIPDwdvt2 = value->rValue; + mod->B3SOIPDwdvt2Given = TRUE; + break; + case B3SOIPD_MOD_WDVT0W: + mod->B3SOIPDwdvt0w = value->rValue; + mod->B3SOIPDwdvt0wGiven = TRUE; + break; + case B3SOIPD_MOD_WDVT1W: + mod->B3SOIPDwdvt1w = value->rValue; + mod->B3SOIPDwdvt1wGiven = TRUE; + break; + case B3SOIPD_MOD_WDVT2W: + mod->B3SOIPDwdvt2w = value->rValue; + mod->B3SOIPDwdvt2wGiven = TRUE; + break; + case B3SOIPD_MOD_WU0: + mod->B3SOIPDwu0 = value->rValue; + mod->B3SOIPDwu0Given = TRUE; + break; + case B3SOIPD_MOD_WUA: + mod->B3SOIPDwua = value->rValue; + mod->B3SOIPDwuaGiven = TRUE; + break; + case B3SOIPD_MOD_WUB: + mod->B3SOIPDwub = value->rValue; + mod->B3SOIPDwubGiven = TRUE; + break; + case B3SOIPD_MOD_WUC: + mod->B3SOIPDwuc = value->rValue; + mod->B3SOIPDwucGiven = TRUE; + break; + case B3SOIPD_MOD_WVSAT: + mod->B3SOIPDwvsat = value->rValue; + mod->B3SOIPDwvsatGiven = TRUE; + break; + case B3SOIPD_MOD_WA0: + mod->B3SOIPDwa0 = value->rValue; + mod->B3SOIPDwa0Given = TRUE; + break; + case B3SOIPD_MOD_WAGS: + mod->B3SOIPDwags = value->rValue; + mod->B3SOIPDwagsGiven = TRUE; + break; + case B3SOIPD_MOD_WB0: + mod->B3SOIPDwb0 = value->rValue; + mod->B3SOIPDwb0Given = TRUE; + break; + case B3SOIPD_MOD_WB1: + mod->B3SOIPDwb1 = value->rValue; + mod->B3SOIPDwb1Given = TRUE; + break; + case B3SOIPD_MOD_WKETA: + mod->B3SOIPDwketa = value->rValue; + mod->B3SOIPDwketaGiven = TRUE; + break; + case B3SOIPD_MOD_WKETAS: + mod->B3SOIPDwketas = value->rValue; + mod->B3SOIPDwketasGiven = TRUE; + break; + case B3SOIPD_MOD_WA1: + mod->B3SOIPDwa1 = value->rValue; + mod->B3SOIPDwa1Given = TRUE; + break; + case B3SOIPD_MOD_WA2: + mod->B3SOIPDwa2 = value->rValue; + mod->B3SOIPDwa2Given = TRUE; + break; + case B3SOIPD_MOD_WRDSW: + mod->B3SOIPDwrdsw = value->rValue; + mod->B3SOIPDwrdswGiven = TRUE; + break; + case B3SOIPD_MOD_WPRWB: + mod->B3SOIPDwprwb = value->rValue; + mod->B3SOIPDwprwbGiven = TRUE; + break; + case B3SOIPD_MOD_WPRWG: + mod->B3SOIPDwprwg = value->rValue; + mod->B3SOIPDwprwgGiven = TRUE; + break; + case B3SOIPD_MOD_WWR: + mod->B3SOIPDwwr = value->rValue; + mod->B3SOIPDwwrGiven = TRUE; + break; + case B3SOIPD_MOD_WNFACTOR: + mod->B3SOIPDwnfactor = value->rValue; + mod->B3SOIPDwnfactorGiven = TRUE; + break; + case B3SOIPD_MOD_WDWG: + mod->B3SOIPDwdwg = value->rValue; + mod->B3SOIPDwdwgGiven = TRUE; + break; + case B3SOIPD_MOD_WDWB: + mod->B3SOIPDwdwb = value->rValue; + mod->B3SOIPDwdwbGiven = TRUE; + break; + case B3SOIPD_MOD_WVOFF: + mod->B3SOIPDwvoff = value->rValue; + mod->B3SOIPDwvoffGiven = TRUE; + break; + case B3SOIPD_MOD_WETA0: + mod->B3SOIPDweta0 = value->rValue; + mod->B3SOIPDweta0Given = TRUE; + break; + case B3SOIPD_MOD_WETAB: + mod->B3SOIPDwetab = value->rValue; + mod->B3SOIPDwetabGiven = TRUE; + break; + case B3SOIPD_MOD_WDSUB: + mod->B3SOIPDwdsub = value->rValue; + mod->B3SOIPDwdsubGiven = TRUE; + break; + case B3SOIPD_MOD_WCIT: + mod->B3SOIPDwcit = value->rValue; + mod->B3SOIPDwcitGiven = TRUE; + break; + case B3SOIPD_MOD_WCDSC: + mod->B3SOIPDwcdsc = value->rValue; + mod->B3SOIPDwcdscGiven = TRUE; + break; + case B3SOIPD_MOD_WCDSCB: + mod->B3SOIPDwcdscb = value->rValue; + mod->B3SOIPDwcdscbGiven = TRUE; + break; + case B3SOIPD_MOD_WCDSCD: + mod->B3SOIPDwcdscd = value->rValue; + mod->B3SOIPDwcdscdGiven = TRUE; + break; + case B3SOIPD_MOD_WPCLM: + mod->B3SOIPDwpclm = value->rValue; + mod->B3SOIPDwpclmGiven = TRUE; + break; + case B3SOIPD_MOD_WPDIBL1: + mod->B3SOIPDwpdibl1 = value->rValue; + mod->B3SOIPDwpdibl1Given = TRUE; + break; + case B3SOIPD_MOD_WPDIBL2: + mod->B3SOIPDwpdibl2 = value->rValue; + mod->B3SOIPDwpdibl2Given = TRUE; + break; + case B3SOIPD_MOD_WPDIBLB: + mod->B3SOIPDwpdiblb = value->rValue; + mod->B3SOIPDwpdiblbGiven = TRUE; + break; + case B3SOIPD_MOD_WDROUT: + mod->B3SOIPDwdrout = value->rValue; + mod->B3SOIPDwdroutGiven = TRUE; + break; + case B3SOIPD_MOD_WPVAG: + mod->B3SOIPDwpvag = value->rValue; + mod->B3SOIPDwpvagGiven = TRUE; + break; + case B3SOIPD_MOD_WDELTA: + mod->B3SOIPDwdelta = value->rValue; + mod->B3SOIPDwdeltaGiven = TRUE; + break; + case B3SOIPD_MOD_WALPHA0: + mod->B3SOIPDwalpha0 = value->rValue; + mod->B3SOIPDwalpha0Given = TRUE; + break; + case B3SOIPD_MOD_WFBJTII: + mod->B3SOIPDwfbjtii = value->rValue; + mod->B3SOIPDwfbjtiiGiven = TRUE; + break; + case B3SOIPD_MOD_WBETA0: + mod->B3SOIPDwbeta0 = value->rValue; + mod->B3SOIPDwbeta0Given = TRUE; + break; + case B3SOIPD_MOD_WBETA1: + mod->B3SOIPDwbeta1 = value->rValue; + mod->B3SOIPDwbeta1Given = TRUE; + break; + case B3SOIPD_MOD_WBETA2: + mod->B3SOIPDwbeta2 = value->rValue; + mod->B3SOIPDwbeta2Given = TRUE; + break; + case B3SOIPD_MOD_WVDSATII0: + mod->B3SOIPDwvdsatii0 = value->rValue; + mod->B3SOIPDwvdsatii0Given = TRUE; + break; + case B3SOIPD_MOD_WLII: + mod->B3SOIPDwlii = value->rValue; + mod->B3SOIPDwliiGiven = TRUE; + break; + case B3SOIPD_MOD_WESATII: + mod->B3SOIPDwesatii = value->rValue; + mod->B3SOIPDwesatiiGiven = TRUE; + break; + case B3SOIPD_MOD_WSII0: + mod->B3SOIPDwsii0 = value->rValue; + mod->B3SOIPDwsii0Given = TRUE; + break; + case B3SOIPD_MOD_WSII1: + mod->B3SOIPDwsii1 = value->rValue; + mod->B3SOIPDwsii1Given = TRUE; + break; + case B3SOIPD_MOD_WSII2: + mod->B3SOIPDwsii2 = value->rValue; + mod->B3SOIPDwsii2Given = TRUE; + break; + case B3SOIPD_MOD_WSIID: + mod->B3SOIPDwsiid = value->rValue; + mod->B3SOIPDwsiidGiven = TRUE; + break; + case B3SOIPD_MOD_WAGIDL: + mod->B3SOIPDwagidl = value->rValue; + mod->B3SOIPDwagidlGiven = TRUE; + break; + case B3SOIPD_MOD_WBGIDL: + mod->B3SOIPDwbgidl = value->rValue; + mod->B3SOIPDwbgidlGiven = TRUE; + break; + case B3SOIPD_MOD_WNGIDL: + mod->B3SOIPDwngidl = value->rValue; + mod->B3SOIPDwngidlGiven = TRUE; + break; + case B3SOIPD_MOD_WNTUN: + mod->B3SOIPDwntun = value->rValue; + mod->B3SOIPDwntunGiven = TRUE; + break; + case B3SOIPD_MOD_WNDIODE: + mod->B3SOIPDwndiode = value->rValue; + mod->B3SOIPDwndiodeGiven = TRUE; + break; + case B3SOIPD_MOD_WNRECF0: + mod->B3SOIPDwnrecf0 = value->rValue; + mod->B3SOIPDwnrecf0Given = TRUE; + break; + case B3SOIPD_MOD_WNRECR0: + mod->B3SOIPDwnrecr0 = value->rValue; + mod->B3SOIPDwnrecr0Given = TRUE; + break; + case B3SOIPD_MOD_WISBJT: + mod->B3SOIPDwisbjt = value->rValue; + mod->B3SOIPDwisbjtGiven = TRUE; + break; + case B3SOIPD_MOD_WISDIF: + mod->B3SOIPDwisdif = value->rValue; + mod->B3SOIPDwisdifGiven = TRUE; + break; + case B3SOIPD_MOD_WISREC: + mod->B3SOIPDwisrec = value->rValue; + mod->B3SOIPDwisrecGiven = TRUE; + break; + case B3SOIPD_MOD_WISTUN: + mod->B3SOIPDwistun = value->rValue; + mod->B3SOIPDwistunGiven = TRUE; + break; + case B3SOIPD_MOD_WVREC0: + mod->B3SOIPDwvrec0 = value->rValue; + mod->B3SOIPDwvrec0Given = TRUE; + break; + case B3SOIPD_MOD_WVTUN0: + mod->B3SOIPDwvtun0 = value->rValue; + mod->B3SOIPDwvtun0Given = TRUE; + break; + case B3SOIPD_MOD_WNBJT: + mod->B3SOIPDwnbjt = value->rValue; + mod->B3SOIPDwnbjtGiven = TRUE; + break; + case B3SOIPD_MOD_WLBJT0: + mod->B3SOIPDwlbjt0 = value->rValue; + mod->B3SOIPDwlbjt0Given = TRUE; + break; + case B3SOIPD_MOD_WVABJT: + mod->B3SOIPDwvabjt = value->rValue; + mod->B3SOIPDwvabjtGiven = TRUE; + break; + case B3SOIPD_MOD_WAELY: + mod->B3SOIPDwaely = value->rValue; + mod->B3SOIPDwaelyGiven = TRUE; + break; + case B3SOIPD_MOD_WAHLI: + mod->B3SOIPDwahli = value->rValue; + mod->B3SOIPDwahliGiven = TRUE; + break; + /* CV Model */ + case B3SOIPD_MOD_WVSDFB: + mod->B3SOIPDwvsdfb = value->rValue; + mod->B3SOIPDwvsdfbGiven = TRUE; + break; + case B3SOIPD_MOD_WVSDTH: + mod->B3SOIPDwvsdth = value->rValue; + mod->B3SOIPDwvsdthGiven = TRUE; + break; + case B3SOIPD_MOD_WDELVT: + mod->B3SOIPDwdelvt = value->rValue; + mod->B3SOIPDwdelvtGiven = TRUE; + break; + case B3SOIPD_MOD_WACDE: + mod->B3SOIPDwacde = value->rValue; + mod->B3SOIPDwacdeGiven = TRUE; + break; + case B3SOIPD_MOD_WMOIN: + mod->B3SOIPDwmoin = value->rValue; + mod->B3SOIPDwmoinGiven = TRUE; + break; + + /* Cross-term Dependence */ + case B3SOIPD_MOD_PNPEAK: + mod->B3SOIPDpnpeak = value->rValue; + mod->B3SOIPDpnpeakGiven = TRUE; + break; + case B3SOIPD_MOD_PNSUB: + mod->B3SOIPDpnsub = value->rValue; + mod->B3SOIPDpnsubGiven = TRUE; + break; + case B3SOIPD_MOD_PNGATE: + mod->B3SOIPDpngate = value->rValue; + mod->B3SOIPDpngateGiven = TRUE; + break; + case B3SOIPD_MOD_PVTH0: + mod->B3SOIPDpvth0 = value->rValue; + mod->B3SOIPDpvth0Given = TRUE; + break; + case B3SOIPD_MOD_PK1: + mod->B3SOIPDpk1 = value->rValue; + mod->B3SOIPDpk1Given = TRUE; + break; + case B3SOIPD_MOD_PK1W1: + mod->B3SOIPDpk1w1 = value->rValue; + mod->B3SOIPDpk1w1Given = TRUE; + break; + case B3SOIPD_MOD_PK1W2: + mod->B3SOIPDpk1w2 = value->rValue; + mod->B3SOIPDpk1w2Given = TRUE; + break; + case B3SOIPD_MOD_PK2: + mod->B3SOIPDpk2 = value->rValue; + mod->B3SOIPDpk2Given = TRUE; + break; + case B3SOIPD_MOD_PK3: + mod->B3SOIPDpk3 = value->rValue; + mod->B3SOIPDpk3Given = TRUE; + break; + case B3SOIPD_MOD_PK3B: + mod->B3SOIPDpk3b = value->rValue; + mod->B3SOIPDpk3bGiven = TRUE; + break; + case B3SOIPD_MOD_PKB1: + mod->B3SOIPDpkb1 = value->rValue; + mod->B3SOIPDpkb1Given = TRUE; + break; + case B3SOIPD_MOD_PW0: + mod->B3SOIPDpw0 = value->rValue; + mod->B3SOIPDpw0Given = TRUE; + break; + case B3SOIPD_MOD_PNLX: + mod->B3SOIPDpnlx = value->rValue; + mod->B3SOIPDpnlxGiven = TRUE; + break; + case B3SOIPD_MOD_PDVT0: + mod->B3SOIPDpdvt0 = value->rValue; + mod->B3SOIPDpdvt0Given = TRUE; + break; + case B3SOIPD_MOD_PDVT1: + mod->B3SOIPDpdvt1 = value->rValue; + mod->B3SOIPDpdvt1Given = TRUE; + break; + case B3SOIPD_MOD_PDVT2: + mod->B3SOIPDpdvt2 = value->rValue; + mod->B3SOIPDpdvt2Given = TRUE; + break; + case B3SOIPD_MOD_PDVT0W: + mod->B3SOIPDpdvt0w = value->rValue; + mod->B3SOIPDpdvt0wGiven = TRUE; + break; + case B3SOIPD_MOD_PDVT1W: + mod->B3SOIPDpdvt1w = value->rValue; + mod->B3SOIPDpdvt1wGiven = TRUE; + break; + case B3SOIPD_MOD_PDVT2W: + mod->B3SOIPDpdvt2w = value->rValue; + mod->B3SOIPDpdvt2wGiven = TRUE; + break; + case B3SOIPD_MOD_PU0: + mod->B3SOIPDpu0 = value->rValue; + mod->B3SOIPDpu0Given = TRUE; + break; + case B3SOIPD_MOD_PUA: + mod->B3SOIPDpua = value->rValue; + mod->B3SOIPDpuaGiven = TRUE; + break; + case B3SOIPD_MOD_PUB: + mod->B3SOIPDpub = value->rValue; + mod->B3SOIPDpubGiven = TRUE; + break; + case B3SOIPD_MOD_PUC: + mod->B3SOIPDpuc = value->rValue; + mod->B3SOIPDpucGiven = TRUE; + break; + case B3SOIPD_MOD_PVSAT: + mod->B3SOIPDpvsat = value->rValue; + mod->B3SOIPDpvsatGiven = TRUE; + break; + case B3SOIPD_MOD_PA0: + mod->B3SOIPDpa0 = value->rValue; + mod->B3SOIPDpa0Given = TRUE; + break; + case B3SOIPD_MOD_PAGS: + mod->B3SOIPDpags = value->rValue; + mod->B3SOIPDpagsGiven = TRUE; + break; + case B3SOIPD_MOD_PB0: + mod->B3SOIPDpb0 = value->rValue; + mod->B3SOIPDpb0Given = TRUE; + break; + case B3SOIPD_MOD_PB1: + mod->B3SOIPDpb1 = value->rValue; + mod->B3SOIPDpb1Given = TRUE; + break; + case B3SOIPD_MOD_PKETA: + mod->B3SOIPDpketa = value->rValue; + mod->B3SOIPDpketaGiven = TRUE; + break; + case B3SOIPD_MOD_PKETAS: + mod->B3SOIPDpketas = value->rValue; + mod->B3SOIPDpketasGiven = TRUE; + break; + case B3SOIPD_MOD_PA1: + mod->B3SOIPDpa1 = value->rValue; + mod->B3SOIPDpa1Given = TRUE; + break; + case B3SOIPD_MOD_PA2: + mod->B3SOIPDpa2 = value->rValue; + mod->B3SOIPDpa2Given = TRUE; + break; + case B3SOIPD_MOD_PRDSW: + mod->B3SOIPDprdsw = value->rValue; + mod->B3SOIPDprdswGiven = TRUE; + break; + case B3SOIPD_MOD_PPRWB: + mod->B3SOIPDpprwb = value->rValue; + mod->B3SOIPDpprwbGiven = TRUE; + break; + case B3SOIPD_MOD_PPRWG: + mod->B3SOIPDpprwg = value->rValue; + mod->B3SOIPDpprwgGiven = TRUE; + break; + case B3SOIPD_MOD_PWR: + mod->B3SOIPDpwr = value->rValue; + mod->B3SOIPDpwrGiven = TRUE; + break; + case B3SOIPD_MOD_PNFACTOR: + mod->B3SOIPDpnfactor = value->rValue; + mod->B3SOIPDpnfactorGiven = TRUE; + break; + case B3SOIPD_MOD_PDWG: + mod->B3SOIPDpdwg = value->rValue; + mod->B3SOIPDpdwgGiven = TRUE; + break; + case B3SOIPD_MOD_PDWB: + mod->B3SOIPDpdwb = value->rValue; + mod->B3SOIPDpdwbGiven = TRUE; + break; + case B3SOIPD_MOD_PVOFF: + mod->B3SOIPDpvoff = value->rValue; + mod->B3SOIPDpvoffGiven = TRUE; + break; + case B3SOIPD_MOD_PETA0: + mod->B3SOIPDpeta0 = value->rValue; + mod->B3SOIPDpeta0Given = TRUE; + break; + case B3SOIPD_MOD_PETAB: + mod->B3SOIPDpetab = value->rValue; + mod->B3SOIPDpetabGiven = TRUE; + break; + case B3SOIPD_MOD_PDSUB: + mod->B3SOIPDpdsub = value->rValue; + mod->B3SOIPDpdsubGiven = TRUE; + break; + case B3SOIPD_MOD_PCIT: + mod->B3SOIPDpcit = value->rValue; + mod->B3SOIPDpcitGiven = TRUE; + break; + case B3SOIPD_MOD_PCDSC: + mod->B3SOIPDpcdsc = value->rValue; + mod->B3SOIPDpcdscGiven = TRUE; + break; + case B3SOIPD_MOD_PCDSCB: + mod->B3SOIPDpcdscb = value->rValue; + mod->B3SOIPDpcdscbGiven = TRUE; + break; + case B3SOIPD_MOD_PCDSCD: + mod->B3SOIPDpcdscd = value->rValue; + mod->B3SOIPDpcdscdGiven = TRUE; + break; + case B3SOIPD_MOD_PPCLM: + mod->B3SOIPDppclm = value->rValue; + mod->B3SOIPDppclmGiven = TRUE; + break; + case B3SOIPD_MOD_PPDIBL1: + mod->B3SOIPDppdibl1 = value->rValue; + mod->B3SOIPDppdibl1Given = TRUE; + break; + case B3SOIPD_MOD_PPDIBL2: + mod->B3SOIPDppdibl2 = value->rValue; + mod->B3SOIPDppdibl2Given = TRUE; + break; + case B3SOIPD_MOD_PPDIBLB: + mod->B3SOIPDppdiblb = value->rValue; + mod->B3SOIPDppdiblbGiven = TRUE; + break; + case B3SOIPD_MOD_PDROUT: + mod->B3SOIPDpdrout = value->rValue; + mod->B3SOIPDpdroutGiven = TRUE; + break; + case B3SOIPD_MOD_PPVAG: + mod->B3SOIPDppvag = value->rValue; + mod->B3SOIPDppvagGiven = TRUE; + break; + case B3SOIPD_MOD_PDELTA: + mod->B3SOIPDpdelta = value->rValue; + mod->B3SOIPDpdeltaGiven = TRUE; + break; + case B3SOIPD_MOD_PALPHA0: + mod->B3SOIPDpalpha0 = value->rValue; + mod->B3SOIPDpalpha0Given = TRUE; + break; + case B3SOIPD_MOD_PFBJTII: + mod->B3SOIPDpfbjtii = value->rValue; + mod->B3SOIPDpfbjtiiGiven = TRUE; + break; + case B3SOIPD_MOD_PBETA0: + mod->B3SOIPDpbeta0 = value->rValue; + mod->B3SOIPDpbeta0Given = TRUE; + break; + case B3SOIPD_MOD_PBETA1: + mod->B3SOIPDpbeta1 = value->rValue; + mod->B3SOIPDpbeta1Given = TRUE; + break; + case B3SOIPD_MOD_PBETA2: + mod->B3SOIPDpbeta2 = value->rValue; + mod->B3SOIPDpbeta2Given = TRUE; + break; + case B3SOIPD_MOD_PVDSATII0: + mod->B3SOIPDpvdsatii0 = value->rValue; + mod->B3SOIPDpvdsatii0Given = TRUE; + break; + case B3SOIPD_MOD_PLII: + mod->B3SOIPDplii = value->rValue; + mod->B3SOIPDpliiGiven = TRUE; + break; + case B3SOIPD_MOD_PESATII: + mod->B3SOIPDpesatii = value->rValue; + mod->B3SOIPDpesatiiGiven = TRUE; + break; + case B3SOIPD_MOD_PSII0: + mod->B3SOIPDpsii0 = value->rValue; + mod->B3SOIPDpsii0Given = TRUE; + break; + case B3SOIPD_MOD_PSII1: + mod->B3SOIPDpsii1 = value->rValue; + mod->B3SOIPDpsii1Given = TRUE; + break; + case B3SOIPD_MOD_PSII2: + mod->B3SOIPDpsii2 = value->rValue; + mod->B3SOIPDpsii2Given = TRUE; + break; + case B3SOIPD_MOD_PSIID: + mod->B3SOIPDpsiid = value->rValue; + mod->B3SOIPDpsiidGiven = TRUE; + break; + case B3SOIPD_MOD_PAGIDL: + mod->B3SOIPDpagidl = value->rValue; + mod->B3SOIPDpagidlGiven = TRUE; + break; + case B3SOIPD_MOD_PBGIDL: + mod->B3SOIPDpbgidl = value->rValue; + mod->B3SOIPDpbgidlGiven = TRUE; + break; + case B3SOIPD_MOD_PNGIDL: + mod->B3SOIPDpngidl = value->rValue; + mod->B3SOIPDpngidlGiven = TRUE; + break; + case B3SOIPD_MOD_PNTUN: + mod->B3SOIPDpntun = value->rValue; + mod->B3SOIPDpntunGiven = TRUE; + break; + case B3SOIPD_MOD_PNDIODE: + mod->B3SOIPDpndiode = value->rValue; + mod->B3SOIPDpndiodeGiven = TRUE; + break; + case B3SOIPD_MOD_PNRECF0: + mod->B3SOIPDpnrecf0 = value->rValue; + mod->B3SOIPDpnrecf0Given = TRUE; + break; + case B3SOIPD_MOD_PNRECR0: + mod->B3SOIPDpnrecr0 = value->rValue; + mod->B3SOIPDpnrecr0Given = TRUE; + break; + case B3SOIPD_MOD_PISBJT: + mod->B3SOIPDpisbjt = value->rValue; + mod->B3SOIPDpisbjtGiven = TRUE; + break; + case B3SOIPD_MOD_PISDIF: + mod->B3SOIPDpisdif = value->rValue; + mod->B3SOIPDpisdifGiven = TRUE; + break; + case B3SOIPD_MOD_PISREC: + mod->B3SOIPDpisrec = value->rValue; + mod->B3SOIPDpisrecGiven = TRUE; + break; + case B3SOIPD_MOD_PISTUN: + mod->B3SOIPDpistun = value->rValue; + mod->B3SOIPDpistunGiven = TRUE; + break; + case B3SOIPD_MOD_PVREC0: + mod->B3SOIPDpvrec0 = value->rValue; + mod->B3SOIPDpvrec0Given = TRUE; + break; + case B3SOIPD_MOD_PVTUN0: + mod->B3SOIPDpvtun0 = value->rValue; + mod->B3SOIPDpvtun0Given = TRUE; + break; + case B3SOIPD_MOD_PNBJT: + mod->B3SOIPDpnbjt = value->rValue; + mod->B3SOIPDpnbjtGiven = TRUE; + break; + case B3SOIPD_MOD_PLBJT0: + mod->B3SOIPDplbjt0 = value->rValue; + mod->B3SOIPDplbjt0Given = TRUE; + break; + case B3SOIPD_MOD_PVABJT: + mod->B3SOIPDpvabjt = value->rValue; + mod->B3SOIPDpvabjtGiven = TRUE; + break; + case B3SOIPD_MOD_PAELY: + mod->B3SOIPDpaely = value->rValue; + mod->B3SOIPDpaelyGiven = TRUE; + break; + case B3SOIPD_MOD_PAHLI: + mod->B3SOIPDpahli = value->rValue; + mod->B3SOIPDpahliGiven = TRUE; + break; + /* CV Model */ + case B3SOIPD_MOD_PVSDFB: + mod->B3SOIPDpvsdfb = value->rValue; + mod->B3SOIPDpvsdfbGiven = TRUE; + break; + case B3SOIPD_MOD_PVSDTH: + mod->B3SOIPDpvsdth = value->rValue; + mod->B3SOIPDpvsdthGiven = TRUE; + break; + case B3SOIPD_MOD_PDELVT: + mod->B3SOIPDpdelvt = value->rValue; + mod->B3SOIPDpdelvtGiven = TRUE; + break; + case B3SOIPD_MOD_PACDE: + mod->B3SOIPDpacde = value->rValue; + mod->B3SOIPDpacdeGiven = TRUE; + break; + case B3SOIPD_MOD_PMOIN: + mod->B3SOIPDpmoin = value->rValue; + mod->B3SOIPDpmoinGiven = TRUE; + break; +/* Added for binning - END */ + + case B3SOIPD_MOD_NMOS: + if (value->iValue) + { + mod->B3SOIPDtype = 1; + mod->B3SOIPDtypeGiven = TRUE; + } + break; + case B3SOIPD_MOD_PMOS: + if (value->iValue) + { + mod->B3SOIPDtype = -1; + mod->B3SOIPDtypeGiven = TRUE; + } + break; + default: + return (E_BADPARM); + } + return (OK); +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdnoi.c b/src/spicelib/devices/bsim3soi_pd/b3soipdnoi.c new file mode 100644 index 000000000..244550a03 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdnoi.c @@ -0,0 +1,432 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipdnoi.c 98/5/01 +**********/ + +#include "ngspice.h" +#include +#include +#include "b3soipddef.h" +#include "cktdefs.h" +#include "iferrmsg.h" +#include "noisedef.h" +#include "suffix.h" +#include "const.h" /* jwan */ + +/* + * B3SOIPDnoise (mode, operation, firstModel, ckt, data, OnDens) + * This routine names and evaluates all of the noise sources + * associated with MOSFET's. It starts with the model *firstModel and + * traverses all of its insts. It then proceeds to any other models + * on the linked list. The total output noise density generated by + * all of the MOSFET's is summed with the variable "OnDens". + */ + +/* + Channel thermal and flicker noises are calculated based on the value + of model->B3SOIPDnoiMod. + If model->B3SOIPDnoiMod = 1, + Channel thermal noise = SPICE2 model + Flicker noise = SPICE2 model + If model->B3SOIPDnoiMod = 2, + Channel thermal noise = B3SOIPD model + Flicker noise = B3SOIPD model + If model->B3SOIPDnoiMod = 3, + Channel thermal noise = SPICE2 model + Flicker noise = B3SOIPD model + If model->B3SOIPDnoiMod = 4, + Channel thermal noise = B3SOIPD model + Flicker noise = SPICE2 model + */ + +extern void NevalSrc (); +extern double Nintegrate (); + +double +B3SOIPDStrongInversionNoiseEval (vgs, vds, model, here, freq, temp) + double vgs, vds, freq, temp; + B3SOIPDmodel *model; + B3SOIPDinstance *here; +{ + struct b3soipdSizeDependParam *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 req, ceq; + + pParam = here->pParam; + cd = fabs (here->B3SOIPDcd); + if (vds > here->B3SOIPDvdsat) + { + esat = 2.0 * pParam->B3SOIPDvsattemp / here->B3SOIPDueff; + T0 = + ((((vds + - here->B3SOIPDvdsat) / pParam->B3SOIPDlitl) + + model->B3SOIPDem) / esat); + DelClm = pParam->B3SOIPDlitl * log (MAX (T0, N_MINLOG)); + } + else + DelClm = 0.0; + EffFreq = pow (freq, model->B3SOIPDef); + T1 = CHARGE * CHARGE * 8.62e-5 * cd * temp * here->B3SOIPDueff; + T2 = 1.0e8 * EffFreq * model->B3SOIPDcox + * pParam->B3SOIPDleff * pParam->B3SOIPDleff; + Vgst = vgs - here->B3SOIPDvon; + N0 = model->B3SOIPDcox * Vgst / CHARGE; + if (N0 < 0.0) + N0 = 0.0; + Nl = model->B3SOIPDcox * (Vgst - MIN (vds, here->B3SOIPDvdsat)) / CHARGE; + if (Nl < 0.0) + Nl = 0.0; + + T3 = model->B3SOIPDoxideTrapDensityA + * log (MAX (((N0 + 2.0e14) / (Nl + 2.0e14)), N_MINLOG)); + T4 = model->B3SOIPDoxideTrapDensityB * (N0 - Nl); + T5 = model->B3SOIPDoxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl); + + T6 = 8.62e-5 * temp * cd * cd; + T7 = 1.0e8 * EffFreq * pParam->B3SOIPDleff + * pParam->B3SOIPDleff * pParam->B3SOIPDweff; + T8 = model->B3SOIPDoxideTrapDensityA + model->B3SOIPDoxideTrapDensityB * Nl + + model->B3SOIPDoxideTrapDensityC * Nl * Nl; + T9 = (Nl + 2.0e14) * (Nl + 2.0e14); + + Ssi = T1 / T2 * (T3 + T4 + T5) + T6 / T7 * DelClm * T8 / T9; + + return Ssi; +} + +int +B3SOIPDnoise (mode, operation, inModel, ckt, data, OnDens) + int mode, operation; + GENmodel *inModel; + CKTcircuit *ckt; + Ndata *data; + double *OnDens; +{ + B3SOIPDmodel *model = (B3SOIPDmodel *) inModel; + B3SOIPDinstance *here; + struct b3soipdSizeDependParam *pParam; + char name[N_MXVLNTH]; + double tempOnoise; + double tempInoise; + double noizDens[B3SOIPDNSRCS]; + double lnNdens[B3SOIPDNSRCS]; + + 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; + + int error, i; + + /* define the names of the noise sources */ + static char *B3SOIPDnNames[B3SOIPDNSRCS] = { /* Note that we have to keep the order */ + ".rd", /* noise due to rd */ + /* consistent with the index definitions */ + ".rs", /* noise due to rs */ + /* in B3SOIPDdefs.h */ + ".id", /* noise due to id */ + ".1overf", /* flicker (1/f) noise */ + ".fb", /* noise due to floating body */ + "" /* total transistor noise */ + }; + + for (; model != NULL; model = model->B3SOIPDnextModel) + { + for (here = model->B3SOIPDinstances; here != NULL; + here = here->B3SOIPDnextInstance) + { + pParam = here->pParam; + switch (operation) + { + case N_OPEN: + /* see if we have to to produce a summary report */ + /* if so, name all the noise generators */ + + if (((NOISEAN *) ckt->CKTcurJob)->NStpsSm != 0) + { + switch (mode) + { + case N_DENS: + for (i = 0; i < B3SOIPDNSRCS; i++) + { + (void) sprintf (name, "onoise.%s%s", + here->B3SOIPDname, + B3SOIPDnNames[i]); + data->namelist = (IFuid *) trealloc ( + (char *) data-> + namelist, + (data-> + numPlots + + 1) * + sizeof + (IFuid)); + if (!data->namelist) + return (E_NOMEM); + (*(SPfrontEnd->IFnewUid)) (ckt, + &(data-> + namelist[data-> + numPlots++]), + (IFuid) NULL, name, + UID_OTHER, + (void **) NULL); + /* we've added one more plot */ + } + break; + case INT_NOIZ: + for (i = 0; i < B3SOIPDNSRCS; i++) + { + (void) sprintf (name, "onoise_total.%s%s", + here->B3SOIPDname, + B3SOIPDnNames[i]); + data->namelist = (IFuid *) trealloc ( + (char *) data-> + namelist, + (data-> + numPlots + + 1) * + sizeof + (IFuid)); + if (!data->namelist) + return (E_NOMEM); + (*(SPfrontEnd->IFnewUid)) (ckt, + &(data-> + namelist[data-> + numPlots++]), + (IFuid) NULL, name, + UID_OTHER, + (void **) NULL); + /* we've added one more plot */ + + (void) sprintf (name, "inoise_total.%s%s", + here->B3SOIPDname, + B3SOIPDnNames[i]); + data->namelist = (IFuid *) trealloc ( + (char *) data-> + namelist, + (data-> + numPlots + + 1) * + sizeof + (IFuid)); + if (!data->namelist) + return (E_NOMEM); + (*(SPfrontEnd->IFnewUid)) (ckt, + &(data-> + namelist[data-> + numPlots++]), + (IFuid) NULL, name, + UID_OTHER, + (void **) NULL); + /* we've added one more plot */ + } + break; + } + } + break; + case N_CALC: + switch (mode) + { + case N_DENS: + NevalSrc (&noizDens[B3SOIPDRDNOIZ], + &lnNdens[B3SOIPDRDNOIZ], ckt, THERMNOISE, + here->B3SOIPDdNodePrime, here->B3SOIPDdNode, + here->B3SOIPDdrainConductance); + + NevalSrc (&noizDens[B3SOIPDRSNOIZ], + &lnNdens[B3SOIPDRSNOIZ], ckt, THERMNOISE, + here->B3SOIPDsNodePrime, here->B3SOIPDsNode, + here->B3SOIPDsourceConductance); + + switch (model->B3SOIPDnoiMod) + { + case 1: + case 3: + NevalSrc (&noizDens[B3SOIPDIDNOIZ], + &lnNdens[B3SOIPDIDNOIZ], ckt, + THERMNOISE, here->B3SOIPDdNodePrime, + here->B3SOIPDsNodePrime, + (2.0 / 3.0 * fabs (here->B3SOIPDgm + + here->B3SOIPDgds + + here->B3SOIPDgmbs))); + break; + case 2: + case 4: + NevalSrc (&noizDens[B3SOIPDIDNOIZ], + &lnNdens[B3SOIPDIDNOIZ], ckt, + THERMNOISE, here->B3SOIPDdNodePrime, + here->B3SOIPDsNodePrime, + (here->B3SOIPDueff + * fabs (here->B3SOIPDqinv + / (pParam->B3SOIPDleff + * pParam->B3SOIPDleff)))); + break; + } + NevalSrc (&noizDens[B3SOIPDFLNOIZ], (double *) NULL, + ckt, N_GAIN, here->B3SOIPDdNodePrime, + here->B3SOIPDsNodePrime, (double) 0.0); + + switch (model->B3SOIPDnoiMod) + { + case 1: + case 4: + noizDens[B3SOIPDFLNOIZ] *= model->B3SOIPDkf + * exp (model->B3SOIPDaf + * log (MAX (fabs (here->B3SOIPDcd), + N_MINLOG))) + / (pow (data->freq, model->B3SOIPDef) + * pParam->B3SOIPDleff + * pParam->B3SOIPDleff * model->B3SOIPDcox); + break; + case 2: + case 3: + vgs = *(ckt->CKTstates[0] + here->B3SOIPDvgs); + vds = *(ckt->CKTstates[0] + here->B3SOIPDvds); + if (vds < 0.0) + { + vds = -vds; + vgs = vgs + vds; + } + if (vgs >= here->B3SOIPDvon + 0.1) + { + Ssi = B3SOIPDStrongInversionNoiseEval (vgs, + vds, model, + here, + data->freq, + ckt-> + CKTtemp); + noizDens[B3SOIPDFLNOIZ] *= Ssi; + } + else + { + pParam = here->pParam; + T10 = model->B3SOIPDoxideTrapDensityA + * 8.62e-5 * ckt->CKTtemp; + T11 = pParam->B3SOIPDweff + * pParam->B3SOIPDleff + * pow (data->freq, model->B3SOIPDef) * 4.0e36; + Swi = T10 / T11 * here->B3SOIPDcd * here->B3SOIPDcd; + Slimit = + B3SOIPDStrongInversionNoiseEval (here-> + B3SOIPDvon + 0.1, + vds, model, here, + data->freq, + ckt->CKTtemp); + T1 = Swi + Slimit; + if (T1 > 0.0) + noizDens[B3SOIPDFLNOIZ] *= (Slimit * Swi) / T1; + else + noizDens[B3SOIPDFLNOIZ] *= 0.0; + } + break; + } + + lnNdens[B3SOIPDFLNOIZ] = + log (MAX (noizDens[B3SOIPDFLNOIZ], N_MINLOG)); + + /* Low frequency excess noise due to FBE */ + NevalSrc (&noizDens[B3SOIPDFBNOIZ], &lnNdens[B3SOIPDFBNOIZ], + ckt, SHOTNOISE, here->B3SOIPDsNodePrime, + here->B3SOIPDbNode, + 2.0 * model->B3SOIPDnoif * here->B3SOIPDibs); + + noizDens[B3SOIPDTOTNOIZ] = noizDens[B3SOIPDRDNOIZ] + + noizDens[B3SOIPDRSNOIZ] + + noizDens[B3SOIPDIDNOIZ] + + noizDens[B3SOIPDFLNOIZ] + noizDens[B3SOIPDFBNOIZ]; + lnNdens[B3SOIPDTOTNOIZ] = + log (MAX (noizDens[B3SOIPDTOTNOIZ], N_MINLOG)); + + *OnDens += noizDens[B3SOIPDTOTNOIZ]; + + if (data->delFreq == 0.0) + { /* if we haven't done any previous + integration, we need to initialize our + "history" variables. + */ + + for (i = 0; i < B3SOIPDNSRCS; i++) + { + here->B3SOIPDnVar[LNLSTDENS][i] = lnNdens[i]; + } + + /* clear out our integration variables + if it's the first pass + */ + if (data->freq == + ((NOISEAN *) ckt->CKTcurJob)->NstartFreq) + { + for (i = 0; i < B3SOIPDNSRCS; i++) + { + here->B3SOIPDnVar[OUTNOIZ][i] = 0.0; + here->B3SOIPDnVar[INNOIZ][i] = 0.0; + } + } + } + else + { /* data->delFreq != 0.0, + we have to integrate. + */ + for (i = 0; i < B3SOIPDNSRCS; i++) + { + if (i != B3SOIPDTOTNOIZ) + { + tempOnoise = Nintegrate (noizDens[i], + lnNdens[i], + here-> + B3SOIPDnVar[LNLSTDENS] + [i], data); + tempInoise = + Nintegrate (noizDens[i] * data->GainSqInv, + lnNdens[i] + data->lnGainInv, + here->B3SOIPDnVar[LNLSTDENS][i] + + data->lnGainInv, data); + here->B3SOIPDnVar[LNLSTDENS][i] = lnNdens[i]; + data->outNoiz += tempOnoise; + data->inNoise += tempInoise; + if (((NOISEAN *) ckt->CKTcurJob)->NStpsSm != 0) + { + here->B3SOIPDnVar[OUTNOIZ][i] += tempOnoise; + here->B3SOIPDnVar[OUTNOIZ][B3SOIPDTOTNOIZ] + += tempOnoise; + here->B3SOIPDnVar[INNOIZ][i] += tempInoise; + here->B3SOIPDnVar[INNOIZ][B3SOIPDTOTNOIZ] + += tempInoise; + } + } + } + } + if (data->prtSummary) + { + for (i = 0; i < B3SOIPDNSRCS; i++) + { /* print a summary report */ + data->outpVector[data->outNumber++] = noizDens[i]; + } + } + break; + case INT_NOIZ: + /* already calculated, just output */ + if (((NOISEAN *) ckt->CKTcurJob)->NStpsSm != 0) + { + for (i = 0; i < B3SOIPDNSRCS; i++) + { + data->outpVector[data->outNumber++] + = here->B3SOIPDnVar[OUTNOIZ][i]; + data->outpVector[data->outNumber++] + = here->B3SOIPDnVar[INNOIZ][i]; + } + } + break; + } + break; + case N_CLOSE: + /* do nothing, the main calling routine will close */ + return (OK); + break; /* the plots */ + } /* switch (operation) */ + } /* for here */ + } /* for model */ + + return (OK); +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdpar.c b/src/spicelib/devices/bsim3soi_pd/b3soipdpar.c new file mode 100644 index 000000000..44f300b1b --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdpar.c @@ -0,0 +1,166 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipdpar.c 98/5/01 +Modified by Pin Su 99/2/15 +**********/ + + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "b3soipddef.h" +#include "sperror.h" +#include "suffix.h" + +int +B3SOIPDparam (param, value, inst, select) + int param; + IFvalue *value; + GENinstance *inst; + IFvalue *select; +{ + B3SOIPDinstance *here = (B3SOIPDinstance *) inst; + switch (param) + { + case B3SOIPD_W: + here->B3SOIPDw = value->rValue; + here->B3SOIPDwGiven = TRUE; + break; + case B3SOIPD_L: + here->B3SOIPDl = value->rValue; + here->B3SOIPDlGiven = TRUE; + break; + case B3SOIPD_AS: + here->B3SOIPDsourceArea = value->rValue; + here->B3SOIPDsourceAreaGiven = TRUE; + break; + case B3SOIPD_AD: + here->B3SOIPDdrainArea = value->rValue; + here->B3SOIPDdrainAreaGiven = TRUE; + break; + case B3SOIPD_PS: + here->B3SOIPDsourcePerimeter = value->rValue; + here->B3SOIPDsourcePerimeterGiven = TRUE; + break; + case B3SOIPD_PD: + here->B3SOIPDdrainPerimeter = value->rValue; + here->B3SOIPDdrainPerimeterGiven = TRUE; + break; + case B3SOIPD_NRS: + here->B3SOIPDsourceSquares = value->rValue; + here->B3SOIPDsourceSquaresGiven = TRUE; + break; + case B3SOIPD_NRD: + here->B3SOIPDdrainSquares = value->rValue; + here->B3SOIPDdrainSquaresGiven = TRUE; + break; + case B3SOIPD_OFF: + here->B3SOIPDoff = value->iValue; + here->B3SOIPDoffGiven = TRUE; + break; + case B3SOIPD_IC_VBS: + here->B3SOIPDicVBS = value->rValue; + here->B3SOIPDicVBSGiven = TRUE; + break; + case B3SOIPD_IC_VDS: + here->B3SOIPDicVDS = value->rValue; + here->B3SOIPDicVDSGiven = TRUE; + break; + case B3SOIPD_IC_VGS: + here->B3SOIPDicVGS = value->rValue; + here->B3SOIPDicVGSGiven = TRUE; + break; + case B3SOIPD_IC_VES: + here->B3SOIPDicVES = value->rValue; + here->B3SOIPDicVESGiven = TRUE; + break; + case B3SOIPD_IC_VPS: + here->B3SOIPDicVPS = value->rValue; + here->B3SOIPDicVPSGiven = TRUE; + break; + case B3SOIPD_BJTOFF: + here->B3SOIPDbjtoff = value->iValue; + here->B3SOIPDbjtoffGiven = TRUE; + break; + case B3SOIPD_DEBUG: + here->B3SOIPDdebugMod = value->iValue; + here->B3SOIPDdebugModGiven = TRUE; + break; + case B3SOIPD_RTH0: + here->B3SOIPDrth0 = value->rValue; + here->B3SOIPDrth0Given = TRUE; + break; + case B3SOIPD_CTH0: + here->B3SOIPDcth0 = value->rValue; + here->B3SOIPDcth0Given = TRUE; + break; + case B3SOIPD_NRB: + here->B3SOIPDbodySquares = value->rValue; + here->B3SOIPDbodySquaresGiven = TRUE; + break; + + +/* v2.0 release */ + case B3SOIPD_NBC: + here->B3SOIPDnbc = value->rValue; + here->B3SOIPDnbcGiven = TRUE; + break; + case B3SOIPD_NSEG: + here->B3SOIPDnseg = value->rValue; + here->B3SOIPDnsegGiven = TRUE; + break; + case B3SOIPD_PDBCP: + here->B3SOIPDpdbcp = value->rValue; + here->B3SOIPDpdbcpGiven = TRUE; + break; + case B3SOIPD_PSBCP: + here->B3SOIPDpsbcp = value->rValue; + here->B3SOIPDpsbcpGiven = TRUE; + break; + case B3SOIPD_AGBCP: + here->B3SOIPDagbcp = value->rValue; + here->B3SOIPDagbcpGiven = TRUE; + break; + case B3SOIPD_AEBCP: + here->B3SOIPDaebcp = value->rValue; + here->B3SOIPDaebcpGiven = TRUE; + break; + case B3SOIPD_VBSUSR: + here->B3SOIPDvbsusr = value->rValue; + here->B3SOIPDvbsusrGiven = TRUE; + break; + case B3SOIPD_TNODEOUT: + here->B3SOIPDtnodeout = value->iValue; + here->B3SOIPDtnodeoutGiven = TRUE; + break; + + + case B3SOIPD_IC: + switch (value->v.numValue) + { + case 5: + here->B3SOIPDicVPS = *(value->v.vec.rVec + 4); + here->B3SOIPDicVPSGiven = TRUE; + case 4: + here->B3SOIPDicVES = *(value->v.vec.rVec + 3); + here->B3SOIPDicVESGiven = TRUE; + case 3: + here->B3SOIPDicVBS = *(value->v.vec.rVec + 2); + here->B3SOIPDicVBSGiven = TRUE; + case 2: + here->B3SOIPDicVGS = *(value->v.vec.rVec + 1); + here->B3SOIPDicVGSGiven = TRUE; + case 1: + here->B3SOIPDicVDS = *(value->v.vec.rVec); + here->B3SOIPDicVDSGiven = TRUE; + break; + default: + return (E_BADPARM); + } + break; + default: + return (E_BADPARM); + } + return (OK); +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdpzld.c b/src/spicelib/devices/bsim3soi_pd/b3soipdpzld.c new file mode 100644 index 000000000..0ad2c329d --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdpzld.c @@ -0,0 +1,153 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipzld.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "complex.h" +#include "sperror.h" +#include "b3soipddef.h" +#include "suffix.h" + +int +B3SOIPDpzLoad (inModel, ckt, s) + GENmodel *inModel; + CKTcircuit *ckt; + SPcomplex *s; +{ + B3SOIPDmodel *model = (B3SOIPDmodel *) inModel; + B3SOIPDinstance *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; + double GSoverlapCap, GDoverlapCap, GBoverlapCap; + double FwdSum, RevSum, Gm, Gmbs; + + for (; model != NULL; model = model->B3SOIPDnextModel) + { + for (here = model->B3SOIPDinstances; here != NULL; + here = here->B3SOIPDnextInstance) + { + if (here->B3SOIPDmode >= 0) + { + Gm = here->B3SOIPDgm; + Gmbs = here->B3SOIPDgmbs; + FwdSum = Gm + Gmbs; + RevSum = 0.0; + cggb = here->B3SOIPDcggb; + cgsb = here->B3SOIPDcgsb; + cgdb = here->B3SOIPDcgdb; + + cbgb = here->B3SOIPDcbgb; + cbsb = here->B3SOIPDcbsb; + cbdb = here->B3SOIPDcbdb; + + cdgb = here->B3SOIPDcdgb; + cdsb = here->B3SOIPDcdsb; + cddb = here->B3SOIPDcddb; + } + else + { + Gm = -here->B3SOIPDgm; + Gmbs = -here->B3SOIPDgmbs; + FwdSum = 0.0; + RevSum = -Gm - Gmbs; + cggb = here->B3SOIPDcggb; + cgsb = here->B3SOIPDcgdb; + cgdb = here->B3SOIPDcgsb; + + cbgb = here->B3SOIPDcbgb; + cbsb = here->B3SOIPDcbdb; + cbdb = here->B3SOIPDcbsb; + + cdgb = -(here->B3SOIPDcdgb + cggb + cbgb); + cdsb = -(here->B3SOIPDcddb + cgsb + cbsb); + cddb = -(here->B3SOIPDcdsb + cgdb + cbdb); + } + gdpr = here->B3SOIPDdrainConductance; + gspr = here->B3SOIPDsourceConductance; + gds = here->B3SOIPDgds; + gbd = here->B3SOIPDgjdb; + gbs = here->B3SOIPDgjsb; +#ifdef BULKCODE + capbd = here->B3SOIPDcapbd; + capbs = here->B3SOIPDcapbs; +#endif + GSoverlapCap = here->B3SOIPDcgso; + GDoverlapCap = here->B3SOIPDcgdo; +#ifdef BULKCODE + GBoverlapCap = here->pParam->B3SOIPDcgbo; +#endif + + xcdgb = (cdgb - GDoverlapCap); + xcddb = (cddb + capbd + GDoverlapCap); + xcdsb = cdsb; + xcsgb = -(cggb + cbgb + cdgb + GSoverlapCap); + xcsdb = -(cgdb + cbdb + cddb); + xcssb = (capbs + GSoverlapCap - (cgsb + cbsb + cdsb)); + xcggb = (cggb + GDoverlapCap + GSoverlapCap + GBoverlapCap); + xcgdb = (cgdb - GDoverlapCap); + xcgsb = (cgsb - GSoverlapCap); + xcbgb = (cbgb - GBoverlapCap); + xcbdb = (cbdb - capbd); + xcbsb = (cbsb - capbs); + + + *(here->B3SOIPDGgPtr) += xcggb * s->real; + *(here->B3SOIPDGgPtr + 1) += xcggb * s->imag; + *(here->B3SOIPDBbPtr) += (-xcbgb - xcbdb - xcbsb) * s->real; + *(here->B3SOIPDBbPtr + 1) += (-xcbgb - xcbdb - xcbsb) * s->imag; + *(here->B3SOIPDDPdpPtr) += xcddb * s->real; + *(here->B3SOIPDDPdpPtr + 1) += xcddb * s->imag; + *(here->B3SOIPDSPspPtr) += xcssb * s->real; + *(here->B3SOIPDSPspPtr + 1) += xcssb * s->imag; + *(here->B3SOIPDGbPtr) += (-xcggb - xcgdb - xcgsb) * s->real; + *(here->B3SOIPDGbPtr + 1) += (-xcggb - xcgdb - xcgsb) * s->imag; + *(here->B3SOIPDGdpPtr) += xcgdb * s->real; + *(here->B3SOIPDGdpPtr + 1) += xcgdb * s->imag; + *(here->B3SOIPDGspPtr) += xcgsb * s->real; + *(here->B3SOIPDGspPtr + 1) += xcgsb * s->imag; + *(here->B3SOIPDBgPtr) += xcbgb * s->real; + *(here->B3SOIPDBgPtr + 1) += xcbgb * s->imag; + *(here->B3SOIPDBdpPtr) += xcbdb * s->real; + *(here->B3SOIPDBdpPtr + 1) += xcbdb * s->imag; + *(here->B3SOIPDBspPtr) += xcbsb * s->real; + *(here->B3SOIPDBspPtr + 1) += xcbsb * s->imag; + *(here->B3SOIPDDPgPtr) += xcdgb * s->real; + *(here->B3SOIPDDPgPtr + 1) += xcdgb * s->imag; + *(here->B3SOIPDDPbPtr) += (-xcdgb - xcddb - xcdsb) * s->real; + *(here->B3SOIPDDPbPtr + 1) += (-xcdgb - xcddb - xcdsb) * s->imag; + *(here->B3SOIPDDPspPtr) += xcdsb * s->real; + *(here->B3SOIPDDPspPtr + 1) += xcdsb * s->imag; + *(here->B3SOIPDSPgPtr) += xcsgb * s->real; + *(here->B3SOIPDSPgPtr + 1) += xcsgb * s->imag; + *(here->B3SOIPDSPbPtr) += (-xcsgb - xcsdb - xcssb) * s->real; + *(here->B3SOIPDSPbPtr + 1) += (-xcsgb - xcsdb - xcssb) * s->imag; + *(here->B3SOIPDSPdpPtr) += xcsdb * s->real; + *(here->B3SOIPDSPdpPtr + 1) += xcsdb * s->imag; + *(here->B3SOIPDDdPtr) += gdpr; + *(here->B3SOIPDSsPtr) += gspr; + *(here->B3SOIPDBbPtr) += gbd + gbs; + *(here->B3SOIPDDPdpPtr) += gdpr + gds + gbd + RevSum; + *(here->B3SOIPDSPspPtr) += gspr + gds + gbs + FwdSum; + *(here->B3SOIPDDdpPtr) -= gdpr; + *(here->B3SOIPDSspPtr) -= gspr; + *(here->B3SOIPDBdpPtr) -= gbd; + *(here->B3SOIPDBspPtr) -= gbs; + *(here->B3SOIPDDPdPtr) -= gdpr; + *(here->B3SOIPDDPgPtr) += Gm; + *(here->B3SOIPDDPbPtr) -= gbd - Gmbs; + *(here->B3SOIPDDPspPtr) -= gds + FwdSum; + *(here->B3SOIPDSPgPtr) -= Gm; + *(here->B3SOIPDSPsPtr) -= gspr; + *(here->B3SOIPDSPbPtr) -= gbs + Gmbs; + *(here->B3SOIPDSPdpPtr) -= gds + RevSum; + + } + } + return (OK); +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdset.c b/src/spicelib/devices/bsim3soi_pd/b3soipdset.c new file mode 100644 index 000000000..53ef0802e --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdset.c @@ -0,0 +1,1498 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipdset.c 98/5/01 +Modified by Pin Su and Jan Feng 99/2/15 +Modified by Pin Su 99/4/30 +Modified by Pin Su, Wei Jin 99/9/27 +Modified by Pin Su 00/3/1 +**********/ + + +#include "ngspice.h" +#include +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "b3soipddef.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + +#define SMOOTHFACTOR 0.1 +#define EPSOX 3.453133e-11 +#define EPSSI 1.03594e-10 +#define PI 3.141592654 +#define Charge_q 1.60219e-19 +#define Meter2Micron 1.0e6 + +int +B3SOIPDsetup (matrix, inModel, ckt, states) + SMPmatrix *matrix; + GENmodel *inModel; + CKTcircuit *ckt; + int *states; +{ + B3SOIPDmodel *model = (B3SOIPDmodel *) inModel; + B3SOIPDinstance *here; + int error; + CKTnode *tmp; + + double tmp1, tmp2; + double nfb0, Cboxt; + int itmp1; + + /* loop through all the B3SOIPD device models */ + for (; model != NULL; model = model->B3SOIPDnextModel) + { +/* Default value Processing for B3SOIPD MOSFET Models */ + + if (!model->B3SOIPDtypeGiven) + model->B3SOIPDtype = NMOS; + if (!model->B3SOIPDmobModGiven) + model->B3SOIPDmobMod = 1; + if (!model->B3SOIPDbinUnitGiven) + model->B3SOIPDbinUnit = 1; + if (!model->B3SOIPDparamChkGiven) + model->B3SOIPDparamChk = 0; + if (!model->B3SOIPDcapModGiven) + model->B3SOIPDcapMod = 2; + if (!model->B3SOIPDnoiModGiven) + model->B3SOIPDnoiMod = 1; + if (!model->B3SOIPDshModGiven) + model->B3SOIPDshMod = 0; + if (!model->B3SOIPDversionGiven) + model->B3SOIPDversion = 2.0; + if (!model->B3SOIPDtoxGiven) + model->B3SOIPDtox = 100.0e-10; + model->B3SOIPDcox = 3.453133e-11 / model->B3SOIPDtox; + + if (!model->B3SOIPDcdscGiven) + model->B3SOIPDcdsc = 2.4e-4; /* unit Q/V/m^2 */ + if (!model->B3SOIPDcdscbGiven) + model->B3SOIPDcdscb = 0.0; /* unit Q/V/m^2 */ + if (!model->B3SOIPDcdscdGiven) + model->B3SOIPDcdscd = 0.0; /* unit Q/V/m^2 */ + if (!model->B3SOIPDcitGiven) + model->B3SOIPDcit = 0.0; /* unit Q/V/m^2 */ + if (!model->B3SOIPDnfactorGiven) + model->B3SOIPDnfactor = 1; + if (!model->B3SOIPDvsatGiven) + model->B3SOIPDvsat = 8.0e4; /* unit m/s */ + if (!model->B3SOIPDatGiven) + model->B3SOIPDat = 3.3e4; /* unit m/s */ + if (!model->B3SOIPDa0Given) + model->B3SOIPDa0 = 1.0; + if (!model->B3SOIPDagsGiven) + model->B3SOIPDags = 0.0; + if (!model->B3SOIPDa1Given) + model->B3SOIPDa1 = 0.0; + if (!model->B3SOIPDa2Given) + model->B3SOIPDa2 = 1.0; + if (!model->B3SOIPDketaGiven) + model->B3SOIPDketa = -0.6; /* unit / V */ + if (!model->B3SOIPDnsubGiven) + model->B3SOIPDnsub = 6.0e16; /* unit 1/cm3 */ + if (!model->B3SOIPDnpeakGiven) + model->B3SOIPDnpeak = 1.7e17; /* unit 1/cm3 */ + if (!model->B3SOIPDngateGiven) + model->B3SOIPDngate = 0; /* unit 1/cm3 */ + if (!model->B3SOIPDvbmGiven) + model->B3SOIPDvbm = -3.0; + if (!model->B3SOIPDxtGiven) + model->B3SOIPDxt = 1.55e-7; + if (!model->B3SOIPDkt1Given) + model->B3SOIPDkt1 = -0.11; /* unit V */ + if (!model->B3SOIPDkt1lGiven) + model->B3SOIPDkt1l = 0.0; /* unit V*m */ + if (!model->B3SOIPDkt2Given) + model->B3SOIPDkt2 = 0.022; /* No unit */ + if (!model->B3SOIPDk3Given) + model->B3SOIPDk3 = 0.0; + if (!model->B3SOIPDk3bGiven) + model->B3SOIPDk3b = 0.0; + if (!model->B3SOIPDw0Given) + model->B3SOIPDw0 = 2.5e-6; + if (!model->B3SOIPDnlxGiven) + model->B3SOIPDnlx = 1.74e-7; + if (!model->B3SOIPDdvt0Given) + model->B3SOIPDdvt0 = 2.2; + if (!model->B3SOIPDdvt1Given) + model->B3SOIPDdvt1 = 0.53; + if (!model->B3SOIPDdvt2Given) + model->B3SOIPDdvt2 = -0.032; /* unit 1 / V */ + + if (!model->B3SOIPDdvt0wGiven) + model->B3SOIPDdvt0w = 0.0; + if (!model->B3SOIPDdvt1wGiven) + model->B3SOIPDdvt1w = 5.3e6; + if (!model->B3SOIPDdvt2wGiven) + model->B3SOIPDdvt2w = -0.032; + + if (!model->B3SOIPDdroutGiven) + model->B3SOIPDdrout = 0.56; + if (!model->B3SOIPDdsubGiven) + model->B3SOIPDdsub = model->B3SOIPDdrout; + if (!model->B3SOIPDvth0Given) + model->B3SOIPDvth0 = (model->B3SOIPDtype == NMOS) ? 0.7 : -0.7; + if (!model->B3SOIPDuaGiven) + model->B3SOIPDua = 2.25e-9; /* unit m/V */ + if (!model->B3SOIPDua1Given) + model->B3SOIPDua1 = 4.31e-9; /* unit m/V */ + if (!model->B3SOIPDubGiven) + model->B3SOIPDub = 5.87e-19; /* unit (m/V)**2 */ + if (!model->B3SOIPDub1Given) + model->B3SOIPDub1 = -7.61e-18; /* unit (m/V)**2 */ + if (!model->B3SOIPDucGiven) + model->B3SOIPDuc = (model->B3SOIPDmobMod == 3) ? -0.0465 : -0.0465e-9; + if (!model->B3SOIPDuc1Given) + model->B3SOIPDuc1 = (model->B3SOIPDmobMod == 3) ? -0.056 : -0.056e-9; + if (!model->B3SOIPDu0Given) + model->B3SOIPDu0 = (model->B3SOIPDtype == NMOS) ? 0.067 : 0.025; + if (!model->B3SOIPDuteGiven) + model->B3SOIPDute = -1.5; + if (!model->B3SOIPDvoffGiven) + model->B3SOIPDvoff = -0.08; + if (!model->B3SOIPDdeltaGiven) + model->B3SOIPDdelta = 0.01; + if (!model->B3SOIPDrdswGiven) + model->B3SOIPDrdsw = 100; + if (!model->B3SOIPDprwgGiven) + model->B3SOIPDprwg = 0.0; /* unit 1/V */ + if (!model->B3SOIPDprwbGiven) + model->B3SOIPDprwb = 0.0; + if (!model->B3SOIPDprtGiven) + if (!model->B3SOIPDprtGiven) + model->B3SOIPDprt = 0.0; + if (!model->B3SOIPDeta0Given) + model->B3SOIPDeta0 = 0.08; /* no unit */ + if (!model->B3SOIPDetabGiven) + model->B3SOIPDetab = -0.07; /* unit 1/V */ + if (!model->B3SOIPDpclmGiven) + model->B3SOIPDpclm = 1.3; /* no unit */ + if (!model->B3SOIPDpdibl1Given) + model->B3SOIPDpdibl1 = .39; /* no unit */ + if (!model->B3SOIPDpdibl2Given) + model->B3SOIPDpdibl2 = 0.0086; /* no unit */ + if (!model->B3SOIPDpdiblbGiven) + model->B3SOIPDpdiblb = 0.0; /* 1/V */ + if (!model->B3SOIPDpvagGiven) + model->B3SOIPDpvag = 0.0; + if (!model->B3SOIPDwrGiven) + model->B3SOIPDwr = 1.0; + if (!model->B3SOIPDdwgGiven) + model->B3SOIPDdwg = 0.0; + if (!model->B3SOIPDdwbGiven) + model->B3SOIPDdwb = 0.0; + if (!model->B3SOIPDb0Given) + model->B3SOIPDb0 = 0.0; + if (!model->B3SOIPDb1Given) + model->B3SOIPDb1 = 0.0; + if (!model->B3SOIPDalpha0Given) + model->B3SOIPDalpha0 = 0.0; + + if (!model->B3SOIPDcgslGiven) + model->B3SOIPDcgsl = 0.0; + if (!model->B3SOIPDcgdlGiven) + model->B3SOIPDcgdl = 0.0; + if (!model->B3SOIPDckappaGiven) + model->B3SOIPDckappa = 0.6; + if (!model->B3SOIPDclcGiven) + model->B3SOIPDclc = 0.1e-7; + if (!model->B3SOIPDcleGiven) + model->B3SOIPDcle = 0.0; + if (!model->B3SOIPDtboxGiven) + model->B3SOIPDtbox = 3e-7; + if (!model->B3SOIPDtsiGiven) + model->B3SOIPDtsi = 1e-7; + if (!model->B3SOIPDxjGiven) + model->B3SOIPDxj = model->B3SOIPDtsi; + if (!model->B3SOIPDrbodyGiven) + model->B3SOIPDrbody = 0.0; + if (!model->B3SOIPDrbshGiven) + model->B3SOIPDrbsh = 0.0; + if (!model->B3SOIPDrth0Given) + model->B3SOIPDrth0 = 0; + + if (!model->B3SOIPDcth0Given) + model->B3SOIPDcth0 = 0; + + if (!model->B3SOIPDagidlGiven) + model->B3SOIPDagidl = 0.0; + if (!model->B3SOIPDbgidlGiven) + model->B3SOIPDbgidl = 0.0; + if (!model->B3SOIPDngidlGiven) + model->B3SOIPDngidl = 1.2; + if (!model->B3SOIPDndiodeGiven) + model->B3SOIPDndiode = 1.0; + if (!model->B3SOIPDntunGiven) + model->B3SOIPDntun = 10.0; + + if (!model->B3SOIPDnrecf0Given) + model->B3SOIPDnrecf0 = 2.0; + if (!model->B3SOIPDnrecr0Given) + model->B3SOIPDnrecr0 = 10.0; + + if (!model->B3SOIPDisbjtGiven) + model->B3SOIPDisbjt = 1e-6; + if (!model->B3SOIPDisdifGiven) + model->B3SOIPDisdif = 0.0; + if (!model->B3SOIPDisrecGiven) + model->B3SOIPDisrec = 1e-5; + if (!model->B3SOIPDistunGiven) + model->B3SOIPDistun = 0.0; + if (!model->B3SOIPDxbjtGiven) + model->B3SOIPDxbjt = 1; +/* + if (!model->B3SOIPDxdifGiven) + model->B3SOIPDxdif = 1; +*/ + if (!model->B3SOIPDxdifGiven) + model->B3SOIPDxdif = model->B3SOIPDxbjt; + + if (!model->B3SOIPDxrecGiven) + model->B3SOIPDxrec = 1; + if (!model->B3SOIPDxtunGiven) + model->B3SOIPDxtun = 0; + if (!model->B3SOIPDttGiven) + model->B3SOIPDtt = 1e-12; + if (!model->B3SOIPDasdGiven) + model->B3SOIPDasd = 0.3; + + /* unit degree celcius */ + if (!model->B3SOIPDtnomGiven) + model->B3SOIPDtnom = ckt->CKTnomTemp; + if (!model->B3SOIPDLintGiven) + model->B3SOIPDLint = 0.0; + if (!model->B3SOIPDLlGiven) + model->B3SOIPDLl = 0.0; + if (!model->B3SOIPDLlnGiven) + model->B3SOIPDLln = 1.0; + if (!model->B3SOIPDLwGiven) + model->B3SOIPDLw = 0.0; + if (!model->B3SOIPDLwnGiven) + model->B3SOIPDLwn = 1.0; + if (!model->B3SOIPDLwlGiven) + model->B3SOIPDLwl = 0.0; + if (!model->B3SOIPDLminGiven) + model->B3SOIPDLmin = 0.0; + if (!model->B3SOIPDLmaxGiven) + model->B3SOIPDLmax = 1.0; + if (!model->B3SOIPDWintGiven) + model->B3SOIPDWint = 0.0; + if (!model->B3SOIPDWlGiven) + model->B3SOIPDWl = 0.0; + if (!model->B3SOIPDWlnGiven) + model->B3SOIPDWln = 1.0; + if (!model->B3SOIPDWwGiven) + model->B3SOIPDWw = 0.0; + if (!model->B3SOIPDWwnGiven) + model->B3SOIPDWwn = 1.0; + if (!model->B3SOIPDWwlGiven) + model->B3SOIPDWwl = 0.0; + if (!model->B3SOIPDWminGiven) + model->B3SOIPDWmin = 0.0; + if (!model->B3SOIPDWmaxGiven) + model->B3SOIPDWmax = 1.0; + if (!model->B3SOIPDdwcGiven) + model->B3SOIPDdwc = model->B3SOIPDWint; + if (!model->B3SOIPDdlcGiven) + model->B3SOIPDdlc = model->B3SOIPDLint; + + +/* v2.2 release */ + if (!model->B3SOIPDwth0Given) + model->B3SOIPDwth0 = 0.0; + if (!model->B3SOIPDrhaloGiven) + model->B3SOIPDrhalo = 1e15; + if (!model->B3SOIPDntoxGiven) + model->B3SOIPDntox = 1; + if (!model->B3SOIPDtoxrefGiven) + model->B3SOIPDtoxref = 2.5e-9; + if (!model->B3SOIPDebgGiven) + model->B3SOIPDebg = 1.2; + if (!model->B3SOIPDnevbGiven) + model->B3SOIPDnevb = 3; + if (!model->B3SOIPDalphaGB1Given) + model->B3SOIPDalphaGB1 = 0.35; + if (!model->B3SOIPDbetaGB1Given) + model->B3SOIPDbetaGB1 = 0.03; + if (!model->B3SOIPDvgb1Given) + model->B3SOIPDvgb1 = 300; + if (!model->B3SOIPDalphaGB2Given) + model->B3SOIPDalphaGB2 = 0.43; + if (!model->B3SOIPDbetaGB2Given) + model->B3SOIPDbetaGB2 = 0.05; + if (!model->B3SOIPDnecbGiven) + model->B3SOIPDnecb = 1; + if (!model->B3SOIPDvgb2Given) + model->B3SOIPDvgb2 = 17; + if (!model->B3SOIPDtoxqmGiven) + model->B3SOIPDtoxqm = model->B3SOIPDtox; + if (!model->B3SOIPDvoxhGiven) + model->B3SOIPDvoxh = 5.0; + if (!model->B3SOIPDdeltavoxGiven) + model->B3SOIPDdeltavox = 0.005; + if (!model->B3SOIPDigModGiven) + model->B3SOIPDigMod = 0; + + +/* v2.0 release */ + if (!model->B3SOIPDk1w1Given) + model->B3SOIPDk1w1 = 0.0; + if (!model->B3SOIPDk1w2Given) + model->B3SOIPDk1w2 = 0.0; + if (!model->B3SOIPDketasGiven) + model->B3SOIPDketas = 0.0; + if (!model->B3SOIPDdwbcGiven) + model->B3SOIPDdwbc = 0.0; + if (!model->B3SOIPDbeta0Given) + model->B3SOIPDbeta0 = 0.0; + if (!model->B3SOIPDbeta1Given) + model->B3SOIPDbeta1 = 0.0; + if (!model->B3SOIPDbeta2Given) + model->B3SOIPDbeta2 = 0.1; + if (!model->B3SOIPDvdsatii0Given) + model->B3SOIPDvdsatii0 = 0.9; + if (!model->B3SOIPDtiiGiven) + model->B3SOIPDtii = 0.0; + if (!model->B3SOIPDliiGiven) + model->B3SOIPDlii = 0.0; + if (!model->B3SOIPDsii0Given) + model->B3SOIPDsii0 = 0.5; + if (!model->B3SOIPDsii1Given) + model->B3SOIPDsii1 = 0.1; + if (!model->B3SOIPDsii2Given) + model->B3SOIPDsii2 = 0.0; + if (!model->B3SOIPDsiidGiven) + model->B3SOIPDsiid = 0.0; + if (!model->B3SOIPDfbjtiiGiven) + model->B3SOIPDfbjtii = 0.0; + if (!model->B3SOIPDesatiiGiven) + model->B3SOIPDesatii = 1e7; + if (!model->B3SOIPDlnGiven) + model->B3SOIPDln = 2e-6; + if (!model->B3SOIPDvrec0Given) + model->B3SOIPDvrec0 = 0; + if (!model->B3SOIPDvtun0Given) + model->B3SOIPDvtun0 = 0; + if (!model->B3SOIPDnbjtGiven) + model->B3SOIPDnbjt = 1.0; + if (!model->B3SOIPDlbjt0Given) + model->B3SOIPDlbjt0 = 0.20e-6; + if (!model->B3SOIPDldif0Given) + model->B3SOIPDldif0 = 1.0; + if (!model->B3SOIPDvabjtGiven) + model->B3SOIPDvabjt = 10.0; + if (!model->B3SOIPDaelyGiven) + model->B3SOIPDaely = 0; + if (!model->B3SOIPDahliGiven) + model->B3SOIPDahli = 0; + if (!model->B3SOIPDrbodyGiven) + model->B3SOIPDrbody = 0.0; + if (!model->B3SOIPDrbshGiven) + model->B3SOIPDrbsh = 0.0; + if (!model->B3SOIPDntrecfGiven) + model->B3SOIPDntrecf = 0.0; + if (!model->B3SOIPDntrecrGiven) + model->B3SOIPDntrecr = 0.0; + if (!model->B3SOIPDndifGiven) + model->B3SOIPDndif = -1.0; + if (!model->B3SOIPDdlcbGiven) + model->B3SOIPDdlcb = 0.0; + if (!model->B3SOIPDfbodyGiven) + model->B3SOIPDfbody = 1.0; + if (!model->B3SOIPDtcjswgGiven) + model->B3SOIPDtcjswg = 0.0; + if (!model->B3SOIPDtpbswgGiven) + model->B3SOIPDtpbswg = 0.0; + if (!model->B3SOIPDacdeGiven) + model->B3SOIPDacde = 1.0; + if (!model->B3SOIPDmoinGiven) + model->B3SOIPDmoin = 15.0; + if (!model->B3SOIPDdelvtGiven) + model->B3SOIPDdelvt = 0.0; + if (!model->B3SOIPDkb1Given) + model->B3SOIPDkb1 = 1.0; + if (!model->B3SOIPDdlbgGiven) + model->B3SOIPDdlbg = 0.0; + +/* Added for binning - START */ + /* Length dependence */ + if (!model->B3SOIPDlnpeakGiven) + model->B3SOIPDlnpeak = 0.0; + if (!model->B3SOIPDlnsubGiven) + model->B3SOIPDlnsub = 0.0; + if (!model->B3SOIPDlngateGiven) + model->B3SOIPDlngate = 0.0; + if (!model->B3SOIPDlvth0Given) + model->B3SOIPDlvth0 = 0.0; + if (!model->B3SOIPDlk1Given) + model->B3SOIPDlk1 = 0.0; + if (!model->B3SOIPDlk1w1Given) + model->B3SOIPDlk1w1 = 0.0; + if (!model->B3SOIPDlk1w2Given) + model->B3SOIPDlk1w2 = 0.0; + if (!model->B3SOIPDlk2Given) + model->B3SOIPDlk2 = 0.0; + if (!model->B3SOIPDlk3Given) + model->B3SOIPDlk3 = 0.0; + if (!model->B3SOIPDlk3bGiven) + model->B3SOIPDlk3b = 0.0; + if (!model->B3SOIPDlkb1Given) + model->B3SOIPDlkb1 = 0.0; + if (!model->B3SOIPDlw0Given) + model->B3SOIPDlw0 = 0.0; + if (!model->B3SOIPDlnlxGiven) + model->B3SOIPDlnlx = 0.0; + if (!model->B3SOIPDldvt0Given) + model->B3SOIPDldvt0 = 0.0; + if (!model->B3SOIPDldvt1Given) + model->B3SOIPDldvt1 = 0.0; + if (!model->B3SOIPDldvt2Given) + model->B3SOIPDldvt2 = 0.0; + if (!model->B3SOIPDldvt0wGiven) + model->B3SOIPDldvt0w = 0.0; + if (!model->B3SOIPDldvt1wGiven) + model->B3SOIPDldvt1w = 0.0; + if (!model->B3SOIPDldvt2wGiven) + model->B3SOIPDldvt2w = 0.0; + if (!model->B3SOIPDlu0Given) + model->B3SOIPDlu0 = 0.0; + if (!model->B3SOIPDluaGiven) + model->B3SOIPDlua = 0.0; + if (!model->B3SOIPDlubGiven) + model->B3SOIPDlub = 0.0; + if (!model->B3SOIPDlucGiven) + model->B3SOIPDluc = 0.0; + if (!model->B3SOIPDlvsatGiven) + model->B3SOIPDlvsat = 0.0; + if (!model->B3SOIPDla0Given) + model->B3SOIPDla0 = 0.0; + if (!model->B3SOIPDlagsGiven) + model->B3SOIPDlags = 0.0; + if (!model->B3SOIPDlb0Given) + model->B3SOIPDlb0 = 0.0; + if (!model->B3SOIPDlb1Given) + model->B3SOIPDlb1 = 0.0; + if (!model->B3SOIPDlketaGiven) + model->B3SOIPDlketa = 0.0; + if (!model->B3SOIPDlketasGiven) + model->B3SOIPDlketas = 0.0; + if (!model->B3SOIPDla1Given) + model->B3SOIPDla1 = 0.0; + if (!model->B3SOIPDla2Given) + model->B3SOIPDla2 = 0.0; + if (!model->B3SOIPDlrdswGiven) + model->B3SOIPDlrdsw = 0.0; + if (!model->B3SOIPDlprwbGiven) + model->B3SOIPDlprwb = 0.0; + if (!model->B3SOIPDlprwgGiven) + model->B3SOIPDlprwg = 0.0; + if (!model->B3SOIPDlwrGiven) + model->B3SOIPDlwr = 0.0; + if (!model->B3SOIPDlnfactorGiven) + model->B3SOIPDlnfactor = 0.0; + if (!model->B3SOIPDldwgGiven) + model->B3SOIPDldwg = 0.0; + if (!model->B3SOIPDldwbGiven) + model->B3SOIPDldwb = 0.0; + if (!model->B3SOIPDlvoffGiven) + model->B3SOIPDlvoff = 0.0; + if (!model->B3SOIPDleta0Given) + model->B3SOIPDleta0 = 0.0; + if (!model->B3SOIPDletabGiven) + model->B3SOIPDletab = 0.0; + if (!model->B3SOIPDldsubGiven) + model->B3SOIPDldsub = 0.0; + if (!model->B3SOIPDlcitGiven) + model->B3SOIPDlcit = 0.0; + if (!model->B3SOIPDlcdscGiven) + model->B3SOIPDlcdsc = 0.0; + if (!model->B3SOIPDlcdscbGiven) + model->B3SOIPDlcdscb = 0.0; + if (!model->B3SOIPDlcdscdGiven) + model->B3SOIPDlcdscd = 0.0; + if (!model->B3SOIPDlpclmGiven) + model->B3SOIPDlpclm = 0.0; + if (!model->B3SOIPDlpdibl1Given) + model->B3SOIPDlpdibl1 = 0.0; + if (!model->B3SOIPDlpdibl2Given) + model->B3SOIPDlpdibl2 = 0.0; + if (!model->B3SOIPDlpdiblbGiven) + model->B3SOIPDlpdiblb = 0.0; + if (!model->B3SOIPDldroutGiven) + model->B3SOIPDldrout = 0.0; + if (!model->B3SOIPDlpvagGiven) + model->B3SOIPDlpvag = 0.0; + if (!model->B3SOIPDldeltaGiven) + model->B3SOIPDldelta = 0.0; + if (!model->B3SOIPDlalpha0Given) + model->B3SOIPDlalpha0 = 0.0; + if (!model->B3SOIPDlfbjtiiGiven) + model->B3SOIPDlfbjtii = 0.0; + if (!model->B3SOIPDlbeta0Given) + model->B3SOIPDlbeta0 = 0.0; + if (!model->B3SOIPDlbeta1Given) + model->B3SOIPDlbeta1 = 0.0; + if (!model->B3SOIPDlbeta2Given) + model->B3SOIPDlbeta2 = 0.0; + if (!model->B3SOIPDlvdsatii0Given) + model->B3SOIPDlvdsatii0 = 0.0; + if (!model->B3SOIPDlliiGiven) + model->B3SOIPDllii = 0.0; + if (!model->B3SOIPDlesatiiGiven) + model->B3SOIPDlesatii = 0.0; + if (!model->B3SOIPDlsii0Given) + model->B3SOIPDlsii0 = 0.0; + if (!model->B3SOIPDlsii1Given) + model->B3SOIPDlsii1 = 0.0; + if (!model->B3SOIPDlsii2Given) + model->B3SOIPDlsii2 = 0.0; + if (!model->B3SOIPDlsiidGiven) + model->B3SOIPDlsiid = 0.0; + if (!model->B3SOIPDlagidlGiven) + model->B3SOIPDlagidl = 0.0; + if (!model->B3SOIPDlbgidlGiven) + model->B3SOIPDlbgidl = 0.0; + if (!model->B3SOIPDlngidlGiven) + model->B3SOIPDlngidl = 0.0; + if (!model->B3SOIPDlntunGiven) + model->B3SOIPDlntun = 0.0; + if (!model->B3SOIPDlndiodeGiven) + model->B3SOIPDlndiode = 0.0; + if (!model->B3SOIPDlnrecf0Given) + model->B3SOIPDlnrecf0 = 0.0; + if (!model->B3SOIPDlnrecr0Given) + model->B3SOIPDlnrecr0 = 0.0; + if (!model->B3SOIPDlisbjtGiven) + model->B3SOIPDlisbjt = 0.0; + if (!model->B3SOIPDlisdifGiven) + model->B3SOIPDlisdif = 0.0; + if (!model->B3SOIPDlisrecGiven) + model->B3SOIPDlisrec = 0.0; + if (!model->B3SOIPDlistunGiven) + model->B3SOIPDlistun = 0.0; + if (!model->B3SOIPDlvrec0Given) + model->B3SOIPDlvrec0 = 0.0; + if (!model->B3SOIPDlvtun0Given) + model->B3SOIPDlvtun0 = 0.0; + if (!model->B3SOIPDlnbjtGiven) + model->B3SOIPDlnbjt = 0.0; + if (!model->B3SOIPDllbjt0Given) + model->B3SOIPDllbjt0 = 0.0; + if (!model->B3SOIPDlvabjtGiven) + model->B3SOIPDlvabjt = 0.0; + if (!model->B3SOIPDlaelyGiven) + model->B3SOIPDlaely = 0.0; + if (!model->B3SOIPDlahliGiven) + model->B3SOIPDlahli = 0.0; + /* CV Model */ + if (!model->B3SOIPDlvsdfbGiven) + model->B3SOIPDlvsdfb = 0.0; + if (!model->B3SOIPDlvsdthGiven) + model->B3SOIPDlvsdth = 0.0; + if (!model->B3SOIPDldelvtGiven) + model->B3SOIPDldelvt = 0.0; + if (!model->B3SOIPDlacdeGiven) + model->B3SOIPDlacde = 0.0; + if (!model->B3SOIPDlmoinGiven) + model->B3SOIPDlmoin = 0.0; + + /* Width dependence */ + if (!model->B3SOIPDwnpeakGiven) + model->B3SOIPDwnpeak = 0.0; + if (!model->B3SOIPDwnsubGiven) + model->B3SOIPDwnsub = 0.0; + if (!model->B3SOIPDwngateGiven) + model->B3SOIPDwngate = 0.0; + if (!model->B3SOIPDwvth0Given) + model->B3SOIPDwvth0 = 0.0; + if (!model->B3SOIPDwk1Given) + model->B3SOIPDwk1 = 0.0; + if (!model->B3SOIPDwk1w1Given) + model->B3SOIPDwk1w1 = 0.0; + if (!model->B3SOIPDwk1w2Given) + model->B3SOIPDwk1w2 = 0.0; + if (!model->B3SOIPDwk2Given) + model->B3SOIPDwk2 = 0.0; + if (!model->B3SOIPDwk3Given) + model->B3SOIPDwk3 = 0.0; + if (!model->B3SOIPDwk3bGiven) + model->B3SOIPDwk3b = 0.0; + if (!model->B3SOIPDwkb1Given) + model->B3SOIPDwkb1 = 0.0; + if (!model->B3SOIPDww0Given) + model->B3SOIPDww0 = 0.0; + if (!model->B3SOIPDwnlxGiven) + model->B3SOIPDwnlx = 0.0; + if (!model->B3SOIPDwdvt0Given) + model->B3SOIPDwdvt0 = 0.0; + if (!model->B3SOIPDwdvt1Given) + model->B3SOIPDwdvt1 = 0.0; + if (!model->B3SOIPDwdvt2Given) + model->B3SOIPDwdvt2 = 0.0; + if (!model->B3SOIPDwdvt0wGiven) + model->B3SOIPDwdvt0w = 0.0; + if (!model->B3SOIPDwdvt1wGiven) + model->B3SOIPDwdvt1w = 0.0; + if (!model->B3SOIPDwdvt2wGiven) + model->B3SOIPDwdvt2w = 0.0; + if (!model->B3SOIPDwu0Given) + model->B3SOIPDwu0 = 0.0; + if (!model->B3SOIPDwuaGiven) + model->B3SOIPDwua = 0.0; + if (!model->B3SOIPDwubGiven) + model->B3SOIPDwub = 0.0; + if (!model->B3SOIPDwucGiven) + model->B3SOIPDwuc = 0.0; + if (!model->B3SOIPDwvsatGiven) + model->B3SOIPDwvsat = 0.0; + if (!model->B3SOIPDwa0Given) + model->B3SOIPDwa0 = 0.0; + if (!model->B3SOIPDwagsGiven) + model->B3SOIPDwags = 0.0; + if (!model->B3SOIPDwb0Given) + model->B3SOIPDwb0 = 0.0; + if (!model->B3SOIPDwb1Given) + model->B3SOIPDwb1 = 0.0; + if (!model->B3SOIPDwketaGiven) + model->B3SOIPDwketa = 0.0; + if (!model->B3SOIPDwketasGiven) + model->B3SOIPDwketas = 0.0; + if (!model->B3SOIPDwa1Given) + model->B3SOIPDwa1 = 0.0; + if (!model->B3SOIPDwa2Given) + model->B3SOIPDwa2 = 0.0; + if (!model->B3SOIPDwrdswGiven) + model->B3SOIPDwrdsw = 0.0; + if (!model->B3SOIPDwprwbGiven) + model->B3SOIPDwprwb = 0.0; + if (!model->B3SOIPDwprwgGiven) + model->B3SOIPDwprwg = 0.0; + if (!model->B3SOIPDwwrGiven) + model->B3SOIPDwwr = 0.0; + if (!model->B3SOIPDwnfactorGiven) + model->B3SOIPDwnfactor = 0.0; + if (!model->B3SOIPDwdwgGiven) + model->B3SOIPDwdwg = 0.0; + if (!model->B3SOIPDwdwbGiven) + model->B3SOIPDwdwb = 0.0; + if (!model->B3SOIPDwvoffGiven) + model->B3SOIPDwvoff = 0.0; + if (!model->B3SOIPDweta0Given) + model->B3SOIPDweta0 = 0.0; + if (!model->B3SOIPDwetabGiven) + model->B3SOIPDwetab = 0.0; + if (!model->B3SOIPDwdsubGiven) + model->B3SOIPDwdsub = 0.0; + if (!model->B3SOIPDwcitGiven) + model->B3SOIPDwcit = 0.0; + if (!model->B3SOIPDwcdscGiven) + model->B3SOIPDwcdsc = 0.0; + if (!model->B3SOIPDwcdscbGiven) + model->B3SOIPDwcdscb = 0.0; + if (!model->B3SOIPDwcdscdGiven) + model->B3SOIPDwcdscd = 0.0; + if (!model->B3SOIPDwpclmGiven) + model->B3SOIPDwpclm = 0.0; + if (!model->B3SOIPDwpdibl1Given) + model->B3SOIPDwpdibl1 = 0.0; + if (!model->B3SOIPDwpdibl2Given) + model->B3SOIPDwpdibl2 = 0.0; + if (!model->B3SOIPDwpdiblbGiven) + model->B3SOIPDwpdiblb = 0.0; + if (!model->B3SOIPDwdroutGiven) + model->B3SOIPDwdrout = 0.0; + if (!model->B3SOIPDwpvagGiven) + model->B3SOIPDwpvag = 0.0; + if (!model->B3SOIPDwdeltaGiven) + model->B3SOIPDwdelta = 0.0; + if (!model->B3SOIPDwalpha0Given) + model->B3SOIPDwalpha0 = 0.0; + if (!model->B3SOIPDwfbjtiiGiven) + model->B3SOIPDwfbjtii = 0.0; + if (!model->B3SOIPDwbeta0Given) + model->B3SOIPDwbeta0 = 0.0; + if (!model->B3SOIPDwbeta1Given) + model->B3SOIPDwbeta1 = 0.0; + if (!model->B3SOIPDwbeta2Given) + model->B3SOIPDwbeta2 = 0.0; + if (!model->B3SOIPDwvdsatii0Given) + model->B3SOIPDwvdsatii0 = 0.0; + if (!model->B3SOIPDwliiGiven) + model->B3SOIPDwlii = 0.0; + if (!model->B3SOIPDwesatiiGiven) + model->B3SOIPDwesatii = 0.0; + if (!model->B3SOIPDwsii0Given) + model->B3SOIPDwsii0 = 0.0; + if (!model->B3SOIPDwsii1Given) + model->B3SOIPDwsii1 = 0.0; + if (!model->B3SOIPDwsii2Given) + model->B3SOIPDwsii2 = 0.0; + if (!model->B3SOIPDwsiidGiven) + model->B3SOIPDwsiid = 0.0; + if (!model->B3SOIPDwagidlGiven) + model->B3SOIPDwagidl = 0.0; + if (!model->B3SOIPDwbgidlGiven) + model->B3SOIPDwbgidl = 0.0; + if (!model->B3SOIPDwngidlGiven) + model->B3SOIPDwngidl = 0.0; + if (!model->B3SOIPDwntunGiven) + model->B3SOIPDwntun = 0.0; + if (!model->B3SOIPDwndiodeGiven) + model->B3SOIPDwndiode = 0.0; + if (!model->B3SOIPDwnrecf0Given) + model->B3SOIPDwnrecf0 = 0.0; + if (!model->B3SOIPDwnrecr0Given) + model->B3SOIPDwnrecr0 = 0.0; + if (!model->B3SOIPDwisbjtGiven) + model->B3SOIPDwisbjt = 0.0; + if (!model->B3SOIPDwisdifGiven) + model->B3SOIPDwisdif = 0.0; + if (!model->B3SOIPDwisrecGiven) + model->B3SOIPDwisrec = 0.0; + if (!model->B3SOIPDwistunGiven) + model->B3SOIPDwistun = 0.0; + if (!model->B3SOIPDwvrec0Given) + model->B3SOIPDwvrec0 = 0.0; + if (!model->B3SOIPDwvtun0Given) + model->B3SOIPDwvtun0 = 0.0; + if (!model->B3SOIPDwnbjtGiven) + model->B3SOIPDwnbjt = 0.0; + if (!model->B3SOIPDwlbjt0Given) + model->B3SOIPDwlbjt0 = 0.0; + if (!model->B3SOIPDwvabjtGiven) + model->B3SOIPDwvabjt = 0.0; + if (!model->B3SOIPDwaelyGiven) + model->B3SOIPDwaely = 0.0; + if (!model->B3SOIPDwahliGiven) + model->B3SOIPDwahli = 0.0; + /* CV Model */ + if (!model->B3SOIPDwvsdfbGiven) + model->B3SOIPDwvsdfb = 0.0; + if (!model->B3SOIPDwvsdthGiven) + model->B3SOIPDwvsdth = 0.0; + if (!model->B3SOIPDwdelvtGiven) + model->B3SOIPDwdelvt = 0.0; + if (!model->B3SOIPDwacdeGiven) + model->B3SOIPDwacde = 0.0; + if (!model->B3SOIPDwmoinGiven) + model->B3SOIPDwmoin = 0.0; + + /* Cross-term dependence */ + if (!model->B3SOIPDpnpeakGiven) + model->B3SOIPDpnpeak = 0.0; + if (!model->B3SOIPDpnsubGiven) + model->B3SOIPDpnsub = 0.0; + if (!model->B3SOIPDpngateGiven) + model->B3SOIPDpngate = 0.0; + if (!model->B3SOIPDpvth0Given) + model->B3SOIPDpvth0 = 0.0; + if (!model->B3SOIPDpk1Given) + model->B3SOIPDpk1 = 0.0; + if (!model->B3SOIPDpk1w1Given) + model->B3SOIPDpk1w1 = 0.0; + if (!model->B3SOIPDpk1w2Given) + model->B3SOIPDpk1w2 = 0.0; + if (!model->B3SOIPDpk2Given) + model->B3SOIPDpk2 = 0.0; + if (!model->B3SOIPDpk3Given) + model->B3SOIPDpk3 = 0.0; + if (!model->B3SOIPDpk3bGiven) + model->B3SOIPDpk3b = 0.0; + if (!model->B3SOIPDpkb1Given) + model->B3SOIPDpkb1 = 0.0; + if (!model->B3SOIPDpw0Given) + model->B3SOIPDpw0 = 0.0; + if (!model->B3SOIPDpnlxGiven) + model->B3SOIPDpnlx = 0.0; + if (!model->B3SOIPDpdvt0Given) + model->B3SOIPDpdvt0 = 0.0; + if (!model->B3SOIPDpdvt1Given) + model->B3SOIPDpdvt1 = 0.0; + if (!model->B3SOIPDpdvt2Given) + model->B3SOIPDpdvt2 = 0.0; + if (!model->B3SOIPDpdvt0wGiven) + model->B3SOIPDpdvt0w = 0.0; + if (!model->B3SOIPDpdvt1wGiven) + model->B3SOIPDpdvt1w = 0.0; + if (!model->B3SOIPDpdvt2wGiven) + model->B3SOIPDpdvt2w = 0.0; + if (!model->B3SOIPDpu0Given) + model->B3SOIPDpu0 = 0.0; + if (!model->B3SOIPDpuaGiven) + model->B3SOIPDpua = 0.0; + if (!model->B3SOIPDpubGiven) + model->B3SOIPDpub = 0.0; + if (!model->B3SOIPDpucGiven) + model->B3SOIPDpuc = 0.0; + if (!model->B3SOIPDpvsatGiven) + model->B3SOIPDpvsat = 0.0; + if (!model->B3SOIPDpa0Given) + model->B3SOIPDpa0 = 0.0; + if (!model->B3SOIPDpagsGiven) + model->B3SOIPDpags = 0.0; + if (!model->B3SOIPDpb0Given) + model->B3SOIPDpb0 = 0.0; + if (!model->B3SOIPDpb1Given) + model->B3SOIPDpb1 = 0.0; + if (!model->B3SOIPDpketaGiven) + model->B3SOIPDpketa = 0.0; + if (!model->B3SOIPDpketasGiven) + model->B3SOIPDpketas = 0.0; + if (!model->B3SOIPDpa1Given) + model->B3SOIPDpa1 = 0.0; + if (!model->B3SOIPDpa2Given) + model->B3SOIPDpa2 = 0.0; + if (!model->B3SOIPDprdswGiven) + model->B3SOIPDprdsw = 0.0; + if (!model->B3SOIPDpprwbGiven) + model->B3SOIPDpprwb = 0.0; + if (!model->B3SOIPDpprwgGiven) + model->B3SOIPDpprwg = 0.0; + if (!model->B3SOIPDpwrGiven) + model->B3SOIPDpwr = 0.0; + if (!model->B3SOIPDpnfactorGiven) + model->B3SOIPDpnfactor = 0.0; + if (!model->B3SOIPDpdwgGiven) + model->B3SOIPDpdwg = 0.0; + if (!model->B3SOIPDpdwbGiven) + model->B3SOIPDpdwb = 0.0; + if (!model->B3SOIPDpvoffGiven) + model->B3SOIPDpvoff = 0.0; + if (!model->B3SOIPDpeta0Given) + model->B3SOIPDpeta0 = 0.0; + if (!model->B3SOIPDpetabGiven) + model->B3SOIPDpetab = 0.0; + if (!model->B3SOIPDpdsubGiven) + model->B3SOIPDpdsub = 0.0; + if (!model->B3SOIPDpcitGiven) + model->B3SOIPDpcit = 0.0; + if (!model->B3SOIPDpcdscGiven) + model->B3SOIPDpcdsc = 0.0; + if (!model->B3SOIPDpcdscbGiven) + model->B3SOIPDpcdscb = 0.0; + if (!model->B3SOIPDpcdscdGiven) + model->B3SOIPDpcdscd = 0.0; + if (!model->B3SOIPDppclmGiven) + model->B3SOIPDppclm = 0.0; + if (!model->B3SOIPDppdibl1Given) + model->B3SOIPDppdibl1 = 0.0; + if (!model->B3SOIPDppdibl2Given) + model->B3SOIPDppdibl2 = 0.0; + if (!model->B3SOIPDppdiblbGiven) + model->B3SOIPDppdiblb = 0.0; + if (!model->B3SOIPDpdroutGiven) + model->B3SOIPDpdrout = 0.0; + if (!model->B3SOIPDppvagGiven) + model->B3SOIPDppvag = 0.0; + if (!model->B3SOIPDpdeltaGiven) + model->B3SOIPDpdelta = 0.0; + if (!model->B3SOIPDpalpha0Given) + model->B3SOIPDpalpha0 = 0.0; + if (!model->B3SOIPDpfbjtiiGiven) + model->B3SOIPDpfbjtii = 0.0; + if (!model->B3SOIPDpbeta0Given) + model->B3SOIPDpbeta0 = 0.0; + if (!model->B3SOIPDpbeta1Given) + model->B3SOIPDpbeta1 = 0.0; + if (!model->B3SOIPDpbeta2Given) + model->B3SOIPDpbeta2 = 0.0; + if (!model->B3SOIPDpvdsatii0Given) + model->B3SOIPDpvdsatii0 = 0.0; + if (!model->B3SOIPDpliiGiven) + model->B3SOIPDplii = 0.0; + if (!model->B3SOIPDpesatiiGiven) + model->B3SOIPDpesatii = 0.0; + if (!model->B3SOIPDpsii0Given) + model->B3SOIPDpsii0 = 0.0; + if (!model->B3SOIPDpsii1Given) + model->B3SOIPDpsii1 = 0.0; + if (!model->B3SOIPDpsii2Given) + model->B3SOIPDpsii2 = 0.0; + if (!model->B3SOIPDpsiidGiven) + model->B3SOIPDpsiid = 0.0; + if (!model->B3SOIPDpagidlGiven) + model->B3SOIPDpagidl = 0.0; + if (!model->B3SOIPDpbgidlGiven) + model->B3SOIPDpbgidl = 0.0; + if (!model->B3SOIPDpngidlGiven) + model->B3SOIPDpngidl = 0.0; + if (!model->B3SOIPDpntunGiven) + model->B3SOIPDpntun = 0.0; + if (!model->B3SOIPDpndiodeGiven) + model->B3SOIPDpndiode = 0.0; + if (!model->B3SOIPDpnrecf0Given) + model->B3SOIPDpnrecf0 = 0.0; + if (!model->B3SOIPDpnrecr0Given) + model->B3SOIPDpnrecr0 = 0.0; + if (!model->B3SOIPDpisbjtGiven) + model->B3SOIPDpisbjt = 0.0; + if (!model->B3SOIPDpisdifGiven) + model->B3SOIPDpisdif = 0.0; + if (!model->B3SOIPDpisrecGiven) + model->B3SOIPDpisrec = 0.0; + if (!model->B3SOIPDpistunGiven) + model->B3SOIPDpistun = 0.0; + if (!model->B3SOIPDpvrec0Given) + model->B3SOIPDpvrec0 = 0.0; + if (!model->B3SOIPDpvtun0Given) + model->B3SOIPDpvtun0 = 0.0; + if (!model->B3SOIPDpnbjtGiven) + model->B3SOIPDpnbjt = 0.0; + if (!model->B3SOIPDplbjt0Given) + model->B3SOIPDplbjt0 = 0.0; + if (!model->B3SOIPDpvabjtGiven) + model->B3SOIPDpvabjt = 0.0; + if (!model->B3SOIPDpaelyGiven) + model->B3SOIPDpaely = 0.0; + if (!model->B3SOIPDpahliGiven) + model->B3SOIPDpahli = 0.0; + /* CV Model */ + if (!model->B3SOIPDpvsdfbGiven) + model->B3SOIPDpvsdfb = 0.0; + if (!model->B3SOIPDpvsdthGiven) + model->B3SOIPDpvsdth = 0.0; + if (!model->B3SOIPDpdelvtGiven) + model->B3SOIPDpdelvt = 0.0; + if (!model->B3SOIPDpacdeGiven) + model->B3SOIPDpacde = 0.0; + if (!model->B3SOIPDpmoinGiven) + model->B3SOIPDpmoin = 0.0; +/* Added for binning - END */ + + if (!model->B3SOIPDcfGiven) + model->B3SOIPDcf = 2.0 * EPSOX / PI + * log (1.0 + 0.4e-6 / model->B3SOIPDtox); + if (!model->B3SOIPDcgdoGiven) + { + if (model->B3SOIPDdlcGiven && (model->B3SOIPDdlc > 0.0)) + { + model->B3SOIPDcgdo = model->B3SOIPDdlc * model->B3SOIPDcox + - model->B3SOIPDcgdl; + } + else + model->B3SOIPDcgdo = 0.6 * model->B3SOIPDxj * model->B3SOIPDcox; + } + if (!model->B3SOIPDcgsoGiven) + { + if (model->B3SOIPDdlcGiven && (model->B3SOIPDdlc > 0.0)) + { + model->B3SOIPDcgso = model->B3SOIPDdlc * model->B3SOIPDcox + - model->B3SOIPDcgsl; + } + else + model->B3SOIPDcgso = 0.6 * model->B3SOIPDxj * model->B3SOIPDcox; + } + + if (!model->B3SOIPDcgeoGiven) + { + model->B3SOIPDcgeo = 0.0; + } + if (!model->B3SOIPDxpartGiven) + model->B3SOIPDxpart = 0.0; + if (!model->B3SOIPDsheetResistanceGiven) + model->B3SOIPDsheetResistance = 0.0; + if (!model->B3SOIPDcsdeswGiven) + model->B3SOIPDcsdesw = 0.0; + if (!model->B3SOIPDunitLengthGateSidewallJctCapGiven) + model->B3SOIPDunitLengthGateSidewallJctCap = 1e-10; + if (!model->B3SOIPDGatesidewallJctPotentialGiven) + model->B3SOIPDGatesidewallJctPotential = 0.7; + if (!model->B3SOIPDbodyJctGateSideGradingCoeffGiven) + model->B3SOIPDbodyJctGateSideGradingCoeff = 0.5; + if (!model->B3SOIPDoxideTrapDensityAGiven) + { + if (model->B3SOIPDtype == NMOS) + model->B3SOIPDoxideTrapDensityA = 1e20; + else + model->B3SOIPDoxideTrapDensityA = 9.9e18; + } + if (!model->B3SOIPDoxideTrapDensityBGiven) + { + if (model->B3SOIPDtype == NMOS) + model->B3SOIPDoxideTrapDensityB = 5e4; + else + model->B3SOIPDoxideTrapDensityB = 2.4e3; + } + if (!model->B3SOIPDoxideTrapDensityCGiven) + { + if (model->B3SOIPDtype == NMOS) + model->B3SOIPDoxideTrapDensityC = -1.4e-12; + else + model->B3SOIPDoxideTrapDensityC = 1.4e-12; + + } + if (!model->B3SOIPDemGiven) + model->B3SOIPDem = 4.1e7; /* V/m */ + if (!model->B3SOIPDefGiven) + model->B3SOIPDef = 1.0; + if (!model->B3SOIPDafGiven) + model->B3SOIPDaf = 1.0; + if (!model->B3SOIPDkfGiven) + model->B3SOIPDkf = 0.0; + if (!model->B3SOIPDnoifGiven) + model->B3SOIPDnoif = 1.0; + + /* loop through all the instances of the model */ + for (here = model->B3SOIPDinstances; here != NULL; + here = here->B3SOIPDnextInstance) + { /* allocate a chunk of the state vector */ + here->B3SOIPDstates = *states; + *states += B3SOIPDnumStates; + /* perform the parameter defaulting */ + if (!here->B3SOIPDdrainAreaGiven) + here->B3SOIPDdrainArea = 0.0; + if (!here->B3SOIPDdrainPerimeterGiven) + here->B3SOIPDdrainPerimeter = 0.0; + if (!here->B3SOIPDdrainSquaresGiven) + here->B3SOIPDdrainSquares = 1.0; + if (!here->B3SOIPDicVBSGiven) + here->B3SOIPDicVBS = 0; + if (!here->B3SOIPDicVDSGiven) + here->B3SOIPDicVDS = 0; + if (!here->B3SOIPDicVGSGiven) + here->B3SOIPDicVGS = 0; + if (!here->B3SOIPDicVESGiven) + here->B3SOIPDicVES = 0; + if (!here->B3SOIPDicVPSGiven) + here->B3SOIPDicVPS = 0; + if (!here->B3SOIPDbjtoffGiven) + here->B3SOIPDbjtoff = 0; + if (!here->B3SOIPDdebugModGiven) + here->B3SOIPDdebugMod = 0; + if (!here->B3SOIPDrth0Given) + here->B3SOIPDrth0 = model->B3SOIPDrth0; + if (!here->B3SOIPDcth0Given) + here->B3SOIPDcth0 = model->B3SOIPDcth0; + if (!here->B3SOIPDbodySquaresGiven) + here->B3SOIPDbodySquares = 1.0; + if (!here->B3SOIPDlGiven) + here->B3SOIPDl = 5e-6; + if (!here->B3SOIPDsourceAreaGiven) + here->B3SOIPDsourceArea = 0; + if (!here->B3SOIPDsourcePerimeterGiven) + here->B3SOIPDsourcePerimeter = 0; + if (!here->B3SOIPDsourceSquaresGiven) + here->B3SOIPDsourceSquares = 1; + if (!here->B3SOIPDwGiven) + here->B3SOIPDw = 5e-6; + + +/* v2.0 release */ + if (!here->B3SOIPDnbcGiven) + here->B3SOIPDnbc = 0; + if (!here->B3SOIPDnsegGiven) + here->B3SOIPDnseg = 1; + if (!here->B3SOIPDpdbcpGiven) + here->B3SOIPDpdbcp = 0; + if (!here->B3SOIPDpsbcpGiven) + here->B3SOIPDpsbcp = 0; + if (!here->B3SOIPDagbcpGiven) + here->B3SOIPDagbcp = 0; + if (!here->B3SOIPDaebcpGiven) + here->B3SOIPDaebcp = 0; + + if (!here->B3SOIPDoffGiven) + here->B3SOIPDoff = 0; + + /* process drain series resistance */ + if ((model->B3SOIPDsheetResistance > 0.0) && + (here->B3SOIPDdrainSquares > 0.0) && + (here->B3SOIPDdNodePrime == 0)) + { + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "drain"); + if (error) + return (error); + here->B3SOIPDdNodePrime = tmp->number; + } + else + { + here->B3SOIPDdNodePrime = here->B3SOIPDdNode; + } + + /* process source series resistance */ + if ((model->B3SOIPDsheetResistance > 0.0) && + (here->B3SOIPDsourceSquares > 0.0) && + (here->B3SOIPDsNodePrime == 0)) + { + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "source"); + if (error) + return (error); + here->B3SOIPDsNodePrime = tmp->number; + } + else + { + here->B3SOIPDsNodePrime = here->B3SOIPDsNode; + } + + /* process effective silicon film thickness */ + model->B3SOIPDcbox = 3.453133e-11 / model->B3SOIPDtbox; + model->B3SOIPDcsi = 1.03594e-10 / model->B3SOIPDtsi; + Cboxt = + model->B3SOIPDcbox * model->B3SOIPDcsi / (model->B3SOIPDcbox + + model->B3SOIPDcsi); + model->B3SOIPDqsi = + Charge_q * model->B3SOIPDnpeak * 1e6 * model->B3SOIPDtsi; + + + here->B3SOIPDfloat = 0; + if (here->B3SOIPDpNode == -1) + { /* floating body case -- 4-node */ + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Body"); + if (error) + return (error); + here->B3SOIPDbNode = tmp->number; + here->B3SOIPDpNode = 0; + here->B3SOIPDfloat = 1; + here->B3SOIPDbodyMod = 0; + } + else /* the 5th Node has been assigned */ + { + if (!here->B3SOIPDtnodeoutGiven) + { /* if t-node not assigned */ + if (here->B3SOIPDbNode == -1) + { /* 5-node body tie, bNode has not been assigned */ + if ((model->B3SOIPDrbody == 0.0) + && (model->B3SOIPDrbsh == 0.0)) + { /* ideal body tie, pNode is not used */ + here->B3SOIPDbNode = here->B3SOIPDpNode; + here->B3SOIPDbodyMod = 2; + } + else + { /* nonideal body tie */ + error = + CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Body"); + if (error) + return (error); + here->B3SOIPDbNode = tmp->number; + here->B3SOIPDbodyMod = 1; + } + } + else + { /* 6-node body tie, bNode has been assigned */ + if ((model->B3SOIPDrbody == 0.0) + && (model->B3SOIPDrbsh == 0.0)) + { + printf + ("\n Warning: model parameter rbody=0!\n"); + model->B3SOIPDrbody = 1e0; + here->B3SOIPDbodyMod = 1; + } + else + { /* nonideal body tie */ + here->B3SOIPDbodyMod = 1; + } + } + } + else + { /* t-node assigned */ + if (here->B3SOIPDbNode == -1) + { /* 4 nodes & t-node, floating body */ + error = + CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Body"); + if (error) + return (error); + here->B3SOIPDbNode = tmp->number; + here->B3SOIPDtempNode = here->B3SOIPDpNode; + here->B3SOIPDpNode = 0; + here->B3SOIPDfloat = 1; + here->B3SOIPDbodyMod = 0; + } + else + { /* 5 or 6 nodes & t-node, body-contact device */ + if (here->B3SOIPDtempNode == -1) + { /* 5 nodes & tnode */ + if ((model->B3SOIPDrbody == 0.0) + && (model->B3SOIPDrbsh == 0.0)) + { /* ideal body tie, pNode is not used */ + here->B3SOIPDtempNode = here->B3SOIPDbNode; + here->B3SOIPDbNode = here->B3SOIPDpNode; + here->B3SOIPDbodyMod = 2; + } + else + { /* nonideal body tie */ + here->B3SOIPDtempNode = here->B3SOIPDbNode; + error = + CKTmkVolt (ckt, &tmp, here->B3SOIPDname, + "Body"); + if (error) + return (error); + here->B3SOIPDbNode = tmp->number; + here->B3SOIPDbodyMod = 1; + } + } + else + { /* 6 nodes & t-node */ + if ((model->B3SOIPDrbody == 0.0) + && (model->B3SOIPDrbsh == 0.0)) + { + printf + ("\n Warning: model parameter rbody=0!\n"); + model->B3SOIPDrbody = 1e0; + here->B3SOIPDbodyMod = 1; + } + else + { /* nonideal body tie */ + here->B3SOIPDbodyMod = 1; + } + } + } + } + } + + + if ((model->B3SOIPDshMod == 1) && (here->B3SOIPDrth0 != 0)) + { + if (here->B3SOIPDtempNode == -1) + { + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Temp"); + if (error) + return (error); + here->B3SOIPDtempNode = tmp->number; + } + + } + else + { + here->B3SOIPDtempNode = 0; + } + +/* here for debugging purpose only */ + if (here->B3SOIPDdebugMod != 0) + { + /* The real Vbs value */ + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Vbs"); + if (error) + return (error); + here->B3SOIPDvbsNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Ids"); + if (error) + return (error); + here->B3SOIPDidsNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Ic"); + if (error) + return (error); + here->B3SOIPDicNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Ibs"); + if (error) + return (error); + here->B3SOIPDibsNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Ibd"); + if (error) + return (error); + here->B3SOIPDibdNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Iii"); + if (error) + return (error); + here->B3SOIPDiiiNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Ig"); + if (error) + return (error); + here->B3SOIPDigNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Gigg"); + if (error) + return (error); + here->B3SOIPDgiggNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Gigd"); + if (error) + return (error); + here->B3SOIPDgigdNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Gigb"); + if (error) + return (error); + here->B3SOIPDgigbNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Igidl"); + if (error) + return (error); + here->B3SOIPDigidlNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Itun"); + if (error) + return (error); + here->B3SOIPDitunNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Ibp"); + if (error) + return (error); + here->B3SOIPDibpNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Cbb"); + if (error) + return (error); + here->B3SOIPDcbbNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Cbd"); + if (error) + return (error); + here->B3SOIPDcbdNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Cbg"); + if (error) + return (error); + here->B3SOIPDcbgNode = tmp->number; + + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Qbf"); + if (error) + return (error); + here->B3SOIPDqbfNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Qjs"); + if (error) + return (error); + here->B3SOIPDqjsNode = tmp->number; + + error = CKTmkVolt (ckt, &tmp, here->B3SOIPDname, "Qjd"); + if (error) + return (error); + here->B3SOIPDqjdNode = tmp->number; + + } + + /* set Sparse Matrix Pointers */ + +/* macro to make elements with built in test for out of memory */ +#define TSTALLOC(ptr,first,second) \ +if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ + return(E_NOMEM);\ +} + + + if ((model->B3SOIPDshMod == 1) && (here->B3SOIPDrth0 != 0.0)) + { + TSTALLOC (B3SOIPDTemptempPtr, B3SOIPDtempNode, B3SOIPDtempNode) + TSTALLOC (B3SOIPDTempdpPtr, B3SOIPDtempNode, + B3SOIPDdNodePrime) TSTALLOC (B3SOIPDTempspPtr, + B3SOIPDtempNode, + B3SOIPDsNodePrime) + TSTALLOC (B3SOIPDTempgPtr, B3SOIPDtempNode, + B3SOIPDgNode) TSTALLOC (B3SOIPDTempbPtr, + B3SOIPDtempNode, + B3SOIPDbNode) + TSTALLOC (B3SOIPDGtempPtr, B3SOIPDgNode, + B3SOIPDtempNode) TSTALLOC (B3SOIPDDPtempPtr, + B3SOIPDdNodePrime, + B3SOIPDtempNode) + TSTALLOC (B3SOIPDSPtempPtr, B3SOIPDsNodePrime, + B3SOIPDtempNode) TSTALLOC (B3SOIPDEtempPtr, + B3SOIPDeNode, + B3SOIPDtempNode) + TSTALLOC (B3SOIPDBtempPtr, B3SOIPDbNode, + B3SOIPDtempNode) if (here->B3SOIPDbodyMod == 1) + { + TSTALLOC (B3SOIPDPtempPtr, B3SOIPDpNode, B3SOIPDtempNode)} + } + if (here->B3SOIPDbodyMod == 2) + { + /* Don't create any Jacobian entry for pNode */ + } + else if (here->B3SOIPDbodyMod == 1) + { + TSTALLOC (B3SOIPDBpPtr, B3SOIPDbNode, B3SOIPDpNode) + TSTALLOC (B3SOIPDPbPtr, B3SOIPDpNode, B3SOIPDbNode) + TSTALLOC (B3SOIPDPpPtr, B3SOIPDpNode, B3SOIPDpNode)} + + TSTALLOC (B3SOIPDEbPtr, B3SOIPDeNode, B3SOIPDbNode) + TSTALLOC (B3SOIPDGbPtr, B3SOIPDgNode, B3SOIPDbNode) + TSTALLOC (B3SOIPDDPbPtr, B3SOIPDdNodePrime, B3SOIPDbNode) + TSTALLOC (B3SOIPDSPbPtr, B3SOIPDsNodePrime, B3SOIPDbNode) + TSTALLOC (B3SOIPDBePtr, B3SOIPDbNode, B3SOIPDeNode) + TSTALLOC (B3SOIPDBgPtr, B3SOIPDbNode, B3SOIPDgNode) + TSTALLOC (B3SOIPDBdpPtr, B3SOIPDbNode, B3SOIPDdNodePrime) + TSTALLOC (B3SOIPDBspPtr, B3SOIPDbNode, B3SOIPDsNodePrime) + TSTALLOC (B3SOIPDBbPtr, B3SOIPDbNode, B3SOIPDbNode) + TSTALLOC (B3SOIPDEgPtr, B3SOIPDeNode, B3SOIPDgNode) + TSTALLOC (B3SOIPDEdpPtr, B3SOIPDeNode, B3SOIPDdNodePrime) + TSTALLOC (B3SOIPDEspPtr, B3SOIPDeNode, B3SOIPDsNodePrime) + TSTALLOC (B3SOIPDGePtr, B3SOIPDgNode, B3SOIPDeNode) + TSTALLOC (B3SOIPDDPePtr, B3SOIPDdNodePrime, B3SOIPDeNode) + TSTALLOC (B3SOIPDSPePtr, B3SOIPDsNodePrime, B3SOIPDeNode) + TSTALLOC (B3SOIPDEbPtr, B3SOIPDeNode, B3SOIPDbNode) + TSTALLOC (B3SOIPDEePtr, B3SOIPDeNode, B3SOIPDeNode) + TSTALLOC (B3SOIPDGgPtr, B3SOIPDgNode, B3SOIPDgNode) + TSTALLOC (B3SOIPDGdpPtr, B3SOIPDgNode, B3SOIPDdNodePrime) + TSTALLOC (B3SOIPDGspPtr, B3SOIPDgNode, B3SOIPDsNodePrime) + TSTALLOC (B3SOIPDDPgPtr, B3SOIPDdNodePrime, B3SOIPDgNode) + TSTALLOC (B3SOIPDDPdpPtr, B3SOIPDdNodePrime, B3SOIPDdNodePrime) + TSTALLOC (B3SOIPDDPspPtr, B3SOIPDdNodePrime, B3SOIPDsNodePrime) + TSTALLOC (B3SOIPDDPdPtr, B3SOIPDdNodePrime, B3SOIPDdNode) + TSTALLOC (B3SOIPDSPgPtr, B3SOIPDsNodePrime, B3SOIPDgNode) + TSTALLOC (B3SOIPDSPdpPtr, B3SOIPDsNodePrime, B3SOIPDdNodePrime) + TSTALLOC (B3SOIPDSPspPtr, B3SOIPDsNodePrime, B3SOIPDsNodePrime) + TSTALLOC (B3SOIPDSPsPtr, B3SOIPDsNodePrime, B3SOIPDsNode) + TSTALLOC (B3SOIPDDdPtr, B3SOIPDdNode, B3SOIPDdNode) + TSTALLOC (B3SOIPDDdpPtr, B3SOIPDdNode, B3SOIPDdNodePrime) + TSTALLOC (B3SOIPDSsPtr, B3SOIPDsNode, B3SOIPDsNode) + TSTALLOC (B3SOIPDSspPtr, B3SOIPDsNode, B3SOIPDsNodePrime) +/* here for debugging purpose only */ + if (here->B3SOIPDdebugMod != 0) + { + TSTALLOC (B3SOIPDVbsPtr, B3SOIPDvbsNode, B3SOIPDvbsNode) + TSTALLOC (B3SOIPDIdsPtr, B3SOIPDidsNode, B3SOIPDidsNode) + TSTALLOC (B3SOIPDIcPtr, B3SOIPDicNode, B3SOIPDicNode) + TSTALLOC (B3SOIPDIbsPtr, B3SOIPDibsNode, B3SOIPDibsNode) + TSTALLOC (B3SOIPDIbdPtr, B3SOIPDibdNode, B3SOIPDibdNode) + TSTALLOC (B3SOIPDIiiPtr, B3SOIPDiiiNode, B3SOIPDiiiNode) + TSTALLOC (B3SOIPDIgPtr, B3SOIPDigNode, B3SOIPDigNode) + TSTALLOC (B3SOIPDGiggPtr, B3SOIPDgiggNode, B3SOIPDgiggNode) + TSTALLOC (B3SOIPDGigdPtr, B3SOIPDgigdNode, B3SOIPDgigdNode) + TSTALLOC (B3SOIPDGigbPtr, B3SOIPDgigbNode, B3SOIPDgigbNode) + TSTALLOC (B3SOIPDIgidlPtr, B3SOIPDigidlNode, B3SOIPDigidlNode) + TSTALLOC (B3SOIPDItunPtr, B3SOIPDitunNode, B3SOIPDitunNode) + TSTALLOC (B3SOIPDIbpPtr, B3SOIPDibpNode, B3SOIPDibpNode) + TSTALLOC (B3SOIPDCbbPtr, B3SOIPDcbbNode, B3SOIPDcbbNode) + TSTALLOC (B3SOIPDCbdPtr, B3SOIPDcbdNode, B3SOIPDcbdNode) + TSTALLOC (B3SOIPDCbgPtr, B3SOIPDcbgNode, B3SOIPDcbgNode) + TSTALLOC (B3SOIPDQbfPtr, B3SOIPDqbfNode, B3SOIPDqbfNode) + TSTALLOC (B3SOIPDQjsPtr, B3SOIPDqjsNode, B3SOIPDqjsNode) + TSTALLOC (B3SOIPDQjdPtr, B3SOIPDqjdNode, B3SOIPDqjdNode)} + + } + } + return (OK); +} + +int +B3SOIPDunsetup (inModel, ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ +#ifndef HAS_BATCHSIM + B3SOIPDmodel *model; + B3SOIPDinstance *here; + + for (model = (B3SOIPDmodel *) inModel; model != NULL; + model = model->B3SOIPDnextModel) + { + for (here = model->B3SOIPDinstances; here != NULL; + here = here->B3SOIPDnextInstance) + { + if (here->B3SOIPDdNodePrime + && here->B3SOIPDdNodePrime != here->B3SOIPDdNode) + { + CKTdltNNum (ckt, here->B3SOIPDdNodePrime); + here->B3SOIPDdNodePrime = 0; + } + if (here->B3SOIPDsNodePrime + && here->B3SOIPDsNodePrime != here->B3SOIPDsNode) + { + CKTdltNNum (ckt, here->B3SOIPDsNodePrime); + here->B3SOIPDsNodePrime = 0; + } + } + } +#endif + return OK; +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdtemp.c b/src/spicelib/devices/bsim3soi_pd/b3soipdtemp.c new file mode 100644 index 000000000..3ee2bdab9 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdtemp.c @@ -0,0 +1,1037 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipdtemp.c 98/5/01 +Modified by Pin Su 99/2/15 +Modified by Pin Su 99/4/30 +Modified by Pin Su, Wei Jin 99/9/27 +Modified by Pin Su 00/3/1 +**********/ + +/* Lmin, Lmax, Wmin, Wmax */ + +#include "ngspice.h" +#include +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "b3soipddef.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + +#define Kb 1.3806226e-23 +#define KboQ 8.617087e-5 /* Kb / q where q = 1.60219e-19 */ +#define EPSOX 3.453133e-11 +#define EPSSI 1.03594e-10 +#define PI 3.141592654 +#define Charge_q 1.60219e-19 +#define Eg300 1.115 /* energy gap at 300K */ + +#define MAX_EXPL 2.688117142e+43 +#define MIN_EXPL 3.720075976e-44 +#define EXPL_THRESHOLD 100.0 +#define DEXP(A,B) { \ + if (A > EXPL_THRESHOLD) { \ + B = MAX_EXPL*(1.0+(A)-EXPL_THRESHOLD); \ + } else if (A < -EXPL_THRESHOLD) { \ + B = MIN_EXPL; \ + } else { \ + B = exp(A); \ + } \ + } + +/* ARGSUSED */ +int +B3SOIPDtemp (inModel, ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + B3SOIPDmodel *model = (B3SOIPDmodel *) inModel; + B3SOIPDinstance *here; + struct b3soipdSizeDependParam *pSizeDependParamKnot, *pLastKnot, *pParam; + double tmp, tmp1, tmp2, Eg, Eg0, ni, T0, T1, T2, T3, T4, T5, T6, Ldrn, Wdrn; + double Temp, TempRatio, Inv_L, Inv_W, Inv_LW, Dw, Dl, Vtm0, Tnom; + double SDphi, SDgamma; + int Size_Not_Found; + +/* v2.0 release */ + double tmp3, T7, T8, T9; + + + /* loop through all the B3SOIPD device models */ + for (; model != NULL; model = model->B3SOIPDnextModel) + { + Temp = ckt->CKTtemp; + if (model->B3SOIPDGatesidewallJctPotential < 0.1) + model->B3SOIPDGatesidewallJctPotential = 0.1; + model->pSizeDependParamKnot = NULL; + pLastKnot = NULL; + + Tnom = model->B3SOIPDtnom; + TempRatio = Temp / Tnom; + + model->B3SOIPDvcrit = + CONSTvt0 * log (CONSTvt0 / (CONSTroot2 * 1.0e-14)); + model->B3SOIPDfactor1 = sqrt (EPSSI / EPSOX * model->B3SOIPDtox); + + Vtm0 = KboQ * Tnom; + Eg0 = 1.16 - 7.02e-4 * Tnom * Tnom / (Tnom + 1108.0); + model->B3SOIPDeg0 = Eg0; + model->B3SOIPDvtm = KboQ * Temp; + + Eg = 1.16 - 7.02e-4 * Temp * Temp / (Temp + 1108.0); + /* ni is in cm^-3 */ + ni = 1.45e10 * (Temp / 300.15) * sqrt (Temp / 300.15) + * exp (21.5565981 - Eg / (2.0 * model->B3SOIPDvtm)); + + + /* loop through all the instances of the model */ + /* MCJ: Length and Width not initialized */ + for (here = model->B3SOIPDinstances; here != NULL; + here = here->B3SOIPDnextInstance) + { + here->B3SOIPDrbodyext = here->B3SOIPDbodySquares * + model->B3SOIPDrbsh; + pSizeDependParamKnot = model->pSizeDependParamKnot; + Size_Not_Found = 1; + while ((pSizeDependParamKnot != NULL) && Size_Not_Found) + { + if ((here->B3SOIPDl == pSizeDependParamKnot->Length) + && (here->B3SOIPDw == pSizeDependParamKnot->Width) + && (here->B3SOIPDrth0 == pSizeDependParamKnot->Rth0) + && (here->B3SOIPDcth0 == pSizeDependParamKnot->Cth0)) + { + Size_Not_Found = 0; + here->pParam = pSizeDependParamKnot; + } + else + { + pLastKnot = pSizeDependParamKnot; + pSizeDependParamKnot = pSizeDependParamKnot->pNext; + } + } + + if (Size_Not_Found) + { + pParam = + (struct b3soipdSizeDependParam *) + malloc (sizeof (struct b3soipdSizeDependParam)); + if (pLastKnot == NULL) + model->pSizeDependParamKnot = pParam; + else + pLastKnot->pNext = pParam; + pParam->pNext = NULL; + here->pParam = pParam; + + Ldrn = here->B3SOIPDl; + Wdrn = here->B3SOIPDw; + pParam->Length = Ldrn; + pParam->Width = Wdrn; + pParam->Rth0 = here->B3SOIPDrth0; + pParam->Cth0 = here->B3SOIPDcth0; + + T0 = pow (Ldrn, model->B3SOIPDLln); + T1 = pow (Wdrn, model->B3SOIPDLwn); + tmp1 = model->B3SOIPDLl / T0 + model->B3SOIPDLw / T1 + + model->B3SOIPDLwl / (T0 * T1); + pParam->B3SOIPDdl = model->B3SOIPDLint + tmp1; + pParam->B3SOIPDdlc = model->B3SOIPDdlc + tmp1; + + T2 = pow (Ldrn, model->B3SOIPDWln); + T3 = pow (Wdrn, model->B3SOIPDWwn); + tmp2 = model->B3SOIPDWl / T2 + model->B3SOIPDWw / T3 + + model->B3SOIPDWwl / (T2 * T3); + pParam->B3SOIPDdw = model->B3SOIPDWint + tmp2; + pParam->B3SOIPDdwc = model->B3SOIPDdwc + tmp2; + + pParam->B3SOIPDleff = here->B3SOIPDl - 2.0 * pParam->B3SOIPDdl; + if (pParam->B3SOIPDleff <= 0.0) + { + IFuid namarray[2]; + namarray[0] = model->B3SOIPDmodName; + namarray[1] = here->B3SOIPDname; + (*(SPfrontEnd->IFerror)) (ERR_FATAL, + "B3SOIPD: mosfet %s, model %s: Effective channel length <= 0", + namarray); + return (E_BADPARM); + } + + pParam->B3SOIPDweff = + here->B3SOIPDw - here->B3SOIPDnbc * model->B3SOIPDdwbc - + (2.0 - here->B3SOIPDnbc) * pParam->B3SOIPDdw; + if (pParam->B3SOIPDweff <= 0.0) + { + IFuid namarray[2]; + namarray[0] = model->B3SOIPDmodName; + namarray[1] = here->B3SOIPDname; + (*(SPfrontEnd->IFerror)) (ERR_FATAL, + "B3SOIPD: mosfet %s, model %s: Effective channel width <= 0", + namarray); + return (E_BADPARM); + } + + pParam->B3SOIPDwdiod = + pParam->B3SOIPDweff / here->B3SOIPDnseg + here->B3SOIPDpdbcp; + pParam->B3SOIPDwdios = + pParam->B3SOIPDweff / here->B3SOIPDnseg + here->B3SOIPDpsbcp; + + pParam->B3SOIPDleffCV = + here->B3SOIPDl - 2.0 * pParam->B3SOIPDdlc; + if (pParam->B3SOIPDleffCV <= 0.0) + { + IFuid namarray[2]; + namarray[0] = model->B3SOIPDmodName; + namarray[1] = here->B3SOIPDname; + (*(SPfrontEnd->IFerror)) (ERR_FATAL, + "B3SOIPD: mosfet %s, model %s: Effective channel length for C-V <= 0", + namarray); + return (E_BADPARM); + } + + pParam->B3SOIPDweffCV = + here->B3SOIPDw - here->B3SOIPDnbc * model->B3SOIPDdwbc - + (2.0 - here->B3SOIPDnbc) * pParam->B3SOIPDdwc; + if (pParam->B3SOIPDweffCV <= 0.0) + { + IFuid namarray[2]; + namarray[0] = model->B3SOIPDmodName; + namarray[1] = here->B3SOIPDname; + (*(SPfrontEnd->IFerror)) (ERR_FATAL, + "B3SOIPD: mosfet %s, model %s: Effective channel width for C-V <= 0", + namarray); + return (E_BADPARM); + } + + pParam->B3SOIPDwdiodCV = + pParam->B3SOIPDweffCV / here->B3SOIPDnseg + + here->B3SOIPDpdbcp; + pParam->B3SOIPDwdiosCV = + pParam->B3SOIPDweffCV / here->B3SOIPDnseg + + here->B3SOIPDpsbcp; + + pParam->B3SOIPDleffCVb = + here->B3SOIPDl - 2.0 * pParam->B3SOIPDdlc - + model->B3SOIPDdlcb; + if (pParam->B3SOIPDleffCVb <= 0.0) + { + IFuid namarray[2]; + namarray[0] = model->B3SOIPDmodName; + namarray[1] = here->B3SOIPDname; + (*(SPfrontEnd->IFerror)) (ERR_FATAL, + "B3SOIPD: mosfet %s, model %s: Effective channel length for C-V (body) <= 0", + namarray); + return (E_BADPARM); + } + + pParam->B3SOIPDleffCVbg = + pParam->B3SOIPDleffCVb + 2 * model->B3SOIPDdlbg; + if (pParam->B3SOIPDleffCVbg <= 0.0) + { + IFuid namarray[2]; + namarray[0] = model->B3SOIPDmodName; + namarray[1] = here->B3SOIPDname; + (*(SPfrontEnd->IFerror)) (ERR_FATAL, + "B3SOIPD: mosfet %s, model %s: Effective channel length for C-V (backgate) <= 0", + namarray); + return (E_BADPARM); + } + + /* Not binned - START */ + pParam->B3SOIPDat = model->B3SOIPDat; + pParam->B3SOIPDgamma1 = model->B3SOIPDgamma1; + pParam->B3SOIPDgamma2 = model->B3SOIPDgamma2; + pParam->B3SOIPDvbx = model->B3SOIPDvbx; + pParam->B3SOIPDvbm = model->B3SOIPDvbm; + pParam->B3SOIPDxt = model->B3SOIPDxt; + pParam->B3SOIPDkt1 = model->B3SOIPDkt1; + pParam->B3SOIPDkt1l = model->B3SOIPDkt1l; + pParam->B3SOIPDkt2 = model->B3SOIPDkt2; + pParam->B3SOIPDua1 = model->B3SOIPDua1; + pParam->B3SOIPDub1 = model->B3SOIPDub1; + pParam->B3SOIPDuc1 = model->B3SOIPDuc1; + pParam->B3SOIPDute = model->B3SOIPDute; + pParam->B3SOIPDprt = model->B3SOIPDprt; + /* Not binned - END */ + + /* CV model */ + pParam->B3SOIPDcgsl = model->B3SOIPDcgsl; + pParam->B3SOIPDcgdl = model->B3SOIPDcgdl; + pParam->B3SOIPDckappa = model->B3SOIPDckappa; + pParam->B3SOIPDcf = model->B3SOIPDcf; + pParam->B3SOIPDclc = model->B3SOIPDclc; + pParam->B3SOIPDcle = model->B3SOIPDcle; + + pParam->B3SOIPDabulkCVfactor = + 1.0 + pow ((pParam->B3SOIPDclc / pParam->B3SOIPDleff), + pParam->B3SOIPDcle); + + /* Added for binning - START */ + if (model->B3SOIPDbinUnit == 1) + { + Inv_L = 1.0e-6 / pParam->B3SOIPDleff; + Inv_W = 1.0e-6 / pParam->B3SOIPDweff; + Inv_LW = 1.0e-12 / (pParam->B3SOIPDleff + * pParam->B3SOIPDweff); + } + else + { + Inv_L = 1.0 / pParam->B3SOIPDleff; + Inv_W = 1.0 / pParam->B3SOIPDweff; + Inv_LW = 1.0 / (pParam->B3SOIPDleff * pParam->B3SOIPDweff); + } + pParam->B3SOIPDnpeak = model->B3SOIPDnpeak + + model->B3SOIPDlnpeak * Inv_L + + model->B3SOIPDwnpeak * Inv_W + + model->B3SOIPDpnpeak * Inv_LW; + pParam->B3SOIPDnsub = model->B3SOIPDnsub + + model->B3SOIPDlnsub * Inv_L + + model->B3SOIPDwnsub * Inv_W + model->B3SOIPDpnsub * Inv_LW; + pParam->B3SOIPDngate = model->B3SOIPDngate + + model->B3SOIPDlngate * Inv_L + + model->B3SOIPDwngate * Inv_W + + model->B3SOIPDpngate * Inv_LW; + pParam->B3SOIPDvth0 = model->B3SOIPDvth0 + + model->B3SOIPDlvth0 * Inv_L + + model->B3SOIPDwvth0 * Inv_W + model->B3SOIPDpvth0 * Inv_LW; + pParam->B3SOIPDk1 = model->B3SOIPDk1 + + model->B3SOIPDlk1 * Inv_L + + model->B3SOIPDwk1 * Inv_W + model->B3SOIPDpk1 * Inv_LW; + pParam->B3SOIPDk2 = model->B3SOIPDk2 + + model->B3SOIPDlk2 * Inv_L + + model->B3SOIPDwk2 * Inv_W + model->B3SOIPDpk2 * Inv_LW; + pParam->B3SOIPDk1w1 = model->B3SOIPDk1w1 + + model->B3SOIPDlk1w1 * Inv_L + + model->B3SOIPDwk1w1 * Inv_W + model->B3SOIPDpk1w1 * Inv_LW; + pParam->B3SOIPDk1w2 = model->B3SOIPDk1w2 + + model->B3SOIPDlk1w2 * Inv_L + + model->B3SOIPDwk1w2 * Inv_W + model->B3SOIPDpk1w2 * Inv_LW; + pParam->B3SOIPDk3 = model->B3SOIPDk3 + + model->B3SOIPDlk3 * Inv_L + + model->B3SOIPDwk3 * Inv_W + model->B3SOIPDpk3 * Inv_LW; + pParam->B3SOIPDk3b = model->B3SOIPDk3b + + model->B3SOIPDlk3b * Inv_L + + model->B3SOIPDwk3b * Inv_W + model->B3SOIPDpk3b * Inv_LW; + pParam->B3SOIPDkb1 = model->B3SOIPDkb1 + + model->B3SOIPDlkb1 * Inv_L + + model->B3SOIPDwkb1 * Inv_W + model->B3SOIPDpkb1 * Inv_LW; + pParam->B3SOIPDw0 = model->B3SOIPDw0 + + model->B3SOIPDlw0 * Inv_L + + model->B3SOIPDww0 * Inv_W + model->B3SOIPDpw0 * Inv_LW; + pParam->B3SOIPDnlx = model->B3SOIPDnlx + + model->B3SOIPDlnlx * Inv_L + + model->B3SOIPDwnlx * Inv_W + model->B3SOIPDpnlx * Inv_LW; + pParam->B3SOIPDdvt0 = model->B3SOIPDdvt0 + + model->B3SOIPDldvt0 * Inv_L + + model->B3SOIPDwdvt0 * Inv_W + model->B3SOIPDpdvt0 * Inv_LW; + pParam->B3SOIPDdvt1 = model->B3SOIPDdvt1 + + model->B3SOIPDldvt1 * Inv_L + + model->B3SOIPDwdvt1 * Inv_W + model->B3SOIPDpdvt1 * Inv_LW; + pParam->B3SOIPDdvt2 = model->B3SOIPDdvt2 + + model->B3SOIPDldvt2 * Inv_L + + model->B3SOIPDwdvt2 * Inv_W + model->B3SOIPDpdvt2 * Inv_LW; + pParam->B3SOIPDdvt0w = model->B3SOIPDdvt0w + + model->B3SOIPDldvt0w * Inv_L + + model->B3SOIPDwdvt0w * Inv_W + + model->B3SOIPDpdvt0w * Inv_LW; + pParam->B3SOIPDdvt1w = model->B3SOIPDdvt1w + + model->B3SOIPDldvt1w * Inv_L + + model->B3SOIPDwdvt1w * Inv_W + + model->B3SOIPDpdvt1w * Inv_LW; + pParam->B3SOIPDdvt2w = model->B3SOIPDdvt2w + + model->B3SOIPDldvt2w * Inv_L + + model->B3SOIPDwdvt2w * Inv_W + + model->B3SOIPDpdvt2w * Inv_LW; + pParam->B3SOIPDu0 = model->B3SOIPDu0 + + model->B3SOIPDlu0 * Inv_L + + model->B3SOIPDwu0 * Inv_W + model->B3SOIPDpu0 * Inv_LW; + pParam->B3SOIPDua = model->B3SOIPDua + + model->B3SOIPDlua * Inv_L + + model->B3SOIPDwua * Inv_W + model->B3SOIPDpua * Inv_LW; + pParam->B3SOIPDub = model->B3SOIPDub + + model->B3SOIPDlub * Inv_L + + model->B3SOIPDwub * Inv_W + model->B3SOIPDpub * Inv_LW; + pParam->B3SOIPDuc = model->B3SOIPDuc + + model->B3SOIPDluc * Inv_L + + model->B3SOIPDwuc * Inv_W + model->B3SOIPDpuc * Inv_LW; + pParam->B3SOIPDvsat = model->B3SOIPDvsat + + model->B3SOIPDlvsat * Inv_L + + model->B3SOIPDwvsat * Inv_W + model->B3SOIPDpvsat * Inv_LW; + pParam->B3SOIPDa0 = model->B3SOIPDa0 + + model->B3SOIPDla0 * Inv_L + + model->B3SOIPDwa0 * Inv_W + model->B3SOIPDpa0 * Inv_LW; + pParam->B3SOIPDags = model->B3SOIPDags + + model->B3SOIPDlags * Inv_L + + model->B3SOIPDwags * Inv_W + model->B3SOIPDpags * Inv_LW; + pParam->B3SOIPDb0 = model->B3SOIPDb0 + + model->B3SOIPDlb0 * Inv_L + + model->B3SOIPDwb0 * Inv_W + model->B3SOIPDpb0 * Inv_LW; + pParam->B3SOIPDb1 = model->B3SOIPDb1 + + model->B3SOIPDlb1 * Inv_L + + model->B3SOIPDwb1 * Inv_W + model->B3SOIPDpb1 * Inv_LW; + pParam->B3SOIPDketa = model->B3SOIPDketa + + model->B3SOIPDlketa * Inv_L + + model->B3SOIPDwketa * Inv_W + model->B3SOIPDpketa * Inv_LW; + pParam->B3SOIPDketas = model->B3SOIPDketas + + model->B3SOIPDlketas * Inv_L + + model->B3SOIPDwketas * Inv_W + + model->B3SOIPDpketas * Inv_LW; + pParam->B3SOIPDa1 = model->B3SOIPDa1 + + model->B3SOIPDla1 * Inv_L + + model->B3SOIPDwa1 * Inv_W + model->B3SOIPDpa1 * Inv_LW; + pParam->B3SOIPDa2 = model->B3SOIPDa2 + + model->B3SOIPDla2 * Inv_L + + model->B3SOIPDwa2 * Inv_W + model->B3SOIPDpa2 * Inv_LW; + pParam->B3SOIPDrdsw = model->B3SOIPDrdsw + + model->B3SOIPDlrdsw * Inv_L + + model->B3SOIPDwrdsw * Inv_W + model->B3SOIPDprdsw * Inv_LW; + pParam->B3SOIPDprwb = model->B3SOIPDprwb + + model->B3SOIPDlprwb * Inv_L + + model->B3SOIPDwprwb * Inv_W + model->B3SOIPDpprwb * Inv_LW; + pParam->B3SOIPDprwg = model->B3SOIPDprwg + + model->B3SOIPDlprwg * Inv_L + + model->B3SOIPDwprwg * Inv_W + model->B3SOIPDpprwg * Inv_LW; + pParam->B3SOIPDwr = model->B3SOIPDwr + + model->B3SOIPDlwr * Inv_L + + model->B3SOIPDwwr * Inv_W + model->B3SOIPDpwr * Inv_LW; + pParam->B3SOIPDnfactor = model->B3SOIPDnfactor + + model->B3SOIPDlnfactor * Inv_L + + model->B3SOIPDwnfactor * Inv_W + + model->B3SOIPDpnfactor * Inv_LW; + pParam->B3SOIPDdwg = model->B3SOIPDdwg + + model->B3SOIPDldwg * Inv_L + + model->B3SOIPDwdwg * Inv_W + model->B3SOIPDpdwg * Inv_LW; + pParam->B3SOIPDdwb = model->B3SOIPDdwb + + model->B3SOIPDldwb * Inv_L + + model->B3SOIPDwdwb * Inv_W + model->B3SOIPDpdwb * Inv_LW; + pParam->B3SOIPDvoff = model->B3SOIPDvoff + + model->B3SOIPDlvoff * Inv_L + + model->B3SOIPDwvoff * Inv_W + model->B3SOIPDpvoff * Inv_LW; + pParam->B3SOIPDeta0 = model->B3SOIPDeta0 + + model->B3SOIPDleta0 * Inv_L + + model->B3SOIPDweta0 * Inv_W + model->B3SOIPDpeta0 * Inv_LW; + pParam->B3SOIPDetab = model->B3SOIPDetab + + model->B3SOIPDletab * Inv_L + + model->B3SOIPDwetab * Inv_W + model->B3SOIPDpetab * Inv_LW; + pParam->B3SOIPDdsub = model->B3SOIPDdsub + + model->B3SOIPDldsub * Inv_L + + model->B3SOIPDwdsub * Inv_W + model->B3SOIPDpdsub * Inv_LW; + pParam->B3SOIPDcit = model->B3SOIPDcit + + model->B3SOIPDlcit * Inv_L + + model->B3SOIPDwcit * Inv_W + model->B3SOIPDpcit * Inv_LW; + pParam->B3SOIPDcdsc = model->B3SOIPDcdsc + + model->B3SOIPDlcdsc * Inv_L + + model->B3SOIPDwcdsc * Inv_W + model->B3SOIPDpcdsc * Inv_LW; + pParam->B3SOIPDcdscb = model->B3SOIPDcdscb + + model->B3SOIPDlcdscb * Inv_L + + model->B3SOIPDwcdscb * Inv_W + + model->B3SOIPDpcdscb * Inv_LW; + pParam->B3SOIPDcdscd = model->B3SOIPDcdscd + + model->B3SOIPDlcdscd * Inv_L + + model->B3SOIPDwcdscd * Inv_W + + model->B3SOIPDpcdscd * Inv_LW; + pParam->B3SOIPDpclm = model->B3SOIPDpclm + + model->B3SOIPDlpclm * Inv_L + + model->B3SOIPDwpclm * Inv_W + model->B3SOIPDppclm * Inv_LW; + pParam->B3SOIPDpdibl1 = model->B3SOIPDpdibl1 + + model->B3SOIPDlpdibl1 * Inv_L + + model->B3SOIPDwpdibl1 * Inv_W + + model->B3SOIPDppdibl1 * Inv_LW; + pParam->B3SOIPDpdibl2 = model->B3SOIPDpdibl2 + + model->B3SOIPDlpdibl2 * Inv_L + + model->B3SOIPDwpdibl2 * Inv_W + + model->B3SOIPDppdibl2 * Inv_LW; + pParam->B3SOIPDpdiblb = model->B3SOIPDpdiblb + + model->B3SOIPDlpdiblb * Inv_L + + model->B3SOIPDwpdiblb * Inv_W + + model->B3SOIPDppdiblb * Inv_LW; + pParam->B3SOIPDdrout = model->B3SOIPDdrout + + model->B3SOIPDldrout * Inv_L + + model->B3SOIPDwdrout * Inv_W + + model->B3SOIPDpdrout * Inv_LW; + pParam->B3SOIPDpvag = model->B3SOIPDpvag + + model->B3SOIPDlpvag * Inv_L + + model->B3SOIPDwpvag * Inv_W + model->B3SOIPDppvag * Inv_LW; + pParam->B3SOIPDdelta = model->B3SOIPDdelta + + model->B3SOIPDldelta * Inv_L + + model->B3SOIPDwdelta * Inv_W + + model->B3SOIPDpdelta * Inv_LW; + pParam->B3SOIPDalpha0 = model->B3SOIPDalpha0 + + model->B3SOIPDlalpha0 * Inv_L + + model->B3SOIPDwalpha0 * Inv_W + + model->B3SOIPDpalpha0 * Inv_LW; + pParam->B3SOIPDfbjtii = model->B3SOIPDfbjtii + + model->B3SOIPDlfbjtii * Inv_L + + model->B3SOIPDwfbjtii * Inv_W + + model->B3SOIPDpfbjtii * Inv_LW; + pParam->B3SOIPDbeta0 = model->B3SOIPDbeta0 + + model->B3SOIPDlbeta0 * Inv_L + + model->B3SOIPDwbeta0 * Inv_W + + model->B3SOIPDpbeta0 * Inv_LW; + pParam->B3SOIPDbeta1 = model->B3SOIPDbeta1 + + model->B3SOIPDlbeta1 * Inv_L + + model->B3SOIPDwbeta1 * Inv_W + + model->B3SOIPDpbeta1 * Inv_LW; + pParam->B3SOIPDbeta2 = model->B3SOIPDbeta2 + + model->B3SOIPDlbeta2 * Inv_L + + model->B3SOIPDwbeta2 * Inv_W + + model->B3SOIPDpbeta2 * Inv_LW; + pParam->B3SOIPDvdsatii0 = model->B3SOIPDvdsatii0 + + model->B3SOIPDlvdsatii0 * Inv_L + + model->B3SOIPDwvdsatii0 * Inv_W + + model->B3SOIPDpvdsatii0 * Inv_LW; + pParam->B3SOIPDlii = model->B3SOIPDlii + + model->B3SOIPDllii * Inv_L + + model->B3SOIPDwlii * Inv_W + model->B3SOIPDplii * Inv_LW; + pParam->B3SOIPDesatii = model->B3SOIPDesatii + + model->B3SOIPDlesatii * Inv_L + + model->B3SOIPDwesatii * Inv_W + + model->B3SOIPDpesatii * Inv_LW; + pParam->B3SOIPDsii0 = model->B3SOIPDsii0 + + model->B3SOIPDlsii0 * Inv_L + + model->B3SOIPDwsii0 * Inv_W + model->B3SOIPDpsii0 * Inv_LW; + pParam->B3SOIPDsii1 = model->B3SOIPDsii1 + + model->B3SOIPDlsii1 * Inv_L + + model->B3SOIPDwsii1 * Inv_W + model->B3SOIPDpsii1 * Inv_LW; + pParam->B3SOIPDsii2 = model->B3SOIPDsii2 + + model->B3SOIPDlsii2 * Inv_L + + model->B3SOIPDwsii2 * Inv_W + model->B3SOIPDpsii2 * Inv_LW; + pParam->B3SOIPDsiid = model->B3SOIPDsiid + + model->B3SOIPDlsiid * Inv_L + + model->B3SOIPDwsiid * Inv_W + model->B3SOIPDpsiid * Inv_LW; + pParam->B3SOIPDagidl = model->B3SOIPDagidl + + model->B3SOIPDlagidl * Inv_L + + model->B3SOIPDwagidl * Inv_W + + model->B3SOIPDpagidl * Inv_LW; + pParam->B3SOIPDbgidl = model->B3SOIPDbgidl + + model->B3SOIPDlbgidl * Inv_L + + model->B3SOIPDwbgidl * Inv_W + + model->B3SOIPDpbgidl * Inv_LW; + pParam->B3SOIPDngidl = model->B3SOIPDngidl + + model->B3SOIPDlngidl * Inv_L + + model->B3SOIPDwngidl * Inv_W + + model->B3SOIPDpngidl * Inv_LW; + pParam->B3SOIPDntun = model->B3SOIPDntun + + model->B3SOIPDlntun * Inv_L + + model->B3SOIPDwntun * Inv_W + model->B3SOIPDpntun * Inv_LW; + pParam->B3SOIPDndiode = model->B3SOIPDndiode + + model->B3SOIPDlndiode * Inv_L + + model->B3SOIPDwndiode * Inv_W + + model->B3SOIPDpndiode * Inv_LW; + pParam->B3SOIPDnrecf0 = model->B3SOIPDnrecf0 + + model->B3SOIPDlnrecf0 * Inv_L + + model->B3SOIPDwnrecf0 * Inv_W + + model->B3SOIPDpnrecf0 * Inv_LW; + pParam->B3SOIPDnrecr0 = model->B3SOIPDnrecr0 + + model->B3SOIPDlnrecr0 * Inv_L + + model->B3SOIPDwnrecr0 * Inv_W + + model->B3SOIPDpnrecr0 * Inv_LW; + pParam->B3SOIPDisbjt = model->B3SOIPDisbjt + + model->B3SOIPDlisbjt * Inv_L + + model->B3SOIPDwisbjt * Inv_W + + model->B3SOIPDpisbjt * Inv_LW; + pParam->B3SOIPDisdif = model->B3SOIPDisdif + + model->B3SOIPDlisdif * Inv_L + + model->B3SOIPDwisdif * Inv_W + + model->B3SOIPDpisdif * Inv_LW; + pParam->B3SOIPDisrec = model->B3SOIPDisrec + + model->B3SOIPDlisrec * Inv_L + + model->B3SOIPDwisrec * Inv_W + + model->B3SOIPDpisrec * Inv_LW; + pParam->B3SOIPDistun = model->B3SOIPDistun + + model->B3SOIPDlistun * Inv_L + + model->B3SOIPDwistun * Inv_W + + model->B3SOIPDpistun * Inv_LW; + pParam->B3SOIPDvrec0 = model->B3SOIPDvrec0 + + model->B3SOIPDlvrec0 * Inv_L + + model->B3SOIPDwvrec0 * Inv_W + + model->B3SOIPDpvrec0 * Inv_LW; + pParam->B3SOIPDvtun0 = model->B3SOIPDvtun0 + + model->B3SOIPDlvtun0 * Inv_L + + model->B3SOIPDwvtun0 * Inv_W + + model->B3SOIPDpvtun0 * Inv_LW; + pParam->B3SOIPDnbjt = model->B3SOIPDnbjt + + model->B3SOIPDlnbjt * Inv_L + + model->B3SOIPDwnbjt * Inv_W + model->B3SOIPDpnbjt * Inv_LW; + pParam->B3SOIPDlbjt0 = model->B3SOIPDlbjt0 + + model->B3SOIPDllbjt0 * Inv_L + + model->B3SOIPDwlbjt0 * Inv_W + + model->B3SOIPDplbjt0 * Inv_LW; + pParam->B3SOIPDvabjt = model->B3SOIPDvabjt + + model->B3SOIPDlvabjt * Inv_L + + model->B3SOIPDwvabjt * Inv_W + + model->B3SOIPDpvabjt * Inv_LW; + pParam->B3SOIPDaely = model->B3SOIPDaely + + model->B3SOIPDlaely * Inv_L + + model->B3SOIPDwaely * Inv_W + model->B3SOIPDpaely * Inv_LW; + pParam->B3SOIPDahli = model->B3SOIPDahli + + model->B3SOIPDlahli * Inv_L + + model->B3SOIPDwahli * Inv_W + model->B3SOIPDpahli * Inv_LW; + /* CV model */ + pParam->B3SOIPDvsdfb = model->B3SOIPDvsdfb + + model->B3SOIPDlvsdfb * Inv_L + + model->B3SOIPDwvsdfb * Inv_W + + model->B3SOIPDpvsdfb * Inv_LW; + pParam->B3SOIPDvsdth = model->B3SOIPDvsdth + + model->B3SOIPDlvsdth * Inv_L + + model->B3SOIPDwvsdth * Inv_W + + model->B3SOIPDpvsdth * Inv_LW; + pParam->B3SOIPDdelvt = model->B3SOIPDdelvt + + model->B3SOIPDldelvt * Inv_L + + model->B3SOIPDwdelvt * Inv_W + + model->B3SOIPDpdelvt * Inv_LW; + pParam->B3SOIPDacde = model->B3SOIPDacde + + model->B3SOIPDlacde * Inv_L + + model->B3SOIPDwacde * Inv_W + model->B3SOIPDpacde * Inv_LW; + pParam->B3SOIPDmoin = model->B3SOIPDmoin + + model->B3SOIPDlmoin * Inv_L + + model->B3SOIPDwmoin * Inv_W + model->B3SOIPDpmoin * Inv_LW; + /* Added for binning - END */ + + T0 = (TempRatio - 1.0); + + pParam->B3SOIPDuatemp = pParam->B3SOIPDua; /* save ua, ub, and uc for b3soild.c */ + pParam->B3SOIPDubtemp = pParam->B3SOIPDub; + pParam->B3SOIPDuctemp = pParam->B3SOIPDuc; + pParam->B3SOIPDrds0denom = + pow (pParam->B3SOIPDweff * 1E6, pParam->B3SOIPDwr); + + +/* v2.2 release */ + pParam->B3SOIPDrth = + here->B3SOIPDrth0 / (pParam->B3SOIPDweff + + model->B3SOIPDwth0) * here->B3SOIPDnseg; + pParam->B3SOIPDcth = + here->B3SOIPDcth0 * (pParam->B3SOIPDweff + + model->B3SOIPDwth0) / here->B3SOIPDnseg; + pParam->B3SOIPDrbody = + model->B3SOIPDrbody * model->B3SOIPDrhalo / (2 * + model-> + B3SOIPDrbody + + model-> + B3SOIPDrhalo * + pParam-> + B3SOIPDleff) * + pParam->B3SOIPDweff / here->B3SOIPDnseg; + + pParam->B3SOIPDoxideRatio = + pow (model->B3SOIPDtoxref / model->B3SOIPDtoxqm, + model->B3SOIPDntox) / model->B3SOIPDtoxqm / + model->B3SOIPDtoxqm; +/* v2.2 release */ + + + pParam->B3SOIPDua = pParam->B3SOIPDua + pParam->B3SOIPDua1 * T0; + pParam->B3SOIPDub = pParam->B3SOIPDub + pParam->B3SOIPDub1 * T0; + pParam->B3SOIPDuc = pParam->B3SOIPDuc + pParam->B3SOIPDuc1 * T0; + if (pParam->B3SOIPDu0 > 1.0) + pParam->B3SOIPDu0 = pParam->B3SOIPDu0 / 1.0e4; + + pParam->B3SOIPDu0temp = pParam->B3SOIPDu0 + * pow (TempRatio, pParam->B3SOIPDute); + pParam->B3SOIPDvsattemp = + pParam->B3SOIPDvsat - pParam->B3SOIPDat * T0; + pParam->B3SOIPDrds0 = + (pParam->B3SOIPDrdsw + + pParam->B3SOIPDprt * T0) / pow (pParam->B3SOIPDweff * 1E6, + pParam->B3SOIPDwr); + + if (B3SOIPDcheckModel (model, here, ckt)) + { + IFuid namarray[2]; + namarray[0] = model->B3SOIPDmodName; + namarray[1] = here->B3SOIPDname; + + (*(SPfrontEnd->IFerror)) (ERR_FATAL, + "Fatal error(s) detected during B3SOIPDV3 parameter checking for %s in model %s", + namarray); + return (E_BADPARM); + } + + + pParam->B3SOIPDcgdo = (model->B3SOIPDcgdo + pParam->B3SOIPDcf) + * pParam->B3SOIPDwdiodCV; + pParam->B3SOIPDcgso = (model->B3SOIPDcgso + pParam->B3SOIPDcf) + * pParam->B3SOIPDwdiosCV; + + pParam->B3SOIPDcgeo = model->B3SOIPDcgeo + * pParam->B3SOIPDleffCV; + + + if (!model->B3SOIPDnpeakGiven && model->B3SOIPDgamma1Given) + { + T0 = pParam->B3SOIPDgamma1 * model->B3SOIPDcox; + pParam->B3SOIPDnpeak = 3.021E22 * T0 * T0; + } + + + T4 = Eg300 / model->B3SOIPDvtm * (TempRatio - 1.0); + T7 = model->B3SOIPDxbjt * T4 / pParam->B3SOIPDndiode; + DEXP (T7, T0); + T7 = model->B3SOIPDxdif * T4 / pParam->B3SOIPDndiode; + DEXP (T7, T1); + T7 = model->B3SOIPDxrec * T4 / pParam->B3SOIPDnrecf0; + DEXP (T7, T2); + + pParam->B3SOIPDahli = pParam->B3SOIPDahli * T0; + + pParam->B3SOIPDjbjt = pParam->B3SOIPDisbjt * T0; + pParam->B3SOIPDjdif = pParam->B3SOIPDisdif * T1; + pParam->B3SOIPDjrec = pParam->B3SOIPDisrec * T2; + + T7 = model->B3SOIPDxtun * (TempRatio - 1); + DEXP (T7, T0); + pParam->B3SOIPDjtun = pParam->B3SOIPDistun * T0; + + + if (pParam->B3SOIPDnsub > 0) + pParam->B3SOIPDvfbb = + -model->B3SOIPDtype * model->B3SOIPDvtm * + log (pParam->B3SOIPDnpeak / pParam->B3SOIPDnsub); + else + pParam->B3SOIPDvfbb = + -model->B3SOIPDtype * model->B3SOIPDvtm * + log (-pParam->B3SOIPDnpeak * pParam->B3SOIPDnsub / ni / ni); + + if (!model->B3SOIPDvsdfbGiven) + { + if (pParam->B3SOIPDnsub > 0) + pParam->B3SOIPDvsdfb = + -model->B3SOIPDtype * (model->B3SOIPDvtm * + log (1e20 * pParam->B3SOIPDnsub / + ni / ni) - 0.3); + else if (pParam->B3SOIPDnsub < 0) + pParam->B3SOIPDvsdfb = + -model->B3SOIPDtype * (model->B3SOIPDvtm * + log (-1e20 / + pParam->B3SOIPDnsub) + 0.3); + } + + /* Phi & Gamma */ + SDphi = + 2.0 * model->B3SOIPDvtm * log (fabs (pParam->B3SOIPDnsub) / + ni); + SDgamma = + 5.753e-12 * sqrt (fabs (pParam->B3SOIPDnsub)) / + model->B3SOIPDcbox; + + if (!model->B3SOIPDvsdthGiven) + { + if (((pParam->B3SOIPDnsub > 0) && (model->B3SOIPDtype > 0)) + || ((pParam->B3SOIPDnsub < 0) + && (model->B3SOIPDtype < 0))) + pParam->B3SOIPDvsdth = + pParam->B3SOIPDvsdfb + SDphi + SDgamma * sqrt (SDphi); + else + pParam->B3SOIPDvsdth = + pParam->B3SOIPDvsdfb - SDphi - SDgamma * sqrt (SDphi); + } + + if (!model->B3SOIPDcsdminGiven) + { + /* Cdmin */ + tmp = sqrt (2.0 * EPSSI * SDphi / (Charge_q * + fabs (pParam-> + B3SOIPDnsub) * + 1.0e6)); + tmp1 = EPSSI / tmp; + model->B3SOIPDcsdmin = tmp1 * model->B3SOIPDcbox / + (tmp1 + model->B3SOIPDcbox); + } + + T0 = model->B3SOIPDcsdesw * log (1 + model->B3SOIPDtsi / + model->B3SOIPDtbox); + T1 = here->B3SOIPDsourcePerimeter - here->B3SOIPDw; + if (T1 > 0.0) + pParam->B3SOIPDcsesw = T0 * T1; + else + pParam->B3SOIPDcsesw = 0.0; + T1 = here->B3SOIPDdrainPerimeter - here->B3SOIPDw; + if (T1 > 0.0) + pParam->B3SOIPDcdesw = T0 * T1; + else + pParam->B3SOIPDcdesw = 0.0; + + pParam->B3SOIPDphi = 2.0 * model->B3SOIPDvtm + * log (pParam->B3SOIPDnpeak / ni); + + pParam->B3SOIPDsqrtPhi = sqrt (pParam->B3SOIPDphi); + pParam->B3SOIPDphis3 = + pParam->B3SOIPDsqrtPhi * pParam->B3SOIPDphi; + + pParam->B3SOIPDXdep0 = sqrt (2.0 * EPSSI / (Charge_q + * + pParam-> + B3SOIPDnpeak * + 1.0e6)) * + pParam->B3SOIPDsqrtPhi; + pParam->B3SOIPDsqrtXdep0 = sqrt (pParam->B3SOIPDXdep0); + pParam->B3SOIPDlitl = sqrt (3.0 * model->B3SOIPDxj + * model->B3SOIPDtox); + pParam->B3SOIPDvbi = model->B3SOIPDvtm * log (1.0e20 + * + pParam-> + B3SOIPDnpeak / + (ni * ni)); + pParam->B3SOIPDcdep0 = + sqrt (Charge_q * EPSSI * pParam->B3SOIPDnpeak * 1.0e6 / 2.0 / + pParam->B3SOIPDphi); + + if (model->B3SOIPDk1Given || model->B3SOIPDk2Given) + { + if (!model->B3SOIPDk1Given) + { + fprintf (stdout, + "Warning: k1 should be specified with k2.\n"); + pParam->B3SOIPDk1 = 0.53; + } + if (!model->B3SOIPDk2Given) + { + fprintf (stdout, + "Warning: k2 should be specified with k1.\n"); + pParam->B3SOIPDk2 = -0.0186; + } + if (model->B3SOIPDxtGiven) + fprintf (stdout, + "Warning: xt is ignored because k1 or k2 is given.\n"); + if (model->B3SOIPDvbxGiven) + fprintf (stdout, + "Warning: vbx is ignored because k1 or k2 is given.\n"); + if (model->B3SOIPDvbmGiven) + fprintf (stdout, + "Warning: vbm is ignored because k1 or k2 is given.\n"); + if (model->B3SOIPDgamma1Given) + fprintf (stdout, + "Warning: gamma1 is ignored because k1 or k2 is given.\n"); + if (model->B3SOIPDgamma2Given) + fprintf (stdout, + "Warning: gamma2 is ignored because k1 or k2 is given.\n"); + } + else + { + if (!model->B3SOIPDvbxGiven) + pParam->B3SOIPDvbx = pParam->B3SOIPDphi - 7.7348e-4 + * pParam->B3SOIPDnpeak + * pParam->B3SOIPDxt * pParam->B3SOIPDxt; + if (pParam->B3SOIPDvbx > 0.0) + pParam->B3SOIPDvbx = -pParam->B3SOIPDvbx; + if (pParam->B3SOIPDvbm > 0.0) + pParam->B3SOIPDvbm = -pParam->B3SOIPDvbm; + + if (!model->B3SOIPDgamma1Given) + pParam->B3SOIPDgamma1 = 5.753e-12 + * sqrt (pParam->B3SOIPDnpeak) / model->B3SOIPDcox; + if (!model->B3SOIPDgamma2Given) + pParam->B3SOIPDgamma2 = 5.753e-12 + * sqrt (pParam->B3SOIPDnsub) / model->B3SOIPDcox; + + T0 = pParam->B3SOIPDgamma1 - pParam->B3SOIPDgamma2; + T1 = sqrt (pParam->B3SOIPDphi - pParam->B3SOIPDvbx) + - pParam->B3SOIPDsqrtPhi; + T2 = sqrt (pParam->B3SOIPDphi * (pParam->B3SOIPDphi + - pParam->B3SOIPDvbm)) - + pParam->B3SOIPDphi; + pParam->B3SOIPDk2 = + T0 * T1 / (2.0 * T2 + pParam->B3SOIPDvbm); + pParam->B3SOIPDk1 = + pParam->B3SOIPDgamma2 - + 2.0 * pParam->B3SOIPDk2 * sqrt (pParam->B3SOIPDphi - + pParam->B3SOIPDvbm); + } + + if (pParam->B3SOIPDk2 < 0.0) + { + T0 = 0.5 * pParam->B3SOIPDk1 / pParam->B3SOIPDk2; + pParam->B3SOIPDvbsc = 0.9 * (pParam->B3SOIPDphi - T0 * T0); + if (pParam->B3SOIPDvbsc > -3.0) + pParam->B3SOIPDvbsc = -3.0; + else if (pParam->B3SOIPDvbsc < -30.0) + pParam->B3SOIPDvbsc = -30.0; + } + else + { + pParam->B3SOIPDvbsc = -30.0; + } + if (pParam->B3SOIPDvbsc > pParam->B3SOIPDvbm) + pParam->B3SOIPDvbsc = pParam->B3SOIPDvbm; + + if ((T0 = pParam->B3SOIPDweff + pParam->B3SOIPDk1w2) < 1e-8) + T0 = 1e-8; + pParam->B3SOIPDk1eff = + pParam->B3SOIPDk1 * (1 + pParam->B3SOIPDk1w1 / T0); + + if (model->B3SOIPDvth0Given) + { + pParam->B3SOIPDvfb = + model->B3SOIPDtype * pParam->B3SOIPDvth0 - + pParam->B3SOIPDphi - + pParam->B3SOIPDk1eff * pParam->B3SOIPDsqrtPhi; + } + else + { + pParam->B3SOIPDvfb = -1.0; + pParam->B3SOIPDvth0 = + model->B3SOIPDtype * (pParam->B3SOIPDvfb + + pParam->B3SOIPDphi + + pParam->B3SOIPDk1eff * + pParam->B3SOIPDsqrtPhi); + } + T1 = sqrt (EPSSI / EPSOX * model->B3SOIPDtox + * pParam->B3SOIPDXdep0); + T0 = + exp (-0.5 * pParam->B3SOIPDdsub * pParam->B3SOIPDleff / T1); + pParam->B3SOIPDtheta0vb0 = (T0 + 2.0 * T0 * T0); + + T0 = + exp (-0.5 * pParam->B3SOIPDdrout * pParam->B3SOIPDleff / T1); + T2 = (T0 + 2.0 * T0 * T0); + pParam->B3SOIPDthetaRout = pParam->B3SOIPDpdibl1 * T2 + + pParam->B3SOIPDpdibl2; + } + + here->B3SOIPDcsbox = model->B3SOIPDcbox * here->B3SOIPDsourceArea; + here->B3SOIPDcsmin = model->B3SOIPDcsdmin * here->B3SOIPDsourceArea; + here->B3SOIPDcdbox = model->B3SOIPDcbox * here->B3SOIPDdrainArea; + here->B3SOIPDcdmin = model->B3SOIPDcsdmin * here->B3SOIPDdrainArea; + + if (((pParam->B3SOIPDnsub > 0) && (model->B3SOIPDtype > 0)) || + ((pParam->B3SOIPDnsub < 0) && (model->B3SOIPDtype < 0))) + { + T0 = pParam->B3SOIPDvsdth - pParam->B3SOIPDvsdfb; + pParam->B3SOIPDsdt1 = + pParam->B3SOIPDvsdfb + model->B3SOIPDasd * T0; + T1 = here->B3SOIPDcsbox - here->B3SOIPDcsmin; + T2 = T1 / T0 / T0; + pParam->B3SOIPDst2 = T2 / model->B3SOIPDasd; + pParam->B3SOIPDst3 = T2 / (1 - model->B3SOIPDasd); + here->B3SOIPDst4 = T0 * T1 * (1 + model->B3SOIPDasd) / 3 + - here->B3SOIPDcsmin * pParam->B3SOIPDvsdfb; + + T1 = here->B3SOIPDcdbox - here->B3SOIPDcdmin; + T2 = T1 / T0 / T0; + pParam->B3SOIPDdt2 = T2 / model->B3SOIPDasd; + pParam->B3SOIPDdt3 = T2 / (1 - model->B3SOIPDasd); + here->B3SOIPDdt4 = T0 * T1 * (1 + model->B3SOIPDasd) / 3 + - here->B3SOIPDcdmin * pParam->B3SOIPDvsdfb; + } + else + { + T0 = pParam->B3SOIPDvsdfb - pParam->B3SOIPDvsdth; + pParam->B3SOIPDsdt1 = + pParam->B3SOIPDvsdth + model->B3SOIPDasd * T0; + T1 = here->B3SOIPDcsmin - here->B3SOIPDcsbox; + T2 = T1 / T0 / T0; + pParam->B3SOIPDst2 = T2 / model->B3SOIPDasd; + pParam->B3SOIPDst3 = T2 / (1 - model->B3SOIPDasd); + here->B3SOIPDst4 = T0 * T1 * (1 + model->B3SOIPDasd) / 3 + - here->B3SOIPDcsbox * pParam->B3SOIPDvsdth; + + T1 = here->B3SOIPDcdmin - here->B3SOIPDcdbox; + T2 = T1 / T0 / T0; + pParam->B3SOIPDdt2 = T2 / model->B3SOIPDasd; + pParam->B3SOIPDdt3 = T2 / (1 - model->B3SOIPDasd); + here->B3SOIPDdt4 = T0 * T1 * (1 + model->B3SOIPDasd) / 3 + - here->B3SOIPDcdbox * pParam->B3SOIPDvsdth; + } + + here->B3SOIPDphi = pParam->B3SOIPDphi; + /* process source/drain series resistance */ + here->B3SOIPDdrainConductance = model->B3SOIPDsheetResistance + * here->B3SOIPDdrainSquares; + if (here->B3SOIPDdrainConductance > 0.0) + here->B3SOIPDdrainConductance = 1.0 + / here->B3SOIPDdrainConductance; + else + here->B3SOIPDdrainConductance = 0.0; + + here->B3SOIPDsourceConductance = model->B3SOIPDsheetResistance + * here->B3SOIPDsourceSquares; + if (here->B3SOIPDsourceConductance > 0.0) + here->B3SOIPDsourceConductance = 1.0 + / here->B3SOIPDsourceConductance; + else + here->B3SOIPDsourceConductance = 0.0; + here->B3SOIPDcgso = pParam->B3SOIPDcgso; + here->B3SOIPDcgdo = pParam->B3SOIPDcgdo; + + +/* v2.0 release */ + if (model->B3SOIPDln < 1e-15) + model->B3SOIPDln = 1e-15; + T0 = + -0.5 * pParam->B3SOIPDleff * pParam->B3SOIPDleff / + model->B3SOIPDln / model->B3SOIPDln; + DEXP (T0, T1); + pParam->B3SOIPDarfabjt = T1; + + T0 = + pParam->B3SOIPDlbjt0 * (1.0 / pParam->B3SOIPDleff + + 1.0 / model->B3SOIPDln); + pParam->B3SOIPDlratio = pow (T0, pParam->B3SOIPDnbjt); + pParam->B3SOIPDlratiodif = + 1.0 + model->B3SOIPDldif0 * pow (T0, model->B3SOIPDndif); + + if ( + (pParam->B3SOIPDvearly = + pParam->B3SOIPDvabjt + + pParam->B3SOIPDaely * pParam->B3SOIPDleff) < 1) + pParam->B3SOIPDvearly = 1; + + /* vfbzb calculation for capMod 3 */ + tmp = sqrt (pParam->B3SOIPDXdep0); + tmp1 = pParam->B3SOIPDvbi - pParam->B3SOIPDphi; + tmp2 = model->B3SOIPDfactor1 * tmp; + + T0 = -0.5 * pParam->B3SOIPDdvt1w * pParam->B3SOIPDweff + * pParam->B3SOIPDleff / tmp2; + if (T0 > -EXPL_THRESHOLD) + { + T1 = exp (T0); + T2 = T1 * (1.0 + 2.0 * T1); + } + else + { + T1 = MIN_EXPL; + T2 = T1 * (1.0 + 2.0 * T1); + } + T0 = pParam->B3SOIPDdvt0w * T2; + T2 = T0 * tmp1; + + T0 = -0.5 * pParam->B3SOIPDdvt1 * pParam->B3SOIPDleff / tmp2; + if (T0 > -EXPL_THRESHOLD) + { + T1 = exp (T0); + T3 = T1 * (1.0 + 2.0 * T1); + } + else + { + T1 = MIN_EXPL; + T3 = T1 * (1.0 + 2.0 * T1); + } + T3 = pParam->B3SOIPDdvt0 * T3 * tmp1; + + T4 = model->B3SOIPDtox * pParam->B3SOIPDphi + / (pParam->B3SOIPDweff + pParam->B3SOIPDw0); + + T0 = sqrt (1.0 + pParam->B3SOIPDnlx / pParam->B3SOIPDleff); + T5 = pParam->B3SOIPDk1eff * (T0 - 1.0) * pParam->B3SOIPDsqrtPhi + + (pParam->B3SOIPDkt1 + pParam->B3SOIPDkt1l / pParam->B3SOIPDleff) + * (TempRatio - 1.0); + + tmp3 = model->B3SOIPDtype * pParam->B3SOIPDvth0 + - T2 - T3 + pParam->B3SOIPDk3 * T4 + T5; + pParam->B3SOIPDvfbzb = + tmp3 - pParam->B3SOIPDphi - + pParam->B3SOIPDk1eff * pParam->B3SOIPDsqrtPhi; + /* End of vfbzb */ + + pParam->B3SOIPDldeb = + sqrt (EPSSI * Vtm0 / (Charge_q * pParam->B3SOIPDnpeak * 1.0e6)) / + 3.0; + pParam->B3SOIPDacde = + pParam->B3SOIPDacde * pow ((pParam->B3SOIPDnpeak / 2.0e16), + -0.25); + } + } + return (OK); +} diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdtrunc.c b/src/spicelib/devices/bsim3soi_pd/b3soipdtrunc.c new file mode 100644 index 000000000..3cb66d5da --- /dev/null +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdtrunc.c @@ -0,0 +1,51 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soipdtrunc.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "b3soipddef.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIPDtrunc (inModel, ckt, timeStep) + GENmodel *inModel; + CKTcircuit *ckt; + double *timeStep; +{ + B3SOIPDmodel *model = (B3SOIPDmodel *) inModel; + B3SOIPDinstance *here; + +#ifdef STEPDEBUG + double debugtemp; +#endif /* STEPDEBUG */ + + for (; model != NULL; model = model->B3SOIPDnextModel) + { + for (here = model->B3SOIPDinstances; here != NULL; + here = here->B3SOIPDnextInstance) + { +#ifdef STEPDEBUG + debugtemp = *timeStep; +#endif /* STEPDEBUG */ + CKTterr (here->B3SOIPDqb, ckt, timeStep); + CKTterr (here->B3SOIPDqg, ckt, timeStep); + CKTterr (here->B3SOIPDqd, ckt, timeStep); +#ifdef STEPDEBUG + if (debugtemp != *timeStep) + { + printf ("device %s reduces step from %g to %g\n", + here->B3SOIPDname, debugtemp, *timeStep); + } +#endif /* STEPDEBUG */ + } + } + return (OK); +} 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 1517fd0b3..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 91dc95c9d..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 7db286aaf..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 ac708ccc6..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 c603642f5..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 4f2754016..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 5fb0cb475..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 c71a7fc88..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 6e7044c2f..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 76bdaa19d..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 94a8b1bb7..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 60ad98aab..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 0f93a8f39..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 9aa0be00d..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 79a8b0252..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 c03093d9d..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 938b7e26d..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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 ec86d0d3d..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 2000-04-27 20:03:59 pnenzi -Initial revision - - * 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/bsim3v1init.c b/src/spicelib/devices/bsim3v1/bsim3v1init.c new file mode 100644 index 000000000..5adacdfea --- /dev/null +++ b/src/spicelib/devices/bsim3v1/bsim3v1init.c @@ -0,0 +1,66 @@ +#include + +#include + +#include "bsim3v1itf.h" +#include "bsim3v1ext.h" +#include "bsim3v1init.h" + + +SPICEdev BSIM3V1info = { + { + "BSIM3V1", + "Berkeley Short Channel IGFET Model Version-3 (3v3.1)", + + &BSIM3V1nSize, + &BSIM3V1nSize, + BSIM3V1names, + + &BSIM3V1pTSize, + BSIM3V1pTable, + + &BSIM3V1mPTSize, + BSIM3V1mPTable, + DEV_DEFAULT, + + }, + + DEVparam : BSIM3V1param, + DEVmodParam : BSIM3V1mParam, + DEVload : BSIM3V1load, + DEVsetup : BSIM3V1setup, + DEVunsetup : NULL, + DEVpzSetup : BSIM3V1setup, + DEVtemperature: BSIM3V1temp, + DEVtrunc : BSIM3V1trunc, + DEVfindBranch : NULL, + DEVacLoad : BSIM3V1acLoad, + DEVaccept : NULL, + DEVdestroy : BSIM3V1destroy, + DEVmodDelete : BSIM3V1mDelete, + DEVdelete : BSIM3V1delete, + DEVsetic : BSIM3V1getic, + DEVask : BSIM3V1ask, + DEVmodAsk : BSIM3V1mAsk, + DEVpzLoad : BSIM3V1pzLoad, + DEVconvTest : BSIM3V1convTest, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, + DEVnoise : BSIM3V1noise, + + DEVinstSize : &BSIM3V1iSize, + DEVmodSize : &BSIM3V1mSize + +}; + + +SPICEdev * +get_bsim3v1_info(void) +{ + return &BSIM3V1info; +} diff --git a/src/spicelib/devices/bsim3v1/bsim3v1init.h b/src/spicelib/devices/bsim3v1/bsim3v1init.h new file mode 100644 index 000000000..7c8ae9b3c --- /dev/null +++ b/src/spicelib/devices/bsim3v1/bsim3v1init.h @@ -0,0 +1,13 @@ +#ifndef _BSIM3V1INIT_H +#define _BSIM3V1INIT_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; + +#endif 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 55b5528ea..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 b47860030..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 cc1325dfd..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 2f270b7ea..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 2f59d3781..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 f935a5b4e..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 50380f4ab..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 ba732b358..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 6b315712a..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 e5366c337..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 4c19c47fd..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 e485959b5..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 7e4b09b3e..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 e5d3985a7..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 255c2d127..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 529d60867..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 f6c4ee0b5..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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 38f20e7db..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 2000-04-27 20:03:59 pnenzi - Initial revision - - * 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/bsim3v2init.c b/src/spicelib/devices/bsim3v2/bsim3v2init.c new file mode 100644 index 000000000..4a82a3901 --- /dev/null +++ b/src/spicelib/devices/bsim3v2/bsim3v2init.c @@ -0,0 +1,64 @@ +#include + +#include + +#include "bsim3v2itf.h" +#include "bsim3v2ext.h" +#include "bsim3v2init.h" + + +SPICEdev BSIM3V2info = { + { "BSIM3V2", + "Berkeley Short Channel IGFET Model Version-3 (3v3.2)", + + &BSIM3V2nSize, + &BSIM3V2nSize, + BSIM3V2names, + + &BSIM3V2pTSize, + BSIM3V2pTable, + + &BSIM3V2mPTSize, + BSIM3V2mPTable, + DEV_DEFAULT + }, + + DEVparam : BSIM3V2param, + DEVmodParam : BSIM3V2mParam, + DEVload : BSIM3V2load, + DEVsetup : BSIM3V2setup, + DEVunsetup : BSIM3V2unsetup, + DEVpzSetup : BSIM3V2setup, + DEVtemperature: BSIM3V2temp, + DEVtrunc : BSIM3V2trunc, + DEVfindBranch : NULL, + DEVacLoad : BSIM3V2acLoad, + DEVaccept : NULL, + DEVdestroy : BSIM3V2destroy, + DEVmodDelete : BSIM3V2mDelete, + DEVdelete : BSIM3V2delete, + DEVsetic : BSIM3V2getic, + DEVask : BSIM3V2ask, + DEVmodAsk : BSIM3V2mAsk, + DEVpzLoad : BSIM3V2pzLoad, + DEVconvTest : BSIM3V2convTest, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, + DEVnoise : BSIM3V2noise, + + DEVinstSize : &BSIM3V2iSize, + DEVmodSize : &BSIM3V2mSize + +}; + + +SPICEdev * +get_bsim3v2_info(void) +{ + return &BSIM3V2info; +} diff --git a/src/spicelib/devices/bsim3v2/bsim3v2init.h b/src/spicelib/devices/bsim3v2/bsim3v2init.h new file mode 100644 index 000000000..3ac12cfc5 --- /dev/null +++ b/src/spicelib/devices/bsim3v2/bsim3v2init.h @@ -0,0 +1,13 @@ +#ifndef _BSIM3V2INIT_H +#define _BSIM3V2INIT_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; + +#endif 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/bsim4init.c b/src/spicelib/devices/bsim4/bsim4init.c new file mode 100644 index 000000000..6d906ef90 --- /dev/null +++ b/src/spicelib/devices/bsim4/bsim4init.c @@ -0,0 +1,64 @@ +#include + +#include + +#include "bsim4itf.h" +#include "bsim4ext.h" +#include "bsim4init.h" + + +SPICEdev BSIM4info = { + { + "BSIM4", + "Berkeley Short Channel IGFET Model-4", + + &BSIM4nSize, + &BSIM4nSize, + BSIM4names, + + &BSIM4pTSize, + BSIM4pTable, + + &BSIM4mPTSize, + BSIM4mPTable, + DEV_DEFAULT + }, + + DEVparam : BSIM4param, + DEVmodParam : BSIM4mParam, + DEVload : BSIM4load, + DEVsetup : BSIM4setup, + DEVunsetup : BSIM4unsetup, + DEVpzSetup : BSIM4setup, + DEVtemperature: BSIM4temp, + DEVtrunc : BSIM4trunc, + DEVfindBranch : NULL, + DEVacLoad : BSIM4acLoad, + DEVaccept : NULL, + DEVdestroy : BSIM4destroy, + DEVmodDelete : BSIM4mDelete, + DEVdelete : BSIM4delete, + DEVsetic : BSIM4getic, + DEVask : BSIM4ask, + DEVmodAsk : BSIM4mAsk, + DEVpzLoad : BSIM4pzLoad, + DEVconvTest : BSIM4convTest, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, + DEVnoise : BSIM4noise, + + DEVinstSize : &BSIM4iSize, + DEVmodSize : &BSIM4mSize +}; + + +SPICEdev * +get_bsim4_info(void) +{ + return &BSIM4info; +} diff --git a/src/spicelib/devices/bsim4/bsim4init.h b/src/spicelib/devices/bsim4/bsim4init.h new file mode 100644 index 000000000..11faee141 --- /dev/null +++ b/src/spicelib/devices/bsim4/bsim4init.h @@ -0,0 +1,13 @@ +#ifndef _BSIM4INIT_H +#define _BSIM4INIT_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; + +#endif 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/capinit.c b/src/spicelib/devices/cap/capinit.c new file mode 100644 index 000000000..4954d563b --- /dev/null +++ b/src/spicelib/devices/cap/capinit.c @@ -0,0 +1,63 @@ +#include + +#include + +#include "capitf.h" +#include "capext.h" +#include "capinit.h" + + +SPICEdev CAPinfo = { + { "Capacitor", + "Fixed capacitor", + + &CAPnSize, + &CAPnSize, + CAPnames, + + &CAPpTSize, + CAPpTable, + + &CAPmPTSize, + CAPmPTable, + 0 + }, + + DEVparam : CAPparam, + DEVmodParam : CAPmParam, + DEVload : CAPload, + DEVsetup : CAPsetup, + DEVunsetup : NULL, + DEVpzSetup : CAPsetup, + DEVtemperature: CAPtemp, + DEVtrunc : CAPtrunc, + DEVfindBranch : NULL, + DEVacLoad : CAPacLoad, + DEVaccept : NULL, + DEVdestroy : CAPdestroy, + DEVmodDelete : CAPmDelete, + DEVdelete : CAPdelete, + DEVsetic : CAPgetic, + DEVask : CAPask, + DEVmodAsk : CAPmAsk, + DEVpzLoad : CAPpzLoad, + DEVconvTest : NULL, + DEVsenSetup : CAPsSetup, + DEVsenLoad : CAPsLoad, + DEVsenUpdate : CAPsUpdate, + DEVsenAcLoad : CAPsAcLoad, + DEVsenPrint : CAPsPrint, + DEVsenTrunc : NULL, + DEVdisto : NULL, /* DISTO */ + DEVnoise : NULL, /* NOISE */ + + DEVinstSize : &CAPiSize, + DEVmodSize : &CAPmSize +}; + + +SPICEdev * +get_cap_info(void) +{ + return &CAPinfo; +} diff --git a/src/spicelib/devices/cap/capinit.h b/src/spicelib/devices/cap/capinit.h new file mode 100644 index 000000000..143abfb62 --- /dev/null +++ b/src/spicelib/devices/cap/capinit.h @@ -0,0 +1,13 @@ +#ifndef _CAPINIT_H +#define _CAPINIT_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; + +#endif 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/cccsinit.c b/src/spicelib/devices/cccs/cccsinit.c new file mode 100644 index 000000000..f061a39f2 --- /dev/null +++ b/src/spicelib/devices/cccs/cccsinit.c @@ -0,0 +1,64 @@ +#include + +#include + +#include "cccsitf.h" +#include "cccsext.h" +#include "cccsinit.h" + + +SPICEdev CCCSinfo = { + { "CCCS", + "Current controlled current source", + + &CCCSnSize, + &CCCSnSize, + CCCSnames, + + &CCCSpTSize, + CCCSpTable, + + 0, + NULL, + DEV_DEFAULT + }, + + DEVparam : CCCSparam, + DEVmodParam : NULL, + DEVload : CCCSload, + DEVsetup : CCCSsetup, + DEVunsetup : NULL, + DEVpzSetup : CCCSsetup, + DEVtemperature: NULL, + DEVtrunc : NULL, + DEVfindBranch : NULL, + DEVacLoad : CCCSload, + DEVaccept : NULL, + DEVdestroy : CCCSdestroy, + DEVmodDelete : CCCSmDelete, + DEVdelete : CCCSdelete, + DEVsetic : NULL, + DEVask : CCCSask, + DEVmodAsk : NULL, + DEVpzLoad : CCCSpzLoad, + DEVconvTest : NULL, + DEVsenSetup : CCCSsSetup, + DEVsenLoad : CCCSsLoad, + DEVsenUpdate : NULL, + DEVsenAcLoad : CCCSsAcLoad, + DEVsenPrint : CCCSsPrint, + DEVsenTrunc : NULL, + DEVdisto : NULL, /* DISTO */ + DEVnoise : NULL, /* NOISE */ + + DEVinstSize : &CCCSiSize, + DEVmodSize : &CCCSmSize + +}; + + +SPICEdev * +get_cccs_info(void) +{ + return &CCCSinfo; +} diff --git a/src/spicelib/devices/cccs/cccsinit.h b/src/spicelib/devices/cccs/cccsinit.h new file mode 100644 index 000000000..4d7dd002c --- /dev/null +++ b/src/spicelib/devices/cccs/cccsinit.h @@ -0,0 +1,11 @@ +#ifndef _CCCSINIT_H +#define _CCCSINIT_H + +extern IFparm CCCSpTable[ ]; +extern char *CCCSnames[ ]; +extern int CCCSpTSize; +extern int CCCSnSize; +extern int CCCSiSize; +extern int CCCSmSize; + +#endif 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/ccvsinit.c b/src/spicelib/devices/ccvs/ccvsinit.c new file mode 100644 index 000000000..1df05d896 --- /dev/null +++ b/src/spicelib/devices/ccvs/ccvsinit.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "ccvsitf.h" +#include "ccvsext.h" +#include "ccvsinit.h" + + +SPICEdev CCVSinfo = { + { + "CCVS", + "Linear current controlled current source", + + &CCVSnSize, + &CCVSnSize, + CCVSnames, + + &CCVSpTSize, + CCVSpTable, + + 0, + NULL, + DEV_DEFAULT + }, + + DEVparam : CCVSparam, + DEVmodParam : NULL, + DEVload : CCVSload, + DEVsetup : CCVSsetup, + DEVunsetup : CCVSunsetup, + DEVpzSetup : CCVSsetup, + DEVtemperature: NULL, + DEVtrunc : NULL, + DEVfindBranch : CCVSfindBr, + DEVacLoad : CCVSload, /* ac and normal load functions identical */ + DEVaccept : NULL, + DEVdestroy : CCVSdestroy, + DEVmodDelete : CCVSmDelete, + DEVdelete : CCVSdelete, + DEVsetic : NULL, + DEVask : CCVSask, + DEVmodAsk : NULL, + DEVpzLoad : CCVSpzLoad, + DEVconvTest : NULL, + DEVsenSetup : CCVSsSetup, + DEVsenLoad : CCVSsLoad, + DEVsenUpdate : NULL, + DEVsenAcLoad : CCVSsAcLoad, + DEVsenPrint : CCVSsPrint, + DEVsenTrunc : NULL, + DEVdisto : NULL, /* DISTO */ + DEVnoise : NULL, /* NOISE */ + + DEVinstSize : &CCVSiSize, + DEVmodSize : &CCVSmSize + +}; + + +SPICEdev * +get_ccvs_info(void) +{ + return &CCVSinfo; +} diff --git a/src/spicelib/devices/ccvs/ccvsinit.h b/src/spicelib/devices/ccvs/ccvsinit.h new file mode 100644 index 000000000..59a0299ad --- /dev/null +++ b/src/spicelib/devices/ccvs/ccvsinit.h @@ -0,0 +1,11 @@ +#ifndef _CCVSINIT_H +#define _CCVSINIT_H + +extern IFparm CCVSpTable[ ]; +extern char *CCVSnames[ ]; +extern int CCVSpTSize; +extern int CCVSnSize; +extern int CCVSiSize; +extern int CCVSmSize; + +#endif 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/cktaccept.c b/src/spicelib/devices/cktaccept.c new file mode 100644 index 000000000..558fc6b67 --- /dev/null +++ b/src/spicelib/devices/cktaccept.c @@ -0,0 +1,52 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +/* CKTaccept(ckt) + * + * this is a driver program to iterate through all the various accept + * functions provided for the circuit elements in the given circuit */ + +#include +#include +#include +#include +#include + +#include "dev.h" + +int +CKTaccept(CKTcircuit *ckt) +{ + int i; + int error; + SPICEdev **devs; + +#ifdef PREDICTOR + double *temp; + int size; +#endif + + devs = devices(); + for (i = 0; i < DEVmaxnum; i++) { + if ( ((*devs[i]).DEVaccept != NULL) && (ckt->CKThead[i] != NULL) ){ + error = (*((*devs[i]).DEVaccept))(ckt,ckt->CKThead[i]); + if (error) + return(error); + } + } +#ifdef PREDICTOR + /* now, move the sols vectors around */ + temp = ckt->CKTsols[7]; + for ( i=7;i>0;i--) { + ckt->CKTsols[i] = ckt->CKTsols[i-1]; + } + ckt->CKTsols[0]=temp; + size = SMPmatSize(ckt->CKTmatrix); + for(i=0;i<=size;i++) { + ckt->CKTsols[0][i]=ckt->CKTrhs[i]; + } +#endif /* PREDICTOR */ + return(OK); +} diff --git a/src/spicelib/devices/cktaccept.h b/src/spicelib/devices/cktaccept.h new file mode 100644 index 000000000..c68be5601 --- /dev/null +++ b/src/spicelib/devices/cktaccept.h @@ -0,0 +1,6 @@ +#ifndef _CKTACCEPT_H +#define _CKTACCEPT_H + +int CKTaccept(CKTcircuit *ckt); + +#endif diff --git a/src/spicelib/devices/cktask.c b/src/spicelib/devices/cktask.c new file mode 100644 index 000000000..c645fc986 --- /dev/null +++ b/src/spicelib/devices/cktask.c @@ -0,0 +1,45 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +/* CKTask + * + * Ask questions about a specified device. */ + +#include +#include +#include + +#include "dev.h" + + +int +CKTask(void *ckt, void *fast, int which, IFvalue *value, IFvalue *selector) +{ + GENinstance *instance = (GENinstance *) fast; + int type = instance->GENmodPtr->GENmodType; + int error; +#ifdef PARALLEL_ARCH + long msgtype, length; + long from = instance->GENowner; +#endif /* PARALLEL_ARCH */ + SPICEdev **DEVices; + + DEVices = devices(); + if((*DEVices[type]).DEVask) { + error = DEVices[type]->DEVask((CKTcircuit *)ckt, + (GENinstance *)fast,which,value,selector); + } else { + error = E_BADPARM; + } +#ifdef PARALLEL_ARCH + msgtype = MT_ASK; + length = sizeof(IFvalue); + BRDCST_(&msgtype, (char *)value, &length, &from); + msgtype++; + length = sizeof(int); + BRDCST_(&msgtype, (char *)&error, &length, &from); +#endif /* PARALLEL_ARCH */ + return(error); +} diff --git a/src/spicelib/devices/cktbindnode.c b/src/spicelib/devices/cktbindnode.c new file mode 100644 index 000000000..5b9e2c7d1 --- /dev/null +++ b/src/spicelib/devices/cktbindnode.c @@ -0,0 +1,59 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +/* CKTbindNode + * + * bind a node of the specified device of the given type to its place + * in the specified circuit. */ + +#include +#include +#include +#include + +#include "dev.h" + +int +CKTbindNode(void *ckt, void *fast, int term, void *node) +{ + int mappednode; + SPICEdev **devs; + GENinstance *instance = (GENinstance *) fast; + int type = instance->GENmodPtr->GENmodType; + + devs = devices(); + mappednode = ((CKTnode *)node)->number; + + if (*((*devs[type]).DEVpublic.terms) >= term && term >0 ) { + switch(term) { + default: + return E_NOTERM; + case 1: + instance->GENnode1 = mappednode; + break; + case 2: + instance->GENnode2 = mappednode; + break; + case 3: + instance->GENnode3 = mappednode; + break; + case 4: + instance->GENnode4 = mappednode; + break; + case 5: + instance->GENnode5 = mappednode; + break; + case 6:/* added to consider the body node 01/06/99 */ + instance->GENnode6 = mappednode; + break; + case 7:/* added to consider the temp node 02/03/99 */ + instance->GENnode7 = mappednode; + break; + } + return OK; + } else { + return E_NOTERM; + } +} diff --git a/src/spicelib/devices/cktcrte.c b/src/spicelib/devices/cktcrte.c new file mode 100644 index 000000000..7afd64893 --- /dev/null +++ b/src/spicelib/devices/cktcrte.c @@ -0,0 +1,53 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +/* CKTcrtElement(ckt,type,inModPtr,inInstPtr,name,subname) + * + * Create a device of the specified type, with the given name, using + * the specified model in the named circuit. */ + +#include +#include +#include + +#include "dev.h" + +int +CKTcrtElt(void *ckt, void *inModPtr, void **inInstPtr, IFuid name) +{ + GENinstance *instPtr = NULL; + GENmodel *modPtr=(GENmodel*)inModPtr; + SPICEdev **DEVices; + int error; + int type; + + DEVices = devices(); + if((GENmodel *)modPtr==(GENmodel*)NULL) + return E_NOMOD; + type = ((GENmodel*)modPtr)->GENmodType; + + error = CKTfndDev(ckt, &type, (void**)&instPtr, name, inModPtr, + (char *)NULL ); + if (error == OK) { + if (inInstPtr) + *inInstPtr=(void *)instPtr; + return E_EXISTS; + } else if (error != E_NODEV) + return error; + + instPtr = (GENinstance *) tmalloc(*DEVices[type]->DEVinstSize); + if (instPtr == (GENinstance *)NULL) + return E_NOMEM; + + instPtr->GENname = name; + instPtr->GENmodPtr = modPtr; + instPtr->GENnextInstance = modPtr->GENinstances; + modPtr->GENinstances = instPtr; + + if(inInstPtr != NULL) + *inInstPtr = (void *)instPtr; + + return OK; +} diff --git a/src/spicelib/devices/cktfinddev.c b/src/spicelib/devices/cktfinddev.c new file mode 100644 index 000000000..66b29eb64 --- /dev/null +++ b/src/spicelib/devices/cktfinddev.c @@ -0,0 +1,97 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include +#include +#include + + +int +CKTfndDev(void *Ckt, int *type, void **fast, IFuid name, void *modfast, IFuid modname) +{ + CKTcircuit *ckt=(CKTcircuit *)Ckt; + GENinstance *here; + GENmodel *mods; + + if((GENinstance **)fast != (GENinstance **)NULL && + *(GENinstance **)fast != (GENinstance *)NULL) { + /* already have fast, so nothing much to do just get & set + type */ + if (type) + *type = (*((GENinstance**)fast))->GENmodPtr->GENmodType; + return(OK); + } + + if(modfast) { + /* have model, just need device */ + mods = (GENmodel*)modfast; + for (here = mods->GENinstances; + here != NULL; + here = here->GENnextInstance) { + if (here->GENname == name) { + if (fast != NULL) + *(GENinstance **)fast = here; + + if (type) + *type = mods->GENmodType; + + return OK; + } + } + return E_NODEV; + } + + if (*type >= 0 && *type < DEVmaxnum) { + /* have device type, need to find model & device */ + /* look through all models */ + for (mods = (GENmodel *)ckt->CKThead[*type]; + mods != NULL ; + mods = mods->GENnextModel) { + /* and all instances */ + if (modname == (char *)NULL || mods->GENmodName == modname) { + for (here = mods->GENinstances; + here != NULL; + here = here->GENnextInstance) { + if (here->GENname == name) { + if (fast != 0) + *(GENinstance **)fast = here; + return OK; + } + } + if(mods->GENmodName == modname) { + return E_NODEV; + } + } + } + return E_NOMOD; + } else if (*type == -1) { + /* look through all types (UGH - worst case - take forever) */ + for(*type = 0; *type < DEVmaxnum; (*type)++) { + /* need to find model & device */ + /* look through all models */ + for(mods=(GENmodel *)ckt->CKThead[*type];mods!=NULL; + mods = mods->GENnextModel) { + /* and all instances */ + if(modname == (char *)NULL || mods->GENmodName == modname) { + for (here = mods->GENinstances; + here != NULL; + here = here->GENnextInstance) { + if (here->GENname == name) { + if(fast != 0) + *(GENinstance **)fast = here; + return OK; + } + } + if(mods->GENmodName == modname) { + return E_NODEV; + } + } + } + } + *type = -1; + return E_NODEV; + } else + return E_BADPARM; +} diff --git a/src/spicelib/devices/cktinit.c b/src/spicelib/devices/cktinit.c new file mode 100644 index 000000000..bfd7d966a --- /dev/null +++ b/src/spicelib/devices/cktinit.c @@ -0,0 +1,126 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modifed: 2000 AlansFixes +**********/ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#ifdef XSPICE +/* gtri - add - wbk - 11/26/90 - add include for MIF global data */ +#include "mif.h" +/* gtri - end - wbk - 11/26/90 */ +#endif + +int +CKTinit(void **ckt) /* new circuit to create */ +{ + extern void load_alldevs(void); + int i; + CKTcircuit *sckt; + *ckt = (void *) tmalloc(sizeof(CKTcircuit)); + sckt = (CKTcircuit *)(*ckt); + if (sckt == NULL) + return(E_NOMEM); +/* gtri - begin - dynamically allocate the array of model lists */ +/* CKThead used to be statically sized in CKTdefs.h, but has been changed */ +/* to a ** pointer */ + (sckt)->CKThead = (GENmodel **)MALLOC(DEVmaxnum * sizeof(GENmodel *)); + if((sckt)->CKThead == NULL) return(E_NOMEM); +/* gtri - end - dynamically allocate the array of model lists */ + + + + for (i = 0; i < DEVmaxnum; i++) + sckt->CKThead[i] = (GENmodel *) NULL; + + sckt->CKTmaxEqNum = 1; + sckt->CKTnodes = (CKTnode *) NULL; + sckt->CKTlastNode = (CKTnode *) NULL; + sckt->CKTmatrix = NULL; + + sckt->CKTgmin = 1e-12; + sckt->CKTgshunt=0; + sckt->CKTabstol = 1e-12; + sckt->CKTreltol = 1e-3; + sckt->CKTchgtol = 1e-14; + sckt->CKTvoltTol = 1e-6; + sckt->CKTtrtol = 7; + sckt->CKTbypass = 0; + sckt->CKTisSetup = 0; + sckt->CKTtranMaxIter = 10; + sckt->CKTdcMaxIter = 100; + sckt->CKTdcTrcvMaxIter = 50; + sckt->CKTintegrateMethod = TRAPEZOIDAL; + sckt->CKTorder = 1; + sckt->CKTmaxOrder = 2; + sckt->CKTpivotAbsTol = 1e-13; + sckt->CKTpivotRelTol = 1e-3; + sckt->CKTtemp = 300.15; + sckt->CKTnomTemp = 300.15; + sckt->CKTdefaultMosM = 1; + sckt->CKTdefaultMosL = 1e-4; + sckt->CKTdefaultMosW = 1e-4; + sckt->CKTdefaultMosAD = 0; + sckt->CKTdefaultMosAS = 0; + sckt->CKTsrcFact=1; + sckt->CKTdiagGmin=0; + sckt->CKTstat = (STATistics *) tmalloc(sizeof(STATistics)); + sckt->CKTtroubleNode = 0; + sckt->CKTtroubleElt = NULL; + sckt->CKTtimePoints = NULL; + if (sckt->CKTstat == (STATistics *)NULL) + return E_NOMEM; + sckt->CKTnodeDamping = 0; + sckt->CKTabsDv = 0.5; + sckt->CKTrelDv = 2.0; + +#ifdef XSPICE +/* gtri - begin - wbk - allocate/initialize substructs */ + + /* Allocate evt data structure */ + (sckt)->evt = (void *) MALLOC(sizeof(Evt_Ckt_Data_t)); + if(! (sckt)->evt) + return(E_NOMEM); + + /* Initialize options data */ + (sckt)->evt->options.op_alternate = MIF_TRUE; + + /* Allocate enh data structure */ + (sckt)->enh = (void *) MALLOC(sizeof(Enh_Ckt_Data_t)); + if(! (sckt)->enh) + return(E_NOMEM); + + /* Initialize non-zero, non-NULL data */ + (sckt)->enh->breakpoint.current = 1.0e30; + (sckt)->enh->breakpoint.last = 1.0e30; + (sckt)->enh->ramp.ramptime = 0.0; + (sckt)->enh->conv_limit.enabled = MIF_TRUE; + (sckt)->enh->conv_limit.step = 0.25; + (sckt)->enh->conv_limit.abs_step = 0.1; + (sckt)->enh->rshunt_data.enabled = MIF_FALSE; + +/* gtri - end - wbk - allocate/initialize substructs */ + +/* gtri - add - wbk - 01/12/91 - initialize g_mif_info */ + g_mif_info.circuit.init = MIF_TRUE; + g_mif_info.circuit.anal_init = MIF_TRUE; + g_mif_info.circuit.anal_type = MIF_DC; + g_mif_info.instance = NULL; + g_mif_info.ckt = sckt; + g_mif_info.errmsg = NULL; + g_mif_info.auto_partial.global = MIF_FALSE; + g_mif_info.auto_partial.local = MIF_FALSE; +/* gtri - end - wbk - 01/12/91 */ +#endif + return OK; +} diff --git a/src/spicelib/devices/cpl/Makefile.am b/src/spicelib/devices/cpl/Makefile.am new file mode 100755 index 000000000..28161c144 --- /dev/null +++ b/src/spicelib/devices/cpl/Makefile.am @@ -0,0 +1,18 @@ +## Process this file with automake to produce Makefile.in + +pkglib_LTLIBRARIES = libcpl.la + +libcpl_la_SOURCES = \ + cpl.c \ + cpldest.c \ + cplmdel.c \ + cplparam.c \ + cpldel.c \ + cplload.c \ + cplmpar.c \ + cplsetup.c \ + cplinit.c + +INCLUDES = -I$(top_srcdir)/src/include + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/cpl/cpl.c b/src/spicelib/devices/cpl/cpl.c new file mode 100644 index 000000000..4bb1aaf46 --- /dev/null +++ b/src/spicelib/devices/cpl/cpl.c @@ -0,0 +1,39 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + +#include "ngspice.h" +#include +#include "cpldefs.h" +#include "devdefs.h" +#include "ifsim.h" +#include "suffix.h" + +IFparm CPLpTable[] = { + IOP("pos_nodes", CPL_POS_NODE, IF_VECTOR|IF_STRING, "in nodes"), + IOP("neg_nodes", CPL_NEG_NODE, IF_VECTOR|IF_STRING, "out nodes"), + IOP("dimension", CPL_DIM, IF_INTEGER, "number of coupled lines"), + IOP("length", CPL_LENGTH, IF_REAL, "length of lines"), +}; + +IFparm CPLmPTable[] = { /* model parameters */ + IOP( "r", CPL_R, IF_REALVEC,"resistance per length"), + IOP( "l", CPL_L, IF_REALVEC,"inductance per length"), + IOP( "c", CPL_C, IF_REALVEC,"capacitance per length"), + IOP( "g", CPL_G, IF_REALVEC,"conductance per length"), + IOP( "length", CPL_length, IF_REAL,"length"), + IP( "cpl", CPL_MOD_R, IF_FLAG,"Device is a cpl model"), +}; + +char *CPLnames[] = { + "P+", + "P-" +}; + +int CPLnSize = NUMELEMS(CPLnames); +int CPLiSize = sizeof(CPLinstance); +int CPLmSize = sizeof(CPLmodel); +int CPLmPTSize = NUMELEMS(CPLmPTable); +int CPLpTSize = NUMELEMS(CPLpTable); diff --git a/src/spicelib/devices/cpl/cpldefs.h b/src/spicelib/devices/cpl/cpldefs.h new file mode 100644 index 000000000..81aa5a0b3 --- /dev/null +++ b/src/spicelib/devices/cpl/cpldefs.h @@ -0,0 +1,97 @@ +#ifndef CPL +#define CPL + +#include "ifsim.h" +#include "cktdefs.h" +#include "gendefs.h" +#include "complex.h" +#include "noisedef.h" +#include "swec.h" + +/* information used to describe a single instance */ + +typedef struct sCPLinstance { + struct sCPLmodel *CPLmodPtr; /* backpointer to model */ + struct sCPLinstance *CPLnextInstance; /* pointer to next instance of + * current model*/ + + IFuid CPLname; /* pointer to character string naming this instance */ + + int dimension; + int *CPLposNodes; + int *CPLnegNodes; + double CPLlength; + int *CPLibr1; + int *CPLibr2; + CPLine *cplines; /* pointer to SWEC cplines type */ + CPLine *cplines2; /* temporary pointer to SWEC cplines type */ + + char **in_node_names; + char **out_node_names; + + double **CPLibr1Ibr1; + double **CPLibr2Ibr2; + double **CPLposIbr1; + double **CPLnegIbr2; + /* trial */ + double **CPLposPos; + double **CPLnegNeg; + double **CPLposNeg; + double **CPLnegPos; + + double ***CPLibr1Pos; + double ***CPLibr2Neg; + double ***CPLibr1Neg; + double ***CPLibr2Pos; + double ***CPLibr1Ibr2; + double ***CPLibr2Ibr1; + + unsigned CPLibr1Given : 1; + unsigned CPLibr2Given : 1; + unsigned CPLdcGiven : 1; + unsigned CPLlengthgiven : 1; + +} CPLinstance ; + + +/* per model data */ + +typedef struct sCPLmodel { /* model structure for a cpl */ + int CPLmodType; /* type index of this device type */ + struct sCPLmodel *CPLnextModel; /* pointer to next possible model in + * linked list */ + CPLinstance * CPLinstances; /* pointer to list of instances that have this + * model */ + IFuid CPLmodName; /* pointer to character string naming this model */ + + double *Rm; + double *Gm; + double *Lm; + double *Cm; + double length; + unsigned Rmgiven : 1; + unsigned Lmgiven : 1; + unsigned Gmgiven : 1; + unsigned Cmgiven : 1; + unsigned lengthgiven : 1; + +} CPLmodel; + +/* instance parameters */ +#define CPL_POS_NODE 1 +#define CPL_NEG_NODE 2 +#define CPL_DIM 3 +#define CPL_LENGTH 4 + +/* model parameters */ +#define CPL_R 101 +#define CPL_C 102 +#define CPL_G 103 +#define CPL_L 104 +#define CPL_length 105 +#define CPL_MOD_R 106 + +#include "cplext.h" +extern VI_list *pool_vi; + +#endif /*CPL*/ diff --git a/src/spicelib/devices/cpl/cpldel.c b/src/spicelib/devices/cpl/cpldel.c new file mode 100644 index 000000000..746811eaf --- /dev/null +++ b/src/spicelib/devices/cpl/cpldel.c @@ -0,0 +1,38 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + + +#include "ngspice.h" +#include +#include "cpldefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +CPLdelete(inModel,name,inst) + GENmodel *inModel; + IFuid name; + GENinstance **inst; +{ + CPLmodel *model = (CPLmodel *)inModel; + CPLinstance **fast = (CPLinstance **)inst; + CPLinstance **prev = NULL; + CPLinstance *here; + + for( ; model ; model = model->CPLnextModel) { + prev = &(model->CPLinstances); + for(here = *prev; here ; here = *prev) { + if(here->CPLname == name || (fast && here==*fast) ) { + *prev= here->CPLnextInstance; + FREE(here); + return(OK); + } + prev = &(here->CPLnextInstance); + } + } + return(E_NODEV); +} diff --git a/src/spicelib/devices/cpl/cpldest.c b/src/spicelib/devices/cpl/cpldest.c new file mode 100644 index 000000000..e0c6b46f6 --- /dev/null +++ b/src/spicelib/devices/cpl/cpldest.c @@ -0,0 +1,34 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + +#include "ngspice.h" +#include +#include "cpldefs.h" +#include "suffix.h" + +void +CPLdestroy(inModel) + GENmodel **inModel; +{ + CPLmodel **model = (CPLmodel **)inModel; + CPLinstance *here; + CPLinstance *prev = NULL; + CPLmodel *mod = *model; + CPLmodel *oldmod = NULL; + + for( ; mod ; mod = mod->CPLnextModel) { + if(oldmod) FREE(oldmod); + oldmod = mod; + prev = (CPLinstance *)NULL; + for(here = mod->CPLinstances ; here ; here = here->CPLnextInstance) { + if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + } + if(oldmod) FREE(oldmod); + *model = NULL; +} diff --git a/src/spicelib/devices/cpl/cplext.h b/src/spicelib/devices/cpl/cplext.h new file mode 100644 index 000000000..bc96eb61b --- /dev/null +++ b/src/spicelib/devices/cpl/cplext.h @@ -0,0 +1,19 @@ +#ifdef __STDC__ +/* extern int CPLaccept(CKTcircuit*,GENmodel*); */ +extern int CPLdelete(GENmodel*,IFuid,GENinstance**); +extern void CPLdestroy(GENmodel**); +extern int CPLload(GENmodel*,CKTcircuit*); +extern int CPLmDelete(GENmodel**,IFuid,GENmodel*); +extern int CPLmParam(int,IFvalue*,GENmodel*); +extern int CPLparam(int,IFvalue*,GENinstance*,IFvalue*); +extern int CPLsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); +#else /* stdc */ +/* extern int CPLaccept(); */ +extern int CPLdelete(); +extern void CPLdestroy(); +extern int CPLload(); +extern int CPLmDelete(); +extern int CPLmParam(); +extern int CPLparam(); +extern int CPLsetup(); +#endif /* stdc */ diff --git a/src/spicelib/devices/cpl/cplinit.c b/src/spicelib/devices/cpl/cplinit.c new file mode 100644 index 000000000..8e45b21f0 --- /dev/null +++ b/src/spicelib/devices/cpl/cplinit.c @@ -0,0 +1,68 @@ +#include + +#include + +#include "cplitf.h" +#include "cplext.h" +#include "cplinit.h" + +SPICEdev CPLinfo = { + { + "CplLines", + "Simple Coupled Multiconductor Lines", + + &CPLnSize, + &CPLnSize, + CPLnames, + + &CPLpTSize, + CPLpTable, + + &CPLmPTSize, + CPLmPTable, + 0 + }, + + CPLparam, + CPLmParam, + CPLload, + CPLsetup, + NULL, + NULL, + NULL, + NULL, + NULL, /* CPLfindBranch, */ + NULL, + NULL, + CPLdestroy, +#ifdef DELETES + CPLmDelete, + CPLdelete, +#else /* DELETES */ + NULL, + NULL, +#endif /* DELETES */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + &CPLiSize, + &CPLmSize + +}; + +SPICEdev * +get_cpl_info(void) +{ + return &CPLinfo; +} diff --git a/src/spicelib/devices/cpl/cplinit.h b/src/spicelib/devices/cpl/cplinit.h new file mode 100644 index 000000000..17f4a5b24 --- /dev/null +++ b/src/spicelib/devices/cpl/cplinit.h @@ -0,0 +1,13 @@ +#ifndef _CPLINIT_H +#define _CPLINIT_H + +extern IFparm CPLpTable[ ]; +extern IFparm CPLmPTable[ ]; +extern int CPLmPTSize; +extern int CPLpTSize; +extern char *CPLnames[ ]; +extern int CPLiSize; +extern int CPLmSize; +extern int CPLnSize; + +#endif diff --git a/src/spicelib/devices/cpl/cplitf.h b/src/spicelib/devices/cpl/cplitf.h new file mode 100644 index 000000000..4a690f024 --- /dev/null +++ b/src/spicelib/devices/cpl/cplitf.h @@ -0,0 +1,6 @@ +#ifndef DEV_CPL +#define DEV_CPL + +SPICEdev *get_cpl_info(void); + +#endif diff --git a/src/spicelib/devices/cpl/cplload.c b/src/spicelib/devices/cpl/cplload.c new file mode 100644 index 000000000..5b502fe5e --- /dev/null +++ b/src/spicelib/devices/cpl/cplload.c @@ -0,0 +1,890 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + + +#include "ngspice.h" +#include +#include "cpldefs.h" +#include "sperror.h" +#include "suffix.h" + +VI_list *pool_vi; +static double ratio[MAX_CP_TX_LINES]; +static VI_list *new_vi(); +static void free_vi(); +static int get_pvs_vi(); +static int update_cnv(); +static int add_new_vi(); +static int right_consts(); +static int update_delayed_cnv(); +static int multC(); +static int expC(); +static int divC(); +static void update_cnv_a(); +static void copy_cp(); + + +/*ARGSUSED*/ +int +CPLload(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + register CPLmodel *model = (CPLmodel *)inModel; + register CPLinstance *here; + CPLine *cp, *cp2; + int *k, *l; + int time, time2; + double h, h1, f; + int hint; + float hf; + NODE *nd; + double v, v1, g; + int cond1, i; + int noL, m, p, q; + CKTnode *node; + VI_list *vi, *vi_before; + int before, delta; + int resindex; + + + h = ckt->CKTdelta; + h1 = 0.5 * h; + time2 = (int) (ckt->CKTtime * 1e12); + hint = (int)(h * 1e12); + hf = (float)(h * 1e12); + time = (int) ((ckt->CKTtime - ckt->CKTdelta) * 1e12); + + cond1= ckt->CKTmode & MODEDC; + + for( ; model != NULL; model = model->CPLnextModel ) { + for (here = model->CPLinstances; here != NULL ; + here=here->CPLnextInstance) { + + cp = here->cplines; + if (cond1 || cp->vi_head == NULL) continue; + + noL = cp->noL = here->dimension; + if (cp->vi_tail->time > time) { + time = cp->vi_tail->time; + hint = time2 - time; + } + + before = cp->vi_tail->time; + vi_before = cp->vi_tail; + + if (time > cp->vi_tail->time) { + + copy_cp(cp, here->cplines2); + add_new_vi(here, ckt, time); + delta = time - before; + + for (m = 0; m < noL; m++) { + nd = cp->in_node[m]; + v = vi_before->v_i[m]; + v1 = nd->V = cp->vi_tail->v_i[m]; + nd->dv = (v1 - v) / delta; + } + for (m = 0; m < noL; m++) { + nd = cp->out_node[m]; + v = vi_before->v_o[m]; + v1 = nd->V = cp->vi_tail->v_o[m]; + nd->dv = (v1 - v) / delta; + } + + update_cnv(cp, (float)delta); + if (cp->ext) update_delayed_cnv(cp, (float)delta); + } + } + } + + model = (CPLmodel *)inModel; + /* loop through all the models */ + for( ; model != NULL; model = model->CPLnextModel ) { + + /* loop through all the instances of the model */ + for (here = model->CPLinstances; here != NULL ; + here=here->CPLnextInstance) { + + double mintaul = 123456789.0; + + cp = here->cplines; + cp2 = here->cplines2; + + for (i = 0; i < cp->noL; i++) { + if (mintaul > cp->taul[i]) mintaul = cp->taul[i]; + } + if (mintaul < hf) { + + fprintf(stderr, "your time step is too large for tau.\n"); + fprintf(stderr, "please decrease max time step in .tran card.\n"); + fprintf(stderr, ".tran tstep tstop tstart tmax.\n"); + fprintf(stderr, "make tmax smaller than %e and try again.\n", + mintaul * 1e-12); + + return (1111); + + } + + noL = cp->noL = here->dimension; + if (cond1) { + resindex = 0; + for (m = 0; m < noL; m++) { + if (here->CPLlengthgiven) + g = model->Rm[resindex] * here->CPLlength; + else g = model->Rm[resindex] * here->CPLmodPtr->length; + *(here->CPLposIbr1[m]) += 1.0; + *(here->CPLnegIbr2[m]) += 1.0; + *(here->CPLibr1Ibr1[m]) += 1.0; + *(here->CPLibr1Ibr2[m][m]) += 1.0; + *(here->CPLibr2Pos[m][m]) += 1.0; + *(here->CPLibr2Neg[m][m]) -= 1.0; + *(here->CPLibr2Ibr1[m][m]) -= g; + resindex = resindex + noL - m; + } + continue; + } + + /* dc setup */ + if (here->CPLdcGiven == 0 && !cond1) { + for (i = 0; i < cp->noL; i++) { + nd = cp->in_node[i]; + for(node = ckt->CKTnodes;node; node = node->next) { + if (strcmp(nd->name->id, node->name) == 0) { + cp->dc1[i] = ckt->CKTrhsOld[node->number]; + cp2->dc1[i] = nd->V = cp->dc1[i]; + break; + } + } + nd = cp->out_node[i]; + for(node = ckt->CKTnodes;node; node = node->next) { + if (strcmp(nd->name->id, node->name) == 0) { + cp->dc2[i] = ckt->CKTrhsOld[node->number]; + cp2->dc2[i] = nd->V = cp->dc2[i]; + break; + } + } + } + here->CPLdcGiven = 1; + + vi = new_vi(); + vi->time = 0; + { + int i, j, k, l; + for (i = 0; i < cp->noL; i++) { + for (j = 0; j < cp->noL; j++) { + TMS *tms; + double a, b; + + tms = cp->h1t[i][j]; + if (tms->ifImg) { + tms->tm[0].cnv_i = - cp->dc1[j] * + tms->tm[0].c / tms->tm[0].x; + tms->tm[0].cnv_o = - cp->dc2[j] * + tms->tm[0].c / tms->tm[0].x; + divC(tms->tm[1].c, tms->tm[2].c, + tms->tm[1].x, tms->tm[2].x, &a, &b); + tms->tm[1].cnv_i = - cp->dc1[j] * a; + tms->tm[1].cnv_o = - cp->dc2[j] * a; + tms->tm[2].cnv_i = - cp->dc1[j] * b; + tms->tm[2].cnv_o = - cp->dc2[j] * b; + } else + for (k = 0; k < 3; k++) { + tms->tm[k].cnv_i = - cp->dc1[j] * + tms->tm[k].c / tms->tm[k].x; + tms->tm[k].cnv_o = - cp->dc2[j] * + tms->tm[k].c / tms->tm[k].x; + } + + for (l = 0; l < cp->noL; l++) { + tms = cp->h2t[i][j][l]; + for (k = 0; k < 3; k++) { + tms->tm[k].cnv_i = 0.0; + tms->tm[k].cnv_o = 0.0; + } + } + for (l = 0; l < cp->noL; l++) { + tms = cp->h3t[i][j][l]; + if (tms->ifImg) { + tms->tm[0].cnv_i = - cp->dc1[j] * + tms->tm[0].c / tms->tm[0].x; + tms->tm[0].cnv_o = - cp->dc2[j] * + tms->tm[0].c / tms->tm[0].x; + divC(tms->tm[1].c, tms->tm[2].c, + tms->tm[1].x, tms->tm[2].x, &a, &b); + tms->tm[1].cnv_i = - cp->dc1[j] * a; + tms->tm[1].cnv_o = - cp->dc2[j] * a; + tms->tm[2].cnv_i = - cp->dc1[j] * b; + tms->tm[2].cnv_o = - cp->dc2[j] * b; + } else + for (k = 0; k < 3; k++) { + tms->tm[k].cnv_i = - cp->dc1[j] * + tms->tm[k].c / tms->tm[k].x; + tms->tm[k].cnv_o = - cp->dc2[j] * + tms->tm[k].c / tms->tm[k].x; + } + } + } + + for (i = 0; i < cp->noL; i++) { + vi->i_i[i] = vi->i_o[i] = 0.0; + vi->v_i[i] = cp->dc1[i]; + vi->v_o[i] = cp->dc2[i]; + } + } + + vi->next = NULL; + cp->vi_tail = vi; + cp->vi_head = vi; + cp2->vi_tail = vi; + cp2->vi_head = vi; + + } + } + + for (m = 0; m < noL; m++) { + *(here->CPLibr1Ibr1[m]) = -1.0; + *(here->CPLibr2Ibr2[m]) = -1.0; + } + + for (m = 0; m < noL; m++) { + *(here->CPLposIbr1[m]) = 1.0; + *(here->CPLnegIbr2[m]) = 1.0; + } + + for (m = 0; m < noL; m++) { + for (p = 0; p < noL; p++) { + *(here->CPLibr1Pos[m][p]) = + cp->h1t[m][p]->aten + h1 * cp->h1C[m][p]; + *(here->CPLibr2Neg[m][p]) = + cp->h1t[m][p]->aten + h1 * cp->h1C[m][p]; + } + } + + k = here->CPLibr1; + l = here->CPLibr2; + + copy_cp(cp2, cp); + + if (right_consts(here,cp2, time,time2,h,h1,k,l,ckt)) { + cp2->ext = 1; + for (q = 0; q < noL; q++) { + cp->ratio[q] = ratio[q]; + if (ratio[q] > 0.0) { + for (m = 0; m < noL; m++) { + for (p = 0; p < noL; p++) { + + + if (cp->h3t[m][p][q]) { + f = ratio[q] * (h1 * cp->h3C[m][p][q] + + cp->h3t[m][p][q]->aten); + *(here->CPLibr1Neg[m][p]) = -f; + *(here->CPLibr2Pos[m][p]) = -f; + } + if (cp->h2t[m][p][q]) { + f = ratio[q] * (h1 * cp->h2C[m][p][q] + + cp->h2t[m][p][q]->aten); + *(here->CPLibr1Ibr2[m][p]) = -f; + *(here->CPLibr2Ibr1[m][p]) = -f; + } + + } + } + } + } + } + else cp->ext = 0; + } + } + + return(OK); +} + +static void +copy_cp(new, old) +CPLine *new, *old; +{ + int i, j, k, l, m; + VI_list *temp; + + new->noL = m = old->noL; + new->ext = old->ext; + for (i = 0; i < m; i++) { + new->ratio[i] = old->ratio[i]; + new->taul[i] = old->taul[i]; + + for (j = 0; j < m; j++) { + if (new->h1t[i][j] == NULL) + new->h1t[i][j] = (TMS *) malloc(sizeof (TMS)); + new->h1t[i][j]->ifImg = old->h1t[i][j]->ifImg; + new->h1t[i][j]->aten = old->h1t[i][j]->aten; + new->h1C[i][j] = old->h1C[i][j]; + + for (k = 0; k < 3; k++) { + new->h1t[i][j]->tm[k].c = old->h1t[i][j]->tm[k].c; + new->h1t[i][j]->tm[k].x = old->h1t[i][j]->tm[k].x; + new->h1t[i][j]->tm[k].cnv_i = old->h1t[i][j]->tm[k].cnv_i; + new->h1t[i][j]->tm[k].cnv_o = old->h1t[i][j]->tm[k].cnv_o; + new->h1e[i][j][k] = old->h1e[i][j][k]; + } + for (l = 0; l < m; l++) { + if (new->h2t[i][j][l] == NULL) + new->h2t[i][j][l] = (TMS *) malloc(sizeof (TMS)); + new->h2t[i][j][l]->ifImg = old->h2t[i][j][l]->ifImg; + new->h2t[i][j][l]->aten = old->h2t[i][j][l]->aten; + new->h2C[i][j][l] = old->h2C[i][j][l]; + new->h3C[i][j][l] = old->h3C[i][j][l]; + for (k = 0; k < 3; k++) { + new->h2t[i][j][l]->tm[k].c = old->h2t[i][j][l]->tm[k].c; + new->h2t[i][j][l]->tm[k].x = old->h2t[i][j][l]->tm[k].x; + new->h2t[i][j][l]->tm[k].cnv_i + = old->h2t[i][j][l]->tm[k].cnv_i; + new->h2t[i][j][l]->tm[k].cnv_o + = old->h2t[i][j][l]->tm[k].cnv_o; + } + + if (new->h3t[i][j][l] == NULL) + new->h3t[i][j][l] = (TMS *) malloc(sizeof (TMS)); + new->h3t[i][j][l]->ifImg = old->h3t[i][j][l]->ifImg; + new->h3t[i][j][l]->aten = old->h3t[i][j][l]->aten; + for (k = 0; k < 3; k++) { + new->h3t[i][j][l]->tm[k].c = old->h3t[i][j][l]->tm[k].c; + new->h3t[i][j][l]->tm[k].x = old->h3t[i][j][l]->tm[k].x; + new->h3t[i][j][l]->tm[k].cnv_i + = old->h3t[i][j][l]->tm[k].cnv_i; + new->h3t[i][j][l]->tm[k].cnv_o + = old->h3t[i][j][l]->tm[k].cnv_o; + } + } + } + } + + while (new->vi_head->time < old->vi_head->time) { + temp = new->vi_head; + new->vi_head = new->vi_head->next; + free_vi(temp); + } +} + + +static int +right_consts(here, cp, t, time, h, h1, l1, l2, ckt) +CPLinstance *here; +CPLine *cp; +int t, time; +double h, h1; +int *l1, *l2; +CKTcircuit *ckt; +{ + int i, j, k, l; + double e; + double ff[MAX_CP_TX_LINES], gg[MAX_CP_TX_LINES]; + double v1_i[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double v2_i[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double i1_i[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double i2_i[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double v1_o[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double v2_o[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double i1_o[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double i2_o[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + int ext; + register int noL; + + noL = cp->noL; + + for (j = 0; j < noL; j++) { + register double ff1; + + ff[j] = 0.0; + gg[j] = 0.0; + for (k = 0; k < noL; k++) + if (cp->h1t[j][k]) { + if (cp->h1t[j][k]->ifImg) { + double er, ei, a, b, a1, b1; + TMS *tms; + tms = cp->h1t[j][k]; + cp->h1e[j][k][0] = e = exp((double) tms->tm[0].x * h); + expC(tms->tm[1].x, tms->tm[2].x, h, &er, &ei); + cp->h1e[j][k][1] = er; + cp->h1e[j][k][2] = ei; + + ff1 = tms->tm[0].c * e * h1; + ff[j] -= tms->tm[0].cnv_i * e; + gg[j] -= tms->tm[0].cnv_o * e; + ff[j] -= ff1 * cp->in_node[k]->V; + gg[j] -= ff1 * cp->out_node[k]->V; + + multC(tms->tm[1].c, tms->tm[2].c, er, ei, &a1, &b1); + multC(tms->tm[1].cnv_i, tms->tm[2].cnv_i, er, ei, &a, &b); + ff[j] -= 2.0 * (a1 * h1 * cp->in_node[k]->V + a); + multC(tms->tm[1].cnv_o, tms->tm[2].cnv_o, er, ei, &a, &b); + gg[j] -= 2.0 * (a1 * h1 * cp->out_node[k]->V + a); + } else { + ff1 = 0.0; + for (i = 0; i < 3; i++) { + cp->h1e[j][k][i] = e = exp((double) cp->h1t[j][k]->tm[i].x * h); + ff1 -= cp->h1t[j][k]->tm[i].c * e; + ff[j] -= cp->h1t[j][k]->tm[i].cnv_i * e; + gg[j] -= cp->h1t[j][k]->tm[i].cnv_o * e; + } + ff[j] += ff1 * h1 * cp->in_node[k]->V; + gg[j] += ff1 * h1 * cp->out_node[k]->V; + } + } + } + + ext = get_pvs_vi(t, time, cp, v1_i, v2_i, i1_i, i2_i, + v1_o, v2_o, i1_o, i2_o); + + for (j = 0; j < noL; j++) { /** current eqn **/ + register TERM *tm; + + for (k = 0; k < noL; k++) /** node voltage **/ + for (l = 0; l < noL; l++) /** different mode **/ + if (cp->h3t[j][k][l]) { + if (cp->h3t[j][k][l]->ifImg) { + double er, ei, a, b, a1, b1, a2, b2; + register TMS *tms; + tms = cp->h3t[j][k][l]; + expC(tms->tm[1].x, tms->tm[2].x, h, &er, &ei); + a2 = h1 * tms->tm[1].c; + b2 = h1 * tms->tm[2].c; + a = tms->tm[1].cnv_i; + b = tms->tm[2].cnv_i; + multC(a, b, er, ei, &a, &b); + multC(a2, b2, (double) v1_i[l][k] * er + v2_i[l][k], (double) v1_i[l][k] * ei, &a1, &b1); + tms->tm[1].cnv_i = a + a1; + tms->tm[2].cnv_i = b + b1; + a = tms->tm[1].cnv_o; + b = tms->tm[2].cnv_o; + multC(a, b, er, ei, &a, &b); + multC(a2, b2, (double) v1_o[l][k] * er + v2_o[l][k], (double) v1_o[l][k] * ei, &a1, &b1); + tms->tm[1].cnv_o = a + a1; + tms->tm[2].cnv_o = b + b1; + tm = &(tms->tm[0]); + e = exp((double) tm->x * h); + tm->cnv_i = tm->cnv_i * e + h1 * tm->c * + (v1_i[l][k] * e + v2_i[l][k]); + tm->cnv_o = tm->cnv_o * e + h1 * tm->c * + (v1_o[l][k] * e + v2_o[l][k]); + ff[j] += tms->aten * v2_o[l][k] + tm->cnv_o + + 2.0 * tms->tm[1].cnv_o; + gg[j] += tms->aten * v2_i[l][k] + tm->cnv_i + + 2.0 * tms->tm[1].cnv_i; + } else { + for (i = 0; i < 3; i++) { /** 3 poles **/ + tm = &(cp->h3t[j][k][l]->tm[i]); + e = exp((double) tm->x * h); + tm->cnv_i = tm->cnv_i * e + h1 * tm->c * (v1_i[l][k] * e + v2_i[l][k]); + tm->cnv_o = tm->cnv_o * e + h1 * tm->c * (v1_o[l][k] * e + v2_o[l][k]); + ff[j] += tm->cnv_o; + gg[j] += tm->cnv_i; + } + + ff[j] += cp->h3t[j][k][l]->aten * v2_o[l][k]; + gg[j] += cp->h3t[j][k][l]->aten * v2_i[l][k]; + } + } + for (k = 0; k < noL; k++) /** line current **/ + for (l = 0; l < noL; l++) /** different mode **/ + if (cp->h2t[j][k][l]) { + if (cp->h2t[j][k][l]->ifImg) { + double er, ei, a, b, a1, b1, a2, b2; + register TMS *tms; + tms = cp->h2t[j][k][l]; + expC(tms->tm[1].x, tms->tm[2].x, h, &er, &ei); + a2 = h1 * tms->tm[1].c; + b2 = h1 * tms->tm[2].c; + a = tms->tm[1].cnv_i; + b = tms->tm[2].cnv_i; + multC(a, b, er, ei, &a, &b); + multC(a2, b2, (double) i1_i[l][k] * er + i2_i[l][k], (double) i1_i[l][k] * ei, &a1, &b1); + tms->tm[1].cnv_i = a + a1; + tms->tm[2].cnv_i = b + b1; + a = tms->tm[1].cnv_o; + b = tms->tm[2].cnv_o; + multC(a, b, er, ei, &a, &b); + multC(a2, b2, (double) i1_o[l][k] * er + i2_o[l][k], (double) i1_o[l][k] * ei, &a1, &b1); + tms->tm[1].cnv_o = a + a1; + tms->tm[2].cnv_o = b + b1; + tm = &(tms->tm[0]); + e = exp((double) tm->x * h); + tm->cnv_i = tm->cnv_i * e + h1 * tm->c * + (i1_i[l][k] * e + i2_i[l][k]); + tm->cnv_o = tm->cnv_o * e + h1 * tm->c * + (i1_o[l][k] * e + i2_o[l][k]); + ff[j] += tms->aten * i2_o[l][k] + tm->cnv_o + + 2.0 * tms->tm[1].cnv_o; + gg[j] += tms->aten * i2_i[l][k] + tm->cnv_i + + 2.0 * tms->tm[1].cnv_i; + } else { + for (i = 0; i < 3; i++) { /** 3 poles **/ + tm = &(cp->h2t[j][k][l]->tm[i]); + e = exp((double) tm->x * h); + tm->cnv_i = tm->cnv_i * e + h1 * tm->c * (i1_i[l][k] * e + i2_i[l][k]); + tm->cnv_o = tm->cnv_o * e + h1 * tm->c * (i1_o[l][k] * e + i2_o[l][k]); + ff[j] += tm->cnv_o; + gg[j] += tm->cnv_i; + } + + ff[j] += cp->h2t[j][k][l]->aten * i2_o[l][k]; + gg[j] += cp->h2t[j][k][l]->aten * i2_i[l][k]; + } + } + } + + for (i = 0; i < noL; i++) { + *(ckt->CKTrhs + l1[i]) = ff[i]; + *(ckt->CKTrhs + l2[i]) = gg[i]; + } + + return(ext); +} + +static int +update_cnv(cp, h) +CPLine *cp; +float h; +{ + int i, j, k; + register int noL; + double ai, bi, ao, bo; + double e, t; + register TMS *tms; + register TERM *tm; + + noL = cp->noL; + for (j = 0; j < noL; j++) + for (k = 0; k < noL; k++) { + ai = cp->in_node[k]->V; + ao = cp->out_node[k]->V; + bi = cp->in_node[k]->dv; + bo = cp->out_node[k]->dv; + + if (cp->h1t[j][k]) { + if (cp->h1t[j][k]->ifImg) { + tms = cp->h1t[j][k]; + if (tms == NULL) + continue; + tm = &(tms->tm[0]); + e = cp->h1e[j][k][0]; + t = tm->c / tm->x; + update_cnv_a(tms, h, ai, ao, ai - bi * h, ao - bo * h, + cp->h1e[j][k][1], cp->h1e[j][k][2]); + bi *= t; + bo *= t; + tm->cnv_i = (tm->cnv_i - bi*h) * e + (e - 1.0)*(ai*t + + 1.0e+12*bi/tm->x); + tm->cnv_o = (tm->cnv_o - bo*h) * e + (e - 1.0)*(ao*t + + 1.0e+12*bo/tm->x); + } else + for (i = 0; i < 3; i++) { + tm = &(cp->h1t[j][k]->tm[i]); + + e = cp->h1e[j][k][i]; + + t = tm->c / tm->x; + bi *= t; + bo *= t; + + tm->cnv_i = (tm->cnv_i - bi*h) * e + (e - 1.0)*(ai*t + 1.0e+12*bi/tm->x); + tm->cnv_o = (tm->cnv_o - bo*h) * e + (e - 1.0)*(ao*t + 1.0e+12*bo/tm->x); + } + } + } + return 0; +} + +static VI_list +*new_vi() +{ + VI_list *q; + + if (pool_vi) { + q = pool_vi; + pool_vi = pool_vi->pool; + return(q); + } else return((VI_list *) malloc (sizeof (VI_list))); +} + +static void +free_vi(q) +VI_list *q; +{ + q->pool = pool_vi; + pool_vi = q; +} + + +static int +add_new_vi(here, ckt, time) + CPLinstance *here; + CKTcircuit *ckt; + int time; +{ + VI_list *vi; + register int i, noL; + CPLine *cp, *cp2; + + cp = here->cplines; + cp2 = here->cplines2; + + vi = new_vi(); + vi->time = time; + noL = cp->noL; + for (i = 0; i < noL; i++) { + /* + vi->v_i[i] = cp->in_node[i]->V; + vi->v_o[i] = cp->out_node[i]->V; + */ + vi->v_i[i] = *(ckt->CKTrhsOld + here->CPLposNodes[i]); + vi->v_o[i] = *(ckt->CKTrhsOld + here->CPLnegNodes[i]); + vi->i_i[i] = *(ckt->CKTrhsOld + here->CPLibr1[i]); + vi->i_o[i] = *(ckt->CKTrhsOld + here->CPLibr2[i]); + } + cp->vi_tail->next = vi; + cp2->vi_tail->next = vi; + vi->next = NULL; + cp->vi_tail = vi; + cp2->vi_tail = vi; + + return(1); +} + + +static int +get_pvs_vi(t1, t2, cp, v1_i, v2_i, i1_i, i2_i, v1_o, v2_o, i1_o, i2_o) + CPLine *cp; + int t1, t2; + double v1_i[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double v2_i[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double i1_i[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double i2_i[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double v1_o[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double v2_o[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double i1_o[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; + double i2_o[MAX_CP_TX_LINES][MAX_CP_TX_LINES]; +{ + double ta[MAX_CP_TX_LINES], tb[MAX_CP_TX_LINES]; + register VI_list *vi, *vi1; + register double f; + register int i, j; + int mini = -1; + double minta = 123456789.0; + int ext = 0; + register int noL; + + noL = cp->noL; + + for (i = 0; i < noL; i++) { + ta[i] = t1 - cp->taul[i]; + tb[i] = t2 - cp->taul[i]; + if (ta[i] < minta) { + minta = ta[i]; + mini = i; + } + } + + for (i = 0; i < noL; i++) { + + ratio[i] = 0.0; + + if (tb[i] <= 0) { + for (j = 0; j < noL; j++) { + i1_i[i][j] = i2_i[i][j] = i1_o[i][j] = i2_o[i][j] = 0.0; + v1_i[i][j] = v2_i[i][j] = cp->dc1[j]; + v1_o[i][j] = v2_o[i][j] = cp->dc2[j]; + } + } else { + if (ta[i] <= 0) { + for (j = 0; j < noL; j++) { + i1_i[i][j] = i1_o[i][j] = 0.0; + v1_i[i][j] = cp->dc1[j]; + v1_o[i][j] = cp->dc2[j]; + } + vi1 = cp->vi_head; + vi = vi1->next; + } else { + vi1 = cp->vi_head; + for (vi = vi1->next; vi->time < ta[i]; ) { + /* if (i == mini) + free_vi(vi1); */ + vi1 = vi; + + /* new */ + vi = vi->next; + if (vi == NULL) goto errordetect; + } + f = (ta[i] - vi1->time) / (vi->time - vi1->time); + for (j = 0; j < noL; j++) { + v1_i[i][j] = vi1->v_i[j] + f * (vi->v_i[j] - vi1->v_i[j]); + v1_o[i][j] = vi1->v_o[j] + f * (vi->v_o[j] - vi1->v_o[j]); + i1_i[i][j] = vi1->i_i[j] + f * (vi->i_i[j] - vi1->i_i[j]); + i1_o[i][j] = vi1->i_o[j] + f * (vi->i_o[j] - vi1->i_o[j]); + } + if (i == mini) + cp->vi_head = vi1; + } + + if (tb[i] > t1) { + /* + fprintf(stderr, "pvs: time = %d\n", t2); + */ + ext = 1; + + ratio[i] = f = (tb[i] - t1) / (t2 - t1); + + if (vi) + for (; vi->next; vi = vi->next); + else + vi = vi1; + f = 1 - f; + for (j = 0; j < noL; j++) { + v2_i[i][j] = vi->v_i[j] * f; + v2_o[i][j] = vi->v_o[j] * f; + i2_i[i][j] = vi->i_i[j] * f; + i2_o[i][j] = vi->i_o[j] * f; + } + } else { + for (; vi->time < tb[i];) { + vi1 = vi; + + /* new */ + vi = vi->next; + if (vi == NULL) goto errordetect; + } + + f = (tb[i] - vi1->time) / (vi->time - vi1->time); + for (j = 0; j < noL; j++) { + v2_i[i][j] = vi1->v_i[j] + f * (vi->v_i[j] - vi1->v_i[j]); + v2_o[i][j] = vi1->v_o[j] + f * (vi->v_o[j] - vi1->v_o[j]); + i2_i[i][j] = vi1->i_i[j] + f * (vi->i_i[j] - vi1->i_i[j]); + i2_o[i][j] = vi1->i_o[j] + f * (vi->i_o[j] - vi1->i_o[j]); + } + } + } + } + + return(ext); + +errordetect: + fprintf(stderr, "your maximum time step is too large for tau.\n"); + fprintf(stderr, "decrease max time step in .tran card and try again\n"); + exit(0); +} + + +static int +update_delayed_cnv(cp, h) + CPLine *cp; + float h; +{ + int i, j, k; + float *ratio; + register double f; + register VI_list *vi; + register TMS *tms; + register int noL; + + h *= 0.5e-12; + ratio = cp->ratio; + vi = cp->vi_tail; + noL = cp->noL; + + for (k = 0; k < noL; k++) /* mode */ + if (ratio[k] > 0.0) + for (i = 0; i < noL; i++) /* current eqn */ + for (j = 0; j < noL; j++) { + tms = cp->h3t[i][j][k]; + if (tms == NULL) + continue; + f = h * ratio[k] * vi->v_i[j]; + tms->tm[0].cnv_i += f * tms->tm[0].c; + tms->tm[1].cnv_i += f * tms->tm[1].c; + tms->tm[2].cnv_i += f * tms->tm[2].c; + + f = h * ratio[k] * vi->v_o[j]; + tms->tm[0].cnv_o += f * tms->tm[0].c; + tms->tm[1].cnv_o += f * tms->tm[1].c; + tms->tm[2].cnv_o += f * tms->tm[2].c; + + tms = cp->h2t[i][j][k]; + f = h * ratio[k] * vi->i_i[j]; + tms->tm[0].cnv_i += f * tms->tm[0].c; + tms->tm[1].cnv_i += f * tms->tm[1].c; + tms->tm[2].cnv_i += f * tms->tm[2].c; + + f = h * ratio[k] * vi->i_o[j]; + tms->tm[0].cnv_o += f * tms->tm[0].c; + tms->tm[1].cnv_o += f * tms->tm[1].c; + tms->tm[2].cnv_o += f * tms->tm[2].c; + } + return(1); +} + + +static int expC(ar, ai, h, cr, ci) +double ar, ai, *cr, *ci; +double h; +{ + double e, cs, si; + + e = exp((double) ar * h); + cs = cos((double) ai * h); + si = sin((double) ai * h); + *cr = e * cs; + *ci = e * si; + + return(1); +} + +static int multC(ar, ai, br, bi, cr, ci) +double ar, ai, br, bi; +double *cr, *ci; +{ + register double tp; + + tp = ar*br - ai*bi; + *ci = ar*bi+ai*br; + *cr = tp; + + return (1); + +} + +static void +update_cnv_a(tms, h, ai, ao, bi, bo, er, ei) + TMS *tms; + float h; + double ai, bi, ao, bo; + double er, ei; +{ + double a, b, a1, b1; + + h *= 0.5e-12; + multC(tms->tm[1].c, tms->tm[2].c, er, ei, &a1, &b1); + multC(tms->tm[1].cnv_i, tms->tm[2].cnv_i, er, ei, &a, &b); + tms->tm[1].cnv_i = a + h * (a1 * bi + ai * tms->tm[1].c); + tms->tm[2].cnv_i = b + h * (b1 * bi + ai * tms->tm[2].c); + + multC(tms->tm[1].cnv_o, tms->tm[2].cnv_o, er, ei, &a, &b); + tms->tm[1].cnv_o = a + h * (a1 * bo + ao * tms->tm[1].c); + tms->tm[2].cnv_o = b + h * (b1 * bo + ao * tms->tm[2].c); +} + +static int divC(ar, ai, br, bi, cr, ci) +double ar, ai, br, bi; +double *cr, *ci; +{ + double t; + + t = br*br + bi*bi; + *cr = (ar*br + ai*bi) / t; + *ci = (ai*br - ar*bi) / t; + + return(1); +} + diff --git a/src/spicelib/devices/cpl/cplmdel.c b/src/spicelib/devices/cpl/cplmdel.c new file mode 100644 index 000000000..0697dc890 --- /dev/null +++ b/src/spicelib/devices/cpl/cplmdel.c @@ -0,0 +1,45 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + + +#include "ngspice.h" +#include +#include "cpldefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +CPLmDelete(inModel,modname,kill) + GENmodel **inModel; + IFuid modname; + GENmodel *kill; +{ + CPLmodel **model = (CPLmodel **)inModel; + CPLmodel *modfast = (CPLmodel *)kill; + CPLinstance *here; + CPLinstance *prev = NULL; + CPLmodel **oldmod; + oldmod = model; + + for( ; *model ; model = &((*model)->CPLnextModel)) { + if( (*model)->CPLmodName == modname || + (modfast && *model == modfast) ) goto delgot; + oldmod = model; + } + return(E_NOMOD); + +delgot: + *oldmod = (*model)->CPLnextModel; /* cut deleted device out of list */ + for(here = (*model)->CPLinstances ; here ; here = here->CPLnextInstance) { + if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + FREE(*model); + return(OK); + +} diff --git a/src/spicelib/devices/cpl/cplmpar.c b/src/spicelib/devices/cpl/cplmpar.c new file mode 100644 index 000000000..03cef866f --- /dev/null +++ b/src/spicelib/devices/cpl/cplmpar.c @@ -0,0 +1,51 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + + +#include "ngspice.h" +#include +#include "const.h" +#include "ifsim.h" +#include "cpldefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +CPLmParam(param,value,inModel) + int param; + IFvalue *value; + GENmodel *inModel; +{ + register CPLmodel *model = (CPLmodel *)inModel; + switch(param) { + case CPL_R: + model->Rm = value->v.vec.rVec; + model->Rmgiven = TRUE; + break; + case CPL_L: + model->Lm = value->v.vec.rVec; + model->Lmgiven = TRUE; + break; + case CPL_G: + model->Gm = value->v.vec.rVec; + model->Gmgiven = TRUE; + break; + case CPL_C: + model->Cm = value->v.vec.rVec; + model->Cmgiven = TRUE; + break; + case CPL_length: + model->length = value->rValue; + model->lengthgiven = TRUE; + break; + case CPL_MOD_R: + break; + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/cpl/cplparam.c b/src/spicelib/devices/cpl/cplparam.c new file mode 100644 index 000000000..98dd7eaec --- /dev/null +++ b/src/spicelib/devices/cpl/cplparam.c @@ -0,0 +1,45 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + + +#include "ngspice.h" +#include +#include "const.h" +#include "ifsim.h" +#include "cpldefs.h" +#include "sperror.h" +#include "suffix.h" + + +/* ARGSUSED */ +int +CPLparam(param,value,inst,select) + int param; + IFvalue *value; + GENinstance *inst; + IFvalue *select; +{ + CPLinstance *here = (CPLinstance *)inst; + switch(param) { + case CPL_POS_NODE: + here->in_node_names = value->v.vec.sVec; + break; + case CPL_NEG_NODE: + here->out_node_names = value->v.vec.sVec; + break; + case CPL_DIM: + here->dimension = value->iValue; + break; + case CPL_LENGTH: + here->CPLlength = value->rValue; + here->CPLlengthgiven = TRUE; + break; + + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/cpl/cplsetup.c b/src/spicelib/devices/cpl/cplsetup.c new file mode 100644 index 000000000..f5bb8337c --- /dev/null +++ b/src/spicelib/devices/cpl/cplsetup.c @@ -0,0 +1,2101 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cpldefs.h" +#include "sperror.h" +#include "suffix.h" + +#include "../cap/capdefs.h" +#include "multi_line.h" + +#define VECTOR_ALLOC(vec, n) { \ + int i; \ + vec = (double **) malloc(n * sizeof(double *)); \ + for (i = 0; i < n; i++) { \ + vec[i] = (double *) malloc(sizeof(double)); \ + } \ +} +#define MATRIX_ALLOC(mat, m, j) { \ + int k; \ + mat = (double ***) malloc(m * sizeof(double **)); \ + for (k = 0; k < m; k++) { \ + VECTOR_ALLOC(mat[k], j); \ + } \ +} + +#define MAX_DEG 8 +#define epsilon 1.0e-88 +#define ABS(x) ((x) >= 0 ? (x) : (-(x))) +#define MAX_STRING 128 + +static double ZY[MAX_DIM][MAX_DIM]; +static double Sv[MAX_DIM][MAX_DIM]; +static double D[MAX_DIM]; +static double Y5[MAX_DIM][MAX_DIM]; +static double Y5_1[MAX_DIM][MAX_DIM]; +static double Sv_1[MAX_DIM][MAX_DIM]; + +static double R_m[MAX_DIM][MAX_DIM]; +static double G_m[MAX_DIM][MAX_DIM]; +static double L_m[MAX_DIM][MAX_DIM]; +static double C_m[MAX_DIM][MAX_DIM]; +static double length; +static double TAU[MAX_DIM]; + +static double A[MAX_DIM][2*MAX_DIM]; + +static double frequency[MAX_DEG]; + +static double Si[MAX_DIM][MAX_DIM]; +static double Si_1[MAX_DIM][MAX_DIM]; + +/* MacLaurin Series */ +static double *SiSv_1[MAX_DIM][MAX_DIM]; +static double *Sip[MAX_DIM][MAX_DIM]; +static double *Si_1p[MAX_DIM][MAX_DIM]; +static double *Sv_1p[MAX_DIM][MAX_DIM]; +static double *W[MAX_DIM]; + +static Mult_Out IWI[MAX_DIM][MAX_DIM]; +static Mult_Out IWV[MAX_DIM][MAX_DIM]; +static Single_Out SIV[MAX_DIM][MAX_DIM]; +static double At[4][4]; +static double Scaling_F; +static double Scaling_F2; + +/* misc.c match */ +static void new_memory(); +static double *vector(); +static void free_vector(); +static void polint(); +/*static int match_x();*/ +static int match(); +static int Gaussian_Elimination2(); +static void eval_Si_Si_1(); +static void loop_ZY(); +static void poly_matrix(); +/*static int checkW();*/ +static void poly_W(); +static void eval_frequency(); +static void store(); +static void store_SiSv_1(); +/*static int check();*/ +static int coupled(); +static int generate_out(); +static int ReadCpL(); +/*static int divC();*/ + +/* mult */ +static void mult_p(); +static void matrix_p_mult(); +static double approx_mode(); +static double eval2(); +static int get_c(); +static int Pade_apx(); +static int Gaussian_Elimination(); +static double root3(); +static int div3(); +static int find_roots(); + +static NODE* insert_node(); +static NDnamePt insert_ND(); +static NODE* NEW_node(); +static NDnamePt ndn; +static NODE *node_tab; +#define epsi_mult 1e-28 + +/* diag */ +static MAXE_PTR sort(); +static void ordering(); +static MAXE_PTR delete_1(); +static void reordering(); +static void diag(); +static int rotate(); + +#define epsi 1.0e-16 +static char *message = "tau of coupled lines is larger than max time step"; + +/* ARGSUSED */ +int +CPLsetup(matrix,inModel,ckt,state) + register SMPmatrix *matrix; + GENmodel *inModel; + CKTcircuit*ckt; + int *state; +{ + register CPLmodel *model = (CPLmodel *)inModel; + register CPLinstance *here; + CKTnode *tmp, *node; + int error, m, p; + char **branchname; + int noL; + + /* loop through all the models */ + for( ; model != NULL; model = model->CPLnextModel ) { + + /* loop through all the instances of the model */ + for (here = model->CPLinstances; here != NULL ; + here=here->CPLnextInstance) { + +/* macro to make elements with built in test for out of memory */ +#define TSTALLOC(ptr,first,second) \ +if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ + return(E_NOMEM);\ +} + noL = here->dimension; + + here->CPLposNodes = (int *) malloc(noL * sizeof(int)); + here->CPLnegNodes = (int *) malloc(noL * sizeof(int)); + here->CPLibr1 = (int *) malloc(noL * sizeof(int)); + here->CPLibr2 = (int *) malloc(noL * sizeof(int)); + + VECTOR_ALLOC(here->CPLibr1Ibr1, noL); + VECTOR_ALLOC(here->CPLibr2Ibr2, noL); + VECTOR_ALLOC(here->CPLposIbr1, noL); + VECTOR_ALLOC(here->CPLnegIbr2, noL); + VECTOR_ALLOC(here->CPLposPos, noL); + VECTOR_ALLOC(here->CPLnegNeg, noL); + VECTOR_ALLOC(here->CPLnegPos, noL); + VECTOR_ALLOC(here->CPLposNeg, noL); + + MATRIX_ALLOC(here->CPLibr1Pos, noL, noL); + MATRIX_ALLOC(here->CPLibr2Neg, noL, noL); + MATRIX_ALLOC(here->CPLibr1Neg, noL, noL); + MATRIX_ALLOC(here->CPLibr2Pos, noL, noL); + MATRIX_ALLOC(here->CPLibr1Ibr2, noL, noL); + MATRIX_ALLOC(here->CPLibr2Ibr1, noL, noL); + + branchname = (char **) malloc(sizeof(char *) * here->dimension); + if (! here->CPLibr1Given) { + for (m = 0; m < here->dimension; m++) { + branchname[m] = malloc(MAX_STRING); + sprintf(branchname[m], "branch1_%d", m); + error = + CKTmkCur(ckt, &tmp, here->CPLname, branchname[m]); + if (error) return (error); + here->CPLibr1[m] = tmp->number; + } + here->CPLibr1Given = 1; + } + free(branchname); + branchname = (char **) malloc(sizeof(char *) * here->dimension); + if (! here->CPLibr2Given) { + for (m = 0; m < here->dimension; m++) { + branchname[m] = malloc(MAX_STRING); + sprintf(branchname[m], "branch2_%d", m); + error = + CKTmkCur(ckt, &tmp, here->CPLname, branchname[m]); + if (error) return (error); + here->CPLibr2[m] = tmp->number; + } + here->CPLibr2Given = 1; + } + free(branchname); + + for (m = 0; m < here->dimension; m++) { + for (node = ckt->CKTnodes; node; node = node->next) { + if (strcmp(here->in_node_names[m], + node->name) == 0){ + here->CPLposNodes[m] = node->number; + } + } + } + for (m = 0; m < here->dimension; m++) { + for (node = ckt->CKTnodes; node; node = node->next) { + if (strcmp(here->out_node_names[m], + node->name) == 0){ + here->CPLnegNodes[m] = node->number; + } + } + } + + for (m = 0; m < here->dimension; m++) { + TSTALLOC(CPLibr1Ibr1[m],CPLibr1[m],CPLibr1[m]); + TSTALLOC(CPLibr2Ibr2[m],CPLibr2[m],CPLibr2[m]); + TSTALLOC(CPLposIbr1[m],CPLposNodes[m],CPLibr1[m]); + TSTALLOC(CPLnegIbr2[m],CPLnegNodes[m],CPLibr2[m]); + TSTALLOC(CPLposPos[m],CPLposNodes[m],CPLposNodes[m]); + TSTALLOC(CPLnegNeg[m],CPLnegNodes[m],CPLnegNodes[m]); + TSTALLOC(CPLnegPos[m],CPLnegNodes[m],CPLposNodes[m]); + TSTALLOC(CPLposNeg[m],CPLposNodes[m],CPLnegNodes[m]); + + for (p = 0; p < here->dimension; p++) { + + TSTALLOC(CPLibr1Pos[m][p],CPLibr1[m],CPLposNodes[p]); + TSTALLOC(CPLibr2Neg[m][p],CPLibr2[m],CPLnegNodes[p]); + TSTALLOC(CPLibr1Neg[m][p],CPLibr1[m],CPLnegNodes[p]); + TSTALLOC(CPLibr2Pos[m][p],CPLibr2[m],CPLposNodes[p]); + TSTALLOC(CPLibr1Ibr2[m][p],CPLibr1[m],CPLibr2[p]); + TSTALLOC(CPLibr2Ibr1[m][p],CPLibr2[m],CPLibr1[p]); + + } + } + + ReadCpL(here, ckt); + + } + } + + return(OK); +} + + +static int +ReadCpL(here, ckt) +CPLinstance *here; +CKTcircuit *ckt; +{ + int i, j, noL, counter; + float f; + char *name; + CPLine *c, *c2; + ECPLine *ec; + NODE *nd; + RLINE *lines[MAX_CP_TX_LINES]; + ERLINE *er; + + c = (CPLine *) malloc(sizeof (CPLine)); + c2 = (CPLine *) malloc(sizeof (CPLine)); + c->vi_head = c->vi_tail = NULL; + noL = c->noL = here->dimension; + here->cplines = c; + here->cplines2 = c2; + + for (i = 0; i < noL; i++) { + ec = (ECPLine *) malloc(sizeof (ECPLine)); + name = here->in_node_names[i]; + nd = insert_node(name); + ec->link = nd->cplptr; + nd->cplptr = ec; + ec->line = c; + c->in_node[i] = nd; + c2->in_node[i] = nd; + + er = (ERLINE *) malloc(sizeof (ERLINE)); + er->link = nd->rlptr; + nd->rlptr = er; + er->rl = lines[i] = (RLINE *) malloc(sizeof (RLINE)); + er->rl->in_node = nd; + + c->dc1[i] = c->dc2[i] = 0.0; + } + + for (i = 0; i < noL; i++) { + ec = (ECPLine *) malloc(sizeof (ECPLine)); + name = here->out_node_names[i]; + nd = insert_node(name); + ec->link = nd->cplptr; + nd->cplptr = ec; + ec->line = c; + c->out_node[i] = nd; + c2->out_node[i] = nd; + + er = (ERLINE *) malloc(sizeof (ERLINE)); + er->link = nd->rlptr; + nd->rlptr = er; + er->rl = lines[i]; + er->rl->out_node = nd; + } + + + counter = 0; + for (i = 0; i < noL; i++) { + for (j = 0; j < noL; j++) { + if (i > j) { + R_m[i][j] = R_m[j][i]; + G_m[i][j] = G_m[j][i]; + C_m[i][j] = C_m[j][i]; + L_m[i][j] = L_m[j][i]; + } + else { + f = here->CPLmodPtr->Rm[counter]; + R_m[i][j] =here->CPLmodPtr->Rm[counter]= MAX(f, 1.0e-4); + G_m[i][j] = here->CPLmodPtr->Gm[counter]; + L_m[i][j] = here->CPLmodPtr->Lm[counter]; + C_m[i][j] = here->CPLmodPtr->Cm[counter]; + counter++; + } + } + } + if (here->CPLlengthgiven) + length = here->CPLlength; + else length = here->CPLmodPtr->length; + + for (i = 0; i < noL; i++) + lines[i]->g = 1.0 / (R_m[i][i] * length); + + coupled(noL); + + for (i = 0; i < noL; i++) { + double d, t; + int k; + + c->taul[i] = TAU[i] * 1.0e+12; + for (j = 0; j < noL; j++) { + if (SIV[i][j].C_0 == 0.0) + c->h1t[i][j] = NULL; + else { + c->h1t[i][j] = (TMS *) malloc(sizeof (TMS)); + d = c->h1t[i][j]->aten = SIV[i][j].C_0; + c->h1t[i][j]->ifImg = (int) SIV[i][j].Poly[6] - 1.0; + /* since originally 2 for img 1 for noimg */ + c->h1t[i][j]->tm[0].c = SIV[i][j].Poly[0] * d; + c->h1t[i][j]->tm[1].c = SIV[i][j].Poly[1] * d; + c->h1t[i][j]->tm[2].c = SIV[i][j].Poly[2] * d; + c->h1t[i][j]->tm[0].x = SIV[i][j].Poly[3]; + c->h1t[i][j]->tm[1].x = SIV[i][j].Poly[4]; + c->h1t[i][j]->tm[2].x = SIV[i][j].Poly[5]; + if (c->h1t[i][j]->ifImg) + c->h1C[i][j] = c->h1t[i][j]->tm[0].c + 2.0 * c->h1t[i][j]->tm[1].c; + else { + t = 0.0; + for (k = 0; k < 3; k++) + t += c->h1t[i][j]->tm[k].c; + c->h1C[i][j] = t; + } + } + + for (k = 0; k < noL; k++) { + if (IWI[i][j].C_0[k] == 0.0) + c->h2t[i][j][k] = NULL; + else { + c->h2t[i][j][k] = (TMS *) malloc(sizeof (TMS)); + d = c->h2t[i][j][k]->aten = IWI[i][j].C_0[k]; + c->h2t[i][j][k]->ifImg = (int) IWI[i][j].Poly[k][6] - 1.0; + /* since originally 2 for img 1 for noimg */ + c->h2t[i][j][k]->tm[0].c = IWI[i][j].Poly[k][0] * d; + c->h2t[i][j][k]->tm[1].c = IWI[i][j].Poly[k][1] * d; + c->h2t[i][j][k]->tm[2].c = IWI[i][j].Poly[k][2] * d; + c->h2t[i][j][k]->tm[0].x = IWI[i][j].Poly[k][3]; + c->h2t[i][j][k]->tm[1].x = IWI[i][j].Poly[k][4]; + c->h2t[i][j][k]->tm[2].x = IWI[i][j].Poly[k][5]; + if (c->h2t[i][j][k]->ifImg) + c->h2C[i][j][k] = c->h2t[i][j][k]->tm[0].c + 2.0 * + c->h2t[i][j][k]->tm[1].c; + else + c->h2C[i][j][k] = c->h2t[i][j][k]->tm[0].c + + c->h2t[i][j][k]->tm[1].c + + c->h2t[i][j][k]->tm[2].c; + } + if (IWV[i][j].C_0[k] == 0.0) + c->h3t[i][j][k] = NULL; + else { + c->h3t[i][j][k] = (TMS *) malloc(sizeof (TMS)); + d = c->h3t[i][j][k]->aten = IWV[i][j].C_0[k]; + c->h3t[i][j][k]->ifImg = (int) IWV[i][j].Poly[k][6] - 1.0; + /* since originally 2 for img 1 for noimg */ + c->h3t[i][j][k]->tm[0].c = IWV[i][j].Poly[k][0] * d; + c->h3t[i][j][k]->tm[1].c = IWV[i][j].Poly[k][1] * d; + c->h3t[i][j][k]->tm[2].c = IWV[i][j].Poly[k][2] * d; + c->h3t[i][j][k]->tm[0].x = IWV[i][j].Poly[k][3]; + c->h3t[i][j][k]->tm[1].x = IWV[i][j].Poly[k][4]; + c->h3t[i][j][k]->tm[2].x = IWV[i][j].Poly[k][5]; + if (c->h3t[i][j][k]->ifImg) + c->h3C[i][j][k] = c->h3t[i][j][k]->tm[0].c + 2.0 * + c->h3t[i][j][k]->tm[1].c; + else + c->h3C[i][j][k] = c->h3t[i][j][k]->tm[0].c + + c->h3t[i][j][k]->tm[1].c + + c->h3t[i][j][k]->tm[2].c; + } + } + } + } + + for (i = 0; i < noL; i++) { + if (c->taul[i] < ckt->CKTmaxStep) { + errMsg = MALLOC(strlen(message)+1); + strcpy(errMsg,message); + return(-1); + } + } + + return(1); +} + + +/**************************************************************** + misc.c Miscellaneous procedures for simulation of + coupled transmission lines. + ****************************************************************/ + + +static void +new_memory(dim, deg, deg_o) + int dim, deg, deg_o; +{ + int i, j; + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + SiSv_1[i][j] = (double *) calloc(deg_o+1, sizeof(double)); + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + Sip[i][j] = (double *) calloc(deg_o+1, sizeof(double)); + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + Si_1p[i][j] = (double *) calloc(deg_o+1, sizeof(double)); + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + Sv_1p[i][j] = (double *) calloc(deg_o+1, sizeof(double)); + + for (i = 0; i < dim; i++) + W[i] = (double *) calloc(MAX_DEG, sizeof(double)); +} + +/*** + ***/ + +/**************************************************************** + match Create a polynomial matching given data points + ****************************************************************/ + + +static double +*vector(nl, nh) + int nl, nh; +{ + double *v; + + v = (double *) malloc((unsigned) (nh - nl +1) * sizeof(double)); + if (!v) { + fprintf(stderr, "Memory Allocation Error by malloc in vector().\n"); + fprintf(stderr, "...now exiting to system ...\n"); + exit(0); + } + return v-nl; +} + +static void +free_vector(v, nl, nh) + double *v; + int nl, nh; +{ + free((char*) (v +nl)); +} + +static void +polint(xa, ya, n, x, y, dy) +/* + Given arrays xa[1..n] and ya[1..n], and given a value x, this routine + returns a value y, and an error estimate dy. If P(x) is the + polynomial of degree n-1 such that P(xa) = ya, then the returned + value y = P(x) + */ + double xa[], ya[], x, *y, *dy; + int n; +{ + int i, m, ns = 1; + double den, dif, dift, ho, hp, w; + double *c, *d, *vector(); + void free_vector(); + + dif = ABS(x - xa[1]); + c = vector(1, n); + d = vector(1, n); + for (i = 1; i <= n; i++) { + if ((dift = ABS(x - xa[i])) < dif) { + ns = i; + dif = dift; + } + c[i] = ya[i]; + d[i] = ya[i]; + } + *y = ya[ns--]; + for (m = 1; m < n; m++) { + for (i = 1; i <= n-m; i++) { + ho = xa[i]-x; + hp = xa[i+m]-x; + w = c[i+1]-d[i]; + if ((den=ho-hp) == 0.0) { + fprintf(stderr, "(Error) in routine POLINT\n"); + fprintf(stderr, "...now exiting to system ...\n"); + exit(0); + } + den = w/den; + d[i] = hp * den; + c[i] = ho * den; + } + *y += (*dy = (2*ns < (n-m) ? c[ns+1] : d[ns--])); + } + free_vector(d, 1, n); + free_vector(c, 1, n); +} + +static int +match(n, cof, xa, ya) + double xa[], ya[], cof[]; + int n; +/* + Given arrays xa[0..n] and ya[0..n] containing a tabulated function + ya = f(xa), this routine returns an array of coefficients cof[0..n], + such that ya[i] = sum_j {cof[j]*xa[i]**j}. + */ +{ + int k, j, i; + double xmin, dy, *x, *y, *xx, *vector(); + void polint(), free_vector(); + + x = vector(0, n); + y = vector(0, n); + xx = vector(0, n); + for (j = 0; j <= n; j++) { + x[j] = xa[j]; + xx[j] = y[j] = ya[j]; + } + for (j = 0; j <= n; j++) { + polint(x-1, y-1, n+1-j, (double) 0.0, &cof[j], &dy); + xmin = 1.0e38; + k = -1; + for (i = 0; i <= n-j; i++) { + if (ABS(x[i]) < xmin) { + xmin = ABS(x[i]); + k = i; + } + if (x[i]) y[i] = (y[i] - cof[j]) / x[i]; + } + for (i = k+1; i <= n-j; i++) { + y[i-1] = y[i]; + x[i-1] = x[i]; + } + } + free_vector(y, 0, n); + free_vector(x, 0, n); + + /**** check ****/ + /* + for (i = 0; i <= n; i++) { + xmin = xa[i]; + dy = cof[0]; + for (j = 1; j <= n; j++) { + dy += xmin * cof[j]; + xmin *= xa[i]; + } + printf("*** real x = %e y = %e\n", xa[i], xx[i]); + printf("*** calculated y = %e\n", dy); + printf("*** error = %e \% \n", (dy-xx[i])/xx[i]); + } + */ + return 0; +} + +/*** + ***/ +/*** +static int +match_x(dim, Alfa, X, Y) + int dim; + double X[]; + double Y[]; + double Alfa[]; +{ + int i, j; + double f; + double scale; + + **** check **** + double xx[16]; + for (i = 0; i <= dim; i++) + xx[i] = Y[i]; + + if (Y[1] == Y[0]) + scale = 1.0; + else + scale = X[1] / (Y[1] - Y[0]); + for (i = 0; i < dim; i++) { + f = X[i+1]; + for (j = dim-1; j >= 0; j--) { + A[i][j] = f; + f *= X[i+1]; + } + A[i][dim] = (Y[i+1] - Y[0])*scale; + } + Gaussian_Elimination2(dim, 1); + Alfa[0] = Y[0]; + for (i = 1; i <= dim; i++) + Alfa[i] = A[dim-i][dim] / scale; + + **** check **** + * + for (i = 0; i <= dim; i++) { + f = X[i]; + scale = Alfa[0]; + for (j = 1; j <= dim; j++) { + scale += f * Alfa[j]; + f *= X[i]; + } + printf("*** real x = %e y = %e\n", X[i], xx[i]); + printf("*** calculated y = %e\n", scale); + printf("*** error = %e \% \n", (scale-xx[i])/xx[i]); + } + * + + return(1); +} +***/ +/*** + ***/ + +static int +Gaussian_Elimination2(dims, type) + /* type = 1 : to solve a linear system + -1 : to inverse a matrix */ + int dims; + int type; +{ + register int i, j, k, dim; + register double f; + double max; + int imax; + + if (type == -1) + dim = 2 * dims; + else + dim = dims; + + for (i = 0; i < dims; i++) { + imax = i; + max = ABS(A[i][i]); + for (j = i+1; j < dim; j++) + if (ABS(A[j][i]) > max) { + imax = j; + max = ABS(A[j][i]); + } + if (max < epsilon) { + fprintf(stderr, " can not choose a pivot (misc)\n"); + exit(0); + } + if (imax != i) + for (k = i; k <= dim; k++) { + f = A[i][k]; + A[i][k] = A[imax][k]; + A[imax][k] = f; + } + + f = 1.0 / A[i][i]; + A[i][i] = 1.0; + + for (j = i+1; j <= dim; j++) + A[i][j] *= f; + + for (j = 0; j < dims ; j++) { + if (i == j) + continue; + f = A[j][i]; + A[j][i] = 0.0; + for (k = i+1; k <= dim; k++) + A[j][k] -= f * A[i][k]; + } + } + + return(1); +} + +/*** + +static void +eval_Si_Si_1(dim, y) + int dim; + double y; +{ + int i, j, k; + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + Si_1[i][j] = 0.0; + for (k = 0; k < dim; k++) + if (k == j) + Si_1[i][j] += Sv_1[i][k] * + (y * R_m[k][j] + Scaling_F * L_m[k][j]); + else + Si_1[i][j] += Sv_1[i][k] * L_m[k][j] * Scaling_F; + / + Si_1[i][j] *= Scaling_F; + / + } + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + Si_1[i][j] /= sqrt((double) D[i]); + + for (i = 0; i < dim; i++) { + for (j = 0; j < dim; j++) + A[i][j] = Si_1[i][j]; + for (j = dim; j < 2* dim; j++) + A[i][j] = 0.0; + A[i][i+dim] = 1.0; + } + Gaussian_Elimination2(dim, -1); + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + Si[i][j] = A[i][j+dim]; +} + +***/ + +static void +eval_Si_Si_1(dim, y) + int dim; + double y; +{ + int i, j, k; + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + Si_1[i][j] = 0.0; + for (k = 0; k < dim; k++) + Si_1[i][j] += Sv_1[i][k] * (y * R_m[k][j] + Scaling_F * L_m[k][j]); + /* + else + Si_1[i][j] += Sv_1[i][k] * L_m[k][j] * Scaling_F; + Si_1[i][j] *= Scaling_F; + */ + } + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + Si_1[i][j] /= sqrt((double) D[i]); + + for (i = 0; i < dim; i++) { + for (j = 0; j < dim; j++) + A[i][j] = Si_1[i][j]; + for (j = dim; j < 2* dim; j++) + A[i][j] = 0.0; + A[i][i+dim] = 1.0; + } + Gaussian_Elimination2(dim, -1); + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + Si[i][j] = A[i][j+dim]; +} + +/*** + +static void +loop_ZY(dim, y) + int dim; + double y; +{ + int i, j, k; + double fmin, fmin1; + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + if (i == j) + ZY[i][j] = Scaling_F * C_m[i][i] + G_m[i] * y; + else + ZY[i][j] = Scaling_F * C_m[i][j]; + diag(dim); + fmin = D[0]; + for (i = 1; i < dim; i++) + if (D[i] < fmin) + fmin = D[i]; + if (fmin < 0) { + fprintf(stderr, "(Error) The capacitance matrix of the multiconductor system is not positive definite.\n"); + exit(0); + } else { + fmin = sqrt(fmin); + fmin1 = 1 / fmin; + } + for (i = 0; i < dim; i++) + D[i] = sqrt((double) D[i]); + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + Y5[i][j] = D[i] * Sv[j][i]; + Y5_1[i][j] = Sv[j][i] / D[i]; + } + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + Sv_1[i][j] = 0.0; + for (k = 0; k < dim; k++) + Sv_1[i][j] += Sv[i][k] * Y5[k][j]; + } + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + Y5[i][j] = Sv_1[i][j]; + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + Sv_1[i][j] = 0.0; + for (k = 0; k < dim; k++) + Sv_1[i][j] += Sv[i][k] * Y5_1[k][j]; + } + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + Y5_1[i][j] = Sv_1[i][j]; + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + ZY[i][j] = 0.0; + for (k = 0; k < dim; k++) + if (k == i) + ZY[i][j] += (Scaling_F * L_m[i][i] + R_m[i] * y) * + Y5[k][j]; + else + ZY[i][j] += L_m[i][k] * Y5[k][j] * Scaling_F; + } + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + Sv_1[i][j] = 0.0; + for (k = 0; k < dim; k++) + Sv_1[i][j] += Y5[i][k] * ZY[k][j]; + } + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + ZY[i][j] = Sv_1[i][j]; + + diag(dim); + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + Sv_1[i][j] = 0.0; + for (k = 0; k < dim; k++) + Sv_1[i][j] += Sv[k][i] * Y5[k][j]; + Sv_1[i][j] *= fmin1; + } + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + ZY[i][j] = 0.0; + for (k = 0; k < dim; k++) + ZY[i][j] += Y5_1[i][k] * Sv[k][j]; + ZY[i][j] *= fmin; + } + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + Sv[i][j] = ZY[i][j]; + +} +***/ + +static void +loop_ZY(dim, y) + int dim; + double y; +{ + int i, j, k; + double fmin, fmin1; + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + ZY[i][j] = Scaling_F * C_m[i][j] + G_m[i][j] * y; + /* + else + ZY[i][j] = Scaling_F * C_m[i][j]; + */ + diag(dim); + fmin = D[0]; + for (i = 1; i < dim; i++) + if (D[i] < fmin) + fmin = D[i]; + if (fmin < 0) { + fprintf(stderr, "(Error) The capacitance matrix of the multiconductor system is not positive definite.\n"); + exit(0); + } else { + fmin = sqrt(fmin); + fmin1 = 1 / fmin; + } + for (i = 0; i < dim; i++) + D[i] = sqrt((double) D[i]); + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + Y5[i][j] = D[i] * Sv[j][i]; + Y5_1[i][j] = Sv[j][i] / D[i]; + } + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + Sv_1[i][j] = 0.0; + for (k = 0; k < dim; k++) + Sv_1[i][j] += Sv[i][k] * Y5[k][j]; + } + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + Y5[i][j] = Sv_1[i][j]; + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + Sv_1[i][j] = 0.0; + for (k = 0; k < dim; k++) + Sv_1[i][j] += Sv[i][k] * Y5_1[k][j]; + } + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + Y5_1[i][j] = Sv_1[i][j]; + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + ZY[i][j] = 0.0; + for (k = 0; k < dim; k++) + ZY[i][j] += (Scaling_F * L_m[i][k] + R_m[i][k] * y) * Y5[k][j]; + /* + else + ZY[i][j] += L_m[i][k] * Y5[k][j] * Scaling_F; + */ + } + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + Sv_1[i][j] = 0.0; + for (k = 0; k < dim; k++) + Sv_1[i][j] += Y5[i][k] * ZY[k][j]; + } + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + ZY[i][j] = Sv_1[i][j]; + + diag(dim); + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + Sv_1[i][j] = 0.0; + for (k = 0; k < dim; k++) + Sv_1[i][j] += Sv[k][i] * Y5[k][j]; + Sv_1[i][j] *= fmin1; + } + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + ZY[i][j] = 0.0; + for (k = 0; k < dim; k++) + ZY[i][j] += Y5_1[i][k] * Sv[k][j]; + ZY[i][j] *= fmin; + } + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + Sv[i][j] = ZY[i][j]; + +} + + +/*** + ***/ + +static void +poly_matrix(A, dim, deg) + double *A[MAX_DIM][MAX_DIM]; + int dim, deg; +{ + int i, j; + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + match(deg, A[i][j], frequency, A[i][j]); +} + +/*** + ***/ +/*** +static int +checkW(W, d) + double W[], d; +{ + double f, y; + float y1; + int k; + + printf("(W)y ="); + scanf("%f", &y1); + + f = W[0]; + y = y1; + f += y * W[1]; + for (k = 2; k < 6; k++) { + y *= y1; + f += y * W[k]; + } + printf("W[i]= %e\n ", f*exp((double)-d/y1)); + + return(1); +} +***/ +/*** + ***/ + +static void +poly_W(dim, deg) + int dim, deg; +{ + int i; + extern double approx_mode(); + + for (i = 0; i < dim; i++) { + match(deg, W[i], frequency, W[i]); + TAU[i] = approx_mode(W[i], W[i], length); + /* + checkW(W[i], TAU[i]); + */ + } +} + +/*** + ***/ + +static void +eval_frequency(dim, deg_o) + int deg_o; +{ + int i, im; + double min; + + min = D[0]; + im = 0; + + for (i = 1; i < dim; i++) + if (D[i] < min) { + min = D[i]; + im = i; + } + + if (min <= 0) { + fprintf(stderr, "A mode frequency is not positive. Abort!\n"); + exit(0); + } + + Scaling_F2 = 1.0 / min; + Scaling_F = sqrt(Scaling_F2); + min = length * 8.0; + /* + min *= 1.0e18; + min = sqrt(min)*1.0e-9*length/8.0; + */ + + frequency[0] = 0.0; + + for (i = 1; i <= deg_o; i++) + frequency[i] = frequency[i-1] + min; + + for (i = 0; i < dim; i++) + D[i] *= Scaling_F2; +} + +/*** + ***/ + +static void +store(dim, ind) + int ind; +{ + int i, j; + + for (i = 0; i < dim; i++) { + for (j = 0; j < dim; j++) { + /* store_Sip */ + Sip[i][j][ind] = Si[i][j]; + /* store_Si_1p */ + Si_1p[i][j][ind] = Si_1[i][j]; + /* store_Sv_1p */ + Sv_1p[i][j][ind] = Sv_1[i][j]; + } + /* store_W */ + W[i][ind] = D[i]; + } +} + +/*** + ***/ + +static void +store_SiSv_1(dim, ind) +{ + int i, j, k; + double temp; + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + temp = 0.0; + for (k = 0; k < dim; k++) + temp += Si[i][k] * Sv_1[k][j]; + SiSv_1[i][j][ind] = temp; + } +} + +/*** + ***/ +/*** +static int +check(Sip, Si_1p, Sv_1p, SiSv_1p) + double *Sip[MAX_DIM][MAX_DIM]; + double *Si_1p[MAX_DIM][MAX_DIM]; + double *Sv_1p[MAX_DIM][MAX_DIM]; + double *SiSv_1p[MAX_DIM][MAX_DIM]; +{ + double f, y; + float y1; + int i, j, k; + + printf("y ="); + scanf("%f", &y1); + + printf("\n"); + printf("Si =\n"); + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + f = Sip[i][j][0]; + y = y1; + f += y * Sip[i][j][1]; + for (k = 2; k < 8; k++) { + y *= y1; + f += y * Sip[i][j][k]; + } + printf("%e ", f); + } + printf("\n"); + } + printf("\n"); + printf("Si_1 =\n"); + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + f = Si_1p[i][j][0]; + y = y1; + f += y * Si_1p[i][j][1]; + for (k = 2; k < 8; k++) { + y *= y1; + f += y * Si_1p[i][j][k]; + } + printf("%e ", f); + } + printf("\n"); + } + printf("\n"); + printf("Sv_1 =\n"); + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + f = Sv_1p[i][j][0]; + y = y1; + f += y * Sv_1p[i][j][1]; + for (k = 2; k < 8; k++) { + y *= y1; + f += y * Sv_1p[i][j][k]; + } + printf("%e ", f); + } + printf("\n"); + } + printf("\n"); + printf("SiSv_1 =\n"); + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + f = SiSv_1p[i][j][0]; + y = y1; + f += y * SiSv_1p[i][j][1]; + for (k = 2; k < 8; k++) { + y *= y1; + f += y * SiSv_1p[i][j][k]; + } + printf("%e ", f); + } + printf("\n"); + } + return(1); +} +***/ +/*** + ***/ + +static int +coupled(dim) + int dim; +{ + int deg, deg_o; + int i; + + deg = Right_deg; + deg_o = Left_deg; + new_memory(dim, deg, deg_o); + + Scaling_F = Scaling_F2 = 1.0; + + /*** y = 0 : ZY = LC ***/ + loop_ZY(dim, (double) 0.0); + eval_frequency(dim, deg_o); + eval_Si_Si_1(dim, (double) 0.0); + store_SiSv_1(dim, (int) 0); + store(dim, (int) 0); + + /*** Step 1 ***/ + /*** Step 2 ***/ + for (i = 1; i <= deg_o; i++) { + loop_ZY(dim, frequency[i]); + eval_Si_Si_1(dim, frequency[i]); + store_SiSv_1(dim, i); + store(dim, i); + } + poly_matrix(Sip, dim, deg_o); + poly_matrix(Si_1p, dim, deg_o); + poly_matrix(Sv_1p, dim, deg_o); + poly_W(dim, deg_o); + matrix_p_mult(Sip, W, Si_1p, dim, deg_o, deg_o, IWI); + matrix_p_mult(Sip, W, Sv_1p, dim, deg_o, deg_o, IWV); + + poly_matrix(SiSv_1, dim, deg_o); + + /*** + check(Sip, Si_1p, Sv_1p, SiSv_1); + ***/ + + generate_out(dim, deg_o); + + return(1); +} + +/*** + ***/ + +static int +generate_out(dim, deg_o) + int dim, deg_o; +{ + int i, j, k, rtv; + double C; + double *p; + double c1, c2, c3, x1, x2, x3; + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + p = SiSv_1[i][j]; + SIV[i][j].C_0 = C = p[0]; + if (C == 0.0) + continue; + for (k = 0; k <= deg_o; k++) + p[k] /= C; + if (i == j) { + rtv = Pade_apx((double) sqrt((double) G_m[i][i] / R_m[i][i]) / C, + p, &c1, &c2, &c3, &x1, &x2, &x3); + if (rtv == 0) { + SIV[i][j].C_0 = 0.0; + printf("SIV\n"); + continue; + } + } else { + rtv = Pade_apx((double) 0.0, + p, &c1, &c2, &c3, &x1, &x2, &x3); + if (rtv == 0) { + SIV[i][j].C_0 = 0.0; + printf("SIV\n"); + continue; + } + } + p = SIV[i][j].Poly = (double *) calloc(7, sizeof(double)); + p[0] = c1; + p[1] = c2; + p[2] = c3; + p[3] = x1; + p[4] = x2; + p[5] = x3; + p[6] = (double) rtv; + } + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + for (k = 0; k < dim; k++) { + p = IWI[i][j].Poly[k]; + C = IWI[i][j].C_0[k]; + if (C == 0.0) + continue; + if (i == j && k == i) { + rtv = Pade_apx((double) + exp(- sqrt((double) G_m[i][i] * R_m[i][i]) * length) / C, + p, &c1, &c2, &c3, &x1, &x2, &x3); + if (rtv == 0) { + IWI[i][j].C_0[k] = 0.0; + printf("IWI %d %d %d\n", i, j, k); + continue; + } + } else { + rtv = Pade_apx((double) 0.0, + p, &c1, &c2, &c3, &x1, &x2, &x3); + if (rtv == 0) { + IWI[i][j].C_0[k] = 0.0; + printf("IWI %d %d %d\n", i, j, k); + continue; + } + } + p[0] = c1; + p[1] = c2; + p[2] = c3; + p[3] = x1; + p[4] = x2; + p[5] = x3; + p[6] = (double) rtv; + } + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + for (k = 0; k < dim; k++) { + p = IWV[i][j].Poly[k]; + C = IWV[i][j].C_0[k]; + if (C == 0.0) + continue; + if (i == j && k == i) { + rtv = Pade_apx((double) sqrt((double) G_m[i][i] / R_m[i][i]) * + exp(- sqrt((double) G_m[i][i] * R_m[i][i]) * length) / C, + p, &c1, &c2, &c3, &x1, &x2, &x3); + if (rtv == 0) { + IWV[i][j].C_0[k] = 0.0; + printf("IWV %d %d %d\n", i, j, k); + continue; + } + } else { + rtv = Pade_apx((double) 0.0, + p, &c1, &c2, &c3, &x1, &x2, &x3); + if (rtv == 0) { + IWV[i][j].C_0[k] = 0.0; + printf("IWV %d %d %d\n", i, j, k); + continue; + } + } + p[0] = c1; + p[1] = c2; + p[2] = c3; + p[3] = x1; + p[4] = x2; + p[5] = x3; + p[6] = (double) rtv; + } + return(1); +} + +/**************************************************************** + mult.c Multiplication for Matrix of Polynomial + X(y) = A(y) D(y) B(y), + where D(y) is a diagonal matrix with each + diagonal entry of the form + e^{-a_i s}d(y), for which s = 1/y + and i = 1..N. + Each entry of X(y) will be of the form + \sum_{i=1}^N c_i e^{-a_i s} b_i(y), where + b_i(0) = 1; therefore, those + b_i(y)'s will be each entry's output. + ****************************************************************/ + +static void +mult_p(p1, p2, p3, d1, d2, d3) +/* p3 = p1 * p2 */ + double *p1, *p2, *p3; + int d1, d2, d3; +{ + int i, j, k; + + for (i = 0; i <= d3; i++) + p3[i] = 0.0; + for (i = 0; i <= d1; i++) + for (j = i, k = 0; k <= d2; j++, k++) { + if (j > d3) + break; + p3[j] += p1[i] * p2[k]; + } +} + + +static void +matrix_p_mult(A, D, B, dim, deg, deg_o, X) + double *A[MAX_DIM][MAX_DIM]; + double *D[MAX_DIM]; + double *B[MAX_DIM][MAX_DIM]; + int dim, deg, deg_o; + Mult_Out X[MAX_DIM][MAX_DIM]; +{ + int i, j, k, l; + double *p; + double *T[MAX_DIM][MAX_DIM]; + double t1; + + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + p = T[i][j] = (double *) calloc(deg_o+1, sizeof(double)); + mult_p(B[i][j], D[i], p, deg, deg_o, deg_o); + } + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) + for (k = 0; k < dim; k++) { + p = X[i][j].Poly[k] = + (double *) calloc(deg_o+1, sizeof(double)); + mult_p(A[i][k], T[k][j], p, deg, deg_o, deg_o); + t1 = X[i][j].C_0[k] = p[0]; + if (t1 != 0.0) { + p[0] = 1.0; + for (l = 1; l <= deg_o; l++) + p[l] /= t1; + } + } + + /********** + for (i = 0; i < dim; i++) + for (j = 0; j < dim; j++) { + for (k = 0; k < dim; k++) { + fprintf(outFile, "(%5.3f)", X[i][j].C_0[k]); + p = X[i][j].Poly[k]; + for (l = 0; l <= deg_o; l++) + fprintf(outFile, "%5.3f ", p[l]); + fprintf(outFile, "\n"); + } + fprintf(outFile, "\n"); + } + ***********/ +} + +/**************************************************************** + mode approximation + + ****************************************************************/ + +/*** + ***/ + +static double +approx_mode(X, b, length) + double X[], b[], length; +{ + double w0, w1, w2, w3, w4, w5; + double a[8]; + double delay, atten; + double y1, y2, y3, y4, y5, y6; + int i, j; + + w0 = X[0]; + w1 = X[1] / w0; /* a */ + w2 = X[2] / w0; /* b */ + w3 = X[3] / w0; /* c */ + w4 = X[4] / w0; /* d */ + w5 = X[5] / w0; /* e */ + + y1 = 0.5 * w1; + y2 = w2 - y1 * y1; + y3 = 3 * w3 - 3.0 * y1 * y2; + y4 = 12.0 * w4 - 3.0 * y2 * y2 - 4.0 * y1 * y3; + y5 = 60.0 * w5 - 5.0 * y1 * y4 -10.0 * y2 * y3; + y6 = -10.0 * y3 * y3 - 15.0 * y2 * y4 - 6.0 * y1 * y5; + + delay = sqrt(w0) * length / Scaling_F; + atten = exp((double) - delay * y1); + + a[1] = y2 / 2.0; + a[2] = y3 / 6.0; + a[3] = y4 / 24.0; + a[4] = y5 / 120.0; + a[5] = y6 / 720.0; + + a[1] *= -delay; + a[2] *= -delay; + a[3] *= -delay; + a[4] *= -delay; + a[5] *= -delay; + + b[0] = 1.0; + b[1] = a[1]; + for (i = 2; i <= 5; i++) { + b[i] = 0.0; + for (j = 1; j <= i; j++) + b[i] += j * a[j] * b[i-j]; + b[i] = b[i] / (double) i; + } + + for (i = 0; i <= 5; i++) + b[i] *= atten; + + return(delay); +} + +/*** + ***/ + +static double +eval2(a, b, c, x) + double a, b, c, x; +{ + return(a*x*x + b*x + c); +} + +/*** + ***/ + +static int +get_c(q1, q2, q3, p1, p2, a, b, cr, ci) + double q1, q2, q3, p1, p2, a, b; + double *cr, *ci; +{ + double d, n; + + d = (3.0*(a*a-b*b)+2.0*p1*a+p2)*(3.0*(a*a-b*b)+2.0*p1*a+p2); + d += (6.0*a*b+2.0*p1*b)*(6.0*a*b+2.0*p1*b); + n = -(q1*(a*a-b*b)+q2*a+q3)*(6.0*a*b+2.0*p1*b); + n += (2.0*q1*a*b+q2*b)*(3.0*(a*a-b*b)+2.0*p1*a+p2); + *ci = n/d; + n = (3.0*(a*a-b*b)+2.0*p1*a+p2)*(q1*(a*a-b*b)+q2*a+q3); + n += (6.0*a*b+2.0*p1*b)*(2.0*q1*a*b+q2*b); + *cr = n/d; + + return(1); +} + + +static int +Pade_apx(a_b, b, c1, c2, c3, x1, x2, x3) +/* + b[0] + b[1]*y + b[2]*y^2 + ... + b[5]*y^5 + ... + = (q3*y^3 + q2*y^2 + q1*y + 1) / (p3*y^3 + p2*y^2 + p1*y + 1) + + where b[0] is always equal to 1.0 and neglected, + and y = 1/s. + + (q3*y^3 + q2*y^2 + q1*y + 1) / (p3*y^3 + p2*y^2 + p1*y + 1) + = (s^3 + q1*s^2 + q2*s + q3) / (s^3 + p1*s^2 + p2*s + p3) + = c1 / (s - x1) + c2 / (s - x2) + c3 / (s - x3) + 1.0 + */ + double a_b; + double b[]; + double *c1, *c2, *c3; + double *x1, *x2, *x3; +{ + double p1, p2, p3, q1, q2, q3; + + At[0][0] = 1.0 - a_b; + At[0][1] = b[1]; + At[0][2] = b[2]; + At[0][3] = -b[3]; + + At[1][0] = b[1]; + At[1][1] = b[2]; + At[1][2] = b[3]; + At[1][3] = -b[4]; + + At[2][0] = b[2]; + At[2][1] = b[3]; + At[2][2] = b[4]; + At[2][3] = -b[5]; + + Gaussian_Elimination(3); + + p3 = At[0][3]; + p2 = At[1][3]; + p1 = At[2][3]; + /* + if (p3 < 0.0 || p2 < 0.0 || p1 < 0.0 || p1*p2 <= p3) + return(0); + */ + q1 = p1 + b[1]; + q2 = b[1] * p1 + p2 + b[2]; + q3 = p3 * a_b; + + if (find_roots(p1, p2, p3, x1, x2, x3)) { + /* + printf("complex roots : %e %e %e \n", *x1, *x2, *x3); + */ + *c1 = eval2(q1 - p1, q2 - p2, q3 - p3, *x1) / + eval2((double) 3.0, (double) 2.0 * p1, p2, *x1); + get_c(q1 - p1, q2 - p2, q3 - p3, p1, p2, *x2, *x3, c2, c3); + return(2); + } else { + /* new + printf("roots are %e %e %e \n", *x1, *x2, *x3); + */ + *c1 = eval2(q1 - p1, q2 - p2, q3 - p3, *x1) / + eval2((double) 3.0, (double) 2.0 * p1, p2, *x1); + *c2 = eval2(q1 - p1, q2 - p2, q3 - p3, *x2) / + eval2((double) 3.0, (double) 2.0 * p1, p2, *x2); + *c3 = eval2(q1 - p1, q2 - p2, q3 - p3, *x3) / + eval2((double) 3.0, (double) 2.0 * p1, p2, *x3); + return(1); + } +} + +static int +Gaussian_Elimination(dims) + int dims; +{ + register int i, j, k, dim; + register double f; + double max; + int imax; + + dim = dims; + + for (i = 0; i < dim; i++) { + imax = i; + max = ABS(At[i][i]); + for (j = i+1; j < dim; j++) + if (ABS(At[j][i]) > max) { + imax = j; + max = ABS(At[j][i]); + } + if (max < epsi_mult) { + fprintf(stderr, " can not choose a pivot (mult)\n"); + exit(0); + } + if (imax != i) + for (k = i; k <= dim; k++) { + f = At[i][k]; + At[i][k] = At[imax][k]; + At[imax][k] = f; + } + + f = 1.0 / At[i][i]; + At[i][i] = 1.0; + + for (j = i+1; j <= dim; j++) + At[i][j] *= f; + + for (j = 0; j < dim ; j++) { + if (i == j) + continue; + f = At[j][i]; + At[j][i] = 0.0; + for (k = i+1; k <= dim; k++) + At[j][k] -= f * At[i][k]; + } + } + return(1); +} + +static double +root3(a1, a2, a3, x) + double x; + double a1, a2, a3; +{ + double t1, t2; + + t1 = x * (x * (x + a1) + a2) + a3; + t2 = x * (2.0*a1 + 3.0*x) + a2; + + return(x - t1 / t2); +} + +static int +div3(a1, a2, a3, x, p1, p2) + double x; + double a1, a2, a3; + double *p1, *p2; +{ + *p1 = a1 + x; + + /* *p2 = a2 + (a1 + x) * x; */ + + *p2 = - a3 / x; + + return(1); +} + + +static int +find_roots(a1, a2, a3, x1, x2, x3) + double a1, a2, a3; + double *x1, *x2, *x3; +{ + double x, t; + double p, q; + + /*********************************************** + double m,n; + p = a1*a1/3.0 - a2; + q = a1*a2/3.0 - a3 - 2.0*a1*a1*a1/27.0; + p = p*p*p/27.0; + t = q*q - 4.0*p; + if (t < 0.0) { + if (q != 0.0) { + t = atan(sqrt((double)-t)/q); + if (t < 0.0) + t += 3.141592654; + t /= 3.0; + x = 2.0 * pow(p, 0.16666667) * cos(t) - a1 / 3.0; + } else { + t /= -4.0; + x = pow(t, 0.16666667) * 1.732 - a1 / 3.0; + } + } else { + t = sqrt(t); + m = 0.5*(q - t); + n = 0.5*(q + t); + if (m < 0.0) + m = -pow((double) -m, (double) 0.3333333); + else + m = pow((double) m, (double) 0.3333333); + if (n < 0.0) + n = -pow((double) -n, (double) 0.3333333); + else + n = pow((double) n, (double) 0.3333333); + x = m + n - a1 / 3.0; + } + ************************************************/ + q = (a1*a1-3.0*a2) / 9.0; + p = (2.0*a1*a1*a1-9.0*a1*a2+27.0*a3) / 54.0; + t = q*q*q - p*p; + if (t >= 0.0) { + t = acos((double) p /(q * sqrt(q))); + x = -2.0*sqrt(q)*cos(t / 3.0) - a1/3.0; + } else { + if (p > 0.0) { + t = pow(sqrt(-t)+p, (double) 1.0 / 3.0); + x = -(t + q / t) - a1/3.0; + } else if (p == 0.0) { + x = -a1/3.0; + } else { + t = pow(sqrt(-t)-p, (double) 1.0 / 3.0); + x = (t + q / t) - a1/3.0; + } + } + /* + fprintf(stderr, "..1.. %e\n", x*x*x+a1*x*x+a2*x+a3); + */ + { + double x1; + int i = 0; + x1 = x; + for (t = root3(a1, a2, a3, x); ABS(t-x) > 5.0e-4; + t = root3(a1, a2, a3, x)) + if (++i == 32) { + x = x1; + break; + } else + x = t; + } + /* + fprintf(stderr, "..2.. %e\n", x*x*x+a1*x*x+a2*x+a3); + */ + + + *x1 = x; + div3(a1, a2, a3, x, &a1, &a2); + + t = a1 * a1 - 4.0 * a2; + if (t < 0) { + /* + fprintf(stderr, "***** Two Imaginary Roots.\n Update.\n"); + *x2 = -0.5 * a1; + *x3 = a2 / *x2; + */ + *x3 = 0.5 * sqrt(-t); + *x2 = -0.5 * a1; + return(1); + } else { + t = sqrt(t); + if (a1 >= 0.0) + *x2 = t = -0.5 * (a1 + t); + else + *x2 = t = -0.5 * (a1 - t); + *x3 = a2 / t; + return(0); + } +} + + +static NDnamePt +insert_ND(name, ndn) + char *name; + NDnamePt *ndn; +{ + int cmp; + NDnamePt p; + + if (*ndn == NULL) { + p = *ndn = (NDnamePt) malloc(sizeof (NDname)); + p->nd = NULL; + p->right = p->left = NULL; + strcpy(p->id, name); + return(p); + } + cmp = strcmp((*ndn)->id, name); + if (cmp == 0) + return(*ndn); + else { + if (cmp < 0) + return(insert_ND(name, &((*ndn)->left))); + else + return(insert_ND(name, &((*ndn)->right))); + } +} + +static NODE * +insert_node(name) + char *name; +{ + NDnamePt n; + NODE *p; + + n = insert_ND(name, &ndn); + if (n->nd == NULL) { + p = NEW_node(); + p->name = n; + n->nd = p; + p->next = node_tab; + node_tab = p; + return(p); + } else + return(n->nd); +} +/*** +static int divC(ar, ai, br, bi, cr, ci) +double ar, ai, br, bi; +double *cr, *ci; +{ + double t; + + t = br*br + bi*bi; + *cr = (ar*br + ai*bi) / t; + *ci = (ai*br - ar*bi) / t; + + return(1); +} +***/ + +static NODE +*NEW_node() +{ + /* + char *malloc(); + */ + NODE *n; + + n = (NODE *) malloc (sizeof (NODE)); + n->mptr = NULL; + n->gptr = NULL; + n->cptr = NULL; + n->rptr = NULL; + n->tptr = NULL; + n->cplptr = NULL; + n->rlptr = NULL; + n->ddptr = NULL; + n->cvccsptr = NULL; + n->vccsptr = NULL; + n->CL = 0.001; + n->V = n->dv = 0.0; + n->gsum = n->cgsum = 0; + n->is = 0; + n->tag = 0; + n->flag = 0; + n->region = NULL; + n->ofile = NULL; + n->dvtag = 0; + + return(n); +} + + + +/**************************************************************** + diag.c This file contains the main(). + ****************************************************************/ + +#define epsi2 1.0e-8 + +static int dim; +static MAXE_PTR row; + +static MAXE_PTR +sort(list, val, r, c, e) + MAXE_PTR list, e; + float val; + int r, c; +{ + if (list == NULL || list->value < val) { + e->row = r; + e->col = c; + e->value = val; + e->next = list; + return(e); + } else { + list->next = sort(list->next, val, r, c, e); + return(list); + } +} + + +static void +ordering() +{ + MAXE_PTR e; + int i, j, m; + float mv; + + for (i = 0; i < dim-1; i++) { + m = i+1; + mv = ABS(ZY[i][m]); + for (j = m+1; j < dim; j++) + if ((int)(ABS(ZY[i][j]) * 1e7) > (int) (1e7 *mv)) { + + mv = ABS(ZY[i][j]); + m = j; + } + e = (MAXE_PTR) malloc(sizeof (MAXE)); + row = sort(row, mv, i, m, e); + } +} + + +static MAXE_PTR +delete_1(list, rc) + MAXE_PTR *list; + int rc; +{ + MAXE_PTR list1, e; + + list1 = *list; + if ((*list)->row == rc) { + *list = (*list)->next; + return(list1); + } + for (e = list1->next; e->row != rc; e = e->next) + list1 = e; + list1->next = e->next; + return(e); +} + + +static void +reordering(p, q) + int p, q; +{ + MAXE_PTR e; + int j, m; + float mv; + + m = p+1; + mv = ABS(ZY[p][m]); + for (j = m+1; j < dim; j++) + if ((int)(ABS(ZY[p][j]) * 1e7) > (int) (1e7 *mv)) { + mv = ABS(ZY[p][j]); + m = j; + } + e = delete_1(&row, p); + row = sort(row, mv, p, m, e); + + m = q+1; + if (m != dim) { + mv = ABS(ZY[q][m]); + for (j = m+1; j < dim; j++) + if ((int)(ABS(ZY[q][j]) * 1e7) > (int) (1e7 *mv)) { + + mv = ABS(ZY[q][j]); + m = j; + } + e = delete_1(&row, q); + row = sort(row, mv, q, m, e); + } + +} + +static void +diag(dims) + int dims; +{ + int i, j, c; + double fmin, fmax; + + dim = dims; + row = NULL; + + fmin = fmax = ABS(ZY[0][0]); + for (i = 0; i < dim; i++) + for (j = i; j < dim; j++) + if (ABS(ZY[i][j]) > fmax) + fmax = ABS(ZY[i][j]); + else if (ABS(ZY[i][j]) < fmin) + fmin = ABS(ZY[i][j]); + fmin = 2.0 / (fmin + fmax); + for (i = 0; i < dim; i++) + for (j = i; j < dim; j++) + ZY[i][j] *= fmin; + + for (i = 0; i < dim; i++) { + for (j = 0; j < dim; j++) + if (i == j) + Sv[i][i] = 1.0; + else + Sv[i][j] = 0.0; + } + + ordering(); + + if (row) + for (c = 0; row->value > epsi2; c++) { + int p, q; + + p = row->row; + q = row->col; + + rotate(dim, p, q); + reordering(p, q); + } + + for (i = 0; i < dim; i++) + D[i] = ZY[i][i] / fmin; +} + +/**************************************************************** + rotate() rotation of the Jacobi's method + ****************************************************************/ + +static int +rotate(dim, p, q) + int p, q, dim; +{ + int j; + double co, si; + double ve, mu, ld; + double T[MAX_DIM]; + double t; + + ld = - ZY[p][q]; + mu = 0.5 * (ZY[p][p] - ZY[q][q]); + ve = sqrt((double) ld*ld + mu*mu); + co = sqrt((double) (ve + ABS(mu)) / (2.0 * ve)); + si = SGN(mu) * ld / (2.0 * ve * co); + + for (j = p+1; j < dim; j++) + T[j] = ZY[p][j]; + for (j = 0; j < p; j++) + T[j] = ZY[j][p]; + + for (j = p+1; j < dim; j++) { + if (j == q) + continue; + if (j > q) + ZY[p][j] = T[j] * co - ZY[q][j] * si; + else + ZY[p][j] = T[j] * co - ZY[j][q] * si; + } + for (j = q+1; j < dim; j++) { + if (j == p) + continue; + ZY[q][j] = T[j] * si + ZY[q][j] * co; + } + for (j = 0; j < p; j++) { + if (j == q) + continue; + ZY[j][p] = T[j] * co - ZY[j][q] * si; + } + for (j = 0; j < q; j++) { + if (j == p) + continue; + ZY[j][q] = T[j] * si + ZY[j][q] * co; + } + + t = ZY[p][p]; + ZY[p][p] = t * co * co + ZY[q][q] * si * si - 2.0 * ZY[p][q] * si * co; + ZY[q][q] = t * si * si + ZY[q][q] * co * co + 2.0 * ZY[p][q] * si * co; + + ZY[p][q] = 0.0; + + { + double R[MAX_DIM]; + + for (j = 0; j < dim; j++) { + T[j] = Sv[j][p]; + R[j] = Sv[j][q]; + } + + for (j = 0; j < dim; j++) { + Sv[j][p] = T[j] * co - R[j] * si; + Sv[j][q] = T[j] * si + R[j] * co; + } + } + + return(1); + +} + 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/cswinit.c b/src/spicelib/devices/csw/cswinit.c new file mode 100644 index 000000000..ee8d05852 --- /dev/null +++ b/src/spicelib/devices/csw/cswinit.c @@ -0,0 +1,67 @@ +/* Modified: 2000 AlansFixes */ + +#include + +#include + +#include "cswitf.h" +#include "cswext.h" +#include "cswinit.h" + + +SPICEdev CSWinfo = { + { + "CSwitch", + "Current controlled ideal switch", + + &CSWnSize, + &CSWnSize, + CSWnames, + + &CSWpTSize, + CSWpTable, + + &CSWmPTSize, + CSWmPTable, + 0 + }, + + DEVparam : CSWparam, + DEVmodParam : CSWmParam, + DEVload : CSWload, + DEVsetup : CSWsetup, + DEVunsetup : NULL, + DEVpzSetup : CSWsetup, + DEVtemperature: NULL, + DEVtrunc :CSWtrunc, + DEVfindBranch : NULL, + DEVacLoad : CSWacLoad, + DEVaccept : NULL, + DEVdestroy : CSWdestroy, + DEVmodDelete : CSWmDelete, + DEVdelete : CSWdelete, + DEVsetic : NULL, + DEVask : CSWask, + DEVmodAsk : CSWmAsk, + DEVpzLoad : CSWpzLoad, + DEVconvTest : NULL, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, /* DISTO */ + DEVnoise : CSWnoise, + + DEVinstSize : &CSWiSize, + DEVmodSize : &CSWmSize + +}; + + +SPICEdev * +get_csw_info(void) +{ + return &CSWinfo; +} diff --git a/src/spicelib/devices/csw/cswinit.h b/src/spicelib/devices/csw/cswinit.h new file mode 100644 index 000000000..aceb63379 --- /dev/null +++ b/src/spicelib/devices/csw/cswinit.h @@ -0,0 +1,13 @@ +#ifndef _CSWINIT_H +#define _CSWINIT_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; + +#endif 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/csw/cswtrunc.c b/src/spicelib/devices/csw/cswtrunc.c new file mode 100644 index 000000000..9a13a40bf --- /dev/null +++ b/src/spicelib/devices/csw/cswtrunc.c @@ -0,0 +1,50 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "sperror.h" +#include "suffix.h" + +#include "cswdefs.h" + +int +CSWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep) +{ + CSWmodel *model = (CSWmodel*)inModel; + CSWinstance *here; + + double lastChange, maxChange, maxStep, ref; + + for( ; model!= NULL; model = model->CSWnextModel) { + for(here = model->CSWinstances ; here != NULL ; + here = here->CSWnextInstance) { + lastChange = *(ckt->CKTstate0+(here->CSWstate+1)) - + *(ckt->CKTstate1+(here->CSWstate+1)); + if (*(ckt->CKTstate0+(here->CSWstate))==0) { + ref = (model->CSWiThreshold + model->CSWiHysteresis); + if ((*(ckt->CKTstate0+(here->CSWstate+1))0)) { + maxChange = (ref - *(ckt->CKTstate0+(here->CSWstate+1))) * + 0.75 + 0.00005; + maxStep = maxChange/lastChange * ckt->CKTdeltaOld[0]; + if (*timeStep > maxStep) { *timeStep = maxStep; } + } + } else { + ref = (model->CSWiThreshold - model->CSWiHysteresis); + if ((*(ckt->CKTstate0+(here->CSWstate+1))>ref) && (lastChange<0)) { + maxChange = (ref - *(ckt->CKTstate0+(here->CSWstate+1))) * + 0.75 - 0.00005; + maxStep = maxChange/lastChange * ckt->CKTdeltaOld[0]; + if (*timeStep > maxStep) { *timeStep = maxStep; } + } + } + } + } + return(OK); +} diff --git a/src/spicelib/devices/dev.c b/src/spicelib/devices/dev.c new file mode 100644 index 000000000..4c0f46ec1 --- /dev/null +++ b/src/spicelib/devices/dev.c @@ -0,0 +1,410 @@ +/* NG-SPICE -- An electrical circuit simulator + * + * Copyright (c) 1990 University of California + * Copyright (c) 2000 Arno W. Peters + * + * Permission to use, copy, modify, and distribute this software and + * its documentation without fee, and without a written agreement is + * hereby granted, provided that the above copyright notice, this + * paragraph and the following three paragraphs appear in all copies. + * + * This software program and documentation are copyrighted by their + * authors. The software program and documentation are supplied "as + * is", without any accompanying services from the authors. The + * authors do not warrant that the operation of the program will be + * uninterrupted or error-free. The end-user understands that the + * program was developed for research purposes and is advised not to + * rely exclusively on the program for any reason. + * + * IN NO EVENT SHALL THE AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, + * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING + * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS + * DOCUMENTATION, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. THE AUTHORS SPECIFICALLY DISCLAIMS ANY + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + * SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE AUTHORS + * HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, + * ENHANCEMENTS, OR MODIFICATIONS. */ + +#include +#include + +#include +#include + +#include "dev.h" +#include "memory.h" /* to alloc, realloc devices*/ + +#ifdef XSPICE +/*saj headers for xspice*/ +#include /* for strcpy, strcat*/ +#include /* to load librarys*/ +#include "dllitf.h" /* the coreInfo Structure*/ +#include "evtudn.h" /*Use defined nodes */ + +Evt_Udn_Info_t **g_evt_udn_info = NULL; +int g_evt_num_udn_types = 0; + +/*The digital node type */ +extern Evt_Udn_Info_t idn_digital_info; + +int add_udn(int,Evt_Udn_Info_t **); +/*saj*/ +#endif + +#define DEVICES_USED "asrc bjt bjt2 bsim1 bsim2 bsim3 bsim3v2 bsim3v1 bsim4 bsim3soipd bsim3soifd \ + bsim3soidd cap cccs ccvs csw dio hfet hfet2 ind isrc jfet ltra mes mesa mos1 \ + mos2 mos3 mos6 mos9 res soi3 sw tra urc vccs vcvs vsrc (ekv)" + + +/* + * 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 + +#define ANALYSES_USED "op dc tf ac tran pz disto noise sense" + + +#include "asrc/asrcitf.h" +#include "bjt/bjtitf.h" +/* #include "bjt2/bjt2itf.h" */ +#include "bsim1/bsim1itf.h" +#include "bsim2/bsim2itf.h" +#include "bsim3/bsim3itf.h" +#include "bsim3v1/bsim3v1itf.h" +#include "bsim3v2/bsim3v2itf.h" +#include "bsim4/bsim4itf.h" +#include "bsim3soi_pd/b3soipditf.h" +#include "bsim3soi_fd/b3soifditf.h" +#include "bsim3soi_dd/b3soidditf.h" +#include "cap/capitf.h" +#include "cccs/cccsitf.h" +#include "ccvs/ccvsitf.h" +#include "csw/cswitf.h" +#include "dio/dioitf.h" +#include "hfet1/hfetitf.h" +#include "hfet2/hfet2itf.h" +#include "ind/inditf.h" +#include "isrc/isrcitf.h" +#include "jfet/jfetitf.h" +#include "jfet2/jfet2itf.h" +#include "ltra/ltraitf.h" +#include "mes/mesitf.h" +#include "mesa/mesaitf.h" +#include "mos1/mos1itf.h" +#include "mos2/mos2itf.h" +#include "mos3/mos3itf.h" +#include "mos6/mos6itf.h" +#include "mos9/mos9itf.h" +#include "cpl/cplitf.h" +#include "res/resitf.h" +#include "soi3/soi3itf.h" +#include "sw/switf.h" +#include "tra/traitf.h" +#include "txl/txlitf.h" +#include "urc/urcitf.h" +#include "vccs/vccsitf.h" +#include "vcvs/vcvsitf.h" +#include "vsrc/vsrcitf.h" +/*saj in xspice the DEVices size can be varied so DEVNUM is an int*/ +#ifdef HAVE_EKV +#include "ekv/ekvitf.h" +#ifdef XSPICE +static int DEVNUM = 43; +#else +#define DEVNUM 43 +#endif +#else +#ifdef XSPICE +static int DEVNUM = 42; +#else +#define DEVNUM 42 +#endif +#endif + +/*Make this dynamic for later attempt to make all devices dynamic*/ +SPICEdev **DEVices=NULL; + +/*Flag to indicate that device type it is, + *0 = normal spice device + *1 = xspice device + */ +#ifdef XSPICE +int *DEVicesfl=NULL; +int DEVflag(int type){ + if(type < DEVNUM && type >= 0) + return DEVicesfl[type]; + else + return -1; +} +#endif + +void +spice_init_devices(void) +{ +#ifdef XSPICE + /*Initilise the structs and add digital node type */ + g_evt_udn_info = (Evt_Udn_Info_t **)MALLOC(sizeof(Evt_Udn_Info_t *)); + g_evt_num_udn_types = 1; + g_evt_udn_info[0] = &idn_digital_info; + + DEVicesfl = (int *)tmalloc(DEVNUM*sizeof(int)); + /* tmalloc should automaticlly zero the array! */ +#endif + + DEVices = (SPICEdev **)tmalloc(DEVNUM*sizeof(SPICEdev *)); + /* URC device MUST precede both resistors and capacitors */ + DEVices[ 0] = get_urc_info(); + DEVices[ 1] = get_asrc_info(); + DEVices[ 2] = get_bjt_info(); + DEVices[ 3] = get_bjt_info(); /* Quick hack until bjt2 works */ + /* DEVices[ 3] = get bjt2_info(); */ + DEVices[ 4] = get_bsim1_info(); + DEVices[ 5] = get_bsim2_info(); + DEVices[ 6] = get_bsim3_info(); + DEVices[ 7] = get_bsim3v1_info(); + DEVices[ 8] = get_bsim3v2_info(); + DEVices[ 9] = get_bsim4_info(); + DEVices[10] = get_bsim3soipd_info(); + DEVices[11] = get_bsim3soifd_info(); + DEVices[12] = get_bsim3soidd_info(); + DEVices[13] = get_cap_info(); + DEVices[14] = get_cccs_info(); + DEVices[15] = get_ccvs_info(); + DEVices[16] = get_cpl_info(); + DEVices[17] = get_csw_info(); + DEVices[18] = get_dio_info(); + DEVices[19] = get_hfeta_info(); + DEVices[20] = get_hfet2_info(); + DEVices[21] = get_ind_info(); + DEVices[22] = get_mut_info(); + DEVices[23] = get_isrc_info(); + DEVices[24] = get_jfet_info(); + DEVices[25] = get_jfet2_info(); + DEVices[26] = get_ltra_info(); + DEVices[27] = get_mes_info(); + DEVices[28] = get_mesa_info(); + DEVices[29] = get_mos1_info(); + DEVices[30] = get_mos2_info(); + DEVices[31] = get_mos3_info(); + DEVices[32] = get_mos6_info(); + DEVices[33] = get_mos9_info(); + DEVices[34] = get_res_info(); + DEVices[35] = get_soi3_info(); + DEVices[36] = get_sw_info(); + DEVices[37] = get_tra_info(); + DEVices[38] = get_txl_info(); + DEVices[39] = get_vccs_info(); + DEVices[40] = get_vcvs_info(); + DEVices[41] = get_vsrc_info(); +#ifdef HAVE_EKV + DEVices[42] = get_ekv_info(); + assert(43 == DEVNUM); +#else + assert(42 == DEVNUM); +#endif + return; +} + +int +num_devices(void) +{ + return DEVNUM; +} + + +IFdevice ** +devices_ptr(void) +{ + return (IFdevice **) DEVices; +} + + +SPICEdev ** +devices(void) +{ + return DEVices; +} + +#ifdef DEVLIB +/*not yet usable*/ +#ifdef HAVE_EKV +#define DEVICES_USED {"asrc", "bjt", "bjt2", "bsim1", "bsim2", "bsim3", "bsim3v2", "bsim3v1", "bsim4", "bsim3soipd", "bsim3soifd", \ + "bsim3soidd", "cap", "cccs", "ccvs", "csw", "dio", "hfet", "hfet2", "ind", "isrc", "jfet", "ltra", "mes", "mesa" ,"mos1", \ + "mos2", "mos3", "mos6", "mos9", "res", "soi3", "sw", "tra", "urc", "vccs", "vcvs", "vsrc", "ekv" } +#else +#define DEVICES_USED {"asrc", "bjt", "bjt2", "bsim1", "bsim2", "bsim3", "bsim3v2", "bsim3v1", "bsim4", "bsim3soipd", "bsim3soifd", \ + "bsim3soidd", "cap", "cccs", "ccvs", "csw", "dio", "hfet", "hfet2", "ind", "isrc", "jfet", "ltra", "mes", "mesa" ,"mos1", \ + "mos2", "mos3", "mos6", "mos9", "res", "soi3", "sw", "tra", "urc", "vccs", "vcvs", "vsrc"} +#endif +int load_dev(char *name) { + char *msg; + char libname[50]; + void *lib; + SPICEdev *(*fetch)(void)=NULL; + SPICEdev *device; + + strcpy(libname, "lib"); + strcat(libname,name); + strcat(libname,".so"); + + lib = dlopen(libname,RTLD_NOW); + if(!lib){ + msg = dlerror(); + printf("%s\n", msg); + return 1; + } + + strcpy(libname, "get_"); + strcat(libname,name); + strcat(libname,"_info"); + fetch = dlsym(lib,libname); + + if(!fetch){ + msg = dlerror(); + printf("%s\n", msg); + return 1; + } + device = fetch(); + add_device(1,&device,0); + return 0; +} + +void load_alldevs(void){ + char *devs[] = DEVICES_USED; + int num = sizeof(devs)/sizeof(char *); + int i; + for(i=0; i< num;i++) + load_dev(devs[i]); + return; +} +#endif + + +#ifdef XSPICE +#include +#include +#include +#include /*for ft_sim*/ +#include /*for DEVmaxnum*/ + +static void relink() { + ft_sim->numDevices = num_devices(); + DEVmaxnum = num_devices(); + ft_sim->devices = devices_ptr(); + return; +} + +int add_device(int n, SPICEdev **devs, int flag){ + int i; + DEVices = (SPICEdev **)trealloc(DEVices,(DEVNUM+n)*sizeof(SPICEdev *)); + DEVicesfl = (int *)trealloc(DEVicesfl,(DEVNUM+n)*sizeof(int)); + for(i = 0; i < n;i++){ + /*debug*/printf("Added device: %s\n",devs[i]->DEVpublic.name); + DEVices[DEVNUM+i] = devs[i]; + DEVicesfl[DEVNUM+i] = flag; + } + DEVNUM += n; + relink(); + return 0; +} + +int add_udn(int n,Evt_Udn_Info_t **udns){ + int i; + g_evt_udn_info = (Evt_Udn_Info_t **)trealloc(g_evt_udn_info,(g_evt_num_udn_types+n)*sizeof(Evt_Udn_Info_t *)); + for(i = 0; i < n;i++){ + /*debug*/printf("Added udn: %s\n",udns[i]->name); + g_evt_udn_info[g_evt_num_udn_types+i] = udns[i]; + } + g_evt_num_udn_types += n; + return 0; +} + + +extern struct coreInfo_t coreInfo; + + +int load_opus(char *name){ + void *lib; + char *msg; + int *num=NULL; + struct coreInfo_t **core; + SPICEdev **devs; + Evt_Udn_Info_t **udns; + void *(*fetch)(void)=NULL; + + lib = dlopen(name,RTLD_NOW); + if(!lib){ + msg = dlerror(); + printf("%s\n", msg); + return 1; + } + + fetch = dlsym(lib,"CMdevNum"); + if(fetch){ + num = (int *)(*fetch)(); + printf("Got %u devices.\n",*num); + fetch = NULL; + }else{ + msg = dlerror(); + printf("%s\n", msg); + return 1; + } + + fetch = dlsym(lib,"CMdevs"); + if(fetch){ + devs = (SPICEdev **)(*fetch)(); + fetch = NULL; + }else{ + msg = dlerror(); + printf("%s\n", msg); + return 1; + } + + fetch = dlsym(lib,"CMgetCoreItfPtr"); + if(fetch){ + core = (struct coreInfo_t **)(*fetch)(); + *core = &coreInfo; + fetch = NULL; + }else{ + msg = dlerror(); + printf("%s\n", msg); + return 1; + } + add_device(*num,devs,1); + + fetch = dlsym(lib,"CMudnNum"); + if(fetch){ + num = (int *)(*fetch)(); + printf("Got %u udns.\n",*num); + fetch = NULL; + }else{ + msg = dlerror(); + printf("%s\n", msg); + return 1; + } + + fetch = dlsym(lib,"CMudns"); + if(fetch){ + udns = (Evt_Udn_Info_t **)(*fetch)(); + fetch = NULL; + }else{ + msg = dlerror(); + printf("%s\n", msg); + return 1; + } + + add_udn(*num,udns); + + return 0; +} +#endif diff --git a/src/spicelib/devices/dev.h b/src/spicelib/devices/dev.h new file mode 100644 index 000000000..be6a07b03 --- /dev/null +++ b/src/spicelib/devices/dev.h @@ -0,0 +1,18 @@ +#ifndef _DEV_H +#define _DEV_H + + +void spice_init_devices(void); +int num_devices(void); +IFdevice **devices_ptr(void); +SPICEdev **devices(void); +#ifdef XSPICE +int load_opus(char *); +int DEVflag(int type); +#endif +#ifdef DEVLIB +void load_alldevs(void); +int load_dev(char *name); +#endif +#endif + diff --git a/src/spicelib/devices/devsup.c b/src/spicelib/devices/devsup.c new file mode 100644 index 000000000..c6d47125b --- /dev/null +++ b/src/spicelib/devices/devsup.c @@ -0,0 +1,311 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes +**********/ + +/* support routines for device models */ + +#include "ngspice.h" +#include "devdefs.h" +#include "cktdefs.h" +#include "suffix.h" + +/* limit the per-iteration change of VDS */ +double +DEVlimvds(double vnew, + double vold) +{ + + if(vold >= 3.5) { + if(vnew > vold) { + vnew = MIN(vnew,(3 * vold) +2); + } else { + if (vnew < 3.5) { + vnew = MAX(vnew,2); + } + } + } else { + if(vnew > vold) { + vnew = MIN(vnew,4); + } else { + vnew = MAX(vnew,-.5); + } + } + return(vnew); +} + + +/* limit the per-iteration change of PN junction voltages */ +double +DEVpnjlim(double vnew, + double vold, + double vt, + double vcrit, + int *icheck) +{ + double arg; + + if((vnew > vcrit) && (fabs(vnew - vold) > (vt + vt))) { + if(vold > 0) { + arg = (vnew - vold) / vt; + if(arg > 0) { + vnew = vold + vt * (2+log(arg-2)); + } else { + vnew = vold - vt * (2+log(2-arg)); + } + } else { + vnew = vt *log(vnew/vt); + } + *icheck = 1; + } else { + if (vnew < 0) { + if (vold > 0) { + arg = -1*vold-1; + } else { + arg = 2*vold-1; + } + if (vnew < arg) { + vnew = arg; + *icheck = 1; + } else { + *icheck = 0; + }; + } else { + *icheck = 0; + } + } + return(vnew); +} + +/* limit the per-iteration change of FET voltages */ +double +DEVfetlim(double vnew, + double vold, + double vto) +{ + double vtsthi; + double vtstlo; + double vtox; + double delv; + double vtemp; + + vtsthi = fabs(2*(vold-vto))+2; + vtstlo = fabs(vold-vto)+1; + vtox = vto + 3.5; + delv = vnew-vold; + + if (vold >= vto) { + if(vold >= vtox) { + if(delv <= 0) { + /* going off */ + if(vnew >= vtox) { + if(-delv >vtstlo) { + vnew = vold - vtstlo; + } + } else { + vnew = MAX(vnew,vto+2); + } + } else { + /* staying on */ + if(delv >= vtsthi) { + vnew = vold + vtsthi; + } + } + } else { + /* middle region */ + if(delv <= 0) { + /* decreasing */ + vnew = MAX(vnew,vto-.5); + } else { + /* increasing */ + vnew = MIN(vnew,vto+4); + } + } + } else { + /* off */ + if(delv <= 0) { + if(-delv >vtsthi) { + vnew = vold - vtsthi; + } + } else { + vtemp = vto + .5; + if(vnew <= vtemp) { + if(delv >vtstlo) { + vnew = vold + vtstlo; + } + } else { + vnew = vtemp; + } + } + } + return(vnew); +} + + +/* Compute the MOS overlap capacitances as functions of the device + * terminal voltages */ +void +DEVcmeyer(double vgs0, /* initial voltage gate-source */ + double vgd0, /* initial voltage gate-drain */ + double vgb0, /* initial voltage gate-bulk */ + double von0, + double vdsat0, + double vgs1, /* final voltage gate-source */ + double vgd1, /* final voltage gate-drain */ + double vgb1, /* final voltage gate-bulk */ + double covlgs, /* overlap capacitance gate-source */ + double covlgd, /* overlap capacitance gate-drain */ + double covlgb, /* overlap capacitance gate-bulk */ + double *cgs, + double *cgd, + double *cgb, + double phi, + double cox, + double von, + double vdsat) +{ + + + double vdb; + double vdbsat; + double vddif; + double vddif1; + double vddif2; + double vgbt; + + *cgs = 0; + *cgd = 0; + *cgb = 0; + + vgbt = vgs1-von; + if (vgbt <= -phi) { + *cgb = cox; + } else if (vgbt <= -phi/2) { + *cgb = -vgbt*cox/phi; + } else if (vgbt <= 0) { + *cgb = -vgbt*cox/phi; + *cgs = cox/(7.5e-1*phi)*vgbt+cox/1.5; + } else { + vdbsat = vdsat-(vgs1-vgb1); + vdb = vgb1-vgd1; + if (vdbsat <= vdb) { + *cgs = cox/1.5; + } else { + vddif = 2.0*vdbsat-vdb; + vddif1 = vdbsat-vdb-1.0e-12; + vddif2 = vddif*vddif; + *cgd = cox*(1.0-vdbsat*vdbsat/vddif2)/1.5; + *cgs = cox*(1.0-vddif1*vddif1/vddif2)/1.5; + } + } + + vgbt = vgs0-von0; + if (vgbt <= -phi) { + *cgb += cox; + } else if (vgbt <= -phi/2) { + *cgb += -vgbt*cox/phi; + } else if (vgbt <= 0) { + *cgb += -vgbt*cox/phi; + *cgs += cox/(7.5e-1*phi)*vgbt+cox/1.5; + } else { + vdbsat = vdsat0-(vgs0-vgb0); + vdb = vgb0-vgd0; + if (vdbsat <= vdb) { + *cgs += cox/1.5; + } else { + vddif = 2.0*vdbsat-vdb; + vddif1 = vdbsat-vdb-1.0e-12; + vddif2 = vddif*vddif; + *cgd += cox*(1.0-vdbsat*vdbsat/vddif2)/1.5; + *cgs += cox*(1.0-vddif1*vddif1/vddif2)/1.5; + } + } + + *cgs = *cgs *.5 + covlgs; + *cgd = *cgd *.5 + covlgd; + *cgb = *cgb *.5 + covlgb; +} + + +/* Compute the MOS overlap capacitances as functions of the device + * terminal voltages */ +void +DEVqmeyer(double vgs, /* initial voltage gate-source */ + double vgd, /* initial voltage gate-drain */ + double vgb, /* initial voltage gate-bulk */ + double von, + double vdsat, + double *capgs, /* non-constant portion of g-s overlap + capacitance */ + double *capgd, /* non-constant portion of g-d overlap + capacitance */ + double *capgb, /* non-constant portion of g-b overlap + capacitance */ + double phi, + double cox) /* oxide capactiance */ +{ + double vds; + double vddif; + double vddif1; + double vddif2; + double vgst; + +#define MAGIC_VDS 0.025 + + vgst = vgs-von; + vdsat = MAX(vdsat, MAGIC_VDS); + if (vgst <= -phi) { + *capgb = cox/2; + *capgs = 0; + *capgd = 0; + } else if (vgst <= -phi/2) { + *capgb = -vgst*cox/(2*phi); + *capgs = 0; + *capgd = 0; + } else if (vgst <= 0) { + *capgb = -vgst*cox/(2*phi); + *capgs = vgst*cox/(1.5*phi)+cox/3; + vds = vgs-vgd; + if (vds>=vdsat) { + *capgd = 0; + } else { + vddif = 2.0*vdsat-vds; + vddif1 = vdsat-vds/*-1.0e-12*/; + vddif2 = vddif*vddif; + *capgd = *capgs*(1.0-vdsat*vdsat/vddif2); + *capgs = *capgs*(1.0-vddif1*vddif1/vddif2); + } + } else { + vds = vgs-vgd; + vdsat = MAX(vdsat, MAGIC_VDS); + if (vdsat <= vds) { + *capgs = cox/3; + *capgd = 0; + *capgb = 0; + } else { + vddif = 2.0*vdsat-vds; + vddif1 = vdsat-vds/*-1.0e-12*/; + vddif2 = vddif*vddif; + *capgd = cox*(1.0-vdsat*vdsat/vddif2)/3; + *capgs = cox*(1.0-vddif1*vddif1/vddif2)/3; + *capgb = 0; + } + } + +} + + +/* Predict a value for the capacitor at loct by extrapolating from + * previous values */ +double +DEVpred(CKTcircuit *ckt, int loct) +{ +#ifndef NEWTRUNC + double xfact; + + xfact = ckt->CKTdelta/ckt->CKTdeltaOld[1]; + return( ( (1+xfact) * *(ckt->CKTstate1+loct) ) - + ( xfact * *(ckt->CKTstate2+loct) ) ); +#endif /* NEWTRUNC */ +} 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/dioinit.c b/src/spicelib/devices/dio/dioinit.c new file mode 100644 index 000000000..b1d673ac8 --- /dev/null +++ b/src/spicelib/devices/dio/dioinit.c @@ -0,0 +1,66 @@ +#include + +#include +#include + +#include "diodefs.h" +#include "dioitf.h" +#include "dioext.h" +#include "dioinit.h" + + +SPICEdev DIOinfo = { + { + "Diode", + "Junction Diode model", + + &DIOnSize, + &DIOnSize, + DIOnames, + + &DIOpTSize, + DIOpTable, + + &DIOmPTSize, + DIOmPTable, + DEV_DEFAULT + }, + + DEVparam : DIOparam, + DEVmodParam : DIOmParam, + DEVload : DIOload, + DEVsetup : DIOsetup, + DEVunsetup : DIOunsetup, + DEVpzSetup : DIOsetup, + DEVtemperature: DIOtemp, + DEVtrunc : DIOtrunc, + DEVfindBranch : NULL, + DEVacLoad : DIOacLoad, + DEVaccept : NULL, + DEVdestroy : DIOdestroy, + DEVmodDelete : DIOmDelete, + DEVdelete : DIOdelete, + DEVsetic : DIOgetic, + DEVask : DIOask, + DEVmodAsk : DIOmAsk, + DEVpzLoad : DIOpzLoad, + DEVconvTest : DIOconvTest, + DEVsenSetup : DIOsSetup, + DEVsenLoad : DIOsLoad, + DEVsenUpdate : DIOsUpdate, + DEVsenAcLoad : DIOsAcLoad, + DEVsenPrint : DIOsPrint, + DEVsenTrunc : NULL, + DEVdisto : DIOdisto, + DEVnoise : DIOnoise, + + DEVinstSize : &DIOiSize, + DEVmodSize : &DIOmSize +}; + + +SPICEdev * +get_dio_info(void) +{ + return &DIOinfo; +} diff --git a/src/spicelib/devices/dio/dioinit.h b/src/spicelib/devices/dio/dioinit.h new file mode 100644 index 000000000..3bb1b80ee --- /dev/null +++ b/src/spicelib/devices/dio/dioinit.h @@ -0,0 +1,13 @@ +#ifndef _DIOINIT_H +#define _DIOINIT_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; + +#endif 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/hfet1/Makefile.am b/src/spicelib/devices/hfet1/Makefile.am new file mode 100644 index 000000000..8d5ba5c2a --- /dev/null +++ b/src/spicelib/devices/hfet1/Makefile.am @@ -0,0 +1,29 @@ +## Process this file with automake to produce Makefile.in + +pkglib_LTLIBRARIES = libhfet.la + +libhfet_la_SOURCES = \ + hfet.c \ + hfetacl.c \ + hfetask.c \ + hfetdefs.h \ + hfetdel.c \ + hfetdest.c \ + hfetext.h \ + hfetgetic.c \ + hfetinit.c \ + hfetinit.h \ + hfetitf.h \ + hfetload.c \ + hfetmask.c \ + hfetmdel.c \ + hfetmpar.c \ + hfetparam.c \ + hfetsetup.c \ + hfettemp.c \ + hfettrunc.c + + + +INCLUDES = -I$(top_srcdir)/src/include +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/hfet1/hfet.c b/src/spicelib/devices/hfet1/hfet.c new file mode 100644 index 000000000..9453412dc --- /dev/null +++ b/src/spicelib/devices/hfet1/hfet.c @@ -0,0 +1,120 @@ +#include "ngspice.h" +#include +#include "ifsim.h" +#include "devdefs.h" +#include "hfetdefs.h" +#include "suffix.h" + + +IFparm HFETApTable[] = { /* parameters */ + OP("off", HFETA_OFF, IF_FLAG ,"Device initially off"), + IOP("l", HFETA_LENGTH, IF_REAL ,"Length of device"), + IOP("w", HFETA_WIDTH, IF_REAL ,"Width of device"), + IOP("icvds", HFETA_IC_VDS, IF_REAL ,"Initial D-S voltage"), + IOP("icvgs", HFETA_IC_VGS, IF_REAL ,"Initial G-S voltage"), + IOP("temp", HFETA_TEMP, IF_REAL ,"Instance temperature"), + OP("dnode", HFETA_DRAINNODE, IF_INTEGER,"Number of drain node"), + OP("gnode", HFETA_GATENODE, IF_INTEGER,"Number of gate node"), + OP("snode", HFETA_SOURCENODE, IF_INTEGER,"Number of source node"), + OP("dprimenode",HFETA_DRAINPRIMENODE, IF_INTEGER,"Number of internal drain node"), + OP("sprimenode",HFETA_SOURCEPRIMENODE,IF_INTEGER,"Number of internal source node"), + OP("vgs", HFETA_VGS, IF_REAL,"Gate-Source voltage"), + OP("vgd", HFETA_VGD, IF_REAL,"Gate-Drain voltage"), + OP("cg", HFETA_CG, IF_REAL,"Gate capacitance"), + OP("cd", HFETA_CD, IF_REAL,"Drain capacitance"), + OP("cgd", HFETA_CGD, IF_REAL,"Gate_Drain capacitance"), + OP("gm", HFETA_GM, IF_REAL,"Transconductance"), + OP("gds", HFETA_GDS, IF_REAL,"Drain-Source conductance"), + OP("ggs", HFETA_GGS, IF_REAL,"Gate-Source conductance"), + OP("ggd", HFETA_GGD, IF_REAL,"Gate-Drain conductance"), + OP("qgs", HFETA_QGS, IF_REAL,"Gate-Source charge storage"), + OP("cqgs", HFETA_CQGS, IF_REAL,"Capacitance due to gate-source charge storage"), + OP("qgd", HFETA_QGD, IF_REAL,"Gate-Drain charge storage"), + OP("cqgd", HFETA_CQGD, IF_REAL,"Capacitance due to gate-drain charge storage"), + OP("cs", HFETA_CS, IF_REAL ,"Source current"), + OP("p", HFETA_POWER, IF_REAL ,"Power dissipated by the mesfet") + +}; + +IFparm HFETAmPTable[] = { /* model parameters */ + IOP( "vt0", HFETA_MOD_VTO, IF_REAL,"Pinch-off voltage"), + IOP( "vto", HFETA_MOD_VTO, IF_REAL,"Pinch-off voltage"), + IOP( "lambda", HFETA_MOD_LAMBDA, IF_REAL,"Output conductance parameter"), + IOP( "rd", HFETA_MOD_RD, IF_REAL,"Drain ohmic resistance"), + IOP( "rs", HFETA_MOD_RS, IF_REAL,"Source ohmic resistance"), + IOP( "rg", HFETA_MOD_RG, IF_REAL,"Gate ohmic resistance"), + IOP( "rdi", HFETA_MOD_RDI, IF_REAL,"Drain ohmic resistance"), + IOP( "rsi", HFETA_MOD_RSI, IF_REAL,"Source ohmic resistance"), + IOP( "rgs", HFETA_MOD_RGS, IF_REAL,"Gate-source ohmic resistance"), + IOP( "rgd", HFETA_MOD_RGD, IF_REAL,"Gate-drain ohmic resistance"), + IOP( "ri", HFETA_MOD_RI, IF_REAL,""), + IOP( "rf", HFETA_MOD_RF, IF_REAL,""), + IOP( "eta", HFETA_MOD_ETA, IF_REAL,"Subthreshold ideality factor"), + IOP( "m", HFETA_MOD_M, IF_REAL,"Knee shape parameter"), + IOP( "mc", HFETA_MOD_MC, IF_REAL,"Knee shape parameter"), + IOP( "gamma", HFETA_MOD_GAMMA, IF_REAL,"Knee shape parameter"), + IOP( "sigma0", HFETA_MOD_SIGMA0, IF_REAL,"Threshold voltage coefficient"), + IOP( "vsigmat", HFETA_MOD_VSIGMAT,IF_REAL,""), + IOP( "vsigma", HFETA_MOD_VSIGMA, IF_REAL,""), + IOP( "mu", HFETA_MOD_MU, IF_REAL,"Moblity"), + IOP( "di", HFETA_MOD_DI, IF_REAL,"Depth of device"), + IOP( "delta", HFETA_MOD_DELTA, IF_REAL,""), + IOP( "vs", HFETA_MOD_VS, IF_REAL,"Saturation velocity"), + IOP( "nmax", HFETA_MOD_NMAX, IF_REAL,""), + IOP( "deltad", HFETA_MOD_DELTAD, IF_REAL,"Thickness correction"), + IOP( "js1d", HFETA_MOD_JS1D, IF_REAL,""), + IOP( "js2d", HFETA_MOD_JS2D, IF_REAL,""), + IOP( "js1s", HFETA_MOD_JS1S, IF_REAL,""), + IOP( "js2s", HFETA_MOD_JS2S, IF_REAL,""), + IOP( "m1d", HFETA_MOD_M1D, IF_REAL,""), + IOP( "m2d", HFETA_MOD_M2D, IF_REAL,""), + IOP( "m1s", HFETA_MOD_M1S, IF_REAL,""), + IOP( "m2s", HFETA_MOD_M2S, IF_REAL,""), + IOP( "epsi", HFETA_MOD_EPSI, IF_REAL,""), + IOP( "p", HFETA_MOD_P, IF_REAL,""), + IOP( "cm3", HFETA_MOD_CM3, IF_REAL,""), + IOP( "a1", HFETA_MOD_A1, IF_REAL,""), + IOP( "a2", HFETA_MOD_A2, IF_REAL,""), + IOP( "mv1", HFETA_MOD_MV1, IF_REAL,""), + IOP( "kappa", HFETA_MOD_KAPPA, IF_REAL,""), + IOP( "delf", HFETA_MOD_DELF, IF_REAL,""), + IOP( "fgds", HFETA_MOD_FGDS, IF_REAL,""), + IOP( "tf", HFETA_MOD_TF, IF_REAL,""), + IOP( "cds", HFETA_MOD_CDS, IF_REAL,""), + IOP( "phib", HFETA_MOD_PHIB, IF_REAL,""), + IOP( "talpha", HFETA_MOD_TALPHA, IF_REAL,""), + IOP( "mt1", HFETA_MOD_MT1, IF_REAL,""), + IOP( "mt2", HFETA_MOD_MT2, IF_REAL,""), + IOP( "ck1", HFETA_MOD_CK1, IF_REAL,""), + IOP( "ck2", HFETA_MOD_CK2, IF_REAL,""), + IOP( "cm1", HFETA_MOD_CM1, IF_REAL,""), + IOP( "cm2", HFETA_MOD_CM2, IF_REAL,""), + IOP( "astar", HFETA_MOD_ASTAR, IF_REAL,""), + IOP( "eta1", HFETA_MOD_ETA1, IF_REAL,""), + IOP( "d1", HFETA_MOD_D1, IF_REAL,""), + IOP( "vt1", HFETA_MOD_VT1, IF_REAL,""), + IOP( "eta2", HFETA_MOD_ETA2, IF_REAL,""), + IOP( "d2", HFETA_MOD_D2, IF_REAL,""), + IOP( "vt2", HFETA_MOD_VT2, IF_REAL,""), + IOP( "ggr", HFETA_MOD_GGR, IF_REAL,""), + IOP( "del", HFETA_MOD_DEL, IF_REAL,""), + IOP( "gatemod", HFETA_MOD_GATEMOD,IF_INTEGER,""), + IOP( "klambda", HFETA_MOD_KLAMBDA, IF_REAL,""), + IOP( "kmu", HFETA_MOD_KMU, IF_REAL,""), + IOP( "kvto", HFETA_MOD_KVTO, IF_REAL,""), + OP( "type", HFETA_MOD_TYPE, IF_STRING, "NHFET or PHFET"), + IOP( "nhfet", HFETA_MOD_NHFET, IF_FLAG,"N HFET device"), + IOP( "phfet", HFETA_MOD_PHFET, IF_FLAG,"P HFET device"), +}; + +char *HFETAnames[] = { + "Drain", + "Gate", + "Source" +}; + +int HFETAnSize = NUMELEMS(HFETAnames); +int HFETApTSize = NUMELEMS(HFETApTable); +int HFETAmPTSize = NUMELEMS(HFETAmPTable); +int HFETAiSize = sizeof(HFETAinstance); +int HFETAmSize = sizeof(HFETAmodel); diff --git a/src/spicelib/devices/hfet1/hfetacl.c b/src/spicelib/devices/hfet1/hfetacl.c new file mode 100644 index 000000000..859c87f56 --- /dev/null +++ b/src/spicelib/devices/hfet1/hfetacl.c @@ -0,0 +1,88 @@ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "hfetdefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +HFETAacLoad(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + HFETAmodel *model = (HFETAmodel*)inModel; + HFETAinstance *here; + double gm; + double gds; + double xds; + double ggs; + double xgs; + double ggd; + double xgd; + double ggspp; + double ggdpp; + double f; + + for( ; model != NULL; model = model->HFETAnextModel ) + { + for( here = model->HFETAinstances; here != NULL; + here = here->HFETAnextInstance) + { + gm = *(ckt->CKTstate0 + here->HFETAgm); + gds = *(ckt->CKTstate0 + here->HFETAgds); + xds = CDS*ckt->CKTomega; + ggs = *(ckt->CKTstate0 + here->HFETAggs); + xgs = *(ckt->CKTstate0 + here->HFETAqgs) * ckt->CKTomega; + ggd = *(ckt->CKTstate0 + here->HFETAggd); + xgd = *(ckt->CKTstate0 + here->HFETAqgd) * ckt->CKTomega; + ggspp = *(ckt->CKTstate0 + here->HFETAggspp); + ggdpp = *(ckt->CKTstate0 + here->HFETAggdpp); + if(model->HFETAkappaGiven && here->HFETAdelf != 0.0) { + f = ckt->CKTomega/2/M_PI; + gds = gds*(1+0.5*model->HFETAkappa*(1+tanh((f-here->HFETAfgds)/here->HFETAdelf))); + } + *(here->HFETAdrainDrainPtr) += model->HFETAdrainConduct; + *(here->HFETAsourceSourcePtr) += model->HFETAsourceConduct; + *(here->HFETAgatePrimeGatePrimePtr) += (ggd+ggs+ggspp+ggdpp+model->HFETAgateConduct); + *(here->HFETAdrainPrimeDrainPrimePtr) += (gds+ggd+model->HFETAdrainConduct+model->HFETAgf); + *(here->HFETAsourcePrimeSourcePrimePtr) += (gds+gm+ggs+model->HFETAsourceConduct+model->HFETAgi); + *(here->HFETAsourcePrmPrmSourcePrmPrmPtr) += (model->HFETAgi+ggspp); + *(here->HFETAdrainPrmPrmDrainPrmPrmPtr) += (model->HFETAgf+ggdpp); + *(here->HFETAdrainDrainPrimePtr) -= model->HFETAdrainConduct; + *(here->HFETAdrainPrimeDrainPtr) -= model->HFETAdrainConduct; + *(here->HFETAsourceSourcePrimePtr) -= model->HFETAsourceConduct; + *(here->HFETAsourcePrimeSourcePtr) -= model->HFETAsourceConduct; + *(here->HFETAgatePrimeDrainPrimePtr) -= ggd; + *(here->HFETAdrainPrimeGatePrimePtr) += (gm-ggd); + *(here->HFETAgatePrimeSourcePrimePtr) -= ggs; + *(here->HFETAsourcePrimeGatePrimePtr) += (-ggs-gm); + *(here->HFETAdrainPrimeSourcePrimePtr) += (-gds-gm); + *(here->HFETAsourcePrimeDrainPrimePtr) -= gds; + *(here->HFETAsourcePrimeSourcePrmPrmPtr) -= model->HFETAgi; + *(here->HFETAsourcePrmPrmSourcePrimePtr) -= model->HFETAgi; + *(here->HFETAgatePrimeSourcePrmPrmPtr) -= ggspp; + *(here->HFETAsourcePrmPrmGatePrimePtr) -= ggspp; + *(here->HFETAdrainPrimeDrainPrmPrmPtr) -= model->HFETAgf; + *(here->HFETAdrainPrmPrmDrainPrimePtr) -= model->HFETAgf; + *(here->HFETAgatePrimeDrainPrmPrmPtr) -= ggdpp; + *(here->HFETAdrainPrmPrmGatePrimePtr) -= ggdpp; + *(here->HFETAgateGatePtr) += model->HFETAgateConduct; + *(here->HFETAgateGatePrimePtr) -= model->HFETAgateConduct; + *(here->HFETAgatePrimeGatePtr) -= model->HFETAgateConduct; + *(here->HFETAgatePrimeGatePrimePtr+1) += xgd+xgs; + *(here->HFETAdrainPrmPrmDrainPrmPrmPtr+1) += xgd; + *(here->HFETAsourcePrmPrmSourcePrmPrmPtr+1) += xgs; + *(here->HFETAgatePrimeDrainPrmPrmPtr+1) -= xgd; + *(here->HFETAgatePrimeSourcePrmPrmPtr+1) -= xgs; + *(here->HFETAdrainPrmPrmGatePrimePtr+1) -= xgd; + *(here->HFETAsourcePrmPrmGatePrimePtr+1) -= xgs; + *(here->HFETAdrainPrimeDrainPrimePtr+1) += xds; + *(here->HFETAsourcePrimeSourcePrimePtr+1) += xds; + *(here->HFETAdrainPrimeSourcePrimePtr+1) -= xds; + *(here->HFETAsourcePrimeDrainPrimePtr+1) -= xds; + } + } + return(OK); +} diff --git a/src/spicelib/devices/hfet1/hfetask.c b/src/spicelib/devices/hfet1/hfetask.c new file mode 100644 index 000000000..0aa7d9822 --- /dev/null +++ b/src/spicelib/devices/hfet1/hfetask.c @@ -0,0 +1,132 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Thomas L. Quarles +**********/ +/* +Imported into HFETA source: Paolo Nenzi 2001 + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "devdefs.h" +#include "ifsim.h" +#include "hfetdefs.h" +#include "sperror.h" +#include "suffix.h" + + +/* ARGSUSED */ +int +HFETAask(ckt,inst,which,value,select) + CKTcircuit *ckt; + GENinstance *inst; + int which; + IFvalue *value; + IFvalue *select; +{ + HFETAinstance *here = (HFETAinstance*)inst; + static char *msg = "Current and power not available in ac analysis"; + switch(which) { + case HFETA_LENGTH: + value->rValue = here->HFETAlength; + return (OK); + case HFETA_WIDTH: + value->rValue = here->HFETAwidth; + case HFETA_IC_VDS: + value->rValue = here->HFETAicVDS; + return (OK); + case HFETA_IC_VGS: + value->rValue = here->HFETAicVGS; + return (OK); + case HFETA_OFF: + value->iValue = here->HFETAoff; + return (OK); + case HFETA_DRAINNODE: + value->iValue = here->HFETAdrainNode; + return (OK); + case HFETA_GATENODE: + value->iValue = here->HFETAgateNode; + return (OK); + case HFETA_SOURCENODE: + value->iValue = here->HFETAsourceNode; + return (OK); + case HFETA_DRAINPRIMENODE: + value->iValue = here->HFETAdrainPrimeNode; + return (OK); + case HFETA_SOURCEPRIMENODE: + value->iValue = here->HFETAsourcePrimeNode; + return (OK); + case HFETA_TEMP: + value->rValue = here->HFETAtemp; + case HFETA_VGS: + value->rValue = *(ckt->CKTstate0 + here->HFETAvgs); + return (OK); + case HFETA_VGD: + value->rValue = *(ckt->CKTstate0 + here->HFETAvgd); + return (OK); + case HFETA_CG: + value->rValue = *(ckt->CKTstate0 + here->HFETAcg); + return (OK); + case HFETA_CD: + value->rValue = *(ckt->CKTstate0 + here->HFETAcd); + return (OK); + case HFETA_CGD: + value->rValue = *(ckt->CKTstate0 + here->HFETAcgd); + return (OK); + case HFETA_GM: + value->rValue = *(ckt->CKTstate0 + here->HFETAgm); + return (OK); + case HFETA_GDS: + value->rValue = *(ckt->CKTstate0 + here->HFETAgds); + return (OK); + case HFETA_GGS: + value->rValue = *(ckt->CKTstate0 + here->HFETAggs); + return (OK); + case HFETA_GGD: + value->rValue = *(ckt->CKTstate0 + here->HFETAggd); + return (OK); + case HFETA_QGS: + value->rValue = *(ckt->CKTstate0 + here->HFETAqgs); + return (OK); + case HFETA_CQGS: + value->rValue = *(ckt->CKTstate0 + here->HFETAcqgs); + return (OK); + case HFETA_QGD: + value->rValue = *(ckt->CKTstate0 + here->HFETAqgd); + return (OK); + case HFETA_CQGD: + value->rValue = *(ckt->CKTstate0 + here->HFETAcqgd); + return (OK); + case HFETA_CS : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = MALLOC(strlen(msg)+1); + errRtn = "HFETAask"; + strcpy(errMsg,msg); + return(E_ASKCURRENT); + } else { + value->rValue = -*(ckt->CKTstate0 + here->HFETAcd); + value->rValue -= *(ckt->CKTstate0 + here->HFETAcg); + } + return(OK); + case HFETA_POWER : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = MALLOC(strlen(msg)+1); + errRtn = "HFETAask"; + strcpy(errMsg,msg); + return(E_ASKPOWER); + } else { + value->rValue = *(ckt->CKTstate0 + here->HFETAcd) * + *(ckt->CKTrhsOld + here->HFETAdrainNode); + value->rValue += *(ckt->CKTstate0 + here->HFETAcg) * + *(ckt->CKTrhsOld + here->HFETAgateNode); + value->rValue -= (*(ckt->CKTstate0+here->HFETAcd) + + *(ckt->CKTstate0 + here->HFETAcg)) * + *(ckt->CKTrhsOld + here->HFETAsourceNode); + } + return(OK); + default: + return (E_BADPARM); + } + /* NOTREACHED */ +} diff --git a/src/spicelib/devices/hfet1/hfetdefs.h b/src/spicelib/devices/hfet1/hfetdefs.h new file mode 100644 index 000000000..72ed92093 --- /dev/null +++ b/src/spicelib/devices/hfet1/hfetdefs.h @@ -0,0 +1,466 @@ +#ifndef HFETA +#define HFETA + +#include "ifsim.h" +#include "cktdefs.h" +#include "gendefs.h" +#include "complex.h" +#include "noisedef.h" + +#define HFETAnumStates 24 + +typedef struct sHFETAinstance { + struct sHFETAmodel *HFETAmodPtr; + struct sHFETAinstance *HFETAnextInstance; + IFuid HFETAname; + int HFETAowner; /* number of owner process */ + int HFETAstate; /* index into state table for this device */ + + int HFETAdrainNode; + int HFETAgateNode; + int HFETAsourceNode; + int HFETAdrainPrimeNode; + int HFETAgatePrimeNode; + int HFETAsourcePrimeNode; + int HFETAdrainPrmPrmNode; + int HFETAsourcePrmPrmNode; + double HFETAlength; + double HFETAwidth; + double HFETAicVDS; + double HFETAicVGS; + double HFETAtemp; + double HFETAtVto; + double HFETAtMu; + double HFETAtLambda; + double HFETAtLambdahf; + double *HFETAdrainDrainPrimePtr; + double *HFETAgatePrimeDrainPrimePtr; + double *HFETAgatePrimeSourcePrimePtr; + double *HFETAsourceSourcePrimePtr; + double *HFETAdrainPrimeDrainPtr; + double *HFETAdrainPrimeGatePrimePtr; + double *HFETAdrainPrimeSourcePrimePtr; + double *HFETAsourcePrimeGatePrimePtr; + double *HFETAsourcePrimeSourcePtr; + double *HFETAsourcePrimeDrainPrimePtr; + double *HFETAdrainDrainPtr; + double *HFETAgatePrimeGatePrimePtr; + double *HFETAsourceSourcePtr; + double *HFETAdrainPrimeDrainPrimePtr; + double *HFETAsourcePrimeSourcePrimePtr; + double *HFETAdrainPrmPrmDrainPrmPrmPtr; + double *HFETAdrainPrmPrmDrainPrimePtr; + double *HFETAdrainPrimeDrainPrmPrmPtr; + double *HFETAdrainPrmPrmGatePrimePtr; + double *HFETAgatePrimeDrainPrmPrmPtr; + double *HFETAsourcePrmPrmSourcePrmPrmPtr; + double *HFETAsourcePrmPrmSourcePrimePtr; + double *HFETAsourcePrimeSourcePrmPrmPtr; + double *HFETAsourcePrmPrmGatePrimePtr; + double *HFETAgatePrimeSourcePrmPrmPtr; + double *HFETAgateGatePtr; + double *HFETAgateGatePrimePtr; + double *HFETAgatePrimeGatePtr; + + +#define HFETAvgs HFETAstate +#define HFETAvgd HFETAstate+1 +#define HFETAcg HFETAstate+2 +#define HFETAcd HFETAstate+3 +#define HFETAcgd HFETAstate+4 +#define HFETAcgs HFETAstate+5 +#define HFETAgm HFETAstate+6 +#define HFETAgds HFETAstate+7 +#define HFETAggs HFETAstate+8 +#define HFETAggd HFETAstate+9 +#define HFETAqgs HFETAstate+10 +#define HFETAcqgs HFETAstate+11 +#define HFETAqgd HFETAstate+12 +#define HFETAcqgd HFETAstate+13 +#define HFETAvgspp HFETAstate+14 +#define HFETAggspp HFETAstate+15 +#define HFETAcgspp HFETAstate+16 +#define HFETAvgdpp HFETAstate+17 +#define HFETAggdpp HFETAstate+18 +#define HFETAcgdpp HFETAstate+19 +#define HFETAqds HFETAstate+20 +#define HFETAcqds HFETAstate+21 +#define HFETAgmg HFETAstate+22 +#define HFETAgmd HFETAstate+23 + + + + int HFETAoff; + unsigned HFETAlengthGiven : 1; + unsigned HFETAwidthGiven : 1; + unsigned HFETAicVDSGiven : 1; + unsigned HFETAicVGSGiven : 1; + unsigned HFETAtempGiven : 1; + int HFETAmode; + + double HFETAn0; + double HFETAn01; + double HFETAn02; + double HFETAgchi0; + double HFETAcf; + double HFETAis1d; + double HFETAis2d; + double HFETAis1s; + double HFETAis2s; + double HFETAiso; + double HFETAimax; + double HFETAvcrit; + double HFETAdelf; + double HFETAfgds; + double HFETAggrwl; + +} HFETAinstance ; + + +/* per model data */ + +typedef struct sHFETAmodel { + int HFETAmodType; + struct sHFETAmodel *HFETAnextModel; + HFETAinstance *HFETAinstances; + IFuid HFETAmodName; + int HFETAtype; + int HFETAgatemod; + + double HFETAthreshold; + double HFETAlambda; + double HFETAeta; + double HFETAm; + double HFETAmc; + double HFETAgamma; + double HFETAsigma0; + double HFETAvsigmat; + double HFETAvsigma; + double HFETAmu; + double HFETAdi; + double HFETAdelta; + double HFETAvs; + double HFETAnmax; + double HFETAdeltad; + double HFETAjs1d; + double HFETAjs2d; + double HFETAjs1s; + double HFETAjs2s; + double HFETAm1d; + double HFETAm2d; + double HFETAm1s; + double HFETAm2s; + double HFETArd; + double HFETArs; + double HFETArg; + double HFETArdi; + double HFETArsi; + double HFETArgs; + double HFETArgd; + double HFETAri; + double HFETArf; + double HFETAepsi; + double HFETAa1; + double HFETAa2; + double HFETAmv1; + double HFETAp; + double HFETAkappa; + double HFETAdelf; + double HFETAfgds; + double HFETAtf; + double HFETAcds; + double HFETAphib; + double HFETAtalpha; + double HFETAmt1; + double HFETAmt2; + double HFETAck1; + double HFETAck2; + double HFETAcm1; + double HFETAcm2; + double HFETAcm3; + double HFETAastar; + double HFETAeta1; + double HFETAd1; + double HFETAvt1; + double HFETAeta2; + double HFETAd2; + double HFETAvt2; + double HFETAggr; + double HFETAdel; + double HFETAklambda; + double HFETAkmu; + double HFETAkvto; + + double HFETAdrainConduct; + double HFETAsourceConduct; + double HFETAgateConduct; + double HFETAgi; + double HFETAgf; + double HFETAdeltaSqr; + + unsigned HFETAgatemodGiven:1; + unsigned HFETAthresholdGiven:1; + unsigned HFETAlambdaGiven:1; + unsigned HFETAetaGiven:1; + unsigned HFETAmGiven:1; + unsigned HFETAmcGiven:1; + unsigned HFETAgammaGiven:1; + unsigned HFETAsigma0Given:1; + unsigned HFETAvsigmatGiven:1; + unsigned HFETAvsigmaGiven:1; + unsigned HFETAmuGiven:1; + unsigned HFETAdiGiven:1; + unsigned HFETAdeltaGiven:1; + unsigned HFETAvsGiven:1; + unsigned HFETAnmaxGiven:1; + unsigned HFETAdeltadGiven:1; + unsigned HFETAjs1dGiven:1; + unsigned HFETAjs2dGiven:1; + unsigned HFETAjs1sGiven:1; + unsigned HFETAjs2sGiven:1; + unsigned HFETAm1dGiven:1; + unsigned HFETAm2dGiven:1; + unsigned HFETAm1sGiven:1; + unsigned HFETAm2sGiven:1; + unsigned HFETArdGiven:1; + unsigned HFETArsGiven:1; + unsigned HFETArgGiven:1; + unsigned HFETArdiGiven:1; + unsigned HFETArsiGiven:1; + unsigned HFETArgsGiven:1; + unsigned HFETArgdGiven:1; + unsigned HFETAriGiven:1; + unsigned HFETArfGiven:1; + unsigned HFETAepsiGiven:1; + unsigned HFETAa1Given:1; + unsigned HFETAa2Given:1; + unsigned HFETAmv1Given:1; + unsigned HFETApGiven:1; + unsigned HFETAkappaGiven:1; + unsigned HFETAdelfGiven:1; + unsigned HFETAfgdsGiven:1; + unsigned HFETAtfGiven:1; + unsigned HFETAcdsGiven:1; + unsigned HFETAphibGiven:1; + unsigned HFETAtalphaGiven:1; + unsigned HFETAmt1Given:1; + unsigned HFETAmt2Given:1; + unsigned HFETAck1Given:1; + unsigned HFETAck2Given:1; + unsigned HFETAcm1Given:1; + unsigned HFETAcm2Given:1; + unsigned HFETAcm3Given:1; + unsigned HFETAastarGiven:1; + unsigned HFETAeta1Given:1; + unsigned HFETAd1Given:1; + unsigned HFETAvt1Given:1; + unsigned HFETAeta2Given:1; + unsigned HFETAd2Given:1; + unsigned HFETAvt2Given:1; + unsigned HFETAggrGiven:1; + unsigned HFETAdelGiven:1; + unsigned HFETAklambdaGiven:1; + unsigned HFETAkmuGiven:1; + unsigned HFETAkvtoGiven:1; + +} HFETAmodel; + +#ifndef NHFET +#define NHFET 1 +#define PHFET -1 +#endif + +/* device parameters */ +#define HFETA_LENGTH 1 +#define HFETA_WIDTH 2 +#define HFETA_IC_VDS 3 +#define HFETA_IC_VGS 4 +#define HFETA_TEMP 5 +#define HFETA_IC 6 +#define HFETA_OFF 7 +#define HFETA_CS 8 +#define HFETA_POWER 9 + +/* model parameters */ +#define HFETA_MOD_VTO 101 +#define HFETA_MOD_LAMBDA 102 +#define HFETA_MOD_RD 103 +#define HFETA_MOD_RS 104 +#define HFETA_MOD_RG 105 +#define HFETA_MOD_RGS 106 +#define HFETA_MOD_RGD 107 +#define HFETA_MOD_RI 108 +#define HFETA_MOD_RF 109 +#define HFETA_MOD_ETA 110 +#define HFETA_MOD_M 111 +#define HFETA_MOD_MC 112 +#define HFETA_MOD_GAMMA 113 +#define HFETA_MOD_SIGMA0 114 +#define HFETA_MOD_VSIGMAT 115 +#define HFETA_MOD_VSIGMA 116 +#define HFETA_MOD_MU 117 +#define HFETA_MOD_DI 118 +#define HFETA_MOD_DELTA 119 +#define HFETA_MOD_VS 120 +#define HFETA_MOD_NMAX 121 +#define HFETA_MOD_DELTAD 122 +#define HFETA_MOD_JS1D 123 +#define HFETA_MOD_JS2D 124 +#define HFETA_MOD_JS1S 125 +#define HFETA_MOD_JS2S 126 +#define HFETA_MOD_M1D 127 +#define HFETA_MOD_M2D 128 +#define HFETA_MOD_M1S 129 +#define HFETA_MOD_M2S 130 +#define HFETA_MOD_EPSI 132 +#define HFETA_MOD_RDI 133 +#define HFETA_MOD_RSI 134 +#define HFETA_MOD_A1 135 +#define HFETA_MOD_A2 136 +#define HFETA_MOD_MV1 137 +#define HFETA_MOD_P 138 +#define HFETA_MOD_KAPPA 139 +#define HFETA_MOD_DELF 140 +#define HFETA_MOD_FGDS 141 +#define HFETA_MOD_TF 142 +#define HFETA_MOD_CDS 143 +#define HFETA_MOD_PHIB 144 +#define HFETA_MOD_TALPHA 145 +#define HFETA_MOD_MT1 146 +#define HFETA_MOD_MT2 147 +#define HFETA_MOD_CK1 148 +#define HFETA_MOD_CK2 149 +#define HFETA_MOD_CM1 150 +#define HFETA_MOD_CM2 151 +#define HFETA_MOD_CM3 152 +#define HFETA_MOD_ASTAR 153 +#define HFETA_MOD_ETA1 154 +#define HFETA_MOD_D1 155 +#define HFETA_MOD_VT1 156 +#define HFETA_MOD_ETA2 157 +#define HFETA_MOD_D2 158 +#define HFETA_MOD_VT2 159 +#define HFETA_MOD_GGR 160 +#define HFETA_MOD_DEL 161 +#define HFETA_MOD_GATEMOD 162 +#define HFETA_MOD_KLAMBDA 163 +#define HFETA_MOD_KMU 164 +#define HFETA_MOD_KVTO 165 +#define HFETA_MOD_NHFET 166 +#define HFETA_MOD_PHFET 167 +#define HFETA_MOD_TYPE 168 + +/* device questions */ + +#define HFETA_DRAINNODE 201 +#define HFETA_GATENODE 202 +#define HFETA_SOURCENODE 203 +#define HFETA_DRAINPRIMENODE 204 +#define HFETA_SOURCEPRIMENODE 205 + +#define HFETA_VGS 206 +#define HFETA_VGD 207 +#define HFETA_CG 208 +#define HFETA_CD 209 +#define HFETA_CGD 210 +#define HFETA_GM 211 +#define HFETA_GDS 212 +#define HFETA_GGS 213 +#define HFETA_GGD 214 +#define HFETA_QGS 215 +#define HFETA_CQGS 216 +#define HFETA_QGD 217 +#define HFETA_CQGD 218 + +/* model questions */ + +#define HFETA_MOD_DRAINCONDUCT 301 +#define HFETA_MOD_SOURCECONDUCT 302 +#define HFETA_MOD_DEPLETIONCAP 303 +#define HFETA_MOD_VCRIT 304 + + +#define L (here->HFETAlength) +#define W (here->HFETAwidth) +#define VTO (model->HFETAthreshold) +#define LAMBDA (model->HFETAlambda) +#define RDI (model->HFETArdi) +#define RSI (model->HFETArsi) +#define RD (model->HFETArd) +#define RS (model->HFETArs) +#define RG (model->HFETArg) +#define RF (model->HFETArf) +#define RI (model->HFETAri) +#define RGS (model->HFETArgs) +#define RGD (model->HFETArgd) +#define ETA (model->HFETAeta) +#define M (model->HFETAm) +#define MC (model->HFETAmc) +#define GAMMA (model->HFETAgamma) +#define SIGMA0 (model->HFETAsigma0) +#define VSIGMAT (model->HFETAvsigmat) +#define VSIGMA (model->HFETAvsigma) +#define MU (model->HFETAmu) +#define DI (model->HFETAdi) +#define DELTAD (model->HFETAdeltad) +#define DELTASQR (model->HFETAdeltaSqr) +#define VS (model->HFETAvs) +#define NMAX (model->HFETAnmax) +#define EPSI (model->HFETAepsi) +#define JS1D (model->HFETAjs1d) +#define JS2D (model->HFETAjs2d) +#define JS1S (model->HFETAjs1s) +#define JS2S (model->HFETAjs2s) +#define M1D (model->HFETAm1d) +#define M2D (model->HFETAm2d) +#define M1S (model->HFETAm1s) +#define M2S (model->HFETAm2s) +#define ASTAR (model->HFETAastar) +#define PHIB (model->HFETAphib) +#define TALPHA (model->HFETAtalpha) +#define MT1 (model->HFETAmt1) +#define MT2 (model->HFETAmt2) +#define CK1 (model->HFETAck1) +#define CK2 (model->HFETAck2) +#define CM1 (model->HFETAcm1) +#define CM2 (model->HFETAcm2) +#define CM3 (model->HFETAcm3) +#define A1 (model->HFETAa1) +#define A2 (model->HFETAa2) +#define MV1 (model->HFETAmv1) +#define PM (model->HFETAp) +#define CDS (model->HFETAcds) +#define ETA1 (model->HFETAeta1) +#define D1 (model->HFETAd1) +#define IN_VT1 (model->HFETAvt1) /* VT1 was defined in termios.h */ +#define ETA2 (model->HFETAeta2) +#define D2 (model->HFETAd2) +#define VT2 (model->HFETAvt2) +#define GGR (model->HFETAggr) +#define DEL (model->HFETAdel) +#define KLAMBDA (model->HFETAklambda) +#define KMU (model->HFETAkmu) +#define KVTO (model->HFETAkvto) + +#define GCHI0 (here->HFETAgchi0) +#define N0 (here->HFETAn0) +#define N01 (here->HFETAn01) +#define N02 (here->HFETAn02) +#define CF (here->HFETAcf) +#define IMAX (here->HFETAimax) +#define ISO (here->HFETAiso) +#define TEMP (here->HFETAtemp) +#define IS1D (here->HFETAis1d) +#define IS2D (here->HFETAis2d) +#define IS1S (here->HFETAis1s) +#define IS2S (here->HFETAis2s) +#define FGDS (here->HFETAfgds) +#define DELF (here->HFETAdelf) +#define GGRWL (here->HFETAggrwl) +#define TLAMBDA (here->HFETAtLambda) +#define TMU (here->HFETAtMu) +#define TVTO (here->HFETAtVto) + +#include "hfetext.h" + +#endif /*HFETA*/ diff --git a/src/spicelib/devices/hfet1/hfetdel.c b/src/spicelib/devices/hfet1/hfetdel.c new file mode 100644 index 000000000..36a69b378 --- /dev/null +++ b/src/spicelib/devices/hfet1/hfetdel.c @@ -0,0 +1,39 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 S. Hwang +**********/ +/* +Imported into hfeta model: Paolo Nenzi 2001 +*/ + +#include "ngspice.h" +#include +#include "hfetdefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +HFETAdelete(inModel,name,inst) + GENmodel *inModel; + IFuid name; + GENinstance **inst; +{ + HFETAmodel *model = (HFETAmodel*)inModel; + HFETAinstance **fast = (HFETAinstance**)inst; + HFETAinstance **prev = NULL; + HFETAinstance *here; + + for( ; model ; model = model->HFETAnextModel) { + prev = &(model->HFETAinstances); + for(here = *prev; here ; here = *prev) { + if(here->HFETAname == name || (fast && here==*fast) ) { + *prev= here->HFETAnextInstance; + FREE(here); + return(OK); + } + prev = &(here->HFETAnextInstance); + } + } + return(E_NODEV); +} diff --git a/src/spicelib/devices/hfet1/hfetdest.c b/src/spicelib/devices/hfet1/hfetdest.c new file mode 100644 index 000000000..9869b401a --- /dev/null +++ b/src/spicelib/devices/hfet1/hfetdest.c @@ -0,0 +1,31 @@ + +#include "ngspice.h" +#include +#include "hfetdefs.h" +#include "suffix.h" + + +void +HFETAdestroy(inModel) +GENmodel **inModel; +{ + HFETAmodel **model = (HFETAmodel**)inModel; + HFETAinstance *here; + HFETAinstance *prev = NULL; + HFETAmodel *mod = *model; + HFETAmodel *oldmod = NULL; + + for( ; mod ; mod = mod->HFETAnextModel) { + if(oldmod) FREE(oldmod); + oldmod = mod; + prev = (HFETAinstance *)NULL; + for(here = mod->HFETAinstances ; here ; here = here->HFETAnextInstance) { + if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + } + if(oldmod) FREE(oldmod); + *model = NULL; + return; +} diff --git a/src/spicelib/devices/hfet1/hfetext.h b/src/spicelib/devices/hfet1/hfetext.h new file mode 100644 index 000000000..c65cc3e01 --- /dev/null +++ b/src/spicelib/devices/hfet1/hfetext.h @@ -0,0 +1,34 @@ +#ifdef __STDC__ +extern int HFETAacLoad(GENmodel*,CKTcircuit*); +extern int HFETAask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); +extern int HFETAdelete(GENmodel*,IFuid,GENinstance**); +extern void HFETAdestroy(GENmodel**); +extern int HFETAgetic(GENmodel*,CKTcircuit*); +extern int HFETAload(GENmodel*,CKTcircuit*); +extern int HFETAmAsk(CKTcircuit*,GENmodel*,int,IFvalue*); +extern int HFETAmDelete(GENmodel**,IFuid,GENmodel*); +extern int HFETAmParam(int,IFvalue*,GENmodel*); +extern int HFETAparam(int,IFvalue*,GENinstance*,IFvalue*); +extern int HFETAsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); +extern int HFETAtemp(GENmodel*,CKTcircuit*); +extern int HFETAtrunc(GENmodel*,CKTcircuit*,double*); +extern int HFETAunsetup(GENmodel*,CKTcircuit*); + +#else /*stdc*/ +extern int HFETAacLoad(); +extern int HFETAask(); +extern int HFETAdelete(); +extern void HFETAdestroy(); +extern int HFETAgetic(); +extern int HFETAload(); +extern int HFETAmAsk(); +extern int HFETAmDelete(); +extern int HFETAmParam(); +extern int HFETAparam(); +extern int HFETAsetup(); +extern int HFETAtemp(); +extern int HFETAtrunc(); +extern int HFETAunsetup(); + + +#endif \ No newline at end of file diff --git a/src/spicelib/devices/hfet1/hfetgetic.c b/src/spicelib/devices/hfet1/hfetgetic.c new file mode 100644 index 000000000..30836a269 --- /dev/null +++ b/src/spicelib/devices/hfet1/hfetgetic.c @@ -0,0 +1,37 @@ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "hfetdefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +HFETAgetic(inModel,ckt) +GENmodel *inModel; +CKTcircuit *ckt; +{ + HFETAmodel *model = (HFETAmodel*)inModel; + HFETAinstance *here; + /* + * grab initial conditions out of rhs array. User specified, so use + * external nodes to get values + */ + + for( ; model ; model = model->HFETAnextModel) { + for(here = model->HFETAinstances; here ; here = here->HFETAnextInstance) { + if(!here->HFETAicVDSGiven) { + here->HFETAicVDS = + *(ckt->CKTrhs + here->HFETAdrainNode) - + *(ckt->CKTrhs + here->HFETAsourceNode); + } + if(!here->HFETAicVGSGiven) { + here->HFETAicVGS = + *(ckt->CKTrhs + here->HFETAgateNode) - + *(ckt->CKTrhs + here->HFETAsourceNode); + } + } + } + return(OK); +} diff --git a/src/spicelib/devices/hfet1/hfetinit.c b/src/spicelib/devices/hfet1/hfetinit.c new file mode 100644 index 000000000..345ce7047 --- /dev/null +++ b/src/spicelib/devices/hfet1/hfetinit.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "hfetitf.h" +#include "hfetext.h" +#include "hfetinit.h" + + +SPICEdev HFETAinfo = { + { + "HFET1", + "HFET1 Model", + + &HFETAnSize, + &HFETAnSize, + HFETAnames, + + &HFETApTSize, + HFETApTable, + + &HFETAmPTSize, + HFETAmPTable, + DEV_DEFAULT + }, + + DEVparam : HFETAparam, + DEVmodParam : HFETAmParam, + DEVload : HFETAload, + DEVsetup : HFETAsetup, + DEVunsetup : HFETAunsetup, + DEVpzSetup : HFETAsetup, + DEVtemperature: HFETAtemp, + DEVtrunc : HFETAtrunc, + DEVfindBranch : NULL, + DEVacLoad : HFETAacLoad, + DEVaccept : NULL, + DEVdestroy : HFETAdestroy, + DEVmodDelete : HFETAmDelete, + DEVdelete : HFETAdelete, + DEVsetic : HFETAgetic, + DEVask : HFETAask, + DEVmodAsk : HFETAmAsk, + DEVpzLoad : NULL, + DEVconvTest : NULL, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, + DEVnoise : NULL, + + DEVinstSize : &HFETAiSize, + DEVmodSize : &HFETAmSize + +}; + + +SPICEdev * +get_hfeta_info(void) +{ + return &HFETAinfo; +} diff --git a/src/spicelib/devices/hfet1/hfetinit.h b/src/spicelib/devices/hfet1/hfetinit.h new file mode 100644 index 000000000..5d82bdae0 --- /dev/null +++ b/src/spicelib/devices/hfet1/hfetinit.h @@ -0,0 +1,13 @@ +#ifndef _HFETAINIT_H +#define _HFETAINIT_H + +extern IFparm HFETApTable[ ]; +extern IFparm HFETAmPTable[ ]; +extern char *HFETAnames[ ]; +extern int HFETApTSize; +extern int HFETAmPTSize; +extern int HFETAnSize; +extern int HFETAiSize; +extern int HFETAmSize; + +#endif diff --git a/src/spicelib/devices/hfet1/hfetitf.h b/src/spicelib/devices/hfet1/hfetitf.h new file mode 100644 index 000000000..cd9b3db79 --- /dev/null +++ b/src/spicelib/devices/hfet1/hfetitf.h @@ -0,0 +1,7 @@ +#ifndef DEV_HFETA +#define DEV_HFETA + +SPICEdev *get_hfeta_info(void); + +#endif + diff --git a/src/spicelib/devices/hfet1/hfetload.c b/src/spicelib/devices/hfet1/hfetload.c new file mode 100644 index 000000000..672c3a369 --- /dev/null +++ b/src/spicelib/devices/hfet1/hfetload.c @@ -0,0 +1,787 @@ +#include "ngspice.h" +#include +#include "devdefs.h" +#include "cktdefs.h" +#include "hfetdefs.h" +#include "const.h" +#include "trandefs.h" +#include "sperror.h" +#include "suffix.h" +/* +#define true 1 +#define false 0 +*/ + +//#define PHIB 0.5 +double diode(double); + +static void leak(double gmin, double vt, double v, double rs, double is1, + double is2, double m1, double m2, double *il, double *gl); + +static void hfeta(HFETAmodel *model, HFETAinstance *here, CKTcircuit *ckt, + double vgs, double vds, double *cdrain, double *gm, + double *gds, double *capgs, double *capgd, + double *cgd, double *gmg, double *gmd, + double *cgs, double *ggs); + +void Pause(void); + +int HFETAload(inModel, ckt) +GENmodel *inModel; +register CKTcircuit *ckt; +{ + register HFETAmodel *model = (HFETAmodel*)inModel; + register HFETAinstance *here; + double capgd; + double capgs; + double cd; + double cdhat; + double cdrain; + double cdreq; + double ceq; + double ceqgd; + double ceqgs; + double cg; + double cgd=0; + double cgs=0; + double cghat; + double delvds; + double delvgd; + double delvgs; + double delvgdpp=0; + double delvgspp=0; + double gds; + double geq; + double ggd=0; + double ggs=0; + double gm; + double vcrit; + double vds; + double vgd; + double vgs; + double vgs1; + double vgd1; + double vds1; + double xfact; + double temp; + double vt; + double vgspp=0; + double vgdpp=0; + double cgspp=0; + double cgdpp=0; + double ggspp=0; + double ggdpp=0; + double gmg=0; + double gmd=0; + + int inverse=FALSE; + int icheck; + int error; + + for( ; model != NULL; model = model->HFETAnextModel ) { + for (here = model->HFETAinstances; here != NULL ; + here=here->HFETAnextInstance) { + vcrit = here->HFETAvcrit; + vt = CONSTKoverQ * here->HFETAtemp; + icheck = 0; + if( ckt->CKTmode & MODEINITSMSIG) { + vgs = *(ckt->CKTstate0 + here->HFETAvgs); + vgd = *(ckt->CKTstate0 + here->HFETAvgd); + vgspp = *(ckt->CKTstate0 + here->HFETAvgspp); + vgdpp = *(ckt->CKTstate0 + here->HFETAvgdpp); + } else if (ckt->CKTmode & MODEINITTRAN) { + vgs = *(ckt->CKTstate1 + here->HFETAvgs); + vgd = *(ckt->CKTstate1 + here->HFETAvgd); + vgspp = *(ckt->CKTstate1 + here->HFETAvgspp); + vgdpp = *(ckt->CKTstate1 + here->HFETAvgdpp); + } else if ( (ckt->CKTmode & MODEINITJCT) && + (ckt->CKTmode & MODETRANOP) && + (ckt->CKTmode & MODEUIC) ) { + vds = model->HFETAtype*here->HFETAicVDS; + vgs = model->HFETAtype*here->HFETAicVGS; + vgd = vgs-vds; + vgspp = vgs; + vgdpp = vgd; + } else if ( (ckt->CKTmode & MODEINITJCT) && + (here->HFETAoff == 0) ) { + vgs = -1; + vgd = -1; + vgspp = 0; + vgdpp = 0; + } else if( (ckt->CKTmode & MODEINITJCT) || + ((ckt->CKTmode & MODEINITFIX) && (here->HFETAoff))) { + vgs = 0; + vgd = 0; + vgspp = 0; + vgdpp = 0; + } else { +#ifndef PREDICTOR + if(ckt->CKTmode & MODEINITPRED) { + xfact = ckt->CKTdelta/ckt->CKTdeltaOld[2]; + *(ckt->CKTstate0 + here->HFETAvgs) = + *(ckt->CKTstate1 + here->HFETAvgs); + vgs = (1+xfact) * *(ckt->CKTstate1 + here->HFETAvgs) - + xfact * *(ckt->CKTstate2 + here->HFETAvgs); + *(ckt->CKTstate0 + here->HFETAvgspp) = + *(ckt->CKTstate1 + here->HFETAvgspp); + vgspp = (1+xfact) * *(ckt->CKTstate1 + here->HFETAvgspp) - + xfact * *(ckt->CKTstate2 + here->HFETAvgspp); + *(ckt->CKTstate0 + here->HFETAvgd) = + *(ckt->CKTstate1 + here->HFETAvgd); + vgd = (1+xfact)* *(ckt->CKTstate1 + here->HFETAvgd) - + xfact * *(ckt->CKTstate2 + here->HFETAvgd); + *(ckt->CKTstate0 + here->HFETAvgdpp) = + *(ckt->CKTstate1 + here->HFETAvgdpp); + vgdpp = (1+xfact) * *(ckt->CKTstate1 + here->HFETAvgdpp) - + xfact * *(ckt->CKTstate2 + here->HFETAvgdpp); + *(ckt->CKTstate0 + here->HFETAcg) = + *(ckt->CKTstate1 + here->HFETAcg); + *(ckt->CKTstate0 + here->HFETAcd) = + *(ckt->CKTstate1 + here->HFETAcd); + *(ckt->CKTstate0 + here->HFETAcgd) = + *(ckt->CKTstate1 + here->HFETAcgd); + *(ckt->CKTstate0 + here->HFETAcgs) = + *(ckt->CKTstate1 + here->HFETAcgs); + *(ckt->CKTstate0 + here->HFETAcgspp) = + *(ckt->CKTstate1 + here->HFETAcgspp); + *(ckt->CKTstate0 + here->HFETAcgdpp) = + *(ckt->CKTstate1 + here->HFETAcgdpp); + *(ckt->CKTstate0 + here->HFETAgm) = + *(ckt->CKTstate1 + here->HFETAgm); + *(ckt->CKTstate0 + here->HFETAgds) = + *(ckt->CKTstate1 + here->HFETAgds); + *(ckt->CKTstate0 + here->HFETAggs) = + *(ckt->CKTstate1 + here->HFETAggs); + *(ckt->CKTstate0 + here->HFETAggspp) = + *(ckt->CKTstate1 + here->HFETAggspp); + *(ckt->CKTstate0 + here->HFETAggd) = + *(ckt->CKTstate1 + here->HFETAggd); + *(ckt->CKTstate0 + here->HFETAggdpp) = + *(ckt->CKTstate1 + here->HFETAggdpp); + *(ckt->CKTstate0 + here->HFETAgmg) = + *(ckt->CKTstate1 + here->HFETAgmg); + *(ckt->CKTstate0 + here->HFETAgmd) = + *(ckt->CKTstate1 + here->HFETAgmd); + } else { +#endif /* PREDICTOR */ + /* + * compute new nonlinear branch voltages + */ + vgs = model->HFETAtype* + (*(ckt->CKTrhsOld+ here->HFETAgatePrimeNode)- + *(ckt->CKTrhsOld+ + here->HFETAsourcePrimeNode)); + vgd = model->HFETAtype* + (*(ckt->CKTrhsOld+here->HFETAgatePrimeNode)- + *(ckt->CKTrhsOld+ + here->HFETAdrainPrimeNode)); + vgspp = model->HFETAtype* + (*(ckt->CKTrhsOld+ here->HFETAgatePrimeNode)- + *(ckt->CKTrhsOld+ + here->HFETAsourcePrmPrmNode)); + vgdpp = model->HFETAtype* + (*(ckt->CKTrhsOld+ here->HFETAgatePrimeNode)- + *(ckt->CKTrhsOld+ + here->HFETAdrainPrmPrmNode)); + +#ifndef PREDICTOR + } +#endif /* PREDICTOR */ + delvgs=vgs - *(ckt->CKTstate0 + here->HFETAvgs); + delvgd=vgd - *(ckt->CKTstate0 + here->HFETAvgd); + delvds=delvgs - delvgd; + delvgspp=vgspp - *(ckt->CKTstate0 + here->HFETAvgspp); + delvgdpp=vgdpp - *(ckt->CKTstate0 + here->HFETAvgdpp); + cghat= *(ckt->CKTstate0 + here->HFETAcg) + + *(ckt->CKTstate0 + here->HFETAgmg)*delvgs - + *(ckt->CKTstate0 + here->HFETAgmd)*delvds + + *(ckt->CKTstate0 + here->HFETAggd)*delvgd + + *(ckt->CKTstate0 + here->HFETAggs)*delvgs + + *(ckt->CKTstate0 + here->HFETAggdpp)*delvgdpp + + *(ckt->CKTstate0 + here->HFETAggspp)*delvgspp; + cdhat= *(ckt->CKTstate0 + here->HFETAcd) + + *(ckt->CKTstate0 + here->HFETAgm)*delvgs + + *(ckt->CKTstate0 + here->HFETAgds)*delvds - + *(ckt->CKTstate0 + here->HFETAggd)*delvgd - + (*(ckt->CKTstate0 + here->HFETAgmg)*delvgs - + *(ckt->CKTstate0 + here->HFETAgmd)*delvds); + /* + * bypass if solution has not changed + */ + if((ckt->CKTbypass) && + (!(ckt->CKTmode & MODEINITPRED)) && + (fabs(delvgs) < ckt->CKTreltol*MAX(fabs(vgs), + fabs(*(ckt->CKTstate0 + here->HFETAvgs)))+ + ckt->CKTvoltTol) ) + if ( (fabs(delvgd) < ckt->CKTreltol*MAX(fabs(vgd), + fabs(*(ckt->CKTstate0 + here->HFETAvgd)))+ + ckt->CKTvoltTol)) + if ( (fabs(delvgspp) < ckt->CKTreltol*MAX(fabs(vgspp), + fabs(*(ckt->CKTstate0 + here->HFETAvgspp)))+ + ckt->CKTvoltTol)) + if ( (fabs(delvgdpp) < ckt->CKTreltol*MAX(fabs(vgdpp), + fabs(*(ckt->CKTstate0 + here->HFETAvgdpp)))+ + ckt->CKTvoltTol)) + if ( (fabs(cghat-*(ckt->CKTstate0 + here->HFETAcg)) + < ckt->CKTreltol*MAX(fabs(cghat), + fabs(*(ckt->CKTstate0 + here->HFETAcg)))+ + ckt->CKTabstol) ) if ( /* hack - expression too big */ + (fabs(cdhat-*(ckt->CKTstate0 + here->HFETAcd)) + < ckt->CKTreltol*MAX(fabs(cdhat), + fabs(*(ckt->CKTstate0 + here->HFETAcd)))+ + ckt->CKTabstol) ) { + + /* we can do a bypass */ + vgs = *(ckt->CKTstate0 + here->HFETAvgs); + vgd = *(ckt->CKTstate0 + here->HFETAvgd); + vds = vgs-vgd; + vgspp = *(ckt->CKTstate0 + here->HFETAvgspp); + vgdpp = *(ckt->CKTstate0 + here->HFETAvgdpp); + cg = *(ckt->CKTstate0 + here->HFETAcg); + cd = *(ckt->CKTstate0 + here->HFETAcd); + cgd = *(ckt->CKTstate0 + here->HFETAcgd); + cgs = *(ckt->CKTstate0 + here->HFETAcgs); + cgdpp = *(ckt->CKTstate0 + here->HFETAcgdpp); + cgspp = *(ckt->CKTstate0 + here->HFETAcgspp); + gm = *(ckt->CKTstate0 + here->HFETAgm); + gds = *(ckt->CKTstate0 + here->HFETAgds); + ggs = *(ckt->CKTstate0 + here->HFETAggs); + ggd = *(ckt->CKTstate0 + here->HFETAggd); + ggdpp = *(ckt->CKTstate0 + here->HFETAggdpp); + ggspp = *(ckt->CKTstate0 + here->HFETAggspp); + gmg = *(ckt->CKTstate0 + here->HFETAgmg); + gmd = *(ckt->CKTstate0 + here->HFETAgmd); + goto load; + } + /* + * limit nonlinear branch voltages + */ + vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->HFETAvgs),TVTO); + vgd = DEVfetlim(vgd,*(ckt->CKTstate0 + here->HFETAvgd),TVTO); + } + /* + * determine dc current and derivatives + */ + vds = vgs-vgd; + if(model->HFETAgatemod == 0) { + double arg; + double earg; + if(IS1S == 0 || IS2S == 0) { + cgs = 0; + ggs = 0; + } else + leak(ckt->CKTgmin,vt,vgs,RGS,IS1S,IS2S,M1S,M2S,&cgs,&ggs); + arg = -vgs*DEL/vt; + earg = exp(arg); + cgs += GGRWL*vgs*earg; + ggs += GGRWL*earg*(1-arg); + if(IS1D == 0 || IS2D == 0) { + cgd = 0; + ggd = 0; + } else + leak(ckt->CKTgmin,vt,vgd,RGD,IS1D,IS2D,M1D,M2D,&cgd,&ggd); + arg = -vgd*DEL/vt; + earg = exp(arg); + cgd += GGRWL*vgd*earg; + ggd += GGRWL*earg*(1-arg); + } else + ggd = 0; + if(vds < 0) { + vds = -vds; + inverse = TRUE; + } + hfeta(model,here,ckt,vds>0?vgs:vgd,vds,&cdrain,&gm,&gds,&capgs,&capgd, + &cgd,&gmg,&gmd,&cgs,&ggs); + cg = cgs+cgd; + if(inverse) { + cdrain = -cdrain; + vds = -vds; + temp = capgs; + capgs = capgd; + capgd = temp; + } + /* + * compute equivalent drain current source + */ + cd = cdrain - cgd; + if ( (ckt->CKTmode & (MODETRAN|MODEINITSMSIG)) || + ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) ){ + /* + * charge storage elements + */ + vgs1 = *(ckt->CKTstate1 + here->HFETAvgspp); + vgd1 = *(ckt->CKTstate1 + here->HFETAvgdpp); + vds1 = *(ckt->CKTstate1 + here->HFETAvgs)- + *(ckt->CKTstate1 + here->HFETAvgd); + + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->HFETAqgs) = capgs*vgspp; + *(ckt->CKTstate1 + here->HFETAqgd) = capgd*vgdpp; + *(ckt->CKTstate1 + here->HFETAqds) = CDS*vds; + } + *(ckt->CKTstate0+here->HFETAqgs) = *(ckt->CKTstate1 + here->HFETAqgs) + + capgs*(vgspp-vgs1); + *(ckt->CKTstate0+here->HFETAqgd) = *(ckt->CKTstate1 + here->HFETAqgd) + + capgd*(vgdpp-vgd1); + *(ckt->CKTstate0+here->HFETAqds) = *(ckt->CKTstate1 + here->HFETAqds) + + CDS*(vds-vds1); + + /* + * store small-signal parameters + */ + if( (!(ckt->CKTmode & MODETRANOP)) || + (!(ckt->CKTmode & MODEUIC)) ) { + if(ckt->CKTmode & MODEINITSMSIG) { + *(ckt->CKTstate0 + here->HFETAqgs) = capgs; + *(ckt->CKTstate0 + here->HFETAqgd) = capgd; + *(ckt->CKTstate0 + here->HFETAqds) = CDS; + continue; /*go to 1000*/ + } + /* + * transient analysis + */ + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->HFETAqgs) = + *(ckt->CKTstate0 + here->HFETAqgs); + *(ckt->CKTstate1 + here->HFETAqgd) = + *(ckt->CKTstate0 + here->HFETAqgd); + *(ckt->CKTstate1 + here->HFETAqds) = + *(ckt->CKTstate0 + here->HFETAqds); + } + error = NIintegrate(ckt,&geq,&ceq,capgs,here->HFETAqgs); + if(error) return(error); + ggspp = geq; + cgspp = *(ckt->CKTstate0 + here->HFETAcqgs); + cg = cg + cgspp; + error = NIintegrate(ckt,&geq,&ceq,capgd,here->HFETAqgd); + if(error) return(error); + ggdpp = geq; + cgdpp = *(ckt->CKTstate0 + here->HFETAcqgd); + cg = cg + cgdpp; + cd = cd - cgdpp; + error = NIintegrate(ckt,&geq,&ceq,CDS,here->HFETAqds); + if(error) return(error); + gds += geq; + cd += *(ckt->CKTstate0 + here->HFETAcqds); + if (ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->HFETAcqgs) = + *(ckt->CKTstate0 + here->HFETAcqgs); + *(ckt->CKTstate1 + here->HFETAcqgd) = + *(ckt->CKTstate0 + here->HFETAcqgd); + *(ckt->CKTstate1 + here->HFETAcqds) = + *(ckt->CKTstate0 + here->HFETAcqds); + } + } + } + /* + * check convergence + */ + 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; + } + } + *(ckt->CKTstate0 + here->HFETAvgs) = vgs; + *(ckt->CKTstate0 + here->HFETAvgd) = vgd; + *(ckt->CKTstate0 + here->HFETAvgspp) = vgspp; + *(ckt->CKTstate0 + here->HFETAvgdpp) = vgdpp; + *(ckt->CKTstate0 + here->HFETAcg) = cg; + *(ckt->CKTstate0 + here->HFETAcd) = cd; + *(ckt->CKTstate0 + here->HFETAcgd) = cgd; + *(ckt->CKTstate0 + here->HFETAcgs) = cgs; + *(ckt->CKTstate0 + here->HFETAcgspp) = cgspp; + *(ckt->CKTstate0 + here->HFETAcgdpp) = cgdpp; + *(ckt->CKTstate0 + here->HFETAgm) = gm; + *(ckt->CKTstate0 + here->HFETAgds) = gds; + *(ckt->CKTstate0 + here->HFETAggs) = ggs; + *(ckt->CKTstate0 + here->HFETAggd) = ggd; + *(ckt->CKTstate0 + here->HFETAggspp) = ggspp; + *(ckt->CKTstate0 + here->HFETAggdpp) = ggdpp; + *(ckt->CKTstate0 + here->HFETAgmg) = gmg; + *(ckt->CKTstate0 + here->HFETAgmd) = gmd; + + /* + * load current vector + */ +load: + ceqgd = model->HFETAtype*(cgd+cgdpp-ggd*vgd-gmg*vgs-gmd*vds-ggdpp*vgdpp); + ceqgs = model->HFETAtype*(cgs + cgspp - ggs*vgs - ggspp*vgspp); + cdreq = model->HFETAtype*(cd + cgd + cgdpp - gds*vds - gm*vgs); + *(ckt->CKTrhs + here->HFETAgatePrimeNode) += (-ceqgs-ceqgd); + ceqgd = model->HFETAtype*(cgd-ggd*vgd-gmg*vgs-gmd*vds); + *(ckt->CKTrhs + here->HFETAdrainPrimeNode) += (-cdreq+ceqgd); + ceqgd = model->HFETAtype*(cgdpp-ggdpp*vgdpp); + *(ckt->CKTrhs + here->HFETAdrainPrmPrmNode) += ceqgd; + ceqgs = model->HFETAtype*(cgs-ggs*vgs); + *(ckt->CKTrhs + here->HFETAsourcePrimeNode) += (cdreq+ceqgs); + ceqgs = model->HFETAtype*(cgspp-ggspp*vgspp); + *(ckt->CKTrhs + here->HFETAsourcePrmPrmNode) += ceqgs; + + /* + * load y matrix + */ + + *(here->HFETAdrainDrainPtr) += model->HFETAdrainConduct; + *(here->HFETAsourceSourcePtr) += model->HFETAsourceConduct; + *(here->HFETAgatePrimeGatePrimePtr) += (ggd+ggs+ggspp+ggdpp+gmg+model->HFETAgateConduct); + *(here->HFETAdrainPrimeDrainPrimePtr) += (gds+ggd-gmd+model->HFETAdrainConduct+model->HFETAgf); + *(here->HFETAsourcePrimeSourcePrimePtr) += (gds+gm+ggs+model->HFETAsourceConduct+model->HFETAgi); + *(here->HFETAsourcePrmPrmSourcePrmPrmPtr) += (model->HFETAgi+ggspp); + *(here->HFETAdrainPrmPrmDrainPrmPrmPtr) += (model->HFETAgf+ggdpp); + *(here->HFETAdrainDrainPrimePtr) -= model->HFETAdrainConduct; + *(here->HFETAdrainPrimeDrainPtr) -= model->HFETAdrainConduct; + *(here->HFETAsourceSourcePrimePtr) -= model->HFETAsourceConduct; + *(here->HFETAsourcePrimeSourcePtr) -= model->HFETAsourceConduct; + *(here->HFETAgatePrimeDrainPrimePtr) += -ggd+gmd; + *(here->HFETAdrainPrimeGatePrimePtr) += (gm-ggd-gmg); + *(here->HFETAgatePrimeSourcePrimePtr) -= ggs+gmg+gmd; + *(here->HFETAsourcePrimeGatePrimePtr) += (-ggs-gm); + *(here->HFETAdrainPrimeSourcePrimePtr) += (-gds-gm+gmg+gmd); + *(here->HFETAsourcePrimeDrainPrimePtr) -= gds; + *(here->HFETAsourcePrimeSourcePrmPrmPtr) -= model->HFETAgi; + *(here->HFETAsourcePrmPrmSourcePrimePtr) -= model->HFETAgi; + *(here->HFETAgatePrimeSourcePrmPrmPtr) -= ggspp; + *(here->HFETAsourcePrmPrmGatePrimePtr) -= ggspp; + *(here->HFETAdrainPrimeDrainPrmPrmPtr) -= model->HFETAgf; + *(here->HFETAdrainPrmPrmDrainPrimePtr) -= model->HFETAgf; + *(here->HFETAgatePrimeDrainPrmPrmPtr) -= ggdpp; + *(here->HFETAdrainPrmPrmGatePrimePtr) -= ggdpp; + *(here->HFETAgateGatePtr) += model->HFETAgateConduct; + *(here->HFETAgateGatePrimePtr) -= model->HFETAgateConduct; + *(here->HFETAgatePrimeGatePtr) -= model->HFETAgateConduct; + + + } + } + return(OK); +} + + + + +static void leak(double gmin, double vt, double v, double rs, double is1, double is2, + double m1, double m2, double *il, double *gl) + +{ + + double vt1 = vt*m1; + double vt2 = vt*m2; + + if(v > -10*vt1) { + double dvdi0; + double iaprox; + double iaprox1; + double iaprox2; + double v0; + double vteff = vt1 + vt2; + double iseff = is2*pow((is1/is2),(m1/(m1+m2))); + if(rs > 0) { + double unorm = (v + rs*is1)/vt1 + log(rs*is1/vt1); + iaprox1 = vt1*diode(unorm)/rs - is1; + unorm = (v + rs*iseff)/vteff + log(rs*iseff/vteff); + iaprox2 = vteff*diode(unorm)/rs - iseff; + } else { + iaprox1 = is1*(exp(v/vt1) - 1); + iaprox2 = iseff*(exp(v/vteff) - 1); + } + if((iaprox1*iaprox2) != 0.0) + iaprox = 1./(1./iaprox1 + 1./iaprox2); + else + iaprox = 0.5*(iaprox1 + iaprox2); + + dvdi0 = rs + vt1/(iaprox+is1) + vt2/(iaprox+is2); + v0 = rs*iaprox; + v0 += vt1*log(iaprox/is1 + 1) + vt2*log(iaprox/is2 + 1); + //*il = __max(-is1,iaprox + (v - v0)/dvdi0)*0.99999; + *il = MAX(-is1,iaprox + (v - v0)/dvdi0)*0.99999; + *gl = 1./(rs + vt1/(*il+is1) + vt2/(*il+is2)); + } else { + *gl = gmin; + *il = (*gl)*v-is1; + } + +} + + + + + +static void hfeta(HFETAmodel *model, HFETAinstance *here, CKTcircuit *ckt, + double vgs, double vds, double *cdrain, double *gm, + double *gds, double *capgs, double *capgd, + double *cgd, double *gmg, double *gmd, + double *cgs, double *ggs) + +{ + + double vt; + double vgt; + double vgt0; + double sigma; + double vgte; + double isat; + double isatm; + double ns; + double nsm; + double a; + double b; + double c; + double d; + double e; + double f; + double g; + double h; + double p; + double q; + double s; + double t; + double u; + double nsc; + double nsn; + double temp; + double etavth; + double gch; + double gchi; + double gchim; + double vsate; + double vdse; + double cg1; + double cgc; + double rt; + double vl; + double delidgch; + double delgchgchi; + double delgchins; + double delnsnsm; + double delnsmvgt; + double delvgtevgt; + double delidvsate; + double delvsateisat; + double delisatisatm; + double delisatmvgte; + double delisatmgchim; + double delvsategch; + double delidvds; + double delvgtvgs; + double delvsatevgt; + + vt = CONSTKoverQ*TEMP; + etavth = ETA*vt; + vl = VS/TMU*L; + rt = RSI+RDI; + vgt0 = vgs - TVTO; + s = exp((vgt0-VSIGMAT)/VSIGMA); + sigma = SIGMA0/(1+s); + vgt = vgt0+sigma*vds; + u = 0.5*vgt/vt-1; + t = sqrt(model->HFETAdeltaSqr+u*u); + vgte = vt*(2+u+t); + b = exp(vgt/etavth); + if(model->HFETAeta2Given && model->HFETAd2Given) { + nsc = N02*exp((vgt+TVTO-VT2)/(ETA2*vt)); + nsn = 2*N0*log(1+0.5*b); + nsm = nsn*nsc/(nsn+nsc); + } else { + nsm = 2*N0*log(1+0.5*b); + } + if(nsm < 1.0e-38) { + *cdrain = 0; + *gm = 0.0; + *gds = 0.0; + *capgs = CF; + *capgd = CF; + goto cgd_calc; + } + c = pow(nsm/NMAX,GAMMA); + q = pow(1+c,1.0/GAMMA); + ns = nsm/q; + gchi = GCHI0*ns; + gch = gchi/(1+gchi*rt); + gchim = GCHI0*nsm; + h = sqrt(1+2*gchim*RSI + vgte*vgte/(vl*vl)); + p = 1+gchim*RSI+h; + isatm = gchim*vgte/p; + g = pow(isatm/IMAX,GAMMA); + isat = isatm/pow(1+g,1/GAMMA); + vsate = isat/gch; + d = pow(vds/vsate,M); + e = pow(1+d,1.0/M); + delidgch = vds*(1+TLAMBDA*vds)/e; + *cdrain = gch*delidgch; + delidvsate = (*cdrain)*d/vsate/(1+d); + delidvds = gch*(1+2*TLAMBDA*vds)/e-(*cdrain)* + pow(vds/vsate,M-1)/(vsate*(1+d)); + a = 1+gchi*rt; + delgchgchi = 1.0/(a*a); + delgchins = GCHI0; + delnsnsm = ns/nsm*(1-c/(1+c)); + delvgtevgt = 0.5*(1+u/t); + delnsmvgt = N0/etavth/(1.0/b + 0.5); + if(model->HFETAeta2Given && model->HFETAd2Given) + delnsmvgt = nsc*(nsc*delnsmvgt+nsn*nsn/(ETA2*vt))/((nsc+nsn)*(nsc+nsn)); + delvsateisat = 1.0/gch; + delisatisatm = isat/isatm*(1-g/(1+g)); + delisatmvgte = gchim*(p - vgte*vgte/(vl*vl*h))/(p*p); + delvsategch = -vsate/gch; + delisatmgchim = vgte*(p - gchim*RSI*(1+1.0/h))/(p*p); + delvgtvgs = 1-vds*SIGMA0/VSIGMA*s/((1+s)*(1+s)); + p = delgchgchi*delgchins*delnsnsm*delnsmvgt; + delvsatevgt = (delvsateisat*delisatisatm*(delisatmvgte*delvgtevgt + + delisatmgchim*GCHI0*delnsmvgt)+delvsategch*p); + g = delidgch*p + delidvsate*delvsatevgt; + *gm = g*delvgtvgs; + *gds = delidvds + g*sigma; + + // Capacitance calculations + temp = ETA1*vt; + cg1 = 1/(D1/EPSI+temp*exp(-(vgs-IN_VT1)/temp)); + cgc = W*L*(CHARGE*delnsnsm*delnsmvgt*delvgtvgs+cg1); + vdse = vds*pow(1+pow(vds/vsate,MC),-1.0/MC); + a = (vsate-vdse)/(2*vsate-vdse); + a = a*a; + temp = 2.0/3.0; + p = PM + (1-PM)*exp(-vds/vsate); + *capgs = CF+2*temp*cgc*(1-a)/(1+p); + a = vsate/(2*vsate-vdse); + a = a*a; + *capgd = CF+2*p*temp*cgc*(1-a)/(1+p); +/* + { + char buf[128]; + FILE *fp; + fp = fopen("d:\\temp\\debug.txt","at"); + sprintf(buf,"%f\t%f\t%e\t%e\n",vgs,vds,W*L*CHARGE*delnsnsm*delnsmvgt*delvgtvgs,cgc); + fputs(buf,fp); + fclose(fp); + } +*/ +cgd_calc: + + if(model->HFETAgatemod != 0) { + // Gate-drain current calculation + double vkneet; + double vmax; + double td; + double delcgdvgs; + double delcgdtd; + double deltdvdse; + double deltdvkneet; + double delvdsevmax; + double delvdsevds; + double dvdsevgs; + double dvdsevds; + double dtdvgs; + double dtdvds; + + vkneet = CK1*vsate+CK2; + vmax = CM1*vsate+CM2; + a = pow(vds/vmax,MT2); + b = pow(1+a,1/MT2); + vdse = vds/b; + c = pow(vdse/vkneet,MT1); + d = pow(1+c,1/MT1); + td = TEMP+TALPHA*vdse*vdse/d; + e = CONSTKoverQ*td*M2D; + p = PHIB/(CONSTboltz*td); + f = exp(-p); + q = (vgs-vdse)/e; + g = exp(q); + h = ISO*td*td*f*g; + *cgd = h - ISO*TEMP*TEMP*exp(-PHIB/(CONSTboltz*TEMP)); + delcgdvgs = h/e; + delcgdtd = h*(p-q+2)/td; + deltdvdse = TALPHA*vdse*(2-c/(1+c))/d; + deltdvkneet = (td-TEMP)*c/((1+c)*vkneet); + delvdsevmax = vdse*a/((1+a)*vmax); + delvdsevds = (1-a/(1+a))/b; + temp = delvsatevgt*delvgtvgs; + dvdsevgs = delvdsevmax*CM1*temp; + dtdvgs = deltdvdse*dvdsevgs+deltdvkneet*CK1*temp; + *gmg = delcgdvgs+delcgdtd*dtdvgs; + temp = delvsatevgt*sigma; + dvdsevds = delvdsevds+delvdsevmax*CM1*temp; + dtdvds = deltdvdse*dvdsevds+deltdvkneet*CK1*temp; + *gmd = -delcgdvgs*dvdsevds+delcgdtd*dtdvds; + } else { + gmg = 0; + gmd = 0; + } + + if(model->HFETAgatemod != 0) { + // Gate-source current calculation + double evgs; + double vtn = vt*M2S; + double csat = ISO*TEMP*TEMP*exp(-PHIB/(CONSTboltz*TEMP)); + if (vgs <= -5*vt) { + *ggs = -csat/vgs+ckt->CKTgmin; + *cgs = (*ggs)*vgs; + } else { + evgs = exp(vgs/vtn); + *ggs = csat*evgs/vtn+ckt->CKTgmin; + *cgs = csat*(evgs-1)+ckt->CKTgmin*vgs; + } + } + + if(model->HFETAgatemod != 0 && (A1 != 0.0 || A2 != 0.0)) { + // Correction current calculations + double vmax; + double delvdsevmax; + double delvdsevds; + double dvdsevgs; + double dvdsevds; + vmax = CM3*vsate; + a = pow(vds/vmax,MV1); + b = pow(1+a,1/MV1); + vdse = vds/b; + delvdsevmax = vdse*a/((1+a)*vmax); + delvdsevds = (1-a/(1+a))/b; + dvdsevgs = delvdsevmax*CM3*delvsatevgt*delvgtvgs; + dvdsevds = delvdsevds+delvdsevmax*CM3*delvsatevgt*sigma; + c = vgte*vdse; + d = 1+A2*c; + e = vdse*delvgtevgt; + f = A2*(*cgd); + *cdrain += A1*(d*(*cgd) - (*cgs)); + *gds += A1*(d*(*gmd)+f*(vgte*dvdsevds+e*sigma)); + *gm += A1*(d*(*gmg)+f*(vgte*dvdsevgs+e*delvgtvgs) - (*ggs)); + } + +} + + +double diode(double u) +{ + +#define U0 (-2.303) +#define A (2.221) +#define B (6.804) +#define C (1.685) + double it; + double ut; + double b; + double c; + double i; + double expu=exp(u); + + if(u <= U0) + { + it = expu*(1-expu); + }else + { + b = 0.5*(u-U0); + it = u + A*exp((U0-u)/B) - log(b+sqrt(b*b + 0.25*C*C)); + } + + ut = it + log(it); + b = u-ut; + c = 1+it; + i = it*(1 + b/c + 0.5*b*b/c/c/c); + return(i); +} diff --git a/src/spicelib/devices/hfet1/hfetmask.c b/src/spicelib/devices/hfet1/hfetmask.c new file mode 100644 index 000000000..0c942afbd --- /dev/null +++ b/src/spicelib/devices/hfet1/hfetmask.c @@ -0,0 +1,245 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Thomas L. Quarles +**********/ +/* +Imported into HFETA model: Paolo Nenzi 2001 + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "devdefs.h" +#include "ifsim.h" +#include "hfetdefs.h" +#include "sperror.h" +#include "suffix.h" + + +/* ARGSUSED */ +int +HFETAmAsk(ckt,inst,which,value) + CKTcircuit *ckt; + GENmodel *inst; + int which; + IFvalue *value; +{ + HFETAmodel *here = (HFETAmodel*)inst; + switch(which) { + case HFETA_MOD_VTO: + value->rValue = here->HFETAthreshold; + return (OK); + case HFETA_MOD_LAMBDA: + value->rValue = here->HFETAlambda; + return (OK); + case HFETA_MOD_RD: + value->rValue = here->HFETArd; + return (OK); + case HFETA_MOD_RS: + value->rValue = here->HFETArs; + return (OK); + case HFETA_MOD_RG: + value->rValue = here->HFETArg; + return (OK); + case HFETA_MOD_RDI: + value->rValue = here->HFETArdi; + return (OK); + case HFETA_MOD_RSI: + value->rValue = here->HFETArsi; + return (OK); + case HFETA_MOD_RGS: + value->rValue = here->HFETArgs; + return (OK); + case HFETA_MOD_RGD: + value->rValue = here->HFETArgd; + return (OK); + case HFETA_MOD_RI: + value->rValue = here->HFETAri; + return (OK); + case HFETA_MOD_RF: + value->rValue = here->HFETArf; + return (OK); + case HFETA_MOD_ETA: + value->rValue = here->HFETAeta; + return (OK); + case HFETA_MOD_M: + value->rValue = here->HFETAm; + return (OK); + case HFETA_MOD_MC: + value->rValue = here->HFETAmc; + return (OK); + case HFETA_MOD_GAMMA: + value->rValue = here->HFETAgamma; + return (OK); + case HFETA_MOD_SIGMA0: + value->rValue = here->HFETAsigma0; + return (OK); + case HFETA_MOD_VSIGMAT: + value->rValue = here->HFETAvsigmat; + return (OK); + case HFETA_MOD_VSIGMA: + value->rValue = here->HFETAvsigma; + return (OK); + case HFETA_MOD_MU: + value->rValue = here->HFETAmu; + return (OK); + case HFETA_MOD_DI: + value->rValue = here->HFETAdi; + return (OK); + case HFETA_MOD_DELTA: + value->rValue = here->HFETAdelta; + return (OK); + case HFETA_MOD_VS: + value->rValue = here->HFETAvs; + return (OK); + case HFETA_MOD_NMAX: + value->rValue = here->HFETAnmax; + return (OK); + case HFETA_MOD_DELTAD: + value->rValue = here->HFETAdeltad; + return (OK); + case HFETA_MOD_JS1D: + value->rValue = here->HFETAjs1d; + return (OK); + case HFETA_MOD_JS2D: + value->rValue = here->HFETAjs2d; + return (OK); + case HFETA_MOD_JS1S: + value->rValue = here->HFETAjs1s; + return (OK); + case HFETA_MOD_JS2S: + value->rValue = here->HFETAjs2s; + return (OK); + case HFETA_MOD_M1D: + value->rValue = here->HFETAm1d; + return (OK); + case HFETA_MOD_M2D: + value->rValue = here->HFETAm2d; + return (OK); + case HFETA_MOD_M1S: + value->rValue = here->HFETAm1s; + return (OK); + case HFETA_MOD_M2S: + value->rValue = here->HFETAm2s; + return (OK); + case HFETA_MOD_EPSI: + value->rValue = here->HFETAepsi; + return (OK); + case HFETA_MOD_P: + value->rValue = here->HFETAp; + return (OK); + case HFETA_MOD_CM3: + value->rValue = here->HFETAcm3; + return (OK); + case HFETA_MOD_A1: + value->rValue = here->HFETAa1; + return (OK); + case HFETA_MOD_A2: + value->rValue = here->HFETAa2; + return (OK); + case HFETA_MOD_MV1: + value->rValue = here->HFETAmv1; + return (OK); + case HFETA_MOD_KAPPA: + value->rValue = here->HFETAkappa; + return (OK); + case HFETA_MOD_DELF: + value->rValue = here->HFETAdelf; + return (OK); + case HFETA_MOD_FGDS: + value->rValue = here->HFETAfgds; + return (OK); + case HFETA_MOD_TF: + value->rValue = here->HFETAtf; + return (OK); + case HFETA_MOD_CDS: + value->rValue = here->HFETAcds; + return (OK); + case HFETA_MOD_PHIB: + value->rValue = here->HFETAphib; + return (OK); + + case HFETA_MOD_TALPHA: + value->rValue = here->HFETAtalpha; + return (OK); + case HFETA_MOD_MT1: + value->rValue = here->HFETAmt1; + return (OK); + case HFETA_MOD_MT2: + value->rValue = here->HFETAmt2; + return (OK); + case HFETA_MOD_CK1: + value->rValue = here->HFETAck1; + return (OK); + case HFETA_MOD_CK2: + value->rValue = here->HFETAck2; + return (OK); + case HFETA_MOD_CM1: + value->rValue = here->HFETAcm1; + return (OK); + case HFETA_MOD_CM2: + value->rValue = here->HFETAcm2; + return (OK); + case HFETA_MOD_ASTAR: + value->rValue = here->HFETAastar; + return (OK); + case HFETA_MOD_ETA1: + value->rValue = here->HFETAeta1; + return (OK); + case HFETA_MOD_D1: + value->rValue = here->HFETAd1; + return (OK); + case HFETA_MOD_VT1: + value->rValue = here->HFETAvt1; + return (OK); + case HFETA_MOD_ETA2: + value->rValue = here->HFETAeta2; + return (OK); + case HFETA_MOD_D2: + value->rValue = here->HFETAd2; + return (OK); + case HFETA_MOD_VT2: + value->rValue = here->HFETAvt2; + return (OK); + case HFETA_MOD_GGR: + value->rValue = here->HFETAggr; + return (OK); + case HFETA_MOD_DEL: + value->rValue = here->HFETAdel; + return (OK); + case HFETA_MOD_GATEMOD: + value->iValue = here->HFETAgatemod; + return (OK); + case HFETA_MOD_KLAMBDA: + value->rValue = here->HFETAklambda; + return (OK); + case HFETA_MOD_KMU: + value->rValue = here->HFETAkmu; + return (OK); + case HFETA_MOD_KVTO: + value->rValue = here->HFETAkvto; + return (OK); + + case HFETA_MOD_DRAINCONDUCT: + value->rValue = here->HFETAdrainConduct; + return (OK); + case HFETA_MOD_SOURCECONDUCT: + value->rValue = here->HFETAsourceConduct; + return (OK); + /* case HFETA_MOD_DEPLETIONCAP: + value->rValue = here->HFETA???; + return(OK); */ + /* case HFETA_MOD_VCRIT: + value->rValue = here->HFETAvcrit; + return (OK); */ + + case HFETA_MOD_TYPE: + if (here->HFETAtype == NHFET) + value->sValue = "nhfet"; + else + value->sValue = "phfet"; + default: + return (E_BADPARM); + } + /* NOTREACHED */ +} diff --git a/src/spicelib/devices/hfet1/hfetmdel.c b/src/spicelib/devices/hfet1/hfetmdel.c new file mode 100644 index 000000000..2dd7aa40e --- /dev/null +++ b/src/spicelib/devices/hfet1/hfetmdel.c @@ -0,0 +1,45 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 S. Hwang +**********/ +/* +Imported into hfeta model: Paolo Nenzi 2001 + */ + +#include "ngspice.h" +#include +#include "hfetdefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +HFETAmDelete(inModel,modname,kill) + GENmodel **inModel; + IFuid modname; + GENmodel *kill; +{ + HFETAmodel **model = (HFETAmodel**)inModel; + HFETAmodel *modfast = (HFETAmodel*)kill; + HFETAinstance *here; + HFETAinstance *prev = NULL; + HFETAmodel **oldmod; + oldmod = model; + for( ; *model ; model = &((*model)->HFETAnextModel)) { + if( (*model)->HFETAmodName == modname || + (modfast && *model == modfast) ) goto delgot; + oldmod = model; + } + return(E_NOMOD); + +delgot: + *oldmod = (*model)->HFETAnextModel; /* cut deleted device out of list */ + for(here = (*model)->HFETAinstances ; here ; here = here->HFETAnextInstance) { + if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + FREE(*model); + return(OK); + +} diff --git a/src/spicelib/devices/hfet1/hfetmpar.c b/src/spicelib/devices/hfet1/hfetmpar.c new file mode 100644 index 000000000..4a3a05b8f --- /dev/null +++ b/src/spicelib/devices/hfet1/hfetmpar.c @@ -0,0 +1,290 @@ + +#include "ngspice.h" +#include +#include "const.h" +#include "ifsim.h" +#include "hfetdefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +HFETAmParam(param,value,inModel) + int param; + IFvalue *value; + GENmodel *inModel; +{ + HFETAmodel *model = (HFETAmodel*)inModel; + switch(param) + { + case HFETA_MOD_VTO: + model->HFETAthresholdGiven = TRUE; + model->HFETAthreshold = value->rValue; + break; + case HFETA_MOD_LAMBDA: + model->HFETAlambdaGiven = TRUE; + model->HFETAlambda = value->rValue; + break; + case HFETA_MOD_RD: + model->HFETArdGiven = TRUE; + model->HFETArd = value->rValue; + break; + case HFETA_MOD_RS: + model->HFETArsGiven = TRUE; + model->HFETArs = value->rValue; + break; + case HFETA_MOD_RG: + model->HFETArgGiven = TRUE; + model->HFETArg = value->rValue; + break; + case HFETA_MOD_RDI: + model->HFETArdiGiven = TRUE; + model->HFETArdi = value->rValue; + break; + case HFETA_MOD_RSI: + model->HFETArsiGiven = TRUE; + model->HFETArsi = value->rValue; + break; + case HFETA_MOD_RGS: + model->HFETArgsGiven = TRUE; + model->HFETArgs = value->rValue; + break; + case HFETA_MOD_RGD: + model->HFETArgdGiven = TRUE; + model->HFETArgd = value->rValue; + break; + case HFETA_MOD_RI: + model->HFETAriGiven = TRUE; + model->HFETAri = value->rValue; + break; + case HFETA_MOD_RF: + model->HFETArfGiven = TRUE; + model->HFETArf = value->rValue; + break; + case HFETA_MOD_ETA: + model->HFETAetaGiven = TRUE; + model->HFETAeta = value->rValue; + break; + case HFETA_MOD_M: + model->HFETAmGiven = TRUE; + model->HFETAm = value->rValue; + break; + case HFETA_MOD_MC: + model->HFETAmcGiven = TRUE; + model->HFETAmc = value->rValue; + break; + case HFETA_MOD_GAMMA: + model->HFETAgammaGiven = TRUE; + model->HFETAgamma = value->rValue; + break; + case HFETA_MOD_SIGMA0: + model->HFETAsigma0Given = TRUE; + model->HFETAsigma0 = value->rValue; + break; + case HFETA_MOD_VSIGMAT: + model->HFETAvsigmatGiven = TRUE; + model->HFETAvsigmat = value->rValue; + break; + case HFETA_MOD_VSIGMA: + model->HFETAvsigmaGiven = TRUE; + model->HFETAvsigma = value->rValue; + break; + case HFETA_MOD_MU: + model->HFETAmuGiven = TRUE; + model->HFETAmu = value->rValue; + break; + case HFETA_MOD_DI: + model->HFETAdiGiven = TRUE; + model->HFETAdi = value->rValue; + break; + case HFETA_MOD_DELTA: + model->HFETAdeltaGiven = TRUE; + model->HFETAdelta = value->rValue; + break; + case HFETA_MOD_VS: + model->HFETAvsGiven = TRUE; + model->HFETAvs = value->rValue; + break; + case HFETA_MOD_NMAX: + model->HFETAnmaxGiven = TRUE; + model->HFETAnmax = value->rValue; + break; + case HFETA_MOD_DELTAD: + model->HFETAdeltadGiven = TRUE; + model->HFETAdeltad = value->rValue; + break; + case HFETA_MOD_JS1D: + model->HFETAjs1dGiven = TRUE; + model->HFETAjs1d = value->rValue; + break; + case HFETA_MOD_JS2D: + model->HFETAjs2dGiven = TRUE; + model->HFETAjs2d = value->rValue; + break; + case HFETA_MOD_JS1S: + model->HFETAjs1sGiven = TRUE; + model->HFETAjs1s = value->rValue; + break; + case HFETA_MOD_JS2S: + model->HFETAjs2sGiven = TRUE; + model->HFETAjs2s = value->rValue; + break; + case HFETA_MOD_M1D: + model->HFETAm1dGiven = TRUE; + model->HFETAm1d = value->rValue; + break; + case HFETA_MOD_M2D: + model->HFETAm2dGiven = TRUE; + model->HFETAm2d = value->rValue; + break; + case HFETA_MOD_M1S: + model->HFETAm1sGiven = TRUE; + model->HFETAm1s = value->rValue; + break; + case HFETA_MOD_M2S: + model->HFETAm2sGiven = TRUE; + model->HFETAm2s = value->rValue; + break; + case HFETA_MOD_EPSI: + model->HFETAepsiGiven = TRUE; + model->HFETAepsi = value->rValue; + break; + case HFETA_MOD_A1: + model->HFETAa1Given = TRUE; + model->HFETAa1 = value->rValue; + break; + case HFETA_MOD_A2: + model->HFETAa2Given = TRUE; + model->HFETAa2 = value->rValue; + break; + case HFETA_MOD_MV1: + model->HFETAmv1Given = TRUE; + model->HFETAmv1 = value->rValue; + break; + case HFETA_MOD_P: + model->HFETApGiven = TRUE; + model->HFETAp = value->rValue; + break; + case HFETA_MOD_KAPPA: + model->HFETAkappaGiven = TRUE; + model->HFETAkappa = value->rValue; + break; + case HFETA_MOD_DELF: + model->HFETAdelfGiven = TRUE; + model->HFETAdelf = value->rValue; + break; + case HFETA_MOD_FGDS: + model->HFETAfgdsGiven = TRUE; + model->HFETAfgds = value->rValue; + break; + case HFETA_MOD_TF: + model->HFETAtfGiven = TRUE; + model->HFETAtf = value->rValue+CONSTCtoK; + break; + case HFETA_MOD_CDS: + model->HFETAcdsGiven = TRUE; + model->HFETAcds = value->rValue; + break; + case HFETA_MOD_PHIB: + model->HFETAphibGiven = TRUE; + model->HFETAphib = value->rValue*CHARGE; + break; + case HFETA_MOD_TALPHA: + model->HFETAtalphaGiven = TRUE; + model->HFETAtalpha = value->rValue; + break; + case HFETA_MOD_MT1: + model->HFETAmt1Given = TRUE; + model->HFETAmt1 = value->rValue; + break; + case HFETA_MOD_MT2: + model->HFETAmt2Given = TRUE; + model->HFETAmt2 = value->rValue; + break; + case HFETA_MOD_CK1: + model->HFETAck1Given = TRUE; + model->HFETAck1 = value->rValue; + break; + case HFETA_MOD_CK2: + model->HFETAck2Given = TRUE; + model->HFETAck2 = value->rValue; + break; + case HFETA_MOD_CM1: + model->HFETAcm1Given = TRUE; + model->HFETAcm1 = value->rValue; + break; + case HFETA_MOD_CM2: + model->HFETAcm2Given = TRUE; + model->HFETAcm2 = value->rValue; + break; + case HFETA_MOD_CM3: + model->HFETAcm3Given = TRUE; + model->HFETAcm3 = value->rValue; + break; + case HFETA_MOD_ASTAR: + model->HFETAastarGiven = TRUE; + model->HFETAastar = value->rValue; + break; + case HFETA_MOD_ETA1: + model->HFETAeta1Given = TRUE; + model->HFETAeta1 = value->rValue; + break; + case HFETA_MOD_D1: + model->HFETAd1Given = TRUE; + model->HFETAd1 = value->rValue; + break; + case HFETA_MOD_VT1: + model->HFETAvt1Given = TRUE; + model->HFETAvt1 = value->rValue; + break; + case HFETA_MOD_ETA2: + model->HFETAeta2Given = TRUE; + model->HFETAeta2 = value->rValue; + break; + case HFETA_MOD_D2: + model->HFETAd2Given = TRUE; + model->HFETAd2 = value->rValue; + break; + case HFETA_MOD_VT2: + model->HFETAvt2Given = TRUE; + model->HFETAvt2 = value->rValue; + break; + case HFETA_MOD_GGR: + model->HFETAggrGiven = TRUE; + model->HFETAggr = value->rValue; + break; + case HFETA_MOD_DEL: + model->HFETAdelGiven = TRUE; + model->HFETAdel = value->rValue; + break; + case HFETA_MOD_GATEMOD: + model->HFETAgatemodGiven = TRUE; + model->HFETAgatemod = value->iValue; + break; + case HFETA_MOD_KLAMBDA: + model->HFETAklambdaGiven = TRUE; + KLAMBDA = value->rValue; + break; + case HFETA_MOD_KMU: + model->HFETAkmuGiven = TRUE; + KMU = value->rValue; + break; + case HFETA_MOD_KVTO: + model->HFETAkvtoGiven = TRUE; + KVTO = value->rValue; + break; + case HFETA_MOD_NHFET: + if(value->iValue) { + model->HFETAtype = NHFET; + } + break; + case HFETA_MOD_PHFET: + if(value->iValue) { + model->HFETAtype = PHFET; + } + break; + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/hfet1/hfetparam.c b/src/spicelib/devices/hfet1/hfetparam.c new file mode 100644 index 000000000..5fef5ff9c --- /dev/null +++ b/src/spicelib/devices/hfet1/hfetparam.c @@ -0,0 +1,60 @@ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "hfetdefs.h" +#include "sperror.h" +#include "suffix.h" + + +/* ARGSUSED */ +int +HFETAparam(param,value,inst,select) + int param; + IFvalue *value; + GENinstance *inst; + IFvalue *select; +{ + HFETAinstance *here = (HFETAinstance*)inst; + switch(param) { + case HFETA_LENGTH: + here->HFETAlength = value->rValue; + here->HFETAlengthGiven = TRUE; + break; + case HFETA_WIDTH: + here->HFETAwidth = value->rValue; + here->HFETAwidthGiven = TRUE; + break; + case HFETA_IC_VDS: + here->HFETAicVDS = value->rValue; + here->HFETAicVDSGiven = TRUE; + break; + case HFETA_IC_VGS: + here->HFETAicVGS = value->rValue; + here->HFETAicVGSGiven = TRUE; + break; + case HFETA_OFF: + here->HFETAoff = value->iValue; + break; + case HFETA_IC: + switch(value->v.numValue) { + case 2: + here->HFETAicVGS = *(value->v.vec.rVec+1); + here->HFETAicVGSGiven = TRUE; + case 1: + here->HFETAicVDS = *(value->v.vec.rVec); + here->HFETAicVDSGiven = TRUE; + break; + default: + return(E_BADPARM); + } + break; + case HFETA_TEMP: + here->HFETAtemp = value->rValue+CONSTCtoK; + here->HFETAtempGiven = TRUE; + break; + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/hfet1/hfetsetup.c b/src/spicelib/devices/hfet1/hfetsetup.c new file mode 100644 index 000000000..5b5f36f7e --- /dev/null +++ b/src/spicelib/devices/hfet1/hfetsetup.c @@ -0,0 +1,432 @@ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "hfetdefs.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + +//#define HFETAphibGiven +//#define CHARGE 1.60219e-19 + +int +HFETAsetup(matrix,inModel,ckt,states) + SMPmatrix *matrix; + GENmodel *inModel; + CKTcircuit *ckt; + int *states; + /* load the diode structure with those pointers needed later + * for fast matrix loading + */ +{ + HFETAmodel *model = (HFETAmodel*)inModel; + HFETAinstance *here; + int error; + CKTnode *tmp; + + + /* loop through all the diode models */ + for( ; model != NULL; model = model->HFETAnextModel ) { + if( (model->HFETAtype != NHFET) && (model->HFETAtype != PHFET) ) { + model->HFETAtype = NHFET; + } + if(!model->HFETAthresholdGiven) { + if(model->HFETAtype == NHFET) + model->HFETAthreshold = 0.15; + else + model->HFETAthreshold = -0.15; + } + if(!model->HFETAdiGiven) { + model->HFETAdi = 0.04e-6; + } + if(!model->HFETAlambdaGiven) { + model->HFETAlambda = 0.15; + } + if(!model->HFETAetaGiven) { + if(model->HFETAtype == NHFET) + model->HFETAeta = 1.28; + else + model->HFETAeta = 1.4; + } + if(!model->HFETAmGiven) { + model->HFETAm = 3.0; + } + if(!model->HFETAmcGiven) { + model->HFETAmc = 3.0; + } + if(!model->HFETAgammaGiven) { + model->HFETAgamma = 3.0; + } + if(!model->HFETAsigma0Given) { + model->HFETAsigma0 = 0.057; + } + if(!model->HFETAvsigmatGiven) { + model->HFETAvsigmat = 0.3; + } + if(!model->HFETAvsigmaGiven) { + model->HFETAvsigma = 0.1; + } + if(!model->HFETAmuGiven) { + if(model->HFETAtype == NHFET) + model->HFETAmu = 0.4; + else + model->HFETAmu = 0.03; + } + if(!model->HFETAdeltaGiven) { + model->HFETAdelta = 3.0; + } + if(!model->HFETAvsGiven) { + if(model->HFETAtype == NHFET) + model->HFETAvs = 1.5e5; + else + model->HFETAvs = 0.8e5; + } + if(!model->HFETAnmaxGiven) { + model->HFETAnmax = 2e16; + } + if(!model->HFETAdeltadGiven) { + model->HFETAdeltad = 4.5e-9; + } + if(!model->HFETAjs1dGiven) { + model->HFETAjs1d = 1.0; + } + if(!model->HFETAjs2dGiven) { + model->HFETAjs2d = 1.15e6; + } + if(!model->HFETAjs1sGiven) { + model->HFETAjs1s = 1.0; + } + if(!model->HFETAjs2sGiven) { + model->HFETAjs2s = 1.15e6; + } + if(!model->HFETAm1dGiven) { + model->HFETAm1d = 1.32; + } + if(!model->HFETAm2dGiven) { + model->HFETAm2d = 6.9; + } + if(!model->HFETAm1sGiven) { + model->HFETAm1s = 1.32; + } + if(!model->HFETAm2sGiven) { + model->HFETAm2s = 6.9; + } + if(!model->HFETArdGiven) { + model->HFETArd = 0; + } + if(!model->HFETArsGiven) { + model->HFETArs = 0; + } + if(!model->HFETArdiGiven) { + model->HFETArdi = 0; + } + if(!model->HFETArsiGiven) { + model->HFETArsi = 0; + } + if(!model->HFETArgsGiven) { + model->HFETArgs = 90; + } + if(!model->HFETArgdGiven) { + model->HFETArgd = 90; + } + if(!model->HFETAriGiven) { + model->HFETAri = 0; + } + if(!model->HFETArfGiven) { + model->HFETArf = 0; + } + if(!model->HFETAepsiGiven) { + model->HFETAepsi = 12.244*8.85418e-12; + } + if(!model->HFETAa1Given) { + model->HFETAa1 = 0; + } + if(!model->HFETAa2Given) { + model->HFETAa2 = 0; + } + if(!model->HFETAmv1Given) { + model->HFETAmv1 = 3; + } + if(!model->HFETApGiven) { + model->HFETAp = 1; + } + if(!model->HFETAkappaGiven) { + model->HFETAkappa = 0; + } + if(!model->HFETAdelfGiven) { + model->HFETAdelf = 0; + } + if(!model->HFETAfgdsGiven) { + model->HFETAfgds = 0; + } + if(!model->HFETAtfGiven) { + model->HFETAtf = ckt->CKTtemp; + } + if(!model->HFETAcdsGiven) { + model->HFETAcds = 0; + } + if(!model->HFETAphibGiven) { + model->HFETAphib = 0.5*CHARGE; + } + if(!model->HFETAtalphaGiven) { + model->HFETAtalpha = 1200; + } + if(!model->HFETAmt1Given) { + model->HFETAmt1 = 3.5; + } + if(!model->HFETAmt2Given) { + model->HFETAmt2 = 9.9; + } + if(!model->HFETAck1Given) { + model->HFETAck1 = 1; + } + if(!model->HFETAck2Given) { + model->HFETAck2 = 0; + } + if(!model->HFETAcm1Given) { + model->HFETAcm1 = 3; + } + if(!model->HFETAcm2Given) { + model->HFETAcm2 = 0; + } + if(!model->HFETAcm3Given) { + model->HFETAcm3 = 0.17; + } + if(!model->HFETAastarGiven) { + model->HFETAastar = 4.0e4; + } + if(!model->HFETAeta1Given) { + model->HFETAeta1 = 2; + } + if(!model->HFETAd1Given) { + model->HFETAd1 = 0.03e-6; + } + if(!model->HFETAeta2Given) { + model->HFETAeta2 = 2; + } + if(!model->HFETAd2Given) { + model->HFETAd2 = 0.2e-6; + } + if(!model->HFETAvt2Given) { + // initialized in HFETAtemp + model->HFETAvt2 = 0; + } + + if(!model->HFETAggrGiven) { + model->HFETAggr = 40; + } + if(!model->HFETAdelGiven) { + model->HFETAdel = 0.04; + } + if(!model->HFETAklambdaGiven) + KLAMBDA = 0; + if(!model->HFETAkmuGiven) + KMU = 0; + if(!model->HFETAkvtoGiven) + KVTO = 0; + + /* loop through all the instances of the model */ + for (here = model->HFETAinstances; here != NULL ; + here=here->HFETAnextInstance) { + + if(!here->HFETAlengthGiven) { + here->HFETAlength = 1e-6; + } + if(!here->HFETAwidthGiven) { + here->HFETAwidth = 20e-6; + } + if(!here->HFETAtempGiven) { + here->HFETAtemp = ckt->CKTtemp; + } + + here->HFETAstate = *states; + // *states += 24; + *states += HFETAnumStates; + +matrixpointers: + if(model->HFETArs != 0 && here->HFETAsourcePrimeNode==0) { + error = CKTmkVolt(ckt,&tmp,here->HFETAname,"source"); + if(error) return(error); + here->HFETAsourcePrimeNode = tmp->number; + +/* XXX: Applied AlansFixes */ + 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->HFETAsourcePrimeNode = here->HFETAsourceNode; + } + + if(model->HFETArd != 0 && here->HFETAdrainPrimeNode==0) { + error = CKTmkVolt(ckt,&tmp,here->HFETAname,"drain"); + if(error) return(error); + here->HFETAdrainPrimeNode = tmp->number; + +/* XXX: Applied AlansFixes */ + 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->HFETAdrainPrimeNode = here->HFETAdrainNode; + } + + if(model->HFETArg != 0 && here->HFETAgatePrimeNode==0) { + error = CKTmkVolt(ckt,&tmp,here->HFETAname,"gate"); + if(error) return(error); + here->HFETAgatePrimeNode = tmp->number; + +/* XXX: Applied AlansFixes */ + 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->HFETAgatePrimeNode = here->HFETAgateNode; + } + if(model->HFETArf != 0 && here->HFETAdrainPrmPrmNode==0) { + error = CKTmkVolt(ckt,&tmp,here->HFETAname,"gd"); + if(error) return(error); + here->HFETAdrainPrmPrmNode = tmp->number; + +/* XXX: Applied AlansFixes */ + 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->HFETAdrainPrmPrmNode = here->HFETAdrainPrimeNode; + } + + if(model->HFETAri != 0 && here->HFETAsourcePrmPrmNode==0) { + error = CKTmkVolt(ckt,&tmp,here->HFETAname,"gs"); + if(error) return(error); + here->HFETAsourcePrmPrmNode = tmp->number; + +/* XXX: Applied AlanFixes */ + 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->HFETAsourcePrmPrmNode = here->HFETAsourcePrimeNode; + } + +/* macro to make elements with built in test for out of memory */ +#define TSTALLOC(ptr,first,second) \ +if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ + return(E_NOMEM);\ +} + + TSTALLOC(HFETAdrainDrainPrimePtr,HFETAdrainNode,HFETAdrainPrimeNode) + TSTALLOC(HFETAgatePrimeDrainPrimePtr,HFETAgatePrimeNode,HFETAdrainPrimeNode) + TSTALLOC(HFETAgatePrimeSourcePrimePtr,HFETAgatePrimeNode,HFETAsourcePrimeNode) + TSTALLOC(HFETAsourceSourcePrimePtr,HFETAsourceNode,HFETAsourcePrimeNode) + TSTALLOC(HFETAdrainPrimeDrainPtr,HFETAdrainPrimeNode,HFETAdrainNode) + TSTALLOC(HFETAdrainPrimeGatePrimePtr,HFETAdrainPrimeNode,HFETAgatePrimeNode) + TSTALLOC(HFETAdrainPrimeSourcePrimePtr,HFETAdrainPrimeNode,HFETAsourcePrimeNode) + TSTALLOC(HFETAsourcePrimeGatePrimePtr,HFETAsourcePrimeNode,HFETAgatePrimeNode) + TSTALLOC(HFETAsourcePrimeSourcePtr,HFETAsourcePrimeNode,HFETAsourceNode) + TSTALLOC(HFETAsourcePrimeDrainPrimePtr,HFETAsourcePrimeNode,HFETAdrainPrimeNode) + TSTALLOC(HFETAdrainDrainPtr,HFETAdrainNode,HFETAdrainNode) + TSTALLOC(HFETAgatePrimeGatePrimePtr,HFETAgatePrimeNode,HFETAgatePrimeNode) + TSTALLOC(HFETAsourceSourcePtr,HFETAsourceNode,HFETAsourceNode) + TSTALLOC(HFETAdrainPrimeDrainPrimePtr,HFETAdrainPrimeNode,HFETAdrainPrimeNode) + TSTALLOC(HFETAsourcePrimeSourcePrimePtr,HFETAsourcePrimeNode,HFETAsourcePrimeNode) + TSTALLOC(HFETAdrainPrimeDrainPrmPrmPtr,HFETAdrainPrimeNode,HFETAdrainPrmPrmNode) + TSTALLOC(HFETAdrainPrmPrmDrainPrimePtr,HFETAdrainPrmPrmNode,HFETAdrainPrimeNode) + TSTALLOC(HFETAdrainPrmPrmGatePrimePtr,HFETAdrainPrmPrmNode,HFETAgatePrimeNode) + TSTALLOC(HFETAgatePrimeDrainPrmPrmPtr,HFETAgatePrimeNode,HFETAdrainPrmPrmNode) + TSTALLOC(HFETAdrainPrmPrmDrainPrmPrmPtr,HFETAdrainPrmPrmNode,HFETAdrainPrmPrmNode) + TSTALLOC(HFETAsourcePrimeSourcePrmPrmPtr,HFETAsourcePrimeNode,HFETAsourcePrmPrmNode) + TSTALLOC(HFETAsourcePrmPrmSourcePrimePtr,HFETAsourcePrmPrmNode,HFETAsourcePrimeNode) + TSTALLOC(HFETAsourcePrmPrmGatePrimePtr,HFETAsourcePrmPrmNode,HFETAgatePrimeNode) + TSTALLOC(HFETAgatePrimeSourcePrmPrmPtr,HFETAgatePrimeNode,HFETAsourcePrmPrmNode) + TSTALLOC(HFETAsourcePrmPrmSourcePrmPrmPtr,HFETAsourcePrmPrmNode,HFETAsourcePrmPrmNode) + TSTALLOC(HFETAgateGatePtr,HFETAgateNode,HFETAgateNode) + TSTALLOC(HFETAgateGatePrimePtr,HFETAgateNode,HFETAgatePrimeNode) + TSTALLOC(HFETAgatePrimeGatePtr,HFETAgatePrimeNode,HFETAgateNode) + } + } + return(OK); +} + +int +HFETAunsetup(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + HFETAmodel *model; + HFETAinstance *here; + + for (model = (HFETAmodel *)inModel; model != NULL; + model = model->HFETAnextModel) + { + for (here = model->HFETAinstances; here != NULL; + here=here->HFETAnextInstance) + { + if (here->HFETAdrainPrimeNode + && here->HFETAdrainPrimeNode != here->HFETAdrainNode) + { + CKTdltNNum(ckt, here->HFETAdrainPrimeNode); + here->HFETAdrainPrimeNode = 0; + } + if (here->HFETAsourcePrimeNode + && here->HFETAsourcePrimeNode != here->HFETAsourceNode) + { + CKTdltNNum(ckt, here->HFETAsourcePrimeNode); + here->HFETAsourcePrimeNode = 0; + } + } if (here->HFETAgatePrimeNode + && here->HFETAgatePrimeNode != here->HFETAgateNode) + { + CKTdltNNum(ckt, here->HFETAgatePrimeNode); + here->HFETAgatePrimeNode = 0; + } + } + return OK; +} + diff --git a/src/spicelib/devices/hfet1/hfettemp.c b/src/spicelib/devices/hfet1/hfettemp.c new file mode 100644 index 000000000..66ec1b6cf --- /dev/null +++ b/src/spicelib/devices/hfet1/hfettemp.c @@ -0,0 +1,96 @@ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "hfetdefs.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + + +/* ARGSUSED */ +int +HFETAtemp(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + HFETAmodel *model = (HFETAmodel*)inModel; + HFETAinstance *here; + double vt; + double temp; + + /* loop through all the diode models */ + for( ; model != NULL; model = model->HFETAnextModel ) { + if(model->HFETArd != 0) { + model->HFETAdrainConduct = 1/model->HFETArd; + } else { + model->HFETAdrainConduct = 0; + } + if(model->HFETArs != 0) { + model->HFETAsourceConduct = 1/model->HFETArs; + } else { + model->HFETAsourceConduct = 0; + } + if(model->HFETArg != 0) { + model->HFETAgateConduct = 1/model->HFETArg; + } else { + model->HFETAgateConduct = 0; + } + if(model->HFETAri != 0) { + model->HFETAgi = 1/model->HFETAri; + } else { + model->HFETAgi = 0; + } + if(model->HFETArf != 0) { + model->HFETAgf = 1/model->HFETArf; + } else { + model->HFETAgf = 0; + } + model->HFETAdeltaSqr = model->HFETAdelta*model->HFETAdelta; + model->HFETAthreshold *= model->HFETAtype; + + if(!model->HFETAvt2Given) + VT2 = VTO; + if(!model->HFETAvt1Given) + IN_VT1 = VTO+CHARGE*NMAX*DI/EPSI; + + for (here = model->HFETAinstances; here != NULL ; + here=here->HFETAnextInstance) { + vt = CONSTKoverQ*TEMP; + TLAMBDA = LAMBDA + KLAMBDA*(TEMP-ckt->CKTnomTemp); + TMU = MU - KMU*(TEMP-ckt->CKTnomTemp); + TVTO = VTO - KVTO*(TEMP-ckt->CKTnomTemp); + N0 = EPSI*ETA*vt/2/CHARGE/(DI+DELTAD); + N01 = EPSI*ETA1*vt/2/CHARGE/D1; + if(model->HFETAeta2Given) + N02 = EPSI*ETA2*vt/2/CHARGE/D2; + else + N02 = 0.0; + GCHI0 = CHARGE*W*TMU/L; + CF = 0.5*EPSI*W; + IMAX = CHARGE*NMAX*VS*W; + IS1D = JS1D*W*L/2; + IS2D = JS2D*W*L/2; + IS1S = JS1S*W*L/2; + IS2S = JS2S*W*L/2; + ISO = ASTAR*W*L/2; + GGRWL = GGR*L*W/2; + temp = exp(TEMP/model->HFETAtf); + FGDS = model->HFETAfgds*temp; + DELF = model->HFETAdelf*temp; + if(model->HFETAgatemod == 0) { + if(IS1S != 0) + here->HFETAvcrit = vt*log(vt/(CONSTroot2*IS1S)); + else + here->HFETAvcrit = DBL_MAX; + } else { + if(ISO != 0.0) + here->HFETAvcrit = vt*log(vt/(CONSTroot2*ISO)); + else + here->HFETAvcrit = DBL_MAX; + } + } + } + return(OK); +} diff --git a/src/spicelib/devices/hfet1/hfettrunc.c b/src/spicelib/devices/hfet1/hfettrunc.c new file mode 100644 index 000000000..31f9c392c --- /dev/null +++ b/src/spicelib/devices/hfet1/hfettrunc.c @@ -0,0 +1,26 @@ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "hfetdefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +HFETAtrunc(inModel,ckt,timeStep) + GENmodel *inModel; + CKTcircuit *ckt; + double *timeStep; +{ + HFETAmodel *model = (HFETAmodel*)inModel; + HFETAinstance *here; + + for( ; model != NULL; model = model->HFETAnextModel) { + for(here=model->HFETAinstances;here!=NULL;here = here->HFETAnextInstance){ + CKTterr(here->HFETAqgs,ckt,timeStep); + CKTterr(here->HFETAqgd,ckt,timeStep); + } + } + return(OK); +} diff --git a/src/spicelib/devices/hfet2/Makefile.am b/src/spicelib/devices/hfet2/Makefile.am new file mode 100644 index 000000000..7ea86fa7b --- /dev/null +++ b/src/spicelib/devices/hfet2/Makefile.am @@ -0,0 +1,29 @@ +## Process this file with automake to produce Makefile.in + +pkglib_LTLIBRARIES = libhfet2.la + +libhfet2_la_SOURCES = \ + hfet2.c \ + hfet2acl.c \ + hfet2ask.c \ + hfet2defs.h \ + hfet2del.c \ + hfet2dest.c \ + hfet2ext.h \ + hfet2getic.c \ + hfet2init.c \ + hfet2init.h \ + hfet2itf.h \ + hfet2load.c \ + hfet2mask.c \ + hfet2mdel.c \ + hfet2mpar.c \ + hfet2param.c \ + hfet2setup.c \ + hfet2temp.c \ + hfet2trunc.c + + + +INCLUDES = -I$(top_srcdir)/src/include +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/hfet2/hfet2.c b/src/spicelib/devices/hfet2/hfet2.c new file mode 100644 index 000000000..fdaf30222 --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2.c @@ -0,0 +1,94 @@ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "devdefs.h" +#include "hfet2defs.h" +#include "suffix.h" + + +IFparm HFET2pTable[] = { /* parameters */ + OP("off", HFET2_OFF, IF_FLAG ,""), + IOP("l", HFET2_LENGTH, IF_REAL ,""), + IOP("w", HFET2_WIDTH, IF_REAL ,""), + IOP("icvds", HFET2_IC_VDS, IF_REAL ,""), + IOP("icvgs", HFET2_IC_VGS, IF_REAL ,""), + IOP("temp", HFET2_TEMP, IF_REAL ,""), + OP("dnode", HFET2_DRAINNODE, IF_INTEGER ,""), + OP("gnode", HFET2_GATENODE, IF_INTEGER ,""), + OP("snode", HFET2_SOURCENODE, IF_INTEGER ,""), + OP("dprimenode",HFET2_DRAINPRIMENODE, IF_INTEGER ,""), + OP("sprimenode",HFET2_SOURCEPRIMENODE,IF_INTEGER ,""), + OP("vgs", HFET2_VGS, IF_REAL ,""), + OP("vgd", HFET2_VGD, IF_REAL ,""), + OP("cg", HFET2_CG, IF_REAL ,""), + OP("cd", HFET2_CD, IF_REAL ,""), + OP("cgd", HFET2_CGD, IF_REAL ,""), + OP("gm", HFET2_GM, IF_REAL ,""), + OP("gds", HFET2_GDS, IF_REAL ,""), + OP("ggs", HFET2_GGS, IF_REAL ,""), + OP("ggd", HFET2_GGD, IF_REAL ,""), + OP("qgs", HFET2_QGS, IF_REAL ,""), + OP("cqgs", HFET2_CQGS, IF_REAL ,""), + OP("qgd", HFET2_QGD, IF_REAL ,""), + OP("cqgd", HFET2_CQGD, IF_REAL ,""), + OP("cs", HFET2_CS, IF_REAL ,""), + OP("p", HFET2_POWER, IF_REAL ,"") + +}; + +IFparm HFET2mPTable[] = { /* model parameters */ + OP( "type", HFET2_MOD_TYPE, IF_STRING,"NHFET or PHFET"), + IOP( "nhfet", HFET2_MOD_NHFET, IF_FLAG,"N type HFET model"), + IOP( "phfet", HFET2_MOD_PHFET, IF_FLAG,"P type HFET model"), + IOP( "cf", HFET2_MOD_CF, IF_REAL,""), + IOP( "d1", HFET2_MOD_D1, IF_REAL,""), + IOP( "d2", HFET2_MOD_D2, IF_REAL,""), + IOP( "del", HFET2_MOD_DEL, IF_REAL,""), + IOP( "delta", HFET2_MOD_DELTA, IF_REAL,""), + IOP( "deltad", HFET2_MOD_DELTAD, IF_REAL,"Thickness correction"), + IOP( "di", HFET2_MOD_DI, IF_REAL,"Depth of device"), + IOP( "epsi", HFET2_MOD_EPSI, IF_REAL,""), + IOP( "eta", HFET2_MOD_ETA, IF_REAL,"Subthreshold ideality factor"), + IOP( "eta1", HFET2_MOD_ETA1, IF_REAL,""), + IOP( "eta2", HFET2_MOD_ETA2, IF_REAL,""), + IOP( "gamma", HFET2_MOD_GAMMA, IF_REAL,"Knee shape parameter"), + IOP( "ggr", HFET2_MOD_GGR, IF_REAL,""), + IOP( "js", HFET2_MOD_JS, IF_REAL,""), + IOP( "klambda", HFET2_MOD_KLAMBDA, IF_REAL,""), + IOP( "kmu", HFET2_MOD_KMU, IF_REAL,""), + IOP( "knmax", HFET2_MOD_KNMAX, IF_REAL,""), + IOP( "kvto", HFET2_MOD_KVTO, IF_REAL,""), + IOP( "lambda", HFET2_MOD_LAMBDA, IF_REAL,"Output conductance parameter"), + IOP( "m", HFET2_MOD_M, IF_REAL,"Knee shape parameter"), + IOP( "mc", HFET2_MOD_MC, IF_REAL,"Knee shape parameter"), + IOP( "mu", HFET2_MOD_MU, IF_REAL,"Moblity"), + IOP( "n", HFET2_MOD_N, IF_REAL,""), + IOP( "nmax", HFET2_MOD_NMAX, IF_REAL,""), + IOP( "p", HFET2_MOD_P, IF_REAL,""), + IOP( "rd", HFET2_MOD_RD, IF_REAL,"Drain ohmic resistance"), + IOP( "rdi", HFET2_MOD_RDI, IF_REAL,"Drain ohmic resistance"), + IOP( "rs", HFET2_MOD_RS, IF_REAL,"Source ohmic resistance"), + IOP( "rsi", HFET2_MOD_RSI, IF_REAL,"Source ohmic resistance"), + IOP( "sigma0", HFET2_MOD_SIGMA0, IF_REAL,"DIBL parameter"), + IOP( "vs", HFET2_MOD_VS, IF_REAL,"Saturation velocity"), + IOP( "vsigma", HFET2_MOD_VSIGMA, IF_REAL,""), + IOP( "vsigmat", HFET2_MOD_VSIGMAT, IF_REAL,""), + IOP( "vt0", HFET2_MOD_VTO, IF_REAL,""), + IOP( "vt1", HFET2_MOD_VT1, IF_REAL,""), + IOP( "vt2", HFET2_MOD_VT2, IF_REAL,""), + IOP( "vto", HFET2_MOD_VTO, IF_REAL,"") + +}; + +char *HFET2names[] = { + "Drain", + "Gate", + "Source" +}; + +int HFET2nSize = NUMELEMS(HFET2names); +int HFET2pTSize = NUMELEMS(HFET2pTable); +int HFET2mPTSize = NUMELEMS(HFET2mPTable); +int HFET2iSize = sizeof(HFET2instance); +int HFET2mSize = sizeof(HFET2model); diff --git a/src/spicelib/devices/hfet2/hfet2acl.c b/src/spicelib/devices/hfet2/hfet2acl.c new file mode 100644 index 000000000..aedd25391 --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2acl.c @@ -0,0 +1,64 @@ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "hfet2defs.h" +#include "sperror.h" +#include "suffix.h" + + +int HFET2acLoad(inModel, ckt) +GENmodel *inModel; +CKTcircuit *ckt; +{ + + HFET2model *model = (HFET2model*)inModel; + HFET2instance *here; + double gdpr; + double gspr; + double gm; + double gds; + double ggs; + double xgs; + double ggd; + double xgd; + + for( ; model != NULL; model = model->HFET2nextModel ) + { + for( here = model->HFET2instances; here != NULL; here = here->HFET2nextInstance) + { + gdpr=model->HFET2drainConduct; + gspr=model->HFET2sourceConduct; + gm= *(ckt->CKTstate0 + here->HFET2gm) ; + gds= *(ckt->CKTstate0 + here->HFET2gds) ; + ggs= *(ckt->CKTstate0 + here->HFET2ggs) ; + xgs= *(ckt->CKTstate0 + here->HFET2qgs) * ckt->CKTomega ; + ggd= *(ckt->CKTstate0 + here->HFET2ggd) ; + xgd= *(ckt->CKTstate0 + here->HFET2qgd) * ckt->CKTomega ; + *(here->HFET2drainDrainPtr ) += gdpr; + *(here->HFET2gateGatePtr ) += ggd+ggs; + *(here->HFET2gateGatePtr +1) += xgd+xgs; + *(here->HFET2sourceSourcePtr ) += gspr; + *(here->HFET2drainPrimeDrainPrimePtr ) += gdpr+gds+ggd; + *(here->HFET2drainPrimeDrainPrimePtr +1) += xgd; + *(here->HFET2sourcePriHFET2ourcePrimePtr ) += gspr+gds+gm+ggs; + *(here->HFET2sourcePriHFET2ourcePrimePtr +1) += xgs; + *(here->HFET2drainDrainPrimePtr ) -= gdpr; + *(here->HFET2gateDrainPrimePtr ) -= ggd; + *(here->HFET2gateDrainPrimePtr +1) -= xgd; + *(here->HFET2gateSourcePrimePtr ) -= ggs; + *(here->HFET2gateSourcePrimePtr +1) -= xgs; + *(here->HFET2sourceSourcePrimePtr ) -= gspr; + *(here->HFET2drainPrimeDrainPtr ) -= gdpr; + *(here->HFET2drainPrimeGatePtr ) += (-ggd+gm); + *(here->HFET2drainPrimeGatePtr +1) -= xgd; + *(here->HFET2drainPriHFET2ourcePrimePtr ) += (-gds-gm); + *(here->HFET2sourcePrimeGatePtr ) += (-ggs-gm); + *(here->HFET2sourcePrimeGatePtr +1) -= xgs; + *(here->HFET2sourcePriHFET2ourcePtr ) -= gspr; + *(here->HFET2sourcePrimeDrainPrimePtr ) -= gds; + } + } + return(OK); + +} diff --git a/src/spicelib/devices/hfet2/hfet2ask.c b/src/spicelib/devices/hfet2/hfet2ask.c new file mode 100644 index 000000000..d40d41982 --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2ask.c @@ -0,0 +1,132 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Thomas L. Quarles +**********/ +/* +Imported into HFET2 source: Paolo Nenzi 2001 + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "devdefs.h" +#include "ifsim.h" +#include "hfet2defs.h" +#include "sperror.h" +#include "suffix.h" + + +/* ARGSUSED */ +int +HFET2ask(ckt,inst,which,value,select) + CKTcircuit *ckt; + GENinstance *inst; + int which; + IFvalue *value; + IFvalue *select; +{ + HFET2instance *here = (HFET2instance*)inst; + static char *msg = "Current and power not available in ac analysis"; + switch(which) { + case HFET2_LENGTH: + value->rValue = here->HFET2length; + return (OK); + case HFET2_WIDTH: + value->rValue = here->HFET2width; + case HFET2_IC_VDS: + value->rValue = here->HFET2icVDS; + return (OK); + case HFET2_IC_VGS: + value->rValue = here->HFET2icVGS; + return (OK); + case HFET2_OFF: + value->iValue = here->HFET2off; + return (OK); + case HFET2_DRAINNODE: + value->iValue = here->HFET2drainNode; + return (OK); + case HFET2_GATENODE: + value->iValue = here->HFET2gateNode; + return (OK); + case HFET2_SOURCENODE: + value->iValue = here->HFET2sourceNode; + return (OK); + case HFET2_DRAINPRIMENODE: + value->iValue = here->HFET2drainPrimeNode; + return (OK); + case HFET2_SOURCEPRIMENODE: + value->iValue = here->HFET2sourcePrimeNode; + return (OK); + case HFET2_TEMP: + value->rValue = here->HFET2temp; + case HFET2_VGS: + value->rValue = *(ckt->CKTstate0 + here->HFET2vgs); + return (OK); + case HFET2_VGD: + value->rValue = *(ckt->CKTstate0 + here->HFET2vgd); + return (OK); + case HFET2_CG: + value->rValue = *(ckt->CKTstate0 + here->HFET2cg); + return (OK); + case HFET2_CD: + value->rValue = *(ckt->CKTstate0 + here->HFET2cd); + return (OK); + case HFET2_CGD: + value->rValue = *(ckt->CKTstate0 + here->HFET2cgd); + return (OK); + case HFET2_GM: + value->rValue = *(ckt->CKTstate0 + here->HFET2gm); + return (OK); + case HFET2_GDS: + value->rValue = *(ckt->CKTstate0 + here->HFET2gds); + return (OK); + case HFET2_GGS: + value->rValue = *(ckt->CKTstate0 + here->HFET2ggs); + return (OK); + case HFET2_GGD: + value->rValue = *(ckt->CKTstate0 + here->HFET2ggd); + return (OK); + case HFET2_QGS: + value->rValue = *(ckt->CKTstate0 + here->HFET2qgs); + return (OK); + case HFET2_CQGS: + value->rValue = *(ckt->CKTstate0 + here->HFET2cqgs); + return (OK); + case HFET2_QGD: + value->rValue = *(ckt->CKTstate0 + here->HFET2qgd); + return (OK); + case HFET2_CQGD: + value->rValue = *(ckt->CKTstate0 + here->HFET2cqgd); + return (OK); + case HFET2_CS : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = MALLOC(strlen(msg)+1); + errRtn = "HFET2ask"; + strcpy(errMsg,msg); + return(E_ASKCURRENT); + } else { + value->rValue = -*(ckt->CKTstate0 + here->HFET2cd); + value->rValue -= *(ckt->CKTstate0 + here->HFET2cg); + } + return(OK); + case HFET2_POWER : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = MALLOC(strlen(msg)+1); + errRtn = "HFET2ask"; + strcpy(errMsg,msg); + return(E_ASKPOWER); + } else { + value->rValue = *(ckt->CKTstate0 + here->HFET2cd) * + *(ckt->CKTrhsOld + here->HFET2drainNode); + value->rValue += *(ckt->CKTstate0 + here->HFET2cg) * + *(ckt->CKTrhsOld + here->HFET2gateNode); + value->rValue -= (*(ckt->CKTstate0+here->HFET2cd) + + *(ckt->CKTstate0 + here->HFET2cg)) * + *(ckt->CKTrhsOld + here->HFET2sourceNode); + } + return(OK); + default: + return (E_BADPARM); + } + /* NOTREACHED */ +} diff --git a/src/spicelib/devices/hfet2/hfet2defs.h b/src/spicelib/devices/hfet2/hfet2defs.h new file mode 100644 index 000000000..842bf1362 --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2defs.h @@ -0,0 +1,318 @@ + +#ifndef HFET2 +#define HFET2 + +#include "ifsim.h" +#include "cktdefs.h" +#include "gendefs.h" +#include "complex.h" +#include "noisedef.h" + + +typedef struct sHFET2instance { + struct sHFET2model *HFET2modPtr; + struct sHFET2instance *HFET2nextInstance; + IFuid HFET2name; + int HFET2owner; /* number of owner process */ + int HFET2state; /* index into state table for this device */ + + int HFET2drainNode; + int HFET2gateNode; + int HFET2sourceNode; + int HFET2drainPrimeNode; + int HFET2sourcePrimeNode; + double HFET2length; + double HFET2width; + double HFET2temp; + double HFET2tLambda; + double HFET2tMu; + double HFET2tNmax; + double HFET2tVto; + double HFET2icVDS; + double HFET2icVGS; + double *HFET2drainDrainPrimePtr; + double *HFET2gateDrainPrimePtr; + double *HFET2gateSourcePrimePtr; + double *HFET2sourceSourcePrimePtr; + double *HFET2drainPrimeDrainPtr; + double *HFET2drainPrimeGatePtr; + double *HFET2drainPriHFET2ourcePrimePtr; + double *HFET2sourcePrimeGatePtr; + double *HFET2sourcePriHFET2ourcePtr; + double *HFET2sourcePrimeDrainPrimePtr; + double *HFET2drainDrainPtr; + double *HFET2gateGatePtr; + double *HFET2sourceSourcePtr; + double *HFET2drainPrimeDrainPrimePtr; + double *HFET2sourcePriHFET2ourcePrimePtr; + + +#define HFET2vgs HFET2state +#define HFET2vgd HFET2state+1 +#define HFET2cg HFET2state+2 +#define HFET2cd HFET2state+3 +#define HFET2cgd HFET2state+4 +#define HFET2gm HFET2state+5 +#define HFET2gds HFET2state+6 +#define HFET2ggs HFET2state+7 +#define HFET2ggd HFET2state+8 +#define HFET2qgs HFET2state+9 +#define HFET2cqgs HFET2state+10 +#define HFET2qgd HFET2state+11 +#define HFET2cqgd HFET2state+12 + + int HFET2mode; + int HFET2off; + + unsigned HFET2icVDSGiven : 1; + unsigned HFET2icVGSGiven : 1; + unsigned HFET2lengthGiven : 1; + unsigned HFET2widthGiven : 1; + unsigned HFET2tempGiven : 1; + + double HFET2n0; + double HFET2n01; + double HFET2n02; + double HFET2gchi0; + double HFET2imax; + double HFET2vcrit; + double HFET2ggrlw; + double HFET2jslw; + +} HFET2instance ; + + + +typedef struct sHFET2model { + int HFET2modType; + struct sHFET2model *HFET2nextModel; + HFET2instance * HFET2instances; + IFuid HFET2modName; + int HFET2type; + + double HFET2cf; + double HFET2d1; + double HFET2d2; + double HFET2del; + double HFET2delta; + double HFET2deltad; + double HFET2di; + double HFET2epsi; + double HFET2eta; + double HFET2eta1; + double HFET2eta2; + double HFET2gamma; + double HFET2ggr; + double HFET2js; + double HFET2klambda; + double HFET2kmu; + double HFET2knmax; + double HFET2kvto; + double HFET2lambda; + double HFET2m; + double HFET2mc; + double HFET2mu; + double HFET2n; + double HFET2nmax; + double HFET2p; + double HFET2rd; + double HFET2rdi; + double HFET2rs; + double HFET2rsi; + double HFET2sigma0; + double HFET2vs; + double HFET2vsigma; + double HFET2vsigmat; + double HFET2vt1; + double HFET2vt2; + double HFET2vto; + + double HFET2drainConduct; + double HFET2sourceConduct; + double HFET2deltaSqr; + + unsigned HFET2cfGiven : 1; + unsigned HFET2d1Given : 1; + unsigned HFET2d2Given : 1; + unsigned HFET2delGiven : 1; + unsigned HFET2deltaGiven : 1; + unsigned HFET2deltadGiven : 1; + unsigned HFET2diGiven : 1; + unsigned HFET2epsiGiven : 1; + unsigned HFET2etaGiven : 1; + unsigned HFET2eta1Given : 1; + unsigned HFET2eta2Given : 1; + unsigned HFET2gammaGiven : 1; + unsigned HFET2ggrGiven : 1; + unsigned HFET2jsGiven : 1; + unsigned HFET2klambdaGiven : 1; + unsigned HFET2kmuGiven : 1; + unsigned HFET2knmaxGiven : 1; + unsigned HFET2kvtoGiven : 1; + unsigned HFET2lambdaGiven : 1; + unsigned HFET2mGiven : 1; + unsigned HFET2mcGiven : 1; + unsigned HFET2muGiven : 1; + unsigned HFET2nGiven : 1; + unsigned HFET2nmaxGiven : 1; + unsigned HFET2pGiven : 1; + unsigned HFET2rdGiven : 1; + unsigned HFET2rdiGiven : 1; + unsigned HFET2rsGiven : 1; + unsigned HFET2rsiGiven : 1; + unsigned HFET2sigma0Given : 1; + unsigned HFET2vsGiven : 1; + unsigned HFET2vsigmaGiven : 1; + unsigned HFET2vsigmatGiven : 1; + unsigned HFET2vt1Given : 1; + unsigned HFET2vt2Given : 1; + unsigned HFET2vtoGiven : 1; + +} HFET2model; + + +#ifndef NHFET +#define NHFET 1 +#define PHFET -1 +#endif /*NMF*/ + +/* device parameters */ +#define HFET2_LENGTH 1 +#define HFET2_WIDTH 2 +#define HFET2_IC_VDS 3 +#define HFET2_IC_VGS 4 +#define HFET2_IC 5 +#define HFET2_OFF 6 +#define HFET2_CS 7 +#define HFET2_POWER 8 +#define HFET2_TEMP 9 + +/* model parameters */ +#define HFET2_MOD_NHFET 101 +#define HFET2_MOD_PHFET 102 +#define HFET2_MOD_CF 103 +#define HFET2_MOD_D1 104 +#define HFET2_MOD_D2 105 +#define HFET2_MOD_DEL 106 +#define HFET2_MOD_DELTA 107 +#define HFET2_MOD_DELTAD 108 +#define HFET2_MOD_DI 109 +#define HFET2_MOD_EPSI 110 +#define HFET2_MOD_ETA 111 +#define HFET2_MOD_ETA1 112 +#define HFET2_MOD_ETA2 113 +#define HFET2_MOD_GAMMA 114 +#define HFET2_MOD_GGR 115 +#define HFET2_MOD_JS 116 +#define HFET2_MOD_KLAMBDA 117 +#define HFET2_MOD_KMU 118 +#define HFET2_MOD_KNMAX 119 +#define HFET2_MOD_KVTO 120 +#define HFET2_MOD_LAMBDA 121 +#define HFET2_MOD_M 122 +#define HFET2_MOD_MC 123 +#define HFET2_MOD_MU 124 +#define HFET2_MOD_N 125 +#define HFET2_MOD_NMAX 126 +#define HFET2_MOD_P 127 +#define HFET2_MOD_RD 128 +#define HFET2_MOD_RDI 129 +#define HFET2_MOD_RS 130 +#define HFET2_MOD_RSI 131 +#define HFET2_MOD_SIGMA0 132 +#define HFET2_MOD_VS 133 +#define HFET2_MOD_VSIGMA 134 +#define HFET2_MOD_VSIGMAT 135 +#define HFET2_MOD_VT1 136 +#define HFET2_MOD_VT2 137 +#define HFET2_MOD_VTO 138 +#define HFET2_MOD_TYPE 139 + +/* device questions */ + +#define HFET2_DRAINNODE 201 +#define HFET2_GATENODE 202 +#define HFET2_SOURCENODE 203 +#define HFET2_DRAINPRIMENODE 204 +#define HFET2_SOURCEPRIMENODE 205 + +#define HFET2_VGS 206 +#define HFET2_VGD 207 +#define HFET2_CG 208 +#define HFET2_CD 209 +#define HFET2_CGD 210 +#define HFET2_GM 211 +#define HFET2_GDS 212 +#define HFET2_GGS 213 +#define HFET2_GGD 214 +#define HFET2_QGS 215 +#define HFET2_CQGS 216 +#define HFET2_QGD 217 +#define HFET2_CQGD 218 + +/* model questions */ + +#define HFET2_MOD_DRAINCONDUCT 301 +#define HFET2_MOD_SOURCECONDUCT 302 +#define HFET2_MOD_DEPLETIONCAP 303 +#define HFET2_MOD_VCRIT 304 + +#define CF (model->HFET2cf) +#define D1 (model->HFET2d1) +#define D2 (model->HFET2d2) +#define DEL (model->HFET2del) +#define DELTA (model->HFET2delta) +#define DELTAD (model->HFET2deltad) +#define DI (model->HFET2di) +#define EPSI (model->HFET2epsi) +#define ETA (model->HFET2eta) +#define ETA1 (model->HFET2eta1) +#define ETA2 (model->HFET2eta2) +#define GAMMA (model->HFET2gamma) +#define GGR (model->HFET2ggr) +#define JS (model->HFET2js) +#define KLAMBDA (model->HFET2klambda) +#define KMU (model->HFET2kmu) +#define KNMAX (model->HFET2knmax) +#define KVTO (model->HFET2kvto) +#define LAMBDA (model->HFET2lambda) +#define M (model->HFET2m) +#define MC (model->HFET2mc) +#define MU (model->HFET2mu) +#define N (model->HFET2n) +#define NMAX (model->HFET2nmax) +#define PP (model->HFET2p) +#define RD (model->HFET2rd) +#define RDI (model->HFET2rdi) +#define RS (model->HFET2rs) +#define RSI (model->HFET2rsi) +#define SIGMA0 (model->HFET2sigma0) +#define TYPE (model->HFET2type) +#define VS (model->HFET2vs) +#define VSIGMA (model->HFET2vsigma) +#define VSIGMAT (model->HFET2vsigmat) +#define HFET2_VT1 (model->HFET2vt1) /* Fix a redefinition in include files */ +#define VT2 (model->HFET2vt2) +#define VTO (model->HFET2vto) + +#define DELTA2 (model->HFET2deltaSqr) + +#define GCHI0 (here->HFET2gchi0) +#define GGRLW (here->HFET2ggrlw) +#define JSLW (here->HFET2jslw) +#define IMAX (here->HFET2imax) +#define L (here->HFET2length) +#define N0 (here->HFET2n0) +#define N01 (here->HFET2n01) +#define N02 (here->HFET2n02) +#define TEMP (here->HFET2temp) +#define TLAMBDA (here->HFET2tLambda) +#define TMU (here->HFET2tMu) +#define TNMAX (here->HFET2tNmax) +#define TVTO (here->HFET2tVto) +#define VCRIT (here->HFET2vcrit) +#define W (here->HFET2width) + +#include "hfet2ext.h" + +#endif /*HFET2*/ diff --git a/src/spicelib/devices/hfet2/hfet2del.c b/src/spicelib/devices/hfet2/hfet2del.c new file mode 100644 index 000000000..0eac5dabf --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2del.c @@ -0,0 +1,39 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 S. Hwang +**********/ +/* +Imported into hfet2 model: Paolo Nenzi 2001 +*/ + +#include "ngspice.h" +#include +#include "hfet2defs.h" +#include "sperror.h" +#include "suffix.h" + + +int +HFET2delete(inModel,name,inst) + GENmodel *inModel; + IFuid name; + GENinstance **inst; +{ + HFET2model *model = (HFET2model*)inModel; + HFET2instance **fast = (HFET2instance**)inst; + HFET2instance **prev = NULL; + HFET2instance *here; + + for( ; model ; model = model->HFET2nextModel) { + prev = &(model->HFET2instances); + for(here = *prev; here ; here = *prev) { + if(here->HFET2name == name || (fast && here==*fast) ) { + *prev= here->HFET2nextInstance; + FREE(here); + return(OK); + } + prev = &(here->HFET2nextInstance); + } + } + return(E_NODEV); +} diff --git a/src/spicelib/devices/hfet2/hfet2dest.c b/src/spicelib/devices/hfet2/hfet2dest.c new file mode 100644 index 000000000..1af55e904 --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2dest.c @@ -0,0 +1,32 @@ + +#include "ngspice.h" +#include +#include "hfet2defs.h" +#include "suffix.h" + + +void HFET2destroy(inModel) +GENmodel **inModel; +{ + + HFET2model **model = (HFET2model**)inModel; + HFET2instance *here; + HFET2instance *prev = NULL; + HFET2model *mod = *model; + HFET2model *oldmod = NULL; + + for( ; mod ; mod = mod->HFET2nextModel) { + if(oldmod) FREE(oldmod); + oldmod = mod; + prev = (HFET2instance *)NULL; + for(here = mod->HFET2instances ; here ; here = here->HFET2nextInstance) { + if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + } + if(oldmod) FREE(oldmod); + *model = NULL; + return; + +} diff --git a/src/spicelib/devices/hfet2/hfet2ext.h b/src/spicelib/devices/hfet2/hfet2ext.h new file mode 100644 index 000000000..9604af910 --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2ext.h @@ -0,0 +1,38 @@ +/********** +Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. +Author: Trond Ytterdal +**********/ + +#ifdef __STDC__ +extern int HFET2acLoad(GENmodel*,CKTcircuit*); +extern int HFET2ask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); +extern int HFET2delete(GENmodel*,IFuid,GENinstance**); +extern void HFET2destroy(GENmodel**); +extern int HFET2getic(GENmodel*,CKTcircuit*); +extern int HFET2load(GENmodel*,CKTcircuit*); +extern int HFET2mAsk(CKTcircuit*,GENmodel*,int,IFvalue*); +extern int HFET2mDelete(GENmodel**,IFuid,GENmodel*); +extern int HFET2mParam(int,IFvalue*,GENmodel*); +extern int HFET2param(int,IFvalue*,GENinstance*,IFvalue*); +extern int HFET2setup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); +extern int HFET2temp(GENmodel*,CKTcircuit*); +extern int HFET2trunc(GENmodel*,CKTcircuit*,double*); +extern int HFET2unsetup( GENmodel*,CKTcircuit*); + +#else /* stdc */ +extern int HFET2acLoad(); +extern int HFET2ask(); +extern int HFET2delete(); +extern void HFET2destroy(); +extern int HFET2getic(); +extern int HFET2load(); +extern int HFETAmAsk(); +extern int HFETAmDelete(); +extern int HFET2mParam(); +extern int HFET2param(); +extern int HFET2setup(); +extern int HFET2temp(); +extern int HFET2trunc(); +extern int HFET2unsetup(); +#endif + diff --git a/src/spicelib/devices/hfet2/hfet2getic.c b/src/spicelib/devices/hfet2/hfet2getic.c new file mode 100644 index 000000000..e3e0ab7b8 --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2getic.c @@ -0,0 +1,32 @@ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "hfet2defs.h" +#include "sperror.h" +#include "suffix.h" + + +int HFET2getic(inModel, ckt) +GENmodel *inModel; +CKTcircuit *ckt; +{ + + HFET2model *model = (HFET2model*)inModel; + HFET2instance *here; + + for( ; model ; model = model->HFET2nextModel) { + for(here = model->HFET2instances; here ; here = here->HFET2nextInstance) { + if(!here->HFET2icVDSGiven) { + here->HFET2icVDS = *(ckt->CKTrhs + here->HFET2drainNode) - + *(ckt->CKTrhs + here->HFET2sourceNode); + } + if(!here->HFET2icVGSGiven) { + here->HFET2icVGS = *(ckt->CKTrhs + here->HFET2gateNode) - + *(ckt->CKTrhs + here->HFET2sourceNode); + } + } + } + return(OK); + +} diff --git a/src/spicelib/devices/hfet2/hfet2init.c b/src/spicelib/devices/hfet2/hfet2init.c new file mode 100644 index 000000000..55bfb6dd9 --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2init.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "hfet2itf.h" +#include "hfet2ext.h" +#include "hfet2init.h" + + +SPICEdev HFET2info = { + { + "HFET2", + "HFET2 Model", + + &HFET2nSize, + &HFET2nSize, + HFET2names, + + &HFET2pTSize, + HFET2pTable, + + &HFET2mPTSize, + HFET2mPTable, + DEV_DEFAULT + }, + + DEVparam : HFET2param, + DEVmodParam : HFET2mParam, + DEVload : HFET2load, + DEVsetup : HFET2setup, + DEVunsetup : HFET2unsetup, + DEVpzSetup : HFET2setup, + DEVtemperature: HFET2temp, + DEVtrunc : HFET2trunc, + DEVfindBranch : NULL, + DEVacLoad : HFET2acLoad, + DEVaccept : NULL, + DEVdestroy : HFET2destroy, + DEVmodDelete : HFET2mDelete, + DEVdelete : HFET2delete, + DEVsetic : HFET2getic, + DEVask : HFET2ask, + DEVmodAsk : HFET2mAsk, + DEVpzLoad : NULL, + DEVconvTest : NULL, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, + DEVnoise : NULL, + + DEVinstSize : &HFET2iSize, + DEVmodSize : &HFET2mSize + +}; + + +SPICEdev * +get_hfet2_info(void) +{ + return &HFET2info; +} diff --git a/src/spicelib/devices/hfet2/hfet2init.h b/src/spicelib/devices/hfet2/hfet2init.h new file mode 100644 index 000000000..30ec34c6c --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2init.h @@ -0,0 +1,13 @@ +#ifndef _HFET2INIT_H +#define _HFET2INIT_H + +extern IFparm HFET2pTable[ ]; +extern IFparm HFET2mPTable[ ]; +extern char *HFET2names[ ]; +extern int HFET2pTSize; +extern int HFET2mPTSize; +extern int HFET2nSize; +extern int HFET2iSize; +extern int HFET2mSize; + +#endif diff --git a/src/spicelib/devices/hfet2/hfet2itf.h b/src/spicelib/devices/hfet2/hfet2itf.h new file mode 100644 index 000000000..ef62a26b6 --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2itf.h @@ -0,0 +1,7 @@ +#ifndef DEV_HFET2 +#define DEV_HFET2 + +SPICEdev *get_hfet2_info(void); + +#endif + diff --git a/src/spicelib/devices/hfet2/hfet2load.c b/src/spicelib/devices/hfet2/hfet2load.c new file mode 100644 index 000000000..609cc2973 --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2load.c @@ -0,0 +1,456 @@ + +#include "ngspice.h" +#include +#include "devdefs.h" +#include "cktdefs.h" +#include "hfet2defs.h" +#include "const.h" +#include "trandefs.h" +#include "sperror.h" +#include "suffix.h" + +void Pause(void); + +static void hfeta2(HFET2model *model, HFET2instance *here, CKTcircuit *ckt, + double vgs, double vds, double *cdrain, double *gm, + double *gds, double *capgs, double *capgd); + + +int HFET2load(inModel, ckt) +GENmodel *inModel; +register CKTcircuit *ckt; +{ + + register HFET2model *model = (HFET2model*)inModel; + register HFET2instance *here; + double capgd; + double capgs; + double cd; + double cdhat; + double cdrain; + double cdreq; + double ceq; + double ceqgd; + double ceqgs; + double cg; + double cgd; + double cghat; + double delvds; + double delvgd; + double delvgs; + double gdpr; + double gds; + double geq; + double ggd; + double ggs; + double gm; + double gspr; + double vcrit; + double vds; + double vgd; + double vgd1; + double vgs; + double vgs1; + double vt; + double vto; + double xfact; + int icheck; + int ichk1; + int error; + int inverse; + + for( ; model != NULL; model = model->HFET2nextModel ) { + for(here = model->HFET2instances; here != NULL; here=here->HFET2nextInstance) { + gdpr = model->HFET2drainConduct; + gspr = model->HFET2sourceConduct; + vcrit = VCRIT; + vto = TVTO; + vt = CONSTKoverQ*TEMP; + icheck = 1; + if( ckt->CKTmode & MODEINITSMSIG) { + vgs = *(ckt->CKTstate0 + here->HFET2vgs); + vgd = *(ckt->CKTstate0 + here->HFET2vgd); + } else if(ckt->CKTmode & MODEINITTRAN) { + vgs = *(ckt->CKTstate1 + here->HFET2vgs); + vgd = *(ckt->CKTstate1 + here->HFET2vgd); + } else if((ckt->CKTmode & MODEINITJCT) && (ckt->CKTmode & MODETRANOP) && + (ckt->CKTmode & MODEUIC) ) { + vds = model->HFET2type*here->HFET2icVDS; + vgs = model->HFET2type*here->HFET2icVGS; + vgd = vgs-vds; + } else if ( (ckt->CKTmode & MODEINITJCT) && (here->HFET2off == 0) ) { + vgs = -1; + vgd = -1; + } else if((ckt->CKTmode & MODEINITJCT) || + ((ckt->CKTmode & MODEINITFIX) && (here->HFET2off))) { + vgs = 0; + vgd = 0; + } else { +#ifndef PREDICTOR + if(ckt->CKTmode & MODEINITPRED) { + xfact = ckt->CKTdelta/ckt->CKTdeltaOld[2]; + *(ckt->CKTstate0 + here->HFET2vgs) = + *(ckt->CKTstate1 + here->HFET2vgs); + vgs = (1+xfact) * *(ckt->CKTstate1 + here->HFET2vgs) - + xfact * *(ckt->CKTstate2 + here->HFET2vgs); + *(ckt->CKTstate0 + here->HFET2vgd) = + *(ckt->CKTstate1 + here->HFET2vgd); + vgd = (1+xfact)* *(ckt->CKTstate1 + here->HFET2vgd) - + xfact * *(ckt->CKTstate2 + here->HFET2vgd); + *(ckt->CKTstate0 + here->HFET2cg) = + *(ckt->CKTstate1 + here->HFET2cg); + *(ckt->CKTstate0 + here->HFET2cd) = + *(ckt->CKTstate1 + here->HFET2cd); + *(ckt->CKTstate0 + here->HFET2cgd) = + *(ckt->CKTstate1 + here->HFET2cgd); + *(ckt->CKTstate0 + here->HFET2gm) = + *(ckt->CKTstate1 + here->HFET2gm); + *(ckt->CKTstate0 + here->HFET2gds) = + *(ckt->CKTstate1 + here->HFET2gds); + *(ckt->CKTstate0 + here->HFET2ggs) = + *(ckt->CKTstate1 + here->HFET2ggs); + *(ckt->CKTstate0 + here->HFET2ggd) = + *(ckt->CKTstate1 + here->HFET2ggd); + } else { +#endif /* PREDICTOR */ + vgs = model->HFET2type* + (*(ckt->CKTrhsOld+ here->HFET2gateNode)- *(ckt->CKTrhsOld+ + here->HFET2sourcePrimeNode)); + vgd = model->HFET2type* + (*(ckt->CKTrhsOld+here->HFET2gateNode)- *(ckt->CKTrhsOld+ + here->HFET2drainPrimeNode)); +#ifndef PREDICTOR + } +#endif /* PREDICTOR */ + delvgs=vgs - *(ckt->CKTstate0 + here->HFET2vgs); + delvgd=vgd - *(ckt->CKTstate0 + here->HFET2vgd); + delvds=delvgs - delvgd; + cghat= *(ckt->CKTstate0 + here->HFET2cg) + + *(ckt->CKTstate0 + here->HFET2ggd)*delvgd + + *(ckt->CKTstate0 + here->HFET2ggs)*delvgs; + cdhat= *(ckt->CKTstate0 + here->HFET2cd) + + *(ckt->CKTstate0 + here->HFET2gm)*delvgs + + *(ckt->CKTstate0 + here->HFET2gds)*delvds - + *(ckt->CKTstate0 + here->HFET2ggd)*delvgd; + + // bypass if solution has not changed + + if((ckt->CKTbypass) && + (!(ckt->CKTmode & MODEINITPRED)) && + (fabs(delvgs) < ckt->CKTreltol*MAX(fabs(vgs), + fabs(*(ckt->CKTstate0 + here->HFET2vgs)))+ + ckt->CKTvoltTol) ) + if ( (fabs(delvgd) < ckt->CKTreltol*MAX(fabs(vgd), + fabs(*(ckt->CKTstate0 + here->HFET2vgd)))+ + ckt->CKTvoltTol)) + if ( (fabs(cghat-*(ckt->CKTstate0 + here->HFET2cg)) + < ckt->CKTreltol*MAX(fabs(cghat), + fabs(*(ckt->CKTstate0 + here->HFET2cg)))+ + ckt->CKTabstol) ) if ( /* hack - expression too big */ + (fabs(cdhat-*(ckt->CKTstate0 + here->HFET2cd)) + < ckt->CKTreltol*MAX(fabs(cdhat), + fabs(*(ckt->CKTstate0 + here->HFET2cd)))+ + ckt->CKTabstol) ) { + + /* we can do a bypass */ + vgs= *(ckt->CKTstate0 + here->HFET2vgs); + vgd= *(ckt->CKTstate0 + here->HFET2vgd); + vds= vgs-vgd; + cg= *(ckt->CKTstate0 + here->HFET2cg); + cd= *(ckt->CKTstate0 + here->HFET2cd); + cgd= *(ckt->CKTstate0 + here->HFET2cgd); + gm= *(ckt->CKTstate0 + here->HFET2gm); + gds= *(ckt->CKTstate0 + here->HFET2gds); + ggs= *(ckt->CKTstate0 + here->HFET2ggs); + ggd= *(ckt->CKTstate0 + here->HFET2ggd); + goto load; + } + + // limit nonlinear branch voltages + + ichk1=1; + vgs = DEVpnjlim(vgs,*(ckt->CKTstate0 + here->HFET2vgs),CONSTvt0,vcrit, &icheck); + vgd = DEVpnjlim(vgd,*(ckt->CKTstate0 + here->HFET2vgd),CONSTvt0,vcrit,&ichk1); + if(ichk1 == 1) { + icheck=1; + } + vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->HFET2vgs),TVTO); + vgd = DEVfetlim(vgd,*(ckt->CKTstate0 + here->HFET2vgd),TVTO); + } + cg = 0; + cgd = 0; + ggd = 0; + ggs = 0; + vds = vgs-vgd; + { + double arg = -vgs*DEL/vt; + double earg = exp(arg); + double vtn = N*vt; + double expe = exp(vgs/vtn); + ggs = JSLW*expe/vtn+GGRLW*earg*(1-arg); + cg = JSLW*(expe-1)+GGRLW*vgs*earg; + arg = -vgd*DEL/vt; + earg = exp(arg); + expe = exp(vgd/vtn); + ggd = JSLW*expe/vtn+GGRLW*earg*(1-arg); + cgd = JSLW*(expe-1)+GGRLW*vgd*earg; + cg += cgd; + } + if(vds < 0) { + vds = -vds; + inverse = 1; + } else + inverse = 0; + hfeta2(model,here,ckt,vds>0?vgs:vgd,vds,&cdrain,&gm,&gds,&capgs,&capgd); + if(inverse) { + double temp; + cdrain = -cdrain; + vds = -vds; + temp = capgs; + capgs = capgd; + capgd = temp; + } + cd = cdrain - cgd; + if((ckt->CKTmode & (MODETRAN|MODEINITSMSIG)) || ((ckt->CKTmode & MODETRANOP) && + (ckt->CKTmode & MODEUIC)) ){ + // charge storage elements + vgs1 = *(ckt->CKTstate1 + here->HFET2vgs); + vgd1 = *(ckt->CKTstate1 + here->HFET2vgd); + + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->HFET2qgs) = capgs*vgs; + *(ckt->CKTstate1 + here->HFET2qgd) = capgd*vgd; + } + *(ckt->CKTstate0+here->HFET2qgs) = *(ckt->CKTstate1+here->HFET2qgs) + + capgs*(vgs-vgs1); + *(ckt->CKTstate0+here->HFET2qgd) = *(ckt->CKTstate1+here->HFET2qgd) + + capgd*(vgd-vgd1); + + // store small-signal parameters + + if( (!(ckt->CKTmode & MODETRANOP)) || (!(ckt->CKTmode & MODEUIC)) ) { + if(ckt->CKTmode & MODEINITSMSIG) { + *(ckt->CKTstate0 + here->HFET2qgs) = capgs; + *(ckt->CKTstate0 + here->HFET2qgd) = capgd; + continue; /*go to 1000*/ + } + + // transient analysis + + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->HFET2qgs) = *(ckt->CKTstate0 + here->HFET2qgs); + *(ckt->CKTstate1 + here->HFET2qgd) = *(ckt->CKTstate0 + here->HFET2qgd); + } + error = NIintegrate(ckt,&geq,&ceq,capgs,here->HFET2qgs); + if(error) return(error); + ggs = ggs + geq; + cg = cg + *(ckt->CKTstate0 + here->HFET2cqgs); + error = NIintegrate(ckt,&geq,&ceq,capgd,here->HFET2qgd); + if(error) return(error); + ggd = ggd + geq; + cg = cg + *(ckt->CKTstate0 + here->HFET2cqgd); + cd = cd - *(ckt->CKTstate0 + here->HFET2cqgd); + cgd = cgd + *(ckt->CKTstate0 + here->HFET2cqgd); + if (ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->HFET2cqgs) = *(ckt->CKTstate0 + here->HFET2cqgs); + *(ckt->CKTstate1 + here->HFET2cqgd) = *(ckt->CKTstate0 + here->HFET2cqgd); + } + } + } + + // check convergence + + 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->CKTstate0 + here->HFET2vgs) = vgs; + *(ckt->CKTstate0 + here->HFET2vgd) = vgd; + *(ckt->CKTstate0 + here->HFET2cg) = cg; + *(ckt->CKTstate0 + here->HFET2cd) = cd; + *(ckt->CKTstate0 + here->HFET2cgd) = cgd; + *(ckt->CKTstate0 + here->HFET2gm) = gm; + *(ckt->CKTstate0 + here->HFET2gds) = gds; + *(ckt->CKTstate0 + here->HFET2ggs) = ggs; + *(ckt->CKTstate0 + here->HFET2ggd) = ggd; + + // load current vector + +load: + ceqgd=model->HFET2type*(cgd-ggd*vgd); + ceqgs=model->HFET2type*((cg-cgd)-ggs*vgs); + cdreq=model->HFET2type*((cd+cgd)-gds*vds-gm*vgs); + *(ckt->CKTrhs + here->HFET2gateNode) += (-ceqgs-ceqgd); + *(ckt->CKTrhs + here->HFET2drainPrimeNode) += (-cdreq+ceqgd); + *(ckt->CKTrhs + here->HFET2sourcePrimeNode) += (cdreq+ceqgs); + + // load y matrix + + *(here->HFET2drainDrainPrimePtr) += (-gdpr); + *(here->HFET2gateDrainPrimePtr) += (-ggd); + *(here->HFET2gateSourcePrimePtr) += (-ggs); + *(here->HFET2sourceSourcePrimePtr) += (-gspr); + *(here->HFET2drainPrimeDrainPtr) += (-gdpr); + *(here->HFET2drainPrimeGatePtr) += (gm-ggd); + *(here->HFET2drainPriHFET2ourcePrimePtr) += (-gds-gm); + *(here->HFET2sourcePrimeGatePtr) += (-ggs-gm); + *(here->HFET2sourcePriHFET2ourcePtr) += (-gspr); + *(here->HFET2sourcePrimeDrainPrimePtr) += (-gds); + *(here->HFET2drainDrainPtr) += (gdpr); + *(here->HFET2gateGatePtr) += (ggd+ggs); + *(here->HFET2sourceSourcePtr) += (gspr); + *(here->HFET2drainPrimeDrainPrimePtr) += (gdpr+gds+ggd); + *(here->HFET2sourcePriHFET2ourcePrimePtr) += (gspr+gds+gm+ggs); + } + } + return(OK); + +} + + + + +static void hfeta2(HFET2model *model, HFET2instance *here, CKTcircuit *ckt, + double vgs, double vds, double *cdrain, double *gm, + double *gds, double *capgs, double *capgd) + +{ + + double vt; + double vgt; + double vgt0; + double sigma; + double vgte; + double isat; + double isatm; + double ns; + double nsm; + double a; + double b; + double c; + double d; + double e; + double g; + double h; + double p; + double q; + double s; + double t; + double u; + double nsc; + double nsn; + double temp; + double etavth; + double gch; + double gchi; + double gchim; + double vsate; + double vdse; + double cg1; + double cgc; + double rt; + double vl; + double delidgch; + double delgchgchi; + double delgchins; + double delnsnsm; + double delnsmvgt; + double delvgtevgt; + double delidvsate; + double delvsateisat; + double delisatisatm; + double delisatmvgte; + double delisatmgchim; + double delvsategch; + double delidvds; + double delvgtvgs; + double delvsatevgt; + + vt = CONSTKoverQ*TEMP; + etavth = ETA*vt; + vl = VS/TMU*L; + rt = RSI+RDI; + vgt0 = vgs - TVTO; + s = exp((vgt0-VSIGMAT)/VSIGMA); + sigma = SIGMA0/(1+s); + vgt = vgt0+sigma*vds; + u = 0.5*vgt/vt-1; + t = sqrt(DELTA2+u*u); + vgte = vt*(2+u+t); + b = exp(vgt/etavth); + if(model->HFET2eta2Given && model->HFET2d2Given) { + nsc = N02*exp((vgt+TVTO-VT2)/(ETA2*vt)); + nsn = 2*N0*log(1+0.5*b); + nsm = nsn*nsc/(nsn+nsc); + } else { + nsm = 2*N0*log(1+0.5*b); + } + if(nsm < 1.0e-38) { + *cdrain = 0; + *gm = 0.0; + *gds = 0.0; + *capgs = CF; + *capgd = CF; + return; + } + c = pow(nsm/TNMAX,GAMMA); + q = pow(1+c,1.0/GAMMA); + ns = nsm/q; + gchi = GCHI0*ns; + gch = gchi/(1+gchi*rt); + gchim = GCHI0*nsm; + h = sqrt(1+2*gchim*RSI + vgte*vgte/(vl*vl)); + p = 1+gchim*RSI+h; + isatm = gchim*vgte/p; + g = pow(isatm/IMAX,GAMMA); + isat = isatm/pow(1+g,1/GAMMA); + vsate = isat/gch; + d = pow(vds/vsate,M); + e = pow(1+d,1.0/M); + delidgch = vds*(1+TLAMBDA*vds)/e; + *cdrain = gch*delidgch; + delidvsate = (*cdrain)*d/vsate/(1+d); + delidvds = gch*(1+2*TLAMBDA*vds)/e-(*cdrain)* + pow(vds/vsate,M-1)/(vsate*(1+d)); + a = 1+gchi*rt; + delgchgchi = 1.0/(a*a); + delgchins = GCHI0; + delnsnsm = ns/nsm*(1-c/(1+c)); + delvgtevgt = 0.5*(1+u/t); + delnsmvgt = N0/etavth/(1.0/b + 0.5); + if(model->HFET2eta2Given && model->HFET2d2Given) + delnsmvgt = nsc*(nsc*delnsmvgt+nsn*nsn/(ETA2*vt))/((nsc+nsn)*(nsc+nsn)); + delvsateisat = 1.0/gch; + delisatisatm = isat/isatm*(1-g/(1+g)); + delisatmvgte = gchim*(p - vgte*vgte/(vl*vl*h))/(p*p); + delvsategch = -vsate/gch; + delisatmgchim = vgte*(p - gchim*RSI*(1+1.0/h))/(p*p); + delvgtvgs = 1-vds*SIGMA0/VSIGMA*s/((1+s)*(1+s)); + p = delgchgchi*delgchins*delnsnsm*delnsmvgt; + delvsatevgt = (delvsateisat*delisatisatm*(delisatmvgte*delvgtevgt + + delisatmgchim*GCHI0*delnsmvgt)+delvsategch*p); + g = delidgch*p + delidvsate*delvsatevgt; + *gm = g*delvgtvgs; + *gds = delidvds + g*sigma; + + // Capacitance calculations + temp = ETA1*vt; + cg1 = 1/(D1/EPSI+temp*exp(-(vgs-HFET2_VT1)/temp)); + cgc = W*L*(CHARGE*delnsnsm*delnsmvgt*delvgtvgs+cg1); + vdse = vds*pow(1+pow(vds/vsate,MC),-1.0/MC); + a = (vsate-vdse)/(2*vsate-vdse); + a = a*a; + temp = 2.0/3.0; + p = PP + (1-PP)*exp(-vds/vsate); + *capgs = CF+2*temp*cgc*(1-a)/(1+p); + a = vsate/(2*vsate-vdse); + a = a*a; + *capgd = CF+2*p*temp*cgc*(1-a)/(1+p); + +} diff --git a/src/spicelib/devices/hfet2/hfet2mask.c b/src/spicelib/devices/hfet2/hfet2mask.c new file mode 100644 index 000000000..0b1e54a31 --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2mask.c @@ -0,0 +1,160 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Thomas L. Quarles +**********/ +/* +Imported into HFET2 model: Paolo Nenzi 2001 + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "devdefs.h" +#include "ifsim.h" +#include "hfet2defs.h" +#include "sperror.h" +#include "suffix.h" + + +/* ARGSUSED */ +int +HFET2mAsk(ckt,inst,which,value) + CKTcircuit *ckt; + GENmodel *inst; + int which; + IFvalue *value; +{ + HFET2model *here = (HFET2model*)inst; + switch(which) { + case HFET2_MOD_VTO: + value->rValue = here->HFET2vto; + return (OK); + case HFET2_MOD_LAMBDA: + value->rValue = here->HFET2lambda; + return (OK); + case HFET2_MOD_RD: + value->rValue = here->HFET2rd; + return (OK); + case HFET2_MOD_RS: + value->rValue = here->HFET2rs; + return (OK); + case HFET2_MOD_RDI: + value->rValue = here->HFET2rdi; + return (OK); + case HFET2_MOD_RSI: + value->rValue = here->HFET2rsi; + return (OK); + case HFET2_MOD_ETA: + value->rValue = here->HFET2eta; + return (OK); + case HFET2_MOD_M: + value->rValue = here->HFET2m; + return (OK); + case HFET2_MOD_MC: + value->rValue = here->HFET2mc; + return (OK); + case HFET2_MOD_GAMMA: + value->rValue = here->HFET2gamma; + return (OK); + case HFET2_MOD_SIGMA0: + value->rValue = here->HFET2sigma0; + return (OK); + case HFET2_MOD_VSIGMAT: + value->rValue = here->HFET2vsigmat; + return (OK); + case HFET2_MOD_VSIGMA: + value->rValue = here->HFET2vsigma; + return (OK); + case HFET2_MOD_MU: + value->rValue = here->HFET2mu; + return (OK); + case HFET2_MOD_DI: + value->rValue = here->HFET2di; + return (OK); + case HFET2_MOD_DELTA: + value->rValue = here->HFET2delta; + return (OK); + case HFET2_MOD_VS: + value->rValue = here->HFET2vs; + return (OK); + case HFET2_MOD_NMAX: + value->rValue = here->HFET2nmax; + return (OK); + case HFET2_MOD_DELTAD: + value->rValue = here->HFET2deltad; + return (OK); + case HFET2_MOD_P: + value->rValue = here->HFET2p; + return (OK); + case HFET2_MOD_JS: + value->rValue = here->HFET2js; + return (OK); + case HFET2_MOD_ETA1: + value->rValue = here->HFET2eta1; + return (OK); + case HFET2_MOD_D1: + value->rValue = here->HFET2d1; + return (OK); + case HFET2_MOD_VT1: + value->rValue = here->HFET2vt1; + return (OK); + case HFET2_MOD_ETA2: + value->rValue = here->HFET2eta2; + return (OK); + case HFET2_MOD_D2: + value->rValue = here->HFET2d2; + return (OK); + case HFET2_MOD_VT2: + value->rValue = here->HFET2vt2; + return (OK); + case HFET2_MOD_GGR: + value->rValue = here->HFET2ggr; + return (OK); + case HFET2_MOD_DEL: + value->rValue = here->HFET2del; + return (OK); + case HFET2_MOD_KLAMBDA: + value->rValue = here->HFET2klambda; + return (OK); + case HFET2_MOD_KMU: + value->rValue = here->HFET2kmu; + return (OK); + case HFET2_MOD_KVTO: + value->rValue = here->HFET2kvto; + return (OK); + case HFET2_MOD_EPSI: + value->rValue = here->HFET2epsi; + return (OK); + case HFET2_MOD_KNMAX: + value->rValue = here->HFET2knmax; + return (OK); + case HFET2_MOD_N: + value->rValue = here->HFET2n; + return (OK); + case HFET2_MOD_CF: + value->rValue = here->HFET2cf; + return (OK); + + case HFET2_MOD_DRAINCONDUCT: + value->rValue = here->HFET2drainConduct; + return (OK); + case HFET2_MOD_SOURCECONDUCT: + value->rValue = here->HFET2sourceConduct; + return (OK); + /* case HFET2_MOD_DEPLETIONCAP: + value->rValue = here->HFET2???; + return(OK); */ + /* case HFET2_MOD_VCRIT: + value->rValue = here->HFET2vcrit; + return (OK); */ + + case HFET2_MOD_TYPE: + if (here->HFET2type == NHFET) + value->sValue = "nhfet"; + else + value->sValue = "phfet"; + default: + return (E_BADPARM); + } + /* NOTREACHED */ +} diff --git a/src/spicelib/devices/hfet2/hfet2mdel.c b/src/spicelib/devices/hfet2/hfet2mdel.c new file mode 100644 index 000000000..661bd59ad --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2mdel.c @@ -0,0 +1,45 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 S. Hwang +**********/ +/* +Imported into hfet2 model: Paolo Nenzi 2001 + */ + +#include "ngspice.h" +#include +#include "hfet2defs.h" +#include "sperror.h" +#include "suffix.h" + + +int +HFET2mDelete(inModel,modname,kill) + GENmodel **inModel; + IFuid modname; + GENmodel *kill; +{ + HFET2model **model = (HFET2model**)inModel; + HFET2model *modfast = (HFET2model*)kill; + HFET2instance *here; + HFET2instance *prev = NULL; + HFET2model **oldmod; + oldmod = model; + for( ; *model ; model = &((*model)->HFET2nextModel)) { + if( (*model)->HFET2modName == modname || + (modfast && *model == modfast) ) goto delgot; + oldmod = model; + } + return(E_NOMOD); + +delgot: + *oldmod = (*model)->HFET2nextModel; /* cut deleted device out of list */ + for(here = (*model)->HFET2instances ; here ; here = here->HFET2nextInstance) { + if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + FREE(*model); + return(OK); + +} diff --git a/src/spicelib/devices/hfet2/hfet2mpar.c b/src/spicelib/devices/hfet2/hfet2mpar.c new file mode 100644 index 000000000..f372c3a5c --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2mpar.c @@ -0,0 +1,177 @@ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "hfet2defs.h" +#include "sperror.h" +#include "suffix.h" + + +int HFET2mParam(param, value, inModel) +int param; +IFvalue *value; +GENmodel *inModel; +{ + + HFET2model *model = (HFET2model*)inModel; + switch(param) { + case HFET2_MOD_CF: + model->HFET2cfGiven = TRUE; + CF = value->rValue; + break; + case HFET2_MOD_D1: + model->HFET2d1Given = TRUE; + D1 = value->rValue; + break; + case HFET2_MOD_D2: + model->HFET2d2Given = TRUE; + D2 = value->rValue; + break; + case HFET2_MOD_DEL: + model->HFET2delGiven = TRUE; + DEL = value->rValue; + break; + case HFET2_MOD_DELTA: + model->HFET2deltaGiven = TRUE; + DELTA = value->rValue; + break; + case HFET2_MOD_DELTAD: + model->HFET2deltadGiven = TRUE; + DELTAD = value->rValue; + break; + case HFET2_MOD_DI: + model->HFET2diGiven = TRUE; + DI = value->rValue; + break; + case HFET2_MOD_EPSI: + model->HFET2epsiGiven = TRUE; + EPSI = value->rValue; + break; + case HFET2_MOD_ETA: + model->HFET2etaGiven = TRUE; + ETA = value->rValue; + break; + case HFET2_MOD_ETA1: + model->HFET2eta1Given = TRUE; + ETA1 = value->rValue; + break; + case HFET2_MOD_ETA2: + model->HFET2eta2Given = TRUE; + ETA2 = value->rValue; + break; + case HFET2_MOD_GAMMA: + model->HFET2gammaGiven = TRUE; + GAMMA = value->rValue; + break; + case HFET2_MOD_GGR: + model->HFET2ggrGiven = TRUE; + GGR = value->rValue; + break; + case HFET2_MOD_JS: + model->HFET2jsGiven = TRUE; + JS = value->rValue; + break; + case HFET2_MOD_KLAMBDA: + model->HFET2klambdaGiven = TRUE; + KLAMBDA = value->rValue; + break; + case HFET2_MOD_KMU: + model->HFET2kmuGiven = TRUE; + KMU = value->rValue; + break; + case HFET2_MOD_KNMAX: + model->HFET2knmaxGiven = TRUE; + KNMAX = value->rValue; + break; + case HFET2_MOD_KVTO: + model->HFET2kvtoGiven = TRUE; + KVTO = value->rValue; + break; + case HFET2_MOD_LAMBDA: + model->HFET2lambdaGiven = TRUE; + LAMBDA = value->rValue; + break; + case HFET2_MOD_M: + model->HFET2mGiven = TRUE; + M = value->rValue; + break; + case HFET2_MOD_MC: + model->HFET2mcGiven = TRUE; + MC = value->rValue; + break; + case HFET2_MOD_MU: + model->HFET2muGiven = TRUE; + MU = value->rValue; + break; + case HFET2_MOD_N: + model->HFET2nGiven = TRUE; + N = value->rValue; + break; + case HFET2_MOD_NMAX: + model->HFET2nmaxGiven = TRUE; + NMAX = value->rValue; + break; + case HFET2_MOD_P: + model->HFET2pGiven = TRUE; + PP = value->rValue; + break; + case HFET2_MOD_RD: + model->HFET2rdGiven = TRUE; + RD = value->rValue; + break; + case HFET2_MOD_RDI: + model->HFET2rdiGiven = TRUE; + RDI = value->rValue; + break; + case HFET2_MOD_RS: + model->HFET2rsGiven = TRUE; + RS = value->rValue; + break; + case HFET2_MOD_RSI: + model->HFET2rsiGiven = TRUE; + RSI = value->rValue; + break; + case HFET2_MOD_SIGMA0: + model->HFET2sigma0Given = TRUE; + SIGMA0 = value->rValue; + break; + case HFET2_MOD_VS: + model->HFET2vsGiven = TRUE; + VS = value->rValue; + break; + case HFET2_MOD_VSIGMA: + model->HFET2vsigmaGiven = TRUE; + VSIGMA = value->rValue; + break; + case HFET2_MOD_VSIGMAT: + model->HFET2vsigmatGiven = TRUE; + VSIGMAT = value->rValue; + break; + case HFET2_MOD_VT1: + model->HFET2vt1Given = TRUE; + HFET2_VT1 = value->rValue; + break; + case HFET2_MOD_VT2: + model->HFET2vt2Given = TRUE; + VT2 = value->rValue; + break; + case HFET2_MOD_VTO: + model->HFET2vtoGiven = TRUE; + VTO = value->rValue; + break; + case HFET2_MOD_NHFET: + if(value->iValue) { + TYPE = NHFET; + } + break; + case HFET2_MOD_PHFET: + if(value->iValue) { + TYPE = PHFET; + } + break; + default: + return(E_BADPARM); + } + return(OK); + +} diff --git a/src/spicelib/devices/hfet2/hfet2param.c b/src/spicelib/devices/hfet2/hfet2param.c new file mode 100644 index 000000000..b23a2bbd0 --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2param.c @@ -0,0 +1,60 @@ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "hfet2defs.h" +#include "sperror.h" +#include "suffix.h" + + +int HFET2param(param, value, inst, select) +int param; +IFvalue *value; +GENinstance *inst; +IFvalue *select; +{ + + HFET2instance *here = (HFET2instance*)inst; + switch(param) { + case HFET2_LENGTH: + L = value->rValue; + here->HFET2lengthGiven = TRUE; + break; + case HFET2_IC_VDS: + here->HFET2icVDS = value->rValue; + here->HFET2icVDSGiven = TRUE; + break; + case HFET2_IC_VGS: + here->HFET2icVGS = value->rValue; + here->HFET2icVGSGiven = TRUE; + break; + case HFET2_OFF: + here->HFET2off = value->iValue; + break; + case HFET2_IC: + switch(value->v.numValue) { + case 2: + here->HFET2icVGS = *(value->v.vec.rVec+1); + here->HFET2icVGSGiven = TRUE; + case 1: + here->HFET2icVDS = *(value->v.vec.rVec); + here->HFET2icVDSGiven = TRUE; + break; + default: + return(E_BADPARM); + } + break; + case HFET2_TEMP: + TEMP = value->rValue+CONSTCtoK; + here->HFET2tempGiven = TRUE; + break; + case HFET2_WIDTH: + W = value->rValue; + here->HFET2widthGiven = TRUE; + break; + default: + return(E_BADPARM); + } + return(OK); + +} diff --git a/src/spicelib/devices/hfet2/hfet2setup.c b/src/spicelib/devices/hfet2/hfet2setup.c new file mode 100644 index 000000000..67d306231 --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2setup.c @@ -0,0 +1,233 @@ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "hfet2defs.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + + +int HFET2setup(matrix, inModel, ckt, states) +SMPmatrix *matrix; +GENmodel *inModel; +CKTcircuit *ckt; +int *states; +{ + + HFET2model *model = (HFET2model*)inModel; + HFET2instance *here; + int error; + CKTnode *tmp; + + for( ; model != NULL; model = model->HFET2nextModel ) { + if((TYPE != NHFET) && (TYPE != PHFET) ) + TYPE = NHFET; + if(!model->HFET2cfGiven) + CF = 0; + if(!model->HFET2d1Given) + D1 = 0.03e-6; + if(!model->HFET2d2Given) + D2 = 0.2e-6; + if(!model->HFET2delGiven) + DEL = 0.04; + if(!model->HFET2deltaGiven) + DELTA = 3.0; + if(!model->HFET2deltadGiven) + DELTAD = 4.5e-9; + if(!model->HFET2diGiven) + DI = 0.04e-6; + if(!model->HFET2epsiGiven) + EPSI = 12.244*8.85418e-12; + if(!model->HFET2etaGiven) + if(TYPE == NHFET) + ETA = 1.28; + else + ETA = 1.4; + if(!model->HFET2eta1Given) + ETA1 = 2; + if(!model->HFET2eta2Given) + ETA2 = 2; + if(!model->HFET2gammaGiven) + GAMMA = 3.0; + if(!model->HFET2ggrGiven) + GGR = 0; + if(!model->HFET2jsGiven) + JS = 0; + if(!model->HFET2klambdaGiven) + KLAMBDA = 0; + if(!model->HFET2kmuGiven) + KMU = 0; + if(!model->HFET2knmaxGiven) + KNMAX = 0; + if(!model->HFET2kvtoGiven) + KVTO = 0; + if(!model->HFET2lambdaGiven) + LAMBDA = 0.15; + if(!model->HFET2mGiven) + M = 3.0; + if(!model->HFET2mcGiven) + MC = 3.0; + if(!model->HFET2muGiven) + if(TYPE == NHFET) + MU = 0.4; + else + MU = 0.03; + if(!model->HFET2nGiven) + N = 5.0; + if(!model->HFET2nmaxGiven) + NMAX = 2e16; + if(!model->HFET2pGiven) + PP = 1; + if(!model->HFET2rdGiven) + RD = 0; + if(!model->HFET2rdiGiven) + RDI = 0; + if(!model->HFET2rsGiven) + RS = 0; + if(!model->HFET2rsiGiven) + RSI = 0; + if(!model->HFET2sigma0Given) + SIGMA0 = 0.057; + if(!model->HFET2vsGiven) + if(TYPE == NHFET) + VS = 1.5e5; + else + VS = 0.8e5; + if(!model->HFET2vsigmaGiven) + VSIGMA = 0.1; + if(!model->HFET2vsigmatGiven) + VSIGMAT = 0.3; + if(!model->HFET2vt1Given) + // initialized in HFET2temp + HFET2_VT1 = 0; + if(!model->HFET2vt2Given) + // initialized in HFET2temp + VT2 = 0; + if(!model->HFET2vtoGiven) { + if(model->HFET2type == NHFET) + VTO = 0.15; + else + VTO = -0.15; + } + + /* loop through all the instances of the model */ + + + for (here = model->HFET2instances; here != NULL; here=here->HFET2nextInstance) { + + CKTnode *tmpNode; + IFuid tmpName; + + here->HFET2state = *states; + *states += 13; + + if(!here->HFET2lengthGiven) + L = 1e-6; + if(!here->HFET2tempGiven) + TEMP = ckt->CKTtemp; + if(!here->HFET2widthGiven) + W = 20e-6; + + if(model->HFET2rs != 0 && here->HFET2sourcePrimeNode==0) { + error = CKTmkVolt(ckt,&tmp,here->HFET2name,"source"); + if(error) return(error); + here->HFET2sourcePrimeNode = 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->HFET2sourcePrimeNode = here->HFET2sourceNode; + } + if(model->HFET2rd != 0 && here->HFET2drainPrimeNode==0) { + error = CKTmkVolt(ckt,&tmp,here->HFET2name,"drain"); + if(error) return(error); + here->HFET2drainPrimeNode = 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->HFET2drainPrimeNode = here->HFET2drainNode; + } + +/* macro to make elements with built in test for out of memory */ +#define TSTALLOC(ptr,first,second) \ +if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ + return(E_NOMEM);\ +} + + TSTALLOC(HFET2drainDrainPrimePtr,HFET2drainNode,HFET2drainPrimeNode) + TSTALLOC(HFET2gateDrainPrimePtr,HFET2gateNode,HFET2drainPrimeNode) + TSTALLOC(HFET2gateSourcePrimePtr,HFET2gateNode,HFET2sourcePrimeNode) + TSTALLOC(HFET2sourceSourcePrimePtr,HFET2sourceNode,HFET2sourcePrimeNode) + TSTALLOC(HFET2drainPrimeDrainPtr,HFET2drainPrimeNode,HFET2drainNode) + TSTALLOC(HFET2drainPrimeGatePtr,HFET2drainPrimeNode,HFET2gateNode) + TSTALLOC(HFET2drainPriHFET2ourcePrimePtr,HFET2drainPrimeNode,HFET2sourcePrimeNode) + TSTALLOC(HFET2sourcePrimeGatePtr,HFET2sourcePrimeNode,HFET2gateNode) + TSTALLOC(HFET2sourcePriHFET2ourcePtr,HFET2sourcePrimeNode,HFET2sourceNode) + TSTALLOC(HFET2sourcePrimeDrainPrimePtr,HFET2sourcePrimeNode,HFET2drainPrimeNode) + TSTALLOC(HFET2drainDrainPtr,HFET2drainNode,HFET2drainNode) + TSTALLOC(HFET2gateGatePtr,HFET2gateNode,HFET2gateNode) + TSTALLOC(HFET2sourceSourcePtr,HFET2sourceNode,HFET2sourceNode) + TSTALLOC(HFET2drainPrimeDrainPrimePtr,HFET2drainPrimeNode,HFET2drainPrimeNode) + TSTALLOC(HFET2sourcePriHFET2ourcePrimePtr,HFET2sourcePrimeNode,HFET2sourcePrimeNode) + + } + } + return(OK); + +} + + +int +HFET2unsetup(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + HFET2model *model; + HFET2instance *here; + + for (model = (HFET2model *)inModel; model != NULL; + model = model->HFET2nextModel) + { + for (here = model->HFET2instances; here != NULL; + here=here->HFET2nextInstance) + { + if (here->HFET2drainPrimeNode + && here->HFET2drainPrimeNode != here->HFET2drainNode) + { + CKTdltNNum(ckt, here->HFET2drainPrimeNode); + here->HFET2drainPrimeNode = 0; + } + if (here->HFET2sourcePrimeNode + && here->HFET2sourcePrimeNode != here->HFET2sourceNode) + { + CKTdltNNum(ckt, here->HFET2sourcePrimeNode); + here->HFET2sourcePrimeNode = 0; + } + /*if (here->HFET2gateNode + && here->HFET2gateNode != here->HFET2gateNode) + { + CKTdltNNum(ckt, here->HFET2gateNode); + here->HFET2gateNode = 0; + }*/ + } + + } + return OK; +} \ No newline at end of file diff --git a/src/spicelib/devices/hfet2/hfet2temp.c b/src/spicelib/devices/hfet2/hfet2temp.c new file mode 100644 index 000000000..e512a5713 --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2temp.c @@ -0,0 +1,56 @@ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "hfet2defs.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + + +int HFET2temp(inModel, ckt) +GENmodel *inModel; +CKTcircuit *ckt; +{ + + HFET2instance *here; + HFET2model *model = (HFET2model*)inModel; + + for( ; model != NULL; model = model->HFET2nextModel ) { + if(model->HFET2rd != 0) + model->HFET2drainConduct = 1/model->HFET2rd; + else + model->HFET2drainConduct = 0; + if(model->HFET2rs != 0) + model->HFET2sourceConduct = 1/model->HFET2rs; + else + model->HFET2sourceConduct = 0; + if(!model->HFET2vt1Given) + HFET2_VT1 = VTO+CHARGE*NMAX*DI/EPSI; + if(!model->HFET2vt2Given) + VT2 = VTO; + DELTA2 = DELTA*DELTA; + for (here = model->HFET2instances; here != NULL; here=here->HFET2nextInstance) { + double vt = CONSTKoverQ*TEMP; + double tdiff = TEMP - ckt->CKTnomTemp; + TLAMBDA = LAMBDA + KLAMBDA*tdiff; + TMU = MU - KMU*tdiff; + TNMAX = NMAX - KNMAX*tdiff; + TVTO = TYPE*VTO - KVTO*tdiff; + JSLW = JS*L*W/2; + GGRLW = GGR*L*W/2; + N0 = EPSI*ETA*vt/2/CHARGE/(DI+DELTAD); + N01 = EPSI*ETA1*vt/2/CHARGE/D1; + if(model->HFET2eta2Given) + N02 = EPSI*ETA2*vt/2/CHARGE/D2; + else + N02 = 0.0; + GCHI0 = CHARGE*W*TMU/L; + IMAX = CHARGE*TNMAX*VS*W; + VCRIT = vt*log(vt/(CONSTroot2 * 1e-11)); + } + } + return(OK); + +} diff --git a/src/spicelib/devices/hfet2/hfet2trunc.c b/src/spicelib/devices/hfet2/hfet2trunc.c new file mode 100644 index 000000000..ce74da535 --- /dev/null +++ b/src/spicelib/devices/hfet2/hfet2trunc.c @@ -0,0 +1,27 @@ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "hfet2defs.h" +#include "sperror.h" +#include "suffix.h" + + +int HFET2trunc(inModel, ckt, tiHFET2tep) +GENmodel *inModel; +CKTcircuit *ckt; +double *tiHFET2tep; +{ + + HFET2model *model = (HFET2model*)inModel; + HFET2instance *here; + + for( ; model != NULL; model = model->HFET2nextModel) { + for(here=model->HFET2instances;here!=NULL;here = here->HFET2nextInstance){ + CKTterr(here->HFET2qgs,ckt,tiHFET2tep); + CKTterr(here->HFET2qgd,ckt,tiHFET2tep); + } + } + return(OK); + +} 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/indinit.c b/src/spicelib/devices/ind/indinit.c new file mode 100644 index 000000000..7847de3e5 --- /dev/null +++ b/src/spicelib/devices/ind/indinit.c @@ -0,0 +1,122 @@ +#include + +#include + +#include "inditf.h" +#include "indext.h" +#include "indinit.h" + + +SPICEdev INDinfo = { + { + "Inductor", + "Inductors", + + &INDnSize, + &INDnSize, + INDnames, + + &INDpTSize, + INDpTable, + + 0, + NULL, + 0 + }, + + DEVparam : INDparam, + DEVmodParam : NULL, + DEVload : INDload, + DEVsetup : INDsetup, + DEVunsetup : INDunsetup, + DEVpzSetup : INDsetup, + DEVtemperature: NULL, + DEVtrunc : INDtrunc, + DEVfindBranch : NULL, + DEVacLoad : INDacLoad, + DEVaccept : NULL, + DEVdestroy : INDdestroy, + DEVmodDelete : INDmDelete, + DEVdelete : INDdelete, + DEVsetic : NULL, + DEVask : INDask, + DEVmodAsk : NULL, + DEVpzLoad : INDpzLoad, + DEVconvTest : NULL, + DEVsenSetup : INDsSetup, + DEVsenLoad : INDsLoad, + DEVsenUpdate : INDsUpdate, + DEVsenAcLoad : INDsAcLoad, + DEVsenPrint : INDsPrint, + DEVsenTrunc : NULL, + DEVdisto : NULL, /* DISTO */ + DEVnoise : NULL, /* NOISE */ + + DEVinstSize : &INDiSize, + DEVmodSize : &INDmSize + +}; + + +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, + MUTmDelete, + MUTdelete, + NULL, + MUTask, + NULL, + MUTpzLoad, + NULL, + MUTsSetup, + NULL, + NULL, + NULL, + MUTsPrint, + NULL, + NULL, /* DISTO */ + NULL, /* NOISE */ + + &MUTiSize, + &MUTmSize + +}; + + +SPICEdev * +get_ind_info(void) +{ + return &INDinfo; +} + + +SPICEdev * +get_mut_info(void) +{ + return &MUTinfo; +} diff --git a/src/spicelib/devices/ind/indinit.h b/src/spicelib/devices/ind/indinit.h new file mode 100644 index 000000000..9e4913c68 --- /dev/null +++ b/src/spicelib/devices/ind/indinit.h @@ -0,0 +1,16 @@ +#ifndef _INDINIT_H +#define _INDINIT_H + +extern IFparm INDpTable[ ]; +extern char *INDnames[ ]; +extern int INDpTSize; +extern int INDnSize; +extern int INDiSize; +extern int INDmSize; + +extern IFparm MUTpTable[ ]; +extern int MUTpTSize; +extern int MUTiSize; +extern int MUTmSize; + +#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/isrcinit.c b/src/spicelib/devices/isrc/isrcinit.c new file mode 100644 index 000000000..903288a80 --- /dev/null +++ b/src/spicelib/devices/isrc/isrcinit.c @@ -0,0 +1,64 @@ +#include + +#include + +#include "isrcitf.h" +#include "isrcext.h" +#include "isrcinit.h" + + +SPICEdev ISRCinfo = { + { + "Isource", + "Independent current source", + + &ISRCnSize, + &ISRCnSize, + ISRCnames, + + &ISRCpTSize, + ISRCpTable, + + 0, + NULL, + DEV_DEFAULT + }, + + DEVparam : ISRCparam, + DEVmodParam : NULL, + DEVload : ISRCload, + DEVsetup : NULL, + DEVunsetup : NULL, + DEVpzSetup : NULL, + DEVtemperature: ISRCtemp, + DEVtrunc : NULL, + DEVfindBranch : NULL, + DEVacLoad : ISRCacLoad, + DEVaccept : ISRCaccept, + DEVdestroy : ISRCdestroy, + DEVmodDelete : ISRCmDelete, + DEVdelete : ISRCdelete, + DEVsetic : NULL, + DEVask : ISRCask, + DEVmodAsk : NULL, + DEVpzLoad : NULL, + DEVconvTest : NULL, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, /* DISTO */ + DEVnoise : NULL, /* NOISE */ + + DEVinstSize : &ISRCiSize, + DEVmodSize : &ISRCmSize +}; + + +SPICEdev * +get_isrc_info(void) +{ + return &ISRCinfo; +} diff --git a/src/spicelib/devices/isrc/isrcinit.h b/src/spicelib/devices/isrc/isrcinit.h new file mode 100644 index 000000000..effc6bfd3 --- /dev/null +++ b/src/spicelib/devices/isrc/isrcinit.h @@ -0,0 +1,11 @@ +#ifndef _ISRCINIT_H +#define _ISRCINIT_H + +extern IFparm ISRCpTable[ ]; +extern char *ISRCnames[ ]; +extern int ISRCpTSize; +extern int ISRCnSize; +extern int ISRCiSize; +extern int ISRCmSize; + +#endif 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/jfetinit.c b/src/spicelib/devices/jfet/jfetinit.c new file mode 100644 index 000000000..77d169a56 --- /dev/null +++ b/src/spicelib/devices/jfet/jfetinit.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "jfetitf.h" +#include "jfetext.h" +#include "jfetinit.h" + + +SPICEdev JFETinfo = { + { + "JFET", + "Junction Field effect transistor", + + &JFETnSize, + &JFETnSize, + JFETnames, + + &JFETpTSize, + JFETpTable, + + &JFETmPTSize, + JFETmPTable, + DEV_DEFAULT + }, + + DEVparam : JFETparam, + DEVmodParam : JFETmParam, + DEVload : JFETload, + DEVsetup : JFETsetup, + DEVunsetup : JFETunsetup, + DEVpzSetup : JFETsetup, + DEVtemperature: JFETtemp, + DEVtrunc : JFETtrunc, + DEVfindBranch : NULL, + DEVacLoad : JFETacLoad, + DEVaccept : NULL, + DEVdestroy : JFETdestroy, + DEVmodDelete : JFETmDelete, + DEVdelete : JFETdelete, + DEVsetic : JFETgetic, + DEVask : JFETask, + DEVmodAsk : JFETmAsk, + DEVpzLoad : JFETpzLoad, + DEVconvTest : NULL, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : JFETdisto, + DEVnoise : JFETnoise, + + DEVinstSize : &JFETiSize, + DEVmodSize : &JFETmSize + +}; + + +SPICEdev * +get_jfet_info(void) +{ + return &JFETinfo; +} diff --git a/src/spicelib/devices/jfet/jfetinit.h b/src/spicelib/devices/jfet/jfetinit.h new file mode 100644 index 000000000..e7e6ab3d8 --- /dev/null +++ b/src/spicelib/devices/jfet/jfetinit.h @@ -0,0 +1,13 @@ +#ifndef _JFETINIT_H +#define _JFETINIT_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; + +#endif 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/jfet2init.c b/src/spicelib/devices/jfet2/jfet2init.c new file mode 100644 index 000000000..0b4f1ee84 --- /dev/null +++ b/src/spicelib/devices/jfet2/jfet2init.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "jfet2itf.h" +#include "jfet2ext.h" +#include "jfet2init.h" + + +SPICEdev JFET2info = { + { + "JFET2", + "Short channel field effect transistor", + + &JFET2nSize, + &JFET2nSize, + JFET2names, + + &JFET2pTSize, + JFET2pTable, + + &JFET2mPTSize, + JFET2mPTable, + DEV_DEFAULT + }, + + DEVparam : JFET2param, + DEVmodParam : JFET2mParam, + DEVload : JFET2load, + DEVsetup : JFET2setup, + DEVunsetup : JFET2unsetup, + DEVpzSetup : JFET2setup, + DEVtemperature: JFET2temp, + DEVtrunc : JFET2trunc, + DEVfindBranch : NULL, + DEVacLoad : JFET2acLoad, + DEVaccept : NULL, + DEVdestroy : JFET2destroy, + DEVmodDelete : JFET2mDelete, + DEVdelete : JFET2delete, + DEVsetic : JFET2getic, + DEVask : JFET2ask, + DEVmodAsk : JFET2mAsk, + DEVpzLoad : NULL, /* AN_pz */ + DEVconvTest : NULL, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, /* AN_disto */ + DEVnoise : JFET2noise, + + DEVinstSize : &JFET2iSize, + DEVmodSize : &JFET2mSize + +}; + + +SPICEdev * +get_jfet2_info(void) +{ + return &JFET2info; +} diff --git a/src/spicelib/devices/jfet2/jfet2init.h b/src/spicelib/devices/jfet2/jfet2init.h new file mode 100644 index 000000000..48dd27dd2 --- /dev/null +++ b/src/spicelib/devices/jfet2/jfet2init.h @@ -0,0 +1,13 @@ +#ifndef _JFET2INIT_H +#define _JFET2INIT_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; + +#endif 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/ltrainit.c b/src/spicelib/devices/ltra/ltrainit.c new file mode 100644 index 000000000..5c62e3573 --- /dev/null +++ b/src/spicelib/devices/ltra/ltrainit.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "ltraitf.h" +#include "ltraext.h" +#include "ltrainit.h" + + +SPICEdev LTRAinfo = { + { + "LTRA", + "Lossy transmission line", + + <RAnSize, + <RAnSize, + LTRAnames, + + <RApTSize, + LTRApTable, + + <RAmPTSize, + LTRAmPTable, + 0 + }, + + DEVparam : LTRAparam, + DEVmodParam : LTRAmParam, + DEVload : LTRAload, + DEVsetup : LTRAsetup, + DEVunsetup : LTRAunsetup, + DEVpzSetup : LTRAsetup, + DEVtemperature: LTRAtemp, + DEVtrunc : LTRAtrunc, + DEVfindBranch : NULL, + DEVacLoad : LTRAacLoad /*LTRAacLoad*/, + DEVaccept : LTRAaccept, + DEVdestroy : LTRAdestroy, + DEVmodDelete : LTRAmDelete, + DEVdelete : LTRAdelete, + DEVsetic : NULL, /* getic */ + DEVask : LTRAask, + DEVmodAsk : LTRAmAsk, /* */ + DEVpzLoad : NULL, /* pzLoad */ + DEVconvTest : NULL, /* convTest */ + DEVsenSetup : NULL, /* sSetup */ + DEVsenLoad : NULL, /* sLoad */ + DEVsenUpdate : NULL, /* sUpdate */ + DEVsenAcLoad : NULL, /* sAcLoad */ + DEVsenPrint : NULL, /* sPrint */ + DEVsenTrunc : NULL, /* */ + DEVdisto : NULL, /* disto */ + DEVnoise : NULL, /* noise */ + + DEVinstSize : <RAiSize, + DEVmodSize : <RAmSize + +}; + + +SPICEdev * +get_ltra_info(void) +{ + return <RAinfo; +} diff --git a/src/spicelib/devices/ltra/ltrainit.h b/src/spicelib/devices/ltra/ltrainit.h new file mode 100644 index 000000000..90f466f86 --- /dev/null +++ b/src/spicelib/devices/ltra/ltrainit.h @@ -0,0 +1,13 @@ +#ifndef _LTRAINIT_H +#define _LTRAINIT_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; + +#endif 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/mesinit.c b/src/spicelib/devices/mes/mesinit.c new file mode 100644 index 000000000..18abd8deb --- /dev/null +++ b/src/spicelib/devices/mes/mesinit.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "mesitf.h" +#include "mesext.h" +#include "mesinit.h" + + +SPICEdev MESinfo = { + { + "MES", + "GaAs MESFET model", + + &MESnSize, + &MESnSize, + MESnames, + + &MESpTSize, + MESpTable, + + &MESmPTSize, + MESmPTable, + DEV_DEFAULT + }, + + DEVparam : MESparam, + DEVmodParam : MESmParam, + DEVload : MESload, + DEVsetup : MESsetup, + DEVunsetup : MESunsetup, + DEVpzSetup : MESsetup, + DEVtemperature: MEStemp, + DEVtrunc : MEStrunc, + DEVfindBranch : NULL, + DEVacLoad : MESacLoad, + DEVaccept : NULL, + DEVdestroy : MESdestroy, + DEVmodDelete : MESmDelete, + DEVdelete : MESdelete, + DEVsetic : MESgetic, + DEVask : MESask, + DEVmodAsk : MESmAsk, + DEVpzLoad : MESpzLoad, + DEVconvTest : NULL, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : MESdisto, + DEVnoise : MESnoise, + + DEVinstSize : &MESiSize, + DEVmodSize : &MESmSize + +}; + + +SPICEdev * +get_mes_info(void) +{ + return &MESinfo; +} diff --git a/src/spicelib/devices/mes/mesinit.h b/src/spicelib/devices/mes/mesinit.h new file mode 100644 index 000000000..541cb8ad5 --- /dev/null +++ b/src/spicelib/devices/mes/mesinit.h @@ -0,0 +1,13 @@ +#ifndef _MESINIT_H +#define _MESINIT_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; + +#endif 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/mesa/Makefile.am b/src/spicelib/devices/mesa/Makefile.am new file mode 100644 index 000000000..1e5c48fed --- /dev/null +++ b/src/spicelib/devices/mesa/Makefile.am @@ -0,0 +1,29 @@ +## Process this file with automake to produce Makefile.in + +pkglib_LTLIBRARIES = libmesa.la + +libmesa_la_SOURCES = \ + mesa.c \ + mesaacl.c \ + mesaask.c \ + mesadefs.h \ + mesadel.c \ + mesadest.c \ + mesaext.h \ + mesagetic.c \ + mesainit.c \ + mesainit.h \ + mesaitf.h \ + mesaload.c \ + mesamask.c \ + mesamdel.c \ + mesamparam.c \ + mesaparam.c \ + mesasetup.c \ + mesatemp.c \ + mesatrunc.c + + + +INCLUDES = -I$(top_srcdir)/src/include +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/mesa/mesa.c b/src/spicelib/devices/mesa/mesa.c new file mode 100644 index 000000000..bdc3a887e --- /dev/null +++ b/src/spicelib/devices/mesa/mesa.c @@ -0,0 +1,130 @@ +/********** +Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. +Author: Trond Ytterdal +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "devdefs.h" +#include "mesadefs.h" +#include "suffix.h" + + +IFparm MESApTable[] = { /* parameters */ + OP("off", MESA_OFF, IF_FLAG ,"Device initially off"), + IOP("l", MESA_LENGTH, IF_REAL ,"Length of device"), + IOP("w", MESA_WIDTH, IF_REAL ,"Width of device"), + IOP("icvds", MESA_IC_VDS, IF_REAL ,"Initial D-S voltage"), + IOP("icvgs", MESA_IC_VGS, IF_REAL ,"Initial G-S voltage"), + IOP("td", MESA_TD, IF_REAL ,"Instance drain temperature"), + IOP("ts", MESA_TS, IF_REAL ,"Instance source temperature"), + OP("dnode", MESA_DRAINNODE, IF_INTEGER,"Number of drain node"), + OP("gnode", MESA_GATENODE, IF_INTEGER,"Number of gate node"), + OP("snode", MESA_SOURCENODE, IF_INTEGER,"Number of source node"), + OP("dprimenode",MESA_DRAINPRIMENODE, IF_INTEGER,"Number of internal drain node"), + OP("sprimenode",MESA_SOURCEPRIMENODE,IF_INTEGER,"Number of internal source node"), + OP("gprimenode",MESA_GATEPRIMENODE, IF_INTEGER,"Number of internal gate node"), + OP("vgs", MESA_VGS, IF_REAL,"Gate-Source voltage"), + OP("vgd", MESA_VGD, IF_REAL,"Gate-Drain voltage"), + OP("cg", MESA_CG, IF_REAL,"Gate capacitance"), + OP("cd", MESA_CD, IF_REAL,"Drain capacitance"), + OP("cgd", MESA_CGD, IF_REAL,"Gate_Drain capacitance"), + OP("gm", MESA_GM, IF_REAL,"Transconductance"), + OP("gds", MESA_GDS, IF_REAL,"Drain-Source conductance"), + OP("ggs", MESA_GGS, IF_REAL,"Gate-Source conductance"), + OP("ggd", MESA_GGD, IF_REAL,"Gate-Drain conductance"), + OP("qgs", MESA_QGS, IF_REAL,"Gate-Source charge storage"), + OP("cqgs", MESA_CQGS, IF_REAL,"Capacitance due to gate-source charge storage"), + OP("qgd", MESA_QGD, IF_REAL,"Gate-Drain charge storage"), + OP("cqgd", MESA_CQGD, IF_REAL,"Capacitance due to gate-drain charge storage"), + OP("cs", MESA_CS, IF_REAL,"Source current"), + OP("p", MESA_POWER, IF_REAL,"Power dissipated by the mesfet") + +}; + +IFparm MESAmPTable[] = { /* model parameters */ + IOP( "vt0", MESA_MOD_VTO, IF_REAL,"Pinch-off voltage"), + IOP( "vto", MESA_MOD_VTO, IF_REAL,"Pinch-off voltage"), + IOP( "lambda", MESA_MOD_LAMBDA, IF_REAL,"Output conductance parameter"), + IOP( "lambdahf",MESA_MOD_LAMBDAHF, IF_REAL,"Output conductance parameter at high frequencies"), + IOP( "beta", MESA_MOD_BETA, IF_REAL,"Transconductance parameter"), + IOP( "vs", MESA_MOD_VS, IF_REAL,"Saturation velocity"), + IOP( "rd", MESA_MOD_RD, IF_REAL,"Drain ohmic resistance"), + IOP( "rs", MESA_MOD_RS, IF_REAL,"Source ohmic resistance"), + IOP( "rg", MESA_MOD_RG, IF_REAL,"Gate ohmic resistance"), + IOP( "ri", MESA_MOD_RI, IF_REAL,"Gate-source ohmic resistance"), + IOP( "rf", MESA_MOD_RF, IF_REAL,"Gate-drain ohmic resistance"), + IOP( "rdi", MESA_MOD_RDI, IF_REAL,"Intrinsic source ohmic resistance"), + IOP( "rsi", MESA_MOD_RSI, IF_REAL,"Intrinsic drain ohmic resistance"), + IOP( "phib", MESA_MOD_PHIB, IF_REAL,"Effective Schottky barrier height at room temperature"), + IOP( "phib1", MESA_MOD_PHIB1, IF_REAL,""), + IOP( "tphib", MESA_MOD_PHIB1, IF_REAL,""), + IOP( "astar", MESA_MOD_ASTAR, IF_REAL,"Effective Richardson constant"), + IOP( "ggr", MESA_MOD_GGR, IF_REAL,"Reverse diode conductance"), + IOP( "del", MESA_MOD_DEL, IF_REAL,""), + IOP( "xchi", MESA_MOD_XCHI, IF_REAL,""), + IOP( "tggr", MESA_MOD_XCHI, IF_REAL,""), + IOP( "n", MESA_MOD_N, IF_REAL,"Emission coefficient"), + IOP( "eta", MESA_MOD_ETA, IF_REAL,"Subthreshold ideality factor"), + IOP( "m", MESA_MOD_M, IF_REAL,"Knee shape parameter"), + IOP( "mc", MESA_MOD_MC, IF_REAL,"Knee shape parameter"), + IOP( "alpha", MESA_MOD_ALPHA, IF_REAL,""), + IOP( "sigma0", MESA_MOD_SIGMA0, IF_REAL,"Threshold voltage coefficient"), + IOP( "vsigmat",MESA_MOD_VSIGMAT,IF_REAL,""), + IOP( "vsigma", MESA_MOD_VSIGMA, IF_REAL,""), + IOP( "mu", MESA_MOD_MU, IF_REAL,"Mobility"), + IOP( "theta", MESA_MOD_THETA, IF_REAL,""), + IOP( "mu1", MESA_MOD_MU1, IF_REAL,"Second moblity parameter"), + IOP( "mu2", MESA_MOD_MU2, IF_REAL,"Third moblity parameter"), + IOP( "d", MESA_MOD_D, IF_REAL,"Depth of device"), + IOP( "nd", MESA_MOD_ND, IF_REAL,"Doping density"), + IOP( "du", MESA_MOD_DU, IF_REAL,"Depth of device"), + IOP( "ndu", MESA_MOD_NDU, IF_REAL,"Doping density"), + IOP( "th", MESA_MOD_TH, IF_REAL,"Thickness of delta doped layer"), + IOP( "ndelta", MESA_MOD_NDELTA, IF_REAL,"Delta doped layer doping density"), + IOP( "delta", MESA_MOD_DELTA, IF_REAL,""), + IOP( "tc", MESA_MOD_TC, IF_REAL,"Transconductance compression factor"), + IOP( "tvto", MESA_MOD_TVTO, IF_REAL,"Temperature coefficient for vto"), + IOP( "alphat", MESA_MOD_TVTO, IF_REAL,""), + IOP( "tlambda",MESA_MOD_TLAMBDA,IF_REAL,"Temperature coefficient for lambda"), + IOP( "teta0", MESA_MOD_TETA0, IF_REAL,"First temperature coefficient for eta"), + IOP( "teta1", MESA_MOD_TETA1, IF_REAL,"Second temperature coefficient for eta"), + IOP( "tmu", MESA_MOD_TMU, IF_REAL,"Temperature coefficient for mobility"), + IOP( "xtm0", MESA_MOD_XTM0, IF_REAL,"First exponent for temp dependence of mobility"), + IOP( "xtm1", MESA_MOD_XTM1, IF_REAL,"Second exponent for temp dependence of mobility"), + IOP( "xtm2", MESA_MOD_XTM2, IF_REAL,"Third exponent for temp dependence of mobility"), + IOP( "ks", MESA_MOD_KS, IF_REAL,"Sidegating coefficient"), + IOP( "vsg", MESA_MOD_VSG, IF_REAL,"Sidegating voltage"), + IOP( "tf", MESA_MOD_TF, IF_REAL,"Characteristic temperature determined by traps"), + IOP( "flo", MESA_MOD_FLO, IF_REAL,""), + IOP( "delfo", MESA_MOD_DELFO, IF_REAL,""), + IOP( "ag", MESA_MOD_AG, IF_REAL,""), + IOP( "rtc1", MESA_MOD_TC1, IF_REAL,""), + IOP( "rtc2", MESA_MOD_TC2, IF_REAL,""), + IOP( "zeta", MESA_MOD_ZETA, IF_REAL,""), + IOP( "level", MESA_MOD_LEVEL, IF_REAL,""), + IOP( "nmax", MESA_MOD_NMAX, IF_REAL,""), + IOP( "gamma", MESA_MOD_GAMMA, IF_REAL,""), + IOP( "epsi", MESA_MOD_EPSI, IF_REAL,""), + IOP( "cas", MESA_MOD_CAS, IF_REAL,""), + IOP( "cbs", MESA_MOD_CBS, IF_REAL,""), + OP( "type", MESA_MOD_TYPE, IF_FLAG,"N-type or P-type MESfet model"), + IP( "pmf", MESA_MOD_PMF, IF_FLAG,"P type MESfet model"), + IP( "nmf", MESA_MOD_NMF, IF_FLAG,"N type MESfet model"), + OP( "gd", MESA_MOD_DRAINCONDUCT, IF_REAL,"Drain conductance"), + OP( "gs", MESA_MOD_SOURCECONDUCT, IF_REAL,"Source conductance"), + OP( "vcrit", MESA_MOD_VCRIT, IF_REAL,"Critical voltage"), +}; + +char *MESAnames[] = { + "Drain", + "Gate", + "Source" +}; + +int MESAnSize = NUMELEMS(MESAnames); +int MESApTSize = NUMELEMS(MESApTable); +int MESAmPTSize = NUMELEMS(MESAmPTable); +int MESAiSize = sizeof(MESAinstance); +int MESAmSize = sizeof(MESAmodel); diff --git a/src/spicelib/devices/mesa/mesaacl.c b/src/spicelib/devices/mesa/mesaacl.c new file mode 100644 index 000000000..efe4c8c6d --- /dev/null +++ b/src/spicelib/devices/mesa/mesaacl.c @@ -0,0 +1,97 @@ +/********** +Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. +Author: Trond Ytterdal +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "mesadefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +MESAacLoad(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + MESAmodel *model = (MESAmodel*)inModel; + MESAinstance *here; + double gm; + double gds; + double ggspp; + double ggdpp; + double ggs; + double xgs; + double ggd; + double xgd; + double f; + double lambda; + double vds; + double delidgch; + double delidvds; + + for( ; model != NULL; model = model->MESAnextModel ) { + for( here = model->MESAinstances; here != NULL; + here = here->MESAnextInstance) { + f = ckt->CKTomega/2/M_PI; + if(here->MESAdelf == 0) + lambda = here->MESAtLambda; + else + lambda = here->MESAtLambda+0.5*(here->MESAtLambdahf-here->MESAtLambda)* + (1+tanh((f-here->MESAfl)/here->MESAdelf)); + vds= *(ckt->CKTstate0 + here->MESAvgs) - + *(ckt->CKTstate0 + here->MESAvgd); + delidgch = here->MESAdelidgch0*(1+lambda*vds); + delidvds = here->MESAdelidvds0*(1+2*lambda*vds) - + here->MESAdelidvds1; + gm = (delidgch*here->MESAgm0+here->MESAgm1)*here->MESAgm2; + gds = delidvds+here->MESAgds0; + + ggspp=*(ckt->CKTstate0 + here->MESAggspp); + ggdpp=*(ckt->CKTstate0 + here->MESAggdpp); + ggs= *(ckt->CKTstate0 + here->MESAggs) ; + xgs= *(ckt->CKTstate0 + here->MESAqgs) * ckt->CKTomega ; + ggd= *(ckt->CKTstate0 + here->MESAggd) ; + xgd= *(ckt->CKTstate0 + here->MESAqgd) * ckt->CKTomega ; + + *(here->MESAdrainDrainPtr) += here->MESAdrainConduct; + *(here->MESAsourceSourcePtr) += here->MESAsourceConduct; + *(here->MESAgateGatePtr) += here->MESAgateConduct; + *(here->MESAsourcePrmPrmSourcePrmPrmPtr) += (here->MESAtGi+ggspp); + *(here->MESAdrainPrmPrmDrainPrmPrmPtr) += (here->MESAtGf+ggdpp); + *(here->MESAdrainDrainPrimePtr) -= here->MESAdrainConduct; + *(here->MESAdrainPrimeDrainPtr) -= here->MESAdrainConduct; + *(here->MESAsourceSourcePrimePtr) -= here->MESAsourceConduct; + *(here->MESAsourcePrimeSourcePtr) -= here->MESAsourceConduct; + *(here->MESAgateGatePrimePtr) -= here->MESAgateConduct; + *(here->MESAgatePrimeGatePtr) -= here->MESAgateConduct; + *(here->MESAgatePrimeDrainPrimePtr) += (-ggd); + *(here->MESAgatePrimeSourcePrimePtr) += (-ggs); + *(here->MESAdrainPrimeGatePrimePtr) += (gm-ggd); + *(here->MESAdrainPrimeSourcePrimePtr) += (-gds-gm); + *(here->MESAsourcePrimeGatePrimePtr) += (-ggs-gm); + *(here->MESAsourcePrimeDrainPrimePtr) += (-gds); + *(here->MESAgatePrimeGatePrimePtr) += (ggd+ggs+here->MESAgateConduct+ggspp+ggdpp); + *(here->MESAdrainPrimeDrainPrimePtr) += (gds+ggd+here->MESAdrainConduct+here->MESAtGf); + *(here->MESAsourcePrimeSourcePrimePtr) += (gds+gm+ggs+here->MESAsourceConduct+here->MESAtGi); + *(here->MESAsourcePrimeSourcePrmPrmPtr) -= here->MESAtGi; + *(here->MESAsourcePrmPrmSourcePrimePtr) -= here->MESAtGi; + *(here->MESAgatePrimeSourcePrmPrmPtr) -= ggspp; + *(here->MESAsourcePrmPrmGatePrimePtr) -= ggspp; + *(here->MESAdrainPrimeDrainPrmPrmPtr) -= here->MESAtGf; + *(here->MESAdrainPrmPrmDrainPrimePtr) -= here->MESAtGf; + *(here->MESAgatePrimeDrainPrmPrmPtr) -= ggdpp; + *(here->MESAdrainPrmPrmGatePrimePtr) -= ggdpp; + *(here->MESAsourcePrmPrmSourcePrmPrmPtr+1) += xgs; + *(here->MESAdrainPrmPrmDrainPrmPrmPtr+1) += xgd; + *(here->MESAgatePrimeGatePrimePtr+1) += xgd+xgs; + *(here->MESAgatePrimeDrainPrmPrmPtr+1) -= xgd; + *(here->MESAdrainPrmPrmGatePrimePtr+1) -= xgd; + *(here->MESAgatePrimeSourcePrmPrmPtr+1) -= xgs; + *(here->MESAsourcePrmPrmGatePrimePtr+1) -= xgs; + } + } + return(OK); +} diff --git a/src/spicelib/devices/mesa/mesaask.c b/src/spicelib/devices/mesa/mesaask.c new file mode 100644 index 000000000..931f88342 --- /dev/null +++ b/src/spicelib/devices/mesa/mesaask.c @@ -0,0 +1,140 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Thomas L. Quarles +**********/ +/* +Imported into MESA model: 2001 Paolo Nenzi + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "devdefs.h" +#include "ifsim.h" +#include "mesadefs.h" +#include "sperror.h" +#include "suffix.h" + + +/* ARGSUSED */ +int +MESAask(ckt,inst,which,value,select) + CKTcircuit *ckt; + GENinstance *inst; + int which; + IFvalue *value; + IFvalue *select; +{ + MESAinstance *here = (MESAinstance*)inst; + static char *msg = "Current and power not available in ac analysis"; + switch(which) { + case MESA_LENGTH: + value->rValue = here->MESAlength; + return (OK); + case MESA_WIDTH: + value->rValue = here->MESAwidth; + return (OK); + case MESA_IC_VDS: + value->rValue = here->MESAicVDS; + return (OK); + case MESA_IC_VGS: + value->rValue = here->MESAicVGS; + return (OK); + case MESA_OFF: + value->iValue = here->MESAoff; + return (OK); + case MESA_TD: + value->rValue = here->MESAtd; + return (OK); + case MESA_TS: + value->rValue = here->MESAts; + return (OK); + case MESA_DRAINNODE: + value->iValue = here->MESAdrainNode; + return (OK); + case MESA_GATENODE: + value->iValue = here->MESAgateNode; + return (OK); + case MESA_SOURCENODE: + value->iValue = here->MESAsourceNode; + return (OK); + case MESA_DRAINPRIMENODE: + value->iValue = here->MESAdrainPrimeNode; + return (OK); + case MESA_SOURCEPRIMENODE: + value->iValue = here->MESAsourcePrimeNode; + return (OK); + case MESA_GATEPRIMENODE: + value->iValue = here->MESAgatePrimeNode; + return (OK); + case MESA_VGS: + value->rValue = *(ckt->CKTstate0 + here->MESAvgs); + return (OK); + case MESA_VGD: + value->rValue = *(ckt->CKTstate0 + here->MESAvgd); + return (OK); + case MESA_CG: + value->rValue = *(ckt->CKTstate0 + here->MESAcg); + return (OK); + case MESA_CD: + value->rValue = *(ckt->CKTstate0 + here->MESAcd); + return (OK); + case MESA_CGD: + value->rValue = *(ckt->CKTstate0 + here->MESAcgd); + return (OK); + case MESA_GM: + value->rValue = *(ckt->CKTstate0 + here->MESAgm); + return (OK); + case MESA_GDS: + value->rValue = *(ckt->CKTstate0 + here->MESAgds); + return (OK); + case MESA_GGS: + value->rValue = *(ckt->CKTstate0 + here->MESAggs); + return (OK); + case MESA_GGD: + value->rValue = *(ckt->CKTstate0 + here->MESAggd); + return (OK); + case MESA_QGS: + value->rValue = *(ckt->CKTstate0 + here->MESAqgs); + return (OK); + case MESA_CQGS: + value->rValue = *(ckt->CKTstate0 + here->MESAcqgs); + return (OK); + case MESA_QGD: + value->rValue = *(ckt->CKTstate0 + here->MESAqgd); + return (OK); + case MESA_CQGD: + value->rValue = *(ckt->CKTstate0 + here->MESAcqgd); + return (OK); + case MESA_CS : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = MALLOC(strlen(msg)+1); + errRtn = "MESAask"; + strcpy(errMsg,msg); + return(E_ASKCURRENT); + } else { + value->rValue = -*(ckt->CKTstate0 + here->MESAcd); + value->rValue -= *(ckt->CKTstate0 + here->MESAcg); + } + return(OK); + case MESA_POWER : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = MALLOC(strlen(msg)+1); + errRtn = "MESAask"; + strcpy(errMsg,msg); + return(E_ASKPOWER); + } else { + value->rValue = *(ckt->CKTstate0 + here->MESAcd) * + *(ckt->CKTrhsOld + here->MESAdrainNode); + value->rValue += *(ckt->CKTstate0 + here->MESAcg) * + *(ckt->CKTrhsOld + here->MESAgateNode); + value->rValue -= (*(ckt->CKTstate0+here->MESAcd) + + *(ckt->CKTstate0 + here->MESAcg)) * + *(ckt->CKTrhsOld + here->MESAsourceNode); + } + return(OK); + default: + return (E_BADPARM); + } + /* NOTREACHED */ +} diff --git a/src/spicelib/devices/mesa/mesadefs.h b/src/spicelib/devices/mesa/mesadefs.h new file mode 100644 index 000000000..2daf7b6fc --- /dev/null +++ b/src/spicelib/devices/mesa/mesadefs.h @@ -0,0 +1,467 @@ +/********** +Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. +Author: Trond Ytterdal +**********/ + +#ifndef MESA +#define MESA + +#include "ifsim.h" +#include "cktdefs.h" +#include "gendefs.h" +#include "complex.h" +#include "noisedef.h" + + /* structures used to describe MESFET Transistors */ + + +/* information used to describe a single instance */ + +typedef struct sMESAinstance { + struct sMESAmodel *MESAmodPtr; /* backpointer to model */ + struct sMESAinstance *MESAnextInstance; /* pointer to next instance of + * current model*/ + IFuid MESAname; /* pointer to character string naming this instance */ + int MESAowner; /* number of owner process */ + int MESAstate; /* pointer to start of state vector for MESAfet */ + + int MESAdrainNode; /* number of drain node of MESAfet */ + int MESAgateNode; /* number of gate node of MESAfet */ + int MESAsourceNode; /* number of source node of MESAfet */ + int MESAdrainPrimeNode; /* number of internal drain node of MESAfet */ + int MESAgatePrimeNode; /* number of internal gate node of MESAfet */ + int MESAsourcePrimeNode; /* number of internal source node of MESAfet */ + int MESAsourcePrmPrmNode; + int MESAdrainPrmPrmNode; + double MESAlength; /* length of MESAfet */ + double MESAwidth; /* width of MESAfet */ + double MESAicVDS; /* initial condition voltage D-S*/ + double MESAicVGS; /* initial condition voltage G-S*/ + double MESAtd; /* drain temperature */ + double MESAts; /* source temperature */ + double MESAtVto; + double MESAtLambda; + double MESAtLambdahf; + double MESAtEta; + double MESAtMu; + double MESAtPhib; + double MESAtTheta; + double MESAtRsi; + double MESAtRdi; + double MESAtRs; + double MESAtRd; + double MESAtRg; + double MESAtRi; + double MESAtRf; + double MESAtGi; + double MESAtGf; + double MESAdrainConduct; + double MESAsourceConduct; + double MESAgateConduct; + double *MESAdrainDrainPrimePtr; + double *MESAgatePrimeDrainPrimePtr; + double *MESAgatePrimeSourcePrimePtr; + double *MESAsourceSourcePrimePtr; + double *MESAdrainPrimeDrainPtr; + double *MESAdrainPrimeGatePrimePtr; + double *MESAdrainPrimeSourcePrimePtr; + double *MESAsourcePrimeGatePrimePtr; + double *MESAsourcePrimeSourcePtr; + double *MESAsourcePrimeDrainPrimePtr; + double *MESAdrainDrainPtr; + double *MESAgatePrimeGatePrimePtr; + double *MESAsourceSourcePtr; + double *MESAdrainPrimeDrainPrimePtr; + double *MESAsourcePrimeSourcePrimePtr; + double *MESAgateGatePrimePtr; + double *MESAgatePrimeGatePtr; + double *MESAgateGatePtr; + double *MESAsourcePrmPrmSourcePrmPrmPtr; + double *MESAsourcePrmPrmSourcePrimePtr; + double *MESAsourcePrimeSourcePrmPrmPtr; + double *MESAsourcePrmPrmGatePrimePtr; + double *MESAgatePrimeSourcePrmPrmPtr; + double *MESAdrainPrmPrmDrainPrmPrmPtr; + double *MESAdrainPrmPrmDrainPrimePtr; + double *MESAdrainPrimeDrainPrmPrmPtr; + double *MESAdrainPrmPrmGatePrimePtr; + double *MESAgatePrimeDrainPrmPrmPtr; + +#define MESAvgs MESAstate +#define MESAvgd MESAstate+1 +#define MESAcg MESAstate+2 +#define MESAcd MESAstate+3 +#define MESAcgd MESAstate+4 +#define MESAcgs MESAstate+5 +#define MESAgm MESAstate+6 +#define MESAgds MESAstate+7 +#define MESAggs MESAstate+8 +#define MESAggd MESAstate+9 +#define MESAqgs MESAstate+10 +#define MESAcqgs MESAstate+11 +#define MESAqgd MESAstate+12 +#define MESAcqgd MESAstate+13 +#define MESAvgspp MESAstate+14 +#define MESAggspp MESAstate+15 +#define MESAcgspp MESAstate+16 +#define MESAvgdpp MESAstate+17 +#define MESAggdpp MESAstate+18 +#define MESAcgdpp MESAstate+19 + + int MESAoff; + unsigned MESAlengthGiven : 1; + unsigned MESAwidthGiven : 1; + unsigned MESAicVDSGiven : 1; + unsigned MESAicVGSGiven : 1; + unsigned MESAtdGiven : 1; + unsigned MESAtsGiven : 1; + +int MESAmode; + +/* + * naming convention: + * x = vgs + * y = vgd + * z = vds + * cdr = cdrain + */ + +#define MESANDCOEFFS 27 + +#ifndef NODISTO + double MESAdCoeffs[MESANDCOEFFS]; +#else /* NODISTO */ + double *MESAdCoeffs; +#endif /* NODISTO */ + +#ifndef CONFIG + +#define cdr_x MESAdCoeffs[0] +#define cdr_z MESAdCoeffs[1] +#define cdr_x2 MESAdCoeffs[2] +#define cdr_z2 MESAdCoeffs[3] +#define cdr_xz MESAdCoeffs[4] +#define cdr_x3 MESAdCoeffs[5] +#define cdr_z3 MESAdCoeffs[6] +#define cdr_x2z MESAdCoeffs[7] +#define cdr_xz2 MESAdCoeffs[8] + +#define ggs3 MESAdCoeffs[9] +#define ggd3 MESAdCoeffs[10] +#define ggs2 MESAdCoeffs[11] +#define ggd2 MESAdCoeffs[12] + +#define qgs_x2 MESAdCoeffs[13] +#define qgs_y2 MESAdCoeffs[14] +#define qgs_xy MESAdCoeffs[15] +#define qgs_x3 MESAdCoeffs[16] +#define qgs_y3 MESAdCoeffs[17] +#define qgs_x2y MESAdCoeffs[18] +#define qgs_xy2 MESAdCoeffs[19] + +#define qgd_x2 MESAdCoeffs[20] +#define qgd_y2 MESAdCoeffs[21] +#define qgd_xy MESAdCoeffs[22] +#define qgd_x3 MESAdCoeffs[23] +#define qgd_y3 MESAdCoeffs[24] +#define qgd_x2y MESAdCoeffs[25] +#define qgd_xy2 MESAdCoeffs[26] + +#endif + +/* indices to the array of MESAFET noise sources */ + +#define MESARDNOIZ 0 +#define MESARSNOIZ 1 +#define MESAIDNOIZ 2 +#define MESAFLNOIZ 3 +#define MESATOTNOIZ 4 + +#define MESANSRCS 5 /* the number of MESAFET noise sources */ + +#ifndef NONOISE + double MESAnVar[NSTATVARS][MESANSRCS]; +#else /* NONOISE */ + double **MESAnVar; +#endif /* NONOISE */ + double MESAcsatfs; + double MESAcsatfd; + double MESAggrwl; + double MESAgchi0; + double MESAbeta; + double MESAisatb0; + double MESAimax; + double MESAcf; + double MESAfl; + double MESAdelf; + double MESAgds0; + double MESAgm0; + double MESAgm1; + double MESAgm2; + double MESAdelidvds0; + double MESAdelidvds1; + double MESAdelidgch0; + double MESAn0; + double MESAnsb0; + double MESAvcrits; + double MESAvcritd; +} MESAinstance ; + + +/* per model data */ + +typedef struct sMESAmodel { /* model structure for a MESAfet */ + int MESAmodType; /* type index of this device type */ + struct sMESAmodel *MESAnextModel; /* pointer to next possible model in + * linked list */ + MESAinstance * MESAinstances; /* pointer to list of instances + * that have this model */ + IFuid MESAmodName; /* pointer to character string naming this model */ + int MESAtype; + + double MESAthreshold; + double MESAlambda; + double MESAbeta; + double MESAvs; + double MESAeta; + double MESAm; + double MESAmc; + double MESAalpha; + double MESAsigma0; + double MESAvsigmat; + double MESAvsigma; + double MESAmu; + double MESAtheta; + double MESAmu1; + double MESAmu2; + double MESAd; + double MESAnd; + double MESAdu; + double MESAndu; + double MESAth; + double MESAndelta; + double MESAdelta; + double MESAtc; + double MESArdi; + double MESArsi; + double MESAdrainResist; + double MESAsourceResist; + double MESAgateResist; + double MESAri; + double MESArf; + double MESAphib; + double MESAphib1; + double MESAastar; + double MESAggr; + double MESAdel; + double MESAxchi; + double MESAn; + double MESAtvto; + double MESAtlambda; + double MESAteta0; + double MESAteta1; + double MESAtmu; + double MESAxtm0; + double MESAxtm1; + double MESAxtm2; + double MESAks; + double MESAvsg; + double MESAlambdahf; + double MESAtf; + double MESAflo; + double MESAdelfo; + double MESAag; + double MESAtc1; + double MESAtc2; + double MESAzeta; + double MESAlevel; + double MESAnmax; + double MESAgamma; + double MESAepsi; + double MESAcbs; + double MESAcas; + + double MESAsigma; + double MESAvpo; + double MESAvpou; + double MESAvpod; + double MESAdeltaSqr; + + unsigned MESAthresholdGiven:1; + unsigned MESAlambdaGiven:1; + unsigned MESAbetaGiven:1; + unsigned MESAvsGiven:1; + unsigned MESAetaGiven:1; + unsigned MESAmGiven:1; + unsigned MESAmcGiven:1; + unsigned MESAalphaGiven:1; + unsigned MESAsigma0Given:1; + unsigned MESAvsigmatGiven:1; + unsigned MESAvsigmaGiven:1; + unsigned MESAmuGiven:1; + unsigned MESAthetaGiven:1; + unsigned MESAmu1Given:1; + unsigned MESAmu2Given:1; + unsigned MESAdGiven:1; + unsigned MESAndGiven:1; + unsigned MESAduGiven:1; + unsigned MESAnduGiven:1; + unsigned MESAthGiven:1; + unsigned MESAndeltaGiven:1; + unsigned MESAdeltaGiven:1; + unsigned MESAtcGiven:1; + unsigned MESArdiGiven:1; + unsigned MESArsiGiven:1; + unsigned MESAdrainResistGiven:1; + unsigned MESAsourceResistGiven:1; + unsigned MESAgateResistGiven:1; + unsigned MESAriGiven:1; + unsigned MESArfGiven:1; + unsigned MESAphibGiven:1; + unsigned MESAphib1Given:1; + unsigned MESAastarGiven:1; + unsigned MESAggrGiven:1; + unsigned MESAdelGiven:1; + unsigned MESAxchiGiven:1; + unsigned MESAnGiven:1; + unsigned MESAtvtoGiven:1; + unsigned MESAtlambdaGiven:1; + unsigned MESAteta0Given:1; + unsigned MESAteta1Given:1; + unsigned MESAtmuGiven:1; + unsigned MESAxtm0Given:1; + unsigned MESAxtm1Given:1; + unsigned MESAxtm2Given:1; + unsigned MESAksGiven:1; + unsigned MESAvsgGiven:1; + unsigned MESAlambdahfGiven:1; + unsigned MESAtfGiven:1; + unsigned MESAfloGiven:1; + unsigned MESAdelfoGiven:1; + unsigned MESAagGiven:1; + unsigned MESAtc1Given:1; + unsigned MESAtc2Given:1; + unsigned MESAzetaGiven:1; + unsigned MESAlevelGiven:1; + unsigned MESAnmaxGiven:1; + unsigned MESAgammaGiven:1; + unsigned MESAepsiGiven:1; + unsigned MESAcbsGiven:1; + unsigned MESAcasGiven:1; + +} MESAmodel; + +#ifndef NMF + +#define NMF 1 +#define PMF -1 +#endif + +/* device parameters */ +#define MESA_LENGTH 1 +#define MESA_WIDTH 2 +#define MESA_IC_VDS 3 +#define MESA_IC_VGS 4 +#define MESA_TD 5 +#define MESA_TS 6 +#define MESA_IC 7 +#define MESA_OFF 8 +#define MESA_CS 9 +#define MESA_POWER 10 + +/* model parameters */ +#define MESA_MOD_VTO 101 +#define MESA_MOD_VS 102 +#define MESA_MOD_LAMBDA 103 +#define MESA_MOD_RD 104 +#define MESA_MOD_RS 105 +#define MESA_MOD_RG 106 +#define MESA_MOD_RI 107 +#define MESA_MOD_RF 108 +#define MESA_MOD_RDI 109 +#define MESA_MOD_RSI 110 +#define MESA_MOD_PHIB 111 +#define MESA_MOD_PHIB1 112 +#define MESA_MOD_ASTAR 113 +#define MESA_MOD_GGR 114 +#define MESA_MOD_DEL 115 +#define MESA_MOD_XCHI 116 +#define MESA_MOD_N 117 +#define MESA_MOD_ETA 118 +#define MESA_MOD_M 119 +#define MESA_MOD_MC 120 +#define MESA_MOD_SIGMA0 121 +#define MESA_MOD_VSIGMAT 122 +#define MESA_MOD_VSIGMA 123 +#define MESA_MOD_MU 124 +#define MESA_MOD_MU1 125 +#define MESA_MOD_MU2 126 +#define MESA_MOD_D 127 +#define MESA_MOD_ND 128 +#define MESA_MOD_DELTA 129 +#define MESA_MOD_TC 130 +#define MESA_MOD_NMF 131 +#define MESA_MOD_TVTO 132 +#define MESA_MOD_TLAMBDA 134 +#define MESA_MOD_TETA0 135 +#define MESA_MOD_TETA1 136 +#define MESA_MOD_TMU 137 +#define MESA_MOD_XTM0 138 +#define MESA_MOD_XTM1 139 +#define MESA_MOD_XTM2 140 +#define MESA_MOD_KS 141 +#define MESA_MOD_VSG 142 +#define MESA_MOD_LAMBDAHF 143 +#define MESA_MOD_TF 144 +#define MESA_MOD_FLO 145 +#define MESA_MOD_DELFO 146 +#define MESA_MOD_AG 147 +#define MESA_MOD_THETA 148 +#define MESA_MOD_ALPHA 149 +#define MESA_MOD_TC1 150 +#define MESA_MOD_TC2 151 +#define MESA_MOD_ZETA 152 +#define MESA_MOD_BETA 153 +#define MESA_MOD_DU 154 +#define MESA_MOD_NDU 155 +#define MESA_MOD_TH 156 +#define MESA_MOD_NDELTA 157 +#define MESA_MOD_LEVEL 158 +#define MESA_MOD_NMAX 159 +#define MESA_MOD_GAMMA 160 +#define MESA_MOD_EPSI 161 +#define MESA_MOD_CBS 162 +#define MESA_MOD_CAS 163 +#define MESA_MOD_PMF 164 +#define MESA_MOD_TYPE 165 + +#define MESA_DRAINNODE 201 +#define MESA_GATENODE 202 +#define MESA_SOURCENODE 203 +#define MESA_DRAINPRIMENODE 204 +#define MESA_SOURCEPRIMENODE 205 +#define MESA_GATEPRIMENODE 206 + +#define MESA_VGS 207 +#define MESA_VGD 208 +#define MESA_CG 209 +#define MESA_CD 210 +#define MESA_CGD 211 +#define MESA_GM 212 +#define MESA_GDS 213 +#define MESA_GGS 214 +#define MESA_GGD 215 +#define MESA_QGS 216 +#define MESA_CQGS 217 +#define MESA_QGD 218 +#define MESA_CQGD 219 + +#define MESA_MOD_DRAINCONDUCT 301 +#define MESA_MOD_SOURCECONDUCT 302 +#define MESA_MOD_GATECONDUCT 303 +#define MESA_MOD_DEPLETIONCAP 304 +#define MESA_MOD_VCRIT 305 + +#include "mesaext.h" + +#endif /*MESA*/ diff --git a/src/spicelib/devices/mesa/mesadel.c b/src/spicelib/devices/mesa/mesadel.c new file mode 100644 index 000000000..7df0bcfd9 --- /dev/null +++ b/src/spicelib/devices/mesa/mesadel.c @@ -0,0 +1,39 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 S. Hwang +**********/ +/* +Imported into mesa model: 2001 Paolo Nenzi + */ + +#include "ngspice.h" +#include +#include "mesadefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +MESAdelete(inModel,name,inst) + GENmodel *inModel; + IFuid name; + GENinstance **inst; +{ + MESAmodel *model = (MESAmodel*)inModel; + MESAinstance **fast = (MESAinstance**)inst; + MESAinstance **prev = NULL; + MESAinstance *here; + + for( ; model ; model = model->MESAnextModel) { + prev = &(model->MESAinstances); + for(here = *prev; here ; here = *prev) { + if(here->MESAname == name || (fast && here==*fast) ) { + *prev= here->MESAnextInstance; + FREE(here); + return(OK); + } + prev = &(here->MESAnextInstance); + } + } + return(E_NODEV); +} diff --git a/src/spicelib/devices/mesa/mesadest.c b/src/spicelib/devices/mesa/mesadest.c new file mode 100644 index 000000000..56cd32313 --- /dev/null +++ b/src/spicelib/devices/mesa/mesadest.c @@ -0,0 +1,35 @@ +/********** +Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. +Author: Trond Ytterdal +**********/ + +#include "ngspice.h" +#include +#include "mesadefs.h" +#include "suffix.h" + + +void +MESAdestroy(inModel) + GENmodel **inModel; +{ + MESAmodel **model = (MESAmodel**)inModel; + MESAinstance *here; + MESAinstance *prev = NULL; + MESAmodel *mod = *model; + MESAmodel *oldmod = NULL; + + for( ; mod ; mod = mod->MESAnextModel) { + if(oldmod) FREE(oldmod); + oldmod = mod; + prev = (MESAinstance *)NULL; + for(here = mod->MESAinstances ; here ; here = here->MESAnextInstance) { + if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + } + if(oldmod) FREE(oldmod); + *model = NULL; + return; +} diff --git a/src/spicelib/devices/mesa/mesaext.h b/src/spicelib/devices/mesa/mesaext.h new file mode 100644 index 000000000..39db02e25 --- /dev/null +++ b/src/spicelib/devices/mesa/mesaext.h @@ -0,0 +1,37 @@ +/********** +Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. +Author: Trond Ytterdal +**********/ + +#ifdef __STDC__ +extern int MESAacLoad(GENmodel*,CKTcircuit*); +extern int MESAask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); +extern int MESAdelete(GENmodel*,IFuid,GENinstance**); +extern void MESAdestroy(GENmodel**); +extern int MESAgetic(GENmodel*,CKTcircuit*); +extern int MESAload(GENmodel*,CKTcircuit*); +extern int MESAmAsk(CKTcircuit*,GENmodel*,int,IFvalue*); +extern int MESAmDelete(GENmodel**,IFuid,GENmodel*); +extern int MESAmParam(int,IFvalue*,GENmodel*); +extern int MESAparam(int,IFvalue*,GENinstance*,IFvalue*); +extern int MESAsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); +extern int MESAtemp(GENmodel*,CKTcircuit*); +extern int MESAtrunc(GENmodel*,CKTcircuit*,double*); +extern int MESAunsetup(GENmodel*,CKTcircuit*); + +#else /*stdc*/ +extern int MESAacLoad(); +extern int MESAask(); +extern int MESAdelete(); +extern void MESAdestroy(); +extern int MESAgetic(); +extern int MESAload(); +extern int MESAmAsk(); +extern int MESAmDelete(); +extern int MESAmParam(); +extern int MESAparam(); +extern int MESAsetup(); +extern int MESAtemp(); +extern int MESAtrunc(); +extern int MESAunsetup(); +#endif diff --git a/src/spicelib/devices/mesa/mesagetic.c b/src/spicelib/devices/mesa/mesagetic.c new file mode 100644 index 000000000..160ab4429 --- /dev/null +++ b/src/spicelib/devices/mesa/mesagetic.c @@ -0,0 +1,41 @@ +/********** +Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. +Author: Trond Ytterdal +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "mesadefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +MESAgetic(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + MESAmodel *model = (MESAmodel*)inModel; + MESAinstance *here; + /* + * grab initial conditions out of rhs array. User specified, so use + * external nodes to get values + */ + + for( ; model ; model = model->MESAnextModel) { + for(here = model->MESAinstances; here ; here = here->MESAnextInstance) { + if(!here->MESAicVDSGiven) { + here->MESAicVDS = + *(ckt->CKTrhs + here->MESAdrainNode) - + *(ckt->CKTrhs + here->MESAsourceNode); + } + if(!here->MESAicVGSGiven) { + here->MESAicVGS = + *(ckt->CKTrhs + here->MESAgateNode) - + *(ckt->CKTrhs + here->MESAsourceNode); + } + } + } + return(OK); +} diff --git a/src/spicelib/devices/mesa/mesainit.c b/src/spicelib/devices/mesa/mesainit.c new file mode 100644 index 000000000..5e1cc38ad --- /dev/null +++ b/src/spicelib/devices/mesa/mesainit.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "mesaitf.h" +#include "mesaext.h" +#include "mesainit.h" + + +SPICEdev MESAinfo = { + { + "MESA", + "GaAs MESFET model", + + &MESAnSize, + &MESAnSize, + MESAnames, + + &MESApTSize, + MESApTable, + + &MESAmPTSize, + MESAmPTable, + DEV_DEFAULT + }, + + DEVparam : MESAparam, + DEVmodParam : MESAmParam, + DEVload : MESAload, + DEVsetup : MESAsetup, + DEVunsetup : MESAunsetup, + DEVpzSetup : MESAsetup, + DEVtemperature: MESAtemp, + DEVtrunc : MESAtrunc, + DEVfindBranch : NULL, + DEVacLoad : MESAacLoad, + DEVaccept : NULL, + DEVdestroy : MESAdestroy, + DEVmodDelete : MESAmDelete, + DEVdelete : MESAdelete, + DEVsetic : MESAgetic, + DEVask : MESAask, + DEVmodAsk : MESAmAsk, + DEVpzLoad : NULL, + DEVconvTest : NULL, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, + DEVnoise : NULL, + + DEVinstSize : &MESAiSize, + DEVmodSize : &MESAmSize + +}; + + +SPICEdev * +get_mesa_info(void) +{ + return &MESAinfo; +} diff --git a/src/spicelib/devices/mesa/mesainit.h b/src/spicelib/devices/mesa/mesainit.h new file mode 100644 index 000000000..aa4420569 --- /dev/null +++ b/src/spicelib/devices/mesa/mesainit.h @@ -0,0 +1,13 @@ +#ifndef _MESAINIT_H +#define _MESAINIT_H + +extern IFparm MESApTable[ ]; +extern IFparm MESAmPTable[ ]; +extern char *MESAnames[ ]; +extern int MESApTSize; +extern int MESAmPTSize; +extern int MESAnSize; +extern int MESAiSize; +extern int MESAmSize; + +#endif diff --git a/src/spicelib/devices/mesa/mesaitf.h b/src/spicelib/devices/mesa/mesaitf.h new file mode 100644 index 000000000..36493b837 --- /dev/null +++ b/src/spicelib/devices/mesa/mesaitf.h @@ -0,0 +1,9 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +**********/ +#ifndef DEV_MESA +#define DEV_MESA + +SPICEdev *get_mesa_info(void); + +#endif diff --git a/src/spicelib/devices/mesa/mesaload.c b/src/spicelib/devices/mesa/mesaload.c new file mode 100644 index 000000000..cd6444cef --- /dev/null +++ b/src/spicelib/devices/mesa/mesaload.c @@ -0,0 +1,987 @@ +/********** +Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. +Author: Trond Ytterdal +**********/ + +#include "ngspice.h" +#include +#include "devdefs.h" +#include "cktdefs.h" +#include "mesadefs.h" +#include "const.h" +#include "trandefs.h" +#include "sperror.h" +#include "suffix.h" + +/* +#define true 1 +#define false 0 +*/ + +#define EPSILONGAAS (12.244*8.85418e-12) + +#define W (here->MESAwidth) +#define L (here->MESAlength) + +static void mesa1(MESAmodel*, MESAinstance*, double, double, double, + double*, double*, double*, double*,double*); + +static void mesa2(MESAmodel*, MESAinstance*, double, double, double, + double*, double*, double*, double*,double*); + +static void mesa3(MESAmodel*, MESAinstance*, double, double, double, + double*, double*, double*, double*,double*); + +void Pause(void); + +int +MESAload(inModel,ckt) + GENmodel *inModel; + //register CKTcircuit *ckt; + CKTcircuit *ckt; +{ + MESAmodel *model = (MESAmodel*)inModel; + MESAinstance *here; + double capgd; + double capgs; + double cd; + double cdhat; + double cdrain; + double cdreq; + double ceq; + double ceqgd; + double ceqgs; + double cg; + double cgd; + double cgs; + double cghat; + double arg; + double earg; + double delvds; + double delvgd; + double delvgs; + double delvgspp=0; + double delvgdpp=0; + double evgd; + double evgs; + double gds; + double geq; + double ggd; + double ggs; + double gm; + double ggspp=0; + double cgspp=0; + double ggdpp=0; + double cgdpp=0; + double vcrits; + double vcritd; + double vds=0; + double vgd=0; + double vgs=0; + double vgspp=0; + double vgdpp=0; + double vgs1=0; + double vgd1=0; + double xfact; + double temp; + double vted; + double vtes; + double vtd; + double vts; + double von; + double ccorr; + int inverse=FALSE; + int icheck; + int ichk1; + int error; + + /* loop through all the models */ + for( ; model != NULL; model = model->MESAnextModel ) { + + /* loop through all the instances of the model */ + for (here = model->MESAinstances; here != NULL ; + here=here->MESAnextInstance) { + + /* + * dc model parameters + */ + vcrits = here->MESAvcrits; + vcritd = here->MESAvcritd; + vtd = CONSTKoverQ * here->MESAtd; + vts = CONSTKoverQ * here->MESAts; + vted = model->MESAn*vtd; + vtes = model->MESAn*vts; + /* + * initialization + */ + icheck = 1; + if( ckt->CKTmode & MODEINITSMSIG) { + vgs = *(ckt->CKTstate0 + here->MESAvgs); + vgd = *(ckt->CKTstate0 + here->MESAvgd); + vgspp = *(ckt->CKTstate0 + here->MESAvgspp); + vgdpp = *(ckt->CKTstate0 + here->MESAvgdpp); + } else if (ckt->CKTmode & MODEINITTRAN) { + vgs = *(ckt->CKTstate1 + here->MESAvgs); + vgd = *(ckt->CKTstate1 + here->MESAvgd); + vgspp = *(ckt->CKTstate1 + here->MESAvgspp); + vgdpp = *(ckt->CKTstate1 + here->MESAvgdpp); + } else if ( (ckt->CKTmode & MODEINITJCT) && + (ckt->CKTmode & MODETRANOP) && + (ckt->CKTmode & MODEUIC) ) { + vds = here->MESAicVDS; + vgs = here->MESAicVGS; + vgd = vgs-vds; + vgspp = vgs; + vgdpp = vgd; + } else if ( (ckt->CKTmode & MODEINITJCT) && + (here->MESAoff == 0) ) { + vgs = -1; + vgd = -1; + vgspp = 0; + vgdpp = 0; + } else if( (ckt->CKTmode & MODEINITJCT) || + ((ckt->CKTmode & MODEINITFIX) && (here->MESAoff))) { + vgs = 0; + vgd = 0; + vgspp = 0; + vgdpp = 0; + } else { +#ifndef PREDICTOR + if(ckt->CKTmode & MODEINITPRED) { + xfact = ckt->CKTdelta/ckt->CKTdeltaOld[2]; + *(ckt->CKTstate0 + here->MESAvgs) = + *(ckt->CKTstate1 + here->MESAvgs); + vgs = (1+xfact) * *(ckt->CKTstate1 + here->MESAvgs) - + xfact * *(ckt->CKTstate2 + here->MESAvgs); + *(ckt->CKTstate0 + here->MESAvgspp) = + *(ckt->CKTstate1 + here->MESAvgspp); + vgspp = (1+xfact) * *(ckt->CKTstate1 + here->MESAvgspp) - + xfact * *(ckt->CKTstate2 + here->MESAvgspp); + *(ckt->CKTstate0 + here->MESAvgd) = + *(ckt->CKTstate1 + here->MESAvgd); + vgd = (1+xfact)* *(ckt->CKTstate1 + here->MESAvgd) - + xfact * *(ckt->CKTstate2 + here->MESAvgd); + *(ckt->CKTstate0 + here->MESAvgdpp) = + *(ckt->CKTstate1 + here->MESAvgdpp); + vgdpp = (1+xfact) * *(ckt->CKTstate1 + here->MESAvgdpp) - + xfact * *(ckt->CKTstate2 + here->MESAvgdpp); + *(ckt->CKTstate0 + here->MESAcg) = + *(ckt->CKTstate1 + here->MESAcg); + *(ckt->CKTstate0 + here->MESAcd) = + *(ckt->CKTstate1 + here->MESAcd); + *(ckt->CKTstate0 + here->MESAcgd) = + *(ckt->CKTstate1 + here->MESAcgd); + *(ckt->CKTstate0 + here->MESAcgs) = + *(ckt->CKTstate1 + here->MESAcgs); + *(ckt->CKTstate0 + here->MESAgm) = + *(ckt->CKTstate1 + here->MESAgm); + *(ckt->CKTstate0 + here->MESAgds) = + *(ckt->CKTstate1 + here->MESAgds); + *(ckt->CKTstate0 + here->MESAggs) = + *(ckt->CKTstate1 + here->MESAggs); + *(ckt->CKTstate0 + here->MESAggd) = + *(ckt->CKTstate1 + here->MESAggd); + *(ckt->CKTstate0 + here->MESAggspp) = + *(ckt->CKTstate1 + here->MESAggspp); + *(ckt->CKTstate0 + here->MESAcgspp) = + *(ckt->CKTstate1 + here->MESAcgspp); + *(ckt->CKTstate0 + here->MESAggdpp) = + *(ckt->CKTstate1 + here->MESAggdpp); + *(ckt->CKTstate0 + here->MESAcgdpp) = + *(ckt->CKTstate1 + here->MESAcgdpp); + } else { +#endif /* PREDICTOR */ + /* + * compute new nonlinear branch voltages + */ + vgs = (*(ckt->CKTrhsOld+ here->MESAgatePrimeNode)- + *(ckt->CKTrhsOld+here->MESAsourcePrimeNode)); + vgd = (*(ckt->CKTrhsOld+here->MESAgatePrimeNode)- + *(ckt->CKTrhsOld+here->MESAdrainPrimeNode)); + vgspp = (*(ckt->CKTrhsOld+here->MESAgatePrimeNode)- + *(ckt->CKTrhsOld+here->MESAsourcePrmPrmNode)); + vgdpp = (*(ckt->CKTrhsOld+here->MESAgatePrimeNode)- + *(ckt->CKTrhsOld+here->MESAdrainPrmPrmNode)); + +#ifndef PREDICTOR + } +#endif /* PREDICTOR */ + delvgs=vgs - *(ckt->CKTstate0 + here->MESAvgs); + delvgd=vgd - *(ckt->CKTstate0 + here->MESAvgd); + delvds=delvgs - delvgd; + delvgspp = vgspp - *(ckt->CKTstate0 + here->MESAvgspp); + delvgdpp = vgdpp - *(ckt->CKTstate0 + here->MESAvgdpp); + cghat= *(ckt->CKTstate0 + here->MESAcg) + + *(ckt->CKTstate0 + here->MESAggd)*delvgd + + *(ckt->CKTstate0 + here->MESAggs)*delvgs + + *(ckt->CKTstate0 + here->MESAggspp)*delvgspp+ + *(ckt->CKTstate0 + here->MESAggdpp)*delvgdpp; + cdhat= *(ckt->CKTstate0 + here->MESAcd) + + *(ckt->CKTstate0 + here->MESAgm)*delvgs + + *(ckt->CKTstate0 + here->MESAgds)*delvds - + *(ckt->CKTstate0 + here->MESAggd)*delvgd; + /* + * bypass if solution has not changed + */ + if((ckt->CKTbypass) && + (!(ckt->CKTmode & MODEINITPRED)) && + (fabs(delvgs) < ckt->CKTreltol*MAX(fabs(vgs), + fabs(*(ckt->CKTstate0 + here->MESAvgs)))+ + ckt->CKTvoltTol) ) + if((fabs(delvgd) < ckt->CKTreltol*MAX(fabs(vgd), + fabs(*(ckt->CKTstate0 + here->MESAvgd)))+ + ckt->CKTvoltTol)) + if((fabs(delvgspp) < ckt->CKTreltol*MAX(fabs(vgspp), + fabs(*(ckt->CKTstate0 + here->MESAvgspp)))+ + ckt->CKTvoltTol)) + if((fabs(delvgdpp) < ckt->CKTreltol*MAX(fabs(vgdpp), + fabs(*(ckt->CKTstate0 + here->MESAvgdpp)))+ + ckt->CKTvoltTol)) + if((fabs(cghat-*(ckt->CKTstate0 + here->MESAcg)) + < ckt->CKTreltol*MAX(fabs(cghat), + fabs(*(ckt->CKTstate0 + here->MESAcg)))+ + ckt->CKTabstol)) + if((fabs(cdhat-*(ckt->CKTstate0 + here->MESAcd)) + < ckt->CKTreltol*MAX(fabs(cdhat), + fabs(*(ckt->CKTstate0 + here->MESAcd)))+ + ckt->CKTabstol)) { + + /* we can do a bypass */ + vgs= *(ckt->CKTstate0 + here->MESAvgs); + vgd= *(ckt->CKTstate0 + here->MESAvgd); + vds= vgs-vgd; + vgspp = *(ckt->CKTstate0 + here->MESAvgspp); + vgdpp = *(ckt->CKTstate0 + here->MESAvgdpp); + cg= *(ckt->CKTstate0 + here->MESAcg); + cd= *(ckt->CKTstate0 + here->MESAcd); + cgs= *(ckt->CKTstate0 + here->MESAcgs); + cgd= *(ckt->CKTstate0 + here->MESAcgd); + gm= *(ckt->CKTstate0 + here->MESAgm); + gds= *(ckt->CKTstate0 + here->MESAgds); + ggs= *(ckt->CKTstate0 + here->MESAggs); + ggd= *(ckt->CKTstate0 + here->MESAggd); + ggspp = *(ckt->CKTstate0 + here->MESAggspp); + cgspp = *(ckt->CKTstate0 + here->MESAcgspp); + ggdpp = *(ckt->CKTstate0 + here->MESAggdpp); + cgdpp = *(ckt->CKTstate0 + here->MESAcgdpp); + goto load; + } + /* + * limit nonlinear branch voltages + */ + ichk1=1; + vgs = DEVpnjlim(vgs,*(ckt->CKTstate0 + here->MESAvgs),vtes, + vcrits, &icheck); + vgd = DEVpnjlim(vgd,*(ckt->CKTstate0 + here->MESAvgd),vted, + vcritd,&ichk1); + if (ichk1 == 1) { + icheck=1; + } + vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->MESAvgs), + here->MESAtVto); + vgd = DEVfetlim(vgd,*(ckt->CKTstate0 + here->MESAvgd), + here->MESAtVto); + if(here->MESAsourcePrmPrmNode == here->MESAsourcePrimeNode) + vgspp = vgs; + if(here->MESAdrainPrmPrmNode == here->MESAdrainPrimeNode) + vgdpp = vgd; + } + /* + * determine dc current and derivatives + */ + vds = vgs-vgd; + + arg = -vgs*model->MESAdel/vts; + earg = exp(arg); + evgs = exp(vgs/vtes); + ggs = here->MESAcsatfs*evgs/vtes+here->MESAggrwl*earg*(1-arg)+ckt->CKTgmin; + cgs = here->MESAcsatfs*(evgs-1)+here->MESAggrwl*vgs*earg+ + ckt->CKTgmin*vgs; + cg = cgs; + + arg = -vgd*model->MESAdel/vtd; + earg = exp(arg); + evgd = exp(vgd/vted); + ggd = here->MESAcsatfd*evgd/vted+here->MESAggrwl*earg*(1-arg)+ckt->CKTgmin; + cgd = here->MESAcsatfd*(evgd-1)+here->MESAggrwl*vgd*earg+ + ckt->CKTgmin*vgd; + cg = cg+cgd; + + if(vds < 0) { + vds = -vds; + inverse = TRUE; + } + von = here->MESAtVto+model->MESAks*(*(ckt->CKTrhsOld+here->MESAsourcePrimeNode)-model->MESAvsg); + if(model->MESAlevel == 2) + mesa1(model,here,inverse?vgd:vgs,vds,von,&cdrain,&gm,&gds,&capgs,&capgd); + else if(model->MESAlevel == 3) + mesa2(model,here,inverse?vgd:vgs,vds,von,&cdrain,&gm,&gds,&capgs,&capgd); + else if(model->MESAlevel == 4) + mesa3(model,here,inverse?vgd:vgs,vds,von,&cdrain,&gm,&gds,&capgs,&capgd); + if(inverse) { + cdrain = -cdrain; + vds = -vds; + temp = capgs; + capgs = capgd; + capgd = temp; + } + /* + * compute equivalent drain current source + */ + cd = cdrain - cgd; + if ( (ckt->CKTmode & (MODETRAN|MODEINITSMSIG)) || + ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) ){ + /* + * charge storage elements + */ + vgs1 = *(ckt->CKTstate1 + here->MESAvgspp); + vgd1 = *(ckt->CKTstate1 + here->MESAvgdpp); + + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->MESAqgs) = capgs*vgspp; + *(ckt->CKTstate1 + here->MESAqgd) = capgd*vgdpp; + } + *(ckt->CKTstate0+here->MESAqgs) = *(ckt->CKTstate1 + here->MESAqgs) + + capgs*(vgspp-vgs1); + *(ckt->CKTstate0+here->MESAqgd) = *(ckt->CKTstate1 + here->MESAqgd) + + capgd*(vgdpp-vgd1); + + /* + * store small-signal parameters + */ + if( (!(ckt->CKTmode & MODETRANOP)) || + (!(ckt->CKTmode & MODEUIC)) ) { + if(ckt->CKTmode & MODEINITSMSIG) { + *(ckt->CKTstate0 + here->MESAqgs) = capgs; + *(ckt->CKTstate0 + here->MESAqgd) = capgd; + continue; /*go to 1000*/ + } + /* + * transient analysis + */ + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->MESAqgs) = + *(ckt->CKTstate0 + here->MESAqgs); + *(ckt->CKTstate1 + here->MESAqgd) = + *(ckt->CKTstate0 + here->MESAqgd); + } + error = NIintegrate(ckt,&geq,&ceq,capgs,here->MESAqgs); + if(error) return(error); + ggspp = geq; + cgspp = *(ckt->CKTstate0 + here->MESAcqgs); + cg = cg + cgspp; + error = NIintegrate(ckt,&geq,&ceq,capgd,here->MESAqgd); + if(error) return(error); + ggdpp = geq; + cgdpp = *(ckt->CKTstate0 + here->MESAcqgd); + cg = cg + cgdpp; + cd = cd - cgdpp; + if (ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->MESAcqgs) = + *(ckt->CKTstate0 + here->MESAcqgs); + *(ckt->CKTstate1 + here->MESAcqgd) = + *(ckt->CKTstate0 + here->MESAcqgd); + } + } + } + /* + * check convergence + */ + 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->CKTstate0 + here->MESAvgs) = vgs; + *(ckt->CKTstate0 + here->MESAvgspp) = vgspp; + *(ckt->CKTstate0 + here->MESAvgd) = vgd; + *(ckt->CKTstate0 + here->MESAvgdpp) = vgdpp; + *(ckt->CKTstate0 + here->MESAcg) = cg; + *(ckt->CKTstate0 + here->MESAcd) = cd; + *(ckt->CKTstate0 + here->MESAcgd) = cgd; + *(ckt->CKTstate0 + here->MESAcgs) = cgs; + *(ckt->CKTstate0 + here->MESAgm) = gm; + *(ckt->CKTstate0 + here->MESAgds) = gds; + *(ckt->CKTstate0 + here->MESAggs) = ggs; + *(ckt->CKTstate0 + here->MESAggd) = ggd; + *(ckt->CKTstate0 + here->MESAggspp) = ggspp; + *(ckt->CKTstate0 + here->MESAcgspp) = cgspp; + *(ckt->CKTstate0 + here->MESAggdpp) = ggdpp; + *(ckt->CKTstate0 + here->MESAcgdpp) = cgdpp; + + /* + * load current vector + */ +load: + ccorr = model->MESAag*(cgs-cgd); + ceqgd = cgd + cgdpp - ggd*vgd - ggdpp*vgdpp; + ceqgs = cgs + cgspp - ggs*vgs - ggspp*vgspp; + cdreq=((cd+cgd+cgdpp)-gds*vds-gm*vgs); + *(ckt->CKTrhs + here->MESAgatePrimeNode) += (-ceqgs-ceqgd); + ceqgd = (cgd-ggd*vgd); + *(ckt->CKTrhs + here->MESAdrainPrimeNode) += (-cdreq+ceqgd+ccorr); + ceqgd = (cgdpp-ggdpp*vgdpp); + *(ckt->CKTrhs + here->MESAdrainPrmPrmNode) += ceqgd; + ceqgs = (cgs-ggs*vgs); + *(ckt->CKTrhs + here->MESAsourcePrimeNode) += (cdreq+ceqgs-ccorr); + ceqgs = (cgspp-ggspp*vgspp); + *(ckt->CKTrhs + here->MESAsourcePrmPrmNode) += ceqgs; + + /* + * load y matrix + */ + *(here->MESAdrainDrainPtr) += here->MESAdrainConduct; + *(here->MESAsourceSourcePtr) += here->MESAsourceConduct; + *(here->MESAgateGatePtr) += here->MESAgateConduct; + *(here->MESAsourcePrmPrmSourcePrmPrmPtr) += (here->MESAtGi+ggspp); + *(here->MESAdrainPrmPrmDrainPrmPrmPtr) += (here->MESAtGf+ggdpp); + *(here->MESAgatePrimeGatePrimePtr) += (ggd+ggs+here->MESAgateConduct+ggspp+ggdpp); + *(here->MESAdrainPrimeDrainPrimePtr) += (gds+ggd+here->MESAdrainConduct+here->MESAtGf); + *(here->MESAsourcePrimeSourcePrimePtr) += (gds+gm+ggs+here->MESAsourceConduct+here->MESAtGi); + *(here->MESAdrainDrainPrimePtr) -= here->MESAdrainConduct; + *(here->MESAdrainPrimeDrainPtr) -= here->MESAdrainConduct; + *(here->MESAsourceSourcePrimePtr) -= here->MESAsourceConduct; + *(here->MESAsourcePrimeSourcePtr) -= here->MESAsourceConduct; + *(here->MESAgateGatePrimePtr) -= here->MESAgateConduct; + *(here->MESAgatePrimeGatePtr) -= here->MESAgateConduct; + *(here->MESAgatePrimeDrainPrimePtr) -= ggd; + *(here->MESAgatePrimeSourcePrimePtr) -= ggs; + *(here->MESAdrainPrimeGatePrimePtr) += (gm-ggd); + *(here->MESAdrainPrimeSourcePrimePtr) += (-gds-gm); + *(here->MESAsourcePrimeGatePrimePtr) += (-ggs-gm); + *(here->MESAsourcePrimeDrainPrimePtr) -= gds; + *(here->MESAsourcePrimeSourcePrmPrmPtr) -= here->MESAtGi; + *(here->MESAsourcePrmPrmSourcePrimePtr) -= here->MESAtGi; + *(here->MESAgatePrimeSourcePrmPrmPtr) -= ggspp; + *(here->MESAsourcePrmPrmGatePrimePtr) -= ggspp; + *(here->MESAdrainPrimeDrainPrmPrmPtr) -= here->MESAtGf; + *(here->MESAdrainPrmPrmDrainPrimePtr) -= here->MESAtGf; + *(here->MESAgatePrimeDrainPrmPrmPtr) -= ggdpp; + *(here->MESAdrainPrmPrmGatePrimePtr) -= ggdpp; + } + } + return(OK); +} + + +#define ETA (here->MESAtEta) +#define MU0 (here->MESAtMu) +#define RS (here->MESAtRsi) +#define RD (here->MESAtRdi) +#define SIGMA0 (model->MESAsigma0) +#define VSIGMAT (model->MESAvsigmat) +#define VSIGMA (model->MESAvsigma) +#define THETA (model->MESAtheta) +#define VS (model->MESAvs) +#define ND (model->MESAnd) +#define D (model->MESAd) +#define TC (model->MESAtc) +#define MC (model->MESAmc) +#define M0 (model->MESAm) +#define ALPHA (model->MESAalpha) +#define LAMBDA (here->MESAtLambda) +#define NDELTA (model->MESAndelta) +#define TH (model->MESAth) +#define NDU (model->MESAndu) +#define DU (model->MESAdu) +#define NMAX (model->MESAnmax) +#define GAMMA (model->MESAgamma) + + +static void mesa1(MESAmodel *model, MESAinstance *here, double vgs, + double vds, double von, double *cdrain, + double *gm, double *gds, double *capgs, double *capgd) + +{ + + double vt; + double etavth; + double vl; + double rt; + double mu; + double beta; + double vgt; + double vgt0; + double sigma; + double vgte; + double isat; + double isata; + double isatb; + double ns; + double a; + double b; + double c; + double d; + double e; + double f; + double g; + double h; + double m; + double p; + double q; + double r; + double s; + double t; + double u; + double v; + double w; + double temp; + double gch; + double gchi; + double vsate; + double vdse; + double cgc; + double sqrt1; + double delidgch; + double delgchgchi; + double delgchins; + double delnsvgt; + double delnsvgte; + double delvgtevgt; + double delidvsate; + double delvsateisat; + double delisatisata; + double delisatavgte; + double delisatabeta; + double delisatisatb; + double delvsategch; + double delidvds; + double ddevgte; + double dvgtvgs; + double dgchivgt; + double dvgtevds; + double dgchivds; + double disatavgt; + double disatavds; + double disatbvgt; + double dvsatevgt; + double dvsatevds; + double gmmadd; + double gdsmadd; + + + vt = CONSTKoverQ * here->MESAts; + etavth = ETA*vt; + rt = RS+RD; + vgt0 = vgs - von; + s = exp((vgt0-VSIGMAT)/VSIGMA); + sigma = SIGMA0/(1+s); + vgt = vgt0+sigma*vds; + mu = MU0+THETA*vgt; + vl = VS/mu*here->MESAlength; + beta = here->MESAbeta/(model->MESAvpo+3*vl); + u = vgt/vt-1; + t = sqrt(model->MESAdeltaSqr+u*u); + vgte = 0.5*vt*(2+u+t); + a = 2*beta*vgte; + b = exp(-vgt/etavth); + if(vgte > model->MESAvpo) + sqrt1 = 0; + else + sqrt1 = sqrt(1-vgte/model->MESAvpo); + ns = 1.0/(1.0/ND/D/(1-sqrt1) + 1.0/here->MESAn0*b); + if(ns < 1.0e-38) { + *cdrain = 0; + *gm = 0.0; + *gds = 0.0; + *capgs = here->MESAcf; + *capgd = here->MESAcf; + return; + } + gchi = here->MESAgchi0*mu*ns; + gch = gchi/(1+gchi*rt); + f = sqrt(1+2*a*RS); + d = 1+a*RS + f; + e = 1+TC*vgte; + isata = a*vgte/(d*e); + isatb = here->MESAisatb0*mu*exp(vgt/etavth); + isat = isata*isatb/(isata+isatb); + vsate = isat/gch; + vdse = vds*pow(1+pow(vds/vsate,MC),-1.0/MC); + m = M0+ALPHA*vgte; + g = pow(vds/vsate,m); + h = pow(1+g,1.0/m); + here->MESAdelidgch0 = vds/h; + delidgch = here->MESAdelidgch0*(1+LAMBDA*vds); + *cdrain = gch*delidgch; + if(vgt > model->MESAvpo) + temp = 0; + else + temp = sqrt(1-vgt/model->MESAvpo); + cgc = W*L*EPSILONGAAS/(temp+b)/D; + c = (vsate-vdse)/(2*vsate-vdse); + c = c*c; + *capgs = here->MESAcf+2.0/3.0*cgc*(1-c); + c = vsate/(2*vsate-vdse); + c = c*c; + *capgd = here->MESAcf+2.0/3.0*cgc*(1-c); + temp = 1+gchi*rt; + delgchgchi = 1.0/(temp*temp); + delgchins = here->MESAgchi0*mu; + delnsvgt = ns*ns*1.0/here->MESAn0/etavth*b; + q = 1 - sqrt1; + if(sqrt1 == 0) + delnsvgte = 0; + else + delnsvgte = 0.5*ns*ns/(model->MESAvpo*ND*D*sqrt1*q*q); + delvgtevgt = 0.5*(1+u/t); + here->MESAdelidvds0 = gch/h; + if(vds != 0.0) + here->MESAdelidvds1 = (*cdrain)*pow(vds/vsate,m-1)/(vsate*(1+g)); + else + here->MESAdelidvds1 = 0.0; + delidvds = here->MESAdelidvds0*(1+2*LAMBDA*vds) - here->MESAdelidvds1; + delidvsate = (*cdrain)*g/(vsate*(1+g)); + delvsateisat = 1.0/gch; + r = isata+isatb; + r = r*r; + delisatisata = isatb*isatb/r; + v = 1.0+1.0/f; + ddevgte = 2*beta*RS*v*e+d*TC; + temp = d*d*e*e; + delisatavgte = (2*a*d*e - a*vgte*ddevgte)/temp; + delisatabeta = 2*vgte*vgte*(d*e-a*e*RS*v)/temp; + delisatisatb = isata*isata/r; + delvsategch = -vsate/gch; + dvgtvgs = 1 - SIGMA0*vds*s/VSIGMA/((1+s)*(1+s)); + temp = here->MESAgchi0*ns*THETA; + dgchivgt = delgchins*(delnsvgte*delvgtevgt+delnsvgt)+temp; + dvgtevds = delvgtevgt*sigma; + dgchivds = delgchins*(delnsvgte*dvgtevds+delnsvgt*sigma)+temp*sigma; + temp = delisatabeta*3*beta*vl*THETA/(mu*(model->MESAvpo+3*vl)); + disatavgt = delisatavgte*delvgtevgt+temp; + disatavds = delisatavgte*dvgtevds+temp*sigma; + disatbvgt = isatb/etavth+isatb/mu*THETA; + p = delgchgchi*dgchivgt; + w = delgchgchi*dgchivds; + dvsatevgt = delvsateisat*(delisatisata*disatavgt+delisatisatb*disatbvgt)+delvsategch*p; + dvsatevds = delvsateisat*(delisatisata*disatavds+delisatisatb*disatbvgt*sigma)+delvsategch*w; + if(ALPHA != 0) { + if(vds == 0) + gmmadd = 0; + else + gmmadd = (*cdrain)*(log(1+g)/(m*m)-g*log(vds/vsate)/(m*(1+g)))* + ALPHA*delvgtevgt; + gdsmadd = gmmadd*sigma; + } else { + gmmadd = 0; + gdsmadd = 0; + } + here->MESAgm0 = p; + here->MESAgm1 = delidvsate*dvsatevgt; + here->MESAgm2 = dvgtvgs; + g = delidgch*p+here->MESAgm1; + *gm = (g+gmmadd)*dvgtvgs; + here->MESAgds0 = delidvsate*dvsatevds+delidgch*w+gdsmadd; + *gds = delidvds+here->MESAgds0; + +} + + + +static void mesa2(MESAmodel *model, MESAinstance *here, double vgs, + double vds, double von, double *cdrain, double *gm, + double *gds, double *capgs, double *capgd) + +{ + + double vt; + double rt; + double vgt; + double etavth; + double vgt0; + double sigma; + double vgte; + double isat; + double isata; + double isatb; + double nsa; + double nsb; + double ns; + double a; + double b; + double c; + double d; + double e; + double f; + double g; + double h; + double p; + double q; + double r; + double s; + double t; + double gch; + double gchi; + double vsate; + double vdse; + double ca; + double cb; + double cgc; + double delidgch; + double delgchgchi; + double delgchins; + double delnsvgt; + double delnsbvgt; + double delnsavgte; + double delvgtevgt; + double delidvsate; + double delvsateisat; + double delisatisata; + double delisatavgte; + double delisatisatb; + double delvsategch; + double delisatbvgt; + double delvsatevgt; + double delidvds; + double ddevgte; + double delvgtvgs; + + + vt = CONSTKoverQ * here->MESAts; + etavth = ETA*vt; + rt = RS+RD; + vgt0 = vgs - von; + s = exp((vgt0-VSIGMAT)/VSIGMA); + sigma = SIGMA0/(1+s); + vgt = vgt0+sigma*vds; + t = vgt/vt-1; + q = sqrt(model->MESAdeltaSqr+t*t); + vgte = 0.5*vt*(2+t+q); + a = 2*model->MESAbeta*vgte; + if(vgt > model->MESAvpod) { + if(vgte > model->MESAvpo) { + nsa = NDELTA*TH + NDU*DU; + ca = EPSILONGAAS/DU; + delnsavgte = 0; + } else { + r = sqrt((model->MESAvpo-vgte)/model->MESAvpou); + nsa = NDELTA*TH + NDU*DU*(1-r); + ca = EPSILONGAAS/DU/r; + delnsavgte = NDU*DU/model->MESAvpou/2.0/r; + } + } else { + if(model->MESAvpod - vgte < 0) { + nsa = NDELTA*TH*(1-DU/TH); + ca = EPSILONGAAS/DU; + delnsavgte = 0; + } else { + r = sqrt(1+NDU/NDELTA*(model->MESAvpod - vgte)/model->MESAvpou); + nsa = NDELTA*TH*(1-DU/TH*(r-1)); + ca = EPSILONGAAS/DU/r; + delnsavgte = DU*NDU/2.0/model->MESAvpou/r; + } + } + b = exp(vgt/etavth); + cb = EPSILONGAAS/(DU+TH)*b; + nsb = here->MESAnsb0*b; + delnsbvgt = nsb/etavth; + ns = nsa*nsb/(nsa+nsb); + if(ns < 1.0e-38) { + *cdrain = 0; + *gm = 0.0; + *gds = 0.0; + *capgs = here->MESAcf; + *capgd = here->MESAcf; + return; + } + gchi = here->MESAgchi0*ns; + gch = gchi/(1+gchi*rt); + f = sqrt(1+2*a*RS); + d = 1+a*RS + f; + e = 1+TC*vgte; + isata = a*vgte/d/e; + isatb = here->MESAisatb0*b; + isat = isata*isatb/(isata+isatb); + vsate = isat/gch; + vdse = vds*pow(1+pow(vds/vsate,MC),-1.0/MC); + g = pow(vds/vsate,M0); + h = pow(1+g,1.0/M0); + here->MESAdelidgch0 = vds/h; + delidgch = here->MESAdelidgch0*(1+LAMBDA*vds); + *cdrain = gch*delidgch; + cgc = W*L*ca*cb/(ca+cb); + c = (vsate-vdse)/(2*vsate-vdse); + c = c*c; + *capgs = here->MESAcf+2.0/3.0*cgc*(1-c); + c = vsate/(2*vsate-vdse); + c = c*c; + *capgd = here->MESAcf+2.0/3.0*cgc*(1-c); + c = vgt/vt-1; + delvgtevgt = 0.5*(1+t/q); + here->MESAdelidvds0 = gch/h; + if(vds != 0.0) + here->MESAdelidvds1 = (*cdrain)*pow(vds/vsate,M0-1)/vsate/(1+g); + else + here->MESAdelidvds1 = 0.0; + delidvds = here->MESAdelidvds0*(1+2*LAMBDA*vds) - + here->MESAdelidvds1; + delgchgchi = 1.0/(1+gchi*rt)/(1+gchi*rt); + delgchins = here->MESAgchi0; + r = nsa+nsb; + r = r*r; + delnsvgt = (nsb*nsb*delvgtevgt*delnsavgte + nsa*nsa*delnsbvgt)/r; + delidvsate = (*cdrain)*g/vsate/(1+g); + delvsateisat = 1.0/gch; + r = isata+isatb; + r = r*r; + delisatisata = isatb*isatb/r; + ddevgte = 2*model->MESAbeta*RS*(1+1.0/f)*e+d*TC; + delisatavgte = (2*a*d*e - a*vgte*ddevgte)/d/d/e/e; + delisatisatb = isata*isata/r; + delisatbvgt = isatb/etavth; + delvsategch = -vsate/gch; + delvgtvgs = 1-SIGMA0*vds*s/VSIGMA/(1+s)/(1+s); + p = delgchgchi*delgchins*delnsvgt; + delvsatevgt = delvsateisat*(delisatisata*delisatavgte*delvgtevgt + + delisatisatb*delisatbvgt) + delvsategch*p; + here->MESAgm0 = p; + here->MESAgm1 = delidvsate*delvsatevgt; + here->MESAgm2 = delvgtvgs; + g = delidgch*p + here->MESAgm1; + *gm = g*delvgtvgs; + here->MESAgds0 = g*sigma; + *gds = delidvds+here->MESAgds0; + +} + + + +static void mesa3(MESAmodel *model, MESAinstance *here, double vgs, + double vds, double von, double *cdrain, double *gm, + double *gds, double *capgs, double *capgd) + +{ + + double vt; + double vgt; + double vgt0; + double sigma; + double vgte; + double isat; + double isatm; + double ns; + double nsm; + double a; + double b; + double c; + double d; + double e; + double g; + double h; + double p; + double q; + double s; + double t; + double u; + double temp; + double etavth; + double gch; + double gchi; + double gchim; + double vsate; + double vdse; + double cgc; + double cgcm; + double rt; + double vl; + double delidgch; + double delgchgchi; + double delgchins; + double delnsnsm; + double delnsmvgt; + double delvgtevgt; + double delidvsate; + double delvsateisat; + double delisatisatm; + double delisatmvgte; + double delisatmgchim; + double delvsategch; + double delidvds; + double delvgtvgs; + double delvsatevgt; + + vt = CONSTKoverQ * here->MESAts; + etavth = ETA*vt; + vl = VS/MU0*L; + rt = RS+RD; + vgt0 = vgs - von; + s = exp((vgt0-VSIGMAT)/VSIGMA); + sigma = SIGMA0/(1+s); + vgt = vgt0+sigma*vds; + u = 0.5*vgt/vt-1; + t = sqrt(model->MESAdeltaSqr+u*u); + vgte = vt*(2+u+t); + b = exp(vgt/etavth); + nsm = 2*here->MESAn0*log(1+0.5*b); + if(nsm < 1.0e-38) { + *cdrain = 0; + *gm = 0.0; + *gds = 0.0; + *capgs = here->MESAcf; + *capgd = here->MESAcf; + return; + } + c = pow(nsm/NMAX,GAMMA); + q = pow(1+c,1.0/GAMMA); + ns = nsm/q; + gchi = here->MESAgchi0*ns; + gch = gchi/(1+gchi*rt); + gchim = here->MESAgchi0*nsm; + h = sqrt(1+2*gchim*model->MESArsi + vgte*vgte/(vl*vl)); + p = 1+gchim*RS+h; + isatm = gchim*vgte/p; + g = pow(isatm/here->MESAimax,GAMMA); + isat = isatm/pow(1+g,1/GAMMA); + vsate = isat/gch; + vdse = vds*pow(1+pow(vds/vsate,MC),-1.0/MC); + d = pow(vds/vsate,M0); + e = pow(1+d,1.0/M0); + delidgch = vds*(1+LAMBDA*vds)/e; + *cdrain = gch*delidgch; + cgcm = 1.0/(1/model->MESAcas*D/model->MESAepsi + + 1/model->MESAcbs*etavth/CHARGE/here->MESAn0*exp(-vgt/etavth)); + cgc = W*L*cgcm/pow(1+c,1+1.0/GAMMA); +/* + { + char buf[256]; + void far pascal OutputDebugString(char*); + sprintf(buf,"\n%f\t%e\0",vgs,cgc); + OutputDebugString(buf); + } +*/ + a = (vsate-vdse)/(2*vsate-vdse); + a = a*a; + temp = 2.0/3.0; + *capgs = here->MESAcf+temp*cgc*(1-a); + a = vsate/(2*vsate-vdse); + a = a*a; + *capgd = here->MESAcf+temp*cgc*(1-a); + delidvsate = (*cdrain)*d/vsate/(1+d); + delidvds = gch*(1+2*LAMBDA*vds)/e-(*cdrain)* + pow(vds/vsate,M0-1)/(vsate*(1+d)); + a = 1+gchi*rt; + delgchgchi = 1.0/(a*a); + delgchins = here->MESAgchi0; + delnsnsm = ns/nsm*(1-c/(1+c)); + delnsmvgt = here->MESAn0/etavth/(1.0/b + 0.5); + delvgtevgt = 0.5*(1+u/t); + delvsateisat = 1.0/gch; + delisatisatm = isat/isatm*(1-g/(1+g)); + delisatmvgte = gchim*(p - vgte*vgte/(vl*vl*h))/(p*p); + delvsategch = -vsate/gch; + delisatmgchim = vgte*(p - gchim*RS*(1+1.0/h))/(p*p); + delvgtvgs = 1-vds*SIGMA0/VSIGMA*s/((1+s)*(1+s)); + p = delgchgchi*delgchins*delnsnsm*delnsmvgt; + delvsatevgt = (delvsateisat*delisatisatm*(delisatmvgte*delvgtevgt + + delisatmgchim*here->MESAgchi0*delnsmvgt)+delvsategch*p); + g = delidgch*p + delidvsate*delvsatevgt; + *gm = g*delvgtvgs; + *gds = delidvds + g*sigma; + +} diff --git a/src/spicelib/devices/mesa/mesamask.c b/src/spicelib/devices/mesa/mesamask.c new file mode 100644 index 000000000..85e9d2809 --- /dev/null +++ b/src/spicelib/devices/mesa/mesamask.c @@ -0,0 +1,223 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Thomas L. Quarles +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "devdefs.h" +#include "ifsim.h" +#include "mesadefs.h" +#include "sperror.h" +#include "suffix.h" + + +/* ARGSUSED */ +int +MESAmAsk(ckt,inst,which,value) + CKTcircuit *ckt; + GENmodel *inst; + int which; + IFvalue *value; +{ + MESAmodel *here = (MESAmodel*)inst; + switch(which) { + case MESA_MOD_VTO: + value->rValue = here->MESAthreshold; + return (OK); + case MESA_MOD_VS: + value->rValue = here->MESAvs; + return (OK); + case MESA_MOD_ALPHA: + value->rValue = here->MESAalpha; + return (OK); + case MESA_MOD_BETA: + value->rValue = here->MESAbeta; + return (OK); + case MESA_MOD_LAMBDA: + value->rValue = here->MESAlambda; + return (OK); + case MESA_MOD_RG: + value->rValue = here->MESAgateResist; + return (OK); + case MESA_MOD_RD: + value->rValue = here->MESAdrainResist; + return (OK); + case MESA_MOD_RS: + value->rValue = here->MESAsourceResist; + return (OK); + case MESA_MOD_RI: + value->rValue = here->MESAri; + return (OK); + case MESA_MOD_RF: + value->rValue = here->MESArf; + return (OK); + case MESA_MOD_RDI: + value->rValue = here->MESArdi; + return (OK); + case MESA_MOD_RSI: + value->rValue = here->MESArsi; + return (OK); + case MESA_MOD_PHIB: + value->rValue = here->MESAphib; + return (OK); + case MESA_MOD_PHIB1: + value->rValue = here->MESAphib1; + return (OK); + case MESA_MOD_ASTAR: + value->rValue = here->MESAastar; + return (OK); + case MESA_MOD_GGR: + value->rValue = here->MESAggr; + return (OK); + case MESA_MOD_DEL: + value->rValue = here->MESAdel; + return (OK); + case MESA_MOD_XCHI: + value->rValue = here->MESAxchi; + return (OK); + case MESA_MOD_N: + value->rValue = here->MESAn; + return (OK); + case MESA_MOD_ETA: + value->rValue = here->MESAeta; + return (OK); + case MESA_MOD_M: + value->rValue = here->MESAm; + return (OK); + case MESA_MOD_MC: + value->rValue = here->MESAmc; + return (OK); + case MESA_MOD_SIGMA0: + value->rValue = here->MESAsigma0; + return (OK); + case MESA_MOD_VSIGMAT: + value->rValue = here->MESAvsigmat; + return (OK); + case MESA_MOD_VSIGMA: + value->rValue = here->MESAvsigma; + return (OK); + case MESA_MOD_MU: + value->rValue = here->MESAmu; + return (OK); + case MESA_MOD_MU1: + value->rValue = here->MESAmu1; + return (OK); + case MESA_MOD_MU2: + value->rValue = here->MESAmu2; + return (OK); + case MESA_MOD_D: + value->rValue = here->MESAd; + return (OK); + case MESA_MOD_ND: + value->rValue = here->MESAnd; + return (OK); + case MESA_MOD_DELTA: + value->rValue = here->MESAdelta; + return (OK); + case MESA_MOD_TC: + value->rValue = here->MESAtc; + return (OK); + case MESA_MOD_TVTO: + value->rValue = here->MESAtvto; + return (OK); + case MESA_MOD_TLAMBDA: + value->rValue = here->MESAtlambda; + return (OK); + case MESA_MOD_TETA0: + value->rValue = here->MESAteta0; + return (OK); + case MESA_MOD_TETA1: + value->rValue = here->MESAteta1; + return (OK); + case MESA_MOD_TMU: + value->rValue = here->MESAtmu; + return (OK); + case MESA_MOD_XTM0: + value->rValue = here->MESAxtm0; + return (OK); + case MESA_MOD_XTM1: + value->rValue = here->MESAxtm1; + return (OK); + case MESA_MOD_XTM2: + value->rValue = here->MESAxtm2; + return (OK); + case MESA_MOD_KS: + value->rValue = here->MESAks; + return (OK); + case MESA_MOD_VSG: + value->rValue = here->MESAvsg; + return (OK); + case MESA_MOD_LAMBDAHF: + value->rValue = here->MESAlambdahf; + return (OK); + case MESA_MOD_TF: + value->rValue = here->MESAtf; + return (OK); + case MESA_MOD_FLO: + value->rValue = here->MESAflo; + return (OK); + case MESA_MOD_DELFO: + value->rValue = here->MESAdelfo; + return (OK); + case MESA_MOD_AG: + value->rValue = here->MESAag; + return (OK); + case MESA_MOD_THETA: + value->rValue = here->MESAtheta; + return (OK); + case MESA_MOD_TC1: + value->rValue = here->MESAtc1; + return (OK); + case MESA_MOD_TC2: + value->rValue = here->MESAtc2; + return (OK); + case MESA_MOD_ZETA: + value->rValue = here->MESAzeta; + return (OK); + case MESA_MOD_DU: + value->rValue = here->MESAdu; + return (OK); + + + + case MESA_MOD_NDU: + value->rValue = here->MESAndu; + return (OK); + case MESA_MOD_TH: + value->rValue = here->MESAth; + return (OK); + case MESA_MOD_NDELTA: + value->rValue = here->MESAndelta; + return (OK); + case MESA_MOD_LEVEL: + value->rValue = here->MESAlevel; + return (OK); + case MESA_MOD_NMAX: + value->rValue = here->MESAnmax; + return (OK); + case MESA_MOD_GAMMA: + value->rValue = here->MESAgamma; + return (OK); + case MESA_MOD_EPSI: + value->rValue = here->MESAepsi; + return (OK); + case MESA_MOD_CBS: + value->rValue = here->MESAcbs; + return (OK); + case MESA_MOD_CAS: + value->rValue = here->MESAcas; + return (OK); + case MESA_MOD_TYPE: + if (here->MESAtype == NMF) + value->sValue = "nmf"; + else + value->sValue = "pmf"; + default: + return (E_BADPARM); + } + /* NOTREACHED */ +} diff --git a/src/spicelib/devices/mesa/mesamdel.c b/src/spicelib/devices/mesa/mesamdel.c new file mode 100644 index 000000000..e5cbdf136 --- /dev/null +++ b/src/spicelib/devices/mesa/mesamdel.c @@ -0,0 +1,45 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 S. Hwang +**********/ +/* + Imported into mesa model: 2001 Paolo Nenzi + */ + +#include "ngspice.h" +#include +#include "mesadefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +MESAmDelete(inModel,modname,kill) + GENmodel **inModel; + IFuid modname; + GENmodel *kill; +{ + MESAmodel **model = (MESAmodel**)inModel; + MESAmodel *modfast = (MESAmodel*)kill; + MESAinstance *here; + MESAinstance *prev = NULL; + MESAmodel **oldmod; + oldmod = model; + for( ; *model ; model = &((*model)->MESAnextModel)) { + if( (*model)->MESAmodName == modname || + (modfast && *model == modfast) ) goto delgot; + oldmod = model; + } + return(E_NOMOD); + +delgot: + *oldmod = (*model)->MESAnextModel; /* cut deleted device out of list */ + for(here = (*model)->MESAinstances ; here ; here = here->MESAnextInstance) { + if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + FREE(*model); + return(OK); + +} diff --git a/src/spicelib/devices/mesa/mesamparam.c b/src/spicelib/devices/mesa/mesamparam.c new file mode 100644 index 000000000..1a13a328c --- /dev/null +++ b/src/spicelib/devices/mesa/mesamparam.c @@ -0,0 +1,273 @@ +/********** +Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. +Author: Trond Ytterdal +**********/ + +#include "ngspice.h" +#include +#include "const.h" +#include "ifsim.h" +#include "mesadefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +MESAmParam(param,value,inModel) + int param; + IFvalue *value; + GENmodel *inModel; +{ + MESAmodel *model = (MESAmodel*)inModel; + switch(param) { + case MESA_MOD_VTO: + model->MESAthresholdGiven = TRUE; + model->MESAthreshold = value->rValue; + break; + case MESA_MOD_BETA: + model->MESAbetaGiven = TRUE; + model->MESAbeta = value->rValue; + break; + case MESA_MOD_VS: + model->MESAvsGiven = TRUE; + model->MESAvs = value->rValue; + break; + case MESA_MOD_LAMBDA: + model->MESAlambdaGiven = TRUE; + model->MESAlambda = value->rValue; + break; + case MESA_MOD_RD: + model->MESAdrainResistGiven = TRUE; + model->MESAdrainResist = value->rValue; + break; + case MESA_MOD_RS: + model->MESAsourceResistGiven = TRUE; + model->MESAsourceResist = value->rValue; + break; + case MESA_MOD_RG: + model->MESAgateResistGiven = TRUE; + model->MESAgateResist = value->rValue; + break; + case MESA_MOD_RI: + model->MESAriGiven = TRUE; + model->MESAri = value->rValue; + break; + case MESA_MOD_RF: + model->MESArfGiven = TRUE; + model->MESArf = value->rValue; + break; + case MESA_MOD_RDI: + model->MESArdiGiven = TRUE; + model->MESArdi = value->rValue; + break; + case MESA_MOD_RSI: + model->MESArsiGiven = TRUE; + model->MESArsi = value->rValue; + break; + case MESA_MOD_PHIB: + model->MESAphibGiven = TRUE; + model->MESAphib = value->rValue*CHARGE; + break; + case MESA_MOD_PHIB1: + model->MESAphib1Given = TRUE; + model->MESAphib1 = value->rValue*CHARGE; + break; + case MESA_MOD_ASTAR: + model->MESAastarGiven = TRUE; + model->MESAastar = value->rValue; + break; + case MESA_MOD_GGR: + model->MESAggrGiven = TRUE; + model->MESAggr = value->rValue; + break; + case MESA_MOD_DEL: + model->MESAdelGiven = TRUE; + model->MESAdel = value->rValue; + break; + case MESA_MOD_XCHI: + model->MESAxchiGiven = TRUE; + model->MESAxchi = value->rValue; + break; + case MESA_MOD_N: + model->MESAnGiven = TRUE; + model->MESAn = value->rValue; + break; + case MESA_MOD_ETA: + model->MESAetaGiven = TRUE; + model->MESAeta = value->rValue; + break; + case MESA_MOD_M: + model->MESAmGiven = TRUE; + model->MESAm = value->rValue; + break; + case MESA_MOD_MC: + model->MESAmcGiven = TRUE; + model->MESAmc = value->rValue; + break; + case MESA_MOD_ALPHA: + model->MESAalphaGiven = TRUE; + model->MESAalpha = value->rValue; + break; + case MESA_MOD_SIGMA0: + model->MESAsigma0Given = TRUE; + model->MESAsigma0 = value->rValue; + break; + case MESA_MOD_VSIGMAT: + model->MESAvsigmatGiven = TRUE; + model->MESAvsigmat = value->rValue; + break; + case MESA_MOD_VSIGMA: + model->MESAvsigmaGiven = TRUE; + model->MESAvsigma = value->rValue; + break; + case MESA_MOD_MU: + model->MESAmuGiven = TRUE; + model->MESAmu = value->rValue; + break; + case MESA_MOD_THETA: + model->MESAthetaGiven = TRUE; + model->MESAtheta = value->rValue; + break; + case MESA_MOD_MU1: + model->MESAmu1Given = TRUE; + model->MESAmu1 = value->rValue; + break; + case MESA_MOD_MU2: + model->MESAmu2Given = TRUE; + model->MESAmu2 = value->rValue; + break; + case MESA_MOD_D: + model->MESAdGiven = TRUE; + model->MESAd = value->rValue; + break; + case MESA_MOD_ND: + model->MESAndGiven = TRUE; + model->MESAnd = value->rValue; + break; + case MESA_MOD_DU: + model->MESAduGiven = TRUE; + model->MESAdu = value->rValue; + break; + case MESA_MOD_NDU: + model->MESAnduGiven = TRUE; + model->MESAndu = value->rValue; + break; + case MESA_MOD_TH: + model->MESAthGiven = TRUE; + model->MESAth = value->rValue; + break; + case MESA_MOD_NDELTA: + model->MESAndeltaGiven = TRUE; + model->MESAndelta = value->rValue; + break; + case MESA_MOD_DELTA: + model->MESAdeltaGiven = TRUE; + model->MESAdelta = value->rValue; + break; + case MESA_MOD_TC: + model->MESAtcGiven = TRUE; + model->MESAtc = value->rValue; + break; + case MESA_MOD_NMF: + break; + case MESA_MOD_TVTO: + model->MESAtvtoGiven = TRUE; + model->MESAtvto = value->rValue; + break; + case MESA_MOD_TLAMBDA: + model->MESAtlambdaGiven = TRUE; + model->MESAtlambda = value->rValue+CONSTCtoK; + break; + case MESA_MOD_TETA0: + model->MESAteta0Given = TRUE; + model->MESAteta0 = value->rValue+CONSTCtoK; + break; + case MESA_MOD_TETA1: + model->MESAteta1Given = TRUE; + model->MESAteta1 = value->rValue+CONSTCtoK; + break; + case MESA_MOD_TMU: + model->MESAtmuGiven = TRUE; + model->MESAtmu = value->rValue+CONSTCtoK; + break; + case MESA_MOD_XTM0: + model->MESAxtm0Given = TRUE; + model->MESAxtm0 = value->rValue; + break; + case MESA_MOD_XTM1: + model->MESAxtm1Given = TRUE; + model->MESAxtm1 = value->rValue; + break; + case MESA_MOD_XTM2: + model->MESAxtm2Given = TRUE; + model->MESAxtm2 = value->rValue; + break; + case MESA_MOD_KS: + model->MESAksGiven = TRUE; + model->MESAks = value->rValue; + break; + case MESA_MOD_VSG: + model->MESAvsgGiven = TRUE; + model->MESAvsg = value->rValue; + break; + case MESA_MOD_LAMBDAHF: + model->MESAlambdahfGiven = TRUE; + model->MESAlambdahf = value->rValue; + break; + case MESA_MOD_TF: + model->MESAtfGiven = TRUE; + model->MESAtf = value->rValue+CONSTCtoK; + break; + case MESA_MOD_FLO: + model->MESAfloGiven = TRUE; + model->MESAflo = value->rValue; + break; + case MESA_MOD_DELFO: + model->MESAdelfoGiven = TRUE; + model->MESAdelfo = value->rValue; + break; + case MESA_MOD_AG: + model->MESAagGiven = TRUE; + model->MESAag = value->rValue; + break; + case MESA_MOD_TC1: + model->MESAtc1Given = TRUE; + model->MESAtc1 = value->rValue; + break; + case MESA_MOD_TC2: + model->MESAtc2Given = TRUE; + model->MESAtc2 = value->rValue; + break; + case MESA_MOD_ZETA: + model->MESAzetaGiven = TRUE; + model->MESAzeta = value->rValue; + break; + case MESA_MOD_LEVEL: + model->MESAlevelGiven = TRUE; + model->MESAlevel = value->rValue; + break; + case MESA_MOD_NMAX: + model->MESAnmaxGiven = TRUE; + model->MESAnmax = value->rValue; + break; + case MESA_MOD_GAMMA: + model->MESAgammaGiven = TRUE; + model->MESAgamma = value->rValue; + break; + case MESA_MOD_EPSI: + model->MESAepsiGiven = TRUE; + model->MESAepsi = value->rValue; + break; + case MESA_MOD_CBS: + model->MESAcbsGiven = TRUE; + model->MESAcbs = value->rValue; + break; + case MESA_MOD_CAS: + model->MESAcasGiven = TRUE; + model->MESAcas = value->rValue; + break; + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/mesa/mesaparam.c b/src/spicelib/devices/mesa/mesaparam.c new file mode 100644 index 000000000..87e8aa2d8 --- /dev/null +++ b/src/spicelib/devices/mesa/mesaparam.c @@ -0,0 +1,69 @@ +/********** +Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. +Author: Trond Ytterdal +**********/ + +#include "ngspice.h" +#include +#include "const.h" +#include "ifsim.h" +#include "mesadefs.h" +#include "sperror.h" +#include "suffix.h" + + +/* ARGSUSED */ +int +MESAparam(param,value,inst,select) + int param; + IFvalue *value; + GENinstance *inst; + IFvalue *select; +{ + MESAinstance *here = (MESAinstance*)inst; + switch(param) { + case MESA_LENGTH: + here->MESAlength = value->rValue; + here->MESAlengthGiven = TRUE; + break; + case MESA_WIDTH: + here->MESAwidth = value->rValue; + here->MESAwidthGiven = TRUE; + break; + case MESA_IC_VDS: + here->MESAicVDS = value->rValue; + here->MESAicVDSGiven = TRUE; + break; + case MESA_IC_VGS: + here->MESAicVGS = value->rValue; + here->MESAicVGSGiven = TRUE; + break; + case MESA_OFF: + here->MESAoff = value->iValue; + break; + case MESA_IC: + switch(value->v.numValue) { + case 2: + here->MESAicVGS = *(value->v.vec.rVec+1); + here->MESAicVGSGiven = TRUE; + case 1: + here->MESAicVDS = *(value->v.vec.rVec); + here->MESAicVDSGiven = TRUE; + break; + default: + return(E_BADPARM); + } + break; + case MESA_TD: + here->MESAtd = value->rValue+CONSTCtoK; + here->MESAtdGiven = TRUE; + break; + case MESA_TS: + here->MESAts = value->rValue+CONSTCtoK; + here->MESAtsGiven = TRUE; + break; + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/mesa/mesasetup.c b/src/spicelib/devices/mesa/mesasetup.c new file mode 100644 index 000000000..3a9d6c799 --- /dev/null +++ b/src/spicelib/devices/mesa/mesasetup.c @@ -0,0 +1,417 @@ +/********** +Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. +Author: Trond Ytterdal +Modified: 2001 AlansFixes +**********/ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "mesadefs.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + + +int +MESAsetup(matrix,inModel,ckt,states) + register SMPmatrix *matrix; + register GENmodel *inModel; + register CKTcircuit *ckt; + int *states; + + /* load the diode structure with those pointers needed later + * for fast matrix loading + */ +{ + register MESAmodel *model = (MESAmodel*)inModel; + register MESAinstance *here; + int error; + CKTnode *tmp; + + + /* loop through all the diode models */ + for( ; model != NULL; model = model->MESAnextModel ) { + if(!model->MESAthresholdGiven) { + model->MESAthreshold = -1.26; + } + if(!model->MESAdGiven) { + model->MESAd = 0.12e-6; + } + if(!model->MESAduGiven) { + model->MESAdu = 0.035e-6; + } + if(!model->MESAlambdaGiven) { + model->MESAlambda = 0.045; + } + if(!model->MESAvsGiven) { + model->MESAvs = 1.5e5; + } + if(!model->MESAbetaGiven) { + model->MESAbeta = 0.0085; + } + if(!model->MESAetaGiven) { + model->MESAeta = 1.73; + } + if(!model->MESAmGiven) { + model->MESAm = 2.5; + } + if(!model->MESAmcGiven) { + model->MESAmc = 3.0; + } + if(!model->MESAalphaGiven) { + model->MESAalpha = 0.0; + } + if(!model->MESAsigma0Given) { + model->MESAsigma0 = 0.081; + } + if(!model->MESAvsigmatGiven) { + model->MESAvsigmat = 1.01; + } + if(!model->MESAvsigmaGiven) { + model->MESAvsigma = 0.1; + } + if(!model->MESAmuGiven) { + model->MESAmu = 0.23; + } + if(!model->MESAthetaGiven) { + model->MESAtheta = 0; + } + if(!model->MESAmu1Given) { + model->MESAmu1 = 0; + } + if(!model->MESAmu2Given) { + model->MESAmu2 = 0; + } + if(!model->MESAndGiven) { + model->MESAnd = 2.0e23; + } + if(!model->MESAnduGiven) { + model->MESAndu = 1e22; + } + if(!model->MESAndeltaGiven) { + model->MESAndelta = 6e24; + } + if(!model->MESAthGiven) { + model->MESAth = 0.01e-6; + } + if(!model->MESAdeltaGiven) { + model->MESAdelta = 5.0; + } + if(!model->MESAtcGiven) { + model->MESAtc = 0.0; + } + if(!model->MESAdrainResistGiven) { + model->MESAdrainResist = 0; + } + if(!model->MESAsourceResistGiven) { + model->MESAsourceResist = 0; + } + if(!model->MESAgateResistGiven) { + model->MESAgateResist = 0; + } + if(!model->MESAriGiven) { + model->MESAri = 0; + } + if(!model->MESArfGiven) { + model->MESArf = 0; + } + if(!model->MESArdiGiven) { + model->MESArdi = 0; + } + if(!model->MESArsiGiven) { + model->MESArsi = 0; + } + if(!model->MESAphibGiven) { + model->MESAphib = 0.5*CHARGE; + } + if(!model->MESAphib1Given) { + model->MESAphib1 = 0; + } + if(!model->MESAastarGiven) { + model->MESAastar = 4.0e4; + } + if(!model->MESAggrGiven) { + model->MESAggr = 40; + } + if(!model->MESAdelGiven) { + model->MESAdel = 0.04; + } + if(!model->MESAxchiGiven) { + model->MESAxchi = 0.033; + } + if(!model->MESAnGiven) { + model->MESAn = 1; + } + if(!model->MESAtvtoGiven) { + model->MESAtvto = 0; + } + if(!model->MESAtlambdaGiven) { + model->MESAtlambda = DBL_MAX; + } + if(!model->MESAteta0Given) { + model->MESAteta0 = DBL_MAX; + } + if(!model->MESAteta1Given) { + model->MESAteta1 = 0; + } + if(!model->MESAtmuGiven) { + model->MESAtmu = 300.15; + } + if(!model->MESAxtm0Given) { + model->MESAxtm0 = 0; + } + if(!model->MESAxtm1Given) { + model->MESAxtm1 = 0; + } + if(!model->MESAxtm2Given) { + model->MESAxtm2 = 0; + } + if(!model->MESAksGiven) { + model->MESAks = 0; + } + if(!model->MESAvsgGiven) { + model->MESAvsg = 0; + } + if(!model->MESAtfGiven) { + model->MESAtf = ckt->CKTtemp; + } + if(!model->MESAfloGiven) { + model->MESAflo = 0; + } + if(!model->MESAdelfoGiven) { + model->MESAdelfo = 0; + } + if(!model->MESAagGiven) { + model->MESAag = 0; + } + if(!model->MESAtc1Given) { + model->MESAtc1 = 0; + } + if(!model->MESAtc2Given) { + model->MESAtc2 = 0; + } + if(!model->MESAzetaGiven) { + model->MESAzeta = 1; + } + if(!model->MESAlevelGiven) { + model->MESAlevel = 2; + } + if(!model->MESAnmaxGiven) { + model->MESAnmax = 2e16; + } + if(!model->MESAgammaGiven) { + model->MESAgamma = 3.0; + } + if(!model->MESAepsiGiven) { + model->MESAepsi = 12.244*8.85418e-12; + } + if(!model->MESAcasGiven) { + model->MESAcas = 1; + } + if(!model->MESAcbsGiven) { + model->MESAcbs = 1; + } + + /* loop through all the instances of the model */ + for (here = model->MESAinstances; here != NULL ; + here=here->MESAnextInstance) { + + if(!here->MESAlengthGiven) { + here->MESAlength = 1e-6; + } + if(!here->MESAwidthGiven) { + here->MESAwidth = 20e-6; + } + if(!here->MESAtdGiven) { + here->MESAtd = ckt->CKTtemp; + } + if(!here->MESAtsGiven) { + here->MESAts = ckt->CKTtemp; + } + + here->MESAstate = *states; + *states += 20; + + if(model->MESAsourceResist != 0 && here->MESAsourcePrimeNode==0) { + error = CKTmkVolt(ckt,&tmp,here->MESAname,"source"); + if(error) return(error); + here->MESAsourcePrimeNode = 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->MESAsourcePrimeNode = here->MESAsourceNode; + } + + if(model->MESAdrainResist != 0 && here->MESAdrainPrimeNode==0) { + error = CKTmkVolt(ckt,&tmp,here->MESAname,"drain"); + if(error) return(error); + here->MESAdrainPrimeNode = 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->MESAdrainPrimeNode = here->MESAdrainNode; + } + if(model->MESAgateResist != 0 && here->MESAgatePrimeNode==0) { + error = CKTmkVolt(ckt,&tmp,here->MESAname,"gate"); + if(error) return(error); + here->MESAgatePrimeNode = 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->MESAgatePrimeNode = here->MESAgateNode; + } + + + if(model->MESAri != 0 && here->MESAsourcePrmPrmNode==0) { + error = CKTmkVolt(ckt,&tmp,here->MESAname,"gs"); + if(error) return(error); + here->MESAsourcePrmPrmNode = 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->MESAsourcePrmPrmNode = here->MESAsourcePrimeNode; + } + if(model->MESArf != 0 && here->MESAdrainPrmPrmNode==0) { + error = CKTmkVolt(ckt,&tmp,here->MESAname,"gd"); + if(error) return(error); + here->MESAdrainPrmPrmNode = 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->MESAdrainPrmPrmNode = here->MESAdrainPrimeNode; + } + +#define TSTALLOC(ptr,first,second) \ +if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ + return(E_NOMEM);\ +} + + TSTALLOC(MESAdrainDrainPtr,MESAdrainNode,MESAdrainNode) + TSTALLOC(MESAdrainPrimeDrainPrimePtr,MESAdrainPrimeNode,MESAdrainPrimeNode) + TSTALLOC(MESAdrainPrmPrmDrainPrmPrmPtr,MESAdrainPrmPrmNode,MESAdrainPrmPrmNode) + TSTALLOC(MESAgateGatePtr,MESAgateNode,MESAgateNode) + TSTALLOC(MESAgatePrimeGatePrimePtr,MESAgatePrimeNode,MESAgatePrimeNode) + TSTALLOC(MESAsourceSourcePtr,MESAsourceNode,MESAsourceNode) + TSTALLOC(MESAsourcePrimeSourcePrimePtr,MESAsourcePrimeNode,MESAsourcePrimeNode) + TSTALLOC(MESAsourcePrmPrmSourcePrmPrmPtr,MESAsourcePrmPrmNode,MESAsourcePrmPrmNode) + TSTALLOC(MESAdrainDrainPrimePtr,MESAdrainNode,MESAdrainPrimeNode) + TSTALLOC(MESAdrainPrimeDrainPtr,MESAdrainPrimeNode,MESAdrainNode) + TSTALLOC(MESAgatePrimeDrainPrimePtr,MESAgatePrimeNode,MESAdrainPrimeNode) + TSTALLOC(MESAdrainPrimeGatePrimePtr,MESAdrainPrimeNode,MESAgatePrimeNode) + TSTALLOC(MESAgatePrimeSourcePrimePtr,MESAgatePrimeNode,MESAsourcePrimeNode) + TSTALLOC(MESAsourcePrimeGatePrimePtr,MESAsourcePrimeNode,MESAgatePrimeNode) + TSTALLOC(MESAsourceSourcePrimePtr,MESAsourceNode,MESAsourcePrimeNode) + TSTALLOC(MESAsourcePrimeSourcePtr,MESAsourcePrimeNode,MESAsourceNode) + TSTALLOC(MESAdrainPrimeSourcePrimePtr,MESAdrainPrimeNode,MESAsourcePrimeNode) + TSTALLOC(MESAsourcePrimeDrainPrimePtr,MESAsourcePrimeNode,MESAdrainPrimeNode) + TSTALLOC(MESAgatePrimeGatePtr,MESAgatePrimeNode,MESAgateNode) + TSTALLOC(MESAgateGatePrimePtr,MESAgateNode,MESAgatePrimeNode) + TSTALLOC(MESAsourcePrmPrmSourcePrimePtr,MESAsourcePrmPrmNode,MESAsourcePrimeNode) + TSTALLOC(MESAsourcePrimeSourcePrmPrmPtr,MESAsourcePrimeNode,MESAsourcePrmPrmNode) + TSTALLOC(MESAsourcePrmPrmGatePrimePtr,MESAsourcePrmPrmNode,MESAgatePrimeNode) + TSTALLOC(MESAgatePrimeSourcePrmPrmPtr,MESAgatePrimeNode,MESAsourcePrmPrmNode) + TSTALLOC(MESAdrainPrmPrmDrainPrimePtr,MESAdrainPrmPrmNode,MESAdrainPrimeNode) + TSTALLOC(MESAdrainPrimeDrainPrmPrmPtr,MESAdrainPrimeNode,MESAdrainPrmPrmNode) + TSTALLOC(MESAdrainPrmPrmGatePrimePtr,MESAdrainPrmPrmNode,MESAgatePrimeNode) + TSTALLOC(MESAgatePrimeDrainPrmPrmPtr,MESAgatePrimeNode,MESAdrainPrmPrmNode) + } + } + return(OK); +} + + +int +MESAunsetup(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + MESAmodel *model; + MESAinstance *here; + + for (model = (MESAmodel *)inModel; model != NULL; + model = model->MESAnextModel) + { + for (here = model->MESAinstances; here != NULL; + here=here->MESAnextInstance) + { + if (here->MESAdrainPrimeNode + && here->MESAdrainPrimeNode != here->MESAdrainNode) + { + CKTdltNNum(ckt, here->MESAdrainPrimeNode); + here->MESAdrainPrimeNode = 0; + } + if (here->MESAsourcePrimeNode + && here->MESAsourcePrimeNode != here->MESAsourceNode) + { + CKTdltNNum(ckt, here->MESAsourcePrimeNode); + here->MESAsourcePrimeNode = 0; + } + if (here->MESAgatePrimeNode + && here->MESAgatePrimeNode != here->MESAgateNode) + { + CKTdltNNum(ckt, here->MESAgatePrimeNode); + here->MESAgatePrimeNode = 0; + } + + } + } + return OK; +} \ No newline at end of file diff --git a/src/spicelib/devices/mesa/mesatemp.c b/src/spicelib/devices/mesa/mesatemp.c new file mode 100644 index 000000000..3940bed9d --- /dev/null +++ b/src/spicelib/devices/mesa/mesatemp.c @@ -0,0 +1,177 @@ +/********** +Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. +Author: Trond Ytterdal +**********/ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "mesadefs.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + + +#define EPSILONGAAS (12.244*8.85418e-12) + +int +MESAtemp(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + + register MESAmodel *model = (MESAmodel*)inModel; + register MESAinstance *here; + double temp; + double vt; + double d; + + + for( ; model != NULL; model = model->MESAnextModel ) { + if(!model->MESAlambdahfGiven) + model->MESAlambdahf = model->MESAlambda; + if(model->MESAlevel == 2) + model->MESAvpo = CHARGE*model->MESAnd*model->MESAd*model->MESAd/ + 2/EPSILONGAAS; + else { + model->MESAvpou = CHARGE*model->MESAndu*model->MESAdu*model->MESAdu/ + 2/EPSILONGAAS; + model->MESAvpod = CHARGE*model->MESAndelta*model->MESAth* + (2*model->MESAdu + model->MESAth)/2/EPSILONGAAS; + model->MESAvpo = model->MESAvpou+model->MESAvpod; + } + model->MESAdeltaSqr = model->MESAdelta*model->MESAdelta; + + for (here = model->MESAinstances; here != NULL ; + here=here->MESAnextInstance) { + vt = CONSTKoverQ * here->MESAts; + if(model->MESAmu1 == 0 && model->MESAmu2 == 0) + here->MESAtMu = model->MESAmu*pow(here->MESAts/ + model->MESAtmu,model->MESAxtm0); + else { + double muimp = model->MESAmu*pow(here->MESAts/ + model->MESAtmu,model->MESAxtm0); + double mupo = model->MESAmu1*pow(model->MESAtmu/ + here->MESAts,model->MESAxtm1) + + model->MESAmu2*pow(model->MESAtmu/ + here->MESAts,model->MESAxtm2); + here->MESAtMu = 1/(1/muimp+1/mupo); + } + here->MESAtTheta = model->MESAtheta; + here->MESAtPhib = model->MESAphib-model->MESAphib1*(here->MESAts-ckt->CKTnomTemp); + here->MESAtVto = model->MESAthreshold-model->MESAtvto*(here->MESAts-ckt->CKTnomTemp); + here->MESAimax = CHARGE*model->MESAnmax*model->MESAvs*here->MESAwidth; + + if(model->MESAlevel == 2) + here->MESAgchi0 = CHARGE*here->MESAwidth/here->MESAlength; + else + here->MESAgchi0 = CHARGE*here->MESAwidth/here->MESAlength*here->MESAtMu; + here->MESAbeta = 2*EPSILONGAAS*model->MESAvs*model->MESAzeta*here->MESAwidth/ + model->MESAd; + here->MESAtEta = model->MESAeta*(1+here->MESAts/model->MESAteta0)+ + model->MESAteta1/here->MESAts; + here->MESAtLambda= model->MESAlambda*(1-here->MESAts/model->MESAtlambda); + here->MESAtLambdahf = model->MESAlambdahf*(1-here->MESAts/model->MESAtlambda); + if(model->MESAlevel == 3) + d = model->MESAdu; + else + d = model->MESAd; + if(model->MESAlevel == 4) + here->MESAn0 = model->MESAepsi*here->MESAtEta*vt/2/CHARGE/d; + else + here->MESAn0 = EPSILONGAAS*here->MESAtEta*vt/CHARGE/d; + here->MESAnsb0 = EPSILONGAAS*here->MESAtEta*vt/CHARGE/ + (model->MESAdu + model->MESAth); + here->MESAisatb0 = CHARGE*here->MESAn0*vt* + here->MESAwidth/here->MESAlength; + if(model->MESAlevel == 4) + here->MESAcf = 0.5*model->MESAepsi*here->MESAwidth; + else + here->MESAcf = 0.5*EPSILONGAAS*here->MESAwidth; + here->MESAcsatfs = 0.5*model->MESAastar*here->MESAts* + here->MESAts*exp(-here->MESAtPhib/(CONSTboltz*here->MESAts))* + here->MESAlength*here->MESAwidth; + here->MESAcsatfd = 0.5*model->MESAastar*here->MESAtd* + here->MESAtd*exp(-here->MESAtPhib/(CONSTboltz*here->MESAtd))* + here->MESAlength*here->MESAwidth; + here->MESAggrwl = model->MESAggr*here->MESAlength*here->MESAwidth* + exp(model->MESAxchi*(here->MESAts-ckt->CKTnomTemp)); + if(here->MESAcsatfs != 0) + here->MESAvcrits = vt*log(vt/(CONSTroot2 * here->MESAcsatfs)); + else + here->MESAvcrits = DBL_MAX; + if(here->MESAcsatfd != 0) { + double vtd = CONSTKoverQ * here->MESAtd; + here->MESAvcritd = vtd*log(vtd/(CONSTroot2 * here->MESAcsatfd)); + } else + here->MESAvcritd = DBL_MAX; + temp = exp(here->MESAts/model->MESAtf); + here->MESAfl = model->MESAflo*temp; + here->MESAdelf = model->MESAdelfo*temp; + if(model->MESArdi != 0.0) + here->MESAtRdi = model->MESArdi*(1+ + model->MESAtc1*(here->MESAtd-ckt->CKTnomTemp)+ + model->MESAtc2*(here->MESAtd-ckt->CKTnomTemp)*(here->MESAtd-ckt->CKTnomTemp)); + else + here->MESAtRdi = 0; + if(model->MESArsi != 0.0) + here->MESAtRsi = model->MESArsi*(1+ + model->MESAtc1*(here->MESAts-ckt->CKTnomTemp)+ + model->MESAtc2*(here->MESAts-ckt->CKTnomTemp)*(here->MESAts-ckt->CKTnomTemp)); + else + here->MESAtRsi = 0; + if(model->MESAgateResist != 0.0) + here->MESAtRg = model->MESAgateResist*(1+ + model->MESAtc1*(here->MESAts-ckt->CKTnomTemp)+ + model->MESAtc2*(here->MESAts-ckt->CKTnomTemp)*(here->MESAts-ckt->CKTnomTemp)); + else + here->MESAtRg = 0; + if(model->MESAsourceResist != 0.0) + here->MESAtRs = model->MESAsourceResist*(1+ + model->MESAtc1*(here->MESAts-ckt->CKTnomTemp)+ + model->MESAtc2*(here->MESAts-ckt->CKTnomTemp)*(here->MESAts-ckt->CKTnomTemp)); + else + here->MESAtRs = 0; + if(model->MESAdrainResist != 0.0) + here->MESAtRd = model->MESAdrainResist*(1+ + model->MESAtc1*(here->MESAtd-ckt->CKTnomTemp)+ + model->MESAtc2*(here->MESAtd-ckt->CKTnomTemp)*(here->MESAtd-ckt->CKTnomTemp)); + else + here->MESAtRd = 0; + if(model->MESAri != 0.0) + here->MESAtRi = model->MESAri*(1+ + model->MESAtc1*(here->MESAts-ckt->CKTnomTemp)+ + model->MESAtc2*(here->MESAts-ckt->CKTnomTemp)*(here->MESAts-ckt->CKTnomTemp)); + else + here->MESAtRi = 0; + if(model->MESArf != 0.0) + here->MESAtRf = model->MESArf*(1+ + model->MESAtc1*(here->MESAtd-ckt->CKTnomTemp)+ + model->MESAtc2*(here->MESAtd-ckt->CKTnomTemp)*(here->MESAtd-ckt->CKTnomTemp)); + else + here->MESAtRf = 0; + if(here->MESAtRd != 0) + here->MESAdrainConduct = 1/here->MESAtRd; + else + here->MESAdrainConduct = 0; + if(here->MESAtRs != 0) + here->MESAsourceConduct = 1/here->MESAtRs; + else + here->MESAsourceConduct = 0; + if(here->MESAtRg != 0) + here->MESAgateConduct = 1/here->MESAtRg; + else + here->MESAgateConduct = 0; + if(here->MESAtRi != 0) + here->MESAtGi = 1/here->MESAtRi; + else + here->MESAtGi = 0; + if(here->MESAtRf != 0) + here->MESAtGf = 1/here->MESAtRf; + else + here->MESAtGf = 0; + } + } + return(OK); +} diff --git a/src/spicelib/devices/mesa/mesatrunc.c b/src/spicelib/devices/mesa/mesatrunc.c new file mode 100644 index 000000000..43ac9b005 --- /dev/null +++ b/src/spicelib/devices/mesa/mesatrunc.c @@ -0,0 +1,30 @@ +/********** +Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved. +Author: Trond Ytterdal +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "mesadefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +MESAtrunc(inModel,ckt,timeStep) + GENmodel *inModel; + CKTcircuit *ckt; + double *timeStep; +{ + MESAmodel *model = (MESAmodel*)inModel; + MESAinstance *here; + + for( ; model != NULL; model = model->MESAnextModel) { + for(here=model->MESAinstances;here!=NULL;here = here->MESAnextInstance){ + CKTterr(here->MESAqgs,ckt,timeStep); + CKTterr(here->MESAqgd,ckt,timeStep); + } + } + return(OK); +} 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/mos1init.c b/src/spicelib/devices/mos1/mos1init.c new file mode 100644 index 000000000..915b65af0 --- /dev/null +++ b/src/spicelib/devices/mos1/mos1init.c @@ -0,0 +1,64 @@ +#include + +#include + +#include "mos1itf.h" +#include "mos1ext.h" +#include "mos1init.h" + + +SPICEdev MOS1info = { + { + "Mos1", + "Level 1 MOSfet model with Meyer capacitance model", + + &MOS1nSize, + &MOS1nSize, + MOS1names, + + &MOS1pTSize, + MOS1pTable, + + &MOS1mPTSize, + MOS1mPTable, + DEV_DEFAULT + }, + + DEVparam : MOS1param, + DEVmodParam : MOS1mParam, + DEVload : MOS1load, + DEVsetup : MOS1setup, + DEVunsetup : MOS1unsetup, + DEVpzSetup : MOS1setup, + DEVtemperature: MOS1temp, + DEVtrunc : MOS1trunc, + DEVfindBranch : NULL, + DEVacLoad : MOS1acLoad, + DEVaccept : NULL, + DEVdestroy : MOS1destroy, + DEVmodDelete : MOS1mDelete, + DEVdelete : MOS1delete, + DEVsetic : MOS1getic, + DEVask : MOS1ask, + DEVmodAsk : MOS1mAsk, + DEVpzLoad : MOS1pzLoad, + DEVconvTest : MOS1convTest, + DEVsenSetup : MOS1sSetup, + DEVsenLoad : MOS1sLoad, + DEVsenUpdate : MOS1sUpdate, + DEVsenAcLoad : MOS1sAcLoad, + DEVsenPrint : MOS1sPrint, + DEVsenTrunc : NULL, + DEVdisto : MOS1disto, + DEVnoise : MOS1noise, + + DEVinstSize : &MOS1iSize, + DEVmodSize : &MOS1mSize +}; + + +SPICEdev * +get_mos1_info(void) +{ + return &MOS1info; +} diff --git a/src/spicelib/devices/mos1/mos1init.h b/src/spicelib/devices/mos1/mos1init.h new file mode 100644 index 000000000..80ed9959a --- /dev/null +++ b/src/spicelib/devices/mos1/mos1init.h @@ -0,0 +1,13 @@ +#ifndef _MOS1INIT_H +#define _MOS1INIT_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; + +#endif 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/mos2init.c b/src/spicelib/devices/mos2/mos2init.c new file mode 100644 index 000000000..70fd535b0 --- /dev/null +++ b/src/spicelib/devices/mos2/mos2init.c @@ -0,0 +1,64 @@ +#include + +#include + +#include "mos2itf.h" +#include "mos2ext.h" +#include "mos2init.h" + + +SPICEdev MOS2info = { + { + "Mos2", + "Level 2 MOSfet model with Meyer capacitance model", + + &MOS2nSize, + &MOS2nSize, + MOS2names, + + &MOS2pTSize, + MOS2pTable, + + &MOS2mPTSize, + MOS2mPTable, + DEV_DEFAULT + }, + + DEVparam : MOS2param, + DEVmodParam : MOS2mParam, + DEVload : MOS2load, + DEVsetup : MOS2setup, + DEVunsetup : MOS2unsetup, + DEVpzSetup : MOS2setup, + DEVtemperature: MOS2temp, + DEVtrunc : MOS2trunc, + DEVfindBranch : NULL, + DEVacLoad : MOS2acLoad, + DEVaccept : NULL, + DEVdestroy : MOS2destroy, + DEVmodDelete : MOS2mDelete, + DEVdelete : MOS2delete, + DEVsetic : MOS2getic, + DEVask : MOS2ask, + DEVmodAsk : MOS2mAsk, + DEVpzLoad : MOS2pzLoad, + DEVconvTest : MOS2convTest, + DEVsenSetup : MOS2sSetup, + DEVsenLoad : MOS2sLoad, + DEVsenUpdate : MOS2sUpdate, + DEVsenAcLoad : MOS2sAcLoad, + DEVsenPrint : MOS2sPrint, + DEVsenTrunc : NULL, + DEVdisto : MOS2disto, + DEVnoise : MOS2noise, + + DEVinstSize : &MOS2iSize, + DEVmodSize : &MOS2mSize +}; + + +SPICEdev * +get_mos2_info(void) +{ + return &MOS2info; +} diff --git a/src/spicelib/devices/mos2/mos2init.h b/src/spicelib/devices/mos2/mos2init.h new file mode 100644 index 000000000..b7ba9b220 --- /dev/null +++ b/src/spicelib/devices/mos2/mos2init.h @@ -0,0 +1,13 @@ +#ifndef _MOS2INIT_H +#define _MOS2INIT_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; + +#endif 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/mos3init.c b/src/spicelib/devices/mos3/mos3init.c new file mode 100644 index 000000000..4c847b5f5 --- /dev/null +++ b/src/spicelib/devices/mos3/mos3init.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "mos3itf.h" +#include "mos3ext.h" +#include "mos3init.h" + + +SPICEdev MOS3info = { + { + "Mos3", + "Level 3 MOSfet model with Meyer capacitance model", + + &MOS3nSize, + &MOS3nSize, + MOS3names, + + &MOS3pTSize, + MOS3pTable, + + &MOS3mPTSize, + MOS3mPTable, + DEV_DEFAULT + }, + + DEVparam : MOS3param, + DEVmodParam : MOS3mParam, + DEVload : MOS3load, + DEVsetup : MOS3setup, + DEVunsetup : MOS3unsetup, + DEVpzSetup : MOS3setup, + DEVtemperature: MOS3temp, + DEVtrunc : MOS3trunc, + DEVfindBranch : NULL, + DEVacLoad : MOS3acLoad, + DEVaccept : NULL, + DEVdestroy : MOS3destroy, + DEVmodDelete : MOS3mDelete, + DEVdelete : MOS3delete, + DEVsetic : MOS3getic, + DEVask : MOS3ask, + DEVmodAsk : MOS3mAsk, + DEVpzLoad : MOS3pzLoad, + DEVconvTest : MOS3convTest, + DEVsenSetup : MOS3sSetup, + DEVsenLoad : MOS3sLoad, + DEVsenUpdate : MOS3sUpdate, + DEVsenAcLoad : MOS3sAcLoad, + DEVsenPrint : MOS3sPrint, + DEVsenTrunc : NULL, + DEVdisto : MOS3disto, + DEVnoise : MOS3noise, + + DEVinstSize : &MOS3iSize, + DEVmodSize : &MOS3mSize + +}; + + +SPICEdev * +get_mos3_info(void) +{ + return &MOS3info; +} diff --git a/src/spicelib/devices/mos3/mos3init.h b/src/spicelib/devices/mos3/mos3init.h new file mode 100644 index 000000000..3c527cb79 --- /dev/null +++ b/src/spicelib/devices/mos3/mos3init.h @@ -0,0 +1,13 @@ +#ifndef _MOS3INIT_H +#define _MOS3INIT_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; + +#endif 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/mos6init.c b/src/spicelib/devices/mos6/mos6init.c new file mode 100644 index 000000000..06c6e908f --- /dev/null +++ b/src/spicelib/devices/mos6/mos6init.c @@ -0,0 +1,64 @@ +#include + +#include + +#include "mos6itf.h" +#include "mos6ext.h" +#include "mos6init.h" + + +SPICEdev MOS6info = { + { + "Mos6", + "Level 6 MOSfet model with Meyer capacitance model", + + &MOS6nSize, + &MOS6nSize, + MOS6names, + + &MOS6pTSize, + MOS6pTable, + + &MOS6mPTSize, + MOS6mPTable, + DEV_DEFAULT + }, + + DEVparam : MOS6param, + DEVmodParam : MOS6mParam, + DEVload : MOS6load, + DEVsetup : MOS6setup, + DEVunsetup : MOS6unsetup, + DEVpzSetup : NULL, /* PZsetup routine */ + DEVtemperature: MOS6temp, + DEVtrunc : MOS6trunc, + DEVfindBranch : NULL, + DEVacLoad : NULL, /* MOS6acLoad, XXX */ + DEVaccept : NULL, + DEVdestroy : MOS6destroy, + DEVmodDelete : NULL, + DEVdelete : NULL, + DEVsetic : MOS6getic, + DEVask : MOS6ask, + DEVmodAsk : MOS6mAsk, + DEVpzLoad : NULL, /*MOS6pzLoad, XXX */ + DEVconvTest : MOS6convTest, + DEVsenSetup : NULL /* MOS6sSetup */, + DEVsenLoad : NULL /* MOS6sLoad */, + DEVsenUpdate : NULL /* MOS6sUpdate */, + DEVsenAcLoad : NULL /* MOS6sAcLoad */, + DEVsenPrint : NULL /* MOS6sPrint */, + DEVsenTrunc : NULL, + DEVdisto : NULL, /* Distortion routine */ + DEVnoise : NULL, /* Noise routine */ + + DEVinstSize : &MOS6iSize, + DEVmodSize : &MOS6mSize +}; + + +SPICEdev * +get_mos6_info(void) +{ + return &MOS6info; +} diff --git a/src/spicelib/devices/mos6/mos6init.h b/src/spicelib/devices/mos6/mos6init.h new file mode 100644 index 000000000..391bbf28b --- /dev/null +++ b/src/spicelib/devices/mos6/mos6init.h @@ -0,0 +1,13 @@ +#ifndef _MOS6INIT_H +#define _MOS6INIT_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; + +#endif 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/mos9/Makefile.am b/src/spicelib/devices/mos9/Makefile.am new file mode 100644 index 000000000..16d3d4359 --- /dev/null +++ b/src/spicelib/devices/mos9/Makefile.am @@ -0,0 +1,39 @@ +## Process this file with automake to produce Makefile.in + +pkglib_LTLIBRARIES = libmos9.la + +libmos9_la_SOURCES = \ + mos9.c \ + mos9acld.c \ + mos9ask.c \ + mos9conv.c \ + mos9defs.h \ + mos9del.c \ + mos9dest.c \ + mos9dist.c \ + mos9dset.c \ + mos9ext.h \ + mos9ic.c \ + mos9init.c \ + mos9init.h \ + mos9itf.h \ + mos9load.c \ + mos9mask.c \ + mos9mdel.c \ + mos9mpar.c \ + mos9noi.c \ + mos9par.c \ + mos9pzld.c \ + mos9sacl.c \ + mos9set.c \ + mos9sld.c \ + mos9sprt.c \ + mos9sset.c \ + mos9supd.c \ + mos9temp.c \ + mos9trun.c + + + +INCLUDES = -I$(top_srcdir)/src/include +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/mos9/mos9.c b/src/spicelib/devices/mos9/mos9.c new file mode 100644 index 000000000..acf6a863d --- /dev/null +++ b/src/spicelib/devices/mos9/mos9.c @@ -0,0 +1,174 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Thomas L. Quarles +Modified: Alan Gillespie +**********/ + +#include "ngspice.h" +#include +#include "devdefs.h" +#include "ifsim.h" +#include "mos9defs.h" +#include "suffix.h" + +IFparm MOS9pTable[] = { /* parameters */ + + IOPU("m", MOS9_M, IF_REAL , "Multiplier"), + IOPU("l", MOS9_L, IF_REAL , "Length"), + IOPU("w", MOS9_W, IF_REAL , "Width"), + IOPU("ad", MOS9_AD, IF_REAL , "Drain area"), + IOPU("as", MOS9_AS, IF_REAL , "Source area"), + IOPU("pd", MOS9_PD, IF_REAL , "Drain perimeter"), + IOPU("ps", MOS9_PS, IF_REAL , "Source perimeter"), + OP("id", MOS9_CD, IF_REAL, "Drain current"), + OPR("cd", MOS9_CD, IF_REAL, "Drain current"), + OPU("ibd", MOS9_CBD, IF_REAL, "B-D junction current"), + OPU("ibs", MOS9_CBS, IF_REAL, "B-S junction current"), + OPU("is", MOS9_CS, IF_REAL, "Source current"), + OPU("ig", MOS9_CG, IF_REAL, "Gate current"), + OPU("ib", MOS9_CB, IF_REAL, "Bulk current"), + OP("vgs", MOS9_VGS, IF_REAL, "Gate-Source voltage"), + OP("vds", MOS9_VDS, IF_REAL, "Drain-Source voltage"), + OP("vbs", MOS9_VBS, IF_REAL, "Bulk-Source voltage"), + OPU("vbd", MOS9_VBD, IF_REAL, "Bulk-Drain voltage"), + IOPU("nrd", MOS9_NRD, IF_REAL , "Drain squares"), + IOPU("nrs", MOS9_NRS, IF_REAL , "Source squares"), + IP("off", MOS9_OFF, IF_FLAG , "Device initially off"), + IOPAU("icvds", MOS9_IC_VDS, IF_REAL , "Initial D-S voltage"), + IOPAU("icvgs", MOS9_IC_VGS, IF_REAL , "Initial G-S voltage"), + IOPAU("icvbs", MOS9_IC_VBS, IF_REAL , "Initial B-S voltage"), + IOPU("ic", MOS9_IC, IF_REALVEC, "Vector of D-S, G-S, B-S voltages"), + IOPU("temp", MOS9_TEMP, IF_REAL , "Instance operating temperature"), + IP("sens_l", MOS9_L_SENS, IF_FLAG, "flag to request sensitivity WRT length"), + IP("sens_w", MOS9_W_SENS, IF_FLAG, "flag to request sensitivity WRT width"), + OPU("dnode", MOS9_DNODE, IF_INTEGER, "Number of drain node"), + OPU("gnode", MOS9_GNODE, IF_INTEGER, "Number of gate node"), + OPU("snode", MOS9_SNODE, IF_INTEGER, "Number of source node"), + OPU("bnode", MOS9_BNODE, IF_INTEGER, "Number of bulk node"), + OPU("dnodeprime", MOS9_DNODEPRIME,IF_INTEGER,"Number of internal drain node"), + OPU("snodeprime", MOS9_SNODEPRIME,IF_INTEGER,"Number of internal source node"), + OP("von", MOS9_VON, IF_REAL, "Turn-on voltage"), + OP("vdsat", MOS9_VDSAT, IF_REAL, "Saturation drain voltage"), + OPU("sourcevcrit", MOS9_SOURCEVCRIT, IF_REAL, "Critical source voltage"), + OPU("drainvcrit", MOS9_DRAINVCRIT, IF_REAL, "Critical drain voltage"), + OP("rs", MOS9_SOURCERESIST, IF_REAL, "Source resistance"), + OPU("sourceconductance", MOS9_SOURCECONDUCT, IF_REAL, "Source conductance"), + OP("rd", MOS9_DRAINRESIST, IF_REAL, "Drain resistance"), + OPU("drainconductance", MOS9_DRAINCONDUCT, IF_REAL, "Drain conductance"), + OP("gm", MOS9_GM, IF_REAL, "Transconductance"), + OP("gds", MOS9_GDS, IF_REAL, "Drain-Source conductance"), + OP("gmb", MOS9_GMBS, IF_REAL, "Bulk-Source transconductance"), + OPR("gmbs", MOS9_GMBS, IF_REAL, "Bulk-Source transconductance"), + OPU("gbd", MOS9_GBD, IF_REAL, "Bulk-Drain conductance"), + OPU("gbs", MOS9_GBS, IF_REAL, "Bulk-Source conductance"), + + OP("cbd", MOS9_CAPBD, IF_REAL, "Bulk-Drain capacitance"), + OP("cbs", MOS9_CAPBS, IF_REAL, "Bulk-Source capacitance"), + OP("cgs", MOS9_CAPGS, IF_REAL, "Gate-Source capacitance"), +/* OPR("cgs", MOS9_CGS, IF_REAL , "Gate-Source capacitance"),*/ + OP("cgd", MOS9_CAPGD, IF_REAL, "Gate-Drain capacitance"), +/* OPR("cgd", MOS9_CGD, IF_REAL , "Gate-Drain capacitance"),*/ + OP("cgb", MOS9_CAPGB, IF_REAL, "Gate-Bulk capacitance"), + + OPU("cqgs",MOS9_CQGS,IF_REAL,"Capacitance due to gate-source charge storage"), + OPU("cqgd",MOS9_CQGD, IF_REAL,"Capacitance due to gate-drain charge storage"), + OPU("cqgb",MOS9_CQGB, IF_REAL,"Capacitance due to gate-bulk charge storage"), + OPU("cqbd",MOS9_CQBD,IF_REAL,"Capacitance due to bulk-drain charge storage"), + OPU("cqbs",MOS9_CQBS,IF_REAL,"Capacitance due to bulk-source charge storage"), + + OPU("cbd0",MOS9_CAPZEROBIASBD,IF_REAL,"Zero-Bias B-D junction capacitance"), + OPU("cbdsw0",MOS9_CAPZEROBIASBDSW,IF_REAL, + "Zero-Bias B-D sidewall capacitance"), + OPU("cbs0",MOS9_CAPZEROBIASBS,IF_REAL,"Zero-Bias B-S junction capacitance"), + OPU("cbssw0",MOS9_CAPZEROBIASBSSW,IF_REAL, + "Zero-Bias B-S sidewall capacitance"), + OPU("qbs", MOS9_QBS, IF_REAL, "Bulk-Source charge storage"), + OPU("qgs", MOS9_QGS, IF_REAL, "Gate-Source charge storage"), + OPU("qgd", MOS9_QGD, IF_REAL, "Gate-Drain charge storage"), + OPU("qgb", MOS9_QGB, IF_REAL, "Gate-Bulk charge storage"), + OPU("qbd", MOS9_QBD, IF_REAL, "Bulk-Drain charge storage"), + OPU("p", MOS9_POWER, IF_REAL, "Instantaneous power"), + OPU("sens_l_dc", MOS9_L_SENS_DC, IF_REAL, "dc sensitivity wrt length"), + OPU("sens_l_real",MOS9_L_SENS_REAL, IF_REAL, + "real part of ac sensitivity wrt length"), + OPU("sens_l_imag",MOS9_L_SENS_IMAG, IF_REAL, + "imag part of ac sensitivity wrt length"), + OPU("sens_l_cplx",MOS9_L_SENS_CPLX, IF_COMPLEX, "ac sensitivity wrt length"), + OPU("sens_l_mag", MOS9_L_SENS_MAG, IF_REAL, + "sensitivity wrt l of ac magnitude"), + OPU("sens_l_ph", MOS9_L_SENS_PH, IF_REAL, "sensitivity wrt l of ac phase"), + OPU("sens_w_dc", MOS9_W_SENS_DC, IF_REAL, "dc sensitivity wrt width"), + OPU("sens_w_real",MOS9_W_SENS_REAL, IF_REAL, + "real part of ac sensitivity wrt width"), + OPU("sens_w_imag",MOS9_W_SENS_IMAG, IF_REAL, + "imag part of ac sensitivity wrt width"), + OPU("sens_w_mag", MOS9_W_SENS_MAG, IF_REAL, + "sensitivity wrt w of ac magnitude"), + OPU("sens_w_ph", MOS9_W_SENS_PH, IF_REAL, "sensitivity wrt w of ac phase"), + OPU("sens_w_cplx",MOS9_W_SENS_CPLX, IF_COMPLEX, "ac sensitivity wrt width") +}; + +IFparm MOS9mPTable[] = { /* model parameters */ + OP("type", MOS9_MOD_TYPE, IF_STRING ,"N-channel or P-channel MOS"), + IP("nmos", MOS9_MOD_NMOS, IF_FLAG ,"N type MOSfet model"), + IP("pmos", MOS9_MOD_PMOS, IF_FLAG ,"P type MOSfet model"), + IOP("vto", MOS9_MOD_VTO, IF_REAL ,"Threshold voltage"), + IOPR("vt0", MOS9_MOD_VTO, IF_REAL ,"Threshold voltage"), + IOP("kp", MOS9_MOD_KP, IF_REAL ,"Transconductance parameter"), + IOP("gamma", MOS9_MOD_GAMMA, IF_REAL ,"Bulk threshold parameter"), + IOP("phi", MOS9_MOD_PHI, IF_REAL ,"Surface potential"), + IOP("rd", MOS9_MOD_RD, IF_REAL ,"Drain ohmic resistance"), + IOP("rs", MOS9_MOD_RS, IF_REAL ,"Source ohmic resistance"), + IOPA("cbd", MOS9_MOD_CBD, IF_REAL ,"B-D junction capacitance"), + IOPA("cbs", MOS9_MOD_CBS, IF_REAL ,"B-S junction capacitance"), + IOP("is", MOS9_MOD_IS, IF_REAL ,"Bulk junction sat. current"), + IOP("pb", MOS9_MOD_PB, IF_REAL ,"Bulk junction potential"), + IOPA("cgso", MOS9_MOD_CGSO, IF_REAL ,"Gate-source overlap cap."), + IOPA("cgdo", MOS9_MOD_CGDO, IF_REAL ,"Gate-drain overlap cap."), + IOPA("cgbo", MOS9_MOD_CGBO, IF_REAL ,"Gate-bulk overlap cap."), + IOP("rsh", MOS9_MOD_RSH, IF_REAL ,"Sheet resistance"), + IOPA("cj", MOS9_MOD_CJ, IF_REAL ,"Bottom junction cap per area"), + IOP("mj", MOS9_MOD_MJ, IF_REAL ,"Bottom grading coefficient"), + IOPA("cjsw", MOS9_MOD_CJSW, IF_REAL ,"Side junction cap per area"), + IOP("mjsw", MOS9_MOD_MJSW, IF_REAL ,"Side grading coefficient"), + IOPU("js", MOS9_MOD_JS, IF_REAL ,"Bulk jct. sat. current density"), + IOP("tox", MOS9_MOD_TOX, IF_REAL ,"Oxide thickness"), + IOP("ld", MOS9_MOD_LD, IF_REAL ,"Lateral diffusion"), + IOP("xl", MOS9_MOD_XL, IF_REAL ,"Length mask adjustment"), + IOP("wd", MOS9_MOD_WD, IF_REAL ,"Width Narrowing (Diffusion)"), + IOP("xw", MOS9_MOD_XW, IF_REAL ,"Width mask adjustment"), + IOPU("delvto", MOS9_MOD_DELVTO, IF_REAL ,"Threshold voltage Adjust"), + IOPR("delvt0", MOS9_MOD_DELVTO, IF_REAL ,"Threshold voltage Adjust"), + IOP("u0", MOS9_MOD_U0, IF_REAL ,"Surface mobility"), + IOPR("uo", MOS9_MOD_U0, IF_REAL ,"Surface mobility"), + IOP("fc", MOS9_MOD_FC, IF_REAL ,"Forward bias jct. fit parm."), + IOP("nsub", MOS9_MOD_NSUB, IF_REAL ,"Substrate doping"), + IOP("tpg", MOS9_MOD_TPG, IF_INTEGER,"Gate type"), + IOP("nss", MOS9_MOD_NSS, IF_REAL ,"Surface state density"), + IOP("vmax", MOS9_MOD_VMAX, IF_REAL ,"Maximum carrier drift velocity"), + IOP("xj", MOS9_MOD_XJ, IF_REAL ,"Junction depth"), + IOP("nfs", MOS9_MOD_NFS, IF_REAL ,"Fast surface state density"), + IOP("xd", MOS9_MOD_XD, IF_REAL ,"Depletion layer width"), + IOP("alpha", MOS9_MOD_ALPHA, IF_REAL ,"Alpha"), + IOP("eta", MOS9_MOD_ETA, IF_REAL ,"Vds dependence of threshold voltage"), + IOP("delta", MOS9_MOD_DELTA, IF_REAL ,"Width effect on threshold"), + IOPR("input_delta", MOS9_DELTA, IF_REAL ,""), + IOP("theta", MOS9_MOD_THETA, IF_REAL ,"Vgs dependence on mobility"), + IOP("kappa", MOS9_MOD_KAPPA, IF_REAL ,"Kappa"), + IOPU("tnom", MOS9_MOD_TNOM, IF_REAL ,"Parameter measurement temperature"), + IOP("kf", MOS9_MOD_KF, IF_REAL ,"Flicker noise coefficient"), + IOP("af", MOS9_MOD_AF, IF_REAL ,"Flicker noise exponent") +}; + +char *MOS9names[] = { + "Drain", + "Gate", + "Source", + "Bulk" +}; + +int MOS9nSize = NUMELEMS(MOS9names); +int MOS9pTSize = NUMELEMS(MOS9pTable); +int MOS9mPTSize = NUMELEMS(MOS9mPTable); +int MOS9iSize = sizeof(MOS9instance); +int MOS9mSize = sizeof(MOS9model); diff --git a/src/spicelib/devices/mos9/mos9acld.c b/src/spicelib/devices/mos9/mos9acld.c new file mode 100644 index 000000000..730b11a2b --- /dev/null +++ b/src/spicelib/devices/mos9/mos9acld.c @@ -0,0 +1,128 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "mos9defs.h" +#include "sperror.h" +#include "suffix.h" + + +int +MOS9acLoad(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + MOS9model *model = (MOS9model *)inModel; + MOS9instance *here; + int xnrm; + int xrev; + double EffectiveLength; + double EffectiveWidth; + double xgs; + double xgd; + double xgb; + double xbd; + double xbs; + double capgs; + double capgd; + double capgb; + double GateBulkOverlapCap; + double GateDrainOverlapCap; + double GateSourceOverlapCap; + + for( ; model != NULL; model = model->MOS9nextModel) { + for(here = model->MOS9instances; here!= NULL; + here = here->MOS9nextInstance) { + + if (here->MOS9mode < 0) { + xnrm=0; + xrev=1; + } else { + xnrm=1; + xrev=0; + } + /* + * charge oriented model parameters + */ + EffectiveWidth=here->MOS9w-2*model->MOS9widthNarrow+ + model->MOS9widthAdjust; + EffectiveLength=here->MOS9l - 2*model->MOS9latDiff+ + model->MOS9lengthAdjust; + GateSourceOverlapCap = model->MOS9gateSourceOverlapCapFactor * + here->MOS9m * EffectiveWidth; + GateDrainOverlapCap = model->MOS9gateDrainOverlapCapFactor * + here->MOS9m * EffectiveWidth; + GateBulkOverlapCap = model->MOS9gateBulkOverlapCapFactor * + here->MOS9m * EffectiveLength; + + + /* + * meyer"s model parameters + */ + capgs = ( *(ckt->CKTstate0+here->MOS9capgs)+ + *(ckt->CKTstate0+here->MOS9capgs) + + GateSourceOverlapCap ); + capgd = ( *(ckt->CKTstate0+here->MOS9capgd)+ + *(ckt->CKTstate0+here->MOS9capgd) + + GateDrainOverlapCap ); + capgb = ( *(ckt->CKTstate0+here->MOS9capgb)+ + *(ckt->CKTstate0+here->MOS9capgb) + + GateBulkOverlapCap ); + xgs = capgs * ckt->CKTomega; + xgd = capgd * ckt->CKTomega; + xgb = capgb * ckt->CKTomega; + xbd = here->MOS9capbd * ckt->CKTomega; + xbs = here->MOS9capbs * ckt->CKTomega; + + /* + * load matrix + */ + + *(here->MOS9GgPtr +1) += xgd+xgs+xgb; + *(here->MOS9BbPtr +1) += xgb+xbd+xbs; + *(here->MOS9DPdpPtr +1) += xgd+xbd; + *(here->MOS9SPspPtr +1) += xgs+xbs; + *(here->MOS9GbPtr +1) -= xgb; + *(here->MOS9GdpPtr +1) -= xgd; + *(here->MOS9GspPtr +1) -= xgs; + *(here->MOS9BgPtr +1) -= xgb; + *(here->MOS9BdpPtr +1) -= xbd; + *(here->MOS9BspPtr +1) -= xbs; + *(here->MOS9DPgPtr +1) -= xgd; + *(here->MOS9DPbPtr +1) -= xbd; + *(here->MOS9SPgPtr +1) -= xgs; + *(here->MOS9SPbPtr +1) -= xbs; + *(here->MOS9DdPtr) += here->MOS9drainConductance; + *(here->MOS9SsPtr) += here->MOS9sourceConductance; + *(here->MOS9BbPtr) += here->MOS9gbd+here->MOS9gbs; + *(here->MOS9DPdpPtr) += here->MOS9drainConductance+ + here->MOS9gds+here->MOS9gbd+ + xrev*(here->MOS9gm+here->MOS9gmbs); + *(here->MOS9SPspPtr) += here->MOS9sourceConductance+ + here->MOS9gds+here->MOS9gbs+ + xnrm*(here->MOS9gm+here->MOS9gmbs); + *(here->MOS9DdpPtr) -= here->MOS9drainConductance; + *(here->MOS9SspPtr) -= here->MOS9sourceConductance; + *(here->MOS9BdpPtr) -= here->MOS9gbd; + *(here->MOS9BspPtr) -= here->MOS9gbs; + *(here->MOS9DPdPtr) -= here->MOS9drainConductance; + *(here->MOS9DPgPtr) += (xnrm-xrev)*here->MOS9gm; + *(here->MOS9DPbPtr) += -here->MOS9gbd+(xnrm-xrev)*here->MOS9gmbs; + *(here->MOS9DPspPtr) -= here->MOS9gds+ + xnrm*(here->MOS9gm+here->MOS9gmbs); + *(here->MOS9SPgPtr) -= (xnrm-xrev)*here->MOS9gm; + *(here->MOS9SPsPtr) -= here->MOS9sourceConductance; + *(here->MOS9SPbPtr) -= here->MOS9gbs+(xnrm-xrev)*here->MOS9gmbs; + *(here->MOS9SPdpPtr) -= here->MOS9gds+ + xrev*(here->MOS9gm+here->MOS9gmbs); + } + } + return(OK); +} diff --git a/src/spicelib/devices/mos9/mos9ask.c b/src/spicelib/devices/mos9/mos9ask.c new file mode 100644 index 000000000..a975adf22 --- /dev/null +++ b/src/spicelib/devices/mos9/mos9ask.c @@ -0,0 +1,444 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Mathew Lew and Thomas L. Quarles +Modified: Alan Gillespie +**********/ + +#include "ngspice.h" +#include +#include "const.h" +#include "ifsim.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "mos9defs.h" +#include "sperror.h" +#include "suffix.h" + +/*ARGSUSED*/ +int +MOS9ask(ckt,inst,which,value,select) + CKTcircuit *ckt; + GENinstance *inst; + int which; + IFvalue *value; + IFvalue *select; +{ + MOS9instance *here = (MOS9instance *)inst; + double vr; + double vi; + double sr; + double si; + double vm; + static char *msg = "Current and power not available for ac analysis"; + switch(which) { + case MOS9_TEMP: + value->rValue = here->MOS9temp-CONSTCtoK; + return(OK); + case MOS9_CGS: + value->rValue = 2* *(ckt->CKTstate0 + here->MOS9capgs); + return(OK); + case MOS9_CGD: + value->rValue = 2* *(ckt->CKTstate0 + here->MOS9capgd); + return(OK); + case MOS9_M: + value->rValue = here->MOS9m; + return(OK); + case MOS9_L: + value->rValue = here->MOS9l; + return(OK); + case MOS9_W: + value->rValue = here->MOS9w; + return(OK); + case MOS9_AS: + value->rValue = here->MOS9sourceArea; + return(OK); + case MOS9_AD: + value->rValue = here->MOS9drainArea; + return(OK); + case MOS9_PS: + value->rValue = here->MOS9sourcePerimiter; + return(OK); + case MOS9_PD: + value->rValue = here->MOS9drainPerimiter; + return(OK); + case MOS9_NRS: + value->rValue = here->MOS9sourceSquares; + return(OK); + case MOS9_NRD: + value->rValue = here->MOS9drainSquares; + return(OK); + case MOS9_OFF: + value->rValue = here->MOS9off; + return(OK); + case MOS9_IC_VBS: + value->rValue = here->MOS9icVBS; + return(OK); + case MOS9_IC_VDS: + value->rValue = here->MOS9icVDS; + return(OK); + case MOS9_IC_VGS: + value->rValue = here->MOS9icVGS; + return(OK); + case MOS9_DNODE: + value->iValue = here->MOS9dNode; + return(OK); + case MOS9_GNODE: + value->iValue = here->MOS9gNode; + return(OK); + case MOS9_SNODE: + value->iValue = here->MOS9sNode; + return(OK); + case MOS9_BNODE: + value->iValue = here->MOS9bNode; + return(OK); + case MOS9_DNODEPRIME: + value->iValue = here->MOS9dNodePrime; + return(OK); + case MOS9_SNODEPRIME: + value->iValue = here->MOS9sNodePrime; + return(OK); + case MOS9_SOURCECONDUCT: + value->rValue = here->MOS9sourceConductance; + return(OK); + case MOS9_DRAINCONDUCT: + value->rValue = here->MOS9drainConductance; + return(OK); + case MOS9_SOURCERESIST: + if (here->MOS9sNodePrime != here->MOS9sNode) + value->rValue = 1.0 / here->MOS9sourceConductance; + else + value->rValue = 0.0; + return(OK); + case MOS9_DRAINRESIST: + if (here->MOS9dNodePrime != here->MOS9dNode) + value->rValue = 1.0 / here->MOS9drainConductance; + else + value->rValue = 0.0; + return(OK); + case MOS9_VON: + value->rValue = here->MOS9von; + return(OK); + case MOS9_VDSAT: + value->rValue = here->MOS9vdsat; + return(OK); + case MOS9_SOURCEVCRIT: + value->rValue = here->MOS9sourceVcrit; + return(OK); + case MOS9_DRAINVCRIT: + value->rValue = here->MOS9drainVcrit; + return(OK); + case MOS9_CD: + value->rValue = here->MOS9cd; + return(OK); + case MOS9_CBS: + value->rValue = here->MOS9cbs; + return(OK); + case MOS9_CBD: + value->rValue = here->MOS9cbd; + return(OK); + case MOS9_GMBS: + value->rValue = here->MOS9gmbs; + return(OK); + case MOS9_GM: + value->rValue = here->MOS9gm; + return(OK); + case MOS9_GDS: + value->rValue = here->MOS9gds; + return(OK); + case MOS9_GBD: + value->rValue = here->MOS9gbd; + return(OK); + case MOS9_GBS: + value->rValue = here->MOS9gbs; + return(OK); + case MOS9_CAPBD: + value->rValue = here->MOS9capbd; + return(OK); + case MOS9_CAPBS: + value->rValue = here->MOS9capbs; + return(OK); + case MOS9_CAPZEROBIASBD: + value->rValue = here->MOS9Cbd; + return(OK); + case MOS9_CAPZEROBIASBDSW: + value->rValue = here->MOS9Cbdsw; + return(OK); + case MOS9_CAPZEROBIASBS: + value->rValue = here->MOS9Cbs; + return(OK); + case MOS9_CAPZEROBIASBSSW: + value->rValue = here->MOS9Cbssw; + return(OK); + case MOS9_VBD: + value->rValue = *(ckt->CKTstate0 + here->MOS9vbd); + return(OK); + case MOS9_VBS: + value->rValue = *(ckt->CKTstate0 + here->MOS9vbs); + return(OK); + case MOS9_VGS: + value->rValue = *(ckt->CKTstate0 + here->MOS9vgs); + return(OK); + case MOS9_VDS: + value->rValue = *(ckt->CKTstate0 + here->MOS9vds); + return(OK); + case MOS9_CAPGS: + value->rValue = 2* *(ckt->CKTstate0 + here->MOS9capgs); +/* add overlap capacitance */ + value->rValue += (here->MOS9modPtr->MOS9gateSourceOverlapCapFactor) + * here->MOS9m + * (here->MOS9w + +here->MOS9modPtr->MOS9widthAdjust + -2*(here->MOS9modPtr->MOS9widthNarrow)); + return(OK); + case MOS9_QGS: + value->rValue = *(ckt->CKTstate0 + here->MOS9qgs); + return(OK); + case MOS9_CQGS: + value->rValue = *(ckt->CKTstate0 + here->MOS9cqgs); + return(OK); + case MOS9_CAPGD: + value->rValue = 2* *(ckt->CKTstate0 + here->MOS9capgd); +/* add overlap capacitance */ + value->rValue += (here->MOS9modPtr->MOS9gateDrainOverlapCapFactor) + * here->MOS9m + * (here->MOS9w + +here->MOS9modPtr->MOS9widthAdjust + -2*(here->MOS9modPtr->MOS9widthNarrow)); + return(OK); + case MOS9_QGD: + value->rValue = *(ckt->CKTstate0 + here->MOS9qgd); + return(OK); + case MOS9_CQGD: + value->rValue = *(ckt->CKTstate0 + here->MOS9cqgd); + return(OK); + case MOS9_CAPGB: + value->rValue = 2* *(ckt->CKTstate0 + here->MOS9capgb); +/* add overlap capacitance */ + value->rValue += (here->MOS9modPtr->MOS9gateBulkOverlapCapFactor) + * here->MOS9m + * (here->MOS9l + +here->MOS9modPtr->MOS9lengthAdjust + -2*(here->MOS9modPtr->MOS9latDiff)); + return(OK); + case MOS9_QGB: + value->rValue = *(ckt->CKTstate0 + here->MOS9qgb); + return(OK); + case MOS9_CQGB: + value->rValue = *(ckt->CKTstate0 + here->MOS9cqgb); + return(OK); + case MOS9_QBD: + value->rValue = *(ckt->CKTstate0 + here->MOS9qbd); + return(OK); + case MOS9_CQBD: + value->rValue = *(ckt->CKTstate0 + here->MOS9cqbd); + return(OK); + case MOS9_QBS: + value->rValue = *(ckt->CKTstate0 + here->MOS9qbs); + return(OK); + case MOS9_CQBS: + value->rValue = *(ckt->CKTstate0 + here->MOS9cqbs); + return(OK); + case MOS9_L_SENS_DC: + if(ckt->CKTsenInfo){ + value->rValue = *(ckt->CKTsenInfo->SEN_Sap[select->iValue + 1]+ + here->MOS9senParmNo); + } + return(OK); + case MOS9_L_SENS_REAL: + if(ckt->CKTsenInfo){ + value->rValue = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->MOS9senParmNo); + } + return(OK); + case MOS9_L_SENS_IMAG: + if(ckt->CKTsenInfo){ + value->rValue = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->MOS9senParmNo); + } + return(OK); + case MOS9_L_SENS_MAG: + if(ckt->CKTsenInfo){ + vr = *(ckt->CKTrhsOld + select->iValue + 1); + vi = *(ckt->CKTirhsOld + select->iValue + 1); + vm = sqrt(vr*vr + vi*vi); + if(vm == 0){ + value->rValue = 0; + return(OK); + } + sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->MOS9senParmNo); + si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->MOS9senParmNo); + value->rValue = (vr * sr + vi * si)/vm; + } + return(OK); + case MOS9_L_SENS_PH: + if(ckt->CKTsenInfo){ + vr = *(ckt->CKTrhsOld + select->iValue + 1); + vi = *(ckt->CKTirhsOld + select->iValue + 1); + vm = vr*vr + vi*vi; + if(vm == 0){ + value->rValue = 0; + return(OK); + } + sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->MOS9senParmNo); + si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->MOS9senParmNo); + value->rValue = (vr * si - vi * sr)/vm; + } + return(OK); + case MOS9_L_SENS_CPLX: + if(ckt->CKTsenInfo){ + value->cValue.real= + *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->MOS9senParmNo); + value->cValue.imag= + *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->MOS9senParmNo); + } + return(OK); + case MOS9_W_SENS_DC: + if(ckt->CKTsenInfo){ + value->rValue = *(ckt->CKTsenInfo->SEN_Sap[select->iValue + 1]+ + here->MOS9senParmNo + here->MOS9sens_l); + } + return(OK); + case MOS9_W_SENS_REAL: + if(ckt->CKTsenInfo){ + value->rValue = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->MOS9senParmNo + here->MOS9sens_l); + } + return(OK); + case MOS9_W_SENS_IMAG: + if(ckt->CKTsenInfo){ + value->rValue = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->MOS9senParmNo + here->MOS9sens_l); + } + return(OK); + case MOS9_W_SENS_MAG: + if(ckt->CKTsenInfo){ + vr = *(ckt->CKTrhsOld + select->iValue + 1); + vi = *(ckt->CKTirhsOld + select->iValue + 1); + vm = sqrt(vr*vr + vi*vi); + if(vm == 0){ + value->rValue = 0; + return(OK); + } + sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->MOS9senParmNo + here->MOS9sens_l); + si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->MOS9senParmNo + here->MOS9sens_l); + value->rValue = (vr * sr + vi * si)/vm; + } + return(OK); + case MOS9_W_SENS_PH: + if(ckt->CKTsenInfo){ + vr = *(ckt->CKTrhsOld + select->iValue + 1); + vi = *(ckt->CKTirhsOld + select->iValue + 1); + vm = vr*vr + vi*vi; + if(vm == 0){ + value->rValue = 0; + return(OK); + } + sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->MOS9senParmNo + here->MOS9sens_l); + si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->MOS9senParmNo + here->MOS9sens_l); + value->rValue = (vr * si - vi * sr)/vm; + } + return(OK); + case MOS9_W_SENS_CPLX: + if(ckt->CKTsenInfo){ + value->cValue.real= + *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->MOS9senParmNo + here->MOS9sens_l); + value->cValue.imag= + *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->MOS9senParmNo + here->MOS9sens_l); + } + return(OK); + case MOS9_CB : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = MALLOC(strlen(msg)+1); + errRtn = "MOS9ask.c"; + strcpy(errMsg,msg); + return(E_ASKCURRENT); + } else { + value->rValue = here->MOS9cbd + here->MOS9cbs - *(ckt->CKTstate0 + + here->MOS9cqgb); + } + return(OK); + case MOS9_CG : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = MALLOC(strlen(msg)+1); + errRtn = "MOS9ask.c"; + strcpy(errMsg,msg); + return(E_ASKCURRENT); + } else if (ckt->CKTcurrentAnalysis & (DOING_DCOP | DOING_TRCV)) { + value->rValue = 0; + } else if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && + (ckt->CKTmode & MODETRANOP)) { + value->rValue = 0; + } else { + value->rValue = *(ckt->CKTstate0 + here->MOS9cqgb) + + *(ckt->CKTstate0 + here->MOS9cqgd) + *(ckt->CKTstate0 + + here->MOS9cqgs); + } + return(OK); + case MOS9_CS : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = MALLOC(strlen(msg)+1); + errRtn = "MOS9ask.c"; + strcpy(errMsg,msg); + return(E_ASKCURRENT); + } else { + value->rValue = -here->MOS9cd; + value->rValue -= here->MOS9cbd + here->MOS9cbs - + *(ckt->CKTstate0 + here->MOS9cqgb); + if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && + !(ckt->CKTmode & MODETRANOP)) { + value->rValue -= *(ckt->CKTstate0 + here->MOS9cqgb) + + *(ckt->CKTstate0 + here->MOS9cqgd) + + *(ckt->CKTstate0 + here->MOS9cqgs); + } + } + return(OK); + case MOS9_POWER : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = MALLOC(strlen(msg)+1); + errRtn = "MOS9ask.c"; + strcpy(errMsg,msg); + return(E_ASKPOWER); + } else { + double temp; + + value->rValue = here->MOS9cd * + *(ckt->CKTrhsOld + here->MOS9dNode); + value->rValue += (here->MOS9cbd + here->MOS9cbs - + *(ckt->CKTstate0 + here->MOS9cqgb)) * + *(ckt->CKTrhsOld + here->MOS9bNode); + if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && + !(ckt->CKTmode & MODETRANOP)) { + value->rValue += (*(ckt->CKTstate0 + here->MOS9cqgb) + + *(ckt->CKTstate0 + here->MOS9cqgd) + + *(ckt->CKTstate0 + here->MOS9cqgs)) * + *(ckt->CKTrhsOld + here->MOS9gNode); + } + temp = -here->MOS9cd; + temp -= here->MOS9cbd + here->MOS9cbs ; + if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && + !(ckt->CKTmode & MODETRANOP)) { + temp -= *(ckt->CKTstate0 + here->MOS9cqgb) + + *(ckt->CKTstate0 + here->MOS9cqgd) + + *(ckt->CKTstate0 + here->MOS9cqgs); + } + value->rValue += temp * *(ckt->CKTrhsOld + here->MOS9sNode); + } + return(OK); + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} + diff --git a/src/spicelib/devices/mos9/mos9conv.c b/src/spicelib/devices/mos9/mos9conv.c new file mode 100644 index 000000000..15d12daf6 --- /dev/null +++ b/src/spicelib/devices/mos9/mos9conv.c @@ -0,0 +1,104 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "mos9defs.h" +#include "sperror.h" + +#include "suffix.h" + +int +MOS9convTest(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + MOS9model *model = (MOS9model *)inModel; + MOS9instance *here; + double delvbs; + double delvbd; + double delvgs; + double delvds; + double delvgd; + double cbhat; + double cdhat; + double vbs; + double vbd; + double vgs; + double vds; + double vgd; + double vgdo; + double tol; + + for( ; model != NULL; model = model->MOS9nextModel) { + for(here = model->MOS9instances; here!= NULL; + here = here->MOS9nextInstance) { + + vbs = model->MOS9type * ( + *(ckt->CKTrhs+here->MOS9bNode) - + *(ckt->CKTrhs+here->MOS9sNodePrime)); + vgs = model->MOS9type * ( + *(ckt->CKTrhs+here->MOS9gNode) - + *(ckt->CKTrhs+here->MOS9sNodePrime)); + vds = model->MOS9type * ( + *(ckt->CKTrhs+here->MOS9dNodePrime) - + *(ckt->CKTrhs+here->MOS9sNodePrime)); + vbd=vbs-vds; + vgd=vgs-vds; + vgdo = *(ckt->CKTstate0 + here->MOS9vgs) - + *(ckt->CKTstate0 + here->MOS9vds); + delvbs = vbs - *(ckt->CKTstate0 + here->MOS9vbs); + delvbd = vbd - *(ckt->CKTstate0 + here->MOS9vbd); + delvgs = vgs - *(ckt->CKTstate0 + here->MOS9vgs); + delvds = vds - *(ckt->CKTstate0 + here->MOS9vds); + delvgd = vgd-vgdo; + + /* these are needed for convergence testing */ + + if (here->MOS9mode >= 0) { + cdhat= + here->MOS9cd- + here->MOS9gbd * delvbd + + here->MOS9gmbs * delvbs + + here->MOS9gm * delvgs + + here->MOS9gds * delvds ; + } else { + cdhat= + here->MOS9cd - + ( here->MOS9gbd - + here->MOS9gmbs) * delvbd - + here->MOS9gm * delvgd + + here->MOS9gds * delvds ; + } + cbhat= + here->MOS9cbs + + here->MOS9cbd + + here->MOS9gbd * delvbd + + here->MOS9gbs * delvbs ; + /* + * check convergence + */ + tol=ckt->CKTreltol*MAX(fabs(cdhat),fabs(here->MOS9cd))+ + ckt->CKTabstol; + if (fabs(cdhat-here->MOS9cd) >= tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue, we haven't converged */ + } else { + tol=ckt->CKTreltol* + MAX(fabs(cbhat),fabs(here->MOS9cbs+here->MOS9cbd)) + + ckt->CKTabstol; + if (fabs(cbhat-(here->MOS9cbs+here->MOS9cbd)) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue, we haven't converged*/ + } + } + } + } + return(OK); +} diff --git a/src/spicelib/devices/mos9/mos9defs.h b/src/spicelib/devices/mos9/mos9defs.h new file mode 100644 index 000000000..8c3b27bcc --- /dev/null +++ b/src/spicelib/devices/mos9/mos9defs.h @@ -0,0 +1,560 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ + +#ifndef MOS9 +#define MOS9 + +#include "ifsim.h" +#include "cktdefs.h" +#include "gendefs.h" +#include "complex.h" +#include "noisedef.h" + + /* declarations for level 9 MOSFETs */ + +/* information needed for each instance */ + +typedef struct sMOS9instance { + struct sMOS9model *MOS9modPtr; /* backpointer to model */ + struct sMOS9instance *MOS9nextInstance; /* pointer to next instance of + *current model*/ + IFuid MOS9name; /* pointer to character string naming this instance */ + int MOS9owner; /* number of owner process */ + int MOS9states; /* index into state table for this device */ + int MOS9dNode; /* number of the gate node of the mosfet */ + int MOS9gNode; /* number of the gate node of the mosfet */ + int MOS9sNode; /* number of the source node of the mosfet */ + int MOS9bNode; /* number of the bulk node of the mosfet */ + int MOS9dNodePrime; /* number of the internal drain node of the mosfet */ + int MOS9sNodePrime; /* number of the internal source node of the mosfet */ + + double MOS9m; /* parallel device multiplier */ + double MOS9l; /* the length of the channel region */ + double MOS9w; /* the width of the channel region */ + double MOS9drainArea; /* the area of the drain diffusion */ + double MOS9sourceArea; /* the area of the source diffusion */ + double MOS9drainSquares; /* the length of the drain in squares */ + double MOS9sourceSquares; /* the length of the source in squares */ + double MOS9drainPerimiter; + double MOS9sourcePerimiter; + double MOS9sourceConductance; /*conductance of source(or 0):set in setup*/ + double MOS9drainConductance; /*conductance of drain(or 0):set in setup*/ + double MOS9temp; /* operating temperature of this instance */ + + double MOS9tTransconductance; /* temperature corrected transconductance*/ + double MOS9tSurfMob; /* temperature corrected surface mobility */ + double MOS9tPhi; /* temperature corrected Phi */ + double MOS9tVto; /* temperature corrected Vto */ + double MOS9tSatCur; /* temperature corrected saturation Cur. */ + double MOS9tSatCurDens; /* temperature corrected saturation Cur. density*/ + double MOS9tCbd; /* temperature corrected B-D Capacitance */ + double MOS9tCbs; /* temperature corrected B-S Capacitance */ + double MOS9tCj; /* temperature corrected Bulk bottom Capacitance */ + double MOS9tCjsw; /* temperature corrected Bulk side Capacitance */ + double MOS9tBulkPot; /* temperature corrected Bulk potential */ + double MOS9tDepCap; /* temperature adjusted transition point in */ + /* the cureve matching Fc * Vj */ + double MOS9tVbi; /* temperature adjusted Vbi */ + + double MOS9icVBS; /* initial condition B-S voltage */ + double MOS9icVDS; /* initial condition D-S voltage */ + double MOS9icVGS; /* initial condition G-S voltage */ + double MOS9von; + double MOS9vdsat; + double MOS9sourceVcrit; /* vcrit for pos. vds */ + double MOS9drainVcrit; /* vcrit for neg. vds */ + double MOS9cd; + double MOS9cbs; + double MOS9cbd; + double MOS9gmbs; + double MOS9gm; + double MOS9gds; + double MOS9gbd; + double MOS9gbs; + double MOS9capbd; + double MOS9capbs; + double MOS9Cbd; + double MOS9Cbdsw; + double MOS9Cbs; + double MOS9Cbssw; + double MOS9f2d; + double MOS9f3d; + double MOS9f4d; + double MOS9f2s; + double MOS9f3s; + double MOS9f4s; + int MOS9mode; /* device mode : 1 = normal, -1 = inverse */ + + + unsigned MOS9off :1;/* non-zero to indicate device is off for dc analysis*/ + unsigned MOS9tempGiven :1; /* instance temperature specified */ + + unsigned MOS9mGiven :1; + + unsigned MOS9lGiven :1; + unsigned MOS9wGiven :1; + unsigned MOS9drainAreaGiven :1; + unsigned MOS9sourceAreaGiven :1; + unsigned MOS9drainSquaresGiven :1; + unsigned MOS9sourceSquaresGiven :1; + unsigned MOS9drainPerimiterGiven :1; + unsigned MOS9sourcePerimiterGiven :1; + unsigned MOS9dNodePrimeSet :1; + unsigned MOS9sNodePrimeSet :1; + unsigned MOS9icVBSGiven :1; + unsigned MOS9icVDSGiven :1; + unsigned MOS9icVGSGiven :1; + unsigned MOS9vonGiven :1; + unsigned MOS9vdsatGiven :1; + unsigned MOS9modeGiven :1; + + + double *MOS9DdPtr; /* pointer to sparse matrix element at + * (Drain node,drain node) */ + double *MOS9GgPtr; /* pointer to sparse matrix element at + * (gate node,gate node) */ + double *MOS9SsPtr; /* pointer to sparse matrix element at + * (source node,source node) */ + double *MOS9BbPtr; /* pointer to sparse matrix element at + * (bulk node,bulk node) */ + double *MOS9DPdpPtr; /* pointer to sparse matrix element at + * (drain prime node,drain prime node) */ + double *MOS9SPspPtr; /* pointer to sparse matrix element at + * (source prime node,source prime node) */ + double *MOS9DdpPtr; /* pointer to sparse matrix element at + * (drain node,drain prime node) */ + double *MOS9GbPtr; /* pointer to sparse matrix element at + * (gate node,bulk node) */ + double *MOS9GdpPtr; /* pointer to sparse matrix element at + * (gate node,drain prime node) */ + double *MOS9GspPtr; /* pointer to sparse matrix element at + * (gate node,source prime node) */ + double *MOS9SspPtr; /* pointer to sparse matrix element at + * (source node,source prime node) */ + double *MOS9BdpPtr; /* pointer to sparse matrix element at + * (bulk node,drain prime node) */ + double *MOS9BspPtr; /* pointer to sparse matrix element at + * (bulk node,source prime node) */ + double *MOS9DPspPtr; /* pointer to sparse matrix element at + * (drain prime node,source prime node) */ + double *MOS9DPdPtr; /* pointer to sparse matrix element at + * (drain prime node,drain node) */ + double *MOS9BgPtr; /* pointer to sparse matrix element at + * (bulk node,gate node) */ + double *MOS9DPgPtr; /* pointer to sparse matrix element at + * (drain prime node,gate node) */ + + double *MOS9SPgPtr; /* pointer to sparse matrix element at + * (source prime node,gate node) */ + double *MOS9SPsPtr; /* pointer to sparse matrix element at + * (source prime node,source node) */ + double *MOS9DPbPtr; /* pointer to sparse matrix element at + * (drain prime node,bulk node) */ + double *MOS9SPbPtr; /* pointer to sparse matrix element at + * (source prime node,bulk node) */ + double *MOS9SPdpPtr; /* pointer to sparse matrix element at + * (source prime node,drain prime node) */ + int MOS9senParmNo; /* parameter # for sensitivity use; + set equal to 0 if neither length + nor width of the mosfet is a design + parameter */ + unsigned MOS9sens_l :1; /* field which indicates whether + length of the mosfet is a design + parameter or not */ + unsigned MOS9sens_w :1; /* field which indicates whether + width of the mosfet is a design + parameter or not */ + unsigned MOS9senPertFlag :1; /* indictes whether the the parameter of + the particular instance is to be perturbed */ + double MOS9cgs; + double MOS9cgd; + double MOS9cgb; + double *MOS9sens; + +#define MOS9senGdpr MOS9sens +#define MOS9senGspr MOS9sens + 1 +#define MOS9senCgs MOS9sens + 2 /* contains pertured values of cgs */ +#define MOS9senCgd MOS9sens + 8 /* contains perturbed values of cgd*/ +#define MOS9senCgb MOS9sens + 14 /* contains perturbed values of cgb*/ +#define MOS9senCbd MOS9sens + 20 /* contains perturbed values of cbd*/ +#define MOS9senCbs MOS9sens + 26 /* contains perturbed values of cbs*/ +#define MOS9senGds MOS9sens + 32 /* contains perturbed values of gds*/ +#define MOS9senGbs MOS9sens + 38 /* contains perturbed values of gbs*/ +#define MOS9senGbd MOS9sens + 44 /* contains perturbed values of gbd*/ +#define MOS9senGm MOS9sens + 50 /* contains perturbed values of gm*/ +#define MOS9senGmbs MOS9sens + 56 /* contains perturbed values of gmbs*/ +#define MOS9dphigs_dl MOS9sens + 62 +#define MOS9dphigd_dl MOS9sens + 63 +#define MOS9dphigb_dl MOS9sens + 64 +#define MOS9dphibs_dl MOS9sens + 65 +#define MOS9dphibd_dl MOS9sens + 66 +#define MOS9dphigs_dw MOS9sens + 67 +#define MOS9dphigd_dw MOS9sens + 68 +#define MOS9dphigb_dw MOS9sens + 69 +#define MOS9dphibs_dw MOS9sens + 70 +#define MOS9dphibd_dw MOS9sens + 71 + + /* distortion stuff */ +/* + * naming convention: + * x = vgs + * y = vbs + * z = vds + * cdr = cdrain + */ + + +#define MOS9NDCOEFFS 30 + +#ifndef NODISTO + double MOS9dCoeffs[MOS9NDCOEFFS]; +#else /* NODISTO */ + double *MOS9dCoeffs; +#endif /* NODISTO */ + +#ifndef CONFIG + +#define capbs2 MOS9dCoeffs[0] +#define capbs3 MOS9dCoeffs[1] +#define capbd2 MOS9dCoeffs[2] +#define capbd3 MOS9dCoeffs[3] +#define gbs2 MOS9dCoeffs[4] +#define gbs3 MOS9dCoeffs[5] +#define gbd2 MOS9dCoeffs[6] +#define gbd3 MOS9dCoeffs[7] +#define capgb2 MOS9dCoeffs[8] +#define capgb3 MOS9dCoeffs[9] +#define cdr_x2 MOS9dCoeffs[10] +#define cdr_y2 MOS9dCoeffs[11] +#define cdr_z2 MOS9dCoeffs[12] +#define cdr_xy MOS9dCoeffs[13] +#define cdr_yz MOS9dCoeffs[14] +#define cdr_xz MOS9dCoeffs[15] +#define cdr_x3 MOS9dCoeffs[16] +#define cdr_y3 MOS9dCoeffs[17] +#define cdr_z3 MOS9dCoeffs[18] +#define cdr_x2z MOS9dCoeffs[19] +#define cdr_x2y MOS9dCoeffs[20] +#define cdr_y2z MOS9dCoeffs[21] +#define cdr_xy2 MOS9dCoeffs[22] +#define cdr_xz2 MOS9dCoeffs[23] +#define cdr_yz2 MOS9dCoeffs[24] +#define cdr_xyz MOS9dCoeffs[25] +#define capgs2 MOS9dCoeffs[26] +#define capgs3 MOS9dCoeffs[27] +#define capgd2 MOS9dCoeffs[28] +#define capgd3 MOS9dCoeffs[29] + +#endif + + /* end distortion coeffs. */ +/* indices to the array of MOSFET(3) noise sources */ + +#define MOS9RDNOIZ 0 +#define MOS9RSNOIZ 1 +#define MOS9IDNOIZ 2 +#define MOS9FLNOIZ 3 +#define MOS9TOTNOIZ 4 + +#define MOS9NSRCS 5 /* the number of MOSFET(9) noise sources */ + +#ifndef NONOISE + double MOS9nVar[NSTATVARS][MOS9NSRCS]; +#else /* NONOISE */ + double **MOS9nVar; +#endif /* NONOISE */ + +} MOS9instance ; + +#define MOS9vbd MOS9states+ 0 +#define MOS9vbs MOS9states+ 1 +#define MOS9vgs MOS9states+ 2 +#define MOS9vds MOS9states+ 3 + +/* meyer capacitances */ +#define MOS9capgs MOS9states+ 4 /* gate-source capacitor value */ +#define MOS9qgs MOS9states+ 5 /* gate-source capacitor charge */ +#define MOS9cqgs MOS9states+ 6 /* gate-source capacitor current */ + +#define MOS9capgd MOS9states+ 7 /* gate-drain capacitor value */ +#define MOS9qgd MOS9states+ 8 /* gate-drain capacitor charge */ +#define MOS9cqgd MOS9states+ 9 /* gate-drain capacitor current */ + +#define MOS9capgb MOS9states+ 10/* gate-bulk capacitor value */ +#define MOS9qgb MOS9states+ 11 /* gate-bulk capacitor charge */ +#define MOS9cqgb MOS9states+ 12 /* gate-bulk capacitor current */ + +/* diode capacitances */ +#define MOS9qbd MOS9states+ 13 /* bulk-drain capacitor charge */ +#define MOS9cqbd MOS9states+ 14 /* bulk-drain capacitor current */ + +#define MOS9qbs MOS9states+ 15 /* bulk-source capacitor charge */ +#define MOS9cqbs MOS9states+ 16 /* bulk-source capacitor current */ + +#define MOS9NUMSTATES 17 + + +#define MOS9sensxpgs MOS9states+17 /* charge sensitivities and their derivatives + +18 for the derivatives - pointer to the + beginning of the array */ +#define MOS9sensxpgd MOS9states+19 +#define MOS9sensxpgb MOS9states+21 +#define MOS9sensxpbs MOS9states+23 +#define MOS9sensxpbd MOS9states+25 + +#define MOS9numSenStates 10 + + +/* per model data */ + + /* NOTE: parameters marked 'input - use xxxx' are paramters for + * which a temperature correction is applied in MOS9temp, thus + * the MOS9xxxx value in the per-instance structure should be used + * instead in all calculations + */ + +typedef struct sMOS9model { /* model structure for a resistor */ + int MOS9modType; /* type index of this device type */ + struct sMOS9model *MOS9nextModel; /* pointer to next possible model + *in linked list */ + MOS9instance * MOS9instances; /* pointer to list of instances + * that have this model */ + IFuid MOS9modName; /* pointer to character string naming this model */ + int MOS9type; /* device type : 1 = nmos, -1 = pmos */ + double MOS9tnom; /* temperature at which parameters measured */ + double MOS9latDiff; + double MOS9lengthAdjust; /* New parm: mask adjustment to length */ + double MOS9widthNarrow; /* New parm to reduce effective width */ + double MOS9widthAdjust; /* New parm: mask adjustment to width */ + double MOS9delvt0; /* New parm: adjustment to calculated vtO */ + double MOS9jctSatCurDensity; /* input - use tSatCurDens*/ + double MOS9jctSatCur; /* input - use tSatCur instead */ + double MOS9drainResistance; + double MOS9sourceResistance; + double MOS9sheetResistance; + double MOS9transconductance; /* input - use tTransconductance */ + double MOS9gateSourceOverlapCapFactor; + double MOS9gateDrainOverlapCapFactor; + double MOS9gateBulkOverlapCapFactor; + double MOS9oxideCapFactor; + double MOS9vt0; /* input - use tVto */ + double MOS9capBD; /* input - use tCbs */ + double MOS9capBS; /* input - use tCbd */ + double MOS9bulkCapFactor; /* input - use tCj */ + double MOS9sideWallCapFactor; /* input - use tCjsw */ + double MOS9bulkJctPotential; /* input - use tBulkPot */ + double MOS9bulkJctBotGradingCoeff; + double MOS9bulkJctSideGradingCoeff; + double MOS9fwdCapDepCoeff; + double MOS9phi; /* input - use tPhi */ + double MOS9gamma; + double MOS9substrateDoping; + int MOS9gateType; + double MOS9surfaceStateDensity; + double MOS9oxideThickness; + double MOS9surfaceMobility; /* input - use tSurfMob */ + double MOS9eta; + double MOS9junctionDepth; + double MOS9coeffDepLayWidth; /* xd */ + double MOS9narrowFactor; /* delta */ + double MOS9delta; /* input delta */ + double MOS9fastSurfaceStateDensity; /* nfs */ + double MOS9theta; /* theta */ + double MOS9maxDriftVel; /* vmax */ + double MOS9alpha; /* alpha */ + double MOS9kappa; /* kappa */ + double MOS9fNcoef; + double MOS9fNexp; + + unsigned MOS9typeGiven :1; + unsigned MOS9latDiffGiven :1; + unsigned MOS9lengthAdjustGiven :1; + unsigned MOS9widthNarrowGiven :1; + unsigned MOS9widthAdjustGiven :1; + unsigned MOS9delvt0Given :1; + unsigned MOS9jctSatCurDensityGiven :1; + unsigned MOS9jctSatCurGiven :1; + unsigned MOS9drainResistanceGiven :1; + unsigned MOS9sourceResistanceGiven :1; + unsigned MOS9sheetResistanceGiven :1; + unsigned MOS9transconductanceGiven :1; + unsigned MOS9gateSourceOverlapCapFactorGiven :1; + unsigned MOS9gateDrainOverlapCapFactorGiven :1; + unsigned MOS9gateBulkOverlapCapFactorGiven :1; + unsigned MOS9vt0Given :1; + unsigned MOS9capBDGiven :1; + unsigned MOS9capBSGiven :1; + unsigned MOS9bulkCapFactorGiven :1; + unsigned MOS9sideWallCapFactorGiven :1; + unsigned MOS9bulkJctPotentialGiven :1; + unsigned MOS9bulkJctBotGradingCoeffGiven :1; + unsigned MOS9bulkJctSideGradingCoeffGiven :1; + unsigned MOS9fwdCapDepCoeffGiven :1; + unsigned MOS9phiGiven :1; + unsigned MOS9gammaGiven :1; + unsigned MOS9substrateDopingGiven :1; + unsigned MOS9gateTypeGiven :1; + unsigned MOS9surfaceStateDensityGiven :1; + unsigned MOS9oxideThicknessGiven :1; + unsigned MOS9surfaceMobilityGiven :1; + unsigned MOS9etaGiven :1; + unsigned MOS9junctionDepthGiven :1; + unsigned MOS9deltaGiven :1; /* delta */ + unsigned MOS9fastSurfaceStateDensityGiven :1; /* nfs */ + unsigned MOS9thetaGiven :1; /* theta */ + unsigned MOS9maxDriftVelGiven :1; /* vmax */ + unsigned MOS9kappaGiven :1; /* kappa */ + unsigned MOS9tnomGiven :1; /* Tnom was given? */ + unsigned MOS9fNcoefGiven :1; + unsigned MOS9fNexpGiven :1; + +} MOS9model; + +#ifndef NMOS +#define NMOS 1 +#define PMOS -1 +#endif /*NMOS*/ + +/* device parameters */ +#define MOS9_W 1 +#define MOS9_L 2 +#define MOS9_AS 3 +#define MOS9_AD 4 +#define MOS9_PS 5 +#define MOS9_PD 6 +#define MOS9_NRS 7 +#define MOS9_NRD 8 +#define MOS9_OFF 9 +#define MOS9_IC 10 +#define MOS9_IC_VBS 11 +#define MOS9_IC_VDS 12 +#define MOS9_IC_VGS 13 +#define MOS9_W_SENS 14 +#define MOS9_L_SENS 15 +#define MOS9_CB 16 +#define MOS9_CG 17 +#define MOS9_CS 18 +#define MOS9_POWER 19 +#define MOS9_CGS 20 +#define MOS9_CGD 21 +#define MOS9_DNODE 22 +#define MOS9_GNODE 23 +#define MOS9_SNODE 24 +#define MOS9_BNODE 25 +#define MOS9_DNODEPRIME 26 +#define MOS9_SNODEPRIME 27 +#define MOS9_SOURCECONDUCT 28 +#define MOS9_DRAINCONDUCT 29 +#define MOS9_VON 30 +#define MOS9_VDSAT 31 +#define MOS9_SOURCEVCRIT 32 +#define MOS9_DRAINVCRIT 33 +#define MOS9_CD 34 +#define MOS9_CBS 35 +#define MOS9_CBD 36 +#define MOS9_GMBS 37 +#define MOS9_GM 38 +#define MOS9_GDS 39 +#define MOS9_GBD 40 +#define MOS9_GBS 41 +#define MOS9_CAPBD 42 +#define MOS9_CAPBS 43 +#define MOS9_CAPZEROBIASBD 44 +#define MOS9_CAPZEROBIASBDSW 45 +#define MOS9_CAPZEROBIASBS 46 +#define MOS9_CAPZEROBIASBSSW 47 +#define MOS9_VBD 48 +#define MOS9_VBS 49 +#define MOS9_VGS 50 +#define MOS9_VDS 51 +#define MOS9_CAPGS 52 +#define MOS9_QGS 53 +#define MOS9_CQGS 54 +#define MOS9_CAPGD 55 +#define MOS9_QGD 56 +#define MOS9_CQGD 57 +#define MOS9_CAPGB 58 +#define MOS9_QGB 59 +#define MOS9_CQGB 60 +#define MOS9_QBD 61 +#define MOS9_CQBD 62 +#define MOS9_QBS 63 +#define MOS9_CQBS 64 +#define MOS9_W_SENS_REAL 65 +#define MOS9_W_SENS_IMAG 66 +#define MOS9_W_SENS_MAG 67 +#define MOS9_W_SENS_PH 68 +#define MOS9_W_SENS_CPLX 69 +#define MOS9_L_SENS_REAL 70 +#define MOS9_L_SENS_IMAG 71 +#define MOS9_L_SENS_MAG 72 +#define MOS9_L_SENS_PH 73 +#define MOS9_L_SENS_CPLX 74 +#define MOS9_W_SENS_DC 75 +#define MOS9_L_SENS_DC 76 +#define MOS9_TEMP 77 +#define MOS9_SOURCERESIST 78 +#define MOS9_DRAINRESIST 79 +#define MOS9_M 80 + +/* model parameters */ +#define MOS9_MOD_VTO 101 +#define MOS9_MOD_KP 102 +#define MOS9_MOD_GAMMA 103 +#define MOS9_MOD_PHI 104 +#define MOS9_MOD_RD 105 +#define MOS9_MOD_RS 106 +#define MOS9_MOD_CBD 107 +#define MOS9_MOD_CBS 108 +#define MOS9_MOD_IS 109 +#define MOS9_MOD_PB 110 +#define MOS9_MOD_CGSO 111 +#define MOS9_MOD_CGDO 112 +#define MOS9_MOD_CGBO 113 +#define MOS9_MOD_RSH 114 +#define MOS9_MOD_CJ 115 +#define MOS9_MOD_MJ 116 +#define MOS9_MOD_CJSW 117 +#define MOS9_MOD_MJSW 118 +#define MOS9_MOD_JS 119 +#define MOS9_MOD_TOX 120 +#define MOS9_MOD_LD 121 +#define MOS9_MOD_U0 122 +#define MOS9_MOD_FC 123 +#define MOS9_MOD_NSUB 124 +#define MOS9_MOD_TPG 125 +#define MOS9_MOD_NSS 126 +#define MOS9_MOD_ETA 127 +#define MOS9_MOD_DELTA 128 +#define MOS9_MOD_NFS 129 +#define MOS9_MOD_THETA 130 +#define MOS9_MOD_VMAX 131 +#define MOS9_MOD_KAPPA 132 +#define MOS9_MOD_NMOS 133 +#define MOS9_MOD_PMOS 134 +#define MOS9_MOD_XJ 135 +#define MOS9_MOD_UEXP 136 +#define MOS9_MOD_NEFF 137 +#define MOS9_MOD_XD 138 +#define MOS9_MOD_ALPHA 139 +#define MOS9_DELTA 140 +#define MOS9_MOD_TNOM 141 +#define MOS9_MOD_KF 142 +#define MOS9_MOD_AF 143 +#define MOS9_MOD_TYPE 144 +#define MOS9_MOD_XL 145 +#define MOS9_MOD_WD 146 +#define MOS9_MOD_XW 147 +#define MOS9_MOD_DELVTO 148 + +/* device questions */ + + +/* model questions */ + +#include "mos9ext.h" + +#endif /*MOS9*/ diff --git a/src/spicelib/devices/mos9/mos9del.c b/src/spicelib/devices/mos9/mos9del.c new file mode 100644 index 000000000..698c83195 --- /dev/null +++ b/src/spicelib/devices/mos9/mos9del.c @@ -0,0 +1,39 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "mos9defs.h" +#include "sperror.h" +#include "suffix.h" + + +int +MOS9delete(inModel,name,inst) + GENmodel *inModel; + IFuid name; + GENinstance **inst; +{ + MOS9model *model = (MOS9model *)inModel; + MOS9instance **fast = (MOS9instance **)inst; + MOS9instance **prev = NULL; + MOS9instance *here; + + for( ; model ; model = model->MOS9nextModel) { + prev = &(model->MOS9instances); + for(here = *prev; here ; here = *prev) { + if(here->MOS9name == name || (fast && here==*fast) ) { + *prev= here->MOS9nextInstance; + FREE(here); + return(OK); + } + prev = &(here->MOS9nextInstance); + } + } + return(E_NODEV); +} diff --git a/src/spicelib/devices/mos9/mos9dest.c b/src/spicelib/devices/mos9/mos9dest.c new file mode 100644 index 000000000..e5ad27659 --- /dev/null +++ b/src/spicelib/devices/mos9/mos9dest.c @@ -0,0 +1,40 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "mos9defs.h" +#include "suffix.h" + + +void +MOS9destroy(inModel) + GENmodel **inModel; +{ + MOS9model **model = (MOS9model **)inModel; + MOS9instance *here; + MOS9instance *prev = NULL; + MOS9model *mod = *model; + MOS9model *oldmod = NULL; + + for( ; mod ; mod = mod->MOS9nextModel) { + if(oldmod) FREE(oldmod); + oldmod = mod; + prev = (MOS9instance *)NULL; + for(here = mod->MOS9instances ; here ; here = here->MOS9nextInstance) { + if(prev){ + if(prev->MOS9sens) FREE(prev->MOS9sens); + FREE(prev); + } + prev = here; + } + if(prev) FREE(prev); + } + if(oldmod) FREE(oldmod); + *model = NULL; +} diff --git a/src/spicelib/devices/mos9/mos9dist.c b/src/spicelib/devices/mos9/mos9dist.c new file mode 100644 index 000000000..b66209533 --- /dev/null +++ b/src/spicelib/devices/mos9/mos9dist.c @@ -0,0 +1,1386 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Jaijeet S Roychowdhury +Modified: Alan Gillespie +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "mos9defs.h" +#include "sperror.h" +#include "distodef.h" +#include "suffix.h" + +int +MOS9disto(mode,genmodel,ckt) + GENmodel *genmodel; + CKTcircuit *ckt; + int mode; + +/* assuming here that ckt->CKTomega has been initialised to + * the correct value + */ +{ + MOS9model *model = (MOS9model *) genmodel; + DISTOAN* job = (DISTOAN*) ckt->CKTcurJob; + DpassStr pass; + double r1h1x,i1h1x; + double r1h1y,i1h1y; + double r1h1z, i1h1z; + double r1h2x, i1h2x; + double r1h2y, i1h2y; + double r1h2z, i1h2z; + double r1hm2x,i1hm2x; + double r1hm2y,i1hm2y; + double r1hm2z, i1hm2z; + double r2h11x,i2h11x; + double r2h11y,i2h11y; + double r2h11z, i2h11z; + double r2h1m2x,i2h1m2x; + double r2h1m2y,i2h1m2y; + double r2h1m2z, i2h1m2z; + double temp, itemp; + register MOS9instance *here; + +if (mode == D_SETUP) + return(MOS9dSetup(model,ckt)); + +if ((mode == D_TWOF1) || (mode == D_THRF1) || + (mode == D_F1PF2) || (mode == D_F1MF2) || + (mode == D_2F1MF2)) { + + /* loop through all the MOS9 models */ +for( ; model != NULL; model = model->MOS9nextModel ) { + + /* loop through all the instances of the model */ + for (here = model->MOS9instances; here != NULL ; + here=here->MOS9nextInstance) { + + + + /* loading starts here */ + + switch (mode) { + case D_TWOF1: + /* x = vgs, y = vbs z = vds */ + + /* getting first order (linear) Volterra kernel */ + r1h1x = *(job->r1H1ptr + (here->MOS9gNode)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i1h1x = *(job->i1H1ptr + (here->MOS9gNode)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r1h1y = *(job->r1H1ptr + (here->MOS9bNode)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i1h1y = *(job->i1H1ptr + (here->MOS9bNode)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r1h1z = *(job->r1H1ptr + (here->MOS9dNodePrime)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i1h1z = *(job->i1H1ptr + (here->MOS9dNodePrime)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + /* loading starts here */ + /* loading cdrain term */ + + temp = DFn2F1(here->cdr_x2, + here->cdr_y2, + here->cdr_z2, + here->cdr_xy, + here->cdr_yz, + here->cdr_xz, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z); + + itemp = DFi2F1(here->cdr_x2, + here->cdr_y2, + here->cdr_z2, + here->cdr_xy, + here->cdr_yz, + here->cdr_xz, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z); + + *(ckt->CKTrhs + (here->MOS9dNodePrime)) -= temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* cdrain term over */ + + /* loading gbs term */ + + temp = D1n2F1(here->gbs2, + r1h1y, + i1h1y); + + itemp = D1i2F1(here->gbs2, + r1h1y, + i1h1y); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* gbs over */ + + /* loading gbd term */ + + temp = D1n2F1(here->gbd2, + r1h1y - r1h1z, + i1h1y - i1h1z); + + itemp = D1i2F1(here->gbd2, + r1h1y - r1h1z, + i1h1y - i1h1z); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9dNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) += itemp; + + /* gbd over */ + + /* loading capgs term */ + + temp = -ckt->CKTomega * + D1i2F1(here->capgs2, + r1h1x, + i1h1x); + + itemp = ckt->CKTomega * + D1n2F1(here->capgs2, + r1h1x, + i1h1x); + + *(ckt->CKTrhs + (here->MOS9gNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9gNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* capgs over */ + + /* loading capgd term */ + + temp = -ckt->CKTomega * + D1i2F1(here->capgd2, + r1h1x - r1h1z, + i1h1x - i1h1z); + + itemp = ckt->CKTomega * + D1n2F1(here->capgd2, + r1h1x - r1h1z, + i1h1x - i1h1z); + + + *(ckt->CKTrhs + (here->MOS9gNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9gNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9dNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) += itemp; + + /* capgd over */ + /* loading capgb term */ + + temp = -ckt->CKTomega * + D1i2F1(here->capgb2, + r1h1x - r1h1y, + i1h1x - i1h1y); + + itemp = ckt->CKTomega * + D1n2F1(here->capgb2, + r1h1x - r1h1y, + i1h1x - i1h1y); + + *(ckt->CKTrhs + (here->MOS9gNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9gNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9bNode)) += temp; + *(ckt->CKTirhs + (here->MOS9bNode)) += itemp; + + /* capgb over */ + + /* loading capbs term */ + + temp = -ckt->CKTomega * + D1i2F1(here->capbs2, + r1h1y, + i1h1y); + + itemp = ckt->CKTomega * + D1n2F1(here->capbs2, + r1h1y, + i1h1y); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* capbs over */ + + /* loading capbd term */ + + temp = -ckt->CKTomega * + D1i2F1(here->capbd2, + r1h1y - r1h1z, + i1h1y - i1h1z); + + itemp = ckt->CKTomega * + D1n2F1(here->capbd2, + r1h1y - r1h1z, + i1h1y - i1h1z); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9dNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) += itemp; + + /* capbd over */ + /* all done */ + + break; + + case D_THRF1: + /* x = vgs, y = vbs z = vds */ + + /* getting first order (linear) Volterra kernel */ + r1h1x = *(job->r1H1ptr + (here->MOS9gNode)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i1h1x = *(job->i1H1ptr + (here->MOS9gNode)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r1h1y = *(job->r1H1ptr + (here->MOS9bNode)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i1h1y = *(job->i1H1ptr + (here->MOS9bNode)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r1h1z = *(job->r1H1ptr + (here->MOS9dNodePrime)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i1h1z = *(job->i1H1ptr + (here->MOS9dNodePrime)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r2h11x = *(job->r2H11ptr + (here->MOS9gNode)) - + *(job->r2H11ptr + (here->MOS9sNodePrime)); + i2h11x = *(job->i2H11ptr + (here->MOS9gNode)) - + *(job->i2H11ptr + (here->MOS9sNodePrime)); + + r2h11y = *(job->r2H11ptr + (here->MOS9bNode)) - + *(job->r2H11ptr + (here->MOS9sNodePrime)); + i2h11y = *(job->i2H11ptr + (here->MOS9bNode)) - + *(job->i2H11ptr + (here->MOS9sNodePrime)); + + r2h11z = *(job->r2H11ptr + (here->MOS9dNodePrime)) - + *(job->r2H11ptr + (here->MOS9sNodePrime)); + i2h11z = *(job->i2H11ptr + (here->MOS9dNodePrime)) - + *(job->i2H11ptr + (here->MOS9sNodePrime)); + /* loading starts here */ + /* loading cdrain term */ + + temp = DFn3F1(here->cdr_x2, + here->cdr_y2, + here->cdr_z2, + here->cdr_xy, + here->cdr_yz, + here->cdr_xz, + here->cdr_x3, + here->cdr_y3, + here->cdr_z3, + here->cdr_x2y, + here->cdr_x2z, + here->cdr_xy2, + here->cdr_y2z, + here->cdr_xz2, + here->cdr_yz2, + here->cdr_xyz, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r2h11x, + i2h11x, + r2h11y, + i2h11y, + r2h11z, + i2h11z); + itemp = DFi3F1(here->cdr_x2, + here->cdr_y2, + here->cdr_z2, + here->cdr_xy, + here->cdr_yz, + here->cdr_xz, + here->cdr_x3, + here->cdr_y3, + here->cdr_z3, + here->cdr_x2y, + here->cdr_x2z, + here->cdr_xy2, + here->cdr_y2z, + here->cdr_xz2, + here->cdr_yz2, + here->cdr_xyz, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r2h11x, + i2h11x, + r2h11y, + i2h11y, + r2h11z, + i2h11z); + + + *(ckt->CKTrhs + (here->MOS9dNodePrime)) -= temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* cdrain term over */ + + /* loading gbs term */ + + temp = D1n3F1(here->gbs2, + here->gbs3, + r1h1y, + i1h1y, + r2h11y, + i2h11y); + + + itemp = D1i3F1(here->gbs2, + here->gbs3, + r1h1y, + i1h1y, + r2h11y, + i2h11y); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* gbs over */ + + /* loading gbd term */ + + temp = D1n3F1(here->gbd2, + here->gbd3, + r1h1y - r1h1z, + i1h1y - i1h1z, + r2h11y - r2h11z, + i2h11y - i2h11z); + + itemp = D1i3F1(here->gbd2, + here->gbd3, + r1h1y - r1h1z, + i1h1y - i1h1z, + r2h11y - r2h11z, + i2h11y - i2h11z); + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9dNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) += itemp; + + /* gbd over */ + + /* loading capgs term */ + + temp = -ckt->CKTomega * + D1i3F1(here->capgs2, + here->capgs3, + r1h1x, + i1h1x, + r2h11x, + i2h11x); + + itemp = ckt->CKTomega * + D1n3F1(here->capgs2, + here->capgs3, + r1h1x, + i1h1x, + r2h11x, + i2h11x); + + *(ckt->CKTrhs + (here->MOS9gNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9gNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* capgs over */ + + /* loading capgd term */ + + temp = -ckt->CKTomega * + D1i3F1(here->capgd2, + here->capgd3, + r1h1x - r1h1z, + i1h1x - i1h1z, + r2h11x - r2h11z, + i2h11x - i2h11z); + + itemp = ckt->CKTomega * + D1n3F1(here->capgd2, + here->capgd3, + r1h1x - r1h1z, + i1h1x - i1h1z, + r2h11x - r2h11z, + i2h11x - i2h11z); + + + *(ckt->CKTrhs + (here->MOS9gNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9gNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9dNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) += itemp; + + /* capgd over */ + /* loading capgb term */ + + temp = -ckt->CKTomega * + D1i3F1(here->capgb2, + here->capgb3, + r1h1x - r1h1y, + i1h1x - i1h1y, + r2h11x - r2h11y, + i2h11x - i2h11y); + + itemp = ckt->CKTomega * + D1n3F1(here->capgb2, + here->capgb3, + r1h1x - r1h1y, + i1h1x - i1h1y, + r2h11x - r2h11y, + i2h11x - i2h11y); + + *(ckt->CKTrhs + (here->MOS9gNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9gNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9bNode)) += temp; + *(ckt->CKTirhs + (here->MOS9bNode)) += itemp; + + /* capgb over */ + + /* loading capbs term */ + + temp = -ckt->CKTomega * + D1i3F1(here->capbs2, + here->capbs3, + r1h1y, + i1h1y, + r2h11y, + i2h11y); + + itemp = ckt->CKTomega * + D1n3F1(here->capbs2, + here->capbs3, + r1h1y, + i1h1y, + r2h11y, + i2h11y); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* capbs over */ + + /* loading capbd term */ + + temp = -ckt->CKTomega * + D1i3F1(here->capbd2, + here->capbd3, + r1h1y - r1h1z, + i1h1y - i1h1z, + r2h11y - r2h11z, + i2h11y - i2h11z); + + itemp = ckt->CKTomega * + D1n3F1(here->capbd2, + here->capbd3, + r1h1y - r1h1z, + i1h1y - i1h1z, + r2h11y - r2h11z, + i2h11y - i2h11z); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9dNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) += itemp; + + /* capbd over */ + /* all done */ + + break; + case D_F1PF2: + /* x = vgs, y = vbs z = vds */ + + /* getting first order (linear) Volterra kernel */ + r1h1x = *(job->r1H1ptr + (here->MOS9gNode)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i1h1x = *(job->i1H1ptr + (here->MOS9gNode)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r1h1y = *(job->r1H1ptr + (here->MOS9bNode)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i1h1y = *(job->i1H1ptr + (here->MOS9bNode)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r1h1z = *(job->r1H1ptr + (here->MOS9dNodePrime)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i1h1z = *(job->i1H1ptr + (here->MOS9dNodePrime)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r1h2x = *(job->r1H2ptr + (here->MOS9gNode)) - + *(job->r1H2ptr + (here->MOS9sNodePrime)); + i1h2x = *(job->i1H2ptr + (here->MOS9gNode)) - + *(job->i1H2ptr + (here->MOS9sNodePrime)); + + r1h2y = *(job->r1H2ptr + (here->MOS9bNode)) - + *(job->r1H2ptr + (here->MOS9sNodePrime)); + i1h2y = *(job->i1H2ptr + (here->MOS9bNode)) - + *(job->i1H2ptr + (here->MOS9sNodePrime)); + + r1h2z = *(job->r1H2ptr + (here->MOS9dNodePrime)) - + *(job->r1H2ptr + (here->MOS9sNodePrime)); + i1h2z = *(job->i1H2ptr + (here->MOS9dNodePrime)) - + *(job->i1H2ptr + (here->MOS9sNodePrime)); + + /* loading starts here */ + /* loading cdrain term */ + + temp = DFnF12(here->cdr_x2, + here->cdr_y2, + here->cdr_z2, + here->cdr_xy, + here->cdr_yz, + here->cdr_xz, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r1h2x, + i1h2x, + r1h2y, + i1h2y, + r1h2z, + i1h2z); + + itemp = DFiF12(here->cdr_x2, + here->cdr_y2, + here->cdr_z2, + here->cdr_xy, + here->cdr_yz, + here->cdr_xz, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r1h2x, + i1h2x, + r1h2y, + i1h2y, + r1h2z, + i1h2z); + + *(ckt->CKTrhs + (here->MOS9dNodePrime)) -= temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* cdrain term over */ + + /* loading gbs term */ + + temp = D1nF12(here->gbs2, + r1h1y, + i1h1y, + r1h2y, + i1h2y); + + itemp = D1iF12(here->gbs2, + r1h1y, + i1h1y, + r1h2y, + i1h2y); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* gbs over */ + + /* loading gbd term */ + + temp = D1nF12(here->gbd2, + r1h1y - r1h1z, + i1h1y - i1h1z, + r1h2y - r1h2z, + i1h2y - i1h2z); + + itemp = D1iF12(here->gbd2, + r1h1y - r1h1z, + i1h1y - i1h1z, + r1h2y - r1h2z, + i1h2y - i1h2z); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9dNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) += itemp; + + /* gbd over */ + + /* loading capgs term */ + + temp = -ckt->CKTomega * + D1iF12(here->capgs2, + r1h1x, + i1h1x, + r1h2x, + i1h2x); + + itemp = ckt->CKTomega * + D1nF12(here->capgs2, + r1h1x, + i1h1x, + r1h2x, + i1h2x); + + *(ckt->CKTrhs + (here->MOS9gNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9gNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* capgs over */ + + /* loading capgd term */ + + temp = -ckt->CKTomega * + D1iF12(here->capgd2, + r1h1x - r1h1z, + i1h1x - i1h1z, + r1h2x - r1h2z, + i1h2x - i1h2z); + + itemp = ckt->CKTomega * + D1nF12(here->capgd2, + r1h1x - r1h1z, + i1h1x - i1h1z, + r1h2x - r1h2z, + i1h2x - i1h2z); + + + *(ckt->CKTrhs + (here->MOS9gNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9gNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9dNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) += itemp; + + /* capgd over */ + /* loading capgb term */ + + temp = -ckt->CKTomega * + D1iF12(here->capgb2, + r1h1x - r1h1y, + i1h1x - i1h1y, + r1h2x - r1h2y, + i1h2x - i1h2y); + + itemp = ckt->CKTomega * + D1nF12(here->capgb2, + r1h1x - r1h1y, + i1h1x - i1h1y, + r1h2x - r1h2y, + i1h2x - i1h2y); + + *(ckt->CKTrhs + (here->MOS9gNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9gNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9bNode)) += temp; + *(ckt->CKTirhs + (here->MOS9bNode)) += itemp; + + /* capgb over */ + + /* loading capbs term */ + + temp = -ckt->CKTomega * + D1iF12(here->capbs2, + r1h1y, + i1h1y, + r1h2y, + i1h2y); + + itemp = ckt->CKTomega * + D1nF12(here->capbs2, + r1h1y, + i1h1y, + r1h2y, + i1h2y); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* capbs over */ + + /* loading capbd term */ + + temp = -ckt->CKTomega * + D1iF12(here->capbd2, + r1h1y - r1h1z, + i1h1y - i1h1z, + r1h2y - r1h2z, + i1h2y - i1h2z); + + itemp = ckt->CKTomega * + D1nF12(here->capbd2, + r1h1y - r1h1z, + i1h1y - i1h1z, + r1h2y - r1h2z, + i1h2y - i1h2z); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9dNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) += itemp; + + /* capbd over */ + /* all done */ + + break; + case D_F1MF2: + /* x = vgs, y = vbs z = vds */ + + /* getting first order (linear) Volterra kernel */ + r1h1x = *(job->r1H1ptr + (here->MOS9gNode)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i1h1x = *(job->i1H1ptr + (here->MOS9gNode)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r1h1y = *(job->r1H1ptr + (here->MOS9bNode)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i1h1y = *(job->i1H1ptr + (here->MOS9bNode)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r1h1z = *(job->r1H1ptr + (here->MOS9dNodePrime)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i1h1z = *(job->i1H1ptr + (here->MOS9dNodePrime)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r1hm2x = *(job->r1H2ptr + (here->MOS9gNode)) - + *(job->r1H2ptr + (here->MOS9sNodePrime)); + i1hm2x = -(*(job->i1H2ptr + (here->MOS9gNode)) - + *(job->i1H2ptr + (here->MOS9sNodePrime))); + + r1hm2y = *(job->r1H2ptr + (here->MOS9bNode)) - + *(job->r1H2ptr + (here->MOS9sNodePrime)); + i1hm2y = -(*(job->i1H2ptr + (here->MOS9bNode)) - + *(job->i1H2ptr + (here->MOS9sNodePrime))); + + r1hm2z = *(job->r1H2ptr + (here->MOS9dNodePrime)) - + *(job->r1H2ptr + (here->MOS9sNodePrime)); + i1hm2z = -(*(job->i1H2ptr + (here->MOS9dNodePrime)) - + *(job->i1H2ptr + (here->MOS9sNodePrime))); + + /* loading starts here */ + /* loading cdrain term */ + + temp = DFnF12(here->cdr_x2, + here->cdr_y2, + here->cdr_z2, + here->cdr_xy, + here->cdr_yz, + here->cdr_xz, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r1hm2x, + i1hm2x, + r1hm2y, + i1hm2y, + r1hm2z, + i1hm2z); + + itemp = DFiF12(here->cdr_x2, + here->cdr_y2, + here->cdr_z2, + here->cdr_xy, + here->cdr_yz, + here->cdr_xz, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r1hm2x, + i1hm2x, + r1hm2y, + i1hm2y, + r1hm2z, + i1hm2z); + + *(ckt->CKTrhs + (here->MOS9dNodePrime)) -= temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* cdrain term over */ + + /* loading gbs term */ + + temp = D1nF12(here->gbs2, + r1h1y, + i1h1y, + r1hm2y, + i1hm2y); + + itemp = D1iF12(here->gbs2, + r1h1y, + i1h1y, + r1hm2y, + i1hm2y); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* gbs over */ + + /* loading gbd term */ + + temp = D1nF12(here->gbd2, + r1h1y - r1h1z, + i1h1y - i1h1z, + r1hm2y - r1hm2z, + i1hm2y - i1hm2z); + + itemp = D1iF12(here->gbd2, + r1h1y - r1h1z, + i1h1y - i1h1z, + r1hm2y - r1hm2z, + i1hm2y - i1hm2z); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9dNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) += itemp; + + /* gbd over */ + + /* loading capgs term */ + + temp = -ckt->CKTomega * + D1iF12(here->capgs2, + r1h1x, + i1h1x, + r1hm2x, + i1hm2x); + + itemp = ckt->CKTomega * + D1nF12(here->capgs2, + r1h1x, + i1h1x, + r1hm2x, + i1hm2x); + + *(ckt->CKTrhs + (here->MOS9gNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9gNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* capgs over */ + + /* loading capgd term */ + + temp = -ckt->CKTomega * + D1iF12(here->capgd2, + r1h1x - r1h1z, + i1h1x - i1h1z, + r1hm2x - r1hm2z, + i1hm2x - i1hm2z); + + itemp = ckt->CKTomega * + D1nF12(here->capgd2, + r1h1x - r1h1z, + i1h1x - i1h1z, + r1hm2x - r1hm2z, + i1hm2x - i1hm2z); + + + *(ckt->CKTrhs + (here->MOS9gNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9gNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9dNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) += itemp; + + /* capgd over */ + /* loading capgb term */ + + temp = -ckt->CKTomega * + D1iF12(here->capgb2, + r1h1x - r1h1y, + i1h1x - i1h1y, + r1hm2x - r1hm2y, + i1hm2x - i1hm2y); + + itemp = ckt->CKTomega * + D1nF12(here->capgb2, + r1h1x - r1h1y, + i1h1x - i1h1y, + r1hm2x - r1hm2y, + i1hm2x - i1hm2y); + + *(ckt->CKTrhs + (here->MOS9gNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9gNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9bNode)) += temp; + *(ckt->CKTirhs + (here->MOS9bNode)) += itemp; + + /* capgb over */ + + /* loading capbs term */ + + temp = -ckt->CKTomega * + D1iF12(here->capbs2, + r1h1y, + i1h1y, + r1hm2y, + i1hm2y); + + itemp = ckt->CKTomega * + D1nF12(here->capbs2, + r1h1y, + i1h1y, + r1hm2y, + i1hm2y); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* capbs over */ + + /* loading capbd term */ + + temp = -ckt->CKTomega * + D1iF12(here->capbd2, + r1h1y - r1h1z, + i1h1y - i1h1z, + r1hm2y - r1hm2z, + i1hm2y - i1hm2z); + + itemp = ckt->CKTomega * + D1nF12(here->capbd2, + r1h1y - r1h1z, + i1h1y - i1h1z, + r1hm2y - r1hm2z, + i1hm2y - i1hm2z); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9dNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) += itemp; + + /* capbd over */ + /* all done */ + + break; + case D_2F1MF2: + /* x = vgs, y = vbs z = vds */ + + /* getting first order (linear) Volterra kernel */ + r1h1x = *(job->r1H1ptr + (here->MOS9gNode)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i1h1x = *(job->i1H1ptr + (here->MOS9gNode)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r1h1y = *(job->r1H1ptr + (here->MOS9bNode)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i1h1y = *(job->i1H1ptr + (here->MOS9bNode)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r1h1z = *(job->r1H1ptr + (here->MOS9dNodePrime)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i1h1z = *(job->i1H1ptr + (here->MOS9dNodePrime)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r1hm2x = *(job->r1H2ptr + (here->MOS9gNode)) - + *(job->r1H2ptr + (here->MOS9sNodePrime)); + i1hm2x = -(*(job->i1H2ptr + (here->MOS9gNode)) - + *(job->i1H2ptr + (here->MOS9sNodePrime))); + + r1hm2y = *(job->r1H2ptr + (here->MOS9bNode)) - + *(job->r1H2ptr + (here->MOS9sNodePrime)); + i1hm2y = -(*(job->i1H2ptr + (here->MOS9bNode)) - + *(job->i1H2ptr + (here->MOS9sNodePrime))); + + r1hm2z = *(job->r1H2ptr + (here->MOS9dNodePrime)) - + *(job->r1H2ptr + (here->MOS9sNodePrime)); + i1hm2z = -(*(job->i1H2ptr + (here->MOS9dNodePrime)) - + *(job->i1H2ptr + (here->MOS9sNodePrime))); + + r2h11x = *(job->r1H1ptr + (here->MOS9gNode)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i2h11x = *(job->i1H1ptr + (here->MOS9gNode)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r2h11y = *(job->r1H1ptr + (here->MOS9bNode)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i2h11y = *(job->i1H1ptr + (here->MOS9bNode)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r2h11z = *(job->r1H1ptr + (here->MOS9dNodePrime)) - + *(job->r1H1ptr + (here->MOS9sNodePrime)); + i2h11z = *(job->i1H1ptr + (here->MOS9dNodePrime)) - + *(job->i1H1ptr + (here->MOS9sNodePrime)); + + r2h1m2x = *(job->r2H1m2ptr + (here->MOS9gNode)) - + *(job->r2H1m2ptr + (here->MOS9sNodePrime)); + i2h1m2x = *(job->i2H1m2ptr + (here->MOS9gNode)) - + *(job->i2H1m2ptr + (here->MOS9sNodePrime)); + + r2h1m2y = *(job->r2H1m2ptr + (here->MOS9bNode)) - + *(job->r2H1m2ptr + (here->MOS9sNodePrime)); + i2h1m2y = *(job->i2H1m2ptr + (here->MOS9bNode)) - + *(job->i2H1m2ptr + (here->MOS9sNodePrime)); + +r2h1m2z = *(job->r2H1m2ptr + (here->MOS9dNodePrime)) - + *(job->r2H1m2ptr + (here->MOS9sNodePrime)); +i2h1m2z = *(job->i2H1m2ptr + (here->MOS9dNodePrime)) - + *(job->i2H1m2ptr + (here->MOS9sNodePrime)); + + /* loading starts here */ + /* loading cdrain term */ + +pass.cxx = here->cdr_x2; +pass.cyy = here->cdr_y2; +pass.czz = here->cdr_z2; +pass.cxy = here->cdr_xy; +pass.cyz = here->cdr_yz; +pass.cxz = here->cdr_xz; +pass.cxxx = here->cdr_x3; +pass.cyyy = here->cdr_y3; +pass.czzz = here->cdr_z3; +pass.cxxy = here->cdr_x2y; +pass.cxxz = here->cdr_x2z; +pass.cxyy = here->cdr_xy2; +pass.cyyz = here->cdr_y2z; +pass.cxzz = here->cdr_xz2; +pass.cyzz = here->cdr_yz2; +pass.cxyz = here->cdr_xyz; +pass.r1h1x = r1h1x; +pass.i1h1x = i1h1x; +pass.r1h1y = r1h1y; +pass.i1h1y = i1h1y; +pass.r1h1z = r1h1z; +pass.i1h1z = i1h1z; +pass.r1h2x = r1hm2x; +pass.i1h2x = i1hm2x; +pass.r1h2y = r1hm2y; +pass.i1h2y = i1hm2y; +pass.r1h2z = r1hm2z; +pass.i1h2z = i1hm2z; +pass.r2h11x = r2h11x; +pass.i2h11x = i2h11x; +pass.r2h11y = r2h11y; +pass.i2h11y = i2h11y; +pass.r2h11z = r2h11z; +pass.i2h11z = i2h11z; +pass.h2f1f2x = r2h1m2x; +pass.ih2f1f2x = i2h1m2x; +pass.h2f1f2y = r2h1m2y; +pass.ih2f1f2y = i2h1m2y; +pass.h2f1f2z = r2h1m2z; +pass.ih2f1f2z = i2h1m2z; + temp = DFn2F12(&pass); + + itemp = DFi2F12(&pass); + + + *(ckt->CKTrhs + (here->MOS9dNodePrime)) -= temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* cdrain term over */ + + /* loading gbs term */ + + temp = D1n2F12(here->gbs2, + here->gbs3, + r1h1y, + i1h1y, + r1hm2y, + i1hm2y, + r2h11y, + i2h11y, + r2h1m2y, + i2h1m2y); + + + + itemp = D1i2F12(here->gbs2, + here->gbs3, + r1h1y, + i1h1y, + r1hm2y, + i1hm2y, + r2h11y, + i2h11y, + r2h1m2y, + i2h1m2y); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* gbs over */ + + /* loading gbd term */ + + temp = D1n2F12(here->gbd2, + here->gbd3, + r1h1y - r1h1z, + i1h1y - i1h1z, + r1hm2y - r1hm2z, + i1hm2y - i1hm2z, + r2h11y - r2h11z, + i2h11y - i2h11z, + r2h1m2y - r2h1m2z, + i2h1m2y - i2h1m2z); + + itemp = D1i2F12(here->gbd2, + here->gbd3, + r1h1y - r1h1z, + i1h1y - i1h1z, + r1hm2y - r1hm2z, + i1hm2y - i1hm2z, + r2h11y - r2h11z, + i2h11y - i2h11z, + r2h1m2y - r2h1m2z, + i2h1m2y - i2h1m2z); + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9dNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) += itemp; + + /* gbd over */ + + /* loading capgs term */ + + temp = -ckt->CKTomega * + D1i2F12(here->capgs2, + here->capgs3, + r1h1x, + i1h1x, + r1hm2x, + i1hm2x, + r2h11x, + i2h11x, + r2h1m2x, + i2h1m2x); + + itemp = ckt->CKTomega * + D1n2F12(here->capgs2, + here->capgs3, + r1h1x, + i1h1x, + r1hm2x, + i1hm2x, + r2h11x, + i2h11x, + r2h1m2x, + i2h1m2x); + + *(ckt->CKTrhs + (here->MOS9gNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9gNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* capgs over */ + + /* loading capgd term */ + + temp = -ckt->CKTomega * + D1i2F12(here->capgd2, + here->capgd3, + r1h1x - r1h1z, + i1h1x - i1h1z, + r1hm2x - r1hm2z, + i1hm2x - i1hm2z, + r2h11x - r2h11z, + i2h11x - i2h11z, + r2h1m2x - r2h1m2z, + i2h1m2x - i2h1m2z); + + itemp = ckt->CKTomega * + D1n2F12(here->capgd2, + here->capgd3, + r1h1x - r1h1z, + i1h1x - i1h1z, + r1hm2x - r1hm2z, + i1hm2x - i1hm2z, + r2h11x - r2h11z, + i2h11x - i2h11z, + r2h1m2x - r2h1m2z, + i2h1m2x - i2h1m2z); + + + *(ckt->CKTrhs + (here->MOS9gNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9gNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9dNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) += itemp; + + /* capgd over */ + /* loading capgb term */ + + temp = -ckt->CKTomega * + D1i2F12(here->capgb2, + here->capgb3, + r1h1x - r1h1y, + i1h1x - i1h1y, + r1hm2x - r1hm2y, + i1hm2x - i1hm2y, + r2h11x - r2h11y, + i2h11x - i2h11y, + r2h1m2x - r2h1m2y, + i2h1m2x - i2h1m2y); + + itemp = ckt->CKTomega * + D1n2F12(here->capgb2, + here->capgb3, + r1h1x - r1h1y, + i1h1x - i1h1y, + r1hm2x - r1hm2y, + i1hm2x - i1hm2y, + r2h11x - r2h11y, + i2h11x - i2h11y, + r2h1m2x - r2h1m2y, + i2h1m2x - i2h1m2y); + + *(ckt->CKTrhs + (here->MOS9gNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9gNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9bNode)) += temp; + *(ckt->CKTirhs + (here->MOS9bNode)) += itemp; + + /* capgb over */ + + /* loading capbs term */ + + temp = -ckt->CKTomega * + D1i2F12(here->capbs2, + here->capbs3, + r1h1y, + i1h1y, + r1hm2y, + i1hm2y, + r2h11y, + i2h11y, + r2h1m2y, + i2h1m2y); + + itemp = ckt->CKTomega * + D1n2F12(here->capbs2, + here->capbs3, + r1h1y, + i1h1y, + r1hm2y, + i1hm2y, + r2h11y, + i2h11y, + r2h1m2y, + i2h1m2y); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9sNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9sNodePrime)) += itemp; + + /* capbs over */ + + /* loading capbd term */ + + temp = -ckt->CKTomega * + D1i2F12(here->capbd2, + here->capbd3, + r1h1y - r1h1z, + i1h1y - i1h1z, + r1hm2y - r1hm2z, + i1hm2y - i1hm2z, + r2h11y - r2h11z, + i2h11y - i2h11z, + r2h1m2y - r2h1m2z, + i2h1m2y - i2h1m2z); + + itemp = ckt->CKTomega * + D1n2F12(here->capbd2, + here->capbd3, + r1h1y - r1h1z, + i1h1y - i1h1z, + r1hm2y - r1hm2z, + i1hm2y - i1hm2z, + r2h11y - r2h11z, + i2h11y - i2h11z, + r2h1m2y - r2h1m2z, + i2h1m2y - i2h1m2z); + + + *(ckt->CKTrhs + (here->MOS9bNode)) -= temp; + *(ckt->CKTirhs + (here->MOS9bNode)) -= itemp; + *(ckt->CKTrhs + (here->MOS9dNodePrime)) += temp; + *(ckt->CKTirhs + (here->MOS9dNodePrime)) += itemp; + + /* capbd over */ + /* all done */ + + break; + default: +; + } + } +} +return(OK); +} + else + return(E_BADPARM); +} diff --git a/src/spicelib/devices/mos9/mos9dset.c b/src/spicelib/devices/mos9/mos9dset.c new file mode 100644 index 000000000..da335548b --- /dev/null +++ b/src/spicelib/devices/mos9/mos9dset.c @@ -0,0 +1,980 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Jaijeet S Roychowdhury +Modified: Alan Gillespie +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "devdefs.h" +#include "mos9defs.h" +#include "trandefs.h" +#include "distodef.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + +int +MOS9dSetup(inModel,ckt) + GENmodel *inModel; + register CKTcircuit *ckt; + /* actually load the current value into the + * sparse matrix previously provided + */ +{ + register MOS9model *model = (MOS9model *)inModel; + register MOS9instance *here; + double Beta; + double DrainSatCur; + double EffectiveLength; + double EffectiveWidth; + double GateBulkOverlapCap; + double GateDrainOverlapCap; + double GateSourceOverlapCap; + double OxideCap; + double SourceSatCur; + double arg; + double cdrain; + double evbs; + double sarg; + double sargsw; + double lvgs; + double vbd; + double vbs; + double vds; + double vdsat; + double vgb; + double vgd; + double vgs; + double von; + double lcapgs2,lcapgs3; /* total gate-source capacitance */ + double lcapgd2,lcapgd3; /* total gate-drain capacitance */ + double lcapgb2,lcapgb3; /* total gate-bulk capacitance */ + double lgbs, lgbs2, lgbs3; + double lgbd, lgbd2, lgbd3; + double gm2, gb2, gds2, gmb, gmds, gbds; + double gm3, gb3, gds3, gm2ds, gm2b, gb2ds, gbds2, gmb2, gmds2, gmbds; + double lcapbd, lcapbd2, lcapbd3; + double lcapbs, lcapbs2, lcapbs3; + double ebd; + double vt; /* vt at instance temperature */ + Dderivs d_cdrain; + + + + /* loop through all the MOS9 device models */ +next: for( ; model != NULL; model = model->MOS9nextModel ) { + + /* loop through all the instances of the model */ + for (here = model->MOS9instances; here != NULL ; + here=here->MOS9nextInstance) { + + vt = CONSTKoverQ * here->MOS9temp; + + + /* 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 + */ + + EffectiveWidth=here->MOS9w-2*model->MOS9widthNarrow+ + model->MOS9widthAdjust; + EffectiveLength=here->MOS9l - 2*model->MOS9latDiff+ + model->MOS9lengthAdjust; + + if( (here->MOS9tSatCurDens == 0) || + (here->MOS9drainArea == 0) || + (here->MOS9sourceArea == 0)) { + DrainSatCur = here->MOS9m * here->MOS9tSatCur; + SourceSatCur = here->MOS9m * here->MOS9tSatCur; + } else { + DrainSatCur = here->MOS9tSatCurDens * + here->MOS9m * here->MOS9drainArea; + SourceSatCur = here->MOS9tSatCurDens * + here->MOS9m * here->MOS9sourceArea; + } + GateSourceOverlapCap = model->MOS9gateSourceOverlapCapFactor * + here->MOS9m * EffectiveWidth; + GateDrainOverlapCap = model->MOS9gateDrainOverlapCapFactor * + here->MOS9m * EffectiveWidth; + GateBulkOverlapCap = model->MOS9gateBulkOverlapCapFactor * + here->MOS9m * EffectiveLength; + Beta = here->MOS9tTransconductance * here->MOS9m * + EffectiveWidth/EffectiveLength; + OxideCap = model->MOS9oxideCapFactor * EffectiveLength * + here->MOS9m * EffectiveWidth; + + + /* + * 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 + */ + + + /* general iteration */ + + vbs = model->MOS9type * ( + *(ckt->CKTrhsOld+here->MOS9bNode) - + *(ckt->CKTrhsOld+here->MOS9sNodePrime)); + vgs = model->MOS9type * ( + *(ckt->CKTrhsOld+here->MOS9gNode) - + *(ckt->CKTrhsOld+here->MOS9sNodePrime)); + vds = model->MOS9type * ( + *(ckt->CKTrhsOld+here->MOS9dNodePrime) - + *(ckt->CKTrhsOld+here->MOS9sNodePrime)); + + /* now some common crunching for some more useful quantities */ + + + + /* + * now all the preliminaries are over - we can start doing the + * real work + */ + vbd = vbs - vds; + vgd = vgs - vds; + vgb = vgs - vbs; + + /* bulk-source and bulk-drain doides + * here we just evaluate the ideal diode current and the + * correspoinding derivative (conductance). + */ +next1: if(vbs <= 0) { + lgbs = SourceSatCur/vt; + lgbs += ckt->CKTgmin; + lgbs2 = lgbs3 = 0; + } else { + evbs = exp(MIN(MAX_EXP_ARG,vbs/vt)); + lgbs = SourceSatCur*evbs/vt + ckt->CKTgmin; + lgbs2 = model->MOS9type *0.5 * (lgbs - ckt->CKTgmin)/vt; + lgbs3 = model->MOS9type *lgbs2/(vt*3); + + } + if(vbd <= 0) { + lgbd = DrainSatCur/vt; + lgbd += ckt->CKTgmin; + lgbd2 = lgbd3 = 0; + } else { + ebd = exp(MIN(MAX_EXP_ARG,vbd/vt)); + lgbd = DrainSatCur*ebd/vt +ckt->CKTgmin; + lgbd2 = model->MOS9type *0.5 * (lgbd - ckt->CKTgmin)/vt; + lgbd3 = model->MOS9type *lgbd2/(vt*3); + } + + + /* now to determine whether the user was able to correctly + * identify the source and drain of his device + */ + if(vds >= 0) { + /* normal mode */ + here->MOS9mode = 1; + } else { + /* inverse mode */ + here->MOS9mode = -1; + } + + { + /* + * 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 + */ + + /* + 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 sqphis; /* square root of phi */ + double wps; + double oneoverxj; /* 1/junction depth */ + double xjonxl; /* junction depth/effective length */ + double djonxj; + double wponxj; + double arga; + double argb; + double argc; + double gammas; + double fbodys; + double fbody; + double onfbdy; + double qbonco; + double vbix; + double wconxj; + double vth; + double csonco; + double cdonco; + double vgsx; + double onfg; + double fgate; + double us; + double xn; + double vdsc; + double onvdsc; + double vdsx; + double cdnorm; + double cdo; + double fdrain; + double gdsat; + double cdsat; + double emax; + double delxl; + double dlonxl; + double xlfact; + double ondvt; + double onxn; + double wfact; + double fshort; + double lvds, lvbs, lvbd; + Dderivs d_onxn, d_ondvt, d_wfact, d_MOS9gds; + Dderivs d_emax, d_delxl, d_dlonxl, d_xlfact; + Dderivs d_cdonco, d_fdrain, d_cdsat, d_gdsat; + Dderivs d_vdsx, d_cdo, d_cdnorm, d_Beta, d_dummy; + Dderivs d_vdsc, d_onvdsc, d_arga, d_argb; + Dderivs d_onfg, d_fgate, d_us, d_vgsx; + Dderivs d_von, d_xn, d_vth, d_onfbdy, d_qbonco, d_vbix; + Dderivs d_argc, d_fshort, d_gammas, d_fbodys, d_fbody; + Dderivs d_wps, d_wconxj, d_wponxj; + Dderivs d_phibs, d_sqphbs; + Dderivs d_p, d_q, d_r, d_zero, d_vdsat; + + /* + * bypasses the computation of charges + */ + if (here->MOS9mode == 1) { + lvgs = vgs; + lvds = vds; + lvbs = vbs; + lvbd = vbd; + } else { + lvgs = vgd; + lvds = -vds; + lvbs = vbd; + lvbd = vbs; + } + + /* + * reference cdrain equations to source and + * charge equations to bulk + */ +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_p2r = 0.0; +d_p.d3_p2q = 0.0; +d_p.d3_q2r = 0.0; +d_p.d3_pq2 = 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); + EqualDeriv(&d_r,&d_p); + EqualDeriv(&d_zero,&d_p); + d_q.d1_p = d_r.d1_p = d_zero.d1_p = 0.0; + d_q.d1_q = d_r.d1_r = 1.0; + vdsat = 0.0; + EqualDeriv(&d_vdsat,&d_zero); + oneoverxl = 1.0/EffectiveLength;/*const*/ + eta = model->MOS9eta * 8.15e-22/(model->MOS9oxideCapFactor* + EffectiveLength*EffectiveLength*EffectiveLength);/*const*/ + /* + *.....square root term + */ + if ( lvbs <= 0.0 ) { + phibs = here->MOS9tPhi-lvbs; + EqualDeriv(&d_phibs,&d_q); + d_phibs.value = lvbs; + TimesDeriv(&d_phibs,&d_phibs,-1.0); + d_phibs.value += here->MOS9tPhi; + sqphbs = sqrt(phibs); + SqrtDeriv(&d_sqphbs,&d_phibs); + } else { + sqphis = sqrt(here->MOS9tPhi);/*const*/ + /*sqphs3 = here->MOS9tPhi*sqphis;const*/ + sqphbs = sqphis/(1.0+lvbs/ + (here->MOS9tPhi+here->MOS9tPhi)); + EqualDeriv(&d_sqphbs,&d_q); d_sqphbs.value = lvbs; + TimesDeriv(&d_sqphbs,&d_sqphbs,1/(here->MOS9tPhi+here->MOS9tPhi)); + d_sqphbs.value += 1.0; + InvDeriv(&d_sqphbs,&d_sqphbs); + TimesDeriv(&d_sqphbs,&d_sqphbs,sqphis); + phibs = sqphbs*sqphbs; + MultDeriv(&d_phibs,&d_sqphbs,&d_sqphbs); + } + /* + *.....short channel effect factor + */ + if ( (model->MOS9junctionDepth != 0.0) && + (model->MOS9coeffDepLayWidth != 0.0) ) { + wps = model->MOS9coeffDepLayWidth*sqphbs; + TimesDeriv(&d_wps,&d_sqphbs,model->MOS9coeffDepLayWidth); + oneoverxj = 1.0/model->MOS9junctionDepth;/*const*/ + xjonxl = model->MOS9junctionDepth*oneoverxl;/*const*/ + djonxj = model->MOS9latDiff*oneoverxj;/*const*/ + wponxj = wps*oneoverxj; + TimesDeriv(&d_wponxj,&d_wps,oneoverxj); + wconxj = coeff0+coeff1*wponxj+coeff2*wponxj*wponxj; + TimesDeriv(&d_wconxj,&d_wponxj,coeff2); + d_wconxj.value += coeff1; + MultDeriv(&d_wconxj,&d_wconxj,&d_wponxj); + d_wconxj.value += coeff0; + arga = wconxj + djonxj; + EqualDeriv(&d_arga,&d_wconxj); d_arga.value += djonxj; + argc = wponxj/(1.0+wponxj); + EqualDeriv(&d_argc,&d_wponxj); + d_argc.value += 1.0; + InvDeriv(&d_argc,&d_argc); + MultDeriv(&d_argc,&d_argc,&d_wponxj); + argb = sqrt(1.0-argc*argc); + MultDeriv(&d_argb,&d_argc,&d_argc); + TimesDeriv(&d_argb,&d_argb,-1.0); + d_argb.value += 1.0; + SqrtDeriv(&d_argb,&d_argb); + + fshort = 1.0-xjonxl*(arga*argb-djonxj); + MultDeriv(&d_fshort,&d_arga,&d_argb); + d_fshort.value -= djonxj; + TimesDeriv(&d_fshort,&d_fshort,-xjonxl); + d_fshort.value += 1.0; + } else { + fshort = 1.0; + EqualDeriv(&d_fshort,&d_zero); + d_fshort.value = 1.0; + + } + /* + *.....body effect + */ + gammas = model->MOS9gamma*fshort; + TimesDeriv(&d_gammas,&d_fshort,model->MOS9gamma); + fbodys = 0.5*gammas/(sqphbs+sqphbs); + DivDeriv(&d_fbodys,&d_gammas,&d_sqphbs); + TimesDeriv(&d_fbodys,&d_fbodys,0.25); + fbody = fbodys+model->MOS9narrowFactor/EffectiveWidth; + EqualDeriv(&d_fbody,&d_fbodys); + d_fbody.value += fbody - fbodys; + + onfbdy = 1.0/(1.0+fbody); + EqualDeriv(&d_onfbdy,&d_fbody); + d_onfbdy.value += 1.0; + InvDeriv(&d_onfbdy,&d_onfbdy); + qbonco =gammas*sqphbs+model->MOS9narrowFactor*phibs/EffectiveWidth; + EqualDeriv(&d_dummy,&d_phibs); + TimesDeriv(&d_dummy,&d_dummy,model-> + MOS9narrowFactor*EffectiveWidth); + MultDeriv(&d_qbonco,&d_gammas,&d_sqphbs); + PlusDeriv(&d_qbonco,&d_qbonco,&d_dummy); + /* + *.....static feedback effect + */ + vbix = here->MOS9tVbi*model->MOS9type-eta*(lvds); + EqualDeriv(&d_vbix,&d_r); d_vbix.value = vbix; + d_vbix.d1_r = -eta; + /* + *.....threshold voltage + */ + vth = vbix+qbonco; + PlusDeriv(&d_vth,&d_vbix,&d_qbonco); + /* + *.....joint weak inversion and strong inversion + */ + von = vth; + EqualDeriv(&d_von,&d_vth); + if ( model->MOS9fastSurfaceStateDensity != 0.0 ) { + csonco = CHARGE*model->MOS9fastSurfaceStateDensity * + 1e4 /*(cm**2/m**2)*/ *EffectiveLength*EffectiveWidth * + here->MOS9m/OxideCap; /*const*/ + cdonco = 0.5*qbonco/phibs; + DivDeriv(&d_cdonco,&d_qbonco,&d_phibs); + TimesDeriv(&d_cdonco,&d_cdonco,0.5); + xn = 1.0+csonco+cdonco; + EqualDeriv(&d_xn,&d_cdonco); + d_xn.value += 1.0 + csonco; + von = vth+vt*xn; + TimesDeriv(&d_von,&d_xn,vt); + PlusDeriv(&d_von,&d_von,&d_vth); + + + } else { + /* + *.....cutoff region + */ + if ( lvgs <= von ) { + cdrain = 0.0; + EqualDeriv(&d_cdrain,&d_zero); + goto innerline1000; + } + } + /* + *.....device is on + */ + vgsx = MAX(lvgs,von); +if (lvgs >= von) { +EqualDeriv(&d_vgsx,&d_p); +d_vgsx.value = lvgs; +} else { +EqualDeriv(&d_vgsx,&d_von); +} + /* + *.....mobility modulation by gate voltage + */ + onfg = 1.0+model->MOS9theta*(vgsx-vth); + TimesDeriv(&d_onfg,&d_vth,-1.0); + PlusDeriv(&d_onfg,&d_onfg,&d_vgsx); + TimesDeriv(&d_onfg,&d_onfg,model->MOS9theta); + d_onfg.value += 1.0; + fgate = 1.0/onfg; + InvDeriv(&d_fgate,&d_onfg); + us = here->MOS9tSurfMob * 1e-4 /*(m**2/cm**2)*/ *fgate; + TimesDeriv(&d_us,&d_fgate,here->MOS9tSurfMob * 1e-4); + /* + *.....saturation voltage + */ + vdsat = (vgsx-vth)*onfbdy; + TimesDeriv(&d_vdsat,&d_vth, -1.0); + PlusDeriv(&d_vdsat,&d_vdsat,&d_vgsx); + MultDeriv(&d_vdsat,&d_vdsat,&d_onfbdy); + if ( model->MOS9maxDriftVel <= 0.0 ) { + } else { + vdsc = EffectiveLength*model->MOS9maxDriftVel/us; + InvDeriv(&d_vdsc,&d_us); + TimesDeriv(&d_vdsc,&d_vdsc,EffectiveLength*model->MOS9maxDriftVel); + onvdsc = 1.0/vdsc; + InvDeriv(&d_onvdsc,&d_vdsc); + arga = (vgsx-vth)*onfbdy; + /* note arga = vdsat at this point */ + EqualDeriv(&d_arga,&d_vdsat); + argb = sqrt(arga*arga+vdsc*vdsc); + MultDeriv(&d_dummy,&d_arga,&d_arga); + MultDeriv(&d_argb,&d_vdsc,&d_vdsc); + PlusDeriv(&d_argb,&d_argb,&d_dummy); + SqrtDeriv(&d_argb,&d_argb); + vdsat = arga+vdsc-argb; + TimesDeriv(&d_vdsat,&d_argb,-1.0); + PlusDeriv(&d_vdsat,&d_vdsat,&d_vdsc); + PlusDeriv(&d_vdsat,&d_vdsat,&d_arga); + } + /* + *.....current factors in linear region + */ + vdsx = MIN((lvds),vdsat); +if (lvds < vdsat) { +EqualDeriv(&d_vdsx,&d_r); +d_vdsx.value = lvds; +} else { +EqualDeriv(&d_vdsx,&d_vdsat); +} + + if ( vdsx == 0.0 ) goto line900; + cdo = vgsx-vth-0.5*(1.0+fbody)*vdsx; + EqualDeriv(&d_cdo,&d_fbody); + d_cdo.value += 1.0; + MultDeriv(&d_cdo,&d_cdo,&d_vdsx); + TimesDeriv(&d_cdo,&d_cdo,0.5); + PlusDeriv(&d_cdo,&d_cdo,&d_vth); + TimesDeriv(&d_cdo,&d_cdo,-1.0); + PlusDeriv(&d_cdo,&d_cdo,&d_vgsx); + + + /* + *.....normalized drain current + */ + cdnorm = cdo*vdsx; + MultDeriv(&d_cdnorm,&d_cdo,&d_vdsx); + /* + *.....drain current without velocity saturation effect + */ +/* Beta is a constant till now */ + Beta = Beta*fgate; + TimesDeriv(&d_Beta,&d_fgate,Beta); + cdrain = Beta*cdnorm; + MultDeriv(&d_cdrain,&d_Beta,&d_cdnorm); + /* + *.....velocity saturation factor + */ + if ( model->MOS9maxDriftVel != 0.0 ) { + fdrain = 1.0/(1.0+vdsx*onvdsc); + MultDeriv(&d_fdrain,&d_vdsx,&d_onvdsc); + d_fdrain.value += 1.0; + InvDeriv(&d_fdrain,&d_fdrain); + /* + *.....drain current + */ + cdrain = fdrain*cdrain; + MultDeriv(&d_cdrain,&d_cdrain,&d_fdrain); + Beta = Beta*fdrain; + MultDeriv(&d_Beta,&d_Beta,&d_fdrain); + + } + /* + *.....channel length modulation + */ + if ( (lvds) <= vdsat ) goto line700; + if ( model->MOS9maxDriftVel == 0.0 ) goto line510; + if (model->MOS9alpha == 0.0) goto line700; + cdsat = cdrain; + EqualDeriv(&d_cdsat,&d_cdrain); + gdsat = cdsat*(1.0-fdrain)*onvdsc; + TimesDeriv(&d_dummy,&d_fdrain,-1.0); + d_dummy.value += 1.0; + MultDeriv(&d_gdsat,&d_cdsat,&d_dummy); + MultDeriv(&d_gdsat,&d_gdsat,&d_onvdsc); + gdsat = MAX(1.0e-12,gdsat); + if (gdsat == 1.0e-12) { + EqualDeriv(&d_gdsat,&d_zero); + d_gdsat.value = gdsat; + } + + emax = cdsat*oneoverxl/gdsat; + DivDeriv(&d_emax,&d_cdsat,&d_gdsat); + TimesDeriv(&d_emax,&d_emax,oneoverxl); + + + arga = 0.5*emax*model->MOS9alpha; + TimesDeriv(&d_arga,&d_emax,0.5*model->MOS9alpha); + argc = model->MOS9kappa*model->MOS9alpha;/*const*/ + argb = sqrt(arga*arga+argc*((lvds)-vdsat)); + TimesDeriv(&d_dummy,&d_vdsat,-1.0); + d_dummy.value += lvds; + d_dummy.d1_r += 1.0; + TimesDeriv(&d_argb,&d_dummy,argc); + MultDeriv(&d_dummy,&d_arga,&d_arga); + PlusDeriv(&d_argb,&d_argb,&d_dummy); + SqrtDeriv(&d_argb,&d_argb); + delxl = argb-arga; + TimesDeriv(&d_delxl,&d_arga,-1.0); + PlusDeriv(&d_delxl,&d_argb,&d_delxl); + goto line520; +line510: + delxl = sqrt(model->MOS9kappa*((lvds)-vdsat)*model->MOS9alpha); + TimesDeriv(&d_delxl,&d_vdsat,-1.0); + d_delxl.value += lvds; + d_delxl.d1_r += 1.0; + TimesDeriv(&d_delxl,&d_delxl,model->MOS9kappa*model->MOS9alpha); + SqrtDeriv(&d_delxl,&d_delxl); + + /* + *.....punch through approximation + */ +line520: + if ( delxl > (0.5*EffectiveLength) ) { + delxl = EffectiveLength - (EffectiveLength*EffectiveLength/ + delxl*0.25); + InvDeriv(&d_delxl,&d_delxl); + TimesDeriv(&d_delxl,&d_delxl,-EffectiveLength*EffectiveLength*0.25); + d_delxl.value += EffectiveLength; + } + /* + *.....saturation region + */ + dlonxl = delxl*oneoverxl; + TimesDeriv(&d_dlonxl,&d_delxl,oneoverxl); + xlfact = 1.0/(1.0-dlonxl); + TimesDeriv(&d_xlfact,&d_dlonxl,-1.0); + d_xlfact.value += 1.0; + InvDeriv(&d_xlfact,&d_xlfact); + + cdrain = cdrain*xlfact; + MultDeriv(&d_cdrain,&d_cdrain,&d_xlfact); + /* + *.....finish strong inversion case + */ +line700: + if ( lvgs < von ) { + /* + *.....weak inversion + */ + onxn = 1.0/xn; + InvDeriv(&d_onxn,&d_xn); + ondvt = onxn/vt; + TimesDeriv(&d_ondvt,&d_onxn,1/vt); + wfact = exp( (lvgs-von)*ondvt ); + TimesDeriv(&d_wfact,&d_von,-1.0); + d_wfact.value += lvgs; + d_wfact.d1_p += 1.0; + MultDeriv(&d_wfact,&d_wfact,&d_ondvt); + ExpDeriv(&d_wfact,&d_wfact); + cdrain = cdrain*wfact; + MultDeriv(&d_cdrain,&d_cdrain,&d_wfact); + } + /* + *.....charge computation + */ + goto innerline1000; + /* + *.....special case of vds = 0.0d0 + */ + +line900: + Beta = Beta*fgate; + /* Beta is still a constant */ + TimesDeriv(&d_Beta,&d_fgate,Beta); + cdrain = 0.0; + EqualDeriv(&d_cdrain,&d_zero); + here->MOS9gds = Beta*(vgsx-vth); + TimesDeriv(&d_MOS9gds,&d_vth,-1.0); + PlusDeriv(&d_MOS9gds,&d_MOS9gds,&d_vgsx); + MultDeriv(&d_MOS9gds,&d_MOS9gds,&d_Beta); + if ( (model->MOS9fastSurfaceStateDensity != 0.0) && + (lvgs < von) ) { + here->MOS9gds *=exp((lvgs-von)/(vt*xn)); + TimesDeriv(&d_dummy,&d_von,-1.0); + d_dummy.value += lvgs; + d_dummy.d1_p += 1.0; + DivDeriv(&d_dummy,&d_dummy,&d_xn); + TimesDeriv(&d_dummy,&d_dummy,1/vt); + ExpDeriv(&d_dummy,&d_dummy); + MultDeriv(&d_MOS9gds,&d_MOS9gds,&d_dummy); + } + d_cdrain.d1_r = d_MOS9gds.value; + d_cdrain.d2_r2 = d_MOS9gds.d1_r; + d_cdrain.d3_r3 = d_MOS9gds.d2_r2; + + + +innerline1000:; + /* + *.....done + */ + } + + + /* + * COMPUTE EQUIVALENT DRAIN CURRENT SOURCE + */ + /* + * 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 + */ + if (vbs < here->MOS9tDepCap){ + arg=1-vbs/here->MOS9tBulkPot; + /* + * 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->MOS9bulkJctBotGradingCoeff == + model->MOS9bulkJctSideGradingCoeff) { + if(model->MOS9bulkJctBotGradingCoeff == .5) { + sarg = sargsw = 1/sqrt(arg); + } else { + sarg = sargsw = + exp(-model->MOS9bulkJctBotGradingCoeff* + log(arg)); + } + } else { + if(model->MOS9bulkJctBotGradingCoeff == .5) { + sarg = 1/sqrt(arg); + } else { +#endif /*NOSQRT*/ + sarg = exp(-model->MOS9bulkJctBotGradingCoeff* + log(arg)); +#ifndef NOSQRT + } + if(model->MOS9bulkJctSideGradingCoeff == .5) { + sargsw = 1/sqrt(arg); + } else { +#endif /*NOSQRT*/ + sargsw =exp(-model->MOS9bulkJctSideGradingCoeff* + log(arg)); +#ifndef NOSQRT + } + } +#endif /*NOSQRT*/ + lcapbs=here->MOS9Cbs*sarg+ + here->MOS9Cbssw*sargsw; + lcapbs2 = model->MOS9type*0.5/here->MOS9tBulkPot*( + here->MOS9Cbs*model->MOS9bulkJctBotGradingCoeff* + sarg/arg + here->MOS9Cbssw* + model->MOS9bulkJctSideGradingCoeff*sargsw/arg); + lcapbs3 = here->MOS9Cbs*sarg* + model->MOS9bulkJctBotGradingCoeff* + (model->MOS9bulkJctBotGradingCoeff+1); + lcapbs3 += here->MOS9Cbssw*sargsw* + model->MOS9bulkJctSideGradingCoeff* + (model->MOS9bulkJctSideGradingCoeff+1); + lcapbs3 = lcapbs3/(6*here->MOS9tBulkPot* + here->MOS9tBulkPot*arg*arg); + } else { + /* *(ckt->CKTstate0 + here->MOS9qbs)= here->MOS9f4s + + vbs*(here->MOS9f2s+vbs*(here->MOS9f3s/2));*/ + lcapbs=here->MOS9f2s+here->MOS9f3s*vbs; + lcapbs2 = 0.5*here->MOS9f3s; + lcapbs3 = 0; + } + if (vbd < here->MOS9tDepCap) { + arg=1-vbd/here->MOS9tBulkPot; + /* + * 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->MOS9bulkJctBotGradingCoeff == .5 && + model->MOS9bulkJctSideGradingCoeff == .5) { + sarg = sargsw = 1/sqrt(arg); + } else { + if(model->MOS9bulkJctBotGradingCoeff == .5) { + sarg = 1/sqrt(arg); + } else { +#endif /*NOSQRT*/ + sarg = exp(-model->MOS9bulkJctBotGradingCoeff* + log(arg)); +#ifndef NOSQRT + } + if(model->MOS9bulkJctSideGradingCoeff == .5) { + sargsw = 1/sqrt(arg); + } else { +#endif /*NOSQRT*/ + sargsw =exp(-model->MOS9bulkJctSideGradingCoeff* + log(arg)); +#ifndef NOSQRT + } + } +#endif /*NOSQRT*/ + lcapbd=here->MOS9Cbd*sarg+ + here->MOS9Cbdsw*sargsw; + lcapbd2 = model->MOS9type*0.5/here->MOS9tBulkPot*( + here->MOS9Cbd*model->MOS9bulkJctBotGradingCoeff* + sarg/arg + here->MOS9Cbdsw* + model->MOS9bulkJctSideGradingCoeff*sargsw/arg); + lcapbd3 = here->MOS9Cbd*sarg* + model->MOS9bulkJctBotGradingCoeff* + (model->MOS9bulkJctBotGradingCoeff+1); + lcapbd3 += here->MOS9Cbdsw*sargsw* + model->MOS9bulkJctSideGradingCoeff* + (model->MOS9bulkJctSideGradingCoeff+1); + lcapbd3 = lcapbd3/(6*here->MOS9tBulkPot* + here->MOS9tBulkPot*arg*arg); + } else { + lcapbd=here->MOS9f2d + vbd * here->MOS9f3d; + lcapbd2=0.5*here->MOS9f3d; + lcapbd3=0; + } + /* + * meyer's capacitor model + */ + /* + * the meyer capacitance equations are in DEVqmeyer + * these expressions are derived from those equations. + * these expressions are incorrect; they assume just one + * controlling variable for each charge storage element + * while actually there are several; the MOS9 small + * signal ac linear model is also wrong because it + * ignores controlled capacitive elements. these can be + * corrected (as can the linear ss ac model) if the + * expressions for the charge are available + */ + + +{ + + + double phi; + double cox; + double vddif; + double vddif1; + double vddif2; + double vgst; + /* von, lvgs and vdsat have already been adjusted for + possible source-drain interchange */ + + + + vgst = lvgs -von; + phi = here->MOS9tPhi; + cox = OxideCap; + if (vgst <= -phi) { + lcapgb2=lcapgb3=lcapgs2=lcapgs3=lcapgd2=lcapgd3=0; + } else if (vgst <= -phi/2) { + lcapgb2= -cox/(4*phi); + lcapgb3=lcapgs2=lcapgs3=lcapgd2=lcapgd3=0; + } else if (vgst <= 0) { + lcapgb2= -cox/(4*phi); + lcapgb3=lcapgs3=lcapgd2=lcapgd3=0; + lcapgs2 = cox/(3*phi); + } else { /* the MOS9modes are around because + vds has not been adjusted */ + if (vdsat <= here->MOS9mode*vds) { + lcapgb2=lcapgb3=lcapgs2=lcapgs3=lcapgd2=lcapgd3=0; + } else { + vddif = 2.0*vdsat-here->MOS9mode*vds; + vddif1 = vdsat-here->MOS9mode*vds/*-1.0e-12*/; + vddif2 = vddif*vddif; + lcapgd2 = -vdsat*here->MOS9mode*vds*cox/(3*vddif*vddif2); + lcapgd3 = - here->MOS9mode*vds*cox*(vddif - 6*vdsat)/(9*vddif2*vddif2); + lcapgs2 = -vddif1*here->MOS9mode*vds*cox/(3*vddif*vddif2); + lcapgs3 = - here->MOS9mode*vds*cox*(vddif - 6*vddif1)/(9*vddif2*vddif2); + lcapgb2=lcapgb3=0; + } + } + } + + /* the b-s and b-d diodes need no processing ... */ + here->capbs2 = lcapbs2; + here->capbs3 = lcapbs3; + here->capbd2 = lcapbd2; + here->capbd3 = lcapbd3; + here->gbs2 = lgbs2; + here->gbs3 = lgbs3; + here->gbd2 = lgbd2; + here->gbd3 = lgbd3; + here->capgb2 = model->MOS9type*lcapgb2; + here->capgb3 = lcapgb3; + /* + * process to get Taylor coefficients, taking into + * account type and mode. + */ +gm2 = d_cdrain.d2_p2; +gb2 = d_cdrain.d2_q2; +gds2 = d_cdrain.d2_r2; +gmb = d_cdrain.d2_pq; +gbds = d_cdrain.d2_qr; +gmds = d_cdrain.d2_pr; +gm3 = d_cdrain.d3_p3; +gb3 = d_cdrain.d3_q3; +gds3 = d_cdrain.d3_r3; +gm2ds = d_cdrain.d3_p2r; +gm2b = d_cdrain.d3_p2q; +gb2ds = d_cdrain.d3_q2r; +gmb2 = d_cdrain.d3_pq2; +gmds2 = d_cdrain.d3_pr2; +gbds2 = d_cdrain.d3_qr2; +gmbds = d_cdrain.d3_pqr; + + if (here->MOS9mode == 1) + { + /* normal mode - no source-drain interchange */ + + here->cdr_x2 = gm2; + here->cdr_y2 = gb2;; + here->cdr_z2 = gds2;; + here->cdr_xy = gmb; + here->cdr_yz = gbds; + here->cdr_xz = gmds; + here->cdr_x3 = gm3; + here->cdr_y3 = gb3; + here->cdr_z3 = gds3; + here->cdr_x2z = gm2ds; + here->cdr_x2y = gm2b; + here->cdr_y2z = gb2ds; + here->cdr_xy2 = gmb2; + here->cdr_xz2 = gmds2; + here->cdr_yz2 = gbds2; + here->cdr_xyz = gmbds; + + /* the gate caps have been divided and made into + Taylor coeffs., but not adjusted for type */ + + here->capgs2 = model->MOS9type*lcapgs2; + here->capgs3 = lcapgs3; + here->capgd2 = model->MOS9type*lcapgd2; + here->capgd3 = lcapgd3; +} else { + /* + * inverse mode - source and drain interchanged + */ + +here->cdr_x2 = -gm2; +here->cdr_y2 = -gb2; +here->cdr_z2 = -(gm2 + gb2 + gds2 + 2*(gmb + gmds + gbds)); +here->cdr_xy = -gmb; +here->cdr_yz = gmb + gb2 + gbds; +here->cdr_xz = gm2 + gmb + gmds; +here->cdr_x3 = -gm3; +here->cdr_y3 = -gb3; +here->cdr_z3 = gm3 + gb3 + gds3 + + 3*(gm2b + gm2ds + gmb2 + gb2ds + gmds2 + gbds2) + 6*gmbds ; +here->cdr_x2z = gm3 + gm2b + gm2ds; +here->cdr_x2y = -gm2b; +here->cdr_y2z = gmb2 + gb3 + gb2ds; +here->cdr_xy2 = -gmb2; +here->cdr_xz2 = -(gm3 + 2*(gm2b + gm2ds + gmbds) + + gmb2 + gmds2); +here->cdr_yz2 = -(gb3 + 2*(gmb2 + gb2ds + gmbds) + + gm2b + gbds2); +here->cdr_xyz = gm2b + gmb2 + gmbds; + + here->capgs2 = model->MOS9type*lcapgd2; + here->capgs3 = lcapgd3; + + here->capgd2 = model->MOS9type*lcapgs2; + here->capgd3 = lcapgs3; + +} + +/* now to adjust for type and multiply by factors to convert to Taylor coeffs. */ + +here->cdr_x2 = 0.5*model->MOS9type*here->cdr_x2; +here->cdr_y2 = 0.5*model->MOS9type*here->cdr_y2; +here->cdr_z2 = 0.5*model->MOS9type*here->cdr_z2; +here->cdr_xy = model->MOS9type*here->cdr_xy; +here->cdr_yz = model->MOS9type*here->cdr_yz; +here->cdr_xz = model->MOS9type*here->cdr_xz; +here->cdr_x3 = here->cdr_x3/6.; +here->cdr_y3 = here->cdr_y3/6.; +here->cdr_z3 = here->cdr_z3/6.; +here->cdr_x2z = 0.5*here->cdr_x2z; +here->cdr_x2y = 0.5*here->cdr_x2y; +here->cdr_y2z = 0.5*here->cdr_y2z; +here->cdr_xy2 = 0.5*here->cdr_xy2; +here->cdr_xz2 = 0.5*here->cdr_xz2; +here->cdr_yz2 = 0.5*here->cdr_yz2; + + + } + } + return(OK); +} diff --git a/src/spicelib/devices/mos9/mos9ext.h b/src/spicelib/devices/mos9/mos9ext.h new file mode 100644 index 000000000..d365f6b6d --- /dev/null +++ b/src/spicelib/devices/mos9/mos9ext.h @@ -0,0 +1,30 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ + +extern int MOS9acLoad(GENmodel*,CKTcircuit*); +extern int MOS9ask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); +extern int MOS9convTest(GENmodel *,CKTcircuit *); +extern int MOS9delete(GENmodel*,IFuid,GENinstance**); +extern void MOS9destroy(GENmodel**); +extern int MOS9getic(GENmodel*,CKTcircuit*); +extern int MOS9load(GENmodel*,CKTcircuit*); +extern int MOS9mAsk(CKTcircuit*,GENmodel*,int,IFvalue*); +extern int MOS9mDelete(GENmodel**,IFuid,GENmodel*); +extern int MOS9mParam(int,IFvalue*,GENmodel*); +extern int MOS9param(int,IFvalue*,GENinstance*,IFvalue*); +extern int MOS9pzLoad(GENmodel*,CKTcircuit*,SPcomplex*); +extern int MOS9sAcLoad(GENmodel*,CKTcircuit*); +extern int MOS9sLoad(GENmodel*,CKTcircuit*); +extern void MOS9sPrint(GENmodel*,CKTcircuit*); +extern int MOS9sSetup(SENstruct*,GENmodel*); +extern int MOS9sUpdate(GENmodel*,CKTcircuit*); +extern int MOS9setup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); +extern int MOS9unsetup(GENmodel*,CKTcircuit*); +extern int MOS9temp(GENmodel*,CKTcircuit*); +extern int MOS9trunc(GENmodel*,CKTcircuit*,double*); +extern int MOS9disto(int,GENmodel*,CKTcircuit*); +extern int MOS9noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); +extern int MOS9dSetup(GENmodel*,CKTcircuit*); \ No newline at end of file diff --git a/src/spicelib/devices/mos9/mos9ic.c b/src/spicelib/devices/mos9/mos9ic.c new file mode 100644 index 000000000..a3beee038 --- /dev/null +++ b/src/spicelib/devices/mos9/mos9ic.c @@ -0,0 +1,49 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "mos9defs.h" +#include "sperror.h" +#include "suffix.h" + + +int +MOS9getic(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + MOS9model *model = (MOS9model *)inModel; + MOS9instance *here; + /* + * grab initial conditions out of rhs array. User specified, so use + * external nodes to get values + */ + + for( ; model ; model = model->MOS9nextModel) { + for(here = model->MOS9instances; here ; here = here->MOS9nextInstance) { + if(!here->MOS9icVBSGiven) { + here->MOS9icVBS = + *(ckt->CKTrhs + here->MOS9bNode) - + *(ckt->CKTrhs + here->MOS9sNode); + } + if(!here->MOS9icVDSGiven) { + here->MOS9icVDS = + *(ckt->CKTrhs + here->MOS9dNode) - + *(ckt->CKTrhs + here->MOS9sNode); + } + if(!here->MOS9icVGSGiven) { + here->MOS9icVGS = + *(ckt->CKTrhs + here->MOS9gNode) - + *(ckt->CKTrhs + here->MOS9sNode); + } + } + } + return(OK); +} diff --git a/src/spicelib/devices/mos9/mos9init.c b/src/spicelib/devices/mos9/mos9init.c new file mode 100644 index 000000000..7f5b9a6ac --- /dev/null +++ b/src/spicelib/devices/mos9/mos9init.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "mos9itf.h" +#include "mos9ext.h" +#include "mos9init.h" + + +SPICEdev MOS9info = { + { + "Mos9", + "Modified Level 3 MOSfet model", + + &MOS9nSize, + &MOS9nSize, + MOS9names, + + &MOS9pTSize, + MOS9pTable, + + &MOS9mPTSize, + MOS9mPTable, + DEV_DEFAULT + }, + + DEVparam : MOS9param, + DEVmodParam : MOS9mParam, + DEVload : MOS9load, + DEVsetup : MOS9setup, + DEVunsetup : MOS9unsetup, + DEVpzSetup : MOS9setup, + DEVtemperature: MOS9temp, + DEVtrunc : MOS9trunc, + DEVfindBranch : NULL, + DEVacLoad : MOS9acLoad, + DEVaccept : NULL, + DEVdestroy : MOS9destroy, + DEVmodDelete : MOS9mDelete, + DEVdelete : MOS9delete, + DEVsetic : MOS9getic, + DEVask : MOS9ask, + DEVmodAsk : MOS9mAsk, + DEVpzLoad : MOS9pzLoad, + DEVconvTest : MOS9convTest, + DEVsenSetup : MOS9sSetup, + DEVsenLoad : MOS9sLoad, + DEVsenUpdate : MOS9sUpdate, + DEVsenAcLoad : MOS9sAcLoad, + DEVsenPrint : MOS9sPrint, + DEVsenTrunc : NULL, + DEVdisto : MOS9disto, + DEVnoise : MOS9noise, + + DEVinstSize : &MOS9iSize, + DEVmodSize : &MOS9mSize + +}; + + +SPICEdev * +get_mos9_info(void) +{ + return &MOS9info; +} diff --git a/src/spicelib/devices/mos9/mos9init.h b/src/spicelib/devices/mos9/mos9init.h new file mode 100644 index 000000000..5163e2188 --- /dev/null +++ b/src/spicelib/devices/mos9/mos9init.h @@ -0,0 +1,13 @@ +#ifndef _MOS9INIT_H +#define _MOS9INIT_H + +extern IFparm MOS9pTable[ ]; +extern IFparm MOS9mPTable[ ]; +extern char *MOS9names[ ]; +extern int MOS9pTSize; +extern int MOS9mPTSize; +extern int MOS9nSize; +extern int MOS9iSize; +extern int MOS9mSize; + +#endif diff --git a/src/spicelib/devices/mos9/mos9itf.h b/src/spicelib/devices/mos9/mos9itf.h new file mode 100644 index 000000000..98c13c194 --- /dev/null +++ b/src/spicelib/devices/mos9/mos9itf.h @@ -0,0 +1,10 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +**********/ + +#ifndef DEV_MOS9 +#define DEV_MOS9 + +SPICEdev *get_mos9_info(void); + +#endif diff --git a/src/spicelib/devices/mos9/mos9load.c b/src/spicelib/devices/mos9/mos9load.c new file mode 100644 index 000000000..0e4b5fb67 --- /dev/null +++ b/src/spicelib/devices/mos9/mos9load.c @@ -0,0 +1,1358 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "devdefs.h" +#include "mos9defs.h" +#include "trandefs.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + +int +MOS9load(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; + /* actually load the current value into the + * sparse matrix previously provided + */ +{ + MOS9model *model = (MOS9model *)inModel; + MOS9instance *here; + double Beta; + double DrainSatCur; + double EffectiveLength; + double EffectiveWidth; + double GateBulkOverlapCap; + double GateDrainOverlapCap; + double GateSourceOverlapCap; + double OxideCap; + double SourceSatCur; + double arg; + double cbhat; + double cdhat; + double cdrain; + double cdreq; + double ceq; + double ceqbd; + double ceqbs; + double ceqgb; + double ceqgd; + double ceqgs; + double delvbd; + double delvbs; + double delvds; + double delvgd; + double delvgs; + double evbd; + double evbs; + double gcgb; + double gcgd; + double gcgs; + double geq; + double sarg; + double sargsw; + double tol; + double vbd; + double vbs; + double vds; + double vdsat; + double vgb1; + double vgb; + double vgd1; + double vgd; + double vgdo; + double vgs1; + double vgs; + double von; + double xfact; + int xnrm; + int xrev; + double capgs; /* total gate-source capacitance */ + double capgd; /* total gate-drain capacitance */ + double capgb; /* total gate-bulk capacitance */ + int Check; + double tempv; + 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 */ + } + goto next; + } + } + + /* loop through all the MOS9 device models */ +next: + for( ; model != NULL; model = model->MOS9nextModel ) { + + /* loop through all the instances of the model */ + for (here = model->MOS9instances; here != NULL ; + here=here->MOS9nextInstance) { + + vt = CONSTKoverQ * here->MOS9temp; + Check=1; + + if(ckt->CKTsenInfo){ +#ifdef SENSDEBUG + printf("MOS9load \n"); +#endif /* SENSDEBUG */ + + if(ckt->CKTsenInfo->SENstatus == PERTURBATION) + if(here->MOS9senPertFlag == OFF)continue; + + } + SenCond = ckt->CKTsenInfo && here->MOS9senPertFlag; +#ifdef DETAILPROF +asm(" .globl mos9pta"); +asm("mos9pta:"); +#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 + */ + + EffectiveWidth=here->MOS9w-2*model->MOS9widthNarrow+ + model->MOS9widthAdjust; + EffectiveLength=here->MOS9l - 2*model->MOS9latDiff+ + model->MOS9lengthAdjust; + + if( (here->MOS9tSatCurDens == 0) || + (here->MOS9drainArea == 0) || + (here->MOS9sourceArea == 0)) { + DrainSatCur = here->MOS9m * here->MOS9tSatCur; + SourceSatCur = here->MOS9m * here->MOS9tSatCur; + } else { + DrainSatCur = here->MOS9m * here->MOS9tSatCurDens * + here->MOS9drainArea; + SourceSatCur = here->MOS9m * here->MOS9tSatCurDens * + here->MOS9sourceArea; + } + GateSourceOverlapCap = model->MOS9gateSourceOverlapCapFactor * + here->MOS9m * EffectiveWidth; + GateDrainOverlapCap = model->MOS9gateDrainOverlapCapFactor * + here->MOS9m * EffectiveWidth; + GateBulkOverlapCap = model->MOS9gateBulkOverlapCapFactor * + here->MOS9m * EffectiveLength; + Beta = here->MOS9tTransconductance * + here->MOS9m * EffectiveWidth/EffectiveLength; + OxideCap = model->MOS9oxideCapFactor * EffectiveLength * + here->MOS9m * EffectiveWidth; + + + if(SenCond){ +#ifdef SENSDEBUG + printf("MOS9senPertFlag = ON \n"); +#endif /* SENSDEBUG */ + if((ckt->CKTsenInfo->SENmode == TRANSEN) && + (ckt->CKTmode & MODEINITTRAN)) { + vgs = *(ckt->CKTstate1 + here->MOS9vgs); + vds = *(ckt->CKTstate1 + here->MOS9vds); + vbs = *(ckt->CKTstate1 + here->MOS9vbs); + vbd = *(ckt->CKTstate1 + here->MOS9vbd); + vgb = vgs - vbs; + vgd = vgs - vds; + } + else if (ckt->CKTsenInfo->SENmode == ACSEN){ + vgb = model->MOS9type * ( + *(ckt->CKTrhsOp+here->MOS9gNode) - + *(ckt->CKTrhsOp+here->MOS9bNode)); + vbs = *(ckt->CKTstate0 + here->MOS9vbs); + vbd = *(ckt->CKTstate0 + here->MOS9vbd); + vgd = vgb + vbd ; + vgs = vgb + vbs ; + vds = vbs - vbd ; + } + else{ + vgs = *(ckt->CKTstate0 + here->MOS9vgs); + vds = *(ckt->CKTstate0 + here->MOS9vds); + vbs = *(ckt->CKTstate0 + here->MOS9vbs); + vbd = *(ckt->CKTstate0 + here->MOS9vbd); + vgb = vgs - vbs; + vgd = vgs - vds; + } +#ifdef SENSDEBUG + printf(" vbs = %.7e ,vbd = %.7e,vgb = %.7e\n",vbs,vbd,vgb); + printf(" vgs = %.7e ,vds = %.7e,vgd = %.7e\n",vgs,vds,vgd); +#endif /* SENSDEBUG */ + goto next1; + } + +#ifdef DETAILPROF +asm(" .globl mos9ptax"); +asm("mos9ptax:"); +#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 + */ + + if((ckt->CKTmode & (MODEINITFLOAT | MODEINITPRED | MODEINITSMSIG | + MODEINITTRAN)) || + ( (ckt->CKTmode & MODEINITFIX) && (!here->MOS9off) ) ) { +#ifndef PREDICTOR + if(ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) { + + /* predictor step */ + + xfact=ckt->CKTdelta/ckt->CKTdeltaOld[1]; + *(ckt->CKTstate0 + here->MOS9vbs) = + *(ckt->CKTstate1 + here->MOS9vbs); + vbs = (1+xfact)* (*(ckt->CKTstate1 + here->MOS9vbs)) + -(xfact * (*(ckt->CKTstate2 + here->MOS9vbs))); + *(ckt->CKTstate0 + here->MOS9vgs) = + *(ckt->CKTstate1 + here->MOS9vgs); + vgs = (1+xfact)* (*(ckt->CKTstate1 + here->MOS9vgs)) + -(xfact * (*(ckt->CKTstate2 + here->MOS9vgs))); + *(ckt->CKTstate0 + here->MOS9vds) = + *(ckt->CKTstate1 + here->MOS9vds); + vds = (1+xfact)* (*(ckt->CKTstate1 + here->MOS9vds)) + -(xfact * (*(ckt->CKTstate2 + here->MOS9vds))); + *(ckt->CKTstate0 + here->MOS9vbd) = + *(ckt->CKTstate0 + here->MOS9vbs)- + *(ckt->CKTstate0 + here->MOS9vds); + } else { +#endif /*PREDICTOR*/ + + /* general iteration */ + + vbs = model->MOS9type * ( + *(ckt->CKTrhsOld+here->MOS9bNode) - + *(ckt->CKTrhsOld+here->MOS9sNodePrime)); + vgs = model->MOS9type * ( + *(ckt->CKTrhsOld+here->MOS9gNode) - + *(ckt->CKTrhsOld+here->MOS9sNodePrime)); + vds = model->MOS9type * ( + *(ckt->CKTrhsOld+here->MOS9dNodePrime) - + *(ckt->CKTrhsOld+here->MOS9sNodePrime)); +#ifndef PREDICTOR + } +#endif /*PREDICTOR*/ + + /* now some common crunching for some more useful quantities */ +#ifdef DETAILPROF +asm(" .globl mos9ptay"); +asm("mos9ptay:"); +#endif /* DETAILPROF */ + + vbd=vbs-vds; + vgd=vgs-vds; + vgdo = *(ckt->CKTstate0 + here->MOS9vgs) - + *(ckt->CKTstate0 + here->MOS9vds); + delvbs = vbs - *(ckt->CKTstate0 + here->MOS9vbs); + delvbd = vbd - *(ckt->CKTstate0 + here->MOS9vbd); + delvgs = vgs - *(ckt->CKTstate0 + here->MOS9vgs); + delvds = vds - *(ckt->CKTstate0 + here->MOS9vds); + delvgd = vgd-vgdo; + + /* these are needed for convergence testing */ + + if (here->MOS9mode >= 0) { + cdhat= + here->MOS9cd- + here->MOS9gbd * delvbd + + here->MOS9gmbs * delvbs + + here->MOS9gm * delvgs + + here->MOS9gds * delvds ; + } else { + cdhat= + here->MOS9cd - + ( here->MOS9gbd - + here->MOS9gmbs) * delvbd - + here->MOS9gm * delvgd + + here->MOS9gds * delvds ; + } + cbhat= + here->MOS9cbs + + here->MOS9cbd + + here->MOS9gbd * delvbd + + here->MOS9gbs * delvbs ; + +#ifdef DETAILPROF +asm(" .globl mos9ptb"); +asm("mos9ptb:"); +#endif /* DETAILPROF */ + /* 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->MOS9cbs + + here->MOS9cbd))+ckt->CKTabstol; + if((!(ckt->CKTmode & (MODEINITPRED|MODEINITTRAN|MODEINITSMSIG) + )) && (ckt->CKTbypass) ) + if ( (fabs(cbhat-(here->MOS9cbs + + here->MOS9cbd)) < ckt->CKTreltol * + tempv)) + if( (fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs), + fabs(*(ckt->CKTstate0+here->MOS9vbs)))+ + ckt->CKTvoltTol))) + if ( (fabs(delvbd) < (ckt->CKTreltol * MAX(fabs(vbd), + fabs(*(ckt->CKTstate0+here->MOS9vbd)))+ + ckt->CKTvoltTol)) ) + if( (fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs), + fabs(*(ckt->CKTstate0+here->MOS9vgs)))+ + ckt->CKTvoltTol))) + if ( (fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), + fabs(*(ckt->CKTstate0+here->MOS9vds)))+ + ckt->CKTvoltTol)) ) + if( (fabs(cdhat- here->MOS9cd) < + ckt->CKTreltol * MAX(fabs(cdhat),fabs( + here->MOS9cd)) + 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->MOS9vbs); + vbd = *(ckt->CKTstate0 + here->MOS9vbd); + vgs = *(ckt->CKTstate0 + here->MOS9vgs); + vds = *(ckt->CKTstate0 + here->MOS9vds); + vgd = vgs - vds; + vgb = vgs - vbs; + cdrain = here->MOS9mode * (here->MOS9cd + here->MOS9cbd); + if(ckt->CKTmode & (MODETRAN | MODETRANOP)) { + capgs = ( *(ckt->CKTstate0+here->MOS9capgs)+ + *(ckt->CKTstate1+here->MOS9capgs) + + GateSourceOverlapCap ); + capgd = ( *(ckt->CKTstate0+here->MOS9capgd)+ + *(ckt->CKTstate1+here->MOS9capgd) + + GateDrainOverlapCap ); + capgb = ( *(ckt->CKTstate0+here->MOS9capgb)+ + *(ckt->CKTstate1+here->MOS9capgb) + + GateBulkOverlapCap ); + } + goto bypass; + } + +#ifdef DETAILPROF +asm(" .globl mos9ptc"); +asm("mos9ptc:"); +#endif /* DETAILPROF */ + /* ok - bypass is out, do it the hard way */ + + von = model->MOS9type * here->MOS9von; + +#ifndef NODELIMITING + /* + * limiting + * we want to keep device voltages from changing + * so fast that the exponentials churn out overflows + * and similar rudeness + */ + + if(*(ckt->CKTstate0 + here->MOS9vds) >=0) { + vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->MOS9vgs) + ,von); + vds = vgs - vgd; + vds = DEVlimvds(vds,*(ckt->CKTstate0 + here->MOS9vds)); + vgd = vgs - vds; + } else { + vgd = DEVfetlim(vgd,vgdo,von); + vds = vgs - vgd; + if(!(ckt->CKTfixLimit)) { + vds = -DEVlimvds(-vds,-(*(ckt->CKTstate0 + + here->MOS9vds))); + } + vgs = vgd + vds; + } + if(vds >= 0) { + vbs = DEVpnjlim(vbs,*(ckt->CKTstate0 + here->MOS9vbs), + vt,here->MOS9sourceVcrit,&Check); + vbd = vbs-vds; + } else { + vbd = DEVpnjlim(vbd,*(ckt->CKTstate0 + here->MOS9vbd), + vt,here->MOS9drainVcrit,&Check); + vbs = vbd + vds; + } +#endif /*NODELIMITING*/ + + } else { + +#ifdef DETAILPROF +asm(" .globl mos9ptd"); +asm("mos9ptd:"); +#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 + */ + + if((ckt->CKTmode & MODEINITJCT) && !here->MOS9off) { + vds= model->MOS9type * here->MOS9icVDS; + vgs= model->MOS9type * here->MOS9icVGS; + vbs= model->MOS9type * here->MOS9icVBS; + if((vds==0) && (vgs==0) && (vbs==0) && + ((ckt->CKTmode & + (MODETRAN|MODEDCOP|MODEDCTRANCURVE)) || + (!(ckt->CKTmode & MODEUIC)))) { + vbs = -1; + vgs = model->MOS9type * here->MOS9tVto; + vds = 0; + } + } else { + vbs=vgs=vds=0; + } + } + +#ifdef DETAILPROF +asm(" .globl mos9pte"); +asm("mos9pte:"); +#endif /* DETAILPROF */ + /* + * now all the preliminaries are over - we can start doing the + * real work + */ + vbd = vbs - vds; + vgd = vgs - vds; + vgb = vgs - vbs; + + + /* + * bulk-source and bulk-drain diodes + * here we just evaluate the ideal diode current and the + * corresponding derivative (conductance). + */ + +next1: if(vbs <= -3*vt) { + arg=3*vt/(vbs*CONSTe); + arg = arg * arg * arg; + here->MOS9cbs = -SourceSatCur*(1+arg)+ckt->CKTgmin*vbs; + here->MOS9gbs = SourceSatCur*3*arg/vbs+ckt->CKTgmin; + } else { + evbs = exp(MIN(MAX_EXP_ARG,vbs/vt)); + here->MOS9gbs = SourceSatCur*evbs/vt + ckt->CKTgmin; + here->MOS9cbs = SourceSatCur*(evbs-1) + ckt->CKTgmin*vbs; + } + if(vbd <= -3*vt) { + arg=3*vt/(vbd*CONSTe); + arg = arg * arg * arg; + here->MOS9cbd = -DrainSatCur*(1+arg)+ckt->CKTgmin*vbd; + here->MOS9gbd = DrainSatCur*3*arg/vbd+ckt->CKTgmin; + } else { + evbd = exp(MIN(MAX_EXP_ARG,vbd/vt)); + here->MOS9gbd = DrainSatCur*evbd/vt + ckt->CKTgmin; + here->MOS9cbd = DrainSatCur*(evbd-1) + ckt->CKTgmin*vbd; + } + + + /* now to determine whether the user was able to correctly + * identify the source and drain of his device + */ + if(vds >= 0) { + /* normal mode */ + here->MOS9mode = 1; + } else { + /* inverse mode */ + here->MOS9mode = -1; + } + +#ifdef DETAILPROF +asm(" .globl mos9ptf"); +asm("mos9ptf:"); +#endif /* DETAILPROF */ + { + /* + * 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 + */ + + /* + 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->MOS9eta * 8.15e-22/(model->MOS9oxideCapFactor* + EffectiveLength*EffectiveLength*EffectiveLength); + /* + *.....square root term + */ + if ( (here->MOS9mode==1?vbs:vbd) <= 0.0 ) { + phibs = here->MOS9tPhi-(here->MOS9mode==1?vbs:vbd); + sqphbs = sqrt(phibs); + dsqdvb = -0.5/sqphbs; + } else { + sqphis = sqrt(here->MOS9tPhi); + sqphs3 = here->MOS9tPhi*sqphis; + sqphbs = sqphis/(1.0+(here->MOS9mode==1?vbs:vbd)/ + (here->MOS9tPhi+here->MOS9tPhi)); + phibs = sqphbs*sqphbs; + dsqdvb = -phibs/(sqphs3+sqphs3); + } + /* + *.....short channel effect factor + */ + if ( (model->MOS9junctionDepth != 0.0) && + (model->MOS9coeffDepLayWidth != 0.0) ) { + wps = model->MOS9coeffDepLayWidth*sqphbs; + oneoverxj = 1.0/model->MOS9junctionDepth; + xjonxl = model->MOS9junctionDepth*oneoverxl; + djonxj = model->MOS9latDiff*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->MOS9coeffDepLayWidth*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->MOS9gamma*fshort; + fbodys = 0.5*gammas/(sqphbs+sqphbs); + fbody = fbodys+model->MOS9narrowFactor/EffectiveWidth; + onfbdy = 1.0/(1.0+fbody); + dfbdvb = -fbodys*dsqdvb/sqphbs+fbodys*dfsdvb/fshort; + qbonco =gammas*sqphbs+model->MOS9narrowFactor*phibs/EffectiveWidth; + dqbdvb = gammas*dsqdvb+model->MOS9gamma*dfsdvb*sqphbs- + model->MOS9narrowFactor/EffectiveWidth; + + /* + *.....static feedback effect + */ + vbix = here->MOS9tVbi*model->MOS9type-eta*(here->MOS9mode*vds); + /* + *.....threshold voltage + */ + vth = vbix+qbonco; + dvtdvd = -eta; + dvtdvb = dqbdvb; + /* + *.....joint weak inversion and strong inversion + */ + von = vth; + if ( model->MOS9fastSurfaceStateDensity != 0.0 ) { + csonco = CHARGE*model->MOS9fastSurfaceStateDensity * + 1e4 /*(cm**2/m**2)*/ *EffectiveLength*EffectiveWidth * + here->MOS9m/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->MOS9mode==1?vgs:vgd) <= von ) { + cdrain = 0.0; + here->MOS9gm = 0.0; + here->MOS9gds = 0.0; + here->MOS9gmbs = 0.0; + goto innerline1000; + } + } + /* + *.....device is on + */ + vgsx = MAX((here->MOS9mode==1?vgs:vgd),von); + /* + *.....mobility modulation by gate voltage + */ + onfg = 1.0+model->MOS9theta*(vgsx-vth); + fgate = 1.0/onfg; + us = here->MOS9tSurfMob * 1e-4 /*(m**2/cm**2)*/ *fgate; + dfgdvg = -model->MOS9theta*fgate*fgate; + dfgdvd = -dfgdvg*dvtdvd; + dfgdvb = -dfgdvg*dvtdvb; + /* + *.....saturation voltage + */ + vdsat = (vgsx-vth)*onfbdy; + if ( model->MOS9maxDriftVel <= 0.0 ) { + dvsdvg = onfbdy; + dvsdvd = -dvsdvg*dvtdvd; + dvsdvb = -dvsdvg*dvtdvb-vdsat*dfbdvb*onfbdy; + } else { + vdsc = EffectiveLength*model->MOS9maxDriftVel/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->MOS9mode*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->MOS9gm = vdsx; + if ((here->MOS9mode*vds) > vdsat) here->MOS9gds = -dvtdvd*vdsx; + else here->MOS9gds = vgsx-vth-(1.0+fbody+dvtdvd)*vdsx; + here->MOS9gmbs = dcodvb*vdsx; + /* + *.....drain current without velocity saturation effect + */ + cd1 = Beta*cdnorm; + Beta = Beta*fgate; + cdrain = Beta*cdnorm; + here->MOS9gm = Beta*here->MOS9gm+dfgdvg*cd1; + here->MOS9gds = Beta*here->MOS9gds+dfgdvd*cd1; + here->MOS9gmbs = Beta*here->MOS9gmbs+dfgdvb*cd1; + /* + *.....velocity saturation factor + */ + if ( model->MOS9maxDriftVel > 0.0 ) { + fdrain = 1.0/(1.0+vdsx*onvdsc); + fd2 = fdrain*fdrain; + arga = fd2*vdsx*onvdsc*onfg; + dfddvg = -dfgdvg*arga; + if ((here->MOS9mode*vds) > vdsat) dfddvd = -dfgdvd*arga; + else dfddvd = -dfgdvd*arga-fd2*onvdsc; + dfddvb = -dfgdvb*arga; + /* + *.....drain current + */ + here->MOS9gm = fdrain*here->MOS9gm+dfddvg*cdrain; + here->MOS9gds = fdrain*here->MOS9gds+dfddvd*cdrain; + here->MOS9gmbs = fdrain*here->MOS9gmbs+dfddvb*cdrain; + cdrain = fdrain*cdrain; + Beta = Beta*fdrain; + } + /* + *.....channel length modulation + */ + if ((here->MOS9mode*vds) <= vdsat) { + if ( (model->MOS9maxDriftVel > 0.0) || + (model->MOS9alpha == 0.0) || + (ckt->CKTbadMos3) ) goto line700; + else { + arga = (here->MOS9mode*vds)/vdsat; + delxl = sqrt(model->MOS9kappa*model->MOS9alpha*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->MOS9maxDriftVel <= 0.0 ) goto line510; + if (model->MOS9alpha == 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->MOS9gm-gdonfd*dfddvg+gdonfg*dfgdvg; + dgdvd = gdoncd*here->MOS9gds-gdonfd*dfddvd+gdonfg*dfgdvd; + dgdvb = gdoncd*here->MOS9gmbs-gdonfd*dfddvb+gdonfg*dfgdvb; + + if (ckt->CKTbadMos3) + emax = cdsat*oneoverxl/gdsat; + else + emax = model->MOS9kappa * cdsat*oneoverxl/gdsat; + emoncd = emax/cdsat; + emongd = emax/gdsat; + demdvg = emoncd*here->MOS9gm-emongd*dgdvg; + demdvd = emoncd*here->MOS9gds-emongd*dgdvd; + demdvb = emoncd*here->MOS9gmbs-emongd*dgdvb; + + arga = 0.5*emax*model->MOS9alpha; + argc = model->MOS9kappa*model->MOS9alpha; + argb = sqrt(arga*arga+argc*((here->MOS9mode*vds)-vdsat)); + delxl = argb-arga; + dldvd = argc/(argb+argb); + dldem = 0.5*(arga/argb-1.0)*model->MOS9alpha; + ddldvg = dldem*demdvg; + ddldvd = dldem*demdvd-dldvd; + ddldvb = dldem*demdvb; + goto line520; +line510: + if (ckt->CKTbadMos3) { + delxl = sqrt(model->MOS9kappa*((here->MOS9mode*vds)-vdsat)* + model->MOS9alpha); + dldvd = 0.5*delxl/((here->MOS9mode*vds)-vdsat); + } else { + delxl = sqrt(model->MOS9kappa*model->MOS9alpha* + ((here->MOS9mode*vds)-vdsat+(vdsat/8))); + dldvd = 0.5*delxl/((here->MOS9mode*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); + cd1 = cdrain; + cdrain = cdrain*xlfact; + diddl = cdrain/(EffectiveLength-delxl); + here->MOS9gm = here->MOS9gm*xlfact+diddl*ddldvg; + here->MOS9gmbs = here->MOS9gmbs*xlfact+diddl*ddldvb; + gds0 = diddl*ddldvd; + here->MOS9gm = here->MOS9gm+gds0*dvsdvg; + here->MOS9gmbs = here->MOS9gmbs+gds0*dvsdvb; + here->MOS9gds = here->MOS9gds*xlfact+diddl*dldvd+gds0*dvsdvd; +/* here->MOS9gds = (here->MOS9gds*xlfact)+gds0*dvsdvd- + (cd1*ddldvd/(EffectiveLength*(1-2*dlonxl+dlonxl*dlonxl)));*/ + + /* + *.....finish strong inversion case + */ +line700: + if ( (here->MOS9mode==1?vgs:vgd) < von ) { + /* + *.....weak inversion + */ + onxn = 1.0/xn; + ondvt = onxn/vt; + wfact = exp( ((here->MOS9mode==1?vgs:vgd)-von)*ondvt ); + cdrain = cdrain*wfact; + gms = here->MOS9gm*wfact; + gmw = cdrain*ondvt; + here->MOS9gm = gmw; + if ((here->MOS9mode*vds) > vdsat) { + here->MOS9gm = here->MOS9gm+gds0*dvsdvg*wfact; + } + here->MOS9gds = here->MOS9gds*wfact+(gms-gmw)*dvodvd; + here->MOS9gmbs = here->MOS9gmbs*wfact+(gms-gmw)*dvodvb-gmw* + ((here->MOS9mode==1?vgs:vgd)-von)*onxn*dxndvb; + } + /* + *.....charge computation + */ + goto innerline1000; + /* + *.....special case of vds = 0.0d0 + */ +line900: + Beta = Beta*fgate; + cdrain = 0.0; + here->MOS9gm = 0.0; + here->MOS9gds = Beta*(vgsx-vth); + here->MOS9gmbs = 0.0; + if ( (model->MOS9fastSurfaceStateDensity != 0.0) && + ((here->MOS9mode==1?vgs:vgd) < von) ) { + here->MOS9gds *=exp(((here->MOS9mode==1?vgs:vgd)-von)/(vt*xn)); + } +innerline1000:; + /* + *.....done + */ + } + +#ifdef DETAILPROF +asm(" .globl mos9ptg"); +asm("mos9ptg:"); +#endif /* DETAILPROF */ + + /* now deal with n vs p polarity */ + + here->MOS9von = model->MOS9type * von; + here->MOS9vdsat = model->MOS9type * vdsat; + /* line 490 */ + /* + * COMPUTE EQUIVALENT DRAIN CURRENT SOURCE + */ + here->MOS9cd=here->MOS9mode * cdrain - here->MOS9cbd; + + 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->MOS9vbs)))+ + ckt->CKTvoltTol)|| senflag ) +#endif /*CAPBYPASS*/ + { + /* can't bypass the diode capacitance calculations */ +#ifdef CAPZEROBYPASS + if(here->MOS9Cbs != 0 || here->MOS9Cbssw != 0 ) { +#endif /*CAPZEROBYPASS*/ + if (vbs < here->MOS9tDepCap){ + arg=1-vbs/here->MOS9tBulkPot; + /* + * 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->MOS9bulkJctBotGradingCoeff == + model->MOS9bulkJctSideGradingCoeff) { + if(model->MOS9bulkJctBotGradingCoeff == .5) { + sarg = sargsw = 1/sqrt(arg); + } else { + sarg = sargsw = + exp(-model->MOS9bulkJctBotGradingCoeff* + log(arg)); + } + } else { + if(model->MOS9bulkJctBotGradingCoeff == .5) { + sarg = 1/sqrt(arg); + } else { +#endif /*NOSQRT*/ + sarg = exp(-model->MOS9bulkJctBotGradingCoeff* + log(arg)); +#ifndef NOSQRT + } + if(model->MOS9bulkJctSideGradingCoeff == .5) { + sargsw = 1/sqrt(arg); + } else { +#endif /*NOSQRT*/ + sargsw =exp(-model->MOS9bulkJctSideGradingCoeff* + log(arg)); +#ifndef NOSQRT + } + } +#endif /*NOSQRT*/ + *(ckt->CKTstate0 + here->MOS9qbs) = + here->MOS9tBulkPot*(here->MOS9Cbs* + (1-arg*sarg)/(1-model->MOS9bulkJctBotGradingCoeff) + +here->MOS9Cbssw* + (1-arg*sargsw)/ + (1-model->MOS9bulkJctSideGradingCoeff)); + here->MOS9capbs=here->MOS9Cbs*sarg+ + here->MOS9Cbssw*sargsw; + } else { + *(ckt->CKTstate0 + here->MOS9qbs) = here->MOS9f4s + + vbs*(here->MOS9f2s+vbs*(here->MOS9f3s/2)); + here->MOS9capbs=here->MOS9f2s+here->MOS9f3s*vbs; + } +#ifdef CAPZEROBYPASS + } else { + *(ckt->CKTstate0 + here->MOS9qbs) = 0; + here->MOS9capbs=0; + } +#endif /*CAPZEROBYPASS*/ + } +#ifdef CAPBYPASS + if(((ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) || + fabs(delvbd) >= ckt->CKTreltol * MAX(fabs(vbd), + fabs(*(ckt->CKTstate0+here->MOS9vbd)))+ + ckt->CKTvoltTol)|| senflag ) +#endif /*CAPBYPASS*/ + /* can't bypass the diode capacitance calculations */ + { +#ifdef CAPZEROBYPASS + if(here->MOS9Cbd != 0 || here->MOS9Cbdsw != 0 ) { +#endif /*CAPZEROBYPASS*/ + if (vbd < here->MOS9tDepCap) { + arg=1-vbd/here->MOS9tBulkPot; + /* + * 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->MOS9bulkJctBotGradingCoeff == .5 && + model->MOS9bulkJctSideGradingCoeff == .5) { + sarg = sargsw = 1/sqrt(arg); + } else { + if(model->MOS9bulkJctBotGradingCoeff == .5) { + sarg = 1/sqrt(arg); + } else { +#endif /*NOSQRT*/ + sarg = exp(-model->MOS9bulkJctBotGradingCoeff* + log(arg)); +#ifndef NOSQRT + } + if(model->MOS9bulkJctSideGradingCoeff == .5) { + sargsw = 1/sqrt(arg); + } else { +#endif /*NOSQRT*/ + sargsw =exp(-model->MOS9bulkJctSideGradingCoeff* + log(arg)); +#ifndef NOSQRT + } + } +#endif /*NOSQRT*/ + *(ckt->CKTstate0 + here->MOS9qbd) = + here->MOS9tBulkPot*(here->MOS9Cbd* + (1-arg*sarg) + /(1-model->MOS9bulkJctBotGradingCoeff) + +here->MOS9Cbdsw* + (1-arg*sargsw) + /(1-model->MOS9bulkJctSideGradingCoeff)); + here->MOS9capbd=here->MOS9Cbd*sarg+ + here->MOS9Cbdsw*sargsw; + } else { + *(ckt->CKTstate0 + here->MOS9qbd) = here->MOS9f4d + + vbd * (here->MOS9f2d + vbd * here->MOS9f3d/2); + here->MOS9capbd=here->MOS9f2d + vbd * here->MOS9f3d; + } +#ifdef CAPZEROBYPASS + } else { + *(ckt->CKTstate0 + here->MOS9qbd) = 0; + here->MOS9capbd = 0; + } +#endif /*CAPZEROBYPASS*/ + } +#ifdef DETAILPROF +asm(" .globl mos9pth"); +asm("mos9pth:"); +#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->MOS9capbd, + here->MOS9qbd); + if(error) return(error); + here->MOS9gbd += geq; + here->MOS9cbd += *(ckt->CKTstate0 + here->MOS9cqbd); + here->MOS9cd -= *(ckt->CKTstate0 + here->MOS9cqbd); + error = NIintegrate(ckt,&geq,&ceq,here->MOS9capbs, + here->MOS9qbs); + if(error) return(error); + here->MOS9gbs += geq; + here->MOS9cbs += *(ckt->CKTstate0 + here->MOS9cqbs); + } + } +#ifdef DETAILPROF +asm(" .globl mos9pti"); +asm("mos9pti:"); +#endif /* DETAILPROF */ + if(SenCond) goto next2; + + /* + * check convergence + */ + if ( (here->MOS9off == 0) || + (!(ckt->CKTmode & (MODEINITFIX|MODEINITSMSIG))) ){ + if (Check == 1) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + } + } + +#ifdef DETAILPROF +asm(" .globl mos9ptj"); +asm("mos9ptj:"); +#endif /* DETAILPROF */ + + /* save things away for next time */ + +next2: *(ckt->CKTstate0 + here->MOS9vbs) = vbs; + *(ckt->CKTstate0 + here->MOS9vbd) = vbd; + *(ckt->CKTstate0 + here->MOS9vgs) = vgs; + *(ckt->CKTstate0 + here->MOS9vds) = vds; + +#ifdef DETAILPROF +asm(" .globl mos9ptk"); +asm("mos9ptk:"); +#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->MOS9mode > 0){ + DEVqmeyer (vgs,vgd,vgb,von,vdsat, + (ckt->CKTstate0 + here->MOS9capgs), + (ckt->CKTstate0 + here->MOS9capgd), + (ckt->CKTstate0 + here->MOS9capgb), + here->MOS9tPhi,OxideCap); + } else { + DEVqmeyer (vgd,vgs,vgb,von,vdsat, + (ckt->CKTstate0 + here->MOS9capgd), + (ckt->CKTstate0 + here->MOS9capgs), + (ckt->CKTstate0 + here->MOS9capgb), + here->MOS9tPhi,OxideCap); + } + vgs1 = *(ckt->CKTstate1 + here->MOS9vgs); + vgd1 = vgs1 - *(ckt->CKTstate1 + here->MOS9vds); + vgb1 = vgs1 - *(ckt->CKTstate1 + here->MOS9vbs); + if(ckt->CKTmode & MODETRANOP) { + capgs = 2 * *(ckt->CKTstate0+here->MOS9capgs)+ + GateSourceOverlapCap ; + capgd = 2 * *(ckt->CKTstate0+here->MOS9capgd)+ + GateDrainOverlapCap ; + capgb = 2 * *(ckt->CKTstate0+here->MOS9capgb)+ + GateBulkOverlapCap ; + } else { + capgs = ( *(ckt->CKTstate0+here->MOS9capgs)+ + *(ckt->CKTstate1+here->MOS9capgs) + + GateSourceOverlapCap ); + capgd = ( *(ckt->CKTstate0+here->MOS9capgd)+ + *(ckt->CKTstate1+here->MOS9capgd) + + GateDrainOverlapCap ); + capgb = ( *(ckt->CKTstate0+here->MOS9capgb)+ + *(ckt->CKTstate1+here->MOS9capgb) + + GateBulkOverlapCap ); + } + if(ckt->CKTsenInfo){ + here->MOS9cgs = capgs; + here->MOS9cgd = capgd; + here->MOS9cgb = capgb; + } + +#ifdef DETAILPROF +asm(" .globl mos9ptl"); +asm("mos9ptl:"); +#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; + } + } +#ifndef PREDICTOR + if (ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) { + *(ckt->CKTstate0 + here->MOS9qgs) = + (1+xfact) * *(ckt->CKTstate1 + here->MOS9qgs) + - xfact * *(ckt->CKTstate2 + here->MOS9qgs); + *(ckt->CKTstate0 + here->MOS9qgd) = + (1+xfact) * *(ckt->CKTstate1 + here->MOS9qgd) + - xfact * *(ckt->CKTstate2 + here->MOS9qgd); + *(ckt->CKTstate0 + here->MOS9qgb) = + (1+xfact) * *(ckt->CKTstate1 + here->MOS9qgb) + - xfact * *(ckt->CKTstate2 + here->MOS9qgb); + } else { +#endif /*PREDICTOR*/ + if(ckt->CKTmode & MODETRAN) { + *(ckt->CKTstate0 + here->MOS9qgs) = (vgs-vgs1)*capgs + + *(ckt->CKTstate1 + here->MOS9qgs) ; + *(ckt->CKTstate0 + here->MOS9qgd) = (vgd-vgd1)*capgd + + *(ckt->CKTstate1 + here->MOS9qgd) ; + *(ckt->CKTstate0 + here->MOS9qgb) = (vgb-vgb1)*capgb + + *(ckt->CKTstate1 + here->MOS9qgb) ; + } else { + /* TRANOP only */ + *(ckt->CKTstate0 + here->MOS9qgs) = vgs*capgs; + *(ckt->CKTstate0 + here->MOS9qgd) = vgd*capgd; + *(ckt->CKTstate0 + here->MOS9qgb) = vgb*capgb; + } +#ifndef PREDICTOR + } +#endif /*PREDICTOR*/ + } +bypass: + if(SenCond) continue; +#ifdef DETAILPROF +asm(" .globl mos9ptm"); +asm("mos9ptm:"); +#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->MOS9cqgs) =0; + if(capgd == 0) *(ckt->CKTstate0 + here->MOS9cqgd) =0; + if(capgb == 0) *(ckt->CKTstate0 + here->MOS9cqgb) =0; + /* + * calculate equivalent conductances and currents for + * meyer"s capacitors + */ + error = NIintegrate(ckt,&gcgs,&ceqgs,capgs,here->MOS9qgs); + if(error) return(error); + error = NIintegrate(ckt,&gcgd,&ceqgd,capgd,here->MOS9qgd); + if(error) return(error); + error = NIintegrate(ckt,&gcgb,&ceqgb,capgb,here->MOS9qgb); + if(error) return(error); + ceqgs=ceqgs-gcgs*vgs+ckt->CKTag[0]* + *(ckt->CKTstate0 + here->MOS9qgs); + ceqgd=ceqgd-gcgd*vgd+ckt->CKTag[0]* + *(ckt->CKTstate0 + here->MOS9qgd); + ceqgb=ceqgb-gcgb*vgb+ckt->CKTag[0]* + *(ckt->CKTstate0 + here->MOS9qgb); + } + /* + * store charge storage info for meyer's cap in lx table + */ + +#ifdef DETAILPROF +asm(" .globl mos9ptn"); +asm("mos9ptn:"); +#endif /* DETAILPROF */ + /* + * load current vector + */ + ceqbs = model->MOS9type * + (here->MOS9cbs-(here->MOS9gbs)*vbs); + ceqbd = model->MOS9type * + (here->MOS9cbd-(here->MOS9gbd)*vbd); + if (here->MOS9mode >= 0) { + xnrm=1; + xrev=0; + cdreq=model->MOS9type*(cdrain-here->MOS9gds*vds- + here->MOS9gm*vgs-here->MOS9gmbs*vbs); + } else { + xnrm=0; + xrev=1; + cdreq = -(model->MOS9type)*(cdrain-here->MOS9gds*(-vds)- + here->MOS9gm*vgd-here->MOS9gmbs*vbd); + } + *(ckt->CKTrhs + here->MOS9gNode) -= + (model->MOS9type * (ceqgs + ceqgb + ceqgd)); + *(ckt->CKTrhs + here->MOS9bNode) -= + (ceqbs + ceqbd - model->MOS9type * ceqgb); + *(ckt->CKTrhs + here->MOS9dNodePrime) += + (ceqbd - cdreq + model->MOS9type * ceqgd); + *(ckt->CKTrhs + here->MOS9sNodePrime) += + cdreq + ceqbs + model->MOS9type * ceqgs; + /* + * load y matrix + */ +/*printf(" loading %s at time %g\n",here->MOS9name,ckt->CKTtime);*/ +/*printf("%g %g %g %g %g\n", here->MOS9drainConductance,gcgd+gcgs+gcgb, + here->MOS9sourceConductance,here->MOS9gbd,here->MOS9gbs);*/ +/*printf("%g %g %g %g %g\n",-gcgb,0.0,0.0,here->MOS9gds,here->MOS9gm);*/ +/*printf("%g %g %g %g %g\n", here->MOS9gds,here->MOS9gmbs,gcgd,-gcgs,-gcgd);*/ +/*printf("%g %g %g %g %g\n", -gcgs,-gcgd,0.0,-gcgs,0.0);*/ + + *(here->MOS9DdPtr) += (here->MOS9drainConductance); + *(here->MOS9GgPtr) += ((gcgd+gcgs+gcgb)); + *(here->MOS9SsPtr) += (here->MOS9sourceConductance); + *(here->MOS9BbPtr) += (here->MOS9gbd+here->MOS9gbs+gcgb); + *(here->MOS9DPdpPtr) += + (here->MOS9drainConductance+here->MOS9gds+ + here->MOS9gbd+xrev*(here->MOS9gm+here->MOS9gmbs)+gcgd); + *(here->MOS9SPspPtr) += + (here->MOS9sourceConductance+here->MOS9gds+ + here->MOS9gbs+xnrm*(here->MOS9gm+here->MOS9gmbs)+gcgs); + *(here->MOS9DdpPtr) += (-here->MOS9drainConductance); + *(here->MOS9GbPtr) -= gcgb; + *(here->MOS9GdpPtr) -= gcgd; + *(here->MOS9GspPtr) -= gcgs; + *(here->MOS9SspPtr) += (-here->MOS9sourceConductance); + *(here->MOS9BgPtr) -= gcgb; + *(here->MOS9BdpPtr) -= here->MOS9gbd; + *(here->MOS9BspPtr) -= here->MOS9gbs; + *(here->MOS9DPdPtr) += (-here->MOS9drainConductance); + *(here->MOS9DPgPtr) += ((xnrm-xrev)*here->MOS9gm-gcgd); + *(here->MOS9DPbPtr) += (-here->MOS9gbd+(xnrm-xrev)*here->MOS9gmbs); + *(here->MOS9DPspPtr) += (-here->MOS9gds- + xnrm*(here->MOS9gm+here->MOS9gmbs)); + *(here->MOS9SPgPtr) += (-(xnrm-xrev)*here->MOS9gm-gcgs); + *(here->MOS9SPsPtr) += (-here->MOS9sourceConductance); + *(here->MOS9SPbPtr) += (-here->MOS9gbs-(xnrm-xrev)*here->MOS9gmbs); + *(here->MOS9SPdpPtr) += (-here->MOS9gds- + xrev*(here->MOS9gm+here->MOS9gmbs)); + } + } + return(OK); +} diff --git a/src/spicelib/devices/mos9/mos9mask.c b/src/spicelib/devices/mos9/mos9mask.c new file mode 100644 index 000000000..30c8031ec --- /dev/null +++ b/src/spicelib/devices/mos9/mos9mask.c @@ -0,0 +1,171 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Thomas L. Quarles +Modified: Alan Gillespie +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "const.h" +#include "ifsim.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "mos9defs.h" +#include "sperror.h" +#include "suffix.h" + + +/*ARGSUSED*/ +int +MOS9mAsk(ckt,inst,which,value) + CKTcircuit *ckt; + GENmodel *inst; + int which; + IFvalue *value; +{ + MOS9model *here = (MOS9model *)inst; + switch(which) { + case MOS9_MOD_TNOM: + value->rValue = here->MOS9tnom-CONSTCtoK; + return(OK); + case MOS9_MOD_VTO: + value->rValue = here->MOS9vt0; + return(OK); + case MOS9_MOD_KP: + value->rValue = here->MOS9transconductance; + return(OK); + case MOS9_MOD_GAMMA: + value->rValue = here->MOS9gamma; + return(OK); + case MOS9_MOD_PHI: + value->rValue = here->MOS9phi; + return(OK); + case MOS9_MOD_RD: + value->rValue = here->MOS9drainResistance; + return(OK); + case MOS9_MOD_RS: + value->rValue = here->MOS9sourceResistance; + return(OK); + case MOS9_MOD_CBD: + value->rValue = here->MOS9capBD; + return(OK); + case MOS9_MOD_CBS: + value->rValue = here->MOS9capBS; + return(OK); + case MOS9_MOD_IS: + value->rValue = here->MOS9jctSatCur; + return(OK); + case MOS9_MOD_PB: + value->rValue = here->MOS9bulkJctPotential; + return(OK); + case MOS9_MOD_CGSO: + value->rValue = here->MOS9gateSourceOverlapCapFactor; + return(OK); + case MOS9_MOD_CGDO: + value->rValue = here->MOS9gateDrainOverlapCapFactor; + return(OK); + case MOS9_MOD_CGBO: + value->rValue = here->MOS9gateBulkOverlapCapFactor; + return(OK); + case MOS9_MOD_CJ: + value->rValue = here->MOS9bulkCapFactor; + return(OK); + case MOS9_MOD_MJ: + value->rValue = here->MOS9bulkJctBotGradingCoeff; + return(OK); + case MOS9_MOD_CJSW: + value->rValue = here->MOS9sideWallCapFactor; + return(OK); + case MOS9_MOD_MJSW: + value->rValue = here->MOS9bulkJctSideGradingCoeff; + return(OK); + case MOS9_MOD_JS: + value->rValue = here->MOS9jctSatCurDensity; + return(OK); + case MOS9_MOD_TOX: + value->rValue = here->MOS9oxideThickness; + return(OK); + case MOS9_MOD_LD: + value->rValue = here->MOS9latDiff; + return(OK); + case MOS9_MOD_XL: + value->rValue = here->MOS9lengthAdjust; + return(OK); + case MOS9_MOD_WD: + value->rValue = here->MOS9widthNarrow; + return(OK); + case MOS9_MOD_XW: + value->rValue = here->MOS9widthAdjust; + return(OK); + case MOS9_MOD_DELVTO: + value->rValue = here->MOS9delvt0; + return(OK); + case MOS9_MOD_RSH: + value->rValue = here->MOS9sheetResistance; + return(OK); + case MOS9_MOD_U0: + value->rValue = here->MOS9surfaceMobility; + return(OK); + case MOS9_MOD_FC: + value->rValue = here->MOS9fwdCapDepCoeff; + return(OK); + case MOS9_MOD_NSUB: + value->rValue = here->MOS9substrateDoping; + return(OK); + case MOS9_MOD_TPG: + value->iValue = here->MOS9gateType; + return(OK); + case MOS9_MOD_NSS: + value->rValue = here->MOS9surfaceStateDensity; + return(OK); + case MOS9_MOD_NFS: + value->rValue = here->MOS9fastSurfaceStateDensity; + return(OK); + case MOS9_MOD_DELTA: + value->rValue = here->MOS9narrowFactor; + return(OK); + case MOS9_MOD_VMAX: + value->rValue = here->MOS9maxDriftVel; + return(OK); + case MOS9_MOD_XJ: + value->rValue = here->MOS9junctionDepth; + return(OK); + case MOS9_MOD_ETA: + value->rValue = here->MOS9eta; + return(OK); + case MOS9_MOD_XD: + value->rValue = here->MOS9coeffDepLayWidth; + return(OK); + case MOS9_DELTA: + value->rValue = here->MOS9delta; + return(OK); + case MOS9_MOD_THETA: + value->rValue = here->MOS9theta; + return(OK); + case MOS9_MOD_ALPHA: + value->rValue = here->MOS9alpha; + return(OK); + case MOS9_MOD_KAPPA: + value->rValue = here->MOS9kappa; + return(OK); + case MOS9_MOD_KF: + value->rValue = here->MOS9fNcoef; + return(OK); + case MOS9_MOD_AF: + value->rValue = here->MOS9fNexp; + return(OK); + + case MOS9_MOD_TYPE: + if (here->MOS9type > 0) + value->sValue = "nmos"; + else + value->sValue = "pmos"; + return(OK); + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} + diff --git a/src/spicelib/devices/mos9/mos9mdel.c b/src/spicelib/devices/mos9/mos9mdel.c new file mode 100644 index 000000000..1165b28f2 --- /dev/null +++ b/src/spicelib/devices/mos9/mos9mdel.c @@ -0,0 +1,45 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "mos9defs.h" +#include "sperror.h" +#include "suffix.h" + + +int +MOS9mDelete(inModel,modname,kill) + GENmodel **inModel; + IFuid modname; + GENmodel *kill; +{ + MOS9model **model = (MOS9model **)inModel; + MOS9model *modfast = (MOS9model *)kill; + MOS9instance *here; + MOS9instance *prev = NULL; + MOS9model **oldmod; + oldmod = model; + for( ; *model ; model = &((*model)->MOS9nextModel)) { + if( (*model)->MOS9modName == modname || + (modfast && *model == modfast) ) goto delgot; + oldmod = model; + } + return(E_NOMOD); + +delgot: + *oldmod = (*model)->MOS9nextModel; /* cut deleted device out of list */ + for(here = (*model)->MOS9instances ; here ; here = here->MOS9nextInstance) { + if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + FREE(*model); + return(OK); + +} diff --git a/src/spicelib/devices/mos9/mos9mpar.c b/src/spicelib/devices/mos9/mos9mpar.c new file mode 100644 index 000000000..b21550e23 --- /dev/null +++ b/src/spicelib/devices/mos9/mos9mpar.c @@ -0,0 +1,202 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "const.h" +#include "ifsim.h" +#include "mos9defs.h" +#include "sperror.h" +#include "suffix.h" + + +int +MOS9mParam(param,value,inModel) + int param; + IFvalue *value; + GENmodel *inModel; +{ + register MOS9model *model = (MOS9model *)inModel; + switch(param) { + case MOS9_MOD_VTO: + model->MOS9vt0 = value->rValue; + model->MOS9vt0Given = TRUE; + break; + case MOS9_MOD_KP: + model->MOS9transconductance = value->rValue; + model->MOS9transconductanceGiven = TRUE; + break; + case MOS9_MOD_GAMMA: + model->MOS9gamma = value->rValue; + model->MOS9gammaGiven = TRUE; + break; + case MOS9_MOD_PHI: + model->MOS9phi = value->rValue; + model->MOS9phiGiven = TRUE; + break; + case MOS9_MOD_RD: + model->MOS9drainResistance = value->rValue; + model->MOS9drainResistanceGiven = TRUE; + break; + case MOS9_MOD_RS: + model->MOS9sourceResistance = value->rValue; + model->MOS9sourceResistanceGiven = TRUE; + break; + case MOS9_MOD_CBD: + model->MOS9capBD = value->rValue; + model->MOS9capBDGiven = TRUE; + break; + case MOS9_MOD_CBS: + model->MOS9capBS = value->rValue; + model->MOS9capBSGiven = TRUE; + break; + case MOS9_MOD_IS: + model->MOS9jctSatCur = value->rValue; + model->MOS9jctSatCurGiven = TRUE; + break; + case MOS9_MOD_PB: + model->MOS9bulkJctPotential = value->rValue; + model->MOS9bulkJctPotentialGiven = TRUE; + break; + case MOS9_MOD_CGSO: + model->MOS9gateSourceOverlapCapFactor = value->rValue; + model->MOS9gateSourceOverlapCapFactorGiven = TRUE; + break; + case MOS9_MOD_CGDO: + model->MOS9gateDrainOverlapCapFactor = value->rValue; + model->MOS9gateDrainOverlapCapFactorGiven = TRUE; + break; + case MOS9_MOD_CGBO: + model->MOS9gateBulkOverlapCapFactor = value->rValue; + model->MOS9gateBulkOverlapCapFactorGiven = TRUE; + break; + case MOS9_MOD_RSH: + model->MOS9sheetResistance = value->rValue; + model->MOS9sheetResistanceGiven = TRUE; + break; + case MOS9_MOD_CJ: + model->MOS9bulkCapFactor = value->rValue; + model->MOS9bulkCapFactorGiven = TRUE; + break; + case MOS9_MOD_MJ: + model->MOS9bulkJctBotGradingCoeff = value->rValue; + model->MOS9bulkJctBotGradingCoeffGiven = TRUE; + break; + case MOS9_MOD_CJSW: + model->MOS9sideWallCapFactor = value->rValue; + model->MOS9sideWallCapFactorGiven = TRUE; + break; + case MOS9_MOD_MJSW: + model->MOS9bulkJctSideGradingCoeff = value->rValue; + model->MOS9bulkJctSideGradingCoeffGiven = TRUE; + break; + case MOS9_MOD_JS: + model->MOS9jctSatCurDensity = value->rValue; + model->MOS9jctSatCurDensityGiven = TRUE; + break; + case MOS9_MOD_TOX: + model->MOS9oxideThickness = value->rValue; + model->MOS9oxideThicknessGiven = TRUE; + break; + case MOS9_MOD_LD: + model->MOS9latDiff = value->rValue; + model->MOS9latDiffGiven = TRUE; + break; + case MOS9_MOD_XL: + model->MOS9lengthAdjust = value->rValue; + model->MOS9lengthAdjustGiven = TRUE; + break; + case MOS9_MOD_WD: + model->MOS9widthNarrow = value->rValue; + model->MOS9widthNarrowGiven = TRUE; + break; + case MOS9_MOD_XW: + model->MOS9widthAdjust = value->rValue; + model->MOS9widthAdjustGiven = TRUE; + break; + case MOS9_MOD_DELVTO: + model->MOS9delvt0 = value->rValue; + model->MOS9delvt0Given = TRUE; + break; + case MOS9_MOD_U0: + model->MOS9surfaceMobility = value->rValue; + model->MOS9surfaceMobilityGiven = TRUE; + break; + case MOS9_MOD_FC: + model->MOS9fwdCapDepCoeff = value->rValue; + model->MOS9fwdCapDepCoeffGiven = TRUE; + break; + case MOS9_MOD_NSUB: + model->MOS9substrateDoping = value->rValue; + model->MOS9substrateDopingGiven = TRUE; + break; + case MOS9_MOD_TPG: + model->MOS9gateType = value->iValue; + model->MOS9gateTypeGiven = TRUE; + break; + case MOS9_MOD_NSS: + model->MOS9surfaceStateDensity = value->rValue; + model->MOS9surfaceStateDensityGiven = TRUE; + break; + case MOS9_MOD_ETA: + model->MOS9eta = value->rValue; + model->MOS9etaGiven = TRUE; + break; + case MOS9_MOD_DELTA: + model->MOS9delta = value->rValue; + model->MOS9deltaGiven = TRUE; + break; + case MOS9_MOD_NFS: + model->MOS9fastSurfaceStateDensity = value->rValue; + model->MOS9fastSurfaceStateDensityGiven = TRUE; + break; + case MOS9_MOD_THETA: + model->MOS9theta = value->rValue; + model->MOS9thetaGiven = TRUE; + break; + case MOS9_MOD_VMAX: + model->MOS9maxDriftVel = value->rValue; + model->MOS9maxDriftVelGiven = TRUE; + break; + case MOS9_MOD_KAPPA: + model->MOS9kappa = value->rValue; + model->MOS9kappaGiven = TRUE; + break; + case MOS9_MOD_NMOS: + if(value->iValue) { + model->MOS9type = 1; + model->MOS9typeGiven = TRUE; + } + break; + case MOS9_MOD_PMOS: + if(value->iValue) { + model->MOS9type = -1; + model->MOS9typeGiven = TRUE; + } + break; + case MOS9_MOD_XJ: + model->MOS9junctionDepth = value->rValue; + model->MOS9junctionDepthGiven = TRUE; + break; + case MOS9_MOD_TNOM: + model->MOS9tnom = value->rValue+CONSTCtoK; + model->MOS9tnomGiven = TRUE; + break; + case MOS9_MOD_KF: + model->MOS9fNcoef = value->rValue; + model->MOS9fNcoefGiven = TRUE; + break; + case MOS9_MOD_AF: + model->MOS9fNexp = value->rValue; + model->MOS9fNexpGiven = TRUE; + break; + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/mos9/mos9noi.c b/src/spicelib/devices/mos9/mos9noi.c new file mode 100644 index 000000000..306694d4b --- /dev/null +++ b/src/spicelib/devices/mos9/mos9noi.c @@ -0,0 +1,219 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Gary W. Ng +Modified: Alan Gillespie +**********/ + +#include "ngspice.h" +#include +#include "mos9defs.h" +#include "cktdefs.h" +#include "iferrmsg.h" +#include "noisedef.h" +#include "suffix.h" + +/* + * MOS9noise (mode, operation, firstModel, ckt, data, OnDens) + * This routine names and evaluates all of the noise sources + * associated with MOSFET's. It starts with the model *firstModel and + * traverses all of its insts. It then proceeds to any other models + * on the linked list. The total output noise density generated by + * all of the MOSFET's is summed with the variable "OnDens". + */ + +extern void NevalSrc(); +extern double Nintegrate(); + +int +MOS9noise (mode, operation, genmodel, ckt, data, OnDens) + int mode; + int operation; + GENmodel *genmodel; + CKTcircuit *ckt; + Ndata *data; + double *OnDens; +{ + MOS9model *firstModel = (MOS9model *) genmodel; + MOS9model *model; + MOS9instance *inst; + char name[N_MXVLNTH]; + double tempOnoise; + double tempInoise; + double noizDens[MOS9NSRCS]; + double lnNdens[MOS9NSRCS]; + int error; + int i; + + /* define the names of the noise sources */ + + static char *MOS9nNames[MOS9NSRCS] = { /* Note that we have to keep the order */ + "_rd", /* noise due to rd */ /* consistent with the index definitions */ + "_rs", /* noise due to rs */ /* in MOS9defs.h */ + "_id", /* noise due to id */ + "_1overf", /* flicker (1/f) noise */ + "" /* total transistor noise */ + }; + + for (model=firstModel; model != NULL; model=model->MOS9nextModel) { + for (inst=model->MOS9instances; inst != NULL; inst=inst->MOS9nextInstance) { + switch (operation) { + + case N_OPEN: + + /* see if we have to to produce a summary report */ + /* if so, name all the noise generators */ + + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { + switch (mode) { + + case N_DENS: + for (i=0; i < MOS9NSRCS; i++) { + (void)sprintf(name,"onoise_%s%s",inst->MOS9name,MOS9nNames[i]); + + +data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid)); +if (!data->namelist) return(E_NOMEM); + (*(SPfrontEnd->IFnewUid))(ckt, + &(data->namelist[data->numPlots++]), + (IFuid)NULL,name,UID_OTHER,(void **)NULL); + /* we've added one more plot */ + + + } + break; + + case INT_NOIZ: + for (i=0; i < MOS9NSRCS; i++) { + (void)sprintf(name,"onoise_total_%s%s",inst->MOS9name,MOS9nNames[i]); + + +data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid)); +if (!data->namelist) return(E_NOMEM); + (*(SPfrontEnd->IFnewUid))(ckt, + &(data->namelist[data->numPlots++]), + (IFuid)NULL,name,UID_OTHER,(void **)NULL); + /* we've added one more plot */ + + + (void)sprintf(name,"inoise_total_%s%s",inst->MOS9name,MOS9nNames[i]); + + +data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid)); +if (!data->namelist) return(E_NOMEM); + (*(SPfrontEnd->IFnewUid))(ckt, + &(data->namelist[data->numPlots++]), + (IFuid)NULL,name,UID_OTHER,(void **)NULL); + /* we've added one more plot */ + + + + } + break; + } + } + break; + + case N_CALC: + switch (mode) { + + case N_DENS: + NevalSrc(&noizDens[MOS9RDNOIZ],&lnNdens[MOS9RDNOIZ], + ckt,THERMNOISE,inst->MOS9dNodePrime,inst->MOS9dNode, + inst->MOS9drainConductance); + + NevalSrc(&noizDens[MOS9RSNOIZ],&lnNdens[MOS9RSNOIZ], + ckt,THERMNOISE,inst->MOS9sNodePrime,inst->MOS9sNode, + inst->MOS9sourceConductance); + + NevalSrc(&noizDens[MOS9IDNOIZ],&lnNdens[MOS9IDNOIZ], + ckt,THERMNOISE,inst->MOS9dNodePrime,inst->MOS9sNodePrime, + (2.0/3.0 * fabs(inst->MOS9gm))); + + NevalSrc(&noizDens[MOS9FLNOIZ],(double*)NULL,ckt, + N_GAIN,inst->MOS9dNodePrime, inst->MOS9sNodePrime, + (double)0.0); + noizDens[MOS9FLNOIZ] *= model->MOS9fNcoef * + exp(model->MOS9fNexp * + log(MAX(fabs(inst->MOS9cd),N_MINLOG))) / + (data->freq * + (inst->MOS9w - 2*model->MOS9widthNarrow) * + inst->MOS9m * + (inst->MOS9l - 2*model->MOS9latDiff) * + model->MOS9oxideCapFactor * model->MOS9oxideCapFactor); + lnNdens[MOS9FLNOIZ] = + log(MAX(noizDens[MOS9FLNOIZ],N_MINLOG)); + + noizDens[MOS9TOTNOIZ] = noizDens[MOS9RDNOIZ] + + noizDens[MOS9RSNOIZ] + + noizDens[MOS9IDNOIZ] + + noizDens[MOS9FLNOIZ]; + lnNdens[MOS9TOTNOIZ] = + log(MAX(noizDens[MOS9TOTNOIZ], N_MINLOG)); + + *OnDens += noizDens[MOS9TOTNOIZ]; + + if (data->delFreq == 0.0) { + + /* if we haven't done any previous integration, we need to */ + /* initialize our "history" variables */ + + for (i=0; i < MOS9NSRCS; i++) { + inst->MOS9nVar[LNLSTDENS][i] = lnNdens[i]; + } + + /* clear out our integration variables if it's the first pass */ + + if (data->freq == ((NOISEAN*)ckt->CKTcurJob)->NstartFreq) { + for (i=0; i < MOS9NSRCS; i++) { + inst->MOS9nVar[OUTNOIZ][i] = 0.0; + inst->MOS9nVar[INNOIZ][i] = 0.0; + } + } + } else { /* data->delFreq != 0.0 (we have to integrate) */ + for (i=0; i < MOS9NSRCS; i++) { + if (i != MOS9TOTNOIZ) { + tempOnoise = Nintegrate(noizDens[i], lnNdens[i], + inst->MOS9nVar[LNLSTDENS][i], data); + tempInoise = Nintegrate(noizDens[i] * data->GainSqInv , + lnNdens[i] + data->lnGainInv, + inst->MOS9nVar[LNLSTDENS][i] + data->lnGainInv, + data); + inst->MOS9nVar[LNLSTDENS][i] = lnNdens[i]; + data->outNoiz += tempOnoise; + data->inNoise += tempInoise; + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { + inst->MOS9nVar[OUTNOIZ][i] += tempOnoise; + inst->MOS9nVar[OUTNOIZ][MOS9TOTNOIZ] += tempOnoise; + inst->MOS9nVar[INNOIZ][i] += tempInoise; + inst->MOS9nVar[INNOIZ][MOS9TOTNOIZ] += tempInoise; + } + } + } + } + if (data->prtSummary) { + for (i=0; i < MOS9NSRCS; i++) { /* print a summary report */ + data->outpVector[data->outNumber++] = noizDens[i]; + } + } + break; + + case INT_NOIZ: /* already calculated, just output */ + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { + for (i=0; i < MOS9NSRCS; i++) { + data->outpVector[data->outNumber++] = inst->MOS9nVar[OUTNOIZ][i]; + data->outpVector[data->outNumber++] = inst->MOS9nVar[INNOIZ][i]; + } + } /* if */ + break; + } /* switch (mode) */ + break; + + case N_CLOSE: + return (OK); /* do nothing, the main calling routine will close */ + break; /* the plots */ + } /* switch (operation) */ + } /* for inst */ + } /* for model */ + +return(OK); +} diff --git a/src/spicelib/devices/mos9/mos9par.c b/src/spicelib/devices/mos9/mos9par.c new file mode 100644 index 000000000..5068a653e --- /dev/null +++ b/src/spicelib/devices/mos9/mos9par.c @@ -0,0 +1,116 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "const.h" +#include "ifsim.h" +#include "mos9defs.h" +#include "sperror.h" +#include "suffix.h" + + +/* ARGSUSED */ +int +MOS9param(param,value,inst,select) + int param; + IFvalue *value; + GENinstance *inst; + IFvalue *select; +{ + MOS9instance *here = (MOS9instance *)inst; + switch(param) { + + case MOS9_M: + here->MOS9m = value->rValue; + here->MOS9mGiven = TRUE; + break; + case MOS9_W: + here->MOS9w = value->rValue; + here->MOS9wGiven = TRUE; + break; + case MOS9_L: + here->MOS9l = value->rValue; + here->MOS9lGiven = TRUE; + break; + case MOS9_AS: + here->MOS9sourceArea = value->rValue; + here->MOS9sourceAreaGiven = TRUE; + break; + case MOS9_AD: + here->MOS9drainArea = value->rValue; + here->MOS9drainAreaGiven = TRUE; + break; + case MOS9_PS: + here->MOS9sourcePerimiter = value->rValue; + here->MOS9sourcePerimiterGiven = TRUE; + break; + case MOS9_PD: + here->MOS9drainPerimiter = value->rValue; + here->MOS9drainPerimiterGiven = TRUE; + break; + case MOS9_NRS: + here->MOS9sourceSquares = value->rValue; + here->MOS9sourceSquaresGiven = TRUE; + break; + case MOS9_NRD: + here->MOS9drainSquares = value->rValue; + here->MOS9drainSquaresGiven = TRUE; + break; + case MOS9_OFF: + here->MOS9off = value->iValue; + break; + case MOS9_IC_VBS: + here->MOS9icVBS = value->rValue; + here->MOS9icVBSGiven = TRUE; + break; + case MOS9_IC_VDS: + here->MOS9icVDS = value->rValue; + here->MOS9icVDSGiven = TRUE; + break; + case MOS9_IC_VGS: + here->MOS9icVGS = value->rValue; + here->MOS9icVGSGiven = TRUE; + break; + case MOS9_TEMP: + here->MOS9temp = value->rValue+CONSTCtoK; + here->MOS9tempGiven = TRUE; + break; + case MOS9_IC: + switch(value->v.numValue){ + case 3: + here->MOS9icVBS = *(value->v.vec.rVec+2); + here->MOS9icVBSGiven = TRUE; + case 2: + here->MOS9icVGS = *(value->v.vec.rVec+1); + here->MOS9icVGSGiven = TRUE; + case 1: + here->MOS9icVDS = *(value->v.vec.rVec); + here->MOS9icVDSGiven = TRUE; + break; + default: + return(E_BADPARM); + } + break; + case MOS9_L_SENS: + if(value->iValue) { + here->MOS9senParmNo = 1; + here->MOS9sens_l = 1; + } + break; + case MOS9_W_SENS: + if(value->iValue) { + here->MOS9senParmNo = 1; + here->MOS9sens_w = 1; + } + break; + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/mos9/mos9pzld.c b/src/spicelib/devices/mos9/mos9pzld.c new file mode 100644 index 000000000..52576637b --- /dev/null +++ b/src/spicelib/devices/mos9/mos9pzld.c @@ -0,0 +1,141 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "complex.h" +#include "mos9defs.h" +#include "sperror.h" +#include "suffix.h" + + +int +MOS9pzLoad(inModel,ckt,s) + GENmodel *inModel; + CKTcircuit *ckt; + SPcomplex *s; +{ + MOS9model *model = (MOS9model *)inModel; + MOS9instance *here; + int xnrm; + int xrev; + double xgs; + double xgd; + double xgb; + double xbd; + double xbs; + double capgs; + double capgd; + double capgb; + double GateBulkOverlapCap; + double GateDrainOverlapCap; + double GateSourceOverlapCap; + double EffectiveLength; + double EffectiveWidth; + + for( ; model != NULL; model = model->MOS9nextModel) { + for(here = model->MOS9instances; here!= NULL; + here = here->MOS9nextInstance) { + + if (here->MOS9mode < 0) { + xnrm=0; + xrev=1; + } else { + xnrm=1; + xrev=0; + } + /* + * meyer's model parameters + */ + + EffectiveWidth=here->MOS9w-2*model->MOS9widthNarrow+ + model->MOS9widthAdjust; + EffectiveLength=here->MOS9l - 2*model->MOS9latDiff+ + model->MOS9lengthAdjust; + + GateSourceOverlapCap = model->MOS9gateSourceOverlapCapFactor * + here->MOS9m * EffectiveWidth; + GateDrainOverlapCap = model->MOS9gateDrainOverlapCapFactor * + here->MOS9m * EffectiveWidth; + GateBulkOverlapCap = model->MOS9gateBulkOverlapCapFactor * + here->MOS9m * EffectiveLength; + + capgs = ( 2* *(ckt->CKTstate0+here->MOS9capgs)+ + GateSourceOverlapCap ); + capgd = ( 2* *(ckt->CKTstate0+here->MOS9capgd)+ + GateDrainOverlapCap ); + capgb = ( 2* *(ckt->CKTstate0+here->MOS9capgb)+ + GateBulkOverlapCap ); + xgs = capgs; + xgd = capgd; + xgb = capgb; + xbd = here->MOS9capbd; + xbs = here->MOS9capbs; + /*printf("mos2: xgs=%g, xgd=%g, xgb=%g, xbd=%g, xbs=%g\n", + xgs,xgd,xgb,xbd,xbs);*/ + /* + * load matrix + */ + + *(here->MOS9GgPtr ) += (xgd+xgs+xgb)*s->real; + *(here->MOS9GgPtr +1) += (xgd+xgs+xgb)*s->imag; + *(here->MOS9BbPtr ) += (xgb+xbd+xbs)*s->real; + *(here->MOS9BbPtr +1) += (xgb+xbd+xbs)*s->imag; + *(here->MOS9DPdpPtr ) += (xgd+xbd)*s->real; + *(here->MOS9DPdpPtr +1) += (xgd+xbd)*s->imag; + *(here->MOS9SPspPtr ) += (xgs+xbs)*s->real; + *(here->MOS9SPspPtr +1) += (xgs+xbs)*s->imag; + *(here->MOS9GbPtr ) -= xgb*s->real; + *(here->MOS9GbPtr +1) -= xgb*s->imag; + *(here->MOS9GdpPtr ) -= xgd*s->real; + *(here->MOS9GdpPtr +1) -= xgd*s->imag; + *(here->MOS9GspPtr ) -= xgs*s->real; + *(here->MOS9GspPtr +1) -= xgs*s->imag; + *(here->MOS9BgPtr ) -= xgb*s->real; + *(here->MOS9BgPtr +1) -= xgb*s->imag; + *(here->MOS9BdpPtr ) -= xbd*s->real; + *(here->MOS9BdpPtr +1) -= xbd*s->imag; + *(here->MOS9BspPtr ) -= xbs*s->real; + *(here->MOS9BspPtr +1) -= xbs*s->imag; + *(here->MOS9DPgPtr ) -= xgd*s->real; + *(here->MOS9DPgPtr +1) -= xgd*s->imag; + *(here->MOS9DPbPtr ) -= xbd*s->real; + *(here->MOS9DPbPtr +1) -= xbd*s->imag; + *(here->MOS9SPgPtr ) -= xgs*s->real; + *(here->MOS9SPgPtr +1) -= xgs*s->imag; + *(here->MOS9SPbPtr ) -= xbs*s->real; + *(here->MOS9SPbPtr +1) -= xbs*s->imag; + *(here->MOS9DdPtr) += here->MOS9drainConductance; + *(here->MOS9SsPtr) += here->MOS9sourceConductance; + *(here->MOS9BbPtr) += here->MOS9gbd+here->MOS9gbs; + *(here->MOS9DPdpPtr) += here->MOS9drainConductance+ + here->MOS9gds+here->MOS9gbd+ + xrev*(here->MOS9gm+here->MOS9gmbs); + *(here->MOS9SPspPtr) += here->MOS9sourceConductance+ + here->MOS9gds+here->MOS9gbs+ + xnrm*(here->MOS9gm+here->MOS9gmbs); + *(here->MOS9DdpPtr) -= here->MOS9drainConductance; + *(here->MOS9SspPtr) -= here->MOS9sourceConductance; + *(here->MOS9BdpPtr) -= here->MOS9gbd; + *(here->MOS9BspPtr) -= here->MOS9gbs; + *(here->MOS9DPdPtr) -= here->MOS9drainConductance; + *(here->MOS9DPgPtr) += (xnrm-xrev)*here->MOS9gm; + *(here->MOS9DPbPtr) += -here->MOS9gbd+(xnrm-xrev)*here->MOS9gmbs; + *(here->MOS9DPspPtr) -= here->MOS9gds+ + xnrm*(here->MOS9gm+here->MOS9gmbs); + *(here->MOS9SPgPtr) -= (xnrm-xrev)*here->MOS9gm; + *(here->MOS9SPsPtr) -= here->MOS9sourceConductance; + *(here->MOS9SPbPtr) -= here->MOS9gbs+(xnrm-xrev)*here->MOS9gmbs; + *(here->MOS9SPdpPtr) -= here->MOS9gds+ + xrev*(here->MOS9gm+here->MOS9gmbs); + + } + } + return(OK); +} diff --git a/src/spicelib/devices/mos9/mos9sacl.c b/src/spicelib/devices/mos9/mos9sacl.c new file mode 100644 index 000000000..f9944c695 --- /dev/null +++ b/src/spicelib/devices/mos9/mos9sacl.c @@ -0,0 +1,782 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ + +/* actually load the current ac sensitivity + * information into the array previously provided + */ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "const.h" +#include "mos9defs.h" +#include "sperror.h" +#include "suffix.h" + +int +MOS9sAcLoad(inModel,ckt) +GENmodel *inModel; +CKTcircuit *ckt; +{ + MOS9model *model = (MOS9model *)inModel; + MOS9instance *here; + int xnrm; + int xrev; + double A0; + double Apert; + double DELA; + double DELAinv; + double gdpr0; + double gspr0; + double gds0; + double gbs0; + double gbd0; + double gm0; + double gmbs0; + double gdpr; + double gspr; + double gds; + double gbs; + double gbd; + double gm; + double gmbs; + double xcgs0; + double xcgd0; + double xcgb0; + double xbd0; + double xbs0; + double xcgs; + double xcgd; + double xcgb; + double xbd; + double xbs; + double vbsOp; + double vbdOp; + double vspr; + double vdpr; + double vgs; + double vgd; + double vgb; + double vbs; + double vbd; + double vds; + double ivspr; + double ivdpr; + double ivgs; + double ivgd; + double ivgb; + double ivbs; + double ivbd; + double ivds; + double cspr; + double cdpr; + double cgs; + double cgd; + double cgb; + double cbs; + double cbd; + double cds; + double cs0; + double csprm0; + double cd0; + double cdprm0; + double cg0; + double cb0; + double cs; + double csprm; + double cd; + double cdprm; + double cg; + double cb; + double icspr; + double icdpr; + double icgs; + double icgd; + double icgb; + double icbs; + double icbd; + double icds; + double ics0; + double icsprm0; + double icd0; + double icdprm0; + double icg0; + double icb0; + double ics; + double icsprm; + double icd; + double icdprm; + double icg; + double icb; + double DvDp; + int i; + int flag; + int error; + int iparmno; + double arg; + double sarg; + double sargsw; + double SaveState[44]; + int save_mode; + SENstruct *info; + +#ifdef SENSDEBUG + printf("MOS9senacload\n"); + printf("CKTomega = %.5e\n",ckt->CKTomega); +#endif /* SENSDEBUG */ + info = ckt->CKTsenInfo; + info->SENstatus = PERTURBATION; + for( ; model != NULL; model = model->MOS9nextModel) { + for(here = model->MOS9instances; here!= NULL; + here = here->MOS9nextInstance) { + + /* save the unperturbed values in the state vector */ + for(i=0; i <= 16; i++) + *(SaveState + i) = *(ckt->CKTstate0 + here->MOS9states + i); + + *(SaveState + 17) = here->MOS9sourceConductance; + *(SaveState + 18) = here->MOS9drainConductance; + *(SaveState + 19) = here->MOS9cd; + *(SaveState + 20) = here->MOS9cbs; + *(SaveState + 21) = here->MOS9cbd; + *(SaveState + 22) = here->MOS9gmbs; + *(SaveState + 23) = here->MOS9gm; + *(SaveState + 24) = here->MOS9gds; + *(SaveState + 25) = here->MOS9gbd; + *(SaveState + 26) = here->MOS9gbs; + *(SaveState + 27) = here->MOS9capbd; + *(SaveState + 28) = here->MOS9capbs; + *(SaveState + 29) = here->MOS9Cbd; + *(SaveState + 30) = here->MOS9Cbdsw; + *(SaveState + 31) = here->MOS9Cbs; + *(SaveState + 32) = here->MOS9Cbssw; + *(SaveState + 33) = here->MOS9f2d; + *(SaveState + 34) = here->MOS9f3d; + *(SaveState + 35) = here->MOS9f4d; + *(SaveState + 36) = here->MOS9f2s; + *(SaveState + 37) = here->MOS9f3s; + *(SaveState + 38) = here->MOS9f4s; + *(SaveState + 39) = here->MOS9cgs; + *(SaveState + 40) = here->MOS9cgd; + *(SaveState + 41) = here->MOS9cgb; + *(SaveState + 42) = here->MOS9vdsat; + *(SaveState + 43) = here->MOS9von; + save_mode = here->MOS9mode; + + xnrm=1; + xrev=0; + if (here->MOS9mode < 0) { + xnrm=0; + xrev=1; + } + + vbsOp = model->MOS9type * ( + *(ckt->CKTrhsOp+here->MOS9bNode) - + *(ckt->CKTrhsOp+here->MOS9sNodePrime)); + vbdOp = model->MOS9type * ( + *(ckt->CKTrhsOp+here->MOS9bNode) - + *(ckt->CKTrhsOp+here->MOS9dNodePrime)); + vspr = *(ckt->CKTrhsOld + here->MOS9sNode) + - *(ckt->CKTrhsOld + + here->MOS9sNodePrime) ; + ivspr = *(ckt->CKTirhsOld + here->MOS9sNode) + - *(ckt->CKTirhsOld + + here->MOS9sNodePrime) ; + vdpr = *(ckt->CKTrhsOld + here->MOS9dNode) + - *(ckt->CKTrhsOld + + here->MOS9dNodePrime) ; + ivdpr = *(ckt->CKTirhsOld + here->MOS9dNode) + - *(ckt->CKTirhsOld + + here->MOS9dNodePrime) ; + vgb = *(ckt->CKTrhsOld + here->MOS9gNode) + - *(ckt->CKTrhsOld + + here->MOS9bNode) ; + ivgb = *(ckt->CKTirhsOld + here->MOS9gNode) + - *(ckt->CKTirhsOld + + here->MOS9bNode) ; + vbs = *(ckt->CKTrhsOld + here->MOS9bNode) + - *(ckt->CKTrhsOld + + here->MOS9sNodePrime) ; + ivbs = *(ckt->CKTirhsOld + here->MOS9bNode) + - *(ckt->CKTirhsOld + + here->MOS9sNodePrime) ; + vbd = *(ckt->CKTrhsOld + here->MOS9bNode) + - *(ckt->CKTrhsOld + + here->MOS9dNodePrime) ; + ivbd = *(ckt->CKTirhsOld + here->MOS9bNode) + - *(ckt->CKTirhsOld + + here->MOS9dNodePrime) ; + vds = vbs - vbd ; + ivds = ivbs - ivbd ; + vgs = vgb + vbs ; + ivgs = ivgb + ivbs ; + vgd = vgb + vbd ; + ivgd = ivgb + ivbd ; + +#ifdef SENSDEBUG + printf("senacload instance name %s\n",here->MOS9name); + printf("gate = %d ,drain = %d, drainprm = %d\n", + here->MOS9gNode,here->MOS9dNode,here->MOS9dNodePrime); + printf("source = %d , sourceprm = %d ,body = %d, senparmno = %d\n", + here->MOS9sNode ,here->MOS9sNodePrime, + here->MOS9bNode,here->MOS9senParmNo); + printf("\n without perturbation \n"); +#endif /* SENSDEBUG */ + /* without perturbation */ + *(ckt->CKTstate0 + here->MOS9vbs) = vbsOp; + *(ckt->CKTstate0 + here->MOS9vbd) = vbdOp; + + here->MOS9senPertFlag = ON ; + if(info->SENacpertflag == 1){ + /* store the unperturbed values of small signal parameters */ + if(error = MOS9load((GENmodel*)model,ckt)) return(error); + *(here->MOS9senCgs) = here->MOS9cgs; + *(here->MOS9senCgd) = here->MOS9cgd; + *(here->MOS9senCgb) = here->MOS9cgb; + *(here->MOS9senCbd) = here->MOS9capbd; + *(here->MOS9senCbs) = here->MOS9capbs; + *(here->MOS9senGds) = here->MOS9gds; + *(here->MOS9senGbs) = here->MOS9gbs; + *(here->MOS9senGbd) = here->MOS9gbd; + *(here->MOS9senGm) = here->MOS9gm; + *(here->MOS9senGmbs) = here->MOS9gmbs; + + } + xcgs0= *(here->MOS9senCgs) * ckt->CKTomega; + xcgd0= *(here->MOS9senCgd) * ckt->CKTomega; + xcgb0= *(here->MOS9senCgb) * ckt->CKTomega; + xbd0= *(here->MOS9senCbd) * ckt->CKTomega; + xbs0= *(here->MOS9senCbs) * ckt->CKTomega; + gds0= *(here->MOS9senGds); + gbs0= *(here->MOS9senGbs); + gbd0= *(here->MOS9senGbd); + gm0= *(here->MOS9senGm); + gmbs0= *(here->MOS9senGmbs); + gdpr0 = here->MOS9drainConductance; + gspr0 = here->MOS9sourceConductance; + + + cspr = gspr0 * vspr ; + icspr = gspr0 * ivspr ; + cdpr = gdpr0 * vdpr ; + icdpr = gdpr0 * ivdpr ; + cgs = ( - xcgs0 * ivgs ); + icgs = xcgs0 * vgs ; + cgd = ( - xcgd0 * ivgd ); + icgd = xcgd0 * vgd ; + cgb = ( - xcgb0 * ivgb ); + icgb = xcgb0 * vgb ; + cbs = ( gbs0 * vbs - xbs0 * ivbs ); + icbs = ( xbs0 * vbs + gbs0 * ivbs ); + cbd = ( gbd0 * vbd - xbd0 * ivbd ); + icbd = ( xbd0 * vbd + gbd0 * ivbd ); + cds = ( gds0 * vds + xnrm * (gm0 * vgs + gmbs0 * vbs) + - xrev * (gm0 * vgd + gmbs0 * vbd) ); + icds = ( gds0 * ivds + xnrm * (gm0 * ivgs + gmbs0 * ivbs) + - xrev * (gm0 * ivgd + gmbs0 * ivbd) ); + + cs0 = cspr; + ics0 = icspr; + csprm0 = ( -cspr - cgs - cbs - cds ) ; + icsprm0 = ( -icspr - icgs - icbs - icds ) ; + cd0 = cdpr; + icd0 = icdpr; + cdprm0 = ( -cdpr - cgd - cbd + cds ) ; + icdprm0 = ( -icdpr - icgd - icbd + icds ) ; + cg0 = cgs + cgd + cgb ; + icg0 = icgs + icgd + icgb ; + cb0 = cbs + cbd - cgb ; + icb0 = icbs + icbd - icgb ; +#ifdef SENSDEBUG + printf("gspr0 = %.7e , gdpr0 = %.7e , gds0 = %.7e, gbs0 = %.7e\n", + gspr0,gdpr0,gds0,gbs0); + printf("gbd0 = %.7e , gm0 = %.7e , gmbs0 = %.7e\n",gbd0,gm0,gmbs0); + printf("xcgs0 = %.7e , xcgd0 = %.7e ,", xcgs0,xcgd0); + printf("xcgb0 = %.7e, xbd0 = %.7e,xbs0 = %.7e\n" ,xcgb0,xbd0,xbs0); + printf("vbs = %.7e , vbd = %.7e , vgb = %.7e\n",vbs,vbd,vgb); + printf("ivbs = %.7e , ivbd = %.7e , ivgb = %.7e\n",ivbs,ivbd,ivgb); + printf("cbs0 = %.7e , cbd0 = %.7e , cgb0 = %.7e\n",cbs,cbd,cgb); + printf("cb0 = %.7e , cg0 = %.7e , cs0 = %.7e\n",cb0,cg0,cs0); + printf("csprm0 = %.7e, cd0 = %.7e, cdprm0 = %.7e\n", + csprm0,cd0,cdprm0); + printf("icb0 = %.7e , icg0 = %.7e , ics0 = %.7e\n",icb0,icg0,ics0); + printf("icsprm0 = %.7e, icd0 = %.7e, icdprm0 = %.7e\n", + icsprm0,icd0,icdprm0); + printf("\nPerturbation of vbs\n"); +#endif /* SENSDEBUG */ + + /* Perturbation of vbs */ + flag = 1; + A0 = vbsOp; + DELA = info->SENpertfac * CONSTvt0 ; + DELAinv = 1.0/DELA; + + if(info->SENacpertflag == 1){ + /* store the values of small signal parameters + * corresponding to perturbed vbs */ + Apert = A0 + DELA; + *(ckt->CKTstate0 + here->MOS9vbs) = Apert; + *(ckt->CKTstate0 + here->MOS9vbd) = vbdOp; + + if(error = MOS9load((GENmodel*)model,ckt)) return(error); + + *(here->MOS9senCgs + 1) = here->MOS9cgs; + *(here->MOS9senCgd + 1) = here->MOS9cgd; + *(here->MOS9senCgb + 1) = here->MOS9cgb; + *(here->MOS9senCbd + 1) = here->MOS9capbd; + *(here->MOS9senCbs + 1) = here->MOS9capbs; + *(here->MOS9senGds + 1) = here->MOS9gds; + *(here->MOS9senGbs + 1) = here->MOS9gbs; + *(here->MOS9senGbd + 1) = here->MOS9gbd; + *(here->MOS9senGm + 1) = here->MOS9gm; + *(here->MOS9senGmbs + 1) = here->MOS9gmbs; + + *(ckt->CKTstate0 + here->MOS9vbs) = A0; + + + } + + goto load; + + +pertvbd: /* Perturbation of vbd */ +#ifdef SENSDEBUG + printf("\nPerturbation of vbd\n"); +#endif /* SENSDEBUG */ + + flag = 2; + A0 = vbdOp; + DELA = info->SENpertfac * CONSTvt0 + 1e-8; + DELAinv = 1.0/DELA; + + if(info->SENacpertflag == 1){ + /* store the values of small signal parameters + * corresponding to perturbed vbd */ + Apert = A0 + DELA; + *(ckt->CKTstate0 + here->MOS9vbs) = vbsOp; + *(ckt->CKTstate0 + here->MOS9vbd) = Apert; + + if(error = MOS9load((GENmodel*)model,ckt)) return(error); + + *(here->MOS9senCgs + 2) = here->MOS9cgs; + *(here->MOS9senCgd + 2) = here->MOS9cgd; + *(here->MOS9senCgb + 2) = here->MOS9cgb; + *(here->MOS9senCbd + 2) = here->MOS9capbd; + *(here->MOS9senCbs + 2) = here->MOS9capbs; + *(here->MOS9senGds + 2) = here->MOS9gds; + *(here->MOS9senGbs + 2) = here->MOS9gbs; + *(here->MOS9senGbd + 2) = here->MOS9gbd; + *(here->MOS9senGm + 2) = here->MOS9gm; + *(here->MOS9senGmbs + 2) = here->MOS9gmbs; + + *(ckt->CKTstate0 + here->MOS9vbd) = A0; + + } + + goto load; + + +pertvgb: /* Perturbation of vgb */ +#ifdef SENSDEBUG + printf("\nPerturbation of vgb\n"); +#endif /* SENSDEBUG */ + + flag = 3; + A0 = model->MOS9type * (*(ckt->CKTrhsOp + here->MOS9gNode) + - *(ckt->CKTrhsOp + here->MOS9bNode)); + DELA = info->SENpertfac * A0 + 1e-8; + DELAinv = model->MOS9type * 1.0/DELA; + + + if(info->SENacpertflag == 1){ + /* store the values of small signal parameters + * corresponding to perturbed vgb */ + *(ckt->CKTstate0 + here->MOS9vbs) = vbsOp; + *(ckt->CKTstate0 + here->MOS9vbd) = vbdOp; + *(ckt->CKTrhsOp + here->MOS9bNode) -= DELA; + + if(error = MOS9load((GENmodel*)model,ckt)) return(error); + + *(here->MOS9senCgs + 3) = here->MOS9cgs; + *(here->MOS9senCgd + 3) = here->MOS9cgd; + *(here->MOS9senCgb + 3) = here->MOS9cgb; + *(here->MOS9senCbd + 3) = here->MOS9capbd; + *(here->MOS9senCbs + 3) = here->MOS9capbs; + *(here->MOS9senGds + 3) = here->MOS9gds; + *(here->MOS9senGbs + 3) = here->MOS9gbs; + *(here->MOS9senGbd + 3) = here->MOS9gbd; + *(here->MOS9senGm + 3) = here->MOS9gm; + *(here->MOS9senGmbs + 3) = here->MOS9gmbs; + + + *(ckt->CKTrhsOp + here->MOS9bNode) += DELA; + } + goto load; + +pertl: /* Perturbation of length */ + + if(here->MOS9sens_l == 0){ + goto pertw; + } +#ifdef SENSDEBUG + printf("\nPerturbation of length\n"); +#endif /* SENSDEBUG */ + flag = 4; + A0 = here->MOS9l; + DELA = info->SENpertfac * A0; + DELAinv = 1.0/DELA; + + if(info->SENacpertflag == 1){ + /* store the values of small signal parameters + * corresponding to perturbed length */ + Apert = A0 + DELA; + here->MOS9l = Apert; + + *(ckt->CKTstate0 + here->MOS9vbs) = vbsOp; + *(ckt->CKTstate0 + here->MOS9vbd) = vbdOp; + + if(error = MOS9load((GENmodel*)model,ckt)) return(error); + + *(here->MOS9senCgs + 4) = here->MOS9cgs; + *(here->MOS9senCgd + 4) = here->MOS9cgd; + *(here->MOS9senCgb + 4) = here->MOS9cgb; + *(here->MOS9senCbd + 4) = here->MOS9capbd; + *(here->MOS9senCbs + 4) = here->MOS9capbs; + *(here->MOS9senGds + 4) = here->MOS9gds; + *(here->MOS9senGbs + 4) = here->MOS9gbs; + *(here->MOS9senGbd + 4) = here->MOS9gbd; + *(here->MOS9senGm + 4) = here->MOS9gm; + *(here->MOS9senGmbs + 4) = here->MOS9gmbs; + + here->MOS9l = A0; + + } + + goto load; + +pertw: /* Perturbation of width */ + if(here->MOS9sens_w == 0) + goto next; +#ifdef SENSDEBUG + printf("\nPerturbation of width\n"); +#endif /* SENSDEBUG */ + flag = 5; + A0 = here->MOS9w; + DELA = info->SENpertfac * A0; + DELAinv = 1.0/DELA; + Apert = A0 + DELA; + + if(info->SENacpertflag == 1){ + /* store the values of small signal parameters + * corresponding to perturbed width */ + here->MOS9w = Apert; + here->MOS9drainArea *= (1 + info->SENpertfac); + here->MOS9sourceArea *= (1 + info->SENpertfac); + here->MOS9Cbd *= (1 + info->SENpertfac); + here->MOS9Cbs *= (1 + info->SENpertfac); + if(here->MOS9drainPerimiter){ + here->MOS9Cbdsw += here->MOS9Cbdsw * + DELA/here->MOS9drainPerimiter; + } + if(here->MOS9sourcePerimiter){ + here->MOS9Cbssw += here->MOS9Cbssw * + DELA/here->MOS9sourcePerimiter; + } + if(vbdOp >= here->MOS9tDepCap){ + arg = 1-model->MOS9fwdCapDepCoeff; + sarg = exp( (-model->MOS9bulkJctBotGradingCoeff) * + log(arg) ); + sargsw = exp( (-model->MOS9bulkJctSideGradingCoeff) * + log(arg) ); + here->MOS9f2d = here->MOS9Cbd*(1-model->MOS9fwdCapDepCoeff* + (1+model->MOS9bulkJctBotGradingCoeff))* sarg/arg + + here->MOS9Cbdsw*(1-model->MOS9fwdCapDepCoeff* + (1+model->MOS9bulkJctSideGradingCoeff))* + sargsw/arg; + here->MOS9f3d = here->MOS9Cbd * + model->MOS9bulkJctBotGradingCoeff * sarg/arg/ + model->MOS9bulkJctPotential + + here->MOS9Cbdsw * + model->MOS9bulkJctSideGradingCoeff * sargsw/arg / + model->MOS9bulkJctPotential; + here->MOS9f4d = here->MOS9Cbd*model->MOS9bulkJctPotential* + (1-arg*sarg)/ (1-model->MOS9bulkJctBotGradingCoeff) + + here->MOS9Cbdsw*model->MOS9bulkJctPotential* + (1-arg*sargsw)/ + (1-model->MOS9bulkJctSideGradingCoeff) + -here->MOS9f3d/2* + (here->MOS9tDepCap*here->MOS9tDepCap) + -here->MOS9tDepCap * here->MOS9f2d; + } + if(vbsOp >= here->MOS9tDepCap){ + arg = 1-model->MOS9fwdCapDepCoeff; + sarg = exp( (-model->MOS9bulkJctBotGradingCoeff) * + log(arg) ); + sargsw = exp( (-model->MOS9bulkJctSideGradingCoeff) * + log(arg) ); + here->MOS9f2s = here->MOS9Cbs*(1-model->MOS9fwdCapDepCoeff* + (1+model->MOS9bulkJctBotGradingCoeff))* sarg/arg + + here->MOS9Cbssw*(1-model->MOS9fwdCapDepCoeff* + (1+model->MOS9bulkJctSideGradingCoeff))* + sargsw/arg; + here->MOS9f3s = here->MOS9Cbs * + model->MOS9bulkJctBotGradingCoeff * sarg/arg/ + model->MOS9bulkJctPotential + here->MOS9Cbssw * + model->MOS9bulkJctSideGradingCoeff * sargsw/arg / + model->MOS9bulkJctPotential; + here->MOS9f4s = here->MOS9Cbs*model->MOS9bulkJctPotential* + (1-arg*sarg)/ (1-model->MOS9bulkJctBotGradingCoeff) + + here->MOS9Cbssw*model->MOS9bulkJctPotential* + (1-arg*sargsw)/ + (1-model->MOS9bulkJctSideGradingCoeff) + -here->MOS9f3s/2* + (here->MOS9tBulkPot*here->MOS9tBulkPot) + -here->MOS9tBulkPot * here->MOS9f2s; + } + + *(ckt->CKTstate0 + here->MOS9vbs) = vbsOp; + *(ckt->CKTstate0 + here->MOS9vbd) = vbdOp; + + if(error = MOS9load((GENmodel*)model,ckt)) return(error); + + *(here->MOS9senCgs + 5) = here->MOS9cgs; + *(here->MOS9senCgd + 5) = here->MOS9cgd; + *(here->MOS9senCgb + 5) = here->MOS9cgb; + *(here->MOS9senCbd + 5) = here->MOS9capbd; + *(here->MOS9senCbs + 5) = here->MOS9capbs; + *(here->MOS9senGds + 5) = here->MOS9gds; + *(here->MOS9senGbs + 5) = here->MOS9gbs; + *(here->MOS9senGbd + 5) = here->MOS9gbd; + *(here->MOS9senGm + 5) = here->MOS9gm; + *(here->MOS9senGmbs + 5) = here->MOS9gmbs; + + here->MOS9w = A0; + here->MOS9drainArea /= (1 + info->SENpertfac); + here->MOS9sourceArea /= (1 + info->SENpertfac); + } + +load: + + gds= *(here->MOS9senGds + flag); + gbs= *(here->MOS9senGbs + flag); + gbd= *(here->MOS9senGbd + flag); + gm= *(here->MOS9senGm + flag); + gmbs= *(here->MOS9senGmbs + flag); + if(flag == 5){ + gdpr = here->MOS9drainConductance * Apert/A0; + gspr = here->MOS9sourceConductance * Apert/A0; + } + else{ + gdpr = here->MOS9drainConductance; + gspr = here->MOS9sourceConductance; + } + + xcgs= *(here->MOS9senCgs + flag) * ckt->CKTomega; + xcgd= *(here->MOS9senCgd + flag) * ckt->CKTomega; + xcgb= *(here->MOS9senCgb + flag) * ckt->CKTomega; + xbd= *(here->MOS9senCbd + flag) * ckt->CKTomega; + xbs= *(here->MOS9senCbs + flag) * ckt->CKTomega; + +#ifdef SENSDEBUG + printf("flag = %d \n",flag); + printf("gspr = %.7e , gdpr = %.7e , gds = %.7e, gbs = %.7e\n", + gspr,gdpr,gds,gbs); + printf("gbd = %.7e , gm = %.7e , gmbs = %.7e\n",gbd,gm,gmbs); + printf("xcgs = %.7e , xcgd = %.7e , xcgb = %.7e,", xcgs,xcgd,xcgb); + printf("xbd = %.7e,xbs = %.7e\n" ,xbd,xbs); +#endif /* SENSDEBUG */ + cspr = gspr * vspr ; + icspr = gspr * ivspr ; + cdpr = gdpr * vdpr ; + icdpr = gdpr * ivdpr ; + cgs = ( - xcgs * ivgs ); + icgs = xcgs * vgs ; + cgd = ( - xcgd * ivgd ); + icgd = xcgd * vgd ; + cgb = ( - xcgb * ivgb ); + icgb = xcgb * vgb ; + cbs = ( gbs * vbs - xbs * ivbs ); + icbs = ( xbs * vbs + gbs * ivbs ); + cbd = ( gbd * vbd - xbd * ivbd ); + icbd = ( xbd * vbd + gbd * ivbd ); + cds = ( gds * vds + xnrm * (gm * vgs + gmbs * vbs) + - xrev * (gm * vgd + gmbs * vbd) ); + icds = ( gds * ivds + xnrm * (gm * ivgs + gmbs * ivbs) + - xrev * (gm * ivgd + gmbs * ivbd) ); + + cs = cspr; + ics = icspr; + csprm = ( -cspr - cgs - cbs - cds ) ; + icsprm = ( -icspr - icgs - icbs - icds ) ; + cd = cdpr; + icd = icdpr; + cdprm = ( -cdpr - cgd - cbd + cds ) ; + icdprm = ( -icdpr - icgd - icbd + icds ) ; + cg = cgs + cgd + cgb ; + icg = icgs + icgd + icgb ; + cb = cbs + cbd - cgb ; + icb = icbs + icbd - icgb ; + +#ifdef SENSDEBUG + printf("vbs = %.7e , vbd = %.7e , vgb = %.7e\n",vbs,vbd,vgb); + printf("ivbs = %.7e , ivbd = %.7e , ivgb = %.7e\n",ivbs,ivbd,ivgb); + printf("cbs = %.7e , cbd = %.7e , cgb = %.7e\n",cbs,cbd,cgb); + printf("cb = %.7e , cg = %.7e , cs = %.7e\n",cb,cg,cs); + printf("csprm = %.7e, cd = %.7e, cdprm = %.7e\n",csprm,cd,cdprm); + printf("icb = %.7e , icg = %.7e , ics = %.7e\n",icb,icg,ics); + printf("icsprm = %.7e, icd = %.7e, icdprm = %.7e\n", + icsprm,icd,icdprm); +#endif /* SENSDEBUG */ + for(iparmno = 1;iparmno<=info->SENparms;iparmno++){ + if( (flag == 4) && (iparmno != here->MOS9senParmNo) ) continue; + if( (flag == 5) && (iparmno != (here->MOS9senParmNo + + here->MOS9sens_l)) ) continue; + + switch(flag){ + case 1: + DvDp = model->MOS9type * + (info->SEN_Sap[here->MOS9bNode][iparmno] + - info->SEN_Sap[here->MOS9sNodePrime][iparmno]); + break; + case 2: + DvDp = model->MOS9type * + ( info->SEN_Sap[here->MOS9bNode][iparmno] + - info->SEN_Sap[here->MOS9dNodePrime][iparmno]); + break; + case 3: + DvDp = model->MOS9type * + ( info->SEN_Sap[here->MOS9gNode][iparmno] + - info->SEN_Sap[here->MOS9bNode][iparmno]); + break; + case 4: + DvDp = 1; + break; + case 5: + DvDp = 1; + break; + } + *(info->SEN_RHS[here->MOS9bNode] + iparmno) -= + ( cb - cb0) * DELAinv * DvDp; + *(info->SEN_iRHS[here->MOS9bNode] + iparmno) -= + ( icb - icb0) * DELAinv * DvDp; + + *(info->SEN_RHS[here->MOS9gNode] + iparmno) -= + ( cg - cg0) * DELAinv * DvDp; + *(info->SEN_iRHS[here->MOS9gNode] + iparmno) -= + ( icg - icg0) * DELAinv * DvDp; + + if(here->MOS9sNode != here->MOS9sNodePrime){ + *(info->SEN_RHS[here->MOS9sNode] + iparmno) -= + ( cs - cs0) * DELAinv * DvDp; + *(info->SEN_iRHS[here->MOS9sNode] + iparmno) -= + ( ics - ics0) * DELAinv * DvDp; + } + + *(info->SEN_RHS[here->MOS9sNodePrime] + iparmno) -= + ( csprm - csprm0) * DELAinv * DvDp; + *(info->SEN_iRHS[here->MOS9sNodePrime] + iparmno) -= + ( icsprm - icsprm0) * DELAinv * DvDp; + + if(here->MOS9dNode != here->MOS9dNodePrime){ + *(info->SEN_RHS[here->MOS9dNode] + iparmno) -= + ( cd - cd0) * DELAinv * DvDp; + *(info->SEN_iRHS[here->MOS9dNode] + iparmno) -= + ( icd - icd0) * DELAinv * DvDp; + } + + *(info->SEN_RHS[here->MOS9dNodePrime] + iparmno) -= + ( cdprm - cdprm0) * DELAinv * DvDp; + *(info->SEN_iRHS[here->MOS9dNodePrime] + iparmno) -= + ( icdprm - icdprm0) * DELAinv * DvDp; +#ifdef SENSDEBUG + printf("after loading\n"); + printf("DvDp = %.5e , DELAinv = %.5e ,flag = %d ,", + DvDp,DELAinv,flag); + printf("iparmno = %d,senparmno = %d\n", + iparmno,here->MOS9senParmNo); + printf("A0 = %.5e , Apert = %.5e ,CONSTvt0 = %.5e \n", + A0,Apert,CONSTvt0); + printf("senb = %.7e + j%.7e ", + *(info->SEN_RHS[here->MOS9bNode] + iparmno), + *(info->SEN_iRHS[here->MOS9bNode] + iparmno)); + printf("seng = %.7e + j%.7e ", + *(info->SEN_RHS[here->MOS9gNode] + iparmno), + *(info->SEN_iRHS[here->MOS9gNode] + iparmno)); + printf("sens = %.7e + j%.7e ", + *(info->SEN_RHS[here->MOS9sNode] + iparmno), + *(info->SEN_iRHS[here->MOS9sNode] + iparmno)); + printf("sensprm = %.7e + j%.7e ", + *(info->SEN_RHS[here->MOS9sNodePrime] + iparmno), + *(info->SEN_iRHS[here->MOS9sNodePrime] + iparmno)); + printf("send = %.7e + j%.7e ", + *(info->SEN_RHS[here->MOS9dNode] + iparmno), + *(info->SEN_iRHS[here->MOS9dNode] + iparmno)); + printf("sendprm = %.7e + j%.7e ", + *(info->SEN_RHS[here->MOS9dNodePrime] + iparmno), + *(info->SEN_iRHS[here->MOS9dNodePrime] + iparmno)); +#endif /* SENSDEBUG */ + + } + switch(flag){ + case 1: + goto pertvbd ; + case 2: + goto pertvgb ; + case 3: + goto pertl ; + case 4: + goto pertw ; + case 5: + break; + } +next: + ; + + /* put the unperturbed values back into the state vector */ + for(i=0; i <= 16; i++) + *(ckt->CKTstate0 + here->MOS9states + i) = *(SaveState + i); + + here->MOS9sourceConductance = *(SaveState + 17) ; + here->MOS9drainConductance = *(SaveState + 18) ; + here->MOS9cd = *(SaveState + 19) ; + here->MOS9cbs = *(SaveState + 20) ; + here->MOS9cbd = *(SaveState + 21) ; + here->MOS9gmbs = *(SaveState + 22) ; + here->MOS9gm = *(SaveState + 23) ; + here->MOS9gds = *(SaveState + 24) ; + here->MOS9gbd = *(SaveState + 25) ; + here->MOS9gbs = *(SaveState + 26) ; + here->MOS9capbd = *(SaveState + 27) ; + here->MOS9capbs = *(SaveState + 28) ; + here->MOS9Cbd = *(SaveState + 29) ; + here->MOS9Cbdsw = *(SaveState + 30) ; + here->MOS9Cbs = *(SaveState + 31) ; + here->MOS9Cbssw = *(SaveState + 32) ; + here->MOS9f2d = *(SaveState + 33) ; + here->MOS9f3d = *(SaveState + 34) ; + here->MOS9f4d = *(SaveState + 35) ; + here->MOS9f2s = *(SaveState + 36) ; + here->MOS9f3s = *(SaveState + 37) ; + here->MOS9f4s = *(SaveState + 38) ; + here->MOS9cgs = *(SaveState + 39) ; + here->MOS9cgd = *(SaveState + 40) ; + here->MOS9cgb = *(SaveState + 41) ; + here->MOS9vdsat = *(SaveState + 42) ; + here->MOS9von = *(SaveState + 43) ; + here->MOS9mode = save_mode ; + + here->MOS9senPertFlag = OFF; + } + } + info->SENstatus = NORMAL; +#ifdef SENSDEBUG + printf("MOS9senacload end\n"); +#endif /* SENSDEBUG */ + return(OK); +} + + diff --git a/src/spicelib/devices/mos9/mos9set.c b/src/spicelib/devices/mos9/mos9set.c new file mode 100644 index 000000000..728093b0e --- /dev/null +++ b/src/spicelib/devices/mos9/mos9set.c @@ -0,0 +1,294 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "mos9defs.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + +/* assuming silicon - make definition for epsilon of silicon */ +#define EPSSIL (11.7 * 8.854214871e-12) + +int +MOS9setup(matrix,inModel,ckt,states) + SMPmatrix *matrix; + GENmodel *inModel; + CKTcircuit *ckt; + int *states; + /* load the MOS9 device structure with those pointers needed later + * for fast matrix loading + */ + +{ + register MOS9model *model = (MOS9model *)inModel; + register MOS9instance *here; + int error; + CKTnode *tmp; + + /* loop through all the MOS9 device models */ + for( ; model != NULL; model = model->MOS9nextModel ) { + + /* perform model defaulting */ + if(!model->MOS9typeGiven) { + model->MOS9type = NMOS; + } + if(!model->MOS9latDiffGiven) { + model->MOS9latDiff = 0; + } + if(!model->MOS9lengthAdjustGiven) { + model->MOS9lengthAdjust = 0; + } + if(!model->MOS9widthNarrowGiven) { + model->MOS9widthNarrow = 0; + } + if(!model->MOS9widthAdjustGiven) { + model->MOS9widthAdjust = 0; + } + if(!model->MOS9delvt0Given) { + model->MOS9delvt0 = 0; + } + if(!model->MOS9jctSatCurDensityGiven) { + model->MOS9jctSatCurDensity = 0; + } + if(!model->MOS9jctSatCurGiven) { + model->MOS9jctSatCur = 1e-14; + } + if(!model->MOS9drainResistanceGiven) { + model->MOS9drainResistance = 0; + } + if(!model->MOS9sourceResistanceGiven) { + model->MOS9sourceResistance = 0; + } + if(!model->MOS9sheetResistanceGiven) { + model->MOS9sheetResistance = 0; + } + if(!model->MOS9transconductanceGiven) { + model->MOS9transconductance = 2e-5; + } + if(!model->MOS9gateSourceOverlapCapFactorGiven) { + model->MOS9gateSourceOverlapCapFactor = 0; + } + if(!model->MOS9gateDrainOverlapCapFactorGiven) { + model->MOS9gateDrainOverlapCapFactor = 0; + } + if(!model->MOS9gateBulkOverlapCapFactorGiven) { + model->MOS9gateBulkOverlapCapFactor = 0; + } + if(!model->MOS9vt0Given) { + model->MOS9vt0 = 0; + } + if(!model->MOS9capBDGiven) { + model->MOS9capBD = 0; + } + if(!model->MOS9capBSGiven) { + model->MOS9capBS = 0; + } + if(!model->MOS9bulkCapFactorGiven) { + model->MOS9bulkCapFactor = 0; + } + if(!model->MOS9sideWallCapFactorGiven) { + model->MOS9sideWallCapFactor = 0; + } + if(!model->MOS9bulkJctPotentialGiven) { + model->MOS9bulkJctPotential = .8; + } + if(!model->MOS9bulkJctBotGradingCoeffGiven) { + model->MOS9bulkJctBotGradingCoeff = .5; + } + if(!model->MOS9bulkJctSideGradingCoeffGiven) { + model->MOS9bulkJctSideGradingCoeff = .33; + } + if(!model->MOS9fwdCapDepCoeffGiven) { + model->MOS9fwdCapDepCoeff = .5; + } + if(!model->MOS9phiGiven) { + model->MOS9phi = .6; + } + if(!model->MOS9gammaGiven) { + model->MOS9gamma = 0; + } + if(!model->MOS9deltaGiven) { + model->MOS9delta = 0; + } + if(!model->MOS9maxDriftVelGiven) { + model->MOS9maxDriftVel = 0; + } + if(!model->MOS9junctionDepthGiven) { + model->MOS9junctionDepth = 0; + } + if(!model->MOS9fastSurfaceStateDensityGiven) { + model->MOS9fastSurfaceStateDensity = 0; + } + if(!model->MOS9etaGiven) { + model->MOS9eta = 0; + } + if(!model->MOS9thetaGiven) { + model->MOS9theta = 0; + } + if(!model->MOS9kappaGiven) { + model->MOS9kappa = .2; + } + if(!model->MOS9oxideThicknessGiven) { + model->MOS9oxideThickness = 1e-7; + } + if(!model->MOS9fNcoefGiven) { + model->MOS9fNcoef = 0; + } + if(!model->MOS9fNexpGiven) { + model->MOS9fNexp = 1; + } + + /* loop through all the instances of the model */ + for (here = model->MOS9instances; here != NULL ; + here=here->MOS9nextInstance) { + + CKTnode *tmpNode; + IFuid tmpName; + + /* allocate a chunk of the state vector */ + here->MOS9states = *states; + *states += MOS9NUMSTATES; + + if(!here->MOS9drainAreaGiven) { + here->MOS9drainArea = ckt->CKTdefaultMosAD; + } + if(!here->MOS9drainPerimiterGiven) { + here->MOS9drainPerimiter = 0; + } + if(!here->MOS9drainSquaresGiven) { + here->MOS9drainSquares = 1; + } + if(!here->MOS9icVBSGiven) { + here->MOS9icVBS = 0; + } + if(!here->MOS9icVDSGiven) { + here->MOS9icVDS = 0; + } + if(!here->MOS9icVGSGiven) { + here->MOS9icVGS = 0; + } + if(!here->MOS9sourcePerimiterGiven) { + here->MOS9sourcePerimiter = 0; + } + if(!here->MOS9sourceSquaresGiven) { + here->MOS9sourceSquares = 1; + } + if(!here->MOS9vdsatGiven) { + here->MOS9vdsat = 0; + } + if(!here->MOS9vonGiven) { + here->MOS9von = 0; + } + if(!here->MOS9modeGiven) { + here->MOS9mode = 1; + } + + if((model->MOS9drainResistance != 0 || + (model->MOS9sheetResistance != 0 && + here->MOS9drainSquares != 0 ) ) && + here->MOS9dNodePrime==0) { + error = CKTmkVolt(ckt,&tmp,here->MOS9name,"internal#drain"); + if(error) return(error); + here->MOS9dNodePrime = 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->MOS9dNodePrime = here->MOS9dNode; + } + + if((model->MOS9sourceResistance != 0 || + (model->MOS9sheetResistance != 0 && + here->MOS9sourceSquares != 0 ) ) && + here->MOS9sNodePrime==0) { + error = CKTmkVolt(ckt,&tmp,here->MOS9name,"internal#source"); + if(error) return(error); + here->MOS9sNodePrime = 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->MOS9sNodePrime = here->MOS9sNode; + } + +/* macro to make elements with built in test for out of memory */ +#define TSTALLOC(ptr,first,second) \ +if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ + return(E_NOMEM);\ +} + + TSTALLOC(MOS9DdPtr, MOS9dNode, MOS9dNode) + TSTALLOC(MOS9GgPtr, MOS9gNode, MOS9gNode) + TSTALLOC(MOS9SsPtr, MOS9sNode, MOS9sNode) + TSTALLOC(MOS9BbPtr, MOS9bNode, MOS9bNode) + TSTALLOC(MOS9DPdpPtr, MOS9dNodePrime, MOS9dNodePrime) + TSTALLOC(MOS9SPspPtr, MOS9sNodePrime, MOS9sNodePrime) + TSTALLOC(MOS9DdpPtr, MOS9dNode, MOS9dNodePrime) + TSTALLOC(MOS9GbPtr, MOS9gNode, MOS9bNode) + TSTALLOC(MOS9GdpPtr, MOS9gNode, MOS9dNodePrime) + TSTALLOC(MOS9GspPtr, MOS9gNode, MOS9sNodePrime) + TSTALLOC(MOS9SspPtr, MOS9sNode, MOS9sNodePrime) + TSTALLOC(MOS9BdpPtr, MOS9bNode, MOS9dNodePrime) + TSTALLOC(MOS9BspPtr, MOS9bNode, MOS9sNodePrime) + TSTALLOC(MOS9DPspPtr, MOS9dNodePrime, MOS9sNodePrime) + TSTALLOC(MOS9DPdPtr, MOS9dNodePrime, MOS9dNode) + TSTALLOC(MOS9BgPtr, MOS9bNode, MOS9gNode) + TSTALLOC(MOS9DPgPtr, MOS9dNodePrime, MOS9gNode) + TSTALLOC(MOS9SPgPtr, MOS9sNodePrime, MOS9gNode) + TSTALLOC(MOS9SPsPtr, MOS9sNodePrime, MOS9sNode) + TSTALLOC(MOS9DPbPtr, MOS9dNodePrime, MOS9bNode) + TSTALLOC(MOS9SPbPtr, MOS9sNodePrime, MOS9bNode) + TSTALLOC(MOS9SPdpPtr, MOS9sNodePrime, MOS9dNodePrime) + + } + } + return(OK); +} + +int +MOS9unsetup(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + MOS9model *model; + MOS9instance *here; + + for (model = (MOS9model *)inModel; model != NULL; + model = model->MOS9nextModel) + { + for (here = model->MOS9instances; here != NULL; + here=here->MOS9nextInstance) + { + if (here->MOS9dNodePrime + && here->MOS9dNodePrime != here->MOS9dNode) + { + CKTdltNNum(ckt, here->MOS9dNodePrime); + here->MOS9dNodePrime= 0; + } + if (here->MOS9sNodePrime + && here->MOS9sNodePrime != here->MOS9sNode) + { + CKTdltNNum(ckt, here->MOS9sNodePrime); + here->MOS9sNodePrime= 0; + } + } + } + return OK; +} diff --git a/src/spicelib/devices/mos9/mos9sld.c b/src/spicelib/devices/mos9/mos9sld.c new file mode 100644 index 000000000..088653fe0 --- /dev/null +++ b/src/spicelib/devices/mos9/mos9sld.c @@ -0,0 +1,625 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ + +/* actually load the current sensitivity + * information into the array previously provided + */ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "mos9defs.h" +#include "sperror.h" +#include "suffix.h" + +int +MOS9sLoad(inModel,ckt) +GENmodel *inModel; +CKTcircuit *ckt; +{ + MOS9model *model = (MOS9model *)inModel; + MOS9instance *here; + double SaveState[44]; + int save_mode; + int i; + int iparmno; + int error; + int flag; + double A0; + double DELA; + double Apert; + double DELAinv; + double gspr0; + double gspr; + double gdpr0; + double gdpr; + double cdpr0; + double cspr0; + double cd0; + double cbd0; + double cbs0; + double cd; + double cbd; + double cbs; + double DcdprDp; + double DcsprDp; + double DcbDp; + double DcdDp; + double DcbsDp; + double DcbdDp; + double DcdprmDp; + double DcsprmDp; + double qgs0; + double qgd0; + double qgb0; + double qbd0; + double qbd; + double qbs0; + double qbs; + double DqgsDp; + double DqgdDp; + double DqgbDp; + double DqbdDp; + double DqbsDp; + double Osxpgs; + double Osxpgd; + double Osxpgb; + double Osxpbd; + double Osxpbs; + double tag0; + double tag1; + double arg; + double sarg; + double sargsw; + int offset; + double EffectiveLength; + double EffectiveWidth; + SENstruct *info; + +#ifdef SENSDEBUG + printf("MOS9senload \n"); + printf("CKTtime = %.5e\n",ckt->CKTtime); + printf("CKTorder = %d\n",ckt->CKTorder); +#endif /* SENSDEBUG */ + + info = ckt->CKTsenInfo; + info->SENstatus = PERTURBATION; + + tag0 = ckt->CKTag[0]; + tag1 = ckt->CKTag[1]; + if(ckt->CKTorder == 1){ + tag1 = 0; + } + + /* loop through all the models */ + for( ; model != NULL; model = model->MOS9nextModel ) { + + /* loop through all the instances of the model */ + for (here = model->MOS9instances; here != NULL ; + here=here->MOS9nextInstance) { + + +#ifdef SENSDEBUG + printf("senload instance name %s\n",here->MOS9name); + printf("gate = %d ,drain = %d, drainprm = %d\n", + here->MOS9gNode,here->MOS9dNode,here->MOS9dNodePrime); + printf("source = %d , sourceprm = %d ,body = %d, senparmno = %d\n", + here->MOS9sNode ,here->MOS9sNodePrime, + here->MOS9bNode,here->MOS9senParmNo); +#endif /* SENSDEBUG */ + + + /* save the unperturbed values in the state vector */ + for(i=0; i <= 16; i++){ + *(SaveState + i) = *(ckt->CKTstate0 + here->MOS9states + i); + } + + *(SaveState + 17) = here->MOS9sourceConductance; + *(SaveState + 18) = here->MOS9drainConductance; + *(SaveState + 19) = here->MOS9cd; + *(SaveState + 20) = here->MOS9cbs; + *(SaveState + 21) = here->MOS9cbd; + *(SaveState + 22) = here->MOS9gmbs; + *(SaveState + 23) = here->MOS9gm; + *(SaveState + 24) = here->MOS9gds; + *(SaveState + 25) = here->MOS9gbd; + *(SaveState + 26) = here->MOS9gbs; + *(SaveState + 27) = here->MOS9capbd; + *(SaveState + 28) = here->MOS9capbs; + *(SaveState + 29) = here->MOS9Cbd; + *(SaveState + 30) = here->MOS9Cbdsw; + *(SaveState + 31) = here->MOS9Cbs; + *(SaveState + 32) = here->MOS9Cbssw; + *(SaveState + 33) = here->MOS9f2d; + *(SaveState + 34) = here->MOS9f3d; + *(SaveState + 35) = here->MOS9f4d; + *(SaveState + 36) = here->MOS9f2s; + *(SaveState + 37) = here->MOS9f3s; + *(SaveState + 38) = here->MOS9f4s; + *(SaveState + 39) = here->MOS9cgs; + *(SaveState + 40) = here->MOS9cgd; + *(SaveState + 41) = here->MOS9cgb; + *(SaveState + 42) = here->MOS9vdsat; + *(SaveState + 43) = here->MOS9von; + save_mode = here->MOS9mode; + + + if(here->MOS9senParmNo == 0) goto next1; + +#ifdef SENSDEBUG + printf("without perturbation \n"); +#endif /* SENSDEBUG */ + + cdpr0= here->MOS9cd; + cspr0= -(here->MOS9cd + here->MOS9cbd + here->MOS9cbs); + if((info->SENmode == TRANSEN) && + (ckt->CKTmode & MODEINITTRAN)){ + qgs0 = *(ckt->CKTstate1 + here->MOS9qgs); + qgd0 = *(ckt->CKTstate1 + here->MOS9qgd); + qgb0 = *(ckt->CKTstate1 + here->MOS9qgb); + } + else{ + qgs0 = *(ckt->CKTstate0 + here->MOS9qgs); + qgd0 = *(ckt->CKTstate0 + here->MOS9qgd); + qgb0 = *(ckt->CKTstate0 + here->MOS9qgb); + } + + here->MOS9senPertFlag = ON; + error = MOS9load((GENmodel*)model,ckt); + if(error) return(error); + + cd0 = here->MOS9cd ; + cbd0 = here->MOS9cbd ; + cbs0 = here->MOS9cbs ; + gspr0= here->MOS9sourceConductance ; + gdpr0= here->MOS9drainConductance ; + + qbs0 = *(ckt->CKTstate0 + here->MOS9qbs); + qbd0 = *(ckt->CKTstate0 + here->MOS9qbd); + + for( flag = 0 ; flag <= 1 ; flag++){ + if(here->MOS9sens_l == 0) + if(flag == 0) goto next2; + if(here->MOS9sens_w == 0) + if(flag == 1) goto next2; + if(flag == 0){ + A0 = here->MOS9l; + DELA = info->SENpertfac * A0; + DELAinv = 1.0/DELA; + Apert = A0 + DELA; + here->MOS9l = Apert; + } + else{ + A0 = here->MOS9w; + DELA = info->SENpertfac * A0; + DELAinv = 1.0/DELA; + Apert = A0 + DELA; + here->MOS9w = Apert; + here->MOS9drainArea *= (1 + info->SENpertfac); + here->MOS9sourceArea *= (1 + info->SENpertfac); + here->MOS9Cbd *= (1 + info->SENpertfac); + here->MOS9Cbs *= (1 + info->SENpertfac); + if(here->MOS9drainPerimiter){ + here->MOS9Cbdsw += here->MOS9Cbdsw * + DELA/here->MOS9drainPerimiter; + } + if(here->MOS9sourcePerimiter){ + here->MOS9Cbssw += here->MOS9Cbssw * + DELA/here->MOS9sourcePerimiter; + } + if(*(ckt->CKTstate0 + here->MOS9vbd) >= + here->MOS9tDepCap){ + arg = 1-model->MOS9fwdCapDepCoeff; + sarg = exp( (-model->MOS9bulkJctBotGradingCoeff) * + log(arg) ); + sargsw = exp( (-model->MOS9bulkJctSideGradingCoeff) * + log(arg) ); + here->MOS9f2d = here->MOS9Cbd* + (1-model->MOS9fwdCapDepCoeff* + (1+model->MOS9bulkJctBotGradingCoeff))* sarg/arg + + here->MOS9Cbdsw*(1-model->MOS9fwdCapDepCoeff* + (1+model->MOS9bulkJctSideGradingCoeff))* + sargsw/arg; + here->MOS9f3d = here->MOS9Cbd * + model->MOS9bulkJctBotGradingCoeff * sarg/arg/ + model->MOS9bulkJctPotential + + here->MOS9Cbdsw * + model->MOS9bulkJctSideGradingCoeff *sargsw/arg / + model->MOS9bulkJctPotential; + here->MOS9f4d = here->MOS9Cbd* + model->MOS9bulkJctPotential*(1-arg*sarg)/ + (1-model->MOS9bulkJctBotGradingCoeff) + + here->MOS9Cbdsw*model->MOS9bulkJctPotential* + (1-arg*sargsw)/ + (1-model->MOS9bulkJctSideGradingCoeff) + -here->MOS9f3d/2* + (here->MOS9tDepCap*here->MOS9tDepCap) + -here->MOS9tDepCap * here->MOS9f2d; + } + if(*(ckt->CKTstate0 + here->MOS9vbs) >= + here->MOS9tDepCap){ + arg = 1-model->MOS9fwdCapDepCoeff; + sarg = exp( (-model->MOS9bulkJctBotGradingCoeff) * + log(arg) ); + sargsw = exp( (-model->MOS9bulkJctSideGradingCoeff) * + log(arg) ); + here->MOS9f2s = here->MOS9Cbs* + (1-model->MOS9fwdCapDepCoeff* + (1+model->MOS9bulkJctBotGradingCoeff))* sarg/arg + + here->MOS9Cbssw*(1-model->MOS9fwdCapDepCoeff* + (1+model->MOS9bulkJctSideGradingCoeff))* + sargsw/arg; + here->MOS9f3s = here->MOS9Cbs * + model->MOS9bulkJctBotGradingCoeff * sarg/arg/ + model->MOS9bulkJctPotential + + here->MOS9Cbssw * + model->MOS9bulkJctSideGradingCoeff * sargsw/arg/ + model->MOS9bulkJctPotential; + here->MOS9f4s = here->MOS9Cbs* + model->MOS9bulkJctPotential*(1-arg*sarg)/ + (1-model->MOS9bulkJctBotGradingCoeff) + + here->MOS9Cbssw*model->MOS9bulkJctPotential* + (1-arg*sargsw)/ + (1-model->MOS9bulkJctSideGradingCoeff) + -here->MOS9f3s/2* + (here->MOS9tBulkPot*here->MOS9tBulkPot) + -here->MOS9tBulkPot * here->MOS9f2s; + } + here->MOS9drainConductance *= Apert/A0; + here->MOS9sourceConductance *= Apert/A0; + } + + +#ifdef SENSDEBUG + if(flag == 0) + printf("perturbation of l\n"); + if(flag == 1) + printf("perturbation of w\n"); +#endif /* SENSDEBUG */ + + error = MOS9load((GENmodel*)model,ckt); + if(error) return(error); + + if(flag == 0){ + here->MOS9l = A0; + } + else{ + here->MOS9w = A0; + here->MOS9drainArea /= (1 + info->SENpertfac); + here->MOS9sourceArea /= (1 + info->SENpertfac); + here->MOS9drainConductance *= A0/Apert; + here->MOS9sourceConductance *= A0/Apert; + } + cd = here->MOS9cd ; + cbd = here->MOS9cbd ; + cbs = here->MOS9cbs ; + + gspr= here->MOS9sourceConductance ; + gdpr= here->MOS9drainConductance ; + + DcdDp = (cd - cd0) * DELAinv; + DcbsDp = (cbs - cbs0) * DELAinv; + DcbdDp = (cbd - cbd0) * DELAinv; + DcbDp = ( DcbsDp + DcbdDp ); + + DcdprDp = 0; + DcsprDp = 0; + if(here->MOS9dNode != here->MOS9dNodePrime) + if(gdpr0) DcdprDp = cdpr0 * (gdpr - gdpr0)/gdpr0 * DELAinv; + if(here->MOS9sNode != here->MOS9sNodePrime) + if(gspr0) DcsprDp = cspr0 * (gspr - gspr0)/gspr0 * DELAinv; + + DcdprmDp = ( - DcdprDp + DcdDp); + DcsprmDp = ( - DcbsDp - DcdDp - DcbdDp - DcsprDp); + + if(flag == 0){ + EffectiveLength = here->MOS9l + - 2*model->MOS9latDiff + model->MOS9lengthAdjust; + if(EffectiveLength == 0){ + DqgsDp = 0; + DqgdDp = 0; + DqgbDp = 0; + } + else{ + DqgsDp = model->MOS9type * qgs0 / EffectiveLength; + DqgdDp = model->MOS9type * qgd0 / EffectiveLength; + DqgbDp = model->MOS9type * qgb0 / EffectiveLength; + } + } + else{ + EffectiveWidth = here->MOS9w + - 2*model->MOS9widthNarrow + model->MOS9widthAdjust; + DqgsDp = model->MOS9type * qgs0 / EffectiveWidth; + DqgdDp = model->MOS9type * qgd0 / EffectiveWidth; + DqgbDp = model->MOS9type * qgb0 / EffectiveWidth; + } + + + qbd = *(ckt->CKTstate0 + here->MOS9qbd); + qbs = *(ckt->CKTstate0 + here->MOS9qbs); + + DqbsDp = model->MOS9type * (qbs - qbs0)*DELAinv; + DqbdDp = model->MOS9type * (qbd - qbd0)*DELAinv; + + if(flag == 0){ + *(here->MOS9dphigs_dl) = DqgsDp; + *(here->MOS9dphigd_dl) = DqgdDp; + *(here->MOS9dphibs_dl) = DqbsDp; + *(here->MOS9dphibd_dl) = DqbdDp; + *(here->MOS9dphigb_dl) = DqgbDp; + } + else{ + *(here->MOS9dphigs_dw) = DqgsDp; + *(here->MOS9dphigd_dw) = DqgdDp; + *(here->MOS9dphibs_dw) = DqbsDp; + *(here->MOS9dphibd_dw) = DqbdDp; + *(here->MOS9dphigb_dw) = DqgbDp; + } + + +#ifdef SENSDEBUG + printf("CKTag[0]=%.7e,CKTag[1]=%.7e,flag= %d\n", + ckt->CKTag[0],ckt->CKTag[1],flag); + printf("cd0 = %.7e ,cd = %.7e,\n",cd0,cd); + printf("cbs0 = %.7e ,cbs = %.7e,\n",cbs0,cbs); + printf("cbd0 = %.7e ,cbd = %.7e,\n",cbd0,cbd); + printf("DcdprmDp = %.7e,\n",DcdprmDp); + printf("DcsprmDp = %.7e,\n",DcsprmDp); + printf("DcdprDp = %.7e,\n",DcdprDp); + printf("DcsprDp = %.7e,\n",DcsprDp); + printf("qgs0 = %.7e \n",qgs0); + printf("qgd0 = %.7e \n",qgd0); + printf("qgb0 = %.7e \n",qgb0); + printf("qbs0 = %.7e ,qbs = %.7e,\n",qbs0,qbs); + printf("qbd0 = %.7e ,qbd = %.7e,\n",qbd0,qbd); + printf("DqgsDp = %.7e \n",DqgsDp); + printf("DqgdDp = %.7e \n",DqgdDp); + printf("DqgbDp = %.7e \n",DqgbDp); + printf("DqbsDp = %.7e \n",DqbsDp); + printf("DqbdDp = %.7e \n",DqbdDp); + printf("EffectiveLength = %.7e \n",EffectiveLength); + printf("tdepCap = %.7e \n",here->MOS9tDepCap); + printf("\n"); +#endif /* SENSDEBUG*/ + if((info->SENmode == TRANSEN) && + (ckt->CKTmode & MODEINITTRAN)) + goto next2; + + /* + * load RHS matrix + */ + + if(flag == 0){ + *(info->SEN_RHS[here->MOS9bNode] + here->MOS9senParmNo) + -= model->MOS9type * DcbDp; + *(info->SEN_RHS[here->MOS9dNode] + here->MOS9senParmNo) + -= model->MOS9type * DcdprDp; + *(info->SEN_RHS[here->MOS9dNodePrime] + here->MOS9senParmNo) + -= model->MOS9type * DcdprmDp; + *(info->SEN_RHS[here->MOS9sNode] + here->MOS9senParmNo) + -= model->MOS9type * DcsprDp; + *(info->SEN_RHS[here->MOS9sNodePrime] + here->MOS9senParmNo) + -= model->MOS9type * DcsprmDp; + } + else{ + offset = here->MOS9sens_l; + + *(info->SEN_RHS[here->MOS9bNode] + here->MOS9senParmNo + + offset) -= model->MOS9type * DcbDp; + *(info->SEN_RHS[here->MOS9dNode] + here->MOS9senParmNo + + offset) -= model->MOS9type * DcdprDp; + *(info->SEN_RHS[here->MOS9dNodePrime] + here->MOS9senParmNo + + offset) -= model->MOS9type * DcdprmDp; + *(info->SEN_RHS[here->MOS9sNode] + here->MOS9senParmNo + + offset) -= model->MOS9type * DcsprDp; + *(info->SEN_RHS[here->MOS9sNodePrime] + here->MOS9senParmNo + + offset) -= model->MOS9type * DcsprmDp; + } +#ifdef SENSDEBUG + printf("after loading\n"); + if(flag == 0){ + printf("DcbDp=%.7e\n", + *(info->SEN_RHS[here->MOS9bNode] + + here->MOS9senParmNo)); + printf("DcdprDp=%.7e\n", + *(info->SEN_RHS[here->MOS9dNode] + + here->MOS9senParmNo)); + printf("DcsprDp=%.7e\n", + *(info->SEN_RHS[here->MOS9sNode] + + here->MOS9senParmNo)); + printf("DcdprmDp=%.7e\n", + *(info->SEN_RHS[here->MOS9dNodePrime] + + here->MOS9senParmNo)); + printf("DcsprmDp=%.7e\n", + *(info->SEN_RHS[here->MOS9sNodePrime] + + here->MOS9senParmNo)); + printf("\n"); + } + else{ + printf("DcbDp=%.7e\n", + *(info->SEN_RHS[here->MOS9bNode] + + here->MOS9senParmNo + here->MOS9sens_l)); + printf("DcdprDp=%.7e\n", + *(info->SEN_RHS[here->MOS9dNode] + + here->MOS9senParmNo + here->MOS9sens_l)); + printf("DcsprDp=%.7e\n", + *(info->SEN_RHS[here->MOS9sNode] + + here->MOS9senParmNo + here->MOS9sens_l)); + printf("DcdprmDp=%.7e\n", + *(info->SEN_RHS[here->MOS9dNodePrime] + + here->MOS9senParmNo + here->MOS9sens_l)); + printf("DcsprmDp=%.7e\n", + *(info->SEN_RHS[here->MOS9sNodePrime] + + here->MOS9senParmNo + here->MOS9sens_l)); + } +#endif /* SENSDEBUG*/ +next2: + ; + } +next1: + if((info->SENmode == DCSEN) || + (ckt->CKTmode&MODETRANOP) ) goto restore; + if((info->SENmode == TRANSEN) && + (ckt->CKTmode & MODEINITTRAN)) goto restore; + for(iparmno = 1;iparmno<=info->SENparms;iparmno++){ +#ifdef SENSDEBUG + printf("after conductive currents\n"); + printf("iparmno = %d\n",iparmno); + printf("DcbDp=%.7e\n", + *(info->SEN_RHS[here->MOS9bNode] + iparmno)); + printf("DcdprDp=%.7e\n", + *(info->SEN_RHS[here->MOS9dNode] + iparmno)); + printf("DcdprmDp=%.7e\n", + *(info->SEN_RHS[here->MOS9dNodePrime] + iparmno)); + printf("DcsprDp=%.7e\n", + *(info->SEN_RHS[here->MOS9sNode] + iparmno)); + printf("DcsprmDp=%.7e\n", + *(info->SEN_RHS[here->MOS9sNodePrime] + iparmno)); + printf("\n"); +#endif /* SENSDEBUG */ + Osxpgs = tag0 * *(ckt->CKTstate1 + here->MOS9sensxpgs + + 10*(iparmno - 1)) + + tag1 * *(ckt->CKTstate1 + here->MOS9sensxpgs + + 10*(iparmno - 1) + 1); + + Osxpgd = tag0 * *(ckt->CKTstate1 + here->MOS9sensxpgd + + 10*(iparmno - 1)) + + tag1 * *(ckt->CKTstate1 + here->MOS9sensxpgd + + 10*(iparmno - 1) + 1); + + Osxpbs = tag0 * *(ckt->CKTstate1 + here->MOS9sensxpbs + + 10*(iparmno - 1)) + + tag1 * *(ckt->CKTstate1 + here->MOS9sensxpbs + + 10*(iparmno - 1) + 1); + + Osxpbd =tag0 * *(ckt->CKTstate1 + here->MOS9sensxpbd + + 10*(iparmno - 1)) + + tag1 * *(ckt->CKTstate1 + here->MOS9sensxpbd + + 10*(iparmno - 1) + 1); + Osxpgb = tag0 * *(ckt->CKTstate1 + here->MOS9sensxpgb + + 10*(iparmno - 1)) + + tag1 * *(ckt->CKTstate1 + here->MOS9sensxpgb + + 10*(iparmno - 1) + 1); + +#ifdef SENSDEBUG + printf("iparmno=%d\n",iparmno); + printf("sxpgs=%.7e,sdgs=%.7e\n", + *(ckt->CKTstate1 + here->MOS9sensxpgs + + 10*(iparmno - 1)), *(ckt->CKTstate1 + + here->MOS9sensxpgs + 10*(iparmno - 1) + 1)); + printf("sxpgd=%.7e,sdgd=%.7e\n", + *(ckt->CKTstate1 + here->MOS9sensxpgd + + 10*(iparmno - 1)), *(ckt->CKTstate1 + + here->MOS9sensxpgd + 10*(iparmno - 1) + 1)); + printf("sxpbs=%.7e,sdbs=%.7e\n", + *(ckt->CKTstate1 + here->MOS9sensxpbs + + 10*(iparmno - 1)), *(ckt->CKTstate1 + + here->MOS9sensxpbs + 10*(iparmno - 1) + 1)); + printf("sxpbd=%.7e,sdbd=%.7e\n", + *(ckt->CKTstate1 + here->MOS9sensxpbd + + 10*(iparmno - 1)), *(ckt->CKTstate1 + + here->MOS9sensxpbd + 10*(iparmno - 1) + 1)); + printf("sxpgb=%.7e,sdgb=%.7e\n", + *(ckt->CKTstate1 + here->MOS9sensxpgb + + 10*(iparmno - 1)), *(ckt->CKTstate1 + + here->MOS9sensxpgb + 10*(iparmno - 1) + 1)); + printf("before loading DqDp\n"); + printf("Osxpgs=%.7e,Osxpgd=%.7e\n",Osxpgs,Osxpgd); + printf("Osxpbs=%.7e,Osxpbd=%.7e,Osxpgb=%.7e\n", + Osxpbs,Osxpbd,Osxpgb); + printf("\n"); +#endif /* SENSDEBUG */ + if(here->MOS9sens_l && (iparmno == here->MOS9senParmNo)){ + Osxpgs -= tag0 * *(here->MOS9dphigs_dl); + Osxpgd -= tag0 * *(here->MOS9dphigd_dl); + Osxpbs -= tag0 * *(here->MOS9dphibs_dl); + Osxpbd -= tag0 * *(here->MOS9dphibd_dl); + Osxpgb -= tag0 * *(here->MOS9dphigb_dl); + } + if(here->MOS9sens_w && + (iparmno == (here->MOS9senParmNo + here->MOS9sens_l))){ + Osxpgs -= tag0 * *(here->MOS9dphigs_dw); + Osxpgd -= tag0 * *(here->MOS9dphigd_dw); + Osxpbs -= tag0 * *(here->MOS9dphibs_dw); + Osxpbd -= tag0 * *(here->MOS9dphibd_dw); + Osxpgb -= tag0 * *(here->MOS9dphigb_dw); + } +#ifdef SENSDEBUG + printf("after loading DqDp\n"); + printf("DqgsDp=%.7e",DqgsDp); + printf("Osxpgs=%.7e,Osxpgd=%.7e\n",Osxpgs,Osxpgd); + printf("Osxpbs=%.7e,Osxpbd=%.7e,Osxpgb=%.7e\n", + Osxpbs,Osxpbd,Osxpgb); +#endif /* SENSDEBUG */ + + *(info->SEN_RHS[here->MOS9bNode] + iparmno) += + Osxpbs + Osxpbd -Osxpgb; + *(info->SEN_RHS[here->MOS9gNode] + iparmno) += + Osxpgs + Osxpgd + Osxpgb; + + *(info->SEN_RHS[here->MOS9dNodePrime] + iparmno) -= + Osxpgd + Osxpbd ; + *(info->SEN_RHS[here->MOS9sNodePrime] + iparmno) -= + Osxpgs + Osxpbs; +#ifdef SENSDEBUG + printf("after capacitive currents\n"); + printf("DcbDp=%.7e\n", + *(info->SEN_RHS[here->MOS9bNode] + iparmno)); + printf("DcdprDp=%.7e\n", + *(info->SEN_RHS[here->MOS9dNode] + iparmno)); + printf("DcdprmDp=%.7e\n", + *(info->SEN_RHS[here->MOS9dNodePrime] + iparmno)); + printf("DcsprDp=%.7e\n", + *(info->SEN_RHS[here->MOS9sNode] + iparmno)); + printf("DcsprmDp=%.7e\n", + *(info->SEN_RHS[here->MOS9sNodePrime] + iparmno)); +#endif /* SENSDEBUG */ + + } +restore: /* put the unperturbed values back into the state vector */ + for(i=0; i <= 16; i++) + *(ckt->CKTstate0 + here->MOS9states + i) = *(SaveState + i); + here->MOS9sourceConductance = *(SaveState + 17) ; + here->MOS9drainConductance = *(SaveState + 18) ; + here->MOS9cd = *(SaveState + 19) ; + here->MOS9cbs = *(SaveState + 20) ; + here->MOS9cbd = *(SaveState + 21) ; + here->MOS9gmbs = *(SaveState + 22) ; + here->MOS9gm = *(SaveState + 23) ; + here->MOS9gds = *(SaveState + 24) ; + here->MOS9gbd = *(SaveState + 25) ; + here->MOS9gbs = *(SaveState + 26) ; + here->MOS9capbd = *(SaveState + 27) ; + here->MOS9capbs = *(SaveState + 28) ; + here->MOS9Cbd = *(SaveState + 29) ; + here->MOS9Cbdsw = *(SaveState + 30) ; + here->MOS9Cbs = *(SaveState + 31) ; + here->MOS9Cbssw = *(SaveState + 32) ; + here->MOS9f2d = *(SaveState + 33) ; + here->MOS9f3d = *(SaveState + 34) ; + here->MOS9f4d = *(SaveState + 35) ; + here->MOS9f2s = *(SaveState + 36) ; + here->MOS9f3s = *(SaveState + 37) ; + here->MOS9f4s = *(SaveState + 38) ; + here->MOS9cgs = *(SaveState + 39) ; + here->MOS9cgd = *(SaveState + 40) ; + here->MOS9cgb = *(SaveState + 41) ; + here->MOS9vdsat = *(SaveState + 42) ; + here->MOS9von = *(SaveState + 43) ; + here->MOS9mode = save_mode ; + + here->MOS9senPertFlag = OFF; + + } + } + info->SENstatus = NORMAL; +#ifdef SENSDEBUG + printf("MOS9senload end\n"); +#endif /* SENSDEBUG */ + return(OK); +} + diff --git a/src/spicelib/devices/mos9/mos9sprt.c b/src/spicelib/devices/mos9/mos9sprt.c new file mode 100644 index 000000000..183c104a8 --- /dev/null +++ b/src/spicelib/devices/mos9/mos9sprt.c @@ -0,0 +1,65 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ + + /* Pretty print the sensitivity info for all the MOS9 + * devices in the circuit. + */ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "mos9defs.h" +#include "sperror.h" +#include "suffix.h" + +void +MOS9sPrint(inModel,ckt) + GENmodel *inModel; + register CKTcircuit *ckt; +{ + register MOS9model *model = (MOS9model *)inModel; + register MOS9instance *here; + + printf("LEVEL 3 MOSFETS (AG) -----------------\n"); + /* loop through all the MOS9 models */ + for( ; model != NULL; model = model->MOS9nextModel ) { + + printf("Model name:%s\n",model->MOS9modName); + + /* loop through all the instances of the model */ + for (here = model->MOS9instances; here != NULL ; + here=here->MOS9nextInstance) { + + printf(" Instance name:%s\n",here->MOS9name); + printf(" Drain, Gate , Source nodes: %s, %s ,%s\n", + CKTnodName(ckt,here->MOS9dNode),CKTnodName(ckt,here->MOS9gNode), + CKTnodName(ckt,here->MOS9sNode)); + + printf(" Multiplier: %g ",here->MOS9m); + printf(here->MOS9mGiven ? "(specified)\n" : "(default)\n"); + printf(" Length: %g ",here->MOS9l); + printf(here->MOS9lGiven ? "(specified)\n" : "(default)\n"); + printf(" Width: %g ",here->MOS9w); + printf(here->MOS9wGiven ? "(specified)\n" : "(default)\n"); + if(here->MOS9sens_l == 1){ + printf(" MOS9senParmNo:l = %d ",here->MOS9senParmNo); + } + else{ + printf(" MOS9senParmNo:l = 0 "); + } + if(here->MOS9sens_w == 1){ + printf(" w = %d \n",here->MOS9senParmNo + here->MOS9sens_l); + } + else{ + printf(" w = 0 \n"); + } + + + } + } +} + diff --git a/src/spicelib/devices/mos9/mos9sset.c b/src/spicelib/devices/mos9/mos9sset.c new file mode 100644 index 000000000..9ad775856 --- /dev/null +++ b/src/spicelib/devices/mos9/mos9sset.c @@ -0,0 +1,54 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ + + /* loop through all the devices and + * allocate parameter #s to design parameters + */ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "mos9defs.h" +#include "sperror.h" +#include "suffix.h" + +int +MOS9sSetup(info,inModel) + SENstruct *info; + GENmodel *inModel; +{ + MOS9model *model = (MOS9model *)inModel; + MOS9instance *here; + + /* loop through all the models */ + for( ; model != NULL; model = model->MOS9nextModel ) { + + /* loop through all the instances of the model */ + for (here = model->MOS9instances; here != NULL ; + here=here->MOS9nextInstance) { + + + if(here->MOS9senParmNo){ + if((here->MOS9sens_l)&&(here->MOS9sens_w)){ + here->MOS9senParmNo = ++(info->SENparms); + ++(info->SENparms);/* MOS has two design parameters */ + } + else{ + here->MOS9senParmNo = ++(info->SENparms); + } + } + here->MOS9senPertFlag = OFF; + if((here->MOS9sens = (double *)MALLOC(72*sizeof(double))) == NULL) { + return(E_NOMEM); + } + + } + } + return(OK); +} + + diff --git a/src/spicelib/devices/mos9/mos9supd.c b/src/spicelib/devices/mos9/mos9supd.c new file mode 100644 index 000000000..21f680d1e --- /dev/null +++ b/src/spicelib/devices/mos9/mos9supd.c @@ -0,0 +1,182 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ + +#include +#include "ngspice.h" +#include "smpdefs.h" +#include "cktdefs.h" +#include "mos9defs.h" +#include "sperror.h" +#include "suffix.h" + +int +MOS9sUpdate(inModel,ckt) +GENmodel *inModel; +CKTcircuit *ckt; +{ + MOS9model *model = (MOS9model *)inModel; + MOS9instance *here; + int iparmno; + double sb; + double sg; + double sdprm; + double ssprm; + double sxpgs; + double sxpgd; + double sxpbs; + double sxpbd; + double sxpgb; + double dummy1; + double dummy2; + SENstruct *info; + + + if(ckt->CKTtime == 0) return(OK); + info = ckt->CKTsenInfo; + +#ifdef SENSDEBUG + printf("MOS9senupdate\n"); + printf("CKTtime = %.5e\n",ckt->CKTtime); +#endif /* SENSDEBUG */ + + sxpgs = 0; + sxpgd = 0; + sxpbs = 0; + sxpbd = 0; + sxpgb = 0; + dummy1 = 0; + dummy2 = 0; + + /* loop through all the MOS9 models */ + for( ; model != NULL; model = model->MOS9nextModel ) { + + /* loop through all the instances of the model */ + for (here = model->MOS9instances; here != NULL ; + here=here->MOS9nextInstance) { + + +#ifdef SENSDEBUG + printf("senupdate instance name %s\n",here->MOS9name); + printf("before loading\n"); + printf("CKTag[0] = %.2e,CKTag[1] = %.2e\n", + ckt->CKTag[0],ckt->CKTag[1]); + printf("capgs = %.7e\n",here->MOS9cgs); + printf("capgd = %.7e\n",here->MOS9cgd); + printf("capgb = %.7e\n",here->MOS9cgb); + printf("capbs = %.7e\n",here->MOS9capbs); + printf("capbd = %.7e\n",here->MOS9capbd); +#endif /* SENSDEBUG */ + + for(iparmno = 1;iparmno<=info->SENparms;iparmno++){ + + sb = *(info->SEN_Sap[here->MOS9bNode] + iparmno); + sg = *(info->SEN_Sap[here->MOS9gNode] + iparmno); + ssprm = *(info->SEN_Sap[here->MOS9sNodePrime] + iparmno); + sdprm = *(info->SEN_Sap[here->MOS9dNodePrime] + iparmno); +#ifdef SENSDEBUG + printf("iparmno = %d\n",iparmno); + printf("sb = %.7e,sg = %.7e\n",sb,sg); + printf("ssprm = %.7e,sdprm = %.7e\n",ssprm,sdprm); +#endif /* SENSDEBUG */ + + sxpgs = (sg - ssprm) * here->MOS9cgs ; + sxpgd = (sg - sdprm) * here->MOS9cgd ; + sxpgb = (sg - sb) * here->MOS9cgb ; + sxpbs = (sb - ssprm) * here->MOS9capbs ; + sxpbd = (sb - sdprm) * here->MOS9capbd ; + + if(here->MOS9sens_l && (iparmno == here->MOS9senParmNo)){ + sxpgs += *(here->MOS9dphigs_dl); + sxpgd += *(here->MOS9dphigd_dl); + sxpbs += *(here->MOS9dphibs_dl); + sxpbd += *(here->MOS9dphibd_dl); + sxpgb += *(here->MOS9dphigb_dl); + } + if(here->MOS9sens_w && + (iparmno == (here->MOS9senParmNo+here->MOS9sens_l))){ + sxpgs += *(here->MOS9dphigs_dw); + sxpgd += *(here->MOS9dphigd_dw); + sxpbs += *(here->MOS9dphibs_dw); + sxpbd += *(here->MOS9dphibd_dw); + sxpgb += *(here->MOS9dphigb_dw); + } + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->MOS9sensxpgs + + 10 * (iparmno - 1)) = sxpgs; + *(ckt->CKTstate1 + here->MOS9sensxpgd + + 10 * (iparmno - 1)) = sxpgd; + *(ckt->CKTstate1 + here->MOS9sensxpbs + + 10 * (iparmno - 1)) = sxpbs; + *(ckt->CKTstate1 + here->MOS9sensxpbd + + 10 * (iparmno - 1)) = sxpbd; + *(ckt->CKTstate1 + here->MOS9sensxpgb + + 10 * (iparmno - 1)) = sxpgb; + *(ckt->CKTstate1 + here->MOS9sensxpgs + + 10 * (iparmno - 1) + 1) = 0; + *(ckt->CKTstate1 + here->MOS9sensxpgd + + 10 * (iparmno - 1) + 1) = 0; + *(ckt->CKTstate1 + here->MOS9sensxpbs + + 10 * (iparmno - 1) + 1) = 0; + *(ckt->CKTstate1 + here->MOS9sensxpbd + + 10 * (iparmno - 1) + 1) = 0; + *(ckt->CKTstate1 + here->MOS9sensxpgb + + 10 * (iparmno - 1) + 1) = 0; + goto next; + } + + *(ckt->CKTstate0 + here->MOS9sensxpgs + + 10 * (iparmno - 1)) = sxpgs; + *(ckt->CKTstate0 + here->MOS9sensxpgd + + 10 * (iparmno - 1)) = sxpgd; + *(ckt->CKTstate0 + here->MOS9sensxpbs + + 10 * (iparmno - 1)) = sxpbs; + *(ckt->CKTstate0 + here->MOS9sensxpbd + + 10 * (iparmno - 1)) = sxpbd; + *(ckt->CKTstate0 + here->MOS9sensxpgb + + 10 * (iparmno - 1)) = sxpgb; + + NIintegrate(ckt,&dummy1,&dummy2,here->MOS9cgs, + here->MOS9sensxpgs + 10*(iparmno -1)); + NIintegrate(ckt,&dummy1,&dummy2,here->MOS9cgd, + here->MOS9sensxpgd + 10*(iparmno -1)); + NIintegrate(ckt,&dummy1,&dummy2,here->MOS9cgb, + here->MOS9sensxpgb + 10*(iparmno -1)); + NIintegrate(ckt,&dummy1,&dummy2,here->MOS9capbs, + here->MOS9sensxpbs + 10*(iparmno -1)); + NIintegrate(ckt,&dummy1,&dummy2,here->MOS9capbd, + here->MOS9sensxpbd + 10*(iparmno -1)); + + +next: + ; +#ifdef SENSDEBUG + printf("after loading\n"); + printf("sxpgs = %.7e,sdotxpgs = %.7e\n", + sxpgs,*(ckt->CKTstate0 + here->MOS9sensxpgs + + 10 * (iparmno - 1) + 1)); + printf("sxpgd = %.7e,sdotxpgd = %.7e\n", + sxpgd,*(ckt->CKTstate0 + here->MOS9sensxpgd + + 10 * (iparmno - 1) + 1)); + printf("sxpgb = %.7e,sdotxpgb = %.7e\n", + sxpgb,*(ckt->CKTstate0 + here->MOS9sensxpgb + + 10 * (iparmno - 1) + 1)); + printf("sxpbs = %.7e,sdotxpbs = %.7e\n", + sxpbs,*(ckt->CKTstate0 + here->MOS9sensxpbs + + 10 * (iparmno - 1) + 1)); + printf("sxpbd = %.7e,sdotxpbd = %.7e\n", + sxpbd,*(ckt->CKTstate0 + here->MOS9sensxpbd + + 10 * (iparmno - 1) + 1)); +#endif /* SENSDEBUG */ + } + } + } +#ifdef SENSDEBUG + printf("MOS9senupdate end\n"); +#endif /* SENSDEBUG */ + return(OK); + +} + diff --git a/src/spicelib/devices/mos9/mos9temp.c b/src/spicelib/devices/mos9/mos9temp.c new file mode 100644 index 000000000..f5c00f608 --- /dev/null +++ b/src/spicelib/devices/mos9/mos9temp.c @@ -0,0 +1,343 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "mos9defs.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + +/* assuming silicon - make definition for epsilon of silicon */ +#define EPSSIL (11.7 * 8.854214871e-12) + +int +MOS9temp(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + MOS9model *model = (MOS9model *)inModel; + MOS9instance *here; + double wkfngs; + double wkfng; + double fermig; + double fermis; + double vfb; + double fact1,fact2; + double vt,vtnom; + double kt,kt1; + double ratio,ratio4; + double egfet,egfet1; + double pbfact,pbfact1,pbo; + double phio; + double arg1; + double capfact; + double gmanew,gmaold; + double ni_temp, nifact; + /* loop through all the mosfet models */ + for( ; model != NULL; model = model->MOS9nextModel) { + + if(!model->MOS9tnomGiven) { + model->MOS9tnom = ckt->CKTnomTemp; + } + fact1 = model->MOS9tnom/REFTEMP; + vtnom = model->MOS9tnom*CONSTKoverQ; + kt1 = CONSTboltz * model->MOS9tnom; + egfet1 = 1.16-(7.02e-4*model->MOS9tnom*model->MOS9tnom)/ + (model->MOS9tnom+1108); + arg1 = -egfet1/(kt1+kt1)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP)); + pbfact1 = -2*vtnom *(1.5*log(fact1)+CHARGE*arg1); + + nifact=(model->MOS9tnom/300)*sqrt(model->MOS9tnom/300); + nifact*=exp(0.5*egfet1*((1/(double)300)-(1/model->MOS9tnom))/ + CONSTKoverQ); + ni_temp=1.45e16*nifact; + + + model->MOS9oxideCapFactor = 3.9 * 8.854214871e-12/ + model->MOS9oxideThickness; + if(!model->MOS9surfaceMobilityGiven) model->MOS9surfaceMobility=600; + if(!model->MOS9transconductanceGiven) { + model->MOS9transconductance = model->MOS9surfaceMobility * + model->MOS9oxideCapFactor * 1e-4; + } + if(model->MOS9substrateDopingGiven) { + if(model->MOS9substrateDoping*1e6 /*(cm**3/m**3)*/ >ni_temp) { + + if(!model->MOS9phiGiven) { + model->MOS9phi = 2*vtnom* + log(model->MOS9substrateDoping* + + 1e6/*(cm**3/m**3)*//ni_temp); + + model->MOS9phi = MAX(.1,model->MOS9phi); + } + fermis = model->MOS9type * .5 * model->MOS9phi; + wkfng = 3.2; + if(!model->MOS9gateTypeGiven) model->MOS9gateType=1; + if(model->MOS9gateType != 0) { + fermig = model->MOS9type * model->MOS9gateType*.5*egfet1; + wkfng = 3.25 + .5 * egfet1 - fermig; + } + wkfngs = wkfng - (3.25 + .5 * egfet1 +fermis); + if(!model->MOS9gammaGiven) { + model->MOS9gamma = sqrt(2 * EPSSIL * + CHARGE * model->MOS9substrateDoping* + 1e6 /*(cm**3/m**3)*/ )/ model->MOS9oxideCapFactor; + } + if(!model->MOS9vt0Given) { + if(!model->MOS9surfaceStateDensityGiven) + model->MOS9surfaceStateDensity=0; + vfb = wkfngs - model->MOS9surfaceStateDensity * 1e4 + * CHARGE/model->MOS9oxideCapFactor; + model->MOS9vt0 = vfb + model->MOS9type * + (model->MOS9gamma * sqrt(model->MOS9phi)+ + model->MOS9phi); + } else { + vfb = model->MOS9vt0 - model->MOS9type * (model->MOS9gamma* + sqrt(model->MOS9phi)+model->MOS9phi); + } + model->MOS9alpha = (EPSSIL+EPSSIL)/ + (CHARGE*model->MOS9substrateDoping*1e6 /*(cm**3/m**3)*/ ); + model->MOS9coeffDepLayWidth = sqrt(model->MOS9alpha); + } else { + model->MOS9substrateDoping = 0; + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "%s: Nsub < Ni ",&(model->MOS9modName)); + return(E_BADPARM); + } + } + /* now model parameter preprocessing */ + model->MOS9narrowFactor = model->MOS9delta * 0.5 * M_PI * EPSSIL / + model->MOS9oxideCapFactor ; + + + /* loop through all instances of the model */ + for(here = model->MOS9instances; here!= NULL; + here = here->MOS9nextInstance) { + + double czbd; /* zero voltage bulk-drain capacitance */ + double czbdsw; /* zero voltage bulk-drain sidewall capacitance */ + double czbs; /* zero voltage bulk-source capacitance */ + double czbssw; /* zero voltage bulk-source sidewall capacitance */ + double arg; /* 1 - fc */ + double sarg; /* (1-fc) ^^ (-mj) */ + double sargsw; /* (1-fc) ^^ (-mjsw) */ + + /* perform the parameter defaulting */ + + if(!here->MOS9tempGiven) { + here->MOS9temp = ckt->CKTtemp; + } + vt = here->MOS9temp * CONSTKoverQ; + ratio = here->MOS9temp/model->MOS9tnom; + fact2 = here->MOS9temp/REFTEMP; + kt = here->MOS9temp * CONSTboltz; + egfet = 1.16-(7.02e-4*here->MOS9temp*here->MOS9temp)/ + (here->MOS9temp+1108); + arg = -egfet/(kt+kt)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP)); + pbfact = -2*vt *(1.5*log(fact2)+CHARGE*arg); + + if(!here->MOS9mGiven) { + here->MOS9m = ckt->CKTdefaultMosM; + } + + if(!here->MOS9lGiven) { + here->MOS9l = ckt->CKTdefaultMosL; + } + if(!here->MOS9sourceAreaGiven) { + here->MOS9sourceArea = ckt->CKTdefaultMosAS; + } + if(!here->MOS9wGiven) { + here->MOS9w = ckt->CKTdefaultMosW; + } + if(model->MOS9drainResistanceGiven) { + if(model->MOS9drainResistance != 0) { + here->MOS9drainConductance = here->MOS9m / + model->MOS9drainResistance; + } else { + here->MOS9drainConductance = 0; + } + } else if (model->MOS9sheetResistanceGiven) { + if ((model->MOS9sheetResistance != 0) && + (here->MOS9drainSquares != 0)) { + here->MOS9drainConductance = + here->MOS9m / + (model->MOS9sheetResistance*here->MOS9drainSquares); + } else { + here->MOS9drainConductance = 0; + } + } else { + here->MOS9drainConductance = 0; + } + if(model->MOS9sourceResistanceGiven) { + if(model->MOS9sourceResistance != 0) { + here->MOS9sourceConductance = here->MOS9m / + model->MOS9sourceResistance; + } else { + here->MOS9sourceConductance = 0; + } + } else if (model->MOS9sheetResistanceGiven) { + if ((model->MOS9sheetResistance != 0) && + (here->MOS9sourceSquares != 0)) { + here->MOS9sourceConductance = + here->MOS9m / + (model->MOS9sheetResistance*here->MOS9sourceSquares); + } else { + here->MOS9sourceConductance = 0; + } + } else { + here->MOS9sourceConductance = 0; + } + + if(here->MOS9l - 2 * model->MOS9latDiff + + model->MOS9lengthAdjust <1e-6) { + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "%s: effective channel length less than zero", + &(here->MOS9name)); + return(E_PARMVAL); + } + + if(here->MOS9w - 2 * model->MOS9widthNarrow + + model->MOS9widthAdjust <1e-6) { + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "%s: effective channel width less than zero", + &(here->MOS9name)); + return(E_PARMVAL); + } + + + ratio4 = ratio * sqrt(ratio); + here->MOS9tTransconductance = model->MOS9transconductance / ratio4; + here->MOS9tSurfMob = model->MOS9surfaceMobility/ratio4; + phio= (model->MOS9phi-pbfact1)/fact1; + here->MOS9tPhi = fact2 * phio + pbfact; + here->MOS9tVbi = + model->MOS9delvt0 + + model->MOS9vt0 - model->MOS9type * + (model->MOS9gamma* sqrt(model->MOS9phi)) + +.5*(egfet1-egfet) + + model->MOS9type*.5* (here->MOS9tPhi-model->MOS9phi); + here->MOS9tVto = here->MOS9tVbi + model->MOS9type * + model->MOS9gamma * sqrt(here->MOS9tPhi); + here->MOS9tSatCur = model->MOS9jctSatCur* + exp(-egfet/vt+egfet1/vtnom); + here->MOS9tSatCurDens = model->MOS9jctSatCurDensity * + exp(-egfet/vt+egfet1/vtnom); + pbo = (model->MOS9bulkJctPotential - pbfact1)/fact1; + gmaold = (model->MOS9bulkJctPotential-pbo)/pbo; + capfact = 1/(1+model->MOS9bulkJctBotGradingCoeff* + (4e-4*(model->MOS9tnom-REFTEMP)-gmaold)); + here->MOS9tCbd = model->MOS9capBD * capfact; + here->MOS9tCbs = model->MOS9capBS * capfact; + here->MOS9tCj = model->MOS9bulkCapFactor * capfact; + capfact = 1/(1+model->MOS9bulkJctSideGradingCoeff* + (4e-4*(model->MOS9tnom-REFTEMP)-gmaold)); + here->MOS9tCjsw = model->MOS9sideWallCapFactor * capfact; + here->MOS9tBulkPot = fact2 * pbo+pbfact; + gmanew = (here->MOS9tBulkPot-pbo)/pbo; + capfact = (1+model->MOS9bulkJctBotGradingCoeff* + (4e-4*(here->MOS9temp-REFTEMP)-gmanew)); + here->MOS9tCbd *= capfact; + here->MOS9tCbs *= capfact; + here->MOS9tCj *= capfact; + capfact = (1+model->MOS9bulkJctSideGradingCoeff* + (4e-4*(here->MOS9temp-REFTEMP)-gmanew)); + here->MOS9tCjsw *= capfact; + here->MOS9tDepCap = model->MOS9fwdCapDepCoeff * here->MOS9tBulkPot; + + if( (model->MOS9jctSatCurDensity == 0) || + (here->MOS9drainArea == 0) || + (here->MOS9sourceArea == 0) ) { + here->MOS9sourceVcrit = here->MOS9drainVcrit = + vt*log(vt/(CONSTroot2*here->MOS9m*here->MOS9tSatCur)); + } else { + here->MOS9drainVcrit = + vt * log( vt / (CONSTroot2 * + here->MOS9m * + here->MOS9tSatCurDens * here->MOS9drainArea)); + here->MOS9sourceVcrit = + vt * log( vt / (CONSTroot2 * + here->MOS9m * + here->MOS9tSatCurDens * here->MOS9sourceArea)); + } + if(model->MOS9capBDGiven) { + czbd = here->MOS9tCbd * here->MOS9m; + } else { + if(model->MOS9bulkCapFactorGiven) { + czbd=here->MOS9tCj*here->MOS9drainArea * here->MOS9m; + } else { + czbd=0; + } + } + if(model->MOS9sideWallCapFactorGiven) { + czbdsw= here->MOS9tCjsw * here->MOS9drainPerimiter * + here->MOS9m; + } else { + czbdsw=0; + } + arg = 1-model->MOS9fwdCapDepCoeff; + sarg = exp( (-model->MOS9bulkJctBotGradingCoeff) * log(arg) ); + sargsw = exp( (-model->MOS9bulkJctSideGradingCoeff) * log(arg) ); + here->MOS9Cbd = czbd; + here->MOS9Cbdsw = czbdsw; + here->MOS9f2d = czbd*(1-model->MOS9fwdCapDepCoeff* + (1+model->MOS9bulkJctBotGradingCoeff))* sarg/arg + + czbdsw*(1-model->MOS9fwdCapDepCoeff* + (1+model->MOS9bulkJctSideGradingCoeff))* + sargsw/arg; + here->MOS9f3d = czbd * model->MOS9bulkJctBotGradingCoeff * sarg/arg/ + here->MOS9tBulkPot + + czbdsw * model->MOS9bulkJctSideGradingCoeff * sargsw/arg / + here->MOS9tBulkPot; + here->MOS9f4d = czbd*here->MOS9tBulkPot*(1-arg*sarg)/ + (1-model->MOS9bulkJctBotGradingCoeff) + + czbdsw*here->MOS9tBulkPot*(1-arg*sargsw)/ + (1-model->MOS9bulkJctSideGradingCoeff) + -here->MOS9f3d/2* + (here->MOS9tDepCap*here->MOS9tDepCap) + -here->MOS9tDepCap * here->MOS9f2d; + if(model->MOS9capBSGiven) { + czbs = here->MOS9tCbs * here->MOS9m; + } else { + if(model->MOS9bulkCapFactorGiven) { + czbs=here->MOS9tCj*here->MOS9sourceArea * here->MOS9m; + } else { + czbs=0; + } + } + if(model->MOS9sideWallCapFactorGiven) { + czbssw = here->MOS9tCjsw * here->MOS9sourcePerimiter * + here->MOS9m; + } else { + czbssw=0; + } + arg = 1-model->MOS9fwdCapDepCoeff; + sarg = exp( (-model->MOS9bulkJctBotGradingCoeff) * log(arg) ); + sargsw = exp( (-model->MOS9bulkJctSideGradingCoeff) * log(arg) ); + here->MOS9Cbs = czbs; + here->MOS9Cbssw = czbssw; + here->MOS9f2s = czbs*(1-model->MOS9fwdCapDepCoeff* + (1+model->MOS9bulkJctBotGradingCoeff))* sarg/arg + + czbssw*(1-model->MOS9fwdCapDepCoeff* + (1+model->MOS9bulkJctSideGradingCoeff))* + sargsw/arg; + here->MOS9f3s = czbs * model->MOS9bulkJctBotGradingCoeff * sarg/arg/ + here->MOS9tBulkPot + + czbssw * model->MOS9bulkJctSideGradingCoeff * sargsw/arg / + here->MOS9tBulkPot; + here->MOS9f4s = czbs*here->MOS9tBulkPot*(1-arg*sarg)/ + (1-model->MOS9bulkJctBotGradingCoeff) + + czbssw*here->MOS9tBulkPot*(1-arg*sargsw)/ + (1-model->MOS9bulkJctSideGradingCoeff) + -here->MOS9f3s/2* + (here->MOS9tDepCap*here->MOS9tDepCap) + -here->MOS9tDepCap * here->MOS9f2s; + } + } + return(OK); +} diff --git a/src/spicelib/devices/mos9/mos9trun.c b/src/spicelib/devices/mos9/mos9trun.c new file mode 100644 index 000000000..d9d5f26cf --- /dev/null +++ b/src/spicelib/devices/mos9/mos9trun.c @@ -0,0 +1,31 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "mos9defs.h" +#include "sperror.h" +#include "suffix.h" + +int +MOS9trunc(inModel,ckt,timeStep) + GENmodel *inModel; + CKTcircuit *ckt; + double *timeStep; +{ + MOS9model *model = (MOS9model *)inModel; + MOS9instance *here; + + for( ; model != NULL; model = model->MOS9nextModel) { + for(here=model->MOS9instances;here!=NULL;here = here->MOS9nextInstance){ + CKTterr(here->MOS9qgs,ckt,timeStep); + CKTterr(here->MOS9qgd,ckt,timeStep); + CKTterr(here->MOS9qgb,ckt,timeStep); + } + } + return(OK); +} 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/resinit.c b/src/spicelib/devices/res/resinit.c new file mode 100644 index 000000000..d7780225e --- /dev/null +++ b/src/spicelib/devices/res/resinit.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "resitf.h" +#include "resext.h" +#include "resinit.h" + + +SPICEdev RESinfo = { + { + "Resistor", + "Simple linear resistor", + + &RESnSize, + &RESnSize, + RESnames, + + &RESpTSize, + RESpTable, + + &RESmPTSize, + RESmPTable, + 0 + }, + + DEVparam : RESparam, + DEVmodParam : RESmParam, + DEVload : RESload, + DEVsetup : RESsetup, + DEVunsetup : NULL, + DEVpzSetup : RESsetup, + DEVtemperature: REStemp, + DEVtrunc : NULL, + DEVfindBranch : NULL, + DEVacLoad : RESacload, /* ac load and normal load are identical */ + DEVaccept : NULL, + DEVdestroy : RESdestroy, + DEVmodDelete : RESmDelete, + DEVdelete : RESdelete, + DEVsetic : NULL, + DEVask : RESask, + DEVmodAsk : RESmodAsk, + DEVpzLoad : RESpzLoad, + DEVconvTest : NULL, + DEVsenSetup : RESsSetup, + DEVsenLoad : RESsLoad, + DEVsenUpdate : NULL, + DEVsenAcLoad : RESsAcLoad, + DEVsenPrint : RESsPrint, + DEVsenTrunc : NULL, + DEVdisto : NULL, + DEVnoise : RESnoise, + + DEVinstSize : &RESiSize, + DEVmodSize : &RESmSize + +}; + + +SPICEdev * +get_res_info(void) +{ + return &RESinfo; +} diff --git a/src/spicelib/devices/res/resinit.h b/src/spicelib/devices/res/resinit.h new file mode 100644 index 000000000..b3f71595f --- /dev/null +++ b/src/spicelib/devices/res/resinit.h @@ -0,0 +1,13 @@ +#ifndef _RESINIT_H +#define _RESINIT_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; + +#endif 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/soi3/Makefile.am b/src/spicelib/devices/soi3/Makefile.am new file mode 100644 index 000000000..1cadd6d21 --- /dev/null +++ b/src/spicelib/devices/soi3/Makefile.am @@ -0,0 +1,32 @@ +## Process this file with automake to produce Makefile.in + +pkglib_LTLIBRARIES = libsoi3.la + +libsoi3_la_SOURCES = \ + soi3.c \ + soi3acld.c \ + soi3ask.c \ + soi3cap.c \ + soi3conv.c \ + soi3defs.h \ + soi3del.c \ + soi3dest.c \ + soi3ext.h \ + soi3ic.c \ + soi3init.c \ + soi3init.h \ + soi3itf.h \ + soi3load.c \ + soi3mask.c \ + soi3mdel.c \ + soi3mpar.c \ + soi3nois.c \ + soi3par.c \ + soi3set.c \ + soi3temp.c \ + soi3trun.c + + + +INCLUDES = -I$(top_srcdir)/src/include +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/soi3/README b/src/spicelib/devices/soi3/README new file mode 100644 index 000000000..4fa56ee9d --- /dev/null +++ b/src/spicelib/devices/soi3/README @@ -0,0 +1,55 @@ +Licence Agreement (STAG) from DERA + +1. The STAG Computer Model is subject to Copyright owned by the United Kingdom +Secretary of State for Defence acting through the Defence Evaluation and Research Agency +(DERA). It is made available to licensee (hereinafter LICENSEE) on the following conditions:- + +2. Downloading the STAG Model deems acceptance of the terms of the licence. + +3. DERA grants to LICENSEE a royalty free non-exclusive licence to use the furnished STAG +Model. LICENSEE is permitted to copy, distribute, and transfer the STAG Model to +customers for their royalty free use on the same licence terms. + +4. LICENSEE acknowledges that STAG is a research tool still in the development stage, that +it is being supplied "as is", without any accompanying services or improvements from +DERA. + +5. LICENSEE acknowledges that STAG is a Model developed by the Department of +Electronics and Computer Science at the University of Southampton (UOS), England, and is +incorporated within SPICE 3f5, a program developed by the Department of Electrical +Engineering and Computer Science at the University of California, Berkeley, California +(UCB). As such, LICENSEE acknowledges that in addition to the rights licensed by DERA, +UCB itself imposes restrictions on use, copying, and distribution of the SPICE 3f5 program +and its derivatives. + +6. LICENSEE undertakes to obtain any separate licence required for the use of SPICE 3f5 +from UCB. + +7. DERA make no representations or warranties, express or implied. DERA shall not be held +liable for any liability nor for any direct, indirect, or consequential damages with respect to +any claim by LICENSEE or any third party on account of or arising from this Agreement or +use of STAG. + +8. Title to copyright of all portions of STAG developed at UOS and/or DERA together with +associated documentation shall at all times remain with DERA, and LICENSEE agrees to +preserve same. LICENSEE agrees to ensure that this information and appropriate copyright +notice is reproduced with any copies of STAG or any modified versions derived from it. + +9. This agreement shall be construed, interpreted, and applied in accordance with the laws +of England. + +for DERA by: + +J B EDWARDS +IPD5A +10 NOV 1997 + +Intellectual Property Department +Defence Evaluation and Research Agency +St Andrews Road +Malvern +WR14 3PS +United Kingdom + +phone: +44 - 1684 - 894234 +fax: +44 - 1684 - 894146 diff --git a/src/spicelib/devices/soi3/soi3.c b/src/spicelib/devices/soi3/soi3.c new file mode 100644 index 000000000..80a82e0be --- /dev/null +++ b/src/spicelib/devices/soi3/soi3.c @@ -0,0 +1,239 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#include "ngspice.h" +#include +#include "devdefs.h" +#include "ifsim.h" +#include "soi3defs.h" +#include "suffix.h" + + + +char *SOI3names[] = { + "Drain", + "Front Gate", + "Source", + "Back Gate", + "Bulk", + "Thermal" +}; + + +IFparm SOI3pTable[] = { /* parameters */ + IOP("l", SOI3_L, IF_REAL, "Length"), + IOP("w", SOI3_W, IF_REAL, "Width"), + IOP("nrd", SOI3_NRD, IF_REAL, "Drain squares"), + IOP("nrs", SOI3_NRS, IF_REAL, "Source squares"), + IP("off", SOI3_OFF, IF_FLAG, "Device initially off"), + IOP("icvds", SOI3_IC_VDS, IF_REAL, "Initial D-S voltage"), + IOP("icvgfs", SOI3_IC_VGFS, IF_REAL, "Initial GF-S voltage"), + IOP("icvgbs", SOI3_IC_VGBS, IF_REAL, "Initial GB-S voltage"), + IOP("icvbs", SOI3_IC_VBS, IF_REAL, "Initial B-S voltage"), + IOP("temp", SOI3_TEMP, IF_REAL, "Instance temperature"), + IOP("rt", SOI3_RT, IF_REAL, "Instance Lumped Thermal Resistance"), + IOP("ct", SOI3_CT, IF_REAL, "Instance Lumped Thermal Capacitance"), + IOP("rt1", SOI3_RT1, IF_REAL, "Second Thermal Resistance"), + IOP("ct1", SOI3_CT1, IF_REAL, "Second Thermal Capacitance"), + IOP("rt2", SOI3_RT2, IF_REAL, "Third Thermal Resistance"), + IOP("ct2", SOI3_CT2, IF_REAL, "Third Thermal Capacitance"), + IOP("rt3", SOI3_RT3, IF_REAL, "Fourth Thermal Resistance"), + IOP("ct3", SOI3_CT3, IF_REAL, "Fourth Thermal Capacitance"), + IOP("rt4", SOI3_RT4, IF_REAL, "Fifth Thermal Resistance"), + IOP("ct4", SOI3_CT4, IF_REAL, "Fifth Thermal Capacitance"), + + IP( "ic", SOI3_IC, IF_REALVEC,"Vector of D-S, GF-S, GB-S, B-S voltages"), +/* IP( "sens_l", SOI3_L_SENS, IF_FLAG, "flag to request sensitivity WRT length"), + IP( "sens_w", SOI3_W_SENS, IF_FLAG, "flag to request sensitivity WRT width"),*/ + OP( "dnode", SOI3_DNODE, IF_INTEGER, "Number of the drain node "), + OP( "gfnode", SOI3_GFNODE, IF_INTEGER, "Number of frt. gate node "), + OP( "snode", SOI3_SNODE, IF_INTEGER, "Number of the source node "), + OP( "gbnode", SOI3_GBNODE, IF_INTEGER, "Number of back gate node "), + OP( "bnode", SOI3_BNODE, IF_INTEGER, "Number of the body node "), + OP( "dnodeprime", SOI3_DNODEPRIME, IF_INTEGER, "Number of int. drain node"), + OP( "snodeprime", SOI3_SNODEPRIME, IF_INTEGER, "Number of int. source node "), + OP( "tnode", SOI3_TNODE, IF_INTEGER, "Number of thermal node "), + OP( "branch", SOI3_BRANCH, IF_INTEGER, "Number of thermal branch "), + OP( "sourceconductance", SOI3_SOURCECONDUCT, IF_REAL, "Conductance of source"), + OP( "drainconductance", SOI3_DRAINCONDUCT, IF_REAL, "Conductance of drain"), + OP( "von", SOI3_VON, IF_REAL, "Effective Threshold Voltage (von) "), + OP( "vfbf", SOI3_VFBF, IF_REAL, "Temperature adjusted flat band voltage"), + OP( "vdsat", SOI3_VDSAT, IF_REAL, "Saturation drain voltage"), + OP( "sourcevcrit", SOI3_SOURCEVCRIT,IF_REAL, "Critical source voltage"), + OP( "drainvcrit", SOI3_DRAINVCRIT, IF_REAL, "Critical drain voltage"), + OP( "id", SOI3_ID, IF_REAL, "Drain current"), + OP( "ibs", SOI3_IBS, IF_REAL, "B-S junction current"), + OP( "ibd", SOI3_IBD, IF_REAL, "B-D junction current"), + OP( "gmbs", SOI3_GMBS, IF_REAL, "Bulk-Source transconductance"), + OP( "gmf", SOI3_GMF, IF_REAL, "Front transconductance"), + OP( "gmb", SOI3_GMB, IF_REAL, "Back transconductance"), + OP( "gds", SOI3_GDS, IF_REAL, "Drain-Source conductance"), + OP( "gbd", SOI3_GBD, IF_REAL, "Bulk-Drain conductance"), + OP( "gbs", SOI3_GBS, IF_REAL, "Bulk-Source conductance"), + OP( "capbd", SOI3_CAPBD, IF_REAL, "Bulk-Drain capacitance"), + OP( "capbs", SOI3_CAPBS, IF_REAL, "Bulk-Source capacitance"), + OP( "cbd0", SOI3_CAPZEROBIASBD, IF_REAL, "Zero-Bias B-D junction capacitance"), + OP( "cbs0", SOI3_CAPZEROBIASBS, IF_REAL, "Zero-Bias B-S junction capacitance"), + OP( "vbd", SOI3_VBD, IF_REAL, "Bulk-Drain voltage"), + OP( "vbs", SOI3_VBS, IF_REAL, "Bulk-Source voltage"), + OP( "vgfs", SOI3_VGFS, IF_REAL, "Front gate-Source voltage"), + OP( "vgbs", SOI3_VGBS, IF_REAL, "Back gate-Source voltage"), + OP( "vds", SOI3_VDS, IF_REAL, "Drain-Source voltage"), + OP( "qgf", SOI3_QGF, IF_REAL, "Front Gate charge storage"), + OP( "iqgf",SOI3_IQGF,IF_REAL,"Current due to front gate charge storage"), +/* + OP( "qgb", SOI3_QGB, IF_REAL, "Back Gate charge storage"), + OP( "iqgb",SOI3_IQGB,IF_REAL,"Current due to back gate charge storage"), +*/ + OP( "qd", SOI3_QD, IF_REAL, "Drain charge storage"), + OP( "iqd",SOI3_IQD,IF_REAL,"Current due to drain charge storage"), + OP( "qs", SOI3_QS, IF_REAL, "Source charge storage"), + OP( "iqs",SOI3_IQS,IF_REAL,"Current due to source charge storage"), + OP( "qbd", SOI3_QBD, IF_REAL, "Bulk-Drain charge storage"), + OP( "iqbd",SOI3_IQBD,IF_REAL,"Current due to bulk-drain charge storage"), + OP( "qbs", SOI3_QBS, IF_REAL, "Bulk-Source charge storage"), + OP( "iqbs",SOI3_IQBS,IF_REAL,"Currnet due to bulk-source charge storage"), +/* extra stuff for newer model -msll Jan96 */ + OP( "vfbb", SOI3_VFBB, IF_REAL, "Temperature adjusted back flat band voltage") + +/*, + OP( "sens_l_dc", SOI3_L_SENS_DC, IF_REAL, "dc sensitivity wrt length"), + OP( "sens_l_real", SOI3_L_SENS_REAL,IF_REAL, + "real part of ac sensitivity wrt length"), + OP( "sens_l_imag", SOI3_L_SENS_IMAG,IF_REAL, + "imag part of ac sensitivity wrt length"), + OP( "sens_l_mag", SOI3_L_SENS_MAG, IF_REAL, + "sensitivity wrt l of ac magnitude"), + OP( "sens_l_ph", SOI3_L_SENS_PH, IF_REAL, + "sensitivity wrt l of ac phase"), + OP( "sens_l_cplx", SOI3_L_SENS_CPLX,IF_COMPLEX, "ac sensitivity wrt length"), + OP( "sens_w_dc", SOI3_W_SENS_DC, IF_REAL, "dc sensitivity wrt width"), + OP( "sens_w_real", SOI3_W_SENS_REAL,IF_REAL, + "real part of ac sensitivity wrt width"), + OP( "sens_w_imag", SOI3_W_SENS_IMAG,IF_REAL, + "imag part of ac sensitivity wrt width"), + OP( "sens_w_mag", SOI3_W_SENS_MAG, IF_REAL, + "sensitivity wrt w of ac magnitude"), + OP( "sens_w_ph", SOI3_W_SENS_PH, IF_REAL, + "sensitivity wrt w of ac phase"), + OP( "sens_w_cplx", SOI3_W_SENS_CPLX,IF_COMPLEX, "ac sensitivity wrt width")*/ +}; + +IFparm SOI3mPTable[] = { /* model parameters */ + IOP("vto", SOI3_MOD_VTO, IF_REAL ,"Threshold voltage"), + IOP("vt0", SOI3_MOD_VTO, IF_REAL ,"Threshold voltage"), + IOP("vfbf", SOI3_MOD_VFBF, IF_REAL ,"Flat band voltage"), + IOP("kp", SOI3_MOD_KP, IF_REAL ,"Transconductance parameter"), + IOP("gamma", SOI3_MOD_GAMMA, IF_REAL ,"Body Factor"), + IOP("phi", SOI3_MOD_PHI, IF_REAL ,"Surface potential"), + IOP("lambda",SOI3_MOD_LAMBDA,IF_REAL ,"Channel length modulation"), + IOP("theta", SOI3_MOD_THETA, IF_REAL ,"Vertical field mobility degradation"), + IOP("rd", SOI3_MOD_RD, IF_REAL ,"Drain ohmic resistance"), + IOP("rs", SOI3_MOD_RS, IF_REAL ,"Source ohmic resistance"), + IOP("cbd", SOI3_MOD_CBD, IF_REAL ,"B-D junction capacitance"), + IOP("cbs", SOI3_MOD_CBS, IF_REAL ,"B-S junction capacitance"), + IOP("is", SOI3_MOD_IS, IF_REAL ,"Bulk junction sat. current"), + IOP("is1", SOI3_MOD_IS1, IF_REAL ,"2nd Bulk junction sat. current"), + IOP("pb", SOI3_MOD_PB, IF_REAL ,"Bulk junction potential"), + IOP("cgfso", SOI3_MOD_CGFSO, IF_REAL ,"Front Gate-source overlap cap."), + IOP("cgfdo", SOI3_MOD_CGFDO, IF_REAL ,"Front Gate-drain overlap cap."), + IOP("cgfbo", SOI3_MOD_CGFBO, IF_REAL ,"Front Gate-bulk overlap cap."), + IOP("cgbso", SOI3_MOD_CGBSO, IF_REAL ,"Back Gate-source overlap cap."), + IOP("cgbdo", SOI3_MOD_CGBDO, IF_REAL ,"Back Gate-drain overlap cap."), + IOP("cgb_bo", SOI3_MOD_CGB_BO, IF_REAL ,"Back Gate-bulk overlap cap."), + IOP("rsh", SOI3_MOD_RSH, IF_REAL ,"Sheet resistance"), + IOP("cj", SOI3_MOD_CJSW, IF_REAL ,"Side junction cap per area"), + IOP("mj", SOI3_MOD_MJSW, IF_REAL ,"Side grading coefficient"), + IOP("js", SOI3_MOD_JS, IF_REAL ,"Bulk jct. sat. current density"), + IOP("js1", SOI3_MOD_JS1, IF_REAL ,"2nd Bulk jct. sat. current density"), + IOP("tof", SOI3_MOD_TOF, IF_REAL ,"Front Oxide thickness"), + IOP("tob", SOI3_MOD_TOB, IF_REAL ,"Back Oxide thickness"), + IOP("tb", SOI3_MOD_TB, IF_REAL ,"Bulk film thickness"), + IOP("ld", SOI3_MOD_LD, IF_REAL ,"Lateral diffusion"), + IOP("u0", SOI3_MOD_U0, IF_REAL ,"Surface mobility"), + IOP("uo", SOI3_MOD_U0, IF_REAL ,"Surface mobility"), + IOP("fc", SOI3_MOD_FC, IF_REAL ,"Forward bias jct. fit parm."), + IP("nsoi", SOI3_MOD_NSOI3, IF_FLAG ,"N type SOI3fet model"), + IP("psoi", SOI3_MOD_PSOI3, IF_FLAG ,"P type SOI3fet model"), + IOP("kox", SOI3_MOD_KOX, IF_REAL ,"Oxide thermal conductivity"), + IOP("shsi", SOI3_MOD_SHSI, IF_REAL ,"Specific heat of silicon"), + IOP("dsi", SOI3_MOD_DSI, IF_REAL ,"Density of silicon"), + IOP("nsub", SOI3_MOD_NSUB, IF_REAL ,"Substrate doping"), + IOP("tpg", SOI3_MOD_TPG, IF_INTEGER,"Gate type"), + IOP("nqff", SOI3_MOD_NQFF, IF_REAL ,"Front fixed oxide charge density"), + IOP("nqfb", SOI3_MOD_NQFB, IF_REAL ,"Back fixed oxide charge density"), + IOP("nssf", SOI3_MOD_NSSF, IF_REAL ,"Front surface state density"), + IOP("nssb", SOI3_MOD_NSSB, IF_REAL ,"Back surface state density"), + IOP("tnom", SOI3_MOD_TNOM, IF_REAL ,"Parameter measurement temp"), + IP("kf", SOI3_MOD_KF, IF_REAL ,"Flicker noise coefficient"), + IP("af", SOI3_MOD_AF, IF_REAL ,"Flicker noise exponent"), +/* extra stuff for newer model - msll Jan96 */ + IOP("sigma", SOI3_MOD_SIGMA, IF_REAL ,"DIBL coefficient"), + IOP("chifb", SOI3_MOD_CHIFB, IF_REAL ,"Temperature coeff of flatband voltage"), + IOP("chiphi",SOI3_MOD_CHIPHI, IF_REAL ,"Temperature coeff of PHI"), + IOP("deltaw",SOI3_MOD_DELTAW,IF_REAL ,"Narrow width factor"), + IOP("deltal",SOI3_MOD_DELTAL,IF_REAL ,"Short channel factor"), + IOP("vsat", SOI3_MOD_VSAT, IF_REAL ,"Saturation velocity"), + IOP("k", SOI3_MOD_K, IF_REAL ,"Thermal exponent"), + IOP("lx", SOI3_MOD_LX, IF_REAL ,"Channel length modulation (alternative)"), + IOP("vp", SOI3_MOD_VP, IF_REAL ,"Channel length modulation (alt. empirical)"), + IOP("eta", SOI3_MOD_ETA, IF_REAL ,"Impact ionization field adjustment factor"), + IOP("alpha0",SOI3_MOD_ALPHA0,IF_REAL ,"First impact ionisation coeff (alpha0)"), + IOP("beta0", SOI3_MOD_BETA0, IF_REAL ,"Second impact ionisation coeff (beta0)"), + IOP("lm", SOI3_MOD_LM, IF_REAL ,"Impact ion. drain region length"), + IOP("lm1", SOI3_MOD_LM1, IF_REAL ,"Impact ion. drain region length coeff"), + IOP("lm2", SOI3_MOD_LM2, IF_REAL ,"Impact ion. drain region length coeff"), + IOP("etad", SOI3_MOD_ETAD, IF_REAL ,"Diode ideality factor"), + IOP("etad1", SOI3_MOD_ETAD1, IF_REAL ,"2nd Diode ideality factor"), + IOP("chibeta",SOI3_MOD_CHIBETA,IF_REAL ,"Impact ionisation temperature coefficient"), + IOP("vfbb", SOI3_MOD_VFBB, IF_REAL ,"Back Flat band voltage"), + IOP("gammab",SOI3_MOD_GAMMAB,IF_REAL ,"Back Body Factor"), + IOP("chid", SOI3_MOD_CHID, IF_REAL ,"Junction temperature factor"), + IOP("chid1", SOI3_MOD_CHID1, IF_REAL ,"2nd Junction temperature factor"), + IOP("dvt", SOI3_MOD_DVT, IF_INTEGER,"Switch for temperature dependence of vt in diodes"), + IOP("nlev", SOI3_MOD_NLEV, IF_INTEGER,"Level switch for flicker noise model"), + IOP("betabjt",SOI3_MOD_BETABJT,IF_REAL ,"Beta for BJT"), + IOP("tauf", SOI3_MOD_TAUFBJT,IF_REAL ,"Forward tau for BJT"), + IOP("taur", SOI3_MOD_TAURBJT,IF_REAL ,"Reverse tau for BJT"), + IOP("betaexp",SOI3_MOD_BETAEXP,IF_REAL ,"Exponent for Beta of BJT"), + IOP("tauexp", SOI3_MOD_TAUEXP,IF_REAL, "Exponent for Transit time of BJT"), + IOP("rsw", SOI3_MOD_RSW, IF_REAL ,"Source resistance width scaling factor"), + IOP("rdw", SOI3_MOD_RDW, IF_REAL ,"Drain resistance width scaling factor"), + IOP("fmin", SOI3_MOD_FMIN, IF_REAL ,"Minimum feature size of technology"), + IOP("vtex", SOI3_MOD_VTEX, IF_REAL ,"Extracted threshold voltage"), + IOP("vdex", SOI3_MOD_VDEX, IF_REAL ,"Drain bias at which vtex extracted"), + IOP("delta0",SOI3_MOD_DELTA0,IF_REAL ,"Surface potential factor for vtex conversion"), + IOP("csf", SOI3_MOD_CSF ,IF_REAL ,"Saturation region charge sharing factor"), + IOP("nplus", SOI3_MOD_NPLUS ,IF_REAL ,"Doping concentration of N+ or P+ regions"), + IOP("rta", SOI3_MOD_RTA ,IF_REAL ,"Thermal resistance area scaling factor"), + IOP("cta", SOI3_MOD_CTA ,IF_REAL ,"Thermal capacitance area scaling factor") + +}; + + + +int SOI3nSize = NUMELEMS(SOI3names); +int SOI3pTSize = NUMELEMS(SOI3pTable); +int SOI3mPTSize = NUMELEMS(SOI3mPTable); +int SOI3iSize = sizeof(SOI3instance); +int SOI3mSize = sizeof(SOI3model); + + + + diff --git a/src/spicelib/devices/soi3/soi3acld.c b/src/spicelib/devices/soi3/soi3acld.c new file mode 100644 index 000000000..0a962002e --- /dev/null +++ b/src/spicelib/devices/soi3/soi3acld.c @@ -0,0 +1,406 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "soi3defs.h" +#include "sperror.h" +#include "suffix.h" + + +int +SOI3acLoad(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + SOI3model *model = (SOI3model*)inModel; + SOI3instance *here; + int xnrm; + int xrev; + + double cgfgf,cgfd,cgfs,cgfdeltaT; + double cdgf,cdd,cds,cddeltaT; + double csgf,csd,css,csdeltaT; + double cbgf,cbd,cbs,cbdeltaT,cbgb; + double cgbgb,cgbsb,cgbdb; + + double xcgfgf,xcgfd,xcgfs,xcgfdeltaT; + double xcdgf,xcdd,xcds,xcddeltaT; + double xcsgf,xcsd,xcss,xcsdeltaT; + double xcbgf,xcbd,xcbs,xcbdeltaT,xcbgb; + double xcgbgb,xcgbsb,xcgbdb; + + double capbd,capbs; /* diode capacitances */ + + double xcBJTbsbs,xcBJTbsdeltaT; + double xcBJTbdbd,xcBJTbddeltaT; + + double rtargs[5]; + double grt[5]; + double ctargs[5]; + double xct[5]; /* 1/reactance of thermal cap */ + int tnodeindex; + + double cgfb0; + double cgfd0; + double cgfs0; + + double cgbb0; + double cgbd0; + double cgbs0; + + double xcgbd0,xcgbs0; + + double EffectiveLength; + + double omega; + + omega = ckt->CKTomega; + + for( ; model != NULL; model = model->SOI3nextModel) + { + for(here = model->SOI3instances; here!= NULL; + here = here->SOI3nextInstance) + { + + if (here->SOI3mode < 0) + { + xnrm=0; + xrev=1; + } + else + { + xnrm=1; + xrev=0; + } + + EffectiveLength=here->SOI3l - 2*model->SOI3latDiff; + cgfs0 = model->SOI3frontGateSourceOverlapCapFactor * here->SOI3w; + cgfd0 = model->SOI3frontGateDrainOverlapCapFactor * here->SOI3w; + cgfb0 = model->SOI3frontGateBulkOverlapCapFactor * EffectiveLength; + + /* JimB - can use basic device geometry to calculate source/back gate */ + /* and drain/back gate capacitances to a first approximation. Use this*/ + /* default model if capacitance factors aren't given in model netlist. */ + + if(model->SOI3backGateSourceOverlapCapFactorGiven) + { + cgbs0 = model->SOI3backGateSourceOverlapCapFactor * here->SOI3w; + } + else + { + /* As a basic circuit designers approximation, length of drain and */ + /* source regions often taken to have length of twice the minimum */ + /* feature size for that technology. */ + cgbs0 = 2*1e-6*model->SOI3minimumFeatureSize * here->SOI3w + * model->SOI3backOxideCapFactor; + } + if(model->SOI3backGateDrainOverlapCapFactorGiven) + { + cgbd0 = model->SOI3backGateDrainOverlapCapFactor * here->SOI3w; + } + else + { + /* As a basic circuit designer's approximation, length of drain and */ + /* source regions often taken to have length of twice the minimum */ + /* feature size for that technology. */ + cgbd0 = 2*1e-6*model->SOI3minimumFeatureSize * here->SOI3w + * model->SOI3backOxideCapFactor; + } + cgbb0 = model->SOI3backGateBulkOverlapCapFactor * EffectiveLength; + + capbd = here->SOI3capbd; + capbs = here->SOI3capbs; + + cgfgf = *(ckt->CKTstate0 + here->SOI3cgfgf); + cgfd = *(ckt->CKTstate0 + here->SOI3cgfd); + cgfs = *(ckt->CKTstate0 + here->SOI3cgfs); + cgfdeltaT = *(ckt->CKTstate0 + here->SOI3cgfdeltaT); + csgf = *(ckt->CKTstate0 + here->SOI3csgf); + csd = *(ckt->CKTstate0 + here->SOI3csd); + css = *(ckt->CKTstate0 + here->SOI3css); + csdeltaT = *(ckt->CKTstate0 + here->SOI3csdeltaT); + cdgf = *(ckt->CKTstate0 + here->SOI3cdgf); + cdd = *(ckt->CKTstate0 + here->SOI3cdd); + cds = *(ckt->CKTstate0 + here->SOI3cds); + cddeltaT = *(ckt->CKTstate0 + here->SOI3cddeltaT); + cgbgb = *(ckt->CKTstate0 + here->SOI3cgbgb); + cgbsb = *(ckt->CKTstate0 + here->SOI3cgbsb); + cgbdb = *(ckt->CKTstate0 + here->SOI3cgbdb); + cbgf = -(cgfgf + cdgf + csgf); + cbd = -(cgfd + cdd + csd + cgbdb); + cbs = -(cgfs + cds + css + cgbsb); + cbdeltaT = -(cgfdeltaT + cddeltaT + csdeltaT); + cbgb = -cgbgb; + + xcgfgf = (cgfgf + cgfd0 + cgfs0 + cgfb0) * omega; + xcgfd = (cgfd - cgfd0) * omega; + xcgfs = (cgfs - cgfs0) * omega; + xcgfdeltaT = cgfdeltaT * omega; + xcsgf = (csgf - cgfs0) * omega; + xcsd = csd * omega; + xcss = (css + capbs + cgfs0) * omega; + xcsdeltaT = csdeltaT * omega; + xcdgf = (cdgf - cgfd0) * omega; + xcdd = (cdd + capbd + cgfd0) * omega; + xcds = cds * omega; + xcddeltaT = cddeltaT * omega; + xcgbgb = (cgbgb + cgbb0 + cgbd0 + cgbs0) * omega; + xcgbsb = (cgbsb - cgbs0) * omega; + xcgbdb = -cgbd0 * omega; + xcbgf = (cbgf - cgfb0) * omega; + xcbd = (cbd - capbd) * omega; + xcbs = (cbs - capbs) * omega; + xcbdeltaT = cbdeltaT * omega; + xcbgb = cbgb * omega; + + xcgbs0 = cgbs0 * omega; + xcgbd0 = cgbd0 * omega; + + xcBJTbsbs = *(ckt->CKTstate0 + here->SOI3cBJTbsbs) * omega; + xcBJTbsdeltaT = *(ckt->CKTstate0 + here->SOI3cBJTbsdeltaT) * omega; + xcBJTbdbd = *(ckt->CKTstate0 + here->SOI3cBJTbdbd) * omega; + xcBJTbddeltaT = *(ckt->CKTstate0 + here->SOI3cBJTbddeltaT) * omega; + + /* JimB - 15/9/99 */ + /* Code for multiple thermal time constants. Start by moving all */ + /* rt and ct constants into arrays. */ + rtargs[0]=here->SOI3rt; + rtargs[1]=here->SOI3rt1; + rtargs[2]=here->SOI3rt2; + rtargs[3]=here->SOI3rt3; + rtargs[4]=here->SOI3rt4; + + ctargs[0]=here->SOI3ct; + ctargs[1]=here->SOI3ct1; + ctargs[2]=here->SOI3ct2; + ctargs[3]=here->SOI3ct3; + ctargs[4]=here->SOI3ct4; + + /* Set all admittance components to zero. */ + grt[0]=grt[1]=grt[2]=grt[3]=grt[4]=0.0; + xct[0]=xct[1]=xct[2]=xct[3]=xct[4]=0.0; + /* Now calculate conductances and susceptances from rt and ct. */ + /* Don't need to worry about divide by zero when calculating */ + /* grt components, as soi3setup() only creates a thermal node */ + /* if corresponding rt is greater than zero. */ + for(tnodeindex=0;tnodeindexSOI3numThermalNodes;tnodeindex++) + { + xct[tnodeindex] = ctargs[tnodeindex] * ckt->CKTomega; + grt[tnodeindex] = 1/rtargs[tnodeindex]; + } + /* End JimB */ + + /* + * load matrix + */ + + *(here->SOI3GF_gfPtr + 1) += xcgfgf; + *(here->SOI3GB_gbPtr + 1) += xcgbgb; + *(here->SOI3B_bPtr + 1) += -(xcbgf+xcbd+xcbs+xcbgb) + +xcBJTbsbs+xcBJTbdbd; + + *(here->SOI3DP_dpPtr + 1) += xcdd+xcgbd0+xcBJTbdbd; + *(here->SOI3SP_spPtr + 1) += xcss+xcgbs0+xcBJTbsbs; + + *(here->SOI3GF_dpPtr + 1) += xcgfd; + *(here->SOI3GF_spPtr + 1) += xcgfs; + *(here->SOI3GF_bPtr + 1) -= (xcgfgf + xcgfd + xcgfs); + + *(here->SOI3GB_dpPtr + 1) += xcgbdb; + *(here->SOI3GB_spPtr + 1) += xcgbsb; + *(here->SOI3GB_bPtr + 1) -= (xcgbgb + xcgbdb + xcgbsb); + + *(here->SOI3B_gfPtr + 1) += xcbgf; + *(here->SOI3B_gbPtr + 1) += xcbgb; + *(here->SOI3B_dpPtr + 1) += xcbd-xcBJTbdbd; + *(here->SOI3B_spPtr + 1) += xcbs-xcBJTbsbs; + + *(here->SOI3DP_gfPtr + 1) += xcdgf; + *(here->SOI3DP_gbPtr + 1) += -xcgbd0; + *(here->SOI3DP_bPtr + 1) += -(xcdgf + xcdd + xcds + xcBJTbdbd); + *(here->SOI3DP_spPtr + 1) += xcds; + + *(here->SOI3SP_gfPtr + 1) += xcsgf; + *(here->SOI3SP_gbPtr + 1) += -xcgbs0; + *(here->SOI3SP_bPtr + 1) += -(xcsgf + xcsd + xcss + xcBJTbsbs); + *(here->SOI3SP_dpPtr + 1) += xcsd; + +/* if no thermal behaviour specified, then put in zero valued indpt. voltage source + between TOUT and ground */ + if (here->SOI3rt==0) + { + *(here->SOI3TOUT_ibrPtr + 1) += 1.0; + *(here->SOI3IBR_toutPtr + 1) += 1.0; + *(ckt->CKTirhs + (here->SOI3branch)) = 0; + } + else + { + *(here->SOI3TOUT_toutPtr + 1) += xct[0]; + if (here->SOI3numThermalNodes > 1) + { + *(here->SOI3TOUT_tout1Ptr + 1) += -xct[0]; + *(here->SOI3TOUT1_toutPtr + 1) += -xct[0]; + *(here->SOI3TOUT1_tout1Ptr + 1) += xct[0]+xct[1]; + } + if (here->SOI3numThermalNodes > 2) + { + *(here->SOI3TOUT1_tout2Ptr + 1) += -xct[1]; + *(here->SOI3TOUT2_tout1Ptr + 1) += -xct[1]; + *(here->SOI3TOUT2_tout2Ptr + 1) += xct[1]+xct[2]; + } + if (here->SOI3numThermalNodes > 3) + { + *(here->SOI3TOUT2_tout3Ptr + 1) += -xct[2]; + *(here->SOI3TOUT3_tout2Ptr + 1) += -xct[2]; + *(here->SOI3TOUT3_tout3Ptr + 1) += xct[2]+xct[3]; + } + if (here->SOI3numThermalNodes > 4) + { + *(here->SOI3TOUT3_tout4Ptr + 1) += -xct[3]; + *(here->SOI3TOUT4_tout3Ptr + 1) += -xct[3]; + *(here->SOI3TOUT4_tout4Ptr + 1) += xct[3]+xct[4]; + } + *(here->SOI3GF_toutPtr + 1) += xcgfdeltaT*model->SOI3type; + *(here->SOI3DP_toutPtr + 1) += (xcddeltaT - xcBJTbddeltaT)*model->SOI3type; + *(here->SOI3SP_toutPtr + 1) += (xcsdeltaT - xcBJTbsdeltaT)*model->SOI3type; + *(here->SOI3B_toutPtr + 1) += model->SOI3type* + (xcbdeltaT + xcBJTbsdeltaT + xcBJTbddeltaT); + } + + + /* and now real part */ + *(here->SOI3D_dPtr) += (here->SOI3drainConductance); + *(here->SOI3S_sPtr) += (here->SOI3sourceConductance); + *(here->SOI3B_bPtr) += (here->SOI3gbd+here->SOI3gbs - + here->SOI3gMmbs + - here->SOI3gBJTdb_bs - here->SOI3gBJTsb_bd); + + *(here->SOI3DP_dpPtr) += + (here->SOI3drainConductance+here->SOI3gds+ + here->SOI3gbd+xrev*(here->SOI3gmf+here->SOI3gmbs+ + here->SOI3gmb)+xnrm*here->SOI3gMd); + *(here->SOI3SP_spPtr) += + (here->SOI3sourceConductance+here->SOI3gds+ + here->SOI3gbs+xnrm*(here->SOI3gmf+here->SOI3gmbs+ + here->SOI3gmb)+xrev*here->SOI3gMd); + + *(here->SOI3D_dpPtr) += (-here->SOI3drainConductance); + + *(here->SOI3S_spPtr) += (-here->SOI3sourceConductance); + *(here->SOI3B_gfPtr) += -here->SOI3gMmf; + *(here->SOI3B_gbPtr) += -(here->SOI3gMmb); + *(here->SOI3B_dpPtr) += -(here->SOI3gbd) + here->SOI3gBJTsb_bd + + xrev*(here->SOI3gMmf+here->SOI3gMmb+ + here->SOI3gMmbs+here->SOI3gMd) - + xnrm*here->SOI3gMd; + *(here->SOI3B_spPtr) += -(here->SOI3gbs) + here->SOI3gBJTdb_bs + + xnrm*(here->SOI3gMmf+here->SOI3gMmb+ + here->SOI3gMmbs+here->SOI3gMd) - + xrev*here->SOI3gMd; + *(here->SOI3DP_dPtr) += (-here->SOI3drainConductance); + *(here->SOI3SP_sPtr) += (-here->SOI3sourceConductance); + + *(here->SOI3DP_gfPtr) += ((xnrm-xrev)*here->SOI3gmf + + xnrm*here->SOI3gMmf); + *(here->SOI3DP_gbPtr) += ((xnrm-xrev)*here->SOI3gmb + + xnrm*here->SOI3gMmb); + *(here->SOI3DP_bPtr) += (-here->SOI3gbd + here->SOI3gBJTdb_bs + +(xnrm-xrev)*here->SOI3gmbs+ + xnrm*here->SOI3gMmbs); + *(here->SOI3DP_spPtr) += (-here->SOI3gds - here->SOI3gBJTdb_bs + -xnrm*(here->SOI3gmf+here->SOI3gmb+here->SOI3gmbs + + here->SOI3gMmf+here->SOI3gMmb+here->SOI3gMmbs+here->SOI3gMd)); + + *(here->SOI3SP_gfPtr) += (-(xnrm-xrev)*here->SOI3gmf+ + xrev*here->SOI3gMmf); + *(here->SOI3SP_gbPtr) += (-(xnrm-xrev)*here->SOI3gmb+ + xrev*here->SOI3gMmb); + *(here->SOI3SP_bPtr) += (-here->SOI3gbs + here->SOI3gBJTsb_bd + -(xnrm-xrev)*here->SOI3gmbs+ + xrev*here->SOI3gMmbs); + *(here->SOI3SP_dpPtr) += (-here->SOI3gds - here->SOI3gBJTsb_bd + -xrev*(here->SOI3gmf+here->SOI3gmb+here->SOI3gmbs+ + here->SOI3gMmf+here->SOI3gMmb+here->SOI3gMmbs+here->SOI3gMd)); + +/* if no thermal behaviour specified, then put in zero valued indpt. voltage source + between TOUT and ground */ + if (here->SOI3rt==0) + { + *(here->SOI3TOUT_ibrPtr) += 1.0; + *(here->SOI3IBR_toutPtr) += 1.0; + *(ckt->CKTrhs + (here->SOI3branch)) = 0; + } + else + { + *(here->SOI3TOUT_toutPtr) += -(here->SOI3gPdT)+grt[0]; + if (here->SOI3numThermalNodes > 1) + { + *(here->SOI3TOUT_tout1Ptr) += -grt[0]; + *(here->SOI3TOUT1_toutPtr) += -grt[0]; + *(here->SOI3TOUT1_tout1Ptr) += grt[0]+grt[1]; + } + if (here->SOI3numThermalNodes > 2) + { + *(here->SOI3TOUT1_tout2Ptr) += -grt[1]; + *(here->SOI3TOUT2_tout1Ptr) += -grt[1]; + *(here->SOI3TOUT2_tout2Ptr) += grt[1]+grt[2]; + } + if (here->SOI3numThermalNodes > 3) + { + *(here->SOI3TOUT2_tout3Ptr) += -grt[2]; + *(here->SOI3TOUT3_tout2Ptr) += -grt[2]; + *(here->SOI3TOUT3_tout3Ptr) += grt[2]+grt[3]; + } + if (here->SOI3numThermalNodes > 4) + { + *(here->SOI3TOUT3_tout4Ptr) += -grt[3]; + *(here->SOI3TOUT4_tout3Ptr) += -grt[3]; + *(here->SOI3TOUT4_tout4Ptr) += grt[3]+grt[4]; + } + + *(here->SOI3TOUT_dpPtr) += xnrm*(-(here->SOI3gPds*model->SOI3type)) + +xrev*(here->SOI3gPds+here->SOI3gPmf+ + here->SOI3gPmb+here->SOI3gPmbs)* + model->SOI3type; + *(here->SOI3TOUT_gfPtr) += -(here->SOI3gPmf*model->SOI3type); + *(here->SOI3TOUT_gbPtr) += -(here->SOI3gPmb*model->SOI3type); + *(here->SOI3TOUT_bPtr) += -(here->SOI3gPmbs*model->SOI3type); + *(here->SOI3TOUT_spPtr) += xnrm*(here->SOI3gPds+here->SOI3gPmf+ + here->SOI3gPmb+here->SOI3gPmbs)*model->SOI3type + +xrev*(-(here->SOI3gPds*model->SOI3type)); + + *(here->SOI3DP_toutPtr) += (xnrm-xrev)*here->SOI3gt*model->SOI3type; + *(here->SOI3SP_toutPtr) += (xrev-xnrm)*here->SOI3gt*model->SOI3type; +/* need to mult by type in above as conductances will be used with exterior voltages + which will be -ve for PMOS except for gPdT */ +/* now for thermal influence on impact ionisation current and tranisent stuff */ + *(here->SOI3DP_toutPtr) += (xnrm*here->SOI3gMdeltaT - + here->SOI3gbdT + here->SOI3gBJTdb_deltaT)*model->SOI3type; + *(here->SOI3SP_toutPtr) += (xrev*here->SOI3gMdeltaT - + here->SOI3gbsT + here->SOI3gBJTsb_deltaT)*model->SOI3type; + *(here->SOI3B_toutPtr) -= (here->SOI3gMdeltaT - here->SOI3gbsT - + here->SOI3gbdT + here->SOI3gBJTdb_deltaT + + here->SOI3gBJTsb_deltaT)*model->SOI3type; + } + } + } + return(OK); +} diff --git a/src/spicelib/devices/soi3/soi3ask.c b/src/spicelib/devices/soi3/soi3ask.c new file mode 100644 index 000000000..f284e6ae5 --- /dev/null +++ b/src/spicelib/devices/soi3/soi3ask.c @@ -0,0 +1,505 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#include "ngspice.h" +#include +#include "const.h" +#include "ifsim.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "soi3defs.h" +#include "sperror.h" +#include "suffix.h" + + +/*ARGSUSED*/ +int +SOI3ask(ckt,inst,which,value,select) + CKTcircuit *ckt; + GENinstance *inst; + int which; + IFvalue *value; + IFvalue *select; +{ + SOI3instance *here = (SOI3instance*)inst; + double vr; + double vi; + double sr; + double si; + double vm; + static char *msg = "Current and power not available for ac analysis"; + switch(which) { + case SOI3_L: + value->rValue = here->SOI3l; + return(OK); + case SOI3_W: + value->rValue = here->SOI3w; + return(OK); + case SOI3_NRS: + value->rValue = here->SOI3sourceSquares; + return(OK); + case SOI3_NRD: + value->rValue = here->SOI3drainSquares; + return(OK); + case SOI3_OFF: + value->rValue = here->SOI3off; + return(OK); + case SOI3_IC_VDS: + value->rValue = here->SOI3icVDS; + return(OK); + case SOI3_IC_VGFS: + value->rValue = here->SOI3icVGFS; + return(OK); + case SOI3_IC_VGBS: + value->rValue = here->SOI3icVGBS; + return(OK); + case SOI3_IC_VBS: + value->rValue = here->SOI3icVBS; + return(OK); + case SOI3_TEMP: + value->rValue = here->SOI3temp-CONSTCtoK; + return(OK); + case SOI3_RT: + value->rValue = here->SOI3rt; + return(OK); + case SOI3_CT: + value->rValue = here->SOI3ct; + return(OK); + case SOI3_DNODE: + value->iValue = here->SOI3dNode; + return(OK); + case SOI3_GFNODE: + value->iValue = here->SOI3gfNode; + return(OK); + case SOI3_SNODE: + value->iValue = here->SOI3sNode; + return(OK); + case SOI3_GBNODE: + value->iValue = here->SOI3gbNode; + return(OK); + case SOI3_BNODE: + value->iValue = here->SOI3bNode; + return(OK); + case SOI3_DNODEPRIME: + value->iValue = here->SOI3dNodePrime; + return(OK); + case SOI3_SNODEPRIME: + value->iValue = here->SOI3sNodePrime; + return(OK); + case SOI3_TNODE: + value->iValue = here->SOI3toutNode; + return(OK); + case SOI3_BRANCH: + value->iValue = here->SOI3branch; + return(OK); + case SOI3_SOURCECONDUCT: + value->rValue = here->SOI3sourceConductance; + return(OK); + case SOI3_DRAINCONDUCT: + value->rValue = here->SOI3drainConductance; + return(OK); + case SOI3_VON: + value->rValue = here->SOI3tVto; + return(OK); + case SOI3_VFBF: + value->rValue = here->SOI3tVfbF; + return(OK); + case SOI3_VDSAT: + value->rValue = here->SOI3vdsat; + return(OK); + case SOI3_SOURCEVCRIT: + value->rValue = here->SOI3sourceVcrit; + return(OK); + case SOI3_DRAINVCRIT: + value->rValue = here->SOI3drainVcrit; + return(OK); + case SOI3_ID: + value->rValue = here->SOI3id; + return(OK); + case SOI3_IBS: + value->rValue = here->SOI3ibs; + return(OK); + case SOI3_IBD: + value->rValue = here->SOI3ibd; + return(OK); + case SOI3_GMBS: + value->rValue = here->SOI3gmbs; + return(OK); + case SOI3_GMF: + value->rValue = here->SOI3gmf; + return(OK); + case SOI3_GMB: + value->rValue = here->SOI3gmb; + return(OK); + case SOI3_GDS: + value->rValue = here->SOI3gds; + return(OK); + case SOI3_GBD: + value->rValue = here->SOI3gbd; + return(OK); + case SOI3_GBS: + value->rValue = here->SOI3gbs; + return(OK); + case SOI3_CAPBD: + value->rValue = here->SOI3capbd; + return(OK); + case SOI3_CAPBS: + value->rValue = here->SOI3capbs; + return(OK); + case SOI3_CAPZEROBIASBD: + value->rValue = here->SOI3Cbd; + return(OK); + case SOI3_CAPZEROBIASBS: + value->rValue = here->SOI3Cbs; + return(OK); + case SOI3_VBD: + value->rValue = *(ckt->CKTstate0 + here->SOI3vbd); + return(OK); + case SOI3_VBS: + value->rValue = *(ckt->CKTstate0 + here->SOI3vbs); + return(OK); + case SOI3_VGFS: + value->rValue = *(ckt->CKTstate0 + here->SOI3vgfs); + return(OK); + case SOI3_VGBS: + value->rValue = *(ckt->CKTstate0 + here->SOI3vgbs); + return(OK); + case SOI3_VDS: + value->rValue = *(ckt->CKTstate0 + here->SOI3vds); + return(OK); + case SOI3_QGF: + value->rValue = *(ckt->CKTstate0 + here->SOI3qgf); + return(OK); + case SOI3_IQGF: + value->rValue = *(ckt->CKTstate0 + here->SOI3iqgf); + return(OK); + case SOI3_QD: + value->rValue = *(ckt->CKTstate0 + here->SOI3qd); + return(OK); + case SOI3_IQD: + value->rValue = *(ckt->CKTstate0 + here->SOI3iqd); + return(OK); + case SOI3_QS: + value->rValue = *(ckt->CKTstate0 + here->SOI3qs); + return(OK); + case SOI3_IQS: + value->rValue = *(ckt->CKTstate0 + here->SOI3iqs); + return(OK); + case SOI3_CGFGF: + value->rValue = *(ckt->CKTstate0 + here->SOI3cgfgf); + return (OK); + case SOI3_CGFD: + value->rValue = *(ckt->CKTstate0 + here->SOI3cgfd); + return (OK); + case SOI3_CGFS: + value->rValue = *(ckt->CKTstate0 + here->SOI3cgfs); + return (OK); + case SOI3_CGFDELTAT: + value->rValue = *(ckt->CKTstate0 + here->SOI3cgfdeltaT); + return (OK); + case SOI3_CDGF: + value->rValue = *(ckt->CKTstate0 + here->SOI3cdgf); + return (OK); + case SOI3_CDD: + value->rValue = *(ckt->CKTstate0 + here->SOI3cdd); + return (OK); + case SOI3_CDS: + value->rValue = *(ckt->CKTstate0 + here->SOI3cds); + return (OK); + case SOI3_CDDELTAT: + value->rValue = *(ckt->CKTstate0 + here->SOI3cddeltaT); + return (OK); + case SOI3_CSGF: + value->rValue = *(ckt->CKTstate0 + here->SOI3csgf); + return (OK); + case SOI3_CSD: + value->rValue = *(ckt->CKTstate0 + here->SOI3csd); + return (OK); + case SOI3_CSS: + value->rValue = *(ckt->CKTstate0 + here->SOI3css); + return (OK); + case SOI3_CSDELTAT: + value->rValue = *(ckt->CKTstate0 + here->SOI3csdeltaT); + return (OK); + case SOI3_QBD: + value->rValue = *(ckt->CKTstate0 + here->SOI3qbd); + return(OK); + case SOI3_IQBD: + value->rValue = *(ckt->CKTstate0 + here->SOI3iqbd); + return(OK); + case SOI3_QBS: + value->rValue = *(ckt->CKTstate0 + here->SOI3qbs); + return(OK); + case SOI3_IQBS: + value->rValue = *(ckt->CKTstate0 + here->SOI3iqbs); + return(OK); +/* extra stuff for newer model - msll Jan96 */ + case SOI3_VFBB: + value->rValue = here->SOI3tVfbB; + return(OK); + case SOI3_RT1: + value->rValue = here->SOI3rt1; + return(OK); + case SOI3_CT1: + value->rValue = here->SOI3ct1; + return(OK); + case SOI3_RT2: + value->rValue = here->SOI3rt2; + return(OK); + case SOI3_CT2: + value->rValue = here->SOI3ct2; + return(OK); + case SOI3_RT3: + value->rValue = here->SOI3rt3; + return(OK); + case SOI3_CT3: + value->rValue = here->SOI3ct3; + return(OK); + case SOI3_RT4: + value->rValue = here->SOI3rt4; + return(OK); + case SOI3_CT4: + value->rValue = here->SOI3ct4; + return(OK); + +/* + case SOI3_L_SENS_DC: + if(ckt->CKTsenInfo && here->SOI3sens_l){ + value->rValue = *(ckt->CKTsenInfo->SEN_Sap[select->iValue + 1]+ + here->SOI3senParmNo); + } + return(OK); + case SOI3_L_SENS_REAL: + if(ckt->CKTsenInfo && here->SOI3sens_l){ + value->rValue = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->SOI3senParmNo); + } + return(OK); + case SOI3_L_SENS_IMAG: + if(ckt->CKTsenInfo && here->SOI3sens_l){ + value->rValue = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->SOI3senParmNo); + } + return(OK); + case SOI3_L_SENS_MAG: + if(ckt->CKTsenInfo && here->SOI3sens_l){ + vr = *(ckt->CKTrhsOld + select->iValue + 1); + vi = *(ckt->CKTirhsOld + select->iValue + 1); + vm = sqrt(vr*vr + vi*vi); + if(vm == 0){ + value->rValue = 0; + return(OK); + } + sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->SOI3senParmNo); + si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->SOI3senParmNo); + value->rValue = (vr * sr + vi * si)/vm; + } + return(OK); + case SOI3_L_SENS_PH: + if(ckt->CKTsenInfo && here->SOI3sens_l){ + vr = *(ckt->CKTrhsOld + select->iValue + 1); + vi = *(ckt->CKTirhsOld + select->iValue + 1); + vm = vr*vr + vi*vi; + if(vm == 0){ + value->rValue = 0; + return(OK); + } + sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->SOI3senParmNo); + si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->SOI3senParmNo); + value->rValue = (vr * si - vi * sr)/vm; + } + return(OK); + case SOI3_L_SENS_CPLX: + if(ckt->CKTsenInfo && here->SOI3sens_l){ + value->cValue.real= + *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->SOI3senParmNo); + value->cValue.imag= + *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->SOI3senParmNo); + } + return(OK); + case SOI3_W_SENS_DC: + if(ckt->CKTsenInfo && here->SOI3sens_w){ + value->rValue = *(ckt->CKTsenInfo->SEN_Sap[select->iValue + 1]+ + here->SOI3senParmNo + here->SOI3sens_l); + } + return(OK); + case SOI3_W_SENS_REAL: + if(ckt->CKTsenInfo && here->SOI3sens_w){ + value->rValue = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->SOI3senParmNo + here->SOI3sens_l); + } + return(OK); + case SOI3_W_SENS_IMAG: + if(ckt->CKTsenInfo && here->SOI3sens_w){ + value->rValue = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->SOI3senParmNo + here->SOI3sens_l); + } + return(OK); + case SOI3_W_SENS_MAG: + if(ckt->CKTsenInfo && here->SOI3sens_w){ + vr = *(ckt->CKTrhsOld + select->iValue + 1); + vi = *(ckt->CKTirhsOld + select->iValue + 1); + vm = sqrt(vr*vr + vi*vi); + if(vm == 0){ + value->rValue = 0; + return(OK); + } + sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->SOI3senParmNo + here->SOI3sens_l); + si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->SOI3senParmNo + here->SOI3sens_l); + value->rValue = (vr * sr + vi * si)/vm; + } + return(OK); + case SOI3_W_SENS_PH: + if(ckt->CKTsenInfo && here->SOI3sens_w){ + vr = *(ckt->CKTrhsOld + select->iValue + 1); + vi = *(ckt->CKTirhsOld + select->iValue + 1); + vm = vr*vr + vi*vi; + if(vm == 0){ + value->rValue = 0; + return(OK); + } + sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->SOI3senParmNo + here->SOI3sens_l); + si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->SOI3senParmNo + here->SOI3sens_l); + value->rValue = (vr * si - vi * sr)/vm; + } + return(OK); + case SOI3_W_SENS_CPLX: + if(ckt->CKTsenInfo && here->SOI3sens_w){ + value->cValue.real= + *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ + here->SOI3senParmNo + here->SOI3sens_l); + value->cValue.imag= + *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ + here->SOI3senParmNo + here->SOI3sens_l); + } + return(OK); */ + +/* + case SOI3_IS : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = MALLOC(strlen(msg)+1); + errRtn = "SOI3ask.c"; + strcpy(errMsg,msg); + return(E_ASKCURRENT); + } else { + value->rValue = -here->SOI3id; + value->rValue -= here->SOI3ibd + here->SOI3ibs - + *(ckt->CKTstate0 + here->SOI3iqgfb); + if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && + !(ckt->CKTmode & MODETRANOP)) { + value->rValue -= *(ckt->CKTstate0 + here->SOI3iqgfb) + + *(ckt->CKTstate0 + here->SOI3iqgfd) + + *(ckt->CKTstate0 + here->SOI3iqgfs); + } + } + return(OK); + case SOI3_IB : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = MALLOC(strlen(msg)+1); + errRtn = "SOI3ask.c"; + strcpy(errMsg,msg); + return(E_ASKCURRENT); + } else { + value->rValue = here->SOI3ibd + here->SOI3ibs - + *(ckt->CKTstate0 + here->SOI3iqgfb); + } + return(OK); + case SOI3_IGF : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = MALLOC(strlen(msg)+1); + errRtn = "SOI3ask.c"; + strcpy(errMsg,msg); + return(E_ASKCURRENT); + } else if (ckt->CKTcurrentAnalysis & (DOING_DCOP | DOING_TRCV)) { + value->rValue = 0; + } else if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && + (ckt->CKTmode & MODETRANOP)) { + value->rValue = 0; + } else { + value->rValue = *(ckt->CKTstate0 + here->SOI3iqgfb) + + *(ckt->CKTstate0 + here->SOI3iqgfd) + *(ckt->CKTstate0 + + here->SOI3iqgfs); + } + return(OK); + case SOI3_IGB : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = MALLOC(strlen(msg)+1); + errRtn = "SOI3ask.c"; + strcpy(errMsg,msg); + return(E_ASKCURRENT); + } else if (ckt->CKTcurrentAnalysis & (DOING_DCOP | DOING_TRCV)) { + value->rValue = 0; + } else if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && + (ckt->CKTmode & MODETRANOP)) { + value->rValue = 0; + } else { + value->rValue = *(ckt->CKTstate0 + here->SOI3iqgfb) + + *(ckt->CKTstate0 + here->SOI3iqgfd) + *(ckt->CKTstate0 + + here->SOI3iqgfs); + } + return(OK); + case SOI3_POWER : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = MALLOC(strlen(msg)+1); + errRtn = "SOI3ask.c"; + strcpy(errMsg,msg); + return(E_ASKPOWER); + } else { + double temp; + + value->rValue = here->SOI3id * + *(ckt->CKTrhsOld + here->SOI3dNode); + value->rValue += ((here->SOI3ibd + here->SOI3ibs) - + *(ckt->CKTstate0 + here->SOI3iqgfb)) * + *(ckt->CKTrhsOld + here->SOI3bNode); + if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && + !(ckt->CKTmode & MODETRANOP)) { + value->rValue += (*(ckt->CKTstate0 + here->SOI3iqgfb) + + *(ckt->CKTstate0 + here->SOI3iqgfd) + + *(ckt->CKTstate0 + here->SOI3iqgfs)) * + *(ckt->CKTrhsOld + here->SOI3gfNode); + } + temp = -here->SOI3id; + temp -= here->SOI3ibd + here->SOI3ibs ; + if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && + !(ckt->CKTmode & MODETRANOP)) { + temp -= *(ckt->CKTstate0 + here->SOI3iqgfb) + + *(ckt->CKTstate0 + here->SOI3iqgfd) + + *(ckt->CKTstate0 + here->SOI3iqgfs); + } + value->rValue += temp * *(ckt->CKTrhsOld + here->SOI3sNode); + } + return(OK); +*/ + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} + diff --git a/src/spicelib/devices/soi3/soi3cap.c b/src/spicelib/devices/soi3/soi3cap.c new file mode 100644 index 000000000..351bb03d6 --- /dev/null +++ b/src/spicelib/devices/soi3/soi3cap.c @@ -0,0 +1,590 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#include "ngspice.h" +#include "cktdefs.h" +#include "suffix.h" +#include "soi3defs.h" +#include "trandefs.h" +#include "const.h" + + +void +SOI3cap(vgB,Phiplusvsb,gammaB, + paramargs, + Bfargs,alpha_args,psi_st0args, + vGTargs, + psi_sLargs,psi_s0args, + ldargs, + Qg,Qb,Qd,QgB, + cggf,cgd,cgs,cgdeltaT, + cbgf,cbd,cbs,cbdeltaT,cbgb, + cdgf,cdd,cds,cddeltaT, + cgbgb,cgbsb + ) + +double vgB,Phiplusvsb,gammaB; +double paramargs[10]; +double Bfargs[2],alpha_args[5]; +double psi_st0args[5]; +double vGTargs[5]; +double psi_sLargs[5],psi_s0args[5]; +double ldargs[5]; + +double *Qg,*Qb,*Qd,*QgB; +double *cggf,*cgd,*cgs,*cgdeltaT; +double *cbgf,*cbd,*cbs,*cbdeltaT,*cbgb; +double *cdgf,*cdd,*cds,*cddeltaT; +double *cgbgb,*cgbsb; + + +/****** Part 1 - declare local variables. ******/ + +{ +double WCox,WCob,L; +double gamma,eta_s,vt,delta,sigma,chiFB; +double Bf,pDBf_Dpsi_st0; +double alpha,Dalpha_Dvgfb,Dalpha_Dvdb,Dalpha_Dvsb,Dalpha_DdeltaT; +double Dpsi_st0_Dvgfb,Dpsi_st0_Dvdb,Dpsi_st0_Dvsb,Dpsi_st0_DdeltaT; +double vGT,DvGT_Dvgfb,DvGT_Dvdb,DvGT_Dvsb,DvGT_DdeltaT; +double psi_sL,Dpsi_sL_Dvgfb,Dpsi_sL_Dvdb,Dpsi_sL_Dvsb,Dpsi_sL_DdeltaT; +double psi_s0,Dpsi_s0_Dvgfb,Dpsi_s0_Dvdb,Dpsi_s0_Dvsb,Dpsi_s0_DdeltaT; +double ld,Dld_Dvgfb,Dld_Dvdb,Dld_Dvsb,Dld_DdeltaT; + +double Lprime,Fc; +double Qbprime,Qcprime,Qdprime,Qgprime,Qb2prime,Qc2prime,Qd2prime,Qg2prime; +double Dlimc,Dlimd; +double Vqd,Vqs; +double F,F2; +double cq,dq; +double dercq,derdq; +double sigmaC,Eqc,Eqd; +double DVqs_Dvgfb,DVqs_Dvdb,DVqs_Dvsb,DVqs_DdeltaT; +double DF_Dvgfb,DF_Dvdb,DF_Dvsb,DF_DdeltaT; +double ccgf,ccd,ccs,ccdeltaT; + +double A0B,EA0B,tmpsb; +double Vgmax0B,VgBx0,EBmax0,tmpmax0,tmpmaxsb; +double VgBy0,EBy0,tmpmin0; +double SgB0; + +double vg,vgacc,Egacc,tmpacc,Qacc; +double csf; + +/****** Part 2 - extract variables passed from soi3load(), which ******/ +/****** have been passed to soi3cap() in *arg arrays. ******/ + +WCox = paramargs[0]; +L = paramargs[1]; +gamma = paramargs[2]; +eta_s = paramargs[3]; +vt = paramargs[4]; +delta = paramargs[5]; +WCob = paramargs[6]; +sigma = paramargs[7]; +chiFB = paramargs[8]; +csf = paramargs[9]; +Bf = Bfargs[0]; +pDBf_Dpsi_st0 = Bfargs[1]; +alpha = alpha_args[0]; +Dalpha_Dvgfb = alpha_args[1]; +Dalpha_Dvdb = alpha_args[2]; +Dalpha_Dvsb = alpha_args[3]; +Dalpha_DdeltaT = alpha_args[4]; + +Dpsi_st0_Dvgfb = psi_st0args[1]; +Dpsi_st0_Dvdb = psi_st0args[2]; +Dpsi_st0_Dvsb = psi_st0args[3]; +Dpsi_st0_DdeltaT = psi_st0args[4]; + +vGT = vGTargs[0]; +DvGT_Dvgfb = vGTargs[1]; +DvGT_Dvdb = vGTargs[2]; +DvGT_Dvsb = vGTargs[3]; +DvGT_DdeltaT = vGTargs[4]; + +psi_sL = psi_sLargs[0]; +Dpsi_sL_Dvgfb = psi_sLargs[1]; +Dpsi_sL_Dvdb = psi_sLargs[2]; +Dpsi_sL_Dvsb = psi_sLargs[3]; +Dpsi_sL_DdeltaT = psi_sLargs[4]; +psi_s0 = psi_s0args[0]; +Dpsi_s0_Dvgfb = psi_s0args[1]; +Dpsi_s0_Dvdb = psi_s0args[2]; +Dpsi_s0_Dvsb = psi_s0args[3]; +Dpsi_s0_DdeltaT = psi_s0args[4]; +ld = ldargs[0]; +Dld_Dvgfb = ldargs[1]; +Dld_Dvdb = ldargs[2]; +Dld_Dvsb = ldargs[3]; +Dld_DdeltaT = ldargs[4]; + + +/****** Part 3 - define some important quantities. ******/ + +sigmaC = 1E-8; + +Vqd = (vGT - alpha*psi_sL); /* This is -qd/Cof */ +Vqs = (vGT - alpha*psi_s0); /* This is -qs/Cof */ +if (Vqs<=0) { /* deep subthreshold contingency */ + F = 1; +} else { + F = Vqd/Vqs; + if (F<0) { /* physically impossible situation */ + F=0; + } +} +F2 = F*F; + +Fc = 1 + ld/L; +Lprime = L/Fc; + + +/****** Part 4 - calculate normalised (see note below) terminal ******/ +/****** charge expressions for the GCA region. ******/ + +/* JimB - important note */ +/* The charge expressions Qcprime, Qd2prime etc in this file are not charges */ +/* but voltages! Each expression is equal to the derived expression for the */ +/* total charge in each region, but divided by a factor WL'Cof. This is */ +/* compensated for later on. */ + +/* Channel charge Qc1 */ +cq = (F*F + F + 1)/(F+1); +Qcprime = -2*Vqs*cq/3; + +if ((-Qcprime/sigmaC) MAX_EXP_ARG) { + vgacc = vg; + tmpacc = 1; +} else { + Egacc = exp(-vg/vt); + vgacc = -vt*log(1+Egacc); + tmpacc = Egacc/(1+Egacc); +} +Qacc = -WCox*L*vgacc; + +/* Now work out GCA region charges */ + +*Qb = WCox*Lprime*Qbprime + Qacc; + +*Qd = WCox*Lprime*Qdprime; + +*Qg = WCox*Lprime*Qgprime - Qacc; + + +/****** Part 7 - calculate normalised (see note below) terminal ******/ +/****** charge expressions for the saturated drain region. ******/ + +Qc2prime = -Vqd; + +/* Basic expression for the intrinsic body charge in the saturation region is */ +/* modified by csf, to reflect the fact that the body charge will be shared */ +/* between the gate and the drain/body depletion region. This factor must be */ +/* between 0 and 1, since it represents the fraction of ld over which qb is */ +/* integrated to give Qb2. */ +Qb2prime = -gamma*csf*(Bf + delta*psi_sL); + +Qd2prime = 0.5*Qc2prime; +/* JimB - 9/1/99. Re-partition drain region charge */ +/* Qd2prime = Qc2prime; */ + +Qg2prime = -Qc2prime-Qb2prime; + +*Qb += WCox*ld*Qb2prime; +*Qd += WCox*ld*Qd2prime; +*Qg += WCox*ld*Qg2prime; + + +/****** Part 8 - calculate full capacitance expressions, accounting ******/ +/****** for both GCA and drain region contributions. As explained ******/ +/****** in part 5, *cbgf, *cbd etc only derivatives of GCA charge ******/ +/****** expression w.r.t. Vx. Now need to include Lprime/ld ******/ +/****** dependence on Vx as well. ******/ + +*cbgf = WCox*(Lprime*(*cbgf) - ld*csf*(pDBf_Dpsi_st0*Dpsi_st0_Dvgfb + delta*Dpsi_sL_Dvgfb + + (psi_sL*Dalpha_Dvgfb/gamma)) + + (Qb2prime - Qbprime/(Fc*Fc))*Dld_Dvgfb + ); +*cbd = WCox*(Lprime*(*cbd) - ld*csf*(pDBf_Dpsi_st0*Dpsi_st0_Dvdb + delta*Dpsi_sL_Dvdb + + (psi_sL*Dalpha_Dvdb/gamma)) + + (Qb2prime - Qbprime/(Fc*Fc))*Dld_Dvdb + ); +*cbs = WCox*(Lprime*(*cbs) - ld*csf*(pDBf_Dpsi_st0*Dpsi_st0_Dvsb + delta*Dpsi_sL_Dvsb + + (psi_sL*Dalpha_Dvsb/gamma)) + + (Qb2prime - Qbprime/(Fc*Fc))*Dld_Dvsb + ); +*cbdeltaT = WCox*(Lprime*(*cbdeltaT) - ld*csf*(pDBf_Dpsi_st0*Dpsi_st0_DdeltaT + delta*Dpsi_sL_DdeltaT + + (psi_sL*Dalpha_DdeltaT/gamma)) + + (Qb2prime - Qbprime/(Fc*Fc))*Dld_DdeltaT + ); + + +ccgf = WCox*(Lprime*(ccgf) - ld*(DvGT_Dvgfb - alpha*Dpsi_sL_Dvgfb - psi_sL*Dalpha_Dvgfb) + + (Qc2prime - Qcprime/(Fc*Fc))*Dld_Dvgfb + ); +ccd = WCox*(Lprime*(ccd) - ld*(DvGT_Dvdb - alpha*Dpsi_sL_Dvdb - psi_sL*Dalpha_Dvdb) + + (Qc2prime - Qcprime/(Fc*Fc))*Dld_Dvdb + ); +ccs = WCox*(Lprime*(ccs) - ld*(DvGT_Dvsb - alpha*Dpsi_sL_Dvsb - psi_sL*Dalpha_Dvsb) + + (Qc2prime - Qcprime/(Fc*Fc))*Dld_Dvsb + ); +ccdeltaT = WCox*(Lprime*(ccdeltaT) - + ld*(DvGT_DdeltaT - alpha*Dpsi_sL_DdeltaT - psi_sL*Dalpha_DdeltaT) + + (Qc2prime - Qcprime/(Fc*Fc))*Dld_DdeltaT + ); + + +/* JimB - 9/1/99. Re-partition drain region charge */ + +/* +*cdgf = WCox*(Lprime*(*cdgf) - ld*(DvGT_Dvgfb - alpha*Dpsi_sL_Dvgfb - psi_sL*Dalpha_Dvgfb) + + (Qd2prime - Qdprime/(Fc*Fc))*Dld_Dvgfb + ); +*cdd = WCox*(Lprime*(*cdd) - ld*(DvGT_Dvdb - alpha*Dpsi_sL_Dvdb - psi_sL*Dalpha_Dvdb) + + (Qd2prime - Qdprime/(Fc*Fc))*Dld_Dvdb + ); +*cds = WCox*(Lprime*(*cds) - ld*(DvGT_Dvsb - alpha*Dpsi_sL_Dvsb - psi_sL*Dalpha_Dvsb) + + (Qd2prime - Qdprime/(Fc*Fc))*Dld_Dvsb + ); +*cddeltaT = WCox*(Lprime*(*cddeltaT) - ld*(DvGT_DdeltaT - + alpha*Dpsi_sL_DdeltaT - psi_sL*Dalpha_DdeltaT) + + (Qd2prime - Qdprime/(Fc*Fc))*Dld_DdeltaT + ); +*/ + +*cdgf = WCox*(Lprime*(*cdgf) - 0.5*ld*(DvGT_Dvgfb - alpha*Dpsi_sL_Dvgfb - psi_sL*Dalpha_Dvgfb) + + (Qd2prime - Qdprime/(Fc*Fc))*Dld_Dvgfb + ); +*cdd = WCox*(Lprime*(*cdd) - 0.5*ld*(DvGT_Dvdb - alpha*Dpsi_sL_Dvdb - psi_sL*Dalpha_Dvdb) + + (Qd2prime - Qdprime/(Fc*Fc))*Dld_Dvdb + ); +*cds = WCox*(Lprime*(*cds) - 0.5*ld*(DvGT_Dvsb - alpha*Dpsi_sL_Dvsb - psi_sL*Dalpha_Dvsb) + + (Qd2prime - Qdprime/(Fc*Fc))*Dld_Dvsb + ); +*cddeltaT = WCox*(Lprime*(*cddeltaT) - 0.5*ld*(DvGT_DdeltaT - + alpha*Dpsi_sL_DdeltaT - psi_sL*Dalpha_DdeltaT) + + (Qd2prime - Qdprime/(Fc*Fc))*Dld_DdeltaT + ); + + +/****** Part 9 - Finally, include accumulation charge derivatives. ******/ + +/* Now include accumulation charge derivs */ + +*cbgf += -WCox*L*tmpacc; +*cbd += -WCox*L*tmpacc*sigma; +*cbs += -WCox*L*tmpacc*(-sigma); +*cbdeltaT += -WCox*L*tmpacc*chiFB; + +*cggf = -(ccgf + *cbgf); +*cgd = -(ccd + *cbd); +*cgs = -(ccs + *cbs); +*cgdeltaT = -(ccdeltaT + *cbdeltaT); + + +/****** Part 10 - Back gate stuff - doesn't work, so commented out. ******/ + +/* front gate stuff is self consistent by itself, now add in back gate stuff + we're not too interested in EXACT back gate behaviour, so this is quite a + rough model. + But even this causes convergence problems in transient - so leave it out + for now. Scope for further work. +*/ +/* +if (Phiplusvsb > vt*MAX_EXP_ARG) { + A0B = Phiplusvsb; + tmpsb = 1; +} else { + EA0B = exp(Phiplusvsb/vt); + A0B = vt*log(1+EA0B); + tmpsb = EA0B/(1+EA0B); +} + +Vgmax0B = A0B + gammaB*sqrt(A0B); + +if ((Vgmax0B-vgB)>vt*MAX_EXP_ARG) { + VgBx0=vgB; + tmpmax0 = 1; + tmpmaxsb = 0; +} else { + EBmax0 = exp((Vgmax0B - vgB)/vt); + VgBx0=Vgmax0B - vt*log(1+EBmax0); + tmpmax0 = EBmax0/(1+EBmax0); + tmpmaxsb = 1/(1+EBmax0); +} + +if (VgBx0>vt*MAX_EXP_ARG) { + VgBy0 = VgBx0; + tmpmin0 = 1; +} else { + EBy0 = exp(VgBx0/vt); + VgBy0 = vt*log(1+EBy0); + tmpmin0 = EBy0/(1+EBy0); +} + +SgB0 = sqrt(gammaB*gammaB + 4*VgBy0); + +*QgB = -WCob*L*gammaB*0.5*(gammaB-SgB0); +*Qb -= *QgB; + +*cgbgb = (WCob*L*gammaB/SgB0)*tmpmin0*tmpmax0; +*cgbsb = (WCob*L*gammaB/SgB0)*tmpmin0*tmpmaxsb*(1+0.5*gammaB/sqrt(A0B))*tmpsb; + +*cbgb = -(*cgbgb); +*cbs -= *cgbsb; +*/ + +*QgB = 0; +*cbgb = 0; +*cgbgb = 0; +*cgbsb = 0; + +} + +void +SOI3capEval(ckt, + Frontcapargs, + Backcapargs, + cgfgf,cgfd,cgfs,cgfdeltaT, + cdgf,cdd,cds,cddeltaT, + csgf,csd,css,csdeltaT, + cbgf,cbd,cbs,cbdeltaT,cbgb, + cgbgb,cgbsb, + gcgfgf,gcgfd,gcgfs,gcgfdeltaT, + gcdgf,gcdd,gcds,gcddeltaT, + gcsgf,gcsd,gcss,gcsdeltaT, + gcbgf,gcbd,gcbs,gcbdeltaT,gcbgb, + gcgbgb,gcgbsb,gcgbdb, + gcgbs0,gcgbd0, + qgatef,qbody,qdrn,qsrc,qgateb) + +register CKTcircuit *ckt; +double Frontcapargs[6]; +double Backcapargs[6]; + + +double cgfgf,cgfd,cgfs,cgfdeltaT; +double cdgf,cdd,cds,cddeltaT; +double csgf,csd,css,csdeltaT; +double cbgf,cbd,cbs,cbdeltaT,cbgb; +double cgbgb,cgbsb; + +double *gcgfgf,*gcgfd,*gcgfs,*gcgfdeltaT; +double *gcdgf,*gcdd,*gcds,*gcddeltaT; +double *gcsgf,*gcsd,*gcss,*gcsdeltaT; +double *gcbgf,*gcbd,*gcbs,*gcbdeltaT,*gcbgb; +double *gcgbgb,*gcgbsb,*gcgbdb; +double *gcgbs0,*gcgbd0; + +double *qgatef; +double *qbody; +double *qdrn; +double *qsrc; +double *qgateb; + +{ +double vgfd,vgfs,vgfb; +double vgbd,vgbs,vgbb; +double cgd0,cgs0,cgb0; +double cgbd0,cgbs0,cgbb0; +double ag0; +double qgd,qgs,qgb; +double qgb_d,qgb_s,qgb_b; + +cgd0 = Frontcapargs[0]; +cgs0 = Frontcapargs[1]; +cgb0 = Frontcapargs[2]; +vgfd = Frontcapargs[3]; +vgfs = Frontcapargs[4]; +vgfb = Frontcapargs[5]; + +cgbd0 = Backcapargs[0]; +cgbs0 = Backcapargs[1]; +cgbb0 = Backcapargs[2]; +vgbd = Backcapargs[3]; +vgbs = Backcapargs[4]; +vgbb = Backcapargs[5]; + +/* stuff below includes overlap caps' conductances */ +ag0 = ckt->CKTag[0]; + +*gcgfgf = (cgfgf + cgd0 + cgs0 + cgb0) * ag0; +*gcgfd = (cgfd - cgd0) * ag0; +*gcgfs = (cgfs - cgs0) * ag0; +*gcgfdeltaT = cgfdeltaT * ag0; + +*gcdgf = (cdgf - cgd0) * ag0; +*gcdd = (cdd + cgd0) * ag0; +*gcds = cds * ag0; +*gcddeltaT = cddeltaT * ag0; + +*gcsgf = (csgf - cgs0) * ag0; +*gcsd = csd * ag0; +*gcss = (css + cgs0) * ag0; +*gcsdeltaT = csdeltaT * ag0; + +*gcbgf = (cbgf - cgb0) * ag0; +*gcbd = cbd * ag0; +*gcbs = cbs * ag0; +*gcbdeltaT = cbdeltaT * ag0; + +*gcbgb = cbgb * ag0; +/* +*gcbgb = (cbgb - cgbb0) * ag0; + + +*gcgbgb = (cgbgb + cgbb0 + cgbd0 + cgbs0) * ag0; +*gcgbsb = (cgbsb - cgbs0) * ag0; +*gcgbdb = -cgbd0 * ag0; + +*gcgbd0 = cgbd0 * ag0; +*gcgbs0 = cgbs0 * ag0; +*/ + +*gcgbgb = cgbgb * ag0; +*gcgbsb = cgbsb * ag0; +*gcgbdb = 0; + +*gcgbd0 = 0; +*gcgbs0 = 0; + +qgd = cgd0 * vgfd; +qgs = cgs0 * vgfs; +qgb = cgb0 * vgfb; + +/* +qgb_d = cgbd0 * vgbd; +qgb_s = cgbs0 * vgbs; +qgb_b = cgbb0 * vgbb; +*/ +qgb_d = 0; +qgb_s = 0; +qgb_b = 0; + +*qgatef = *qgatef + qgd + qgs + qgb; +*qbody = *qbody - qgb - qgb_b; +*qdrn = *qdrn - qgd - qgb_d; +*qgateb = *qgateb + qgb_d + qgb_s + qgb_b; +*qsrc = -(*qgatef + *qbody + *qdrn + *qgateb); +} diff --git a/src/spicelib/devices/soi3/soi3conv.c b/src/spicelib/devices/soi3/soi3conv.c new file mode 100644 index 000000000..156db8af8 --- /dev/null +++ b/src/spicelib/devices/soi3/soi3conv.c @@ -0,0 +1,217 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "soi3defs.h" +#include "sperror.h" +#include "suffix.h" + + +int +SOI3convTest(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + SOI3model *model = (SOI3model*)inModel; + SOI3instance *here; + double delvbs; + double delvbd; + double delvgfs; + double delvgbs; + double delvds; + double delvgfd; + double delvgbd; + double deldeltaT; + double ibhat; + double idhat; + double iPthat; + double vbs; + double vbd; + double vgfs; + double vgbs; + double vds; + double deltaT; + double vgfd; + double vgbd; + double vgfdo; + double vgbdo; + double tol; + FILE *fp,*fopen(); + + for( ; model != NULL; model = model->SOI3nextModel) { + for(here = model->SOI3instances; here!= NULL; + here = here->SOI3nextInstance) { + + vbs = model->SOI3type * ( + *(ckt->CKTrhs+here->SOI3bNode) - + *(ckt->CKTrhs+here->SOI3sNodePrime)); + vgfs = model->SOI3type * ( + *(ckt->CKTrhs+here->SOI3gfNode) - + *(ckt->CKTrhs+here->SOI3sNodePrime)); + vgbs = model->SOI3type * ( + *(ckt->CKTrhs+here->SOI3gbNode) - + *(ckt->CKTrhs+here->SOI3sNodePrime)); + vds = model->SOI3type * ( + *(ckt->CKTrhs+here->SOI3dNodePrime) - + *(ckt->CKTrhs+here->SOI3sNodePrime)); + deltaT = MAX(0,*(ckt->CKTrhs+here->SOI3toutNode)); + /* voltage deltaT is V(tout) wrt thermal ground */ + vbd=vbs-vds; + vgfd=vgfs-vds; + vgbd=vgbs-vds; + vgfdo = *(ckt->CKTstate0 + here->SOI3vgfs) - + *(ckt->CKTstate0 + here->SOI3vds); + vgbdo = *(ckt->CKTstate0 + here->SOI3vgbs) - + *(ckt->CKTstate0 + here->SOI3vds); + delvbs = vbs - *(ckt->CKTstate0 + here->SOI3vbs); + delvbd = vbd - *(ckt->CKTstate0 + here->SOI3vbd); + delvgfs = vgfs - *(ckt->CKTstate0 + here->SOI3vgfs); + delvgbs = vgbs - *(ckt->CKTstate0 + here->SOI3vgbs); + delvds = vds - *(ckt->CKTstate0 + here->SOI3vds); + delvgfd = vgfd-vgfdo; + delvgbd = vgbd-vgbdo; + deldeltaT = deltaT - *(ckt->CKTstate0 + here->SOI3deltaT); + + /* these are needed for convergence testing */ + + if (here->SOI3mode >= 0) { /* normal */ + idhat= + here->SOI3id- + here->SOI3gbd * delvbd - + here->SOI3gbdT * deldeltaT + /* for -ibd bit of id */ + (here->SOI3gmbs + + here->SOI3gMmbs) * delvbs + + (here->SOI3gmf + + here->SOI3gMmf) * delvgfs + + (here->SOI3gmb + + here->SOI3gMmb) * delvgbs + + (here->SOI3gds + + here->SOI3gMd) * delvds + + (here->SOI3gt + + here->SOI3gMdeltaT) * deldeltaT + + here->SOI3gBJTdb_bs * delvbs + + here->SOI3gBJTdb_deltaT * deldeltaT; + ibhat= + here->SOI3ibs + + here->SOI3ibd + + here->SOI3gbd * delvbd + + here->SOI3gbdT * deldeltaT + + here->SOI3gbs * delvbs + + here->SOI3gbsT * deldeltaT - + here->SOI3iMdb - + here->SOI3gMmbs * delvbs - + (here->SOI3gMmf)* delvgfs - + (here->SOI3gMmb)* delvgbs - + here->SOI3gMd * delvds - + here->SOI3gMdeltaT * deldeltaT - + here->SOI3iBJTsb - + here->SOI3gBJTsb_bd * delvbd - + here->SOI3gBJTsb_deltaT * deldeltaT - + here->SOI3iBJTdb - + here->SOI3gBJTdb_bs * delvbs - + here->SOI3gBJTdb_deltaT * deldeltaT; + } else { /* A over T */ + idhat= + here->SOI3id - + ( here->SOI3gbd + + here->SOI3gmbs) * delvbd - + (here->SOI3gmf) * delvgfd - + (here->SOI3gmb) * delvgbd + + (here->SOI3gds) * delvds - + (here->SOI3gt + + here->SOI3gbdT) * deldeltaT + + here->SOI3gBJTdb_bs * delvbs + + here->SOI3gBJTdb_deltaT * deldeltaT; + ibhat= + here->SOI3ibs + + here->SOI3ibd + + here->SOI3gbd * delvbd + + here->SOI3gbdT * deldeltaT + + here->SOI3gbs * delvbs + + here->SOI3gbsT * deldeltaT - + here->SOI3iMsb - + here->SOI3gMmbs * delvbd - + here->SOI3gMmf * delvgfd - + here->SOI3gMmb * delvgbd + + here->SOI3gMd * delvds - /* gMd should go with vsd */ + here->SOI3gMdeltaT * deldeltaT - + here->SOI3iBJTsb - + here->SOI3gBJTsb_bd * delvbd - + here->SOI3gBJTsb_deltaT * deldeltaT - + here->SOI3iBJTdb - + here->SOI3gBJTdb_bs * delvbs - + here->SOI3gBJTdb_deltaT * deldeltaT; + } + iPthat = + here->SOI3iPt + + here->SOI3gPmbs * delvbs + + here->SOI3gPmf * delvgfs + + here->SOI3gPmb * delvgbs + + here->SOI3gPds * delvds * here->SOI3mode + + here->SOI3gPdT * deldeltaT; + /* + * check convergence + */ + tol=ckt->CKTreltol*MAX(fabs(idhat),fabs(here->SOI3id))+ + ckt->CKTabstol; + if (fabs(idhat-here->SOI3id) >= tol) { + ckt->CKTnoncon++; + /* JimB - Remove line containing ckt->CKTtroubleElt for the */ + /* Simetrix DLL version - element removed from ckt structure */ + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue, we haven't converged */ + } else { + tol=ckt->CKTreltol* + MAX(fabs(ibhat),fabs(here->SOI3ibs+here->SOI3ibd + - here->SOI3iMdb - here->SOI3iMsb + - here->SOI3iBJTdb - here->SOI3iBJTsb))+ + ckt->CKTabstol; + if (fabs(ibhat-(here->SOI3ibs+here->SOI3ibd + - here->SOI3iMdb - here->SOI3iMsb + - here->SOI3iBJTdb - here->SOI3iBJTsb)) > tol) { + ckt->CKTnoncon++; + /* JimB - Remove line containing ckt->CKTtroubleElt for the */ + /* Simetrix DLL version - element removed from ckt structure */ + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue,we haven't converged*/ + } else { + tol=ckt->CKTreltol*MAX(fabs(iPthat), + fabs(here->SOI3iPt))+ckt->CKTabstol; + if (fabs(iPthat-here->SOI3iPt) >= tol) { + ckt->CKTnoncon++; + /* JimB - Remove line containing ckt->CKTtroubleElt for the */ + /* Simetrix DLL version - element removed from ckt structure */ + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue,we haven't converged*/ + } + } + } +/* debug stuff */ +/* fp=fopen("level3.dat","a"); + fprintf(fp,"%2.3f %2.3f %.15e %.15e %.15e %.15e %.15e %.15e %.15e\n", + vgfs-vbs,vds,ckt->CKTtime,here->SOI3debug1,here->SOI3debug2,here->SOI3debug3, + here->SOI3debug4,here->SOI3debug5,here->SOI3debug6); + fclose(fp); +*/ + } + } + return(OK); +} diff --git a/src/spicelib/devices/soi3/soi3defs.h b/src/spicelib/devices/soi3/soi3defs.h new file mode 100644 index 000000000..ef349d2d1 --- /dev/null +++ b/src/spicelib/devices/soi3/soi3defs.h @@ -0,0 +1,800 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +#ifndef SOI3 +#define SOI3 + +#include "ifsim.h" +#include "cktdefs.h" +#include "gendefs.h" +#include "complex.h" +#include "noisedef.h" + + +/* declarations for SOI3 MOSFETs */ + +/* information needed for each instance */ + +typedef struct sSOI3instance { + + + struct sSOI3model *sSOI3modPtr; /* backpointer to model */ + struct sSOI3instance *SOI3nextInstance; /* pointer to next instance of + *current model*/ + IFuid SOI3name; /* pointer to character string naming this instance */ + int SOI3owner; /* number of owner process */ + int SOI3states; /* index into state table for this device */ + + + int SOI3dNode; /* number of the drain node of the mosfet */ + int SOI3gfNode; /* number of the front gate node of the mosfet */ + int SOI3sNode; /* number of the source node of the mosfet */ + int SOI3gbNode; /* number of the back gate node of the mosfet */ + int SOI3bNode; /* number of the bulk node of the mosfet */ + int SOI3toutNode; /* number of thermal output node (tout) */ + + int SOI3branch; /* branch number for zero voltage source if no thermal */ + + int SOI3dNodePrime; /* number of the internal drain node of the mosfet */ + int SOI3sNodePrime; /* number of the internal source node of the mosfet */ + + + + int SOI3tout1Node; /* first internal thermal node */ + int SOI3tout2Node; /* second internal thermal node */ + int SOI3tout3Node; /* third internal thermal node */ + int SOI3tout4Node; /* fourth internal thermal node */ + + double SOI3l; /* the length of the channel region */ + double SOI3w; /* the width of the channel region */ + + double SOI3drainSquares; /* the length of the drain in squares */ + double SOI3sourceSquares; /* the length of the source in squares */ + + double SOI3sourceConductance; /*conductance of source(or 0):set in setup*/ + double SOI3drainConductance; /*conductance of drain(or 0):set in setup*/ + double SOI3temp; /* operating temperature of this instance */ + double SOI3rt; /* Thermal resistance */ + double SOI3ct; /* Thermal capacitance */ + double SOI3rt1; /* 1st internal Thermal resistance */ + double SOI3ct1; /* 1st internal Thermal capacitance */ + double SOI3rt2; /* 2nd internal Thermal resistance */ + double SOI3ct2; /* 2nd internal Thermal capacitance */ + double SOI3rt3; /* 3rd internal Thermal resistance */ + double SOI3ct3; /* 3rd internal Thermal capacitance */ + double SOI3rt4; /* 4th internal Thermal resistance */ + double SOI3ct4; /* 4th internal Thermal capacitance */ + + + double SOI3tTransconductance; /* temperature corrected transconductance (KP param) */ + double SOI3ueff; /* passed on to noise model */ + double SOI3tSurfMob; /* temperature corrected surface mobility */ + double SOI3tPhi; /* temperature corrected Phi */ + double SOI3tVto; /* temperature corrected Vto */ + double SOI3tVfbF; /* temperature corrected Vfb */ + double SOI3tVfbB; /* temperature corrected Vfb (back gate) */ + double SOI3tSatCur; /* temperature corrected jnct saturation Cur. */ + double SOI3tSatCur1; /* temperature corrected jnct saturation Cur. */ + double SOI3tSatCurDens; /* temperature corrected jnct saturation Cur. density */ + double SOI3tSatCurDens1; /* temperature corrected jnct saturation Cur. density */ + double SOI3tCbd; /* temperature corrected B-D Capacitance */ + double SOI3tCbs; /* temperature corrected B-S Capacitance */ + double SOI3tCjsw; /* temperature corrected Bulk side Capacitance */ + double SOI3tBulkPot; /* temperature corrected Bulk potential */ + double SOI3tDepCap; /* temperature adjusted transition point in */ + /* the curve matching Fc * Vj */ + double SOI3tVbi; /* temperature adjusted Vbi diode built-in voltage */ + + double SOI3icVBS; /* initial condition B-S voltage */ + double SOI3icVDS; /* initial condition D-S voltage */ + double SOI3icVGFS; /* initial condition GF-S voltage */ + double SOI3icVGBS; /* initial condition GB-S voltage */ + double SOI3von; + double SOI3vdsat; + double SOI3sourceVcrit; /* Vcrit for pos. vds */ + double SOI3drainVcrit; /* Vcrit for pos. vds */ + double SOI3id; /* drain current */ + double SOI3ibs; /* bulk source current */ + double SOI3ibd; /* bulk drain current */ + double SOI3iMdb; /* drain bulk impact ionisation current */ + double SOI3iMsb; /* source bulk impact ionisation cur. (rev mode) */ + double SOI3iPt; /* heat 'current' in thermal circuit */ + double SOI3gmbs; + double SOI3gmf; + double SOI3gmb; + double SOI3gds; + double SOI3gt; /* change of channel current wrt deltaT */ + double SOI3gdsnotherm; /* gds0 at elevated temp - ac use only) */ + double SOI3gMmbs; + double SOI3gMmf; + double SOI3gMmb; + double SOI3gMd; + double SOI3gMdeltaT; + double SOI3iBJTdb; + double SOI3gBJTdb_bs; + double SOI3gBJTdb_deltaT; + double SOI3iBJTsb; + double SOI3gBJTsb_bd; + double SOI3gBJTsb_deltaT; + double SOI3gPmf; /* change of Pt wrt vgfs */ + double SOI3gPmb; /* change of Pt wrt vgbs */ + double SOI3gPmbs; /* change of Pt wrt vbs */ + double SOI3gPds; /* change of Pt wrt vds */ + double SOI3gPdT; /* change of Pt wrt deltaT */ + double SOI3gbd; /* for body drain current */ + double SOI3gbdT; /* for body drain current */ + double SOI3gbs; /* for body source current */ + double SOI3gbsT; /* for body source current */ + double SOI3capbd; + double SOI3capbs; + double SOI3Cbd; + double SOI3Cbs; + double SOI3f2d; + double SOI3f3d; + double SOI3f4d; + double SOI3f2s; + double SOI3f3s; + double SOI3f4s; + double SOI3dDT_dVds; /* sm-sig gT term */ + double SOI3dId_dDT; /* sm-sig source term */ +/*debug stuff*/ + double SOI3debug1; + double SOI3debug2; + double SOI3debug3; + double SOI3debug4; + double SOI3debug5; + double SOI3debug6; +/* extra stuff for newer model - msll Jan96 */ + +/* + * naming convention: + * x = vgs + * y = vbs + * z = vds + * cdr = cdrain + */ + int SOI3mode; /* device mode : 1 = normal, -1 = inverse */ + int SOI3backstate; /* indicates charge condition of back surface */ + int SOI3numThermalNodes; /* Number of thermal nodes required */ + + unsigned SOI3off:1; /* non-zero to indicate device is off for dc analysis*/ + unsigned SOI3tempGiven :1; /* instance temperature specified */ + unsigned SOI3lGiven :1; + unsigned SOI3wGiven :1; + unsigned SOI3drainSquaresGiven :1; + unsigned SOI3sourceSquaresGiven :1; + unsigned SOI3dNodePrimeSet :1; + unsigned SOI3sNodePrimeSet :1; + unsigned SOI3icVBSGiven :1; + unsigned SOI3icVDSGiven :1; + unsigned SOI3icVGFSGiven:1; + unsigned SOI3icVGBSGiven:1; + unsigned SOI3rtGiven:1; + unsigned SOI3ctGiven:1; + unsigned SOI3rt1Given:1; + unsigned SOI3ct1Given:1; + unsigned SOI3rt2Given:1; + unsigned SOI3ct2Given:1; + unsigned SOI3rt3Given:1; + unsigned SOI3ct3Given:1; + unsigned SOI3rt4Given:1; + unsigned SOI3ct4Given:1; + unsigned SOI3vonGiven :1; + unsigned SOI3vdsatGiven :1; + unsigned SOI3modeGiven :1; + + + double *SOI3D_dPtr; /* pointer to sparse matrix element at + * (Drain node,drain node) */ + double *SOI3GF_gfPtr; /* pointer to sparse matrix element at + * (front gate node,front gate node) */ + double *SOI3S_sPtr; /* pointer to sparse matrix element at + * (source node,source node) */ + double *SOI3B_bPtr; /* pointer to sparse matrix element at + * (bulk node,bulk node) */ + double *SOI3GB_gbPtr; /* pointer to sparse matrix element at + * (back gate node,back gate node) */ + double *SOI3DP_dpPtr; /* pointer to sparse matrix element at + * (drain prime node,drain prime node) */ + double *SOI3SP_spPtr; /* pointer to sparse matrix element at + * (source prime node,source prime node) */ + double *SOI3D_dpPtr; /* pointer to sparse matrix element at + * (drain node,drain prime node) */ + double *SOI3GF_bPtr; /* pointer to sparse matrix element at + * (front gate node,bulk node) */ + double *SOI3GB_bPtr; /* pointer to sparse matrix element at + * (back gate node,bulk node) */ + double *SOI3GF_dpPtr; /* pointer to sparse matrix element at + * (front gate node,drain prime node) */ + double *SOI3GB_dpPtr; /* pointer to sparse matrix element at + * (back gate node,drain prime node) */ + double *SOI3GF_spPtr; /* pointer to sparse matrix element at + * (front gate node,source prime node) */ + double *SOI3GB_spPtr; /* pointer to sparse matrix element at + * (back gate node,source prime node) */ + double *SOI3S_spPtr; /* pointer to sparse matrix element at + * (source node,source prime node) */ + double *SOI3B_dpPtr; /* pointer to sparse matrix element at + * (bulk node,drain prime node) */ + double *SOI3B_spPtr; /* pointer to sparse matrix element at + * (bulk node,source prime node) */ + double *SOI3DP_spPtr; /* pointer to sparse matrix element at + * (drain prime node,source prime node) */ + double *SOI3DP_dPtr; /* pointer to sparse matrix element at + * (drain prime node,drain node) */ + double *SOI3B_gfPtr; /* pointer to sparse matrix element at + * (bulk node,front gate node) */ + double *SOI3B_gbPtr; /* pointer to sparse matrix element at + * (bulk node,back gate node) */ + double *SOI3DP_gfPtr; /* pointer to sparse matrix element at + * (drain prime node,front gate node) */ + double *SOI3DP_gbPtr; /* pointer to sparse matrix element at + * (drain prime node,back gate node) */ + double *SOI3SP_gfPtr; /* pointer to sparse matrix element at + * (source prime node,front gate node) */ + double *SOI3SP_gbPtr; /* pointer to sparse matrix element at + * (source prime node,back gate node) */ + double *SOI3SP_sPtr; /* pointer to sparse matrix element at + * (source prime node,source node) */ + double *SOI3DP_bPtr; /* pointer to sparse matrix element at + * (drain prime node,bulk node) */ + double *SOI3SP_bPtr; /* pointer to sparse matrix element at + * (source prime node,bulk node) */ + double *SOI3SP_dpPtr; /* pointer to sparse matrix element at + * (source prime node,drain prime node) */ + +/** Now for Thermal Node **/ + + double *SOI3TOUT_toutPtr; + double *SOI3TOUT_dpPtr; + double *SOI3TOUT_gfPtr; + double *SOI3TOUT_gbPtr; + double *SOI3TOUT_bPtr; + double *SOI3TOUT_spPtr; + + double *SOI3GF_toutPtr; + double *SOI3DP_toutPtr; + double *SOI3SP_toutPtr; + + double *SOI3TOUT_ibrPtr; /* these are for zero voltage source should */ + double *SOI3IBR_toutPtr; /* no thermal behaviour be specified */ + + double *SOI3B_toutPtr; /* for impact ionisation current source */ + + double *SOI3TOUT_tout1Ptr; + double *SOI3TOUT1_toutPtr; + double *SOI3TOUT1_tout1Ptr; + double *SOI3TOUT1_tout2Ptr; + double *SOI3TOUT2_tout1Ptr; + double *SOI3TOUT2_tout2Ptr; + double *SOI3TOUT2_tout3Ptr; + double *SOI3TOUT3_tout2Ptr; + double *SOI3TOUT3_tout3Ptr; + double *SOI3TOUT3_tout4Ptr; + double *SOI3TOUT4_tout3Ptr; + double *SOI3TOUT4_tout4Ptr; + + +/* indices to the array of SOI(3) noise sources */ + +#define SOI3RDNOIZ 0 +#define SOI3RSNOIZ 1 +#define SOI3IDNOIZ 2 +#define SOI3FLNOIZ 3 +#define SOI3TOTNOIZ 4 + +#define SOI3NSRCS 5 /* the number of SOI(3) noise sources */ + +#ifndef NONOISE + double SOI3nVar[NSTATVARS][SOI3NSRCS]; +#else /* NONOISE */ + double **SOI3nVar; +#endif /* NONOISE */ + +} SOI3instance ; + +#define SOI3vbd SOI3states+ 0 /* bulk-drain voltage */ +#define SOI3vbs SOI3states+ 1 /* bulk-source voltage */ +#define SOI3vgfs SOI3states+ 2 /* front gate-source voltage */ +#define SOI3vgbs SOI3states+ 3 /* back gate-source voltage */ +#define SOI3vds SOI3states+ 4 /* drain-source voltage */ +#define SOI3deltaT SOI3states+ 5 /* final temperature difference */ + +#define SOI3qgf SOI3states + 6 /* front gate charge */ +#define SOI3iqgf SOI3states +7 /* front gate current */ + +#define SOI3qgb SOI3states+ 8 /* back gate charge */ +#define SOI3iqgb SOI3states+ 9 /* back gate current */ + +#define SOI3qd SOI3states+ 10 /* drain charge */ +#define SOI3iqd SOI3states+ 11 /* drain current */ + +#define SOI3qs SOI3states+ 14 /* body charge */ +#define SOI3iqs SOI3states+ 15 /* body current */ + +#define SOI3cgfgf SOI3states+ 16 +#define SOI3cgfd SOI3states+ 17 +#define SOI3cgfs SOI3states+ 18 +#define SOI3cgfdeltaT SOI3states+ 19 + +#define SOI3cdgf SOI3states+ 20 +#define SOI3cdd SOI3states+ 21 +#define SOI3cds SOI3states+ 22 +#define SOI3cddeltaT SOI3states+ 23 + +#define SOI3csgf SOI3states+ 24 +#define SOI3csd SOI3states+ 25 +#define SOI3css SOI3states+ 26 +#define SOI3csdeltaT SOI3states+ 27 + +#define SOI3cgbgb SOI3states + 28 +#define SOI3cgbsb SOI3states + 29 +#define SOI3cgbdb SOI3states + 30 + +#define SOI3qbd SOI3states+ 31 /* body-drain capacitor charge */ +#define SOI3iqbd SOI3states+ 32 /* body-drain capacitor current */ + +#define SOI3qbs SOI3states+ 33 /* body-source capacitor charge */ +#define SOI3iqbs SOI3states+ 34 /* body-source capacitor current */ + +#define SOI3qt SOI3states+ 35 /* Energy or 'charge' associated with ct */ +#define SOI3iqt SOI3states+ 36 /* equiv current source for ct */ +#define SOI3qt1 SOI3states+ 37 /* Energy or 'charge' associated with ct */ +#define SOI3iqt1 SOI3states+ 38 /* equiv current source for ct */ +#define SOI3qt2 SOI3states+ 39 /* Energy or 'charge' associated with ct */ +#define SOI3iqt2 SOI3states+ 40 /* equiv current source for ct */ +#define SOI3qt3 SOI3states+ 41 /* Energy or 'charge' associated with ct */ +#define SOI3iqt3 SOI3states+ 42 /* equiv current source for ct */ +#define SOI3qt4 SOI3states+ 43 /* Energy or 'charge' associated with ct */ +#define SOI3iqt4 SOI3states+ 44 /* equiv current source for ct */ + +#define SOI3qBJTbs SOI3states+ 45 +#define SOI3iqBJTbs SOI3states+ 46 + +#define SOI3qBJTbd SOI3states+ 47 +#define SOI3iqBJTbd SOI3states+ 48 + +#define SOI3cBJTbsbs SOI3states+ 49 +#define SOI3cBJTbsdeltaT SOI3states+ 50 + +#define SOI3cBJTbdbd SOI3states+ 51 +#define SOI3cBJTbddeltaT SOI3states+ 52 + +#define SOI3idrain SOI3states+ 53 /* final drain current at timepoint (no define) */ + +#define SOI3deltaT1 SOI3states+ 54 /* final temperature difference */ +#define SOI3deltaT2 SOI3states+ 55 /* final temperature difference */ +#define SOI3deltaT3 SOI3states+ 56 /* final temperature difference */ +#define SOI3deltaT4 SOI3states+ 57 /* final temperature difference */ +#define SOI3deltaT5 SOI3states+ 58 /* final temperature difference */ + +#define SOI3numStates 59 + +/* per model data */ + + /* NOTE: parameters marked 'input - use xxxx' are paramters for + * which a temperature correction is applied in SOI3temp, thus + * the SOI3xxxx value in the per-instance structure should be used + * instead in all calculations + */ + + +typedef struct sSOI3model { /* model structure for an SOI3 MOSFET */ + + + int SOI3modType; /* type index to this device type */ + struct sSOI3model *SOI3nextModel; /* pointer to next possible model + *in linked list */ + SOI3instance * SOI3instances; /* pointer to list of instances + * that have this model */ + IFuid SOI3modName; /* pointer to character string naming this model */ + int SOI3type; /* device type : 1 = nsoi, -1 = psoi */ + double SOI3tnom; /* temperature at which parameters measured */ + double SOI3latDiff; + double SOI3jctSatCurDensity; /* input - use tSatCurDens (jnct)*/ + double SOI3jctSatCurDensity1; /* input - use tSatCurDens1 (jnct)*/ + double SOI3jctSatCur; /* input - use tSatCur (jnct Is)*/ + double SOI3jctSatCur1; /* input - use tSatCur1 (jnct Is)*/ + double SOI3drainResistance; + double SOI3sourceResistance; + double SOI3sheetResistance; + double SOI3transconductance; /* (KP) input - use tTransconductance */ + double SOI3frontGateSourceOverlapCapFactor; + double SOI3frontGateDrainOverlapCapFactor; + double SOI3frontGateBulkOverlapCapFactor; + double SOI3backGateSourceOverlapCapFactor; + double SOI3backGateDrainOverlapCapFactor; + double SOI3backGateBulkOverlapCapFactor; + double SOI3frontOxideCapFactor; /* Cof NO DEFINES */ + double SOI3backOxideCapFactor; /* Cob OR */ + double SOI3bodyCapFactor; /* Cb FLAGS */ + double SOI3C_bb; /* Cb in series with Cob */ + double SOI3C_fb; /* Cb in series with Cof */ + double SOI3C_ssf; /* q*NQFF */ + double SOI3C_ssb; /* q*NQFB */ + double SOI3C_fac; /* C_ob/(C_ob+C_b+C_ssb) */ + double SOI3vt0; /* input - use tVto */ + double SOI3vfbF; /* flat-band voltage. input - use tVfbF */ + double SOI3vfbB; /* back flat-band voltage. input - use tVfbB */ + double SOI3gamma; /* gamma */ + double SOI3gammaB; /* back gamma */ + double SOI3capBD; /* input - use tCbd */ + double SOI3capBS; /* input - use tCbs */ + double SOI3sideWallCapFactor; /* input - use tCjsw */ + double SOI3bulkJctPotential; /* input - use tBulkPot */ + double SOI3bulkJctSideGradingCoeff; /* MJSW */ + double SOI3fwdCapDepCoeff; /* FC */ + double SOI3phi; /* input - use tPhi */ + double SOI3vbi; /* input - use tVbi */ + double SOI3lambda; + double SOI3theta; + double SOI3substrateDoping; /* Nsub */ + double SOI3substrateCharge; /* Qb - no define/flag */ + int SOI3gateType; /* +1=same, -1=different, 0=Al */ + double SOI3frontFixedChargeDensity; + double SOI3backFixedChargeDensity; + double SOI3frontSurfaceStateDensity; + double SOI3backSurfaceStateDensity; + double SOI3frontOxideThickness; + double SOI3backOxideThickness; + double SOI3bodyThickness; + double SOI3surfaceMobility; /* input - use tSurfMob */ + double SOI3oxideThermalConductivity; + double SOI3siliconSpecificHeat; + double SOI3siliconDensity; + double SOI3fNcoef; + double SOI3fNexp; +/* new stuff for newer model - msll Jan96 */ + double SOI3sigma; /* DIBL factor */ + double SOI3chiFB; /* temperature coeff of flatband voltage */ + double SOI3chiPHI; /* temperature coeff of PHI */ + double SOI3deltaW; /* narrow width effect factor */ + double SOI3deltaL; /* short channel effect factor */ + double SOI3vsat; /* input - saturation velocity, use tVsat */ + double SOI3TVF0; /* internal use - precalculation of exp to save time */ + double SOI3k; /* thermal exponent for mobility factor */ + double SOI3lx; /* channel length modulation factor */ + double SOI3vp; /* channel length modulation empirical voltage */ + double SOI3eta; /* Imp. ion. field adjustment factor */ + double SOI3alpha0; /* 1st impact ionisation coeff */ + double SOI3beta0; /* 2nd impact ionisation coeff */ + double SOI3lm; /* impact ion. drain region length cf LX */ + double SOI3lm1; /* impact ion. drain region coeff */ + double SOI3lm2; /* impact ion. drain region coeff */ + double SOI3etad; /* diode ideality factor */ + double SOI3etad1; /* 2nd diode ideality factor */ + double SOI3chibeta; /* temp coeff of BETA0 */ + double SOI3chid; /* temp factor for junction 1 */ + double SOI3chid1; /* temp factor for junction 2 */ + int SOI3dvt; /* switch for temp dependence of vt in diodes */ + int SOI3nLev; /* level switch for noise model */ + double SOI3betaBJT; /* beta for Eber Moll BJT model */ + double SOI3tauFBJT; /* forward BJT transit time */ + double SOI3tauRBJT; /* reverse BJT transit time */ + double SOI3betaEXP; + double SOI3tauEXP; + double SOI3rsw; /* source resistance width scaling factor */ + double SOI3rdw; /* drain resistance width scaling factor */ + double SOI3minimumFeatureSize; /* minimum feature size of simulated process technology */ + double SOI3vtex; /* Extracted threshold voltage */ + double SOI3vdex; /* Drain bias at which vtex extracted */ + double SOI3delta0; /* Surface potential factor for vtex conversion */ + double SOI3satChargeShareFactor; /* Saturation region charge sharing factor */ + double SOI3nplusDoping; /* Doping concentration of N+ or P+ regions */ + double SOI3rta; /* thermal resistance area scaling factor */ + double SOI3cta; /* thermal capacitance area scaling factor */ + + unsigned SOI3typeGiven :1; + unsigned SOI3latDiffGiven :1; + unsigned SOI3jctSatCurDensityGiven :1; + unsigned SOI3jctSatCurDensity1Given :1; + unsigned SOI3jctSatCurGiven :1; + unsigned SOI3jctSatCur1Given :1; + unsigned SOI3drainResistanceGiven :1; + unsigned SOI3sourceResistanceGiven :1; + unsigned SOI3sheetResistanceGiven :1; + unsigned SOI3transconductanceGiven :1; + unsigned SOI3frontGateSourceOverlapCapFactorGiven :1; + unsigned SOI3frontGateDrainOverlapCapFactorGiven :1; + unsigned SOI3frontGateBulkOverlapCapFactorGiven :1; + unsigned SOI3backGateSourceOverlapCapFactorGiven :1; + unsigned SOI3backGateDrainOverlapCapFactorGiven :1; + unsigned SOI3backGateBulkOverlapCapFactorGiven :1; + unsigned SOI3subsBiasFactorGiven :1; + unsigned SOI3bodyFactorGiven :1; + unsigned SOI3vt0Given :1; + unsigned SOI3vfbFGiven :1; + unsigned SOI3vfbBGiven :1; + unsigned SOI3gammaGiven :1; + unsigned SOI3gammaBGiven :1; + unsigned SOI3capBDGiven :1; + unsigned SOI3capBSGiven :1; + unsigned SOI3sideWallCapFactorGiven :1; + unsigned SOI3bulkJctPotentialGiven :1; + unsigned SOI3bulkJctSideGradingCoeffGiven :1; + unsigned SOI3fwdCapDepCoeffGiven :1; + unsigned SOI3phiGiven :1; + unsigned SOI3lambdaGiven :1; + unsigned SOI3thetaGiven :1; + unsigned SOI3substrateDopingGiven :1; + unsigned SOI3gateTypeGiven :1; + unsigned SOI3frontFixedChargeDensityGiven :1; + unsigned SOI3backFixedChargeDensityGiven :1; + unsigned SOI3frontSurfaceStateDensityGiven :1; + unsigned SOI3backSurfaceStateDensityGiven :1; + unsigned SOI3frontOxideThicknessGiven :1; + unsigned SOI3backOxideThicknessGiven :1; + unsigned SOI3bodyThicknessGiven :1; + unsigned SOI3surfaceMobilityGiven :1; + unsigned SOI3tnomGiven :1; + unsigned SOI3oxideThermalConductivityGiven :1; + unsigned SOI3siliconSpecificHeatGiven :1; + unsigned SOI3siliconDensityGiven :1; + unsigned SOI3fNcoefGiven :1; + unsigned SOI3fNexpGiven :1; +/* extra stuff for newer model - msll Jan96 */ + unsigned SOI3sigmaGiven :1; + unsigned SOI3chiFBGiven :1; + unsigned SOI3chiPHIGiven :1; + unsigned SOI3deltaWGiven :1; + unsigned SOI3deltaLGiven :1; + unsigned SOI3vsatGiven :1; + unsigned SOI3kGiven :1; + unsigned SOI3lxGiven :1; + unsigned SOI3vpGiven :1; + unsigned SOI3useLAMBDA :1; + unsigned SOI3etaGiven :1; + unsigned SOI3alpha0Given :1; + unsigned SOI3beta0Given :1; + unsigned SOI3lmGiven :1; + unsigned SOI3lm1Given :1; + unsigned SOI3lm2Given :1; + unsigned SOI3etadGiven :1; + unsigned SOI3etad1Given :1; + unsigned SOI3chibetaGiven :1; + unsigned SOI3chidGiven :1; + unsigned SOI3chid1Given :1; + unsigned SOI3dvtGiven :1; + unsigned SOI3nLevGiven :1; + unsigned SOI3betaBJTGiven :1; + unsigned SOI3tauFBJTGiven :1; + unsigned SOI3tauRBJTGiven :1; + unsigned SOI3betaEXPGiven :1; + unsigned SOI3tauEXPGiven :1; + unsigned SOI3rswGiven :1; + unsigned SOI3rdwGiven :1; + unsigned SOI3minimumFeatureSizeGiven :1; + unsigned SOI3vtexGiven :1; + unsigned SOI3vdexGiven :1; + unsigned SOI3delta0Given :1; + unsigned SOI3satChargeShareFactorGiven :1; + unsigned SOI3nplusDopingGiven :1; + unsigned SOI3rtaGiven :1; + unsigned SOI3ctaGiven :1; + +} SOI3model; + +#ifndef NSOI3 +#define NSOI3 1 +#define PSOI3 -1 +#endif /*NSOI3*/ + +/* device parameters */ +#define SOI3_W 1 +#define SOI3_L 2 +#define SOI3_AS 3 +#define SOI3_AD 4 +#define SOI3_PS 5 +#define SOI3_PD 6 +#define SOI3_NRS 7 +#define SOI3_NRD 8 +#define SOI3_OFF 9 +#define SOI3_IC 10 +#define SOI3_IC_VBS 11 +#define SOI3_IC_VDS 12 +#define SOI3_IC_VGFS 13 +#define SOI3_IC_VGBS 21 +#define SOI3_W_SENS 14 +#define SOI3_L_SENS 15 +#define SOI3_IB 16 +#define SOI3_IGF 17 +#define SOI3_IGB 22 +#define SOI3_IS 18 +#define SOI3_POWER 19 +#define SOI3_TEMP 20 + +/* model parameters */ +#define SOI3_MOD_VTO 101 +#define SOI3_MOD_VFBF 149 +#define SOI3_MOD_KP 102 +#define SOI3_MOD_GAMMA 103 +#define SOI3_MOD_PHI 104 +#define SOI3_MOD_LAMBDA 105 +#define SOI3_MOD_THETA 139 +#define SOI3_MOD_RD 106 +#define SOI3_MOD_RS 107 +#define SOI3_MOD_CBD 108 +#define SOI3_MOD_CBS 109 +#define SOI3_MOD_IS 110 +#define SOI3_MOD_PB 111 +#define SOI3_MOD_CGFSO 112 +#define SOI3_MOD_CGFDO 113 +#define SOI3_MOD_CGFBO 114 +#define SOI3_MOD_CGBSO 144 +#define SOI3_MOD_CGBDO 145 +#define SOI3_MOD_CGB_BO 146 +#define SOI3_MOD_CJ 115 +#define SOI3_MOD_MJ 116 +#define SOI3_MOD_CJSW 117 +#define SOI3_MOD_MJSW 118 +#define SOI3_MOD_JS 119 +#define SOI3_MOD_TOF 120 +#define SOI3_MOD_TOB 133 +#define SOI3_MOD_TB 134 +#define SOI3_MOD_LD 121 +#define SOI3_MOD_RSH 122 +#define SOI3_MOD_U0 123 +#define SOI3_MOD_FC 124 +#define SOI3_MOD_NSUB 125 +#define SOI3_MOD_TPG 126 +#define SOI3_MOD_NQFF 147 +#define SOI3_MOD_NQFB 148 +#define SOI3_MOD_NSSF 127 +#define SOI3_MOD_NSSB 135 +#define SOI3_MOD_NSOI3 128 +#define SOI3_MOD_PSOI3 129 +#define SOI3_MOD_TNOM 130 +#define SOI3_MOD_KF 131 +#define SOI3_MOD_AF 132 +#define SOI3_MOD_KOX 142 +#define SOI3_MOD_SHSI 143 +/* extra stuff for newer model - msll Jan96 */ +#define SOI3_MOD_SIGMA 150 +#define SOI3_MOD_CHIFB 151 +#define SOI3_MOD_CHIPHI 152 +#define SOI3_MOD_DELTAW 153 +#define SOI3_MOD_DELTAL 154 +#define SOI3_MOD_VSAT 155 +#define SOI3_MOD_K 156 +#define SOI3_MOD_LX 157 +#define SOI3_MOD_VP 158 +#define SOI3_MOD_ETA 159 +#define SOI3_MOD_ALPHA0 140 +#define SOI3_MOD_BETA0 141 +#define SOI3_MOD_LM 160 +#define SOI3_MOD_LM1 161 +#define SOI3_MOD_LM2 162 +#define SOI3_MOD_ETAD 163 +#define SOI3_MOD_ETAD1 164 +#define SOI3_MOD_IS1 165 +#define SOI3_MOD_JS1 166 +#define SOI3_MOD_CHIBETA 167 +#define SOI3_MOD_VFBB 168 +#define SOI3_MOD_GAMMAB 169 +#define SOI3_MOD_CHID 170 +#define SOI3_MOD_CHID1 171 +#define SOI3_MOD_DVT 172 +#define SOI3_MOD_NLEV 173 +#define SOI3_MOD_BETABJT 174 +#define SOI3_MOD_TAUFBJT 176 +#define SOI3_MOD_TAURBJT 177 +#define SOI3_MOD_BETAEXP 178 +#define SOI3_MOD_TAUEXP 179 +#define SOI3_MOD_RSW 180 +#define SOI3_MOD_RDW 181 +#define SOI3_MOD_FMIN 382 +#define SOI3_MOD_VTEX 383 +#define SOI3_MOD_VDEX 384 +#define SOI3_MOD_DELTA0 385 +#define SOI3_MOD_CSF 386 +#define SOI3_MOD_DSI 387 +#define SOI3_MOD_NPLUS 388 +#define SOI3_MOD_RTA 389 +#define SOI3_MOD_CTA 390 + +/* device questions */ +#define SOI3_DNODE 201 +#define SOI3_GFNODE 202 +#define SOI3_SNODE 203 +#define SOI3_GBNODE 204 +#define SOI3_BNODE 205 +#define SOI3_DNODEPRIME 206 +#define SOI3_SNODEPRIME 207 +#define SOI3_TNODE 208 +#define SOI3_BRANCH 209 +#define SOI3_SOURCECONDUCT 210 +#define SOI3_DRAINCONDUCT 211 +#define SOI3_VON 212 +#define SOI3_VFBF 213 +#define SOI3_VDSAT 214 +#define SOI3_SOURCEVCRIT 215 +#define SOI3_DRAINVCRIT 216 +#define SOI3_ID 217 +#define SOI3_IBS 218 +#define SOI3_IBD 219 +#define SOI3_GMBS 220 +#define SOI3_GMF 221 +#define SOI3_GMB 222 +#define SOI3_GDS 223 +#define SOI3_GBD 224 +#define SOI3_GBS 225 +#define SOI3_CAPBD 226 +#define SOI3_CAPBS 227 +#define SOI3_CAPZEROBIASBD 228 +#define SOI3_CAPZEROBIASBDSW 229 +#define SOI3_CAPZEROBIASBS 230 +#define SOI3_CAPZEROBIASBSSW 231 +#define SOI3_VBD 232 +#define SOI3_VBS 233 +#define SOI3_VGFS 234 +#define SOI3_VGBS 235 +#define SOI3_VDS 236 +#define SOI3_QGF 237 +#define SOI3_IQGF 238 +#define SOI3_QGB 239 +#define SOI3_IQGB 240 +#define SOI3_QD 241 +#define SOI3_IQD 242 +#define SOI3_QS 243 +#define SOI3_IQS 244 +#define SOI3_QBD 245 +#define SOI3_IQBD 246 +#define SOI3_QBS 247 +#define SOI3_IQBS 248 +#define SOI3_CGFGF 249 +#define SOI3_CGFD 250 +#define SOI3_CGFS 251 +#define SOI3_CGFDELTAT 252 +#define SOI3_CDGF 253 +#define SOI3_CDD 254 +#define SOI3_CDS 255 +#define SOI3_CDDELTAT 256 +#define SOI3_CSGF 257 +#define SOI3_CSD 258 +#define SOI3_CSS 259 +#define SOI3_CSDELTAT 260 +#define SOI3_L_SENS_REAL 261 +#define SOI3_L_SENS_IMAG 262 +#define SOI3_L_SENS_MAG 263 +#define SOI3_L_SENS_PH 264 +#define SOI3_L_SENS_CPLX 265 +#define SOI3_W_SENS_REAL 266 +#define SOI3_W_SENS_IMAG 267 +#define SOI3_W_SENS_MAG 268 +#define SOI3_W_SENS_PH 269 +#define SOI3_W_SENS_CPLX 270 +#define SOI3_L_SENS_DC 271 +#define SOI3_W_SENS_DC 272 +#define SOI3_RT 273 +#define SOI3_CT 274 +/* extra stuff for newer model - msll Jan96 */ +#define SOI3_VFBB 275 +#define SOI3_RT1 276 +#define SOI3_CT1 277 +#define SOI3_RT2 278 +#define SOI3_CT2 279 +#define SOI3_RT3 280 +#define SOI3_CT3 281 +#define SOI3_RT4 282 +#define SOI3_CT4 283 + +/* model questions */ + +#include "soi3ext.h" + +#endif /*SOI3*/ + diff --git a/src/spicelib/devices/soi3/soi3del.c b/src/spicelib/devices/soi3/soi3del.c new file mode 100644 index 000000000..58a4793b9 --- /dev/null +++ b/src/spicelib/devices/soi3/soi3del.c @@ -0,0 +1,50 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#include "ngspice.h" +#include +#include "soi3defs.h" +#include "sperror.h" +#include "suffix.h" + + +int +SOI3delete(inModel,name,inst) + GENmodel *inModel; + IFuid name; + GENinstance **inst; +{ + SOI3model *model = (SOI3model *)inModel; + SOI3instance **fast = (SOI3instance **)inst; + SOI3instance **prev = NULL; + SOI3instance *here; + + for( ; model ; model = model->SOI3nextModel) { + prev = &(model->SOI3instances); + for(here = *prev; here ; here = *prev) { + if(here->SOI3name == name || (fast && here==*fast) ) { + *prev= here->SOI3nextInstance; + FREE(here); + return(OK); + } + prev = &(here->SOI3nextInstance); + } + } + return(E_NODEV); +} diff --git a/src/spicelib/devices/soi3/soi3dest.c b/src/spicelib/devices/soi3/soi3dest.c new file mode 100644 index 000000000..e5ae5926d --- /dev/null +++ b/src/spicelib/devices/soi3/soi3dest.c @@ -0,0 +1,51 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#include "ngspice.h" +#include +#include "soi3defs.h" +#include "suffix.h" + + +void +SOI3destroy(inModel) + GENmodel **inModel; +{ + SOI3model **model = (SOI3model**)inModel; + SOI3instance *here; + SOI3instance *prev = NULL; + SOI3model *mod = *model; + SOI3model *oldmod = NULL; + + for( ; mod ; mod = mod->SOI3nextModel) { + if(oldmod) FREE(oldmod); + oldmod = mod; + prev = (SOI3instance *)NULL; + for(here = mod->SOI3instances ; here ; here = here->SOI3nextInstance) { + if(prev){ + /* if(prev->SOI3sens) FREE(prev->SOI3sens); */ + FREE(prev); + } + prev = here; + } + if(prev) FREE(prev); + } + if(oldmod) FREE(oldmod); + *model = NULL; +} diff --git a/src/spicelib/devices/soi3/soi3ext.h b/src/spicelib/devices/soi3/soi3ext.h new file mode 100644 index 000000000..e3d518d81 --- /dev/null +++ b/src/spicelib/devices/soi3/soi3ext.h @@ -0,0 +1,95 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +#ifdef __STDC__ +extern int SOI3acLoad(GENmodel *,CKTcircuit*); +extern int SOI3ask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); +extern int SOI3delete(GENmodel*,IFuid,GENinstance**); +extern void SOI3destroy(GENmodel**); +extern int SOI3getic(GENmodel*,CKTcircuit*); +extern int SOI3load(GENmodel*,CKTcircuit*); +extern int SOI3mAsk(CKTcircuit *,GENmodel *,int,IFvalue*); +extern int SOI3mDelete(GENmodel**,IFuid,GENmodel*); +extern int SOI3mParam(int,IFvalue*,GENmodel*); +extern void SOI3cap(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*); +extern void SOI3capEval(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*,double*, + double*,double*,double*,double*,double*, + double*,double*,double*, + double*,double*, + double*,double*,double*,double*,double*); +extern int SOI3param(int,IFvalue*,GENinstance*,IFvalue*); +/* extern int SOI3pzLoad(GENmodel*,CKTcircuit*,SPcomplex*); | +extern int SOI3sAcLoad(GENmodel*,CKTcircuit*); | +extern int SOI3sLoad(GENmodel*,CKTcircuit*); | Ignored +extern void SOI3sPrint(GENmodel*,CKTcircuit*); | +extern int SOI3sSetup(SENstruct*,GENmodel*); | +extern int SOI3sUpdate(GENmodel*,CKTcircuit*); | */ +extern int SOI3setup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); +extern int SOI3unsetup(GENmodel*,CKTcircuit*); +extern int SOI3temp(GENmodel*,CKTcircuit*); +extern int SOI3trunc(GENmodel*,CKTcircuit*,double*); + +#ifdef SIMETRIX_VERSION +/* NTL modification 27.4.98 - add lastAttempt */ +extern int SOI3convTest(GENmodel*,CKTcircuit*,int lastAttempt); +/* end NTL modification */ +#else /* SIMETRIX_VERSION */ +extern int SOI3convTest(GENmodel*,CKTcircuit*); +#endif /* SIMETRIX_VERSION */ + +/* extern int SOI3disto(int,GENmodel*,CKTcircuit*); */ +extern int SOI3noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); + +#else /* stdc */ +extern int SOI3acLoad(); +extern int SOI3ask(); +extern int SOI3delete(); +extern void SOI3destroy(); +extern int SOI3getic(); +extern int SOI3load(); +extern int SOI3mAsk(); +extern int SOI3mDelete(); +extern int SOI3mParam(); +extern void SOI3cap(); +extern void SOI3capEval(); +extern int SOI3param(); +/* extern int SOI3pzLoad(); | +extern int SOI3sAcLoad(); | +extern int SOI3sLoad(); | ignored +extern void SOI3sPrint(); | +extern int SOI3sSetup(); | +extern int SOI3sUpdate(); */ +extern int SOI3setup(); +extern int SOI3unsetup(); +extern int SOI3temp(); +extern int SOI3trunc(); +extern int SOI3convTest(); +/* extern int SOI3disto(); */ +extern int SOI3noise(); +#endif /* stdc */ diff --git a/src/spicelib/devices/soi3/soi3ic.c b/src/spicelib/devices/soi3/soi3ic.c new file mode 100644 index 000000000..c217a6fca --- /dev/null +++ b/src/spicelib/devices/soi3/soi3ic.c @@ -0,0 +1,65 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "soi3defs.h" +#include "sperror.h" +#include "suffix.h" + + +int +SOI3getic(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + SOI3model *model = (SOI3model *)inModel; + SOI3instance *here; + /* + * grab initial conditions out of rhs array. User specified, so use + * external nodes to get values + */ + + for( ; model ; model = model->SOI3nextModel) { + for(here = model->SOI3instances; here ; here = here->SOI3nextInstance) { + if(!here->SOI3icVBSGiven) { + here->SOI3icVBS = + *(ckt->CKTrhs + here->SOI3bNode) - + *(ckt->CKTrhs + here->SOI3sNode); + } + if(!here->SOI3icVDSGiven) { + here->SOI3icVDS = + *(ckt->CKTrhs + here->SOI3dNode) - + *(ckt->CKTrhs + here->SOI3sNode); + } + if(!here->SOI3icVGFSGiven) { + here->SOI3icVGFS = + *(ckt->CKTrhs + here->SOI3gfNode) - + *(ckt->CKTrhs + here->SOI3sNode); + } + if(!here->SOI3icVGBSGiven) { + here->SOI3icVGBS = + *(ckt->CKTrhs + here->SOI3gbNode) - + *(ckt->CKTrhs + here->SOI3sNode); + } + } + } + return(OK); +} diff --git a/src/spicelib/devices/soi3/soi3init.c b/src/spicelib/devices/soi3/soi3init.c new file mode 100644 index 000000000..3a9744878 --- /dev/null +++ b/src/spicelib/devices/soi3/soi3init.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "soi3itf.h" +#include "soi3ext.h" +#include "soi3init.h" + + +SPICEdev SOI3info = { + { + "SOI3", + "Basic Thick Film SOI3 model", + + &SOI3nSize, + &SOI3nSize, + SOI3names, + + &SOI3pTSize, + SOI3pTable, + + &SOI3mPTSize, + SOI3mPTable, + DEV_DEFAULT + }, + + DEVparam : SOI3param, + DEVmodParam : SOI3mParam, + DEVload : SOI3load, + DEVsetup : SOI3setup, + DEVunsetup : SOI3unsetup, + DEVpzSetup : SOI3setup, + DEVtemperature: SOI3temp, + DEVtrunc : SOI3trunc, + DEVfindBranch : NULL, + DEVacLoad : SOI3acLoad, + DEVaccept : NULL, + DEVdestroy : SOI3destroy, + DEVmodDelete : SOI3mDelete, + DEVdelete : SOI3delete, + DEVsetic : SOI3getic, + DEVask : SOI3ask, + DEVmodAsk : SOI3mAsk, + DEVpzLoad : NULL, + DEVconvTest : SOI3convTest, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, + DEVnoise : SOI3noise, + + DEVinstSize : &SOI3iSize, + DEVmodSize : &SOI3mSize + +}; + + +SPICEdev * +get_soi3_info(void) +{ + return &SOI3info; +} diff --git a/src/spicelib/devices/soi3/soi3init.h b/src/spicelib/devices/soi3/soi3init.h new file mode 100644 index 000000000..0a957206e --- /dev/null +++ b/src/spicelib/devices/soi3/soi3init.h @@ -0,0 +1,13 @@ +#ifndef _SOI3INIT_H +#define _SOI3INIT_H + +extern IFparm SOI3pTable[ ]; +extern IFparm SOI3mPTable[ ]; +extern char *SOI3names[ ]; +extern int SOI3pTSize; +extern int SOI3mPTSize; +extern int SOI3nSize; +extern int SOI3iSize; +extern int SOI3mSize; + +#endif diff --git a/src/spicelib/devices/soi3/soi3itf.h b/src/spicelib/devices/soi3/soi3itf.h new file mode 100644 index 000000000..b91193d39 --- /dev/null +++ b/src/spicelib/devices/soi3/soi3itf.h @@ -0,0 +1,26 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#ifndef DEV_SOI3 +#define DEV_SOI3 + +SPICEdev *get_soi3_info(void); + + +#endif diff --git a/src/spicelib/devices/soi3/soi3load.c b/src/spicelib/devices/soi3/soi3load.c new file mode 100644 index 000000000..9317e078b --- /dev/null +++ b/src/spicelib/devices/soi3/soi3load.c @@ -0,0 +1,2560 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "devdefs.h" +#include "soi3defs.h" +#include "trandefs.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + +extern double DEVsoipnjlim(double vnew, double vold,double vt,double vcrit,int *icheck); +/* extern double DEVsoipnjlim(); */ + +int +SOI3load(inModel,ckt) + GENmodel *inModel; + register CKTcircuit *ckt; + /* actually load the current value into the + * sparse matrix previously provided + */ +{ + register SOI3model *model = (SOI3model *) inModel; + register SOI3instance *here; + double Beta; + double DrainSatCur; /* for drain pn junction */ + double SourceSatCur; /* for source pn junction */ + double DrainSatCur1; /* for 2nd drain pn junction */ + double SourceSatCur1; /* for 2nd source pn junction */ + double EffectiveLength,logL; + double FrontGateBulkOverlapCap; + double FrontGateDrainOverlapCap; + double FrontGateSourceOverlapCap; + double BackGateBulkOverlapCap; + double BackGateDrainOverlapCap; + double BackGateSourceOverlapCap; + double Frontcapargs[6]; + double Backcapargs[6]; + double FrontOxideCap; + double BackOxideCap; + double arg; + double ibhat; + double idhat; + double iPthat; /* needed for convergence */ + double ieqPt; /* value of equivalent current source */ + double idrain; + double idreq; + double ieq; + double ieqct,ieqct1,ieqct2,ieqct3,ieqct4; + double ieqbd; + double ieqbs; + double iMdbeq; + double iMsbeq; + double iBJTdbeq; + double iBJTsbeq; + double delvbd; + double delvbs; + double delvds; + double delvgfd; + double delvgfs; + double delvgbd; + double delvgbs; + double deldeltaT; + double evbd,evbd1; + double evbs,evbs1; + double rtargs[5]; + double grt[5]; + double gct[5]; + int tnodeindex; + double geq; + double sarg; + double sargsw; + double tol; + double vbd; + double vbs; + double vds; +/* the next lot are so we can cast the problem with the body node as ref */ + double vsb; + double vdb; + double vgbb; +/* now back to our regular programming */ +/* vgfb exists already for gate cap calc */ + double deltaT,deltaT1,deltaT2,deltaT3,deltaT4,deltaT5; + double vdsat; + double vgfb; + double vgfd; + double vgbd; + double vgfdo; + double vgbdo; + double vgfs; + double vgbs; + double von; + double vt; + double xfact; + int xnrm; + int xrev; + +/* now stuff needed for new charge model */ + double paramargs[10]; + double Bfargs[2],alpha_args[5]; + double psi_st0args[5]; + double vGTargs[5]; + double psi_sLargs[5],psi_s0args[5]; + double ldargs[5]; + double qgatef,qdrn,qsrc,qbody,qgateb; + double ieqqgf,ieqqd,ieqqs,ieqqgb; + double cgfgf,cgfd,cgfs,cgfdeltaT; + double cdgf,cdd,cds,cddeltaT; + double csgf,csd,css,csdeltaT; + double cbgf,cbd,cbs,cbdeltaT,cbgb; + double cgbgb,cgbsb,cgbdb; + double gcgfgf,gcgfd,gcgfs,gcgfdeltaT; + double gcdgf,gcdd,gcds,gcddeltaT; + double gcsgf,gcsd,gcss,gcsdeltaT; + double gcbgf,gcbd,gcbs,gcbdeltaT,gcbgb; + double gcgbgb,gcgbsb,gcgbdb; + double gcgbs0,gcgbd0; + + double alphaBJT; + double tauFBJTeff,tauRBJTeff; + double ISts,IS1ts,IStd,IS1td; + double ieqqBJTbs,ieqqBJTbd; + double gcBJTbsbs,gcBJTbsdeltaT; + double gcBJTbdbd,gcBJTbddeltaT; + double ag0; + + int Check; + int ByPass; + + double tempv; + + int error; +#ifdef CAPBYPASS + int senflag; +#endif /* CAPBYPASS */ + int SenCond; + + /* JimB - 4/1/99. New variables for junction */ + /* depletion capacitance model. */ + double Esj, Vsj, Xs; + double Edj, Vdj, Xd; + double DXs_Dvgfb, DXs_Dvdb, DXs_Dvsb, DXs_DdeltaT; + double DXd_Dvgfb, DXd_Dvdb, DXd_Dvsb, DXd_DdeltaT; + + + for( ; model != NULL; model = model->SOI3nextModel ) { + + /* loop through all the instances of the model */ + for (here = model->SOI3instances; here != NULL ; + here=here->SOI3nextInstance) { + + vt = CONSTKoverQ * here->SOI3temp; + Check=1; + ByPass=0; + + /* 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->SOI3l - 2*model->SOI3latDiff; + logL = log(EffectiveLength); + if (here->SOI3tSatCurDens == 0) { + DrainSatCur = here->SOI3tSatCur; + SourceSatCur = here->SOI3tSatCur; + } else { + DrainSatCur = here->SOI3tSatCurDens * + here->SOI3w; + SourceSatCur = here->SOI3tSatCurDens * + here->SOI3w; + } + if (here->SOI3tSatCurDens1 == 0) { + DrainSatCur1 = here->SOI3tSatCur1; + SourceSatCur1 = here->SOI3tSatCur1; + } else { + DrainSatCur1 = here->SOI3tSatCurDens1 * + here->SOI3w; + SourceSatCur1 = here->SOI3tSatCurDens1 * + here->SOI3w; + } +/* NB Junction sat. cur. density is NOW PER UNIT WIDTH */ + + FrontGateSourceOverlapCap = model->SOI3frontGateSourceOverlapCapFactor * + here->SOI3w; + FrontGateDrainOverlapCap = model->SOI3frontGateDrainOverlapCapFactor * + here->SOI3w; + FrontGateBulkOverlapCap = model->SOI3frontGateBulkOverlapCapFactor * + EffectiveLength; + BackGateSourceOverlapCap = model->SOI3backGateSourceOverlapCapFactor * + here->SOI3w; + BackGateDrainOverlapCap = model->SOI3backGateDrainOverlapCapFactor * + here->SOI3w; + BackGateBulkOverlapCap = model->SOI3backGateBulkOverlapCapFactor * + EffectiveLength; + + Beta = here->SOI3tTransconductance * here->SOI3w/EffectiveLength; + /* reset mu_eff to ambient temp value in SI units */ + here->SOI3ueff = here->SOI3tTransconductance/ + model->SOI3frontOxideCapFactor; + FrontOxideCap = model->SOI3frontOxideCapFactor * EffectiveLength * + here->SOI3w; + BackOxideCap = model->SOI3backOxideCapFactor * EffectiveLength * + here->SOI3w; + /* + * ok - now to do the start-up operations + * + * we must get values for vbs, vds, vgfs and vgbs 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 + */ + + /* yeah, but we'll then use vsb and vdb for the real work */ + +/* we will use conventional voltages to save * + * work rewriting the convergence criteria */ + + if((ckt->CKTmode & (MODEINITFLOAT | MODEINITPRED | MODEINITSMSIG + | MODEINITTRAN)) || + ( (ckt->CKTmode & MODEINITFIX) && (!here->SOI3off) ) ) + { +#ifndef PREDICTOR + if(ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) + { + + /* predictor step */ + + xfact=ckt->CKTdelta/ckt->CKTdeltaOld[1]; + *(ckt->CKTstate0 + here->SOI3vbs) = + *(ckt->CKTstate1 + here->SOI3vbs); + vbs = (1+xfact)* (*(ckt->CKTstate1 + here->SOI3vbs)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3vbs))); + *(ckt->CKTstate0 + here->SOI3vgfs) = + *(ckt->CKTstate1 + here->SOI3vgfs); + vgfs = (1+xfact)* (*(ckt->CKTstate1 + here->SOI3vgfs)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3vgfs))); + *(ckt->CKTstate0 + here->SOI3vgbs) = + *(ckt->CKTstate1 + here->SOI3vgbs); + vgbs = (1+xfact)* (*(ckt->CKTstate1 + here->SOI3vgbs)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3vgbs))); + *(ckt->CKTstate0 + here->SOI3vds) = + *(ckt->CKTstate1 + here->SOI3vds); + vds = (1+xfact)* (*(ckt->CKTstate1 + here->SOI3vds)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3vds))); + *(ckt->CKTstate0 + here->SOI3vbd) = + *(ckt->CKTstate0 + here->SOI3vbs)- + *(ckt->CKTstate0 + here->SOI3vds); + *(ckt->CKTstate0 + here->SOI3deltaT) = + *(ckt->CKTstate1 + here->SOI3deltaT); + deltaT = MAX(0,(1+xfact)* (*(ckt->CKTstate1 + here->SOI3deltaT)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3deltaT)))); + /* need to stop deltaT being -ve */ + + /* JimB - 19/5/99 */ + if (here->SOI3numThermalNodes == 0) + { + deltaT1=deltaT2=deltaT3=deltaT4=deltaT5=0.0; + } + if (here->SOI3numThermalNodes == 1) + { + deltaT1=deltaT; + deltaT2=deltaT3=deltaT4=deltaT5=0.0; + } + if (here->SOI3numThermalNodes == 2) + { + deltaT1 = MAX(0,(1+xfact)* (*(ckt->CKTstate1 + here->SOI3deltaT1)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3deltaT1)))); + deltaT2 = MAX(0,(1+xfact)* (*(ckt->CKTstate1 + here->SOI3deltaT2)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3deltaT2)))); + deltaT3=deltaT4=deltaT5=0.0; + } + if (here->SOI3numThermalNodes == 3) + { + deltaT1 = MAX(0,(1+xfact)* (*(ckt->CKTstate1 + here->SOI3deltaT1)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3deltaT1)))); + deltaT2 = MAX(0,(1+xfact)* (*(ckt->CKTstate1 + here->SOI3deltaT2)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3deltaT2)))); + deltaT3 = MAX(0,(1+xfact)* (*(ckt->CKTstate1 + here->SOI3deltaT3)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3deltaT3)))); + deltaT4=deltaT5=0.0; + } + if (here->SOI3numThermalNodes == 4) + { + deltaT1 = MAX(0,(1+xfact)* (*(ckt->CKTstate1 + here->SOI3deltaT1)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3deltaT1)))); + deltaT2 = MAX(0,(1+xfact)* (*(ckt->CKTstate1 + here->SOI3deltaT2)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3deltaT2)))); + deltaT3 = MAX(0,(1+xfact)* (*(ckt->CKTstate1 + here->SOI3deltaT3)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3deltaT3)))); + deltaT4 = MAX(0,(1+xfact)* (*(ckt->CKTstate1 + here->SOI3deltaT4)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3deltaT4)))); + deltaT5=0.0; + } + if (here->SOI3numThermalNodes == 5) + { + deltaT1 = MAX(0,(1+xfact)* (*(ckt->CKTstate1 + here->SOI3deltaT1)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3deltaT1)))); + deltaT2 = MAX(0,(1+xfact)* (*(ckt->CKTstate1 + here->SOI3deltaT2)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3deltaT2)))); + deltaT3 = MAX(0,(1+xfact)* (*(ckt->CKTstate1 + here->SOI3deltaT3)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3deltaT3)))); + deltaT4 = MAX(0,(1+xfact)* (*(ckt->CKTstate1 + here->SOI3deltaT4)) + -(xfact * (*(ckt->CKTstate2 + here->SOI3deltaT4)))); + deltaT5 =MAX(0,deltaT-deltaT1-deltaT2-deltaT3-deltaT4); + } + + *(ckt->CKTstate0 + here->SOI3idrain) = + *(ckt->CKTstate1 + here->SOI3idrain); + *(ckt->CKTstate0 + here->SOI3cgfgf) = + *(ckt->CKTstate1 + here->SOI3cgfgf); + *(ckt->CKTstate0 + here->SOI3cgfd) = + *(ckt->CKTstate1 + here->SOI3cgfd); + *(ckt->CKTstate0 + here->SOI3cgfs) = + *(ckt->CKTstate1 + here->SOI3cgfs); + *(ckt->CKTstate0 + here->SOI3cgfdeltaT) = + *(ckt->CKTstate1 + here->SOI3cgfdeltaT); + *(ckt->CKTstate0 + here->SOI3csgf) = + *(ckt->CKTstate1 + here->SOI3csgf); + *(ckt->CKTstate0 + here->SOI3csd) = + *(ckt->CKTstate1 + here->SOI3csd); + *(ckt->CKTstate0 + here->SOI3css) = + *(ckt->CKTstate1 + here->SOI3css); + *(ckt->CKTstate0 + here->SOI3csdeltaT) = + *(ckt->CKTstate1 + here->SOI3csdeltaT); + *(ckt->CKTstate0 + here->SOI3cdgf) = + *(ckt->CKTstate1 + here->SOI3cdgf); + *(ckt->CKTstate0 + here->SOI3cdd) = + *(ckt->CKTstate1 + here->SOI3cdd); + *(ckt->CKTstate0 + here->SOI3cds) = + *(ckt->CKTstate1 + here->SOI3cds); + *(ckt->CKTstate0 + here->SOI3cddeltaT) = + *(ckt->CKTstate1 + here->SOI3cddeltaT); + *(ckt->CKTstate0 + here->SOI3cgbgb) = + *(ckt->CKTstate1 + here->SOI3cgbgb); + *(ckt->CKTstate0 + here->SOI3cgbsb) = + *(ckt->CKTstate1 + here->SOI3cgbsb); + *(ckt->CKTstate0 + here->SOI3cgbdb) = + *(ckt->CKTstate1 + here->SOI3cgbdb); + *(ckt->CKTstate0 + here->SOI3cBJTbsbs) = + *(ckt->CKTstate1 + here->SOI3cBJTbsbs); + *(ckt->CKTstate0 + here->SOI3cBJTbsdeltaT) = + *(ckt->CKTstate1 + here->SOI3cBJTbsdeltaT); + *(ckt->CKTstate0 + here->SOI3cBJTbdbd) = + *(ckt->CKTstate1 + here->SOI3cBJTbdbd); + *(ckt->CKTstate0 + here->SOI3cBJTbddeltaT) = + *(ckt->CKTstate1 + here->SOI3cBJTbddeltaT); + } + else + { +#endif /* PREDICTOR */ + + /* general iteration */ + + vbs = model->SOI3type * ( + *(ckt->CKTrhsOld+here->SOI3bNode) - + *(ckt->CKTrhsOld+here->SOI3sNodePrime)); + vgfs = model->SOI3type * ( + *(ckt->CKTrhsOld+here->SOI3gfNode) - + *(ckt->CKTrhsOld+here->SOI3sNodePrime)); + vgbs = model->SOI3type * ( + *(ckt->CKTrhsOld+here->SOI3gbNode) - + *(ckt->CKTrhsOld+here->SOI3sNodePrime)); + vds = model->SOI3type * ( + *(ckt->CKTrhsOld+here->SOI3dNodePrime) - + *(ckt->CKTrhsOld+here->SOI3sNodePrime)); + deltaT = MAX(0,*(ckt->CKTrhsOld+here->SOI3toutNode)); + /* voltage deltaT is V(tout) wrt ground + and shoule be positive */ +/* the next lot are needed for the (extra) thermal capacitances */ + /* JimB - 19/5/99 */ + if (here->SOI3numThermalNodes == 0) + { + deltaT1=deltaT2=deltaT3=deltaT4=deltaT5=0; + } + if (here->SOI3numThermalNodes == 1) + { + deltaT1=deltaT; + deltaT2=deltaT3=deltaT4=deltaT5=0; + } + if (here->SOI3numThermalNodes == 2) + { + deltaT2 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout1Node)); + deltaT1 = deltaT - deltaT2; + deltaT3=deltaT4=deltaT5=0; + } + if (here->SOI3numThermalNodes == 3) + { + deltaT3 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout2Node)); + deltaT2 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout1Node) - deltaT3); + deltaT1 = deltaT - deltaT2 - deltaT3; + deltaT4=deltaT5=0; + } + if (here->SOI3numThermalNodes == 4) + { + deltaT4 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout3Node)); + deltaT3 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout2Node) - deltaT4); + deltaT2 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout1Node) - deltaT3); + deltaT1 = deltaT - deltaT2 - deltaT3 - deltaT4; + deltaT5=0; + } + if (here->SOI3numThermalNodes == 5) + { + deltaT5 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout4Node)); + deltaT4 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout3Node) - deltaT5); + deltaT3 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout2Node) - deltaT4); + deltaT2 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout1Node) - deltaT3); + deltaT1 = deltaT - deltaT2 - deltaT3 - deltaT4 - deltaT5; + } +#ifndef PREDICTOR + } +#endif /* PREDICTOR */ + + + /* now some common crunching for some more useful quantities */ + /* bloody useful in our case */ + + vbd=vbs-vds; + vdb=-vbd; + vsb=-vbs; + + vgfd=vgfs-vds; + vgbd=vgbs-vds; + vgbb=vgbs-vbs; + vgfdo = *(ckt->CKTstate0 + here->SOI3vgfs) - + *(ckt->CKTstate0 + here->SOI3vds); + vgbdo = *(ckt->CKTstate0 + here->SOI3vgbs) - + *(ckt->CKTstate0 + here->SOI3vds); + delvbs = vbs - *(ckt->CKTstate0 + here->SOI3vbs); + delvbd = vbd - *(ckt->CKTstate0 + here->SOI3vbd); + delvgfs = vgfs - *(ckt->CKTstate0 + here->SOI3vgfs); + delvgbs = vgbs - *(ckt->CKTstate0 + here->SOI3vgbs); + delvds = vds - *(ckt->CKTstate0 + here->SOI3vds); + delvgfd = vgfd-vgfdo; + delvgbd = vgbd-vgbdo; + deldeltaT = deltaT - *(ckt->CKTstate0 + here->SOI3deltaT); + + /* these are needed for convergence testing */ + /* we're keeping these the same as convergence on + vgfs, vbs, vbd, vgbs, deltaT is equiv to conv. + on vgfb, vsb, vdb, vgb_b, deltaT */ + + if (here->SOI3mode >= 0) { /* normal */ + idhat= + here->SOI3id- + here->SOI3gbd * delvbd - + here->SOI3gbdT * deldeltaT + /* for -ibd bit of id */ + (here->SOI3gmbs + + here->SOI3gMmbs) * delvbs + + (here->SOI3gmf + + here->SOI3gMmf) * delvgfs + + (here->SOI3gmb + + here->SOI3gMmb) * delvgbs + + (here->SOI3gds + + here->SOI3gMd) * delvds + + (here->SOI3gt + + here->SOI3gMdeltaT) * deldeltaT + + here->SOI3gBJTdb_bs * delvbs + + here->SOI3gBJTdb_deltaT * deldeltaT; + ibhat= + here->SOI3ibs + + here->SOI3ibd + + here->SOI3gbd * delvbd + + here->SOI3gbdT * deldeltaT + + here->SOI3gbs * delvbs + + here->SOI3gbsT * deldeltaT - + here->SOI3iMdb - + here->SOI3gMmbs * delvbs - + here->SOI3gMmf * delvgfs - + here->SOI3gMmb * delvgbs - + here->SOI3gMd * delvds - + here->SOI3gMdeltaT * deldeltaT - + here->SOI3iBJTsb - + here->SOI3gBJTsb_bd * delvbd - + here->SOI3gBJTsb_deltaT * deldeltaT - + here->SOI3iBJTdb - + here->SOI3gBJTdb_bs * delvbs - + here->SOI3gBJTdb_deltaT * deldeltaT; + } else { /* A over T */ + idhat= + here->SOI3id - + ( here->SOI3gbd + + here->SOI3gmbs) * delvbd - + (here->SOI3gmf) * delvgfd - + (here->SOI3gmb) * delvgbd + + (here->SOI3gds) * delvds - + (here->SOI3gt + + here->SOI3gbdT) * deldeltaT + + here->SOI3gBJTdb_bs * delvbs + + here->SOI3gBJTdb_deltaT * deldeltaT; + ibhat= + here->SOI3ibs + + here->SOI3ibd + + here->SOI3gbd * delvbd + + here->SOI3gbdT * deldeltaT + + here->SOI3gbs * delvbs + + here->SOI3gbsT * deldeltaT - + here->SOI3iMsb - + here->SOI3gMmbs * delvbd - + here->SOI3gMmf * delvgfd - + here->SOI3gMmb * delvgbd + + here->SOI3gMd * delvds - /* gMd should go with vsd */ + here->SOI3gMdeltaT * deldeltaT - + here->SOI3iBJTsb - + here->SOI3gBJTsb_bd * delvbd - + here->SOI3gBJTsb_deltaT * deldeltaT - + here->SOI3iBJTdb - + here->SOI3gBJTdb_bs * delvbs - + here->SOI3gBJTdb_deltaT * deldeltaT; + } +/* thermal current source comparator */ + iPthat =here->SOI3iPt + + here->SOI3gPmbs * delvbs + + here->SOI3gPmf * delvgfs + + here->SOI3gPmb * delvgbs + + here->SOI3gPds * delvds * here->SOI3mode + + here->SOI3gPdT * deldeltaT; +/* + +*/ + +#ifdef DETAILPROF +asm(" .globl mosptb"); +asm("mosptb:"); +#endif /*DETAILPROF*/ + + /* 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 + */ + /* bypass just needs to check any four voltages have not changed + so leave as before to avoid hassle */ + tempv = MAX(fabs(ibhat),fabs(here->SOI3ibs + + here->SOI3ibd-here->SOI3iMsb + - here->SOI3iMdb - here->SOI3iBJTdb + - here->SOI3iBJTsb))+ckt->CKTabstol; + if((!(ckt->CKTmode & (MODEINITPRED|MODEINITTRAN|MODEINITSMSIG) + )) && (ckt->CKTbypass) ) + if ( (fabs(ibhat-(here->SOI3ibs + + here->SOI3ibd-here->SOI3iMdb + - here->SOI3iMsb - here->SOI3iBJTdb + - here->SOI3iBJTsb)) < ckt->CKTreltol * + tempv)) + if( (fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs), + fabs(*(ckt->CKTstate0+here->SOI3vbs)))+ + ckt->CKTvoltTol))) + if ( (fabs(delvbd) < (ckt->CKTreltol * MAX(fabs(vbd), + fabs(*(ckt->CKTstate0+here->SOI3vbd)))+ + ckt->CKTvoltTol)) ) + if( (fabs(delvgfs) < (ckt->CKTreltol * MAX(fabs(vgfs), + fabs(*(ckt->CKTstate0+here->SOI3vgfs)))+ + ckt->CKTvoltTol))) + if( (fabs(delvgbs) < (ckt->CKTreltol * MAX(fabs(vgbs), + fabs(*(ckt->CKTstate0+here->SOI3vgbs)))+ + ckt->CKTvoltTol))) + if ( (fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), + fabs(*(ckt->CKTstate0+here->SOI3vds)))+ + ckt->CKTvoltTol)) ) + if ( (fabs(deldeltaT) < (ckt->CKTreltol * MAX(fabs(deltaT), + fabs(*(ckt->CKTstate0+here->SOI3deltaT)))+ + ckt->CKTvoltTol)) ) + if( (fabs(iPthat- here->SOI3iPt) < + ckt->CKTreltol * MAX(fabs(iPthat),fabs( + here->SOI3iPt)) + ckt->CKTabstol) ) + if( (fabs(idhat- here->SOI3id) < + ckt->CKTreltol * MAX(fabs(idhat),fabs( + here->SOI3id)) + 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->SOI3vbs); + vbd = *(ckt->CKTstate0 + here->SOI3vbd); + vgfs = *(ckt->CKTstate0 + here->SOI3vgfs); + vgbs = *(ckt->CKTstate0 + here->SOI3vgbs); + vds = *(ckt->CKTstate0 + here->SOI3vds); + deltaT = *(ckt->CKTstate0 + here->SOI3deltaT); + deltaT1 = *(ckt->CKTstate0 + here->SOI3deltaT1); + deltaT2 = *(ckt->CKTstate0 + here->SOI3deltaT2); + deltaT3 = *(ckt->CKTstate0 + here->SOI3deltaT3); + deltaT4 = *(ckt->CKTstate0 + here->SOI3deltaT4); + deltaT5 = *(ckt->CKTstate0 + here->SOI3deltaT5); + /* and now the extra ones */ + vsb=-vbs; + vdb=-vbd; + vgfb = vgfs - vbs; + vgbb = vgbs - vbs; + + /* JimB - 15/9/99 */ + /* Code for multiple thermal time constants. Start by moving all */ + /* rt constants into arrays. */ + rtargs[0]=here->SOI3rt; + rtargs[1]=here->SOI3rt1; + rtargs[2]=here->SOI3rt2; + rtargs[3]=here->SOI3rt3; + rtargs[4]=here->SOI3rt4; + + /* Set all conductance components to zero. */ + grt[0]=grt[1]=grt[2]=grt[3]=grt[4]=0.0; + /* Now calculate conductances from rt. */ + /* Don't need to worry about divide by zero when calculating */ + /* grt components, as soi3setup() only creates a thermal node */ + /* if corresponding rt is greater than zero. */ + for(tnodeindex=0;tnodeindexSOI3numThermalNodes;tnodeindex++) + { + grt[tnodeindex]=1/rtargs[tnodeindex]; + } + /* End JimB */ + + vgfd = vgfs - vds; + vgbd = vgbs - vds; + if (here->SOI3mode==1) + { + idrain = here->SOI3id + here->SOI3ibd - here->SOI3iMdb + - here->SOI3iBJTdb; + } + else + { + idrain = -here->SOI3id - here->SOI3ibd + + here->SOI3iBJTdb; + } + + /* Pt doesn't need changing as it's in here->SOI3iPt */ + + if((ckt->CKTmode & (MODETRAN | MODEAC)) || + (ckt->CKTmode & MODETRANOP)) + { + cgfgf = *(ckt->CKTstate0 + here->SOI3cgfgf); + cgfd = *(ckt->CKTstate0 + here->SOI3cgfd); + cgfs = *(ckt->CKTstate0 + here->SOI3cgfs); + cgfdeltaT = *(ckt->CKTstate0 + here->SOI3cgfdeltaT); + csgf = *(ckt->CKTstate0 + here->SOI3csgf); + csd = *(ckt->CKTstate0 + here->SOI3csd); + css = *(ckt->CKTstate0 + here->SOI3css); + csdeltaT = *(ckt->CKTstate0 + here->SOI3csdeltaT); + cdgf = *(ckt->CKTstate0 + here->SOI3cdgf); + cdd = *(ckt->CKTstate0 + here->SOI3cdd); + cds = *(ckt->CKTstate0 + here->SOI3cds); + cddeltaT = *(ckt->CKTstate0 + here->SOI3cddeltaT); + cgbgb = *(ckt->CKTstate0 + here->SOI3cgbgb); + cgbsb = *(ckt->CKTstate0 + here->SOI3cgbsb); + cgbdb = *(ckt->CKTstate0 + here->SOI3cgbdb); + cbgf = -(cgfgf + cdgf + csgf); + cbd = -(cgfd + cdd + csd + cgbdb); + cbs = -(cgfs + cds + css + cgbsb); + cbdeltaT = -(cgfdeltaT + cddeltaT + csdeltaT); + cbgb = -cgbgb; + qgatef = *(ckt->CKTstate0 + here->SOI3qgf); + qdrn = *(ckt->CKTstate0 + here->SOI3qd); + qsrc = *(ckt->CKTstate0 + here->SOI3qs); + qgateb = *(ckt->CKTstate0 + here->SOI3qgb); + qbody = -(qgatef + qdrn + qsrc + qgateb); + ByPass = 1; + goto bypass1; + } + goto bypass2; + } +/* + +*/ + +#ifdef DETAILPROF +asm(" .globl mosptc"); +asm("mosptc:"); +#endif /*DETAILPROF*/ + /* ok - bypass is out, do it the hard way */ + + von = model->SOI3type * here->SOI3von; + +#ifndef NODELIMITING + /* + * limiting + * we want to keep device voltages from changing + * so fast that the exponentials churn out overflows + * and similar rudeness + */ + + if(*(ckt->CKTstate0 + here->SOI3vds) >=0) + { + vgfs = DEVfetlim(vgfs,*(ckt->CKTstate0 + here->SOI3vgfs) + ,von); + vds = vgfs - vgfd; + vds = DEVlimvds(vds,*(ckt->CKTstate0 + here->SOI3vds)); + vgfd = vgfs - vds; + } + else + { + vgfd = DEVfetlim(vgfd,vgfdo,von); + vds = vgfs - vgfd; + if(!(ckt->CKTfixLimit)) + { + vds = -DEVlimvds(-vds,-(*(ckt->CKTstate0 + + here->SOI3vds))); + } + vgfs = vgfd + vds; + } + if(vds >= 0) + { + vbs = DEVsoipnjlim(vbs,*(ckt->CKTstate0 + here->SOI3vbs), + vt,here->SOI3sourceVcrit,&Check); + vbd = vbs-vds; + } + else + { + vbd = DEVsoipnjlim(vbd,*(ckt->CKTstate0 + here->SOI3vbd), + vt,here->SOI3drainVcrit,&Check); + vbs = vbd + vds; + } + + + /* and now some limiting of the temperature rise */ + if (deltaT>(10 + *(ckt->CKTstate0 + here->SOI3deltaT))) + { + deltaT = 10 + *(ckt->CKTstate0 + here->SOI3deltaT); + + /* need limiting, therefore must also impose limits on other + thermal voltages. + */ + + /* JimB - 19/5/99 */ + if (here->SOI3numThermalNodes == 0) + { + deltaT1=deltaT2=deltaT3=deltaT4=deltaT5=0; + } + if (here->SOI3numThermalNodes == 1) + { + deltaT1=deltaT; + deltaT2=deltaT3=deltaT4=deltaT5=0; + } + if (here->SOI3numThermalNodes == 2) + { + deltaT2 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout1Node)); + deltaT1 = deltaT - deltaT2; + deltaT3=deltaT4=deltaT5=0; + } + if (here->SOI3numThermalNodes == 3) + { + deltaT3 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout2Node)); + deltaT2 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout1Node) - deltaT3); + deltaT1 = deltaT - deltaT2 - deltaT3; + deltaT4=deltaT5=0; + } + if (here->SOI3numThermalNodes == 4) + { + deltaT4 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout3Node)); + deltaT3 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout2Node) - deltaT4); + deltaT2 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout1Node) - deltaT3); + deltaT1 = deltaT - deltaT2 - deltaT3 - deltaT4; + deltaT5=0; + } + if (here->SOI3numThermalNodes == 5) + { + deltaT5 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout4Node)); + deltaT4 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout3Node) - deltaT5); + deltaT3 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout2Node) - deltaT4); + deltaT2 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout1Node) - deltaT3); + deltaT1 = deltaT - deltaT2 - deltaT3 - deltaT4 - deltaT5; + } + + Check = 1; + } +#endif /*NODELIMITING*/ +/* + +*/ + +#ifdef DETAILPROF +asm(" .globl mosptd"); +asm("mosptd:"); +#endif /*DETAILPROF*/ + } else { + + /* 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 + */ + + if((ckt->CKTmode & MODEINITJCT) && !here->SOI3off) + { + vds= model->SOI3type * here->SOI3icVDS; + vgfs= model->SOI3type * here->SOI3icVGFS; + vgbs= model->SOI3type * here->SOI3icVGBS; + vbs= model->SOI3type * here->SOI3icVBS; + deltaT=deltaT1=deltaT2=deltaT3=deltaT4=deltaT5=0.0; + if((vds==0) && (vgfs==0) && (vbs==0) && (vgbs==0) && + ((ckt->CKTmode & + (MODETRAN|MODEDCOP|MODEDCTRANCURVE)) || + (!(ckt->CKTmode & MODEUIC)))) + { + vbs = -1; + vgfs = model->SOI3type * here->SOI3tVto; + vds = 0; + vgbs = 0; + deltaT=deltaT1=deltaT2=deltaT3=deltaT4=deltaT5=0.0; + } + } + else + { + vbs=vgfs=vds=vgbs=deltaT=deltaT1=deltaT2=deltaT3=deltaT4=deltaT5=0.0; + } + } +/* + +*/ + +#ifdef DETAILPROF +asm(" .globl mospte"); +asm("mospte:"); +#endif /*DETAILPROF*/ + + /* + * now all the preliminaries are over - we can start doing the + * real work + */ + vbd = vbs - vds; + vgfd = vgfs - vds; + vgbd = vgbs - vds; + vgfb = vgfs - vbs; + vgbb = vgbs - vbs; + vsb = -vbs; + vdb = -vbd; + + + /* now to determine whether the user was able to correctly + * identify the source and drain of his device + */ + if(vds >= 0) { + /* normal mode */ + here->SOI3mode = 1; + } else { + /* inverse mode */ + here->SOI3mode = -1; + } +/* + +*/ + +#ifdef DETAILPROF +asm(" .globl mosptf"); +asm("mosptf:"); +#endif /*DETAILPROF*/ + { /* begin block */ + + /* + * This block works out drain current and derivatives. + * It does this via the calculation of the surface potential + * which is a bit complex mostly for reasons of continuity + * and robustness - c'est la vie. + * + */ + + /* the following variables are local to this code block until + * it is obvious that they can be made global + */ + double vg; + double eta_s; /* 1+Citf/Cof */ + double gamma,sigma; + double Egy,vgy,Sgy; + double psi_ss; + double AL,A0,LL,L0; + double ALx,A0x,EAL,EA0; + double logterm0,logtermL; + double Vgconst0,VgconstL; + double Egx0,EgxL; + double vgx0,vgxL; + double psi_si0,psi_siL,psi_st0; + double Esi0,EsiL,Ess0; + double theta2; + double TVF; /* thermal velocity-saturation factor */ + double Mmob; + double sqt0,sqt0one; + double alpha,delta,Bf; + double vGBF,vGT,vGBT; + double PSI; + double S; + double psi_sLsat; + double Esd0,EsdL; + + double psi_s0,psi_sL; + double fL,f0; + double DfL_Dvgfb,DfL_Dvdb,DfL_Dvsb,DfL_DdeltaT; + double Df0_Dvgfb,Df0_Dvdb,Df0_Dvsb,Df0_DdeltaT; + double ld,Dld_Dvgfb,Dld_Dvdb,Dld_Dvsb,Dld_DdeltaT; + + double ich0; + + double pDpsi_si0_Dvgx0,pDpsi_siL_DvgxL; + double Dvgx0_Dvgfb,pDvgx0_Dvg,Dvgx0_Dvsb,Dvgx0_Dvdb,Dvgx0_DdeltaT; + double DvgxL_Dvgfb,pDvgxL_Dvg,DvgxL_Dvsb,DvgxL_Dvdb,DvgxL_DdeltaT; + double pDpsi_si0_Dvsb,pDpsi_siL_Dvdb; + double Dpsi_si0_Dvgfb,Dpsi_si0_Dvsb,Dpsi_si0_Dvdb; + double Dpsi_siL_Dvgfb,Dpsi_siL_Dvsb,Dpsi_siL_Dvdb; + double Dpsi_ss_Dvgfb,Dpsi_ss_Dvsb,Dpsi_ss_Dvdb; + double Dpsi_st0_Dvgfb,Dpsi_st0_Dvsb,Dpsi_st0_Dvdb; + double pDdelta_Dpsi_st0; + double Dalpha_Dvgfb,Dalpha_Dvdb,Dalpha_Dvsb,Dalpha_DdeltaT; + double DPSI_Dvgfb,DPSI_Dvdb,DPSI_Dvsb,DPSI_DdeltaT; + double pDBf_Dpsi_st0,DvGT_Dvgfb,DvGT_Dvsb,DvGT_Dvdb,DvGT_DdeltaT; + double D,DS_Dvgfb,DS_Dvsb,DS_Dvdb,DS_DdeltaT; + double Dpsi_sLsat_Dvgfb,Dpsi_sLsat_Dvsb,Dpsi_sLsat_Dvdb; + double gmg,gmd,gms,gmt; + double Dpsi_si0_DdeltaT,Dpsi_siL_DdeltaT; + double Dpsi_ss_DdeltaT,Dpsi_st0_DdeltaT; + double Dpsi_sLsat_DdeltaT; + double Dpsi_sL_Dvgfb,Dpsi_s0_Dvgfb,Dpsi_sL_Dvdb,Dpsi_s0_Dvdb; + double Dpsi_sL_Dvsb,Dpsi_s0_Dvsb,Dpsi_sL_DdeltaT,Dpsi_s0_DdeltaT; + double Vm,Em,Vmx; + double DVmx_Dvgfb,DVmx_Dvdb,DVmx_Dvsb,DVmx_DdeltaT; + double Vm1,Em1,Vm1x; + double DVm1x_Dvgfb,DVm1x_Dvdb,DVm1x_Dvsb,DVm1x_DdeltaT; + double vgeff,lm,lmeff,lmeff2,Elm,Dlm_Dvgfb,Dlm_Dvdb,Dlm_Dvsb,Dlm_DdeltaT; + + double Mminus1=0; + double EM,betaM; + double gMg,gMd,gMs; + double Fm; /* mobility degradation factor */ + double Y; /* channel length modulation factor */ + double tmp,tmp1; /* temporary var to aid pre-calculation */ + double TMF; /* thermal mobility factor */ + int vgx0trans,vgxLtrans; /* flags to indicate if vg transform performed */ + int psi_s0_trans,psi_sL_trans; + int Ess0_trans,Esd0_trans,EsdL_trans; + int A0trans,ALtrans; + + double vT,EchiD,EchiD1; + double BetaBJTeff; + +/* Now we use a nasty trick - if device is A over T, must "swap" drain and source + potentials. we do a literal switch and change it back for the outside world. */ + if (here->SOI3mode == -1) { + tmp = vsb; + vsb = vdb; + vdb = tmp; + } + +/* Intrinsic Electrical Bit - has a bit of thermal due to TTC */ + sigma = model->SOI3sigma/(EffectiveLength); + eta_s = 1 + (model->SOI3C_ssf/model->SOI3frontOxideCapFactor); + vg = vgfb - here->SOI3tVfbF * model->SOI3type + + sigma*(here->SOI3mode*vds) + - model->SOI3chiFB*deltaT; + gamma = model->SOI3gamma * (1 + (model->SOI3deltaW)/(here->SOI3w)) + * (1 - (model->SOI3deltaL)/EffectiveLength); +/* must introduce some limiting to prevent exp overflow */ + if (vg > (vt*MAX_EXP_ARG)) { + vgy = vg; + } else { + Egy = exp(vg/vt); + vgy = vt*log(1+Egy); + } + Sgy = sqrt((vgy/eta_s) + (gamma*gamma)/(4*eta_s*eta_s)); + psi_ss = (Sgy-0.5*gamma/eta_s)*(Sgy-0.5*gamma/eta_s); + A0 = here->SOI3tPhi + vsb; + AL = here->SOI3tPhi + vdb; + if (A0 > (vt*MAX_EXP_ARG)) { + A0x = A0; + A0trans = 0; + } else { + EA0 = exp(A0/vt); + A0x = vt * log(1+EA0); + A0trans = 1; + } + if (AL > (vt*MAX_EXP_ARG)) { + ALx = AL; + ALtrans = 0; + } else { + EAL = exp(AL/vt); + ALx = vt * log(1+EAL); + ALtrans = 1; + } +/* if vg is very large then don't need to transform + vg into vgx. +*/ + Vgconst0 = eta_s*A0x - vt*(eta_s - 1) + gamma*sqrt(A0x); + if ((vg-Vgconst0) < (5 * vt * MAX_EXP_ARG)) { + vgx0trans = 1; + Egx0 = exp((vg - Vgconst0)/(5*vt)); + vgx0 = (5*vt) * log(1 + Egx0) + Vgconst0; + } else { + vgx0trans = 0; /* no transform performed */ + vgx0 = vg; + } + + + VgconstL = eta_s*ALx - vt*(eta_s - 1) + gamma*sqrt(ALx); + if ((vg-VgconstL) < (5 * vt * MAX_EXP_ARG)) { + vgxLtrans = 1; + EgxL = exp((vg - VgconstL)/(5*vt)); + vgxL = (5*vt) * log(1 + EgxL) + VgconstL; + } else { + vgxLtrans = 0; /* no transform performed */ + vgxL = vg; + } + + L0 = vgx0 - eta_s*(A0 - vt); + LL = vgxL - eta_s*(AL - vt); + logterm0 = ((L0/gamma)*(L0/gamma) - A0)/vt; + logtermL = ((LL/gamma)*(LL/gamma) - AL)/vt; + if (logterm0<=0) { /* can only happen due to numerical problems with sqrt*/ + psi_si0 = A0 + model->SOI3chiPHI*deltaT + vt*log(vt/(gamma*gamma)); + } else { + psi_si0 = A0 + model->SOI3chiPHI*deltaT + vt*log(logterm0); + } + if (logtermL<=0) { + psi_siL = AL + model->SOI3chiPHI*deltaT + vt*log(vt/(gamma*gamma)); + } else { + psi_siL = AL + model->SOI3chiPHI*deltaT + vt*log(logtermL); + } + + if ((psi_si0-psi_ss) < vt*MAX_EXP_ARG) { + Ess0 = exp((psi_si0-psi_ss)/vt); + Ess0_trans = 1; + if (psi_si0 > (vt * MAX_EXP_ARG)) { /* psi_si0 is BIG */ + psi_st0 = psi_si0 - vt*log(1+Ess0); + psi_s0_trans = 0; + } else { + Esi0 = exp(psi_si0/vt); + psi_st0 = vt*log(1+(Esi0/(1+Ess0))); + psi_s0_trans = 1; + } + } else { + psi_st0 = psi_ss; + Ess0_trans = 0; + psi_s0_trans = 0; + } + +/* now for psi_sLsat - has thermal influence ! (if vel sat is included) */ + TMF = exp(-model->SOI3k*log(1+(deltaT/here->SOI3temp))); + sqt0 = sqrt(psi_st0+1E-25); + sqt0one = sqrt(1+psi_st0); +/* delta is formulated this way so we can change it here and nowhere else */ + delta = 0.5/sqt0one; + pDdelta_Dpsi_st0 = -0.25/((1+psi_st0)*sqt0one); + alpha = eta_s+gamma*delta; + vGBF = vg - psi_st0; + Bf = sqt0 - delta*psi_st0; + vGT = vg - gamma*Bf; + vGBT = vGT + alpha*vt; + + if(model->SOI3vsat == 0) { + theta2 = 0; + TVF = 0.0; /* could be any nominal value */ + } else { + TVF = 0.8*exp((here->SOI3temp+deltaT)/600); + theta2 = (here->SOI3tSurfMob/(model->SOI3vsat))*1e-2 /*cm to m*/ + *TMF*(1+TVF)/(EffectiveLength*(1+model->SOI3TVF0)); + /* theta2=1/(L.Ec) */ + } + Mmob = theta2 - 0.5*model->SOI3theta; + + PSI = MAX(0,(vGT/alpha) - psi_st0); + S = 0.5*(1+sqrt(1 + (2*Mmob*PSI)/(1+model->SOI3theta*vGBF))); + psi_sLsat = psi_st0 + PSI/S; + + if ((psi_si0 - psi_sLsat)<(vt*MAX_EXP_ARG)) { + Esd0 = exp((psi_si0 - psi_sLsat)/vt); + Esd0_trans = 1; + if (psi_s0_trans) { + psi_s0 = vt*log(1+Esi0/(1+Esd0)); + } else { + psi_s0 = psi_si0 - vt*log(1+Esd0); + } + } else { + psi_s0 = psi_sLsat; + Esd0_trans = 0; + } + + if ((psi_siL - psi_sLsat)<(vt*MAX_EXP_ARG)) { + EsdL = exp((psi_siL - psi_sLsat)/vt); + EsdL_trans = 1; + if (psi_siL < (vt * MAX_EXP_ARG)) { + EsiL = exp(psi_siL/vt); + psi_sL = vt*log(1+EsiL/(1+EsdL)); + psi_sL_trans = 1; + } else { + psi_sL = psi_siL - vt*log(1+EsdL); + psi_sL_trans = 0; + } + } else { + psi_sL = psi_sLsat; + EsdL_trans = 0; + } +/* if, after all that, we have impossible situation due to numerical limiting schemes ... */ + + if (psi_s0>psi_sL) { + psi_sL = psi_s0; + } + +/* now we can finally work out surface potential for source and drain end */ + +/* now surface potential is ready */ + + f0 = (vGBT - 0.5*alpha*psi_s0)*psi_s0; + fL = (vGBT - 0.5*alpha*psi_sL)*psi_sL; + + ich0 = Beta * (fL - f0); /* This is "intrinsic" bit */ + +/* now for derivatives - they're a bit of a nightmare * + * notation pD... means PARTIAL derivative whilst D... * + * means FULL derivative */ + +/* first sub-threshold */ + + if (vg > (vt*MAX_EXP_ARG)) { + Dpsi_ss_Dvgfb = (1-0.5*gamma/(eta_s*Sgy))/eta_s; + } else { + Dpsi_ss_Dvgfb = (1-0.5*gamma/(eta_s*Sgy))*(Egy/(1+Egy))/eta_s; + } + Dpsi_ss_Dvsb = Dpsi_ss_Dvgfb*(-sigma); + Dpsi_ss_Dvdb = Dpsi_ss_Dvgfb*(sigma); + Dpsi_ss_DdeltaT = Dpsi_ss_Dvgfb*(-model->SOI3chiFB); + +/* now for strong inversion */ + + pDpsi_si0_Dvgx0 = 2*vt*L0/(L0*L0-gamma*gamma*A0); + pDpsi_siL_DvgxL = 2*vt*LL/(LL*LL-gamma*gamma*AL); + + /* if vg is transformed, must have deriv accordingly, else it is 1 */ + + if (vgx0trans) { + Dvgx0_Dvgfb = pDvgx0_Dvg = Egx0/(1+Egx0); + if (A0trans) { + /* JimB - 27/8/98 */ + /* Get divide by zero errors when A0x is equal to zero */ + /* Temporary fix - add small constant to denominator */ +/* Dvgx0_Dvsb = pDvgx0_Dvg * (-sigma) + + (1-pDvgx0_Dvg)*(eta_s+0.5*gamma/sqrt(A0x))* + (EA0/(1+EA0)); */ + Dvgx0_Dvsb = pDvgx0_Dvg * (-sigma) + + (1-pDvgx0_Dvg)*(eta_s+0.5*gamma/(sqrt(A0x)+1e-25))* + (EA0/(1+EA0)); + /* End JimB */ + } else { + /* JimB - 27/8/97 */ + /* Temporary fix - add small constant to denominator */ + /*Dvgx0_Dvsb = pDvgx0_Dvg * (-sigma) + + (1-pDvgx0_Dvg)*(eta_s+0.5*gamma/sqrt(A0)); */ + Dvgx0_Dvsb = pDvgx0_Dvg * (-sigma) + + (1-pDvgx0_Dvg)*(eta_s+0.5*gamma/(sqrt(A0)+1e-25)); + /* End JimB */ + } + Dvgx0_Dvdb = pDvgx0_Dvg*(sigma); + Dvgx0_DdeltaT = pDvgx0_Dvg*(-model->SOI3chiFB); + } else { + Dvgx0_Dvgfb = pDvgx0_Dvg = 1; + Dvgx0_Dvsb = (-sigma); + Dvgx0_Dvdb = (sigma); + Dvgx0_DdeltaT = (-model->SOI3chiFB); + } + + if (vgxLtrans) { + DvgxL_Dvgfb = pDvgxL_Dvg = EgxL/(1+EgxL); + DvgxL_Dvsb = pDvgxL_Dvg * (-sigma); + if (ALtrans) { + /* JimB - 27/8/98 */ + /* Get divide by zero errors when ALx is equal to zero */ + /* Temporary fix - add small constant to denominator */ + /*DvgxL_Dvdb = pDvgxL_Dvg * (sigma) + + (1-pDvgxL_Dvg)*(eta_s+0.5*gamma/sqrt(ALx))* + (EAL/(1+EAL)); */ + DvgxL_Dvdb = pDvgxL_Dvg * (sigma) + + (1-pDvgxL_Dvg)*(eta_s+0.5*gamma/(sqrt(ALx)+1e-25))* + (EAL/(1+EAL)); + /* End JimB */ + } else { + /* JimB - 27/8/97 */ + /* Temporary fix - add small constant to denominator */ +/* DvgxL_Dvdb = pDvgxL_Dvg * (sigma) + + (1-pDvgxL_Dvg)*(eta_s+0.5*gamma/sqrt(AL)); */ + DvgxL_Dvdb = pDvgxL_Dvg * (sigma) + + (1-pDvgxL_Dvg)*(eta_s+0.5*gamma/(sqrt(AL)+1e-25)); + /* End JimB */ + } + DvgxL_DdeltaT = pDvgxL_Dvg * (-model->SOI3chiFB); + } else { + DvgxL_Dvgfb = 1; + DvgxL_Dvsb = (-sigma); + DvgxL_Dvdb = (sigma); + DvgxL_DdeltaT = (-model->SOI3chiFB); + } + + pDpsi_si0_Dvsb = 1 - (2*vt*eta_s*L0+vt*gamma*gamma)/(L0*L0-gamma*gamma*A0); + pDpsi_siL_Dvdb = 1 - (2*vt*eta_s*LL+vt*gamma*gamma)/(LL*LL-gamma*gamma*AL); + + Dpsi_si0_Dvgfb = pDpsi_si0_Dvgx0*Dvgx0_Dvgfb; + Dpsi_si0_Dvsb = pDpsi_si0_Dvgx0*Dvgx0_Dvsb + pDpsi_si0_Dvsb; + Dpsi_si0_Dvdb = pDpsi_si0_Dvgx0*Dvgx0_Dvdb; + Dpsi_si0_DdeltaT = model->SOI3chiPHI + + pDpsi_si0_Dvgx0*Dvgx0_DdeltaT; + + Dpsi_siL_Dvgfb = pDpsi_siL_DvgxL*DvgxL_Dvgfb; + Dpsi_siL_Dvsb = pDpsi_siL_DvgxL*DvgxL_Dvsb; + Dpsi_siL_Dvdb = pDpsi_siL_DvgxL*DvgxL_Dvdb + pDpsi_siL_Dvdb; + Dpsi_siL_DdeltaT = model->SOI3chiPHI + + pDpsi_siL_DvgxL*DvgxL_DdeltaT; + +/* now we can get full deriv of first guess + but also, partials of psi_s0 and psi_sL, the + final values have similar structure, so do + them now as well */ + + /* deriv of psi_s etc wrt psi_si must be according to transform used */ + + if (Ess0_trans) { + if (psi_s0_trans) { + tmp = (Esi0/(1+Ess0+Esi0))/(1+Ess0); + tmp1 = (Esi0/(1+Ess0+Esi0))*(Ess0/(1+Ess0)); + } else { + tmp = 1/(1+Ess0); + tmp1 = Ess0*tmp; + } + Dpsi_st0_Dvgfb = tmp*Dpsi_si0_Dvgfb + tmp1*Dpsi_ss_Dvgfb; + Dpsi_st0_Dvsb = tmp*Dpsi_si0_Dvsb + tmp1*Dpsi_ss_Dvsb; + Dpsi_st0_Dvdb = tmp*Dpsi_si0_Dvdb + tmp1*Dpsi_ss_Dvdb; + Dpsi_st0_DdeltaT = tmp*Dpsi_si0_DdeltaT + tmp1*Dpsi_ss_DdeltaT; + } else { + Dpsi_st0_Dvgfb = Dpsi_ss_Dvgfb; + Dpsi_st0_Dvdb = Dpsi_ss_Dvdb; + Dpsi_st0_Dvsb = Dpsi_ss_Dvsb; + Dpsi_st0_DdeltaT = Dpsi_ss_DdeltaT; + } + +/* now some itsy bitsy quantities useful all over the shop */ + /* Ddelta_Dpsi_st0 is defined earlier with delta to allow + change of delta expression in one place */ + + pDBf_Dpsi_st0 = 0.5/sqt0 - psi_st0*pDdelta_Dpsi_st0 - delta; + + DvGT_Dvgfb = 1 - gamma*pDBf_Dpsi_st0*Dpsi_st0_Dvgfb; + DvGT_Dvsb = (-sigma) - gamma*pDBf_Dpsi_st0*Dpsi_st0_Dvsb; + DvGT_Dvdb = (sigma) - gamma*pDBf_Dpsi_st0*Dpsi_st0_Dvdb; + DvGT_DdeltaT = (-model->SOI3chiFB) - gamma*pDBf_Dpsi_st0*Dpsi_st0_DdeltaT; + + Dalpha_Dvgfb = gamma*pDdelta_Dpsi_st0*Dpsi_st0_Dvgfb; + Dalpha_Dvsb = gamma*pDdelta_Dpsi_st0*Dpsi_st0_Dvsb; + Dalpha_Dvdb = gamma*pDdelta_Dpsi_st0*Dpsi_st0_Dvdb; + Dalpha_DdeltaT = gamma*pDdelta_Dpsi_st0*Dpsi_st0_DdeltaT; + +/* Now for saturation stuff psi_sLsat */ +/* NB no need for special case, theta2=0 ==> Mmob=-theta/2 */ + + if (PSI != 0) { /* stops unnecessary math if PSI = 0 */ + DPSI_Dvgfb = (DvGT_Dvgfb - (vGT/alpha)*Dalpha_Dvgfb + )/alpha - Dpsi_st0_Dvgfb; + DPSI_Dvsb = (DvGT_Dvsb - (vGT/alpha)*Dalpha_Dvsb + )/alpha - Dpsi_st0_Dvsb; + DPSI_Dvdb = (DvGT_Dvdb - (vGT/alpha)*Dalpha_Dvdb + )/alpha - Dpsi_st0_Dvdb; + DPSI_DdeltaT = (DvGT_DdeltaT - (vGT/alpha)*Dalpha_DdeltaT + )/alpha - Dpsi_st0_DdeltaT; + + D = 2*(1+model->SOI3theta*vGBF)* + sqrt(1 + (2*Mmob*PSI)/(1+model->SOI3theta*vGBF)); + + DS_Dvgfb = (Mmob/D)*DPSI_Dvgfb - + (Mmob*PSI*(model->SOI3theta)/(D*(1+model->SOI3theta*vGBF))) + *(1-Dpsi_st0_Dvgfb); + DS_Dvsb = (Mmob/D)*DPSI_Dvsb - + (Mmob*PSI*(model->SOI3theta)/(D*(1+model->SOI3theta*vGBF))) + *((-sigma)-Dpsi_st0_Dvsb); + DS_Dvdb = (Mmob/D)*DPSI_Dvdb - + (Mmob*PSI*(model->SOI3theta)/(D*(1+model->SOI3theta*vGBF))) + *((sigma)-Dpsi_st0_Dvdb); + DS_DdeltaT = (Mmob/D)*DPSI_DdeltaT - + (Mmob*PSI*(model->SOI3theta)/(D*(1+model->SOI3theta*vGBF))) + *((-model->SOI3chiFB)-Dpsi_st0_DdeltaT) - + (PSI/D)*theta2*(model->SOI3k/(deltaT+here->SOI3temp) - + TVF/(600*(1+TVF))); + + Dpsi_sLsat_Dvgfb = Dpsi_st0_Dvgfb + + DPSI_Dvgfb/S - + PSI*DS_Dvgfb/(S*S); + Dpsi_sLsat_Dvsb = Dpsi_st0_Dvsb + + DPSI_Dvsb/S - + PSI*DS_Dvsb/(S*S); + Dpsi_sLsat_Dvdb = Dpsi_st0_Dvdb + + DPSI_Dvdb/S - + PSI*DS_Dvdb/(S*S); + Dpsi_sLsat_DdeltaT = Dpsi_st0_DdeltaT + + DPSI_DdeltaT/S - + PSI*DS_DdeltaT/(S*S); + } else { + Dpsi_sLsat_Dvgfb = Dpsi_st0_Dvgfb; + Dpsi_sLsat_Dvsb = Dpsi_st0_Dvsb; + Dpsi_sLsat_Dvdb = Dpsi_st0_Dvdb; + Dpsi_sLsat_DdeltaT = Dpsi_st0_DdeltaT; + } + + if (Esd0_trans) { + if (psi_s0_trans) { + tmp = (Esi0/(1+Esd0+Esi0))/(1+Esd0); + tmp1 = (Esi0/(1+Esd0+Esi0))*(Esd0/(1+Esd0)); + } else { + tmp = 1/(1+Esd0); + tmp1 = Esd0*tmp; + } + Dpsi_s0_Dvgfb = tmp*Dpsi_si0_Dvgfb + tmp1*Dpsi_sLsat_Dvgfb; + Dpsi_s0_Dvdb = tmp*Dpsi_si0_Dvdb + tmp1*Dpsi_sLsat_Dvdb; + Dpsi_s0_Dvsb = tmp*Dpsi_si0_Dvsb + tmp1*Dpsi_sLsat_Dvsb; + Dpsi_s0_DdeltaT = tmp*Dpsi_si0_DdeltaT + tmp1*Dpsi_sLsat_DdeltaT; + } else { + Dpsi_s0_Dvgfb = Dpsi_sLsat_Dvgfb; + Dpsi_s0_Dvdb = Dpsi_sLsat_Dvdb; + Dpsi_s0_Dvsb = Dpsi_sLsat_Dvsb; + Dpsi_s0_DdeltaT = Dpsi_sLsat_DdeltaT; + } + + if (EsdL_trans) { + if (psi_sL_trans) { + tmp = (EsiL/(1+EsdL+EsiL))/(1+EsdL); + tmp1 = (EsiL/(1+EsdL+EsiL))*(EsdL/(1+EsdL)); + } else { + tmp = 1/(1+EsdL); + tmp1 = EsdL*tmp; + } + Dpsi_sL_Dvgfb = tmp*Dpsi_siL_Dvgfb + tmp1*Dpsi_sLsat_Dvgfb; + Dpsi_sL_Dvdb = tmp*Dpsi_siL_Dvdb + tmp1*Dpsi_sLsat_Dvdb; + Dpsi_sL_Dvsb = tmp*Dpsi_siL_Dvsb + tmp1*Dpsi_sLsat_Dvsb; + Dpsi_sL_DdeltaT = tmp*Dpsi_siL_DdeltaT + tmp1*Dpsi_sLsat_DdeltaT; + } else { + Dpsi_sL_Dvgfb = Dpsi_sLsat_Dvgfb; + Dpsi_sL_Dvdb = Dpsi_sLsat_Dvdb; + Dpsi_sL_Dvsb = Dpsi_sLsat_Dvsb; + Dpsi_sL_DdeltaT = Dpsi_sLsat_DdeltaT; + } + +/* now for the whole kaboodle */ + + DfL_Dvgfb = psi_sL*(DvGT_Dvgfb + vt*Dalpha_Dvgfb) - + psi_sL*psi_sL*0.5*Dalpha_Dvgfb + + (vGBT - alpha*psi_sL)*Dpsi_sL_Dvgfb; + Df0_Dvgfb = psi_s0*(DvGT_Dvgfb + vt*Dalpha_Dvgfb) - + psi_s0*psi_s0*0.5*Dalpha_Dvgfb + + (vGBT - alpha*psi_s0)*Dpsi_s0_Dvgfb; + + DfL_Dvdb = psi_sL*(DvGT_Dvdb + vt*Dalpha_Dvdb) - + psi_sL*psi_sL*0.5*Dalpha_Dvdb + + (vGBT - alpha*psi_sL)*Dpsi_sL_Dvdb; + Df0_Dvdb = psi_s0*(DvGT_Dvdb + vt*Dalpha_Dvdb) - + psi_s0*psi_s0*0.5*Dalpha_Dvdb + + (vGBT - alpha*psi_s0)*Dpsi_s0_Dvdb; + + DfL_Dvsb = psi_sL*(DvGT_Dvsb + vt*Dalpha_Dvsb) - + psi_sL*psi_sL*0.5*Dalpha_Dvsb + + (vGBT - alpha*psi_sL)*Dpsi_sL_Dvsb; + Df0_Dvsb = psi_s0*(DvGT_Dvsb + vt*Dalpha_Dvsb) - + psi_s0*psi_s0*0.5*Dalpha_Dvsb + + (vGBT - alpha*psi_s0)*Dpsi_s0_Dvsb; + + DfL_DdeltaT = psi_sL*(DvGT_DdeltaT + vt*Dalpha_DdeltaT) - + psi_sL*psi_sL*0.5*Dalpha_DdeltaT + + (vGBT - alpha*psi_sL)*Dpsi_sL_DdeltaT; + Df0_DdeltaT = psi_s0*(DvGT_DdeltaT + vt*Dalpha_DdeltaT) - + psi_s0*psi_s0*0.5*Dalpha_DdeltaT + + (vGBT - alpha*psi_s0)*Dpsi_s0_DdeltaT; + +/* put them all together and what have you got ...? */ + + gmg = Beta*(DfL_Dvgfb - Df0_Dvgfb); + + gmd = Beta*(DfL_Dvdb - Df0_Dvdb); + + gms = Beta*(DfL_Dvsb - Df0_Dvsb); + + gmt = Beta*(DfL_DdeltaT - Df0_DdeltaT); + +/* End Intrinsic Electrical Bit */ + + +/* + * High Field Mobility Effects + */ + Fm = 1 + model->SOI3theta*(vg - 0.5*(psi_sL + psi_s0)) + + theta2 * (psi_sL - psi_s0); + ich0 = ich0/Fm; + here->SOI3ueff = here->SOI3ueff/Fm; + gmg = (gmg-ich0*(model->SOI3theta* + (1-0.5*(Dpsi_sL_Dvgfb + Dpsi_s0_Dvgfb)) + + theta2*(Dpsi_sL_Dvgfb - Dpsi_s0_Dvgfb) + ) + )/Fm; + gmd = (gmd-ich0*(model->SOI3theta* + (sigma-0.5*(Dpsi_sL_Dvdb + Dpsi_s0_Dvdb)) + + theta2*(Dpsi_sL_Dvdb - Dpsi_s0_Dvdb) + ) + )/Fm; + gms = (gms-ich0*(model->SOI3theta* + (-sigma-0.5*(Dpsi_sL_Dvsb + Dpsi_s0_Dvsb)) + + theta2*(Dpsi_sL_Dvsb - Dpsi_s0_Dvsb) + ) + )/Fm; + gmt = (gmt-ich0*(model->SOI3theta* + ((-model->SOI3chiFB)-0.5*(Dpsi_sL_DdeltaT + Dpsi_s0_DdeltaT) + ) + + theta2*(Dpsi_sL_DdeltaT - Dpsi_s0_DdeltaT - + (psi_sL - psi_s0)*(model->SOI3k/(deltaT+here->SOI3temp) - + TVF/(600*(1+TVF)) + ) + ) + ) + )/Fm; + +/* + * End High Field Mobility Effects + */ + +/* Now to define bits which affect the drain region */ +/* + * Channel Length Modulation + */ + + Vm = (here->SOI3mode*vds) + psi_s0 - psi_sLsat; + if (model->SOI3useLAMBDA) { + Vmx = Vm; + DVmx_Dvgfb = (Dpsi_s0_Dvgfb - Dpsi_sLsat_Dvgfb); + DVmx_Dvdb = (1 + Dpsi_s0_Dvdb - Dpsi_sLsat_Dvdb); + DVmx_Dvsb = (Dpsi_s0_Dvsb - Dpsi_sLsat_Dvsb - 1); + DVmx_DdeltaT = (Dpsi_s0_DdeltaT - Dpsi_sLsat_DdeltaT); + ld = model->SOI3lambda*Vmx; + tmp = model->SOI3lambda; + } else { + if (Vm > (vt*MAX_EXP_ARG)) { + Vmx = Vm; + tmp = 1; + } else { + Em = exp(Vm/vt); + Vmx = vt * log(1 + Em) + 1e-25; + tmp = (Em/(1+Em)); + } + DVmx_Dvgfb = tmp * (Dpsi_s0_Dvgfb - Dpsi_sLsat_Dvgfb); + DVmx_Dvdb = tmp * (1 + Dpsi_s0_Dvdb - Dpsi_sLsat_Dvdb); + DVmx_Dvsb = tmp * (Dpsi_s0_Dvsb - Dpsi_sLsat_Dvsb - 1); + DVmx_DdeltaT = tmp * (Dpsi_s0_DdeltaT - Dpsi_sLsat_DdeltaT); + ld = model->SOI3lx * log(1 + Vmx/model->SOI3vp); + tmp = model->SOI3lx/(model->SOI3vp + Vmx); + } + + Y = 1 + (ld/EffectiveLength); + + Dld_Dvgfb = tmp * DVmx_Dvgfb; + Dld_Dvdb = tmp * DVmx_Dvdb; + Dld_Dvsb = tmp * DVmx_Dvsb; + Dld_DdeltaT = tmp * DVmx_DdeltaT; + + gmg = gmg * Y + (ich0/EffectiveLength) * Dld_Dvgfb; + gmd = gmd * Y + (ich0/EffectiveLength) * Dld_Dvdb; + gms = gms * Y + (ich0/EffectiveLength) * Dld_Dvsb; + gmt = gmt * Y + (ich0/EffectiveLength) * Dld_DdeltaT; + + ich0 = ich0 * Y; + /* Need to do ich0 last as its old value is needed for gds */ + +/* + * End Channel Length Modulation + */ + + here->SOI3gdsnotherm = here->SOI3gds; + + /************** Thermal Mobility Stuff **************/ + + /* thermal effect on intrinsic electrical circuit */ + idrain = ich0 * TMF; /* idrain has new value now */ + here->SOI3ueff *= TMF; + gmg = gmg * TMF; +/* here->SOI3gmb = here->SOI3gmb * TMF; */ + gms = gms * TMF; + gmd = gmd * TMF; + /* deltaT is indpt voltage now */ + gmt = gmt*TMF - (model->SOI3k/(deltaT+here->SOI3temp)) * idrain; + ich0 = idrain; + + /* + * finished intrinsic electrical + */ +/* + * Impact Ionisation current sources + */ + + Vm1 = (here->SOI3mode*vds) + model->SOI3eta*(psi_s0 - psi_sLsat); + if (Vm1 > (vt*MAX_EXP_ARG)) { + Vm1x = Vm1; + tmp = 1; + } else { + Em1 = exp(MIN(MAX_EXP_ARG,Vm1/vt)); + Vm1x = vt * log(1 + Em1) + 1e-25; + tmp = (Em1/(1+Em1)); + } + DVm1x_Dvgfb = tmp*model->SOI3eta*(Dpsi_s0_Dvgfb - Dpsi_sLsat_Dvgfb); + DVm1x_Dvdb = tmp*(model->SOI3eta*(Dpsi_s0_Dvdb - Dpsi_sLsat_Dvdb) + 1); + DVm1x_Dvsb = tmp*(model->SOI3eta*(Dpsi_s0_Dvsb - Dpsi_sLsat_Dvsb) - 1); + DVm1x_DdeltaT = tmp*model->SOI3eta*(Dpsi_s0_DdeltaT - Dpsi_sLsat_DdeltaT); + + vgeff = vg - vsb - eta_s*here->SOI3tPhi - gamma*sqrt(here->SOI3tPhi); + lm = model->SOI3lm + model->SOI3lm1*(here->SOI3mode*vds-vgeff) + + model->SOI3lm2*(here->SOI3mode*vds-vgeff)*(here->SOI3mode*vds-vgeff); + Elm = exp(MIN(MAX_EXP_ARG,lm/MAX(1e-10,(model->SOI3lm/40)))); + lmeff = (model->SOI3lm/40)*log(1+Elm); + betaM = 100*(model->SOI3beta0 + model->SOI3chibeta*deltaT); + EM = exp(MIN(MAX_EXP_ARG,-(lmeff*betaM)/Vm1x)); + Mminus1 = (100*model->SOI3alpha0/betaM) * Vm1x * EM; + if (here->SOI3mode==1) { + here->SOI3iMdb=Mminus1*ich0; + here->SOI3iMsb=0; + } else { + here->SOI3iMsb=Mminus1*ich0; + here->SOI3iMdb=0; + } + tmp = (Elm/(1+Elm))* + (model->SOI3lm1 + 2*model->SOI3lm2*(here->SOI3mode*vds-vgeff)); + Dlm_Dvgfb = -tmp; + Dlm_Dvdb = tmp*(1-sigma); + Dlm_Dvsb = tmp*(sigma); + Dlm_DdeltaT = tmp*(model->SOI3chiFB); + tmp = (ich0/Vm1x); + tmp1 = (1+(lmeff*betaM/Vm1x)); + gMg = Mminus1 * (gmg + tmp * (tmp1*DVm1x_Dvgfb - betaM*Dlm_Dvgfb)); + gMd = Mminus1 * (gmd + tmp * (tmp1*DVm1x_Dvdb - betaM*Dlm_Dvdb)); + gMs = Mminus1 * (gms + tmp * (tmp1*DVm1x_Dvsb - betaM*Dlm_Dvsb)); + + here->SOI3gMmf = gMg; + here->SOI3gMmb = 0; + here->SOI3gMmbs= -(gMs + gMg + gMd); + here->SOI3gMd = gMd; + here->SOI3gMdeltaT = Mminus1*(gmt+ + tmp*(tmp1*DVm1x_DdeltaT - betaM*Dlm_DdeltaT - + lmeff*model->SOI3chibeta*100) + - (ich0*model->SOI3chibeta*100/betaM) + ); + +/* + * End Impact Ionisation current sources + */ + +/***** time to convert to conventional names for (trans)conductances *****/ + + here->SOI3gmf = gmg; + here->SOI3gmb = 0; /* FOR NOW */ + here->SOI3gmbs = -(gms + gmg + gmd); + here->SOI3gds = gmd; + here->SOI3gt = gmt; + vdsat = psi_sLsat - psi_s0; + + /* now for thermal subcircuit values */ + tmp = (here->SOI3drainConductance==0?0:(1/(here->SOI3drainConductance))); + tmp += (here->SOI3sourceConductance==0?0:(1/(here->SOI3sourceConductance))); + /* tmp = RS+RD */ + here->SOI3iPt = (here->SOI3mode*vds + idrain*tmp)*idrain; + here->SOI3gPmf = (here->SOI3mode*vds + 2*idrain*tmp)*here->SOI3gmf; + here->SOI3gPmb = (here->SOI3mode*vds + 2*idrain*tmp)*here->SOI3gmb; + here->SOI3gPmbs = (here->SOI3mode*vds + 2*idrain*tmp)*here->SOI3gmbs; + here->SOI3gPds = idrain + (here->SOI3mode*vds + 2*idrain*tmp)*here->SOI3gds; + here->SOI3gPdT = (here->SOI3mode*vds + 2*idrain*tmp)*here->SOI3gt; + + /* JimB - 15/9/99 */ + /* Code for multiple thermal time constants. Start by moving all */ + /* rt constants into arrays. */ + rtargs[0]=here->SOI3rt; + rtargs[1]=here->SOI3rt1; + rtargs[2]=here->SOI3rt2; + rtargs[3]=here->SOI3rt3; + rtargs[4]=here->SOI3rt4; + + /* Set all conductance components to zero. */ + grt[0]=grt[1]=grt[2]=grt[3]=grt[4]=0.0; + /* Now calculate conductances from rt. */ + /* Don't need to worry about divide by zero when calculating */ + /* grt components, as soi3setup() only creates a thermal node */ + /* if corresponding rt is greater than zero. */ + for(tnodeindex=0;tnodeindexSOI3numThermalNodes;tnodeindex++) + { + grt[tnodeindex]=1/rtargs[tnodeindex]; + } + /* End JimB */ + +/* now end nasty trick - if vsb and vdb have been switched, reverse them back */ + if (here->SOI3mode == -1) + { + tmp = vsb; + vsb = vdb; + vdb = tmp; + } + + /* + * bulk-source and bulk-drain diodes + * includes parasitic BJT and 2nd diode + * + */ + + tmp = here->SOI3temp+deltaT; + tmp1 = here->SOI3temp + model->SOI3dvt * deltaT; + vT = CONSTKoverQ * tmp1; + + if ((model->SOI3betaEXP) != 1.0) + { + if ((model->SOI3betaEXP) != 2.0) + { + BetaBJTeff = model->SOI3betaBJT * + exp(-(model->SOI3betaEXP)*logL); + } + else + { + BetaBJTeff = model->SOI3betaBJT/ + (EffectiveLength*EffectiveLength); + } + } + else + { + BetaBJTeff = model->SOI3betaBJT/EffectiveLength; + } + + alphaBJT = BetaBJTeff/(BetaBJTeff + 1); + + EchiD = exp(MIN(MAX_EXP_ARG, + (model->SOI3chid * deltaT)/(here->SOI3temp*tmp) + ) + ); + EchiD1 = exp(MIN(MAX_EXP_ARG, + (model->SOI3chid1 * deltaT)/(here->SOI3temp*tmp) + ) + ); + ISts = SourceSatCur*EchiD; + IS1ts = SourceSatCur1*EchiD1; + + evbs = exp(MIN(MAX_EXP_ARG,vbs/((model->SOI3etad)*vT))); + evbs1 = exp(MIN(MAX_EXP_ARG,vbs/((model->SOI3etad1)*vT))); +/* First Junction */ + here->SOI3ibs = ISts * (evbs-1); + here->SOI3gbs = ISts*evbs/((model->SOI3etad)*vT); + here->SOI3gbsT = ISts*((evbs-1)*model->SOI3chid/(tmp*tmp) - + evbs*vbs*model->SOI3dvt/((model->SOI3etad)*vT*tmp1)); +/* Now Bipolar */ + here->SOI3iBJTdb = alphaBJT * ISts * (evbs-1); + here->SOI3gBJTdb_bs = alphaBJT * here->SOI3gbs; + here->SOI3gBJTdb_deltaT = alphaBJT * here->SOI3gbsT; +/* Now second junction and gmin */ + /* JimB - make gmin code consistent */ + here->SOI3ibs += IS1ts * (evbs1-1) + ckt->CKTgmin*vbs; + here->SOI3gbs += IS1ts*evbs1/((model->SOI3etad1)*vT) + ckt->CKTgmin; + /* End JimB */ + here->SOI3gbsT += IS1ts*((evbs1-1)*model->SOI3chid1/(tmp*tmp) - + evbs1*vbs*model->SOI3dvt/((model->SOI3etad1)*vT*tmp1) + ); + + + IStd = DrainSatCur*EchiD; + IS1td = DrainSatCur1*EchiD1; + + evbd = exp(MIN(MAX_EXP_ARG,vbd/((model->SOI3etad)*vT))); + evbd1 = exp(MIN(MAX_EXP_ARG,vbd/((model->SOI3etad1)*vT))); +/* First Junction */ + here->SOI3ibd = IStd *(evbd-1); + here->SOI3gbd = IStd*evbd/((model->SOI3etad)*vT); + here->SOI3gbdT = IStd*((evbd-1)*model->SOI3chid/(tmp*tmp) - + evbd*vbd*model->SOI3dvt/((model->SOI3etad)*vT*tmp1)); +/* Now Bipolar */ + here->SOI3iBJTsb = alphaBJT * IStd *(evbd-1); + here->SOI3gBJTsb_bd = alphaBJT * here->SOI3gbd; + here->SOI3gBJTsb_deltaT = alphaBJT * here->SOI3gbdT; +/* Now second junction and gmin */ + /* JimB - make gmin code consistent */ + here->SOI3ibd += IS1td *(evbd1-1) + ckt->CKTgmin*vbd; + here->SOI3gbd += IS1td*evbd1/((model->SOI3etad1)*vT) + ckt->CKTgmin; + /* End JimB */ + here->SOI3gbdT += IS1td*((evbd1-1)*model->SOI3chid1/(tmp*tmp) - + evbd1*vbd*model->SOI3dvt/((model->SOI3etad1)*vT*tmp1) + ); + + +/* initialise von for voltage limiting purposes */ + von = (here->SOI3tVfbF * model->SOI3type) + psi_s0 + gamma*sqt0 + + sigma*(here->SOI3mode*vds) + - model->SOI3chiFB*deltaT; + +/* finally if we're going to do charge/capacitance calcs, store + * some stuff to pass to function. Need to use arrays 'cos there's + * a limit to how many parameters you can pass in standard C + */ + paramargs[0] = here->SOI3w*model->SOI3frontOxideCapFactor; + paramargs[1] = EffectiveLength; + paramargs[2] = gamma; + paramargs[3] = eta_s; + paramargs[4] = vt; + paramargs[5] = delta; + paramargs[6] = here->SOI3w*model->SOI3backOxideCapFactor; + paramargs[7] = sigma; + paramargs[8] = model->SOI3chiFB; + paramargs[9] = model->SOI3satChargeShareFactor; + Bfargs[0] = Bf; + Bfargs[1] = pDBf_Dpsi_st0; + alpha_args[0] = alpha; + alpha_args[1] = Dalpha_Dvgfb; + alpha_args[2] = Dalpha_Dvdb; + alpha_args[3] = Dalpha_Dvsb; + alpha_args[4] = Dalpha_DdeltaT; + psi_st0args[0] = psi_st0; + psi_st0args[1] = Dpsi_st0_Dvgfb; + psi_st0args[2] = Dpsi_st0_Dvdb; + psi_st0args[3] = Dpsi_st0_Dvsb; + psi_st0args[4] = Dpsi_st0_DdeltaT; + vGTargs[0] = vGT; + vGTargs[1] = DvGT_Dvgfb; + vGTargs[2] = DvGT_Dvdb; + vGTargs[3] = DvGT_Dvsb; + vGTargs[4] = DvGT_DdeltaT; + psi_sLargs[0] = psi_sL; + psi_sLargs[1] = Dpsi_sL_Dvgfb; + psi_sLargs[2] = Dpsi_sL_Dvdb; + psi_sLargs[3] = Dpsi_sL_Dvsb; + psi_sLargs[4] = Dpsi_sL_DdeltaT; + psi_s0args[0] = psi_s0; + psi_s0args[1] = Dpsi_s0_Dvgfb; + psi_s0args[2] = Dpsi_s0_Dvdb; + psi_s0args[3] = Dpsi_s0_Dvsb; + psi_s0args[4] = Dpsi_s0_DdeltaT; + ldargs[0] = ld; + ldargs[1] = Dld_Dvgfb; + ldargs[2] = Dld_Dvdb; + ldargs[3] = Dld_Dvsb; + ldargs[4] = Dld_DdeltaT; +/* debug stuff */ + here->SOI3debug1 = psi_sL; + here->SOI3debug2 = psi_s0; + here->SOI3debug3 = fL; + here->SOI3debug4 = f0; + here->SOI3debug5 = gmd; + here->SOI3debug6 = gms; + + } /* end block */ + + +/* + +*/ + +#ifdef DETAILPROF +asm(" .globl mosptg"); +asm("mosptg:"); +#endif /*DETAILPROF*/ + + /* now deal with n vs p polarity */ + + here->SOI3von = model->SOI3type * von; + here->SOI3vdsat = model->SOI3type * vdsat; + /* line 490 */ + /* + * COMPUTE EQUIVALENT DRAIN CURRENT SOURCE + * + OLD here->SOI3id=here->SOI3mode * idrain - here->SOI3ibd; + */ + if (here->SOI3mode==1) { + here->SOI3id= idrain - here->SOI3ibd + here->SOI3iMdb + + here->SOI3iBJTdb; + } else { + here->SOI3id= -idrain - here->SOI3ibd + + here->SOI3iBJTdb; + } + + + /* JimB - 4/1/99 */ + /* Tidy up depletion capacitance code, and remove unwanted */ + /* compile options. */ + + 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. This is because most users use the default + * grading coefficients of 0.5, and sqrt is MUCH faster than + * an exp(log()), so we use this special case to buy time - + * as much as 10% of total job time! + */ + + /******** Bulk-source depletion capacitance ********/ + +#ifdef CAPBYPASS + if(((ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) || + fabs(delvbs) >= ckt->CKTreltol * MAX(fabs(vbs), + fabs(*(ckt->CKTstate0+here->SOI3vbs)))+ + ckt->CKTvoltTol)) +#endif /*CAPBYPASS*/ + { + if(here->SOI3Cbs != 0) + { + if (vbs < here->SOI3tDepCap) + { + arg=1-vbs/here->SOI3tBulkPot; + if(model->SOI3bulkJctSideGradingCoeff == 0.5) + { + sarg = 1/sqrt(arg); + } + else + { + sarg = exp(-model->SOI3bulkJctSideGradingCoeff* + log(arg)); + } + *(ckt->CKTstate0 + here->SOI3qbs) = + here->SOI3tBulkPot*(here->SOI3Cbs* + (1-arg*sarg)/(1-model->SOI3bulkJctSideGradingCoeff)); + here->SOI3capbs=here->SOI3Cbs*sarg; + } + else + { + *(ckt->CKTstate0 + here->SOI3qbs) = here->SOI3f4s + + vbs*(here->SOI3f2s+vbs*(here->SOI3f3s/2)); + here->SOI3capbs=here->SOI3f2s+here->SOI3f3s*vbs; + } + } + else + { + *(ckt->CKTstate0 + here->SOI3qbs) = 0; + here->SOI3capbs=0; + } + } + + /******** End bulk-source depletion capcitance ********/ + + /******** Bulk-drain depletion capacitance ********/ + +#ifdef CAPBYPASS + if(((ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) || + fabs(delvbd) >= ckt->CKTreltol * MAX(fabs(vbd), + fabs(*(ckt->CKTstate0+here->SOI3vbd)))+ + ckt->CKTvoltTol)) +#endif /*CAPBYPASS*/ + { + if(here->SOI3Cbd != 0) + { + if (vbd < here->SOI3tDepCap) + { + arg=1-vbd/here->SOI3tBulkPot; + if(model->SOI3bulkJctSideGradingCoeff == 0.5) + { + sarg = 1/sqrt(arg); + } + else + { + sarg = exp(-model->SOI3bulkJctSideGradingCoeff* + log(arg)); + } + *(ckt->CKTstate0 + here->SOI3qbd) = + here->SOI3tBulkPot*(here->SOI3Cbd* + (1-arg*sarg)/(1-model->SOI3bulkJctSideGradingCoeff)); + here->SOI3capbd=here->SOI3Cbd*sarg; + } + else + { + *(ckt->CKTstate0 + here->SOI3qbd) = here->SOI3f4d + + vbd * (here->SOI3f2d + vbd *(here->SOI3f3d/2)); + here->SOI3capbd=here->SOI3f2d + vbd * here->SOI3f3d; + } + } + else + { + *(ckt->CKTstate0 + here->SOI3qbd) = 0; + here->SOI3capbd = 0; + } + } + + /******** End bulk-drain depletion capacitance ********/ + + +/* Need to work out charge on thermal cap */ + *(ckt->CKTstate0 + here->SOI3qt) = here->SOI3ct * deltaT1; + *(ckt->CKTstate0 + here->SOI3qt1) = here->SOI3ct1 * deltaT2; + *(ckt->CKTstate0 + here->SOI3qt2) = here->SOI3ct2 * deltaT3; + *(ckt->CKTstate0 + here->SOI3qt3) = here->SOI3ct3 * deltaT4; + *(ckt->CKTstate0 + here->SOI3qt4) = here->SOI3ct4 * deltaT5; +/* ct is constant, so integral is trivial */ +/* + +*/ + +#ifdef DETAILPROF +asm(" .globl mospth"); +asm("mospth:"); +#endif /*DETAILPROF*/ + + if ( (ckt->CKTmode & MODETRAN) || ( (ckt->CKTmode&MODEINITTRAN) + && !(ckt->CKTmode&MODEUIC)) ) { + /* (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,&ieq,here->SOI3capbd, + here->SOI3qbd); + if(error) return(error); + here->SOI3gbd += geq; + here->SOI3ibd += *(ckt->CKTstate0 + here->SOI3iqbd); + here->SOI3id -= *(ckt->CKTstate0 + here->SOI3iqbd); + error = NIintegrate(ckt,&geq,&ieq,here->SOI3capbs, + here->SOI3qbs); + if(error) return(error); + here->SOI3gbs += geq; + here->SOI3ibs += *(ckt->CKTstate0 + here->SOI3iqbs); + } + } +/* + +*/ + +#ifdef DETAILPROF +asm(" .globl mospti"); +asm("mospti:"); +#endif /*DETAILPROF*/ + +/* if(SenCond) goto next2; */ + + + /* + * check convergence + */ + if ( (here->SOI3off == 0) || + (!(ckt->CKTmode & (MODEINITFIX|MODEINITSMSIG))) ){ + if (Check == 1) { + ckt->CKTnoncon++; + } + } +/* + +*/ + /* + * new capacitor model + */ + if ((ckt->CKTmode & (MODETRAN | MODEAC | MODEINITSMSIG)) || + ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) + ){ + /* + * calculate charges and capacitances + */ + /* + * Partially Depleted model => back surface neglected + * so back capacitances are ignored. + */ + /* + * All the args assume vsb and vdb are 'correct' + * so must make sure we're getting right values + * back. + */ + if (here->SOI3mode > 0) + { + SOI3cap((vgbb-here->SOI3tVfbB),(here->SOI3tPhi + vsb),model->SOI3gammaB, + paramargs, + Bfargs,alpha_args,psi_st0args, + vGTargs, + psi_sLargs,psi_s0args, + ldargs, + &qgatef,&qbody,&qdrn,&qgateb, + &cgfgf,&cgfd,&cgfs,&cgfdeltaT, + &cbgf,&cbd,&cbs,&cbdeltaT,&cbgb, + &cdgf,&cdd,&cds,&cddeltaT, + &cgbgb,&cgbsb); + csgf = -(cgfgf + cdgf + cbgf); + csd = -(cgfd + cdd + cbd); + css = -(cgfs + cds + cbs); + csdeltaT = -(cgfdeltaT + cddeltaT + cbdeltaT); + cgbdb = 0; + } + else + { + SOI3cap((vgbb-here->SOI3tVfbB),(here->SOI3tPhi + vdb),model->SOI3gammaB, + paramargs, + Bfargs,alpha_args,psi_st0args, + vGTargs, + psi_sLargs,psi_s0args, + ldargs, + &qgatef,&qbody,&qsrc,&qgateb, + &cgfgf,&cgfs,&cgfd,&cgfdeltaT, + &cbgf,&cbs,&cbd,&cbdeltaT,&cbgb, + &csgf,&css,&csd,&csdeltaT, + &cgbgb,&cgbdb); + cdgf = -(cgfgf + csgf + cbgf); + cdd = -(cgfd + csd + cbd); + cds = -(cgfs + css + cbs); + cddeltaT = -(cgfdeltaT + csdeltaT + cbdeltaT); + cgbsb = 0; + } + + *(ckt->CKTstate0 + here->SOI3cgfgf) = cgfgf; + *(ckt->CKTstate0 + here->SOI3cgfd) = cgfd; + *(ckt->CKTstate0 + here->SOI3cgfs) = cgfs; + *(ckt->CKTstate0 + here->SOI3cgfdeltaT) = cgfdeltaT; + + *(ckt->CKTstate0 + here->SOI3csgf) = csgf; + *(ckt->CKTstate0 + here->SOI3csd) = csd; + *(ckt->CKTstate0 + here->SOI3css) = css; + *(ckt->CKTstate0 + here->SOI3csdeltaT) = csdeltaT; + + *(ckt->CKTstate0 + here->SOI3cdgf) = cdgf; + *(ckt->CKTstate0 + here->SOI3cdd) = cdd; + *(ckt->CKTstate0 + here->SOI3cds) = cds; + *(ckt->CKTstate0 + here->SOI3cddeltaT) = cddeltaT; + + *(ckt->CKTstate0 + here->SOI3cgbgb) = cgbgb; + *(ckt->CKTstate0 + here->SOI3cgbsb) = cgbsb; + *(ckt->CKTstate0 + here->SOI3cgbdb) = cgbdb; +/* got charges and caps now, must get equiv conductances/current sources + * but first work out charge and caps for BJT charge storage + */ + + if ((model->SOI3tauEXP) != 2.0) + { + if ((model->SOI3tauEXP) != 1.0) + { + tauFBJTeff = model->SOI3tauFBJT * + exp((model->SOI3tauEXP)*logL); + tauRBJTeff = model->SOI3tauRBJT * + exp((model->SOI3tauEXP)*logL); + } + else + { + tauFBJTeff = model->SOI3tauFBJT*EffectiveLength; + tauRBJTeff = model->SOI3tauRBJT*EffectiveLength; + } + } + else + { + tauFBJTeff = model->SOI3tauFBJT*(EffectiveLength*EffectiveLength); + tauRBJTeff = model->SOI3tauRBJT*(EffectiveLength*EffectiveLength); + } + + *(ckt->CKTstate0 + here->SOI3qBJTbs) = tauFBJTeff * + here->SOI3iBJTdb; + *(ckt->CKTstate0 + here->SOI3cBJTbsbs) = tauFBJTeff * + here->SOI3gBJTdb_bs; + *(ckt->CKTstate0 + here->SOI3cBJTbsdeltaT) = tauFBJTeff * + here->SOI3gBJTdb_deltaT; + + *(ckt->CKTstate0 + here->SOI3qBJTbd) = tauRBJTeff * + here->SOI3iBJTsb; + *(ckt->CKTstate0 + here->SOI3cBJTbdbd) = tauRBJTeff * + here->SOI3gBJTsb_bd; + *(ckt->CKTstate0 + here->SOI3cBJTbddeltaT) = tauRBJTeff * + here->SOI3gBJTsb_deltaT; + } /* end of charge/cap calculations */ + +/* + +*/ +#ifdef DETAILPROF +asm(" .globl mosptj"); +asm("mosptj:"); +#endif /*DETAILPROF*/ + + /* save things away for next time */ + + *(ckt->CKTstate0 + here->SOI3vbs) = vbs; + *(ckt->CKTstate0 + here->SOI3vbd) = vbd; + *(ckt->CKTstate0 + here->SOI3vgfs) = vgfs; + *(ckt->CKTstate0 + here->SOI3vgbs) = vgbs; + *(ckt->CKTstate0 + here->SOI3vds) = vds; + *(ckt->CKTstate0 + here->SOI3deltaT) = deltaT; + *(ckt->CKTstate0 + here->SOI3deltaT1) = deltaT1; + *(ckt->CKTstate0 + here->SOI3deltaT2) = deltaT2; + *(ckt->CKTstate0 + here->SOI3deltaT3) = deltaT3; + *(ckt->CKTstate0 + here->SOI3deltaT4) = deltaT4; + *(ckt->CKTstate0 + here->SOI3deltaT5) = deltaT5; + *(ckt->CKTstate0 + here->SOI3idrain) = idrain; + + if((!(ckt->CKTmode & (MODETRAN | MODEAC))) && + ((!(ckt->CKTmode & MODETRANOP)) || + (!(ckt->CKTmode & MODEUIC))) && (!(ckt->CKTmode + & MODEINITSMSIG))) goto bypass2; +bypass1: + + if (here->SOI3mode>0) { + Frontcapargs[0] = FrontGateDrainOverlapCap; + Frontcapargs[1] = FrontGateSourceOverlapCap; + Frontcapargs[2] = FrontGateBulkOverlapCap; + Frontcapargs[3] = vgfd; + Frontcapargs[4] = vgfs; + Frontcapargs[5] = vgfb; + Backcapargs[0] = BackGateDrainOverlapCap; + Backcapargs[1] = BackGateSourceOverlapCap; + Backcapargs[2] = BackGateBulkOverlapCap; + Backcapargs[3] = vgbd; + Backcapargs[4] = vgbs; + Backcapargs[5] = vgbb; + SOI3capEval(ckt, + Frontcapargs, + Backcapargs, + cgfgf,cgfd,cgfs,cgfdeltaT, + cdgf,cdd,cds,cddeltaT, + csgf,csd,css,csdeltaT, + cbgf,cbd,cbs,cbdeltaT,cbgb, + cgbgb,cgbsb, + &gcgfgf,&gcgfd,&gcgfs,&gcgfdeltaT, + &gcdgf,&gcdd,&gcds,&gcddeltaT, + &gcsgf,&gcsd,&gcss,&gcsdeltaT, + &gcbgf,&gcbd,&gcbs,&gcbdeltaT,&gcbgb, + &gcgbgb,&gcgbsb,&gcgbdb, + &gcgbs0,&gcgbd0, + &qgatef,&qbody,&qdrn,&qsrc,&qgateb); + } else { + Frontcapargs[0] = FrontGateSourceOverlapCap; + Frontcapargs[1] = FrontGateDrainOverlapCap; + Frontcapargs[2] = FrontGateBulkOverlapCap; + Frontcapargs[3] = vgfs; + Frontcapargs[4] = vgfd; + Frontcapargs[5] = vgfb; + Backcapargs[0] = BackGateSourceOverlapCap; + Backcapargs[1] = BackGateDrainOverlapCap; + Backcapargs[2] = BackGateBulkOverlapCap; + Backcapargs[3] = vgbs; + Backcapargs[4] = vgbd; + Backcapargs[5] = vgbb; + SOI3capEval(ckt, + Frontcapargs, + Backcapargs, + cgfgf,cgfs,cgfd,cgfdeltaT, + csgf,css,csd,csdeltaT, + cdgf,cds,cdd,cddeltaT, + cbgf,cbs,cbd,cbdeltaT,cbgb, + cgbgb,cgbdb, + &gcgfgf,&gcgfs,&gcgfd,&gcgfdeltaT, + &gcsgf,&gcss,&gcsd,&gcsdeltaT, + &gcdgf,&gcds,&gcdd,&gcddeltaT, + &gcbgf,&gcbs,&gcbd,&gcbdeltaT,&gcbgb, + &gcgbgb,&gcgbdb,&gcgbsb, + &gcgbd0,&gcgbs0, + &qgatef,&qbody,&qsrc,&qdrn,&qgateb); + } + ag0 = ckt->CKTag[0]; + gcBJTbsbs = ag0 * *(ckt->CKTstate0+here->SOI3cBJTbsbs); + gcBJTbsdeltaT = ag0 * *(ckt->CKTstate0+here->SOI3cBJTbsdeltaT); + gcBJTbdbd = ag0 * *(ckt->CKTstate0+here->SOI3cBJTbdbd); + gcBJTbddeltaT = ag0 * *(ckt->CKTstate0+here->SOI3cBJTbddeltaT); + + if (ByPass) goto line860; /* already stored charges */ + + *(ckt->CKTstate0 + here->SOI3qgf) = qgatef; + *(ckt->CKTstate0 + here->SOI3qd) = qdrn; + *(ckt->CKTstate0 + here->SOI3qs) = qsrc; + *(ckt->CKTstate0 + here->SOI3qgb) = qgateb; + /* NB, we've kept charge/cap associated with diodes separately */ + + if((!(ckt->CKTmode & (MODEAC | MODETRAN))) && + (ckt->CKTmode & MODETRANOP ) && (ckt->CKTmode & + MODEUIC )) goto bypass2; + + /* store small signal parameters */ + if(ckt->CKTmode & MODEINITSMSIG ) { + *(ckt->CKTstate0+here->SOI3cgfgf) = cgfgf; + *(ckt->CKTstate0+here->SOI3cgfd) = cgfd; + *(ckt->CKTstate0+here->SOI3cgfs) = cgfs; + *(ckt->CKTstate0+here->SOI3cgfdeltaT) = cgfdeltaT; + *(ckt->CKTstate0+here->SOI3cdgf) = cdgf; + *(ckt->CKTstate0+here->SOI3cdd) = cdd; + *(ckt->CKTstate0+here->SOI3cds) = cds; + *(ckt->CKTstate0+here->SOI3cddeltaT) = cddeltaT; + *(ckt->CKTstate0+here->SOI3csgf) = csgf; + *(ckt->CKTstate0+here->SOI3csd) = csd; + *(ckt->CKTstate0+here->SOI3css) = css; + *(ckt->CKTstate0+here->SOI3csdeltaT) = csdeltaT; + *(ckt->CKTstate0+here->SOI3cgbgb) = cgbgb; + *(ckt->CKTstate0+here->SOI3cgbsb) = cgbsb; + *(ckt->CKTstate0+here->SOI3cgbdb) = cgbdb; + goto End; + } + + if (ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->SOI3qgf) = + *(ckt->CKTstate0 + here->SOI3qgf); + *(ckt->CKTstate1 + here->SOI3qd) = + *(ckt->CKTstate0 + here->SOI3qd); + *(ckt->CKTstate1 + here->SOI3qs) = + *(ckt->CKTstate0 + here->SOI3qs); + *(ckt->CKTstate1 + here->SOI3qgb) = + *(ckt->CKTstate0 + here->SOI3qgb); + *(ckt->CKTstate1 + here->SOI3qBJTbs) = + *(ckt->CKTstate0 + here->SOI3qBJTbs); + *(ckt->CKTstate1 + here->SOI3qBJTbd) = + *(ckt->CKTstate0 + here->SOI3qBJTbd); + } + + /* + * numerical integration of intrinsic caps + * and BJT caps + */ + error = NIintegrate(ckt,&geq,&ieq,0.0,here->SOI3qgf); + if(error) return(error); + error = NIintegrate(ckt,&geq,&ieq,0.0,here->SOI3qd); + if(error) return(error); + error = NIintegrate(ckt,&geq,&ieq,0.0,here->SOI3qs); + if(error) return(error); + error = NIintegrate(ckt,&geq,&ieq,0.0,here->SOI3qgb); + if(error) return(error); + + error = NIintegrate(ckt,&geq,&ieq,0.0,here->SOI3qBJTbs); + if(error) return(error); + error = NIintegrate(ckt,&geq,&ieq,0.0,here->SOI3qBJTbd); + if(error) return(error); + goto line860; + +bypass2: + + /* + * initialize to zero charge conductances + * and current (DC and TRANOP) + */ + ieqqgf = ieqqd = ieqqs = ieqqgb = 0.0; + gcgfgf = gcgfd = gcgfs = gcgfdeltaT = 0.0; + gcdgf = gcdd = gcds = gcddeltaT = 0.0; + gcsgf = gcsd = gcss = gcsdeltaT = 0.0; + gcbgf = gcbd = gcbs = gcbdeltaT = gcbgb = 0.0; + gcgbgb = gcgbsb = gcgbdb = 0.0; + gcgbd0 = gcgbs0 = 0.0; + gct[0]=gct[1]=gct[2]=gct[3]=gct[4]=0.0; + ieqct=ieqct1=ieqct2=ieqct3=ieqct4=0.0; + ieqqBJTbs = ieqqBJTbd = 0.0; + gcBJTbsbs = gcBJTbsdeltaT = gcBJTbdbd = gcBJTbddeltaT = 0.0; + goto LoadUp; + +line860: + + /* evaluate equivalent charge currents */ + + ieqqgf = *(ckt->CKTstate0 + here->SOI3iqgf) - + gcgfgf * vgfb - gcgfd * vdb - gcgfs * vsb - gcgfdeltaT * deltaT; + ieqqd = *(ckt->CKTstate0 + here->SOI3iqd) - + gcdgf * vgfb - gcdd * vdb - gcds * vsb - gcddeltaT * deltaT + + gcgbd0 * vgbd; + ieqqs = *(ckt->CKTstate0 + here->SOI3iqs) - + gcsgf * vgfb - gcsd * vdb - gcss * vsb - gcsdeltaT * deltaT + + gcgbs0 * vgbs; + ieqqgb = *(ckt->CKTstate0 + here->SOI3iqgb) - + gcgbgb * vgbb - gcgbdb * vdb - gcgbsb * vsb; + + ieqqBJTbs = *(ckt->CKTstate0 + here->SOI3iqBJTbs) - + gcBJTbsbs * vbs - gcBJTbsdeltaT * deltaT; + ieqqBJTbd = *(ckt->CKTstate0 + here->SOI3iqBJTbd) - + gcBJTbdbd * vbd - gcBJTbddeltaT * deltaT; + + /* now for the thermal capacitance + is constant and linear so no need + to fart about with equiv current */ + + + error = NIintegrate(ckt,&gct[0],&ieqct,here->SOI3ct, + here->SOI3qt); + if(error) return(error); + error = NIintegrate(ckt,&gct[1],&ieqct1,here->SOI3ct1, + here->SOI3qt1); + if(error) return(error); + error = NIintegrate(ckt,&gct[2],&ieqct2,here->SOI3ct2, + here->SOI3qt2); + if(error) return(error); + error = NIintegrate(ckt,&gct[3],&ieqct3,here->SOI3ct3, + here->SOI3qt3); + if(error) return(error); + error = NIintegrate(ckt,&gct[4],&ieqct4,here->SOI3ct4, + here->SOI3qt4); + if(error) return(error); + +LoadUp: + + /* + * load current vector + */ + ieqbs = model->SOI3type * + (here->SOI3ibs-(here->SOI3gbs-ckt->CKTgmin)*vbs + -(here->SOI3gbsT)*deltaT); + ieqbd = model->SOI3type * + (here->SOI3ibd-(here->SOI3gbd-ckt->CKTgmin)*vbd + -(here->SOI3gbdT)*deltaT); + iBJTdbeq = model->SOI3type * + (here->SOI3iBJTdb -(here->SOI3gBJTdb_bs)*vbs + -(here->SOI3gBJTdb_deltaT)*deltaT); + iBJTsbeq = model->SOI3type * + (here->SOI3iBJTsb -(here->SOI3gBJTsb_bd)*vbd + -(here->SOI3gBJTsb_deltaT)*deltaT); + ieqPt = here->SOI3iPt - (here->SOI3gPds*(here->SOI3mode*vds)+ + here->SOI3gPmf*(here->SOI3mode==1?vgfs:vgfd)+ + here->SOI3gPmb*(here->SOI3mode==1?vgbs:vgbd)+ + here->SOI3gPmbs*(here->SOI3mode==1?vbs:vbd)+ + here->SOI3gPdT*(deltaT)); + if (here->SOI3mode >= 0) { + xnrm=1; + xrev=0; + idreq=model->SOI3type*(idrain-here->SOI3gds*vds- + here->SOI3gmf*vgfs-here->SOI3gmbs*vbs- + here->SOI3gmb*vgbs-here->SOI3gt*deltaT); + iMdbeq=model->SOI3type*(here->SOI3iMdb-here->SOI3gMd*vds- + here->SOI3gMmf*vgfs-here->SOI3gMmbs*vbs- + here->SOI3gMmb*vgbs-here->SOI3gMdeltaT*deltaT); + iMsbeq=0; + } else { + xnrm=0; + xrev=1; + idreq = -(model->SOI3type)*(idrain-here->SOI3gds*(-vds)- + here->SOI3gmf*vgfd-here->SOI3gmbs*vbd- + here->SOI3gmb*vgbd-here->SOI3gt*deltaT); + iMsbeq= (model->SOI3type)*(here->SOI3iMsb-here->SOI3gMd*(-vds)- + here->SOI3gMmf*vgfd-here->SOI3gMmbs*vbd- + here->SOI3gMmb*vgbd-here->SOI3gMdeltaT*deltaT); + iMdbeq = 0; + } + *(ckt->CKTrhs + here->SOI3gfNode) -= + (model->SOI3type * ieqqgf); + *(ckt->CKTrhs + here->SOI3gbNode) -= + (model->SOI3type * ieqqgb); + *(ckt->CKTrhs + here->SOI3bNode) += -(ieqbs + ieqbd) + + iMdbeq + iMsbeq /* one is 0 */ + +iBJTdbeq + iBJTsbeq + + model->SOI3type * (ieqqgf + ieqqd + ieqqs + ieqqgb) + - model->SOI3type * (ieqqBJTbs + ieqqBJTbd); + *(ckt->CKTrhs + here->SOI3dNodePrime) += (ieqbd-idreq) - + iMdbeq - iBJTdbeq + - model->SOI3type * (ieqqd) + + model->SOI3type * (ieqqBJTbd); + *(ckt->CKTrhs + here->SOI3sNodePrime) += (idreq + ieqbs) - + iMsbeq - iBJTsbeq + - model->SOI3type * (ieqqs) + + model->SOI3type * (ieqqBJTbs); + *(ckt->CKTrhs + here->SOI3toutNode) += ieqPt-ieqct; + if (here->SOI3numThermalNodes > 1) + { + *(ckt->CKTrhs + here->SOI3tout1Node) += ieqct-ieqct1; + } + if (here->SOI3numThermalNodes > 2) + { + *(ckt->CKTrhs + here->SOI3tout2Node) += ieqct1-ieqct2; + } + if (here->SOI3numThermalNodes > 3) + { + *(ckt->CKTrhs + here->SOI3tout3Node) += ieqct2-ieqct3; + } + if (here->SOI3numThermalNodes > 2) + { + *(ckt->CKTrhs + here->SOI3tout4Node) += ieqct3-ieqct4; + } + + + /* + * load y matrix + */ + *(here->SOI3D_dPtr) += (here->SOI3drainConductance); + *(here->SOI3GF_gfPtr) += gcgfgf; + *(here->SOI3GB_gbPtr) += gcgbgb; + *(here->SOI3S_sPtr) += (here->SOI3sourceConductance); + *(here->SOI3B_bPtr) += (here->SOI3gbd+here->SOI3gbs - + here->SOI3gMmbs + - here->SOI3gBJTdb_bs - here->SOI3gBJTsb_bd) - + (gcbgf+gcbd+gcbs+gcbgb) + +gcBJTbsbs+gcBJTbdbd; + + *(here->SOI3DP_dpPtr) += + (here->SOI3drainConductance+here->SOI3gds+ + here->SOI3gbd+xrev*(here->SOI3gmf+here->SOI3gmbs+ + here->SOI3gmb)+xnrm*here->SOI3gMd + gcdd)+ + gcgbd0 + gcBJTbdbd; + *(here->SOI3SP_spPtr) += + (here->SOI3sourceConductance+here->SOI3gds+ + here->SOI3gbs+xnrm*(here->SOI3gmf+here->SOI3gmbs+ + here->SOI3gmb)+xrev*here->SOI3gMd + gcss)+ + gcgbs0 + gcBJTbsbs; + + *(here->SOI3D_dpPtr) += (-here->SOI3drainConductance); + *(here->SOI3GF_dpPtr) += gcgfd; + *(here->SOI3GF_spPtr) += gcgfs; + *(here->SOI3GF_bPtr) -= (gcgfgf + gcgfd + gcgfs); + + *(here->SOI3GB_dpPtr) += gcgbdb; + *(here->SOI3GB_spPtr) += gcgbsb; + *(here->SOI3GB_bPtr) -= (gcgbgb + gcgbdb + gcgbsb); + + *(here->SOI3S_spPtr) += (-here->SOI3sourceConductance); + *(here->SOI3B_gfPtr) += -here->SOI3gMmf + gcbgf; + *(here->SOI3B_gbPtr) += -(here->SOI3gMmb) + gcbgb; + *(here->SOI3B_dpPtr) += -(here->SOI3gbd) + here->SOI3gBJTsb_bd + + xrev*(here->SOI3gMmf+here->SOI3gMmb+ + here->SOI3gMmbs+here->SOI3gMd) - + xnrm*here->SOI3gMd + + gcbd - gcBJTbdbd; + *(here->SOI3B_spPtr) += -(here->SOI3gbs) + here->SOI3gBJTdb_bs + + xnrm*(here->SOI3gMmf+here->SOI3gMmb+ + here->SOI3gMmbs+here->SOI3gMd) - + xrev*here->SOI3gMd + + gcbs - gcBJTbsbs; + *(here->SOI3DP_dPtr) += (-here->SOI3drainConductance); + *(here->SOI3SP_sPtr) += (-here->SOI3sourceConductance); + + *(here->SOI3DP_gfPtr) += ((xnrm-xrev)*here->SOI3gmf + gcdgf+ + xnrm*here->SOI3gMmf); + *(here->SOI3DP_gbPtr) += ((xnrm-xrev)*here->SOI3gmb + + xnrm*here->SOI3gMmb) - gcgbd0; + *(here->SOI3DP_bPtr) += (-here->SOI3gbd + here->SOI3gBJTdb_bs + +(xnrm-xrev)*here->SOI3gmbs+ + xnrm*here->SOI3gMmbs) - + (gcdgf + gcdd + gcds + gcBJTbdbd); + *(here->SOI3DP_spPtr) += (-here->SOI3gds - here->SOI3gBJTdb_bs + -xnrm*(here->SOI3gmf+here->SOI3gmb+here->SOI3gmbs + + here->SOI3gMmf+here->SOI3gMmb+here->SOI3gMmbs+here->SOI3gMd)) + + gcds; + + *(here->SOI3SP_gfPtr) += (-(xnrm-xrev)*here->SOI3gmf+ + xrev*here->SOI3gMmf) + + gcsgf; + *(here->SOI3SP_gbPtr) += (-(xnrm-xrev)*here->SOI3gmb+ + xrev*here->SOI3gMmb) - gcgbs0; + *(here->SOI3SP_bPtr) += (-here->SOI3gbs + here->SOI3gBJTsb_bd + -(xnrm-xrev)*here->SOI3gmbs+ + xrev*here->SOI3gMmbs) - + (gcsgf + gcsd + gcss + gcBJTbsbs); + *(here->SOI3SP_dpPtr) += (-here->SOI3gds - here->SOI3gBJTsb_bd + -xrev*(here->SOI3gmf+here->SOI3gmb+here->SOI3gmbs+ + here->SOI3gMmf+here->SOI3gMmb+here->SOI3gMmbs+here->SOI3gMd)) + + gcsd; + +/* if no thermal behaviour specified, then put in zero valued indpt. voltage source + between TOUT and ground */ + if (here->SOI3rt==0) + { + *(here->SOI3TOUT_ibrPtr) += 1.0 ; + *(here->SOI3IBR_toutPtr) += 1.0 ; + *(ckt->CKTrhs + (here->SOI3branch)) = 0 ; + } + else + { + *(here->SOI3TOUT_toutPtr) += -(here->SOI3gPdT)+grt[0]+gct[0]; + + if (here->SOI3numThermalNodes > 1) + { + *(here->SOI3TOUT_tout1Ptr) += -grt[0]-gct[0]; + *(here->SOI3TOUT1_toutPtr) += -grt[0]-gct[0]; + *(here->SOI3TOUT1_tout1Ptr) += grt[0]+grt[1]+gct[0]+gct[1]; + } + if (here->SOI3numThermalNodes > 2) + { + *(here->SOI3TOUT1_tout2Ptr) += -grt[1]-gct[1]; + *(here->SOI3TOUT2_tout1Ptr) += -grt[1]-gct[1]; + *(here->SOI3TOUT2_tout2Ptr) += grt[1]+grt[2]+gct[1]+gct[2]; + } + if (here->SOI3numThermalNodes > 3) + { + *(here->SOI3TOUT2_tout3Ptr) += -grt[2]-gct[2]; + *(here->SOI3TOUT3_tout2Ptr) += -grt[2]-gct[2]; + *(here->SOI3TOUT3_tout3Ptr) += grt[2]+grt[3]+gct[2]+gct[3]; + } + if (here->SOI3numThermalNodes > 4) + { + *(here->SOI3TOUT3_tout4Ptr) += -grt[3]-gct[3]; + *(here->SOI3TOUT4_tout3Ptr) += -grt[3]-gct[3]; + *(here->SOI3TOUT4_tout4Ptr) += grt[3]+grt[4]+gct[3]+gct[4]; + } + + *(here->SOI3TOUT_dpPtr) += xnrm*(-(here->SOI3gPds*model->SOI3type)) + +xrev*(here->SOI3gPds+here->SOI3gPmf+ + here->SOI3gPmb+here->SOI3gPmbs)* + model->SOI3type; + *(here->SOI3TOUT_gfPtr) += -(here->SOI3gPmf*model->SOI3type); + *(here->SOI3TOUT_gbPtr) += -(here->SOI3gPmb*model->SOI3type); + *(here->SOI3TOUT_bPtr) += -(here->SOI3gPmbs*model->SOI3type); + *(here->SOI3TOUT_spPtr) += xnrm*(here->SOI3gPds+here->SOI3gPmf+ + here->SOI3gPmb+here->SOI3gPmbs)*model->SOI3type + +xrev*(-(here->SOI3gPds*model->SOI3type)); + + *(here->SOI3DP_toutPtr) += (xnrm-xrev)*here->SOI3gt*model->SOI3type; + *(here->SOI3SP_toutPtr) += (xrev-xnrm)*here->SOI3gt*model->SOI3type; +/* need to mult by type in above as conductances will be used with exterior voltages + which will be -ve for PMOS except for gPdT */ +/* now for thermal influence on impact ionisation current and tranisent stuff */ + *(here->SOI3GF_toutPtr) += gcgfdeltaT*model->SOI3type; + *(here->SOI3DP_toutPtr) += (xnrm*here->SOI3gMdeltaT + gcddeltaT - + here->SOI3gbdT + here->SOI3gBJTdb_deltaT + - gcBJTbddeltaT)*model->SOI3type; + *(here->SOI3SP_toutPtr) += (xrev*here->SOI3gMdeltaT + gcsdeltaT - + here->SOI3gbsT + here->SOI3gBJTsb_deltaT + - gcBJTbsdeltaT)*model->SOI3type; + *(here->SOI3B_toutPtr) -= (here->SOI3gMdeltaT - gcbdeltaT - + here->SOI3gbsT - here->SOI3gbdT + + here->SOI3gBJTdb_deltaT + + here->SOI3gBJTsb_deltaT + -gcBJTbsdeltaT-gcBJTbddeltaT)*model->SOI3type; + } +End: ; + } + } + return(OK); +} + +void common_handler(int sig,int code,struct sigcontext *scp,char * addr) +{; +} + + /* DEVsoipnjlim(vnew,vold,vt,vcrit,icheck) + * limit the per-iteration change of PN junction voltages + */ + +double +DEVsoipnjlim(vnew,vold,vt,vcrit,icheck) + + double vnew; + double vold; + double vt; + double vcrit; + int *icheck; + +{ + double arg; + + if((vnew > vcrit) && (fabs(vnew - vold) > (vt + vt))) { + if(vold > 0) { + arg = 1 + (vnew - vold) / vt; + if(arg > 0) { + vnew = vold + vt * log(arg); + } else { + vnew = vcrit; + } + } else { + vnew = vt *log(vnew/vt); + } + *icheck = 1; + } else { + if (fabs(vnew - vold) < (vt + vt)) { + *icheck = 0; + } else { + if (vnew>vold) { + *icheck = 0; + } else { + arg = 1 + (vold - vnew) / vt; + vnew = vold - vt*log(arg); + *icheck = 1; + } + } + } + return(vnew); +} diff --git a/src/spicelib/devices/soi3/soi3mask.c b/src/spicelib/devices/soi3/soi3mask.c new file mode 100644 index 000000000..50136982c --- /dev/null +++ b/src/spicelib/devices/soi3/soi3mask.c @@ -0,0 +1,286 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: Paolo Nenzi 2001 */ + +#include "ngspice.h" +#include +#include "const.h" +#include "ifsim.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "soi3defs.h" +#include "sperror.h" +#include "suffix.h" + + +/*ARGSUSED*/ +int +SOI3mAsk(ckt,inst,which,value) + CKTcircuit *ckt; + GENmodel *inst; + int which; + IFvalue *value; +{ + SOI3model *model = (SOI3model *)inst; + switch(which) { + case SOI3_MOD_VTO: + value->rValue = model->SOI3vt0; + return(OK); + case SOI3_MOD_VFBF: + value->rValue = model->SOI3vfbF; + return(OK); + case SOI3_MOD_KP: + value->rValue = model->SOI3transconductance; + return(OK); + case SOI3_MOD_GAMMA: + value->rValue = model->SOI3gamma; + return(OK); + case SOI3_MOD_PHI: + value->rValue = model->SOI3phi; + return(OK); + case SOI3_MOD_LAMBDA: + value->rValue = model->SOI3lambda; + return(OK); + case SOI3_MOD_THETA: + value->rValue = model->SOI3theta; + return(OK); + case SOI3_MOD_RD: + value->rValue = model->SOI3drainResistance; + return(OK); + case SOI3_MOD_RS: + value->rValue = model->SOI3sourceResistance; + return(OK); + case SOI3_MOD_CBD: + value->rValue = model->SOI3capBD; + return(OK); + case SOI3_MOD_CBS: + value->rValue = model->SOI3capBS; + return(OK); + case SOI3_MOD_IS: + value->rValue = model->SOI3jctSatCur; + return(OK); + case SOI3_MOD_IS1: + value->rValue = model->SOI3jctSatCur1; + return(OK); + case SOI3_MOD_PB: + value->rValue = model->SOI3bulkJctPotential; + return(OK); + case SOI3_MOD_CGFSO: + value->rValue = model->SOI3frontGateSourceOverlapCapFactor; + return(OK); + case SOI3_MOD_CGFDO: + value->rValue = model->SOI3frontGateDrainOverlapCapFactor; + return(OK); + case SOI3_MOD_CGFBO: + value->rValue = model->SOI3frontGateBulkOverlapCapFactor; + return(OK); + case SOI3_MOD_CGBSO: + value->rValue = model->SOI3backGateSourceOverlapCapFactor; + return(OK); + case SOI3_MOD_CGBDO: + value->rValue = model->SOI3backGateDrainOverlapCapFactor; + return(OK); + case SOI3_MOD_CGB_BO: + value->rValue = model->SOI3backGateBulkOverlapCapFactor; + return(OK); + case SOI3_MOD_RSH: + value->rValue = model->SOI3sheetResistance; + return(OK); + case SOI3_MOD_CJSW: + value->rValue = model->SOI3sideWallCapFactor; + return(OK); + case SOI3_MOD_MJSW: + value->rValue = model->SOI3bulkJctSideGradingCoeff; + return(OK); + case SOI3_MOD_JS: + value->rValue = model->SOI3jctSatCurDensity; + return(OK); + case SOI3_MOD_JS1: + value->rValue = model->SOI3jctSatCurDensity1; + return(OK); + case SOI3_MOD_TOF: + value->rValue = model->SOI3frontOxideThickness; + return(OK); + case SOI3_MOD_TOB: + value->rValue = model->SOI3backOxideThickness; + return(OK); + case SOI3_MOD_TB: + value->rValue = model->SOI3bodyThickness; + return(OK); + case SOI3_MOD_LD: + value->rValue = model->SOI3latDiff; + return(OK); + case SOI3_MOD_U0: + value->rValue = model->SOI3surfaceMobility; + return(OK); + case SOI3_MOD_FC: + value->rValue = model->SOI3fwdCapDepCoeff; + return(OK); + case SOI3_MOD_KOX: + value->rValue = model->SOI3oxideThermalConductivity; + return(OK); + case SOI3_MOD_SHSI: + value->rValue = model->SOI3siliconSpecificHeat; + return(OK); + case SOI3_MOD_DSI: + value->rValue = model->SOI3siliconDensity; + return(OK); + case SOI3_MOD_NSUB: + value->rValue = model->SOI3substrateDoping; + return(OK); + case SOI3_MOD_TPG: + value->iValue = model->SOI3gateType; + return(OK); + case SOI3_MOD_NQFF: + value->rValue = model->SOI3frontFixedChargeDensity; + return(OK); + case SOI3_MOD_NQFB: + value->rValue = model->SOI3backFixedChargeDensity; + return(OK); + case SOI3_MOD_NSSF: + value->rValue = model->SOI3frontSurfaceStateDensity; + return(OK); + case SOI3_MOD_NSSB: + value->rValue = model->SOI3backSurfaceStateDensity; + return(OK); + case SOI3_MOD_TNOM: + value->rValue = model->SOI3tnom-CONSTCtoK; + return(OK); +/* extra stuff for newer model - msll Jan96 */ + case SOI3_MOD_SIGMA: + value->rValue = model->SOI3sigma; + return(OK); + case SOI3_MOD_CHIFB: + value->rValue = model->SOI3chiFB; + return(OK); + case SOI3_MOD_CHIPHI: + value->rValue = model->SOI3chiPHI; + return(OK); + case SOI3_MOD_DELTAW: + value->rValue = model->SOI3deltaW; + return(OK); + case SOI3_MOD_DELTAL: + value->rValue = model->SOI3deltaL; + return(OK); + case SOI3_MOD_VSAT: + value->rValue = model->SOI3vsat; + return(OK); + case SOI3_MOD_K: + value->rValue = model->SOI3k; + return(OK); + case SOI3_MOD_LX: + value->rValue = model->SOI3lx; + return(OK); + case SOI3_MOD_VP: + value->rValue = model->SOI3vp; + return(OK); + case SOI3_MOD_ETA: + value->rValue = model->SOI3eta; + return(OK); + case SOI3_MOD_ALPHA0: + value->rValue = model->SOI3alpha0; + return(OK); + case SOI3_MOD_BETA0: + value->rValue = model->SOI3beta0; + return(OK); + case SOI3_MOD_LM: + value->rValue = model->SOI3lm; + return(OK); + case SOI3_MOD_LM1: + value->rValue = model->SOI3lm1; + return(OK); + case SOI3_MOD_LM2: + value->rValue = model->SOI3lm2; + return(OK); + case SOI3_MOD_ETAD: + value->rValue = model->SOI3etad; + return(OK); + case SOI3_MOD_ETAD1: + value->rValue = model->SOI3etad1; + return(OK); + case SOI3_MOD_CHIBETA: + value->rValue = model->SOI3chibeta; + return(OK); + case SOI3_MOD_VFBB: + value->rValue = model->SOI3vfbB; + return(OK); + case SOI3_MOD_GAMMAB: + value->rValue = model->SOI3gammaB; + return(OK); + case SOI3_MOD_CHID: + value->rValue = model->SOI3chid; + return(OK); + case SOI3_MOD_CHID1: + value->rValue = model->SOI3chid1; + return(OK); + case SOI3_MOD_DVT: + value->iValue = model->SOI3dvt; + return(OK); + case SOI3_MOD_NLEV: + value->iValue = model->SOI3nLev; + return(OK); + case SOI3_MOD_BETABJT: + value->rValue = model->SOI3betaBJT; + return(OK); + case SOI3_MOD_TAUFBJT: + value->rValue = model->SOI3tauFBJT; + return(OK); + case SOI3_MOD_TAURBJT: + value->rValue = model->SOI3tauRBJT; + return(OK); + case SOI3_MOD_BETAEXP: + value->rValue = model->SOI3betaEXP; + return(OK); + case SOI3_MOD_TAUEXP: + value->rValue = model->SOI3tauEXP; + return(OK); + case SOI3_MOD_RSW: + value->rValue = model->SOI3rsw; + return(OK); + case SOI3_MOD_RDW: + value->rValue = model->SOI3rdw; + return(OK); + case SOI3_MOD_FMIN: + value->rValue = model->SOI3minimumFeatureSize; + return(OK); + case SOI3_MOD_VTEX: + value->rValue = model->SOI3vtex; + return(OK); + case SOI3_MOD_VDEX: + value->rValue = model->SOI3vdex; + return(OK); + case SOI3_MOD_DELTA0: + value->rValue = model->SOI3delta0; + return(OK); + case SOI3_MOD_CSF: + value->rValue = model->SOI3satChargeShareFactor; + return(OK); + case SOI3_MOD_NPLUS: + value->rValue = model->SOI3nplusDoping; + return(OK); + case SOI3_MOD_RTA: + value->rValue = model->SOI3rta; + return(OK); + case SOI3_MOD_CTA: + value->rValue = model->SOI3cta; + return(OK); + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} diff --git a/src/spicelib/devices/soi3/soi3mdel.c b/src/spicelib/devices/soi3/soi3mdel.c new file mode 100644 index 000000000..be6c05c06 --- /dev/null +++ b/src/spicelib/devices/soi3/soi3mdel.c @@ -0,0 +1,56 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#include "ngspice.h" +#include +#include "soi3defs.h" +#include "sperror.h" +#include "suffix.h" + + +int +SOI3mDelete(inModel,modname,kill) + GENmodel **inModel; + IFuid modname; + GENmodel *kill; +{ + SOI3model **model = (SOI3model **)inModel; + SOI3model *modfast = (SOI3model *)kill; + SOI3instance *here; + SOI3instance *prev = NULL; + SOI3model **oldmod; + oldmod = model; + for( ; *model ; model = &((*model)->SOI3nextModel)) { + if( (*model)->SOI3modName == modname || + (modfast && *model == modfast) ) goto delgot; + oldmod = model; + } + return(E_NOMOD); + +delgot: + *oldmod = (*model)->SOI3nextModel; /* cut deleted device out of list */ + for(here = (*model)->SOI3instances ; here ; here = here->SOI3nextInstance) { + if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + FREE(*model); + return(OK); + +} diff --git a/src/spicelib/devices/soi3/soi3mpar.c b/src/spicelib/devices/soi3/soi3mpar.c new file mode 100644 index 000000000..4ff0417ba --- /dev/null +++ b/src/spicelib/devices/soi3/soi3mpar.c @@ -0,0 +1,390 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#include "ngspice.h" +#include +#include "const.h" +#include "ifsim.h" +#include "soi3defs.h" +#include "sperror.h" +#include "suffix.h" + +int +SOI3mParam(param,value,inModel) + int param; + IFvalue *value; + GENmodel *inModel; +{ + register SOI3model *model = (SOI3model *)inModel; + switch(param) { + case SOI3_MOD_VTO: + model->SOI3vt0 = value->rValue; + model->SOI3vt0Given = TRUE; + break; + case SOI3_MOD_VFBF: + model->SOI3vfbF = value->rValue; + model->SOI3vfbFGiven = TRUE; + break; + case SOI3_MOD_KP: + model->SOI3transconductance = value->rValue; + model->SOI3transconductanceGiven = TRUE; + break; + case SOI3_MOD_GAMMA: + model->SOI3gamma = value->rValue; + model->SOI3gammaGiven = TRUE; + break; + case SOI3_MOD_PHI: + model->SOI3phi = value->rValue; + model->SOI3phiGiven = TRUE; + break; + case SOI3_MOD_LAMBDA: + model->SOI3lambda = value->rValue; + model->SOI3lambdaGiven = TRUE; + break; + case SOI3_MOD_THETA: + model->SOI3theta = value->rValue; + model->SOI3thetaGiven = TRUE; + break; + case SOI3_MOD_RD: + model->SOI3drainResistance = value->rValue; + model->SOI3drainResistanceGiven = TRUE; + break; + case SOI3_MOD_RS: + model->SOI3sourceResistance = value->rValue; + model->SOI3sourceResistanceGiven = TRUE; + break; + case SOI3_MOD_CBD: + model->SOI3capBD = value->rValue; + model->SOI3capBDGiven = TRUE; + break; + case SOI3_MOD_CBS: + model->SOI3capBS = value->rValue; + model->SOI3capBSGiven = TRUE; + break; + case SOI3_MOD_IS: + model->SOI3jctSatCur = value->rValue; + model->SOI3jctSatCurGiven = TRUE; + break; + case SOI3_MOD_IS1: + model->SOI3jctSatCur1 = value->rValue; + model->SOI3jctSatCur1Given = TRUE; + break; + case SOI3_MOD_PB: + model->SOI3bulkJctPotential = value->rValue; + model->SOI3bulkJctPotentialGiven = TRUE; + break; + case SOI3_MOD_CGFSO: + model->SOI3frontGateSourceOverlapCapFactor = value->rValue; + model->SOI3frontGateSourceOverlapCapFactorGiven = TRUE; + break; + case SOI3_MOD_CGFDO: + model->SOI3frontGateDrainOverlapCapFactor = value->rValue; + model->SOI3frontGateDrainOverlapCapFactorGiven = TRUE; + break; + case SOI3_MOD_CGFBO: + model->SOI3frontGateBulkOverlapCapFactor = value->rValue; + model->SOI3frontGateBulkOverlapCapFactorGiven = TRUE; + break; + case SOI3_MOD_CGBSO: + model->SOI3backGateSourceOverlapCapFactor = value->rValue; + model->SOI3backGateSourceOverlapCapFactorGiven = TRUE; + break; + case SOI3_MOD_CGBDO: + model->SOI3backGateDrainOverlapCapFactor = value->rValue; + model->SOI3backGateDrainOverlapCapFactorGiven = TRUE; + break; + case SOI3_MOD_CGB_BO: + model->SOI3backGateBulkOverlapCapFactor = value->rValue; + model->SOI3backGateBulkOverlapCapFactorGiven = TRUE; + break; +/* case SOI3_MOD_CJ: + model->SOI3bulkCapFactor = value->rValue; + model->SOI3bulkCapFactorGiven = TRUE; + break; + case SOI3_MOD_MJ: + model->SOI3bulkJctBotGradingCoeff = value->rValue; + model->SOI3bulkJctBotGradingCoeffGiven = TRUE; + break; */ + case SOI3_MOD_RSH: + model->SOI3sheetResistance = value->rValue; + model->SOI3sheetResistanceGiven = TRUE; + break; + case SOI3_MOD_CJSW: + model->SOI3sideWallCapFactor = value->rValue; + model->SOI3sideWallCapFactorGiven = TRUE; + break; + case SOI3_MOD_MJSW: + model->SOI3bulkJctSideGradingCoeff = value->rValue; + model->SOI3bulkJctSideGradingCoeffGiven = TRUE; + break; + case SOI3_MOD_JS: + model->SOI3jctSatCurDensity = value->rValue; + model->SOI3jctSatCurDensityGiven = TRUE; + break; + case SOI3_MOD_JS1: + model->SOI3jctSatCurDensity1 = value->rValue; + model->SOI3jctSatCurDensity1Given = TRUE; + break; + case SOI3_MOD_TOF: + model->SOI3frontOxideThickness = value->rValue; + model->SOI3frontOxideThicknessGiven = TRUE; + break; + case SOI3_MOD_TOB: + model->SOI3backOxideThickness = value->rValue; + model->SOI3backOxideThicknessGiven = TRUE; + break; + case SOI3_MOD_TB: + model->SOI3bodyThickness = value->rValue; + model->SOI3bodyThicknessGiven = TRUE; + break; + case SOI3_MOD_LD: + model->SOI3latDiff = value->rValue; + model->SOI3latDiffGiven = TRUE; + break; + case SOI3_MOD_U0: + model->SOI3surfaceMobility = value->rValue; + model->SOI3surfaceMobilityGiven = TRUE; + break; + case SOI3_MOD_FC: + model->SOI3fwdCapDepCoeff = value->rValue; + model->SOI3fwdCapDepCoeffGiven = TRUE; + break; + case SOI3_MOD_NSOI3: + if(value->iValue) { + model->SOI3type = 1; + model->SOI3typeGiven = TRUE; + } + break; + case SOI3_MOD_PSOI3: + if(value->iValue) { + model->SOI3type = -1; + model->SOI3typeGiven = TRUE; + } + break; + case SOI3_MOD_KOX: + model->SOI3oxideThermalConductivity = value->rValue; + model->SOI3oxideThermalConductivityGiven = TRUE; + break; + case SOI3_MOD_SHSI: + model->SOI3siliconSpecificHeat = value->rValue; + model->SOI3siliconSpecificHeatGiven = TRUE; + break; + case SOI3_MOD_DSI: + model->SOI3siliconDensity = value->rValue; + model->SOI3siliconDensityGiven = TRUE; + break; + case SOI3_MOD_NSUB: + model->SOI3substrateDoping = value->rValue; + model->SOI3substrateDopingGiven = TRUE; + break; + case SOI3_MOD_TPG: + model->SOI3gateType = value->iValue; + model->SOI3gateTypeGiven = TRUE; + break; + case SOI3_MOD_NQFF: + model->SOI3frontFixedChargeDensity = value->rValue; + model->SOI3frontFixedChargeDensityGiven = TRUE; + break; + case SOI3_MOD_NQFB: + model->SOI3backFixedChargeDensity = value->rValue; + model->SOI3backFixedChargeDensityGiven = TRUE; + break; + case SOI3_MOD_NSSF: + model->SOI3frontSurfaceStateDensity = value->rValue; + model->SOI3frontSurfaceStateDensityGiven = TRUE; + break; + case SOI3_MOD_NSSB: + model->SOI3backSurfaceStateDensity = value->rValue; + model->SOI3backSurfaceStateDensityGiven = TRUE; + break; + case SOI3_MOD_TNOM: + model->SOI3tnom = value->rValue+CONSTCtoK; + model->SOI3tnomGiven = TRUE; + break; + case SOI3_MOD_KF: + model->SOI3fNcoef = value->rValue; + model->SOI3fNcoefGiven = TRUE; + break; + case SOI3_MOD_AF: + model->SOI3fNexp = value->rValue; + model->SOI3fNexpGiven = TRUE; + break; +/* extra stuff for newer model - msll Jan96 */ + case SOI3_MOD_SIGMA: + model->SOI3sigma = value->rValue; + model->SOI3sigmaGiven = TRUE; + break; + case SOI3_MOD_CHIFB: + model->SOI3chiFB = value->rValue; + model->SOI3chiFBGiven = TRUE; + break; + case SOI3_MOD_CHIPHI: + model->SOI3chiPHI = value->rValue; + model->SOI3chiPHIGiven = TRUE; + break; + case SOI3_MOD_DELTAW: + model->SOI3deltaW = value->rValue; + model->SOI3deltaWGiven = TRUE; + break; + case SOI3_MOD_DELTAL: + model->SOI3deltaL = value->rValue; + model->SOI3deltaLGiven = TRUE; + break; + case SOI3_MOD_VSAT: + model->SOI3vsat = value->rValue; + model->SOI3vsatGiven = TRUE; + break; + case SOI3_MOD_K: + model->SOI3k = value->rValue; + model->SOI3kGiven = TRUE; + break; + case SOI3_MOD_LX: + model->SOI3lx = value->rValue; + model->SOI3lxGiven = TRUE; + break; + case SOI3_MOD_VP: + model->SOI3vp = value->rValue; + model->SOI3vpGiven = TRUE; + break; + case SOI3_MOD_ETA: + model->SOI3eta = value->rValue; + model->SOI3etaGiven = TRUE; + break; + case SOI3_MOD_ALPHA0: + model->SOI3alpha0 = value->rValue; + model->SOI3alpha0Given = TRUE; + break; + case SOI3_MOD_BETA0: + model->SOI3beta0 = value->rValue; + model->SOI3beta0Given = TRUE; + break; + case SOI3_MOD_LM: + model->SOI3lm = value->rValue; + model->SOI3lmGiven = TRUE; + break; + case SOI3_MOD_LM1: + model->SOI3lm1 = value->rValue; + model->SOI3lm1Given = TRUE; + break; + case SOI3_MOD_LM2: + model->SOI3lm2 = value->rValue; + model->SOI3lm2Given = TRUE; + break; + case SOI3_MOD_ETAD: + model->SOI3etad = value->rValue; + model->SOI3etadGiven = TRUE; + break; + case SOI3_MOD_ETAD1: + model->SOI3etad1 = value->rValue; + model->SOI3etad1Given = TRUE; + break; + case SOI3_MOD_CHIBETA: + model->SOI3chibeta = value->rValue; + model->SOI3chibetaGiven = TRUE; + break; + case SOI3_MOD_VFBB: + model->SOI3vfbB = value->rValue; + model->SOI3vfbBGiven = TRUE; + break; + case SOI3_MOD_GAMMAB: + model->SOI3gammaB = value->rValue; + model->SOI3gammaBGiven = TRUE; + break; + case SOI3_MOD_CHID: + model->SOI3chid = value->rValue; + model->SOI3chidGiven = TRUE; + break; + case SOI3_MOD_CHID1: + model->SOI3chid1 = value->rValue; + model->SOI3chid1Given = TRUE; + break; + case SOI3_MOD_DVT: + model->SOI3dvt = value->iValue; + model->SOI3dvtGiven = TRUE; + break; + case SOI3_MOD_NLEV: + model->SOI3nLev = value->iValue; + model->SOI3nLevGiven = TRUE; + break; + case SOI3_MOD_BETABJT: + model->SOI3betaBJT = value->rValue; + model->SOI3betaBJTGiven = TRUE; + break; + case SOI3_MOD_TAUFBJT: + model->SOI3tauFBJT = value->rValue; + model->SOI3tauFBJTGiven = TRUE; + break; + case SOI3_MOD_TAURBJT: + model->SOI3tauRBJT = value->rValue; + model->SOI3tauRBJTGiven = TRUE; + break; + case SOI3_MOD_BETAEXP: + model->SOI3betaEXP = value->rValue; + model->SOI3betaEXPGiven = TRUE; + break; + case SOI3_MOD_TAUEXP: + model->SOI3tauEXP = value->rValue; + model->SOI3tauEXPGiven = TRUE; + break; + case SOI3_MOD_RSW: + model->SOI3rsw = value->rValue; + model->SOI3rswGiven = TRUE; + break; + case SOI3_MOD_RDW: + model->SOI3rdw = value->rValue; + model->SOI3rdwGiven = TRUE; + break; + case SOI3_MOD_FMIN: + model->SOI3minimumFeatureSize = value->rValue; + model->SOI3minimumFeatureSizeGiven = TRUE; + break; + case SOI3_MOD_VTEX: + model->SOI3vtex = value->rValue; + model->SOI3vtexGiven = TRUE; + break; + case SOI3_MOD_VDEX: + model->SOI3vdex = value->rValue; + model->SOI3vdexGiven = TRUE; + break; + case SOI3_MOD_DELTA0: + model->SOI3delta0 = value->rValue; + model->SOI3delta0Given = TRUE; + break; + case SOI3_MOD_CSF: + model->SOI3satChargeShareFactor = value->rValue; + model->SOI3satChargeShareFactorGiven = TRUE; + break; + case SOI3_MOD_NPLUS: + model->SOI3nplusDoping = value->rValue; + model->SOI3nplusDopingGiven = TRUE; + break; + case SOI3_MOD_RTA: + model->SOI3rta = value->rValue; + model->SOI3rtaGiven = TRUE; + break; + case SOI3_MOD_CTA: + model->SOI3cta = value->rValue; + model->SOI3ctaGiven = TRUE; + break; + + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/soi3/soi3nois.c b/src/spicelib/devices/soi3/soi3nois.c new file mode 100644 index 000000000..9372bc466 --- /dev/null +++ b/src/spicelib/devices/soi3/soi3nois.c @@ -0,0 +1,279 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#include "ngspice.h" +#include +#include "soi3defs.h" +#include "cktdefs.h" +#include "iferrmsg.h" +#include "noisedef.h" +#include "const.h" +#include "suffix.h" + + + +/* This routine is VERY closely based on the standard MOS noise function. + * SOI3noise (mode, operation, firstModel, ckt, data, OnDens) + * This routine names and evaluates all of the noise sources + * associated with MOSFET's. It starts with the model *firstModel and + * traverses all of its insts. It then proceeds to any other models + * on the linked list. The total output noise density generated by + * all of the MOSFET's is summed with the variable "OnDens". + */ + +extern void NevalSrc(); +extern double Nintegrate(); + +int +SOI3noise (mode, operation, genmodel, ckt, data, OnDens) + int mode; + int operation; + GENmodel *genmodel; + CKTcircuit *ckt; + register Ndata *data; + double *OnDens; +{ + SOI3model *firstModel = (SOI3model *) genmodel; + register SOI3model *model; + register SOI3instance *inst; + char name[N_MXVLNTH]; + double tempOnoise; + double tempInoise; + double noizDens[SOI3NSRCS]; + double lnNdens[SOI3NSRCS]; + double gain; + double EffectiveLength; + int error; + int i; + + /* define the names of the noise sources */ + + static char *SOI3nNames[SOI3NSRCS] = { /* Note that we have to keep the order */ + "_rd", /* noise due to rd */ /* consistent with the index definitions */ + "_rs", /* noise due to rs */ /* in SOI3defs.h */ + "_id", /* noise due to id */ + "_1overf", /* flicker (1/f) noise */ + "" /* total transistor noise */ + }; + + for (model=firstModel; model != NULL; model=model->SOI3nextModel) { + for (inst=model->SOI3instances; inst != NULL; inst=inst->SOI3nextInstance) { + switch (operation) { + + case N_OPEN: + + /* see if we have to to produce a summary report */ + /* if so, name all the noise generators */ + + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { + switch (mode) { + + case N_DENS: + for (i=0; i < SOI3NSRCS; i++) { + + (void)sprintf(name,"onoise_%s%s",inst->SOI3name,SOI3nNames[i]); + +data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid)); +if (!data->namelist) return(E_NOMEM); + (*(SPfrontEnd->IFnewUid))(ckt, + &(data->namelist[data->numPlots++]), + (IFuid)NULL,name,UID_OTHER,(void **)NULL); + /* we've added one more plot */ + + + } + break; + + case INT_NOIZ: + for (i=0; i < SOI3NSRCS; i++) { + + (void)sprintf(name,"onoise_total_%s%s",inst->SOI3name,SOI3nNames[i]); + +data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid)); +if (!data->namelist) return(E_NOMEM); + (*(SPfrontEnd->IFnewUid))(ckt, + &(data->namelist[data->numPlots++]), + (IFuid)NULL,name,UID_OTHER,(void **)NULL); + /* we've added one more plot */ + + (void)sprintf(name,"inoise_total_%s%s",inst->SOI3name,SOI3nNames[i]); + + +data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid)); +if (!data->namelist) return(E_NOMEM); + (*(SPfrontEnd->IFnewUid))(ckt, + &(data->namelist[data->numPlots++]), + (IFuid)NULL,name,UID_OTHER,(void **)NULL); + /* we've added one more plot */ + + + + } + break; + } + } + break; + + case N_CALC: + switch (mode) { + + case N_DENS: +/* just get gain from eval routine. Do thermal + * noise ourselves as we have local temperature + * rise. Also can use channel charge so model + * is valid in ALL regions and not just saturation. + */ + EffectiveLength=inst->SOI3l - 2*model->SOI3latDiff; + NevalSrc(&noizDens[SOI3RDNOIZ],(double*)NULL, + ckt,N_GAIN,inst->SOI3dNodePrime,inst->SOI3dNode, + (double)0.0); + noizDens[SOI3RDNOIZ] *= 4 * CONSTboltz * + (ckt->CKTtemp + *(ckt->CKTstate0 + inst->SOI3deltaT)) * + inst->SOI3drainConductance; + lnNdens[SOI3RDNOIZ] = log(MAX(noizDens[SOI3RDNOIZ],N_MINLOG)); + + NevalSrc(&noizDens[SOI3RSNOIZ],(double*)NULL, + ckt,N_GAIN,inst->SOI3sNodePrime,inst->SOI3sNode, + (double)0.0); + noizDens[SOI3RSNOIZ] *= 4 * CONSTboltz * + (ckt->CKTtemp + *(ckt->CKTstate0 + inst->SOI3deltaT)) * + inst->SOI3sourceConductance; + lnNdens[SOI3RSNOIZ] = log(MAX(noizDens[SOI3RSNOIZ],N_MINLOG)); + + NevalSrc(&gain,(double*)NULL,ckt, + N_GAIN,inst->SOI3dNodePrime, inst->SOI3sNodePrime, + (double)0.0); + + noizDens[SOI3IDNOIZ] = (gain * 4 * CONSTboltz * + (ckt->CKTtemp + *(ckt->CKTstate0 + inst->SOI3deltaT)) * + inst->SOI3ueff * + fabs(*(ckt->CKTstate0 + inst->SOI3qd) + + *(ckt->CKTstate0 + inst->SOI3qs)))/ + (EffectiveLength*EffectiveLength); + lnNdens[SOI3IDNOIZ] = log(MAX(noizDens[SOI3IDNOIZ],N_MINLOG)); + + switch (model->SOI3nLev) { + case 2: + noizDens[SOI3FLNOIZ] = gain * model->SOI3fNcoef * + (inst->SOI3gmf)*(inst->SOI3gmf)/ + (model->SOI3frontOxideCapFactor * + inst->SOI3w * EffectiveLength * + exp(model->SOI3fNexp * + log(MAX(fabs(data->freq),N_MINLOG))) + ); + break; + + case 1: + noizDens[SOI3FLNOIZ] = gain * model->SOI3fNcoef * + exp(model->SOI3fNexp * + log(MAX(fabs(inst->SOI3id),N_MINLOG))) / + (data->freq * EffectiveLength * inst->SOI3w * + model->SOI3frontOxideCapFactor); + break; + + case 0: + default: + noizDens[SOI3FLNOIZ] = gain * model->SOI3fNcoef * + exp(model->SOI3fNexp * + log(MAX(fabs(inst->SOI3id),N_MINLOG))) / + (data->freq * EffectiveLength * EffectiveLength * + model->SOI3frontOxideCapFactor); + break; + } + + + + + lnNdens[SOI3FLNOIZ] = + log(MAX(noizDens[SOI3FLNOIZ],N_MINLOG)); + + noizDens[SOI3TOTNOIZ] = noizDens[SOI3RDNOIZ] + + noizDens[SOI3RSNOIZ] + + noizDens[SOI3IDNOIZ] + + noizDens[SOI3FLNOIZ]; + lnNdens[SOI3TOTNOIZ] = + log(MAX(noizDens[SOI3TOTNOIZ], N_MINLOG)); + + *OnDens += noizDens[SOI3TOTNOIZ]; + + if (data->delFreq == 0.0) { + + /* if we haven't done any previous integration, we need to */ + /* initialize our "history" variables */ + + for (i=0; i < SOI3NSRCS; i++) { + inst->SOI3nVar[LNLSTDENS][i] = lnNdens[i]; + } + + /* clear out our integration variables if it's the first pass */ + + if (data->freq == ((NOISEAN*)ckt->CKTcurJob)->NstartFreq) { + for (i=0; i < SOI3NSRCS; i++) { + inst->SOI3nVar[OUTNOIZ][i] = 0.0; + inst->SOI3nVar[INNOIZ][i] = 0.0; + } + } + } else { /* data->delFreq != 0.0 (we have to integrate) */ + for (i=0; i < SOI3NSRCS; i++) { + if (i != SOI3TOTNOIZ) { + tempOnoise = Nintegrate(noizDens[i], lnNdens[i], + inst->SOI3nVar[LNLSTDENS][i], data); + tempInoise = Nintegrate(noizDens[i] * data->GainSqInv , + lnNdens[i] + data->lnGainInv, + inst->SOI3nVar[LNLSTDENS][i] + data->lnGainInv, + data); + inst->SOI3nVar[LNLSTDENS][i] = lnNdens[i]; + data->outNoiz += tempOnoise; + data->inNoise += tempInoise; + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { + inst->SOI3nVar[OUTNOIZ][i] += tempOnoise; + inst->SOI3nVar[OUTNOIZ][SOI3TOTNOIZ] += tempOnoise; + inst->SOI3nVar[INNOIZ][i] += tempInoise; + inst->SOI3nVar[INNOIZ][SOI3TOTNOIZ] += tempInoise; + } + } + } + } + if (data->prtSummary) { + for (i=0; i < SOI3NSRCS; i++) { /* print a summary report */ + data->outpVector[data->outNumber++] = noizDens[i]; + } + } + break; + + case INT_NOIZ: /* already calculated, just output */ + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { + for (i=0; i < SOI3NSRCS; i++) { + data->outpVector[data->outNumber++] = inst->SOI3nVar[OUTNOIZ][i]; + data->outpVector[data->outNumber++] = inst->SOI3nVar[INNOIZ][i]; + } + } /* if */ + break; + } /* switch (mode) */ + break; + + case N_CLOSE: + return (OK); /* do nothing, the main calling routine will close */ + break; /* the plots */ + } /* switch (operation) */ + } /* for inst */ + } /* for model */ + +return(OK); +} diff --git a/src/spicelib/devices/soi3/soi3par.c b/src/spicelib/devices/soi3/soi3par.c new file mode 100644 index 000000000..efcea9b79 --- /dev/null +++ b/src/spicelib/devices/soi3/soi3par.c @@ -0,0 +1,153 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#include "ngspice.h" +#include +#include "const.h" +#include "ifsim.h" +#include "soi3defs.h" +#include "sperror.h" +#include "suffix.h" + + +/* ARGSUSED */ +int +SOI3param(param,value,inst,select) + int param; + IFvalue *value; + GENinstance *inst; + IFvalue *select; +{ + SOI3instance *here = (SOI3instance *)inst; + switch(param) { + case SOI3_L: + here->SOI3l = value->rValue; + here->SOI3lGiven = TRUE; + break; + case SOI3_W: + here->SOI3w = value->rValue; + here->SOI3wGiven = TRUE; + break; + case SOI3_NRD: + here->SOI3drainSquares = value->rValue; + here->SOI3drainSquaresGiven = TRUE; + break; + case SOI3_NRS: + here->SOI3sourceSquares = value->rValue; + here->SOI3sourceSquaresGiven = TRUE; + break; + case SOI3_OFF: + here->SOI3off = value->iValue; + break; + case SOI3_IC_VDS: + here->SOI3icVDS = value->rValue; + here->SOI3icVDSGiven = TRUE; + break; + case SOI3_IC_VGFS: + here->SOI3icVGFS = value->rValue; + here->SOI3icVGFSGiven = TRUE; + break; + case SOI3_IC_VGBS: + here->SOI3icVGBS = value->rValue; + here->SOI3icVGBSGiven = TRUE; + break; + case SOI3_IC_VBS: + here->SOI3icVBS = value->rValue; + here->SOI3icVBSGiven = TRUE; + break; + case SOI3_TEMP: + here->SOI3temp = value->rValue+CONSTCtoK; + here->SOI3tempGiven = TRUE; + break; + case SOI3_RT: + here->SOI3rt = value->rValue; + here->SOI3rtGiven = TRUE; + break; + case SOI3_CT: + here->SOI3ct = value->rValue; + here->SOI3ctGiven = TRUE; + break; + case SOI3_RT1: + here->SOI3rt1 = value->rValue; + here->SOI3rt1Given = TRUE; + break; + case SOI3_CT1: + here->SOI3ct1 = value->rValue; + here->SOI3ct1Given = TRUE; + break; + case SOI3_RT2: + here->SOI3rt2 = value->rValue; + here->SOI3rt2Given = TRUE; + break; + case SOI3_CT2: + here->SOI3ct2 = value->rValue; + here->SOI3ct2Given = TRUE; + break; + case SOI3_RT3: + here->SOI3rt3 = value->rValue; + here->SOI3rt3Given = TRUE; + break; + case SOI3_CT3: + here->SOI3ct3 = value->rValue; + here->SOI3ct3Given = TRUE; + break; + case SOI3_RT4: + here->SOI3rt4 = value->rValue; + here->SOI3rt4Given = TRUE; + break; + case SOI3_CT4: + here->SOI3ct4 = value->rValue; + here->SOI3ct4Given = TRUE; + break; + case SOI3_IC: + switch(value->v.numValue){ + case 4: + here->SOI3icVBS = *(value->v.vec.rVec+3); + here->SOI3icVBSGiven = TRUE; + case 3: + here->SOI3icVGBS = *(value->v.vec.rVec+2); + here->SOI3icVGBSGiven = TRUE; + case 2: + here->SOI3icVGFS = *(value->v.vec.rVec+1); + here->SOI3icVGFSGiven = TRUE; + case 1: + here->SOI3icVDS = *(value->v.vec.rVec); + here->SOI3icVDSGiven = TRUE; + break; + default: + return(E_BADPARM); + } + break; +/* case SOI3_L_SENS: + if(value->iValue) { + here->SOI3senParmNo = 1; + here->SOI3sens_l = 1; + } + break; + case SOI3_W_SENS: + if(value->iValue) { + here->SOI3senParmNo = 1; + here->SOI3sens_w = 1; + } + break; */ + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/soi3/soi3set.c b/src/spicelib/devices/soi3/soi3set.c new file mode 100644 index 000000000..110105663 --- /dev/null +++ b/src/spicelib/devices/soi3/soi3set.c @@ -0,0 +1,751 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "soi3defs.h" +#include "sperror.h" +#include "suffix.h" + + +int +SOI3setup(matrix,inModel,ckt,states) + SMPmatrix *matrix; + GENmodel *inModel; + CKTcircuit *ckt; + int *states; +{ + SOI3model *model = (SOI3model *)inModel; + SOI3instance *here; + int error; + CKTnode *tmp; + + /* JimB - new variable for RT and CT scaling */ + double thermal_area; + + double rtargs[5]; + double * rtptr; + int node_count; + + /****** Part 1 - set any model parameters that are not present in ******/ + /****** the netlist to default values. ******/ + + /* loop through all the SOI3 device models */ + for( ; model != NULL; model = model->SOI3nextModel ) { + + if(!model->SOI3typeGiven) { + model->SOI3type = NSOI3; + } + if(!model->SOI3latDiffGiven) { + model->SOI3latDiff = 0; + } + if(!model->SOI3jctSatCurDensityGiven) { + model->SOI3jctSatCurDensity = 1.0e-10; + } + if(!model->SOI3jctSatCurDensity1Given) { + model->SOI3jctSatCurDensity1 = 0.0; + } + if(!model->SOI3jctSatCurGiven) { + model->SOI3jctSatCur = 0.0; + } + if(!model->SOI3jctSatCur1Given) { + model->SOI3jctSatCur1 = 0.0; + } + if(!model->SOI3transconductanceGiven) { + model->SOI3transconductance = 2e-5; + } + if(!model->SOI3frontGateSourceOverlapCapFactorGiven) { + model->SOI3frontGateSourceOverlapCapFactor = 0; + } + if(!model->SOI3frontGateDrainOverlapCapFactorGiven) { + model->SOI3frontGateDrainOverlapCapFactor = 0; + } + if(!model->SOI3frontGateBulkOverlapCapFactorGiven) { + model->SOI3frontGateBulkOverlapCapFactor = 0; + } + if(!model->SOI3backGateSourceOverlapCapFactorGiven) { + model->SOI3backGateSourceOverlapCapFactor = 0; + } + if(!model->SOI3backGateDrainOverlapCapFactorGiven) { + model->SOI3backGateDrainOverlapCapFactor = 0; + } + if(!model->SOI3backGateBulkOverlapCapFactorGiven) { + model->SOI3backGateBulkOverlapCapFactor = 0; + } + if(!model->SOI3sideWallCapFactorGiven) { + model->SOI3sideWallCapFactor = 0; + } + if(!model->SOI3bulkJctPotentialGiven) { + model->SOI3bulkJctPotential = 0.8; + } + if(!model->SOI3bulkJctSideGradingCoeffGiven) { + model->SOI3bulkJctSideGradingCoeff = 0.5; + } + if(!model->SOI3fwdCapDepCoeffGiven) { + model->SOI3fwdCapDepCoeff = 0.5; + } + if(!model->SOI3lambdaGiven) { + model->SOI3lambda = 0; + } + if(!model->SOI3thetaGiven) { + model->SOI3theta = 0; + } + /* JimB - If SiO2 thermal conductivity given in netlist then use */ + /* that value, otherwise use literature value. (Units W/K*m). */ + if(!model->SOI3oxideThermalConductivityGiven) { + model->SOI3oxideThermalConductivity = 1.4; + } + /* JimB - If Si specific heat given in netlist then use that value, */ + /* otherwise use literature value. (Units J/kg*K). */ + if(!model->SOI3siliconSpecificHeatGiven) { + model->SOI3siliconSpecificHeat = 700; + } + /* JimB - If density of Si given in netlist then use that value, */ + /* otherwise use literature value. (kg/m^3). */ + if(!model->SOI3siliconDensityGiven) { + model->SOI3siliconDensity = 2330; + } + if(!model->SOI3frontFixedChargeDensityGiven) { + model->SOI3frontFixedChargeDensity = 0; + } + if(!model->SOI3backFixedChargeDensityGiven) { + model->SOI3backFixedChargeDensity = 0; + } + if(!model->SOI3frontSurfaceStateDensityGiven) { + model->SOI3frontSurfaceStateDensity = 0; + } + if(!model->SOI3backSurfaceStateDensityGiven) { + model->SOI3backSurfaceStateDensity = 0; + } + if(!model->SOI3gammaGiven) { + model->SOI3gamma = 0; + } + if(!model->SOI3fNcoefGiven) { + model->SOI3fNcoef = 0; + } + if(!model->SOI3fNexpGiven) { + model->SOI3fNexp = 1; + } +/* extra stuff for newer model - msll Jan96 */ + if(!model->SOI3sigmaGiven) { + model->SOI3sigma = 0; + } + if(!model->SOI3chiFBGiven) { + model->SOI3chiFB = 0; + } + if(!model->SOI3chiPHIGiven) { + model->SOI3chiPHI = 0; + } + if(!model->SOI3deltaWGiven) { + model->SOI3deltaW = 0; + } + if(!model->SOI3deltaLGiven) { + model->SOI3deltaL = 0; + } + if(!model->SOI3vsatGiven) { + model->SOI3vsat = 0; /* special case - must check for it */ + } + if(!model->SOI3kGiven) { + model->SOI3k = 1.5; /* defaults to old SPICE value */ + } + if(!model->SOI3lxGiven) { + model->SOI3lx = 0; + } + if(!model->SOI3vpGiven) { + model->SOI3vp = 0; + } + if(!model->SOI3gammaBGiven) { + model->SOI3gammaB = 0; + } +/* now check to determine which CLM model to use */ + if((model->SOI3lx != 0) && (model->SOI3lambda != 0)) { + (*(SPfrontEnd->IFerror))(ERR_WARNING, + "%s: Non-zero values for BOTH LAMBDA and LX. \nDefaulting to simple LAMBDA model", + &model->SOI3modName); + model->SOI3useLAMBDA = TRUE; + } + +/* if only lx given and vp!=0, use froody model, else basic */ + if ((model->SOI3lxGiven) && (model->SOI3lx != 0) && + (!model->SOI3lambdaGiven) && (model->SOI3vp != 0)) { + model->SOI3useLAMBDA = FALSE; + } else { + model->SOI3useLAMBDA = TRUE; + } + if(!model->SOI3etaGiven) { + model->SOI3eta = 1.0; /* normal field for imp. ion. */ + } + if(!model->SOI3alpha0Given) { + model->SOI3alpha0=0; + } + if(!model->SOI3beta0Given) { + model->SOI3beta0=1.92e6; + } + if(!model->SOI3lmGiven) { + model->SOI3lm = 0; + } + if(!model->SOI3lm1Given) { + model->SOI3lm1 = 0; + } + if(!model->SOI3lm2Given) { + model->SOI3lm2 = 0; + } + if((!model->SOI3etadGiven) || (model->SOI3etad == 0 )) { + model->SOI3etad = 1.0; + } + if((!model->SOI3etad1Given) || (model->SOI3etad1 == 0 )) { + model->SOI3etad1 = 1.0; + } + if(!model->SOI3chibetaGiven) { + model->SOI3chibeta = 0.0; + } + if(!model->SOI3dvtGiven) { + model->SOI3dvt = 1; + } + if(!model->SOI3nLevGiven) { + model->SOI3nLev = 0; + } + if(!model->SOI3betaBJTGiven) { + model->SOI3betaBJT = 0.0; + } + if(!model->SOI3tauFBJTGiven) { + model->SOI3tauFBJT = 0.0; + } + if(!model->SOI3tauRBJTGiven) { + model->SOI3tauRBJT = 0.0; + } + if(!model->SOI3betaEXPGiven) { + model->SOI3betaEXP = 2.0; + } + if(!model->SOI3tauEXPGiven) { + model->SOI3tauEXP = 0.0; + } + if(!model->SOI3rswGiven) { + model->SOI3rsw = 0.0; + } + if(!model->SOI3rdwGiven) { + model->SOI3rdw = 0.0; + } + if(!model->SOI3minimumFeatureSizeGiven) { + model->SOI3minimumFeatureSize = 0.0; + } + if(!model->SOI3vtexGiven) { + model->SOI3vtex = 0.0; + } + if(!model->SOI3vdexGiven) { + model->SOI3vdex = 0.0; + } + if(!model->SOI3delta0Given) { + model->SOI3delta0 = 0.0; + } + if(!model->SOI3satChargeShareFactorGiven) { + model->SOI3satChargeShareFactor = 0.5; + } + if(!model->SOI3nplusDopingGiven) { + model->SOI3nplusDoping = 1e20; + } + if(!model->SOI3rtaGiven) { + model->SOI3rta = 0; + } + if(!model->SOI3ctaGiven) { + model->SOI3cta = 0; + } + + + /****** Part 2 - set any instance parameters that are not present ******/ + /****** in the netlist to default values. ******/ + + /* loop through all the instances of the model */ + for (here = model->SOI3instances; here != NULL ; + here=here->SOI3nextInstance) { + + CKTnode *tmpNode; + IFuid tmpName; + + + + if(!here->SOI3icVBSGiven) { + here->SOI3icVBS = 0; + } + if(!here->SOI3icVDSGiven) { + here->SOI3icVDS = 0; + } + if(!here->SOI3icVGFSGiven) { + here->SOI3icVGFS = 0; + } + if(!here->SOI3icVGBSGiven) { + here->SOI3icVGBS = 0; + } + if(!here->SOI3drainSquaresGiven || here->SOI3drainSquares==0) { + here->SOI3drainSquares=1; + } + if(!here->SOI3sourceSquaresGiven || here->SOI3sourceSquares==0) { + here->SOI3sourceSquares=1; + } + + /****** Part 3 - Initialise transconductances. ******/ + + /* initialise gM's */ + here->SOI3iMdb= 0.0; + here->SOI3iMsb= 0.0; + here->SOI3gMmbs = 0.0; + here->SOI3gMmf = 0.0; + here->SOI3gMmb = 0.0; + here->SOI3gMd = 0.0; + here->SOI3gMdeltaT = 0.0; + /* allocate a chunk of the state vector */ + here->SOI3states = *states; + *states += SOI3numStates; +/* if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN) ){ + *states += 10 * (ckt->CKTsenInfo->SENparms); + } +*/ + + /****** Part 4 - check resistance values for internal nodes, ******/ + /****** to see which internal nodes need to be created. ******/ + + /* Start with internal source and drain nodes */ + + if((model->SOI3drainResistance != 0 + || (model->SOI3sheetResistance != 0 && + here->SOI3drainSquares != 0) + || model->SOI3rdw != 0) + && here->SOI3dNodePrime == 0) + { + error = CKTmkVolt(ckt,&tmp,here->SOI3name,"drain"); + if(error) + { + return(error); + } + here->SOI3dNodePrime = 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->SOI3dNodePrime = here->SOI3dNode; + } + + if((model->SOI3sourceResistance != 0 || + (model->SOI3sheetResistance != 0 && + here->SOI3sourceSquares != 0) || + model->SOI3rsw != 0) && + here->SOI3sNodePrime==0) + { + error = CKTmkVolt(ckt,&tmp,here->SOI3name,"source"); + if(error) + { + return(error); + } + here->SOI3sNodePrime = 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->SOI3sNodePrime = here->SOI3sNode; + } + + /* Now for thermal node */ + + /* JimB - If minimum feature size has non-zero value, then this */ + /* will be used to calculate thermal area of SiO2 - this gives */ + /* more accurate values of RT for short-channel devices. Assume*/ + /* 4*fmin added to L, and 2*fmin added to W (fmin in microns). */ + thermal_area = (here->SOI3w + 2*1e-6*model->SOI3minimumFeatureSize) + * (here->SOI3l + 4*1e-6*model->SOI3minimumFeatureSize); + + /* Now calculate RT and CT. */ + + /* If RT is given on instance line, use it, otherwise calculate from */ + /* above variables. */ + if (!here->SOI3rtGiven) + { + if (model->SOI3rtaGiven) + { + here->SOI3rt = model->SOI3rta/thermal_area; + } + else + { + if (model->SOI3oxideThermalConductivity != 0) + { + here->SOI3rt = model->SOI3backOxideThickness / + (model->SOI3oxideThermalConductivity * thermal_area); + } + else + /* If conductivity set to zero in netlist, switch off self-heating. */ + { + here->SOI3rt = 0; + } + } + } + if (!here->SOI3rt1Given) + { + here->SOI3rt1=0; + } + if (!here->SOI3rt2Given) + { + here->SOI3rt2=0; + } + if (!here->SOI3rt3Given) + { + here->SOI3rt3=0; + } + if (!here->SOI3rt4Given) + { + here->SOI3rt4=0; + } + + /* Now same thing for CT, but less complex as CT=0 does not cause problems */ + if (!here->SOI3ctGiven) + { + if (model->SOI3ctaGiven) + { + here->SOI3ct = model->SOI3cta*thermal_area; + } + else + { + here->SOI3ct = model->SOI3siliconDensity * model->SOI3siliconSpecificHeat * + thermal_area * model->SOI3bodyThickness; + } + } + if (!here->SOI3ct1Given) + { + here->SOI3ct1=0; + } + if (!here->SOI3ct2Given) + { + here->SOI3ct2=0; + } + if (!here->SOI3ct3Given) + { + here->SOI3ct3=0; + } + if (!here->SOI3ct4Given) + { + here->SOI3ct4=0; + } + + /* JimB - 15/9/99 */ + rtargs[0]=here->SOI3rt; + rtargs[1]=here->SOI3rt1; + rtargs[2]=here->SOI3rt2; + rtargs[3]=here->SOI3rt3; + rtargs[4]=here->SOI3rt4; + rtptr = rtargs; /* Set pointer to start address of rtargs array. */ + node_count=0; + + while ( (*rtptr) && (node_count<5) ) + { + node_count++; + if (node_count<5) + { + rtptr++; /* Increment pointer to next array element. */ + } + } + here->SOI3numThermalNodes=node_count; + + /* Thermal node is now external and so is automatically created by CKTcreate in INP2A. + It is also bound to the created node's number. However, if rt=0 then no thermal so + make tout be the thermal ground. Can't simply use CKTbindNode 'cos the row and column + associated with the original node has already been created. Thus problems will occur + during pivoting. Instead put zero voltage source here. First create branch for it.*/ + + if ((here->SOI3rt == 0) && (here->SOI3branch == 0)) + { + error = CKTmkCur(ckt,&tmp,here->SOI3name,"branch"); + + if(error) + { + return(error); + } + here->SOI3branch = 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 + { /* have thermal - now how many time constants ? */ + if ((here->SOI3numThermalNodes > 1) && + (here->SOI3tout1Node == 0)) + { + error = CKTmkVolt(ckt,&tmp,here->SOI3name,"tout1"); + if (error) return (error); + here->SOI3tout1Node = 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->SOI3tout1Node = 0; + } + if ((here->SOI3numThermalNodes > 2) && + (here->SOI3tout2Node == 0)) + { + error = CKTmkVolt(ckt,&tmp,here->SOI3name,"tout2"); + if (error) return (error); + here->SOI3tout2Node = 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->SOI3tout2Node = 0; + } + if ((here->SOI3numThermalNodes > 3) && + (here->SOI3tout3Node == 0)) + { + error = CKTmkVolt(ckt,&tmp,here->SOI3name,"tout3"); + if (error) return (error); + here->SOI3tout3Node = 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->SOI3tout3Node = 0; + } + if ((here->SOI3numThermalNodes > 4) && + (here->SOI3tout4Node == 0)) + { + error = CKTmkVolt(ckt,&tmp,here->SOI3name,"tout4"); + if (error) return (error); + here->SOI3tout4Node = 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->SOI3tout4Node = 0; + } + } + + +/****** Part 5 - allocate memory to matrix elements corresponding to ******/ +/****** pairs of nodes. ******/ + +/* macro to make elements with built in test for out of memory */ + +#define TSTALLOC(ptr,first,second) \ +if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ + return(E_NOMEM);\ +} + + TSTALLOC(SOI3D_dPtr,SOI3dNode,SOI3dNode) + TSTALLOC(SOI3GF_gfPtr,SOI3gfNode,SOI3gfNode) + TSTALLOC(SOI3S_sPtr,SOI3sNode,SOI3sNode) + TSTALLOC(SOI3GB_gbPtr,SOI3gbNode,SOI3gbNode) + TSTALLOC(SOI3B_bPtr,SOI3bNode,SOI3bNode) + TSTALLOC(SOI3DP_dpPtr,SOI3dNodePrime,SOI3dNodePrime) + TSTALLOC(SOI3SP_spPtr,SOI3sNodePrime,SOI3sNodePrime) + TSTALLOC(SOI3D_dpPtr,SOI3dNode,SOI3dNodePrime) + TSTALLOC(SOI3GF_bPtr,SOI3gfNode,SOI3bNode) + TSTALLOC(SOI3GF_dpPtr,SOI3gfNode,SOI3dNodePrime) + TSTALLOC(SOI3GF_spPtr,SOI3gfNode,SOI3sNodePrime) + TSTALLOC(SOI3GB_bPtr,SOI3gbNode,SOI3bNode) + TSTALLOC(SOI3GB_dpPtr,SOI3gbNode,SOI3dNodePrime) + TSTALLOC(SOI3GB_spPtr,SOI3gbNode,SOI3sNodePrime) + TSTALLOC(SOI3S_spPtr,SOI3sNode,SOI3sNodePrime) + TSTALLOC(SOI3B_dpPtr,SOI3bNode,SOI3dNodePrime) + TSTALLOC(SOI3B_spPtr,SOI3bNode,SOI3sNodePrime) + TSTALLOC(SOI3DP_spPtr,SOI3dNodePrime,SOI3sNodePrime) + TSTALLOC(SOI3DP_dPtr,SOI3dNodePrime,SOI3dNode) + TSTALLOC(SOI3B_gfPtr,SOI3bNode,SOI3gfNode) + TSTALLOC(SOI3DP_gfPtr,SOI3dNodePrime,SOI3gfNode) + TSTALLOC(SOI3SP_gfPtr,SOI3sNodePrime,SOI3gfNode) + TSTALLOC(SOI3B_gbPtr,SOI3bNode,SOI3gbNode) + TSTALLOC(SOI3DP_gbPtr,SOI3dNodePrime,SOI3gbNode) + TSTALLOC(SOI3SP_gbPtr,SOI3sNodePrime,SOI3gbNode) + TSTALLOC(SOI3SP_sPtr,SOI3sNodePrime,SOI3sNode) + TSTALLOC(SOI3DP_bPtr,SOI3dNodePrime,SOI3bNode) + TSTALLOC(SOI3SP_bPtr,SOI3sNodePrime,SOI3bNode) + TSTALLOC(SOI3SP_dpPtr,SOI3sNodePrime,SOI3dNodePrime) + + if (here->SOI3rt == 0) + { + TSTALLOC(SOI3TOUT_ibrPtr,SOI3toutNode,SOI3branch) + TSTALLOC(SOI3IBR_toutPtr,SOI3branch,SOI3toutNode) + } + else + { + TSTALLOC(SOI3TOUT_toutPtr,SOI3toutNode,SOI3toutNode) + if (here->SOI3numThermalNodes > 1) + { + TSTALLOC(SOI3TOUT_tout1Ptr,SOI3toutNode,SOI3tout1Node) + TSTALLOC(SOI3TOUT1_toutPtr,SOI3tout1Node,SOI3toutNode) + TSTALLOC(SOI3TOUT1_tout1Ptr,SOI3tout1Node,SOI3tout1Node) + } + if (here->SOI3numThermalNodes > 2) + { + TSTALLOC(SOI3TOUT1_tout2Ptr,SOI3tout1Node,SOI3tout2Node) + TSTALLOC(SOI3TOUT2_tout1Ptr,SOI3tout2Node,SOI3tout1Node) + TSTALLOC(SOI3TOUT2_tout2Ptr,SOI3tout2Node,SOI3tout2Node) + } + if (here->SOI3numThermalNodes > 3) + { + TSTALLOC(SOI3TOUT2_tout3Ptr,SOI3tout2Node,SOI3tout3Node) + TSTALLOC(SOI3TOUT3_tout2Ptr,SOI3tout3Node,SOI3tout2Node) + TSTALLOC(SOI3TOUT3_tout3Ptr,SOI3tout3Node,SOI3tout3Node) + } + if (here->SOI3numThermalNodes > 4) + { + TSTALLOC(SOI3TOUT3_tout4Ptr,SOI3tout3Node,SOI3tout4Node) + TSTALLOC(SOI3TOUT4_tout3Ptr,SOI3tout4Node,SOI3tout3Node) + TSTALLOC(SOI3TOUT4_tout4Ptr,SOI3tout4Node,SOI3tout4Node) + } + + TSTALLOC(SOI3TOUT_toutPtr,SOI3toutNode,SOI3toutNode) + TSTALLOC(SOI3TOUT_dpPtr,SOI3toutNode,SOI3dNodePrime) + TSTALLOC(SOI3TOUT_gfPtr,SOI3toutNode,SOI3gfNode) + TSTALLOC(SOI3TOUT_gbPtr,SOI3toutNode,SOI3gbNode) + TSTALLOC(SOI3TOUT_bPtr,SOI3toutNode,SOI3bNode) + TSTALLOC(SOI3TOUT_spPtr,SOI3toutNode,SOI3sNodePrime) + + TSTALLOC(SOI3GF_toutPtr,SOI3gfNode,SOI3toutNode) + TSTALLOC(SOI3DP_toutPtr,SOI3dNodePrime,SOI3toutNode) + TSTALLOC(SOI3SP_toutPtr,SOI3sNodePrime,SOI3toutNode) + + TSTALLOC(SOI3B_toutPtr,SOI3bNode,SOI3toutNode) + } + } + } + return(OK); +} + +/* JimB - SIMetrix is based on SPICE3e2. Since */ +/* unsetup is a SPICE3f5 function, only use it in */ +/* the standard version */ + +int +SOI3unsetup(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + SOI3model *model; + SOI3instance *here; + + for (model = (SOI3model *)inModel; model != NULL; + model = model->SOI3nextModel) + { + for (here = model->SOI3instances; here != NULL; + here=here->SOI3nextInstance) + { + if (here->SOI3dNodePrime + && here->SOI3dNodePrime != here->SOI3dNode) + { + CKTdltNNum(ckt, here->SOI3dNodePrime); + here->SOI3dNodePrime= 0; + } + if (here->SOI3sNodePrime + && here->SOI3sNodePrime != here->SOI3sNode) + { + CKTdltNNum(ckt, here->SOI3sNodePrime); + here->SOI3sNodePrime= 0; + } + if (here->SOI3branch) + { + CKTdltNNum(ckt, here->SOI3branch); + here->SOI3branch=0; + } + if (here->SOI3tout1Node) + { + CKTdltNNum(ckt, here->SOI3tout1Node); + here->SOI3tout1Node = 0; + } + if (here->SOI3tout2Node) + { + CKTdltNNum(ckt, here->SOI3tout2Node); + here->SOI3tout2Node = 0; + } + if (here->SOI3tout3Node) + { + CKTdltNNum(ckt, here->SOI3tout3Node); + here->SOI3tout3Node = 0; + } + if (here->SOI3tout4Node) + { + CKTdltNNum(ckt, here->SOI3tout4Node); + here->SOI3tout4Node = 0; + } + } + } + return OK; +} diff --git a/src/spicelib/devices/soi3/soi3temp.c b/src/spicelib/devices/soi3/soi3temp.c new file mode 100644 index 000000000..8304fa95f --- /dev/null +++ b/src/spicelib/devices/soi3/soi3temp.c @@ -0,0 +1,597 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "soi3defs.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + + +int +SOI3temp(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + SOI3model *model = (SOI3model *)inModel; + SOI3instance *here; + +/* All variables ending in 1 denote that they pertain to the model + and so use model->SOI3tnom for temperature - the others use + here->SOI3temp. REFTEMP is temp at which hard-coded quantities + are given. */ + + double egfet,egfet1; /* Band Gap */ + double fact1,fact2; /* temperature/REFTEMP */ + double kt,kt1; /* kT @ various temps */ + double arg1; /* ??? */ + double ratio,ratio4; /* (temp/tnom) and (temp/tnom)^(3/2) */ + double phio; /* temp adjusted phi PHI0*/ + double pbo; + double gmanew,gmaold; + double capfact; + double pbfact1,pbfact; /* ??? */ + double vt,vtnom; + double wkfngfs; /* work function difference phi(gate,Si) */ + double wkfngf; /* work fn of front gate */ + double wkfngbs; /* work fn diff of back gate = 0 usu. */ + double fermig; /* fermi level of gate */ + double fermis; /* fermi level of Si */ + double xd_max; /* Minimum Si film thickness for this model to be valid */ + double eta_s; + + /* JimB - new variables for improved threshold voltage conversion model. */ + + double Edelta0; + double psi_delta0; + + /* loop through all the transistor models */ + for( ; model != NULL; model = model->SOI3nextModel) + { + + /* perform model defaulting */ + if(!model->SOI3tnomGiven) + { + model->SOI3tnom = ckt->CKTnomTemp; + } + + fact1 = model->SOI3tnom/REFTEMP; + vtnom = model->SOI3tnom*CONSTKoverQ; + kt1 = CONSTboltz * model->SOI3tnom; + egfet1 = 1.16-(7.02e-4*model->SOI3tnom*model->SOI3tnom)/ + (model->SOI3tnom+1108); + arg1 = -egfet1/(kt1+kt1)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP)); + /* this is -Egnom + Egref. - sign due to it being in bracket with log(fact1) + 'cos we wanted log(1/fact1). */ + pbfact1 = -2*vtnom *(1.5*log(fact1)+CHARGE*arg1); + /* 2 comes from fact phi=2*phi_F + ^ */ + + /* now model parameter preprocessing */ + + if(!model->SOI3frontOxideThicknessGiven || + model->SOI3frontOxideThickness == 0 || + !model->SOI3backOxideThicknessGiven || + model->SOI3backOxideThickness == 0 || + !model->SOI3bodyThicknessGiven || + model->SOI3bodyThickness == 0) + { + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "%s: SOI3 device film thickness must be supplied", + &model->SOI3modName); + return(E_BADPARM); + } + else /* Oxide and film thicknesses are supplied. */ + { + model->SOI3frontOxideCapFactor = 3.9 * 8.854214871e-12/ + model->SOI3frontOxideThickness; + model->SOI3backOxideCapFactor = 3.9 * 8.854214871e-12/ + model->SOI3backOxideThickness; + model->SOI3bodyCapFactor = 11.7 * 8.854214871e-12/ + model->SOI3bodyThickness; + model->SOI3C_ssf = CHARGE*model->SOI3frontSurfaceStateDensity*1e4; + model->SOI3C_ssb = CHARGE*model->SOI3backSurfaceStateDensity*1e4; + eta_s = 1 + model->SOI3C_ssf/model->SOI3frontOxideCapFactor; + + if(!model->SOI3transconductanceGiven) + { + if(!model->SOI3surfaceMobilityGiven) + { + model->SOI3surfaceMobility=600; + } + model->SOI3transconductance = model->SOI3surfaceMobility * + model->SOI3frontOxideCapFactor * 1e-4 /*(m**2/cm**2) + for mobility */; + } + + if(model->SOI3substrateDopingGiven) + { /* work everything out */ + if(model->SOI3substrateDoping*1e6 /*(cm**3/m**3)*/ >1.45e16) + { + if(!model->SOI3phiGiven) + { + model->SOI3phi = 2*vtnom* + log(model->SOI3substrateDoping* + 1e6/*(cm**3/m**3)*//1.45e16); + model->SOI3phi = MAX(0.1,model->SOI3phi); + } +/* Now that we have ascertained both the doping * + * and the body film thickness, check to see * + * if we have a thick film device. If not, complain ! */ + xd_max=2*sqrt((2* 11.7 * 8.854214871e-12 * model->SOI3phi)/ + (CHARGE*1e6 /*(cm**3/m**3)*/ * model->SOI3substrateDoping)); + + if(model->SOI3bodyThickness < xd_max) + { + (*(SPfrontEnd->IFerror))(ERR_WARNING, + "%s: Body Film thickness may be too small \nfor this model to be valid", + &model->SOI3modName); + /* return(E_PAUSE); don't want to stop, + just issue a warning */ + } +/* End of thick film check - msll 21/2/94 + Changed to only give warning - msll 31/10/95 */ + if(!model->SOI3vfbFGiven) + { + if(!model->SOI3frontFixedChargeDensityGiven) + model->SOI3frontFixedChargeDensity = 0; + fermis = model->SOI3type * 0.5 * model->SOI3phi; + wkfngf = 3.2; + if(!model->SOI3gateTypeGiven) model->SOI3gateType=1; + if(model->SOI3gateType != 0) + { + fermig = model->SOI3type *model->SOI3gateType*0.5*egfet1; + wkfngf = 3.25 + 0.5 * egfet1 - fermig; + } + wkfngfs = wkfngf - (3.25 + 0.5 * egfet1 +fermis); + + /* Fixed oxide charge is normally +ve for both + n and p-channel, so need -ve voltage to neutralise it */ + model->SOI3vfbF = wkfngfs - + model->SOI3frontFixedChargeDensity * + 1e4 /*(cm**2/m**2)*/ * + CHARGE/model->SOI3frontOxideCapFactor; + } + if(!model->SOI3vfbBGiven) + { + wkfngbs = (1-model->SOI3type)*0.5*model->SOI3phi; + /* assume p-sub */ + model->SOI3vfbB = wkfngbs - + model->SOI3backFixedChargeDensity * + 1e4 /*(cm**2/m**2)*/ * + CHARGE/model->SOI3backOxideCapFactor; + } + + if(!model->SOI3gammaGiven) + { + model->SOI3gamma = sqrt(2 * 11.70 * 8.854214871e-12 * + CHARGE * model->SOI3substrateDoping * + 1e6 /*(cm**3/m**3)*/)/model->SOI3frontOxideCapFactor; + } + + if(!model->SOI3gammaBGiven) + { + model->SOI3gammaB = sqrt(2 * 11.70 * 8.854214871e-12 * + CHARGE * model->SOI3substrateDoping * + 1e6 /*(cm**3/m**3)*/)/model->SOI3backOxideCapFactor; + } + if(model->SOI3vt0Given) + { /* NSUB given AND VT0 given - change vfbF */ + model->SOI3vfbF = model->SOI3vt0 - model->SOI3type * + (eta_s*model->SOI3phi + + model->SOI3gamma*sqrt(model->SOI3phi)); + } + else + { + if(model->SOI3vtexGiven) + { /* JimB - Improved threshold voltage conversion model. */ + if (model->SOI3delta0 < 0) + { + model->SOI3delta0 = 0; + } + if (model->SOI3vdex < 0) + { + /* Use convention that Vd at which Vtex was extracted */ + /* is always +ve. */ + model->SOI3vdex = -model->SOI3vdex; + } + /* Exponential term delta*phiF/phit (SOI3phi = 2phiF) */ + Edelta0 = exp(MIN(MAX_EXP_ARG, + (model->SOI3delta0*model->SOI3phi)/(2*vtnom)) + ); + /* Modified surface potential term (2+delta)*phiF + vdex/2 */ + /* (SOI3phi = 2phiF) */ + psi_delta0 = ((2+model->SOI3delta0)*model->SOI3phi/2) + + model->SOI3vdex/2; + model->SOI3vfbF = model->SOI3vtex - model->SOI3type * + (eta_s*psi_delta0 + model->SOI3gamma* + sqrt(psi_delta0 + vtnom*Edelta0) + ); + } + } + } + else /* Substrate doping less than intrinsic silicon, so set to zero. */ + { + model->SOI3substrateDoping = 0; + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "%s: Nsub < Ni",&model->SOI3modName); + return(E_BADPARM); + } + } + else /* NSUB not given, have to assume that VT0, PHI and GAMMA are given */ + { + xd_max=(2* 11.7 * 8.854214871e-12*sqrt(model->SOI3phi))/ + (model->SOI3gamma*model->SOI3frontOxideCapFactor); + if(model->SOI3bodyThickness < xd_max) + { + (*(SPfrontEnd->IFerror))(ERR_WARNING, + "%s :Body Film thickness may be too small \nfor this model to be valid", + &model->SOI3modName); + /* return(E_PAUSE); */ + } +/* End of thick film check - msll 21/2/94 + Changed to only give warning - msll 31/10/95 */ + + /* If vtext given in netlist, but no vt0. */ + if( (model->SOI3vtexGiven) && (!model->SOI3vt0Given) ) + { /* JimB - Improved threshold voltage conversion model. */ + if (model->SOI3delta0 < 0) + { + model->SOI3delta0 = 0; + } + if (model->SOI3vdex < 0) + { + /* Use convention that Vd at which Vtex was extracted */ + /* is always +ve. */ + model->SOI3vdex = -model->SOI3vdex; + } + /* Exponential term delta*phiF/phit (SOI3phi = 2phiF) */ + Edelta0 = exp(MIN(MAX_EXP_ARG, + (model->SOI3delta0*model->SOI3phi)/(2*vtnom)) + ); + /* Modified surface potential term (2+delta)*phiF + vdex/2 */ + /* (SOI3phi = 2phiF) */ + psi_delta0 = ((2+model->SOI3delta0)*model->SOI3phi/2) + + model->SOI3vdex/2; + model->SOI3vfbF = model->SOI3vtex - model->SOI3type * + (eta_s*psi_delta0 + model->SOI3gamma* + sqrt(psi_delta0 + vtnom*Edelta0) + ); + } + else /* If no vtex, then use vt0, either netlist or default value. */ + { /* Use standard threshold voltage model. */ + model->SOI3vfbF = model->SOI3vt0 - model->SOI3type * + (eta_s*model->SOI3phi + model->SOI3gamma*sqrt(model->SOI3phi)); + } + if (!model->SOI3vfbBGiven) + { + model->SOI3vfbB = 0; /* NSUB not given, vfbB not given */ + } + } + } + if((model->SOI3vsatGiven)&&(model->SOI3vsat != 0)) + { + model->SOI3TVF0 = 0.8*exp(model->SOI3tnom/600); + } + else + { + model->SOI3TVF0 = 0; + } + + + /* loop through all instances of the model */ + for(here = model->SOI3instances; here!= NULL; + here = here->SOI3nextInstance) + { + + double czbd; /* zero voltage bulk-drain capacitance */ + double czbs; /* zero voltage bulk-source capacitance */ + double cj0; /* default value of zero voltage bulk-source/drain capacitance*/ + double Nratio; /* ratio of Nsub*Nplus/Nsub+Nplus */ + double arg; /* 1 - fc */ + double sarg; /* (1-fc) ^^ (-mj) */ + + /* perform the parameter defaulting */ + if(!here->SOI3tempGiven) + { + here->SOI3temp = ckt->CKTtemp; + } + vt = here->SOI3temp * CONSTKoverQ; + ratio = here->SOI3temp/model->SOI3tnom; + fact2 = here->SOI3temp/REFTEMP; + kt = here->SOI3temp * CONSTboltz; + egfet = 1.16-(7.02e-4*here->SOI3temp*here->SOI3temp)/ + (here->SOI3temp+1108); + if (!model->SOI3chidGiven) + { + model->SOI3chid = CHARGE*egfet/CONSTboltz; + } + if (!model->SOI3chid1Given) + { + model->SOI3chid1 = CHARGE*egfet/CONSTboltz; + } + arg = -egfet/(kt+kt)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP)); + pbfact = -2*vt *(1.5*log(fact2)+CHARGE*arg); + + if(!here->SOI3lGiven) + { + here->SOI3l = ckt->CKTdefaultMosL; + } + if(!here->SOI3wGiven) + { + here->SOI3w = ckt->CKTdefaultMosW; + } + + if(here->SOI3l - 2 * model->SOI3latDiff <=0) + { + (*(SPfrontEnd->IFerror))(ERR_WARNING, + "%s: Effective channel length less than zero \nIncreasing \ + this instance length by 2*LD to remove effect of LD", + &(here->SOI3name)); + here->SOI3l += 2*model->SOI3latDiff; + } + ratio4 = exp(model->SOI3k*log(ratio)); /* ratio4 = (temp/tnom)^k */ + /* i.e. mobilitites prop to */ + /* T^-(k) where k=1.5 for old SPICE */ + here->SOI3tTransconductance = model->SOI3transconductance / ratio4; + here->SOI3tSurfMob = model->SOI3surfaceMobility/ratio4; + phio= (model->SOI3phi-pbfact1)/fact1; /* this is PHI @ REFTEMP */ + here->SOI3tPhi = fact2 * phio + pbfact; + here->SOI3tVfbF = model->SOI3vfbF + + (model->SOI3type * model->SOI3gateType * 0.5*(egfet1-egfet)) + + (model->SOI3type * 0.5 * (model->SOI3phi - here->SOI3tPhi)); + here->SOI3tVfbB = model->SOI3vfbB + + (1-model->SOI3type)*0.5*(here->SOI3tPhi-model->SOI3phi); + + here->SOI3tVto = here->SOI3tVfbF + model->SOI3type * + (model->SOI3gamma * sqrt(here->SOI3tPhi) + eta_s*here->SOI3tPhi); + + here->SOI3tSatCur = model->SOI3jctSatCur* + exp(-egfet/vt+egfet1/vtnom); + here->SOI3tSatCur1 = model->SOI3jctSatCur1* + exp(-egfet/vt+egfet1/vtnom); + here->SOI3tSatCurDens = model->SOI3jctSatCurDensity * + exp(-egfet/vt+egfet1/vtnom); + here->SOI3tSatCurDens1 = model->SOI3jctSatCurDensity1 * + exp(-egfet/vt+egfet1/vtnom); + + pbo = (model->SOI3bulkJctPotential - pbfact1)/fact1; + gmaold = (model->SOI3bulkJctPotential-pbo)/pbo; + capfact = 1/(1+model->SOI3bulkJctSideGradingCoeff* + (4e-4*(model->SOI3tnom-REFTEMP)-gmaold)); + here->SOI3tCbd = model->SOI3capBD * capfact; + here->SOI3tCbs = model->SOI3capBS * capfact; + here->SOI3tCjsw = model->SOI3sideWallCapFactor * capfact; + here->SOI3tBulkPot = fact2 * pbo+pbfact; + gmanew = (here->SOI3tBulkPot-pbo)/pbo; + capfact = (1+model->SOI3bulkJctSideGradingCoeff* + (4e-4*(here->SOI3temp-REFTEMP)-gmanew)); + here->SOI3tCbd *= capfact; + here->SOI3tCbs *= capfact; + here->SOI3tCjsw *= capfact; + here->SOI3tDepCap = model->SOI3fwdCapDepCoeff * here->SOI3tBulkPot; + + if (here->SOI3tSatCurDens == 0) + { + if (here->SOI3tSatCur == 0) + { + here->SOI3sourceVcrit = here->SOI3drainVcrit = + vt*log(vt/(CONSTroot2*1.0e-15)); + } + else + { + here->SOI3sourceVcrit = here->SOI3drainVcrit = + vt*log(vt/(CONSTroot2*here->SOI3tSatCur)); + } + } + else + { + here->SOI3drainVcrit = + vt * log( vt / (CONSTroot2 * + here->SOI3tSatCurDens * (here->SOI3w))); + here->SOI3sourceVcrit = + vt * log( vt / (CONSTroot2 * + here->SOI3tSatCurDens * (here->SOI3w))); + } + + if(model->SOI3capBDGiven) + { + czbd = here->SOI3tCbd; + } + else + { + if(model->SOI3sideWallCapFactorGiven) + { + czbd = here->SOI3tCjsw * (here->SOI3w*model->SOI3bodyThickness); + } + /* JimB - 2/1/99. Calculate default value for Cj0 */ + /* using PN junction theory. */ + else + { + Nratio = (1e6*model->SOI3nplusDoping * model->SOI3substrateDoping)/ + (model->SOI3nplusDoping + model->SOI3substrateDoping); + cj0 = sqrt((Nratio * 11.7 * 8.854214871e-12 * CHARGE)/ + (2 * here->SOI3tBulkPot)); + + /* JimB - temperature dependence code */ + gmaold = (model->SOI3bulkJctPotential-pbo)/pbo; + capfact = 1/(1+model->SOI3bulkJctSideGradingCoeff* + (4e-4*(model->SOI3tnom-REFTEMP)-gmaold)); + cj0 *= capfact; + gmanew = (here->SOI3tBulkPot-pbo)/pbo; + capfact = (1+model->SOI3bulkJctSideGradingCoeff* + (4e-4*(here->SOI3temp-REFTEMP)-gmanew)); + cj0 *= capfact; + + czbd = cj0 * (here->SOI3w*model->SOI3bodyThickness); + } + } + + arg = 1-model->SOI3fwdCapDepCoeff; + sarg = exp( (-model->SOI3bulkJctSideGradingCoeff) * log(arg) ); + here->SOI3Cbd = czbd; + here->SOI3f2d = czbd*(1-model->SOI3fwdCapDepCoeff* + (1+model->SOI3bulkJctSideGradingCoeff))* + sarg/arg; + here->SOI3f3d = czbd * model->SOI3bulkJctSideGradingCoeff * sarg/arg / + here->SOI3tBulkPot; + here->SOI3f4d = czbd*here->SOI3tBulkPot*(1-arg*sarg)/ + (1-model->SOI3bulkJctSideGradingCoeff) + -here->SOI3f3d/2* + (here->SOI3tDepCap*here->SOI3tDepCap) + -here->SOI3tDepCap * here->SOI3f2d; + + if(model->SOI3capBSGiven) + { + czbs=here->SOI3tCbs; + } + else + { + if(model->SOI3sideWallCapFactorGiven) + { + czbs=here->SOI3tCjsw * (here->SOI3w*model->SOI3bodyThickness); + } + /* JimB - 2/1/99. Calculate default value for Cj0 */ + /* using PN junction theory. */ + else + { + Nratio = (1e6*model->SOI3nplusDoping * model->SOI3substrateDoping)/ + (model->SOI3nplusDoping + model->SOI3substrateDoping); + cj0 = sqrt((Nratio * 11.7 * 8.854214871e-12 * CHARGE)/ + (2 * here->SOI3tBulkPot)); + + /* JimB - temperature dependence code */ + gmaold = (model->SOI3bulkJctPotential-pbo)/pbo; + capfact = 1/(1+model->SOI3bulkJctSideGradingCoeff* + (4e-4*(model->SOI3tnom-REFTEMP)-gmaold)); + cj0 *= capfact; + gmanew = (here->SOI3tBulkPot-pbo)/pbo; + capfact = (1+model->SOI3bulkJctSideGradingCoeff* + (4e-4*(here->SOI3temp-REFTEMP)-gmanew)); + cj0 *= capfact; + + czbs = cj0 * (here->SOI3w*model->SOI3bodyThickness); + } + } + arg = 1-model->SOI3fwdCapDepCoeff; + sarg = exp( (-model->SOI3bulkJctSideGradingCoeff) * log(arg) ); + here->SOI3Cbs = czbs; + here->SOI3f2s = czbs*(1-model->SOI3fwdCapDepCoeff* + (1+model->SOI3bulkJctSideGradingCoeff))* + sarg/arg; + here->SOI3f3s = czbs * model->SOI3bulkJctSideGradingCoeff * sarg/arg / + here->SOI3tBulkPot; + here->SOI3f4s = czbs*here->SOI3tBulkPot*(1-arg*sarg)/ + (1-model->SOI3bulkJctSideGradingCoeff) + -here->SOI3f3s/2* + (here->SOI3tDepCap*here->SOI3tDepCap) + -here->SOI3tDepCap * here->SOI3f2s; + + if(model->SOI3drainResistanceGiven) + { + if(model->SOI3drainResistance != 0) + { + here->SOI3drainConductance = 1/model->SOI3drainResistance; + } + else + { + here->SOI3drainConductance = 0; + } + } + else if (model->SOI3sheetResistanceGiven) + { + if(model->SOI3sheetResistance != 0) + { + here->SOI3drainConductance = + 1/(model->SOI3sheetResistance*here->SOI3drainSquares); + } + else + { + here->SOI3drainConductance = 0; + } + } + else if(model->SOI3rdwGiven) + { + if (model->SOI3rdw != 0) + { + /* JimB - 1e6 multiplying factor converts W from m to microns */ + here->SOI3drainConductance = + (here->SOI3w/model->SOI3rdw)*1e6; + } + else + { + here->SOI3drainConductance = 0; + } + } + else + { + here->SOI3drainConductance = 0; + } + + if(model->SOI3sourceResistanceGiven) + { + if(model->SOI3sourceResistance != 0) + { + here->SOI3sourceConductance = 1/model->SOI3sourceResistance; + } + else + { + here->SOI3sourceConductance = 0; + } + } + else if (model->SOI3sheetResistanceGiven) + { + if(model->SOI3sheetResistance != 0) + { + here->SOI3sourceConductance = + 1/(model->SOI3sheetResistance*here->SOI3sourceSquares); + } + else + { + here->SOI3sourceConductance = 0; + } + } + else if(model->SOI3rswGiven) + { + if (model->SOI3rsw != 0) + { + /* JimB - 1e6 multiplying factor converts W from m to microns */ + here->SOI3sourceConductance = + (here->SOI3w/model->SOI3rsw)*1e6; + } + else + { + here->SOI3sourceConductance = 0; + } + } + else + { + here->SOI3sourceConductance = 0; + } +/* extra stuff for newer model - msll Jan96 */ + } /* finish looping through all instances of the model*/ + } /* finish looping through all the transistor models */ + return(OK); +} + + + + diff --git a/src/spicelib/devices/soi3/soi3trun.c b/src/spicelib/devices/soi3/soi3trun.c new file mode 100644 index 000000000..43fb72c03 --- /dev/null +++ b/src/spicelib/devices/soi3/soi3trun.c @@ -0,0 +1,47 @@ +/********** +STAG version 2.6 +Copyright 2000 owned by the United Kingdom Secretary of State for Defence +acting through the Defence Evaluation and Research Agency. +Developed by : Jim Benson, + Department of Electronics and Computer Science, + University of Southampton, + United Kingdom. +With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. + +Based on STAG version 2.1 +Developed by : Mike Lee, +With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards + and John Bunyan. +Acknowledgements : Rupert Howes and Pete Mole. +**********/ + +/* Modified: 2001 Paolo Nenzi */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "soi3defs.h" +#include "sperror.h" +#include "suffix.h" + + +int +SOI3trunc(inModel,ckt,timeStep) + GENmodel *inModel; + register CKTcircuit *ckt; + double *timeStep; +{ + register SOI3model *model = (SOI3model *)inModel; + register SOI3instance *here; + + for( ; model != NULL; model = model->SOI3nextModel) + { + for(here=model->SOI3instances;here!=NULL;here = here->SOI3nextInstance) + { + CKTterr(here->SOI3qgf,ckt,timeStep); + CKTterr(here->SOI3qd,ckt,timeStep); + CKTterr(here->SOI3qs,ckt,timeStep); + } + } + 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/swinit.c b/src/spicelib/devices/sw/swinit.c new file mode 100644 index 000000000..0e2bdd381 --- /dev/null +++ b/src/spicelib/devices/sw/swinit.c @@ -0,0 +1,66 @@ +/* Modified: Alansfixes */ +#include + +#include + +#include "switf.h" +#include "swext.h" +#include "swinit.h" + + +SPICEdev SWinfo = { + { + "Switch", + "Ideal voltage controlled switch", + + &SWnSize, + &SWnSize, + SWnames, + + &SWpTSize, + SWpTable, + + &SWmPTSize, + SWmPTable, + 0 + }, + + DEVparam : SWparam, + DEVmodParam : SWmParam, + DEVload : SWload, + DEVsetup : SWsetup, + DEVunsetup : NULL, + DEVpzSetup : SWsetup, + DEVtemperature: NULL, + DEVtrunc : SWtrunc, + DEVfindBranch : NULL, + DEVacLoad : SWacLoad, + DEVaccept : NULL, + DEVdestroy : SWdestroy, + DEVmodDelete : SWmDelete, + DEVdelete : SWdelete, + DEVsetic : NULL, + DEVask : SWask, + DEVmodAsk : SWmAsk, + DEVpzLoad : SWpzLoad, + DEVconvTest : NULL, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, /* DISTO */ + DEVnoise : SWnoise, + + DEVinstSize : &SWiSize, + DEVmodSize : &SWmSize + +}; + + +SPICEdev * +get_sw_info(void) +{ + return &SWinfo; +} diff --git a/src/spicelib/devices/sw/swinit.h b/src/spicelib/devices/sw/swinit.h new file mode 100644 index 000000000..968f0bbf5 --- /dev/null +++ b/src/spicelib/devices/sw/swinit.h @@ -0,0 +1,13 @@ +#ifndef _SWINIT_H +#define _SWINIT_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; + +#endif 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/sw/swtrunc.c b/src/spicelib/devices/sw/swtrunc.c new file mode 100644 index 000000000..150a34182 --- /dev/null +++ b/src/spicelib/devices/sw/swtrunc.c @@ -0,0 +1,53 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "sperror.h" +#include "suffix.h" + +#include "swdefs.h" + +int +SWtrunc(inModel,ckt,timeStep) + GENmodel *inModel; + register CKTcircuit *ckt; + register double *timeStep; +{ + register SWmodel *model = (SWmodel*)inModel; + register SWinstance *here; + + double lastChange, maxChange, maxStep, ref; + + for( ; model!= NULL; model = model->SWnextModel) { + for(here = model->SWinstances ; here != NULL ; + here = here->SWnextInstance) { + lastChange = *(ckt->CKTstate0+(here->SWstate+1)) - + *(ckt->CKTstate1+(here->SWstate+1)); + if (*(ckt->CKTstate0+(here->SWstate))==0) { + ref = (model->SWvThreshold + model->SWvHysteresis); + if ((*(ckt->CKTstate0+(here->SWstate+1))0)) { + maxChange = (ref - *(ckt->CKTstate0+(here->SWstate+1))) * + 0.75 + 0.05; + maxStep = maxChange/lastChange * ckt->CKTdeltaOld[0]; + if (*timeStep > maxStep) { *timeStep = maxStep; } + } + } else { + ref = (model->SWvThreshold - model->SWvHysteresis); + if ((*(ckt->CKTstate0+(here->SWstate+1))>ref) && (lastChange<0)) { + maxChange = (ref - *(ckt->CKTstate0+(here->SWstate+1))) * + 0.75 - 0.05; + maxStep = maxChange/lastChange * ckt->CKTdeltaOld[0]; + if (*timeStep > maxStep) { *timeStep = maxStep; } + } + } + } + } + return(OK); +} 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/trainit.c b/src/spicelib/devices/tra/trainit.c new file mode 100644 index 000000000..8159d0b6e --- /dev/null +++ b/src/spicelib/devices/tra/trainit.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "traitf.h" +#include "traext.h" +#include "trainit.h" + + +SPICEdev TRAinfo = { + { + "Tranline", + "Lossless transmission line", + + &TRAnSize, + &TRAnSize, + TRAnames, + + &TRApTSize, + TRApTable, + + 0, + NULL, + 0 + }, + + DEVparam : TRAparam, + DEVmodParam : NULL, + DEVload : TRAload, + DEVsetup : TRAsetup, + DEVunsetup : TRAunsetup, + DEVpzSetup : TRAsetup, + DEVtemperature: TRAtemp, + DEVtrunc : TRAtrunc, + DEVfindBranch : NULL, + DEVacLoad : TRAacLoad, + DEVaccept : TRAaccept, + DEVdestroy : TRAdestroy, + DEVmodDelete : TRAmDelete, + DEVdelete : TRAdelete, + DEVsetic : NULL, + DEVask : TRAask, + DEVmodAsk : NULL, + DEVpzLoad : NULL, + DEVconvTest : NULL, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, /* DISTO */ + DEVnoise : NULL, /* NOISE */ + + DEVinstSize : &TRAiSize, + DEVmodSize : &TRAmSize + +}; + + +SPICEdev * +get_tra_info(void) +{ + return &TRAinfo; +} diff --git a/src/spicelib/devices/tra/trainit.h b/src/spicelib/devices/tra/trainit.h new file mode 100644 index 000000000..bd29e1a87 --- /dev/null +++ b/src/spicelib/devices/tra/trainit.h @@ -0,0 +1,11 @@ +#ifndef _TRAINIT_H +#define _TRAINIT_H + +extern IFparm TRApTable[ ]; +extern char *TRAnames[ ]; +extern int TRApTSize; +extern int TRAnSize; +extern int TRAiSize; +extern int TRAmSize; + +#endif 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/txl/Makefile.am b/src/spicelib/devices/txl/Makefile.am new file mode 100755 index 000000000..19f634b5c --- /dev/null +++ b/src/spicelib/devices/txl/Makefile.am @@ -0,0 +1,21 @@ +## Process this file with automake to produce Makefile.in + +pkglib_LTLIBRARIES = libtxl.la + +libtxl_la_SOURCES = \ + txl.c \ + txlask.c \ + txldest.c \ + txlload.c \ + txlmdel.c \ + txlparam.c \ + txlacct.c \ + txldel.c \ + txlmask.c \ + txlmpar.c \ + txlsetup.c \ + txlinit.c + +INCLUDES = -I$(top_srcdir)/src/include + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/txl/txl.c b/src/spicelib/devices/txl/txl.c new file mode 100644 index 000000000..c1b3d2a8c --- /dev/null +++ b/src/spicelib/devices/txl/txl.c @@ -0,0 +1,38 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + +#include "ngspice.h" +#include +#include "txldefs.h" +#include "devdefs.h" +#include "ifsim.h" +#include "suffix.h" + +IFparm TXLpTable[] = { + IP("pos_node", TXL_IN_NODE, IF_INTEGER,"Positive node of txl"), + IP("neg_node", TXL_OUT_NODE, IF_INTEGER,"Negative node of txl"), + IOP("length", TXL_LENGTH, IF_REAL,"length of line"), +}; + +IFparm TXLmPTable[] = { /* model parameters */ + IOP( "r", TXL_R, IF_REAL,"resistance per length"), + IOP( "l", TXL_L, IF_REAL,"inductance per length"), + IOP( "c", TXL_C, IF_REAL,"capacitance per length"), + IOP( "g", TXL_G, IF_REAL,"conductance per length"), + IOP( "length", TXL_length, IF_REAL,"length"), + IP( "txl", TXL_MOD_R, IF_FLAG,"Device is a txl model"), +}; + +char *TXLnames[] = { + "Y+", + "Y-" +}; + +int TXLnSize = NUMELEMS(TXLnames); +int TXLiSize = sizeof(TXLinstance); +int TXLmSize = sizeof(TXLmodel); +int TXLmPTSize = NUMELEMS(TXLmPTable); +int TXLpTSize = NUMELEMS(TXLpTable); diff --git a/src/spicelib/devices/txl/txlacct.c b/src/spicelib/devices/txl/txlacct.c new file mode 100644 index 000000000..bc4c979f6 --- /dev/null +++ b/src/spicelib/devices/txl/txlacct.c @@ -0,0 +1,76 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "txldefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +TXLaccept(ckt,inModel) + register CKTcircuit *ckt; + GENmodel *inModel; + /* set up the breakpoint table. + */ +{ + register TXLmodel *model = (TXLmodel *)inModel; + register TXLinstance *here; + int hint; + double h, v, v1; + NODE *nd; + TXLine *tx; + + /* loop through all the voltage source models */ + for( ; model != NULL; model = model->TXLnextModel ) { + + /* loop through all the instances of the model */ + for (here = model->TXLinstances; here != NULL ; + here=here->TXLnextInstance) { + + h = ckt->CKTdelta; + hint = (int) (h * 1e12); + if (hint != 0) { + tx = here->txline; + nd = tx->in_node; + if (nd->dvtag == 0) { + v = nd->V; + v1 = nd->V = *(ckt->CKTrhs + here->TXLposNode); + nd->dv = (v1 - v) / hint; + nd->dvtag = 1; + } + nd = tx->out_node; + if (nd->dvtag == 0) { + v = nd->V; + v1 = nd->V = *(ckt->CKTrhs + here->TXLnegNode); + nd->dv = (v1 - v) / hint; + nd->dvtag = 1; + } + } + else { + /* can't happen. */ + printf("zero h detected\n"); + exit(1); + } + } + } + model = (TXLmodel *)inModel; + for( ; model != NULL; model = model->TXLnextModel ) { + for (here = model->TXLinstances; here != NULL ; + here=here->TXLnextInstance) { + nd = here->txline->in_node; + nd->dvtag = 0; + nd = here->txline->out_node; + nd->dvtag = 0; + } + } + + return(OK); +} diff --git a/src/spicelib/devices/txl/txlask.c b/src/spicelib/devices/txl/txlask.c new file mode 100644 index 000000000..2fd2dde5f --- /dev/null +++ b/src/spicelib/devices/txl/txlask.c @@ -0,0 +1,43 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + + +#include "ngspice.h" +#include +#include +#include "const.h" +#include "txldefs.h" +#include "ifsim.h" +#include "cktdefs.h" +#include "sperror.h" +#include "suffix.h" + + +/*ARGSUSED*/ +int +TXLask(ckt,inst,which,value,select) + CKTcircuit *ckt; + GENinstance *inst; + int which; + IFvalue *value; + IFvalue *select; +{ + TXLinstance *fast = (TXLinstance *)inst; + switch(which) { + case TXL_OUT_NODE: + value->iValue = fast->TXLnegNode; + return(OK); + case TXL_IN_NODE: + value->iValue = fast->TXLposNode; + return(OK); + case TXL_LENGTH: + value->rValue = fast->TXLlength; + return(OK); + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} diff --git a/src/spicelib/devices/txl/txldefs.h b/src/spicelib/devices/txl/txldefs.h new file mode 100644 index 000000000..3bb520f10 --- /dev/null +++ b/src/spicelib/devices/txl/txldefs.h @@ -0,0 +1,92 @@ +#ifndef TXL +#define TXL + +#include "ifsim.h" +#include "cktdefs.h" +#include "gendefs.h" +#include "complex.h" +#include "noisedef.h" +#include "swec.h" + +/* information used to describe a single instance */ + +typedef struct sTXLinstance { + struct sTXLmodel *TXLmodPtr; /* backpointer to model */ + struct sTXLinstance *TXLnextInstance; /* pointer to next instance of + * current model*/ + + IFuid TXLname; /* pointer to character string naming this instance */ + + int TXLposNode; + int TXLnegNode; + double TXLlength; + int TXLibr1; + int TXLibr2; + TXLine *txline; /* pointer to SWEC txline type */ + TXLine *txline2; /* pointer to SWEC txline type. temporary storage */ + char *in_node_name; + char *out_node_name; + + double *TXLposPosptr; + double *TXLposNegptr; + double *TXLnegPosptr; + double *TXLnegNegptr; + double *TXLibr1Posptr; + double *TXLibr2Negptr; + double *TXLposIbr1ptr; + double *TXLnegIbr2ptr; + double *TXLibr1Negptr; + double *TXLibr2Posptr; + double *TXLibr1Ibr1ptr; + double *TXLibr2Ibr2ptr; + double *TXLibr1Ibr2ptr; + double *TXLibr2Ibr1ptr; + + unsigned TXLibr1Given : 1; + unsigned TXLibr2Given : 1; + unsigned TXLdcGiven : 1; + unsigned TXLlengthgiven : 1; /* flag to indicate C was specified */ + +} TXLinstance ; + + +/* per model data */ + +typedef struct sTXLmodel { /* model structure for a txl */ + int TXLmodType; /* type index of this device type */ + struct sTXLmodel *TXLnextModel; /* pointer to next possible model in + * linked list */ + TXLinstance * TXLinstances; /* pointer to list of instances that have this + * model */ + IFuid TXLmodName; /* pointer to character string naming this model */ + + double R; + double L; + double G; + double C; + double length; + unsigned Rgiven : 1; /* flag to indicate R was specified */ + unsigned Lgiven : 1; /* flag to indicate L was specified */ + unsigned Ggiven : 1; /* flag to indicate G was specified */ + unsigned Cgiven : 1; /* flag to indicate C was specified */ + unsigned lengthgiven : 1; /* flag to indicate C was specified */ + +} TXLmodel; + +/* instance parameters */ +#define TXL_IN_NODE 1 +#define TXL_OUT_NODE 2 +#define TXL_LENGTH 3 + +/* model parameters */ +#define TXL_R 101 +#define TXL_C 102 +#define TXL_G 103 +#define TXL_L 104 +#define TXL_length 105 +#define TXL_MOD_R 106 + +#include "txlext.h" +extern VI_list_txl *pool_vi_txl; + +#endif /*TXL*/ diff --git a/src/spicelib/devices/txl/txldel.c b/src/spicelib/devices/txl/txldel.c new file mode 100644 index 000000000..3817a3f65 --- /dev/null +++ b/src/spicelib/devices/txl/txldel.c @@ -0,0 +1,38 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + + +#include "ngspice.h" +#include +#include "txldefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +TXLdelete(inModel,name,inst) + GENmodel *inModel; + IFuid name; + GENinstance **inst; +{ + TXLmodel *model = (TXLmodel *)inModel; + TXLinstance **fast = (TXLinstance **)inst; + TXLinstance **prev = NULL; + TXLinstance *here; + + for( ; model ; model = model->TXLnextModel) { + prev = &(model->TXLinstances); + for(here = *prev; here ; here = *prev) { + if(here->TXLname == name || (fast && here==*fast) ) { + *prev= here->TXLnextInstance; + FREE(here); + return(OK); + } + prev = &(here->TXLnextInstance); + } + } + return(E_NODEV); +} diff --git a/src/spicelib/devices/txl/txldest.c b/src/spicelib/devices/txl/txldest.c new file mode 100644 index 000000000..6c371f9fe --- /dev/null +++ b/src/spicelib/devices/txl/txldest.c @@ -0,0 +1,36 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + + +#include "ngspice.h" +#include +#include "txldefs.h" +#include "suffix.h" + + +void +TXLdestroy(inModel) + GENmodel **inModel; +{ + TXLmodel **model = (TXLmodel **)inModel; + TXLinstance *here; + TXLinstance *prev = NULL; + TXLmodel *mod = *model; + TXLmodel *oldmod = NULL; + + for( ; mod ; mod = mod->TXLnextModel) { + if(oldmod) FREE(oldmod); + oldmod = mod; + prev = (TXLinstance *)NULL; + for(here = mod->TXLinstances ; here ; here = here->TXLnextInstance) { + if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + } + if(oldmod) FREE(oldmod); + *model = NULL; +} diff --git a/src/spicelib/devices/txl/txlext.h b/src/spicelib/devices/txl/txlext.h new file mode 100644 index 000000000..2ad036a7f --- /dev/null +++ b/src/spicelib/devices/txl/txlext.h @@ -0,0 +1,19 @@ +#ifdef __STDC__ +/* extern int TXLaccept(CKTcircuit*,GENmodel*); */ +extern int TXLdelete(GENmodel*,IFuid,GENinstance**); +extern void TXLdestroy(GENmodel**); +extern int TXLload(GENmodel*,CKTcircuit*); +extern int TXLmDelete(GENmodel**,IFuid,GENmodel*); +extern int TXLmParam(int,IFvalue*,GENmodel*); +extern int TXLparam(int,IFvalue*,GENinstance*,IFvalue*); +extern int TXLsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); +#else /* stdc */ +/* extern int TXLaccept(); */ +extern int TXLdelete(); +extern void TXLdestroy(); +extern int TXLload(); +extern int TXLmDelete(); +extern int TXLmParam(); +extern int TXLparam(); +extern int TXLsetup(); +#endif /* stdc */ diff --git a/src/spicelib/devices/txl/txlfbr.c b/src/spicelib/devices/txl/txlfbr.c new file mode 100644 index 000000000..07d9a5b8f --- /dev/null +++ b/src/spicelib/devices/txl/txlfbr.c @@ -0,0 +1,41 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "txldefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +TXLfindBr(ckt,inModel,name) + register CKTcircuit *ckt; + GENmodel *inModel; + register IFuid name; +{ + register TXLmodel *model = (TXLmodel *)inModel; + register TXLinstance *here; + int error; + CKTnode *tmp; + + for( ; model != NULL; model = model->TXLnextModel) { + for (here = model->TXLinstances; here != NULL; + here = here->TXLnextInstance) { + if(here->TXLname == name) { + if(here->TXLbranch == 0) { + error = CKTmkCur(ckt,&tmp,here->TXLname,"branch"); + if(error) return(error); + here->TXLbranch = tmp->number; + } + return(here->TXLbranch); + } + } + } + return(0); +} diff --git a/src/spicelib/devices/txl/txlinit.c b/src/spicelib/devices/txl/txlinit.c new file mode 100644 index 000000000..ffbd446f2 --- /dev/null +++ b/src/spicelib/devices/txl/txlinit.c @@ -0,0 +1,73 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ +#include + +#include + +#include "txlitf.h" +#include "txlext.h" +#include "txlinit.h" + + +SPICEdev TXLinfo = { + { + "TransLine", + "Simple Lossy Transmission Line", + + &TXLnSize, + &TXLnSize, + TXLnames, + + &TXLpTSize, + TXLpTable, + + &TXLmPTSize, + TXLmPTable, + }, + + TXLparam, + TXLmParam, + TXLload, + TXLsetup, + NULL, + NULL, + NULL, + NULL, + NULL, /* TXLfindBranch, */ + TXLload, /* ac load */ + NULL, + TXLdestroy, +#ifdef DELETES + TXLmDelete, + TXLdelete, +#else /* DELETES */ + NULL, + NULL, +#endif /* DELETES */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + &TXLiSize, + &TXLmSize + +}; + +SPICEdev * +get_txl_info(void) +{ + return &TXLinfo; +} diff --git a/src/spicelib/devices/txl/txlinit.h b/src/spicelib/devices/txl/txlinit.h new file mode 100644 index 000000000..7a64d3706 --- /dev/null +++ b/src/spicelib/devices/txl/txlinit.h @@ -0,0 +1,18 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ +#ifndef _TXLINIT_H +#define _TXLINIT_H + +extern IFparm TXLpTable[ ]; +extern IFparm TXLmPTable[ ]; +extern int TXLmPTSize; +extern int TXLpTSize; +extern char *TXLnames[ ]; +extern int TXLiSize; +extern int TXLmSize; +extern int TXLnSize; + +#endif diff --git a/src/spicelib/devices/txl/txlitf.h b/src/spicelib/devices/txl/txlitf.h new file mode 100644 index 000000000..b4e306300 --- /dev/null +++ b/src/spicelib/devices/txl/txlitf.h @@ -0,0 +1,12 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + +#ifndef DEV_TXL +#define DEV_TXL + +SPICEdev *get_txl_info(void); + +#endif diff --git a/src/spicelib/devices/txl/txlload.c b/src/spicelib/devices/txl/txlload.c new file mode 100644 index 000000000..0c73ceec0 --- /dev/null +++ b/src/spicelib/devices/txl/txlload.c @@ -0,0 +1,689 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + + +#include "ngspice.h" +#include +#include "txldefs.h" +#include "sperror.h" +#include "suffix.h" + +VI_list_txl *pool_vi_txl; +static double ratio[MAX_CP_TX_LINES]; +static int update_cnv_txl(); +static VI_list_txl *new_vi_txl(); +static void free_vi_txl(); +static int add_new_vi_txl(); +static int get_pvs_vi_txl(); +static int right_consts_txl(); +static int update_delayed_cnv_txl(); +static int multC(); +static int expC(); +static void copy_tx(); +/*static char *message = "tau of txl line is larger than max time step";*/ + +/*ARGSUSED*/ +int +TXLload(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + register TXLmodel *model = (TXLmodel *)inModel; + register TXLinstance *here; + TXLine *tx, *tx2; + int k, l; + int time, time2; + double h, h1, f; + int hint; + float hf; + NODE *nd; + double v, v1, g; + int cond1; + CKTnode *node; + VI_list_txl *vi, *vi_before; + int i, before, delta; + + + /* debug + printf("before txlload\n"); + SMPprint(ckt->CKTmatrix, stdout); + */ + + h = ckt->CKTdelta; + h1 = 0.5 * h; + time2 = (int) (ckt->CKTtime * 1e12); + hint = (int)(h * 1e12); + hf = (float)(h * 1e12); + time = (int) ((ckt->CKTtime - ckt->CKTdelta) * 1e12); + + cond1= ckt->CKTmode & MODEDC; + + for( ; model != NULL; model = model->TXLnextModel ) { + for (here = model->TXLinstances; here != NULL ; + here=here->TXLnextInstance) { + + tx = here->txline; + if (cond1 || tx->vi_head == NULL) continue; + + if (time < tx->vi_tail->time) { + time = tx->vi_tail->time; + hint = time2 - time; + } + + vi_before = tx->vi_tail; + before = tx->vi_tail->time; + + if (time > tx->vi_tail->time) { + + copy_tx(tx, here->txline2); + add_new_vi_txl(here, ckt, time); + + delta = time - before; + + nd = tx->in_node; + v = vi_before->v_i; + nd->V = tx->vi_tail->v_i; + v1 = nd->V; + nd->dv = (v1 - v) / delta; + + nd = tx->out_node; + v = vi_before->v_o; + v1 = nd->V = tx->vi_tail->v_o; + nd->dv = (v1 - v) / delta; + + if (tx->lsl) continue; + update_cnv_txl(tx, (float) delta); + if (tx->ext) update_delayed_cnv_txl(tx, (float) delta); + } + } + } + + model = (TXLmodel *)inModel; + for( ; model != NULL; model = model->TXLnextModel ) { + for (here = model->TXLinstances; here != NULL ; + here=here->TXLnextInstance) { + + tx = here->txline; + tx2 = here->txline2; + + if (!tx->lsl && hf > tx->taul) { + + fprintf(stderr, "your time step is too large for tau.\n"); + fprintf(stderr, "please decrease max time step in .tran card.\n"); + fprintf(stderr, ".tran tstep tstop tstart tmax.\n"); + fprintf(stderr, "make tmax smaller than %e and try again.\n", + tx->taul * 1e-12); + + return (1111); + + + } + + if (cond1) { + if (here->TXLlengthgiven) + g = model->R * here->TXLlength; + else g = model->R * here->TXLmodPtr->length; + *(here->TXLposIbr1ptr) += 1.0; + *(here->TXLnegIbr2ptr) += 1.0; + *(here->TXLibr1Ibr1ptr) += 1.0; + *(here->TXLibr1Ibr2ptr) += 1.0; + *(here->TXLibr2Posptr) += 1.0; + *(here->TXLibr2Negptr) -= 1.0; + *(here->TXLibr2Ibr1ptr) -= g; + + continue; + + } + + /* dc setup */ + if (here->TXLdcGiven == 0 && !cond1) { + nd = tx->in_node; + for (node = ckt->CKTnodes;node; node = node->next) { + if (strcmp(nd->name->id, node->name) == 0) { + tx->dc1 = tx2->dc1 = ckt->CKTrhsOld[node->number]; + nd->V = tx->dc1; + break; + } + } + nd = tx->out_node; + for (node = ckt->CKTnodes;node; node = node->next) { + if (strcmp(nd->name->id, node->name) == 0) { + tx->dc2 = tx2->dc2 = ckt->CKTrhsOld[node->number]; + nd->V = tx->dc2; + break; + } + } + here->TXLdcGiven = 1; + + vi = new_vi_txl(); + vi->time = 0; + + vi->i_i = *(ckt->CKTrhsOld + here->TXLibr1); + vi->i_o = *(ckt->CKTrhsOld + here->TXLibr2); + + vi->v_i = tx->dc1; + vi->v_o = tx->dc2; + + for (i = 0; i < 3; i++) { + tx->h1_term[i].cnv_i = + - tx->dc1 * tx->h1_term[i].c / tx->h1_term[i].x; + tx->h1_term[i].cnv_o = + - tx->dc2 * tx->h1_term[i].c / tx->h1_term[i].x; + } + for (i = 0; i < 3; i++) { + tx->h2_term[i].cnv_i = 0.0; + tx->h2_term[i].cnv_o = 0.0; + } + for (i = 0; i < 6; i++) { + tx->h3_term[i].cnv_i = + - tx->dc1 * tx->h3_term[i].c / tx->h3_term[i].x; + tx->h3_term[i].cnv_o = + - tx->dc2 * tx->h3_term[i].c / tx->h3_term[i].x; + } + vi->next = NULL; + tx->vi_tail = vi; + tx->vi_head = vi; + here->txline2->vi_tail = vi; + here->txline2->vi_head = vi; + + } + + /* change 6,6 1/18/93 + *(here->TXLibr1Ibr1ptr) -= 1.0; + *(here->TXLibr2Ibr2ptr) -= 1.0; + *(here->TXLposIbr1ptr) += 1.0; + *(here->TXLnegIbr2ptr) += 1.0; + *(here->TXLibr1Posptr) += tx->sqtCdL + h1 * tx->h1C; + *(here->TXLibr2Negptr) += tx->sqtCdL + h1 * tx->h1C; + */ + *(here->TXLibr1Ibr1ptr) = -1.0; + *(here->TXLibr2Ibr2ptr) = -1.0; + *(here->TXLposIbr1ptr) = 1.0; + *(here->TXLnegIbr2ptr) = 1.0; + *(here->TXLibr1Posptr) = tx->sqtCdL + h1 * tx->h1C; + *(here->TXLibr2Negptr) = tx->sqtCdL + h1 * tx->h1C; + + k = here->TXLibr1; + l = here->TXLibr2; + + copy_tx(tx2, tx); + + if (right_consts_txl(tx2, time, time2, h, h1, k, l, ckt)) { + if (tx->lsl) { + f = ratio[0] * tx->h3_aten; + *(here->TXLibr1Negptr) = -f; + *(here->TXLibr2Posptr) = -f; + f = ratio[0] * tx->h2_aten; + *(here->TXLibr1Ibr2ptr) = -f; + *(here->TXLibr2Ibr1ptr) = -f; + } + else { + tx->ext = 1; + tx->ratio = ratio[0]; + if (ratio[0] > 0.0) { + f = ratio[0] * (h1 * (tx->h3_term[0].c + + tx->h3_term[1].c + tx->h3_term[2].c + + tx->h3_term[3].c + tx->h3_term[4].c + + tx->h3_term[5].c ) + tx->h3_aten); + *(here->TXLibr1Negptr) = -f; + *(here->TXLibr2Posptr) = -f; + f = ratio[0] * (h1 * ( tx->h2_term[0].c + + tx->h2_term[1].c + tx->h2_term[2].c ) + + tx->h2_aten); + *(here->TXLibr1Ibr2ptr) = -f; + *(here->TXLibr2Ibr1ptr) = -f; + } + } + } + else tx->ext = 0; + } + } + + if (cond1) return (OK); + + /* debug + printf("after txlload\n"); + SMPprint(ckt->CKTmatrix, stdout); + */ + + return(OK); +} + +static void copy_tx(new, old) +TXLine *new, *old; +{ + int i; + VI_list_txl *temp; + + new->lsl = old->lsl; + new->ext = old->ext; + new->ratio = old->ratio; + new->taul = old->taul; + new->sqtCdL = old->sqtCdL; + new->h2_aten = old->h2_aten; + new->h3_aten = old->h3_aten; + new->h1C = old->h1C; + for (i= 0; i < 3; i++) { + new->h1e[i] = old->h1e[i]; + + new->h1_term[i].c = old->h1_term[i].c; + new->h1_term[i].x = old->h1_term[i].x; + new->h1_term[i].cnv_i = old->h1_term[i].cnv_i; + new->h1_term[i].cnv_o = old->h1_term[i].cnv_o; + + new->h2_term[i].c = old->h2_term[i].c; + new->h2_term[i].x = old->h2_term[i].x; + new->h2_term[i].cnv_i = old->h2_term[i].cnv_i; + new->h2_term[i].cnv_o = old->h2_term[i].cnv_o; + } + for (i= 0; i < 6; i++) { + new->h3_term[i].c = old->h3_term[i].c; + new->h3_term[i].x = old->h3_term[i].x; + new->h3_term[i].cnv_i = old->h3_term[i].cnv_i; + new->h3_term[i].cnv_o = old->h3_term[i].cnv_o; + } + + new->ifImg = old->ifImg; + if (new->vi_tail != old->vi_tail) { + /* someting wrong */ + exit (0); + } + + while (new->vi_head->time < old->vi_head->time) { + temp = new->vi_head; + new->vi_head = new->vi_head->next; + free_vi_txl(temp); + } + +} + + +static int update_cnv_txl(tx, h) + TXLine *tx; + float h; +{ + int i; + + double ai, bi, ao, bo; + register double e, t; + + ai = tx->in_node->V; + ao = tx->out_node->V; + bi = tx->in_node->dv; + bo = tx->out_node->dv; + + for (i = 0; i < 3; i++) { + register TERM *tm; + tm = &(tx->h1_term[i]); + + e = tx->h1e[i]; + + t = tm->c / tm->x; + bi *= t; + bo *= t; + + tm->cnv_i = (tm->cnv_i - bi*h) * e + (e - 1.0)*(ai*t + 1.0e+12*bi/tm->x); + tm->cnv_o = (tm->cnv_o - bo*h) * e + (e - 1.0)*(ao*t + 1.0e+12*bo/tm->x); + } + return (1); +} + + +static VI_list_txl +*new_vi_txl() +{ + VI_list_txl *q; + + if (pool_vi_txl) { + q = pool_vi_txl; + pool_vi_txl = pool_vi_txl->pool; + return(q); + } else + return((VI_list_txl *) malloc (sizeof (VI_list_txl))); +} + +static void +free_vi_txl(q) + VI_list_txl *q; +{ + q->pool = pool_vi_txl; + pool_vi_txl = q; +} + + +static int add_new_vi_txl(here, ckt, time) +TXLinstance *here; +CKTcircuit *ckt; +int time; +{ + VI_list_txl *vi; + TXLine *tx, *tx2; + + tx = here->txline; + tx2 = here->txline2; + + vi = new_vi_txl(); + vi->time = time; + tx->vi_tail->next = vi; + tx2->vi_tail->next = vi; + vi->next = NULL; + tx->vi_tail = vi; + tx2->vi_tail = vi; + + vi->v_i = *(ckt->CKTrhsOld + here->TXLposNode); + vi->v_o = *(ckt->CKTrhsOld + here->TXLnegNode); + vi->i_i = *(ckt->CKTrhsOld + here->TXLibr1); + vi->i_o = *(ckt->CKTrhsOld + here->TXLibr2); + return(1); +} + + +static int +get_pvs_vi_txl(t1, t2, tx, v1_i, v2_i, i1_i, i2_i, v1_o, v2_o, i1_o, i2_o) + TXLine *tx; + int t1, t2; + double *v1_i, *v2_i, *i1_i, *i2_i, *v1_o, *v2_o, *i1_o, *i2_o; +{ + double ta, tb; + register VI_list_txl *vi, *vi1; + register double f; + int ext = 0; + + ta = t1 - tx->taul; + tb = t2 - tx->taul; + if (tb <= 0) { + *v1_i = *v2_i = tx->dc1; + *v2_o = *v1_o = tx->dc2; + *i1_i = *i2_i = *i1_o = *i2_o = 0; + return(ext); + } + + if (ta <= 0) { + *i1_i = *i1_o = 0.0; + *v1_i = tx->dc1; + *v1_o = tx->dc2; + vi1 = tx->vi_head; + vi = vi1->next; + } else { + vi1 = tx->vi_head; + for (vi = vi1->next; vi->time < ta; vi = vi->next) { + /* free_vi_txl(vi1); */ + vi1 = vi; + } + f = (ta - vi1->time) / (vi->time - vi1->time); + *v1_i = vi1->v_i + f * (vi->v_i - vi1->v_i); + *v1_o = vi1->v_o + f * (vi->v_o - vi1->v_o); + *i1_i = vi1->i_i + f * (vi->i_i - vi1->i_i); + *i1_o = vi1->i_o + f * (vi->i_o - vi1->i_o); + tx->vi_head = vi1; + } + + if (tb > t1) { + + /* fprintf(stderr, "pvs: time = %d\n", t2); */ + ext = 1; + /* + f = tb - t1; + *v2_i = tx->in_node->V + tx->in_node->dv * f; + *v2_o = tx->out_node->V + tx->out_node->dv * f; + + if (vi) { + for (; vi->time != t1; vi = vi->next) + vi1 = vi; + + f /= (double) (t1 - vi1->time); + *i2_i = vi->i_i + f * (vi->i_i - vi1->i_i); + *i2_o = vi->i_o + f * (vi->i_o - vi1->i_o); + } else { + *i2_i = vi1->i_i; + *i2_o = vi1->i_o; + } + */ + ratio[0] = f = (tb - t1) / (t2 - t1); + if (vi) + for (; vi->time != t1; vi = vi->next); + else + vi = vi1; + f = 1 - f; + *v2_i = vi->v_i * f; + *v2_o = vi->v_o * f; + *i2_i = vi->i_i * f; + *i2_o = vi->i_o * f; + } else { + for (; vi->time < tb; vi = vi->next) + vi1 = vi; + + f = (tb - vi1->time) / (vi->time - vi1->time); + *v2_i = vi1->v_i + f * (vi->v_i - vi1->v_i); + *v2_o = vi1->v_o + f * (vi->v_o - vi1->v_o); + *i2_i = vi1->i_i + f * (vi->i_i - vi1->i_i); + *i2_o = vi1->i_o + f * (vi->i_o - vi1->i_o); + } + + return(ext); +} + + +static int +right_consts_txl(tx, t, time, h, h1, l1, l2, ckt) +TXLine *tx; +int t, time; +double h, h1; /*** h1 = 0.5 * h ***/ +int l1, l2; +CKTcircuit *ckt; +{ + int i; + register double ff=0.0, gg=0.0, e; + double v1_i, v2_i, i1_i, i2_i; + double v1_o, v2_o, i1_o, i2_o; + int ext; + + if (! tx->lsl) { + register double ff1=0.0; + for (i = 0; i < 3; i++) { + tx->h1e[i] = e = exp((double) tx->h1_term[i].x * h); + ff1 -= tx->h1_term[i].c * e; + ff -= tx->h1_term[i].cnv_i * e; + gg -= tx->h1_term[i].cnv_o * e; + } + ff += ff1 * h1 * tx->in_node->V; + gg += ff1 * h1 * tx->out_node->V; + } + + ext = get_pvs_vi_txl(t, time, tx, &v1_i, &v2_i, &i1_i, &i2_i, &v1_o, &v2_o, &i1_o, &i2_o); + + if (tx->lsl) { + ff = tx->h3_aten * v2_o + tx->h2_aten * i2_o; + gg = tx->h3_aten * v2_i + tx->h2_aten * i2_i; + } else { + if (tx->ifImg) { + double a, b, er, ei, a1, b1, a2, b2; + + for (i = 0; i < 4; i++) { + register TERM *tm; + tm = &(tx->h3_term[i]); + e = exp((double) tm->x * h); + tm->cnv_i = tm->cnv_i * e + h1 * tm->c * (v1_i * e + v2_i); + tm->cnv_o = tm->cnv_o * e + h1 * tm->c * (v1_o * e + v2_o); + } + expC(tx->h3_term[4].x, tx->h3_term[5].x, h, &er, &ei); + a2 = h1 * tx->h3_term[4].c; + b2 = h1 * tx->h3_term[5].c; + + a = tx->h3_term[4].cnv_i; + b = tx->h3_term[5].cnv_i; + multC(a, b, er, ei, &a, &b); + multC(a2, b2, v1_i * er + v2_i, v1_i * ei, &a1, &b1); + tx->h3_term[4].cnv_i = a + a1; + tx->h3_term[5].cnv_i = b + b1; + + a = tx->h3_term[4].cnv_o; + b = tx->h3_term[5].cnv_o; + multC(a, b, er, ei, &a, &b); + multC(a2, b2, v1_o * er + v2_o, v1_o * ei, &a1, &b1); + tx->h3_term[4].cnv_o = a + a1; + tx->h3_term[5].cnv_o = b + b1; + + ff += tx->h3_aten * v2_o; + gg += tx->h3_aten * v2_i; + + for (i = 0; i < 5; i++) { + ff += tx->h3_term[i].cnv_o; + gg += tx->h3_term[i].cnv_i; + } + ff += tx->h3_term[4].cnv_o; + gg += tx->h3_term[4].cnv_i; + + { + register TERM *tm; + tm = &(tx->h2_term[0]); + + e = exp((double) tm->x * h); + tm->cnv_i = tm->cnv_i * e + h1 * tm->c * (i1_i * e + i2_i); + tm->cnv_o = tm->cnv_o * e + h1 * tm->c * (i1_o * e + i2_o); + } + expC(tx->h2_term[1].x, tx->h2_term[2].x, h, &er, &ei); + a2 = h1 * tx->h2_term[1].c; + b2 = h1 * tx->h2_term[2].c; + + a = tx->h2_term[1].cnv_i; + b = tx->h2_term[2].cnv_i; + multC(a, b, er, ei, &a, &b); + multC(a2, b2, i1_i * er + i2_i, i1_i * ei, &a1, &b1); + tx->h2_term[1].cnv_i = a + a1; + tx->h2_term[2].cnv_i = b + b1; + + a = tx->h2_term[1].cnv_o; + b = tx->h2_term[2].cnv_o; + multC(a, b, er, ei, &a, &b); + multC(a2, b2, i1_o * er + i2_o, i1_o * ei, &a1, &b1); + tx->h2_term[1].cnv_o = a + a1; + tx->h2_term[2].cnv_o = b + b1; + + ff += tx->h2_aten * i2_o + tx->h2_term[0].cnv_o + + 2.0 * tx->h2_term[1].cnv_o; + gg += tx->h2_aten * i2_i + tx->h2_term[0].cnv_i + + 2.0 * tx->h2_term[1].cnv_i; + } else { + for (i = 0; i < 6; i++) { + register TERM *tm; + tm = &(tx->h3_term[i]); + + e = exp((double) tm->x * h); + tm->cnv_i = tm->cnv_i * e + h1 * tm->c * (v1_i * e + v2_i); + tm->cnv_o = tm->cnv_o * e + h1 * tm->c * (v1_o * e + v2_o); + } + + ff += tx->h3_aten * v2_o; + gg += tx->h3_aten * v2_i; + + for (i = 0; i < 6; i++) { + ff += tx->h3_term[i].cnv_o; + gg += tx->h3_term[i].cnv_i; + } + + for (i = 0; i < 3; i++) { + register TERM *tm; + tm = &(tx->h2_term[i]); + + e = exp((double) tm->x * h); + tm->cnv_i = tm->cnv_i * e + h1 * tm->c * (i1_i * e + i2_i); + tm->cnv_o = tm->cnv_o * e + h1 * tm->c * (i1_o * e + i2_o); + } + + ff += tx->h2_aten * i2_o; + gg += tx->h2_aten * i2_i; + + for (i = 0; i < 3; i++) { + ff += tx->h2_term[i].cnv_o; + gg += tx->h2_term[i].cnv_i; + } + } + } + + *(ckt->CKTrhs + l1) = ff; + *(ckt->CKTrhs + l2) = gg; + + return(ext); +} + + +static int +update_delayed_cnv_txl(tx, h) + TXLine *tx; + float h; +{ + float ratio; + register double f; + register VI_list_txl *vi; + register TERM *tms; + + h *= 0.5e-12; + ratio = tx->ratio; + vi = tx->vi_tail; + + if (ratio > 0.0) { + tms = tx->h3_term; + f = h * ratio * vi->v_i; + tms[0].cnv_i += f * tms[0].c; + tms[1].cnv_i += f * tms[1].c; + tms[2].cnv_i += f * tms[2].c; + tms[3].cnv_i += f * tms[3].c; + tms[4].cnv_i += f * tms[4].c; + tms[5].cnv_i += f * tms[5].c; + + f = h * ratio * vi->v_o; + tms[0].cnv_o += f * tms[0].c; + tms[1].cnv_o += f * tms[1].c; + tms[2].cnv_o += f * tms[2].c; + tms[3].cnv_o += f * tms[3].c; + tms[4].cnv_o += f * tms[4].c; + tms[5].cnv_o += f * tms[5].c; + + tms = tx->h2_term; + f = h * ratio * vi->i_i; + tms[0].cnv_i += f * tms[0].c; + tms[1].cnv_i += f * tms[1].c; + tms[2].cnv_i += f * tms[2].c; + + f = h * ratio * vi->i_o; + tms[0].cnv_o += f * tms[0].c; + tms[1].cnv_o += f * tms[1].c; + tms[2].cnv_o += f * tms[2].c; + } + + return(1); +} + +static int expC(ar, ai, h, cr, ci) + double ar, ai, *cr, *ci; + float h; +{ + double e, cs, si; + + e = exp((double) ar * h); + cs = cos((double) ai * h); + si = sin((double) ai * h); + *cr = e * cs; + *ci = e * si; + + return(1); +} + +static int multC(ar, ai, br, bi, cr, ci) + double ar, ai, br, bi; + double *cr, *ci; +{ + register double tp; + + tp = ar*br - ai*bi; + *ci = ar*bi + ai*br; + *cr = tp; + + return (1); + +} + diff --git a/src/spicelib/devices/txl/txlmask.c b/src/spicelib/devices/txl/txlmask.c new file mode 100644 index 000000000..995a8bf74 --- /dev/null +++ b/src/spicelib/devices/txl/txlmask.c @@ -0,0 +1,49 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + + +#include "ngspice.h" +#include +#include "const.h" +#include "cktdefs.h" +#include "ifsim.h" +#include "txldefs.h" +#include "sperror.h" +#include "devdefs.h" +#include "suffix.h" +#include "swec.h" + + +/* ARGSUSED */ +int +TXLmodAsk(ckt,inModel,which,value) + CKTcircuit *ckt; + GENmodel *inModel; + int which; + IFvalue *value; +{ + TXLmodel *model = (TXLmodel *)inModel; + switch(which) { + case TXL_R: + value->rValue = model->R; + return(OK); + case TXL_C: + value->rValue = model->C; + return(OK); + case TXL_G: + value->rValue = model->G; + return(OK); + case TXL_L: + value->rValue = model->L; + return(OK); + case TXL_length: + value->rValue = model->length; + return(OK); + default: + return(E_BADPARM); + } +} + diff --git a/src/spicelib/devices/txl/txlmdel.c b/src/spicelib/devices/txl/txlmdel.c new file mode 100644 index 000000000..434f03543 --- /dev/null +++ b/src/spicelib/devices/txl/txlmdel.c @@ -0,0 +1,45 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + + +#include "ngspice.h" +#include +#include "txldefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +TXLmDelete(inModel,modname,kill) + GENmodel **inModel; + IFuid modname; + GENmodel *kill; +{ + TXLmodel **model = (TXLmodel **)inModel; + TXLmodel *modfast = (TXLmodel *)kill; + TXLinstance *here; + TXLinstance *prev = NULL; + TXLmodel **oldmod; + oldmod = model; + + for( ; *model ; model = &((*model)->TXLnextModel)) { + if( (*model)->TXLmodName == modname || + (modfast && *model == modfast) ) goto delgot; + oldmod = model; + } + return(E_NOMOD); + +delgot: + *oldmod = (*model)->TXLnextModel; /* cut deleted device out of list */ + for(here = (*model)->TXLinstances ; here ; here = here->TXLnextInstance) { + if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + FREE(*model); + return(OK); + +} diff --git a/src/spicelib/devices/txl/txlmpar.c b/src/spicelib/devices/txl/txlmpar.c new file mode 100644 index 000000000..f3346bf55 --- /dev/null +++ b/src/spicelib/devices/txl/txlmpar.c @@ -0,0 +1,51 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + + +#include "ngspice.h" +#include +#include "const.h" +#include "ifsim.h" +#include "txldefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +TXLmParam(param,value,inModel) + int param; + IFvalue *value; + GENmodel *inModel; +{ + register TXLmodel *model = (TXLmodel *)inModel; + switch(param) { + case TXL_R: + model->R = value->rValue; + model->Rgiven = TRUE; + break; + case TXL_L: + model->L = value->rValue; + model->Lgiven = TRUE; + break; + case TXL_G: + model->G = value->rValue; + model->Ggiven = TRUE; + break; + case TXL_C: + model->C = value->rValue; + model->Cgiven = TRUE; + break; + case TXL_length: + model->length = value->rValue; + model->lengthgiven = TRUE; + break; + case TXL_MOD_R: + break; + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/txl/txlparam.c b/src/spicelib/devices/txl/txlparam.c new file mode 100644 index 000000000..83e9aaf93 --- /dev/null +++ b/src/spicelib/devices/txl/txlparam.c @@ -0,0 +1,40 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + +#include "ngspice.h" +#include +#include "const.h" +#include "ifsim.h" +#include "txldefs.h" +#include "sperror.h" +#include "suffix.h" + + +/* ARGSUSED */ +int +TXLparam(param,value,inst,select) + int param; + IFvalue *value; + GENinstance *inst; + IFvalue *select; +{ + TXLinstance *here = (TXLinstance *)inst; + switch(param) { + case TXL_IN_NODE: + here->TXLposNode = value->iValue; + break; + case TXL_OUT_NODE: + here->TXLnegNode = value->iValue; + break; + case TXL_LENGTH: + here->TXLlength = value->rValue; + here->TXLlengthgiven = TRUE; + break; + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/txl/txlsetup.c b/src/spicelib/devices/txl/txlsetup.c new file mode 100644 index 000000000..f9f728a42 --- /dev/null +++ b/src/spicelib/devices/txl/txlsetup.c @@ -0,0 +1,1140 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + + +#include "ngspice.h" +#include +#include "smpdefs.h" +#include "txldefs.h" +#include "sperror.h" +#include "suffix.h" + +#include "../cap/capdefs.h" + +static int ReadTxL(); +/*static int multC();*/ +static int main_pade(); +static int mac(); +/*static int divC();*/ +static int div_C(); +static int div3(); +/*static double approx1();*/ +/*static double approx2();*/ +static int find_roots(); +/*static double f3();*/ +/*static double f2();*/ +/*static int expC();*/ +/*static double exp_approx1();*/ +/*static double exp_approx2();*/ +static int exp_pade(); +/*static int exp_div3();*/ +static int exp_find_roots(); +static double eval2(); +static int get_c(); +static int get_h3(); +static int Gaussian_Elimination2(); +static int Gaussian_Elimination1(); +static int pade(); +static int update_h1C_c(); +static void y_pade(); +static double root3(); +static NDnamePt insert_ND(); +static NODE *insert_node(); +static NODE *NEW_node(); +/*static VI_list_txl *new_vi_txl();*/ + +NODE *node_tab = NULL; +NDnamePt ndn = NULL; +VI_list_txl *pool_vi_txl = NULL; + +/* pade.c */ +/** +static double xx1, xx2, xx3, xx4, xx5, xx6; +static double cc1, cc2, cc3, cc4, cc5, cc6; +**/ + +/* y.c */ +static double sqtCdL; +static double b1, b2, b3, b4, b5; +static double p1, p2, p3, q1, q2, q3; +static double c1, c2, c3, x1, x2, x3; +static double A[3][4]; + +/* exp.c */ +static double RdL, GdC, RG, tau, RC, GL; +static double a0, a1, a2, a3, a4, a5; +static double ep1, ep2, ep3, eq1, eq2, eq3; +static double ec1, ec2, ec3, ex1, ex2, ex3; +static int ifImg; +static double AA[3][4]; + +#define epsi 1.0e-16 +#define epsi2 1.0e-28 + +/* ARGSUSED */ +int +TXLsetup(matrix,inModel,ckt,state) + register SMPmatrix *matrix; + GENmodel *inModel; + CKTcircuit*ckt; + int *state; +{ + register TXLmodel *model = (TXLmodel *)inModel; + register TXLinstance *here; + CKTnode *tmp; + int error; + + /* loop through all the models */ + for( ; model != NULL; model = model->TXLnextModel ) { + + /* loop through all the instances of the model */ + for (here = model->TXLinstances; here != NULL ; + here=here->TXLnextInstance) { + +/* macro to make elements with built in test for out of memory */ +#define TSTALLOC(ptr,first,second) \ +if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ + return(E_NOMEM);\ +} + + if (! here->TXLibr1Given) { + error = CKTmkCur(ckt, &tmp, here->TXLname, "branch1"); + if (error) return (error); + here->TXLibr1 = tmp->number; + } + if (! here->TXLibr2Given) { + error = CKTmkCur(ckt, &tmp, here->TXLname, "branch2"); + if (error) return (error); + here->TXLibr2 = tmp->number; + } + + TSTALLOC(TXLposPosptr, TXLposNode, TXLposNode); + TSTALLOC(TXLposNegptr, TXLposNode, TXLnegNode); + TSTALLOC(TXLnegPosptr, TXLnegNode, TXLposNode); + TSTALLOC(TXLnegNegptr, TXLnegNode, TXLnegNode); + TSTALLOC(TXLibr1Posptr, TXLibr1, TXLposNode); + TSTALLOC(TXLibr2Negptr, TXLibr2, TXLnegNode); + TSTALLOC(TXLnegIbr2ptr, TXLnegNode, TXLibr2); + TSTALLOC(TXLposIbr1ptr, TXLposNode, TXLibr1); + TSTALLOC(TXLibr1Ibr1ptr, TXLibr1, TXLibr1); + TSTALLOC(TXLibr2Ibr2ptr, TXLibr2, TXLibr2); + TSTALLOC(TXLibr1Negptr, TXLibr1, TXLnegNode); + TSTALLOC(TXLibr2Posptr, TXLibr2, TXLposNode); + TSTALLOC(TXLibr1Ibr2ptr, TXLibr1, TXLibr2); + TSTALLOC(TXLibr2Ibr1ptr, TXLibr2, TXLibr1); + + here->in_node_name = CKTnodName(ckt,here->TXLposNode); + here->out_node_name = CKTnodName(ckt,here->TXLnegNode); + ReadTxL(here, ckt); + + } + } + + return(OK); +} + +/*** +static VI_list_txl +*new_vi_txl() +{ + VI_list_txl *q; + + if (pool_vi_txl) { + q = pool_vi_txl; + pool_vi_txl = pool_vi_txl->pool; + return(q); + } else + return((VI_list_txl *) malloc (sizeof (VI_list_txl))); +} +***/ + +static int ReadTxL(tx, ckt) +TXLinstance *tx; +CKTcircuit *ckt; +{ + double R, L, G, C, l; + char *p, *n; + NODE *nd; + ETXLine *et; + TXLine *t, *t2; + RLINE *line; + ERLINE *er; + double LL = 1e-12; + + p = tx->in_node_name; + n = tx->out_node_name; + + line = (RLINE *) malloc(sizeof (RLINE)); + er = (ERLINE *) malloc(sizeof (ERLINE)); + et = (ETXLine *) malloc(sizeof (ETXLine)); + t = (TXLine *) malloc(sizeof (TXLine)); + t2 = (TXLine *) malloc(sizeof (TXLine)); + tx->txline = t; + tx->txline2 = t2; + t->newtp = 0; + t2->newtp = 0; + t->vi_head = t->vi_tail = NULL; + nd = insert_node(p); + et->link = nd->tptr; + nd->tptr = et; + et->line = t; + t->in_node = nd; + t2->in_node = nd; + er->link = nd->rlptr; + nd->rlptr = er; + er->rl = line; + line->in_node = nd; + et = (ETXLine *) malloc(sizeof (ETXLine)); + nd = insert_node(n); + et->link = nd->tptr; + nd->tptr = et; + et->line = t; + t->out_node = nd; + t2->out_node = nd; + er = (ERLINE *) malloc(sizeof (ERLINE)); + er->link = nd->rlptr; + nd->rlptr = er; + er->rl = line; + line->out_node = nd; + t->dc1 = t->dc2 = 0.0; + t2->dc1 = t2->dc2 = 0.0; + t->lsl = 0; + t2->lsl = 0; + l = 0.0; + + R = tx->TXLmodPtr->R; + L = tx->TXLmodPtr->L; + L = MAX(L, LL); + C = tx->TXLmodPtr->C; + G = tx->TXLmodPtr->G; + if (tx->TXLlengthgiven == TRUE) + l = tx->TXLlength; + else l = tx->TXLmodPtr->length; + + + if (l == 0.0) { + fprintf(stderr, "(Error) transmission line of zero length\n"); + exit(0); + } + else { + if (R / L < 5.0e+5) { + line->g = 1.0e+2; + if (G < 1.0e-2) { + t->lsl = 1; /* lossless line */ + t->taul = sqrt((double) C * L) * l * 1.0e12; + t->h3_aten = t->sqtCdL = sqrt((double) C / L); + t->h2_aten = 1.0; + t->h1C = 0.0; + } + } + else line->g = 1.0 / (R * l); + } + + if (! t->lsl) + main_pade(R, L, G, C, l, t); + + return(1); +} + + +/**************************************************************** + pade.c : Calculate the Pade Approxximation of Y(s) + ****************************************************************/ + + +static int main_pade(R, L, G, C, l, h) + double R, L, G, C, l; + TXLine *h; +{ + y_pade(R, L, G, C, h); + h->ifImg = exp_pade(R, L, G, C, l, h); + get_h3(h); + h->taul *= 1.0e12; + update_h1C_c(h); + + return(1); +} + +static int div_C(ar, ai, br, bi, cr, ci) + double ar, ai, br, bi; + double *cr, *ci; +{ + *cr = ar * br + ai * bi; + *ci = - ar * bi + ai * br; + *cr = *cr / (br * br + bi * bi); + *ci = *ci / (br * br + bi * bi); + return (1); +} + +/*** +static int expC(ar, ai, h, cr, ci) + double ar, ai, *cr, *ci; + float h; +{ + double e, cs, si; + + e = exp((double) ar * h); + cs = cos((double) ai * h); + si = sin((double) ai * h); + *cr = e * cs; + *ci = e * si; + + return(1); +} +***/ + +/*** +static int multC(ar, ai, br, bi, cr, ci) + double ar, ai, br, bi; + double *cr, *ci; +{ + *cr = ar*br - ai*bi; + *ci = ar*bi + ai*br; + + return(1); +} +***/ + +/*** +static int divC(ar, ai, br, bi, cr, ci) + double ar, ai, br, bi; + double *cr, *ci; +{ + double t; + t = br*br + bi*bi; + *cr = (ar*br + ai*bi) / t; + *ci = (ai*br - ar*bi) / t; + + return(1); +} +***/ + +static int get_h3(h) + TXLine *h; +{ + double cc1, cc2, cc3, cc4, cc5, cc6; + double xx1, xx2, xx3, xx4, xx5, xx6; + + h->h3_aten = h->h2_aten * h->sqtCdL; + h->h3_term[0].x = xx1 = h->h1_term[0].x; + h->h3_term[1].x = xx2 = h->h1_term[1].x; + h->h3_term[2].x = xx3 = h->h1_term[2].x; + h->h3_term[3].x = xx4 = h->h2_term[0].x; + h->h3_term[4].x = xx5 = h->h2_term[1].x; + h->h3_term[5].x = xx6 = h->h2_term[2].x; + cc1 = h->h1_term[0].c; + cc2 = h->h1_term[1].c; + cc3 = h->h1_term[2].c; + cc4 = h->h2_term[0].c; + cc5 = h->h2_term[1].c; + cc6 = h->h2_term[2].c; + + if (h->ifImg) { + double r, i; + + h->h3_term[0].c = cc1 + cc1 * (cc4/(xx1-xx4) + + 2.0*(cc5*xx1-xx6*cc6-xx5*cc5)/(xx1*xx1-2.0*xx5*xx1+xx5*xx5+xx6*xx6)); + h->h3_term[1].c = cc2 + cc2 * (cc4/(xx2-xx4) + + 2.0*(cc5*xx2-xx6*cc6-xx5*cc5)/(xx2*xx2-2.0*xx5*xx2+xx5*xx5+xx6*xx6)); + h->h3_term[2].c = cc3 + cc3 * (cc4/(xx3-xx4) + + 2.0*(cc5*xx3-xx6*cc6-xx5*cc5)/(xx3*xx3-2.0*xx5*xx3+xx5*xx5+xx6*xx6)); + + h->h3_term[3].c = cc4 + cc4 * (cc1/(xx4-xx1) + cc2/(xx4-xx2) + cc3/(xx4-xx3)); + + h->h3_term[4].c = cc5; + h->h3_term[5].c = cc6; + div_C(cc5, cc6, xx5-xx1, xx6, &r, &i); + h->h3_term[4].c += r * cc1; + h->h3_term[5].c += i * cc1; + div_C(cc5, cc6, xx5-xx2, xx6, &r, &i); + h->h3_term[4].c += r * cc2; + h->h3_term[5].c += i * cc2; + div_C(cc5, cc6, xx5-xx3, xx6, &r, &i); + h->h3_term[4].c += r * cc3; + h->h3_term[5].c += i * cc3; + } else { + h->h3_term[0].c = cc1 + cc1 * (cc4/(xx1-xx4) + cc5/(xx1-xx5) + cc6/(xx1-xx6)); + h->h3_term[1].c = cc2 + cc2 * (cc4/(xx2-xx4) + cc5/(xx2-xx5) + cc6/(xx2-xx6)); + h->h3_term[2].c = cc3 + cc3 * (cc4/(xx3-xx4) + cc5/(xx3-xx5) + cc6/(xx3-xx6)); + + h->h3_term[3].c = cc4 + cc4 * (cc1/(xx4-xx1) + cc2/(xx4-xx2) + cc3/(xx4-xx3)); + h->h3_term[4].c = cc5 + cc5 * (cc1/(xx5-xx1) + cc2/(xx5-xx2) + cc3/(xx5-xx3)); + h->h3_term[5].c = cc6 + cc6 * (cc1/(xx6-xx1) + cc2/(xx6-xx2) + cc3/(xx6-xx3)); + } + + return(1); +} + +static int update_h1C_c(h) + TXLine *h; +{ + int i; + double d = 0; + + for (i = 0; i < 3; i++) { + h->h1_term[i].c *= h->sqtCdL; + d += h->h1_term[i].c; + } + h->h1C = d; + + for (i = 0; i < 3; i++) + h->h2_term[i].c *= h->h2_aten; + + for (i = 0; i < 6; i++) + h->h3_term[i].c *= h->h3_aten; + + return(1); +} +/**************************************************************** + y.c : Calculate the Pade Approximation of Y(s) + ****************************************************************/ + + +static double eval2(a, b, c, x) + double a, b, c, x; +{ + return(a*x*x + b*x + c); +} + +/*** +static double approx1(st) + double st; +{ + double s3, s2, s1; + + s1 = st; + s2 = s1 * s1; + s3 = s2 * s1; + + return((s3 + q1*s2 + q2*s1 + q3) / (s3 + p1*s2 + p2*s1 + p3)); +} +***/ +/*** +static double approx2(st) + double st; +{ + return(1.0 + c1/(st - x1) + c2/(st - x2) + c3/(st - x3)); +} +***/ + +static void y_pade(R, L, G, C, h) + double R, L, G, C; + TXLine *h; +{ + + /* float RdL, GdC; */ + double RdL, GdC; + + sqtCdL = sqrt((double) C / L); + RdL = R / L; + GdC = G / C; + + mac(GdC, RdL, &b1, &b2, &b3, &b4, &b5); + + A[0][0] = 1.0 - sqrt((double) (GdC / RdL)); + A[0][1] = b1; + A[0][2] = b2; + A[0][3] = -b3; + + A[1][0] = b1; + A[1][1] = b2; + A[1][2] = b3; + A[1][3] = -b4; + + A[2][0] = b2; + A[2][1] = b3; + A[2][2] = b4; + A[2][3] = -b5; + + Gaussian_Elimination1(3); + + p3 = A[0][3]; + p2 = A[1][3]; + p1 = A[2][3]; + + q1 = p1 + b1; + q2 = b1 * p1 + p2 + b2; + q3 = p3 * sqrt((double) (GdC / RdL)); + + find_roots(p1, p2, p3, &x1, &x2, &x3); + c1 = eval2(q1 - p1, q2 - p2, q3 - p3, x1) / + eval2((double) 3.0, (double) 2.0 * p1, p2, x1); + c2 = eval2(q1 - p1, q2 - p2, q3 - p3, x2) / + eval2((double) 3.0, (double) 2.0 * p1, p2, x2); + c3 = eval2(q1 - p1, q2 - p2, q3 - p3, x3) / + eval2((double) 3.0, (double) 2.0 * p1, p2, x3); + + h->sqtCdL = sqtCdL; + h->h1_term[0].c = c1; + h->h1_term[1].c = c2; + h->h1_term[2].c = c3; + h->h1_term[0].x = x1; + h->h1_term[1].x = x2; + h->h1_term[2].x = x3; + +} + +static int Gaussian_Elimination1(dims) + int dims; +{ + register int i, j, k, dim; + register double f; + int imax; + double max; + + dim = dims; + + for (i = 0; i < dim; i++) { + imax = i; + max = ABS(A[i][i]); + for (j = i+1; j < dim; j++) + if (ABS(A[j][i]) > max) { + imax = j; + max = ABS(A[j][i]); + } + if (max < epsi) { + fprintf(stderr, " can not choose a pivot \n"); + exit(0); + } + if (imax != i) + for (k = i; k <= dim; k++) { + f = A[i][k]; + A[i][k] = A[imax][k]; + A[imax][k] = f; + } + + f = 1.0 / A[i][i]; + A[i][i] = 1.0; + + for (j = i+1; j <= dim; j++) + A[i][j] *= f; + + for (j = 0; j < dim ; j++) { + if (i == j) + continue; + f = A[j][i]; + A[j][i] = 0.0; + for (k = i+1; k <= dim; k++) + A[j][k] -= f * A[i][k]; + } + } + return(1); +} + +static double root3(a1, a2, a3, x) + double x; + double a1, a2, a3; +{ + double t1, t2; + + t1 = x*x*x + a1*x*x + a2*x + a3; + t2 = 3.0*x*x + 2.0*a1*x + a2; + + return(x - t1 / t2); +} + +static int div3(a1, a2, a3, x, p1, p2) + double x; + double a1, a2, a3; + double *p1, *p2; +{ + *p1 = a1 + x; + *p2 = - a3 / x; + + return(1); +} + + +/**************************************************************** + Calculate the Maclaurin series of F(z) + + F(z) = sqrt((1+az) / (1+bz)) + = 1 + b1 z + b2 z^2 + b3 z^3 + b4 z^4 + b5 z^5 + ****************************************************************/ + +/*** +static double f3(a, b, z) + double a, b, z; +{ + double t4, t3, t2, t1; + double t14, t13, t12, t11; + double sqt11; + + t1 = 1 / (1.0 + b * z); + t2 = t1 * t1; + t3 = t2 * t1; + t4 = t3 * t1; + + t11 = (1.0 + a * z) * t1; + t12 = (1.0 + a * z) * t2; + t13 = (1.0 + a * z) * t3; + t14 = (1.0 + a * z) * t4; + + sqt11 = sqrt(t11); + + + return( + -0.5 * (-2.0*a*b*t2 + 2.0*b*b*t13) * (a*t1 - b*t12) / (t11*sqt11) + +3.0/8.0 * (a*t1-b*t12)*(a*t1-b*t12)*(a*t1-b*t12) / (t11*t11*sqt11) + +0.5 * (4.0*a*b*b*t3 + 2.0*a*b*b*t3 - 6.0*b*b*b*t14) / sqt11 + -0.25 * (-2.0*a*b*t2 + 2.0*b*b*t13) * (a*t1-b*(1.0+a*z)) / + (t11*sqt11) + ); +} +***/ + +/*** +static double f2(a, b, z) + double a, b, z; +{ + double t3, t2, t1; + double t13, t12, t11; + double sqt11; + + t1 = 1 / (1.0 + b * z); + t2 = t1 * t1; + t3 = t2 * t1; + + t11 = (1.0 + a * z) * t1; + t12 = (1.0 + a * z) * t2; + t13 = (1.0 + a * z) * t3; + + sqt11 = sqrt(t11); + + return( + -0.25 * (a*t1-b*t12) * (a*t1-b*t12) / (t11*sqt11) + +0.5 * (-2.0*a*b*t2 + 2.0*b*b*t13) / sqt11 + ); +} +***/ + +static int mac(at, bt, b1, b2, b3, b4, b5) + /* float at, bt; */ + double at, bt; + double *b1, *b2, *b3, *b4, *b5; +{ + double a, b; + double y1, y2, y3, y4, y5; + + a = at; + b = bt; + + y1 = *b1 = 0.5 * (a - b); + y2 = 0.5 * (3.0 * b * b - 2.0 * a * b - a * a) * y1 / (a - b); + y3 = ((3.0 * b * b + a * a) * y1 * y1 + 0.5 * (3.0 * b * b + - 2.0 * a * b - a * a) * y2) / (a - b); + y4 = ((3.0 * b * b - 3.0 * a * a) * y1 * y1 * y1 + (9.0 * b * b + + 3.0 * a * a) * y1 * y2 + 0.5 * (3.0 * b * b - 2.0 * a * b + - a * a) * y3) / (a - b); + y5 = (12.0 * a * a * y1 * y1 * y1 * y1 + y1 * y1 * y2 * ( + 18.0 * b * b - 18.0 * a * a) + (9.0 * b * b + 3.0 * a * a) * + (y2 * y2 + y1 * y3) + (3.0 * b * b + a * a) * y1 * y3 + + 0.5 * (3.0 * b * b - 2.0 * a * b - a * a) * y4) / (a - b); + + *b2 = y2 / 2.0; + *b3 = y3 / 6.0; + *b4 = y4 / 24.0; + *b5 = y5 / 120.0; + + return(1); +} + + +/**************************************************** + exp.c + ****************************************************/ + +/*** +static double exp_approx1(st) + double st; +{ + double s3, s2, s1; + + s1 = st; + s2 = s1 * s1; + s3 = s2 * s1; + + return(exp((double) - st * tau - a0) * + (s3 + eq1*s2 + eq2*s1 + eq3) / (s3 + ep1*s2 + ep2*s1 + ep3)); +} +***/ + +static int get_c(eq1, eq2, eq3, ep1, ep2, a, b, cr, ci) + double eq1, eq2, eq3, ep1, ep2, a, b; + double *cr, *ci; +{ + double d, n; + + d = (3.0*(a*a-b*b)+2.0*ep1*a+ep2)*(3.0*(a*a-b*b)+2.0*ep1*a+ep2); + d += (6.0*a*b+2.0*ep1*b)*(6.0*a*b+2.0*ep1*b); + n = -(eq1*(a*a-b*b)+eq2*a+eq3)*(6.0*a*b+2.0*ep1*b); + n += (2.0*eq1*a*b+eq2*b)*(3.0*(a*a-b*b)+2.0*ep1*a+ep2); + *ci = n/d; + n = (3.0*(a*a-b*b)+2.0*ep1*a+ep2)*(eq1*(a*a-b*b)+eq2*a+eq3); + n += (6.0*a*b+2.0*ep1*b)*(2.0*eq1*a*b+eq2*b); + *cr = n/d; + + return(1); +} + +/*** +static double exp_approx2(st) + double st; +{ + if (ifImg) + return(1.0 + ec1/(st - ex1) + 2.0*(ec2*(st-ex2)-ec3*ex3) / + ((st-ex2)*(st-ex2) + ex3*ex3)); + else + return(1.0 + ec1/(st - ex1) + ec2/(st - ex2) + ec3/(st - ex3)); +} +***/ + +static int exp_pade(R, L, G, C, l, h) + float R, L, G, C, l; + TXLine *h; +{ + + tau = sqrt((double) L*C); + RdL = R / L; + GdC = G / C; + RG = R * G; + RC = R * C; + GL = G * L; + + { + double a, b, t; + double y1, y2, y3, y4, y5, y6; + + a = RdL; + b = GdC; + t = tau; + + /* + y1 = 0.5 * (a + b); + y2 = a * b - y1 * y1; + y3 = - a * b * y1 - 2.0 * y1 * y2 + y1 * y1 * y1; + y4 = 2.0 * a * b * y1 * y1 - a * b * y2 - 2.0 * y2 * y2 + - 2.0 * y1 * y3 + 5.0 * y1 * y1 * y2 + - 2.0 * y1 * y1 * y1 * y1; + y5 = 6.0 * a * b * (y1 * y2 - y1 * y1 * y1) - a * b * y3 + - 2.0 * y1 * y4 + - 6.0 * y2 * y3 + 12.0 * y2 * y2 * y1 + 7.0 * y1 * y1 * y3 + -10.0 * y1 * y1 * y1 * y2 - 8.0 * y1 * y1 * y1 * y2 + + 6.0 * y1 * y1 * y1 * y1 * y1; + y6 = 24.0 * a * b * y1 * y1 * y1 * y1 - 36.0 * a * b * y1 * y1 * y2 + + 6.0 * a * b * y2 * y2 + 8.0 * a * b * y1 * y3 - 2.0 * y2 * y4 + - 2.0 * y1 * y5 + 2.0 * y1 * y1 * y4 - a * b * y4 -6.0 * y3 * y3 + + 44.0 * y1 * y2 * y3 + 60.0 * y1 * y1 * y1 * y1 * y2 + -24.0 * y1 * y1 * y1 * y1 * y1 * y1 + 12.0 * y2 * y2 * y2 + -54.0 * y1 * y1 * y2 * y2 + 7.0 * y1 * y1 * y4 + -24.0 * y1 * y1 * y1 * y3 - 24.0 * y1 * y1 * y2 * y2 + -8.0 * y1 * y1 * y1 * y3 + 24.0 * y1 * y1 * y1 * y1 * y2 + - 6.0 * y2 * y4; + */ + + y1 = 0.5 * (a + b); + y2 = a * b - y1 * y1; + y3 = -3.0 * y1 * y2; + y4 = -3.0 * y2 * y2 - 4.0 * y1 * y3; + y5 = - 5.0 * y1 * y4 -10.0 * y2 * y3; + y6 = -10.0 * y3 * y3 - 15.0 * y2 * y4 - 6.0 * y1 * y5; + + a0 = y1 * t; + a1 = y2 * t * t / 2.0; + a2 = y3 * t * t * t / 6.0; + a3 = y4 * t * t * t * t / 24.0; + a4 = y5 * t * t * t * t * t / 120.0; + a5 = y6 * t * t * t * t * t * t / 720.0; + + } + + a0 *= l; + a1 *= l; + a2 *= l; + a3 *= l; + a4 *= l; + a5 *= l; + + pade(l); + + h->taul = tau * l; + h->h2_aten = exp(- a0); + h->h2_term[0].c = ec1; + h->h2_term[1].c = ec2; + h->h2_term[2].c = ec3; + h->h2_term[0].x = ex1; + h->h2_term[1].x = ex2; + h->h2_term[2].x = ex3; + + return(ifImg); +} + +static int pade(l) + float l; +{ + int i, j; + double a[6]; + double b[6]; + + a[1] = -a1; + a[2] = -a2; + a[3] = -a3; + a[4] = -a4; + a[5] = -a5; + + b[0] = 1.0; + b[1] = a[1]; + for (i = 2; i <= 5; i++) { + b[i] = 0.0; + for (j = 1; j <= i; j++) + b[i] += j * a[j] * b[i-j]; + b[i] = b[i] / (double) i; + } + + AA[0][0] = 1.0 - exp((double) a0 - l * sqrt(RG)); + AA[0][1] = b[1]; + AA[0][2] = b[2]; + AA[0][3] = -b[3]; + + AA[1][0] = b[1]; + AA[1][1] = b[2]; + AA[1][2] = b[3]; + AA[1][3] = -b[4]; + + AA[2][0] = b[2]; + AA[2][1] = b[3]; + AA[2][2] = b[4]; + AA[2][3] = -b[5]; + + Gaussian_Elimination2(3); + + ep3 = AA[0][3]; + ep2 = AA[1][3]; + ep1 = AA[2][3]; + + eq1 = ep1 + b[1]; + eq2 = b[1] * ep1 + ep2 + b[2]; + eq3 = ep3 * exp((double) a0 - l * sqrt(RG)); + + ep3 = ep3 / (tau*tau*tau); + ep2 = ep2 / (tau*tau); + ep1 = ep1 / tau; + eq3 = eq3 / (tau*tau*tau); + eq2 = eq2 / (tau*tau); + eq1 = eq1 / tau; + /* + printf("factor = %e\n", exp(-a0)); + printf("ep1 = %e ep2 = %e ep3 = %e\n", ep1, ep2, ep3); + */ + exp_find_roots(ep1, ep2, ep3, &ex1, &ex2, &ex3); + /* + printf("roots are %e %e %e \n", ex1, ex2, ex3); + */ + ec1 = eval2(eq1 - ep1, eq2 - ep2, eq3 - ep3, ex1) / + eval2((double) 3.0, (double) 2.0 * ep1, ep2, ex1); + if (ifImg) + get_c(eq1 - ep1, eq2 - ep2, eq3 - ep3, ep1, ep2, ex2, ex3, &ec2, &ec3); + else { + ec2 = eval2(eq1 - ep1, eq2 - ep2, eq3 - ep3, ex2) / + eval2((double) 3.0, (double) 2.0 * ep1, ep2, ex2); + ec3 = eval2(eq1 - ep1, eq2 - ep2, eq3 - ep3, ex3) / + eval2((double) 3.0, (double) 2.0 * ep1, ep2, ex3); + } + return (1); +} + +static int Gaussian_Elimination2(dims) + int dims; +{ + register int i, j, k, dim; + register double f; + double max; + int imax; + + dim = dims; + + for (i = 0; i < dim; i++) { + imax = i; + max = ABS(AA[i][i]); + for (j = i+1; j < dim; j++) + if (ABS(AA[j][i]) > max) { + imax = j; + max = ABS(AA[j][i]); + } + if (max < epsi2) { + fprintf(stderr, " can not choose a pivot \n"); + exit(0); + } + if (imax != i) + for (k = i; k <= dim; k++) { + f = AA[i][k]; + AA[i][k] = AA[imax][k]; + AA[imax][k] = f; + } + + f = 1.0 / AA[i][i]; + AA[i][i] = 1.0; + + for (j = i+1; j <= dim; j++) + AA[i][j] *= f; + + for (j = 0; j < dim ; j++) { + if (i == j) + continue; + f = AA[j][i]; + AA[j][i] = 0.0; + for (k = i+1; k <= dim; k++) + AA[j][k] -= f * AA[i][k]; + } + } + return(1); +} + +/*** +static int exp_div3(a1, a2, a3, x, p1, p2) + double x; + double a1, a2, a3; + double *p1, *p2; + { + *p1 = a1 + x; + *p2 = - a3 / x; + + return(1); +} +***/ + +/*** + ***/ + +static int exp_find_roots(a1, a2, a3, ex1, ex2, ex3) + double a1, a2, a3; + double *ex1, *ex2, *ex3; +{ + double x, t; + double p, q; + + q = (a1*a1-3.0*a2) / 9.0; + p = (2.0*a1*a1*a1-9.0*a1*a2+27.0*a3) / 54.0; + t = q*q*q - p*p; + if (t >= 0.0) { + t = acos((double) p /(q * sqrt(q))); + x = -2.0*sqrt(q)*cos(t / 3.0) - a1/3.0; + } else { + if (p > 0.0) { + t = pow(sqrt(-t)+p, (double) 1.0 / 3.0); + x = -(t + q / t) - a1/3.0; + } else if (p == 0.0) { + x = -a1/3.0; + } else { + t = pow(sqrt(-t)-p, (double) 1.0 / 3.0); + x = (t + q / t) - a1/3.0; + } + } + { + double ex1; + int i = 0; + ex1 = x; + for (t = root3(a1, a2, a3, x); ABS(t-x) > 5.0e-4; + t = root3(a1, a2, a3, x)) + if (++i == 32) { + x = ex1; + break; + } else + x = t; + } + /*** + x = a1; + for (t = root3(a1, a2, a3, x); ABS(t-x) > epsi2; + t = root3(a1, a2, a3, x)) { + x = t; + i++; + if (i > 1000) { + x = 0.5 * (x + root3(a1, a2, a3, x)); + j++; + if (j == 3) + break; + i = 0; + } + } + ***/ + *ex1 = x; + div3(a1, a2, a3, x, &a1, &a2); + + t = a1 * a1 - 4.0 * a2; + if (t < 0) { + ifImg = 1; + printf("***** Two Imaginary Roots.\n"); + *ex3 = 0.5 * sqrt(-t); + *ex2 = -0.5 * a1; + } else { + ifImg = 0; + t *= 1.0e-16; + t = sqrt(t)*1.0e8; + if (a1 >= 0.0) + *ex2 = t = -0.5 * (a1 + t); + else + *ex2 = t = -0.5 * (a1 - t); + *ex3 = a2 / t; + /* + *ex2 = 0.5 * (-a1 + t); + *ex3 = 0.5 * (-a1 - t); + */ + } + + return(1); +} +static NDnamePt +insert_ND(name, ndn) + char *name; + NDnamePt *ndn; +{ + int cmp; + NDnamePt p; + + if (*ndn == NULL) { + p = *ndn = (NDnamePt) malloc(sizeof (NDname)); + p->nd = NULL; + p->right = p->left = NULL; + strcpy(p->id, name); + return(p); + } + cmp = strcmp((*ndn)->id, name); + if (cmp == 0) + return(*ndn); + else { + if (cmp < 0) + return(insert_ND(name, &((*ndn)->left))); + else + return(insert_ND(name, &((*ndn)->right))); + } +} + + +static NODE +*insert_node(name) + char *name; +{ + NDnamePt n; + NODE *p; + + n = insert_ND(name, &ndn); + if (n->nd == NULL) { + p = NEW_node(); + p->name = n; + n->nd = p; + p->next = node_tab; + node_tab = p; + return(p); + } else + return(n->nd); +} + +static NODE +*NEW_node() +{ + NODE *n; + + n = (NODE *) malloc (sizeof (NODE)); + n->mptr = NULL; + n->gptr = NULL; + n->cptr = NULL; + n->rptr = NULL; + n->tptr = NULL; + n->cplptr = NULL; + n->rlptr = NULL; + n->ddptr = NULL; + n->cvccsptr = NULL; + n->vccsptr = NULL; + n->CL = 0.0; + n->V = n->dv = 0.0; + n->gsum = n->cgsum = 0; + n->is = 0; + n->tag = 0; + n->flag = 0; + n->region = NULL; + n->ofile = NULL; + n->dvtag = 0; + + return(n); +} + +static int find_roots(a1, a2, a3, x1, x2, x3) + double a1, a2, a3; + double *x1, *x2, *x3; +{ + double x, t; + double p, q; + + q = (a1*a1-3.0*a2) / 9.0; + p = (2.0*a1*a1*a1-9.0*a1*a2+27.0*a3) / 54.0; + t = q*q*q - p*p; + if (t >= 0.0) { + t = acos((double) p /(q * sqrt(q))); + x = -2.0*sqrt(q)*cos(t / 3.0) - a1/3.0; + } else { + if (p > 0.0) { + t = pow(sqrt(-t)+p, (double) 1.0 / 3.0); + x = -(t + q / t) - a1/3.0; + } else if (p == 0.0) { + x = -a1/3.0; + } else { + t = pow(sqrt(-t)-p, (double) 1.0 / 3.0); + x = (t + q / t) - a1/3.0; + } + } + { + double x1; + int i = 0; + x1 = x; + for (t = root3(a1, a2, a3, x); ABS(t-x) > 5.0e-4; + t = root3(a1, a2, a3, x)) + if (++i == 32) { + x = x1; + break; + } else + x = t; + } + /* + x = a1; + i = 0; + j = 0; + for (t = root3(a1, a2, a3, x); ABS(t-x) > epsi; + t = root3(a1, a2, a3, x)) { + x = t; + i++; + if (i > 1000) { + x = 0.5 * (x + root3(a1, a2, a3, x)); + j++; + if (j == 3) + break; + i = 0; + } + } + */ + + *x1 = x; + div3(a1, a2, a3, x, &a1, &a2); + + t = a1 * a1 - 4.0 * a2; + if (t < 0) { + printf("***** Two Imaginary Roots in Characteristic Admittance.\n"); + exit(0); + } + + t *= 1.0e-18; + t = sqrt(t) * 1.0e9; + if (a1 >= 0.0) + *x2 = t = -0.5 * (a1 + t); + else + *x2 = t = -0.5 * (a1 - t); + *x3 = a2 / t; + /* + *x2 = 0.5 * (-a1 + t); + *x3 = 0.5 * (-a1 - t); + */ + return(1); +} + 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/urcinit.c b/src/spicelib/devices/urc/urcinit.c new file mode 100644 index 000000000..b28c413db --- /dev/null +++ b/src/spicelib/devices/urc/urcinit.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "urcitf.h" +#include "urcext.h" +#include "urcinit.h" + + +SPICEdev URCinfo = { + { + "URC", /* MUST precede both resistors and capacitors */ + "Uniform R.C. line", + + &URCnSize, + &URCnSize, + URCnames, + + &URCpTSize, + URCpTable, + + &URCmPTSize, + URCmPTable, + 0 + }, + + DEVparam : URCparam, + DEVmodParam : URCmParam, + DEVload : NULL, + DEVsetup : URCsetup, + DEVunsetup : URCunsetup, + DEVpzSetup : URCsetup, + DEVtemperature: NULL, + DEVtrunc : NULL, + DEVfindBranch : NULL, + DEVacLoad : NULL, + DEVaccept : NULL, + DEVdestroy : URCdestroy, + DEVmodDelete : URCmDelete, + DEVdelete : URCdelete, + DEVsetic : NULL, + DEVask : URCask, + DEVmodAsk : URCmAsk, + DEVpzLoad : NULL, + DEVconvTest : NULL, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, /* DISTO */ + DEVnoise : NULL, /* NOISE */ + + DEVinstSize : &URCiSize, + DEVmodSize : &URCmSize + +}; + + +SPICEdev * +get_urc_info(void) +{ + return &URCinfo; +} diff --git a/src/spicelib/devices/urc/urcinit.h b/src/spicelib/devices/urc/urcinit.h new file mode 100644 index 000000000..845e6e459 --- /dev/null +++ b/src/spicelib/devices/urc/urcinit.h @@ -0,0 +1,13 @@ +#ifndef _URCINIT_H +#define _URCINIT_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; + +#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/vccsinit.c b/src/spicelib/devices/vccs/vccsinit.c new file mode 100644 index 000000000..65b5504ac --- /dev/null +++ b/src/spicelib/devices/vccs/vccsinit.c @@ -0,0 +1,66 @@ +#include + +#include + +#include "vccsitf.h" +#include "vccsext.h" +#include "vccsinit.h" + + +SPICEdev VCCSinfo = { + { + "VCCS", + "Voltage controlled current source", + + &VCCSnSize, + &VCCSnSize, + VCCSnames, + + &VCCSpTSize, + VCCSpTable, + + 0, + NULL, + DEV_DEFAULT + }, + + DEVparam : VCCSparam, + DEVmodParam : NULL, + DEVload : VCCSload, + DEVsetup : VCCSsetup, + DEVunsetup : NULL, + DEVpzSetup : VCCSsetup, + DEVtemperature: NULL, + DEVtrunc : NULL, + DEVfindBranch : NULL, + DEVacLoad : VCCSload, /* ac and normal loads are identical */ + DEVaccept : NULL, + DEVdestroy : VCCSdestroy, + DEVmodDelete : VCCSmDelete, + DEVdelete : VCCSdelete, + DEVsetic : NULL, + DEVask : VCCSask, + DEVmodAsk : NULL, + DEVpzLoad : VCCSpzLoad, + DEVconvTest : NULL, + DEVsenSetup : VCCSsSetup, + DEVsenLoad : VCCSsLoad, + DEVsenUpdate : NULL, + DEVsenAcLoad : VCCSsAcLoad, + DEVsenPrint : VCCSsPrint, + DEVsenTrunc : NULL, + DEVdisto : NULL, /* DISTO */ + DEVnoise : NULL, /* NOISE */ + + DEVinstSize : &VCCSiSize, + DEVmodSize : &VCCSmSize + + +}; + + +SPICEdev * +get_vccs_info(void) +{ + return &VCCSinfo; +} diff --git a/src/spicelib/devices/vccs/vccsinit.h b/src/spicelib/devices/vccs/vccsinit.h new file mode 100644 index 000000000..71756fd9d --- /dev/null +++ b/src/spicelib/devices/vccs/vccsinit.h @@ -0,0 +1,11 @@ +#ifndef _VCCSINIT_H +#define _VCCSINIT_H + +extern IFparm VCCSpTable[ ]; +extern char *VCCSnames[ ]; +extern int VCCSpTSize; +extern int VCCSnSize; +extern int VCCSiSize; +extern int VCCSmSize; + +#endif 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/vcvsinit.c b/src/spicelib/devices/vcvs/vcvsinit.c new file mode 100644 index 000000000..6d3e29dae --- /dev/null +++ b/src/spicelib/devices/vcvs/vcvsinit.c @@ -0,0 +1,65 @@ +#include + +#include + +#include "vcvsitf.h" +#include "vcvsext.h" +#include "vcvsinit.h" + + +SPICEdev VCVSinfo = { + { + "VCVS", + "Voltage controlled voltage source", + + &VCVSnSize, + &VCVSnSize, + VCVSnames, + + &VCVSpTSize, + VCVSpTable, + + 0, + NULL, + DEV_DEFAULT + }, + + DEVparam : VCVSparam, + DEVmodParam : NULL, + DEVload : VCVSload, + DEVsetup : VCVSsetup, + DEVunsetup : VCVSunsetup, + DEVpzSetup : VCVSsetup, + DEVtemperature: NULL, + DEVtrunc : NULL, + DEVfindBranch : VCVSfindBr, + DEVacLoad : VCVSload, /* AC and normal loads are identical */ + DEVaccept : NULL, + DEVdestroy : VCVSdestroy, + DEVmodDelete : VCVSmDelete, + DEVdelete : VCVSdelete, + DEVsetic : NULL, + DEVask : VCVSask, + DEVmodAsk : NULL, + DEVpzLoad : VCVSpzLoad, + DEVconvTest : NULL, + DEVsenSetup : VCVSsSetup, + DEVsenLoad : VCVSsLoad, + DEVsenUpdate : NULL, + DEVsenAcLoad : VCVSsAcLoad, + DEVsenPrint : VCVSsPrint, + DEVsenTrunc : NULL, + DEVdisto : NULL, /* DISTO */ + DEVnoise : NULL, /* NOISE */ + + DEVinstSize : &VCVSiSize, + DEVmodSize : &VCVSmSize + +}; + + +SPICEdev * +get_vcvs_info(void) +{ + return &VCVSinfo; +} diff --git a/src/spicelib/devices/vcvs/vcvsinit.h b/src/spicelib/devices/vcvs/vcvsinit.h new file mode 100644 index 000000000..614154846 --- /dev/null +++ b/src/spicelib/devices/vcvs/vcvsinit.h @@ -0,0 +1,11 @@ +#ifndef _VCVSINIT_H +#define _VCVSINIT_H + +extern IFparm VCVSpTable[ ]; +extern char *VCVSnames[ ]; +extern int VCVSpTSize; +extern int VCVSnSize; +extern int VCVSiSize; +extern int VCVSmSize; + +#endif 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/vsrcinit.c b/src/spicelib/devices/vsrc/vsrcinit.c new file mode 100644 index 000000000..672ce4baa --- /dev/null +++ b/src/spicelib/devices/vsrc/vsrcinit.c @@ -0,0 +1,64 @@ +#include + +#include + +#include "vsrcitf.h" +#include "vsrcext.h" +#include "vsrcinit.h" + + +SPICEdev VSRCinfo = { + { + "Vsource", + "Independent voltage source", + + &VSRCnSize, + &VSRCnSize, + VSRCnames, + + &VSRCpTSize, + VSRCpTable, + + 0, + NULL, + DEV_DEFAULT + }, + + DEVparam : VSRCparam, + DEVmodParam : NULL, + DEVload : VSRCload, + DEVsetup : VSRCsetup, + DEVunsetup : VSRCunsetup, + DEVpzSetup : VSRCpzSetup, + DEVtemperature: VSRCtemp, + DEVtrunc : NULL, + DEVfindBranch : VSRCfindBr, + DEVacLoad : VSRCacLoad, + DEVaccept : VSRCaccept, + DEVdestroy : VSRCdestroy, + DEVmodDelete : VSRCmDelete, + DEVdelete : VSRCdelete, + DEVsetic : NULL, + DEVask : VSRCask, + DEVmodAsk : NULL, + DEVpzLoad : VSRCpzLoad, + DEVconvTest : NULL, + DEVsenSetup : NULL, + DEVsenLoad : NULL, + DEVsenUpdate : NULL, + DEVsenAcLoad : NULL, + DEVsenPrint : NULL, + DEVsenTrunc : NULL, + DEVdisto : NULL, /* DISTO */ + DEVnoise : NULL, /* NOISE */ + + DEVinstSize : &VSRCiSize, + DEVmodSize : &VSRCmSize +}; + + +SPICEdev * +get_vsrc_info(void) +{ + return &VSRCinfo; +} diff --git a/src/spicelib/devices/vsrc/vsrcinit.h b/src/spicelib/devices/vsrc/vsrcinit.h new file mode 100644 index 000000000..e11a2dd67 --- /dev/null +++ b/src/spicelib/devices/vsrc/vsrcinit.h @@ -0,0 +1,11 @@ +#ifndef _VSRCINIT_H +#define _VSRCINIT_H + +extern IFparm VSRCpTable[ ]; +extern char *VSRCnames[ ]; +extern int VSRCpTSize; +extern int VSRCnSize; +extern int VSRCiSize; +extern int VSRCmSize; + +#endif 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/src/spicelib/parser/ChangeLog b/src/spicelib/parser/ChangeLog new file mode 100644 index 000000000..2a81fff41 --- /dev/null +++ b/src/spicelib/parser/ChangeLog @@ -0,0 +1,130 @@ +2000-10-12 Arno W. Peters + + * inpeval.c: Bugfix for subcircuits contributed by Michael + Widlok. + +2000-09-09 Arno W. Peters + + * inp2dot.c: Removed unused static functions dot_ic and + dot_nodeset. + + * inppas2.c: Added back parsing for dotlines. + +2000-09-02 Paolo Nenzi + + * Patched with code sent by Alan Gillespie. See more on top level + ChangeLog. + +2000-07-07 Arno W. Peters + + * circuit/inp2b.c, circuit/inp2c.c, circuit/inp2d.c, + circuit/inp2dot.c, circuit/inp2e.c, circuit/inp2f.c, + circuit/inp2g.c, circuit/inp2h.c, circuit/inp2i.c, + circuit/inp2j.c, circuit/inp2k.c, circuit/inp2l.c, + circuit/inp2m.c, circuit/inp2o.c, circuit/inp2q.c, + circuit/inp2r.c, circuit/inp2s.c, circuit/inp2t.c, + circuit/inp2u.c, circuit/inp2v.c, circuit/inp2w.c, + circuit/inp2z.c: Added ; after macros. + +2000-05-22 Paolo Nenzi + + * inp2dot.c: Applied Widlok patch. + + * inpdoopt.c: Applied Widolok patch:commented the entire function, + seems obsolete. + + * inpptree.c, ptfuncs.c: Applied Widlok patch. Now there is a new + step function called u2. + +2000-04-04 Paolo Nenzi + + * inpfindl.c: Modified the file for BSIM4 and future extensions to + BSIM5 and BSIM6. I have merged the inpfindl.c coming + with the BSIM4 distribution. + + * inp2r.c: Added acval=val to initialize the acval parameter to + a significative value. Hope does not brak anything. + + * inp2m.c: Added BSIM4 support. + + * inpdomod.c: Added support for BSIM4 device model. + +2000-03-28 Paolo Nenzi + + * ptfuncs.c: I have applied a couple of patches by GLAO Dezay. He + noted that PTln, PTlog and PTsqrt returned non consistent values + if the argument was out of domain. If arg <0 they returned + f(-arg). The patch is masked by #ifdef EXPERIMENTAL_CODE. You + have to remove these lines or #define it to compile Dezai's + patched code. + +2000-03-11 Paolo Nenzi + + * inp2dot.c: Applied Glao Dezai patch, adding which = -1 in the + .sens code. + +2000-01-17 Paolo Nenzi + + * inp2m.c, inpdomod.c: Inserted code to dupport BSIM3V1 model as + level 49. + +2000-01-16 Paolo Nenzi + + * inp2r.c: Modified resistor code. Added ac value (ala HSPICE), + from Serban Popescu contributed sources. + +2000-01-15 Paolo Nenzi + + * inp2m.c, inpdomod.c: Inserted code to support BSIM3V2 model as + level 50. + +1999-12-20 Paolo Nenzi + + * inpgtok.c, inpptree.c: Bug Fix + + Bug: Scale factors (eg. m, k, meg, etc.) for constants in + arbitrary source (b devices) are not recognized. + + Fix: Changes to inpgtok.c and inpptree.c, as supplied by Berkeley. + + NOTE: These changes were orignally supplied to me as a patch to + 3e2 by Beorn Johnson who was maintaining Spice a while back. They + were supposed to have been incorporated in Spice 3f2 at that time, + but are missing from the 3f5 version that I recently got from + Berkeley. I don't know if they were removed in ignorance or + because of a conflict with some other requirement, but they appear + to work in 3f5. ALSO, the fix for 3e2 had many more changes, all + of which remain in 3f5, so don't try these alone on 3e2. + +1999-09-07 Arno + + * inpsymt.c: removed unused function prototype for local_remove(). + + * sperror.c: removed unused variable `notempty' + +1999-09-05 Emmanuel Rouat + + * inpptree.c (PTdifferentiate): removed superfluous argument to 2 + occurences of function mkf + + * *.c: put all function prototypes in inp.h + +1999-08-28 Emmanuel Rouat + + * Removed all #includes of misc.h and util.h (now in spice.h) + +1999-08-24 Paolo Nenzi + + * inpdomod.c: added level check for ps model, jfet level 2 + + * inp2j.c: added code for ps model, jfet level 2 + +1999-08-08 Emmanuel Rouat + + * inp2dot.c (INP2dot):changed HAS_SENSE2 in WANT_SENSE2 + +1999-08-03 Emmanuel Rouat + + * ptfuncs.c: changed HAS_ATRIGH to HAVE_ACOSH,HAVE_ASINH and + HAVE_ATANH provided in config.h + diff --git a/src/spicelib/parser/Makefile.am b/src/spicelib/parser/Makefile.am new file mode 100644 index 000000000..b38ce4c70 --- /dev/null +++ b/src/spicelib/parser/Makefile.am @@ -0,0 +1,69 @@ +## Process this file with automake to produce Makefile.in + +noinst_LIBRARIES = libinp.a + +libinp_a_SOURCES = \ + ifeval.c \ + ifnewuid.c \ + inp2b.c \ + inp2c.c \ + inp2d.c \ + inp2dot.c \ + inp2e.c \ + inp2f.c \ + inp2g.c \ + inp2h.c \ + inp2i.c \ + inp2j.c \ + inp2k.c \ + inp2l.c \ + inp2m.c \ + inp2o.c \ + inp2p.c \ + inp2q.c \ + inp2r.c \ + inp2s.c \ + inp2t.c \ + inp2u.c \ + inp2v.c \ + inp2w.c \ + inp2y.c \ + inp2z.c \ + inpaname.c \ + inpapnam.c \ + inpcfix.c \ + inpdomod.c \ + inpdoopt.c \ + inpdpar.c \ + inperrc.c \ + inperror.c \ + inpeval.c \ + inpfindl.c \ + inpgmod.c \ + inpgstr.c \ + inpgtitl.c \ + inpgtok.c \ + inpgval.c \ + inpkmods.c \ + inplist.c \ + inplkmod.c \ + inpmkmod.c \ + inpmktmp.c \ + inppas1.c \ + inppas1.h \ + inppas2.c \ + inppas2.h \ + inppas3.c \ + inppas3.h \ + inppname.c \ + inpptree.c \ + inpsymt.c \ + inptyplk.c \ + ptfuncs.c \ + sperror.c \ + inp.h + + +INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/frontend + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/parser/ifeval.c b/src/spicelib/parser/ifeval.c new file mode 100644 index 000000000..73f796c68 --- /dev/null +++ b/src/spicelib/parser/ifeval.c @@ -0,0 +1,108 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpmacs.h" +#include "fteext.h" +#include "iferrmsg.h" +#include "inpptree.h" +#include "inp.h" + + + + +extern double PTfudge_factor; + +static int PTeval(INPparseNode * tree, double gmin, double *res, + double *vals); + + + +int +IFeval(IFparseTree * tree, double gmin, double *result, double *vals, + double *derivs) +{ + int i, err; + INPparseTree *myTree = (INPparseTree *) tree;; + +/* +INPptPrint("calling PTeval, tree = ", myTree); +printf("values:"); +for (i = 0; i < myTree->p.numVars; i++) +printf("\tvar%d = %lg\n", i, vals[i]); +*/ + + if ((err = PTeval(myTree->tree, gmin, result, vals)) != OK) + return (err); + + for (i = 0; i < myTree->p.numVars; i++) + if ((err = PTeval(myTree->derivs[i], gmin, &derivs[i], vals)) != + OK) return (err); + +/* +printf("results: function = %lg\n", *result); +for (i = 0; i < myTree->p.numVars; i++) +printf("\td / d var%d = %lg\n", i, derivs[i]); +*/ + + return (OK); +} + +static int +PTeval(INPparseNode * tree, double gmin, double *res, double *vals) +{ + double r1, r2; + int err; + + PTfudge_factor = gmin; + switch (tree->type) { + case PT_CONSTANT: + *res = tree->constant; + break; + + case PT_VAR: + *res = vals[tree->valueIndex]; + break; + + case PT_FUNCTION: + err = PTeval(tree->left, gmin, &r1, vals); + if (err != OK) + return (err); + *res = (*tree->function) (r1); + if (*res == HUGE) { + fprintf(stderr, "Error: %g out of range for %s\n", + r1, tree->funcname); + return (E_PARMVAL); + } + break; + + case PT_PLUS: + case PT_MINUS: + case PT_TIMES: + case PT_DIVIDE: + case PT_POWER: + err = PTeval(tree->left, gmin, &r1, vals); + if (err != OK) + return (err); + err = PTeval(tree->right, gmin, &r2, vals); + if (err != OK) + return (err); + *res = (*tree->function) (r1, r2); + if (*res == HUGE) { + fprintf(stderr, "Error: %g, %g out of range for %s\n", + r1, r2, tree->funcname); + return (E_PARMVAL); + } + break; + + default: + fprintf(stderr, "Internal Error: bad node type %d\n", tree->type); + return (E_PANIC); + } + + return (OK); +} diff --git a/src/spicelib/parser/ifnewuid.c b/src/spicelib/parser/ifnewuid.c new file mode 100644 index 000000000..ee59dcc9c --- /dev/null +++ b/src/spicelib/parser/ifnewuid.c @@ -0,0 +1,109 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include + +#ifdef HAVE_STRING_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "ifsim.h" +#include "iferrmsg.h" +#include "fteext.h" +#include "inp.h" + + +int +IFnewUid(void *ckt, IFuid * newuid, IFuid olduid, char *suffix, int type, + void **nodedata) +{ + char *newname; + int error; + + if (olduid) { +#ifdef HAVE_ASPRINTF + asprintf(&newname, "%s#%s", (char *) olduid, suffix); +#else /* ~ HAVE_ASPRINTF */ + if ( (newname = (char *) malloc(strlen((char *) olduid) + + strlen(suffix) + 2)) /* 2 = strlen("#\0") */ + == NULL){ + fprintf(stderr,"malloc failed\n"); + exit(1); + } + sprintf(newname, "%s#%s", (char *) olduid, suffix); +#endif /* HAVE_ASPRINTF */ + + } else { + +#ifdef HAVE_ASPRINTF + asprintf(&newname, "%s", suffix); +#else /* ~ HAVE_ASPRINTF */ + if ( (newname = (char *) malloc(strlen(suffix) + 2 )) == NULL){ + fprintf(stderr,"malloc failed\n"); + exit(1); + } + sprintf(newname, "%s", suffix); +#endif /* HAVE_ASPRINTF */ + } + + switch (type) { + case UID_ANALYSIS: + case UID_TASK: + case UID_INSTANCE: + case UID_OTHER: + case UID_MODEL: + error = INPinsert(&newname, (INPtables *) ft_curckt->ci_symtab); + if (error && error != E_EXISTS) + return (error); + *newuid = (IFuid) newname; + break; + + case UID_SIGNAL: + error = INPmkTerm(ckt, &newname, + (INPtables *) ft_curckt->ci_symtab, nodedata); + if (error && error != E_EXISTS) + return (error); + *newuid = (IFuid) newname; + break; + + default: + return (E_BADPARM); + } + return (OK); +} + +int IFdelUid(void *ckt, IFuid uid, int type) +{ + int error; + + switch (type) { + case UID_ANALYSIS: + case UID_TASK: + case UID_INSTANCE: + case UID_OTHER: + case UID_MODEL: + error = INPremove(uid, (INPtables *) ft_curckt->ci_symtab); + if (error && error != E_EXISTS) + return (error); + break; + + case UID_SIGNAL: + error = INPremTerm(uid, (INPtables *) ft_curckt->ci_symtab); + if (error && error != E_EXISTS) + return (error); + break; + + default: + return (E_BADPARM); + } + return (OK); +} diff --git a/src/spicelib/parser/inp.h b/src/spicelib/parser/inp.h new file mode 100644 index 000000000..7de4abcde --- /dev/null +++ b/src/spicelib/parser/inp.h @@ -0,0 +1,127 @@ +/************* + * Header file for inpxx.c + * 1999 E. Rouat + ************/ + +#ifndef INP_H_INCLUDED +#define INP_H_INCLUDED + +/* ifeval.c */ + +int IFeval(IFparseTree *tree, double gmin, double *result, double *vals, + double *derivs); + +/* ifnewuid.c */ + +int IFnewUid(void *ckt, IFuid *newuid, IFuid olduid, char *suffix, int type, + void **nodedata); +int IFdelUid(void *ckt, IFuid uid, int type); + +/* inp2xx.c */ + +void INP2B(void *ckt, INPtables *tab, card *current); +void INP2C(void *ckt, INPtables *tab, card *current); +void INP2D(void *ckt, INPtables *tab, card *current); +void INP2E(void *ckt, INPtables *tab, card *current); +void INP2F(void *ckt, INPtables *tab, card *current); +void INP2G(void *ckt, INPtables *tab, card *current); +void INP2H(void *ckt, INPtables *tab, card *current); +void INP2I(void *ckt, INPtables *tab, card *current); +void INP2J(void *ckt, INPtables *tab, card *current); +void INP2K(void *ckt, INPtables *tab, card *current); +void INP2L(void *ckt, INPtables *tab, card *current); +void INP2M(void *ckt, INPtables *tab, card *current); +void INP2O(void *ckt, INPtables *tab, card *current); +void INP2P(void *ckt, INPtables *tab, card *current); +void INP2Q(void *ckt, INPtables *tab, card *current, void *gnode); +void INP2R(void *ckt, INPtables *tab, card *current); +void INP2S(void *ckt, INPtables *tab, card *current); +void INP2T(void *ckt, INPtables *tab, card *current); +void INP2U(void *ckt, INPtables *tab, card *current); +void INP2V(void *ckt, INPtables *tab, card *current); +void INP2W(void *ckt, INPtables *tab, card *current); +void INP2Y(void *ckt, INPtables *tab, card *current); +void INP2Z(void *ckt, INPtables *tab, card *current); +int INP2dot(void *ckt, INPtables *tab, card *current, void *task, void *gnode); + +/* inpxxxx.c */ + +int INPaName(char *parm, IFvalue *val, void *ckt, int *dev, char *devnam, + void **fast, IFsimulator *sim, int *dataType, IFvalue *selector); +int INPapName(void *ckt, int type, void *analPtr, char *parmname, IFvalue *value); +void INPcaseFix(register char *string); +char * INPdomodel(void *ckt, card *image, INPtables *tab); +void INPdoOpts(void *ckt, void *anal, card *optCard, INPtables *tab); +char * INPdevParse(char **line, void *ckt, int dev, void *fast, double *leading, + int *waslead, INPtables *tab); +char * INPerrCat(char *a, char *b); +char * INPerror(int type); +double INPevaluate(char **line, int *error, int gobble); +char * INPfindLev(char *line, int *level); +char * INPgetMod(void *ckt, char *name, INPmodel **model, INPtables *tab); +int INPgetStr(char **line, char **token, int gobble); +int INPgetTitle(void **ckt, card **data); +int INPgetTok(char **line, char **token, int gobble); +int INPgetUTok(char **line, char **token, int gobble); +IFvalue * INPgetValue(void *ckt, char **line, int type, INPtables *tab); +void INPkillMods(void); +void INPlist(FILE *file, card *deck, int type); +int INPlookMod(char *name); +int INPmakeMod(char *token, int type, card *line); +char * INPmkTemp(char *string); +void INPpas1(void *ckt, card *deck, INPtables *tab); +void INPpas2(void *ckt, card *data, INPtables *tab, void *task); +int INPpName(char *parm, IFvalue *val, void *ckt, int dev, void *fast); + +/* inpptree.c */ + +void INPgetTree(char **line, INPparseTree **pt, void *ckt, INPtables *tab); + + +/* inpsymt.c */ + +INPtables * INPtabInit(int numlines); +int INPtermInsert(void *ckt, char **token, INPtables *tab, void **node); +int INPmkTerm(void *ckt, char **token, INPtables *tab, void **node); +int INPgndInsert(void *ckt, char **token, INPtables *tab, void **node); +int INPretrieve(char **token, INPtables *tab); +int INPinsert(char **token, INPtables *tab); +int INPinsertNofree(char **token, INPtables *tab); +int INPremove(char *token, INPtables *tab); +int INPremTerm(char *token, INPtables *tab); +void INPtabEnd(INPtables *tab); + +int INPtypelook(char *type); + +/* ptfuncs.c */ + +double PTabs(double arg); +double PTsgn(double arg); +double PTplus(double arg1, double arg2); +double PTminus(double arg1, double arg2); +double PTtimes(double arg1, double arg2); +double PTtimes(double arg1, double arg2); +double PTdivide(double arg1, double arg2); +double PTpower(double arg1, double arg2); +double PTacos(double arg); +double PTacosh(double arg); +double PTasin(double arg); +double PTasinh(double arg); +double PTatan(double arg); +double PTatanh(double arg); +double PTustep(double arg); +double PTuramp(double arg); +double PTcos(double arg); +double PTcosh(double arg); +double PTexp(double arg); +double PTln(double arg); +double PTlog(double arg); +double PTsin(double arg); +double PTsinh(double arg); +double PTsqrt(double arg); +double PTtan(double arg); +double PTuminus(double arg); + +/* sperror.c */ + +#endif diff --git a/src/spicelib/parser/inp2b.c b/src/spicelib/parser/inp2b.c new file mode 100644 index 000000000..8448ebeb7 --- /dev/null +++ b/src/spicelib/parser/inp2b.c @@ -0,0 +1,58 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2B(void *ckt, INPtables * tab, card * current) +{ + + /* Bname [V=expr] [I=expr] */ + + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + int error; /* error code temporary */ + void *fast; /* pointer to the actual instance */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + IFuid uid; /* uid for default model name */ + + /* Arbitrary source. */ + type = INPtypelook("ASRC"); + if (type < 0) { + LITERR("Device type Asource not supported by this binary\n"); + return; + } + + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + + INPgetTok(&line, &nname1, 1); + error = INPtermInsert(ckt, &nname1, tab, &node1); + + INPgetTok(&line, &nname2, 1); + error = INPtermInsert(ckt, &nname2, tab, &node2); + + if (!tab->defBmod) { + /* create default B model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "B", UID_MODEL, (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defBmod), uid)); + } + IFC(newInstance, (ckt, tab->defBmod, &fast, name)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); +} diff --git a/src/spicelib/parser/inp2c.c b/src/spicelib/parser/inp2c.c new file mode 100644 index 000000000..c1f2ac855 --- /dev/null +++ b/src/spicelib/parser/inp2c.c @@ -0,0 +1,92 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2C(void *ckt, INPtables * tab, card * current) +{ + +/* parse a capacitor card */ +/* Cname [IC=] */ + + int mytype; /* the type we determine resistors are */ + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *model; /* the name of the resistor's model */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + double val; /* temp to held resistance */ + int error; /* error code temporary */ + INPmodel *thismodel; /* pointer to model structure describing our model */ + void *mdfast; /* pointer to the actual model */ + void *fast; /* pointer to the actual instance */ + IFvalue ptemp; /* a value structure to package resistance into */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + IFuid uid; /* uid for default cap model */ + + mytype = INPtypelook("Capacitor"); + if (mytype < 0) { + LITERR("Device type Capacitor not supported by this binary\n"); + return; + } + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + val = INPevaluate(&line, &error, 1); + if (error == 0) { /* Looks like a number */ + type = mytype; + ptemp.rValue = val; + if (!tab->defCmod) { + IFnewUid(ckt, &uid, (IFuid) NULL, "C", UID_MODEL, + (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defCmod), uid)); + } + IFC(newInstance, (ckt, tab->defCmod, &fast, name)); + GCA(INPpName, ("capacitance", &ptemp, ckt, type, fast)); + } else { /* looks like character strings */ + INPgetTok(&line, &model, 1); + INPinsert(&model, tab); + thismodel = (INPmodel *) NULL; + current->error = INPgetMod(ckt, model, &thismodel, tab); + if (thismodel != NULL) { + if (mytype != thismodel->INPmodType) { + LITERR("incorrect model type"); + return; + } + type = mytype; + mdfast = thismodel->INPmodfast; + } else { + type = mytype; + if (!tab->defCmod) { + IFnewUid(ckt, &uid, (IFuid) NULL, "C", UID_MODEL, + (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defCmod), uid)); + } + mdfast = tab->defCmod; + } + IFC(newInstance, (ckt, mdfast, &fast, name)); + } + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) { + ptemp.rValue = leadval; + GCA(INPpName, ("capacitance", &ptemp, ckt, type, fast)); + } +} diff --git a/src/spicelib/parser/inp2d.c b/src/spicelib/parser/inp2d.c new file mode 100644 index 000000000..2d65f4544 --- /dev/null +++ b/src/spicelib/parser/inp2d.c @@ -0,0 +1,77 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2D(void *ckt, INPtables * tab, card * current) +{ + +/* Dname [] [OFF] [IC=] */ + + int mytype; /* the type we looked up */ + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + int error; /* error code temporary */ + void *fast; /* pointer to the actual instance */ + IFvalue ptemp; /* a value structure to package resistance into */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + char *model; /* the name of the model */ + INPmodel *thismodel; /* pointer to model description for user's model */ + void *mdfast; /* pointer to the actual model */ + IFuid uid; /* uid of default model */ + + mytype = INPtypelook("Diode"); + if (mytype < 0) { + LITERR("Device type Diode not supported by this binary\n"); + return; + } + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + INPgetTok(&line, &model, 1); + INPinsert(&model, tab); + current->error = INPgetMod(ckt, model, &thismodel, tab); + if (thismodel != NULL) { + if (mytype != thismodel->INPmodType) { + LITERR("incorrect model type"); + return; + } + type = mytype; + mdfast = (thismodel->INPmodfast); + } else { + type = mytype; + if (!tab->defDmod) { + /* create default D model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "D", UID_MODEL, + (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defDmod), uid)); + } + mdfast = tab->defDmod; + } + IFC(newInstance, (ckt, mdfast, &fast, name)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) { + ptemp.rValue = leadval; + GCA(INPpName, ("area", &ptemp, ckt, type, fast)); + } +} diff --git a/src/spicelib/parser/inp2dot.c b/src/spicelib/parser/inp2dot.c new file mode 100644 index 000000000..ef7616664 --- /dev/null +++ b/src/spicelib/parser/inp2dot.c @@ -0,0 +1,713 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +Modified: 2000 AlansFixes +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" +#include "cpdefs.h" + + +static int +dot_noise(char *line, void *ckt, INPtables *tab, card *current, + void *task, void *gnode, void *foo) +{ + int which; /* which analysis we are performing */ + int i; /* generic loop variable */ + int error; /* error code temporary */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + IFvalue ptemp; /* a value structure to package resistance into */ + IFvalue *parm; /* a pointer to a value struct for function returns */ + char *steptype; /* ac analysis, type of stepping function */ + + int found; + char *point; + + /* .noise V(OUTPUT,REF) SRC {DEC OCT LIN} NP FSTART FSTOP */ + which = -1; + for (i = 0; i < ft_sim->numAnalyses; i++) { + if (strcmp(ft_sim->analyses[i]->name, "NOISE") == 0) { + which = i; + break; + } + } + if (which == -1) { + LITERR("Noise analysis unsupported.\n"); + return (0); + } + IFC(newAnalysis, (ckt, which, "Noise Analysis", &foo, task)); + INPgetTok(&line, &name, 1); + + /* Make sure the ".noise" command is followed by V(xxxx). If it + is, extract 'xxxx'. If not, report an error. */ + + if (name != NULL) { + int length; + + length = strlen(name); + if (((*name == 'V') || (*name == 'v')) && (length == 1)) { + + INPgetTok(&line, &nname1, 0); + INPtermInsert(ckt, &nname1, tab, &node1); + ptemp.nValue = (IFnode) node1; + GCA(INPapName, (ckt, which, foo, "output", &ptemp)) + + if (*line != ')') { + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + ptemp.nValue = (IFnode) node2; + } else { + ptemp.nValue = (IFnode) gnode; + } + GCA(INPapName, (ckt, which, foo, "outputref", &ptemp)) + + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + ptemp.uValue = name; + GCA(INPapName, (ckt, which, foo, "input", &ptemp)) + + INPgetTok(&line, &steptype, 1); + ptemp.iValue = 1; + error = INPapName(ckt, which, foo, steptype, &ptemp); + if (error) + current->error = INPerrCat(current->error, INPerror(error)); + parm = INPgetValue(ckt, &line, IF_INTEGER, tab); + error = INPapName(ckt, which, foo, "numsteps", parm); + if (error) + current->error = INPerrCat(current->error, INPerror(error)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); + error = INPapName(ckt, which, foo, "start", parm); + if (error) + current->error = INPerrCat(current->error, INPerror(error)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); + error = INPapName(ckt, which, foo, "stop", parm); + if (error) + current->error = INPerrCat(current->error, INPerror(error)); + + /* now see if "ptspersum" has been specified by the user */ + + for (found = 0, point = line; (!found) && (*point != '\0'); + found = ((*point != ' ') && (*(point++) != '\t'))); + if (found) { + parm = INPgetValue(ckt, &line, IF_INTEGER, tab); + error = INPapName(ckt, which, foo, "ptspersum", parm); + if (error) + current->error = INPerrCat(current->error, INPerror(error)); + } else { + ptemp.iValue = 0; + error = INPapName(ckt, which, foo, "ptspersum", &ptemp); + if (error) + current->error = INPerrCat(current->error, INPerror(error)); + } + } else + LITERR("bad syntax " + "[.noise v(OUT) SRC {DEC OCT LIN} " + "NP FSTART FSTOP ]\n"); + } else { + LITERR("bad syntax " + "[.noise v(OUT) SRC {DEC OCT LIN} " + "NP FSTART FSTOP ]\n"); + } + return 0; +} + + +static int +dot_op(char *line, void *ckt, INPtables *tab, card *current, + void *task, void *gnode, void *foo) +{ + int which; /* which analysis we are performing */ + int i; /* generic loop variable */ + int error; /* error code temporary */ + + /* .op */ + which = -1; + for (i = 0; i < ft_sim->numAnalyses; i++) { + if (strcmp(ft_sim->analyses[i]->name, "OP") == 0) { + which = i; + break; + } + } + if (which == -1) { + LITERR("DC operating point analysis unsupported\n"); + return (0); + } + IFC(newAnalysis, (ckt, which, "Operating Point", &foo, task)); + return (0); +} + + +static int +dot_disto(char *line, void *ckt, INPtables *tab, card *current, + void *task, void *gnode, void *foo) +{ + int which; /* which analysis we are performing */ + int i; /* generic loop variable */ + int error; /* error code temporary */ + IFvalue ptemp; /* a value structure to package resistance into */ + IFvalue *parm; /* a pointer to a value struct for function returns */ + char *steptype; /* ac analysis, type of stepping function */ + + /* .disto {DEC OCT LIN} NP FSTART FSTOP */ + which = -1; + for (i = 0; i < ft_sim->numAnalyses; i++) { + if (strcmp(ft_sim->analyses[i]->name, "DISTO") == 0) { + which = i; + break; + } + } + if (which == -1) { + LITERR("Small signal distortion analysis unsupported.\n"); + return (0); + } + IFC(newAnalysis, (ckt, which, "Distortion Analysis", &foo, task)); + INPgetTok(&line, &steptype, 1); /* get DEC, OCT, or LIN */ + ptemp.iValue = 1; + GCA(INPapName, (ckt, which, foo, steptype, &ptemp)); + parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* number of points */ + GCA(INPapName, (ckt, which, foo, "numsteps", parm)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstart */ + GCA(INPapName, (ckt, which, foo, "start", parm)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstop */ + GCA(INPapName, (ckt, which, foo, "stop", parm)); + if (*line) { + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* f1phase */ + GCA(INPapName, (ckt, which, foo, "f2overf1", parm)); + } + return (0); +} + + +static int +dot_ac(char *line, void *ckt, INPtables *tab, card *current, + void *task, void *gnode, void *foo) +{ + int error; /* error code temporary */ + IFvalue ptemp; /* a value structure to package resistance into */ + IFvalue *parm; /* a pointer to a value struct for function returns */ + int which; /* which analysis we are performing */ + int i; /* generic loop variable */ + char *steptype; /* ac analysis, type of stepping function */ + + /* .ac {DEC OCT LIN} NP FSTART FSTOP */ + which = -1; + for (i = 0; i < ft_sim->numAnalyses; i++) { + if (strcmp(ft_sim->analyses[i]->name, "AC") == 0) { + which = i; + break; + } + } + if (which == -1) { + LITERR("AC small signal analysis unsupported.\n"); + return (0); + } + IFC(newAnalysis, (ckt, which, "AC Analysis", &foo, task)); + INPgetTok(&line, &steptype, 1); /* get DEC, OCT, or LIN */ + ptemp.iValue = 1; + GCA(INPapName, (ckt, which, foo, steptype, &ptemp)); + parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* number of points */ + GCA(INPapName, (ckt, which, foo, "numsteps", parm)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstart */ + GCA(INPapName, (ckt, which, foo, "start", parm)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstop */ + GCA(INPapName, (ckt, which, foo, "stop", parm)); + return (0); +} + +static int +dot_pz(char *line, void *ckt, INPtables *tab, card *current, + void *task, void *gnode, void *foo) +{ + int error; /* error code temporary */ + IFvalue ptemp; /* a value structure to package resistance into */ + IFvalue *parm; /* a pointer to a value struct for function returns */ + int which; /* which analysis we are performing */ + int i; /* generic loop variable */ + char *steptype; /* ac analysis, type of stepping function */ + + /* .pz nodeI nodeG nodeJ nodeK {V I} {POL ZER PZ} */ + which = -1; + for (i = 0; i < ft_sim->numAnalyses; i++) { + if (strcmp(ft_sim->analyses[i]->name, "PZ") == 0) { + which = i; + break; + } + } + if (which == -1) { + LITERR("Pole-zero analysis unsupported.\n"); + return (0); + } + IFC(newAnalysis, (ckt, which, "Pole-Zero Analysis", &foo, task)); + parm = INPgetValue(ckt, &line, IF_NODE, tab); + GCA(INPapName, (ckt, which, foo, "nodei", parm)); + parm = INPgetValue(ckt, &line, IF_NODE, tab); + GCA(INPapName, (ckt, which, foo, "nodeg", parm)); + parm = INPgetValue(ckt, &line, IF_NODE, tab); + GCA(INPapName, (ckt, which, foo, "nodej", parm)); + parm = INPgetValue(ckt, &line, IF_NODE, tab); + GCA(INPapName, (ckt, which, foo, "nodek", parm)); + INPgetTok(&line, &steptype, 1); /* get V or I */ + ptemp.iValue = 1; + GCA(INPapName, (ckt, which, foo, steptype, &ptemp)); + INPgetTok(&line, &steptype, 1); /* get POL, ZER, or PZ */ + ptemp.iValue = 1; + GCA(INPapName, (ckt, which, foo, steptype, &ptemp)); + return (0); +} + + +static int +dot_dc(char *line, void *ckt, INPtables *tab, card *current, + void *task, void *gnode, void *foo) +{ + char *name; /* the resistor's name */ + int error; /* error code temporary */ + IFvalue ptemp; /* a value structure to package resistance into */ + IFvalue *parm; /* a pointer to a value struct for function returns */ + int which; /* which analysis we are performing */ + int i; /* generic loop variable */ + + /* .dc SRC1NAME Vstart1 Vstop1 Vinc1 [SRC2NAME Vstart2 */ + /* Vstop2 Vinc2 */ + which = -1; + for (i = 0; i < ft_sim->numAnalyses; i++) { + if (strcmp(ft_sim->analyses[i]->name, "DC") == 0) { + which = i; + break; + } + } + if (which == -1) { + LITERR("DC transfer curve analysis unsupported\n"); + return (0); + } + IFC(newAnalysis, (ckt, which, "DC transfer characteristic", &foo, task)); + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + ptemp.uValue = name; + GCA(INPapName, (ckt, which, foo, "name1", &ptemp)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstart1 */ + GCA(INPapName, (ckt, which, foo, "start1", parm)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstop1 */ + GCA(INPapName, (ckt, which, foo, "stop1", parm)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vinc1 */ + GCA(INPapName, (ckt, which, foo, "step1", parm)); + if (*line) { + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + ptemp.uValue = name; + GCA(INPapName, (ckt, which, foo, "name2", &ptemp)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstart1 */ + GCA(INPapName, (ckt, which, foo, "start2", parm)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstop1 */ + GCA(INPapName, (ckt, which, foo, "stop2", parm)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vinc1 */ + GCA(INPapName, (ckt, which, foo, "step2", parm)); + } + return 0; +} + + +static int +dot_tf(char *line, void *ckt, INPtables *tab, card *current, + void *task, void *gnode, void *foo) +{ + char *name; /* the resistor's name */ + int error; /* error code temporary */ + IFvalue ptemp; /* a value structure to package resistance into */ + int which; /* which analysis we are performing */ + int i; /* generic loop variable */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + + /* .tf v( node1, node2 ) src */ + /* .tf vsrc2 src */ + which = -1; + for (i = 0; i < ft_sim->numAnalyses; i++) { + if (strcmp(ft_sim->analyses[i]->name, "TF") == 0) { + which = i; + break; + } + } + if (which == -1) { + LITERR("Transfer Function analysis unsupported.\n"); + return (0); + } + IFC(newAnalysis, (ckt, which, "Transfer Function", &foo, task)); + INPgetTok(&line, &name, 0); + /* name is now either V or I or a serious error */ + if (*name == 'v' && strlen(name) == 1) { + if (*line != '(' ) { + /* error, bad input format */ + } + INPgetTok(&line, &nname1, 0); + INPtermInsert(ckt, &nname1, tab, &node1); + ptemp.nValue = (IFnode) node1; + GCA(INPapName, (ckt, which, foo, "outpos", &ptemp)); + if (*line != ')') { + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + ptemp.nValue = (IFnode) node2; + GCA(INPapName, (ckt, which, foo, "outneg", &ptemp)); + ptemp.sValue = + (char *) MALLOC(sizeof(char) * + (5 + strlen(nname1) + strlen(nname2))); + (void) sprintf(ptemp.sValue, "V(%s,%s)", nname1, nname2); + GCA(INPapName, (ckt, which, foo, "outname", &ptemp)); + } else { + ptemp.nValue = (IFnode) gnode; + GCA(INPapName, (ckt, which, foo, "outneg", &ptemp)); + ptemp.sValue = + (char *) MALLOC(sizeof(char) * (4 + strlen(nname1))); + (void) sprintf(ptemp.sValue, "V(%s)", nname1); + GCA(INPapName, (ckt, which, foo, "outname", &ptemp)); + } + } else if (*name == 'i' && strlen(name) == 1) { + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + ptemp.uValue = name; + GCA(INPapName, (ckt, which, foo, "outsrc", &ptemp)); + } else { + LITERR("Syntax error: voltage or current expected.\n"); + return 0; + } + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + ptemp.uValue = name; + GCA(INPapName, (ckt, which, foo, "insrc", &ptemp)); + return (0); +} + + +static int +dot_tran(char *line, void *ckt, INPtables *tab, card *current, + void *task, void *gnode, void *foo) +{ + int error; /* error code temporary */ + IFvalue ptemp; /* a value structure to package resistance into */ + IFvalue *parm; /* a pointer to a value struct for function returns */ + int which; /* which analysis we are performing */ + int i; /* generic loop variable */ + double dtemp; /* random double precision temporary */ + char *word; /* something to stick a word of input into */ + + /* .tran Tstep Tstop > */ + which = -1; + for (i = 0; i < ft_sim->numAnalyses; i++) { + if (strcmp(ft_sim->analyses[i]->name, "TRAN") == 0) { + which = i; + break; + } + } + if (which == -1) { + LITERR("Transient analysis unsupported.\n"); + return (0); + } + IFC(newAnalysis, (ckt, which, "Transient Analysis", &foo, task)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* Tstep */ + GCA(INPapName, (ckt, which, foo, "tstep", parm)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* Tstop */ + GCA(INPapName, (ckt, which, foo, "tstop", parm)); + if (*line) { + dtemp = INPevaluate(&line, &error, 1); /* tstart? */ + if (error == 0) { + ptemp.rValue = dtemp; + GCA(INPapName, (ckt, which, foo, "tstart", &ptemp)); + dtemp = INPevaluate(&line, &error, 1); /* tmax? */ + if (error == 0) { + ptemp.rValue = dtemp; + GCA(INPapName, (ckt, which, foo, "tmax", &ptemp)); + } + } + } + if (*line) { + INPgetTok(&line, &word, 1); /* uic? */ + if (strcmp(word, "uic") == 0) { + ptemp.iValue = 1; + GCA(INPapName, (ckt, which, foo, "uic", &ptemp)); + } else { + LITERR(" Error: unknown parameter on .tran - ignored\n"); + } + } + return (0); +} + + +static int +dot_sens(char *line, void *ckt, INPtables *tab, card *current, + void *task, void *gnode, void *foo) +{ + char *name; /* the resistor's name */ + int error; /* error code temporary */ + IFvalue ptemp; /* a value structure to package resistance into */ + IFvalue *parm; /* a pointer to a value struct for function returns */ + int which; /* which analysis we are performing */ + int i; /* generic loop variable */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + char *steptype; /* ac analysis, type of stepping function */ + + which = -1; /* Bug fix from Glao Dezai */ + for (i = 0; i < ft_sim->numAnalyses; i++) { + if (strcmp(ft_sim->analyses[i]->name, "SENS") == 0) { + which = i; + break; + } + } + if (which == -1) { + LITERR("Sensitivity unsupported.\n"); + return (0); + } + + IFC(newAnalysis, (ckt, which, "Sensitivity Analysis", &foo, task)); + + /* Format is: + * .sens + * + [ac [dec|lin|oct] | dc ] + */ + /* Get the output voltage or current */ + INPgetTok(&line, &name, 0); + /* name is now either V or I or a serious error */ + if (*name == 'v' && strlen(name) == 1) { + if (*line != '(') { + LITERR("Syntax error: '(' expected after 'v'\n"); + return 0; + } + INPgetTok(&line, &nname1, 0); + INPtermInsert(ckt, &nname1, tab, &node1); + ptemp.nValue = (IFnode) node1; + GCA(INPapName, (ckt, which, foo, "outpos", &ptemp)) + + if (*line != ')') { + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + ptemp.nValue = (IFnode) node2; + GCA(INPapName, (ckt, which, foo, "outneg", &ptemp)); + ptemp.sValue = (char *) + MALLOC(sizeof(char) * + (5 + strlen(nname1) + strlen(nname2))); + (void) sprintf(ptemp.sValue, "V(%s,%s)", nname1, nname2); + GCA(INPapName, (ckt, which, foo, "outname", &ptemp)); + } else { + ptemp.nValue = (IFnode) gnode; + GCA(INPapName, (ckt, which, foo, "outneg", &ptemp)); + ptemp.sValue = + (char *) MALLOC(sizeof(char) * (4 + strlen(nname1))); + (void) sprintf(ptemp.sValue, "V(%s)", nname1); + GCA(INPapName, (ckt, which, foo, "outname", &ptemp)); + } + } else if (*name == 'i' && strlen(name) == 1) { + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + ptemp.uValue = name; + GCA(INPapName, (ckt, which, foo, "outsrc", &ptemp)); + } else { + LITERR("Syntax error: voltage or current expected.\n"); + return 0; + } + + INPgetTok(&line, &name, 1); + if (name && !strcmp(name, "pct")) { + ptemp.iValue = 1; + GCA(INPapName, (ckt, which, foo, "pct", &ptemp)) + INPgetTok(&line, &name, 1); + } + if (name && !strcmp(name, "ac")) { + INPgetTok(&line, &steptype, 1); /* get DEC, OCT, or LIN */ + ptemp.iValue = 1; + GCA(INPapName, (ckt, which, foo, steptype, &ptemp)); + parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* number of points */ + GCA(INPapName, (ckt, which, foo, "numsteps", parm)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstart */ + GCA(INPapName, (ckt, which, foo, "start", parm)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstop */ + GCA(INPapName, (ckt, which, foo, "stop", parm)); + return (0); + } else if (name && *name && strcmp(name, "dc")) { + /* Bad flag */ + LITERR("Syntax error: 'ac' or 'dc' expected.\n"); + return 0; + } + return (0); +} + + +#ifdef WANT_SENSE2 +static int +dot_sens2(char *line, void *ckt, INPtables *tab, card *current, + void *task, void *gnode, void *foo) +{ + int error; /* error code temporary */ + IFvalue ptemp; /* a value structure to package resistance into */ + IFvalue *parm; /* a pointer to a value struct for function returns */ + int which; /* which analysis we are performing */ + int i; /* generic loop variable */ + char *token; /* a token from the line */ + + /* .sens {AC} {DC} {TRAN} [dev=nnn parm=nnn]* */ + which = -1; + for (i = 0; i < ft_sim->numAnalyses; i++) { + if (strcmp(ft_sim->analyses[i]->name, "SENS2") == 0) { + which = i; + break; + } + } + if (which == -1) { + LITERR("Sensitivity-2 analysis unsupported\n"); + return (0); + } + IFC(newAnalysis, (ckt, which, "Sensitivity-2 Analysis", &foo, task)); + while (*line) { + /* read the entire line */ + INPgetTok(&line, &token, 1); + for (i = 0; i < ft_sim->analyses[which]->numParms; i++) { + /* find the parameter */ + if (0 == strcmp(token, + ft_sim->analyses[which]->analysisParms[i].keyword)) { + /* found it, analysis which, parameter i */ + if (ft_sim->analyses[which]->analysisParms[i].dataType & IF_FLAG) { + /* one of the keywords! */ + ptemp.iValue = 1; + error = + (*(ft_sim->setAnalysisParm)) (ckt, foo, + ft_sim->analyses[which]->analysisParms[i].id, + &ptemp, + (IFvalue *) NULL); + if (error) + current->error = + INPerrCat(current->error, INPerror(error)); + } else { + parm = + INPgetValue(ckt, &line, + ft_sim->analyses[which]->analysisParms[i].dataType, tab); + error = + (*(ft_sim->setAnalysisParm)) (ckt, foo, + ft_sim-> + analyses + [which]->analysisParms + [i].id, parm, + (IFvalue *) + NULL); + if (error) + current->error = + INPerrCat(current->error, INPerror(error)); + + } + break; + } + } + if (i == ft_sim->analyses[which]->numParms) { + /* didn't find it! */ + LITERR(" Error: unknown parameter on .sens-ignored \n"); + } + } + return (0); +} +#endif + +static int +dot_options(char *line, void *ckt, INPtables *tab, card *current, + void *task, void *gnode, void *foo) +{ + /* .option - specify program options - rather complicated */ + /* use a subroutine to handle all of them to keep this */ + /* subroutine managable. */ + + INPdoOpts(ckt,task,current,tab); + return (0); +} + + +int +INP2dot(void *ckt, INPtables *tab, card *current, void *task, void *gnode) +{ + + /* . Many possibilities */ + char *token; /* a token from the line */ + void *foo = NULL; /* pointer to analysis */ + /* the part of the current line left to parse */ + char *line = current->line; + + INPgetTok(&line, &token, 1); + if (strcmp(token, ".model") == 0) { + /* don't have to do anything, since models were all done in + * pass 1 */ + return (0); + } else if ((strcmp(token, ".width") == 0) || + strcmp(token, ".print") == 0 || strcmp(token, ".plot") == 0) { + /* obsolete - ignore */ + LITERR(" Warning: obsolete control card - ignored \n"); + return (0); + } else if ((strcmp(token, ".temp") == 0)) { + /* .temp temp1 temp2 temp3 temp4 ..... */ + /* not yet implemented - warn & ignore */ + LITERR(" Warning: .TEMP card obsolete - use .options TEMP and TNOM\n"); + return (0); + } else if ((strcmp(token, ".op") == 0)) { + return dot_op(line, ckt, tab, current, task, gnode, foo); + } else if ((strcmp(token, ".nodeset") == 0)) { + return(0); + } else if ((strcmp(token, ".disto") == 0)) { + return dot_disto(line, ckt, tab, current, task, gnode, foo); + } else if ((strcmp(token, ".noise") == 0)) { + return dot_noise(line, ckt, tab, current, task, gnode, foo); + } else if ((strcmp(token, ".four") == 0) + || (strcmp(token, ".fourier") == 0)) { + /* .four */ + /* not implemented - warn & ignore */ + LITERR("Use fourier command to obtain fourier analysis\n"); + return (0); + } else if ((strcmp(token, ".ic") == 0)) { + return (0); + } else if ((strcmp(token, ".ac") == 0)) { + return dot_ac(line, ckt, tab, current, task, gnode, foo); + } else if ((strcmp(token, ".pz") == 0)) { + return dot_pz(line, ckt, tab, current, task, gnode, foo); + } else if ((strcmp(token, ".dc") == 0)) { + return dot_dc(line, ckt, tab, current, task, gnode, foo); + } else if ((strcmp(token, ".tf") == 0)) { + return dot_tf(line, ckt, tab, current, task, gnode, foo); + } else if ((strcmp(token, ".tran") == 0)) { + return dot_tran(line, ckt, tab, current, task, gnode, foo); + } else if ((strcmp(token, ".subckt") == 0) || + (strcmp(token, ".ends") == 0)) { + /* not yet implemented - warn & ignore */ + LITERR(" Warning: Subcircuits not yet implemented - ignored \n"); + return (0); + } else if ((strcmp(token, ".end") == 0)) { + /* .end - end of input */ + /* not allowed to pay attention to additional input - return */ + return (1); + } else if (strcmp(token, ".sens") == 0) { + return dot_sens(line, ckt, tab, current, task, gnode, foo); + } +#ifdef WANT_SENSE2 + else if ((strcmp(token, ".sens2") == 0)) { + return dot_sens2(line, ckt, tab, current, task, gnode, foo); + } +#endif + else if ((strcmp(token, ".probe") == 0)) { + /* Maybe generate a "probe" format file in the future. */ + return 0; + } + else if ((strcmp(token, ".options") == 0)|| + (strcmp(token,".option")==0) || + (strcmp(token,".opt")==0)) { + return dot_options(line, ckt, tab, current, task, gnode, foo); + } + LITERR(" unimplemented control card - error \n"); + return (0); +} diff --git a/src/spicelib/parser/inp2e.c b/src/spicelib/parser/inp2e.c new file mode 100644 index 000000000..cd88609be --- /dev/null +++ b/src/spicelib/parser/inp2e.c @@ -0,0 +1,68 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2E(void *ckt, INPtables * tab, card * current) +{ + +/* Ename */ + + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + char *nname3; /* the third node's name */ + char *nname4; /* the fourth node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + void *node3; /* the third node's node pointer */ + void *node4; /* the fourth node's node pointer */ + int error; /* error code temporary */ + void *fast; /* pointer to the actual instance */ + IFvalue ptemp; /* a value structure to package resistance into */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + IFuid uid; /* uid for default model */ + + type = INPtypelook("VCVS"); + if (type < 0) { + LITERR("Device type VCVS not supported by this binary\n"); + return; + } + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + INPgetTok(&line, &nname3, 1); + INPtermInsert(ckt, &nname3, tab, &node3); + INPgetTok(&line, &nname4, 1); + INPtermInsert(ckt, &nname4, tab, &node4); + if (!tab->defEmod) { + /* create default E model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "E", UID_MODEL, (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defEmod), uid)); + } + IFC(newInstance, (ckt, tab->defEmod, &fast, name)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + IFC(bindNode, (ckt, fast, 3, node3)); + IFC(bindNode, (ckt, fast, 4, node4)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) { + ptemp.rValue = leadval; + GCA(INPpName, ("gain", &ptemp, ckt, type, fast)); + } +} diff --git a/src/spicelib/parser/inp2f.c b/src/spicelib/parser/inp2f.c new file mode 100644 index 000000000..32c477863 --- /dev/null +++ b/src/spicelib/parser/inp2f.c @@ -0,0 +1,61 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2F(void *ckt, INPtables * tab, card * current) +{ + +/* Fname */ + + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + int error; /* error code temporary */ + void *fast; /* pointer to the actual instance */ + IFvalue ptemp; /* a value structure to package resistance into */ + IFvalue *parm; /* a pointer to a value structure to pick things up into */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + IFuid uid; /* uid for default model */ + + type = INPtypelook("CCCS"); + if (type < 0) { + LITERR("Device type CCCS not supported by this binary\n"); + return; + } + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + if (!tab->defFmod) { + /* create default F model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "F", UID_MODEL, (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defFmod), uid)); + } + IFC(newInstance, (ckt, tab->defFmod, &fast, name)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + parm = INPgetValue(ckt, &line, IF_INSTANCE, tab); + GCA(INPpName, ("control", parm, ckt, type, fast)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) { + ptemp.rValue = leadval; + GCA(INPpName, ("gain", &ptemp, ckt, type, fast)); + } +} diff --git a/src/spicelib/parser/inp2g.c b/src/spicelib/parser/inp2g.c new file mode 100644 index 000000000..60ad74de0 --- /dev/null +++ b/src/spicelib/parser/inp2g.c @@ -0,0 +1,68 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2G(void *ckt, INPtables * tab, card * current) +{ + +/* Gname */ + + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + char *nname3; /* the third node's name */ + char *nname4; /* the fourth node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + void *node3; /* the third node's node pointer */ + void *node4; /* the fourth node's node pointer */ + int error; /* error code temporary */ + void *fast; /* pointer to the actual instance */ + IFvalue ptemp; /* a value structure to package resistance into */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + IFuid uid; /* uid of default model to be created */ + + type = INPtypelook("VCCS"); + if (type < 0) { + LITERR("Device type VCCS not supported by this binary\n"); + return; + } + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + INPgetTok(&line, &nname3, 1); + INPtermInsert(ckt, &nname3, tab, &node3); + INPgetTok(&line, &nname4, 1); + INPtermInsert(ckt, &nname4, tab, &node4); + if (!tab->defGmod) { + /* create default G model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "G", UID_MODEL, (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defGmod), uid)); + } + IFC(newInstance, (ckt, tab->defGmod, &fast, name)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + IFC(bindNode, (ckt, fast, 3, node3)); + IFC(bindNode, (ckt, fast, 4, node4)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) { + ptemp.rValue = leadval; + GCA(INPpName, ("gain", &ptemp, ckt, type, fast)); + } +} diff --git a/src/spicelib/parser/inp2h.c b/src/spicelib/parser/inp2h.c new file mode 100644 index 000000000..04d386358 --- /dev/null +++ b/src/spicelib/parser/inp2h.c @@ -0,0 +1,61 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2H(void *ckt, INPtables * tab, card * current) +{ + +/* Hname */ + + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + int error; /* error code temporary */ + void *fast; /* pointer to the actual instance */ + IFvalue ptemp; /* a value structure to package resistance into */ + IFvalue *parm; /* pointer to a value structure for functions which return one */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + IFuid uid; /* uid for default model to be created */ + + type = INPtypelook("CCVS"); + if (type < 0) { + LITERR("Device type CCVS not supported by this binary\n"); + return; + } + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + if (!tab->defHmod) { + /* create default H model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "H", UID_MODEL, (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defHmod), uid)); + } + IFC(newInstance, (ckt, tab->defHmod, &fast, name)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + parm = INPgetValue(ckt, &line, IF_INSTANCE, tab); + GCA(INPpName, ("control", parm, ckt, type, fast)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) { + ptemp.rValue = leadval; + GCA(INPpName, ("gain", &ptemp, ckt, type, fast)); + } +} diff --git a/src/spicelib/parser/inp2i.c b/src/spicelib/parser/inp2i.c new file mode 100644 index 000000000..9bb01c5d5 --- /dev/null +++ b/src/spicelib/parser/inp2i.c @@ -0,0 +1,59 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2I(void *ckt, INPtables * tab, card * current) +{ + + /* Iname [ [DC] ] [AC [ [ ] ] ] + * [] */ + + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + int error; /* error code temporary */ + void *fast; /* pointer to the actual instance */ + IFvalue ptemp; /* a value structure to package resistance into */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + IFuid uid; /* uid for default model */ + + type = INPtypelook("Isource"); + if (type < 0) { + LITERR("Device type Isource not supported by this binary\n"); + return; + } + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + if (!tab->defImod) { + /* create default I model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "I", UID_MODEL, (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defImod), uid)); + } + IFC(newInstance, (ckt, tab->defImod, &fast, name)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) { + ptemp.rValue = leadval; + GCA(INPpName, ("dc", &ptemp, ckt, type, fast)); + } +} diff --git a/src/spicelib/parser/inp2j.c b/src/spicelib/parser/inp2j.c new file mode 100644 index 000000000..565fc12a6 --- /dev/null +++ b/src/spicelib/parser/inp2j.c @@ -0,0 +1,83 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2J(void *ckt, INPtables * tab, card * current) +{ + + /* Jname [] [OFF] [IC=,] */ + + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + char *nname3; /* the third node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + void *node3; /* the third node's node pointer */ + int error; /* error code temporary */ + void *fast; /* pointer to the actual instance */ + IFvalue ptemp; /* a value structure to package resistance into */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + char *model; /* the name of the model */ + INPmodel *thismodel; /* pointer to model description for user's model */ + void *mdfast; /* pointer to the actual model */ + IFuid uid; /* uid of default model */ + + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + INPgetTok(&line, &nname3, 1); + INPtermInsert(ckt, &nname3, tab, &node3); + INPgetTok(&line, &model, 1); + INPinsert(&model, tab); + thismodel = (INPmodel *) NULL; + current->error = INPgetMod(ckt, model, &thismodel, tab); + if (thismodel != NULL) { + if (thismodel->INPmodType != INPtypelook("JFET") + && thismodel->INPmodType != INPtypelook("JFET2") + ) { + LITERR("incorrect model type"); + return; + } + type = thismodel->INPmodType; + mdfast = (thismodel->INPmodfast); + } else { + type = INPtypelook("JFET"); + if (type < 0) { + LITERR("Device type JFET not supported by this binary\n"); + return; + } + if (!tab->defJmod) { + /* create default J model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "J", UID_MODEL, + (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defJmod), uid)); + } + mdfast = tab->defJmod; + } + IFC(newInstance, (ckt, mdfast, &fast, name)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + IFC(bindNode, (ckt, fast, 3, node3)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) { + ptemp.rValue = leadval; + GCA(INPpName, ("area", &ptemp, ckt, type, fast)); + } +} diff --git a/src/spicelib/parser/inp2k.c b/src/spicelib/parser/inp2k.c new file mode 100644 index 000000000..b54a21273 --- /dev/null +++ b/src/spicelib/parser/inp2k.c @@ -0,0 +1,55 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2K(void *ckt, INPtables * tab, card * current) +{ + +/* Kname Lname Lname */ + + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + int error; /* error code temporary */ + void *fast; /* pointer to the actual instance */ + IFvalue ptemp; /* a value structure to package resistance into */ + IFvalue *parm; /* ptr to a value structure for function return values */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + IFuid uid; /* uid for default model */ + + line = current->line; + type = INPtypelook("mutual"); + if (type < 0) { + LITERR("Device type mutual not supported by this binary\n"); + return; + } + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + if (!tab->defKmod) { + /* create deafult K model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "K", UID_MODEL, (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defKmod), uid)); + } + IFC(newInstance, (ckt, tab->defKmod, &fast, name)); + + parm = INPgetValue(ckt, &line, IF_INSTANCE, tab); + GCA(INPpName, ("inductor1", parm, ckt, type, fast)); + parm = INPgetValue(ckt, &line, IF_INSTANCE, tab); + GCA(INPpName, ("inductor2", parm, ckt, type, fast)); + + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) { + ptemp.rValue = leadval; + GCA(INPpName, ("coefficient", &ptemp, ckt, type, fast)); + } +} diff --git a/src/spicelib/parser/inp2l.c b/src/spicelib/parser/inp2l.c new file mode 100644 index 000000000..341463dc7 --- /dev/null +++ b/src/spicelib/parser/inp2l.c @@ -0,0 +1,58 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2L(void *ckt, INPtables * tab, card * current) +{ +/* parse an inductor card */ +/* Lname [IC=] */ + + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + int error; /* error code temporary */ + void *fast; /* pointer to the actual instance */ + IFvalue ptemp; /* a value structure to package resistance into */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + IFuid uid; /* uid for default model */ + + type = INPtypelook("Inductor"); + if (type < 0) { + LITERR("Device type Inductor not supported by this binary\n"); + return; + } + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + if (!tab->defLmod) { + /* create default L model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "L", UID_MODEL, (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defLmod), uid)); + } + IFC(newInstance, (ckt, tab->defLmod, &fast, name)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) { + ptemp.rValue = leadval; + GCA(INPpName, ("inductance", &ptemp, ckt, type, fast)); + } +} diff --git a/src/spicelib/parser/inp2m.c b/src/spicelib/parser/inp2m.c new file mode 100644 index 000000000..341214160 --- /dev/null +++ b/src/spicelib/parser/inp2m.c @@ -0,0 +1,250 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void +INP2M (void *ckt, INPtables * tab, card * current) +{ + + /* Mname [L=] + * [W=] [AD=] [AS=] [PD=] + * [PS=] [NRD=] [NRS=] [OFF] + * [IC=,,] + */ + + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + char *nname3; /* the third node's name */ + char *nname4; /* the fourth node's name */ + char *nname5; /* the fifth node's name */ + char *nname6; /* the sixt node's name */ + char *nname7; /* the seventh node's name */ + char *save; /* saj - used to save the posn of + the start of the parameters if the model is a mosfet*/ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + void *node3; /* the third node's node pointer */ + void *node4; /* the fourth node's node pointer */ + void *node5; /* the fifth node's node pointer */ + void *node6; /* the sixth node's node pointer */ + void *node7; /* the seventh node's node pointer */ + int error; /* error code temporary */ + int nodeflag; /* flag indicating 4 or 5 (or 6 or 7) nodes */ + void *fast; /* pointer to the actual instance */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + char *model; /* the name of the model */ + INPmodel *thismodel; /* pointer to model description for user's model */ + void *mdfast; /* pointer to the actual model */ + IFuid uid; /* uid for default model */ + + nodeflag = 0; /* initially specify a 4 terminal device */ + line = current->line; + INPgetTok (&line, &name, 1); + INPinsert (&name, tab); + INPgetTok (&line, &nname1, 1); + INPtermInsert (ckt, &nname1, tab, &node1); + INPgetTok (&line, &nname2, 1); + INPtermInsert (ckt, &nname2, tab, &node2); + INPgetTok (&line, &nname3, 1); + INPtermInsert (ckt, &nname3, tab, &node3); + INPgetTok (&line, &nname4, 1); + INPtermInsert (ckt, &nname4, tab, &node4); + + /* See if 5th token after device specification is a model name */ + + INPgetTok (&line, &nname5, 1); /* get 5th token */ + save = line; /*saj - save the posn for later if + the default mosfet model is used */ + thismodel = (INPmodel *) NULL; + INPgetMod (ckt, nname5, &thismodel, tab); + if (thismodel == NULL) + { /* 5th token is not a model in the table */ + nodeflag = 1; /* now specify a 5 node device */ + INPgetTok (&line, &nname6, 1); /* get next token */ + thismodel = (INPmodel *) NULL; + INPgetMod (ckt, nname6, &thismodel, tab); + if (thismodel == NULL) + { /* 6th token is not a model in the table */ + nodeflag = 2; /* now specify a 6 node device */ + INPgetTok (&line, &nname7, 1); /* get next token */ + thismodel = (INPmodel *) NULL; + INPgetMod (ckt, nname7, &thismodel, tab); + if (thismodel == NULL) + { /* 7th token is not a model in the table */ + nodeflag = 3; /* now specify a 7 node device */ + INPgetTok (&line, &model, 1); /* get model name */ + INPgetMod (ckt, model, &thismodel, tab); /* get pointer to the model */ + if (thismodel != NULL) + { + if ((thismodel->INPmodType != INPtypelook ("B3SOIPD")) && + (thismodel->INPmodType != INPtypelook ("B3SOIFD")) && + (thismodel->INPmodType != INPtypelook ("B3SOIDD")) + ) + { + /* if model is not variable node B3SOIPD/FD/DD model, error! */ + LITERR ("only level 9-10 B3SOI(PD | FD | DD) can have 7 nodes") return; + } + else + { /* if looking at B3SOIPD/FD/DD model, allocate the 7th node */ + INPtermInsert (ckt, &nname5, tab, &node5); + INPtermInsert (ckt, &nname6, tab, &node6); + INPtermInsert (ckt, &nname7, tab, &node7); + } + } + /*saj unbreak the default model creation*/ + else{ + model = nname5;/*mosfet*/ + line = save; /* reset the posn to what it sould be */ + } + /*saj*/ + } + else + { /* 7th token is a model - only have 6 terminal device */ + if ((thismodel->INPmodType != INPtypelook ("B3SOIPD")) && + (thismodel->INPmodType != INPtypelook ("B3SOIFD")) && + (thismodel->INPmodType != INPtypelook ("B3SOIDD")) && + (thismodel->INPmodType != INPtypelook ("SOI3")) + ) + { + /* if model is not variable node B3SOIPD/FD/DD or STAG model, error! */ + LITERR ("only level 9-10 B3SOI(PD | FD | DD) and STAG (SOI3) can have 6 nodes") return; + } + else + { /* if looking at B3SOIPD/FD/DD or STAG (SOI3) model, allocate the 6th node */ + INPtermInsert (ckt, &nname5, tab, &node5); + INPtermInsert (ckt, &nname6, tab, &node6); + model = nname7; + } + } + } + else + { /* 6th token is a model - only have 5 terminal device */ + if ((thismodel->INPmodType != INPtypelook ("B3SOIPD")) && + (thismodel->INPmodType != INPtypelook ("B3SOIFD")) && + (thismodel->INPmodType != INPtypelook ("B3SOIDD")) && + (thismodel->INPmodType != INPtypelook ("SOI3")) + ) + { + /* if model is not variable node B3SOIPD/FD/DD model, error! */ + LITERR ("only level 9-10 B3SOI(PD | FD | DD) and STAG (SOI3) can have 5 nodes") return; + } + else + { /* if looking at B3SOIPD/FD/DD or STAG (SOI3) model, allocate the 5th node */ + INPtermInsert (ckt, &nname5, tab, &node5); + model = nname6; /* make model point to the correct token */ + } + } + } + + else + { /* 5th token is a model - only have 4 terminal device */ + model = nname5; /* make model point to the correct token */ + } + + + + INPinsert (&model, tab); + thismodel = (INPmodel *) NULL; + current->error = INPgetMod (ckt, model, &thismodel, tab); + if (thismodel != NULL) + { + if (thismodel->INPmodType != INPtypelook ("Mos1") + && thismodel->INPmodType != INPtypelook ("Mos2") + && thismodel->INPmodType != INPtypelook ("Mos3") + && thismodel->INPmodType != INPtypelook ("Mos5") + && thismodel->INPmodType != INPtypelook ("Mos6") + && thismodel->INPmodType != INPtypelook ("Mos8") + && thismodel->INPmodType != INPtypelook ("Mos9") + && thismodel->INPmodType != INPtypelook ("BSIM1") + && thismodel->INPmodType != INPtypelook ("BSIM2") + && thismodel->INPmodType != INPtypelook ("BSIM3") + && thismodel->INPmodType != INPtypelook ("B3SOIPD") + && thismodel->INPmodType != INPtypelook ("B3SOIFD") + && thismodel->INPmodType != INPtypelook ("B3SOIDD") + && thismodel->INPmodType != INPtypelook ("BSIM4") + && thismodel->INPmodType != INPtypelook ("BSIM3V1") + && thismodel->INPmodType != INPtypelook ("BSIM3V2") + && thismodel->INPmodType != INPtypelook ("SOI3") +#ifdef HAVE_EKV + && thismodel->INPmodType != INPtypelook ("EKV") +#endif + ) + { + LITERR ("incorrect model type"); + return; + } + type = thismodel->INPmodType; + mdfast = (thismodel->INPmodfast); + } + else + { + type = INPtypelook ("Mos1"); + if (type < 0) + { + LITERR ("Device type MOS1 not supported by this binary\n"); + return; + } + if (!tab->defMmod) + { + /* create default M model */ + IFnewUid (ckt, &uid, (IFuid) NULL, "M", UID_MODEL, (void **) NULL); + IFC (newModel, (ckt, type, &(tab->defMmod), uid)); + } + mdfast = tab->defMmod; + } + IFC (newInstance, (ckt, mdfast, &fast, name)); + IFC (bindNode, (ckt, fast, 1, node1)); + IFC (bindNode, (ckt, fast, 2, node2)); + IFC (bindNode, (ckt, fast, 3, node3)); + IFC (bindNode, (ckt, fast, 4, node4)); + /*use type not thismodel->INPmodType as it might not exist!*/ + if ((type == INPtypelook ("B3SOIPD")) || + (type == INPtypelook ("B3SOIFD")) || + (type == INPtypelook ("B3SOIDD")) || + (type == INPtypelook ("SOI3"))) + { + switch (nodeflag) + { + case 0: + ((GENinstance *) fast)->GENnode5 = -1; + ((GENinstance *) fast)->GENnode6 = -1; + ((GENinstance *) fast)->GENnode7 = -1; + break; + case 1: + IFC (bindNode, (ckt, fast, 5, node5)) + ((GENinstance *) fast)->GENnode6 = -1; + ((GENinstance *) fast)->GENnode7 = -1; + break; + case 2: + IFC (bindNode, (ckt, fast, 5, node5)) + IFC (bindNode, (ckt, fast, 6, node6)) + ((GENinstance *) fast)->GENnode7 = -1; + break; + case 3: + IFC (bindNode, (ckt, fast, 5, node5)) + IFC (bindNode, (ckt, fast, 6, node6)) + IFC (bindNode, (ckt, fast, 7, node7)) break; + default: + break; + } + } + + PARSECALL ((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) + { + LITERR (" error: no unlabeled parameter permitted on mosfet\n"); + } +} diff --git a/src/spicelib/parser/inp2o.c b/src/spicelib/parser/inp2o.c new file mode 100644 index 000000000..33e7cf59c --- /dev/null +++ b/src/spicelib/parser/inp2o.c @@ -0,0 +1,91 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1990 Jaijeet S. Roychowdhury +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + + +void INP2O(void *ckt, INPtables * tab, card * current) +{ + + /* Oname [IC=,,,] */ + + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + char *nname3; /* the third node's name */ + char *nname4; /* the fourth node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + void *node3; /* the third node's node pointer */ + void *node4; /* the fourth node's node pointer */ + int error; /* error code temporary */ + void *fast; /* pointer to the actual instance */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + char *model; /* the name of the model */ + INPmodel *thismodel; /* pointer to model description for user's model */ + void *mdfast; /* pointer to the actual model */ + IFuid uid; /* uid for default model */ + + + type = INPtypelook("LTRA"); + if (type < 0) { + LITERR("Device type LossyXmissionLine not supported by this binary\n"); + return; + } + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + INPgetTok(&line, &nname3, 1); + INPtermInsert(ckt, &nname3, tab, &node3); + INPgetTok(&line, &nname4, 1); + INPtermInsert(ckt, &nname4, tab, &node4); + INPgetTok(&line, &model, 1); + if (INPlookMod(model)) { + /* do nothing for now */ + /* no action required */ + } else { + /* + nname4 = model; + INPtermInsert(ckt,&nname4,tab,&node4); + INPgetTok(&line,&model,1); + */ + } + INPinsert(&model, tab); + current->error = INPgetMod(ckt, model, &thismodel, tab); + if (thismodel != NULL) { + if (type != thismodel->INPmodType) { + LITERR("incorrect model type"); + return; + } + mdfast = (thismodel->INPmodfast); + } else { + if (!tab->defOmod) { + /* create default O model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "O", UID_MODEL, + (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defOmod), uid)); + } + mdfast = tab->defOmod; + } + IFC(newInstance, (ckt, mdfast, &fast, name)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + IFC(bindNode, (ckt, fast, 3, node3)); + IFC(bindNode, (ckt, fast, 4, node4)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); +} diff --git a/src/spicelib/parser/inp2p.c b/src/spicelib/parser/inp2p.c new file mode 100644 index 000000000..e6977c5bd --- /dev/null +++ b/src/spicelib/parser/inp2p.c @@ -0,0 +1,131 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void +INP2P(ckt,tab,current) + void *ckt; + INPtables *tab; + card *current; + +{ + +int mytype; /* the type we determine cpls are */ +int type; /* the type the model says it is */ +char *line; /* the part of the current line left to parse */ +char *name, *tempname; /* the cpl's name */ +char *model; /* the name of the cpl's model */ +char **nname1; /* the first node's name */ +char **nname2; /* the second node's name */ +char *ground; +void **node1; /* the first node's node pointer */ +void **node2; /* the second node's node pointer */ +void *groundnode; +int error; /* error code temporary */ +int error1; /* secondary error code temporary */ +INPmodel *thismodel; /* pointer to model structure describing our model */ +void *mdfast; /* pointer to the actual model */ +void *fast; /* pointer to the actual instance */ +IFvalue ptemp; /* a value structure to package cpl into */ +IFuid uid; /* uid for default model */ +double lenval = 0; +int lenvalgiven = 0; +int num, i; + + mytype = INPtypelook("CplLines"); + if(mytype < 0 ) { + LITERR("Device type CplLines not supported by this binary\n") + return; + } + line = current->line; + INPgetTok(&line,&name,1); + INPinsert(&name,tab); + /* num = (int) INPevaluate(&line,&error1,1); */ + num = 0; + + /* first pass to determine the dimension */ + while (*line != '\0') { + INPgetTok(&line, &tempname,1); + if (strcmp(tempname, "len") == 0) break; + num ++; + } + num = (num - 2) / 2; + line = current->line; + INPgetTok(&line,&name,1); + + nname1 = (char **) malloc(num * sizeof(char *)); + nname2 = (char **) malloc(num * sizeof(char *)); + node1 = (void **) malloc(num * sizeof(void *)); + node2 = (void **) malloc(num * sizeof(void *)); + + + for (i = 0; i < num; i++) { + INPgetTok(&line,&(nname1[i]),1); + INPtermInsert(ckt,&(nname1[i]),tab,&(node1[i])); + } + INPgetTok(&line,&ground,1); + INPtermInsert(ckt,&ground,tab,&groundnode); + for (i = 0; i < num; i++) { + INPgetTok(&line,&(nname2[i]),1); + INPtermInsert(ckt,&(nname2[i]),tab,&(node2[i])); + } + INPgetTok(&line,&ground,1); + INPtermInsert(ckt,&ground,tab,&groundnode); + + INPgetTok(&line,&model,1); + if (strcmp(model, "len") == 0) { + lenval = INPevaluate(&line,&error1,1); + lenvalgiven = 1; + INPgetTok(&line,&model,1); + } + if(*model) { /* token isn't null */ + INPinsert(&model,tab); + thismodel = (INPmodel *)NULL; + current->error = INPgetMod(ckt,model,&thismodel,tab); + if(thismodel != NULL) { + if(mytype != thismodel->INPmodType) { + LITERR("incorrect model type") + return; + } + mdfast = thismodel->INPmodfast; + type = thismodel->INPmodType; + } else { + type = mytype; + if(!tab->defPmod) { + /* create default P model */ + IFnewUid(ckt,&uid,(IFuid)NULL,"P",UID_MODEL,(void**)NULL); + IFC(newModel, (ckt,type,&(tab->defPmod),uid)) + } + mdfast = tab->defPmod; + } + IFC(newInstance,(ckt,mdfast,&fast,name)) + } else { + LITERR("model name is not found") + return; + } + + /* IFC(bindNode,(ckt,fast,1,fakename)) */ + + ptemp.iValue = num; + GCA(INPpName,("dimension", &ptemp,ckt,type,fast)) + ptemp.v.vec.sVec = nname1; + GCA(INPpName,("pos_nodes", &ptemp,ckt,type,fast)) + ptemp.v.vec.sVec = nname2; + GCA(INPpName,("neg_nodes", &ptemp,ckt,type,fast)) + if (error1 == 0 && lenvalgiven) { + ptemp.rValue = lenval; + GCA(INPpName,("length",&ptemp,ckt,type,fast)) + } + + return; +} diff --git a/src/spicelib/parser/inp2q.c b/src/spicelib/parser/inp2q.c new file mode 100644 index 000000000..0d6423926 --- /dev/null +++ b/src/spicelib/parser/inp2q.c @@ -0,0 +1,96 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2Q(void *ckt, INPtables * tab, card * current, void *gnode) +{ + + /* Qname [] [] [OFF] + * [IC=,] */ + + int mytype; /* the type we looked up */ + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + char *nname3; /* the third node's name */ + char *nname4; /* the fourth node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + void *node3; /* the third node's node pointer */ + void *node4; /* the fourth node's node pointer */ + int error; /* error code temporary */ + void *fast; /* pointer to the actual instance */ + IFvalue ptemp; /* a value structure to package resistance into */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + char *model; /* the name of the model */ + INPmodel *thismodel; /* pointer to model description for user's model */ + void *mdfast; /* pointer to the actual model */ + IFuid uid; /* uid of default model */ + + mytype = INPtypelook("BJT"); + if (mytype < 0) { + LITERR("Device type BJT not supported by this binary\n"); + return; + } + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + INPgetTok(&line, &nname3, 1); + INPtermInsert(ckt, &nname3, tab, &node3); + INPgetTok(&line, &model, 1); + if (INPlookMod(model)) { + /* do nothing for now */ + node4 = gnode; + /* no action required */ + } else { + nname4 = model; + INPtermInsert(ckt, &nname4, tab, &node4); + INPgetTok(&line, &model, 1); + } + INPinsert(&model, tab); + current->error = INPgetMod(ckt, model, &thismodel, tab); + if (thismodel != NULL) { + if(thismodel->INPmodType != INPtypelook("BJT") && + thismodel->INPmodType != INPtypelook("BJT2")) { + LITERR("incorrect model type") + return; + } + type = (thismodel->INPmodType); + mdfast = (thismodel->INPmodfast); + } else { + type = mytype; + if (!tab->defQmod) { + /* create default Q model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "Q", UID_MODEL, + (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defQmod), uid)); + } + mdfast = tab->defQmod; + } + IFC(newInstance, (ckt, mdfast, &fast, name)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + IFC(bindNode, (ckt, fast, 3, node3)); + IFC(bindNode, (ckt, fast, 4, node4)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) { + ptemp.rValue = leadval; + GCA(INPpName, ("area", &ptemp, ckt, type, fast)); + } +} diff --git a/src/spicelib/parser/inp2r.c b/src/spicelib/parser/inp2r.c new file mode 100644 index 000000000..858392238 --- /dev/null +++ b/src/spicelib/parser/inp2r.c @@ -0,0 +1,118 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +Modified: Paolo Nenzi 2000 +Remarks: This code is based on a version written by Serban Popescu which + accepted an optional parameter ac. I have adapted his code + to conform to INP standard. (PN) +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2R(void *ckt, INPtables * tab, card * current) +{ +/* parse a resistor card */ +/* Rname [][][w=][l=][ac=] */ + + int mytype; /* the type we determine resistors are */ + int type = 0; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *saveline; /* ... just in case we need to go back... */ + char *name; /* the resistor's name */ + char *model; /* the name of the resistor's model */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + double val; /* temp to held resistance */ + int error; /* error code temporary */ + int error1; /* secondary error code temporary */ + INPmodel *thismodel; /* pointer to model structure describing our model */ + void *mdfast = NULL; /* pointer to the actual model */ + void *fast; /* pointer to the actual instance */ + IFvalue ptemp; /* a value structure to package resistance into */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + IFuid uid; /* uid for default model */ + + mytype = INPtypelook("Resistor"); + if (mytype < 0) { + LITERR("Device type Resistor not supported by this binary\n"); + return; + } + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + val = INPevaluate(&line, &error1, 1); + /* either not a number -> model, or + * follows a number, so must be a model name + * -> MUST be a model name (or null) + */ + + saveline = line; /* save then old pointer */ + + INPgetTok(&line, &model, 1); + + if (*model) { + /* token isn't null */ + if (INPlookMod(model)) { + /* If this is a valid model connect it */ + INPinsert(&model, tab); + thismodel = (INPmodel *) NULL; + current->error = INPgetMod(ckt, model, &thismodel, tab); + if (thismodel != NULL) { + if (mytype != thismodel->INPmodType) { + LITERR("incorrect model type"); + return; + } + mdfast = thismodel->INPmodfast; + type = thismodel->INPmodType; + } + } else { + /* It is not a model */ + line = saveline; /* go back */ + type = mytype; + if (!tab->defRmod) { /* create default R model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "R", UID_MODEL, + (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defRmod), uid)); + } + mdfast = tab->defRmod; + } + IFC(newInstance, (ckt, mdfast, &fast, name)); + } else { + /* The token is null and a default model will be created */ + type = mytype; + if (!tab->defRmod) { + /* create default R model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "R", UID_MODEL, + (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defRmod), uid)); + } + IFC(newInstance, (ckt, tab->defRmod, &fast, name)); + } + + if (error1 == 0) { /* got a resistance above */ + ptemp.rValue = val; + GCA(INPpName, ("resistance", &ptemp, ckt, type, fast)) + } + + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) { + ptemp.rValue = leadval; + GCA(INPpName, ("resistance", &ptemp, ckt, type, fast)); + } + return; +} diff --git a/src/spicelib/parser/inp2s.c b/src/spicelib/parser/inp2s.c new file mode 100644 index 000000000..9c50f5ef3 --- /dev/null +++ b/src/spicelib/parser/inp2s.c @@ -0,0 +1,86 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2S(void *ckt, INPtables * tab, card * current) +{ + + /* Sname [] [IC] */ + /* VOLTAGE CONTROLLED SWITCH */ + + int mytype; /* the type we determine resistors are */ + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *model; /* the name of the resistor's model */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + char *nname3; /* the third node's name */ + char *nname4; /* the fourth node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + void *node3; /* the third node's node pointer */ + void *node4; /* the fourth node's node pointer */ + int error; /* error code temporary */ + INPmodel *thismodel; /* pointer to model structure describing our model */ + void *mdfast; /* pointer to the actual model */ + void *fast; /* pointer to the actual instance */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + IFuid uid; /* uid of default model */ + + mytype = INPtypelook("Switch"); + if (mytype < 0) { + LITERR("Device type Switch not supported by this binary\n"); + return; + } + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + INPgetTok(&line, &nname3, 1); + INPtermInsert(ckt, &nname3, tab, &node3); + INPgetTok(&line, &nname4, 1); + INPtermInsert(ckt, &nname4, tab, &node4); + INPgetTok(&line, &model, 1); + INPinsert(&model, tab); + current->error = INPgetMod(ckt, model, &thismodel, tab); + if (thismodel != NULL) { + if (mytype != thismodel->INPmodType) { + LITERR("incorrect model type"); + return; + } + type = mytype; + mdfast = (thismodel->INPmodfast); + } else { + type = mytype; + if (!tab->defSmod) { + /* create deafult S model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "S", UID_MODEL, + (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defSmod), uid)); + } + mdfast = tab->defSmod; + } + IFC(newInstance, (ckt, mdfast, &fast, name)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + IFC(bindNode, (ckt, fast, 3, node3)); + IFC(bindNode, (ckt, fast, 4, node4)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) { + /* ignore a number */ + } +} diff --git a/src/spicelib/parser/inp2t.c b/src/spicelib/parser/inp2t.c new file mode 100644 index 000000000..1530306dd --- /dev/null +++ b/src/spicelib/parser/inp2t.c @@ -0,0 +1,65 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2T(void *ckt, INPtables * tab, card * current) +{ + + /* Tname [TD=] + * [F= [NL=]][IC=,,,] */ + + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + char *nname3; /* the third node's name */ + char *nname4; /* the fourth node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + void *node3; /* the third node's node pointer */ + void *node4; /* the fourth node's node pointer */ + int error; /* error code temporary */ + void *fast; /* pointer to the actual instance */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + IFuid uid; /* uid for default model */ + + + type = INPtypelook("Tranline"); + if (type < 0) { + LITERR("Device type Tranline not supported by this binary\n"); + return; + } + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + INPgetTok(&line, &nname3, 1); + INPtermInsert(ckt, &nname3, tab, &node3); + INPgetTok(&line, &nname4, 1); + INPtermInsert(ckt, &nname4, tab, &node4); + if (!tab->defTmod) { + /* create deafult T model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "T", UID_MODEL, (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defTmod), uid)); + } + IFC(newInstance, (ckt, tab->defTmod, &fast, name)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + IFC(bindNode, (ckt, fast, 3, node3)); + IFC(bindNode, (ckt, fast, 4, node4)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); +} diff --git a/src/spicelib/parser/inp2u.c b/src/spicelib/parser/inp2u.c new file mode 100644 index 000000000..6d03cfadf --- /dev/null +++ b/src/spicelib/parser/inp2u.c @@ -0,0 +1,77 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2U(void *ckt, INPtables * tab, card * current) +{ + + /* Uname [l=] [n=] */ + + int mytype; /* the type my lookup says URC is */ + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + char *nname3; /* the third node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + void *node3; /* the third node's node pointer */ + int error; /* error code temporary */ + void *fast; /* pointer to the actual instance */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + char *model; /* name of the model */ + INPmodel *thismodel; /* pointer to our model descriptor */ + void *mdfast; /* pointer to the actual model */ + IFuid uid; /* uid for default model */ + + mytype = INPtypelook("URC"); + if (mytype < 0) { + LITERR("Device type URC not supported by this binary\n"); + return; + } + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + INPgetTok(&line, &nname3, 1); + INPtermInsert(ckt, &nname3, tab, &node3); + INPgetTok(&line, &model, 1); + INPinsert(&model, tab); + current->error = INPgetMod(ckt, model, &thismodel, tab); + if (thismodel != NULL) { + if (mytype != thismodel->INPmodType) { + LITERR("incorrect model type"); + return; + } + type = mytype; + mdfast = (thismodel->INPmodfast); + } else { + type = mytype; + if (!tab->defUmod) { + /* create deafult U model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "U", UID_MODEL, + (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defUmod), uid)); + } + mdfast = tab->defUmod; + } + IFC(newInstance, (ckt, mdfast, &fast, name)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + IFC(bindNode, (ckt, fast, 3, node3)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); +} diff --git a/src/spicelib/parser/inp2v.c b/src/spicelib/parser/inp2v.c new file mode 100644 index 000000000..c8775cade --- /dev/null +++ b/src/spicelib/parser/inp2v.c @@ -0,0 +1,59 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2V(void *ckt, INPtables * tab, card * current) +{ + + /* Vname [ [DC] ] [AC [ [ ] ] ] + * [] */ + + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + int error; /* error code temporary */ + void *fast; /* pointer to the actual instance */ + IFvalue ptemp; /* a value structure to package resistance into */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + IFuid uid; /* uid for default model */ + + type = INPtypelook("Vsource"); + if (type < 0) { + LITERR("Device type Vsource not supported by this binary\n"); + return; + } + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + if (!tab->defVmod) { + /* create default V model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "V", UID_MODEL, (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defVmod), uid)); + } + IFC(newInstance, (ckt, tab->defVmod, &fast, name)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) { + ptemp.rValue = leadval; + GCA(INPpName, ("dc", &ptemp, ckt, type, fast)); + } +} diff --git a/src/spicelib/parser/inp2w.c b/src/spicelib/parser/inp2w.c new file mode 100644 index 000000000..39f9f9ba1 --- /dev/null +++ b/src/spicelib/parser/inp2w.c @@ -0,0 +1,83 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2W(void *ckt, INPtables * tab, card * current) +{ + + /* Wname [] [IC] */ + /* CURRENT CONTROLLED SWITCH */ + + int mytype; /* the type we determine resistors are */ + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *model; /* the name of the resistor's model */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + int error; /* error code temporary */ + INPmodel *thismodel; /* pointer to model structure describing our model */ + void *mdfast; /* pointer to the actual model */ + void *fast; /* pointer to the actual instance */ + IFvalue ptemp; /* a value structure to package resistance into */ + IFvalue *parm; /* pointer to a value structure for functions to return */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + IFuid uid; /* uid for default model */ + + mytype = INPtypelook("CSwitch"); + if (mytype < 0) { + LITERR("Device type CSwitch not supported by this binary\n"); + return; + } + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + parm = INPgetValue(ckt, &line, IF_INSTANCE, tab); + ptemp.uValue = parm->uValue; + + INPgetTok(&line, &model, 1); + INPinsert(&model, tab); + current->error = INPgetMod(ckt, model, &thismodel, tab); + if (thismodel != NULL) { + if (mytype != thismodel->INPmodType) { + LITERR("incorrect model type"); + return; + } + type = mytype; + mdfast = (thismodel->INPmodfast); + } else { + type = mytype; + if (!tab->defWmod) { + /* create deafult W model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "W", UID_MODEL, + (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defWmod), uid)); + } + mdfast = tab->defWmod; + } + IFC(newInstance, (ckt, mdfast, &fast, name)); + + GCA(INPpName, ("control", &ptemp, ckt, type, fast)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if (waslead) { + /* ignore a number */ + } +} diff --git a/src/spicelib/parser/inp2y.c b/src/spicelib/parser/inp2y.c new file mode 100644 index 000000000..84a547405 --- /dev/null +++ b/src/spicelib/parser/inp2y.c @@ -0,0 +1,236 @@ +/********** +Copyright 1992 Regents of the University of California. All rights +reserved. +Author: 1992 Charles Hough +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void +INP2Y(ckt,tab,current) + void *ckt; + INPtables *tab; + card *current; + +{ +/* parse a txl card */ +/* Yxxxx node1 node2 name */ + +int mytype; /* the type to determine txl */ +int mytype2; /* the type to determine cpl */ +int type; /* the type the model says it is */ +char *line; /* the part of the current line left to parse */ +char *name; /* the resistor's name */ +char *buf; /* temporary buffer for parsing */ +char *model; /* the name of the resistor's model */ +char *nname1; /* the first node's name */ +char *nname2; /* the second node's name */ +char rname1[10], rname2[10], rname3[10]; +char cname1[10], cname2[10], cname3[10], cname4[10]; +char *internal1, *internal2; +char *ground1, *ground2; +void *node1; /* the first node's node pointer */ +void *node2; /* the second node's node pointer */ +void *gnode1, *gnode2, *inode1, *inode2; +int error; /* error code temporary */ +int error1; /* secondary error code temporary */ +INPmodel *thismodel; /* pointer to model structure describing our model */ +void *mdfast; /* pointer to the actual model */ +void *fast; /* pointer to the actual instance */ +void *mdfast2, *mdfast3, *mdfast4, *mdfast5, *mdfast6; +void *fast2, *fast3, *fast4, *fast5, *fast6; +IFuid uid; /* uid for default model */ +GENinstance *txl; +IFvalue ptemp; /* a value structure to package into */ +double lval=0, rval=0, cval=0, lenval=0; +int lenvalgiven = 0; + + mytype = INPtypelook("TransLine"); + mytype2 = INPtypelook("CplLines"); + + if(mytype < 0 ) { + LITERR("Device type TransLine not supported by this binary\n") + return; + } + line = current->line; + INPgetTok(&line,&name,1); + INPinsert(&name,tab); + INPgetTok(&line,&nname1,1); + INPtermInsert(ckt,&nname1,tab,&node1); + INPgetTok(&line,&ground1,1); + INPtermInsert(ckt,&ground1,tab,&gnode1); + INPgetTok(&line,&nname2,1); + INPtermInsert(ckt,&nname2,tab,&node2); + INPgetTok(&line,&ground2,1); + INPtermInsert(ckt,&ground2,tab,&gnode2); + + INPgetTok(&line,&model,1); + if (strcmp(model, "len") == 0) { + lenval = INPevaluate(&line,&error1,1); + lenvalgiven = 1; + INPgetTok(&line,&model,1); + } + if(*model) { /* token isn't null */ + INPinsert(&model,tab); + thismodel = (INPmodel *)NULL; + current->error = INPgetMod(ckt,model,&thismodel,tab); + if(thismodel != NULL) { + if (thismodel->INPmodType == mytype2) { + INP2P(ckt,tab,current); + return; + } + else if (mytype != thismodel->INPmodType) { + LITERR("incorrect model type") + return; + } + line = thismodel->INPmodLine->line; + INPgetTok(&line,&buf,1); /* throw out .model */ + INPgetTok(&line,&buf,1); /* throw out model name */ + INPgetTok(&line,&buf,1); /* throw out txl */ + INPgetTok(&line,&buf,1); + while (*line != '\0') { + if (*buf == 'R' || *buf == 'r') { + INPgetTok(&line,&buf,1); + rval = atof(buf); + } + if ((strcmp(buf,"L") == 0) || (strcmp(buf,"l") == 0)) { + INPgetTok(&line,&buf,1); + lval = atof(buf); + } + if ((strcmp(buf,"C") == 0) || (strcmp(buf,"c") == 0)) { + INPgetTok(&line,&buf,1); + cval = atof(buf); + } + if (lenvalgiven == 0) { + if (strcmp(buf,"length")== 0) { + INPgetTok(&line,&buf,1); + lenval = atof(buf); + } + } + INPgetTok(&line,&buf,1); + } + if (lenval && rval && lval && rval/lval > 1.6e10) { + /* use 3-pi model */ + rval = 3.0 / (rval * lenval); + cval = cval * lenval / 6.0; + + type = INPtypelook("Resistor"); + + /* resistor between node1 and internal1 */ + internal1 = (char *) malloc (10); + strcpy(internal1, "txlnd1"); + INPtermInsert(ckt, &internal1, tab, &inode1); + if(!tab->defRmod) { + /* create default R model */ + IFnewUid(ckt,&uid,(IFuid)NULL,"R",UID_MODEL,(void**)NULL); + IFC(newModel, (ckt,type,&(tab->defRmod),uid)) + } + mdfast = tab->defRmod; + strcpy(rname1, "txlres1"); + IFC(newInstance,(ckt,mdfast,&fast,rname1)) + IFC(bindNode,(ckt,fast,1,node1)) + IFC(bindNode,(ckt,fast,2,inode1)) + ptemp.rValue = rval; + GCA(INPpName,("resistance",&ptemp,ckt,type,fast)) + + /* resistor between internal1 and internal2 */ + internal2 = (char *) malloc (10); + strcpy(internal2, "txlnd2"); + INPtermInsert(ckt, &internal2, tab, &inode2); + strcpy(rname2, "txlres2"); + mdfast2 = tab->defRmod; + IFC(newInstance,(ckt,mdfast2,&fast2,rname2)) + IFC(bindNode,(ckt,fast2,1,inode1)) + IFC(bindNode,(ckt,fast2,2,inode2)) + ptemp.rValue = rval; + GCA(INPpName,("resistance",&ptemp,ckt,type,fast2)) + + /* resistor between internal2 and node2 */ + strcpy(rname3, "txlres3"); + mdfast3 = tab->defRmod; + IFC(newInstance,(ckt,mdfast3,&fast3,rname3)) + IFC(bindNode,(ckt,fast3,1,inode2)) + IFC(bindNode,(ckt,fast3,2,node2)) + ptemp.rValue = rval; + GCA(INPpName,("resistance",&ptemp,ckt,type,fast3)) + + /* capacitor on node1 */ + type = INPtypelook("Capacitor"); + if(!tab->defCmod) { + IFnewUid(ckt,&uid,(IFuid)NULL,"C",UID_MODEL,(void**)NULL); + IFC(newModel,(ckt,type,&(tab->defCmod),uid)) + } + mdfast4 = tab->defCmod; + strcpy(cname1, "txlcap1"); + IFC(newInstance,(ckt,mdfast4,&fast4,cname1)) + IFC(bindNode,(ckt,fast4,1,node1)) + IFC(bindNode,(ckt,fast4,2,gnode1)) + ptemp.rValue = cval; + GCA(INPpName,("capacitance",&ptemp,ckt,type,fast4)) + + /* capacitor on internal1 */ + strcpy(cname2, "txlcap2"); + mdfast4 = tab->defCmod; + IFC(newInstance,(ckt,mdfast4,&fast4,cname2)) + IFC(bindNode,(ckt,fast4,1,inode1)) + IFC(bindNode,(ckt,fast4,2,gnode1)) + ptemp.rValue = cval * 2; + GCA(INPpName,("capacitance",&ptemp,ckt,type,fast4)) + + /* capacitor on internal2 */ + strcpy(cname3, "txlcap3"); + mdfast5 = tab->defCmod; + IFC(newInstance,(ckt,mdfast5,&fast5,cname3)) + IFC(bindNode,(ckt,fast5,1,inode2)) + IFC(bindNode,(ckt,fast5,2,gnode1)) + ptemp.rValue = cval * 2; + GCA(INPpName,("capacitance",&ptemp,ckt,type,fast5)) + + /* capacitor on node2 */ + strcpy(cname4, "txlcap4"); + mdfast6 = tab->defCmod; + IFC(newInstance,(ckt,mdfast6,&fast6,cname4)) + IFC(bindNode,(ckt,fast6,1,node2)) + IFC(bindNode,(ckt,fast6,2,gnode1)) + ptemp.rValue = cval; + GCA(INPpName,("capacitance",&ptemp,ckt,type,fast6)) + return; + + } + + /* use regular txl model */ + mdfast = thismodel->INPmodfast; + type = thismodel->INPmodType; + } else { + type = mytype; + if(!tab->defYmod) { + /* create default Y model */ + IFnewUid(ckt,&uid,(IFuid)NULL,"Y",UID_MODEL,(void**)NULL); + IFC(newModel, (ckt,type,&(tab->defYmod),uid)) + } + mdfast = tab->defYmod; + } + IFC(newInstance,(ckt,mdfast,&fast,name)) + } else { + LITERR("model name is not found") + return; + } + + if (error1 == 0 && lenvalgiven) { + ptemp.rValue = lenval; + GCA(INPpName,("length",&ptemp,ckt,type,fast)) + } + + IFC(bindNode,(ckt,fast,1,node1)) + IFC(bindNode,(ckt,fast,2,node2)) + + txl = (GENinstance *)fast; + + return; +} diff --git a/src/spicelib/parser/inp2z.c b/src/spicelib/parser/inp2z.c new file mode 100644 index 000000000..1656b7374 --- /dev/null +++ b/src/spicelib/parser/inp2z.c @@ -0,0 +1,97 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Thomas L. Quarles +**********/ + +/* Added code from macspice3f4 HFET1&2 and MESA model + Original note: + Added device calls for Mesfet models and HFET models + provided by Trond Ytterdal as of Nov 98 +*/ + + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpmacs.h" +#include "fteext.h" +#include "inp.h" + +void INP2Z(void *ckt, INPtables * tab, card * current) +{ + + /* Zname [] [OFF] [IC=,] */ + + int type; /* the type the model says it is */ + char *line; /* the part of the current line left to parse */ + char *name; /* the resistor's name */ + char *nname1; /* the first node's name */ + char *nname2; /* the second node's name */ + char *nname3; /* the third node's name */ + void *node1; /* the first node's node pointer */ + void *node2; /* the second node's node pointer */ + void *node3; /* the third node's node pointer */ + int error; /* error code temporary */ + void *fast; /* pointer to the actual instance */ + IFvalue ptemp; /* a value structure to package resistance into */ + int waslead; /* flag to indicate that funny unlabeled number was found */ + double leadval; /* actual value of unlabeled number */ + char *model; /* the name of the model */ + INPmodel *thismodel; /* pointer to model description for user's model */ + void *mdfast; /* pointer to the actual model */ + IFuid uid; /* uid for default model */ + + + line = current->line; + INPgetTok(&line, &name, 1); + INPinsert(&name, tab); + INPgetTok(&line, &nname1, 1); + INPtermInsert(ckt, &nname1, tab, &node1); + INPgetTok(&line, &nname2, 1); + INPtermInsert(ckt, &nname2, tab, &node2); + INPgetTok(&line, &nname3, 1); + INPtermInsert(ckt, &nname3, tab, &node3); + INPgetTok(&line, &model, 1); + INPinsert(&model, tab); + thismodel = (INPmodel *) NULL; + current->error = INPgetMod(ckt, model, &thismodel, tab); + if (thismodel != NULL) { + if ( thismodel->INPmodType != INPtypelook("MES") + && thismodel->INPmodType != INPtypelook("MESA") + && thismodel->INPmodType != INPtypelook("HFET1") + && thismodel->INPmodType != INPtypelook("HFET2")) + { + LITERR("incorrect model type") + return; + } + + + type = thismodel->INPmodType; + mdfast = (thismodel->INPmodfast); + } else { + + type = INPtypelook("MES"); + if (type < 0 ) { + LITERR("Device type MES not supported by this binary\n"); + return; + } + + if (!tab->defZmod) { + /* create default Z model */ + IFnewUid(ckt, &uid, (IFuid) NULL, "Z", UID_MODEL, + (void **) NULL); + IFC(newModel, (ckt, type, &(tab->defZmod), uid)); + } + mdfast = tab->defZmod; + } + IFC(newInstance, (ckt, mdfast, &fast, name)); + IFC(bindNode, (ckt, fast, 1, node1)); + IFC(bindNode, (ckt, fast, 2, node2)); + IFC(bindNode, (ckt, fast, 3, node3)); + PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab)); + if ( (waslead) && ( thismodel->INPmodType != INPtypelook("MES") ) ) { + ptemp.rValue = leadval; + GCA(INPpName, ("area", &ptemp, ckt, type, fast)); + } +} diff --git a/src/spicelib/parser/inpaname.c b/src/spicelib/parser/inpaname.c new file mode 100644 index 000000000..21db422d7 --- /dev/null +++ b/src/spicelib/parser/inpaname.c @@ -0,0 +1,72 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* + * INPaName() + * + * Take a parameter by Name and ask for the specified value + * *dev is -1 if type unknown, otherwise, device type + * **fast is a device, and will be set if possible. + */ + +#include "ngspice.h" +#include +#include "cpdefs.h" +#include "fteext.h" +#include "ifsim.h" +#include "iferrmsg.h" +#include "inp.h" + +int +INPaName(char *parm, IFvalue * val, void *ckt, int *dev, char *devnam, + void **fast, IFsimulator * sim, int *dataType, IFvalue * selector) + /* the name of the parameter to set */ + /* the parameter union containing the value to set */ + /* the circuit this device is a member of */ + /* the device type code to the device being parsed */ + /* the name of the device */ + /* direct pointer to device being parsed */ + /* the simulator data structure */ + /* the datatype of the returned value structure */ + /* data sub-selector for questions */ +{ + int error; /* int to store evaluate error return codes in */ + int i; + + /* find the instance - don't know about model, so use null there, + * otherwise pass on as much info as we have about the device + * (name, type, direct pointer) - the type and direct pointer + * WILL be set on return unless error is not OK + */ + error = (*(sim->findInstance)) (ckt, dev, fast, devnam, (void *) NULL, + (char *) NULL); + if (error) + return (error); + + /* now find the parameter - hunt through the parameter tables for + * this device type and look for a name match of an 'ask'able + * parameter. + */ + for (i = 0; i < (*(*(sim->devices)[*dev]).numInstanceParms); i++) { + if (strcmp(parm, + ((*(sim->devices)[*dev]).instanceParms[i].keyword)) == 0 + && (((*(sim->devices)[*dev]).instanceParms[i].dataType) & + IF_ASK)) { + /* found it, so we ask the question using the device info we got + * above and put the results in the IFvalue structure our caller + * gave us originally + */ + error = (*(sim->askInstanceQuest)) (ckt, *fast, + (*(sim->devices)[*dev]). + instanceParms[i].id, val, + selector); + if (dataType) + *dataType = + (*(sim->devices)[*dev]).instanceParms[i].dataType; + return (error); + } + } + return (E_BADPARM); +} diff --git a/src/spicelib/parser/inpapnam.c b/src/spicelib/parser/inpapnam.c new file mode 100644 index 000000000..7789d7b96 --- /dev/null +++ b/src/spicelib/parser/inpapnam.c @@ -0,0 +1,34 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "cpdefs.h" +#include "fteext.h" +#include "inp.h" + +int +INPapName(void *ckt, int type, void *analPtr, char *parmname, + IFvalue * value) +{ + int i; + + if (parmname && ft_sim->analyses[type]) { + for (i = 0; i < ft_sim->analyses[type]->numParms; i++) + if (strcmp(parmname, + ft_sim->analyses[type]->analysisParms[i].keyword) == + 0) { + return (*(ft_sim->setAnalysisParm)) (ckt, analPtr, + ft_sim-> + analyses[type]-> + analysisParms[i].id, + value, + (IFvalue *) NULL); + } + } + return (E_BADPARM); +} diff --git a/src/spicelib/parser/inpcfix.c b/src/spicelib/parser/inpcfix.c new file mode 100644 index 000000000..d83f56582 --- /dev/null +++ b/src/spicelib/parser/inpcfix.c @@ -0,0 +1,24 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "fteext.h" +#include "inpdefs.h" +#include "inp.h" + + +void INPcaseFix(register char *string) +{ + + while (*string) { + if (isupper(*string)) { + *string = tolower(*string); + } + string++; + } +} diff --git a/src/spicelib/parser/inpdomod.c b/src/spicelib/parser/inpdomod.c new file mode 100644 index 000000000..319a35713 --- /dev/null +++ b/src/spicelib/parser/inpdomod.c @@ -0,0 +1,440 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "iferrmsg.h" +#include "inpdefs.h" +#include "inp.h" + + +char *INPdomodel(void *ckt, card * image, INPtables * tab) +{ + + char *modname; + int type = -1; + int lev; + char *typename; + char *err = (char *) NULL; + char *line; + + line = image->line; + INPgetTok(&line, &modname, 1); /* throw away '.model' */ + INPgetTok(&line, &modname, 1); + INPinsert(&modname, tab); + INPgetTok(&line, &typename, 1); + if ((strcmp(typename, "npn") == 0) || (strcmp(typename, "pnp") == 0)) { + err = INPfindLev(line,&lev); + switch(lev) { + case 0: + case 1: + type = INPtypelook("BJT"); + if (type < 0) { + err = INPmkTemp( + "Device type BJT not available in this binary\n"); + } + break; + case 2: + type = INPtypelook("BJT2"); + if(type < 0) { + err = INPmkTemp( + "Device type BJT2 not available in this binary\n"); + } + break; + default: /* placeholder; use level 3 for the next model */ + err = INPmkTemp( + "Only BJT levels 1 and 2 are supported in this binary\n"); + break; + + } + INPmakeMod(modname, type, image); + } else if (strcmp(typename, "d") == 0) { + type = INPtypelook("Diode"); + if (type < 0) { + err = + INPmkTemp + ("Device type Diode not available in this binary\n"); + } + INPmakeMod(modname, type, image); + } else if ((strcmp(typename, "njf") == 0) + || (strcmp(typename, "pjf") == 0)) { + err = INPfindLev(line, &lev); + switch (lev) { + case 0: + case 1: + type = INPtypelook("JFET"); + if (type < 0) { + err = + INPmkTemp + ("Device type JFET not available in this binary\n"); + } + break; + case 2: + type = INPtypelook("JFET2"); + if (type < 0) { + err = + INPmkTemp + ("Device type JFET2 not available in this binary\n"); + } + break; + default: /* placeholder; use level 3 for the next model */ + err = + INPmkTemp + ("Only JFET device levels 1-2 are supported in this binary\n"); + break; + } + INPmakeMod(modname, type, image); + } else if ((strcmp(typename, "nmf") == 0) + || (strcmp(typename, "pmf") == 0) + || (strcmp(typename, "nhfet") == 0) + || (strcmp(typename, "phfet") == 0)) { + err = INPfindLev( line, &lev ); + switch ( lev ) + { + case 0: + case 1: + type = INPtypelook("MES"); + if (type < 0) + { + err = INPmkTemp("Device type MES not available\n"); + } + break; + case 2: + type = INPtypelook("MESA"); + if (type < 0) + { + err = INPmkTemp("Device type MES2 not availabe\n"); + } + break; + case 3: + type = INPtypelook("MESA"); + if (type < 0) + { + err = INPmkTemp("Device type MES2 not availabe\n"); + } + break; + case 4: + type = INPtypelook("MESA"); + if ( type < 0) + { + err = INPmkTemp(" Device type MESA not available\n"); + } + break; + case 5: + type = INPtypelook("HFET1"); + if ( type < 0) + { + err = INPmkTemp(" Device type HFET1 not available\n"); + } + break; + case 6: + type = INPtypelook("HFET2"); + if ( type < 0) + { + err = INPmkTemp(" Device type HFET2 not available in this binary\n"); + } + break; + + default: + err = INPmkTemp("only mesfet device level 1 and hfet level 5-6 supported\n"); + break; + } + INPmakeMod(modname, type, image); + } else if (strcmp(typename, "urc") == 0) { + type = INPtypelook("URC"); + if (type < 0) { + err = + INPmkTemp + ("Device type URC not available in this binary\n"); + } + INPmakeMod(modname, type, image); + } else if ((strcmp(typename, "nmos") == 0) + || (strcmp(typename, "pmos") == 0) + || (strcmp(typename, "nsoi") == 0) + || (strcmp(typename, "psoi") == 0)) { + err = INPfindLev(line, &lev); + switch (lev) { + case 0: + case 1: + type = INPtypelook("Mos1"); + if (type < 0) { + err = + INPmkTemp + ("Device type MOS1 not available in this binary\n"); + } + break; + case 2: + type = INPtypelook("Mos2"); + if (type < 0) { + err = + INPmkTemp + ("Device type MOS2 not available in this binary\n"); + } + break; + case 3: + type = INPtypelook("Mos3"); + if (type < 0) { + err = + INPmkTemp + ("Device type MOS3 not available in this binary\n"); + } + break; + case 4: + type = INPtypelook("BSIM1"); + if (type < 0) { + err = + INPmkTemp + ("Device type BSIM1 not available in this binary\n"); + } + break; + case 5: + type = INPtypelook("BSIM2"); + if (type < 0) { + err = + INPmkTemp + ("Device type BSIM2 not available in this binary\n"); + } + break; + case 6: + type = INPtypelook("Mos6"); + if (type < 0) { + err = + INPmkTemp + ("Device type MOS6 not available in this binary\n"); + } + break; + case 7: + type = INPtypelook("MOS7"); + if (type < 0) { + err = + INPmkTemp + ("Device type MOS7 not available in this binary\n"); + } + break; + case 8: + type = INPtypelook("BSIM3"); + if (type < 0) { + err = + INPmkTemp + ("Device type BSIM3 not available in this binary\n"); + } + break; + + case 9: + type = INPtypelook("Mos9"); + if(type < 0) { + err = INPmkTemp( + "Device type MOS9 not available in this binary\n"); + } + break; + case 10: + type = INPtypelook("B3SOIPD"); + if (type < 0) { + err = + INPmkTemp + ("Device type B3SOIPD not available in this binary\n"); + } + break; + case 11: + type = INPtypelook("B3SOIFD"); + if (type < 0) { + err = + INPmkTemp + ("Device type B3SOIFD not available in this binary\n"); + } + break; + case 12: + type = INPtypelook("B3SOIDD"); + if (type < 0) { + err = + INPmkTemp + ("Device type B3SOIDD not available in this binary\n"); + } + break; + case 14: + type = INPtypelook("BSIM4"); + if (type < 0) { + err = + INPmkTemp + ("Device type BSIM4 not available in this binary\n");} + break; + case 15: + type = INPtypelook("BSIM5"); + if (type < 0) { + err = + INPmkTemp + ("Placeholder: Device type BSIM5 not available in this binary\n"); + } + break; + case 16: + type = INPtypelook("BSIM6"); + if (type < 0) { + err = + INPmkTemp + ("Placeholder: Device type BSIM6 not available in this binary\n"); + } + break; + case 44: + type = INPtypelook("EKV"); + if (type < 0) { + err = + INPmkTemp + ("Placeholder for EKV model: look at http://legwww.epfl.ch for info on EKV\n"); + } + break; + case 49: + type = INPtypelook("BSIM3V1"); + if (type < 0) { + err = + INPmkTemp + ("Device type BSIM3V1 not available in this binary\n"); + } + break; + case 50: + type = INPtypelook("BSIM3V2"); + if (type < 0) { + err = + INPmkTemp + ("Device type BSIM3V2 not available in this binary\n"); + } + break; + case 60: + type = INPtypelook("SOI"); + if (type < 0) { + err = + INPmkTemp + ("Device type SOI not available in this binary (internal STAG release)\n"); + } + break; + case 61: + type = INPtypelook("SOI2"); + if (type < 0) { + err = + INPmkTemp + ("Device type SOI2 not available in this binary (internal STAG release)\n"); + } + break; + + case 62: + type = INPtypelook("SOI3"); + if (type < 0) { + err = + INPmkTemp + ("Device type SOI3 not available in this binary (internal STAG release)\n"); + } + break; + default: /* placeholder; use level xxx for the next model */ + err = + INPmkTemp + ("Only MOS device levels 1-6,8,14,44,49-50,62 are supported in this binary\n"); + break; + } + INPmakeMod(modname, type, image); + } else if (strcmp(typename, "r") == 0) { + type = INPtypelook("Resistor"); + if (type < 0) { + err = + INPmkTemp + ("Device type Resistor not available in this binary\n"); + } + INPmakeMod(modname, type, image); + } else if(strcmp(typename,"txl") == 0) { + char *val; + double rval=0, lval=0; + INPgetTok(&line,&val,1); + while (*line != '\0') { + if (*val == 'R' || *val == 'r') { + INPgetTok(&line,&val,1); + rval = atof(val); + } + if ((strcmp(val,"L") == 0) || (strcmp(val,"l") == 0)) { + INPgetTok(&line,&val,1); + lval = atof(val); + } + INPgetTok(&line,&val,1); + } + if(lval) + rval = rval/lval; + if (rval > 1.6e10) { + type = INPtypelook("TransLine"); + INPmakeMod(modname,type,image); + } + if (rval > 1.6e9) { + type = INPtypelook("CplLines"); + INPmakeMod(modname,type,image); + } + else { + type = INPtypelook("TransLine"); + INPmakeMod(modname,type,image); + } + if(type < 0) { + err = INPmkTemp( + "Device type TransLine not available in this binary\n"); + } + + } else if(strcmp(typename,"cpl") == 0) { + type = INPtypelook("CplLines"); + if(type < 0) { + err = INPmkTemp( + "Device type CplLines not available in this binary\n"); + } + INPmakeMod(modname,type,image); + } else if (strcmp(typename, "c") == 0) { + type = INPtypelook("Capacitor"); + if (type < 0) { + err = + INPmkTemp + ("Device type Capacitor not available in this binary\n"); + } + INPmakeMod(modname, type, image); + } else if (strcmp(typename, "sw") == 0) { + type = INPtypelook("Switch"); + if (type < 0) { + err = + INPmkTemp + ("Device type Switch not available in this binary\n"); + } + INPmakeMod(modname, type, image); + } else if (strcmp(typename, "csw") == 0) { + type = INPtypelook("CSwitch"); + if (type < 0) { + err = + INPmkTemp + ("Device type CSwitch not available in this binary\n"); + } + INPmakeMod(modname, type, image); + } else if (strcmp(typename, "ltra") == 0) { + type = INPtypelook("LTRA"); + if (type < 0) { + err = + INPmkTemp + ("Device type LTRA not available in this binary\n"); + } + INPmakeMod(modname, type, image); + } else { +#ifndef XSPICE + type = -1; + err = (char *) MALLOC(35 + strlen(typename)); + (void) sprintf(err, "unknown model type %s - ignored\n", typename); +#else + /* gtri - modify - wbk - 10/23/90 - modify to look for code models */ + + /* add new code */ + + /* look for this model type and put it in the table of models */ + type = INPtypelook(typename); + if(type < 0) { + err = (char *) MALLOC(35 + strlen(typename)); + sprintf(err,"Unknown model type %s - ignored\n",typename); + } + else + INPmakeMod(modname,type,image); + + /* gtri - end - wbk - 10/23/90 */ +#endif + + } + return (err); +} diff --git a/src/spicelib/parser/inpdoopt.c b/src/spicelib/parser/inpdoopt.c new file mode 100644 index 000000000..774e5ecdb --- /dev/null +++ b/src/spicelib/parser/inpdoopt.c @@ -0,0 +1,88 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes +**********/ + + /* INPdoOpts(ckt,option card) + * parse the options off of the given option card and add them to + * the given circuit + */ + +#include "ngspice.h" +#include +#include "inpdefs.h" +#include "ifsim.h" +#include "cpdefs.h" +#include "fteext.h" + + +void +INPdoOpts(ckt,anal,optCard,tab) + void *ckt; + void *anal; + card *optCard; + INPtables *tab; +{ + char *line; + char *token; + char *errmsg; + IFvalue *val; + int error; + int i; + int which; + IFanalysis *prm = NULL; + + which = -1; + i=0; + for(i=0;inumAnalyses;i++) { + prm = ft_sim->analyses[i]; + if(strcmp(prm->name,"options")==0) { + which = i; + break; + } + i++; + } + if(which == -1) { + optCard->error = INPerrCat(optCard->error,INPmkTemp( + "error: analysis options table not found\n")); + return; + } + line = optCard->line; + INPgetTok(&line,&token,1); /* throw away '.option' */ + while (*line) { + INPgetTok(&line,&token,1); + for(i=0;inumParms;i++) { + if(strcmp(token,prm->analysisParms[i].keyword) == 0) { + if(!(prm->analysisParms[i].dataType & IF_UNIMP_MASK)) { + errmsg = (char *)MALLOC((45+strlen(token)) * sizeof(char)); + (void) sprintf(errmsg, + " Warning: %s not yet implemented - ignored \n",token); + optCard->error = INPerrCat(optCard->error,errmsg); + val = INPgetValue(ckt,&line, + prm->analysisParms[i].dataType, tab); + break; + } + if(prm->analysisParms[i].dataType & IF_SET) { + val = INPgetValue(ckt,&line, + prm->analysisParms[i].dataType&IF_VARTYPES, tab); + error = (*(ft_sim->setAnalysisParm))(ckt,anal, + prm->analysisParms[i].id,val,(IFvalue*)NULL); + if(error) { + errmsg =(char *)MALLOC((35+strlen(token))*sizeof(char)); + (void) sprintf(errmsg, + "Warning: can't set option %s\n", token); + optCard->error = INPerrCat(optCard->error, errmsg); + } + break; + } + } + } + if(i == prm->numParms) { + errmsg = (char *)MALLOC(100 * sizeof(char)); + (void) strcpy(errmsg," Error: unknown option - ignored\n"); + optCard->error = INPerrCat(optCard->error,errmsg); + fprintf(stderr, "%s\n", optCard->error); + } + } +} diff --git a/src/spicelib/parser/inpdpar.c b/src/spicelib/parser/inpdpar.c new file mode 100644 index 000000000..1b6d0cf35 --- /dev/null +++ b/src/spicelib/parser/inpdpar.c @@ -0,0 +1,80 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* + * INPdevParse() + * + * parse a given input according to the standard rules - look + * for the parameters given in the parmlists, In addition, + * an optional leading numeric parameter is handled. + */ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "iferrmsg.h" +#include "cpdefs.h" +#include "fteext.h" +#include "inp.h" + +char *INPdevParse(char **line, void *ckt, int dev, void *fast, + double *leading, int *waslead, INPtables * tab) + /* the line to parse */ + /* the circuit this device is a member of */ + /* the device type code to the device being parsed */ + /* direct pointer to device being parsed */ + /* the optional leading numeric parameter */ + /* flag - 1 if leading double given, 0 otherwise */ +{ + int error; /* int to store evaluate error return codes in */ + char *parm; + char *errbuf; + int i; + IFvalue *val; + + /* check for leading value */ + *waslead = 0; + *leading = INPevaluate(line, &error, 1); + if (error == 0) { /* found a good leading number */ + *waslead = 1; + } else + *leading = 0.0; + while (**line != (char) 0) { + error = INPgetTok(line, &parm, 1); + if (!*parm) + continue; + if (error) + return (INPerror(error)); + for (i = 0; i < (*(*(ft_sim->devices)[dev]).numInstanceParms); i++) { + if (strcmp(parm, + ((*(ft_sim->devices)[dev]).instanceParms[i]. + keyword)) == 0) { + val = + INPgetValue(ckt, line, + ((*(ft_sim->devices)[dev]). + instanceParms[i].dataType), tab); + if (!val) + return (INPerror(E_PARMVAL)); + error = (*(ft_sim->setInstanceParm)) (ckt, fast, + (*(ft_sim->devices) + [dev]). + instanceParms[i].id, + val, + (IFvalue *) NULL); + if (error) + return (INPerror(error)); + break; + } + } + if (i == (*(*(ft_sim->devices)[dev]).numInstanceParms)) { + errbuf = MALLOC(strlen(parm) + 25); + (void) sprintf(errbuf, " unknown parameter (%s) \n", parm); + return (errbuf); + } + FREE(parm); + } + return ((char *) NULL); +} diff --git a/src/spicelib/parser/inperrc.c b/src/spicelib/parser/inperrc.c new file mode 100644 index 000000000..e2459d45a --- /dev/null +++ b/src/spicelib/parser/inperrc.c @@ -0,0 +1,35 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "inpdefs.h" +#include "inp.h" + + +char *INPerrCat(char *a, char *b) +{ + + if (a != (char *) NULL) { + if (b == (char *) NULL) { /* a valid, b null, return a */ + return (a); + } else { /* both valid - hard work... */ + register char *errtmp; + errtmp = + (char *) MALLOC((strlen(a) + strlen(b) + 2) * + sizeof(char)); + (void) strcpy(errtmp, a); + (void) strcat(errtmp, "\n"); + (void) strcat(errtmp, b); + FREE(a); + FREE(b); + return (errtmp); + } + } else { /* a null, so return b */ + return (b); + } +} diff --git a/src/spicelib/parser/inperror.c b/src/spicelib/parser/inperror.c new file mode 100644 index 000000000..d1892c4dd --- /dev/null +++ b/src/spicelib/parser/inperror.c @@ -0,0 +1,59 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +/* + * provide the error message appropriate for the given error code + */ + +#include "ngspice.h" +#include +#ifdef HAVE_STRING_H +#include +#endif +#include "fteext.h" +#include "ifsim.h" +#include "iferrmsg.h" +#include "sperror.h" +#include "inp.h" + +char *INPerror(int type) +{ + const char *val; + char *ebuf; + +/*CDHW Lots of things set errMsg but it is never used so let's hack it in CDHW*/ + if ( errMsg ) { + val = errMsg; errMsg=NULL; } + else +/*CDHW end of hack CDHW*/ + val = SPerror(type); + + if (!val) + return NULL; + +#ifdef HAVE_ASPRINTF + if (errRtn) + asprintf(&ebuf, "%s detected in routine \"%s\"\n", val, errRtn); + else + asprintf(&ebuf, "%s\n", val); +#else /* ~ HAVE_ASPRINTF */ + if (errRtn){ + if ( (ebuf = (char *) malloc(strlen(val) + + strlen(errRtn) + 25)) == NULL){ + fprintf(stderr,"malloc failed\n"); + exit(1); + } + sprintf(ebuf, "%s detected in routine \"%s\"\n", val, errRtn); + } + else{ + if ( (ebuf = (char *) malloc(strlen(val) + 2)) == NULL){ + fprintf(stderr,"malloc failed\n"); + exit(1); + } + sprintf(ebuf, "%s\n", val); + } +#endif /* HAVE_ASPRINTF */ + return ebuf; +} diff --git a/src/spicelib/parser/inpeval.c b/src/spicelib/parser/inpeval.c new file mode 100644 index 000000000..029487830 --- /dev/null +++ b/src/spicelib/parser/inpeval.c @@ -0,0 +1,207 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include +#include "inpdefs.h" +#include "inp.h" + +double INPevaluate(char **line, int *error, int gobble) + /* non-zero to gobble rest of token, zero to leave it alone */ +{ + char *token; + char *here; + double mantis; + int expo1; + int expo2; + int sign; + int expsgn; + char *tmpline; + + /* setup */ + tmpline = *line; + if (gobble) { + /* MW. INPgetUTok should be called with gobble=0 or it make + * errors in v(1,2) exp */ + *error = INPgetUTok(line, &token, 0); + if (*error) + return ((double) 0.0); + } else { + token = *line; + *error = 0; + } + mantis = 0; + expo1 = 0; + expo2 = 0; + sign = 1; + expsgn = 1; + /* loop through all of the input token */ + here = token; + if (*here == '+') + here++; /* plus, so do nothing except skip it */ + if (*here == '-') { /* minus, so skip it, and change sign */ + here++; + sign = -1; + } + if ((*here == 0) || ((!(isdigit(*here))) && (*here != '.'))) { + /* number looks like just a sign! */ + *error = 1; + /* back out the 'gettok' operation */ + *line = tmpline; + if (gobble) { + FREE(token); + } else { + *line = here; + } + return (0); + } + while (isdigit(*here)) { + /* digit, so accumulate it. */ + mantis = 10 * mantis + *here - '0'; + here++; + } + if (*here == 0) { + /* reached the end of token - done. */ + if (gobble) { + FREE(token); + } else { + *line = here; + } + return ((double) mantis * sign); + } + if (*here == ':') { + /* hack for subcircuit node numbering */ + *error = 1; + *line = tmpline; + return 0.0; + } + /* after decimal point! */ + if (*here == '.') { + /* found a decimal point! */ + here++; /* skip to next character */ + if (*here == 0) { + /* number ends in the decimal point */ + if (gobble) { + FREE(token); + } else { + *line = here; + } + return ((double) mantis * sign); + } + while (isdigit(*here)) { + /* digit, so accumulate it. */ + mantis = 10 * mantis + *here - '0'; + expo1 = expo1 - 1; + if (*here == 0) { + /* reached the end of token - done. */ + if (gobble) { + FREE(token); + } else { + *line = here; + } + return (mantis * sign * pow(10., (double) expo1)); + } + here++; + } + } + /* now look for "E","e",etc to indicate an exponent */ + if ((*here == 'E') || (*here == 'e') || (*here == 'D') + || (*here == 'd')) { + /* have an exponent, so skip the e */ + here++; + /* now look for exponent sign */ + if (*here == '+') + here++; /* just skip + */ + if (*here == '-') { + here++; /* skip over minus sign */ + expsgn = -1; /* and make a negative exponent */ + /* now look for the digits of the exponent */ + } + while (isdigit(*here)) { + expo2 = 10 * expo2 + *here - '0'; + here++; + } + } + /* now we have all of the numeric part of the number, time to + * look for the scale factor (alphabetic) + */ + switch (*here) { + case 't': + case 'T': + expo1 = expo1 + 12; + break; + case 'g': + case 'G': + expo1 = expo1 + 9; + break; + case 'k': + case 'K': + expo1 = expo1 + 3; + break; + case 'u': + case 'U': + expo1 = expo1 - 6; + break; + case 'n': + case 'N': + expo1 = expo1 - 9; + break; + case 'p': + case 'P': + expo1 = expo1 - 12; + break; + case 'f': + case 'F': + expo1 = expo1 - 15; + break; + case 'm': + case 'M': + { + /* special case for m - may be m or mil or meg */ + if (*(here + 1) != 0 && *(here + 2) != 0) { + /* at least 2 characters, so check them. */ + if ((*(here + 1) == 'E') || (*(here + 1) == 'e')) { + if ((*(here + 2) == 'G') || (*(here + 2) == 'g')) { + expo1 = expo1 + 6; + if (gobble) { + FREE(token); + } else { + *line = here; + } + return (sign * mantis * + pow((double) 10, + (double) (expo1 + expsgn * expo2))); + } + } else if ((*(here + 1) == 'I') || (*(here + 1) == 'i')) { + if ((*(here + 2) == 'L') || (*(here + 2) == 'l')) { + expo1 = expo1 - 6; + mantis = mantis * 25.4; + if (gobble) { + FREE(token); + } else { + *line = here; + } + return (sign * mantis * + pow((double) 10, + (double) (expo1 + expsgn * expo2))); + } + } + } + /* not either special case, so just m => 1e-3 */ + expo1 = expo1 - 3; + } + break; + default: + break; + } + if (gobble) { + FREE(token); + } else { + *line = here; + } + return (sign * mantis * + pow((double) 10, (double) (expo1 + expsgn * expo2))); +} diff --git a/src/spicelib/parser/inpfindl.c b/src/spicelib/parser/inpfindl.c new file mode 100644 index 000000000..52aed3be5 --- /dev/null +++ b/src/spicelib/parser/inpfindl.c @@ -0,0 +1,68 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: 1999 Paolo Nenzi - Now we can use a two digits level code - +**********/ + + /* INPfindLev(line,level) + * find the 'level' parameter on the given line and return its + * value (1,2,..,99 for now, 1 default) + * + */ + +#include "ngspice.h" +#include +#include +#include "inpdefs.h" +#include "inp.h" + +char *INPfindLev(char *line, int *level) +{ + char *where; + + where = line; + + where = strstr(line, "level"); + + if (where != NULL) { /* found a level keyword on the line */ + + where += 5; /* skip the level keyword */ + while ((*where == ' ') || (*where == '\t') || (*where == '=') || + (*where == ',') || (*where == '(') || (*where == ')') || + (*where == '+')) { /* legal white space - ignore */ + where++; + } + + /* now the magic number */ + sscanf(where, "%2d", level); /* We get the level number */ + if (*level < 0) { + *level = 1; + printf("Illegal value for level.\n"); + printf("Level must be >0 (Setting level to 1)\n"); + return (INPmkTemp + (" illegal (negative) argument to level parameter - level=1 assumed")); + } + + if (*level > 99) { /* Limit to change in the future */ + *level = 1; + printf("Illegal value for level.\n"); + printf("Level must be <99 (Setting Level to 1)\n"); + return (INPmkTemp + (" illegal (too high) argument to level parameter - level=1 assumed")); + } + + return ((char *) NULL); + } + + + + else { /* no level on the line => default */ + *level = 1; + printf("Level not specified: Using level 1.\n"); + return ((char *) NULL); + } + + + + +} diff --git a/src/spicelib/parser/inpgmod.c b/src/spicelib/parser/inpgmod.c new file mode 100644 index 000000000..6864e4f03 --- /dev/null +++ b/src/spicelib/parser/inpgmod.c @@ -0,0 +1,108 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "inpdefs.h" +#include "ifsim.h" +#include "cpstd.h" +#include "fteext.h" +#include "inp.h" + +extern INPmodel *modtab; + +char *INPgetMod(void *ckt, char *name, INPmodel ** model, INPtables * tab) +{ + INPmodel *modtmp; + IFvalue *val; + register int j; + char *line; + char *parm; + char *err = NULL; + char *temp; + int error; + + for (modtmp = modtab; modtmp != (INPmodel *) NULL; modtmp = + ((modtmp)->INPnextModel)) { + if (strcmp((modtmp)->INPmodName, name) == 0) { + /* found the model in question - now instantiate if necessary */ + /* and return an appropriate pointer to it */ + if (modtmp->INPmodType < 0) { + /* illegal device type, so can't handle */ + *model = (INPmodel *) NULL; + err = (char *) MALLOC((35 + strlen(name)) * sizeof(char)); + (void) sprintf(err, + "Unknown device type for model %s \n", + name); + return (err); + } + if (!((modtmp)->INPmodUsed)) { + /* not already defined, so create & give parameters */ + error = (*(ft_sim->newModel)) (ckt, (modtmp)->INPmodType, + &((modtmp)->INPmodfast), + (modtmp)->INPmodName); + if (error) + return (INPerror(error)); + /* parameter isolation, identification, binding */ + line = ((modtmp)->INPmodLine)->line; + INPgetTok(&line, &parm, 1); /* throw away '.model' */ + INPgetTok(&line, &parm, 1); /* throw away 'modname' */ + while (*line != 0) { + INPgetTok(&line, &parm, 1); + if (!*parm) + continue; + for (j = 0; j < (* (*(ft_sim->devices)[(modtmp)->INPmodType]).numModelParms); j++) { + + if (strcmp(parm, "txl") == 0) { + if (strcmp("cpl", ((*(ft_sim->devices) [ (modtmp)->INPmodType ]).modelParms[j].keyword)) == 0) { + strcpy(parm, "cpl"); + } + } + + if (strcmp(parm,((*(ft_sim->devices)[(modtmp)->INPmodType]).modelParms[j].keyword)) == 0) { + + val = INPgetValue(ckt, &line, ((* (ft_sim->devices)[(modtmp)->INPmodType]).modelParms[j].dataType), tab); + + error = (*(ft_sim->setModelParm)) (ckt, ((modtmp)->INPmodfast), + (* (ft_sim->devices)[(modtmp)->INPmodType]).modelParms[j].id, + val, (IFvalue *) NULL); + if (error) + return (INPerror(error)); + break; + } + } + if (strcmp(parm, "level") == 0) { + /* just grab the level number and throw away */ + /* since we already have that info from pass1 */ + val = INPgetValue(ckt, &line, IF_REAL, tab); + } else if (j >= + (* + (*(ft_sim->devices) + [(modtmp)->INPmodType]).numModelParms)) { + temp = + (char *) MALLOC((40 + strlen(parm)) * + sizeof(char)); + (void) sprintf(temp, + "unrecognized parameter (%s) - ignored\n", + parm); + err = INPerrCat(err, temp); + } + FREE(parm); + } + (modtmp)->INPmodUsed = 1; + (modtmp)->INPmodLine->error = err; + } + *model = modtmp; + return ((char *) NULL); + } + } + /* didn't find model - ERROR - return model */ + *model = (INPmodel *) NULL; + err = (char *) MALLOC((60 + strlen(name)) * sizeof(char)); + (void) sprintf(err, + " unable to find definition of model %s - default assumed \n", + name); + return (err); +} diff --git a/src/spicelib/parser/inpgstr.c b/src/spicelib/parser/inpgstr.c new file mode 100644 index 000000000..4081cb48b --- /dev/null +++ b/src/spicelib/parser/inpgstr.c @@ -0,0 +1,74 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +/* + * Get string input token from 'line', and return a pointer to it in 'token' + */ + +#include "ngspice.h" +#include +#include "iferrmsg.h" +#include "inpdefs.h" +#include "inp.h" + +int INPgetStr(char **line, char **token, int gobble) + /* eat non-whitespace trash AFTER token? */ +{ + char *point; + char separator = '\0'; + + /* Scan along throwing away garbage characters. */ + for (point = *line; *point != '\0'; point++) { + if ((*point == ' ') || + (*point == '\t') || + (*point == '=') || + (*point == '(') || (*point == ')') || (*point == ',')) + continue; + break; + } + if (*point == '"') { + separator = '"'; + point++; + } else if (*point == '\'') { + separator = '\''; + point++; + } + /* mark beginning of token */ + *line = point; + /* now find all good characters */ + for (point = *line; *point != '\0'; point++) { + if ((*point == ' ') || + (*point == '\t') || + (*point == '=') || + (*point == '(') || + (*point == ')') || (*point == ',') || (*point == separator)) + break; + } + + /* Create token */ + *token = (char *) MALLOC(1 + point - *line); + if (!*token) + return (E_NOMEM); + (void) strncpy(*token, *line, point - *line); + *(*token + (point - *line)) = '\0'; + *line = point; + + /* Gobble garbage to next token. */ + if (separator && **line == separator) { + (*line)++; /* Skip one closing separator */ + } + for (; **line != '\0'; (*line)++) { + if (**line == ' ') + continue; + if (**line == '\t') + continue; + if ((**line == '=') && gobble) + continue; + if ((**line == ',') && gobble) + continue; + break; + } + return (OK); +} diff --git a/src/spicelib/parser/inpgtitl.c b/src/spicelib/parser/inpgtitl.c new file mode 100644 index 000000000..5ae3cb913 --- /dev/null +++ b/src/spicelib/parser/inpgtitl.c @@ -0,0 +1,28 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* INPgetTitle(ckt,data) + * get the title card from the specified data deck and pass + * it through to SPICE-3. + */ + +#include "ngspice.h" +#include +#include "inpdefs.h" +#include "iferrmsg.h" +#include "cpstd.h" +#include "fteext.h" +#include "inp.h" + +int INPgetTitle(void **ckt, card ** data) +{ + int error; + + error = (*(ft_sim->newCircuit)) (ckt); + if (error) + return (error); + *data = (*data)->nextcard; + return (OK); +} diff --git a/src/spicelib/parser/inpgtok.c b/src/spicelib/parser/inpgtok.c new file mode 100644 index 000000000..a83be7e33 --- /dev/null +++ b/src/spicelib/parser/inpgtok.c @@ -0,0 +1,222 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: 2000 AlansFixes +**********/ + + /* get input token from 'line', + * and return a pointer to it in 'token' + */ + +/* INPgetTok: node names + INPgetUTok: numbers and other elements in expressions + (called from INPevaluate) + */ + +#include "ngspice.h" +#include +#include "iferrmsg.h" +#include "inpdefs.h" +#include "inp.h" + +int INPgetTok(char **line, char **token, int gobble) + /* eat non-whitespace trash AFTER token? */ +{ + char *point; + int signstate; + + /* scan along throwing away garbage characters */ + for (point = *line; *point != '\0'; point++) { + if (*point == ' ') + continue; + if (*point == '\t') + continue; + if (*point == '=') + continue; + if (*point == '(') + continue; + if (*point == ')') + continue; + if (*point == ',') + continue; + break; + } + /* mark beginning of token */ + *line = point; + /* now find all good characters */ + signstate = 0; + for (point = *line; *point != '\0'; point++) { + if (*point == ' ') + break; + if (*point == '\t') + break; + if (*point == '=') + break; + if (*point == '(') + break; + if (*point == ')') + break; + if (*point == ',') + break; + /* This is not complex enough to catch all errors, but it will get the "good" parses */ + if ((*point == '+') || (*point == '-')){ + /* Treat '+' signs same as '-' signs */ + if (signstate == 1 || signstate == 3) break; + signstate += 1; + continue; + } + /* saj */ + if (*point == '*') + continue; + /*break;*/ + if (*point == '/') + continue; + /*break;*/ + if (*point == '^') + continue; + /*break;*/ + /*saj */ + if (isdigit(*point) || *point == '.') { + if (signstate > 1) + signstate = 3; + else + signstate = 1; + } else if (tolower(*point) == 'e' && signstate == 1) + signstate = 2; + else + signstate = 3; + + } + if (point == *line && *point) /* Weird items, 1 char */ + point++; + *token = (char *) MALLOC(1 + point - *line); + if (!*token) + return (E_NOMEM); + (void) strncpy(*token, *line, point - *line); + *(*token + (point - *line)) = '\0'; + *line = point; + /* gobble garbage to next token */ + for (; **line != '\0'; (*line)++) { + if (**line == ' ') + continue; + if (**line == '\t') + continue; + if ((**line == '=') && gobble) + continue; + if ((**line == ',') && gobble) + continue; + break; + } + /*printf("found token (%s) and rest of line (%s)\n",*token,*line); */ + return (OK); +} + +int INPgetUTok(char **line, char **token, int gobble) + + + /* eat non-whitespace trash AFTER token? */ +{ + char *point, separator; + int signstate; + /* scan along throwing away garbage characters */ + for (point = *line; *point != '\0'; point++) { + if (*point == ' ') + continue; + if (*point == '\t') + continue; + if (*point == '=') + continue; + if (*point == '(') + continue; + if (*point == ')') + continue; + if (*point == ',') + continue; + break; + } + if (*point == '"') { + separator = '"'; + point++; + } else if (*point == '\'') { + separator = '\''; + point++; + } else + separator = 0; + + /* mark beginning of token */ + *line = point; + + /* now find all good characters */ + signstate = 0; + for (point = *line; *point != '\0'; point++) { + if (separator) { + if (*point == separator) + break; + else + continue; + } + if (*point == ' ') + break; + if (*point == '\t') + break; + if (*point == '=') + break; + if (*point == '(') + break; + if (*point == ')') + break; + if (*point == ',') + break; + /* This is not complex enough to catch all errors, but it will + get the "good" parses */ + if (*point == '+' && (signstate == 1 || signstate == 3)) + break; + if (*point == '-') { + if (signstate == 1 || signstate == 3) + break; + signstate += 1; + continue; + } + if (*point == '*') + break; + if (*point == '/') + break; + if (*point == '^') + break; + if (isdigit(*point) || *point == '.') { + if (signstate > 1) + signstate = 3; + else + signstate = 1; + } else if (tolower(*point) == 'e' && signstate == 1) + signstate = 2; + else + signstate = 3; + } + if (separator && *point == separator) + point--; + if (point == *line && *point) /* Weird items, 1 char */ + point++; + *token = (char *) MALLOC(1 + point - *line); + if (!*token) + return (E_NOMEM); + (void) strncpy(*token, *line, point - *line); + *(*token + (point - *line)) = '\0'; + /* gobble garbage to next token */ + for (; *point != '\0'; point++) { + if (*point == separator) + continue; + if (*point == ' ') + continue; + if (*point == '\t') + continue; + if ((*point == '=') && gobble) + continue; + if ((*point == ',') && gobble) + continue; + break; + } + *line = point; + /* printf("found token (%s) and rest of line (%s)\n",*token,*line); */ + return (OK); +} diff --git a/src/spicelib/parser/inpgval.c b/src/spicelib/parser/inpgval.c new file mode 100644 index 000000000..4f043cb44 --- /dev/null +++ b/src/spicelib/parser/inpgval.c @@ -0,0 +1,81 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "inpdefs.h" +#include "inpptree.h" +#include "inp.h" + +IFvalue *INPgetValue(void *ckt, char **line, int type, INPtables * tab) +{ + double *list; + int *ilist; + double tmp; + char *word; + int error; + static IFvalue temp; + INPparseTree *pt; + + /* make sure we get rid of extra bits in type */ + type &= IF_VARTYPES; + if (type == IF_INTEGER) { + temp.iValue = INPevaluate(line, &error, 1); + /*printf(" returning integer value %d\n",temp.iValue); */ + } else if (type == IF_REAL) { + temp.rValue = INPevaluate(line, &error, 1); + /*printf(" returning real value %e\n",temp.rValue); */ + } else if (type == IF_REALVEC) { + temp.v.numValue = 0; + list = (double *) MALLOC(sizeof(double)); + tmp = INPevaluate(line, &error, 1); + while (error == 0) { + /*printf(" returning vector value %g\n",tmp); */ + temp.v.numValue++; + list = + (double *) REALLOC((char *) list, + temp.v.numValue * sizeof(double)); + *(list + temp.v.numValue - 1) = tmp; + tmp = INPevaluate(line, &error, 1); + } + temp.v.vec.rVec = list; + } else if (type == IF_INTVEC) { + temp.v.numValue = 0; + ilist = (int *) MALLOC(sizeof(int)); + tmp = INPevaluate(line, &error, 1); + while (error == 0) { + /*printf(" returning vector value %g\n",tmp); */ + temp.v.numValue++; + ilist = + (int *) REALLOC((char *) ilist, + temp.v.numValue * sizeof(int)); + *(ilist + temp.v.numValue - 1) = tmp; + tmp = INPevaluate(line, &error, 1); + } + temp.v.vec.iVec = ilist; + } else if (type == IF_FLAG) { + temp.iValue = 1; + } else if (type == IF_NODE) { + INPgetTok(line, &word, 1); + INPtermInsert(ckt, &word, tab, &(temp.nValue)); + } else if (type == IF_INSTANCE) { + INPgetTok(line, &word, 1); + INPinsert(&word, tab); + temp.nValue = word; + } else if (type == IF_STRING) { + INPgetStr(line, &word, 1); + temp.sValue = word; + } else if (type == IF_PARSETREE) { + INPgetTree(line, &pt, ckt, tab); + if (!pt) + return ((IFvalue *) NULL); + temp.tValue = (IFparseTree *) pt; + /*INPptPrint("Parse tree is: ", temp.tValue); */ + } else { /* don't know what type of parameter caller is talking about! */ + return ((IFvalue *) NULL); + } + return (&temp); +} diff --git a/src/spicelib/parser/inpkmods.c b/src/spicelib/parser/inpkmods.c new file mode 100644 index 000000000..e8e2319dd --- /dev/null +++ b/src/spicelib/parser/inpkmods.c @@ -0,0 +1,30 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "inpdefs.h" +#include "inp.h" + + +extern INPmodel *modtab; + +void INPkillMods(void) +{ + INPmodel *modtmp; + INPmodel *prev = NULL; + + for (modtmp = modtab; modtmp != (INPmodel *) NULL; modtmp = + modtmp->INPnextModel) { + if (prev) + FREE(prev); + prev = modtmp; + } + if (prev) + FREE(prev); + modtab = (INPmodel *) NULL; +} diff --git a/src/spicelib/parser/inplist.c b/src/spicelib/parser/inplist.c new file mode 100644 index 000000000..f876842f9 --- /dev/null +++ b/src/spicelib/parser/inplist.c @@ -0,0 +1,52 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + /* INPlist(file,deck,type) + * provide an input listing on the specified file of the given + * card deck. The listing should be of either PHYSICAL or LOGICAL + * lines as specified by the type parameter. + */ + +#include "ngspice.h" +#include +#include "inpdefs.h" +#include "inp.h" + + +void INPlist(FILE * file, card * deck, int type) +{ + + card *here; + card *there; + + if (type == LOGICAL) { + for (here = deck; here != NULL; here = here->nextcard) { + fprintf(file, "%6d : %s\n", here->linenum, here->line); + if (here->error != (char *) NULL) { + fprintf(file, "%s", here->error); + } + } + } else if (type == PHYSICAL) { + for (here = deck; here != NULL; here = here->nextcard) { + if (here->actualLine == (card *) NULL) { + fprintf(file, "%6d : %s\n", here->linenum, here->line); + if (here->error != (char *) NULL) { + fprintf(file, "%s", here->error); + } + } else { + for (there = here->actualLine; there != NULL; + there = there->nextcard) { + fprintf(file, "%6d : %s\n", there->linenum, + there->line); + if (there->error != (char *) NULL) { + fprintf(file, "%s", there->error); + } + } + } + } + } +} diff --git a/src/spicelib/parser/inplkmod.c b/src/spicelib/parser/inplkmod.c new file mode 100644 index 000000000..d1c534bab --- /dev/null +++ b/src/spicelib/parser/inplkmod.c @@ -0,0 +1,29 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "inpdefs.h" +#include "inp.h" + + +extern INPmodel *modtab; + + +int INPlookMod(char *name) +{ + register INPmodel **i; + + for (i = &modtab; *i != (INPmodel *) NULL; i = &((*i)->INPnextModel)) { + if (strcmp((*i)->INPmodName, name) == 0) { + /* found the model in question - return TRUE */ + return (1); + } + } + /* didn't find model - return FALSE */ + return (0); +} diff --git a/src/spicelib/parser/inpmkmod.c b/src/spicelib/parser/inpmkmod.c new file mode 100644 index 000000000..a9b9705d3 --- /dev/null +++ b/src/spicelib/parser/inpmkmod.c @@ -0,0 +1,35 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "ngspice.h" +#include +#include "inpdefs.h" +#include "iferrmsg.h" +#include "inp.h" + +INPmodel *modtab; + + /* create/lookup a 'model' entry */ + +int INPmakeMod(char *token, int type, card * line) +{ + register INPmodel **i; + + for (i = &modtab; *i != (INPmodel *) NULL; i = &((*i)->INPnextModel)) { + if (strcmp((*i)->INPmodName, token) == 0) { + return (OK); + } + } + *i = (INPmodel *) MALLOC(sizeof(INPmodel)); + if (*i == NULL) + return (E_NOMEM); + (*i)->INPmodName = token; + (*i)->INPmodType = type; + (*i)->INPnextModel = (INPmodel *) NULL; + (*i)->INPmodUsed = 0; + (*i)->INPmodLine = line; + (*i)->INPmodfast = NULL; + return (OK); +} diff --git a/src/spicelib/parser/inpmktmp.c b/src/spicelib/parser/inpmktmp.c new file mode 100644 index 000000000..1ed44d65e --- /dev/null +++ b/src/spicelib/parser/inpmktmp.c @@ -0,0 +1,25 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +#include "ngspice.h" +#include +#include "inpdefs.h" +#include "inp.h" + + +char *INPmkTemp(char *string) +{ + int len; + char *temp; + + len = strlen(string); + temp = MALLOC(len + 1); + if (temp != (char *) NULL) + (void) strcpy(temp, string); + return (temp); + +} diff --git a/src/spicelib/parser/inppas1.c b/src/spicelib/parser/inppas1.c new file mode 100644 index 000000000..596df381b --- /dev/null +++ b/src/spicelib/parser/inppas1.c @@ -0,0 +1,41 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include + +#include +#include + +#include "inppas1.h" + +/* + * The first pass of the circuit parser just looks for '.model' lines + */ + +void INPpas1(void *ckt, card * deck, INPtables * tab) +{ + card *current; + char *INPdomodel(void *ckt, card * image, INPtables * tab); + char *temp, *thisline; + + for (current = deck; current != NULL; current = current->nextcard) { + /* SPICE-2 keys off of the first character of the line */ + thisline = current->line; + + while (*thisline && ((*thisline == ' ') || (*thisline == '\t'))) + thisline++; + + if (*thisline == '.') { + if (strncmp(thisline, ".model", 6) == 0) { + temp = INPdomodel(ckt, current, tab); + current->error = INPerrCat(current->error, temp); + } + } + + /* for now, we do nothing with the other cards - just + * keep them in the list for pass 2 + */ + } +} diff --git a/src/spicelib/parser/inppas1.h b/src/spicelib/parser/inppas1.h new file mode 100644 index 000000000..6635e6228 --- /dev/null +++ b/src/spicelib/parser/inppas1.h @@ -0,0 +1,8 @@ +#ifndef _INPPAS1_H +#define _INPPAS1_H + +#include + +void INPpas1(void *ckt, card *deck, INPtables *tab); + +#endif diff --git a/src/spicelib/parser/inppas2.c b/src/spicelib/parser/inppas2.c new file mode 100644 index 000000000..5595c366d --- /dev/null +++ b/src/spicelib/parser/inppas2.c @@ -0,0 +1,218 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include +#include +#include +#include + +#include "inppas2.h" + +#ifdef XSPICE +/* gtri - add - wbk - 11/9/90 - include function prototypes */ +#include "mifproto.h" +/* gtri - end - wbk - 11/9/90 */ +#endif + +/* pass 2 - Scan through the lines. ".model" cards have processed in + * pass1 and are ignored here. */ + +void INPpas2(void *ckt, card * data, INPtables * tab, void *task) +{ + + card *current; + char c; + char *groundname = "0"; + char *gname; + void *gnode; + int error; /* used by the macros defined above */ + + error = INPgetTok(&groundname, &gname, 1); + if (error) + data->error = + INPerrCat(data->error, + INPmkTemp + ("can't read internal ground node name!\n")); + + error = INPgndInsert(ckt, &gname, tab, &gnode); + if (error && error != E_EXISTS) + data->error = + INPerrCat(data->error, + INPmkTemp + ("can't insert internal ground node in symbol table!\n")); + + for (current = data; current != NULL; current = current->nextcard) { + + c = *(current->line); + c = islower(c) ? toupper(c) : c; + + switch (c) { + + case ' ': + /* blank line (space leading) */ + case '\t': + /* blank line (tab leading) */ + break; + +#ifdef XSPICE + /* gtri - add - wbk - 10/23/90 - add case for 'A' devices */ + + case 'A': /* Aname */ + MIF_INP2A(ckt,tab,current); + break; + + /* gtri - end - wbk - 10/23/90 */ +#endif + + case 'R': + /* Rname [][][w=][l=] */ + INP2R(ckt, tab, current); + break; + + case 'C': + /* Cname [IC=] */ + INP2C(ckt, tab, current); + break; + + case 'L': + /* Lname [IC=] */ + INP2L(ckt, tab, current); + break; + + case 'G': + /* Gname */ + INP2G(ckt, tab, current); + break; + + case 'E': + /* Ename */ + INP2E(ckt, tab, current); + break; + + case 'F': + /* Fname */ + INP2F(ckt, tab, current); + break; + + case 'H': + /* Hname */ + INP2H(ckt, tab, current); + break; + + case 'D': + /* Dname [] [OFF] [IC=] */ + INP2D(ckt, tab, current); + break; + + case 'J': + /* Jname [] [OFF] + [IC=,] */ + INP2J(ckt, tab, current); + break; + + case 'Z': + /* Zname [] [OFF] + [IC=,] */ + INP2Z(ckt, tab, current); + break; + + case 'M': + /* Mname [L=] + [W=] [AD=] [AS=] [PD=] + [PS=] [NRD=] [NRS=] [OFF] + [IC=,,] */ + INP2M(ckt, tab, current); + break; + + case 'O': + /* Oname + [IC=,,,] */ + INP2O(ckt, tab, current); + break; + + case 'V': + /* Vname [ [DC] ] [AC [ [ ] ] ] + [] */ + INP2V(ckt, tab, current); + break; + + case 'I': + /* Iname [ [DC] ] [AC [ [ ] ] ] + [] */ + INP2I(ckt, tab, current); + break; + + case 'Q': + /* Qname [] [] [OFF] + [IC=,] */ + INP2Q(ckt, tab, current, gnode); + break; + + case 'T': + /* Tname [TD=] + [F= [NL=]][IC=,,,] */ + INP2T(ckt, tab, current); + break; + + case 'S': + /* Sname [] [IC] */ + INP2S(ckt, tab, current); + break; + + case 'W': + /* Wname [] [IC] */ + /* CURRENT CONTROLLED SWITCH */ + INP2W(ckt, tab, current); + break; + + case 'U': + /* Uname [l=] [n=] */ + INP2U(ckt, tab, current); + break; + + /* Kspice addition - saj */ + case 'P': + /* Pname ...... */ + /* R= L= G= C= l= */ + INP2P(ckt, tab,current); + break; + case 'Y': + /* Yname R= L= G= C= l= */ + INP2Y(ckt, tab,current); + break; + /* end Kspice */ + + case 'K': + /* Kname Lname Lname */ + INP2K(ckt, tab, current); + break; + + case '*': + /* * - a comment - ignore */ + break; + + case 'B': + /* Bname [V=expr] [I=expr] */ + /* Arbitrary source. */ + INP2B(ckt, tab, current); + break; + + case '.': /* . Many possibilities */ + if (INP2dot(ckt,tab,current,task,gnode)) + return; + break; + + case 0: + break; + + default: + /* the un-implemented device */ + LITERR(" unknown device type - error \n"); + break; + } + } + + return; +} diff --git a/src/spicelib/parser/inppas2.h b/src/spicelib/parser/inppas2.h new file mode 100644 index 000000000..9095ef7ae --- /dev/null +++ b/src/spicelib/parser/inppas2.h @@ -0,0 +1,9 @@ +#ifndef _INPPAS2_H +#define _INPPAS2_H + +#include + +void INPpas2(void *ckt, card *data, INPtables *tab, void *task); + + +#endif diff --git a/src/spicelib/parser/inppas3.c b/src/spicelib/parser/inppas3.c new file mode 100644 index 000000000..db8b2bf1d --- /dev/null +++ b/src/spicelib/parser/inppas3.c @@ -0,0 +1,119 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: AlansFixes +**********/ + +#include +#include +#include +#include +#include + +#include "inppas3.h" + +extern IFsimulator *ft_sim; + + +/* pass 3 - Read all nodeset and IC lines. All circuit nodes will have + * been created by now, (except for internal device nodes), so any + * nodeset or IC nodes which have to be created are flagged with a + * warning. */ + +void +INPpas3(void *ckt, card *data, INPtables *tab, void *task, + IFparm *nodeParms, int numNodeParms) +{ + + card *current; + int error; /* used by the macros defined above */ + char *line; /* the part of the current line left + to parse */ + char *name; /* the node's name */ + char *token; /* a token from the line */ + IFparm *prm; /* pointer to parameter to search + through array */ + IFvalue ptemp; /* a value structure to package + resistance into */ + int which; /* which analysis we are performing */ + int length; /* length of a name */ + void *node1; /* the first node's node pointer */ + + for(current = data; current != NULL; current = current->nextcard) { + line = current->line; + INPgetTok(&line,&token,1); + + if (strcmp(token,".nodeset")==0) { + which = -1; + + for(prm = nodeParms; prm < nodeParms + numNodeParms; prm++) { + if(strcmp(prm->keyword,"nodeset")==0) { + which = prm->id; + break; + } + } + + if(which == -1) { + LITERR("nodeset unknown to simulator. \n") + return; + } + + for(;;) { + /* loop until we run out of data */ + INPgetTok(&line,&name,1); + + /* check to see if in the form V(xxx) and grab the xxx */ + if( *name == (char)NULL) break; /* end of line */ + length = strlen(name); + if( (*name == 'V' || *(name) == 'v') && (length == 1)){ + /* looks like V - must be V(xx) - get xx now*/ + INPgetTok(&line,&name,1); + if (INPtermInsert(ckt,&name,tab,&node1)!=E_EXISTS) + fprintf(stderr, + "Warning : Nodeset on non-existant node - %s\n", name); + ptemp.rValue = INPevaluate(&line,&error,1); + IFC(setNodeParm,(ckt,node1,which,&ptemp,(IFvalue*)NULL)); + continue; + } + LITERR(" Error: .nodeset syntax error.\n") + break; + } + } else if ((strcmp(token,".ic") == 0)) { + /* .ic */ + which = -1; + for(prm = nodeParms; prm < nodeParms + numNodeParms; prm++) { + if(strcmp(prm->keyword,"ic")==0) { + which = prm->id; + break; + } + } + + if(which==-1) { + LITERR("ic unknown to simulator. \n") + return; + } + + for(;;) { + /* loop until we run out of data */ + INPgetTok(&line,&name,1); + /* check to see if in the form V(xxx) and grab the xxx */ + if( *name == 0) break; /* end of line */ + length = strlen(name); + if( (*name == 'V' || *(name) == 'v') && (length == 1)){ + /* looks like V - must be V(xx) - get xx now*/ + INPgetTok(&line,&name,1); + if (INPtermInsert(ckt,&name,tab,&node1)!=E_EXISTS) + fprintf(stderr, + "Warning : IC on non-existant node - %s\n", name); + ptemp.rValue = INPevaluate(&line,&error,1); + IFC(setNodeParm,(ckt,node1,which,&ptemp,(IFvalue*)NULL)) + continue; + } + LITERR(" Error: .ic syntax error.\n") + break; + } + } + } + return; +} + diff --git a/src/spicelib/parser/inppas3.h b/src/spicelib/parser/inppas3.h new file mode 100644 index 000000000..c58fb12a5 --- /dev/null +++ b/src/spicelib/parser/inppas3.h @@ -0,0 +1,11 @@ +/* AlansFixes */ +#ifndef _INPPAS3_H +#define _INPPAS3_H + +#include + +void INPpas3(void *ckt, card *data, INPtables *tab, void *task, + IFparm *nodeParms, int numNodeParams); + + +#endif diff --git a/src/spicelib/parser/inppname.c b/src/spicelib/parser/inppname.c new file mode 100644 index 000000000..e89bc38dc --- /dev/null +++ b/src/spicelib/parser/inppname.c @@ -0,0 +1,48 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* + * INPpName() + * + * Take a parameter by Name and set it on the specified device + */ + +#include "ngspice.h" +#include +#include "cpdefs.h" +#include "fteext.h" +#include "ifsim.h" +#include "iferrmsg.h" +#include "inp.h" + +int INPpName(char *parm, IFvalue * val, void *ckt, int dev, void *fast) + /* the name of the parameter to set */ + /* the parameter union containing the value to set */ + /* the circuit this device is a member of */ + /* the device type code to the device being parsed */ + /* direct pointer to device being parsed */ +{ + int error; /* int to store evaluate error return codes in */ + int i; + + for (i = 0; i < (*(*(ft_sim->devices)[dev]).numInstanceParms); i++) { + if (strcmp(parm, + ((*(ft_sim->devices)[dev]).instanceParms[i].keyword)) == + 0) { + error = + (*(ft_sim->setInstanceParm)) (ckt, fast, + (*(ft_sim->devices)[dev]). + instanceParms[i].id, val, + (IFvalue *) NULL); + if (error) + return (error); + break; + } + } + if (i == (*(*(ft_sim->devices)[dev]).numInstanceParms)) { + return (E_BADPARM); + } + return (OK); +} diff --git a/src/spicelib/parser/inpptree.c b/src/spicelib/parser/inpptree.c new file mode 100644 index 000000000..c01eef8a4 --- /dev/null +++ b/src/spicelib/parser/inpptree.c @@ -0,0 +1,1115 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +#include "ngspice.h" +#include +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "inpdefs.h" +#include "inpptree.h" +#include "inp.h" + +static INPparseNode *mkcon(double value); +static INPparseNode *mkb(int type, INPparseNode * left, + INPparseNode * right); +static INPparseNode *mkf(int type, INPparseNode * arg); +static int PTcheck(INPparseNode * p); +static INPparseNode *PTparse(char **line); +static INPparseNode *makepnode(PTelement * elem); +static INPparseNode *mkbnode(int opnum, INPparseNode * arg1, + INPparseNode * arg2); +static INPparseNode *mkfnode(char *fname, INPparseNode * arg); +static INPparseNode *mknnode(double number); +static INPparseNode *mksnode(char *string); +static INPparseNode *PTdifferentiate(INPparseNode * p, int varnum); +static PTelement *PTlexer(char **line); + +static IFvalue *values = NULL; +static int *types; +static int numvalues; +static void *circuit; +static INPtables *tables; + + + +extern IFsimulator *ft_sim; /* XXX */ + +/* Some tables that the parser uses. */ + +static struct op { + int number; + char *name; + double (*funcptr) (); +} ops[] = { + { + PT_COMMA, ",", NULL}, { + PT_PLUS, "+", PTplus}, { + PT_MINUS, "-", PTminus}, { + PT_TIMES, "*", PTtimes}, { + PT_DIVIDE, "/", PTdivide}, { + PT_POWER, "^", PTpower} +}; + +#define NUM_OPS (sizeof (ops) / sizeof (struct op)) + +static struct func { + char *name; + int number; + double (*funcptr) (); +} funcs[] = { + { "abs", PTF_ABS, PTabs } , + { "acos", PTF_ACOS, PTacos } , + { "acosh", PTF_ACOSH, PTacosh } , + { "asin", PTF_ASIN, PTasin } , + { "asinh", PTF_ASINH, PTasinh } , + { "atan", PTF_ATAN, PTatan } , + { "atanh", PTF_ATANH, PTatanh } , + { "cos", PTF_COS, PTcos } , + { "cosh", PTF_COSH, PTcosh } , + { "exp", PTF_EXP, PTexp } , + { "ln", PTF_LN, PTln } , + { "log", PTF_LOG, PTlog } , + { "sgn", PTF_SGN, PTsgn } , + { "sin", PTF_SIN, PTsin } , + { "sinh", PTF_SINH, PTsinh } , + { "sqrt", PTF_SQRT, PTsqrt } , + { "tan", PTF_TAN, PTtan } , + { "tanh", PTF_TANH, PTtanh } , + { "u", PTF_USTEP, PTustep } , + { "uramp", PTF_URAMP, PTuramp } , + { "-", PTF_UMINUS, PTuminus }, + /* MW. cif function added */ + { "u2", PTF_USTEP2, PTustep2} +} ; + +#define NUM_FUNCS (sizeof (funcs) / sizeof (struct func)) + +/* These are all the constants any sane person needs. */ + +static struct constant { + char *name; + double value; +} constants[] = { + { + "e", M_E}, { + "pi", M_PI} +}; + +#define NUM_CONSTANTS (sizeof (constants) / sizeof (struct constant)) + +/* Parse the expression in *line as far as possible, and return the parse + * tree obtained. If there is an error, *pt will be set to NULL and an error + * message will be printed. + */ + +void +INPgetTree(char **line, INPparseTree ** pt, void *ckt, INPtables * tab) +{ + INPparseNode *p; + int i; + + values = NULL; + types = NULL; + numvalues = 0; + + circuit = ckt; + tables = tab; + + p = PTparse(line); + + if (!p || !PTcheck(p)) { + *pt = NULL; + return; + } + + (*pt) = (INPparseTree *) MALLOC(sizeof(INPparseTree)); + + (*pt)->p.numVars = numvalues; + (*pt)->p.varTypes = types; + (*pt)->p.vars = values; + (*pt)->p.IFeval = IFeval; + (*pt)->tree = p; + + (*pt)->derivs = (INPparseNode **) + MALLOC(numvalues * sizeof(INPparseNode *)); + + for (i = 0; i < numvalues; i++) + (*pt)->derivs[i] = PTdifferentiate(p, i); + + return; +} + +/* This routine takes the partial derivative of the parse tree with respect to + * the i'th variable. We try to do optimizations like getting rid of 0-valued + * terms. + * + *** Note that in the interests of simplicity we share some subtrees between + *** the function and its derivatives. This means that you can't free the + *** trees. + */ + +static INPparseNode *PTdifferentiate(INPparseNode * p, int varnum) +{ + INPparseNode *arg1 = NULL, *arg2, *newp; + +/* printf("differentiating: "); printTree(p); printf(" wrt var %d\n", varnum);*/ + + switch (p->type) { + case PT_CONSTANT: + newp = mkcon((double) 0); + break; + + case PT_VAR: + /* Is this the variable we're differentiating wrt? */ + if (p->valueIndex == varnum) + newp = mkcon((double) 1); + else + newp = mkcon((double) 0); + break; + + case PT_PLUS: + case PT_MINUS: + arg1 = PTdifferentiate(p->left, varnum); + arg2 = PTdifferentiate(p->right, varnum); + newp = mkb(p->type, arg1, arg2); + break; + + case PT_TIMES: + /* d(a * b) = d(a) * b + d(b) * a */ + arg1 = PTdifferentiate(p->left, varnum); + arg2 = PTdifferentiate(p->right, varnum); + + newp = mkb(PT_PLUS, mkb(PT_TIMES, arg1, p->right), + mkb(PT_TIMES, p->left, arg2)); + break; + + case PT_DIVIDE: + /* d(a / b) = (d(a) * b - d(b) * a) / b^2 */ + arg1 = PTdifferentiate(p->left, varnum); + arg2 = PTdifferentiate(p->right, varnum); + + newp = mkb(PT_DIVIDE, mkb(PT_MINUS, mkb(PT_TIMES, arg1, + p->right), mkb(PT_TIMES, + p->left, + arg2)), + mkb(PT_POWER, p->right, mkcon((double) 2))); + break; + + case PT_POWER: + /* Two cases... If the power is a constant then we're cool. + * Otherwise we have to be tricky. + */ + if (p->right->type == PT_CONSTANT) { + arg1 = PTdifferentiate(p->left, varnum); + + newp = mkb(PT_TIMES, mkb(PT_TIMES, + mkcon(p->right->constant), + mkb(PT_POWER, p->left, + mkcon(p->right->constant - 1))), + arg1); + } else { + /* This is complicated. f(x) ^ g(x) -> + * exp(y(x) * ln(f(x)) ... + */ + arg1 = PTdifferentiate(p->left, varnum); + arg2 = PTdifferentiate(p->right, varnum); + newp = mkb(PT_TIMES, mkf(PTF_EXP, mkb(PT_TIMES, + p->right, mkf(PTF_LN, + p->left))), + mkb(PT_PLUS, + mkb(PT_TIMES, p->right, + mkb(PT_DIVIDE, arg1, p->left)), + mkb(PT_TIMES, arg2, mkf(PTF_LN, arg1)))); + + } + break; + + case PT_FUNCTION: + /* Many cases. Set arg1 to the derivative of the function, + * and arg2 to the derivative of the argument. + */ + switch (p->funcnum) { + case PTF_ABS: /* sgn(u) */ + /* arg1 = mkf(PTF_SGN, p->left, 0); */ + arg1 = mkf(PTF_SGN, p->left); + break; + + case PTF_SGN: + arg1 = mkcon((double) 0.0); + break; + + case PTF_ACOS: /* - 1 / sqrt(1 - u^2) */ + arg1 = mkb(PT_DIVIDE, mkcon((double) -1), mkf(PTF_SQRT, + mkb(PT_MINUS, + mkcon( + (double) + 1), + mkb(PT_POWER, + p->left, + mkcon( + (double) + 2))))); + break; + + case PTF_ACOSH: /* 1 / sqrt(u^2 - 1) */ + arg1 = mkb(PT_DIVIDE, mkcon((double) 1), mkf(PTF_SQRT, + mkb(PT_MINUS, + mkb(PT_POWER, + p->left, + mkcon( + (double) + 2)), + mkcon((double) + 1)))); + + break; + + case PTF_ASIN: /* 1 / sqrt(1 - u^2) */ + arg1 = mkb(PT_DIVIDE, mkcon((double) 1), mkf(PTF_SQRT, + mkb(PT_MINUS, + mkcon((double) + 1), + mkb(PT_POWER, + p->left, + mkcon( + (double) + 2))))); + break; + + case PTF_ASINH: /* 1 / sqrt(u^2 + 1) */ + arg1 = mkb(PT_DIVIDE, mkcon((double) 1), mkf(PTF_SQRT, + mkb(PT_PLUS, + mkb(PT_POWER, + p->left, + mkcon( + (double) + 2)), + mkcon((double) + 1)))); + break; + + case PTF_ATAN: /* 1 / (1 + u^2) */ + arg1 = mkb(PT_DIVIDE, mkcon((double) 1), mkb(PT_PLUS, + mkb(PT_POWER, + p->left, + mkcon((double) + 2)), + mkcon((double) + 1))); + break; + + case PTF_ATANH: /* 1 / (1 - u^2) */ + arg1 = mkb(PT_DIVIDE, mkcon((double) 1), mkb(PT_MINUS, + mkcon((double) 1), + mkb(PT_POWER, + p->left, + mkcon((double) + 2)))); + break; + + case PTF_COS: /* - sin(u) */ + arg1 = mkf(PTF_UMINUS, mkf(PTF_SIN, p->left)); + break; + + case PTF_COSH: /* sinh(u) */ + arg1 = mkf(PTF_SINH, p->left); + break; + + case PTF_EXP: /* exp(u) */ + /* arg1 = mkf(PTF_EXP, p->left, 0); */ + arg1 = mkf(PTF_EXP, p->left); + break; + + case PTF_LN: /* 1 / u */ + arg1 = mkb(PT_DIVIDE, mkcon((double) 1), p->left); + break; + + case PTF_LOG: /* log(e) / u */ + arg1 = mkb(PT_DIVIDE, mkcon((double) M_LOG10E), p->left); + break; + + case PTF_SIN: /* cos(u) */ + arg1 = mkf(PTF_COS, p->left); + break; + + case PTF_SINH: /* cosh(u) */ + arg1 = mkf(PTF_COSH, p->left); + break; + + case PTF_SQRT: /* 1 / (2 * sqrt(u)) */ + arg1 = mkb(PT_DIVIDE, mkcon((double) 1), mkb(PT_TIMES, + mkcon((double) 2), + mkf(PTF_SQRT, + p->left))); + break; + + case PTF_TAN: /* 1 / (cos(u) ^ 2) */ + arg1 = mkb(PT_DIVIDE, mkcon((double) 1), mkb(PT_POWER, + mkf(PTF_COS, + p->left), + mkcon((double) + 2))); + break; + + case PTF_TANH: /* 1 / (cosh(u) ^ 2) */ + arg1 = mkb(PT_DIVIDE, mkcon((double) 1), mkb(PT_POWER, + mkf(PTF_COSH, + p->left), + mkcon((double) + 2))); + break; + + case PTF_USTEP: + arg1 = mkcon((double) 0.0); + break; + + case PTF_URAMP: + arg1 = mkf(PTF_USTEP, p->left); + break; + + /* MW. PTF_CIF for new cif function */ + case PTF_USTEP2: + arg1 = mkcon((double) 0.0); + break; + + case PTF_UMINUS: /* - 1 ; like a constant (was 0 !) */ + arg1 = mkcon((double) - 1.0); + break; + + default: + fprintf(stderr, "Internal Error: bad function # %d\n", + p->funcnum); + newp = NULL; + break; + } + + arg2 = PTdifferentiate(p->left, varnum); + + newp = mkb(PT_TIMES, arg1, arg2); + + break; + + default: + fprintf(stderr, "Internal error: bad node type %d\n", p->type); + newp = NULL; + break; + } + +/* printf("result is: "); printTree(newp); printf("\n"); */ + return (newp); +} + +static INPparseNode *mkcon(double value) +{ + INPparseNode *p = (INPparseNode *) MALLOC(sizeof(INPparseNode)); + + p->type = PT_CONSTANT; + p->constant = value; + + return (p); +} + +static INPparseNode *mkb(int type, INPparseNode * left, + INPparseNode * right) +{ + INPparseNode *p = (INPparseNode *) MALLOC(sizeof(INPparseNode)); + int i; + + if ((right->type == PT_CONSTANT) && (left->type == PT_CONSTANT)) { + switch (type) { + case PT_TIMES: + return (mkcon(left->constant * right->constant)); + + case PT_DIVIDE: + return (mkcon(left->constant / right->constant)); + + case PT_PLUS: + return (mkcon(left->constant + right->constant)); + + case PT_MINUS: + return (mkcon(left->constant - right->constant)); + + case PT_POWER: + return (mkcon(pow(left->constant, right->constant))); + } + } + switch (type) { + case PT_TIMES: + if ((left->type == PT_CONSTANT) && (left->constant == 0)) + return (left); + else if ((right->type == PT_CONSTANT) && (right->constant == 0)) + return (right); + else if ((left->type == PT_CONSTANT) && (left->constant == 1)) + return (right); + else if ((right->type == PT_CONSTANT) && (right->constant == 1)) + return (left); + break; + + case PT_DIVIDE: + if ((left->type == PT_CONSTANT) && (left->constant == 0)) + return (left); + else if ((right->type == PT_CONSTANT) && (right->constant == 1)) + return (left); + break; + + case PT_PLUS: + if ((left->type == PT_CONSTANT) && (left->constant == 0)) + return (right); + else if ((right->type == PT_CONSTANT) && (right->constant == 0)) + return (left); + break; + + case PT_MINUS: + if ((right->type == PT_CONSTANT) && (right->constant == 0)) + return (left); + else if ((left->type == PT_CONSTANT) && (left->constant == 0)) + return (mkf(PTF_UMINUS, right)); + break; + + case PT_POWER: + if (right->type == PT_CONSTANT) { + if (right->constant == 0) + return (mkcon(1.0)); + else if (right->constant == 1) + return (left); + } + break; + } + + p->type = type; + p->left = left; + p->right = right; + + for (i = 0; i < NUM_OPS; i++) + if (ops[i].number == type) + break; + if (i == NUM_OPS) { + fprintf(stderr, "Internal Error: bad type %d\n", type); + return (NULL); + } + p->function = ops[i].funcptr; + p->funcname = ops[i].name; + + return (p); +} + +static INPparseNode *mkf(int type, INPparseNode * arg) +{ + INPparseNode *p = (INPparseNode *) MALLOC(sizeof(INPparseNode)); + int i; + double constval; + + for (i = 0; i < NUM_FUNCS; i++) + if (funcs[i].number == type) + break; + if (i == NUM_FUNCS) { + fprintf(stderr, "Internal Error: bad type %d\n", type); + return (NULL); + } + + if (arg->type == PT_CONSTANT) { + constval = ((*funcs[i].funcptr) (arg->constant)); + return (mkcon(constval)); + } + + p->type = PT_FUNCTION; + p->left = arg; + + p->funcnum = i; + p->function = funcs[i].funcptr; + p->funcname = funcs[i].name; + + return (p); +} + +/* Check for remaining PT_PLACEHOLDERs in the parse tree. Returns 1 if ok. */ + +static int PTcheck(INPparseNode * p) +{ + switch (p->type) { + case PT_PLACEHOLDER: + return (0); + + case PT_CONSTANT: + case PT_VAR: + return (1); + + case PT_FUNCTION: + return (PTcheck(p->left)); + + case PT_PLUS: + case PT_MINUS: + case PT_TIMES: + case PT_DIVIDE: + case PT_POWER: + return (PTcheck(p->left) && PTcheck(p->right)); + + default: + fprintf(stderr, "Internal error: bad node type %d\n", p->type); + return (0); + } +} + +/* The operator-precedence table for the parser. */ + +#define G 1 /* Greater than. */ +#define L 2 /* Less than. */ +#define E 3 /* Equal. */ +#define R 4 /* Error. */ + +static char prectable[11][11] = { + /* $ + - * / ^ u- ( ) v , */ +/* $ */ {R, L, L, L, L, L, L, L, R, L, R}, +/* + */ {G, G, G, L, L, L, L, L, G, L, G}, +/* - */ {G, G, G, L, L, L, L, L, G, L, G}, +/* * */ {G, G, G, G, G, L, L, L, G, L, G}, +/* / */ {G, G, G, G, G, L, L, L, G, L, G}, +/* ^ */ {G, G, G, G, G, L, L, L, G, L, G}, +/* u-*/ {G, G, G, G, G, G, G, L, G, L, R}, +/* ( */ {R, L, L, L, L, L, L, L, E, L, L}, +/* ) */ {G, G, G, G, G, G, G, R, G, R, G}, +/* v */ {G, G, G, G, G, G, G, G, G, R, G}, +/* , */ {G, L, L, L, L, L, L, L, G, L, G} + +}; + +/* Return an expr. */ + +static INPparseNode *PTparse(char **line) +{ + PTelement stack[PT_STACKSIZE]; + int sp = 0, st, i; + PTelement *top, *next; + INPparseNode *pn, *lpn, *rpn; + + stack[0].token = TOK_END; + next = PTlexer(line); + + while ((sp > 1) || (next->token != TOK_END)) { + /* Find the top-most terminal. */ + i = sp; + do { + top = &stack[i--]; + } while (top->token == TOK_VALUE); + + + switch (prectable[top->token][next->token]) { + case L: + case E: + /* Push the token read. */ + if (sp == (PT_STACKSIZE - 1)) { + fprintf(stderr, "Error: stack overflow\n"); + return (NULL); + } + bcopy((char *) next, (char *) &stack[++sp], sizeof(PTelement)); + next = PTlexer(line); + continue; + + case R: + fprintf(stderr, "Syntax error.\n"); + return (NULL); + + case G: + /* Reduce. Make st and sp point to the elts on the + * stack at the end and beginning of the junk to + * reduce, then try and do some stuff. When scanning + * back for a <, ignore VALUES. + */ + st = sp; + if (stack[sp].token == TOK_VALUE) + sp--; + while (sp > 0) { + if (stack[sp - 1].token == TOK_VALUE) + i = 2; /* No 2 pnodes together... */ + else + i = 1; + if (prectable[stack[sp - i].token] + [stack[sp].token] == L) + break; + else + sp = sp - i; + } + if (stack[sp - 1].token == TOK_VALUE) + sp--; + /* Now try and see what we can make of this. + * The possibilities are: - node + * node op node + * ( node ) + * func ( node ) + * func ( node, node, node, ... ) <- new + * node + */ + if (st == sp) { + pn = makepnode(&stack[st]); + if (pn == NULL) + goto err; + } else if ((stack[sp].token == TOK_UMINUS) && (st == sp + 1)) { + lpn = makepnode(&stack[st]); + if (lpn == NULL) + goto err; + pn = mkfnode("-", lpn); + } else if ((stack[sp].token == TOK_LPAREN) && + (stack[st].token == TOK_RPAREN)) { + pn = makepnode(&stack[sp + 1]); + if (pn == NULL) + goto err; + } else if ((stack[sp + 1].token == TOK_LPAREN) && + (stack[st].token == TOK_RPAREN)) { + lpn = makepnode(&stack[sp + 2]); + if ((lpn == NULL) || (stack[sp].type != TYP_STRING)) + goto err; + if (!(pn = mkfnode(stack[sp].value.string, lpn))) + return (NULL); + } else { /* node op node */ + lpn = makepnode(&stack[sp]); + rpn = makepnode(&stack[st]); + if ((lpn == NULL) || (rpn == NULL)) + goto err; + pn = mkbnode(stack[sp + 1].token, lpn, rpn); + } + stack[sp].token = TOK_VALUE; + stack[sp].type = TYP_PNODE; + stack[sp].value.pnode = pn; + continue; + } + } + pn = makepnode(&stack[1]); + if (pn) + return (pn); + err: + fprintf(stderr, "Syntax error.\n"); + return (NULL); +} + +/* Given a pointer to an element, make a pnode out of it (if it already + * is one, return a pointer to it). If it isn't of type VALUE, then return + * NULL. + */ + +static INPparseNode *makepnode(PTelement * elem) +{ + if (elem->token != TOK_VALUE) + return (NULL); + + switch (elem->type) { + case TYP_STRING: + return (mksnode(elem->value.string)); + + case TYP_NUM: + return (mknnode(elem->value.real)); + + case TYP_PNODE: + return (elem->value.pnode); + + default: + fprintf(stderr, "Internal Error: bad token type\n"); + return (NULL); + } +} + +/* Binop node. */ + +static INPparseNode *mkbnode(int opnum, INPparseNode * arg1, + INPparseNode * arg2) +{ + INPparseNode *p; + int i; + + for (i = 0; i < NUM_OPS; i++) + if (ops[i].number == opnum) + break; + + if (i == NUM_OPS) { + fprintf(stderr, "Internal Error: no such op num %d\n", opnum); + return (NULL); + } + p = (INPparseNode *) MALLOC(sizeof(INPparseNode)); + + p->type = opnum; + p->funcname = ops[i].name; + p->function = ops[i].funcptr; + p->left = arg1; + p->right = arg2; + + return (p); +} + +static INPparseNode *mkfnode(char *fname, INPparseNode * arg) +{ + int i; + INPparseNode *p; + char buf[128], *name, *s; + IFvalue temp; + + /* Make sure the case is ok. */ + (void) strcpy(buf, fname); + for (s = buf; *s; s++) + if (isupper(*s)) + *s = tolower(*s); + + p = (INPparseNode *) MALLOC(sizeof(INPparseNode)); + + if (!strcmp(buf, "v")) { + name = MALLOC(128); + if (arg->type == PT_PLACEHOLDER) { + strcpy(name, arg->funcname); + } else if (arg->type == PT_CONSTANT) { + (void) sprintf(name, "%d", (int) arg->constant); + } else if (arg->type != PT_COMMA) { + fprintf(stderr, "Error: badly formed node voltage\n"); + return (NULL); + } + + if (arg->type == PT_COMMA) { + /* Change v(a,b) into v(a) - v(b) */ + p = mkb(PT_MINUS, mkfnode(fname, arg->left), + mkfnode(fname, arg->right)); + } else { + /* printf("getting a node called '%s'\n", name); */ + INPtermInsert(circuit, &name, tables, &(temp.nValue)); + for (i = 0; i < numvalues; i++) + if ((types[i] == IF_NODE) && (values[i].nValue == + temp.nValue)) break; + if (i == numvalues) { + if (numvalues) { + values = (IFvalue *) + REALLOC((char *) values, + (numvalues + 1) * sizeof(IFvalue)); + types = (int *) + REALLOC((char *) types, + (numvalues + 1) * sizeof(int)); + } else { + values = (IFvalue *) MALLOC(sizeof(IFvalue)); + types = (int *) MALLOC(sizeof(int)); + } + values[i] = temp; + types[i] = IF_NODE; + numvalues++; + } + p->valueIndex = i; + p->type = PT_VAR; + } + } else if (!strcmp(buf, "i")) { + name = MALLOC(128); + if (arg->type == PT_PLACEHOLDER) + strcpy(name, arg->funcname); + else if (arg->type == PT_CONSTANT) + (void) sprintf(name, "%d", (int) arg->constant); + else { + fprintf(stderr, "Error: badly formed branch current\n"); + return (NULL); + } +/* printf("getting a device called '%s'\n", name); */ + INPinsert(&name, tables); + for (i = 0; i < numvalues; i++) + if ((types[i] == IF_INSTANCE) && (values[i].uValue == + temp.uValue)) break; + if (i == numvalues) { + if (numvalues) { + values = (IFvalue *) + REALLOC((char *) values, + (numvalues + 1) * sizeof(IFvalue)); + types = (int *) + REALLOC((char *) types, (numvalues + 1) * sizeof(int)); + } else { + values = (IFvalue *) MALLOC(sizeof(IFvalue)); + types = (int *) MALLOC(sizeof(int)); + } + values[i].uValue = (IFuid) name; + types[i] = IF_INSTANCE; + numvalues++; + } + p->valueIndex = i; + p->type = PT_VAR; + } else { + for (i = 0; i < NUM_FUNCS; i++) + if (!strcmp(funcs[i].name, buf)) + break; + + if (i == NUM_FUNCS) { + fprintf(stderr, "Error: no such function '%s'\n", buf); + return (NULL); + } + + p->type = PT_FUNCTION; + p->left = arg; + p->funcname = funcs[i].name; + p->funcnum = funcs[i].number; + p->function = funcs[i].funcptr; + } + + return (p); +} + +/* Number node. */ + +static INPparseNode *mknnode(double number) +{ + struct INPparseNode *p; + + p = (INPparseNode *) MALLOC(sizeof(INPparseNode)); + + p->type = PT_CONSTANT; + p->constant = number; + + return (p); +} + +/* String node. */ + +static INPparseNode *mksnode(char *string) +{ + int i, j; + char buf[128], *s; + INPparseNode *p; + + /* Make sure the case is ok. */ + (void) strcpy(buf, string); + for (s = buf; *s; s++) + if (isupper(*s)) + *s = tolower(*s); + + p = (INPparseNode *) MALLOC(sizeof(INPparseNode)); + + /* First see if it's something special. */ + for (i = 0; i < ft_sim->numSpecSigs; i++) + if (!strcmp(ft_sim->specSigs[i], buf)) + break; + if (i < ft_sim->numSpecSigs) { + for (j = 0; j < numvalues; j++) + if ((types[j] == IF_STRING) && !strcmp(buf, values[i].sValue)) + break; + if (j == numvalues) { + if (numvalues) { + values = (IFvalue *) + REALLOC((char *) values, + (numvalues + 1) * sizeof(IFvalue)); + types = (int *) + REALLOC((char *) types, (numvalues + 1) * sizeof(int)); + } else { + values = (IFvalue *) MALLOC(sizeof(IFvalue)); + types = (int *) MALLOC(sizeof(int)); + } + values[i].sValue = MALLOC(strlen(buf) + 1); + strcpy(values[i].sValue, buf); + types[i] = IF_STRING; + numvalues++; + } + p->valueIndex = i; + p->type = PT_VAR; + return (p); + } + + for (i = 0; i < NUM_CONSTANTS; i++) + if (!strcmp(constants[i].name, buf)) + break; + + if (i == NUM_CONSTANTS) { + /* We'd better save this in case it's part of i(something). */ + p->type = PT_PLACEHOLDER; + p->funcname = string; + } else { + p->type = PT_CONSTANT; + p->constant = constants[i].value; + } + + return (p); +} + +/* The lexical analysis routine. */ + +static PTelement *PTlexer(char **line) +{ + double td; + int err; + static PTelement el; + static char *specials = " \t()^+-*/,"; + static int lasttoken = TOK_END, lasttype; + char *sbuf, *s; + + sbuf = *line; +#ifdef notdef + printf("entering lexer, sbuf = '%s', lastoken = %d, lasttype = %d\n", + sbuf, lasttoken, lasttype); +#endif + while ((*sbuf == ' ') || (*sbuf == '\t') || (*sbuf == '=')) + sbuf++; + + switch (*sbuf) { + case '\0': + el.token = TOK_END; + break; + + case ',': + el.token = TOK_COMMA; + sbuf++; + break; + + case '-': + if ((lasttoken == TOK_VALUE) || (lasttoken == TOK_RPAREN)) + el.token = TOK_MINUS; + else + el.token = TOK_UMINUS; + sbuf++; + break; + + case '+': + el.token = TOK_PLUS; + sbuf++; + break; + + case '*': + el.token = TOK_TIMES; + sbuf++; + break; + + case '/': + el.token = TOK_DIVIDE; + sbuf++; + break; + + case '^': + el.token = TOK_POWER; + sbuf++; + break; + + case '(': + if (((lasttoken == TOK_VALUE) && ((lasttype == TYP_NUM))) || + (lasttoken == TOK_RPAREN)) { + el.token = TOK_END; + } else { + el.token = TOK_LPAREN; + sbuf++; + } + break; + + case ')': + el.token = TOK_RPAREN; + sbuf++; + break; + + default: + if ((lasttoken == TOK_VALUE) || (lasttoken == TOK_RPAREN)) { + el.token = TOK_END; + break; + } + + td = INPevaluate(&sbuf, &err, 1); + if (err == OK) { + el.token = TOK_VALUE; + el.type = TYP_NUM; + el.value.real = td; + } else { + el.token = TOK_VALUE; + el.type = TYP_STRING; + for (s = sbuf; *s; s++) + if (index(specials, *s)) + break; + el.value.string = MALLOC(s - sbuf + 1); + strncpy(el.value.string, sbuf, s - sbuf); + el.value.string[s - sbuf] = '\0'; + sbuf = s; + } + } + + lasttoken = el.token; + lasttype = el.type; + + *line = sbuf; + +/* printf("PTlexer: token = %d, type = %d, left = '%s'\n", + el.token, el.type, sbuf); */ + + return (&el); +} + +#ifdef notdef + +/* Debugging stuff. */ + + +void printTree(INPparseNode *); + +void INPptPrint(char *str, IFparseTree * ptree) +{ + int i; + + printf("%s\n\t", str); + printTree(((INPparseTree *) ptree)->tree); + printf("\n"); + for (i = 0; i < ptree->numVars; i++) { + printf("d / d v%d : ", i); + printTree(((INPparseTree *) ptree)->derivs[i]); + printf("\n"); + } + return; +} + +void printTree(INPparseNode * pt) +{ + switch (pt->type) { + case PT_CONSTANT: + printf("%g", pt->constant); + break; + + case PT_VAR: + printf("v%d", pt->valueIndex); + break; + + case PT_PLUS: + printf("("); + printTree(pt->left); + printf(") + ("); + printTree(pt->right); + printf(")"); + break; + + case PT_MINUS: + printf("("); + printTree(pt->left); + printf(") - ("); + printTree(pt->right); + printf(")"); + break; + + case PT_TIMES: + printf("("); + printTree(pt->left); + printf(") * ("); + printTree(pt->right); + printf(")"); + break; + + case PT_DIVIDE: + printf("("); + printTree(pt->left); + printf(") / ("); + printTree(pt->right); + printf(")"); + break; + + case PT_POWER: + printf("("); + printTree(pt->left); + printf(") ^ ("); + printTree(pt->right); + printf(")"); + break; + + case PT_FUNCTION: + printf("%s (", pt->funcname); + printTree(pt->left); + printf(")"); + break; + + default: + printf("oops"); + break; + } + return; +} + +#endif diff --git a/src/spicelib/parser/inpsymt.c b/src/spicelib/parser/inpsymt.c new file mode 100644 index 000000000..1d4e093e3 --- /dev/null +++ b/src/spicelib/parser/inpsymt.c @@ -0,0 +1,281 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* + * Stuff for the terminal and node symbol tables. + * Defined: INPtabInit, INPinsert, INPtermInsert, INPtabEnd + */ +/* MW. Special INPinsertNofree for routines from spiceif.c and outif.c */ + +#include "ngspice.h" +#include /* Take this out soon. */ +#include "ifsim.h" +#include "iferrmsg.h" +#include "inpdefs.h" +#include "cpstd.h" +#include "fteext.h" +#include "inp.h" + + +static int hash(char *name, int tsize); + +/* Initialize the symbol tables. */ + +INPtables *INPtabInit(int numlines) +{ + INPtables *tab; + + tab = (INPtables *) tmalloc(sizeof(INPtables)); + tab->INPsymtab = (struct INPtab **) tmalloc((numlines / 4 + 1) * + sizeof(struct INPtab *)); + ZERO(tab->INPsymtab, (numlines / 4 + 1) * sizeof(struct INPtab *)); + tab->INPtermsymtab = (struct INPnTab **) tmalloc(numlines * + sizeof(struct INPnTab + *)); + ZERO(tab->INPtermsymtab, numlines * sizeof(struct INPnTab *)); + tab->INPsize = numlines / 4 + 1; + tab->INPtermsize = numlines; + return (tab); +} + +/* insert 'token' into the terminal symbol table */ +/* create a NEW NODE and return a pointer to it in *node */ + +int INPtermInsert(void *ckt, char **token, INPtables * tab, void **node) +{ + int key; + int error; + struct INPnTab *t; + + key = hash(*token, tab->INPtermsize); + for (t = tab->INPtermsymtab[key]; t; t = t->t_next) { + if (!strcmp(*token, t->t_ent)) { + FREE(*token); + *token = t->t_ent; + if (node) + *node = t->t_node; + return (E_EXISTS); + } + } + t = (struct INPnTab *) tmalloc(sizeof(struct INPnTab)); + if (t == (struct INPnTab *) NULL) + return (E_NOMEM); + ZERO(t, struct INPnTab); + error = (*(ft_sim->newNode)) (ckt, &t->t_node, *token); + if (error) + return (error); + if (node) + *node = t->t_node; + t->t_ent = *token; + t->t_next = tab->INPtermsymtab[key]; + tab->INPtermsymtab[key] = t; + return (OK); +} + + +/* insert 'token' into the terminal symbol table */ +/* USE node as the node pointer */ + + +int INPmkTerm(void *ckt, char **token, INPtables * tab, void **node) +{ + int key; + struct INPnTab *t; + + key = hash(*token, tab->INPtermsize); + for (t = tab->INPtermsymtab[key]; t; t = t->t_next) { + if (!strcmp(*token, t->t_ent)) { + FREE(*token); + *token = t->t_ent; + if (node) + *node = t->t_node; + return (E_EXISTS); + } + } + t = (struct INPnTab *) tmalloc(sizeof(struct INPnTab)); + if (t == (struct INPnTab *) NULL) + return (E_NOMEM); + ZERO(t, struct INPnTab); + t->t_node = *node; + t->t_ent = *token; + t->t_next = tab->INPtermsymtab[key]; + tab->INPtermsymtab[key] = t; + return (OK); +} + +/* insert 'token' into the terminal symbol table as a name for ground*/ + +int INPgndInsert(void *ckt, char **token, INPtables * tab, void **node) +{ + int key; + int error; + struct INPnTab *t; + + key = hash(*token, tab->INPtermsize); + for (t = tab->INPtermsymtab[key]; t; t = t->t_next) { + if (!strcmp(*token, t->t_ent)) { + FREE(*token); + *token = t->t_ent; + if (node) + *node = t->t_node; + return (E_EXISTS); + } + } + t = (struct INPnTab *) tmalloc(sizeof(struct INPnTab)); + if (t == (struct INPnTab *) NULL) + return (E_NOMEM); + ZERO(t, struct INPnTab); + error = (*(ft_sim->groundNode)) (ckt, &t->t_node, *token); + if (error) + return (error); + if (node) + *node = t->t_node; + t->t_ent = *token; + t->t_next = tab->INPtermsymtab[key]; + tab->INPtermsymtab[key] = t; + return (OK); +} + +/* retrieve 'token' from the symbol table */ + +int INPretrieve(char **token, INPtables * tab) +{ + struct INPtab *t; + int key; + + key = hash(*token, tab->INPsize); + for (t = tab->INPsymtab[key]; t; t = t->t_next) + if (!strcmp(*token, t->t_ent)) { + *token = t->t_ent; + return (OK); + } + return (E_BADPARM); +} + + +/* insert 'token' into the symbol table */ + +int INPinsert(char **token, INPtables * tab) +{ + struct INPtab *t; + int key; + + key = hash(*token, tab->INPsize); + for (t = tab->INPsymtab[key]; t; t = t->t_next) + if (!strcmp(*token, t->t_ent)) { + FREE(*token); + *token = t->t_ent; + return (E_EXISTS); + } + t = (struct INPtab *) tmalloc(sizeof(struct INPtab)); + if (t == (struct INPtab *) NULL) + return (E_NOMEM); + ZERO(t, struct INPtab); + t->t_ent = *token; + t->t_next = tab->INPsymtab[key]; + tab->INPsymtab[key] = t; + return (OK); +} + + +/* MW. insert 'token' into the symbol table but no free() token pointer. +* Calling routine should take care for this */ + +int INPinsertNofree(char **token, INPtables * tab) +{ + struct INPtab *t; + int key; + + key = hash(*token, tab->INPsize); + for (t = tab->INPsymtab[key]; t; t = t->t_next) + if (!strcmp(*token, t->t_ent)) { + + /* MW. We can't touch memory pointed by token now */ + *token = t->t_ent; + return (E_EXISTS); + } + t = (struct INPtab *) tmalloc(sizeof(struct INPtab)); + if (t == (struct INPtab *) NULL) + return (E_NOMEM); + ZERO(t, struct INPtab); + t->t_ent = *token; + t->t_next = tab->INPsymtab[key]; + tab->INPsymtab[key] = t; + return (OK); +} + +/* remove 'token' from the symbol table */ +int INPremove(char *token, INPtables * tab) +{ + struct INPtab *t, **prevp; + int key; + + key = hash(token, tab->INPsize); + prevp = &tab->INPsymtab[key]; + for (t = *prevp; t && token != t->t_ent; t = t->t_next) + prevp = &t->t_next; + if (!t) + return OK; + + *prevp = t->t_next; + tfree(t->t_ent); + tfree(t); + + return OK; +} + +/* remove 'token' from the symbol table */ +int INPremTerm(char *token, INPtables * tab) +{ + struct INPnTab *t, **prevp; + int key; + + key = hash(token, tab->INPtermsize); + prevp = &tab->INPtermsymtab[key]; + for (t = *prevp; t && token != t->t_ent; t = t->t_next) + prevp = &t->t_next; + if (!t) + return OK; + + *prevp = t->t_next; + tfree(t->t_ent); + tfree(t); + + return OK; +} + +/* Free the space used by the symbol tables. */ + +void INPtabEnd(INPtables * tab) +{ + struct INPtab *t, *lt; + struct INPnTab *n, *ln; + int i; + + for (i = 0; i < tab->INPsize; i++) + for (t = tab->INPsymtab[i]; t; t = lt) { + lt = t->t_next; + FREE(t); /* But not t_ent ! */ + } + FREE(tab->INPsymtab); + for (i = 0; i < tab->INPtermsize; i++) + for (n = tab->INPtermsymtab[i]; n; n = ln) { + ln = n->t_next; + FREE(n); /* But not t_ent ! */ + } + FREE(tab->INPtermsymtab); + FREE(tab); + return; +} + +static int hash(char *name, int tsize) +{ + char *s; + register int i = 0; + + for (s = name; *s; s++) + i += *s; + return (i % tsize); +} diff --git a/src/spicelib/parser/inptyplk.c b/src/spicelib/parser/inptyplk.c new file mode 100644 index 000000000..13efc98c3 --- /dev/null +++ b/src/spicelib/parser/inptyplk.c @@ -0,0 +1,28 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +/* look up the 'type' in the device description struct and return the + * appropriate strchr for the device found, or -1 for not found + */ + +#include "ngspice.h" +#include "inpdefs.h" +#include "cpdefs.h" +#include "fteext.h" +#include "ifsim.h" +#include "inp.h" + +int INPtypelook(char *type) +{ + + int i; + for (i = 0; i < ft_sim->numDevices; i++) { + if (strcmp(type, (*(ft_sim->devices)[i]).name) == 0) { + /*found the device - return it */ + return i; + } + } + return -1; +} diff --git a/src/spicelib/parser/ptfuncs.c b/src/spicelib/parser/ptfuncs.c new file mode 100644 index 000000000..cb2fe926c --- /dev/null +++ b/src/spicelib/parser/ptfuncs.c @@ -0,0 +1,246 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* + * All the functions used in the parse tree. These functions return HUGE + * if their argument is out of range. + */ + +#include +#include "ngspice.h" +#include +#include "fteext.h" +#include "ifsim.h" +#include "inpptree.h" +#include "inp.h" + +/* XXX These should be in math.h */ + + +#ifndef HAVE_ATANH +extern double asinh(), acosh(), atanh(); +#endif + +double PTfudge_factor; + +#define MODULUS(NUM,LIMIT) ((NUM) - ((int) ((NUM) / (LIMIT))) * (LIMIT)) + +double +PTabs(double arg) +{ + return arg >= 0.0 ? arg : -arg; +} + +double +PTsgn(double arg) +{ + return arg > 0.0 ? 1.0 : arg < 0.0 ? -1.0 : 0.0; +} + +double +PTplus(double arg1, double arg2) +{ + return (arg1 + arg2); +} + +double +PTminus(double arg1, double arg2) +{ + return (arg1 - arg2); +} + +double +PTtimes(double arg1, double arg2) +{ + return (arg1 * arg2); +} + +double +PTdivide(double arg1, double arg2) +{ + if (arg2 >= 0.0) + arg2 += PTfudge_factor; + else + arg2 -= PTfudge_factor; + + if (arg2 == 0.0) + return (HUGE); + + return (arg1 / arg2); +} + +double +PTpower(double arg1, double arg2) +{ + if (arg1 < 0.0) { + if (fabs(arg2 - ((int) arg2)) / (arg2 + 0.001) < 0.000001) { + arg2 = (int) arg2; + } else { + arg1 = -arg1; + } + } + return (pow(arg1, arg2)); +} + +double +PTacos(double arg) +{ + return (acos(arg)); +} + +double +PTacosh(double arg) +{ +#ifdef HAVE_ACOSH + return (acosh(arg)); +#else + if (arg < 1.0) + arg = 1.0; + return (log(arg + sqrt(arg*arg-1.0))); +#endif +} + +double +PTasin(double arg) +{ + return (asin(arg)); +} + +double +PTasinh(double arg) +{ +#ifdef HAVE_ASINH + return (asinh(arg)); +#else + return log(arg + sqrt(arg * arg + 1.0)); +#endif +} + +double +PTatan(double arg) +{ + return (atan(arg)); +} + +double +PTatanh(double arg) +{ +#ifdef HAVE_ATANH + return (atanh(arg)); +#else + if (arg < -1.0) + arg = -1.0 + PTfudge_factor + 1e-10; + else if (arg > 1.0) + arg = 1.0 - PTfudge_factor - 1e-10; + return (log((1.0 + arg) / (1.0 - arg)) / 2.0); +#endif +} + +double +PTustep(double arg) +{ + if (arg < 0.0) + return 0.0; + else if (arg > 0.0) + return 1.0; + else + return 0.5; /* Ick! */ +} + +/* MW. PTcif is like "C" if - 0 for (arg<=0), 1 elsewhere */ + +double +PTustep2(double arg) +{ + if (arg <= 0.0) + return 0.0; + else if (arg <= 1.0) + return arg; + else //if (arg > 1.0) + return 1.0; +} + + +double +PTuramp(double arg) +{ + if (arg < 0.0) + return 0.0; + else + return arg; +} + +double +PTcos(double arg) +{ + return (cos(MODULUS(arg, 2 * M_PI))); +} + +double +PTcosh(double arg) +{ + return (cosh(arg)); +} + +double +PTexp(double arg) +{ + return (exp(arg)); +} + +double +PTln(double arg) +{ + if (arg < 0.0) + return (HUGE); + return (log(arg)); +} + +double +PTlog(double arg) +{ + if (arg <= 0.0) + return (HUGE); + return (log10(arg)); +} + +double +PTsin(double arg) +{ + return (sin(MODULUS(arg, 2 * M_PI))); +} + +double +PTsinh(double arg) +{ + return (sinh(arg)); +} + +double +PTsqrt(double arg) +{ + if (arg < 0.0) + return (HUGE); + return (sqrt(arg)); +} + +double +PTtan(double arg) +{ + return (tan(MODULUS(arg, M_PI))); +} + +double +PTtanh(double arg) +{ + return (tanh(arg)); +} + +double +PTuminus(double arg) +{ + return (- arg); +} + diff --git a/src/spicelib/parser/sperror.c b/src/spicelib/parser/sperror.c new file mode 100644 index 000000000..bd731dedb --- /dev/null +++ b/src/spicelib/parser/sperror.c @@ -0,0 +1,119 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +/* + * provide the error message appropriate for the given error code + */ + +#include "ngspice.h" +#include +#include "fteext.h" +#include "sperror.h" +#include "cktdefs.h" +#include "ifsim.h" +#include "inp.h" + +const char *SPerror(int type) +{ + char *msg; + + switch (type) { + case E_PAUSE: + msg = "pause requested"; + break; + case E_INTERN: + msg = "impossible error - can't occur"; + break; + case E_EXISTS: + msg = "device already exists, existing one being used"; + break; + case E_NODEV: + msg = "no such device"; + break; + case E_NOMOD: + msg = "no such model"; + break; + case E_NOTERM: + msg = "no such terminal on this device"; + break; + case E_BADPARM: + msg = "no such parameter on this device"; + break; + case E_NOMEM: + msg = "out of memory"; + break; + case E_NODECON: + msg = "node already connected; connection replaced"; + break; + case E_UNSUPP: + msg = "operation not supported"; + break; + case E_PARMVAL: + msg = "parameter value out of range or the wrong type"; + break; + case E_BADMATRIX: + msg = "matrix can't be decomposed as is"; + break; + case E_SINGULAR: + msg = "matrix is singular"; + break; + case E_ITERLIM: + msg = "iteration limit reached"; + break; + case E_ORDER: + msg = "unsupported integration order"; + break; + case E_METHOD: + msg = "unsupported integration method"; + break; + case E_TIMESTEP: + msg = "timestep too small"; + break; + case E_XMISSIONLINE: + msg = "transmission lines not supported by pole-zero"; + break; + case E_MAGEXCEEDED: + msg = "magnitude overflow"; + break; + case E_SHORT: + msg = "input or output shorted"; + break; + case E_INISOUT: + msg = "transfer function is 1"; + break; + case E_NODISTO: + msg = "distortion analysis not present"; + break; + case E_NONOISE: + msg = "noise analysis not present"; + break; + case E_NOANAL: + msg = "no such analysis type"; + break; + case E_NOCHANGE: + msg = "unsupported action; no change made"; + break; + case E_NOTFOUND: + msg = "not found"; + break; + case E_NOACINPUT: + msg = "ac input not found"; + break; + case E_NOF2SRC: + msg = "no F2 source for IM disto analysis"; + break; +#ifdef PARALLEL_ARCH + case E_MULTIERR: + msg = "Multiple errors detected by parallel machine"; + break; +#endif /* PARALLEL_ARCH */ + case OK: + return (NULL); + default: + msg = "Unknown error code"; + } + + return msg; +} diff --git a/src/spinit b/src/spinit new file mode 100644 index 000000000..31c8095d3 --- /dev/null +++ b/src/spinit @@ -0,0 +1,4 @@ +* Standard spice and nutmeg init file +alias exit quit +alias acct rusage all +set x11lineararcs diff --git a/src/tcl/ChangeLog b/src/tcl/ChangeLog new file mode 100755 index 000000000..a7de44579 --- /dev/null +++ b/src/tcl/ChangeLog @@ -0,0 +1,34 @@ +25/07/2002: + * Modified configure/Makefiles so use --enable-tcl to make module + * Added option --enable-cluster to configure for cluster version + * Swig no longer needed to compile +23/07/2002: + * Added display device Tk plot + * Added function bltplot +17/04/2002: + * Merged a version of cluster spice. +26/03/2002: + * New TCL function lastVector. +19/02/2002: + * User nodes and codemodels now work in DCtrans analysis, + calculated results are now correct. + * Fixed bug where the first timestep always seems to fail to converge + after a resume or a step, thus cutting delta. +30/01/2002: + * Precompiled Opus/XSpice models are now supported with + --enable-xspice flag, load them using codemodel "opus spice module" +22/01/2002: + * Fixed parameters being ignored when mosfet model is not found +16/01/2002: + * Fixed crash when a mosfet model is not found +In the mists of time: + * Changed spicelib/parser/inpgtok.c to allow / * ^ in node names (/ needed for ext2spice) + * Modifed files in + spicelib/analysis/(acan.c, dctran.c, dctrcurv.c, noisean.c), frontend/outitf.c, + frontend/runcoms.c, frontend/runcoms2.c + so rawfiles continue to be written to after a pause then a resume + * Small modification to main.c to make the struct nutmeginfo global, so tclspice can use it. + * Added ifdefed code to frontend/outitf.c which links output to tclspice. + * Modified main.c and frontend/inp.c so .save lines are always processed + * ifdefed code in misc/alloc.c so the functions use Tcl_Mutex to stop memory allocation conflicts. + * Fixed crash in com_resume() when run without circuit loaded diff --git a/src/tcl/README b/src/tcl/README new file mode 100755 index 000000000..a471ab4b8 --- /dev/null +++ b/src/tcl/README @@ -0,0 +1,170 @@ +Spice Tcl module +$Id$ +DESCRIPTION + +Contained in this package is the source code for a spice tcl module and ng-spice-rework-14. +It allows you run spice commands in tcl and run the spice simulator in the background +so you can manipulate the results while spice is running. + +THANKS: + +Ng-Spice at http://ngspice.sourceforge.net for the spice simulator + +ScriptEDA ( http://www-cad.eecs.berkeley.edu/~pinhong/scriptEDA ) for the idea and examples. + +INSTALLATION + +Requirements: + ngspice, included (only tested with ng-spice-rework-13 and 14, should work with all rework versions) + tcl WITH thread support compiled in (tested with tcl-8.3.3-65 and tcl8.3.4) + BTL for tcl (tested with blt2.4y) + pthreads (most modern OS's have this) + +Installation: + This package contains the ng-spice-rework-14 source code, which has been slightly modifed, and the tcl module source. + The spice source is contained in the ng-spice-rework directory. + Tcl modules's documentation is in the ng-spice-rework/src/tcl directory + + Please hide libgc.so (the garbage collector library), if you have it. You can put it back afterwards! + This is because you don't want tclspice to compile with it included! + + Also if you want to run spice in the background you need to recompile + tcl and tk to enable thread support if they haven't got it enabled already (redhat packages haven't). + If you don't then tclspice will crash frequently!!!! + + The install commands are: + From the root directory of the source: + ./configure --enable-tcl --enable-experimental --enable-xspice --disable-shared + make tcl + And as root: + make tcl_install + +USAGE + +example: + +$tclsh + +%package require spice + (to load the module) + +Then you can run commands either by typing spice command directly or by typing spice +For example: + %spice::version + %spice::source ./example.cir + %spice::bg run + %spice::halt + %spice::show + %spice::plot_nvars 0 + %spice::plot_variables 0 + %spice::plot_datapoints 0 + %spice::bg resume + %spice::halt + %exit + +Commands availiabe: + + spice has it's own namespace (spice::) which can be imported. + Although there are a few conflicts, so not all commands are imported. + + + spice::spice + runs the spicified spice command in the foreground + spice::bg + runs the spice command in the background + All spice commands should be recognised + spice::halt + Stops(or attempts to) a spice background command (like run) (it simulates a ^C) + + spice::running + returns 1 if a background process is running, 0 otherwise + + spice::get_output script ?stderr? + runs the tcl script "script", catching std_out and maping it to the return value. + It can also catch the std_err and put it into the stderr variable. + + spice::get_param device param + Returns the parameter of the device + + spice::spice_data + Returns the names and types of avaliable spice + variables + {name type} {name type} ... {name type} + + spice::spice_header + Returns the current run's title, analysis name, date, and the number of signals as follows: + {title ??} {name ???} {date ????} {variables ???} + + spice::delta ?value? + Sets the value of delta to the given value, if given. + It returns the current setting of delta + + spice::maxstep ?value? + Same as spice::delta but for the maximum stepsize allowed + + variables: + + spice::steps_completed + The number of simulation steps done so far. + +The following concern the BLT vectors generated; + + functions: + spice::spicetoblt vecName signal ?start? ?end? + Sets the blt vector vecName with the contents of the spice signal, signal, + using the optional start and end index. + + spice::lastVector vecName + Sets the blt vector vecName to contain the last spice state vector + + variables: + spice::blt_vnum + The number of signals avalible + +The following only work if there is a plot stored; + + spice::plot_variables plot + returns a list of variables in plot "plot" + plot is from 0-numofplots, newest plot being 0. + + spice::plot_get_value name plot index + returns value of varable "name" in plot "plot", at position "index" + + spice::plot_datapoints plot + returns number of time steps saved so far + + spice::plot_title plot + returns plot title + + spice::plot_date plot + returns date string + + spice::plot_name plot + returns plot name + + spice::plot_nvars plot + returns number of variables in the plot + +Plotting functions; + + spice::plot + The standard plot function has been wrapped to a Tk canvas ".c" See Tcl source in + pkgIndex.tcl The callback functions are named gr_*, modify/override at will. + spice::bltplot + Instead of plotting: For each pair of vectors to plot spice::gr_Plot is called, + "proc spice_gr_Plot { Xname Xtype Xunits Yname Ytype Yunits }" which you can override + With the static Blt vectors "spice::X_Data" and "spice::Y_Data" containing the plot data. + WARNING: + If any of the Tcl callback functions cause an error then a crash may occour as tcl + overwrites random data in the spice code. Not sure why. + +TODO & BUGS + +1) plot and iplot don't work: window opens then tclsh stops, Xserver doesn't respond to spice requests + They aren't really needed anymore, as you now have the blt vectors to play with, + and the Tk plot output and bltplot output. +2) Spice prints to stdout, unavoidable, sorry if it mucks up your commandline +3) tclreadline doesn't like this module very much + +Stefan Jones + diff --git a/src/tcl/example.cir b/src/tcl/example.cir new file mode 100755 index 000000000..b31bb0993 --- /dev/null +++ b/src/tcl/example.cir @@ -0,0 +1,587 @@ +TITLE: proj1.cir.cir - Rotary Traveling Wave Oscillator +.control +set filetype=ascii +.endc + +VDD0 VDD0 VDD DC 0 +VSS0 VSS0 0 DC 0 +VDD_A0 VDD_A0 VDD0 DC 0 +VSS_A0 VSS_A0 VSS0 DC 0 +VDD_B0 VDD_B0 VDD0 DC 0 +VSS_B0 VSS_B0 VSS0 DC 0 +LA0 A0 LCA0 3.69030941553353e-11 +RA0 LCA0 A1 0.266535044422507 +LB0 B0 LCB0 3.69030941553353e-11 +RB0 LCB0 B1 0.266535044422507 +C0 A1 B1 2.50418376625721e-14 +MNA0 B0 A0 VSS_B0 VSS_B0 Nmod L=2.53696435353243e-07 W= ++4.24857778403814e-05 AD=3.125e-11 AS=3.125e-11 PD= ++8.49715556807627e-05 PS=8.49715556807627e-05 NQSMOD=1 +MPA0 B0 A0 VDD_B0 VDD_B0 Pmod L=2.55343565546106e-07 W= ++0.000101772203908557 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000203544407817114 PS=0.000203544407817114 NQSMOD=1 +MNB0 A0 B0 VSS_A0 VSS_A0 Nmod L=2.53941602497219e-07 W= ++4.10652659629401e-05 AD=3.125e-11 AS=3.125e-11 PD= ++8.21305319258802e-05 PS=8.21305319258802e-05 NQSMOD=1 +MPB0 A0 B0 VDD_A0 VDD_A0 Pmod L=2.52010168145607e-07 W= ++0.000103533977891464 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000207067955782928 PS=0.000207067955782928 NQSMOD=1 +LA1 A1 LCA1 3.69030941553353e-11 +RA1 LCA1 A2 0.266535044422507 +LB1 B1 LCB1 3.69030941553353e-11 +RB1 LCB1 B2 0.266535044422507 +C1 A2 B2 2.50418376625721e-14 +MNA1 B1 A1 0 0 Nmod L=2.52370578161099e-07 W=4.12246995102289e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.24493990204578e-05 PS= ++8.24493990204578e-05 NQSMOD=1 +MPA1 B1 A1 VDD VDD Pmod L=2.45709468983316e-07 W=0.000103710764679465 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000207421529358929 PS= ++0.000207421529358929 NQSMOD=1 +MNB1 A1 B1 0 0 Nmod L=2.48115895523017e-07 W=4.26306134285554e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.52612268571108e-05 PS= ++8.52612268571108e-05 NQSMOD=1 +MPB1 A1 B1 VDD VDD Pmod L=2.55265156192223e-07 W=0.000102043840486507 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000204087680973014 PS= ++0.000204087680973014 NQSMOD=1 +LA2 A2 LCA2 3.69030941553353e-11 +RA2 LCA2 A3 0.266535044422507 +LB2 B2 LCB2 3.69030941553353e-11 +RB2 LCB2 B3 0.266535044422507 +C2 A3 B3 2.50418376625721e-14 +MNA2 B2 A2 0 0 Nmod L=2.53484220592882e-07 W=4.16915225420459e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.33830450840917e-05 PS= ++8.33830450840917e-05 NQSMOD=1 +MPA2 B2 A2 VDD VDD Pmod L=2.44256748076514e-07 W=0.00010549295960702 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000210985919214039 PS= ++0.000210985919214039 NQSMOD=1 +MNB2 A2 B2 0 0 Nmod L=2.48805892712811e-07 W=4.15734692647458e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.31469385294916e-05 PS= ++8.31469385294916e-05 NQSMOD=1 +MPB2 A2 B2 VDD VDD Pmod L=2.54004987710956e-07 W=0.00010229621219808 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.00020459242439616 PS= ++0.00020459242439616 NQSMOD=1 +LA3 A3 LCA3 3.69030941553353e-11 +RA3 LCA3 A4 0.266535044422507 +LB3 B3 LCB3 3.69030941553353e-11 +RB3 LCB3 B4 0.266535044422507 +C3 A4 B4 2.50418376625721e-14 +MNA3 B3 A3 0 0 Nmod L=2.54307430347219e-07 W=4.11339076756089e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.22678153512179e-05 PS= ++8.22678153512179e-05 NQSMOD=1 +MPA3 B3 A3 VDD VDD Pmod L=2.52369109463781e-07 W=0.000103371681055656 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000206743362111311 PS= ++0.000206743362111311 NQSMOD=1 +MNB3 A3 B3 0 0 Nmod L=2.4960708801709e-07 W=4.21794611046917e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.43589222093833e-05 PS= ++8.43589222093833e-05 NQSMOD=1 +MPB3 A3 B3 VDD VDD Pmod L=2.53834779766428e-07 W=0.000105556314711602 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000211112629423204 PS= ++0.000211112629423204 NQSMOD=1 +LA4 A4 LCA4 3.69030941553353e-11 +RA4 LCA4 A5 0.266535044422507 +LB4 B4 LCB4 3.69030941553353e-11 +RB4 LCB4 B5 0.266535044422507 +C4 A5 B5 2.50418376625721e-14 +MNA4 B4 A4 0 0 Nmod L=2.48091656083177e-07 W=4.11207568141106e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.22415136282211e-05 PS= ++8.22415136282211e-05 NQSMOD=1 +MPA4 B4 A4 VDD VDD Pmod L=2.47723605289033e-07 W=0.000103463392309261 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000206926784618522 PS= ++0.000206926784618522 NQSMOD=1 +MNB4 A4 B4 0 0 Nmod L=2.49254771880382e-07 W=4.25122425012226e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.50244850024452e-05 PS= ++8.50244850024452e-05 NQSMOD=1 +MPB4 A4 B4 VDD VDD Pmod L=2.49689766979065e-07 W=0.000103227993619608 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000206455987239216 PS= ++0.000206455987239216 NQSMOD=1 +LA5 A5 LCA5 3.69030941553353e-11 +RA5 LCA5 A6 0.266535044422507 +LB5 B5 LCB5 3.69030941553353e-11 +RB5 LCB5 B6 0.266535044422507 +C5 A6 B6 2.50418376625721e-14 +MNA5 B5 A5 0 0 Nmod L=2.53960031106522e-07 W=4.1129961792588e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.22599235851759e-05 PS= ++8.22599235851759e-05 NQSMOD=1 +MPA5 B5 A5 VDD VDD Pmod L=2.47418707088064e-07 W=0.000101621693062467 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000203243386124935 PS= ++0.000203243386124935 NQSMOD=1 +MNB5 A5 B5 0 0 Nmod L=2.49659687529522e-07 W=4.2524931640785e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.50498632815701e-05 PS= ++8.50498632815701e-05 NQSMOD=1 +MPB5 A5 B5 VDD VDD Pmod L=2.46328059754468e-07 W=0.000102061546065548 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000204123092131096 PS= ++0.000204123092131096 NQSMOD=1 +LA6 A6 LCA6 3.69030941553353e-11 +RA6 LCA6 A7 0.266535044422507 +LB6 B6 LCB6 3.69030941553353e-11 +RB6 LCB6 B7 0.266535044422507 +C6 A7 B7 2.50418376625721e-14 +MNA6 B6 A6 0 0 Nmod L=2.54326804653788e-07 W=4.17332976706085e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.34665953412171e-05 PS= ++8.34665953412171e-05 NQSMOD=1 +MPA6 B6 A6 VDD VDD Pmod L=2.48727427835127e-07 W=0.000103244611103459 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000206489222206918 PS= ++0.000206489222206918 NQSMOD=1 +MNB6 A6 B6 0 0 Nmod L=2.49697035135609e-07 W=4.23570035518e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.47140071036001e-05 PS= ++8.47140071036001e-05 NQSMOD=1 +MPB6 A6 B6 VDD VDD Pmod L=2.48995485890626e-07 W=0.000103695454759978 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000207390909519956 PS= ++0.000207390909519956 NQSMOD=1 +LA7 A7 LCA7 3.69030941553353e-11 +RA7 LCA7 A8 0.266535044422507 +LB7 B7 LCB7 3.69030941553353e-11 +RB7 LCB7 B8 0.266535044422507 +C7 A8 B8 2.50418376625721e-14 +MNA7 B7 A7 0 0 Nmod L=2.53418975114981e-07 W=4.06421756574473e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.12843513148946e-05 PS= ++8.12843513148946e-05 NQSMOD=1 +MPA7 B7 A7 VDD VDD Pmod L=2.4471861043622e-07 W=0.000104600862141835 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.00020920172428367 PS= ++0.00020920172428367 NQSMOD=1 +MNB7 A7 B7 0 0 Nmod L=2.50159056393584e-07 W=4.06845582724173e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.13691165448345e-05 PS= ++8.13691165448345e-05 NQSMOD=1 +MPB7 A7 B7 VDD VDD Pmod L=2.55032245177227e-07 W=0.000106482118141681 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000212964236283363 PS= ++0.000212964236283363 NQSMOD=1 +LA8 A8 LCA8 3.69030941553353e-11 +RA8 LCA8 A9 0.266535044422507 +LB8 B8 LCB8 3.69030941553353e-11 +RB8 LCB8 B9 0.266535044422507 +C8 A9 B9 2.50418376625721e-14 +MNA8 B8 A8 0 0 Nmod L=2.45729547191971e-07 W=4.18266198665335e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.3653239733067e-05 PS=8.3653239733067e-05 ++NQSMOD=1 +MPA8 B8 A8 VDD VDD Pmod L=2.45156004861421e-07 W=0.000101593205477244 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000203186410954489 PS= ++0.000203186410954489 NQSMOD=1 +MNB8 A8 B8 0 0 Nmod L=2.49014342219656e-07 W=4.14314219478801e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.28628438957603e-05 PS= ++8.28628438957603e-05 NQSMOD=1 +MPB8 A8 B8 VDD VDD Pmod L=2.50396673007567e-07 W=0.000103029640740115 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.00020605928148023 PS= ++0.00020605928148023 NQSMOD=1 +LA9 A9 LCA9 3.69030941553353e-11 +RA9 LCA9 A10 0.266535044422507 +LB9 B9 LCB9 3.69030941553353e-11 +RB9 LCB9 B10 0.266535044422507 +C9 A10 B10 2.50418376625721e-14 +MNA9 B9 A9 0 0 Nmod L=2.51066307645916e-07 W=4.17044186844862e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.34088373689724e-05 PS= ++8.34088373689724e-05 NQSMOD=1 +MPA9 B9 A9 VDD VDD Pmod L=2.4945438501494e-07 W=0.000104601836030031 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000209203672060063 PS= ++0.000209203672060063 NQSMOD=1 +MNB9 A9 B9 0 0 Nmod L=2.56178041422984e-07 W=4.17990098329256e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.35980196658511e-05 PS= ++8.35980196658511e-05 NQSMOD=1 +MPB9 A9 B9 VDD VDD Pmod L=2.5274010042983e-07 W=0.000103578149162769 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000207156298325537 PS= ++0.000207156298325537 NQSMOD=1 +LA10 A10 LCA10 3.69030941553353e-11 +RA10 LCA10 A11 0.266535044422507 +LB10 B10 LCB10 3.69030941553353e-11 +RB10 LCB10 B11 0.266535044422507 +C10 A11 B11 2.50418376625721e-14 +MNA10 B10 A10 0 0 Nmod L=2.45772611943267e-07 W=4.24345922952649e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.48691845905299e-05 PS= ++8.48691845905299e-05 NQSMOD=1 +MPA10 B10 A10 VDD VDD Pmod L=2.55544710347746e-07 W= ++0.000105625826497323 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000211251652994645 PS=0.000211251652994645 NQSMOD=1 +MNB10 A10 B10 0 0 Nmod L=2.55886308364338e-07 W=4.0850956346516e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.17019126930321e-05 PS= ++8.17019126930321e-05 NQSMOD=1 +MPB10 A10 B10 VDD VDD Pmod L=2.44778614470725e-07 W= ++0.000105511594248206 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000211023188496411 PS=0.000211023188496411 NQSMOD=1 +LA11 A11 LCA11 3.69030941553353e-11 +RA11 LCA11 A12 0.266535044422507 +LB11 B11 LCB11 3.69030941553353e-11 +RB11 LCB11 B12 0.266535044422507 +C11 A12 B12 2.50418376625721e-14 +MNA11 B11 A11 0 0 Nmod L=2.4768739676619e-07 W=4.14724461551725e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.29448923103449e-05 PS= ++8.29448923103449e-05 NQSMOD=1 +MPA11 B11 A11 VDD VDD Pmod L=2.46276216123912e-07 W= ++0.000101782633723501 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000203565267447002 PS=0.000203565267447002 NQSMOD=1 +MNB11 A11 B11 0 0 Nmod L=2.54985612770668e-07 W=4.24608643314108e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.49217286628216e-05 PS= ++8.49217286628216e-05 NQSMOD=1 +MPB11 A11 B11 VDD VDD Pmod L=2.45772463970764e-07 W= ++0.000106109588792745 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.00021221917758549 PS=0.00021221917758549 NQSMOD=1 +LA12 A12 LCA12 3.69030941553353e-11 +RA12 LCA12 A13 0.266535044422507 +LB12 B12 LCB12 3.69030941553353e-11 +RB12 LCB12 B13 0.266535044422507 +C12 A13 B13 2.50418376625721e-14 +MNA12 B12 A12 0 0 Nmod L=2.45480481009462e-07 W=4.20858793029857e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.41717586059714e-05 PS= ++8.41717586059714e-05 NQSMOD=1 +MPA12 B12 A12 VDD VDD Pmod L=2.48462320158069e-07 W= ++0.00010650127744954 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.00021300255489908 PS=0.00021300255489908 NQSMOD=1 +MNB12 A12 B12 0 0 Nmod L=2.51992945030792e-07 W=4.17981435096244e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.35962870192489e-05 PS= ++8.35962870192489e-05 NQSMOD=1 +MPB12 A12 B12 VDD VDD Pmod L=2.49941922576661e-07 W= ++0.0001044851795426 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000208970359085199 PS=0.000208970359085199 NQSMOD=1 +LA13 A13 LCA13 3.69030941553353e-11 +RA13 LCA13 A14 0.266535044422507 +LB13 B13 LCB13 3.69030941553353e-11 +RB13 LCB13 B14 0.266535044422507 +C13 A14 B14 2.50418376625721e-14 +MNA13 B13 A13 0 0 Nmod L=2.51146190542173e-07 W=4.23276196447018e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.46552392894035e-05 PS= ++8.46552392894035e-05 NQSMOD=1 +MPA13 B13 A13 VDD VDD Pmod L=2.46359362747576e-07 W= ++0.00010249565409785 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.0002049913081957 PS=0.0002049913081957 NQSMOD=1 +MNB13 A13 B13 0 0 Nmod L=2.44656485453628e-07 W=4.11044634633624e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.22089269267248e-05 PS= ++8.22089269267248e-05 NQSMOD=1 +MPB13 A13 B13 VDD VDD Pmod L=2.56119611942636e-07 W= ++0.0001064085618438 AD=7.8125e-11 AS=7.8125e-11 PD=0.0002128171236876 ++PS=0.0002128171236876 NQSMOD=1 +LA14 A14 LCA14 3.69030941553353e-11 +RA14 LCA14 A15 0.266535044422507 +LB14 B14 LCB14 3.69030941553353e-11 +RB14 LCB14 B15 0.266535044422507 +C14 A15 B15 2.50418376625721e-14 +MNA14 B14 A14 0 0 Nmod L=2.47663439668801e-07 W=4.20889991075918e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.41779982151835e-05 PS= ++8.41779982151835e-05 NQSMOD=1 +MPA14 B14 A14 VDD VDD Pmod L=2.51252450429323e-07 W= ++0.000103622229824819 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000207244459649638 PS=0.000207244459649638 NQSMOD=1 +MNB14 A14 B14 0 0 Nmod L=2.5044796612668e-07 W=4.24685059762319e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.49370119524638e-05 PS= ++8.49370119524638e-05 NQSMOD=1 +MPB14 A14 B14 VDD VDD Pmod L=2.4786360459861e-07 W= ++0.000104258615459431 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000208517230918863 PS=0.000208517230918863 NQSMOD=1 +LA15 A15 LCA15 3.69030941553353e-11 +RA15 LCA15 A16 0.266535044422507 +LB15 B15 LCB15 3.69030941553353e-11 +RB15 LCB15 B16 0.266535044422507 +C15 A16 B16 2.50418376625721e-14 +MNA15 B15 A15 0 0 Nmod L=2.5213362488047e-07 W=4.26610931467994e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.53221862935989e-05 PS= ++8.53221862935989e-05 NQSMOD=1 +MPA15 B15 A15 VDD VDD Pmod L=2.44411053097269e-07 W= ++0.000104344399065411 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000208688798130821 PS=0.000208688798130821 NQSMOD=1 +MNB15 A15 B15 0 0 Nmod L=2.44947739168727e-07 W=4.18061319080677e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.36122638161354e-05 PS= ++8.36122638161354e-05 NQSMOD=1 +MPB15 A15 B15 VDD VDD Pmod L=2.45133067349567e-07 W= ++0.000103673770597555 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.00020734754119511 PS=0.00020734754119511 NQSMOD=1 +LA16 A16 LCA16 3.69030941553353e-11 +RA16 LCA16 A17 0.266535044422507 +LB16 B16 LCB16 3.69030941553353e-11 +RB16 LCB16 B17 0.266535044422507 +C16 A17 B17 2.50418376625721e-14 +MNA16 B16 A16 0 0 Nmod L=2.5558903414348e-07 W=4.23651981762607e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.47303963525215e-05 PS= ++8.47303963525215e-05 NQSMOD=1 +MPA16 B16 A16 VDD VDD Pmod L=2.46968507923118e-07 W= ++0.000101577430536373 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000203154861072746 PS=0.000203154861072746 NQSMOD=1 +MNB16 A16 B16 0 0 Nmod L=2.52441475326891e-07 W=4.0963445615255e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.192689123051e-05 PS= ++8.192689123051e-05 NQSMOD=1 +MPB16 A16 B16 VDD VDD Pmod L=2.49958772476576e-07 W= ++0.000102341104143712 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000204682208287424 PS=0.000204682208287424 NQSMOD=1 +LA17 A17 LCA17 3.69030941553353e-11 +RA17 LCA17 A18 0.266535044422507 +LB17 B17 LCB17 3.69030941553353e-11 +RB17 LCB17 B18 0.266535044422507 +C17 A18 B18 2.50418376625721e-14 +MNA17 B17 A17 0 0 Nmod L=2.46623947628415e-07 W=4.07033737509309e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.14067475018618e-05 PS= ++8.14067475018618e-05 NQSMOD=1 +MPA17 B17 A17 VDD VDD Pmod L=2.52274212428759e-07 W= ++0.000105423152156798 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000210846304313596 PS=0.000210846304313596 NQSMOD=1 +MNB17 A17 B17 0 0 Nmod L=2.51233452024547e-07 W=4.12815452669714e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.25630905339429e-05 PS= ++8.25630905339429e-05 NQSMOD=1 +MPB17 A17 B17 VDD VDD Pmod L=2.49324495416238e-07 W= ++0.000104142717459091 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000208285434918183 PS=0.000208285434918183 NQSMOD=1 +LA18 A18 LCA18 3.69030941553353e-11 +RA18 LCA18 A19 0.266535044422507 +LB18 B18 LCB18 3.69030941553353e-11 +RB18 LCB18 B19 0.266535044422507 +C18 A19 B19 2.50418376625721e-14 +MNA18 B18 A18 0 0 Nmod L=2.52038203439398e-07 W=4.17044670825126e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.34089341650252e-05 PS= ++8.34089341650252e-05 NQSMOD=1 +MPA18 B18 A18 VDD VDD Pmod L=2.46465042965348e-07 W= ++0.000102305682920291 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000204611365840582 PS=0.000204611365840582 NQSMOD=1 +MNB18 A18 B18 0 0 Nmod L=2.45695550122768e-07 W=4.2510656912981e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.50213138259621e-05 PS= ++8.50213138259621e-05 NQSMOD=1 +MPB18 A18 B18 VDD VDD Pmod L=2.56212134001568e-07 W= ++0.000101696358889307 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000203392717778614 PS=0.000203392717778614 NQSMOD=1 +LA19 A19 LCA19 3.69030941553353e-11 +RA19 LCA19 A20 0.266535044422507 +LB19 B19 LCB19 3.69030941553353e-11 +RB19 LCB19 B20 0.266535044422507 +C19 A20 B20 2.50418376625721e-14 +MNA19 B19 A19 0 0 Nmod L=2.46298724559332e-07 W=4.26183323927543e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.52366647855085e-05 PS= ++8.52366647855085e-05 NQSMOD=1 +MPA19 B19 A19 VDD VDD Pmod L=2.53903413760174e-07 W= ++0.000103580270078538 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000207160540157077 PS=0.000207160540157077 NQSMOD=1 +MNB19 A19 B19 0 0 Nmod L=2.4541336381424e-07 W=4.1471197163819e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.2942394327638e-05 PS=8.2942394327638e-05 ++NQSMOD=1 +MPB19 A19 B19 VDD VDD Pmod L=2.51953325753565e-07 W= ++0.0001019745929959 AD=7.8125e-11 AS=7.8125e-11 PD=0.0002039491859918 ++PS=0.0002039491859918 NQSMOD=1 +LA20 A20 LCA20 3.69030941553353e-11 +RA20 LCA20 A21 0.266535044422507 +LB20 B20 LCB20 3.69030941553353e-11 +RB20 LCB20 B21 0.266535044422507 +C20 A21 B21 2.50418376625721e-14 +MNA20 B20 A20 0 0 Nmod L=2.55318350883171e-07 W=4.2257523363596e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.4515046727192e-05 PS= ++8.4515046727192e-05 NQSMOD=1 +MPA20 B20 A20 VDD VDD Pmod L=2.50733395598687e-07 W= ++0.000105848300738233 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000211696601476467 PS=0.000211696601476467 NQSMOD=1 +MNB20 A20 B20 0 0 Nmod L=2.53961238224852e-07 W=4.07467605160825e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.1493521032165e-05 PS= ++8.1493521032165e-05 NQSMOD=1 +MPB20 A20 B20 VDD VDD Pmod L=2.52173406118976e-07 W= ++0.000104205251139887 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000208410502279773 PS=0.000208410502279773 NQSMOD=1 +LA21 A21 LCA21 3.69030941553353e-11 +RA21 LCA21 A22 0.266535044422507 +LB21 B21 LCB21 3.69030941553353e-11 +RB21 LCB21 B22 0.266535044422507 +C21 A22 B22 2.50418376625721e-14 +MNA21 B21 A21 0 0 Nmod L=2.46323292867561e-07 W=4.1601573531982e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.32031470639639e-05 PS= ++8.32031470639639e-05 NQSMOD=1 +MPA21 B21 A21 VDD VDD Pmod L=2.54613442115316e-07 W= ++0.000104931161465525 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.00020986232293105 PS=0.00020986232293105 NQSMOD=1 +MNB21 A21 B21 0 0 Nmod L=2.55836584454404e-07 W=4.10424160274173e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.20848320548346e-05 PS= ++8.20848320548346e-05 NQSMOD=1 +MPB21 A21 B21 VDD VDD Pmod L=2.54709741956022e-07 W= ++0.000102062091080516 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000204124182161031 PS=0.000204124182161031 NQSMOD=1 +LA22 A22 LCA22 3.69030941553353e-11 +RA22 LCA22 A23 0.266535044422507 +LB22 B22 LCB22 3.69030941553353e-11 +RB22 LCB22 B23 0.266535044422507 +C22 A23 B23 2.50418376625721e-14 +MNA22 B22 A22 0 0 Nmod L=2.54430620981417e-07 W=4.19307535657001e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.38615071314001e-05 PS= ++8.38615071314001e-05 NQSMOD=1 +MPA22 B22 A22 VDD VDD Pmod L=2.46694525572975e-07 W= ++0.000103108817734331 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000206217635468663 PS=0.000206217635468663 NQSMOD=1 +MNB22 A22 B22 0 0 Nmod L=2.4991048194413e-07 W=4.12343575509987e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.24687151019974e-05 PS= ++8.24687151019974e-05 NQSMOD=1 +MPB22 A22 B22 VDD VDD Pmod L=2.53435790976082e-07 W= ++0.000105540213369592 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000211080426739185 PS=0.000211080426739185 NQSMOD=1 +LA23 A23 LCA23 3.69030941553353e-11 +RA23 LCA23 A24 0.266535044422507 +LB23 B23 LCB23 3.69030941553353e-11 +RB23 LCB23 B24 0.266535044422507 +C23 A24 B24 2.50418376625721e-14 +MNA23 B23 A23 0 0 Nmod L=2.47985427798248e-07 W=4.14939059451511e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.29878118903023e-05 PS= ++8.29878118903023e-05 NQSMOD=1 +MPA23 B23 A23 VDD VDD Pmod L=2.50625862917368e-07 W= ++0.000104857443713713 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000209714887427425 PS=0.000209714887427425 NQSMOD=1 +MNB23 A23 B23 0 0 Nmod L=2.48906363214973e-07 W=4.09072154111792e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.18144308223583e-05 PS= ++8.18144308223583e-05 NQSMOD=1 +MPB23 A23 B23 VDD VDD Pmod L=2.544246792556e-07 W= ++0.000106667496188909 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000213334992377817 PS=0.000213334992377817 NQSMOD=1 +RCROSS1 A0 B24 0.001 +RCROSS2 B0 A24 0.001 + +.SAVE VDD0 +.SAVE VSS0 +.SAVE VDD_A0 +.SAVE VSS_A0 +.SAVE VDD_B0 +.SAVE VSS_B0 +.SAVE A0 B0 LA0#branch LB0#branch A1 B1 LA1#branch LB1#branch A2 B2 ++LA2#branch LB2#branch A3 B3 LA3#branch LB3#branch A4 B4 LA4#branch ++LB4#branch A5 B5 LA5#branch LB5#branch A6 B6 LA6#branch LB6#branch ++A7 B7 LA7#branch LB7#branch A8 B8 LA8#branch LB8#branch A9 B9 ++LA9#branch LB9#branch A10 B10 LA10#branch LB10#branch A11 B11 ++LA11#branch LB11#branch A12 B12 LA12#branch LB12#branch A13 B13 ++LA13#branch LB13#branch A14 B14 LA14#branch LB14#branch A15 B15 ++LA15#branch LB15#branch A16 B16 LA16#branch LB16#branch A17 B17 ++LA17#branch LB17#branch A18 B18 LA18#branch LB18#branch A19 B19 ++LA19#branch LB19#branch A20 B20 LA20#branch LB20#branch A21 B21 ++LA21#branch LB21#branch A22 B22 LA22#branch LB22#branch A23 B23 ++LA23#branch LB23#branch + + +** +**INCLUDING FILE: ./proj1/process.models.... +* +* Typical N Typical P - from process corners (taken from tsmc025_corners.bsim3 fron NCSU) +* +* TSMC 0.25u 5M 1P process. 2.5V transistor models + + +.MODEL Nmod NMOS LEVEL=8 ++TNOM = 25 ++VERSION = 3.2.2 TOX = 5.8e-9 ++XJ = 1E-07 NCH = 2.354946E+17 LLN = 1 ++LWN = 1 WLN = 1 WWN = 1 ++LINT = 1.76E-08 WINT = 6.75E-09 MOBMOD = 1 ++BINUNIT = 2 DWG = 0 DWB = 0 ++VTH0 = 0.4321336 LVTH0 = 2.081814E-08 WVTH0 = -5.470342E-11 ++PVTH0 = -6.721795E-16 K1 = 0.3281252 LK1 = 9.238362E-08 ++WK1 = 2.878255E-08 PK1 = -2.426481E-14 K2 = 0.0402824 ++LK2 = -3.208392E-08 WK2 = -1.154091E-08 PK2 = 9.192045E-15 ++K3 = 0 DVT0 = 0 DVT1 = 0 ++DVT2 = 0 DVT0W = 0 DVT1W = 0 ++DVT2W = 0 NLX = 0 W0 = 0 ++K3B = 0 VSAT = 7.586954E+04 LVSAT = 3.094656E-03 ++WVSAT = -1.747416E-03 PVSAT = 8.820956E-10 UA = 8.924498E-10 ++LUA = -1.511745E-16 WUA = -3.509821E-17 PUA = -3.08778E-23 ++UB = 8.928832E-21 LUB = -1.655745E-27 WUB = -2.03282E-27 ++PUB = 3.4578E-34 UC = -1.364265E-11 LUC = 1.170473E-17 ++WUC = -1.256705E-18 PUC = -6.249644E-24 RDSW = 447.8871 ++PRWB = 0 PRWG = 0 WR = 0.99 ++U0 = 0.06005258 LU0 = -6.31976E-09 WU0 = -8.819531E-09 ++PU0 = 3.57209E-15 A0 = -1.468837 LA0 = 6.419548E-07 ++WA0 = 5.512414E-07 PA0 = -9.222928E-14 KETA = -0.04922795 ++LKETA = 2.360844E-08 WKETA = 1.560385E-08 PKETA = -5.98377E-15 ++A1 = 0.02659908 LA1 = -6.511454E-09 A2 = 1 ++AGS = -4.01637 LAGS = 1.090294E-06 WAGS = 1.162021E-06 ++PAGS = -3.108579E-13 B0 = 0 B1 = 0 ++VOFF = -0.1829426 LVOFF = 9.941631E-09 WVOFF = 1.568082E-08 ++PVOFF = -2.832958E-15 NFACTOR = 0.6790636 LNFACTOR= 3.454948E-08 ++WNFACTOR= 1.501016E-07 PNFACTOR= -2.955591E-14 CIT = 2.218499E-04 ++LCIT = -1.076934E-10 WCIT = -3.286884E-10 PCIT = 1.658928E-16 ++CDSC = 0 CDSCB = 0 CDSCD = 0 ++ETA0 = 1.215578E-04 LETA0 = -1.037758E-11 WETA0 = -3.030225E-11 ++PETA0 = 1.529658E-17 ETAB = 3.548681E-03 LETAB = -1.791374E-09 ++WETAB = -6.897268E-10 PETAB = 3.481742E-16 DSUB = 0 ++PCLM = 3.583838 PDIBLC1 = 0 PDIBLC2 = 5.379674E-03 ++LPDIBLC2= 7.808481E-09 WPDIBLC2= 5.516945E-10 PPDIBLC2= -2.784957E-16 ++PDIBLCB = -0.1229374 LPDIBLCB= 4.956215E-08 WPDIBLCB= 3.299946E-08 ++PPDIBLCB= -9.624918E-15 DROUT = 0 PSCBE1 = 4.472639E+08 ++LPSCBE1 = 28.64041 WPSCBE1 = 15.7154 PPSCBE1 = -7.933138E-06 ++PSCBE2 = 1.842585E-06 LPSCBE2 = 2.871008E-12 WPSCBE2 = 2.579183E-12 ++PPSCBE2 = -1.301972E-18 PVAG = -2.015254E-03 LPVAG = 1.017757E-09 ++WPVAG = 3.07622E-10 PPVAG = -1.55418E-16 DELTA = -0.02862256 ++LDELTA = 1.492454E-08 WDELTA = -6.71663E-09 PDELTA = 3.407521E-15 ++ALPHA0 = 0 BETA0 = 30 KT1 = -0.2579945 ++LKT1 = -1.664895E-08 WKT1 = -1.633463E-08 PKT1 = 3.755864E-15 ++KT2 = -0.05347481 LKT2 = 8.244731E-09 WKT2 = 1.13705E-09 ++PKT2 = -1.240924E-15 AT = -1.132632E+04 LAT = 6.469047E-03 ++WAT = 6.829220E-04 PAT = -4.154249E-10 UTE = -2.309089 ++LUTE = 1.662427E-07 WUTE = 1.244801E-07 PUTE = -5.627924E-14 ++UA1 = -3.461758E-10 LUA1 = 1.747495E-16 WUA1 = -1.42065E-16 ++PUA1 = 7.171442E-23 UB1 = 0 UC1 = -2.38157E-12 ++LUC1 = -2.895726E-18 WUC1 = -1.990052E-17 PUC1 = 1.004497E-23 ++KT1L = 0 PRT = -1E-18 CJ = 2.024128E-3 ++MJ = 0.4960069 PB = 0.9173808 CJSW = 2.751528E-10 ++MJSW = 0.443145 PBSW = 0.9173808 CJSWG = 2.135064E-10 ++MJSWG = 0.443145 PBSWG = 0.9173808 ++RSH = 4.5 ++XTI = 3 ++CGDO = 3.11E-10 CGSO = 3.11E-10 CAPMOD = 2 ++XPART = 1 CF = 0 ++JS = 1E-06 ++JSW = 5E-11 + + + +.MODEL Pmod PMOS LEVEL=8 ++VERSION = 3.2.2 ++TNOM = 25 TOX = 5.8e-9 ++XJ = 1E-7 NCH = 4.1589E17 ++LLN = 1 LWN = 1 WLN = 1 ++WWN = 1 LINT = 1.2365E-8 WINT = 7.8E-9 ++MOBMOD = 1 BINUNIT = 2 DWG = 0 ++DWB = 0 VTH0 = -0.6236538 LVTH0 = 2.649834E-8 ++WVTH0 = 3.214189E-8 PVTH0 = -3.22268E-15 K1 = 0.4198155 ++LK1 = 5.770498E-8 WK1 = 5.577151E-8 PK1 = -2.81684E-14 ++K2 = 0.0429467 LK2 = -2.296405E-8 WK2 = -1.355302E-8 ++PK2 = 6.848271E-15 K3 = 0 DVT0 = 0 ++DVT1 = 0 DVT2 = 0 DVT0W = 0 ++DVT1W = 0 DVT2W = 0 NLX = 0 ++W0 = 0 K3B = 0 VSAT = 1.443912E5 ++LVSAT = -7.688012E-4 WVSAT = -6.083648E-3 PVSAT = 2.186471E-10 ++UA = 1.846811E-9 LUA = -3.27694E-16 WUA = -2.82106E-16 ++PUA = 7.180233E-23 UB = -7.84535E-19 LUB = 4.772849E-25 ++WUB = 2.599205E-25 PUB = -1.46530E-31 UC = -1.75560E-10 ++LUC = 3.360832E-17 WUC = 1.504425E-17 PUC = -1.30556E-23 ++RDSW = 1.03E3 PRWB = 0 PRWG = 0 ++WR = 1 U0 = 0.0136443 LU0 = -7.22084E-10 ++WU0 = -1.088554E-9 PU0 = 2.730854E-16 A0 = 0.1071803 ++LA0 = 4.64252E-7 WA0 = 5.383179E-7 PA0 = -1.32033E-13 ++KETA = -4.943762E-3 LKETA = -3.565304E-9 WKETA = -5.226247E-9 ++PKETA = 2.640665E-15 A1 = 0 A2 = 0.4 ++AGS = 0.1664005 LAGS = 1.19106E-7 WAGS = 5.29237E-8 ++PAGS = -2.67304E-14 B0 = 0 B1 = 0 ++VOFF = -0.0592623 LVOFF = -1.96686E-8 WVOFF = -1.486398E-8 ++PVOFF = 7.510321E-15 NFACTOR = 0.8588103 LNFACTOR= -1.158881E-7 ++WNFACTOR= 1.210664E-8 PNFACTOR= -6.11712E-15 CIT = 6.439495E-5 ++LCIT = 2.916437E-10 WCIT = -3.11284E-11 PCIT = 1.572825E-17 ++CDSC = 0 CDSCB = 0 CDSCD = 0 ++ETA0 = -3.819468E-3 LETA0 = 2.155422E-9 WETA0 = 8.235612E-10 ++PETA0 = -4.16037E-16 ETAB = 1.334637E-3 LETAB = -7.93631E-10 ++WETAB = 5.284657E-11 PETAB = -2.68353E-17 DSUB = 0 ++PCLM = 0.1098002 LPCLM = 6.874263E-7 WPCLM = 6.724724E-7 ++PPCLM = -1.97766E-13 PDIBLC1 = 0 PDIBLC2 = 5.801323E-3 ++LPDIBLC2= -1.81964E-9 WPDIBLC2= -5.853396E-9 PPDIBLC2= 2.957545E-15 ++PDIBLCB = 0.1921199 DROUT = 0 PSCBE1 = 7.19E8 ++PSCBE2 = 1E-20 PVAG = 0 DELTA = 0.01 ++ALPHA0 = 0 BETA0 = 30 KT1 = -0.3248987 ++LKT1 = -1.160393E-8 WKT1 = 4.153356E-8 PKT1 = -4.62347E-15 ++KT2 = -0.0367632 AT = 1E4 UTE = -1.04 ++UA1 = 3.992421E-10 UB1 = -9.23294E-19 LUB1 = -5.28718E-26 ++WUB1 = -6.13069E-26 PUB1 = 1.503674E-32 UC1 = -1.00699E-12 ++KT1L = 0 PRT = 0 CJ = 1.931092e-3 ++MJ = 0.4812153 PB = 0.9134669 CJSW = 2.232277e-10 ++MJSW = 0.3237595 PBSW = 0.9134669 CJSWG = 1.607088e-10 ++MJSWG = 0.3237595 PBSWG = 0.9134669 ++RSH = 3.5 ++CGDO = 2.68e-10 CGSO = 2.68e-10 ++CAPMOD = 2 ++XPART = 1 ++CF = 0 XTI = 3 ++JS = 3E-7 ++JSW = 5E-12 + +**.... FINISHED INCLUDING: ./proj1/process.models +** +.OPTIONS TEMP=25 +VSLEW_CONTROL VSLEW 0 (PULSE 0 1 0 1e-09) +EVLOGIC VRAMP 0 VSLEW 0 2.5 +VDDPOWER VDD VRAMP DC 0 +VARACTOR_V VARACTOR_V 0 DC 2.5 +.SAVE vddpower#branch +.SAVE vdd +.SAVE varactor_v +.TRAN 0.02n 3000n 0n 0.5n +.END diff --git a/src/tcl/plot.tcl b/src/tcl/plot.tcl new file mode 100755 index 000000000..810aa418d --- /dev/null +++ b/src/tcl/plot.tcl @@ -0,0 +1,12 @@ +#!/bin/sh +# WishFix \ + exec wish -f "$0" ${1+"$@"} +### + +package require spice + +spice::source example.cir +spice::step 100 + +spice::plot a0 vs b0 +spice::bltplot a0 diff --git a/src/tcl/vector_test.tcl b/src/tcl/vector_test.tcl new file mode 100755 index 000000000..9fc3be419 --- /dev/null +++ b/src/tcl/vector_test.tcl @@ -0,0 +1,50 @@ +#!/bin/sh +# WishFix \ + exec wish -f "$0" ${1+"$@"} +### + +package require BLT +namespace import blt::* + +package require spice + +wm title . "Vector Test script" +wm geometry . 800x600+40+40 +pack propagate . false + +stripchart .chart +pack .chart -side top -fill both -expand true +.chart axis configure x -title "Time" + + +# Create a vector (and call it $vector) +#vector create v1 +spice::source example.cir +spice::bg run + +after 1000 + +vector create a0 +vector create b0 +vector create a1 +vector create b1 +vector create stime +proc bltupdate {} { + spice::spicetoblt a0 a0 + spice::spicetoblt b0 b0 + spice::spicetoblt a1 a1 + spice::spicetoblt b1 b1 + spice::spicetoblt time stime + #puts $spice::lastitercount + after 100 bltupdate +} +bltupdate + + + +.chart element create a0 -color red -xdata stime -ydata a0 +.chart element create b0 -color blue -xdata stime -ydata b0 +.chart element create a1 -color yellow -xdata stime -ydata a1 +.chart element create b1 -color black -xdata stime -ydata b1 + + diff --git a/src/tclspice.c b/src/tclspice.c new file mode 100755 index 000000000..1772e1508 --- /dev/null +++ b/src/tclspice.c @@ -0,0 +1,1323 @@ +/* Copied and written by Stefan Jones (stefan.jones@multigig.com) at Multigig Ltd + * Under GPL licence + * Code based on and copied from ScriptEDA ( http://www-cad.eecs.berkeley.edu/~pinhong/scriptEDA ) + * $Id$ + */ + +/*******************/ +/* Defines */ +/*******************/ + +#define TCLSPICE_name "spice" +#define TCLSPICE_prefix "spice::" +#define TCLSPICE_namespace "spice" + +/**********************************************************************/ +/* Header files for C functions */ +/**********************************************************************/ + +/* Copied from main.c in ngspice*/ +#include +#include +#ifdef HAVE_STRING_H +#include +#endif /* HAVE_STRING_H */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifndef HAVE_GETRUSAGE +#ifdef HAVE_FTIME +#include +#endif +#endif + +/*Included for the module to access data*/ +#include +#include +#include +#include +#include + +/*For get_output*/ +#include +#include + +/* run spicein background */ +#include + +extern IFfrontEnd nutmeginfo; + +extern struct comm spcp_coms[ ]; + +extern int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator); + +/*For blt spice to use*/ +typedef struct { + char *name; + pthread_mutex_t mutex;/*lock for this vector*/ + double *data;/* vector data*/ + int size;/*data it can store*/ + int length;/*actual amount of data*/ +} vector; + +/*The current run (to get variable names, etc)*/ +static runDesc *cur_run = NULL; + +static vector *vectors = NULL; + +/* save this each time called */ +static Tcl_Interp *spice_interp=NULL; +#define save_interp() spice_interp = interp; + + +/****************************************************************************/ +/* BLT and data routines */ +/****************************************************************************/ + +/*this holds the number of time points done (altered by spice)*/ +int steps_completed = 0; +/* number of bltvectors*/ +static int blt_vnum = 0; + + +/*Native Tcl functions */ + +static int spice_header(ClientData clientData, Tcl_Interp *interp, + int args, char **argv){ + char buf[256]; + char *date, *name, *title; + if (args != 1) { + Tcl_SetResult(interp, "Wrong # args. spice::spice_header",TCL_STATIC); + return TCL_ERROR; + } + if(cur_run){ + Tcl_ResetResult(interp); + date = datestring(); + title = cur_run->name; + name = cur_run->type; + sprintf(buf,"{title \"%s\"} {name \"%s\"} {date \"%s\"} {variables %u}",title,name,date,cur_run->numData); + Tcl_AppendResult(interp, (char *)buf,TCL_STATIC); + return TCL_OK; + }else return TCL_ERROR; +} + + +static int spice_data(ClientData clientData, Tcl_Interp *interp, + int args, char **argv){ + char buf[256]; + int i, type; + char *name; + if (args != 1) { + Tcl_SetResult(interp, "Wrong # args. spice::spice_data",TCL_STATIC); + return TCL_ERROR; + } + if(blt_vnum){ + Tcl_ResetResult(interp); + for(i = 0; i < blt_vnum;i++){ + name = vectors[i].name; + if (substring("#branch", name)) + type = SV_CURRENT; + else if (cieq(name, "time")) + type = SV_TIME; + else if (cieq(name, "frequency")) + type = SV_FREQUENCY; + else + type = SV_VOLTAGE; + sprintf(buf,"{%s %s} ",name, + ft_typenames(type)); + Tcl_AppendResult(interp, (char *)buf, TCL_STATIC); + } + return TCL_OK; + }else return TCL_ERROR; +} + +static int resetTriggers(); + +/*Creates and registers the blt vectors, used by spice*/ +void blt_init(void *tmp){ + int i; + runDesc *run = cur_run; + cur_run = NULL; + /* reset varaibles and free*/ + if(vectors){ + resetTriggers(); + for(i = blt_vnum, blt_vnum = 0/*stops vector access*/;i > 0;i--){ + if(run->writeOut) + FREE(vectors[i].data); + FREE(vectors[i].name); + pthread_mutex_destroy(&vectors[i].mutex); + } + FREE(vectors); + } + + + /* initilise */ + cur_run = (runDesc *)tmp;; + vectors = (vector *)MALLOC(cur_run->numData*sizeof(vector)); + for(i = 0;i < cur_run->numData;i++){ + vectors[i].name = copy((cur_run->data[i]).name); + pthread_mutex_init(&vectors[i].mutex,NULL); + vectors[i].data = NULL; + vectors[i].size = 0; + vectors[i].length = 0; + } + blt_vnum = i;/*allows access to vectors*/ + return; +} + +/*Adds data to the stored vector*/ +void blt_add(int index,double value){ + vector *v; + v = &vectors[index]; + pthread_mutex_lock(&vectors[index].mutex); + if(!(v->length < v->size)){ + v->size += 100; + v->data = (double *)REALLOC(v->data,sizeof(double)*v->size); + } + v->data[v->length] = value; + v->length ++; + pthread_mutex_unlock(&vectors[index].mutex); + return; +} + +/* Locks the vector data to stop conflicts*/ +void blt_lockvec(int index){ + pthread_mutex_lock(&vectors[index].mutex); + return; +} + + +/*links a dvec to a blt vector, used to stop duplication of data when writing to a plot, + but makes BLT vectors more unsafe */ +void blt_relink(int index,void *tmp){ + struct dvec *v = (struct dvec *)tmp; + vectors[index].data = v->v_realdata; + vectors[index].length = v->v_length; + vectors[index].size = v->v_length;/*silly spice doesn't use v_rlength*/ + pthread_mutex_unlock(&vectors[index].mutex); + return; +} + + + + +/* Tcl functions to access spice data */ + +/* This copys the last Spice state vector to the given blt_vector + * arg1: blt_vector + */ +static int lastVector(ClientData clientData, Tcl_Interp *interp, + int args, char **argv){ + Blt_Vector *vec; + char *blt; + int i; + double *V; + if (args != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::lastVector vecName",TCL_STATIC); + return TCL_ERROR; + } + blt = argv[1]; + if(Blt_GetVector(interp,blt,&vec)){ + Tcl_SetResult(interp, "Bad blt vector ",TCL_STATIC); + Tcl_AppendResult(interp, (char *)blt, TCL_STATIC); + return TCL_ERROR; + } + if(!(V = (double *)MALLOC(sizeof(double)*blt_vnum))) { + Tcl_SetResult(interp, "Out of Memory",TCL_STATIC); + return TCL_ERROR; + } + + for(i=0;i < blt_vnum;i++){ + pthread_mutex_lock(&vectors[i].mutex); + V[i] = vectors[i].data[vectors[i].length-1]; + pthread_mutex_unlock(&vectors[i].mutex); + } + Blt_ResetVector(vec,V,blt_vnum, + blt_vnum,TCL_VOLATILE); + txfree(V); + return TCL_OK; +} + +/*agr1: spice variable name + *arg2: blt_vector + *arg3: start copy index, optional + *arg4: end copy index. optional + */ +static int spicetoblt(ClientData clientData, Tcl_Interp *interp, + int args, char **argv){ + Blt_Vector *vec; + int index, i; + char *blt, *var; + int start=0,end=-1,len; + + if (args < 3 || args > 5) { + Tcl_SetResult(interp, "Wrong # args. spice::spicetoblt spice_variable vecName ?start? ?end?",TCL_STATIC); + return TCL_ERROR; + } + + var = argv[1]; + blt = argv[2]; + + for(i=0;i < blt_vnum && strcmp(var,vectors[i].name);i++); + + if(i == blt_vnum) { + Tcl_SetResult(interp, "Bad spice variable ",TCL_STATIC); + Tcl_AppendResult(interp, (char *)var, TCL_STATIC); + return TCL_ERROR; + } else index = i; + + if(Blt_GetVector(interp,blt,&vec)){ + Tcl_SetResult(interp, "Bad blt vector ",TCL_STATIC); + Tcl_AppendResult(interp, (char *)blt, TCL_STATIC); + return TCL_ERROR; + } + + + if(args >= 4) + start = atoi(argv[3]); + if(args == 5) + end = atoi(argv[4]); + if(vectors[index].length) { + pthread_mutex_lock(&vectors[index].mutex); + + len = vectors[index].length; + + if(start){ + start = start % len; + if(start < 0) + start += len; + } + + end = end % len; + if(end < 0) + end += len; + + len = abs(end - start + 1); + + Blt_ResetVector(vec,(vectors[index].data + start),len, + len,TCL_VOLATILE); + + pthread_mutex_unlock(&vectors[index].mutex); + } + return TCL_OK; +} + + +/******************************************************************/ +/* Main spice command executions and thread control */ +/*****************************************************************/ + +static pthread_t tid; +static bool fl_running = FALSE; +static bool fl_exited = TRUE; + + +static void *_thread_run(void *string){ + fl_exited = FALSE; + cp_evloop((char *)string); + FREE(string); + fl_exited = TRUE; + return 0; +} + +/*Stops a running thread, hopefully */ +static int _thread_stop(){ + int timeout = 0; + if(fl_running) { + while(!fl_exited && timeout < 100){ + ft_intrpt = TRUE; + timeout++; + sleep(1); + } + if(!fl_exited) { + fprintf(stderr,"couldn't stop tclspice\n"); + return TCL_ERROR; + } + pthread_join(tid, NULL); + fl_running = FALSE; + ft_intrpt = FALSE; + return TCL_OK; + }else { + fprintf(stderr,"spice not running\n"); + } + return TCL_OK; +} + +static int _run(int args,char **argv){ + char buf[1024] = "", *string; + int i; + bool fl_bg = FALSE; + /* run task in background if preceeded by "bg"*/ + if(!strcmp(argv[0],"bg")) { + args--; + argv = &argv[1]; + fl_bg = TRUE; + } + + /*build a char * to pass to cp_evloop */ + for(i=0;i 1) + cp_evloop(buf); + else{ + _thread_stop(); + cp_evloop(buf); + } + else { + /* cannot do anything if spice is running in the bg*/ + if(fl_running){ + if(fl_exited){ + _thread_stop(); + cp_evloop(buf); + }else + fprintf(stderr,"type \"spice stop\" first\n"); + }else{ + /*do the command*/ + cp_evloop(buf); + } + } + return TCL_OK; +} + +static int _tcl_dispatch(ClientData clientData, Tcl_Interp *interp, + int args, char **argv){ + int i; + save_interp(); + /* Looks backwards through the first command and strips the :: part */ + for(i = strlen(argv[0])-1;i > 0;i--) + if(argv[0][i] == *":") + argv[0] += i + 1; + return _run(args,argv); +} + + +/* Runs the spice command given in spice */ +static int _spice_dispatch(ClientData clientData, Tcl_Interp *interp, + int args, char **argv){ + save_interp(); + if(args == 1) return TCL_OK; + return _run(args-1,&argv[1]); +} + +/*Checks if spice is runnuing in the background */ +static int running(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ + Tcl_SetObjResult(interp,Tcl_NewIntObj((long) (fl_running && !fl_exited))); + return TCL_OK; +} + + +/**************************************/ +/* plot manipulation functions */ +/* only usefull if plots are saved */ +/**************************************/ + +/*helper function*/ +inline static struct plot * get_plot(int plot){ + struct plot *pl; + pl = plot_list; + for(;0 < plot;plot--){ + pl = pl->pl_next; + if(!pl) + return (struct plot *)NULL; + } + return pl; +} + +/*Outputs the names of all variables in the plot */ +static int plot_variables(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ + struct plot *pl; + int plot; + struct dvec *v; + + if (argc != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_variables plot",TCL_STATIC); + return TCL_ERROR; + } + + plot = atoi(argv[1]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp,"bad plot given",TCL_STATIC); + return TCL_ERROR; + } + + for(v = pl->pl_dvecs;v;v = v->v_next){ + Tcl_AppendElement(interp,v->v_name); + } + return TCL_OK; +} + +/*returns the value of a variable */ +static int plot_get_value(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ + struct plot *pl; + struct dvec *v; + char *name; + int plot,index; + + if (argc != 4) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_get_value name plot index",TCL_STATIC); + return TCL_ERROR; + } + + name = argv[1]; + plot = atoi(argv[2]); + index = atoi(argv[3]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp, "bad plot",TCL_STATIC); + return TCL_ERROR; + } + for(v = pl->pl_dvecs;v;v = v->v_next) + if(!strcmp(v->v_name,name)){ + if (index < v->v_length) { + Tcl_SetObjResult(interp,Tcl_NewDoubleObj((double) v->v_realdata[index])); + return TCL_OK; + } else { + Tcl_SetResult(interp, "bad index",TCL_STATIC); + return TCL_ERROR; + } + } + Tcl_SetResult(interp, "variable not found",TCL_STATIC); + return TCL_ERROR; +} + + +/*The length of the first vector in a plot*/ +static int plot_datapoints(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ + struct plot *pl; + struct dvec *v; + int plot; + + if (argc != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_datapoints plot",TCL_STATIC); + return TCL_ERROR; + } + + plot = atoi(argv[1]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp, "bad plot", TCL_STATIC); + return TCL_ERROR; + } + + v = pl->pl_dvecs; + + Tcl_SetObjResult(interp,Tcl_NewIntObj((long) v->v_length));// could be very dangeous + return TCL_OK; +} + +/*These functions give you infomation about a plot*/ + +static int plot_title(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ + struct plot *pl; + int plot; + if (argc != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_nvars plot",TCL_STATIC); + return TCL_ERROR; + } + + plot = atoi(argv[1]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp, "bad plot", TCL_STATIC); + return TCL_ERROR; + } + Tcl_SetObjResult(interp,Tcl_NewStringObj(pl->pl_title,-1)); + return TCL_OK; +} + +static int plot_date(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ + struct plot *pl; + + int plot; + if (argc != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_nvars plot",TCL_STATIC); + return TCL_ERROR; + } + + plot = atoi(argv[1]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp, "bad plot", TCL_STATIC); + return TCL_ERROR; + } + Tcl_SetObjResult(interp,Tcl_NewStringObj(pl->pl_date,-1)); + return TCL_OK; +} + +static int plot_name(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ + struct plot *pl; + int plot; + if (argc != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_nvars plot",TCL_STATIC); + return TCL_ERROR; + } + + plot = atoi(argv[1]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp, "bad plot", TCL_STATIC); + return TCL_ERROR; + } + Tcl_SetObjResult(interp,Tcl_NewStringObj(pl->pl_name,-1)); + return TCL_OK; +} + +/*number of variables in a plot*/ + +static int plot_nvars(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ + struct plot *pl; + struct dvec *v; + int plot; + int i=0; + + if (argc != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_nvars plot",TCL_STATIC); + return TCL_ERROR; + } + + plot = atoi(argv[1]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp, "bad plot",TCL_STATIC); + return TCL_ERROR; + } + for(v = pl->pl_dvecs;v;v = v->v_next) + i++; + Tcl_SetObjResult(interp,Tcl_NewIntObj((long) i)); + return TCL_OK; +} + + +/*******************************************/ +/* Misc functions */ +/*******************************************/ + +/*Runs a tcl script and returns the output*/ +static int get_output(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { + FILE *pipein; + int tmp_1,tmp_2=0; + char buf[1024]; + int outfd,outfd2=0; + save_interp(); + if ((argc < 2) || (argc > 3)) { + Tcl_SetResult(interp, "Wrong # args. spice::get_output script ?var_for_stderr?",TCL_STATIC); + return TCL_ERROR; + } + tmp_1=dup(1); + outfd=open("/tmp/tclspice.tmp_out",O_WRONLY|O_CREAT|O_TRUNC,S_IRWXU); + if(argc==3){ + tmp_2=dup(2); + outfd2=open("/tmp/tclspice.tmp_err",O_WRONLY|O_CREAT|O_TRUNC,S_IRWXU); + } + freopen("/tmp/tclspice.tmp_out","w",stdout); + if(argc==3)freopen("/tmp/tclspice.tmp_err","w",stderr); + dup2(outfd,1); + if(argc==3)dup2(outfd2,2); + + Tcl_Eval(interp,argv[1]); + + fclose(stdout); + close(outfd); + if(argc==3){ + fclose(stderr); + close(outfd2); + } + dup2(tmp_1, 1); + close(tmp_1); + if(argc==3){ + dup2(tmp_2, 2); + close(tmp_2); + } + freopen("/dev/fd/1","w",stdout); + if(argc==3)freopen("/dev/fd/2","w",stderr); + pipein=fopen("/tmp/tclspice.tmp_out","r"); + if(pipein==NULL){ + fprintf(stderr,"pipein==NULL\n"); + } + Tcl_ResetResult(interp); + while(fgets(buf,1024,pipein)!=NULL){ + Tcl_AppendResult(interp, (char *)buf, TCL_STATIC); + } + fclose(pipein); + if(argc==3){ + pipein=fopen("/tmp/tclspice.tmp_err","r"); + Tcl_SetVar(interp,argv[2],"",0); + while(fgets(buf,1024,pipein)!=NULL){ + Tcl_SetVar(interp,argv[2],buf,TCL_APPEND_VALUE); + } + fclose(pipein); + } + return TCL_OK; +} + +/* Returns the current value of a parameter + * has lots of memory leaks + */ +static int get_param(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ + wordlist *wl= NULL; + char *device, *param; + struct variable *v; + char buf[128]; + if (argc != 3) { + Tcl_SetResult(interp, "Wrong # args. spice::get_param device param",TCL_STATIC); + return TCL_ERROR; + } + if (!ft_curckt) { + Tcl_SetResult(interp, "No circuit loaded ",TCL_STATIC); + return TCL_ERROR; + } + + device = argv[1]; + param = argv[2]; + /* copied from old_show(wordlist *) */ + v = (*if_getparam)(ft_curckt->ci_ckt, + &device, param, 0, 0); + if (!v) + v = (*if_getparam)(ft_curckt->ci_ckt, + &device, param, 0, 1); + if (v) { + wl = cp_varwl(v); + Tcl_SetResult(interp,wl->wl_word,TCL_VOLATILE); + wl_free(wl); + tfree(v); + return TCL_OK; + + } else { + sprintf(buf,"%s in %s not found",param, device); + Tcl_AppendResult(interp,buf,TCL_STATIC); + } + return TCL_ERROR; + +} + +/* Direct control over the step size + * Spice will still adjust it to keep accuracy wuithin reltol and abstol + */ +static int delta(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ + if (argc < 1 ||argc > 2) { + Tcl_SetResult(interp, "Wrong # args. spice::delta ?value?",TCL_STATIC); + return TCL_ERROR; + } + if (!ft_curckt) { + Tcl_SetResult(interp, "No circuit loaded ",TCL_STATIC); + return TCL_ERROR; + } + + if(argc == 2) { + ((CKTcircuit *)ft_curckt->ci_ckt)->CKTdelta = atof(argv[1]); + } + /*Ok, as log as string less than 200 chars*/ + sprintf(interp->result,"%G",((CKTcircuit *)ft_curckt->ci_ckt)->CKTdelta); + return TCL_OK; +} + +#include +/* Direct control over the maximum stepsize + * Spice will still adjust it to keep accuracy wuithin reltol and abstol + */ +static int maxstep(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ + TRANan *job; + if (argc < 1 ||argc > 2) { + Tcl_SetResult(interp, "Wrong # args. spice::maxstep ?value?",TCL_STATIC); + return TCL_ERROR; + } + if (!ft_curckt) { + Tcl_SetResult(interp, "No circuit loaded ",TCL_STATIC); + return TCL_ERROR; + } + + job = (TRANan*)((CKTcircuit *)ft_curckt->ci_ckt)->CKTcurJob; + if(argc == 2) { + job->TRANmaxStep = atof(argv[1]); + } + /*Ok, as log as string less than 200 chars*/ + sprintf(interp->result,"%G",job->TRANmaxStep); + return TCL_OK; + +} + + +/****************************************/ +/* The Tk frontend for plot */ +/****************************************/ + +/* Use Tcl_GetStringResult to get canvas size etc. from Tcl */ +#include +int sp_Tk_Init(void) { + /* This is hard coded in C at the mo, use X11 values */ + dispdev->numlinestyles = 8; + dispdev->numcolors = 20; + dispdev->width = 1280; + dispdev->height = 1024; + + return 0; +} + +#include +int sp_Tk_NewViewport(GRAPH *graph) { + char *result; + int width, height, fontwidth, fontheight; + graph->devdep = (char *) NULL; + + if(Tcl_GlobalEval(spice_interp,"spice_gr_NewViewport") != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + + result = Tcl_GetStringResult(spice_interp); + if(sscanf(result,"%i %i %i %i",&width,&height,&fontwidth, &fontheight) != 4) { + Tcl_ResetResult(spice_interp); + return 1; + } + graph->absolute.xpos = 0; /* these always seem sensible, let Tcl adjust coods */ + graph->absolute.ypos = 0; + graph->absolute.width = width; + graph->absolute.height = height; + graph->fontwidth = fontwidth; + graph->fontheight = fontheight; + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_Close(void) { + if(Tcl_Eval(spice_interp,"spice_gr_Close") != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_Clear(void) { + if(Tcl_Eval(spice_interp,"spice_gr_Clear") != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_DrawLine(int x1, int y1, int x2, int y2) { + char buf[1024]; + sprintf(buf,"spice_gr_DrawLine %i %i %i %i",x1, y1, x2, y2); + if(Tcl_Eval(spice_interp,buf) != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_Arc(int x0, int y0, int radius, double theta1, double theta2) { + char buf[1024]; + sprintf(buf,"spice_gr_Arc %i %i %i %f %f", x0, y0, radius, theta1, theta2); + if(Tcl_Eval(spice_interp,buf) != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_Text(char *text, int x, int y) { + char buf[1024]; + sprintf(buf,"spice_gr_Text \"%s\" %i %i",text,x,y); + if(Tcl_Eval(spice_interp,buf) != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_DefineColor(int colorid, double red, double green, double blue) { + char buf[1024]; + sprintf(buf,"spice_gr_DefineColor %i %g %g %g",colorid, red, green, blue); + if(Tcl_Eval(spice_interp,buf) != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_DefineLinestyle(int linestyleid, int mask) { + char buf[1024]; + sprintf(buf,"spice_gr_DefineLinestyle %i %i", linestyleid, mask); + if(Tcl_Eval(spice_interp,buf) != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_SetLinestyle(int linestyleid) { + char buf[1024]; + sprintf(buf,"spice_gr_SetLinestyle %i", linestyleid); + if(Tcl_Eval(spice_interp, buf) != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_SetColor(int colorid) { + char buf[1024]; + sprintf(buf,"spice_gr_SetColor %i", colorid); + if(Tcl_Eval(spice_interp,buf) != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_Update(void) { + if(Tcl_Eval(spice_interp,"spice_gr_Update") != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + + +/********************************************************/ +/* The Blt method for plotting */ +/********************************************************/ + +int blt_plot(struct dvec *y,struct dvec *x){ + Blt_Vector *X_Data=NULL, *Y_Data=NULL; + char buf[1024]; + + /* A bug in these functions? , crashes if used so make vectors in Tcl + Blt_CreateVector(spice_interp,"spice::X_Data",1,&X_Data); + Blt_CreateVector(spice_interp,"spice::Y_Data",1,&Y_Data); + */ + Blt_GetVector(spice_interp,"spice::X_Data",&X_Data); + Blt_GetVector(spice_interp,"spice::Y_Data",&Y_Data); + + if(!X_Data || !Y_Data) { + fprintf(stderr,"Error: Blt vector X_Data or Y_Data not created\n"); + return 1; + } + + Blt_ResetVector (Y_Data, y->v_realdata ,y->v_length, y->v_length, TCL_VOLATILE); + + if (x) { + Blt_ResetVector (X_Data, x->v_realdata, x->v_length, x->v_length, TCL_VOLATILE); + } else { + x = y; + /*TODO: handle complex data properly */ + Blt_ResetVector (X_Data, y->v_realdata, y->v_length, y->v_length, TCL_VOLATILE); + } + + sprintf(buf,"spice_gr_Plot %s %s %s %s %s %s", + x->v_name, ft_typenames(x->v_type), ft_typabbrev(x->v_type), + y->v_name, ft_typenames(y->v_type), ft_typabbrev(y->v_type)); + + if(Tcl_Eval(spice_interp,buf) != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + + Tcl_ResetResult(spice_interp); + + return 0; +} + +/********************************************************/ +/* Triggering stuff */ +/********************************************************/ + +struct triggerEvent { + struct triggerEvent *next; + int vector; + int type; + int stepNumber; + double time; +}; + + +struct triggerEvent *eventQueue=NULL; +struct triggerEvent *eventQueueEnd=NULL; + +pthread_mutex_t triggerMutex; + +struct watch { + struct watch *next; + int vector;/* index of vector to watch */ + int type; /* +ive or -ive trigger */ + int state; /* pretriggered or not */ + double Vmin; /* the boundaries */ + double Vmax; +}; + +struct watch *watches=NULL; + +int Tcl_ExecutePerLoop() { + + struct watch *current; + + pthread_mutex_lock(&vectors[0].mutex); + pthread_mutex_lock(&triggerMutex); + + for(current=watches;current;current = current->next) { + vector *v; + v = &vectors[current->vector]; + pthread_mutex_lock(&v->mutex); + + if((current->type > 0 && current->state && v->data[v->length-1] > current->Vmax) || + (current->type < 0 && current->state && v->data[v->length-1] < current->Vmin) ) { + struct triggerEvent *tmp = (struct triggerEvent *)MALLOC(sizeof(struct triggerEvent)); + + tmp->next = NULL; + + if(eventQueue) { + eventQueueEnd->next = tmp; + eventQueueEnd = tmp; + } else { + eventQueue = tmp; + } + + eventQueueEnd = tmp; + + tmp->vector = current->vector; + tmp->type = current->type; + tmp->stepNumber = vectors[0].length; + tmp->time = vectors[0].data[vectors[0].length-1]; + + current->state = 0; + + } else + if((current->type > 0 && v->data[v->length-1] < current->Vmin) || + (current->type < 0 && v->data[v->length-1] > current->Vmax)) + current->state = 1; + pthread_mutex_unlock(&v->mutex); + } + + pthread_mutex_unlock(&triggerMutex); + + pthread_mutex_unlock(&vectors[0].mutex); + + return 0; +} + +static int resetTriggers() { + pthread_mutex_lock(&triggerMutex); + + while(watches) { + struct watch *tmp = watches; + watches = tmp->next; + FREE(tmp); + } + + while(eventQueue) { + struct triggerEvent *tmp = eventQueue; + eventQueue = tmp->next; + FREE(tmp); + } + + eventQueueEnd = NULL; + + pthread_mutex_unlock(&triggerMutex); + return 0; +} + + +/* Registers a watch for a trigger + *arg0: Vector Name to watch + *arg1: Vmin + *arg2: Vmax + *arg3: 1 / -1 for +ive(voltage goes +ive) or -ive trigger + */ +static int registerTrigger(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ + int i, index; + char *var; + struct watch *tmp; + + if (argc != 4 && argc != 5) { + Tcl_SetResult(interp, "Wrong # args. spice::registerTrigger vecName Vmin Vmax ?type?",TCL_STATIC); + return TCL_ERROR; + } + + var = argv[1]; + + for(i=0;i < blt_vnum && strcmp(var,vectors[i].name);i++); + + if(i == blt_vnum) { + Tcl_SetResult(interp, "Bad spice variable ",TCL_STATIC); + Tcl_AppendResult(interp, (char *)var, TCL_STATIC); + return TCL_ERROR; + } else index = i; + + pthread_mutex_lock(&triggerMutex); + + tmp = (struct watch *)MALLOC(sizeof(struct watch)); + + tmp->next = watches; + watches = tmp; + + watches->vector = index; + if(argc == 5) + watches->type = atoi(argv[4]); + else + watches->type = 1; + + watches->state = 0; + watches->Vmin = atof(argv[2]); + watches->Vmax = atof(argv[3]); + + pthread_mutex_unlock(&triggerMutex); + + return TCL_OK; +} +/*unregisters a trigger + *arg0: Vector name + *arg1: type + */ +static int unregisterTrigger(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ + int i, index, type; + char *var; + struct watch *tmp; + struct watch **cut; + + if (argc != 2 && argc != 3) { + Tcl_SetResult(interp, "Wrong # args. spice::unregisterTrigger vecName ?type?",TCL_STATIC); + return TCL_ERROR; + } + + var = argv[1]; + + for(i=0;i < blt_vnum && strcmp(var,vectors[i].name);i++); + + if(i == blt_vnum) { + Tcl_SetResult(interp, "Bad spice variable ",TCL_STATIC); + Tcl_AppendResult(interp, (char *)var, TCL_STATIC); + return TCL_ERROR; + } else index = i; + + if(argc == 3) + type = atoi(argv[4]); + else + type = 1; + + pthread_mutex_lock(&triggerMutex); + + cut = &watches; + + tmp = watches; + + while(tmp) + if(tmp->vector == index && tmp->type == type) { + struct watch *t = tmp; + *cut = tmp->next; + tmp = tmp->next; + FREE(t); + } else { + cut = &tmp->next; + tmp = tmp->next; + } + + pthread_mutex_unlock(&triggerMutex); + + return TCL_OK; +} + +/* returns: +"vecName" "time" "stepNumber" "type" +*/ +static int popTriggerEvent(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ + + if (argc != 1) { + Tcl_SetResult(interp, "Wrong # args. spice::popTriggerEvent",TCL_STATIC); + return TCL_ERROR; + } + + if(eventQueue) { + struct triggerEvent *popedEvent; + Tcl_Obj *list; + + pthread_mutex_lock(&triggerMutex); + + popedEvent = eventQueue; + + eventQueue = popedEvent->next; + + + list = Tcl_NewListObj(0,NULL); + + Tcl_ListObjAppendElement(interp,list,Tcl_NewStringObj(vectors[popedEvent->vector].name,strlen(vectors[popedEvent->vector].name))); + + Tcl_ListObjAppendElement(interp,list,Tcl_NewDoubleObj(popedEvent->time)); + + Tcl_ListObjAppendElement(interp,list,Tcl_NewIntObj(popedEvent->stepNumber)); + + Tcl_ListObjAppendElement(interp,list,Tcl_NewIntObj(popedEvent->type)); + + Tcl_SetObjResult(interp,list); + + FREE(popedEvent); + + pthread_mutex_unlock(&triggerMutex); + } + + return TCL_OK; +} + +static int listTriggers(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){ + struct watch *tmp; + Tcl_Obj *list; + + if (argc != 1) { + Tcl_SetResult(interp, "Wrong # args. spice::listTriggers",TCL_STATIC); + return TCL_ERROR; + } + + list = Tcl_NewListObj(0,NULL); + + pthread_mutex_lock(&triggerMutex); + + for(tmp=watches;tmp;tmp=tmp->next) + Tcl_ListObjAppendElement(interp,list,Tcl_NewStringObj(vectors[tmp->vector].name,strlen(vectors[tmp->vector].name))); + + pthread_mutex_unlock(&triggerMutex); + + Tcl_SetObjResult(interp,list); + + return TCL_OK; +} + + +/*******************************************************/ +/* Initialise spice and setup native methods */ +/*******************************************************/ + +#ifdef __MINGW32__ +__declspec(dllexport) +#endif +int Spice_Init(Tcl_Interp *interp) { + + if (interp == 0) return TCL_ERROR; + +#ifdef USE_TCL_STUBS + if(Tcl_InitStubs(interp, (char *)"8.1",0) == NULL) + return TCL_ERROR; +#endif + + Tcl_PkgProvide(interp, (char*)TCLSPICE_name, (char*)TCLSPICE_version); + + Tcl_Eval(interp, "namespace eval " TCLSPICE_namespace " { }"); + + { + extern void DevInit(); + int i; + char *key; + Tcl_CmdInfo infoPtr; + char buf[256]; + + ft_rawfile = NULL; + ivars( ); + + cp_in = stdin; + cp_out = stdout; + cp_err = stderr; + + /*timer*/ + init_time( ); + + /*IFsimulator struct initilised*/ + SIMinit(&nutmeginfo, &ft_sim); + + /* program name*/ + cp_program = ft_sim->simulator; + + srandom(getpid()); + + /*parameter fetcher, used in show*/ + if_getparam = spif_getparam; + + /*Command prompt stuff */ + ft_cpinit(); + + /* initilise Tk display */ + DevInit(); + + /*parrallel arch support, or not */ + ARCHme = 0; + ARCHsize = 1; + + /* init the mutex */ + pthread_mutex_init(&triggerMutex,NULL); + + /*register functions*/ + for (i = 0;(key = cp_coms[i].co_comname); i++) { + sprintf(buf,"%s%s",TCLSPICE_prefix,key); + if(Tcl_GetCommandInfo(interp,buf, &infoPtr)!= 0){ + printf("Command '%s' can not be registered!\n", buf); + }else{ + Tcl_CreateCommand(interp,buf, _tcl_dispatch, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + } + } + + Tcl_CreateCommand(interp, TCLSPICE_prefix "spice_header", spice_header, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "spice_data", spice_data, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "spicetoblt", spicetoblt, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "lastVector", lastVector, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "spice", _spice_dispatch, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "get_output", get_output, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "bg", _tcl_dispatch, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "halt", _tcl_dispatch, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "get_param", get_param, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "delta", delta, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "maxstep", maxstep, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "running", running, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_variables", plot_variables, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_get_value", plot_get_value, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_datapoints", plot_datapoints, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_title", plot_title, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_date", plot_date, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_name", plot_name, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_nvars", plot_nvars, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "registerTrigger", registerTrigger, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "popTriggerEvent", popTriggerEvent, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "unregisterTrigger", unregisterTrigger, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "listTriggers", listTriggers, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + + Tcl_LinkVar(interp, TCLSPICE_prefix "steps_completed", (char *)&steps_completed, TCL_LINK_READ_ONLY|TCL_LINK_INT); + Tcl_LinkVar(interp, TCLSPICE_prefix "blt_vnum", (char *)&blt_vnum, TCL_LINK_READ_ONLY|TCL_LINK_INT); + } + return TCL_OK; +} diff --git a/src/xspice/Makefile.am b/src/xspice/Makefile.am new file mode 100755 index 000000000..e0e1c6a10 --- /dev/null +++ b/src/xspice/Makefile.am @@ -0,0 +1,16 @@ +# Process this file with automake +CFLAGS = -g -O2 -Wall +CC = gcc +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) + +EXTRA_DIST = README + +SUBDIRS = mif cm enh evt ipc idn + +INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir) + +MAINTAINERCLEANFILES = Makefile.in + +all: xspice.o +xspice.o: + $(COMPILE) -c xspice.c diff --git a/src/xspice/README b/src/xspice/README new file mode 100755 index 000000000..29701bd34 --- /dev/null +++ b/src/xspice/README @@ -0,0 +1,24 @@ +Spice Opus / XSpice code model support. +-------------------------------------- + +Use configure flag --enable-xspice to compile the support in, +when you run the ./configure script. +This creates a new command, "codemodel", which you can +use to load a codemodel. + +Some codemodels are included in the xspice/lib directory +with some examples in xspice/examples, compiled for linux glibc. + +Make sure the the library dir, xspice/lib, is in your LD_LIBRARY_PATH +enviromental variable, otherwise the libs will not be found! + +To create codemodels go to http://www.fe.uni-lj.si/spice/welcome.html +and download their trial version of spice opus for the codemodel toolkit! + +TODO: + Intergrate the ipc stuff from XSpice. + Create ng-spice capacity to create codemodels (a perl script) + Ngspice crashes when you try to plot a digital node + +Stefan Jones + 19/2/2002 diff --git a/src/xspice/cm/Makefile.am b/src/xspice/cm/Makefile.am new file mode 100755 index 000000000..41bcc96fe --- /dev/null +++ b/src/xspice/cm/Makefile.am @@ -0,0 +1,17 @@ +## Process this file with automake to produce Makefile.in +# +# JW 3/9/01 - had a go and makeing an autoconf script. + +noinst_LIBRARIES = libcmxsp.a + +libcmxsp_a_SOURCES = \ +cm.c \ +cmevt.c \ +cmmeters.c \ +cmutil.c + + + +INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/xspice/cm/cm.c b/src/xspice/cm/cm.c new file mode 100755 index 000000000..6c5df7380 --- /dev/null +++ b/src/xspice/cm/cm.c @@ -0,0 +1,701 @@ +/* =========================================================================== +FILE CM.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains functions callable from user code models. + +INTERFACES + + cm_analog_alloc() + cm_analog_get_ptr() + cm_analog_integrate() + cm_analog_converge() + cm_analog_set_temp_bkpt() + cm_analog_set_perm_bkpt() + cm_analog_ramp_factor() + cm_analog_not_converged() + cm_analog_auto_partial() + + cm_message_get_errmsg() + cm_message_send() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ +#include "ngspice.h" +#include "cm.h" +#include "mif.h" +#include "cktdefs.h" +//#include "util.h" + + + + + +static void cm_static_integrate(int byte_index, + double integrand, + double *integral, + double *partial); + +/* + +cm_analog_alloc() + +This function is called from code model C functions to allocate +state storage for a particular instance. It computes the number +of doubles that need to be allocated in SPICE's state storage +vectors from the number of bytes specified in it's argument and +then allocates space for the states. An index into the SPICE +state-vectors is stored in the instance's data structure along +with a ``tag'' variable supplied by the caller so that the location +of the state storage area can be found by cm_analog_get_ptr(). + +*/ + +void *cm_analog_alloc( + int tag, /* The user-specified tag for this block of memory */ + int bytes) /* The number of bytes to allocate */ +{ + MIFinstance *here; + CKTcircuit *ckt; + + Mif_State_t *state; + + int doubles_needed; + int i; + + + /* Get the address of the ckt and instance structs from g_mif_info */ + here = g_mif_info.instance; + ckt = g_mif_info.ckt; + + /* Scan states in instance struct and see if tag has already been used */ + for(i = 0; i < here->num_state; i++) { + if(tag == here->state[i].tag) { + g_mif_info.errmsg = "ERROR - cm_analog_alloc() - Tag already used in previous call\n"; + return(NULL); + } + } + + /* Compute number of doubles needed and allocate space in ckt->CKTstates[i] */ + doubles_needed = bytes / sizeof(double) + 1; + + /* Allocate space in instance struct for this state descriptor */ + if(here->num_state == 0) { + here->num_state = 1; + here->state = (void *) MALLOC(sizeof(Mif_State_t)); + } + else { + here->num_state++; + here->state = (void *) REALLOC(here->state, + here->num_state * sizeof(Mif_State_t)); + } + + /* Fill in the members of the state descriptor struct */ + state = &(here->state[here->num_state - 1]); + state->tag = tag; + state->index = ckt->CKTnumStates; + state->doubles = doubles_needed; + state->bytes = bytes; + + + /* Add the states to the ckt->CKTstates vectors */ + ckt->CKTnumStates += doubles_needed; + for(i=0;i<=ckt->CKTmaxOrder+1;i++) { + if(ckt->CKTnumStates == doubles_needed) + ckt->CKTstates[i] = (double *) MALLOC(ckt->CKTnumStates * sizeof(double)); + else + ckt->CKTstates[i] = (double *) REALLOC(ckt->CKTstates[i], + ckt->CKTnumStates * sizeof(double)); + } + + /* Return pointer to the allocated space in state 0 */ + return( (void *) (ckt->CKTstates[0] + (ckt->CKTnumStates - doubles_needed))); + +} + + +/* +cm_analog_get_ptr() + +This function is called from code model C functions to return a +pointer to state storage allocated with cm_analog_alloc(). A tag +specified in its argument list is used to locate the state in +question. A second argument specifies whether the desired state +is for the current timestep or from a preceding timestep. The +location of the state in memory is then computed and returned. +*/ + +void *cm_analog_get_ptr( + int tag, /* The user-specified tag for this block of memory */ + int timepoint) /* The timepoint of interest - 0=current 1=previous */ +{ + MIFinstance *here; + CKTcircuit *ckt; + + Mif_State_t *state=NULL; + + Mif_Boolean_t got_tag; + + int i; + + + /* Get the address of the ckt and instance structs from g_mif_info */ + here = g_mif_info.instance; + ckt = g_mif_info.ckt; + + /* Scan states in instance struct and see if tag exists */ + for(got_tag = MIF_FALSE, i = 0; i < here->num_state; i++) { + if(tag == here->state[i].tag) { + state = &(here->state[i]); + got_tag = MIF_TRUE; + break; + } + } + + /* Return error if tag not found */ + if(! got_tag) { + g_mif_info.errmsg = "ERROR - cm_analog_get_ptr() - Bad tag\n"; + return(NULL); + } + + /* Return error if timepoint is not 0 or 1 */ + if((timepoint < 0) || (timepoint > 1)) { + g_mif_info.errmsg = "ERROR - cm_analog_get_ptr() - Bad timepoint\n"; + return(NULL); + } + + /* Return address of requested state in ckt->CKTstates[timepoint] vector */ + return( (void *) (ckt->CKTstates[timepoint] + state->index) ); + +} + + +/* +cm_analog_integrate() + +This function performs a numerical integration on the state +supplied in its argument list according to the integrand also +supplied in the argument list. The next value of the integral +and the partial derivative with respect to the integrand input is +returned. The integral argument must be a pointer to memory +previously allocated through a call to cm_analog_alloc(). If this is +the first call to cm_analog_integrate(), information is entered into the +instance structure to mark that the integral should be processed +by MIFtrunc and MIFconvTest. +*/ + +int cm_analog_integrate( + double integrand, /* The integrand */ + double *integral, /* The current and returned value of integral */ + double *partial) /* The partial derivative of integral wrt integrand */ +{ + + MIFinstance *here; + CKTcircuit *ckt; + + Mif_Intgr_t *intgr; + Mif_Boolean_t got_index; + + char *char_state0; + char *char_state; + + int byte_index; + int i; + + + /* Get the address of the ckt and instance structs from g_mif_info */ + here = g_mif_info.instance; + ckt = g_mif_info.ckt; + + /* Check to be sure we're in transient analysis */ + if(g_mif_info.circuit.anal_type != MIF_TRAN) { + g_mif_info.errmsg = + "ERROR - cm_analog_integrate() - Called in non-transient analysis\n"; + *partial = 0.0; + return(MIF_ERROR); + } + + /* Preliminary check to be sure argument was allocated by cm_analog_alloc() */ + if(ckt->CKTnumStates <= 0) { + g_mif_info.errmsg = + "ERROR - cm_analog_integrate() - Integral must be memory allocated by cm_analog_alloc()\n"; + *partial = 0.0; + return(MIF_ERROR); + } + + /* Compute byte offset from start of state0 vector */ + char_state0 = (char *) ckt->CKTstate0; + char_state = (char *) integral; + byte_index = char_state - char_state0; + + /* Check to be sure argument address is in range of state0 vector */ + if((byte_index < 0) || + (byte_index > ((ckt->CKTnumStates - 1) * sizeof(double)) ) ) { + g_mif_info.errmsg = + "ERROR - cm_analog_integrate() - Argument must be in state vector 0\n"; + *partial = 0.0; + return(MIF_ERROR); + } + + /* Scan the intgr array in the instance struct to see if already exists */ + for(got_index = MIF_FALSE, i = 0; i < here->num_intgr; i++) { + if(here->intgr[i].byte_index == byte_index) { + got_index = MIF_TRUE; + } + } + + /* Report error if not found and this is not the first load pass in tran analysis */ + if((! got_index) && (! g_mif_info.circuit.anal_init)) { + g_mif_info.errmsg = + "ERROR - cm_analog_integrate() - New integral and not initialization pass\n"; + *partial = 0.0; + return(MIF_ERROR); + } + + /* If new integral state, allocate space in instance */ + /* struct for this intgr descriptor and register it with */ + /* the cm_analog_converge() function */ + if(! got_index) { + if(here->num_intgr == 0) { + here->num_intgr = 1; + here->intgr = (void *) MALLOC(sizeof(Mif_Intgr_t)); + } + else { + here->num_intgr++; + here->intgr = (void *) REALLOC(here->intgr, + here->num_intgr * sizeof(Mif_Intgr_t)); + } + intgr = &(here->intgr[here->num_intgr - 1]); + intgr->byte_index = byte_index; + if(cm_analog_converge(integral)) { + printf("%s\n",g_mif_info.errmsg); + g_mif_info.errmsg = "ERROR - cm_analog_integrate() - Failure in cm_analog_converge() call\n"; + return(MIF_ERROR); + } + } + + /* Compute the new integral and the partial */ + cm_static_integrate(byte_index, integrand, integral, partial); + + return(MIF_OK); +} + + +/* +cm_analog_converge() + +This function registers a state variable allocated with +cm_analog_alloc() to be subjected to a convergence test at the end of +each iteration. The state variable must be a double. +Information is entered into the instance structure to mark that +the state variable should be processed by MIFconvTest. +*/ + +int cm_analog_converge( + double *state) /* The state to be converged */ +{ + MIFinstance *here; + CKTcircuit *ckt; + + Mif_Conv_t *conv; + + char *char_state0; + char *char_state; + + int byte_index; + int i; + + + /* Get the address of the ckt and instance structs from g_mif_info */ + here = g_mif_info.instance; + ckt = g_mif_info.ckt; + + /* Preliminary check to be sure argument was allocated by cm_analog_alloc() */ + if(ckt->CKTnumStates <= 0) { + g_mif_info.errmsg = + "ERROR - cm_analog_converge() - Argument must be memory allocated by cm_analog_alloc()\n"; + return(MIF_ERROR); + } + + /* Compute byte offset from start of state0 vector */ + char_state0 = (char *) ckt->CKTstate0; + char_state = (char *) state; + byte_index = char_state - char_state0; + + /* Check to be sure argument address is in range of state0 vector */ + if((byte_index < 0) || + (byte_index > ((ckt->CKTnumStates - 1) * sizeof(double)) ) ) { + g_mif_info.errmsg = + "ERROR - cm_analog_converge() - Argument must be in state vector 0\n"; + return(MIF_ERROR); + } + + /* Scan the conv array in the instance struct to see if already registered */ + /* If so, do nothing, just return */ + for(i = 0; i < here->num_conv; i++) { + if(here->conv[i].byte_index == byte_index) + return(MIF_OK); + } + + /* Allocate space in instance struct for this conv descriptor */ + if(here->num_conv == 0) { + here->num_conv = 1; + here->conv = (void *) MALLOC(sizeof(Mif_Conv_t)); + } + else { + here->num_conv++; + here->conv = (void *) REALLOC(here->conv, + here->num_conv * sizeof(Mif_Conv_t)); + } + + /* Fill in the conv descriptor data */ + conv = &(here->conv[here->num_conv - 1]); + conv->byte_index = byte_index; + conv->last_value = 1.0e30; /* There should be a better way ... */ + + return(MIF_OK); +} + + + +/* +cm_message_get_errmsg() + +This function returns the address of an error message string set +by a call to some code model support function. +*/ + +char *cm_message_get_errmsg(void) +{ + return(g_mif_info.errmsg); +} + + + + +/* +cm_analog_set_temp_bkpt() + +This function is called by a code model C function to set a +temporary breakpoint. These temporary breakpoints remain in +effect only until the next timestep is taken. A temporary +breakpoint added with a time less than the current time, but +greater than the last successful timestep causes the simulator to +abandon the current timestep and decrease the timestep to hit the +breakpoint. A temporary breakpoint with a time greater than the +current time causes the simulator to make the breakpoint the next +timepoint if the next timestep would produce a time greater than +that of the breakpoint. +*/ + + +int cm_analog_set_temp_bkpt( + double time) /* The time of the breakpoint to be set */ +{ + CKTcircuit *ckt; + + + /* Get the address of the ckt and instance structs from g_mif_info */ + ckt = g_mif_info.ckt; + + /* Make sure breakpoint is not prior to last accepted timepoint */ + if(time < ((ckt->CKTtime - ckt->CKTdelta) + ckt->CKTminBreak)) { + g_mif_info.errmsg = + "ERROR - cm_analog_set_temp_bkpt() - Time < last accepted timepoint\n"; + return(MIF_ERROR); + } + + /* If too close to a permanent breakpoint or the current time, discard it */ + if( (fabs(time - ckt->CKTbreaks[0]) < ckt->CKTminBreak) || + (fabs(time - ckt->CKTbreaks[1]) < ckt->CKTminBreak) || + (fabs(time - ckt->CKTtime) < ckt->CKTminBreak) ) + return(MIF_OK); + + /* If < current dynamic breakpoint, make it the current breakpoint */ + if( time < g_mif_info.breakpoint.current) + g_mif_info.breakpoint.current = time; + + return(MIF_OK); +} + + + + +/* +cm_analog_set_perm_bkpt() + +This function is called by a code model C function to set a +permanent breakpoint. These permanent breakpoints remain in +effect from the time they are introduced until the simulation +time equals or exceeds the breakpoint time. A permanent +breakpoint added with a time less than the current time, but +greater than the last successful timestep causes the simulator to +abandon the current timestep and decrease the timestep to hit the +breakpoint. A permanent breakpoint with a time greater than the +current time causes the simulator to make the breakpoint the next +timepoint if the next timestep would produce a time greater than +that of the breakpoint. +*/ + + +int cm_analog_set_perm_bkpt( + double time) /* The time of the breakpoint to be set */ +{ + CKTcircuit *ckt; + + + /* Get the address of the ckt and instance structs from g_mif_info */ + ckt = g_mif_info.ckt; + + /* Call cm_analog_set_temp_bkpt() to force backup if less than current time */ + if(time < (ckt->CKTtime + ckt->CKTminBreak)) + return(cm_analog_set_temp_bkpt(time)); + else + CKTsetBreak(ckt,time); + + return(MIF_OK); +} + + +/* +cm_analog_ramp_factor() + +This function returns the current value of the ramp factor +associated with the ``ramptime'' option. For this option +to work best, models with analog outputs that may be non-zero at +time zero should call this function and scale their outputs +and partials by the ramp factor. +*/ + + +double cm_analog_ramp_factor(void) +{ + + CKTcircuit *ckt; + + /* Get the address of the ckt and instance structs from g_mif_info */ + ckt = g_mif_info.ckt; + + + /* if ramptime == 0.0, no ramptime option given, so return 1.0 */ + /* this is the most common case, so it goes first */ + if(ckt->enh->ramp.ramptime == 0.0) + return(1.0); + + /* else if not transient analysis, return 1.0 */ + else if( (!(ckt->CKTmode & MODETRANOP)) && (!(ckt->CKTmode & MODETRAN)) ) + return(1.0); + + /* else if time >= ramptime, return 1.0 */ + else if(ckt->CKTtime >= ckt->enh->ramp.ramptime) + return(1.0); + + /* else time < end of ramp, so compute and return factor based on time */ + else + return(ckt->CKTtime / ckt->enh->ramp.ramptime); +} + + +/* ************************************************************ */ + + +/* + * Copyright (c) 1985 Thomas L. Quarles + * + * This is a modified version of the function NIintegrate() + * + * Modifications are Copyright 1991 Georgia Tech Research Institute + * + */ + +static void cm_static_integrate(int byte_index, + double integrand, + double *integral, + double *partial) +{ + CKTcircuit *ckt; + + double intgr[7]; + double cur=0; + double *double_ptr; + + double ceq; + double geq; + + char *char_ptr; + + int i; + + + /* Get the address of the ckt struct from g_mif_info */ + ckt = g_mif_info.ckt; + + /* Get integral values from current and previous timesteps */ + for(i = 0; i <= ckt->CKTorder; i++) { + char_ptr = (char *) ckt->CKTstates[i]; + char_ptr += byte_index; + double_ptr = (double *) char_ptr; + intgr[i] = *double_ptr; + } + + + /* Do what SPICE3C1 does for its implicit integration */ + + switch(ckt->CKTintegrateMethod) { + + case TRAPEZOIDAL: + + switch(ckt->CKTorder) { + + case 1: + cur = ckt->CKTag[1] * intgr[1]; + break; + + case 2: + /* WARNING - This code needs to be redone. */ + /* The correct code should rely on one previous value */ + /* of cur as done in NIintegrate() */ + cur = -0.5 * ckt->CKTag[0] * intgr[1]; + break; + } + + break; + + case GEAR: + cur = 0.0; + + switch(ckt->CKTorder) { + + case 6: + cur += ckt->CKTag[6] * intgr[6]; + /* fall through */ + case 5: + cur += ckt->CKTag[5] * intgr[5]; + /* fall through */ + case 4: + cur += ckt->CKTag[4] * intgr[4]; + /* fall through */ + case 3: + cur += ckt->CKTag[3] * intgr[3]; + /* fall through */ + case 2: + cur += ckt->CKTag[2] * intgr[2]; + /* fall through */ + case 1: + cur += ckt->CKTag[1] * intgr[1]; + break; + + } + break; + + } + + ceq = cur; + geq = ckt->CKTag[0]; + + /* WARNING: Take this out when the case 2: above is fixed */ + if((ckt->CKTintegrateMethod == TRAPEZOIDAL) && + (ckt->CKTorder == 2)) + geq *= 0.5; + + + /* The following code is equivalent to */ + /* the solution of one matrix iteration to produce the */ + /* integral value. */ + + *integral = (integrand - ceq) / geq; + *partial = 1.0 / geq; + +} + + + + + +/* +cm_analog_not_converged() + +This function tells the simulator not to allow the current +iteration to be the final iteration. It is called when +a code model performs internal limiting on one or more of +its inputs to assist convergence. +*/ + +void cm_analog_not_converged(void) +{ + (g_mif_info.ckt->CKTnoncon)++; +} + + + + +/* +cm_message_send() + +This function prints a message output from a code model, prepending +the instance name. +*/ + + +int cm_message_send( + char *msg) /* The message to output. */ +{ + MIFinstance *here; + + /* Get the address of the instance struct from g_mif_info */ + here = g_mif_info.instance; + + /* Print the name of the instance and the message */ + printf("\nInstance: %s Message: %s\n", (char *) here->MIFname, msg); + + return(0); +} + + + + + + +/* +cm_analog_auto_partial() + +This function tells the simulator to automatically compute +approximations of partial derivatives of analog outputs +with respect to analog inputs. When called from a code +model, it sets a flag in the g_mif_info structure +which tells function MIFload() and it's associated +MIFauto_partial() function to perform the necessary +calculations. +*/ + + +void cm_analog_auto_partial(void) +{ + g_mif_info.auto_partial.local = MIF_TRUE; +} + diff --git a/src/xspice/cm/cmevt.c b/src/xspice/cm/cmevt.c new file mode 100755 index 000000000..7854fa946 --- /dev/null +++ b/src/xspice/cm/cmevt.c @@ -0,0 +1,267 @@ +/* =========================================================================== +FILE CMevt.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains functions callable from user code models + that are associated with the event-driven algorithm. + +INTERFACES + + cm_event_alloc() + cm_event_get_ptr() + cm_event_queue() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + +#include "ngspice.h" +#include "cktdefs.h" +//#include "util.h" + +#include "cm.h" +#include "mif.h" +#include "evt.h" + +#include "evtproto.h" + + + + + +/* +cm_event_alloc() + +This function is called from code model C functions to allocate +state storage for a particular event-driven +instance. It is similar to the +function cm_analog_alloc() used by analog models, but allocates states +that are rotated during event-driven 'timesteps' instead of analog +timesteps. +*/ + + +void *cm_event_alloc( + int tag, /* The user-specified tag for the memory block */ + int bytes) /* The number of bytes to be allocated */ +{ + + int inst_index; + int num_tags; + + MIFinstance *here; + CKTcircuit *ckt; + + void *ptr; + + Evt_State_Desc_t **desc_ptr; + Evt_State_Desc_t *desc; + + Evt_State_Data_t *state_data; + Evt_State_t *state; + + + /* Get the address of the ckt and instance structs from g_mif_info */ + here = g_mif_info.instance; + ckt = g_mif_info.ckt; + + + /* If not initialization pass, return error */ + if(here->initialized) { + g_mif_info.errmsg = + "ERROR - cm_event_alloc() - Cannot alloc when not initialization pass\n"; + return(NULL); + } + + + /* Get pointers for fast access */ + inst_index = here->inst_index; + state_data = ckt->evt->data.state; + + + /* Scan state descriptor list to determine if tag is present and to */ + /* find the end of the list. Report error if duplicate tag */ + desc_ptr = &(state_data->desc[inst_index]); + desc = *desc_ptr; + num_tags = 1; + while(desc) { + if(desc->tag == tag) { + g_mif_info.errmsg = + "ERROR - cm_event_alloc() - Duplicate tag\n"; + return(NULL); + } + desc_ptr = &(desc->next); + desc = *desc_ptr; + num_tags++; + } + + /* Create a new state description structure at end of list */ + /* and fill in the data and update the total size */ + *desc_ptr = (void *) MALLOC(sizeof(Evt_State_Desc_t)); + desc = *desc_ptr; + desc->tag = tag; + desc->size = bytes; + desc->offset = state_data->total_size[inst_index]; + state_data->total_size[inst_index] += bytes; + + /* Create a new state structure if list starting at head is null */ + state = state_data->head[inst_index]; + if(state == NULL) { + state = (void *) MALLOC(sizeof(Evt_State_t)); + state_data->head[inst_index] = state; + } + + /* Create or enlarge the block and set the time */ + if(num_tags == 1) + state->block = MALLOC(state_data->total_size[inst_index]); + else + state->block = REALLOC(state->block, + state_data->total_size[inst_index]); + + state->step = g_mif_info.circuit.evt_step; + + + /* Return allocated memory */ + ptr = ((char *)state->block) + desc->offset; + return(ptr); +} + + + + + +/* +cm_event_get_ptr() + +This function is called from code model C functions to return a +pointer to state storage allocated with cm_event_alloc(). A tag +specified in its argument list is used to locate the state in +question. A second argument specifies whether the desired state +is for the current timestep or from a preceding timestep. The +location of the state in memory is then computed and returned. +*/ + + +void *cm_event_get_ptr( + int tag, /* The user-specified tag for the memory block */ + int timepoint) /* The timepoint - 0=current, 1=previous */ +{ + + int i; + int inst_index; + + MIFinstance *here; + CKTcircuit *ckt; + + void *ptr; + + Evt_State_Desc_t *desc; + + Evt_State_Data_t *state_data; + Evt_State_t *state; + + + /* Get the address of the ckt and instance structs from g_mif_info */ + here = g_mif_info.instance; + ckt = g_mif_info.ckt; + + + /* If initialization pass, return error */ + if((! here->initialized) && (timepoint > 0)) { + g_mif_info.errmsg = + "ERROR - cm_event_get_ptr() - Cannot get_ptr(tag,1) during initialization pass\n"; + return(NULL); + } + + /* Get pointers for fast access */ + inst_index = here->inst_index; + state_data = ckt->evt->data.state; + + /* Scan state descriptor list to find the descriptor for this tag. */ + /* Report error if tag not found */ + desc = state_data->desc[inst_index]; + while(desc) { + if(desc->tag == tag) + break; + desc = desc->next; + } + + if(desc == NULL) { + g_mif_info.errmsg = + "ERROR - cm_event_get_ptr() - Specified tag not found\n"; + return(NULL); + } + + /* Get the state pointer from the current array */ + state = *(state_data->tail[inst_index]); + + /* Backup the specified number of timesteps */ + for(i = 0; i < timepoint; i++) + if(state->prev) + state = state->prev; + + /* Return pointer */ + ptr = ((char *) state->block) + desc->offset; + return(ptr); +} + + + + +/* +cm_event_queue() + +This function queues an event for an instance participating +in the event-driven algorithm. +*/ + + +int cm_event_queue( + double time) /* The time of the event to be queued */ +{ + + MIFinstance *here; + CKTcircuit *ckt; + + + /* Get the address of the ckt and instance structs from g_mif_info */ + here = g_mif_info.instance; + ckt = g_mif_info.ckt; + + /* If breakpoint time <= current event time, return error */ + if(time <= g_mif_info.circuit.evt_step) { + g_mif_info.errmsg = + "ERROR - cm_event_queue() - Event time cannot be <= current time\n"; + return(MIF_ERROR); + } + + /* Add the event time to the inst queue */ + EVTqueue_inst(ckt, here->inst_index, g_mif_info.circuit.evt_step, + time); + + return(MIF_OK); +} diff --git a/src/xspice/cm/cmmeters.c b/src/xspice/cm/cmmeters.c new file mode 100755 index 000000000..d49ed794a --- /dev/null +++ b/src/xspice/cm/cmmeters.c @@ -0,0 +1,314 @@ +/* =========================================================================== +FILE CMmeters.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains functions callable from code models. + These functions are primarily designed for use by the + "cmeter" and "lmeter" models provided in the XSPICE + code model library. + +INTERFACES + + cm_netlist_get_c() + cm_netlist_get_l() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ +#include "ngspice.h" +#include "cm.h" +#include "mif.h" + +#include "cktdefs.h" + +#include "mifdefs.h" +#include "cap/capdefs.h" +#include "ind/inddefs.h" +#include "vsrc/vsrcdefs.h" +#include "inpdefs.h" + + + +/* +cm_netlist_get_c() + +This is a special function designed for use with the c_meter +model. It returns the parallel combination of the capacitance +connected to the first port on the instance. +*/ + +double cm_netlist_get_c() +{ + CKTcircuit *ckt; + + MIFinstance *cmeter_inst; + CAPinstance *cap_inst; + VSRCinstance *vsrc_inst; + + CAPmodel *cap_head; + CAPmodel *cap_model; + VSRCmodel *vsrc_head; + VSRCmodel *vsrc_model; + + int cap_type; + int vsrc_type; + + int cmeter_node; + int vsrc_node; + + double c; + + + /* Get the circuit data structure and current instance */ + ckt = g_mif_info.ckt; + cmeter_inst = g_mif_info.instance; + + /* Get internal node number for positive node of cmeter input */ + cmeter_node = cmeter_inst->conn[0]->port[0]->smp_data.pos_node; + + /* Initialize total capacitance value to zero */ + c = 0.0; + + + /* ****************************************************** */ + /* Look for capacitors connected directly to cmeter input */ + /* ****************************************************** */ + + /* Get the head of the list of capacitor models in the circuit */ + cap_type = INPtypelook("Capacitor"); + if(cap_type < 0) { + printf("\nERROR - Capacitor type not supported in this binary\n"); + return(0); + } + cap_head = (CAPmodel *) ckt->CKThead[cap_type]; + + /* Scan through all capacitor instances and add in values */ + /* of any capacitors connected to cmeter input */ + + for(cap_model = cap_head; cap_model; cap_model = cap_model->CAPnextModel) { + for(cap_inst = cap_model->CAPinstances; + cap_inst; + cap_inst = cap_inst->CAPnextInstance) { + if((cmeter_node == cap_inst->CAPposNode) || + (cmeter_node == cap_inst->CAPnegNode)) { + c += cap_inst->CAPcapac; + } + } + } + + + /* ***************************************************************** */ + /* Look for capacitors connected through zero-valued voltage sources */ + /* ***************************************************************** */ + + /* Get the head of the list of voltage source models in the circuit */ + vsrc_type = INPtypelook("Vsource"); + if(vsrc_type < 0) { + printf("\nERROR - Vsource type not supported in this binary\n"); + return(0); + } + vsrc_head = (VSRCmodel *) ckt->CKThead[vsrc_type]; + + /* Scan through all voltage source instances and add in values */ + /* of any capacitors connected to cmeter input through voltage source */ + + for(vsrc_model = vsrc_head; vsrc_model; vsrc_model = vsrc_model->VSRCnextModel) { + for(vsrc_inst = vsrc_model->VSRCinstances; + vsrc_inst; + vsrc_inst = vsrc_inst->VSRCnextInstance) { + + /* Skip to next if not DC source with value = 0.0 */ + if((vsrc_inst->VSRCfunctionType != 0) || + (vsrc_inst->VSRCdcValue != 0.0)) + continue; + + /* See if voltage source is connected to cmeter input */ + /* If so, get other node voltage source is connected to */ + /* If not, skip to next source */ + if(cmeter_node == vsrc_inst->VSRCposNode) + vsrc_node = vsrc_inst->VSRCnegNode; + else if(cmeter_node == vsrc_inst->VSRCnegNode) + vsrc_node = vsrc_inst->VSRCposNode; + else + continue; + + + /* Scan through all capacitor instances and add in values */ + /* of any capacitors connected to the voltage source node */ + + for(cap_model = cap_head; cap_model; cap_model = cap_model->CAPnextModel) { + for(cap_inst = cap_model->CAPinstances; + cap_inst; + cap_inst = cap_inst->CAPnextInstance) { + if((vsrc_node == cap_inst->CAPposNode) || + (vsrc_node == cap_inst->CAPnegNode)) { + c += cap_inst->CAPcapac; + } + } + } + + + } /* end for all vsrc instances */ + } /* end for all vsrc models */ + + + /* Return the total capacitance value */ + return(c); +} + + + + +/* +cm_netlist_get_l() + +This is a special function designed for use with the l_meter +model. It returns the equivalent value of inductance +connected to the first port on the instance. +*/ + + +double cm_netlist_get_l() +{ + CKTcircuit *ckt; + + MIFinstance *lmeter_inst; + INDinstance *ind_inst; + VSRCinstance *vsrc_inst; + + INDmodel *ind_head; + INDmodel *ind_model; + VSRCmodel *vsrc_head; + VSRCmodel *vsrc_model; + + int ind_type; + int vsrc_type; + + int lmeter_node; + int vsrc_node; + + double l; + + + /* Get the circuit data structure and current instance */ + ckt = g_mif_info.ckt; + lmeter_inst = g_mif_info.instance; + + /* Get internal node number for positive node of lmeter input */ + lmeter_node = lmeter_inst->conn[0]->port[0]->smp_data.pos_node; + + /* Initialize total inductance to infinity */ + l = 1.0e12; + + + /* ****************************************************** */ + /* Look for inductors connected directly to lmeter input */ + /* ****************************************************** */ + + /* Get the head of the list of inductor models in the circuit */ + ind_type = INPtypelook("Inductor"); + if(ind_type < 0) { + printf("\nERROR - Inductor type not supported in this binary\n"); + return(0); + } + ind_head = (INDmodel *) ckt->CKThead[ind_type]; + + /* Scan through all inductor instances and add in values */ + /* of any inductors connected to lmeter input */ + + for(ind_model = ind_head; ind_model; ind_model = ind_model->INDnextModel) { + for(ind_inst = ind_model->INDinstances; + ind_inst; + ind_inst = ind_inst->INDnextInstance) { + if((lmeter_node == ind_inst->INDposNode) || + (lmeter_node == ind_inst->INDnegNode)) { + l = 1.0 / ( (1.0 / l) + (1.0 / ind_inst->INDinduct) ); + } + } + } + + + /* ***************************************************************** */ + /* Look for inductors connected through zero-valued voltage sources */ + /* ***************************************************************** */ + + /* Get the head of the list of voltage source models in the circuit */ + vsrc_type = INPtypelook("Vsource"); + if(vsrc_type < 0) { + printf("\nERROR - Vsource type not supported in this binary\n"); + return(0); + } + vsrc_head = (VSRCmodel *) ckt->CKThead[vsrc_type]; + + /* Scan through all voltage source instances and add in values */ + /* of any inductors connected to lmeter input through voltage source */ + + for(vsrc_model = vsrc_head; vsrc_model; vsrc_model = vsrc_model->VSRCnextModel) { + for(vsrc_inst = vsrc_model->VSRCinstances; + vsrc_inst; + vsrc_inst = vsrc_inst->VSRCnextInstance) { + + /* Skip to next if not DC source with value = 0.0 */ + if((vsrc_inst->VSRCfunctionType != 0) || + (vsrc_inst->VSRCdcValue != 0.0)) + continue; + + /* See if voltage source is connected to lmeter input */ + /* If so, get other node voltage source is connected to */ + /* If not, skip to next source */ + if(lmeter_node == vsrc_inst->VSRCposNode) + vsrc_node = vsrc_inst->VSRCnegNode; + else if(lmeter_node == vsrc_inst->VSRCnegNode) + vsrc_node = vsrc_inst->VSRCposNode; + else + continue; + + + /* Scan through all inductor instances and add in values */ + /* of any inductors connected to the voltage source node */ + + for(ind_model = ind_head; ind_model; ind_model = ind_model->INDnextModel) { + for(ind_inst = ind_model->INDinstances; + ind_inst; + ind_inst = ind_inst->INDnextInstance) { + if((vsrc_node == ind_inst->INDposNode) || + (vsrc_node == ind_inst->INDnegNode)) { + l = 1.0 / ( (1.0 / l) + (1.0 / ind_inst->INDinduct) ); + } + } + } + + + } /* end for all vsrc instances */ + } /* end for all vsrc models */ + + + /* Return the total capacitance value */ + return(l); +} + + diff --git a/src/xspice/cm/cmutil.c b/src/xspice/cm/cmutil.c new file mode 100755 index 000000000..f0cfe8303 --- /dev/null +++ b/src/xspice/cm/cmutil.c @@ -0,0 +1,523 @@ +/* =========================================================================== +FILE CMutil.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Jeff Murray + +MODIFICATIONS + + + +SUMMARY + + This file contains functions callable from user code models. + These functions were written to support code models in the + XSPICE library, but may be useful in general. + +INTERFACES + + cm_smooth_corner() + cm_smooth_discontinuity() + cm_smooth_pwl() + + cm_climit_fcn() + + cm_complex_set() + cm_complex_add() + cm_complex_subtract() + cm_complex_multiply() + cm_complex_divide() + + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ +#include +#include +#include "cm.h" + +/* Corner Smoothing Function ************************************ +* * +* The following function smooths the transition between two * +* slopes into a quadratic (parabolic) curve. The calling * +* function passes an x,y coordinate representing the * +* "breakpoint", a smoothing domain value (d), and the slopes at * +* both endpoints, and the x value itself. The situation is * +* shown below: B C * +* A |<-d->| ^ y * +* ---------*-----* | | * +* lower_slope-^ |<-d->|\ | | * +* \ | | * +* \ | *------>x * +* At Ax * +*****************************************************************/ + +void cm_smooth_discontinuity( + double x_input, /* The x value at which to compute y */ + double x_lower, /* The x value of the lower corner */ + double y_lower, /* The y value of the lower corner */ + double x_upper, /* The x value of the upper corner */ + double y_upper, /* The y value of the upper corner */ + double *y_output, /* The computed smoothed y value */ + double *dy_dx) /* The partial of y wrt x */ +{ + double x_center,y_center,a,b,c,center_slope; + + + /* Derive x_center, y_center & center_slope values */ + x_center = (x_upper + x_lower) / 2.0; + y_center = (y_upper + y_lower) / 2.0; + center_slope = 2.0 * (y_upper - y_lower) / (x_upper - x_lower); + + + if (x_input < x_lower) { /* x_input @ lower level */ + *y_output = y_lower; + *dy_dx = 0.0; + } + else { + if (x_input < x_center) { /* x_input in lower transition */ + a = center_slope / (x_upper - x_lower); + b = center_slope - 2.0 * a * x_center; + c = y_center - a * x_center * x_center - b * x_center; + *y_output = a * x_input * x_input + b * x_input + c; + *dy_dx = 2.0 * a * x_input + b; + } + else { /* x_input in upper transition */ + if (x_input < x_upper) { + a = -center_slope / (x_upper - x_lower); + b = -2.0 * a * x_upper; + c = y_upper - a * x_upper * x_upper - b * x_upper; + *y_output = a * x_input * x_input + b * x_input + c; + *dy_dx = 2.0 * a * x_input + b; + } + else { /* x_input @ upper level */ + *y_output = y_upper; + *dy_dx = 0.0; + } + } + } +} + + + +/* Controlled Limiter Function (modified CLIMIT) */ + +/* +This is a special function created for use with the CLIMIT +controlled limiter model. +*/ + +void cm_climit_fcn( + double in, /* The input value */ + double in_offset, /* The input offset */ + double cntl_upper, /* The upper control input value */ + double cntl_lower, /* The lower control input value */ + double lower_delta, /* The delta from control to limit value */ + double upper_delta, /* The delta from control to limit value */ + double limit_range, /* The limiting range */ + double gain, /* The gain from input to output */ + int percent, /* The fraction vs. absolute range flag */ + double *out_final, /* The output value */ + double *pout_pin_final, /* The partial of output wrt input */ + double *pout_pcntl_lower_final, /* The partial of output wrt lower control input */ + double *pout_pcntl_upper_final) /* The partial of output wrt upper control input */ +{ + +/* Define error message string constants */ + +char *climit_range_error = "\n**** ERROR ****\n* CLIMIT function linear range less than zero. *\n"; + + +double threshold_upper,threshold_lower,linear_range, + out_lower_limit,out_upper_limit,limited_out, + out,pout_pin,pout_pcntl_lower,pout_pcntl_upper,junk; + + /* Find Upper & Lower Limits */ + + out_lower_limit = cntl_lower + lower_delta; + out_upper_limit = cntl_upper - upper_delta; + + + if (percent == TRUE) /* Set range to absolute value */ + limit_range = limit_range * + (out_upper_limit - out_lower_limit); + + + + threshold_upper = out_upper_limit - /* Set Upper Threshold */ + limit_range; + threshold_lower = out_lower_limit + /* Set Lower Threshold */ + limit_range; + linear_range = threshold_upper - threshold_lower; + + + /* Test the linear region & make sure there IS one... */ + if (linear_range < 0.0) { + printf("%s\n",climit_range_error); +/* limited_out = 0.0; + pout_pin = 0.0; + pout_pcntl_lower = 0.0; + pout_pcntl_upper = 0.0; + return; +*/ } + + /* Compute Un-Limited Output */ + out = gain * (in_offset + in); + + + if (out < threshold_lower) { /* Limit Out @ Lower Bound */ + + pout_pcntl_upper= 0.0; + + if (out > (out_lower_limit - limit_range)) { /* Parabolic */ + cm_smooth_corner(out,out_lower_limit,out_lower_limit, + limit_range,0.0,1.0,&limited_out, + &pout_pin); + pout_pin = gain * pout_pin; + cm_smooth_discontinuity(out,out_lower_limit,1.0,threshold_lower, + 0.0,&pout_pcntl_lower,&junk); + } + else { /* Hard-Limited Region */ + limited_out = out_lower_limit; + pout_pin = 0.0; + pout_pcntl_lower = 1.0; + } + } + else { + if (out > threshold_upper) { /* Limit Out @ Upper Bound */ + + pout_pcntl_lower= 0.0; + + if (out < (out_upper_limit+limit_range)) { /* Parabolic */ + cm_smooth_corner(out,out_upper_limit,out_upper_limit, + limit_range,1.0,0.0,&limited_out, + &pout_pin); + pout_pin = gain * pout_pin; + cm_smooth_discontinuity(out,threshold_upper,0.0,out_upper_limit, + 1.0,&pout_pcntl_upper,&junk); + } + else { /* Hard-Limited Region */ + limited_out = out_upper_limit; + pout_pin = 0.0; + pout_pcntl_upper = 1.0; + } + } + else { /* No Limiting Needed */ + limited_out = out; + pout_pin = gain; + pout_pcntl_lower = 0.0; + pout_pcntl_upper = 0.0; + } + } + + + *out_final = limited_out; + *pout_pin_final = pout_pin; + *pout_pcntl_lower_final = pout_pcntl_lower; + *pout_pcntl_upper_final = pout_pcntl_upper; + +} + +/**** End Controlled Limiter Function ****/ + +/*=============================================================================*/ + + +/* Piecewise Linear Smoothing Function ********************* +* The following is a transfer curve function which * +* accepts as input an "x" value, and returns a "y" * +* value. The transfer characteristic is a smoothed * +* piece-wise linear curve described by *x and *y array * +* coordinate pairs. * +* * +* Created 8/14/91 * +* Last Modified 8/14/91 J.P.Murray * +***********************************************************/ + +/*********************************************************** +* * +* ^ x[4] * +* x[1] | * * +* | midpoint /|\ * +* | | / \ * +* | V | / | \ * +* *----*----* \ * +* midpoint /| | | \ * +* | / || * <- midpoint * +* V/ | |x[3] \ * +* <-----------*------------O------------\-------------> * +* | / | \ | | * +* / | \ * +* |/ | \| | * +* * | *-----*---> * +* /| | x[5] x[6] * +* / | * +* / x[0] | * +* / | * +* / | * +* / | * +* V * +* * +***********************************************************/ + +/*********************************************************** +* * +* Note that for the cm_smooth_pwl function, the arguments * +* are as listed below: * +* * +* * +* double x_input; input * * +* double *x; pointer to the x-coordinate * +* array * * +* double *y; pointer to the y-coordinate * +* array * * +* int size; size of the arrays * +* * +* double input_domain; smoothing range * * +* double dout_din; partial derivative of the * +* output w.r.t. the input * * +* * +***********************************************************/ + + +double cm_smooth_pwl(double x_input, double *x, double *y, int size, + double input_domain, double *dout_din) +{ + + int i; /* generic loop counter index */ + + double lower_seg; /* x segment below which input resides */ + double upper_seg; /* x segment above which the input resides */ + double lower_slope; /* slope of the lower segment */ + double upper_slope; /* slope of the upper segment */ + double out; /* output */ + double threshold_lower; /* value below which the output begins smoothing */ + double threshold_upper; /* value above which the output begins smoothing */ + + + /* char *limit_error="\n***ERROR***\nViolation of 50% rule in breakpoints!\n";*/ + + + + + + /* Determine segment boundaries within which x_input resides */ + + if (x_input <= (*(x+1) + *x)/2.0) {/*** x_input below lowest midpoint ***/ + *dout_din = (*(y+1) - *y)/(*(x+1) - *x); + out = *y + (x_input - *x) * *dout_din; + } + else { + if (x_input >= (*(x+size-2) + *(x+size-1))/2.0) { + /*** x_input above highest midpoint ***/ + *dout_din = (*(y+size-1) - *(y+size-2)) / + (*(x+size-1) - *(x+size-2)); + out = *(y+size-1) + (x_input - *(x+size-1)) * *dout_din; + } + else { /*** x_input within bounds of end midpoints... ***/ + /*** must determine position progressively & then ***/ + /*** calculate required output. ***/ + + for (i=1; i + +SUMMARY + + This file contains routines used for general enhancements made + to the Berkeley SPICE3 core. + +INTERFACES + + ENHreport_conv_prob() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +/*=== INCLUDE FILES ===*/ + + +#include +#include "enh.h" + +/* +ENHreport_conv_prob() + +Report convergence problem messages from nodes, branch currents, +or instances. This function is setup to allow providing the SI +with information identifying the type of convergence problem. +For now, it simply writes to stdout. +*/ + + +void ENHreport_conv_prob( + Enh_Conv_Source_t type, /* node, branch, or instance */ + char *name, /* the name of the node/branch/instance */ + char *msg) /* an optional message */ +{ + + char *type_str; + char *msg_str; + + /* Convert the type enum to a string for printing */ + switch(type) { + + case ENH_ANALOG_NODE: + case ENH_EVENT_NODE: + type_str = "node"; + break; + + case ENH_ANALOG_BRANCH: + type_str = "branch current"; + break; + + case ENH_ANALOG_INSTANCE: + case ENH_EVENT_INSTANCE: + case ENH_HYBRID_INSTANCE: + type_str = "instance"; + break; + + default: + printf("\nERROR: Internal error in ENHreport_conv_prob - impossible type\n"); + return; + } + + /* Check for msg == NULL and turn into null string */ + if(msg) + msg_str = msg; + else + msg_str = ""; + + /* Print the convergence problem report */ + printf("\nWARNING: Convergence problems at %s (%s). %s\n", + type_str, name, msg_str); + +} /* ENHreport_conv_prob */ + diff --git a/src/xspice/enh/enhtrans.c b/src/xspice/enh/enhtrans.c new file mode 100755 index 000000000..a76ce2ea0 --- /dev/null +++ b/src/xspice/enh/enhtrans.c @@ -0,0 +1,437 @@ +/* =========================================================================== +FILE ENHtranslate_poly.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains functions used by the simulator in + calling the internal "poly" code model to substitute for + SPICE 2G6 style poly sources found in the input deck. + +INTERFACES + + ENHtranslate_poly() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + +/*=== FUNCTION PROTOTYPES ===*/ + +//void free(void *); //ka removed compiler error +/* int atoi(char *); */ + + +/*=== INCLUDE FILES ===*/ + + +/* #include "prefix.h" */ + +#include "ngspice.h" +//#include "misc.h" + +#include "fteinp.h" +#include "enh.h" +#include "cpdefs.h" +#include "ftedefs.h" +#include "mifproto.h" + +/* #include "suffix.h" */ + + +/*=== FUNCTION PROTOTYPES ===*/ + +static int needs_translating(char *card); +static int count_tokens(char *card); +static char *translate(char *orig_card, char **inst_card, + char **mod_card); +static int get_poly_dimension(char *card); + +// added as a quick bug fix, a lot of standard models have a linear poly(1) which +// fails in this code, Kevin Aylward April 15th 2000 +char * (*FPConvertSpicePoly1ToBsource)(char *card); // this is so I can use the MFC class libary +/* +ENHtranslate_poly() + +Translate all 2G6 style polynomial controlled sources in the deck +to new polynomial controlled source code model syntax. +*/ + + +struct line * ENHtranslate_poly( + struct line *deck) /* Linked list of lines in input deck */ +{ + struct line *d; + struct line *l1; + struct line *l2; + + char *card; + int poly_dimension; + char *buff; + + + /* Iterate through each card in the deck and translate as needed */ + for(d = deck; d; d = d->li_next) + { + + /* If doesn't need to be translated, continue to next card */ + if(! needs_translating(d->li_line)) + continue; + +// Start added as a quick fix to a xspice translation bug in poly(1) code +// Kevin Aylward April 15th 2000, fuck knows where it is + poly_dimension = get_poly_dimension(d->li_line); + + if(poly_dimension == 1)// + { + buff = (FPConvertSpicePoly1ToBsource)(d->li_line); + + if(buff) + { + FREE(d->li_line); + + d->li_line = buff; + } + + continue; + } +// End added as a quick fix to a xspice translation bug in poly(1) code +// Kevin Aylward April 15th 2000 + + + /* Create two new line structs and splice into deck */ +/* l1 = alloc(line); */ /* jgroves */ +/* l2 = alloc(line); */ /* jgroves */ + l1 = alloc(struct line); + l2 = alloc(struct line); + l2->li_next = d->li_next; + l1->li_next = l2; + d->li_next = l1; + + /* Create the translated cards */ + d->li_error = translate(d->li_line, &(l1->li_line), &(l2->li_line)); + + /* Comment out the original line */ + card = (void *) MALLOC(strlen(d->li_line) + 2); + strcpy(card,"*"); + strcat(card, d->li_line); + d->li_line = card; + + /* Advance deck pointer to last line added */ + d = l2; + } + + /* Return head of deck */ + return(deck); + +} /* ENHtranslate_poly */ + + + +/* +needs_translating() + +Test to see if card needs translating. Return true if card defines +an e,f,g, or h controlled source and has too many tokens to be +a simple linear dependent source. Otherwise return false. +*/ + + +static int needs_translating( + char *card) /* the card text to check */ +{ + + switch(*card) { + + case 'e': + case 'g': + if(count_tokens(card) <=6) + return(0); + else + return(1); + + case 'f': + case 'h': + if(count_tokens(card) <= 5) + return(0); + else + return(1); + + default: + return(0); + } + +} /* needs_translating */ + + + + +/* +count_tokens() + +Count and return the number of tokens on the card. +*/ + + +static int count_tokens( + char *card) /* the card text on which to count tokens */ +{ + int i; + + /* Get and count tokens until end of line reached */ + for(i = 0; *card != '\0'; i++) + txfree(MIFgettok(&card)); + + return(i); + +} /* count_tokens */ + + + +/* +translate() + +Do the syntax translation of the 2G6 source to the new code model syntax. +*/ + +static char *translate( + char *orig_card, /* the original untranslated card */ + char **inst_card, /* the instance card created by the translation */ + char **mod_card) /* the model card created by the translation */ +{ + int dim; + int num_tokens; + + int num_conns; + int num_coefs; + int inst_card_len; + int mod_card_len; + + int i; + + char type; + + char *name; + char **out_conn; + char **in_conn; + char **coef; + + char *card; + + + /* Get the first character into local storage for checking type */ + type = *orig_card; + + /* Count the number of tokens for use in parsing */ + num_tokens = count_tokens(orig_card); + + /* Determine the dimension of the poly source */ + dim = get_poly_dimension(orig_card); + if(dim <= 0) + return("ERROR - Argument to poly() is not an integer\n"); + + /* Compute number of input connections based on type and dimension */ + switch(type) { + case 'e': + case 'g': + num_conns = 2 * dim; + break; + + default: + num_conns = dim; + } + + /* Compute number of coefficients. Return error if less than one. */ + if(dim == 1) + num_coefs = num_tokens - num_conns - 3; + else + num_coefs = num_tokens - num_conns - 5; + + if(num_coefs < 1) + return("ERROR - Number of connections differs from poly dimension\n"); + + /* Split card into name, output connections, input connections, */ + /* and coefficients */ + + card = orig_card; + name = MIFgettok(&card); + + out_conn = (void *) MALLOC(2 * sizeof(char *)); + for(i = 0; i < 2; i++) + out_conn[i] = MIFgettok(&card); + + if(dim > 1) + for(i = 0; i < 2; i++) + txfree(MIFgettok(&card)); + + in_conn = (void *) MALLOC(num_conns * sizeof(char *)); + for(i = 0; i < num_conns; i++) + in_conn[i] = MIFgettok(&card); + + coef = (void *) MALLOC(num_coefs * sizeof(char *)); + for(i = 0; i < num_coefs; i++) + coef[i] = MIFgettok(&card); + + /* Compute the size needed for the new cards to be created */ + /* Allow a fair amount of extra space for connection types, etc. */ + /* to be safe... */ + + inst_card_len = 50; + inst_card_len += 2 * (strlen(name) + 1); + for(i = 0; i < 2; i++) + inst_card_len += strlen(out_conn[i]) + 1; + for(i = 0; i < num_conns; i++) + inst_card_len += strlen(in_conn[i]) + 1; + + mod_card_len = 50; + mod_card_len += strlen(name) + 1; + for(i = 0; i < num_coefs; i++) + mod_card_len += strlen(coef[i]) + 1; + + /* Allocate space for the cards and write them into the strings */ + + *inst_card = (void *) MALLOC(inst_card_len); + *mod_card = (void *) MALLOC(mod_card_len); + + strcpy(*inst_card, "a$poly$"); + sprintf(*inst_card + strlen(*inst_card), "%s ", name); + + if((type == 'e') || (type == 'g')) + sprintf(*inst_card + strlen(*inst_card), "%%vd [ "); + else + sprintf(*inst_card + strlen(*inst_card), "%%vnam [ "); + + for(i = 0; i < num_conns; i++) + sprintf(*inst_card + strlen(*inst_card), "%s ", in_conn[i]); + + sprintf(*inst_card + strlen(*inst_card), "] "); + + if((type == 'e') || (type == 'h')) + sprintf(*inst_card + strlen(*inst_card), "%%vd "); + else + sprintf(*inst_card + strlen(*inst_card), "%%id "); + + for(i = 0; i < 2; i++) + sprintf(*inst_card + strlen(*inst_card), "%s ", out_conn[i]); + + sprintf(*inst_card + strlen(*inst_card), "a$poly$%s", name); + + + sprintf(*mod_card, ".model a$poly$%s poly coef = [ ", name); + for(i = 0; i < num_coefs; i++) + sprintf(*mod_card + strlen(*mod_card), "%s ", coef[i]); + sprintf(*mod_card + strlen(*mod_card), "]"); + + + /* Free the temporary space */ + FREE(name); + name = NULL; + + for(i = 0; i < 2; i++) + { + FREE(out_conn[i]); + + out_conn[i] = NULL; + } + + FREE(out_conn); + + out_conn = NULL; + + for(i = 0; i < num_conns; i++) + { + FREE(in_conn[i]); + + in_conn[i] = NULL; + } + + FREE(in_conn); + + in_conn = NULL; + + for(i = 0; i < num_coefs; i++) + { + FREE(coef[i]); + coef[i] = NULL; + } + + FREE(coef); + + coef = NULL; + + /* Return NULL to indicate no error */ + return(NULL); + +} /* translate */ + + +/* +get_poly_dimension() + +Get the poly source dimension from the token immediately following +the 'poly' if any. If 'poly' is not present, return 1. If poly is +present and token following is a valid integer, return it. Else +return 0. +*/ + + +static int get_poly_dimension( + char *card) /* the card text */ +{ + + int i; + int dim; + char *tok; + + + /* Skip over name and output connections */ + for(i = 0; i < 3; i++) + txfree(MIFgettok(&card)); + + /* Check the next token to see if it is "poly" */ + /* If not, return a dimension of 1 */ + tok = MIFgettok(&card); + if(strcmp(tok, "poly")) + { + FREE(tok); + + tok = NULL; + + return(1); + } + + FREE(tok); + + /* Must have been "poly", so next line must be a number */ + /* Try to convert it. If successful, return the number */ + /* else, return 0 to indicate an error... */ + tok = MIFgettok(&card); + dim = atoi(tok); + FREE(tok); + + return(dim); + +} /* get_poly_dimension */ + diff --git a/src/xspice/evt/Makefile.am b/src/xspice/evt/Makefile.am new file mode 100755 index 000000000..d03788259 --- /dev/null +++ b/src/xspice/evt/Makefile.am @@ -0,0 +1,27 @@ +## Process this file with automake to produce Makefile.in +# +# JW 3/9/01 - had a go and makeing an autoconf script. + +noinst_LIBRARIES = libevtxsp.a + +libevtxsp_a_SOURCES = \ +evtaccept.c \ +evtcall_hybrids.c \ +evtdump.c \ +evtiter.c \ +evtnext_time.c \ +evtop.c \ +evtprint.c \ +evtsetup.c \ +evtbackup.c \ +evtdeque.c \ +evtinit.c \ +evtload.c \ +evtnode_copy.c \ +evtplot.c \ +evtqueue.c \ +evttermi.c + +INCLUDES = -I$(top_srcdir)/src/include + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/xspice/evt/evtaccept.c b/src/xspice/evt/evtaccept.c new file mode 100755 index 000000000..16973ed44 --- /dev/null +++ b/src/xspice/evt/evtaccept.c @@ -0,0 +1,170 @@ +/*============================================================================ +FILE EVTaccept.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains a function called at the end of a + successful (accepted) analog timepoint. It saves pointers + to the states of the queues and data at this accepted time. + +INTERFACES + + void EVTaccept(CKTcircuit *ckt, double time) + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +/*=== INCLUDE FILES ===*/ + +#include +#include +#include "cktdefs.h" + +#include "mif.h" +#include "evt.h" + + + +/* +EVTaccept() + +This function is called at the end of a successful (accepted) +analog timepoint. It saves pointers to the states of the +queues and data at this accepted time. +*/ + + + +void EVTaccept( + CKTcircuit *ckt, /* main circuit struct */ + double time) /* time at which analog soln was accepted */ +{ + + int i; + int index; + int num_modified; + + Evt_Inst_Queue_t *inst_queue; + Evt_Output_Queue_t *output_queue; + + Evt_Node_Data_t *node_data; + Evt_State_Data_t *state_data; + Evt_Msg_Data_t *msg_data; + + + /* Exit if no event instances */ + if(ckt->evt->counts.num_insts == 0) + return; + + /* Get often used pointers */ + inst_queue = &(ckt->evt->queue.inst); + output_queue = &(ckt->evt->queue.output); + + node_data = ckt->evt->data.node; + state_data = ckt->evt->data.state; + msg_data = ckt->evt->data.msg; + + + /* Process the inst queue */ + num_modified = inst_queue->num_modified; + /* Loop through list of items modified since last time */ + for(i = 0; i < num_modified; i++) { + /* Get the index of the inst modified */ + index = inst_queue->modified_index[i]; + /* Update last_step for this index */ + inst_queue->last_step[index] = inst_queue->current[index]; + /* Reset the modified flag */ + inst_queue->modified[index] = MIF_FALSE; + } + /* Record the new last_time and reset number modified to zero */ + inst_queue->last_time = time; + inst_queue->num_modified = 0; + + + /* Process the output queue */ + num_modified = output_queue->num_modified; + /* Loop through list of items modified since last time */ + for(i = 0; i < num_modified; i++) { + /* Get the index of the output modified */ + index = output_queue->modified_index[i]; + /* Update last_step for this index */ + output_queue->last_step[index] = output_queue->current[index]; + /* Reset the modified flag */ + output_queue->modified[index] = MIF_FALSE; + } + /* Record the new last_time and reset number modified to zero */ + output_queue->last_time = time; + output_queue->num_modified = 0; + + + /* Process the node data */ + num_modified = node_data->num_modified; + /* Loop through list of items modified since last time */ + for(i = 0; i < num_modified; i++) { + /* Get the index of the node modified */ + index = node_data->modified_index[i]; + /* Update last_step for this index */ + node_data->last_step[index] = node_data->tail[index]; + /* Reset the modified flag */ + node_data->modified[index] = MIF_FALSE; + } + /* Reset number modified to zero */ + node_data->num_modified = 0; + + + /* Process the state data */ + num_modified = state_data->num_modified; + /* Loop through list of items modified since last time */ + for(i = 0; i < num_modified; i++) { + /* Get the index of the state modified */ + index = state_data->modified_index[i]; + /* Update last_step for this index */ + state_data->last_step[index] = state_data->tail[index]; + /* Reset the modified flag */ + state_data->modified[index] = MIF_FALSE; + } + /* Reset number modified to zero */ + state_data->num_modified = 0; + + + /* Process the msg data */ + num_modified = msg_data->num_modified; + /* Loop through list of items modified since last time */ + for(i = 0; i < num_modified; i++) { + /* Get the index of the msg modified */ + index = msg_data->modified_index[i]; + /* Update last_step for this index */ + msg_data->last_step[index] = msg_data->tail[index]; + /* Reset the modified flag */ + msg_data->modified[index] = MIF_FALSE; + } + /* Reset number modified to zero */ + msg_data->num_modified = 0; + +} /* EVTaccept */ + + diff --git a/src/xspice/evt/evtbackup.c b/src/xspice/evt/evtbackup.c new file mode 100755 index 000000000..6ddc24cc6 --- /dev/null +++ b/src/xspice/evt/evtbackup.c @@ -0,0 +1,645 @@ +/*============================================================================ +FILE EVTbackup.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains a function that resets the queues and data + structures to their state at the new analog simulation time specified + following the rejection of an analog timestep by the DCtran routine. + +INTERFACES + + void EVTbackup(CKTcircuit *ckt, double new_time) + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + + +/*=== INCLUDE FILES ===*/ +#include +#include "ngspice.h" + +#include "cktdefs.h" +//#include "util.h" + +#include "mif.h" +#include "evt.h" + +#include "evtproto.h" + + + +/*=== FUNCTION PROTOTYPES ===*/ + + +static void EVTbackup_node_data(CKTcircuit *ckt, double new_time); +static void EVTbackup_state_data(CKTcircuit *ckt, double new_time); +static void EVTbackup_msg_data(CKTcircuit *ckt, double new_time); +static void EVTbackup_inst_queue(CKTcircuit *ckt, double new_time); +static void EVTbackup_output_queue(CKTcircuit *ckt, double new_time); + + + +/* +EVTbackup() + +This function resets the queues and data structures to their state +at the new analog simulation time specified. The algorithms in this file +assume the following timestep coordination between +analog and event-driven algorithms: + + while(not end of analysis) { + + while (next event time <= next analog time) { + do event solution with call_type = event_driven + if any instance set analog breakpoint < next analog time + set next analog time to breakpoint + } + + do analog timestep solution with call_type = analog + call all hybrid models with call_type = event_driven + + if(analog solution doesn't converge) + Call EVTbackup + else + Call EVTaccept + } +*/ + + +void EVTbackup( + CKTcircuit *ckt, /* the main circuit structure */ + double new_time) /* the time to backup to */ +{ + + + /* Backup the node data */ + EVTbackup_node_data(ckt, new_time); + + /* Backup the state data */ + EVTbackup_state_data(ckt, new_time); + + /* Backup the msg data */ + EVTbackup_msg_data(ckt, new_time); + + /* Backup the inst queue */ + EVTbackup_inst_queue(ckt, new_time); + + /* Backup the output queue */ + EVTbackup_output_queue(ckt, new_time); + + /* Record statistics */ + (ckt->evt->data.statistics->tran_time_backups)++; + +} /* EVTbackup */ + + + + +/* +EVTbackup_node_data() + +Reset the node structure data. +*/ + + +static void EVTbackup_node_data( + CKTcircuit *ckt, /* the main circuit structure */ + double new_time) /* the time to backup to */ +{ + + int i; + int j; + + int num_modified; + int node_index; + + Evt_Node_Info_t **node_table; + Evt_Node_Data_t *node_data; + Evt_Node_t **node_ptr; + Evt_Node_t *node; + Evt_Node_t *from_node; + Evt_Node_t *to_node; + Evt_Node_t *head; + Evt_Node_t *tail; + Evt_Node_t *free_head; + + /* Get pointers for quick access */ + node_data = ckt->evt->data.node; + node_table = ckt->evt->info.node_table; + + /* Loop through list of indexes modified since last accepted timepoint */ + num_modified = node_data->num_modified; + for(i = 0; i < num_modified; i++) { + + /* Get the needed node and udn indexes */ + node_index = node_data->modified_index[i]; + + /* Scan data for this node from last_step to determine new setting */ + /* for tail, and splice later data into the free list */ + node_ptr = node_data->last_step[node_index]; + node = *node_ptr; + while(1) { + if((node->next == NULL) || (node->next->step > new_time)) { + + /* Splice rest of list, if any, into free list */ + head = node->next; + if(head) { + tail = *(node_data->tail[node_index]); + free_head = node_data->free[node_index]; + node_data->free[node_index] = head; + tail->next = free_head; + } + + /* Set the tail */ + node_data->tail[node_index] = node_ptr; + node->next = NULL; + + break; + } + node_ptr = &(node->next); + node = node->next; + } + + /* Copy data from the location at tail to rhs and rhsold */ + from_node = *(node_data->tail[node_index]); + to_node = &(node_data->rhs[node_index]); + EVTnode_copy(ckt, node_index, from_node, &to_node); + to_node = &(node_data->rhsold[node_index]); + EVTnode_copy(ckt, node_index, from_node, &to_node); + + } /* end for number modified */ + + /* Update/compact the modified list */ + for(i = 0, j = 0; i < num_modified; i++) { + node_index = node_data->modified_index[i]; + /* If nothing after last_step, remove this index from the modified list */ + if((*(node_data->last_step[node_index]))->next == NULL) { + node_data->modified[node_index] = MIF_FALSE; + (node_data->num_modified)--; + } + /* else, keep the index */ + else { + node_data->modified_index[j] = node_data->modified_index[i]; + j++; + } + } + +} /* EVTbackup_node_data */ + + + +/* +EVTbackup_state_data() + +Reset the state structure data. +*/ + + +static void EVTbackup_state_data( + CKTcircuit *ckt, /* the main circuit structure */ + double new_time) /* the time to backup to */ +{ + int i; + int j; + + int num_modified; + int inst_index; + + Evt_State_Data_t *state_data; + + Evt_State_t **state_ptr; + Evt_State_t *state; + Evt_State_t *head; + Evt_State_t *tail; + Evt_State_t *free_head; + + /* Get pointers for quick access */ + state_data = ckt->evt->data.state; + + /* Loop through list of indexes modified since last accepted timepoint */ + num_modified = state_data->num_modified; + for(i = 0; i < num_modified; i++) { + + /* Get the inst index */ + inst_index = state_data->modified_index[i]; + + /* Scan data for this inst from last_step to determine new setting */ + /* for tail, and splice later data into the free list */ + state_ptr = state_data->last_step[inst_index]; + state = *state_ptr; + while(1) { + if((state->next == NULL) || (state->next->step > new_time)) { + + /* Splice rest of list, if any, into free list */ + head = state->next; + if(head) { + tail = *(state_data->tail[inst_index]); + free_head = state_data->free[inst_index]; + state_data->free[inst_index] = head; + tail->next = free_head; + } + + /* Set the tail */ + state_data->tail[inst_index] = state_ptr; + state->next = NULL; + + break; + } + state_ptr = &(state->next); + state = state->next; + } + } /* end for number modified */ + + /* Update/compact the modified list */ + for(i = 0, j = 0; i < num_modified; i++) { + inst_index = state_data->modified_index[i]; + /* If nothing after last_step, remove this index from the modified list */ + if((*(state_data->last_step[inst_index]))->next == NULL) { + state_data->modified[inst_index] = MIF_FALSE; + (state_data->num_modified)--; + } + /* else, keep the index */ + else { + state_data->modified_index[j] = state_data->modified_index[i]; + j++; + } + } + +} /* EVTbackup_state_data */ + + + +/* +EVTbackup_msg_data() + +Backup the message data. +*/ + + +static void EVTbackup_msg_data( + CKTcircuit *ckt, /* the main circuit structure */ + double new_time) /* the time to backup to */ +{ + int i; + int j; + + int num_modified; + int port_index; + + Evt_Msg_Data_t *msg_data; + + Evt_Msg_t **msg_ptr; + Evt_Msg_t *msg; + Evt_Msg_t *head; + Evt_Msg_t *tail; + Evt_Msg_t *free_head; + + /* Get pointers for quick access */ + msg_data = ckt->evt->data.msg; + + /* Loop through list of indexes modified since last accepted timepoint */ + num_modified = msg_data->num_modified; + for(i = 0; i < num_modified; i++) { + + /* Get the port index */ + port_index = msg_data->modified_index[i]; + + /* Scan data for this port from last_step to determine new setting */ + /* for tail, and splice later data into the free list */ + msg_ptr = msg_data->last_step[port_index]; + msg = *msg_ptr; + while(1) { + if((msg->next == NULL) || (msg->next->step > new_time)) { + + /* Splice rest of list, if any, into free list */ + head = msg->next; + if(head) { + tail = *(msg_data->tail[port_index]); + free_head = msg_data->free[port_index]; + msg_data->free[port_index] = head; + tail->next = free_head; + } + + /* Set the tail */ + msg_data->tail[port_index] = msg_ptr; + msg->next = NULL; + + break; + } + msg_ptr = &(msg->next); + msg = msg->next; + } + + } /* end for number modified */ + + /* Update/compact the modified list */ + for(i = 0, j = 0; i < num_modified; i++) { + port_index = msg_data->modified_index[i]; + /* If nothing after last_step, remove this index from the modified list */ + if((*(msg_data->last_step[port_index]))->next == NULL) { + msg_data->modified[port_index] = MIF_FALSE; + (msg_data->num_modified)--; + } + /* else, keep the index */ + else { + msg_data->modified_index[j] = msg_data->modified_index[i]; + j++; + } + } +} + + + +/* +EVTbackup_inst_queue() + +Backup data in inst queue. +*/ + + +static void EVTbackup_inst_queue( + CKTcircuit *ckt, /* the main circuit structure */ + double new_time) /* the time to backup to */ +{ + + int i; + int j; + + int num_modified; + int num_pending; + int inst_index; + + Evt_Inst_Queue_t *inst_queue; + + Evt_Inst_Event_t **inst_ptr; + Evt_Inst_Event_t *inst; + + double next_time; + double event_time; + + + /* Get pointers for quick access */ + inst_queue = &(ckt->evt->queue.inst); + + /* Loop through list of indexes modified since last accepted timepoint */ + /* and remove events with posted time > new_time */ + num_modified = inst_queue->num_modified; + for(i = 0; i < num_modified; i++) { + + /* Get the inst index */ + inst_index = inst_queue->modified_index[i]; + + /* Scan forward from last_step and cut out data with posted time */ + /* > new_time and add it to the free list */ + + inst_ptr = inst_queue->last_step[inst_index]; + inst = *inst_ptr; + + while(inst) { + if(inst->posted_time > new_time) { + *inst_ptr = inst->next; + inst->next = inst_queue->free[inst_index]; + inst_queue->free[inst_index] = inst; + inst = *inst_ptr; + } + else { + inst_ptr = &(inst->next); + inst = *inst_ptr; + } + } + + /* Scan forward from last_step and set current to first */ + /* event with event_time > new_time */ + + inst_ptr = inst_queue->last_step[inst_index]; + inst = *inst_ptr; + + while(inst) { + if(inst->event_time > new_time) + break; + inst_ptr = &((*inst_ptr)->next); + inst = *inst_ptr; + } + inst_queue->current[inst_index] = inst_ptr; + } + + /* Add set of items modified to set of items pending before updating the */ + /* pending list because things may have been pulled from the pending list */ + for(i = 0; i < num_modified; i++) { + j = inst_queue->modified_index[i]; + if(! inst_queue->pending[j]) { + inst_queue->pending[j] = MIF_TRUE; + inst_queue->pending_index[(inst_queue->num_pending)++] = j; + } + } + + /* Update the pending list and the next time by seeing if there */ + /* is anything at the location pointed to by current */ + next_time = 1e30; + num_pending = inst_queue->num_pending; + for(i = 0, j = 0; i < num_pending; i++) { + inst_index = inst_queue->pending_index[i]; + inst = *(inst_queue->current[inst_index]); + /* If nothing in queue at last_step, remove this index from the pending list */ + if(! inst) { + inst_queue->pending[inst_index] = MIF_FALSE; + (inst_queue->num_pending)--; + } + /* else, keep the index and update the next time */ + else { + inst_queue->pending_index[j] = inst_queue->pending_index[i]; + j++; + event_time = inst->event_time; + if(event_time < next_time) + next_time = event_time; + } + } + inst_queue->next_time = next_time; + + /* Update the modified list by looking for any queued events */ + /* with posted time > last_time */ + for(i = 0, j = 0; i < num_modified; i++) { + + inst_index = inst_queue->modified_index[i]; + inst = *(inst_queue->last_step[inst_index]); + + while(inst) { + if(inst->posted_time > inst_queue->last_time) + break; + inst = inst->next; + } + + if(! inst) { + inst_queue->modified[inst_index] = MIF_FALSE; + (inst_queue->num_modified)--; + } + else { + inst_queue->modified_index[j] = inst_queue->modified_index[i]; + j++; + } + } +} + + + + + +/* +EVTbackup_output_queue() + +Backup data in output queue. +*/ + + + +static void EVTbackup_output_queue( + CKTcircuit *ckt, /* the main circuit structure */ + double new_time) /* the time to backup to */ +{ + + int i; + int j; + + int num_modified; + int num_pending; + + int output_index; + + Evt_Output_Queue_t *output_queue; + + Evt_Output_Event_t **output_ptr; + Evt_Output_Event_t *output; + + double next_time; + double event_time; + + + /* Get pointers for quick access */ + output_queue = &(ckt->evt->queue.output); + + /* Loop through list of indexes modified since last accepted timepoint */ + /* and remove events with posted time > new_time */ + num_modified = output_queue->num_modified; + for(i = 0; i < num_modified; i++) { + + /* Get the output index */ + output_index = output_queue->modified_index[i]; + + /* Scan forward from last_step and cut out data with posted time */ + /* > new_time and add it to the free list */ + /* Also, unremove anything with removed time > new_time */ + + output_ptr = output_queue->last_step[output_index]; + output = *output_ptr; + + while(output) { + if(output->posted_time > new_time) { + *output_ptr = output->next; + output->next = output_queue->free[output_index]; + output_queue->free[output_index] = output; + output = *output_ptr; + } + else { + if(output->removed && (output->removed_time > new_time)) + output->removed = MIF_FALSE; + output_ptr = &(output->next); + output = *output_ptr; + } + } + + /* Scan forward from last_step and set current to first */ + /* event with event_time > new_time */ + + output_ptr = output_queue->last_step[output_index]; + output = *output_ptr; + + while(output) { + if(output->event_time > new_time) + break; + output_ptr = &((*output_ptr)->next); + output = *output_ptr; + } + output_queue->current[output_index] = output_ptr; + } + + /* Add set of items modified to set of items pending before updating the */ + /* pending list because things may have been pulled from the pending list */ + for(i = 0; i < num_modified; i++) { + j = output_queue->modified_index[i]; + if(! output_queue->pending[j]) { + output_queue->pending[j] = MIF_TRUE; + output_queue->pending_index[(output_queue->num_pending)++] = j; + } + } + + /* Update the pending list and the next time by seeing if there */ + /* is anything at the location pointed to by current */ + next_time = 1e30; + num_pending = output_queue->num_pending; + for(i = 0, j = 0; i < num_pending; i++) { + output_index = output_queue->pending_index[i]; + output = *(output_queue->current[output_index]); + /* If nothing in queue at last_step, remove this index from the pending list */ + if(! output) { + output_queue->pending[output_index] = MIF_FALSE; + (output_queue->num_pending)--; + } + /* else, keep the index and update the next time */ + else { + output_queue->pending_index[j] = output_queue->pending_index[i]; + j++; + event_time = output->event_time; + if(event_time < next_time) + next_time = event_time; + } + } + output_queue->next_time = next_time; + + /* Update the modified list by looking for any queued events */ + /* with posted time > last_time */ + for(i = 0, j = 0; i < num_modified; i++) { + + output_index = output_queue->modified_index[i]; + output = *(output_queue->last_step[output_index]); + + while(output) { + if(output->posted_time > output_queue->last_time) + break; + output = output->next; + } + + if(! output) { + output_queue->modified[output_index] = MIF_FALSE; + (output_queue->num_modified)--; + } + else { + output_queue->modified_index[j] = output_queue->modified_index[i]; + j++; + } + } +} diff --git a/src/xspice/evt/evtcall_hybrids.c b/src/xspice/evt/evtcall_hybrids.c new file mode 100755 index 000000000..f44146090 --- /dev/null +++ b/src/xspice/evt/evtcall_hybrids.c @@ -0,0 +1,78 @@ +/*============================================================================ +FILE EVTcall_hybrids.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains function EVTcall_hybrids which calls all models + which have both analog and event-driven ports. It is called following + successful evaluation of an analog iteration attempt to allow + events to be scheduled by the hybrid models. The 'CALL_TYPE' is set + to 'EVENT_DRIVEN' when the model is called from this function. + +INTERFACES + + void EVTcall_hybrids(CKTcircuit *ckt) + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + + +#include "ngspice.h" +#include "cktdefs.h" + +#include "evt.h" + +#include "evtproto.h" + + +/* +EVTcall_hybrids + +This function calls all the hybrid instances. It is called following +the successful evaluation of an analog iteration. +*/ + + +void EVTcall_hybrids( + CKTcircuit *ckt) /* the main circuit structure */ +{ + + int i; + int num_hybrids; + + int *hybrid_index; + + + /* Get needed data for fast access */ + num_hybrids = ckt->evt->counts.num_hybrids; + hybrid_index = ckt->evt->info.hybrid_index; + + /* Call EVTload for all hybrids */ + for(i = 0; i < num_hybrids; i++) + EVTload(ckt, hybrid_index[i]); + +} diff --git a/src/xspice/evt/evtdeque.c b/src/xspice/evt/evtdeque.c new file mode 100755 index 000000000..3f70ce18b --- /dev/null +++ b/src/xspice/evt/evtdeque.c @@ -0,0 +1,366 @@ +/*============================================================================ +FILE EVTdequeue.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains function EVTdequeue which removes any items on the + output and instance queues with event times matching the specified + simulation time. + +INTERFACES + + void EVTdequeue(CKTcircuit *ckt, double time) + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +#include + +#include "ngspice.h" + +#include "cktdefs.h" +//#include "util.h" + +#include "mif.h" +#include "evt.h" +#include "evtudn.h" + +#include "evtproto.h" + + +static void EVTdequeue_output(CKTcircuit *ckt, double time); +static void EVTdequeue_inst(CKTcircuit *ckt, double time); + +static void EVTprocess_output( + CKTcircuit *ckt, + int output_index, + void *value); + + +/* +EVTdequeue + +This function removes any items on the output and instance queues +with event times matching the specified simulation time. EVTiter +is then called to determine which instances need to be called. + +*/ + + +void EVTdequeue( + CKTcircuit *ckt, /* The circuit structure */ + double time) /* The event time of the events to dequeue */ +{ + + /* Take all items on output queue with matching time */ + /* and set changed flags in output queue */ + EVTdequeue_output(ckt, time); + + /* Take all items on inst queue with matching time */ + /* and set to_call flags in inst queue */ + EVTdequeue_inst(ckt, time); + +} + + +/* +EVTdequeue_output + +This function de-queues output events with times matching the +specified time. +*/ + +static void EVTdequeue_output( + CKTcircuit *ckt, /* The circuit structure */ + double time) /* The event time of the events to dequeue */ +{ + + int i; + int j; + + int num_pending; + int index; + int output_index; + + double next_time; + double event_time; + + Evt_Output_Queue_t *output_queue; + + Evt_Output_Event_t *output; + Evt_Output_Event_t **output_ptr; + + + /* Get pointers for fast access */ + output_queue = &(ckt->evt->queue.output); + + /* Exit if nothing pending on output queue or if next_time */ + /* != specified time */ + if(output_queue->num_pending == 0) + return; + if(output_queue->next_time != time) + return; + + /* Scan the list of outputs pending */ + num_pending = output_queue->num_pending; + for(i = 0; i < num_pending; i++) { + + /* Get the index of the output */ + index = output_queue->pending_index[i]; + + /* Get pointer to next event in queue at this index */ + output = *(output_queue->current[index]); + + /* If event time does not match current time, skip */ + if(output->event_time != time) + continue; + + /* It must match, so pull the event from the queue and process it */ + EVTprocess_output(ckt, index, output->value); + + /* Move current to point to next non-removed item in list */ + output_ptr = &(output->next); + output = *output_ptr; + while(output) { + if(! output->removed) + break; + output_ptr = &(output->next); + output = *output_ptr; + } + output_queue->current[index] = output_ptr; + + /* Mark that this index in the queue has been modified */ + if(! output_queue->modified[index]) { + output_queue->modified[index] = MIF_TRUE; + output_queue->modified_index[(output_queue->num_modified)++] = index; + } + } + + + /* Update/compact the pending list and update the next_time */ + next_time = 1e30; + for(i = 0, j = 0; i < num_pending; i++) { + output_index = output_queue->pending_index[i]; + output = *(output_queue->current[output_index]); + /* If nothing in queue at last_step, remove this index from the pending list */ + if(! output) { + output_queue->pending[output_index] = MIF_FALSE; + (output_queue->num_pending)--; + } + /* else, keep the index and update the next time */ + else { + output_queue->pending_index[j] = output_queue->pending_index[i]; + j++; + event_time = output->event_time; + if(event_time < next_time) + next_time = event_time; + } + } + output_queue->next_time = next_time; + + +} + + + +/* +EVTdequeue_inst + +This function de-queues instance events with times matching the +specified time. +*/ + + +void EVTdequeue_inst( + CKTcircuit *ckt, /* The circuit structure */ + double time) /* The event time of the events to dequeue */ +{ + + int i; + int j; + + int num_pending; + int index; + int inst_index; + + double next_time; + double event_time; + + Evt_Inst_Queue_t *inst_queue; + + Evt_Inst_Event_t *inst; + + + /* Get pointers for fast access */ + inst_queue = &(ckt->evt->queue.inst); + + /* Exit if nothing pending on inst queue or if next_time */ + /* != specified time */ + if(inst_queue->num_pending == 0) + return; + if(inst_queue->next_time != time) + return; + + /* Scan the list of insts pending */ + num_pending = inst_queue->num_pending; + for(i = 0; i < num_pending; i++) { + + /* Get the index of the inst */ + index = inst_queue->pending_index[i]; + + /* Get pointer to next event in queue at this index */ + inst = *(inst_queue->current[index]); + + /* If event time does not match current time, skip */ + if(inst->event_time != time) + continue; + + /* It must match, so pull the event from the queue and process it */ + if(! inst_queue->to_call[index]) { + inst_queue->to_call[index] = MIF_TRUE; + inst_queue->to_call_index[(inst_queue->num_to_call)++] = + index; + } + + /* Move current to point to next item in list */ + inst_queue->current[index] = &(inst->next); + + /* Mark that this index in the queue has been modified */ + if(! inst_queue->modified[index]) { + inst_queue->modified[index] = MIF_TRUE; + inst_queue->modified_index[(inst_queue->num_modified)++] = index; + } + } + + + /* Update/compact the pending list and update the next_time */ + next_time = 1e30; + for(i = 0, j = 0; i < num_pending; i++) { + inst_index = inst_queue->pending_index[i]; + inst = *(inst_queue->current[inst_index]); + /* If nothing in queue at last_step, remove this index from the pending list */ + if(! inst) { + inst_queue->pending[inst_index] = MIF_FALSE; + (inst_queue->num_pending)--; + } + /* else, keep the index and update the next time */ + else { + inst_queue->pending_index[j] = inst_queue->pending_index[i]; + j++; + event_time = inst->event_time; + if(event_time < next_time) + next_time = event_time; + } + } + inst_queue->next_time = next_time; + + + +} + + + +/* +EVTprocess_output + +This function processes a specified output after it is pulled +from the queue. +*/ + + +static void EVTprocess_output( + CKTcircuit *ckt, /* The circuit structure */ + int output_index, /* The index of the output to process */ + void *value) /* The output value */ +{ + + int num_outputs; + int node_index; + int udn_index; + int output_subindex; + + Evt_Output_Info_t **output_table; + Evt_Node_Info_t **node_table; + + Evt_Node_t *rhs; + Evt_Node_t *rhsold; + + Evt_Output_Queue_t *output_queue; + + Mif_Boolean_t equal; + + + output_table = ckt->evt->info.output_table; + node_table = ckt->evt->info.node_table; + + node_index = output_table[output_index]->node_index; + num_outputs = node_table[node_index]->num_outputs; + udn_index = node_table[node_index]->udn_index; + + rhs = ckt->evt->data.node->rhs; + rhsold = ckt->evt->data.node->rhsold; + + /* Determine if output is different from rhsold value */ + /* and copy it to rhs AND rhsold if so */ + /* This is somewhat inefficient, but that's the way */ + /* we have setup the structures (rhs and rhsold must match)... */ + if(num_outputs > 1) { + output_subindex = output_table[output_index]->output_subindex; + (*(g_evt_udn_info[udn_index]->compare)) + (value, + rhsold[node_index].output_value[output_subindex], + &equal); + if(! equal) { + (*(g_evt_udn_info[udn_index]->copy)) + (value, rhs[node_index].output_value[output_subindex]); + (*(g_evt_udn_info[udn_index]->copy)) + (value, rhsold[node_index].output_value[output_subindex]); + } + } + else { + (*(g_evt_udn_info[udn_index]->compare)) + (value, + rhsold[node_index].node_value, + &equal); + if(! equal) { + (*(g_evt_udn_info[udn_index]->copy)) + (value, rhs[node_index].node_value); + (*(g_evt_udn_info[udn_index]->copy)) + (value, rhsold[node_index].node_value); + } + } + + /* If different, put in changed list of output queue */ + if(! equal) { + output_queue = &(ckt->evt->queue.output); + if(! output_queue->changed[output_index]) { + output_queue->changed[output_index] = MIF_TRUE; + output_queue->changed_index[(output_queue->num_changed)++] = + output_index; + } + } +} diff --git a/src/xspice/evt/evtdump.c b/src/xspice/evt/evtdump.c new file mode 100755 index 000000000..6bb016791 --- /dev/null +++ b/src/xspice/evt/evtdump.c @@ -0,0 +1,350 @@ +/*============================================================================ +FILE EVTdump.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 6/15/92 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains functions used + to send event-driven node results data to the IPC channel when + the simulator is used with CAE software. + +INTERFACES + + EVTdump() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + + +#include +#include + +#include "ngspice.h" +//#include "misc.h" + +#include "cktdefs.h" +//#include "util.h" +#include "sperror.h" + +#include "mif.h" +#include "evt.h" +#include "evtproto.h" +#include "evtudn.h" + +#include "ipc.h" +#include "ipctiein.h" +#include "ipcproto.h" + + + +static void EVTsend_line( + int ipc_index, /* The index used in the dictionary */ + double step, /* The analysis step */ + void *node_value, /* The node value */ + int udn_index); /* The user-defined node index */ + + + +/* +EVTdump + +This function is called to send event-driven node data to the IPC +channel. A ``mode'' argument determines how the data is located in +the event data structure and what data is sent. + +If the mode is DCOP, then this is necessarily the first call to +the function. In this case, the set of event-driven nodes is +scanned to determine which should be sent. Only nodes that are +not inside subcircuits are sent. Next, the function sends +a ``dictionary'' of node names/types vs. node indexes. +Finally, the function sends the DC operating point solutions +for the event-driven nodes in the dictionary. + +If the mode is DCTRCURVE, it is assumed that the function has +already been called with mode = DCOP. The function scans the solution +vector and sends data for any nodes that have changed. + +If the mode is TRAN, it is assumed that the function has already +been called once with mode = DCOP. The function scans the +event data for nodes that have changed since the last accepted +analog timepoint and sends the new data. + +Note: This function must be called BEFORE calling EVTop_save or +EVTaccept() so that the state of the node data structure will allow +it to determine what has changed. +*/ + + +typedef struct evtdump_s { + Mif_Boolean_t send; /* True if this node should be sent */ + int ipc_index; /* Index for this node in dict sent to CAE system */ + char *node_name_str; /* Node name */ + char *udn_type_str; /* UDN type */ +} evtdump_dict_t; + + + +void EVTdump( + CKTcircuit *ckt, /* The circuit structure */ + Ipc_Anal_t mode, /* The analysis mode for this call */ + double step) /* The sweep step for a DCTRCURVE analysis, or */ + /* 0.0 for DCOP and TRAN */ +{ + static evtdump_dict_t *node_dict = NULL; + static int num_send_nodes; + + int i; + int j; + int num_nodes; + int num_modified; + int index; + + char *name; + int name_len; + + Mif_Boolean_t firstcall; + + Evt_Node_Data_t *node_data; + + Evt_Node_t *rhsold; + Evt_Node_t **head; + Evt_Node_t *here; + + Evt_Node_Info_t **node_table; + + char buff[10000]; + + Mif_Boolean_t equal; + + + /* Return immediately if IPC is not enabled */ + if(! g_ipc.enabled) + return; + + /* Get number of event-driven nodes */ + num_nodes = ckt->evt->counts.num_nodes; + + /* Exit immediately if no event-driven nodes in circuit */ + if(num_nodes <= 0) + return; + + + /* Get pointers for fast access to event data */ + node_data = ckt->evt->data.node; + node_table = ckt->evt->info.node_table; + rhsold = node_data->rhsold; + head = node_data->head; + + + /* Determine if this is the first call */ + if(node_dict == NULL) + firstcall = MIF_TRUE; + else + firstcall = MIF_FALSE; + + + /* If this is the first call, get the dictionary info */ + if(firstcall) { + + /* Allocate local data structure used to process nodes */ + node_dict = (void *) MALLOC(num_nodes * sizeof(evtdump_dict_t)); + + /* Loop through all nodes to determine which nodes should be sent. */ + /* Only nodes not within subcircuits qualify. */ + + num_send_nodes = 0; + for(i = 0; i < num_nodes; i++) { + + /* Get the name of the node. */ + name = node_table[i]->name; + + /* If name is in a subcircuit, mark that node should not be sent */ + /* and continue to next node. */ + name_len = strlen(name); + for(j = 0; j < name_len; j++) { + if(name[j] == ':') + break; + } + if(j < name_len) { + node_dict[i].send = MIF_FALSE; + continue; + } + + /* Otherwise, fill in info in dictionary. */ + node_dict[i].send = MIF_TRUE; + node_dict[i].ipc_index = num_send_nodes; + node_dict[i].node_name_str = name; + node_dict[i].udn_type_str = g_evt_udn_info[node_table[i]->udn_index]->name; + + /* Increment the count of nodes to be sent. */ + num_send_nodes++; + } /* end for */ + } /* end if first call */ + + + /* Exit if there are no nodes to be sent */ + if(num_send_nodes <= 0) + return; + + + /* If this is the first call, send the dictionary */ + if(firstcall) { + ipc_send_evtdict_prefix(); + for(i = 0; i < num_nodes; i++) { + if(node_dict[i].send) { + sprintf(buff, "%d %s %s", node_dict[i].ipc_index, + node_dict[i].node_name_str, + node_dict[i].udn_type_str); + ipc_send_line(buff); + } + } + ipc_send_evtdict_suffix(); + } + + /* If this is the first call, send the operating point solution */ + /* and return. */ + if(firstcall) { + ipc_send_evtdata_prefix(); + for(i = 0; i < num_nodes; i++) { + if(node_dict[i].send) { + EVTsend_line(node_dict[i].ipc_index, + step, + rhsold[i].node_value, + node_table[i]->udn_index); + } + } + ipc_send_evtdata_suffix(); + return; + } + + /* Otherwise, this must be DCTRCURVE or TRAN mode and we need to */ + /* send only stuff that has changed since the last call. */ + /* The determination of what to send is modeled after code in */ + /* EVTop_save() for DCTRCURVE and EVTaccept() for TRAN. */ + + if(mode == IPC_ANAL_DCTRCURVE) { + /* Send data prefix */ + ipc_send_evtdata_prefix(); + /* Loop through event nodes */ + for(i = 0; i < num_nodes; i++) { + /* If dictionary indicates this node should be sent */ + if(node_dict[i].send) { + /* Locate end of node data */ + here = head[i]; + for(;;) { + if(here->next) + here = here->next; + else + break; + } + /* Compare entry at end of list to rhsold */ + (*(g_evt_udn_info[node_table[i]->udn_index]->compare)) ( + rhsold[i].node_value, + here->node_value, + &equal); + /* If value in rhsold is different, send it */ + if(!equal) { + EVTsend_line(node_dict[i].ipc_index, + step, + rhsold[i].node_value, + node_table[i]->udn_index); + } + } + } + /* Send data suffix and return */ + ipc_send_evtdata_suffix(); + return; + } + + + if(mode == IPC_ANAL_TRAN) { + /* Send data prefix */ + ipc_send_evtdata_prefix(); + /* Loop through list of nodes modified since last time */ + num_modified = node_data->num_modified; + for(i = 0; i < num_modified; i++) { + /* Get the index of the node modified */ + index = node_data->modified_index[i]; + /* If dictionary indicates this node should be sent */ + if(node_dict[index].send) { + /* Scan through new events and send the data for each event */ + here = *(node_data->last_step[index]); + while((here = here->next)) { + EVTsend_line(node_dict[index].ipc_index, + here->step, + here->node_value, + node_table[index]->udn_index); + } + } + } + /* Send data suffix and return */ + ipc_send_evtdata_suffix(); + return; + } + +} + + + +/* +EVTsend_line + +This function formats the event node data and sends it to the IPC channel. +*/ + + +static void EVTsend_line( + int ipc_index, /* The index used in the dictionary */ + double step, /* The analysis step */ + void *node_value, /* The node value */ + int udn_index) /* The user-defined node index */ +{ + double dvalue; + char *svalue; + void *pvalue; + int len; + + /* Get the data to send */ + if(g_evt_udn_info[udn_index]->plot_val) + (*(g_evt_udn_info[udn_index]->plot_val)) (node_value, "", &dvalue); + else + dvalue = 0.0; + + if(g_evt_udn_info[udn_index]->print_val) + (*(g_evt_udn_info[udn_index]->print_val)) (node_value, "", &svalue); + else + svalue = ""; + + if(g_evt_udn_info[udn_index]->ipc_val) + (*(g_evt_udn_info[udn_index]->ipc_val)) (node_value, &pvalue, &len); + else { + pvalue = NULL; + len = 0; + } + + /* Send it to the IPC channel */ + ipc_send_event(ipc_index, step, dvalue, svalue, pvalue, len); +} diff --git a/src/xspice/evt/evtinit.c b/src/xspice/evt/evtinit.c new file mode 100755 index 000000000..1c59e01b1 --- /dev/null +++ b/src/xspice/evt/evtinit.c @@ -0,0 +1,437 @@ +/*============================================================================ +FILE EVTinit.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains function EVTinit which allocates and initializes + evt structure elements after the number of instances, nodes, etc. + have been determined in parsing during INPpas2. EVTinit also checks + to be sure no nodes have been used for both analog and event-driven + algorithms simultaneously. + +INTERFACES + + int EVTinit(CKTcircuit *ckt) + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +#include +#include +#include "ngspice.h" +#include "cktdefs.h" +//#include "util.h" +#include "sperror.h" + +#include "evtproto.h" + + + +static int EVTcheck_nodes(CKTcircuit *ckt); +static int EVTcount_hybrids(CKTcircuit *ckt); +static int EVTinit_info(CKTcircuit *ckt); +static int EVTinit_queue(CKTcircuit *ckt); +static int EVTinit_limits(CKTcircuit *ckt); + + + +/* Allocation macro with built-in check for out-of-memory */ +/* Adapted from SPICE 3C1 code in CKTsetup.c */ +#define CKALLOC(var,size,type) \ + if(size) { \ + if(!(var = (void *) MALLOC((size) * sizeof(type)))) \ + return(E_NOMEM); \ + } + + +/* +EVTinit + +Allocate and initialize additional evt structure elements now that +we can determine the number of instances, nodes, etc. + +Also check to be sure that no nodes have been used in both event-driven +and analog domains. + +In this version, we also report an error if there are no hybrids in the +circuit. This restriction may be removed in the future to allow the +simulator to be used with digital only circuits... +*/ + + +int EVTinit( + CKTcircuit *ckt) /* the circuit structure */ +{ + + int err; /* SPICE error return code 0 = OK */ + + /* static char *err_no_hybrids = "ERROR - no hybrids found in input deck";*/ + + + /* Exit immediately if there are no event-driven instances */ + /* but don't complain */ + if(ckt->evt->counts.num_insts == 0) + return(OK); + + /* Count the number of hybrids and hybrid outputs */ + err = EVTcount_hybrids(ckt); + if(err) + return(err); + + /* Exit with error if there are no hybrids in the circuit. */ + /* Will probably remove this restriction later... */ +/* + if(ckt->evt->counts.num_hybrids == 0) { + errMsg = MALLOC(strlen(err_no_hybrids) + 1); + strcpy(errMsg, err_no_hybrids); + return(E_PRIVATE); + } +*/ + /* Check that event nodes have not been used as analog nodes also */ + err = EVTcheck_nodes(ckt); + if(err) + return(err); + + /* Create info table arrays */ + err = EVTinit_info(ckt); + if(err) + return(err); + + /* Setup queues */ + err = EVTinit_queue(ckt); + if(err) + return(err); + + /* Initialize limits */ + err = EVTinit_limits(ckt); + if(err) + return(err); + + /* Note: Options were initialized in CKTinit so that INPpas2 */ + /* could set values according to .options cards in deck. The */ + /* structure 'jobs' will be setup immediately prior to each */ + /* simulation job. The results data structure is also */ + /* allocated immediately prior to each simulation job. */ + + /* Return */ + return(OK); +} + + +/* +EVTcount_hybrids + +Count the number of hybrids and the number of outputs on all hybrids. +*/ + +static int EVTcount_hybrids( + CKTcircuit *ckt) /* The circuit structure */ +{ + + int i; + int j; + + int num_hybrids; + int num_hybrid_outputs; + int num_conn; + int num_port; + + MIFinstance *fast; + + Evt_Inst_Info_t *inst; + + + /* Count number of hybrids and hybrid outputs in the inst list */ + /* created during parsing. Note: other counts */ + /* are created during parsing, but these were */ + /* too difficult to do until now... */ + num_hybrids = 0; + num_hybrid_outputs = 0; + inst = ckt->evt->info.inst_list; + while(inst) { + fast = inst->inst_ptr; + if(fast->analog && fast->event_driven) { + num_hybrids++; + num_conn = fast->num_conn; + for(i = 0; i < num_conn; i++) { + if((! fast->conn[i]->is_null) && (fast->conn[i]->is_output)) { + num_port = fast->conn[i]->size; + for(j = 0; j < num_port; j++) + if(! fast->conn[i]->port[j]->is_null) + num_hybrid_outputs++; + } + } + } + inst = inst->next; + } + ckt->evt->counts.num_hybrids = num_hybrids; + ckt->evt->counts.num_hybrid_outputs = num_hybrid_outputs; + + return(OK); +} + + +/* +EVTcheck_nodes + +Report error if any event node name is also used as an analog node. +*/ + + +static int EVTcheck_nodes( + CKTcircuit *ckt) /* The circuit structure */ +{ + + CKTnode *analog_node; + Evt_Node_Info_t *event_node; + + static char *err_prefix = "ERROR - node "; + static char *err_collide = " cannot be both analog and digital"; + + + /* Report error if any analog node name matches any event node name */ + event_node = ckt->evt->info.node_list; + while(event_node) { + analog_node = ckt->CKTnodes; + while(analog_node) { + if(strcmp(event_node->name, analog_node->name) == 0) { + errMsg = MALLOC(strlen(err_prefix) + strlen(event_node->name) + + strlen(err_collide) + 1); + sprintf(errMsg, "%s%s%s", err_prefix, + event_node->name, + err_collide); + + fprintf(stdout,errMsg); + + return(E_PRIVATE); + } + analog_node = analog_node->next; + } + event_node = event_node->next; + } + + /* Return */ + return(OK); +} + + +/* +EVTinit_info + +This function creates the ``info'' pointer tables used in the +event-driven circuit representation. These arrays allow faster +access to data associated with instances, nodes, ports, and +outputs than could be provided by having to scan the linked-list +representations created during parsing. +*/ + + +static int EVTinit_info( + CKTcircuit *ckt) /* the circuit structure */ +{ + + int i; + int j; + + int num_insts; + int num_nodes; + int num_ports; + int num_outputs; + + Evt_Inst_Info_t *inst; + Evt_Node_Info_t *node; + Evt_Port_Info_t *port; + Evt_Output_Info_t *output; + + Evt_Inst_Info_t **inst_table; + Evt_Node_Info_t **node_table; + Evt_Port_Info_t **port_table; + Evt_Output_Info_t **output_table; + + int *hybrid_index; + + int num_hybrids; + + + /* Allocate and initialize table of inst pointers */ + num_insts = ckt->evt->counts.num_insts; + CKALLOC(inst_table, num_insts, void *) + inst = ckt->evt->info.inst_list; + for(i = 0; i < num_insts; i++) { + inst_table[i] = inst; + inst = inst->next; + } + ckt->evt->info.inst_table = inst_table; + + /* Allocate and initialize table of node pointers */ + num_nodes = ckt->evt->counts.num_nodes; + CKALLOC(node_table, num_nodes, void *) + node = ckt->evt->info.node_list; + for(i = 0; i < num_nodes; i++) { + node_table[i] = node; + node = node->next; + } + ckt->evt->info.node_table = node_table; + + /* Allocate and initialize table of port pointers */ + num_ports = ckt->evt->counts.num_ports; + CKALLOC(port_table, num_ports, void *) + port = ckt->evt->info.port_list; + for(i = 0; i < num_ports; i++) { + port_table[i] = port; + port = port->next; + } + ckt->evt->info.port_table = port_table; + + /* Allocate and initialize table of output pointers */ + num_outputs = ckt->evt->counts.num_outputs; + CKALLOC(output_table, num_outputs, void *) + output = ckt->evt->info.output_list; + for(i = 0; i < num_outputs; i++) { + output_table[i] = output; + output = output->next; + } + ckt->evt->info.output_table = output_table; + + + /* Allocate and create table of indexes into inst_table for hybrids */ + num_hybrids = ckt->evt->counts.num_hybrids; + CKALLOC(hybrid_index, num_hybrids, int) + for(i = 0, j = 0; i < num_insts; i++) { + if(inst_table[i]->inst_ptr->analog) + hybrid_index[j++] = i; + } + ckt->evt->info.hybrid_index = hybrid_index; + + + /* Return */ + return(OK); +} + + + +/* +EVTinit_queue + +This function prepares the event-driven queues for simulation. +*/ + + +static int EVTinit_queue( + CKTcircuit *ckt) /* the circuit structure */ +{ + + int num_insts; + int num_nodes; + int num_outputs; + + Evt_Inst_Queue_t *inst_queue; + Evt_Node_Queue_t *node_queue; + Evt_Output_Queue_t *output_queue; + + + /* Allocate elements in the inst queue */ + + num_insts = ckt->evt->counts.num_insts; + inst_queue = &(ckt->evt->queue.inst); + + CKALLOC(inst_queue->head, num_insts, void *) + CKALLOC(inst_queue->current, num_insts, void *) + CKALLOC(inst_queue->last_step, num_insts, void *) + CKALLOC(inst_queue->free, num_insts, void *) + CKALLOC(inst_queue->modified_index, num_insts, int) + CKALLOC(inst_queue->modified, num_insts, Mif_Boolean_t) + CKALLOC(inst_queue->pending_index, num_insts, int) + CKALLOC(inst_queue->pending, num_insts, Mif_Boolean_t) + CKALLOC(inst_queue->to_call_index, num_insts, int) + CKALLOC(inst_queue->to_call, num_insts, Mif_Boolean_t) + + + /* Allocate elements in the node queue */ + + num_nodes = ckt->evt->counts.num_nodes; + node_queue = &(ckt->evt->queue.node); + + CKALLOC(node_queue->to_eval_index, num_nodes, int) + CKALLOC(node_queue->to_eval, num_nodes, Mif_Boolean_t) + CKALLOC(node_queue->changed_index, num_nodes, int) + CKALLOC(node_queue->changed, num_nodes, Mif_Boolean_t) + + + /* Allocate elements in the output queue */ + + num_outputs = ckt->evt->counts.num_outputs; + output_queue = &(ckt->evt->queue.output); + + CKALLOC(output_queue->head, num_outputs, void *) + CKALLOC(output_queue->current, num_outputs, void *) + CKALLOC(output_queue->last_step, num_outputs, void *) + CKALLOC(output_queue->free, num_outputs, void *) + CKALLOC(output_queue->modified_index, num_outputs, int) + CKALLOC(output_queue->modified, num_outputs, Mif_Boolean_t) + CKALLOC(output_queue->pending_index, num_outputs, int) + CKALLOC(output_queue->pending, num_outputs, Mif_Boolean_t) + CKALLOC(output_queue->changed_index, num_outputs, int) + CKALLOC(output_queue->changed, num_outputs, Mif_Boolean_t) + + + /* Return */ + return(OK); +} + + + + +/* +EVTinit_limits + +This function initializes the iteration limits applicable to the +event-driven algorithm. +*/ + + +static int EVTinit_limits( + CKTcircuit *ckt) /* the circuit structure */ +{ + + /* Set maximum number of event load calls within a single event iteration */ + /* to the number of event outputs. This should allow for the */ + /* maximum possible number of events that can trickle through any */ + /* circuit that does not contain loops. */ + + ckt->evt->limits.max_event_passes = ckt->evt->counts.num_outputs + 1; + + + /* Set maximum number of alternations between analog and event-driven */ + /* iterations to the number of event outputs on hybrids. */ + + ckt->evt->limits.max_op_alternations = ckt->evt->counts.num_hybrid_outputs + 1; + + + /* Return */ + return(OK); +} diff --git a/src/xspice/evt/evtiter.c b/src/xspice/evt/evtiter.c new file mode 100755 index 000000000..d53f0a651 --- /dev/null +++ b/src/xspice/evt/evtiter.c @@ -0,0 +1,300 @@ +/*============================================================================ +FILE EVTiter.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains function EVTiter which iterates through + event-driven outputs and instances until the outputs no longer change. + + +INTERFACES + + int EVTiter(CKTcircuit *ckt) + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +#include +#include + +#include "ngspice.h" +//#include "misc.h" +#include "cktdefs.h" +//#include "util.h" +#include "sperror.h" + +#include "mif.h" +#include "evt.h" +#include "evtudn.h" + +#include "evtproto.h" + + +/* +EVTiter + +This function iterates through event-driven outputs and instances +until the outputs no longer change. The general algorithm used +is: + +Do: + + Scan list of changed outputs + Put items on the node queue 'to_eval' list for + each changed output. + + Scan list of changed nodes + Resolve nodes with multiple outputs posted. + Create inverted state for nodes with attached + inverted inputs. + Put items on the instance queue 'to_call' list + for each changed node. + If transient analysis, put state of the node + into the node data structure. + + Scan instance to_call list + Call EVTload for each instance on list. + +While there are changed outputs + +*/ + + +int EVTiter( + CKTcircuit *ckt) /* the circuit structure */ +{ + + int i; + int num_changed; + + int num_to_eval; + int num_to_call; + + int output_index; + /* int output_subindex;*/ + int inst_index; + int node_index; + int port_index; + + int num_outputs; + int udn_index; + + int passes; + + Evt_Ckt_Data_t *evt; + + Evt_Output_Queue_t *output_queue; + Evt_Node_Queue_t *node_queue; + Evt_Inst_Queue_t *inst_queue; + + Evt_Output_Info_t **output_table; + Evt_Node_Info_t **node_table; + Evt_Port_Info_t **port_table; + + Evt_Inst_Index_t *inst_list; + + Evt_Node_Data_t *node_data; + + Evt_Node_t *rhs; + Evt_Node_t *rhsold; + + Evt_Node_t *node; + + Mif_Boolean_t equal; + + char *err_msg; + + + /* Get temporary pointers for fast access */ + evt = ckt->evt; + + output_queue = &(evt->queue.output); + node_queue = &(evt->queue.node); + inst_queue = &(evt->queue.inst); + + output_table = evt->info.output_table; + node_table = evt->info.node_table; + port_table = evt->info.port_table; + + node_data = evt->data.node; + rhs = node_data->rhs; + rhsold = node_data->rhsold; + + + /* Loop until no more output change, or too many passes through loop */ + for(passes = 0; passes < evt->limits.max_event_passes; passes++) { + + + /* Create list of nodes to evaluate from list of changed outputs */ + num_changed = output_queue->num_changed; + for(i = 0; i < num_changed; i++) { + + /* Get index of node that output is connected to */ + output_index = output_queue->changed_index[i]; + node_index = output_table[output_index]->node_index; + + /* If not already on list of nodes to evaluate, add it */ + if(! node_queue->to_eval[node_index]) { + node_queue->to_eval[node_index] = MIF_TRUE; + node_queue->to_eval_index[(node_queue->num_to_eval)++] + = node_index; + } + + /* Reset the changed flag on the output queue */ + output_queue->changed[output_index] = MIF_FALSE; + + } + output_queue->num_changed = 0; + + + + /* Evaluate nodes and for any which have changed, enter */ + /* the instances that receive inputs from them on the list */ + /* of instances to call */ + + num_to_eval = node_queue->num_to_eval; + for(i = 0; i < num_to_eval; i++) { + + /* Get the node index, udn index and number of outputs */ + node_index = node_queue->to_eval_index[i]; + udn_index = node_table[node_index]->udn_index; + num_outputs = node_table[node_index]->num_outputs; + + /* Resolve the node value if multiple outputs on it */ + /* and test if new node value is different than old value */ + if(num_outputs > 1) { + (*(g_evt_udn_info[udn_index]->resolve)) + (num_outputs, + rhs[node_index].output_value, + rhs[node_index].node_value); + (*(g_evt_udn_info[udn_index]->compare)) + (rhs[node_index].node_value, + rhsold[node_index].node_value, + &equal); + if(! equal) { + (*(g_evt_udn_info[udn_index]->copy)) + (rhs[node_index].node_value, + rhsold[node_index].node_value); + } + } + /* Else, load function has already determined that they were */ + /* not equal */ + else + equal = MIF_FALSE; + + /* If not equal, make inverted copy in rhsold if */ + /* needed, and place indexes of instances with inputs connected */ + /* to the node in the to_call list of inst queue */ + if(! equal) { + if(node_table[node_index]->invert) { + (*(g_evt_udn_info[udn_index]->copy)) + (rhsold[node_index].node_value, + rhsold[node_index].inverted_value); + (*(g_evt_udn_info[udn_index]->invert)) + (rhsold[node_index].inverted_value); + } + inst_list = node_table[node_index]->inst_list; + while(inst_list) { + inst_index = inst_list->index; + if(! inst_queue->to_call[inst_index]) { + inst_queue->to_call[inst_index] = MIF_TRUE; + inst_queue->to_call_index[(inst_queue->num_to_call)++] + = inst_index; + } + inst_list = inst_list->next; + } /* end while instances with inputs on node */ + } /* end if not equal */ + + /* If transient analysis mode */ + /* Save the node data onto the node results list and mark */ + /* that it has been modified, even if the */ + /* resolved node value has not changed */ + if(g_mif_info.circuit.anal_type == MIF_TRAN) { + + node = *(node_data->tail[node_index]); + node_data->tail[node_index] = &(node->next); + EVTnode_copy(ckt, node_index, &(rhsold[node_index]), &(node->next)); + node->next->step = g_mif_info.circuit.evt_step; + + if(! node_data->modified[node_index]) { + node_data->modified[node_index] = MIF_TRUE; + node_data->modified_index[(node_data->num_modified)++] = node_index; + } + } + + /* Reset the to_eval flag on the node queue */ + node_queue->to_eval[node_index] = MIF_FALSE; + + } /* end for number of nodes to evaluate */ + node_queue->num_to_eval = 0; + + + + /* Call the instances with inputs on nodes that have changed */ + num_to_call = inst_queue->num_to_call; + for(i = 0; i < num_to_call; i++) { + inst_index = inst_queue->to_call_index[i]; + inst_queue->to_call[inst_index] = MIF_FALSE; + EVTload(ckt, inst_index); + } + inst_queue->num_to_call = 0; + + + /* Record statistics */ + if(g_mif_info.circuit.anal_type == MIF_DC) + (ckt->evt->data.statistics->op_event_passes)++; + + + /* If no outputs changed, iteration is over, so return with success! */ + if(output_queue->num_changed == 0) + return(0); + + } /* end for */ + + + /* Too many passes through loop, report problems and exit with error */ + + err_msg = MALLOC(10000); + for(i = 0; i < output_queue->num_changed; i++) { + output_index = output_queue->changed_index[i]; + port_index = output_table[output_index]->port_index; + sprintf(err_msg, "\n Instance: %s\n Connection: %s\n Port: %d", + port_table[port_index]->inst_name, + port_table[port_index]->conn_name, + port_table[port_index]->port_num); + ENHreport_conv_prob(ENH_EVENT_NODE, + port_table[port_index]->node_name, + err_msg); + } + FREE(err_msg); + + (*(SPfrontEnd->IFerror)) (ERR_WARNING, + "Too many iteration passes in event-driven circuits", + (IFuid *) NULL); + return(E_ITERLIM); + +} diff --git a/src/xspice/evt/evtload.c b/src/xspice/evt/evtload.c new file mode 100755 index 000000000..606ec4cf2 --- /dev/null +++ b/src/xspice/evt/evtload.c @@ -0,0 +1,613 @@ +/*============================================================================ +FILE EVTload.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains function EVTload which is used to call a + specified event-driven or hybrid code model during an event-driven + iteration. The 'CALL_TYPE' is set to 'EVENT_DRIVEN' when the + model is called from this function. + +INTERFACES + + int EVTload(CKTcircuit *ckt, int inst_index) + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +#include + +#include "ngspice.h" +#include "cktdefs.h" +//#include "util.h" +#include "devdefs.h" +#include "sperror.h" + +#include "mif.h" +#include "evt.h" +#include "evtudn.h" + +#include "mifproto.h" +#include "evtproto.h" + + + + +extern SPICEdev **DEVices; + + + +static void EVTcreate_state( + CKTcircuit *ckt, + int inst_index); + +static void EVTadd_msg( + CKTcircuit *ckt, + int port_index, + char *msg_text); + +static void EVTcreate_output_event( + CKTcircuit *ckt, + int node_index, + int output_index, + void **value_ptr); + +static void EVTprocess_output( + CKTcircuit *ckt, + Mif_Boolean_t changed, + int output_index, + Mif_Boolean_t invert, + double delay); + + + +/* +EVTload + +This function calls the code model function for the specified +instance with CALL_TYPE set to EVENT_DRIVEN. Event outputs, +messages, etc. are processed on return from the code model. +Analog outputs, partials, etc. should not be computed by the +code model when the call type is event-driven and are +ignored. +*/ + +int EVTload( + CKTcircuit *ckt, /* The circuit structure */ + int inst_index) /* The instance to call code model for */ +{ + + int i; + int j; + + int num_conn; + int num_port; + int mod_type; + + Mif_Conn_Data_t *conn; + Mif_Port_Data_t *port; + + Mif_Private_t cm_data; + + MIFinstance *inst; + + Evt_Node_Data_t *node_data; + + void *value_ptr; + + + /* ***************************** */ + /* Prepare the code model inputs */ + /* ***************************** */ + + /* Get pointer to instance data structure and other data */ + /* needed for fast access */ + inst = ckt->evt->info.inst_table[inst_index]->inst_ptr; + node_data = ckt->evt->data.node; + + /* Setup circuit data in struct to be passed to code model function */ + + if(inst->initialized) + cm_data.circuit.init = MIF_FALSE; + else + cm_data.circuit.init = MIF_TRUE; + + cm_data.circuit.anal_init = MIF_FALSE; + cm_data.circuit.anal_type = g_mif_info.circuit.anal_type; + + if(g_mif_info.circuit.anal_type == MIF_TRAN) + cm_data.circuit.time = g_mif_info.circuit.evt_step; + else + cm_data.circuit.time = 0.0; + + cm_data.circuit.call_type = MIF_EVENT_DRIVEN; + cm_data.circuit.temperature = ckt->CKTtemp - 273.15; + + + /* Setup data needed by cm_... functions */ + + g_mif_info.ckt = ckt; + g_mif_info.instance = inst; + g_mif_info.errmsg = ""; + g_mif_info.circuit.call_type = MIF_EVENT_DRIVEN; + + if(inst->initialized) + g_mif_info.circuit.init = MIF_FALSE; + else + g_mif_info.circuit.init = MIF_TRUE; + + + /* If after initialization and in transient analysis mode */ + /* create a new state for the instance */ + + if((g_mif_info.circuit.anal_type == MIF_TRAN) && inst->initialized) + EVTcreate_state(ckt, inst_index); + + + /* Loop through all connections on the instance and setup */ + /* load, total_load, and msg on all ports, and changed flag */ + /* and output pointer on all outputs */ + + num_conn = inst->num_conn; + for(i = 0; i < num_conn; i++) { + + conn = inst->conn[i]; + + /* if connection is null, continue to next */ + if(conn->is_null) + continue; + + /* Loop through each port on the connection */ + num_port = conn->size; + for(j = 0; j < num_port; j++) { + + port = conn->port[j]; + + /* Skip if port is null */ + if(port->is_null) + continue; + + /* If port type is Digital or User-Defined */ + if((port->type == MIF_DIGITAL) || (port->type == MIF_USER_DEFINED)) { + + /* Initialize the msg pointer on the port to NULL, */ + /* initialize the load value to zero, and get the total load */ + port->msg = NULL; + port->load = 0.0; + port->total_load = node_data->total_load[port->evt_data.node_index]; + + /* If connection is an output, initialize changed to true */ + /* and create a new output event object in the free list */ + /* if transient analysis mode */ + if(conn->is_output) { + port->changed = MIF_TRUE; + if(g_mif_info.circuit.anal_type == MIF_TRAN) { + EVTcreate_output_event(ckt, + port->evt_data.node_index, + port->evt_data.output_index, + &value_ptr); + port->output.pvalue = value_ptr; + } + } + } + else { + /* Get the analog input value. All we need to do is */ + /* set it to zero if mode is INITJCT. Otherwise, value */ + /* should still be around from last successful analog call */ + if(ckt->CKTmode & MODEINITJCT) + port->input.rvalue = 0.0; + } + + } /* end for number of ports */ + } /* end for number of connections */ + + + /* Prepare the structure to be passed to the code model */ + cm_data.num_conn = inst->num_conn; + cm_data.conn = inst->conn; + cm_data.num_param = inst->num_param; + cm_data.param = inst->param; + cm_data.num_inst_var = inst->num_inst_var; + cm_data.inst_var = inst->inst_var; + + + /* ******************* */ + /* Call the code model */ + /* ******************* */ + + mod_type = inst->MIFmodPtr->MIFmodType; + (*(DEVices[mod_type]->DEVpublic.cm_func)) (&cm_data); + + + /* ****************************** */ + /* Process the code model outputs */ + /* ****************************** */ + + /* Loop through all connections and ports and process the msgs */ + /* and event outputs */ + + num_conn = inst->num_conn; + for(i = 0; i < num_conn; i++) { + + conn = inst->conn[i]; + if(conn->is_null) + continue; + + /* Loop through each port on the connection */ + num_port = conn->size; + for(j = 0; j < num_port; j++) { + + port = conn->port[j]; + + /* Skip if port is null */ + if(port->is_null) + continue; + + /* Process the message if any */ + if(port->msg) + EVTadd_msg(ckt, port->evt_data.port_index, port->msg); + + /* If this is the initialization pass, process the load factor */ + if(! inst->initialized) { + node_data->total_load[port->evt_data.node_index] += + port->load; + } + + /* If connection is not an event output, continue to next port */ + if(! conn->is_output) + continue; + if((port->type != MIF_DIGITAL) && (port->type != MIF_USER_DEFINED)) + continue; + + /* If output changed, process it */ + EVTprocess_output(ckt, port->changed, + port->evt_data.output_index, + port->invert, port->delay); + + /* And prevent erroneous models from overwriting it during */ + /* analog iterations */ + if(g_mif_info.circuit.anal_type == MIF_TRAN) + port->output.pvalue = NULL; + + } /* end for number of ports */ + } /* end for number of connections */ + + + /* Record statistics */ + if(g_mif_info.circuit.anal_type == MIF_DC) + (ckt->evt->data.statistics->op_load_calls)++; + else if(g_mif_info.circuit.anal_type == MIF_TRAN) + (ckt->evt->data.statistics->tran_load_calls)++; + + /* Mark that the instance has been called once */ + inst->initialized = MIF_TRUE; + + return(OK); +} + + + +/* +EVTcreate_state + +This function creates a new state storage area for a particular instance +during an event-driven simulation. New states must be created so +that old states are saved and can be accessed by code models in the +future. The new state is initialized to the previous state value. +*/ + + +static void EVTcreate_state( + CKTcircuit *ckt, /* The circuit structure */ + int inst_index) /* The instance to create state for */ +{ + int i; + int total_size; + + Evt_State_Data_t *state_data; + + Evt_State_t *new_state; + Evt_State_t *prev_state; + + char *from; + char *to; + + + /* Get variables for fast access */ + state_data = ckt->evt->data.state; + + /* Exit immediately if no states on this instance */ + if(state_data->desc[inst_index] == NULL) + return; + + /* Get size of state block to be allocated */ + total_size = state_data->total_size[inst_index]; + + /* Allocate a new state for the instance */ + if(state_data->free[inst_index]) + { + new_state = state_data->free[inst_index]; + state_data->free[inst_index] = new_state->next; + } + else + { + + new_state = (void *) MALLOC(sizeof(Evt_State_t)); + new_state->block = (void *) MALLOC(total_size); + + } + + /* Splice the new state into the state data linked list */ + /* and update the tail pointer */ + prev_state = *(state_data->tail[inst_index]); + prev_state->next = new_state; + new_state->prev = prev_state; + state_data->tail[inst_index] = &(prev_state->next); + + /* Copy the old state to the new state and set the step */ + from = prev_state->block; + to = new_state->block; + for(i = 0; i < total_size; i++) + to[i] = from[i]; + new_state->step = g_mif_info.circuit.evt_step; + + /* Mark that the state data on the instance has been modified */ + if(! state_data->modified[inst_index]) { + state_data->modified[inst_index] = MIF_TRUE; + state_data->modified_index[(state_data->num_modified)++] = inst_index; + } +} + + +/* +EVTcreate_output_event + +This function creates a new output event. +*/ + +static void EVTcreate_output_event( + CKTcircuit *ckt, /* The circuit structure */ + int node_index, /* The node type port is on */ + int output_index, /* The output index for this port */ + void **value_ptr) /* The event created */ +{ + int udn_index; + Evt_Node_Info_t **node_table; + Evt_Output_Queue_t *output_queue; + Evt_Output_Event_t *event; + + + /* Check the output queue free list and use the structure */ + /* at the head of the list if non-null. Otherwise, create a new one. */ + output_queue = &(ckt->evt->queue.output); + if(output_queue->free[output_index]) { + *value_ptr = output_queue->free[output_index]->value; + } + else { + /* Create a new event */ + event = (void *) MALLOC(sizeof(Evt_Output_Event_t)); + event->next = NULL; + + /* Initialize the value */ + node_table = ckt->evt->info.node_table; + udn_index = node_table[node_index]->udn_index; + (*(g_evt_udn_info[udn_index]->create)) (&(event->value)); + + /* Put the event onto the free list and return the value pointer */ + output_queue->free[output_index] = event; + *value_ptr = event->value; + } +} + + + +/* +EVTadd_msg + +This function records a message output by a code model into the +message results data structure. +*/ + + +static void EVTadd_msg( + CKTcircuit *ckt, /* The circuit structure */ + int port_index, /* The port to add message to */ + char *msg_text) /* The message text */ +{ + + Evt_Msg_Data_t *msg_data; + + Evt_Msg_t **msg_ptr; + Evt_Msg_t *msg; + + + /* Get pointers for fast access */ + msg_data = ckt->evt->data.msg; + msg_ptr = msg_data->tail[port_index]; + + /* Set pointer to location at which to add, and update tail */ + if(*msg_ptr != NULL) { + msg_ptr = &((*msg_ptr)->next); + msg_data->tail[port_index] = msg_ptr; + } + + /* Add a new entry in the list of messages for this port */ + if(msg_data->free[port_index]) { + *msg_ptr = msg_data->free[port_index]; + msg_data->free[port_index] = msg_data->free[port_index]->next; + } + else { + *msg_ptr = (void *) MALLOC(sizeof(Evt_Msg_t)); + } + + /* Fill in the values */ + msg = *msg_ptr; + msg->next = NULL; + if((ckt->CKTmode & MODEDCOP) == MODEDCOP) + msg->op = MIF_TRUE; + else + msg->step = g_mif_info.circuit.evt_step; + msg->text = MIFcopy(msg_text); + + /* Update the modified indexes */ + if(g_mif_info.circuit.anal_type == MIF_TRAN) { + if(! msg_data->modified[port_index]) { + msg_data->modified[port_index] = MIF_TRUE; + msg_data->modified_index[(msg_data->num_modified)++] = port_index; + } + } + +} + + +/* +EVTprocess_output + +This function processes an event-driven output produced by a code +model. If transient analysis mode, the event is placed into the +output queue according to its (non-zero) delay. If DC analysis, +the event is processed immediately. +*/ + + +static void EVTprocess_output( + CKTcircuit *ckt, /* The circuit structure */ + Mif_Boolean_t changed, /* Has output changed? */ + int output_index, /* The output of interest */ + Mif_Boolean_t invert, /* Does output need to be inverted? */ + double delay) /* The output delay in transient analysis */ +{ + + int num_outputs; + int node_index; + int udn_index; + int output_subindex; + + Evt_Output_Info_t **output_table; + Evt_Node_Info_t **node_table; + + Evt_Node_t *rhs; + Evt_Node_t *rhsold; + + Evt_Output_Queue_t *output_queue; + Evt_Output_Event_t *output_event; + + Mif_Boolean_t equal; + + + output_queue = &(ckt->evt->queue.output); + output_table = ckt->evt->info.output_table; + node_table = ckt->evt->info.node_table; + + node_index = output_table[output_index]->node_index; + udn_index = node_table[node_index]->udn_index; + + + /* if transient analysis, just put the output event on the queue */ + /* to be processed at a later time */ + if(g_mif_info.circuit.anal_type == MIF_TRAN) { + /* If model signaled that output was not posted, */ + /* leave the event struct on the free list and return */ + if((! changed) || (delay <= 0.0)) { + if(changed && (delay <= 0.0)) + printf("\nERROR - Output delay <= 0 not allowed - output ignored!\n"); + return; + } + /* Remove the (now used) struct from the head of the free list */ + output_event = output_queue->free[output_index]; + output_queue->free[output_index] = output_event->next; + /* Invert the output value if necessary */ + if(invert) + (*(g_evt_udn_info[udn_index]->invert)) + (output_event->value); + /* Add it to the queue */ + EVTqueue_output(ckt, output_index, udn_index, output_event, + g_mif_info.circuit.evt_step, + g_mif_info.circuit.evt_step + delay); + return; + } + /* If not transient analysis, process immediately. */ + /* Determine if output has changed from rhsold value */ + /* and put entry in output queue changed list if so */ + else { + + /* If model signaled that output was not posted, */ + /* just return */ + if(! changed) + return; +/* + if(delay > 0.0) + printf("\nWARNING - Non-zero output delay not allowed in DCOP - delay ignored!\n"); +*/ + rhs = ckt->evt->data.node->rhs; + rhsold = ckt->evt->data.node->rhsold; + + /* Determine if changed */ + num_outputs = node_table[node_index]->num_outputs; + if(num_outputs > 1) { + output_subindex = output_table[output_index]->output_subindex; + if(invert) + (*(g_evt_udn_info[udn_index]->invert)) + (rhs[node_index].output_value[output_subindex]); + (*(g_evt_udn_info[udn_index]->compare)) + (rhs[node_index].output_value[output_subindex], + rhsold[node_index].output_value[output_subindex], + &equal); + if(! equal) { + (*(g_evt_udn_info[udn_index]->copy)) + (rhs[node_index].output_value[output_subindex], + rhsold[node_index].output_value[output_subindex]); + } + } + else { + if(invert) + (*(g_evt_udn_info[udn_index]->invert)) + (rhs[node_index].node_value); + (*(g_evt_udn_info[udn_index]->compare)) + (rhs[node_index].node_value, + rhsold[node_index].node_value, + &equal); + if(! equal) { + (*(g_evt_udn_info[udn_index]->copy)) + (rhs[node_index].node_value, + rhsold[node_index].node_value); + } + } + + /* If changed, put in changed list of output queue */ + if(! equal) { + if(! output_queue->changed[output_index]) { + output_queue->changed[output_index] = MIF_TRUE; + output_queue->changed_index[(output_queue->num_changed)++] = + output_index; + } + } + + return; + + } /* end else process immediately */ +} diff --git a/src/xspice/evt/evtnext_time.c b/src/xspice/evt/evtnext_time.c new file mode 100755 index 000000000..b2f3c35e9 --- /dev/null +++ b/src/xspice/evt/evtnext_time.c @@ -0,0 +1,93 @@ +/*============================================================================ +FILE EVTnext_time.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains function EVTnext_time which determines and + returns the time of the next scheduled event on the inst and output + queues. + +INTERFACES + + double EVTnext_time(CKTcircuit *ckt) + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +#include + +#include "ngspice.h" +#include "cktdefs.h" +//#include "util.h" + +#include "mif.h" +#include "evt.h" + +#include "evtproto.h" + + + +/* +EVTnext_time + +Get the next event time as the minimum of the next times +in the inst and output queues. If no next time in either, +return machine infinity. +*/ + + +double EVTnext_time( + CKTcircuit *ckt) /* The circuit structure */ +{ + + double next_time; + + Evt_Inst_Queue_t *inst_queue; + Evt_Output_Queue_t *output_queue; + + + /* Initialize next time to machine infinity */ + next_time = 1e30; + + /* Get pointers for fast access */ + inst_queue = &(ckt->evt->queue.inst); + output_queue = &(ckt->evt->queue.output); + + /* If anything pending in inst queue, set next time */ + /* to minimum of itself and the inst queue next time */ + if(inst_queue->num_pending) + if(inst_queue->next_time < next_time) + next_time = inst_queue->next_time; + + /* If anything pending in output queue, set next time */ + /* to minimum of itself and the output queue next time */ + if(output_queue->num_pending) + if(output_queue->next_time < next_time) + next_time = output_queue->next_time; + + return(next_time); +} diff --git a/src/xspice/evt/evtnode_copy.c b/src/xspice/evt/evtnode_copy.c new file mode 100755 index 000000000..6690b9224 --- /dev/null +++ b/src/xspice/evt/evtnode_copy.c @@ -0,0 +1,159 @@ +/*============================================================================ +FILE EVTnode_copy.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains function EVTnode_copy which copies the state + of a node structure. + +INTERFACES + + void EVTnode_copy(CKTcircuit *ckt, int node_index, Evt_Node_t *from, + Evt_Node_t **to) + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +#include "ngspice.h" +#include "cktdefs.h" +//#include "util.h" + +#include "mif.h" +#include "evt.h" +#include "evtudn.h" + +#include "mifproto.h" +#include "evtproto.h" +#include "cm.h" + +/* +EVTnode_copy + +This function copies the state of a node structure. + +If the destination is NULL, it is allocated before the copy. This is the +case when EVTiter copies a node during a transient analysis to +save the state of an element of rhsold into the node data structure +lists. + +If the destination is non-NULL, only the internal elements of the node +structure are copied. This is the case when EVTbackup restores that state +of nodes that existed at a certain timestep back into rhs and rhsold. +*/ + + +void EVTnode_copy( + CKTcircuit *ckt, /* The circuit structure */ + int node_index, /* The node to copy */ + Evt_Node_t *from, /* Location to copy from */ + Evt_Node_t **to) /* Location to copy to */ +{ + + int i; + + int udn_index; + int num_outputs; + Mif_Boolean_t invert; + + Evt_Node_Data_t *node_data; + Evt_Node_Info_t **node_table; + + Evt_Node_t *here; + + /* Digital_t *dummy;*/ + + /* char buff[128];*/ + + /* Get data for fast access */ + node_data = ckt->evt->data.node; + node_table = ckt->evt->info.node_table; + + udn_index = node_table[node_index]->udn_index; + num_outputs = node_table[node_index]->num_outputs; + invert = node_table[node_index]->invert; + + + /* If destination is not allocated, allocate it */ + /* otherwise we just copy into the node struct */ + here = *to; + + if(here == NULL) + { + /* Use allocated structure on free list if available */ + /* Otherwise, allocate a new one */ + here = node_data->free[node_index]; + if(here) + { + *to = here; + node_data->free[node_index] = here->next; + here->next = NULL; + } + else + { + here = (void *) MALLOC(sizeof(Evt_Node_t)); + *to = here; + /* Allocate/initialize the data in the new node struct */ + if(num_outputs > 1) + { + here->output_value = (void *) MALLOC(num_outputs * sizeof(void *)); + + for(i = 0; i < num_outputs; i++) + { + (*(g_evt_udn_info[udn_index]->create)) + ( &(here->output_value[i]) ); + } + } + + here->node_value = NULL; + + (*(g_evt_udn_info[udn_index]->create)) ( &(here->node_value) ); + + if(invert) + (*(g_evt_udn_info[udn_index]->create)) ( &(here->inverted_value) ); + + + } + } + + /* Copy the node data */ + here->op = from->op; + here->step = from->step; + if(num_outputs > 1) + { + for(i = 0; i < num_outputs; i++) + { + (*(g_evt_udn_info[udn_index]->copy)) (from->output_value[i], + here->output_value[i]); + } + } + (*(g_evt_udn_info[udn_index]->copy)) (from->node_value, here->node_value); + if(invert) + { + (*(g_evt_udn_info[udn_index]->copy)) (from->inverted_value, + here->inverted_value); + } +} diff --git a/src/xspice/evt/evtop.c b/src/xspice/evt/evtop.c new file mode 100755 index 000000000..fa431ecd8 --- /dev/null +++ b/src/xspice/evt/evtop.c @@ -0,0 +1,321 @@ +/*============================================================================ +FILE EVTop.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains function EVTop which is used to perform an + operating point analysis in place of CKTop when there are + event-driven instances in the circuit. It alternates between doing + event-driven iterations with EVTiter and doing analog iterations with + NIiter/CKTop until no more event-driven outputs change. + +INTERFACES + + EVTop() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +#include +#include "ngspice.h" +#include "cktdefs.h" +//#include "util.h" +#include "sperror.h" + +#include "mif.h" +#include "evt.h" +#include "evtproto.h" +#include "evtudn.h" + + +static void EVTnode_compare( + CKTcircuit *ckt, + int node_index, + Evt_Node_t *node1, + Evt_Node_t *node2, + Mif_Boolean_t *equal); + + + +/* +EVTop + +This function is used to perform an operating point analysis +in place of CKTop when there are event-driven instances in the +circuit. It alternates between doing event-driven iterations +with EVTiter and doing analog iterations with NIiter/CKTop +until no more event-driven outputs change. +*/ + + +int EVTop( + CKTcircuit *ckt, /* The circuit structure */ + long firstmode, /* The SPICE 3C1 CKTop() firstmode parameter */ + long continuemode, /* The SPICE 3C1 CKTop() continuemode paramter */ + int max_iter, /* The SPICE 3C1 CKTop() max iteration parameter */ + Mif_Boolean_t first_call) /* Is this the first time through? */ +{ + + int i; + int num_insts; + int converged; + int output_index; + int port_index; + + char *err_msg; + + Mif_Boolean_t firstime; + + Evt_Inst_Queue_t *inst_queue; + Evt_Output_Queue_t *output_queue; + + Evt_Output_Info_t **output_table; + Evt_Port_Info_t **port_table; + + + /* get data to local storage for fast access */ + num_insts = ckt->evt->counts.num_insts; + inst_queue = &(ckt->evt->queue.inst); + + /* Initialize to_call entries in event inst queue */ + /* to force calling all event/hybrid instance the first */ + /* time through */ + + if(first_call) { + for(i = 0; i < num_insts; i++) { + inst_queue->to_call[i] = MIF_TRUE; + inst_queue->to_call_index[i] = i; + } + inst_queue->num_to_call = num_insts; + } + + + /* Alternate between event-driven and analog solutions until */ + /* there are no changed event-driven outputs */ + + firstime = MIF_TRUE; + for(;;) { + + /* Call EVTiter to establish initial outputs from */ + /* event/hybrid instances with states (e.g. flip-flops) */ + + ckt->CKTmode = firstmode; + converged = EVTiter(ckt); + if(converged != 0) + return(converged); + + /* Now do analog solution for current state of hybrid outputs */ + + /* If first analog solution, call CKTop */ + if(firstime) { + firstime = MIF_FALSE; + converged = CKTop(ckt, + firstmode, + continuemode, + max_iter); + if(converged != 0) + return(converged); + } + /* Otherwise attempt to converge with mode = continuemode */ + else { + ckt->CKTmode = continuemode; + converged = NIiter(ckt,max_iter); + if(converged != 0) { + converged = CKTop(ckt, + firstmode, + continuemode, + max_iter); + if(converged != 0) + return(converged); + } + } + + /* Call all hybrids to allow new event outputs to be posted */ + EVTcall_hybrids(ckt); + + /* Increment count of successful alternations */ + (ckt->evt->data.statistics->op_alternations)++; + + /* If .option card specified not to alternate solutions, exit */ + /* immediately with this first pass solution */ + if(! ckt->evt->options.op_alternate) + return(0); + + /* If no hybrid instances produced different event outputs, */ + /* alternation is completed, so exit */ + if(ckt->evt->queue.output.num_changed == 0) + return(0); + + /* If too many alternations, exit with error */ + if(ckt->evt->data.statistics->op_alternations >= + ckt->evt->limits.max_op_alternations) { + + (*(SPfrontEnd->IFerror)) (ERR_WARNING, + "Too many analog/event-driven solution alternations", + (IFuid *) NULL); + + err_msg = MALLOC(10000); + output_queue = &(ckt->evt->queue.output); + output_table = ckt->evt->info.output_table; + port_table = ckt->evt->info.port_table; + + for(i = 0; i < output_queue->num_changed; i++) { + output_index = output_queue->changed_index[i]; + port_index = output_table[output_index]->port_index; + sprintf(err_msg, "\n Instance: %s\n Connection: %s\n Port: %d", + port_table[port_index]->inst_name, + port_table[port_index]->conn_name, + port_table[port_index]->port_num); + ENHreport_conv_prob(ENH_EVENT_NODE, + port_table[port_index]->node_name, + err_msg); + } + FREE(err_msg); + + return(E_ITERLIM); + } + + } /* end forever */ +} + + + +/* +EVTop_save + +Save result from operating point iteration into the node data area. +*/ + +void EVTop_save( + CKTcircuit *ckt, /* The circuit structure */ + Mif_Boolean_t op, /* True if from a DCOP analysis, false if TRANOP, etc. */ + double step) +{ + + int i; + int num_nodes; + + Mif_Boolean_t equal; + + Evt_Node_Data_t *node_data; + + Evt_Node_t *rhsold; + Evt_Node_t **head; + Evt_Node_t **here; + + /* char buff[128];*/ + + + /* Get pointers for fast access */ + node_data = ckt->evt->data.node; + rhsold = node_data->rhsold; + head = node_data->head; + + /* For number of event nodes, copy rhsold to node data */ + /* and set the op member if appropriate */ + num_nodes = ckt->evt->counts.num_nodes; + + for(i = 0; i < num_nodes; i++) + { + /* if head is null, just copy there */ + if(head[i] == NULL) + { + EVTnode_copy(ckt, i, &(rhsold[i]), &(head[i])); + + head[i]->op = op; + head[i]->step = step; + + } + /* Otherwise, add to the end of the list */ + else + { + /* Locate end of list */ + here = &(head[i]); + for(;;) + { + if((*here)->next) + here = &((*here)->next); + else + break; + } + /* Compare entry at end of list to rhsold */ + + EVTnode_compare(ckt, i, &(rhsold[i]), *here, &equal); + + /* If new value in rhsold is different, add it to the list */ + if(!equal) + { + here = &((*here)->next); + EVTnode_copy(ckt, i, &(rhsold[i]), here); + (*here)->op = op; + (*here)->step = step; + } + } /* end else add to end of list */ + } /* end for number of nodes */ + +} + + + +/* ************************************************************ */ + + +/* +EVTnode_compare + +This function compares the resolved values of the old and +new states on a node. The actual comparison is done by +calling the appropriate user-defined node compare function. +*/ + + +static void EVTnode_compare( + CKTcircuit *ckt, /* The circuit structure */ + int node_index, /* The index for the node in question */ + Evt_Node_t *node1, /* The first value */ + Evt_Node_t *node2, /* The second value */ + Mif_Boolean_t *equal) /* The computed result */ +{ + + Evt_Node_Data_t *node_data; + Evt_Node_Info_t **node_table; + + int udn_index; + + + /* Get data for fast access */ + node_data = ckt->evt->data.node; + node_table = ckt->evt->info.node_table; + udn_index = node_table[node_index]->udn_index; + + + /* Do compare based on changes in resolved node value only */ + (*(g_evt_udn_info[udn_index]->compare)) ( + node1->node_value, + node2->node_value, + equal); +} diff --git a/src/xspice/evt/evtplot.c b/src/xspice/evt/evtplot.c new file mode 100755 index 000000000..60d47fefc --- /dev/null +++ b/src/xspice/evt/evtplot.c @@ -0,0 +1,218 @@ +/*============================================================================ +FILE EVTplot.c + +MEMBER OF process XSPICE + +Copyright 1992 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 5/7/92 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains function EVTplot which is used to provide basic + plotting of event driven nodes through SPICE3's 'plot' command. + +INTERFACES + + void EVTplot() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +#include +#include + +#include "ngspice.h" +//nclude "misc.h" +#include "evt.h" +#include "evtudn.h" +#include "evtproto.h" +#include "mif.h" +#include "mifproto.h" + +/*saj for output */ +#include "sim.h" +#include "dvec.h" +//#include "ftedata.h" +//#include "fteconstant.h" +//#include "util.h" +#include "cpstd.h" + + +/* + +EVTfindvec() + +This function is called from FTE/vectors.c:findvec() when a node specified +for plotting cannot be located in the analog plot data. It scans the +event driven data structures looking for the node, and if found, returns +a new 'dvec' structure holding the data to be plotted. The dvec struct +is created with it's own v_scale member holding the event time vector +for this node since the time vector is not aligned with the analog data +points or with other event vectors. + +The node name supplied as argument can either be a simple node name, or a +name of the form (), where is the member of +the event-driven structure to be plotted. These member names are defined +by the individual "user-defined node" plot_val routines for the node +type in question. If the simple node name form is used, the special +keyword "all" is supplied to the plot_val routine for the member name. + +*/ + + +struct dvec *EVTfindvec( + char *node) /* The node name (and optional member name) */ +{ + char *name; + char *member = "all"; + char *ptr; + + int i; + int len; + int num_nodes; + int udn_index; + int num_events; + + Mif_Boolean_t found; + Evt_Node_Info_t **node_table; + Evt_Node_t *head; + Evt_Node_t *event; + + double *anal_point_vec; + double *value_vec; + double value; + + struct dvec *d; + struct dvec *scale; + + /* Exit immediately if event-driven stuff not allocated yet, */ + /* or if number of event nodes is zero. */ + if(! g_mif_info.ckt) + return(NULL); + if(! g_mif_info.ckt->evt) + return(NULL); + if(g_mif_info.ckt->evt->counts.num_nodes == 0) + return(NULL); + + /* Make a copy of the node name. */ + /* Do not free this string. It is assigned into the dvec structure below. */ + name = MIFcopy(node); + + /* Convert to all lower case */ + len = strlen(name); + for(i = 0; i < len; i++) + if(isupper(name[i])) + name[i] = tolower(name[i]); + + /* Divide into the node name and member name */ + for(ptr = name; *ptr != '\0'; ptr++) + if(*ptr == '(') + break; + + if(*ptr == '(') { + *ptr = '\0'; + ptr++; + member = ptr; + for( ; *ptr != '\0'; ptr++) + if(*ptr == ')') + break; + *ptr = '\0'; + } + + /* Look for node name in the event-driven node list */ + num_nodes = g_mif_info.ckt->evt->counts.num_nodes; + node_table = g_mif_info.ckt->evt->info.node_table; + + for(i = 0, found = MIF_FALSE; i < num_nodes; i++) { + if(cieq(name, node_table[i]->name)) { + found = MIF_TRUE; + break; + } + } + + if(! found) + return(NULL); + + /* Get the UDN type index */ + udn_index = node_table[i]->udn_index; + + /* Count the number of events */ + head = g_mif_info.ckt->evt->data.node->head[i]; + + for(event = head, num_events = 0; event; event = event->next) + num_events++; + + /* Allocate arrays to hold the analysis point and node value vectors */ + anal_point_vec = (double *) MALLOC(2 * (num_events + 2) * sizeof(double)); + value_vec = (double *) MALLOC(2 * (num_events + 2) * sizeof(double)); + + /* Iterate through the events and fill the arrays. */ + /* Note that we create vertical segments every time an event occurs. */ + /* Need to modify this in the future to complete the vector out to the */ + /* last analysis point... */ + for(i = 0, event = head; event; event = event->next) { + + /* If not first point, put the second value of the horizontal line in the vectors */ + if(i > 0) { + anal_point_vec[i] = event->step; + value_vec[i] = value; + i++; + } + + /* Get the next value by calling the appropriate UDN plot_val function */ + value = 0.0; + (*(g_evt_udn_info[udn_index]->plot_val)) (event->node_value, + member, + &value); + + /* Put the first value of the horizontal line in the vector */ + anal_point_vec[i] = event->step; + value_vec[i] = value; + i++; + + } + + /* Allocate dvec structures and assign the vectors into them. */ + /* See FTE/OUTinterface.c:plotInit() for initialization example. */ + + scale = (void *) MALLOC(sizeof(struct dvec)); + + scale->v_name = MIFcopy("step"); + scale->v_type = SV_TIME; + scale->v_flags = VF_REAL & ~VF_PERMANENT; + scale->v_length = i; + scale->v_realdata = anal_point_vec; + scale->v_scale = NULL; + + d = (void *) MALLOC(sizeof(struct dvec)); + + d->v_name = name; + d->v_type = SV_VOLTAGE; + d->v_flags = VF_REAL & ~VF_PERMANENT; + d->v_length = i; + d->v_realdata = value_vec; + d->v_scale = scale; + + + /* Return the dvec */ + return(d); +} diff --git a/src/xspice/evt/evtprint.c b/src/xspice/evt/evtprint.c new file mode 100755 index 000000000..2c82c2ddb --- /dev/null +++ b/src/xspice/evt/evtprint.c @@ -0,0 +1,369 @@ +/*============================================================================ +FILE EVTprint.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains function EVTprint which is used to provide a simple + tabular output of event-driven node data. This printout is invoked + through a new nutmeg command called 'eprint' which takes event-driven + node names as argument. + +INTERFACES + + void EVTprint(wordlist *wl) + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +#include +#include + +#include "ngspice.h" +//#include "misc.h" + +#include "cpstd.h" + +#include "mif.h" +#include "evt.h" +#include "evtudn.h" + +#include "evtproto.h" + + + +static int get_index(char *node_name); + +static void print_data( + Mif_Boolean_t dcop, + double step, + char **node_value, + int nargs); + +/* +EVTprint + +This function implements the 'eprint' command used to print +event-driven node values and messages from the latest simulation. + +This is a simple prototype implementation of the +eprint command for testing purposes. It is currently lacking +in the following areas: + +1) It accepts only up to 16 nodes. + +2) It does not support the selected printing of different + members of a user-defined data struct. + +3) It is dumb in its output formatting - just tries to print + everything on a line with 4 space separators. + +4) It works only for the latest simulation - i.e. it does not + use the evt jobs structure to find old results. + +5) It does not allow a range of timesteps to be selected. + +*/ + + + +#define EPRINT_MAXARGS 16 + + +void EVTprint( + wordlist *wl) /* The command line entered by user */ +{ + + int i; + int nargs; + int num_ports; + + wordlist *w; + + char *node_name[EPRINT_MAXARGS]; + int node_index[EPRINT_MAXARGS]; + int udn_index[EPRINT_MAXARGS]; + Evt_Node_t *node_data[EPRINT_MAXARGS]; + char *node_value[EPRINT_MAXARGS]; + + CKTcircuit *ckt; + + Evt_Node_Info_t **node_table; + Evt_Port_Info_t **port_table; + + Mif_Boolean_t more; + Mif_Boolean_t dcop; + + double step; + double next_step; + double this_step; + + char *value; + + Evt_Msg_t *msg_data; + Evt_Statistic_t *statistics; + + + /* Count the number of arguments to the command */ + nargs = 0; + w = wl; + while(w) { + nargs++; + w = w->wl_next; + } + + if(nargs < 1) { + printf("Usage: eprint ...\n"); + return; + } + if(nargs > EPRINT_MAXARGS) { + printf("ERROR - eprint currently limited to 16 arguments\n"); + return; + } + + /* Get needed pointers */ + ckt = g_mif_info.ckt; + node_table = ckt->evt->info.node_table; + + /* Get data for each argument */ + w = wl; + for(i = 0; i < nargs; i++) { + node_name[i] = w->wl_word; + node_index[i] = get_index(node_name[i]); + if(node_index[i] < 0) { + printf("ERROR - Node %s is not an event node.\n", node_name[i]); + return; + } + udn_index[i] = node_table[node_index[i]]->udn_index; + node_data[i] = ckt->evt->data.node->head[node_index[i]]; + node_value[i] = ""; + w = w->wl_next; + } + + + /* Print results data */ + printf("\n**** Results Data ****\n\n"); + + /* Print the column identifiers */ + printf("Time or Step\n"); + for(i = 0; i < nargs; i++) + printf("%s\n",node_name[i]); + printf("\n\n"); + + /* Scan the node data and determine if the first vector */ + /* is for a DCOP analysis or the first step in a swept DC */ + /* or transient analysis. Also, determine if there is */ + /* more data following it and if so, what the next step */ + /* is. */ + more = MIF_FALSE; + dcop = MIF_FALSE; + next_step = 1e30; + for(i = 0; i < nargs; i++) { + if(node_data[i]->op) + dcop = MIF_TRUE; + else + step = node_data[i]->step; + (*(g_evt_udn_info[udn_index[i]]->print_val)) + (node_data[i]->node_value, "all", &value); + node_value[i] = value; + node_data[i] = node_data[i]->next; + if(node_data[i]) { + more = MIF_TRUE; + if(node_data[i]->step < next_step) + next_step = node_data[i]->step; + } + } + + /* Print the data */ + print_data(dcop, step, node_value, nargs); + + /* While there is more data, get the next values and print */ + while(more) { + + more = MIF_FALSE; + this_step = next_step; + next_step = 1e30; + + for(i = 0; i < nargs; i++) { + + if(node_data[i]) { + if(node_data[i]->step == this_step) { + (*(g_evt_udn_info[udn_index[i]]->print_val)) + (node_data[i]->node_value, "all", &value); + node_value[i] = value; + node_data[i] = node_data[i]->next; + } + if(node_data[i]) { + more = MIF_TRUE; + if(node_data[i]->step < next_step) + next_step = node_data[i]->step; + } + + } /* end if node_data not NULL */ + + } /* end for number of args */ + + print_data(MIF_FALSE, this_step, node_value, nargs); + + } /* end while there is more data */ + printf("\n\n"); + + + /* Print messages for all ports */ + printf("\n**** Messages ****\n\n"); + + num_ports = ckt->evt->counts.num_ports; + port_table = ckt->evt->info.port_table; + + for(i = 0; i < num_ports; i++) { + + /* Get pointer to messages for this port */ + msg_data = ckt->evt->data.msg->head[i]; + + /* If no messages on this port, skip */ + if(! msg_data) + continue; + + /* Print the port description */ + printf("Node: %s Inst: %s Conn: %s Port: %d\n\n", + port_table[i]->node_name, + port_table[i]->inst_name, + port_table[i]->conn_name, + port_table[i]->port_num); + + /* Print the messages on this port */ + while(msg_data) { + if(msg_data->op) + printf("DCOP "); + else + printf("%-16.9e", msg_data->step); + printf("%s\n", msg_data->text); + msg_data = msg_data->next; + } + printf("\n\n"); + + } /* end for number of ports */ + + + /* Print statistics */ + printf("\n**** Statistics ****\n\n"); + + statistics = ckt->evt->data.statistics; + printf("Operating point analog/event alternations: %d\n", + statistics->op_alternations); + printf("Operating point load calls: %d\n", + statistics->op_load_calls); + printf("Operating point event passes: %d\n", + statistics->op_event_passes); + printf("Transient analysis load calls: %d\n", + statistics->tran_load_calls); + printf("Transient analysis timestep backups: %d\n", + statistics->tran_time_backups); + + printf("\n\n"); +} + + + + +/* +get_index + +This function determines the index of a specified event-driven node. +*/ + + +static int get_index( + char *node_name /* The name of the node to search for */ +) +{ + + /* Get the event-driven node index for the specified name */ + + int index; + + Mif_Boolean_t found; + Evt_Node_Info_t *node; + CKTcircuit *ckt; + + + /* Scan list of nodes in event structure to see if there */ + + found = MIF_FALSE; + index = 0; + + ckt = g_mif_info.ckt; + node = ckt->evt->info.node_list; + + while(node) { + if(strcmp(node_name, node->name) == 0) { + found = MIF_TRUE; + break; + } + else { + index++; + node = node->next; + } + } + + /* Return the index or -1 if not found */ + if(! found) + return(-1); + else + return(index); +} + + + + +/* +print_data + +This function prints the values of one or more nodes to +standard output. +*/ + + +static void print_data( + Mif_Boolean_t dcop, /* Is this the operating point data */ + double step, /* The analysis step if dcop */ + char **node_value, /* The array of values to be printed */ + int nargs) /* The size of the value array */ +{ + + int i; + char step_str[100]; + + if(dcop) + strcpy(step_str, "DCOP "); + else + sprintf(step_str, "%-16.9e", step); + + printf("%s", step_str); + for(i = 0; i < nargs; i++) + printf(" %s", node_value[i]); + printf("\n"); +} diff --git a/src/xspice/evt/evtqueue.c b/src/xspice/evt/evtqueue.c new file mode 100755 index 000000000..1de0b9937 --- /dev/null +++ b/src/xspice/evt/evtqueue.c @@ -0,0 +1,252 @@ +/*============================================================================ +FILE EVTqueue.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains functions that place new events into the output and + instance queues. + +INTERFACES + + void EVTqueue_output( + CKTcircuit *ckt, + int output_index, + int udn_index, + Evt_Output_Event_t *new_event, + double posted_time, + double event_time) + + void EVTqueue_inst( + CKTcircuit *ckt, + int inst_index, + double posted_time, + double event_time) + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + + +#include + +#include "ngspice.h" +#include "cktdefs.h" +//#include "util.h" + +#include "mif.h" +#include "evt.h" +#include "evtudn.h" + +#include "evtproto.h" + + + +/* +EVTqueue_output + +This function places the specified output event onto the output +queue. It is called by EVTload during a transient analysis. + +The linked list in the queue for the specified output is +searched beginning at the current head of the pending events +to find the location at which to insert the new event. The +events are ordered in the list by event_time. If the event +is placed before the end of the list, subsequent events are +removed from the list by marking them as 'removed' and +recording the time of removal. This allows efficient backup +of the state of the queue if a subsequent analog timestep +fails. +*/ + + +void EVTqueue_output( + CKTcircuit *ckt, /* The circuit structure */ + int output_index, /* The output in question */ + int udn_index, /* The associated user-defined node type */ + Evt_Output_Event_t *new_event, /* The event to queue */ + double posted_time, /* The current time */ + double event_time) /* The time the event should happen */ +{ + + Evt_Output_Queue_t *output_queue; + Evt_Output_Event_t **here; + Evt_Output_Event_t *next; + + Mif_Boolean_t splice; + + + /* Get pointers for fast access */ + output_queue = &(ckt->evt->queue.output); + + /* Put the times into the event struct */ + new_event->event_time = event_time; + new_event->posted_time = posted_time; + new_event->removed = MIF_FALSE; + + /* Update next_time in output queue */ + if((output_queue->num_pending <= 0) || + (event_time < output_queue->next_time)) + output_queue->next_time = event_time; + + /* Find location at which to insert event */ + splice = MIF_FALSE; + here = output_queue->current[output_index]; + while(*here) { + if(event_time <= (*here)->event_time) { + splice = MIF_TRUE; + break; + } + here = &((*here)->next); + } + + /* If needs to be spliced into middle of existing list */ + if(splice) { + /* splice it in */ + next = *here; + *here = new_event; + new_event->next = next; + /* mark later events as removed */ + while(next) { + if(! next->removed) { + next->removed = MIF_TRUE; + next->removed_time = posted_time; + } + next = next->next; + } + } + /* else, just put it at the end */ + else { + *here = new_event; + new_event->next = NULL; + } + + /* Add to the list of outputs modified since last accepted timestep */ + if(! output_queue->modified[output_index]) { + output_queue->modified[output_index] = MIF_TRUE; + output_queue->modified_index[(output_queue->num_modified)++] = + output_index; + } + + /* Add to the list of outputs with events pending */ + if(! output_queue->pending[output_index]) { + output_queue->pending[output_index] = MIF_TRUE; + output_queue->pending_index[(output_queue->num_pending)++] = + output_index; + } +} + + + +/* +EVTqueue_inst + +This function places the specified inst event onto the inst +queue. + +The linked list in the queue for the specified inst is +searched beginning at the current head of the pending events +to find the location at which to insert the new event. The +events are ordered in the list by event_time. +*/ + + + + +void EVTqueue_inst( + CKTcircuit *ckt, /* The circuit structure */ + int inst_index, /* The instance in question */ + double posted_time, /* The current time */ + double event_time) /* The time the event should happen */ +{ + + Evt_Inst_Queue_t *inst_queue; + Evt_Inst_Event_t **here; + Evt_Inst_Event_t *new_event; + Evt_Inst_Event_t *next; + + Mif_Boolean_t splice; + + + /* Get pointers for fast access */ + inst_queue = &(ckt->evt->queue.inst); + + /* Update next_time in inst queue */ + if((inst_queue->num_pending <= 0) || + (event_time < inst_queue->next_time)) + inst_queue->next_time = event_time; + + /* Create a new event or get one from the free list and copy in data */ + if(inst_queue->free[inst_index]) { + new_event = inst_queue->free[inst_index]; + inst_queue->free[inst_index] = new_event->next; + } + else { + new_event = (void *) MALLOC(sizeof(Evt_Inst_Event_t)); + } + new_event->event_time = event_time; + new_event->posted_time = posted_time; + + /* Find location at which to insert event */ + splice = MIF_FALSE; + here = inst_queue->current[inst_index]; + while(*here) { + /* If there's an event with the same time, don't duplicate it */ + if(event_time == (*here)->event_time) + return; + else if(event_time < (*here)->event_time) { + splice = MIF_TRUE; + break; + } + here = &((*here)->next); + } + + /* If needs to be spliced into middle of existing list */ + if(splice) { + /* splice it in */ + next = *here; + *here = new_event; + new_event->next = next; + } + /* else, just put it at the end */ + else { + *here = new_event; + new_event->next = NULL; + } + + /* Add to the list of insts modified since last accepted timestep */ + if(! inst_queue->modified[inst_index]) { + inst_queue->modified[inst_index] = MIF_TRUE; + inst_queue->modified_index[(inst_queue->num_modified)++] = + inst_index; + } + + /* Add to the list of insts with events pending */ + if(! inst_queue->pending[inst_index]) { + inst_queue->pending[inst_index] = MIF_TRUE; + inst_queue->pending_index[(inst_queue->num_pending)++] = + inst_index; + } +} diff --git a/src/xspice/evt/evtsetup.c b/src/xspice/evt/evtsetup.c new file mode 100755 index 000000000..59aef7343 --- /dev/null +++ b/src/xspice/evt/evtsetup.c @@ -0,0 +1,578 @@ +/*============================================================================ +FILE EVTsetup.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains function EVTsetup which clears/allocates the + event-driven queues and data structures immediately prior to a new + analysis. In addition, it places entries in the job list so that + results data from multiple analysis can be retrieved similar to + SPICE3C1 saving multiple 'plots'. + +INTERFACES + + int EVTsetup(CKTcircuit *ckt) + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +#include +#include + +#include "ngspice.h" +//#include "misc.h" + +#include "cktdefs.h" +#include "sperror.h" +//#include "util.h" + +#include "mif.h" +#include "evt.h" +#include "evtudn.h" +#include "mifproto.h" +#include "evtproto.h" + + + + +static int EVTsetup_queues(CKTcircuit *ckt); +static int EVTsetup_data(CKTcircuit *ckt); +static int EVTsetup_jobs(CKTcircuit *ckt); +static int EVTsetup_load_ptrs(CKTcircuit *ckt); + + + + +/* Allocation macros with built-in check for out-of-memory */ +/* Adapted from SPICE 3C1 code in CKTsetup.c */ + +#define CKALLOC(var,size,type) \ + if(size) { \ + if(!(var = (void *) MALLOC((size) * sizeof(type)))) \ + return(E_NOMEM); \ + } + +#define CKREALLOC(var,size,type) \ + if((size) == 1) { \ + if(!(var = (void *) MALLOC((size) * sizeof(type)))) \ + return(E_NOMEM); \ + } else if((size) > 1) { \ + if(!(var = (void *) REALLOC((void *) (var), (size) * sizeof(type)))) \ + return(E_NOMEM); \ + } + + +/* +EVTsetup + +This function clears/allocates the event-driven queues and data structures +immediately prior to a new analysis. In addition, it places entries +in the job list so that results data from multiple analysis can be +retrieved similar to SPICE3C1 saving multiple 'plots'. +*/ + + +int EVTsetup( + CKTcircuit *ckt) /* The circuit structure */ +{ + + int err; + + + /* Exit immediately if no event-driven instances in circuit */ + if(ckt->evt->counts.num_insts == 0) + return(OK); + + /* Clear the inst, node, and output queues, and initialize the to_call */ + /* elements in the instance queue to call all event-driven instances */ + err = EVTsetup_queues(ckt); + if(err) + return(err); + + /* Allocate and initialize the node, state, message, and statistics data */ + err = EVTsetup_data(ckt); + if(err) + return(err); + + /* Set the job pointers to the allocated results, states, messages, */ + /* and statistics so that data will be accessable after run */ + err = EVTsetup_jobs(ckt); + if(err) + return(err); + + /* Setup the pointers in the MIFinstance structure for inputs, outputs, */ + /* and total loads */ + err = EVTsetup_load_ptrs(ckt); + if(err) + return(err); + + /* Initialize additional event data */ + g_mif_info.circuit.evt_step = 0.0; + + /* Return OK */ + return(OK); +} + + + + +/* +EVTsetup_queues + +This function clears the event-driven queues in preparation for +a new simulation. +*/ + + +static int EVTsetup_queues( + CKTcircuit *ckt) /* The circuit structure */ +{ + + int i; + int num_insts; + int num_nodes; + int num_outputs; + + Evt_Inst_Queue_t *inst_queue; + Evt_Node_Queue_t *node_queue; + Evt_Output_Queue_t *output_queue; + + Evt_Inst_Event_t *inst_event; + Evt_Output_Event_t *output_event; + + void *ptr; + + /* ************************ */ + /* Clear the instance queue */ + /* ************************ */ + + num_insts = ckt->evt->counts.num_insts; + inst_queue = &(ckt->evt->queue.inst); + + for(i = 0; i < num_insts; i++) { + inst_event = inst_queue->head[i]; + while(inst_event) { + ptr = inst_event; + inst_event = inst_event->next; + FREE(ptr); + } + inst_event = inst_queue->free[i]; + while(inst_event) { + ptr = inst_event; + inst_event = inst_event->next; + FREE(ptr); + } + inst_queue->head[i] = NULL; + inst_queue->current[i] = &(inst_queue->head[i]); + inst_queue->last_step[i] = &(inst_queue->head[i]); + inst_queue->free[i] = NULL; + } + + inst_queue->next_time = 0.0; + inst_queue->last_time = 0.0; + + inst_queue->num_modified = 0; + inst_queue->num_pending = 0; + inst_queue->num_to_call = 0; + + for(i = 0; i < num_insts; i++) { + inst_queue->modified[i] = MIF_FALSE; + inst_queue->pending[i] = MIF_FALSE; + inst_queue->to_call[i] = MIF_FALSE; + } + + + /* ******************** */ + /* Clear the node queue */ + /* ******************** */ + + num_nodes = ckt->evt->counts.num_nodes; + node_queue = &(ckt->evt->queue.node); + + node_queue->num_changed = 0; + node_queue->num_to_eval = 0; + + for(i = 0; i < num_nodes; i++) { + node_queue->changed[i] = MIF_FALSE; + node_queue->to_eval[i] = MIF_FALSE; + } + + /* ********************** */ + /* Clear the output queue */ + /* ********************** */ + + num_outputs = ckt->evt->counts.num_outputs; + output_queue = &(ckt->evt->queue.output); + + for(i = 0; i < num_outputs; i++) { + output_event = output_queue->head[i]; + while(output_event) { + ptr = output_event; + output_event = output_event->next; + FREE(ptr); + } + output_event = output_queue->free[i]; + while(output_event) { + ptr = output_event; + output_event = output_event->next; + FREE(ptr); + } + output_queue->head[i] = NULL; + output_queue->current[i] = &(output_queue->head[i]); + output_queue->last_step[i] = &(output_queue->head[i]); + output_queue->free[i] = NULL; + } + + output_queue->next_time = 0.0; + output_queue->last_time = 0.0; + + output_queue->num_modified = 0; + output_queue->num_pending = 0; + output_queue->num_changed = 0; + + for(i = 0; i < num_outputs; i++) { + output_queue->modified[i] = MIF_FALSE; + output_queue->pending[i] = MIF_FALSE; + output_queue->changed[i] = MIF_FALSE; + } + + return(OK); +} + + + +/* +EVTsetup_data + +This function sets up the event-driven node, state, and +message data runtime structures in preparation for +a new simulation. +*/ + + +static int EVTsetup_data( + CKTcircuit *ckt) /* The circuit structure */ +{ + + Evt_Data_t *data; + + int i; + int j; + + int num_insts; + int num_ports; + int num_nodes; + + int udn_index; + int num_outputs; + + Mif_Boolean_t invert; + + Evt_Node_Data_t *node_data; + Evt_State_Data_t *state_data; + Evt_Msg_Data_t *msg_data; + /* Evt_Statistic_t *statistics_data;*/ + + Evt_Node_t *rhs; + Evt_Node_t *rhsold; + + Evt_Node_Info_t *node_info; + + + /* Allocate main substructures of data */ + /* Note that we don't free any old structures */ + /* since they are pointed to by jobs and need */ + /* to be maintained so that results from multiple */ + /* jobs are kept around like SPICE does */ + + data = &(ckt->evt->data); + CKALLOC(data->node, 1, Evt_Node_Data_t) + CKALLOC(data->state, 1, Evt_State_Data_t) + CKALLOC(data->msg, 1, Evt_Msg_Data_t) + CKALLOC(data->statistics, 1, Evt_Statistic_t) + + /* Allocate node data */ + + num_nodes = ckt->evt->counts.num_nodes; + node_data = data->node; + + CKALLOC(node_data->head, num_nodes, void *) + CKALLOC(node_data->tail, num_nodes, void *) + CKALLOC(node_data->last_step, num_nodes, void *) + CKALLOC(node_data->free, num_nodes, void *) + CKALLOC(node_data->modified_index, num_nodes, int) + CKALLOC(node_data->modified, num_nodes, Mif_Boolean_t) + CKALLOC(node_data->rhs, num_nodes, Evt_Node_t) + CKALLOC(node_data->rhsold, num_nodes, Evt_Node_t) + CKALLOC(node_data->total_load, num_nodes, double) + + /* Initialize the node data */ + + for(i = 0; i < num_nodes; i++) { + node_data->tail[i] = &(node_data->head[i]); + node_data->last_step[i] = &(node_data->head[i]); + } + + for(i = 0; i < num_nodes; i++) { + + /* Get pointers to rhs & rhsold, the user-defined node type index, */ + /* the number of outputs on the node and the invert flag */ + rhs = &(node_data->rhs[i]); + rhsold = &(node_data->rhsold[i]); + node_info = ckt->evt->info.node_table[i]; + udn_index = node_info->udn_index; + num_outputs = node_info->num_outputs; + invert = node_info->invert; + + /* Initialize the elements within rhs and rhsold */ + rhs->step = 0.0; + rhsold->step = 0.0; + if(num_outputs > 1) { + CKALLOC(rhs->output_value, num_outputs, void *) + CKALLOC(rhsold->output_value, num_outputs, void *) + for(j = 0; j < num_outputs; j++) { + (*(g_evt_udn_info[udn_index]->create)) (&(rhs->output_value[j])); + (*(g_evt_udn_info[udn_index]->initialize)) (rhs->output_value[j]); + (*(g_evt_udn_info[udn_index]->create)) (&(rhsold->output_value[j])); + (*(g_evt_udn_info[udn_index]->initialize)) (rhsold->output_value[j]); + } + } + (*(g_evt_udn_info[udn_index]->create)) (&(rhs->node_value)); + (*(g_evt_udn_info[udn_index]->initialize)) (rhs->node_value); + (*(g_evt_udn_info[udn_index]->create)) (&(rhsold->node_value)); + (*(g_evt_udn_info[udn_index]->initialize)) (rhsold->node_value); + if(invert) { + (*(g_evt_udn_info[udn_index]->create)) (&(rhs->inverted_value)); + (*(g_evt_udn_info[udn_index]->initialize)) (rhs->inverted_value); + (*(g_evt_udn_info[udn_index]->create)) (&(rhsold->inverted_value)); + (*(g_evt_udn_info[udn_index]->initialize)) (rhsold->inverted_value); + } + + /* Initialize the total load value to zero */ + node_data->total_load[i] = 0.0; + } + + + /* Allocate and initialize state data */ + + num_insts = ckt->evt->counts.num_insts; + state_data = data->state; + + CKALLOC(state_data->head, num_insts, void *) + CKALLOC(state_data->tail, num_insts, void *) + CKALLOC(state_data->last_step, num_insts, void *) + CKALLOC(state_data->free, num_insts, void *) + CKALLOC(state_data->modified_index, num_insts, int) + CKALLOC(state_data->modified, num_insts, Mif_Boolean_t) + CKALLOC(state_data->total_size, num_insts, int) + CKALLOC(state_data->desc, num_insts, void *) + + for(i = 0; i < num_insts; i++) { + state_data->tail[i] = &(state_data->head[i]); + state_data->last_step[i] = &(state_data->head[i]); + } + + + /* Allocate and initialize msg data */ + + num_ports = ckt->evt->counts.num_ports; + msg_data = data->msg; + + CKALLOC(msg_data->head, num_ports, void *) + CKALLOC(msg_data->tail, num_ports, void *) + CKALLOC(msg_data->last_step, num_ports, void *) + CKALLOC(msg_data->free, num_ports, void *) + CKALLOC(msg_data->modified_index, num_ports, int) + CKALLOC(msg_data->modified, num_ports, Mif_Boolean_t) + + for(i = 0; i < num_ports; i++) { + msg_data->tail[i] = &(msg_data->head[i]); + msg_data->last_step[i] = &(msg_data->head[i]); + } + + /* Don't need to initialize statistics since they were */ + /* calloc'ed above */ + + return(OK); +} + + + + +/* +EVTsetup_jobs + +This function prepares the jobs data for a new simulation. +*/ + + +static int EVTsetup_jobs( + CKTcircuit *ckt) /* The circuit structure */ +{ + + int i; + int num_jobs; + + Evt_Job_t *jobs; + Evt_Data_t *data; + + + jobs = &(ckt->evt->jobs); + data = &(ckt->evt->data); + + /* Increment the number of jobs */ + num_jobs = ++(jobs->num_jobs); + + /* Allocate/reallocate necessary pointers */ + CKREALLOC(jobs->job_name, num_jobs, void *) + CKREALLOC(jobs->node_data, num_jobs, void *) + CKREALLOC(jobs->state_data, num_jobs, void *) + CKREALLOC(jobs->msg_data, num_jobs, void *) + CKREALLOC(jobs->statistics, num_jobs, void *) + + /* Fill in the pointers, etc. for this new job */ + i = num_jobs - 1; + jobs->job_name[i] = MIFcopy((char *) ckt->CKTcurJob->JOBname); + jobs->node_data[i] = data->node; + jobs->state_data[i] = data->state; + jobs->msg_data[i] = data->msg; + jobs->statistics[i] = data->statistics; + + return(OK); +} + + + +/* +EVTsetup_load_ptrs + +This function setups up the required data in the MIFinstance +structure of event-driven and hybrid instances. +*/ + + +static int EVTsetup_load_ptrs( + CKTcircuit *ckt) /* The circuit structure */ +{ + + int i; + int j; + int k; + + int num_insts; + int num_conn; + int num_port; + int num_outputs; + + int node_index; + int output_subindex; + + MIFinstance *fast; + + Mif_Conn_Data_t *conn; + + Mif_Port_Type_t type; + Mif_Port_Data_t *port; + + Evt_Node_Data_t *node_data; + + + /* This function setups up the required data in the MIFinstance */ + /* structure of event-driven and hybrid instances */ + + /* Loop through all event-driven and hybrid instances */ + num_insts = ckt->evt->counts.num_insts; + for(i = 0; i < num_insts; i++) { + + /* Get the MIFinstance pointer */ + fast = ckt->evt->info.inst_table[i]->inst_ptr; + + /* Loop through all connections */ + num_conn = fast->num_conn; + for(j = 0; j < num_conn; j++) { + + /* Skip if connection is null */ + if(fast->conn[j]->is_null) + continue; + + conn = fast->conn[j]; + + /* Loop through all ports */ + num_port = conn->size; + for(k = 0; k < num_port; k++) { + + /* Get port data pointer for quick access */ + port = conn->port[k]; + + if(port->is_null) + continue; + + /* Skip if port is not digital or user-defined type */ + type = port->type; + if((type != MIF_DIGITAL) && (type != MIF_USER_DEFINED)) + continue; + + /* Set input.pvalue to point to rhsold.node_value or to */ + /* rhsold.inverted_value as appropriate */ + node_index = port->evt_data.node_index; + node_data = ckt->evt->data.node; + if(conn->is_input) { + if(port->invert) { + port->input.pvalue = node_data->rhsold[node_index]. + inverted_value; + } + else { + port->input.pvalue = node_data->rhsold[node_index]. + node_value; + } + } + + /* Set output.pvalue to point to rhs.node_value or rhs.output_value[i] */ + /* where i is given by the output_subindex in output info */ + /* depending on whether more than one output is connected to the node. */ + /* Note that this is only for the DCOP analysis. During a transient */ + /* analysis, new structures will be created and the pointers will */ + /* be set by EVTload */ + if(conn->is_output) { + num_outputs = ckt->evt->info.node_table[node_index]->num_outputs; + if(num_outputs <= 1) { + port->output.pvalue = node_data->rhs[node_index]. + node_value; + } + else { + output_subindex = port->evt_data.output_subindex; + port->output.pvalue = node_data->rhs[node_index]. + output_value[output_subindex]; + } + } + + } /* end for number of ports */ + } /* end for number of connections */ + } /* end for number of insts */ + + return(OK); +} diff --git a/src/xspice/evt/evttermi.c b/src/xspice/evt/evttermi.c new file mode 100755 index 000000000..7922ad817 --- /dev/null +++ b/src/xspice/evt/evttermi.c @@ -0,0 +1,512 @@ +/*============================================================================ +FILE EVTtermInsert.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains function EVTtermInsert which is called by + MIF_INP2A during the parsing of the input deck. EVTtermInsert is + similar to SPICE3's INPtermInsert except that it is used when the node + type is event-driven. Calls to this function build the info lists + for instances, nodes, outputs, and ports. The completion of the info + struct is carried out by EVTinit following the parsing of all + instances in the deck. + +INTERFACES + + void EVTtermInsert( + CKTcircuit *ckt, + MIFinstance *fast, + char *node_name, + char *type_name, + int conn_num, + int port_num, + char **err_msg) + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +#include +#include + +#include "ngspice.h" +//#include "misc.h" + +#include "cktdefs.h" +//#include "util.h" + +#include "mif.h" +#include "evt.h" +#include "evtudn.h" + +#include "mifproto.h" +#include "evtproto.h" + + +static void EVTinst_insert( + CKTcircuit *ckt, + MIFinstance *fast, + int *inst_index, + char **err_msg); + +static void EVTnode_insert( + CKTcircuit *ckt, + MIFinstance *fast, + int inst_index, + char *node_name, + char *type_name, + int conn_num, + int port_num, + int *node_index, + int *output_subindex, + char **err_msg); + +static void EVTport_insert( + CKTcircuit *ckt, + MIFinstance *fast, + int inst_index, + int node_index, + char *node_name, + int conn_num, + int port_num, + int *port_index, + char **err_msg); + +static void EVToutput_insert( + CKTcircuit *ckt, + MIFinstance *fast, + int inst_index, + int node_index, + int port_index, + int output_subindex, + int conn_num, + int port_num, + char **err_msg); + + +/* +EVTtermInsert + +This function is called by MIF_INP2A during the parsing of the input +deck. EVTtermInsert is similar to 3C1's INPtermInsert except that it is +used when the node type is event-driven. Calls to this function build +the info lists for instances, nodes, outputs, and ports. The +completion of the info struct is carried out by EVTinit following +the parsing of all instances in the deck. +*/ + + +void EVTtermInsert( + CKTcircuit *ckt, /* The circuit structure */ + MIFinstance *fast, /* The instance being parsed */ + char *node_name, /* The node name */ + char *type_name, /* The type of node */ + int conn_num, /* The port connection number */ + int port_num, /* The sub-port number - 0 for scalar ports */ + char **err_msg) /* Returned error message if any */ +{ + + int inst_index; + int node_index; + int port_index; + + int output_subindex; + + + /* Get the instance index and create new entry in inst */ + /* info list if this is a new instance. */ + EVTinst_insert(ckt, fast, &inst_index, err_msg); + if(*err_msg) + return; + + /* Get the node index and create new entry in node info */ + /* list if this is a new node */ + EVTnode_insert(ckt, fast, inst_index, node_name, type_name, + conn_num, port_num, &node_index, &output_subindex, + err_msg); + if(*err_msg) + return; + + /* Create new entry in port info list and return port index */ + EVTport_insert(ckt, fast, inst_index, node_index, node_name, conn_num, + port_num, &port_index, err_msg); + if(*err_msg) + return; + + /* Create new entry in output info list if appropriate */ + if(fast->conn[conn_num]->is_output) { + EVToutput_insert(ckt, fast, inst_index, node_index, port_index, + output_subindex, conn_num, port_num, err_msg); + if(*err_msg) + return; + } +} + + + + +/* +EVTinst_insert + +This function locates or creates a new entry for the specified +instance in the event-driven ``info'' structures during parsing. +*/ + + +static void EVTinst_insert( + CKTcircuit *ckt, /* The circuit structure */ + MIFinstance *fast, /* The instance being parsed */ + int *inst_index, /* The index found or added */ + char **err_msg) /* Error message if any */ +{ + + Mif_Boolean_t found; + int index; + + Evt_Inst_Info_t *inst; + Evt_Inst_Info_t **inst_ptr; + + + /* Scan list of instances in event structure to see if already there */ + /* and get the index */ + found = MIF_FALSE; + index = 0; + inst = ckt->evt->info.inst_list; + inst_ptr = &(ckt->evt->info.inst_list); + + while(inst) { + if(inst->inst_ptr == fast) { + found = MIF_TRUE; + break; + } + else { + index++; + inst_ptr = &(inst->next); + inst = inst->next; + } + } + + + /* If not found, create a new entry in list and increment the */ + /* instance count in the event structure */ + if(! found) { + *inst_ptr = (void *) MALLOC(sizeof(Evt_Inst_Info_t)); + inst = *inst_ptr; + inst->next = NULL; + inst->inst_ptr = fast; + index = ckt->evt->counts.num_insts; + (ckt->evt->counts.num_insts)++; + } + + /* Record the inst index in the MIFinstance structure and return it */ + fast->inst_index = index; + *inst_index = index; +} + + + +/* +EVTnode_insert + +This function locates or creates a new entry for the specified +node in the event-driven ``info'' structures during parsing. +*/ + + +static void EVTnode_insert( + CKTcircuit *ckt, /* The circuit structure */ + MIFinstance *fast, /* The instance being parsed */ + int inst_index, /* The index of inst in evt structures */ + char *node_name, /* The node name */ + char *type_name, /* The node type specified */ + int conn_num, /* The port connection number */ + int port_num, /* The sub-port number - 0 if scalar port */ + int *node_index, /* The node index found or added */ + int *output_subindex, /* The output number on this node */ + char **err_msg) /* Error message text if any */ +{ + + int i; + int udn_index=0; + Mif_Boolean_t found; + + int index; + + Evt_Node_Info_t *node; + Evt_Node_Info_t **node_ptr; + + Evt_Inst_Index_t *inst; + Evt_Inst_Index_t **inst_ptr; + + + /* *************************************** */ + /* Get and check the node type information */ + /* *************************************** */ + + /* Scan the list of user-defined node types and get the index */ + found = MIF_FALSE; + for(i = 0; i < g_evt_num_udn_types; i++) { + if(strcmp(type_name, g_evt_udn_info[i]->name) == 0) { + udn_index = i; + found = MIF_TRUE; + break; + } + } + + /* Report error if not recognized */ + if(! found) { + *err_msg = "Unrecognized connection type"; + return; + } + + /* If inverted, check to be sure invert function exists for type */ + if(fast->conn[conn_num]->port[port_num]->invert) { + if(g_evt_udn_info[udn_index]->invert == NULL) { + *err_msg = "Connection type cannot be inverted"; + return; + } + } + + + /* ******************************************* */ + /* Find/create entry in event-driven node list */ + /* ******************************************* */ + + /* Scan list of nodes in event structure to see if already there */ + /* and get the index */ + found = MIF_FALSE; + index = 0; + node = ckt->evt->info.node_list; + node_ptr = &(ckt->evt->info.node_list); + + while(node) { + if(strcmp(node_name, node->name) == 0) { + found = MIF_TRUE; + break; + } + else { + index++; + node_ptr = &(node->next); + node = node->next; + } + } + + + /* If found, verify that connection type is same as type of node */ + if(found) { + if(udn_index != node->udn_index) { + *err_msg = "Node cannot have two different types"; + return; + } + } + + /* If not found, create a new entry in list and increment the */ + /* node count in the event structure */ + if(! found) { + *node_ptr = (void *) MALLOC(sizeof(Evt_Node_Info_t)); + node = *node_ptr; + node->next = NULL; + node->name = MIFcopy(node_name); + node->udn_index = udn_index; + index = ckt->evt->counts.num_nodes; + (ckt->evt->counts.num_nodes)++; + } + + + /* ******************************************* */ + /* Update remaining items in node list struct */ + /* ******************************************* */ + + /* Update flag on node that indicates if inversion is used by any */ + /* instance inputs */ + if(fast->conn[conn_num]->is_input) + if(! node->invert) + node->invert = fast->conn[conn_num]->port[port_num]->invert; + + /* Increment counts of ports, outputs connected to node */ + (node->num_ports)++; + if(fast->conn[conn_num]->is_output) + (node->num_outputs)++; + + /* If this is an input, add instance to list if not already there */ + if(fast->conn[conn_num]->is_input) { + + found = MIF_FALSE; + inst = node->inst_list; + inst_ptr = &(node->inst_list); + + while(inst) { + if(inst_index == inst->index) { + found = MIF_TRUE; + break; + } + else { + inst_ptr = &(inst->next); + inst = inst->next; + } + } + + if(! found) { + (node->num_insts)++; + *inst_ptr = (void *) MALLOC(sizeof(Evt_Inst_Index_t)); + inst = *inst_ptr; + inst->next = NULL; + inst->index = inst_index; + } + } + + /* Record the node index in the MIFinstance structure */ + fast->conn[conn_num]->port[port_num]->evt_data.node_index = index; + + /* Return the node index */ + *node_index = index; + if(fast->conn[conn_num]->is_output) + *output_subindex = node->num_outputs - 1; + else + *output_subindex = 0; /* just for safety - shouldn't need this */ +} + + + +/* +EVTport_insert + +This function locates or creates a new entry for the specified +port in the event-driven ``info'' structures during parsing. +*/ + + +static void EVTport_insert( + CKTcircuit *ckt, /* The circuit structure */ + MIFinstance *fast, /* The instance being parsed */ + int inst_index, /* The index of inst in evt structures */ + int node_index, /* The index of the node in evt structures */ + char *node_name, /* The node name */ + int conn_num, /* The port connection number */ + int port_num, /* The sub-port number - 0 if scalar port */ + int *port_index, /* The port index found or added */ + char **err_msg) /* Error message text if any */ +{ + + Evt_Port_Info_t *port; + Evt_Port_Info_t **port_ptr; + + int index; + + /* Find the end of the port info list */ + port = ckt->evt->info.port_list; + port_ptr = &(ckt->evt->info.port_list); + + index = 0; + while(port) { + port_ptr = &(port->next); + port = port->next; + index++; + } + + + /* Update the port count and create a new entry in the list */ + + (ckt->evt->counts.num_ports)++; + + *port_ptr = (void *) MALLOC(sizeof(Evt_Port_Info_t)); + port = *port_ptr; + + /* Fill in the elements */ + port->next = NULL; + port->inst_index = inst_index; + port->node_index = node_index; + port->node_name = MIFcopy(node_name); + port->inst_name = MIFcopy((char *) fast->MIFname); + port->conn_name = MIFcopy((char *) fast->conn[conn_num]->name); + port->port_num = port_num; + + /* Record the port index in the MIFinstance structure */ + fast->conn[conn_num]->port[port_num]->evt_data.port_index = index; + + /* Return the port index */ + *port_index = index; +} + + + + +/* +EVToutput_insert + +This function locates or creates a new entry for the specified +output in the event-driven ``info'' structures during parsing. +*/ + + +static void EVToutput_insert( + CKTcircuit *ckt, /* The circuit structure */ + MIFinstance *fast, /* The instance being parsed */ + int inst_index, /* The index of inst in evt structures */ + int node_index, /* The index of the node in evt structures */ + int port_index, /* The index of the port in the evt structures */ + int output_subindex, /* The output on this node */ + int conn_num, /* The port connection number */ + int port_num, /* The sub-port number - 0 if scalar port */ + char **err_msg) /* Error message text if any */ +{ + Evt_Output_Info_t *output; + Evt_Output_Info_t **output_ptr; + + int index; + + /* Find the end of the port info list */ + output = ckt->evt->info.output_list; + output_ptr = &(ckt->evt->info.output_list); + + index = 0; + while(output) { + output_ptr = &(output->next); + output = output->next; + index++; + } + + + /* Update the port count and create a new entry in the list */ + + (ckt->evt->counts.num_outputs)++; + + *output_ptr = (void *) MALLOC(sizeof(Evt_Output_Info_t)); + output = *output_ptr; + + /* Fill in the elements */ + output->next = NULL; + output->inst_index = inst_index; + output->node_index = node_index; + output->port_index = port_index; + output->output_subindex = output_subindex; + + /* Record the output index and subindex in the MIFinstance structure */ + fast->conn[conn_num]->port[port_num]->evt_data.output_index = index; + fast->conn[conn_num]->port[port_num]->evt_data.output_subindex + = output_subindex; + +} diff --git a/src/xspice/examples/analog_models1_ac.deck b/src/xspice/examples/analog_models1_ac.deck new file mode 100755 index 000000000..6467c2bd2 --- /dev/null +++ b/src/xspice/examples/analog_models1_ac.deck @@ -0,0 +1,67 @@ +Code Model Test - AC: gain, summer, mult, divide, pwl +* +* +*** analysis type *** +.ac dec 10 10 1000 +* +*** input sources *** +* +v1 1 0 1.0 AC 1.0 0.0 +* +v2 2 0 1.0 AC 1.0 0.0 +* +v3 3 0 DC 2.0 +* +v4 4 0 0.5 AC 0.5 0.0 +* +*** gain block *** +a1 1 10 gain1 +.model gain1 gain (in_offset=0.0 gain=2.0 out_offset=0.0) +* +* +*** summer block *** +a2 [1 2] 20 summer1 +.model summer1 summer (in_offset=[0.0 0.0] in_gain=[1.0 1.0] ++ out_gain=1.0 out_offset=0.0) +* +* +*** mult block *** +a3 [1 3] 30 mult1 +.model mult1 mult (in_offset=[0.0 0.0] in_gain=[1.0 1.0] ++ out_gain=1.0 out_offset=0.0) +* +* +*** divider block *** +a4 1 3 40 divide1 +.model divide1 divide (num_offset=0.0 num_gain=1.0 den_offset=0.0 den_gain=1.0 ++ den_lower_limit=1.0e-10 den_domain=1.0e-16 ++ fraction=false out_gain=1.0 out_offset=0.0) +* +* +*** pwl block *** +a5 4 50 pwl1 +.model pwl1 pwl (x_array=[-1.0 0.0 1.0 2.0 3.0 4.0 5.0] ++ y_array=[-1.0 0.0 1.0 4.0 4.5 5.0 5.0] ++ input_domain=0.01 fraction=TRUE) +* +* +*** resistors to ground *** +r1 1 0 1k +r2 2 0 1k +r3 3 0 1k +r4 4 0 1k +* +r10 10 0 1k +r20 20 0 1k +r30 30 0 1k +r40 40 0 1k +r50 50 0 1k +* +* +.end + + + + + + diff --git a/src/xspice/examples/analog_models1_dc.deck b/src/xspice/examples/analog_models1_dc.deck new file mode 100755 index 000000000..4ad6f0c83 --- /dev/null +++ b/src/xspice/examples/analog_models1_dc.deck @@ -0,0 +1,61 @@ +Code Model Test - DC: gain, summer, mult, divide, pwl +* +* +*** analysis type *** +.op +* +*** input sources *** +v1 1 0 DC 2 +* +v2 2 0 DC 2 +* +*** gain block *** +a1 1 10 gain1 +.model gain1 gain (in_offset=0.0 gain=2.0 out_offset=0.0) +* +* +*** summer block *** +a2 [1 2] 20 summer1 +.model summer1 summer (in_offset=[0.0 0.0] in_gain=[1.0 1.0] ++ out_gain=1.0 out_offset=0.0) +* +* +*** mult block *** +a3 [1 1] 30 mult1 +.model mult1 mult (in_offset=[0.0 0.0] in_gain=[1.0 1.0] ++ out_gain=0.1 out_offset=0.0) +* +* +*** divider block *** +a4 2 1 40 divide1 +.model divide1 divide (num_offset=0.0 num_gain=1.0 den_offset=0.0 den_gain=1.0 ++ den_lower_limit=1.0e-10 den_domain=1.0e-16 ++ fraction=false out_gain=1.0 out_offset=0.0) +* +* +*** pwl block *** +a5 1 50 pwl1 +.model pwl1 pwl (x_array=[-1.0 0.0 1.0 2.0 3.0 4.0 5.0] ++ y_array=[ 0.0 0.0 1.0 4.0 4.5 5.0 5.0] ++ input_domain=0.01 fraction=TRUE) +* +* +*** resistors to ground *** +r1 1 0 1k +r2 2 0 1k +r3 3 0 1k +* +r10 10 0 1k +r20 20 0 1k +r30 30 0 1k +r40 40 0 1k +r50 50 0 1k +* +* +.end + + + + + + diff --git a/src/xspice/examples/analog_models1_swept_dc.deck b/src/xspice/examples/analog_models1_swept_dc.deck new file mode 100755 index 000000000..e211325bd --- /dev/null +++ b/src/xspice/examples/analog_models1_swept_dc.deck @@ -0,0 +1,61 @@ +Code Model Test - Swept DC: gain, summer, mult, divide, pwl +* +* +*** analysis type *** +.dc v1 .1 10 .1 +* +*** input sources *** +v1 1 0 DC 2 +* +v2 2 0 DC 2 +* +*** gain block *** +a1 1 10 gain1 +.model gain1 gain (in_offset=0.0 gain=2.0 out_offset=0.0) +* +* +*** summer block *** +a2 [1 2] 20 summer1 +.model summer1 summer (in_offset=[0.0 0.0] in_gain=[1.0 1.0] ++ out_gain=1.0 out_offset=0.0) +* +* +*** mult block *** +a3 [1 1] 30 mult1 +.model mult1 mult (in_offset=[0.0 0.0] in_gain=[1.0 1.0] ++ out_gain=0.1 out_offset=0.0) +* +* +*** divider block *** +a4 2 1 40 divide1 +.model divide1 divide (num_offset=0.0 num_gain=1.0 den_offset=0.0 den_gain=1.0 ++ den_lower_limit=1.0e-10 den_domain=1.0e-16 ++ fraction=false out_gain=1.0 out_offset=0.0) +* +* +*** pwl block *** +a5 1 50 pwl1 +.model pwl1 pwl (x_array=[-1.0 0.0 1.0 2.0 3.0 4.0 5.0] ++ y_array=[ 0.0 0.0 1.0 4.0 4.5 5.0 5.0] ++ input_domain=0.01 fraction=TRUE) +* +* +*** resistors to ground *** +r1 1 0 1k +r2 2 0 1k +r3 3 0 1k +* +r10 10 0 1k +r20 20 0 1k +r30 30 0 1k +r40 40 0 1k +r50 50 0 1k +* +* +.end + + + + + + diff --git a/src/xspice/examples/analog_models1_transient.deck b/src/xspice/examples/analog_models1_transient.deck new file mode 100755 index 000000000..a4967d275 --- /dev/null +++ b/src/xspice/examples/analog_models1_transient.deck @@ -0,0 +1,62 @@ +Code Model Test - Transient: gain, summer, mult, divide, pwl +* +* +*** analysis type *** +.tran .1s 10s +* +*** input sources *** +* +v1 1 0 DC PWL(0 0 10 10) +* +v2 2 0 DC 2 +* +*** gain block *** +a1 1 10 gain1 +.model gain1 gain (in_offset=0.0 gain=2.0 out_offset=0.0) +* +* +*** summer block *** +a2 [1 2] 20 summer1 +.model summer1 summer (in_offset=[0.0 0.0] in_gain=[1.0 1.0] ++ out_gain=1.0 out_offset=0.0) +* +* +*** mult block *** +a3 [1 1] 30 mult1 +.model mult1 mult (in_offset=[0.0 0.0] in_gain=[1.0 1.0] ++ out_gain=0.1 out_offset=0.0) +* +* +*** divider block *** +a4 2 1 40 divide1 +.model divide1 divide (num_offset=0.0 num_gain=1.0 den_offset=0.0 den_gain=1.0 ++ den_lower_limit=0.1 den_domain=1.0e-16 ++ fraction=false out_gain=1.0 out_offset=0.0) +* +* +*** pwl block *** +a5 1 50 pwl1 +.model pwl1 pwl (x_array=[-1.0 0.0 1.0 2.0 3.0 4.0 5.0] ++ y_array=[ 0.0 0.0 1.0 4.0 4.5 5.0 5.0] ++ input_domain=0.01 fraction=TRUE) +* +* +*** resistors to ground *** +r1 1 0 1k +r2 2 0 1k +r3 3 0 1k +* +r10 10 0 1k +r20 20 0 1k +r30 30 0 1k +r40 40 0 1k +r50 50 0 1k +* +* +.end + + + + + + diff --git a/src/xspice/examples/analog_models2_ac.deck b/src/xspice/examples/analog_models2_ac.deck new file mode 100755 index 000000000..0b450c809 --- /dev/null +++ b/src/xspice/examples/analog_models2_ac.deck @@ -0,0 +1,66 @@ +Code Model Test - Swept DC: int, d_dt, s_xfer, core, lcouple +* +* +*** analysis type *** +.ac dec 10 10 1000 +* +* +*** input sources *** +* +v1 1 0 1.0 AC 1.0 0.0 +* +* +*** integrator block *** +a1 1 10 int1 +.model int1 int (in_offset=0.0 gain=2.0 out_lower_limit=-1.0e6 ++ out_upper_limit=1.0e6 limit_range=1.0e-6 out_ic=0.0) +* +* +*** differentiator block *** +a2 1 20 d_dt1 +.model d_dt1 d_dt (out_offset=0.0 gain=1.0 out_lower_limit=-1.0e6 ++ out_upper_limit=1.0e6 limit_range=1.0e-6) +* +* +*** s_xfer block *** +a3 1 30 filter1 +.model filter1 s_xfer (in_offset=0.0 gain=1.0 num_coeff=[1.0] ++ den_coeff=[1.0 1.414214 1.0] int_ic=[0.0 0.0] ++ denormalized_freq=628.0) +* +* +* +*** magnetic core & inductive coupling *** +v40 45 46 0.0 +a4 40 45 core1 +.model core1 core (H_array=[-2.0 -1.0 1.0 2.0] ++ B_array=[-2.0 -1.0 1.0 2.0] ++ area=1.0 length=1.0 input_domain=1.0e-6 ++ fraction=TRUE mode=1 ++ in_low=-1.0 in_high=1.0 hyst=0.5 ++ out_lower_limit=-1.0 out_upper_limit=1.0) +* +* +r5 1 50 100.0 +a5 (50 0) (40 46) inductor1 +.model inductor1 lcouple (num_turns=10) +* +* +*** resistors to ground *** +r1 1 0 1k +* +r10 10 0 1e12 +r20 20 0 1e12 +r30 30 0 1e12 +r40 40 0 1e12 +r45 45 0 1e12 +r50 50 0 1e12 +* +* +.end + + + + + + diff --git a/src/xspice/examples/analog_models2_dc.deck b/src/xspice/examples/analog_models2_dc.deck new file mode 100755 index 000000000..66a612e46 --- /dev/null +++ b/src/xspice/examples/analog_models2_dc.deck @@ -0,0 +1,63 @@ +Code Model Test - DC: int, d_dt, s_xfer, core, lcouple +* +* +*** analysis type *** +.op +* +*** input sources *** +v1 1 0 DC 1.0 +* +* +* +* +*** integrator block *** +a1 1 10 int1 +.model int1 int (in_offset=0.0 gain=2.0 out_lower_limit=-1.0e6 ++ out_upper_limit=1.0e6 limit_range=1.0e-6 out_ic=0.0) +* +* +*** differentiator block *** +a2 1 20 d_dt1 +.model d_dt1 d_dt (out_offset=0.0 gain=1.0 out_lower_limit=-1.0e6 ++ out_upper_limit=1.0e6 limit_range=1.0e-6) +* +* +*** s_xfer block *** +a3 1 30 filter1 +.model filter1 s_xfer (in_offset=0.0 gain=1.0 num_coeff=[1.0] ++ den_coeff=[1.0 1.425625 1.516203] int_ic=[0.0 0.0] ++ denormalized_freq=6283.2) +* +* +*** magnetic core & inductive coupling *** +a4 40 45 core1 +.model core1 core (H_array=[-2.0 -1.0 1.0 2.0] ++ B_array=[-2.0 -1.0 1.0 2.0] ++ area=1.0 length=1.0 input_domain=1.0e-6 ++ fraction=TRUE mode=1 ++ in_low=-1.0 in_high=1.0 hyst=0.5 ++ out_lower_limit=-1.0 out_upper_limit=1.0) +* +* +r5 1 50 100.0 +a5 (50 0) (40 45) inductor1 +.model inductor1 lcouple (num_turns=10) +* +* +*** resistors to ground *** +r1 1 0 1k +* +r10 10 0 1k +r20 20 0 1k +r30 30 0 1k +r40 40 0 1k +r50 50 0 1k +* +* +.end + + + + + + diff --git a/src/xspice/examples/analog_models2_swept_dc.deck b/src/xspice/examples/analog_models2_swept_dc.deck new file mode 100755 index 000000000..470d11c81 --- /dev/null +++ b/src/xspice/examples/analog_models2_swept_dc.deck @@ -0,0 +1,64 @@ +Code Model Test - Swept DC: int, d_dt, s_xfer, core, lcouple +* +* +*** analysis type *** +.dc v1 .1 10 .5 +* +*** input sources *** +v1 1 0 DC 2 +* +* +*** integrator block *** +a1 1 10 int1 +.model int1 int (in_offset=0.0 gain=2.0 out_lower_limit=-1.0e6 ++ out_upper_limit=1.0e6 limit_range=1.0e-6 out_ic=0.0) +* +* +*** differentiator block *** +a2 1 20 d_dt1 +.model d_dt1 d_dt (out_offset=0.0 gain=1.0 out_lower_limit=-1.0e6 ++ out_upper_limit=1.0e6 limit_range=1.0e-6) +* +* +*** s_xfer block *** +a3 1 30 filter1 +.model filter1 s_xfer (in_offset=0.0 gain=1.0 num_coeff=[1.0] ++ den_coeff=[1.0 1.414214 1.0] int_ic=[0.0 0.0] ++ denormalized_freq=1.0) +* +* +* +*** magnetic core & inductive coupling *** +v40 45 46 0.0 +a4 40 45 core1 +.model core1 core (H_array=[-2.0 -1.0 1.0 2.0] ++ B_array=[-2.0 -1.0 1.0 2.0] ++ area=1.0 length=1.0 input_domain=1.0e-6 ++ fraction=TRUE mode=1 ++ in_low=-1.0 in_high=1.0 hyst=0.5 ++ out_lower_limit=-1.0 out_upper_limit=1.0) +* +* +r5 1 50 100.0 +a5 (50 0) (40 46) inductor1 +.model inductor1 lcouple (num_turns=10) +* +* +*** resistors to ground *** +r1 1 0 1k +* +r10 10 0 1e12 +r20 20 0 1e12 +r30 30 0 1e12 +r40 40 0 1e12 +r45 45 0 1e12 +r50 50 0 1e12 +* +* +.end + + + + + + diff --git a/src/xspice/examples/analog_models2_transient.deck b/src/xspice/examples/analog_models2_transient.deck new file mode 100755 index 000000000..c9efac726 --- /dev/null +++ b/src/xspice/examples/analog_models2_transient.deck @@ -0,0 +1,67 @@ +Code Model Test - Transient: int, d_dt, s_xfer, core, lcouple +* +* +*** analysis type *** +.tran .1s 10s +* +*** input sources *** +* +v1 1 0 DC PWL(0 0 10 10) +* +v2 2 0 DC PWL(0 0 0.1 0.1 0.2 0.9 0.3 1.0 10 1.0) +* +* +* +*** integrator block *** +a1 1 10 int1 +.model int1 int (in_offset=0.0 gain=2.0 out_lower_limit=-1.0e6 ++ out_upper_limit=1.0e6 limit_range=1.0e-6 out_ic=0.0) +* +* +*** differentiator block *** +a2 1 20 d_dt1 +.model d_dt1 d_dt (out_offset=0.0 gain=1.0 out_lower_limit=-1.0e6 ++ out_upper_limit=1.0e6 limit_range=1.0e-6) +* +* +*** s_xfer block *** +a3 2 30 filter1 +.model filter1 s_xfer (in_offset=0.0 gain=1.0 num_coeff=[1.0] ++ den_coeff=[1.0 1.414214 1.0] int_ic=[0.0 0.0] ++ denormalized_freq=1.0) +* +* +* +*** magnetic core & inductive coupling *** +a4 40 45 core1 +.model core1 core (H_array=[-2.0 -1.0 1.0 2.0] ++ B_array=[-2.0 -1.0 1.0 2.0] ++ area=1.0 length=1.0 input_domain=1.0e-6 ++ fraction=TRUE mode=1 ++ in_low=-1.0 in_high=1.0 hyst=0.5 ++ out_lower_limit=-1.0 out_upper_limit=1.0) +* +* +r5 1 50 100.0 +a5 (50 0) (40 45) inductor1 +.model inductor1 lcouple (num_turns=10) +* +* +*** resistors to ground *** +r1 1 0 1k +r2 2 0 1k +* +r10 10 0 1k +r20 20 0 1k +r30 30 0 1k +r40 40 0 1k +r50 50 0 1k +* +* +.end + + + + + + diff --git a/src/xspice/examples/analog_models3_ac.deck b/src/xspice/examples/analog_models3_ac.deck new file mode 100755 index 000000000..3c4d7fa96 --- /dev/null +++ b/src/xspice/examples/analog_models3_ac.deck @@ -0,0 +1,81 @@ +Code Model Test - AC: hyst, limit, ilimit, climit, cmeter, lmeter +* +* +*** analysis type *** +.ac dec 10 10 1000 +* +* +*** input sources *** +* +v1 1 0 1.0 AC 1.0 0.0 +* +v2 2 0 DC 10.0 +* +v3 3 0 DC -10.0 +* +* +* +*** hyst block *** +a1 1 10 hyst1 +.model hyst1 hyst (in_low=0.0 in_high=1.0 hyst=0.1 out_lower_limit=0.0 ++ out_upper_limit=1.0 input_domain=0.01 fraction=TRUE) +* +* +*** limit block *** +a2 1 20 limit1 +.model limit1 limit (in_offset=0.0 gain=1.0 out_lower_limit=-1.0e6 ++ out_upper_limit=1.0e6 limit_range=1.0e-6 fraction=FALSE) +* +* +*** ilimit block *** +a3 1 2 3 30 ilimit1 +.model ilimit1 ilimit (in_offset=0.0 gain=1.0 r_out_source=1.0 ++ r_out_sink=1.0 i_limit_source=1.0 ++ i_limit_sink=1.0 v_pwr_range=1.0e-3 ++ i_source_range=1.0e-6 i_sink_range=1.0e-6 ++ r_out_domain=1.0e-6) +* +* +*** climit block *** +a4 1 2 3 40 climit1 +.model climit1 climit (in_offset=0.0 gain=1.0 upper_delta=0.0 ++ lower_delta=0.0 limit_range=1.0e-6 ++ fraction=FALSE) +* +* +*** cmeter block *** +c5 51 0 1.0e-6 +a5 51 50 cmeter1 +.model cmeter1 cmeter (gain=1.0) +* +* +* +*** lmeter block *** +l6 61 0 1.0e-6 +a6 61 60 lmeter1 +.model lmeter1 lmeter (gain=1.0) +* +* +* +*** resistors to ground *** +r1 1 0 10k +r2 2 0 10k +r3 3 0 10k +* +r10 10 0 10k +r20 20 0 10k +r30 30 0 10k +r40 40 0 10k +r50 50 0 10k +r51 51 0 10k +r60 60 0 10k +r61 61 0 10k +* +* +.end + + + + + + diff --git a/src/xspice/examples/analog_models3_dc.deck b/src/xspice/examples/analog_models3_dc.deck new file mode 100755 index 000000000..cff617cdc --- /dev/null +++ b/src/xspice/examples/analog_models3_dc.deck @@ -0,0 +1,79 @@ +Code Model Test - DC: hyst, limit, ilimit, climit, cmeter, lmeter +* +* +*** analysis type *** +.op +* +*** input sources *** +v1 1 0 DC 1.0 +* +v2 2 0 DC 10.0 +* +v3 3 0 DC -10.0 +* +* +* +*** hyst block *** +a1 1 10 hyst1 +.model hyst1 hyst (in_low=0.0 in_high=1.0 hyst=0.1 out_lower_limit=0.0 ++ out_upper_limit=1.0 input_domain=0.01 fraction=TRUE) +* +* +*** limit block *** +a2 1 20 limit1 +.model limit1 limit (in_offset=0.0 gain=1.0 out_lower_limit=-1.0e6 ++ out_upper_limit=1.0e6 limit_range=1.0e-6 fraction=FALSE) +* +* +*** ilimit block *** +a3 1 2 3 30 ilimit1 +.model ilimit1 ilimit (in_offset=0.0 gain=1.0 r_out_source=1.0 ++ r_out_sink=1.0 i_limit_source=1.0 ++ i_limit_sink=1.0 v_pwr_range=1.0e-3 ++ i_source_range=1.0e-3 i_sink_range=1.0e-3 ++ r_out_domain=1.0e-3) +* +* +*** climit block *** +a4 1 2 3 40 climit1 +.model climit1 climit (in_offset=0.0 gain=1.0 upper_delta=0.0 ++ lower_delta=0.0 limit_range=1.0e-6 ++ fraction=FALSE) +* +* +*** cmeter block *** +c5 51 0 1.0e-6 +a5 51 50 cmeter1 +.model cmeter1 cmeter (gain=1.0) +* +* +* +*** lmeter block *** +l6 61 0 1.0e-6 +a6 61 60 lmeter1 +.model lmeter1 lmeter (gain=1.0) +* +* +* +*** resistors to ground *** +r1 1 0 10k +r2 2 0 10k +r3 3 0 10k +* +r10 10 0 10k +r20 20 0 10k +r30 30 0 10k +r40 40 0 10k +r50 50 0 10k +r51 51 0 10k +r60 60 0 10k +r61 61 0 10k +* +* +.end + + + + + + diff --git a/src/xspice/examples/analog_models3_swept_dc.deck b/src/xspice/examples/analog_models3_swept_dc.deck new file mode 100755 index 000000000..394e7aac1 --- /dev/null +++ b/src/xspice/examples/analog_models3_swept_dc.deck @@ -0,0 +1,79 @@ +Code Model Test - DC: hyst, limit, ilimit, climit, cmeter, lmeter +* +* +*** analysis type *** +.dc v1 .1 15 .5 +* +*** input sources *** +v1 1 0 DC 1.0 +* +v2 2 0 DC 10.0 +* +v3 3 0 DC -10.0 +* +* +* +*** hyst block *** +a1 1 10 hyst1 +.model hyst1 hyst (in_low=0.0 in_high=1.0 hyst=0.1 out_lower_limit=0.0 ++ out_upper_limit=1.0 input_domain=0.01 fraction=TRUE) +* +* +*** limit block *** +a2 1 20 limit1 +.model limit1 limit (in_offset=0.0 gain=1.0 out_lower_limit=-1.0e6 ++ out_upper_limit=1.0e6 limit_range=1.0e-6 fraction=FALSE) +* +* +*** ilimit block *** +a3 1 2 3 30 ilimit1 +.model ilimit1 ilimit (in_offset=0.0 gain=1.0 r_out_source=1.0 ++ r_out_sink=1.0 i_limit_source=1.0 ++ i_limit_sink=1.0 v_pwr_range=1.0e-3 ++ i_source_range=1.0e-6 i_sink_range=1.0e-6 ++ r_out_domain=1.0e-6) +* +* +*** climit block *** +a4 1 2 3 40 climit1 +.model climit1 climit (in_offset=0.0 gain=1.0 upper_delta=0.0 ++ lower_delta=0.0 limit_range=1.0e-6 ++ fraction=FALSE) +* +* +*** cmeter block *** +c5 51 0 1.0e-6 +a5 51 50 cmeter1 +.model cmeter1 cmeter (gain=1.0) +* +* +* +*** lmeter block *** +l6 61 0 1.0e-6 +a6 61 60 lmeter1 +.model lmeter1 lmeter (gain=1.0) +* +* +* +*** resistors to ground *** +r1 1 0 10k +r2 2 0 10k +r3 3 0 10k +* +r10 10 0 10k +r20 20 0 10k +r30 30 0 10k +r40 40 0 10k +r50 50 0 10k +r51 51 0 10k +r60 60 0 10k +r61 61 0 10k +* +* +.end + + + + + + diff --git a/src/xspice/examples/analog_models3_transient.deck b/src/xspice/examples/analog_models3_transient.deck new file mode 100755 index 000000000..c92ffff96 --- /dev/null +++ b/src/xspice/examples/analog_models3_transient.deck @@ -0,0 +1,80 @@ +Code Model Test - Transient: hyst, limit, ilimit, climit, cmeter, lmeter +* +* +*** analysis type *** +.tran .1s 15s +* +*** input sources *** +* +v1 1 0 DC PWL(0 0 15 15) +* +v2 2 0 DC 10.0 +* +v3 3 0 DC -10.0 +* +* +* +*** hyst block *** +a1 1 10 hyst1 +.model hyst1 hyst (in_low=0.0 in_high=1.0 hyst=0.1 out_lower_limit=0.0 ++ out_upper_limit=1.0 input_domain=0.01 fraction=TRUE) +* +* +*** limit block *** +a2 1 20 limit1 +.model limit1 limit (in_offset=0.0 gain=1.0 out_lower_limit=-1.0e6 ++ out_upper_limit=1.0e6 limit_range=1.0e-6 fraction=FALSE) +* +* +*** ilimit block *** +a3 1 2 3 30 ilimit1 +.model ilimit1 ilimit (in_offset=0.0 gain=1.0 r_out_source=1.0 ++ r_out_sink=1.0 i_limit_source=1.0 ++ i_limit_sink=1.0 v_pwr_range=1.0e-3 ++ i_source_range=1.0e-6 i_sink_range=1.0e-6 ++ r_out_domain=1.0e-6) +* +* +*** climit block *** +a4 1 2 3 40 climit1 +.model climit1 climit (in_offset=0.0 gain=1.0 upper_delta=0.0 ++ lower_delta=0.0 limit_range=1.0e-6 ++ fraction=FALSE) +* +* +*** cmeter block *** +c5 51 0 1.0e-6 +a5 51 50 cmeter1 +.model cmeter1 cmeter (gain=1.0) +* +* +* +*** lmeter block *** +l6 61 0 1.0e-6 +a6 61 60 lmeter1 +.model lmeter1 lmeter (gain=1.0) +* +* +* +*** resistors to ground *** +r1 1 0 10k +r2 2 0 10k +r3 3 0 10k +* +r10 10 0 10k +r20 20 0 10k +r30 30 0 10k +r40 40 0 10k +r50 50 0 10k +r51 51 0 10k +r60 60 0 10k +r61 61 0 10k +* +* +.end + + + + + + diff --git a/src/xspice/examples/analog_models4_ac.deck b/src/xspice/examples/analog_models4_ac.deck new file mode 100755 index 000000000..70413e1ad --- /dev/null +++ b/src/xspice/examples/analog_models4_ac.deck @@ -0,0 +1,78 @@ +Code Model Test - DC: sine, triangle, aswitch, zener, oneshot +* +* +*** analysis type *** +.ac dec 10 10 1000 +* +* +*** input sources *** +* +v1 1 0 1.0 AC 1.0 0.0 +* +v2 2 0 DC 1.0 +* +v3 3 0 DC 1.0 +* +* +* +* +*** sine block *** +a1 1 10 sine1 +.model sine1 sine (cntl_array=[-1.0 0.0 1.0 2.0] ++ freq_array=[1.0 1.0 100.0 100.0] ++ out_low=-1.0 out_high=1.0) +* +* +*** triangle block *** +a2 1 20 triangle1 +.model triangle1 triangle (cntl_array=[-1.0 0.0 1.0 2.0] ++ freq_array=[1.0 1.0 100.0 100.0] ++ out_low=-1.0 out_high=1.0 duty_cycle=0.8) +* +* +*** aswitch block *** +a3 1 (2 30) aswitch1 +.model aswitch1 aswitch (cntl_off=0.0 cntl_on=1.0 log=TRUE ++ r_off=1.0e12 r_on=10.0) +* +* +*** zener diode *** +r4 1 40 10K +a4 (40 0) zener1 +.model zener1 zener (v_breakdown=10.0 i_breakdown=2.0e-2 ++ r_breakdown=1.0 i_rev=1.0e-6 i_sat=1.0e-12 ++ n_forward=1.0 limit_switch=FALSE) +* +* +*** oneshot block *** +a5 3 1 2 50 oneshot1 +.model oneshot1 oneshot (cntl_array=[-1.0 0.0 1.0 2.0] ++ pw_array=[1.0 1.0 0.1 0.1] clk_trig=0.5 ++ pos_edge_trig=TRUE out_low=0.0 out_high=1.0 ++ rise_time=1.0e-6 rise_delay=1.0e-9 ++ fall_delay=1.0e-9 fall_time=1.0e-6 ++ retrig=FALSE) +* +* +* +* +*** resistors to ground *** +r1 1 0 10k +r2 2 0 10k +r3 3 0 10k +* +r10 10 0 10k +r20 20 0 10k +r30 30 0 10k +r40 40 0 10k +r50 50 0 10k +r60 60 0 10k +* +* +.end + + + + + + diff --git a/src/xspice/examples/analog_models4_dc.deck b/src/xspice/examples/analog_models4_dc.deck new file mode 100755 index 000000000..b3254ea5e --- /dev/null +++ b/src/xspice/examples/analog_models4_dc.deck @@ -0,0 +1,74 @@ +Code Model Test - DC: sine triangle aswitch zener oneshot +* +* +*** analysis type *** +.op +* +*** input sources *** +v1 1 0 DC 1.0 +* +v2 2 0 DC 1.0 +* +v3 3 0 DC 1.0 +* +* +*** sine block *** +a1 1 10 sine1 +.model sine1 sine (cntl_array=[-1.0 0.0 1.0 2.0] ++ freq_array=[1.0 1.0 100.0 100.0] ++ out_low=-1.0 out_high=1.0) +* +* +*** triangle block *** +a2 1 20 triangle1 +.model triangle1 triangle (cntl_array=[-1.0 0.0 1.0 2.0] ++ freq_array=[1.0 1.0 100.0 100.0] ++ out_low=-1.0 out_high=1.0 duty_cycle=0.8) +* +* +*** aswitch block *** +a3 1 (2 30) aswitch1 +.model aswitch1 aswitch (cntl_off=0.0 cntl_on=1.0 log=TRUE ++ r_off=1.0e12 r_on=10.0) +* +* +*** zener diode *** +r4 1 40 10K +a4 (40 0) zener1 +.model zener1 zener (v_breakdown=10.0 i_breakdown=2.0e-2 ++ r_breakdown=1.0 i_rev=1.0e-6 i_sat=1.0e-12 ++ n_forward=1.0 limit_switch=FALSE) +* +* +*** oneshot block *** +a5 3 1 2 50 oneshot1 +.model oneshot1 oneshot (cntl_array=[-1.0 0.0 1.0 2.0] ++ pw_array=[1.0 1.0 0.1 0.1] clk_trig=0.5 ++ pos_edge_trig=TRUE out_low=0.0 out_high=1.0 ++ rise_time=1.0e-6 rise_delay=1.0e-9 ++ fall_delay=1.0e-9 fall_time=1.0e-6 ++ retrig=FALSE) +* +* +* +* +*** resistors to ground *** +r1 1 0 10k +r2 2 0 10k +r3 3 0 10k +* +r10 10 0 10k +r20 20 0 10k +r30 30 0 10k +r40 40 0 10k +r50 50 0 10k +r60 60 0 10k +* +* +.end + + + + + + diff --git a/src/xspice/examples/analog_models4_swept_dc.deck b/src/xspice/examples/analog_models4_swept_dc.deck new file mode 100755 index 000000000..d06fe05f8 --- /dev/null +++ b/src/xspice/examples/analog_models4_swept_dc.deck @@ -0,0 +1,72 @@ +Code Model Test - Swept DC: sine, triangle, aswitch, zener, oneshot +* +* +*** analysis type *** +.dc v1 .1 15 .5 +* +*** input sources *** +v1 1 0 DC 1.0 +* +v2 2 0 DC 1.0 +* +v3 3 0 DC 1.0 +* +* +*** sine block *** +a1 1 10 sine1 +.model sine1 sine (cntl_array=[-1.0 0.0 1.0 2.0] ++ freq_array=[1.0 1.0 100.0 100.0] ++ out_low=-1.0 out_high=1.0) +* +* +*** triangle block *** +a2 1 20 triangle1 +.model triangle1 triangle (cntl_array=[-1.0 0.0 1.0 2.0] ++ freq_array=[1.0 1.0 100.0 100.0] ++ out_low=-1.0 out_high=1.0 duty_cycle=0.8) +* +* +*** aswitch block *** +a3 1 (2 30) aswitch1 +.model aswitch1 aswitch (cntl_off=0.0 cntl_on=1.0 log=TRUE ++ r_off=1.0e12 r_on=10.0) +* +* +*** zener diode *** +r4 1 40 100 +a4 (0 40) zener1 +.model zener1 zener (v_breakdown=8.0 i_breakdown=2.0e-2 ++ r_breakdown=1.0 i_rev=1.0e-6 i_sat=1.0e-12 ++ n_forward=1.0 limit_switch=FALSE) +* +* +*** oneshot block *** +a5 3 1 2 50 oneshot1 +.model oneshot1 oneshot (cntl_array=[-1.0 0.0 1.0 2.0] ++ pw_array=[1.0 1.0 0.1 0.1] clk_trig=0.5 ++ pos_edge_trig=TRUE out_low=0.0 out_high=1.0 ++ rise_time=1.0e-6 rise_delay=1.0e-9 ++ fall_delay=1.0e-9 fall_time=1.0e-6 ++ retrig=FALSE) +* +* +* +* +*** resistors to ground *** +r1 1 0 10k +r2 2 0 10k +r3 3 0 10k +* +r10 10 0 10k +r20 20 0 10k +r30 30 0 10k +r40 40 0 10k +r50 50 0 10k +r60 60 0 10k +* +* +.end + + + + diff --git a/src/xspice/examples/analog_models4_transient.deck b/src/xspice/examples/analog_models4_transient.deck new file mode 100755 index 000000000..9ad60efee --- /dev/null +++ b/src/xspice/examples/analog_models4_transient.deck @@ -0,0 +1,76 @@ +Code Model Test - Transient: sine, triangle, aswitch, zener, oneshot +* +* +*** analysis type *** +.tran .01ms 2ms +* +*** input sources *** +* +v1 1 0 DC 0.0 PWL(0 0 2e-3 2) +* +v2 2 0 DC 0.0 PWL(0 0 2e-3 10) +* +v3 3 0 DC 0.0 PWL(0 0.0 0.9e-3 0.0 1e-3 1.0 1.9e-3 1.0 2e-3 0.0 2.9e-3 0.0) +* +v4 4 0 DC 1.0 +* +* +*** sine block *** +a1 1 10 sine1 +.model sine1 sine (cntl_array=[-1.0 0.0 10.0 20.0] ++ freq_array=[500 500 2000 2000] ++ out_low=-1.0 out_high=1.0) +* +* +*** triangle block *** +a2 1 20 triangle1 +.model triangle1 triangle (cntl_array=[-1.0 0.0 10.0 20.0] ++ freq_array=[500 500 10000 10000] ++ out_low=-1.0 out_high=1.0 duty_cycle=0.5) +* +* +*** aswitch block *** +a3 1 (4 30) aswitch1 +.model aswitch1 aswitch (cntl_off=0.0 cntl_on=1.0 log=TRUE ++ r_off=1.0e12 r_on=10.0) +* +* +*** zener diode *** +rzener 2 40 100 +a4 (0 40) zener1 +.model zener1 zener (v_breakdown=9.0 i_breakdown=2.0e-2 ++ r_breakdown=1.0 i_rev=1.0e-6 i_sat=1.0e-12 ++ n_forward=1.0 limit_switch=FALSE) +* +* +*** oneshot block *** +a5 3 1 0 50 oneshot1 +.model oneshot1 oneshot (cntl_array=[-1.0 0.0 1.0 2.0] ++ pw_array=[2.0e-3 2.0e-3 0.1e-3 0.1e-3] clk_trig=0.5 ++ pos_edge_trig=TRUE out_low=0.0 out_high=1.0 ++ rise_time=1.0e-6 rise_delay=1.0e-9 ++ fall_delay=1.0e-9 fall_time=1.0e-6 ++ retrig=FALSE) +* +* +* +* +*** resistors to ground *** +r1 1 0 10k +r2 2 0 10k +r3 3 0 10k +r4 4 0 10k +* +r10 10 0 10k +r20 20 0 10k +r30 30 0 10k +r40 40 0 10k +r50 50 0 10k +r60 60 0 10k +* +* +.end + + + + diff --git a/src/xspice/examples/arbitrary_phase.deck b/src/xspice/examples/arbitrary_phase.deck new file mode 100755 index 000000000..3ef68bc29 --- /dev/null +++ b/src/xspice/examples/arbitrary_phase.deck @@ -0,0 +1,17 @@ +Arbitrary Phase SIN and PULSE Sources +* +* This circuit generates two cycles of sine and square waves +* beginning at +45 degrees. +* +* Phase shift is specified after Berkeley defined parameters +* on the independent source cards. +* +.tran 2e-5 2e-3 +* +v1 1 0 0.0 sin(0 1 1k 0 0 45.0) +r1 1 0 1k +* +v2 2 0 0.0 pulse(-1 1 0 1e-5 1e-5 5e-4 1e-3 45.0) +r2 2 0 1k +* +.end diff --git a/src/xspice/examples/bad_io.deck b/src/xspice/examples/bad_io.deck new file mode 100755 index 000000000..74678115c --- /dev/null +++ b/src/xspice/examples/bad_io.deck @@ -0,0 +1,17 @@ +Invalid number of inputs/outputs +* +* This circuit contains a simple gain block to demonstrate +* that the simulator reports an error if the number of +* connections on the code model is incorrect. +* +.tran 1e-5 1e-3 +* +v1 1 0 0.0 sin(0 1 1k) +r1 1 0 1k +* +a1 1 2 3 gain_block +a2 1 gain_block +.model gain_block gain (gain=10) +r2 2 0 1k +* +.end diff --git a/src/xspice/examples/bad_io_type.deck b/src/xspice/examples/bad_io_type.deck new file mode 100755 index 000000000..41e64ad59 --- /dev/null +++ b/src/xspice/examples/bad_io_type.deck @@ -0,0 +1,25 @@ +Invalid input/output type +* +* This circuit contains a simple gain block to demonstrate +* that the simulator reports an error if an invalid type +* is used with the code model connections. +* +.tran 1e-5 1e-3 +* +v1 1 0 0.0 sin(0 1 1k) +r1 1 0 1k +* +* Both connections on the gain block must be analog, but +* the second is specified as digital +* +a1 1 %d 2 gain_block +.model gain_block gain (gain=10) +r2 2 0 1k +* +* Node 1 below should be a digital node, but is an analog node +* +a2 [1] [3] dac +.model dac dac_bridge +r3 3 0 1k +* +.end diff --git a/src/xspice/examples/bad_name.deck b/src/xspice/examples/bad_name.deck new file mode 100755 index 000000000..0380cac2e --- /dev/null +++ b/src/xspice/examples/bad_name.deck @@ -0,0 +1,16 @@ +Unknown code model name +* +* This circuit contains a simple gain block to demonstrate +* that the simulator reports an error if the code model name +* is incorrect. +* +.tran 1e-5 1e-3 +* +v1 1 0 0.0 sin(0 1 1k) +r1 1 0 1k +* +a1 1 2 gain_block +.model gain_block this_model_doesnt_exist (gain=10) +r2 2 0 1k +* +.end diff --git a/src/xspice/examples/bad_param.deck b/src/xspice/examples/bad_param.deck new file mode 100755 index 000000000..22a2aa2f0 --- /dev/null +++ b/src/xspice/examples/bad_param.deck @@ -0,0 +1,16 @@ +Unknown code model parameter +* +* This circuit contains a simple gain block to demonstrate +* that the simulator reports an error if the .model card +* references a parameter that doesn't exist +* +.tran 1e-5 1e-3 +* +v1 1 0 0.0 sin(0 1 1k) +r1 1 0 1k +* +a1 1 2 gain_block +.model gain_block gain (this_parameter_doesnt_exist=2 gain=10) +r2 2 0 1k +* +.end diff --git a/src/xspice/examples/bad_param_type.deck b/src/xspice/examples/bad_param_type.deck new file mode 100755 index 000000000..f110feda5 --- /dev/null +++ b/src/xspice/examples/bad_param_type.deck @@ -0,0 +1,16 @@ +Invalid parameter type +* +* This circuit contains a simple gain block to demonstrate +* that the simulator reports an error if the parameter value +* is invalid. +* +.tran 1e-5 1e-3 +* +v1 1 0 0.0 sin(0 1 1k) +r1 1 0 1k +* +a1 1 2 gain_block +.model gain_block gain (gain=false) +r2 2 0 1k +* +.end diff --git a/src/xspice/examples/d_to_real/Makefile b/src/xspice/examples/d_to_real/Makefile new file mode 100755 index 000000000..d2d2af97e --- /dev/null +++ b/src/xspice/examples/d_to_real/Makefile @@ -0,0 +1,40 @@ +# $Id$ +# +# Makefile for Code Model directories +# + +# Include global XSPICE selections for CC and other macros +include /usr/local/xspice-1-0/include/make.include + +INCLUDE = -I. -I$(ROOT)/include/sim + +CFLAGS = -g + +#----------------------------------------------------------------------------- +# Edit the following definition to specify the object files that comprise +# your code model. If your code model is completely specified in the +# cfunc.mod file, there is no need to edit this definition. +# DO NOT include the ifspec.o file. + +CODE_MODEL_OBJECTS = cfunc.o + +#----------------------------------------------------------------------------- +# DO NOT MODIFY THE FOLLOWING DEFINITIONS: + +.SUFFIXES: $(SUFFIXES) .mod .ifs + +.mod.c: + $(BINDIR)/cmpp -mod $< + +.ifs.c: + $(BINDIR)/cmpp -ifs + +.c.o: $*.c + ${CC} ${CFLAGS} ${INCLUDE} -c $*.c + +all : ifspec.o $(CODE_MODEL_OBJECTS) + +cfunc.o : cfunc.c +ifspec.o : ifspec.c + + diff --git a/src/xspice/examples/d_to_real/cfunc.mod b/src/xspice/examples/d_to_real/cfunc.mod new file mode 100755 index 000000000..079fc78ca --- /dev/null +++ b/src/xspice/examples/d_to_real/cfunc.mod @@ -0,0 +1,43 @@ +/* $Id$ */ + +void ucm_d_to_real (ARGS) +{ + + Digital_State_t in; + + double *out; + double delay; + double zero; + double one; + double ena; + + + in = INPUT_STATE(in); + if(PORT_NULL(enable)) + ena = 1.0; + else if(INPUT_STATE(enable) == ONE) + ena = 1.0; + else + ena = 0.0; + out = OUTPUT(out); + + zero = PARAM(zero); + one = PARAM(one); + delay = PARAM(delay); + + + if(in == ZERO) + *out = zero * ena; + else if(in == UNKNOWN) + *out = (zero + one) / 2.0 * ena; + else + *out = one * ena; + + if(TIME > 0.0) + OUTPUT_DELAY(out) = delay; + +} + + + + diff --git a/src/xspice/examples/d_to_real/ifspec.ifs b/src/xspice/examples/d_to_real/ifspec.ifs new file mode 100755 index 000000000..eb2300c82 --- /dev/null +++ b/src/xspice/examples/d_to_real/ifspec.ifs @@ -0,0 +1,32 @@ +/* $Id$ */ + +NAME_TABLE: + +Spice_Model_Name: d_to_real +C_Function_Name: ucm_d_to_real +Description: "Node bridge from digital to real with enable" + + +PORT_TABLE: + +Port_Name: in enable out +Description: "input" "enable" "output" +Direction: in in out +Default_Type: d d real +Allowed_Types: [d] [d] [real] +Vector: no no no +Vector_Bounds: - - - +Null_Allowed: no yes no + + +PARAMETER_TABLE: + +Parameter_Name: zero one delay +Description: "value for 0" "value for 1" "delay" +Data_Type: real real real +Default_Value: 0.0 1.0 1e-9 +Limits: - - [1e-15 -] +Vector: no no no +Vector_Bounds: - - - +Null_Allowed: yes yes yes + diff --git a/src/xspice/examples/diffpair.in b/src/xspice/examples/diffpair.in new file mode 100755 index 000000000..da321ce89 --- /dev/null +++ b/src/xspice/examples/diffpair.in @@ -0,0 +1,28 @@ +difpair ckt - simple differential pair +*.width in=72 +.opt acct list node lvlcod=2 +*.tf v(5) vin +*.dc vin -0.25 0.25 0.005 +*.ac dec 10 1 10ghz +.tran 5ns 500ns +vin 1 0 sin(0 0.1 5meg) ac 1 +vcc 8 0 12 +vee 9 0 -12 +q1 4 2 6 qnl +q2 5 3 6 qnl +rs1 1 2 1k +rs2 3 0 1k +rc1 4 8 10k +rc2 5 8 10k +q3 6 7 9 qnl +q4 7 7 9 qnl +rbias 7 8 20k +.model qnl npn(bf=80 rb=100 ccs=2pf tf=0.3ns tr=6ns cje=3pf cjc=2pf ++ va=50) +.print dc v(4) v(5) +.plot dc v(5) +.print ac vm(5) vp(5) +.plot ac vm(5) vp(5) +.print tran v(4) v(5) +.plot tran v(5) +.end diff --git a/src/xspice/examples/digital_invert.deck b/src/xspice/examples/digital_invert.deck new file mode 100755 index 000000000..08d7f6e91 --- /dev/null +++ b/src/xspice/examples/digital_invert.deck @@ -0,0 +1,23 @@ +Digital inversions +* +.tran 1e-8 1e-6 +* +v1 1 0 0.0 pulse(0 1 0 1e-8 1e-8 0.25e-6 0.5e-6) +r1 1 0 1k +* +a1 [1] [2] adc +.model adc adc_bridge +* +a2 2 3 inv +a3 2 ~4 inv +a4 ~2 5 inv +a5 ~2 ~6 inv +.model inv d_inverter +* +a6 [2 ~4] 7 nand +.model nand d_nand +* +a8 [2 3 4 5 6 7] [12 13 14 15 16 17] dac +.model dac dac_bridge +* +.end diff --git a/src/xspice/examples/digital_models.deck b/src/xspice/examples/digital_models.deck new file mode 100755 index 000000000..39f737278 --- /dev/null +++ b/src/xspice/examples/digital_models.deck @@ -0,0 +1,20 @@ +Digital models +* +* This circuit contains a nand gate oscillator enabled by +* a pulse input after 20nS. Node 1 is an analog node. +* Nodes 2 and 3 are digital nodes. +* +.tran 1e-8 1e-7 +* +v1 1 0 0.0 pulse(0 1 2e-8 1e-9 1e-9) +* +r1 1 0 1k +* +a1 [1] [2] atod1 +.model atod1 adc_bridge (in_low=0.25 in_high=0.75 ++ rise_delay=1e-9 fall_delay=1e-9) +* +a2 [2 3] 3 nand +.model nand d_nand (rise_delay=1e-9 fall_delay=1e-9) +* +.end diff --git a/src/xspice/examples/digital_models1.deck b/src/xspice/examples/digital_models1.deck new file mode 100755 index 000000000..c78fa45ad --- /dev/null +++ b/src/xspice/examples/digital_models1.deck @@ -0,0 +1,77 @@ +Code Model Test: buffer, inverter, and, nand, or, nor, xor, xnor +* +* +*** analysis type *** +.tran .01s 4s +* +*** input sources *** +* +v2 200 0 DC PWL( (0 0.0) (2 0.0) (2.0000000001 1.0) (3 1.0) ) +* +v1 100 0 DC PWL( (0 0.0) (1.0 0.0) (1.0000000001 1.0) (2 1.0) ++ (2.0000000001 0.0) (3 0.0) (3.0000000001 1.0) (4 1.0) ) +* +* +*** adc_bridge blocks *** +aconverter [200 100] [2 1] adc_bridge1 +.model adc_bridge1 adc_bridge (in_low=0.1 in_high=0.9 ++ rise_delay=1.0e-12 fall_delay=1.0e-12) +* +* +* +*** buffer block *** +a1 1 10 d_buffer1 +.model d_buffer1 d_buffer (rise_delay=1.0e-6 fall_delay=2.0e-6 ++ input_load=1.0e-12) +* +* +*** inverter block *** +a2 1 20 d_inv1 +.model d_inv1 d_inverter (rise_delay=1.0e-6 fall_delay=2.0e-6 ++ input_load=1.0e-12) +* +* +*** and block *** +a3 [1 2] 30 d_and1 +.model d_and1 d_and (rise_delay=1.0e-6 fall_delay=2.0e-6 ++ input_load=1.0e-12) +* +* +*** nand block *** +a4 [1 2] 40 d_nand1 +.model d_nand1 d_nand (rise_delay=1.0e-6 fall_delay=2.0e-6 ++ input_load=1.0e-12) +* +* +*** or block *** +a5 [1 2] 50 d_or1 +.model d_or1 d_or (rise_delay=1.0e-6 fall_delay=2.0e-6 ++ input_load=1.0e-12) +* +* +*** nor block *** +a6 [1 2] 60 d_nor1 +.model d_nor1 d_nor (rise_delay=1.0e-6 fall_delay=2.0e-6 ++ input_load=1.0e-12) +* +* +*** xor block *** +a7 [1 2] 70 d_xor1 +.model d_xor1 d_xor (rise_delay=1.0e-6 fall_delay=2.0e-6 ++ input_load=1.0e-12) +* +* +*** xnor block *** +a8 [1 2] 80 d_xnor1 +.model d_xnor1 d_xnor (rise_delay=1.0e-6 fall_delay=2.0e-6 ++ input_load=1.0e-12) +* +* +* +*** resistors to ground *** +r1 100 0 1k +r2 200 0 1k +* +* +* +.end diff --git a/src/xspice/examples/digital_models2.deck b/src/xspice/examples/digital_models2.deck new file mode 100755 index 000000000..9f6244073 --- /dev/null +++ b/src/xspice/examples/digital_models2.deck @@ -0,0 +1,91 @@ +Code Model Test: d flip-flop, jk flip-flop, toggle ff, set-reset ff +* +* +*** analysis type *** +.tran .01s 4s +* +*** input sources *** +* +vdata1 100 0 DC PWL( (0 0.0) (2 0.0) (2.0000000001 1.0) (3 1.0) ) +* +* +vdata2 200 0 DC PWL( (0 0.0) (1.0 0.0) (1.0000000001 1.0) (2 1.0) ++ (2.0000000001 0.0) (3 0.0) (3.0000000001 1.0) (4 1.0) ) +* +* +vclk 300 0 DC PWL( (0 0.0) (0.5 0.0) (0.50000000001 1.0) ++ (1.0 1.0) (1.00000000001 0.0) ++ (1.5 0.0) (1.50000000001 1.0) ++ (2.0 1.0) (2.00000000001 0.0) ++ (2.5 0.0) (2.50000000001 1.0) ++ (3.0 1.0) (3.00000000001 0.0) ++ (3.5 0.0) (3.50000000001 1.0) (4.0 1.0) ) +* +* +vset 400 0 DC 0.0 +* +* +vreset 500 0 DC PWL( (0 0.0) (3.8 0.0) (3.80000000001 1.0) (4 1.0) ) +* +* +*** adc_bridge blocks *** +aconverter [100 200 300 400 500] [1 2 3 4 5] adc_bridge1 +.model adc_bridge1 adc_bridge (in_low=0.1 in_high=0.9 ++ rise_delay=1.0e-12 fall_delay=1.0e-12) +* +* +* +*** d flip-flop block *** +a1 1 3 4 5 10 11 d_dff1 +.model d_dff1 d_dff (clk_delay=1.0e-6 set_delay=2.0e-6 ++ reset_delay=3.0e-6 ic=0 ++ rise_delay=4.0e-6 fall_delay=5.0e-6 ++ data_load=1.0e-12 clk_load=1.0e-12 ++ set_load=1.0e-12 reset_load=1.0e-12) +* +* +*** jk flip-flop block *** +a2 1 2 3 4 5 20 21 d_jkff1 +.model d_jkff1 d_jkff (clk_delay=1.0e-6 set_delay=2.0e-6 ++ reset_delay=3.0e-6 ic=0 ++ rise_delay=4.0e-6 fall_delay=5.0e-6 ++ jk_load=1.0e-12 clk_load=1.0e-12 ++ set_load=1.0e-12 reset_load=1.0e-12) +* +* +*** toggle flip-flop block *** +a3 1 3 4 5 30 31 d_tff1 +.model d_tff1 d_tff (clk_delay=1.0e-6 set_delay=2.0e-6 ++ reset_delay=3.0e-6 ic=0 ++ rise_delay=4.0e-6 fall_delay=5.0e-6 ++ t_load=1.0e-12 clk_load=1.0e-12 ++ set_load=1.0e-12 reset_load=1.0e-12) +* +* +*** set-reset flip-flop block *** +a4 1 2 3 4 5 40 41 d_srff1 +.model d_srff1 d_srff (clk_delay=1.0e-6 set_delay=2.0e-6 ++ reset_delay=3.0e-6 ic=0 ++ rise_delay=4.0e-6 fall_delay=5.0e-6 ++ sr_load=1.0e-12 clk_load=1.0e-12 ++ set_load=1.0e-12 reset_load=1.0e-12) +* +* +* +* +*** resistors to ground *** +r1 100 0 1k +r2 200 0 1k +r3 300 0 1k +r4 400 0 1k +r5 500 0 1k +* +* +* +.end + + + + + + diff --git a/src/xspice/examples/digital_models3.deck b/src/xspice/examples/digital_models3.deck new file mode 100755 index 000000000..b9173ece7 --- /dev/null +++ b/src/xspice/examples/digital_models3.deck @@ -0,0 +1,92 @@ +Code Model Test: d latch, set-reset latch, frequency divider +* +* +*** analysis type *** +.tran .01s 8s +* +*** input sources *** +* +vdata1 100 0 DC PWL( (0 0.0) (2 0.0) (2.0000000001 1.0) (3 1.0) ) +* +* +vdata2 200 0 DC PWL( (0 0.0) (1.0 0.0) (1.0000000001 1.0) (2 1.0) ++ (2.0000000001 0.0) (3 0.0) (3.0000000001 1.0) (4 1.0) ) +* +* +vclk 300 0 DC PWL( (0 0.0) (0.5 0.0) (0.50000000001 1.0) ++ (1.0 1.0) (1.00000000001 0.0) ++ (1.5 0.0) (1.50000000001 1.0) ++ (2.0 1.0) (2.00000000001 0.0) ++ (2.5 0.0) (2.50000000001 1.0) ++ (3.0 1.0) (3.00000000001 0.0) ++ (3.5 0.0) (3.50000000001 1.0) ++ (4.0 1.0) (4.00000000001 0.0) ++ (4.5 0.0) (4.50000000001 1.0) ++ (5.0 1.0) (5.00000000001 0.0) ++ (5.5 0.0) (5.50000000001 1.0) ++ (6.0 1.0) (6.00000000001 0.0) ++ (6.5 0.0) (6.50000000001 1.0) ++ (7.0 1.0) (7.00000000001 0.0) ++ (7.5 0.0) (7.50000000001 1.0) (4.0 1.0) ) +* +* +vset 400 0 DC 0.0 +* +* +vreset 500 0 DC PWL( (0 0.0) (3.8 0.0) (3.80000000001 1.0) (4 1.0) ) +* +* +*** adc_bridge block *** +aconverter [100 200 300 400 500] [1 2 3 4 5] adc_bridge1 +.model adc_bridge1 adc_bridge (in_low=0.1 in_high=0.9 ++ rise_delay=1.0e-12 fall_delay=1.0e-12) +* +* +* +*** d latch block *** +a1 1 3 4 5 10 11 d_dlatch1 +.model d_dlatch1 d_dlatch (data_delay=1.0e-6 enable_delay=2.0e-6 ++ set_delay=3.0e-6 reset_delay=4.0e-6 ++ ic=0 ++ rise_delay=5.0e-6 fall_delay=6.0e-6 ++ data_load=1.0e-12 enable_load=1.0e-12 ++ set_load=1.0e-12 reset_load=1.0e-12) +* +* +*** set-reset latch block *** +a2 1 2 3 4 5 20 21 d_srlatch1 +.model d_srlatch1 d_srlatch (sr_delay=1.0e-6 enable_delay=2.0e-6 ++ set_delay=3.0e-6 reset_delay=4.0e-6 ++ ic=0 ++ rise_delay=5.0e-6 fall_delay=6.0e-6 ++ sr_load=1.0e-12 enable_load=1.0e-12 ++ set_load=1.0e-12 reset_load=1.0e-12) +* +* +*** frequency divider block *** +a3 3 30 d_fdiv1 +.model d_fdiv1 d_fdiv (div_factor=3 high_cycles=2 ++ i_count=0 rise_delay=1.0e-6 fall_delay=2.0e-6 ++ freq_in_load=1.0e-12) +* +* +* +* +* +* +*** resistors to ground *** +r1 100 0 1k +r2 200 0 1k +r3 300 0 1k +r4 400 0 1k +r5 500 0 1k +* +* +* +.end + + + + + + diff --git a/src/xspice/examples/digital_models4.deck b/src/xspice/examples/digital_models4.deck new file mode 100755 index 000000000..8a328c922 --- /dev/null +++ b/src/xspice/examples/digital_models4.deck @@ -0,0 +1,91 @@ +Code Model Test: State Machine, RAM +* +* +*** analysis type *** +.tran .01s 8s +* +*** input sources *** +* +vdata1 100 0 DC PWL( (0 0.0) (2 0.0) (2.0000000001 1.0) (3 1.0) ++ (3.5000000001 0.0) (4 0.0) ) +* +* +vdata2 200 0 DC PWL( (0 0.0) (1.0 0.0) (1.0000000001 1.0) (2 1.0) ++ (2.0000000001 0.0) (3 0.0) (3.0000000001 1.0) (4 1.0) ) +* +* +vclk 300 0 DC PWL( (0 0.0) (0.5 0.0) (0.50000000001 1.0) ++ (1.0 1.0) (1.00000000001 0.0) ++ (1.5 0.0) (1.50000000001 1.0) ++ (2.0 1.0) (2.00000000001 0.0) ++ (2.5 0.0) (2.50000000001 1.0) ++ (3.0 1.0) (3.00000000001 0.0) ++ (3.5 0.0) (3.50000000001 1.0) ++ (4.0 1.0) (4.00000000001 0.0) ++ (4.5 0.0) (4.50000000001 1.0) ++ (5.0 1.0) (5.00000000001 0.0) ++ (5.5 0.0) (5.50000000001 1.0) ++ (6.0 1.0) (6.00000000001 0.0) ++ (6.5 0.0) (6.50000000001 1.0) ++ (7.0 1.0) (7.00000000001 0.0) ++ (7.5 0.0) (7.50000000001 1.0) (4.0 1.0) ) +* +vaddr1 400 0 DC 0 +* +* +vaddr2 500 0 DC PWL( (0 0.0) (0.6 0.0) (0.60000000001 1.0) ++ (0.9 1.0) (0.90000000001 0.0) ++ (2.6 0.0) (2.60000000001 1.0) ++ (2.9 1.0) (2.90000000001 0.0) (3.0 0.0) ) +* +* +* +vselect 600 0 DC PWL( (0 0.0) (1.0 0.0) (2.0000000001 1.0) (2 1.0) ) +* +* +* +* +* +*** adc_bridge block *** +aconverter [100 200 300 400 500 600] [1 2 3 4 5 6] adc_bridge1 +.model adc_bridge1 adc_bridge (in_low=0.1 in_high=0.9 ++ rise_delay=1.0e-12 fall_delay=1.0e-12) +* +* +* +*** state machine block *** +a1 [1 2] 3 4 [10 11] d_state1 +.model d_state1 d_state (clk_delay=1.0e-6 reset_delay=2.0e-6 ++ state_file=state.txt reset_state=0 ++ input_load=1.0e-12 clk_load=1.0e-12 ++ reset_load=1.0e-12) +* +* +*** RAM block *** +a2 [1 2] [20 21] [3 4] 5 [6] d_ram1 +.model d_ram1 d_ram (select_value=1 ic=0 ++ read_delay=1.0e-6 data_load=1.0e-12 ++ address_load=1.0e-12 select_load=1.0e-12 ++ enable_load=1.0e-12) +* +* +* +* +* +*** resistors to ground *** +r1 100 0 10k +r2 200 0 10k +r3 300 0 10k +r4 400 0 10k +r5 500 0 10k +r6 600 0 10k +* +* +* +.end + + + + + + diff --git a/src/xspice/examples/dot_model_ref.deck b/src/xspice/examples/dot_model_ref.deck new file mode 100755 index 000000000..159d144f8 --- /dev/null +++ b/src/xspice/examples/dot_model_ref.deck @@ -0,0 +1,19 @@ +Model card reference +* +* This circuit contains simple gain blocks that share a +* single .model card. +* +.tran 1e-5 1e-3 +* +v1 1 0 0.0 sin(0 1 1k) +r1 1 0 1k +* +a1 1 2 gain_block +r2 2 0 1k +* +a2 1 3 gain_block +r3 3 0 1k +* +.model gain_block gain (in_offset = 1 gain=10) +* +.end diff --git a/src/xspice/examples/hybrid_models1_dc.deck b/src/xspice/examples/hybrid_models1_dc.deck new file mode 100755 index 000000000..190fb0be6 --- /dev/null +++ b/src/xspice/examples/hybrid_models1_dc.deck @@ -0,0 +1,46 @@ +Code Model Test - DC: d_osc, dac_bridge, adc_bridge +* +* +*** analysis type *** +.op +* +*** input sources *** +v1 1 0 DC 2 +* +v2 2 0 DC 2 +* +*** d_osc block *** +a1 1 10 d_osc1 +.model d_osc1 d_osc (cntl_array=[-1.0 0.0 1.0 2.0] ++ freq_array=[100 100 1000 1000] ++ duty_cycle=0.5 init_phase=0.0 ++ rise_delay=1.0e-6 fall_delay=2.0e-6) +* +*** dac_bridge block *** +a2 [10] [20] dac_bridge1 +.model dac_bridge1 dac_bridge (out_low=0.5 out_high=4.5 out_undef=1.8 ++ input_load=1.0e-12 ++ t_rise=1.0e-6 t_fall=2.0e-6) +* +* +*** adc_bridge block *** +a3 [2] [30] adc_bridge1 +.model adc_bridge1 adc_bridge (in_low=0.7 in_high=2.4 ++ rise_delay=1.0e-12 fall_delay=2.0e-12) +* +* +* +*** resistors to ground *** +r1 1 0 1k +r2 2 0 1k +* +r20 20 0 1k +* +* +.end + + + + + + diff --git a/src/xspice/examples/hybrid_models1_transient.deck b/src/xspice/examples/hybrid_models1_transient.deck new file mode 100755 index 000000000..e09b15ad4 --- /dev/null +++ b/src/xspice/examples/hybrid_models1_transient.deck @@ -0,0 +1,48 @@ +Code Model Test - Transient: d_osc, dac_bridge, adc_bridge +* +* +*** analysis type *** +.tran .01s 1s +* +*** input sources *** +* +v1 1 0 DC PWL( (0 0.0) (1 1.0) ) +* +v2 2 0 DC PWL( (0 0.0) (1 5.0) ) +* +* +*** d_osc block *** +a1 1 10 d_osc1 +.model d_osc1 d_osc (cntl_array=[-1.0 0.0 1.0 2.0] ++ freq_array=[1.0 1.0 8.0 8.0] ++ duty_cycle=0.5 init_phase=0.0 ++ rise_delay=1.0e-6 fall_delay=2.0e-6) +* +*** dac_bridge block *** +a2 [10] [20] dac_bridge1 +.model dac_bridge1 dac_bridge (out_low=0.5 out_high=4.5 out_undef=1.8 ++ input_load=1.0e-12 ++ t_rise=1.0e-6 t_fall=2.0e-6) +* +* +*** adc_bridge block *** +a3 [2] [30] adc_bridge1 +.model adc_bridge1 adc_bridge (in_low=0.7 in_high=2.4 ++ rise_delay=1.0e-12 fall_delay=2.0e-12) +* +* +* +*** resistors to ground *** +r1 1 0 1k +r2 2 0 1k +* +r20 20 0 1k +* +* +.end + + + + + + diff --git a/src/xspice/examples/initial_conditions.deck b/src/xspice/examples/initial_conditions.deck new file mode 100755 index 000000000..610383625 --- /dev/null +++ b/src/xspice/examples/initial_conditions.deck @@ -0,0 +1,19 @@ +Capacitor and inductor with natural initial conditions +* +* This circuit contains a capacitor and an inductor with +* initial conditions on them. Each of the components +* has a parallel resistor so that an exponential decay +* of the initial condition occurs with a time constant of +* 1 second. +* +.tran 0.1 5 +* +a1 1 0 cap +.model cap capacitor (c=1000uf ic=1) +r1 1 0 1k +* +a2 2 0 ind +.model ind inductor (l=1H ic=1) +r2 2 0 1.0 +* +.end diff --git a/src/xspice/examples/io_ordering.deck b/src/xspice/examples/io_ordering.deck new file mode 100755 index 000000000..8cc245526 --- /dev/null +++ b/src/xspice/examples/io_ordering.deck @@ -0,0 +1,17 @@ +IO ordering +* +* This circuit contains a simple gain block. The order of +* the nodes listed on the instance line follows the order +* of the connections defined in the 'ifspec.ifs' file for +* the model. Refer to /atesse-su/src/cml/gain/ifspec.ifs . +* +.tran 1e-5 1e-3 +* +v1 1 0 0.0 sin(0 1 1k) +r1 1 0 1k +* +a1 1 2 gain_block +.model gain_block gain (gain=10) +r2 2 0 1k +* +.end diff --git a/src/xspice/examples/io_types.deck b/src/xspice/examples/io_types.deck new file mode 100755 index 000000000..0d792ab73 --- /dev/null +++ b/src/xspice/examples/io_types.deck @@ -0,0 +1,34 @@ +IO types +* +* This circuit contains a mix of input output types including +* voltages, currents, digital signals, and user defined +* signals. +* +.tran 1e-6 1e-4 +* +v1 1 0 0.0 pulse(0 1 2e-5) +r1 1 0 1k +* +abridge1 [1] [enable] node_bridge1 +.model node_bridge1 adc_bridge +* +aclk [enable clk] clk nand +.model nand d_nand (rise_delay=1e-5 fall_delay=1e-5) +* +abridge2 clk enable real_node1 node_bridge2 +.model node_bridge2 d_to_real (zero=-1 one=1) +* +again real_node1 real_node2 times10 +.model times10 real_gain (gain=10) +* +abridge3 real_node2 analog_node node_bridge3 +.model node_bridge3 real_to_v +* +rout analog_node 0 1k +* +again %vnam v1 %i i_out gain_block +.model gain_block gain (gain=10) +ri_out i_out 0 1k +* +* +.end diff --git a/src/xspice/examples/long_names.deck b/src/xspice/examples/long_names.deck new file mode 100755 index 000000000..6a0fecada --- /dev/null +++ b/src/xspice/examples/long_names.deck @@ -0,0 +1,19 @@ +Long names +* +* This circuit contains a sine wave source followed by a +* gain block code model with a gain of 10. Long names +* are used for instances, models, and nodes. +* +.tran 1e-5 1e-3 +* +v1_123456789_123456789_1234 1 0 0.0 sin(0 1 2k) +* +r1_123456789_123456789_1234 1 0 1k +* +a1_123456789_123456789_1234 1 out_123456789_123456789_1234 ++ gain_block_123456789_123456789_1234 +* +.model gain_block_123456789_123456789_1234 gain (gain=10) +r2_123456789_123456789_1234 out_123456789_123456789_1234 0 1k +* +.end diff --git a/src/xspice/examples/mixed_case.deck b/src/xspice/examples/mixed_case.deck new file mode 100755 index 000000000..1a1006492 --- /dev/null +++ b/src/xspice/examples/mixed_case.deck @@ -0,0 +1,15 @@ +MiXeD CaSe +* +* This circuit contains a simple gain block to demonstrate +* that the simulator deck parsing code is case-insensitive. +* +.TrAn 1E-5 1e-3 +* +V1 1 0 0.0 sIn(0 1 1k) +r1 1 0 1k +* +A1 1 2 GaIn_BlOcK +.MODel gAiN_bLoCk GAin (gaIN=10) +r2 2 0 1K +* +.eNd diff --git a/src/xspice/examples/mixed_io_size.deck b/src/xspice/examples/mixed_io_size.deck new file mode 100755 index 000000000..824cdeb4b --- /dev/null +++ b/src/xspice/examples/mixed_io_size.deck @@ -0,0 +1,33 @@ +Mixed IO sizes +* +* This circuit contains a collection of digital and analog +* models with saclar and vector inputs of varying sizes. +* +.tran 1e-5 1e-3 +* +v1 1 0 0.0 pulse(0 1 1e-4) +r1 1 0 1k +* +v2 2 0 0.0 sin(0 1 2k) +r2 2 0 1k +* +abridge1 [1] [enable] atod +.model atod adc_bridge +* +aosc [enable clk] clk nand +.model nand d_nand (rise_delay=1e-4 fall_delay=1e-4) +* +ainv clk clk_bar inv +.model inv d_inverter (rise_delay=1e-5 fall_delay=1e-5) +* +adac [clk clk_bar] [3 4] dac +.model dac dac_bridge (t_rise=1e-5 t_fall=1e-5) +* +asum [1 2 3 4] 5 sum +.model sum summer +* +r3 3 0 1k +r4 4 0 1k +r5 5 0 1k +* +.end diff --git a/src/xspice/examples/mixed_mode.deck b/src/xspice/examples/mixed_mode.deck new file mode 100755 index 000000000..59e4745ba --- /dev/null +++ b/src/xspice/examples/mixed_mode.deck @@ -0,0 +1,98 @@ +Mixed IO types +* +* This circuit contains a mixture of IO types, including +* analog, digital, user-defined (real), and 'null'. +* +* The circuit demonstrates the use of the digital and +* user-defined node capability to model system-level designs +* such as sampled-data filters. The simulated circuit +* contains a digital oscillator enabled after 100us. The +* square wave oscillator output is divided by 8 with a +* ripple counter. The result is passed through a digital +* filter to convert it to a sine wave. +* +.tran 1e-5 1e-3 +* +v1 1 0 0.0 pulse(0 1 1e-4 1e-6) +r1 1 0 1k +* +abridge1 [1] [enable] atod +.model atod adc_bridge +* +aclk [enable clk] clk nand +.model nand d_nand (rise_delay=1e-5 fall_delay=1e-5) +* +adiv2 div2_out clk NULL NULL NULL div2_out dff +adiv4 div4_out div2_out NULL NULL NULL div4_out dff +adiv8 div8_out div4_out NULL NULL NULL div8_out dff +.model dff d_dff +* +abridge2 div8_out enable filt_in node_bridge2 +.model node_bridge2 d_to_real (zero=-1 one=1) +* +xfilter filt_in clk filt_out dig_filter +* +abridge3 filt_out a_out node_bridge3 +.model node_bridge3 real_to_v +* +rlpf1 a_out oa_minus 10k +* +xlpf 0 oa_minus lpf_out opamp +* +rlpf2 oa_minus lpf_out 10k +clpf lpf_out oa_minus 0.01uF +* +* +.subckt dig_filter filt_in clk filt_out +* +.model n0 real_gain (gain=1.0) +.model n1 real_gain (gain=2.0) +.model n2 real_gain (gain=1.0) +.model g1 real_gain (gain=0.125) +.model zm1 real_delay +.model d0a real_gain (gain=-0.75) +.model d1a real_gain (gain=0.5625) +.model d0b real_gain (gain=-0.3438) +.model d1b real_gain (gain=1.0) +* +an0a filt_in x0a n0 +an1a filt_in x1a n1 +an2a filt_in x2a n2 +* +az0a x0a clk x1a zm1 +az1a x1a clk x2a zm1 +* +ad0a x2a x0a d0a +ad1a x2a x1a d1a +* +az2a x2a filt1_out g1 +az3a filt1_out clk filt2_in zm1 +* +an0b filt2_in x0b n0 +an1b filt2_in x1b n1 +an2b filt2_in x2b n2 +* +az0b x0b clk x1b zm1 +az1b x1b clk x2b zm1 +* +ad0 x2b x0b d0b +ad1 x2b x1b d1b +* +az2b x2b clk filt_out zm1 +* +.ends dig_filter +* +* +.subckt opamp plus minus out +* +r1 plus minus 300k +a1 %vd (plus minus) outint lim +.model lim limit (out_lower_limit = -12 out_upper_limit = 12 ++ fraction = true limit_range = 0.2 gain=300e3) +r3 outint out 50.0 +r2 out 0 1e12 +* +.ends opamp +* +* +.end diff --git a/src/xspice/examples/mixed_ref.deck b/src/xspice/examples/mixed_ref.deck new file mode 100755 index 000000000..475e0f655 --- /dev/null +++ b/src/xspice/examples/mixed_ref.deck @@ -0,0 +1,41 @@ +Mixed references +* +* This circuit demonstrates the use of single-ended and +* differential inputs and outputs. +* +* Note that digital models reference a single node for +* their inputs and output (i.e. they are single-ended) +* +.tran 1e-5 1e-3 +* +v1 1 0 0.0 sin(0 1 5k) +v2 2 0 0.0 sin(0 1 1k) +* +r1 1 0 1k +r2 2 0 1k +* +* +a1 %v 1 %i 10 times10 +r10 10 0 1k +* +* +a2 %vd (1 2) %id(11 12) times10 +r11 11 0 1k +r12 12 0 1k +r11_12 11 12 1.0 +* +* +r3 2 3 1k +a3 %i 3 %v 13 times10 +r13 13 0 1k +* +a4 [1] [digital_node1] adc +.model adc adc_bridge +* +a5 digital_node1 digital_node2 inv +.model inv d_inverter +* +* +.model times10 gain (gain=10) +* +.end diff --git a/src/xspice/examples/mosamp2.in b/src/xspice/examples/mosamp2.in new file mode 100755 index 000000000..d8029ad77 --- /dev/null +++ b/src/xspice/examples/mosamp2.in @@ -0,0 +1,42 @@ +mosamp2 - mos amplifier - transient +.options acct abstol=10n vntol=10n +.tran 0.1us 10us +m1 15 15 1 32 m w=88.9u l=25.4u +m2 1 1 2 32 m w=12.7u l=266.7u +m3 2 2 30 32 m w=88.9u l=25.4u +m4 15 5 4 32 m w=12.7u l=106.7u +m5 4 4 30 32 m w=88.9u l=12.7u +m6 15 15 5 32 m w=44.5u l=25.4u +m7 5 20 8 32 m w=482.6u l=12.7u +m8 8 2 30 32 m w=88.9u l=25.4u +m9 15 15 6 32 m w=44.5u l=25.4u +m10 6 21 8 32 m w=482.6u l=12.7u +m11 15 6 7 32 m w=12.7u l=106.7u +m12 7 4 30 32 m w=88.9u l=12.7u +m13 15 10 9 32 m w=139.7u l=12.7u +m14 9 11 30 32 m w=139.7u l=12.7u +m15 15 15 12 32 m w=12.7u l=207.8u +m16 12 12 11 32 m w=54.1u l=12.7u +m17 11 11 30 32 m w=54.1u l=12.7u +m18 15 15 10 32 m w=12.7u l=45.2u +m19 10 12 13 32 m w=270.5u l=12.7u +m20 13 7 30 32 m w=270.5u l=12.7u +m21 15 10 14 32 m w=254u l=12.7u +m22 14 11 30 32 m w=241.3u l=12.7u +m23 15 20 16 32 m w=19u l=38.1u +m24 16 14 30 32 m w=406.4u l=12.7u +m25 15 15 20 32 m w=38.1u l=42.7u +m26 20 16 30 32 m w=381u l=25.4u +m27 20 15 66 32 m w=22.9u l=7.6u +cc 7 9 40pf +cl 66 0 70pf +vin 21 0 pulse(0 5 1ns 1ns 1ns 5us 10us) +vccp 15 0 dc +15 +vddn 30 0 dc -15 +vb 32 0 dc -20 +.model m nmos(nsub=2.2e15 uo=575 ucrit=49k uexp=0.1 tox=0.11u xj=2.95u ++ level=2 cgso=1.5n cgdo=1.5n cbd=4.5f cbs=4.5f ld=2.4485u nss=3.2e10 ++ kp=2e-5 phi=0.6 ) +.print tran v(20) v(66) +.plot tran v(20) v(66) +.end diff --git a/src/xspice/examples/mosmem.in b/src/xspice/examples/mosmem.in new file mode 100755 index 000000000..c2803445b --- /dev/null +++ b/src/xspice/examples/mosmem.in @@ -0,0 +1,27 @@ +mosmem - mos memory cell +.width in=72 +.opt abstol=1u +.opt acct list node +.tran 20ns 2us +vdd 9 0 dc 5 +vs 7 0 pulse(2 0 520ns 20ns 20ns 500ns 2000ns) +vw 1 0 pulse(0 2 20ns 20ns 500ns 200ns) +vwb 2 0 pulse(2 0 20ns 20ns 20ns 2000ns 2000ns) +m1 3 1 0 0 mod w=250u l=5u +m2 4 2 0 0 mod w=250u l=5u +m3 9 9 3 0 mod w=5u l=5u +m4 9 9 4 0 mod w=5u l=5u +m5 5 7 3 0 mod w=50u l=5u +m6 6 7 4 0 mod w=50u l=5u +m7 5 6 0 0 mod w=250u l=5u +m8 6 5 0 0 mod w=250u l=5u +m9 9 9 5 0 mod w=5u l=5u +m10 9 9 6 0 mod w=5u l=5u +m11 8 4 0 0 mod w=250u l=5u +m12 9 9 8 0 mod w=5u l=5u +.model mod nmos(vto=0.5 phi=0.7 kp=1.0e-6 gamma=1.83 lambda=0.115 ++ level=1 cgso=1u cgdo=1u cbd=50p cbs=50p) +.print dc v(5) v(6) +.plot dc v(6) +.plot tran v(6) v(5) v(7) v(1) v(2) +.end diff --git a/src/xspice/examples/nco/Makefile b/src/xspice/examples/nco/Makefile new file mode 100755 index 000000000..d2d2af97e --- /dev/null +++ b/src/xspice/examples/nco/Makefile @@ -0,0 +1,40 @@ +# $Id$ +# +# Makefile for Code Model directories +# + +# Include global XSPICE selections for CC and other macros +include /usr/local/xspice-1-0/include/make.include + +INCLUDE = -I. -I$(ROOT)/include/sim + +CFLAGS = -g + +#----------------------------------------------------------------------------- +# Edit the following definition to specify the object files that comprise +# your code model. If your code model is completely specified in the +# cfunc.mod file, there is no need to edit this definition. +# DO NOT include the ifspec.o file. + +CODE_MODEL_OBJECTS = cfunc.o + +#----------------------------------------------------------------------------- +# DO NOT MODIFY THE FOLLOWING DEFINITIONS: + +.SUFFIXES: $(SUFFIXES) .mod .ifs + +.mod.c: + $(BINDIR)/cmpp -mod $< + +.ifs.c: + $(BINDIR)/cmpp -ifs + +.c.o: $*.c + ${CC} ${CFLAGS} ${INCLUDE} -c $*.c + +all : ifspec.o $(CODE_MODEL_OBJECTS) + +cfunc.o : cfunc.c +ifspec.o : ifspec.c + + diff --git a/src/xspice/examples/nco/cfunc.mod b/src/xspice/examples/nco/cfunc.mod new file mode 100755 index 000000000..993248863 --- /dev/null +++ b/src/xspice/examples/nco/cfunc.mod @@ -0,0 +1,90 @@ +/* $Id$ */ + +void *malloc(unsigned); + +#define OUT_STATE 0 +#define NXT_TIME 1 +#define NUM_NOTES 128 + + +/* A numerically controlled oscillator. Output frequencies */ +/* are determined according to the MIDI note number at input */ + +void ucm_nco (ARGS) +{ + + double *freq; + + int *output_state; + double *next_time; + + int i; + int index; + int scale_factor; + + double half_period; + + + if(INIT) { + + /* Setup storage for the toggled output state */ + output_state = (int *) cm_event_alloc(OUT_STATE, sizeof(int)); + next_time = (double *) cm_event_alloc(NXT_TIME, sizeof(double)); + + /* Allocate storage for frequencies */ + STATIC_VAR(freq) = malloc(NUM_NOTES * sizeof(double)); + freq = STATIC_VAR(freq); + + /* Initialize the frequency array */ + for(i = 0; i < NUM_NOTES; i++) { + if(i == 0) + freq[0] = 8.17578 * PARAM(mult_factor); + else + freq[i] = freq[i-1] * 1.059463094; + } + } + else { + + /* Get old output state */ + output_state = (int *) cm_event_get_ptr(OUT_STATE, 0); + next_time = (double *) cm_event_get_ptr(NXT_TIME, 0); + } + + + /* Convert the input bits to an integer */ + index = 0; + scale_factor = 64; + for(i = 0; i < 7; i++) { + if(INPUT_STATE(in[i]) == ONE) + index += scale_factor; + scale_factor /= 2; + } + + /* Look up the frequency and compute half its period */ + freq = STATIC_VAR(freq); + half_period = 1.0 / freq[index]; + + + /* Queue up events and output the new state */ + if(TIME == 0.0) { + *next_time = half_period; + cm_event_queue(*next_time); + OUTPUT_STATE(out) = *output_state; + } + else { + if(TIME == *next_time) { + *next_time = TIME + half_period; + cm_event_queue(*next_time); + *output_state = 1 - *output_state; + OUTPUT_STATE(out) = *output_state; + OUTPUT_DELAY(out) = PARAM(delay); + } + else + OUTPUT_CHANGED(out) = FALSE; + } + +} + + + + diff --git a/src/xspice/examples/nco/ifspec.ifs b/src/xspice/examples/nco/ifspec.ifs new file mode 100755 index 000000000..30cdba5d7 --- /dev/null +++ b/src/xspice/examples/nco/ifspec.ifs @@ -0,0 +1,38 @@ +/* $Id$ */ + +NAME_TABLE: + +Spice_Model_Name: nco +C_Function_Name: ucm_nco +Description: "A simple MIDI numerically controlled oscillator" + + +PORT_TABLE: + +Port_Name: in out +Description: "program input" "oscillator output" +Direction: in out +Default_Type: d d +Allowed_Types: [d] [d] +Vector: yes no +Vector_Bounds: [7 7] - +Null_Allowed: no no + + +PARAMETER_TABLE: + +Parameter_Name: delay mult_factor +Description: "output delay" "freq multiplier" +Data_Type: real real +Default_Value: 1e-9 1 +Limits: [1e-15 -] [1e-9 -] +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes + + +STATIC_VAR_TABLE: + +Static_Var_Name: freq +Data_Type: pointer +Description: "frequencies of notes" diff --git a/src/xspice/examples/param_defaults.deck b/src/xspice/examples/param_defaults.deck new file mode 100755 index 000000000..75e3542be --- /dev/null +++ b/src/xspice/examples/param_defaults.deck @@ -0,0 +1,16 @@ +Parameter defaults +* +* This circuit contains a code model with +* parameters of various types, which are all defaulted, +* and prints the default values. +* +.op +* +r1 1 0 1k +r2 2 0 1k +r3 1 2 1k +* +a1 [1 2] mod +.model mod print_param_types +* +.end diff --git a/src/xspice/examples/param_types.deck b/src/xspice/examples/param_types.deck new file mode 100755 index 000000000..84a43ef9e --- /dev/null +++ b/src/xspice/examples/param_types.deck @@ -0,0 +1,23 @@ +Parameter types +* +* This circuit contains a code model which accepts several +* parameters of various types and prints them. +* +.op +* +r1 1 0 1k +r2 2 0 1k +r3 1 2 1k +* +a1 [1 2] mod +.model mod print_param_types ++ integer=2 ++ real=3.0 ++ complex=<4.0 5.0> ++ string=six ++ integer_array=[7 8] ++ real_array=[9.0 10.0] ++ complex_array=[< 11.0 12.0 > < 13.0 14.0 >] ++ string_array=[fifteen sixteen] +* +.end diff --git a/src/xspice/examples/parsing.deck b/src/xspice/examples/parsing.deck new file mode 100755 index 000000000..b5de5f594 --- /dev/null +++ b/src/xspice/examples/parsing.deck @@ -0,0 +1,16 @@ +Parsing +* +* This circuit contains a simple gain block to demonstrate +* that the simulator parses the syntax used to reference +* code models. +* +.tran 1e-5 1e-3 +* +v1 1 0 0.0 sin(0 1 1k) +r1 1 0 1k +* +a1 1 2 gain_block +.model gain_block gain (gain=10) +r2 2 0 1k +* +.end diff --git a/src/xspice/examples/polarity.deck b/src/xspice/examples/polarity.deck new file mode 100755 index 000000000..7488e182a --- /dev/null +++ b/src/xspice/examples/polarity.deck @@ -0,0 +1,26 @@ +Polarity of voltages and currents +* +* This circuit contains a set of gain blocks to evaluate +* the polarity of voltages and currents on code models +* +.tran 1e-5 1e-3 +* +v1 1 0 0.0 sin(0 1 1k) +* +r1 1 0 1k +* +* +a1 %v 1 %v 10 times10 +r10 10 0 1k +* +r1_2 1 2 1k +a2 %i 2 %v 11 times10 +r11 11 0 1k +* +a3 1 %i 12 times10 +r12 12 0 1k +* +* +.model times10 gain (gain=10) +* +.end diff --git a/src/xspice/examples/print_param_types/Makefile b/src/xspice/examples/print_param_types/Makefile new file mode 100755 index 000000000..d2d2af97e --- /dev/null +++ b/src/xspice/examples/print_param_types/Makefile @@ -0,0 +1,40 @@ +# $Id$ +# +# Makefile for Code Model directories +# + +# Include global XSPICE selections for CC and other macros +include /usr/local/xspice-1-0/include/make.include + +INCLUDE = -I. -I$(ROOT)/include/sim + +CFLAGS = -g + +#----------------------------------------------------------------------------- +# Edit the following definition to specify the object files that comprise +# your code model. If your code model is completely specified in the +# cfunc.mod file, there is no need to edit this definition. +# DO NOT include the ifspec.o file. + +CODE_MODEL_OBJECTS = cfunc.o + +#----------------------------------------------------------------------------- +# DO NOT MODIFY THE FOLLOWING DEFINITIONS: + +.SUFFIXES: $(SUFFIXES) .mod .ifs + +.mod.c: + $(BINDIR)/cmpp -mod $< + +.ifs.c: + $(BINDIR)/cmpp -ifs + +.c.o: $*.c + ${CC} ${CFLAGS} ${INCLUDE} -c $*.c + +all : ifspec.o $(CODE_MODEL_OBJECTS) + +cfunc.o : cfunc.c +ifspec.o : ifspec.c + + diff --git a/src/xspice/examples/print_param_types/cfunc.mod b/src/xspice/examples/print_param_types/cfunc.mod new file mode 100755 index 000000000..8cf7d02ca --- /dev/null +++ b/src/xspice/examples/print_param_types/cfunc.mod @@ -0,0 +1,33 @@ +/* $Id$ */ + +void ucm_print_param_types (ARGS) +{ + int i; + + if(INIT) { + /* Print scalar parameters */ + printf("\nScalar parameters\n\n"); + printf("integer = %d\n", PARAM(integer)); + printf("real = %e\n", PARAM(real)); + printf("complex = <%e %e>\n", PARAM(complex).real, + PARAM(complex).imag); + printf("string = %s\n", PARAM(string)); + + /* Print vector parameters */ + printf("\nVector parameters\n\n"); + for(i = 0; i < PARAM_SIZE(integer_array); i++) + printf("integer = %d\n", PARAM(integer_array[i])); + for(i = 0; i < PARAM_SIZE(real_array); i++) + printf("real = %e\n", PARAM(real_array[i])); + for(i = 0; i < PARAM_SIZE(complex_array); i++) + printf("complex = <%e %e>\n", PARAM(complex_array[i]).real, + PARAM(complex_array[i]).imag); + for(i = 0; i < PARAM_SIZE(string_array); i++) + printf("string = %s\n", PARAM(string_array[i])); + + } +} + + + + diff --git a/src/xspice/examples/print_param_types/ifspec.ifs b/src/xspice/examples/print_param_types/ifspec.ifs new file mode 100755 index 000000000..e836df007 --- /dev/null +++ b/src/xspice/examples/print_param_types/ifspec.ifs @@ -0,0 +1,112 @@ +/* $Id$ */ + +NAME_TABLE: + +Spice_Model_Name: print_param_types +C_Function_Name: ucm_print_param_types +Description: "ignores its input, but prints its parameters" + + +PORT_TABLE: + + +Port_Name: in +Description: "input" +Direction: in +Default_Type: v +Allowed_Types: [v,vd,i,id,vnam] +Vector: yes +Vector_Bounds: - +Null_Allowed: no + + + +PARAMETER_TABLE: + +Parameter_Name: integer +Description: "integer parameter" +Data_Type: int +Default_Value: 1 +Limits: - +Vector: no +Vector_Bounds: - +Null_Allowed: yes + +PARAMETER_TABLE: + +Parameter_Name: real +Description: "real parameter" +Data_Type: real +Default_Value: 1 +Limits: - +Vector: no +Vector_Bounds: - +Null_Allowed: yes + +PARAMETER_TABLE: + +Parameter_Name: complex +Description: "complex parameter" +Data_Type: complex +Default_Value: <1.0, 1.0> +Limits: - +Vector: no +Vector_Bounds: - +Null_Allowed: yes + +PARAMETER_TABLE: + +Parameter_Name: string +Description: "string parameter" +Data_Type: string +Default_Value: "one" +Limits: - +Vector: no +Vector_Bounds: - +Null_Allowed: yes + +PARAMETER_TABLE: + +Parameter_Name: integer_array +Description: "integer array parameter" +Data_Type: int +Default_Value: 1 +Limits: - +Vector: yes +Vector_Bounds: in +Null_Allowed: yes + +PARAMETER_TABLE: + +Parameter_Name: real_array +Description: "real array parameter" +Data_Type: real +Default_Value: 1 +Limits: - +Vector: yes +Vector_Bounds: in +Null_Allowed: yes + +PARAMETER_TABLE: + +Parameter_Name: complex_array +Description: "complex array parameter" +Data_Type: complex +Default_Value: <1.0 1.0> +Limits: - +Vector: yes +Vector_Bounds: in +Null_Allowed: yes + +PARAMETER_TABLE: + +Parameter_Name: string_array +Description: "string array parameter" +Data_Type: string +Default_Value: "one" +Limits: - +Vector: yes +Vector_Bounds: in +Null_Allowed: yes + + diff --git a/src/xspice/examples/rca3040.in b/src/xspice/examples/rca3040.in new file mode 100755 index 000000000..6b6e52048 --- /dev/null +++ b/src/xspice/examples/rca3040.in @@ -0,0 +1,33 @@ +rca3040 ckt - rca 3040 wideband amplifier +.ac dec 10 1 10ghz +.dc vin -0.25 0.25 0.005 +.tran 2.0ns 200ns +vin 1 0 sin(0 0.1 50meg 0.5ns) ac 1 +vcc 2 0 15.0 +vee 3 0 -15.0 +rs1 30 1 1k +rs2 31 0 1k +r1 5 3 4.8k +r2 6 3 4.8k +r3 9 3 811 +r4 8 3 2.17k +r5 8 0 820 +r6 2 14 1.32k +r7 2 12 4.5k +r8 2 15 1.32k +r9 16 0 5.25k +r10 17 0 5.25k +q1 2 30 5 qnl +q2 2 31 6 qnl +q3 10 5 7 qnl +q4 11 6 7 qnl +q5 14 12 10 qnl +q6 15 12 11 qnl +q7 12 12 13 qnl +q8 13 13 0 qnl +q9 7 8 9 qnl +q10 2 15 16 qnl +q11 2 14 17 qnl +.model qnl npn bf=80 rb=100 ccs=2pf tf=0.3ns tr=6ns cje=3pf ++ cjc=2pf va 50 +.end diff --git a/src/xspice/examples/real_delay/Makefile b/src/xspice/examples/real_delay/Makefile new file mode 100755 index 000000000..d2d2af97e --- /dev/null +++ b/src/xspice/examples/real_delay/Makefile @@ -0,0 +1,40 @@ +# $Id$ +# +# Makefile for Code Model directories +# + +# Include global XSPICE selections for CC and other macros +include /usr/local/xspice-1-0/include/make.include + +INCLUDE = -I. -I$(ROOT)/include/sim + +CFLAGS = -g + +#----------------------------------------------------------------------------- +# Edit the following definition to specify the object files that comprise +# your code model. If your code model is completely specified in the +# cfunc.mod file, there is no need to edit this definition. +# DO NOT include the ifspec.o file. + +CODE_MODEL_OBJECTS = cfunc.o + +#----------------------------------------------------------------------------- +# DO NOT MODIFY THE FOLLOWING DEFINITIONS: + +.SUFFIXES: $(SUFFIXES) .mod .ifs + +.mod.c: + $(BINDIR)/cmpp -mod $< + +.ifs.c: + $(BINDIR)/cmpp -ifs + +.c.o: $*.c + ${CC} ${CFLAGS} ${INCLUDE} -c $*.c + +all : ifspec.o $(CODE_MODEL_OBJECTS) + +cfunc.o : cfunc.c +ifspec.o : ifspec.c + + diff --git a/src/xspice/examples/real_delay/cfunc.mod b/src/xspice/examples/real_delay/cfunc.mod new file mode 100755 index 000000000..5f3c41cbe --- /dev/null +++ b/src/xspice/examples/real_delay/cfunc.mod @@ -0,0 +1,46 @@ +/* $Id$ */ + + +#define CLK_STATE 0 + + +void ucm_real_delay (ARGS) +{ + + double *in; + double *out; + + Digital_State_t *state; + Digital_State_t *old_state; + + + if(INIT) { + state = (void *) cm_event_alloc(CLK_STATE, sizeof(Digital_State_t)); + old_state = state; + *state = INPUT_STATE(clk); + } + else { + state = (void *) cm_event_get_ptr(CLK_STATE, 0); + old_state = (void *) cm_event_get_ptr(CLK_STATE, 1); + } + + if(ANALYSIS != TRANSIENT) + OUTPUT_CHANGED(out) = FALSE; + else { + *state = INPUT_STATE(clk); + if(*state == *old_state) + OUTPUT_CHANGED(out) = FALSE; + else if(*state != ONE) + OUTPUT_CHANGED(out) = FALSE; + else { + in = INPUT(in); + out = OUTPUT(out); + *out = *in; + OUTPUT_DELAY(out) = PARAM(delay); + } + } +} + + + + diff --git a/src/xspice/examples/real_delay/ifspec.ifs b/src/xspice/examples/real_delay/ifspec.ifs new file mode 100755 index 000000000..603bbee27 --- /dev/null +++ b/src/xspice/examples/real_delay/ifspec.ifs @@ -0,0 +1,33 @@ +/* $Id$ */ + +NAME_TABLE: + +Spice_Model_Name: real_delay +C_Function_Name: ucm_real_delay +Description: "A Z ** -1 block working on real data" + + +PORT_TABLE: + +Port_Name: in clk out +Description: "input" "clock" "output" +Direction: in in out +Default_Type: real d real +Allowed_Types: [real] [d] [real] +Vector: no no no +Vector_Bounds: - - - +Null_Allowed: no no no + + +PARAMETER_TABLE: + +Parameter_Name: delay +Description: "delay from clk to out" +Data_Type: real +Default_Value: 1e-9 +Limits: [1e-15 -] +Vector: no +Vector_Bounds: - +Null_Allowed: yes + + diff --git a/src/xspice/examples/real_gain/Makefile b/src/xspice/examples/real_gain/Makefile new file mode 100755 index 000000000..d2d2af97e --- /dev/null +++ b/src/xspice/examples/real_gain/Makefile @@ -0,0 +1,40 @@ +# $Id$ +# +# Makefile for Code Model directories +# + +# Include global XSPICE selections for CC and other macros +include /usr/local/xspice-1-0/include/make.include + +INCLUDE = -I. -I$(ROOT)/include/sim + +CFLAGS = -g + +#----------------------------------------------------------------------------- +# Edit the following definition to specify the object files that comprise +# your code model. If your code model is completely specified in the +# cfunc.mod file, there is no need to edit this definition. +# DO NOT include the ifspec.o file. + +CODE_MODEL_OBJECTS = cfunc.o + +#----------------------------------------------------------------------------- +# DO NOT MODIFY THE FOLLOWING DEFINITIONS: + +.SUFFIXES: $(SUFFIXES) .mod .ifs + +.mod.c: + $(BINDIR)/cmpp -mod $< + +.ifs.c: + $(BINDIR)/cmpp -ifs + +.c.o: $*.c + ${CC} ${CFLAGS} ${INCLUDE} -c $*.c + +all : ifspec.o $(CODE_MODEL_OBJECTS) + +cfunc.o : cfunc.c +ifspec.o : ifspec.c + + diff --git a/src/xspice/examples/real_gain/cfunc.mod b/src/xspice/examples/real_gain/cfunc.mod new file mode 100755 index 000000000..f6934ccc3 --- /dev/null +++ b/src/xspice/examples/real_gain/cfunc.mod @@ -0,0 +1,39 @@ +/* $Id$ */ + +void ucm_real_gain (ARGS) +{ + double *in; + double *out; + + double in_offset; + double gain; + double out_offset; + double delay; + double ic; + + + /* Get the input and output pointers */ + in = INPUT(in); + out = OUTPUT(out); + + /* Get the parameters */ + in_offset = PARAM(in_offset); + gain = PARAM(gain); + out_offset = PARAM(out_offset); + delay = PARAM(delay); + ic = PARAM(ic); + + + /* Assign the output and delay */ + if(ANALYSIS == DC) { + *out = ic; + if(INIT) + cm_event_queue(delay); + } + else { + *out = gain * (*in + in_offset) + out_offset; + OUTPUT_DELAY(out) = delay; + } +} + + diff --git a/src/xspice/examples/real_gain/ifspec.ifs b/src/xspice/examples/real_gain/ifspec.ifs new file mode 100755 index 000000000..886acfdcb --- /dev/null +++ b/src/xspice/examples/real_gain/ifspec.ifs @@ -0,0 +1,45 @@ +/* $Id$ */ + +NAME_TABLE: + +Spice_Model_Name: real_gain +C_Function_Name: ucm_real_gain +Description: "A gain block for event-driven real data" + + +PORT_TABLE: + +Port_Name: in out +Description: "input" "output" +Direction: in out +Default_Type: real real +Allowed_Types: [real] [real] +Vector: no no +Vector_Bounds: - - +Null_Allowed: no no + + +PARAMETER_TABLE: + +Parameter_Name: in_offset gain out_offset +Description: "input offset" "gain" "output offset" +Data_Type: real real real +Default_Value: 0.0 1.0 0.0 +Limits: - - - +Vector: no no no +Vector_Bounds: - - - +Null_Allowed: yes yes yes + + +PARAMETER_TABLE: + +Parameter_Name: delay ic +Description: "delay" "initial condition" +Data_Type: real real +Default_Value: 1.0e-9 0.0 +Limits: - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes + + diff --git a/src/xspice/examples/real_to_v/Makefile b/src/xspice/examples/real_to_v/Makefile new file mode 100755 index 000000000..d2d2af97e --- /dev/null +++ b/src/xspice/examples/real_to_v/Makefile @@ -0,0 +1,40 @@ +# $Id$ +# +# Makefile for Code Model directories +# + +# Include global XSPICE selections for CC and other macros +include /usr/local/xspice-1-0/include/make.include + +INCLUDE = -I. -I$(ROOT)/include/sim + +CFLAGS = -g + +#----------------------------------------------------------------------------- +# Edit the following definition to specify the object files that comprise +# your code model. If your code model is completely specified in the +# cfunc.mod file, there is no need to edit this definition. +# DO NOT include the ifspec.o file. + +CODE_MODEL_OBJECTS = cfunc.o + +#----------------------------------------------------------------------------- +# DO NOT MODIFY THE FOLLOWING DEFINITIONS: + +.SUFFIXES: $(SUFFIXES) .mod .ifs + +.mod.c: + $(BINDIR)/cmpp -mod $< + +.ifs.c: + $(BINDIR)/cmpp -ifs + +.c.o: $*.c + ${CC} ${CFLAGS} ${INCLUDE} -c $*.c + +all : ifspec.o $(CODE_MODEL_OBJECTS) + +cfunc.o : cfunc.c +ifspec.o : ifspec.c + + diff --git a/src/xspice/examples/real_to_v/cfunc.mod b/src/xspice/examples/real_to_v/cfunc.mod new file mode 100755 index 000000000..f6b699391 --- /dev/null +++ b/src/xspice/examples/real_to_v/cfunc.mod @@ -0,0 +1,75 @@ +/* $Id$ */ + + +#define TS 0 +#define VS 1 + + +void ucm_real_to_v (ARGS) +{ + + double *t, *v; + double *in; + + double out; + + + in = INPUT(in); + + if(INIT) { + t = (void *) cm_event_alloc(TS, 2 * sizeof(double)); + v = (void *) cm_event_alloc(VS, 2 * sizeof(double)); + t[0] = -2.0; + t[1] = -1.0; + v[0] = *in; + v[1] = *in; + } + else { + t = (void *) cm_event_get_ptr(TS, 0); + v = (void *) cm_event_get_ptr(VS, 0); + } + + switch(CALL_TYPE) { + + case ANALOG: + if(TIME == 0.0) { + OUTPUT(out) = *in; + v[0] = *in; + v[1] = *in; + } + else { + if(TIME <= t[0]) + OUTPUT(out) = v[0]; + else if(TIME >= t[1]) + OUTPUT(out) = v[1]; + else { + OUTPUT(out) = v[0] + (v[1] - v[0]) * + (TIME - t[0]) / (t[1] - t[0]); + } + } + break; + + case EVENT: + if(TIME == 0.0) + return; + if(TIME >= t[1]) { + v[0] = v[1]; + v[1] = *in; + t[0] = TIME; + t[1] = TIME + PARAM(transition_time); + } + else { + v[0] = v[0] + (v[1] - v[0]) * + (TIME - t[0]) / (t[1] - t[0]); + v[1] = *in; + t[0] = TIME; + t[1] = TIME + PARAM(transition_time); + } + break; + + } +} + + + + diff --git a/src/xspice/examples/real_to_v/ifspec.ifs b/src/xspice/examples/real_to_v/ifspec.ifs new file mode 100755 index 000000000..9b06bf137 --- /dev/null +++ b/src/xspice/examples/real_to_v/ifspec.ifs @@ -0,0 +1,33 @@ +/* $Id$ */ + +NAME_TABLE: + +Spice_Model_Name: real_to_v +C_Function_Name: ucm_real_to_v +Description: "Node bridge from real to analog voltage" + + +PORT_TABLE: + +Port_Name: in out +Description: "input" "output" +Direction: in out +Default_Type: real v +Allowed_Types: [real] [v, vd, i, id] +Vector: no no +Vector_Bounds: - - +Null_Allowed: no no + + +PARAMETER_TABLE: + +Parameter_Name: gain transition_time +Description: "gain" "output transition time" +Data_Type: real real +Default_Value: 1.0 1e-9 +Limits: - [1e-15 -] +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes + + diff --git a/src/xspice/examples/rtlinv.in b/src/xspice/examples/rtlinv.in new file mode 100755 index 000000000..8632a17e8 --- /dev/null +++ b/src/xspice/examples/rtlinv.in @@ -0,0 +1,20 @@ +rtlinv ckt - cascaded rtl inverters +.width in=72 +.opt acct list node lvlcod=2 +.dc vin 0.0 2.5 0.025 +.tran 2ns 200ns +vcc 6 0 5 +vin 1 0 pulse(0 5 2ns 2ns 2ns 80ns) +rb1 1 2 10k +rc1 6 3 1k +q1 3 2 0 qnd +rb2 3 4 10k +q2 5 4 0 qnd +rc2 6 5 1k +.model qnd npn(bf=50 rb=70 rc=40 ccs=2pf tf=0.1ns tr=10ns cje=0.9pf ++ cjc=1.5pf pc=0.85 va=50) +.print dc v(3) v(5) +.plot dc v(3) +.print tran v(3) v(5) +.plot tran v(3) v(5) v(1) +.end diff --git a/src/xspice/examples/schmitt.in b/src/xspice/examples/schmitt.in new file mode 100755 index 000000000..6a7732027 --- /dev/null +++ b/src/xspice/examples/schmitt.in @@ -0,0 +1,24 @@ +schmitt ckt - ecl compatible schmitt trigger +.width in=72 +.opt acct list node lvlcod=2 +.tran 10ns 1000ns +vin 1 0 pulse(-1.6 -1.2 10ns 400ns 400ns 100ns 10000ns) +vee 8 0 -5 +rin 1 2 50 +rc1 0 3 50 +r1 3 5 185 +r2 5 8 760 +rc2 0 6 100 +re 4 8 260 +rth1 7 8 125 +rth2 7 0 85 +cload 7 0 5pf +q1 3 2 4 qstd off +q2 6 5 4 qstd +q3 0 6 7 qstd +q4 0 6 7 qstd +.model qstd npn(is=1.0e-16 bf=50 br=0.1 rb=50 rc=10 tf=0.12ns tr=5ns ++ cje=0.4pf pe=0.8 me=0.4 cjc=0.5pf pc=0.8 mc=0.333 ccs=1pf va=50) +.print tran v(1) v(3) v(5) v(6) +.plot tran v(3) v(5) v(6) v(1) +.end diff --git a/src/xspice/examples/spice3.deck b/src/xspice/examples/spice3.deck new file mode 100755 index 000000000..1055c69b8 --- /dev/null +++ b/src/xspice/examples/spice3.deck @@ -0,0 +1,25 @@ +A Berkeley SPICE3 compatible circuit +* +* This circuit contains only Berkeley SPICE3 components. +* +* The circuit is an AC coupled transistor amplifier with +* a sinewave input at node "1", a gain of approximately -3.9, +* and output on node "coll". +* +.tran 1e-5 2e-3 +* +vcc vcc 0 12.0 +vin 1 0 0.0 ac 1.0 sin(0 1 1k) +* +ccouple 1 base 10uF +* +rbias1 vcc base 100k +rbias2 base 0 24k +* +q1 coll base emit generic +.model generic npn +* +rcollector vcc coll 3.9k +remitter emit 0 1k +* +.end diff --git a/src/xspice/examples/suffixes.deck b/src/xspice/examples/suffixes.deck new file mode 100755 index 000000000..81b9bec75 --- /dev/null +++ b/src/xspice/examples/suffixes.deck @@ -0,0 +1,25 @@ +Engineering suffixes +* +* This circuit contains a code model which accepts several +* parameters of various types and prints them. The values +* specified on the .model card use engineering suffixes on +* the numeric parameters. +* +.op +* +r1 1 0 1k +r2 2 0 1k +r3 1 2 1k +* +a1 [1 2] mod +.model mod print_param_types ++ integer=2k ++ real=3.0u ++ complex=< 4.0f 5.0mil > ++ string=six ++ integer_array=[7meg 8] ++ real_array=[9.0n 10.0p] ++ complex_array=[< 11.0t 12.0g > < 13.0m 14.0 >] ++ string_array=[fifteen sixteen] +* +.end diff --git a/src/xspice/examples/supply_ramping.deck b/src/xspice/examples/supply_ramping.deck new file mode 100755 index 000000000..c2efd8050 --- /dev/null +++ b/src/xspice/examples/supply_ramping.deck @@ -0,0 +1,30 @@ +Supply ramping option +* +* This circuit demonstrates the use of the option +* "ramptime" which ramps independent sources and the +* capacitor and inductor initial conditions from +* zero to their final value during the time period +* specified. +* +* +.tran 0.1 5 +.option ramptime=0.2 +* +a1 1 0 cap +.model cap capacitor (c=1000uf ic=1) +r1 1 0 1k +* +a2 2 0 ind +.model ind inductor (l=1H ic=1) +r2 2 0 1.0 +* +v1 3 0 1.0 +r3 3 0 1k +* +i1 4 0 1e-3 +r4 4 0 1k +* +v2 5 0 0.0 sin(0 1 0.3 0 0 45.0) +r5 5 0 1k +* +.end diff --git a/src/xspice/examples/user_defined_nodes.deck b/src/xspice/examples/user_defined_nodes.deck new file mode 100755 index 000000000..9fb9ca1a4 --- /dev/null +++ b/src/xspice/examples/user_defined_nodes.deck @@ -0,0 +1,30 @@ +User defined nodes +* +* This circuit contains a mix of node types including +* two 'real' type user-defined nodes and associated +* node bridges. +* +.tran 1e-6 1e-4 +* +v1 1 0 0.0 pulse(0 1 2e-5) +r1 1 0 1k +* +abridge1 [1] [enable] node_bridge1 +.model node_bridge1 adc_bridge +* +aclk [enable clk] clk nand +.model nand d_nand (rise_delay=1e-5 fall_delay=1e-5) +* +abridge2 clk enable real_node1 node_bridge2 +.model node_bridge2 d_to_real (zero=-1 one=1) +* +again real_node1 real_node2 times10 +.model times10 real_gain (gain=10) +* +abridge3 real_node2 analog_node node_bridge3 +.model node_bridge3 real_to_v +* +rout analog_node 0 1k +* +* +.end diff --git a/src/xspice/examples/xspice.deck b/src/xspice/examples/xspice.deck new file mode 100755 index 000000000..121ef20b8 --- /dev/null +++ b/src/xspice/examples/xspice.deck @@ -0,0 +1,22 @@ +A simple XSPICE amplifier circuit +* +* This uses an XSPICE "gain" code model to substitute for +* the transistor amplifier circuit in spice3.deck. +* +.tran 1e-5 2e-3 +* +vin 1 0 0.0 ac 1.0 sin(0 1 1k) +* +ccouple 1 in 10uF +* +* +rzin in 0 19.35k +* +aamp in coll gain_block +.model gain_block gain (gain = -3.9 out_offset = 7.003) +* +rzout out coll 3.9k +rbig coll 0 1e12 +* +* +.end diff --git a/src/xspice/icm/Makefile.am b/src/xspice/icm/Makefile.am new file mode 100755 index 000000000..1d1ebc2f9 --- /dev/null +++ b/src/xspice/icm/Makefile.am @@ -0,0 +1,12 @@ +## Process this file with automake to produce Makefile.in +# +# JW 3/9/01 - had a go and makeing an autoconf script. + +noinst_LIBRARIES = libidnxsp.a + +libidnxsp_a_SOURCES = \ + idndig.c + +INCLUDES = -I$(top_srcdir)/src/include + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/xspice/icm/poly/Makefile.am b/src/xspice/icm/poly/Makefile.am new file mode 100755 index 000000000..2490dc745 --- /dev/null +++ b/src/xspice/icm/poly/Makefile.am @@ -0,0 +1,18 @@ +## Process this file with automake to produce Makefile.in +# +# JW 3/9/01 - had a go and makeing an autoconf script. + +noinst_LIBRARIES = libidnxsp.a + +libidnxsp_a_SOURCES = \ + ifspec.c \ + cfunc.c + +INCLUDES = -I$(top_srcdir)/src/include + +MAINTAINERCLEANFILES = Makefile.in + +ifspec.c: + cmpp -ifs +cfunc.c: + cmpp -mod cfunc.mod diff --git a/src/xspice/icm/poly/cfunc.c b/src/xspice/icm/poly/cfunc.c new file mode 100755 index 000000000..d0484d9da --- /dev/null +++ b/src/xspice/icm/poly/cfunc.c @@ -0,0 +1,305 @@ +#line 1 "cfunc.mod" +#include "cm.h" +#line 1 "cfunc.mod" +/* =========================================================================== +FILE cfunc.mod + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the definition of a code model polynomial controlled + source compatible with SPICE 2G6 poly sources. + +INTERFACES + + icm_poly() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + +/* + +This code model implements the non-linear polynomial controlled sources +available in SPICE 2G6. An automatic translator added into the simulator +front end is used to map 2G6 syntax into a call to this model in the +required syntax. + +This model may also be called directly as follows: + + a1 [ ] xxx + .model xxx poly ( coef = [ ] ) + +Refer to the 2G6 User Guide for an explanation of the coefficients. + + +This model is patterned after the FORTRAN code used in the 2G6 simulator. +Function cm_poly() below performs the functions of subroutines NLCSRC and +EVPOLY. Function evterm() performs the function of subroutine EVTERM, +and function nxtpwr() performs the function of subroutine NXTPWR. + +*/ + + + + +void *malloc(int); +void free(void *); + +/* SPICE 2G6 type utility functions */ +static double evterm(double x, int n); +static void nxtpwr(int *pwrseq, int pdim); + + + + +void icm_poly (Mif_Private_t *private) +{ + int num_inputs; /* Number of inputs to model */ + int num_coefs; /* Number of coefficients */ + int *exp; /* List of exponents in products */ + /* One for each input */ + + int i; /* Counter */ + int j; /* Counter */ + int k; /* Counter */ + + double *in; /* Values of inputs to model */ + double *coef; /* Values of coefficients */ + + double sum; /* Temporary for accumulating sum of terms */ + double product; /* Temporary for accumulating product */ + + double *acgains; /* Static variable holding AC gains for AC analysis */ + + + /* Get number of input values */ + + num_inputs = private->conn[0]->size; + + /* If this is the first call to the model, allocate the static variable */ + /* array */ + + if(private->circuit.init) { + acgains = malloc(num_inputs * sizeof(double)); + for(i = 0; i < num_inputs; i++) + acgains[i] = 0.0; + private->inst_var[0]->element[0].pvalue = acgains; + } + else + acgains = private->inst_var[0]->element[0].pvalue; + + /* If analysis type is AC, use the previously computed DC partials */ + /* for the AC gains */ + + if(private->circuit.anal_type == MIF_AC) { + for(i = 0; i < num_inputs; i++) { + acgains = private->inst_var[0]->element[0].pvalue; + private->conn[1]->port[0]->ac_gain[0].port[i].real = acgains[i]; + private->conn[1]->port[0]->ac_gain[0].port[i].imag = 0.0; + } + return; + } + + /* Get input values and coefficients to local storage for faster access */ + + in = malloc(num_inputs * sizeof(double)); + for(i = 0; i < num_inputs; i++) + in[i] = private->conn[0]->port[i]->input.rvalue; + + num_coefs = private->param[0]->size; + + coef = malloc(num_coefs * sizeof(double)); + for(i = 0; i < num_coefs; i++) + coef[i] = private->param[0]->element[i].rvalue; + + + /* Allocate the array of exponents used in computing the poly terms */ + exp = malloc(num_inputs * sizeof(int)); + + /* Initialize the exponents to zeros */ + for(i = 0; i < num_inputs; i++) + exp[i] = 0; + + + /* Compute the output of the source by summing the required products */ + for(i = 1, sum = coef[0]; i < num_coefs; i++) { + + /* Get the list of powers for the product terms in this term of the sum */ + nxtpwr(exp, num_inputs); + + /* Form the product of the inputs taken to the required powers */ + for(j = 0, product = 1.0; j < num_inputs; j++) + product *= evterm(in[j], exp[j]); + + /* Add the product times the appropriate coefficient into the sum */ + sum += coef[i] * product; + } + private->conn[1]->port[0]->output.rvalue = sum; + + + /* Compute and output the partials for each input */ + for(i = 0; i < num_inputs; i++) { + + /* Reinitialize the exponent list to zeros */ + for(j = 0; j < num_inputs; j++) + exp[j] = 0; + + /* Compute the partials by summing the required products */ + for(j = 1, sum = 0.0; j < num_coefs; j++) { + + /* Get the list of powers for the product terms in this term of the sum */ + nxtpwr(exp, num_inputs); + + /* If power for input for which partial is being evaluated */ + /* is zero, the term is a constant, so the partial is zero */ + if(exp[i] == 0) + continue; + + /* Form the product of the inputs taken to the required powers */ + for(k = 0, product = 1.0; k < num_inputs; k++) { + /* If input is not the one for which the partial is being taken */ + /* take the term to the specified exponent */ + if(k != i) + product *= evterm(in[k], exp[k]); + /* else, take the derivative of this term as n*x**(n-1) */ + else + product *= exp[k] * evterm(in[k], exp[k] - 1); + } + + /* Add the product times the appropriate coefficient into the sum */ + sum += coef[j] * product; + } + + private->conn[1]->port[0]->partial[0].port[i] = sum; + + /* If this is DC analysis, save the partial for use as AC gain */ + /* value in an AC analysis */ + + if(private->circuit.anal_type == MIF_DC) + acgains[i] = sum; + } + + /* Free the allocated items and return */ + free(in); + free(coef); + free(exp); + + return; +} + + +/* Function evterm computes the value of x**n */ + +static double evterm( + double x, + int n) +{ + double product; /* Temporary accumlator for forming the product */ + + product = 1.0; + while(n > 0) { + product *= x; + n--; + } + + return(product); +} + + + +/* + +This function is a literal translation of subroutine NXTPWR in SPICE 2G6. +This was done to guarantee compatibility with the ordering of +coefficients used by 2G6. The 2G6 User Guide does not completely define +the algorithm used and the GOTO loaded FORTRAN code is difficult to unravel. +Therefore, a one-to-one translation was deemed the safest approach. + +No attempt is made to document the function statements since no documentaton +is available in the 2G6 code. However, it can be noted that the code +appears to generate the exponents of the product terms in the sum-of-products +produced by the following expansion for two and three dimensional polynomials: + + 2D (a + b) ** n + 3D (a + (b + c)) ** n + +where n begins at 1 and increments as needed for as many terms as there are +coefficients on the polynomial source SPICE deck card, and where terms that +are identical under the laws of associativity are dropped. Thus, for example, +the exponents for the following sums are produced: + + 2D a + b + a**2 + ab + b**2 + c**3 + ... + 3D a + b + c + a**2 + a*b + a*c + b**2 + bc + c**2 + a**3 + ... + +*/ + +/* Define a macro to tranlate between FORTRAN-style array references */ +/* and C-style array references */ + +#define PWRSEQ(x) pwrseq[x - 1] + + +static void nxtpwr( + int *pwrseq, /* Array of exponents */ + int pdim) +{ + int i; + int k; + int km1; + int psum; + + if(pdim == 1) goto stmt80; + k = pdim; +stmt10: if(PWRSEQ(k) != 0) goto stmt20; + k = k - 1; + if(k != 0) goto stmt10; + goto stmt80; +stmt20: if(k == pdim) goto stmt30; + PWRSEQ(k) = PWRSEQ(k) - 1; + PWRSEQ(k+1) = PWRSEQ(k+1) + 1; + goto stmt100; +stmt30: km1 = k - 1; + for(i = 1; i <= km1; i++) + if(PWRSEQ(i) != 0) goto stmt50; +stmt40: PWRSEQ(1) = PWRSEQ(pdim) + 1; + PWRSEQ(pdim) = 0; + goto stmt100; +stmt50: psum = 1; + k = pdim; +stmt60: if(PWRSEQ(k-1) >= 1) goto stmt70; + psum = psum + PWRSEQ(k); + PWRSEQ(k) = 0; + k = k - 1; + goto stmt60; +stmt70: PWRSEQ(k) = PWRSEQ(k) + psum; + PWRSEQ(k-1) = PWRSEQ(k-1) - 1; + goto stmt100; +stmt80: PWRSEQ(1) = PWRSEQ(1) + 1; + +stmt100: return; + +} + diff --git a/src/xspice/icm/poly/cfunc.mod b/src/xspice/icm/poly/cfunc.mod new file mode 100755 index 000000000..d7ec837ed --- /dev/null +++ b/src/xspice/icm/poly/cfunc.mod @@ -0,0 +1,302 @@ +/* =========================================================================== +FILE cfunc.mod + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the definition of a code model polynomial controlled + source compatible with SPICE 2G6 poly sources. + +INTERFACES + + icm_poly() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + +/* + +This code model implements the non-linear polynomial controlled sources +available in SPICE 2G6. An automatic translator added into the simulator +front end is used to map 2G6 syntax into a call to this model in the +required syntax. + +This model may also be called directly as follows: + + a1 [ ] xxx + .model xxx poly ( coef = [ ] ) + +Refer to the 2G6 User Guide for an explanation of the coefficients. + + +This model is patterned after the FORTRAN code used in the 2G6 simulator. +Function cm_poly() below performs the functions of subroutines NLCSRC and +EVPOLY. Function evterm() performs the function of subroutine EVTERM, +and function nxtpwr() performs the function of subroutine NXTPWR. + +*/ + + + + +void *malloc(int); +void free(void *); + +/* SPICE 2G6 type utility functions */ +static double evterm(double x, int n); +static void nxtpwr(int *pwrseq, int pdim); + + + + +void icm_poly (ARGS) +{ + int num_inputs; /* Number of inputs to model */ + int num_coefs; /* Number of coefficients */ + int *exp; /* List of exponents in products */ + /* One for each input */ + + int i; /* Counter */ + int j; /* Counter */ + int k; /* Counter */ + + double *in; /* Values of inputs to model */ + double *coef; /* Values of coefficients */ + + double sum; /* Temporary for accumulating sum of terms */ + double product; /* Temporary for accumulating product */ + + double *acgains; /* Static variable holding AC gains for AC analysis */ + + + /* Get number of input values */ + + num_inputs = PORT_SIZE(in); + + /* If this is the first call to the model, allocate the static variable */ + /* array */ + + if(INIT) { + acgains = malloc(num_inputs * sizeof(double)); + for(i = 0; i < num_inputs; i++) + acgains[i] = 0.0; + STATIC_VAR(acgains) = acgains; + } + else + acgains = STATIC_VAR(acgains); + + /* If analysis type is AC, use the previously computed DC partials */ + /* for the AC gains */ + + if(ANALYSIS == MIF_AC) { + for(i = 0; i < num_inputs; i++) { + acgains = STATIC_VAR(acgains); + AC_GAIN(out,in[i]).real = acgains[i]; + AC_GAIN(out,in[i]).imag = 0.0; + } + return; + } + + /* Get input values and coefficients to local storage for faster access */ + + in = malloc(num_inputs * sizeof(double)); + for(i = 0; i < num_inputs; i++) + in[i] = INPUT(in[i]); + + num_coefs = PARAM_SIZE(coef); + + coef = malloc(num_coefs * sizeof(double)); + for(i = 0; i < num_coefs; i++) + coef[i] = PARAM(coef[i]); + + + /* Allocate the array of exponents used in computing the poly terms */ + exp = malloc(num_inputs * sizeof(int)); + + /* Initialize the exponents to zeros */ + for(i = 0; i < num_inputs; i++) + exp[i] = 0; + + + /* Compute the output of the source by summing the required products */ + for(i = 1, sum = coef[0]; i < num_coefs; i++) { + + /* Get the list of powers for the product terms in this term of the sum */ + nxtpwr(exp, num_inputs); + + /* Form the product of the inputs taken to the required powers */ + for(j = 0, product = 1.0; j < num_inputs; j++) + product *= evterm(in[j], exp[j]); + + /* Add the product times the appropriate coefficient into the sum */ + sum += coef[i] * product; + } + OUTPUT(out) = sum; + + + /* Compute and output the partials for each input */ + for(i = 0; i < num_inputs; i++) { + + /* Reinitialize the exponent list to zeros */ + for(j = 0; j < num_inputs; j++) + exp[j] = 0; + + /* Compute the partials by summing the required products */ + for(j = 1, sum = 0.0; j < num_coefs; j++) { + + /* Get the list of powers for the product terms in this term of the sum */ + nxtpwr(exp, num_inputs); + + /* If power for input for which partial is being evaluated */ + /* is zero, the term is a constant, so the partial is zero */ + if(exp[i] == 0) + continue; + + /* Form the product of the inputs taken to the required powers */ + for(k = 0, product = 1.0; k < num_inputs; k++) { + /* If input is not the one for which the partial is being taken */ + /* take the term to the specified exponent */ + if(k != i) + product *= evterm(in[k], exp[k]); + /* else, take the derivative of this term as n*x**(n-1) */ + else + product *= exp[k] * evterm(in[k], exp[k] - 1); + } + + /* Add the product times the appropriate coefficient into the sum */ + sum += coef[j] * product; + } + + PARTIAL(out,in[i]) = sum; + + /* If this is DC analysis, save the partial for use as AC gain */ + /* value in an AC analysis */ + + if(ANALYSIS == MIF_DC) + acgains[i] = sum; + } + + /* Free the allocated items and return */ + free(in); + free(coef); + free(exp); + + return; +} + + +/* Function evterm computes the value of x**n */ + +static double evterm( + double x, + int n) +{ + double product; /* Temporary accumlator for forming the product */ + + product = 1.0; + while(n > 0) { + product *= x; + n--; + } + + return(product); +} + + + +/* + +This function is a literal translation of subroutine NXTPWR in SPICE 2G6. +This was done to guarantee compatibility with the ordering of +coefficients used by 2G6. The 2G6 User Guide does not completely define +the algorithm used and the GOTO loaded FORTRAN code is difficult to unravel. +Therefore, a one-to-one translation was deemed the safest approach. + +No attempt is made to document the function statements since no documentaton +is available in the 2G6 code. However, it can be noted that the code +appears to generate the exponents of the product terms in the sum-of-products +produced by the following expansion for two and three dimensional polynomials: + + 2D (a + b) ** n + 3D (a + (b + c)) ** n + +where n begins at 1 and increments as needed for as many terms as there are +coefficients on the polynomial source SPICE deck card, and where terms that +are identical under the laws of associativity are dropped. Thus, for example, +the exponents for the following sums are produced: + + 2D a + b + a**2 + ab + b**2 + c**3 + ... + 3D a + b + c + a**2 + a*b + a*c + b**2 + bc + c**2 + a**3 + ... + +*/ + +/* Define a macro to tranlate between FORTRAN-style array references */ +/* and C-style array references */ + +#define PWRSEQ(x) pwrseq[x - 1] + + +static void nxtpwr( + int *pwrseq, /* Array of exponents */ + int pdim) +{ + int i; + int k; + int km1; + int psum; + + if(pdim == 1) goto stmt80; + k = pdim; +stmt10: if(PWRSEQ(k) != 0) goto stmt20; + k = k - 1; + if(k != 0) goto stmt10; + goto stmt80; +stmt20: if(k == pdim) goto stmt30; + PWRSEQ(k) = PWRSEQ(k) - 1; + PWRSEQ(k+1) = PWRSEQ(k+1) + 1; + goto stmt100; +stmt30: km1 = k - 1; + for(i = 1; i <= km1; i++) + if(PWRSEQ(i) != 0) goto stmt50; +stmt40: PWRSEQ(1) = PWRSEQ(pdim) + 1; + PWRSEQ(pdim) = 0; + goto stmt100; +stmt50: psum = 1; + k = pdim; +stmt60: if(PWRSEQ(k-1) >= 1) goto stmt70; + psum = psum + PWRSEQ(k); + PWRSEQ(k) = 0; + k = k - 1; + goto stmt60; +stmt70: PWRSEQ(k) = PWRSEQ(k) + psum; + PWRSEQ(k-1) = PWRSEQ(k-1) - 1; + goto stmt100; +stmt80: PWRSEQ(1) = PWRSEQ(1) + 1; + +stmt100: return; + +} + diff --git a/src/xspice/icm/poly/ifspec.c b/src/xspice/icm/poly/ifspec.c new file mode 100755 index 000000000..707859a58 --- /dev/null +++ b/src/xspice/icm/poly/ifspec.c @@ -0,0 +1,194 @@ + +/* + * Structures for model: poly + * + * Automatically generated by cmpp preprocessor + * + * !!! DO NOT EDIT !!! + * + */ + + +// #include "prefix.h" +#include +#include "spice.h" +#include "devdefs.h" +#include "ifsim.h" +#include "mifdefs.h" +#include "mifproto.h" +#include "mifparse.h" +// #include "suffix.h" + + +static IFparm MIFmPTable[] = { + IOP("coef", 0, (IF_REAL|IF_VECTOR), "2g6 compatible spice card coefficient list"), +}; + + +static IFparm MIFpTable[] = { + OP("acgains", 1, IF_STRING, "partial derivatives from dc analysis used for ac gains"), +}; + + +static Mif_Port_Type_t MIFportEnum0[] = { + MIF_VOLTAGE, + MIF_DIFF_VOLTAGE, + MIF_CURRENT, + MIF_DIFF_CURRENT, + MIF_VSOURCE_CURRENT, +}; + + +static char *MIFportStr0[] = { + "v", + "vd", + "i", + "id", + "vnam", +}; + + +static Mif_Port_Type_t MIFportEnum1[] = { + MIF_VOLTAGE, + MIF_DIFF_VOLTAGE, + MIF_CURRENT, + MIF_DIFF_CURRENT, +}; + + +static char *MIFportStr1[] = { + "v", + "vd", + "i", + "id", +}; + + +static Mif_Conn_Info_t MIFconnTable[] = { + { + "in", + "input", + MIF_IN, + MIF_VOLTAGE, + "v", + 5, + MIFportEnum0, + MIFportStr0, + MIF_TRUE, + MIF_TRUE, + 1, + MIF_FALSE, + 0, + MIF_FALSE, + }, + { + "out", + "output", + MIF_OUT, + MIF_VOLTAGE, + "v", + 4, + MIFportEnum1, + MIFportStr1, + MIF_FALSE, + MIF_FALSE, + 0, + MIF_FALSE, + 0, + MIF_FALSE, + }, +}; + + +static Mif_Param_Info_t MIFparamTable[] = { + { + "coef", + "2g6 compatible spice card coefficient list", + MIF_REAL, + MIF_FALSE, + {MIF_FALSE, 0, 0.0, {0.0, 0.0}, NULL}, + MIF_FALSE, + {MIF_FALSE, 0, 0.0, {0.0, 0.0}, NULL}, + MIF_FALSE, + {MIF_FALSE, 0, 0.0, {0.0, 0.0}, NULL}, + MIF_TRUE, + MIF_FALSE, + 0, + MIF_TRUE, + 2, + MIF_FALSE, + 0, + MIF_FALSE, + }, +}; + + +static Mif_Inst_Var_Info_t MIFinst_varTable[] = { + { + "acgains", + "partial derivatives from dc analysis used for ac gains", + MIF_STRING, + MIF_FALSE, + }, +}; + + +extern void icm_poly(Mif_Private_t *); + +static int val_terms = 0; +static int val_numNames = 0; +static int val_numInstanceParms = 1; +static int val_numModelParms = 1; +static int val_sizeofMIFinstance = sizeof(MIFinstance); +static int val_sizeofMIFmodel = sizeof(MIFmodel); + +SPICEdev icm_poly_info = { + { "poly", + "2g6 compatible polynomial controlled source", + &val_terms, + &val_numNames, + NULL, + &val_numInstanceParms, + MIFpTable, + &val_numModelParms, + MIFmPTable, + icm_poly, + 2, + MIFconnTable, + 1, + MIFparamTable, + 1, + MIFinst_varTable, + }, +NULL, +MIFmParam, +MIFload, +MIFsetup, +MIFunsetup, +NULL, +NULL, +MIFtrunc, +NULL, +MIFload, +NULL, +MIFdestroy, +MIFmDelete, +MIFdelete, +NULL, +MIFask, +MIFmAsk, +NULL, +MIFconvTest, +NULL, +NULL, +NULL, +NULL, +NULL, +NULL, +NULL, +NULL, +&val_sizeofMIFinstance, +&val_sizeofMIFmodel, + +}; + diff --git a/src/xspice/icm/poly/ifspec.ifs b/src/xspice/icm/poly/ifspec.ifs new file mode 100755 index 000000000..39a2aaef8 --- /dev/null +++ b/src/xspice/icm/poly/ifspec.ifs @@ -0,0 +1,75 @@ +/* =========================================================================== +FILE ifspec.ifs + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the definition of a code model polynomial controlled + source compatible with SPICE 2G6 poly sources. + +INTERFACES + + None. + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +=========================================================================== */ + +NAME_TABLE: + +Spice_Model_Name: poly +C_Function_Name: icm_poly +Description: "2G6 compatible polynomial controlled source" + + +PORT_TABLE: + +Port_Name: in out +Description: "input" "output" +Direction: in out +Default_Type: v v +Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] +Vector: yes no +Vector_Bounds: [1 -] - +Null_Allowed: no no + + +PARAMETER_TABLE: + +Parameter_Name: coef +Description: "2G6 compatible spice card coefficient list" +Data_Type: real +Default_Value: - +Limits: - +Vector: yes +Vector_Bounds: [2 -] +Null_Allowed: no + + +STATIC_VAR_TABLE: + +Static_Var_Name: acgains +Data_Type: pointer +Description: "Partial derivatives from DC analysis used for AC gains" diff --git a/src/xspice/icm/poly/make.bat b/src/xspice/icm/poly/make.bat new file mode 100755 index 000000000..19a341b81 --- /dev/null +++ b/src/xspice/icm/poly/make.bat @@ -0,0 +1,3 @@ +#!/bin/sh +cmpp -mod cfunc.mod +cmpp -ifs diff --git a/src/xspice/idn/Makefile.am b/src/xspice/idn/Makefile.am new file mode 100755 index 000000000..1d1ebc2f9 --- /dev/null +++ b/src/xspice/idn/Makefile.am @@ -0,0 +1,12 @@ +## Process this file with automake to produce Makefile.in +# +# JW 3/9/01 - had a go and makeing an autoconf script. + +noinst_LIBRARIES = libidnxsp.a + +libidnxsp_a_SOURCES = \ + idndig.c + +INCLUDES = -I$(top_srcdir)/src/include + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/xspice/idn/idndig.c b/src/xspice/idn/idndig.c new file mode 100755 index 000000000..3fc7701c5 --- /dev/null +++ b/src/xspice/idn/idndig.c @@ -0,0 +1,349 @@ +/*============================================================================ +FILE IDNdig.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the definition of the 'digital' node type + used by 12-state digital models in the code model library. + These functions are called exclusively through function + pointers in an Evt_Udn_Info_t data structure. + +INTERFACES + + Evt_Udn_Info_t idn_digital_info + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +#include + +#include "cm.h" + +#include "evtudn.h" + +void *tmalloc(size_t); + + +/* ************************************************************************ */ + +void idn_digital_create(void **evt_struct) +{ + /* Malloc space for a digital struct */ + + *evt_struct = tmalloc(sizeof(Digital_t)); +} + + +/* ************************************************************************ */ + +void idn_digital_dismantle(void *evt_struct) +{ + /* Do nothing. There are no internally malloc'ed things to dismantle */ +} + + +/* ************************************************************************ */ + +void idn_digital_initialize(void *evt_struct) +{ + Digital_t *dig_struct = evt_struct; + + + /* Initialize to unknown state and strength */ + dig_struct->state = ZERO; + dig_struct->strength = UNDETERMINED; +} + + +/* ************************************************************************ */ + +void idn_digital_invert(void *evt_struct) +{ + Digital_t *dig_struct = evt_struct; + + + /* Invert the state */ + switch(dig_struct->state) { + + case ZERO: + dig_struct->state = ONE; + return; + + case ONE: + dig_struct->state = ZERO; + return; + + default: + return; + } + +} + + +/* ************************************************************************ */ + +void idn_digital_copy(void *evt_from_struct, void *evt_to_struct) +{ + Digital_t *dig_from_struct = evt_from_struct; + Digital_t *dig_to_struct = evt_to_struct; + + /* Copy the structure */ + dig_to_struct->state = dig_from_struct->state; + dig_to_struct->strength = dig_from_struct->strength; +} + + +/* ************************************************************************ */ + +void idn_digital_resolve(int num_struct, + void **evt_struct_array, void *evt_struct) +{ + Digital_t **dig_struct_array; + Digital_t *dig_struct; + + static int map[12][12] = { + { 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2}, + { 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1}, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, + { 0, 1, 2, 3, 5, 5, 3, 3, 3, 9, 11, 11}, + { 0, 1, 2, 5, 4, 5, 4, 4, 4, 11, 10, 11}, + { 0, 1, 2, 5, 5, 5, 5, 5, 5, 10, 11, 11}, + { 0, 1, 2, 3, 4, 5, 6, 8, 8, 9, 11, 11}, + { 0, 1, 2, 3, 4, 5, 8, 7, 8, 11, 10, 11}, + { 0, 1, 2, 3, 4, 5, 8, 8, 8, 11, 11, 11}, + { 0, 2, 2, 9, 11, 11, 9, 11, 11, 9, 11, 11}, + { 2, 1, 2, 11, 10, 11, 11, 10, 11, 11, 10, 11}, + { 2, 1, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11} }; + + int i; + + int index1; + int index2; + + /* Cast the input void pointers to pointers of the digital type */ + dig_struct = evt_struct; + dig_struct_array = evt_struct_array; + + /* Copy the first member of the array directly to the output */ + dig_struct->state = dig_struct_array[0]->state; + dig_struct->strength = dig_struct_array[0]->strength; + + /* Convert struct to index into map */ + index1 = dig_struct->state + ((int)dig_struct->strength) * 3; + + + /* For the remaining members, perform the resolution algorithm */ + for(i = 1; i < num_struct; i++) { + + /* Convert struct to index into map */ + index2 = dig_struct_array[i]->state + + ((int)dig_struct_array[i]->strength) * 3; + + /* Compute the result */ + index1 = map[index1][index2]; + } + + /* Convert result back to state and strength */ + dig_struct->state = index1 % 3; + dig_struct->strength = index1 / 3; +} + + +/* ************************************************************************ */ + +void idn_digital_compare(void *evt_struct1, void *evt_struct2, + Boolean_t *equal) +{ + Digital_t *dig_struct1 = evt_struct1; + Digital_t *dig_struct2 = evt_struct2; + + /* Compare the structures in order of most likely differences */ + if(dig_struct1->state != dig_struct2->state) + *equal = FALSE; + else if(dig_struct1->strength != dig_struct2->strength) + *equal = FALSE; + else + *equal = TRUE; +} + + +/* ************************************************************************ */ + +void idn_digital_plot_val(void *evt_struct, char *member, double *val) +{ + Digital_t *dig_struct = evt_struct; + + + /* Output a value for the requested member of the digital struct */ + if(strcmp(member,"strength") == 0) { + + /* Choose values that will not make plots lie on state plots */ + switch(dig_struct->strength) { + + case STRONG: + *val = 0.1; + return; + + case RESISTIVE: + *val = 0.6; + return; + + case HI_IMPEDANCE: + *val = 1.1; + return; + + case UNDETERMINED: + *val = -0.4; + return; + } + } + else { + /* member = "state" or anything else */ + + /* Pick reasonable values */ + switch(dig_struct->state) { + + case ZERO: + *val = 0.0; + return; + + case ONE: + *val = 1.0; + return; + + case UNKNOWN: + *val = 0.5; + return; + } + } +} + + +/* ************************************************************************ */ + +void idn_digital_print_val(void *evt_struct, char *member, char **val) +{ + Digital_t *dig_struct = evt_struct; + + int index; + + static char *map[] = { "0s", "1s", "Us", + "0r", "1r", "Ur", + "0z", "1z", "Uz", + "0u", "1u", "Uu" }; + + + /* Output a value for the requested member of the digital struct */ + + if(strcmp(member,"state") == 0) { + + /* Pick reasonable values */ + switch(dig_struct->state) { + + case ZERO: + *val = "0"; + return; + + case ONE: + *val = "1"; + return; + + case UNKNOWN: + *val = "U"; + return; + + default: + *val = "?"; + return; + } + } + else if(strcmp(member,"strength") == 0) { + + /* Choose values that will not make plots lie on state plots */ + switch(dig_struct->strength) { + + case STRONG: + *val = "s"; + return; + + case RESISTIVE: + *val = "r"; + return; + + case HI_IMPEDANCE: + *val = "z"; + return; + + case UNDETERMINED: + *val = "u"; + return; + + default: + *val = "?"; + return; + } + } + else { + index = dig_struct->state + ((int)dig_struct->strength) * 3; + if((index < 0) || (index > 11)) + *val = "??"; + else + *val = map[index]; + return; + } +} + + + +/* ************************************************************************ */ + +void idn_digital_ipc_val(void *evt_struct, void **ipc_val, int *ipc_val_size) +{ + /* Return the digital data structure and its size */ + *ipc_val = evt_struct; + *ipc_val_size = sizeof(Digital_t); +} + + + +Evt_Udn_Info_t idn_digital_info = { + +"d", +"12 state digital data", +idn_digital_create, +idn_digital_dismantle, +idn_digital_initialize, +idn_digital_invert, +idn_digital_copy, +idn_digital_resolve, +idn_digital_compare, +idn_digital_plot_val, +idn_digital_print_val, +idn_digital_ipc_val + +}; + diff --git a/src/xspice/ipc/Makefile.am b/src/xspice/ipc/Makefile.am new file mode 100755 index 000000000..dc19a55e9 --- /dev/null +++ b/src/xspice/ipc/Makefile.am @@ -0,0 +1,16 @@ +## Process this file with automake to produce Makefile.in +# +# JW 3/9/01 - had a go and makeing an autoconf script. + +noinst_LIBRARIES = libipcxsp.a + +libipcxsp_a_SOURCES = \ +ipcaegis.c \ +ipc.c \ +ipcsockets.c \ +ipcstdio.c \ +ipctiein.c + +INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/xspice/ipc/ipc.c b/src/xspice/ipc/ipc.c new file mode 100755 index 000000000..03be29fb3 --- /dev/null +++ b/src/xspice/ipc/ipc.c @@ -0,0 +1,987 @@ +/*============================================================================ +FILE IPC.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Steve Tynor + +MODIFICATIONS + + 6/13/92 Bill Kuhn Added some comments + +SUMMARY + + Provides compatibility for the new SPICE simulator to both the MSPICE user + interface and BCP (via ATESSE v.1 style AEGIS mailboxes) and the new ATESSE + v.2 Simulator Interface and BCP (via Bsd Sockets). + + The Interprocess Communications package provides functions + called to receive XSPICE decks from the ATESSE Simulator Interface + or Batch Control processes, and to return results to those + processes. Functions callable from the simulator packages include: + + ipc_initialize_server + ipc_terminate_server + ipc_get_line + ipc_send_line + ipc_send_data_prefix + ipc_send_data_suffix + ipc_send_dcop_prefix + ipc_send_dcop_suffix + ipc_send_evtdict_prefix + ipc_send_evtdict_suffix + ipc_send_evtdata_prefix + ipc_send_evtdata_suffix + ipc_send_errchk + ipc_send_end + ipc_send_boolean + ipc_send_int + ipc_send_double + ipc_send_complex + ipc_send_event + ipc_flush + + These functions communicate with a set of transport-level functions + that implement the interprocess communications under one of + the following protocol types determined by a compile-time option: + + BSD UNIX Sockets + HP/Apollo Mailboxes + + For each transport protocol, the following functions are written: + + ipc_transport_initialize_server + ipc_transport_get_line + ipc_transport_terminate_server + ipc_transport_send_line + + + +============================================================================*/ + +#ifndef NDEBUG +#include +#endif +#include /* Specific to BSD - Use sys/fcntl.h for sys5 */ +#include +#include +#include + +#include +#include +#include +#include /* NOTE: I think this is a Sys5ism (there is not man + * page for it under Bsd, but it's in /usr/include + * and it has a BSD copyright header. Go figure. + */ + +#include "ipc.h" +#include "ipctiein.h" +#include "ipcproto.h" + + +/* + * Conditional compilation sanity check: + */ + +/* +#if !defined (IPC_AEGIS_MAILBOXES) && !defined (IPC_UNIX_SOCKETS)\ + && !defined (IPC_DEBUG_VIA_STDIO) +" compiler error - must specify a transport mechanism"; +#endif + +*///ka removed + +/* + * static 'globals' + */ + +/*typedef unsigned char Buffer_Char_t;*/ +typedef char Buffer_Char_t; + +#define OUT_BUFFER_SIZE 1000 +#define MAX_NUM_RECORDS 200 +static int end_of_record_index [MAX_NUM_RECORDS]; +static int num_records; +static Buffer_Char_t out_buffer [OUT_BUFFER_SIZE]; +static int fill_count; + +static Ipc_Mode_t mode; +static Ipc_Protocol_t protocol; +static Ipc_Boolean_t end_of_deck_seen; +static int batch_fd; + +#define FMT_BUFFER_SIZE 80 +static char fmt_buffer [FMT_BUFFER_SIZE]; + +/*---------------------------------------------------------------------------*/ +Ipc_Boolean_t kw_match (keyword, str) + char *keyword; + char *str; + /* + * returns IPC_TRUE if the first `strlen(keyword)' characters of `str' match + * the ones in `keyword' - case sensitive + */ +{ + char *k = keyword; + char *s = str; + + /* + * quit if we run off the end of either string: + */ + while (*s && *k) { + if (*s != *k) { + return IPC_FALSE; + } + s++; + k++; + } + /* + * if we get this far, it sould be because we ran off the end of the + * keyword else we didn't match: + */ + return (*k == '\0'); +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_initialize_server + +This function creates the interprocess communication channel +server mailbox or socket. +*/ + + +Ipc_Status_t ipc_initialize_server (server_name, m, p) + char *server_name; /* Mailbox path or host/portnumber pair */ + Ipc_Mode_t m; /* Interactive or batch */ + Ipc_Protocol_t p; /* Type of IPC protocol */ + /* + * For mailboxes, `server_name' would be the mailbox pathname; for + * sockets, this needs to be a host/portnumber pair. Maybe this should be + * automatically generated by the routine... + */ +{ + Ipc_Status_t status; + char batch_filename [1025]; + + mode = m; + protocol = p; + end_of_deck_seen = IPC_FALSE; + + num_records = 0; + fill_count = 0; + + status = ipc_transport_initialize_server (server_name, m, p, + batch_filename); + + if (status != IPC_STATUS_OK) { + fprintf (stderr, "ERROR: IPC: error initializing server\n"); + return IPC_STATUS_ERROR; + } + + if (mode == IPC_MODE_BATCH) { +#ifdef IPC_AEGIS_MAILBOXES + strcat (batch_filename, ".log"); +#endif + batch_fd = open (batch_filename, O_WRONLY | O_CREAT, 0666); + if (batch_fd < 0) { + // fprintf (stderr, "ERROR: IPC: Error opening batch output file: %s\n",batch_filename); + perror ("IPC"); + return IPC_STATUS_ERROR; + } + } + return status; +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_terminate_server + +This function deallocates the interprocess communication channel +mailbox or socket. +*/ + +Ipc_Status_t ipc_transport_terminate_server (); + +Ipc_Status_t ipc_terminate_server () +{ + return ipc_transport_terminate_server (); +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_get_line + +This function gets a SPICE deck input line from the interprocess +communication channel. Any special control commands in the deck +beginning with a ``>'' or ``#'' character are processed internally by +this function and not returned to SPICE. +*/ + +Ipc_Status_t ipc_get_line (str, len, wait) + char *str; /* Text retrieved from IPC channel */ + int *len; /* Length of text string */ + Ipc_Wait_t wait; /* Select blocking or non-blocking */ + /* + * Reads one SPICE line from the connection. Strips any control lines + * which cannot be interpretted by the simulator (e.g. >INQCON) and + * processes them. If such a line is read, it is processed and the next + * line is read. `ipc_get_line' does not return until a non-interceptable + * line is read or end of file. + * + * If `wait' is IPC_NO_WAIT and there is no data available on the + * connection, `ipc_get_line' returns IPC_STATUS_NO_DATA. If `wait' is + * IPC_WAIT, `ipc_get_line' will not return until there is data available + * or and end of file condition is reached or an error occurs. + * + * Intercepts and processes the following commands: + * #RETURNI, #MINTIME, #VTRANS, + * >PAUSE, >CONT, >STOP, >INQCON, >NETLIST, >ENDNET + * Other > records are silently ignored. + * + * Intercepts old-style .TEMP card generated by MSPICE + * + * Returns: + * IPC_STATUS_OK - for successful reads + * IPC_STATUS_NO_DATA - when NO_WAIT and no data available + * IPC_STATUS_END_OF_DECK - at end of deck (>ENDNET seen) + * IPC_STATUS_ERROR - otherwise + */ +{ + Ipc_Status_t status; + Ipc_Boolean_t need_another = IPC_TRUE; + + do { + + status = ipc_transport_get_line (str, len, wait); + + switch (status) { + case IPC_STATUS_NO_DATA: + case IPC_STATUS_ERROR: + need_another = IPC_FALSE; + break; + case IPC_STATUS_END_OF_DECK: + assert (0); /* should never get this from the low-level get-line */ + status = IPC_STATUS_ERROR; + need_another = IPC_FALSE; + break; + case IPC_STATUS_OK: + /* + * Got a good line - check to see if it's one of the ones we need to + * intercept + */ + if (str[0] == '>') { + if (kw_match (">STOP", str)) { + ipc_handle_stop(); + } else if (kw_match (">PAUSE", str)) { + /* assert (need_another); */ + /* + * once more around the loop to do a blocking wait for the >CONT + */ + need_another = IPC_TRUE; + wait = IPC_WAIT; + } else if (kw_match (">INQCON", str)) { + ipc_send_line (">ABRTABL"); + ipc_send_line (">PAUSABL"); + ipc_send_line (">KEEPABL"); + status = ipc_flush (); + if (IPC_STATUS_OK != status) { + need_another = IPC_FALSE; + } + } else if (kw_match (">ENDNET", str)) { + end_of_deck_seen = IPC_TRUE; + need_another = IPC_FALSE; + status = IPC_STATUS_END_OF_DECK; + } else { + /* silently ignore */ + } + } else if (str[0] == '#') { + if (kw_match ("#RETURNI", str)) { + ipc_handle_returni (); + } else if (kw_match ("#MINTIME", str)) { + double d1/*,d2*/; + if (1 != sscanf (&str[8], "%lg", &d1)) { + status = IPC_STATUS_ERROR; + need_another = IPC_FALSE; + } else { + ipc_handle_mintime (d1); + } + } else if (kw_match ("#VTRANS", str)) { + char *tok1; + char *tok2; + char *tok3; + + tok1 = &str[8]; + for (tok2 = tok1; *tok2; tok2++) { + if (isspace(*tok2)) { + *tok2 = '\0'; + tok2++; + break; + } + } + for(tok3 = tok2; *tok3; tok3++) { + if(isspace(*tok3)) { + *tok3 = '\0'; + break; + } + } + ipc_handle_vtrans (tok1, tok2); + } else { + /* silently ignore */ + } + } else if (str[0] == '.') { + if (kw_match (".TEMP", str)) { + /* don't pass .TEMP card to caller */ + printf("Old-style .TEMP card found - ignored\n"); + } + else { + /* pass all other . cards to the caller */ + need_another = IPC_FALSE; + } + } else { + /* + * Not a '>' or '#' record - let the caller deal with it + */ + need_another = IPC_FALSE; + } + break; + default: + /* + * some unknown status value! + */ + assert (0); + status = IPC_STATUS_ERROR; + need_another = IPC_FALSE; + break; + } + } while (need_another); + + return status; +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_flush + +This function flushes the interprocess communication channel +buffer contents. +*/ + +Ipc_Status_t ipc_flush () + /* + * Flush all buffered messages out the connection. + */ +{ + Ipc_Status_t status; + int last = 0; + /*int bytes;*/ + int i; + + /* if batch mode */ + if (mode == IPC_MODE_BATCH) { + + assert (batch_fd >= 0); + + /* for number of records in buffer */ + for (i = 0; i < num_records; i++) { + + /* write the records to the .log file */ + if ((end_of_record_index [i] - last) != + write (batch_fd, &out_buffer[last], end_of_record_index [i] - last)) { + // fprintf (stderr,"ERROR: IPC: Error writing to batch output file\n"); + perror ("IPC"); + return IPC_STATUS_ERROR; + } + + /* If the record is one of the batch simulation status messages, */ + /* send it over the ipc channel too */ + if( kw_match("#ERRCHK", &out_buffer[last]) || + kw_match(">ENDANAL", &out_buffer[last]) || + kw_match(">ABORTED", &out_buffer[last]) ) { + + status = ipc_transport_send_line (&out_buffer[last], + end_of_record_index [i] - last); + if (IPC_STATUS_OK != status) { + return status; + } + } + last = end_of_record_index [i]; + } + + /* else, must be interactive mode */ + } else { + /* send the full buffer over the ipc channel */ + status = ipc_transport_send_line (&out_buffer[0], + end_of_record_index [num_records - 1]); + if (IPC_STATUS_OK != status) { + return status; + } + } + + /* reset counts to zero and return */ + num_records = 0; + fill_count = 0; + return IPC_STATUS_OK; +} + +/*---------------------------------------------------------------------------*/ +Ipc_Status_t ipc_send_line_binary (str, len) + char *str; + int len; + /* + * Same as `ipc_send_line' except does not expect the str to be null + * terminated. Sends exactly `len' characters. Use this for binary data + * strings that may have embedded nulls. + * + * Modified by wbk to append newlines for compatibility with + * ATESSE 1.0 + * + */ +{ + int length = len + 1; + /*int diff;*/ + Ipc_Status_t status; + + /* + * If we can't add the whole str to the buffer, or if there are no more + * record indices free, flush the buffer: + */ + if (((fill_count + length) >= OUT_BUFFER_SIZE) || + (num_records >= MAX_NUM_RECORDS)) { + status = ipc_flush (); + if (IPC_STATUS_OK != status) { + return status; + } + } + + /* + * make sure that the str will fit: + */ + if (length + fill_count > OUT_BUFFER_SIZE) { + // fprintf (stderr,"ERROR: IPC: String too long to fit in output buffer (> %d bytes) - truncated\n",OUT_BUFFER_SIZE); + length = OUT_BUFFER_SIZE - fill_count; + } + + /* + * finally, concatenate the str to the end of the buffer and add the newline: + */ + memcpy (&out_buffer[fill_count], str, len); + fill_count += len; + + out_buffer[fill_count] = '\n'; + fill_count++; + + end_of_record_index [num_records++] = fill_count; + + return IPC_STATUS_OK; +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_send_line + +This function sends a line of text over the interprocess +communication channel. +*/ + + +Ipc_Status_t ipc_send_line (str) + char *str; /* The text to send */ +{ + int len; + int send_len; + + char *s; + + Ipc_Status_t status= IPC_STATUS_OK; + + + len = strlen(str); + + /* if short string, send it immediately */ + if(len < 80) + status = ipc_send_line_binary (str, len); + else { + /* otherwise, we have to send it as multiple strings */ + /* because Mspice cannot handle things longer than 80 chars */ + s = str; + while(len > 0) { + if(len < 80) + send_len = len; + else + send_len = 79; + status = ipc_send_line_binary (str, send_len); + if(status != IPC_STATUS_OK) + break; + s += send_len; + len -= send_len; + } + } + + return(status); +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_send_data_prefix + +This function sends a ``>DATAB'' line over the interprocess +communication channel to signal that this is the beginning of a +results dump for the current analysis point. +*/ + +Ipc_Status_t ipc_send_data_prefix (time) + double time; /* The analysis point for this data set */ +{ + char buffer[40]; + + sprintf (buffer, ">DATAB %.5E", time); + return ipc_send_line (buffer); +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_send_data_suffix + +This function sends a ``>ENDDATA'' line over the interprocess +communication channel to signal that this is the end of a results +dump from a particular analysis point. +*/ + + +Ipc_Status_t ipc_send_data_suffix () +{ + Ipc_Status_t status; + + status = ipc_send_line (">ENDDATA"); + + if(status != IPC_STATUS_OK) + return(status); + + return(ipc_flush()); +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_send_dcop_prefix + +This function sends a ``>DCOPB'' line over the interprocess +communication channel to signal that this is the beginning of a +results dump from a DC operating point analysis. +*/ + +Ipc_Status_t ipc_send_dcop_prefix () +{ + return ipc_send_line (">DCOPB"); +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_send_dcop_suffix + +This function sends a ``>ENDDATA'' line over the interprocess +communication channel to signal that this is the end of a results +dump from a particular analysis point. +*/ + + +Ipc_Status_t ipc_send_dcop_suffix () +{ + Ipc_Status_t status; + + status = ipc_send_line (">ENDDCOP"); + + if(status != IPC_STATUS_OK) + return(status); + + return(ipc_flush()); +} + + +/*---------------------------------------------------------------------------*/ + +/* +ipc_send_evtdict_prefix + +This function sends a ``>EVTDICT'' line over the interprocess +communication channel to signal that this is the beginning of an +event-driven node dictionary. + +The line is sent only if the IPC is configured +for UNIX sockets, indicating use with the V2 ATESSE SI process. +*/ + +Ipc_Status_t ipc_send_evtdict_prefix () +{ +#ifdef IPC_AEGIS_MAILBOXES + return IPC_STATUS_OK; +#else + return ipc_send_line (">EVTDICT"); +#endif +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_send_evtdict_suffix + +This function sends a ``>ENDDICT'' line over the interprocess +communication channel to signal that this is the end of an +event-driven node dictionary. + +The line is sent only if the IPC is configured +for UNIX sockets, indicating use with the V2 ATESSE SI process. +*/ + + +Ipc_Status_t ipc_send_evtdict_suffix () +{ +#ifdef IPC_AEGIS_MAILBOXES + return IPC_STATUS_OK; +#else + Ipc_Status_t status; + + status = ipc_send_line (">ENDDICT"); + + if(status != IPC_STATUS_OK) + return(status); + + return(ipc_flush()); +#endif +} + + +/*---------------------------------------------------------------------------*/ + +/* +ipc_send_evtdata_prefix + +This function sends a ``>EVTDATA'' line over the interprocess +communication channel to signal that this is the beginning of an +event-driven node data block. + +The line is sent only if the IPC is configured +for UNIX sockets, indicating use with the V2 ATESSE SI process. +*/ + +Ipc_Status_t ipc_send_evtdata_prefix () +{ +#ifdef IPC_AEGIS_MAILBOXES + return IPC_STATUS_OK; +#else + return ipc_send_line (">EVTDATA"); +#endif +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_send_evtdata_suffix + +This function sends a ``>ENDDATA'' line over the interprocess +communication channel to signal that this is the end of an +event-driven node data block. + +The line is sent only if the IPC is configured +for UNIX sockets, indicating use with the V2 ATESSE SI process. +*/ + + +Ipc_Status_t ipc_send_evtdata_suffix () +{ +#ifdef IPC_AEGIS_MAILBOXES + return IPC_STATUS_OK; +#else + Ipc_Status_t status; + + status = ipc_send_line (">ENDDATA"); + + if(status != IPC_STATUS_OK) + return(status); + + return(ipc_flush()); +#endif +} + + +/*---------------------------------------------------------------------------*/ + +/* +ipc_send_errchk + +This function sends a ``\ERRCHK [GO|NOGO]'' message over the +interprocess communication channel to signal that the initial +parsing of the input deck has been completed and to indicate +whether or not errors were detected. +*/ + + +Ipc_Status_t ipc_send_errchk() +{ + char str[IPC_MAX_LINE_LEN+1]; + Ipc_Status_t status; + + if(g_ipc.errchk_sent) + return(IPC_STATUS_OK); + + if(g_ipc.syntax_error) + sprintf(str, "#ERRCHK NOGO"); + else + sprintf(str, "#ERRCHK GO"); + + g_ipc.errchk_sent = IPC_TRUE; + + status = ipc_send_line(str); + if(status != IPC_STATUS_OK) + return(status); + + return(ipc_flush()); +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_send_end + +This function sends either an ``>ENDANAL'' or an ``>ABORTED'' message +over the interprocess communication channel together with the +total CPU time used to indicate whether or not the simulation +completed normally. +*/ + + +Ipc_Status_t ipc_send_end() +{ + char str[IPC_MAX_LINE_LEN+1]; + Ipc_Status_t status; + + if(g_ipc.syntax_error || g_ipc.run_error) + sprintf(str, ">ABORTED %.4f", g_ipc.cpu_time); + else + sprintf(str, ">ENDANAL %.4f", g_ipc.cpu_time); + + status = ipc_send_line(str); + if(status != IPC_STATUS_OK) + return(status); + + return(ipc_flush()); +} + + +/*---------------------------------------------------------------------------*/ +int stuff_binary_v1 (d1, d2, n, buf, pos) + double d1, d2; /* doubles to be stuffed */ + int n; /* how many of d1, d2 ( 1 <= n <= 2 ) */ + char *buf; /* buffer to stuff to */ + int pos; /* index at which to stuff */ +{ + union { + float float_val[2]; + char ch[32]; + } trick; + int i, j; + + assert (protocol == IPC_PROTOCOL_V1); + assert (sizeof(float) == 4); + assert (sizeof(char) == 1); + assert ((n >= 1) && (n <= 2)); + + trick.float_val[0] = d1; + if (n > 1) { + trick.float_val[1] = d2; + } + for (i = 0, j = pos; i < n*sizeof(float); j++, i++) + buf[j] = trick.ch[i]; + i = sizeof(float)*n + pos; + buf[0] = 'A' + i - 1; + return i; +} + +/*---------------------------------------------------------------------------*/ + + +/* +ipc_send_double + +This function sends a double data value over the interprocess +communication channel preceded by a character string that +identifies the simulation variable. +*/ + +Ipc_Status_t ipc_send_double (tag, value) + char *tag; /* The node or instance */ + double value; /* The data value to send */ +{ + int i; + int len = 0; + int fmt_buffer_len; + + switch (protocol) { + case IPC_PROTOCOL_V1: + strcpy (fmt_buffer, " "); /* save room for the length byte */ + strcat (fmt_buffer, tag); + strcat (fmt_buffer, " "); + + /* If talking to Mentor tools, must force upper case for Mspice 7.0 */ + fmt_buffer_len = strlen(fmt_buffer); + for(i = 0; i < fmt_buffer_len; i++) { + if(islower(fmt_buffer[i])) + fmt_buffer[i] = toupper(fmt_buffer[i]); + } + + len = stuff_binary_v1 (value, 0.0, 1, fmt_buffer, strlen(fmt_buffer)); + break; + case IPC_PROTOCOL_V2: + break; + } + return ipc_send_line_binary (fmt_buffer, len); +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_send_complex + +This function sends a complex data value over the interprocess +communication channel preceded by a character string that +identifies the simulation variable. +*/ + + +Ipc_Status_t ipc_send_complex (tag, value) + char *tag; /* The node or instance */ + Ipc_Complex_t value; /* The data value to send */ +{ + int i; + int len=0; + int fmt_buffer_len; + + switch (protocol) { + case IPC_PROTOCOL_V1: + strcpy (fmt_buffer, " "); /* save room for the length byte */ + strcat (fmt_buffer, tag); + strcat (fmt_buffer, " "); + + /* If talking to Mentor tools, must force upper case for Mspice 7.0 */ + fmt_buffer_len = strlen(fmt_buffer); + for(i = 0; i < fmt_buffer_len; i++) { + if(islower(fmt_buffer[i])) + fmt_buffer[i] = toupper(fmt_buffer[i]); + } + + len = stuff_binary_v1 (value.real, value.imag, 2, fmt_buffer, + strlen(fmt_buffer)); + break; + case IPC_PROTOCOL_V2: + break; + } + return ipc_send_line_binary (fmt_buffer, len); +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_send_event + +This function sends data from an event-driven node over the interprocess +communication channel. The data is sent only if the IPC is configured +for UNIX sockets, indicating use with the V2 ATESSE SI process. +*/ + + +Ipc_Status_t ipc_send_event(ipc_index, step, plot_val, print_val, ipc_val, len) + int ipc_index; /* Index used in EVTDICT */ + double step; /* Analysis point or timestep (0.0 for DC) */ + double plot_val; /* The value for plotting purposes */ + char *print_val; /* The value for printing purposes */ + void *ipc_val; /* The binary representation of the node data */ + int len; /* The length of the binary representation */ +{ +#ifdef IPC_AEGIS_MAILBOXES + return IPC_STATUS_OK; +#else + char buff[OUT_BUFFER_SIZE]; + int i; + int buff_len; + char *buff_ptr; + char *temp_ptr; + float fvalue; + + /* Report error if size of data is too big for IPC channel block size */ + if((len + strlen(print_val) + 100) >= OUT_BUFFER_SIZE) { + printf("ERROR - Size of event-driven data too large for IPC channel\n"); + return IPC_STATUS_ERROR; + } + + /* Place the index into the buffer with a trailing space */ + sprintf(buff, "%d ", ipc_index); + + assert(sizeof(float) == 4); + assert(sizeof(int) == 4); + + /* Put the analysis step bytes in */ + buff_len = strlen(buff); + buff_ptr = buff + buff_len; + fvalue = step; + temp_ptr = (char *) &fvalue; + for(i = 0; i < 4; i++) { + *buff_ptr = temp_ptr[i]; + buff_ptr++; + buff_len++; + } + + /* Put the plot value in */ + fvalue = plot_val; + temp_ptr = (char *) &fvalue; + for(i = 0; i < 4; i++) { + *buff_ptr = temp_ptr[i]; + buff_ptr++; + buff_len++; + } + + /* Put the length of the binary representation in */ + temp_ptr = (char *) &len; + for(i = 0; i < 4; i++) { + *buff_ptr = temp_ptr[i]; + buff_ptr++; + buff_len++; + } + + /* Put the binary representation bytes in last */ + temp_ptr = ipc_val; + for(i = 0; i < len; i++) + buff_ptr[i] = temp_ptr[i]; + buff_ptr += len; + buff_len += len; + + /* Put the print value in */ + strcpy(buff_ptr, print_val); + buff_ptr += strlen(print_val); + buff_len += strlen(print_val); + + /* Send the data to the IPC channel */ + return ipc_send_line_binary(buff, buff_len); + +#endif +} + + diff --git a/src/xspice/ipc/ipcaegis.c b/src/xspice/ipc/ipcaegis.c new file mode 100755 index 000000000..c86cb7216 --- /dev/null +++ b/src/xspice/ipc/ipcaegis.c @@ -0,0 +1,307 @@ +/*============================================================================ +FILE IPCaegis.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Steve Tynor + +MODIFICATIONS + + + +SUMMARY + + Provides compatibility for the new XSPICE simulator to both the MSPICE user + interface and BCP via ATESSE v.1 style AEGIS mailboxes. + +INTERFACES + + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +#ifdef IPC_AEGIS_MAILBOXES + +#include +#include +#include +#include +#include +#include + +#include "ipc.h" + + +typedef unsigned char Buffer_char_t; + +static status_$t status; +typedef enum { + IPC_MBX_UNINITIALIZED, + IPC_MBX_INITIALIZED, + IPC_MBX_CONNECTED_TO_CLIENT, +} Ipc_Mbx_State_t; + +static void *mbx_handle; +static Ipc_Mbx_State_t mbx_state = IPC_MBX_UNINITIALIZED; +static mbx_$server_msg_t mbx_send_msg_buf; +static mbx_$server_msg_t mbx_recieve_msg_buf; +static mbx_$server_msg_t *mbx_ret_ptr; +static int mbx_ret_len; +static short mbx_chan; + +#include "ipcproto.h" + +/*---------------------------------------------------------------------------*/ + +/* +ipc_transport_initialize_server + +This function creates an Aegis mailbox, and if successful, +calls ipc_get_line to wait for the first record sent which is +assumed to be the batch output filename. +*/ + + + +Ipc_Status_t ipc_transport_initialize_server (server_name, m, p, + batch_filename) + char *server_name; /* The mailbox pathname */ + Ipc_Mode_t m; /* Mode - interactive or batch */ + Ipc_Protocol_t p; /* Protocol type */ + char *batch_filename; /* Batch filename returned */ +{ + int len; + // extern void *malloc(); + + assert (p == IPC_PROTOCOL_V1); + + mbx_$create_server (server_name, strlen (server_name), mbx_$serv_msg_max, + 1, &mbx_handle, &status); + + if (status.all != status_$ok) { + fprintf (stderr, + "ERROR: IPC: Error creating mailbox server \"%s\"\n", + server_name); + error_$print (status); + mbx_state = IPC_MBX_UNINITIALIZED; + return IPC_STATUS_ERROR; + } else { + mbx_state = IPC_MBX_INITIALIZED; + /* + * First record is the name of the batch filename - whether we're in + * batch mode or not: + */ + return ipc_get_line (batch_filename, &len, IPC_WAIT); + } + /* + * shouldn't get here + */ + assert (0); + return IPC_STATUS_ERROR; +} +/*---------------------------------------------------------------------------*/ +Ipc_Status_t extract_msg (str, len) + char *str; + int *len; +{ + *len = mbx_ret_len - mbx_$serv_msg_hdr_len; + assert (*len >= 0); + + /* + * null terminate before copy: + */ + mbx_ret_ptr->data [*len] = '\0'; + strcpy (str, mbx_ret_ptr->data); + + return IPC_STATUS_OK; +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_transport_get_line + +This function reads data sent by a client over the mailbox +channel. It also handles the initial opening of the +mailbox channel when requested by a client. +*/ + + + +Ipc_Status_t ipc_transport_get_line (str, len, wait) + char *str; /* The string text read from IPC channel */ + int *len; /* The length of str */ + Ipc_Wait_t wait; /* Blocking or non-blocking */ +{ + if (mbx_state == IPC_MBX_UNINITIALIZED) { + fprintf (stderr, + "ERROR: IPC: Attempted to read from non-initialized mailbox\n"); + return IPC_STATUS_ERROR; + } + + assert ((mbx_state == IPC_MBX_CONNECTED_TO_CLIENT) || + (mbx_state == IPC_MBX_INITIALIZED)); + + do { + if (wait == IPC_WAIT) { + mbx_$get_rec (mbx_handle, &mbx_recieve_msg_buf, mbx_$serv_msg_max, + &mbx_ret_ptr, &mbx_ret_len, &status); + } else { + mbx_$get_conditional (mbx_handle, &mbx_recieve_msg_buf, + mbx_$serv_msg_max, &mbx_ret_ptr, &mbx_ret_len, + &status); + if (status.all == mbx_$channel_empty) { + return IPC_STATUS_NO_DATA; + } + } + + if (status.all != status_$ok) { + fprintf (stderr, "ERROR: IPC: Error reading from mailbox\n"); + error_$print (status); + return IPC_STATUS_ERROR; + } + + switch (mbx_ret_ptr->mt) { + case mbx_$channel_open_mt: + if (mbx_state == IPC_MBX_CONNECTED_TO_CLIENT) { + /* + * we're already connected to a client... refuse the connection + */ + mbx_send_msg_buf.mt = mbx_$reject_open_mt; + } else { + mbx_send_msg_buf.mt = mbx_$accept_open_mt; + mbx_state = IPC_MBX_CONNECTED_TO_CLIENT; + } + mbx_send_msg_buf.cnt = mbx_$serv_msg_hdr_len; + mbx_chan = mbx_ret_ptr->chan; + mbx_send_msg_buf.chan = mbx_chan; + + mbx_$put_rec (mbx_handle, &mbx_send_msg_buf, mbx_$serv_msg_hdr_len, + &status); + + if (status.all != status_$ok) { + fprintf (stderr, "ERROR: IPC: Error writing to mailbox\n"); + error_$print (status); + return IPC_STATUS_ERROR; + } + + /* + * check to see if there was a message buried in the open request: + */ + if (mbx_ret_len > mbx_$serv_msg_hdr_len) { + return extract_msg (str, len); + } + break; + case mbx_$eof_mt: + mbx_chan = mbx_ret_ptr->chan; + mbx_$deallocate(mbx_handle, mbx_chan, &status); + + if (status.all != status_$ok) { + fprintf (stderr, "ERROR: IPC: Error deallocating mailbox\n"); + error_$print (status); + return IPC_STATUS_ERROR; + } + + mbx_state = IPC_MBX_INITIALIZED; + return IPC_STATUS_EOF; + break; + case mbx_$data_mt: + assert (mbx_state == IPC_MBX_CONNECTED_TO_CLIENT); + return extract_msg (str, len); + break; + case mbx_$data_partial_mt: + fprintf (stderr, "ERROR: IPC: Recieved partial data message - ignored\n"); + break; + default: + fprintf (stderr, "ERROR: IPC: Bad message type (0x%x) recieved\n", + mbx_ret_ptr->mt); + } + } while (1); + return IPC_STATUS_ERROR; +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_transport_terminate_server + +This function calls ipc\_transport\_get\_line until it +receives an EOF from the client, which concludes the +communication. +*/ + + +Ipc_Status_t ipc_transport_terminate_server () +{ + char buffer[300]; + int len; + Ipc_Status_t status; + + do { + status = ipc_transport_get_line (buffer, &len, IPC_WAIT); + } while ((status =! IPC_STATUS_ERROR) && + (status =! IPC_STATUS_EOF)); + return status; +} + +/*---------------------------------------------------------------------------*/ + +/* +ipc_transport_send_line + +This function sends a message to the current client through +the mailbox channel. +*/ + + +Ipc_Status_t ipc_transport_send_line (str, len) + char *str; /* The bytes to send */ + int len; /* The number of bytes from str to send */ +{ + long cnt; + + if (mbx_state != IPC_MBX_CONNECTED_TO_CLIENT) { + fprintf (stderr, + "ERROR: IPC: Attempted to write to non-open mailbox\n"); + return IPC_STATUS_ERROR; + } + + mbx_send_msg_buf.mt = mbx_$data_mt; + if (mbx_$serv_msg_hdr_len + len > mbx_$serv_msg_max) { + fprintf (stderr, + "ERROR: IPC: send_line message too long - truncating\n"); + len = mbx_$serv_msg_max - mbx_$serv_msg_hdr_len; + } + + mbx_send_msg_buf.cnt = mbx_$serv_msg_hdr_len + len; + mbx_send_msg_buf.chan = mbx_chan; + memcpy (mbx_send_msg_buf.data, str, len); + + cnt = mbx_send_msg_buf.cnt; + mbx_$put_rec (mbx_handle, &mbx_send_msg_buf, cnt, &status); + + if (status.all != status_$ok) { + fprintf (stderr, "ERROR: IPC: Error writing to mailbox\n"); + error_$print (status); + return IPC_STATUS_ERROR; + } + return IPC_STATUS_OK; +} + +#endif /* IPC_AEGIS_MAILBOXES */ diff --git a/src/xspice/ipc/ipcsockets.c b/src/xspice/ipc/ipcsockets.c new file mode 100755 index 000000000..8c4efeba9 --- /dev/null +++ b/src/xspice/ipc/ipcsockets.c @@ -0,0 +1,744 @@ +/*============================================================================= + + FILE IPCsockets.c + + Copyright 1991 + Georgia Tech Research Corporation, Atlanta, Georgia 30332 + All Rights Reserved + + + PROJECT ATESSE A-8503 + + AUTHOR + Stefan Roth July 1991 + + MODIFICATIONS + none + + SUMMARY + Generic Interprocess Communication module + Provides compatibility for the new SPICE simulator to both the MSPICE user + interface and BCP (via ATESSE v.1 style AEGIS mailboxes) and the new ATESSE + v.2 Simulator Interface and BCP (via BSD Sockets). This file contains the + BSD sockets version. + The Simulator is the server, while the SI and BCP will be the clients. + + + INTERFACES + + FILE ROUTINE CALLED + + IPC.c ipc_get_line(); + + + REFERENCED FILES + + Outputs to stderr. + + +=============================================================================*/ + + +/*============================================================================= + + DESCRIPTION OF FUNCTIONALITY: + + Outline of Initialize_Server function: + create socket; + bind name to socket; + getsockname; + listen; + sock_state = IPC_SOCK_INITIALIZED; + return ipc_get_line (); + + + Format of a message line: + bytes description + ----- ------------------- + 0 recognition character for beginning of line; value is BOL_CHAR. + 1-4 message length (not including bytes 0-4); 32 bits in htonl + format; + if value = -1, then EOF and socket should be closed. + 5-N+5 message body of length specified in bytes 1-4. + + The bytes before the message body are the message header. The header + length is specified as SOCK_MSG_HDR_LEN bytes. + + + Outline of Get_Line function: + read 5 characters; + verify that first char is BOL_CHAR; + interpret message length (N) from bytes 1-4; + do error checking on message header bytes; + read N characters as message body; + do error checking on message body read; + + + Outline of Send_Line function: + write BOL_CHAR; + write 4-byte message body length + write message body (N bytes) + do error checking after each write operation + + + Outline of Terminate_Server function: + Continue to read lines (with ipc_transport_get_line) and ignore + them until socket EOF is reached; + Close the socket. + + +=============================================================================*/ + + +/*#ifdef IPC_UNIX_SOCKETS */ + +/*=== INCLUDE FILES ===*/ +#include "ngspice.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ipc.h" +#include "ipctiein.h" + + + + +/*=== TYPE DEFINITIONS ===*/ + +typedef enum { + IPC_SOCK_UNINITIALIZED, + IPC_SOCK_INITIALIZED, + IPC_SOCK_CONNECTED_TO_CLIENT +} Ipc_Sock_State_t; + + +/*=== LOCAL VARIABLES ===*/ + +static int sock_desc; /* socket descriptor */ +static int msg_stream; /* socket stream */ +static Ipc_Sock_State_t sock_state = IPC_SOCK_UNINITIALIZED; + + +/*=== INCLUDE FILES ===*/ + +#include "ipcproto.h" + +/*============================================================================= + +FUNCTION ipc_transport_initialize_server + +AUTHORS + + July 1991 Stefan Roth + +MODIFICATIONS + + NONE + +SUMMARY + + Creates and opens the BSD socket of the server. Listens for requests + by a client and then reads the first line message. + +INTERFACES + + Called by: (IPC.c) ipc_initialize_server(); + +RETURNED VALUE + + Ipc_Status_t - returns status of the socket connection. + +GLOBAL VARIABLES + + NONE + +NON-STANDARD FEATURES + + NONE + +=============================================================================*/ + +Ipc_Status_t ipc_transport_initialize_server (server_name, mode, protocol, + batch_filename) + char *server_name; /* not used */ + Ipc_Mode_t mode; /* not used */ + Ipc_Protocol_t protocol; /* IN - only used in assert */ + char *batch_filename; /* OUT - returns a value */ + /* Note that unused parameters are required to maintain compatibility */ + /* with version 1 (mailboxes) functions of the same names. */ +{ + struct sockaddr_in server; /* Server specifications for socket*/ + int server_length; /* Size of server structure */ + unsigned int port_num; /* Port number converted from server_name */ + + Ipc_Status_t ipc_get_line (); + + /* assert (protocol == IPC_PROTOCOL_V2); */ /* allow v1 protocol - wbk */ + assert (sock_state == IPC_SOCK_UNINITIALIZED); + + /* convert server_name (from atesse_xspice invocation line) to a port */ + /* number */ + port_num = atoi(server_name); + if((port_num > 0) && (port_num < 1024)) { + /* Reserved port number */ + perror ("ERROR: IPC Port numbers below 1024 are reserved"); + sock_state = IPC_SOCK_UNINITIALIZED; + return IPC_STATUS_ERROR; + } + + + sock_desc = socket (AF_INET, SOCK_STREAM, 0); + + if (sock_desc < 0) { + /* Unsuccessful socket opening */ + perror ("ERROR: IPC Creating socket"); + sock_state = IPC_SOCK_UNINITIALIZED; + return IPC_STATUS_ERROR; + } + + /* Socket opened successfully */ + + server.sin_family = AF_INET; + server.sin_addr.s_addr = INADDR_ANY; + server.sin_port = port_num; /* SOCKET_PORT; */ + + server_length = sizeof (server); + if (bind (sock_desc, (struct sockaddr *)&server, server_length) + < 0) { + fprintf (stderr, "ERROR: IPC: Bind unsuccessful\n"); + perror ("ERROR: IPC"); + sock_state = IPC_SOCK_UNINITIALIZED; + return IPC_STATUS_ERROR; + } + + if (getsockname (sock_desc, (struct sockaddr *)&server, &server_length) + < 0) { + fprintf (stderr, "ERROR: IPC: getting socket name\n"); + perror ("ERROR: IPC"); + sock_state = IPC_SOCK_UNINITIALIZED; + return IPC_STATUS_ERROR; + } + + fprintf (stderr, "Socket port %d.\n", ntohs(server.sin_port)); + + listen (sock_desc, 5); + + sock_state = IPC_SOCK_INITIALIZED; + + /* Socket ok to use now */ + + /* + * First record is the name of the batch filename if we're in batch mode. + */ + + if(g_ipc.mode == IPC_MODE_BATCH) { + int len; + return ipc_get_line (batch_filename, &len, IPC_WAIT); + } + + /* Return success */ + return IPC_STATUS_OK; + +} /* end ipc_transport_initialize_server */ + + + +/*============================================================================= + +FUNCTION bytes_to_integer + +AUTHORS + + July 1991 Stefan Roth + +MODIFICATIONS + + NONE + +SUMMARY + + Convert four bytes at START in the string STR + to a 32-bit unsigned integer. The string is assumed + to be in network byte order and the returned value + is converted to host byte order (with ntohl). + +INTERFACES + + Local to this file. + Called by: ipc_transport_get_line(); + +RETURNED VALUE + + u_long - unsigned 32 bit integer + +GLOBAL VARIABLES + + NONE + +NON-STANDARD FEATURES + + NONE + +=============================================================================*/ + +static u_long bytes_to_integer (str, start) + char *str; /* IN - string that contains the bytes to convert */ + int start; /* IN - index into string where bytes are */ +{ + u_long u; /* Value to be returned */ + char buff[4]; /* Transfer str into buff to word align reqd data */ + int index; /* Index into str and buff for transfer */ + + /* Get the str+start character and cast it into a u_long and put + the value through the network-to-host-short converter and store + it in the variable u. */ + + index = 0; + while (index < sizeof(u)) { + buff[index] = str[index+start]; + index++; + } + u = ntohl (*((u_long *) buff)); + + return u; +} /* end bytes_to_integer */ + + + +/*============================================================================= + +FUNCTION handle_socket_eof + +AUTHORS + + July 1991 Stefan Roth + +MODIFICATIONS + + NONE + +SUMMARY + + Do processing when the socket reaches EOF or when a message from the + client states that EOF has been reached. + +INTERFACES + + Local to this file. + Called by: ipc_transport_get_line(); + +RETURNED VALUE + + Ipc_Status_t - always IPC_STATUS_EOF + +GLOBAL VARIABLES + + NONE + +NON-STANDARD FEATURES + + NONE + +=============================================================================*/ + + +static Ipc_Status_t handle_socket_eof () +{ + close (msg_stream); + close (sock_desc); + + sock_state = IPC_SOCK_UNINITIALIZED; + + return IPC_STATUS_EOF; +} /* handle_socket_eof */ + + + +/*============================================================================= + +FUNCTION read_sock + +AUTHORS + + July 1991 Stefan Roth + +MODIFICATIONS + + NONE + +SUMMARY + + Read N bytes from a socket. Only returns when the read had an error, + when 0 bytes (EOF) could be read, or LENGTH bytes are read. + +INTERFACES + + Local to this file. + Called by: ipc_transport_get_line(); + +RETURNED VALUE + + int - Returns the total number of bytes read. + +GLOBAL VARIABLES + + NONE + +NON-STANDARD FEATURES + + NONE + +=============================================================================*/ + + +static int read_sock (stream, buffer, length, wait, flags) + int stream; /* IN - Socket stream */ + char *buffer; /* OUT - buffer to store incoming data */ + int length; /* IN - Number of bytes to be read */ + Ipc_Wait_t wait; /* IN - type of read operation */ + int flags; /* IN - Original socket flags for blocking read */ +{ + int count; /* Number of bytes read with last `read` */ + int totalcount; /* total number of bytes read */ + char *buf2; + +/* count = 0; */ +/* while (count < length) { */ +/* buffer[count] = 'x'; */ +/* count++; */ +/* } */ + count = read (stream, buffer, length); + if (wait == IPC_NO_WAIT) { + fcntl (stream, F_SETFL, flags); /* Revert to blocking read */ + } + if ((count <= 0) || (count == length)) { + /* If error or if read in reqd number of bytes: */ + return count; + } else { + /* Only got some of the bytes requested */ + totalcount = count; + buf2 = &buffer[totalcount]; + length = length - count; + while (length > 0) { + count = read (stream, buf2, length); + if (count <= 0) /* EOF or read error */ + break; + totalcount = totalcount + count; + buf2 = &buffer[totalcount]; + length = length - count; + } + if (length != 0) { + fprintf (stderr, "WARNING: READ_SOCK read %d bytes instead of %d\n", + totalcount, totalcount + length); + } + return totalcount; + } +} /* end read_sock */ + + + +/*============================================================================= + +FUNCTION ipc_transport_get_line + +AUTHORS + + July 1991 Stefan Roth + +MODIFICATIONS + + NONE + +SUMMARY + + Main function for reading one line from a socket. Requires that the + socket be open. Lines are mostly SPICE code, but commands may also + be embedded in the socket data and they are interpreted by this function. + Therefore, this function may cause the socket to be closed. + +INTERFACES + + Called by: ipc_transport_terminate_server(); + (IPC.c) ipc_get_line(); + +RETURNED VALUE + + Ipc_Status_t - returns status of the read operation + +GLOBAL VARIABLES + + NONE + +NON-STANDARD FEATURES + + NONE + +=============================================================================*/ + + +Ipc_Status_t ipc_transport_get_line (str, len, wait) + char *str; /* returns the result, null terminated */ + int *len; /* length of str passed IN and passed OUT */ + Ipc_Wait_t wait; /* IN - wait or dont wait on incoming msg */ +{ + int count; /* number of bytes read */ + int message_length; /* extracted from message header */ + + if (sock_state == IPC_SOCK_UNINITIALIZED) { + fprintf (stderr, + "ERROR: IPC: Attempted to read from uninitialized socket\n"); + return IPC_STATUS_ERROR; + } + + assert ((sock_state == IPC_SOCK_CONNECTED_TO_CLIENT) || + (sock_state == IPC_SOCK_INITIALIZED)); + + if (sock_state == IPC_SOCK_INITIALIZED) { + /* We have an open socket but have not connected to a client. */ + /* Accept a connection from a client. */ + msg_stream = accept (sock_desc, (struct sockaddr *)0, (int *)0); + + if (msg_stream == -1) { + fprintf (stderr, "ERROR: IPC: Server accepting request\n"); + perror ("ERROR: IPC"); + return IPC_STATUS_ERROR; + } + sock_state = IPC_SOCK_CONNECTED_TO_CLIENT; + } + /*-----------------------------------------------------------------------*/ + /* First read in the message header. */ + { + int flags; + flags = fcntl(msg_stream, F_GETFL, NULL); /* Blocking read mode */ + + if (wait == IPC_WAIT) { + /* Block here and wait for the next message */ + count = read_sock (msg_stream, str, SOCK_MSG_HDR_LEN, wait, flags); + if (count == 0) { + /* EOF, will this ever happen? */ + /* fprintf (stderr, "WARNING: IPC: Reached eof on socket\n"); */ + return handle_socket_eof (); + } + } else if (wait == IPC_NO_WAIT) { + /* Read message, but do not wait if none available. */ + + fcntl (msg_stream, F_SETFL, flags | O_NDELAY); + count = read_sock (msg_stream, str, SOCK_MSG_HDR_LEN, wait, flags); + + if (count == 0) { + /* EOF, will this ever happen? */ + /* fprintf (stderr, "WARNING: IPC: Reached eof on socket\n"); */ + return handle_socket_eof (); + } else if (count == -1) { + if (errno == EWOULDBLOCK) { + return IPC_STATUS_NO_DATA; + } + } + + } else { + /* Serious problem, since it is not reading anything. */ + fprintf (stderr, + "ERROR: IPC: invalid wait arg to ipc_transport_get_line\n"); + } + } + + /* Do more error checking on the read in values of the message header: */ + if (count == -1) { + fprintf (stderr, "ERROR: IPC: Reading from socket\n"); + perror ("ERROR: IPC"); + return IPC_STATUS_ERROR; + } else if (str[0] != BOL_CHAR) { + fprintf (stderr, + "ERROR: IPC: Did not find beginning of message header (%c)\n", + str[0]); + return IPC_STATUS_ERROR; + } else if ((message_length = bytes_to_integer (str, 1)) == -1) { + /* fprintf (stderr, "WARNING: IPC: Reached eof on socket\n"); */ + return handle_socket_eof (); + } else if (message_length == 0) { + *len = 0; + return IPC_STATUS_NO_DATA; + +/* Invalid test... delete - wbk + } else if (message_length > *len) { + fprintf (stderr, + "ERROR: IPC: Buffer (%d) is too short for message (%d)\n", + *len, message_length); + return IPC_STATUS_ERROR; +*/ + + } + + /*-----------------------------------------------------------------------*/ + /* Now read in the message body. */ + /* Always block here since the message header was already read and */ + /* we must get the body. */ + + *len = message_length; + count = read_sock (msg_stream, str, message_length); + if (count == 0) { + /* EOF, will this ever happen? */ + /* fprintf (stderr, */ + /* "WARNING: IPC: Reached eof in message body on socket\n");*/ + return handle_socket_eof (); + } else if (count == -1) { + fprintf (stderr, "ERROR: IPC: reading message body from socket\n"); + perror ("ERROR: IPC"); + return IPC_STATUS_ERROR; + } + + /* Looks like we have a valid message here. Put in the string terminator. */ + *len = count; + str[count] = '\0'; + + return IPC_STATUS_OK; + +} /* end ipc_transport_get_line */ + + + +/*============================================================================= + +FUNCTION ipc_transport_send_line + +AUTHORS + + July 1991 Stefan Roth + +MODIFICATIONS + + NONE + +SUMMARY + Send a line of information. First sends a message header and + then the actual message body. + Error checking is done to make reasonably sure that the data was sent. + + +INTERFACES + + Called by: (IPC.c) ipc_flush (); + +RETURNED VALUE + + Ipc_Status_t - returns status of the send operation (typically + IPC_STATUS_ERROR or IPC_STATUS_OK). + + +GLOBAL VARIABLES + + NONE + +NON-STANDARD FEATURES + + NONE + +=============================================================================*/ + + +Ipc_Status_t ipc_transport_send_line (str, len) + char *str; /* IN - String to write */ + int len; /* IN - Number of characters out of STR to write */ +{ + int count; /* Counts how many bytes were actually written */ + u_long u; /* 32-bit placeholder for transmission of LEN */ + char hdr_buff[5]; /* Buffer for building header message in */ + int i; /* Temporary counter */ + char *char_ptr; /* Pointer for int to bytes conversion */ + + if (sock_state != IPC_SOCK_CONNECTED_TO_CLIENT) { + fprintf (stderr, "ERROR: IPC: Attempt to write to non-open socket\n"); + return IPC_STATUS_ERROR; + } + + /* Write message body header with length: */ + hdr_buff[0] = BOL_CHAR; + u = htonl (len); + char_ptr = (char *) &u; + for(i = 0; i < 4; i++) + hdr_buff[i+1] = char_ptr[i]; + + count = write (msg_stream, hdr_buff, 5); + if (count != 5) { + fprintf (stderr, "ERROR: IPC: (%d) send line error 1\n", count); + return IPC_STATUS_ERROR; + } + + /* Write message body: */ + count = write (msg_stream, str, len); + if (count != len) { + fprintf (stderr, "ERROR: IPC: (%d) send line error 2\n", count); + return IPC_STATUS_ERROR; + } + + return IPC_STATUS_OK; +} /* end ipc_transport_send_line */ + + + +/*============================================================================= + +FUNCTION ipc_transport_terminate_server + +AUTHORS + + July 1991 Stefan Roth + +MODIFICATIONS + + NONE + +SUMMARY + + This function reads all pending incoming messages and discards them. + Reading continues until a read error occurs or EOF is reached, at which + time the socket is closed. + Note that this function does not actually close the socket. This is + done in ipc_transport_get_line, which is called in this function. + + In this function, the incoming line length is limited. See buffer below. + +INTERFACES + + Called by: (IPC.c) ipc_terminate_server(); + +RETURNED VALUE + + Ipc_Status_t - returns status of last read operation (always + IPC_STATUS_ERROR or IPC_STATUS_EOF). + +GLOBAL VARIABLES + + NONE + +NON-STANDARD FEATURES + + NONE + +=============================================================================*/ + + +Ipc_Status_t ipc_transport_terminate_server () +{ + char buffer[17000]; /* temp buffer for incoming data */ + int len; /* placeholder var to as arg to function */ + Ipc_Status_t status; /* value to be returned from function */ + int max_size; /* Max length of buffer */ + + max_size = sizeof (buffer); + do { + len = max_size; + status = ipc_transport_get_line (buffer, &len, IPC_WAIT); + } while ((status != IPC_STATUS_ERROR) && + (status != IPC_STATUS_EOF)); + return status; +} + +/*#endif IPC_UNIX_SOCKETS */ diff --git a/src/xspice/ipc/ipcstdio.c b/src/xspice/ipc/ipcstdio.c new file mode 100755 index 000000000..52598b240 --- /dev/null +++ b/src/xspice/ipc/ipcstdio.c @@ -0,0 +1,69 @@ +/* + * Steve Tynor + * + * Generic Interprocess Communication module + * + * Used for debugging in absense of IPC interface. + * + */ + +//#include + +#ifdef IPC_DEBUG_VIA_STDIO + +#include + + +#include "ipc.h" + +#include "ipcproto.h" + +#include /* 12/1/97 jg */ + +/*---------------------------------------------------------------------------*/ +Ipc_Status_t ipc_transport_initialize_server (server_name, m, p, + batch_filename) + char *server_name; + Ipc_Mode_t m; + Ipc_Protocol_t p; + char *batch_filename; +{ + assert (m == IPC_MODE_INTERACTIVE); + printf ("INITIALIZE_SERVER\n"); + return IPC_STATUS_OK; +} + +/*---------------------------------------------------------------------------*/ +Ipc_Status_t ipc_transport_get_line (str, len, wait) + char *str; + int *len; + Ipc_Wait_t wait; +{ + printf ("GET_LINE\n"); + gets (str); + *len = strlen (str); + return IPC_STATUS_OK; +} + +/*---------------------------------------------------------------------------*/ +Ipc_Status_t ipc_transport_send_line (str, len) + char *str; + int len; +{ + int i; + + printf ("SEND_LINE: /"); + for (i = 0; i < len; i++) + putchar (str[i]); + printf ("/\n"); + return IPC_STATUS_OK; +} + +/*---------------------------------------------------------------------------*/ +Ipc_Status_t ipc_transport_terminate_server () +{ +return IPC_STATUS_OK; +} + + +#endif /* IPC_DEBUG_VIA_STDIO */ diff --git a/src/xspice/ipc/ipctiein.c b/src/xspice/ipc/ipctiein.c new file mode 100755 index 000000000..2980241ab --- /dev/null +++ b/src/xspice/ipc/ipctiein.c @@ -0,0 +1,530 @@ +/*============================================================================ +FILE IPCtiein.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + Provides a protocol independent interface between the simulator + and the IPC method used to interface to CAE packages. + +INTERFACES + + g_ipc (global variable) + + ipc_handle_stop() + ipc_handle_returni() + ipc_handle_mintime() + ipc_handle_vtrans() + ipc_send_stdout() + ipc_send_stderr() + ipc_send_std_files() + ipc_screen_name() + ipc_get_devices() + ipc_free_devices() + ipc_check_pause_stop() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + + + +#include "ngspice.h" +#include +#include +#include +//#include "util.h" +#include "inpdefs.h" +#include "gendefs.h" +#include "cktdefs.h" +#include "bjt/bjtdefs.h" +#include "jfet/jfetdefs.h" +#include "mos1/mos1defs.h" +#include "mos2/mos2defs.h" +#include "mos3/mos3defs.h" +#include "mifproto.h" +#include "ipc.h" +#include "ipctiein.h" + + + +/* +Global variable g_ipc is used by the SPICE mods that take care of +interprocess communications activities. +*/ + + +Ipc_Tiein_t g_ipc = { + IPC_FALSE, /* enabled */ + IPC_MODE_INTERACTIVE, /* mode */ + IPC_ANAL_DCOP, /* analysis mode */ + IPC_FALSE, /* parse_error */ + IPC_FALSE, /* run_error */ + IPC_FALSE, /* errchk_sent */ + IPC_FALSE, /* returni */ + 0.0, /* mintime */ + 0.0, /* lasttime */ + 0.0, /* cpu time */ + NULL, /* send array */ + NULL, /* log file */ + { /* vtrans struct */ + 0, /* size */ + NULL, /* vsrc_name array */ + NULL, /* device_name array */ + }, + IPC_FALSE, /* stop analysis */ +}; + + + +/* +ipc_handle_stop + +This function sets a flag in the g_ipc variable to signal that +a stop message has been received over the IPC channel. +*/ + +void ipc_handle_stop(void) +{ + g_ipc.stop_analysis = IPC_TRUE; +} + + +/* +ipc_handle_returni + +This function sets a flag in the g_ipc variable to signal that +a message has been received over the IPC channel specifying that +current values are to be returned in the results data sets. +*/ + +void ipc_handle_returni(void) +{ + g_ipc.returni = IPC_TRUE; +} + + +/* +ipc_handle_mintime + +This function sets a value in the g_ipc variable that specifies +how often data is to be returned as it is computed. If the +simulator takes timestep backups, data may still be returned +more often that that specified by 'mintime' so that glitches +are not missed. +*/ + +void ipc_handle_mintime(double time) +{ + g_ipc.mintime = time; +} + + + +/* +ipc_handle_vtrans + +This function processes arguments from a #VTRANS card received over +the IPC channel. The data on the card specifies that a particular +zero-valued voltage source name should be translated to the specified +instance name for which it was setup to monitor currents. +*/ + +void ipc_handle_vtrans( + char *vsrc, /* The name of the voltage source to be translated */ + char *dev) /* The device name the vsource name should be translated to */ +{ + int i; + int size; + + + if(g_ipc.vtrans.size == 0) { + g_ipc.vtrans.size = 1; + g_ipc.vtrans.vsrc_name = (void *) MALLOC(sizeof(char *)); + g_ipc.vtrans.device_name = (void *) MALLOC(sizeof(char *)); + g_ipc.vtrans.vsrc_name[0] = MIFcopy(vsrc); + g_ipc.vtrans.device_name[0] = MIFcopy(dev); + } + else { + g_ipc.vtrans.size++; + + size = g_ipc.vtrans.size; + i = g_ipc.vtrans.size - 1; + + g_ipc.vtrans.vsrc_name = (void *) REALLOC(g_ipc.vtrans.vsrc_name, + size * sizeof(char *)); + g_ipc.vtrans.device_name = (void *) REALLOC(g_ipc.vtrans.device_name, + size * sizeof(char *)); + g_ipc.vtrans.vsrc_name[i] = MIFcopy(vsrc); + g_ipc.vtrans.device_name[i] = MIFcopy(dev); + } +} + + + +/* +ipc_send_stdout + +This function sends the data written to stdout over the IPC channel. +This stream was previously redirected to a temporary file during +the simulation. +*/ + +void ipc_send_stdout(void) +{ + int c; + int len; + + char buf[IPC_MAX_LINE_LEN+1]; + + /* rewind the redirected stdout stream */ + rewind(stdout); + + /* Begin reading from the top of file and send lines */ + /* over the IPC channel. */ + + /* Don't send newlines. Also, if line is > IPC_MAX_LINE_LEN chars */ + /* we must wrap it because Mspice can't handle it */ + + len = 0; + while( (c=fgetc(stdout)) != EOF) { + if(c != '\n') { + buf[len] = c; + len++; + } + if((c == '\n') || (len == IPC_MAX_LINE_LEN)) { + buf[len] = '\0'; + ipc_send_line(buf); + len = 0; + } + } + if(len > 0) { + buf[len] = '\0'; + ipc_send_line(buf); + } + + /* Finally, rewind file again to discard the data already sent */ + rewind(stdout); +} + + +/* +ipc_send_stderr + +This function sends the data written to stderr over the IPC channel. +This stream was previously redirected to a temporary file during +the simulation. +*/ + +void ipc_send_stderr(void) +{ + int c; + int len; + + char buf[IPC_MAX_LINE_LEN+1]; + + /* rewind the redirected stderr stream */ + rewind(stderr); + + /* Begin reading from the top of file and send lines */ + /* over the IPC channel. */ + + /* Don't send newlines. Also, if line is > IPC_MAX_LINE_LEN chars */ + /* we must wrap it because Mspice can't handle it */ + + len = 0; + while( (c=fgetc(stderr)) != EOF) { + if(c != '\n') { + buf[len] = c; + len++; + } + if((c == '\n') || (len == IPC_MAX_LINE_LEN)) { + buf[len] = '\0'; + ipc_send_line(buf); + len = 0; + } + } + if(len > 0) { + buf[len] = '\0'; + ipc_send_line(buf); + } + + /* Finally, rewind file again to discard the data already sent */ + rewind(stderr); +} + + +/* +ipc_send_std_files + +This function sends the data written to stdout and stderr over the +IPC channel. These streams were previously redirected to temporary +files during the simulation. +*/ + +Ipc_Status_t ipc_send_std_files() +{ + ipc_send_stdout(); + ipc_send_stderr(); + + return(ipc_flush()); +} + + + +/* +ipc_screen_name + +This function screens names of instances and nodes to limit the +data returned over the IPC channel. +*/ + +Ipc_Boolean_t ipc_screen_name(char *name, char *mapped_name) +{ + char *endp; + int i; + int len; + long l; + + /* Return FALSE if name is in a subcircuit */ + for(i = 0; name[i] != '\0'; i++) { + if(name[i] == ':') + return(IPC_FALSE); + } + + /* Determine if name is numeric and what value is */ + l = strtol(name, &endp, 10); + + /* If numeric */ + if(*endp == '\0') { + /* Return FALSE if >100,000 -> added by ms_server in ATESSE 1.0 */ + if(l >= 100000) + return(IPC_FALSE); + /* Otherwise, copy name to mapped name and return true */ + else { + strcpy(mapped_name,name); + return(IPC_TRUE); + } + } + + /* If node is an internal node from a semiconductor (indicated by a */ + /* trailing #collector, #source, ...), do not return its current. */ + /* Otherwise, map to upper case and eliminate trailing "#branch" if any. */ + for(i = 0; name[i]; i++) { + if(name[i] == '#') { + if(strcmp(name + i, "#branch") == 0) + break; + else + return(IPC_FALSE); + } + else { + if(islower(name[i])) + mapped_name[i] = toupper(name[i]); + else + mapped_name[i] = name[i]; + } + } + mapped_name[i] = '\0'; + len = i; + + /* If len != 8 or 6'th char not equal to $, then doesn't need vtrans */ + /* Otherwise, translate to device name that it monitors */ + if(len != 8) + return(IPC_TRUE); + else if(name[5] != '$') + return(IPC_TRUE); + else { + /* Scan list of prefixes in VTRANS table and convert name */ + for(i = 0; i < g_ipc.vtrans.size; i++) { + if(strncmp(mapped_name, g_ipc.vtrans.vsrc_name[i], 5) == 0) { + strcpy(mapped_name, g_ipc.vtrans.device_name[i]); + return(IPC_TRUE); + } + } + return(IPC_TRUE); + } + + return(IPC_TRUE); +} + + + +/* +ipc_get_devices + +This function is used to setup the OUTinterface data structure that +determines what instances will have data returned over the IPC channel. +*/ + + +int ipc_get_devices( + void *circuit, /* The circuit structure */ + char *device, /* The device name as it appears in the info struct */ + char ***names, /* Array of name strings to be built */ + double **modtypes) /* Array of types to be built */ +{ + int index; + int num_instances; + GENmodel *model; + GENinstance *here; + CKTcircuit *ckt; + char *inst_name; + int inst_name_len; + int i; + + BJTmodel *BJTmod; + JFETmodel *JFETmod; + MOS1model *MOS1mod; + MOS2model *MOS2mod; + MOS3model *MOS3mod; + + /* Initialize local variables */ + ckt = (CKTcircuit *) circuit; + num_instances = 0; + + /* Get the index into the circuit structure linked list of models */ + index = INPtypelook(device); + + /* Iterate through all models of this type */ + for(model = ckt->CKThead[index]; model; model = model->GENnextModel) { + + /* Iterate through all instance of this model */ + for(here = model->GENinstances; here; here = here->GENnextInstance) { + + /* Get the name of the instance */ + inst_name = here->GENname; + inst_name_len = strlen(inst_name); + + /* Skip if it is a inside a subcircuit */ + for(i = 0; i < inst_name_len; i++) + if(inst_name[i] == ':') + break; + if(i < inst_name_len) + continue; + + /* Otherwise, add the name to the list */ + num_instances++; + if(num_instances == 1) + *names = (char **) MALLOC(sizeof(char *)); + else + *names = (char **) REALLOC(*names, num_instances * sizeof(char *)); + (*names)[num_instances-1] = MIFcopy(inst_name); + + /* Then get the type if it is a Q J or M */ + if(num_instances == 1) + *modtypes = (double *) MALLOC(sizeof(double)); + else + *modtypes = (double *) REALLOC((char *) *modtypes, + num_instances * sizeof(double)); + + if(strcmp(device,"BJT") == 0) { + BJTmod = (BJTmodel *) model; + (*modtypes)[num_instances-1] = BJTmod->BJTtype; + } + else if(strcmp(device,"JFET") == 0) { + JFETmod = (JFETmodel *) model; + (*modtypes)[num_instances-1] = JFETmod->JFETtype; + } + else if(strcmp(device,"Mos1") == 0) { + MOS1mod = (MOS1model *) model; + (*modtypes)[num_instances-1] = MOS1mod->MOS1type; + } + else if(strcmp(device,"Mos2") == 0) { + MOS2mod = (MOS2model *) model; + (*modtypes)[num_instances-1] = MOS2mod->MOS2type; + } + else if(strcmp(device,"Mos3") == 0) { + MOS3mod = (MOS3model *) model; + (*modtypes)[num_instances-1] = MOS3mod->MOS3type; + } + else { + (*modtypes)[num_instances-1] = 1.0; + } + + } /* end for all instances */ + } /* end for all models */ + + return(num_instances); +} + + + +/* +ipc_free_devices + +This function frees temporary data created by ipc_get_devices(). +*/ + + +void ipc_free_devices( + int num_items, /* Number of things to free */ + char **names, /* Array of name strings to be built */ + double *modtypes) /* Array of types to be built */ +{ + int i; + + for(i = 0; i < num_items; i++) + { + FREE(names[i]); + names[i] = 0; + } + + if(num_items > 0) + { + FREE(names); + FREE(modtypes); + + names = NULL; + modtypes = NULL; + } +} + + +/* +ipc_check_pause_stop + +This function is called at various times during a simulation to check +for incoming messages of the form >STOP or >PAUSE signaling that +simulation should be stopped or paused. Processing of the messages +is handled by ipc_get_line(). +*/ + +void ipc_check_pause_stop(void) +{ + char buf[1025]; + int len; + + /* If already seen stop analysis, don't call ipc_get_line, just return. */ + /* This is provided so that the function can be called multiple times */ + /* during the process of stopping */ + if(g_ipc.stop_analysis) + return; + + /* Otherwise do a non-blocking call to ipc_get_line() to check for messages. */ + /* We assume that the only possible messages at this point are >PAUSE */ + /* and >STOP, so we don't do anything with the returned text if any */ + ipc_get_line(buf, &len, IPC_NO_WAIT); +} + diff --git a/src/xspice/lib/analog.cm b/src/xspice/lib/analog.cm new file mode 100755 index 000000000..b46966130 Binary files /dev/null and b/src/xspice/lib/analog.cm differ diff --git a/src/xspice/lib/digital.cm b/src/xspice/lib/digital.cm new file mode 100755 index 000000000..383c0b636 Binary files /dev/null and b/src/xspice/lib/digital.cm differ diff --git a/src/xspice/lib/xtradev.cm b/src/xspice/lib/xtradev.cm new file mode 100755 index 000000000..46f308717 Binary files /dev/null and b/src/xspice/lib/xtradev.cm differ diff --git a/src/xspice/lib/xtraevt.cm b/src/xspice/lib/xtraevt.cm new file mode 100755 index 000000000..fa135648d Binary files /dev/null and b/src/xspice/lib/xtraevt.cm differ diff --git a/src/xspice/mif/Makefile.am b/src/xspice/mif/Makefile.am new file mode 100755 index 000000000..757d3dcd8 --- /dev/null +++ b/src/xspice/mif/Makefile.am @@ -0,0 +1,26 @@ +## Process this file with automake to produce Makefile.in +# +# JW 3/9/01 - had a go and makeing an autoconf script. + +noinst_LIBRARIES = libmifxsp.a + +libmifxsp_a_SOURCES = \ + mif_inp2.c \ + mifgetmod.c \ + mifgetvalue.c \ + mifload.c \ + mifmpara.c \ + mifsetup.c \ + mifutil.c \ + mifask.c \ + mifmask.c \ + miftrunc.c \ + mifconvt.c \ + mifdelete.c \ + mifmdelete.c \ + mifdestr.c \ + mif.c + +INCLUDES = -I$(top_srcdir)/src/include + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/xspice/mif/mif.c b/src/xspice/mif/mif.c new file mode 100755 index 000000000..42227c0d4 --- /dev/null +++ b/src/xspice/mif/mif.c @@ -0,0 +1,62 @@ +/*============================================================================ +FILE MIF.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file allocates globals used by various packages, including MIF. + +INTERFACES + + g_mif_info + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + + +#include "mif.h" + +/* jgroves */ + +int MIFiSize = sizeof(MIFinstance); /* jgroves */ +int MIFmSize = sizeof(MIFmodel); /* jgroves */ + + +/* Allocate global used to pass info on analysis type, etc. from */ +/* SPICE to the MIF load routine */ + + +/* This must be initialized so that EVTfindvec can check for */ +/* NULL pointer in g_mif_info.ckt */ + +Mif_Info_t g_mif_info = { + { MIF_FALSE, MIF_FALSE, MIF_DC, MIF_ANALOG, 0.0,}, + NULL, + NULL, + NULL, + { 0.0, 0.0,}, + { MIF_FALSE, MIF_FALSE,}, +}; diff --git a/src/xspice/mif/mif_inp2.c b/src/xspice/mif/mif_inp2.c new file mode 100755 index 000000000..7c5f55f2a --- /dev/null +++ b/src/xspice/mif/mif_inp2.c @@ -0,0 +1,885 @@ +/*============================================================================ +FILE MIF_INP2A.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the main routine for parsing code model lines + in the SPICE circuit description input deck. + +INTERFACES + + MIF_INP2A() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +/* #include "prefix.h" */ /* jgroves */ +#include "ngspice.h" +#include +//#include "util.h" +#include "ifsim.h" +#include "inpdefs.h" +#include "devdefs.h" +#include "inpmacs.h" +#include "fteext.h" + +#include "mifproto.h" +#include "mifparse.h" +#include "mifdefs.h" +#include "mifcmdat.h" + +#include "evt.h" +#include "evtproto.h" + +/* #include "suffix.h" */ /* jgroves */ + + + +/*#define NUM_SPICE3_MODELS 40 (was 23 - jgroves Number of Berkeley models in DEVices array. */ + /* See CKT/SPIinit.c */ + +extern int *DEVicesfl; /*flags for the devices */ +extern SPICEdev **DEVices; /* info about all device types */ +extern int DEVmaxnum; /* size of DEVices array */ + + +static void MIFinit_inst(MIFmodel *mdfast, MIFinstance *fast); + +static void MIFget_port_type( + void *ckt, /* circuit structure to put mod/inst structs in */ + INPtables *tab, /* symbol table for node names, etc. */ + card *current, /* MUST be named 'current' for spice macros */ + char **line, + char **next_token, + Mif_Token_Type_t *next_token_type, + Mif_Port_Type_t *port_type, + char **port_type_str, + Mif_Conn_Info_t *conn_info, /* for faster access to conn info struct */ + Mif_Status_t *status); + + +static void MIFget_port( + void *ckt, /* circuit structure to put mod/inst structs in */ + INPtables *tab, /* symbol table for node names, etc. */ + card *current, /* MUST be named 'current' for spice macros */ + MIFinstance *fast, /* pointer to instance struct */ + char **line, + char **next_token, + Mif_Token_Type_t *next_token_type, + Mif_Port_Type_t def_port_type, + char *def_port_type_str, + Mif_Conn_Info_t *conn_inf, /* for faster access to conn info struct */ + int conn_num, + int port_num, + Mif_Status_t *status); + + + + +/* ********************************************************************* */ + + + +/* +MIF_INP2A + +This function is called by INPpas2() in SPICE to parse the new +``a'' type element cards and build the required circuit structures +for the associated code model device and instance. It first +checks the model name at the end of the element card to be sure +the model was found in pass 1 of the parser. If so, MIFgetMod is +called to process the .model card, creating the necessary +internal model structure and filling in the parameter value +information. Next, the instance structure is allocated. +Finally, the connections on the element card are scanned and the +connection information is filled-in on the instance structure, +and error checks are performed. +*/ + + +void +MIF_INP2A(ckt,tab,current) + +void *ckt; /* circuit structure to put mod/inst structs in */ +INPtables *tab; /* symbol table for node names, etc. */ +card *current; /* the card we are to parse */ + /* Must be called "current" for compatibility */ + /* with macros */ +{ + +/* parse a code model instance card */ +/* Aname */ + + char *line; /* the text line for this card */ + char *name; /* the name of the instance */ + char *model=NULL; /* the name of the model */ + + char *def_port_type_str; /* The default port type in string form */ + char *next_token; /* a token string */ + + int i; /* a loop counter */ + int j; /* a loop counter */ + int type; /* the type of the model for this instance */ + /* int num_conn; number of connections for this model */ + int error; /* for the IFC macro */ + + MIFmodel *mdfast; /* pointer to model struct */ + MIFinstance *fast; /* pointer to instance struct */ + + INPmodel *thismodel; /* pointer to model struct */ + + Mif_Conn_Info_t *conn_info; /* for faster access to conn info struct */ + Mif_Param_Info_t *param_info; /* for faster access to param info struct */ + Mif_Port_Type_t def_port_type; /* the default port type */ + Mif_Status_t status; /* return status */ + Mif_Token_Type_t next_token_type; /* the type of the next token */ + + + /* get the line text from the card struct */ + + line = current->line; + + + /* get the name of the instance and add it to the symbol table */ + + name = MIFgettok(&line); + INPinsert(&name, tab); + + + /* locate the last token on the line and put it into "model" */ + + while(*line != '\0') + model = MIFgettok(&line); + + if(model == NULL) { + LITERR("Missing model on A type device"); + return; + } + + /* Locate model from pass 1. If it hasn't been processed yet, */ + /* allocate a structure in ckt for it, process its parameters */ + /* and return a pointer to its structure in 'thismodel' */ + + current->error = MIFgetMod(ckt, model, &thismodel, tab); + + if(current->error) { + return; + } + + + /* get the integer index into the DEVices data array for this */ + /* model */ + + type = thismodel->INPmodType; + + if((type >= DEVmaxnum) || DEVicesfl[type] == 0) { + LITERR("Invalid model type for A type device"); + return; + } + + /* create a new structure for this instance in ckt */ + + mdfast = thismodel->INPmodfast; + IFC(newInstance, (ckt, mdfast,(void **)&fast, name)) + + + /* initialize the code model specific elements of the inst struct */ + + MIFinit_inst(mdfast, fast); + + + /* *********************** */ + /* Process the connections */ + /* *********************** */ + + /* get the line text from the card struct */ + /* skipping over the name of the instance */ + /* and reading the first token following */ + + line = current->line; + MIFgettok(&line); + next_token = MIFget_token(&line,&next_token_type); + + + /* loop through the fixed number of connections expected */ + + for(i = 0; i < DEVices[type]->DEVpublic.num_conn; i++) { + + /* there better be at least one more token besides the model name */ + if(*line == '\0') { + LITERR("Missing connections on A device"); + return; + } + + /* prepare a pointer for fast access to info about this connection */ + conn_info = &(DEVices[type]->DEVpublic.conn[i]); + + /* get the default port type for this connection */ + def_port_type = conn_info->default_port_type; + def_port_type_str = conn_info->default_type; + + /* set analog and event_driven flags on instance and model */ + if((def_port_type == MIF_DIGITAL) || (def_port_type == MIF_USER_DEFINED)) { + fast->event_driven = MIF_TRUE; + mdfast->event_driven = MIF_TRUE; + } + else { + fast->analog = MIF_TRUE; + mdfast->analog = MIF_TRUE; + } + + /* check for a null connection and continue to next connection if found */ + + if(next_token_type == MIF_NULL_TOK) { + + /* make sure null is allowed */ + if(! conn_info->null_allowed) { + LITERR("NULL connection found where not allowed"); + return; + } + + /* set the null flag to true */ + fast->conn[i]->is_null = MIF_TRUE; + fast->conn[i]->size = 0; + + /* eat the null token and continue to next connection */ + next_token = MIFget_token(&line,&next_token_type); + continue; + } + else { + /* set the null flag to false */ + fast->conn[i]->is_null = MIF_FALSE; + } + + /* process connection as appropriate for scalar or array */ + + if(! conn_info->is_array) { /* a scalar connection - the simpler case */ + + /* do a couple of error checks */ + if(next_token_type == MIF_LARRAY_TOK) { + LITERR("ERROR - Scalar connection expected, [ found"); + return; + } + if(next_token_type == MIF_RARRAY_TOK) { + LITERR("ERROR - Unexpected ]"); + return; + } + + /* If all OK, get the port data into the instance struct */ + /* allocating the port member of the instance struct as needed */ + MIFget_port(ckt, + tab, + current, + fast, + &line, + &next_token, + &next_token_type, + def_port_type, + def_port_type_str, + conn_info, + i, /* connection index */ + 0, /* port index for scalar connection */ + &status); + + if(status == MIF_ERROR) + return; + + fast->conn[i]->size = 1; + } + else { /* the connection is an array - much to be done ... */ + + /* get the leading port type for the array if any */ + /* it will distribute across all ports inside the braces */ + /* overriding the default type in the interface spec */ + + if(next_token_type == MIF_PERCENT_TOK) { + + /* get the port type identifier and check it for validity */ + next_token = MIFget_token(&line,&next_token_type); + MIFget_port_type(ckt, + tab, + current, + &line, + &next_token, + &next_token_type, + &def_port_type, + &def_port_type_str, + conn_info, + &status); + if(status == MIF_ERROR) + return; + } + + /* check for required leading array delim character and eat it if found */ + if(next_token_type != MIF_LARRAY_TOK) { + LITERR("Missing [, an array connection was expected"); + return; + } + else + next_token = MIFget_token(&line,&next_token_type); + + /* get and process ports until ] is encountered */ + + for(j = 0; + (next_token_type != MIF_RARRAY_TOK) && + (*line != '\0'); + j++) { + + /* First, do some error checks */ + + /* check for required leading array delim character */ + if(next_token_type == MIF_LARRAY_TOK) { + LITERR("ERROR - Unexpected [ - Arrays of arrays not allowed"); + return; + } + + /* If all OK, get the port nodes into the instance struct */ + /* allocating the port member of the instance struct as needed */ + + MIFget_port(ckt, + tab, + current, + fast, + &line, + &next_token, + &next_token_type, + def_port_type, + def_port_type_str, + conn_info, + i, /* connection index */ + j, /* port index */ + &status); + + if(status == MIF_ERROR) + return; + } + + /* make sure we exited because the end of the array connection */ + /* was reached. If so, eat the closing array delimiter */ + if(*line == '\0') { + LITERR("Missing ] in array connection"); + return; + } + else + next_token = MIFget_token(&line,&next_token_type); + + /* record the number of ports found for this connection */ + if(j < 1) { + LITERR("Array connection must have at least one port"); + return; + } + fast->conn[i]->size = j; + + } /* array connection processing */ + + /* be careful about putting stuff here, there is a 'continue' used */ + /* in the processing of NULL connections above */ + + } /* for number of connections */ + + + /* *********************** */ + /* Error Checks */ + /* *********************** */ + + /* check for too many connections */ + + if(*line != '\0') { + LITERR("Too many connections"); + return; + } + + /* check connection constraints */ + + for(i = 0; i < DEVices[type]->DEVpublic.num_conn; i++) { + + conn_info = &(DEVices[type]->DEVpublic.conn[i]); + + if( (fast->conn[i]->is_null) && + (! conn_info->null_allowed) ) { + LITERR("Null found for connection where not allowed"); + return; + } + + if(conn_info->has_lower_bound) { + if(fast->conn[i]->size < conn_info->lower_bound) { + LITERR("Too few ports in connection"); + return; + } + } + + if(conn_info->has_upper_bound) { + if(fast->conn[i]->size > conn_info->upper_bound) { + LITERR("Too many ports in connection"); + return; + } + } + } + + /* check model parameter constraints */ + /* some of these should probably be done in MIFgetMod() */ + /* to prevent multiple error messages */ + + for(i = 0; i < DEVices[type]->DEVpublic.num_param; i++) { + + param_info = &(DEVices[type]->DEVpublic.param[i]); + + if(mdfast->param[i]->is_null) { + if(! param_info->has_default) { + LITERR("Parameter on model has no default"); + return; + } + else if((param_info->is_array) && (! param_info->has_conn_ref)) { + LITERR("Defaulted array parameter must have associated array connection"); + return; + } + } + if((! mdfast->param[i]->is_null) && (param_info->is_array)) { + if(param_info->has_conn_ref) { + if(fast->conn[param_info->conn_ref]->size != fast->param[i]->size) { + LITERR("Array parameter size on model does not match connection size"); + return; + } + } + } + } +} + + +/* ********************************************************************* */ + + + +/* +MIFinit_inst + +This function initializes the code model specific elements of the inst struct. +*/ + + +static void MIFinit_inst( + MIFmodel *mdfast, /* The model the instance is derived from */ + MIFinstance *fast) /* The instance to initialize */ +{ + + int mod_type; /* type of this model */ + + Mif_Conn_Info_t *conn_info; + + int i; + + + /* get an index into the DEVices information structure */ + + mod_type = mdfast->MIFmodType; + + + /* allocate code model connector data in instance struct */ + + fast->num_conn = DEVices[mod_type]->DEVpublic.num_conn; + fast->conn = (void *) tmalloc(fast->num_conn * sizeof(void *)); + + for(i = 0; i < fast->num_conn; i++) + fast->conn[i] = (void *) tmalloc(sizeof(Mif_Conn_Data_t)); + + /* initialize code model connector data */ + for(i = 0; i < fast->num_conn; i++) { + conn_info = &(DEVices[mod_type]->DEVpublic.conn[i]); + fast->conn[i]->name = conn_info->name; + fast->conn[i]->description = conn_info->description; + fast->conn[i]->is_null = MIF_TRUE; + fast->conn[i]->size = 0; + fast->conn[i]->port = NULL; + switch(conn_info->direction) { + case MIF_INOUT: + fast->conn[i]->is_input = MIF_TRUE; + fast->conn[i]->is_output = MIF_TRUE; + break; + case MIF_IN: + fast->conn[i]->is_input = MIF_TRUE; + fast->conn[i]->is_output = MIF_FALSE; + break; + case MIF_OUT: + fast->conn[i]->is_input = MIF_FALSE; + fast->conn[i]->is_output = MIF_TRUE; + break; + default: + printf("\nERROR - Impossible direction type in MIFinit_inst\n"); + exit(1); + } + } + + + /* allocate and copy instance variable data to the instance */ + + fast->num_inst_var = DEVices[mod_type]->DEVpublic.num_inst_var; + fast->inst_var = (void *) tmalloc(fast->num_inst_var * sizeof(void *)); + + for(i = 0; i < fast->num_inst_var; i++) { + + fast->inst_var[i] = (void *) tmalloc(sizeof(Mif_Inst_Var_Data_t)); + + if(DEVices[mod_type]->DEVpublic.inst_var[i].is_array) { + fast->inst_var[i]->size = 0; + fast->inst_var[i]->element = NULL; + /* The code model allocates space for the data and sets the size */ + } + else { + fast->inst_var[i]->size = 1; + fast->inst_var[i]->element = (void *) tmalloc(sizeof(Mif_Value_t)); + } + } + + + /* copy model parameter data to the instance */ + + fast->num_param = mdfast->num_param; + fast->param = mdfast->param; + + /* initialize any additional instance data */ + fast->initialized = MIF_FALSE; + fast->analog = MIF_FALSE; + fast->event_driven = MIF_FALSE; + fast->inst_index = 0; +} + + + +/* ********************************************************************* */ + + + +/* +MIFget_port_type + +This function gets the port type identifier and checks it for validity. +*/ + + +static void +MIFget_port_type( + void *ckt, /* circuit structure to put mod/inst structs in */ + INPtables *tab, /* symbol table for node names, etc. */ + card *current, /* MUST be named 'current' for spice macros */ + char **line, + char **next_token, + Mif_Token_Type_t *next_token_type, + Mif_Port_Type_t *port_type, + char **port_type_str, + Mif_Conn_Info_t *conn_info, /* for faster access to conn info struct */ + Mif_Status_t *status) +{ + + Mif_Boolean_t found_type; + char *temp; + + int i; + + if(**line == '\0') { + LITERR("Missing connections on A device"); + *status = MIF_ERROR; + return; + } + + if(*next_token_type != MIF_STRING_TOK) { + LITERR("Invalid port type specifier"); + *status = MIF_ERROR; + return; + } + + /* OK, so get the port type string from the token and read next token */ + + temp = *next_token; + *next_token = MIFget_token(line, next_token_type); + + /* check port type for validity */ + + found_type = MIF_FALSE; + + for(i = 0; i < conn_info->num_allowed_types; i++) { + if(strcmp(temp, conn_info->allowed_type_str[i]) == 0) { + found_type = MIF_TRUE; + *port_type = conn_info->allowed_type[i]; + *port_type_str = temp; + break; + } + } + + if(! found_type) { + LITERR("Port type is invalid"); + *status = MIF_ERROR; + } + else + *status = MIF_OK; +} + + + + +/* ********************************************************************* */ + + +/* +MIFget_port + +This function processes a port being parsed, either single ended, +or both connections of a differential. +*/ + + + + +static void +MIFget_port( + void *ckt, /* circuit structure to put mod/inst structs in */ + INPtables *tab, /* symbol table for node names, etc. */ + card *current, /* MUST be named 'current' for spice macros */ + MIFinstance *fast, /* pointer to instance struct */ + char **line, + char **next_token, + Mif_Token_Type_t *next_token_type, + Mif_Port_Type_t def_port_type, + char *def_port_type_str, + Mif_Conn_Info_t *conn_info, /* for faster access to conn info struct */ + int conn_num, + int port_num, + Mif_Status_t *status) + +{ + + + CKTnode *pos_node; /* positive connection node */ + CKTnode *neg_node; /* negative connection node */ + + char *node; + + /* get the leading port type if any */ + + if(*next_token_type == MIF_PERCENT_TOK) { + + /* get the port type identifier and check it for validity */ + *next_token = MIFget_token(line, next_token_type); + MIFget_port_type(ckt, + tab, + current, + line, + next_token, + next_token_type, + &def_port_type, + &def_port_type_str, + conn_info, + status); + + if(*status == MIF_ERROR) { + return; + } + } + + /* allocate space in the instance data struct for this port */ + if(port_num == 0) { + fast->conn[conn_num]->port = (void *) tmalloc(sizeof(void *)); + fast->conn[conn_num]->port[0] = (void *) tmalloc(sizeof(Mif_Port_Data_t)); + } + else { + fast->conn[conn_num]->port = (void *) REALLOC( + fast->conn[conn_num]->port, + ((port_num + 1) * sizeof(void *)) ); + fast->conn[conn_num]->port[port_num] = (void *) tmalloc(sizeof(Mif_Port_Data_t)); + } + + + /* store the port type information in the instance struct */ + fast->conn[conn_num]->port[port_num]->type = def_port_type; + fast->conn[conn_num]->port[port_num]->type_str = def_port_type_str; + + /* check for a leading tilde on digital ports */ + if(*next_token_type == MIF_TILDE_TOK) { + if((def_port_type != MIF_DIGITAL) && (def_port_type != MIF_USER_DEFINED)) { + LITERR("ERROR - Tilde not allowed on analog nodes"); + *status = MIF_ERROR; + return; + } + fast->conn[conn_num]->port[port_num]->invert = MIF_TRUE; + + /* eat the tilde and get the next token */ + *next_token = MIFget_token(line, next_token_type); + if(**line == '\0') { + LITERR("ERROR - Not enough ports"); + *status = MIF_ERROR; + return; + } + } + else + fast->conn[conn_num]->port[port_num]->invert = MIF_FALSE; + + + /* check for null port */ + if(*next_token_type == MIF_NULL_TOK) { + + /* make sure null is allowed */ + if(! conn_info->null_allowed) { + LITERR("NULL connection found where not allowed"); + *status = MIF_ERROR; + return; + } + + /* set the (port specific) null flag to true */ + fast->conn[conn_num]->port[port_num]->is_null = MIF_TRUE; + + /* set input value to zero in case user code model refers to it */ + fast->conn[conn_num]->port[port_num]->input.rvalue = 0.0; + + /* eat the null token and return */ + *next_token = MIFget_token(line, next_token_type); + *status = MIF_OK; + return; + } + else { + /* set the (port specific) null flag to false */ + fast->conn[conn_num]->port[port_num]->is_null = MIF_FALSE; + } + + + /* next token must be a node/instance identifier ... */ + if(*next_token_type != MIF_STRING_TOK) { + LITERR("ERROR - Expected node/instance identifier"); + *status = MIF_ERROR; + return; + } + + /* Get the first connection or the voltage source name */ + + switch(def_port_type) { + + case MIF_VOLTAGE: + case MIF_DIFF_VOLTAGE: + case MIF_CURRENT: + case MIF_DIFF_CURRENT: + case MIF_CONDUCTANCE: + case MIF_DIFF_CONDUCTANCE: + case MIF_RESISTANCE: + case MIF_DIFF_RESISTANCE: + + /* Call the spice3c1 function to put this node in the node list in ckt */ + INPtermInsert(ckt, next_token, tab,(void **)&pos_node); + + /* store the equation number and node identifier */ + /* This is the equivalent of what CKTbindNode() does in 3C1 */ + fast->conn[conn_num]->port[port_num]->pos_node_str = *next_token; + fast->conn[conn_num]->port[port_num]->smp_data.pos_node = pos_node->number; + + break; + + case MIF_VSOURCE_CURRENT: + + /* Call the spice3c1 function to put this vsource instance name in */ + /* the symbol table */ + INPinsert(next_token, tab); + + /* Now record the name of the vsource instance for processing */ + /* later by MIFsetup. This is equivalent to what INPpName */ + /* does in 3C1. Checking to see if the source is present in */ + /* the circuit is deferred to MIFsetup as is done in 3C1. */ + fast->conn[conn_num]->port[port_num]->vsource_str = *next_token; + + break; + + case MIF_DIGITAL: + case MIF_USER_DEFINED: + /* Insert data into event-driven info structs */ + EVTtermInsert(ckt, + fast, + *next_token, + def_port_type_str, + conn_num, + port_num, + &(current->error)); + if(current->error) { + *status = MIF_ERROR; + return; + } + break; + + default: + + /* impossible connection type */ + LITERR("INTERNAL ERROR - Impossible connection type"); + *status = MIF_ERROR; + return; + } + + /* get the next token */ + *next_token = MIFget_token(line, next_token_type); + + /* get other node if appropriate */ + switch(def_port_type) { + + case MIF_VOLTAGE: + case MIF_CURRENT: + case MIF_CONDUCTANCE: + case MIF_RESISTANCE: + /* These are single ended types, so default other node to ground */ + // This don't work dickhead, INPtermInsert tries to FREE(&node) K.A. Feb 27, 2000 + // which was not allocted + node = (char*)malloc(2);// added by K.A. march 5th 2000 + + *node = '0'; // added by K.A. March 5th 2000 + node[1] ='\0'; // added by K.A. March 5th 2000 +// node = "0"; // deleted by K.A. March 5th 2000, this is incorrect, it creates a new pointer + // that cause a crash in INPtermInsert() + + INPtermInsert(ckt, &node, tab,(void **)&neg_node); + + fast->conn[conn_num]->port[port_num]->neg_node_str = node; + fast->conn[conn_num]->port[port_num]->smp_data.neg_node = neg_node->number; + break; + + case MIF_DIFF_VOLTAGE: + case MIF_DIFF_CURRENT: + case MIF_DIFF_CONDUCTANCE: + case MIF_DIFF_RESISTANCE: + /* These are differential types, so get the other node */ + if((**line == '\0') || (*next_token_type != MIF_STRING_TOK)) { + LITERR("ERROR - Expected node identifier"); + *status = MIF_ERROR; + return; + } + INPtermInsert(ckt, next_token, tab,(void **)&neg_node); + fast->conn[conn_num]->port[port_num]->neg_node_str = *next_token; + fast->conn[conn_num]->port[port_num]->smp_data.neg_node = neg_node->number; + *next_token = MIFget_token(line, next_token_type); + break; + + default: + /* must be vsource name, digital, or user defined, so there is no other node */ + break; + + } + + *status = MIF_OK; + return; +} diff --git a/src/xspice/mif/mifask.c b/src/xspice/mif/mifask.c new file mode 100755 index 000000000..7ff22d171 --- /dev/null +++ b/src/xspice/mif/mifask.c @@ -0,0 +1,231 @@ +/*============================================================================ +FILE MIFask.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the function used by nutmeg to request the + value of a code model static var. + +INTERFACES + + MIFask() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +/* #include "prefix.h" */ +#include "ngspice.h" +#include +//#include "CONST.h" +//#include "util.h" +#include "ifsim.h" +#include "devdefs.h" +#include "sperror.h" + +#include + +#include "mifproto.h" +#include "mifdefs.h" + +/* #include "suffix.h" */ + + + +extern SPICEdev **DEVices; +extern int DEVmaxnum; + + + + + +/* +MIFask + +This function is called by SPICE/Nutmeg to query the value of a +parameter on an instance. It locates the value of the parameter +in the instance structure and converts the value into the IFvalue +structure understood by Nutmeg. For code models, this function +is provided to allow output of Instance Variables defined in the +code model's Interface Specification. +*/ + + +int MIFask( + CKTcircuit *ckt, /* The circuit structure */ + GENinstance *inInst, /* The instance to get the value from */ + int which, /* The parameter to get */ + IFvalue *value, /* The value returned */ + IFvalue *select) /* Unused */ +{ + + MIFinstance *inst; + MIFmodel *model; + int mod_type; + int value_type; + int i; + int size; + + int inst_index; + + Mif_Boolean_t is_array; + + + /* Arrange for access to MIF specific data in the instance */ + inst = (MIFinstance *) inInst; + + /* Arrange for access to MIF specific data in the model */ + model = inst->MIFmodPtr; + + + /* Get model type */ + mod_type = model->MIFmodType; + if((mod_type < 0) || (mod_type >= DEVmaxnum)) + return(E_BADPARM); + + /* Adjust parameter tag to actual index into inst info array */ + inst_index = which - model->num_param; + + /* Check instance index for validity */ + if((inst_index < 0) || (inst_index >= inst->num_inst_var)) + return(E_BADPARM); + + /* get value type to know which members of unions to access */ + value_type = DEVices[mod_type]->DEVpublic.instanceParms[inst_index].dataType; + value_type &= IF_VARTYPES; + + + /* determine if the parameter is an array or not */ + is_array = value_type & IF_VECTOR; + + + /* Transfer the values to the SPICE3C1 value union from the param elements */ + /* This is analagous to what SPICE3 does with other device types */ + + + if(! is_array) { + + switch(value_type) { + + case IF_FLAG: + value->iValue = inst->inst_var[inst_index]->element[0].bvalue; + break; + + case IF_INTEGER: + value->iValue = inst->inst_var[inst_index]->element[0].ivalue; + break; + + case IF_REAL: + value->rValue = inst->inst_var[inst_index]->element[0].rvalue; + break; + + case IF_STRING: + /* Make copy of string. We don't trust caller to not free it */ + /* These copies could get expensive! */ + value->sValue = MIFcopy(inst->inst_var[inst_index]->element[0].svalue); + break; + + case IF_COMPLEX: + /* we don't trust the caller to have a parallel complex structure */ + /* so copy the real and imaginary parts explicitly */ + value->cValue.real = inst->inst_var[inst_index]->element[0].cvalue.real; + value->cValue.imag = inst->inst_var[inst_index]->element[0].cvalue.imag; + break; + + default: + return(E_BADPARM); + + } + } + else { /* it is an array */ + + size = inst->inst_var[inst_index]->size; + if(size < 0) + size = 0; + + value->v.numValue = size; + + switch(value_type) { + + /* Note that we malloc space each time this function is called. */ + /* This is what TRAask.c does, so we do it too, even though */ + /* we don't know if it is ever freed... */ + + case IF_FLAGVEC: + if(size <= 0) + break; + value->v.vec.iVec = (void *) MALLOC(size * sizeof(int)); + for(i = 0; i < size; i++) + value->v.vec.iVec[i] = inst->inst_var[inst_index]->element[i].bvalue; + break; + + case IF_INTVEC: + if(size <= 0) + break; + value->v.vec.iVec = (void *) MALLOC(size * sizeof(int)); + for(i = 0; i < size; i++) + value->v.vec.iVec[i] = inst->inst_var[inst_index]->element[i].ivalue; + break; + + case IF_REALVEC: + if(size <= 0) + break; + value->v.vec.rVec = (void *) MALLOC(size * sizeof(double)); + for(i = 0; i < size; i++) + value->v.vec.rVec[i] = inst->inst_var[inst_index]->element[i].rvalue; + break; + + case IF_STRINGVEC: + if(size <= 0) + break; + value->v.vec.sVec = (void *) MALLOC(size * sizeof(char *)); + for(i = 0; i < size; i++) + /* Make copy of string. We don't trust caller to not free it */ + /* These copies could get expensive! */ + value->v.vec.sVec[i] = MIFcopy(inst->inst_var[inst_index]->element[i].svalue); + break; + + case IF_CPLXVEC: + if(size <= 0) + break; + /* we don't trust the caller to have a parallel complex structure */ + /* so copy the real and imaginary parts explicitly */ + value->v.vec.cVec = (void *) MALLOC(size * sizeof(IFcomplex)); + for(i = 0; i < size; i++) { + value->v.vec.cVec[i].real = inst->inst_var[inst_index]->element[i].cvalue.real; + value->v.vec.cVec[i].imag = inst->inst_var[inst_index]->element[i].cvalue.imag; + } + break; + + default: + return(E_BADPARM); + + } /* end switch */ + + } /* end else */ + + return(OK); +} diff --git a/src/xspice/mif/mifconvt.c b/src/xspice/mif/mifconvt.c new file mode 100755 index 000000000..93d483b11 --- /dev/null +++ b/src/xspice/mif/mifconvt.c @@ -0,0 +1,145 @@ +/*============================================================================ +FILE MIFconvTest.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the function used to check that internal + states of a code model have converged. These internal states + are typically integration states. + +INTERFACES + + MIFconvTest() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +/* #include "prefix.h" */ +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "sperror.h" + +//#include "util.h" +#include "devdefs.h" +//#include "CONST.h" +#include "trandefs.h" +#include + +#include "mifproto.h" +#include "mifparse.h" +#include "mifdefs.h" +#include "mifcmdat.h" + +/* #include "suffix.h" */ + + + + +/* +MIFconvTest + +This function is called by the CKTconvTest() driver function to +check convergence of any states owned by instances of a +particular code model type. It loops through all models of that +type and all instances of each model. For each instance, it +looks in the instance structure to determine if any variables +allocated by cm_analog_alloc() have been registered by a call to +cm_analog_converge() to have their convergence tested. If so, the value +of the function at the last iteration is compared with the value +at the current iteration to see if it has converged to within the +same delta amount used in node convergence checks (as defined by +SPICE 3C1). +*/ + + +int MIFconvTest( + GENmodel *inModel, /* The head of the model list */ + CKTcircuit *ckt) /* The circuit structure */ +{ + + MIFmodel *model; + MIFinstance *here; + + int i; + + double value; + double last_value; + + char *byte_aligned_double_ptr; + double *double_ptr; + + double tol; + + Mif_Boolean_t gotone = MIF_FALSE; + + + /* Setup for access into MIF specific model data */ + model = (MIFmodel *) inModel; + + /* loop through all models of this type */ + for( ; model != NULL; model = model->MIFnextModel) { + + /* Loop through all instances of this model */ + for(here = model->MIFinstances; here != NULL; here = here->MIFnextInstance) { + + /* Loop through all items registered for convergence */ + for(i = 0; i < here->num_conv; i++) { + + /* Get the current value and the last value */ + byte_aligned_double_ptr = (char *) ckt->CKTstate0; + byte_aligned_double_ptr += here->conv[i].byte_index; + double_ptr = (double *) byte_aligned_double_ptr; + value = *double_ptr; + + last_value = here->conv[i].last_value; + + /* If none have failed so far, check convergence */ + if(! gotone) { + + tol = ckt->CKTreltol * MAX(fabs(value), fabs(last_value)) + + ckt->CKTabstol; + if (fabs(value - last_value) > tol) { + if(ckt->enh->conv_debug.report_conv_probs) { + ENHreport_conv_prob(ENH_ANALOG_INSTANCE, + (char *) here->MIFname, + ""); + } + ckt->CKTnoncon++; + gotone = MIF_TRUE; + } + } + + /* Rotate the current value to last_value */ + here->conv[i].last_value = value; + + } /* end for number of conv items */ + } /* end for all instances */ + } /* end for all models of this type */ + + return(OK); +} diff --git a/src/xspice/mif/mifdelete.c b/src/xspice/mif/mifdelete.c new file mode 100755 index 000000000..56db26b32 --- /dev/null +++ b/src/xspice/mif/mifdelete.c @@ -0,0 +1,199 @@ +/*============================================================================ +FILE MIFdelete.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the function used by SPICE to delete an + instance and its allocated data structures from the internal + circuit description data structures. + +INTERFACES + + MIFdelete() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +#include +#include "ngspice.h" +#include "sperror.h" +#include "gendefs.h" + +#include "mifproto.h" +#include "mifdefs.h" + +#include "suffix.h" + + + +/* +MIFdelete + +This function deletes a particular instance from the linked list +of instance structures, freeing all dynamically allocated memory +used by the instance structure. +*/ + + +int +MIFdelete( + GENmodel *inModel, /* The head of the model list */ + IFuid name, /* The name of the instance to delete */ + GENinstance **inst /* The instance structure to delete */ +) +{ + MIFmodel *model; + MIFinstance **fast; + MIFinstance **prev; + MIFinstance *here=NULL; + + Mif_Boolean_t found; + + int i; + int j; + int k; + + int num_conn; + int num_port; + int num_inst_var; + + + /* Convert generic pointers in arg list to MIF specific pointers */ + model = (MIFmodel *) inModel; + fast = (MIFinstance **) inst; + + /*******************************************/ + /* Cut the instance out of the linked list */ + /*******************************************/ + + /* Loop through all models */ + for(found = MIF_FALSE; model; model = model->MIFnextModel) { + prev = &(model->MIFinstances); + /* Loop through all instances of this model */ + for(here = *prev; here; here = here->MIFnextInstance) { + /* If name or pointer matches, cut it out and mark that its found */ + if(here->MIFname == name || (fast && here == *fast) ) { + *prev= here->MIFnextInstance; + found = MIF_TRUE; + break; + } + prev = &(here->MIFnextInstance); + } + if(found) + break; + } + + /* Return error if not found */ + if(!found) + return(E_NODEV); + + + /*******************************/ + /* Free the instance structure */ + /*******************************/ + + /* Loop through all connections on the instance */ + /* and dismantle the stuff allocated during readin/setup */ + /* in MIFinit_inst, MIFget_port, and MIFsetup */ + + num_conn = here->num_conn; + for(i = 0; i < num_conn; i++) { + + /* If connection never used, skip it */ + if(here->conn[i]->is_null) + continue; + + /* If analog output, lots to free... */ + if(here->conn[i]->is_output && here->analog) { + num_port = here->conn[i]->size; + /* For each port on the connector */ + for(j = 0; j < num_port; j++) { + /* Free the partial/ac_gain/smp stuff allocated in MIFsetup */ + for(k = 0; k < num_conn; k++) { + if((here->conn[k]->is_null) || (! here->conn[k]->is_input) ) + continue; + FREE(here->conn[i]->port[j]->partial[k].port); + FREE(here->conn[i]->port[j]->ac_gain[k].port); + FREE(here->conn[i]->port[j]->smp_data.input[k].port); + } + FREE(here->conn[i]->port[j]->partial); + FREE(here->conn[i]->port[j]->ac_gain); + FREE(here->conn[i]->port[j]->smp_data.input); + /* but don't free strings. They are either not owned */ + /* by the inst or are part of tokens. SPICE3C1 never */ + /* frees tokens, so we don't either... */ + } + } + /* Free the basic port structure allocated in MIFget_port */ + num_port = here->conn[i]->size; + for(j = 0; j < num_port; j++) + FREE(here->conn[i]->port[j]); + FREE(here->conn[i]->port); + } + + /* Free the connector stuff allocated in MIFinit_inst */ + /* Don't free name/description! They are not owned */ + /* by the instance */ + for(i = 0; i < num_conn; i++) { + FREE(here->conn[i]); + } + FREE(here->conn); + + /* Loop through all instance variables on the instance */ + /* and free stuff */ + + num_inst_var = here->num_inst_var; + for(i = 0; i < num_inst_var; i++) { + if(here->inst_var[i]->element != NULL) { + FREE(here->inst_var[i]->element); + } + FREE(here->inst_var[i]); + } + FREE(here->inst_var); + + /* ************************************************************* */ + /* Dont free params here. They are not currently implemented on */ + /* a per-instance basis, so their allocated space is owned by */ + /* the parent model, not the instance. Param stuff will be freed */ + /* by MIFmDelete */ + /* ************************************************************* */ + + /* Free the stuff used by the cm_... functions */ + + if(here->num_state && here->state) + FREE(here->state); + if(here->num_intgr && here->intgr) + FREE(here->intgr); + if(here->num_conv && here->conv) + FREE(here->conv); + + + /* Finally, free the instance struct itself */ + FREE(here); + + return(OK); +} diff --git a/src/xspice/mif/mifdestr.c b/src/xspice/mif/mifdestr.c new file mode 100755 index 000000000..c637623ea --- /dev/null +++ b/src/xspice/mif/mifdestr.c @@ -0,0 +1,72 @@ +/*============================================================================ +FILE MIFdestroy.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains a function that deletes all models of a particular + device (code model) type from the circuit description structures. + +INTERFACES + + MIFdestroy() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +/* #include "prefix.h" */ +#include "ngspice.h" +#include + +#include "mifproto.h" + +/* #include "suffix.h" */ + + + +/* +MIFdestroy + +This function deletes all models and all instances of a specified +device type. It traverses the linked list of model structures +for that type and calls MIFmDelete on each model. +*/ + +void MIFdestroy( + GENmodel **inModel) /* The head of the list of models to delete */ +{ + + /* Free all models of this device type by removing */ + /* models from the head of the linked list until */ + /* the head is null */ + + while(*inModel) { + MIFmDelete(inModel, + (*inModel)->GENmodName, + *inModel); + } + +} diff --git a/src/xspice/mif/mifgetmod.c b/src/xspice/mif/mifgetmod.c new file mode 100755 index 000000000..dda0a3176 --- /dev/null +++ b/src/xspice/mif/mifgetmod.c @@ -0,0 +1,235 @@ +/*============================================================================ +FILE + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + + * + * Copyright (c) 1985 Thomas L. Quarles + * + * NOTE: Portions of this code are Copyright Thomas L. Quarles and University of + * California at Berkeley. Other portions are modified and added by + * the Georgia Tech Research Institute. + * + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the routine that allocates a new model structure and + parses the .model card parameters. + +INTERFACES + + MIFgetMod() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +/* #include "prefix.h" */ + +#include "ngspice.h" + + +#include +#include "inpdefs.h" /* maschmann : kleinbuchstaben */ +#include "devdefs.h" /* maschmann : kleinbuchstaben */ +//#include "util.h" +#include "ifsim.h" /* maschmann : kleinbuchstaben */ +#include "cpstd.h" /* maschmann : kleinbuchstaben */ +#include "fteext.h" /* maschmann : kleinbuchstaben */ + +#include "mifproto.h" +#include "mifdefs.h" +#include "mifcmdat.h" + +#include "suffix.h" + + +extern INPmodel *modtab; + +extern SPICEdev **DEVices; /* info about all device types */ + +/* +MIFgetMod + +This function is a modified version of SPICE 3C1 INPgetMod(). +MIFgetMod looks in the table of model information created on the +first pass of the parser to find the text of the .model card. It +then checks to see if the .model card has already been processed +by a previous element card reference. If so, it returns a +pointer to the previously created model structure. If not, it +allocates a new model structure and processes the parameters on +the .model card. Parameter values for parameters not found on +the .model card are not filled in by this function. They are +defaulted later by MIFsetup(). The function returns NULL when +successful, and an error string on failure. +*/ + + +char *MIFgetMod(ckt,name,model,tab) + void *ckt; /* The circuit structure */ + char *name; /* The name of the model to look for */ + INPmodel **model; /* The model found/created */ + INPtables *tab; /* Table of model info from first pass */ +{ + INPmodel *modtmp; + IFvalue * val; + register int j; + char * line; + char *parm; + char *err = NULL; + char *temp; + int error; + + int i; + + char *err1; + char *err2; + + MIFmodel *mdfast; + /* Mif_Param_Info_t *param_info;*/ + + /* locate the named model in the modtab list */ + + + /* maschmann : remove : from name */ + + /* char *pos; + + if((pos=strstr(name,":"))!=NULL) *pos=0; */ + + for (modtmp = modtab; modtmp != NULL; modtmp = ((modtmp)->INPnextModel)) { + + if (strcmp((modtmp)->INPmodName,name) == 0) { + + + + /* found the model in question - now instantiate if necessary */ + /* and return an appropriate pointer to it */ + + /* make sure the type is valid before proceeding */ + if(modtmp->INPmodType<0) { + /* illegal device type, so can't handle */ + *model = NULL; + err = (char *)tmalloc((35+strlen(name)) * sizeof(char)); + sprintf(err, "MIF: Unknown device type for model %s \n",name); + return(err); + } + + /* check to see if this model's parameters have been processed */ + if(! ((modtmp)->INPmodUsed )) { + + /* not already processed, so create data struct */ + error = (*(ft_sim->newModel))( ckt,(modtmp)->INPmodType, + &((modtmp)->INPmodfast), (modtmp)->INPmodName); + if(error) + return(INPerror(error)); + + /* gtri modification: allocate and initialize MIF specific model struct items */ + mdfast = modtmp->INPmodfast; + mdfast->num_param = DEVices[modtmp->INPmodType]->DEVpublic.num_param; + mdfast->param = (void *) tmalloc(mdfast->num_param * sizeof(void *)); + for(i = 0; i < mdfast->num_param; i++) { + mdfast->param[i] = (void *) tmalloc(sizeof(Mif_Param_Data_t)); + mdfast->param[i]->is_null = MIF_TRUE; + mdfast->param[i]->size = 0; + mdfast->param[i]->element = NULL; + } + /* remaining initializations will be done by MIFmParam() and MIFsetup() */ + + /* parameter isolation, identification, binding */ + line = ((modtmp)->INPmodLine)->line; + INPgetTok(&line,&parm,1); /* throw away '.model' */ + INPgetTok(&line,&parm,1); /* throw away 'modname' */ + + /* throw away the modtype - we don't treat it as a parameter */ + /* like SPICE does */ + INPgetTok(&line,&parm,1); /* throw away 'modtype' */ + + while(*line != 0) { + INPgetTok(&line,&parm,1); + for(j=0;j<*((*(ft_sim->devices)[(modtmp)->INPmodType]).numModelParms); j++) { + if (strcmp(parm,((*(ft_sim->devices) [ (modtmp)-> + INPmodType ]).modelParms[j].keyword)) == 0) { + /* gtri modification: call MIFgetValue instead of INPgetValue */ + err1 = NULL; + val = MIFgetValue(ckt,&line, + ((*(ft_sim->devices)[(modtmp)-> + INPmodType ]).modelParms[j]. + dataType),tab,&err1); + if(err1) { + err2 = (void *) tmalloc(25 + strlen(name) + strlen(err1)); + sprintf(err2, "MIF-ERROR - model: %s - %s\n", name, err1); + return(err2); + } + error = (*(ft_sim->setModelParm))(ckt, + ((modtmp)->INPmodfast), + (*(ft_sim->devices)[(modtmp)->INPmodType ]). + modelParms[j].id,val,(IFvalue*)NULL); + if(error) + return(INPerror(error)); + break; + } + } + /* gtri modification: processing of special parameter "level" removed */ + if(j >= *((*(ft_sim->devices)[(modtmp)->INPmodType]).numModelParms)) + { + //err has not been allocated, but free() in INPerrCat() + + // This did not allocate enough memory you wanker, K.A. replaced 5 March 2000 +// temp = (char *)tmalloc((40+strlen(parm)) * sizeof(char)); + temp = (char *)tmalloc((42+strlen(parm)) * sizeof(char));// K.A. replaced 5 March 2000 + + sprintf(temp, "MIF: unrecognized parameter (%s) - ignored\n", parm); + + fprintf(stdout,temp); + err = (char *)tmalloc( (2*strlen(temp) +2)*sizeof(char));// K.A. added 5 March 2000 + + *err = '\0';// K.A. added 5 March 2000 + + err = INPerrCat(err,temp); + } + FREE(parm); + + } /* end while end of line not reached */ + + (modtmp)->INPmodUsed=1; + (modtmp)->INPmodLine->error = err; + + } /* end if model parameters not processed yet */ + + *model = modtmp; + return((char *)NULL); + + } /* end if name matches */ + + } /* end for all models in modtab linked list */ + + + /* didn't find model - ERROR - return NULL model */ + *model = (INPmodel *)NULL; + err = (char *)tmalloc((60+strlen(name)) * sizeof(char)); + sprintf(err, " MIF-ERROR - unable to find definition of model %s\n",name); + + return(err); +} diff --git a/src/xspice/mif/mifgetvalue.c b/src/xspice/mif/mifgetvalue.c new file mode 100755 index 000000000..bd3ad6695 --- /dev/null +++ b/src/xspice/mif/mifgetvalue.c @@ -0,0 +1,368 @@ +/*============================================================================ +FILE MIFgetValue.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the function called to read parameter values from a + .model card. + +INTERFACES + + MIFgetValue() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +/* #include "prefix.h" */ +#include "ngspice.h" +#include +#include "ifsim.h" +//#include "util.h" +#include "inpdefs.h" +#include "inpptree.h" + +/* #include */ +#include + +#include "mifproto.h" +#include "mifparse.h" +#include "mifdefs.h" +#include "mifcmdat.h" + +/* #include "suffix.h" */ + + + +static int MIFget_boolean(char *token, char **err); + +static int MIFget_integer(char *token, char **err); + +static double MIFget_real(char *token, char **err); + +static char *MIFget_string(char *token, char **err); + +static IFcomplex MIFget_complex(char *token, Mif_Token_Type_t token_type, + char **line, char **err); + + + +/* +MIFgetValue + +This function gets a parameter value from the .model text line +into an IFvalue structure. The parameter type is specified in +the argument list and is used to determine how to parse the text +on the .model line. If the parameter is an array, the entire +array is parsed and placed in the IFvalue structure along with +the number of elements found. +*/ + + +IFvalue * +MIFgetValue(ckt,line,type,tab,err) + void *ckt; /* The circuit structure */ + char **line; /* The text line to read value from */ + int type; /* The type of data to read */ + INPtables *tab; /* Unused */ + char **err; /* Error string text */ +{ + static IFvalue val; + + int btemp; + int itemp; + double rtemp; + char *stemp; + IFcomplex ctemp; + + char *token; + Mif_Token_Type_t token_type; + + int value_type; + int is_array; + + + /* Mask off non-type bits */ + value_type = type & IF_VARTYPES; + + /* Setup array boolean */ + is_array = value_type & IF_VECTOR; + + + /* initialize stuff if array */ + if(is_array) { + token = MIFget_token(line, &token_type); + if(token_type != MIF_LARRAY_TOK) { + *err = "Array parameter expected - No array delimiter found"; + return(NULL); + } + val.v.numValue = 0; + val.v.vec.iVec = (void *) MALLOC(1); /* just so that realloc doesn't bomb */ + } + + + /* now get the values into val */ + + while(1) { + + token = MIFget_token(line, &token_type); + + /* exit if no more tokens */ + if(token_type == MIF_NO_TOK) { + *err = "Unexpected end of model card"; + return(NULL); + } + + /* exit if end of array found */ + if(is_array && (token_type == MIF_RARRAY_TOK)) { + if(val.v.numValue == 0) { + *err = "Array parameter must have at least one value"; + return(NULL); + } + break; + } + + /* process the token to extract a value */ + switch(value_type) { + + case IF_FLAG: + val.iValue = MIFget_boolean(token, err); + break; + + case IF_INTEGER: + val.iValue = MIFget_integer(token, err); + break; + + case IF_REAL: + val.rValue = MIFget_real(token, err); + break; + + case IF_STRING: + val.sValue = MIFget_string(token, err); + break; + + case IF_COMPLEX: + val.cValue = MIFget_complex(token, token_type, line, err); + break; + + + case IF_FLAGVEC: + btemp = MIFget_boolean(token, err); + val.v.vec.iVec = (void *) REALLOC(val.v.vec.iVec, + (val.v.numValue + 1) * sizeof(int)); + val.v.vec.iVec[val.v.numValue] = btemp; + val.v.numValue++; + break; + + case IF_INTVEC: + itemp = MIFget_integer(token, err); + val.v.vec.iVec = (void *) REALLOC(val.v.vec.iVec, + (val.v.numValue + 1) * sizeof(int)); + val.v.vec.iVec[val.v.numValue] = itemp; + val.v.numValue++; + break; + + case IF_REALVEC: + rtemp = MIFget_real(token, err); + val.v.vec.rVec = (void *) REALLOC(val.v.vec.rVec, + (val.v.numValue + 1) * sizeof(double)); + val.v.vec.rVec[val.v.numValue] = rtemp; + val.v.numValue++; + break; + + case IF_STRINGVEC: + stemp = MIFget_string(token, err); + val.v.vec.sVec = (void *) REALLOC(val.v.vec.sVec, + (val.v.numValue + 1) * sizeof(char *)); + val.v.vec.sVec[val.v.numValue] = stemp; + val.v.numValue++; + break; + + case IF_CPLXVEC: + ctemp = MIFget_complex(token, token_type, line, err); + val.v.vec.cVec = (void *) REALLOC(val.v.vec.cVec, + (val.v.numValue + 1) * sizeof(IFcomplex)); + val.v.vec.cVec[val.v.numValue] = ctemp; + val.v.numValue++; + break; + + + default: + *err = "Internal error - unexpected value type in MIFgetValue()"; + return(NULL); + + } + + if(*err) + return(NULL); + + /* exit after this single pass if not array */ + if(! is_array) + break; + + } /* end forever loop */ + + + return(&val); +} + + +/* *************************************************************** */ + + +static int MIFget_boolean(char *token, char **err) +{ + *err = NULL; + + if((strcmp(token, "t") == 0) || (strcmp(token, "true") == 0)) + return(1); + else if((strcmp(token, "f") == 0) || (strcmp(token, "false") == 0)) + return(0); + else + *err = "Bad boolean value"; + + return(-1); +} + + +/* *************************************************************** */ + +static int MIFget_integer(char *token, char **err) +{ + int error; + long l; + double dtemp; + char *endp; +/* long strtol(char *, char **, int); */ + + *err = NULL; + + l = strtol(token, &endp, 0); /* handles base 8, 10, 16 automatically */ + + /* if error, probably caused by engineering suffixes, */ + /* so try parsing with INPevaluate */ + if(errno || (*endp != '\0')) { + dtemp = INPevaluate(&token, &error, 1); + if(error) { + *err = "Bad integer, octal, or hex value"; + l = 0; + } + else if(dtemp > 0.0) + l = dtemp + 0.5; + else + l = dtemp - 0.5; + } + + return((int) l); +} + + +/* *************************************************************** */ + +static double MIFget_real(char *token, char **err) +{ + double dtemp; + int error; + + *err = NULL; + + dtemp = INPevaluate(&token, &error, 1); + + if(error) + *err = "Bad real value"; + + return(dtemp); +} + + +/* *************************************************************** */ + +static char *MIFget_string(char *token, char **err) +{ + *err = NULL; + + return(token); +} + + +/* *************************************************************** */ + +static IFcomplex MIFget_complex(char *token, Mif_Token_Type_t token_type, + char **line, char **err) +{ + static char *msg = "Bad complex value"; + + IFcomplex ctemp; + + double dtemp; + int error; + + *err = NULL; + + ctemp.real = 0.0; + ctemp.imag = 0.0; + + /* Complex values must be of form < > */ + if(token_type != MIF_LCOMPLEX_TOK) { + *err = msg; + return(ctemp); + } + + /* get the real part */ + token = MIFget_token(line, &token_type); + if(token_type != MIF_STRING_TOK) { + *err = msg; + return(ctemp); + } + dtemp = INPevaluate(&token, &error, 1); + if(error) { + *err = msg; + return(ctemp); + } + ctemp.real = dtemp; + + /* get the imaginary part */ + token = MIFget_token(line, &token_type); + if(token_type != MIF_STRING_TOK) { + *err = msg; + return(ctemp); + } + dtemp = INPevaluate(&token, &error, 1); + if(error) { + *err = msg; + return(ctemp); + } + ctemp.imag = dtemp; + + /* eat the closing > delimiter */ + token = MIFget_token(line, &token_type); + if(token_type != MIF_RCOMPLEX_TOK) { + *err = msg; + return(ctemp); + } + + return(ctemp); +} diff --git a/src/xspice/mif/mifload.c b/src/xspice/mif/mifload.c new file mode 100755 index 000000000..8202b1ca4 --- /dev/null +++ b/src/xspice/mif/mifload.c @@ -0,0 +1,898 @@ +/*============================================================================ +FILE MIFload.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the driver function for calling code model evaluation + functions. This is one of the most important, complex, and often called + functions in the model interface package. It iterates through all models + and all instances of a specified code model device type, fills in the + inputs for the model, calls the model, and then uses the outputs and + partials returned by the model to load the matrix. + +INTERFACES + + MIFload() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + + +/* #include "prefix.h" */ +#include "ngspice.h" + +#include +#include + +#include "cktdefs.h" +#include "devdefs.h" +#include "sperror.h" + +#include "mifproto.h" +#include "mifparse.h" +#include "mifdefs.h" +#include "mifcmdat.h" +#include "mif.h" + +#include "enh.h" +#include "cm.h" + +/* #include "suffix.h" */ + + + +extern SPICEdev **DEVices; /* info about all device types */ + + + +static void MIFauto_partial( + MIFinstance *here, + void (*cm_func)(), + Mif_Private_t *cm_data +); + + + + + + +/* +MIFload + +This function is called by the CKTload() driver function to call +the C function for each instance of a code model type. It loops +through all models of that type and all instances of each model. +For each instance, it prepares the structure that is passed to +the code model by filling it with the input values for that +instance. The code model's C function is then called, and the +outputs and partial derivatives computed by the C function are +used to fill the matrix for the next solution attempt. +*/ + + +int +MIFload( + GENmodel *inModel, /* The head of the model list */ + CKTcircuit *ckt) /* The circuit structure */ +{ + + MIFmodel *model; + MIFinstance *here; + + Mif_Private_t cm_data; /* data to be passed to/from code model */ + Mif_Port_Type_t type; + Mif_Port_Data_t *fast; + + Mif_Smp_Ptr_t *smp_data_out; + + Mif_Port_Ptr_t *smp_ptr; + + Mif_Port_Type_t in_type; + Mif_Port_Type_t out_type; + + Mif_Boolean_t is_input; + Mif_Boolean_t is_output; + + Mif_Cntl_Src_Type_t cntl_src_type; + + Mif_Analysis_t anal_type; + + Mif_Complex_t czero; + Mif_Complex_t ac_gain; + + int mod_type; + int num_conn; + int num_port; + int num_port_k; + int i; + int j; + int k; + int l; + + /*int tag;*/ + + double *rhs; + double *rhsOld; + double partial; + double temp; + + double *double_ptr0; + double *double_ptr1; + + /*double *input;*/ + /* double *oldinput;*/ + + char *byte_ptr0; + char *byte_ptr1; + + double last_input; + double conv_limit; + + double cntl_input; + + + Evt_Node_Data_t *node_data; + + + /* Prepare a zero complex number for AC gain initializations */ + czero.real = 0.0; + czero.imag = 0.0; + + /* Setup for access into MIF specific model data */ + model = (MIFmodel *) inModel; + mod_type = model->MIFmodType; + + /* Setup pointers for fast access to rhs and rhsOld elements of ckt struct */ + rhs = ckt->CKTrhs; + rhsOld = ckt->CKTrhsOld; + + node_data = ckt->evt->data.node; + + /* *********************************************************************** */ + /* Setup the circuit data in the structure to be passed to the code models */ + /* *********************************************************************** */ + + /* anal_init is set if this is the first iteration at any step in */ + /* an analysis */ + if(!(ckt->CKTmode & MODEINITFLOAT)) + g_mif_info.circuit.anal_init = MIF_TRUE; + cm_data.circuit.anal_init = g_mif_info.circuit.anal_init; + + /* anal_type is determined by CKTload */ + anal_type = g_mif_info.circuit.anal_type; + cm_data.circuit.anal_type = anal_type; + + /* get the analysis freq from the ckt struct if this is an AC analysis */ + /* otherwise, set the freq to zero */ + if(anal_type == MIF_AC) + cm_data.circuit.frequency = ckt->CKTomega; + else + cm_data.circuit.frequency = 0.0; + + /* get the analysis times from the ckt struct if this is a transient analysis */ + /* otherwise, set the times to zero */ + if(anal_type == MIF_TRAN) { + cm_data.circuit.time = ckt->CKTtime; + cm_data.circuit.t[0] = ckt->CKTtime; + for(i = 1; i < 8; i++) { + cm_data.circuit.t[i] = cm_data.circuit.t[i-1] - ckt->CKTdeltaOld[i-1]; + if(cm_data.circuit.t[i] < 0.0) + cm_data.circuit.t[i] = 0.0; + } + } + else { + cm_data.circuit.time = 0.0; + for(i = 0; i < 8; i++) { + cm_data.circuit.t[i] = 0.0; + } + } + + cm_data.circuit.call_type = MIF_ANALOG; + cm_data.circuit.temperature = ckt->CKTtemp - 273.15; + + g_mif_info.circuit.call_type = MIF_ANALOG; + g_mif_info.ckt = ckt; + + + /* ***************************************************************** */ + /* loop through all models of this type */ + /* ***************************************************************** */ + for( ; model != NULL; model = model->MIFnextModel) { + + /* If not an analog or hybrid model, continue to next */ + if(! model->analog) + continue; + + /* ***************************************************************** */ + /* loop through all instances of this model */ + /* ***************************************************************** */ + for(here = model->MIFinstances; here != NULL; here = here->MIFnextInstance) { + /* If not an analog or hybrid instance, continue to next */ + if(! here->analog) + continue; + + /* ***************************************************************** */ + /* Prepare the data needed by the cm_.. functions */ + /* ***************************************************************** */ + g_mif_info.instance = here; + g_mif_info.errmsg = ""; + + if(here->initialized) { + cm_data.circuit.init = MIF_FALSE; + g_mif_info.circuit.init = MIF_FALSE; + } + else { + cm_data.circuit.init = MIF_TRUE; + g_mif_info.circuit.init = MIF_TRUE; + } + + + /* ***************************************************************** */ + /* if tran analysis and anal_init is true, copy state 1 to state 0 */ + /* Otherwise the data in state 0 would be invalid */ + /* ***************************************************************** */ + + if((anal_type == MIF_TRAN) && g_mif_info.circuit.anal_init) { + for(i = 0; i < here->num_state; i++) { + double_ptr0 = ckt->CKTstate0 + here->state[i].index; + double_ptr1 = ckt->CKTstate1 + here->state[i].index; + byte_ptr0 = (char *) double_ptr0; + byte_ptr1 = (char *) double_ptr1; + for(j = 0; j < here->state[i].bytes; j++) + byte_ptr0[j] = byte_ptr1[j]; + } + } + + /* ***************************************************************** */ + /* If not AC analysis, loop through all connections on this instance */ + /* and load the input values for each input port of each connection */ + /* ***************************************************************** */ + + num_conn = here->num_conn; + for(i = 0; i < num_conn; i++) { + + /* If AC analysis, skip getting input values. The input values */ + /* should stay the same as they were at the last iteration of */ + /* the operating point analysis */ + if(anal_type == MIF_AC) + break; + + /* if the connection is null, skip to next connection */ + if(here->conn[i]->is_null) + continue; + + /* if this connection is not an input, skip to next connection */ + if(! here->conn[i]->is_input) + continue; + + /* Get number of ports on this connection */ + num_port = here->conn[i]->size; + + /* loop through all ports on this connection */ + for(j = 0; j < num_port; j++) { + + /*setup a pointer for fast access to port data */ + fast = here->conn[i]->port[j]; + + /* skip if this port is null */ + if(fast->is_null) + continue; + + /* determine the type of this port */ + type = fast->type; + + /* If port type is Digital or User-Defined, we only need */ + /* to get the total load. The input values are pointers */ + /* already set by EVTsetup() */ + if((type == MIF_DIGITAL) || (type == MIF_USER_DEFINED)) { + fast->total_load = + node_data->total_load[fast->evt_data.node_index]; + } + /* otherwise, it is an analog node and we get the input value */ + else { + /* load the input values based on type and mode */ + if(ckt->CKTmode & MODEINITJCT) + /* first iteration step for DC */ + fast->input.rvalue = 0.0; + else if((ckt->CKTmode & MODEINITTRAN) || + (ckt->CKTmode & MODEINITPRED)) + /* first iteration step at timepoint */ + fast->input.rvalue = *(ckt->CKTstate1 + fast->old_input); + else { + /* subsequent iterations */ + + /* record last iteration's input value for convergence limiting */ + last_input = fast->input.rvalue; + + /* get the new input value */ + switch(type) { + case MIF_VOLTAGE: + case MIF_DIFF_VOLTAGE: + case MIF_CONDUCTANCE: + case MIF_DIFF_CONDUCTANCE: + fast->input.rvalue = rhsOld[fast->smp_data.pos_node] - + rhsOld[fast->smp_data.neg_node]; + break; + case MIF_CURRENT: + case MIF_DIFF_CURRENT: + case MIF_VSOURCE_CURRENT: + case MIF_RESISTANCE: + case MIF_DIFF_RESISTANCE: + fast->input.rvalue = rhsOld[fast->smp_data.ibranch]; + break; + case MIF_DIGITAL: + case MIF_USER_DEFINED: + break; + } /* end switch on type of port */ + + /* If convergence limiting enabled, limit maximum input change */ + if(ckt->enh->conv_limit.enabled) { + /* compute the maximum the input is allowed to change */ + conv_limit = fabs(last_input) * ckt->enh->conv_limit.step; + if(conv_limit < ckt->enh->conv_limit.abs_step) + conv_limit = ckt->enh->conv_limit.abs_step; + /* if input has changed too much, limit it and signal not converged */ + if(fabs(fast->input.rvalue - last_input) > conv_limit) { + if((fast->input.rvalue - last_input) > 0.0) + fast->input.rvalue = last_input + conv_limit; + else + fast->input.rvalue = last_input - conv_limit; + (ckt->CKTnoncon)++; + /* report convergence problem if last call */ + if(ckt->enh->conv_debug.report_conv_probs) { + ENHreport_conv_prob(ENH_ANALOG_INSTANCE, + (char *) here->MIFname, ""); + } + } + } + + } /* end else */ + + /* Save value of input for use with MODEINITTRAN */ + *(ckt->CKTstate0 + fast->old_input) = fast->input.rvalue; + + } /* end else analog type */ + } /* end for number of ports */ + } /* end for number of connections */ + + /* ***************************************************************** */ + /* loop through all connections on this instance and zero out all */ + /* outputs/partials/AC gains for each output port of each connection */ + /* ***************************************************************** */ + num_conn = here->num_conn; + for(i = 0; i < num_conn; i++) { + + /* if the connection is null or is not an output */ + /* skip to next connection */ + if(here->conn[i]->is_null || (! here->conn[i]->is_output)) + continue; + + /* loop through all ports on this connection */ + num_port = here->conn[i]->size; + for(j = 0; j < num_port; j++) { + + /*setup a pointer for fast access to port data */ + fast = here->conn[i]->port[j]; + + /* skip if this port is null */ + if(fast->is_null) + continue; + + /* determine the type of this port */ + type = fast->type; + + /* If not an analog node, continue to next port */ + if((type == MIF_DIGITAL) || (type == MIF_USER_DEFINED)) + continue; + + /* initialize the output to zero */ + fast->output.rvalue = 0.0; + + /* loop through all connections and ports that */ + /* could be inputs for this port and zero the partials */ + for(k = 0; k < num_conn; k++) { + if(here->conn[k]->is_null || (! here->conn[k]->is_input)) + continue; + num_port_k = here->conn[k]->size; + for(l = 0; l < num_port_k; l++) { + /* skip if this port is null */ + if(here->conn[k]->port[l]->is_null) + continue; + fast->partial[k].port[l] = 0.0; + fast->ac_gain[k].port[l] = czero; + } /* end for number of ports */ + } /* end for number of connections */ + } /* end for number of ports */ + } /* end for number of connections */ + + + /* ***************************************************************** */ + /* Prepare the structure to be passed to the code model */ + /* ***************************************************************** */ + cm_data.num_conn = here->num_conn; + cm_data.conn = here->conn; + cm_data.num_param = here->num_param; + cm_data.param = here->param; + cm_data.num_inst_var = here->num_inst_var; + cm_data.inst_var = here->inst_var; + + /* Initialize the auto_partial flag to false */ + g_mif_info.auto_partial.local = MIF_FALSE; + + /* ******************* */ + /* Call the code model */ + /* ******************* */ + (*(DEVices[mod_type]->DEVpublic.cm_func)) (&cm_data); + + /* Automatically compute partials if requested by .options auto_partial */ + /* or by model through call to cm_analog_auto_partial() in DC or TRAN analysis */ + if((anal_type != MIF_AC) && + (g_mif_info.auto_partial.global || g_mif_info.auto_partial.local)) + MIFauto_partial(here, DEVices[mod_type]->DEVpublic.cm_func, &cm_data); + + /* ***************************************************************** */ + /* Loop through all connections on this instance and */ + /* load the data into the matrix for each output port */ + /* and for each V source associated with a current input. */ + /* For AC analysis, we only load the +-1s required to satisfy */ + /* KCL and KVL in the matrix equations. */ + /* ***************************************************************** */ + + num_conn = here->num_conn; + for(i = 0; i < num_conn; i++) { + + /* if the connection is null, skip to next connection */ + if(here->conn[i]->is_null) + continue; + + /* prepare things for convenient access later */ + is_input = here->conn[i]->is_input; + is_output = here->conn[i]->is_output; + + /* loop through all ports on this connection */ + num_port = here->conn[i]->size; + for(j = 0; j < num_port; j++) { + + /*setup a pointer for fast access to port data */ + fast = here->conn[i]->port[j]; + + /* skip if this port is null */ + if(fast->is_null) + continue; + + /* determine the type of this port */ + type = fast->type; + + /* If not an analog node, continue to next port */ + if((type == MIF_DIGITAL) || (type == MIF_USER_DEFINED)) + continue; + + /* create a pointer to the smp data for quick access */ + smp_data_out = &(fast->smp_data); + + /* if it is a current input */ + /* load the matrix data needed for the associated zero-valued V source */ + if(is_input && (type == MIF_CURRENT || type == MIF_DIFF_CURRENT)) { + *(smp_data_out->pos_ibranch) += 1.0; + *(smp_data_out->neg_ibranch) -= 1.0; + *(smp_data_out->ibranch_pos) += 1.0; + *(smp_data_out->ibranch_neg) -= 1.0; + /* rhs[smp_data_out->ibranch] += 0.0; */ + } /* end if current input */ + + /* if it has a voltage source output, */ + /* load the matrix with the V source output data */ + if( (is_output && (type == MIF_VOLTAGE || type == MIF_DIFF_VOLTAGE)) || + (type == MIF_RESISTANCE || type == MIF_DIFF_RESISTANCE) ) { + *(smp_data_out->pos_branch) += 1.0; + *(smp_data_out->neg_branch) -= 1.0; + *(smp_data_out->branch_pos) += 1.0; + *(smp_data_out->branch_neg) -= 1.0; + if(anal_type != MIF_AC) + rhs[smp_data_out->branch] += fast->output.rvalue; + } /* end if V source output */ + + /* if it has a current source output, */ + /* load the matrix with the V source output data */ + if( (is_output && (type == MIF_CURRENT || type == MIF_DIFF_CURRENT)) || + (type == MIF_CONDUCTANCE || type == MIF_DIFF_CONDUCTANCE) ) { + if(anal_type != MIF_AC) { + rhs[smp_data_out->pos_node] -= fast->output.rvalue; + rhs[smp_data_out->neg_node] += fast->output.rvalue; + } + } /* end if current output */ + + } /* end for number of ports */ + } /* end for number of connections */ + + + /* ***************************************************************** */ + /* loop through all output connections on this instance and */ + /* load the partials/AC gains into the matrix */ + /* ***************************************************************** */ + for(i = 0; i < num_conn; i++) { + + /* if the connection is null or is not an output */ + /* skip to next connection */ + if((here->conn[i]->is_null) || (! here->conn[i]->is_output)) + continue; + + /* loop through all ports on this connection */ + num_port = here->conn[i]->size; + for(j = 0; j < num_port; j++) { + + /*setup a pointer for fast access to port data */ + fast = here->conn[i]->port[j]; + + /* skip if this port is null */ + if(fast->is_null) + continue; + + /* determine the type of this output port */ + out_type = fast->type; + + /* If not an analog node, continue to next port */ + if((out_type == MIF_DIGITAL) || (out_type == MIF_USER_DEFINED)) + continue; + + /* create a pointer to the smp data for quick access */ + smp_data_out = &(fast->smp_data); + + /* for this port, loop through all connections */ + /* and all ports to touch on each possible input */ + for(k = 0; k < num_conn; k++) { + + /* if the connection is null or is not an input */ + /* skip to next connection */ + if((here->conn[k]->is_null) || (! here->conn[k]->is_input)) + continue; + + num_port_k = here->conn[k]->size; + /* loop through all the ports of this connection */ + for(l = 0; l < num_port_k; l++) { + + /* skip if this port is null */ + if(here->conn[k]->port[l]->is_null) + continue; + + /* determine the type of this input port */ + in_type = here->conn[k]->port[l]->type; + + /* If not an analog node, continue to next port */ + if((in_type == MIF_DIGITAL) || (in_type == MIF_USER_DEFINED)) + continue; + + /* get the partial to local variable for fast access */ + partial = fast->partial[k].port[l]; + ac_gain = fast->ac_gain[k].port[l]; + + /* create a pointer to the matrix pointer data for quick access */ + smp_ptr = &(smp_data_out->input[k].port[l]); + + /* get the input value */ + cntl_input = here->conn[k]->port[l]->input.rvalue; + + /* determine type of controlled source according */ + /* to input and output types */ + cntl_src_type = MIFget_cntl_src_type(in_type, out_type); + + switch(cntl_src_type) { + case MIF_VCVS: + if(anal_type == MIF_AC) { + *(smp_ptr->e.branch_poscntl) -= ac_gain.real; + *(smp_ptr->e.branch_negcntl) += ac_gain.real; + *(smp_ptr->e.branch_poscntl+1) -= ac_gain.imag; + *(smp_ptr->e.branch_negcntl+1) += ac_gain.imag; + } + else { + *(smp_ptr->e.branch_poscntl) -= partial; + *(smp_ptr->e.branch_negcntl) += partial; + rhs[smp_data_out->branch] -= partial * cntl_input; + } + break; + case MIF_ICIS: + if(anal_type == MIF_AC) { + *(smp_ptr->f.pos_ibranchcntl) += ac_gain.real; + *(smp_ptr->f.neg_ibranchcntl) -= ac_gain.real; + *(smp_ptr->f.pos_ibranchcntl+1) += ac_gain.imag; + *(smp_ptr->f.neg_ibranchcntl+1) -= ac_gain.imag; + } + else { + *(smp_ptr->f.pos_ibranchcntl) += partial; + *(smp_ptr->f.neg_ibranchcntl) -= partial; + temp = partial * cntl_input; + rhs[smp_data_out->pos_node] += temp; + rhs[smp_data_out->neg_node] -= temp; + } + break; + case MIF_VCIS: + if(anal_type == MIF_AC) { + *(smp_ptr->g.pos_poscntl) += ac_gain.real; + *(smp_ptr->g.pos_negcntl) -= ac_gain.real; + *(smp_ptr->g.neg_poscntl) -= ac_gain.real; + *(smp_ptr->g.neg_negcntl) += ac_gain.real; + *(smp_ptr->g.pos_poscntl+1) += ac_gain.imag; + *(smp_ptr->g.pos_negcntl+1) -= ac_gain.imag; + *(smp_ptr->g.neg_poscntl+1) -= ac_gain.imag; + *(smp_ptr->g.neg_negcntl+1) += ac_gain.imag; + } + else { + *(smp_ptr->g.pos_poscntl) += partial; + *(smp_ptr->g.pos_negcntl) -= partial; + *(smp_ptr->g.neg_poscntl) -= partial; + *(smp_ptr->g.neg_negcntl) += partial; + temp = partial * cntl_input; + rhs[smp_data_out->pos_node] += temp; + rhs[smp_data_out->neg_node] -= temp; + } + break; + case MIF_ICVS: + if(anal_type == MIF_AC) { + *(smp_ptr->h.branch_ibranchcntl) -= ac_gain.real; + *(smp_ptr->h.branch_ibranchcntl+1) -= ac_gain.imag; + } + else { + *(smp_ptr->h.branch_ibranchcntl) -= partial; + rhs[smp_data_out->branch] -= partial * cntl_input; + } + break; + } /* end switch on controlled source type */ + } /* end for number of input ports */ + } /* end for number of input connections */ + } /* end for number of output ports */ + } /* end for number of output connections */ + + here->initialized = MIF_TRUE; + + } /* end for all instances */ + + } /* end for all models */ + + return(OK); +} + + + + +/* +MIFauto_partial + +This function is called by MIFload() when a code model requests +that partial derivatives be computed automatically. It calls +the code model additional times with an individual input to the +model varied by a small amount at each call. Partial +derivatives of each output with respect to the varied input +are then computed by divided differences. +*/ + + +static void MIFauto_partial( + MIFinstance *here, /* The instance structure */ + void (*cm_func)(), /* The code model function to be called */ + Mif_Private_t *cm_data) /* The data to be passed to the code model */ +{ + + Mif_Port_Data_t *fast; + Mif_Port_Data_t *out_fast; + + Mif_Port_Type_t type; + Mif_Port_Type_t out_type; + + int num_conn; + int num_port; + int num_port_k; + + int i; + int j; + int k; + int l; + + double epsilon; + double nominal_input; + + + /* Reset init and anal_init flags before making additional calls */ + /* to the model */ + cm_data->circuit.init = MIF_FALSE; + g_mif_info.circuit.init = MIF_FALSE; + + cm_data->circuit.anal_init = MIF_FALSE; + g_mif_info.circuit.anal_init = MIF_FALSE; + + + /* *************************** */ + /* Save nominal analog outputs */ + /* *************************** */ + + /* loop through all connections */ + num_conn = here->num_conn; + for(i = 0; i < num_conn; i++) { + + /* if the connection is null or is not an output */ + /* skip to next connection */ + if(here->conn[i]->is_null || (! here->conn[i]->is_output)) + continue; + + /* loop through all ports on this connection */ + num_port = here->conn[i]->size; + for(j = 0; j < num_port; j++) { + + /*setup a pointer for fast access to port data */ + fast = here->conn[i]->port[j]; + + /* skip if this port is null */ + if(fast->is_null) + continue; + + /* determine the type of this port */ + type = fast->type; + + /* If not an analog port, continue to next port */ + if((type == MIF_DIGITAL) || (type == MIF_USER_DEFINED)) + continue; + + /* copy the output for use in computing output deltas */ + fast->nominal_output = fast->output.rvalue; + + } /* end for number of output ports */ + } /* end for number of output connections */ + + + /* ***************************************************************** */ + /* Change each analog input by a small amount and call the model to */ + /* compute new outputs. */ + /* ***************************************************************** */ + + /* loop through all connections */ + num_conn = here->num_conn; + for(i = 0; i < num_conn; i++) { + + /* if the connection is null, skip to next connection */ + if(here->conn[i]->is_null) + continue; + + /* if this connection is not an input, skip to next connection */ + if(! here->conn[i]->is_input) + continue; + + /* Get number of ports on this connection */ + num_port = here->conn[i]->size; + + /* loop through all ports on this connection */ + for(j = 0; j < num_port; j++) { + + /*setup a pointer for fast access to port data */ + fast = here->conn[i]->port[j]; + + /* skip if this port is null */ + if(fast->is_null) + continue; + + /* determine the type of this port */ + type = fast->type; + + /* If port type is Digital or User-Defined, skip it */ + if((type == MIF_DIGITAL) || (type == MIF_USER_DEFINED)) + continue; + + /* otherwise, it is an analog port and we need to perturb it and */ + /* then call the model */ + + /* compute the perturbation amount depending on type of input */ + switch(type) { + case MIF_VOLTAGE: + case MIF_DIFF_VOLTAGE: + case MIF_CONDUCTANCE: + case MIF_DIFF_CONDUCTANCE: + epsilon = 1.0e-6; + break; + + case MIF_CURRENT: + case MIF_DIFF_CURRENT: + case MIF_VSOURCE_CURRENT: + case MIF_RESISTANCE: + case MIF_DIFF_RESISTANCE: + epsilon = 1.0e-12; + break; + + default: + printf("INTERNAL ERROR - MIFauto_partial. Invalid port type\n"); + epsilon = 1.0e-30; + break; + } /* end switch on type of port */ + + /* record and perturb input value */ + nominal_input = fast->input.rvalue; + fast->input.rvalue += epsilon; + + + /* call model to compute new outputs */ + (*cm_func)(cm_data); + + + /* ******************************************************* */ + /* Compute the partials of each output with respect to the */ + /* perturbed input by divided differences. */ + /* ******************************************************* */ + + /* loop through all analog output connections */ + for(k = 0; k < num_conn; k++) { + + /* if the connection is null or is not an output */ + /* skip to next connection */ + if((here->conn[k]->is_null) || (! here->conn[k]->is_output)) + continue; + + /* loop through all the ports of this connection */ + num_port_k = here->conn[k]->size; + for(l = 0; l < num_port_k; l++) { + + /*setup a pointer for out_fast access to port data */ + out_fast = here->conn[k]->port[l]; + + /* skip if this port is null */ + if(out_fast->is_null) + continue; + + /* determine the out_type of this port */ + out_type = out_fast->type; + + /* If port type is Digital or User-Defined, skip it */ + if((out_type == MIF_DIGITAL) || (out_type == MIF_USER_DEFINED)) + continue; + + /* compute partial by divided differences */ + out_fast->partial[i].port[j] = + (out_fast->output.rvalue - out_fast->nominal_output) / epsilon; + + /* zero the output in preparation for next call */ + out_fast->output.rvalue = 0.0; + + } /* end for number of output ports */ + } /* end for number of output connections */ + + /* restore nominal input value */ + fast->input.rvalue = nominal_input; + + } /* end for number of input ports */ + } /* end for number of input connections */ + + + /* *************************************************** */ + /* Call model one last time to recompute nominal case. */ + /* *************************************************** */ + + /* This is needed even though the outputs are recorded, because */ + /* the model may compute other state values that cannot be restored */ + /* to the nominal condition from here */ + + (*cm_func)(cm_data); + +} + + + diff --git a/src/xspice/mif/mifmask.c b/src/xspice/mif/mifmask.c new file mode 100755 index 000000000..3004fd491 --- /dev/null +++ b/src/xspice/mif/mifmask.c @@ -0,0 +1,220 @@ +/*============================================================================ +FILE MIFmAsk.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the function called by nutmeg to get the value + of a specified code model parameter. + +INTERFACES + + MIFmAsk() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +/* #include "prefix.h" */ +#include "ngspice.h" +#include +//#include "CONST.h" +//#include "util.h" +#include "ifsim.h" +#include "devdefs.h" +#include "sperror.h" + +#include + +#include "mifproto.h" +#include "mifdefs.h" + +/* #include "suffix.h" */ + + + +extern SPICEdev **DEVices; +extern int DEVmaxnum; + + + + +/* +MIFmAsk + +This function is called by SPICE/Nutmeg to query the value of a +parameter on a model. It is essentially the opposite of +MIFmParam, taking the index of the parameter, locating the value +of the parameter in the model structure, and converting that +value into the IFvalue structure understood by Nutmeg. +*/ + + +int MIFmAsk( + CKTcircuit *ckt, /* The circuit structure */ + GENmodel *inModel, /* The model to get the value from */ + int param_index, /* The parameter to get */ + IFvalue *value) /* The value returned */ +{ + + MIFmodel *model; + int mod_type; + int value_type; + int i; + int size; + + Mif_Boolean_t is_array; + + + /* Arrange for access to MIF specific data in the model */ + model = (MIFmodel *) inModel; + + + /* Get model type */ + mod_type = model->MIFmodType; + if((mod_type < 0) || (mod_type >= DEVmaxnum)) + return(E_BADPARM); + + + /* Check parameter index for validity */ + if((param_index < 0) || (param_index >= model->num_param)) + return(E_BADPARM); + + /* get value type to know which members of unions to access */ + value_type = DEVices[mod_type]->DEVpublic.modelParms[param_index].dataType; + value_type &= IF_VARTYPES; + + + /* determine if the parameter is an array or not */ + is_array = value_type & IF_VECTOR; + + + /* Transfer the values to the SPICE3C1 value union from the param elements */ + /* This is analagous to what SPICE3 does with other device types */ + + + if(! is_array) { + + switch(value_type) { + + case IF_FLAG: + value->iValue = model->param[param_index]->element[0].bvalue; + break; + + case IF_INTEGER: + value->iValue = model->param[param_index]->element[0].ivalue; + break; + + case IF_REAL: + value->rValue = model->param[param_index]->element[0].rvalue; + break; + + case IF_STRING: + /* Make copy of string. We don't trust caller to not free it */ + /* These copies could get expensive! */ + value->sValue = MIFcopy(model->param[param_index]->element[0].svalue); + break; + + case IF_COMPLEX: + /* we don't trust the caller to have a parallel complex structure */ + /* so copy the real and imaginary parts explicitly */ + value->cValue.real = model->param[param_index]->element[0].cvalue.real; + value->cValue.imag = model->param[param_index]->element[0].cvalue.imag; + break; + + default: + return(E_BADPARM); + + } + } + else { /* it is an array */ + + size = model->param[param_index]->size; + if(size < 0) + size = 0; + + value->v.numValue = size; + + switch(value_type) { + + /* Note that we malloc space each time this function is called. */ + /* This is what TRAask.c does, so we do it too, even though */ + /* we don't know if it is ever freed... */ + + case IF_FLAGVEC: + if(size <= 0) + break; + value->v.vec.iVec = (void *) MALLOC(size * sizeof(int)); + for(i = 0; i < size; i++) + value->v.vec.iVec[i] = model->param[param_index]->element[i].bvalue; + break; + + case IF_INTVEC: + if(size <= 0) + break; + value->v.vec.iVec = (void *) MALLOC(size * sizeof(int)); + for(i = 0; i < size; i++) + value->v.vec.iVec[i] = model->param[param_index]->element[i].ivalue; + break; + + case IF_REALVEC: + if(size <= 0) + break; + value->v.vec.rVec = (void *) MALLOC(size * sizeof(double)); + for(i = 0; i < size; i++) + value->v.vec.rVec[i] = model->param[param_index]->element[i].rvalue; + break; + + case IF_STRINGVEC: + if(size <= 0) + break; + value->v.vec.sVec = (void *) MALLOC(size * sizeof(char *)); + for(i = 0; i < size; i++) + /* Make copy of string. We don't trust caller to not free it */ + /* These copies could get expensive! */ + value->v.vec.sVec[i] = MIFcopy(model->param[param_index]->element[i].svalue); + break; + + case IF_CPLXVEC: + if(size <= 0) + break; + /* we don't trust the caller to have a parallel complex structure */ + /* so copy the real and imaginary parts explicitly */ + value->v.vec.cVec = (void *) MALLOC(size * sizeof(IFcomplex)); + for(i = 0; i < size; i++) { + value->v.vec.cVec[i].real = model->param[param_index]->element[i].cvalue.real; + value->v.vec.cVec[i].imag = model->param[param_index]->element[i].cvalue.imag; + } + break; + + default: + return(E_BADPARM); + + } /* end switch */ + + } /* end else */ + + return(OK); +} diff --git a/src/xspice/mif/mifmdelete.c b/src/xspice/mif/mifmdelete.c new file mode 100755 index 000000000..57c268b7a --- /dev/null +++ b/src/xspice/mif/mifmdelete.c @@ -0,0 +1,123 @@ +/*============================================================================ +FILE MIFmDelete.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the function called by SPICE to delete a model + structure and all instances of that model. + +INTERFACES + + MIFmDelete() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +/* #include "prefix.h" */ +#include "ngspice.h" +#include +//#include "util.h" +#include "sperror.h" +#include "gendefs.h" + +#include "mifproto.h" +#include "mifdefs.h" + +/* #include "suffix.h" */ + + + + +/* +MIFmDelete + +This function deletes a particular model defined by a .model card +from the linked list of model structures of a particular code +model type, freeing all dynamically allocated memory used by the +model structure. It calls MIFdelete as needed to delete all +instances of the specified model. +*/ + + +int MIFmDelete( + GENmodel **inModel, /* The head of the model list */ + IFuid modname, /* The name of the model to delete */ + GENmodel *kill /* The model structure to be deleted */ +) +{ + MIFmodel **model; + MIFmodel *modfast; + MIFmodel **oldmod; + MIFmodel *here=NULL; + + Mif_Boolean_t found; + + int i; + + + /* Convert the generic pointers to MIF specific pointers */ + model = (MIFmodel **) inModel; + modfast = (MIFmodel *) kill; + + /* Locate the model by name or pointer and cut it out of the list */ + oldmod = model; + for(found = MIF_FALSE; *model; model = &((*model)->MIFnextModel)) { + if( (*model)->MIFmodName == modname || + (modfast && *model == modfast) ) { + here = *model; + *oldmod = (*model)->MIFnextModel; + found = MIF_TRUE; + break; + } + oldmod = model; + } + + if(! found) + return(E_NOMOD); + + /* Free the instances under this model if any */ + /* by removing from the head of the linked list */ + /* until the head is null */ + while(here->MIFinstances) { + MIFdelete((GENmodel *) here, + here->MIFinstances->MIFname, + (GENinstance **) &(here->MIFinstances)); + } + + /* Free the model params stuff allocated in MIFget_mod */ + for(i = 0; i < here->num_param; i++) { + if(here->param[i]->element) + FREE(here->param[i]->element); + FREE(here->param[i]); + } + FREE(here->param); + + /* Free the model and return */ + FREE(here); + return(OK); + +} diff --git a/src/xspice/mif/mifmpara.c b/src/xspice/mif/mifmpara.c new file mode 100755 index 000000000..f7bc28b64 --- /dev/null +++ b/src/xspice/mif/mifmpara.c @@ -0,0 +1,211 @@ +/*============================================================================ +FILE MIFmParam.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the function used to assign the value of a parameter + read from the .model card into the appropriate structure in the model. + +INTERFACES + + MIFmParam() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +/* #include "prefix.h" */ +#include "ngspice.h" +#include +//#include "CONST.h" +//#include "util.h" +#include "ifsim.h" +//#include "resdefs.h" +#include "devdefs.h" +#include "sperror.h" + +#include + +#include "mifproto.h" +#include "mifparse.h" +#include "mifdefs.h" +#include "mifcmdat.h" + +/* #include "suffix.h" */ + + + +extern SPICEdev **DEVices; +extern int DEVmaxnum; + + + + +/* +MIFmParam + +This function is called by SPICE/Nutmeg to set the value of a +parameter on a model according to information parsed from a +.model card or information supplied interactively by a user. It +takes the value of the parameter input in an IFvalue structure +and sets the parameter on the specified model structure. Unlike +the procedure for SPICE 3C1 devices, MIFmParam does not use +enumerations for identifying the parameter to set. Instead, the +parameter is identified directly by the index value of the +parameter in the SPICEdev.DEVpublic.modelParms array. +*/ + +int MIFmParam( + int param_index, /* The parameter to set */ + IFvalue *value, /* The value of the parameter */ + GENmodel *inModel) /* The model structure on which to set the value */ +{ + + MIFmodel *model; + int mod_type; + int value_type; + int i; + + Mif_Boolean_t is_array; + + + /* Arrange for access to MIF specific data in the model */ + model = (MIFmodel *) inModel; + + + /* Get model type */ + mod_type = model->MIFmodType; + if((mod_type < 0) || (mod_type >= DEVmaxnum)) + return(E_BADPARM); + + + /* Check parameter index for validity */ + if((param_index < 0) || (param_index >= model->num_param)) + return(E_BADPARM); + + /* get value type to know which members of unions to access */ + value_type = DEVices[mod_type]->DEVpublic.modelParms[param_index].dataType; + value_type &= IF_VARTYPES; + + + /* determine if the parameter is an array or not */ + is_array = value_type & IF_VECTOR; + + /* initialize the parameter is_null and size elements and allocate elements */ + model->param[param_index]->is_null = MIF_FALSE; + if(is_array) { + model->param[param_index]->size = value->v.numValue; + model->param[param_index]->element = (void *) MALLOC(value->v.numValue * + sizeof(Mif_Value_t)); + } + else { + model->param[param_index]->size = 1; + model->param[param_index]->element = (void *) MALLOC(sizeof(Mif_Value_t)); + } + + + /* Transfer the values from the SPICE3C1 value union to the param elements */ + /* This is analagous to what SPICE3 does with other device types */ + + + if(! is_array) { + + switch(value_type) { + + case IF_FLAG: + model->param[param_index]->element[0].bvalue = value->iValue; + break; + + case IF_INTEGER: + model->param[param_index]->element[0].ivalue = value->iValue; + break; + + case IF_REAL: + model->param[param_index]->element[0].rvalue = value->rValue; + break; + + case IF_STRING: + /* we don't trust the caller to keep the string alive, so copy it */ + model->param[param_index]->element[0].svalue = + (void *) MALLOC(1 + strlen(value->sValue)); + strcpy(model->param[param_index]->element[0].svalue, value->sValue); + break; + + case IF_COMPLEX: + /* we don't trust the caller to have a parallel complex structure */ + /* so copy the real and imaginary parts explicitly */ + model->param[param_index]->element[0].cvalue.real = value->cValue.real; + model->param[param_index]->element[0].cvalue.imag = value->cValue.imag; + break; + + default: + return(E_BADPARM); + + } + } + else { /* it is an array */ + + for(i = 0; i < value->v.numValue; i++) { + + switch(value_type) { + + case IF_FLAGVEC: + model->param[param_index]->element[i].bvalue = value->v.vec.iVec[i]; + break; + + case IF_INTVEC: + model->param[param_index]->element[i].ivalue = value->v.vec.iVec[i]; + break; + + case IF_REALVEC: + model->param[param_index]->element[i].rvalue = value->v.vec.rVec[i]; + break; + + case IF_STRINGVEC: + /* we don't trust the caller to keep the string alive, so copy it */ + model->param[param_index]->element[i].svalue = + (void *) MALLOC(1 + strlen(value->v.vec.sVec[i])); + strcpy(model->param[param_index]->element[i].svalue, value->v.vec.sVec[i]); + break; + + case IF_CPLXVEC: + /* we don't trust the caller to have a parallel complex structure */ + /* so copy the real and imaginary parts explicitly */ + model->param[param_index]->element[i].cvalue.real = value->v.vec.cVec[i].real; + model->param[param_index]->element[i].cvalue.imag = value->v.vec.cVec[i].imag; + break; + + default: + return(E_BADPARM); + + } /* end switch */ + + } /* end for number of elements of vector */ + + } /* end else */ + + return(OK); +} diff --git a/src/xspice/mif/mifsetup.c b/src/xspice/mif/mifsetup.c new file mode 100755 index 000000000..11708aa44 --- /dev/null +++ b/src/xspice/mif/mifsetup.c @@ -0,0 +1,456 @@ +/*============================================================================ +FILE MIFsetup.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the function called by SPICE to setup data structures + of a code model after parsing, but prior to beginning a simulation. The + major responsibilities of this function are to default values for model + parameters not given on the .model card, create equations in the matrix + for any voltage sources, and setup the matrix pointers used during + simulation to load the matrix. + +INTERFACES + + MIFsetup() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + + +/* #include "prefix.h" */ +#include "ngspice.h" +#include +//#include "util.h" +#include "smpdefs.h" +#include "devdefs.h" +#include "sperror.h" + +#include "mifproto.h" +#include "mifparse.h" +#include "mifdefs.h" +#include "mifcmdat.h" + +/* #include "suffix.h" */ + + + +extern SPICEdev **DEVices; /* info about all device types */ + + + +/* define macro for easy creation of matrix entries/pointers for outputs */ +#define TSTALLOC(ptr,first,second) \ + if((smp_data_out->ptr = \ + SMPmakeElt(matrix, smp_data_out->first, smp_data_out->second)) == NULL) { \ + return(E_NOMEM); \ + } + +/* define macro for easy creation of matrix entries/pointers for inputs */ +#define CTSTALLOC(ptr,first,second) \ + if((smp_data_out->input[k].port[l].ptr = \ + SMPmakeElt(matrix, smp_data_out->first, smp_data_cntl->second)) == NULL) { \ + return(E_NOMEM); \ + } + + + +/* +MIFsetup + +This function is called by the CKTsetup() driver function to +prepare all code model structures and all code model instance +structures for simulation. It loops through all models of a +particular code model type and provides defaults for any +parameters not specified on a .model card. It loops through all +instances of the model and prepares the instance structures for +simulation. The most important setup task is the creation of +entries in the SPICE matrix and the storage of pointers to +locations of the matrix used by MIFload during a simulation. +*/ + + +int +MIFsetup( + SMPmatrix *matrix, /* The analog simulation matrix structure */ + GENmodel *inModel, /* The head of the model list */ + CKTcircuit *ckt, /* The circuit structure */ + int *states) /* The states vector */ +{ + MIFmodel *model; + MIFinstance *here; + + int mod_type; + int max_size; + int size; + int error; + + int num_conn; + int num_port; + int num_port_k; + int i; + int j; + int k; + int l; + + Mif_Port_Type_t type; + Mif_Port_Type_t in_type; + Mif_Port_Type_t out_type; + + Mif_Cntl_Src_Type_t cntl_src_type; + + Mif_Smp_Ptr_t *smp_data_out; + Mif_Smp_Ptr_t *smp_data_cntl; + + Mif_Param_Info_t *param_info; + /* Mif_Conn_Info_t *conn_info;*/ + + Mif_Boolean_t is_input; + Mif_Boolean_t is_output; + + char *suffix; + CKTnode *tmp; + + + /* Setup for access into MIF specific model data */ + model = (MIFmodel *) inModel; + mod_type = model->MIFmodType; + + + /* loop through all models of this type */ + + for( ; model != NULL; model = model->MIFnextModel) { + + + /* For each parameter not given explicitly on the .model */ + /* card, default it */ + + for(i = 0; i < model->num_param; i++) { + + if(model->param[i]->is_null) { + + /* setup a pointer for quick access */ + param_info = &(DEVices[mod_type]->DEVpublic.param[i]); + + /* determine the size and allocate the parameter element(s) */ + if(! param_info->is_array) { + model->param[i]->size = 1; + model->param[i]->element = (void *) MALLOC(sizeof(Mif_Value_t)); + } + else { /* parameter is an array */ + /* MIF_INP2A() parser assures that there is an associated array connection */ + /* Since several instances may share this model, we have to create an array */ + /* big enough for the instance with the biggest connection array */ + max_size = 0; + for(here = model->MIFinstances; here != NULL; here = here->MIFnextInstance) { + size = here->conn[param_info->conn_ref]->size; + if(size > max_size) + max_size = size; + } + model->param[i]->size = max_size; + model->param[i]->element = (void *) MALLOC(max_size * sizeof(Mif_Value_t)); + } /* end if parameter is an array */ + + /* set the parameter element(s) to default value */ + for(j = 0; j < model->param[i]->size; j++) { + + switch(param_info->type) { + + case MIF_BOOLEAN: + model->param[i]->element[j].bvalue = param_info->default_value.bvalue; + break; + + case MIF_INTEGER: + model->param[i]->element[j].ivalue = param_info->default_value.ivalue; + break; + + case MIF_REAL: + model->param[i]->element[j].rvalue = param_info->default_value.rvalue; + break; + + case MIF_COMPLEX: + model->param[i]->element[j].cvalue = param_info->default_value.cvalue; + break; + + case MIF_STRING: + model->param[i]->element[j].svalue = param_info->default_value.svalue; + break; + + default: + return(E_BADPARM); + } + + } /* end for number of elements in param array */ + + } /* end if null */ + + } /* end for number of parameters */ + + + /* For each instance, initialize stuff used by cm_... functions */ + + for(here = model->MIFinstances; here != NULL; here = here->MIFnextInstance) { + + here->num_state = 0; + here->state = NULL; + + here->num_intgr = 0; + here->intgr = NULL; + + here->num_conv = 0; + here->conv = NULL; + } + + + /* For each instance, allocate runtime structs for output connections/ports */ + /* and grab a place in the state vector for all input connections/ports */ + + for(here = model->MIFinstances; here != NULL; here = here->MIFnextInstance) { + /* Skip these expensive allocations if the instance is not analog */ + if(! here->analog) + continue; + + num_conn = here->num_conn; + for(i = 0; i < num_conn; i++) { + if((here->conn[i]->is_null) || (! here->conn[i]->is_output) ) + continue; + num_port = here->conn[i]->size; + for(j = 0; j < num_port; j++) { + here->conn[i]->port[j]->partial = + (void *) MALLOC(num_conn * sizeof(Mif_Partial_t)); + here->conn[i]->port[j]->ac_gain = + (void *) MALLOC(num_conn * sizeof(Mif_AC_Gain_t)); + here->conn[i]->port[j]->smp_data.input = + (void *) MALLOC(num_conn * sizeof(Mif_Conn_Ptr_t)); + for(k = 0; k < num_conn; k++) { + if((here->conn[k]->is_null) || (! here->conn[k]->is_input) ) + continue; + num_port_k = here->conn[k]->size; + here->conn[i]->port[j]->partial[k].port = + (void *) MALLOC(num_port_k * sizeof(double)); + here->conn[i]->port[j]->ac_gain[k].port = + (void *) MALLOC(num_port_k * sizeof(Mif_Complex_t)); + here->conn[i]->port[j]->smp_data.input[k].port = + (void *) MALLOC(num_port_k * sizeof(Mif_Port_Ptr_t)); + } + } + } + + num_conn = here->num_conn; + for(i = 0; i < num_conn; i++) { + if((here->conn[i]->is_null) || (! here->conn[i]->is_input) ) + continue; + num_port = here->conn[i]->size; + for(j = 0; j < num_port; j++) { + here->conn[i]->port[j]->old_input = *states; + (*states)++; + } + } + } + + + /* Loop through all instances of this model and for each port of each connection */ + /* create current equations, matrix entries, and matrix pointers as necessary. */ + + for(here = model->MIFinstances; here != NULL; here = here->MIFnextInstance) { + /* Skip these expensive allocations if the instance is not analog */ + if(! here->analog) + continue; + + num_conn = here->num_conn; + + /* loop through all connections on this instance */ + /* and create matrix data needed for outputs and */ + /* V sources associated with I inputs */ + for(i = 0; i < num_conn; i++) { + + /* if the connection is null, skip to next connection */ + if(here->conn[i]->is_null) + continue; + + /* prepare things for convenient access later */ + is_input = here->conn[i]->is_input; + is_output = here->conn[i]->is_output; + num_port = here->conn[i]->size; + + /* loop through all ports on this connection */ + for(j = 0; j < num_port; j++) { + + /* if port is null, skip to next */ + if(here->conn[i]->port[j]->is_null) + continue; + + /* determine the type of this port */ + type = here->conn[i]->port[j]->type; + + /* create a pointer to the smp data for quick access */ + smp_data_out = &(here->conn[i]->port[j]->smp_data); + + /* if it has a voltage source output, */ + /* create the matrix data needed */ + if( (is_output && (type == MIF_VOLTAGE || type == MIF_DIFF_VOLTAGE)) || + (type == MIF_RESISTANCE || type == MIF_DIFF_RESISTANCE) ) { + + /* first, make the current equation */ + suffix = (void *) MALLOC(strlen((char *) here->MIFname) + 100); + sprintf(suffix, "branch_%d_%d", i, j); + error = CKTmkCur(ckt, &tmp, here->MIFname, suffix); + FREE(suffix); + if(error) + return(error); + smp_data_out->branch = tmp->number; + + /* ibranch is needed to find the input equation for RESISTANCE type */ + smp_data_out->ibranch = tmp->number; + + /* then make the matrix pointers */ + TSTALLOC(pos_branch, pos_node, branch); + TSTALLOC(neg_branch, neg_node, branch); + TSTALLOC(branch_pos, branch, pos_node); + TSTALLOC(branch_neg, branch, neg_node); + } /* end if current input */ + + /* if it is a current input */ + /* create the matrix data needed for the associated zero-valued V source */ + if(is_input && (type == MIF_CURRENT || type == MIF_DIFF_CURRENT)) { + + /* first, make the current equation */ + suffix = (void *) MALLOC(strlen((char *) here->MIFname) + 100); + sprintf(suffix, "ibranch_%d_%d", i, j); + error = CKTmkCur(ckt, &tmp, here->MIFname, suffix); + FREE(suffix); + if(error) + return(error); + smp_data_out->ibranch = tmp->number; + + /* then make the matrix pointers */ + TSTALLOC(pos_ibranch, pos_node, ibranch); + TSTALLOC(neg_ibranch, neg_node, ibranch); + TSTALLOC(ibranch_pos, ibranch, pos_node); + TSTALLOC(ibranch_neg, ibranch, neg_node); + } /* end if current input */ + + /* if it is a vsource current input (refers to a vsource elsewhere */ + /* in the circuit), locate the source and get its equation number */ + if(is_input && (type == MIF_VSOURCE_CURRENT)) { + smp_data_out->ibranch = CKTfndBranch(ckt, + here->conn[i]->port[j]->vsource_str); + if(smp_data_out->ibranch == (int)NULL) { + IFuid names[2]; + names[0] = here->MIFname; + names[1] = (IFuid) here->conn[i]->port[j]->vsource_str; + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "%s: unknown controlling source %s",names); + return(E_BADPARM); + } + } /* end if vsource current input */ + + } /* end for number of ports */ + } /* end for number of connections */ + + /* now loop through all connections on the instance and create */ + /* matrix data needed for partial derivatives of outputs */ + for(i = 0; i < num_conn; i++) { + + /* if the connection is null or is not an output */ + /* skip to next connection */ + if((here->conn[i]->is_null) || (! here->conn[i]->is_output)) + continue; + + /* loop through all ports on this connection */ + + num_port = here->conn[i]->size; + for(j = 0; j < num_port; j++) { + + /* if port is null, skip to next */ + if(here->conn[i]->port[j]->is_null) + continue; + + /* determine the type of this output port */ + out_type = here->conn[i]->port[j]->type; + + /* create a pointer to the smp data for quick access */ + smp_data_out = &(here->conn[i]->port[j]->smp_data); + + /* for this port, loop through all connections */ + /* and all ports to touch on each possible input */ + for(k = 0; k < num_conn; k++) { + + /* if the connection is null or is not an input */ + /* skip to next connection */ + if((here->conn[k]->is_null) || (! here->conn[k]->is_input)) + continue; + + num_port_k = here->conn[k]->size; + /* loop through all the ports of this connection */ + for(l = 0; l < num_port_k; l++) { + + /* if port is null, skip to next */ + if(here->conn[k]->port[l]->is_null) + continue; + + /* determine the type of this input port */ + in_type = here->conn[k]->port[l]->type; + + /* create a pointer to the smp data for quick access */ + smp_data_cntl = &(here->conn[k]->port[l]->smp_data); + + /* determine type of controlled source according */ + /* to input and output types */ + cntl_src_type = MIFget_cntl_src_type(in_type, out_type); + + switch(cntl_src_type) { + case MIF_VCVS: + CTSTALLOC(e.branch_poscntl, branch, pos_node); + CTSTALLOC(e.branch_negcntl, branch, neg_node); + break; + case MIF_ICIS: + CTSTALLOC(f.pos_ibranchcntl, pos_node, ibranch); + CTSTALLOC(f.neg_ibranchcntl, neg_node, ibranch); + break; + case MIF_VCIS: + CTSTALLOC(g.pos_poscntl, pos_node, pos_node); + CTSTALLOC(g.pos_negcntl, pos_node, neg_node); + CTSTALLOC(g.neg_poscntl, neg_node, pos_node); + CTSTALLOC(g.neg_negcntl, neg_node, neg_node); + break; + case MIF_ICVS: + CTSTALLOC(h.branch_ibranchcntl, branch, ibranch); + break; + } /* end switch on controlled source type */ + } /* end for number of input ports */ + } /* end for number of input connections */ + } /* end for number of output ports */ + } /* end for number of output connections */ + + } /* end for all instances */ + + + } /* end for all models of this type */ + + return(OK); +} diff --git a/src/xspice/mif/miftrunc.c b/src/xspice/mif/miftrunc.c new file mode 100755 index 000000000..0b03fcaf6 --- /dev/null +++ b/src/xspice/mif/miftrunc.c @@ -0,0 +1,224 @@ +/*============================================================================ +FILE MIFtrunc.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains the function called by SPICE to check truncation + error of an integration state used by a code model. + +INTERFACES + + MIFtrunc() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +/* #include "prefix.h" */ +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "sperror.h" + +//#include "util.h" +#include + +#include "mifproto.h" +#include "mifparse.h" +#include "mifdefs.h" +#include "mifcmdat.h" + +/* #include "suffix.h" */ + + + +static void MIFterr(Mif_Intgr_t *intgr, CKTcircuit *ckt, double *timeStep); + + + +/* +MIFtrunc + +This function is called by the CKTtrunc() driver function to +check numerical integration truncation error of any integrals +associated with instances of a particular code model type. It +traverses all models of that type and all instances of each +model. For each instance, it looks in the instance structure to +determine if any variables allocated by cm_analog_alloc() have been used +in a call to cm_analog_integrate(). If so, the truncation error of that +integration is computed and used to set the maximum delta allowed +for the current timestep. +*/ + + +int +MIFtrunc( + GENmodel *inModel, /* The head of the model list */ + CKTcircuit *ckt, /* The circuit structure */ + double *timeStep) /* The timestep delta */ +{ + + MIFmodel *model; + MIFinstance *here; + + int i; + + + /* Setup for access into MIF specific model data */ + model = (MIFmodel *) inModel; + + + /* loop through all models of this type */ + for( ; model != NULL; model = model->MIFnextModel) { + + /* Loop through all instances of this model */ + for(here = model->MIFinstances; here != NULL; here = here->MIFnextInstance) { + + /* Loop through all integration states on the instance */ + for(i = 0; i < here->num_intgr; i++) { + + /* Limit timeStep according to truncation error */ + MIFterr(&(here->intgr[i]), ckt, timeStep); + + } /* end for number of integration states */ + } /* end for all instances */ + } /* end for all models of this type */ + + + return(OK); +} + + + +/* + * Copyright (c) 1985 Thomas L. Quarles + * + * This is a modified version of the function CKTterr(). It limits + * timeStep according to computed truncation error. + * + * Modifications are Copyright 1991 Georgia Tech Research Institute + * + */ + + +static void MIFterr( + Mif_Intgr_t *intgr, + CKTcircuit *ckt, + double *timeStep) +{ + double volttol; + double chargetol; + double tol; + double del; + double diff[8]; + double deltmp[8]; + double factor; + + int i; + int j; + + static double gearCoeff[] = { + .5, + .2222222222, + .1363636364, + .096, + .07299270073, + .05830903790 + }; + static double trapCoeff[] = { + .5, + .08333333333 + }; + + /* Define new local variables. Dimension = number of states in ckt struct */ + char *byte_aligned_state_ptr; + double *state_ptr[8]; + + + /* Set state pointers to the (possibly byte-aligned) states */ + for(i = 0; i < 8; i++) { + byte_aligned_state_ptr = (char *) ckt->CKTstates[i]; + byte_aligned_state_ptr += intgr->byte_index; + state_ptr[i] = (double *) byte_aligned_state_ptr; + } + + /* Modify computation of volttol to not include current from previous timestep */ + /* which is unavailable in this implementation. Note that this makes the */ + /* the overall trunction error timestep smaller (which is better accuracy) */ + + /* Old code */ +/* + volttol = ckt->CKTabstol + ckt->CKTreltol * + MAX( fabs(*(ckt->CKTstate0+ccap)), fabs(*(ckt->CKTstate1+ccap))); +*/ + + /* New code */ + volttol = ckt->CKTabstol + ckt->CKTreltol * fabs(*(state_ptr[0]) - *(state_ptr[1])) + / ckt->CKTdelta; + + /* Modify remaining references to qcap to access byte-aligned MIF state */ + /* Otherwise, remaining code is same as SPICE3C1 ... */ + + chargetol = MAX(fabs(*(state_ptr[0])),fabs(*(state_ptr[1]))); + chargetol = ckt->CKTreltol * MAX(chargetol,ckt->CKTchgtol)/ckt->CKTdelta; + tol = MAX(volttol,chargetol); + /* now divided differences */ + for(i=ckt->CKTorder+1;i>=0;i--) { + diff[i] = *(state_ptr[i]); + } + for(i=0 ; i <= ckt->CKTorder ; i++) { + deltmp[i] = ckt->CKTdeltaOld[i]; + } + j = ckt->CKTorder; + while(1) { + for(i=0;i <= j;i++) { + diff[i] = (diff[i] - diff[i+1])/deltmp[i]; + } + if (--j < 0) break; + for(i=0;i <= j;i++) { + deltmp[i] = deltmp[i+1] + ckt->CKTdeltaOld[i]; + } + } + switch(ckt->CKTintegrateMethod) { + case GEAR: + default: + factor = gearCoeff[ckt->CKTorder-1]; + break; + + case TRAPEZOIDAL: + factor = trapCoeff[ckt->CKTorder - 1] ; + break; + } + del = ckt->CKTtrtol * tol/MAX(ckt->CKTabstol,factor * fabs(diff[0])); + if(ckt->CKTorder == 2) { + del = sqrt(del); + } else if (ckt->CKTorder > 2) { + del = exp(log(del)/ckt->CKTorder); + } + *timeStep = MIN(*timeStep,del); + return; + +} diff --git a/src/xspice/mif/mifutil.c b/src/xspice/mif/mifutil.c new file mode 100755 index 000000000..35ce92f20 --- /dev/null +++ b/src/xspice/mif/mifutil.c @@ -0,0 +1,322 @@ +/*============================================================================ +FILE MIFutil.c + +MEMBER OF process XSPICE + +Copyright 1991 +Georgia Tech Research Corporation +Atlanta, Georgia 30332 +All Rights Reserved + +PROJECT A-8503 + +AUTHORS + + 9/12/91 Bill Kuhn + +MODIFICATIONS + + + +SUMMARY + + This file contains various utility routines used by the MIF package. + +INTERFACES + + MIFgettok() + MIFget_token() + MIFget_cntl_src_type() + MIFcopy() + +REFERENCED FILES + + None. + +NON-STANDARD FEATURES + + None. + +============================================================================*/ + +/* #include "prefix.h" */ +#include "ngspice.h" + +//#include "util.h" +#include "cpstd.h" +#include +#include "miftypes.h" +#include "mifproto.h" + +/* #include "suffix.h" */ + + + + +/* + +MIFgettok + +Get the next token from the input string. The input string pointer +is advanced to the following token and the token from the input +string is copied to malloced storage and a pointer to that storage +is returned. The original input string is undisturbed. + +*/ + +char *MIFgettok(char **s) +{ + + char *buf; /* temporary storage to copy token into */ + char *ret_str; /* storage for returned string */ + + int i; + + /* allocate space big enough for the whole string */ + + buf = (void *) MALLOC(strlen(*s) + 1); + + /* skip over any white space */ + + while(isspace(**s) || (**s == '=') || + (**s == '(') || (**s == ')') || (**s == ',')) + (*s)++; + + /* isolate the next token */ + + switch(**s) { + + case '\0': + FREE(buf); + return(NULL); + + case '<': + case '>': + case '[': + case ']': + case '~': + case '%': + buf[0] = **s; + buf[1] = '\0'; + (*s)++; + break; + + default: + i = 0; + /* if first character is a quote, read until the closing */ + /* quote, or the end of string, discarding the quotes */ + if(**s == '"') { + (*s)++; + while( (**s != '\0') && (**s != '"') ) { + buf[i] = **s; + i++; + (*s)++; + } + if(**s == '"') + (*s)++; + } + /* else, read until the next delimiter */ + else { + while( (**s != '\0') && + (! ( isspace(**s) || (**s == '=') || (**s == '%') || + (**s == '(') || (**s == ')') || (**s == ',') || + (**s == '[') || (**s == ']') || + (**s == '<') || (**s == '>') || (**s == '~') + ) ) ) { + buf[i] = **s; + i++; + (*s)++; + } + } + + buf[i] = '\0'; + break; + } + + /* skip over white space up to next token */ + + while(isspace(**s) || (**s == '=') || + (**s == '(') || (**s == ')') || (**s == ',')) + (*s)++; + + /* make a copy using only the space needed by the string length */ + + ret_str = copy(buf); + FREE(buf); + + return(ret_str); +} + + + + +/* + +MIFget_token + +Get the next token from the input string together with its type. +The input string pointer +is advanced to the following token and the token from the input +string is copied to malloced storage and a pointer to that storage +is returned. The original input string is undisturbed. + +*/ + +char *MIFget_token( + char **s, /* The text line to get the token from */ + Mif_Token_Type_t *type) /* The type of token found */ +{ + + char *ret_str; /* storage for returned string */ + + /* get the token from the input line */ + + ret_str = MIFgettok(s); + + + /* if no next token, return */ + + if(ret_str == NULL) { + *type = MIF_NO_TOK; + return(NULL); + } + + /* else, determine and return token type */ + + switch(*ret_str) { + + case '[': + *type = MIF_LARRAY_TOK; + break; + + case ']': + *type = MIF_RARRAY_TOK; + break; + + case '<': + *type = MIF_LCOMPLEX_TOK; + break; + + case '>': + *type = MIF_RCOMPLEX_TOK; + break; + + case '%': + *type = MIF_PERCENT_TOK; + break; + + case '~': + *type = MIF_TILDE_TOK; + break; + + default: + if(strcmp(ret_str, "null") == 0) + *type = MIF_NULL_TOK; + else + *type = MIF_STRING_TOK; + break; + + } + + return(ret_str); +} + + + +/* +MIFget_cntl_src_type + +This function takes an input connection/port type and an output +connection/port type (MIF_VOLTAGE, MIF_CURRENT, etc.) and maps +this pair to one of the four controlled source types used in +SPICE (VCVS, VCIS, ICVS, ICIS). +*/ + + +Mif_Cntl_Src_Type_t MIFget_cntl_src_type( + Mif_Port_Type_t in_port_type, /* The type of the input port */ + Mif_Port_Type_t out_port_type) /* The type of the output port */ +{ + + switch(in_port_type) { + + case MIF_VOLTAGE: + case MIF_DIFF_VOLTAGE: + case MIF_CONDUCTANCE: + case MIF_DIFF_CONDUCTANCE: + + switch(out_port_type) { + + case MIF_VOLTAGE: + case MIF_DIFF_VOLTAGE: + case MIF_RESISTANCE: + case MIF_DIFF_RESISTANCE: + return(MIF_VCVS); + break; + + case MIF_CURRENT: + case MIF_DIFF_CURRENT: + case MIF_CONDUCTANCE: + case MIF_DIFF_CONDUCTANCE: + return(MIF_VCIS); + break; + + default: + break; + + } + break; + + case MIF_CURRENT: + case MIF_DIFF_CURRENT: + case MIF_VSOURCE_CURRENT: + case MIF_RESISTANCE: + case MIF_DIFF_RESISTANCE: + + switch(out_port_type) { + + case MIF_VOLTAGE: + case MIF_DIFF_VOLTAGE: + case MIF_RESISTANCE: + case MIF_DIFF_RESISTANCE: + return(MIF_ICVS); + break; + + case MIF_CURRENT: + case MIF_DIFF_CURRENT: + case MIF_CONDUCTANCE: + case MIF_DIFF_CONDUCTANCE: + return(MIF_ICIS); + break; + + default: + break; + + } + break; + + default: + break; + + } + + return(-1); +} + + +/* +MIFcopy + +This function allocates a new copy of a string. +*/ + +char *MIFcopy(char *str) +{ + char *temp; + + /* Allocate space for the string and then copy it */ + temp = MALLOC(strlen(str) + 1); + strcpy(temp,str); + + return(temp); +} diff --git a/src/xspice/xspice.c b/src/xspice/xspice.c new file mode 100755 index 000000000..4839e967d --- /dev/null +++ b/src/xspice/xspice.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include + + +/*how annoying!, needed for structure below*/ +void *tcalloc(size_t a, size_t b){ + return tmalloc(a*b); +} +int MIFunsetup(GENmodel *model, CKTcircuit *ckt){ + return 0; +} + +struct coreInfo_t coreInfo = +{ + MIF_INP2A, + MIFgetMod, + MIFgetValue, + MIFsetup, + MIFunsetup, + MIFload, + MIFmParam, + MIFask, + MIFmAsk, + MIFtrunc, + MIFconvTest, + MIFdelete, + MIFmDelete, + MIFdestroy, + MIFgettok, + MIFget_token, + MIFget_cntl_src_type, + MIFcopy, + cm_climit_fcn, + cm_smooth_corner, + cm_smooth_discontinuity, + cm_smooth_pwl, + cm_analog_ramp_factor, + cm_analog_alloc, + cm_analog_get_ptr, + cm_analog_integrate, + cm_analog_converge, + cm_analog_set_temp_bkpt, + cm_analog_set_perm_bkpt, + cm_analog_not_converged, + cm_analog_auto_partial, + cm_event_alloc, + cm_event_get_ptr, + cm_event_queue, + cm_message_get_errmsg, + cm_message_send, + cm_netlist_get_c, + cm_netlist_get_l, + cm_complex_set, + cm_complex_add, + cm_complex_subtract, + cm_complex_multiply, + cm_complex_divide, + NULL, + NULL, + NULL, + tmalloc, + tcalloc, + trealloc, + txfree, + tmalloc, + trealloc, + txfree +}; diff --git a/tests/ChangeLog b/tests/ChangeLog new file mode 100644 index 000000000..96f56f5b0 --- /dev/null +++ b/tests/ChangeLog @@ -0,0 +1,23 @@ +2001-12-07 Paolo Nenzi + + * tests/: added mesa tests from macspice3f4 and corrected all other tests. + +2001-12-04 Emmanuel Rouat + + * check.sh (testdir): turned that script into 'real' sh script + (was bash, really) + +2000-09-14 Arno W. Peters + + * diffpair.out, filters/lowpass.out, polezero/filt_bridge_t.out, + polezero/filt_multistage.out, polezero/filt_rc.out, + resistance/res_array.out, resistance/res_partition.out: Updated + for new spice output. + + +2000-09-09 Arno W. Peters + + * fourbitadder.out, resistance/res_simple.out: Updated to + correspond to the new output from ngspice. + + 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/bsim3soidd/Makefile.am b/tests/bsim3soidd/Makefile.am new file mode 100644 index 000000000..acf97dd4a --- /dev/null +++ b/tests/bsim3soidd/Makefile.am @@ -0,0 +1,16 @@ +## Process this file with automake to produce Makefile.in + +TESTS = \ + t3.cir \ + t4.cir \ + t5.cir \ + inv2.cir \ + RampVg2.cir + +TESTS_ENVIRONMENT = $(SHELL) $(srcdir)/../check.sh $(top_builddir)/src/ngspice + +EXTRA_DIST = \ + $(TESTS) \ + $(TESTS:.cir=.out) + +MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/bsim3soidd/RampVg2.cir b/tests/bsim3soidd/RampVg2.cir new file mode 100644 index 000000000..b9fc6f378 --- /dev/null +++ b/tests/bsim3soidd/RampVg2.cir @@ -0,0 +1,19 @@ +* BSIMSOI (DD) example +* +* SOI, Ramp Vg + +Vd d 0 1.5 +Vg g 0 0.0 PULSE 0V 2V .02n .1n .1n .2n .6n +Ve e 0 0.0 +Vs s 0 0.0 +Vb b 0 0.0 + +m1 d g s e n1 w=10u l=0.25u debug=-1 + +.option gmin=1e-20 itl1=200 itl2=200 abstol=1e-9 +.tran 1p 1.0ns +.print tran @m1[Vbs], V(g)/10 +.include nmosdd.mod + +.end + diff --git a/tests/bsim3soidd/RampVg2.out b/tests/bsim3soidd/RampVg2.out new file mode 100644 index 000000000..1e93ce93b --- /dev/null +++ b/tests/bsim3soidd/RampVg2.out @@ -0,0 +1,1113 @@ + +Circuit: * BSIMSOI (DD) example + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. + +Initial Transient Solution +-------------------------- + +Node Voltage +---- ------- +d 1.5 +g 0 +e 0 +s 0 +b 0 +vb#branch 0 +vs#branch 1.06195e-11 +ve#branch 0 +vg#branch 1.5e-20 +vd#branch -1.06195e-11 + + Reference value : 1.64500e-10 Reference value : 7.41500e-10 +No. of Data Rows : 1029 + * BSIMSOI (DD) example +-------------------------------------------------------------------------------- +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +0 0.000000e+00 9.166197e-02 0.000000e+00 +1 1.000000e-14 9.166197e-02 0.000000e+00 +2 2.000000e-14 9.166197e-02 0.000000e+00 +3 4.000000e-14 9.166197e-02 0.000000e+00 +4 8.000000e-14 9.166197e-02 0.000000e+00 +5 1.600000e-13 9.166197e-02 0.000000e+00 +6 3.200000e-13 9.166197e-02 0.000000e+00 +7 6.400000e-13 9.166197e-02 0.000000e+00 +8 1.280000e-12 9.166197e-02 0.000000e+00 +9 2.280000e-12 9.166197e-02 0.000000e+00 +10 3.280000e-12 9.166197e-02 0.000000e+00 +11 4.280000e-12 9.166197e-02 0.000000e+00 +12 5.280000e-12 9.166197e-02 0.000000e+00 +13 6.280000e-12 9.166197e-02 0.000000e+00 +14 7.280000e-12 9.166197e-02 0.000000e+00 +15 8.280000e-12 9.166197e-02 0.000000e+00 +16 9.280000e-12 9.166197e-02 0.000000e+00 +17 1.028000e-11 9.166197e-02 0.000000e+00 +18 1.128000e-11 9.166197e-02 0.000000e+00 +19 1.228000e-11 9.166197e-02 0.000000e+00 +20 1.328000e-11 9.166197e-02 0.000000e+00 +21 1.428000e-11 9.166197e-02 0.000000e+00 +22 1.528000e-11 9.166197e-02 0.000000e+00 +23 1.628000e-11 9.166197e-02 0.000000e+00 +24 1.728000e-11 9.166197e-02 0.000000e+00 +25 1.828000e-11 9.166197e-02 0.000000e+00 +26 1.928000e-11 9.166197e-02 0.000000e+00 +27 2.000000e-11 9.166197e-02 0.000000e+00 +28 2.010000e-11 9.393837e-02 2.000000e-04 +29 2.030000e-11 9.863117e-02 6.000000e-04 +30 2.070000e-11 1.087280e-01 1.400000e-03 +31 2.150000e-11 1.322177e-01 3.000000e-03 +32 2.250000e-11 1.634796e-01 5.000000e-03 +33 2.350000e-11 1.940307e-01 7.000000e-03 +34 2.450000e-11 2.234013e-01 9.000000e-03 +35 2.550000e-11 2.517648e-01 1.100000e-02 +36 2.650000e-11 2.793418e-01 1.300000e-02 +37 2.750000e-11 3.062522e-01 1.500000e-02 +38 2.850000e-11 3.324855e-01 1.700000e-02 +39 2.950000e-11 3.579054e-01 1.900000e-02 +40 3.050000e-11 3.823391e-01 2.100000e-02 +41 3.150000e-11 4.056560e-01 2.300000e-02 +42 3.250000e-11 4.274094e-01 2.500000e-02 +43 3.350000e-11 4.473552e-01 2.700000e-02 +44 3.450000e-11 4.654300e-01 2.900000e-02 +45 3.550000e-11 4.816628e-01 3.100000e-02 +46 3.650000e-11 4.960864e-01 3.300000e-02 +47 3.750000e-11 5.086947e-01 3.500000e-02 +48 3.850000e-11 5.194648e-01 3.700000e-02 +49 3.950000e-11 5.284127e-01 3.900000e-02 +50 4.050000e-11 5.356307e-01 4.100000e-02 +51 4.150000e-11 5.412833e-01 4.300000e-02 +52 4.250000e-11 5.455761e-01 4.500000e-02 +53 4.350000e-11 5.487215e-01 4.700000e-02 +54 4.450000e-11 5.509170e-01 4.900000e-02 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +55 4.550000e-11 5.523348e-01 5.100000e-02 +56 4.650000e-11 5.531191e-01 5.300000e-02 +57 4.750000e-11 5.533822e-01 5.500000e-02 +58 4.850000e-11 5.532192e-01 5.700000e-02 +59 4.950000e-11 5.527043e-01 5.900000e-02 +60 5.050000e-11 5.518973e-01 6.100000e-02 +61 5.150000e-11 5.508468e-01 6.300000e-02 +62 5.250000e-11 5.495931e-01 6.500000e-02 +63 5.350000e-11 5.481708e-01 6.700000e-02 +64 5.450000e-11 5.466097e-01 6.900000e-02 +65 5.550000e-11 5.449353e-01 7.100000e-02 +66 5.650000e-11 5.431672e-01 7.300000e-02 +67 5.750000e-11 5.413166e-01 7.500000e-02 +68 5.850000e-11 5.393863e-01 7.700000e-02 +69 5.950000e-11 5.373728e-01 7.900000e-02 +70 6.050000e-11 5.352711e-01 8.100000e-02 +71 6.150000e-11 5.330781e-01 8.300000e-02 +72 6.250000e-11 5.307926e-01 8.500000e-02 +73 6.350000e-11 5.284156e-01 8.700000e-02 +74 6.450000e-11 5.259491e-01 8.900000e-02 +75 6.550000e-11 5.233960e-01 9.100000e-02 +76 6.650000e-11 5.207593e-01 9.300000e-02 +77 6.750000e-11 5.180419e-01 9.500000e-02 +78 6.850000e-11 5.152467e-01 9.700000e-02 +79 6.950000e-11 5.123764e-01 9.900000e-02 +80 7.050000e-11 5.094333e-01 1.010000e-01 +81 7.150000e-11 5.064195e-01 1.030000e-01 +82 7.250000e-11 5.033370e-01 1.050000e-01 +83 7.350000e-11 5.001872e-01 1.070000e-01 +84 7.450000e-11 4.969717e-01 1.090000e-01 +85 7.550000e-11 4.936916e-01 1.110000e-01 +86 7.650000e-11 4.903477e-01 1.130000e-01 +87 7.750000e-11 4.869410e-01 1.150000e-01 +88 7.850000e-11 4.834719e-01 1.170000e-01 +89 7.950000e-11 4.799410e-01 1.190000e-01 +90 8.050000e-11 4.763484e-01 1.210000e-01 +91 8.150000e-11 4.726943e-01 1.230000e-01 +92 8.250000e-11 4.689787e-01 1.250000e-01 +93 8.350000e-11 4.652015e-01 1.270000e-01 +94 8.450000e-11 4.613625e-01 1.290000e-01 +95 8.550000e-11 4.574612e-01 1.310000e-01 +96 8.650000e-11 4.534972e-01 1.330000e-01 +97 8.750000e-11 4.494700e-01 1.350000e-01 +98 8.850000e-11 4.453789e-01 1.370000e-01 +99 8.950000e-11 4.412230e-01 1.390000e-01 +100 9.050000e-11 4.370016e-01 1.410000e-01 +101 9.150000e-11 4.327138e-01 1.430000e-01 +102 9.250000e-11 4.283583e-01 1.450000e-01 +103 9.350000e-11 4.239342e-01 1.470000e-01 +104 9.450000e-11 4.194401e-01 1.490000e-01 +105 9.550000e-11 4.148747e-01 1.510000e-01 +106 9.650000e-11 4.102365e-01 1.530000e-01 +107 9.750000e-11 4.055240e-01 1.550000e-01 +108 9.850000e-11 4.007354e-01 1.570000e-01 +109 9.950000e-11 3.958690e-01 1.590000e-01 +110 1.005000e-10 3.909226e-01 1.610000e-01 +111 1.015000e-10 3.858942e-01 1.630000e-01 +112 1.025000e-10 3.807814e-01 1.650000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +113 1.035000e-10 3.755814e-01 1.670000e-01 +114 1.045000e-10 3.702913e-01 1.690000e-01 +115 1.055000e-10 3.649099e-01 1.710000e-01 +116 1.065000e-10 3.594362e-01 1.730000e-01 +117 1.075000e-10 3.538676e-01 1.750000e-01 +118 1.085000e-10 3.482015e-01 1.770000e-01 +119 1.095000e-10 3.424348e-01 1.790000e-01 +120 1.105000e-10 3.365645e-01 1.810000e-01 +121 1.115000e-10 3.305872e-01 1.830000e-01 +122 1.125000e-10 3.244994e-01 1.850000e-01 +123 1.135000e-10 3.182971e-01 1.870000e-01 +124 1.145000e-10 3.119763e-01 1.890000e-01 +125 1.155000e-10 3.055324e-01 1.910000e-01 +126 1.165000e-10 2.989603e-01 1.930000e-01 +127 1.175000e-10 2.922546e-01 1.950000e-01 +128 1.185000e-10 2.854089e-01 1.970000e-01 +129 1.195000e-10 2.784155e-01 1.990000e-01 +130 1.200000e-10 2.748605e-01 2.000000e-01 +131 1.201000e-10 2.748604e-01 2.000000e-01 +132 1.203000e-10 2.748604e-01 2.000000e-01 +133 1.207000e-10 2.748604e-01 2.000000e-01 +134 1.215000e-10 2.748604e-01 2.000000e-01 +135 1.225000e-10 2.748604e-01 2.000000e-01 +136 1.235000e-10 2.748604e-01 2.000000e-01 +137 1.245000e-10 2.748604e-01 2.000000e-01 +138 1.255000e-10 2.748604e-01 2.000000e-01 +139 1.265000e-10 2.748604e-01 2.000000e-01 +140 1.275000e-10 2.748604e-01 2.000000e-01 +141 1.285000e-10 2.748604e-01 2.000000e-01 +142 1.295000e-10 2.748604e-01 2.000000e-01 +143 1.305000e-10 2.748604e-01 2.000000e-01 +144 1.315000e-10 2.748604e-01 2.000000e-01 +145 1.325000e-10 2.748604e-01 2.000000e-01 +146 1.335000e-10 2.748604e-01 2.000000e-01 +147 1.345000e-10 2.748604e-01 2.000000e-01 +148 1.355000e-10 2.748604e-01 2.000000e-01 +149 1.365000e-10 2.748604e-01 2.000000e-01 +150 1.375000e-10 2.748604e-01 2.000000e-01 +151 1.385000e-10 2.748604e-01 2.000000e-01 +152 1.395000e-10 2.748604e-01 2.000000e-01 +153 1.405000e-10 2.748604e-01 2.000000e-01 +154 1.415000e-10 2.748604e-01 2.000000e-01 +155 1.425000e-10 2.748604e-01 2.000000e-01 +156 1.435000e-10 2.748604e-01 2.000000e-01 +157 1.445000e-10 2.748604e-01 2.000000e-01 +158 1.455000e-10 2.748604e-01 2.000000e-01 +159 1.465000e-10 2.748604e-01 2.000000e-01 +160 1.475000e-10 2.748604e-01 2.000000e-01 +161 1.485000e-10 2.748604e-01 2.000000e-01 +162 1.495000e-10 2.748604e-01 2.000000e-01 +163 1.505000e-10 2.748604e-01 2.000000e-01 +164 1.515000e-10 2.748604e-01 2.000000e-01 +165 1.525000e-10 2.748604e-01 2.000000e-01 +166 1.535000e-10 2.748604e-01 2.000000e-01 +167 1.545000e-10 2.748604e-01 2.000000e-01 +168 1.555000e-10 2.748604e-01 2.000000e-01 +169 1.565000e-10 2.748604e-01 2.000000e-01 +170 1.575000e-10 2.748604e-01 2.000000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +171 1.585000e-10 2.748604e-01 2.000000e-01 +172 1.595000e-10 2.748604e-01 2.000000e-01 +173 1.605000e-10 2.748604e-01 2.000000e-01 +174 1.615000e-10 2.748604e-01 2.000000e-01 +175 1.625000e-10 2.748604e-01 2.000000e-01 +176 1.635000e-10 2.748604e-01 2.000000e-01 +177 1.645000e-10 2.748604e-01 2.000000e-01 +178 1.655000e-10 2.748604e-01 2.000000e-01 +179 1.665000e-10 2.748604e-01 2.000000e-01 +180 1.675000e-10 2.748604e-01 2.000000e-01 +181 1.685000e-10 2.748604e-01 2.000000e-01 +182 1.695000e-10 2.748604e-01 2.000000e-01 +183 1.705000e-10 2.748604e-01 2.000000e-01 +184 1.715000e-10 2.748604e-01 2.000000e-01 +185 1.725000e-10 2.748604e-01 2.000000e-01 +186 1.735000e-10 2.748604e-01 2.000000e-01 +187 1.745000e-10 2.748604e-01 2.000000e-01 +188 1.755000e-10 2.748604e-01 2.000000e-01 +189 1.765000e-10 2.748604e-01 2.000000e-01 +190 1.775000e-10 2.748604e-01 2.000000e-01 +191 1.785000e-10 2.748604e-01 2.000000e-01 +192 1.795000e-10 2.748604e-01 2.000000e-01 +193 1.805000e-10 2.748604e-01 2.000000e-01 +194 1.815000e-10 2.748604e-01 2.000000e-01 +195 1.825000e-10 2.748604e-01 2.000000e-01 +196 1.835000e-10 2.748604e-01 2.000000e-01 +197 1.845000e-10 2.748604e-01 2.000000e-01 +198 1.855000e-10 2.748604e-01 2.000000e-01 +199 1.865000e-10 2.748604e-01 2.000000e-01 +200 1.875000e-10 2.748604e-01 2.000000e-01 +201 1.885000e-10 2.748604e-01 2.000000e-01 +202 1.895000e-10 2.748604e-01 2.000000e-01 +203 1.905000e-10 2.748604e-01 2.000000e-01 +204 1.915000e-10 2.748604e-01 2.000000e-01 +205 1.925000e-10 2.748604e-01 2.000000e-01 +206 1.935000e-10 2.748604e-01 2.000000e-01 +207 1.945000e-10 2.748604e-01 2.000000e-01 +208 1.955000e-10 2.748604e-01 2.000000e-01 +209 1.965000e-10 2.748604e-01 2.000000e-01 +210 1.975000e-10 2.748604e-01 2.000000e-01 +211 1.985000e-10 2.748604e-01 2.000000e-01 +212 1.995000e-10 2.748604e-01 2.000000e-01 +213 2.005000e-10 2.748604e-01 2.000000e-01 +214 2.015000e-10 2.748604e-01 2.000000e-01 +215 2.025000e-10 2.748604e-01 2.000000e-01 +216 2.035000e-10 2.748604e-01 2.000000e-01 +217 2.045000e-10 2.748604e-01 2.000000e-01 +218 2.055000e-10 2.748604e-01 2.000000e-01 +219 2.065000e-10 2.748604e-01 2.000000e-01 +220 2.075000e-10 2.748604e-01 2.000000e-01 +221 2.085000e-10 2.748604e-01 2.000000e-01 +222 2.095000e-10 2.748604e-01 2.000000e-01 +223 2.105000e-10 2.748604e-01 2.000000e-01 +224 2.115000e-10 2.748604e-01 2.000000e-01 +225 2.125000e-10 2.748604e-01 2.000000e-01 +226 2.135000e-10 2.748604e-01 2.000000e-01 +227 2.145000e-10 2.748604e-01 2.000000e-01 +228 2.155000e-10 2.748604e-01 2.000000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +229 2.165000e-10 2.748604e-01 2.000000e-01 +230 2.175000e-10 2.748604e-01 2.000000e-01 +231 2.185000e-10 2.748604e-01 2.000000e-01 +232 2.195000e-10 2.748604e-01 2.000000e-01 +233 2.205000e-10 2.748604e-01 2.000000e-01 +234 2.215000e-10 2.748604e-01 2.000000e-01 +235 2.225000e-10 2.748604e-01 2.000000e-01 +236 2.235000e-10 2.748604e-01 2.000000e-01 +237 2.245000e-10 2.748604e-01 2.000000e-01 +238 2.255000e-10 2.748604e-01 2.000000e-01 +239 2.265000e-10 2.748604e-01 2.000000e-01 +240 2.275000e-10 2.748604e-01 2.000000e-01 +241 2.285000e-10 2.748604e-01 2.000000e-01 +242 2.295000e-10 2.748604e-01 2.000000e-01 +243 2.305000e-10 2.748604e-01 2.000000e-01 +244 2.315000e-10 2.748604e-01 2.000000e-01 +245 2.325000e-10 2.748604e-01 2.000000e-01 +246 2.335000e-10 2.748604e-01 2.000000e-01 +247 2.345000e-10 2.748604e-01 2.000000e-01 +248 2.355000e-10 2.748604e-01 2.000000e-01 +249 2.365000e-10 2.748604e-01 2.000000e-01 +250 2.375000e-10 2.748604e-01 2.000000e-01 +251 2.385000e-10 2.748604e-01 2.000000e-01 +252 2.395000e-10 2.748604e-01 2.000000e-01 +253 2.405000e-10 2.748604e-01 2.000000e-01 +254 2.415000e-10 2.748604e-01 2.000000e-01 +255 2.425000e-10 2.748604e-01 2.000000e-01 +256 2.435000e-10 2.748604e-01 2.000000e-01 +257 2.445000e-10 2.748604e-01 2.000000e-01 +258 2.455000e-10 2.748604e-01 2.000000e-01 +259 2.465000e-10 2.748604e-01 2.000000e-01 +260 2.475000e-10 2.748604e-01 2.000000e-01 +261 2.485000e-10 2.748604e-01 2.000000e-01 +262 2.495000e-10 2.748604e-01 2.000000e-01 +263 2.505000e-10 2.748604e-01 2.000000e-01 +264 2.515000e-10 2.748604e-01 2.000000e-01 +265 2.525000e-10 2.748604e-01 2.000000e-01 +266 2.535000e-10 2.748604e-01 2.000000e-01 +267 2.545000e-10 2.748604e-01 2.000000e-01 +268 2.555000e-10 2.748604e-01 2.000000e-01 +269 2.565000e-10 2.748604e-01 2.000000e-01 +270 2.575000e-10 2.748604e-01 2.000000e-01 +271 2.585000e-10 2.748604e-01 2.000000e-01 +272 2.595000e-10 2.748604e-01 2.000000e-01 +273 2.605000e-10 2.748604e-01 2.000000e-01 +274 2.615000e-10 2.748604e-01 2.000000e-01 +275 2.625000e-10 2.748604e-01 2.000000e-01 +276 2.635000e-10 2.748604e-01 2.000000e-01 +277 2.645000e-10 2.748604e-01 2.000000e-01 +278 2.655000e-10 2.748604e-01 2.000000e-01 +279 2.665000e-10 2.748604e-01 2.000000e-01 +280 2.675000e-10 2.748604e-01 2.000000e-01 +281 2.685000e-10 2.748604e-01 2.000000e-01 +282 2.695000e-10 2.748604e-01 2.000000e-01 +283 2.705000e-10 2.748604e-01 2.000000e-01 +284 2.715000e-10 2.748604e-01 2.000000e-01 +285 2.725000e-10 2.748604e-01 2.000000e-01 +286 2.735000e-10 2.748604e-01 2.000000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +287 2.745000e-10 2.748604e-01 2.000000e-01 +288 2.755000e-10 2.748604e-01 2.000000e-01 +289 2.765000e-10 2.748604e-01 2.000000e-01 +290 2.775000e-10 2.748604e-01 2.000000e-01 +291 2.785000e-10 2.748604e-01 2.000000e-01 +292 2.795000e-10 2.748604e-01 2.000000e-01 +293 2.805000e-10 2.748604e-01 2.000000e-01 +294 2.815000e-10 2.748604e-01 2.000000e-01 +295 2.825000e-10 2.748604e-01 2.000000e-01 +296 2.835000e-10 2.748604e-01 2.000000e-01 +297 2.845000e-10 2.748604e-01 2.000000e-01 +298 2.855000e-10 2.748604e-01 2.000000e-01 +299 2.865000e-10 2.748604e-01 2.000000e-01 +300 2.875000e-10 2.748604e-01 2.000000e-01 +301 2.885000e-10 2.748604e-01 2.000000e-01 +302 2.895000e-10 2.748604e-01 2.000000e-01 +303 2.905000e-10 2.748604e-01 2.000000e-01 +304 2.915000e-10 2.748604e-01 2.000000e-01 +305 2.925000e-10 2.748604e-01 2.000000e-01 +306 2.935000e-10 2.748604e-01 2.000000e-01 +307 2.945000e-10 2.748604e-01 2.000000e-01 +308 2.955000e-10 2.748604e-01 2.000000e-01 +309 2.965000e-10 2.748604e-01 2.000000e-01 +310 2.975000e-10 2.748604e-01 2.000000e-01 +311 2.985000e-10 2.748604e-01 2.000000e-01 +312 2.995000e-10 2.748604e-01 2.000000e-01 +313 3.005000e-10 2.748604e-01 2.000000e-01 +314 3.015000e-10 2.748604e-01 2.000000e-01 +315 3.025000e-10 2.748604e-01 2.000000e-01 +316 3.035000e-10 2.748604e-01 2.000000e-01 +317 3.045000e-10 2.748604e-01 2.000000e-01 +318 3.055000e-10 2.748604e-01 2.000000e-01 +319 3.065000e-10 2.748604e-01 2.000000e-01 +320 3.075000e-10 2.748604e-01 2.000000e-01 +321 3.085000e-10 2.748604e-01 2.000000e-01 +322 3.095000e-10 2.748604e-01 2.000000e-01 +323 3.105000e-10 2.748604e-01 2.000000e-01 +324 3.115000e-10 2.748604e-01 2.000000e-01 +325 3.125000e-10 2.748604e-01 2.000000e-01 +326 3.135000e-10 2.748604e-01 2.000000e-01 +327 3.145000e-10 2.748604e-01 2.000000e-01 +328 3.155000e-10 2.748604e-01 2.000000e-01 +329 3.165000e-10 2.748604e-01 2.000000e-01 +330 3.175000e-10 2.748604e-01 2.000000e-01 +331 3.185000e-10 2.748604e-01 2.000000e-01 +332 3.195000e-10 2.748604e-01 2.000000e-01 +333 3.200000e-10 2.748604e-01 2.000000e-01 +334 3.201000e-10 2.755747e-01 1.998000e-01 +335 3.203000e-10 2.769983e-01 1.994000e-01 +336 3.207000e-10 2.798265e-01 1.986000e-01 +337 3.215000e-10 2.854089e-01 1.970000e-01 +338 3.225000e-10 2.922546e-01 1.950000e-01 +339 3.235000e-10 2.989603e-01 1.930000e-01 +340 3.245000e-10 3.055324e-01 1.910000e-01 +341 3.255000e-10 3.119763e-01 1.890000e-01 +342 3.265000e-10 3.182971e-01 1.870000e-01 +343 3.275000e-10 3.244994e-01 1.850000e-01 +344 3.285000e-10 3.305872e-01 1.830000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +345 3.295000e-10 3.365645e-01 1.810000e-01 +346 3.305000e-10 3.424348e-01 1.790000e-01 +347 3.315000e-10 3.482015e-01 1.770000e-01 +348 3.325000e-10 3.538677e-01 1.750000e-01 +349 3.335000e-10 3.594362e-01 1.730000e-01 +350 3.345000e-10 3.649099e-01 1.710000e-01 +351 3.355000e-10 3.702913e-01 1.690000e-01 +352 3.365000e-10 3.755814e-01 1.670000e-01 +353 3.375000e-10 3.807814e-01 1.650000e-01 +354 3.385000e-10 3.858942e-01 1.630000e-01 +355 3.395000e-10 3.909226e-01 1.610000e-01 +356 3.405000e-10 3.958690e-01 1.590000e-01 +357 3.415000e-10 4.007354e-01 1.570000e-01 +358 3.425000e-10 4.055240e-01 1.550000e-01 +359 3.435000e-10 4.102365e-01 1.530000e-01 +360 3.445000e-10 4.148747e-01 1.510000e-01 +361 3.455000e-10 4.194401e-01 1.490000e-01 +362 3.465000e-10 4.239342e-01 1.470000e-01 +363 3.475000e-10 4.283583e-01 1.450000e-01 +364 3.485000e-10 4.327138e-01 1.430000e-01 +365 3.495000e-10 4.370016e-01 1.410000e-01 +366 3.505000e-10 4.412230e-01 1.390000e-01 +367 3.515000e-10 4.453789e-01 1.370000e-01 +368 3.525000e-10 4.494700e-01 1.350000e-01 +369 3.535000e-10 4.534972e-01 1.330000e-01 +370 3.545000e-10 4.574612e-01 1.310000e-01 +371 3.555000e-10 4.613625e-01 1.290000e-01 +372 3.565000e-10 4.652015e-01 1.270000e-01 +373 3.575000e-10 4.689787e-01 1.250000e-01 +374 3.585000e-10 4.726943e-01 1.230000e-01 +375 3.595000e-10 4.763484e-01 1.210000e-01 +376 3.605000e-10 4.799410e-01 1.190000e-01 +377 3.615000e-10 4.834719e-01 1.170000e-01 +378 3.625000e-10 4.869410e-01 1.150000e-01 +379 3.635000e-10 4.903477e-01 1.130000e-01 +380 3.645000e-10 4.936916e-01 1.110000e-01 +381 3.655000e-10 4.969717e-01 1.090000e-01 +382 3.665000e-10 5.001872e-01 1.070000e-01 +383 3.675000e-10 5.033370e-01 1.050000e-01 +384 3.685000e-10 5.064195e-01 1.030000e-01 +385 3.695000e-10 5.094333e-01 1.010000e-01 +386 3.705000e-10 5.123764e-01 9.900000e-02 +387 3.715000e-10 5.152467e-01 9.700000e-02 +388 3.725000e-10 5.180419e-01 9.500000e-02 +389 3.735000e-10 5.207593e-01 9.300000e-02 +390 3.745000e-10 5.233960e-01 9.100000e-02 +391 3.755000e-10 5.259491e-01 8.900000e-02 +392 3.765000e-10 5.284156e-01 8.700000e-02 +393 3.775000e-10 5.307926e-01 8.500000e-02 +394 3.785000e-10 5.330781e-01 8.300000e-02 +395 3.795000e-10 5.352711e-01 8.100000e-02 +396 3.805000e-10 5.373728e-01 7.900000e-02 +397 3.815000e-10 5.393863e-01 7.700000e-02 +398 3.825000e-10 5.413166e-01 7.500000e-02 +399 3.835000e-10 5.431672e-01 7.300000e-02 +400 3.845000e-10 5.449353e-01 7.100000e-02 +401 3.855000e-10 5.466097e-01 6.900000e-02 +402 3.865000e-10 5.481708e-01 6.700000e-02 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +403 3.875000e-10 5.495931e-01 6.500000e-02 +404 3.885000e-10 5.508467e-01 6.300000e-02 +405 3.895000e-10 5.518972e-01 6.100000e-02 +406 3.905000e-10 5.527042e-01 5.900000e-02 +407 3.915000e-10 5.532190e-01 5.700000e-02 +408 3.925000e-10 5.533818e-01 5.500000e-02 +409 3.935000e-10 5.531185e-01 5.300000e-02 +410 3.945000e-10 5.523362e-01 5.100000e-02 +411 3.955000e-10 5.509170e-01 4.900000e-02 +412 3.965000e-10 5.487215e-01 4.700000e-02 +413 3.975000e-10 5.455761e-01 4.500000e-02 +414 3.985000e-10 5.412833e-01 4.300000e-02 +415 3.995000e-10 5.356307e-01 4.100000e-02 +416 4.005000e-10 5.284127e-01 3.900000e-02 +417 4.015000e-10 5.194648e-01 3.700000e-02 +418 4.025000e-10 5.086947e-01 3.500000e-02 +419 4.035000e-10 4.960864e-01 3.300000e-02 +420 4.045000e-10 4.816628e-01 3.100000e-02 +421 4.055000e-10 4.654300e-01 2.900000e-02 +422 4.065000e-10 4.473552e-01 2.700000e-02 +423 4.075000e-10 4.274094e-01 2.500000e-02 +424 4.085000e-10 4.056560e-01 2.300000e-02 +425 4.095000e-10 3.823391e-01 2.100000e-02 +426 4.105000e-10 3.579054e-01 1.900000e-02 +427 4.115000e-10 3.324855e-01 1.700000e-02 +428 4.125000e-10 3.062522e-01 1.500000e-02 +429 4.135000e-10 2.793418e-01 1.300000e-02 +430 4.145000e-10 2.517648e-01 1.100000e-02 +431 4.155000e-10 2.234013e-01 9.000000e-03 +432 4.165000e-10 1.940307e-01 7.000000e-03 +433 4.175000e-10 1.634796e-01 5.000000e-03 +434 4.185000e-10 1.322176e-01 3.000000e-03 +435 4.195000e-10 1.035401e-01 1.000000e-03 +436 4.200000e-10 9.166197e-02 3.230922e-17 +437 4.201000e-10 9.166197e-02 0.000000e+00 +438 4.203000e-10 9.166197e-02 0.000000e+00 +439 4.207000e-10 9.166197e-02 0.000000e+00 +440 4.215000e-10 9.166197e-02 0.000000e+00 +441 4.225000e-10 9.166197e-02 0.000000e+00 +442 4.235000e-10 9.166197e-02 0.000000e+00 +443 4.245000e-10 9.166197e-02 0.000000e+00 +444 4.255000e-10 9.166197e-02 0.000000e+00 +445 4.265000e-10 9.166197e-02 0.000000e+00 +446 4.275000e-10 9.166197e-02 0.000000e+00 +447 4.285000e-10 9.166197e-02 0.000000e+00 +448 4.295000e-10 9.166197e-02 0.000000e+00 +449 4.305000e-10 9.166197e-02 0.000000e+00 +450 4.315000e-10 9.166197e-02 0.000000e+00 +451 4.325000e-10 9.166197e-02 0.000000e+00 +452 4.335000e-10 9.166197e-02 0.000000e+00 +453 4.345000e-10 9.166197e-02 0.000000e+00 +454 4.355000e-10 9.166197e-02 0.000000e+00 +455 4.365000e-10 9.166197e-02 0.000000e+00 +456 4.375000e-10 9.166197e-02 0.000000e+00 +457 4.385000e-10 9.166197e-02 0.000000e+00 +458 4.395000e-10 9.166197e-02 0.000000e+00 +459 4.405000e-10 9.166197e-02 0.000000e+00 +460 4.415000e-10 9.166197e-02 0.000000e+00 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +461 4.425000e-10 9.166197e-02 0.000000e+00 +462 4.435000e-10 9.166197e-02 0.000000e+00 +463 4.445000e-10 9.166197e-02 0.000000e+00 +464 4.455000e-10 9.166197e-02 0.000000e+00 +465 4.465000e-10 9.166197e-02 0.000000e+00 +466 4.475000e-10 9.166197e-02 0.000000e+00 +467 4.485000e-10 9.166197e-02 0.000000e+00 +468 4.495000e-10 9.166197e-02 0.000000e+00 +469 4.505000e-10 9.166197e-02 0.000000e+00 +470 4.515000e-10 9.166197e-02 0.000000e+00 +471 4.525000e-10 9.166197e-02 0.000000e+00 +472 4.535000e-10 9.166197e-02 0.000000e+00 +473 4.545000e-10 9.166197e-02 0.000000e+00 +474 4.555000e-10 9.166197e-02 0.000000e+00 +475 4.565000e-10 9.166197e-02 0.000000e+00 +476 4.575000e-10 9.166197e-02 0.000000e+00 +477 4.585000e-10 9.166197e-02 0.000000e+00 +478 4.595000e-10 9.166197e-02 0.000000e+00 +479 4.605000e-10 9.166197e-02 0.000000e+00 +480 4.615000e-10 9.166197e-02 0.000000e+00 +481 4.625000e-10 9.166197e-02 0.000000e+00 +482 4.635000e-10 9.166197e-02 0.000000e+00 +483 4.645000e-10 9.166197e-02 0.000000e+00 +484 4.655000e-10 9.166197e-02 0.000000e+00 +485 4.665000e-10 9.166197e-02 0.000000e+00 +486 4.675000e-10 9.166197e-02 0.000000e+00 +487 4.685000e-10 9.166197e-02 0.000000e+00 +488 4.695000e-10 9.166197e-02 0.000000e+00 +489 4.705000e-10 9.166197e-02 0.000000e+00 +490 4.715000e-10 9.166197e-02 0.000000e+00 +491 4.725000e-10 9.166197e-02 0.000000e+00 +492 4.735000e-10 9.166197e-02 0.000000e+00 +493 4.745000e-10 9.166197e-02 0.000000e+00 +494 4.755000e-10 9.166197e-02 0.000000e+00 +495 4.765000e-10 9.166197e-02 0.000000e+00 +496 4.775000e-10 9.166197e-02 0.000000e+00 +497 4.785000e-10 9.166197e-02 0.000000e+00 +498 4.795000e-10 9.166197e-02 0.000000e+00 +499 4.805000e-10 9.166197e-02 0.000000e+00 +500 4.815000e-10 9.166197e-02 0.000000e+00 +501 4.825000e-10 9.166197e-02 0.000000e+00 +502 4.835000e-10 9.166197e-02 0.000000e+00 +503 4.845000e-10 9.166197e-02 0.000000e+00 +504 4.855000e-10 9.166197e-02 0.000000e+00 +505 4.865000e-10 9.166197e-02 0.000000e+00 +506 4.875000e-10 9.166197e-02 0.000000e+00 +507 4.885000e-10 9.166197e-02 0.000000e+00 +508 4.895000e-10 9.166197e-02 0.000000e+00 +509 4.905000e-10 9.166197e-02 0.000000e+00 +510 4.915000e-10 9.166197e-02 0.000000e+00 +511 4.925000e-10 9.166197e-02 0.000000e+00 +512 4.935000e-10 9.166197e-02 0.000000e+00 +513 4.945000e-10 9.166197e-02 0.000000e+00 +514 4.955000e-10 9.166197e-02 0.000000e+00 +515 4.965000e-10 9.166197e-02 0.000000e+00 +516 4.975000e-10 9.166197e-02 0.000000e+00 +517 4.985000e-10 9.166197e-02 0.000000e+00 +518 4.995000e-10 9.166197e-02 0.000000e+00 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +519 5.005000e-10 9.166197e-02 0.000000e+00 +520 5.015000e-10 9.166197e-02 0.000000e+00 +521 5.025000e-10 9.166197e-02 0.000000e+00 +522 5.035000e-10 9.166197e-02 0.000000e+00 +523 5.045000e-10 9.166197e-02 0.000000e+00 +524 5.055000e-10 9.166197e-02 0.000000e+00 +525 5.065000e-10 9.166197e-02 0.000000e+00 +526 5.075000e-10 9.166197e-02 0.000000e+00 +527 5.085000e-10 9.166197e-02 0.000000e+00 +528 5.095000e-10 9.166197e-02 0.000000e+00 +529 5.105000e-10 9.166197e-02 0.000000e+00 +530 5.115000e-10 9.166197e-02 0.000000e+00 +531 5.125000e-10 9.166197e-02 0.000000e+00 +532 5.135000e-10 9.166197e-02 0.000000e+00 +533 5.145000e-10 9.166197e-02 0.000000e+00 +534 5.155000e-10 9.166197e-02 0.000000e+00 +535 5.165000e-10 9.166197e-02 0.000000e+00 +536 5.175000e-10 9.166197e-02 0.000000e+00 +537 5.185000e-10 9.166197e-02 0.000000e+00 +538 5.195000e-10 9.166197e-02 0.000000e+00 +539 5.205000e-10 9.166197e-02 0.000000e+00 +540 5.215000e-10 9.166197e-02 0.000000e+00 +541 5.225000e-10 9.166197e-02 0.000000e+00 +542 5.235000e-10 9.166197e-02 0.000000e+00 +543 5.245000e-10 9.166197e-02 0.000000e+00 +544 5.255000e-10 9.166197e-02 0.000000e+00 +545 5.265000e-10 9.166197e-02 0.000000e+00 +546 5.275000e-10 9.166197e-02 0.000000e+00 +547 5.285000e-10 9.166197e-02 0.000000e+00 +548 5.295000e-10 9.166197e-02 0.000000e+00 +549 5.305000e-10 9.166197e-02 0.000000e+00 +550 5.315000e-10 9.166197e-02 0.000000e+00 +551 5.325000e-10 9.166197e-02 0.000000e+00 +552 5.335000e-10 9.166197e-02 0.000000e+00 +553 5.345000e-10 9.166197e-02 0.000000e+00 +554 5.355000e-10 9.166197e-02 0.000000e+00 +555 5.365000e-10 9.166197e-02 0.000000e+00 +556 5.375000e-10 9.166197e-02 0.000000e+00 +557 5.385000e-10 9.166197e-02 0.000000e+00 +558 5.395000e-10 9.166197e-02 0.000000e+00 +559 5.405000e-10 9.166197e-02 0.000000e+00 +560 5.415000e-10 9.166197e-02 0.000000e+00 +561 5.425000e-10 9.166197e-02 0.000000e+00 +562 5.435000e-10 9.166197e-02 0.000000e+00 +563 5.445000e-10 9.166197e-02 0.000000e+00 +564 5.455000e-10 9.166197e-02 0.000000e+00 +565 5.465000e-10 9.166197e-02 0.000000e+00 +566 5.475000e-10 9.166197e-02 0.000000e+00 +567 5.485000e-10 9.166197e-02 0.000000e+00 +568 5.495000e-10 9.166197e-02 0.000000e+00 +569 5.505000e-10 9.166197e-02 0.000000e+00 +570 5.515000e-10 9.166197e-02 0.000000e+00 +571 5.525000e-10 9.166197e-02 0.000000e+00 +572 5.535000e-10 9.166197e-02 0.000000e+00 +573 5.545000e-10 9.166197e-02 0.000000e+00 +574 5.555000e-10 9.166197e-02 0.000000e+00 +575 5.565000e-10 9.166197e-02 0.000000e+00 +576 5.575000e-10 9.166197e-02 0.000000e+00 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +577 5.585000e-10 9.166197e-02 0.000000e+00 +578 5.595000e-10 9.166197e-02 0.000000e+00 +579 5.605000e-10 9.166197e-02 0.000000e+00 +580 5.615000e-10 9.166197e-02 0.000000e+00 +581 5.625000e-10 9.166197e-02 0.000000e+00 +582 5.635000e-10 9.166197e-02 0.000000e+00 +583 5.645000e-10 9.166197e-02 0.000000e+00 +584 5.655000e-10 9.166197e-02 0.000000e+00 +585 5.665000e-10 9.166197e-02 0.000000e+00 +586 5.675000e-10 9.166197e-02 0.000000e+00 +587 5.685000e-10 9.166197e-02 0.000000e+00 +588 5.695000e-10 9.166197e-02 0.000000e+00 +589 5.705000e-10 9.166197e-02 0.000000e+00 +590 5.715000e-10 9.166197e-02 0.000000e+00 +591 5.725000e-10 9.166197e-02 0.000000e+00 +592 5.735000e-10 9.166197e-02 0.000000e+00 +593 5.745000e-10 9.166197e-02 0.000000e+00 +594 5.755000e-10 9.166197e-02 0.000000e+00 +595 5.765000e-10 9.166197e-02 0.000000e+00 +596 5.775000e-10 9.166197e-02 0.000000e+00 +597 5.785000e-10 9.166197e-02 0.000000e+00 +598 5.795000e-10 9.166197e-02 0.000000e+00 +599 5.805000e-10 9.166197e-02 0.000000e+00 +600 5.815000e-10 9.166197e-02 0.000000e+00 +601 5.825000e-10 9.166197e-02 0.000000e+00 +602 5.835000e-10 9.166197e-02 0.000000e+00 +603 5.845000e-10 9.166197e-02 0.000000e+00 +604 5.855000e-10 9.166197e-02 0.000000e+00 +605 5.865000e-10 9.166197e-02 0.000000e+00 +606 5.875000e-10 9.166197e-02 0.000000e+00 +607 5.885000e-10 9.166197e-02 0.000000e+00 +608 5.895000e-10 9.166197e-02 0.000000e+00 +609 5.905000e-10 9.166197e-02 0.000000e+00 +610 5.915000e-10 9.166197e-02 0.000000e+00 +611 5.925000e-10 9.166197e-02 0.000000e+00 +612 5.935000e-10 9.166197e-02 0.000000e+00 +613 5.945000e-10 9.166197e-02 0.000000e+00 +614 5.955000e-10 9.166197e-02 0.000000e+00 +615 5.965000e-10 9.166197e-02 0.000000e+00 +616 5.975000e-10 9.166197e-02 0.000000e+00 +617 5.985000e-10 9.166197e-02 0.000000e+00 +618 5.995000e-10 9.166197e-02 0.000000e+00 +619 6.005000e-10 9.166197e-02 0.000000e+00 +620 6.015000e-10 9.166197e-02 0.000000e+00 +621 6.025000e-10 9.166197e-02 0.000000e+00 +622 6.035000e-10 9.166197e-02 0.000000e+00 +623 6.045000e-10 9.166197e-02 0.000000e+00 +624 6.055000e-10 9.166197e-02 0.000000e+00 +625 6.065000e-10 9.166197e-02 0.000000e+00 +626 6.075000e-10 9.166197e-02 0.000000e+00 +627 6.085000e-10 9.166197e-02 0.000000e+00 +628 6.095000e-10 9.166197e-02 0.000000e+00 +629 6.105000e-10 9.166197e-02 0.000000e+00 +630 6.115000e-10 9.166197e-02 0.000000e+00 +631 6.125000e-10 9.166197e-02 0.000000e+00 +632 6.135000e-10 9.166197e-02 0.000000e+00 +633 6.145000e-10 9.166197e-02 0.000000e+00 +634 6.155000e-10 9.166197e-02 0.000000e+00 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +635 6.165000e-10 9.166197e-02 0.000000e+00 +636 6.175000e-10 9.166197e-02 0.000000e+00 +637 6.185000e-10 9.166197e-02 0.000000e+00 +638 6.195000e-10 9.166197e-02 0.000000e+00 +639 6.200000e-10 9.166197e-02 7.108583e-17 +640 6.201000e-10 9.393837e-02 2.000000e-04 +641 6.203000e-10 9.863117e-02 6.000000e-04 +642 6.207000e-10 1.087280e-01 1.400000e-03 +643 6.215000e-10 1.322177e-01 3.000000e-03 +644 6.225000e-10 1.634796e-01 5.000000e-03 +645 6.235000e-10 1.940307e-01 7.000000e-03 +646 6.245000e-10 2.234013e-01 9.000000e-03 +647 6.255000e-10 2.517648e-01 1.100000e-02 +648 6.265000e-10 2.793418e-01 1.300000e-02 +649 6.275000e-10 3.062522e-01 1.500000e-02 +650 6.285000e-10 3.324855e-01 1.700000e-02 +651 6.295000e-10 3.579054e-01 1.900000e-02 +652 6.305000e-10 3.823391e-01 2.100000e-02 +653 6.315000e-10 4.056560e-01 2.300000e-02 +654 6.325000e-10 4.274094e-01 2.500000e-02 +655 6.335000e-10 4.473552e-01 2.700000e-02 +656 6.345000e-10 4.654300e-01 2.900000e-02 +657 6.355000e-10 4.816628e-01 3.100000e-02 +658 6.365000e-10 4.960864e-01 3.300000e-02 +659 6.375000e-10 5.086947e-01 3.500000e-02 +660 6.385000e-10 5.194648e-01 3.700000e-02 +661 6.395000e-10 5.284127e-01 3.900000e-02 +662 6.405000e-10 5.356307e-01 4.100000e-02 +663 6.415000e-10 5.412833e-01 4.300000e-02 +664 6.425000e-10 5.455761e-01 4.500000e-02 +665 6.435000e-10 5.487215e-01 4.700000e-02 +666 6.445000e-10 5.509170e-01 4.900000e-02 +667 6.455000e-10 5.523348e-01 5.100000e-02 +668 6.465000e-10 5.531191e-01 5.300000e-02 +669 6.475000e-10 5.533822e-01 5.500000e-02 +670 6.485000e-10 5.532192e-01 5.700000e-02 +671 6.495000e-10 5.527043e-01 5.900000e-02 +672 6.505000e-10 5.518973e-01 6.100000e-02 +673 6.515000e-10 5.508468e-01 6.300000e-02 +674 6.525000e-10 5.495931e-01 6.500000e-02 +675 6.535000e-10 5.481708e-01 6.700000e-02 +676 6.545000e-10 5.466097e-01 6.900000e-02 +677 6.555000e-10 5.449353e-01 7.100000e-02 +678 6.565000e-10 5.431672e-01 7.300000e-02 +679 6.575000e-10 5.413166e-01 7.500000e-02 +680 6.585000e-10 5.393863e-01 7.700000e-02 +681 6.595000e-10 5.373728e-01 7.900000e-02 +682 6.605000e-10 5.352711e-01 8.100000e-02 +683 6.615000e-10 5.330781e-01 8.300000e-02 +684 6.625000e-10 5.307926e-01 8.500000e-02 +685 6.635000e-10 5.284156e-01 8.700000e-02 +686 6.645000e-10 5.259491e-01 8.900000e-02 +687 6.655000e-10 5.233960e-01 9.100000e-02 +688 6.665000e-10 5.207593e-01 9.300000e-02 +689 6.675000e-10 5.180419e-01 9.500000e-02 +690 6.685000e-10 5.152467e-01 9.700000e-02 +691 6.695000e-10 5.123764e-01 9.900000e-02 +692 6.705000e-10 5.094333e-01 1.010000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +693 6.715000e-10 5.064195e-01 1.030000e-01 +694 6.725000e-10 5.033370e-01 1.050000e-01 +695 6.735000e-10 5.001872e-01 1.070000e-01 +696 6.745000e-10 4.969717e-01 1.090000e-01 +697 6.755000e-10 4.936916e-01 1.110000e-01 +698 6.765000e-10 4.903477e-01 1.130000e-01 +699 6.775000e-10 4.869410e-01 1.150000e-01 +700 6.785000e-10 4.834719e-01 1.170000e-01 +701 6.795000e-10 4.799410e-01 1.190000e-01 +702 6.805000e-10 4.763484e-01 1.210000e-01 +703 6.815000e-10 4.726943e-01 1.230000e-01 +704 6.825000e-10 4.689787e-01 1.250000e-01 +705 6.835000e-10 4.652015e-01 1.270000e-01 +706 6.845000e-10 4.613625e-01 1.290000e-01 +707 6.855000e-10 4.574612e-01 1.310000e-01 +708 6.865000e-10 4.534972e-01 1.330000e-01 +709 6.875000e-10 4.494700e-01 1.350000e-01 +710 6.885000e-10 4.453789e-01 1.370000e-01 +711 6.895000e-10 4.412230e-01 1.390000e-01 +712 6.905000e-10 4.370016e-01 1.410000e-01 +713 6.915000e-10 4.327138e-01 1.430000e-01 +714 6.925000e-10 4.283583e-01 1.450000e-01 +715 6.935000e-10 4.239342e-01 1.470000e-01 +716 6.945000e-10 4.194401e-01 1.490000e-01 +717 6.955000e-10 4.148747e-01 1.510000e-01 +718 6.965000e-10 4.102365e-01 1.530000e-01 +719 6.975000e-10 4.055240e-01 1.550000e-01 +720 6.985000e-10 4.007354e-01 1.570000e-01 +721 6.995000e-10 3.958690e-01 1.590000e-01 +722 7.005000e-10 3.909226e-01 1.610000e-01 +723 7.015000e-10 3.858942e-01 1.630000e-01 +724 7.025000e-10 3.807814e-01 1.650000e-01 +725 7.035000e-10 3.755814e-01 1.670000e-01 +726 7.045000e-10 3.702913e-01 1.690000e-01 +727 7.055000e-10 3.649099e-01 1.710000e-01 +728 7.065000e-10 3.594362e-01 1.730000e-01 +729 7.075000e-10 3.538676e-01 1.750000e-01 +730 7.085000e-10 3.482015e-01 1.770000e-01 +731 7.095000e-10 3.424348e-01 1.790000e-01 +732 7.105000e-10 3.365645e-01 1.810000e-01 +733 7.115000e-10 3.305872e-01 1.830000e-01 +734 7.125000e-10 3.244994e-01 1.850000e-01 +735 7.135000e-10 3.182971e-01 1.870000e-01 +736 7.145000e-10 3.119763e-01 1.890000e-01 +737 7.155000e-10 3.055324e-01 1.910000e-01 +738 7.165000e-10 2.989603e-01 1.930000e-01 +739 7.175000e-10 2.922546e-01 1.950000e-01 +740 7.185000e-10 2.854089e-01 1.970000e-01 +741 7.195000e-10 2.784155e-01 1.990000e-01 +742 7.200000e-10 2.748605e-01 2.000000e-01 +743 7.201000e-10 2.748604e-01 2.000000e-01 +744 7.203000e-10 2.748604e-01 2.000000e-01 +745 7.207000e-10 2.748604e-01 2.000000e-01 +746 7.215000e-10 2.748604e-01 2.000000e-01 +747 7.225000e-10 2.748604e-01 2.000000e-01 +748 7.235000e-10 2.748604e-01 2.000000e-01 +749 7.245000e-10 2.748604e-01 2.000000e-01 +750 7.255000e-10 2.748604e-01 2.000000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +751 7.265000e-10 2.748604e-01 2.000000e-01 +752 7.275000e-10 2.748604e-01 2.000000e-01 +753 7.285000e-10 2.748604e-01 2.000000e-01 +754 7.295000e-10 2.748604e-01 2.000000e-01 +755 7.305000e-10 2.748604e-01 2.000000e-01 +756 7.315000e-10 2.748604e-01 2.000000e-01 +757 7.325000e-10 2.748604e-01 2.000000e-01 +758 7.335000e-10 2.748604e-01 2.000000e-01 +759 7.345000e-10 2.748604e-01 2.000000e-01 +760 7.355000e-10 2.748604e-01 2.000000e-01 +761 7.365000e-10 2.748604e-01 2.000000e-01 +762 7.375000e-10 2.748604e-01 2.000000e-01 +763 7.385000e-10 2.748604e-01 2.000000e-01 +764 7.395000e-10 2.748604e-01 2.000000e-01 +765 7.405000e-10 2.748604e-01 2.000000e-01 +766 7.415000e-10 2.748604e-01 2.000000e-01 +767 7.425000e-10 2.748604e-01 2.000000e-01 +768 7.435000e-10 2.748604e-01 2.000000e-01 +769 7.445000e-10 2.748604e-01 2.000000e-01 +770 7.455000e-10 2.748604e-01 2.000000e-01 +771 7.465000e-10 2.748604e-01 2.000000e-01 +772 7.475000e-10 2.748604e-01 2.000000e-01 +773 7.485000e-10 2.748604e-01 2.000000e-01 +774 7.495000e-10 2.748604e-01 2.000000e-01 +775 7.505000e-10 2.748604e-01 2.000000e-01 +776 7.515000e-10 2.748604e-01 2.000000e-01 +777 7.525000e-10 2.748604e-01 2.000000e-01 +778 7.535000e-10 2.748604e-01 2.000000e-01 +779 7.545000e-10 2.748604e-01 2.000000e-01 +780 7.555000e-10 2.748604e-01 2.000000e-01 +781 7.565000e-10 2.748604e-01 2.000000e-01 +782 7.575000e-10 2.748604e-01 2.000000e-01 +783 7.585000e-10 2.748604e-01 2.000000e-01 +784 7.595000e-10 2.748604e-01 2.000000e-01 +785 7.605000e-10 2.748604e-01 2.000000e-01 +786 7.615000e-10 2.748604e-01 2.000000e-01 +787 7.625000e-10 2.748604e-01 2.000000e-01 +788 7.635000e-10 2.748604e-01 2.000000e-01 +789 7.645000e-10 2.748604e-01 2.000000e-01 +790 7.655000e-10 2.748604e-01 2.000000e-01 +791 7.665000e-10 2.748604e-01 2.000000e-01 +792 7.675000e-10 2.748604e-01 2.000000e-01 +793 7.685000e-10 2.748604e-01 2.000000e-01 +794 7.695000e-10 2.748604e-01 2.000000e-01 +795 7.705000e-10 2.748604e-01 2.000000e-01 +796 7.715000e-10 2.748604e-01 2.000000e-01 +797 7.725000e-10 2.748604e-01 2.000000e-01 +798 7.735000e-10 2.748604e-01 2.000000e-01 +799 7.745000e-10 2.748604e-01 2.000000e-01 +800 7.755000e-10 2.748604e-01 2.000000e-01 +801 7.765000e-10 2.748604e-01 2.000000e-01 +802 7.775000e-10 2.748604e-01 2.000000e-01 +803 7.785000e-10 2.748604e-01 2.000000e-01 +804 7.795000e-10 2.748604e-01 2.000000e-01 +805 7.805000e-10 2.748604e-01 2.000000e-01 +806 7.815000e-10 2.748604e-01 2.000000e-01 +807 7.825000e-10 2.748604e-01 2.000000e-01 +808 7.835000e-10 2.748604e-01 2.000000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +809 7.845000e-10 2.748604e-01 2.000000e-01 +810 7.855000e-10 2.748604e-01 2.000000e-01 +811 7.865000e-10 2.748604e-01 2.000000e-01 +812 7.875000e-10 2.748604e-01 2.000000e-01 +813 7.885000e-10 2.748604e-01 2.000000e-01 +814 7.895000e-10 2.748604e-01 2.000000e-01 +815 7.905000e-10 2.748604e-01 2.000000e-01 +816 7.915000e-10 2.748604e-01 2.000000e-01 +817 7.925000e-10 2.748604e-01 2.000000e-01 +818 7.935000e-10 2.748604e-01 2.000000e-01 +819 7.945000e-10 2.748604e-01 2.000000e-01 +820 7.955000e-10 2.748604e-01 2.000000e-01 +821 7.965000e-10 2.748604e-01 2.000000e-01 +822 7.975000e-10 2.748604e-01 2.000000e-01 +823 7.985000e-10 2.748604e-01 2.000000e-01 +824 7.995000e-10 2.748604e-01 2.000000e-01 +825 8.005000e-10 2.748604e-01 2.000000e-01 +826 8.015000e-10 2.748604e-01 2.000000e-01 +827 8.025000e-10 2.748604e-01 2.000000e-01 +828 8.035000e-10 2.748604e-01 2.000000e-01 +829 8.045000e-10 2.748604e-01 2.000000e-01 +830 8.055000e-10 2.748604e-01 2.000000e-01 +831 8.065000e-10 2.748604e-01 2.000000e-01 +832 8.075000e-10 2.748604e-01 2.000000e-01 +833 8.085000e-10 2.748604e-01 2.000000e-01 +834 8.095000e-10 2.748604e-01 2.000000e-01 +835 8.105000e-10 2.748604e-01 2.000000e-01 +836 8.115000e-10 2.748604e-01 2.000000e-01 +837 8.125000e-10 2.748604e-01 2.000000e-01 +838 8.135000e-10 2.748604e-01 2.000000e-01 +839 8.145000e-10 2.748604e-01 2.000000e-01 +840 8.155000e-10 2.748604e-01 2.000000e-01 +841 8.165000e-10 2.748604e-01 2.000000e-01 +842 8.175000e-10 2.748604e-01 2.000000e-01 +843 8.185000e-10 2.748604e-01 2.000000e-01 +844 8.195000e-10 2.748604e-01 2.000000e-01 +845 8.205000e-10 2.748604e-01 2.000000e-01 +846 8.215000e-10 2.748604e-01 2.000000e-01 +847 8.225000e-10 2.748604e-01 2.000000e-01 +848 8.235000e-10 2.748604e-01 2.000000e-01 +849 8.245000e-10 2.748604e-01 2.000000e-01 +850 8.255000e-10 2.748604e-01 2.000000e-01 +851 8.265000e-10 2.748604e-01 2.000000e-01 +852 8.275000e-10 2.748604e-01 2.000000e-01 +853 8.285000e-10 2.748604e-01 2.000000e-01 +854 8.295000e-10 2.748604e-01 2.000000e-01 +855 8.305000e-10 2.748604e-01 2.000000e-01 +856 8.315000e-10 2.748604e-01 2.000000e-01 +857 8.325000e-10 2.748604e-01 2.000000e-01 +858 8.335000e-10 2.748604e-01 2.000000e-01 +859 8.345000e-10 2.748604e-01 2.000000e-01 +860 8.355000e-10 2.748604e-01 2.000000e-01 +861 8.365000e-10 2.748604e-01 2.000000e-01 +862 8.375000e-10 2.748604e-01 2.000000e-01 +863 8.385000e-10 2.748604e-01 2.000000e-01 +864 8.395000e-10 2.748604e-01 2.000000e-01 +865 8.405000e-10 2.748604e-01 2.000000e-01 +866 8.415000e-10 2.748604e-01 2.000000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +867 8.425000e-10 2.748604e-01 2.000000e-01 +868 8.435000e-10 2.748604e-01 2.000000e-01 +869 8.445000e-10 2.748604e-01 2.000000e-01 +870 8.455000e-10 2.748604e-01 2.000000e-01 +871 8.465000e-10 2.748604e-01 2.000000e-01 +872 8.475000e-10 2.748604e-01 2.000000e-01 +873 8.485000e-10 2.748604e-01 2.000000e-01 +874 8.495000e-10 2.748604e-01 2.000000e-01 +875 8.505000e-10 2.748604e-01 2.000000e-01 +876 8.515000e-10 2.748604e-01 2.000000e-01 +877 8.525000e-10 2.748604e-01 2.000000e-01 +878 8.535000e-10 2.748604e-01 2.000000e-01 +879 8.545000e-10 2.748604e-01 2.000000e-01 +880 8.555000e-10 2.748604e-01 2.000000e-01 +881 8.565000e-10 2.748604e-01 2.000000e-01 +882 8.575000e-10 2.748604e-01 2.000000e-01 +883 8.585000e-10 2.748604e-01 2.000000e-01 +884 8.595000e-10 2.748604e-01 2.000000e-01 +885 8.605000e-10 2.748604e-01 2.000000e-01 +886 8.615000e-10 2.748604e-01 2.000000e-01 +887 8.625000e-10 2.748604e-01 2.000000e-01 +888 8.635000e-10 2.748604e-01 2.000000e-01 +889 8.645000e-10 2.748604e-01 2.000000e-01 +890 8.655000e-10 2.748604e-01 2.000000e-01 +891 8.665000e-10 2.748604e-01 2.000000e-01 +892 8.675000e-10 2.748604e-01 2.000000e-01 +893 8.685000e-10 2.748604e-01 2.000000e-01 +894 8.695000e-10 2.748604e-01 2.000000e-01 +895 8.705000e-10 2.748604e-01 2.000000e-01 +896 8.715000e-10 2.748604e-01 2.000000e-01 +897 8.725000e-10 2.748604e-01 2.000000e-01 +898 8.735000e-10 2.748604e-01 2.000000e-01 +899 8.745000e-10 2.748604e-01 2.000000e-01 +900 8.755000e-10 2.748604e-01 2.000000e-01 +901 8.765000e-10 2.748604e-01 2.000000e-01 +902 8.775000e-10 2.748604e-01 2.000000e-01 +903 8.785000e-10 2.748604e-01 2.000000e-01 +904 8.795000e-10 2.748604e-01 2.000000e-01 +905 8.805000e-10 2.748604e-01 2.000000e-01 +906 8.815000e-10 2.748604e-01 2.000000e-01 +907 8.825000e-10 2.748604e-01 2.000000e-01 +908 8.835000e-10 2.748604e-01 2.000000e-01 +909 8.845000e-10 2.748604e-01 2.000000e-01 +910 8.855000e-10 2.748604e-01 2.000000e-01 +911 8.865000e-10 2.748604e-01 2.000000e-01 +912 8.875000e-10 2.748604e-01 2.000000e-01 +913 8.885000e-10 2.748604e-01 2.000000e-01 +914 8.895000e-10 2.748604e-01 2.000000e-01 +915 8.905000e-10 2.748604e-01 2.000000e-01 +916 8.915000e-10 2.748604e-01 2.000000e-01 +917 8.925000e-10 2.748604e-01 2.000000e-01 +918 8.935000e-10 2.748604e-01 2.000000e-01 +919 8.945000e-10 2.748604e-01 2.000000e-01 +920 8.955000e-10 2.748604e-01 2.000000e-01 +921 8.965000e-10 2.748604e-01 2.000000e-01 +922 8.975000e-10 2.748604e-01 2.000000e-01 +923 8.985000e-10 2.748604e-01 2.000000e-01 +924 8.995000e-10 2.748604e-01 2.000000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +925 9.005000e-10 2.748604e-01 2.000000e-01 +926 9.015000e-10 2.748604e-01 2.000000e-01 +927 9.025000e-10 2.748604e-01 2.000000e-01 +928 9.035000e-10 2.748604e-01 2.000000e-01 +929 9.045000e-10 2.748604e-01 2.000000e-01 +930 9.055000e-10 2.748604e-01 2.000000e-01 +931 9.065000e-10 2.748604e-01 2.000000e-01 +932 9.075000e-10 2.748604e-01 2.000000e-01 +933 9.085000e-10 2.748604e-01 2.000000e-01 +934 9.095000e-10 2.748604e-01 2.000000e-01 +935 9.105000e-10 2.748604e-01 2.000000e-01 +936 9.115000e-10 2.748604e-01 2.000000e-01 +937 9.125000e-10 2.748604e-01 2.000000e-01 +938 9.135000e-10 2.748604e-01 2.000000e-01 +939 9.145000e-10 2.748604e-01 2.000000e-01 +940 9.155000e-10 2.748604e-01 2.000000e-01 +941 9.165000e-10 2.748604e-01 2.000000e-01 +942 9.175000e-10 2.748604e-01 2.000000e-01 +943 9.185000e-10 2.748604e-01 2.000000e-01 +944 9.195000e-10 2.748604e-01 2.000000e-01 +945 9.200000e-10 2.748604e-01 2.000000e-01 +946 9.201000e-10 2.755747e-01 1.998000e-01 +947 9.203000e-10 2.769983e-01 1.994000e-01 +948 9.207000e-10 2.798265e-01 1.986000e-01 +949 9.215000e-10 2.854089e-01 1.970000e-01 +950 9.225000e-10 2.922546e-01 1.950000e-01 +951 9.235000e-10 2.989603e-01 1.930000e-01 +952 9.245000e-10 3.055324e-01 1.910000e-01 +953 9.255000e-10 3.119763e-01 1.890000e-01 +954 9.265000e-10 3.182971e-01 1.870000e-01 +955 9.275000e-10 3.244994e-01 1.850000e-01 +956 9.285000e-10 3.305872e-01 1.830000e-01 +957 9.295000e-10 3.365645e-01 1.810000e-01 +958 9.305000e-10 3.424348e-01 1.790000e-01 +959 9.315000e-10 3.482015e-01 1.770000e-01 +960 9.325000e-10 3.538677e-01 1.750000e-01 +961 9.335000e-10 3.594362e-01 1.730000e-01 +962 9.345000e-10 3.649099e-01 1.710000e-01 +963 9.355000e-10 3.702913e-01 1.690000e-01 +964 9.365000e-10 3.755814e-01 1.670000e-01 +965 9.375000e-10 3.807814e-01 1.650000e-01 +966 9.385000e-10 3.858942e-01 1.630000e-01 +967 9.395000e-10 3.909226e-01 1.610000e-01 +968 9.405000e-10 3.958690e-01 1.590000e-01 +969 9.415000e-10 4.007354e-01 1.570000e-01 +970 9.425000e-10 4.055240e-01 1.550000e-01 +971 9.435000e-10 4.102365e-01 1.530000e-01 +972 9.445000e-10 4.148747e-01 1.510000e-01 +973 9.455000e-10 4.194401e-01 1.490000e-01 +974 9.465000e-10 4.239342e-01 1.470000e-01 +975 9.475000e-10 4.283583e-01 1.450000e-01 +976 9.485000e-10 4.327138e-01 1.430000e-01 +977 9.495000e-10 4.370016e-01 1.410000e-01 +978 9.505000e-10 4.412230e-01 1.390000e-01 +979 9.515000e-10 4.453789e-01 1.370000e-01 +980 9.525000e-10 4.494700e-01 1.350000e-01 +981 9.535000e-10 4.534972e-01 1.330000e-01 +982 9.545000e-10 4.574612e-01 1.310000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +983 9.555000e-10 4.613625e-01 1.290000e-01 +984 9.565000e-10 4.652015e-01 1.270000e-01 +985 9.575000e-10 4.689787e-01 1.250000e-01 +986 9.585000e-10 4.726943e-01 1.230000e-01 +987 9.595000e-10 4.763484e-01 1.210000e-01 +988 9.605000e-10 4.799410e-01 1.190000e-01 +989 9.615000e-10 4.834719e-01 1.170000e-01 +990 9.625000e-10 4.869410e-01 1.150000e-01 +991 9.635000e-10 4.903477e-01 1.130000e-01 +992 9.645000e-10 4.936916e-01 1.110000e-01 +993 9.655000e-10 4.969717e-01 1.090000e-01 +994 9.665000e-10 5.001872e-01 1.070000e-01 +995 9.675000e-10 5.033370e-01 1.050000e-01 +996 9.685000e-10 5.064195e-01 1.030000e-01 +997 9.695000e-10 5.094333e-01 1.010000e-01 +998 9.705000e-10 5.123764e-01 9.900000e-02 +999 9.715000e-10 5.152467e-01 9.700000e-02 +1000 9.725000e-10 5.180419e-01 9.500000e-02 +1001 9.735000e-10 5.207593e-01 9.300000e-02 +1002 9.745000e-10 5.233960e-01 9.100000e-02 +1003 9.755000e-10 5.259491e-01 8.900000e-02 +1004 9.765000e-10 5.284156e-01 8.700000e-02 +1005 9.775000e-10 5.307926e-01 8.500000e-02 +1006 9.785000e-10 5.330781e-01 8.300000e-02 +1007 9.795000e-10 5.352711e-01 8.100000e-02 +1008 9.805000e-10 5.373728e-01 7.900000e-02 +1009 9.815000e-10 5.393863e-01 7.700000e-02 +1010 9.825000e-10 5.413166e-01 7.500000e-02 +1011 9.835000e-10 5.431672e-01 7.300000e-02 +1012 9.845000e-10 5.449353e-01 7.100000e-02 +1013 9.855000e-10 5.466097e-01 6.900000e-02 +1014 9.865000e-10 5.481708e-01 6.700000e-02 +1015 9.875000e-10 5.495931e-01 6.500000e-02 +1016 9.885000e-10 5.508467e-01 6.300000e-02 +1017 9.895000e-10 5.518972e-01 6.100000e-02 +1018 9.905000e-10 5.527042e-01 5.900000e-02 +1019 9.915000e-10 5.532190e-01 5.700000e-02 +1020 9.925000e-10 5.533818e-01 5.500000e-02 +1021 9.935000e-10 5.531185e-01 5.300000e-02 +1022 9.945000e-10 5.523362e-01 5.100000e-02 +1023 9.955000e-10 5.509170e-01 4.900000e-02 +1024 9.965000e-10 5.487215e-01 4.700000e-02 +1025 9.975000e-10 5.455761e-01 4.500000e-02 +1026 9.985000e-10 5.412833e-01 4.300000e-02 +1027 9.995000e-10 5.356307e-01 4.100000e-02 +1028 1.000000e-09 5.322290e-01 4.000000e-02 + + + + diff --git a/tests/bsim3soidd/inv2.cir b/tests/bsim3soidd/inv2.cir new file mode 100644 index 000000000..6213f4cc1 --- /dev/null +++ b/tests/bsim3soidd/inv2.cir @@ -0,0 +1,17 @@ +* model = BSIMSOI (DD) +* +* +* SOI Inverter - floating body + +vin in 0 dc 2.5 +vdd dd 0 dc 2.5 +vss ss 0 dc 0 +ve e 0 dc 1.25 +m1 out in dd e p1 w=20u l=0.25u +m2 out in ss e n1 w=10u l=0.25u + +.option itl1=500 gmin=1e-25 +.dc vin 0 2.5 0.01 +.print dc v(in), v(out) +.include nmosdd.mod +.include pmosdd.mod diff --git a/tests/bsim3soidd/inv2.out b/tests/bsim3soidd/inv2.out new file mode 100644 index 000000000..1192e38ea --- /dev/null +++ b/tests/bsim3soidd/inv2.out @@ -0,0 +1,281 @@ + Reference value : 3.00000e-02 +No. of Data Rows : 251 + +Circuit: * model = BSIMSOI (DD) + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. + * model = BSIMSOI (DD) +-------------------------------------------------------------------------------- +Index v-sweep v(in) v(out) +-------------------------------------------------------------------------------- +0 0.000000e+00 0.000000e+00 2.500000e+00 +1 1.000000e-02 1.000000e-02 2.500000e+00 +2 2.000000e-02 2.000000e-02 2.500000e+00 +3 3.000000e-02 3.000000e-02 2.500000e+00 +4 4.000000e-02 4.000000e-02 2.500000e+00 +5 5.000000e-02 5.000000e-02 2.500000e+00 +6 6.000000e-02 6.000000e-02 2.499999e+00 +7 7.000000e-02 7.000000e-02 2.499999e+00 +8 8.000000e-02 8.000000e-02 2.499998e+00 +9 9.000000e-02 9.000000e-02 2.499997e+00 +10 1.000000e-01 1.000000e-01 2.499995e+00 +11 1.100000e-01 1.100000e-01 2.499993e+00 +12 1.200000e-01 1.200000e-01 2.499988e+00 +13 1.300000e-01 1.300000e-01 2.499982e+00 +14 1.400000e-01 1.400000e-01 2.499972e+00 +15 1.500000e-01 1.500000e-01 2.499957e+00 +16 1.600000e-01 1.600000e-01 2.499936e+00 +17 1.700000e-01 1.700000e-01 2.499905e+00 +18 1.800000e-01 1.800000e-01 2.499861e+00 +19 1.900000e-01 1.900000e-01 2.499802e+00 +20 2.000000e-01 2.000000e-01 2.499720e+00 +21 2.100000e-01 2.100000e-01 2.499612e+00 +22 2.200000e-01 2.200000e-01 2.499469e+00 +23 2.300000e-01 2.300000e-01 2.499283e+00 +24 2.400000e-01 2.400000e-01 2.499045e+00 +25 2.500000e-01 2.500000e-01 2.498745e+00 +26 2.600000e-01 2.600000e-01 2.498373e+00 +27 2.700000e-01 2.700000e-01 2.497919e+00 +28 2.800000e-01 2.800000e-01 2.497374e+00 +29 2.900000e-01 2.900000e-01 2.496733e+00 +30 3.000000e-01 3.000000e-01 2.495990e+00 +31 3.100000e-01 3.100000e-01 2.495142e+00 +32 3.200000e-01 3.200000e-01 2.494190e+00 +33 3.300000e-01 3.300000e-01 2.493135e+00 +34 3.400000e-01 3.400000e-01 2.491980e+00 +35 3.500000e-01 3.500000e-01 2.490729e+00 +36 3.600000e-01 3.600000e-01 2.489387e+00 +37 3.700000e-01 3.700000e-01 2.487957e+00 +38 3.800000e-01 3.800000e-01 2.486445e+00 +39 3.900000e-01 3.900000e-01 2.484855e+00 +40 4.000000e-01 4.000000e-01 2.483191e+00 +41 4.100000e-01 4.100000e-01 2.481458e+00 +42 4.200000e-01 4.200000e-01 2.479656e+00 +43 4.300000e-01 4.300000e-01 2.477790e+00 +44 4.400000e-01 4.400000e-01 2.475893e+00 +45 4.500000e-01 4.500000e-01 2.473902e+00 +46 4.600000e-01 4.600000e-01 2.471850e+00 +47 4.700000e-01 4.700000e-01 2.469739e+00 +48 4.800000e-01 4.800000e-01 2.467568e+00 +49 4.900000e-01 4.900000e-01 2.465338e+00 +50 5.000000e-01 5.000000e-01 2.463047e+00 +51 5.100000e-01 5.100000e-01 2.460695e+00 +52 5.200000e-01 5.200000e-01 2.458281e+00 +53 5.300000e-01 5.300000e-01 2.455803e+00 +54 5.400000e-01 5.400000e-01 2.453258e+00 + +Index v-sweep v(in) v(out) +-------------------------------------------------------------------------------- +55 5.500000e-01 5.500000e-01 2.450645e+00 +56 5.600000e-01 5.600000e-01 2.447959e+00 +57 5.700000e-01 5.700000e-01 2.445199e+00 +58 5.800000e-01 5.800000e-01 2.442359e+00 +59 5.900000e-01 5.900000e-01 2.439436e+00 +60 6.000000e-01 6.000000e-01 2.436423e+00 +61 6.100000e-01 6.100000e-01 2.433315e+00 +62 6.200000e-01 6.200000e-01 2.430106e+00 +63 6.300000e-01 6.300000e-01 2.426790e+00 +64 6.400000e-01 6.400000e-01 2.423360e+00 +65 6.500000e-01 6.500000e-01 2.419810e+00 +66 6.600000e-01 6.600000e-01 2.416136e+00 +67 6.700000e-01 6.700000e-01 2.412332e+00 +68 6.800000e-01 6.800000e-01 2.408396e+00 +69 6.900000e-01 6.900000e-01 2.404326e+00 +70 7.000000e-01 7.000000e-01 2.400119e+00 +71 7.100000e-01 7.100000e-01 2.395776e+00 +72 7.200000e-01 7.200000e-01 2.391296e+00 +73 7.300000e-01 7.300000e-01 2.386678e+00 +74 7.400000e-01 7.400000e-01 2.381922e+00 +75 7.500000e-01 7.500000e-01 2.377028e+00 +76 7.600000e-01 7.600000e-01 2.371993e+00 +77 7.700000e-01 7.700000e-01 2.366817e+00 +78 7.800000e-01 7.800000e-01 2.361497e+00 +79 7.900000e-01 7.900000e-01 2.356032e+00 +80 8.000000e-01 8.000000e-01 2.350417e+00 +81 8.100000e-01 8.100000e-01 2.344649e+00 +82 8.200000e-01 8.200000e-01 2.338725e+00 +83 8.300000e-01 8.300000e-01 2.332640e+00 +84 8.400000e-01 8.400000e-01 2.326389e+00 +85 8.500000e-01 8.500000e-01 2.319966e+00 +86 8.600000e-01 8.600000e-01 2.313365e+00 +87 8.700000e-01 8.700000e-01 2.306580e+00 +88 8.800000e-01 8.800000e-01 2.299602e+00 +89 8.900000e-01 8.900000e-01 2.292425e+00 +90 9.000000e-01 9.000000e-01 2.285038e+00 +91 9.100000e-01 9.100000e-01 2.277432e+00 +92 9.200000e-01 9.200000e-01 2.269597e+00 +93 9.300000e-01 9.300000e-01 2.261521e+00 +94 9.400000e-01 9.400000e-01 2.253190e+00 +95 9.500000e-01 9.500000e-01 2.244591e+00 +96 9.600000e-01 9.600000e-01 2.235708e+00 +97 9.700000e-01 9.700000e-01 2.226524e+00 +98 9.800000e-01 9.800000e-01 2.217020e+00 +99 9.900000e-01 9.900000e-01 2.207174e+00 +100 1.000000e+00 1.000000e+00 2.196963e+00 +101 1.010000e+00 1.010000e+00 2.186360e+00 +102 1.020000e+00 1.020000e+00 2.175336e+00 +103 1.030000e+00 1.030000e+00 2.163856e+00 +104 1.040000e+00 1.040000e+00 2.151884e+00 +105 1.050000e+00 1.050000e+00 2.139374e+00 +106 1.060000e+00 1.060000e+00 2.126277e+00 +107 1.070000e+00 1.070000e+00 2.112535e+00 +108 1.080000e+00 1.080000e+00 2.098080e+00 +109 1.090000e+00 1.090000e+00 2.082832e+00 +110 1.100000e+00 1.100000e+00 2.066695e+00 +111 1.110000e+00 1.110000e+00 2.049555e+00 +112 1.120000e+00 1.120000e+00 2.031270e+00 + +Index v-sweep v(in) v(out) +-------------------------------------------------------------------------------- +113 1.130000e+00 1.130000e+00 2.011666e+00 +114 1.140000e+00 1.140000e+00 1.990519e+00 +115 1.150000e+00 1.150000e+00 1.967540e+00 +116 1.160000e+00 1.160000e+00 1.942344e+00 +117 1.170000e+00 1.170000e+00 1.912764e+00 +118 1.180000e+00 1.180000e+00 1.880765e+00 +119 1.190000e+00 1.190000e+00 1.843736e+00 +120 1.200000e+00 1.200000e+00 1.799486e+00 +121 1.210000e+00 1.210000e+00 1.744438e+00 +122 1.220000e+00 1.220000e+00 1.674623e+00 +123 1.230000e+00 1.230000e+00 1.591732e+00 +124 1.240000e+00 1.240000e+00 1.504796e+00 +125 1.250000e+00 1.250000e+00 1.341767e+00 +126 1.260000e+00 1.260000e+00 1.088859e+00 +127 1.270000e+00 1.270000e+00 8.944283e-01 +128 1.280000e+00 1.280000e+00 7.996930e-01 +129 1.290000e+00 1.290000e+00 7.421102e-01 +130 1.300000e+00 1.300000e+00 6.965273e-01 +131 1.310000e+00 1.310000e+00 6.585117e-01 +132 1.320000e+00 1.320000e+00 6.255682e-01 +133 1.330000e+00 1.330000e+00 5.963416e-01 +134 1.340000e+00 1.340000e+00 5.699237e-01 +135 1.350000e+00 1.350000e+00 5.457322e-01 +136 1.360000e+00 1.360000e+00 5.233658e-01 +137 1.370000e+00 1.370000e+00 5.025323e-01 +138 1.380000e+00 1.380000e+00 4.830104e-01 +139 1.390000e+00 1.390000e+00 4.646277e-01 +140 1.400000e+00 1.400000e+00 4.472460e-01 +141 1.410000e+00 1.410000e+00 4.303257e-01 +142 1.420000e+00 1.420000e+00 4.146844e-01 +143 1.430000e+00 1.430000e+00 3.997397e-01 +144 1.440000e+00 1.440000e+00 3.854417e-01 +145 1.450000e+00 1.450000e+00 3.717346e-01 +146 1.460000e+00 1.460000e+00 3.585700e-01 +147 1.470000e+00 1.470000e+00 3.459059e-01 +148 1.480000e+00 1.480000e+00 3.337054e-01 +149 1.490000e+00 1.490000e+00 3.219360e-01 +150 1.500000e+00 1.500000e+00 3.105687e-01 +151 1.510000e+00 1.510000e+00 2.995777e-01 +152 1.520000e+00 1.520000e+00 2.889401e-01 +153 1.530000e+00 1.530000e+00 2.786350e-01 +154 1.540000e+00 1.540000e+00 2.686438e-01 +155 1.550000e+00 1.550000e+00 2.589495e-01 +156 1.560000e+00 1.560000e+00 2.495370e-01 +157 1.570000e+00 1.570000e+00 2.403921e-01 +158 1.580000e+00 1.580000e+00 2.315022e-01 +159 1.590000e+00 1.590000e+00 2.228557e-01 +160 1.600000e+00 1.600000e+00 2.144420e-01 +161 1.610000e+00 1.610000e+00 2.062514e-01 +162 1.620000e+00 1.620000e+00 1.982749e-01 +163 1.630000e+00 1.630000e+00 1.905043e-01 +164 1.640000e+00 1.640000e+00 1.829322e-01 +165 1.650000e+00 1.650000e+00 1.755516e-01 +166 1.660000e+00 1.660000e+00 1.683562e-01 +167 1.670000e+00 1.670000e+00 1.613401e-01 +168 1.680000e+00 1.680000e+00 1.544981e-01 +169 1.690000e+00 1.690000e+00 1.478252e-01 +170 1.700000e+00 1.700000e+00 1.413171e-01 + +Index v-sweep v(in) v(out) +-------------------------------------------------------------------------------- +171 1.710000e+00 1.710000e+00 1.349697e-01 +172 1.720000e+00 1.720000e+00 1.287794e-01 +173 1.730000e+00 1.730000e+00 1.227429e-01 +174 1.740000e+00 1.740000e+00 1.168574e-01 +175 1.750000e+00 1.750000e+00 1.111205e-01 +176 1.760000e+00 1.760000e+00 1.055301e-01 +177 1.770000e+00 1.770000e+00 1.000844e-01 +178 1.780000e+00 1.780000e+00 9.478225e-02 +179 1.790000e+00 1.790000e+00 8.962282e-02 +180 1.800000e+00 1.800000e+00 8.460577e-02 +181 1.810000e+00 1.810000e+00 7.973125e-02 +182 1.820000e+00 1.820000e+00 7.500000e-02 +183 1.830000e+00 1.830000e+00 7.048553e-02 +184 1.840000e+00 1.840000e+00 6.604639e-02 +185 1.850000e+00 1.850000e+00 6.175652e-02 +186 1.860000e+00 1.860000e+00 5.761877e-02 +187 1.870000e+00 1.870000e+00 5.363615e-02 +188 1.880000e+00 1.880000e+00 4.981126e-02 +189 1.890000e+00 1.890000e+00 4.614572e-02 +190 1.900000e+00 1.900000e+00 4.263946e-02 +191 1.910000e+00 1.910000e+00 3.929044e-02 +192 1.920000e+00 1.920000e+00 3.609476e-02 +193 1.930000e+00 1.930000e+00 3.304738e-02 +194 1.940000e+00 1.940000e+00 3.014312e-02 +195 1.950000e+00 1.950000e+00 2.737756e-02 +196 1.960000e+00 1.960000e+00 2.474756e-02 +197 1.970000e+00 1.970000e+00 2.225155e-02 +198 1.980000e+00 1.980000e+00 1.988946e-02 +199 1.990000e+00 1.990000e+00 1.766254e-02 +200 2.000000e+00 2.000000e+00 1.557305e-02 +201 2.010000e+00 2.010000e+00 1.362390e-02 +202 2.020000e+00 2.020000e+00 1.181825e-02 +203 2.030000e+00 2.030000e+00 1.015903e-02 +204 2.040000e+00 2.040000e+00 8.648498e-03 +205 2.050000e+00 2.050000e+00 7.287658e-03 +206 2.060000e+00 2.060000e+00 6.075845e-03 +207 2.070000e+00 2.070000e+00 5.010414e-03 +208 2.080000e+00 2.080000e+00 4.086512e-03 +209 2.090000e+00 2.090000e+00 3.296760e-03 +210 2.100000e+00 2.100000e+00 2.631395e-03 +211 2.110000e+00 2.110000e+00 2.078792e-03 +212 2.120000e+00 2.120000e+00 1.626135e-03 +213 2.130000e+00 2.130000e+00 1.260138e-03 +214 2.140000e+00 2.140000e+00 9.677529e-04 +215 2.150000e+00 2.150000e+00 7.367491e-04 +216 2.160000e+00 2.160000e+00 5.561208e-04 +217 2.170000e+00 2.170000e+00 4.162671e-04 +218 2.180000e+00 2.180000e+00 3.086589e-04 +219 2.190000e+00 2.190000e+00 2.265207e-04 +220 2.200000e+00 2.200000e+00 1.644502e-04 +221 2.210000e+00 2.210000e+00 1.180552e-04 +222 2.220000e+00 2.220000e+00 8.378694e-05 +223 2.230000e+00 2.230000e+00 5.879526e-05 +224 2.240000e+00 2.240000e+00 4.080839e-05 +225 2.250000e+00 2.250000e+00 2.803515e-05 +226 2.260000e+00 2.260000e+00 1.908330e-05 +227 2.270000e+00 2.270000e+00 1.288943e-05 +228 2.280000e+00 2.280000e+00 8.657802e-06 + +Index v-sweep v(in) v(out) +-------------------------------------------------------------------------------- +229 2.290000e+00 2.290000e+00 5.808017e-06 +230 2.300000e+00 2.300000e+00 3.929469e-06 +231 2.310000e+00 2.310000e+00 2.709442e-06 +232 2.320000e+00 2.320000e+00 1.888953e-06 +233 2.330000e+00 2.330000e+00 1.319648e-06 +234 2.340000e+00 2.340000e+00 9.225229e-07 +235 2.350000e+00 2.350000e+00 6.447846e-07 +236 2.360000e+00 2.360000e+00 4.503306e-07 +237 2.370000e+00 2.370000e+00 3.142418e-07 +238 2.380000e+00 2.380000e+00 2.190908e-07 +239 2.390000e+00 2.390000e+00 1.526323e-07 +240 2.400000e+00 2.400000e+00 1.062600e-07 +241 2.410000e+00 2.410000e+00 7.393178e-08 +242 2.420000e+00 2.420000e+00 5.141199e-08 +243 2.430000e+00 2.430000e+00 3.573541e-08 +244 2.440000e+00 2.440000e+00 2.482901e-08 +245 2.450000e+00 2.450000e+00 1.724520e-08 +246 2.460000e+00 2.460000e+00 1.197412e-08 +247 2.470000e+00 2.470000e+00 8.311920e-09 +248 2.480000e+00 2.480000e+00 5.768392e-09 +249 2.490000e+00 2.490000e+00 4.002351e-09 +250 2.500000e+00 2.500000e+00 2.776464e-09 + + + + diff --git a/tests/bsim3soidd/t3.cir b/tests/bsim3soidd/t3.cir new file mode 100644 index 000000000..f3b11da33 --- /dev/null +++ b/tests/bsim3soidd/t3.cir @@ -0,0 +1,18 @@ +*model = BSIMSOI (DD) +*Berkeley Spice Compatibility +* +* SOI NMOSFET, floating body simulation + +vd d 0 dc 1.5 +vs s 0 dc 0 +ve e 0 dc 0 +vg g 0 dc 3 + + +m1 d g s e n1 w=10u l=0.25u + +.option gmin=1e-25 itl1=500 +.dc vd 0 3 0.01 vg 0.5 3 0.5 +.print dc v(g), i(vs) +.include nmosdd.mod + diff --git a/tests/bsim3soidd/t3.out b/tests/bsim3soidd/t3.out new file mode 100644 index 000000000..d12cec162 --- /dev/null +++ b/tests/bsim3soidd/t3.out @@ -0,0 +1,1915 @@ + Reference value : 1.05000e+00 Reference value : 1.45000e+00 +No. of Data Rows : 1806 + +Circuit: *model = BSIMSOI (DD) + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. + *model = BSIMSOI (DD) +-------------------------------------------------------------------------------- +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 5.000000e-01 -2.914133e-21 +1 1.000000e-02 5.000000e-01 3.628821e-06 +2 2.000000e-02 5.000000e-01 6.866714e-06 +3 3.000000e-02 5.000000e-01 9.721321e-06 +4 4.000000e-02 5.000000e-01 1.220246e-05 +5 5.000000e-02 5.000000e-01 1.432317e-05 +6 6.000000e-02 5.000000e-01 1.610108e-05 +7 7.000000e-02 5.000000e-01 1.755994e-05 +8 8.000000e-02 5.000000e-01 1.873090e-05 +9 9.000000e-02 5.000000e-01 1.965237e-05 +10 1.000000e-01 5.000000e-01 2.036791e-05 +11 1.100000e-01 5.000000e-01 2.092197e-05 +12 1.200000e-01 5.000000e-01 2.135522e-05 +13 1.300000e-01 5.000000e-01 2.170127e-05 +14 1.400000e-01 5.000000e-01 2.198575e-05 +15 1.500000e-01 5.000000e-01 2.222712e-05 +16 1.600000e-01 5.000000e-01 2.243823e-05 +17 1.700000e-01 5.000000e-01 2.262788e-05 +18 1.800000e-01 5.000000e-01 2.280899e-05 +19 1.900000e-01 5.000000e-01 2.297010e-05 +20 2.000000e-01 5.000000e-01 2.312338e-05 +21 2.100000e-01 5.000000e-01 2.327068e-05 +22 2.200000e-01 5.000000e-01 2.341336e-05 +23 2.300000e-01 5.000000e-01 2.355243e-05 +24 2.400000e-01 5.000000e-01 2.368862e-05 +25 2.500000e-01 5.000000e-01 2.382250e-05 +26 2.600000e-01 5.000000e-01 2.395451e-05 +27 2.700000e-01 5.000000e-01 2.408499e-05 +28 2.800000e-01 5.000000e-01 2.421420e-05 +29 2.900000e-01 5.000000e-01 2.434237e-05 +30 3.000000e-01 5.000000e-01 2.446965e-05 +31 3.100000e-01 5.000000e-01 2.459620e-05 +32 3.200000e-01 5.000000e-01 2.472212e-05 +33 3.300000e-01 5.000000e-01 2.484752e-05 +34 3.400000e-01 5.000000e-01 2.497246e-05 +35 3.500000e-01 5.000000e-01 2.509703e-05 +36 3.600000e-01 5.000000e-01 2.522127e-05 +37 3.700000e-01 5.000000e-01 2.534523e-05 +38 3.800000e-01 5.000000e-01 2.546895e-05 +39 3.900000e-01 5.000000e-01 2.559248e-05 +40 4.000000e-01 5.000000e-01 2.571584e-05 +41 4.100000e-01 5.000000e-01 2.583905e-05 +42 4.200000e-01 5.000000e-01 2.596214e-05 +43 4.300000e-01 5.000000e-01 2.608514e-05 +44 4.400000e-01 5.000000e-01 2.620805e-05 +45 4.500000e-01 5.000000e-01 2.633090e-05 +46 4.600000e-01 5.000000e-01 2.645370e-05 +47 4.700000e-01 5.000000e-01 2.657646e-05 +48 4.800000e-01 5.000000e-01 2.669920e-05 +49 4.900000e-01 5.000000e-01 2.682192e-05 +50 5.000000e-01 5.000000e-01 2.694463e-05 +51 5.100000e-01 5.000000e-01 2.706734e-05 +52 5.200000e-01 5.000000e-01 2.719006e-05 +53 5.300000e-01 5.000000e-01 2.731280e-05 +54 5.400000e-01 5.000000e-01 2.743556e-05 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +55 5.500000e-01 5.000000e-01 2.755834e-05 +56 5.600000e-01 5.000000e-01 2.768116e-05 +57 5.700000e-01 5.000000e-01 2.780401e-05 +58 5.800000e-01 5.000000e-01 2.792690e-05 +59 5.900000e-01 5.000000e-01 2.804984e-05 +60 6.000000e-01 5.000000e-01 2.817283e-05 +61 6.100000e-01 5.000000e-01 2.829587e-05 +62 6.200000e-01 5.000000e-01 2.841897e-05 +63 6.300000e-01 5.000000e-01 2.854212e-05 +64 6.400000e-01 5.000000e-01 2.866533e-05 +65 6.500000e-01 5.000000e-01 2.878865e-05 +66 6.600000e-01 5.000000e-01 2.891200e-05 +67 6.700000e-01 5.000000e-01 2.903542e-05 +68 6.800000e-01 5.000000e-01 2.915892e-05 +69 6.900000e-01 5.000000e-01 2.928250e-05 +70 7.000000e-01 5.000000e-01 2.940617e-05 +71 7.100000e-01 5.000000e-01 2.952995e-05 +72 7.200000e-01 5.000000e-01 2.965384e-05 +73 7.300000e-01 5.000000e-01 2.977787e-05 +74 7.400000e-01 5.000000e-01 2.990204e-05 +75 7.500000e-01 5.000000e-01 3.002638e-05 +76 7.600000e-01 5.000000e-01 3.015091e-05 +77 7.700000e-01 5.000000e-01 3.027565e-05 +78 7.800000e-01 5.000000e-01 3.040061e-05 +79 7.900000e-01 5.000000e-01 3.052581e-05 +80 8.000000e-01 5.000000e-01 3.065113e-05 +81 8.100000e-01 5.000000e-01 3.077688e-05 +82 8.200000e-01 5.000000e-01 3.090296e-05 +83 8.300000e-01 5.000000e-01 3.102945e-05 +84 8.400000e-01 5.000000e-01 3.115644e-05 +85 8.500000e-01 5.000000e-01 3.128410e-05 +86 8.600000e-01 5.000000e-01 3.141266e-05 +87 8.700000e-01 5.000000e-01 3.154251e-05 +88 8.800000e-01 5.000000e-01 3.167436e-05 +89 8.900000e-01 5.000000e-01 3.180955e-05 +90 9.000000e-01 5.000000e-01 3.195099e-05 +91 9.100000e-01 5.000000e-01 3.210603e-05 +92 9.200000e-01 5.000000e-01 3.233421e-05 +93 9.300000e-01 5.000000e-01 3.268787e-05 +94 9.400000e-01 5.000000e-01 3.315737e-05 +95 9.500000e-01 5.000000e-01 3.364289e-05 +96 9.600000e-01 5.000000e-01 3.411220e-05 +97 9.700000e-01 5.000000e-01 3.456858e-05 +98 9.800000e-01 5.000000e-01 3.503438e-05 +99 9.900000e-01 5.000000e-01 3.553760e-05 +100 1.000000e+00 5.000000e-01 3.615687e-05 +101 1.010000e+00 5.000000e-01 3.686245e-05 +102 1.020000e+00 5.000000e-01 3.770443e-05 +103 1.030000e+00 5.000000e-01 3.868068e-05 +104 1.040000e+00 5.000000e-01 3.976837e-05 +105 1.050000e+00 5.000000e-01 4.090246e-05 +106 1.060000e+00 5.000000e-01 4.214607e-05 +107 1.070000e+00 5.000000e-01 4.343558e-05 +108 1.080000e+00 5.000000e-01 4.476119e-05 +109 1.090000e+00 5.000000e-01 4.611753e-05 +110 1.100000e+00 5.000000e-01 4.750069e-05 +111 1.110000e+00 5.000000e-01 4.890786e-05 +112 1.120000e+00 5.000000e-01 5.035725e-05 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +113 1.130000e+00 5.000000e-01 5.183807e-05 +114 1.140000e+00 5.000000e-01 5.334484e-05 +115 1.150000e+00 5.000000e-01 5.487450e-05 +116 1.160000e+00 5.000000e-01 5.642457e-05 +117 1.170000e+00 5.000000e-01 5.799298e-05 +118 1.180000e+00 5.000000e-01 5.957797e-05 +119 1.190000e+00 5.000000e-01 6.117802e-05 +120 1.200000e+00 5.000000e-01 6.279182e-05 +121 1.210000e+00 5.000000e-01 6.441820e-05 +122 1.220000e+00 5.000000e-01 6.605608e-05 +123 1.230000e+00 5.000000e-01 6.770454e-05 +124 1.240000e+00 5.000000e-01 6.936269e-05 +125 1.250000e+00 5.000000e-01 7.102973e-05 +126 1.260000e+00 5.000000e-01 7.270493e-05 +127 1.270000e+00 5.000000e-01 7.438759e-05 +128 1.280000e+00 5.000000e-01 7.607708e-05 +129 1.290000e+00 5.000000e-01 7.777278e-05 +130 1.300000e+00 5.000000e-01 7.947414e-05 +131 1.310000e+00 5.000000e-01 8.118062e-05 +132 1.320000e+00 5.000000e-01 8.289171e-05 +133 1.330000e+00 5.000000e-01 8.460694e-05 +134 1.340000e+00 5.000000e-01 8.632584e-05 +135 1.350000e+00 5.000000e-01 8.804800e-05 +136 1.360000e+00 5.000000e-01 8.977299e-05 +137 1.370000e+00 5.000000e-01 9.150043e-05 +138 1.380000e+00 5.000000e-01 9.322994e-05 +139 1.390000e+00 5.000000e-01 9.496117e-05 +140 1.400000e+00 5.000000e-01 9.669379e-05 +141 1.410000e+00 5.000000e-01 9.842747e-05 +142 1.420000e+00 5.000000e-01 1.001619e-04 +143 1.430000e+00 5.000000e-01 1.018968e-04 +144 1.440000e+00 5.000000e-01 1.036319e-04 +145 1.450000e+00 5.000000e-01 1.053668e-04 +146 1.460000e+00 5.000000e-01 1.071015e-04 +147 1.470000e+00 5.000000e-01 1.088355e-04 +148 1.480000e+00 5.000000e-01 1.105687e-04 +149 1.490000e+00 5.000000e-01 1.123009e-04 +150 1.500000e+00 5.000000e-01 1.140318e-04 +151 1.510000e+00 5.000000e-01 1.157612e-04 +152 1.520000e+00 5.000000e-01 1.174890e-04 +153 1.530000e+00 5.000000e-01 1.192149e-04 +154 1.540000e+00 5.000000e-01 1.209388e-04 +155 1.550000e+00 5.000000e-01 1.226605e-04 +156 1.560000e+00 5.000000e-01 1.243799e-04 +157 1.570000e+00 5.000000e-01 1.260967e-04 +158 1.580000e+00 5.000000e-01 1.278109e-04 +159 1.590000e+00 5.000000e-01 1.295223e-04 +160 1.600000e+00 5.000000e-01 1.312307e-04 +161 1.610000e+00 5.000000e-01 1.329361e-04 +162 1.620000e+00 5.000000e-01 1.346383e-04 +163 1.630000e+00 5.000000e-01 1.363371e-04 +164 1.640000e+00 5.000000e-01 1.380326e-04 +165 1.650000e+00 5.000000e-01 1.397245e-04 +166 1.660000e+00 5.000000e-01 1.414128e-04 +167 1.670000e+00 5.000000e-01 1.430974e-04 +168 1.680000e+00 5.000000e-01 1.447782e-04 +169 1.690000e+00 5.000000e-01 1.464550e-04 +170 1.700000e+00 5.000000e-01 1.481279e-04 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +171 1.710000e+00 5.000000e-01 1.497967e-04 +172 1.720000e+00 5.000000e-01 1.514613e-04 +173 1.730000e+00 5.000000e-01 1.531218e-04 +174 1.740000e+00 5.000000e-01 1.547779e-04 +175 1.750000e+00 5.000000e-01 1.564297e-04 +176 1.760000e+00 5.000000e-01 1.580771e-04 +177 1.770000e+00 5.000000e-01 1.597200e-04 +178 1.780000e+00 5.000000e-01 1.613584e-04 +179 1.790000e+00 5.000000e-01 1.629922e-04 +180 1.800000e+00 5.000000e-01 1.646214e-04 +181 1.810000e+00 5.000000e-01 1.662459e-04 +182 1.820000e+00 5.000000e-01 1.678657e-04 +183 1.830000e+00 5.000000e-01 1.694807e-04 +184 1.840000e+00 5.000000e-01 1.710909e-04 +185 1.850000e+00 5.000000e-01 1.726962e-04 +186 1.860000e+00 5.000000e-01 1.742967e-04 +187 1.870000e+00 5.000000e-01 1.758922e-04 +188 1.880000e+00 5.000000e-01 1.774828e-04 +189 1.890000e+00 5.000000e-01 1.790685e-04 +190 1.900000e+00 5.000000e-01 1.806491e-04 +191 1.910000e+00 5.000000e-01 1.822247e-04 +192 1.920000e+00 5.000000e-01 1.837952e-04 +193 1.930000e+00 5.000000e-01 1.853607e-04 +194 1.940000e+00 5.000000e-01 1.869210e-04 +195 1.950000e+00 5.000000e-01 1.884762e-04 +196 1.960000e+00 5.000000e-01 1.900263e-04 +197 1.970000e+00 5.000000e-01 1.915713e-04 +198 1.980000e+00 5.000000e-01 1.931110e-04 +199 1.990000e+00 5.000000e-01 1.946456e-04 +200 2.000000e+00 5.000000e-01 1.961750e-04 +201 2.010000e+00 5.000000e-01 1.976991e-04 +202 2.020000e+00 5.000000e-01 1.992181e-04 +203 2.030000e+00 5.000000e-01 2.007318e-04 +204 2.040000e+00 5.000000e-01 2.022403e-04 +205 2.050000e+00 5.000000e-01 2.037435e-04 +206 2.060000e+00 5.000000e-01 2.052415e-04 +207 2.070000e+00 5.000000e-01 2.067342e-04 +208 2.080000e+00 5.000000e-01 2.082217e-04 +209 2.090000e+00 5.000000e-01 2.097039e-04 +210 2.100000e+00 5.000000e-01 2.111808e-04 +211 2.110000e+00 5.000000e-01 2.126525e-04 +212 2.120000e+00 5.000000e-01 2.141188e-04 +213 2.130000e+00 5.000000e-01 2.155800e-04 +214 2.140000e+00 5.000000e-01 2.170358e-04 +215 2.150000e+00 5.000000e-01 2.184864e-04 +216 2.160000e+00 5.000000e-01 2.199317e-04 +217 2.170000e+00 5.000000e-01 2.213718e-04 +218 2.180000e+00 5.000000e-01 2.228066e-04 +219 2.190000e+00 5.000000e-01 2.242361e-04 +220 2.200000e+00 5.000000e-01 2.256604e-04 +221 2.210000e+00 5.000000e-01 2.270795e-04 +222 2.220000e+00 5.000000e-01 2.284933e-04 +223 2.230000e+00 5.000000e-01 2.299020e-04 +224 2.240000e+00 5.000000e-01 2.313054e-04 +225 2.250000e+00 5.000000e-01 2.327036e-04 +226 2.260000e+00 5.000000e-01 2.340965e-04 +227 2.270000e+00 5.000000e-01 2.354844e-04 +228 2.280000e+00 5.000000e-01 2.368670e-04 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +229 2.290000e+00 5.000000e-01 2.382445e-04 +230 2.300000e+00 5.000000e-01 2.396168e-04 +231 2.310000e+00 5.000000e-01 2.409840e-04 +232 2.320000e+00 5.000000e-01 2.423460e-04 +233 2.330000e+00 5.000000e-01 2.437030e-04 +234 2.340000e+00 5.000000e-01 2.450548e-04 +235 2.350000e+00 5.000000e-01 2.464016e-04 +236 2.360000e+00 5.000000e-01 2.477433e-04 +237 2.370000e+00 5.000000e-01 2.490800e-04 +238 2.380000e+00 5.000000e-01 2.504116e-04 +239 2.390000e+00 5.000000e-01 2.517382e-04 +240 2.400000e+00 5.000000e-01 2.530599e-04 +241 2.410000e+00 5.000000e-01 2.543765e-04 +242 2.420000e+00 5.000000e-01 2.556883e-04 +243 2.430000e+00 5.000000e-01 2.569950e-04 +244 2.440000e+00 5.000000e-01 2.582969e-04 +245 2.450000e+00 5.000000e-01 2.595939e-04 +246 2.460000e+00 5.000000e-01 2.608860e-04 +247 2.470000e+00 5.000000e-01 2.621732e-04 +248 2.480000e+00 5.000000e-01 2.634557e-04 +249 2.490000e+00 5.000000e-01 2.647333e-04 +250 2.500000e+00 5.000000e-01 2.660062e-04 +251 2.510000e+00 5.000000e-01 2.672743e-04 +252 2.520000e+00 5.000000e-01 2.685377e-04 +253 2.530000e+00 5.000000e-01 2.697964e-04 +254 2.540000e+00 5.000000e-01 2.710505e-04 +255 2.550000e+00 5.000000e-01 2.722999e-04 +256 2.560000e+00 5.000000e-01 2.735447e-04 +257 2.570000e+00 5.000000e-01 2.747849e-04 +258 2.580000e+00 5.000000e-01 2.760206e-04 +259 2.590000e+00 5.000000e-01 2.772517e-04 +260 2.600000e+00 5.000000e-01 2.784783e-04 +261 2.610000e+00 5.000000e-01 2.797005e-04 +262 2.620000e+00 5.000000e-01 2.809183e-04 +263 2.630000e+00 5.000000e-01 2.821317e-04 +264 2.640000e+00 5.000000e-01 2.833407e-04 +265 2.650000e+00 5.000000e-01 2.845454e-04 +266 2.660000e+00 5.000000e-01 2.857458e-04 +267 2.670000e+00 5.000000e-01 2.869420e-04 +268 2.680000e+00 5.000000e-01 2.881339e-04 +269 2.690000e+00 5.000000e-01 2.893217e-04 +270 2.700000e+00 5.000000e-01 2.905053e-04 +271 2.710000e+00 5.000000e-01 2.916848e-04 +272 2.720000e+00 5.000000e-01 2.928602e-04 +273 2.730000e+00 5.000000e-01 2.940317e-04 +274 2.740000e+00 5.000000e-01 2.951991e-04 +275 2.750000e+00 5.000000e-01 2.963626e-04 +276 2.760000e+00 5.000000e-01 2.975222e-04 +277 2.770000e+00 5.000000e-01 2.986779e-04 +278 2.780000e+00 5.000000e-01 2.998299e-04 +279 2.790000e+00 5.000000e-01 3.009780e-04 +280 2.800000e+00 5.000000e-01 3.021224e-04 +281 2.810000e+00 5.000000e-01 3.032631e-04 +282 2.820000e+00 5.000000e-01 3.044002e-04 +283 2.830000e+00 5.000000e-01 3.055337e-04 +284 2.840000e+00 5.000000e-01 3.066637e-04 +285 2.850000e+00 5.000000e-01 3.077901e-04 +286 2.860000e+00 5.000000e-01 3.089132e-04 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +287 2.870000e+00 5.000000e-01 3.100328e-04 +288 2.880000e+00 5.000000e-01 3.111490e-04 +289 2.890000e+00 5.000000e-01 3.122620e-04 +290 2.900000e+00 5.000000e-01 3.133717e-04 +291 2.910000e+00 5.000000e-01 3.144782e-04 +292 2.920000e+00 5.000000e-01 3.155815e-04 +293 2.930000e+00 5.000000e-01 3.166818e-04 +294 2.940000e+00 5.000000e-01 3.177790e-04 +295 2.950000e+00 5.000000e-01 3.188732e-04 +296 2.960000e+00 5.000000e-01 3.199645e-04 +297 2.970000e+00 5.000000e-01 3.210529e-04 +298 2.980000e+00 5.000000e-01 3.221385e-04 +299 2.990000e+00 5.000000e-01 3.232213e-04 +300 3.000000e+00 5.000000e-01 3.243014e-04 +301 0.000000e+00 1.000000e+00 -4.127090e-32 +302 1.000000e-02 1.000000e+00 3.035382e-05 +303 2.000000e-02 1.000000e+00 6.014191e-05 +304 3.000000e-02 1.000000e+00 8.936619e-05 +305 4.000000e-02 1.000000e+00 1.180286e-04 +306 5.000000e-02 1.000000e+00 1.461310e-04 +307 6.000000e-02 1.000000e+00 1.736754e-04 +308 7.000000e-02 1.000000e+00 2.006636e-04 +309 8.000000e-02 1.000000e+00 2.270975e-04 +310 9.000000e-02 1.000000e+00 2.529791e-04 +311 1.000000e-01 1.000000e+00 2.783103e-04 +312 1.100000e-01 1.000000e+00 3.030928e-04 +313 1.200000e-01 1.000000e+00 3.273287e-04 +314 1.300000e-01 1.000000e+00 3.510198e-04 +315 1.400000e-01 1.000000e+00 3.741679e-04 +316 1.500000e-01 1.000000e+00 3.967749e-04 +317 1.600000e-01 1.000000e+00 4.188428e-04 +318 1.700000e-01 1.000000e+00 4.403734e-04 +319 1.800000e-01 1.000000e+00 4.616360e-04 +320 1.900000e-01 1.000000e+00 4.820967e-04 +321 2.000000e-01 1.000000e+00 5.020257e-04 +322 2.100000e-01 1.000000e+00 5.214250e-04 +323 2.200000e-01 1.000000e+00 5.402964e-04 +324 2.300000e-01 1.000000e+00 5.586418e-04 +325 2.400000e-01 1.000000e+00 5.764632e-04 +326 2.500000e-01 1.000000e+00 5.937625e-04 +327 2.600000e-01 1.000000e+00 6.105416e-04 +328 2.700000e-01 1.000000e+00 6.268026e-04 +329 2.800000e-01 1.000000e+00 6.425474e-04 +330 2.900000e-01 1.000000e+00 6.577781e-04 +331 3.000000e-01 1.000000e+00 6.724969e-04 +332 3.100000e-01 1.000000e+00 6.867059e-04 +333 3.200000e-01 1.000000e+00 7.004073e-04 +334 3.300000e-01 1.000000e+00 7.136036e-04 +335 3.400000e-01 1.000000e+00 7.262972e-04 +336 3.500000e-01 1.000000e+00 7.384907e-04 +337 3.600000e-01 1.000000e+00 7.501870e-04 +338 3.700000e-01 1.000000e+00 7.613891e-04 +339 3.800000e-01 1.000000e+00 7.721005e-04 +340 3.900000e-01 1.000000e+00 7.823248e-04 +341 4.000000e-01 1.000000e+00 7.920664e-04 +342 4.100000e-01 1.000000e+00 8.013299e-04 +343 4.200000e-01 1.000000e+00 8.101209e-04 +344 4.300000e-01 1.000000e+00 8.184458e-04 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +345 4.400000e-01 1.000000e+00 8.263120e-04 +346 4.500000e-01 1.000000e+00 8.337282e-04 +347 4.600000e-01 1.000000e+00 8.407046e-04 +348 4.700000e-01 1.000000e+00 8.472530e-04 +349 4.800000e-01 1.000000e+00 8.533869e-04 +350 4.900000e-01 1.000000e+00 8.591217e-04 +351 5.000000e-01 1.000000e+00 8.644749e-04 +352 5.100000e-01 1.000000e+00 8.694655e-04 +353 5.200000e-01 1.000000e+00 8.741141e-04 +354 5.300000e-01 1.000000e+00 8.784427e-04 +355 5.400000e-01 1.000000e+00 8.824737e-04 +356 5.500000e-01 1.000000e+00 8.862300e-04 +357 5.600000e-01 1.000000e+00 8.897343e-04 +358 5.700000e-01 1.000000e+00 8.930086e-04 +359 5.800000e-01 1.000000e+00 8.960739e-04 +360 5.900000e-01 1.000000e+00 8.989499e-04 +361 6.000000e-01 1.000000e+00 9.016552e-04 +362 6.100000e-01 1.000000e+00 9.042064e-04 +363 6.200000e-01 1.000000e+00 9.066190e-04 +364 6.300000e-01 1.000000e+00 9.089068e-04 +365 6.400000e-01 1.000000e+00 9.110824e-04 +366 6.500000e-01 1.000000e+00 9.131567e-04 +367 6.600000e-01 1.000000e+00 9.151399e-04 +368 6.700000e-01 1.000000e+00 9.170409e-04 +369 6.800000e-01 1.000000e+00 9.188674e-04 +370 6.900000e-01 1.000000e+00 9.206266e-04 +371 7.000000e-01 1.000000e+00 9.223246e-04 +372 7.100000e-01 1.000000e+00 9.239672e-04 +373 7.200000e-01 1.000000e+00 9.255593e-04 +374 7.300000e-01 1.000000e+00 9.271053e-04 +375 7.400000e-01 1.000000e+00 9.286091e-04 +376 7.500000e-01 1.000000e+00 9.300744e-04 +377 7.600000e-01 1.000000e+00 9.315043e-04 +378 7.700000e-01 1.000000e+00 9.329017e-04 +379 7.800000e-01 1.000000e+00 9.342692e-04 +380 7.900000e-01 1.000000e+00 9.356090e-04 +381 8.000000e-01 1.000000e+00 9.369234e-04 +382 8.100000e-01 1.000000e+00 9.382141e-04 +383 8.200000e-01 1.000000e+00 9.394830e-04 +384 8.300000e-01 1.000000e+00 9.407315e-04 +385 8.400000e-01 1.000000e+00 9.419611e-04 +386 8.500000e-01 1.000000e+00 9.431731e-04 +387 8.600000e-01 1.000000e+00 9.443687e-04 +388 8.700000e-01 1.000000e+00 9.455489e-04 +389 8.800000e-01 1.000000e+00 9.467148e-04 +390 8.900000e-01 1.000000e+00 9.478673e-04 +391 9.000000e-01 1.000000e+00 9.490010e-04 +392 9.100000e-01 1.000000e+00 9.501305e-04 +393 9.200000e-01 1.000000e+00 9.512496e-04 +394 9.300000e-01 1.000000e+00 9.523590e-04 +395 9.400000e-01 1.000000e+00 9.534597e-04 +396 9.500000e-01 1.000000e+00 9.545524e-04 +397 9.600000e-01 1.000000e+00 9.556378e-04 +398 9.700000e-01 1.000000e+00 9.567166e-04 +399 9.800000e-01 1.000000e+00 9.577924e-04 +400 9.900000e-01 1.000000e+00 9.588578e-04 +401 1.000000e+00 1.000000e+00 9.599222e-04 +402 1.010000e+00 1.000000e+00 9.609844e-04 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +403 1.020000e+00 1.000000e+00 9.620466e-04 +404 1.030000e+00 1.000000e+00 9.631129e-04 +405 1.040000e+00 1.000000e+00 9.641899e-04 +406 1.050000e+00 1.000000e+00 9.652919e-04 +407 1.060000e+00 1.000000e+00 9.664149e-04 +408 1.070000e+00 1.000000e+00 9.676715e-04 +409 1.080000e+00 1.000000e+00 9.693004e-04 +410 1.090000e+00 1.000000e+00 9.734431e-04 +411 1.100000e+00 1.000000e+00 9.780210e-04 +412 1.110000e+00 1.000000e+00 9.834849e-04 +413 1.120000e+00 1.000000e+00 9.886748e-04 +414 1.130000e+00 1.000000e+00 9.936873e-04 +415 1.140000e+00 1.000000e+00 9.985700e-04 +416 1.150000e+00 1.000000e+00 1.003324e-03 +417 1.160000e+00 1.000000e+00 1.007959e-03 +418 1.170000e+00 1.000000e+00 1.012479e-03 +419 1.180000e+00 1.000000e+00 1.016892e-03 +420 1.190000e+00 1.000000e+00 1.021204e-03 +421 1.200000e+00 1.000000e+00 1.025419e-03 +422 1.210000e+00 1.000000e+00 1.029544e-03 +423 1.220000e+00 1.000000e+00 1.033583e-03 +424 1.230000e+00 1.000000e+00 1.037542e-03 +425 1.240000e+00 1.000000e+00 1.041424e-03 +426 1.250000e+00 1.000000e+00 1.045256e-03 +427 1.260000e+00 1.000000e+00 1.049121e-03 +428 1.270000e+00 1.000000e+00 1.052956e-03 +429 1.280000e+00 1.000000e+00 1.056750e-03 +430 1.290000e+00 1.000000e+00 1.060497e-03 +431 1.300000e+00 1.000000e+00 1.064195e-03 +432 1.310000e+00 1.000000e+00 1.067841e-03 +433 1.320000e+00 1.000000e+00 1.071433e-03 +434 1.330000e+00 1.000000e+00 1.074970e-03 +435 1.340000e+00 1.000000e+00 1.078455e-03 +436 1.350000e+00 1.000000e+00 1.081885e-03 +437 1.360000e+00 1.000000e+00 1.085263e-03 +438 1.370000e+00 1.000000e+00 1.088590e-03 +439 1.380000e+00 1.000000e+00 1.091866e-03 +440 1.390000e+00 1.000000e+00 1.095093e-03 +441 1.400000e+00 1.000000e+00 1.098273e-03 +442 1.410000e+00 1.000000e+00 1.101406e-03 +443 1.420000e+00 1.000000e+00 1.104494e-03 +444 1.430000e+00 1.000000e+00 1.107538e-03 +445 1.440000e+00 1.000000e+00 1.110540e-03 +446 1.450000e+00 1.000000e+00 1.113502e-03 +447 1.460000e+00 1.000000e+00 1.116424e-03 +448 1.470000e+00 1.000000e+00 1.119307e-03 +449 1.480000e+00 1.000000e+00 1.122154e-03 +450 1.490000e+00 1.000000e+00 1.124965e-03 +451 1.500000e+00 1.000000e+00 1.127742e-03 +452 1.510000e+00 1.000000e+00 1.130485e-03 +453 1.520000e+00 1.000000e+00 1.133196e-03 +454 1.530000e+00 1.000000e+00 1.135876e-03 +455 1.540000e+00 1.000000e+00 1.138526e-03 +456 1.550000e+00 1.000000e+00 1.141147e-03 +457 1.560000e+00 1.000000e+00 1.143740e-03 +458 1.570000e+00 1.000000e+00 1.146306e-03 +459 1.580000e+00 1.000000e+00 1.148845e-03 +460 1.590000e+00 1.000000e+00 1.151360e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +461 1.600000e+00 1.000000e+00 1.153850e-03 +462 1.610000e+00 1.000000e+00 1.156317e-03 +463 1.620000e+00 1.000000e+00 1.158760e-03 +464 1.630000e+00 1.000000e+00 1.161182e-03 +465 1.640000e+00 1.000000e+00 1.163582e-03 +466 1.650000e+00 1.000000e+00 1.165961e-03 +467 1.660000e+00 1.000000e+00 1.168321e-03 +468 1.670000e+00 1.000000e+00 1.170661e-03 +469 1.680000e+00 1.000000e+00 1.172982e-03 +470 1.690000e+00 1.000000e+00 1.175286e-03 +471 1.700000e+00 1.000000e+00 1.177571e-03 +472 1.710000e+00 1.000000e+00 1.179840e-03 +473 1.720000e+00 1.000000e+00 1.182092e-03 +474 1.730000e+00 1.000000e+00 1.184328e-03 +475 1.740000e+00 1.000000e+00 1.186548e-03 +476 1.750000e+00 1.000000e+00 1.188754e-03 +477 1.760000e+00 1.000000e+00 1.190944e-03 +478 1.770000e+00 1.000000e+00 1.193121e-03 +479 1.780000e+00 1.000000e+00 1.195283e-03 +480 1.790000e+00 1.000000e+00 1.197433e-03 +481 1.800000e+00 1.000000e+00 1.199569e-03 +482 1.810000e+00 1.000000e+00 1.201692e-03 +483 1.820000e+00 1.000000e+00 1.203803e-03 +484 1.830000e+00 1.000000e+00 1.205901e-03 +485 1.840000e+00 1.000000e+00 1.207988e-03 +486 1.850000e+00 1.000000e+00 1.210063e-03 +487 1.860000e+00 1.000000e+00 1.212128e-03 +488 1.870000e+00 1.000000e+00 1.214181e-03 +489 1.880000e+00 1.000000e+00 1.216223e-03 +490 1.890000e+00 1.000000e+00 1.218255e-03 +491 1.900000e+00 1.000000e+00 1.220277e-03 +492 1.910000e+00 1.000000e+00 1.222288e-03 +493 1.920000e+00 1.000000e+00 1.224290e-03 +494 1.930000e+00 1.000000e+00 1.226282e-03 +495 1.940000e+00 1.000000e+00 1.228265e-03 +496 1.950000e+00 1.000000e+00 1.230238e-03 +497 1.960000e+00 1.000000e+00 1.232202e-03 +498 1.970000e+00 1.000000e+00 1.234157e-03 +499 1.980000e+00 1.000000e+00 1.236104e-03 +500 1.990000e+00 1.000000e+00 1.238041e-03 +501 2.000000e+00 1.000000e+00 1.239970e-03 +502 2.010000e+00 1.000000e+00 1.241891e-03 +503 2.020000e+00 1.000000e+00 1.243803e-03 +504 2.030000e+00 1.000000e+00 1.245707e-03 +505 2.040000e+00 1.000000e+00 1.247603e-03 +506 2.050000e+00 1.000000e+00 1.249491e-03 +507 2.060000e+00 1.000000e+00 1.251371e-03 +508 2.070000e+00 1.000000e+00 1.253243e-03 +509 2.080000e+00 1.000000e+00 1.255107e-03 +510 2.090000e+00 1.000000e+00 1.256964e-03 +511 2.100000e+00 1.000000e+00 1.258813e-03 +512 2.110000e+00 1.000000e+00 1.260654e-03 +513 2.120000e+00 1.000000e+00 1.262488e-03 +514 2.130000e+00 1.000000e+00 1.264314e-03 +515 2.140000e+00 1.000000e+00 1.266133e-03 +516 2.150000e+00 1.000000e+00 1.267945e-03 +517 2.160000e+00 1.000000e+00 1.269749e-03 +518 2.170000e+00 1.000000e+00 1.271546e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +519 2.180000e+00 1.000000e+00 1.273336e-03 +520 2.190000e+00 1.000000e+00 1.275118e-03 +521 2.200000e+00 1.000000e+00 1.276893e-03 +522 2.210000e+00 1.000000e+00 1.278661e-03 +523 2.220000e+00 1.000000e+00 1.280422e-03 +524 2.230000e+00 1.000000e+00 1.282176e-03 +525 2.240000e+00 1.000000e+00 1.283923e-03 +526 2.250000e+00 1.000000e+00 1.285662e-03 +527 2.260000e+00 1.000000e+00 1.287395e-03 +528 2.270000e+00 1.000000e+00 1.289121e-03 +529 2.280000e+00 1.000000e+00 1.290839e-03 +530 2.290000e+00 1.000000e+00 1.292551e-03 +531 2.300000e+00 1.000000e+00 1.294255e-03 +532 2.310000e+00 1.000000e+00 1.295953e-03 +533 2.320000e+00 1.000000e+00 1.297643e-03 +534 2.330000e+00 1.000000e+00 1.299327e-03 +535 2.340000e+00 1.000000e+00 1.301004e-03 +536 2.350000e+00 1.000000e+00 1.302673e-03 +537 2.360000e+00 1.000000e+00 1.304336e-03 +538 2.370000e+00 1.000000e+00 1.305992e-03 +539 2.380000e+00 1.000000e+00 1.307641e-03 +540 2.390000e+00 1.000000e+00 1.309284e-03 +541 2.400000e+00 1.000000e+00 1.310919e-03 +542 2.410000e+00 1.000000e+00 1.312548e-03 +543 2.420000e+00 1.000000e+00 1.314169e-03 +544 2.430000e+00 1.000000e+00 1.315784e-03 +545 2.440000e+00 1.000000e+00 1.317392e-03 +546 2.450000e+00 1.000000e+00 1.318994e-03 +547 2.460000e+00 1.000000e+00 1.320588e-03 +548 2.470000e+00 1.000000e+00 1.322176e-03 +549 2.480000e+00 1.000000e+00 1.323757e-03 +550 2.490000e+00 1.000000e+00 1.325331e-03 +551 2.500000e+00 1.000000e+00 1.326899e-03 +552 2.510000e+00 1.000000e+00 1.328460e-03 +553 2.520000e+00 1.000000e+00 1.330015e-03 +554 2.530000e+00 1.000000e+00 1.331562e-03 +555 2.540000e+00 1.000000e+00 1.333104e-03 +556 2.550000e+00 1.000000e+00 1.334638e-03 +557 2.560000e+00 1.000000e+00 1.336167e-03 +558 2.570000e+00 1.000000e+00 1.337688e-03 +559 2.580000e+00 1.000000e+00 1.339204e-03 +560 2.590000e+00 1.000000e+00 1.340713e-03 +561 2.600000e+00 1.000000e+00 1.342215e-03 +562 2.610000e+00 1.000000e+00 1.343712e-03 +563 2.620000e+00 1.000000e+00 1.345202e-03 +564 2.630000e+00 1.000000e+00 1.346686e-03 +565 2.640000e+00 1.000000e+00 1.348163e-03 +566 2.650000e+00 1.000000e+00 1.349635e-03 +567 2.660000e+00 1.000000e+00 1.351100e-03 +568 2.670000e+00 1.000000e+00 1.352560e-03 +569 2.680000e+00 1.000000e+00 1.354013e-03 +570 2.690000e+00 1.000000e+00 1.355461e-03 +571 2.700000e+00 1.000000e+00 1.356903e-03 +572 2.710000e+00 1.000000e+00 1.358339e-03 +573 2.720000e+00 1.000000e+00 1.359769e-03 +574 2.730000e+00 1.000000e+00 1.361194e-03 +575 2.740000e+00 1.000000e+00 1.362613e-03 +576 2.750000e+00 1.000000e+00 1.364027e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +577 2.760000e+00 1.000000e+00 1.365435e-03 +578 2.770000e+00 1.000000e+00 1.366838e-03 +579 2.780000e+00 1.000000e+00 1.368236e-03 +580 2.790000e+00 1.000000e+00 1.369629e-03 +581 2.800000e+00 1.000000e+00 1.371016e-03 +582 2.810000e+00 1.000000e+00 1.372399e-03 +583 2.820000e+00 1.000000e+00 1.373777e-03 +584 2.830000e+00 1.000000e+00 1.375149e-03 +585 2.840000e+00 1.000000e+00 1.376517e-03 +586 2.850000e+00 1.000000e+00 1.377881e-03 +587 2.860000e+00 1.000000e+00 1.379240e-03 +588 2.870000e+00 1.000000e+00 1.380594e-03 +589 2.880000e+00 1.000000e+00 1.381945e-03 +590 2.890000e+00 1.000000e+00 1.383291e-03 +591 2.900000e+00 1.000000e+00 1.384632e-03 +592 2.910000e+00 1.000000e+00 1.385970e-03 +593 2.920000e+00 1.000000e+00 1.387304e-03 +594 2.930000e+00 1.000000e+00 1.388635e-03 +595 2.940000e+00 1.000000e+00 1.389961e-03 +596 2.950000e+00 1.000000e+00 1.391284e-03 +597 2.960000e+00 1.000000e+00 1.392604e-03 +598 2.970000e+00 1.000000e+00 1.393920e-03 +599 2.980000e+00 1.000000e+00 1.395233e-03 +600 2.990000e+00 1.000000e+00 1.396543e-03 +601 3.000000e+00 1.000000e+00 1.397850e-03 +602 0.000000e+00 1.500000e+00 1.702997e-33 +603 1.000000e-02 1.500000e+00 4.579468e-05 +604 2.000000e-02 1.500000e+00 9.111651e-05 +605 3.000000e-02 1.500000e+00 1.359666e-04 +606 4.000000e-02 1.500000e+00 1.803462e-04 +607 5.000000e-02 1.500000e+00 2.242563e-04 +608 6.000000e-02 1.500000e+00 2.676981e-04 +609 7.000000e-02 1.500000e+00 3.106727e-04 +610 8.000000e-02 1.500000e+00 3.531813e-04 +611 9.000000e-02 1.500000e+00 3.952248e-04 +612 1.000000e-01 1.500000e+00 4.368045e-04 +613 1.100000e-01 1.500000e+00 4.779215e-04 +614 1.200000e-01 1.500000e+00 5.185768e-04 +615 1.300000e-01 1.500000e+00 5.587716e-04 +616 1.400000e-01 1.500000e+00 5.985069e-04 +617 1.500000e-01 1.500000e+00 6.377839e-04 +618 1.600000e-01 1.500000e+00 6.766036e-04 +619 1.700000e-01 1.500000e+00 7.149671e-04 +620 1.800000e-01 1.500000e+00 7.531028e-04 +621 1.900000e-01 1.500000e+00 7.905567e-04 +622 2.000000e-01 1.500000e+00 8.275575e-04 +623 2.100000e-01 1.500000e+00 8.641064e-04 +624 2.200000e-01 1.500000e+00 9.002045e-04 +625 2.300000e-01 1.500000e+00 9.358528e-04 +626 2.400000e-01 1.500000e+00 9.710523e-04 +627 2.500000e-01 1.500000e+00 1.005804e-03 +628 2.600000e-01 1.500000e+00 1.040109e-03 +629 2.700000e-01 1.500000e+00 1.073969e-03 +630 2.800000e-01 1.500000e+00 1.107384e-03 +631 2.900000e-01 1.500000e+00 1.140355e-03 +632 3.000000e-01 1.500000e+00 1.172884e-03 +633 3.100000e-01 1.500000e+00 1.204971e-03 +634 3.200000e-01 1.500000e+00 1.236617e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +635 3.300000e-01 1.500000e+00 1.267824e-03 +636 3.400000e-01 1.500000e+00 1.298593e-03 +637 3.500000e-01 1.500000e+00 1.328923e-03 +638 3.600000e-01 1.500000e+00 1.358817e-03 +639 3.700000e-01 1.500000e+00 1.388276e-03 +640 3.800000e-01 1.500000e+00 1.417299e-03 +641 3.900000e-01 1.500000e+00 1.445889e-03 +642 4.000000e-01 1.500000e+00 1.474046e-03 +643 4.100000e-01 1.500000e+00 1.501771e-03 +644 4.200000e-01 1.500000e+00 1.529065e-03 +645 4.300000e-01 1.500000e+00 1.555928e-03 +646 4.400000e-01 1.500000e+00 1.582362e-03 +647 4.500000e-01 1.500000e+00 1.608368e-03 +648 4.600000e-01 1.500000e+00 1.633946e-03 +649 4.700000e-01 1.500000e+00 1.659097e-03 +650 4.800000e-01 1.500000e+00 1.683822e-03 +651 4.900000e-01 1.500000e+00 1.708122e-03 +652 5.000000e-01 1.500000e+00 1.731998e-03 +653 5.100000e-01 1.500000e+00 1.755449e-03 +654 5.200000e-01 1.500000e+00 1.778477e-03 +655 5.300000e-01 1.500000e+00 1.801083e-03 +656 5.400000e-01 1.500000e+00 1.823267e-03 +657 5.500000e-01 1.500000e+00 1.845030e-03 +658 5.600000e-01 1.500000e+00 1.866371e-03 +659 5.700000e-01 1.500000e+00 1.887293e-03 +660 5.800000e-01 1.500000e+00 1.907794e-03 +661 5.900000e-01 1.500000e+00 1.927876e-03 +662 6.000000e-01 1.500000e+00 1.947538e-03 +663 6.100000e-01 1.500000e+00 1.966782e-03 +664 6.200000e-01 1.500000e+00 1.985606e-03 +665 6.300000e-01 1.500000e+00 2.004012e-03 +666 6.400000e-01 1.500000e+00 2.021998e-03 +667 6.500000e-01 1.500000e+00 2.039565e-03 +668 6.600000e-01 1.500000e+00 2.056713e-03 +669 6.700000e-01 1.500000e+00 2.073440e-03 +670 6.800000e-01 1.500000e+00 2.089748e-03 +671 6.900000e-01 1.500000e+00 2.105634e-03 +672 7.000000e-01 1.500000e+00 2.121097e-03 +673 7.100000e-01 1.500000e+00 2.136138e-03 +674 7.200000e-01 1.500000e+00 2.150755e-03 +675 7.300000e-01 1.500000e+00 2.164947e-03 +676 7.400000e-01 1.500000e+00 2.178711e-03 +677 7.500000e-01 1.500000e+00 2.192048e-03 +678 7.600000e-01 1.500000e+00 2.204955e-03 +679 7.700000e-01 1.500000e+00 2.217431e-03 +680 7.800000e-01 1.500000e+00 2.229475e-03 +681 7.900000e-01 1.500000e+00 2.241086e-03 +682 8.000000e-01 1.500000e+00 2.252262e-03 +683 8.100000e-01 1.500000e+00 2.263004e-03 +684 8.200000e-01 1.500000e+00 2.273313e-03 +685 8.300000e-01 1.500000e+00 2.283189e-03 +686 8.400000e-01 1.500000e+00 2.292635e-03 +687 8.500000e-01 1.500000e+00 2.301655e-03 +688 8.600000e-01 1.500000e+00 2.310254e-03 +689 8.700000e-01 1.500000e+00 2.318438e-03 +690 8.800000e-01 1.500000e+00 2.326216e-03 +691 8.900000e-01 1.500000e+00 2.333598e-03 +692 9.000000e-01 1.500000e+00 2.340596e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +693 9.100000e-01 1.500000e+00 2.347224e-03 +694 9.200000e-01 1.500000e+00 2.353495e-03 +695 9.300000e-01 1.500000e+00 2.359426e-03 +696 9.400000e-01 1.500000e+00 2.365034e-03 +697 9.500000e-01 1.500000e+00 2.370335e-03 +698 9.600000e-01 1.500000e+00 2.375348e-03 +699 9.700000e-01 1.500000e+00 2.380090e-03 +700 9.800000e-01 1.500000e+00 2.384579e-03 +701 9.900000e-01 1.500000e+00 2.388831e-03 +702 1.000000e+00 1.500000e+00 2.392864e-03 +703 1.010000e+00 1.500000e+00 2.396692e-03 +704 1.020000e+00 1.500000e+00 2.400330e-03 +705 1.030000e+00 1.500000e+00 2.403794e-03 +706 1.040000e+00 1.500000e+00 2.407095e-03 +707 1.050000e+00 1.500000e+00 2.410246e-03 +708 1.060000e+00 1.500000e+00 2.413258e-03 +709 1.070000e+00 1.500000e+00 2.416143e-03 +710 1.080000e+00 1.500000e+00 2.418908e-03 +711 1.090000e+00 1.500000e+00 2.421565e-03 +712 1.100000e+00 1.500000e+00 2.424120e-03 +713 1.110000e+00 1.500000e+00 2.426537e-03 +714 1.120000e+00 1.500000e+00 2.428918e-03 +715 1.130000e+00 1.500000e+00 2.431220e-03 +716 1.140000e+00 1.500000e+00 2.433449e-03 +717 1.150000e+00 1.500000e+00 2.435610e-03 +718 1.160000e+00 1.500000e+00 2.437708e-03 +719 1.170000e+00 1.500000e+00 2.439777e-03 +720 1.180000e+00 1.500000e+00 2.441763e-03 +721 1.190000e+00 1.500000e+00 2.443701e-03 +722 1.200000e+00 1.500000e+00 2.445575e-03 +723 1.210000e+00 1.500000e+00 2.447435e-03 +724 1.220000e+00 1.500000e+00 2.449265e-03 +725 1.230000e+00 1.500000e+00 2.451077e-03 +726 1.240000e+00 1.500000e+00 2.452884e-03 +727 1.250000e+00 1.500000e+00 2.454714e-03 +728 1.260000e+00 1.500000e+00 2.456659e-03 +729 1.270000e+00 1.500000e+00 2.459023e-03 +730 1.280000e+00 1.500000e+00 2.463133e-03 +731 1.290000e+00 1.500000e+00 2.470754e-03 +732 1.300000e+00 1.500000e+00 2.478547e-03 +733 1.310000e+00 1.500000e+00 2.485973e-03 +734 1.320000e+00 1.500000e+00 2.493229e-03 +735 1.330000e+00 1.500000e+00 2.500347e-03 +736 1.340000e+00 1.500000e+00 2.507335e-03 +737 1.350000e+00 1.500000e+00 2.514198e-03 +738 1.360000e+00 1.500000e+00 2.520939e-03 +739 1.370000e+00 1.500000e+00 2.527562e-03 +740 1.380000e+00 1.500000e+00 2.534073e-03 +741 1.390000e+00 1.500000e+00 2.540475e-03 +742 1.400000e+00 1.500000e+00 2.546774e-03 +743 1.410000e+00 1.500000e+00 2.552972e-03 +744 1.420000e+00 1.500000e+00 2.559073e-03 +745 1.430000e+00 1.500000e+00 2.565082e-03 +746 1.440000e+00 1.500000e+00 2.571048e-03 +747 1.450000e+00 1.500000e+00 2.577053e-03 +748 1.460000e+00 1.500000e+00 2.583017e-03 +749 1.470000e+00 1.500000e+00 2.588926e-03 +750 1.480000e+00 1.500000e+00 2.594771e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +751 1.490000e+00 1.500000e+00 2.600546e-03 +752 1.500000e+00 1.500000e+00 2.606246e-03 +753 1.510000e+00 1.500000e+00 2.611868e-03 +754 1.520000e+00 1.500000e+00 2.617412e-03 +755 1.530000e+00 1.500000e+00 2.622876e-03 +756 1.540000e+00 1.500000e+00 2.628261e-03 +757 1.550000e+00 1.500000e+00 2.633566e-03 +758 1.560000e+00 1.500000e+00 2.638793e-03 +759 1.570000e+00 1.500000e+00 2.643941e-03 +760 1.580000e+00 1.500000e+00 2.649013e-03 +761 1.590000e+00 1.500000e+00 2.654009e-03 +762 1.600000e+00 1.500000e+00 2.658931e-03 +763 1.610000e+00 1.500000e+00 2.663781e-03 +764 1.620000e+00 1.500000e+00 2.668558e-03 +765 1.630000e+00 1.500000e+00 2.673266e-03 +766 1.640000e+00 1.500000e+00 2.677906e-03 +767 1.650000e+00 1.500000e+00 2.682478e-03 +768 1.660000e+00 1.500000e+00 2.686984e-03 +769 1.670000e+00 1.500000e+00 2.691427e-03 +770 1.680000e+00 1.500000e+00 2.695807e-03 +771 1.690000e+00 1.500000e+00 2.700125e-03 +772 1.700000e+00 1.500000e+00 2.704384e-03 +773 1.710000e+00 1.500000e+00 2.708584e-03 +774 1.720000e+00 1.500000e+00 2.712727e-03 +775 1.730000e+00 1.500000e+00 2.716813e-03 +776 1.740000e+00 1.500000e+00 2.720845e-03 +777 1.750000e+00 1.500000e+00 2.724824e-03 +778 1.760000e+00 1.500000e+00 2.728750e-03 +779 1.770000e+00 1.500000e+00 2.732626e-03 +780 1.780000e+00 1.500000e+00 2.736451e-03 +781 1.790000e+00 1.500000e+00 2.740227e-03 +782 1.800000e+00 1.500000e+00 2.743956e-03 +783 1.810000e+00 1.500000e+00 2.747638e-03 +784 1.820000e+00 1.500000e+00 2.751274e-03 +785 1.830000e+00 1.500000e+00 2.754865e-03 +786 1.840000e+00 1.500000e+00 2.758413e-03 +787 1.850000e+00 1.500000e+00 2.761917e-03 +788 1.860000e+00 1.500000e+00 2.765380e-03 +789 1.870000e+00 1.500000e+00 2.768802e-03 +790 1.880000e+00 1.500000e+00 2.772184e-03 +791 1.890000e+00 1.500000e+00 2.775526e-03 +792 1.900000e+00 1.500000e+00 2.778830e-03 +793 1.910000e+00 1.500000e+00 2.782095e-03 +794 1.920000e+00 1.500000e+00 2.785324e-03 +795 1.930000e+00 1.500000e+00 2.788517e-03 +796 1.940000e+00 1.500000e+00 2.791674e-03 +797 1.950000e+00 1.500000e+00 2.794796e-03 +798 1.960000e+00 1.500000e+00 2.797884e-03 +799 1.970000e+00 1.500000e+00 2.800939e-03 +800 1.980000e+00 1.500000e+00 2.803960e-03 +801 1.990000e+00 1.500000e+00 2.806949e-03 +802 2.000000e+00 1.500000e+00 2.809907e-03 +803 2.010000e+00 1.500000e+00 2.812834e-03 +804 2.020000e+00 1.500000e+00 2.815730e-03 +805 2.030000e+00 1.500000e+00 2.818596e-03 +806 2.040000e+00 1.500000e+00 2.821432e-03 +807 2.050000e+00 1.500000e+00 2.824240e-03 +808 2.060000e+00 1.500000e+00 2.827019e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +809 2.070000e+00 1.500000e+00 2.829770e-03 +810 2.080000e+00 1.500000e+00 2.832494e-03 +811 2.090000e+00 1.500000e+00 2.835191e-03 +812 2.100000e+00 1.500000e+00 2.837861e-03 +813 2.110000e+00 1.500000e+00 2.840505e-03 +814 2.120000e+00 1.500000e+00 2.843123e-03 +815 2.130000e+00 1.500000e+00 2.845717e-03 +816 2.140000e+00 1.500000e+00 2.848285e-03 +817 2.150000e+00 1.500000e+00 2.850828e-03 +818 2.160000e+00 1.500000e+00 2.853348e-03 +819 2.170000e+00 1.500000e+00 2.855843e-03 +820 2.180000e+00 1.500000e+00 2.858316e-03 +821 2.190000e+00 1.500000e+00 2.860765e-03 +822 2.200000e+00 1.500000e+00 2.863191e-03 +823 2.210000e+00 1.500000e+00 2.865595e-03 +824 2.220000e+00 1.500000e+00 2.867976e-03 +825 2.230000e+00 1.500000e+00 2.870336e-03 +826 2.240000e+00 1.500000e+00 2.872675e-03 +827 2.250000e+00 1.500000e+00 2.874992e-03 +828 2.260000e+00 1.500000e+00 2.877288e-03 +829 2.270000e+00 1.500000e+00 2.879563e-03 +830 2.280000e+00 1.500000e+00 2.881818e-03 +831 2.290000e+00 1.500000e+00 2.884053e-03 +832 2.300000e+00 1.500000e+00 2.886267e-03 +833 2.310000e+00 1.500000e+00 2.888462e-03 +834 2.320000e+00 1.500000e+00 2.890638e-03 +835 2.330000e+00 1.500000e+00 2.892794e-03 +836 2.340000e+00 1.500000e+00 2.894932e-03 +837 2.350000e+00 1.500000e+00 2.897050e-03 +838 2.360000e+00 1.500000e+00 2.899150e-03 +839 2.370000e+00 1.500000e+00 2.901231e-03 +840 2.380000e+00 1.500000e+00 2.903295e-03 +841 2.390000e+00 1.500000e+00 2.905340e-03 +842 2.400000e+00 1.500000e+00 2.907367e-03 +843 2.410000e+00 1.500000e+00 2.909377e-03 +844 2.420000e+00 1.500000e+00 2.911370e-03 +845 2.430000e+00 1.500000e+00 2.913345e-03 +846 2.440000e+00 1.500000e+00 2.915303e-03 +847 2.450000e+00 1.500000e+00 2.917244e-03 +848 2.460000e+00 1.500000e+00 2.919169e-03 +849 2.470000e+00 1.500000e+00 2.921077e-03 +850 2.480000e+00 1.500000e+00 2.922968e-03 +851 2.490000e+00 1.500000e+00 2.924844e-03 +852 2.500000e+00 1.500000e+00 2.926703e-03 +853 2.510000e+00 1.500000e+00 2.928546e-03 +854 2.520000e+00 1.500000e+00 2.930374e-03 +855 2.530000e+00 1.500000e+00 2.932186e-03 +856 2.540000e+00 1.500000e+00 2.933982e-03 +857 2.550000e+00 1.500000e+00 2.935763e-03 +858 2.560000e+00 1.500000e+00 2.937529e-03 +859 2.570000e+00 1.500000e+00 2.939280e-03 +860 2.580000e+00 1.500000e+00 2.941016e-03 +861 2.590000e+00 1.500000e+00 2.942738e-03 +862 2.600000e+00 1.500000e+00 2.944444e-03 +863 2.610000e+00 1.500000e+00 2.946137e-03 +864 2.620000e+00 1.500000e+00 2.947815e-03 +865 2.630000e+00 1.500000e+00 2.949479e-03 +866 2.640000e+00 1.500000e+00 2.951129e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +867 2.650000e+00 1.500000e+00 2.952765e-03 +868 2.660000e+00 1.500000e+00 2.954388e-03 +869 2.670000e+00 1.500000e+00 2.955997e-03 +870 2.680000e+00 1.500000e+00 2.957593e-03 +871 2.690000e+00 1.500000e+00 2.959175e-03 +872 2.700000e+00 1.500000e+00 2.960745e-03 +873 2.710000e+00 1.500000e+00 2.962301e-03 +874 2.720000e+00 1.500000e+00 2.963845e-03 +875 2.730000e+00 1.500000e+00 2.965376e-03 +876 2.740000e+00 1.500000e+00 2.966895e-03 +877 2.750000e+00 1.500000e+00 2.968401e-03 +878 2.760000e+00 1.500000e+00 2.969896e-03 +879 2.770000e+00 1.500000e+00 2.971378e-03 +880 2.780000e+00 1.500000e+00 2.972849e-03 +881 2.790000e+00 1.500000e+00 2.974308e-03 +882 2.800000e+00 1.500000e+00 2.975755e-03 +883 2.810000e+00 1.500000e+00 2.977192e-03 +884 2.820000e+00 1.500000e+00 2.978617e-03 +885 2.830000e+00 1.500000e+00 2.980031e-03 +886 2.840000e+00 1.500000e+00 2.981435e-03 +887 2.850000e+00 1.500000e+00 2.982828e-03 +888 2.860000e+00 1.500000e+00 2.984211e-03 +889 2.870000e+00 1.500000e+00 2.985584e-03 +890 2.880000e+00 1.500000e+00 2.986947e-03 +891 2.890000e+00 1.500000e+00 2.988299e-03 +892 2.900000e+00 1.500000e+00 2.989643e-03 +893 2.910000e+00 1.500000e+00 2.990977e-03 +894 2.920000e+00 1.500000e+00 2.992302e-03 +895 2.930000e+00 1.500000e+00 2.993618e-03 +896 2.940000e+00 1.500000e+00 2.994925e-03 +897 2.950000e+00 1.500000e+00 2.996224e-03 +898 2.960000e+00 1.500000e+00 2.997514e-03 +899 2.970000e+00 1.500000e+00 2.998797e-03 +900 2.980000e+00 1.500000e+00 3.000071e-03 +901 2.990000e+00 1.500000e+00 3.001338e-03 +902 3.000000e+00 1.500000e+00 3.002598e-03 +903 0.000000e+00 2.000000e+00 -6.516941e-35 +904 1.000000e-02 2.000000e+00 5.447069e-05 +905 2.000000e-02 2.000000e+00 1.085482e-04 +906 3.000000e-02 2.000000e+00 1.622332e-04 +907 4.000000e-02 2.000000e+00 2.155265e-04 +908 5.000000e-02 2.000000e+00 2.684288e-04 +909 6.000000e-02 2.000000e+00 3.209408e-04 +910 7.000000e-02 2.000000e+00 3.730632e-04 +911 8.000000e-02 2.000000e+00 4.247969e-04 +912 9.000000e-02 2.000000e+00 4.761425e-04 +913 1.000000e-01 2.000000e+00 5.271007e-04 +914 1.100000e-01 2.000000e+00 5.776722e-04 +915 1.200000e-01 2.000000e+00 6.278579e-04 +916 1.300000e-01 2.000000e+00 6.776583e-04 +917 1.400000e-01 2.000000e+00 7.270742e-04 +918 1.500000e-01 2.000000e+00 7.761064e-04 +919 1.600000e-01 2.000000e+00 8.247555e-04 +920 1.700000e-01 2.000000e+00 8.730222e-04 +921 1.800000e-01 2.000000e+00 9.210980e-04 +922 1.900000e-01 2.000000e+00 9.686018e-04 +923 2.000000e-01 2.000000e+00 1.015725e-03 +924 2.100000e-01 2.000000e+00 1.062469e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +925 2.200000e-01 2.000000e+00 1.108835e-03 +926 2.300000e-01 2.000000e+00 1.154822e-03 +927 2.400000e-01 2.000000e+00 1.200431e-03 +928 2.500000e-01 2.000000e+00 1.245664e-03 +929 2.600000e-01 2.000000e+00 1.290521e-03 +930 2.700000e-01 2.000000e+00 1.335002e-03 +931 2.800000e-01 2.000000e+00 1.379109e-03 +932 2.900000e-01 2.000000e+00 1.422842e-03 +933 3.000000e-01 2.000000e+00 1.466201e-03 +934 3.100000e-01 2.000000e+00 1.509188e-03 +935 3.200000e-01 2.000000e+00 1.551802e-03 +936 3.300000e-01 2.000000e+00 1.594046e-03 +937 3.400000e-01 2.000000e+00 1.635919e-03 +938 3.500000e-01 2.000000e+00 1.677421e-03 +939 3.600000e-01 2.000000e+00 1.718555e-03 +940 3.700000e-01 2.000000e+00 1.759320e-03 +941 3.800000e-01 2.000000e+00 1.799716e-03 +942 3.900000e-01 2.000000e+00 1.839746e-03 +943 4.000000e-01 2.000000e+00 1.879408e-03 +944 4.100000e-01 2.000000e+00 1.918705e-03 +945 4.200000e-01 2.000000e+00 1.957636e-03 +946 4.300000e-01 2.000000e+00 1.996203e-03 +947 4.400000e-01 2.000000e+00 2.034405e-03 +948 4.500000e-01 2.000000e+00 2.072244e-03 +949 4.600000e-01 2.000000e+00 2.109720e-03 +950 4.700000e-01 2.000000e+00 2.146834e-03 +951 4.800000e-01 2.000000e+00 2.183586e-03 +952 4.900000e-01 2.000000e+00 2.219977e-03 +953 5.000000e-01 2.000000e+00 2.256007e-03 +954 5.100000e-01 2.000000e+00 2.291678e-03 +955 5.200000e-01 2.000000e+00 2.326990e-03 +956 5.300000e-01 2.000000e+00 2.361942e-03 +957 5.400000e-01 2.000000e+00 2.396537e-03 +958 5.500000e-01 2.000000e+00 2.430775e-03 +959 5.600000e-01 2.000000e+00 2.464655e-03 +960 5.700000e-01 2.000000e+00 2.498179e-03 +961 5.800000e-01 2.000000e+00 2.531348e-03 +962 5.900000e-01 2.000000e+00 2.564161e-03 +963 6.000000e-01 2.000000e+00 2.596620e-03 +964 6.100000e-01 2.000000e+00 2.628724e-03 +965 6.200000e-01 2.000000e+00 2.660475e-03 +966 6.300000e-01 2.000000e+00 2.691873e-03 +967 6.400000e-01 2.000000e+00 2.722918e-03 +968 6.500000e-01 2.000000e+00 2.753611e-03 +969 6.600000e-01 2.000000e+00 2.783952e-03 +970 6.700000e-01 2.000000e+00 2.813942e-03 +971 6.800000e-01 2.000000e+00 2.843581e-03 +972 6.900000e-01 2.000000e+00 2.872871e-03 +973 7.000000e-01 2.000000e+00 2.901810e-03 +974 7.100000e-01 2.000000e+00 2.930400e-03 +975 7.200000e-01 2.000000e+00 2.958640e-03 +976 7.300000e-01 2.000000e+00 2.986532e-03 +977 7.400000e-01 2.000000e+00 3.014076e-03 +978 7.500000e-01 2.000000e+00 3.041271e-03 +979 7.600000e-01 2.000000e+00 3.068119e-03 +980 7.700000e-01 2.000000e+00 3.094619e-03 +981 7.800000e-01 2.000000e+00 3.120772e-03 +982 7.900000e-01 2.000000e+00 3.146577e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +983 8.000000e-01 2.000000e+00 3.172036e-03 +984 8.100000e-01 2.000000e+00 3.197147e-03 +985 8.200000e-01 2.000000e+00 3.221912e-03 +986 8.300000e-01 2.000000e+00 3.246330e-03 +987 8.400000e-01 2.000000e+00 3.270401e-03 +988 8.500000e-01 2.000000e+00 3.294125e-03 +989 8.600000e-01 2.000000e+00 3.317502e-03 +990 8.700000e-01 2.000000e+00 3.340531e-03 +991 8.800000e-01 2.000000e+00 3.363213e-03 +992 8.900000e-01 2.000000e+00 3.385546e-03 +993 9.000000e-01 2.000000e+00 3.407532e-03 +994 9.100000e-01 2.000000e+00 3.429167e-03 +995 9.200000e-01 2.000000e+00 3.450453e-03 +996 9.300000e-01 2.000000e+00 3.471389e-03 +997 9.400000e-01 2.000000e+00 3.491972e-03 +998 9.500000e-01 2.000000e+00 3.512203e-03 +999 9.600000e-01 2.000000e+00 3.532080e-03 +1000 9.700000e-01 2.000000e+00 3.551602e-03 +1001 9.800000e-01 2.000000e+00 3.570767e-03 +1002 9.900000e-01 2.000000e+00 3.589573e-03 +1003 1.000000e+00 2.000000e+00 3.608019e-03 +1004 1.010000e+00 2.000000e+00 3.626102e-03 +1005 1.020000e+00 2.000000e+00 3.643820e-03 +1006 1.030000e+00 2.000000e+00 3.661171e-03 +1007 1.040000e+00 2.000000e+00 3.678151e-03 +1008 1.050000e+00 2.000000e+00 3.694758e-03 +1009 1.060000e+00 2.000000e+00 3.710988e-03 +1010 1.070000e+00 2.000000e+00 3.726838e-03 +1011 1.080000e+00 2.000000e+00 3.742305e-03 +1012 1.090000e+00 2.000000e+00 3.757384e-03 +1013 1.100000e+00 2.000000e+00 3.772071e-03 +1014 1.110000e+00 2.000000e+00 3.786364e-03 +1015 1.120000e+00 2.000000e+00 3.800257e-03 +1016 1.130000e+00 2.000000e+00 3.813746e-03 +1017 1.140000e+00 2.000000e+00 3.826829e-03 +1018 1.150000e+00 2.000000e+00 3.839502e-03 +1019 1.160000e+00 2.000000e+00 3.851761e-03 +1020 1.170000e+00 2.000000e+00 3.863605e-03 +1021 1.180000e+00 2.000000e+00 3.875032e-03 +1022 1.190000e+00 2.000000e+00 3.886042e-03 +1023 1.200000e+00 2.000000e+00 3.896635e-03 +1024 1.210000e+00 2.000000e+00 3.906813e-03 +1025 1.220000e+00 2.000000e+00 3.916578e-03 +1026 1.230000e+00 2.000000e+00 3.925936e-03 +1027 1.240000e+00 2.000000e+00 3.934893e-03 +1028 1.250000e+00 2.000000e+00 3.943455e-03 +1029 1.260000e+00 2.000000e+00 3.951632e-03 +1030 1.270000e+00 2.000000e+00 3.959434e-03 +1031 1.280000e+00 2.000000e+00 3.966873e-03 +1032 1.290000e+00 2.000000e+00 3.973961e-03 +1033 1.300000e+00 2.000000e+00 3.980711e-03 +1034 1.310000e+00 2.000000e+00 3.986981e-03 +1035 1.320000e+00 2.000000e+00 3.993113e-03 +1036 1.330000e+00 2.000000e+00 3.998952e-03 +1037 1.340000e+00 2.000000e+00 4.004515e-03 +1038 1.350000e+00 2.000000e+00 4.009816e-03 +1039 1.360000e+00 2.000000e+00 4.014992e-03 +1040 1.370000e+00 2.000000e+00 4.019808e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1041 1.380000e+00 2.000000e+00 4.024408e-03 +1042 1.390000e+00 2.000000e+00 4.028805e-03 +1043 1.400000e+00 2.000000e+00 4.033014e-03 +1044 1.410000e+00 2.000000e+00 4.037051e-03 +1045 1.420000e+00 2.000000e+00 4.040932e-03 +1046 1.430000e+00 2.000000e+00 4.044676e-03 +1047 1.440000e+00 2.000000e+00 4.048311e-03 +1048 1.450000e+00 2.000000e+00 4.051887e-03 +1049 1.460000e+00 2.000000e+00 4.055525e-03 +1050 1.470000e+00 2.000000e+00 4.059638e-03 +1051 1.480000e+00 2.000000e+00 4.065967e-03 +1052 1.490000e+00 2.000000e+00 4.075835e-03 +1053 1.500000e+00 2.000000e+00 4.085587e-03 +1054 1.510000e+00 2.000000e+00 4.094973e-03 +1055 1.520000e+00 2.000000e+00 4.104168e-03 +1056 1.530000e+00 2.000000e+00 4.113201e-03 +1057 1.540000e+00 2.000000e+00 4.122078e-03 +1058 1.550000e+00 2.000000e+00 4.130803e-03 +1059 1.560000e+00 2.000000e+00 4.139383e-03 +1060 1.570000e+00 2.000000e+00 4.147822e-03 +1061 1.580000e+00 2.000000e+00 4.156125e-03 +1062 1.590000e+00 2.000000e+00 4.164298e-03 +1063 1.600000e+00 2.000000e+00 4.172345e-03 +1064 1.610000e+00 2.000000e+00 4.180271e-03 +1065 1.620000e+00 2.000000e+00 4.188080e-03 +1066 1.630000e+00 2.000000e+00 4.195777e-03 +1067 1.640000e+00 2.000000e+00 4.203450e-03 +1068 1.650000e+00 2.000000e+00 4.211142e-03 +1069 1.660000e+00 2.000000e+00 4.218776e-03 +1070 1.670000e+00 2.000000e+00 4.226338e-03 +1071 1.680000e+00 2.000000e+00 4.233818e-03 +1072 1.690000e+00 2.000000e+00 4.241210e-03 +1073 1.700000e+00 2.000000e+00 4.248508e-03 +1074 1.710000e+00 2.000000e+00 4.255710e-03 +1075 1.720000e+00 2.000000e+00 4.262814e-03 +1076 1.730000e+00 2.000000e+00 4.269819e-03 +1077 1.740000e+00 2.000000e+00 4.276725e-03 +1078 1.750000e+00 2.000000e+00 4.283534e-03 +1079 1.760000e+00 2.000000e+00 4.290244e-03 +1080 1.770000e+00 2.000000e+00 4.296858e-03 +1081 1.780000e+00 2.000000e+00 4.303377e-03 +1082 1.790000e+00 2.000000e+00 4.309802e-03 +1083 1.800000e+00 2.000000e+00 4.316135e-03 +1084 1.810000e+00 2.000000e+00 4.322377e-03 +1085 1.820000e+00 2.000000e+00 4.328530e-03 +1086 1.830000e+00 2.000000e+00 4.334595e-03 +1087 1.840000e+00 2.000000e+00 4.340575e-03 +1088 1.850000e+00 2.000000e+00 4.346471e-03 +1089 1.860000e+00 2.000000e+00 4.352284e-03 +1090 1.870000e+00 2.000000e+00 4.358017e-03 +1091 1.880000e+00 2.000000e+00 4.363670e-03 +1092 1.890000e+00 2.000000e+00 4.369247e-03 +1093 1.900000e+00 2.000000e+00 4.374747e-03 +1094 1.910000e+00 2.000000e+00 4.380173e-03 +1095 1.920000e+00 2.000000e+00 4.385527e-03 +1096 1.930000e+00 2.000000e+00 4.390809e-03 +1097 1.940000e+00 2.000000e+00 4.396022e-03 +1098 1.950000e+00 2.000000e+00 4.401166e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1099 1.960000e+00 2.000000e+00 4.406244e-03 +1100 1.970000e+00 2.000000e+00 4.411256e-03 +1101 1.980000e+00 2.000000e+00 4.416205e-03 +1102 1.990000e+00 2.000000e+00 4.421090e-03 +1103 2.000000e+00 2.000000e+00 4.425914e-03 +1104 2.010000e+00 2.000000e+00 4.430678e-03 +1105 2.020000e+00 2.000000e+00 4.435382e-03 +1106 2.030000e+00 2.000000e+00 4.440029e-03 +1107 2.040000e+00 2.000000e+00 4.444619e-03 +1108 2.050000e+00 2.000000e+00 4.449154e-03 +1109 2.060000e+00 2.000000e+00 4.453634e-03 +1110 2.070000e+00 2.000000e+00 4.458060e-03 +1111 2.080000e+00 2.000000e+00 4.462435e-03 +1112 2.090000e+00 2.000000e+00 4.466758e-03 +1113 2.100000e+00 2.000000e+00 4.471030e-03 +1114 2.110000e+00 2.000000e+00 4.475253e-03 +1115 2.120000e+00 2.000000e+00 4.479428e-03 +1116 2.130000e+00 2.000000e+00 4.483554e-03 +1117 2.140000e+00 2.000000e+00 4.487635e-03 +1118 2.150000e+00 2.000000e+00 4.491669e-03 +1119 2.160000e+00 2.000000e+00 4.495658e-03 +1120 2.170000e+00 2.000000e+00 4.499603e-03 +1121 2.180000e+00 2.000000e+00 4.503504e-03 +1122 2.190000e+00 2.000000e+00 4.507363e-03 +1123 2.200000e+00 2.000000e+00 4.511180e-03 +1124 2.210000e+00 2.000000e+00 4.514955e-03 +1125 2.220000e+00 2.000000e+00 4.518690e-03 +1126 2.230000e+00 2.000000e+00 4.522385e-03 +1127 2.240000e+00 2.000000e+00 4.526041e-03 +1128 2.250000e+00 2.000000e+00 4.529658e-03 +1129 2.260000e+00 2.000000e+00 4.533237e-03 +1130 2.270000e+00 2.000000e+00 4.536779e-03 +1131 2.280000e+00 2.000000e+00 4.540284e-03 +1132 2.290000e+00 2.000000e+00 4.543753e-03 +1133 2.300000e+00 2.000000e+00 4.547187e-03 +1134 2.310000e+00 2.000000e+00 4.550585e-03 +1135 2.320000e+00 2.000000e+00 4.553949e-03 +1136 2.330000e+00 2.000000e+00 4.557278e-03 +1137 2.340000e+00 2.000000e+00 4.560574e-03 +1138 2.350000e+00 2.000000e+00 4.563837e-03 +1139 2.360000e+00 2.000000e+00 4.567068e-03 +1140 2.370000e+00 2.000000e+00 4.570266e-03 +1141 2.380000e+00 2.000000e+00 4.573432e-03 +1142 2.390000e+00 2.000000e+00 4.576568e-03 +1143 2.400000e+00 2.000000e+00 4.579672e-03 +1144 2.410000e+00 2.000000e+00 4.582746e-03 +1145 2.420000e+00 2.000000e+00 4.585790e-03 +1146 2.430000e+00 2.000000e+00 4.588804e-03 +1147 2.440000e+00 2.000000e+00 4.591789e-03 +1148 2.450000e+00 2.000000e+00 4.594745e-03 +1149 2.460000e+00 2.000000e+00 4.597673e-03 +1150 2.470000e+00 2.000000e+00 4.600572e-03 +1151 2.480000e+00 2.000000e+00 4.603443e-03 +1152 2.490000e+00 2.000000e+00 4.606287e-03 +1153 2.500000e+00 2.000000e+00 4.609104e-03 +1154 2.510000e+00 2.000000e+00 4.611893e-03 +1155 2.520000e+00 2.000000e+00 4.614656e-03 +1156 2.530000e+00 2.000000e+00 4.617393e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1157 2.540000e+00 2.000000e+00 4.620103e-03 +1158 2.550000e+00 2.000000e+00 4.622788e-03 +1159 2.560000e+00 2.000000e+00 4.625447e-03 +1160 2.570000e+00 2.000000e+00 4.628082e-03 +1161 2.580000e+00 2.000000e+00 4.630691e-03 +1162 2.590000e+00 2.000000e+00 4.633275e-03 +1163 2.600000e+00 2.000000e+00 4.635835e-03 +1164 2.610000e+00 2.000000e+00 4.638371e-03 +1165 2.620000e+00 2.000000e+00 4.640883e-03 +1166 2.630000e+00 2.000000e+00 4.643371e-03 +1167 2.640000e+00 2.000000e+00 4.645835e-03 +1168 2.650000e+00 2.000000e+00 4.648277e-03 +1169 2.660000e+00 2.000000e+00 4.650695e-03 +1170 2.670000e+00 2.000000e+00 4.653090e-03 +1171 2.680000e+00 2.000000e+00 4.655463e-03 +1172 2.690000e+00 2.000000e+00 4.657814e-03 +1173 2.700000e+00 2.000000e+00 4.660142e-03 +1174 2.710000e+00 2.000000e+00 4.662449e-03 +1175 2.720000e+00 2.000000e+00 4.664734e-03 +1176 2.730000e+00 2.000000e+00 4.666997e-03 +1177 2.740000e+00 2.000000e+00 4.669239e-03 +1178 2.750000e+00 2.000000e+00 4.671460e-03 +1179 2.760000e+00 2.000000e+00 4.673660e-03 +1180 2.770000e+00 2.000000e+00 4.675840e-03 +1181 2.780000e+00 2.000000e+00 4.677999e-03 +1182 2.790000e+00 2.000000e+00 4.680138e-03 +1183 2.800000e+00 2.000000e+00 4.682257e-03 +1184 2.810000e+00 2.000000e+00 4.684356e-03 +1185 2.820000e+00 2.000000e+00 4.686435e-03 +1186 2.830000e+00 2.000000e+00 4.688495e-03 +1187 2.840000e+00 2.000000e+00 4.690536e-03 +1188 2.850000e+00 2.000000e+00 4.692558e-03 +1189 2.860000e+00 2.000000e+00 4.694561e-03 +1190 2.870000e+00 2.000000e+00 4.696546e-03 +1191 2.880000e+00 2.000000e+00 4.698513e-03 +1192 2.890000e+00 2.000000e+00 4.700461e-03 +1193 2.900000e+00 2.000000e+00 4.702392e-03 +1194 2.910000e+00 2.000000e+00 4.704305e-03 +1195 2.920000e+00 2.000000e+00 4.706201e-03 +1196 2.930000e+00 2.000000e+00 4.708080e-03 +1197 2.940000e+00 2.000000e+00 4.709942e-03 +1198 2.950000e+00 2.000000e+00 4.711787e-03 +1199 2.960000e+00 2.000000e+00 4.713616e-03 +1200 2.970000e+00 2.000000e+00 4.715429e-03 +1201 2.980000e+00 2.000000e+00 4.717226e-03 +1202 2.990000e+00 2.000000e+00 4.719007e-03 +1203 3.000000e+00 2.000000e+00 4.720774e-03 +1204 0.000000e+00 2.500000e+00 6.421455e-33 +1205 1.000000e-02 2.500000e+00 5.946712e-05 +1206 2.000000e-02 2.500000e+00 1.186031e-04 +1207 3.000000e-02 2.500000e+00 1.774084e-04 +1208 4.000000e-02 2.500000e+00 2.358836e-04 +1209 5.000000e-02 2.500000e+00 2.940291e-04 +1210 6.000000e-02 2.500000e+00 3.518455e-04 +1211 7.000000e-02 2.500000e+00 4.093333e-04 +1212 8.000000e-02 2.500000e+00 4.664929e-04 +1213 9.000000e-02 2.500000e+00 5.233249e-04 +1214 1.000000e-01 2.500000e+00 5.798297e-04 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1215 1.100000e-01 2.500000e+00 6.360079e-04 +1216 1.200000e-01 2.500000e+00 6.918600e-04 +1217 1.300000e-01 2.500000e+00 7.473864e-04 +1218 1.400000e-01 2.500000e+00 8.025876e-04 +1219 1.500000e-01 2.500000e+00 8.574642e-04 +1220 1.600000e-01 2.500000e+00 9.120167e-04 +1221 1.700000e-01 2.500000e+00 9.662454e-04 +1222 1.800000e-01 2.500000e+00 1.020312e-03 +1223 1.900000e-01 2.500000e+00 1.073895e-03 +1224 2.000000e-01 2.500000e+00 1.127156e-03 +1225 2.100000e-01 2.500000e+00 1.180094e-03 +1226 2.200000e-01 2.500000e+00 1.232712e-03 +1227 2.300000e-01 2.500000e+00 1.285008e-03 +1228 2.400000e-01 2.500000e+00 1.336985e-03 +1229 2.500000e-01 2.500000e+00 1.388641e-03 +1230 2.600000e-01 2.500000e+00 1.439979e-03 +1231 2.700000e-01 2.500000e+00 1.490997e-03 +1232 2.800000e-01 2.500000e+00 1.541698e-03 +1233 2.900000e-01 2.500000e+00 1.592080e-03 +1234 3.000000e-01 2.500000e+00 1.642145e-03 +1235 3.100000e-01 2.500000e+00 1.691893e-03 +1236 3.200000e-01 2.500000e+00 1.741324e-03 +1237 3.300000e-01 2.500000e+00 1.790440e-03 +1238 3.400000e-01 2.500000e+00 1.839240e-03 +1239 3.500000e-01 2.500000e+00 1.887725e-03 +1240 3.600000e-01 2.500000e+00 1.935895e-03 +1241 3.700000e-01 2.500000e+00 1.983752e-03 +1242 3.800000e-01 2.500000e+00 2.031294e-03 +1243 3.900000e-01 2.500000e+00 2.078524e-03 +1244 4.000000e-01 2.500000e+00 2.125441e-03 +1245 4.100000e-01 2.500000e+00 2.172045e-03 +1246 4.200000e-01 2.500000e+00 2.218338e-03 +1247 4.300000e-01 2.500000e+00 2.264320e-03 +1248 4.400000e-01 2.500000e+00 2.309990e-03 +1249 4.500000e-01 2.500000e+00 2.355350e-03 +1250 4.600000e-01 2.500000e+00 2.400401e-03 +1251 4.700000e-01 2.500000e+00 2.445141e-03 +1252 4.800000e-01 2.500000e+00 2.489573e-03 +1253 4.900000e-01 2.500000e+00 2.533696e-03 +1254 5.000000e-01 2.500000e+00 2.577511e-03 +1255 5.100000e-01 2.500000e+00 2.621018e-03 +1256 5.200000e-01 2.500000e+00 2.664218e-03 +1257 5.300000e-01 2.500000e+00 2.707111e-03 +1258 5.400000e-01 2.500000e+00 2.749697e-03 +1259 5.500000e-01 2.500000e+00 2.791978e-03 +1260 5.600000e-01 2.500000e+00 2.833953e-03 +1261 5.700000e-01 2.500000e+00 2.875623e-03 +1262 5.800000e-01 2.500000e+00 2.916988e-03 +1263 5.900000e-01 2.500000e+00 2.958049e-03 +1264 6.000000e-01 2.500000e+00 2.998806e-03 +1265 6.100000e-01 2.500000e+00 3.039260e-03 +1266 6.200000e-01 2.500000e+00 3.079411e-03 +1267 6.300000e-01 2.500000e+00 3.119259e-03 +1268 6.400000e-01 2.500000e+00 3.158806e-03 +1269 6.500000e-01 2.500000e+00 3.198050e-03 +1270 6.600000e-01 2.500000e+00 3.236993e-03 +1271 6.700000e-01 2.500000e+00 3.275635e-03 +1272 6.800000e-01 2.500000e+00 3.313977e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1273 6.900000e-01 2.500000e+00 3.352019e-03 +1274 7.000000e-01 2.500000e+00 3.389761e-03 +1275 7.100000e-01 2.500000e+00 3.427204e-03 +1276 7.200000e-01 2.500000e+00 3.464348e-03 +1277 7.300000e-01 2.500000e+00 3.501193e-03 +1278 7.400000e-01 2.500000e+00 3.537740e-03 +1279 7.500000e-01 2.500000e+00 3.573989e-03 +1280 7.600000e-01 2.500000e+00 3.609941e-03 +1281 7.700000e-01 2.500000e+00 3.645597e-03 +1282 7.800000e-01 2.500000e+00 3.680955e-03 +1283 7.900000e-01 2.500000e+00 3.716017e-03 +1284 8.000000e-01 2.500000e+00 3.750783e-03 +1285 8.100000e-01 2.500000e+00 3.785254e-03 +1286 8.200000e-01 2.500000e+00 3.819429e-03 +1287 8.300000e-01 2.500000e+00 3.853310e-03 +1288 8.400000e-01 2.500000e+00 3.886896e-03 +1289 8.500000e-01 2.500000e+00 3.920187e-03 +1290 8.600000e-01 2.500000e+00 3.953185e-03 +1291 8.700000e-01 2.500000e+00 3.985890e-03 +1292 8.800000e-01 2.500000e+00 4.018300e-03 +1293 8.900000e-01 2.500000e+00 4.050418e-03 +1294 9.000000e-01 2.500000e+00 4.082243e-03 +1295 9.100000e-01 2.500000e+00 4.113776e-03 +1296 9.200000e-01 2.500000e+00 4.145017e-03 +1297 9.300000e-01 2.500000e+00 4.175965e-03 +1298 9.400000e-01 2.500000e+00 4.206622e-03 +1299 9.500000e-01 2.500000e+00 4.236987e-03 +1300 9.600000e-01 2.500000e+00 4.267061e-03 +1301 9.700000e-01 2.500000e+00 4.296844e-03 +1302 9.800000e-01 2.500000e+00 4.326336e-03 +1303 9.900000e-01 2.500000e+00 4.355537e-03 +1304 1.000000e+00 2.500000e+00 4.384448e-03 +1305 1.010000e+00 2.500000e+00 4.413068e-03 +1306 1.020000e+00 2.500000e+00 4.441398e-03 +1307 1.030000e+00 2.500000e+00 4.469437e-03 +1308 1.040000e+00 2.500000e+00 4.497186e-03 +1309 1.050000e+00 2.500000e+00 4.524645e-03 +1310 1.060000e+00 2.500000e+00 4.551814e-03 +1311 1.070000e+00 2.500000e+00 4.578693e-03 +1312 1.080000e+00 2.500000e+00 4.605281e-03 +1313 1.090000e+00 2.500000e+00 4.631578e-03 +1314 1.100000e+00 2.500000e+00 4.657585e-03 +1315 1.110000e+00 2.500000e+00 4.683302e-03 +1316 1.120000e+00 2.500000e+00 4.708727e-03 +1317 1.130000e+00 2.500000e+00 4.733861e-03 +1318 1.140000e+00 2.500000e+00 4.758703e-03 +1319 1.150000e+00 2.500000e+00 4.783253e-03 +1320 1.160000e+00 2.500000e+00 4.807511e-03 +1321 1.170000e+00 2.500000e+00 4.831476e-03 +1322 1.180000e+00 2.500000e+00 4.855147e-03 +1323 1.190000e+00 2.500000e+00 4.878524e-03 +1324 1.200000e+00 2.500000e+00 4.901606e-03 +1325 1.210000e+00 2.500000e+00 4.924392e-03 +1326 1.220000e+00 2.500000e+00 4.946881e-03 +1327 1.230000e+00 2.500000e+00 4.969073e-03 +1328 1.240000e+00 2.500000e+00 4.990965e-03 +1329 1.250000e+00 2.500000e+00 5.012557e-03 +1330 1.260000e+00 2.500000e+00 5.033847e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1331 1.270000e+00 2.500000e+00 5.054834e-03 +1332 1.280000e+00 2.500000e+00 5.075516e-03 +1333 1.290000e+00 2.500000e+00 5.095890e-03 +1334 1.300000e+00 2.500000e+00 5.115956e-03 +1335 1.310000e+00 2.500000e+00 5.135711e-03 +1336 1.320000e+00 2.500000e+00 5.155152e-03 +1337 1.330000e+00 2.500000e+00 5.174276e-03 +1338 1.340000e+00 2.500000e+00 5.193082e-03 +1339 1.350000e+00 2.500000e+00 5.211565e-03 +1340 1.360000e+00 2.500000e+00 5.229723e-03 +1341 1.370000e+00 2.500000e+00 5.247552e-03 +1342 1.380000e+00 2.500000e+00 5.265048e-03 +1343 1.390000e+00 2.500000e+00 5.282208e-03 +1344 1.400000e+00 2.500000e+00 5.299027e-03 +1345 1.410000e+00 2.500000e+00 5.315501e-03 +1346 1.420000e+00 2.500000e+00 5.331625e-03 +1347 1.430000e+00 2.500000e+00 5.347395e-03 +1348 1.440000e+00 2.500000e+00 5.362806e-03 +1349 1.450000e+00 2.500000e+00 5.377853e-03 +1350 1.460000e+00 2.500000e+00 5.392532e-03 +1351 1.470000e+00 2.500000e+00 5.406838e-03 +1352 1.480000e+00 2.500000e+00 5.420766e-03 +1353 1.490000e+00 2.500000e+00 5.434313e-03 +1354 1.500000e+00 2.500000e+00 5.447474e-03 +1355 1.510000e+00 2.500000e+00 5.460247e-03 +1356 1.520000e+00 2.500000e+00 5.472628e-03 +1357 1.530000e+00 2.500000e+00 5.484420e-03 +1358 1.540000e+00 2.500000e+00 5.496019e-03 +1359 1.550000e+00 2.500000e+00 5.507226e-03 +1360 1.560000e+00 2.500000e+00 5.518042e-03 +1361 1.570000e+00 2.500000e+00 5.528470e-03 +1362 1.580000e+00 2.500000e+00 5.538705e-03 +1363 1.590000e+00 2.500000e+00 5.548367e-03 +1364 1.600000e+00 2.500000e+00 5.557655e-03 +1365 1.610000e+00 2.500000e+00 5.566579e-03 +1366 1.620000e+00 2.500000e+00 5.575149e-03 +1367 1.630000e+00 2.500000e+00 5.583377e-03 +1368 1.640000e+00 2.500000e+00 5.591280e-03 +1369 1.650000e+00 2.500000e+00 5.598882e-03 +1370 1.660000e+00 2.500000e+00 5.606221e-03 +1371 1.670000e+00 2.500000e+00 5.613377e-03 +1372 1.680000e+00 2.500000e+00 5.620580e-03 +1373 1.690000e+00 2.500000e+00 5.628762e-03 +1374 1.700000e+00 2.500000e+00 5.640631e-03 +1375 1.710000e+00 2.500000e+00 5.654006e-03 +1376 1.720000e+00 2.500000e+00 5.666740e-03 +1377 1.730000e+00 2.500000e+00 5.679123e-03 +1378 1.740000e+00 2.500000e+00 5.691239e-03 +1379 1.750000e+00 2.500000e+00 5.703101e-03 +1380 1.760000e+00 2.500000e+00 5.714718e-03 +1381 1.770000e+00 2.500000e+00 5.726098e-03 +1382 1.780000e+00 2.500000e+00 5.737250e-03 +1383 1.790000e+00 2.500000e+00 5.748183e-03 +1384 1.800000e+00 2.500000e+00 5.758905e-03 +1385 1.810000e+00 2.500000e+00 5.769424e-03 +1386 1.820000e+00 2.500000e+00 5.779750e-03 +1387 1.830000e+00 2.500000e+00 5.789888e-03 +1388 1.840000e+00 2.500000e+00 5.799847e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1389 1.850000e+00 2.500000e+00 5.809707e-03 +1390 1.860000e+00 2.500000e+00 5.819554e-03 +1391 1.870000e+00 2.500000e+00 5.829293e-03 +1392 1.880000e+00 2.500000e+00 5.838909e-03 +1393 1.890000e+00 2.500000e+00 5.848393e-03 +1394 1.900000e+00 2.500000e+00 5.857738e-03 +1395 1.910000e+00 2.500000e+00 5.866942e-03 +1396 1.920000e+00 2.500000e+00 5.876003e-03 +1397 1.930000e+00 2.500000e+00 5.884920e-03 +1398 1.940000e+00 2.500000e+00 5.893696e-03 +1399 1.950000e+00 2.500000e+00 5.902330e-03 +1400 1.960000e+00 2.500000e+00 5.910825e-03 +1401 1.970000e+00 2.500000e+00 5.919184e-03 +1402 1.980000e+00 2.500000e+00 5.927408e-03 +1403 1.990000e+00 2.500000e+00 5.935501e-03 +1404 2.000000e+00 2.500000e+00 5.943466e-03 +1405 2.010000e+00 2.500000e+00 5.951304e-03 +1406 2.020000e+00 2.500000e+00 5.959019e-03 +1407 2.030000e+00 2.500000e+00 5.966614e-03 +1408 2.040000e+00 2.500000e+00 5.974092e-03 +1409 2.050000e+00 2.500000e+00 5.981455e-03 +1410 2.060000e+00 2.500000e+00 5.988706e-03 +1411 2.070000e+00 2.500000e+00 5.995848e-03 +1412 2.080000e+00 2.500000e+00 6.002884e-03 +1413 2.090000e+00 2.500000e+00 6.009816e-03 +1414 2.100000e+00 2.500000e+00 6.016646e-03 +1415 2.110000e+00 2.500000e+00 6.023377e-03 +1416 2.120000e+00 2.500000e+00 6.030012e-03 +1417 2.130000e+00 2.500000e+00 6.036552e-03 +1418 2.140000e+00 2.500000e+00 6.043000e-03 +1419 2.150000e+00 2.500000e+00 6.049359e-03 +1420 2.160000e+00 2.500000e+00 6.055629e-03 +1421 2.170000e+00 2.500000e+00 6.061814e-03 +1422 2.180000e+00 2.500000e+00 6.067915e-03 +1423 2.190000e+00 2.500000e+00 6.073934e-03 +1424 2.200000e+00 2.500000e+00 6.079873e-03 +1425 2.210000e+00 2.500000e+00 6.085734e-03 +1426 2.220000e+00 2.500000e+00 6.091519e-03 +1427 2.230000e+00 2.500000e+00 6.097228e-03 +1428 2.240000e+00 2.500000e+00 6.102865e-03 +1429 2.250000e+00 2.500000e+00 6.108430e-03 +1430 2.260000e+00 2.500000e+00 6.113925e-03 +1431 2.270000e+00 2.500000e+00 6.119351e-03 +1432 2.280000e+00 2.500000e+00 6.124711e-03 +1433 2.290000e+00 2.500000e+00 6.130005e-03 +1434 2.300000e+00 2.500000e+00 6.135234e-03 +1435 2.310000e+00 2.500000e+00 6.140401e-03 +1436 2.320000e+00 2.500000e+00 6.145505e-03 +1437 2.330000e+00 2.500000e+00 6.150550e-03 +1438 2.340000e+00 2.500000e+00 6.155535e-03 +1439 2.350000e+00 2.500000e+00 6.160461e-03 +1440 2.360000e+00 2.500000e+00 6.165331e-03 +1441 2.370000e+00 2.500000e+00 6.170145e-03 +1442 2.380000e+00 2.500000e+00 6.174904e-03 +1443 2.390000e+00 2.500000e+00 6.179609e-03 +1444 2.400000e+00 2.500000e+00 6.184261e-03 +1445 2.410000e+00 2.500000e+00 6.188862e-03 +1446 2.420000e+00 2.500000e+00 6.193411e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1447 2.430000e+00 2.500000e+00 6.197910e-03 +1448 2.440000e+00 2.500000e+00 6.202360e-03 +1449 2.450000e+00 2.500000e+00 6.206762e-03 +1450 2.460000e+00 2.500000e+00 6.211116e-03 +1451 2.470000e+00 2.500000e+00 6.215424e-03 +1452 2.480000e+00 2.500000e+00 6.219685e-03 +1453 2.490000e+00 2.500000e+00 6.223901e-03 +1454 2.500000e+00 2.500000e+00 6.228073e-03 +1455 2.510000e+00 2.500000e+00 6.232201e-03 +1456 2.520000e+00 2.500000e+00 6.236286e-03 +1457 2.530000e+00 2.500000e+00 6.240329e-03 +1458 2.540000e+00 2.500000e+00 6.244329e-03 +1459 2.550000e+00 2.500000e+00 6.248289e-03 +1460 2.560000e+00 2.500000e+00 6.252208e-03 +1461 2.570000e+00 2.500000e+00 6.256086e-03 +1462 2.580000e+00 2.500000e+00 6.259926e-03 +1463 2.590000e+00 2.500000e+00 6.263727e-03 +1464 2.600000e+00 2.500000e+00 6.267489e-03 +1465 2.610000e+00 2.500000e+00 6.271213e-03 +1466 2.620000e+00 2.500000e+00 6.274901e-03 +1467 2.630000e+00 2.500000e+00 6.278551e-03 +1468 2.640000e+00 2.500000e+00 6.282165e-03 +1469 2.650000e+00 2.500000e+00 6.285743e-03 +1470 2.660000e+00 2.500000e+00 6.289286e-03 +1471 2.670000e+00 2.500000e+00 6.292793e-03 +1472 2.680000e+00 2.500000e+00 6.296267e-03 +1473 2.690000e+00 2.500000e+00 6.299705e-03 +1474 2.700000e+00 2.500000e+00 6.303111e-03 +1475 2.710000e+00 2.500000e+00 6.306482e-03 +1476 2.720000e+00 2.500000e+00 6.309821e-03 +1477 2.730000e+00 2.500000e+00 6.313127e-03 +1478 2.740000e+00 2.500000e+00 6.316401e-03 +1479 2.750000e+00 2.500000e+00 6.319643e-03 +1480 2.760000e+00 2.500000e+00 6.322854e-03 +1481 2.770000e+00 2.500000e+00 6.326033e-03 +1482 2.780000e+00 2.500000e+00 6.329181e-03 +1483 2.790000e+00 2.500000e+00 6.332299e-03 +1484 2.800000e+00 2.500000e+00 6.335386e-03 +1485 2.810000e+00 2.500000e+00 6.338444e-03 +1486 2.820000e+00 2.500000e+00 6.341472e-03 +1487 2.830000e+00 2.500000e+00 6.344470e-03 +1488 2.840000e+00 2.500000e+00 6.347439e-03 +1489 2.850000e+00 2.500000e+00 6.350380e-03 +1490 2.860000e+00 2.500000e+00 6.353292e-03 +1491 2.870000e+00 2.500000e+00 6.356176e-03 +1492 2.880000e+00 2.500000e+00 6.359032e-03 +1493 2.890000e+00 2.500000e+00 6.361860e-03 +1494 2.900000e+00 2.500000e+00 6.364661e-03 +1495 2.910000e+00 2.500000e+00 6.367435e-03 +1496 2.920000e+00 2.500000e+00 6.370182e-03 +1497 2.930000e+00 2.500000e+00 6.372903e-03 +1498 2.940000e+00 2.500000e+00 6.375597e-03 +1499 2.950000e+00 2.500000e+00 6.378265e-03 +1500 2.960000e+00 2.500000e+00 6.380907e-03 +1501 2.970000e+00 2.500000e+00 6.383524e-03 +1502 2.980000e+00 2.500000e+00 6.386116e-03 +1503 2.990000e+00 2.500000e+00 6.388682e-03 +1504 3.000000e+00 2.500000e+00 6.391225e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1505 0.000000e+00 3.000000e+00 -5.180603e-33 +1506 1.000000e-02 3.000000e+00 6.230785e-05 +1507 2.000000e-02 3.000000e+00 1.243329e-04 +1508 3.000000e-02 3.000000e+00 1.860755e-04 +1509 4.000000e-02 3.000000e+00 2.475361e-04 +1510 5.000000e-02 3.000000e+00 3.087150e-04 +1511 6.000000e-02 3.000000e+00 3.696125e-04 +1512 7.000000e-02 3.000000e+00 4.302290e-04 +1513 8.000000e-02 3.000000e+00 4.905649e-04 +1514 9.000000e-02 3.000000e+00 5.506206e-04 +1515 1.000000e-01 3.000000e+00 6.103963e-04 +1516 1.100000e-01 3.000000e+00 6.698925e-04 +1517 1.200000e-01 3.000000e+00 7.291094e-04 +1518 1.300000e-01 3.000000e+00 7.880476e-04 +1519 1.400000e-01 3.000000e+00 8.467072e-04 +1520 1.500000e-01 3.000000e+00 9.050888e-04 +1521 1.600000e-01 3.000000e+00 9.631925e-04 +1522 1.700000e-01 3.000000e+00 1.021019e-03 +1523 1.800000e-01 3.000000e+00 1.078707e-03 +1524 1.900000e-01 3.000000e+00 1.135979e-03 +1525 2.000000e-01 3.000000e+00 1.192975e-03 +1526 2.100000e-01 3.000000e+00 1.249695e-03 +1527 2.200000e-01 3.000000e+00 1.306139e-03 +1528 2.300000e-01 3.000000e+00 1.362308e-03 +1529 2.400000e-01 3.000000e+00 1.418203e-03 +1530 2.500000e-01 3.000000e+00 1.473822e-03 +1531 2.600000e-01 3.000000e+00 1.529167e-03 +1532 2.700000e-01 3.000000e+00 1.584238e-03 +1533 2.800000e-01 3.000000e+00 1.639036e-03 +1534 2.900000e-01 3.000000e+00 1.693561e-03 +1535 3.000000e-01 3.000000e+00 1.747812e-03 +1536 3.100000e-01 3.000000e+00 1.801791e-03 +1537 3.200000e-01 3.000000e+00 1.855498e-03 +1538 3.300000e-01 3.000000e+00 1.908933e-03 +1539 3.400000e-01 3.000000e+00 1.962097e-03 +1540 3.500000e-01 3.000000e+00 2.014989e-03 +1541 3.600000e-01 3.000000e+00 2.067611e-03 +1542 3.700000e-01 3.000000e+00 2.119962e-03 +1543 3.800000e-01 3.000000e+00 2.172043e-03 +1544 3.900000e-01 3.000000e+00 2.223854e-03 +1545 4.000000e-01 3.000000e+00 2.275396e-03 +1546 4.100000e-01 3.000000e+00 2.326668e-03 +1547 4.200000e-01 3.000000e+00 2.377672e-03 +1548 4.300000e-01 3.000000e+00 2.428407e-03 +1549 4.400000e-01 3.000000e+00 2.478874e-03 +1550 4.500000e-01 3.000000e+00 2.529074e-03 +1551 4.600000e-01 3.000000e+00 2.579006e-03 +1552 4.700000e-01 3.000000e+00 2.628670e-03 +1553 4.800000e-01 3.000000e+00 2.678068e-03 +1554 4.900000e-01 3.000000e+00 2.727200e-03 +1555 5.000000e-01 3.000000e+00 2.776065e-03 +1556 5.100000e-01 3.000000e+00 2.824665e-03 +1557 5.200000e-01 3.000000e+00 2.872999e-03 +1558 5.300000e-01 3.000000e+00 2.921068e-03 +1559 5.400000e-01 3.000000e+00 2.968872e-03 +1560 5.500000e-01 3.000000e+00 3.016412e-03 +1561 5.600000e-01 3.000000e+00 3.063687e-03 +1562 5.700000e-01 3.000000e+00 3.110699e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1563 5.800000e-01 3.000000e+00 3.157447e-03 +1564 5.900000e-01 3.000000e+00 3.203932e-03 +1565 6.000000e-01 3.000000e+00 3.250154e-03 +1566 6.100000e-01 3.000000e+00 3.296114e-03 +1567 6.200000e-01 3.000000e+00 3.341811e-03 +1568 6.300000e-01 3.000000e+00 3.387246e-03 +1569 6.400000e-01 3.000000e+00 3.432420e-03 +1570 6.500000e-01 3.000000e+00 3.477332e-03 +1571 6.600000e-01 3.000000e+00 3.521984e-03 +1572 6.700000e-01 3.000000e+00 3.566375e-03 +1573 6.800000e-01 3.000000e+00 3.610505e-03 +1574 6.900000e-01 3.000000e+00 3.654375e-03 +1575 7.000000e-01 3.000000e+00 3.697986e-03 +1576 7.100000e-01 3.000000e+00 3.741337e-03 +1577 7.200000e-01 3.000000e+00 3.784430e-03 +1578 7.300000e-01 3.000000e+00 3.827263e-03 +1579 7.400000e-01 3.000000e+00 3.869838e-03 +1580 7.500000e-01 3.000000e+00 3.912155e-03 +1581 7.600000e-01 3.000000e+00 3.954213e-03 +1582 7.700000e-01 3.000000e+00 3.996015e-03 +1583 7.800000e-01 3.000000e+00 4.037559e-03 +1584 7.900000e-01 3.000000e+00 4.078846e-03 +1585 8.000000e-01 3.000000e+00 4.119876e-03 +1586 8.100000e-01 3.000000e+00 4.160650e-03 +1587 8.200000e-01 3.000000e+00 4.201167e-03 +1588 8.300000e-01 3.000000e+00 4.241429e-03 +1589 8.400000e-01 3.000000e+00 4.281436e-03 +1590 8.500000e-01 3.000000e+00 4.321187e-03 +1591 8.600000e-01 3.000000e+00 4.360683e-03 +1592 8.700000e-01 3.000000e+00 4.399925e-03 +1593 8.800000e-01 3.000000e+00 4.438912e-03 +1594 8.900000e-01 3.000000e+00 4.477646e-03 +1595 9.000000e-01 3.000000e+00 4.516125e-03 +1596 9.100000e-01 3.000000e+00 4.554351e-03 +1597 9.200000e-01 3.000000e+00 4.592324e-03 +1598 9.300000e-01 3.000000e+00 4.630043e-03 +1599 9.400000e-01 3.000000e+00 4.667510e-03 +1600 9.500000e-01 3.000000e+00 4.704725e-03 +1601 9.600000e-01 3.000000e+00 4.741687e-03 +1602 9.700000e-01 3.000000e+00 4.778397e-03 +1603 9.800000e-01 3.000000e+00 4.814856e-03 +1604 9.900000e-01 3.000000e+00 4.851063e-03 +1605 1.000000e+00 3.000000e+00 4.887019e-03 +1606 1.010000e+00 3.000000e+00 4.922725e-03 +1607 1.020000e+00 3.000000e+00 4.958179e-03 +1608 1.030000e+00 3.000000e+00 4.993384e-03 +1609 1.040000e+00 3.000000e+00 5.028338e-03 +1610 1.050000e+00 3.000000e+00 5.063042e-03 +1611 1.060000e+00 3.000000e+00 5.097496e-03 +1612 1.070000e+00 3.000000e+00 5.131701e-03 +1613 1.080000e+00 3.000000e+00 5.165656e-03 +1614 1.090000e+00 3.000000e+00 5.199363e-03 +1615 1.100000e+00 3.000000e+00 5.232821e-03 +1616 1.110000e+00 3.000000e+00 5.266030e-03 +1617 1.120000e+00 3.000000e+00 5.298990e-03 +1618 1.130000e+00 3.000000e+00 5.331703e-03 +1619 1.140000e+00 3.000000e+00 5.364167e-03 +1620 1.150000e+00 3.000000e+00 5.396383e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1621 1.160000e+00 3.000000e+00 5.428352e-03 +1622 1.170000e+00 3.000000e+00 5.460073e-03 +1623 1.180000e+00 3.000000e+00 5.491547e-03 +1624 1.190000e+00 3.000000e+00 5.522773e-03 +1625 1.200000e+00 3.000000e+00 5.553753e-03 +1626 1.210000e+00 3.000000e+00 5.584485e-03 +1627 1.220000e+00 3.000000e+00 5.614970e-03 +1628 1.230000e+00 3.000000e+00 5.645209e-03 +1629 1.240000e+00 3.000000e+00 5.675201e-03 +1630 1.250000e+00 3.000000e+00 5.704946e-03 +1631 1.260000e+00 3.000000e+00 5.734445e-03 +1632 1.270000e+00 3.000000e+00 5.763698e-03 +1633 1.280000e+00 3.000000e+00 5.792703e-03 +1634 1.290000e+00 3.000000e+00 5.821463e-03 +1635 1.300000e+00 3.000000e+00 5.849976e-03 +1636 1.310000e+00 3.000000e+00 5.878242e-03 +1637 1.320000e+00 3.000000e+00 5.906262e-03 +1638 1.330000e+00 3.000000e+00 5.934036e-03 +1639 1.340000e+00 3.000000e+00 5.961563e-03 +1640 1.350000e+00 3.000000e+00 5.988843e-03 +1641 1.360000e+00 3.000000e+00 6.015876e-03 +1642 1.370000e+00 3.000000e+00 6.042662e-03 +1643 1.380000e+00 3.000000e+00 6.069201e-03 +1644 1.390000e+00 3.000000e+00 6.095493e-03 +1645 1.400000e+00 3.000000e+00 6.121536e-03 +1646 1.410000e+00 3.000000e+00 6.147332e-03 +1647 1.420000e+00 3.000000e+00 6.172879e-03 +1648 1.430000e+00 3.000000e+00 6.198178e-03 +1649 1.440000e+00 3.000000e+00 6.223227e-03 +1650 1.450000e+00 3.000000e+00 6.248027e-03 +1651 1.460000e+00 3.000000e+00 6.272576e-03 +1652 1.470000e+00 3.000000e+00 6.296875e-03 +1653 1.480000e+00 3.000000e+00 6.320922e-03 +1654 1.490000e+00 3.000000e+00 6.344717e-03 +1655 1.500000e+00 3.000000e+00 6.368260e-03 +1656 1.510000e+00 3.000000e+00 6.391548e-03 +1657 1.520000e+00 3.000000e+00 6.414581e-03 +1658 1.530000e+00 3.000000e+00 6.437359e-03 +1659 1.540000e+00 3.000000e+00 6.459880e-03 +1660 1.550000e+00 3.000000e+00 6.482143e-03 +1661 1.560000e+00 3.000000e+00 6.504146e-03 +1662 1.570000e+00 3.000000e+00 6.525888e-03 +1663 1.580000e+00 3.000000e+00 6.547368e-03 +1664 1.590000e+00 3.000000e+00 6.568583e-03 +1665 1.600000e+00 3.000000e+00 6.589532e-03 +1666 1.610000e+00 3.000000e+00 6.610214e-03 +1667 1.620000e+00 3.000000e+00 6.630625e-03 +1668 1.630000e+00 3.000000e+00 6.650763e-03 +1669 1.640000e+00 3.000000e+00 6.670627e-03 +1670 1.650000e+00 3.000000e+00 6.690212e-03 +1671 1.660000e+00 3.000000e+00 6.709518e-03 +1672 1.670000e+00 3.000000e+00 6.728540e-03 +1673 1.680000e+00 3.000000e+00 6.747275e-03 +1674 1.690000e+00 3.000000e+00 6.765719e-03 +1675 1.700000e+00 3.000000e+00 6.783871e-03 +1676 1.710000e+00 3.000000e+00 6.801724e-03 +1677 1.720000e+00 3.000000e+00 6.819276e-03 +1678 1.730000e+00 3.000000e+00 6.836522e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1679 1.740000e+00 3.000000e+00 6.853457e-03 +1680 1.750000e+00 3.000000e+00 6.870078e-03 +1681 1.760000e+00 3.000000e+00 6.886380e-03 +1682 1.770000e+00 3.000000e+00 6.902197e-03 +1683 1.780000e+00 3.000000e+00 6.917850e-03 +1684 1.790000e+00 3.000000e+00 6.933172e-03 +1685 1.800000e+00 3.000000e+00 6.948157e-03 +1686 1.810000e+00 3.000000e+00 6.962973e-03 +1687 1.820000e+00 3.000000e+00 6.977275e-03 +1688 1.830000e+00 3.000000e+00 6.991231e-03 +1689 1.840000e+00 3.000000e+00 7.004836e-03 +1690 1.850000e+00 3.000000e+00 7.018090e-03 +1691 1.860000e+00 3.000000e+00 7.030994e-03 +1692 1.870000e+00 3.000000e+00 7.043553e-03 +1693 1.880000e+00 3.000000e+00 7.055778e-03 +1694 1.890000e+00 3.000000e+00 7.067699e-03 +1695 1.900000e+00 3.000000e+00 7.079396e-03 +1696 1.910000e+00 3.000000e+00 7.091137e-03 +1697 1.920000e+00 3.000000e+00 7.104155e-03 +1698 1.930000e+00 3.000000e+00 7.121250e-03 +1699 1.940000e+00 3.000000e+00 7.138984e-03 +1700 1.950000e+00 3.000000e+00 7.156016e-03 +1701 1.960000e+00 3.000000e+00 7.172645e-03 +1702 1.970000e+00 3.000000e+00 7.188924e-03 +1703 1.980000e+00 3.000000e+00 7.204859e-03 +1704 1.990000e+00 3.000000e+00 7.220456e-03 +1705 2.000000e+00 3.000000e+00 7.235719e-03 +1706 2.010000e+00 3.000000e+00 7.250654e-03 +1707 2.020000e+00 3.000000e+00 7.265269e-03 +1708 2.030000e+00 3.000000e+00 7.279570e-03 +1709 2.040000e+00 3.000000e+00 7.293566e-03 +1710 2.050000e+00 3.000000e+00 7.307264e-03 +1711 2.060000e+00 3.000000e+00 7.320674e-03 +1712 2.070000e+00 3.000000e+00 7.333831e-03 +1713 2.080000e+00 3.000000e+00 7.346916e-03 +1714 2.090000e+00 3.000000e+00 7.359801e-03 +1715 2.100000e+00 3.000000e+00 7.372468e-03 +1716 2.110000e+00 3.000000e+00 7.384908e-03 +1717 2.120000e+00 3.000000e+00 7.397117e-03 +1718 2.130000e+00 3.000000e+00 7.409092e-03 +1719 2.140000e+00 3.000000e+00 7.420836e-03 +1720 2.150000e+00 3.000000e+00 7.432349e-03 +1721 2.160000e+00 3.000000e+00 7.443635e-03 +1722 2.170000e+00 3.000000e+00 7.454700e-03 +1723 2.180000e+00 3.000000e+00 7.465547e-03 +1724 2.190000e+00 3.000000e+00 7.476182e-03 +1725 2.200000e+00 3.000000e+00 7.486610e-03 +1726 2.210000e+00 3.000000e+00 7.496837e-03 +1727 2.220000e+00 3.000000e+00 7.506869e-03 +1728 2.230000e+00 3.000000e+00 7.516711e-03 +1729 2.240000e+00 3.000000e+00 7.526369e-03 +1730 2.250000e+00 3.000000e+00 7.535848e-03 +1731 2.260000e+00 3.000000e+00 7.545153e-03 +1732 2.270000e+00 3.000000e+00 7.554290e-03 +1733 2.280000e+00 3.000000e+00 7.563264e-03 +1734 2.290000e+00 3.000000e+00 7.572080e-03 +1735 2.300000e+00 3.000000e+00 7.580743e-03 +1736 2.310000e+00 3.000000e+00 7.589256e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1737 2.320000e+00 3.000000e+00 7.597625e-03 +1738 2.330000e+00 3.000000e+00 7.605855e-03 +1739 2.340000e+00 3.000000e+00 7.613948e-03 +1740 2.350000e+00 3.000000e+00 7.621909e-03 +1741 2.360000e+00 3.000000e+00 7.629742e-03 +1742 2.370000e+00 3.000000e+00 7.637451e-03 +1743 2.380000e+00 3.000000e+00 7.645039e-03 +1744 2.390000e+00 3.000000e+00 7.652510e-03 +1745 2.400000e+00 3.000000e+00 7.659867e-03 +1746 2.410000e+00 3.000000e+00 7.667112e-03 +1747 2.420000e+00 3.000000e+00 7.674250e-03 +1748 2.430000e+00 3.000000e+00 7.681283e-03 +1749 2.440000e+00 3.000000e+00 7.688213e-03 +1750 2.450000e+00 3.000000e+00 7.695045e-03 +1751 2.460000e+00 3.000000e+00 7.701779e-03 +1752 2.470000e+00 3.000000e+00 7.708419e-03 +1753 2.480000e+00 3.000000e+00 7.714967e-03 +1754 2.490000e+00 3.000000e+00 7.721426e-03 +1755 2.500000e+00 3.000000e+00 7.727797e-03 +1756 2.510000e+00 3.000000e+00 7.734083e-03 +1757 2.520000e+00 3.000000e+00 7.740286e-03 +1758 2.530000e+00 3.000000e+00 7.746408e-03 +1759 2.540000e+00 3.000000e+00 7.752450e-03 +1760 2.550000e+00 3.000000e+00 7.758415e-03 +1761 2.560000e+00 3.000000e+00 7.764305e-03 +1762 2.570000e+00 3.000000e+00 7.770120e-03 +1763 2.580000e+00 3.000000e+00 7.775863e-03 +1764 2.590000e+00 3.000000e+00 7.781536e-03 +1765 2.600000e+00 3.000000e+00 7.787139e-03 +1766 2.610000e+00 3.000000e+00 7.792675e-03 +1767 2.620000e+00 3.000000e+00 7.798144e-03 +1768 2.630000e+00 3.000000e+00 7.803549e-03 +1769 2.640000e+00 3.000000e+00 7.808890e-03 +1770 2.650000e+00 3.000000e+00 7.814169e-03 +1771 2.660000e+00 3.000000e+00 7.819387e-03 +1772 2.670000e+00 3.000000e+00 7.824544e-03 +1773 2.680000e+00 3.000000e+00 7.829643e-03 +1774 2.690000e+00 3.000000e+00 7.834685e-03 +1775 2.700000e+00 3.000000e+00 7.839670e-03 +1776 2.710000e+00 3.000000e+00 7.844599e-03 +1777 2.720000e+00 3.000000e+00 7.849474e-03 +1778 2.730000e+00 3.000000e+00 7.854296e-03 +1779 2.740000e+00 3.000000e+00 7.859065e-03 +1780 2.750000e+00 3.000000e+00 7.863782e-03 +1781 2.760000e+00 3.000000e+00 7.868448e-03 +1782 2.770000e+00 3.000000e+00 7.873064e-03 +1783 2.780000e+00 3.000000e+00 7.877631e-03 +1784 2.790000e+00 3.000000e+00 7.882149e-03 +1785 2.800000e+00 3.000000e+00 7.886620e-03 +1786 2.810000e+00 3.000000e+00 7.891044e-03 +1787 2.820000e+00 3.000000e+00 7.895421e-03 +1788 2.830000e+00 3.000000e+00 7.899753e-03 +1789 2.840000e+00 3.000000e+00 7.904041e-03 +1790 2.850000e+00 3.000000e+00 7.908283e-03 +1791 2.860000e+00 3.000000e+00 7.912483e-03 +1792 2.870000e+00 3.000000e+00 7.916639e-03 +1793 2.880000e+00 3.000000e+00 7.920752e-03 +1794 2.890000e+00 3.000000e+00 7.924824e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1795 2.900000e+00 3.000000e+00 7.928854e-03 +1796 2.910000e+00 3.000000e+00 7.932844e-03 +1797 2.920000e+00 3.000000e+00 7.936793e-03 +1798 2.930000e+00 3.000000e+00 7.940702e-03 +1799 2.940000e+00 3.000000e+00 7.944572e-03 +1800 2.950000e+00 3.000000e+00 7.948404e-03 +1801 2.960000e+00 3.000000e+00 7.952196e-03 +1802 2.970000e+00 3.000000e+00 7.955951e-03 +1803 2.980000e+00 3.000000e+00 7.959668e-03 +1804 2.990000e+00 3.000000e+00 7.963348e-03 +1805 3.000000e+00 3.000000e+00 7.966992e-03 + + + + diff --git a/tests/bsim3soidd/t4.cir b/tests/bsim3soidd/t4.cir new file mode 100644 index 000000000..2742e60ae --- /dev/null +++ b/tests/bsim3soidd/t4.cir @@ -0,0 +1,17 @@ +*model = BSIMSOI (DD) +*Berkeley Spice Compatibility +* +* SOI NMOSFET, tied body simulation + +vd d 0 dc 0.05 +vs s 0 dc 0 +ve e 0 dc 0 +vg g 0 dc 3 +vb b 0 dc 0 + +m1 d g s e b n1 w=10u l=0.25u + +.option gmin=1e-25 itl1=500 +.dc vg 0 1.5 0.01 vb -0.3 0.5 0.1 +.print dc i(vs) +.include nmosdd.mod diff --git a/tests/bsim3soidd/t4.out b/tests/bsim3soidd/t4.out new file mode 100644 index 000000000..16826d9ee --- /dev/null +++ b/tests/bsim3soidd/t4.out @@ -0,0 +1,1444 @@ + Reference value : 1.03000e+00 +No. of Data Rows : 1359 + +Circuit: *model = BSIMSOI (DD) + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. + *model = BSIMSOI (DD) +-------------------------------------------------------------------------------- +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 4.146227e-12 +1 1.000000e-02 5.646207e-12 +2 2.000000e-02 8.105438e-12 +3 3.000000e-02 1.163351e-11 +4 4.000000e-02 1.669365e-11 +5 5.000000e-02 2.524361e-11 +6 6.000000e-02 3.620261e-11 +7 7.000000e-02 5.190353e-11 +8 8.000000e-02 7.438857e-11 +9 9.000000e-02 1.065733e-10 +10 1.000000e-01 1.526162e-10 +11 1.100000e-01 2.184419e-10 +12 1.200000e-01 3.124799e-10 +13 1.300000e-01 4.467056e-10 +14 1.400000e-01 6.381011e-10 +15 1.500000e-01 9.106977e-10 +16 1.600000e-01 1.298398e-09 +17 1.700000e-01 1.848760e-09 +18 1.800000e-01 2.628478e-09 +19 1.900000e-01 3.730652e-09 +20 2.000000e-01 5.284624e-09 +21 2.100000e-01 7.469127e-09 +22 2.200000e-01 1.052965e-08 +23 2.300000e-01 1.480108e-08 +24 2.400000e-01 2.073668e-08 +25 2.500000e-01 2.894472e-08 +26 2.600000e-01 4.023376e-08 +27 2.700000e-01 5.566760e-08 +28 2.800000e-01 7.663072e-08 +29 2.900000e-01 1.049046e-07 +30 3.000000e-01 1.427557e-07 +31 3.100000e-01 1.930347e-07 +32 3.200000e-01 2.592898e-07 +33 3.300000e-01 3.458940e-07 +34 3.400000e-01 4.581896e-07 +35 3.500000e-01 6.026505e-07 +36 3.600000e-01 7.870605e-07 +37 3.700000e-01 1.020699e-06 +38 3.800000e-01 1.314508e-06 +39 3.900000e-01 1.681213e-06 +40 4.000000e-01 2.135318e-06 +41 4.100000e-01 2.692908e-06 +42 4.200000e-01 3.371145e-06 +43 4.300000e-01 4.187271e-06 +44 4.400000e-01 5.156795e-06 +45 4.500000e-01 6.290054e-06 +46 4.600000e-01 7.586744e-06 +47 4.700000e-01 9.036984e-06 +48 4.800000e-01 1.063872e-05 +49 4.900000e-01 1.239891e-05 +50 5.000000e-01 1.432076e-05 +51 5.100000e-01 1.640136e-05 +52 5.200000e-01 1.863330e-05 +53 5.300000e-01 2.100609e-05 +54 5.400000e-01 2.350716e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +55 5.500000e-01 2.612264e-05 +56 5.600000e-01 2.883806e-05 +57 5.700000e-01 3.163886e-05 +58 5.800000e-01 3.447759e-05 +59 5.900000e-01 3.741399e-05 +60 6.000000e-01 4.039517e-05 +61 6.100000e-01 4.340966e-05 +62 6.200000e-01 4.644716e-05 +63 6.300000e-01 4.949858e-05 +64 6.400000e-01 5.255597e-05 +65 6.500000e-01 5.561244e-05 +66 6.600000e-01 5.866209e-05 +67 6.700000e-01 6.169994e-05 +68 6.800000e-01 6.472177e-05 +69 6.900000e-01 6.772407e-05 +70 7.000000e-01 7.070396e-05 +71 7.100000e-01 7.365905e-05 +72 7.200000e-01 7.658744e-05 +73 7.300000e-01 7.948759e-05 +74 7.400000e-01 8.235831e-05 +75 7.500000e-01 8.519865e-05 +76 7.600000e-01 8.800794e-05 +77 7.700000e-01 9.078568e-05 +78 7.800000e-01 9.353154e-05 +79 7.900000e-01 9.624531e-05 +80 8.000000e-01 9.892692e-05 +81 8.100000e-01 1.015764e-04 +82 8.200000e-01 1.041938e-04 +83 8.300000e-01 1.067792e-04 +84 8.400000e-01 1.093330e-04 +85 8.500000e-01 1.118553e-04 +86 8.600000e-01 1.143464e-04 +87 8.700000e-01 1.168066e-04 +88 8.800000e-01 1.192362e-04 +89 8.900000e-01 1.216356e-04 +90 9.000000e-01 1.240052e-04 +91 9.100000e-01 1.263452e-04 +92 9.200000e-01 1.286561e-04 +93 9.300000e-01 1.309383e-04 +94 9.400000e-01 1.331920e-04 +95 9.500000e-01 1.354178e-04 +96 9.600000e-01 1.376160e-04 +97 9.700000e-01 1.397869e-04 +98 9.800000e-01 1.419309e-04 +99 9.900000e-01 1.440485e-04 +100 1.000000e+00 1.461399e-04 +101 1.010000e+00 1.482056e-04 +102 1.020000e+00 1.502459e-04 +103 1.030000e+00 1.522611e-04 +104 1.040000e+00 1.542517e-04 +105 1.050000e+00 1.562180e-04 +106 1.060000e+00 1.581602e-04 +107 1.070000e+00 1.600788e-04 +108 1.080000e+00 1.619741e-04 +109 1.090000e+00 1.638465e-04 +110 1.100000e+00 1.656961e-04 +111 1.110000e+00 1.675234e-04 +112 1.120000e+00 1.693287e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +113 1.130000e+00 1.711123e-04 +114 1.140000e+00 1.728745e-04 +115 1.150000e+00 1.746156e-04 +116 1.160000e+00 1.763358e-04 +117 1.170000e+00 1.780356e-04 +118 1.180000e+00 1.797151e-04 +119 1.190000e+00 1.813746e-04 +120 1.200000e+00 1.830145e-04 +121 1.210000e+00 1.846349e-04 +122 1.220000e+00 1.862362e-04 +123 1.230000e+00 1.878186e-04 +124 1.240000e+00 1.893825e-04 +125 1.250000e+00 1.909279e-04 +126 1.260000e+00 1.924552e-04 +127 1.270000e+00 1.939647e-04 +128 1.280000e+00 1.954565e-04 +129 1.290000e+00 1.969309e-04 +130 1.300000e+00 1.983882e-04 +131 1.310000e+00 1.998286e-04 +132 1.320000e+00 2.012522e-04 +133 1.330000e+00 2.026594e-04 +134 1.340000e+00 2.040504e-04 +135 1.350000e+00 2.054252e-04 +136 1.360000e+00 2.067843e-04 +137 1.370000e+00 2.081277e-04 +138 1.380000e+00 2.094558e-04 +139 1.390000e+00 2.107686e-04 +140 1.400000e+00 2.120664e-04 +141 1.410000e+00 2.133494e-04 +142 1.420000e+00 2.146177e-04 +143 1.430000e+00 2.158716e-04 +144 1.440000e+00 2.171113e-04 +145 1.450000e+00 2.183369e-04 +146 1.460000e+00 2.195486e-04 +147 1.470000e+00 2.207466e-04 +148 1.480000e+00 2.219311e-04 +149 1.490000e+00 2.231022e-04 +150 1.500000e+00 2.242602e-04 +151 0.000000e+00 4.146482e-12 +152 1.000000e-02 5.646551e-12 +153 2.000000e-02 8.105918e-12 +154 3.000000e-02 1.163417e-11 +155 4.000000e-02 1.669458e-11 +156 5.000000e-02 2.524497e-11 +157 6.000000e-02 3.620450e-11 +158 7.000000e-02 5.190617e-11 +159 8.000000e-02 7.439226e-11 +160 9.000000e-02 1.065785e-10 +161 1.000000e-01 1.526234e-10 +162 1.100000e-01 2.184519e-10 +163 1.200000e-01 3.124937e-10 +164 1.300000e-01 4.467248e-10 +165 1.400000e-01 6.381277e-10 +166 1.500000e-01 9.107344e-10 +167 1.600000e-01 1.298449e-09 +168 1.700000e-01 1.848830e-09 +169 1.800000e-01 2.628573e-09 +170 1.900000e-01 3.730782e-09 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +171 2.000000e-01 5.284801e-09 +172 2.100000e-01 7.469365e-09 +173 2.200000e-01 1.052997e-08 +174 2.300000e-01 1.480151e-08 +175 2.400000e-01 2.073725e-08 +176 2.500000e-01 2.894546e-08 +177 2.600000e-01 4.023472e-08 +178 2.700000e-01 5.566883e-08 +179 2.800000e-01 7.663228e-08 +180 2.900000e-01 1.049066e-07 +181 3.000000e-01 1.427581e-07 +182 3.100000e-01 1.930377e-07 +183 3.200000e-01 2.592935e-07 +184 3.300000e-01 3.458986e-07 +185 3.400000e-01 4.581953e-07 +186 3.500000e-01 6.026578e-07 +187 3.600000e-01 7.870701e-07 +188 3.700000e-01 1.020712e-06 +189 3.800000e-01 1.314526e-06 +190 3.900000e-01 1.681238e-06 +191 4.000000e-01 2.135353e-06 +192 4.100000e-01 2.692957e-06 +193 4.200000e-01 3.371213e-06 +194 4.300000e-01 4.187363e-06 +195 4.400000e-01 5.156917e-06 +196 4.500000e-01 6.290212e-06 +197 4.600000e-01 7.586942e-06 +198 4.700000e-01 9.037226e-06 +199 4.800000e-01 1.063901e-05 +200 4.900000e-01 1.239925e-05 +201 5.000000e-01 1.432115e-05 +202 5.100000e-01 1.640180e-05 +203 5.200000e-01 1.863378e-05 +204 5.300000e-01 2.100662e-05 +205 5.400000e-01 2.350774e-05 +206 5.500000e-01 2.612326e-05 +207 5.600000e-01 2.883871e-05 +208 5.700000e-01 3.163955e-05 +209 5.800000e-01 3.447831e-05 +210 5.900000e-01 3.741473e-05 +211 6.000000e-01 4.039593e-05 +212 6.100000e-01 4.341043e-05 +213 6.200000e-01 4.644795e-05 +214 6.300000e-01 4.949938e-05 +215 6.400000e-01 5.255677e-05 +216 6.500000e-01 5.561325e-05 +217 6.600000e-01 5.866291e-05 +218 6.700000e-01 6.170076e-05 +219 6.800000e-01 6.472259e-05 +220 6.900000e-01 6.772489e-05 +221 7.000000e-01 7.070478e-05 +222 7.100000e-01 7.365987e-05 +223 7.200000e-01 7.658826e-05 +224 7.300000e-01 7.948840e-05 +225 7.400000e-01 8.235911e-05 +226 7.500000e-01 8.519946e-05 +227 7.600000e-01 8.800874e-05 +228 7.700000e-01 9.078648e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +229 7.800000e-01 9.353232e-05 +230 7.900000e-01 9.624609e-05 +231 8.000000e-01 9.892769e-05 +232 8.100000e-01 1.015771e-04 +233 8.200000e-01 1.041945e-04 +234 8.300000e-01 1.067800e-04 +235 8.400000e-01 1.093337e-04 +236 8.500000e-01 1.118560e-04 +237 8.600000e-01 1.143471e-04 +238 8.700000e-01 1.168073e-04 +239 8.800000e-01 1.192369e-04 +240 8.900000e-01 1.216363e-04 +241 9.000000e-01 1.240059e-04 +242 9.100000e-01 1.263459e-04 +243 9.200000e-01 1.286568e-04 +244 9.300000e-01 1.309390e-04 +245 9.400000e-01 1.331927e-04 +246 9.500000e-01 1.354185e-04 +247 9.600000e-01 1.376167e-04 +248 9.700000e-01 1.397876e-04 +249 9.800000e-01 1.419316e-04 +250 9.900000e-01 1.440492e-04 +251 1.000000e+00 1.461406e-04 +252 1.010000e+00 1.482063e-04 +253 1.020000e+00 1.502465e-04 +254 1.030000e+00 1.522618e-04 +255 1.040000e+00 1.542524e-04 +256 1.050000e+00 1.562186e-04 +257 1.060000e+00 1.581609e-04 +258 1.070000e+00 1.600795e-04 +259 1.080000e+00 1.619748e-04 +260 1.090000e+00 1.638471e-04 +261 1.100000e+00 1.656967e-04 +262 1.110000e+00 1.675240e-04 +263 1.120000e+00 1.693293e-04 +264 1.130000e+00 1.711129e-04 +265 1.140000e+00 1.728751e-04 +266 1.150000e+00 1.746162e-04 +267 1.160000e+00 1.763364e-04 +268 1.170000e+00 1.780361e-04 +269 1.180000e+00 1.797156e-04 +270 1.190000e+00 1.813752e-04 +271 1.200000e+00 1.830150e-04 +272 1.210000e+00 1.846355e-04 +273 1.220000e+00 1.862368e-04 +274 1.230000e+00 1.878192e-04 +275 1.240000e+00 1.893830e-04 +276 1.250000e+00 1.909284e-04 +277 1.260000e+00 1.924558e-04 +278 1.270000e+00 1.939652e-04 +279 1.280000e+00 1.954570e-04 +280 1.290000e+00 1.969315e-04 +281 1.300000e+00 1.983887e-04 +282 1.310000e+00 1.998291e-04 +283 1.320000e+00 2.012528e-04 +284 1.330000e+00 2.026599e-04 +285 1.340000e+00 2.040509e-04 +286 1.350000e+00 2.054257e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +287 1.360000e+00 2.067848e-04 +288 1.370000e+00 2.081282e-04 +289 1.380000e+00 2.094563e-04 +290 1.390000e+00 2.107691e-04 +291 1.400000e+00 2.120669e-04 +292 1.410000e+00 2.133498e-04 +293 1.420000e+00 2.146182e-04 +294 1.430000e+00 2.158721e-04 +295 1.440000e+00 2.171118e-04 +296 1.450000e+00 2.183374e-04 +297 1.460000e+00 2.195491e-04 +298 1.470000e+00 2.207471e-04 +299 1.480000e+00 2.219316e-04 +300 1.490000e+00 2.231027e-04 +301 1.500000e+00 2.242606e-04 +302 0.000000e+00 4.147012e-12 +303 1.000000e-02 5.647254e-12 +304 2.000000e-02 8.106891e-12 +305 3.000000e-02 1.163552e-11 +306 4.000000e-02 1.669644e-11 +307 5.000000e-02 2.524766e-11 +308 6.000000e-02 3.620823e-11 +309 7.000000e-02 5.191133e-11 +310 8.000000e-02 7.439939e-11 +311 9.000000e-02 1.065883e-10 +312 1.000000e-01 1.526370e-10 +313 1.100000e-01 2.184707e-10 +314 1.200000e-01 3.125197e-10 +315 1.300000e-01 4.467605e-10 +316 1.400000e-01 6.381768e-10 +317 1.500000e-01 9.108019e-10 +318 1.600000e-01 1.298541e-09 +319 1.700000e-01 1.848956e-09 +320 1.800000e-01 2.628745e-09 +321 1.900000e-01 3.731015e-09 +322 2.000000e-01 5.285115e-09 +323 2.100000e-01 7.469787e-09 +324 2.200000e-01 1.053054e-08 +325 2.300000e-01 1.480225e-08 +326 2.400000e-01 2.073822e-08 +327 2.500000e-01 2.894674e-08 +328 2.600000e-01 4.023636e-08 +329 2.700000e-01 5.567092e-08 +330 2.800000e-01 7.663492e-08 +331 2.900000e-01 1.049099e-07 +332 3.000000e-01 1.427622e-07 +333 3.100000e-01 1.930427e-07 +334 3.200000e-01 2.592996e-07 +335 3.300000e-01 3.459061e-07 +336 3.400000e-01 4.582048e-07 +337 3.500000e-01 6.026698e-07 +338 3.600000e-01 7.870858e-07 +339 3.700000e-01 1.020733e-06 +340 3.800000e-01 1.314555e-06 +341 3.900000e-01 1.681279e-06 +342 4.000000e-01 2.135409e-06 +343 4.100000e-01 2.693036e-06 +344 4.200000e-01 3.371321e-06 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +345 4.300000e-01 4.187509e-06 +346 4.400000e-01 5.157110e-06 +347 4.500000e-01 6.290461e-06 +348 4.600000e-01 7.587255e-06 +349 4.700000e-01 9.037608e-06 +350 4.800000e-01 1.063946e-05 +351 4.900000e-01 1.239978e-05 +352 5.000000e-01 1.432176e-05 +353 5.100000e-01 1.640249e-05 +354 5.200000e-01 1.863455e-05 +355 5.300000e-01 2.100746e-05 +356 5.400000e-01 2.350864e-05 +357 5.500000e-01 2.612423e-05 +358 5.600000e-01 2.883973e-05 +359 5.700000e-01 3.164062e-05 +360 5.800000e-01 3.447942e-05 +361 5.900000e-01 3.741588e-05 +362 6.000000e-01 4.039711e-05 +363 6.100000e-01 4.341164e-05 +364 6.200000e-01 4.644918e-05 +365 6.300000e-01 4.950063e-05 +366 6.400000e-01 5.255803e-05 +367 6.500000e-01 5.561452e-05 +368 6.600000e-01 5.866419e-05 +369 6.700000e-01 6.170204e-05 +370 6.800000e-01 6.472387e-05 +371 6.900000e-01 6.772618e-05 +372 7.000000e-01 7.070606e-05 +373 7.100000e-01 7.366115e-05 +374 7.200000e-01 7.658953e-05 +375 7.300000e-01 7.948967e-05 +376 7.400000e-01 8.236038e-05 +377 7.500000e-01 8.520071e-05 +378 7.600000e-01 8.800999e-05 +379 7.700000e-01 9.078772e-05 +380 7.800000e-01 9.353356e-05 +381 7.900000e-01 9.624732e-05 +382 8.000000e-01 9.892891e-05 +383 8.100000e-01 1.015784e-04 +384 8.200000e-01 1.041957e-04 +385 8.300000e-01 1.067812e-04 +386 8.400000e-01 1.093349e-04 +387 8.500000e-01 1.118572e-04 +388 8.600000e-01 1.143483e-04 +389 8.700000e-01 1.168085e-04 +390 8.800000e-01 1.192381e-04 +391 8.900000e-01 1.216375e-04 +392 9.000000e-01 1.240070e-04 +393 9.100000e-01 1.263470e-04 +394 9.200000e-01 1.286579e-04 +395 9.300000e-01 1.309401e-04 +396 9.400000e-01 1.331938e-04 +397 9.500000e-01 1.354196e-04 +398 9.600000e-01 1.376177e-04 +399 9.700000e-01 1.397886e-04 +400 9.800000e-01 1.419327e-04 +401 9.900000e-01 1.440502e-04 +402 1.000000e+00 1.461416e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +403 1.010000e+00 1.482073e-04 +404 1.020000e+00 1.502476e-04 +405 1.030000e+00 1.522628e-04 +406 1.040000e+00 1.542534e-04 +407 1.050000e+00 1.562196e-04 +408 1.060000e+00 1.581618e-04 +409 1.070000e+00 1.600804e-04 +410 1.080000e+00 1.619757e-04 +411 1.090000e+00 1.638480e-04 +412 1.100000e+00 1.656977e-04 +413 1.110000e+00 1.675250e-04 +414 1.120000e+00 1.693303e-04 +415 1.130000e+00 1.711139e-04 +416 1.140000e+00 1.728760e-04 +417 1.150000e+00 1.746171e-04 +418 1.160000e+00 1.763373e-04 +419 1.170000e+00 1.780370e-04 +420 1.180000e+00 1.797165e-04 +421 1.190000e+00 1.813761e-04 +422 1.200000e+00 1.830159e-04 +423 1.210000e+00 1.846363e-04 +424 1.220000e+00 1.862376e-04 +425 1.230000e+00 1.878201e-04 +426 1.240000e+00 1.893838e-04 +427 1.250000e+00 1.909293e-04 +428 1.260000e+00 1.924566e-04 +429 1.270000e+00 1.939660e-04 +430 1.280000e+00 1.954579e-04 +431 1.290000e+00 1.969323e-04 +432 1.300000e+00 1.983896e-04 +433 1.310000e+00 1.998299e-04 +434 1.320000e+00 2.012536e-04 +435 1.330000e+00 2.026607e-04 +436 1.340000e+00 2.040516e-04 +437 1.350000e+00 2.054265e-04 +438 1.360000e+00 2.067856e-04 +439 1.370000e+00 2.081290e-04 +440 1.380000e+00 2.094570e-04 +441 1.390000e+00 2.107698e-04 +442 1.400000e+00 2.120676e-04 +443 1.410000e+00 2.133506e-04 +444 1.420000e+00 2.146189e-04 +445 1.430000e+00 2.158728e-04 +446 1.440000e+00 2.171125e-04 +447 1.450000e+00 2.183381e-04 +448 1.460000e+00 2.195498e-04 +449 1.470000e+00 2.207478e-04 +450 1.480000e+00 2.219323e-04 +451 1.490000e+00 2.231034e-04 +452 1.500000e+00 2.242613e-04 +453 0.000000e+00 4.148791e-12 +454 1.000000e-02 5.649556e-12 +455 2.000000e-02 8.109987e-12 +456 3.000000e-02 1.163969e-11 +457 4.000000e-02 1.670208e-11 +458 5.000000e-02 2.525557e-11 +459 6.000000e-02 3.621893e-11 +460 7.000000e-02 5.192582e-11 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +461 8.000000e-02 7.441903e-11 +462 9.000000e-02 1.066149e-10 +463 1.000000e-01 1.526731e-10 +464 1.100000e-01 2.185196e-10 +465 1.200000e-01 3.125860e-10 +466 1.300000e-01 4.468504e-10 +467 1.400000e-01 6.382984e-10 +468 1.500000e-01 9.109662e-10 +469 1.600000e-01 1.298763e-09 +470 1.700000e-01 1.849255e-09 +471 1.800000e-01 2.629145e-09 +472 1.900000e-01 3.731550e-09 +473 2.000000e-01 5.285828e-09 +474 2.100000e-01 7.470732e-09 +475 2.200000e-01 1.053178e-08 +476 2.300000e-01 1.480388e-08 +477 2.400000e-01 2.074034e-08 +478 2.500000e-01 2.894946e-08 +479 2.600000e-01 4.023983e-08 +480 2.700000e-01 5.567530e-08 +481 2.800000e-01 7.664038e-08 +482 2.900000e-01 1.049166e-07 +483 3.000000e-01 1.427704e-07 +484 3.100000e-01 1.930527e-07 +485 3.200000e-01 2.593118e-07 +486 3.300000e-01 3.459211e-07 +487 3.400000e-01 4.582232e-07 +488 3.500000e-01 6.026931e-07 +489 3.600000e-01 7.871160e-07 +490 3.700000e-01 1.020773e-06 +491 3.800000e-01 1.314610e-06 +492 3.900000e-01 1.681355e-06 +493 4.000000e-01 2.135515e-06 +494 4.100000e-01 2.693183e-06 +495 4.200000e-01 3.371522e-06 +496 4.300000e-01 4.187779e-06 +497 4.400000e-01 5.157463e-06 +498 4.500000e-01 6.290913e-06 +499 4.600000e-01 7.587820e-06 +500 4.700000e-01 9.038297e-06 +501 4.800000e-01 1.064028e-05 +502 4.900000e-01 1.240074e-05 +503 5.000000e-01 1.432286e-05 +504 5.100000e-01 1.640373e-05 +505 5.200000e-01 1.863593e-05 +506 5.300000e-01 2.100897e-05 +507 5.400000e-01 2.351027e-05 +508 5.500000e-01 2.612596e-05 +509 5.600000e-01 2.884157e-05 +510 5.700000e-01 3.164254e-05 +511 5.800000e-01 3.448143e-05 +512 5.900000e-01 3.741796e-05 +513 6.000000e-01 4.039924e-05 +514 6.100000e-01 4.341382e-05 +515 6.200000e-01 4.645139e-05 +516 6.300000e-01 4.950287e-05 +517 6.400000e-01 5.256030e-05 +518 6.500000e-01 5.561680e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +519 6.600000e-01 5.866648e-05 +520 6.700000e-01 6.170434e-05 +521 6.800000e-01 6.472618e-05 +522 6.900000e-01 6.772848e-05 +523 7.000000e-01 7.070836e-05 +524 7.100000e-01 7.366345e-05 +525 7.200000e-01 7.659182e-05 +526 7.300000e-01 7.949196e-05 +527 7.400000e-01 8.236265e-05 +528 7.500000e-01 8.520297e-05 +529 7.600000e-01 8.801224e-05 +530 7.700000e-01 9.078995e-05 +531 7.800000e-01 9.353578e-05 +532 7.900000e-01 9.624952e-05 +533 8.000000e-01 9.893110e-05 +534 8.100000e-01 1.015805e-04 +535 8.200000e-01 1.041979e-04 +536 8.300000e-01 1.067833e-04 +537 8.400000e-01 1.093370e-04 +538 8.500000e-01 1.118593e-04 +539 8.600000e-01 1.143504e-04 +540 8.700000e-01 1.168105e-04 +541 8.800000e-01 1.192401e-04 +542 8.900000e-01 1.216395e-04 +543 9.000000e-01 1.240090e-04 +544 9.100000e-01 1.263490e-04 +545 9.200000e-01 1.286599e-04 +546 9.300000e-01 1.309420e-04 +547 9.400000e-01 1.331958e-04 +548 9.500000e-01 1.354215e-04 +549 9.600000e-01 1.376197e-04 +550 9.700000e-01 1.397905e-04 +551 9.800000e-01 1.419346e-04 +552 9.900000e-01 1.440521e-04 +553 1.000000e+00 1.461435e-04 +554 1.010000e+00 1.482091e-04 +555 1.020000e+00 1.502494e-04 +556 1.030000e+00 1.522646e-04 +557 1.040000e+00 1.542552e-04 +558 1.050000e+00 1.562214e-04 +559 1.060000e+00 1.581636e-04 +560 1.070000e+00 1.600822e-04 +561 1.080000e+00 1.619775e-04 +562 1.090000e+00 1.638498e-04 +563 1.100000e+00 1.656994e-04 +564 1.110000e+00 1.675267e-04 +565 1.120000e+00 1.693320e-04 +566 1.130000e+00 1.711155e-04 +567 1.140000e+00 1.728777e-04 +568 1.150000e+00 1.746187e-04 +569 1.160000e+00 1.763390e-04 +570 1.170000e+00 1.780387e-04 +571 1.180000e+00 1.797181e-04 +572 1.190000e+00 1.813776e-04 +573 1.200000e+00 1.830175e-04 +574 1.210000e+00 1.846379e-04 +575 1.220000e+00 1.862392e-04 +576 1.230000e+00 1.878216e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +577 1.240000e+00 1.893854e-04 +578 1.250000e+00 1.909308e-04 +579 1.260000e+00 1.924581e-04 +580 1.270000e+00 1.939675e-04 +581 1.280000e+00 1.954593e-04 +582 1.290000e+00 1.969338e-04 +583 1.300000e+00 1.983910e-04 +584 1.310000e+00 1.998314e-04 +585 1.320000e+00 2.012550e-04 +586 1.330000e+00 2.026622e-04 +587 1.340000e+00 2.040531e-04 +588 1.350000e+00 2.054279e-04 +589 1.360000e+00 2.067870e-04 +590 1.370000e+00 2.081304e-04 +591 1.380000e+00 2.094584e-04 +592 1.390000e+00 2.107712e-04 +593 1.400000e+00 2.120690e-04 +594 1.410000e+00 2.133519e-04 +595 1.420000e+00 2.146202e-04 +596 1.430000e+00 2.158741e-04 +597 1.440000e+00 2.171138e-04 +598 1.450000e+00 2.183394e-04 +599 1.460000e+00 2.195511e-04 +600 1.470000e+00 2.207491e-04 +601 1.480000e+00 2.219335e-04 +602 1.490000e+00 2.231046e-04 +603 1.500000e+00 2.242625e-04 +604 0.000000e+00 4.342370e-12 +605 1.000000e-02 5.848072e-12 +606 2.000000e-02 8.319404e-12 +607 3.000000e-02 1.186246e-11 +608 4.000000e-02 1.693181e-11 +609 5.000000e-02 2.548303e-11 +610 6.000000e-02 3.645059e-11 +611 7.000000e-02 5.217063e-11 +612 8.000000e-02 7.468824e-11 +613 9.000000e-02 1.069212e-10 +614 1.000000e-01 1.530310e-10 +615 1.100000e-01 2.189467e-10 +616 1.200000e-01 3.131039e-10 +617 1.300000e-01 4.474865e-10 +618 1.400000e-01 6.390874e-10 +619 1.500000e-01 9.119524e-10 +620 1.600000e-01 1.300003e-09 +621 1.700000e-01 1.850819e-09 +622 1.800000e-01 2.631125e-09 +623 1.900000e-01 3.734059e-09 +624 2.000000e-01 5.289006e-09 +625 2.100000e-01 7.474753e-09 +626 2.200000e-01 1.053686e-08 +627 2.300000e-01 1.481026e-08 +628 2.400000e-01 2.074831e-08 +629 2.500000e-01 2.895936e-08 +630 2.600000e-01 4.025203e-08 +631 2.700000e-01 5.569021e-08 +632 2.800000e-01 7.665845e-08 +633 2.900000e-01 1.049383e-07 +634 3.000000e-01 1.427963e-07 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +635 3.100000e-01 1.930834e-07 +636 3.200000e-01 2.593481e-07 +637 3.300000e-01 3.459644e-07 +638 3.400000e-01 4.582756e-07 +639 3.500000e-01 6.027579e-07 +640 3.600000e-01 7.871986e-07 +641 3.700000e-01 1.020881e-06 +642 3.800000e-01 1.314755e-06 +643 3.900000e-01 1.681552e-06 +644 4.000000e-01 2.135786e-06 +645 4.100000e-01 2.693551e-06 +646 4.200000e-01 3.372018e-06 +647 4.300000e-01 4.188435e-06 +648 4.400000e-01 5.158314e-06 +649 4.500000e-01 6.291990e-06 +650 4.600000e-01 7.589152e-06 +651 4.700000e-01 9.039911e-06 +652 4.800000e-01 1.064220e-05 +653 4.900000e-01 1.240298e-05 +654 5.000000e-01 1.432543e-05 +655 5.100000e-01 1.640662e-05 +656 5.200000e-01 1.863913e-05 +657 5.300000e-01 2.101247e-05 +658 5.400000e-01 2.351405e-05 +659 5.500000e-01 2.613000e-05 +660 5.600000e-01 2.884584e-05 +661 5.700000e-01 3.164702e-05 +662 5.800000e-01 3.448610e-05 +663 5.900000e-01 3.742278e-05 +664 6.000000e-01 4.040419e-05 +665 6.100000e-01 4.341887e-05 +666 6.200000e-01 4.645654e-05 +667 6.300000e-01 4.950808e-05 +668 6.400000e-01 5.256557e-05 +669 6.500000e-01 5.562211e-05 +670 6.600000e-01 5.867181e-05 +671 6.700000e-01 6.170969e-05 +672 6.800000e-01 6.473153e-05 +673 6.900000e-01 6.773384e-05 +674 7.000000e-01 7.071371e-05 +675 7.100000e-01 7.366879e-05 +676 7.200000e-01 7.659714e-05 +677 7.300000e-01 7.949726e-05 +678 7.400000e-01 8.236793e-05 +679 7.500000e-01 8.520822e-05 +680 7.600000e-01 8.801746e-05 +681 7.700000e-01 9.079514e-05 +682 7.800000e-01 9.354093e-05 +683 7.900000e-01 9.625464e-05 +684 8.000000e-01 9.893619e-05 +685 8.100000e-01 1.015856e-04 +686 8.200000e-01 1.042029e-04 +687 8.300000e-01 1.067883e-04 +688 8.400000e-01 1.093420e-04 +689 8.500000e-01 1.118642e-04 +690 8.600000e-01 1.143552e-04 +691 8.700000e-01 1.168154e-04 +692 8.800000e-01 1.192449e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +693 8.900000e-01 1.216443e-04 +694 9.000000e-01 1.240137e-04 +695 9.100000e-01 1.263537e-04 +696 9.200000e-01 1.286645e-04 +697 9.300000e-01 1.309466e-04 +698 9.400000e-01 1.332003e-04 +699 9.500000e-01 1.354260e-04 +700 9.600000e-01 1.376241e-04 +701 9.700000e-01 1.397950e-04 +702 9.800000e-01 1.419390e-04 +703 9.900000e-01 1.440564e-04 +704 1.000000e+00 1.461478e-04 +705 1.010000e+00 1.482134e-04 +706 1.020000e+00 1.502537e-04 +707 1.030000e+00 1.522688e-04 +708 1.040000e+00 1.542594e-04 +709 1.050000e+00 1.562255e-04 +710 1.060000e+00 1.581677e-04 +711 1.070000e+00 1.600863e-04 +712 1.080000e+00 1.619815e-04 +713 1.090000e+00 1.638538e-04 +714 1.100000e+00 1.657034e-04 +715 1.110000e+00 1.675306e-04 +716 1.120000e+00 1.693359e-04 +717 1.130000e+00 1.711194e-04 +718 1.140000e+00 1.728815e-04 +719 1.150000e+00 1.746225e-04 +720 1.160000e+00 1.763427e-04 +721 1.170000e+00 1.780424e-04 +722 1.180000e+00 1.797219e-04 +723 1.190000e+00 1.813813e-04 +724 1.200000e+00 1.830212e-04 +725 1.210000e+00 1.846415e-04 +726 1.220000e+00 1.862428e-04 +727 1.230000e+00 1.878252e-04 +728 1.240000e+00 1.893889e-04 +729 1.250000e+00 1.909343e-04 +730 1.260000e+00 1.924616e-04 +731 1.270000e+00 1.939710e-04 +732 1.280000e+00 1.954628e-04 +733 1.290000e+00 1.969372e-04 +734 1.300000e+00 1.983944e-04 +735 1.310000e+00 1.998347e-04 +736 1.320000e+00 2.012583e-04 +737 1.330000e+00 2.026655e-04 +738 1.340000e+00 2.040563e-04 +739 1.350000e+00 2.054312e-04 +740 1.360000e+00 2.067902e-04 +741 1.370000e+00 2.081336e-04 +742 1.380000e+00 2.094616e-04 +743 1.390000e+00 2.107743e-04 +744 1.400000e+00 2.120721e-04 +745 1.410000e+00 2.133550e-04 +746 1.420000e+00 2.146233e-04 +747 1.430000e+00 2.158772e-04 +748 1.440000e+00 2.171168e-04 +749 1.450000e+00 2.183424e-04 +750 1.460000e+00 2.195541e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +751 1.470000e+00 2.207520e-04 +752 1.480000e+00 2.219365e-04 +753 1.490000e+00 2.231076e-04 +754 1.500000e+00 2.242654e-04 +755 0.000000e+00 1.035825e-11 +756 1.000000e-02 1.374050e-11 +757 2.000000e-02 1.904459e-11 +758 3.000000e-02 2.757713e-11 +759 4.000000e-02 3.821258e-11 +760 5.000000e-02 5.294171e-11 +761 6.000000e-02 7.333502e-11 +762 7.000000e-02 1.015622e-10 +763 8.000000e-02 1.406188e-10 +764 9.000000e-02 1.946371e-10 +765 1.000000e-01 2.693124e-10 +766 1.100000e-01 3.724855e-10 +767 1.200000e-01 5.149374e-10 +768 1.300000e-01 7.114699e-10 +769 1.400000e-01 9.823713e-10 +770 1.500000e-01 1.355395e-09 +771 1.600000e-01 1.868398e-09 +772 1.700000e-01 2.572718e-09 +773 1.800000e-01 3.538056e-09 +774 1.900000e-01 4.858667e-09 +775 2.000000e-01 6.661560e-09 +776 2.100000e-01 9.117327e-09 +777 2.200000e-01 1.245447e-08 +778 2.300000e-01 1.697864e-08 +779 2.400000e-01 2.309950e-08 +780 2.500000e-01 3.137067e-08 +781 2.600000e-01 4.255412e-08 +782 2.700000e-01 5.772124e-08 +783 2.800000e-01 7.835827e-08 +784 2.900000e-01 1.063745e-07 +785 3.000000e-01 1.440740e-07 +786 3.100000e-01 1.942644e-07 +787 3.200000e-01 2.604440e-07 +788 3.300000e-01 3.469806e-07 +789 3.400000e-01 4.592439e-07 +790 3.500000e-01 6.037297e-07 +791 3.600000e-01 7.882339e-07 +792 3.700000e-01 1.022048e-06 +793 3.800000e-01 1.316131e-06 +794 3.900000e-01 1.683226e-06 +795 4.000000e-01 2.137861e-06 +796 4.100000e-01 2.696140e-06 +797 4.200000e-01 3.375239e-06 +798 4.300000e-01 4.192406e-06 +799 4.400000e-01 5.163146e-06 +800 4.500000e-01 6.297792e-06 +801 4.600000e-01 7.596049e-06 +802 4.700000e-01 9.048061e-06 +803 4.800000e-01 1.065176e-05 +804 4.900000e-01 1.241405e-05 +805 5.000000e-01 1.433806e-05 +806 5.100000e-01 1.642081e-05 +807 5.200000e-01 1.865485e-05 +808 5.300000e-01 2.102965e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +809 5.400000e-01 2.353259e-05 +810 5.500000e-01 2.614978e-05 +811 5.600000e-01 2.886674e-05 +812 5.700000e-01 3.166891e-05 +813 5.800000e-01 3.450891e-05 +814 5.900000e-01 3.744633e-05 +815 6.000000e-01 4.042837e-05 +816 6.100000e-01 4.344357e-05 +817 6.200000e-01 4.648165e-05 +818 6.300000e-01 4.953353e-05 +819 6.400000e-01 5.259127e-05 +820 6.500000e-01 5.564800e-05 +821 6.600000e-01 5.869783e-05 +822 6.700000e-01 6.173579e-05 +823 6.800000e-01 6.475767e-05 +824 6.900000e-01 6.775997e-05 +825 7.000000e-01 7.073981e-05 +826 7.100000e-01 7.369482e-05 +827 7.200000e-01 7.662310e-05 +828 7.300000e-01 7.952311e-05 +829 7.400000e-01 8.239365e-05 +830 7.500000e-01 8.523382e-05 +831 7.600000e-01 8.804291e-05 +832 7.700000e-01 9.082044e-05 +833 7.800000e-01 9.356607e-05 +834 7.900000e-01 9.627961e-05 +835 8.000000e-01 9.896098e-05 +836 8.100000e-01 1.016102e-04 +837 8.200000e-01 1.042273e-04 +838 8.300000e-01 1.068125e-04 +839 8.400000e-01 1.093660e-04 +840 8.500000e-01 1.118881e-04 +841 8.600000e-01 1.143789e-04 +842 8.700000e-01 1.168388e-04 +843 8.800000e-01 1.192682e-04 +844 8.900000e-01 1.216674e-04 +845 9.000000e-01 1.240367e-04 +846 9.100000e-01 1.263765e-04 +847 9.200000e-01 1.286871e-04 +848 9.300000e-01 1.309690e-04 +849 9.400000e-01 1.332225e-04 +850 9.500000e-01 1.354480e-04 +851 9.600000e-01 1.376460e-04 +852 9.700000e-01 1.398166e-04 +853 9.800000e-01 1.419604e-04 +854 9.900000e-01 1.440777e-04 +855 1.000000e+00 1.461689e-04 +856 1.010000e+00 1.482344e-04 +857 1.020000e+00 1.502744e-04 +858 1.030000e+00 1.522894e-04 +859 1.040000e+00 1.542798e-04 +860 1.050000e+00 1.562458e-04 +861 1.060000e+00 1.581878e-04 +862 1.070000e+00 1.601062e-04 +863 1.080000e+00 1.620012e-04 +864 1.090000e+00 1.638733e-04 +865 1.100000e+00 1.657228e-04 +866 1.110000e+00 1.675499e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +867 1.120000e+00 1.693550e-04 +868 1.130000e+00 1.711383e-04 +869 1.140000e+00 1.729003e-04 +870 1.150000e+00 1.746412e-04 +871 1.160000e+00 1.763612e-04 +872 1.170000e+00 1.780607e-04 +873 1.180000e+00 1.797400e-04 +874 1.190000e+00 1.813994e-04 +875 1.200000e+00 1.830390e-04 +876 1.210000e+00 1.846593e-04 +877 1.220000e+00 1.862604e-04 +878 1.230000e+00 1.878426e-04 +879 1.240000e+00 1.894062e-04 +880 1.250000e+00 1.909515e-04 +881 1.260000e+00 1.924786e-04 +882 1.270000e+00 1.939879e-04 +883 1.280000e+00 1.954795e-04 +884 1.290000e+00 1.969538e-04 +885 1.300000e+00 1.984109e-04 +886 1.310000e+00 1.998511e-04 +887 1.320000e+00 2.012745e-04 +888 1.330000e+00 2.026816e-04 +889 1.340000e+00 2.040723e-04 +890 1.350000e+00 2.054470e-04 +891 1.360000e+00 2.068059e-04 +892 1.370000e+00 2.081492e-04 +893 1.380000e+00 2.094770e-04 +894 1.390000e+00 2.107897e-04 +895 1.400000e+00 2.120873e-04 +896 1.410000e+00 2.133701e-04 +897 1.420000e+00 2.146383e-04 +898 1.430000e+00 2.158921e-04 +899 1.440000e+00 2.171316e-04 +900 1.450000e+00 2.183570e-04 +901 1.460000e+00 2.195686e-04 +902 1.470000e+00 2.207665e-04 +903 1.480000e+00 2.219508e-04 +904 1.490000e+00 2.231218e-04 +905 1.500000e+00 2.242795e-04 +906 0.000000e+00 2.888814e-11 +907 1.000000e-02 3.985200e-11 +908 2.000000e-02 5.497377e-11 +909 3.000000e-02 7.582477e-11 +910 4.000000e-02 1.045667e-10 +911 5.000000e-02 1.441716e-10 +912 6.000000e-02 1.987217e-10 +913 7.000000e-02 2.738195e-10 +914 8.000000e-02 3.771447e-10 +915 9.000000e-02 5.192109e-10 +916 1.000000e-01 7.143893e-10 +917 1.100000e-01 9.822894e-10 +918 1.200000e-01 1.349613e-09 +919 1.300000e-01 1.852634e-09 +920 1.400000e-01 2.540492e-09 +921 1.500000e-01 3.479546e-09 +922 1.600000e-01 4.759021e-09 +923 1.700000e-01 6.497972e-09 +924 1.800000e-01 8.855179e-09 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +925 1.900000e-01 1.204107e-08 +926 2.000000e-01 1.633276e-08 +927 2.100000e-01 2.209272e-08 +928 2.200000e-01 2.979157e-08 +929 2.300000e-01 4.003547e-08 +930 2.400000e-01 5.359841e-08 +931 2.500000e-01 7.145981e-08 +932 2.600000e-01 9.484748e-08 +933 2.700000e-01 1.252861e-07 +934 2.800000e-01 1.646516e-07 +935 2.900000e-01 2.152318e-07 +936 3.000000e-01 2.797944e-07 +937 3.100000e-01 3.616633e-07 +938 3.200000e-01 4.648060e-07 +939 3.300000e-01 5.939315e-07 +940 3.400000e-01 7.546012e-07 +941 3.500000e-01 9.533483e-07 +942 3.600000e-01 1.197800e-06 +943 3.700000e-01 1.496793e-06 +944 3.800000e-01 1.860454e-06 +945 3.900000e-01 2.300243e-06 +946 4.000000e-01 2.828906e-06 +947 4.100000e-01 3.460354e-06 +948 4.200000e-01 4.209458e-06 +949 4.300000e-01 5.091849e-06 +950 4.400000e-01 6.123857e-06 +951 4.500000e-01 7.322601e-06 +952 4.600000e-01 8.704781e-06 +953 4.700000e-01 1.028153e-05 +954 4.800000e-01 1.205570e-05 +955 4.900000e-01 1.402401e-05 +956 5.000000e-01 1.617661e-05 +957 5.100000e-01 1.849841e-05 +958 5.200000e-01 2.097175e-05 +959 5.300000e-01 2.357818e-05 +960 5.400000e-01 2.629938e-05 +961 5.500000e-01 2.911767e-05 +962 5.600000e-01 3.201639e-05 +963 5.700000e-01 3.495007e-05 +964 5.800000e-01 3.797144e-05 +965 5.900000e-01 4.103021e-05 +966 6.000000e-01 4.411506e-05 +967 6.100000e-01 4.721604e-05 +968 6.200000e-01 5.032449e-05 +969 6.300000e-01 5.343296e-05 +970 6.400000e-01 5.653509e-05 +971 6.500000e-01 5.962550e-05 +972 6.600000e-01 6.269969e-05 +973 6.700000e-01 6.575390e-05 +974 6.800000e-01 6.878506e-05 +975 6.900000e-01 7.179063e-05 +976 7.000000e-01 7.476860e-05 +977 7.100000e-01 7.771735e-05 +978 7.200000e-01 8.063561e-05 +979 7.300000e-01 8.352244e-05 +980 7.400000e-01 8.637711e-05 +981 7.500000e-01 8.919913e-05 +982 7.600000e-01 9.198815e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +983 7.700000e-01 9.474399e-05 +984 7.800000e-01 9.746659e-05 +985 7.900000e-01 1.001560e-04 +986 8.000000e-01 1.028123e-04 +987 8.100000e-01 1.054356e-04 +988 8.200000e-01 1.080263e-04 +989 8.300000e-01 1.105845e-04 +990 8.400000e-01 1.131106e-04 +991 8.500000e-01 1.156049e-04 +992 8.600000e-01 1.180678e-04 +993 8.700000e-01 1.204996e-04 +994 8.800000e-01 1.229008e-04 +995 8.900000e-01 1.252716e-04 +996 9.000000e-01 1.276126e-04 +997 9.100000e-01 1.299241e-04 +998 9.200000e-01 1.322065e-04 +999 9.300000e-01 1.344602e-04 +1000 9.400000e-01 1.366856e-04 +1001 9.500000e-01 1.388832e-04 +1002 9.600000e-01 1.410533e-04 +1003 9.700000e-01 1.431962e-04 +1004 9.800000e-01 1.453125e-04 +1005 9.900000e-01 1.474025e-04 +1006 1.000000e+00 1.494665e-04 +1007 1.010000e+00 1.515050e-04 +1008 1.020000e+00 1.535183e-04 +1009 1.030000e+00 1.555068e-04 +1010 1.040000e+00 1.574708e-04 +1011 1.050000e+00 1.594106e-04 +1012 1.060000e+00 1.613268e-04 +1013 1.070000e+00 1.632195e-04 +1014 1.080000e+00 1.650891e-04 +1015 1.090000e+00 1.669360e-04 +1016 1.100000e+00 1.687604e-04 +1017 1.110000e+00 1.705627e-04 +1018 1.120000e+00 1.723433e-04 +1019 1.130000e+00 1.741023e-04 +1020 1.140000e+00 1.758402e-04 +1021 1.150000e+00 1.775573e-04 +1022 1.160000e+00 1.792537e-04 +1023 1.170000e+00 1.809298e-04 +1024 1.180000e+00 1.825860e-04 +1025 1.190000e+00 1.842224e-04 +1026 1.200000e+00 1.858393e-04 +1027 1.210000e+00 1.874371e-04 +1028 1.220000e+00 1.890160e-04 +1029 1.230000e+00 1.905762e-04 +1030 1.240000e+00 1.921180e-04 +1031 1.250000e+00 1.936417e-04 +1032 1.260000e+00 1.951475e-04 +1033 1.270000e+00 1.966356e-04 +1034 1.280000e+00 1.981063e-04 +1035 1.290000e+00 1.995598e-04 +1036 1.300000e+00 2.009964e-04 +1037 1.310000e+00 2.024163e-04 +1038 1.320000e+00 2.038197e-04 +1039 1.330000e+00 2.052068e-04 +1040 1.340000e+00 2.065779e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1041 1.350000e+00 2.079331e-04 +1042 1.360000e+00 2.092727e-04 +1043 1.370000e+00 2.105969e-04 +1044 1.380000e+00 2.119058e-04 +1045 1.390000e+00 2.131998e-04 +1046 1.400000e+00 2.144789e-04 +1047 1.410000e+00 2.157434e-04 +1048 1.420000e+00 2.169934e-04 +1049 1.430000e+00 2.182292e-04 +1050 1.440000e+00 2.194510e-04 +1051 1.450000e+00 2.206588e-04 +1052 1.460000e+00 2.218530e-04 +1053 1.470000e+00 2.230336e-04 +1054 1.480000e+00 2.242009e-04 +1055 1.490000e+00 2.253549e-04 +1056 1.500000e+00 2.264960e-04 +1057 0.000000e+00 9.353506e-11 +1058 1.000000e-02 1.279145e-10 +1059 2.000000e-02 1.750465e-10 +1060 3.000000e-02 2.396334e-10 +1061 4.000000e-02 3.280945e-10 +1062 5.000000e-02 4.491831e-10 +1063 6.000000e-02 6.148191e-10 +1064 7.000000e-02 8.412100e-10 +1065 8.000000e-02 1.150353e-09 +1066 9.000000e-02 1.572042e-09 +1067 1.000000e-01 2.146534e-09 +1068 1.100000e-01 2.928076e-09 +1069 1.200000e-01 3.989531e-09 +1070 1.300000e-01 5.428422e-09 +1071 1.400000e-01 7.374732e-09 +1072 1.500000e-01 1.000091e-08 +1073 1.600000e-01 1.353437e-08 +1074 1.700000e-01 1.827214e-08 +1075 1.800000e-01 2.460148e-08 +1076 1.900000e-01 3.302316e-08 +1077 2.000000e-01 4.417953e-08 +1078 2.100000e-01 5.888767e-08 +1079 2.200000e-01 7.817794e-08 +1080 2.300000e-01 1.033380e-07 +1081 2.400000e-01 1.359629e-07 +1082 2.500000e-01 1.780104e-07 +1083 2.600000e-01 2.318645e-07 +1084 2.700000e-01 3.004048e-07 +1085 2.800000e-01 3.870860e-07 +1086 2.900000e-01 4.960270e-07 +1087 3.000000e-01 6.321102e-07 +1088 3.100000e-01 8.010920e-07 +1089 3.200000e-01 1.009717e-06 +1090 3.300000e-01 1.265831e-06 +1091 3.400000e-01 1.578474e-06 +1092 3.500000e-01 1.957932e-06 +1093 3.600000e-01 2.415719e-06 +1094 3.700000e-01 2.964459e-06 +1095 3.800000e-01 3.617623e-06 +1096 3.900000e-01 4.389115e-06 +1097 4.000000e-01 5.292685e-06 +1098 4.100000e-01 6.341219e-06 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1099 4.200000e-01 7.545935e-06 +1100 4.300000e-01 8.915619e-06 +1101 4.400000e-01 1.045596e-05 +1102 4.500000e-01 1.216909e-05 +1103 4.600000e-01 1.405338e-05 +1104 4.700000e-01 1.610353e-05 +1105 4.800000e-01 1.831121e-05 +1106 4.900000e-01 2.066572e-05 +1107 5.000000e-01 2.315455e-05 +1108 5.100000e-01 2.576403e-05 +1109 5.200000e-01 2.847997e-05 +1110 5.300000e-01 3.128834e-05 +1111 5.400000e-01 3.417569e-05 +1112 5.500000e-01 3.709826e-05 +1113 5.600000e-01 4.011279e-05 +1114 5.700000e-01 4.317202e-05 +1115 5.800000e-01 4.626735e-05 +1116 5.900000e-01 4.939112e-05 +1117 6.000000e-01 5.253592e-05 +1118 6.100000e-01 5.569386e-05 +1119 6.200000e-01 5.885626e-05 +1120 6.300000e-01 6.201413e-05 +1121 6.400000e-01 6.515914e-05 +1122 6.500000e-01 6.828434e-05 +1123 6.600000e-01 7.138439e-05 +1124 6.700000e-01 7.445536e-05 +1125 6.800000e-01 7.749444e-05 +1126 6.900000e-01 8.049965e-05 +1127 7.000000e-01 8.346967e-05 +1128 7.100000e-01 8.640361e-05 +1129 7.200000e-01 8.930097e-05 +1130 7.300000e-01 9.216148e-05 +1131 7.400000e-01 9.498508e-05 +1132 7.500000e-01 9.777186e-05 +1133 7.600000e-01 1.005220e-04 +1134 7.700000e-01 1.032359e-04 +1135 7.800000e-01 1.059138e-04 +1136 7.900000e-01 1.085561e-04 +1137 8.000000e-01 1.111634e-04 +1138 8.100000e-01 1.137360e-04 +1139 8.200000e-01 1.162744e-04 +1140 8.300000e-01 1.187792e-04 +1141 8.400000e-01 1.212509e-04 +1142 8.500000e-01 1.236899e-04 +1143 8.600000e-01 1.260968e-04 +1144 8.700000e-01 1.284721e-04 +1145 8.800000e-01 1.308162e-04 +1146 8.900000e-01 1.331297e-04 +1147 9.000000e-01 1.354132e-04 +1148 9.100000e-01 1.376669e-04 +1149 9.200000e-01 1.398915e-04 +1150 9.300000e-01 1.420874e-04 +1151 9.400000e-01 1.442551e-04 +1152 9.500000e-01 1.463949e-04 +1153 9.600000e-01 1.485075e-04 +1154 9.700000e-01 1.505931e-04 +1155 9.800000e-01 1.526522e-04 +1156 9.900000e-01 1.546852e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1157 1.000000e+00 1.566926e-04 +1158 1.010000e+00 1.586748e-04 +1159 1.020000e+00 1.606320e-04 +1160 1.030000e+00 1.625648e-04 +1161 1.040000e+00 1.644735e-04 +1162 1.050000e+00 1.663584e-04 +1163 1.060000e+00 1.682199e-04 +1164 1.070000e+00 1.700585e-04 +1165 1.080000e+00 1.718743e-04 +1166 1.090000e+00 1.736678e-04 +1167 1.100000e+00 1.754393e-04 +1168 1.110000e+00 1.771892e-04 +1169 1.120000e+00 1.789176e-04 +1170 1.130000e+00 1.806251e-04 +1171 1.140000e+00 1.823118e-04 +1172 1.150000e+00 1.839780e-04 +1173 1.160000e+00 1.856242e-04 +1174 1.170000e+00 1.872505e-04 +1175 1.180000e+00 1.888572e-04 +1176 1.190000e+00 1.904446e-04 +1177 1.200000e+00 1.920131e-04 +1178 1.210000e+00 1.935628e-04 +1179 1.220000e+00 1.950941e-04 +1180 1.230000e+00 1.966071e-04 +1181 1.240000e+00 1.981022e-04 +1182 1.250000e+00 1.995796e-04 +1183 1.260000e+00 2.010396e-04 +1184 1.270000e+00 2.024823e-04 +1185 1.280000e+00 2.039081e-04 +1186 1.290000e+00 2.053171e-04 +1187 1.300000e+00 2.067096e-04 +1188 1.310000e+00 2.080858e-04 +1189 1.320000e+00 2.094460e-04 +1190 1.330000e+00 2.107903e-04 +1191 1.340000e+00 2.121190e-04 +1192 1.350000e+00 2.134322e-04 +1193 1.360000e+00 2.147303e-04 +1194 1.370000e+00 2.160133e-04 +1195 1.380000e+00 2.172815e-04 +1196 1.390000e+00 2.185351e-04 +1197 1.400000e+00 2.197743e-04 +1198 1.410000e+00 2.209992e-04 +1199 1.420000e+00 2.222101e-04 +1200 1.430000e+00 2.234071e-04 +1201 1.440000e+00 2.245905e-04 +1202 1.450000e+00 2.257603e-04 +1203 1.460000e+00 2.269168e-04 +1204 1.470000e+00 2.280602e-04 +1205 1.480000e+00 2.291905e-04 +1206 1.490000e+00 2.303081e-04 +1207 1.500000e+00 2.314129e-04 +1208 0.000000e+00 3.853291e-10 +1209 1.000000e-02 5.115682e-10 +1210 2.000000e-02 6.831691e-10 +1211 3.000000e-02 9.162574e-10 +1212 4.000000e-02 1.232590e-09 +1213 5.000000e-02 1.661468e-09 +1214 6.000000e-02 2.242261e-09 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1215 7.000000e-02 3.027733e-09 +1216 8.000000e-02 4.088398e-09 +1217 9.000000e-02 5.518170e-09 +1218 1.000000e-01 7.441664e-09 +1219 1.100000e-01 1.002352e-08 +1220 1.200000e-01 1.348020e-08 +1221 1.300000e-01 1.809483e-08 +1222 1.400000e-01 2.423546e-08 +1223 1.500000e-01 3.237750e-08 +1224 1.600000e-01 4.313011e-08 +1225 1.700000e-01 5.726476e-08 +1226 1.800000e-01 7.575602e-08 +1227 1.900000e-01 9.982342e-08 +1228 2.000000e-01 1.309796e-07 +1229 2.100000e-01 1.710852e-07 +1230 2.200000e-01 2.224108e-07 +1231 2.300000e-01 2.877061e-07 +1232 2.400000e-01 3.702785e-07 +1233 2.500000e-01 4.740812e-07 +1234 2.600000e-01 6.038112e-07 +1235 2.700000e-01 7.650179e-07 +1236 2.800000e-01 9.642163e-07 +1237 2.900000e-01 1.209000e-06 +1238 3.000000e-01 1.508136e-06 +1239 3.100000e-01 1.871627e-06 +1240 3.200000e-01 2.310709e-06 +1241 3.300000e-01 2.837751e-06 +1242 3.400000e-01 3.466032e-06 +1243 3.500000e-01 4.209363e-06 +1244 3.600000e-01 5.081545e-06 +1245 3.700000e-01 6.095690e-06 +1246 3.800000e-01 7.263442e-06 +1247 3.900000e-01 8.594197e-06 +1248 4.000000e-01 1.009442e-05 +1249 4.100000e-01 1.176714e-05 +1250 4.200000e-01 1.361174e-05 +1251 4.300000e-01 1.562402e-05 +1252 4.400000e-01 1.779649e-05 +1253 4.500000e-01 2.011889e-05 +1254 4.600000e-01 2.257882e-05 +1255 4.700000e-01 2.516240e-05 +1256 4.800000e-01 2.785503e-05 +1257 4.900000e-01 3.064202e-05 +1258 5.000000e-01 3.350892e-05 +1259 5.100000e-01 3.641112e-05 +1260 5.200000e-01 3.940360e-05 +1261 5.300000e-01 4.243685e-05 +1262 5.400000e-01 4.550008e-05 +1263 5.500000e-01 4.858376e-05 +1264 5.600000e-01 5.167949e-05 +1265 5.700000e-01 5.478002e-05 +1266 5.800000e-01 5.787913e-05 +1267 5.900000e-01 6.097156e-05 +1268 6.000000e-01 6.405293e-05 +1269 6.100000e-01 6.711962e-05 +1270 6.200000e-01 7.016871e-05 +1271 6.300000e-01 7.319789e-05 +1272 6.400000e-01 7.620537e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1273 6.500000e-01 7.918981e-05 +1274 6.600000e-01 8.215019e-05 +1275 6.700000e-01 8.508571e-05 +1276 6.800000e-01 8.799571e-05 +1277 6.900000e-01 9.087949e-05 +1278 7.000000e-01 9.373626e-05 +1279 7.100000e-01 9.656507e-05 +1280 7.200000e-01 9.936481e-05 +1281 7.300000e-01 1.021343e-04 +1282 7.400000e-01 1.048725e-04 +1283 7.500000e-01 1.075784e-04 +1284 7.600000e-01 1.102513e-04 +1285 7.700000e-01 1.128906e-04 +1286 7.800000e-01 1.154960e-04 +1287 7.900000e-01 1.180675e-04 +1288 8.000000e-01 1.206049e-04 +1289 8.100000e-01 1.231086e-04 +1290 8.200000e-01 1.255788e-04 +1291 8.300000e-01 1.280158e-04 +1292 8.400000e-01 1.304200e-04 +1293 8.500000e-01 1.327919e-04 +1294 8.600000e-01 1.351319e-04 +1295 8.700000e-01 1.374406e-04 +1296 8.800000e-01 1.397183e-04 +1297 8.900000e-01 1.419657e-04 +1298 9.000000e-01 1.441832e-04 +1299 9.100000e-01 1.463712e-04 +1300 9.200000e-01 1.485303e-04 +1301 9.300000e-01 1.506610e-04 +1302 9.400000e-01 1.527638e-04 +1303 9.500000e-01 1.548391e-04 +1304 9.600000e-01 1.568873e-04 +1305 9.700000e-01 1.589090e-04 +1306 9.800000e-01 1.609045e-04 +1307 9.900000e-01 1.628743e-04 +1308 1.000000e+00 1.648189e-04 +1309 1.010000e+00 1.667386e-04 +1310 1.020000e+00 1.686338e-04 +1311 1.030000e+00 1.705050e-04 +1312 1.040000e+00 1.723525e-04 +1313 1.050000e+00 1.741767e-04 +1314 1.060000e+00 1.759780e-04 +1315 1.070000e+00 1.777567e-04 +1316 1.080000e+00 1.795132e-04 +1317 1.090000e+00 1.812478e-04 +1318 1.100000e+00 1.829609e-04 +1319 1.110000e+00 1.846529e-04 +1320 1.120000e+00 1.863239e-04 +1321 1.130000e+00 1.879744e-04 +1322 1.140000e+00 1.896046e-04 +1323 1.150000e+00 1.912149e-04 +1324 1.160000e+00 1.928056e-04 +1325 1.170000e+00 1.943769e-04 +1326 1.180000e+00 1.959292e-04 +1327 1.190000e+00 1.974626e-04 +1328 1.200000e+00 1.989776e-04 +1329 1.210000e+00 2.004743e-04 +1330 1.220000e+00 2.019531e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1331 1.230000e+00 2.034141e-04 +1332 1.240000e+00 2.048577e-04 +1333 1.250000e+00 2.062840e-04 +1334 1.260000e+00 2.076934e-04 +1335 1.270000e+00 2.090861e-04 +1336 1.280000e+00 2.104622e-04 +1337 1.290000e+00 2.118221e-04 +1338 1.300000e+00 2.131660e-04 +1339 1.310000e+00 2.144940e-04 +1340 1.320000e+00 2.158064e-04 +1341 1.330000e+00 2.171035e-04 +1342 1.340000e+00 2.183854e-04 +1343 1.350000e+00 2.196523e-04 +1344 1.360000e+00 2.209044e-04 +1345 1.370000e+00 2.221420e-04 +1346 1.380000e+00 2.233653e-04 +1347 1.390000e+00 2.245743e-04 +1348 1.400000e+00 2.257694e-04 +1349 1.410000e+00 2.269506e-04 +1350 1.420000e+00 2.281182e-04 +1351 1.430000e+00 2.292724e-04 +1352 1.440000e+00 2.304134e-04 +1353 1.450000e+00 2.315412e-04 +1354 1.460000e+00 2.326561e-04 +1355 1.470000e+00 2.337583e-04 +1356 1.480000e+00 2.348479e-04 +1357 1.490000e+00 2.359250e-04 +1358 1.500000e+00 2.369899e-04 + + + + diff --git a/tests/bsim3soidd/t5.cir b/tests/bsim3soidd/t5.cir new file mode 100644 index 000000000..8d27cb729 --- /dev/null +++ b/tests/bsim3soidd/t5.cir @@ -0,0 +1,16 @@ +*model = BSIMSOI (DD) +*Berkeley Spice Compatibility +* +* SOI NMOSFET, floating body simulation + +vd d 0 dc 0.05 +vs s 0 dc 0 +ve e 0 dc 0 +vg g 0 dc 3 + +m1 d g s e n1 w=10u l=0.25u + +.option gmin=1e-25 itl1=500 +.dc vg 0 1.5 0.01 ve -4 4 1 +.print dc i(vs) +.include nmosdd.mod diff --git a/tests/bsim3soidd/t5.out b/tests/bsim3soidd/t5.out new file mode 100644 index 000000000..8ecbfc1d7 --- /dev/null +++ b/tests/bsim3soidd/t5.out @@ -0,0 +1,1444 @@ + Reference value : 2.80000e-01 +No. of Data Rows : 1359 + +Circuit: *model = BSIMSOI (DD) + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. + *model = BSIMSOI (DD) +-------------------------------------------------------------------------------- +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 2.064981e-12 +1 1.000000e-02 2.750966e-12 +2 2.000000e-02 3.834753e-12 +3 3.000000e-02 5.345268e-12 +4 4.000000e-02 7.450202e-12 +5 5.000000e-02 1.038322e-11 +6 6.000000e-02 1.446957e-11 +7 7.000000e-02 2.016188e-11 +8 8.000000e-02 2.938743e-11 +9 9.000000e-02 4.093474e-11 +10 1.000000e-01 5.700856e-11 +11 1.100000e-01 7.937633e-11 +12 1.200000e-01 1.104912e-10 +13 1.300000e-01 1.537552e-10 +14 1.400000e-01 2.138818e-10 +15 1.500000e-01 2.973940e-10 +16 1.600000e-01 4.133010e-10 +17 1.700000e-01 5.739877e-10 +18 1.800000e-01 7.965107e-10 +19 1.900000e-01 1.104291e-09 +20 2.000000e-01 1.529397e-09 +21 2.100000e-01 2.115610e-09 +22 2.200000e-01 2.922495e-09 +23 2.300000e-01 4.030771e-09 +24 2.400000e-01 5.549341e-09 +25 2.500000e-01 7.624372e-09 +26 2.600000e-01 1.045092e-08 +27 2.700000e-01 1.428761e-08 +28 2.800000e-01 1.947483e-08 +29 2.900000e-01 2.645706e-08 +30 3.000000e-01 3.580963e-08 +31 3.100000e-01 4.827032e-08 +32 3.200000e-01 6.477582e-08 +33 3.300000e-01 8.650332e-08 +34 3.400000e-01 1.149169e-07 +35 3.500000e-01 1.518190e-07 +36 3.600000e-01 1.994073e-07 +37 3.700000e-01 2.603381e-07 +38 3.800000e-01 3.377970e-07 +39 3.900000e-01 4.355794e-07 +40 4.000000e-01 5.581821e-07 +41 4.100000e-01 7.108746e-07 +42 4.200000e-01 8.996268e-07 +43 4.300000e-01 1.131406e-06 +44 4.400000e-01 1.414288e-06 +45 4.500000e-01 1.757461e-06 +46 4.600000e-01 2.171230e-06 +47 4.700000e-01 2.666926e-06 +48 4.800000e-01 3.256704e-06 +49 4.900000e-01 3.953195e-06 +50 5.000000e-01 4.769004e-06 +51 5.100000e-01 5.716084e-06 +52 5.200000e-01 6.805016e-06 +53 5.300000e-01 8.044296e-06 +54 5.400000e-01 9.439702e-06 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +55 5.500000e-01 1.099386e-05 +56 5.600000e-01 1.270604e-05 +57 5.700000e-01 1.457225e-05 +58 5.800000e-01 1.658558e-05 +59 5.900000e-01 1.873680e-05 +60 6.000000e-01 2.101516e-05 +61 6.100000e-01 2.340955e-05 +62 6.200000e-01 2.591048e-05 +63 6.300000e-01 2.851274e-05 +64 6.400000e-01 3.121346e-05 +65 6.500000e-01 3.400052e-05 +66 6.600000e-01 3.682399e-05 +67 6.700000e-01 3.973373e-05 +68 6.800000e-01 4.267639e-05 +69 6.900000e-01 4.564151e-05 +70 7.000000e-01 4.862013e-05 +71 7.100000e-01 5.160457e-05 +72 7.200000e-01 5.458823e-05 +73 7.300000e-01 5.756553e-05 +74 7.400000e-01 6.053177e-05 +75 7.500000e-01 6.348300e-05 +76 7.600000e-01 6.641595e-05 +77 7.700000e-01 6.932793e-05 +78 7.800000e-01 7.221673e-05 +79 7.900000e-01 7.508055e-05 +80 8.000000e-01 7.791798e-05 +81 8.100000e-01 8.072789e-05 +82 8.200000e-01 8.350941e-05 +83 8.300000e-01 8.626190e-05 +84 8.400000e-01 8.898488e-05 +85 8.500000e-01 9.167803e-05 +86 8.600000e-01 9.434117e-05 +87 8.700000e-01 9.697422e-05 +88 8.800000e-01 9.957718e-05 +89 8.900000e-01 1.021501e-04 +90 9.000000e-01 1.046932e-04 +91 9.100000e-01 1.072067e-04 +92 9.200000e-01 1.096907e-04 +93 9.300000e-01 1.121456e-04 +94 9.400000e-01 1.145716e-04 +95 9.500000e-01 1.169692e-04 +96 9.600000e-01 1.193386e-04 +97 9.700000e-01 1.216802e-04 +98 9.800000e-01 1.239944e-04 +99 9.900000e-01 1.262816e-04 +100 1.000000e+00 1.285421e-04 +101 1.010000e+00 1.307764e-04 +102 1.020000e+00 1.329848e-04 +103 1.030000e+00 1.351677e-04 +104 1.040000e+00 1.373255e-04 +105 1.050000e+00 1.394584e-04 +106 1.060000e+00 1.415668e-04 +107 1.070000e+00 1.436509e-04 +108 1.080000e+00 1.457110e-04 +109 1.090000e+00 1.477474e-04 +110 1.100000e+00 1.497601e-04 +111 1.110000e+00 1.517494e-04 +112 1.120000e+00 1.537155e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +113 1.130000e+00 1.556586e-04 +114 1.140000e+00 1.575788e-04 +115 1.150000e+00 1.594762e-04 +116 1.160000e+00 1.613512e-04 +117 1.170000e+00 1.632039e-04 +118 1.180000e+00 1.650344e-04 +119 1.190000e+00 1.668431e-04 +120 1.200000e+00 1.686301e-04 +121 1.210000e+00 1.703957e-04 +122 1.220000e+00 1.721401e-04 +123 1.230000e+00 1.738636e-04 +124 1.240000e+00 1.755664e-04 +125 1.250000e+00 1.772488e-04 +126 1.260000e+00 1.789111e-04 +127 1.270000e+00 1.805535e-04 +128 1.280000e+00 1.821763e-04 +129 1.290000e+00 1.837797e-04 +130 1.300000e+00 1.853640e-04 +131 1.310000e+00 1.869296e-04 +132 1.320000e+00 1.884765e-04 +133 1.330000e+00 1.900051e-04 +134 1.340000e+00 1.915157e-04 +135 1.350000e+00 1.930085e-04 +136 1.360000e+00 1.944837e-04 +137 1.370000e+00 1.959416e-04 +138 1.380000e+00 1.973823e-04 +139 1.390000e+00 1.988063e-04 +140 1.400000e+00 2.002136e-04 +141 1.410000e+00 2.016046e-04 +142 1.420000e+00 2.029794e-04 +143 1.430000e+00 2.043382e-04 +144 1.440000e+00 2.056814e-04 +145 1.450000e+00 2.070090e-04 +146 1.460000e+00 2.083214e-04 +147 1.470000e+00 2.096186e-04 +148 1.480000e+00 2.109010e-04 +149 1.490000e+00 2.121687e-04 +150 1.500000e+00 2.134218e-04 +151 0.000000e+00 2.065527e-12 +152 1.000000e-02 2.751725e-12 +153 2.000000e-02 3.835825e-12 +154 3.000000e-02 5.346726e-12 +155 4.000000e-02 7.452258e-12 +156 5.000000e-02 1.038612e-11 +157 6.000000e-02 1.447365e-11 +158 7.000000e-02 2.016763e-11 +159 8.000000e-02 2.939595e-11 +160 9.000000e-02 4.094675e-11 +161 1.000000e-01 5.702548e-11 +162 1.100000e-01 7.940017e-11 +163 1.200000e-01 1.105248e-10 +164 1.300000e-01 1.538025e-10 +165 1.400000e-01 2.139484e-10 +166 1.500000e-01 2.974877e-10 +167 1.600000e-01 4.134327e-10 +168 1.700000e-01 5.741729e-10 +169 1.800000e-01 7.967707e-10 +170 1.900000e-01 1.104655e-09 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +171 2.000000e-01 1.529908e-09 +172 2.100000e-01 2.116325e-09 +173 2.200000e-01 2.923494e-09 +174 2.300000e-01 4.032165e-09 +175 2.400000e-01 5.551280e-09 +176 2.500000e-01 7.627065e-09 +177 2.600000e-01 1.045465e-08 +178 2.700000e-01 1.429276e-08 +179 2.800000e-01 1.948192e-08 +180 2.900000e-01 2.646679e-08 +181 3.000000e-01 3.582292e-08 +182 3.100000e-01 4.828839e-08 +183 3.200000e-01 6.480030e-08 +184 3.300000e-01 8.653629e-08 +185 3.400000e-01 1.149610e-07 +186 3.500000e-01 1.518778e-07 +187 3.600000e-01 1.994843e-07 +188 3.700000e-01 2.604018e-07 +189 3.800000e-01 3.376975e-07 +190 3.900000e-01 4.350425e-07 +191 4.000000e-01 5.567666e-07 +192 4.100000e-01 7.079415e-07 +193 4.200000e-01 8.944774e-07 +194 4.300000e-01 1.123220e-06 +195 4.400000e-01 1.402039e-06 +196 4.500000e-01 1.739883e-06 +197 4.600000e-01 2.146786e-06 +198 4.700000e-01 2.633791e-06 +199 4.800000e-01 3.212758e-06 +200 4.900000e-01 3.896042e-06 +201 5.000000e-01 4.696027e-06 +202 5.100000e-01 5.624529e-06 +203 5.200000e-01 6.692127e-06 +204 5.300000e-01 7.907490e-06 +205 5.400000e-01 9.276805e-06 +206 5.500000e-01 1.080344e-05 +207 5.600000e-01 1.248799e-05 +208 5.700000e-01 1.432898e-05 +209 5.800000e-01 1.632471e-05 +210 5.900000e-01 1.847540e-05 +211 6.000000e-01 2.077826e-05 +212 6.100000e-01 2.321891e-05 +213 6.200000e-01 2.577786e-05 +214 6.300000e-01 2.843711e-05 +215 6.400000e-01 3.118050e-05 +216 6.500000e-01 3.396094e-05 +217 6.600000e-01 3.683610e-05 +218 6.700000e-01 3.975417e-05 +219 6.800000e-01 4.270408e-05 +220 6.900000e-01 4.567603e-05 +221 7.000000e-01 4.866143e-05 +222 7.100000e-01 5.165288e-05 +223 7.200000e-01 5.464401e-05 +224 7.300000e-01 5.762944e-05 +225 7.400000e-01 6.060466e-05 +226 7.500000e-01 6.356593e-05 +227 7.600000e-01 6.651019e-05 +228 7.700000e-01 6.943498e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +229 7.800000e-01 7.233835e-05 +230 7.900000e-01 7.521880e-05 +231 8.000000e-01 7.807519e-05 +232 8.100000e-01 8.090669e-05 +233 8.200000e-01 8.371268e-05 +234 8.300000e-01 8.649270e-05 +235 8.400000e-01 8.924633e-05 +236 8.500000e-01 9.197312e-05 +237 8.600000e-01 9.467258e-05 +238 8.700000e-01 9.734410e-05 +239 8.800000e-01 9.998703e-05 +240 8.900000e-01 1.026007e-04 +241 9.000000e-01 1.051846e-04 +242 9.100000e-01 1.077380e-04 +243 9.200000e-01 1.102609e-04 +244 9.300000e-01 1.127528e-04 +245 9.400000e-01 1.152137e-04 +246 9.500000e-01 1.176437e-04 +247 9.600000e-01 1.200430e-04 +248 9.700000e-01 1.224117e-04 +249 9.800000e-01 1.247502e-04 +250 9.900000e-01 1.270588e-04 +251 1.000000e+00 1.293378e-04 +252 1.010000e+00 1.315876e-04 +253 1.020000e+00 1.338087e-04 +254 1.030000e+00 1.360014e-04 +255 1.040000e+00 1.381662e-04 +256 1.050000e+00 1.403035e-04 +257 1.060000e+00 1.424137e-04 +258 1.070000e+00 1.444972e-04 +259 1.080000e+00 1.465544e-04 +260 1.090000e+00 1.485858e-04 +261 1.100000e+00 1.505918e-04 +262 1.110000e+00 1.525726e-04 +263 1.120000e+00 1.545289e-04 +264 1.130000e+00 1.564608e-04 +265 1.140000e+00 1.583689e-04 +266 1.150000e+00 1.602534e-04 +267 1.160000e+00 1.621148e-04 +268 1.170000e+00 1.639533e-04 +269 1.180000e+00 1.657694e-04 +270 1.190000e+00 1.675633e-04 +271 1.200000e+00 1.693355e-04 +272 1.210000e+00 1.710862e-04 +273 1.220000e+00 1.728157e-04 +274 1.230000e+00 1.745245e-04 +275 1.240000e+00 1.762126e-04 +276 1.250000e+00 1.778806e-04 +277 1.260000e+00 1.795287e-04 +278 1.270000e+00 1.811571e-04 +279 1.280000e+00 1.827661e-04 +280 1.290000e+00 1.843561e-04 +281 1.300000e+00 1.859273e-04 +282 1.310000e+00 1.874800e-04 +283 1.320000e+00 1.890144e-04 +284 1.330000e+00 1.905308e-04 +285 1.340000e+00 1.920294e-04 +286 1.350000e+00 1.935106e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +287 1.360000e+00 1.949744e-04 +288 1.370000e+00 1.964213e-04 +289 1.380000e+00 1.978514e-04 +290 1.390000e+00 1.992649e-04 +291 1.400000e+00 2.006620e-04 +292 1.410000e+00 2.020431e-04 +293 1.420000e+00 2.034083e-04 +294 1.430000e+00 2.047578e-04 +295 1.440000e+00 2.060919e-04 +296 1.450000e+00 2.074106e-04 +297 1.460000e+00 2.087144e-04 +298 1.470000e+00 2.100033e-04 +299 1.480000e+00 2.112775e-04 +300 1.490000e+00 2.125373e-04 +301 1.500000e+00 2.137828e-04 +302 0.000000e+00 2.066772e-12 +303 1.000000e-02 2.753407e-12 +304 2.000000e-02 3.838216e-12 +305 3.000000e-02 5.350124e-12 +306 4.000000e-02 7.457088e-12 +307 5.000000e-02 1.039299e-11 +308 6.000000e-02 1.448342e-11 +309 7.000000e-02 2.018152e-11 +310 8.000000e-02 2.941671e-11 +311 9.000000e-02 4.097628e-11 +312 1.000000e-01 5.706747e-11 +313 1.100000e-01 7.945989e-11 +314 1.200000e-01 1.106097e-10 +315 1.300000e-01 1.539232e-10 +316 1.400000e-01 2.141201e-10 +317 1.500000e-01 2.977317e-10 +318 1.600000e-01 4.137794e-10 +319 1.700000e-01 5.746652e-10 +320 1.800000e-01 7.974695e-10 +321 1.900000e-01 1.105646e-09 +322 2.000000e-01 1.531312e-09 +323 2.100000e-01 2.118313e-09 +324 2.200000e-01 2.926303e-09 +325 2.300000e-01 4.036131e-09 +326 2.400000e-01 5.556869e-09 +327 2.500000e-01 7.634925e-09 +328 2.600000e-01 1.046568e-08 +329 2.700000e-01 1.430820e-08 +330 2.800000e-01 1.950346e-08 +331 2.900000e-01 2.649674e-08 +332 3.000000e-01 3.586443e-08 +333 3.100000e-01 4.834567e-08 +334 3.200000e-01 6.487844e-08 +335 3.300000e-01 8.662492e-08 +336 3.400000e-01 1.150059e-07 +337 3.500000e-01 1.517738e-07 +338 3.600000e-01 1.990533e-07 +339 3.700000e-01 2.593955e-07 +340 3.800000e-01 3.358387e-07 +341 3.900000e-01 4.319774e-07 +342 4.000000e-01 5.520402e-07 +343 4.100000e-01 7.009767e-07 +344 4.200000e-01 8.845520e-07 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +345 4.300000e-01 1.109443e-06 +346 4.400000e-01 1.383327e-06 +347 4.500000e-01 1.714939e-06 +348 4.600000e-01 2.114095e-06 +349 4.700000e-01 2.591624e-06 +350 4.800000e-01 3.159216e-06 +351 4.900000e-01 3.829144e-06 +352 5.000000e-01 4.613877e-06 +353 5.100000e-01 5.525622e-06 +354 5.200000e-01 6.575919e-06 +355 5.300000e-01 7.775580e-06 +356 5.400000e-01 9.135477e-06 +357 5.500000e-01 1.066724e-05 +358 5.600000e-01 1.237822e-05 +359 5.700000e-01 1.426579e-05 +360 5.800000e-01 1.632211e-05 +361 5.900000e-01 1.853797e-05 +362 6.000000e-01 2.090342e-05 +363 6.100000e-01 2.340782e-05 +364 6.200000e-01 2.603975e-05 +365 6.300000e-01 2.878602e-05 +366 6.400000e-01 3.163063e-05 +367 6.500000e-01 3.455495e-05 +368 6.600000e-01 3.751266e-05 +369 6.700000e-01 4.054886e-05 +370 6.800000e-01 4.361170e-05 +371 6.900000e-01 4.668901e-05 +372 7.000000e-01 4.977105e-05 +373 7.100000e-01 5.284994e-05 +374 7.200000e-01 5.591929e-05 +375 7.300000e-01 5.897391e-05 +376 7.400000e-01 6.200960e-05 +377 7.500000e-01 6.502294e-05 +378 7.600000e-01 6.801124e-05 +379 7.700000e-01 7.097232e-05 +380 7.800000e-01 7.390449e-05 +381 7.900000e-01 7.680645e-05 +382 8.000000e-01 7.967720e-05 +383 8.100000e-01 8.251604e-05 +384 8.200000e-01 8.532245e-05 +385 8.300000e-01 8.809611e-05 +386 8.400000e-01 9.083686e-05 +387 8.500000e-01 9.354464e-05 +388 8.600000e-01 9.621949e-05 +389 8.700000e-01 9.886155e-05 +390 8.800000e-01 1.014710e-04 +391 8.900000e-01 1.040481e-04 +392 9.000000e-01 1.065931e-04 +393 9.100000e-01 1.091063e-04 +394 9.200000e-01 1.115882e-04 +395 9.300000e-01 1.140390e-04 +396 9.400000e-01 1.164591e-04 +397 9.500000e-01 1.188489e-04 +398 9.600000e-01 1.212088e-04 +399 9.700000e-01 1.235392e-04 +400 9.800000e-01 1.258405e-04 +401 9.900000e-01 1.281132e-04 +402 1.000000e+00 1.303575e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +403 1.010000e+00 1.325740e-04 +404 1.020000e+00 1.347629e-04 +405 1.030000e+00 1.369248e-04 +406 1.040000e+00 1.390600e-04 +407 1.050000e+00 1.411688e-04 +408 1.060000e+00 1.432517e-04 +409 1.070000e+00 1.453091e-04 +410 1.080000e+00 1.473412e-04 +411 1.090000e+00 1.493486e-04 +412 1.100000e+00 1.513314e-04 +413 1.110000e+00 1.532902e-04 +414 1.120000e+00 1.552252e-04 +415 1.130000e+00 1.571367e-04 +416 1.140000e+00 1.590252e-04 +417 1.150000e+00 1.608909e-04 +418 1.160000e+00 1.627342e-04 +419 1.170000e+00 1.645554e-04 +420 1.180000e+00 1.663548e-04 +421 1.190000e+00 1.681327e-04 +422 1.200000e+00 1.698894e-04 +423 1.210000e+00 1.716252e-04 +424 1.220000e+00 1.733405e-04 +425 1.230000e+00 1.750354e-04 +426 1.240000e+00 1.767104e-04 +427 1.250000e+00 1.783655e-04 +428 1.260000e+00 1.800013e-04 +429 1.270000e+00 1.816178e-04 +430 1.280000e+00 1.832154e-04 +431 1.290000e+00 1.847943e-04 +432 1.300000e+00 1.863549e-04 +433 1.310000e+00 1.878972e-04 +434 1.320000e+00 1.894216e-04 +435 1.330000e+00 1.909284e-04 +436 1.340000e+00 1.924177e-04 +437 1.350000e+00 1.938899e-04 +438 1.360000e+00 1.953451e-04 +439 1.370000e+00 1.967835e-04 +440 1.380000e+00 1.982054e-04 +441 1.390000e+00 1.996110e-04 +442 1.400000e+00 2.010006e-04 +443 1.410000e+00 2.023742e-04 +444 1.420000e+00 2.037322e-04 +445 1.430000e+00 2.050748e-04 +446 1.440000e+00 2.064021e-04 +447 1.450000e+00 2.077143e-04 +448 1.460000e+00 2.090117e-04 +449 1.470000e+00 2.102945e-04 +450 1.480000e+00 2.115627e-04 +451 1.490000e+00 2.128167e-04 +452 1.500000e+00 2.140566e-04 +453 0.000000e+00 2.072522e-12 +454 1.000000e-02 2.761350e-12 +455 2.000000e-02 3.849869e-12 +456 3.000000e-02 5.367250e-12 +457 4.000000e-02 7.482301e-12 +458 5.000000e-02 1.043018e-11 +459 6.000000e-02 1.453840e-11 +460 7.000000e-02 2.026299e-11 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +461 8.000000e-02 2.954567e-11 +462 9.000000e-02 4.116854e-11 +463 1.000000e-01 5.735505e-11 +464 1.100000e-01 7.989155e-11 +465 1.200000e-01 1.112602e-10 +466 1.300000e-01 1.549081e-10 +467 1.400000e-01 2.156189e-10 +468 1.500000e-01 3.000266e-10 +469 1.600000e-01 4.173183e-10 +470 1.700000e-01 5.801683e-10 +471 1.800000e-01 8.061148e-10 +472 1.900000e-01 1.119402e-09 +473 2.000000e-01 1.553552e-09 +474 2.100000e-01 2.155020e-09 +475 2.200000e-01 2.988527e-09 +476 2.300000e-01 4.145176e-09 +477 2.400000e-01 5.755065e-09 +478 2.500000e-01 8.004832e-09 +479 2.600000e-01 1.115475e-08 +480 2.700000e-01 1.555195e-08 +481 2.800000e-01 2.165279e-08 +482 2.900000e-01 3.005843e-08 +483 3.000000e-01 4.155874e-08 +484 3.100000e-01 5.719560e-08 +485 3.200000e-01 7.831618e-08 +486 3.300000e-01 1.066349e-07 +487 3.400000e-01 1.443092e-07 +488 3.500000e-01 1.940253e-07 +489 3.600000e-01 2.590932e-07 +490 3.700000e-01 3.435517e-07 +491 3.800000e-01 4.522870e-07 +492 3.900000e-01 5.911651e-07 +493 4.000000e-01 7.671765e-07 +494 4.100000e-01 9.885874e-07 +495 4.200000e-01 1.265079e-06 +496 4.300000e-01 1.607851e-06 +497 4.400000e-01 2.029632e-06 +498 4.500000e-01 2.544561e-06 +499 4.600000e-01 3.167847e-06 +500 4.700000e-01 3.915125e-06 +501 4.800000e-01 4.801366e-06 +502 4.900000e-01 5.839018e-06 +503 5.000000e-01 7.034884e-06 +504 5.100000e-01 8.388099e-06 +505 5.200000e-01 9.897562e-06 +506 5.300000e-01 1.156778e-05 +507 5.400000e-01 1.340158e-05 +508 5.500000e-01 1.539660e-05 +509 5.600000e-01 1.754618e-05 +510 5.700000e-01 1.984048e-05 +511 5.800000e-01 2.226739e-05 +512 5.900000e-01 2.481331e-05 +513 6.000000e-01 2.746386e-05 +514 6.100000e-01 3.020442e-05 +515 6.200000e-01 3.302065e-05 +516 6.300000e-01 3.587008e-05 +517 6.400000e-01 3.880365e-05 +518 6.500000e-01 4.177408e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +519 6.600000e-01 4.477071e-05 +520 6.700000e-01 4.778414e-05 +521 6.800000e-01 5.080610e-05 +522 6.900000e-01 5.382945e-05 +523 7.000000e-01 5.684803e-05 +524 7.100000e-01 5.985665e-05 +525 7.200000e-01 6.285092e-05 +526 7.300000e-01 6.582715e-05 +527 7.400000e-01 6.878233e-05 +528 7.500000e-01 7.171395e-05 +529 7.600000e-01 7.462001e-05 +530 7.700000e-01 7.749888e-05 +531 7.800000e-01 8.034929e-05 +532 7.900000e-01 8.317024e-05 +533 8.000000e-01 8.596098e-05 +534 8.100000e-01 8.872098e-05 +535 8.200000e-01 9.144984e-05 +536 8.300000e-01 9.414734e-05 +537 8.400000e-01 9.681336e-05 +538 8.500000e-01 9.944787e-05 +539 8.600000e-01 1.020509e-04 +540 8.700000e-01 1.046227e-04 +541 8.800000e-01 1.071633e-04 +542 8.900000e-01 1.096729e-04 +543 9.000000e-01 1.121520e-04 +544 9.100000e-01 1.146006e-04 +545 9.200000e-01 1.170191e-04 +546 9.300000e-01 1.194079e-04 +547 9.400000e-01 1.217673e-04 +548 9.500000e-01 1.240976e-04 +549 9.600000e-01 1.263993e-04 +550 9.700000e-01 1.286725e-04 +551 9.800000e-01 1.309178e-04 +552 9.900000e-01 1.331355e-04 +553 1.000000e+00 1.353260e-04 +554 1.010000e+00 1.374895e-04 +555 1.020000e+00 1.396266e-04 +556 1.030000e+00 1.417375e-04 +557 1.040000e+00 1.438226e-04 +558 1.050000e+00 1.458823e-04 +559 1.060000e+00 1.479169e-04 +560 1.070000e+00 1.499268e-04 +561 1.080000e+00 1.519123e-04 +562 1.090000e+00 1.538737e-04 +563 1.100000e+00 1.558114e-04 +564 1.110000e+00 1.577258e-04 +565 1.120000e+00 1.596171e-04 +566 1.130000e+00 1.614857e-04 +567 1.140000e+00 1.633319e-04 +568 1.150000e+00 1.651560e-04 +569 1.160000e+00 1.669583e-04 +570 1.170000e+00 1.687391e-04 +571 1.180000e+00 1.704987e-04 +572 1.190000e+00 1.722375e-04 +573 1.200000e+00 1.739556e-04 +574 1.210000e+00 1.756534e-04 +575 1.220000e+00 1.773312e-04 +576 1.230000e+00 1.789892e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +577 1.240000e+00 1.806277e-04 +578 1.250000e+00 1.822470e-04 +579 1.260000e+00 1.838473e-04 +580 1.270000e+00 1.854289e-04 +581 1.280000e+00 1.869921e-04 +582 1.290000e+00 1.885371e-04 +583 1.300000e+00 1.900641e-04 +584 1.310000e+00 1.915734e-04 +585 1.320000e+00 1.930652e-04 +586 1.330000e+00 1.945398e-04 +587 1.340000e+00 1.959973e-04 +588 1.350000e+00 1.974381e-04 +589 1.360000e+00 1.988623e-04 +590 1.370000e+00 2.002702e-04 +591 1.380000e+00 2.016619e-04 +592 1.390000e+00 2.030378e-04 +593 1.400000e+00 2.043979e-04 +594 1.410000e+00 2.057425e-04 +595 1.420000e+00 2.070718e-04 +596 1.430000e+00 2.083860e-04 +597 1.440000e+00 2.096854e-04 +598 1.450000e+00 2.109700e-04 +599 1.460000e+00 2.122400e-04 +600 1.470000e+00 2.134958e-04 +601 1.480000e+00 2.147374e-04 +602 1.490000e+00 2.159650e-04 +603 1.500000e+00 2.171788e-04 +604 0.000000e+00 4.149697e-12 +605 1.000000e-02 5.650698e-12 +606 2.000000e-02 8.111478e-12 +607 3.000000e-02 1.164165e-11 +608 4.000000e-02 1.670464e-11 +609 5.000000e-02 2.525906e-11 +610 6.000000e-02 3.622354e-11 +611 7.000000e-02 5.193193e-11 +612 8.000000e-02 7.442713e-11 +613 9.000000e-02 1.066257e-10 +614 1.000000e-01 1.526874e-10 +615 1.100000e-01 2.185387e-10 +616 1.200000e-01 3.126114e-10 +617 1.300000e-01 4.468842e-10 +618 1.400000e-01 6.383434e-10 +619 1.500000e-01 9.110261e-10 +620 1.600000e-01 1.298843e-09 +621 1.700000e-01 1.849360e-09 +622 1.800000e-01 2.629285e-09 +623 1.900000e-01 3.731735e-09 +624 2.000000e-01 5.286071e-09 +625 2.100000e-01 7.471051e-09 +626 2.200000e-01 1.053220e-08 +627 2.300000e-01 1.480442e-08 +628 2.400000e-01 2.074103e-08 +629 2.500000e-01 2.895034e-08 +630 2.600000e-01 4.024094e-08 +631 2.700000e-01 5.567669e-08 +632 2.800000e-01 7.664210e-08 +633 2.900000e-01 1.049187e-07 +634 3.000000e-01 1.427730e-07 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +635 3.100000e-01 1.930558e-07 +636 3.200000e-01 2.593155e-07 +637 3.300000e-01 3.459256e-07 +638 3.400000e-01 4.582287e-07 +639 3.500000e-01 6.027000e-07 +640 3.600000e-01 7.871250e-07 +641 3.700000e-01 1.020785e-06 +642 3.800000e-01 1.314626e-06 +643 3.900000e-01 1.681377e-06 +644 4.000000e-01 2.135546e-06 +645 4.100000e-01 2.693225e-06 +646 4.200000e-01 3.371579e-06 +647 4.300000e-01 4.187855e-06 +648 4.400000e-01 5.157563e-06 +649 4.500000e-01 6.291041e-06 +650 4.600000e-01 7.587978e-06 +651 4.700000e-01 9.038489e-06 +652 4.800000e-01 1.064051e-05 +653 4.900000e-01 1.240101e-05 +654 5.000000e-01 1.432317e-05 +655 5.100000e-01 1.640407e-05 +656 5.200000e-01 1.863631e-05 +657 5.300000e-01 2.100939e-05 +658 5.400000e-01 2.351072e-05 +659 5.500000e-01 2.612645e-05 +660 5.600000e-01 2.884208e-05 +661 5.700000e-01 3.164308e-05 +662 5.800000e-01 3.448199e-05 +663 5.900000e-01 3.741853e-05 +664 6.000000e-01 4.039983e-05 +665 6.100000e-01 4.341442e-05 +666 6.200000e-01 4.645201e-05 +667 6.300000e-01 4.950350e-05 +668 6.400000e-01 5.256093e-05 +669 6.500000e-01 5.561744e-05 +670 6.600000e-01 5.866712e-05 +671 6.700000e-01 6.170498e-05 +672 6.800000e-01 6.472682e-05 +673 6.900000e-01 6.772912e-05 +674 7.000000e-01 7.070900e-05 +675 7.100000e-01 7.366409e-05 +676 7.200000e-01 7.659246e-05 +677 7.300000e-01 7.949259e-05 +678 7.400000e-01 8.236328e-05 +679 7.500000e-01 8.520360e-05 +680 7.600000e-01 8.801287e-05 +681 7.700000e-01 9.079057e-05 +682 7.800000e-01 9.353640e-05 +683 7.900000e-01 9.625014e-05 +684 8.000000e-01 9.893171e-05 +685 8.100000e-01 1.015811e-04 +686 8.200000e-01 1.041985e-04 +687 8.300000e-01 1.067839e-04 +688 8.400000e-01 1.093376e-04 +689 8.500000e-01 1.118599e-04 +690 8.600000e-01 1.143509e-04 +691 8.700000e-01 1.168111e-04 +692 8.800000e-01 1.192407e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +693 8.900000e-01 1.216401e-04 +694 9.000000e-01 1.240096e-04 +695 9.100000e-01 1.263496e-04 +696 9.200000e-01 1.286605e-04 +697 9.300000e-01 1.309426e-04 +698 9.400000e-01 1.331963e-04 +699 9.500000e-01 1.354221e-04 +700 9.600000e-01 1.376202e-04 +701 9.700000e-01 1.397911e-04 +702 9.800000e-01 1.419351e-04 +703 9.900000e-01 1.440526e-04 +704 1.000000e+00 1.461440e-04 +705 1.010000e+00 1.482097e-04 +706 1.020000e+00 1.502499e-04 +707 1.030000e+00 1.522651e-04 +708 1.040000e+00 1.542557e-04 +709 1.050000e+00 1.562219e-04 +710 1.060000e+00 1.581641e-04 +711 1.070000e+00 1.600827e-04 +712 1.080000e+00 1.619780e-04 +713 1.090000e+00 1.638502e-04 +714 1.100000e+00 1.656999e-04 +715 1.110000e+00 1.675272e-04 +716 1.120000e+00 1.693324e-04 +717 1.130000e+00 1.711160e-04 +718 1.140000e+00 1.728781e-04 +719 1.150000e+00 1.746192e-04 +720 1.160000e+00 1.763394e-04 +721 1.170000e+00 1.780391e-04 +722 1.180000e+00 1.797186e-04 +723 1.190000e+00 1.813781e-04 +724 1.200000e+00 1.830179e-04 +725 1.210000e+00 1.846383e-04 +726 1.220000e+00 1.862396e-04 +727 1.230000e+00 1.878220e-04 +728 1.240000e+00 1.893858e-04 +729 1.250000e+00 1.909312e-04 +730 1.260000e+00 1.924585e-04 +731 1.270000e+00 1.939679e-04 +732 1.280000e+00 1.954598e-04 +733 1.290000e+00 1.969342e-04 +734 1.300000e+00 1.983914e-04 +735 1.310000e+00 1.998318e-04 +736 1.320000e+00 2.012554e-04 +737 1.330000e+00 2.026626e-04 +738 1.340000e+00 2.040535e-04 +739 1.350000e+00 2.054283e-04 +740 1.360000e+00 2.067873e-04 +741 1.370000e+00 2.081308e-04 +742 1.380000e+00 2.094588e-04 +743 1.390000e+00 2.107716e-04 +744 1.400000e+00 2.120693e-04 +745 1.410000e+00 2.133523e-04 +746 1.420000e+00 2.146206e-04 +747 1.430000e+00 2.158745e-04 +748 1.440000e+00 2.171142e-04 +749 1.450000e+00 2.183397e-04 +750 1.460000e+00 2.195514e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +751 1.470000e+00 2.207494e-04 +752 1.480000e+00 2.219339e-04 +753 1.490000e+00 2.231050e-04 +754 1.500000e+00 2.242629e-04 +755 0.000000e+00 2.039674e-11 +756 1.000000e-02 2.936285e-11 +757 2.000000e-02 4.225803e-11 +758 3.000000e-02 6.079651e-11 +759 4.000000e-02 8.743568e-11 +760 5.000000e-02 1.256951e-10 +761 6.000000e-02 1.806104e-10 +762 7.000000e-02 2.593780e-10 +763 8.000000e-02 3.722671e-10 +764 9.000000e-02 5.339088e-10 +765 1.000000e-01 7.651084e-10 +766 1.100000e-01 1.095385e-09 +767 1.200000e-01 1.566511e-09 +768 1.300000e-01 2.237422e-09 +769 1.400000e-01 3.190971e-09 +770 1.500000e-01 4.543156e-09 +771 1.600000e-01 6.455517e-09 +772 1.700000e-01 9.151132e-09 +773 1.800000e-01 1.293714e-08 +774 1.900000e-01 1.823313e-08 +775 2.000000e-01 2.560762e-08 +776 2.100000e-01 3.582410e-08 +777 2.200000e-01 4.989798e-08 +778 2.300000e-01 6.916574e-08 +779 2.400000e-01 9.536735e-08 +780 2.500000e-01 1.307429e-07 +781 2.600000e-01 1.781442e-07 +782 2.700000e-01 2.411632e-07 +783 2.800000e-01 3.242784e-07 +784 2.900000e-01 4.330219e-07 +785 3.000000e-01 5.741683e-07 +786 3.100000e-01 7.559600e-07 +787 3.200000e-01 9.884636e-07 +788 3.300000e-01 1.283590e-06 +789 3.400000e-01 1.655271e-06 +790 3.500000e-01 2.119490e-06 +791 3.600000e-01 2.694047e-06 +792 3.700000e-01 3.397920e-06 +793 3.800000e-01 4.250005e-06 +794 3.900000e-01 5.266717e-06 +795 4.000000e-01 6.457328e-06 +796 4.100000e-01 7.816460e-06 +797 4.200000e-01 9.326264e-06 +798 4.300000e-01 1.098167e-05 +799 4.400000e-01 1.279167e-05 +800 4.500000e-01 1.476130e-05 +801 4.600000e-01 1.688842e-05 +802 4.700000e-01 1.916588e-05 +803 4.800000e-01 2.158327e-05 +804 4.900000e-01 2.412806e-05 +805 5.000000e-01 2.678642e-05 +806 5.100000e-01 2.954396e-05 +807 5.200000e-01 3.238621e-05 +808 5.300000e-01 3.526608e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +809 5.400000e-01 3.824278e-05 +810 5.500000e-01 4.126380e-05 +811 5.600000e-01 4.431773e-05 +812 5.700000e-01 4.739428e-05 +813 5.800000e-01 5.048437e-05 +814 5.900000e-01 5.358002e-05 +815 6.000000e-01 5.667433e-05 +816 6.100000e-01 5.976137e-05 +817 6.200000e-01 6.283612e-05 +818 6.300000e-01 6.589432e-05 +819 6.400000e-01 6.893244e-05 +820 6.500000e-01 7.194754e-05 +821 6.600000e-01 7.493723e-05 +822 6.700000e-01 7.789956e-05 +823 6.800000e-01 8.083298e-05 +824 6.900000e-01 8.373627e-05 +825 7.000000e-01 8.660850e-05 +826 7.100000e-01 8.944896e-05 +827 7.200000e-01 9.225715e-05 +828 7.300000e-01 9.503273e-05 +829 7.400000e-01 9.777552e-05 +830 7.500000e-01 1.004854e-04 +831 7.600000e-01 1.031625e-04 +832 7.700000e-01 1.058068e-04 +833 7.800000e-01 1.084185e-04 +834 7.900000e-01 1.109977e-04 +835 8.000000e-01 1.135449e-04 +836 8.100000e-01 1.160602e-04 +837 8.200000e-01 1.185440e-04 +838 8.300000e-01 1.209965e-04 +839 8.400000e-01 1.234183e-04 +840 8.500000e-01 1.258095e-04 +841 8.600000e-01 1.281707e-04 +842 8.700000e-01 1.305022e-04 +843 8.800000e-01 1.328043e-04 +844 8.900000e-01 1.350776e-04 +845 9.000000e-01 1.373222e-04 +846 9.100000e-01 1.395388e-04 +847 9.200000e-01 1.417276e-04 +848 9.300000e-01 1.438890e-04 +849 9.400000e-01 1.460235e-04 +850 9.500000e-01 1.481313e-04 +851 9.600000e-01 1.502130e-04 +852 9.700000e-01 1.522688e-04 +853 9.800000e-01 1.542991e-04 +854 9.900000e-01 1.563043e-04 +855 1.000000e+00 1.582848e-04 +856 1.010000e+00 1.602408e-04 +857 1.020000e+00 1.621729e-04 +858 1.030000e+00 1.640812e-04 +859 1.040000e+00 1.659661e-04 +860 1.050000e+00 1.678281e-04 +861 1.060000e+00 1.696673e-04 +862 1.070000e+00 1.714842e-04 +863 1.080000e+00 1.732790e-04 +864 1.090000e+00 1.750520e-04 +865 1.100000e+00 1.768036e-04 +866 1.110000e+00 1.785341e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +867 1.120000e+00 1.802438e-04 +868 1.130000e+00 1.819329e-04 +869 1.140000e+00 1.836017e-04 +870 1.150000e+00 1.852506e-04 +871 1.160000e+00 1.868797e-04 +872 1.170000e+00 1.884895e-04 +873 1.180000e+00 1.900801e-04 +874 1.190000e+00 1.916518e-04 +875 1.200000e+00 1.932049e-04 +876 1.210000e+00 1.947396e-04 +877 1.220000e+00 1.962562e-04 +878 1.230000e+00 1.977549e-04 +879 1.240000e+00 1.992360e-04 +880 1.250000e+00 2.006997e-04 +881 1.260000e+00 2.021463e-04 +882 1.270000e+00 2.035759e-04 +883 1.280000e+00 2.049889e-04 +884 1.290000e+00 2.063853e-04 +885 1.300000e+00 2.077656e-04 +886 1.310000e+00 2.091298e-04 +887 1.320000e+00 2.104781e-04 +888 1.330000e+00 2.118109e-04 +889 1.340000e+00 2.131283e-04 +890 1.350000e+00 2.144304e-04 +891 1.360000e+00 2.157176e-04 +892 1.370000e+00 2.169899e-04 +893 1.380000e+00 2.182477e-04 +894 1.390000e+00 2.194910e-04 +895 1.400000e+00 2.207201e-04 +896 1.410000e+00 2.219352e-04 +897 1.420000e+00 2.231364e-04 +898 1.430000e+00 2.243239e-04 +899 1.440000e+00 2.254978e-04 +900 1.450000e+00 2.266585e-04 +901 1.460000e+00 2.278060e-04 +902 1.470000e+00 2.289404e-04 +903 1.480000e+00 2.300621e-04 +904 1.490000e+00 2.311710e-04 +905 1.500000e+00 2.322675e-04 +906 0.000000e+00 1.468737e-10 +907 1.000000e-02 2.126740e-10 +908 2.000000e-02 3.077418e-10 +909 3.000000e-02 4.449567e-10 +910 4.000000e-02 6.427766e-10 +911 5.000000e-02 9.275941e-10 +912 6.000000e-02 1.337051e-09 +913 7.000000e-02 1.924673e-09 +914 8.000000e-02 2.766314e-09 +915 9.000000e-02 3.969041e-09 +916 1.000000e-01 5.683300e-09 +917 1.100000e-01 8.119385e-09 +918 1.200000e-01 1.156952e-08 +919 1.300000e-01 1.643703e-08 +920 1.400000e-01 2.327445e-08 +921 1.500000e-01 3.283237e-08 +922 1.600000e-01 4.612049e-08 +923 1.700000e-01 6.447923e-08 +924 1.800000e-01 8.967626e-08 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +925 1.900000e-01 1.240158e-07 +926 2.000000e-01 1.704680e-07 +927 2.100000e-01 2.328208e-07 +928 2.200000e-01 3.158556e-07 +929 2.300000e-01 4.255513e-07 +930 2.400000e-01 5.693147e-07 +931 2.500000e-01 7.562375e-07 +932 2.600000e-01 9.973625e-07 +933 2.700000e-01 1.305927e-06 +934 2.800000e-01 1.697521e-06 +935 2.900000e-01 2.190055e-06 +936 3.000000e-01 2.803399e-06 +937 3.100000e-01 3.558467e-06 +938 3.200000e-01 4.475389e-06 +939 3.300000e-01 5.569931e-06 +940 3.400000e-01 6.846410e-06 +941 3.500000e-01 8.288679e-06 +942 3.600000e-01 9.872788e-06 +943 3.700000e-01 1.159878e-05 +944 3.800000e-01 1.347855e-05 +945 3.900000e-01 1.551694e-05 +946 4.000000e-01 1.771117e-05 +947 4.100000e-01 2.005365e-05 +948 4.200000e-01 2.253366e-05 +949 4.300000e-01 2.513854e-05 +950 4.400000e-01 2.785449e-05 +951 4.500000e-01 3.066722e-05 +952 4.600000e-01 3.356246e-05 +953 4.700000e-01 3.649428e-05 +954 4.800000e-01 3.952011e-05 +955 4.900000e-01 4.258872e-05 +956 5.000000e-01 4.568887e-05 +957 5.100000e-01 4.881048e-05 +958 5.200000e-01 5.194455e-05 +959 5.300000e-01 5.508323e-05 +960 5.400000e-01 5.821966e-05 +961 5.500000e-01 6.134798e-05 +962 5.600000e-01 6.446317e-05 +963 5.700000e-01 6.756101e-05 +964 5.800000e-01 7.063796e-05 +965 5.900000e-01 7.369109e-05 +966 6.000000e-01 7.671800e-05 +967 6.100000e-01 7.971673e-05 +968 6.200000e-01 8.268574e-05 +969 6.300000e-01 8.562380e-05 +970 6.400000e-01 8.852997e-05 +971 6.500000e-01 9.140355e-05 +972 6.600000e-01 9.424405e-05 +973 6.700000e-01 9.705114e-05 +974 6.800000e-01 9.982463e-05 +975 6.900000e-01 1.025645e-04 +976 7.000000e-01 1.052706e-04 +977 7.100000e-01 1.079433e-04 +978 7.200000e-01 1.105826e-04 +979 7.300000e-01 1.131887e-04 +980 7.400000e-01 1.157620e-04 +981 7.500000e-01 1.183028e-04 +982 7.600000e-01 1.208113e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +983 7.700000e-01 1.232879e-04 +984 7.800000e-01 1.257331e-04 +985 7.900000e-01 1.281471e-04 +986 8.000000e-01 1.305304e-04 +987 8.100000e-01 1.328834e-04 +988 8.200000e-01 1.352065e-04 +989 8.300000e-01 1.375001e-04 +990 8.400000e-01 1.397646e-04 +991 8.500000e-01 1.420004e-04 +992 8.600000e-01 1.442079e-04 +993 8.700000e-01 1.463876e-04 +994 8.800000e-01 1.485397e-04 +995 8.900000e-01 1.506648e-04 +996 9.000000e-01 1.527631e-04 +997 9.100000e-01 1.548352e-04 +998 9.200000e-01 1.568813e-04 +999 9.300000e-01 1.589018e-04 +1000 9.400000e-01 1.608972e-04 +1001 9.500000e-01 1.628678e-04 +1002 9.600000e-01 1.648139e-04 +1003 9.700000e-01 1.667359e-04 +1004 9.800000e-01 1.686341e-04 +1005 9.900000e-01 1.705089e-04 +1006 1.000000e+00 1.723607e-04 +1007 1.010000e+00 1.741897e-04 +1008 1.020000e+00 1.759963e-04 +1009 1.030000e+00 1.777808e-04 +1010 1.040000e+00 1.795435e-04 +1011 1.050000e+00 1.812848e-04 +1012 1.060000e+00 1.830049e-04 +1013 1.070000e+00 1.847041e-04 +1014 1.080000e+00 1.863828e-04 +1015 1.090000e+00 1.880412e-04 +1016 1.100000e+00 1.896796e-04 +1017 1.110000e+00 1.912983e-04 +1018 1.120000e+00 1.928975e-04 +1019 1.130000e+00 1.944776e-04 +1020 1.140000e+00 1.960388e-04 +1021 1.150000e+00 1.975814e-04 +1022 1.160000e+00 1.991056e-04 +1023 1.170000e+00 2.006116e-04 +1024 1.180000e+00 2.020998e-04 +1025 1.190000e+00 2.035704e-04 +1026 1.200000e+00 2.050236e-04 +1027 1.210000e+00 2.064596e-04 +1028 1.220000e+00 2.078787e-04 +1029 1.230000e+00 2.092811e-04 +1030 1.240000e+00 2.106670e-04 +1031 1.250000e+00 2.120367e-04 +1032 1.260000e+00 2.133904e-04 +1033 1.270000e+00 2.147283e-04 +1034 1.280000e+00 2.160506e-04 +1035 1.290000e+00 2.173574e-04 +1036 1.300000e+00 2.186491e-04 +1037 1.310000e+00 2.199258e-04 +1038 1.320000e+00 2.211877e-04 +1039 1.330000e+00 2.224350e-04 +1040 1.340000e+00 2.236679e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1041 1.350000e+00 2.248866e-04 +1042 1.360000e+00 2.260913e-04 +1043 1.370000e+00 2.272821e-04 +1044 1.380000e+00 2.284592e-04 +1045 1.390000e+00 2.296228e-04 +1046 1.400000e+00 2.307731e-04 +1047 1.410000e+00 2.319103e-04 +1048 1.420000e+00 2.330345e-04 +1049 1.430000e+00 2.341458e-04 +1050 1.440000e+00 2.352445e-04 +1051 1.450000e+00 2.363307e-04 +1052 1.460000e+00 2.374046e-04 +1053 1.470000e+00 2.384663e-04 +1054 1.480000e+00 2.395159e-04 +1055 1.490000e+00 2.405537e-04 +1056 1.500000e+00 2.415798e-04 +1057 0.000000e+00 1.491864e-09 +1058 1.000000e-02 2.158102e-09 +1059 2.000000e-02 3.116114e-09 +1060 3.000000e-02 4.490120e-09 +1061 4.000000e-02 6.455027e-09 +1062 5.000000e-02 9.255779e-09 +1063 6.000000e-02 1.323331e-08 +1064 7.000000e-02 1.885894e-08 +1065 8.000000e-02 2.677935e-08 +1066 9.000000e-02 3.787446e-08 +1067 1.000000e-01 5.333102e-08 +1068 1.100000e-01 7.473436e-08 +1069 1.200000e-01 1.041815e-07 +1070 1.300000e-01 1.444187e-07 +1071 1.400000e-01 1.990065e-07 +1072 1.500000e-01 2.725171e-07 +1073 1.600000e-01 3.707627e-07 +1074 1.700000e-01 5.010355e-07 +1075 1.800000e-01 6.724479e-07 +1076 1.900000e-01 8.962557e-07 +1077 2.000000e-01 1.186173e-06 +1078 2.100000e-01 1.558611e-06 +1079 2.200000e-01 2.032706e-06 +1080 2.300000e-01 2.629957e-06 +1081 2.400000e-01 3.373140e-06 +1082 2.500000e-01 4.283943e-06 +1083 2.600000e-01 5.378000e-06 +1084 2.700000e-01 6.654960e-06 +1085 2.800000e-01 8.089410e-06 +1086 2.900000e-01 9.656277e-06 +1087 3.000000e-01 1.136243e-05 +1088 3.100000e-01 1.322275e-05 +1089 3.200000e-01 1.524300e-05 +1090 3.300000e-01 1.742118e-05 +1091 3.400000e-01 1.975043e-05 +1092 3.500000e-01 2.222073e-05 +1093 3.600000e-01 2.482002e-05 +1094 3.700000e-01 2.753496e-05 +1095 3.800000e-01 3.035163e-05 +1096 3.900000e-01 3.325593e-05 +1097 4.000000e-01 3.619941e-05 +1098 4.100000e-01 3.924462e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1099 4.200000e-01 4.233757e-05 +1100 4.300000e-01 4.546668e-05 +1101 4.400000e-01 4.862146e-05 +1102 4.500000e-01 5.179251e-05 +1103 4.600000e-01 5.497146e-05 +1104 4.700000e-01 5.815102e-05 +1105 4.800000e-01 6.132482e-05 +1106 4.900000e-01 6.448742e-05 +1107 5.000000e-01 6.763417e-05 +1108 5.100000e-01 7.076113e-05 +1109 5.200000e-01 7.386504e-05 +1110 5.300000e-01 7.694318e-05 +1111 5.400000e-01 7.999334e-05 +1112 5.500000e-01 8.301372e-05 +1113 5.600000e-01 8.600292e-05 +1114 5.700000e-01 8.895981e-05 +1115 5.800000e-01 9.188357e-05 +1116 5.900000e-01 9.477359e-05 +1117 6.000000e-01 9.762944e-05 +1118 6.100000e-01 1.004509e-04 +1119 6.200000e-01 1.032378e-04 +1120 6.300000e-01 1.059901e-04 +1121 6.400000e-01 1.087080e-04 +1122 6.500000e-01 1.113915e-04 +1123 6.600000e-01 1.140410e-04 +1124 6.700000e-01 1.166566e-04 +1125 6.800000e-01 1.192387e-04 +1126 6.900000e-01 1.217877e-04 +1127 7.000000e-01 1.243038e-04 +1128 7.100000e-01 1.267875e-04 +1129 7.200000e-01 1.292391e-04 +1130 7.300000e-01 1.316592e-04 +1131 7.400000e-01 1.340481e-04 +1132 7.500000e-01 1.364062e-04 +1133 7.600000e-01 1.387339e-04 +1134 7.700000e-01 1.410318e-04 +1135 7.800000e-01 1.433002e-04 +1136 7.900000e-01 1.455395e-04 +1137 8.000000e-01 1.477502e-04 +1138 8.100000e-01 1.499326e-04 +1139 8.200000e-01 1.520873e-04 +1140 8.300000e-01 1.542146e-04 +1141 8.400000e-01 1.563148e-04 +1142 8.500000e-01 1.583885e-04 +1143 8.600000e-01 1.604360e-04 +1144 8.700000e-01 1.624577e-04 +1145 8.800000e-01 1.644540e-04 +1146 8.900000e-01 1.664252e-04 +1147 9.000000e-01 1.683717e-04 +1148 9.100000e-01 1.702939e-04 +1149 9.200000e-01 1.721922e-04 +1150 9.300000e-01 1.740668e-04 +1151 9.400000e-01 1.759182e-04 +1152 9.500000e-01 1.777466e-04 +1153 9.600000e-01 1.795525e-04 +1154 9.700000e-01 1.813361e-04 +1155 9.800000e-01 1.830977e-04 +1156 9.900000e-01 1.848377e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1157 1.000000e+00 1.865564e-04 +1158 1.010000e+00 1.882541e-04 +1159 1.020000e+00 1.899310e-04 +1160 1.030000e+00 1.915876e-04 +1161 1.040000e+00 1.932240e-04 +1162 1.050000e+00 1.948406e-04 +1163 1.060000e+00 1.964376e-04 +1164 1.070000e+00 1.980154e-04 +1165 1.080000e+00 1.995741e-04 +1166 1.090000e+00 2.011141e-04 +1167 1.100000e+00 2.026356e-04 +1168 1.110000e+00 2.041388e-04 +1169 1.120000e+00 2.056241e-04 +1170 1.130000e+00 2.070917e-04 +1171 1.140000e+00 2.085417e-04 +1172 1.150000e+00 2.099745e-04 +1173 1.160000e+00 2.113903e-04 +1174 1.170000e+00 2.127893e-04 +1175 1.180000e+00 2.141718e-04 +1176 1.190000e+00 2.155379e-04 +1177 1.200000e+00 2.168880e-04 +1178 1.210000e+00 2.182221e-04 +1179 1.220000e+00 2.195406e-04 +1180 1.230000e+00 2.208436e-04 +1181 1.240000e+00 2.221313e-04 +1182 1.250000e+00 2.234040e-04 +1183 1.260000e+00 2.246618e-04 +1184 1.270000e+00 2.259050e-04 +1185 1.280000e+00 2.271336e-04 +1186 1.290000e+00 2.283480e-04 +1187 1.300000e+00 2.295483e-04 +1188 1.310000e+00 2.307347e-04 +1189 1.320000e+00 2.319074e-04 +1190 1.330000e+00 2.330665e-04 +1191 1.340000e+00 2.342123e-04 +1192 1.350000e+00 2.353448e-04 +1193 1.360000e+00 2.364643e-04 +1194 1.370000e+00 2.375709e-04 +1195 1.380000e+00 2.386649e-04 +1196 1.390000e+00 2.397463e-04 +1197 1.400000e+00 2.408153e-04 +1198 1.410000e+00 2.418721e-04 +1199 1.420000e+00 2.429168e-04 +1200 1.430000e+00 2.439496e-04 +1201 1.440000e+00 2.449706e-04 +1202 1.450000e+00 2.459800e-04 +1203 1.460000e+00 2.469779e-04 +1204 1.470000e+00 2.479645e-04 +1205 1.480000e+00 2.489399e-04 +1206 1.490000e+00 2.499043e-04 +1207 1.500000e+00 2.508577e-04 +1208 0.000000e+00 1.048409e-08 +1209 1.000000e-02 1.505832e-08 +1210 2.000000e-02 2.154301e-08 +1211 3.000000e-02 3.068721e-08 +1212 4.000000e-02 4.350714e-08 +1213 5.000000e-02 6.136848e-08 +1214 6.000000e-02 8.608831e-08 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1215 7.000000e-02 1.200599e-07 +1216 8.000000e-02 1.664038e-07 +1217 9.000000e-02 2.291479e-07 +1218 1.000000e-01 3.134426e-07 +1219 1.100000e-01 4.258100e-07 +1220 1.200000e-01 5.744308e-07 +1221 1.300000e-01 7.694535e-07 +1222 1.400000e-01 1.023296e-06 +1223 1.500000e-01 1.350867e-06 +1224 1.600000e-01 1.769554e-06 +1225 1.700000e-01 2.298628e-06 +1226 1.800000e-01 2.957947e-06 +1227 1.900000e-01 3.764320e-06 +1228 2.000000e-01 4.723621e-06 +1229 2.100000e-01 5.822589e-06 +1230 2.200000e-01 7.047310e-06 +1231 2.300000e-01 8.409078e-06 +1232 2.400000e-01 9.926061e-06 +1233 2.500000e-01 1.160887e-05 +1234 2.600000e-01 1.346102e-05 +1235 2.700000e-01 1.548098e-05 +1236 2.800000e-01 1.766340e-05 +1237 2.900000e-01 1.999995e-05 +1238 3.000000e-01 2.248005e-05 +1239 3.100000e-01 2.509145e-05 +1240 3.200000e-01 2.782085e-05 +1241 3.300000e-01 3.065437e-05 +1242 3.400000e-01 3.357803e-05 +1243 3.500000e-01 3.654212e-05 +1244 3.600000e-01 3.961177e-05 +1245 3.700000e-01 4.273162e-05 +1246 3.800000e-01 4.588997e-05 +1247 3.900000e-01 4.907612e-05 +1248 4.000000e-01 5.228041e-05 +1249 4.100000e-01 5.549423e-05 +1250 4.200000e-01 5.870995e-05 +1251 4.300000e-01 6.192092e-05 +1252 4.400000e-01 6.512138e-05 +1253 4.500000e-01 6.830641e-05 +1254 4.600000e-01 7.147180e-05 +1255 4.700000e-01 7.461405e-05 +1256 4.800000e-01 7.773022e-05 +1257 4.900000e-01 8.081792e-05 +1258 5.000000e-01 8.387519e-05 +1259 5.100000e-01 8.690048e-05 +1260 5.200000e-01 8.989259e-05 +1261 5.300000e-01 9.285059e-05 +1262 5.400000e-01 9.577381e-05 +1263 5.500000e-01 9.866180e-05 +1264 5.600000e-01 1.015143e-04 +1265 5.700000e-01 1.043311e-04 +1266 5.800000e-01 1.071122e-04 +1267 5.900000e-01 1.098578e-04 +1268 6.000000e-01 1.125680e-04 +1269 6.100000e-01 1.152430e-04 +1270 6.200000e-01 1.178831e-04 +1271 6.300000e-01 1.204888e-04 +1272 6.400000e-01 1.230602e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1273 6.500000e-01 1.255980e-04 +1274 6.600000e-01 1.281024e-04 +1275 6.700000e-01 1.305740e-04 +1276 6.800000e-01 1.330131e-04 +1277 6.900000e-01 1.354203e-04 +1278 7.000000e-01 1.377959e-04 +1279 7.100000e-01 1.401406e-04 +1280 7.200000e-01 1.424546e-04 +1281 7.300000e-01 1.447385e-04 +1282 7.400000e-01 1.469927e-04 +1283 7.500000e-01 1.492178e-04 +1284 7.600000e-01 1.514140e-04 +1285 7.700000e-01 1.535820e-04 +1286 7.800000e-01 1.557220e-04 +1287 7.900000e-01 1.578346e-04 +1288 8.000000e-01 1.599202e-04 +1289 8.100000e-01 1.619791e-04 +1290 8.200000e-01 1.640118e-04 +1291 8.300000e-01 1.660186e-04 +1292 8.400000e-01 1.680001e-04 +1293 8.500000e-01 1.699565e-04 +1294 8.600000e-01 1.718882e-04 +1295 8.700000e-01 1.737957e-04 +1296 8.800000e-01 1.756792e-04 +1297 8.900000e-01 1.775392e-04 +1298 9.000000e-01 1.793759e-04 +1299 9.100000e-01 1.811898e-04 +1300 9.200000e-01 1.829811e-04 +1301 9.300000e-01 1.847502e-04 +1302 9.400000e-01 1.864974e-04 +1303 9.500000e-01 1.882231e-04 +1304 9.600000e-01 1.899275e-04 +1305 9.700000e-01 1.916110e-04 +1306 9.800000e-01 1.932739e-04 +1307 9.900000e-01 1.949164e-04 +1308 1.000000e+00 1.965388e-04 +1309 1.010000e+00 1.981415e-04 +1310 1.020000e+00 1.997247e-04 +1311 1.030000e+00 2.012888e-04 +1312 1.040000e+00 2.028338e-04 +1313 1.050000e+00 2.043602e-04 +1314 1.060000e+00 2.058682e-04 +1315 1.070000e+00 2.073581e-04 +1316 1.080000e+00 2.088300e-04 +1317 1.090000e+00 2.102844e-04 +1318 1.100000e+00 2.117213e-04 +1319 1.110000e+00 2.131410e-04 +1320 1.120000e+00 2.145438e-04 +1321 1.130000e+00 2.159299e-04 +1322 1.140000e+00 2.172996e-04 +1323 1.150000e+00 2.186530e-04 +1324 1.160000e+00 2.199903e-04 +1325 1.170000e+00 2.213119e-04 +1326 1.180000e+00 2.226179e-04 +1327 1.190000e+00 2.239084e-04 +1328 1.200000e+00 2.251838e-04 +1329 1.210000e+00 2.264442e-04 +1330 1.220000e+00 2.276899e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1331 1.230000e+00 2.289209e-04 +1332 1.240000e+00 2.301376e-04 +1333 1.250000e+00 2.313400e-04 +1334 1.260000e+00 2.325285e-04 +1335 1.270000e+00 2.337031e-04 +1336 1.280000e+00 2.348640e-04 +1337 1.290000e+00 2.360115e-04 +1338 1.300000e+00 2.371457e-04 +1339 1.310000e+00 2.382667e-04 +1340 1.320000e+00 2.393748e-04 +1341 1.330000e+00 2.404701e-04 +1342 1.340000e+00 2.415527e-04 +1343 1.350000e+00 2.426229e-04 +1344 1.360000e+00 2.436808e-04 +1345 1.370000e+00 2.447265e-04 +1346 1.380000e+00 2.457602e-04 +1347 1.390000e+00 2.467821e-04 +1348 1.400000e+00 2.477923e-04 +1349 1.410000e+00 2.487909e-04 +1350 1.420000e+00 2.497781e-04 +1351 1.430000e+00 2.507540e-04 +1352 1.440000e+00 2.517188e-04 +1353 1.450000e+00 2.526727e-04 +1354 1.460000e+00 2.536156e-04 +1355 1.470000e+00 2.545479e-04 +1356 1.480000e+00 2.554695e-04 +1357 1.490000e+00 2.563807e-04 +1358 1.500000e+00 2.572816e-04 + + + + diff --git a/tests/bsim3soifd/Makefile.am b/tests/bsim3soifd/Makefile.am new file mode 100644 index 000000000..acf97dd4a --- /dev/null +++ b/tests/bsim3soifd/Makefile.am @@ -0,0 +1,16 @@ +## Process this file with automake to produce Makefile.in + +TESTS = \ + t3.cir \ + t4.cir \ + t5.cir \ + inv2.cir \ + RampVg2.cir + +TESTS_ENVIRONMENT = $(SHELL) $(srcdir)/../check.sh $(top_builddir)/src/ngspice + +EXTRA_DIST = \ + $(TESTS) \ + $(TESTS:.cir=.out) + +MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/bsim3soifd/RampVg2.cir b/tests/bsim3soifd/RampVg2.cir new file mode 100644 index 000000000..5ce191d61 --- /dev/null +++ b/tests/bsim3soifd/RampVg2.cir @@ -0,0 +1,19 @@ +* BSIMSOI (FD) example +* +* SOI, Ramp Vg + +Vd d 0 1.5 +Vg g 0 0.0 PULSE 0V 2V .02n .1n .1n .2n .6n +Ve e 0 0.0 +Vs s 0 0.0 +Vb b 0 0.0 + +m1 d g s e n1 w=10u l=0.25u debug=-1 + +.option gmin=1e-20 itl1=200 itl2=200 abstol=1e-9 +.tran 1p 1.0ns +.print tran @m1[Vbs], V(g)/10 +.include nmosfd.mod + +.end + diff --git a/tests/bsim3soifd/RampVg2.out b/tests/bsim3soifd/RampVg2.out new file mode 100644 index 000000000..0378a607c --- /dev/null +++ b/tests/bsim3soifd/RampVg2.out @@ -0,0 +1,1113 @@ + +Circuit: * BSIMSOI (FD) example + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. + +Initial Transient Solution +-------------------------- + +Node Voltage +---- ------- +d 1.5 +g 0 +e 0 +s 0 +b 0 +vb#branch 0 +vs#branch 9.60282e-12 +ve#branch 0 +vg#branch 1.5e-20 +vd#branch -9.60282e-12 + + Reference value : 3.33500e-10 +No. of Data Rows : 1029 + * BSIMSOI (FD) example +-------------------------------------------------------------------------------- +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +0 0.000000e+00 0.000000e+00 0.000000e+00 +1 1.000000e-14 0.000000e+00 0.000000e+00 +2 2.000000e-14 0.000000e+00 0.000000e+00 +3 4.000000e-14 0.000000e+00 0.000000e+00 +4 8.000000e-14 0.000000e+00 0.000000e+00 +5 1.600000e-13 0.000000e+00 0.000000e+00 +6 3.200000e-13 0.000000e+00 0.000000e+00 +7 6.400000e-13 0.000000e+00 0.000000e+00 +8 1.280000e-12 0.000000e+00 0.000000e+00 +9 2.280000e-12 0.000000e+00 0.000000e+00 +10 3.280000e-12 0.000000e+00 0.000000e+00 +11 4.280000e-12 0.000000e+00 0.000000e+00 +12 5.280000e-12 0.000000e+00 0.000000e+00 +13 6.280000e-12 0.000000e+00 0.000000e+00 +14 7.280000e-12 0.000000e+00 0.000000e+00 +15 8.280000e-12 0.000000e+00 0.000000e+00 +16 9.280000e-12 0.000000e+00 0.000000e+00 +17 1.028000e-11 0.000000e+00 0.000000e+00 +18 1.128000e-11 0.000000e+00 0.000000e+00 +19 1.228000e-11 0.000000e+00 0.000000e+00 +20 1.328000e-11 0.000000e+00 0.000000e+00 +21 1.428000e-11 0.000000e+00 0.000000e+00 +22 1.528000e-11 0.000000e+00 0.000000e+00 +23 1.628000e-11 0.000000e+00 0.000000e+00 +24 1.728000e-11 0.000000e+00 0.000000e+00 +25 1.828000e-11 0.000000e+00 0.000000e+00 +26 1.928000e-11 0.000000e+00 0.000000e+00 +27 2.000000e-11 0.000000e+00 0.000000e+00 +28 2.010000e-11 0.000000e+00 2.000000e-04 +29 2.030000e-11 0.000000e+00 6.000000e-04 +30 2.070000e-11 0.000000e+00 1.400000e-03 +31 2.150000e-11 0.000000e+00 3.000000e-03 +32 2.250000e-11 0.000000e+00 5.000000e-03 +33 2.350000e-11 0.000000e+00 7.000000e-03 +34 2.450000e-11 0.000000e+00 9.000000e-03 +35 2.550000e-11 0.000000e+00 1.100000e-02 +36 2.650000e-11 0.000000e+00 1.300000e-02 +37 2.750000e-11 0.000000e+00 1.500000e-02 +38 2.850000e-11 0.000000e+00 1.700000e-02 +39 2.950000e-11 0.000000e+00 1.900000e-02 +40 3.050000e-11 0.000000e+00 2.100000e-02 +41 3.150000e-11 0.000000e+00 2.300000e-02 +42 3.250000e-11 0.000000e+00 2.500000e-02 +43 3.350000e-11 0.000000e+00 2.700000e-02 +44 3.450000e-11 0.000000e+00 2.900000e-02 +45 3.550000e-11 0.000000e+00 3.100000e-02 +46 3.650000e-11 0.000000e+00 3.300000e-02 +47 3.750000e-11 0.000000e+00 3.500000e-02 +48 3.850000e-11 0.000000e+00 3.700000e-02 +49 3.950000e-11 0.000000e+00 3.900000e-02 +50 4.050000e-11 0.000000e+00 4.100000e-02 +51 4.150000e-11 0.000000e+00 4.300000e-02 +52 4.250000e-11 0.000000e+00 4.500000e-02 +53 4.350000e-11 0.000000e+00 4.700000e-02 +54 4.450000e-11 0.000000e+00 4.900000e-02 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +55 4.550000e-11 0.000000e+00 5.100000e-02 +56 4.650000e-11 0.000000e+00 5.300000e-02 +57 4.750000e-11 0.000000e+00 5.500000e-02 +58 4.850000e-11 0.000000e+00 5.700000e-02 +59 4.950000e-11 0.000000e+00 5.900000e-02 +60 5.050000e-11 0.000000e+00 6.100000e-02 +61 5.150000e-11 0.000000e+00 6.300000e-02 +62 5.250000e-11 0.000000e+00 6.500000e-02 +63 5.350000e-11 0.000000e+00 6.700000e-02 +64 5.450000e-11 0.000000e+00 6.900000e-02 +65 5.550000e-11 0.000000e+00 7.100000e-02 +66 5.650000e-11 0.000000e+00 7.300000e-02 +67 5.750000e-11 0.000000e+00 7.500000e-02 +68 5.850000e-11 0.000000e+00 7.700000e-02 +69 5.950000e-11 0.000000e+00 7.900000e-02 +70 6.050000e-11 0.000000e+00 8.100000e-02 +71 6.150000e-11 0.000000e+00 8.300000e-02 +72 6.250000e-11 0.000000e+00 8.500000e-02 +73 6.350000e-11 0.000000e+00 8.700000e-02 +74 6.450000e-11 0.000000e+00 8.900000e-02 +75 6.550000e-11 0.000000e+00 9.100000e-02 +76 6.650000e-11 0.000000e+00 9.300000e-02 +77 6.750000e-11 0.000000e+00 9.500000e-02 +78 6.850000e-11 0.000000e+00 9.700000e-02 +79 6.950000e-11 0.000000e+00 9.900000e-02 +80 7.050000e-11 0.000000e+00 1.010000e-01 +81 7.150000e-11 0.000000e+00 1.030000e-01 +82 7.250000e-11 0.000000e+00 1.050000e-01 +83 7.350000e-11 0.000000e+00 1.070000e-01 +84 7.450000e-11 0.000000e+00 1.090000e-01 +85 7.550000e-11 0.000000e+00 1.110000e-01 +86 7.650000e-11 0.000000e+00 1.130000e-01 +87 7.750000e-11 0.000000e+00 1.150000e-01 +88 7.850000e-11 0.000000e+00 1.170000e-01 +89 7.950000e-11 0.000000e+00 1.190000e-01 +90 8.050000e-11 0.000000e+00 1.210000e-01 +91 8.150000e-11 0.000000e+00 1.230000e-01 +92 8.250000e-11 0.000000e+00 1.250000e-01 +93 8.350000e-11 0.000000e+00 1.270000e-01 +94 8.450000e-11 0.000000e+00 1.290000e-01 +95 8.550000e-11 0.000000e+00 1.310000e-01 +96 8.650000e-11 0.000000e+00 1.330000e-01 +97 8.750000e-11 0.000000e+00 1.350000e-01 +98 8.850000e-11 0.000000e+00 1.370000e-01 +99 8.950000e-11 0.000000e+00 1.390000e-01 +100 9.050000e-11 0.000000e+00 1.410000e-01 +101 9.150000e-11 0.000000e+00 1.430000e-01 +102 9.250000e-11 0.000000e+00 1.450000e-01 +103 9.350000e-11 0.000000e+00 1.470000e-01 +104 9.450000e-11 0.000000e+00 1.490000e-01 +105 9.550000e-11 0.000000e+00 1.510000e-01 +106 9.650000e-11 0.000000e+00 1.530000e-01 +107 9.750000e-11 0.000000e+00 1.550000e-01 +108 9.850000e-11 0.000000e+00 1.570000e-01 +109 9.950000e-11 0.000000e+00 1.590000e-01 +110 1.005000e-10 0.000000e+00 1.610000e-01 +111 1.015000e-10 0.000000e+00 1.630000e-01 +112 1.025000e-10 0.000000e+00 1.650000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +113 1.035000e-10 0.000000e+00 1.670000e-01 +114 1.045000e-10 0.000000e+00 1.690000e-01 +115 1.055000e-10 0.000000e+00 1.710000e-01 +116 1.065000e-10 0.000000e+00 1.730000e-01 +117 1.075000e-10 0.000000e+00 1.750000e-01 +118 1.085000e-10 0.000000e+00 1.770000e-01 +119 1.095000e-10 0.000000e+00 1.790000e-01 +120 1.105000e-10 0.000000e+00 1.810000e-01 +121 1.115000e-10 0.000000e+00 1.830000e-01 +122 1.125000e-10 0.000000e+00 1.850000e-01 +123 1.135000e-10 0.000000e+00 1.870000e-01 +124 1.145000e-10 0.000000e+00 1.890000e-01 +125 1.155000e-10 0.000000e+00 1.910000e-01 +126 1.165000e-10 0.000000e+00 1.930000e-01 +127 1.175000e-10 0.000000e+00 1.950000e-01 +128 1.185000e-10 0.000000e+00 1.970000e-01 +129 1.195000e-10 0.000000e+00 1.990000e-01 +130 1.200000e-10 0.000000e+00 2.000000e-01 +131 1.201000e-10 0.000000e+00 2.000000e-01 +132 1.203000e-10 0.000000e+00 2.000000e-01 +133 1.207000e-10 0.000000e+00 2.000000e-01 +134 1.215000e-10 0.000000e+00 2.000000e-01 +135 1.225000e-10 0.000000e+00 2.000000e-01 +136 1.235000e-10 0.000000e+00 2.000000e-01 +137 1.245000e-10 0.000000e+00 2.000000e-01 +138 1.255000e-10 0.000000e+00 2.000000e-01 +139 1.265000e-10 0.000000e+00 2.000000e-01 +140 1.275000e-10 0.000000e+00 2.000000e-01 +141 1.285000e-10 0.000000e+00 2.000000e-01 +142 1.295000e-10 0.000000e+00 2.000000e-01 +143 1.305000e-10 0.000000e+00 2.000000e-01 +144 1.315000e-10 0.000000e+00 2.000000e-01 +145 1.325000e-10 0.000000e+00 2.000000e-01 +146 1.335000e-10 0.000000e+00 2.000000e-01 +147 1.345000e-10 0.000000e+00 2.000000e-01 +148 1.355000e-10 0.000000e+00 2.000000e-01 +149 1.365000e-10 0.000000e+00 2.000000e-01 +150 1.375000e-10 0.000000e+00 2.000000e-01 +151 1.385000e-10 0.000000e+00 2.000000e-01 +152 1.395000e-10 0.000000e+00 2.000000e-01 +153 1.405000e-10 0.000000e+00 2.000000e-01 +154 1.415000e-10 0.000000e+00 2.000000e-01 +155 1.425000e-10 0.000000e+00 2.000000e-01 +156 1.435000e-10 0.000000e+00 2.000000e-01 +157 1.445000e-10 0.000000e+00 2.000000e-01 +158 1.455000e-10 0.000000e+00 2.000000e-01 +159 1.465000e-10 0.000000e+00 2.000000e-01 +160 1.475000e-10 0.000000e+00 2.000000e-01 +161 1.485000e-10 0.000000e+00 2.000000e-01 +162 1.495000e-10 0.000000e+00 2.000000e-01 +163 1.505000e-10 0.000000e+00 2.000000e-01 +164 1.515000e-10 0.000000e+00 2.000000e-01 +165 1.525000e-10 0.000000e+00 2.000000e-01 +166 1.535000e-10 0.000000e+00 2.000000e-01 +167 1.545000e-10 0.000000e+00 2.000000e-01 +168 1.555000e-10 0.000000e+00 2.000000e-01 +169 1.565000e-10 0.000000e+00 2.000000e-01 +170 1.575000e-10 0.000000e+00 2.000000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +171 1.585000e-10 0.000000e+00 2.000000e-01 +172 1.595000e-10 0.000000e+00 2.000000e-01 +173 1.605000e-10 0.000000e+00 2.000000e-01 +174 1.615000e-10 0.000000e+00 2.000000e-01 +175 1.625000e-10 0.000000e+00 2.000000e-01 +176 1.635000e-10 0.000000e+00 2.000000e-01 +177 1.645000e-10 0.000000e+00 2.000000e-01 +178 1.655000e-10 0.000000e+00 2.000000e-01 +179 1.665000e-10 0.000000e+00 2.000000e-01 +180 1.675000e-10 0.000000e+00 2.000000e-01 +181 1.685000e-10 0.000000e+00 2.000000e-01 +182 1.695000e-10 0.000000e+00 2.000000e-01 +183 1.705000e-10 0.000000e+00 2.000000e-01 +184 1.715000e-10 0.000000e+00 2.000000e-01 +185 1.725000e-10 0.000000e+00 2.000000e-01 +186 1.735000e-10 0.000000e+00 2.000000e-01 +187 1.745000e-10 0.000000e+00 2.000000e-01 +188 1.755000e-10 0.000000e+00 2.000000e-01 +189 1.765000e-10 0.000000e+00 2.000000e-01 +190 1.775000e-10 0.000000e+00 2.000000e-01 +191 1.785000e-10 0.000000e+00 2.000000e-01 +192 1.795000e-10 0.000000e+00 2.000000e-01 +193 1.805000e-10 0.000000e+00 2.000000e-01 +194 1.815000e-10 0.000000e+00 2.000000e-01 +195 1.825000e-10 0.000000e+00 2.000000e-01 +196 1.835000e-10 0.000000e+00 2.000000e-01 +197 1.845000e-10 0.000000e+00 2.000000e-01 +198 1.855000e-10 0.000000e+00 2.000000e-01 +199 1.865000e-10 0.000000e+00 2.000000e-01 +200 1.875000e-10 0.000000e+00 2.000000e-01 +201 1.885000e-10 0.000000e+00 2.000000e-01 +202 1.895000e-10 0.000000e+00 2.000000e-01 +203 1.905000e-10 0.000000e+00 2.000000e-01 +204 1.915000e-10 0.000000e+00 2.000000e-01 +205 1.925000e-10 0.000000e+00 2.000000e-01 +206 1.935000e-10 0.000000e+00 2.000000e-01 +207 1.945000e-10 0.000000e+00 2.000000e-01 +208 1.955000e-10 0.000000e+00 2.000000e-01 +209 1.965000e-10 0.000000e+00 2.000000e-01 +210 1.975000e-10 0.000000e+00 2.000000e-01 +211 1.985000e-10 0.000000e+00 2.000000e-01 +212 1.995000e-10 0.000000e+00 2.000000e-01 +213 2.005000e-10 0.000000e+00 2.000000e-01 +214 2.015000e-10 0.000000e+00 2.000000e-01 +215 2.025000e-10 0.000000e+00 2.000000e-01 +216 2.035000e-10 0.000000e+00 2.000000e-01 +217 2.045000e-10 0.000000e+00 2.000000e-01 +218 2.055000e-10 0.000000e+00 2.000000e-01 +219 2.065000e-10 0.000000e+00 2.000000e-01 +220 2.075000e-10 0.000000e+00 2.000000e-01 +221 2.085000e-10 0.000000e+00 2.000000e-01 +222 2.095000e-10 0.000000e+00 2.000000e-01 +223 2.105000e-10 0.000000e+00 2.000000e-01 +224 2.115000e-10 0.000000e+00 2.000000e-01 +225 2.125000e-10 0.000000e+00 2.000000e-01 +226 2.135000e-10 0.000000e+00 2.000000e-01 +227 2.145000e-10 0.000000e+00 2.000000e-01 +228 2.155000e-10 0.000000e+00 2.000000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +229 2.165000e-10 0.000000e+00 2.000000e-01 +230 2.175000e-10 0.000000e+00 2.000000e-01 +231 2.185000e-10 0.000000e+00 2.000000e-01 +232 2.195000e-10 0.000000e+00 2.000000e-01 +233 2.205000e-10 0.000000e+00 2.000000e-01 +234 2.215000e-10 0.000000e+00 2.000000e-01 +235 2.225000e-10 0.000000e+00 2.000000e-01 +236 2.235000e-10 0.000000e+00 2.000000e-01 +237 2.245000e-10 0.000000e+00 2.000000e-01 +238 2.255000e-10 0.000000e+00 2.000000e-01 +239 2.265000e-10 0.000000e+00 2.000000e-01 +240 2.275000e-10 0.000000e+00 2.000000e-01 +241 2.285000e-10 0.000000e+00 2.000000e-01 +242 2.295000e-10 0.000000e+00 2.000000e-01 +243 2.305000e-10 0.000000e+00 2.000000e-01 +244 2.315000e-10 0.000000e+00 2.000000e-01 +245 2.325000e-10 0.000000e+00 2.000000e-01 +246 2.335000e-10 0.000000e+00 2.000000e-01 +247 2.345000e-10 0.000000e+00 2.000000e-01 +248 2.355000e-10 0.000000e+00 2.000000e-01 +249 2.365000e-10 0.000000e+00 2.000000e-01 +250 2.375000e-10 0.000000e+00 2.000000e-01 +251 2.385000e-10 0.000000e+00 2.000000e-01 +252 2.395000e-10 0.000000e+00 2.000000e-01 +253 2.405000e-10 0.000000e+00 2.000000e-01 +254 2.415000e-10 0.000000e+00 2.000000e-01 +255 2.425000e-10 0.000000e+00 2.000000e-01 +256 2.435000e-10 0.000000e+00 2.000000e-01 +257 2.445000e-10 0.000000e+00 2.000000e-01 +258 2.455000e-10 0.000000e+00 2.000000e-01 +259 2.465000e-10 0.000000e+00 2.000000e-01 +260 2.475000e-10 0.000000e+00 2.000000e-01 +261 2.485000e-10 0.000000e+00 2.000000e-01 +262 2.495000e-10 0.000000e+00 2.000000e-01 +263 2.505000e-10 0.000000e+00 2.000000e-01 +264 2.515000e-10 0.000000e+00 2.000000e-01 +265 2.525000e-10 0.000000e+00 2.000000e-01 +266 2.535000e-10 0.000000e+00 2.000000e-01 +267 2.545000e-10 0.000000e+00 2.000000e-01 +268 2.555000e-10 0.000000e+00 2.000000e-01 +269 2.565000e-10 0.000000e+00 2.000000e-01 +270 2.575000e-10 0.000000e+00 2.000000e-01 +271 2.585000e-10 0.000000e+00 2.000000e-01 +272 2.595000e-10 0.000000e+00 2.000000e-01 +273 2.605000e-10 0.000000e+00 2.000000e-01 +274 2.615000e-10 0.000000e+00 2.000000e-01 +275 2.625000e-10 0.000000e+00 2.000000e-01 +276 2.635000e-10 0.000000e+00 2.000000e-01 +277 2.645000e-10 0.000000e+00 2.000000e-01 +278 2.655000e-10 0.000000e+00 2.000000e-01 +279 2.665000e-10 0.000000e+00 2.000000e-01 +280 2.675000e-10 0.000000e+00 2.000000e-01 +281 2.685000e-10 0.000000e+00 2.000000e-01 +282 2.695000e-10 0.000000e+00 2.000000e-01 +283 2.705000e-10 0.000000e+00 2.000000e-01 +284 2.715000e-10 0.000000e+00 2.000000e-01 +285 2.725000e-10 0.000000e+00 2.000000e-01 +286 2.735000e-10 0.000000e+00 2.000000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +287 2.745000e-10 0.000000e+00 2.000000e-01 +288 2.755000e-10 0.000000e+00 2.000000e-01 +289 2.765000e-10 0.000000e+00 2.000000e-01 +290 2.775000e-10 0.000000e+00 2.000000e-01 +291 2.785000e-10 0.000000e+00 2.000000e-01 +292 2.795000e-10 0.000000e+00 2.000000e-01 +293 2.805000e-10 0.000000e+00 2.000000e-01 +294 2.815000e-10 0.000000e+00 2.000000e-01 +295 2.825000e-10 0.000000e+00 2.000000e-01 +296 2.835000e-10 0.000000e+00 2.000000e-01 +297 2.845000e-10 0.000000e+00 2.000000e-01 +298 2.855000e-10 0.000000e+00 2.000000e-01 +299 2.865000e-10 0.000000e+00 2.000000e-01 +300 2.875000e-10 0.000000e+00 2.000000e-01 +301 2.885000e-10 0.000000e+00 2.000000e-01 +302 2.895000e-10 0.000000e+00 2.000000e-01 +303 2.905000e-10 0.000000e+00 2.000000e-01 +304 2.915000e-10 0.000000e+00 2.000000e-01 +305 2.925000e-10 0.000000e+00 2.000000e-01 +306 2.935000e-10 0.000000e+00 2.000000e-01 +307 2.945000e-10 0.000000e+00 2.000000e-01 +308 2.955000e-10 0.000000e+00 2.000000e-01 +309 2.965000e-10 0.000000e+00 2.000000e-01 +310 2.975000e-10 0.000000e+00 2.000000e-01 +311 2.985000e-10 0.000000e+00 2.000000e-01 +312 2.995000e-10 0.000000e+00 2.000000e-01 +313 3.005000e-10 0.000000e+00 2.000000e-01 +314 3.015000e-10 0.000000e+00 2.000000e-01 +315 3.025000e-10 0.000000e+00 2.000000e-01 +316 3.035000e-10 0.000000e+00 2.000000e-01 +317 3.045000e-10 0.000000e+00 2.000000e-01 +318 3.055000e-10 0.000000e+00 2.000000e-01 +319 3.065000e-10 0.000000e+00 2.000000e-01 +320 3.075000e-10 0.000000e+00 2.000000e-01 +321 3.085000e-10 0.000000e+00 2.000000e-01 +322 3.095000e-10 0.000000e+00 2.000000e-01 +323 3.105000e-10 0.000000e+00 2.000000e-01 +324 3.115000e-10 0.000000e+00 2.000000e-01 +325 3.125000e-10 0.000000e+00 2.000000e-01 +326 3.135000e-10 0.000000e+00 2.000000e-01 +327 3.145000e-10 0.000000e+00 2.000000e-01 +328 3.155000e-10 0.000000e+00 2.000000e-01 +329 3.165000e-10 0.000000e+00 2.000000e-01 +330 3.175000e-10 0.000000e+00 2.000000e-01 +331 3.185000e-10 0.000000e+00 2.000000e-01 +332 3.195000e-10 0.000000e+00 2.000000e-01 +333 3.200000e-10 0.000000e+00 2.000000e-01 +334 3.201000e-10 0.000000e+00 1.998000e-01 +335 3.203000e-10 0.000000e+00 1.994000e-01 +336 3.207000e-10 0.000000e+00 1.986000e-01 +337 3.215000e-10 0.000000e+00 1.970000e-01 +338 3.225000e-10 0.000000e+00 1.950000e-01 +339 3.235000e-10 0.000000e+00 1.930000e-01 +340 3.245000e-10 0.000000e+00 1.910000e-01 +341 3.255000e-10 0.000000e+00 1.890000e-01 +342 3.265000e-10 0.000000e+00 1.870000e-01 +343 3.275000e-10 0.000000e+00 1.850000e-01 +344 3.285000e-10 0.000000e+00 1.830000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +345 3.295000e-10 0.000000e+00 1.810000e-01 +346 3.305000e-10 0.000000e+00 1.790000e-01 +347 3.315000e-10 0.000000e+00 1.770000e-01 +348 3.325000e-10 0.000000e+00 1.750000e-01 +349 3.335000e-10 0.000000e+00 1.730000e-01 +350 3.345000e-10 0.000000e+00 1.710000e-01 +351 3.355000e-10 0.000000e+00 1.690000e-01 +352 3.365000e-10 0.000000e+00 1.670000e-01 +353 3.375000e-10 0.000000e+00 1.650000e-01 +354 3.385000e-10 0.000000e+00 1.630000e-01 +355 3.395000e-10 0.000000e+00 1.610000e-01 +356 3.405000e-10 0.000000e+00 1.590000e-01 +357 3.415000e-10 0.000000e+00 1.570000e-01 +358 3.425000e-10 0.000000e+00 1.550000e-01 +359 3.435000e-10 0.000000e+00 1.530000e-01 +360 3.445000e-10 0.000000e+00 1.510000e-01 +361 3.455000e-10 0.000000e+00 1.490000e-01 +362 3.465000e-10 0.000000e+00 1.470000e-01 +363 3.475000e-10 0.000000e+00 1.450000e-01 +364 3.485000e-10 0.000000e+00 1.430000e-01 +365 3.495000e-10 0.000000e+00 1.410000e-01 +366 3.505000e-10 0.000000e+00 1.390000e-01 +367 3.515000e-10 0.000000e+00 1.370000e-01 +368 3.525000e-10 0.000000e+00 1.350000e-01 +369 3.535000e-10 0.000000e+00 1.330000e-01 +370 3.545000e-10 0.000000e+00 1.310000e-01 +371 3.555000e-10 0.000000e+00 1.290000e-01 +372 3.565000e-10 0.000000e+00 1.270000e-01 +373 3.575000e-10 0.000000e+00 1.250000e-01 +374 3.585000e-10 0.000000e+00 1.230000e-01 +375 3.595000e-10 0.000000e+00 1.210000e-01 +376 3.605000e-10 0.000000e+00 1.190000e-01 +377 3.615000e-10 0.000000e+00 1.170000e-01 +378 3.625000e-10 0.000000e+00 1.150000e-01 +379 3.635000e-10 0.000000e+00 1.130000e-01 +380 3.645000e-10 0.000000e+00 1.110000e-01 +381 3.655000e-10 0.000000e+00 1.090000e-01 +382 3.665000e-10 0.000000e+00 1.070000e-01 +383 3.675000e-10 0.000000e+00 1.050000e-01 +384 3.685000e-10 0.000000e+00 1.030000e-01 +385 3.695000e-10 0.000000e+00 1.010000e-01 +386 3.705000e-10 0.000000e+00 9.900000e-02 +387 3.715000e-10 0.000000e+00 9.700000e-02 +388 3.725000e-10 0.000000e+00 9.500000e-02 +389 3.735000e-10 0.000000e+00 9.300000e-02 +390 3.745000e-10 0.000000e+00 9.100000e-02 +391 3.755000e-10 0.000000e+00 8.900000e-02 +392 3.765000e-10 0.000000e+00 8.700000e-02 +393 3.775000e-10 0.000000e+00 8.500000e-02 +394 3.785000e-10 0.000000e+00 8.300000e-02 +395 3.795000e-10 0.000000e+00 8.100000e-02 +396 3.805000e-10 0.000000e+00 7.900000e-02 +397 3.815000e-10 0.000000e+00 7.700000e-02 +398 3.825000e-10 0.000000e+00 7.500000e-02 +399 3.835000e-10 0.000000e+00 7.300000e-02 +400 3.845000e-10 0.000000e+00 7.100000e-02 +401 3.855000e-10 0.000000e+00 6.900000e-02 +402 3.865000e-10 0.000000e+00 6.700000e-02 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +403 3.875000e-10 0.000000e+00 6.500000e-02 +404 3.885000e-10 0.000000e+00 6.300000e-02 +405 3.895000e-10 0.000000e+00 6.100000e-02 +406 3.905000e-10 0.000000e+00 5.900000e-02 +407 3.915000e-10 0.000000e+00 5.700000e-02 +408 3.925000e-10 0.000000e+00 5.500000e-02 +409 3.935000e-10 0.000000e+00 5.300000e-02 +410 3.945000e-10 0.000000e+00 5.100000e-02 +411 3.955000e-10 0.000000e+00 4.900000e-02 +412 3.965000e-10 0.000000e+00 4.700000e-02 +413 3.975000e-10 0.000000e+00 4.500000e-02 +414 3.985000e-10 0.000000e+00 4.300000e-02 +415 3.995000e-10 0.000000e+00 4.100000e-02 +416 4.005000e-10 0.000000e+00 3.900000e-02 +417 4.015000e-10 0.000000e+00 3.700000e-02 +418 4.025000e-10 0.000000e+00 3.500000e-02 +419 4.035000e-10 0.000000e+00 3.300000e-02 +420 4.045000e-10 0.000000e+00 3.100000e-02 +421 4.055000e-10 0.000000e+00 2.900000e-02 +422 4.065000e-10 0.000000e+00 2.700000e-02 +423 4.075000e-10 0.000000e+00 2.500000e-02 +424 4.085000e-10 0.000000e+00 2.300000e-02 +425 4.095000e-10 0.000000e+00 2.100000e-02 +426 4.105000e-10 0.000000e+00 1.900000e-02 +427 4.115000e-10 0.000000e+00 1.700000e-02 +428 4.125000e-10 0.000000e+00 1.500000e-02 +429 4.135000e-10 0.000000e+00 1.300000e-02 +430 4.145000e-10 0.000000e+00 1.100000e-02 +431 4.155000e-10 0.000000e+00 9.000000e-03 +432 4.165000e-10 0.000000e+00 7.000000e-03 +433 4.175000e-10 0.000000e+00 5.000000e-03 +434 4.185000e-10 0.000000e+00 3.000000e-03 +435 4.195000e-10 0.000000e+00 1.000000e-03 +436 4.200000e-10 0.000000e+00 3.230922e-17 +437 4.201000e-10 0.000000e+00 0.000000e+00 +438 4.203000e-10 0.000000e+00 0.000000e+00 +439 4.207000e-10 0.000000e+00 0.000000e+00 +440 4.215000e-10 0.000000e+00 0.000000e+00 +441 4.225000e-10 0.000000e+00 0.000000e+00 +442 4.235000e-10 0.000000e+00 0.000000e+00 +443 4.245000e-10 0.000000e+00 0.000000e+00 +444 4.255000e-10 0.000000e+00 0.000000e+00 +445 4.265000e-10 0.000000e+00 0.000000e+00 +446 4.275000e-10 0.000000e+00 0.000000e+00 +447 4.285000e-10 0.000000e+00 0.000000e+00 +448 4.295000e-10 0.000000e+00 0.000000e+00 +449 4.305000e-10 0.000000e+00 0.000000e+00 +450 4.315000e-10 0.000000e+00 0.000000e+00 +451 4.325000e-10 0.000000e+00 0.000000e+00 +452 4.335000e-10 0.000000e+00 0.000000e+00 +453 4.345000e-10 0.000000e+00 0.000000e+00 +454 4.355000e-10 0.000000e+00 0.000000e+00 +455 4.365000e-10 0.000000e+00 0.000000e+00 +456 4.375000e-10 0.000000e+00 0.000000e+00 +457 4.385000e-10 0.000000e+00 0.000000e+00 +458 4.395000e-10 0.000000e+00 0.000000e+00 +459 4.405000e-10 0.000000e+00 0.000000e+00 +460 4.415000e-10 0.000000e+00 0.000000e+00 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +461 4.425000e-10 0.000000e+00 0.000000e+00 +462 4.435000e-10 0.000000e+00 0.000000e+00 +463 4.445000e-10 0.000000e+00 0.000000e+00 +464 4.455000e-10 0.000000e+00 0.000000e+00 +465 4.465000e-10 0.000000e+00 0.000000e+00 +466 4.475000e-10 0.000000e+00 0.000000e+00 +467 4.485000e-10 0.000000e+00 0.000000e+00 +468 4.495000e-10 0.000000e+00 0.000000e+00 +469 4.505000e-10 0.000000e+00 0.000000e+00 +470 4.515000e-10 0.000000e+00 0.000000e+00 +471 4.525000e-10 0.000000e+00 0.000000e+00 +472 4.535000e-10 0.000000e+00 0.000000e+00 +473 4.545000e-10 0.000000e+00 0.000000e+00 +474 4.555000e-10 0.000000e+00 0.000000e+00 +475 4.565000e-10 0.000000e+00 0.000000e+00 +476 4.575000e-10 0.000000e+00 0.000000e+00 +477 4.585000e-10 0.000000e+00 0.000000e+00 +478 4.595000e-10 0.000000e+00 0.000000e+00 +479 4.605000e-10 0.000000e+00 0.000000e+00 +480 4.615000e-10 0.000000e+00 0.000000e+00 +481 4.625000e-10 0.000000e+00 0.000000e+00 +482 4.635000e-10 0.000000e+00 0.000000e+00 +483 4.645000e-10 0.000000e+00 0.000000e+00 +484 4.655000e-10 0.000000e+00 0.000000e+00 +485 4.665000e-10 0.000000e+00 0.000000e+00 +486 4.675000e-10 0.000000e+00 0.000000e+00 +487 4.685000e-10 0.000000e+00 0.000000e+00 +488 4.695000e-10 0.000000e+00 0.000000e+00 +489 4.705000e-10 0.000000e+00 0.000000e+00 +490 4.715000e-10 0.000000e+00 0.000000e+00 +491 4.725000e-10 0.000000e+00 0.000000e+00 +492 4.735000e-10 0.000000e+00 0.000000e+00 +493 4.745000e-10 0.000000e+00 0.000000e+00 +494 4.755000e-10 0.000000e+00 0.000000e+00 +495 4.765000e-10 0.000000e+00 0.000000e+00 +496 4.775000e-10 0.000000e+00 0.000000e+00 +497 4.785000e-10 0.000000e+00 0.000000e+00 +498 4.795000e-10 0.000000e+00 0.000000e+00 +499 4.805000e-10 0.000000e+00 0.000000e+00 +500 4.815000e-10 0.000000e+00 0.000000e+00 +501 4.825000e-10 0.000000e+00 0.000000e+00 +502 4.835000e-10 0.000000e+00 0.000000e+00 +503 4.845000e-10 0.000000e+00 0.000000e+00 +504 4.855000e-10 0.000000e+00 0.000000e+00 +505 4.865000e-10 0.000000e+00 0.000000e+00 +506 4.875000e-10 0.000000e+00 0.000000e+00 +507 4.885000e-10 0.000000e+00 0.000000e+00 +508 4.895000e-10 0.000000e+00 0.000000e+00 +509 4.905000e-10 0.000000e+00 0.000000e+00 +510 4.915000e-10 0.000000e+00 0.000000e+00 +511 4.925000e-10 0.000000e+00 0.000000e+00 +512 4.935000e-10 0.000000e+00 0.000000e+00 +513 4.945000e-10 0.000000e+00 0.000000e+00 +514 4.955000e-10 0.000000e+00 0.000000e+00 +515 4.965000e-10 0.000000e+00 0.000000e+00 +516 4.975000e-10 0.000000e+00 0.000000e+00 +517 4.985000e-10 0.000000e+00 0.000000e+00 +518 4.995000e-10 0.000000e+00 0.000000e+00 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +519 5.005000e-10 0.000000e+00 0.000000e+00 +520 5.015000e-10 0.000000e+00 0.000000e+00 +521 5.025000e-10 0.000000e+00 0.000000e+00 +522 5.035000e-10 0.000000e+00 0.000000e+00 +523 5.045000e-10 0.000000e+00 0.000000e+00 +524 5.055000e-10 0.000000e+00 0.000000e+00 +525 5.065000e-10 0.000000e+00 0.000000e+00 +526 5.075000e-10 0.000000e+00 0.000000e+00 +527 5.085000e-10 0.000000e+00 0.000000e+00 +528 5.095000e-10 0.000000e+00 0.000000e+00 +529 5.105000e-10 0.000000e+00 0.000000e+00 +530 5.115000e-10 0.000000e+00 0.000000e+00 +531 5.125000e-10 0.000000e+00 0.000000e+00 +532 5.135000e-10 0.000000e+00 0.000000e+00 +533 5.145000e-10 0.000000e+00 0.000000e+00 +534 5.155000e-10 0.000000e+00 0.000000e+00 +535 5.165000e-10 0.000000e+00 0.000000e+00 +536 5.175000e-10 0.000000e+00 0.000000e+00 +537 5.185000e-10 0.000000e+00 0.000000e+00 +538 5.195000e-10 0.000000e+00 0.000000e+00 +539 5.205000e-10 0.000000e+00 0.000000e+00 +540 5.215000e-10 0.000000e+00 0.000000e+00 +541 5.225000e-10 0.000000e+00 0.000000e+00 +542 5.235000e-10 0.000000e+00 0.000000e+00 +543 5.245000e-10 0.000000e+00 0.000000e+00 +544 5.255000e-10 0.000000e+00 0.000000e+00 +545 5.265000e-10 0.000000e+00 0.000000e+00 +546 5.275000e-10 0.000000e+00 0.000000e+00 +547 5.285000e-10 0.000000e+00 0.000000e+00 +548 5.295000e-10 0.000000e+00 0.000000e+00 +549 5.305000e-10 0.000000e+00 0.000000e+00 +550 5.315000e-10 0.000000e+00 0.000000e+00 +551 5.325000e-10 0.000000e+00 0.000000e+00 +552 5.335000e-10 0.000000e+00 0.000000e+00 +553 5.345000e-10 0.000000e+00 0.000000e+00 +554 5.355000e-10 0.000000e+00 0.000000e+00 +555 5.365000e-10 0.000000e+00 0.000000e+00 +556 5.375000e-10 0.000000e+00 0.000000e+00 +557 5.385000e-10 0.000000e+00 0.000000e+00 +558 5.395000e-10 0.000000e+00 0.000000e+00 +559 5.405000e-10 0.000000e+00 0.000000e+00 +560 5.415000e-10 0.000000e+00 0.000000e+00 +561 5.425000e-10 0.000000e+00 0.000000e+00 +562 5.435000e-10 0.000000e+00 0.000000e+00 +563 5.445000e-10 0.000000e+00 0.000000e+00 +564 5.455000e-10 0.000000e+00 0.000000e+00 +565 5.465000e-10 0.000000e+00 0.000000e+00 +566 5.475000e-10 0.000000e+00 0.000000e+00 +567 5.485000e-10 0.000000e+00 0.000000e+00 +568 5.495000e-10 0.000000e+00 0.000000e+00 +569 5.505000e-10 0.000000e+00 0.000000e+00 +570 5.515000e-10 0.000000e+00 0.000000e+00 +571 5.525000e-10 0.000000e+00 0.000000e+00 +572 5.535000e-10 0.000000e+00 0.000000e+00 +573 5.545000e-10 0.000000e+00 0.000000e+00 +574 5.555000e-10 0.000000e+00 0.000000e+00 +575 5.565000e-10 0.000000e+00 0.000000e+00 +576 5.575000e-10 0.000000e+00 0.000000e+00 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +577 5.585000e-10 0.000000e+00 0.000000e+00 +578 5.595000e-10 0.000000e+00 0.000000e+00 +579 5.605000e-10 0.000000e+00 0.000000e+00 +580 5.615000e-10 0.000000e+00 0.000000e+00 +581 5.625000e-10 0.000000e+00 0.000000e+00 +582 5.635000e-10 0.000000e+00 0.000000e+00 +583 5.645000e-10 0.000000e+00 0.000000e+00 +584 5.655000e-10 0.000000e+00 0.000000e+00 +585 5.665000e-10 0.000000e+00 0.000000e+00 +586 5.675000e-10 0.000000e+00 0.000000e+00 +587 5.685000e-10 0.000000e+00 0.000000e+00 +588 5.695000e-10 0.000000e+00 0.000000e+00 +589 5.705000e-10 0.000000e+00 0.000000e+00 +590 5.715000e-10 0.000000e+00 0.000000e+00 +591 5.725000e-10 0.000000e+00 0.000000e+00 +592 5.735000e-10 0.000000e+00 0.000000e+00 +593 5.745000e-10 0.000000e+00 0.000000e+00 +594 5.755000e-10 0.000000e+00 0.000000e+00 +595 5.765000e-10 0.000000e+00 0.000000e+00 +596 5.775000e-10 0.000000e+00 0.000000e+00 +597 5.785000e-10 0.000000e+00 0.000000e+00 +598 5.795000e-10 0.000000e+00 0.000000e+00 +599 5.805000e-10 0.000000e+00 0.000000e+00 +600 5.815000e-10 0.000000e+00 0.000000e+00 +601 5.825000e-10 0.000000e+00 0.000000e+00 +602 5.835000e-10 0.000000e+00 0.000000e+00 +603 5.845000e-10 0.000000e+00 0.000000e+00 +604 5.855000e-10 0.000000e+00 0.000000e+00 +605 5.865000e-10 0.000000e+00 0.000000e+00 +606 5.875000e-10 0.000000e+00 0.000000e+00 +607 5.885000e-10 0.000000e+00 0.000000e+00 +608 5.895000e-10 0.000000e+00 0.000000e+00 +609 5.905000e-10 0.000000e+00 0.000000e+00 +610 5.915000e-10 0.000000e+00 0.000000e+00 +611 5.925000e-10 0.000000e+00 0.000000e+00 +612 5.935000e-10 0.000000e+00 0.000000e+00 +613 5.945000e-10 0.000000e+00 0.000000e+00 +614 5.955000e-10 0.000000e+00 0.000000e+00 +615 5.965000e-10 0.000000e+00 0.000000e+00 +616 5.975000e-10 0.000000e+00 0.000000e+00 +617 5.985000e-10 0.000000e+00 0.000000e+00 +618 5.995000e-10 0.000000e+00 0.000000e+00 +619 6.005000e-10 0.000000e+00 0.000000e+00 +620 6.015000e-10 0.000000e+00 0.000000e+00 +621 6.025000e-10 0.000000e+00 0.000000e+00 +622 6.035000e-10 0.000000e+00 0.000000e+00 +623 6.045000e-10 0.000000e+00 0.000000e+00 +624 6.055000e-10 0.000000e+00 0.000000e+00 +625 6.065000e-10 0.000000e+00 0.000000e+00 +626 6.075000e-10 0.000000e+00 0.000000e+00 +627 6.085000e-10 0.000000e+00 0.000000e+00 +628 6.095000e-10 0.000000e+00 0.000000e+00 +629 6.105000e-10 0.000000e+00 0.000000e+00 +630 6.115000e-10 0.000000e+00 0.000000e+00 +631 6.125000e-10 0.000000e+00 0.000000e+00 +632 6.135000e-10 0.000000e+00 0.000000e+00 +633 6.145000e-10 0.000000e+00 0.000000e+00 +634 6.155000e-10 0.000000e+00 0.000000e+00 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +635 6.165000e-10 0.000000e+00 0.000000e+00 +636 6.175000e-10 0.000000e+00 0.000000e+00 +637 6.185000e-10 0.000000e+00 0.000000e+00 +638 6.195000e-10 0.000000e+00 0.000000e+00 +639 6.200000e-10 0.000000e+00 7.108583e-17 +640 6.201000e-10 0.000000e+00 2.000000e-04 +641 6.203000e-10 0.000000e+00 6.000000e-04 +642 6.207000e-10 0.000000e+00 1.400000e-03 +643 6.215000e-10 0.000000e+00 3.000000e-03 +644 6.225000e-10 0.000000e+00 5.000000e-03 +645 6.235000e-10 0.000000e+00 7.000000e-03 +646 6.245000e-10 0.000000e+00 9.000000e-03 +647 6.255000e-10 0.000000e+00 1.100000e-02 +648 6.265000e-10 0.000000e+00 1.300000e-02 +649 6.275000e-10 0.000000e+00 1.500000e-02 +650 6.285000e-10 0.000000e+00 1.700000e-02 +651 6.295000e-10 0.000000e+00 1.900000e-02 +652 6.305000e-10 0.000000e+00 2.100000e-02 +653 6.315000e-10 0.000000e+00 2.300000e-02 +654 6.325000e-10 0.000000e+00 2.500000e-02 +655 6.335000e-10 0.000000e+00 2.700000e-02 +656 6.345000e-10 0.000000e+00 2.900000e-02 +657 6.355000e-10 0.000000e+00 3.100000e-02 +658 6.365000e-10 0.000000e+00 3.300000e-02 +659 6.375000e-10 0.000000e+00 3.500000e-02 +660 6.385000e-10 0.000000e+00 3.700000e-02 +661 6.395000e-10 0.000000e+00 3.900000e-02 +662 6.405000e-10 0.000000e+00 4.100000e-02 +663 6.415000e-10 0.000000e+00 4.300000e-02 +664 6.425000e-10 0.000000e+00 4.500000e-02 +665 6.435000e-10 0.000000e+00 4.700000e-02 +666 6.445000e-10 0.000000e+00 4.900000e-02 +667 6.455000e-10 0.000000e+00 5.100000e-02 +668 6.465000e-10 0.000000e+00 5.300000e-02 +669 6.475000e-10 0.000000e+00 5.500000e-02 +670 6.485000e-10 0.000000e+00 5.700000e-02 +671 6.495000e-10 0.000000e+00 5.900000e-02 +672 6.505000e-10 0.000000e+00 6.100000e-02 +673 6.515000e-10 0.000000e+00 6.300000e-02 +674 6.525000e-10 0.000000e+00 6.500000e-02 +675 6.535000e-10 0.000000e+00 6.700000e-02 +676 6.545000e-10 0.000000e+00 6.900000e-02 +677 6.555000e-10 0.000000e+00 7.100000e-02 +678 6.565000e-10 0.000000e+00 7.300000e-02 +679 6.575000e-10 0.000000e+00 7.500000e-02 +680 6.585000e-10 0.000000e+00 7.700000e-02 +681 6.595000e-10 0.000000e+00 7.900000e-02 +682 6.605000e-10 0.000000e+00 8.100000e-02 +683 6.615000e-10 0.000000e+00 8.300000e-02 +684 6.625000e-10 0.000000e+00 8.500000e-02 +685 6.635000e-10 0.000000e+00 8.700000e-02 +686 6.645000e-10 0.000000e+00 8.900000e-02 +687 6.655000e-10 0.000000e+00 9.100000e-02 +688 6.665000e-10 0.000000e+00 9.300000e-02 +689 6.675000e-10 0.000000e+00 9.500000e-02 +690 6.685000e-10 0.000000e+00 9.700000e-02 +691 6.695000e-10 0.000000e+00 9.900000e-02 +692 6.705000e-10 0.000000e+00 1.010000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +693 6.715000e-10 0.000000e+00 1.030000e-01 +694 6.725000e-10 0.000000e+00 1.050000e-01 +695 6.735000e-10 0.000000e+00 1.070000e-01 +696 6.745000e-10 0.000000e+00 1.090000e-01 +697 6.755000e-10 0.000000e+00 1.110000e-01 +698 6.765000e-10 0.000000e+00 1.130000e-01 +699 6.775000e-10 0.000000e+00 1.150000e-01 +700 6.785000e-10 0.000000e+00 1.170000e-01 +701 6.795000e-10 0.000000e+00 1.190000e-01 +702 6.805000e-10 0.000000e+00 1.210000e-01 +703 6.815000e-10 0.000000e+00 1.230000e-01 +704 6.825000e-10 0.000000e+00 1.250000e-01 +705 6.835000e-10 0.000000e+00 1.270000e-01 +706 6.845000e-10 0.000000e+00 1.290000e-01 +707 6.855000e-10 0.000000e+00 1.310000e-01 +708 6.865000e-10 0.000000e+00 1.330000e-01 +709 6.875000e-10 0.000000e+00 1.350000e-01 +710 6.885000e-10 0.000000e+00 1.370000e-01 +711 6.895000e-10 0.000000e+00 1.390000e-01 +712 6.905000e-10 0.000000e+00 1.410000e-01 +713 6.915000e-10 0.000000e+00 1.430000e-01 +714 6.925000e-10 0.000000e+00 1.450000e-01 +715 6.935000e-10 0.000000e+00 1.470000e-01 +716 6.945000e-10 0.000000e+00 1.490000e-01 +717 6.955000e-10 0.000000e+00 1.510000e-01 +718 6.965000e-10 0.000000e+00 1.530000e-01 +719 6.975000e-10 0.000000e+00 1.550000e-01 +720 6.985000e-10 0.000000e+00 1.570000e-01 +721 6.995000e-10 0.000000e+00 1.590000e-01 +722 7.005000e-10 0.000000e+00 1.610000e-01 +723 7.015000e-10 0.000000e+00 1.630000e-01 +724 7.025000e-10 0.000000e+00 1.650000e-01 +725 7.035000e-10 0.000000e+00 1.670000e-01 +726 7.045000e-10 0.000000e+00 1.690000e-01 +727 7.055000e-10 0.000000e+00 1.710000e-01 +728 7.065000e-10 0.000000e+00 1.730000e-01 +729 7.075000e-10 0.000000e+00 1.750000e-01 +730 7.085000e-10 0.000000e+00 1.770000e-01 +731 7.095000e-10 0.000000e+00 1.790000e-01 +732 7.105000e-10 0.000000e+00 1.810000e-01 +733 7.115000e-10 0.000000e+00 1.830000e-01 +734 7.125000e-10 0.000000e+00 1.850000e-01 +735 7.135000e-10 0.000000e+00 1.870000e-01 +736 7.145000e-10 0.000000e+00 1.890000e-01 +737 7.155000e-10 0.000000e+00 1.910000e-01 +738 7.165000e-10 0.000000e+00 1.930000e-01 +739 7.175000e-10 0.000000e+00 1.950000e-01 +740 7.185000e-10 0.000000e+00 1.970000e-01 +741 7.195000e-10 0.000000e+00 1.990000e-01 +742 7.200000e-10 0.000000e+00 2.000000e-01 +743 7.201000e-10 0.000000e+00 2.000000e-01 +744 7.203000e-10 0.000000e+00 2.000000e-01 +745 7.207000e-10 0.000000e+00 2.000000e-01 +746 7.215000e-10 0.000000e+00 2.000000e-01 +747 7.225000e-10 0.000000e+00 2.000000e-01 +748 7.235000e-10 0.000000e+00 2.000000e-01 +749 7.245000e-10 0.000000e+00 2.000000e-01 +750 7.255000e-10 0.000000e+00 2.000000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +751 7.265000e-10 0.000000e+00 2.000000e-01 +752 7.275000e-10 0.000000e+00 2.000000e-01 +753 7.285000e-10 0.000000e+00 2.000000e-01 +754 7.295000e-10 0.000000e+00 2.000000e-01 +755 7.305000e-10 0.000000e+00 2.000000e-01 +756 7.315000e-10 0.000000e+00 2.000000e-01 +757 7.325000e-10 0.000000e+00 2.000000e-01 +758 7.335000e-10 0.000000e+00 2.000000e-01 +759 7.345000e-10 0.000000e+00 2.000000e-01 +760 7.355000e-10 0.000000e+00 2.000000e-01 +761 7.365000e-10 0.000000e+00 2.000000e-01 +762 7.375000e-10 0.000000e+00 2.000000e-01 +763 7.385000e-10 0.000000e+00 2.000000e-01 +764 7.395000e-10 0.000000e+00 2.000000e-01 +765 7.405000e-10 0.000000e+00 2.000000e-01 +766 7.415000e-10 0.000000e+00 2.000000e-01 +767 7.425000e-10 0.000000e+00 2.000000e-01 +768 7.435000e-10 0.000000e+00 2.000000e-01 +769 7.445000e-10 0.000000e+00 2.000000e-01 +770 7.455000e-10 0.000000e+00 2.000000e-01 +771 7.465000e-10 0.000000e+00 2.000000e-01 +772 7.475000e-10 0.000000e+00 2.000000e-01 +773 7.485000e-10 0.000000e+00 2.000000e-01 +774 7.495000e-10 0.000000e+00 2.000000e-01 +775 7.505000e-10 0.000000e+00 2.000000e-01 +776 7.515000e-10 0.000000e+00 2.000000e-01 +777 7.525000e-10 0.000000e+00 2.000000e-01 +778 7.535000e-10 0.000000e+00 2.000000e-01 +779 7.545000e-10 0.000000e+00 2.000000e-01 +780 7.555000e-10 0.000000e+00 2.000000e-01 +781 7.565000e-10 0.000000e+00 2.000000e-01 +782 7.575000e-10 0.000000e+00 2.000000e-01 +783 7.585000e-10 0.000000e+00 2.000000e-01 +784 7.595000e-10 0.000000e+00 2.000000e-01 +785 7.605000e-10 0.000000e+00 2.000000e-01 +786 7.615000e-10 0.000000e+00 2.000000e-01 +787 7.625000e-10 0.000000e+00 2.000000e-01 +788 7.635000e-10 0.000000e+00 2.000000e-01 +789 7.645000e-10 0.000000e+00 2.000000e-01 +790 7.655000e-10 0.000000e+00 2.000000e-01 +791 7.665000e-10 0.000000e+00 2.000000e-01 +792 7.675000e-10 0.000000e+00 2.000000e-01 +793 7.685000e-10 0.000000e+00 2.000000e-01 +794 7.695000e-10 0.000000e+00 2.000000e-01 +795 7.705000e-10 0.000000e+00 2.000000e-01 +796 7.715000e-10 0.000000e+00 2.000000e-01 +797 7.725000e-10 0.000000e+00 2.000000e-01 +798 7.735000e-10 0.000000e+00 2.000000e-01 +799 7.745000e-10 0.000000e+00 2.000000e-01 +800 7.755000e-10 0.000000e+00 2.000000e-01 +801 7.765000e-10 0.000000e+00 2.000000e-01 +802 7.775000e-10 0.000000e+00 2.000000e-01 +803 7.785000e-10 0.000000e+00 2.000000e-01 +804 7.795000e-10 0.000000e+00 2.000000e-01 +805 7.805000e-10 0.000000e+00 2.000000e-01 +806 7.815000e-10 0.000000e+00 2.000000e-01 +807 7.825000e-10 0.000000e+00 2.000000e-01 +808 7.835000e-10 0.000000e+00 2.000000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +809 7.845000e-10 0.000000e+00 2.000000e-01 +810 7.855000e-10 0.000000e+00 2.000000e-01 +811 7.865000e-10 0.000000e+00 2.000000e-01 +812 7.875000e-10 0.000000e+00 2.000000e-01 +813 7.885000e-10 0.000000e+00 2.000000e-01 +814 7.895000e-10 0.000000e+00 2.000000e-01 +815 7.905000e-10 0.000000e+00 2.000000e-01 +816 7.915000e-10 0.000000e+00 2.000000e-01 +817 7.925000e-10 0.000000e+00 2.000000e-01 +818 7.935000e-10 0.000000e+00 2.000000e-01 +819 7.945000e-10 0.000000e+00 2.000000e-01 +820 7.955000e-10 0.000000e+00 2.000000e-01 +821 7.965000e-10 0.000000e+00 2.000000e-01 +822 7.975000e-10 0.000000e+00 2.000000e-01 +823 7.985000e-10 0.000000e+00 2.000000e-01 +824 7.995000e-10 0.000000e+00 2.000000e-01 +825 8.005000e-10 0.000000e+00 2.000000e-01 +826 8.015000e-10 0.000000e+00 2.000000e-01 +827 8.025000e-10 0.000000e+00 2.000000e-01 +828 8.035000e-10 0.000000e+00 2.000000e-01 +829 8.045000e-10 0.000000e+00 2.000000e-01 +830 8.055000e-10 0.000000e+00 2.000000e-01 +831 8.065000e-10 0.000000e+00 2.000000e-01 +832 8.075000e-10 0.000000e+00 2.000000e-01 +833 8.085000e-10 0.000000e+00 2.000000e-01 +834 8.095000e-10 0.000000e+00 2.000000e-01 +835 8.105000e-10 0.000000e+00 2.000000e-01 +836 8.115000e-10 0.000000e+00 2.000000e-01 +837 8.125000e-10 0.000000e+00 2.000000e-01 +838 8.135000e-10 0.000000e+00 2.000000e-01 +839 8.145000e-10 0.000000e+00 2.000000e-01 +840 8.155000e-10 0.000000e+00 2.000000e-01 +841 8.165000e-10 0.000000e+00 2.000000e-01 +842 8.175000e-10 0.000000e+00 2.000000e-01 +843 8.185000e-10 0.000000e+00 2.000000e-01 +844 8.195000e-10 0.000000e+00 2.000000e-01 +845 8.205000e-10 0.000000e+00 2.000000e-01 +846 8.215000e-10 0.000000e+00 2.000000e-01 +847 8.225000e-10 0.000000e+00 2.000000e-01 +848 8.235000e-10 0.000000e+00 2.000000e-01 +849 8.245000e-10 0.000000e+00 2.000000e-01 +850 8.255000e-10 0.000000e+00 2.000000e-01 +851 8.265000e-10 0.000000e+00 2.000000e-01 +852 8.275000e-10 0.000000e+00 2.000000e-01 +853 8.285000e-10 0.000000e+00 2.000000e-01 +854 8.295000e-10 0.000000e+00 2.000000e-01 +855 8.305000e-10 0.000000e+00 2.000000e-01 +856 8.315000e-10 0.000000e+00 2.000000e-01 +857 8.325000e-10 0.000000e+00 2.000000e-01 +858 8.335000e-10 0.000000e+00 2.000000e-01 +859 8.345000e-10 0.000000e+00 2.000000e-01 +860 8.355000e-10 0.000000e+00 2.000000e-01 +861 8.365000e-10 0.000000e+00 2.000000e-01 +862 8.375000e-10 0.000000e+00 2.000000e-01 +863 8.385000e-10 0.000000e+00 2.000000e-01 +864 8.395000e-10 0.000000e+00 2.000000e-01 +865 8.405000e-10 0.000000e+00 2.000000e-01 +866 8.415000e-10 0.000000e+00 2.000000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +867 8.425000e-10 0.000000e+00 2.000000e-01 +868 8.435000e-10 0.000000e+00 2.000000e-01 +869 8.445000e-10 0.000000e+00 2.000000e-01 +870 8.455000e-10 0.000000e+00 2.000000e-01 +871 8.465000e-10 0.000000e+00 2.000000e-01 +872 8.475000e-10 0.000000e+00 2.000000e-01 +873 8.485000e-10 0.000000e+00 2.000000e-01 +874 8.495000e-10 0.000000e+00 2.000000e-01 +875 8.505000e-10 0.000000e+00 2.000000e-01 +876 8.515000e-10 0.000000e+00 2.000000e-01 +877 8.525000e-10 0.000000e+00 2.000000e-01 +878 8.535000e-10 0.000000e+00 2.000000e-01 +879 8.545000e-10 0.000000e+00 2.000000e-01 +880 8.555000e-10 0.000000e+00 2.000000e-01 +881 8.565000e-10 0.000000e+00 2.000000e-01 +882 8.575000e-10 0.000000e+00 2.000000e-01 +883 8.585000e-10 0.000000e+00 2.000000e-01 +884 8.595000e-10 0.000000e+00 2.000000e-01 +885 8.605000e-10 0.000000e+00 2.000000e-01 +886 8.615000e-10 0.000000e+00 2.000000e-01 +887 8.625000e-10 0.000000e+00 2.000000e-01 +888 8.635000e-10 0.000000e+00 2.000000e-01 +889 8.645000e-10 0.000000e+00 2.000000e-01 +890 8.655000e-10 0.000000e+00 2.000000e-01 +891 8.665000e-10 0.000000e+00 2.000000e-01 +892 8.675000e-10 0.000000e+00 2.000000e-01 +893 8.685000e-10 0.000000e+00 2.000000e-01 +894 8.695000e-10 0.000000e+00 2.000000e-01 +895 8.705000e-10 0.000000e+00 2.000000e-01 +896 8.715000e-10 0.000000e+00 2.000000e-01 +897 8.725000e-10 0.000000e+00 2.000000e-01 +898 8.735000e-10 0.000000e+00 2.000000e-01 +899 8.745000e-10 0.000000e+00 2.000000e-01 +900 8.755000e-10 0.000000e+00 2.000000e-01 +901 8.765000e-10 0.000000e+00 2.000000e-01 +902 8.775000e-10 0.000000e+00 2.000000e-01 +903 8.785000e-10 0.000000e+00 2.000000e-01 +904 8.795000e-10 0.000000e+00 2.000000e-01 +905 8.805000e-10 0.000000e+00 2.000000e-01 +906 8.815000e-10 0.000000e+00 2.000000e-01 +907 8.825000e-10 0.000000e+00 2.000000e-01 +908 8.835000e-10 0.000000e+00 2.000000e-01 +909 8.845000e-10 0.000000e+00 2.000000e-01 +910 8.855000e-10 0.000000e+00 2.000000e-01 +911 8.865000e-10 0.000000e+00 2.000000e-01 +912 8.875000e-10 0.000000e+00 2.000000e-01 +913 8.885000e-10 0.000000e+00 2.000000e-01 +914 8.895000e-10 0.000000e+00 2.000000e-01 +915 8.905000e-10 0.000000e+00 2.000000e-01 +916 8.915000e-10 0.000000e+00 2.000000e-01 +917 8.925000e-10 0.000000e+00 2.000000e-01 +918 8.935000e-10 0.000000e+00 2.000000e-01 +919 8.945000e-10 0.000000e+00 2.000000e-01 +920 8.955000e-10 0.000000e+00 2.000000e-01 +921 8.965000e-10 0.000000e+00 2.000000e-01 +922 8.975000e-10 0.000000e+00 2.000000e-01 +923 8.985000e-10 0.000000e+00 2.000000e-01 +924 8.995000e-10 0.000000e+00 2.000000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +925 9.005000e-10 0.000000e+00 2.000000e-01 +926 9.015000e-10 0.000000e+00 2.000000e-01 +927 9.025000e-10 0.000000e+00 2.000000e-01 +928 9.035000e-10 0.000000e+00 2.000000e-01 +929 9.045000e-10 0.000000e+00 2.000000e-01 +930 9.055000e-10 0.000000e+00 2.000000e-01 +931 9.065000e-10 0.000000e+00 2.000000e-01 +932 9.075000e-10 0.000000e+00 2.000000e-01 +933 9.085000e-10 0.000000e+00 2.000000e-01 +934 9.095000e-10 0.000000e+00 2.000000e-01 +935 9.105000e-10 0.000000e+00 2.000000e-01 +936 9.115000e-10 0.000000e+00 2.000000e-01 +937 9.125000e-10 0.000000e+00 2.000000e-01 +938 9.135000e-10 0.000000e+00 2.000000e-01 +939 9.145000e-10 0.000000e+00 2.000000e-01 +940 9.155000e-10 0.000000e+00 2.000000e-01 +941 9.165000e-10 0.000000e+00 2.000000e-01 +942 9.175000e-10 0.000000e+00 2.000000e-01 +943 9.185000e-10 0.000000e+00 2.000000e-01 +944 9.195000e-10 0.000000e+00 2.000000e-01 +945 9.200000e-10 0.000000e+00 2.000000e-01 +946 9.201000e-10 0.000000e+00 1.998000e-01 +947 9.203000e-10 0.000000e+00 1.994000e-01 +948 9.207000e-10 0.000000e+00 1.986000e-01 +949 9.215000e-10 0.000000e+00 1.970000e-01 +950 9.225000e-10 0.000000e+00 1.950000e-01 +951 9.235000e-10 0.000000e+00 1.930000e-01 +952 9.245000e-10 0.000000e+00 1.910000e-01 +953 9.255000e-10 0.000000e+00 1.890000e-01 +954 9.265000e-10 0.000000e+00 1.870000e-01 +955 9.275000e-10 0.000000e+00 1.850000e-01 +956 9.285000e-10 0.000000e+00 1.830000e-01 +957 9.295000e-10 0.000000e+00 1.810000e-01 +958 9.305000e-10 0.000000e+00 1.790000e-01 +959 9.315000e-10 0.000000e+00 1.770000e-01 +960 9.325000e-10 0.000000e+00 1.750000e-01 +961 9.335000e-10 0.000000e+00 1.730000e-01 +962 9.345000e-10 0.000000e+00 1.710000e-01 +963 9.355000e-10 0.000000e+00 1.690000e-01 +964 9.365000e-10 0.000000e+00 1.670000e-01 +965 9.375000e-10 0.000000e+00 1.650000e-01 +966 9.385000e-10 0.000000e+00 1.630000e-01 +967 9.395000e-10 0.000000e+00 1.610000e-01 +968 9.405000e-10 0.000000e+00 1.590000e-01 +969 9.415000e-10 0.000000e+00 1.570000e-01 +970 9.425000e-10 0.000000e+00 1.550000e-01 +971 9.435000e-10 0.000000e+00 1.530000e-01 +972 9.445000e-10 0.000000e+00 1.510000e-01 +973 9.455000e-10 0.000000e+00 1.490000e-01 +974 9.465000e-10 0.000000e+00 1.470000e-01 +975 9.475000e-10 0.000000e+00 1.450000e-01 +976 9.485000e-10 0.000000e+00 1.430000e-01 +977 9.495000e-10 0.000000e+00 1.410000e-01 +978 9.505000e-10 0.000000e+00 1.390000e-01 +979 9.515000e-10 0.000000e+00 1.370000e-01 +980 9.525000e-10 0.000000e+00 1.350000e-01 +981 9.535000e-10 0.000000e+00 1.330000e-01 +982 9.545000e-10 0.000000e+00 1.310000e-01 + +Index time @m1[vbs] v(g)/10 +-------------------------------------------------------------------------------- +983 9.555000e-10 0.000000e+00 1.290000e-01 +984 9.565000e-10 0.000000e+00 1.270000e-01 +985 9.575000e-10 0.000000e+00 1.250000e-01 +986 9.585000e-10 0.000000e+00 1.230000e-01 +987 9.595000e-10 0.000000e+00 1.210000e-01 +988 9.605000e-10 0.000000e+00 1.190000e-01 +989 9.615000e-10 0.000000e+00 1.170000e-01 +990 9.625000e-10 0.000000e+00 1.150000e-01 +991 9.635000e-10 0.000000e+00 1.130000e-01 +992 9.645000e-10 0.000000e+00 1.110000e-01 +993 9.655000e-10 0.000000e+00 1.090000e-01 +994 9.665000e-10 0.000000e+00 1.070000e-01 +995 9.675000e-10 0.000000e+00 1.050000e-01 +996 9.685000e-10 0.000000e+00 1.030000e-01 +997 9.695000e-10 0.000000e+00 1.010000e-01 +998 9.705000e-10 0.000000e+00 9.900000e-02 +999 9.715000e-10 0.000000e+00 9.700000e-02 +1000 9.725000e-10 0.000000e+00 9.500000e-02 +1001 9.735000e-10 0.000000e+00 9.300000e-02 +1002 9.745000e-10 0.000000e+00 9.100000e-02 +1003 9.755000e-10 0.000000e+00 8.900000e-02 +1004 9.765000e-10 0.000000e+00 8.700000e-02 +1005 9.775000e-10 0.000000e+00 8.500000e-02 +1006 9.785000e-10 0.000000e+00 8.300000e-02 +1007 9.795000e-10 0.000000e+00 8.100000e-02 +1008 9.805000e-10 0.000000e+00 7.900000e-02 +1009 9.815000e-10 0.000000e+00 7.700000e-02 +1010 9.825000e-10 0.000000e+00 7.500000e-02 +1011 9.835000e-10 0.000000e+00 7.300000e-02 +1012 9.845000e-10 0.000000e+00 7.100000e-02 +1013 9.855000e-10 0.000000e+00 6.900000e-02 +1014 9.865000e-10 0.000000e+00 6.700000e-02 +1015 9.875000e-10 0.000000e+00 6.500000e-02 +1016 9.885000e-10 0.000000e+00 6.300000e-02 +1017 9.895000e-10 0.000000e+00 6.100000e-02 +1018 9.905000e-10 0.000000e+00 5.900000e-02 +1019 9.915000e-10 0.000000e+00 5.700000e-02 +1020 9.925000e-10 0.000000e+00 5.500000e-02 +1021 9.935000e-10 0.000000e+00 5.300000e-02 +1022 9.945000e-10 0.000000e+00 5.100000e-02 +1023 9.955000e-10 0.000000e+00 4.900000e-02 +1024 9.965000e-10 0.000000e+00 4.700000e-02 +1025 9.975000e-10 0.000000e+00 4.500000e-02 +1026 9.985000e-10 0.000000e+00 4.300000e-02 +1027 9.995000e-10 0.000000e+00 4.100000e-02 +1028 1.000000e-09 0.000000e+00 4.000000e-02 + + + + diff --git a/tests/bsim3soifd/inv2.cir b/tests/bsim3soifd/inv2.cir new file mode 100644 index 000000000..6fa33b206 --- /dev/null +++ b/tests/bsim3soifd/inv2.cir @@ -0,0 +1,17 @@ +* model = BSIMSOI (FD) +* +* +* SOI Inverter - floating body + +vin in 0 dc 2.5 +vdd dd 0 dc 2.5 +vss ss 0 dc 0 +ve e 0 dc 1.25 +m1 out in dd e p1 w=20u l=0.25u +m2 out in ss e n1 w=10u l=0.25u + +.option itl1=500 gmin=1e-25 +.dc vin 0 2.5 0.01 +.print dc v(in), v(out) +.include nmosfd.mod +.include pmosfd.mod diff --git a/tests/bsim3soifd/inv2.out b/tests/bsim3soifd/inv2.out new file mode 100644 index 000000000..f14f70590 --- /dev/null +++ b/tests/bsim3soifd/inv2.out @@ -0,0 +1,281 @@ + +No. of Data Rows : 251 + +Circuit: * model = BSIMSOI (FD) + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. + * model = BSIMSOI (FD) +-------------------------------------------------------------------------------- +Index v-sweep v(in) v(out) +-------------------------------------------------------------------------------- +0 0.000000e+00 0.000000e+00 2.500000e+00 +1 1.000000e-02 1.000000e-02 2.500000e+00 +2 2.000000e-02 2.000000e-02 2.500000e+00 +3 3.000000e-02 3.000000e-02 2.500000e+00 +4 4.000000e-02 4.000000e-02 2.500000e+00 +5 5.000000e-02 5.000000e-02 2.500000e+00 +6 6.000000e-02 6.000000e-02 2.500000e+00 +7 7.000000e-02 7.000000e-02 2.500000e+00 +8 8.000000e-02 8.000000e-02 2.500000e+00 +9 9.000000e-02 9.000000e-02 2.500000e+00 +10 1.000000e-01 1.000000e-01 2.499999e+00 +11 1.100000e-01 1.100000e-01 2.499999e+00 +12 1.200000e-01 1.200000e-01 2.499999e+00 +13 1.300000e-01 1.300000e-01 2.499999e+00 +14 1.400000e-01 1.400000e-01 2.499998e+00 +15 1.500000e-01 1.500000e-01 2.499997e+00 +16 1.600000e-01 1.600000e-01 2.499996e+00 +17 1.700000e-01 1.700000e-01 2.499994e+00 +18 1.800000e-01 1.800000e-01 2.499991e+00 +19 1.900000e-01 1.900000e-01 2.499988e+00 +20 2.000000e-01 2.000000e-01 2.499983e+00 +21 2.100000e-01 2.100000e-01 2.499976e+00 +22 2.200000e-01 2.200000e-01 2.499967e+00 +23 2.300000e-01 2.300000e-01 2.499955e+00 +24 2.400000e-01 2.400000e-01 2.499938e+00 +25 2.500000e-01 2.500000e-01 2.499915e+00 +26 2.600000e-01 2.600000e-01 2.499885e+00 +27 2.700000e-01 2.700000e-01 2.499846e+00 +28 2.800000e-01 2.800000e-01 2.499794e+00 +29 2.900000e-01 2.900000e-01 2.499726e+00 +30 3.000000e-01 3.000000e-01 2.499639e+00 +31 3.100000e-01 3.100000e-01 2.499527e+00 +32 3.200000e-01 3.200000e-01 2.499386e+00 +33 3.300000e-01 3.300000e-01 2.499207e+00 +34 3.400000e-01 3.400000e-01 2.498983e+00 +35 3.500000e-01 3.500000e-01 2.498704e+00 +36 3.600000e-01 3.600000e-01 2.498361e+00 +37 3.700000e-01 3.700000e-01 2.497944e+00 +38 3.800000e-01 3.800000e-01 2.497443e+00 +39 3.900000e-01 3.900000e-01 2.496857e+00 +40 4.000000e-01 4.000000e-01 2.496188e+00 +41 4.100000e-01 4.100000e-01 2.495427e+00 +42 4.200000e-01 4.200000e-01 2.494563e+00 +43 4.300000e-01 4.300000e-01 2.493585e+00 +44 4.400000e-01 4.400000e-01 2.492485e+00 +45 4.500000e-01 4.500000e-01 2.491259e+00 +46 4.600000e-01 4.600000e-01 2.489902e+00 +47 4.700000e-01 4.700000e-01 2.488412e+00 +48 4.800000e-01 4.800000e-01 2.486790e+00 +49 4.900000e-01 4.900000e-01 2.485036e+00 +50 5.000000e-01 5.000000e-01 2.483154e+00 +51 5.100000e-01 5.100000e-01 2.481144e+00 +52 5.200000e-01 5.200000e-01 2.479013e+00 +53 5.300000e-01 5.300000e-01 2.476763e+00 +54 5.400000e-01 5.400000e-01 2.474398e+00 + +Index v-sweep v(in) v(out) +-------------------------------------------------------------------------------- +55 5.500000e-01 5.500000e-01 2.471922e+00 +56 5.600000e-01 5.600000e-01 2.469340e+00 +57 5.700000e-01 5.700000e-01 2.466654e+00 +58 5.800000e-01 5.800000e-01 2.463918e+00 +59 5.900000e-01 5.900000e-01 2.461032e+00 +60 6.000000e-01 6.000000e-01 2.458051e+00 +61 6.100000e-01 6.100000e-01 2.454976e+00 +62 6.200000e-01 6.200000e-01 2.451809e+00 +63 6.300000e-01 6.300000e-01 2.448549e+00 +64 6.400000e-01 6.400000e-01 2.445198e+00 +65 6.500000e-01 6.500000e-01 2.441756e+00 +66 6.600000e-01 6.600000e-01 2.438222e+00 +67 6.700000e-01 6.700000e-01 2.434596e+00 +68 6.800000e-01 6.800000e-01 2.430877e+00 +69 6.900000e-01 6.900000e-01 2.427064e+00 +70 7.000000e-01 7.000000e-01 2.423155e+00 +71 7.100000e-01 7.100000e-01 2.419148e+00 +72 7.200000e-01 7.200000e-01 2.415042e+00 +73 7.300000e-01 7.300000e-01 2.410835e+00 +74 7.400000e-01 7.400000e-01 2.406524e+00 +75 7.500000e-01 7.500000e-01 2.402106e+00 +76 7.600000e-01 7.600000e-01 2.397579e+00 +77 7.700000e-01 7.700000e-01 2.392939e+00 +78 7.800000e-01 7.800000e-01 2.388183e+00 +79 7.900000e-01 7.900000e-01 2.383307e+00 +80 8.000000e-01 8.000000e-01 2.378309e+00 +81 8.100000e-01 8.100000e-01 2.373182e+00 +82 8.200000e-01 8.200000e-01 2.367923e+00 +83 8.300000e-01 8.300000e-01 2.362527e+00 +84 8.400000e-01 8.400000e-01 2.356989e+00 +85 8.500000e-01 8.500000e-01 2.351303e+00 +86 8.600000e-01 8.600000e-01 2.345464e+00 +87 8.700000e-01 8.700000e-01 2.339464e+00 +88 8.800000e-01 8.800000e-01 2.333297e+00 +89 8.900000e-01 8.900000e-01 2.326955e+00 +90 9.000000e-01 9.000000e-01 2.320430e+00 +91 9.100000e-01 9.100000e-01 2.313714e+00 +92 9.200000e-01 9.200000e-01 2.306797e+00 +93 9.300000e-01 9.300000e-01 2.299668e+00 +94 9.400000e-01 9.400000e-01 2.292317e+00 +95 9.500000e-01 9.500000e-01 2.284730e+00 +96 9.600000e-01 9.600000e-01 2.276895e+00 +97 9.700000e-01 9.700000e-01 2.268797e+00 +98 9.800000e-01 9.800000e-01 2.260419e+00 +99 9.900000e-01 9.900000e-01 2.251744e+00 +100 1.000000e+00 1.000000e+00 2.242750e+00 +101 1.010000e+00 1.010000e+00 2.233418e+00 +102 1.020000e+00 1.020000e+00 2.223720e+00 +103 1.030000e+00 1.030000e+00 2.213630e+00 +104 1.040000e+00 1.040000e+00 2.203116e+00 +105 1.050000e+00 1.050000e+00 2.192141e+00 +106 1.060000e+00 1.060000e+00 2.180667e+00 +107 1.070000e+00 1.070000e+00 2.168644e+00 +108 1.080000e+00 1.080000e+00 2.156020e+00 +109 1.090000e+00 1.090000e+00 2.142730e+00 +110 1.100000e+00 1.100000e+00 2.128699e+00 +111 1.110000e+00 1.110000e+00 2.113838e+00 +112 1.120000e+00 1.120000e+00 2.098038e+00 + +Index v-sweep v(in) v(out) +-------------------------------------------------------------------------------- +113 1.130000e+00 1.130000e+00 2.081168e+00 +114 1.140000e+00 1.140000e+00 2.063060e+00 +115 1.150000e+00 1.150000e+00 2.043506e+00 +116 1.160000e+00 1.160000e+00 2.022229e+00 +117 1.170000e+00 1.170000e+00 1.998859e+00 +118 1.180000e+00 1.180000e+00 1.972881e+00 +119 1.190000e+00 1.190000e+00 1.941435e+00 +120 1.200000e+00 1.200000e+00 1.906641e+00 +121 1.210000e+00 1.210000e+00 1.864458e+00 +122 1.220000e+00 1.220000e+00 1.809591e+00 +123 1.230000e+00 1.230000e+00 1.728152e+00 +124 1.240000e+00 1.240000e+00 1.582225e+00 +125 1.250000e+00 1.250000e+00 1.353901e+00 +126 1.260000e+00 1.260000e+00 1.099554e+00 +127 1.270000e+00 1.270000e+00 8.992829e-01 +128 1.280000e+00 1.280000e+00 7.843174e-01 +129 1.290000e+00 1.290000e+00 7.150875e-01 +130 1.300000e+00 1.300000e+00 6.659598e-01 +131 1.310000e+00 1.310000e+00 6.261926e-01 +132 1.320000e+00 1.320000e+00 5.923729e-01 +133 1.330000e+00 1.330000e+00 5.626957e-01 +134 1.340000e+00 1.340000e+00 5.361114e-01 +135 1.350000e+00 1.350000e+00 5.119489e-01 +136 1.360000e+00 1.360000e+00 4.897489e-01 +137 1.370000e+00 1.370000e+00 4.691802e-01 +138 1.380000e+00 1.380000e+00 4.499945e-01 +139 1.390000e+00 1.390000e+00 4.320002e-01 +140 1.400000e+00 1.400000e+00 4.150458e-01 +141 1.410000e+00 1.410000e+00 3.990087e-01 +142 1.420000e+00 1.420000e+00 3.837887e-01 +143 1.430000e+00 1.430000e+00 3.689482e-01 +144 1.440000e+00 1.440000e+00 3.551681e-01 +145 1.450000e+00 1.450000e+00 3.419740e-01 +146 1.460000e+00 1.460000e+00 3.293280e-01 +147 1.470000e+00 1.470000e+00 3.171858e-01 +148 1.480000e+00 1.480000e+00 3.055091e-01 +149 1.490000e+00 1.490000e+00 2.942639e-01 +150 1.500000e+00 1.500000e+00 2.834205e-01 +151 1.510000e+00 1.510000e+00 2.729522e-01 +152 1.520000e+00 1.520000e+00 2.628353e-01 +153 1.530000e+00 1.530000e+00 2.530486e-01 +154 1.540000e+00 1.540000e+00 2.435729e-01 +155 1.550000e+00 1.550000e+00 2.343910e-01 +156 1.560000e+00 1.560000e+00 2.254871e-01 +157 1.570000e+00 1.570000e+00 2.168472e-01 +158 1.580000e+00 1.580000e+00 2.084581e-01 +159 1.590000e+00 1.590000e+00 2.003080e-01 +160 1.600000e+00 1.600000e+00 1.923863e-01 +161 1.610000e+00 1.610000e+00 1.846829e-01 +162 1.620000e+00 1.620000e+00 1.771887e-01 +163 1.630000e+00 1.630000e+00 1.698954e-01 +164 1.640000e+00 1.640000e+00 1.627953e-01 +165 1.650000e+00 1.650000e+00 1.558813e-01 +166 1.660000e+00 1.660000e+00 1.491470e-01 +167 1.670000e+00 1.670000e+00 1.425863e-01 +168 1.680000e+00 1.680000e+00 1.361939e-01 +169 1.690000e+00 1.690000e+00 1.299647e-01 +170 1.700000e+00 1.700000e+00 1.238942e-01 + +Index v-sweep v(in) v(out) +-------------------------------------------------------------------------------- +171 1.710000e+00 1.710000e+00 1.179781e-01 +172 1.720000e+00 1.720000e+00 1.122128e-01 +173 1.730000e+00 1.730000e+00 1.065948e-01 +174 1.740000e+00 1.740000e+00 1.011213e-01 +175 1.750000e+00 1.750000e+00 9.578971e-02 +176 1.760000e+00 1.760000e+00 9.059774e-02 +177 1.770000e+00 1.770000e+00 8.554362e-02 +178 1.780000e+00 1.780000e+00 8.062595e-02 +179 1.790000e+00 1.790000e+00 7.584371e-02 +180 1.800000e+00 1.800000e+00 7.119632e-02 +181 1.810000e+00 1.810000e+00 6.668362e-02 +182 1.820000e+00 1.820000e+00 6.237316e-02 +183 1.830000e+00 1.830000e+00 5.813162e-02 +184 1.840000e+00 1.840000e+00 5.402726e-02 +185 1.850000e+00 1.850000e+00 5.006175e-02 +186 1.860000e+00 1.860000e+00 4.623728e-02 +187 1.870000e+00 1.870000e+00 4.255645e-02 +188 1.880000e+00 1.880000e+00 3.902231e-02 +189 1.890000e+00 1.890000e+00 3.563830e-02 +190 1.900000e+00 1.900000e+00 3.240814e-02 +191 1.910000e+00 1.910000e+00 2.933576e-02 +192 1.920000e+00 1.920000e+00 2.642517e-02 +193 1.930000e+00 1.930000e+00 2.368025e-02 +194 1.940000e+00 1.940000e+00 2.110458e-02 +195 1.950000e+00 1.950000e+00 1.870116e-02 +196 1.960000e+00 1.960000e+00 1.647220e-02 +197 1.970000e+00 1.970000e+00 1.441877e-02 +198 1.980000e+00 1.980000e+00 1.254062e-02 +199 1.990000e+00 1.990000e+00 1.083588e-02 +200 2.000000e+00 2.000000e+00 9.300902e-03 +201 2.010000e+00 2.010000e+00 7.930185e-03 +202 2.020000e+00 2.020000e+00 6.716310e-03 +203 2.030000e+00 2.030000e+00 5.649981e-03 +204 2.040000e+00 2.040000e+00 4.720005e-03 +205 2.050000e+00 2.050000e+00 3.913144e-03 +206 2.060000e+00 2.060000e+00 3.214640e-03 +207 2.070000e+00 2.070000e+00 2.612806e-03 +208 2.080000e+00 2.080000e+00 2.102740e-03 +209 2.090000e+00 2.090000e+00 1.678848e-03 +210 2.100000e+00 2.100000e+00 1.331488e-03 +211 2.110000e+00 2.110000e+00 1.049587e-03 +212 2.120000e+00 2.120000e+00 8.225166e-04 +213 2.130000e+00 2.130000e+00 6.407784e-04 +214 2.140000e+00 2.140000e+00 4.961839e-04 +215 2.150000e+00 2.150000e+00 3.818140e-04 +216 2.160000e+00 2.160000e+00 2.918967e-04 +217 2.170000e+00 2.170000e+00 2.216557e-04 +218 2.180000e+00 2.180000e+00 1.671597e-04 +219 2.190000e+00 2.190000e+00 1.251862e-04 +220 2.200000e+00 2.200000e+00 9.310380e-05 +221 2.210000e+00 2.210000e+00 6.877418e-05 +222 2.220000e+00 2.220000e+00 5.047020e-05 +223 2.230000e+00 2.230000e+00 3.680768e-05 +224 2.240000e+00 2.240000e+00 2.668746e-05 +225 2.250000e+00 2.250000e+00 1.924567e-05 +226 2.260000e+00 2.260000e+00 1.381080e-05 +227 2.270000e+00 2.270000e+00 9.866643e-06 +228 2.280000e+00 2.280000e+00 7.020805e-06 + +Index v-sweep v(in) v(out) +-------------------------------------------------------------------------------- +229 2.290000e+00 2.290000e+00 4.978102e-06 +230 2.300000e+00 2.300000e+00 3.518681e-06 +231 2.310000e+00 2.310000e+00 2.480280e-06 +232 2.320000e+00 2.320000e+00 1.744116e-06 +233 2.330000e+00 2.330000e+00 1.223875e-06 +234 2.340000e+00 2.340000e+00 8.572430e-07 +235 2.350000e+00 2.350000e+00 5.994986e-07 +236 2.360000e+00 2.360000e+00 4.187151e-07 +237 2.370000e+00 2.370000e+00 2.921310e-07 +238 2.380000e+00 2.380000e+00 2.036254e-07 +239 2.390000e+00 2.390000e+00 1.418205e-07 +240 2.400000e+00 2.400000e+00 9.870679e-08 +241 2.410000e+00 2.410000e+00 6.865905e-08 +242 2.420000e+00 2.420000e+00 4.773382e-08 +243 2.430000e+00 2.430000e+00 3.317125e-08 +244 2.440000e+00 2.440000e+00 2.304252e-08 +245 2.450000e+00 2.450000e+00 1.600116e-08 +246 2.460000e+00 2.460000e+00 1.110821e-08 +247 2.470000e+00 2.470000e+00 7.709443e-09 +248 2.480000e+00 2.480000e+00 5.349347e-09 +249 2.490000e+00 2.490000e+00 3.710974e-09 +250 2.500000e+00 2.500000e+00 2.573910e-09 + + + + diff --git a/tests/bsim3soifd/t3.cir b/tests/bsim3soifd/t3.cir new file mode 100644 index 000000000..fa51d4d82 --- /dev/null +++ b/tests/bsim3soifd/t3.cir @@ -0,0 +1,18 @@ +*model = BSIMSOI (FD) +*Berkeley Spice Compatibility +* +* SOI NMOSFET, floating body simulation + +vd d 0 dc 1.5 +vs s 0 dc 0 +ve e 0 dc 0 +vg g 0 dc 3 + + +m1 d g s e n1 w=10u l=0.25u + +.option gmin=1e-25 itl1=500 +.dc vd 0 3 0.01 vg 0.5 3 0.5 +.print dc v(g), i(vs) +.include nmosfd.mod + diff --git a/tests/bsim3soifd/t3.out b/tests/bsim3soifd/t3.out new file mode 100644 index 000000000..7cf115290 --- /dev/null +++ b/tests/bsim3soifd/t3.out @@ -0,0 +1,1915 @@ + Reference value : 2.74000e+00 +No. of Data Rows : 1806 + +Circuit: *model = BSIMSOI (FD) + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. + *model = BSIMSOI (FD) +-------------------------------------------------------------------------------- +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 5.000000e-01 -1.250000e-19 +1 1.000000e-02 5.000000e-01 3.403448e-06 +2 2.000000e-02 5.000000e-01 6.447166e-06 +3 3.000000e-02 5.000000e-01 9.138041e-06 +4 4.000000e-02 5.000000e-01 1.148481e-05 +5 5.000000e-02 5.000000e-01 1.349892e-05 +6 6.000000e-02 5.000000e-01 1.519577e-05 +7 7.000000e-02 5.000000e-01 1.659602e-05 +8 8.000000e-02 5.000000e-01 1.772678e-05 +9 9.000000e-02 5.000000e-01 1.862188e-05 +10 1.000000e-01 5.000000e-01 1.932024e-05 +11 1.100000e-01 5.000000e-01 1.986244e-05 +12 1.200000e-01 5.000000e-01 2.028646e-05 +13 1.300000e-01 5.000000e-01 2.062437e-05 +14 1.400000e-01 5.000000e-01 2.090110e-05 +15 1.500000e-01 5.000000e-01 2.115380e-05 +16 1.600000e-01 5.000000e-01 2.135170e-05 +17 1.700000e-01 5.000000e-01 2.152996e-05 +18 1.800000e-01 5.000000e-01 2.169408e-05 +19 1.900000e-01 5.000000e-01 2.184783e-05 +20 2.000000e-01 5.000000e-01 2.199384e-05 +21 2.100000e-01 5.000000e-01 2.213397e-05 +22 2.200000e-01 5.000000e-01 2.226958e-05 +23 2.300000e-01 5.000000e-01 2.240167e-05 +24 2.400000e-01 5.000000e-01 2.253096e-05 +25 2.500000e-01 5.000000e-01 2.265802e-05 +26 2.600000e-01 5.000000e-01 2.278327e-05 +27 2.700000e-01 5.000000e-01 2.290706e-05 +28 2.800000e-01 5.000000e-01 2.302964e-05 +29 2.900000e-01 5.000000e-01 2.315121e-05 +30 3.000000e-01 5.000000e-01 2.327195e-05 +31 3.100000e-01 5.000000e-01 2.339200e-05 +32 3.200000e-01 5.000000e-01 2.351145e-05 +33 3.300000e-01 5.000000e-01 2.363042e-05 +34 3.400000e-01 5.000000e-01 2.374896e-05 +35 3.500000e-01 5.000000e-01 2.386715e-05 +36 3.600000e-01 5.000000e-01 2.398503e-05 +37 3.700000e-01 5.000000e-01 2.410267e-05 +38 3.800000e-01 5.000000e-01 2.422008e-05 +39 3.900000e-01 5.000000e-01 2.433732e-05 +40 4.000000e-01 5.000000e-01 2.445440e-05 +41 4.100000e-01 5.000000e-01 2.457135e-05 +42 4.200000e-01 5.000000e-01 2.468820e-05 +43 4.300000e-01 5.000000e-01 2.480496e-05 +44 4.400000e-01 5.000000e-01 2.492165e-05 +45 4.500000e-01 5.000000e-01 2.503828e-05 +46 4.600000e-01 5.000000e-01 2.515488e-05 +47 4.700000e-01 5.000000e-01 2.527144e-05 +48 4.800000e-01 5.000000e-01 2.538799e-05 +49 4.900000e-01 5.000000e-01 2.550453e-05 +50 5.000000e-01 5.000000e-01 2.562106e-05 +51 5.100000e-01 5.000000e-01 2.573761e-05 +52 5.200000e-01 5.000000e-01 2.585416e-05 +53 5.300000e-01 5.000000e-01 2.597074e-05 +54 5.400000e-01 5.000000e-01 2.608734e-05 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +55 5.500000e-01 5.000000e-01 2.620398e-05 +56 5.600000e-01 5.000000e-01 2.632064e-05 +57 5.700000e-01 5.000000e-01 2.643735e-05 +58 5.800000e-01 5.000000e-01 2.655410e-05 +59 5.900000e-01 5.000000e-01 2.667090e-05 +60 6.000000e-01 5.000000e-01 2.678775e-05 +61 6.100000e-01 5.000000e-01 2.690465e-05 +62 6.200000e-01 5.000000e-01 2.702161e-05 +63 6.300000e-01 5.000000e-01 2.713863e-05 +64 6.400000e-01 5.000000e-01 2.725571e-05 +65 6.500000e-01 5.000000e-01 2.737286e-05 +66 6.600000e-01 5.000000e-01 2.749007e-05 +67 6.700000e-01 5.000000e-01 2.760734e-05 +68 6.800000e-01 5.000000e-01 2.772469e-05 +69 6.900000e-01 5.000000e-01 2.784211e-05 +70 7.000000e-01 5.000000e-01 2.795960e-05 +71 7.100000e-01 5.000000e-01 2.807716e-05 +72 7.200000e-01 5.000000e-01 2.819481e-05 +73 7.300000e-01 5.000000e-01 2.831252e-05 +74 7.400000e-01 5.000000e-01 2.843032e-05 +75 7.500000e-01 5.000000e-01 2.854819e-05 +76 7.600000e-01 5.000000e-01 2.866615e-05 +77 7.700000e-01 5.000000e-01 2.878419e-05 +78 7.800000e-01 5.000000e-01 2.890231e-05 +79 7.900000e-01 5.000000e-01 2.902051e-05 +80 8.000000e-01 5.000000e-01 2.913880e-05 +81 8.100000e-01 5.000000e-01 2.925717e-05 +82 8.200000e-01 5.000000e-01 2.937563e-05 +83 8.300000e-01 5.000000e-01 2.949417e-05 +84 8.400000e-01 5.000000e-01 2.961280e-05 +85 8.500000e-01 5.000000e-01 2.973152e-05 +86 8.600000e-01 5.000000e-01 2.985033e-05 +87 8.700000e-01 5.000000e-01 2.996923e-05 +88 8.800000e-01 5.000000e-01 3.008821e-05 +89 8.900000e-01 5.000000e-01 3.020729e-05 +90 9.000000e-01 5.000000e-01 3.032645e-05 +91 9.100000e-01 5.000000e-01 3.044571e-05 +92 9.200000e-01 5.000000e-01 3.056506e-05 +93 9.300000e-01 5.000000e-01 3.068450e-05 +94 9.400000e-01 5.000000e-01 3.080404e-05 +95 9.500000e-01 5.000000e-01 3.092366e-05 +96 9.600000e-01 5.000000e-01 3.104338e-05 +97 9.700000e-01 5.000000e-01 3.116319e-05 +98 9.800000e-01 5.000000e-01 3.128310e-05 +99 9.900000e-01 5.000000e-01 3.140310e-05 +100 1.000000e+00 5.000000e-01 3.152320e-05 +101 1.010000e+00 5.000000e-01 3.164339e-05 +102 1.020000e+00 5.000000e-01 3.176367e-05 +103 1.030000e+00 5.000000e-01 3.188406e-05 +104 1.040000e+00 5.000000e-01 3.200453e-05 +105 1.050000e+00 5.000000e-01 3.212511e-05 +106 1.060000e+00 5.000000e-01 3.224577e-05 +107 1.070000e+00 5.000000e-01 3.236654e-05 +108 1.080000e+00 5.000000e-01 3.248740e-05 +109 1.090000e+00 5.000000e-01 3.260836e-05 +110 1.100000e+00 5.000000e-01 3.272942e-05 +111 1.110000e+00 5.000000e-01 3.285058e-05 +112 1.120000e+00 5.000000e-01 3.297183e-05 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +113 1.130000e+00 5.000000e-01 3.309318e-05 +114 1.140000e+00 5.000000e-01 3.321463e-05 +115 1.150000e+00 5.000000e-01 3.333617e-05 +116 1.160000e+00 5.000000e-01 3.345782e-05 +117 1.170000e+00 5.000000e-01 3.357956e-05 +118 1.180000e+00 5.000000e-01 3.370141e-05 +119 1.190000e+00 5.000000e-01 3.382335e-05 +120 1.200000e+00 5.000000e-01 3.394539e-05 +121 1.210000e+00 5.000000e-01 3.406753e-05 +122 1.220000e+00 5.000000e-01 3.418977e-05 +123 1.230000e+00 5.000000e-01 3.431211e-05 +124 1.240000e+00 5.000000e-01 3.443455e-05 +125 1.250000e+00 5.000000e-01 3.455709e-05 +126 1.260000e+00 5.000000e-01 3.467973e-05 +127 1.270000e+00 5.000000e-01 3.480247e-05 +128 1.280000e+00 5.000000e-01 3.492532e-05 +129 1.290000e+00 5.000000e-01 3.504826e-05 +130 1.300000e+00 5.000000e-01 3.517130e-05 +131 1.310000e+00 5.000000e-01 3.529444e-05 +132 1.320000e+00 5.000000e-01 3.541769e-05 +133 1.330000e+00 5.000000e-01 3.554103e-05 +134 1.340000e+00 5.000000e-01 3.566448e-05 +135 1.350000e+00 5.000000e-01 3.578803e-05 +136 1.360000e+00 5.000000e-01 3.591168e-05 +137 1.370000e+00 5.000000e-01 3.603543e-05 +138 1.380000e+00 5.000000e-01 3.615928e-05 +139 1.390000e+00 5.000000e-01 3.628324e-05 +140 1.400000e+00 5.000000e-01 3.640729e-05 +141 1.410000e+00 5.000000e-01 3.653145e-05 +142 1.420000e+00 5.000000e-01 3.665571e-05 +143 1.430000e+00 5.000000e-01 3.678008e-05 +144 1.440000e+00 5.000000e-01 3.690454e-05 +145 1.450000e+00 5.000000e-01 3.702911e-05 +146 1.460000e+00 5.000000e-01 3.715378e-05 +147 1.470000e+00 5.000000e-01 3.727856e-05 +148 1.480000e+00 5.000000e-01 3.740343e-05 +149 1.490000e+00 5.000000e-01 3.752841e-05 +150 1.500000e+00 5.000000e-01 3.765349e-05 +151 1.510000e+00 5.000000e-01 3.777868e-05 +152 1.520000e+00 5.000000e-01 3.790396e-05 +153 1.530000e+00 5.000000e-01 3.802935e-05 +154 1.540000e+00 5.000000e-01 3.815485e-05 +155 1.550000e+00 5.000000e-01 3.828045e-05 +156 1.560000e+00 5.000000e-01 3.840615e-05 +157 1.570000e+00 5.000000e-01 3.853195e-05 +158 1.580000e+00 5.000000e-01 3.865786e-05 +159 1.590000e+00 5.000000e-01 3.878387e-05 +160 1.600000e+00 5.000000e-01 3.890999e-05 +161 1.610000e+00 5.000000e-01 3.903621e-05 +162 1.620000e+00 5.000000e-01 3.916253e-05 +163 1.630000e+00 5.000000e-01 3.928896e-05 +164 1.640000e+00 5.000000e-01 3.941549e-05 +165 1.650000e+00 5.000000e-01 3.954213e-05 +166 1.660000e+00 5.000000e-01 3.966887e-05 +167 1.670000e+00 5.000000e-01 3.979571e-05 +168 1.680000e+00 5.000000e-01 3.992266e-05 +169 1.690000e+00 5.000000e-01 4.004971e-05 +170 1.700000e+00 5.000000e-01 4.017687e-05 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +171 1.710000e+00 5.000000e-01 4.030413e-05 +172 1.720000e+00 5.000000e-01 4.043150e-05 +173 1.730000e+00 5.000000e-01 4.055897e-05 +174 1.740000e+00 5.000000e-01 4.068655e-05 +175 1.750000e+00 5.000000e-01 4.081423e-05 +176 1.760000e+00 5.000000e-01 4.094201e-05 +177 1.770000e+00 5.000000e-01 4.106990e-05 +178 1.780000e+00 5.000000e-01 4.119790e-05 +179 1.790000e+00 5.000000e-01 4.132600e-05 +180 1.800000e+00 5.000000e-01 4.145421e-05 +181 1.810000e+00 5.000000e-01 4.158252e-05 +182 1.820000e+00 5.000000e-01 4.171094e-05 +183 1.830000e+00 5.000000e-01 4.183946e-05 +184 1.840000e+00 5.000000e-01 4.196809e-05 +185 1.850000e+00 5.000000e-01 4.209682e-05 +186 1.860000e+00 5.000000e-01 4.222566e-05 +187 1.870000e+00 5.000000e-01 4.235461e-05 +188 1.880000e+00 5.000000e-01 4.248366e-05 +189 1.890000e+00 5.000000e-01 4.261281e-05 +190 1.900000e+00 5.000000e-01 4.274208e-05 +191 1.910000e+00 5.000000e-01 4.287144e-05 +192 1.920000e+00 5.000000e-01 4.300092e-05 +193 1.930000e+00 5.000000e-01 4.313050e-05 +194 1.940000e+00 5.000000e-01 4.326018e-05 +195 1.950000e+00 5.000000e-01 4.338998e-05 +196 1.960000e+00 5.000000e-01 4.351988e-05 +197 1.970000e+00 5.000000e-01 4.364988e-05 +198 1.980000e+00 5.000000e-01 4.377999e-05 +199 1.990000e+00 5.000000e-01 4.391021e-05 +200 2.000000e+00 5.000000e-01 4.404053e-05 +201 2.010000e+00 5.000000e-01 4.417096e-05 +202 2.020000e+00 5.000000e-01 4.430150e-05 +203 2.030000e+00 5.000000e-01 4.443214e-05 +204 2.040000e+00 5.000000e-01 4.456289e-05 +205 2.050000e+00 5.000000e-01 4.469375e-05 +206 2.060000e+00 5.000000e-01 4.482471e-05 +207 2.070000e+00 5.000000e-01 4.495578e-05 +208 2.080000e+00 5.000000e-01 4.508696e-05 +209 2.090000e+00 5.000000e-01 4.521825e-05 +210 2.100000e+00 5.000000e-01 4.534964e-05 +211 2.110000e+00 5.000000e-01 4.548114e-05 +212 2.120000e+00 5.000000e-01 4.561274e-05 +213 2.130000e+00 5.000000e-01 4.574445e-05 +214 2.140000e+00 5.000000e-01 4.587627e-05 +215 2.150000e+00 5.000000e-01 4.600820e-05 +216 2.160000e+00 5.000000e-01 4.614024e-05 +217 2.170000e+00 5.000000e-01 4.627238e-05 +218 2.180000e+00 5.000000e-01 4.640463e-05 +219 2.190000e+00 5.000000e-01 4.653698e-05 +220 2.200000e+00 5.000000e-01 4.666945e-05 +221 2.210000e+00 5.000000e-01 4.680202e-05 +222 2.220000e+00 5.000000e-01 4.693470e-05 +223 2.230000e+00 5.000000e-01 4.706749e-05 +224 2.240000e+00 5.000000e-01 4.720038e-05 +225 2.250000e+00 5.000000e-01 4.733338e-05 +226 2.260000e+00 5.000000e-01 4.746649e-05 +227 2.270000e+00 5.000000e-01 4.759971e-05 +228 2.280000e+00 5.000000e-01 4.773304e-05 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +229 2.290000e+00 5.000000e-01 4.786647e-05 +230 2.300000e+00 5.000000e-01 4.800002e-05 +231 2.310000e+00 5.000000e-01 4.813367e-05 +232 2.320000e+00 5.000000e-01 4.826743e-05 +233 2.330000e+00 5.000000e-01 4.840129e-05 +234 2.340000e+00 5.000000e-01 4.853527e-05 +235 2.350000e+00 5.000000e-01 4.866935e-05 +236 2.360000e+00 5.000000e-01 4.880354e-05 +237 2.370000e+00 5.000000e-01 4.893784e-05 +238 2.380000e+00 5.000000e-01 4.907225e-05 +239 2.390000e+00 5.000000e-01 4.920677e-05 +240 2.400000e+00 5.000000e-01 4.934140e-05 +241 2.410000e+00 5.000000e-01 4.947613e-05 +242 2.420000e+00 5.000000e-01 4.961097e-05 +243 2.430000e+00 5.000000e-01 4.974593e-05 +244 2.440000e+00 5.000000e-01 4.988099e-05 +245 2.450000e+00 5.000000e-01 5.001616e-05 +246 2.460000e+00 5.000000e-01 5.015143e-05 +247 2.470000e+00 5.000000e-01 5.028682e-05 +248 2.480000e+00 5.000000e-01 5.042232e-05 +249 2.490000e+00 5.000000e-01 5.055792e-05 +250 2.500000e+00 5.000000e-01 5.069364e-05 +251 2.510000e+00 5.000000e-01 5.082946e-05 +252 2.520000e+00 5.000000e-01 5.096539e-05 +253 2.530000e+00 5.000000e-01 5.110144e-05 +254 2.540000e+00 5.000000e-01 5.123759e-05 +255 2.550000e+00 5.000000e-01 5.137385e-05 +256 2.560000e+00 5.000000e-01 5.151022e-05 +257 2.570000e+00 5.000000e-01 5.164670e-05 +258 2.580000e+00 5.000000e-01 5.178328e-05 +259 2.590000e+00 5.000000e-01 5.191998e-05 +260 2.600000e+00 5.000000e-01 5.205679e-05 +261 2.610000e+00 5.000000e-01 5.219371e-05 +262 2.620000e+00 5.000000e-01 5.233073e-05 +263 2.630000e+00 5.000000e-01 5.246787e-05 +264 2.640000e+00 5.000000e-01 5.260512e-05 +265 2.650000e+00 5.000000e-01 5.274247e-05 +266 2.660000e+00 5.000000e-01 5.287994e-05 +267 2.670000e+00 5.000000e-01 5.301751e-05 +268 2.680000e+00 5.000000e-01 5.315520e-05 +269 2.690000e+00 5.000000e-01 5.329300e-05 +270 2.700000e+00 5.000000e-01 5.343090e-05 +271 2.710000e+00 5.000000e-01 5.356892e-05 +272 2.720000e+00 5.000000e-01 5.370704e-05 +273 2.730000e+00 5.000000e-01 5.384528e-05 +274 2.740000e+00 5.000000e-01 5.398363e-05 +275 2.750000e+00 5.000000e-01 5.412208e-05 +276 2.760000e+00 5.000000e-01 5.426065e-05 +277 2.770000e+00 5.000000e-01 5.439933e-05 +278 2.780000e+00 5.000000e-01 5.453811e-05 +279 2.790000e+00 5.000000e-01 5.467701e-05 +280 2.800000e+00 5.000000e-01 5.481602e-05 +281 2.810000e+00 5.000000e-01 5.495514e-05 +282 2.820000e+00 5.000000e-01 5.509437e-05 +283 2.830000e+00 5.000000e-01 5.523371e-05 +284 2.840000e+00 5.000000e-01 5.537316e-05 +285 2.850000e+00 5.000000e-01 5.551272e-05 +286 2.860000e+00 5.000000e-01 5.565239e-05 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +287 2.870000e+00 5.000000e-01 5.579218e-05 +288 2.880000e+00 5.000000e-01 5.593207e-05 +289 2.890000e+00 5.000000e-01 5.607208e-05 +290 2.900000e+00 5.000000e-01 5.621219e-05 +291 2.910000e+00 5.000000e-01 5.635242e-05 +292 2.920000e+00 5.000000e-01 5.649276e-05 +293 2.930000e+00 5.000000e-01 5.663321e-05 +294 2.940000e+00 5.000000e-01 5.677377e-05 +295 2.950000e+00 5.000000e-01 5.691444e-05 +296 2.960000e+00 5.000000e-01 5.705522e-05 +297 2.970000e+00 5.000000e-01 5.719612e-05 +298 2.980000e+00 5.000000e-01 5.733712e-05 +299 2.990000e+00 5.000000e-01 5.747824e-05 +300 3.000000e+00 5.000000e-01 5.761947e-05 +301 0.000000e+00 1.000000e+00 -1.250000e-19 +302 1.000000e-02 1.000000e+00 3.008580e-05 +303 2.000000e-02 1.000000e+00 5.960829e-05 +304 3.000000e-02 1.000000e+00 8.856943e-05 +305 4.000000e-02 1.000000e+00 1.169712e-04 +306 5.000000e-02 1.000000e+00 1.448155e-04 +307 6.000000e-02 1.000000e+00 1.721043e-04 +308 7.000000e-02 1.000000e+00 1.988396e-04 +309 8.000000e-02 1.000000e+00 2.250233e-04 +310 9.000000e-02 1.000000e+00 2.506572e-04 +311 1.000000e-01 1.000000e+00 2.760169e-04 +312 1.100000e-01 1.000000e+00 3.005563e-04 +313 1.200000e-01 1.000000e+00 3.245517e-04 +314 1.300000e-01 1.000000e+00 3.480051e-04 +315 1.400000e-01 1.000000e+00 3.709184e-04 +316 1.500000e-01 1.000000e+00 3.932934e-04 +317 1.600000e-01 1.000000e+00 4.151321e-04 +318 1.700000e-01 1.000000e+00 4.364364e-04 +319 1.800000e-01 1.000000e+00 4.572082e-04 +320 1.900000e-01 1.000000e+00 4.774494e-04 +321 2.000000e-01 1.000000e+00 4.971618e-04 +322 2.100000e-01 1.000000e+00 5.163475e-04 +323 2.200000e-01 1.000000e+00 5.350084e-04 +324 2.300000e-01 1.000000e+00 5.531463e-04 +325 2.400000e-01 1.000000e+00 5.707632e-04 +326 2.500000e-01 1.000000e+00 5.878612e-04 +327 2.600000e-01 1.000000e+00 6.044421e-04 +328 2.700000e-01 1.000000e+00 6.205080e-04 +329 2.800000e-01 1.000000e+00 6.360610e-04 +330 2.900000e-01 1.000000e+00 6.511031e-04 +331 3.000000e-01 1.000000e+00 6.656366e-04 +332 3.100000e-01 1.000000e+00 6.796635e-04 +333 3.200000e-01 1.000000e+00 6.931863e-04 +334 3.300000e-01 1.000000e+00 7.062073e-04 +335 3.400000e-01 1.000000e+00 7.187291e-04 +336 3.500000e-01 1.000000e+00 7.307544e-04 +337 3.600000e-01 1.000000e+00 7.422861e-04 +338 3.700000e-01 1.000000e+00 7.533272e-04 +339 3.800000e-01 1.000000e+00 7.638814e-04 +340 3.900000e-01 1.000000e+00 7.739524e-04 +341 4.000000e-01 1.000000e+00 7.835445e-04 +342 4.100000e-01 1.000000e+00 7.926628e-04 +343 4.200000e-01 1.000000e+00 8.013129e-04 +344 4.300000e-01 1.000000e+00 8.095013e-04 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +345 4.400000e-01 1.000000e+00 8.172357e-04 +346 4.500000e-01 1.000000e+00 8.245250e-04 +347 4.600000e-01 1.000000e+00 8.313797e-04 +348 4.700000e-01 1.000000e+00 8.378116e-04 +349 4.800000e-01 1.000000e+00 8.438347e-04 +350 4.900000e-01 1.000000e+00 8.494647e-04 +351 5.000000e-01 1.000000e+00 8.547190e-04 +352 5.100000e-01 1.000000e+00 8.596170e-04 +353 5.200000e-01 1.000000e+00 8.641793e-04 +354 5.300000e-01 1.000000e+00 8.684279e-04 +355 5.400000e-01 1.000000e+00 8.723852e-04 +356 5.500000e-01 1.000000e+00 8.760739e-04 +357 5.600000e-01 1.000000e+00 8.795164e-04 +358 5.700000e-01 1.000000e+00 8.827344e-04 +359 5.800000e-01 1.000000e+00 8.857487e-04 +360 5.900000e-01 1.000000e+00 8.885786e-04 +361 6.000000e-01 1.000000e+00 8.912422e-04 +362 6.100000e-01 1.000000e+00 8.937558e-04 +363 6.200000e-01 1.000000e+00 8.961346e-04 +364 6.300000e-01 1.000000e+00 8.983919e-04 +365 6.400000e-01 1.000000e+00 9.005400e-04 +366 6.500000e-01 1.000000e+00 9.025896e-04 +367 6.600000e-01 1.000000e+00 9.045506e-04 +368 6.700000e-01 1.000000e+00 9.064315e-04 +369 6.800000e-01 1.000000e+00 9.082400e-04 +370 6.900000e-01 1.000000e+00 9.099829e-04 +371 7.000000e-01 1.000000e+00 9.116664e-04 +372 7.100000e-01 1.000000e+00 9.132959e-04 +373 7.200000e-01 1.000000e+00 9.148761e-04 +374 7.300000e-01 1.000000e+00 9.164115e-04 +375 7.400000e-01 1.000000e+00 9.179058e-04 +376 7.500000e-01 1.000000e+00 9.193625e-04 +377 7.600000e-01 1.000000e+00 9.207848e-04 +378 7.700000e-01 1.000000e+00 9.221753e-04 +379 7.800000e-01 1.000000e+00 9.235367e-04 +380 7.900000e-01 1.000000e+00 9.248711e-04 +381 8.000000e-01 1.000000e+00 9.261806e-04 +382 8.100000e-01 1.000000e+00 9.274671e-04 +383 8.200000e-01 1.000000e+00 9.287322e-04 +384 8.300000e-01 1.000000e+00 9.299774e-04 +385 8.400000e-01 1.000000e+00 9.312042e-04 +386 8.500000e-01 1.000000e+00 9.324138e-04 +387 8.600000e-01 1.000000e+00 9.336073e-04 +388 8.700000e-01 1.000000e+00 9.347859e-04 +389 8.800000e-01 1.000000e+00 9.359504e-04 +390 8.900000e-01 1.000000e+00 9.371018e-04 +391 9.000000e-01 1.000000e+00 9.382408e-04 +392 9.100000e-01 1.000000e+00 9.393683e-04 +393 9.200000e-01 1.000000e+00 9.404849e-04 +394 9.300000e-01 1.000000e+00 9.415913e-04 +395 9.400000e-01 1.000000e+00 9.426880e-04 +396 9.500000e-01 1.000000e+00 9.437756e-04 +397 9.600000e-01 1.000000e+00 9.448547e-04 +398 9.700000e-01 1.000000e+00 9.459256e-04 +399 9.800000e-01 1.000000e+00 9.469888e-04 +400 9.900000e-01 1.000000e+00 9.480447e-04 +401 1.000000e+00 1.000000e+00 9.490938e-04 +402 1.010000e+00 1.000000e+00 9.501363e-04 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +403 1.020000e+00 1.000000e+00 9.511726e-04 +404 1.030000e+00 1.000000e+00 9.522029e-04 +405 1.040000e+00 1.000000e+00 9.532277e-04 +406 1.050000e+00 1.000000e+00 9.542471e-04 +407 1.060000e+00 1.000000e+00 9.552614e-04 +408 1.070000e+00 1.000000e+00 9.562709e-04 +409 1.080000e+00 1.000000e+00 9.572757e-04 +410 1.090000e+00 1.000000e+00 9.582762e-04 +411 1.100000e+00 1.000000e+00 9.592724e-04 +412 1.110000e+00 1.000000e+00 9.602645e-04 +413 1.120000e+00 1.000000e+00 9.612528e-04 +414 1.130000e+00 1.000000e+00 9.622374e-04 +415 1.140000e+00 1.000000e+00 9.632185e-04 +416 1.150000e+00 1.000000e+00 9.641962e-04 +417 1.160000e+00 1.000000e+00 9.651706e-04 +418 1.170000e+00 1.000000e+00 9.661419e-04 +419 1.180000e+00 1.000000e+00 9.671102e-04 +420 1.190000e+00 1.000000e+00 9.680757e-04 +421 1.200000e+00 1.000000e+00 9.690384e-04 +422 1.210000e+00 1.000000e+00 9.699984e-04 +423 1.220000e+00 1.000000e+00 9.709559e-04 +424 1.230000e+00 1.000000e+00 9.719109e-04 +425 1.240000e+00 1.000000e+00 9.728636e-04 +426 1.250000e+00 1.000000e+00 9.738140e-04 +427 1.260000e+00 1.000000e+00 9.747622e-04 +428 1.270000e+00 1.000000e+00 9.757083e-04 +429 1.280000e+00 1.000000e+00 9.766524e-04 +430 1.290000e+00 1.000000e+00 9.775944e-04 +431 1.300000e+00 1.000000e+00 9.785346e-04 +432 1.310000e+00 1.000000e+00 9.794730e-04 +433 1.320000e+00 1.000000e+00 9.804096e-04 +434 1.330000e+00 1.000000e+00 9.813445e-04 +435 1.340000e+00 1.000000e+00 9.822777e-04 +436 1.350000e+00 1.000000e+00 9.832093e-04 +437 1.360000e+00 1.000000e+00 9.841394e-04 +438 1.370000e+00 1.000000e+00 9.850680e-04 +439 1.380000e+00 1.000000e+00 9.859952e-04 +440 1.390000e+00 1.000000e+00 9.869210e-04 +441 1.400000e+00 1.000000e+00 9.878454e-04 +442 1.410000e+00 1.000000e+00 9.887684e-04 +443 1.420000e+00 1.000000e+00 9.896903e-04 +444 1.430000e+00 1.000000e+00 9.906108e-04 +445 1.440000e+00 1.000000e+00 9.915302e-04 +446 1.450000e+00 1.000000e+00 9.924484e-04 +447 1.460000e+00 1.000000e+00 9.933655e-04 +448 1.470000e+00 1.000000e+00 9.942816e-04 +449 1.480000e+00 1.000000e+00 9.951965e-04 +450 1.490000e+00 1.000000e+00 9.961104e-04 +451 1.500000e+00 1.000000e+00 9.970233e-04 +452 1.510000e+00 1.000000e+00 9.979353e-04 +453 1.520000e+00 1.000000e+00 9.988463e-04 +454 1.530000e+00 1.000000e+00 9.997564e-04 +455 1.540000e+00 1.000000e+00 1.000666e-03 +456 1.550000e+00 1.000000e+00 1.001574e-03 +457 1.560000e+00 1.000000e+00 1.002481e-03 +458 1.570000e+00 1.000000e+00 1.003388e-03 +459 1.580000e+00 1.000000e+00 1.004294e-03 +460 1.590000e+00 1.000000e+00 1.005199e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +461 1.600000e+00 1.000000e+00 1.006103e-03 +462 1.610000e+00 1.000000e+00 1.007007e-03 +463 1.620000e+00 1.000000e+00 1.007910e-03 +464 1.630000e+00 1.000000e+00 1.008812e-03 +465 1.640000e+00 1.000000e+00 1.009714e-03 +466 1.650000e+00 1.000000e+00 1.010614e-03 +467 1.660000e+00 1.000000e+00 1.011515e-03 +468 1.670000e+00 1.000000e+00 1.012414e-03 +469 1.680000e+00 1.000000e+00 1.013313e-03 +470 1.690000e+00 1.000000e+00 1.014212e-03 +471 1.700000e+00 1.000000e+00 1.015109e-03 +472 1.710000e+00 1.000000e+00 1.016007e-03 +473 1.720000e+00 1.000000e+00 1.016903e-03 +474 1.730000e+00 1.000000e+00 1.017799e-03 +475 1.740000e+00 1.000000e+00 1.018695e-03 +476 1.750000e+00 1.000000e+00 1.019590e-03 +477 1.760000e+00 1.000000e+00 1.020484e-03 +478 1.770000e+00 1.000000e+00 1.021379e-03 +479 1.780000e+00 1.000000e+00 1.022272e-03 +480 1.790000e+00 1.000000e+00 1.023165e-03 +481 1.800000e+00 1.000000e+00 1.024058e-03 +482 1.810000e+00 1.000000e+00 1.024950e-03 +483 1.820000e+00 1.000000e+00 1.025842e-03 +484 1.830000e+00 1.000000e+00 1.026733e-03 +485 1.840000e+00 1.000000e+00 1.027624e-03 +486 1.850000e+00 1.000000e+00 1.028515e-03 +487 1.860000e+00 1.000000e+00 1.029405e-03 +488 1.870000e+00 1.000000e+00 1.030295e-03 +489 1.880000e+00 1.000000e+00 1.031184e-03 +490 1.890000e+00 1.000000e+00 1.032073e-03 +491 1.900000e+00 1.000000e+00 1.032961e-03 +492 1.910000e+00 1.000000e+00 1.033850e-03 +493 1.920000e+00 1.000000e+00 1.034738e-03 +494 1.930000e+00 1.000000e+00 1.035625e-03 +495 1.940000e+00 1.000000e+00 1.036512e-03 +496 1.950000e+00 1.000000e+00 1.037399e-03 +497 1.960000e+00 1.000000e+00 1.038286e-03 +498 1.970000e+00 1.000000e+00 1.039172e-03 +499 1.980000e+00 1.000000e+00 1.040058e-03 +500 1.990000e+00 1.000000e+00 1.040944e-03 +501 2.000000e+00 1.000000e+00 1.041829e-03 +502 2.010000e+00 1.000000e+00 1.042714e-03 +503 2.020000e+00 1.000000e+00 1.043599e-03 +504 2.030000e+00 1.000000e+00 1.044483e-03 +505 2.040000e+00 1.000000e+00 1.045368e-03 +506 2.050000e+00 1.000000e+00 1.046252e-03 +507 2.060000e+00 1.000000e+00 1.047135e-03 +508 2.070000e+00 1.000000e+00 1.048019e-03 +509 2.080000e+00 1.000000e+00 1.048902e-03 +510 2.090000e+00 1.000000e+00 1.049785e-03 +511 2.100000e+00 1.000000e+00 1.050668e-03 +512 2.110000e+00 1.000000e+00 1.051550e-03 +513 2.120000e+00 1.000000e+00 1.052432e-03 +514 2.130000e+00 1.000000e+00 1.053314e-03 +515 2.140000e+00 1.000000e+00 1.054196e-03 +516 2.150000e+00 1.000000e+00 1.055078e-03 +517 2.160000e+00 1.000000e+00 1.055959e-03 +518 2.170000e+00 1.000000e+00 1.056840e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +519 2.180000e+00 1.000000e+00 1.057721e-03 +520 2.190000e+00 1.000000e+00 1.058602e-03 +521 2.200000e+00 1.000000e+00 1.059483e-03 +522 2.210000e+00 1.000000e+00 1.060363e-03 +523 2.220000e+00 1.000000e+00 1.061243e-03 +524 2.230000e+00 1.000000e+00 1.062123e-03 +525 2.240000e+00 1.000000e+00 1.063003e-03 +526 2.250000e+00 1.000000e+00 1.063883e-03 +527 2.260000e+00 1.000000e+00 1.064762e-03 +528 2.270000e+00 1.000000e+00 1.065641e-03 +529 2.280000e+00 1.000000e+00 1.066520e-03 +530 2.290000e+00 1.000000e+00 1.067399e-03 +531 2.300000e+00 1.000000e+00 1.068278e-03 +532 2.310000e+00 1.000000e+00 1.069157e-03 +533 2.320000e+00 1.000000e+00 1.070035e-03 +534 2.330000e+00 1.000000e+00 1.070913e-03 +535 2.340000e+00 1.000000e+00 1.071792e-03 +536 2.350000e+00 1.000000e+00 1.072670e-03 +537 2.360000e+00 1.000000e+00 1.073547e-03 +538 2.370000e+00 1.000000e+00 1.074425e-03 +539 2.380000e+00 1.000000e+00 1.075303e-03 +540 2.390000e+00 1.000000e+00 1.076180e-03 +541 2.400000e+00 1.000000e+00 1.077057e-03 +542 2.410000e+00 1.000000e+00 1.077935e-03 +543 2.420000e+00 1.000000e+00 1.078812e-03 +544 2.430000e+00 1.000000e+00 1.079689e-03 +545 2.440000e+00 1.000000e+00 1.080565e-03 +546 2.450000e+00 1.000000e+00 1.081442e-03 +547 2.460000e+00 1.000000e+00 1.082318e-03 +548 2.470000e+00 1.000000e+00 1.083195e-03 +549 2.480000e+00 1.000000e+00 1.084071e-03 +550 2.490000e+00 1.000000e+00 1.084947e-03 +551 2.500000e+00 1.000000e+00 1.085823e-03 +552 2.510000e+00 1.000000e+00 1.086699e-03 +553 2.520000e+00 1.000000e+00 1.087575e-03 +554 2.530000e+00 1.000000e+00 1.088451e-03 +555 2.540000e+00 1.000000e+00 1.089327e-03 +556 2.550000e+00 1.000000e+00 1.090202e-03 +557 2.560000e+00 1.000000e+00 1.091077e-03 +558 2.570000e+00 1.000000e+00 1.091953e-03 +559 2.580000e+00 1.000000e+00 1.092828e-03 +560 2.590000e+00 1.000000e+00 1.093703e-03 +561 2.600000e+00 1.000000e+00 1.094578e-03 +562 2.610000e+00 1.000000e+00 1.095453e-03 +563 2.620000e+00 1.000000e+00 1.096328e-03 +564 2.630000e+00 1.000000e+00 1.097203e-03 +565 2.640000e+00 1.000000e+00 1.098077e-03 +566 2.650000e+00 1.000000e+00 1.098952e-03 +567 2.660000e+00 1.000000e+00 1.099826e-03 +568 2.670000e+00 1.000000e+00 1.100701e-03 +569 2.680000e+00 1.000000e+00 1.101575e-03 +570 2.690000e+00 1.000000e+00 1.102449e-03 +571 2.700000e+00 1.000000e+00 1.103324e-03 +572 2.710000e+00 1.000000e+00 1.104198e-03 +573 2.720000e+00 1.000000e+00 1.105072e-03 +574 2.730000e+00 1.000000e+00 1.105946e-03 +575 2.740000e+00 1.000000e+00 1.106819e-03 +576 2.750000e+00 1.000000e+00 1.107693e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +577 2.760000e+00 1.000000e+00 1.108567e-03 +578 2.770000e+00 1.000000e+00 1.109440e-03 +579 2.780000e+00 1.000000e+00 1.110314e-03 +580 2.790000e+00 1.000000e+00 1.111188e-03 +581 2.800000e+00 1.000000e+00 1.112061e-03 +582 2.810000e+00 1.000000e+00 1.112934e-03 +583 2.820000e+00 1.000000e+00 1.113808e-03 +584 2.830000e+00 1.000000e+00 1.114681e-03 +585 2.840000e+00 1.000000e+00 1.115554e-03 +586 2.850000e+00 1.000000e+00 1.116427e-03 +587 2.860000e+00 1.000000e+00 1.117300e-03 +588 2.870000e+00 1.000000e+00 1.118173e-03 +589 2.880000e+00 1.000000e+00 1.119046e-03 +590 2.890000e+00 1.000000e+00 1.119919e-03 +591 2.900000e+00 1.000000e+00 1.120792e-03 +592 2.910000e+00 1.000000e+00 1.121664e-03 +593 2.920000e+00 1.000000e+00 1.122537e-03 +594 2.930000e+00 1.000000e+00 1.123410e-03 +595 2.940000e+00 1.000000e+00 1.124282e-03 +596 2.950000e+00 1.000000e+00 1.125155e-03 +597 2.960000e+00 1.000000e+00 1.126027e-03 +598 2.970000e+00 1.000000e+00 1.126900e-03 +599 2.980000e+00 1.000000e+00 1.127772e-03 +600 2.990000e+00 1.000000e+00 1.128645e-03 +601 3.000000e+00 1.000000e+00 1.129517e-03 +602 0.000000e+00 1.500000e+00 -1.250000e-19 +603 1.000000e-02 1.500000e+00 4.561848e-05 +604 2.000000e-02 1.500000e+00 9.076433e-05 +605 3.000000e-02 1.500000e+00 1.354387e-04 +606 4.000000e-02 1.500000e+00 1.796427e-04 +607 5.000000e-02 1.500000e+00 2.233776e-04 +608 6.000000e-02 1.500000e+00 2.668782e-04 +609 7.000000e-02 1.500000e+00 3.096776e-04 +610 8.000000e-02 1.500000e+00 3.520112e-04 +611 9.000000e-02 1.500000e+00 3.938802e-04 +612 1.000000e-01 1.500000e+00 4.352856e-04 +613 1.100000e-01 1.500000e+00 4.762287e-04 +614 1.200000e-01 1.500000e+00 5.167105e-04 +615 1.300000e-01 1.500000e+00 5.567322e-04 +616 1.400000e-01 1.500000e+00 5.962948e-04 +617 1.500000e-01 1.500000e+00 6.353995e-04 +618 1.600000e-01 1.500000e+00 6.740473e-04 +619 1.700000e-01 1.500000e+00 7.122394e-04 +620 1.800000e-01 1.500000e+00 7.499769e-04 +621 1.900000e-01 1.500000e+00 7.872608e-04 +622 2.000000e-01 1.500000e+00 8.240922e-04 +623 2.100000e-01 1.500000e+00 8.604722e-04 +624 2.200000e-01 1.500000e+00 8.964018e-04 +625 2.300000e-01 1.500000e+00 9.318822e-04 +626 2.400000e-01 1.500000e+00 9.669144e-04 +627 2.500000e-01 1.500000e+00 1.001499e-03 +628 2.600000e-01 1.500000e+00 1.035638e-03 +629 2.700000e-01 1.500000e+00 1.069332e-03 +630 2.800000e-01 1.500000e+00 1.102582e-03 +631 2.900000e-01 1.500000e+00 1.135389e-03 +632 3.000000e-01 1.500000e+00 1.167754e-03 +633 3.100000e-01 1.500000e+00 1.199678e-03 +634 3.200000e-01 1.500000e+00 1.231162e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +635 3.300000e-01 1.500000e+00 1.262207e-03 +636 3.400000e-01 1.500000e+00 1.292814e-03 +637 3.500000e-01 1.500000e+00 1.322984e-03 +638 3.600000e-01 1.500000e+00 1.352718e-03 +639 3.700000e-01 1.500000e+00 1.382017e-03 +640 3.800000e-01 1.500000e+00 1.410882e-03 +641 3.900000e-01 1.500000e+00 1.439314e-03 +642 4.000000e-01 1.500000e+00 1.467314e-03 +643 4.100000e-01 1.500000e+00 1.494883e-03 +644 4.200000e-01 1.500000e+00 1.522021e-03 +645 4.300000e-01 1.500000e+00 1.548730e-03 +646 4.400000e-01 1.500000e+00 1.575010e-03 +647 4.500000e-01 1.500000e+00 1.600863e-03 +648 4.600000e-01 1.500000e+00 1.626289e-03 +649 4.700000e-01 1.500000e+00 1.651288e-03 +650 4.800000e-01 1.500000e+00 1.675863e-03 +651 4.900000e-01 1.500000e+00 1.700013e-03 +652 5.000000e-01 1.500000e+00 1.723740e-03 +653 5.100000e-01 1.500000e+00 1.747043e-03 +654 5.200000e-01 1.500000e+00 1.769924e-03 +655 5.300000e-01 1.500000e+00 1.792384e-03 +656 5.400000e-01 1.500000e+00 1.814423e-03 +657 5.500000e-01 1.500000e+00 1.836041e-03 +658 5.600000e-01 1.500000e+00 1.857239e-03 +659 5.700000e-01 1.500000e+00 1.878018e-03 +660 5.800000e-01 1.500000e+00 1.898378e-03 +661 5.900000e-01 1.500000e+00 1.918320e-03 +662 6.000000e-01 1.500000e+00 1.937843e-03 +663 6.100000e-01 1.500000e+00 1.956948e-03 +664 6.200000e-01 1.500000e+00 1.975635e-03 +665 6.300000e-01 1.500000e+00 1.993905e-03 +666 6.400000e-01 1.500000e+00 2.011756e-03 +667 6.500000e-01 1.500000e+00 2.029189e-03 +668 6.600000e-01 1.500000e+00 2.046204e-03 +669 6.700000e-01 1.500000e+00 2.062801e-03 +670 6.800000e-01 1.500000e+00 2.078977e-03 +671 6.900000e-01 1.500000e+00 2.094734e-03 +672 7.000000e-01 1.500000e+00 2.110070e-03 +673 7.100000e-01 1.500000e+00 2.124985e-03 +674 7.200000e-01 1.500000e+00 2.139477e-03 +675 7.300000e-01 1.500000e+00 2.153544e-03 +676 7.400000e-01 1.500000e+00 2.167187e-03 +677 7.500000e-01 1.500000e+00 2.180403e-03 +678 7.600000e-01 1.500000e+00 2.193191e-03 +679 7.700000e-01 1.500000e+00 2.205550e-03 +680 7.800000e-01 1.500000e+00 2.217478e-03 +681 7.900000e-01 1.500000e+00 2.228975e-03 +682 8.000000e-01 1.500000e+00 2.240039e-03 +683 8.100000e-01 1.500000e+00 2.250672e-03 +684 8.200000e-01 1.500000e+00 2.260874e-03 +685 8.300000e-01 1.500000e+00 2.270645e-03 +686 8.400000e-01 1.500000e+00 2.279989e-03 +687 8.500000e-01 1.500000e+00 2.288910e-03 +688 8.600000e-01 1.500000e+00 2.297413e-03 +689 8.700000e-01 1.500000e+00 2.305505e-03 +690 8.800000e-01 1.500000e+00 2.313195e-03 +691 8.900000e-01 1.500000e+00 2.320492e-03 +692 9.000000e-01 1.500000e+00 2.327409e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +693 9.100000e-01 1.500000e+00 2.333960e-03 +694 9.200000e-01 1.500000e+00 2.340158e-03 +695 9.300000e-01 1.500000e+00 2.346021e-03 +696 9.400000e-01 1.500000e+00 2.351565e-03 +697 9.500000e-01 1.500000e+00 2.356806e-03 +698 9.600000e-01 1.500000e+00 2.361763e-03 +699 9.700000e-01 1.500000e+00 2.366454e-03 +700 9.800000e-01 1.500000e+00 2.370895e-03 +701 9.900000e-01 1.500000e+00 2.375103e-03 +702 1.000000e+00 1.500000e+00 2.379095e-03 +703 1.010000e+00 1.500000e+00 2.382886e-03 +704 1.020000e+00 1.500000e+00 2.386490e-03 +705 1.030000e+00 1.500000e+00 2.389922e-03 +706 1.040000e+00 1.500000e+00 2.393195e-03 +707 1.050000e+00 1.500000e+00 2.396320e-03 +708 1.060000e+00 1.500000e+00 2.399308e-03 +709 1.070000e+00 1.500000e+00 2.402171e-03 +710 1.080000e+00 1.500000e+00 2.404917e-03 +711 1.090000e+00 1.500000e+00 2.407555e-03 +712 1.100000e+00 1.500000e+00 2.410094e-03 +713 1.110000e+00 1.500000e+00 2.412541e-03 +714 1.120000e+00 1.500000e+00 2.414901e-03 +715 1.130000e+00 1.500000e+00 2.417183e-03 +716 1.140000e+00 1.500000e+00 2.419391e-03 +717 1.150000e+00 1.500000e+00 2.421531e-03 +718 1.160000e+00 1.500000e+00 2.423607e-03 +719 1.170000e+00 1.500000e+00 2.425624e-03 +720 1.180000e+00 1.500000e+00 2.427587e-03 +721 1.190000e+00 1.500000e+00 2.429497e-03 +722 1.200000e+00 1.500000e+00 2.431360e-03 +723 1.210000e+00 1.500000e+00 2.433178e-03 +724 1.220000e+00 1.500000e+00 2.434954e-03 +725 1.230000e+00 1.500000e+00 2.436691e-03 +726 1.240000e+00 1.500000e+00 2.438390e-03 +727 1.250000e+00 1.500000e+00 2.440056e-03 +728 1.260000e+00 1.500000e+00 2.441689e-03 +729 1.270000e+00 1.500000e+00 2.443291e-03 +730 1.280000e+00 1.500000e+00 2.444865e-03 +731 1.290000e+00 1.500000e+00 2.446411e-03 +732 1.300000e+00 1.500000e+00 2.447932e-03 +733 1.310000e+00 1.500000e+00 2.449429e-03 +734 1.320000e+00 1.500000e+00 2.450904e-03 +735 1.330000e+00 1.500000e+00 2.452356e-03 +736 1.340000e+00 1.500000e+00 2.453789e-03 +737 1.350000e+00 1.500000e+00 2.455202e-03 +738 1.360000e+00 1.500000e+00 2.456597e-03 +739 1.370000e+00 1.500000e+00 2.457974e-03 +740 1.380000e+00 1.500000e+00 2.459335e-03 +741 1.390000e+00 1.500000e+00 2.460680e-03 +742 1.400000e+00 1.500000e+00 2.462011e-03 +743 1.410000e+00 1.500000e+00 2.463327e-03 +744 1.420000e+00 1.500000e+00 2.464630e-03 +745 1.430000e+00 1.500000e+00 2.465920e-03 +746 1.440000e+00 1.500000e+00 2.467197e-03 +747 1.450000e+00 1.500000e+00 2.468463e-03 +748 1.460000e+00 1.500000e+00 2.469718e-03 +749 1.470000e+00 1.500000e+00 2.470962e-03 +750 1.480000e+00 1.500000e+00 2.472196e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +751 1.490000e+00 1.500000e+00 2.473420e-03 +752 1.500000e+00 1.500000e+00 2.474635e-03 +753 1.510000e+00 1.500000e+00 2.475841e-03 +754 1.520000e+00 1.500000e+00 2.477038e-03 +755 1.530000e+00 1.500000e+00 2.478227e-03 +756 1.540000e+00 1.500000e+00 2.479408e-03 +757 1.550000e+00 1.500000e+00 2.480582e-03 +758 1.560000e+00 1.500000e+00 2.481748e-03 +759 1.570000e+00 1.500000e+00 2.482907e-03 +760 1.580000e+00 1.500000e+00 2.484060e-03 +761 1.590000e+00 1.500000e+00 2.485206e-03 +762 1.600000e+00 1.500000e+00 2.486346e-03 +763 1.610000e+00 1.500000e+00 2.487480e-03 +764 1.620000e+00 1.500000e+00 2.488608e-03 +765 1.630000e+00 1.500000e+00 2.489730e-03 +766 1.640000e+00 1.500000e+00 2.490848e-03 +767 1.650000e+00 1.500000e+00 2.491960e-03 +768 1.660000e+00 1.500000e+00 2.493067e-03 +769 1.670000e+00 1.500000e+00 2.494169e-03 +770 1.680000e+00 1.500000e+00 2.495267e-03 +771 1.690000e+00 1.500000e+00 2.496360e-03 +772 1.700000e+00 1.500000e+00 2.497448e-03 +773 1.710000e+00 1.500000e+00 2.498533e-03 +774 1.720000e+00 1.500000e+00 2.499614e-03 +775 1.730000e+00 1.500000e+00 2.500690e-03 +776 1.740000e+00 1.500000e+00 2.501763e-03 +777 1.750000e+00 1.500000e+00 2.502832e-03 +778 1.760000e+00 1.500000e+00 2.503898e-03 +779 1.770000e+00 1.500000e+00 2.504960e-03 +780 1.780000e+00 1.500000e+00 2.506019e-03 +781 1.790000e+00 1.500000e+00 2.507074e-03 +782 1.800000e+00 1.500000e+00 2.508127e-03 +783 1.810000e+00 1.500000e+00 2.509176e-03 +784 1.820000e+00 1.500000e+00 2.510222e-03 +785 1.830000e+00 1.500000e+00 2.511266e-03 +786 1.840000e+00 1.500000e+00 2.512307e-03 +787 1.850000e+00 1.500000e+00 2.513345e-03 +788 1.860000e+00 1.500000e+00 2.514380e-03 +789 1.870000e+00 1.500000e+00 2.515413e-03 +790 1.880000e+00 1.500000e+00 2.516444e-03 +791 1.890000e+00 1.500000e+00 2.517472e-03 +792 1.900000e+00 1.500000e+00 2.518497e-03 +793 1.910000e+00 1.500000e+00 2.519521e-03 +794 1.920000e+00 1.500000e+00 2.520542e-03 +795 1.930000e+00 1.500000e+00 2.521561e-03 +796 1.940000e+00 1.500000e+00 2.522578e-03 +797 1.950000e+00 1.500000e+00 2.523593e-03 +798 1.960000e+00 1.500000e+00 2.524606e-03 +799 1.970000e+00 1.500000e+00 2.525616e-03 +800 1.980000e+00 1.500000e+00 2.526626e-03 +801 1.990000e+00 1.500000e+00 2.527633e-03 +802 2.000000e+00 1.500000e+00 2.528638e-03 +803 2.010000e+00 1.500000e+00 2.529642e-03 +804 2.020000e+00 1.500000e+00 2.530644e-03 +805 2.030000e+00 1.500000e+00 2.531644e-03 +806 2.040000e+00 1.500000e+00 2.532643e-03 +807 2.050000e+00 1.500000e+00 2.533640e-03 +808 2.060000e+00 1.500000e+00 2.534635e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +809 2.070000e+00 1.500000e+00 2.535630e-03 +810 2.080000e+00 1.500000e+00 2.536622e-03 +811 2.090000e+00 1.500000e+00 2.537613e-03 +812 2.100000e+00 1.500000e+00 2.538603e-03 +813 2.110000e+00 1.500000e+00 2.539591e-03 +814 2.120000e+00 1.500000e+00 2.540578e-03 +815 2.130000e+00 1.500000e+00 2.541564e-03 +816 2.140000e+00 1.500000e+00 2.542549e-03 +817 2.150000e+00 1.500000e+00 2.543532e-03 +818 2.160000e+00 1.500000e+00 2.544514e-03 +819 2.170000e+00 1.500000e+00 2.545494e-03 +820 2.180000e+00 1.500000e+00 2.546474e-03 +821 2.190000e+00 1.500000e+00 2.547453e-03 +822 2.200000e+00 1.500000e+00 2.548430e-03 +823 2.210000e+00 1.500000e+00 2.549406e-03 +824 2.220000e+00 1.500000e+00 2.550381e-03 +825 2.230000e+00 1.500000e+00 2.551355e-03 +826 2.240000e+00 1.500000e+00 2.552329e-03 +827 2.250000e+00 1.500000e+00 2.553301e-03 +828 2.260000e+00 1.500000e+00 2.554272e-03 +829 2.270000e+00 1.500000e+00 2.555242e-03 +830 2.280000e+00 1.500000e+00 2.556211e-03 +831 2.290000e+00 1.500000e+00 2.557179e-03 +832 2.300000e+00 1.500000e+00 2.558147e-03 +833 2.310000e+00 1.500000e+00 2.559113e-03 +834 2.320000e+00 1.500000e+00 2.560079e-03 +835 2.330000e+00 1.500000e+00 2.561044e-03 +836 2.340000e+00 1.500000e+00 2.562008e-03 +837 2.350000e+00 1.500000e+00 2.562971e-03 +838 2.360000e+00 1.500000e+00 2.563933e-03 +839 2.370000e+00 1.500000e+00 2.564894e-03 +840 2.380000e+00 1.500000e+00 2.565855e-03 +841 2.390000e+00 1.500000e+00 2.566815e-03 +842 2.400000e+00 1.500000e+00 2.567774e-03 +843 2.410000e+00 1.500000e+00 2.568733e-03 +844 2.420000e+00 1.500000e+00 2.569691e-03 +845 2.430000e+00 1.500000e+00 2.570648e-03 +846 2.440000e+00 1.500000e+00 2.571604e-03 +847 2.450000e+00 1.500000e+00 2.572560e-03 +848 2.460000e+00 1.500000e+00 2.573515e-03 +849 2.470000e+00 1.500000e+00 2.574469e-03 +850 2.480000e+00 1.500000e+00 2.575423e-03 +851 2.490000e+00 1.500000e+00 2.576376e-03 +852 2.500000e+00 1.500000e+00 2.577329e-03 +853 2.510000e+00 1.500000e+00 2.578281e-03 +854 2.520000e+00 1.500000e+00 2.579232e-03 +855 2.530000e+00 1.500000e+00 2.580183e-03 +856 2.540000e+00 1.500000e+00 2.581133e-03 +857 2.550000e+00 1.500000e+00 2.582082e-03 +858 2.560000e+00 1.500000e+00 2.583031e-03 +859 2.570000e+00 1.500000e+00 2.583980e-03 +860 2.580000e+00 1.500000e+00 2.584928e-03 +861 2.590000e+00 1.500000e+00 2.585875e-03 +862 2.600000e+00 1.500000e+00 2.586822e-03 +863 2.610000e+00 1.500000e+00 2.587768e-03 +864 2.620000e+00 1.500000e+00 2.588714e-03 +865 2.630000e+00 1.500000e+00 2.589660e-03 +866 2.640000e+00 1.500000e+00 2.590604e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +867 2.650000e+00 1.500000e+00 2.591549e-03 +868 2.660000e+00 1.500000e+00 2.592493e-03 +869 2.670000e+00 1.500000e+00 2.593436e-03 +870 2.680000e+00 1.500000e+00 2.594379e-03 +871 2.690000e+00 1.500000e+00 2.595322e-03 +872 2.700000e+00 1.500000e+00 2.596264e-03 +873 2.710000e+00 1.500000e+00 2.597205e-03 +874 2.720000e+00 1.500000e+00 2.598147e-03 +875 2.730000e+00 1.500000e+00 2.599088e-03 +876 2.740000e+00 1.500000e+00 2.600028e-03 +877 2.750000e+00 1.500000e+00 2.600968e-03 +878 2.760000e+00 1.500000e+00 2.601908e-03 +879 2.770000e+00 1.500000e+00 2.602847e-03 +880 2.780000e+00 1.500000e+00 2.603785e-03 +881 2.790000e+00 1.500000e+00 2.604724e-03 +882 2.800000e+00 1.500000e+00 2.605662e-03 +883 2.810000e+00 1.500000e+00 2.606600e-03 +884 2.820000e+00 1.500000e+00 2.607537e-03 +885 2.830000e+00 1.500000e+00 2.608474e-03 +886 2.840000e+00 1.500000e+00 2.609410e-03 +887 2.850000e+00 1.500000e+00 2.610347e-03 +888 2.860000e+00 1.500000e+00 2.611283e-03 +889 2.870000e+00 1.500000e+00 2.612218e-03 +890 2.880000e+00 1.500000e+00 2.613153e-03 +891 2.890000e+00 1.500000e+00 2.614088e-03 +892 2.900000e+00 1.500000e+00 2.615023e-03 +893 2.910000e+00 1.500000e+00 2.615957e-03 +894 2.920000e+00 1.500000e+00 2.616891e-03 +895 2.930000e+00 1.500000e+00 2.617824e-03 +896 2.940000e+00 1.500000e+00 2.618758e-03 +897 2.950000e+00 1.500000e+00 2.619691e-03 +898 2.960000e+00 1.500000e+00 2.620623e-03 +899 2.970000e+00 1.500000e+00 2.621556e-03 +900 2.980000e+00 1.500000e+00 2.622488e-03 +901 2.990000e+00 1.500000e+00 2.623419e-03 +902 3.000000e+00 1.500000e+00 2.624351e-03 +903 0.000000e+00 2.000000e+00 -1.250000e-19 +904 1.000000e-02 2.000000e+00 5.434813e-05 +905 2.000000e-02 2.000000e+00 1.083028e-04 +906 3.000000e-02 2.000000e+00 1.618647e-04 +907 4.000000e-02 2.000000e+00 2.152306e-04 +908 5.000000e-02 2.000000e+00 2.680090e-04 +909 6.000000e-02 2.000000e+00 3.203969e-04 +910 7.000000e-02 2.000000e+00 3.723951e-04 +911 8.000000e-02 2.000000e+00 4.240043e-04 +912 9.000000e-02 2.000000e+00 4.752252e-04 +913 1.000000e-01 2.000000e+00 5.260586e-04 +914 1.100000e-01 2.000000e+00 5.765052e-04 +915 1.200000e-01 2.000000e+00 6.265657e-04 +916 1.300000e-01 2.000000e+00 6.762409e-04 +917 1.400000e-01 2.000000e+00 7.255314e-04 +918 1.500000e-01 2.000000e+00 7.744380e-04 +919 1.600000e-01 2.000000e+00 8.229615e-04 +920 1.700000e-01 2.000000e+00 8.711025e-04 +921 1.800000e-01 2.000000e+00 9.188618e-04 +922 1.900000e-01 2.000000e+00 9.662400e-04 +923 2.000000e-01 2.000000e+00 1.013238e-03 +924 2.100000e-01 2.000000e+00 1.059856e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +925 2.200000e-01 2.000000e+00 1.106096e-03 +926 2.300000e-01 2.000000e+00 1.151957e-03 +927 2.400000e-01 2.000000e+00 1.197440e-03 +928 2.500000e-01 2.000000e+00 1.242547e-03 +929 2.600000e-01 2.000000e+00 1.287278e-03 +930 2.700000e-01 2.000000e+00 1.331633e-03 +931 2.800000e-01 2.000000e+00 1.375614e-03 +932 2.900000e-01 2.000000e+00 1.419221e-03 +933 3.000000e-01 2.000000e+00 1.462454e-03 +934 3.100000e-01 2.000000e+00 1.505315e-03 +935 3.200000e-01 2.000000e+00 1.547803e-03 +936 3.300000e-01 2.000000e+00 1.589921e-03 +937 3.400000e-01 2.000000e+00 1.631667e-03 +938 3.500000e-01 2.000000e+00 1.673044e-03 +939 3.600000e-01 2.000000e+00 1.714052e-03 +940 3.700000e-01 2.000000e+00 1.754690e-03 +941 3.800000e-01 2.000000e+00 1.794961e-03 +942 3.900000e-01 2.000000e+00 1.834865e-03 +943 4.000000e-01 2.000000e+00 1.874402e-03 +944 4.100000e-01 2.000000e+00 1.913573e-03 +945 4.200000e-01 2.000000e+00 1.952379e-03 +946 4.300000e-01 2.000000e+00 1.990820e-03 +947 4.400000e-01 2.000000e+00 2.028896e-03 +948 4.500000e-01 2.000000e+00 2.066610e-03 +949 4.600000e-01 2.000000e+00 2.103961e-03 +950 4.700000e-01 2.000000e+00 2.140949e-03 +951 4.800000e-01 2.000000e+00 2.177576e-03 +952 4.900000e-01 2.000000e+00 2.213843e-03 +953 5.000000e-01 2.000000e+00 2.249748e-03 +954 5.100000e-01 2.000000e+00 2.285295e-03 +955 5.200000e-01 2.000000e+00 2.320482e-03 +956 5.300000e-01 2.000000e+00 2.355310e-03 +957 5.400000e-01 2.000000e+00 2.389781e-03 +958 5.500000e-01 2.000000e+00 2.423895e-03 +959 5.600000e-01 2.000000e+00 2.457651e-03 +960 5.700000e-01 2.000000e+00 2.491052e-03 +961 5.800000e-01 2.000000e+00 2.524097e-03 +962 5.900000e-01 2.000000e+00 2.556787e-03 +963 6.000000e-01 2.000000e+00 2.589123e-03 +964 6.100000e-01 2.000000e+00 2.621104e-03 +965 6.200000e-01 2.000000e+00 2.652733e-03 +966 6.300000e-01 2.000000e+00 2.684008e-03 +967 6.400000e-01 2.000000e+00 2.714931e-03 +968 6.500000e-01 2.000000e+00 2.745502e-03 +969 6.600000e-01 2.000000e+00 2.775722e-03 +970 6.700000e-01 2.000000e+00 2.805591e-03 +971 6.800000e-01 2.000000e+00 2.835109e-03 +972 6.900000e-01 2.000000e+00 2.864278e-03 +973 7.000000e-01 2.000000e+00 2.893096e-03 +974 7.100000e-01 2.000000e+00 2.921566e-03 +975 7.200000e-01 2.000000e+00 2.949687e-03 +976 7.300000e-01 2.000000e+00 2.977459e-03 +977 7.400000e-01 2.000000e+00 3.004883e-03 +978 7.500000e-01 2.000000e+00 3.031959e-03 +979 7.600000e-01 2.000000e+00 3.058688e-03 +980 7.700000e-01 2.000000e+00 3.085070e-03 +981 7.800000e-01 2.000000e+00 3.111105e-03 +982 7.900000e-01 2.000000e+00 3.136792e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +983 8.000000e-01 2.000000e+00 3.162134e-03 +984 8.100000e-01 2.000000e+00 3.187128e-03 +985 8.200000e-01 2.000000e+00 3.211776e-03 +986 8.300000e-01 2.000000e+00 3.236078e-03 +987 8.400000e-01 2.000000e+00 3.260033e-03 +988 8.500000e-01 2.000000e+00 3.283641e-03 +989 8.600000e-01 2.000000e+00 3.306903e-03 +990 8.700000e-01 2.000000e+00 3.329818e-03 +991 8.800000e-01 2.000000e+00 3.352385e-03 +992 8.900000e-01 2.000000e+00 3.374605e-03 +993 9.000000e-01 2.000000e+00 3.396476e-03 +994 9.100000e-01 2.000000e+00 3.417999e-03 +995 9.200000e-01 2.000000e+00 3.439172e-03 +996 9.300000e-01 2.000000e+00 3.459996e-03 +997 9.400000e-01 2.000000e+00 3.480467e-03 +998 9.500000e-01 2.000000e+00 3.500587e-03 +999 9.600000e-01 2.000000e+00 3.520353e-03 +1000 9.700000e-01 2.000000e+00 3.539765e-03 +1001 9.800000e-01 2.000000e+00 3.558820e-03 +1002 9.900000e-01 2.000000e+00 3.577517e-03 +1003 1.000000e+00 2.000000e+00 3.595854e-03 +1004 1.010000e+00 2.000000e+00 3.613828e-03 +1005 1.020000e+00 2.000000e+00 3.631439e-03 +1006 1.030000e+00 2.000000e+00 3.648682e-03 +1007 1.040000e+00 2.000000e+00 3.665555e-03 +1008 1.050000e+00 2.000000e+00 3.682056e-03 +1009 1.060000e+00 2.000000e+00 3.698180e-03 +1010 1.070000e+00 2.000000e+00 3.713925e-03 +1011 1.080000e+00 2.000000e+00 3.729288e-03 +1012 1.090000e+00 2.000000e+00 3.744263e-03 +1013 1.100000e+00 2.000000e+00 3.758847e-03 +1014 1.110000e+00 2.000000e+00 3.773037e-03 +1015 1.120000e+00 2.000000e+00 3.786829e-03 +1016 1.130000e+00 2.000000e+00 3.800218e-03 +1017 1.140000e+00 2.000000e+00 3.813201e-03 +1018 1.150000e+00 2.000000e+00 3.825775e-03 +1019 1.160000e+00 2.000000e+00 3.837937e-03 +1020 1.170000e+00 2.000000e+00 3.849685e-03 +1021 1.180000e+00 2.000000e+00 3.861018e-03 +1022 1.190000e+00 2.000000e+00 3.871935e-03 +1023 1.200000e+00 2.000000e+00 3.882437e-03 +1024 1.210000e+00 2.000000e+00 3.892525e-03 +1025 1.220000e+00 2.000000e+00 3.902204e-03 +1026 1.230000e+00 2.000000e+00 3.911478e-03 +1027 1.240000e+00 2.000000e+00 3.920353e-03 +1028 1.250000e+00 2.000000e+00 3.928836e-03 +1029 1.260000e+00 2.000000e+00 3.936937e-03 +1030 1.270000e+00 2.000000e+00 3.944666e-03 +1031 1.280000e+00 2.000000e+00 3.952035e-03 +1032 1.290000e+00 2.000000e+00 3.959057e-03 +1033 1.300000e+00 2.000000e+00 3.965744e-03 +1034 1.310000e+00 2.000000e+00 3.972112e-03 +1035 1.320000e+00 2.000000e+00 3.978175e-03 +1036 1.330000e+00 2.000000e+00 3.983947e-03 +1037 1.340000e+00 2.000000e+00 3.989444e-03 +1038 1.350000e+00 2.000000e+00 3.994681e-03 +1039 1.360000e+00 2.000000e+00 3.999671e-03 +1040 1.370000e+00 2.000000e+00 4.004431e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1041 1.380000e+00 2.000000e+00 4.008973e-03 +1042 1.390000e+00 2.000000e+00 4.013310e-03 +1043 1.400000e+00 2.000000e+00 4.017456e-03 +1044 1.410000e+00 2.000000e+00 4.021422e-03 +1045 1.420000e+00 2.000000e+00 4.025220e-03 +1046 1.430000e+00 2.000000e+00 4.028861e-03 +1047 1.440000e+00 2.000000e+00 4.032355e-03 +1048 1.450000e+00 2.000000e+00 4.035711e-03 +1049 1.460000e+00 2.000000e+00 4.038938e-03 +1050 1.470000e+00 2.000000e+00 4.042045e-03 +1051 1.480000e+00 2.000000e+00 4.045039e-03 +1052 1.490000e+00 2.000000e+00 4.047928e-03 +1053 1.500000e+00 2.000000e+00 4.050719e-03 +1054 1.510000e+00 2.000000e+00 4.053417e-03 +1055 1.520000e+00 2.000000e+00 4.056028e-03 +1056 1.530000e+00 2.000000e+00 4.058558e-03 +1057 1.540000e+00 2.000000e+00 4.061012e-03 +1058 1.550000e+00 2.000000e+00 4.063394e-03 +1059 1.560000e+00 2.000000e+00 4.065710e-03 +1060 1.570000e+00 2.000000e+00 4.067962e-03 +1061 1.580000e+00 2.000000e+00 4.070154e-03 +1062 1.590000e+00 2.000000e+00 4.072291e-03 +1063 1.600000e+00 2.000000e+00 4.074375e-03 +1064 1.610000e+00 2.000000e+00 4.076409e-03 +1065 1.620000e+00 2.000000e+00 4.078396e-03 +1066 1.630000e+00 2.000000e+00 4.080339e-03 +1067 1.640000e+00 2.000000e+00 4.082241e-03 +1068 1.650000e+00 2.000000e+00 4.084102e-03 +1069 1.660000e+00 2.000000e+00 4.085926e-03 +1070 1.670000e+00 2.000000e+00 4.087715e-03 +1071 1.680000e+00 2.000000e+00 4.089470e-03 +1072 1.690000e+00 2.000000e+00 4.091193e-03 +1073 1.700000e+00 2.000000e+00 4.092886e-03 +1074 1.710000e+00 2.000000e+00 4.094550e-03 +1075 1.720000e+00 2.000000e+00 4.096186e-03 +1076 1.730000e+00 2.000000e+00 4.097797e-03 +1077 1.740000e+00 2.000000e+00 4.099383e-03 +1078 1.750000e+00 2.000000e+00 4.100945e-03 +1079 1.760000e+00 2.000000e+00 4.102485e-03 +1080 1.770000e+00 2.000000e+00 4.104004e-03 +1081 1.780000e+00 2.000000e+00 4.105502e-03 +1082 1.790000e+00 2.000000e+00 4.106980e-03 +1083 1.800000e+00 2.000000e+00 4.108440e-03 +1084 1.810000e+00 2.000000e+00 4.109882e-03 +1085 1.820000e+00 2.000000e+00 4.111307e-03 +1086 1.830000e+00 2.000000e+00 4.112715e-03 +1087 1.840000e+00 2.000000e+00 4.114109e-03 +1088 1.850000e+00 2.000000e+00 4.115487e-03 +1089 1.860000e+00 2.000000e+00 4.116850e-03 +1090 1.870000e+00 2.000000e+00 4.118200e-03 +1091 1.880000e+00 2.000000e+00 4.119537e-03 +1092 1.890000e+00 2.000000e+00 4.120861e-03 +1093 1.900000e+00 2.000000e+00 4.122173e-03 +1094 1.910000e+00 2.000000e+00 4.123473e-03 +1095 1.920000e+00 2.000000e+00 4.124762e-03 +1096 1.930000e+00 2.000000e+00 4.126040e-03 +1097 1.940000e+00 2.000000e+00 4.127308e-03 +1098 1.950000e+00 2.000000e+00 4.128566e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1099 1.960000e+00 2.000000e+00 4.129814e-03 +1100 1.970000e+00 2.000000e+00 4.131052e-03 +1101 1.980000e+00 2.000000e+00 4.132282e-03 +1102 1.990000e+00 2.000000e+00 4.133503e-03 +1103 2.000000e+00 2.000000e+00 4.134716e-03 +1104 2.010000e+00 2.000000e+00 4.135921e-03 +1105 2.020000e+00 2.000000e+00 4.137118e-03 +1106 2.030000e+00 2.000000e+00 4.138307e-03 +1107 2.040000e+00 2.000000e+00 4.139489e-03 +1108 2.050000e+00 2.000000e+00 4.140664e-03 +1109 2.060000e+00 2.000000e+00 4.141833e-03 +1110 2.070000e+00 2.000000e+00 4.142994e-03 +1111 2.080000e+00 2.000000e+00 4.144150e-03 +1112 2.090000e+00 2.000000e+00 4.145299e-03 +1113 2.100000e+00 2.000000e+00 4.146443e-03 +1114 2.110000e+00 2.000000e+00 4.147580e-03 +1115 2.120000e+00 2.000000e+00 4.148712e-03 +1116 2.130000e+00 2.000000e+00 4.149839e-03 +1117 2.140000e+00 2.000000e+00 4.150960e-03 +1118 2.150000e+00 2.000000e+00 4.152076e-03 +1119 2.160000e+00 2.000000e+00 4.153188e-03 +1120 2.170000e+00 2.000000e+00 4.154294e-03 +1121 2.180000e+00 2.000000e+00 4.155396e-03 +1122 2.190000e+00 2.000000e+00 4.156494e-03 +1123 2.200000e+00 2.000000e+00 4.157587e-03 +1124 2.210000e+00 2.000000e+00 4.158675e-03 +1125 2.220000e+00 2.000000e+00 4.159760e-03 +1126 2.230000e+00 2.000000e+00 4.160841e-03 +1127 2.240000e+00 2.000000e+00 4.161917e-03 +1128 2.250000e+00 2.000000e+00 4.162990e-03 +1129 2.260000e+00 2.000000e+00 4.164059e-03 +1130 2.270000e+00 2.000000e+00 4.165125e-03 +1131 2.280000e+00 2.000000e+00 4.166187e-03 +1132 2.290000e+00 2.000000e+00 4.167246e-03 +1133 2.300000e+00 2.000000e+00 4.168301e-03 +1134 2.310000e+00 2.000000e+00 4.169353e-03 +1135 2.320000e+00 2.000000e+00 4.170402e-03 +1136 2.330000e+00 2.000000e+00 4.171448e-03 +1137 2.340000e+00 2.000000e+00 4.172491e-03 +1138 2.350000e+00 2.000000e+00 4.173531e-03 +1139 2.360000e+00 2.000000e+00 4.174569e-03 +1140 2.370000e+00 2.000000e+00 4.175603e-03 +1141 2.380000e+00 2.000000e+00 4.176635e-03 +1142 2.390000e+00 2.000000e+00 4.177664e-03 +1143 2.400000e+00 2.000000e+00 4.178690e-03 +1144 2.410000e+00 2.000000e+00 4.179714e-03 +1145 2.420000e+00 2.000000e+00 4.180736e-03 +1146 2.430000e+00 2.000000e+00 4.181755e-03 +1147 2.440000e+00 2.000000e+00 4.182772e-03 +1148 2.450000e+00 2.000000e+00 4.183787e-03 +1149 2.460000e+00 2.000000e+00 4.184799e-03 +1150 2.470000e+00 2.000000e+00 4.185809e-03 +1151 2.480000e+00 2.000000e+00 4.186817e-03 +1152 2.490000e+00 2.000000e+00 4.187823e-03 +1153 2.500000e+00 2.000000e+00 4.188827e-03 +1154 2.510000e+00 2.000000e+00 4.189829e-03 +1155 2.520000e+00 2.000000e+00 4.190829e-03 +1156 2.530000e+00 2.000000e+00 4.191827e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1157 2.540000e+00 2.000000e+00 4.192824e-03 +1158 2.550000e+00 2.000000e+00 4.193818e-03 +1159 2.560000e+00 2.000000e+00 4.194811e-03 +1160 2.570000e+00 2.000000e+00 4.195802e-03 +1161 2.580000e+00 2.000000e+00 4.196791e-03 +1162 2.590000e+00 2.000000e+00 4.197779e-03 +1163 2.600000e+00 2.000000e+00 4.198765e-03 +1164 2.610000e+00 2.000000e+00 4.199749e-03 +1165 2.620000e+00 2.000000e+00 4.200732e-03 +1166 2.630000e+00 2.000000e+00 4.201713e-03 +1167 2.640000e+00 2.000000e+00 4.202693e-03 +1168 2.650000e+00 2.000000e+00 4.203671e-03 +1169 2.660000e+00 2.000000e+00 4.204648e-03 +1170 2.670000e+00 2.000000e+00 4.205623e-03 +1171 2.680000e+00 2.000000e+00 4.206597e-03 +1172 2.690000e+00 2.000000e+00 4.207570e-03 +1173 2.700000e+00 2.000000e+00 4.208541e-03 +1174 2.710000e+00 2.000000e+00 4.209511e-03 +1175 2.720000e+00 2.000000e+00 4.210480e-03 +1176 2.730000e+00 2.000000e+00 4.211448e-03 +1177 2.740000e+00 2.000000e+00 4.212414e-03 +1178 2.750000e+00 2.000000e+00 4.213379e-03 +1179 2.760000e+00 2.000000e+00 4.214343e-03 +1180 2.770000e+00 2.000000e+00 4.215306e-03 +1181 2.780000e+00 2.000000e+00 4.216267e-03 +1182 2.790000e+00 2.000000e+00 4.217228e-03 +1183 2.800000e+00 2.000000e+00 4.218187e-03 +1184 2.810000e+00 2.000000e+00 4.219145e-03 +1185 2.820000e+00 2.000000e+00 4.220102e-03 +1186 2.830000e+00 2.000000e+00 4.221059e-03 +1187 2.840000e+00 2.000000e+00 4.222014e-03 +1188 2.850000e+00 2.000000e+00 4.222968e-03 +1189 2.860000e+00 2.000000e+00 4.223921e-03 +1190 2.870000e+00 2.000000e+00 4.224873e-03 +1191 2.880000e+00 2.000000e+00 4.225825e-03 +1192 2.890000e+00 2.000000e+00 4.226775e-03 +1193 2.900000e+00 2.000000e+00 4.227724e-03 +1194 2.910000e+00 2.000000e+00 4.228673e-03 +1195 2.920000e+00 2.000000e+00 4.229620e-03 +1196 2.930000e+00 2.000000e+00 4.230567e-03 +1197 2.940000e+00 2.000000e+00 4.231513e-03 +1198 2.950000e+00 2.000000e+00 4.232458e-03 +1199 2.960000e+00 2.000000e+00 4.233402e-03 +1200 2.970000e+00 2.000000e+00 4.234345e-03 +1201 2.980000e+00 2.000000e+00 4.235288e-03 +1202 2.990000e+00 2.000000e+00 4.236230e-03 +1203 3.000000e+00 2.000000e+00 4.237171e-03 +1204 0.000000e+00 2.500000e+00 -1.250000e-19 +1205 1.000000e-02 2.500000e+00 5.937829e-05 +1206 2.000000e-02 2.500000e+00 1.184251e-04 +1207 3.000000e-02 2.500000e+00 1.773062e-04 +1208 4.000000e-02 2.500000e+00 2.356913e-04 +1209 5.000000e-02 2.500000e+00 2.937463e-04 +1210 6.000000e-02 2.500000e+00 3.514719e-04 +1211 7.000000e-02 2.500000e+00 4.088685e-04 +1212 8.000000e-02 2.500000e+00 4.659367e-04 +1213 9.000000e-02 2.500000e+00 5.226769e-04 +1214 1.000000e-01 2.500000e+00 5.790896e-04 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1215 1.100000e-01 2.500000e+00 6.351755e-04 +1216 1.200000e-01 2.500000e+00 6.909349e-04 +1217 1.300000e-01 2.500000e+00 7.463683e-04 +1218 1.400000e-01 2.500000e+00 8.014764e-04 +1219 1.500000e-01 2.500000e+00 8.562595e-04 +1220 1.600000e-01 2.500000e+00 9.107181e-04 +1221 1.700000e-01 2.500000e+00 9.648528e-04 +1222 1.800000e-01 2.500000e+00 1.018664e-03 +1223 1.900000e-01 2.500000e+00 1.072152e-03 +1224 2.000000e-01 2.500000e+00 1.125318e-03 +1225 2.100000e-01 2.500000e+00 1.178162e-03 +1226 2.200000e-01 2.500000e+00 1.230685e-03 +1227 2.300000e-01 2.500000e+00 1.282886e-03 +1228 2.400000e-01 2.500000e+00 1.334767e-03 +1229 2.500000e-01 2.500000e+00 1.386328e-03 +1230 2.600000e-01 2.500000e+00 1.437569e-03 +1231 2.700000e-01 2.500000e+00 1.488492e-03 +1232 2.800000e-01 2.500000e+00 1.539095e-03 +1233 2.900000e-01 2.500000e+00 1.589381e-03 +1234 3.000000e-01 2.500000e+00 1.639349e-03 +1235 3.100000e-01 2.500000e+00 1.689000e-03 +1236 3.200000e-01 2.500000e+00 1.738335e-03 +1237 3.300000e-01 2.500000e+00 1.787353e-03 +1238 3.400000e-01 2.500000e+00 1.836055e-03 +1239 3.500000e-01 2.500000e+00 1.884443e-03 +1240 3.600000e-01 2.500000e+00 1.932515e-03 +1241 3.700000e-01 2.500000e+00 1.980273e-03 +1242 3.800000e-01 2.500000e+00 2.027718e-03 +1243 3.900000e-01 2.500000e+00 2.074849e-03 +1244 4.000000e-01 2.500000e+00 2.121667e-03 +1245 4.100000e-01 2.500000e+00 2.168173e-03 +1246 4.200000e-01 2.500000e+00 2.214367e-03 +1247 4.300000e-01 2.500000e+00 2.260250e-03 +1248 4.400000e-01 2.500000e+00 2.305821e-03 +1249 4.500000e-01 2.500000e+00 2.351082e-03 +1250 4.600000e-01 2.500000e+00 2.396033e-03 +1251 4.700000e-01 2.500000e+00 2.440674e-03 +1252 4.800000e-01 2.500000e+00 2.485006e-03 +1253 4.900000e-01 2.500000e+00 2.529029e-03 +1254 5.000000e-01 2.500000e+00 2.572744e-03 +1255 5.100000e-01 2.500000e+00 2.616152e-03 +1256 5.200000e-01 2.500000e+00 2.659251e-03 +1257 5.300000e-01 2.500000e+00 2.702044e-03 +1258 5.400000e-01 2.500000e+00 2.744530e-03 +1259 5.500000e-01 2.500000e+00 2.786711e-03 +1260 5.600000e-01 2.500000e+00 2.828585e-03 +1261 5.700000e-01 2.500000e+00 2.870155e-03 +1262 5.800000e-01 2.500000e+00 2.911420e-03 +1263 5.900000e-01 2.500000e+00 2.952380e-03 +1264 6.000000e-01 2.500000e+00 2.993037e-03 +1265 6.100000e-01 2.500000e+00 3.033390e-03 +1266 6.200000e-01 2.500000e+00 3.073440e-03 +1267 6.300000e-01 2.500000e+00 3.113187e-03 +1268 6.400000e-01 2.500000e+00 3.152633e-03 +1269 6.500000e-01 2.500000e+00 3.191776e-03 +1270 6.600000e-01 2.500000e+00 3.230619e-03 +1271 6.700000e-01 2.500000e+00 3.269160e-03 +1272 6.800000e-01 2.500000e+00 3.307401e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1273 6.900000e-01 2.500000e+00 3.345341e-03 +1274 7.000000e-01 2.500000e+00 3.382982e-03 +1275 7.100000e-01 2.500000e+00 3.420324e-03 +1276 7.200000e-01 2.500000e+00 3.457367e-03 +1277 7.300000e-01 2.500000e+00 3.494111e-03 +1278 7.400000e-01 2.500000e+00 3.530557e-03 +1279 7.500000e-01 2.500000e+00 3.566705e-03 +1280 7.600000e-01 2.500000e+00 3.602556e-03 +1281 7.700000e-01 2.500000e+00 3.638110e-03 +1282 7.800000e-01 2.500000e+00 3.673368e-03 +1283 7.900000e-01 2.500000e+00 3.708329e-03 +1284 8.000000e-01 2.500000e+00 3.742994e-03 +1285 8.100000e-01 2.500000e+00 3.777363e-03 +1286 8.200000e-01 2.500000e+00 3.811438e-03 +1287 8.300000e-01 2.500000e+00 3.845218e-03 +1288 8.400000e-01 2.500000e+00 3.878703e-03 +1289 8.500000e-01 2.500000e+00 3.911893e-03 +1290 8.600000e-01 2.500000e+00 3.944790e-03 +1291 8.700000e-01 2.500000e+00 3.977394e-03 +1292 8.800000e-01 2.500000e+00 4.009704e-03 +1293 8.900000e-01 2.500000e+00 4.041721e-03 +1294 9.000000e-01 2.500000e+00 4.073446e-03 +1295 9.100000e-01 2.500000e+00 4.104878e-03 +1296 9.200000e-01 2.500000e+00 4.136018e-03 +1297 9.300000e-01 2.500000e+00 4.166866e-03 +1298 9.400000e-01 2.500000e+00 4.197423e-03 +1299 9.500000e-01 2.500000e+00 4.227688e-03 +1300 9.600000e-01 2.500000e+00 4.257662e-03 +1301 9.700000e-01 2.500000e+00 4.287345e-03 +1302 9.800000e-01 2.500000e+00 4.316737e-03 +1303 9.900000e-01 2.500000e+00 4.345838e-03 +1304 1.000000e+00 2.500000e+00 4.374649e-03 +1305 1.010000e+00 2.500000e+00 4.403170e-03 +1306 1.020000e+00 2.500000e+00 4.431400e-03 +1307 1.030000e+00 2.500000e+00 4.459340e-03 +1308 1.040000e+00 2.500000e+00 4.486990e-03 +1309 1.050000e+00 2.500000e+00 4.514350e-03 +1310 1.060000e+00 2.500000e+00 4.541419e-03 +1311 1.070000e+00 2.500000e+00 4.568199e-03 +1312 1.080000e+00 2.500000e+00 4.594688e-03 +1313 1.090000e+00 2.500000e+00 4.620887e-03 +1314 1.100000e+00 2.500000e+00 4.646796e-03 +1315 1.110000e+00 2.500000e+00 4.672414e-03 +1316 1.120000e+00 2.500000e+00 4.697741e-03 +1317 1.130000e+00 2.500000e+00 4.722777e-03 +1318 1.140000e+00 2.500000e+00 4.747521e-03 +1319 1.150000e+00 2.500000e+00 4.771974e-03 +1320 1.160000e+00 2.500000e+00 4.796134e-03 +1321 1.170000e+00 2.500000e+00 4.820002e-03 +1322 1.180000e+00 2.500000e+00 4.843576e-03 +1323 1.190000e+00 2.500000e+00 4.866856e-03 +1324 1.200000e+00 2.500000e+00 4.889841e-03 +1325 1.210000e+00 2.500000e+00 4.912530e-03 +1326 1.220000e+00 2.500000e+00 4.934923e-03 +1327 1.230000e+00 2.500000e+00 4.957018e-03 +1328 1.240000e+00 2.500000e+00 4.978814e-03 +1329 1.250000e+00 2.500000e+00 5.000310e-03 +1330 1.260000e+00 2.500000e+00 5.021504e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1331 1.270000e+00 2.500000e+00 5.042396e-03 +1332 1.280000e+00 2.500000e+00 5.062982e-03 +1333 1.290000e+00 2.500000e+00 5.083262e-03 +1334 1.300000e+00 2.500000e+00 5.103232e-03 +1335 1.310000e+00 2.500000e+00 5.122892e-03 +1336 1.320000e+00 2.500000e+00 5.142238e-03 +1337 1.330000e+00 2.500000e+00 5.161268e-03 +1338 1.340000e+00 2.500000e+00 5.179980e-03 +1339 1.350000e+00 2.500000e+00 5.198369e-03 +1340 1.360000e+00 2.500000e+00 5.216433e-03 +1341 1.370000e+00 2.500000e+00 5.234168e-03 +1342 1.380000e+00 2.500000e+00 5.251570e-03 +1343 1.390000e+00 2.500000e+00 5.268636e-03 +1344 1.400000e+00 2.500000e+00 5.285362e-03 +1345 1.410000e+00 2.500000e+00 5.301743e-03 +1346 1.420000e+00 2.500000e+00 5.317774e-03 +1347 1.430000e+00 2.500000e+00 5.333451e-03 +1348 1.440000e+00 2.500000e+00 5.348770e-03 +1349 1.450000e+00 2.500000e+00 5.363726e-03 +1350 1.460000e+00 2.500000e+00 5.378313e-03 +1351 1.470000e+00 2.500000e+00 5.392527e-03 +1352 1.480000e+00 2.500000e+00 5.406365e-03 +1353 1.490000e+00 2.500000e+00 5.419822e-03 +1354 1.500000e+00 2.500000e+00 5.432893e-03 +1355 1.510000e+00 2.500000e+00 5.445577e-03 +1356 1.520000e+00 2.500000e+00 5.457871e-03 +1357 1.530000e+00 2.500000e+00 5.469772e-03 +1358 1.540000e+00 2.500000e+00 5.481280e-03 +1359 1.550000e+00 2.500000e+00 5.492395e-03 +1360 1.560000e+00 2.500000e+00 5.503118e-03 +1361 1.570000e+00 2.500000e+00 5.513452e-03 +1362 1.580000e+00 2.500000e+00 5.523400e-03 +1363 1.590000e+00 2.500000e+00 5.532967e-03 +1364 1.600000e+00 2.500000e+00 5.542159e-03 +1365 1.610000e+00 2.500000e+00 5.550982e-03 +1366 1.620000e+00 2.500000e+00 5.559446e-03 +1367 1.630000e+00 2.500000e+00 5.567559e-03 +1368 1.640000e+00 2.500000e+00 5.575331e-03 +1369 1.650000e+00 2.500000e+00 5.582774e-03 +1370 1.660000e+00 2.500000e+00 5.589899e-03 +1371 1.670000e+00 2.500000e+00 5.596718e-03 +1372 1.680000e+00 2.500000e+00 5.603244e-03 +1373 1.690000e+00 2.500000e+00 5.609489e-03 +1374 1.700000e+00 2.500000e+00 5.615465e-03 +1375 1.710000e+00 2.500000e+00 5.621186e-03 +1376 1.720000e+00 2.500000e+00 5.626664e-03 +1377 1.730000e+00 2.500000e+00 5.631911e-03 +1378 1.740000e+00 2.500000e+00 5.636939e-03 +1379 1.750000e+00 2.500000e+00 5.641760e-03 +1380 1.760000e+00 2.500000e+00 5.646386e-03 +1381 1.770000e+00 2.500000e+00 5.650826e-03 +1382 1.780000e+00 2.500000e+00 5.655092e-03 +1383 1.790000e+00 2.500000e+00 5.659193e-03 +1384 1.800000e+00 2.500000e+00 5.663139e-03 +1385 1.810000e+00 2.500000e+00 5.666938e-03 +1386 1.820000e+00 2.500000e+00 5.670598e-03 +1387 1.830000e+00 2.500000e+00 5.674129e-03 +1388 1.840000e+00 2.500000e+00 5.677537e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1389 1.850000e+00 2.500000e+00 5.680829e-03 +1390 1.860000e+00 2.500000e+00 5.684011e-03 +1391 1.870000e+00 2.500000e+00 5.687091e-03 +1392 1.880000e+00 2.500000e+00 5.690074e-03 +1393 1.890000e+00 2.500000e+00 5.692965e-03 +1394 1.900000e+00 2.500000e+00 5.695770e-03 +1395 1.910000e+00 2.500000e+00 5.698493e-03 +1396 1.920000e+00 2.500000e+00 5.701139e-03 +1397 1.930000e+00 2.500000e+00 5.703712e-03 +1398 1.940000e+00 2.500000e+00 5.706215e-03 +1399 1.950000e+00 2.500000e+00 5.708654e-03 +1400 1.960000e+00 2.500000e+00 5.711030e-03 +1401 1.970000e+00 2.500000e+00 5.713348e-03 +1402 1.980000e+00 2.500000e+00 5.715611e-03 +1403 1.990000e+00 2.500000e+00 5.717820e-03 +1404 2.000000e+00 2.500000e+00 5.719980e-03 +1405 2.010000e+00 2.500000e+00 5.722092e-03 +1406 2.020000e+00 2.500000e+00 5.724159e-03 +1407 2.030000e+00 2.500000e+00 5.726184e-03 +1408 2.040000e+00 2.500000e+00 5.728167e-03 +1409 2.050000e+00 2.500000e+00 5.730111e-03 +1410 2.060000e+00 2.500000e+00 5.732019e-03 +1411 2.070000e+00 2.500000e+00 5.733891e-03 +1412 2.080000e+00 2.500000e+00 5.735730e-03 +1413 2.090000e+00 2.500000e+00 5.737537e-03 +1414 2.100000e+00 2.500000e+00 5.739313e-03 +1415 2.110000e+00 2.500000e+00 5.741059e-03 +1416 2.120000e+00 2.500000e+00 5.742778e-03 +1417 2.130000e+00 2.500000e+00 5.744470e-03 +1418 2.140000e+00 2.500000e+00 5.746137e-03 +1419 2.150000e+00 2.500000e+00 5.747779e-03 +1420 2.160000e+00 2.500000e+00 5.749398e-03 +1421 2.170000e+00 2.500000e+00 5.750994e-03 +1422 2.180000e+00 2.500000e+00 5.752569e-03 +1423 2.190000e+00 2.500000e+00 5.754123e-03 +1424 2.200000e+00 2.500000e+00 5.755658e-03 +1425 2.210000e+00 2.500000e+00 5.757173e-03 +1426 2.220000e+00 2.500000e+00 5.758670e-03 +1427 2.230000e+00 2.500000e+00 5.760150e-03 +1428 2.240000e+00 2.500000e+00 5.761613e-03 +1429 2.250000e+00 2.500000e+00 5.763059e-03 +1430 2.260000e+00 2.500000e+00 5.764490e-03 +1431 2.270000e+00 2.500000e+00 5.765906e-03 +1432 2.280000e+00 2.500000e+00 5.767308e-03 +1433 2.290000e+00 2.500000e+00 5.768696e-03 +1434 2.300000e+00 2.500000e+00 5.770070e-03 +1435 2.310000e+00 2.500000e+00 5.771431e-03 +1436 2.320000e+00 2.500000e+00 5.772780e-03 +1437 2.330000e+00 2.500000e+00 5.774117e-03 +1438 2.340000e+00 2.500000e+00 5.775442e-03 +1439 2.350000e+00 2.500000e+00 5.776756e-03 +1440 2.360000e+00 2.500000e+00 5.778059e-03 +1441 2.370000e+00 2.500000e+00 5.779352e-03 +1442 2.380000e+00 2.500000e+00 5.780634e-03 +1443 2.390000e+00 2.500000e+00 5.781907e-03 +1444 2.400000e+00 2.500000e+00 5.783170e-03 +1445 2.410000e+00 2.500000e+00 5.784425e-03 +1446 2.420000e+00 2.500000e+00 5.785670e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1447 2.430000e+00 2.500000e+00 5.786907e-03 +1448 2.440000e+00 2.500000e+00 5.788135e-03 +1449 2.450000e+00 2.500000e+00 5.789355e-03 +1450 2.460000e+00 2.500000e+00 5.790568e-03 +1451 2.470000e+00 2.500000e+00 5.791773e-03 +1452 2.480000e+00 2.500000e+00 5.792971e-03 +1453 2.490000e+00 2.500000e+00 5.794161e-03 +1454 2.500000e+00 2.500000e+00 5.795345e-03 +1455 2.510000e+00 2.500000e+00 5.796522e-03 +1456 2.520000e+00 2.500000e+00 5.797692e-03 +1457 2.530000e+00 2.500000e+00 5.798856e-03 +1458 2.540000e+00 2.500000e+00 5.800014e-03 +1459 2.550000e+00 2.500000e+00 5.801166e-03 +1460 2.560000e+00 2.500000e+00 5.802313e-03 +1461 2.570000e+00 2.500000e+00 5.803453e-03 +1462 2.580000e+00 2.500000e+00 5.804588e-03 +1463 2.590000e+00 2.500000e+00 5.805718e-03 +1464 2.600000e+00 2.500000e+00 5.806843e-03 +1465 2.610000e+00 2.500000e+00 5.807962e-03 +1466 2.620000e+00 2.500000e+00 5.809077e-03 +1467 2.630000e+00 2.500000e+00 5.810187e-03 +1468 2.640000e+00 2.500000e+00 5.811292e-03 +1469 2.650000e+00 2.500000e+00 5.812393e-03 +1470 2.660000e+00 2.500000e+00 5.813489e-03 +1471 2.670000e+00 2.500000e+00 5.814581e-03 +1472 2.680000e+00 2.500000e+00 5.815669e-03 +1473 2.690000e+00 2.500000e+00 5.816753e-03 +1474 2.700000e+00 2.500000e+00 5.817832e-03 +1475 2.710000e+00 2.500000e+00 5.818908e-03 +1476 2.720000e+00 2.500000e+00 5.819980e-03 +1477 2.730000e+00 2.500000e+00 5.821049e-03 +1478 2.740000e+00 2.500000e+00 5.822113e-03 +1479 2.750000e+00 2.500000e+00 5.823175e-03 +1480 2.760000e+00 2.500000e+00 5.824232e-03 +1481 2.770000e+00 2.500000e+00 5.825287e-03 +1482 2.780000e+00 2.500000e+00 5.826338e-03 +1483 2.790000e+00 2.500000e+00 5.827386e-03 +1484 2.800000e+00 2.500000e+00 5.828431e-03 +1485 2.810000e+00 2.500000e+00 5.829473e-03 +1486 2.820000e+00 2.500000e+00 5.830511e-03 +1487 2.830000e+00 2.500000e+00 5.831547e-03 +1488 2.840000e+00 2.500000e+00 5.832580e-03 +1489 2.850000e+00 2.500000e+00 5.833611e-03 +1490 2.860000e+00 2.500000e+00 5.834638e-03 +1491 2.870000e+00 2.500000e+00 5.835663e-03 +1492 2.880000e+00 2.500000e+00 5.836685e-03 +1493 2.890000e+00 2.500000e+00 5.837705e-03 +1494 2.900000e+00 2.500000e+00 5.838722e-03 +1495 2.910000e+00 2.500000e+00 5.839737e-03 +1496 2.920000e+00 2.500000e+00 5.840749e-03 +1497 2.930000e+00 2.500000e+00 5.841759e-03 +1498 2.940000e+00 2.500000e+00 5.842767e-03 +1499 2.950000e+00 2.500000e+00 5.843773e-03 +1500 2.960000e+00 2.500000e+00 5.844776e-03 +1501 2.970000e+00 2.500000e+00 5.845777e-03 +1502 2.980000e+00 2.500000e+00 5.846776e-03 +1503 2.990000e+00 2.500000e+00 5.847773e-03 +1504 3.000000e+00 2.500000e+00 5.848768e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1505 0.000000e+00 3.000000e+00 -1.250000e-19 +1506 1.000000e-02 3.000000e+00 6.224150e-05 +1507 2.000000e-02 3.000000e+00 1.241998e-04 +1508 3.000000e-02 3.000000e+00 1.860167e-04 +1509 4.000000e-02 3.000000e+00 2.474097e-04 +1510 5.000000e-02 3.000000e+00 3.085206e-04 +1511 6.000000e-02 3.000000e+00 3.693498e-04 +1512 7.000000e-02 3.000000e+00 4.298976e-04 +1513 8.000000e-02 3.000000e+00 4.901645e-04 +1514 9.000000e-02 3.000000e+00 5.501508e-04 +1515 1.000000e-01 3.000000e+00 6.098569e-04 +1516 1.100000e-01 3.000000e+00 6.692831e-04 +1517 1.200000e-01 3.000000e+00 7.284297e-04 +1518 1.300000e-01 3.000000e+00 7.872972e-04 +1519 1.400000e-01 3.000000e+00 8.458860e-04 +1520 1.500000e-01 3.000000e+00 9.041962e-04 +1521 1.600000e-01 3.000000e+00 9.622284e-04 +1522 1.700000e-01 3.000000e+00 1.019983e-03 +1523 1.800000e-01 3.000000e+00 1.077460e-03 +1524 1.900000e-01 3.000000e+00 1.134660e-03 +1525 2.000000e-01 3.000000e+00 1.191584e-03 +1526 2.100000e-01 3.000000e+00 1.248231e-03 +1527 2.200000e-01 3.000000e+00 1.304602e-03 +1528 2.300000e-01 3.000000e+00 1.360698e-03 +1529 2.400000e-01 3.000000e+00 1.416518e-03 +1530 2.500000e-01 3.000000e+00 1.472063e-03 +1531 2.600000e-01 3.000000e+00 1.527334e-03 +1532 2.700000e-01 3.000000e+00 1.582331e-03 +1533 2.800000e-01 3.000000e+00 1.637054e-03 +1534 2.900000e-01 3.000000e+00 1.691503e-03 +1535 3.000000e-01 3.000000e+00 1.745680e-03 +1536 3.100000e-01 3.000000e+00 1.799583e-03 +1537 3.200000e-01 3.000000e+00 1.853214e-03 +1538 3.300000e-01 3.000000e+00 1.906573e-03 +1539 3.400000e-01 3.000000e+00 1.959661e-03 +1540 3.500000e-01 3.000000e+00 2.012476e-03 +1541 3.600000e-01 3.000000e+00 2.065021e-03 +1542 3.700000e-01 3.000000e+00 2.117295e-03 +1543 3.800000e-01 3.000000e+00 2.169299e-03 +1544 3.900000e-01 3.000000e+00 2.221033e-03 +1545 4.000000e-01 3.000000e+00 2.272496e-03 +1546 4.100000e-01 3.000000e+00 2.323691e-03 +1547 4.200000e-01 3.000000e+00 2.374617e-03 +1548 4.300000e-01 3.000000e+00 2.425273e-03 +1549 4.400000e-01 3.000000e+00 2.475662e-03 +1550 4.500000e-01 3.000000e+00 2.525783e-03 +1551 4.600000e-01 3.000000e+00 2.575635e-03 +1552 4.700000e-01 3.000000e+00 2.625221e-03 +1553 4.800000e-01 3.000000e+00 2.674540e-03 +1554 4.900000e-01 3.000000e+00 2.723592e-03 +1555 5.000000e-01 3.000000e+00 2.772377e-03 +1556 5.100000e-01 3.000000e+00 2.820897e-03 +1557 5.200000e-01 3.000000e+00 2.869151e-03 +1558 5.300000e-01 3.000000e+00 2.917139e-03 +1559 5.400000e-01 3.000000e+00 2.964863e-03 +1560 5.500000e-01 3.000000e+00 3.012322e-03 +1561 5.600000e-01 3.000000e+00 3.059516e-03 +1562 5.700000e-01 3.000000e+00 3.106447e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1563 5.800000e-01 3.000000e+00 3.153114e-03 +1564 5.900000e-01 3.000000e+00 3.199517e-03 +1565 6.000000e-01 3.000000e+00 3.245658e-03 +1566 6.100000e-01 3.000000e+00 3.291535e-03 +1567 6.200000e-01 3.000000e+00 3.337151e-03 +1568 6.300000e-01 3.000000e+00 3.382504e-03 +1569 6.400000e-01 3.000000e+00 3.427595e-03 +1570 6.500000e-01 3.000000e+00 3.472426e-03 +1571 6.600000e-01 3.000000e+00 3.516994e-03 +1572 6.700000e-01 3.000000e+00 3.561303e-03 +1573 6.800000e-01 3.000000e+00 3.605350e-03 +1574 6.900000e-01 3.000000e+00 3.649138e-03 +1575 7.000000e-01 3.000000e+00 3.692665e-03 +1576 7.100000e-01 3.000000e+00 3.735933e-03 +1577 7.200000e-01 3.000000e+00 3.778942e-03 +1578 7.300000e-01 3.000000e+00 3.821692e-03 +1579 7.400000e-01 3.000000e+00 3.864183e-03 +1580 7.500000e-01 3.000000e+00 3.906416e-03 +1581 7.600000e-01 3.000000e+00 3.948391e-03 +1582 7.700000e-01 3.000000e+00 3.990109e-03 +1583 7.800000e-01 3.000000e+00 4.031569e-03 +1584 7.900000e-01 3.000000e+00 4.072771e-03 +1585 8.000000e-01 3.000000e+00 4.113717e-03 +1586 8.100000e-01 3.000000e+00 4.154407e-03 +1587 8.200000e-01 3.000000e+00 4.194840e-03 +1588 8.300000e-01 3.000000e+00 4.235018e-03 +1589 8.400000e-01 3.000000e+00 4.274940e-03 +1590 8.500000e-01 3.000000e+00 4.314606e-03 +1591 8.600000e-01 3.000000e+00 4.354018e-03 +1592 8.700000e-01 3.000000e+00 4.393174e-03 +1593 8.800000e-01 3.000000e+00 4.432077e-03 +1594 8.900000e-01 3.000000e+00 4.470725e-03 +1595 9.000000e-01 3.000000e+00 4.509119e-03 +1596 9.100000e-01 3.000000e+00 4.547260e-03 +1597 9.200000e-01 3.000000e+00 4.585147e-03 +1598 9.300000e-01 3.000000e+00 4.622781e-03 +1599 9.400000e-01 3.000000e+00 4.660163e-03 +1600 9.500000e-01 3.000000e+00 4.697291e-03 +1601 9.600000e-01 3.000000e+00 4.734168e-03 +1602 9.700000e-01 3.000000e+00 4.770793e-03 +1603 9.800000e-01 3.000000e+00 4.807166e-03 +1604 9.900000e-01 3.000000e+00 4.843288e-03 +1605 1.000000e+00 3.000000e+00 4.879158e-03 +1606 1.010000e+00 3.000000e+00 4.914777e-03 +1607 1.020000e+00 3.000000e+00 4.950146e-03 +1608 1.030000e+00 3.000000e+00 4.985264e-03 +1609 1.040000e+00 3.000000e+00 5.020132e-03 +1610 1.050000e+00 3.000000e+00 5.054750e-03 +1611 1.060000e+00 3.000000e+00 5.089119e-03 +1612 1.070000e+00 3.000000e+00 5.123238e-03 +1613 1.080000e+00 3.000000e+00 5.157107e-03 +1614 1.090000e+00 3.000000e+00 5.190727e-03 +1615 1.100000e+00 3.000000e+00 5.224099e-03 +1616 1.110000e+00 3.000000e+00 5.257222e-03 +1617 1.120000e+00 3.000000e+00 5.290096e-03 +1618 1.130000e+00 3.000000e+00 5.322722e-03 +1619 1.140000e+00 3.000000e+00 5.355101e-03 +1620 1.150000e+00 3.000000e+00 5.387231e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1621 1.160000e+00 3.000000e+00 5.419113e-03 +1622 1.170000e+00 3.000000e+00 5.450748e-03 +1623 1.180000e+00 3.000000e+00 5.482136e-03 +1624 1.190000e+00 3.000000e+00 5.513276e-03 +1625 1.200000e+00 3.000000e+00 5.544169e-03 +1626 1.210000e+00 3.000000e+00 5.574815e-03 +1627 1.220000e+00 3.000000e+00 5.605214e-03 +1628 1.230000e+00 3.000000e+00 5.635367e-03 +1629 1.240000e+00 3.000000e+00 5.665272e-03 +1630 1.250000e+00 3.000000e+00 5.694932e-03 +1631 1.260000e+00 3.000000e+00 5.724344e-03 +1632 1.270000e+00 3.000000e+00 5.753511e-03 +1633 1.280000e+00 3.000000e+00 5.782430e-03 +1634 1.290000e+00 3.000000e+00 5.811104e-03 +1635 1.300000e+00 3.000000e+00 5.839531e-03 +1636 1.310000e+00 3.000000e+00 5.867711e-03 +1637 1.320000e+00 3.000000e+00 5.895645e-03 +1638 1.330000e+00 3.000000e+00 5.923333e-03 +1639 1.340000e+00 3.000000e+00 5.950774e-03 +1640 1.350000e+00 3.000000e+00 5.977968e-03 +1641 1.360000e+00 3.000000e+00 6.004915e-03 +1642 1.370000e+00 3.000000e+00 6.031616e-03 +1643 1.380000e+00 3.000000e+00 6.058069e-03 +1644 1.390000e+00 3.000000e+00 6.084275e-03 +1645 1.400000e+00 3.000000e+00 6.110233e-03 +1646 1.410000e+00 3.000000e+00 6.135943e-03 +1647 1.420000e+00 3.000000e+00 6.161404e-03 +1648 1.430000e+00 3.000000e+00 6.186618e-03 +1649 1.440000e+00 3.000000e+00 6.211581e-03 +1650 1.450000e+00 3.000000e+00 6.236296e-03 +1651 1.460000e+00 3.000000e+00 6.260760e-03 +1652 1.470000e+00 3.000000e+00 6.284973e-03 +1653 1.480000e+00 3.000000e+00 6.308935e-03 +1654 1.490000e+00 3.000000e+00 6.332645e-03 +1655 1.500000e+00 3.000000e+00 6.356102e-03 +1656 1.510000e+00 3.000000e+00 6.379306e-03 +1657 1.520000e+00 3.000000e+00 6.402254e-03 +1658 1.530000e+00 3.000000e+00 6.424947e-03 +1659 1.540000e+00 3.000000e+00 6.447383e-03 +1660 1.550000e+00 3.000000e+00 6.469561e-03 +1661 1.560000e+00 3.000000e+00 6.491479e-03 +1662 1.570000e+00 3.000000e+00 6.513136e-03 +1663 1.580000e+00 3.000000e+00 6.534531e-03 +1664 1.590000e+00 3.000000e+00 6.555662e-03 +1665 1.600000e+00 3.000000e+00 6.576527e-03 +1666 1.610000e+00 3.000000e+00 6.597123e-03 +1667 1.620000e+00 3.000000e+00 6.617450e-03 +1668 1.630000e+00 3.000000e+00 6.637504e-03 +1669 1.640000e+00 3.000000e+00 6.657282e-03 +1670 1.650000e+00 3.000000e+00 6.676784e-03 +1671 1.660000e+00 3.000000e+00 6.696004e-03 +1672 1.670000e+00 3.000000e+00 6.714942e-03 +1673 1.680000e+00 3.000000e+00 6.733592e-03 +1674 1.690000e+00 3.000000e+00 6.751952e-03 +1675 1.700000e+00 3.000000e+00 6.770019e-03 +1676 1.710000e+00 3.000000e+00 6.787787e-03 +1677 1.720000e+00 3.000000e+00 6.805254e-03 +1678 1.730000e+00 3.000000e+00 6.822415e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1679 1.740000e+00 3.000000e+00 6.839266e-03 +1680 1.750000e+00 3.000000e+00 6.855803e-03 +1681 1.760000e+00 3.000000e+00 6.872020e-03 +1682 1.770000e+00 3.000000e+00 6.887912e-03 +1683 1.780000e+00 3.000000e+00 6.903476e-03 +1684 1.790000e+00 3.000000e+00 6.918706e-03 +1685 1.800000e+00 3.000000e+00 6.933598e-03 +1686 1.810000e+00 3.000000e+00 6.948147e-03 +1687 1.820000e+00 3.000000e+00 6.962349e-03 +1688 1.830000e+00 3.000000e+00 6.976199e-03 +1689 1.840000e+00 3.000000e+00 6.989694e-03 +1690 1.850000e+00 3.000000e+00 7.002830e-03 +1691 1.860000e+00 3.000000e+00 7.015604e-03 +1692 1.870000e+00 3.000000e+00 7.028014e-03 +1693 1.880000e+00 3.000000e+00 7.040060e-03 +1694 1.890000e+00 3.000000e+00 7.051739e-03 +1695 1.900000e+00 3.000000e+00 7.063052e-03 +1696 1.910000e+00 3.000000e+00 7.074000e-03 +1697 1.920000e+00 3.000000e+00 7.084585e-03 +1698 1.930000e+00 3.000000e+00 7.094810e-03 +1699 1.940000e+00 3.000000e+00 7.104679e-03 +1700 1.950000e+00 3.000000e+00 7.114197e-03 +1701 1.960000e+00 3.000000e+00 7.123370e-03 +1702 1.970000e+00 3.000000e+00 7.132204e-03 +1703 1.980000e+00 3.000000e+00 7.140707e-03 +1704 1.990000e+00 3.000000e+00 7.148887e-03 +1705 2.000000e+00 3.000000e+00 7.156754e-03 +1706 2.010000e+00 3.000000e+00 7.164316e-03 +1707 2.020000e+00 3.000000e+00 7.171584e-03 +1708 2.030000e+00 3.000000e+00 7.178568e-03 +1709 2.040000e+00 3.000000e+00 7.185279e-03 +1710 2.050000e+00 3.000000e+00 7.191727e-03 +1711 2.060000e+00 3.000000e+00 7.197924e-03 +1712 2.070000e+00 3.000000e+00 7.203879e-03 +1713 2.080000e+00 3.000000e+00 7.209603e-03 +1714 2.090000e+00 3.000000e+00 7.215108e-03 +1715 2.100000e+00 3.000000e+00 7.220403e-03 +1716 2.110000e+00 3.000000e+00 7.225499e-03 +1717 2.120000e+00 3.000000e+00 7.230404e-03 +1718 2.130000e+00 3.000000e+00 7.235129e-03 +1719 2.140000e+00 3.000000e+00 7.239682e-03 +1720 2.150000e+00 3.000000e+00 7.244073e-03 +1721 2.160000e+00 3.000000e+00 7.248308e-03 +1722 2.170000e+00 3.000000e+00 7.252398e-03 +1723 2.180000e+00 3.000000e+00 7.256348e-03 +1724 2.190000e+00 3.000000e+00 7.260166e-03 +1725 2.200000e+00 3.000000e+00 7.263860e-03 +1726 2.210000e+00 3.000000e+00 7.267435e-03 +1727 2.220000e+00 3.000000e+00 7.270897e-03 +1728 2.230000e+00 3.000000e+00 7.274253e-03 +1729 2.240000e+00 3.000000e+00 7.277508e-03 +1730 2.250000e+00 3.000000e+00 7.280666e-03 +1731 2.260000e+00 3.000000e+00 7.283734e-03 +1732 2.270000e+00 3.000000e+00 7.286716e-03 +1733 2.280000e+00 3.000000e+00 7.289615e-03 +1734 2.290000e+00 3.000000e+00 7.292437e-03 +1735 2.300000e+00 3.000000e+00 7.295184e-03 +1736 2.310000e+00 3.000000e+00 7.297861e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1737 2.320000e+00 3.000000e+00 7.300472e-03 +1738 2.330000e+00 3.000000e+00 7.303018e-03 +1739 2.340000e+00 3.000000e+00 7.305504e-03 +1740 2.350000e+00 3.000000e+00 7.307932e-03 +1741 2.360000e+00 3.000000e+00 7.310306e-03 +1742 2.370000e+00 3.000000e+00 7.312627e-03 +1743 2.380000e+00 3.000000e+00 7.314898e-03 +1744 2.390000e+00 3.000000e+00 7.317121e-03 +1745 2.400000e+00 3.000000e+00 7.319299e-03 +1746 2.410000e+00 3.000000e+00 7.321433e-03 +1747 2.420000e+00 3.000000e+00 7.323526e-03 +1748 2.430000e+00 3.000000e+00 7.325580e-03 +1749 2.440000e+00 3.000000e+00 7.327595e-03 +1750 2.450000e+00 3.000000e+00 7.329574e-03 +1751 2.460000e+00 3.000000e+00 7.331518e-03 +1752 2.470000e+00 3.000000e+00 7.333430e-03 +1753 2.480000e+00 3.000000e+00 7.335309e-03 +1754 2.490000e+00 3.000000e+00 7.337158e-03 +1755 2.500000e+00 3.000000e+00 7.338977e-03 +1756 2.510000e+00 3.000000e+00 7.340769e-03 +1757 2.520000e+00 3.000000e+00 7.342533e-03 +1758 2.530000e+00 3.000000e+00 7.344272e-03 +1759 2.540000e+00 3.000000e+00 7.345985e-03 +1760 2.550000e+00 3.000000e+00 7.347675e-03 +1761 2.560000e+00 3.000000e+00 7.349342e-03 +1762 2.570000e+00 3.000000e+00 7.350987e-03 +1763 2.580000e+00 3.000000e+00 7.352610e-03 +1764 2.590000e+00 3.000000e+00 7.354213e-03 +1765 2.600000e+00 3.000000e+00 7.355797e-03 +1766 2.610000e+00 3.000000e+00 7.357361e-03 +1767 2.620000e+00 3.000000e+00 7.358907e-03 +1768 2.630000e+00 3.000000e+00 7.360436e-03 +1769 2.640000e+00 3.000000e+00 7.361947e-03 +1770 2.650000e+00 3.000000e+00 7.363442e-03 +1771 2.660000e+00 3.000000e+00 7.364921e-03 +1772 2.670000e+00 3.000000e+00 7.366385e-03 +1773 2.680000e+00 3.000000e+00 7.367834e-03 +1774 2.690000e+00 3.000000e+00 7.369269e-03 +1775 2.700000e+00 3.000000e+00 7.370690e-03 +1776 2.710000e+00 3.000000e+00 7.372098e-03 +1777 2.720000e+00 3.000000e+00 7.373493e-03 +1778 2.730000e+00 3.000000e+00 7.374875e-03 +1779 2.740000e+00 3.000000e+00 7.376245e-03 +1780 2.750000e+00 3.000000e+00 7.377604e-03 +1781 2.760000e+00 3.000000e+00 7.378951e-03 +1782 2.770000e+00 3.000000e+00 7.380287e-03 +1783 2.780000e+00 3.000000e+00 7.381613e-03 +1784 2.790000e+00 3.000000e+00 7.382928e-03 +1785 2.800000e+00 3.000000e+00 7.384234e-03 +1786 2.810000e+00 3.000000e+00 7.385529e-03 +1787 2.820000e+00 3.000000e+00 7.386815e-03 +1788 2.830000e+00 3.000000e+00 7.388093e-03 +1789 2.840000e+00 3.000000e+00 7.389361e-03 +1790 2.850000e+00 3.000000e+00 7.390621e-03 +1791 2.860000e+00 3.000000e+00 7.391872e-03 +1792 2.870000e+00 3.000000e+00 7.393115e-03 +1793 2.880000e+00 3.000000e+00 7.394351e-03 +1794 2.890000e+00 3.000000e+00 7.395578e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1795 2.900000e+00 3.000000e+00 7.396799e-03 +1796 2.910000e+00 3.000000e+00 7.398012e-03 +1797 2.920000e+00 3.000000e+00 7.399218e-03 +1798 2.930000e+00 3.000000e+00 7.400417e-03 +1799 2.940000e+00 3.000000e+00 7.401609e-03 +1800 2.950000e+00 3.000000e+00 7.402795e-03 +1801 2.960000e+00 3.000000e+00 7.403975e-03 +1802 2.970000e+00 3.000000e+00 7.405149e-03 +1803 2.980000e+00 3.000000e+00 7.406316e-03 +1804 2.990000e+00 3.000000e+00 7.407478e-03 +1805 3.000000e+00 3.000000e+00 7.408634e-03 + + + + diff --git a/tests/bsim3soifd/t4.cir b/tests/bsim3soifd/t4.cir new file mode 100644 index 000000000..616c1ec4f --- /dev/null +++ b/tests/bsim3soifd/t4.cir @@ -0,0 +1,17 @@ +*model = BSIMSOI (FD) +*Berkeley Spice Compatibility +* +* SOI NMOSFET, tied body simulation + +vd d 0 dc 0.05 +vs s 0 dc 0 +ve e 0 dc 0 +vg g 0 dc 3 +vb b 0 dc 0 + +m1 d g s e b n1 w=10u l=0.25u + +.option gmin=1e-25 itl1=500 +.dc vg 0 1.5 0.01 vb -0.3 0.5 0.1 +.print dc i(vs) +.include nmosfd.mod diff --git a/tests/bsim3soifd/t4.out b/tests/bsim3soifd/t4.out new file mode 100644 index 000000000..c0071a1b9 --- /dev/null +++ b/tests/bsim3soifd/t4.out @@ -0,0 +1,1444 @@ + Reference value : 1.10000e+00 +No. of Data Rows : 1359 + +Circuit: *model = BSIMSOI (FD) + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. + *model = BSIMSOI (FD) +-------------------------------------------------------------------------------- +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 3.802857e-12 +1 1.000000e-02 5.179405e-12 +2 2.000000e-02 7.436916e-12 +3 3.000000e-02 1.067638e-11 +4 4.000000e-02 1.532378e-11 +5 5.000000e-02 2.317943e-11 +6 6.000000e-02 3.325101e-11 +7 7.000000e-02 4.768511e-11 +8 8.000000e-02 6.836303e-11 +9 9.000000e-02 9.797210e-11 +10 1.000000e-01 1.403476e-10 +11 1.100000e-01 2.009572e-10 +12 1.200000e-01 2.875868e-10 +13 1.300000e-01 4.113064e-10 +14 1.400000e-01 5.878303e-10 +15 1.500000e-01 8.394210e-10 +16 1.600000e-01 1.197526e-09 +17 1.700000e-01 1.706327e-09 +18 1.800000e-01 2.427883e-09 +19 1.900000e-01 3.448995e-09 +20 2.000000e-01 4.890513e-09 +21 2.100000e-01 6.919840e-09 +22 2.200000e-01 9.767530e-09 +23 2.300000e-01 1.374902e-08 +24 2.400000e-01 1.929264e-08 +25 2.500000e-01 2.697515e-08 +26 2.600000e-01 3.756591e-08 +27 2.700000e-01 5.208067e-08 +28 2.800000e-01 7.184554e-08 +29 2.900000e-01 9.857148e-08 +30 3.000000e-01 1.344389e-07 +31 3.100000e-01 1.821917e-07 +32 3.200000e-01 2.452412e-07 +33 3.300000e-01 3.277779e-07 +34 3.400000e-01 4.348938e-07 +35 3.500000e-01 5.727141e-07 +36 3.600000e-01 7.485378e-07 +37 3.700000e-01 9.709820e-07 +38 3.800000e-01 1.250117e-06 +39 3.900000e-01 1.597567e-06 +40 4.000000e-01 2.026526e-06 +41 4.100000e-01 2.551636e-06 +42 4.200000e-01 3.188614e-06 +43 4.300000e-01 3.953476e-06 +44 4.400000e-01 4.861015e-06 +45 4.500000e-01 5.921696e-06 +46 4.600000e-01 7.136545e-06 +47 4.700000e-01 8.498437e-06 +48 4.800000e-01 1.000774e-05 +49 4.900000e-01 1.167295e-05 +50 5.000000e-01 1.349892e-05 +51 5.100000e-01 1.548464e-05 +52 5.200000e-01 1.762458e-05 +53 5.300000e-01 1.990991e-05 +54 5.400000e-01 2.232939e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +55 5.500000e-01 2.487011e-05 +56 5.600000e-01 2.751817e-05 +57 5.700000e-01 3.025929e-05 +58 5.800000e-01 3.307926e-05 +59 5.900000e-01 3.593405e-05 +60 6.000000e-01 3.887775e-05 +61 6.100000e-01 4.186125e-05 +62 6.200000e-01 4.487369e-05 +63 6.300000e-01 4.790535e-05 +64 6.400000e-01 5.094767e-05 +65 6.500000e-01 5.399320e-05 +66 6.600000e-01 5.703551e-05 +67 6.700000e-01 6.006913e-05 +68 6.800000e-01 6.308940e-05 +69 6.900000e-01 6.609245e-05 +70 7.000000e-01 6.907502e-05 +71 7.100000e-01 7.203445e-05 +72 7.200000e-01 7.496857e-05 +73 7.300000e-01 7.787563e-05 +74 7.400000e-01 8.075423e-05 +75 7.500000e-01 8.360329e-05 +76 7.600000e-01 8.642197e-05 +77 7.700000e-01 8.920966e-05 +78 7.800000e-01 9.196592e-05 +79 7.900000e-01 9.469048e-05 +80 8.000000e-01 9.738318e-05 +81 8.100000e-01 1.000440e-04 +82 8.200000e-01 1.026729e-04 +83 8.300000e-01 1.052700e-04 +84 8.400000e-01 1.078355e-04 +85 8.500000e-01 1.103696e-04 +86 8.600000e-01 1.128726e-04 +87 8.700000e-01 1.153446e-04 +88 8.800000e-01 1.177862e-04 +89 8.900000e-01 1.201975e-04 +90 9.000000e-01 1.225789e-04 +91 9.100000e-01 1.249307e-04 +92 9.200000e-01 1.272534e-04 +93 9.300000e-01 1.295472e-04 +94 9.400000e-01 1.318126e-04 +95 9.500000e-01 1.340500e-04 +96 9.600000e-01 1.362596e-04 +97 9.700000e-01 1.384419e-04 +98 9.800000e-01 1.405972e-04 +99 9.900000e-01 1.427260e-04 +100 1.000000e+00 1.448286e-04 +101 1.010000e+00 1.469053e-04 +102 1.020000e+00 1.489565e-04 +103 1.030000e+00 1.509825e-04 +104 1.040000e+00 1.529838e-04 +105 1.050000e+00 1.549607e-04 +106 1.060000e+00 1.569135e-04 +107 1.070000e+00 1.588425e-04 +108 1.080000e+00 1.607482e-04 +109 1.090000e+00 1.626307e-04 +110 1.100000e+00 1.644905e-04 +111 1.110000e+00 1.663278e-04 +112 1.120000e+00 1.681431e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +113 1.130000e+00 1.699365e-04 +114 1.140000e+00 1.717084e-04 +115 1.150000e+00 1.734591e-04 +116 1.160000e+00 1.751888e-04 +117 1.170000e+00 1.768980e-04 +118 1.180000e+00 1.785868e-04 +119 1.190000e+00 1.802556e-04 +120 1.200000e+00 1.819046e-04 +121 1.210000e+00 1.835341e-04 +122 1.220000e+00 1.851443e-04 +123 1.230000e+00 1.867356e-04 +124 1.240000e+00 1.883082e-04 +125 1.250000e+00 1.898623e-04 +126 1.260000e+00 1.913982e-04 +127 1.270000e+00 1.929161e-04 +128 1.280000e+00 1.944163e-04 +129 1.290000e+00 1.958991e-04 +130 1.300000e+00 1.973646e-04 +131 1.310000e+00 1.988131e-04 +132 1.320000e+00 2.002448e-04 +133 1.330000e+00 2.016600e-04 +134 1.340000e+00 2.030588e-04 +135 1.350000e+00 2.044415e-04 +136 1.360000e+00 2.058082e-04 +137 1.370000e+00 2.071593e-04 +138 1.380000e+00 2.084949e-04 +139 1.390000e+00 2.098152e-04 +140 1.400000e+00 2.111204e-04 +141 1.410000e+00 2.124107e-04 +142 1.420000e+00 2.136863e-04 +143 1.430000e+00 2.149474e-04 +144 1.440000e+00 2.161942e-04 +145 1.450000e+00 2.174268e-04 +146 1.460000e+00 2.186455e-04 +147 1.470000e+00 2.198504e-04 +148 1.480000e+00 2.210417e-04 +149 1.490000e+00 2.222196e-04 +150 1.500000e+00 2.233842e-04 +151 0.000000e+00 3.802857e-12 +152 1.000000e-02 5.179405e-12 +153 2.000000e-02 7.436916e-12 +154 3.000000e-02 1.067638e-11 +155 4.000000e-02 1.532378e-11 +156 5.000000e-02 2.317943e-11 +157 6.000000e-02 3.325101e-11 +158 7.000000e-02 4.768511e-11 +159 8.000000e-02 6.836303e-11 +160 9.000000e-02 9.797210e-11 +161 1.000000e-01 1.403476e-10 +162 1.100000e-01 2.009572e-10 +163 1.200000e-01 2.875868e-10 +164 1.300000e-01 4.113064e-10 +165 1.400000e-01 5.878303e-10 +166 1.500000e-01 8.394210e-10 +167 1.600000e-01 1.197526e-09 +168 1.700000e-01 1.706327e-09 +169 1.800000e-01 2.427883e-09 +170 1.900000e-01 3.448995e-09 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +171 2.000000e-01 4.890513e-09 +172 2.100000e-01 6.919840e-09 +173 2.200000e-01 9.767530e-09 +174 2.300000e-01 1.374902e-08 +175 2.400000e-01 1.929264e-08 +176 2.500000e-01 2.697515e-08 +177 2.600000e-01 3.756591e-08 +178 2.700000e-01 5.208067e-08 +179 2.800000e-01 7.184554e-08 +180 2.900000e-01 9.857148e-08 +181 3.000000e-01 1.344389e-07 +182 3.100000e-01 1.821917e-07 +183 3.200000e-01 2.452412e-07 +184 3.300000e-01 3.277779e-07 +185 3.400000e-01 4.348938e-07 +186 3.500000e-01 5.727141e-07 +187 3.600000e-01 7.485378e-07 +188 3.700000e-01 9.709820e-07 +189 3.800000e-01 1.250117e-06 +190 3.900000e-01 1.597567e-06 +191 4.000000e-01 2.026526e-06 +192 4.100000e-01 2.551636e-06 +193 4.200000e-01 3.188614e-06 +194 4.300000e-01 3.953476e-06 +195 4.400000e-01 4.861015e-06 +196 4.500000e-01 5.921696e-06 +197 4.600000e-01 7.136545e-06 +198 4.700000e-01 8.498437e-06 +199 4.800000e-01 1.000774e-05 +200 4.900000e-01 1.167295e-05 +201 5.000000e-01 1.349892e-05 +202 5.100000e-01 1.548464e-05 +203 5.200000e-01 1.762458e-05 +204 5.300000e-01 1.990991e-05 +205 5.400000e-01 2.232939e-05 +206 5.500000e-01 2.487011e-05 +207 5.600000e-01 2.751817e-05 +208 5.700000e-01 3.025929e-05 +209 5.800000e-01 3.307926e-05 +210 5.900000e-01 3.593405e-05 +211 6.000000e-01 3.887775e-05 +212 6.100000e-01 4.186125e-05 +213 6.200000e-01 4.487369e-05 +214 6.300000e-01 4.790535e-05 +215 6.400000e-01 5.094767e-05 +216 6.500000e-01 5.399320e-05 +217 6.600000e-01 5.703551e-05 +218 6.700000e-01 6.006913e-05 +219 6.800000e-01 6.308940e-05 +220 6.900000e-01 6.609245e-05 +221 7.000000e-01 6.907502e-05 +222 7.100000e-01 7.203445e-05 +223 7.200000e-01 7.496857e-05 +224 7.300000e-01 7.787563e-05 +225 7.400000e-01 8.075423e-05 +226 7.500000e-01 8.360329e-05 +227 7.600000e-01 8.642197e-05 +228 7.700000e-01 8.920966e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +229 7.800000e-01 9.196592e-05 +230 7.900000e-01 9.469048e-05 +231 8.000000e-01 9.738318e-05 +232 8.100000e-01 1.000440e-04 +233 8.200000e-01 1.026729e-04 +234 8.300000e-01 1.052700e-04 +235 8.400000e-01 1.078355e-04 +236 8.500000e-01 1.103696e-04 +237 8.600000e-01 1.128726e-04 +238 8.700000e-01 1.153446e-04 +239 8.800000e-01 1.177862e-04 +240 8.900000e-01 1.201975e-04 +241 9.000000e-01 1.225789e-04 +242 9.100000e-01 1.249307e-04 +243 9.200000e-01 1.272534e-04 +244 9.300000e-01 1.295472e-04 +245 9.400000e-01 1.318126e-04 +246 9.500000e-01 1.340500e-04 +247 9.600000e-01 1.362596e-04 +248 9.700000e-01 1.384419e-04 +249 9.800000e-01 1.405972e-04 +250 9.900000e-01 1.427260e-04 +251 1.000000e+00 1.448286e-04 +252 1.010000e+00 1.469053e-04 +253 1.020000e+00 1.489565e-04 +254 1.030000e+00 1.509825e-04 +255 1.040000e+00 1.529838e-04 +256 1.050000e+00 1.549607e-04 +257 1.060000e+00 1.569135e-04 +258 1.070000e+00 1.588425e-04 +259 1.080000e+00 1.607482e-04 +260 1.090000e+00 1.626307e-04 +261 1.100000e+00 1.644905e-04 +262 1.110000e+00 1.663278e-04 +263 1.120000e+00 1.681431e-04 +264 1.130000e+00 1.699365e-04 +265 1.140000e+00 1.717084e-04 +266 1.150000e+00 1.734591e-04 +267 1.160000e+00 1.751888e-04 +268 1.170000e+00 1.768980e-04 +269 1.180000e+00 1.785868e-04 +270 1.190000e+00 1.802556e-04 +271 1.200000e+00 1.819046e-04 +272 1.210000e+00 1.835341e-04 +273 1.220000e+00 1.851443e-04 +274 1.230000e+00 1.867356e-04 +275 1.240000e+00 1.883082e-04 +276 1.250000e+00 1.898623e-04 +277 1.260000e+00 1.913982e-04 +278 1.270000e+00 1.929161e-04 +279 1.280000e+00 1.944163e-04 +280 1.290000e+00 1.958991e-04 +281 1.300000e+00 1.973646e-04 +282 1.310000e+00 1.988131e-04 +283 1.320000e+00 2.002448e-04 +284 1.330000e+00 2.016600e-04 +285 1.340000e+00 2.030588e-04 +286 1.350000e+00 2.044415e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +287 1.360000e+00 2.058082e-04 +288 1.370000e+00 2.071593e-04 +289 1.380000e+00 2.084949e-04 +290 1.390000e+00 2.098152e-04 +291 1.400000e+00 2.111204e-04 +292 1.410000e+00 2.124107e-04 +293 1.420000e+00 2.136863e-04 +294 1.430000e+00 2.149474e-04 +295 1.440000e+00 2.161942e-04 +296 1.450000e+00 2.174268e-04 +297 1.460000e+00 2.186455e-04 +298 1.470000e+00 2.198504e-04 +299 1.480000e+00 2.210417e-04 +300 1.490000e+00 2.222196e-04 +301 1.500000e+00 2.233842e-04 +302 0.000000e+00 3.802857e-12 +303 1.000000e-02 5.179405e-12 +304 2.000000e-02 7.436916e-12 +305 3.000000e-02 1.067638e-11 +306 4.000000e-02 1.532378e-11 +307 5.000000e-02 2.317943e-11 +308 6.000000e-02 3.325101e-11 +309 7.000000e-02 4.768511e-11 +310 8.000000e-02 6.836303e-11 +311 9.000000e-02 9.797210e-11 +312 1.000000e-01 1.403476e-10 +313 1.100000e-01 2.009572e-10 +314 1.200000e-01 2.875868e-10 +315 1.300000e-01 4.113064e-10 +316 1.400000e-01 5.878303e-10 +317 1.500000e-01 8.394210e-10 +318 1.600000e-01 1.197526e-09 +319 1.700000e-01 1.706327e-09 +320 1.800000e-01 2.427883e-09 +321 1.900000e-01 3.448995e-09 +322 2.000000e-01 4.890513e-09 +323 2.100000e-01 6.919840e-09 +324 2.200000e-01 9.767530e-09 +325 2.300000e-01 1.374902e-08 +326 2.400000e-01 1.929264e-08 +327 2.500000e-01 2.697515e-08 +328 2.600000e-01 3.756591e-08 +329 2.700000e-01 5.208067e-08 +330 2.800000e-01 7.184554e-08 +331 2.900000e-01 9.857148e-08 +332 3.000000e-01 1.344389e-07 +333 3.100000e-01 1.821917e-07 +334 3.200000e-01 2.452412e-07 +335 3.300000e-01 3.277779e-07 +336 3.400000e-01 4.348938e-07 +337 3.500000e-01 5.727141e-07 +338 3.600000e-01 7.485378e-07 +339 3.700000e-01 9.709820e-07 +340 3.800000e-01 1.250117e-06 +341 3.900000e-01 1.597567e-06 +342 4.000000e-01 2.026526e-06 +343 4.100000e-01 2.551636e-06 +344 4.200000e-01 3.188614e-06 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +345 4.300000e-01 3.953476e-06 +346 4.400000e-01 4.861015e-06 +347 4.500000e-01 5.921696e-06 +348 4.600000e-01 7.136545e-06 +349 4.700000e-01 8.498437e-06 +350 4.800000e-01 1.000774e-05 +351 4.900000e-01 1.167295e-05 +352 5.000000e-01 1.349892e-05 +353 5.100000e-01 1.548464e-05 +354 5.200000e-01 1.762458e-05 +355 5.300000e-01 1.990991e-05 +356 5.400000e-01 2.232939e-05 +357 5.500000e-01 2.487011e-05 +358 5.600000e-01 2.751817e-05 +359 5.700000e-01 3.025929e-05 +360 5.800000e-01 3.307926e-05 +361 5.900000e-01 3.593405e-05 +362 6.000000e-01 3.887775e-05 +363 6.100000e-01 4.186125e-05 +364 6.200000e-01 4.487369e-05 +365 6.300000e-01 4.790535e-05 +366 6.400000e-01 5.094767e-05 +367 6.500000e-01 5.399320e-05 +368 6.600000e-01 5.703551e-05 +369 6.700000e-01 6.006913e-05 +370 6.800000e-01 6.308940e-05 +371 6.900000e-01 6.609245e-05 +372 7.000000e-01 6.907502e-05 +373 7.100000e-01 7.203445e-05 +374 7.200000e-01 7.496857e-05 +375 7.300000e-01 7.787563e-05 +376 7.400000e-01 8.075423e-05 +377 7.500000e-01 8.360329e-05 +378 7.600000e-01 8.642197e-05 +379 7.700000e-01 8.920966e-05 +380 7.800000e-01 9.196592e-05 +381 7.900000e-01 9.469048e-05 +382 8.000000e-01 9.738318e-05 +383 8.100000e-01 1.000440e-04 +384 8.200000e-01 1.026729e-04 +385 8.300000e-01 1.052700e-04 +386 8.400000e-01 1.078355e-04 +387 8.500000e-01 1.103696e-04 +388 8.600000e-01 1.128726e-04 +389 8.700000e-01 1.153446e-04 +390 8.800000e-01 1.177862e-04 +391 8.900000e-01 1.201975e-04 +392 9.000000e-01 1.225789e-04 +393 9.100000e-01 1.249307e-04 +394 9.200000e-01 1.272534e-04 +395 9.300000e-01 1.295472e-04 +396 9.400000e-01 1.318126e-04 +397 9.500000e-01 1.340500e-04 +398 9.600000e-01 1.362596e-04 +399 9.700000e-01 1.384419e-04 +400 9.800000e-01 1.405972e-04 +401 9.900000e-01 1.427260e-04 +402 1.000000e+00 1.448286e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +403 1.010000e+00 1.469053e-04 +404 1.020000e+00 1.489565e-04 +405 1.030000e+00 1.509825e-04 +406 1.040000e+00 1.529838e-04 +407 1.050000e+00 1.549607e-04 +408 1.060000e+00 1.569135e-04 +409 1.070000e+00 1.588425e-04 +410 1.080000e+00 1.607482e-04 +411 1.090000e+00 1.626307e-04 +412 1.100000e+00 1.644905e-04 +413 1.110000e+00 1.663278e-04 +414 1.120000e+00 1.681431e-04 +415 1.130000e+00 1.699365e-04 +416 1.140000e+00 1.717084e-04 +417 1.150000e+00 1.734591e-04 +418 1.160000e+00 1.751888e-04 +419 1.170000e+00 1.768980e-04 +420 1.180000e+00 1.785868e-04 +421 1.190000e+00 1.802556e-04 +422 1.200000e+00 1.819046e-04 +423 1.210000e+00 1.835341e-04 +424 1.220000e+00 1.851443e-04 +425 1.230000e+00 1.867356e-04 +426 1.240000e+00 1.883082e-04 +427 1.250000e+00 1.898623e-04 +428 1.260000e+00 1.913982e-04 +429 1.270000e+00 1.929161e-04 +430 1.280000e+00 1.944163e-04 +431 1.290000e+00 1.958991e-04 +432 1.300000e+00 1.973646e-04 +433 1.310000e+00 1.988131e-04 +434 1.320000e+00 2.002448e-04 +435 1.330000e+00 2.016600e-04 +436 1.340000e+00 2.030588e-04 +437 1.350000e+00 2.044415e-04 +438 1.360000e+00 2.058082e-04 +439 1.370000e+00 2.071593e-04 +440 1.380000e+00 2.084949e-04 +441 1.390000e+00 2.098152e-04 +442 1.400000e+00 2.111204e-04 +443 1.410000e+00 2.124107e-04 +444 1.420000e+00 2.136863e-04 +445 1.430000e+00 2.149474e-04 +446 1.440000e+00 2.161942e-04 +447 1.450000e+00 2.174268e-04 +448 1.460000e+00 2.186455e-04 +449 1.470000e+00 2.198504e-04 +450 1.480000e+00 2.210417e-04 +451 1.490000e+00 2.222196e-04 +452 1.500000e+00 2.233842e-04 +453 0.000000e+00 3.802857e-12 +454 1.000000e-02 5.179405e-12 +455 2.000000e-02 7.436916e-12 +456 3.000000e-02 1.067638e-11 +457 4.000000e-02 1.532378e-11 +458 5.000000e-02 2.317943e-11 +459 6.000000e-02 3.325101e-11 +460 7.000000e-02 4.768511e-11 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +461 8.000000e-02 6.836303e-11 +462 9.000000e-02 9.797210e-11 +463 1.000000e-01 1.403476e-10 +464 1.100000e-01 2.009572e-10 +465 1.200000e-01 2.875868e-10 +466 1.300000e-01 4.113064e-10 +467 1.400000e-01 5.878303e-10 +468 1.500000e-01 8.394210e-10 +469 1.600000e-01 1.197526e-09 +470 1.700000e-01 1.706327e-09 +471 1.800000e-01 2.427883e-09 +472 1.900000e-01 3.448995e-09 +473 2.000000e-01 4.890513e-09 +474 2.100000e-01 6.919840e-09 +475 2.200000e-01 9.767530e-09 +476 2.300000e-01 1.374902e-08 +477 2.400000e-01 1.929264e-08 +478 2.500000e-01 2.697515e-08 +479 2.600000e-01 3.756591e-08 +480 2.700000e-01 5.208067e-08 +481 2.800000e-01 7.184554e-08 +482 2.900000e-01 9.857148e-08 +483 3.000000e-01 1.344389e-07 +484 3.100000e-01 1.821917e-07 +485 3.200000e-01 2.452412e-07 +486 3.300000e-01 3.277779e-07 +487 3.400000e-01 4.348938e-07 +488 3.500000e-01 5.727141e-07 +489 3.600000e-01 7.485378e-07 +490 3.700000e-01 9.709820e-07 +491 3.800000e-01 1.250117e-06 +492 3.900000e-01 1.597567e-06 +493 4.000000e-01 2.026526e-06 +494 4.100000e-01 2.551636e-06 +495 4.200000e-01 3.188614e-06 +496 4.300000e-01 3.953476e-06 +497 4.400000e-01 4.861015e-06 +498 4.500000e-01 5.921696e-06 +499 4.600000e-01 7.136545e-06 +500 4.700000e-01 8.498437e-06 +501 4.800000e-01 1.000774e-05 +502 4.900000e-01 1.167295e-05 +503 5.000000e-01 1.349892e-05 +504 5.100000e-01 1.548464e-05 +505 5.200000e-01 1.762458e-05 +506 5.300000e-01 1.990991e-05 +507 5.400000e-01 2.232939e-05 +508 5.500000e-01 2.487011e-05 +509 5.600000e-01 2.751817e-05 +510 5.700000e-01 3.025929e-05 +511 5.800000e-01 3.307926e-05 +512 5.900000e-01 3.593405e-05 +513 6.000000e-01 3.887775e-05 +514 6.100000e-01 4.186125e-05 +515 6.200000e-01 4.487369e-05 +516 6.300000e-01 4.790535e-05 +517 6.400000e-01 5.094767e-05 +518 6.500000e-01 5.399320e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +519 6.600000e-01 5.703551e-05 +520 6.700000e-01 6.006913e-05 +521 6.800000e-01 6.308940e-05 +522 6.900000e-01 6.609245e-05 +523 7.000000e-01 6.907502e-05 +524 7.100000e-01 7.203445e-05 +525 7.200000e-01 7.496857e-05 +526 7.300000e-01 7.787563e-05 +527 7.400000e-01 8.075423e-05 +528 7.500000e-01 8.360329e-05 +529 7.600000e-01 8.642197e-05 +530 7.700000e-01 8.920966e-05 +531 7.800000e-01 9.196592e-05 +532 7.900000e-01 9.469048e-05 +533 8.000000e-01 9.738318e-05 +534 8.100000e-01 1.000440e-04 +535 8.200000e-01 1.026729e-04 +536 8.300000e-01 1.052700e-04 +537 8.400000e-01 1.078355e-04 +538 8.500000e-01 1.103696e-04 +539 8.600000e-01 1.128726e-04 +540 8.700000e-01 1.153446e-04 +541 8.800000e-01 1.177862e-04 +542 8.900000e-01 1.201975e-04 +543 9.000000e-01 1.225789e-04 +544 9.100000e-01 1.249307e-04 +545 9.200000e-01 1.272534e-04 +546 9.300000e-01 1.295472e-04 +547 9.400000e-01 1.318126e-04 +548 9.500000e-01 1.340500e-04 +549 9.600000e-01 1.362596e-04 +550 9.700000e-01 1.384419e-04 +551 9.800000e-01 1.405972e-04 +552 9.900000e-01 1.427260e-04 +553 1.000000e+00 1.448286e-04 +554 1.010000e+00 1.469053e-04 +555 1.020000e+00 1.489565e-04 +556 1.030000e+00 1.509825e-04 +557 1.040000e+00 1.529838e-04 +558 1.050000e+00 1.549607e-04 +559 1.060000e+00 1.569135e-04 +560 1.070000e+00 1.588425e-04 +561 1.080000e+00 1.607482e-04 +562 1.090000e+00 1.626307e-04 +563 1.100000e+00 1.644905e-04 +564 1.110000e+00 1.663278e-04 +565 1.120000e+00 1.681431e-04 +566 1.130000e+00 1.699365e-04 +567 1.140000e+00 1.717084e-04 +568 1.150000e+00 1.734591e-04 +569 1.160000e+00 1.751888e-04 +570 1.170000e+00 1.768980e-04 +571 1.180000e+00 1.785868e-04 +572 1.190000e+00 1.802556e-04 +573 1.200000e+00 1.819046e-04 +574 1.210000e+00 1.835341e-04 +575 1.220000e+00 1.851443e-04 +576 1.230000e+00 1.867356e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +577 1.240000e+00 1.883082e-04 +578 1.250000e+00 1.898623e-04 +579 1.260000e+00 1.913982e-04 +580 1.270000e+00 1.929161e-04 +581 1.280000e+00 1.944163e-04 +582 1.290000e+00 1.958991e-04 +583 1.300000e+00 1.973646e-04 +584 1.310000e+00 1.988131e-04 +585 1.320000e+00 2.002448e-04 +586 1.330000e+00 2.016600e-04 +587 1.340000e+00 2.030588e-04 +588 1.350000e+00 2.044415e-04 +589 1.360000e+00 2.058082e-04 +590 1.370000e+00 2.071593e-04 +591 1.380000e+00 2.084949e-04 +592 1.390000e+00 2.098152e-04 +593 1.400000e+00 2.111204e-04 +594 1.410000e+00 2.124107e-04 +595 1.420000e+00 2.136863e-04 +596 1.430000e+00 2.149474e-04 +597 1.440000e+00 2.161942e-04 +598 1.450000e+00 2.174268e-04 +599 1.460000e+00 2.186455e-04 +600 1.470000e+00 2.198504e-04 +601 1.480000e+00 2.210417e-04 +602 1.490000e+00 2.222196e-04 +603 1.500000e+00 2.233842e-04 +604 0.000000e+00 3.802857e-12 +605 1.000000e-02 5.179405e-12 +606 2.000000e-02 7.436916e-12 +607 3.000000e-02 1.067638e-11 +608 4.000000e-02 1.532378e-11 +609 5.000000e-02 2.317943e-11 +610 6.000000e-02 3.325101e-11 +611 7.000000e-02 4.768511e-11 +612 8.000000e-02 6.836303e-11 +613 9.000000e-02 9.797210e-11 +614 1.000000e-01 1.403476e-10 +615 1.100000e-01 2.009572e-10 +616 1.200000e-01 2.875868e-10 +617 1.300000e-01 4.113064e-10 +618 1.400000e-01 5.878303e-10 +619 1.500000e-01 8.394210e-10 +620 1.600000e-01 1.197526e-09 +621 1.700000e-01 1.706327e-09 +622 1.800000e-01 2.427883e-09 +623 1.900000e-01 3.448995e-09 +624 2.000000e-01 4.890513e-09 +625 2.100000e-01 6.919840e-09 +626 2.200000e-01 9.767530e-09 +627 2.300000e-01 1.374902e-08 +628 2.400000e-01 1.929264e-08 +629 2.500000e-01 2.697515e-08 +630 2.600000e-01 3.756591e-08 +631 2.700000e-01 5.208067e-08 +632 2.800000e-01 7.184554e-08 +633 2.900000e-01 9.857148e-08 +634 3.000000e-01 1.344389e-07 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +635 3.100000e-01 1.821917e-07 +636 3.200000e-01 2.452412e-07 +637 3.300000e-01 3.277779e-07 +638 3.400000e-01 4.348938e-07 +639 3.500000e-01 5.727141e-07 +640 3.600000e-01 7.485378e-07 +641 3.700000e-01 9.709820e-07 +642 3.800000e-01 1.250117e-06 +643 3.900000e-01 1.597567e-06 +644 4.000000e-01 2.026526e-06 +645 4.100000e-01 2.551636e-06 +646 4.200000e-01 3.188614e-06 +647 4.300000e-01 3.953476e-06 +648 4.400000e-01 4.861015e-06 +649 4.500000e-01 5.921696e-06 +650 4.600000e-01 7.136545e-06 +651 4.700000e-01 8.498437e-06 +652 4.800000e-01 1.000774e-05 +653 4.900000e-01 1.167295e-05 +654 5.000000e-01 1.349892e-05 +655 5.100000e-01 1.548464e-05 +656 5.200000e-01 1.762458e-05 +657 5.300000e-01 1.990991e-05 +658 5.400000e-01 2.232939e-05 +659 5.500000e-01 2.487011e-05 +660 5.600000e-01 2.751817e-05 +661 5.700000e-01 3.025929e-05 +662 5.800000e-01 3.307926e-05 +663 5.900000e-01 3.593405e-05 +664 6.000000e-01 3.887775e-05 +665 6.100000e-01 4.186125e-05 +666 6.200000e-01 4.487369e-05 +667 6.300000e-01 4.790535e-05 +668 6.400000e-01 5.094767e-05 +669 6.500000e-01 5.399320e-05 +670 6.600000e-01 5.703551e-05 +671 6.700000e-01 6.006913e-05 +672 6.800000e-01 6.308940e-05 +673 6.900000e-01 6.609245e-05 +674 7.000000e-01 6.907502e-05 +675 7.100000e-01 7.203445e-05 +676 7.200000e-01 7.496857e-05 +677 7.300000e-01 7.787563e-05 +678 7.400000e-01 8.075423e-05 +679 7.500000e-01 8.360329e-05 +680 7.600000e-01 8.642197e-05 +681 7.700000e-01 8.920966e-05 +682 7.800000e-01 9.196592e-05 +683 7.900000e-01 9.469048e-05 +684 8.000000e-01 9.738318e-05 +685 8.100000e-01 1.000440e-04 +686 8.200000e-01 1.026729e-04 +687 8.300000e-01 1.052700e-04 +688 8.400000e-01 1.078355e-04 +689 8.500000e-01 1.103696e-04 +690 8.600000e-01 1.128726e-04 +691 8.700000e-01 1.153446e-04 +692 8.800000e-01 1.177862e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +693 8.900000e-01 1.201975e-04 +694 9.000000e-01 1.225789e-04 +695 9.100000e-01 1.249307e-04 +696 9.200000e-01 1.272534e-04 +697 9.300000e-01 1.295472e-04 +698 9.400000e-01 1.318126e-04 +699 9.500000e-01 1.340500e-04 +700 9.600000e-01 1.362596e-04 +701 9.700000e-01 1.384419e-04 +702 9.800000e-01 1.405972e-04 +703 9.900000e-01 1.427260e-04 +704 1.000000e+00 1.448286e-04 +705 1.010000e+00 1.469053e-04 +706 1.020000e+00 1.489565e-04 +707 1.030000e+00 1.509825e-04 +708 1.040000e+00 1.529838e-04 +709 1.050000e+00 1.549607e-04 +710 1.060000e+00 1.569135e-04 +711 1.070000e+00 1.588425e-04 +712 1.080000e+00 1.607482e-04 +713 1.090000e+00 1.626307e-04 +714 1.100000e+00 1.644905e-04 +715 1.110000e+00 1.663278e-04 +716 1.120000e+00 1.681431e-04 +717 1.130000e+00 1.699365e-04 +718 1.140000e+00 1.717084e-04 +719 1.150000e+00 1.734591e-04 +720 1.160000e+00 1.751888e-04 +721 1.170000e+00 1.768980e-04 +722 1.180000e+00 1.785868e-04 +723 1.190000e+00 1.802556e-04 +724 1.200000e+00 1.819046e-04 +725 1.210000e+00 1.835341e-04 +726 1.220000e+00 1.851443e-04 +727 1.230000e+00 1.867356e-04 +728 1.240000e+00 1.883082e-04 +729 1.250000e+00 1.898623e-04 +730 1.260000e+00 1.913982e-04 +731 1.270000e+00 1.929161e-04 +732 1.280000e+00 1.944163e-04 +733 1.290000e+00 1.958991e-04 +734 1.300000e+00 1.973646e-04 +735 1.310000e+00 1.988131e-04 +736 1.320000e+00 2.002448e-04 +737 1.330000e+00 2.016600e-04 +738 1.340000e+00 2.030588e-04 +739 1.350000e+00 2.044415e-04 +740 1.360000e+00 2.058082e-04 +741 1.370000e+00 2.071593e-04 +742 1.380000e+00 2.084949e-04 +743 1.390000e+00 2.098152e-04 +744 1.400000e+00 2.111204e-04 +745 1.410000e+00 2.124107e-04 +746 1.420000e+00 2.136863e-04 +747 1.430000e+00 2.149474e-04 +748 1.440000e+00 2.161942e-04 +749 1.450000e+00 2.174268e-04 +750 1.460000e+00 2.186455e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +751 1.470000e+00 2.198504e-04 +752 1.480000e+00 2.210417e-04 +753 1.490000e+00 2.222196e-04 +754 1.500000e+00 2.233842e-04 +755 0.000000e+00 3.802857e-12 +756 1.000000e-02 5.179405e-12 +757 2.000000e-02 7.436916e-12 +758 3.000000e-02 1.067638e-11 +759 4.000000e-02 1.532378e-11 +760 5.000000e-02 2.317943e-11 +761 6.000000e-02 3.325101e-11 +762 7.000000e-02 4.768511e-11 +763 8.000000e-02 6.836303e-11 +764 9.000000e-02 9.797210e-11 +765 1.000000e-01 1.403476e-10 +766 1.100000e-01 2.009572e-10 +767 1.200000e-01 2.875868e-10 +768 1.300000e-01 4.113064e-10 +769 1.400000e-01 5.878303e-10 +770 1.500000e-01 8.394210e-10 +771 1.600000e-01 1.197526e-09 +772 1.700000e-01 1.706327e-09 +773 1.800000e-01 2.427883e-09 +774 1.900000e-01 3.448995e-09 +775 2.000000e-01 4.890513e-09 +776 2.100000e-01 6.919840e-09 +777 2.200000e-01 9.767530e-09 +778 2.300000e-01 1.374902e-08 +779 2.400000e-01 1.929264e-08 +780 2.500000e-01 2.697515e-08 +781 2.600000e-01 3.756591e-08 +782 2.700000e-01 5.208067e-08 +783 2.800000e-01 7.184554e-08 +784 2.900000e-01 9.857148e-08 +785 3.000000e-01 1.344389e-07 +786 3.100000e-01 1.821917e-07 +787 3.200000e-01 2.452412e-07 +788 3.300000e-01 3.277779e-07 +789 3.400000e-01 4.348938e-07 +790 3.500000e-01 5.727141e-07 +791 3.600000e-01 7.485378e-07 +792 3.700000e-01 9.709820e-07 +793 3.800000e-01 1.250117e-06 +794 3.900000e-01 1.597567e-06 +795 4.000000e-01 2.026526e-06 +796 4.100000e-01 2.551636e-06 +797 4.200000e-01 3.188614e-06 +798 4.300000e-01 3.953476e-06 +799 4.400000e-01 4.861015e-06 +800 4.500000e-01 5.921696e-06 +801 4.600000e-01 7.136545e-06 +802 4.700000e-01 8.498437e-06 +803 4.800000e-01 1.000774e-05 +804 4.900000e-01 1.167295e-05 +805 5.000000e-01 1.349892e-05 +806 5.100000e-01 1.548464e-05 +807 5.200000e-01 1.762458e-05 +808 5.300000e-01 1.990991e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +809 5.400000e-01 2.232939e-05 +810 5.500000e-01 2.487011e-05 +811 5.600000e-01 2.751817e-05 +812 5.700000e-01 3.025929e-05 +813 5.800000e-01 3.307926e-05 +814 5.900000e-01 3.593405e-05 +815 6.000000e-01 3.887775e-05 +816 6.100000e-01 4.186125e-05 +817 6.200000e-01 4.487369e-05 +818 6.300000e-01 4.790535e-05 +819 6.400000e-01 5.094767e-05 +820 6.500000e-01 5.399320e-05 +821 6.600000e-01 5.703551e-05 +822 6.700000e-01 6.006913e-05 +823 6.800000e-01 6.308940e-05 +824 6.900000e-01 6.609245e-05 +825 7.000000e-01 6.907502e-05 +826 7.100000e-01 7.203445e-05 +827 7.200000e-01 7.496857e-05 +828 7.300000e-01 7.787563e-05 +829 7.400000e-01 8.075423e-05 +830 7.500000e-01 8.360329e-05 +831 7.600000e-01 8.642197e-05 +832 7.700000e-01 8.920966e-05 +833 7.800000e-01 9.196592e-05 +834 7.900000e-01 9.469048e-05 +835 8.000000e-01 9.738318e-05 +836 8.100000e-01 1.000440e-04 +837 8.200000e-01 1.026729e-04 +838 8.300000e-01 1.052700e-04 +839 8.400000e-01 1.078355e-04 +840 8.500000e-01 1.103696e-04 +841 8.600000e-01 1.128726e-04 +842 8.700000e-01 1.153446e-04 +843 8.800000e-01 1.177862e-04 +844 8.900000e-01 1.201975e-04 +845 9.000000e-01 1.225789e-04 +846 9.100000e-01 1.249307e-04 +847 9.200000e-01 1.272534e-04 +848 9.300000e-01 1.295472e-04 +849 9.400000e-01 1.318126e-04 +850 9.500000e-01 1.340500e-04 +851 9.600000e-01 1.362596e-04 +852 9.700000e-01 1.384419e-04 +853 9.800000e-01 1.405972e-04 +854 9.900000e-01 1.427260e-04 +855 1.000000e+00 1.448286e-04 +856 1.010000e+00 1.469053e-04 +857 1.020000e+00 1.489565e-04 +858 1.030000e+00 1.509825e-04 +859 1.040000e+00 1.529838e-04 +860 1.050000e+00 1.549607e-04 +861 1.060000e+00 1.569135e-04 +862 1.070000e+00 1.588425e-04 +863 1.080000e+00 1.607482e-04 +864 1.090000e+00 1.626307e-04 +865 1.100000e+00 1.644905e-04 +866 1.110000e+00 1.663278e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +867 1.120000e+00 1.681431e-04 +868 1.130000e+00 1.699365e-04 +869 1.140000e+00 1.717084e-04 +870 1.150000e+00 1.734591e-04 +871 1.160000e+00 1.751888e-04 +872 1.170000e+00 1.768980e-04 +873 1.180000e+00 1.785868e-04 +874 1.190000e+00 1.802556e-04 +875 1.200000e+00 1.819046e-04 +876 1.210000e+00 1.835341e-04 +877 1.220000e+00 1.851443e-04 +878 1.230000e+00 1.867356e-04 +879 1.240000e+00 1.883082e-04 +880 1.250000e+00 1.898623e-04 +881 1.260000e+00 1.913982e-04 +882 1.270000e+00 1.929161e-04 +883 1.280000e+00 1.944163e-04 +884 1.290000e+00 1.958991e-04 +885 1.300000e+00 1.973646e-04 +886 1.310000e+00 1.988131e-04 +887 1.320000e+00 2.002448e-04 +888 1.330000e+00 2.016600e-04 +889 1.340000e+00 2.030588e-04 +890 1.350000e+00 2.044415e-04 +891 1.360000e+00 2.058082e-04 +892 1.370000e+00 2.071593e-04 +893 1.380000e+00 2.084949e-04 +894 1.390000e+00 2.098152e-04 +895 1.400000e+00 2.111204e-04 +896 1.410000e+00 2.124107e-04 +897 1.420000e+00 2.136863e-04 +898 1.430000e+00 2.149474e-04 +899 1.440000e+00 2.161942e-04 +900 1.450000e+00 2.174268e-04 +901 1.460000e+00 2.186455e-04 +902 1.470000e+00 2.198504e-04 +903 1.480000e+00 2.210417e-04 +904 1.490000e+00 2.222196e-04 +905 1.500000e+00 2.233842e-04 +906 0.000000e+00 3.802857e-12 +907 1.000000e-02 5.179405e-12 +908 2.000000e-02 7.436916e-12 +909 3.000000e-02 1.067638e-11 +910 4.000000e-02 1.532378e-11 +911 5.000000e-02 2.317943e-11 +912 6.000000e-02 3.325101e-11 +913 7.000000e-02 4.768511e-11 +914 8.000000e-02 6.836303e-11 +915 9.000000e-02 9.797210e-11 +916 1.000000e-01 1.403476e-10 +917 1.100000e-01 2.009572e-10 +918 1.200000e-01 2.875868e-10 +919 1.300000e-01 4.113064e-10 +920 1.400000e-01 5.878303e-10 +921 1.500000e-01 8.394210e-10 +922 1.600000e-01 1.197526e-09 +923 1.700000e-01 1.706327e-09 +924 1.800000e-01 2.427883e-09 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +925 1.900000e-01 3.448995e-09 +926 2.000000e-01 4.890513e-09 +927 2.100000e-01 6.919840e-09 +928 2.200000e-01 9.767530e-09 +929 2.300000e-01 1.374902e-08 +930 2.400000e-01 1.929264e-08 +931 2.500000e-01 2.697515e-08 +932 2.600000e-01 3.756591e-08 +933 2.700000e-01 5.208067e-08 +934 2.800000e-01 7.184554e-08 +935 2.900000e-01 9.857148e-08 +936 3.000000e-01 1.344389e-07 +937 3.100000e-01 1.821917e-07 +938 3.200000e-01 2.452412e-07 +939 3.300000e-01 3.277779e-07 +940 3.400000e-01 4.348938e-07 +941 3.500000e-01 5.727141e-07 +942 3.600000e-01 7.485378e-07 +943 3.700000e-01 9.709820e-07 +944 3.800000e-01 1.250117e-06 +945 3.900000e-01 1.597567e-06 +946 4.000000e-01 2.026526e-06 +947 4.100000e-01 2.551636e-06 +948 4.200000e-01 3.188614e-06 +949 4.300000e-01 3.953476e-06 +950 4.400000e-01 4.861015e-06 +951 4.500000e-01 5.921696e-06 +952 4.600000e-01 7.136545e-06 +953 4.700000e-01 8.498437e-06 +954 4.800000e-01 1.000774e-05 +955 4.900000e-01 1.167295e-05 +956 5.000000e-01 1.349892e-05 +957 5.100000e-01 1.548464e-05 +958 5.200000e-01 1.762458e-05 +959 5.300000e-01 1.990991e-05 +960 5.400000e-01 2.232939e-05 +961 5.500000e-01 2.487011e-05 +962 5.600000e-01 2.751817e-05 +963 5.700000e-01 3.025929e-05 +964 5.800000e-01 3.307926e-05 +965 5.900000e-01 3.593405e-05 +966 6.000000e-01 3.887775e-05 +967 6.100000e-01 4.186125e-05 +968 6.200000e-01 4.487369e-05 +969 6.300000e-01 4.790535e-05 +970 6.400000e-01 5.094767e-05 +971 6.500000e-01 5.399320e-05 +972 6.600000e-01 5.703551e-05 +973 6.700000e-01 6.006913e-05 +974 6.800000e-01 6.308940e-05 +975 6.900000e-01 6.609245e-05 +976 7.000000e-01 6.907502e-05 +977 7.100000e-01 7.203445e-05 +978 7.200000e-01 7.496857e-05 +979 7.300000e-01 7.787563e-05 +980 7.400000e-01 8.075423e-05 +981 7.500000e-01 8.360329e-05 +982 7.600000e-01 8.642197e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +983 7.700000e-01 8.920966e-05 +984 7.800000e-01 9.196592e-05 +985 7.900000e-01 9.469048e-05 +986 8.000000e-01 9.738318e-05 +987 8.100000e-01 1.000440e-04 +988 8.200000e-01 1.026729e-04 +989 8.300000e-01 1.052700e-04 +990 8.400000e-01 1.078355e-04 +991 8.500000e-01 1.103696e-04 +992 8.600000e-01 1.128726e-04 +993 8.700000e-01 1.153446e-04 +994 8.800000e-01 1.177862e-04 +995 8.900000e-01 1.201975e-04 +996 9.000000e-01 1.225789e-04 +997 9.100000e-01 1.249307e-04 +998 9.200000e-01 1.272534e-04 +999 9.300000e-01 1.295472e-04 +1000 9.400000e-01 1.318126e-04 +1001 9.500000e-01 1.340500e-04 +1002 9.600000e-01 1.362596e-04 +1003 9.700000e-01 1.384419e-04 +1004 9.800000e-01 1.405972e-04 +1005 9.900000e-01 1.427260e-04 +1006 1.000000e+00 1.448286e-04 +1007 1.010000e+00 1.469053e-04 +1008 1.020000e+00 1.489565e-04 +1009 1.030000e+00 1.509825e-04 +1010 1.040000e+00 1.529838e-04 +1011 1.050000e+00 1.549607e-04 +1012 1.060000e+00 1.569135e-04 +1013 1.070000e+00 1.588425e-04 +1014 1.080000e+00 1.607482e-04 +1015 1.090000e+00 1.626307e-04 +1016 1.100000e+00 1.644905e-04 +1017 1.110000e+00 1.663278e-04 +1018 1.120000e+00 1.681431e-04 +1019 1.130000e+00 1.699365e-04 +1020 1.140000e+00 1.717084e-04 +1021 1.150000e+00 1.734591e-04 +1022 1.160000e+00 1.751888e-04 +1023 1.170000e+00 1.768980e-04 +1024 1.180000e+00 1.785868e-04 +1025 1.190000e+00 1.802556e-04 +1026 1.200000e+00 1.819046e-04 +1027 1.210000e+00 1.835341e-04 +1028 1.220000e+00 1.851443e-04 +1029 1.230000e+00 1.867356e-04 +1030 1.240000e+00 1.883082e-04 +1031 1.250000e+00 1.898623e-04 +1032 1.260000e+00 1.913982e-04 +1033 1.270000e+00 1.929161e-04 +1034 1.280000e+00 1.944163e-04 +1035 1.290000e+00 1.958991e-04 +1036 1.300000e+00 1.973646e-04 +1037 1.310000e+00 1.988131e-04 +1038 1.320000e+00 2.002448e-04 +1039 1.330000e+00 2.016600e-04 +1040 1.340000e+00 2.030588e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1041 1.350000e+00 2.044415e-04 +1042 1.360000e+00 2.058082e-04 +1043 1.370000e+00 2.071593e-04 +1044 1.380000e+00 2.084949e-04 +1045 1.390000e+00 2.098152e-04 +1046 1.400000e+00 2.111204e-04 +1047 1.410000e+00 2.124107e-04 +1048 1.420000e+00 2.136863e-04 +1049 1.430000e+00 2.149474e-04 +1050 1.440000e+00 2.161942e-04 +1051 1.450000e+00 2.174268e-04 +1052 1.460000e+00 2.186455e-04 +1053 1.470000e+00 2.198504e-04 +1054 1.480000e+00 2.210417e-04 +1055 1.490000e+00 2.222196e-04 +1056 1.500000e+00 2.233842e-04 +1057 0.000000e+00 3.802857e-12 +1058 1.000000e-02 5.179405e-12 +1059 2.000000e-02 7.436916e-12 +1060 3.000000e-02 1.067638e-11 +1061 4.000000e-02 1.532378e-11 +1062 5.000000e-02 2.317943e-11 +1063 6.000000e-02 3.325101e-11 +1064 7.000000e-02 4.768511e-11 +1065 8.000000e-02 6.836303e-11 +1066 9.000000e-02 9.797210e-11 +1067 1.000000e-01 1.403476e-10 +1068 1.100000e-01 2.009572e-10 +1069 1.200000e-01 2.875868e-10 +1070 1.300000e-01 4.113064e-10 +1071 1.400000e-01 5.878303e-10 +1072 1.500000e-01 8.394210e-10 +1073 1.600000e-01 1.197526e-09 +1074 1.700000e-01 1.706327e-09 +1075 1.800000e-01 2.427883e-09 +1076 1.900000e-01 3.448995e-09 +1077 2.000000e-01 4.890513e-09 +1078 2.100000e-01 6.919840e-09 +1079 2.200000e-01 9.767530e-09 +1080 2.300000e-01 1.374902e-08 +1081 2.400000e-01 1.929264e-08 +1082 2.500000e-01 2.697515e-08 +1083 2.600000e-01 3.756591e-08 +1084 2.700000e-01 5.208067e-08 +1085 2.800000e-01 7.184554e-08 +1086 2.900000e-01 9.857148e-08 +1087 3.000000e-01 1.344389e-07 +1088 3.100000e-01 1.821917e-07 +1089 3.200000e-01 2.452412e-07 +1090 3.300000e-01 3.277779e-07 +1091 3.400000e-01 4.348938e-07 +1092 3.500000e-01 5.727141e-07 +1093 3.600000e-01 7.485378e-07 +1094 3.700000e-01 9.709820e-07 +1095 3.800000e-01 1.250117e-06 +1096 3.900000e-01 1.597567e-06 +1097 4.000000e-01 2.026526e-06 +1098 4.100000e-01 2.551636e-06 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1099 4.200000e-01 3.188614e-06 +1100 4.300000e-01 3.953476e-06 +1101 4.400000e-01 4.861015e-06 +1102 4.500000e-01 5.921696e-06 +1103 4.600000e-01 7.136545e-06 +1104 4.700000e-01 8.498437e-06 +1105 4.800000e-01 1.000774e-05 +1106 4.900000e-01 1.167295e-05 +1107 5.000000e-01 1.349892e-05 +1108 5.100000e-01 1.548464e-05 +1109 5.200000e-01 1.762458e-05 +1110 5.300000e-01 1.990991e-05 +1111 5.400000e-01 2.232939e-05 +1112 5.500000e-01 2.487011e-05 +1113 5.600000e-01 2.751817e-05 +1114 5.700000e-01 3.025929e-05 +1115 5.800000e-01 3.307926e-05 +1116 5.900000e-01 3.593405e-05 +1117 6.000000e-01 3.887775e-05 +1118 6.100000e-01 4.186125e-05 +1119 6.200000e-01 4.487369e-05 +1120 6.300000e-01 4.790535e-05 +1121 6.400000e-01 5.094767e-05 +1122 6.500000e-01 5.399320e-05 +1123 6.600000e-01 5.703551e-05 +1124 6.700000e-01 6.006913e-05 +1125 6.800000e-01 6.308940e-05 +1126 6.900000e-01 6.609245e-05 +1127 7.000000e-01 6.907502e-05 +1128 7.100000e-01 7.203445e-05 +1129 7.200000e-01 7.496857e-05 +1130 7.300000e-01 7.787563e-05 +1131 7.400000e-01 8.075423e-05 +1132 7.500000e-01 8.360329e-05 +1133 7.600000e-01 8.642197e-05 +1134 7.700000e-01 8.920966e-05 +1135 7.800000e-01 9.196592e-05 +1136 7.900000e-01 9.469048e-05 +1137 8.000000e-01 9.738318e-05 +1138 8.100000e-01 1.000440e-04 +1139 8.200000e-01 1.026729e-04 +1140 8.300000e-01 1.052700e-04 +1141 8.400000e-01 1.078355e-04 +1142 8.500000e-01 1.103696e-04 +1143 8.600000e-01 1.128726e-04 +1144 8.700000e-01 1.153446e-04 +1145 8.800000e-01 1.177862e-04 +1146 8.900000e-01 1.201975e-04 +1147 9.000000e-01 1.225789e-04 +1148 9.100000e-01 1.249307e-04 +1149 9.200000e-01 1.272534e-04 +1150 9.300000e-01 1.295472e-04 +1151 9.400000e-01 1.318126e-04 +1152 9.500000e-01 1.340500e-04 +1153 9.600000e-01 1.362596e-04 +1154 9.700000e-01 1.384419e-04 +1155 9.800000e-01 1.405972e-04 +1156 9.900000e-01 1.427260e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1157 1.000000e+00 1.448286e-04 +1158 1.010000e+00 1.469053e-04 +1159 1.020000e+00 1.489565e-04 +1160 1.030000e+00 1.509825e-04 +1161 1.040000e+00 1.529838e-04 +1162 1.050000e+00 1.549607e-04 +1163 1.060000e+00 1.569135e-04 +1164 1.070000e+00 1.588425e-04 +1165 1.080000e+00 1.607482e-04 +1166 1.090000e+00 1.626307e-04 +1167 1.100000e+00 1.644905e-04 +1168 1.110000e+00 1.663278e-04 +1169 1.120000e+00 1.681431e-04 +1170 1.130000e+00 1.699365e-04 +1171 1.140000e+00 1.717084e-04 +1172 1.150000e+00 1.734591e-04 +1173 1.160000e+00 1.751888e-04 +1174 1.170000e+00 1.768980e-04 +1175 1.180000e+00 1.785868e-04 +1176 1.190000e+00 1.802556e-04 +1177 1.200000e+00 1.819046e-04 +1178 1.210000e+00 1.835341e-04 +1179 1.220000e+00 1.851443e-04 +1180 1.230000e+00 1.867356e-04 +1181 1.240000e+00 1.883082e-04 +1182 1.250000e+00 1.898623e-04 +1183 1.260000e+00 1.913982e-04 +1184 1.270000e+00 1.929161e-04 +1185 1.280000e+00 1.944163e-04 +1186 1.290000e+00 1.958991e-04 +1187 1.300000e+00 1.973646e-04 +1188 1.310000e+00 1.988131e-04 +1189 1.320000e+00 2.002448e-04 +1190 1.330000e+00 2.016600e-04 +1191 1.340000e+00 2.030588e-04 +1192 1.350000e+00 2.044415e-04 +1193 1.360000e+00 2.058082e-04 +1194 1.370000e+00 2.071593e-04 +1195 1.380000e+00 2.084949e-04 +1196 1.390000e+00 2.098152e-04 +1197 1.400000e+00 2.111204e-04 +1198 1.410000e+00 2.124107e-04 +1199 1.420000e+00 2.136863e-04 +1200 1.430000e+00 2.149474e-04 +1201 1.440000e+00 2.161942e-04 +1202 1.450000e+00 2.174268e-04 +1203 1.460000e+00 2.186455e-04 +1204 1.470000e+00 2.198504e-04 +1205 1.480000e+00 2.210417e-04 +1206 1.490000e+00 2.222196e-04 +1207 1.500000e+00 2.233842e-04 +1208 0.000000e+00 3.802857e-12 +1209 1.000000e-02 5.179405e-12 +1210 2.000000e-02 7.436916e-12 +1211 3.000000e-02 1.067638e-11 +1212 4.000000e-02 1.532378e-11 +1213 5.000000e-02 2.317943e-11 +1214 6.000000e-02 3.325101e-11 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1215 7.000000e-02 4.768511e-11 +1216 8.000000e-02 6.836303e-11 +1217 9.000000e-02 9.797210e-11 +1218 1.000000e-01 1.403476e-10 +1219 1.100000e-01 2.009572e-10 +1220 1.200000e-01 2.875868e-10 +1221 1.300000e-01 4.113064e-10 +1222 1.400000e-01 5.878303e-10 +1223 1.500000e-01 8.394210e-10 +1224 1.600000e-01 1.197526e-09 +1225 1.700000e-01 1.706327e-09 +1226 1.800000e-01 2.427883e-09 +1227 1.900000e-01 3.448995e-09 +1228 2.000000e-01 4.890513e-09 +1229 2.100000e-01 6.919840e-09 +1230 2.200000e-01 9.767530e-09 +1231 2.300000e-01 1.374902e-08 +1232 2.400000e-01 1.929264e-08 +1233 2.500000e-01 2.697515e-08 +1234 2.600000e-01 3.756591e-08 +1235 2.700000e-01 5.208067e-08 +1236 2.800000e-01 7.184554e-08 +1237 2.900000e-01 9.857148e-08 +1238 3.000000e-01 1.344389e-07 +1239 3.100000e-01 1.821917e-07 +1240 3.200000e-01 2.452412e-07 +1241 3.300000e-01 3.277779e-07 +1242 3.400000e-01 4.348938e-07 +1243 3.500000e-01 5.727141e-07 +1244 3.600000e-01 7.485378e-07 +1245 3.700000e-01 9.709820e-07 +1246 3.800000e-01 1.250117e-06 +1247 3.900000e-01 1.597567e-06 +1248 4.000000e-01 2.026526e-06 +1249 4.100000e-01 2.551636e-06 +1250 4.200000e-01 3.188614e-06 +1251 4.300000e-01 3.953476e-06 +1252 4.400000e-01 4.861015e-06 +1253 4.500000e-01 5.921696e-06 +1254 4.600000e-01 7.136545e-06 +1255 4.700000e-01 8.498437e-06 +1256 4.800000e-01 1.000774e-05 +1257 4.900000e-01 1.167295e-05 +1258 5.000000e-01 1.349892e-05 +1259 5.100000e-01 1.548464e-05 +1260 5.200000e-01 1.762458e-05 +1261 5.300000e-01 1.990991e-05 +1262 5.400000e-01 2.232939e-05 +1263 5.500000e-01 2.487011e-05 +1264 5.600000e-01 2.751817e-05 +1265 5.700000e-01 3.025929e-05 +1266 5.800000e-01 3.307926e-05 +1267 5.900000e-01 3.593405e-05 +1268 6.000000e-01 3.887775e-05 +1269 6.100000e-01 4.186125e-05 +1270 6.200000e-01 4.487369e-05 +1271 6.300000e-01 4.790535e-05 +1272 6.400000e-01 5.094767e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1273 6.500000e-01 5.399320e-05 +1274 6.600000e-01 5.703551e-05 +1275 6.700000e-01 6.006913e-05 +1276 6.800000e-01 6.308940e-05 +1277 6.900000e-01 6.609245e-05 +1278 7.000000e-01 6.907502e-05 +1279 7.100000e-01 7.203445e-05 +1280 7.200000e-01 7.496857e-05 +1281 7.300000e-01 7.787563e-05 +1282 7.400000e-01 8.075423e-05 +1283 7.500000e-01 8.360329e-05 +1284 7.600000e-01 8.642197e-05 +1285 7.700000e-01 8.920966e-05 +1286 7.800000e-01 9.196592e-05 +1287 7.900000e-01 9.469048e-05 +1288 8.000000e-01 9.738318e-05 +1289 8.100000e-01 1.000440e-04 +1290 8.200000e-01 1.026729e-04 +1291 8.300000e-01 1.052700e-04 +1292 8.400000e-01 1.078355e-04 +1293 8.500000e-01 1.103696e-04 +1294 8.600000e-01 1.128726e-04 +1295 8.700000e-01 1.153446e-04 +1296 8.800000e-01 1.177862e-04 +1297 8.900000e-01 1.201975e-04 +1298 9.000000e-01 1.225789e-04 +1299 9.100000e-01 1.249307e-04 +1300 9.200000e-01 1.272534e-04 +1301 9.300000e-01 1.295472e-04 +1302 9.400000e-01 1.318126e-04 +1303 9.500000e-01 1.340500e-04 +1304 9.600000e-01 1.362596e-04 +1305 9.700000e-01 1.384419e-04 +1306 9.800000e-01 1.405972e-04 +1307 9.900000e-01 1.427260e-04 +1308 1.000000e+00 1.448286e-04 +1309 1.010000e+00 1.469053e-04 +1310 1.020000e+00 1.489565e-04 +1311 1.030000e+00 1.509825e-04 +1312 1.040000e+00 1.529838e-04 +1313 1.050000e+00 1.549607e-04 +1314 1.060000e+00 1.569135e-04 +1315 1.070000e+00 1.588425e-04 +1316 1.080000e+00 1.607482e-04 +1317 1.090000e+00 1.626307e-04 +1318 1.100000e+00 1.644905e-04 +1319 1.110000e+00 1.663278e-04 +1320 1.120000e+00 1.681431e-04 +1321 1.130000e+00 1.699365e-04 +1322 1.140000e+00 1.717084e-04 +1323 1.150000e+00 1.734591e-04 +1324 1.160000e+00 1.751888e-04 +1325 1.170000e+00 1.768980e-04 +1326 1.180000e+00 1.785868e-04 +1327 1.190000e+00 1.802556e-04 +1328 1.200000e+00 1.819046e-04 +1329 1.210000e+00 1.835341e-04 +1330 1.220000e+00 1.851443e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1331 1.230000e+00 1.867356e-04 +1332 1.240000e+00 1.883082e-04 +1333 1.250000e+00 1.898623e-04 +1334 1.260000e+00 1.913982e-04 +1335 1.270000e+00 1.929161e-04 +1336 1.280000e+00 1.944163e-04 +1337 1.290000e+00 1.958991e-04 +1338 1.300000e+00 1.973646e-04 +1339 1.310000e+00 1.988131e-04 +1340 1.320000e+00 2.002448e-04 +1341 1.330000e+00 2.016600e-04 +1342 1.340000e+00 2.030588e-04 +1343 1.350000e+00 2.044415e-04 +1344 1.360000e+00 2.058082e-04 +1345 1.370000e+00 2.071593e-04 +1346 1.380000e+00 2.084949e-04 +1347 1.390000e+00 2.098152e-04 +1348 1.400000e+00 2.111204e-04 +1349 1.410000e+00 2.124107e-04 +1350 1.420000e+00 2.136863e-04 +1351 1.430000e+00 2.149474e-04 +1352 1.440000e+00 2.161942e-04 +1353 1.450000e+00 2.174268e-04 +1354 1.460000e+00 2.186455e-04 +1355 1.470000e+00 2.198504e-04 +1356 1.480000e+00 2.210417e-04 +1357 1.490000e+00 2.222196e-04 +1358 1.500000e+00 2.233842e-04 + + + + diff --git a/tests/bsim3soifd/t5.cir b/tests/bsim3soifd/t5.cir new file mode 100644 index 000000000..0d44c378a --- /dev/null +++ b/tests/bsim3soifd/t5.cir @@ -0,0 +1,16 @@ +*model = BSIMSOI (FD) +*Berkeley Spice Compatibility +* +* SOI NMOSFET, floating body simulation + +vd d 0 dc 0.05 +vs s 0 dc 0 +ve e 0 dc 0 +vg g 0 dc 3 + +m1 d g s e n1 w=10u l=0.25u + +.option gmin=1e-25 itl1=500 +.dc vg 0 1.5 0.01 ve -4 4 1 +.print dc i(vs) +.include nmosfd.mod diff --git a/tests/bsim3soifd/t5.out b/tests/bsim3soifd/t5.out new file mode 100644 index 000000000..a4d9bf3b0 --- /dev/null +++ b/tests/bsim3soifd/t5.out @@ -0,0 +1,1444 @@ + Reference value : 5.50000e-01 +No. of Data Rows : 1359 + +Circuit: *model = BSIMSOI (FD) + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. + *model = BSIMSOI (FD) +-------------------------------------------------------------------------------- +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 2.494471e-14 +1 1.000000e-02 1.210630e-14 +2 2.000000e-02 1.680554e-14 +3 3.000000e-02 6.865338e-14 +4 4.000000e-02 9.780122e-14 +5 5.000000e-02 1.392800e-13 +6 6.000000e-02 1.982874e-13 +7 7.000000e-02 2.822037e-13 +8 8.000000e-02 4.015052e-13 +9 9.000000e-02 5.710570e-13 +10 1.000000e-01 8.119448e-13 +11 1.100000e-01 1.154067e-12 +12 1.200000e-01 1.639799e-12 +13 1.300000e-01 2.329183e-12 +14 1.400000e-01 3.307249e-12 +15 1.500000e-01 4.694367e-12 +16 1.600000e-01 6.660852e-12 +17 1.700000e-01 9.447000e-12 +18 1.800000e-01 1.339138e-11 +19 1.900000e-01 1.897272e-11 +20 2.000000e-01 2.821752e-11 +21 2.100000e-01 3.992749e-11 +22 2.200000e-01 5.646278e-11 +23 2.300000e-01 7.979470e-11 +24 2.400000e-01 1.126909e-10 +25 2.500000e-01 1.590320e-10 +26 2.600000e-01 2.242515e-10 +27 2.700000e-01 3.159445e-10 +28 2.800000e-01 4.447080e-10 +29 2.900000e-01 6.252959e-10 +30 3.000000e-01 8.782006e-10 +31 3.100000e-01 1.231806e-09 +32 3.200000e-01 1.725301e-09 +33 3.300000e-01 2.412600e-09 +34 3.400000e-01 3.367565e-09 +35 3.500000e-01 4.690912e-09 +36 3.600000e-01 6.519232e-09 +37 3.700000e-01 9.036644e-09 +38 3.800000e-01 1.248962e-08 +39 3.900000e-01 1.720557e-08 +40 4.000000e-01 2.361569e-08 +41 4.100000e-01 3.228250e-08 +42 4.200000e-01 4.393235e-08 +43 4.300000e-01 5.949286e-08 +44 4.400000e-01 8.013501e-08 +45 4.500000e-01 1.073195e-07 +46 4.600000e-01 1.428466e-07 +47 4.700000e-01 1.889097e-07 +48 4.800000e-01 2.481514e-07 +49 4.900000e-01 3.237247e-07 +50 5.000000e-01 4.193583e-07 +51 5.100000e-01 5.394302e-07 +52 5.200000e-01 6.890472e-07 +53 5.300000e-01 8.741323e-07 +54 5.400000e-01 1.101512e-06 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +55 5.500000e-01 1.378997e-06 +56 5.600000e-01 1.715435e-06 +57 5.700000e-01 2.120714e-06 +58 5.800000e-01 2.605704e-06 +59 5.900000e-01 3.182083e-06 +60 6.000000e-01 3.862081e-06 +61 6.100000e-01 4.658138e-06 +62 6.200000e-01 5.582629e-06 +63 6.300000e-01 6.647804e-06 +64 6.400000e-01 7.865113e-06 +65 6.500000e-01 9.242348e-06 +66 6.600000e-01 1.078247e-05 +67 6.700000e-01 1.248496e-05 +68 6.800000e-01 1.434625e-05 +69 6.900000e-01 1.635981e-05 +70 7.000000e-01 1.851645e-05 +71 7.100000e-01 2.080484e-05 +72 7.200000e-01 2.321211e-05 +73 7.300000e-01 2.572448e-05 +74 7.400000e-01 2.832782e-05 +75 7.500000e-01 3.100816e-05 +76 7.600000e-01 3.372246e-05 +77 7.700000e-01 3.652348e-05 +78 7.800000e-01 3.936336e-05 +79 7.900000e-01 4.223160e-05 +80 8.000000e-01 4.511888e-05 +81 8.100000e-01 4.801702e-05 +82 8.200000e-01 5.091896e-05 +83 8.300000e-01 5.381861e-05 +84 8.400000e-01 5.671083e-05 +85 8.500000e-01 5.959124e-05 +86 8.600000e-01 6.245623e-05 +87 8.700000e-01 6.530278e-05 +88 8.800000e-01 6.812841e-05 +89 8.900000e-01 7.093110e-05 +90 9.000000e-01 7.370922e-05 +91 9.100000e-01 7.646149e-05 +92 9.200000e-01 7.918688e-05 +93 9.300000e-01 8.188463e-05 +94 9.400000e-01 8.455416e-05 +95 9.500000e-01 8.719504e-05 +96 9.600000e-01 8.980701e-05 +97 9.700000e-01 9.238990e-05 +98 9.800000e-01 9.494364e-05 +99 9.900000e-01 9.746825e-05 +100 1.000000e+00 9.996379e-05 +101 1.010000e+00 1.024304e-04 +102 1.020000e+00 1.048683e-04 +103 1.030000e+00 1.072776e-04 +104 1.040000e+00 1.096586e-04 +105 1.050000e+00 1.120115e-04 +106 1.060000e+00 1.143366e-04 +107 1.070000e+00 1.166343e-04 +108 1.080000e+00 1.189047e-04 +109 1.090000e+00 1.211483e-04 +110 1.100000e+00 1.233653e-04 +111 1.110000e+00 1.255561e-04 +112 1.120000e+00 1.277209e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +113 1.130000e+00 1.298602e-04 +114 1.140000e+00 1.319741e-04 +115 1.150000e+00 1.340632e-04 +116 1.160000e+00 1.361276e-04 +117 1.170000e+00 1.381677e-04 +118 1.180000e+00 1.401838e-04 +119 1.190000e+00 1.421762e-04 +120 1.200000e+00 1.441453e-04 +121 1.210000e+00 1.460914e-04 +122 1.220000e+00 1.480147e-04 +123 1.230000e+00 1.499156e-04 +124 1.240000e+00 1.517944e-04 +125 1.250000e+00 1.536513e-04 +126 1.260000e+00 1.554867e-04 +127 1.270000e+00 1.573008e-04 +128 1.280000e+00 1.590939e-04 +129 1.290000e+00 1.608664e-04 +130 1.300000e+00 1.626185e-04 +131 1.310000e+00 1.643504e-04 +132 1.320000e+00 1.660624e-04 +133 1.330000e+00 1.677548e-04 +134 1.340000e+00 1.694279e-04 +135 1.350000e+00 1.710819e-04 +136 1.360000e+00 1.727170e-04 +137 1.370000e+00 1.743335e-04 +138 1.380000e+00 1.759317e-04 +139 1.390000e+00 1.775118e-04 +140 1.400000e+00 1.790740e-04 +141 1.410000e+00 1.806186e-04 +142 1.420000e+00 1.821458e-04 +143 1.430000e+00 1.836558e-04 +144 1.440000e+00 1.851488e-04 +145 1.450000e+00 1.866251e-04 +146 1.460000e+00 1.880849e-04 +147 1.470000e+00 1.895284e-04 +148 1.480000e+00 1.909557e-04 +149 1.490000e+00 1.923672e-04 +150 1.500000e+00 1.937630e-04 +151 0.000000e+00 8.728369e-14 +152 1.000000e-02 1.185890e-13 +153 2.000000e-02 1.696780e-13 +154 3.000000e-02 2.426935e-13 +155 4.000000e-02 3.470095e-13 +156 5.000000e-02 4.959916e-13 +157 6.000000e-02 7.086893e-13 +158 7.000000e-02 1.012243e-12 +159 8.000000e-02 1.445304e-12 +160 9.000000e-02 2.062893e-12 +161 1.000000e-01 2.943304e-12 +162 1.100000e-01 4.197887e-12 +163 1.200000e-01 5.984937e-12 +164 1.300000e-01 8.529367e-12 +165 1.400000e-01 1.215056e-11 +166 1.500000e-01 1.730180e-11 +167 1.600000e-01 2.590033e-11 +168 1.700000e-01 3.683771e-11 +169 1.800000e-01 5.236104e-11 +170 1.900000e-01 7.437674e-11 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +171 2.000000e-01 1.055750e-10 +172 2.100000e-01 1.497472e-10 +173 2.200000e-01 2.122290e-10 +174 2.300000e-01 3.005170e-10 +175 2.400000e-01 4.251248e-10 +176 2.500000e-01 6.007661e-10 +177 2.600000e-01 8.479832e-10 +178 2.700000e-01 1.195378e-09 +179 2.800000e-01 1.682650e-09 +180 2.900000e-01 2.364702e-09 +181 3.000000e-01 3.317155e-09 +182 3.100000e-01 4.643674e-09 +183 3.200000e-01 6.485609e-09 +184 3.300000e-01 9.034525e-09 +185 3.400000e-01 1.254826e-08 +186 3.500000e-01 1.737115e-08 +187 3.600000e-01 2.395917e-08 +188 3.700000e-01 3.291032e-08 +189 3.800000e-01 4.500082e-08 +190 3.900000e-01 6.122707e-08 +191 4.000000e-01 8.285314e-08 +192 4.100000e-01 1.114633e-07 +193 4.200000e-01 1.490193e-07 +194 4.300000e-01 1.979209e-07 +195 4.400000e-01 2.610715e-07 +196 4.500000e-01 3.419474e-07 +197 4.600000e-01 4.446734e-07 +198 4.700000e-01 5.741062e-07 +199 4.800000e-01 7.359242e-07 +200 4.900000e-01 9.367238e-07 +201 5.000000e-01 1.184113e-06 +202 5.100000e-01 1.486791e-06 +203 5.200000e-01 1.854588e-06 +204 5.300000e-01 2.298443e-06 +205 5.400000e-01 2.830278e-06 +206 5.500000e-01 3.462743e-06 +207 5.600000e-01 4.208798e-06 +208 5.700000e-01 5.081108e-06 +209 5.800000e-01 6.091255e-06 +210 5.900000e-01 7.248896e-06 +211 6.000000e-01 8.561544e-06 +212 6.100000e-01 1.003471e-05 +213 6.200000e-01 1.167098e-05 +214 6.300000e-01 1.346937e-05 +215 6.400000e-01 1.542542e-05 +216 6.500000e-01 1.753156e-05 +217 6.600000e-01 1.977766e-05 +218 6.700000e-01 2.215162e-05 +219 6.800000e-01 2.464004e-05 +220 6.900000e-01 2.722881e-05 +221 7.000000e-01 2.990369e-05 +222 7.100000e-01 3.265074e-05 +223 7.200000e-01 3.542938e-05 +224 7.300000e-01 3.828791e-05 +225 7.400000e-01 4.118117e-05 +226 7.500000e-01 4.409900e-05 +227 7.600000e-01 4.703241e-05 +228 7.700000e-01 4.997357e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +229 7.800000e-01 5.291570e-05 +230 7.900000e-01 5.585302e-05 +231 8.000000e-01 5.878062e-05 +232 8.100000e-01 6.169437e-05 +233 8.200000e-01 6.459084e-05 +234 8.300000e-01 6.746719e-05 +235 8.400000e-01 7.032109e-05 +236 8.500000e-01 7.315066e-05 +237 8.600000e-01 7.595438e-05 +238 8.700000e-01 7.873107e-05 +239 8.800000e-01 8.147979e-05 +240 8.900000e-01 8.419984e-05 +241 9.000000e-01 8.689072e-05 +242 9.100000e-01 8.955206e-05 +243 9.200000e-01 9.218364e-05 +244 9.300000e-01 9.478534e-05 +245 9.400000e-01 9.735714e-05 +246 9.500000e-01 9.989908e-05 +247 9.600000e-01 1.024113e-04 +248 9.700000e-01 1.048939e-04 +249 9.800000e-01 1.073471e-04 +250 9.900000e-01 1.097711e-04 +251 1.000000e+00 1.121663e-04 +252 1.010000e+00 1.145328e-04 +253 1.020000e+00 1.168710e-04 +254 1.030000e+00 1.191811e-04 +255 1.040000e+00 1.214636e-04 +256 1.050000e+00 1.237187e-04 +257 1.060000e+00 1.259467e-04 +258 1.070000e+00 1.281481e-04 +259 1.080000e+00 1.303230e-04 +260 1.090000e+00 1.324720e-04 +261 1.100000e+00 1.345952e-04 +262 1.110000e+00 1.366931e-04 +263 1.120000e+00 1.387659e-04 +264 1.130000e+00 1.408141e-04 +265 1.140000e+00 1.428379e-04 +266 1.150000e+00 1.448377e-04 +267 1.160000e+00 1.468137e-04 +268 1.170000e+00 1.487664e-04 +269 1.180000e+00 1.506960e-04 +270 1.190000e+00 1.526028e-04 +271 1.200000e+00 1.544872e-04 +272 1.210000e+00 1.563494e-04 +273 1.220000e+00 1.581898e-04 +274 1.230000e+00 1.600087e-04 +275 1.240000e+00 1.618063e-04 +276 1.250000e+00 1.635829e-04 +277 1.260000e+00 1.653388e-04 +278 1.270000e+00 1.670743e-04 +279 1.280000e+00 1.687897e-04 +280 1.290000e+00 1.704853e-04 +281 1.300000e+00 1.721612e-04 +282 1.310000e+00 1.738178e-04 +283 1.320000e+00 1.754553e-04 +284 1.330000e+00 1.770740e-04 +285 1.340000e+00 1.786742e-04 +286 1.350000e+00 1.802560e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +287 1.360000e+00 1.818197e-04 +288 1.370000e+00 1.833656e-04 +289 1.380000e+00 1.848939e-04 +290 1.390000e+00 1.864048e-04 +291 1.400000e+00 1.878986e-04 +292 1.410000e+00 1.893754e-04 +293 1.420000e+00 1.908356e-04 +294 1.430000e+00 1.922793e-04 +295 1.440000e+00 1.937067e-04 +296 1.450000e+00 1.951180e-04 +297 1.460000e+00 1.965135e-04 +298 1.470000e+00 1.978934e-04 +299 1.480000e+00 1.992578e-04 +300 1.490000e+00 2.006069e-04 +301 1.500000e+00 2.019410e-04 +302 0.000000e+00 2.887436e-13 +303 1.000000e-02 3.931018e-13 +304 2.000000e-02 5.641699e-13 +305 3.000000e-02 8.095897e-13 +306 4.000000e-02 1.161630e-12 +307 5.000000e-02 1.666535e-12 +308 6.000000e-02 2.390439e-12 +309 7.000000e-02 3.427388e-12 +310 8.000000e-02 4.912089e-12 +311 9.000000e-02 7.036995e-12 +312 1.000000e-01 1.007676e-11 +313 1.100000e-01 1.442317e-11 +314 1.200000e-01 2.173201e-11 +315 1.300000e-01 3.107171e-11 +316 1.400000e-01 4.440208e-11 +317 1.500000e-01 6.341614e-11 +318 1.600000e-01 9.051711e-11 +319 1.700000e-01 1.291030e-10 +320 1.800000e-01 1.839867e-10 +321 1.900000e-01 2.619706e-10 +322 2.000000e-01 3.726502e-10 +323 2.100000e-01 5.295336e-10 +324 2.200000e-01 7.515928e-10 +325 2.300000e-01 1.065404e-09 +326 2.400000e-01 1.508086e-09 +327 2.500000e-01 2.131297e-09 +328 2.600000e-01 3.006656e-09 +329 2.700000e-01 4.233000e-09 +330 2.800000e-01 5.946025e-09 +331 2.900000e-01 8.330945e-09 +332 3.000000e-01 1.163887e-08 +333 3.100000e-01 1.620772e-08 +334 3.200000e-01 2.248837e-08 +335 3.300000e-01 3.107690e-08 +336 3.400000e-01 4.275325e-08 +337 3.500000e-01 5.852676e-08 +338 3.600000e-01 7.968840e-08 +339 3.700000e-01 1.078692e-07 +340 3.800000e-01 1.451046e-07 +341 3.900000e-01 1.939032e-07 +342 4.000000e-01 2.573212e-07 +343 4.100000e-01 3.390415e-07 +344 4.200000e-01 4.434590e-07 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +345 4.300000e-01 5.757735e-07 +346 4.400000e-01 7.420905e-07 +347 4.500000e-01 9.495256e-07 +348 4.600000e-01 1.206306e-06 +349 4.700000e-01 1.521853e-06 +350 4.800000e-01 1.906814e-06 +351 4.900000e-01 2.373019e-06 +352 5.000000e-01 2.933310e-06 +353 5.100000e-01 3.601183e-06 +354 5.200000e-01 4.390191e-06 +355 5.300000e-01 5.312956e-06 +356 5.400000e-01 6.379594e-06 +357 5.500000e-01 7.596206e-06 +358 5.600000e-01 8.967049e-06 +359 5.700000e-01 1.049743e-05 +360 5.800000e-01 1.219063e-05 +361 5.900000e-01 1.404581e-05 +362 6.000000e-01 1.605825e-05 +363 6.100000e-01 1.822001e-05 +364 6.200000e-01 2.052060e-05 +365 6.300000e-01 2.294763e-05 +366 6.400000e-01 2.548749e-05 +367 6.500000e-01 2.812594e-05 +368 6.600000e-01 3.084868e-05 +369 6.700000e-01 3.360889e-05 +370 6.800000e-01 3.646564e-05 +371 6.900000e-01 3.936677e-05 +372 7.000000e-01 4.230101e-05 +373 7.100000e-01 4.525831e-05 +374 7.200000e-01 4.822978e-05 +375 7.300000e-01 5.120765e-05 +376 7.400000e-01 5.418523e-05 +377 7.500000e-01 5.715681e-05 +378 7.600000e-01 6.011753e-05 +379 7.700000e-01 6.306333e-05 +380 7.800000e-01 6.599083e-05 +381 7.900000e-01 6.889722e-05 +382 8.000000e-01 7.178022e-05 +383 8.100000e-01 7.463797e-05 +384 8.200000e-01 7.746900e-05 +385 8.300000e-01 8.027214e-05 +386 8.400000e-01 8.304649e-05 +387 8.500000e-01 8.579138e-05 +388 8.600000e-01 8.850631e-05 +389 8.700000e-01 9.119096e-05 +390 8.800000e-01 9.384511e-05 +391 8.900000e-01 9.646867e-05 +392 9.000000e-01 9.906164e-05 +393 9.100000e-01 1.016241e-04 +394 9.200000e-01 1.041561e-04 +395 9.300000e-01 1.066579e-04 +396 9.400000e-01 1.091297e-04 +397 9.500000e-01 1.115717e-04 +398 9.600000e-01 1.139842e-04 +399 9.700000e-01 1.163676e-04 +400 9.800000e-01 1.187220e-04 +401 9.900000e-01 1.210479e-04 +402 1.000000e+00 1.233455e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +403 1.010000e+00 1.256153e-04 +404 1.020000e+00 1.278575e-04 +405 1.030000e+00 1.300725e-04 +406 1.040000e+00 1.322606e-04 +407 1.050000e+00 1.344223e-04 +408 1.060000e+00 1.365578e-04 +409 1.070000e+00 1.386675e-04 +410 1.080000e+00 1.407518e-04 +411 1.090000e+00 1.428109e-04 +412 1.100000e+00 1.448453e-04 +413 1.110000e+00 1.468553e-04 +414 1.120000e+00 1.488412e-04 +415 1.130000e+00 1.508032e-04 +416 1.140000e+00 1.527419e-04 +417 1.150000e+00 1.546574e-04 +418 1.160000e+00 1.565502e-04 +419 1.170000e+00 1.584204e-04 +420 1.180000e+00 1.602685e-04 +421 1.190000e+00 1.620947e-04 +422 1.200000e+00 1.638994e-04 +423 1.210000e+00 1.656827e-04 +424 1.220000e+00 1.674451e-04 +425 1.230000e+00 1.691868e-04 +426 1.240000e+00 1.709080e-04 +427 1.250000e+00 1.726091e-04 +428 1.260000e+00 1.742904e-04 +429 1.270000e+00 1.759520e-04 +430 1.280000e+00 1.775944e-04 +431 1.290000e+00 1.792176e-04 +432 1.300000e+00 1.808221e-04 +433 1.310000e+00 1.824079e-04 +434 1.320000e+00 1.839755e-04 +435 1.330000e+00 1.855250e-04 +436 1.340000e+00 1.870567e-04 +437 1.350000e+00 1.885708e-04 +438 1.360000e+00 1.900676e-04 +439 1.370000e+00 1.915472e-04 +440 1.380000e+00 1.930099e-04 +441 1.390000e+00 1.944559e-04 +442 1.400000e+00 1.958855e-04 +443 1.410000e+00 1.972989e-04 +444 1.420000e+00 1.986962e-04 +445 1.430000e+00 2.000777e-04 +446 1.440000e+00 2.014435e-04 +447 1.450000e+00 2.027940e-04 +448 1.460000e+00 2.041292e-04 +449 1.470000e+00 2.054495e-04 +450 1.480000e+00 2.067549e-04 +451 1.490000e+00 2.080456e-04 +452 1.500000e+00 2.093219e-04 +453 0.000000e+00 9.877774e-13 +454 1.000000e-02 1.344554e-12 +455 2.000000e-02 1.929166e-12 +456 3.000000e-02 2.767567e-12 +457 4.000000e-02 3.969726e-12 +458 5.000000e-02 5.693138e-12 +459 6.000000e-02 8.163313e-12 +460 7.000000e-02 1.170302e-11 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +461 8.000000e-02 1.677409e-11 +462 9.000000e-02 2.532864e-11 +463 1.000000e-01 3.628335e-11 +464 1.100000e-01 5.196066e-11 +465 1.200000e-01 7.438710e-11 +466 1.300000e-01 1.064528e-10 +467 1.400000e-01 1.522756e-10 +468 1.500000e-01 2.177161e-10 +469 1.600000e-01 3.110992e-10 +470 1.700000e-01 4.442001e-10 +471 1.800000e-01 6.336941e-10 +472 1.900000e-01 9.031304e-10 +473 2.000000e-01 1.285674e-09 +474 2.100000e-01 1.827892e-09 +475 2.200000e-01 2.594944e-09 +476 2.300000e-01 3.677637e-09 +477 2.400000e-01 5.201872e-09 +478 2.500000e-01 7.340609e-09 +479 2.600000e-01 1.033002e-08 +480 2.700000e-01 1.449134e-08 +481 2.800000e-01 2.025755e-08 +482 2.900000e-01 2.820684e-08 +483 3.000000e-01 3.910366e-08 +484 3.100000e-01 5.394782e-08 +485 3.200000e-01 7.403175e-08 +486 3.300000e-01 1.010058e-07 +487 3.400000e-01 1.369511e-07 +488 3.500000e-01 1.844586e-07 +489 3.600000e-01 2.467149e-07 +490 3.700000e-01 3.275944e-07 +491 3.800000e-01 4.317573e-07 +492 3.900000e-01 5.647567e-07 +493 4.000000e-01 7.331521e-07 +494 4.100000e-01 9.446282e-07 +495 4.200000e-01 1.208106e-06 +496 4.300000e-01 1.533833e-06 +497 4.400000e-01 1.933408e-06 +498 4.500000e-01 2.419717e-06 +499 4.600000e-01 3.006693e-06 +500 4.700000e-01 3.708835e-06 +501 4.800000e-01 4.540337e-06 +502 4.900000e-01 5.513507e-06 +503 5.000000e-01 6.636007e-06 +504 5.100000e-01 7.908968e-06 +505 5.200000e-01 9.333435e-06 +506 5.300000e-01 1.091545e-05 +507 5.400000e-01 1.265940e-05 +508 5.500000e-01 1.456477e-05 +509 5.600000e-01 1.662676e-05 +510 5.700000e-01 1.883722e-05 +511 5.800000e-01 2.118542e-05 +512 5.900000e-01 2.365882e-05 +513 6.000000e-01 2.624370e-05 +514 6.100000e-01 2.892577e-05 +515 6.200000e-01 3.169074e-05 +516 6.300000e-01 3.449249e-05 +517 6.400000e-01 3.738877e-05 +518 6.500000e-01 4.032818e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +519 6.600000e-01 4.329953e-05 +520 6.700000e-01 4.629284e-05 +521 6.800000e-01 4.929925e-05 +522 6.900000e-01 5.231108e-05 +523 7.000000e-01 5.532167e-05 +524 7.100000e-01 5.832533e-05 +525 7.200000e-01 6.131726e-05 +526 7.300000e-01 6.429341e-05 +527 7.400000e-01 6.725040e-05 +528 7.500000e-01 7.018548e-05 +529 7.600000e-01 7.309635e-05 +530 7.700000e-01 7.598120e-05 +531 7.800000e-01 7.883855e-05 +532 7.900000e-01 8.166725e-05 +533 8.000000e-01 8.446643e-05 +534 8.100000e-01 8.723541e-05 +535 8.200000e-01 8.997372e-05 +536 8.300000e-01 9.268104e-05 +537 8.400000e-01 9.535719e-05 +538 8.500000e-01 9.800208e-05 +539 8.600000e-01 1.006157e-04 +540 8.700000e-01 1.031982e-04 +541 8.800000e-01 1.057496e-04 +542 8.900000e-01 1.082702e-04 +543 9.000000e-01 1.107602e-04 +544 9.100000e-01 1.132198e-04 +545 9.200000e-01 1.156494e-04 +546 9.300000e-01 1.180492e-04 +547 9.400000e-01 1.204196e-04 +548 9.500000e-01 1.227609e-04 +549 9.600000e-01 1.250734e-04 +550 9.700000e-01 1.273576e-04 +551 9.800000e-01 1.296137e-04 +552 9.900000e-01 1.318421e-04 +553 1.000000e+00 1.340433e-04 +554 1.010000e+00 1.362175e-04 +555 1.020000e+00 1.383651e-04 +556 1.030000e+00 1.404865e-04 +557 1.040000e+00 1.425820e-04 +558 1.050000e+00 1.446520e-04 +559 1.060000e+00 1.466968e-04 +560 1.070000e+00 1.487168e-04 +561 1.080000e+00 1.507124e-04 +562 1.090000e+00 1.526838e-04 +563 1.100000e+00 1.546314e-04 +564 1.110000e+00 1.565556e-04 +565 1.120000e+00 1.584566e-04 +566 1.130000e+00 1.603348e-04 +567 1.140000e+00 1.621905e-04 +568 1.150000e+00 1.640240e-04 +569 1.160000e+00 1.658356e-04 +570 1.170000e+00 1.676257e-04 +571 1.180000e+00 1.693945e-04 +572 1.190000e+00 1.711423e-04 +573 1.200000e+00 1.728694e-04 +574 1.210000e+00 1.745761e-04 +575 1.220000e+00 1.762627e-04 +576 1.230000e+00 1.779294e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +577 1.240000e+00 1.795766e-04 +578 1.250000e+00 1.812044e-04 +579 1.260000e+00 1.828132e-04 +580 1.270000e+00 1.844032e-04 +581 1.280000e+00 1.859747e-04 +582 1.290000e+00 1.875278e-04 +583 1.300000e+00 1.890630e-04 +584 1.310000e+00 1.905803e-04 +585 1.320000e+00 1.920801e-04 +586 1.330000e+00 1.935626e-04 +587 1.340000e+00 1.950279e-04 +588 1.350000e+00 1.964764e-04 +589 1.360000e+00 1.979083e-04 +590 1.370000e+00 1.993237e-04 +591 1.380000e+00 2.007230e-04 +592 1.390000e+00 2.021062e-04 +593 1.400000e+00 2.034737e-04 +594 1.410000e+00 2.048256e-04 +595 1.420000e+00 2.061621e-04 +596 1.430000e+00 2.074834e-04 +597 1.440000e+00 2.087898e-04 +598 1.450000e+00 2.100814e-04 +599 1.460000e+00 2.113584e-04 +600 1.470000e+00 2.126210e-04 +601 1.480000e+00 2.138693e-04 +602 1.490000e+00 2.151037e-04 +603 1.500000e+00 2.163241e-04 +604 0.000000e+00 3.802857e-12 +605 1.000000e-02 5.179405e-12 +606 2.000000e-02 7.436916e-12 +607 3.000000e-02 1.067638e-11 +608 4.000000e-02 1.532378e-11 +609 5.000000e-02 2.317943e-11 +610 6.000000e-02 3.325101e-11 +611 7.000000e-02 4.768511e-11 +612 8.000000e-02 6.836303e-11 +613 9.000000e-02 9.797210e-11 +614 1.000000e-01 1.403476e-10 +615 1.100000e-01 2.009572e-10 +616 1.200000e-01 2.875868e-10 +617 1.300000e-01 4.113064e-10 +618 1.400000e-01 5.878303e-10 +619 1.500000e-01 8.394210e-10 +620 1.600000e-01 1.197526e-09 +621 1.700000e-01 1.706327e-09 +622 1.800000e-01 2.427883e-09 +623 1.900000e-01 3.448995e-09 +624 2.000000e-01 4.890513e-09 +625 2.100000e-01 6.919840e-09 +626 2.200000e-01 9.767530e-09 +627 2.300000e-01 1.374902e-08 +628 2.400000e-01 1.929264e-08 +629 2.500000e-01 2.697515e-08 +630 2.600000e-01 3.756591e-08 +631 2.700000e-01 5.208067e-08 +632 2.800000e-01 7.184554e-08 +633 2.900000e-01 9.857148e-08 +634 3.000000e-01 1.344389e-07 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +635 3.100000e-01 1.821917e-07 +636 3.200000e-01 2.452412e-07 +637 3.300000e-01 3.277779e-07 +638 3.400000e-01 4.348938e-07 +639 3.500000e-01 5.727141e-07 +640 3.600000e-01 7.485378e-07 +641 3.700000e-01 9.709820e-07 +642 3.800000e-01 1.250117e-06 +643 3.900000e-01 1.597567e-06 +644 4.000000e-01 2.026526e-06 +645 4.100000e-01 2.551636e-06 +646 4.200000e-01 3.188614e-06 +647 4.300000e-01 3.953476e-06 +648 4.400000e-01 4.861015e-06 +649 4.500000e-01 5.921696e-06 +650 4.600000e-01 7.136545e-06 +651 4.700000e-01 8.498437e-06 +652 4.800000e-01 1.000774e-05 +653 4.900000e-01 1.167295e-05 +654 5.000000e-01 1.349892e-05 +655 5.100000e-01 1.548464e-05 +656 5.200000e-01 1.762458e-05 +657 5.300000e-01 1.990991e-05 +658 5.400000e-01 2.232939e-05 +659 5.500000e-01 2.487011e-05 +660 5.600000e-01 2.751817e-05 +661 5.700000e-01 3.025929e-05 +662 5.800000e-01 3.307926e-05 +663 5.900000e-01 3.593405e-05 +664 6.000000e-01 3.887775e-05 +665 6.100000e-01 4.186125e-05 +666 6.200000e-01 4.487369e-05 +667 6.300000e-01 4.790535e-05 +668 6.400000e-01 5.094767e-05 +669 6.500000e-01 5.399320e-05 +670 6.600000e-01 5.703551e-05 +671 6.700000e-01 6.006913e-05 +672 6.800000e-01 6.308940e-05 +673 6.900000e-01 6.609245e-05 +674 7.000000e-01 6.907502e-05 +675 7.100000e-01 7.203445e-05 +676 7.200000e-01 7.496857e-05 +677 7.300000e-01 7.787563e-05 +678 7.400000e-01 8.075423e-05 +679 7.500000e-01 8.360329e-05 +680 7.600000e-01 8.642197e-05 +681 7.700000e-01 8.920966e-05 +682 7.800000e-01 9.196592e-05 +683 7.900000e-01 9.469048e-05 +684 8.000000e-01 9.738318e-05 +685 8.100000e-01 1.000440e-04 +686 8.200000e-01 1.026729e-04 +687 8.300000e-01 1.052700e-04 +688 8.400000e-01 1.078355e-04 +689 8.500000e-01 1.103696e-04 +690 8.600000e-01 1.128726e-04 +691 8.700000e-01 1.153446e-04 +692 8.800000e-01 1.177862e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +693 8.900000e-01 1.201975e-04 +694 9.000000e-01 1.225789e-04 +695 9.100000e-01 1.249307e-04 +696 9.200000e-01 1.272534e-04 +697 9.300000e-01 1.295472e-04 +698 9.400000e-01 1.318126e-04 +699 9.500000e-01 1.340500e-04 +700 9.600000e-01 1.362596e-04 +701 9.700000e-01 1.384419e-04 +702 9.800000e-01 1.405972e-04 +703 9.900000e-01 1.427260e-04 +704 1.000000e+00 1.448286e-04 +705 1.010000e+00 1.469053e-04 +706 1.020000e+00 1.489565e-04 +707 1.030000e+00 1.509825e-04 +708 1.040000e+00 1.529838e-04 +709 1.050000e+00 1.549607e-04 +710 1.060000e+00 1.569135e-04 +711 1.070000e+00 1.588425e-04 +712 1.080000e+00 1.607482e-04 +713 1.090000e+00 1.626307e-04 +714 1.100000e+00 1.644905e-04 +715 1.110000e+00 1.663278e-04 +716 1.120000e+00 1.681431e-04 +717 1.130000e+00 1.699365e-04 +718 1.140000e+00 1.717084e-04 +719 1.150000e+00 1.734591e-04 +720 1.160000e+00 1.751888e-04 +721 1.170000e+00 1.768980e-04 +722 1.180000e+00 1.785868e-04 +723 1.190000e+00 1.802556e-04 +724 1.200000e+00 1.819046e-04 +725 1.210000e+00 1.835341e-04 +726 1.220000e+00 1.851443e-04 +727 1.230000e+00 1.867356e-04 +728 1.240000e+00 1.883082e-04 +729 1.250000e+00 1.898623e-04 +730 1.260000e+00 1.913982e-04 +731 1.270000e+00 1.929161e-04 +732 1.280000e+00 1.944163e-04 +733 1.290000e+00 1.958991e-04 +734 1.300000e+00 1.973646e-04 +735 1.310000e+00 1.988131e-04 +736 1.320000e+00 2.002448e-04 +737 1.330000e+00 2.016600e-04 +738 1.340000e+00 2.030588e-04 +739 1.350000e+00 2.044415e-04 +740 1.360000e+00 2.058082e-04 +741 1.370000e+00 2.071593e-04 +742 1.380000e+00 2.084949e-04 +743 1.390000e+00 2.098152e-04 +744 1.400000e+00 2.111204e-04 +745 1.410000e+00 2.124107e-04 +746 1.420000e+00 2.136863e-04 +747 1.430000e+00 2.149474e-04 +748 1.440000e+00 2.161942e-04 +749 1.450000e+00 2.174268e-04 +750 1.460000e+00 2.186455e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +751 1.470000e+00 2.198504e-04 +752 1.480000e+00 2.210417e-04 +753 1.490000e+00 2.222196e-04 +754 1.500000e+00 2.233842e-04 +755 0.000000e+00 1.825247e-11 +756 1.000000e-02 2.627973e-11 +757 2.000000e-02 3.782706e-11 +758 3.000000e-02 5.443185e-11 +759 4.000000e-02 7.829900e-11 +760 5.000000e-02 1.125882e-10 +761 6.000000e-02 1.618231e-10 +762 7.000000e-02 2.324729e-10 +763 8.000000e-02 3.337774e-10 +764 9.000000e-02 4.789138e-10 +765 1.000000e-01 6.866413e-10 +766 1.100000e-01 9.836112e-10 +767 1.200000e-01 1.407596e-09 +768 1.300000e-01 2.011981e-09 +769 1.400000e-01 2.871967e-09 +770 1.500000e-01 4.093086e-09 +771 1.600000e-01 5.822686e-09 +772 1.700000e-01 8.264853e-09 +773 1.800000e-01 1.170150e-08 +774 1.900000e-01 1.651914e-08 +775 2.000000e-01 2.324352e-08 +776 2.100000e-01 3.258355e-08 +777 2.200000e-01 4.548595e-08 +778 2.300000e-01 6.320174e-08 +779 2.400000e-01 8.736539e-08 +780 2.500000e-01 1.200869e-07 +781 2.600000e-01 1.640566e-07 +782 2.700000e-01 2.226621e-07 +783 2.800000e-01 3.001177e-07 +784 2.900000e-01 4.016046e-07 +785 3.000000e-01 5.334234e-07 +786 3.100000e-01 7.031560e-07 +787 3.200000e-01 9.198327e-07 +788 3.300000e-01 1.194089e-06 +789 3.400000e-01 1.538284e-06 +790 3.500000e-01 1.966529e-06 +791 3.600000e-01 2.494560e-06 +792 3.700000e-01 3.139647e-06 +793 3.800000e-01 3.919324e-06 +794 3.900000e-01 4.849285e-06 +795 4.000000e-01 5.939502e-06 +796 4.100000e-01 7.187440e-06 +797 4.200000e-01 8.579616e-06 +798 4.300000e-01 1.011389e-05 +799 4.400000e-01 1.180075e-05 +800 4.500000e-01 1.364700e-05 +801 4.600000e-01 1.565274e-05 +802 4.700000e-01 1.781303e-05 +803 4.800000e-01 2.011946e-05 +804 4.900000e-01 2.256106e-05 +805 5.000000e-01 2.512513e-05 +806 5.100000e-01 2.779796e-05 +807 5.200000e-01 3.056533e-05 +808 5.300000e-01 3.341311e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +809 5.400000e-01 3.629646e-05 +810 5.500000e-01 3.927099e-05 +811 5.600000e-01 4.228672e-05 +812 5.700000e-01 4.533260e-05 +813 5.800000e-01 4.839878e-05 +814 5.900000e-01 5.147652e-05 +815 6.000000e-01 5.455818e-05 +816 6.100000e-01 5.763716e-05 +817 6.200000e-01 6.070781e-05 +818 6.300000e-01 6.376532e-05 +819 6.400000e-01 6.680567e-05 +820 6.500000e-01 6.982547e-05 +821 6.600000e-01 7.282195e-05 +822 6.700000e-01 7.579283e-05 +823 6.800000e-01 7.873628e-05 +824 6.900000e-01 8.165083e-05 +825 7.000000e-01 8.453533e-05 +826 7.100000e-01 8.738891e-05 +827 7.200000e-01 9.021090e-05 +828 7.300000e-01 9.300084e-05 +829 7.400000e-01 9.575843e-05 +830 7.500000e-01 9.848349e-05 +831 7.600000e-01 1.011760e-04 +832 7.700000e-01 1.038359e-04 +833 7.800000e-01 1.064633e-04 +834 7.900000e-01 1.090585e-04 +835 8.000000e-01 1.116216e-04 +836 8.100000e-01 1.141528e-04 +837 8.200000e-01 1.166525e-04 +838 8.300000e-01 1.191210e-04 +839 8.400000e-01 1.215586e-04 +840 8.500000e-01 1.239657e-04 +841 8.600000e-01 1.263426e-04 +842 8.700000e-01 1.286897e-04 +843 8.800000e-01 1.310074e-04 +844 8.900000e-01 1.332960e-04 +845 9.000000e-01 1.355560e-04 +846 9.100000e-01 1.377877e-04 +847 9.200000e-01 1.399915e-04 +848 9.300000e-01 1.421679e-04 +849 9.400000e-01 1.443171e-04 +850 9.500000e-01 1.464396e-04 +851 9.600000e-01 1.485357e-04 +852 9.700000e-01 1.506058e-04 +853 9.800000e-01 1.526503e-04 +854 9.900000e-01 1.546696e-04 +855 1.000000e+00 1.566640e-04 +856 1.010000e+00 1.586338e-04 +857 1.020000e+00 1.605794e-04 +858 1.030000e+00 1.625012e-04 +859 1.040000e+00 1.643995e-04 +860 1.050000e+00 1.662746e-04 +861 1.060000e+00 1.681269e-04 +862 1.070000e+00 1.699566e-04 +863 1.080000e+00 1.717642e-04 +864 1.090000e+00 1.735498e-04 +865 1.100000e+00 1.753139e-04 +866 1.110000e+00 1.770567e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +867 1.120000e+00 1.787785e-04 +868 1.130000e+00 1.804797e-04 +869 1.140000e+00 1.821605e-04 +870 1.150000e+00 1.838211e-04 +871 1.160000e+00 1.854620e-04 +872 1.170000e+00 1.870832e-04 +873 1.180000e+00 1.886852e-04 +874 1.190000e+00 1.902682e-04 +875 1.200000e+00 1.918325e-04 +876 1.210000e+00 1.933782e-04 +877 1.220000e+00 1.949057e-04 +878 1.230000e+00 1.964152e-04 +879 1.240000e+00 1.979070e-04 +880 1.250000e+00 1.993812e-04 +881 1.260000e+00 2.008382e-04 +882 1.270000e+00 2.022781e-04 +883 1.280000e+00 2.037013e-04 +884 1.290000e+00 2.051078e-04 +885 1.300000e+00 2.064980e-04 +886 1.310000e+00 2.078721e-04 +887 1.320000e+00 2.092302e-04 +888 1.330000e+00 2.105726e-04 +889 1.340000e+00 2.118995e-04 +890 1.350000e+00 2.132111e-04 +891 1.360000e+00 2.145076e-04 +892 1.370000e+00 2.157892e-04 +893 1.380000e+00 2.170561e-04 +894 1.390000e+00 2.183085e-04 +895 1.400000e+00 2.195465e-04 +896 1.410000e+00 2.207704e-04 +897 1.420000e+00 2.219803e-04 +898 1.430000e+00 2.231765e-04 +899 1.440000e+00 2.243590e-04 +900 1.450000e+00 2.255282e-04 +901 1.460000e+00 2.266840e-04 +902 1.470000e+00 2.278268e-04 +903 1.480000e+00 2.289566e-04 +904 1.490000e+00 2.300737e-04 +905 1.500000e+00 2.311782e-04 +906 0.000000e+00 1.258752e-10 +907 1.000000e-02 1.823407e-10 +908 2.000000e-02 2.639900e-10 +909 3.000000e-02 3.819525e-10 +910 4.000000e-02 5.522071e-10 +911 5.000000e-02 7.976497e-10 +912 6.000000e-02 1.151011e-09 +913 7.000000e-02 1.658958e-09 +914 8.000000e-02 2.387814e-09 +915 9.000000e-02 3.431510e-09 +916 1.000000e-01 4.922511e-09 +917 1.100000e-01 7.046734e-09 +918 1.200000e-01 1.006368e-08 +919 1.300000e-01 1.433325e-08 +920 1.400000e-01 2.035107e-08 +921 1.500000e-01 2.879411e-08 +922 1.600000e-01 4.057812e-08 +923 1.700000e-01 5.692562e-08 +924 1.800000e-01 7.945695e-08 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +925 1.900000e-01 1.102933e-07 +926 2.000000e-01 1.521772e-07 +927 2.100000e-01 2.086101e-07 +928 2.200000e-01 2.840068e-07 +929 2.300000e-01 3.838663e-07 +930 2.400000e-01 5.149567e-07 +931 2.500000e-01 6.855130e-07 +932 2.600000e-01 9.054375e-07 +933 2.700000e-01 1.186486e-06 +934 2.800000e-01 1.542398e-06 +935 2.900000e-01 1.988913e-06 +936 3.000000e-01 2.543547e-06 +937 3.100000e-01 3.224972e-06 +938 3.200000e-01 4.051625e-06 +939 3.300000e-01 5.038769e-06 +940 3.400000e-01 6.192279e-06 +941 3.500000e-01 7.500371e-06 +942 3.600000e-01 8.944384e-06 +943 3.700000e-01 1.052707e-05 +944 3.800000e-01 1.226188e-05 +945 3.900000e-01 1.415578e-05 +946 4.000000e-01 1.620858e-05 +947 4.100000e-01 1.841513e-05 +948 4.200000e-01 2.076690e-05 +949 4.300000e-01 2.325291e-05 +950 4.400000e-01 2.586055e-05 +951 4.500000e-01 2.857620e-05 +952 4.600000e-01 3.138583e-05 +953 4.700000e-01 3.427546e-05 +954 4.800000e-01 3.720050e-05 +955 4.900000e-01 4.021642e-05 +956 5.000000e-01 4.327347e-05 +957 5.100000e-01 4.636069e-05 +958 5.200000e-01 4.946821e-05 +959 5.300000e-01 5.258728e-05 +960 5.400000e-01 5.571023e-05 +961 5.500000e-01 5.883040e-05 +962 5.600000e-01 6.194206e-05 +963 5.700000e-01 6.504034e-05 +964 5.800000e-01 6.812113e-05 +965 5.900000e-01 7.118099e-05 +966 6.000000e-01 7.421707e-05 +967 6.100000e-01 7.722703e-05 +968 6.200000e-01 8.020898e-05 +969 6.300000e-01 8.316142e-05 +970 6.400000e-01 8.608316e-05 +971 6.500000e-01 8.897328e-05 +972 6.600000e-01 9.183111e-05 +973 6.700000e-01 9.465617e-05 +974 6.800000e-01 9.744813e-05 +975 6.900000e-01 1.002068e-04 +976 7.000000e-01 1.029322e-04 +977 7.100000e-01 1.056242e-04 +978 7.200000e-01 1.082830e-04 +979 7.300000e-01 1.109088e-04 +980 7.400000e-01 1.135018e-04 +981 7.500000e-01 1.160622e-04 +982 7.600000e-01 1.185904e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +983 7.700000e-01 1.210867e-04 +984 7.800000e-01 1.235514e-04 +985 7.900000e-01 1.259848e-04 +986 8.000000e-01 1.283875e-04 +987 8.100000e-01 1.307597e-04 +988 8.200000e-01 1.331018e-04 +989 8.300000e-01 1.354143e-04 +990 8.400000e-01 1.376975e-04 +991 8.500000e-01 1.399519e-04 +992 8.600000e-01 1.421778e-04 +993 8.700000e-01 1.443756e-04 +994 8.800000e-01 1.465458e-04 +995 8.900000e-01 1.486887e-04 +996 9.000000e-01 1.508047e-04 +997 9.100000e-01 1.528943e-04 +998 9.200000e-01 1.549577e-04 +999 9.300000e-01 1.569953e-04 +1000 9.400000e-01 1.590076e-04 +1001 9.500000e-01 1.609949e-04 +1002 9.600000e-01 1.629576e-04 +1003 9.700000e-01 1.648959e-04 +1004 9.800000e-01 1.668104e-04 +1005 9.900000e-01 1.687012e-04 +1006 1.000000e+00 1.705688e-04 +1007 1.010000e+00 1.724134e-04 +1008 1.020000e+00 1.742355e-04 +1009 1.030000e+00 1.760352e-04 +1010 1.040000e+00 1.778131e-04 +1011 1.050000e+00 1.795692e-04 +1012 1.060000e+00 1.813041e-04 +1013 1.070000e+00 1.830179e-04 +1014 1.080000e+00 1.847110e-04 +1015 1.090000e+00 1.863836e-04 +1016 1.100000e+00 1.880361e-04 +1017 1.110000e+00 1.896687e-04 +1018 1.120000e+00 1.912818e-04 +1019 1.130000e+00 1.928754e-04 +1020 1.140000e+00 1.944501e-04 +1021 1.150000e+00 1.960059e-04 +1022 1.160000e+00 1.975433e-04 +1023 1.170000e+00 1.990623e-04 +1024 1.180000e+00 2.005633e-04 +1025 1.190000e+00 2.020466e-04 +1026 1.200000e+00 2.035123e-04 +1027 1.210000e+00 2.049607e-04 +1028 1.220000e+00 2.063921e-04 +1029 1.230000e+00 2.078066e-04 +1030 1.240000e+00 2.092045e-04 +1031 1.250000e+00 2.105860e-04 +1032 1.260000e+00 2.119514e-04 +1033 1.270000e+00 2.133009e-04 +1034 1.280000e+00 2.146346e-04 +1035 1.290000e+00 2.159528e-04 +1036 1.300000e+00 2.172556e-04 +1037 1.310000e+00 2.185434e-04 +1038 1.320000e+00 2.198162e-04 +1039 1.330000e+00 2.210744e-04 +1040 1.340000e+00 2.223180e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1041 1.350000e+00 2.235472e-04 +1042 1.360000e+00 2.247623e-04 +1043 1.370000e+00 2.259635e-04 +1044 1.380000e+00 2.271508e-04 +1045 1.390000e+00 2.283246e-04 +1046 1.400000e+00 2.294849e-04 +1047 1.410000e+00 2.306319e-04 +1048 1.420000e+00 2.317659e-04 +1049 1.430000e+00 2.328869e-04 +1050 1.440000e+00 2.339952e-04 +1051 1.450000e+00 2.350909e-04 +1052 1.460000e+00 2.361741e-04 +1053 1.470000e+00 2.372451e-04 +1054 1.480000e+00 2.383039e-04 +1055 1.490000e+00 2.393508e-04 +1056 1.500000e+00 2.403858e-04 +1057 0.000000e+00 1.251192e-09 +1058 1.000000e-02 1.813709e-09 +1059 2.000000e-02 2.624757e-09 +1060 3.000000e-02 3.791412e-09 +1061 4.000000e-02 5.465157e-09 +1062 5.000000e-02 7.859239e-09 +1063 6.000000e-02 1.127214e-08 +1064 7.000000e-02 1.611896e-08 +1065 8.000000e-02 2.297285e-08 +1066 9.000000e-02 3.261873e-08 +1067 1.000000e-01 4.612204e-08 +1068 1.100000e-01 6.491486e-08 +1069 1.200000e-01 9.090182e-08 +1070 1.300000e-01 1.265877e-07 +1071 1.400000e-01 1.752284e-07 +1072 1.500000e-01 2.410054e-07 +1073 1.600000e-01 3.292206e-07 +1074 1.700000e-01 4.464887e-07 +1075 1.800000e-01 6.010065e-07 +1076 1.900000e-01 8.027946e-07 +1077 2.000000e-01 1.063932e-06 +1078 2.100000e-01 1.398741e-06 +1079 2.200000e-01 1.823838e-06 +1080 2.300000e-01 2.357916e-06 +1081 2.400000e-01 3.021002e-06 +1082 2.500000e-01 3.832660e-06 +1083 2.600000e-01 4.807913e-06 +1084 2.700000e-01 5.948551e-06 +1085 2.800000e-01 7.234720e-06 +1086 2.900000e-01 8.646884e-06 +1087 3.000000e-01 1.019402e-05 +1088 3.100000e-01 1.189245e-05 +1089 3.200000e-01 1.375032e-05 +1090 3.300000e-01 1.576849e-05 +1091 3.400000e-01 1.794291e-05 +1092 3.500000e-01 2.026608e-05 +1093 3.600000e-01 2.272796e-05 +1094 3.700000e-01 2.531672e-05 +1095 3.800000e-01 2.801933e-05 +1096 3.900000e-01 3.082218e-05 +1097 4.000000e-01 3.371147e-05 +1098 4.100000e-01 3.663943e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1099 4.200000e-01 3.966790e-05 +1100 4.300000e-01 4.274360e-05 +1101 4.400000e-01 4.585514e-05 +1102 4.500000e-01 4.899215e-05 +1103 4.600000e-01 5.214534e-05 +1104 4.700000e-01 5.530647e-05 +1105 4.800000e-01 5.846830e-05 +1106 4.900000e-01 6.162457e-05 +1107 5.000000e-01 6.476986e-05 +1108 5.100000e-01 6.789959e-05 +1109 5.200000e-01 7.100988e-05 +1110 5.300000e-01 7.409748e-05 +1111 5.400000e-01 7.715971e-05 +1112 5.500000e-01 8.019436e-05 +1113 5.600000e-01 8.319966e-05 +1114 5.700000e-01 8.617420e-05 +1115 5.800000e-01 8.911689e-05 +1116 5.900000e-01 9.202687e-05 +1117 6.000000e-01 9.490355e-05 +1118 6.100000e-01 9.774649e-05 +1119 6.200000e-01 1.005554e-04 +1120 6.300000e-01 1.033302e-04 +1121 6.400000e-01 1.060709e-04 +1122 6.500000e-01 1.087775e-04 +1123 6.600000e-01 1.114501e-04 +1124 6.700000e-01 1.140890e-04 +1125 6.800000e-01 1.166944e-04 +1126 6.900000e-01 1.192666e-04 +1127 7.000000e-01 1.218060e-04 +1128 7.100000e-01 1.243128e-04 +1129 7.200000e-01 1.267876e-04 +1130 7.300000e-01 1.292306e-04 +1131 7.400000e-01 1.316423e-04 +1132 7.500000e-01 1.340230e-04 +1133 7.600000e-01 1.363732e-04 +1134 7.700000e-01 1.386934e-04 +1135 7.800000e-01 1.409838e-04 +1136 7.900000e-01 1.432450e-04 +1137 8.000000e-01 1.454774e-04 +1138 8.100000e-01 1.476813e-04 +1139 8.200000e-01 1.498572e-04 +1140 8.300000e-01 1.520055e-04 +1141 8.400000e-01 1.541265e-04 +1142 8.500000e-01 1.562208e-04 +1143 8.600000e-01 1.582886e-04 +1144 8.700000e-01 1.603304e-04 +1145 8.800000e-01 1.623466e-04 +1146 8.900000e-01 1.643374e-04 +1147 9.000000e-01 1.663034e-04 +1148 9.100000e-01 1.682448e-04 +1149 9.200000e-01 1.701621e-04 +1150 9.300000e-01 1.720555e-04 +1151 9.400000e-01 1.739254e-04 +1152 9.500000e-01 1.757722e-04 +1153 9.600000e-01 1.775961e-04 +1154 9.700000e-01 1.793976e-04 +1155 9.800000e-01 1.811770e-04 +1156 9.900000e-01 1.829345e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1157 1.000000e+00 1.846704e-04 +1158 1.010000e+00 1.863852e-04 +1159 1.020000e+00 1.880790e-04 +1160 1.030000e+00 1.897522e-04 +1161 1.040000e+00 1.914051e-04 +1162 1.050000e+00 1.930380e-04 +1163 1.060000e+00 1.946511e-04 +1164 1.070000e+00 1.962448e-04 +1165 1.080000e+00 1.978192e-04 +1166 1.090000e+00 1.993747e-04 +1167 1.100000e+00 2.009115e-04 +1168 1.110000e+00 2.024299e-04 +1169 1.120000e+00 2.039302e-04 +1170 1.130000e+00 2.054125e-04 +1171 1.140000e+00 2.068772e-04 +1172 1.150000e+00 2.083244e-04 +1173 1.160000e+00 2.097545e-04 +1174 1.170000e+00 2.111677e-04 +1175 1.180000e+00 2.125641e-04 +1176 1.190000e+00 2.139440e-04 +1177 1.200000e+00 2.153077e-04 +1178 1.210000e+00 2.166553e-04 +1179 1.220000e+00 2.179870e-04 +1180 1.230000e+00 2.193032e-04 +1181 1.240000e+00 2.206039e-04 +1182 1.250000e+00 2.218895e-04 +1183 1.260000e+00 2.231600e-04 +1184 1.270000e+00 2.244157e-04 +1185 1.280000e+00 2.256568e-04 +1186 1.290000e+00 2.268835e-04 +1187 1.300000e+00 2.280960e-04 +1188 1.310000e+00 2.292944e-04 +1189 1.320000e+00 2.304789e-04 +1190 1.330000e+00 2.316498e-04 +1191 1.340000e+00 2.328071e-04 +1192 1.350000e+00 2.339511e-04 +1193 1.360000e+00 2.350820e-04 +1194 1.370000e+00 2.361998e-04 +1195 1.380000e+00 2.373048e-04 +1196 1.390000e+00 2.383972e-04 +1197 1.400000e+00 2.394771e-04 +1198 1.410000e+00 2.405446e-04 +1199 1.420000e+00 2.415999e-04 +1200 1.430000e+00 2.426432e-04 +1201 1.440000e+00 2.436746e-04 +1202 1.450000e+00 2.446943e-04 +1203 1.460000e+00 2.457024e-04 +1204 1.470000e+00 2.466990e-04 +1205 1.480000e+00 2.476843e-04 +1206 1.490000e+00 2.486585e-04 +1207 1.500000e+00 2.496217e-04 +1208 0.000000e+00 8.743036e-09 +1209 1.000000e-02 1.261676e-08 +1210 2.000000e-02 1.814181e-08 +1211 3.000000e-02 2.598346e-08 +1212 4.000000e-02 3.705280e-08 +1213 5.000000e-02 5.258576e-08 +1214 6.000000e-02 7.424152e-08 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1215 7.000000e-02 1.042231e-07 +1216 8.000000e-02 1.454217e-07 +1217 9.000000e-02 2.015865e-07 +1218 1.000000e-01 2.775194e-07 +1219 1.100000e-01 3.792947e-07 +1220 1.200000e-01 5.144985e-07 +1221 1.300000e-01 6.924777e-07 +1222 1.400000e-01 9.245763e-07 +1223 1.500000e-01 1.224307e-06 +1224 1.600000e-01 1.607340e-06 +1225 1.700000e-01 2.091021e-06 +1226 1.800000e-01 2.693299e-06 +1227 1.900000e-01 3.429510e-06 +1228 2.000000e-01 4.305019e-06 +1229 2.100000e-01 5.307255e-06 +1230 2.200000e-01 6.423287e-06 +1231 2.300000e-01 7.665067e-06 +1232 2.400000e-01 9.051983e-06 +1233 2.500000e-01 1.059674e-05 +1234 2.600000e-01 1.230554e-05 +1235 2.700000e-01 1.417983e-05 +1236 2.800000e-01 1.621724e-05 +1237 2.900000e-01 1.841222e-05 +1238 3.000000e-01 2.075660e-05 +1239 3.100000e-01 2.324009e-05 +1240 3.200000e-01 2.585087e-05 +1241 3.300000e-01 2.857605e-05 +1242 3.400000e-01 3.140217e-05 +1243 3.500000e-01 3.431565e-05 +1244 3.600000e-01 3.726830e-05 +1245 3.700000e-01 4.032314e-05 +1246 3.800000e-01 4.342646e-05 +1247 3.900000e-01 4.656687e-05 +1248 4.000000e-01 4.973393e-05 +1249 4.100000e-01 5.291824e-05 +1250 4.200000e-01 5.611139e-05 +1251 4.300000e-01 5.930598e-05 +1252 4.400000e-01 6.249555e-05 +1253 4.500000e-01 6.567448e-05 +1254 4.600000e-01 6.883800e-05 +1255 4.700000e-01 7.198204e-05 +1256 4.800000e-01 7.510317e-05 +1257 4.900000e-01 7.819856e-05 +1258 5.000000e-01 8.126587e-05 +1259 5.100000e-01 8.430322e-05 +1260 5.200000e-01 8.730910e-05 +1261 5.300000e-01 9.028233e-05 +1262 5.400000e-01 9.322201e-05 +1263 5.500000e-01 9.612748e-05 +1264 5.600000e-01 9.899830e-05 +1265 5.700000e-01 1.018342e-04 +1266 5.800000e-01 1.046350e-04 +1267 5.900000e-01 1.074007e-04 +1268 6.000000e-01 1.101313e-04 +1269 6.100000e-01 1.128272e-04 +1270 6.200000e-01 1.154883e-04 +1271 6.300000e-01 1.181152e-04 +1272 6.400000e-01 1.207080e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1273 6.500000e-01 1.232671e-04 +1274 6.600000e-01 1.257929e-04 +1275 6.700000e-01 1.282858e-04 +1276 6.800000e-01 1.307463e-04 +1277 6.900000e-01 1.331748e-04 +1278 7.000000e-01 1.355716e-04 +1279 7.100000e-01 1.379373e-04 +1280 7.200000e-01 1.402723e-04 +1281 7.300000e-01 1.425771e-04 +1282 7.400000e-01 1.448520e-04 +1283 7.500000e-01 1.470976e-04 +1284 7.600000e-01 1.493142e-04 +1285 7.700000e-01 1.515023e-04 +1286 7.800000e-01 1.536624e-04 +1287 7.900000e-01 1.557948e-04 +1288 8.000000e-01 1.579000e-04 +1289 8.100000e-01 1.599783e-04 +1290 8.200000e-01 1.620303e-04 +1291 8.300000e-01 1.640562e-04 +1292 8.400000e-01 1.660565e-04 +1293 8.500000e-01 1.680316e-04 +1294 8.600000e-01 1.699818e-04 +1295 8.700000e-01 1.719074e-04 +1296 8.800000e-01 1.738090e-04 +1297 8.900000e-01 1.756868e-04 +1298 9.000000e-01 1.775412e-04 +1299 9.100000e-01 1.793725e-04 +1300 9.200000e-01 1.811810e-04 +1301 9.300000e-01 1.829672e-04 +1302 9.400000e-01 1.847312e-04 +1303 9.500000e-01 1.864736e-04 +1304 9.600000e-01 1.881944e-04 +1305 9.700000e-01 1.898942e-04 +1306 9.800000e-01 1.915731e-04 +1307 9.900000e-01 1.932315e-04 +1308 1.000000e+00 1.948696e-04 +1309 1.010000e+00 1.964879e-04 +1310 1.020000e+00 1.980864e-04 +1311 1.030000e+00 1.996656e-04 +1312 1.040000e+00 2.012256e-04 +1313 1.050000e+00 2.027668e-04 +1314 1.060000e+00 2.042894e-04 +1315 1.070000e+00 2.057937e-04 +1316 1.080000e+00 2.072799e-04 +1317 1.090000e+00 2.087484e-04 +1318 1.100000e+00 2.101992e-04 +1319 1.110000e+00 2.116327e-04 +1320 1.120000e+00 2.130491e-04 +1321 1.130000e+00 2.144487e-04 +1322 1.140000e+00 2.158316e-04 +1323 1.150000e+00 2.171982e-04 +1324 1.160000e+00 2.185485e-04 +1325 1.170000e+00 2.198829e-04 +1326 1.180000e+00 2.212016e-04 +1327 1.190000e+00 2.225047e-04 +1328 1.200000e+00 2.237925e-04 +1329 1.210000e+00 2.250652e-04 +1330 1.220000e+00 2.263229e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1331 1.230000e+00 2.275659e-04 +1332 1.240000e+00 2.287944e-04 +1333 1.250000e+00 2.300086e-04 +1334 1.260000e+00 2.312086e-04 +1335 1.270000e+00 2.323946e-04 +1336 1.280000e+00 2.335668e-04 +1337 1.290000e+00 2.347255e-04 +1338 1.300000e+00 2.358707e-04 +1339 1.310000e+00 2.370027e-04 +1340 1.320000e+00 2.381216e-04 +1341 1.330000e+00 2.392275e-04 +1342 1.340000e+00 2.403207e-04 +1343 1.350000e+00 2.414014e-04 +1344 1.360000e+00 2.424696e-04 +1345 1.370000e+00 2.435255e-04 +1346 1.380000e+00 2.445693e-04 +1347 1.390000e+00 2.456011e-04 +1348 1.400000e+00 2.466212e-04 +1349 1.410000e+00 2.476296e-04 +1350 1.420000e+00 2.486264e-04 +1351 1.430000e+00 2.496119e-04 +1352 1.440000e+00 2.505862e-04 +1353 1.450000e+00 2.515493e-04 +1354 1.460000e+00 2.525015e-04 +1355 1.470000e+00 2.534429e-04 +1356 1.480000e+00 2.543736e-04 +1357 1.490000e+00 2.552937e-04 +1358 1.500000e+00 2.562035e-04 + + + + diff --git a/tests/bsim3soipd/Makefile.am b/tests/bsim3soipd/Makefile.am new file mode 100644 index 000000000..acf97dd4a --- /dev/null +++ b/tests/bsim3soipd/Makefile.am @@ -0,0 +1,16 @@ +## Process this file with automake to produce Makefile.in + +TESTS = \ + t3.cir \ + t4.cir \ + t5.cir \ + inv2.cir \ + RampVg2.cir + +TESTS_ENVIRONMENT = $(SHELL) $(srcdir)/../check.sh $(top_builddir)/src/ngspice + +EXTRA_DIST = \ + $(TESTS) \ + $(TESTS:.cir=.out) + +MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/bsim3soipd/RampVg2.cir b/tests/bsim3soipd/RampVg2.cir new file mode 100644 index 000000000..7af951932 --- /dev/null +++ b/tests/bsim3soipd/RampVg2.cir @@ -0,0 +1,20 @@ +* BSIMSOI (PD) example +* +* SOI, Ramp Vg + +Vd d 0 1.5 +Vg g 0 0.0 PULSE 0V 2V .02n .1n .1n .2n .6n +Ve e 0 0.0 +Vs s 0 0.0 +Vb b 0 0.0 + +m1 d g s e n1 w=10u l=0.25u debug=-1 + +.option gmin=1e-20 itl1=200 itl2=200 abstol=1e-9 +.tran 1p 1.0ns +.save @m1[Vbs], V(g)/10 +.print tran v(g)/10 +.include nmospd.mod + +.end + diff --git a/tests/bsim3soipd/RampVg2.out b/tests/bsim3soipd/RampVg2.out new file mode 100644 index 000000000..f4a4f52fe --- /dev/null +++ b/tests/bsim3soipd/RampVg2.out @@ -0,0 +1,1113 @@ + +Circuit: * BSIMSOI (PD) example + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. + +Initial Transient Solution +-------------------------- + +Node Voltage +---- ------- +d 1.5 +g 0 +e 0 +s 0 +b 0 +vb#branch 0 +vs#branch 1.17881e-09 +ve#branch 0 +vg#branch 1.5e-20 +vd#branch -1.17881e-09 + + Reference value : 3.21500e-10 +No. of Data Rows : 1029 + * BSIMSOI (PD) example +-------------------------------------------------------------------------------- +Index time v(g)/10 +-------------------------------------------------------------------------------- +0 0.000000e+00 0.000000e+00 +1 1.000000e-14 0.000000e+00 +2 2.000000e-14 0.000000e+00 +3 4.000000e-14 0.000000e+00 +4 8.000000e-14 0.000000e+00 +5 1.600000e-13 0.000000e+00 +6 3.200000e-13 0.000000e+00 +7 6.400000e-13 0.000000e+00 +8 1.280000e-12 0.000000e+00 +9 2.280000e-12 0.000000e+00 +10 3.280000e-12 0.000000e+00 +11 4.280000e-12 0.000000e+00 +12 5.280000e-12 0.000000e+00 +13 6.280000e-12 0.000000e+00 +14 7.280000e-12 0.000000e+00 +15 8.280000e-12 0.000000e+00 +16 9.280000e-12 0.000000e+00 +17 1.028000e-11 0.000000e+00 +18 1.128000e-11 0.000000e+00 +19 1.228000e-11 0.000000e+00 +20 1.328000e-11 0.000000e+00 +21 1.428000e-11 0.000000e+00 +22 1.528000e-11 0.000000e+00 +23 1.628000e-11 0.000000e+00 +24 1.728000e-11 0.000000e+00 +25 1.828000e-11 0.000000e+00 +26 1.928000e-11 0.000000e+00 +27 2.000000e-11 0.000000e+00 +28 2.010000e-11 2.000000e-04 +29 2.030000e-11 6.000000e-04 +30 2.070000e-11 1.400000e-03 +31 2.150000e-11 3.000000e-03 +32 2.250000e-11 5.000000e-03 +33 2.350000e-11 7.000000e-03 +34 2.450000e-11 9.000000e-03 +35 2.550000e-11 1.100000e-02 +36 2.650000e-11 1.300000e-02 +37 2.750000e-11 1.500000e-02 +38 2.850000e-11 1.700000e-02 +39 2.950000e-11 1.900000e-02 +40 3.050000e-11 2.100000e-02 +41 3.150000e-11 2.300000e-02 +42 3.250000e-11 2.500000e-02 +43 3.350000e-11 2.700000e-02 +44 3.450000e-11 2.900000e-02 +45 3.550000e-11 3.100000e-02 +46 3.650000e-11 3.300000e-02 +47 3.750000e-11 3.500000e-02 +48 3.850000e-11 3.700000e-02 +49 3.950000e-11 3.900000e-02 +50 4.050000e-11 4.100000e-02 +51 4.150000e-11 4.300000e-02 +52 4.250000e-11 4.500000e-02 +53 4.350000e-11 4.700000e-02 +54 4.450000e-11 4.900000e-02 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +55 4.550000e-11 5.100000e-02 +56 4.650000e-11 5.300000e-02 +57 4.750000e-11 5.500000e-02 +58 4.850000e-11 5.700000e-02 +59 4.950000e-11 5.900000e-02 +60 5.050000e-11 6.100000e-02 +61 5.150000e-11 6.300000e-02 +62 5.250000e-11 6.500000e-02 +63 5.350000e-11 6.700000e-02 +64 5.450000e-11 6.900000e-02 +65 5.550000e-11 7.100000e-02 +66 5.650000e-11 7.300000e-02 +67 5.750000e-11 7.500000e-02 +68 5.850000e-11 7.700000e-02 +69 5.950000e-11 7.900000e-02 +70 6.050000e-11 8.100000e-02 +71 6.150000e-11 8.300000e-02 +72 6.250000e-11 8.500000e-02 +73 6.350000e-11 8.700000e-02 +74 6.450000e-11 8.900000e-02 +75 6.550000e-11 9.100000e-02 +76 6.650000e-11 9.300000e-02 +77 6.750000e-11 9.500000e-02 +78 6.850000e-11 9.700000e-02 +79 6.950000e-11 9.900000e-02 +80 7.050000e-11 1.010000e-01 +81 7.150000e-11 1.030000e-01 +82 7.250000e-11 1.050000e-01 +83 7.350000e-11 1.070000e-01 +84 7.450000e-11 1.090000e-01 +85 7.550000e-11 1.110000e-01 +86 7.650000e-11 1.130000e-01 +87 7.750000e-11 1.150000e-01 +88 7.850000e-11 1.170000e-01 +89 7.950000e-11 1.190000e-01 +90 8.050000e-11 1.210000e-01 +91 8.150000e-11 1.230000e-01 +92 8.250000e-11 1.250000e-01 +93 8.350000e-11 1.270000e-01 +94 8.450000e-11 1.290000e-01 +95 8.550000e-11 1.310000e-01 +96 8.650000e-11 1.330000e-01 +97 8.750000e-11 1.350000e-01 +98 8.850000e-11 1.370000e-01 +99 8.950000e-11 1.390000e-01 +100 9.050000e-11 1.410000e-01 +101 9.150000e-11 1.430000e-01 +102 9.250000e-11 1.450000e-01 +103 9.350000e-11 1.470000e-01 +104 9.450000e-11 1.490000e-01 +105 9.550000e-11 1.510000e-01 +106 9.650000e-11 1.530000e-01 +107 9.750000e-11 1.550000e-01 +108 9.850000e-11 1.570000e-01 +109 9.950000e-11 1.590000e-01 +110 1.005000e-10 1.610000e-01 +111 1.015000e-10 1.630000e-01 +112 1.025000e-10 1.650000e-01 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +113 1.035000e-10 1.670000e-01 +114 1.045000e-10 1.690000e-01 +115 1.055000e-10 1.710000e-01 +116 1.065000e-10 1.730000e-01 +117 1.075000e-10 1.750000e-01 +118 1.085000e-10 1.770000e-01 +119 1.095000e-10 1.790000e-01 +120 1.105000e-10 1.810000e-01 +121 1.115000e-10 1.830000e-01 +122 1.125000e-10 1.850000e-01 +123 1.135000e-10 1.870000e-01 +124 1.145000e-10 1.890000e-01 +125 1.155000e-10 1.910000e-01 +126 1.165000e-10 1.930000e-01 +127 1.175000e-10 1.950000e-01 +128 1.185000e-10 1.970000e-01 +129 1.195000e-10 1.990000e-01 +130 1.200000e-10 2.000000e-01 +131 1.201000e-10 2.000000e-01 +132 1.203000e-10 2.000000e-01 +133 1.207000e-10 2.000000e-01 +134 1.215000e-10 2.000000e-01 +135 1.225000e-10 2.000000e-01 +136 1.235000e-10 2.000000e-01 +137 1.245000e-10 2.000000e-01 +138 1.255000e-10 2.000000e-01 +139 1.265000e-10 2.000000e-01 +140 1.275000e-10 2.000000e-01 +141 1.285000e-10 2.000000e-01 +142 1.295000e-10 2.000000e-01 +143 1.305000e-10 2.000000e-01 +144 1.315000e-10 2.000000e-01 +145 1.325000e-10 2.000000e-01 +146 1.335000e-10 2.000000e-01 +147 1.345000e-10 2.000000e-01 +148 1.355000e-10 2.000000e-01 +149 1.365000e-10 2.000000e-01 +150 1.375000e-10 2.000000e-01 +151 1.385000e-10 2.000000e-01 +152 1.395000e-10 2.000000e-01 +153 1.405000e-10 2.000000e-01 +154 1.415000e-10 2.000000e-01 +155 1.425000e-10 2.000000e-01 +156 1.435000e-10 2.000000e-01 +157 1.445000e-10 2.000000e-01 +158 1.455000e-10 2.000000e-01 +159 1.465000e-10 2.000000e-01 +160 1.475000e-10 2.000000e-01 +161 1.485000e-10 2.000000e-01 +162 1.495000e-10 2.000000e-01 +163 1.505000e-10 2.000000e-01 +164 1.515000e-10 2.000000e-01 +165 1.525000e-10 2.000000e-01 +166 1.535000e-10 2.000000e-01 +167 1.545000e-10 2.000000e-01 +168 1.555000e-10 2.000000e-01 +169 1.565000e-10 2.000000e-01 +170 1.575000e-10 2.000000e-01 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +171 1.585000e-10 2.000000e-01 +172 1.595000e-10 2.000000e-01 +173 1.605000e-10 2.000000e-01 +174 1.615000e-10 2.000000e-01 +175 1.625000e-10 2.000000e-01 +176 1.635000e-10 2.000000e-01 +177 1.645000e-10 2.000000e-01 +178 1.655000e-10 2.000000e-01 +179 1.665000e-10 2.000000e-01 +180 1.675000e-10 2.000000e-01 +181 1.685000e-10 2.000000e-01 +182 1.695000e-10 2.000000e-01 +183 1.705000e-10 2.000000e-01 +184 1.715000e-10 2.000000e-01 +185 1.725000e-10 2.000000e-01 +186 1.735000e-10 2.000000e-01 +187 1.745000e-10 2.000000e-01 +188 1.755000e-10 2.000000e-01 +189 1.765000e-10 2.000000e-01 +190 1.775000e-10 2.000000e-01 +191 1.785000e-10 2.000000e-01 +192 1.795000e-10 2.000000e-01 +193 1.805000e-10 2.000000e-01 +194 1.815000e-10 2.000000e-01 +195 1.825000e-10 2.000000e-01 +196 1.835000e-10 2.000000e-01 +197 1.845000e-10 2.000000e-01 +198 1.855000e-10 2.000000e-01 +199 1.865000e-10 2.000000e-01 +200 1.875000e-10 2.000000e-01 +201 1.885000e-10 2.000000e-01 +202 1.895000e-10 2.000000e-01 +203 1.905000e-10 2.000000e-01 +204 1.915000e-10 2.000000e-01 +205 1.925000e-10 2.000000e-01 +206 1.935000e-10 2.000000e-01 +207 1.945000e-10 2.000000e-01 +208 1.955000e-10 2.000000e-01 +209 1.965000e-10 2.000000e-01 +210 1.975000e-10 2.000000e-01 +211 1.985000e-10 2.000000e-01 +212 1.995000e-10 2.000000e-01 +213 2.005000e-10 2.000000e-01 +214 2.015000e-10 2.000000e-01 +215 2.025000e-10 2.000000e-01 +216 2.035000e-10 2.000000e-01 +217 2.045000e-10 2.000000e-01 +218 2.055000e-10 2.000000e-01 +219 2.065000e-10 2.000000e-01 +220 2.075000e-10 2.000000e-01 +221 2.085000e-10 2.000000e-01 +222 2.095000e-10 2.000000e-01 +223 2.105000e-10 2.000000e-01 +224 2.115000e-10 2.000000e-01 +225 2.125000e-10 2.000000e-01 +226 2.135000e-10 2.000000e-01 +227 2.145000e-10 2.000000e-01 +228 2.155000e-10 2.000000e-01 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +229 2.165000e-10 2.000000e-01 +230 2.175000e-10 2.000000e-01 +231 2.185000e-10 2.000000e-01 +232 2.195000e-10 2.000000e-01 +233 2.205000e-10 2.000000e-01 +234 2.215000e-10 2.000000e-01 +235 2.225000e-10 2.000000e-01 +236 2.235000e-10 2.000000e-01 +237 2.245000e-10 2.000000e-01 +238 2.255000e-10 2.000000e-01 +239 2.265000e-10 2.000000e-01 +240 2.275000e-10 2.000000e-01 +241 2.285000e-10 2.000000e-01 +242 2.295000e-10 2.000000e-01 +243 2.305000e-10 2.000000e-01 +244 2.315000e-10 2.000000e-01 +245 2.325000e-10 2.000000e-01 +246 2.335000e-10 2.000000e-01 +247 2.345000e-10 2.000000e-01 +248 2.355000e-10 2.000000e-01 +249 2.365000e-10 2.000000e-01 +250 2.375000e-10 2.000000e-01 +251 2.385000e-10 2.000000e-01 +252 2.395000e-10 2.000000e-01 +253 2.405000e-10 2.000000e-01 +254 2.415000e-10 2.000000e-01 +255 2.425000e-10 2.000000e-01 +256 2.435000e-10 2.000000e-01 +257 2.445000e-10 2.000000e-01 +258 2.455000e-10 2.000000e-01 +259 2.465000e-10 2.000000e-01 +260 2.475000e-10 2.000000e-01 +261 2.485000e-10 2.000000e-01 +262 2.495000e-10 2.000000e-01 +263 2.505000e-10 2.000000e-01 +264 2.515000e-10 2.000000e-01 +265 2.525000e-10 2.000000e-01 +266 2.535000e-10 2.000000e-01 +267 2.545000e-10 2.000000e-01 +268 2.555000e-10 2.000000e-01 +269 2.565000e-10 2.000000e-01 +270 2.575000e-10 2.000000e-01 +271 2.585000e-10 2.000000e-01 +272 2.595000e-10 2.000000e-01 +273 2.605000e-10 2.000000e-01 +274 2.615000e-10 2.000000e-01 +275 2.625000e-10 2.000000e-01 +276 2.635000e-10 2.000000e-01 +277 2.645000e-10 2.000000e-01 +278 2.655000e-10 2.000000e-01 +279 2.665000e-10 2.000000e-01 +280 2.675000e-10 2.000000e-01 +281 2.685000e-10 2.000000e-01 +282 2.695000e-10 2.000000e-01 +283 2.705000e-10 2.000000e-01 +284 2.715000e-10 2.000000e-01 +285 2.725000e-10 2.000000e-01 +286 2.735000e-10 2.000000e-01 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +287 2.745000e-10 2.000000e-01 +288 2.755000e-10 2.000000e-01 +289 2.765000e-10 2.000000e-01 +290 2.775000e-10 2.000000e-01 +291 2.785000e-10 2.000000e-01 +292 2.795000e-10 2.000000e-01 +293 2.805000e-10 2.000000e-01 +294 2.815000e-10 2.000000e-01 +295 2.825000e-10 2.000000e-01 +296 2.835000e-10 2.000000e-01 +297 2.845000e-10 2.000000e-01 +298 2.855000e-10 2.000000e-01 +299 2.865000e-10 2.000000e-01 +300 2.875000e-10 2.000000e-01 +301 2.885000e-10 2.000000e-01 +302 2.895000e-10 2.000000e-01 +303 2.905000e-10 2.000000e-01 +304 2.915000e-10 2.000000e-01 +305 2.925000e-10 2.000000e-01 +306 2.935000e-10 2.000000e-01 +307 2.945000e-10 2.000000e-01 +308 2.955000e-10 2.000000e-01 +309 2.965000e-10 2.000000e-01 +310 2.975000e-10 2.000000e-01 +311 2.985000e-10 2.000000e-01 +312 2.995000e-10 2.000000e-01 +313 3.005000e-10 2.000000e-01 +314 3.015000e-10 2.000000e-01 +315 3.025000e-10 2.000000e-01 +316 3.035000e-10 2.000000e-01 +317 3.045000e-10 2.000000e-01 +318 3.055000e-10 2.000000e-01 +319 3.065000e-10 2.000000e-01 +320 3.075000e-10 2.000000e-01 +321 3.085000e-10 2.000000e-01 +322 3.095000e-10 2.000000e-01 +323 3.105000e-10 2.000000e-01 +324 3.115000e-10 2.000000e-01 +325 3.125000e-10 2.000000e-01 +326 3.135000e-10 2.000000e-01 +327 3.145000e-10 2.000000e-01 +328 3.155000e-10 2.000000e-01 +329 3.165000e-10 2.000000e-01 +330 3.175000e-10 2.000000e-01 +331 3.185000e-10 2.000000e-01 +332 3.195000e-10 2.000000e-01 +333 3.200000e-10 2.000000e-01 +334 3.201000e-10 1.998000e-01 +335 3.203000e-10 1.994000e-01 +336 3.207000e-10 1.986000e-01 +337 3.215000e-10 1.970000e-01 +338 3.225000e-10 1.950000e-01 +339 3.235000e-10 1.930000e-01 +340 3.245000e-10 1.910000e-01 +341 3.255000e-10 1.890000e-01 +342 3.265000e-10 1.870000e-01 +343 3.275000e-10 1.850000e-01 +344 3.285000e-10 1.830000e-01 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +345 3.295000e-10 1.810000e-01 +346 3.305000e-10 1.790000e-01 +347 3.315000e-10 1.770000e-01 +348 3.325000e-10 1.750000e-01 +349 3.335000e-10 1.730000e-01 +350 3.345000e-10 1.710000e-01 +351 3.355000e-10 1.690000e-01 +352 3.365000e-10 1.670000e-01 +353 3.375000e-10 1.650000e-01 +354 3.385000e-10 1.630000e-01 +355 3.395000e-10 1.610000e-01 +356 3.405000e-10 1.590000e-01 +357 3.415000e-10 1.570000e-01 +358 3.425000e-10 1.550000e-01 +359 3.435000e-10 1.530000e-01 +360 3.445000e-10 1.510000e-01 +361 3.455000e-10 1.490000e-01 +362 3.465000e-10 1.470000e-01 +363 3.475000e-10 1.450000e-01 +364 3.485000e-10 1.430000e-01 +365 3.495000e-10 1.410000e-01 +366 3.505000e-10 1.390000e-01 +367 3.515000e-10 1.370000e-01 +368 3.525000e-10 1.350000e-01 +369 3.535000e-10 1.330000e-01 +370 3.545000e-10 1.310000e-01 +371 3.555000e-10 1.290000e-01 +372 3.565000e-10 1.270000e-01 +373 3.575000e-10 1.250000e-01 +374 3.585000e-10 1.230000e-01 +375 3.595000e-10 1.210000e-01 +376 3.605000e-10 1.190000e-01 +377 3.615000e-10 1.170000e-01 +378 3.625000e-10 1.150000e-01 +379 3.635000e-10 1.130000e-01 +380 3.645000e-10 1.110000e-01 +381 3.655000e-10 1.090000e-01 +382 3.665000e-10 1.070000e-01 +383 3.675000e-10 1.050000e-01 +384 3.685000e-10 1.030000e-01 +385 3.695000e-10 1.010000e-01 +386 3.705000e-10 9.900000e-02 +387 3.715000e-10 9.700000e-02 +388 3.725000e-10 9.500000e-02 +389 3.735000e-10 9.300000e-02 +390 3.745000e-10 9.100000e-02 +391 3.755000e-10 8.900000e-02 +392 3.765000e-10 8.700000e-02 +393 3.775000e-10 8.500000e-02 +394 3.785000e-10 8.300000e-02 +395 3.795000e-10 8.100000e-02 +396 3.805000e-10 7.900000e-02 +397 3.815000e-10 7.700000e-02 +398 3.825000e-10 7.500000e-02 +399 3.835000e-10 7.300000e-02 +400 3.845000e-10 7.100000e-02 +401 3.855000e-10 6.900000e-02 +402 3.865000e-10 6.700000e-02 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +403 3.875000e-10 6.500000e-02 +404 3.885000e-10 6.300000e-02 +405 3.895000e-10 6.100000e-02 +406 3.905000e-10 5.900000e-02 +407 3.915000e-10 5.700000e-02 +408 3.925000e-10 5.500000e-02 +409 3.935000e-10 5.300000e-02 +410 3.945000e-10 5.100000e-02 +411 3.955000e-10 4.900000e-02 +412 3.965000e-10 4.700000e-02 +413 3.975000e-10 4.500000e-02 +414 3.985000e-10 4.300000e-02 +415 3.995000e-10 4.100000e-02 +416 4.005000e-10 3.900000e-02 +417 4.015000e-10 3.700000e-02 +418 4.025000e-10 3.500000e-02 +419 4.035000e-10 3.300000e-02 +420 4.045000e-10 3.100000e-02 +421 4.055000e-10 2.900000e-02 +422 4.065000e-10 2.700000e-02 +423 4.075000e-10 2.500000e-02 +424 4.085000e-10 2.300000e-02 +425 4.095000e-10 2.100000e-02 +426 4.105000e-10 1.900000e-02 +427 4.115000e-10 1.700000e-02 +428 4.125000e-10 1.500000e-02 +429 4.135000e-10 1.300000e-02 +430 4.145000e-10 1.100000e-02 +431 4.155000e-10 9.000000e-03 +432 4.165000e-10 7.000000e-03 +433 4.175000e-10 5.000000e-03 +434 4.185000e-10 3.000000e-03 +435 4.195000e-10 1.000000e-03 +436 4.200000e-10 3.230922e-17 +437 4.201000e-10 0.000000e+00 +438 4.203000e-10 0.000000e+00 +439 4.207000e-10 0.000000e+00 +440 4.215000e-10 0.000000e+00 +441 4.225000e-10 0.000000e+00 +442 4.235000e-10 0.000000e+00 +443 4.245000e-10 0.000000e+00 +444 4.255000e-10 0.000000e+00 +445 4.265000e-10 0.000000e+00 +446 4.275000e-10 0.000000e+00 +447 4.285000e-10 0.000000e+00 +448 4.295000e-10 0.000000e+00 +449 4.305000e-10 0.000000e+00 +450 4.315000e-10 0.000000e+00 +451 4.325000e-10 0.000000e+00 +452 4.335000e-10 0.000000e+00 +453 4.345000e-10 0.000000e+00 +454 4.355000e-10 0.000000e+00 +455 4.365000e-10 0.000000e+00 +456 4.375000e-10 0.000000e+00 +457 4.385000e-10 0.000000e+00 +458 4.395000e-10 0.000000e+00 +459 4.405000e-10 0.000000e+00 +460 4.415000e-10 0.000000e+00 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +461 4.425000e-10 0.000000e+00 +462 4.435000e-10 0.000000e+00 +463 4.445000e-10 0.000000e+00 +464 4.455000e-10 0.000000e+00 +465 4.465000e-10 0.000000e+00 +466 4.475000e-10 0.000000e+00 +467 4.485000e-10 0.000000e+00 +468 4.495000e-10 0.000000e+00 +469 4.505000e-10 0.000000e+00 +470 4.515000e-10 0.000000e+00 +471 4.525000e-10 0.000000e+00 +472 4.535000e-10 0.000000e+00 +473 4.545000e-10 0.000000e+00 +474 4.555000e-10 0.000000e+00 +475 4.565000e-10 0.000000e+00 +476 4.575000e-10 0.000000e+00 +477 4.585000e-10 0.000000e+00 +478 4.595000e-10 0.000000e+00 +479 4.605000e-10 0.000000e+00 +480 4.615000e-10 0.000000e+00 +481 4.625000e-10 0.000000e+00 +482 4.635000e-10 0.000000e+00 +483 4.645000e-10 0.000000e+00 +484 4.655000e-10 0.000000e+00 +485 4.665000e-10 0.000000e+00 +486 4.675000e-10 0.000000e+00 +487 4.685000e-10 0.000000e+00 +488 4.695000e-10 0.000000e+00 +489 4.705000e-10 0.000000e+00 +490 4.715000e-10 0.000000e+00 +491 4.725000e-10 0.000000e+00 +492 4.735000e-10 0.000000e+00 +493 4.745000e-10 0.000000e+00 +494 4.755000e-10 0.000000e+00 +495 4.765000e-10 0.000000e+00 +496 4.775000e-10 0.000000e+00 +497 4.785000e-10 0.000000e+00 +498 4.795000e-10 0.000000e+00 +499 4.805000e-10 0.000000e+00 +500 4.815000e-10 0.000000e+00 +501 4.825000e-10 0.000000e+00 +502 4.835000e-10 0.000000e+00 +503 4.845000e-10 0.000000e+00 +504 4.855000e-10 0.000000e+00 +505 4.865000e-10 0.000000e+00 +506 4.875000e-10 0.000000e+00 +507 4.885000e-10 0.000000e+00 +508 4.895000e-10 0.000000e+00 +509 4.905000e-10 0.000000e+00 +510 4.915000e-10 0.000000e+00 +511 4.925000e-10 0.000000e+00 +512 4.935000e-10 0.000000e+00 +513 4.945000e-10 0.000000e+00 +514 4.955000e-10 0.000000e+00 +515 4.965000e-10 0.000000e+00 +516 4.975000e-10 0.000000e+00 +517 4.985000e-10 0.000000e+00 +518 4.995000e-10 0.000000e+00 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +519 5.005000e-10 0.000000e+00 +520 5.015000e-10 0.000000e+00 +521 5.025000e-10 0.000000e+00 +522 5.035000e-10 0.000000e+00 +523 5.045000e-10 0.000000e+00 +524 5.055000e-10 0.000000e+00 +525 5.065000e-10 0.000000e+00 +526 5.075000e-10 0.000000e+00 +527 5.085000e-10 0.000000e+00 +528 5.095000e-10 0.000000e+00 +529 5.105000e-10 0.000000e+00 +530 5.115000e-10 0.000000e+00 +531 5.125000e-10 0.000000e+00 +532 5.135000e-10 0.000000e+00 +533 5.145000e-10 0.000000e+00 +534 5.155000e-10 0.000000e+00 +535 5.165000e-10 0.000000e+00 +536 5.175000e-10 0.000000e+00 +537 5.185000e-10 0.000000e+00 +538 5.195000e-10 0.000000e+00 +539 5.205000e-10 0.000000e+00 +540 5.215000e-10 0.000000e+00 +541 5.225000e-10 0.000000e+00 +542 5.235000e-10 0.000000e+00 +543 5.245000e-10 0.000000e+00 +544 5.255000e-10 0.000000e+00 +545 5.265000e-10 0.000000e+00 +546 5.275000e-10 0.000000e+00 +547 5.285000e-10 0.000000e+00 +548 5.295000e-10 0.000000e+00 +549 5.305000e-10 0.000000e+00 +550 5.315000e-10 0.000000e+00 +551 5.325000e-10 0.000000e+00 +552 5.335000e-10 0.000000e+00 +553 5.345000e-10 0.000000e+00 +554 5.355000e-10 0.000000e+00 +555 5.365000e-10 0.000000e+00 +556 5.375000e-10 0.000000e+00 +557 5.385000e-10 0.000000e+00 +558 5.395000e-10 0.000000e+00 +559 5.405000e-10 0.000000e+00 +560 5.415000e-10 0.000000e+00 +561 5.425000e-10 0.000000e+00 +562 5.435000e-10 0.000000e+00 +563 5.445000e-10 0.000000e+00 +564 5.455000e-10 0.000000e+00 +565 5.465000e-10 0.000000e+00 +566 5.475000e-10 0.000000e+00 +567 5.485000e-10 0.000000e+00 +568 5.495000e-10 0.000000e+00 +569 5.505000e-10 0.000000e+00 +570 5.515000e-10 0.000000e+00 +571 5.525000e-10 0.000000e+00 +572 5.535000e-10 0.000000e+00 +573 5.545000e-10 0.000000e+00 +574 5.555000e-10 0.000000e+00 +575 5.565000e-10 0.000000e+00 +576 5.575000e-10 0.000000e+00 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +577 5.585000e-10 0.000000e+00 +578 5.595000e-10 0.000000e+00 +579 5.605000e-10 0.000000e+00 +580 5.615000e-10 0.000000e+00 +581 5.625000e-10 0.000000e+00 +582 5.635000e-10 0.000000e+00 +583 5.645000e-10 0.000000e+00 +584 5.655000e-10 0.000000e+00 +585 5.665000e-10 0.000000e+00 +586 5.675000e-10 0.000000e+00 +587 5.685000e-10 0.000000e+00 +588 5.695000e-10 0.000000e+00 +589 5.705000e-10 0.000000e+00 +590 5.715000e-10 0.000000e+00 +591 5.725000e-10 0.000000e+00 +592 5.735000e-10 0.000000e+00 +593 5.745000e-10 0.000000e+00 +594 5.755000e-10 0.000000e+00 +595 5.765000e-10 0.000000e+00 +596 5.775000e-10 0.000000e+00 +597 5.785000e-10 0.000000e+00 +598 5.795000e-10 0.000000e+00 +599 5.805000e-10 0.000000e+00 +600 5.815000e-10 0.000000e+00 +601 5.825000e-10 0.000000e+00 +602 5.835000e-10 0.000000e+00 +603 5.845000e-10 0.000000e+00 +604 5.855000e-10 0.000000e+00 +605 5.865000e-10 0.000000e+00 +606 5.875000e-10 0.000000e+00 +607 5.885000e-10 0.000000e+00 +608 5.895000e-10 0.000000e+00 +609 5.905000e-10 0.000000e+00 +610 5.915000e-10 0.000000e+00 +611 5.925000e-10 0.000000e+00 +612 5.935000e-10 0.000000e+00 +613 5.945000e-10 0.000000e+00 +614 5.955000e-10 0.000000e+00 +615 5.965000e-10 0.000000e+00 +616 5.975000e-10 0.000000e+00 +617 5.985000e-10 0.000000e+00 +618 5.995000e-10 0.000000e+00 +619 6.005000e-10 0.000000e+00 +620 6.015000e-10 0.000000e+00 +621 6.025000e-10 0.000000e+00 +622 6.035000e-10 0.000000e+00 +623 6.045000e-10 0.000000e+00 +624 6.055000e-10 0.000000e+00 +625 6.065000e-10 0.000000e+00 +626 6.075000e-10 0.000000e+00 +627 6.085000e-10 0.000000e+00 +628 6.095000e-10 0.000000e+00 +629 6.105000e-10 0.000000e+00 +630 6.115000e-10 0.000000e+00 +631 6.125000e-10 0.000000e+00 +632 6.135000e-10 0.000000e+00 +633 6.145000e-10 0.000000e+00 +634 6.155000e-10 0.000000e+00 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +635 6.165000e-10 0.000000e+00 +636 6.175000e-10 0.000000e+00 +637 6.185000e-10 0.000000e+00 +638 6.195000e-10 0.000000e+00 +639 6.200000e-10 7.108583e-17 +640 6.201000e-10 2.000000e-04 +641 6.203000e-10 6.000000e-04 +642 6.207000e-10 1.400000e-03 +643 6.215000e-10 3.000000e-03 +644 6.225000e-10 5.000000e-03 +645 6.235000e-10 7.000000e-03 +646 6.245000e-10 9.000000e-03 +647 6.255000e-10 1.100000e-02 +648 6.265000e-10 1.300000e-02 +649 6.275000e-10 1.500000e-02 +650 6.285000e-10 1.700000e-02 +651 6.295000e-10 1.900000e-02 +652 6.305000e-10 2.100000e-02 +653 6.315000e-10 2.300000e-02 +654 6.325000e-10 2.500000e-02 +655 6.335000e-10 2.700000e-02 +656 6.345000e-10 2.900000e-02 +657 6.355000e-10 3.100000e-02 +658 6.365000e-10 3.300000e-02 +659 6.375000e-10 3.500000e-02 +660 6.385000e-10 3.700000e-02 +661 6.395000e-10 3.900000e-02 +662 6.405000e-10 4.100000e-02 +663 6.415000e-10 4.300000e-02 +664 6.425000e-10 4.500000e-02 +665 6.435000e-10 4.700000e-02 +666 6.445000e-10 4.900000e-02 +667 6.455000e-10 5.100000e-02 +668 6.465000e-10 5.300000e-02 +669 6.475000e-10 5.500000e-02 +670 6.485000e-10 5.700000e-02 +671 6.495000e-10 5.900000e-02 +672 6.505000e-10 6.100000e-02 +673 6.515000e-10 6.300000e-02 +674 6.525000e-10 6.500000e-02 +675 6.535000e-10 6.700000e-02 +676 6.545000e-10 6.900000e-02 +677 6.555000e-10 7.100000e-02 +678 6.565000e-10 7.300000e-02 +679 6.575000e-10 7.500000e-02 +680 6.585000e-10 7.700000e-02 +681 6.595000e-10 7.900000e-02 +682 6.605000e-10 8.100000e-02 +683 6.615000e-10 8.300000e-02 +684 6.625000e-10 8.500000e-02 +685 6.635000e-10 8.700000e-02 +686 6.645000e-10 8.900000e-02 +687 6.655000e-10 9.100000e-02 +688 6.665000e-10 9.300000e-02 +689 6.675000e-10 9.500000e-02 +690 6.685000e-10 9.700000e-02 +691 6.695000e-10 9.900000e-02 +692 6.705000e-10 1.010000e-01 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +693 6.715000e-10 1.030000e-01 +694 6.725000e-10 1.050000e-01 +695 6.735000e-10 1.070000e-01 +696 6.745000e-10 1.090000e-01 +697 6.755000e-10 1.110000e-01 +698 6.765000e-10 1.130000e-01 +699 6.775000e-10 1.150000e-01 +700 6.785000e-10 1.170000e-01 +701 6.795000e-10 1.190000e-01 +702 6.805000e-10 1.210000e-01 +703 6.815000e-10 1.230000e-01 +704 6.825000e-10 1.250000e-01 +705 6.835000e-10 1.270000e-01 +706 6.845000e-10 1.290000e-01 +707 6.855000e-10 1.310000e-01 +708 6.865000e-10 1.330000e-01 +709 6.875000e-10 1.350000e-01 +710 6.885000e-10 1.370000e-01 +711 6.895000e-10 1.390000e-01 +712 6.905000e-10 1.410000e-01 +713 6.915000e-10 1.430000e-01 +714 6.925000e-10 1.450000e-01 +715 6.935000e-10 1.470000e-01 +716 6.945000e-10 1.490000e-01 +717 6.955000e-10 1.510000e-01 +718 6.965000e-10 1.530000e-01 +719 6.975000e-10 1.550000e-01 +720 6.985000e-10 1.570000e-01 +721 6.995000e-10 1.590000e-01 +722 7.005000e-10 1.610000e-01 +723 7.015000e-10 1.630000e-01 +724 7.025000e-10 1.650000e-01 +725 7.035000e-10 1.670000e-01 +726 7.045000e-10 1.690000e-01 +727 7.055000e-10 1.710000e-01 +728 7.065000e-10 1.730000e-01 +729 7.075000e-10 1.750000e-01 +730 7.085000e-10 1.770000e-01 +731 7.095000e-10 1.790000e-01 +732 7.105000e-10 1.810000e-01 +733 7.115000e-10 1.830000e-01 +734 7.125000e-10 1.850000e-01 +735 7.135000e-10 1.870000e-01 +736 7.145000e-10 1.890000e-01 +737 7.155000e-10 1.910000e-01 +738 7.165000e-10 1.930000e-01 +739 7.175000e-10 1.950000e-01 +740 7.185000e-10 1.970000e-01 +741 7.195000e-10 1.990000e-01 +742 7.200000e-10 2.000000e-01 +743 7.201000e-10 2.000000e-01 +744 7.203000e-10 2.000000e-01 +745 7.207000e-10 2.000000e-01 +746 7.215000e-10 2.000000e-01 +747 7.225000e-10 2.000000e-01 +748 7.235000e-10 2.000000e-01 +749 7.245000e-10 2.000000e-01 +750 7.255000e-10 2.000000e-01 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +751 7.265000e-10 2.000000e-01 +752 7.275000e-10 2.000000e-01 +753 7.285000e-10 2.000000e-01 +754 7.295000e-10 2.000000e-01 +755 7.305000e-10 2.000000e-01 +756 7.315000e-10 2.000000e-01 +757 7.325000e-10 2.000000e-01 +758 7.335000e-10 2.000000e-01 +759 7.345000e-10 2.000000e-01 +760 7.355000e-10 2.000000e-01 +761 7.365000e-10 2.000000e-01 +762 7.375000e-10 2.000000e-01 +763 7.385000e-10 2.000000e-01 +764 7.395000e-10 2.000000e-01 +765 7.405000e-10 2.000000e-01 +766 7.415000e-10 2.000000e-01 +767 7.425000e-10 2.000000e-01 +768 7.435000e-10 2.000000e-01 +769 7.445000e-10 2.000000e-01 +770 7.455000e-10 2.000000e-01 +771 7.465000e-10 2.000000e-01 +772 7.475000e-10 2.000000e-01 +773 7.485000e-10 2.000000e-01 +774 7.495000e-10 2.000000e-01 +775 7.505000e-10 2.000000e-01 +776 7.515000e-10 2.000000e-01 +777 7.525000e-10 2.000000e-01 +778 7.535000e-10 2.000000e-01 +779 7.545000e-10 2.000000e-01 +780 7.555000e-10 2.000000e-01 +781 7.565000e-10 2.000000e-01 +782 7.575000e-10 2.000000e-01 +783 7.585000e-10 2.000000e-01 +784 7.595000e-10 2.000000e-01 +785 7.605000e-10 2.000000e-01 +786 7.615000e-10 2.000000e-01 +787 7.625000e-10 2.000000e-01 +788 7.635000e-10 2.000000e-01 +789 7.645000e-10 2.000000e-01 +790 7.655000e-10 2.000000e-01 +791 7.665000e-10 2.000000e-01 +792 7.675000e-10 2.000000e-01 +793 7.685000e-10 2.000000e-01 +794 7.695000e-10 2.000000e-01 +795 7.705000e-10 2.000000e-01 +796 7.715000e-10 2.000000e-01 +797 7.725000e-10 2.000000e-01 +798 7.735000e-10 2.000000e-01 +799 7.745000e-10 2.000000e-01 +800 7.755000e-10 2.000000e-01 +801 7.765000e-10 2.000000e-01 +802 7.775000e-10 2.000000e-01 +803 7.785000e-10 2.000000e-01 +804 7.795000e-10 2.000000e-01 +805 7.805000e-10 2.000000e-01 +806 7.815000e-10 2.000000e-01 +807 7.825000e-10 2.000000e-01 +808 7.835000e-10 2.000000e-01 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +809 7.845000e-10 2.000000e-01 +810 7.855000e-10 2.000000e-01 +811 7.865000e-10 2.000000e-01 +812 7.875000e-10 2.000000e-01 +813 7.885000e-10 2.000000e-01 +814 7.895000e-10 2.000000e-01 +815 7.905000e-10 2.000000e-01 +816 7.915000e-10 2.000000e-01 +817 7.925000e-10 2.000000e-01 +818 7.935000e-10 2.000000e-01 +819 7.945000e-10 2.000000e-01 +820 7.955000e-10 2.000000e-01 +821 7.965000e-10 2.000000e-01 +822 7.975000e-10 2.000000e-01 +823 7.985000e-10 2.000000e-01 +824 7.995000e-10 2.000000e-01 +825 8.005000e-10 2.000000e-01 +826 8.015000e-10 2.000000e-01 +827 8.025000e-10 2.000000e-01 +828 8.035000e-10 2.000000e-01 +829 8.045000e-10 2.000000e-01 +830 8.055000e-10 2.000000e-01 +831 8.065000e-10 2.000000e-01 +832 8.075000e-10 2.000000e-01 +833 8.085000e-10 2.000000e-01 +834 8.095000e-10 2.000000e-01 +835 8.105000e-10 2.000000e-01 +836 8.115000e-10 2.000000e-01 +837 8.125000e-10 2.000000e-01 +838 8.135000e-10 2.000000e-01 +839 8.145000e-10 2.000000e-01 +840 8.155000e-10 2.000000e-01 +841 8.165000e-10 2.000000e-01 +842 8.175000e-10 2.000000e-01 +843 8.185000e-10 2.000000e-01 +844 8.195000e-10 2.000000e-01 +845 8.205000e-10 2.000000e-01 +846 8.215000e-10 2.000000e-01 +847 8.225000e-10 2.000000e-01 +848 8.235000e-10 2.000000e-01 +849 8.245000e-10 2.000000e-01 +850 8.255000e-10 2.000000e-01 +851 8.265000e-10 2.000000e-01 +852 8.275000e-10 2.000000e-01 +853 8.285000e-10 2.000000e-01 +854 8.295000e-10 2.000000e-01 +855 8.305000e-10 2.000000e-01 +856 8.315000e-10 2.000000e-01 +857 8.325000e-10 2.000000e-01 +858 8.335000e-10 2.000000e-01 +859 8.345000e-10 2.000000e-01 +860 8.355000e-10 2.000000e-01 +861 8.365000e-10 2.000000e-01 +862 8.375000e-10 2.000000e-01 +863 8.385000e-10 2.000000e-01 +864 8.395000e-10 2.000000e-01 +865 8.405000e-10 2.000000e-01 +866 8.415000e-10 2.000000e-01 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +867 8.425000e-10 2.000000e-01 +868 8.435000e-10 2.000000e-01 +869 8.445000e-10 2.000000e-01 +870 8.455000e-10 2.000000e-01 +871 8.465000e-10 2.000000e-01 +872 8.475000e-10 2.000000e-01 +873 8.485000e-10 2.000000e-01 +874 8.495000e-10 2.000000e-01 +875 8.505000e-10 2.000000e-01 +876 8.515000e-10 2.000000e-01 +877 8.525000e-10 2.000000e-01 +878 8.535000e-10 2.000000e-01 +879 8.545000e-10 2.000000e-01 +880 8.555000e-10 2.000000e-01 +881 8.565000e-10 2.000000e-01 +882 8.575000e-10 2.000000e-01 +883 8.585000e-10 2.000000e-01 +884 8.595000e-10 2.000000e-01 +885 8.605000e-10 2.000000e-01 +886 8.615000e-10 2.000000e-01 +887 8.625000e-10 2.000000e-01 +888 8.635000e-10 2.000000e-01 +889 8.645000e-10 2.000000e-01 +890 8.655000e-10 2.000000e-01 +891 8.665000e-10 2.000000e-01 +892 8.675000e-10 2.000000e-01 +893 8.685000e-10 2.000000e-01 +894 8.695000e-10 2.000000e-01 +895 8.705000e-10 2.000000e-01 +896 8.715000e-10 2.000000e-01 +897 8.725000e-10 2.000000e-01 +898 8.735000e-10 2.000000e-01 +899 8.745000e-10 2.000000e-01 +900 8.755000e-10 2.000000e-01 +901 8.765000e-10 2.000000e-01 +902 8.775000e-10 2.000000e-01 +903 8.785000e-10 2.000000e-01 +904 8.795000e-10 2.000000e-01 +905 8.805000e-10 2.000000e-01 +906 8.815000e-10 2.000000e-01 +907 8.825000e-10 2.000000e-01 +908 8.835000e-10 2.000000e-01 +909 8.845000e-10 2.000000e-01 +910 8.855000e-10 2.000000e-01 +911 8.865000e-10 2.000000e-01 +912 8.875000e-10 2.000000e-01 +913 8.885000e-10 2.000000e-01 +914 8.895000e-10 2.000000e-01 +915 8.905000e-10 2.000000e-01 +916 8.915000e-10 2.000000e-01 +917 8.925000e-10 2.000000e-01 +918 8.935000e-10 2.000000e-01 +919 8.945000e-10 2.000000e-01 +920 8.955000e-10 2.000000e-01 +921 8.965000e-10 2.000000e-01 +922 8.975000e-10 2.000000e-01 +923 8.985000e-10 2.000000e-01 +924 8.995000e-10 2.000000e-01 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +925 9.005000e-10 2.000000e-01 +926 9.015000e-10 2.000000e-01 +927 9.025000e-10 2.000000e-01 +928 9.035000e-10 2.000000e-01 +929 9.045000e-10 2.000000e-01 +930 9.055000e-10 2.000000e-01 +931 9.065000e-10 2.000000e-01 +932 9.075000e-10 2.000000e-01 +933 9.085000e-10 2.000000e-01 +934 9.095000e-10 2.000000e-01 +935 9.105000e-10 2.000000e-01 +936 9.115000e-10 2.000000e-01 +937 9.125000e-10 2.000000e-01 +938 9.135000e-10 2.000000e-01 +939 9.145000e-10 2.000000e-01 +940 9.155000e-10 2.000000e-01 +941 9.165000e-10 2.000000e-01 +942 9.175000e-10 2.000000e-01 +943 9.185000e-10 2.000000e-01 +944 9.195000e-10 2.000000e-01 +945 9.200000e-10 2.000000e-01 +946 9.201000e-10 1.998000e-01 +947 9.203000e-10 1.994000e-01 +948 9.207000e-10 1.986000e-01 +949 9.215000e-10 1.970000e-01 +950 9.225000e-10 1.950000e-01 +951 9.235000e-10 1.930000e-01 +952 9.245000e-10 1.910000e-01 +953 9.255000e-10 1.890000e-01 +954 9.265000e-10 1.870000e-01 +955 9.275000e-10 1.850000e-01 +956 9.285000e-10 1.830000e-01 +957 9.295000e-10 1.810000e-01 +958 9.305000e-10 1.790000e-01 +959 9.315000e-10 1.770000e-01 +960 9.325000e-10 1.750000e-01 +961 9.335000e-10 1.730000e-01 +962 9.345000e-10 1.710000e-01 +963 9.355000e-10 1.690000e-01 +964 9.365000e-10 1.670000e-01 +965 9.375000e-10 1.650000e-01 +966 9.385000e-10 1.630000e-01 +967 9.395000e-10 1.610000e-01 +968 9.405000e-10 1.590000e-01 +969 9.415000e-10 1.570000e-01 +970 9.425000e-10 1.550000e-01 +971 9.435000e-10 1.530000e-01 +972 9.445000e-10 1.510000e-01 +973 9.455000e-10 1.490000e-01 +974 9.465000e-10 1.470000e-01 +975 9.475000e-10 1.450000e-01 +976 9.485000e-10 1.430000e-01 +977 9.495000e-10 1.410000e-01 +978 9.505000e-10 1.390000e-01 +979 9.515000e-10 1.370000e-01 +980 9.525000e-10 1.350000e-01 +981 9.535000e-10 1.330000e-01 +982 9.545000e-10 1.310000e-01 + +Index time v(g)/10 +-------------------------------------------------------------------------------- +983 9.555000e-10 1.290000e-01 +984 9.565000e-10 1.270000e-01 +985 9.575000e-10 1.250000e-01 +986 9.585000e-10 1.230000e-01 +987 9.595000e-10 1.210000e-01 +988 9.605000e-10 1.190000e-01 +989 9.615000e-10 1.170000e-01 +990 9.625000e-10 1.150000e-01 +991 9.635000e-10 1.130000e-01 +992 9.645000e-10 1.110000e-01 +993 9.655000e-10 1.090000e-01 +994 9.665000e-10 1.070000e-01 +995 9.675000e-10 1.050000e-01 +996 9.685000e-10 1.030000e-01 +997 9.695000e-10 1.010000e-01 +998 9.705000e-10 9.900000e-02 +999 9.715000e-10 9.700000e-02 +1000 9.725000e-10 9.500000e-02 +1001 9.735000e-10 9.300000e-02 +1002 9.745000e-10 9.100000e-02 +1003 9.755000e-10 8.900000e-02 +1004 9.765000e-10 8.700000e-02 +1005 9.775000e-10 8.500000e-02 +1006 9.785000e-10 8.300000e-02 +1007 9.795000e-10 8.100000e-02 +1008 9.805000e-10 7.900000e-02 +1009 9.815000e-10 7.700000e-02 +1010 9.825000e-10 7.500000e-02 +1011 9.835000e-10 7.300000e-02 +1012 9.845000e-10 7.100000e-02 +1013 9.855000e-10 6.900000e-02 +1014 9.865000e-10 6.700000e-02 +1015 9.875000e-10 6.500000e-02 +1016 9.885000e-10 6.300000e-02 +1017 9.895000e-10 6.100000e-02 +1018 9.905000e-10 5.900000e-02 +1019 9.915000e-10 5.700000e-02 +1020 9.925000e-10 5.500000e-02 +1021 9.935000e-10 5.300000e-02 +1022 9.945000e-10 5.100000e-02 +1023 9.955000e-10 4.900000e-02 +1024 9.965000e-10 4.700000e-02 +1025 9.975000e-10 4.500000e-02 +1026 9.985000e-10 4.300000e-02 +1027 9.995000e-10 4.100000e-02 +1028 1.000000e-09 4.000000e-02 + + + + diff --git a/tests/bsim3soipd/inv2.cir b/tests/bsim3soipd/inv2.cir new file mode 100644 index 000000000..484ed49c1 --- /dev/null +++ b/tests/bsim3soipd/inv2.cir @@ -0,0 +1,17 @@ +* model = BSIMSOI (PD) +* +* +* SOI Inverter - floating body + +vin in 0 dc 2.5 +vdd dd 0 dc 2.5 +vss ss 0 dc 0 +ve e 0 dc 1.25 +m1 out in dd e p1 w=20u l=0.25u +m2 out in ss e n1 w=10u l=0.25u + +.option itl1=500 gmin=1e-25 +.dc vin 0 2.5 0.01 +.print dc v(in), v(out) +.include nmospd.mod +.include pmospd.mod diff --git a/tests/bsim3soipd/inv2.out b/tests/bsim3soipd/inv2.out new file mode 100644 index 000000000..8d98a1836 --- /dev/null +++ b/tests/bsim3soipd/inv2.out @@ -0,0 +1,281 @@ + Reference value : 2.47000e+00 +No. of Data Rows : 251 + +Circuit: * model = BSIMSOI (PD) + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. + * model = BSIMSOI (PD) +-------------------------------------------------------------------------------- +Index v-sweep v(in) v(out) +-------------------------------------------------------------------------------- +0 0.000000e+00 0.000000e+00 2.499999e+00 +1 1.000000e-02 1.000000e-02 2.499998e+00 +2 2.000000e-02 2.000000e-02 2.499998e+00 +3 3.000000e-02 3.000000e-02 2.499997e+00 +4 4.000000e-02 4.000000e-02 2.499996e+00 +5 5.000000e-02 5.000000e-02 2.499994e+00 +6 6.000000e-02 6.000000e-02 2.499991e+00 +7 7.000000e-02 7.000000e-02 2.499986e+00 +8 8.000000e-02 8.000000e-02 2.499980e+00 +9 9.000000e-02 9.000000e-02 2.499970e+00 +10 1.000000e-01 1.000000e-01 2.499955e+00 +11 1.100000e-01 1.100000e-01 2.499934e+00 +12 1.200000e-01 1.200000e-01 2.499903e+00 +13 1.300000e-01 1.300000e-01 2.499859e+00 +14 1.400000e-01 1.400000e-01 2.499799e+00 +15 1.500000e-01 1.500000e-01 2.499717e+00 +16 1.600000e-01 1.600000e-01 2.499607e+00 +17 1.700000e-01 1.700000e-01 2.499461e+00 +18 1.800000e-01 1.800000e-01 2.499270e+00 +19 1.900000e-01 1.900000e-01 2.499024e+00 +20 2.000000e-01 2.000000e-01 2.498710e+00 +21 2.100000e-01 2.100000e-01 2.498318e+00 +22 2.200000e-01 2.200000e-01 2.497836e+00 +23 2.300000e-01 2.300000e-01 2.497253e+00 +24 2.400000e-01 2.400000e-01 2.496562e+00 +25 2.500000e-01 2.500000e-01 2.495756e+00 +26 2.600000e-01 2.600000e-01 2.494834e+00 +27 2.700000e-01 2.700000e-01 2.493792e+00 +28 2.800000e-01 2.800000e-01 2.492633e+00 +29 2.900000e-01 2.900000e-01 2.491358e+00 +30 3.000000e-01 3.000000e-01 2.489971e+00 +31 3.100000e-01 3.100000e-01 2.488475e+00 +32 3.200000e-01 3.200000e-01 2.486875e+00 +33 3.300000e-01 3.300000e-01 2.485175e+00 +34 3.400000e-01 3.400000e-01 2.483378e+00 +35 3.500000e-01 3.500000e-01 2.481488e+00 +36 3.600000e-01 3.600000e-01 2.479508e+00 +37 3.700000e-01 3.700000e-01 2.477441e+00 +38 3.800000e-01 3.800000e-01 2.475290e+00 +39 3.900000e-01 3.900000e-01 2.473056e+00 +40 4.000000e-01 4.000000e-01 2.470782e+00 +41 4.100000e-01 4.100000e-01 2.468387e+00 +42 4.200000e-01 4.200000e-01 2.465913e+00 +43 4.300000e-01 4.300000e-01 2.463361e+00 +44 4.400000e-01 4.400000e-01 2.460731e+00 +45 4.500000e-01 4.500000e-01 2.458023e+00 +46 4.600000e-01 4.600000e-01 2.455238e+00 +47 4.700000e-01 4.700000e-01 2.452373e+00 +48 4.800000e-01 4.800000e-01 2.449430e+00 +49 4.900000e-01 4.900000e-01 2.446406e+00 +50 5.000000e-01 5.000000e-01 2.443302e+00 +51 5.100000e-01 5.100000e-01 2.440115e+00 +52 5.200000e-01 5.200000e-01 2.436845e+00 +53 5.300000e-01 5.300000e-01 2.433490e+00 +54 5.400000e-01 5.400000e-01 2.430049e+00 + +Index v-sweep v(in) v(out) +-------------------------------------------------------------------------------- +55 5.500000e-01 5.500000e-01 2.426520e+00 +56 5.600000e-01 5.600000e-01 2.422900e+00 +57 5.700000e-01 5.700000e-01 2.419189e+00 +58 5.800000e-01 5.800000e-01 2.415383e+00 +59 5.900000e-01 5.900000e-01 2.411481e+00 +60 6.000000e-01 6.000000e-01 2.407479e+00 +61 6.100000e-01 6.100000e-01 2.403376e+00 +62 6.200000e-01 6.200000e-01 2.399169e+00 +63 6.300000e-01 6.300000e-01 2.394854e+00 +64 6.400000e-01 6.400000e-01 2.390428e+00 +65 6.500000e-01 6.500000e-01 2.385889e+00 +66 6.600000e-01 6.600000e-01 2.381231e+00 +67 6.700000e-01 6.700000e-01 2.376453e+00 +68 6.800000e-01 6.800000e-01 2.371548e+00 +69 6.900000e-01 6.900000e-01 2.366514e+00 +70 7.000000e-01 7.000000e-01 2.361346e+00 +71 7.100000e-01 7.100000e-01 2.356038e+00 +72 7.200000e-01 7.200000e-01 2.350585e+00 +73 7.300000e-01 7.300000e-01 2.344982e+00 +74 7.400000e-01 7.400000e-01 2.339222e+00 +75 7.500000e-01 7.500000e-01 2.333300e+00 +76 7.600000e-01 7.600000e-01 2.327208e+00 +77 7.700000e-01 7.700000e-01 2.320938e+00 +78 7.800000e-01 7.800000e-01 2.314483e+00 +79 7.900000e-01 7.900000e-01 2.307833e+00 +80 8.000000e-01 8.000000e-01 2.300980e+00 +81 8.100000e-01 8.100000e-01 2.293913e+00 +82 8.200000e-01 8.200000e-01 2.286621e+00 +83 8.300000e-01 8.300000e-01 2.279092e+00 +84 8.400000e-01 8.400000e-01 2.271312e+00 +85 8.500000e-01 8.500000e-01 2.263267e+00 +86 8.600000e-01 8.600000e-01 2.254941e+00 +87 8.700000e-01 8.700000e-01 2.246317e+00 +88 8.800000e-01 8.800000e-01 2.237375e+00 +89 8.900000e-01 8.900000e-01 2.228093e+00 +90 9.000000e-01 9.000000e-01 2.218448e+00 +91 9.100000e-01 9.100000e-01 2.208412e+00 +92 9.200000e-01 9.200000e-01 2.197956e+00 +93 9.300000e-01 9.300000e-01 2.187045e+00 +94 9.400000e-01 9.400000e-01 2.175640e+00 +95 9.500000e-01 9.500000e-01 2.163697e+00 +96 9.600000e-01 9.600000e-01 2.151164e+00 +97 9.700000e-01 9.700000e-01 2.137982e+00 +98 9.800000e-01 9.800000e-01 2.124081e+00 +99 9.900000e-01 9.900000e-01 2.109377e+00 +100 1.000000e+00 1.000000e+00 2.093773e+00 +101 1.010000e+00 1.010000e+00 2.077147e+00 +102 1.020000e+00 1.020000e+00 2.059352e+00 +103 1.030000e+00 1.030000e+00 2.040203e+00 +104 1.040000e+00 1.040000e+00 2.019463e+00 +105 1.050000e+00 1.050000e+00 1.996826e+00 +106 1.060000e+00 1.060000e+00 1.971884e+00 +107 1.070000e+00 1.070000e+00 1.944084e+00 +108 1.080000e+00 1.080000e+00 1.910492e+00 +109 1.090000e+00 1.090000e+00 1.873867e+00 +110 1.100000e+00 1.100000e+00 1.831532e+00 +111 1.110000e+00 1.110000e+00 1.783130e+00 +112 1.120000e+00 1.120000e+00 1.729458e+00 + +Index v-sweep v(in) v(out) +-------------------------------------------------------------------------------- +113 1.130000e+00 1.130000e+00 1.672095e+00 +114 1.140000e+00 1.140000e+00 1.612626e+00 +115 1.150000e+00 1.150000e+00 1.552549e+00 +116 1.160000e+00 1.160000e+00 1.491943e+00 +117 1.170000e+00 1.170000e+00 1.432297e+00 +118 1.180000e+00 1.180000e+00 1.373873e+00 +119 1.190000e+00 1.190000e+00 1.317154e+00 +120 1.200000e+00 1.200000e+00 1.262585e+00 +121 1.210000e+00 1.210000e+00 1.210554e+00 +122 1.220000e+00 1.220000e+00 1.161308e+00 +123 1.230000e+00 1.230000e+00 1.114785e+00 +124 1.240000e+00 1.240000e+00 1.070345e+00 +125 1.250000e+00 1.250000e+00 1.026307e+00 +126 1.260000e+00 1.260000e+00 9.804299e-01 +127 1.270000e+00 1.270000e+00 9.294541e-01 +128 1.280000e+00 1.280000e+00 8.694885e-01 +129 1.290000e+00 1.290000e+00 8.002735e-01 +130 1.300000e+00 1.300000e+00 7.294759e-01 +131 1.310000e+00 1.310000e+00 6.656970e-01 +132 1.320000e+00 1.320000e+00 6.123182e-01 +133 1.330000e+00 1.330000e+00 5.686657e-01 +134 1.340000e+00 1.340000e+00 5.325773e-01 +135 1.350000e+00 1.350000e+00 5.019922e-01 +136 1.360000e+00 1.360000e+00 4.754187e-01 +137 1.370000e+00 1.370000e+00 4.518595e-01 +138 1.380000e+00 1.380000e+00 4.306467e-01 +139 1.390000e+00 1.390000e+00 4.113193e-01 +140 1.400000e+00 1.400000e+00 3.935474e-01 +141 1.410000e+00 1.410000e+00 3.770864e-01 +142 1.420000e+00 1.420000e+00 3.617492e-01 +143 1.430000e+00 1.430000e+00 3.473890e-01 +144 1.440000e+00 1.440000e+00 3.338879e-01 +145 1.450000e+00 1.450000e+00 3.211498e-01 +146 1.460000e+00 1.460000e+00 3.090946e-01 +147 1.470000e+00 1.470000e+00 2.973578e-01 +148 1.480000e+00 1.480000e+00 2.865129e-01 +149 1.490000e+00 1.490000e+00 2.761639e-01 +150 1.500000e+00 1.500000e+00 2.662793e-01 +151 1.510000e+00 1.510000e+00 2.568222e-01 +152 1.520000e+00 1.520000e+00 2.477604e-01 +153 1.530000e+00 1.530000e+00 2.390652e-01 +154 1.540000e+00 1.540000e+00 2.307112e-01 +155 1.550000e+00 1.550000e+00 2.226758e-01 +156 1.560000e+00 1.560000e+00 2.149383e-01 +157 1.570000e+00 1.570000e+00 2.074804e-01 +158 1.580000e+00 1.580000e+00 2.002854e-01 +159 1.590000e+00 1.590000e+00 1.933382e-01 +160 1.600000e+00 1.600000e+00 1.866248e-01 +161 1.610000e+00 1.610000e+00 1.801328e-01 +162 1.620000e+00 1.620000e+00 1.738505e-01 +163 1.630000e+00 1.630000e+00 1.677672e-01 +164 1.640000e+00 1.640000e+00 1.618733e-01 +165 1.650000e+00 1.650000e+00 1.561596e-01 +166 1.660000e+00 1.660000e+00 1.506179e-01 +167 1.670000e+00 1.670000e+00 1.452404e-01 +168 1.680000e+00 1.680000e+00 1.400200e-01 +169 1.690000e+00 1.690000e+00 1.349498e-01 +170 1.700000e+00 1.700000e+00 1.300239e-01 + +Index v-sweep v(in) v(out) +-------------------------------------------------------------------------------- +171 1.710000e+00 1.710000e+00 1.252363e-01 +172 1.720000e+00 1.720000e+00 1.205816e-01 +173 1.730000e+00 1.730000e+00 1.160548e-01 +174 1.740000e+00 1.740000e+00 1.116512e-01 +175 1.750000e+00 1.750000e+00 1.073663e-01 +176 1.760000e+00 1.760000e+00 1.031960e-01 +177 1.770000e+00 1.770000e+00 9.913640e-02 +178 1.780000e+00 1.780000e+00 9.518378e-02 +179 1.790000e+00 1.790000e+00 9.133472e-02 +180 1.800000e+00 1.800000e+00 8.758600e-02 +181 1.810000e+00 1.810000e+00 8.393457e-02 +182 1.820000e+00 1.820000e+00 8.037755e-02 +183 1.830000e+00 1.830000e+00 7.691227e-02 +184 1.840000e+00 1.840000e+00 7.353618e-02 +185 1.850000e+00 1.850000e+00 7.024692e-02 +186 1.860000e+00 1.860000e+00 6.704225e-02 +187 1.870000e+00 1.870000e+00 6.392009e-02 +188 1.880000e+00 1.880000e+00 6.087849e-02 +189 1.890000e+00 1.890000e+00 5.791562e-02 +190 1.900000e+00 1.900000e+00 5.502981e-02 +191 1.910000e+00 1.910000e+00 5.221950e-02 +192 1.920000e+00 1.920000e+00 4.948326e-02 +193 1.930000e+00 1.930000e+00 4.681981e-02 +194 1.940000e+00 1.940000e+00 4.422799e-02 +195 1.950000e+00 1.950000e+00 4.170678e-02 +196 1.960000e+00 1.960000e+00 3.925531e-02 +197 1.970000e+00 1.970000e+00 3.687285e-02 +198 1.980000e+00 1.980000e+00 3.455885e-02 +199 1.990000e+00 1.990000e+00 3.234669e-02 +200 2.000000e+00 2.000000e+00 3.016853e-02 +201 2.010000e+00 2.010000e+00 2.805831e-02 +202 2.020000e+00 2.020000e+00 2.601623e-02 +203 2.030000e+00 2.030000e+00 2.404273e-02 +204 2.040000e+00 2.040000e+00 2.213847e-02 +205 2.050000e+00 2.050000e+00 2.030439e-02 +206 2.060000e+00 2.060000e+00 1.854170e-02 +207 2.070000e+00 2.070000e+00 1.685186e-02 +208 2.080000e+00 2.080000e+00 1.523664e-02 +209 2.090000e+00 2.090000e+00 1.369808e-02 +210 2.100000e+00 2.100000e+00 1.223845e-02 +211 2.110000e+00 2.110000e+00 1.086024e-02 +212 2.120000e+00 2.120000e+00 9.566075e-03 +213 2.130000e+00 2.130000e+00 8.358601e-03 +214 2.140000e+00 2.140000e+00 7.240352e-03 +215 2.150000e+00 2.150000e+00 6.213554e-03 +216 2.160000e+00 2.160000e+00 5.279894e-03 +217 2.170000e+00 2.170000e+00 4.440255e-03 +218 2.180000e+00 2.180000e+00 3.694430e-03 +219 2.190000e+00 2.190000e+00 3.040858e-03 +220 2.200000e+00 2.200000e+00 2.476428e-03 +221 2.210000e+00 2.210000e+00 1.996392e-03 +222 2.220000e+00 2.220000e+00 1.594448e-03 +223 2.230000e+00 2.230000e+00 1.262998e-03 +224 2.240000e+00 2.240000e+00 9.935713e-04 +225 2.250000e+00 2.250000e+00 7.773429e-04 +226 2.260000e+00 2.260000e+00 6.056638e-04 +227 2.270000e+00 2.270000e+00 4.705029e-04 +228 2.280000e+00 2.280000e+00 3.647470e-04 + +Index v-sweep v(in) v(out) +-------------------------------------------------------------------------------- +229 2.290000e+00 2.290000e+00 2.823411e-04 +230 2.300000e+00 2.300000e+00 2.182925e-04 +231 2.310000e+00 2.310000e+00 1.685827e-04 +232 2.320000e+00 2.320000e+00 1.300320e-04 +233 2.330000e+00 2.330000e+00 1.001521e-04 +234 2.340000e+00 2.340000e+00 7.700750e-05 +235 2.350000e+00 2.350000e+00 5.909614e-05 +236 2.360000e+00 2.360000e+00 4.525247e-05 +237 2.370000e+00 2.370000e+00 3.457078e-05 +238 2.380000e+00 2.380000e+00 2.634596e-05 +239 2.390000e+00 2.390000e+00 2.002816e-05 +240 2.400000e+00 2.400000e+00 1.518814e-05 +241 2.410000e+00 2.410000e+00 1.149079e-05 +242 2.420000e+00 2.420000e+00 8.674635e-06 +243 2.430000e+00 2.430000e+00 6.536015e-06 +244 2.440000e+00 2.440000e+00 4.916669e-06 +245 2.450000e+00 2.450000e+00 3.693987e-06 +246 2.460000e+00 2.460000e+00 2.773298e-06 +247 2.470000e+00 2.470000e+00 2.081773e-06 +248 2.480000e+00 2.480000e+00 1.563599e-06 +249 2.490000e+00 2.490000e+00 1.176165e-06 +250 2.500000e+00 2.500000e+00 8.870574e-07 + + + + diff --git a/tests/bsim3soipd/t3.cir b/tests/bsim3soipd/t3.cir new file mode 100644 index 000000000..a591061a9 --- /dev/null +++ b/tests/bsim3soipd/t3.cir @@ -0,0 +1,18 @@ +*model = BSIMSOI (PD) +*Berkeley Spice Compatibility +* +* SOI NMOSFET, floating body simulation + +vd d 0 dc 1.5 +vs s 0 dc 0 +ve e 0 dc 0 +vg g 0 dc 3 + + +m1 d g s e n1 w=10u l=0.25u + +.option gmin=1e-25 itl1=500 +.dc vd 0 3 0.01 vg 0.5 3 0.5 +.print dc v(g), i(vs) +.include nmospd.mod + diff --git a/tests/bsim3soipd/t3.out b/tests/bsim3soipd/t3.out new file mode 100644 index 000000000..9dff63c6d --- /dev/null +++ b/tests/bsim3soipd/t3.out @@ -0,0 +1,1915 @@ + Reference value : 2.77000e+00 +No. of Data Rows : 1806 + +Circuit: *model = BSIMSOI (PD) + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. + *model = BSIMSOI (PD) +-------------------------------------------------------------------------------- +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 5.000000e-01 1.478176e-42 +1 1.000000e-02 5.000000e-01 2.933649e-06 +2 2.000000e-02 5.000000e-01 5.424818e-06 +3 3.000000e-02 5.000000e-01 7.494120e-06 +4 4.000000e-02 5.000000e-01 9.168763e-06 +5 5.000000e-02 5.000000e-01 1.048555e-05 +6 6.000000e-02 5.000000e-01 1.149269e-05 +7 7.000000e-02 5.000000e-01 1.224807e-05 +8 8.000000e-02 5.000000e-01 1.281282e-05 +9 9.000000e-02 5.000000e-01 1.324287e-05 +10 1.000000e-01 5.000000e-01 1.358286e-05 +11 1.100000e-01 5.000000e-01 1.386488e-05 +12 1.200000e-01 5.000000e-01 1.411044e-05 +13 1.300000e-01 5.000000e-01 1.434292e-05 +14 1.400000e-01 5.000000e-01 1.454858e-05 +15 1.500000e-01 5.000000e-01 1.474768e-05 +16 1.600000e-01 5.000000e-01 1.494352e-05 +17 1.700000e-01 5.000000e-01 1.513834e-05 +18 1.800000e-01 5.000000e-01 1.533368e-05 +19 1.900000e-01 5.000000e-01 1.553066e-05 +20 2.000000e-01 5.000000e-01 1.573012e-05 +21 2.100000e-01 5.000000e-01 1.593269e-05 +22 2.200000e-01 5.000000e-01 1.613886e-05 +23 2.300000e-01 5.000000e-01 1.634904e-05 +24 2.400000e-01 5.000000e-01 1.656355e-05 +25 2.500000e-01 5.000000e-01 1.678267e-05 +26 2.600000e-01 5.000000e-01 1.700664e-05 +27 2.700000e-01 5.000000e-01 1.723565e-05 +28 2.800000e-01 5.000000e-01 1.746991e-05 +29 2.900000e-01 5.000000e-01 1.770956e-05 +30 3.000000e-01 5.000000e-01 1.795475e-05 +31 3.100000e-01 5.000000e-01 1.820563e-05 +32 3.200000e-01 5.000000e-01 1.846232e-05 +33 3.300000e-01 5.000000e-01 1.872494e-05 +34 3.400000e-01 5.000000e-01 1.899359e-05 +35 3.500000e-01 5.000000e-01 1.926838e-05 +36 3.600000e-01 5.000000e-01 1.954941e-05 +37 3.700000e-01 5.000000e-01 1.983677e-05 +38 3.800000e-01 5.000000e-01 2.013054e-05 +39 3.900000e-01 5.000000e-01 2.043082e-05 +40 4.000000e-01 5.000000e-01 2.073770e-05 +41 4.100000e-01 5.000000e-01 2.105124e-05 +42 4.200000e-01 5.000000e-01 2.137153e-05 +43 4.300000e-01 5.000000e-01 2.169865e-05 +44 4.400000e-01 5.000000e-01 2.203268e-05 +45 4.500000e-01 5.000000e-01 2.237369e-05 +46 4.600000e-01 5.000000e-01 2.272177e-05 +47 4.700000e-01 5.000000e-01 2.307700e-05 +48 4.800000e-01 5.000000e-01 2.343947e-05 +49 4.900000e-01 5.000000e-01 2.380925e-05 +50 5.000000e-01 5.000000e-01 2.418645e-05 +51 5.100000e-01 5.000000e-01 2.457116e-05 +52 5.200000e-01 5.000000e-01 2.496350e-05 +53 5.300000e-01 5.000000e-01 2.536357e-05 +54 5.400000e-01 5.000000e-01 2.577151e-05 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +55 5.500000e-01 5.000000e-01 2.618747e-05 +56 5.600000e-01 5.000000e-01 2.661159e-05 +57 5.700000e-01 5.000000e-01 2.704406e-05 +58 5.800000e-01 5.000000e-01 2.748507e-05 +59 5.900000e-01 5.000000e-01 2.793486e-05 +60 6.000000e-01 5.000000e-01 2.839367e-05 +61 6.100000e-01 5.000000e-01 2.886181e-05 +62 6.200000e-01 5.000000e-01 2.933958e-05 +63 6.300000e-01 5.000000e-01 2.982738e-05 +64 6.400000e-01 5.000000e-01 3.032562e-05 +65 6.500000e-01 5.000000e-01 3.083478e-05 +66 6.600000e-01 5.000000e-01 3.135542e-05 +67 6.700000e-01 5.000000e-01 3.188814e-05 +68 6.800000e-01 5.000000e-01 3.243364e-05 +69 6.900000e-01 5.000000e-01 3.299273e-05 +70 7.000000e-01 5.000000e-01 3.356628e-05 +71 7.100000e-01 5.000000e-01 3.415530e-05 +72 7.200000e-01 5.000000e-01 3.476091e-05 +73 7.300000e-01 5.000000e-01 3.538438e-05 +74 7.400000e-01 5.000000e-01 3.602712e-05 +75 7.500000e-01 5.000000e-01 3.669070e-05 +76 7.600000e-01 5.000000e-01 3.737686e-05 +77 7.700000e-01 5.000000e-01 3.808756e-05 +78 7.800000e-01 5.000000e-01 3.882492e-05 +79 7.900000e-01 5.000000e-01 3.959132e-05 +80 8.000000e-01 5.000000e-01 4.038934e-05 +81 8.100000e-01 5.000000e-01 4.122182e-05 +82 8.200000e-01 5.000000e-01 4.209184e-05 +83 8.300000e-01 5.000000e-01 4.300273e-05 +84 8.400000e-01 5.000000e-01 4.395807e-05 +85 8.500000e-01 5.000000e-01 4.496167e-05 +86 8.600000e-01 5.000000e-01 4.601760e-05 +87 8.700000e-01 5.000000e-01 4.713008e-05 +88 8.800000e-01 5.000000e-01 4.830350e-05 +89 8.900000e-01 5.000000e-01 4.954234e-05 +90 9.000000e-01 5.000000e-01 5.085110e-05 +91 9.100000e-01 5.000000e-01 5.223417e-05 +92 9.200000e-01 5.000000e-01 5.369578e-05 +93 9.300000e-01 5.000000e-01 5.523981e-05 +94 9.400000e-01 5.000000e-01 5.686964e-05 +95 9.500000e-01 5.000000e-01 5.858802e-05 +96 9.600000e-01 5.000000e-01 6.039692e-05 +97 9.700000e-01 5.000000e-01 6.229733e-05 +98 9.800000e-01 5.000000e-01 6.428918e-05 +99 9.900000e-01 5.000000e-01 6.637124e-05 +100 1.000000e+00 5.000000e-01 6.854109e-05 +101 1.010000e+00 5.000000e-01 7.079515e-05 +102 1.020000e+00 5.000000e-01 7.312874e-05 +103 1.030000e+00 5.000000e-01 7.553625e-05 +104 1.040000e+00 5.000000e-01 7.801133e-05 +105 1.050000e+00 5.000000e-01 8.054708e-05 +106 1.060000e+00 5.000000e-01 8.315532e-05 +107 1.070000e+00 5.000000e-01 8.581955e-05 +108 1.080000e+00 5.000000e-01 8.852644e-05 +109 1.090000e+00 5.000000e-01 9.126681e-05 +110 1.100000e+00 5.000000e-01 9.403267e-05 +111 1.110000e+00 5.000000e-01 9.681718e-05 +112 1.120000e+00 5.000000e-01 9.961452e-05 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +113 1.130000e+00 5.000000e-01 1.024198e-04 +114 1.140000e+00 5.000000e-01 1.052289e-04 +115 1.150000e+00 5.000000e-01 1.080387e-04 +116 1.160000e+00 5.000000e-01 1.108463e-04 +117 1.170000e+00 5.000000e-01 1.136497e-04 +118 1.180000e+00 5.000000e-01 1.164472e-04 +119 1.190000e+00 5.000000e-01 1.192377e-04 +120 1.200000e+00 5.000000e-01 1.220201e-04 +121 1.210000e+00 5.000000e-01 1.247939e-04 +122 1.220000e+00 5.000000e-01 1.275586e-04 +123 1.230000e+00 5.000000e-01 1.303141e-04 +124 1.240000e+00 5.000000e-01 1.330602e-04 +125 1.250000e+00 5.000000e-01 1.357969e-04 +126 1.260000e+00 5.000000e-01 1.385244e-04 +127 1.270000e+00 5.000000e-01 1.412429e-04 +128 1.280000e+00 5.000000e-01 1.439526e-04 +129 1.290000e+00 5.000000e-01 1.466538e-04 +130 1.300000e+00 5.000000e-01 1.493468e-04 +131 1.310000e+00 5.000000e-01 1.520319e-04 +132 1.320000e+00 5.000000e-01 1.547095e-04 +133 1.330000e+00 5.000000e-01 1.573797e-04 +134 1.340000e+00 5.000000e-01 1.600431e-04 +135 1.350000e+00 5.000000e-01 1.627000e-04 +136 1.360000e+00 5.000000e-01 1.653505e-04 +137 1.370000e+00 5.000000e-01 1.679951e-04 +138 1.380000e+00 5.000000e-01 1.706341e-04 +139 1.390000e+00 5.000000e-01 1.732677e-04 +140 1.400000e+00 5.000000e-01 1.758962e-04 +141 1.410000e+00 5.000000e-01 1.785199e-04 +142 1.420000e+00 5.000000e-01 1.811390e-04 +143 1.430000e+00 5.000000e-01 1.837538e-04 +144 1.440000e+00 5.000000e-01 1.863645e-04 +145 1.450000e+00 5.000000e-01 1.889713e-04 +146 1.460000e+00 5.000000e-01 1.915744e-04 +147 1.470000e+00 5.000000e-01 1.941740e-04 +148 1.480000e+00 5.000000e-01 1.967704e-04 +149 1.490000e+00 5.000000e-01 1.993636e-04 +150 1.500000e+00 5.000000e-01 2.019539e-04 +151 1.510000e+00 5.000000e-01 2.045413e-04 +152 1.520000e+00 5.000000e-01 2.071261e-04 +153 1.530000e+00 5.000000e-01 2.097084e-04 +154 1.540000e+00 5.000000e-01 2.122883e-04 +155 1.550000e+00 5.000000e-01 2.148659e-04 +156 1.560000e+00 5.000000e-01 2.174414e-04 +157 1.570000e+00 5.000000e-01 2.200148e-04 +158 1.580000e+00 5.000000e-01 2.225863e-04 +159 1.590000e+00 5.000000e-01 2.251560e-04 +160 1.600000e+00 5.000000e-01 2.277239e-04 +161 1.610000e+00 5.000000e-01 2.302901e-04 +162 1.620000e+00 5.000000e-01 2.328548e-04 +163 1.630000e+00 5.000000e-01 2.354179e-04 +164 1.640000e+00 5.000000e-01 2.379796e-04 +165 1.650000e+00 5.000000e-01 2.405399e-04 +166 1.660000e+00 5.000000e-01 2.430988e-04 +167 1.670000e+00 5.000000e-01 2.456565e-04 +168 1.680000e+00 5.000000e-01 2.482129e-04 +169 1.690000e+00 5.000000e-01 2.507682e-04 +170 1.700000e+00 5.000000e-01 2.533223e-04 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +171 1.710000e+00 5.000000e-01 2.558752e-04 +172 1.720000e+00 5.000000e-01 2.584270e-04 +173 1.730000e+00 5.000000e-01 2.609778e-04 +174 1.740000e+00 5.000000e-01 2.635275e-04 +175 1.750000e+00 5.000000e-01 2.660762e-04 +176 1.760000e+00 5.000000e-01 2.686238e-04 +177 1.770000e+00 5.000000e-01 2.711704e-04 +178 1.780000e+00 5.000000e-01 2.737159e-04 +179 1.790000e+00 5.000000e-01 2.762604e-04 +180 1.800000e+00 5.000000e-01 2.788039e-04 +181 1.810000e+00 5.000000e-01 2.813463e-04 +182 1.820000e+00 5.000000e-01 2.838877e-04 +183 1.830000e+00 5.000000e-01 2.864280e-04 +184 1.840000e+00 5.000000e-01 2.889672e-04 +185 1.850000e+00 5.000000e-01 2.915053e-04 +186 1.860000e+00 5.000000e-01 2.940423e-04 +187 1.870000e+00 5.000000e-01 2.965781e-04 +188 1.880000e+00 5.000000e-01 2.991127e-04 +189 1.890000e+00 5.000000e-01 3.016462e-04 +190 1.900000e+00 5.000000e-01 3.041784e-04 +191 1.910000e+00 5.000000e-01 3.067094e-04 +192 1.920000e+00 5.000000e-01 3.092391e-04 +193 1.930000e+00 5.000000e-01 3.117675e-04 +194 1.940000e+00 5.000000e-01 3.142946e-04 +195 1.950000e+00 5.000000e-01 3.168203e-04 +196 1.960000e+00 5.000000e-01 3.193446e-04 +197 1.970000e+00 5.000000e-01 3.218676e-04 +198 1.980000e+00 5.000000e-01 3.243891e-04 +199 1.990000e+00 5.000000e-01 3.269091e-04 +200 2.000000e+00 5.000000e-01 3.294277e-04 +201 2.010000e+00 5.000000e-01 3.319447e-04 +202 2.020000e+00 5.000000e-01 3.344603e-04 +203 2.030000e+00 5.000000e-01 3.369743e-04 +204 2.040000e+00 5.000000e-01 3.394867e-04 +205 2.050000e+00 5.000000e-01 3.419975e-04 +206 2.060000e+00 5.000000e-01 3.445068e-04 +207 2.070000e+00 5.000000e-01 3.470144e-04 +208 2.080000e+00 5.000000e-01 3.495205e-04 +209 2.090000e+00 5.000000e-01 3.520248e-04 +210 2.100000e+00 5.000000e-01 3.545275e-04 +211 2.110000e+00 5.000000e-01 3.570286e-04 +212 2.120000e+00 5.000000e-01 3.595280e-04 +213 2.130000e+00 5.000000e-01 3.620257e-04 +214 2.140000e+00 5.000000e-01 3.645218e-04 +215 2.150000e+00 5.000000e-01 3.670161e-04 +216 2.160000e+00 5.000000e-01 3.695088e-04 +217 2.170000e+00 5.000000e-01 3.719997e-04 +218 2.180000e+00 5.000000e-01 3.744890e-04 +219 2.190000e+00 5.000000e-01 3.769765e-04 +220 2.200000e+00 5.000000e-01 3.794624e-04 +221 2.210000e+00 5.000000e-01 3.819465e-04 +222 2.220000e+00 5.000000e-01 3.844290e-04 +223 2.230000e+00 5.000000e-01 3.869098e-04 +224 2.240000e+00 5.000000e-01 3.893889e-04 +225 2.250000e+00 5.000000e-01 3.918662e-04 +226 2.260000e+00 5.000000e-01 3.943420e-04 +227 2.270000e+00 5.000000e-01 3.968160e-04 +228 2.280000e+00 5.000000e-01 3.992884e-04 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +229 2.290000e+00 5.000000e-01 4.017590e-04 +230 2.300000e+00 5.000000e-01 4.042281e-04 +231 2.310000e+00 5.000000e-01 4.066955e-04 +232 2.320000e+00 5.000000e-01 4.091612e-04 +233 2.330000e+00 5.000000e-01 4.116253e-04 +234 2.340000e+00 5.000000e-01 4.140878e-04 +235 2.350000e+00 5.000000e-01 4.165487e-04 +236 2.360000e+00 5.000000e-01 4.190080e-04 +237 2.370000e+00 5.000000e-01 4.214657e-04 +238 2.380000e+00 5.000000e-01 4.239218e-04 +239 2.390000e+00 5.000000e-01 4.263763e-04 +240 2.400000e+00 5.000000e-01 4.288293e-04 +241 2.410000e+00 5.000000e-01 4.312807e-04 +242 2.420000e+00 5.000000e-01 4.337306e-04 +243 2.430000e+00 5.000000e-01 4.361789e-04 +244 2.440000e+00 5.000000e-01 4.386258e-04 +245 2.450000e+00 5.000000e-01 4.410711e-04 +246 2.460000e+00 5.000000e-01 4.435150e-04 +247 2.470000e+00 5.000000e-01 4.459573e-04 +248 2.480000e+00 5.000000e-01 4.483982e-04 +249 2.490000e+00 5.000000e-01 4.508377e-04 +250 2.500000e+00 5.000000e-01 4.532757e-04 +251 2.510000e+00 5.000000e-01 4.557123e-04 +252 2.520000e+00 5.000000e-01 4.581475e-04 +253 2.530000e+00 5.000000e-01 4.605813e-04 +254 2.540000e+00 5.000000e-01 4.630137e-04 +255 2.550000e+00 5.000000e-01 4.654448e-04 +256 2.560000e+00 5.000000e-01 4.678745e-04 +257 2.570000e+00 5.000000e-01 4.703028e-04 +258 2.580000e+00 5.000000e-01 4.727299e-04 +259 2.590000e+00 5.000000e-01 4.751556e-04 +260 2.600000e+00 5.000000e-01 4.775800e-04 +261 2.610000e+00 5.000000e-01 4.800032e-04 +262 2.620000e+00 5.000000e-01 4.824250e-04 +263 2.630000e+00 5.000000e-01 4.848457e-04 +264 2.640000e+00 5.000000e-01 4.872650e-04 +265 2.650000e+00 5.000000e-01 4.896832e-04 +266 2.660000e+00 5.000000e-01 4.921001e-04 +267 2.670000e+00 5.000000e-01 4.945159e-04 +268 2.680000e+00 5.000000e-01 4.969305e-04 +269 2.690000e+00 5.000000e-01 4.993439e-04 +270 2.700000e+00 5.000000e-01 5.017561e-04 +271 2.710000e+00 5.000000e-01 5.041673e-04 +272 2.720000e+00 5.000000e-01 5.065773e-04 +273 2.730000e+00 5.000000e-01 5.089862e-04 +274 2.740000e+00 5.000000e-01 5.113940e-04 +275 2.750000e+00 5.000000e-01 5.138007e-04 +276 2.760000e+00 5.000000e-01 5.162064e-04 +277 2.770000e+00 5.000000e-01 5.186110e-04 +278 2.780000e+00 5.000000e-01 5.210146e-04 +279 2.790000e+00 5.000000e-01 5.234172e-04 +280 2.800000e+00 5.000000e-01 5.258188e-04 +281 2.810000e+00 5.000000e-01 5.282194e-04 +282 2.820000e+00 5.000000e-01 5.306190e-04 +283 2.830000e+00 5.000000e-01 5.330177e-04 +284 2.840000e+00 5.000000e-01 5.354155e-04 +285 2.850000e+00 5.000000e-01 5.378123e-04 +286 2.860000e+00 5.000000e-01 5.402082e-04 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +287 2.870000e+00 5.000000e-01 5.426032e-04 +288 2.880000e+00 5.000000e-01 5.449974e-04 +289 2.890000e+00 5.000000e-01 5.473907e-04 +290 2.900000e+00 5.000000e-01 5.497831e-04 +291 2.910000e+00 5.000000e-01 5.521747e-04 +292 2.920000e+00 5.000000e-01 5.545655e-04 +293 2.930000e+00 5.000000e-01 5.569555e-04 +294 2.940000e+00 5.000000e-01 5.593448e-04 +295 2.950000e+00 5.000000e-01 5.617332e-04 +296 2.960000e+00 5.000000e-01 5.641209e-04 +297 2.970000e+00 5.000000e-01 5.665079e-04 +298 2.980000e+00 5.000000e-01 5.688941e-04 +299 2.990000e+00 5.000000e-01 5.712796e-04 +300 3.000000e+00 5.000000e-01 5.736645e-04 +301 0.000000e+00 1.000000e+00 -3.547623e-41 +302 1.000000e-02 1.000000e+00 3.715407e-05 +303 2.000000e-02 1.000000e+00 7.321271e-05 +304 3.000000e-02 1.000000e+00 1.081949e-04 +305 4.000000e-02 1.000000e+00 1.421186e-04 +306 5.000000e-02 1.000000e+00 1.750005e-04 +307 6.000000e-02 1.000000e+00 2.068564e-04 +308 7.000000e-02 1.000000e+00 2.377013e-04 +309 8.000000e-02 1.000000e+00 2.675495e-04 +310 9.000000e-02 1.000000e+00 2.964147e-04 +311 1.000000e-01 1.000000e+00 3.243101e-04 +312 1.100000e-01 1.000000e+00 3.512487e-04 +313 1.200000e-01 1.000000e+00 3.772430e-04 +314 1.300000e-01 1.000000e+00 4.023054e-04 +315 1.400000e-01 1.000000e+00 4.264481e-04 +316 1.500000e-01 1.000000e+00 4.496832e-04 +317 1.600000e-01 1.000000e+00 4.724684e-04 +318 1.700000e-01 1.000000e+00 4.939185e-04 +319 1.800000e-01 1.000000e+00 5.144968e-04 +320 1.900000e-01 1.000000e+00 5.342157e-04 +321 2.000000e-01 1.000000e+00 5.530872e-04 +322 2.100000e-01 1.000000e+00 5.711238e-04 +323 2.200000e-01 1.000000e+00 5.883381e-04 +324 2.300000e-01 1.000000e+00 6.047429e-04 +325 2.400000e-01 1.000000e+00 6.203516e-04 +326 2.500000e-01 1.000000e+00 6.351782e-04 +327 2.600000e-01 1.000000e+00 6.492373e-04 +328 2.700000e-01 1.000000e+00 6.625447e-04 +329 2.800000e-01 1.000000e+00 6.751172e-04 +330 2.900000e-01 1.000000e+00 6.869730e-04 +331 3.000000e-01 1.000000e+00 6.981323e-04 +332 3.100000e-01 1.000000e+00 7.086173e-04 +333 3.200000e-01 1.000000e+00 7.184528e-04 +334 3.300000e-01 1.000000e+00 7.276660e-04 +335 3.400000e-01 1.000000e+00 7.362876e-04 +336 3.500000e-01 1.000000e+00 7.443511e-04 +337 3.600000e-01 1.000000e+00 7.518929e-04 +338 3.700000e-01 1.000000e+00 7.589521e-04 +339 3.800000e-01 1.000000e+00 7.655696e-04 +340 3.900000e-01 1.000000e+00 7.717874e-04 +341 4.000000e-01 1.000000e+00 7.776473e-04 +342 4.100000e-01 1.000000e+00 7.831903e-04 +343 4.200000e-01 1.000000e+00 7.884548e-04 +344 4.300000e-01 1.000000e+00 7.934768e-04 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +345 4.400000e-01 1.000000e+00 7.982888e-04 +346 4.500000e-01 1.000000e+00 8.029197e-04 +347 4.600000e-01 1.000000e+00 8.073950e-04 +348 4.700000e-01 1.000000e+00 8.117367e-04 +349 4.800000e-01 1.000000e+00 8.159639e-04 +350 4.900000e-01 1.000000e+00 8.200930e-04 +351 5.000000e-01 1.000000e+00 8.241379e-04 +352 5.100000e-01 1.000000e+00 8.281107e-04 +353 5.200000e-01 1.000000e+00 8.320217e-04 +354 5.300000e-01 1.000000e+00 8.358797e-04 +355 5.400000e-01 1.000000e+00 8.396924e-04 +356 5.500000e-01 1.000000e+00 8.434666e-04 +357 5.600000e-01 1.000000e+00 8.472083e-04 +358 5.700000e-01 1.000000e+00 8.509228e-04 +359 5.800000e-01 1.000000e+00 8.546151e-04 +360 5.900000e-01 1.000000e+00 8.582896e-04 +361 6.000000e-01 1.000000e+00 8.619507e-04 +362 6.100000e-01 1.000000e+00 8.656027e-04 +363 6.200000e-01 1.000000e+00 8.692496e-04 +364 6.300000e-01 1.000000e+00 8.728958e-04 +365 6.400000e-01 1.000000e+00 8.765457e-04 +366 6.500000e-01 1.000000e+00 8.802041e-04 +367 6.600000e-01 1.000000e+00 8.838759e-04 +368 6.700000e-01 1.000000e+00 8.875669e-04 +369 6.800000e-01 1.000000e+00 8.912829e-04 +370 6.900000e-01 1.000000e+00 8.950309e-04 +371 7.000000e-01 1.000000e+00 8.988182e-04 +372 7.100000e-01 1.000000e+00 9.026533e-04 +373 7.200000e-01 1.000000e+00 9.065454e-04 +374 7.300000e-01 1.000000e+00 9.105048e-04 +375 7.400000e-01 1.000000e+00 9.145426e-04 +376 7.500000e-01 1.000000e+00 9.186715e-04 +377 7.600000e-01 1.000000e+00 9.229047e-04 +378 7.700000e-01 1.000000e+00 9.272569e-04 +379 7.800000e-01 1.000000e+00 9.317435e-04 +380 7.900000e-01 1.000000e+00 9.363810e-04 +381 8.000000e-01 1.000000e+00 9.411863e-04 +382 8.100000e-01 1.000000e+00 9.461768e-04 +383 8.200000e-01 1.000000e+00 9.513700e-04 +384 8.300000e-01 1.000000e+00 9.567827e-04 +385 8.400000e-01 1.000000e+00 9.624311e-04 +386 8.500000e-01 1.000000e+00 9.683298e-04 +387 8.600000e-01 1.000000e+00 9.744915e-04 +388 8.700000e-01 1.000000e+00 9.809259e-04 +389 8.800000e-01 1.000000e+00 9.876399e-04 +390 8.900000e-01 1.000000e+00 9.946365e-04 +391 9.000000e-01 1.000000e+00 1.001914e-03 +392 9.100000e-01 1.000000e+00 1.009468e-03 +393 9.200000e-01 1.000000e+00 1.017288e-03 +394 9.300000e-01 1.000000e+00 1.025359e-03 +395 9.400000e-01 1.000000e+00 1.033663e-03 +396 9.500000e-01 1.000000e+00 1.042178e-03 +397 9.600000e-01 1.000000e+00 1.050879e-03 +398 9.700000e-01 1.000000e+00 1.059740e-03 +399 9.800000e-01 1.000000e+00 1.068731e-03 +400 9.900000e-01 1.000000e+00 1.077824e-03 +401 1.000000e+00 1.000000e+00 1.086989e-03 +402 1.010000e+00 1.000000e+00 1.096200e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +403 1.020000e+00 1.000000e+00 1.105481e-03 +404 1.030000e+00 1.000000e+00 1.114797e-03 +405 1.040000e+00 1.000000e+00 1.124094e-03 +406 1.050000e+00 1.000000e+00 1.133346e-03 +407 1.060000e+00 1.000000e+00 1.142531e-03 +408 1.070000e+00 1.000000e+00 1.151634e-03 +409 1.080000e+00 1.000000e+00 1.160643e-03 +410 1.090000e+00 1.000000e+00 1.169548e-03 +411 1.100000e+00 1.000000e+00 1.178344e-03 +412 1.110000e+00 1.000000e+00 1.187027e-03 +413 1.120000e+00 1.000000e+00 1.195595e-03 +414 1.130000e+00 1.000000e+00 1.204047e-03 +415 1.140000e+00 1.000000e+00 1.212385e-03 +416 1.150000e+00 1.000000e+00 1.220610e-03 +417 1.160000e+00 1.000000e+00 1.228724e-03 +418 1.170000e+00 1.000000e+00 1.236730e-03 +419 1.180000e+00 1.000000e+00 1.244631e-03 +420 1.190000e+00 1.000000e+00 1.252430e-03 +421 1.200000e+00 1.000000e+00 1.260130e-03 +422 1.210000e+00 1.000000e+00 1.267736e-03 +423 1.220000e+00 1.000000e+00 1.275250e-03 +424 1.230000e+00 1.000000e+00 1.282676e-03 +425 1.240000e+00 1.000000e+00 1.290018e-03 +426 1.250000e+00 1.000000e+00 1.297279e-03 +427 1.260000e+00 1.000000e+00 1.304462e-03 +428 1.270000e+00 1.000000e+00 1.311570e-03 +429 1.280000e+00 1.000000e+00 1.318605e-03 +430 1.290000e+00 1.000000e+00 1.325572e-03 +431 1.300000e+00 1.000000e+00 1.332472e-03 +432 1.310000e+00 1.000000e+00 1.339309e-03 +433 1.320000e+00 1.000000e+00 1.346084e-03 +434 1.330000e+00 1.000000e+00 1.352800e-03 +435 1.340000e+00 1.000000e+00 1.359458e-03 +436 1.350000e+00 1.000000e+00 1.366062e-03 +437 1.360000e+00 1.000000e+00 1.372614e-03 +438 1.370000e+00 1.000000e+00 1.379114e-03 +439 1.380000e+00 1.000000e+00 1.385565e-03 +440 1.390000e+00 1.000000e+00 1.391968e-03 +441 1.400000e+00 1.000000e+00 1.398325e-03 +442 1.410000e+00 1.000000e+00 1.404638e-03 +443 1.420000e+00 1.000000e+00 1.410908e-03 +444 1.430000e+00 1.000000e+00 1.417136e-03 +445 1.440000e+00 1.000000e+00 1.423324e-03 +446 1.450000e+00 1.000000e+00 1.429473e-03 +447 1.460000e+00 1.000000e+00 1.435584e-03 +448 1.470000e+00 1.000000e+00 1.441658e-03 +449 1.480000e+00 1.000000e+00 1.447696e-03 +450 1.490000e+00 1.000000e+00 1.453700e-03 +451 1.500000e+00 1.000000e+00 1.459670e-03 +452 1.510000e+00 1.000000e+00 1.465607e-03 +453 1.520000e+00 1.000000e+00 1.471512e-03 +454 1.530000e+00 1.000000e+00 1.477386e-03 +455 1.540000e+00 1.000000e+00 1.483230e-03 +456 1.550000e+00 1.000000e+00 1.489044e-03 +457 1.560000e+00 1.000000e+00 1.494829e-03 +458 1.570000e+00 1.000000e+00 1.500586e-03 +459 1.580000e+00 1.000000e+00 1.506316e-03 +460 1.590000e+00 1.000000e+00 1.512018e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +461 1.600000e+00 1.000000e+00 1.517694e-03 +462 1.610000e+00 1.000000e+00 1.523345e-03 +463 1.620000e+00 1.000000e+00 1.528970e-03 +464 1.630000e+00 1.000000e+00 1.534570e-03 +465 1.640000e+00 1.000000e+00 1.540146e-03 +466 1.650000e+00 1.000000e+00 1.545698e-03 +467 1.660000e+00 1.000000e+00 1.551227e-03 +468 1.670000e+00 1.000000e+00 1.556733e-03 +469 1.680000e+00 1.000000e+00 1.562216e-03 +470 1.690000e+00 1.000000e+00 1.567676e-03 +471 1.700000e+00 1.000000e+00 1.573115e-03 +472 1.710000e+00 1.000000e+00 1.578532e-03 +473 1.720000e+00 1.000000e+00 1.583927e-03 +474 1.730000e+00 1.000000e+00 1.589302e-03 +475 1.740000e+00 1.000000e+00 1.594656e-03 +476 1.750000e+00 1.000000e+00 1.599989e-03 +477 1.760000e+00 1.000000e+00 1.605301e-03 +478 1.770000e+00 1.000000e+00 1.610594e-03 +479 1.780000e+00 1.000000e+00 1.615867e-03 +480 1.790000e+00 1.000000e+00 1.621120e-03 +481 1.800000e+00 1.000000e+00 1.626354e-03 +482 1.810000e+00 1.000000e+00 1.631568e-03 +483 1.820000e+00 1.000000e+00 1.636764e-03 +484 1.830000e+00 1.000000e+00 1.641940e-03 +485 1.840000e+00 1.000000e+00 1.647099e-03 +486 1.850000e+00 1.000000e+00 1.652238e-03 +487 1.860000e+00 1.000000e+00 1.657360e-03 +488 1.870000e+00 1.000000e+00 1.662463e-03 +489 1.880000e+00 1.000000e+00 1.667549e-03 +490 1.890000e+00 1.000000e+00 1.672617e-03 +491 1.900000e+00 1.000000e+00 1.677667e-03 +492 1.910000e+00 1.000000e+00 1.682700e-03 +493 1.920000e+00 1.000000e+00 1.687716e-03 +494 1.930000e+00 1.000000e+00 1.692715e-03 +495 1.940000e+00 1.000000e+00 1.697697e-03 +496 1.950000e+00 1.000000e+00 1.702663e-03 +497 1.960000e+00 1.000000e+00 1.707612e-03 +498 1.970000e+00 1.000000e+00 1.712545e-03 +499 1.980000e+00 1.000000e+00 1.717462e-03 +500 1.990000e+00 1.000000e+00 1.722363e-03 +501 2.000000e+00 1.000000e+00 1.727248e-03 +502 2.010000e+00 1.000000e+00 1.732118e-03 +503 2.020000e+00 1.000000e+00 1.736973e-03 +504 2.030000e+00 1.000000e+00 1.741812e-03 +505 2.040000e+00 1.000000e+00 1.746637e-03 +506 2.050000e+00 1.000000e+00 1.751446e-03 +507 2.060000e+00 1.000000e+00 1.756241e-03 +508 2.070000e+00 1.000000e+00 1.761021e-03 +509 2.080000e+00 1.000000e+00 1.765788e-03 +510 2.090000e+00 1.000000e+00 1.770539e-03 +511 2.100000e+00 1.000000e+00 1.775277e-03 +512 2.110000e+00 1.000000e+00 1.780002e-03 +513 2.120000e+00 1.000000e+00 1.784712e-03 +514 2.130000e+00 1.000000e+00 1.789409e-03 +515 2.140000e+00 1.000000e+00 1.794093e-03 +516 2.150000e+00 1.000000e+00 1.798763e-03 +517 2.160000e+00 1.000000e+00 1.803421e-03 +518 2.170000e+00 1.000000e+00 1.808065e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +519 2.180000e+00 1.000000e+00 1.812697e-03 +520 2.190000e+00 1.000000e+00 1.817317e-03 +521 2.200000e+00 1.000000e+00 1.821923e-03 +522 2.210000e+00 1.000000e+00 1.826518e-03 +523 2.220000e+00 1.000000e+00 1.831101e-03 +524 2.230000e+00 1.000000e+00 1.835671e-03 +525 2.240000e+00 1.000000e+00 1.840230e-03 +526 2.250000e+00 1.000000e+00 1.844777e-03 +527 2.260000e+00 1.000000e+00 1.849313e-03 +528 2.270000e+00 1.000000e+00 1.853837e-03 +529 2.280000e+00 1.000000e+00 1.858350e-03 +530 2.290000e+00 1.000000e+00 1.862852e-03 +531 2.300000e+00 1.000000e+00 1.867342e-03 +532 2.310000e+00 1.000000e+00 1.871822e-03 +533 2.320000e+00 1.000000e+00 1.876291e-03 +534 2.330000e+00 1.000000e+00 1.880750e-03 +535 2.340000e+00 1.000000e+00 1.885198e-03 +536 2.350000e+00 1.000000e+00 1.889636e-03 +537 2.360000e+00 1.000000e+00 1.894063e-03 +538 2.370000e+00 1.000000e+00 1.898481e-03 +539 2.380000e+00 1.000000e+00 1.902888e-03 +540 2.390000e+00 1.000000e+00 1.907286e-03 +541 2.400000e+00 1.000000e+00 1.911674e-03 +542 2.410000e+00 1.000000e+00 1.916052e-03 +543 2.420000e+00 1.000000e+00 1.920421e-03 +544 2.430000e+00 1.000000e+00 1.924780e-03 +545 2.440000e+00 1.000000e+00 1.929130e-03 +546 2.450000e+00 1.000000e+00 1.933471e-03 +547 2.460000e+00 1.000000e+00 1.937803e-03 +548 2.470000e+00 1.000000e+00 1.942125e-03 +549 2.480000e+00 1.000000e+00 1.946439e-03 +550 2.490000e+00 1.000000e+00 1.950745e-03 +551 2.500000e+00 1.000000e+00 1.955041e-03 +552 2.510000e+00 1.000000e+00 1.959330e-03 +553 2.520000e+00 1.000000e+00 1.963609e-03 +554 2.530000e+00 1.000000e+00 1.967881e-03 +555 2.540000e+00 1.000000e+00 1.972144e-03 +556 2.550000e+00 1.000000e+00 1.976399e-03 +557 2.560000e+00 1.000000e+00 1.980646e-03 +558 2.570000e+00 1.000000e+00 1.984885e-03 +559 2.580000e+00 1.000000e+00 1.989116e-03 +560 2.590000e+00 1.000000e+00 1.993340e-03 +561 2.600000e+00 1.000000e+00 1.997556e-03 +562 2.610000e+00 1.000000e+00 2.001764e-03 +563 2.620000e+00 1.000000e+00 2.005965e-03 +564 2.630000e+00 1.000000e+00 2.010159e-03 +565 2.640000e+00 1.000000e+00 2.014345e-03 +566 2.650000e+00 1.000000e+00 2.018525e-03 +567 2.660000e+00 1.000000e+00 2.022697e-03 +568 2.670000e+00 1.000000e+00 2.026862e-03 +569 2.680000e+00 1.000000e+00 2.031020e-03 +570 2.690000e+00 1.000000e+00 2.035171e-03 +571 2.700000e+00 1.000000e+00 2.039316e-03 +572 2.710000e+00 1.000000e+00 2.043454e-03 +573 2.720000e+00 1.000000e+00 2.047585e-03 +574 2.730000e+00 1.000000e+00 2.051710e-03 +575 2.740000e+00 1.000000e+00 2.055829e-03 +576 2.750000e+00 1.000000e+00 2.059941e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +577 2.760000e+00 1.000000e+00 2.064047e-03 +578 2.770000e+00 1.000000e+00 2.068147e-03 +579 2.780000e+00 1.000000e+00 2.072241e-03 +580 2.790000e+00 1.000000e+00 2.076328e-03 +581 2.800000e+00 1.000000e+00 2.080410e-03 +582 2.810000e+00 1.000000e+00 2.084486e-03 +583 2.820000e+00 1.000000e+00 2.088556e-03 +584 2.830000e+00 1.000000e+00 2.092621e-03 +585 2.840000e+00 1.000000e+00 2.096680e-03 +586 2.850000e+00 1.000000e+00 2.100733e-03 +587 2.860000e+00 1.000000e+00 2.104781e-03 +588 2.870000e+00 1.000000e+00 2.108823e-03 +589 2.880000e+00 1.000000e+00 2.112860e-03 +590 2.890000e+00 1.000000e+00 2.116892e-03 +591 2.900000e+00 1.000000e+00 2.120919e-03 +592 2.910000e+00 1.000000e+00 2.124941e-03 +593 2.920000e+00 1.000000e+00 2.128957e-03 +594 2.930000e+00 1.000000e+00 2.132969e-03 +595 2.940000e+00 1.000000e+00 2.136975e-03 +596 2.950000e+00 1.000000e+00 2.140977e-03 +597 2.960000e+00 1.000000e+00 2.144974e-03 +598 2.970000e+00 1.000000e+00 2.148966e-03 +599 2.980000e+00 1.000000e+00 2.152954e-03 +600 2.990000e+00 1.000000e+00 2.156937e-03 +601 3.000000e+00 1.000000e+00 2.160916e-03 +602 0.000000e+00 1.500000e+00 -3.009338e-36 +603 1.000000e-02 1.500000e+00 6.670045e-05 +604 2.000000e-02 1.500000e+00 1.321933e-04 +605 3.000000e-02 1.500000e+00 1.964976e-04 +606 4.000000e-02 1.500000e+00 2.596311e-04 +607 5.000000e-02 1.500000e+00 3.216106e-04 +608 6.000000e-02 1.500000e+00 3.824518e-04 +609 7.000000e-02 1.500000e+00 4.421697e-04 +610 8.000000e-02 1.500000e+00 5.007785e-04 +611 9.000000e-02 1.500000e+00 5.582918e-04 +612 1.000000e-01 1.500000e+00 6.147226e-04 +613 1.100000e-01 1.500000e+00 6.706166e-04 +614 1.200000e-01 1.500000e+00 7.249146e-04 +615 1.300000e-01 1.500000e+00 7.781672e-04 +616 1.400000e-01 1.500000e+00 8.303866e-04 +617 1.500000e-01 1.500000e+00 8.815844e-04 +618 1.600000e-01 1.500000e+00 9.317721e-04 +619 1.700000e-01 1.500000e+00 9.809609e-04 +620 1.800000e-01 1.500000e+00 1.029162e-03 +621 1.900000e-01 1.500000e+00 1.076387e-03 +622 2.000000e-01 1.500000e+00 1.122645e-03 +623 2.100000e-01 1.500000e+00 1.167949e-03 +624 2.200000e-01 1.500000e+00 1.212308e-03 +625 2.300000e-01 1.500000e+00 1.255733e-03 +626 2.400000e-01 1.500000e+00 1.298234e-03 +627 2.500000e-01 1.500000e+00 1.339822e-03 +628 2.600000e-01 1.500000e+00 1.380505e-03 +629 2.700000e-01 1.500000e+00 1.420294e-03 +630 2.800000e-01 1.500000e+00 1.459199e-03 +631 2.900000e-01 1.500000e+00 1.497228e-03 +632 3.000000e-01 1.500000e+00 1.534392e-03 +633 3.100000e-01 1.500000e+00 1.570698e-03 +634 3.200000e-01 1.500000e+00 1.606157e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +635 3.300000e-01 1.500000e+00 1.640776e-03 +636 3.400000e-01 1.500000e+00 1.674565e-03 +637 3.500000e-01 1.500000e+00 1.707531e-03 +638 3.600000e-01 1.500000e+00 1.739683e-03 +639 3.700000e-01 1.500000e+00 1.771030e-03 +640 3.800000e-01 1.500000e+00 1.801579e-03 +641 3.900000e-01 1.500000e+00 1.831338e-03 +642 4.000000e-01 1.500000e+00 1.860315e-03 +643 4.100000e-01 1.500000e+00 1.888518e-03 +644 4.200000e-01 1.500000e+00 1.915955e-03 +645 4.300000e-01 1.500000e+00 1.942632e-03 +646 4.400000e-01 1.500000e+00 1.968558e-03 +647 4.500000e-01 1.500000e+00 1.993740e-03 +648 4.600000e-01 1.500000e+00 2.018185e-03 +649 4.700000e-01 1.500000e+00 2.041901e-03 +650 4.800000e-01 1.500000e+00 2.064895e-03 +651 4.900000e-01 1.500000e+00 2.087176e-03 +652 5.000000e-01 1.500000e+00 2.108751e-03 +653 5.100000e-01 1.500000e+00 2.129627e-03 +654 5.200000e-01 1.500000e+00 2.149814e-03 +655 5.300000e-01 1.500000e+00 2.169320e-03 +656 5.400000e-01 1.500000e+00 2.188153e-03 +657 5.500000e-01 1.500000e+00 2.206323e-03 +658 5.600000e-01 1.500000e+00 2.223841e-03 +659 5.700000e-01 1.500000e+00 2.240717e-03 +660 5.800000e-01 1.500000e+00 2.256963e-03 +661 5.900000e-01 1.500000e+00 2.272592e-03 +662 6.000000e-01 1.500000e+00 2.287618e-03 +663 6.100000e-01 1.500000e+00 2.302055e-03 +664 6.200000e-01 1.500000e+00 2.315922e-03 +665 6.300000e-01 1.500000e+00 2.329235e-03 +666 6.400000e-01 1.500000e+00 2.342014e-03 +667 6.500000e-01 1.500000e+00 2.354282e-03 +668 6.600000e-01 1.500000e+00 2.366060e-03 +669 6.700000e-01 1.500000e+00 2.377373e-03 +670 6.800000e-01 1.500000e+00 2.388245e-03 +671 6.900000e-01 1.500000e+00 2.398704e-03 +672 7.000000e-01 1.500000e+00 2.408774e-03 +673 7.100000e-01 1.500000e+00 2.418484e-03 +674 7.200000e-01 1.500000e+00 2.427859e-03 +675 7.300000e-01 1.500000e+00 2.436926e-03 +676 7.400000e-01 1.500000e+00 2.445712e-03 +677 7.500000e-01 1.500000e+00 2.454241e-03 +678 7.600000e-01 1.500000e+00 2.462538e-03 +679 7.700000e-01 1.500000e+00 2.470629e-03 +680 7.800000e-01 1.500000e+00 2.478536e-03 +681 7.900000e-01 1.500000e+00 2.486283e-03 +682 8.000000e-01 1.500000e+00 2.493894e-03 +683 8.100000e-01 1.500000e+00 2.501392e-03 +684 8.200000e-01 1.500000e+00 2.508799e-03 +685 8.300000e-01 1.500000e+00 2.516141e-03 +686 8.400000e-01 1.500000e+00 2.523442e-03 +687 8.500000e-01 1.500000e+00 2.530726e-03 +688 8.600000e-01 1.500000e+00 2.538022e-03 +689 8.700000e-01 1.500000e+00 2.545355e-03 +690 8.800000e-01 1.500000e+00 2.552756e-03 +691 8.900000e-01 1.500000e+00 2.560254e-03 +692 9.000000e-01 1.500000e+00 2.567881e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +693 9.100000e-01 1.500000e+00 2.575669e-03 +694 9.200000e-01 1.500000e+00 2.583650e-03 +695 9.300000e-01 1.500000e+00 2.591858e-03 +696 9.400000e-01 1.500000e+00 2.600325e-03 +697 9.500000e-01 1.500000e+00 2.609080e-03 +698 9.600000e-01 1.500000e+00 2.618153e-03 +699 9.700000e-01 1.500000e+00 2.627567e-03 +700 9.800000e-01 1.500000e+00 2.637344e-03 +701 9.900000e-01 1.500000e+00 2.647497e-03 +702 1.000000e+00 1.500000e+00 2.658034e-03 +703 1.010000e+00 1.500000e+00 2.668955e-03 +704 1.020000e+00 1.500000e+00 2.680254e-03 +705 1.030000e+00 1.500000e+00 2.691914e-03 +706 1.040000e+00 1.500000e+00 2.703913e-03 +707 1.050000e+00 1.500000e+00 2.716221e-03 +708 1.060000e+00 1.500000e+00 2.728803e-03 +709 1.070000e+00 1.500000e+00 2.741618e-03 +710 1.080000e+00 1.500000e+00 2.754623e-03 +711 1.090000e+00 1.500000e+00 2.767774e-03 +712 1.100000e+00 1.500000e+00 2.781043e-03 +713 1.110000e+00 1.500000e+00 2.794473e-03 +714 1.120000e+00 1.500000e+00 2.807941e-03 +715 1.130000e+00 1.500000e+00 2.821394e-03 +716 1.140000e+00 1.500000e+00 2.834790e-03 +717 1.150000e+00 1.500000e+00 2.848095e-03 +718 1.160000e+00 1.500000e+00 2.861281e-03 +719 1.170000e+00 1.500000e+00 2.874327e-03 +720 1.180000e+00 1.500000e+00 2.887219e-03 +721 1.190000e+00 1.500000e+00 2.899944e-03 +722 1.200000e+00 1.500000e+00 2.912496e-03 +723 1.210000e+00 1.500000e+00 2.924870e-03 +724 1.220000e+00 1.500000e+00 2.937065e-03 +725 1.230000e+00 1.500000e+00 2.949081e-03 +726 1.240000e+00 1.500000e+00 2.960920e-03 +727 1.250000e+00 1.500000e+00 2.972584e-03 +728 1.260000e+00 1.500000e+00 2.984078e-03 +729 1.270000e+00 1.500000e+00 2.995407e-03 +730 1.280000e+00 1.500000e+00 3.006575e-03 +731 1.290000e+00 1.500000e+00 3.017588e-03 +732 1.300000e+00 1.500000e+00 3.028450e-03 +733 1.310000e+00 1.500000e+00 3.039169e-03 +734 1.320000e+00 1.500000e+00 3.049747e-03 +735 1.330000e+00 1.500000e+00 3.060193e-03 +736 1.340000e+00 1.500000e+00 3.070509e-03 +737 1.350000e+00 1.500000e+00 3.080702e-03 +738 1.360000e+00 1.500000e+00 3.090776e-03 +739 1.370000e+00 1.500000e+00 3.100736e-03 +740 1.380000e+00 1.500000e+00 3.110585e-03 +741 1.390000e+00 1.500000e+00 3.120330e-03 +742 1.400000e+00 1.500000e+00 3.129973e-03 +743 1.410000e+00 1.500000e+00 3.139518e-03 +744 1.420000e+00 1.500000e+00 3.148969e-03 +745 1.430000e+00 1.500000e+00 3.158329e-03 +746 1.440000e+00 1.500000e+00 3.167602e-03 +747 1.450000e+00 1.500000e+00 3.176791e-03 +748 1.460000e+00 1.500000e+00 3.185898e-03 +749 1.470000e+00 1.500000e+00 3.194927e-03 +750 1.480000e+00 1.500000e+00 3.203880e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +751 1.490000e+00 1.500000e+00 3.212760e-03 +752 1.500000e+00 1.500000e+00 3.221569e-03 +753 1.510000e+00 1.500000e+00 3.230310e-03 +754 1.520000e+00 1.500000e+00 3.238983e-03 +755 1.530000e+00 1.500000e+00 3.247593e-03 +756 1.540000e+00 1.500000e+00 3.256140e-03 +757 1.550000e+00 1.500000e+00 3.264627e-03 +758 1.560000e+00 1.500000e+00 3.273054e-03 +759 1.570000e+00 1.500000e+00 3.281425e-03 +760 1.580000e+00 1.500000e+00 3.289740e-03 +761 1.590000e+00 1.500000e+00 3.298002e-03 +762 1.600000e+00 1.500000e+00 3.306210e-03 +763 1.610000e+00 1.500000e+00 3.314368e-03 +764 1.620000e+00 1.500000e+00 3.322476e-03 +765 1.630000e+00 1.500000e+00 3.330535e-03 +766 1.640000e+00 1.500000e+00 3.338547e-03 +767 1.650000e+00 1.500000e+00 3.346512e-03 +768 1.660000e+00 1.500000e+00 3.354432e-03 +769 1.670000e+00 1.500000e+00 3.362308e-03 +770 1.680000e+00 1.500000e+00 3.370141e-03 +771 1.690000e+00 1.500000e+00 3.377931e-03 +772 1.700000e+00 1.500000e+00 3.385679e-03 +773 1.710000e+00 1.500000e+00 3.393387e-03 +774 1.720000e+00 1.500000e+00 3.401055e-03 +775 1.730000e+00 1.500000e+00 3.408683e-03 +776 1.740000e+00 1.500000e+00 3.416273e-03 +777 1.750000e+00 1.500000e+00 3.423824e-03 +778 1.760000e+00 1.500000e+00 3.431339e-03 +779 1.770000e+00 1.500000e+00 3.438816e-03 +780 1.780000e+00 1.500000e+00 3.446257e-03 +781 1.790000e+00 1.500000e+00 3.453663e-03 +782 1.800000e+00 1.500000e+00 3.461033e-03 +783 1.810000e+00 1.500000e+00 3.468368e-03 +784 1.820000e+00 1.500000e+00 3.475669e-03 +785 1.830000e+00 1.500000e+00 3.482936e-03 +786 1.840000e+00 1.500000e+00 3.490169e-03 +787 1.850000e+00 1.500000e+00 3.497370e-03 +788 1.860000e+00 1.500000e+00 3.504538e-03 +789 1.870000e+00 1.500000e+00 3.511674e-03 +790 1.880000e+00 1.500000e+00 3.518778e-03 +791 1.890000e+00 1.500000e+00 3.525850e-03 +792 1.900000e+00 1.500000e+00 3.532892e-03 +793 1.910000e+00 1.500000e+00 3.539903e-03 +794 1.920000e+00 1.500000e+00 3.546883e-03 +795 1.930000e+00 1.500000e+00 3.553834e-03 +796 1.940000e+00 1.500000e+00 3.560755e-03 +797 1.950000e+00 1.500000e+00 3.567647e-03 +798 1.960000e+00 1.500000e+00 3.574510e-03 +799 1.970000e+00 1.500000e+00 3.581345e-03 +800 1.980000e+00 1.500000e+00 3.588152e-03 +801 1.990000e+00 1.500000e+00 3.594931e-03 +802 2.000000e+00 1.500000e+00 3.601682e-03 +803 2.010000e+00 1.500000e+00 3.608407e-03 +804 2.020000e+00 1.500000e+00 3.615105e-03 +805 2.030000e+00 1.500000e+00 3.621776e-03 +806 2.040000e+00 1.500000e+00 3.628422e-03 +807 2.050000e+00 1.500000e+00 3.635042e-03 +808 2.060000e+00 1.500000e+00 3.641637e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +809 2.070000e+00 1.500000e+00 3.648207e-03 +810 2.080000e+00 1.500000e+00 3.654752e-03 +811 2.090000e+00 1.500000e+00 3.661272e-03 +812 2.100000e+00 1.500000e+00 3.667769e-03 +813 2.110000e+00 1.500000e+00 3.674243e-03 +814 2.120000e+00 1.500000e+00 3.680692e-03 +815 2.130000e+00 1.500000e+00 3.687119e-03 +816 2.140000e+00 1.500000e+00 3.693523e-03 +817 2.150000e+00 1.500000e+00 3.699905e-03 +818 2.160000e+00 1.500000e+00 3.706265e-03 +819 2.170000e+00 1.500000e+00 3.712602e-03 +820 2.180000e+00 1.500000e+00 3.718919e-03 +821 2.190000e+00 1.500000e+00 3.725214e-03 +822 2.200000e+00 1.500000e+00 3.731488e-03 +823 2.210000e+00 1.500000e+00 3.737741e-03 +824 2.220000e+00 1.500000e+00 3.743974e-03 +825 2.230000e+00 1.500000e+00 3.750187e-03 +826 2.240000e+00 1.500000e+00 3.756380e-03 +827 2.250000e+00 1.500000e+00 3.762553e-03 +828 2.260000e+00 1.500000e+00 3.768707e-03 +829 2.270000e+00 1.500000e+00 3.774842e-03 +830 2.280000e+00 1.500000e+00 3.780959e-03 +831 2.290000e+00 1.500000e+00 3.787056e-03 +832 2.300000e+00 1.500000e+00 3.793136e-03 +833 2.310000e+00 1.500000e+00 3.799197e-03 +834 2.320000e+00 1.500000e+00 3.805241e-03 +835 2.330000e+00 1.500000e+00 3.811267e-03 +836 2.340000e+00 1.500000e+00 3.817275e-03 +837 2.350000e+00 1.500000e+00 3.823267e-03 +838 2.360000e+00 1.500000e+00 3.829241e-03 +839 2.370000e+00 1.500000e+00 3.835199e-03 +840 2.380000e+00 1.500000e+00 3.841140e-03 +841 2.390000e+00 1.500000e+00 3.847066e-03 +842 2.400000e+00 1.500000e+00 3.852975e-03 +843 2.410000e+00 1.500000e+00 3.858868e-03 +844 2.420000e+00 1.500000e+00 3.864746e-03 +845 2.430000e+00 1.500000e+00 3.870608e-03 +846 2.440000e+00 1.500000e+00 3.876456e-03 +847 2.450000e+00 1.500000e+00 3.882288e-03 +848 2.460000e+00 1.500000e+00 3.888105e-03 +849 2.470000e+00 1.500000e+00 3.893908e-03 +850 2.480000e+00 1.500000e+00 3.899697e-03 +851 2.490000e+00 1.500000e+00 3.905471e-03 +852 2.500000e+00 1.500000e+00 3.911231e-03 +853 2.510000e+00 1.500000e+00 3.916977e-03 +854 2.520000e+00 1.500000e+00 3.922710e-03 +855 2.530000e+00 1.500000e+00 3.928429e-03 +856 2.540000e+00 1.500000e+00 3.934135e-03 +857 2.550000e+00 1.500000e+00 3.939828e-03 +858 2.560000e+00 1.500000e+00 3.945508e-03 +859 2.570000e+00 1.500000e+00 3.951175e-03 +860 2.580000e+00 1.500000e+00 3.956829e-03 +861 2.590000e+00 1.500000e+00 3.962471e-03 +862 2.600000e+00 1.500000e+00 3.968101e-03 +863 2.610000e+00 1.500000e+00 3.973719e-03 +864 2.620000e+00 1.500000e+00 3.979324e-03 +865 2.630000e+00 1.500000e+00 3.984918e-03 +866 2.640000e+00 1.500000e+00 3.990500e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +867 2.650000e+00 1.500000e+00 3.996071e-03 +868 2.660000e+00 1.500000e+00 4.001631e-03 +869 2.670000e+00 1.500000e+00 4.007179e-03 +870 2.680000e+00 1.500000e+00 4.012716e-03 +871 2.690000e+00 1.500000e+00 4.018242e-03 +872 2.700000e+00 1.500000e+00 4.023758e-03 +873 2.710000e+00 1.500000e+00 4.029263e-03 +874 2.720000e+00 1.500000e+00 4.034757e-03 +875 2.730000e+00 1.500000e+00 4.040241e-03 +876 2.740000e+00 1.500000e+00 4.045715e-03 +877 2.750000e+00 1.500000e+00 4.051179e-03 +878 2.760000e+00 1.500000e+00 4.056633e-03 +879 2.770000e+00 1.500000e+00 4.062077e-03 +880 2.780000e+00 1.500000e+00 4.067512e-03 +881 2.790000e+00 1.500000e+00 4.072937e-03 +882 2.800000e+00 1.500000e+00 4.078353e-03 +883 2.810000e+00 1.500000e+00 4.083759e-03 +884 2.820000e+00 1.500000e+00 4.089157e-03 +885 2.830000e+00 1.500000e+00 4.094545e-03 +886 2.840000e+00 1.500000e+00 4.099924e-03 +887 2.850000e+00 1.500000e+00 4.105295e-03 +888 2.860000e+00 1.500000e+00 4.110657e-03 +889 2.870000e+00 1.500000e+00 4.116011e-03 +890 2.880000e+00 1.500000e+00 4.121356e-03 +891 2.890000e+00 1.500000e+00 4.126693e-03 +892 2.900000e+00 1.500000e+00 4.132022e-03 +893 2.910000e+00 1.500000e+00 4.137342e-03 +894 2.920000e+00 1.500000e+00 4.142655e-03 +895 2.930000e+00 1.500000e+00 4.147960e-03 +896 2.940000e+00 1.500000e+00 4.153257e-03 +897 2.950000e+00 1.500000e+00 4.158547e-03 +898 2.960000e+00 1.500000e+00 4.163829e-03 +899 2.970000e+00 1.500000e+00 4.169103e-03 +900 2.980000e+00 1.500000e+00 4.174371e-03 +901 2.990000e+00 1.500000e+00 4.179631e-03 +902 3.000000e+00 1.500000e+00 4.184884e-03 +903 0.000000e+00 2.000000e+00 -1.093850e-40 +904 1.000000e-02 2.000000e+00 8.811600e-05 +905 2.000000e-02 2.000000e+00 1.750348e-04 +906 3.000000e-02 2.000000e+00 2.607739e-04 +907 4.000000e-02 2.000000e+00 3.453498e-04 +908 5.000000e-02 2.000000e+00 4.287780e-04 +909 6.000000e-02 2.000000e+00 5.110728e-04 +910 7.000000e-02 2.000000e+00 5.922480e-04 +911 8.000000e-02 2.000000e+00 6.723166e-04 +912 9.000000e-02 2.000000e+00 7.512910e-04 +913 1.000000e-01 2.000000e+00 8.291832e-04 +914 1.100000e-01 2.000000e+00 9.065381e-04 +915 1.200000e-01 2.000000e+00 9.822948e-04 +916 1.300000e-01 2.000000e+00 1.057003e-03 +917 1.400000e-01 2.000000e+00 1.130674e-03 +918 1.500000e-01 2.000000e+00 1.203318e-03 +919 1.600000e-01 2.000000e+00 1.274945e-03 +920 1.700000e-01 2.000000e+00 1.345567e-03 +921 1.800000e-01 2.000000e+00 1.415193e-03 +922 1.900000e-01 2.000000e+00 1.483833e-03 +923 2.000000e-01 2.000000e+00 1.551497e-03 +924 2.100000e-01 2.000000e+00 1.618195e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +925 2.200000e-01 2.000000e+00 1.683938e-03 +926 2.300000e-01 2.000000e+00 1.748733e-03 +927 2.400000e-01 2.000000e+00 1.812591e-03 +928 2.500000e-01 2.000000e+00 1.875521e-03 +929 2.600000e-01 2.000000e+00 1.937533e-03 +930 2.700000e-01 2.000000e+00 1.998634e-03 +931 2.800000e-01 2.000000e+00 2.058834e-03 +932 2.900000e-01 2.000000e+00 2.118142e-03 +933 3.000000e-01 2.000000e+00 2.176565e-03 +934 3.100000e-01 2.000000e+00 2.234113e-03 +935 3.200000e-01 2.000000e+00 2.290793e-03 +936 3.300000e-01 2.000000e+00 2.346613e-03 +937 3.400000e-01 2.000000e+00 2.401582e-03 +938 3.500000e-01 2.000000e+00 2.455706e-03 +939 3.600000e-01 2.000000e+00 2.508994e-03 +940 3.700000e-01 2.000000e+00 2.561452e-03 +941 3.800000e-01 2.000000e+00 2.613088e-03 +942 3.900000e-01 2.000000e+00 2.663910e-03 +943 4.000000e-01 2.000000e+00 2.713922e-03 +944 4.100000e-01 2.000000e+00 2.763134e-03 +945 4.200000e-01 2.000000e+00 2.811551e-03 +946 4.300000e-01 2.000000e+00 2.859179e-03 +947 4.400000e-01 2.000000e+00 2.906025e-03 +948 4.500000e-01 2.000000e+00 2.952096e-03 +949 4.600000e-01 2.000000e+00 2.997397e-03 +950 4.700000e-01 2.000000e+00 3.041934e-03 +951 4.800000e-01 2.000000e+00 3.085713e-03 +952 4.900000e-01 2.000000e+00 3.128741e-03 +953 5.000000e-01 2.000000e+00 3.171021e-03 +954 5.100000e-01 2.000000e+00 3.212561e-03 +955 5.200000e-01 2.000000e+00 3.253364e-03 +956 5.300000e-01 2.000000e+00 3.293438e-03 +957 5.400000e-01 2.000000e+00 3.332786e-03 +958 5.500000e-01 2.000000e+00 3.371413e-03 +959 5.600000e-01 2.000000e+00 3.409326e-03 +960 5.700000e-01 2.000000e+00 3.446528e-03 +961 5.800000e-01 2.000000e+00 3.483024e-03 +962 5.900000e-01 2.000000e+00 3.518819e-03 +963 6.000000e-01 2.000000e+00 3.553917e-03 +964 6.100000e-01 2.000000e+00 3.588323e-03 +965 6.200000e-01 2.000000e+00 3.622041e-03 +966 6.300000e-01 2.000000e+00 3.655076e-03 +967 6.400000e-01 2.000000e+00 3.687431e-03 +968 6.500000e-01 2.000000e+00 3.719110e-03 +969 6.600000e-01 2.000000e+00 3.750118e-03 +970 6.700000e-01 2.000000e+00 3.780458e-03 +971 6.800000e-01 2.000000e+00 3.810135e-03 +972 6.900000e-01 2.000000e+00 3.839151e-03 +973 7.000000e-01 2.000000e+00 3.867510e-03 +974 7.100000e-01 2.000000e+00 3.895216e-03 +975 7.200000e-01 2.000000e+00 3.922273e-03 +976 7.300000e-01 2.000000e+00 3.948683e-03 +977 7.400000e-01 2.000000e+00 3.974450e-03 +978 7.500000e-01 2.000000e+00 3.999578e-03 +979 7.600000e-01 2.000000e+00 4.024070e-03 +980 7.700000e-01 2.000000e+00 4.047929e-03 +981 7.800000e-01 2.000000e+00 4.071160e-03 +982 7.900000e-01 2.000000e+00 4.093766e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +983 8.000000e-01 2.000000e+00 4.115751e-03 +984 8.100000e-01 2.000000e+00 4.137120e-03 +985 8.200000e-01 2.000000e+00 4.157878e-03 +986 8.300000e-01 2.000000e+00 4.178032e-03 +987 8.400000e-01 2.000000e+00 4.197587e-03 +988 8.500000e-01 2.000000e+00 4.216553e-03 +989 8.600000e-01 2.000000e+00 4.234938e-03 +990 8.700000e-01 2.000000e+00 4.252754e-03 +991 8.800000e-01 2.000000e+00 4.270012e-03 +992 8.900000e-01 2.000000e+00 4.286729e-03 +993 9.000000e-01 2.000000e+00 4.302921e-03 +994 9.100000e-01 2.000000e+00 4.318608e-03 +995 9.200000e-01 2.000000e+00 4.333812e-03 +996 9.300000e-01 2.000000e+00 4.348559e-03 +997 9.400000e-01 2.000000e+00 4.362878e-03 +998 9.500000e-01 2.000000e+00 4.376799e-03 +999 9.600000e-01 2.000000e+00 4.390357e-03 +1000 9.700000e-01 2.000000e+00 4.403590e-03 +1001 9.800000e-01 2.000000e+00 4.416537e-03 +1002 9.900000e-01 2.000000e+00 4.429241e-03 +1003 1.000000e+00 2.000000e+00 4.441749e-03 +1004 1.010000e+00 2.000000e+00 4.454108e-03 +1005 1.020000e+00 2.000000e+00 4.466367e-03 +1006 1.030000e+00 2.000000e+00 4.478580e-03 +1007 1.040000e+00 2.000000e+00 4.490798e-03 +1008 1.050000e+00 2.000000e+00 4.503075e-03 +1009 1.060000e+00 2.000000e+00 4.515463e-03 +1010 1.070000e+00 2.000000e+00 4.528014e-03 +1011 1.080000e+00 2.000000e+00 4.540774e-03 +1012 1.090000e+00 2.000000e+00 4.553789e-03 +1013 1.100000e+00 2.000000e+00 4.567096e-03 +1014 1.110000e+00 2.000000e+00 4.580726e-03 +1015 1.120000e+00 2.000000e+00 4.594702e-03 +1016 1.130000e+00 2.000000e+00 4.609036e-03 +1017 1.140000e+00 2.000000e+00 4.623731e-03 +1018 1.150000e+00 2.000000e+00 4.638777e-03 +1019 1.160000e+00 2.000000e+00 4.654157e-03 +1020 1.170000e+00 2.000000e+00 4.669840e-03 +1021 1.180000e+00 2.000000e+00 4.685791e-03 +1022 1.190000e+00 2.000000e+00 4.701967e-03 +1023 1.200000e+00 2.000000e+00 4.718374e-03 +1024 1.210000e+00 2.000000e+00 4.734997e-03 +1025 1.220000e+00 2.000000e+00 4.751717e-03 +1026 1.230000e+00 2.000000e+00 4.768469e-03 +1027 1.240000e+00 2.000000e+00 4.785198e-03 +1028 1.250000e+00 2.000000e+00 4.801855e-03 +1029 1.260000e+00 2.000000e+00 4.818398e-03 +1030 1.270000e+00 2.000000e+00 4.834796e-03 +1031 1.280000e+00 2.000000e+00 4.851022e-03 +1032 1.290000e+00 2.000000e+00 4.867056e-03 +1033 1.300000e+00 2.000000e+00 4.882882e-03 +1034 1.310000e+00 2.000000e+00 4.898492e-03 +1035 1.320000e+00 2.000000e+00 4.913878e-03 +1036 1.330000e+00 2.000000e+00 4.929037e-03 +1037 1.340000e+00 2.000000e+00 4.943969e-03 +1038 1.350000e+00 2.000000e+00 4.958676e-03 +1039 1.360000e+00 2.000000e+00 4.973161e-03 +1040 1.370000e+00 2.000000e+00 4.987428e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1041 1.380000e+00 2.000000e+00 5.001483e-03 +1042 1.390000e+00 2.000000e+00 5.015332e-03 +1043 1.400000e+00 2.000000e+00 5.028981e-03 +1044 1.410000e+00 2.000000e+00 5.042436e-03 +1045 1.420000e+00 2.000000e+00 5.055705e-03 +1046 1.430000e+00 2.000000e+00 5.068794e-03 +1047 1.440000e+00 2.000000e+00 5.081710e-03 +1048 1.450000e+00 2.000000e+00 5.094459e-03 +1049 1.460000e+00 2.000000e+00 5.107047e-03 +1050 1.470000e+00 2.000000e+00 5.119481e-03 +1051 1.480000e+00 2.000000e+00 5.131767e-03 +1052 1.490000e+00 2.000000e+00 5.143910e-03 +1053 1.500000e+00 2.000000e+00 5.155915e-03 +1054 1.510000e+00 2.000000e+00 5.167788e-03 +1055 1.520000e+00 2.000000e+00 5.179534e-03 +1056 1.530000e+00 2.000000e+00 5.191157e-03 +1057 1.540000e+00 2.000000e+00 5.202662e-03 +1058 1.550000e+00 2.000000e+00 5.214053e-03 +1059 1.560000e+00 2.000000e+00 5.225334e-03 +1060 1.570000e+00 2.000000e+00 5.236509e-03 +1061 1.580000e+00 2.000000e+00 5.247581e-03 +1062 1.590000e+00 2.000000e+00 5.258555e-03 +1063 1.600000e+00 2.000000e+00 5.269433e-03 +1064 1.610000e+00 2.000000e+00 5.280219e-03 +1065 1.620000e+00 2.000000e+00 5.290915e-03 +1066 1.630000e+00 2.000000e+00 5.301524e-03 +1067 1.640000e+00 2.000000e+00 5.312050e-03 +1068 1.650000e+00 2.000000e+00 5.322494e-03 +1069 1.660000e+00 2.000000e+00 5.332859e-03 +1070 1.670000e+00 2.000000e+00 5.343148e-03 +1071 1.680000e+00 2.000000e+00 5.353362e-03 +1072 1.690000e+00 2.000000e+00 5.363504e-03 +1073 1.700000e+00 2.000000e+00 5.373576e-03 +1074 1.710000e+00 2.000000e+00 5.383579e-03 +1075 1.720000e+00 2.000000e+00 5.393515e-03 +1076 1.730000e+00 2.000000e+00 5.403387e-03 +1077 1.740000e+00 2.000000e+00 5.413195e-03 +1078 1.750000e+00 2.000000e+00 5.422942e-03 +1079 1.760000e+00 2.000000e+00 5.432628e-03 +1080 1.770000e+00 2.000000e+00 5.442255e-03 +1081 1.780000e+00 2.000000e+00 5.451824e-03 +1082 1.790000e+00 2.000000e+00 5.461337e-03 +1083 1.800000e+00 2.000000e+00 5.470794e-03 +1084 1.810000e+00 2.000000e+00 5.480197e-03 +1085 1.820000e+00 2.000000e+00 5.489547e-03 +1086 1.830000e+00 2.000000e+00 5.498844e-03 +1087 1.840000e+00 2.000000e+00 5.508089e-03 +1088 1.850000e+00 2.000000e+00 5.517284e-03 +1089 1.860000e+00 2.000000e+00 5.526430e-03 +1090 1.870000e+00 2.000000e+00 5.535526e-03 +1091 1.880000e+00 2.000000e+00 5.544574e-03 +1092 1.890000e+00 2.000000e+00 5.553574e-03 +1093 1.900000e+00 2.000000e+00 5.562528e-03 +1094 1.910000e+00 2.000000e+00 5.571436e-03 +1095 1.920000e+00 2.000000e+00 5.580298e-03 +1096 1.930000e+00 2.000000e+00 5.589115e-03 +1097 1.940000e+00 2.000000e+00 5.597888e-03 +1098 1.950000e+00 2.000000e+00 5.606618e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1099 1.960000e+00 2.000000e+00 5.615305e-03 +1100 1.970000e+00 2.000000e+00 5.623949e-03 +1101 1.980000e+00 2.000000e+00 5.632552e-03 +1102 1.990000e+00 2.000000e+00 5.641113e-03 +1103 2.000000e+00 2.000000e+00 5.649634e-03 +1104 2.010000e+00 2.000000e+00 5.658114e-03 +1105 2.020000e+00 2.000000e+00 5.666556e-03 +1106 2.030000e+00 2.000000e+00 5.674958e-03 +1107 2.040000e+00 2.000000e+00 5.683322e-03 +1108 2.050000e+00 2.000000e+00 5.691648e-03 +1109 2.060000e+00 2.000000e+00 5.699937e-03 +1110 2.070000e+00 2.000000e+00 5.708189e-03 +1111 2.080000e+00 2.000000e+00 5.716405e-03 +1112 2.090000e+00 2.000000e+00 5.724585e-03 +1113 2.100000e+00 2.000000e+00 5.732730e-03 +1114 2.110000e+00 2.000000e+00 5.740841e-03 +1115 2.120000e+00 2.000000e+00 5.748917e-03 +1116 2.130000e+00 2.000000e+00 5.756960e-03 +1117 2.140000e+00 2.000000e+00 5.764969e-03 +1118 2.150000e+00 2.000000e+00 5.772946e-03 +1119 2.160000e+00 2.000000e+00 5.780890e-03 +1120 2.170000e+00 2.000000e+00 5.788803e-03 +1121 2.180000e+00 2.000000e+00 5.796685e-03 +1122 2.190000e+00 2.000000e+00 5.804535e-03 +1123 2.200000e+00 2.000000e+00 5.812356e-03 +1124 2.210000e+00 2.000000e+00 5.820146e-03 +1125 2.220000e+00 2.000000e+00 5.827907e-03 +1126 2.230000e+00 2.000000e+00 5.835639e-03 +1127 2.240000e+00 2.000000e+00 5.843342e-03 +1128 2.250000e+00 2.000000e+00 5.851018e-03 +1129 2.260000e+00 2.000000e+00 5.858665e-03 +1130 2.270000e+00 2.000000e+00 5.866285e-03 +1131 2.280000e+00 2.000000e+00 5.873878e-03 +1132 2.290000e+00 2.000000e+00 5.881445e-03 +1133 2.300000e+00 2.000000e+00 5.888985e-03 +1134 2.310000e+00 2.000000e+00 5.896500e-03 +1135 2.320000e+00 2.000000e+00 5.903989e-03 +1136 2.330000e+00 2.000000e+00 5.911453e-03 +1137 2.340000e+00 2.000000e+00 5.918893e-03 +1138 2.350000e+00 2.000000e+00 5.926308e-03 +1139 2.360000e+00 2.000000e+00 5.933699e-03 +1140 2.370000e+00 2.000000e+00 5.941067e-03 +1141 2.380000e+00 2.000000e+00 5.948411e-03 +1142 2.390000e+00 2.000000e+00 5.955733e-03 +1143 2.400000e+00 2.000000e+00 5.963031e-03 +1144 2.410000e+00 2.000000e+00 5.970308e-03 +1145 2.420000e+00 2.000000e+00 5.977562e-03 +1146 2.430000e+00 2.000000e+00 5.984795e-03 +1147 2.440000e+00 2.000000e+00 5.992007e-03 +1148 2.450000e+00 2.000000e+00 5.999197e-03 +1149 2.460000e+00 2.000000e+00 6.006367e-03 +1150 2.470000e+00 2.000000e+00 6.013516e-03 +1151 2.480000e+00 2.000000e+00 6.020645e-03 +1152 2.490000e+00 2.000000e+00 6.027754e-03 +1153 2.500000e+00 2.000000e+00 6.034844e-03 +1154 2.510000e+00 2.000000e+00 6.041914e-03 +1155 2.520000e+00 2.000000e+00 6.048966e-03 +1156 2.530000e+00 2.000000e+00 6.055998e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1157 2.540000e+00 2.000000e+00 6.063012e-03 +1158 2.550000e+00 2.000000e+00 6.070008e-03 +1159 2.560000e+00 2.000000e+00 6.076986e-03 +1160 2.570000e+00 2.000000e+00 6.083946e-03 +1161 2.580000e+00 2.000000e+00 6.090889e-03 +1162 2.590000e+00 2.000000e+00 6.097814e-03 +1163 2.600000e+00 2.000000e+00 6.104723e-03 +1164 2.610000e+00 2.000000e+00 6.111614e-03 +1165 2.620000e+00 2.000000e+00 6.118489e-03 +1166 2.630000e+00 2.000000e+00 6.125348e-03 +1167 2.640000e+00 2.000000e+00 6.132191e-03 +1168 2.650000e+00 2.000000e+00 6.139018e-03 +1169 2.660000e+00 2.000000e+00 6.145830e-03 +1170 2.670000e+00 2.000000e+00 6.152626e-03 +1171 2.680000e+00 2.000000e+00 6.159407e-03 +1172 2.690000e+00 2.000000e+00 6.166173e-03 +1173 2.700000e+00 2.000000e+00 6.172924e-03 +1174 2.710000e+00 2.000000e+00 6.179661e-03 +1175 2.720000e+00 2.000000e+00 6.186383e-03 +1176 2.730000e+00 2.000000e+00 6.193091e-03 +1177 2.740000e+00 2.000000e+00 6.199786e-03 +1178 2.750000e+00 2.000000e+00 6.206466e-03 +1179 2.760000e+00 2.000000e+00 6.213133e-03 +1180 2.770000e+00 2.000000e+00 6.219787e-03 +1181 2.780000e+00 2.000000e+00 6.226428e-03 +1182 2.790000e+00 2.000000e+00 6.233056e-03 +1183 2.800000e+00 2.000000e+00 6.239670e-03 +1184 2.810000e+00 2.000000e+00 6.246273e-03 +1185 2.820000e+00 2.000000e+00 6.252863e-03 +1186 2.830000e+00 2.000000e+00 6.259440e-03 +1187 2.840000e+00 2.000000e+00 6.266006e-03 +1188 2.850000e+00 2.000000e+00 6.272560e-03 +1189 2.860000e+00 2.000000e+00 6.279102e-03 +1190 2.870000e+00 2.000000e+00 6.285632e-03 +1191 2.880000e+00 2.000000e+00 6.292151e-03 +1192 2.890000e+00 2.000000e+00 6.298659e-03 +1193 2.900000e+00 2.000000e+00 6.305156e-03 +1194 2.910000e+00 2.000000e+00 6.311642e-03 +1195 2.920000e+00 2.000000e+00 6.318117e-03 +1196 2.930000e+00 2.000000e+00 6.324582e-03 +1197 2.940000e+00 2.000000e+00 6.331036e-03 +1198 2.950000e+00 2.000000e+00 6.337480e-03 +1199 2.960000e+00 2.000000e+00 6.343913e-03 +1200 2.970000e+00 2.000000e+00 6.350337e-03 +1201 2.980000e+00 2.000000e+00 6.356751e-03 +1202 2.990000e+00 2.000000e+00 6.363155e-03 +1203 3.000000e+00 2.000000e+00 6.369550e-03 +1204 0.000000e+00 2.500000e+00 3.009119e-36 +1205 1.000000e-02 2.500000e+00 1.026370e-04 +1206 2.000000e-02 2.500000e+00 2.041497e-04 +1207 3.000000e-02 2.500000e+00 3.045539e-04 +1208 4.000000e-02 2.500000e+00 4.038641e-04 +1209 5.000000e-02 2.500000e+00 5.020939e-04 +1210 6.000000e-02 2.500000e+00 5.992562e-04 +1211 7.000000e-02 2.500000e+00 6.953628e-04 +1212 8.000000e-02 2.500000e+00 7.904251e-04 +1213 9.000000e-02 2.500000e+00 8.844539e-04 +1214 1.000000e-01 2.500000e+00 9.774598e-04 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1215 1.100000e-01 2.500000e+00 1.069957e-03 +1216 1.200000e-01 2.500000e+00 1.160942e-03 +1217 1.300000e-01 2.500000e+00 1.250933e-03 +1218 1.400000e-01 2.500000e+00 1.339940e-03 +1219 1.500000e-01 2.500000e+00 1.427972e-03 +1220 1.600000e-01 2.500000e+00 1.515038e-03 +1221 1.700000e-01 2.500000e+00 1.601148e-03 +1222 1.800000e-01 2.500000e+00 1.686309e-03 +1223 1.900000e-01 2.500000e+00 1.770531e-03 +1224 2.000000e-01 2.500000e+00 1.853822e-03 +1225 2.100000e-01 2.500000e+00 1.936192e-03 +1226 2.200000e-01 2.500000e+00 2.017649e-03 +1227 2.300000e-01 2.500000e+00 2.098200e-03 +1228 2.400000e-01 2.500000e+00 2.177854e-03 +1229 2.500000e-01 2.500000e+00 2.256620e-03 +1230 2.600000e-01 2.500000e+00 2.334505e-03 +1231 2.700000e-01 2.500000e+00 2.411518e-03 +1232 2.800000e-01 2.500000e+00 2.487665e-03 +1233 2.900000e-01 2.500000e+00 2.562955e-03 +1234 3.000000e-01 2.500000e+00 2.637395e-03 +1235 3.100000e-01 2.500000e+00 2.710992e-03 +1236 3.200000e-01 2.500000e+00 2.783753e-03 +1237 3.300000e-01 2.500000e+00 2.855686e-03 +1238 3.400000e-01 2.500000e+00 2.926797e-03 +1239 3.500000e-01 2.500000e+00 2.997093e-03 +1240 3.600000e-01 2.500000e+00 3.066581e-03 +1241 3.700000e-01 2.500000e+00 3.135267e-03 +1242 3.800000e-01 2.500000e+00 3.203158e-03 +1243 3.900000e-01 2.500000e+00 3.270259e-03 +1244 4.000000e-01 2.500000e+00 3.336576e-03 +1245 4.100000e-01 2.500000e+00 3.402116e-03 +1246 4.200000e-01 2.500000e+00 3.466885e-03 +1247 4.300000e-01 2.500000e+00 3.530888e-03 +1248 4.400000e-01 2.500000e+00 3.594131e-03 +1249 4.500000e-01 2.500000e+00 3.656619e-03 +1250 4.600000e-01 2.500000e+00 3.718357e-03 +1251 4.700000e-01 2.500000e+00 3.779351e-03 +1252 4.800000e-01 2.500000e+00 3.839606e-03 +1253 4.900000e-01 2.500000e+00 3.899127e-03 +1254 5.000000e-01 2.500000e+00 3.957919e-03 +1255 5.100000e-01 2.500000e+00 4.015987e-03 +1256 5.200000e-01 2.500000e+00 4.073335e-03 +1257 5.300000e-01 2.500000e+00 4.129968e-03 +1258 5.400000e-01 2.500000e+00 4.185890e-03 +1259 5.500000e-01 2.500000e+00 4.241107e-03 +1260 5.600000e-01 2.500000e+00 4.295622e-03 +1261 5.700000e-01 2.500000e+00 4.349440e-03 +1262 5.800000e-01 2.500000e+00 4.402564e-03 +1263 5.900000e-01 2.500000e+00 4.455000e-03 +1264 6.000000e-01 2.500000e+00 4.506750e-03 +1265 6.100000e-01 2.500000e+00 4.557820e-03 +1266 6.200000e-01 2.500000e+00 4.608212e-03 +1267 6.300000e-01 2.500000e+00 4.657931e-03 +1268 6.400000e-01 2.500000e+00 4.706980e-03 +1269 6.500000e-01 2.500000e+00 4.755363e-03 +1270 6.600000e-01 2.500000e+00 4.803084e-03 +1271 6.700000e-01 2.500000e+00 4.850146e-03 +1272 6.800000e-01 2.500000e+00 4.896552e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1273 6.900000e-01 2.500000e+00 4.942306e-03 +1274 7.000000e-01 2.500000e+00 4.987411e-03 +1275 7.100000e-01 2.500000e+00 5.031870e-03 +1276 7.200000e-01 2.500000e+00 5.075687e-03 +1277 7.300000e-01 2.500000e+00 5.118864e-03 +1278 7.400000e-01 2.500000e+00 5.161405e-03 +1279 7.500000e-01 2.500000e+00 5.203312e-03 +1280 7.600000e-01 2.500000e+00 5.244588e-03 +1281 7.700000e-01 2.500000e+00 5.285236e-03 +1282 7.800000e-01 2.500000e+00 5.325259e-03 +1283 7.900000e-01 2.500000e+00 5.364660e-03 +1284 8.000000e-01 2.500000e+00 5.403440e-03 +1285 8.100000e-01 2.500000e+00 5.441602e-03 +1286 8.200000e-01 2.500000e+00 5.479149e-03 +1287 8.300000e-01 2.500000e+00 5.516083e-03 +1288 8.400000e-01 2.500000e+00 5.552407e-03 +1289 8.500000e-01 2.500000e+00 5.588121e-03 +1290 8.600000e-01 2.500000e+00 5.623229e-03 +1291 8.700000e-01 2.500000e+00 5.657733e-03 +1292 8.800000e-01 2.500000e+00 5.691633e-03 +1293 8.900000e-01 2.500000e+00 5.724933e-03 +1294 9.000000e-01 2.500000e+00 5.757634e-03 +1295 9.100000e-01 2.500000e+00 5.789738e-03 +1296 9.200000e-01 2.500000e+00 5.821247e-03 +1297 9.300000e-01 2.500000e+00 5.852161e-03 +1298 9.400000e-01 2.500000e+00 5.882485e-03 +1299 9.500000e-01 2.500000e+00 5.912218e-03 +1300 9.600000e-01 2.500000e+00 5.941364e-03 +1301 9.700000e-01 2.500000e+00 5.969925e-03 +1302 9.800000e-01 2.500000e+00 5.997903e-03 +1303 9.900000e-01 2.500000e+00 6.025303e-03 +1304 1.000000e+00 2.500000e+00 6.052127e-03 +1305 1.010000e+00 2.500000e+00 6.078380e-03 +1306 1.020000e+00 2.500000e+00 6.104068e-03 +1307 1.030000e+00 2.500000e+00 6.129197e-03 +1308 1.040000e+00 2.500000e+00 6.153776e-03 +1309 1.050000e+00 2.500000e+00 6.177814e-03 +1310 1.060000e+00 2.500000e+00 6.201322e-03 +1311 1.070000e+00 2.500000e+00 6.224315e-03 +1312 1.080000e+00 2.500000e+00 6.246810e-03 +1313 1.090000e+00 2.500000e+00 6.268826e-03 +1314 1.100000e+00 2.500000e+00 6.290386e-03 +1315 1.110000e+00 2.500000e+00 6.311518e-03 +1316 1.120000e+00 2.500000e+00 6.332252e-03 +1317 1.130000e+00 2.500000e+00 6.352624e-03 +1318 1.140000e+00 2.500000e+00 6.372674e-03 +1319 1.150000e+00 2.500000e+00 6.392444e-03 +1320 1.160000e+00 2.500000e+00 6.411982e-03 +1321 1.170000e+00 2.500000e+00 6.431339e-03 +1322 1.180000e+00 2.500000e+00 6.450568e-03 +1323 1.190000e+00 2.500000e+00 6.469722e-03 +1324 1.200000e+00 2.500000e+00 6.488856e-03 +1325 1.210000e+00 2.500000e+00 6.508019e-03 +1326 1.220000e+00 2.500000e+00 6.527259e-03 +1327 1.230000e+00 2.500000e+00 6.546618e-03 +1328 1.240000e+00 2.500000e+00 6.566127e-03 +1329 1.250000e+00 2.500000e+00 6.585809e-03 +1330 1.260000e+00 2.500000e+00 6.605678e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1331 1.270000e+00 2.500000e+00 6.625733e-03 +1332 1.280000e+00 2.500000e+00 6.645964e-03 +1333 1.290000e+00 2.500000e+00 6.666366e-03 +1334 1.300000e+00 2.500000e+00 6.687001e-03 +1335 1.310000e+00 2.500000e+00 6.707756e-03 +1336 1.320000e+00 2.500000e+00 6.728571e-03 +1337 1.330000e+00 2.500000e+00 6.749387e-03 +1338 1.340000e+00 2.500000e+00 6.770149e-03 +1339 1.350000e+00 2.500000e+00 6.790805e-03 +1340 1.360000e+00 2.500000e+00 6.811309e-03 +1341 1.370000e+00 2.500000e+00 6.831622e-03 +1342 1.380000e+00 2.500000e+00 6.851711e-03 +1343 1.390000e+00 2.500000e+00 6.871549e-03 +1344 1.400000e+00 2.500000e+00 6.891117e-03 +1345 1.410000e+00 2.500000e+00 6.910399e-03 +1346 1.420000e+00 2.500000e+00 6.929386e-03 +1347 1.430000e+00 2.500000e+00 6.948072e-03 +1348 1.440000e+00 2.500000e+00 6.966454e-03 +1349 1.450000e+00 2.500000e+00 6.984534e-03 +1350 1.460000e+00 2.500000e+00 7.002316e-03 +1351 1.470000e+00 2.500000e+00 7.019803e-03 +1352 1.480000e+00 2.500000e+00 7.037003e-03 +1353 1.490000e+00 2.500000e+00 7.053923e-03 +1354 1.500000e+00 2.500000e+00 7.070571e-03 +1355 1.510000e+00 2.500000e+00 7.086957e-03 +1356 1.520000e+00 2.500000e+00 7.103088e-03 +1357 1.530000e+00 2.500000e+00 7.118974e-03 +1358 1.540000e+00 2.500000e+00 7.134625e-03 +1359 1.550000e+00 2.500000e+00 7.150048e-03 +1360 1.560000e+00 2.500000e+00 7.165252e-03 +1361 1.570000e+00 2.500000e+00 7.180247e-03 +1362 1.580000e+00 2.500000e+00 7.195040e-03 +1363 1.590000e+00 2.500000e+00 7.209638e-03 +1364 1.600000e+00 2.500000e+00 7.224051e-03 +1365 1.610000e+00 2.500000e+00 7.238284e-03 +1366 1.620000e+00 2.500000e+00 7.252345e-03 +1367 1.630000e+00 2.500000e+00 7.266240e-03 +1368 1.640000e+00 2.500000e+00 7.279976e-03 +1369 1.650000e+00 2.500000e+00 7.293559e-03 +1370 1.660000e+00 2.500000e+00 7.306994e-03 +1371 1.670000e+00 2.500000e+00 7.320286e-03 +1372 1.680000e+00 2.500000e+00 7.333442e-03 +1373 1.690000e+00 2.500000e+00 7.346466e-03 +1374 1.700000e+00 2.500000e+00 7.359362e-03 +1375 1.710000e+00 2.500000e+00 7.372135e-03 +1376 1.720000e+00 2.500000e+00 7.384790e-03 +1377 1.730000e+00 2.500000e+00 7.397329e-03 +1378 1.740000e+00 2.500000e+00 7.409758e-03 +1379 1.750000e+00 2.500000e+00 7.422080e-03 +1380 1.760000e+00 2.500000e+00 7.434297e-03 +1381 1.770000e+00 2.500000e+00 7.446414e-03 +1382 1.780000e+00 2.500000e+00 7.458434e-03 +1383 1.790000e+00 2.500000e+00 7.470359e-03 +1384 1.800000e+00 2.500000e+00 7.482192e-03 +1385 1.810000e+00 2.500000e+00 7.493937e-03 +1386 1.820000e+00 2.500000e+00 7.505594e-03 +1387 1.830000e+00 2.500000e+00 7.517167e-03 +1388 1.840000e+00 2.500000e+00 7.528658e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1389 1.850000e+00 2.500000e+00 7.540070e-03 +1390 1.860000e+00 2.500000e+00 7.551403e-03 +1391 1.870000e+00 2.500000e+00 7.562660e-03 +1392 1.880000e+00 2.500000e+00 7.573843e-03 +1393 1.890000e+00 2.500000e+00 7.584953e-03 +1394 1.900000e+00 2.500000e+00 7.595992e-03 +1395 1.910000e+00 2.500000e+00 7.606961e-03 +1396 1.920000e+00 2.500000e+00 7.617862e-03 +1397 1.930000e+00 2.500000e+00 7.628697e-03 +1398 1.940000e+00 2.500000e+00 7.639466e-03 +1399 1.950000e+00 2.500000e+00 7.650170e-03 +1400 1.960000e+00 2.500000e+00 7.660811e-03 +1401 1.970000e+00 2.500000e+00 7.671390e-03 +1402 1.980000e+00 2.500000e+00 7.681909e-03 +1403 1.990000e+00 2.500000e+00 7.692367e-03 +1404 2.000000e+00 2.500000e+00 7.702766e-03 +1405 2.010000e+00 2.500000e+00 7.713108e-03 +1406 2.020000e+00 2.500000e+00 7.723392e-03 +1407 2.030000e+00 2.500000e+00 7.733620e-03 +1408 2.040000e+00 2.500000e+00 7.743793e-03 +1409 2.050000e+00 2.500000e+00 7.753912e-03 +1410 2.060000e+00 2.500000e+00 7.763977e-03 +1411 2.070000e+00 2.500000e+00 7.773990e-03 +1412 2.080000e+00 2.500000e+00 7.783951e-03 +1413 2.090000e+00 2.500000e+00 7.793861e-03 +1414 2.100000e+00 2.500000e+00 7.803721e-03 +1415 2.110000e+00 2.500000e+00 7.813532e-03 +1416 2.120000e+00 2.500000e+00 7.823294e-03 +1417 2.130000e+00 2.500000e+00 7.833009e-03 +1418 2.140000e+00 2.500000e+00 7.842677e-03 +1419 2.150000e+00 2.500000e+00 7.852298e-03 +1420 2.160000e+00 2.500000e+00 7.861874e-03 +1421 2.170000e+00 2.500000e+00 7.871405e-03 +1422 2.180000e+00 2.500000e+00 7.880893e-03 +1423 2.190000e+00 2.500000e+00 7.890337e-03 +1424 2.200000e+00 2.500000e+00 7.899739e-03 +1425 2.210000e+00 2.500000e+00 7.909098e-03 +1426 2.220000e+00 2.500000e+00 7.918417e-03 +1427 2.230000e+00 2.500000e+00 7.927695e-03 +1428 2.240000e+00 2.500000e+00 7.936933e-03 +1429 2.250000e+00 2.500000e+00 7.946132e-03 +1430 2.260000e+00 2.500000e+00 7.955292e-03 +1431 2.270000e+00 2.500000e+00 7.964415e-03 +1432 2.280000e+00 2.500000e+00 7.973500e-03 +1433 2.290000e+00 2.500000e+00 7.982548e-03 +1434 2.300000e+00 2.500000e+00 7.991560e-03 +1435 2.310000e+00 2.500000e+00 8.000537e-03 +1436 2.320000e+00 2.500000e+00 8.009479e-03 +1437 2.330000e+00 2.500000e+00 8.018386e-03 +1438 2.340000e+00 2.500000e+00 8.027260e-03 +1439 2.350000e+00 2.500000e+00 8.036100e-03 +1440 2.360000e+00 2.500000e+00 8.044907e-03 +1441 2.370000e+00 2.500000e+00 8.053682e-03 +1442 2.380000e+00 2.500000e+00 8.062426e-03 +1443 2.390000e+00 2.500000e+00 8.071138e-03 +1444 2.400000e+00 2.500000e+00 8.079819e-03 +1445 2.410000e+00 2.500000e+00 8.088470e-03 +1446 2.420000e+00 2.500000e+00 8.097092e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1447 2.430000e+00 2.500000e+00 8.105684e-03 +1448 2.440000e+00 2.500000e+00 8.114247e-03 +1449 2.450000e+00 2.500000e+00 8.122781e-03 +1450 2.460000e+00 2.500000e+00 8.131288e-03 +1451 2.470000e+00 2.500000e+00 8.139767e-03 +1452 2.480000e+00 2.500000e+00 8.148219e-03 +1453 2.490000e+00 2.500000e+00 8.156645e-03 +1454 2.500000e+00 2.500000e+00 8.165044e-03 +1455 2.510000e+00 2.500000e+00 8.173417e-03 +1456 2.520000e+00 2.500000e+00 8.181765e-03 +1457 2.530000e+00 2.500000e+00 8.190088e-03 +1458 2.540000e+00 2.500000e+00 8.198385e-03 +1459 2.550000e+00 2.500000e+00 8.206659e-03 +1460 2.560000e+00 2.500000e+00 8.214909e-03 +1461 2.570000e+00 2.500000e+00 8.223135e-03 +1462 2.580000e+00 2.500000e+00 8.231338e-03 +1463 2.590000e+00 2.500000e+00 8.239518e-03 +1464 2.600000e+00 2.500000e+00 8.247675e-03 +1465 2.610000e+00 2.500000e+00 8.255810e-03 +1466 2.620000e+00 2.500000e+00 8.263924e-03 +1467 2.630000e+00 2.500000e+00 8.272016e-03 +1468 2.640000e+00 2.500000e+00 8.280086e-03 +1469 2.650000e+00 2.500000e+00 8.288136e-03 +1470 2.660000e+00 2.500000e+00 8.296165e-03 +1471 2.670000e+00 2.500000e+00 8.304174e-03 +1472 2.680000e+00 2.500000e+00 8.312163e-03 +1473 2.690000e+00 2.500000e+00 8.320132e-03 +1474 2.700000e+00 2.500000e+00 8.328082e-03 +1475 2.710000e+00 2.500000e+00 8.336013e-03 +1476 2.720000e+00 2.500000e+00 8.343925e-03 +1477 2.730000e+00 2.500000e+00 8.351819e-03 +1478 2.740000e+00 2.500000e+00 8.359694e-03 +1479 2.750000e+00 2.500000e+00 8.367552e-03 +1480 2.760000e+00 2.500000e+00 8.375391e-03 +1481 2.770000e+00 2.500000e+00 8.383213e-03 +1482 2.780000e+00 2.500000e+00 8.391018e-03 +1483 2.790000e+00 2.500000e+00 8.398807e-03 +1484 2.800000e+00 2.500000e+00 8.406578e-03 +1485 2.810000e+00 2.500000e+00 8.414333e-03 +1486 2.820000e+00 2.500000e+00 8.422072e-03 +1487 2.830000e+00 2.500000e+00 8.429795e-03 +1488 2.840000e+00 2.500000e+00 8.437502e-03 +1489 2.850000e+00 2.500000e+00 8.445194e-03 +1490 2.860000e+00 2.500000e+00 8.452870e-03 +1491 2.870000e+00 2.500000e+00 8.460532e-03 +1492 2.880000e+00 2.500000e+00 8.468179e-03 +1493 2.890000e+00 2.500000e+00 8.475811e-03 +1494 2.900000e+00 2.500000e+00 8.483429e-03 +1495 2.910000e+00 2.500000e+00 8.491032e-03 +1496 2.920000e+00 2.500000e+00 8.498622e-03 +1497 2.930000e+00 2.500000e+00 8.506198e-03 +1498 2.940000e+00 2.500000e+00 8.513760e-03 +1499 2.950000e+00 2.500000e+00 8.521310e-03 +1500 2.960000e+00 2.500000e+00 8.528846e-03 +1501 2.970000e+00 2.500000e+00 8.536369e-03 +1502 2.980000e+00 2.500000e+00 8.543879e-03 +1503 2.990000e+00 2.500000e+00 8.551377e-03 +1504 3.000000e+00 2.500000e+00 8.558862e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1505 0.000000e+00 3.000000e+00 -1.832939e-40 +1506 1.000000e-02 3.000000e+00 1.118014e-04 +1507 2.000000e-02 3.000000e+00 2.225797e-04 +1508 3.000000e-02 3.000000e+00 3.323487e-04 +1509 4.000000e-02 3.000000e+00 4.411212e-04 +1510 5.000000e-02 3.000000e+00 5.489088e-04 +1511 6.000000e-02 3.000000e+00 6.557227e-04 +1512 7.000000e-02 3.000000e+00 7.615731e-04 +1513 8.000000e-02 3.000000e+00 8.664696e-04 +1514 9.000000e-02 3.000000e+00 9.704215e-04 +1515 1.000000e-01 3.000000e+00 1.073438e-03 +1516 1.100000e-01 3.000000e+00 1.175989e-03 +1517 1.200000e-01 3.000000e+00 1.277155e-03 +1518 1.300000e-01 3.000000e+00 1.377409e-03 +1519 1.400000e-01 3.000000e+00 1.476761e-03 +1520 1.500000e-01 3.000000e+00 1.575218e-03 +1521 1.600000e-01 3.000000e+00 1.672788e-03 +1522 1.700000e-01 3.000000e+00 1.769477e-03 +1523 1.800000e-01 3.000000e+00 1.865295e-03 +1524 1.900000e-01 3.000000e+00 1.960248e-03 +1525 2.000000e-01 3.000000e+00 2.054343e-03 +1526 2.100000e-01 3.000000e+00 2.147589e-03 +1527 2.200000e-01 3.000000e+00 2.239991e-03 +1528 2.300000e-01 3.000000e+00 2.331559e-03 +1529 2.400000e-01 3.000000e+00 2.422297e-03 +1530 2.500000e-01 3.000000e+00 2.512214e-03 +1531 2.600000e-01 3.000000e+00 2.601316e-03 +1532 2.700000e-01 3.000000e+00 2.689610e-03 +1533 2.800000e-01 3.000000e+00 2.777103e-03 +1534 2.900000e-01 3.000000e+00 2.863800e-03 +1535 3.000000e-01 3.000000e+00 2.949709e-03 +1536 3.100000e-01 3.000000e+00 3.034836e-03 +1537 3.200000e-01 3.000000e+00 3.119186e-03 +1538 3.300000e-01 3.000000e+00 3.202766e-03 +1539 3.400000e-01 3.000000e+00 3.285582e-03 +1540 3.500000e-01 3.000000e+00 3.367639e-03 +1541 3.600000e-01 3.000000e+00 3.448942e-03 +1542 3.700000e-01 3.000000e+00 3.529499e-03 +1543 3.800000e-01 3.000000e+00 3.609313e-03 +1544 3.900000e-01 3.000000e+00 3.688391e-03 +1545 4.000000e-01 3.000000e+00 3.766736e-03 +1546 4.100000e-01 3.000000e+00 3.844356e-03 +1547 4.200000e-01 3.000000e+00 3.921253e-03 +1548 4.300000e-01 3.000000e+00 3.997434e-03 +1549 4.400000e-01 3.000000e+00 4.072903e-03 +1550 4.500000e-01 3.000000e+00 4.147664e-03 +1551 4.600000e-01 3.000000e+00 4.221722e-03 +1552 4.700000e-01 3.000000e+00 4.295082e-03 +1553 4.800000e-01 3.000000e+00 4.367748e-03 +1554 4.900000e-01 3.000000e+00 4.439724e-03 +1555 5.000000e-01 3.000000e+00 4.511015e-03 +1556 5.100000e-01 3.000000e+00 4.581624e-03 +1557 5.200000e-01 3.000000e+00 4.651555e-03 +1558 5.300000e-01 3.000000e+00 4.720813e-03 +1559 5.400000e-01 3.000000e+00 4.789401e-03 +1560 5.500000e-01 3.000000e+00 4.857323e-03 +1561 5.600000e-01 3.000000e+00 4.924582e-03 +1562 5.700000e-01 3.000000e+00 4.991183e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1563 5.800000e-01 3.000000e+00 5.057129e-03 +1564 5.900000e-01 3.000000e+00 5.122423e-03 +1565 6.000000e-01 3.000000e+00 5.187068e-03 +1566 6.100000e-01 3.000000e+00 5.251069e-03 +1567 6.200000e-01 3.000000e+00 5.314428e-03 +1568 6.300000e-01 3.000000e+00 5.377149e-03 +1569 6.400000e-01 3.000000e+00 5.439235e-03 +1570 6.500000e-01 3.000000e+00 5.500688e-03 +1571 6.600000e-01 3.000000e+00 5.561512e-03 +1572 6.700000e-01 3.000000e+00 5.621710e-03 +1573 6.800000e-01 3.000000e+00 5.681285e-03 +1574 6.900000e-01 3.000000e+00 5.740240e-03 +1575 7.000000e-01 3.000000e+00 5.798577e-03 +1576 7.100000e-01 3.000000e+00 5.856299e-03 +1577 7.200000e-01 3.000000e+00 5.913409e-03 +1578 7.300000e-01 3.000000e+00 5.969910e-03 +1579 7.400000e-01 3.000000e+00 6.025805e-03 +1580 7.500000e-01 3.000000e+00 6.081095e-03 +1581 7.600000e-01 3.000000e+00 6.135784e-03 +1582 7.700000e-01 3.000000e+00 6.189873e-03 +1583 7.800000e-01 3.000000e+00 6.243366e-03 +1584 7.900000e-01 3.000000e+00 6.296265e-03 +1585 8.000000e-01 3.000000e+00 6.348572e-03 +1586 8.100000e-01 3.000000e+00 6.400289e-03 +1587 8.200000e-01 3.000000e+00 6.451419e-03 +1588 8.300000e-01 3.000000e+00 6.501964e-03 +1589 8.400000e-01 3.000000e+00 6.551926e-03 +1590 8.500000e-01 3.000000e+00 6.601307e-03 +1591 8.600000e-01 3.000000e+00 6.650110e-03 +1592 8.700000e-01 3.000000e+00 6.698336e-03 +1593 8.800000e-01 3.000000e+00 6.745988e-03 +1594 8.900000e-01 3.000000e+00 6.793067e-03 +1595 9.000000e-01 3.000000e+00 6.839575e-03 +1596 9.100000e-01 3.000000e+00 6.885515e-03 +1597 9.200000e-01 3.000000e+00 6.930887e-03 +1598 9.300000e-01 3.000000e+00 6.975695e-03 +1599 9.400000e-01 3.000000e+00 7.019939e-03 +1600 9.500000e-01 3.000000e+00 7.063622e-03 +1601 9.600000e-01 3.000000e+00 7.106745e-03 +1602 9.700000e-01 3.000000e+00 7.149310e-03 +1603 9.800000e-01 3.000000e+00 7.191319e-03 +1604 9.900000e-01 3.000000e+00 7.232772e-03 +1605 1.000000e+00 3.000000e+00 7.273673e-03 +1606 1.010000e+00 3.000000e+00 7.314022e-03 +1607 1.020000e+00 3.000000e+00 7.353821e-03 +1608 1.030000e+00 3.000000e+00 7.393072e-03 +1609 1.040000e+00 3.000000e+00 7.431777e-03 +1610 1.050000e+00 3.000000e+00 7.469938e-03 +1611 1.060000e+00 3.000000e+00 7.507556e-03 +1612 1.070000e+00 3.000000e+00 7.544635e-03 +1613 1.080000e+00 3.000000e+00 7.581176e-03 +1614 1.090000e+00 3.000000e+00 7.617182e-03 +1615 1.100000e+00 3.000000e+00 7.652658e-03 +1616 1.110000e+00 3.000000e+00 7.687606e-03 +1617 1.120000e+00 3.000000e+00 7.722032e-03 +1618 1.130000e+00 3.000000e+00 7.755940e-03 +1619 1.140000e+00 3.000000e+00 7.789337e-03 +1620 1.150000e+00 3.000000e+00 7.822231e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1621 1.160000e+00 3.000000e+00 7.854630e-03 +1622 1.170000e+00 3.000000e+00 7.886544e-03 +1623 1.180000e+00 3.000000e+00 7.917987e-03 +1624 1.190000e+00 3.000000e+00 7.948971e-03 +1625 1.200000e+00 3.000000e+00 7.979514e-03 +1626 1.210000e+00 3.000000e+00 8.009636e-03 +1627 1.220000e+00 3.000000e+00 8.039357e-03 +1628 1.230000e+00 3.000000e+00 8.068703e-03 +1629 1.240000e+00 3.000000e+00 8.097703e-03 +1630 1.250000e+00 3.000000e+00 8.126387e-03 +1631 1.260000e+00 3.000000e+00 8.154791e-03 +1632 1.270000e+00 3.000000e+00 8.182952e-03 +1633 1.280000e+00 3.000000e+00 8.210910e-03 +1634 1.290000e+00 3.000000e+00 8.238706e-03 +1635 1.300000e+00 3.000000e+00 8.266382e-03 +1636 1.310000e+00 3.000000e+00 8.293981e-03 +1637 1.320000e+00 3.000000e+00 8.321541e-03 +1638 1.330000e+00 3.000000e+00 8.349098e-03 +1639 1.340000e+00 3.000000e+00 8.376683e-03 +1640 1.350000e+00 3.000000e+00 8.404317e-03 +1641 1.360000e+00 3.000000e+00 8.432015e-03 +1642 1.370000e+00 3.000000e+00 8.459778e-03 +1643 1.380000e+00 3.000000e+00 8.487660e-03 +1644 1.390000e+00 3.000000e+00 8.515642e-03 +1645 1.400000e+00 3.000000e+00 8.543664e-03 +1646 1.410000e+00 3.000000e+00 8.571675e-03 +1647 1.420000e+00 3.000000e+00 8.599622e-03 +1648 1.430000e+00 3.000000e+00 8.627444e-03 +1649 1.440000e+00 3.000000e+00 8.655084e-03 +1650 1.450000e+00 3.000000e+00 8.682485e-03 +1651 1.460000e+00 3.000000e+00 8.709594e-03 +1652 1.470000e+00 3.000000e+00 8.736364e-03 +1653 1.480000e+00 3.000000e+00 8.762756e-03 +1654 1.490000e+00 3.000000e+00 8.788736e-03 +1655 1.500000e+00 3.000000e+00 8.814279e-03 +1656 1.510000e+00 3.000000e+00 8.839365e-03 +1657 1.520000e+00 3.000000e+00 8.863983e-03 +1658 1.530000e+00 3.000000e+00 8.888125e-03 +1659 1.540000e+00 3.000000e+00 8.911791e-03 +1660 1.550000e+00 3.000000e+00 8.934981e-03 +1661 1.560000e+00 3.000000e+00 8.957703e-03 +1662 1.570000e+00 3.000000e+00 8.979966e-03 +1663 1.580000e+00 3.000000e+00 9.001779e-03 +1664 1.590000e+00 3.000000e+00 9.023156e-03 +1665 1.600000e+00 3.000000e+00 9.044110e-03 +1666 1.610000e+00 3.000000e+00 9.064655e-03 +1667 1.620000e+00 3.000000e+00 9.084806e-03 +1668 1.630000e+00 3.000000e+00 9.104578e-03 +1669 1.640000e+00 3.000000e+00 9.123987e-03 +1670 1.650000e+00 3.000000e+00 9.143046e-03 +1671 1.660000e+00 3.000000e+00 9.161770e-03 +1672 1.670000e+00 3.000000e+00 9.180174e-03 +1673 1.680000e+00 3.000000e+00 9.198270e-03 +1674 1.690000e+00 3.000000e+00 9.216072e-03 +1675 1.700000e+00 3.000000e+00 9.233593e-03 +1676 1.710000e+00 3.000000e+00 9.250844e-03 +1677 1.720000e+00 3.000000e+00 9.267837e-03 +1678 1.730000e+00 3.000000e+00 9.284583e-03 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1679 1.740000e+00 3.000000e+00 9.301092e-03 +1680 1.750000e+00 3.000000e+00 9.317375e-03 +1681 1.760000e+00 3.000000e+00 9.333440e-03 +1682 1.770000e+00 3.000000e+00 9.349296e-03 +1683 1.780000e+00 3.000000e+00 9.364953e-03 +1684 1.790000e+00 3.000000e+00 9.380418e-03 +1685 1.800000e+00 3.000000e+00 9.395699e-03 +1686 1.810000e+00 3.000000e+00 9.410803e-03 +1687 1.820000e+00 3.000000e+00 9.425737e-03 +1688 1.830000e+00 3.000000e+00 9.440507e-03 +1689 1.840000e+00 3.000000e+00 9.455120e-03 +1690 1.850000e+00 3.000000e+00 9.469581e-03 +1691 1.860000e+00 3.000000e+00 9.483896e-03 +1692 1.870000e+00 3.000000e+00 9.498070e-03 +1693 1.880000e+00 3.000000e+00 9.512109e-03 +1694 1.890000e+00 3.000000e+00 9.526016e-03 +1695 1.900000e+00 3.000000e+00 9.539796e-03 +1696 1.910000e+00 3.000000e+00 9.553454e-03 +1697 1.920000e+00 3.000000e+00 9.566992e-03 +1698 1.930000e+00 3.000000e+00 9.580416e-03 +1699 1.940000e+00 3.000000e+00 9.593728e-03 +1700 1.950000e+00 3.000000e+00 9.606932e-03 +1701 1.960000e+00 3.000000e+00 9.620030e-03 +1702 1.970000e+00 3.000000e+00 9.633026e-03 +1703 1.980000e+00 3.000000e+00 9.645923e-03 +1704 1.990000e+00 3.000000e+00 9.658723e-03 +1705 2.000000e+00 3.000000e+00 9.671428e-03 +1706 2.010000e+00 3.000000e+00 9.684041e-03 +1707 2.020000e+00 3.000000e+00 9.696565e-03 +1708 2.030000e+00 3.000000e+00 9.709000e-03 +1709 2.040000e+00 3.000000e+00 9.721350e-03 +1710 2.050000e+00 3.000000e+00 9.733615e-03 +1711 2.060000e+00 3.000000e+00 9.745799e-03 +1712 2.070000e+00 3.000000e+00 9.757903e-03 +1713 2.080000e+00 3.000000e+00 9.769927e-03 +1714 2.090000e+00 3.000000e+00 9.781875e-03 +1715 2.100000e+00 3.000000e+00 9.793748e-03 +1716 2.110000e+00 3.000000e+00 9.805546e-03 +1717 2.120000e+00 3.000000e+00 9.817272e-03 +1718 2.130000e+00 3.000000e+00 9.828927e-03 +1719 2.140000e+00 3.000000e+00 9.840513e-03 +1720 2.150000e+00 3.000000e+00 9.852030e-03 +1721 2.160000e+00 3.000000e+00 9.863480e-03 +1722 2.170000e+00 3.000000e+00 9.874865e-03 +1723 2.180000e+00 3.000000e+00 9.886185e-03 +1724 2.190000e+00 3.000000e+00 9.897443e-03 +1725 2.200000e+00 3.000000e+00 9.908638e-03 +1726 2.210000e+00 3.000000e+00 9.919773e-03 +1727 2.220000e+00 3.000000e+00 9.930847e-03 +1728 2.230000e+00 3.000000e+00 9.941864e-03 +1729 2.240000e+00 3.000000e+00 9.952823e-03 +1730 2.250000e+00 3.000000e+00 9.963726e-03 +1731 2.260000e+00 3.000000e+00 9.974574e-03 +1732 2.270000e+00 3.000000e+00 9.985367e-03 +1733 2.280000e+00 3.000000e+00 9.996107e-03 +1734 2.290000e+00 3.000000e+00 1.000680e-02 +1735 2.300000e+00 3.000000e+00 1.001743e-02 +1736 2.310000e+00 3.000000e+00 1.002802e-02 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1737 2.320000e+00 3.000000e+00 1.003856e-02 +1738 2.330000e+00 3.000000e+00 1.004905e-02 +1739 2.340000e+00 3.000000e+00 1.005949e-02 +1740 2.350000e+00 3.000000e+00 1.006988e-02 +1741 2.360000e+00 3.000000e+00 1.008023e-02 +1742 2.370000e+00 3.000000e+00 1.009053e-02 +1743 2.380000e+00 3.000000e+00 1.010079e-02 +1744 2.390000e+00 3.000000e+00 1.011101e-02 +1745 2.400000e+00 3.000000e+00 1.012119e-02 +1746 2.410000e+00 3.000000e+00 1.013132e-02 +1747 2.420000e+00 3.000000e+00 1.014141e-02 +1748 2.430000e+00 3.000000e+00 1.015146e-02 +1749 2.440000e+00 3.000000e+00 1.016147e-02 +1750 2.450000e+00 3.000000e+00 1.017144e-02 +1751 2.460000e+00 3.000000e+00 1.018138e-02 +1752 2.470000e+00 3.000000e+00 1.019127e-02 +1753 2.480000e+00 3.000000e+00 1.020113e-02 +1754 2.490000e+00 3.000000e+00 1.021096e-02 +1755 2.500000e+00 3.000000e+00 1.022075e-02 +1756 2.510000e+00 3.000000e+00 1.023050e-02 +1757 2.520000e+00 3.000000e+00 1.024022e-02 +1758 2.530000e+00 3.000000e+00 1.024990e-02 +1759 2.540000e+00 3.000000e+00 1.025955e-02 +1760 2.550000e+00 3.000000e+00 1.026917e-02 +1761 2.560000e+00 3.000000e+00 1.027876e-02 +1762 2.570000e+00 3.000000e+00 1.028831e-02 +1763 2.580000e+00 3.000000e+00 1.029784e-02 +1764 2.590000e+00 3.000000e+00 1.030733e-02 +1765 2.600000e+00 3.000000e+00 1.031679e-02 +1766 2.610000e+00 3.000000e+00 1.032623e-02 +1767 2.620000e+00 3.000000e+00 1.033563e-02 +1768 2.630000e+00 3.000000e+00 1.034501e-02 +1769 2.640000e+00 3.000000e+00 1.035435e-02 +1770 2.650000e+00 3.000000e+00 1.036367e-02 +1771 2.660000e+00 3.000000e+00 1.037297e-02 +1772 2.670000e+00 3.000000e+00 1.038223e-02 +1773 2.680000e+00 3.000000e+00 1.039147e-02 +1774 2.690000e+00 3.000000e+00 1.040069e-02 +1775 2.700000e+00 3.000000e+00 1.040988e-02 +1776 2.710000e+00 3.000000e+00 1.041904e-02 +1777 2.720000e+00 3.000000e+00 1.042818e-02 +1778 2.730000e+00 3.000000e+00 1.043729e-02 +1779 2.740000e+00 3.000000e+00 1.044638e-02 +1780 2.750000e+00 3.000000e+00 1.045545e-02 +1781 2.760000e+00 3.000000e+00 1.046449e-02 +1782 2.770000e+00 3.000000e+00 1.047352e-02 +1783 2.780000e+00 3.000000e+00 1.048252e-02 +1784 2.790000e+00 3.000000e+00 1.049149e-02 +1785 2.800000e+00 3.000000e+00 1.050045e-02 +1786 2.810000e+00 3.000000e+00 1.050938e-02 +1787 2.820000e+00 3.000000e+00 1.051829e-02 +1788 2.830000e+00 3.000000e+00 1.052719e-02 +1789 2.840000e+00 3.000000e+00 1.053606e-02 +1790 2.850000e+00 3.000000e+00 1.054491e-02 +1791 2.860000e+00 3.000000e+00 1.055374e-02 +1792 2.870000e+00 3.000000e+00 1.056256e-02 +1793 2.880000e+00 3.000000e+00 1.057135e-02 +1794 2.890000e+00 3.000000e+00 1.058012e-02 + +Index v-sweep v(g) vs#branch +-------------------------------------------------------------------------------- +1795 2.900000e+00 3.000000e+00 1.058888e-02 +1796 2.910000e+00 3.000000e+00 1.059762e-02 +1797 2.920000e+00 3.000000e+00 1.060634e-02 +1798 2.930000e+00 3.000000e+00 1.061504e-02 +1799 2.940000e+00 3.000000e+00 1.062372e-02 +1800 2.950000e+00 3.000000e+00 1.063239e-02 +1801 2.960000e+00 3.000000e+00 1.064104e-02 +1802 2.970000e+00 3.000000e+00 1.064968e-02 +1803 2.980000e+00 3.000000e+00 1.065829e-02 +1804 2.990000e+00 3.000000e+00 1.066690e-02 +1805 3.000000e+00 3.000000e+00 1.067548e-02 + + + + diff --git a/tests/bsim3soipd/t4.cir b/tests/bsim3soipd/t4.cir new file mode 100644 index 000000000..e7b3fabe0 --- /dev/null +++ b/tests/bsim3soipd/t4.cir @@ -0,0 +1,18 @@ +*model = BSIMSOI (PD) +*Berkeley Spice Compatibility +* +* SOI NMOSFET, tied body simulation + +vd d 0 dc 0.05 +vs s 0 dc 0 +ve e 0 dc 0 +vg g 0 dc 3 +vb b 0 dc 0 + +m1 d g s e b n1 w=10u l=0.25u + +.option gmin=1e-25 itl1=500 +.dc vg 0 1.5 0.01 vb -0.3 0.5 0.1 +.print dc i(vs) +.include nmospd.mod + diff --git a/tests/bsim3soipd/t4.out b/tests/bsim3soipd/t4.out new file mode 100644 index 000000000..9308a92d2 --- /dev/null +++ b/tests/bsim3soipd/t4.out @@ -0,0 +1,1444 @@ + Reference value : 6.50000e-01 +No. of Data Rows : 1359 + +Circuit: *model = BSIMSOI (PD) + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. + *model = BSIMSOI (PD) +-------------------------------------------------------------------------------- +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 8.433234e-11 +1 1.000000e-02 1.173853e-10 +2 2.000000e-02 1.632588e-10 +3 3.000000e-02 2.268841e-10 +4 4.000000e-02 3.150653e-10 +5 5.000000e-02 4.371752e-10 +6 6.000000e-02 6.061032e-10 +7 7.000000e-02 8.395378e-10 +8 8.000000e-02 1.161696e-09 +9 9.000000e-02 1.605642e-09 +10 1.000000e-01 2.216377e-09 +11 1.100000e-01 3.054930e-09 +12 1.200000e-01 4.203719e-09 +13 1.300000e-01 5.773527e-09 +14 1.400000e-01 7.912466e-09 +15 1.500000e-01 1.081736e-08 +16 1.600000e-01 1.474798e-08 +17 1.700000e-01 2.004465e-08 +18 1.800000e-01 2.714951e-08 +19 1.900000e-01 3.663184e-08 +20 2.000000e-01 4.921768e-08 +21 2.100000e-01 6.582364e-08 +22 2.200000e-01 8.759512e-08 +23 2.300000e-01 1.159487e-07 +24 2.400000e-01 1.526188e-07 +25 2.500000e-01 1.997099e-07 +26 2.600000e-01 2.597536e-07 +27 2.700000e-01 3.357750e-07 +28 2.800000e-01 4.313687e-07 +29 2.900000e-01 5.507868e-07 +30 3.000000e-01 6.990425e-07 +31 3.100000e-01 8.820264e-07 +32 3.200000e-01 1.106633e-06 +33 3.300000e-01 1.380887e-06 +34 3.400000e-01 1.714056e-06 +35 3.500000e-01 2.116720e-06 +36 3.600000e-01 2.600778e-06 +37 3.700000e-01 3.179341e-06 +38 3.800000e-01 3.866500e-06 +39 3.900000e-01 4.676920e-06 +40 4.000000e-01 5.625275e-06 +41 4.100000e-01 6.725549e-06 +42 4.200000e-01 7.990251e-06 +43 4.300000e-01 9.429650e-06 +44 4.400000e-01 1.105112e-05 +45 4.500000e-01 1.285872e-05 +46 4.600000e-01 1.485294e-05 +47 4.700000e-01 1.703086e-05 +48 4.800000e-01 1.938642e-05 +49 4.900000e-01 2.191092e-05 +50 5.000000e-01 2.459361e-05 +51 5.100000e-01 2.742233e-05 +52 5.200000e-01 3.038407e-05 +53 5.300000e-01 3.346549e-05 +54 5.400000e-01 3.665341e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +55 5.500000e-01 3.993505e-05 +56 5.600000e-01 4.325947e-05 +57 5.700000e-01 4.669870e-05 +58 5.800000e-01 5.019764e-05 +59 5.900000e-01 5.374699e-05 +60 6.000000e-01 5.733843e-05 +61 6.100000e-01 6.096457e-05 +62 6.200000e-01 6.461890e-05 +63 6.300000e-01 6.829571e-05 +64 6.400000e-01 7.199002e-05 +65 6.500000e-01 7.569748e-05 +66 6.600000e-01 7.941432e-05 +67 6.700000e-01 8.313730e-05 +68 6.800000e-01 8.686359e-05 +69 6.900000e-01 9.059074e-05 +70 7.000000e-01 9.431666e-05 +71 7.100000e-01 9.803951e-05 +72 7.200000e-01 1.017577e-04 +73 7.300000e-01 1.054700e-04 +74 7.400000e-01 1.091750e-04 +75 7.500000e-01 1.128718e-04 +76 7.600000e-01 1.165595e-04 +77 7.700000e-01 1.202374e-04 +78 7.800000e-01 1.239046e-04 +79 7.900000e-01 1.275607e-04 +80 8.000000e-01 1.312051e-04 +81 8.100000e-01 1.348374e-04 +82 8.200000e-01 1.384571e-04 +83 8.300000e-01 1.420638e-04 +84 8.400000e-01 1.456573e-04 +85 8.500000e-01 1.492373e-04 +86 8.600000e-01 1.528034e-04 +87 8.700000e-01 1.563555e-04 +88 8.800000e-01 1.598933e-04 +89 8.900000e-01 1.634167e-04 +90 9.000000e-01 1.669255e-04 +91 9.100000e-01 1.704194e-04 +92 9.200000e-01 1.738984e-04 +93 9.300000e-01 1.773623e-04 +94 9.400000e-01 1.808111e-04 +95 9.500000e-01 1.842445e-04 +96 9.600000e-01 1.876625e-04 +97 9.700000e-01 1.910649e-04 +98 9.800000e-01 1.944518e-04 +99 9.900000e-01 1.978229e-04 +100 1.000000e+00 2.011783e-04 +101 1.010000e+00 2.045178e-04 +102 1.020000e+00 2.078415e-04 +103 1.030000e+00 2.111491e-04 +104 1.040000e+00 2.144407e-04 +105 1.050000e+00 2.177162e-04 +106 1.060000e+00 2.209755e-04 +107 1.070000e+00 2.242186e-04 +108 1.080000e+00 2.274455e-04 +109 1.090000e+00 2.306562e-04 +110 1.100000e+00 2.338505e-04 +111 1.110000e+00 2.370284e-04 +112 1.120000e+00 2.401900e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +113 1.130000e+00 2.433351e-04 +114 1.140000e+00 2.464638e-04 +115 1.150000e+00 2.495761e-04 +116 1.160000e+00 2.526718e-04 +117 1.170000e+00 2.557511e-04 +118 1.180000e+00 2.588138e-04 +119 1.190000e+00 2.618599e-04 +120 1.200000e+00 2.648896e-04 +121 1.210000e+00 2.679026e-04 +122 1.220000e+00 2.708991e-04 +123 1.230000e+00 2.738790e-04 +124 1.240000e+00 2.768423e-04 +125 1.250000e+00 2.797890e-04 +126 1.260000e+00 2.827191e-04 +127 1.270000e+00 2.856326e-04 +128 1.280000e+00 2.885296e-04 +129 1.290000e+00 2.914099e-04 +130 1.300000e+00 2.942737e-04 +131 1.310000e+00 2.971209e-04 +132 1.320000e+00 2.999515e-04 +133 1.330000e+00 3.027655e-04 +134 1.340000e+00 3.055630e-04 +135 1.350000e+00 3.083440e-04 +136 1.360000e+00 3.111084e-04 +137 1.370000e+00 3.138564e-04 +138 1.380000e+00 3.165878e-04 +139 1.390000e+00 3.193027e-04 +140 1.400000e+00 3.220012e-04 +141 1.410000e+00 3.246833e-04 +142 1.420000e+00 3.273489e-04 +143 1.430000e+00 3.299982e-04 +144 1.440000e+00 3.326310e-04 +145 1.450000e+00 3.352476e-04 +146 1.460000e+00 3.378478e-04 +147 1.470000e+00 3.404317e-04 +148 1.480000e+00 3.429993e-04 +149 1.490000e+00 3.455507e-04 +150 1.500000e+00 3.480858e-04 +151 0.000000e+00 3.189255e-11 +152 1.000000e-02 4.435540e-11 +153 2.000000e-02 6.163784e-11 +154 3.000000e-02 8.559318e-11 +155 4.000000e-02 1.187814e-10 +156 5.000000e-02 1.647354e-10 +157 6.000000e-02 2.283245e-10 +158 7.000000e-02 3.162525e-10 +159 8.000000e-02 4.377338e-10 +160 9.000000e-02 6.054119e-10 +161 1.000000e-01 8.366013e-10 +162 1.100000e-01 1.154958e-09 +163 1.200000e-01 1.592716e-09 +164 1.300000e-01 2.193662e-09 +165 1.400000e-01 3.017072e-09 +166 1.500000e-01 4.142860e-09 +167 1.600000e-01 5.678277e-09 +168 1.700000e-01 7.766511e-09 +169 1.800000e-01 1.059761e-08 +170 1.900000e-01 1.442217e-08 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +171 2.000000e-01 1.956821e-08 +172 2.100000e-01 2.646166e-08 +173 2.200000e-01 3.565081e-08 +174 2.300000e-01 4.783488e-08 +175 2.400000e-01 6.389687e-08 +176 2.500000e-01 8.494072e-08 +177 2.600000e-01 1.123326e-07 +178 2.700000e-01 1.477468e-07 +179 2.800000e-01 1.932161e-07 +180 2.900000e-01 2.511888e-07 +181 3.000000e-01 3.245919e-07 +182 3.100000e-01 4.169056e-07 +183 3.200000e-01 5.322484e-07 +184 3.300000e-01 6.754765e-07 +185 3.400000e-01 8.522962e-07 +186 3.500000e-01 1.069386e-06 +187 3.600000e-01 1.334520e-06 +188 3.700000e-01 1.656678e-06 +189 3.800000e-01 2.046121e-06 +190 3.900000e-01 2.514397e-06 +191 4.000000e-01 3.074263e-06 +192 4.100000e-01 3.739458e-06 +193 4.200000e-01 4.524337e-06 +194 4.300000e-01 5.443337e-06 +195 4.400000e-01 6.510303e-06 +196 4.500000e-01 7.737734e-06 +197 4.600000e-01 9.136030e-06 +198 4.700000e-01 1.071284e-05 +199 4.800000e-01 1.247258e-05 +200 4.900000e-01 1.441625e-05 +201 5.000000e-01 1.654142e-05 +202 5.100000e-01 1.884257e-05 +203 5.200000e-01 2.131151e-05 +204 5.300000e-01 2.393794e-05 +205 5.400000e-01 2.671009e-05 +206 5.500000e-01 2.961528e-05 +207 5.600000e-01 3.264041e-05 +208 5.700000e-01 3.577248e-05 +209 5.800000e-01 3.899883e-05 +210 5.900000e-01 4.226826e-05 +211 6.000000e-01 4.565345e-05 +212 6.100000e-01 4.909901e-05 +213 6.200000e-01 5.259558e-05 +214 6.300000e-01 5.613480e-05 +215 6.400000e-01 5.970922e-05 +216 6.500000e-01 6.331225e-05 +217 6.600000e-01 6.693812e-05 +218 6.700000e-01 7.058178e-05 +219 6.800000e-01 7.423883e-05 +220 6.900000e-01 7.790544e-05 +221 7.000000e-01 8.157831e-05 +222 7.100000e-01 8.525456e-05 +223 7.200000e-01 8.893171e-05 +224 7.300000e-01 9.260763e-05 +225 7.400000e-01 9.628046e-05 +226 7.500000e-01 9.994860e-05 +227 7.600000e-01 1.036107e-04 +228 7.700000e-01 1.072654e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +229 7.800000e-01 1.109119e-04 +230 7.900000e-01 1.145491e-04 +231 8.000000e-01 1.181763e-04 +232 8.100000e-01 1.217928e-04 +233 8.200000e-01 1.253980e-04 +234 8.300000e-01 1.289914e-04 +235 8.400000e-01 1.325725e-04 +236 8.500000e-01 1.361408e-04 +237 8.600000e-01 1.396961e-04 +238 8.700000e-01 1.432379e-04 +239 8.800000e-01 1.467661e-04 +240 8.900000e-01 1.502803e-04 +241 9.000000e-01 1.537804e-04 +242 9.100000e-01 1.572660e-04 +243 9.200000e-01 1.607371e-04 +244 9.300000e-01 1.641934e-04 +245 9.400000e-01 1.676348e-04 +246 9.500000e-01 1.710611e-04 +247 9.600000e-01 1.744723e-04 +248 9.700000e-01 1.778682e-04 +249 9.800000e-01 1.812486e-04 +250 9.900000e-01 1.846136e-04 +251 1.000000e+00 1.879629e-04 +252 1.010000e+00 1.912966e-04 +253 1.020000e+00 1.946145e-04 +254 1.030000e+00 1.979165e-04 +255 1.040000e+00 2.012027e-04 +256 1.050000e+00 2.044729e-04 +257 1.060000e+00 2.077271e-04 +258 1.070000e+00 2.109652e-04 +259 1.080000e+00 2.141871e-04 +260 1.090000e+00 2.173929e-04 +261 1.100000e+00 2.205825e-04 +262 1.110000e+00 2.237558e-04 +263 1.120000e+00 2.269129e-04 +264 1.130000e+00 2.300536e-04 +265 1.140000e+00 2.331780e-04 +266 1.150000e+00 2.362860e-04 +267 1.160000e+00 2.393776e-04 +268 1.170000e+00 2.424528e-04 +269 1.180000e+00 2.455116e-04 +270 1.190000e+00 2.485539e-04 +271 1.200000e+00 2.515798e-04 +272 1.210000e+00 2.545891e-04 +273 1.220000e+00 2.575820e-04 +274 1.230000e+00 2.605584e-04 +275 1.240000e+00 2.635183e-04 +276 1.250000e+00 2.664617e-04 +277 1.260000e+00 2.693886e-04 +278 1.270000e+00 2.722990e-04 +279 1.280000e+00 2.751928e-04 +280 1.290000e+00 2.780702e-04 +281 1.300000e+00 2.809311e-04 +282 1.310000e+00 2.837755e-04 +283 1.320000e+00 2.866034e-04 +284 1.330000e+00 2.894148e-04 +285 1.340000e+00 2.922098e-04 +286 1.350000e+00 2.949883e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +287 1.360000e+00 2.977504e-04 +288 1.370000e+00 3.004960e-04 +289 1.380000e+00 3.032253e-04 +290 1.390000e+00 3.059382e-04 +291 1.400000e+00 3.086347e-04 +292 1.410000e+00 3.113148e-04 +293 1.420000e+00 3.139787e-04 +294 1.430000e+00 3.166262e-04 +295 1.440000e+00 3.192574e-04 +296 1.450000e+00 3.218724e-04 +297 1.460000e+00 3.244712e-04 +298 1.470000e+00 3.270537e-04 +299 1.480000e+00 3.296201e-04 +300 1.490000e+00 3.321704e-04 +301 1.500000e+00 3.347045e-04 +302 0.000000e+00 1.721668e-11 +303 1.000000e-02 2.388772e-11 +304 2.000000e-02 3.312193e-11 +305 3.000000e-02 4.589976e-11 +306 4.000000e-02 6.357426e-11 +307 5.000000e-02 8.801134e-11 +308 6.000000e-02 1.217820e-10 +309 7.000000e-02 1.684254e-10 +310 8.000000e-02 2.328078e-10 +311 9.000000e-02 3.216122e-10 +312 1.000000e-01 4.440024e-10 +313 1.100000e-01 6.125230e-10 +314 1.200000e-01 8.443127e-10 +315 1.300000e-01 1.162735e-09 +316 1.400000e-01 1.599553e-09 +317 1.500000e-01 2.197827e-09 +318 1.600000e-01 3.015724e-09 +319 1.700000e-01 4.131521e-09 +320 1.800000e-01 5.650076e-09 +321 1.900000e-01 7.711158e-09 +322 2.000000e-01 1.050001e-08 +323 2.100000e-01 1.426057e-08 +324 2.200000e-01 1.931181e-08 +325 2.300000e-01 2.606762e-08 +326 2.400000e-01 3.506045e-08 +327 2.500000e-01 4.696916e-08 +328 2.600000e-01 6.265104e-08 +329 2.700000e-01 8.317815e-08 +330 2.800000e-01 1.098779e-07 +331 2.900000e-01 1.443779e-07 +332 3.000000e-01 1.886563e-07 +333 3.100000e-01 2.450966e-07 +334 3.200000e-01 3.165513e-07 +335 3.300000e-01 4.064134e-07 +336 3.400000e-01 5.187001e-07 +337 3.500000e-01 6.581490e-07 +338 3.600000e-01 8.303274e-07 +339 3.700000e-01 1.041750e-06 +340 3.800000e-01 1.300001e-06 +341 3.900000e-01 1.613841e-06 +342 4.000000e-01 1.993282e-06 +343 4.100000e-01 2.449604e-06 +344 4.200000e-01 2.995279e-06 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +345 4.300000e-01 3.643767e-06 +346 4.400000e-01 4.409168e-06 +347 4.500000e-01 5.305717e-06 +348 4.600000e-01 6.347133e-06 +349 4.700000e-01 7.545891e-06 +350 4.800000e-01 8.912481e-06 +351 4.900000e-01 1.045475e-05 +352 5.000000e-01 1.217743e-05 +353 5.100000e-01 1.408188e-05 +354 5.200000e-01 1.616612e-05 +355 5.300000e-01 1.842507e-05 +356 5.400000e-01 2.085096e-05 +357 5.500000e-01 2.343390e-05 +358 5.600000e-01 2.616247e-05 +359 5.700000e-01 2.902425e-05 +360 5.800000e-01 3.200641e-05 +361 5.900000e-01 3.509606e-05 +362 6.000000e-01 3.828069e-05 +363 6.100000e-01 4.150876e-05 +364 6.200000e-01 4.485374e-05 +365 6.300000e-01 4.825986e-05 +366 6.400000e-01 5.171774e-05 +367 6.500000e-01 5.521895e-05 +368 6.600000e-01 5.875598e-05 +369 6.700000e-01 6.232220e-05 +370 6.800000e-01 6.591175e-05 +371 6.900000e-01 6.951953e-05 +372 7.000000e-01 7.314107e-05 +373 7.100000e-01 7.677248e-05 +374 7.200000e-01 8.041041e-05 +375 7.300000e-01 8.405193e-05 +376 7.400000e-01 8.769452e-05 +377 7.500000e-01 9.133601e-05 +378 7.600000e-01 9.497450e-05 +379 7.700000e-01 9.860836e-05 +380 7.800000e-01 1.022362e-04 +381 7.900000e-01 1.058568e-04 +382 8.000000e-01 1.094690e-04 +383 8.100000e-01 1.130720e-04 +384 8.200000e-01 1.166650e-04 +385 8.300000e-01 1.202472e-04 +386 8.400000e-01 1.238181e-04 +387 8.500000e-01 1.273771e-04 +388 8.600000e-01 1.309237e-04 +389 8.700000e-01 1.344575e-04 +390 8.800000e-01 1.379783e-04 +391 8.900000e-01 1.414855e-04 +392 9.000000e-01 1.449790e-04 +393 9.100000e-01 1.484585e-04 +394 9.200000e-01 1.519237e-04 +395 9.300000e-01 1.553745e-04 +396 9.400000e-01 1.588107e-04 +397 9.500000e-01 1.622320e-04 +398 9.600000e-01 1.656384e-04 +399 9.700000e-01 1.690297e-04 +400 9.800000e-01 1.724057e-04 +401 9.900000e-01 1.757664e-04 +402 1.000000e+00 1.791117e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +403 1.010000e+00 1.824414e-04 +404 1.020000e+00 1.857555e-04 +405 1.030000e+00 1.890539e-04 +406 1.040000e+00 1.923365e-04 +407 1.050000e+00 1.956032e-04 +408 1.060000e+00 1.988540e-04 +409 1.070000e+00 2.020888e-04 +410 1.080000e+00 2.053076e-04 +411 1.090000e+00 2.085103e-04 +412 1.100000e+00 2.116969e-04 +413 1.110000e+00 2.148673e-04 +414 1.120000e+00 2.180215e-04 +415 1.130000e+00 2.211594e-04 +416 1.140000e+00 2.242811e-04 +417 1.150000e+00 2.273865e-04 +418 1.160000e+00 2.304755e-04 +419 1.170000e+00 2.335483e-04 +420 1.180000e+00 2.366046e-04 +421 1.190000e+00 2.396446e-04 +422 1.200000e+00 2.426681e-04 +423 1.210000e+00 2.456753e-04 +424 1.220000e+00 2.486660e-04 +425 1.230000e+00 2.516403e-04 +426 1.240000e+00 2.545982e-04 +427 1.250000e+00 2.575396e-04 +428 1.260000e+00 2.604646e-04 +429 1.270000e+00 2.633731e-04 +430 1.280000e+00 2.662652e-04 +431 1.290000e+00 2.691408e-04 +432 1.300000e+00 2.720000e-04 +433 1.310000e+00 2.748428e-04 +434 1.320000e+00 2.776692e-04 +435 1.330000e+00 2.804791e-04 +436 1.340000e+00 2.832727e-04 +437 1.350000e+00 2.860499e-04 +438 1.360000e+00 2.888106e-04 +439 1.370000e+00 2.915551e-04 +440 1.380000e+00 2.942832e-04 +441 1.390000e+00 2.969949e-04 +442 1.400000e+00 2.996904e-04 +443 1.410000e+00 3.023696e-04 +444 1.420000e+00 3.050325e-04 +445 1.430000e+00 3.076791e-04 +446 1.440000e+00 3.103096e-04 +447 1.450000e+00 3.129238e-04 +448 1.460000e+00 3.155219e-04 +449 1.470000e+00 3.181039e-04 +450 1.480000e+00 3.206697e-04 +451 1.490000e+00 3.232195e-04 +452 1.500000e+00 3.257532e-04 +453 0.000000e+00 1.394691e-11 +454 1.000000e-02 1.846015e-11 +455 2.000000e-02 2.662913e-11 +456 3.000000e-02 3.678196e-11 +457 4.000000e-02 5.079150e-11 +458 5.000000e-02 7.011527e-11 +459 6.000000e-02 9.675755e-11 +460 7.000000e-02 1.334720e-10 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +461 8.000000e-02 1.840385e-10 +462 9.000000e-02 2.536393e-10 +463 1.000000e-01 3.493704e-10 +464 1.100000e-01 4.809346e-10 +465 1.200000e-01 6.615750e-10 +466 1.300000e-01 9.093331e-10 +467 1.400000e-01 1.248731e-09 +468 1.500000e-01 1.713011e-09 +469 1.600000e-01 2.347109e-09 +470 1.700000e-01 3.211553e-09 +471 1.800000e-01 4.387562e-09 +472 1.900000e-01 5.983636e-09 +473 2.000000e-01 8.143998e-09 +474 2.100000e-01 1.105928e-08 +475 2.200000e-01 1.497988e-08 +476 2.300000e-01 2.023239e-08 +477 2.400000e-01 2.723958e-08 +478 2.500000e-01 3.654419e-08 +479 2.600000e-01 4.883680e-08 +480 2.700000e-01 6.498795e-08 +481 2.800000e-01 8.608465e-08 +482 2.900000e-01 1.134711e-07 +483 3.000000e-01 1.487940e-07 +484 3.100000e-01 1.940529e-07 +485 3.200000e-01 2.516566e-07 +486 3.300000e-01 3.244861e-07 +487 3.400000e-01 4.159679e-07 +488 3.500000e-01 5.301580e-07 +489 3.600000e-01 6.718379e-07 +490 3.700000e-01 8.466230e-07 +491 3.800000e-01 1.061080e-06 +492 3.900000e-01 1.322842e-06 +493 4.000000e-01 1.640714e-06 +494 4.100000e-01 2.024740e-06 +495 4.200000e-01 2.486206e-06 +496 4.300000e-01 3.037558e-06 +497 4.400000e-01 3.692188e-06 +498 4.500000e-01 4.464072e-06 +499 4.600000e-01 5.367267e-06 +500 4.700000e-01 6.415259e-06 +501 4.800000e-01 7.620246e-06 +502 4.900000e-01 8.992417e-06 +503 5.000000e-01 1.053931e-05 +504 5.100000e-01 1.226539e-05 +505 5.200000e-01 1.417177e-05 +506 5.300000e-01 1.625631e-05 +507 5.400000e-01 1.851382e-05 +508 5.500000e-01 2.093652e-05 +509 5.600000e-01 2.351455e-05 +510 5.700000e-01 2.623658e-05 +511 5.800000e-01 2.909032e-05 +512 5.900000e-01 3.206308e-05 +513 6.000000e-01 3.514216e-05 +514 6.100000e-01 3.831518e-05 +515 6.200000e-01 4.153118e-05 +516 6.300000e-01 4.486289e-05 +517 6.400000e-01 4.825513e-05 +518 6.500000e-01 5.169865e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +519 6.600000e-01 5.518510e-05 +520 6.700000e-01 5.870706e-05 +521 6.800000e-01 6.225794e-05 +522 6.900000e-01 6.583196e-05 +523 7.000000e-01 6.942404e-05 +524 7.100000e-01 7.302973e-05 +525 7.200000e-01 7.664519e-05 +526 7.300000e-01 8.026707e-05 +527 7.400000e-01 8.389246e-05 +528 7.500000e-01 8.751885e-05 +529 7.600000e-01 9.114407e-05 +530 7.700000e-01 9.476624e-05 +531 7.800000e-01 9.838372e-05 +532 7.900000e-01 1.019951e-04 +533 8.000000e-01 1.055992e-04 +534 8.100000e-01 1.091949e-04 +535 8.200000e-01 1.127813e-04 +536 8.300000e-01 1.163577e-04 +537 8.400000e-01 1.199233e-04 +538 8.500000e-01 1.234774e-04 +539 8.600000e-01 1.270196e-04 +540 8.700000e-01 1.305495e-04 +541 8.800000e-01 1.340665e-04 +542 8.900000e-01 1.375703e-04 +543 9.000000e-01 1.410607e-04 +544 9.100000e-01 1.445372e-04 +545 9.200000e-01 1.479997e-04 +546 9.300000e-01 1.514480e-04 +547 9.400000e-01 1.548817e-04 +548 9.500000e-01 1.583008e-04 +549 9.600000e-01 1.617050e-04 +550 9.700000e-01 1.650943e-04 +551 9.800000e-01 1.684684e-04 +552 9.900000e-01 1.718273e-04 +553 1.000000e+00 1.751708e-04 +554 1.010000e+00 1.784989e-04 +555 1.020000e+00 1.818114e-04 +556 1.030000e+00 1.851082e-04 +557 1.040000e+00 1.883893e-04 +558 1.050000e+00 1.916546e-04 +559 1.060000e+00 1.949041e-04 +560 1.070000e+00 1.981376e-04 +561 1.080000e+00 2.013552e-04 +562 1.090000e+00 2.045567e-04 +563 1.100000e+00 2.077421e-04 +564 1.110000e+00 2.109114e-04 +565 1.120000e+00 2.140645e-04 +566 1.130000e+00 2.172014e-04 +567 1.140000e+00 2.203221e-04 +568 1.150000e+00 2.234265e-04 +569 1.160000e+00 2.265147e-04 +570 1.170000e+00 2.295865e-04 +571 1.180000e+00 2.326420e-04 +572 1.190000e+00 2.356811e-04 +573 1.200000e+00 2.387039e-04 +574 1.210000e+00 2.417103e-04 +575 1.220000e+00 2.447003e-04 +576 1.230000e+00 2.476739e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +577 1.240000e+00 2.506311e-04 +578 1.250000e+00 2.535719e-04 +579 1.260000e+00 2.564963e-04 +580 1.270000e+00 2.594042e-04 +581 1.280000e+00 2.622958e-04 +582 1.290000e+00 2.651709e-04 +583 1.300000e+00 2.680296e-04 +584 1.310000e+00 2.708720e-04 +585 1.320000e+00 2.736979e-04 +586 1.330000e+00 2.765075e-04 +587 1.340000e+00 2.793006e-04 +588 1.350000e+00 2.820775e-04 +589 1.360000e+00 2.848379e-04 +590 1.370000e+00 2.875821e-04 +591 1.380000e+00 2.903099e-04 +592 1.390000e+00 2.930214e-04 +593 1.400000e+00 2.957167e-04 +594 1.410000e+00 2.983957e-04 +595 1.420000e+00 3.010585e-04 +596 1.430000e+00 3.037050e-04 +597 1.440000e+00 3.063354e-04 +598 1.450000e+00 3.089496e-04 +599 1.460000e+00 3.115476e-04 +600 1.470000e+00 3.141296e-04 +601 1.480000e+00 3.166954e-04 +602 1.490000e+00 3.192452e-04 +603 1.500000e+00 3.217790e-04 +604 0.000000e+00 1.754769e-11 +605 1.000000e-02 2.311481e-11 +606 2.000000e-02 3.313622e-11 +607 3.000000e-02 4.555909e-11 +608 4.000000e-02 6.264591e-11 +609 5.000000e-02 8.613817e-11 +610 6.000000e-02 1.184225e-10 +611 7.000000e-02 1.627667e-10 +612 8.000000e-02 2.236405e-10 +613 9.000000e-02 3.071507e-10 +614 1.000000e-01 4.216291e-10 +615 1.100000e-01 5.784260e-10 +616 1.200000e-01 7.929764e-10 +617 1.300000e-01 1.086227e-09 +618 1.400000e-01 1.486537e-09 +619 1.500000e-01 2.032200e-09 +620 1.600000e-01 2.774763e-09 +621 1.700000e-01 3.783370e-09 +622 1.800000e-01 5.150401e-09 +623 1.900000e-01 6.998722e-09 +624 2.000000e-01 9.490909e-09 +625 2.100000e-01 1.284086e-08 +626 2.200000e-01 1.732819e-08 +627 2.300000e-01 2.331591e-08 +628 2.400000e-01 3.127163e-08 +629 2.500000e-01 4.179280e-08 +630 2.600000e-01 5.563606e-08 +631 2.700000e-01 7.375095e-08 +632 2.800000e-01 9.731799e-08 +633 2.900000e-01 1.277913e-07 +634 3.000000e-01 1.669460e-07 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +635 3.100000e-01 2.169310e-07 +636 3.200000e-01 2.803284e-07 +637 3.300000e-01 3.602206e-07 +638 3.400000e-01 4.602673e-07 +639 3.500000e-01 5.847947e-07 +640 3.600000e-01 7.388948e-07 +641 3.700000e-01 9.285377e-07 +642 3.800000e-01 1.160686e-06 +643 3.900000e-01 1.443408e-06 +644 4.000000e-01 1.785962e-06 +645 4.100000e-01 2.198846e-06 +646 4.200000e-01 2.693765e-06 +647 4.300000e-01 3.283499e-06 +648 4.400000e-01 3.981636e-06 +649 4.500000e-01 4.802161e-06 +650 4.600000e-01 5.758892e-06 +651 4.700000e-01 6.864813e-06 +652 4.800000e-01 8.131351e-06 +653 4.900000e-01 9.567693e-06 +654 5.000000e-01 1.118022e-05 +655 5.100000e-01 1.297214e-05 +656 5.200000e-01 1.494337e-05 +657 5.300000e-01 1.709066e-05 +658 5.400000e-01 1.940791e-05 +659 5.500000e-01 2.188661e-05 +660 5.600000e-01 2.451644e-05 +661 5.700000e-01 2.728577e-05 +662 5.800000e-01 3.018226e-05 +663 5.900000e-01 3.319328e-05 +664 6.000000e-01 3.630632e-05 +665 6.100000e-01 3.950927e-05 +666 6.200000e-01 4.275330e-05 +667 6.300000e-01 4.610771e-05 +668 6.400000e-01 4.951966e-05 +669 6.500000e-01 5.298023e-05 +670 6.600000e-01 5.648142e-05 +671 6.700000e-01 6.001611e-05 +672 6.800000e-01 6.357799e-05 +673 6.900000e-01 6.716150e-05 +674 7.000000e-01 7.076179e-05 +675 7.100000e-01 7.437461e-05 +676 7.200000e-01 7.799627e-05 +677 7.300000e-01 8.162356e-05 +678 7.400000e-01 8.525368e-05 +679 7.500000e-01 8.888425e-05 +680 7.600000e-01 9.251315e-05 +681 7.700000e-01 9.613860e-05 +682 7.800000e-01 9.975902e-05 +683 7.900000e-01 1.033731e-04 +684 8.000000e-01 1.069795e-04 +685 8.100000e-01 1.105774e-04 +686 8.200000e-01 1.141659e-04 +687 8.300000e-01 1.177441e-04 +688 8.400000e-01 1.213113e-04 +689 8.500000e-01 1.248671e-04 +690 8.600000e-01 1.284109e-04 +691 8.700000e-01 1.319421e-04 +692 8.800000e-01 1.354605e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +693 8.900000e-01 1.389656e-04 +694 9.000000e-01 1.424572e-04 +695 9.100000e-01 1.459350e-04 +696 9.200000e-01 1.493987e-04 +697 9.300000e-01 1.528480e-04 +698 9.400000e-01 1.562829e-04 +699 9.500000e-01 1.597030e-04 +700 9.600000e-01 1.631083e-04 +701 9.700000e-01 1.664986e-04 +702 9.800000e-01 1.698737e-04 +703 9.900000e-01 1.732336e-04 +704 1.000000e+00 1.765781e-04 +705 1.010000e+00 1.799071e-04 +706 1.020000e+00 1.832205e-04 +707 1.030000e+00 1.865183e-04 +708 1.040000e+00 1.898004e-04 +709 1.050000e+00 1.930666e-04 +710 1.060000e+00 1.963169e-04 +711 1.070000e+00 1.995514e-04 +712 1.080000e+00 2.027698e-04 +713 1.090000e+00 2.059722e-04 +714 1.100000e+00 2.091585e-04 +715 1.110000e+00 2.123286e-04 +716 1.120000e+00 2.154826e-04 +717 1.130000e+00 2.186204e-04 +718 1.140000e+00 2.217419e-04 +719 1.150000e+00 2.248472e-04 +720 1.160000e+00 2.279362e-04 +721 1.170000e+00 2.310088e-04 +722 1.180000e+00 2.340651e-04 +723 1.190000e+00 2.371051e-04 +724 1.200000e+00 2.401287e-04 +725 1.210000e+00 2.431358e-04 +726 1.220000e+00 2.461266e-04 +727 1.230000e+00 2.491010e-04 +728 1.240000e+00 2.520590e-04 +729 1.250000e+00 2.550006e-04 +730 1.260000e+00 2.579257e-04 +731 1.270000e+00 2.608344e-04 +732 1.280000e+00 2.637267e-04 +733 1.290000e+00 2.666026e-04 +734 1.300000e+00 2.694620e-04 +735 1.310000e+00 2.723051e-04 +736 1.320000e+00 2.751317e-04 +737 1.330000e+00 2.779420e-04 +738 1.340000e+00 2.807359e-04 +739 1.350000e+00 2.835134e-04 +740 1.360000e+00 2.862745e-04 +741 1.370000e+00 2.890193e-04 +742 1.380000e+00 2.917478e-04 +743 1.390000e+00 2.944600e-04 +744 1.400000e+00 2.971559e-04 +745 1.410000e+00 2.998355e-04 +746 1.420000e+00 3.024989e-04 +747 1.430000e+00 3.051461e-04 +748 1.440000e+00 3.077771e-04 +749 1.450000e+00 3.103919e-04 +750 1.460000e+00 3.129905e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +751 1.470000e+00 3.155730e-04 +752 1.480000e+00 3.181395e-04 +753 1.490000e+00 3.206898e-04 +754 1.500000e+00 3.232242e-04 +755 0.000000e+00 3.463674e-11 +756 1.000000e-02 4.717950e-11 +757 2.000000e-02 6.437258e-11 +758 3.000000e-02 8.793096e-11 +759 4.000000e-02 1.201972e-10 +760 5.000000e-02 1.643681e-10 +761 6.000000e-02 2.248026e-10 +762 7.000000e-02 3.074369e-10 +763 8.000000e-02 4.203452e-10 +764 9.000000e-02 5.744935e-10 +765 1.000000e-01 7.847505e-10 +766 1.100000e-01 1.071237e-09 +767 1.200000e-01 1.461121e-09 +768 1.300000e-01 1.990993e-09 +769 1.400000e-01 2.709990e-09 +770 1.500000e-01 3.683879e-09 +771 1.600000e-01 5.000357e-09 +772 1.700000e-01 6.775862e-09 +773 1.800000e-01 9.164250e-09 +774 1.900000e-01 1.236773e-08 +775 2.000000e-01 1.665046e-08 +776 2.100000e-01 2.235526e-08 +777 2.200000e-01 2.992382e-08 +778 2.300000e-01 3.992077e-08 +779 2.400000e-01 5.306190e-08 +780 2.500000e-01 7.024675e-08 +781 2.600000e-01 9.259568e-08 +782 2.700000e-01 1.214916e-07 +783 2.800000e-01 1.586265e-07 +784 2.900000e-01 2.060534e-07 +785 3.000000e-01 2.662449e-07 +786 3.100000e-01 3.421587e-07 +787 3.200000e-01 4.373131e-07 +788 3.300000e-01 5.558728e-07 +789 3.400000e-01 7.027467e-07 +790 3.500000e-01 8.836952e-07 +791 3.600000e-01 1.105445e-06 +792 3.700000e-01 1.375800e-06 +793 3.800000e-01 1.703734e-06 +794 3.900000e-01 2.099446e-06 +795 4.000000e-01 2.574350e-06 +796 4.100000e-01 3.140969e-06 +797 4.200000e-01 3.812702e-06 +798 4.300000e-01 4.603452e-06 +799 4.400000e-01 5.527108e-06 +800 4.500000e-01 6.596900e-06 +801 4.600000e-01 7.824699e-06 +802 4.700000e-01 9.220318e-06 +803 4.800000e-01 1.079092e-05 +804 4.900000e-01 1.254061e-05 +805 5.000000e-01 1.447022e-05 +806 5.100000e-01 1.657740e-05 +807 5.200000e-01 1.885687e-05 +808 5.300000e-01 2.130084e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +809 5.400000e-01 2.389954e-05 +810 5.500000e-01 2.664175e-05 +811 5.600000e-01 2.951538e-05 +812 5.700000e-01 3.250792e-05 +813 5.800000e-01 3.560688e-05 +814 5.900000e-01 3.880005e-05 +815 6.000000e-01 4.203639e-05 +816 6.100000e-01 4.538918e-05 +817 6.200000e-01 4.880317e-05 +818 6.300000e-01 5.226918e-05 +819 6.400000e-01 5.577892e-05 +820 6.500000e-01 5.932496e-05 +821 6.600000e-01 6.290073e-05 +822 6.700000e-01 6.650043e-05 +823 6.800000e-01 7.011894e-05 +824 6.900000e-01 7.375180e-05 +825 7.000000e-01 7.739512e-05 +826 7.100000e-01 8.104551e-05 +827 7.200000e-01 8.470002e-05 +828 7.300000e-01 8.835609e-05 +829 7.400000e-01 9.201152e-05 +830 7.500000e-01 9.566437e-05 +831 7.600000e-01 9.931300e-05 +832 7.700000e-01 1.029559e-04 +833 7.800000e-01 1.065920e-04 +834 7.900000e-01 1.102200e-04 +835 8.000000e-01 1.138390e-04 +836 8.100000e-01 1.174483e-04 +837 8.200000e-01 1.210470e-04 +838 8.300000e-01 1.246346e-04 +839 8.400000e-01 1.282105e-04 +840 8.500000e-01 1.317743e-04 +841 8.600000e-01 1.353254e-04 +842 8.700000e-01 1.388635e-04 +843 8.800000e-01 1.423883e-04 +844 8.900000e-01 1.458995e-04 +845 9.000000e-01 1.493968e-04 +846 9.100000e-01 1.528800e-04 +847 9.200000e-01 1.563488e-04 +848 9.300000e-01 1.598030e-04 +849 9.400000e-01 1.632426e-04 +850 9.500000e-01 1.666672e-04 +851 9.600000e-01 1.700769e-04 +852 9.700000e-01 1.734713e-04 +853 9.800000e-01 1.768505e-04 +854 9.900000e-01 1.802143e-04 +855 1.000000e+00 1.835626e-04 +856 1.010000e+00 1.868954e-04 +857 1.020000e+00 1.902124e-04 +858 1.030000e+00 1.935137e-04 +859 1.040000e+00 1.967992e-04 +860 1.050000e+00 2.000688e-04 +861 1.060000e+00 2.033225e-04 +862 1.070000e+00 2.065601e-04 +863 1.080000e+00 2.097817e-04 +864 1.090000e+00 2.129872e-04 +865 1.100000e+00 2.161765e-04 +866 1.110000e+00 2.193496e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +867 1.120000e+00 2.225066e-04 +868 1.130000e+00 2.256472e-04 +869 1.140000e+00 2.287716e-04 +870 1.150000e+00 2.318796e-04 +871 1.160000e+00 2.349713e-04 +872 1.170000e+00 2.380466e-04 +873 1.180000e+00 2.411055e-04 +874 1.190000e+00 2.441480e-04 +875 1.200000e+00 2.471741e-04 +876 1.210000e+00 2.501838e-04 +877 1.220000e+00 2.531770e-04 +878 1.230000e+00 2.561538e-04 +879 1.240000e+00 2.591141e-04 +880 1.250000e+00 2.620579e-04 +881 1.260000e+00 2.649853e-04 +882 1.270000e+00 2.678962e-04 +883 1.280000e+00 2.707906e-04 +884 1.290000e+00 2.736686e-04 +885 1.300000e+00 2.765301e-04 +886 1.310000e+00 2.793752e-04 +887 1.320000e+00 2.822038e-04 +888 1.330000e+00 2.850160e-04 +889 1.340000e+00 2.878117e-04 +890 1.350000e+00 2.905910e-04 +891 1.360000e+00 2.933540e-04 +892 1.370000e+00 2.961005e-04 +893 1.380000e+00 2.988307e-04 +894 1.390000e+00 3.015445e-04 +895 1.400000e+00 3.042420e-04 +896 1.410000e+00 3.069232e-04 +897 1.420000e+00 3.095880e-04 +898 1.430000e+00 3.122366e-04 +899 1.440000e+00 3.148690e-04 +900 1.450000e+00 3.174851e-04 +901 1.460000e+00 3.200851e-04 +902 1.470000e+00 3.226688e-04 +903 1.480000e+00 3.252365e-04 +904 1.490000e+00 3.277880e-04 +905 1.500000e+00 3.303234e-04 +906 0.000000e+00 1.045384e-10 +907 1.000000e-02 1.404399e-10 +908 2.000000e-02 1.893844e-10 +909 3.000000e-02 2.560736e-10 +910 4.000000e-02 3.468845e-10 +911 5.000000e-02 4.704551e-10 +912 6.000000e-02 6.384687e-10 +913 7.000000e-02 8.667021e-10 +914 8.000000e-02 1.176419e-09 +915 9.000000e-02 1.596215e-09 +916 1.000000e-01 2.164452e-09 +917 1.100000e-01 2.932448e-09 +918 1.200000e-01 3.968627e-09 +919 1.300000e-01 5.363896e-09 +920 1.400000e-01 7.238524e-09 +921 1.500000e-01 9.750897e-09 +922 1.600000e-01 1.310851e-08 +923 1.700000e-01 1.758161e-08 +924 1.800000e-01 2.352000e-08 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +925 1.900000e-01 3.137322e-08 +926 2.000000e-01 4.171477e-08 +927 2.100000e-01 5.527041e-08 +928 2.200000e-01 7.295098e-08 +929 2.300000e-01 9.588982e-08 +930 2.400000e-01 1.254851e-07 +931 2.500000e-01 1.634470e-07 +932 2.600000e-01 2.118512e-07 +933 2.700000e-01 2.731982e-07 +934 2.800000e-01 3.504810e-07 +935 2.900000e-01 4.472614e-07 +936 3.000000e-01 5.677581e-07 +937 3.100000e-01 7.169442e-07 +938 3.200000e-01 9.006563e-07 +939 3.300000e-01 1.125706e-06 +940 3.400000e-01 1.399992e-06 +941 3.500000e-01 1.732584e-06 +942 3.600000e-01 2.133780e-06 +943 3.700000e-01 2.615081e-06 +944 3.800000e-01 3.189086e-06 +945 3.900000e-01 3.869251e-06 +946 4.000000e-01 4.669510e-06 +947 4.100000e-01 5.603758e-06 +948 4.200000e-01 6.685210e-06 +949 4.300000e-01 7.925707e-06 +950 4.400000e-01 9.335025e-06 +951 4.500000e-01 1.092030e-05 +952 4.600000e-01 1.268561e-05 +953 4.700000e-01 1.463182e-05 +954 4.800000e-01 1.675661e-05 +955 4.900000e-01 1.905474e-05 +956 5.000000e-01 2.151851e-05 +957 5.100000e-01 2.413824e-05 +958 5.200000e-01 2.690280e-05 +959 5.300000e-01 2.980018e-05 +960 5.400000e-01 3.281794e-05 +961 5.500000e-01 3.594363e-05 +962 5.600000e-01 3.916507e-05 +963 5.700000e-01 4.243047e-05 +964 5.800000e-01 4.581462e-05 +965 5.900000e-01 4.926149e-05 +966 6.000000e-01 5.276183e-05 +967 6.100000e-01 5.630729e-05 +968 6.200000e-01 5.989037e-05 +969 6.300000e-01 6.350442e-05 +970 6.400000e-01 6.714356e-05 +971 6.500000e-01 7.080260e-05 +972 6.600000e-01 7.447701e-05 +973 6.700000e-01 7.816280e-05 +974 6.800000e-01 8.185652e-05 +975 6.900000e-01 8.555515e-05 +976 7.000000e-01 8.925609e-05 +977 7.100000e-01 9.295705e-05 +978 7.200000e-01 9.665607e-05 +979 7.300000e-01 1.003514e-04 +980 7.400000e-01 1.040417e-04 +981 7.500000e-01 1.077254e-04 +982 7.600000e-01 1.114017e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +983 7.700000e-01 1.150694e-04 +984 7.800000e-01 1.187276e-04 +985 7.900000e-01 1.223758e-04 +986 8.000000e-01 1.260132e-04 +987 8.100000e-01 1.296391e-04 +988 8.200000e-01 1.332532e-04 +989 8.300000e-01 1.368550e-04 +990 8.400000e-01 1.404441e-04 +991 8.500000e-01 1.440201e-04 +992 8.600000e-01 1.475826e-04 +993 8.700000e-01 1.511315e-04 +994 8.800000e-01 1.546665e-04 +995 8.900000e-01 1.581873e-04 +996 9.000000e-01 1.616938e-04 +997 9.100000e-01 1.651857e-04 +998 9.200000e-01 1.686629e-04 +999 9.300000e-01 1.721252e-04 +1000 9.400000e-01 1.755724e-04 +1001 9.500000e-01 1.790046e-04 +1002 9.600000e-01 1.824214e-04 +1003 9.700000e-01 1.858229e-04 +1004 9.800000e-01 1.892089e-04 +1005 9.900000e-01 1.925794e-04 +1006 1.000000e+00 1.959341e-04 +1007 1.010000e+00 1.992732e-04 +1008 1.020000e+00 2.025964e-04 +1009 1.030000e+00 2.059037e-04 +1010 1.040000e+00 2.091951e-04 +1011 1.050000e+00 2.124704e-04 +1012 1.060000e+00 2.157297e-04 +1013 1.070000e+00 2.189729e-04 +1014 1.080000e+00 2.221999e-04 +1015 1.090000e+00 2.254107e-04 +1016 1.100000e+00 2.286053e-04 +1017 1.110000e+00 2.317836e-04 +1018 1.120000e+00 2.349455e-04 +1019 1.130000e+00 2.380911e-04 +1020 1.140000e+00 2.412203e-04 +1021 1.150000e+00 2.443331e-04 +1022 1.160000e+00 2.474295e-04 +1023 1.170000e+00 2.505094e-04 +1024 1.180000e+00 2.535728e-04 +1025 1.190000e+00 2.566198e-04 +1026 1.200000e+00 2.596502e-04 +1027 1.210000e+00 2.626642e-04 +1028 1.220000e+00 2.656616e-04 +1029 1.230000e+00 2.686425e-04 +1030 1.240000e+00 2.716068e-04 +1031 1.250000e+00 2.745546e-04 +1032 1.260000e+00 2.774858e-04 +1033 1.270000e+00 2.804005e-04 +1034 1.280000e+00 2.832987e-04 +1035 1.290000e+00 2.861803e-04 +1036 1.300000e+00 2.890453e-04 +1037 1.310000e+00 2.918938e-04 +1038 1.320000e+00 2.947258e-04 +1039 1.330000e+00 2.975413e-04 +1040 1.340000e+00 3.003403e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1041 1.350000e+00 3.031228e-04 +1042 1.360000e+00 3.058887e-04 +1043 1.370000e+00 3.086382e-04 +1044 1.380000e+00 3.113713e-04 +1045 1.390000e+00 3.140879e-04 +1046 1.400000e+00 3.167881e-04 +1047 1.410000e+00 3.194719e-04 +1048 1.420000e+00 3.221393e-04 +1049 1.430000e+00 3.247904e-04 +1050 1.440000e+00 3.274251e-04 +1051 1.450000e+00 3.300435e-04 +1052 1.460000e+00 3.326456e-04 +1053 1.470000e+00 3.352315e-04 +1054 1.480000e+00 3.378011e-04 +1055 1.490000e+00 3.403546e-04 +1056 1.500000e+00 3.428918e-04 +1057 0.000000e+00 4.795506e-10 +1058 1.000000e-02 6.196464e-10 +1059 2.000000e-02 8.091557e-10 +1060 3.000000e-02 1.065278e-09 +1061 4.000000e-02 1.411076e-09 +1062 5.000000e-02 1.877411e-09 +1063 6.000000e-02 2.505474e-09 +1064 7.000000e-02 3.350099e-09 +1065 8.000000e-02 4.484049e-09 +1066 9.000000e-02 6.003532e-09 +1067 1.000000e-01 8.035260e-09 +1068 1.100000e-01 1.074536e-08 +1069 1.200000e-01 1.435056e-08 +1070 1.300000e-01 1.913204e-08 +1071 1.400000e-01 2.545238e-08 +1072 1.500000e-01 3.377604e-08 +1073 1.600000e-01 4.469378e-08 +1074 1.700000e-01 5.895133e-08 +1075 1.800000e-01 7.748264e-08 +1076 1.900000e-01 1.014480e-07 +1077 2.000000e-01 1.322771e-07 +1078 2.100000e-01 1.717180e-07 +1079 2.200000e-01 2.218914e-07 +1080 2.300000e-01 2.853528e-07 +1081 2.400000e-01 3.651618e-07 +1082 2.500000e-01 4.649620e-07 +1083 2.600000e-01 5.890700e-07 +1084 2.700000e-01 7.425761e-07 +1085 2.800000e-01 9.314530e-07 +1086 2.900000e-01 1.162668e-06 +1087 3.000000e-01 1.444289e-06 +1088 3.100000e-01 1.785569e-06 +1089 3.200000e-01 2.196987e-06 +1090 3.300000e-01 2.690219e-06 +1091 3.400000e-01 3.278015e-06 +1092 3.500000e-01 3.973945e-06 +1093 3.600000e-01 4.792012e-06 +1094 3.700000e-01 5.746120e-06 +1095 3.800000e-01 6.849443e-06 +1096 3.900000e-01 8.113722e-06 +1097 4.000000e-01 9.548603e-06 +1098 4.100000e-01 1.116107e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1099 4.200000e-01 1.295505e-05 +1100 4.300000e-01 1.493128e-05 +1101 4.400000e-01 1.708735e-05 +1102 4.500000e-01 1.941797e-05 +1103 4.600000e-01 2.191543e-05 +1104 4.700000e-01 2.457007e-05 +1105 4.800000e-01 2.737081e-05 +1106 4.900000e-01 3.030571e-05 +1107 5.000000e-01 3.336239e-05 +1108 5.100000e-01 3.652846e-05 +1109 5.200000e-01 3.979178e-05 +1110 5.300000e-01 4.309982e-05 +1111 5.400000e-01 4.652892e-05 +1112 5.500000e-01 5.002227e-05 +1113 5.600000e-01 5.357061e-05 +1114 5.700000e-01 5.716553e-05 +1115 5.800000e-01 6.079949e-05 +1116 5.900000e-01 6.446578e-05 +1117 6.000000e-01 6.815845e-05 +1118 6.100000e-01 7.187223e-05 +1119 6.200000e-01 7.560252e-05 +1120 6.300000e-01 7.934528e-05 +1121 6.400000e-01 8.309697e-05 +1122 6.500000e-01 8.685452e-05 +1123 6.600000e-01 9.061525e-05 +1124 6.700000e-01 9.437683e-05 +1125 6.800000e-01 9.813724e-05 +1126 6.900000e-01 1.018947e-04 +1127 7.000000e-01 1.056477e-04 +1128 7.100000e-01 1.093949e-04 +1129 7.200000e-01 1.131351e-04 +1130 7.300000e-01 1.168674e-04 +1131 7.400000e-01 1.205908e-04 +1132 7.500000e-01 1.243045e-04 +1133 7.600000e-01 1.280079e-04 +1134 7.700000e-01 1.317004e-04 +1135 7.800000e-01 1.353814e-04 +1136 7.900000e-01 1.390505e-04 +1137 8.000000e-01 1.427072e-04 +1138 8.100000e-01 1.463512e-04 +1139 8.200000e-01 1.499821e-04 +1140 8.300000e-01 1.535997e-04 +1141 8.400000e-01 1.572037e-04 +1142 8.500000e-01 1.607938e-04 +1143 8.600000e-01 1.643698e-04 +1144 8.700000e-01 1.679315e-04 +1145 8.800000e-01 1.714788e-04 +1146 8.900000e-01 1.750114e-04 +1147 9.000000e-01 1.785292e-04 +1148 9.100000e-01 1.820321e-04 +1149 9.200000e-01 1.855199e-04 +1150 9.300000e-01 1.889925e-04 +1151 9.400000e-01 1.924498e-04 +1152 9.500000e-01 1.958917e-04 +1153 9.600000e-01 1.993181e-04 +1154 9.700000e-01 2.027288e-04 +1155 9.800000e-01 2.061239e-04 +1156 9.900000e-01 2.095033e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1157 1.000000e+00 2.128667e-04 +1158 1.010000e+00 2.162143e-04 +1159 1.020000e+00 2.195459e-04 +1160 1.030000e+00 2.228615e-04 +1161 1.040000e+00 2.261610e-04 +1162 1.050000e+00 2.294443e-04 +1163 1.060000e+00 2.327114e-04 +1164 1.070000e+00 2.359623e-04 +1165 1.080000e+00 2.391969e-04 +1166 1.090000e+00 2.424151e-04 +1167 1.100000e+00 2.456170e-04 +1168 1.110000e+00 2.488025e-04 +1169 1.120000e+00 2.519716e-04 +1170 1.130000e+00 2.551242e-04 +1171 1.140000e+00 2.582603e-04 +1172 1.150000e+00 2.613798e-04 +1173 1.160000e+00 2.644829e-04 +1174 1.170000e+00 2.675694e-04 +1175 1.180000e+00 2.706393e-04 +1176 1.190000e+00 2.736926e-04 +1177 1.200000e+00 2.767293e-04 +1178 1.210000e+00 2.797494e-04 +1179 1.220000e+00 2.827528e-04 +1180 1.230000e+00 2.857397e-04 +1181 1.240000e+00 2.887098e-04 +1182 1.250000e+00 2.916633e-04 +1183 1.260000e+00 2.946002e-04 +1184 1.270000e+00 2.975204e-04 +1185 1.280000e+00 3.004240e-04 +1186 1.290000e+00 3.033109e-04 +1187 1.300000e+00 3.061811e-04 +1188 1.310000e+00 3.090347e-04 +1189 1.320000e+00 3.118717e-04 +1190 1.330000e+00 3.146920e-04 +1191 1.340000e+00 3.174957e-04 +1192 1.350000e+00 3.202828e-04 +1193 1.360000e+00 3.230534e-04 +1194 1.370000e+00 3.258073e-04 +1195 1.380000e+00 3.285446e-04 +1196 1.390000e+00 3.312654e-04 +1197 1.400000e+00 3.339697e-04 +1198 1.410000e+00 3.366574e-04 +1199 1.420000e+00 3.393287e-04 +1200 1.430000e+00 3.419834e-04 +1201 1.440000e+00 3.446217e-04 +1202 1.450000e+00 3.472436e-04 +1203 1.460000e+00 3.498491e-04 +1204 1.470000e+00 3.524382e-04 +1205 1.480000e+00 3.550109e-04 +1206 1.490000e+00 3.575673e-04 +1207 1.500000e+00 3.601074e-04 +1208 0.000000e+00 3.964428e-09 +1209 1.000000e-02 4.609593e-09 +1210 2.000000e-02 5.472023e-09 +1211 3.000000e-02 6.623095e-09 +1212 4.000000e-02 8.156726e-09 +1213 5.000000e-02 1.019603e-08 +1214 6.000000e-02 1.290176e-08 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1215 7.000000e-02 1.648280e-08 +1216 8.000000e-02 2.120931e-08 +1217 9.000000e-02 2.742865e-08 +1218 1.000000e-01 3.558485e-08 +1219 1.100000e-01 4.624181e-08 +1220 1.200000e-01 6.011071e-08 +1221 1.300000e-01 7.808208e-08 +1222 1.400000e-01 1.012627e-07 +1223 1.500000e-01 1.310179e-07 +1224 1.600000e-01 1.690196e-07 +1225 1.700000e-01 2.173002e-07 +1226 1.800000e-01 2.783144e-07 +1227 1.900000e-01 3.550087e-07 +1228 2.000000e-01 4.508997e-07 +1229 2.100000e-01 5.701636e-07 +1230 2.200000e-01 7.177351e-07 +1231 2.300000e-01 8.994153e-07 +1232 2.400000e-01 1.121983e-06 +1233 2.500000e-01 1.393303e-06 +1234 2.600000e-01 1.722410e-06 +1235 2.700000e-01 2.119565e-06 +1236 2.800000e-01 2.596235e-06 +1237 2.900000e-01 3.164994e-06 +1238 3.000000e-01 3.839298e-06 +1239 3.100000e-01 4.633133e-06 +1240 3.200000e-01 5.560519e-06 +1241 3.300000e-01 6.634904e-06 +1242 3.400000e-01 7.868491e-06 +1243 3.500000e-01 9.271556e-06 +1244 3.600000e-01 1.085187e-05 +1245 3.700000e-01 1.261427e-05 +1246 3.800000e-01 1.456043e-05 +1247 3.900000e-01 1.668888e-05 +1248 4.000000e-01 1.899525e-05 +1249 4.100000e-01 2.147258e-05 +1250 4.200000e-01 2.411187e-05 +1251 4.300000e-01 2.690254e-05 +1252 4.400000e-01 2.983300e-05 +1253 4.500000e-01 3.289107e-05 +1254 4.600000e-01 3.606442e-05 +1255 4.700000e-01 3.934088e-05 +1256 4.800000e-01 4.270873e-05 +1257 4.900000e-01 4.611851e-05 +1258 5.000000e-01 4.964158e-05 +1259 5.100000e-01 5.322456e-05 +1260 5.200000e-01 5.685873e-05 +1261 5.300000e-01 6.053620e-05 +1262 5.400000e-01 6.424992e-05 +1263 5.500000e-01 6.799359e-05 +1264 5.600000e-01 7.176165e-05 +1265 5.700000e-01 7.554919e-05 +1266 5.800000e-01 7.935191e-05 +1267 5.900000e-01 8.316601e-05 +1268 6.000000e-01 8.698819e-05 +1269 6.100000e-01 9.081557e-05 +1270 6.200000e-01 9.464562e-05 +1271 6.300000e-01 9.847617e-05 +1272 6.400000e-01 1.023053e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1273 6.500000e-01 1.061313e-04 +1274 6.600000e-01 1.099528e-04 +1275 6.700000e-01 1.137685e-04 +1276 6.800000e-01 1.175773e-04 +1277 6.900000e-01 1.213782e-04 +1278 7.000000e-01 1.251703e-04 +1279 7.100000e-01 1.289530e-04 +1280 7.200000e-01 1.327255e-04 +1281 7.300000e-01 1.364873e-04 +1282 7.400000e-01 1.402379e-04 +1283 7.500000e-01 1.439767e-04 +1284 7.600000e-01 1.477035e-04 +1285 7.700000e-01 1.514177e-04 +1286 7.800000e-01 1.551192e-04 +1287 7.900000e-01 1.588075e-04 +1288 8.000000e-01 1.624825e-04 +1289 8.100000e-01 1.661438e-04 +1290 8.200000e-01 1.697913e-04 +1291 8.300000e-01 1.734248e-04 +1292 8.400000e-01 1.770440e-04 +1293 8.500000e-01 1.806488e-04 +1294 8.600000e-01 1.842390e-04 +1295 8.700000e-01 1.878144e-04 +1296 8.800000e-01 1.913750e-04 +1297 8.900000e-01 1.949206e-04 +1298 9.000000e-01 1.984511e-04 +1299 9.100000e-01 2.019664e-04 +1300 9.200000e-01 2.054663e-04 +1301 9.300000e-01 2.089508e-04 +1302 9.400000e-01 2.124197e-04 +1303 9.500000e-01 2.158731e-04 +1304 9.600000e-01 2.193107e-04 +1305 9.700000e-01 2.227325e-04 +1306 9.800000e-01 2.261385e-04 +1307 9.900000e-01 2.295286e-04 +1308 1.000000e+00 2.329026e-04 +1309 1.010000e+00 2.362606e-04 +1310 1.020000e+00 2.396025e-04 +1311 1.030000e+00 2.429282e-04 +1312 1.040000e+00 2.462377e-04 +1313 1.050000e+00 2.495309e-04 +1314 1.060000e+00 2.528077e-04 +1315 1.070000e+00 2.560683e-04 +1316 1.080000e+00 2.593123e-04 +1317 1.090000e+00 2.625400e-04 +1318 1.100000e+00 2.657512e-04 +1319 1.110000e+00 2.689458e-04 +1320 1.120000e+00 2.721239e-04 +1321 1.130000e+00 2.752854e-04 +1322 1.140000e+00 2.784303e-04 +1323 1.150000e+00 2.815586e-04 +1324 1.160000e+00 2.846702e-04 +1325 1.170000e+00 2.877652e-04 +1326 1.180000e+00 2.908434e-04 +1327 1.190000e+00 2.939050e-04 +1328 1.200000e+00 2.969498e-04 +1329 1.210000e+00 2.999779e-04 +1330 1.220000e+00 3.029892e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1331 1.230000e+00 3.059838e-04 +1332 1.240000e+00 3.089616e-04 +1333 1.250000e+00 3.119226e-04 +1334 1.260000e+00 3.148669e-04 +1335 1.270000e+00 3.177944e-04 +1336 1.280000e+00 3.207051e-04 +1337 1.290000e+00 3.235990e-04 +1338 1.300000e+00 3.264762e-04 +1339 1.310000e+00 3.293365e-04 +1340 1.320000e+00 3.321802e-04 +1341 1.330000e+00 3.350070e-04 +1342 1.340000e+00 3.378171e-04 +1343 1.350000e+00 3.406105e-04 +1344 1.360000e+00 3.433871e-04 +1345 1.370000e+00 3.461470e-04 +1346 1.380000e+00 3.488902e-04 +1347 1.390000e+00 3.516167e-04 +1348 1.400000e+00 3.543266e-04 +1349 1.410000e+00 3.570198e-04 +1350 1.420000e+00 3.596963e-04 +1351 1.430000e+00 3.623562e-04 +1352 1.440000e+00 3.649995e-04 +1353 1.450000e+00 3.676263e-04 +1354 1.460000e+00 3.702365e-04 +1355 1.470000e+00 3.728301e-04 +1356 1.480000e+00 3.754073e-04 +1357 1.490000e+00 3.779680e-04 +1358 1.500000e+00 3.805122e-04 + + + + diff --git a/tests/bsim3soipd/t5.cir b/tests/bsim3soipd/t5.cir new file mode 100644 index 000000000..ead629c77 --- /dev/null +++ b/tests/bsim3soipd/t5.cir @@ -0,0 +1,16 @@ +*model = BSIMSOI (PD) +*Berkeley Spice Compatibility +* +* SOI NMOSFET, floating body simulation + +vd d 0 dc 0.05 +vs s 0 dc 0 +ve e 0 dc 0 +vg g 0 dc 3 + +m1 d g s e n1 w=10u l=0.25u + +.option gmin=1e-25 itl1=500 +.dc vg 0 1.5 0.01 ve -4 4 1 +.print dc i(vs) +.include nmospd.mod diff --git a/tests/bsim3soipd/t5.out b/tests/bsim3soipd/t5.out new file mode 100644 index 000000000..fe28bddff --- /dev/null +++ b/tests/bsim3soipd/t5.out @@ -0,0 +1,1444 @@ + Reference value : 6.00000e-01 +No. of Data Rows : 1359 + +Circuit: *model = BSIMSOI (PD) + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: Pd = 0 is less than W. +Warning: Ps = 0 is less than W. + *model = BSIMSOI (PD) +-------------------------------------------------------------------------------- +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 1.412965e-11 +1 1.000000e-02 1.868439e-11 +2 2.000000e-02 2.691900e-11 +3 3.000000e-02 3.714787e-11 +4 4.000000e-02 5.125290e-11 +5 5.000000e-02 7.069545e-11 +6 6.000000e-02 9.748369e-11 +7 7.000000e-02 1.343749e-10 +8 8.000000e-02 1.851513e-10 +9 9.000000e-02 2.549952e-10 +10 1.000000e-01 3.509984e-10 +11 1.100000e-01 4.828510e-10 +12 1.200000e-01 6.637719e-10 +13 1.300000e-01 9.117578e-10 +14 1.400000e-01 1.251256e-09 +15 1.500000e-01 1.715390e-09 +16 1.600000e-01 2.348907e-09 +17 1.700000e-01 3.212054e-09 +18 1.800000e-01 4.385633e-09 +19 1.900000e-01 5.977539e-09 +20 2.000000e-01 8.131134e-09 +21 2.100000e-01 1.103584e-08 +22 2.200000e-01 1.494041e-08 +23 2.300000e-01 2.016920e-08 +24 2.400000e-01 2.714203e-08 +25 2.500000e-01 3.639779e-08 +26 2.600000e-01 4.862215e-08 +27 2.700000e-01 6.467955e-08 +28 2.800000e-01 8.564949e-08 +29 2.900000e-01 1.128671e-07 +30 3.000000e-01 1.479685e-07 +31 3.100000e-01 1.929409e-07 +32 3.200000e-01 2.501785e-07 +33 3.300000e-01 3.225462e-07 +34 3.400000e-01 4.134518e-07 +35 3.500000e-01 5.269298e-07 +36 3.600000e-01 6.677368e-07 +37 3.700000e-01 8.414599e-07 +38 3.800000e-01 1.054632e-06 +39 3.900000e-01 1.314850e-06 +40 4.000000e-01 1.630874e-06 +41 4.100000e-01 2.012700e-06 +42 4.200000e-01 2.471565e-06 +43 4.300000e-01 3.019864e-06 +44 4.400000e-01 3.670941e-06 +45 4.500000e-01 4.438738e-06 +46 4.600000e-01 5.337287e-06 +47 4.700000e-01 6.380076e-06 +48 4.800000e-01 7.579326e-06 +49 4.900000e-01 8.945277e-06 +50 5.000000e-01 1.048555e-05 +51 5.100000e-01 1.220469e-05 +52 5.200000e-01 1.410395e-05 +53 5.300000e-01 1.618128e-05 +54 5.400000e-01 1.843163e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +55 5.500000e-01 2.084730e-05 +56 5.600000e-01 2.341855e-05 +57 5.700000e-01 2.613410e-05 +58 5.800000e-01 2.898174e-05 +59 5.900000e-01 3.194880e-05 +60 6.000000e-01 3.502262e-05 +61 6.100000e-01 3.819081e-05 +62 6.200000e-01 4.140222e-05 +63 6.300000e-01 4.472996e-05 +64 6.400000e-01 4.811866e-05 +65 6.500000e-01 5.155900e-05 +66 6.600000e-01 5.504264e-05 +67 6.700000e-01 5.856210e-05 +68 6.800000e-01 6.211079e-05 +69 6.900000e-01 6.568286e-05 +70 7.000000e-01 6.927323e-05 +71 7.100000e-01 7.287743e-05 +72 7.200000e-01 7.649158e-05 +73 7.300000e-01 8.011231e-05 +74 7.400000e-01 8.373669e-05 +75 7.500000e-01 8.736220e-05 +76 7.600000e-01 9.098665e-05 +77 7.700000e-01 9.460814e-05 +78 7.800000e-01 9.822504e-05 +79 7.900000e-01 1.018359e-04 +80 8.000000e-01 1.054396e-04 +81 8.100000e-01 1.090349e-04 +82 8.200000e-01 1.126210e-04 +83 8.300000e-01 1.161970e-04 +84 8.400000e-01 1.197623e-04 +85 8.500000e-01 1.233162e-04 +86 8.600000e-01 1.268582e-04 +87 8.700000e-01 1.303879e-04 +88 8.800000e-01 1.339047e-04 +89 8.900000e-01 1.374084e-04 +90 9.000000e-01 1.408987e-04 +91 9.100000e-01 1.443751e-04 +92 9.200000e-01 1.478375e-04 +93 9.300000e-01 1.512857e-04 +94 9.400000e-01 1.547193e-04 +95 9.500000e-01 1.581383e-04 +96 9.600000e-01 1.615425e-04 +97 9.700000e-01 1.649317e-04 +98 9.800000e-01 1.683058e-04 +99 9.900000e-01 1.716647e-04 +100 1.000000e+00 1.750082e-04 +101 1.010000e+00 1.783362e-04 +102 1.020000e+00 1.816487e-04 +103 1.030000e+00 1.849455e-04 +104 1.040000e+00 1.882266e-04 +105 1.050000e+00 1.914919e-04 +106 1.060000e+00 1.947414e-04 +107 1.070000e+00 1.979749e-04 +108 1.080000e+00 2.011925e-04 +109 1.090000e+00 2.043940e-04 +110 1.100000e+00 2.075794e-04 +111 1.110000e+00 2.107487e-04 +112 1.120000e+00 2.139019e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +113 1.130000e+00 2.170388e-04 +114 1.140000e+00 2.201595e-04 +115 1.150000e+00 2.232640e-04 +116 1.160000e+00 2.263522e-04 +117 1.170000e+00 2.294240e-04 +118 1.180000e+00 2.324796e-04 +119 1.190000e+00 2.355187e-04 +120 1.200000e+00 2.385416e-04 +121 1.210000e+00 2.415480e-04 +122 1.220000e+00 2.445380e-04 +123 1.230000e+00 2.475117e-04 +124 1.240000e+00 2.504689e-04 +125 1.250000e+00 2.534098e-04 +126 1.260000e+00 2.563342e-04 +127 1.270000e+00 2.592422e-04 +128 1.280000e+00 2.621338e-04 +129 1.290000e+00 2.650090e-04 +130 1.300000e+00 2.678678e-04 +131 1.310000e+00 2.707102e-04 +132 1.320000e+00 2.735362e-04 +133 1.330000e+00 2.763458e-04 +134 1.340000e+00 2.791390e-04 +135 1.350000e+00 2.819159e-04 +136 1.360000e+00 2.846765e-04 +137 1.370000e+00 2.874207e-04 +138 1.380000e+00 2.901486e-04 +139 1.390000e+00 2.928602e-04 +140 1.400000e+00 2.955555e-04 +141 1.410000e+00 2.982346e-04 +142 1.420000e+00 3.008974e-04 +143 1.430000e+00 3.035440e-04 +144 1.440000e+00 3.061745e-04 +145 1.450000e+00 3.087887e-04 +146 1.460000e+00 3.113869e-04 +147 1.470000e+00 3.139689e-04 +148 1.480000e+00 3.165348e-04 +149 1.490000e+00 3.190847e-04 +150 1.500000e+00 3.216186e-04 +151 0.000000e+00 1.412965e-11 +152 1.000000e-02 1.868439e-11 +153 2.000000e-02 2.691900e-11 +154 3.000000e-02 3.714787e-11 +155 4.000000e-02 5.125290e-11 +156 5.000000e-02 7.069545e-11 +157 6.000000e-02 9.748369e-11 +158 7.000000e-02 1.343749e-10 +159 8.000000e-02 1.851513e-10 +160 9.000000e-02 2.549952e-10 +161 1.000000e-01 3.509984e-10 +162 1.100000e-01 4.828510e-10 +163 1.200000e-01 6.637719e-10 +164 1.300000e-01 9.117578e-10 +165 1.400000e-01 1.251256e-09 +166 1.500000e-01 1.715390e-09 +167 1.600000e-01 2.348907e-09 +168 1.700000e-01 3.212054e-09 +169 1.800000e-01 4.385633e-09 +170 1.900000e-01 5.977539e-09 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +171 2.000000e-01 8.131134e-09 +172 2.100000e-01 1.103584e-08 +173 2.200000e-01 1.494041e-08 +174 2.300000e-01 2.016920e-08 +175 2.400000e-01 2.714203e-08 +176 2.500000e-01 3.639779e-08 +177 2.600000e-01 4.862215e-08 +178 2.700000e-01 6.467955e-08 +179 2.800000e-01 8.564949e-08 +180 2.900000e-01 1.128671e-07 +181 3.000000e-01 1.479685e-07 +182 3.100000e-01 1.929409e-07 +183 3.200000e-01 2.501785e-07 +184 3.300000e-01 3.225462e-07 +185 3.400000e-01 4.134518e-07 +186 3.500000e-01 5.269298e-07 +187 3.600000e-01 6.677368e-07 +188 3.700000e-01 8.414599e-07 +189 3.800000e-01 1.054632e-06 +190 3.900000e-01 1.314850e-06 +191 4.000000e-01 1.630874e-06 +192 4.100000e-01 2.012700e-06 +193 4.200000e-01 2.471565e-06 +194 4.300000e-01 3.019864e-06 +195 4.400000e-01 3.670941e-06 +196 4.500000e-01 4.438738e-06 +197 4.600000e-01 5.337287e-06 +198 4.700000e-01 6.380076e-06 +199 4.800000e-01 7.579326e-06 +200 4.900000e-01 8.945277e-06 +201 5.000000e-01 1.048555e-05 +202 5.100000e-01 1.220469e-05 +203 5.200000e-01 1.410395e-05 +204 5.300000e-01 1.618128e-05 +205 5.400000e-01 1.843163e-05 +206 5.500000e-01 2.084730e-05 +207 5.600000e-01 2.341855e-05 +208 5.700000e-01 2.613410e-05 +209 5.800000e-01 2.898174e-05 +210 5.900000e-01 3.194880e-05 +211 6.000000e-01 3.502262e-05 +212 6.100000e-01 3.819081e-05 +213 6.200000e-01 4.140222e-05 +214 6.300000e-01 4.472996e-05 +215 6.400000e-01 4.811866e-05 +216 6.500000e-01 5.155900e-05 +217 6.600000e-01 5.504264e-05 +218 6.700000e-01 5.856210e-05 +219 6.800000e-01 6.211079e-05 +220 6.900000e-01 6.568286e-05 +221 7.000000e-01 6.927323e-05 +222 7.100000e-01 7.287743e-05 +223 7.200000e-01 7.649158e-05 +224 7.300000e-01 8.011231e-05 +225 7.400000e-01 8.373669e-05 +226 7.500000e-01 8.736220e-05 +227 7.600000e-01 9.098665e-05 +228 7.700000e-01 9.460814e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +229 7.800000e-01 9.822504e-05 +230 7.900000e-01 1.018359e-04 +231 8.000000e-01 1.054396e-04 +232 8.100000e-01 1.090349e-04 +233 8.200000e-01 1.126210e-04 +234 8.300000e-01 1.161970e-04 +235 8.400000e-01 1.197623e-04 +236 8.500000e-01 1.233162e-04 +237 8.600000e-01 1.268582e-04 +238 8.700000e-01 1.303879e-04 +239 8.800000e-01 1.339047e-04 +240 8.900000e-01 1.374084e-04 +241 9.000000e-01 1.408987e-04 +242 9.100000e-01 1.443751e-04 +243 9.200000e-01 1.478375e-04 +244 9.300000e-01 1.512857e-04 +245 9.400000e-01 1.547193e-04 +246 9.500000e-01 1.581383e-04 +247 9.600000e-01 1.615425e-04 +248 9.700000e-01 1.649317e-04 +249 9.800000e-01 1.683058e-04 +250 9.900000e-01 1.716647e-04 +251 1.000000e+00 1.750082e-04 +252 1.010000e+00 1.783362e-04 +253 1.020000e+00 1.816487e-04 +254 1.030000e+00 1.849455e-04 +255 1.040000e+00 1.882266e-04 +256 1.050000e+00 1.914919e-04 +257 1.060000e+00 1.947414e-04 +258 1.070000e+00 1.979749e-04 +259 1.080000e+00 2.011925e-04 +260 1.090000e+00 2.043940e-04 +261 1.100000e+00 2.075794e-04 +262 1.110000e+00 2.107487e-04 +263 1.120000e+00 2.139019e-04 +264 1.130000e+00 2.170388e-04 +265 1.140000e+00 2.201595e-04 +266 1.150000e+00 2.232640e-04 +267 1.160000e+00 2.263522e-04 +268 1.170000e+00 2.294240e-04 +269 1.180000e+00 2.324796e-04 +270 1.190000e+00 2.355187e-04 +271 1.200000e+00 2.385416e-04 +272 1.210000e+00 2.415480e-04 +273 1.220000e+00 2.445380e-04 +274 1.230000e+00 2.475117e-04 +275 1.240000e+00 2.504689e-04 +276 1.250000e+00 2.534098e-04 +277 1.260000e+00 2.563342e-04 +278 1.270000e+00 2.592422e-04 +279 1.280000e+00 2.621338e-04 +280 1.290000e+00 2.650090e-04 +281 1.300000e+00 2.678678e-04 +282 1.310000e+00 2.707102e-04 +283 1.320000e+00 2.735362e-04 +284 1.330000e+00 2.763458e-04 +285 1.340000e+00 2.791390e-04 +286 1.350000e+00 2.819159e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +287 1.360000e+00 2.846765e-04 +288 1.370000e+00 2.874207e-04 +289 1.380000e+00 2.901486e-04 +290 1.390000e+00 2.928602e-04 +291 1.400000e+00 2.955555e-04 +292 1.410000e+00 2.982346e-04 +293 1.420000e+00 3.008974e-04 +294 1.430000e+00 3.035440e-04 +295 1.440000e+00 3.061745e-04 +296 1.450000e+00 3.087887e-04 +297 1.460000e+00 3.113869e-04 +298 1.470000e+00 3.139689e-04 +299 1.480000e+00 3.165348e-04 +300 1.490000e+00 3.190847e-04 +301 1.500000e+00 3.216186e-04 +302 0.000000e+00 1.412965e-11 +303 1.000000e-02 1.868439e-11 +304 2.000000e-02 2.691900e-11 +305 3.000000e-02 3.714787e-11 +306 4.000000e-02 5.125290e-11 +307 5.000000e-02 7.069545e-11 +308 6.000000e-02 9.748369e-11 +309 7.000000e-02 1.343749e-10 +310 8.000000e-02 1.851513e-10 +311 9.000000e-02 2.549952e-10 +312 1.000000e-01 3.509984e-10 +313 1.100000e-01 4.828510e-10 +314 1.200000e-01 6.637719e-10 +315 1.300000e-01 9.117578e-10 +316 1.400000e-01 1.251256e-09 +317 1.500000e-01 1.715390e-09 +318 1.600000e-01 2.348907e-09 +319 1.700000e-01 3.212054e-09 +320 1.800000e-01 4.385633e-09 +321 1.900000e-01 5.977539e-09 +322 2.000000e-01 8.131134e-09 +323 2.100000e-01 1.103584e-08 +324 2.200000e-01 1.494041e-08 +325 2.300000e-01 2.016920e-08 +326 2.400000e-01 2.714203e-08 +327 2.500000e-01 3.639779e-08 +328 2.600000e-01 4.862215e-08 +329 2.700000e-01 6.467955e-08 +330 2.800000e-01 8.564949e-08 +331 2.900000e-01 1.128671e-07 +332 3.000000e-01 1.479685e-07 +333 3.100000e-01 1.929409e-07 +334 3.200000e-01 2.501785e-07 +335 3.300000e-01 3.225462e-07 +336 3.400000e-01 4.134518e-07 +337 3.500000e-01 5.269298e-07 +338 3.600000e-01 6.677368e-07 +339 3.700000e-01 8.414599e-07 +340 3.800000e-01 1.054632e-06 +341 3.900000e-01 1.314850e-06 +342 4.000000e-01 1.630874e-06 +343 4.100000e-01 2.012700e-06 +344 4.200000e-01 2.471565e-06 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +345 4.300000e-01 3.019864e-06 +346 4.400000e-01 3.670941e-06 +347 4.500000e-01 4.438738e-06 +348 4.600000e-01 5.337287e-06 +349 4.700000e-01 6.380076e-06 +350 4.800000e-01 7.579326e-06 +351 4.900000e-01 8.945277e-06 +352 5.000000e-01 1.048555e-05 +353 5.100000e-01 1.220469e-05 +354 5.200000e-01 1.410395e-05 +355 5.300000e-01 1.618128e-05 +356 5.400000e-01 1.843163e-05 +357 5.500000e-01 2.084730e-05 +358 5.600000e-01 2.341855e-05 +359 5.700000e-01 2.613410e-05 +360 5.800000e-01 2.898174e-05 +361 5.900000e-01 3.194880e-05 +362 6.000000e-01 3.502262e-05 +363 6.100000e-01 3.819081e-05 +364 6.200000e-01 4.140222e-05 +365 6.300000e-01 4.472996e-05 +366 6.400000e-01 4.811866e-05 +367 6.500000e-01 5.155900e-05 +368 6.600000e-01 5.504264e-05 +369 6.700000e-01 5.856210e-05 +370 6.800000e-01 6.211079e-05 +371 6.900000e-01 6.568286e-05 +372 7.000000e-01 6.927323e-05 +373 7.100000e-01 7.287743e-05 +374 7.200000e-01 7.649158e-05 +375 7.300000e-01 8.011231e-05 +376 7.400000e-01 8.373669e-05 +377 7.500000e-01 8.736220e-05 +378 7.600000e-01 9.098665e-05 +379 7.700000e-01 9.460814e-05 +380 7.800000e-01 9.822504e-05 +381 7.900000e-01 1.018359e-04 +382 8.000000e-01 1.054396e-04 +383 8.100000e-01 1.090349e-04 +384 8.200000e-01 1.126210e-04 +385 8.300000e-01 1.161970e-04 +386 8.400000e-01 1.197623e-04 +387 8.500000e-01 1.233162e-04 +388 8.600000e-01 1.268582e-04 +389 8.700000e-01 1.303879e-04 +390 8.800000e-01 1.339047e-04 +391 8.900000e-01 1.374084e-04 +392 9.000000e-01 1.408987e-04 +393 9.100000e-01 1.443751e-04 +394 9.200000e-01 1.478375e-04 +395 9.300000e-01 1.512857e-04 +396 9.400000e-01 1.547193e-04 +397 9.500000e-01 1.581383e-04 +398 9.600000e-01 1.615425e-04 +399 9.700000e-01 1.649317e-04 +400 9.800000e-01 1.683058e-04 +401 9.900000e-01 1.716647e-04 +402 1.000000e+00 1.750082e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +403 1.010000e+00 1.783362e-04 +404 1.020000e+00 1.816487e-04 +405 1.030000e+00 1.849455e-04 +406 1.040000e+00 1.882266e-04 +407 1.050000e+00 1.914919e-04 +408 1.060000e+00 1.947414e-04 +409 1.070000e+00 1.979749e-04 +410 1.080000e+00 2.011925e-04 +411 1.090000e+00 2.043940e-04 +412 1.100000e+00 2.075794e-04 +413 1.110000e+00 2.107487e-04 +414 1.120000e+00 2.139019e-04 +415 1.130000e+00 2.170388e-04 +416 1.140000e+00 2.201595e-04 +417 1.150000e+00 2.232640e-04 +418 1.160000e+00 2.263522e-04 +419 1.170000e+00 2.294240e-04 +420 1.180000e+00 2.324796e-04 +421 1.190000e+00 2.355187e-04 +422 1.200000e+00 2.385416e-04 +423 1.210000e+00 2.415480e-04 +424 1.220000e+00 2.445380e-04 +425 1.230000e+00 2.475117e-04 +426 1.240000e+00 2.504689e-04 +427 1.250000e+00 2.534098e-04 +428 1.260000e+00 2.563342e-04 +429 1.270000e+00 2.592422e-04 +430 1.280000e+00 2.621338e-04 +431 1.290000e+00 2.650090e-04 +432 1.300000e+00 2.678678e-04 +433 1.310000e+00 2.707102e-04 +434 1.320000e+00 2.735362e-04 +435 1.330000e+00 2.763458e-04 +436 1.340000e+00 2.791390e-04 +437 1.350000e+00 2.819159e-04 +438 1.360000e+00 2.846765e-04 +439 1.370000e+00 2.874207e-04 +440 1.380000e+00 2.901486e-04 +441 1.390000e+00 2.928602e-04 +442 1.400000e+00 2.955555e-04 +443 1.410000e+00 2.982346e-04 +444 1.420000e+00 3.008974e-04 +445 1.430000e+00 3.035440e-04 +446 1.440000e+00 3.061745e-04 +447 1.450000e+00 3.087887e-04 +448 1.460000e+00 3.113869e-04 +449 1.470000e+00 3.139689e-04 +450 1.480000e+00 3.165348e-04 +451 1.490000e+00 3.190847e-04 +452 1.500000e+00 3.216186e-04 +453 0.000000e+00 1.412965e-11 +454 1.000000e-02 1.868439e-11 +455 2.000000e-02 2.691900e-11 +456 3.000000e-02 3.714787e-11 +457 4.000000e-02 5.125290e-11 +458 5.000000e-02 7.069545e-11 +459 6.000000e-02 9.748369e-11 +460 7.000000e-02 1.343749e-10 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +461 8.000000e-02 1.851513e-10 +462 9.000000e-02 2.549952e-10 +463 1.000000e-01 3.509984e-10 +464 1.100000e-01 4.828510e-10 +465 1.200000e-01 6.637719e-10 +466 1.300000e-01 9.117578e-10 +467 1.400000e-01 1.251256e-09 +468 1.500000e-01 1.715390e-09 +469 1.600000e-01 2.348907e-09 +470 1.700000e-01 3.212054e-09 +471 1.800000e-01 4.385633e-09 +472 1.900000e-01 5.977539e-09 +473 2.000000e-01 8.131134e-09 +474 2.100000e-01 1.103584e-08 +475 2.200000e-01 1.494041e-08 +476 2.300000e-01 2.016920e-08 +477 2.400000e-01 2.714203e-08 +478 2.500000e-01 3.639779e-08 +479 2.600000e-01 4.862215e-08 +480 2.700000e-01 6.467955e-08 +481 2.800000e-01 8.564949e-08 +482 2.900000e-01 1.128671e-07 +483 3.000000e-01 1.479685e-07 +484 3.100000e-01 1.929409e-07 +485 3.200000e-01 2.501785e-07 +486 3.300000e-01 3.225462e-07 +487 3.400000e-01 4.134518e-07 +488 3.500000e-01 5.269298e-07 +489 3.600000e-01 6.677368e-07 +490 3.700000e-01 8.414599e-07 +491 3.800000e-01 1.054632e-06 +492 3.900000e-01 1.314850e-06 +493 4.000000e-01 1.630874e-06 +494 4.100000e-01 2.012700e-06 +495 4.200000e-01 2.471565e-06 +496 4.300000e-01 3.019864e-06 +497 4.400000e-01 3.670941e-06 +498 4.500000e-01 4.438738e-06 +499 4.600000e-01 5.337287e-06 +500 4.700000e-01 6.380076e-06 +501 4.800000e-01 7.579326e-06 +502 4.900000e-01 8.945277e-06 +503 5.000000e-01 1.048555e-05 +504 5.100000e-01 1.220469e-05 +505 5.200000e-01 1.410395e-05 +506 5.300000e-01 1.618128e-05 +507 5.400000e-01 1.843163e-05 +508 5.500000e-01 2.084730e-05 +509 5.600000e-01 2.341855e-05 +510 5.700000e-01 2.613410e-05 +511 5.800000e-01 2.898174e-05 +512 5.900000e-01 3.194880e-05 +513 6.000000e-01 3.502262e-05 +514 6.100000e-01 3.819081e-05 +515 6.200000e-01 4.140222e-05 +516 6.300000e-01 4.472996e-05 +517 6.400000e-01 4.811866e-05 +518 6.500000e-01 5.155900e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +519 6.600000e-01 5.504264e-05 +520 6.700000e-01 5.856210e-05 +521 6.800000e-01 6.211079e-05 +522 6.900000e-01 6.568286e-05 +523 7.000000e-01 6.927323e-05 +524 7.100000e-01 7.287743e-05 +525 7.200000e-01 7.649158e-05 +526 7.300000e-01 8.011231e-05 +527 7.400000e-01 8.373669e-05 +528 7.500000e-01 8.736220e-05 +529 7.600000e-01 9.098665e-05 +530 7.700000e-01 9.460814e-05 +531 7.800000e-01 9.822504e-05 +532 7.900000e-01 1.018359e-04 +533 8.000000e-01 1.054396e-04 +534 8.100000e-01 1.090349e-04 +535 8.200000e-01 1.126210e-04 +536 8.300000e-01 1.161970e-04 +537 8.400000e-01 1.197623e-04 +538 8.500000e-01 1.233162e-04 +539 8.600000e-01 1.268582e-04 +540 8.700000e-01 1.303879e-04 +541 8.800000e-01 1.339047e-04 +542 8.900000e-01 1.374084e-04 +543 9.000000e-01 1.408987e-04 +544 9.100000e-01 1.443751e-04 +545 9.200000e-01 1.478375e-04 +546 9.300000e-01 1.512857e-04 +547 9.400000e-01 1.547193e-04 +548 9.500000e-01 1.581383e-04 +549 9.600000e-01 1.615425e-04 +550 9.700000e-01 1.649317e-04 +551 9.800000e-01 1.683058e-04 +552 9.900000e-01 1.716647e-04 +553 1.000000e+00 1.750082e-04 +554 1.010000e+00 1.783362e-04 +555 1.020000e+00 1.816487e-04 +556 1.030000e+00 1.849455e-04 +557 1.040000e+00 1.882266e-04 +558 1.050000e+00 1.914919e-04 +559 1.060000e+00 1.947414e-04 +560 1.070000e+00 1.979749e-04 +561 1.080000e+00 2.011925e-04 +562 1.090000e+00 2.043940e-04 +563 1.100000e+00 2.075794e-04 +564 1.110000e+00 2.107487e-04 +565 1.120000e+00 2.139019e-04 +566 1.130000e+00 2.170388e-04 +567 1.140000e+00 2.201595e-04 +568 1.150000e+00 2.232640e-04 +569 1.160000e+00 2.263522e-04 +570 1.170000e+00 2.294240e-04 +571 1.180000e+00 2.324796e-04 +572 1.190000e+00 2.355187e-04 +573 1.200000e+00 2.385416e-04 +574 1.210000e+00 2.415480e-04 +575 1.220000e+00 2.445380e-04 +576 1.230000e+00 2.475117e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +577 1.240000e+00 2.504689e-04 +578 1.250000e+00 2.534098e-04 +579 1.260000e+00 2.563342e-04 +580 1.270000e+00 2.592422e-04 +581 1.280000e+00 2.621338e-04 +582 1.290000e+00 2.650090e-04 +583 1.300000e+00 2.678678e-04 +584 1.310000e+00 2.707102e-04 +585 1.320000e+00 2.735362e-04 +586 1.330000e+00 2.763458e-04 +587 1.340000e+00 2.791390e-04 +588 1.350000e+00 2.819159e-04 +589 1.360000e+00 2.846765e-04 +590 1.370000e+00 2.874207e-04 +591 1.380000e+00 2.901486e-04 +592 1.390000e+00 2.928602e-04 +593 1.400000e+00 2.955555e-04 +594 1.410000e+00 2.982346e-04 +595 1.420000e+00 3.008974e-04 +596 1.430000e+00 3.035440e-04 +597 1.440000e+00 3.061745e-04 +598 1.450000e+00 3.087887e-04 +599 1.460000e+00 3.113869e-04 +600 1.470000e+00 3.139689e-04 +601 1.480000e+00 3.165348e-04 +602 1.490000e+00 3.190847e-04 +603 1.500000e+00 3.216186e-04 +604 0.000000e+00 1.412965e-11 +605 1.000000e-02 1.868439e-11 +606 2.000000e-02 2.691900e-11 +607 3.000000e-02 3.714787e-11 +608 4.000000e-02 5.125290e-11 +609 5.000000e-02 7.069545e-11 +610 6.000000e-02 9.748369e-11 +611 7.000000e-02 1.343749e-10 +612 8.000000e-02 1.851513e-10 +613 9.000000e-02 2.549952e-10 +614 1.000000e-01 3.509984e-10 +615 1.100000e-01 4.828510e-10 +616 1.200000e-01 6.637719e-10 +617 1.300000e-01 9.117578e-10 +618 1.400000e-01 1.251256e-09 +619 1.500000e-01 1.715390e-09 +620 1.600000e-01 2.348907e-09 +621 1.700000e-01 3.212054e-09 +622 1.800000e-01 4.385633e-09 +623 1.900000e-01 5.977539e-09 +624 2.000000e-01 8.131134e-09 +625 2.100000e-01 1.103584e-08 +626 2.200000e-01 1.494041e-08 +627 2.300000e-01 2.016920e-08 +628 2.400000e-01 2.714203e-08 +629 2.500000e-01 3.639779e-08 +630 2.600000e-01 4.862215e-08 +631 2.700000e-01 6.467955e-08 +632 2.800000e-01 8.564949e-08 +633 2.900000e-01 1.128671e-07 +634 3.000000e-01 1.479685e-07 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +635 3.100000e-01 1.929409e-07 +636 3.200000e-01 2.501785e-07 +637 3.300000e-01 3.225462e-07 +638 3.400000e-01 4.134518e-07 +639 3.500000e-01 5.269298e-07 +640 3.600000e-01 6.677368e-07 +641 3.700000e-01 8.414599e-07 +642 3.800000e-01 1.054632e-06 +643 3.900000e-01 1.314850e-06 +644 4.000000e-01 1.630874e-06 +645 4.100000e-01 2.012700e-06 +646 4.200000e-01 2.471565e-06 +647 4.300000e-01 3.019864e-06 +648 4.400000e-01 3.670941e-06 +649 4.500000e-01 4.438738e-06 +650 4.600000e-01 5.337287e-06 +651 4.700000e-01 6.380076e-06 +652 4.800000e-01 7.579326e-06 +653 4.900000e-01 8.945277e-06 +654 5.000000e-01 1.048555e-05 +655 5.100000e-01 1.220469e-05 +656 5.200000e-01 1.410395e-05 +657 5.300000e-01 1.618128e-05 +658 5.400000e-01 1.843163e-05 +659 5.500000e-01 2.084730e-05 +660 5.600000e-01 2.341855e-05 +661 5.700000e-01 2.613410e-05 +662 5.800000e-01 2.898174e-05 +663 5.900000e-01 3.194880e-05 +664 6.000000e-01 3.502262e-05 +665 6.100000e-01 3.819081e-05 +666 6.200000e-01 4.140222e-05 +667 6.300000e-01 4.472996e-05 +668 6.400000e-01 4.811866e-05 +669 6.500000e-01 5.155900e-05 +670 6.600000e-01 5.504264e-05 +671 6.700000e-01 5.856210e-05 +672 6.800000e-01 6.211079e-05 +673 6.900000e-01 6.568286e-05 +674 7.000000e-01 6.927323e-05 +675 7.100000e-01 7.287743e-05 +676 7.200000e-01 7.649158e-05 +677 7.300000e-01 8.011231e-05 +678 7.400000e-01 8.373669e-05 +679 7.500000e-01 8.736220e-05 +680 7.600000e-01 9.098665e-05 +681 7.700000e-01 9.460814e-05 +682 7.800000e-01 9.822504e-05 +683 7.900000e-01 1.018359e-04 +684 8.000000e-01 1.054396e-04 +685 8.100000e-01 1.090349e-04 +686 8.200000e-01 1.126210e-04 +687 8.300000e-01 1.161970e-04 +688 8.400000e-01 1.197623e-04 +689 8.500000e-01 1.233162e-04 +690 8.600000e-01 1.268582e-04 +691 8.700000e-01 1.303879e-04 +692 8.800000e-01 1.339047e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +693 8.900000e-01 1.374084e-04 +694 9.000000e-01 1.408987e-04 +695 9.100000e-01 1.443751e-04 +696 9.200000e-01 1.478375e-04 +697 9.300000e-01 1.512857e-04 +698 9.400000e-01 1.547193e-04 +699 9.500000e-01 1.581383e-04 +700 9.600000e-01 1.615425e-04 +701 9.700000e-01 1.649317e-04 +702 9.800000e-01 1.683058e-04 +703 9.900000e-01 1.716647e-04 +704 1.000000e+00 1.750082e-04 +705 1.010000e+00 1.783362e-04 +706 1.020000e+00 1.816487e-04 +707 1.030000e+00 1.849455e-04 +708 1.040000e+00 1.882266e-04 +709 1.050000e+00 1.914919e-04 +710 1.060000e+00 1.947414e-04 +711 1.070000e+00 1.979749e-04 +712 1.080000e+00 2.011925e-04 +713 1.090000e+00 2.043940e-04 +714 1.100000e+00 2.075794e-04 +715 1.110000e+00 2.107487e-04 +716 1.120000e+00 2.139019e-04 +717 1.130000e+00 2.170388e-04 +718 1.140000e+00 2.201595e-04 +719 1.150000e+00 2.232640e-04 +720 1.160000e+00 2.263522e-04 +721 1.170000e+00 2.294240e-04 +722 1.180000e+00 2.324796e-04 +723 1.190000e+00 2.355187e-04 +724 1.200000e+00 2.385416e-04 +725 1.210000e+00 2.415480e-04 +726 1.220000e+00 2.445380e-04 +727 1.230000e+00 2.475117e-04 +728 1.240000e+00 2.504689e-04 +729 1.250000e+00 2.534098e-04 +730 1.260000e+00 2.563342e-04 +731 1.270000e+00 2.592422e-04 +732 1.280000e+00 2.621338e-04 +733 1.290000e+00 2.650090e-04 +734 1.300000e+00 2.678678e-04 +735 1.310000e+00 2.707102e-04 +736 1.320000e+00 2.735362e-04 +737 1.330000e+00 2.763458e-04 +738 1.340000e+00 2.791390e-04 +739 1.350000e+00 2.819159e-04 +740 1.360000e+00 2.846765e-04 +741 1.370000e+00 2.874207e-04 +742 1.380000e+00 2.901486e-04 +743 1.390000e+00 2.928602e-04 +744 1.400000e+00 2.955555e-04 +745 1.410000e+00 2.982346e-04 +746 1.420000e+00 3.008974e-04 +747 1.430000e+00 3.035440e-04 +748 1.440000e+00 3.061745e-04 +749 1.450000e+00 3.087887e-04 +750 1.460000e+00 3.113869e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +751 1.470000e+00 3.139689e-04 +752 1.480000e+00 3.165348e-04 +753 1.490000e+00 3.190847e-04 +754 1.500000e+00 3.216186e-04 +755 0.000000e+00 1.412965e-11 +756 1.000000e-02 1.868439e-11 +757 2.000000e-02 2.691900e-11 +758 3.000000e-02 3.714787e-11 +759 4.000000e-02 5.125290e-11 +760 5.000000e-02 7.069545e-11 +761 6.000000e-02 9.748369e-11 +762 7.000000e-02 1.343749e-10 +763 8.000000e-02 1.851513e-10 +764 9.000000e-02 2.549952e-10 +765 1.000000e-01 3.509984e-10 +766 1.100000e-01 4.828510e-10 +767 1.200000e-01 6.637719e-10 +768 1.300000e-01 9.117578e-10 +769 1.400000e-01 1.251256e-09 +770 1.500000e-01 1.715390e-09 +771 1.600000e-01 2.348907e-09 +772 1.700000e-01 3.212054e-09 +773 1.800000e-01 4.385633e-09 +774 1.900000e-01 5.977539e-09 +775 2.000000e-01 8.131134e-09 +776 2.100000e-01 1.103584e-08 +777 2.200000e-01 1.494041e-08 +778 2.300000e-01 2.016920e-08 +779 2.400000e-01 2.714203e-08 +780 2.500000e-01 3.639779e-08 +781 2.600000e-01 4.862215e-08 +782 2.700000e-01 6.467955e-08 +783 2.800000e-01 8.564949e-08 +784 2.900000e-01 1.128671e-07 +785 3.000000e-01 1.479685e-07 +786 3.100000e-01 1.929409e-07 +787 3.200000e-01 2.501785e-07 +788 3.300000e-01 3.225462e-07 +789 3.400000e-01 4.134518e-07 +790 3.500000e-01 5.269298e-07 +791 3.600000e-01 6.677368e-07 +792 3.700000e-01 8.414599e-07 +793 3.800000e-01 1.054632e-06 +794 3.900000e-01 1.314850e-06 +795 4.000000e-01 1.630874e-06 +796 4.100000e-01 2.012700e-06 +797 4.200000e-01 2.471565e-06 +798 4.300000e-01 3.019864e-06 +799 4.400000e-01 3.670941e-06 +800 4.500000e-01 4.438738e-06 +801 4.600000e-01 5.337287e-06 +802 4.700000e-01 6.380076e-06 +803 4.800000e-01 7.579326e-06 +804 4.900000e-01 8.945277e-06 +805 5.000000e-01 1.048555e-05 +806 5.100000e-01 1.220469e-05 +807 5.200000e-01 1.410395e-05 +808 5.300000e-01 1.618128e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +809 5.400000e-01 1.843163e-05 +810 5.500000e-01 2.084730e-05 +811 5.600000e-01 2.341855e-05 +812 5.700000e-01 2.613410e-05 +813 5.800000e-01 2.898174e-05 +814 5.900000e-01 3.194880e-05 +815 6.000000e-01 3.502262e-05 +816 6.100000e-01 3.819081e-05 +817 6.200000e-01 4.140222e-05 +818 6.300000e-01 4.472996e-05 +819 6.400000e-01 4.811866e-05 +820 6.500000e-01 5.155900e-05 +821 6.600000e-01 5.504264e-05 +822 6.700000e-01 5.856210e-05 +823 6.800000e-01 6.211079e-05 +824 6.900000e-01 6.568286e-05 +825 7.000000e-01 6.927323e-05 +826 7.100000e-01 7.287743e-05 +827 7.200000e-01 7.649158e-05 +828 7.300000e-01 8.011231e-05 +829 7.400000e-01 8.373669e-05 +830 7.500000e-01 8.736220e-05 +831 7.600000e-01 9.098665e-05 +832 7.700000e-01 9.460814e-05 +833 7.800000e-01 9.822504e-05 +834 7.900000e-01 1.018359e-04 +835 8.000000e-01 1.054396e-04 +836 8.100000e-01 1.090349e-04 +837 8.200000e-01 1.126210e-04 +838 8.300000e-01 1.161970e-04 +839 8.400000e-01 1.197623e-04 +840 8.500000e-01 1.233162e-04 +841 8.600000e-01 1.268582e-04 +842 8.700000e-01 1.303879e-04 +843 8.800000e-01 1.339047e-04 +844 8.900000e-01 1.374084e-04 +845 9.000000e-01 1.408987e-04 +846 9.100000e-01 1.443751e-04 +847 9.200000e-01 1.478375e-04 +848 9.300000e-01 1.512857e-04 +849 9.400000e-01 1.547193e-04 +850 9.500000e-01 1.581383e-04 +851 9.600000e-01 1.615425e-04 +852 9.700000e-01 1.649317e-04 +853 9.800000e-01 1.683058e-04 +854 9.900000e-01 1.716647e-04 +855 1.000000e+00 1.750082e-04 +856 1.010000e+00 1.783362e-04 +857 1.020000e+00 1.816487e-04 +858 1.030000e+00 1.849455e-04 +859 1.040000e+00 1.882266e-04 +860 1.050000e+00 1.914919e-04 +861 1.060000e+00 1.947414e-04 +862 1.070000e+00 1.979749e-04 +863 1.080000e+00 2.011925e-04 +864 1.090000e+00 2.043940e-04 +865 1.100000e+00 2.075794e-04 +866 1.110000e+00 2.107487e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +867 1.120000e+00 2.139019e-04 +868 1.130000e+00 2.170388e-04 +869 1.140000e+00 2.201595e-04 +870 1.150000e+00 2.232640e-04 +871 1.160000e+00 2.263522e-04 +872 1.170000e+00 2.294240e-04 +873 1.180000e+00 2.324796e-04 +874 1.190000e+00 2.355187e-04 +875 1.200000e+00 2.385416e-04 +876 1.210000e+00 2.415480e-04 +877 1.220000e+00 2.445380e-04 +878 1.230000e+00 2.475117e-04 +879 1.240000e+00 2.504689e-04 +880 1.250000e+00 2.534098e-04 +881 1.260000e+00 2.563342e-04 +882 1.270000e+00 2.592422e-04 +883 1.280000e+00 2.621338e-04 +884 1.290000e+00 2.650090e-04 +885 1.300000e+00 2.678678e-04 +886 1.310000e+00 2.707102e-04 +887 1.320000e+00 2.735362e-04 +888 1.330000e+00 2.763458e-04 +889 1.340000e+00 2.791390e-04 +890 1.350000e+00 2.819159e-04 +891 1.360000e+00 2.846765e-04 +892 1.370000e+00 2.874207e-04 +893 1.380000e+00 2.901486e-04 +894 1.390000e+00 2.928602e-04 +895 1.400000e+00 2.955555e-04 +896 1.410000e+00 2.982346e-04 +897 1.420000e+00 3.008974e-04 +898 1.430000e+00 3.035440e-04 +899 1.440000e+00 3.061745e-04 +900 1.450000e+00 3.087887e-04 +901 1.460000e+00 3.113869e-04 +902 1.470000e+00 3.139689e-04 +903 1.480000e+00 3.165348e-04 +904 1.490000e+00 3.190847e-04 +905 1.500000e+00 3.216186e-04 +906 0.000000e+00 1.412965e-11 +907 1.000000e-02 1.868439e-11 +908 2.000000e-02 2.691900e-11 +909 3.000000e-02 3.714787e-11 +910 4.000000e-02 5.125290e-11 +911 5.000000e-02 7.069545e-11 +912 6.000000e-02 9.748369e-11 +913 7.000000e-02 1.343749e-10 +914 8.000000e-02 1.851513e-10 +915 9.000000e-02 2.549952e-10 +916 1.000000e-01 3.509984e-10 +917 1.100000e-01 4.828510e-10 +918 1.200000e-01 6.637719e-10 +919 1.300000e-01 9.117578e-10 +920 1.400000e-01 1.251256e-09 +921 1.500000e-01 1.715390e-09 +922 1.600000e-01 2.348907e-09 +923 1.700000e-01 3.212054e-09 +924 1.800000e-01 4.385633e-09 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +925 1.900000e-01 5.977539e-09 +926 2.000000e-01 8.131134e-09 +927 2.100000e-01 1.103584e-08 +928 2.200000e-01 1.494041e-08 +929 2.300000e-01 2.016920e-08 +930 2.400000e-01 2.714203e-08 +931 2.500000e-01 3.639779e-08 +932 2.600000e-01 4.862215e-08 +933 2.700000e-01 6.467955e-08 +934 2.800000e-01 8.564949e-08 +935 2.900000e-01 1.128671e-07 +936 3.000000e-01 1.479685e-07 +937 3.100000e-01 1.929409e-07 +938 3.200000e-01 2.501785e-07 +939 3.300000e-01 3.225462e-07 +940 3.400000e-01 4.134518e-07 +941 3.500000e-01 5.269298e-07 +942 3.600000e-01 6.677368e-07 +943 3.700000e-01 8.414599e-07 +944 3.800000e-01 1.054632e-06 +945 3.900000e-01 1.314850e-06 +946 4.000000e-01 1.630874e-06 +947 4.100000e-01 2.012700e-06 +948 4.200000e-01 2.471565e-06 +949 4.300000e-01 3.019864e-06 +950 4.400000e-01 3.670941e-06 +951 4.500000e-01 4.438738e-06 +952 4.600000e-01 5.337287e-06 +953 4.700000e-01 6.380076e-06 +954 4.800000e-01 7.579326e-06 +955 4.900000e-01 8.945277e-06 +956 5.000000e-01 1.048555e-05 +957 5.100000e-01 1.220469e-05 +958 5.200000e-01 1.410395e-05 +959 5.300000e-01 1.618128e-05 +960 5.400000e-01 1.843163e-05 +961 5.500000e-01 2.084730e-05 +962 5.600000e-01 2.341855e-05 +963 5.700000e-01 2.613410e-05 +964 5.800000e-01 2.898174e-05 +965 5.900000e-01 3.194880e-05 +966 6.000000e-01 3.502262e-05 +967 6.100000e-01 3.819081e-05 +968 6.200000e-01 4.140222e-05 +969 6.300000e-01 4.472996e-05 +970 6.400000e-01 4.811866e-05 +971 6.500000e-01 5.155900e-05 +972 6.600000e-01 5.504264e-05 +973 6.700000e-01 5.856210e-05 +974 6.800000e-01 6.211079e-05 +975 6.900000e-01 6.568286e-05 +976 7.000000e-01 6.927323e-05 +977 7.100000e-01 7.287743e-05 +978 7.200000e-01 7.649158e-05 +979 7.300000e-01 8.011231e-05 +980 7.400000e-01 8.373669e-05 +981 7.500000e-01 8.736220e-05 +982 7.600000e-01 9.098665e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +983 7.700000e-01 9.460814e-05 +984 7.800000e-01 9.822504e-05 +985 7.900000e-01 1.018359e-04 +986 8.000000e-01 1.054396e-04 +987 8.100000e-01 1.090349e-04 +988 8.200000e-01 1.126210e-04 +989 8.300000e-01 1.161970e-04 +990 8.400000e-01 1.197623e-04 +991 8.500000e-01 1.233162e-04 +992 8.600000e-01 1.268582e-04 +993 8.700000e-01 1.303879e-04 +994 8.800000e-01 1.339047e-04 +995 8.900000e-01 1.374084e-04 +996 9.000000e-01 1.408987e-04 +997 9.100000e-01 1.443751e-04 +998 9.200000e-01 1.478375e-04 +999 9.300000e-01 1.512857e-04 +1000 9.400000e-01 1.547193e-04 +1001 9.500000e-01 1.581383e-04 +1002 9.600000e-01 1.615425e-04 +1003 9.700000e-01 1.649317e-04 +1004 9.800000e-01 1.683058e-04 +1005 9.900000e-01 1.716647e-04 +1006 1.000000e+00 1.750082e-04 +1007 1.010000e+00 1.783362e-04 +1008 1.020000e+00 1.816487e-04 +1009 1.030000e+00 1.849455e-04 +1010 1.040000e+00 1.882266e-04 +1011 1.050000e+00 1.914919e-04 +1012 1.060000e+00 1.947414e-04 +1013 1.070000e+00 1.979749e-04 +1014 1.080000e+00 2.011925e-04 +1015 1.090000e+00 2.043940e-04 +1016 1.100000e+00 2.075794e-04 +1017 1.110000e+00 2.107487e-04 +1018 1.120000e+00 2.139019e-04 +1019 1.130000e+00 2.170388e-04 +1020 1.140000e+00 2.201595e-04 +1021 1.150000e+00 2.232640e-04 +1022 1.160000e+00 2.263522e-04 +1023 1.170000e+00 2.294240e-04 +1024 1.180000e+00 2.324796e-04 +1025 1.190000e+00 2.355187e-04 +1026 1.200000e+00 2.385416e-04 +1027 1.210000e+00 2.415480e-04 +1028 1.220000e+00 2.445380e-04 +1029 1.230000e+00 2.475117e-04 +1030 1.240000e+00 2.504689e-04 +1031 1.250000e+00 2.534098e-04 +1032 1.260000e+00 2.563342e-04 +1033 1.270000e+00 2.592422e-04 +1034 1.280000e+00 2.621338e-04 +1035 1.290000e+00 2.650090e-04 +1036 1.300000e+00 2.678678e-04 +1037 1.310000e+00 2.707102e-04 +1038 1.320000e+00 2.735362e-04 +1039 1.330000e+00 2.763458e-04 +1040 1.340000e+00 2.791390e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1041 1.350000e+00 2.819159e-04 +1042 1.360000e+00 2.846765e-04 +1043 1.370000e+00 2.874207e-04 +1044 1.380000e+00 2.901486e-04 +1045 1.390000e+00 2.928602e-04 +1046 1.400000e+00 2.955555e-04 +1047 1.410000e+00 2.982346e-04 +1048 1.420000e+00 3.008974e-04 +1049 1.430000e+00 3.035440e-04 +1050 1.440000e+00 3.061745e-04 +1051 1.450000e+00 3.087887e-04 +1052 1.460000e+00 3.113869e-04 +1053 1.470000e+00 3.139689e-04 +1054 1.480000e+00 3.165348e-04 +1055 1.490000e+00 3.190847e-04 +1056 1.500000e+00 3.216186e-04 +1057 0.000000e+00 1.412965e-11 +1058 1.000000e-02 1.868439e-11 +1059 2.000000e-02 2.691900e-11 +1060 3.000000e-02 3.714787e-11 +1061 4.000000e-02 5.125290e-11 +1062 5.000000e-02 7.069545e-11 +1063 6.000000e-02 9.748369e-11 +1064 7.000000e-02 1.343749e-10 +1065 8.000000e-02 1.851513e-10 +1066 9.000000e-02 2.549952e-10 +1067 1.000000e-01 3.509984e-10 +1068 1.100000e-01 4.828510e-10 +1069 1.200000e-01 6.637719e-10 +1070 1.300000e-01 9.117578e-10 +1071 1.400000e-01 1.251256e-09 +1072 1.500000e-01 1.715390e-09 +1073 1.600000e-01 2.348907e-09 +1074 1.700000e-01 3.212054e-09 +1075 1.800000e-01 4.385633e-09 +1076 1.900000e-01 5.977539e-09 +1077 2.000000e-01 8.131134e-09 +1078 2.100000e-01 1.103584e-08 +1079 2.200000e-01 1.494041e-08 +1080 2.300000e-01 2.016920e-08 +1081 2.400000e-01 2.714203e-08 +1082 2.500000e-01 3.639779e-08 +1083 2.600000e-01 4.862215e-08 +1084 2.700000e-01 6.467955e-08 +1085 2.800000e-01 8.564949e-08 +1086 2.900000e-01 1.128671e-07 +1087 3.000000e-01 1.479685e-07 +1088 3.100000e-01 1.929409e-07 +1089 3.200000e-01 2.501785e-07 +1090 3.300000e-01 3.225462e-07 +1091 3.400000e-01 4.134518e-07 +1092 3.500000e-01 5.269298e-07 +1093 3.600000e-01 6.677368e-07 +1094 3.700000e-01 8.414599e-07 +1095 3.800000e-01 1.054632e-06 +1096 3.900000e-01 1.314850e-06 +1097 4.000000e-01 1.630874e-06 +1098 4.100000e-01 2.012700e-06 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1099 4.200000e-01 2.471565e-06 +1100 4.300000e-01 3.019864e-06 +1101 4.400000e-01 3.670941e-06 +1102 4.500000e-01 4.438738e-06 +1103 4.600000e-01 5.337287e-06 +1104 4.700000e-01 6.380076e-06 +1105 4.800000e-01 7.579326e-06 +1106 4.900000e-01 8.945277e-06 +1107 5.000000e-01 1.048555e-05 +1108 5.100000e-01 1.220469e-05 +1109 5.200000e-01 1.410395e-05 +1110 5.300000e-01 1.618128e-05 +1111 5.400000e-01 1.843163e-05 +1112 5.500000e-01 2.084730e-05 +1113 5.600000e-01 2.341855e-05 +1114 5.700000e-01 2.613410e-05 +1115 5.800000e-01 2.898174e-05 +1116 5.900000e-01 3.194880e-05 +1117 6.000000e-01 3.502262e-05 +1118 6.100000e-01 3.819081e-05 +1119 6.200000e-01 4.140222e-05 +1120 6.300000e-01 4.472996e-05 +1121 6.400000e-01 4.811866e-05 +1122 6.500000e-01 5.155900e-05 +1123 6.600000e-01 5.504264e-05 +1124 6.700000e-01 5.856210e-05 +1125 6.800000e-01 6.211079e-05 +1126 6.900000e-01 6.568286e-05 +1127 7.000000e-01 6.927323e-05 +1128 7.100000e-01 7.287743e-05 +1129 7.200000e-01 7.649158e-05 +1130 7.300000e-01 8.011231e-05 +1131 7.400000e-01 8.373669e-05 +1132 7.500000e-01 8.736220e-05 +1133 7.600000e-01 9.098665e-05 +1134 7.700000e-01 9.460814e-05 +1135 7.800000e-01 9.822504e-05 +1136 7.900000e-01 1.018359e-04 +1137 8.000000e-01 1.054396e-04 +1138 8.100000e-01 1.090349e-04 +1139 8.200000e-01 1.126210e-04 +1140 8.300000e-01 1.161970e-04 +1141 8.400000e-01 1.197623e-04 +1142 8.500000e-01 1.233162e-04 +1143 8.600000e-01 1.268582e-04 +1144 8.700000e-01 1.303879e-04 +1145 8.800000e-01 1.339047e-04 +1146 8.900000e-01 1.374084e-04 +1147 9.000000e-01 1.408987e-04 +1148 9.100000e-01 1.443751e-04 +1149 9.200000e-01 1.478375e-04 +1150 9.300000e-01 1.512857e-04 +1151 9.400000e-01 1.547193e-04 +1152 9.500000e-01 1.581383e-04 +1153 9.600000e-01 1.615425e-04 +1154 9.700000e-01 1.649317e-04 +1155 9.800000e-01 1.683058e-04 +1156 9.900000e-01 1.716647e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1157 1.000000e+00 1.750082e-04 +1158 1.010000e+00 1.783362e-04 +1159 1.020000e+00 1.816487e-04 +1160 1.030000e+00 1.849455e-04 +1161 1.040000e+00 1.882266e-04 +1162 1.050000e+00 1.914919e-04 +1163 1.060000e+00 1.947414e-04 +1164 1.070000e+00 1.979749e-04 +1165 1.080000e+00 2.011925e-04 +1166 1.090000e+00 2.043940e-04 +1167 1.100000e+00 2.075794e-04 +1168 1.110000e+00 2.107487e-04 +1169 1.120000e+00 2.139019e-04 +1170 1.130000e+00 2.170388e-04 +1171 1.140000e+00 2.201595e-04 +1172 1.150000e+00 2.232640e-04 +1173 1.160000e+00 2.263522e-04 +1174 1.170000e+00 2.294240e-04 +1175 1.180000e+00 2.324796e-04 +1176 1.190000e+00 2.355187e-04 +1177 1.200000e+00 2.385416e-04 +1178 1.210000e+00 2.415480e-04 +1179 1.220000e+00 2.445380e-04 +1180 1.230000e+00 2.475117e-04 +1181 1.240000e+00 2.504689e-04 +1182 1.250000e+00 2.534098e-04 +1183 1.260000e+00 2.563342e-04 +1184 1.270000e+00 2.592422e-04 +1185 1.280000e+00 2.621338e-04 +1186 1.290000e+00 2.650090e-04 +1187 1.300000e+00 2.678678e-04 +1188 1.310000e+00 2.707102e-04 +1189 1.320000e+00 2.735362e-04 +1190 1.330000e+00 2.763458e-04 +1191 1.340000e+00 2.791390e-04 +1192 1.350000e+00 2.819159e-04 +1193 1.360000e+00 2.846765e-04 +1194 1.370000e+00 2.874207e-04 +1195 1.380000e+00 2.901486e-04 +1196 1.390000e+00 2.928602e-04 +1197 1.400000e+00 2.955555e-04 +1198 1.410000e+00 2.982346e-04 +1199 1.420000e+00 3.008974e-04 +1200 1.430000e+00 3.035440e-04 +1201 1.440000e+00 3.061745e-04 +1202 1.450000e+00 3.087887e-04 +1203 1.460000e+00 3.113869e-04 +1204 1.470000e+00 3.139689e-04 +1205 1.480000e+00 3.165348e-04 +1206 1.490000e+00 3.190847e-04 +1207 1.500000e+00 3.216186e-04 +1208 0.000000e+00 1.412965e-11 +1209 1.000000e-02 1.868439e-11 +1210 2.000000e-02 2.691900e-11 +1211 3.000000e-02 3.714787e-11 +1212 4.000000e-02 5.125290e-11 +1213 5.000000e-02 7.069545e-11 +1214 6.000000e-02 9.748369e-11 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1215 7.000000e-02 1.343749e-10 +1216 8.000000e-02 1.851513e-10 +1217 9.000000e-02 2.549952e-10 +1218 1.000000e-01 3.509984e-10 +1219 1.100000e-01 4.828510e-10 +1220 1.200000e-01 6.637719e-10 +1221 1.300000e-01 9.117578e-10 +1222 1.400000e-01 1.251256e-09 +1223 1.500000e-01 1.715390e-09 +1224 1.600000e-01 2.348907e-09 +1225 1.700000e-01 3.212054e-09 +1226 1.800000e-01 4.385633e-09 +1227 1.900000e-01 5.977539e-09 +1228 2.000000e-01 8.131134e-09 +1229 2.100000e-01 1.103584e-08 +1230 2.200000e-01 1.494041e-08 +1231 2.300000e-01 2.016920e-08 +1232 2.400000e-01 2.714203e-08 +1233 2.500000e-01 3.639779e-08 +1234 2.600000e-01 4.862215e-08 +1235 2.700000e-01 6.467955e-08 +1236 2.800000e-01 8.564949e-08 +1237 2.900000e-01 1.128671e-07 +1238 3.000000e-01 1.479685e-07 +1239 3.100000e-01 1.929409e-07 +1240 3.200000e-01 2.501785e-07 +1241 3.300000e-01 3.225462e-07 +1242 3.400000e-01 4.134518e-07 +1243 3.500000e-01 5.269298e-07 +1244 3.600000e-01 6.677368e-07 +1245 3.700000e-01 8.414599e-07 +1246 3.800000e-01 1.054632e-06 +1247 3.900000e-01 1.314850e-06 +1248 4.000000e-01 1.630874e-06 +1249 4.100000e-01 2.012700e-06 +1250 4.200000e-01 2.471565e-06 +1251 4.300000e-01 3.019864e-06 +1252 4.400000e-01 3.670941e-06 +1253 4.500000e-01 4.438738e-06 +1254 4.600000e-01 5.337287e-06 +1255 4.700000e-01 6.380076e-06 +1256 4.800000e-01 7.579326e-06 +1257 4.900000e-01 8.945277e-06 +1258 5.000000e-01 1.048555e-05 +1259 5.100000e-01 1.220469e-05 +1260 5.200000e-01 1.410395e-05 +1261 5.300000e-01 1.618128e-05 +1262 5.400000e-01 1.843163e-05 +1263 5.500000e-01 2.084730e-05 +1264 5.600000e-01 2.341855e-05 +1265 5.700000e-01 2.613410e-05 +1266 5.800000e-01 2.898174e-05 +1267 5.900000e-01 3.194880e-05 +1268 6.000000e-01 3.502262e-05 +1269 6.100000e-01 3.819081e-05 +1270 6.200000e-01 4.140222e-05 +1271 6.300000e-01 4.472996e-05 +1272 6.400000e-01 4.811866e-05 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1273 6.500000e-01 5.155900e-05 +1274 6.600000e-01 5.504264e-05 +1275 6.700000e-01 5.856210e-05 +1276 6.800000e-01 6.211079e-05 +1277 6.900000e-01 6.568286e-05 +1278 7.000000e-01 6.927323e-05 +1279 7.100000e-01 7.287743e-05 +1280 7.200000e-01 7.649158e-05 +1281 7.300000e-01 8.011231e-05 +1282 7.400000e-01 8.373669e-05 +1283 7.500000e-01 8.736220e-05 +1284 7.600000e-01 9.098665e-05 +1285 7.700000e-01 9.460814e-05 +1286 7.800000e-01 9.822504e-05 +1287 7.900000e-01 1.018359e-04 +1288 8.000000e-01 1.054396e-04 +1289 8.100000e-01 1.090349e-04 +1290 8.200000e-01 1.126210e-04 +1291 8.300000e-01 1.161970e-04 +1292 8.400000e-01 1.197623e-04 +1293 8.500000e-01 1.233162e-04 +1294 8.600000e-01 1.268582e-04 +1295 8.700000e-01 1.303879e-04 +1296 8.800000e-01 1.339047e-04 +1297 8.900000e-01 1.374084e-04 +1298 9.000000e-01 1.408987e-04 +1299 9.100000e-01 1.443751e-04 +1300 9.200000e-01 1.478375e-04 +1301 9.300000e-01 1.512857e-04 +1302 9.400000e-01 1.547193e-04 +1303 9.500000e-01 1.581383e-04 +1304 9.600000e-01 1.615425e-04 +1305 9.700000e-01 1.649317e-04 +1306 9.800000e-01 1.683058e-04 +1307 9.900000e-01 1.716647e-04 +1308 1.000000e+00 1.750082e-04 +1309 1.010000e+00 1.783362e-04 +1310 1.020000e+00 1.816487e-04 +1311 1.030000e+00 1.849455e-04 +1312 1.040000e+00 1.882266e-04 +1313 1.050000e+00 1.914919e-04 +1314 1.060000e+00 1.947414e-04 +1315 1.070000e+00 1.979749e-04 +1316 1.080000e+00 2.011925e-04 +1317 1.090000e+00 2.043940e-04 +1318 1.100000e+00 2.075794e-04 +1319 1.110000e+00 2.107487e-04 +1320 1.120000e+00 2.139019e-04 +1321 1.130000e+00 2.170388e-04 +1322 1.140000e+00 2.201595e-04 +1323 1.150000e+00 2.232640e-04 +1324 1.160000e+00 2.263522e-04 +1325 1.170000e+00 2.294240e-04 +1326 1.180000e+00 2.324796e-04 +1327 1.190000e+00 2.355187e-04 +1328 1.200000e+00 2.385416e-04 +1329 1.210000e+00 2.415480e-04 +1330 1.220000e+00 2.445380e-04 + +Index v-sweep vs#branch +-------------------------------------------------------------------------------- +1331 1.230000e+00 2.475117e-04 +1332 1.240000e+00 2.504689e-04 +1333 1.250000e+00 2.534098e-04 +1334 1.260000e+00 2.563342e-04 +1335 1.270000e+00 2.592422e-04 +1336 1.280000e+00 2.621338e-04 +1337 1.290000e+00 2.650090e-04 +1338 1.300000e+00 2.678678e-04 +1339 1.310000e+00 2.707102e-04 +1340 1.320000e+00 2.735362e-04 +1341 1.330000e+00 2.763458e-04 +1342 1.340000e+00 2.791390e-04 +1343 1.350000e+00 2.819159e-04 +1344 1.360000e+00 2.846765e-04 +1345 1.370000e+00 2.874207e-04 +1346 1.380000e+00 2.901486e-04 +1347 1.390000e+00 2.928602e-04 +1348 1.400000e+00 2.955555e-04 +1349 1.410000e+00 2.982346e-04 +1350 1.420000e+00 3.008974e-04 +1351 1.430000e+00 3.035440e-04 +1352 1.440000e+00 3.061745e-04 +1353 1.450000e+00 3.087887e-04 +1354 1.460000e+00 3.113869e-04 +1355 1.470000e+00 3.139689e-04 +1356 1.480000e+00 3.165348e-04 +1357 1.490000e+00 3.190847e-04 +1358 1.500000e+00 3.216186e-04 + + + + diff --git a/tests/bsim4/Makefile.am b/tests/bsim4/Makefile.am new file mode 100644 index 000000000..98e5e4629 --- /dev/null +++ b/tests/bsim4/Makefile.am @@ -0,0 +1,29 @@ +## Process this file with automake to produce Makefile.in + +TESTS = \ + test1.cir \ + test2.cir \ + test3.cir \ + test4.cir \ + test5.cir \ + test6.cir \ + test7.cir \ + test8.cir \ + test9.cir \ + test10.cir \ + test11.cir \ + test12.cir \ + test13.cir \ + test14.cir \ + comprt.cir \ + gstage.cir \ + oneshot.cir \ + opamp.cir + +TESTS_ENVIRONMENT = $(SHELL) $(srcdir)/../check.sh $(top_builddir)/src/ngspice + +EXTRA_DIST = \ + $(TESTS) \ + $(TESTS:.cir=.out) + +MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/bsim4/comprt.cir b/tests/bsim4/comprt.cir new file mode 100644 index 000000000..17fd43f81 --- /dev/null +++ b/tests/bsim4/comprt.cir @@ -0,0 +1,34 @@ +** One-Bit Comparator (Tran): Benchmarking Implementation of BSIM4.0.0 by Weidong Liu 5/16/2000. + +M1 Anot A Vdd Vdd P1 W=3.6u L=1.2u +M2 Anot A 0 0 N1 W=1.8u L=1.2u +M3 Bnot B Vdd Vdd P1 W=3.6u L=1.2u +M4 Bnot B 0 0 N1 W=1.8u L=1.2u +M5 AorBnot 0 Vdd Vdd P1 W=1.8u L=3.6u +M6 AorBnot B 1 0 N1 W=1.8u L=1.2u +M7 1 Anot 0 0 N1 W=1.8u L=1.2u +M8 Lnot 0 Vdd Vdd P1 W=1.8u L=3.6u +M9 Lnot Bnot 2 0 N1 W=1.8u L=1.2u +M10 2 A 0 0 N1 W=1.8u L=1.2u +M11 Qnot 0 Vdd Vdd P1 W=3.6u L=3.6u +M12 Qnot AorBnot 3 0 N1 W=1.8u L=1.2u +M13 3 Lnot 0 0 N1 W=1.8u L=1.2u +MQLO 8 Qnot Vdd Vdd P1 W=3.6u L=1.2u +MQL1 8 Qnot 0 0 N1 W=1.8u L=1.2u +MLTO 9 Lnot Vdd Vdd P1 W=3.6u L=1.2u +MLT1 9 Lnot 0 0 N1 W=1.8u L=1.2u +CQ Qnot 0 30f +CL Lnot 0 10f + +Vdd Vdd 0 1.8 +Va A 0 pulse 0 1.8 10ns .1ns .1ns 15ns 30ns +Vb B 0 0 + +.include modelcard.nmos +.include modelcard.pmos + +.tran 1ns 60ns +.option post +.print tran a b v(9) v(8) + +.end diff --git a/tests/bsim4/comprt.out b/tests/bsim4/comprt.out new file mode 100644 index 000000000..67e0126c8 --- /dev/null +++ b/tests/bsim4/comprt.out @@ -0,0 +1,374 @@ +Warning: va: no DC value, transient time 0 value used + +Circuit: ** One-Bit Comparator (Tran): Benchmarking Implementation of BSIM4.0.0 by Weidong Liu 5/16/2000. + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. + +Initial Transient Solution +-------------------------- + +Node Voltage +---- ------- +anot 1.8 +a 0 +vdd 1.8 +bnot 1.8 +b 0 +aorbnot 1.8 +1 1.07908e-11 +lnot 1.8 +2 1.4123 +qnot 1.25451 +3 0.372541 +8 0.0024126 +9 1.67983e-06 +vb#branch 1.03325e-15 +va#branch 1.02861e-15 +vdd#branch -8.79668e-05 + + Reference value : 7.68000e-10 Reference value : 2.51571e-08 Reference value : 4.06091e-08 +No. of Data Rows : 151 +** One-Bit Comparator (Tran): Benchmarking Implementation of BSIM4.0.0 by Weidong Liu 5/16/2000. +-------------------------------------------------------------------------------- +Index time a b v(9) +-------------------------------------------------------------------------------- +0 0.000000e+00 0.000000e+00 0.000000e+00 1.679830e-06 +1 3.000000e-12 0.000000e+00 0.000000e+00 1.679830e-06 +2 6.000000e-12 0.000000e+00 0.000000e+00 1.679830e-06 +3 1.200000e-11 0.000000e+00 0.000000e+00 1.679830e-06 +4 2.400000e-11 0.000000e+00 0.000000e+00 1.679830e-06 +5 4.800000e-11 0.000000e+00 0.000000e+00 1.679830e-06 +6 9.600000e-11 0.000000e+00 0.000000e+00 1.679830e-06 +7 1.920000e-10 0.000000e+00 0.000000e+00 1.679830e-06 +8 3.840000e-10 0.000000e+00 0.000000e+00 1.679830e-06 +9 7.680000e-10 0.000000e+00 0.000000e+00 1.679830e-06 +10 1.536000e-09 0.000000e+00 0.000000e+00 1.679831e-06 +11 2.536000e-09 0.000000e+00 0.000000e+00 1.679831e-06 +12 3.536000e-09 0.000000e+00 0.000000e+00 1.679831e-06 +13 4.536000e-09 0.000000e+00 0.000000e+00 1.679831e-06 +14 5.536000e-09 0.000000e+00 0.000000e+00 1.679831e-06 +15 6.536000e-09 0.000000e+00 0.000000e+00 1.679830e-06 +16 7.536000e-09 0.000000e+00 0.000000e+00 1.679830e-06 +17 8.536000e-09 0.000000e+00 0.000000e+00 1.679831e-06 +18 9.536000e-09 0.000000e+00 0.000000e+00 1.679831e-06 +19 1.000000e-08 0.000000e+00 0.000000e+00 1.679830e-06 +20 1.001000e-08 1.800000e-01 0.000000e+00 4.182287e-06 +21 1.003000e-08 5.400000e-01 0.000000e+00 8.346524e-06 +22 1.005585e-08 1.005329e+00 0.000000e+00 2.427311e-05 +23 1.007961e-08 1.432921e+00 0.000000e+00 1.950225e-05 +24 1.010000e-08 1.800000e+00 0.000000e+00 1.030377e-05 +25 1.010298e-08 1.800000e+00 0.000000e+00 1.910133e-06 +26 1.010895e-08 1.800000e+00 0.000000e+00 -8.825250e-06 +27 1.012087e-08 1.800000e+00 0.000000e+00 -2.406138e-05 +28 1.014473e-08 1.800000e+00 0.000000e+00 -4.090862e-05 +29 1.019244e-08 1.800000e+00 0.000000e+00 1.086461e-03 +30 1.025261e-08 1.800000e+00 0.000000e+00 2.145156e-03 +31 1.031823e-08 1.800000e+00 0.000000e+00 -2.748803e-03 +32 1.042313e-08 1.800000e+00 0.000000e+00 -1.448746e-02 +33 1.058343e-08 1.800000e+00 0.000000e+00 -2.690455e-02 +34 1.075348e-08 1.800000e+00 0.000000e+00 -3.099896e-02 +35 1.096575e-08 1.800000e+00 0.000000e+00 -3.050495e-02 +36 1.115208e-08 1.800000e+00 0.000000e+00 -2.939290e-02 +37 1.136020e-08 1.800000e+00 0.000000e+00 -3.115804e-02 +38 1.170205e-08 1.800000e+00 0.000000e+00 -1.840994e-02 +39 1.218097e-08 1.800000e+00 0.000000e+00 9.704631e-02 +40 1.283702e-08 1.800000e+00 0.000000e+00 7.630072e-01 +41 1.346996e-08 1.800000e+00 0.000000e+00 1.626938e+00 +42 1.390160e-08 1.800000e+00 0.000000e+00 1.768010e+00 +43 1.437264e-08 1.800000e+00 0.000000e+00 1.765331e+00 +44 1.488695e-08 1.800000e+00 0.000000e+00 1.789447e+00 +45 1.543201e-08 1.800000e+00 0.000000e+00 1.790618e+00 +46 1.643201e-08 1.800000e+00 0.000000e+00 1.798089e+00 +47 1.743201e-08 1.800000e+00 0.000000e+00 1.797511e+00 +48 1.843201e-08 1.800000e+00 0.000000e+00 1.799823e+00 +49 1.943201e-08 1.800000e+00 0.000000e+00 1.799032e+00 +50 2.043201e-08 1.800000e+00 0.000000e+00 1.800033e+00 +51 2.143201e-08 1.800000e+00 0.000000e+00 1.799491e+00 +52 2.243201e-08 1.800000e+00 0.000000e+00 1.799982e+00 +53 2.343201e-08 1.800000e+00 0.000000e+00 1.799680e+00 +54 2.443201e-08 1.800000e+00 0.000000e+00 1.799920e+00 + +Index time a b v(9) +-------------------------------------------------------------------------------- +55 2.510000e-08 1.800000e+00 0.000000e+00 1.799767e+00 +56 2.511000e-08 1.620000e+00 0.000000e+00 1.799454e+00 +57 2.513000e-08 1.260000e+00 0.000000e+00 1.798084e+00 +58 2.515711e-08 7.720510e-01 0.000000e+00 1.794336e+00 +59 2.518215e-08 3.213575e-01 0.000000e+00 1.790316e+00 +60 2.520000e-08 2.745200e-14 0.000000e+00 1.788375e+00 +61 2.520314e-08 0.000000e+00 0.000000e+00 1.788193e+00 +62 2.520941e-08 0.000000e+00 0.000000e+00 1.787922e+00 +63 2.522195e-08 0.000000e+00 0.000000e+00 1.787872e+00 +64 2.524703e-08 0.000000e+00 0.000000e+00 1.789245e+00 +65 2.528205e-08 0.000000e+00 0.000000e+00 1.793054e+00 +66 2.532493e-08 0.000000e+00 0.000000e+00 1.798740e+00 +67 2.538345e-08 0.000000e+00 0.000000e+00 1.806752e+00 +68 2.545434e-08 0.000000e+00 0.000000e+00 1.813805e+00 +69 2.555352e-08 0.000000e+00 0.000000e+00 1.819445e+00 +70 2.569472e-08 0.000000e+00 0.000000e+00 1.822536e+00 +71 2.586264e-08 0.000000e+00 0.000000e+00 1.820818e+00 +72 2.608660e-08 0.000000e+00 0.000000e+00 1.808522e+00 +73 2.639079e-08 0.000000e+00 0.000000e+00 1.776965e+00 +74 2.698379e-08 0.000000e+00 0.000000e+00 1.580809e+00 +75 2.764404e-08 0.000000e+00 0.000000e+00 4.658885e-01 +76 2.813844e-08 0.000000e+00 0.000000e+00 -1.235803e-03 +77 2.855842e-08 0.000000e+00 0.000000e+00 2.119098e-02 +78 2.898513e-08 0.000000e+00 0.000000e+00 9.166811e-03 +79 2.940707e-08 0.000000e+00 0.000000e+00 8.025941e-03 +80 3.025093e-08 0.000000e+00 0.000000e+00 3.433417e-03 +81 3.125093e-08 0.000000e+00 0.000000e+00 1.677095e-03 +82 3.225093e-08 0.000000e+00 0.000000e+00 5.419305e-04 +83 3.325093e-08 0.000000e+00 0.000000e+00 3.133362e-04 +84 3.425093e-08 0.000000e+00 0.000000e+00 9.220598e-05 +85 3.525093e-08 0.000000e+00 0.000000e+00 5.929611e-05 +86 3.625093e-08 0.000000e+00 0.000000e+00 3.219898e-05 +87 3.725093e-08 0.000000e+00 0.000000e+00 3.790398e-06 +88 3.825093e-08 0.000000e+00 0.000000e+00 2.725496e-05 +89 3.925093e-08 0.000000e+00 0.000000e+00 -1.211300e-05 +90 4.000000e-08 0.000000e+00 0.000000e+00 2.937370e-05 +91 4.001000e-08 1.800000e-01 0.000000e+00 -6.031414e-05 +92 4.003000e-08 5.400000e-01 0.000000e+00 -1.457585e-04 +93 4.005586e-08 1.005400e+00 0.000000e+00 -1.505408e-04 +94 4.007961e-08 1.433059e+00 0.000000e+00 -1.067201e-04 +95 4.010000e-08 1.800000e+00 0.000000e+00 -8.145477e-05 +96 4.010298e-08 1.800000e+00 0.000000e+00 -8.567019e-05 +97 4.010894e-08 1.800000e+00 0.000000e+00 -8.582685e-05 +98 4.012087e-08 1.800000e+00 0.000000e+00 -5.843944e-05 +99 4.014471e-08 1.800000e+00 0.000000e+00 8.825277e-04 +100 4.019241e-08 1.800000e+00 0.000000e+00 2.500492e-03 +101 4.025457e-08 1.800000e+00 0.000000e+00 -5.847753e-04 +102 4.031954e-08 1.800000e+00 0.000000e+00 -7.817596e-03 +103 4.044948e-08 1.800000e+00 0.000000e+00 -2.097910e-02 +104 4.060914e-08 1.800000e+00 0.000000e+00 -2.934132e-02 +105 4.082160e-08 1.800000e+00 0.000000e+00 -3.113064e-02 +106 4.102427e-08 1.800000e+00 0.000000e+00 -2.979997e-02 +107 4.122082e-08 1.800000e+00 0.000000e+00 -2.976696e-02 +108 4.143797e-08 1.800000e+00 0.000000e+00 -3.208480e-02 +109 4.178774e-08 1.800000e+00 0.000000e+00 1.800004e-03 +110 4.240598e-08 1.800000e+00 0.000000e+00 2.311151e-01 +111 4.329146e-08 1.800000e+00 0.000000e+00 1.503793e+00 +112 4.388026e-08 1.800000e+00 0.000000e+00 1.792673e+00 + +Index time a b v(9) +-------------------------------------------------------------------------------- +113 4.445049e-08 1.800000e+00 0.000000e+00 1.757071e+00 +114 4.494088e-08 1.800000e+00 0.000000e+00 1.796437e+00 +115 4.546172e-08 1.800000e+00 0.000000e+00 1.788489e+00 +116 4.624811e-08 1.800000e+00 0.000000e+00 1.799267e+00 +117 4.721336e-08 1.800000e+00 0.000000e+00 1.796198e+00 +118 4.821336e-08 1.800000e+00 0.000000e+00 1.800532e+00 +119 4.921336e-08 1.800000e+00 0.000000e+00 1.798387e+00 +120 5.021336e-08 1.800000e+00 0.000000e+00 1.800454e+00 +121 5.121336e-08 1.800000e+00 0.000000e+00 1.799139e+00 +122 5.221336e-08 1.800000e+00 0.000000e+00 1.800220e+00 +123 5.321336e-08 1.800000e+00 0.000000e+00 1.799483e+00 +124 5.421336e-08 1.800000e+00 0.000000e+00 1.800050e+00 +125 5.510000e-08 1.800000e+00 0.000000e+00 1.799661e+00 +126 5.511000e-08 1.620000e+00 0.000000e+00 1.799350e+00 +127 5.513000e-08 1.260000e+00 0.000000e+00 1.798004e+00 +128 5.515711e-08 7.720271e-01 0.000000e+00 1.794281e+00 +129 5.518215e-08 3.213096e-01 0.000000e+00 1.790276e+00 +130 5.520000e-08 2.745200e-14 0.000000e+00 1.788344e+00 +131 5.520314e-08 0.000000e+00 0.000000e+00 1.788164e+00 +132 5.520941e-08 0.000000e+00 0.000000e+00 1.787896e+00 +133 5.522195e-08 0.000000e+00 0.000000e+00 1.787850e+00 +134 5.524703e-08 0.000000e+00 0.000000e+00 1.789230e+00 +135 5.528200e-08 0.000000e+00 0.000000e+00 1.793039e+00 +136 5.532505e-08 0.000000e+00 0.000000e+00 1.798750e+00 +137 5.538127e-08 0.000000e+00 0.000000e+00 1.806485e+00 +138 5.545307e-08 0.000000e+00 0.000000e+00 1.813706e+00 +139 5.555021e-08 0.000000e+00 0.000000e+00 1.819311e+00 +140 5.569176e-08 0.000000e+00 0.000000e+00 1.822516e+00 +141 5.585921e-08 0.000000e+00 0.000000e+00 1.820916e+00 +142 5.608326e-08 0.000000e+00 0.000000e+00 1.808790e+00 +143 5.638356e-08 0.000000e+00 0.000000e+00 1.777898e+00 +144 5.696863e-08 0.000000e+00 0.000000e+00 1.599189e+00 +145 5.763214e-08 0.000000e+00 0.000000e+00 4.857124e-01 +146 5.812795e-08 0.000000e+00 0.000000e+00 1.713690e-03 +147 5.854341e-08 0.000000e+00 0.000000e+00 2.058016e-02 +148 5.896677e-08 0.000000e+00 0.000000e+00 9.571945e-03 +149 5.938952e-08 0.000000e+00 0.000000e+00 8.069029e-03 +150 6.000000e-08 0.000000e+00 0.000000e+00 4.453081e-03 + +** One-Bit Comparator (Tran): Benchmarking Implementation of BSIM4.0.0 by Weidong Liu 5/16/2000. +-------------------------------------------------------------------------------- +Index time v(8) +-------------------------------------------------------------------------------- +0 0.000000e+00 2.412597e-03 +1 3.000000e-12 2.412597e-03 +2 6.000000e-12 2.412597e-03 +3 1.200000e-11 2.412597e-03 +4 2.400000e-11 2.412597e-03 +5 4.800000e-11 2.412597e-03 +6 9.600000e-11 2.412597e-03 +7 1.920000e-10 2.412597e-03 +8 3.840000e-10 2.412597e-03 +9 7.680000e-10 2.412597e-03 +10 1.536000e-09 2.412597e-03 +11 2.536000e-09 2.412597e-03 +12 3.536000e-09 2.412597e-03 +13 4.536000e-09 2.412597e-03 +14 5.536000e-09 2.412597e-03 +15 6.536000e-09 2.412597e-03 +16 7.536000e-09 2.412597e-03 +17 8.536000e-09 2.412597e-03 +18 9.536000e-09 2.412597e-03 +19 1.000000e-08 2.412597e-03 +20 1.001000e-08 2.412647e-03 +21 1.003000e-08 2.412570e-03 +22 1.005585e-08 2.412498e-03 +23 1.007961e-08 2.412679e-03 +24 1.010000e-08 2.412881e-03 +25 1.010298e-08 2.412876e-03 +26 1.010895e-08 2.412978e-03 +27 1.012087e-08 2.413042e-03 +28 1.014473e-08 2.412881e-03 +29 1.019244e-08 2.409219e-03 +30 1.025261e-08 2.428448e-03 +31 1.031823e-08 2.456834e-03 +32 1.042313e-08 2.306078e-03 +33 1.058343e-08 1.974098e-03 +34 1.075348e-08 2.100057e-03 +35 1.096575e-08 3.148715e-03 +36 1.115208e-08 4.519726e-03 +37 1.136020e-08 6.158601e-03 +38 1.170205e-08 8.565018e-03 +39 1.218097e-08 1.004791e-02 +40 1.283702e-08 1.007491e-02 +41 1.346996e-08 8.472598e-03 +42 1.390160e-08 6.619870e-03 +43 1.437264e-08 5.054428e-03 +44 1.488695e-08 3.783568e-03 +45 1.543201e-08 2.558173e-03 +46 1.643201e-08 8.712699e-04 +47 1.743201e-08 2.984190e-04 +48 1.843201e-08 9.777131e-05 +49 1.943201e-08 5.398885e-05 +50 2.043201e-08 2.440990e-05 +51 2.143201e-08 1.919079e-05 +52 2.243201e-08 9.582300e-06 +53 2.343201e-08 1.001398e-05 +54 2.443201e-08 6.136671e-06 + +Index time v(8) +-------------------------------------------------------------------------------- +55 2.510000e-08 6.534327e-06 +56 2.511000e-08 6.912850e-06 +57 2.513000e-08 8.838157e-06 +58 2.515711e-08 1.378484e-05 +59 2.518215e-08 1.834463e-05 +60 2.520000e-08 1.989936e-05 +61 2.520314e-08 1.996154e-05 +62 2.520941e-08 1.993172e-05 +63 2.522195e-08 1.927731e-05 +64 2.524703e-08 1.633750e-05 +65 2.528205e-08 1.049157e-05 +66 2.532493e-08 2.824180e-06 +67 2.538345e-08 -7.447706e-06 +68 2.545434e-08 -1.696973e-05 +69 2.555352e-08 -2.401984e-05 +70 2.569472e-08 -1.607553e-05 +71 2.586264e-08 2.193295e-05 +72 2.608660e-08 1.292451e-04 +73 2.639079e-08 -1.434376e-04 +74 2.698379e-08 -5.450108e-03 +75 2.764404e-08 -9.908297e-03 +76 2.813844e-08 -9.360216e-03 +77 2.855842e-08 -8.272891e-03 +78 2.898513e-08 -6.935492e-03 +79 2.940707e-08 -5.875185e-03 +80 3.025093e-08 -3.651437e-03 +81 3.125093e-08 -1.797428e-03 +82 3.225093e-08 -4.370291e-05 +83 3.325093e-08 9.786208e-04 +84 3.425093e-08 1.698680e-03 +85 3.525093e-08 2.019681e-03 +86 3.625093e-08 2.226638e-03 +87 3.725093e-08 2.305560e-03 +88 3.825093e-08 2.360087e-03 +89 3.925093e-08 2.377758e-03 +90 4.000000e-08 2.390071e-03 +91 4.001000e-08 2.390562e-03 +92 4.003000e-08 2.390655e-03 +93 4.005586e-08 2.389428e-03 +94 4.007961e-08 2.388219e-03 +95 4.010000e-08 2.387854e-03 +96 4.010298e-08 2.387801e-03 +97 4.010894e-08 2.387829e-03 +98 4.012087e-08 2.387658e-03 +99 4.014471e-08 2.381538e-03 +100 4.019241e-08 2.394316e-03 +101 4.025457e-08 2.437962e-03 +102 4.031954e-08 2.400836e-03 +103 4.044948e-08 2.120264e-03 +104 4.060914e-08 1.921432e-03 +105 4.082160e-08 2.529084e-03 +106 4.102427e-08 3.850799e-03 +107 4.122082e-08 5.384841e-03 +108 4.143797e-08 7.069169e-03 +109 4.178774e-08 9.181009e-03 +110 4.240598e-08 1.019927e-02 +111 4.329146e-08 9.104005e-03 +112 4.388026e-08 6.688135e-03 + +Index time v(8) +-------------------------------------------------------------------------------- +113 4.445049e-08 4.663633e-03 +114 4.494088e-08 3.530351e-03 +115 4.546172e-08 2.434409e-03 +116 4.624811e-08 1.038372e-03 +117 4.721336e-08 3.855462e-04 +118 4.821336e-08 1.103526e-04 +119 4.921336e-08 6.727117e-05 +120 5.021336e-08 2.224420e-05 +121 5.121336e-08 2.421863e-05 +122 5.221336e-08 9.183772e-06 +123 5.321336e-08 1.124641e-05 +124 5.421336e-08 5.743883e-06 +125 5.510000e-08 6.990089e-06 +126 5.511000e-08 7.226050e-06 +127 5.513000e-08 9.066564e-06 +128 5.515711e-08 1.391898e-05 +129 5.518215e-08 1.841461e-05 +130 5.520000e-08 1.993491e-05 +131 5.520314e-08 1.999239e-05 +132 5.520941e-08 1.995420e-05 +133 5.522195e-08 1.928616e-05 +134 5.524703e-08 1.632792e-05 +135 5.528200e-08 1.047476e-05 +136 5.532505e-08 2.774571e-06 +137 5.538127e-08 -7.146062e-06 +138 5.545307e-08 -1.685574e-05 +139 5.555021e-08 -2.395126e-05 +140 5.569176e-08 -1.654242e-05 +141 5.585921e-08 2.073581e-05 +142 5.608326e-08 1.266977e-04 +143 5.638356e-08 -1.101070e-04 +144 5.696863e-08 -5.303890e-03 +145 5.763214e-08 -9.877889e-03 +146 5.812795e-08 -9.385202e-03 +147 5.854341e-08 -8.315924e-03 +148 5.896677e-08 -6.989080e-03 +149 5.938952e-08 -5.925138e-03 +150 6.000000e-08 -4.226731e-03 + + + + diff --git a/tests/bsim4/gstage.cir b/tests/bsim4/gstage.cir new file mode 100644 index 000000000..cbbea4aa3 --- /dev/null +++ b/tests/bsim4/gstage.cir @@ -0,0 +1,15 @@ +** MOSFET Gain Stage (AC): Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +M1 3 2 0 0 N1 L=1u W=4u +Rsource 1 2 100k +Rload 3 vdd 25k + +Vdd vdd 0 1.8 +Vin 1 0 1.2 ac 0.1 + +.ac dec 10 100 1000Meg +.print ac vdb(3) + +.include modelcard.nmos + +.end diff --git a/tests/bsim4/gstage.out b/tests/bsim4/gstage.out new file mode 100644 index 000000000..dd1a61790 --- /dev/null +++ b/tests/bsim4/gstage.out @@ -0,0 +1,89 @@ + +No. of Data Rows : 71 + +Circuit: ** MOSFET Gain Stage (AC): Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +** MOSFET Gain Stage (AC): Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. +-------------------------------------------------------------------------------- +Index frequency db(v(3)) +-------------------------------------------------------------------------------- +0 1.000000e+02, 0.000000e+00 -3.738822e+01 +1 1.258925e+02, 0.000000e+00 -3.738822e+01 +2 1.584893e+02, 0.000000e+00 -3.738822e+01 +3 1.995262e+02, 0.000000e+00 -3.738822e+01 +4 2.511886e+02, 0.000000e+00 -3.738822e+01 +5 3.162278e+02, 0.000000e+00 -3.738822e+01 +6 3.981072e+02, 0.000000e+00 -3.738822e+01 +7 5.011872e+02, 0.000000e+00 -3.738822e+01 +8 6.309573e+02, 0.000000e+00 -3.738822e+01 +9 7.943282e+02, 0.000000e+00 -3.738822e+01 +10 1.000000e+03, 0.000000e+00 -3.738822e+01 +11 1.258925e+03, 0.000000e+00 -3.738822e+01 +12 1.584893e+03, 0.000000e+00 -3.738822e+01 +13 1.995262e+03, 0.000000e+00 -3.738822e+01 +14 2.511886e+03, 0.000000e+00 -3.738822e+01 +15 3.162278e+03, 0.000000e+00 -3.738822e+01 +16 3.981072e+03, 0.000000e+00 -3.738822e+01 +17 5.011872e+03, 0.000000e+00 -3.738822e+01 +18 6.309573e+03, 0.000000e+00 -3.738822e+01 +19 7.943282e+03, 0.000000e+00 -3.738822e+01 +20 1.000000e+04, 0.000000e+00 -3.738822e+01 +21 1.258925e+04, 0.000000e+00 -3.738822e+01 +22 1.584893e+04, 0.000000e+00 -3.738822e+01 +23 1.995262e+04, 0.000000e+00 -3.738822e+01 +24 2.511886e+04, 0.000000e+00 -3.738823e+01 +25 3.162278e+04, 0.000000e+00 -3.738823e+01 +26 3.981072e+04, 0.000000e+00 -3.738823e+01 +27 5.011872e+04, 0.000000e+00 -3.738823e+01 +28 6.309573e+04, 0.000000e+00 -3.738824e+01 +29 7.943282e+04, 0.000000e+00 -3.738825e+01 +30 1.000000e+05, 0.000000e+00 -3.738826e+01 +31 1.258925e+05, 0.000000e+00 -3.738828e+01 +32 1.584893e+05, 0.000000e+00 -3.738832e+01 +33 1.995262e+05, 0.000000e+00 -3.738837e+01 +34 2.511886e+05, 0.000000e+00 -3.738846e+01 +35 3.162278e+05, 0.000000e+00 -3.738859e+01 +36 3.981072e+05, 0.000000e+00 -3.738881e+01 +37 5.011872e+05, 0.000000e+00 -3.738915e+01 +38 6.309573e+05, 0.000000e+00 -3.738969e+01 +39 7.943282e+05, 0.000000e+00 -3.739055e+01 +40 1.000000e+06, 0.000000e+00 -3.739191e+01 +41 1.258925e+06, 0.000000e+00 -3.739407e+01 +42 1.584893e+06, 0.000000e+00 -3.739748e+01 +43 1.995262e+06, 0.000000e+00 -3.740289e+01 +44 2.511886e+06, 0.000000e+00 -3.741144e+01 +45 3.162278e+06, 0.000000e+00 -3.742496e+01 +46 3.981072e+06, 0.000000e+00 -3.744630e+01 +47 5.011872e+06, 0.000000e+00 -3.747991e+01 +48 6.309573e+06, 0.000000e+00 -3.753265e+01 +49 7.943282e+06, 0.000000e+00 -3.761493e+01 +50 1.000000e+07, 0.000000e+00 -3.774220e+01 +51 1.258925e+07, 0.000000e+00 -3.793649e+01 +52 1.584893e+07, 0.000000e+00 -3.822748e+01 +53 1.995262e+07, 0.000000e+00 -3.865171e+01 +54 2.511886e+07, 0.000000e+00 -3.924839e+01 + +Index frequency db(v(3)) +-------------------------------------------------------------------------------- +55 3.162278e+07, 0.000000e+00 -4.005092e+01 +56 3.981072e+07, 0.000000e+00 -4.107660e+01 +57 5.011872e+07, 0.000000e+00 -4.231969e+01 +58 6.309573e+07, 0.000000e+00 -4.375230e+01 +59 7.943282e+07, 0.000000e+00 -4.533216e+01 +60 1.000000e+08, 0.000000e+00 -4.701175e+01 +61 1.258925e+08, 0.000000e+00 -4.874413e+01 +62 1.584893e+08, 0.000000e+00 -5.048434e+01 +63 1.995262e+08, 0.000000e+00 -5.218800e+01 +64 2.511886e+08, 0.000000e+00 -5.380960e+01 +65 3.162278e+08, 0.000000e+00 -5.530297e+01 +66 3.981072e+08, 0.000000e+00 -5.662616e+01 +67 5.011872e+08, 0.000000e+00 -5.775040e+01 +68 6.309573e+08, 0.000000e+00 -5.866973e+01 +69 7.943282e+08, 0.000000e+00 -5.940544e+01 +70 1.000000e+09, 0.000000e+00 -6.000259e+01 + + + + diff --git a/tests/bsim4/oneshot.cir b/tests/bsim4/oneshot.cir new file mode 100644 index 000000000..6de60d0aa --- /dev/null +++ b/tests/bsim4/oneshot.cir @@ -0,0 +1,38 @@ +** One-Shot Trigger (Tran): Benchmarking Implementation of BSIM4.0.0 by Weidong Liu 5/16/2000. + +Md1 4 in Vdd Vdd P1 W=3.6u L=1.2u +Md2 4 in 0 0 N1 W=1.8u L=1.2u +c4 4 0 30f +Md3 A 4 Vdd Vdd P1 W=3.6u L=1.2u +Md4 A 4 0 0 N1 W=1.8u L=1.2u +ca a 0 30f + +M1 Anot A Vdd Vdd P1 W=3.6u L=1.2u +M2 Anot A 0 0 N1 W=1.8u L=1.2u + +M3 Bnot in Vdd Vdd P1 W=3.6u L=1.2u +M4 Bnot in 0 0 N1 W=1.8u L=1.2u + +M5 AorBnot 0 Vdd Vdd P1 W=1.8u L=3.6u +M6 AorBnot in 1 0 N1 W=1.8u L=1.2u +M7 1 Anot 0 0 N1 W=1.8u L=1.2u + +M8 Lnot 0 Vdd Vdd P1 W=1.8u L=3.6u +M9 Lnot Bnot 2 0 N1 W=1.8u L=1.2u +M10 2 A 0 0 N1 W=1.8u L=1.2u + +M11 out 0 Vdd Vdd P1 W=3.6u L=3.6u +M12 out AorBnot 3 0 N1 W=1.8u L=1.2u +M13 3 Lnot 0 0 N1 W=1.8u L=1.2u + +Vcc vdd 0 1.8 +vin in 0 pulse 0 1.8 1ns .1ns .1ns .8ns 5ns + +.include modelcard.nmos +.include modelcard.pmos + +.tran 1ns 10ns +.print tran in out +.option post + +.end diff --git a/tests/bsim4/oneshot.out b/tests/bsim4/oneshot.out new file mode 100644 index 000000000..d87737166 --- /dev/null +++ b/tests/bsim4/oneshot.out @@ -0,0 +1,164 @@ +Warning: vin: no DC value, transient time 0 value used + +Circuit: ** One-Shot Trigger (Tran): Benchmarking Implementation of BSIM4.0.0 by Weidong Liu 5/16/2000. + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. + +Initial Transient Solution +-------------------------- + +Node Voltage +---- ------- +4 1.8 +in 0 +vdd 1.8 +a 1.67982e-06 +anot 1.8 +bnot 1.8 +aorbnot 1.8 +1 1.07908e-11 +lnot 1.8 +2 1.41228 +out 1.25451 +3 0.372541 +vin#branch 2.05443e-15 +vcc#branch -8.74236e-05 + + Reference value : 4.56000e-10 Reference value : 5.84544e-09 +No. of Data Rows : 108 +** One-Shot Trigger (Tran): Benchmarking Implementation of BSIM4.0.0 by Weidong Liu 5/16/2000. +-------------------------------------------------------------------------------- +Index time in out +-------------------------------------------------------------------------------- +0 0.000000e+00 0.000000e+00 1.254513e+00 +1 5.000000e-13 0.000000e+00 1.254513e+00 +2 1.000000e-12 0.000000e+00 1.254513e+00 +3 2.000000e-12 0.000000e+00 1.254513e+00 +4 4.000000e-12 0.000000e+00 1.254513e+00 +5 8.000000e-12 0.000000e+00 1.254513e+00 +6 1.600000e-11 0.000000e+00 1.254513e+00 +7 3.200000e-11 0.000000e+00 1.254513e+00 +8 6.400000e-11 0.000000e+00 1.254513e+00 +9 1.280000e-10 0.000000e+00 1.254513e+00 +10 2.560000e-10 0.000000e+00 1.254513e+00 +11 4.560000e-10 0.000000e+00 1.254513e+00 +12 6.560000e-10 0.000000e+00 1.254513e+00 +13 8.560000e-10 0.000000e+00 1.254513e+00 +14 1.000000e-09 0.000000e+00 1.254513e+00 +15 1.010000e-09 1.800000e-01 1.254829e+00 +16 1.030000e-09 5.400000e-01 1.255383e+00 +17 1.055806e-09 1.004512e+00 1.257084e+00 +18 1.079503e-09 1.431059e+00 1.256617e+00 +19 1.100000e-09 1.800000e+00 1.254692e+00 +20 1.102152e-09 1.800000e+00 1.254125e+00 +21 1.106457e-09 1.800000e+00 1.253036e+00 +22 1.115067e-09 1.800000e+00 1.251065e+00 +23 1.132287e-09 1.800000e+00 1.247941e+00 +24 1.165462e-09 1.800000e+00 1.244997e+00 +25 1.221146e-09 1.800000e+00 1.246579e+00 +26 1.290365e-09 1.800000e+00 1.257326e+00 +27 1.365650e-09 1.800000e+00 1.276733e+00 +28 1.516219e-09 1.800000e+00 1.328434e+00 +29 1.716219e-09 1.800000e+00 1.408256e+00 +30 1.900000e-09 1.800000e+00 1.482869e+00 +31 1.910000e-09 1.620000e+00 1.485543e+00 +32 1.930000e-09 1.260000e+00 1.491956e+00 +33 1.956704e-09 7.793359e-01 1.503197e+00 +34 1.981501e-09 3.329775e-01 1.516605e+00 +35 2.000000e-09 0.000000e+00 1.526449e+00 +36 2.003074e-09 0.000000e+00 1.528152e+00 +37 2.009223e-09 0.000000e+00 1.531472e+00 +38 2.021521e-09 0.000000e+00 1.537730e+00 +39 2.046117e-09 0.000000e+00 1.548829e+00 +40 2.075434e-09 0.000000e+00 1.559815e+00 +41 2.129419e-09 0.000000e+00 1.574663e+00 +42 2.197215e-09 0.000000e+00 1.585278e+00 +43 2.269349e-09 0.000000e+00 1.588917e+00 +44 2.381420e-09 0.000000e+00 1.583582e+00 +45 2.493296e-09 0.000000e+00 1.569198e+00 +46 2.645445e-09 0.000000e+00 1.541841e+00 +47 2.845445e-09 0.000000e+00 1.500376e+00 +48 3.045445e-09 0.000000e+00 1.458739e+00 +49 3.245445e-09 0.000000e+00 1.420516e+00 +50 3.445445e-09 0.000000e+00 1.387555e+00 +51 3.645445e-09 0.000000e+00 1.359951e+00 +52 3.845445e-09 0.000000e+00 1.336965e+00 +53 4.045445e-09 0.000000e+00 1.318289e+00 +54 4.245445e-09 0.000000e+00 1.303384e+00 + +Index time in out +-------------------------------------------------------------------------------- +55 4.445445e-09 0.000000e+00 1.291662e+00 +56 4.645445e-09 0.000000e+00 1.282557e+00 +57 4.845445e-09 0.000000e+00 1.275558e+00 +58 5.045445e-09 0.000000e+00 1.270226e+00 +59 5.245445e-09 0.000000e+00 1.266194e+00 +60 5.445445e-09 0.000000e+00 1.263165e+00 +61 5.645445e-09 0.000000e+00 1.260900e+00 +62 5.845445e-09 0.000000e+00 1.259215e+00 +63 6.000000e-09 0.000000e+00 1.258220e+00 +64 6.010000e-09 1.800000e-01 1.258472e+00 +65 6.030000e-09 5.400000e-01 1.258917e+00 +66 6.055806e-09 1.004512e+00 1.260480e+00 +67 6.079504e-09 1.431068e+00 1.259880e+00 +68 6.100000e-09 1.800000e+00 1.257851e+00 +69 6.102151e-09 1.800000e+00 1.257274e+00 +70 6.106454e-09 1.800000e+00 1.256168e+00 +71 6.115060e-09 1.800000e+00 1.254162e+00 +72 6.132272e-09 1.800000e+00 1.250968e+00 +73 6.164959e-09 1.800000e+00 1.247918e+00 +74 6.219998e-09 1.800000e+00 1.249157e+00 +75 6.289111e-09 1.800000e+00 1.259477e+00 +76 6.363799e-09 1.800000e+00 1.278317e+00 +77 6.513176e-09 1.800000e+00 1.328908e+00 +78 6.713176e-09 1.800000e+00 1.408134e+00 +79 6.900000e-09 1.800000e+00 1.483666e+00 +80 6.910000e-09 1.620000e+00 1.486327e+00 +81 6.930000e-09 1.260000e+00 1.492713e+00 +82 6.956704e-09 7.793200e-01 1.503921e+00 +83 6.981503e-09 3.329384e-01 1.517301e+00 +84 7.000000e-09 6.979335e-15 1.527124e+00 +85 7.003074e-09 0.000000e+00 1.528823e+00 +86 7.009223e-09 0.000000e+00 1.532137e+00 +87 7.021521e-09 0.000000e+00 1.538383e+00 +88 7.046117e-09 0.000000e+00 1.549458e+00 +89 7.075505e-09 0.000000e+00 1.560441e+00 +90 7.129284e-09 0.000000e+00 1.575188e+00 +91 7.197041e-09 0.000000e+00 1.585759e+00 +92 7.269193e-09 0.000000e+00 1.589364e+00 +93 7.381199e-09 0.000000e+00 1.583980e+00 +94 7.492987e-09 0.000000e+00 1.569565e+00 +95 7.644826e-09 0.000000e+00 1.542217e+00 +96 7.844826e-09 0.000000e+00 1.500697e+00 +97 8.044826e-09 0.000000e+00 1.459006e+00 +98 8.244826e-09 0.000000e+00 1.420734e+00 +99 8.444826e-09 0.000000e+00 1.387731e+00 +100 8.644826e-09 0.000000e+00 1.360092e+00 +101 8.844826e-09 0.000000e+00 1.337075e+00 +102 9.044826e-09 0.000000e+00 1.318375e+00 +103 9.244826e-09 0.000000e+00 1.303450e+00 +104 9.444826e-09 0.000000e+00 1.291712e+00 +105 9.644826e-09 0.000000e+00 1.282595e+00 +106 9.844826e-09 0.000000e+00 1.275587e+00 +107 1.000000e-08 0.000000e+00 1.271324e+00 + + + + diff --git a/tests/bsim4/opamp.cir b/tests/bsim4/opamp.cir new file mode 100644 index 000000000..d8b982447 --- /dev/null +++ b/tests/bsim4/opamp.cir @@ -0,0 +1,29 @@ +** Operational Amplifier (AC): Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +M1 bias1 1 cm cm N1 L=1u W=10u +M2 bias2 in2 cm cm N1 L=1u W=10u +M3 vdd bias1 bias1 vdd P1 L=1u W=2u +M4 bias2 bias1 vdd vdd P1 L=1u W=2u + +m5 cm bias vss vss N1 L=1u W=2u +mbias bias bias vss vss N1 L=1u W=2u +rbias 0 bias 195k + +m6 8 bias vss vss N1 L=1u W=2u +m7 8 bias2 vdd out N1 L=1u W=2u + +Cfb bias2 8 2p + +Vid 1 c 0 ac 0.1 +eid in2 c 1 c -1 +vic c 0 dc 0 +vss vss 0 -1.8 +Vdd vdd 0 1.8 + +.ac dec 10 100 100Meg +.print ac vdb(8) + +.include modelcard.nmos +.include modelcard.pmos + +.end diff --git a/tests/bsim4/opamp.out b/tests/bsim4/opamp.out new file mode 100644 index 000000000..8176f1959 --- /dev/null +++ b/tests/bsim4/opamp.out @@ -0,0 +1,86 @@ + +No. of Data Rows : 61 + +Circuit: ** Operational Amplifier (AC): Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +Warning: This model is BSIM4.2.1; you specified a wrong version number. +** Operational Amplifier (AC): Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. +-------------------------------------------------------------------------------- +Index frequency db(v(8)) +-------------------------------------------------------------------------------- +0 1.000000e+02, 0.000000e+00 3.083153e+01 +1 1.258925e+02, 0.000000e+00 3.083139e+01 +2 1.584893e+02, 0.000000e+00 3.083118e+01 +3 1.995262e+02, 0.000000e+00 3.083085e+01 +4 2.511886e+02, 0.000000e+00 3.083035e+01 +5 3.162278e+02, 0.000000e+00 3.082958e+01 +6 3.981072e+02, 0.000000e+00 3.082844e+01 +7 5.011872e+02, 0.000000e+00 3.082680e+01 +8 6.309573e+02, 0.000000e+00 3.082456e+01 +9 7.943282e+02, 0.000000e+00 3.082170e+01 +10 1.000000e+03, 0.000000e+00 3.081831e+01 +11 1.258925e+03, 0.000000e+00 3.081468e+01 +12 1.584893e+03, 0.000000e+00 3.081115e+01 +13 1.995262e+03, 0.000000e+00 3.080803e+01 +14 2.511886e+03, 0.000000e+00 3.080545e+01 +15 3.162278e+03, 0.000000e+00 3.080338e+01 +16 3.981072e+03, 0.000000e+00 3.080168e+01 +17 5.011872e+03, 0.000000e+00 3.080013e+01 +18 6.309573e+03, 0.000000e+00 3.079846e+01 +19 7.943282e+03, 0.000000e+00 3.079635e+01 +20 1.000000e+04, 0.000000e+00 3.079336e+01 +21 1.258925e+04, 0.000000e+00 3.078884e+01 +22 1.584893e+04, 0.000000e+00 3.078184e+01 +23 1.995262e+04, 0.000000e+00 3.077085e+01 +24 2.511886e+04, 0.000000e+00 3.075356e+01 +25 3.162278e+04, 0.000000e+00 3.072632e+01 +26 3.981072e+04, 0.000000e+00 3.068352e+01 +27 5.011872e+04, 0.000000e+00 3.061655e+01 +28 6.309573e+04, 0.000000e+00 3.051250e+01 +29 7.943282e+04, 0.000000e+00 3.035255e+01 +30 1.000000e+05, 0.000000e+00 3.011055e+01 +31 1.258925e+05, 0.000000e+00 2.975269e+01 +32 1.584893e+05, 0.000000e+00 2.923989e+01 +33 1.995262e+05, 0.000000e+00 2.853412e+01 +34 2.511886e+05, 0.000000e+00 2.760831e+01 +35 3.162278e+05, 0.000000e+00 2.645542e+01 +36 3.981072e+05, 0.000000e+00 2.509123e+01 +37 5.011872e+05, 0.000000e+00 2.354887e+01 +38 6.309573e+05, 0.000000e+00 2.186899e+01 +39 7.943282e+05, 0.000000e+00 2.009113e+01 +40 1.000000e+06, 0.000000e+00 1.824924e+01 +41 1.258925e+06, 0.000000e+00 1.637106e+01 +42 1.584893e+06, 0.000000e+00 1.447981e+01 +43 1.995262e+06, 0.000000e+00 1.259683e+01 +44 2.511886e+06, 0.000000e+00 1.074451e+01 +45 3.162278e+06, 0.000000e+00 8.948878e+00 +46 3.981072e+06, 0.000000e+00 7.241238e+00 +47 5.011872e+06, 0.000000e+00 5.657491e+00 +48 6.309573e+06, 0.000000e+00 4.233533e+00 +49 7.943282e+06, 0.000000e+00 2.996131e+00 +50 1.000000e+07, 0.000000e+00 1.951715e+00 +51 1.258925e+07, 0.000000e+00 1.078641e+00 +52 1.584893e+07, 0.000000e+00 3.275464e-01 +53 1.995262e+07, 0.000000e+00 -3.706484e-01 +54 2.511886e+07, 0.000000e+00 -1.093132e+00 + +Index frequency db(v(8)) +-------------------------------------------------------------------------------- +55 3.162278e+07, 0.000000e+00 -1.913009e+00 +56 3.981072e+07, 0.000000e+00 -2.887719e+00 +57 5.011872e+07, 0.000000e+00 -4.050661e+00 +58 6.309573e+07, 0.000000e+00 -5.411067e+00 +59 7.943282e+07, 0.000000e+00 -6.965497e+00 +60 1.000000e+08, 0.000000e+00 -8.717244e+00 + + + + diff --git a/tests/bsim4/test1.cir b/tests/bsim4/test1.cir new file mode 100644 index 000000000..a3d6b65bc --- /dev/null +++ b/tests/bsim4/test1.cir @@ -0,0 +1,13 @@ +** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +** Circuit Description ** +m1 2 1 0 0 n1 L=0.13u W=10.0u rgeoMod=1 +vgs 1 0 1.8 +vds 2 0 1.8 + +.dc vds 0 1.8 0.05 vgs 0.6 1.8 0.3 + +.print dc i(vds) + +.include modelcard.nmos +.end diff --git a/tests/bsim4/test1.out b/tests/bsim4/test1.out new file mode 100644 index 000000000..89b592e3d --- /dev/null +++ b/tests/bsim4/test1.out @@ -0,0 +1,209 @@ + +No. of Data Rows : 185 + +Circuit: ** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. +-------------------------------------------------------------------------------- +Index v-sweep vds#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 1.314482e-17 +1 5.000000e-02 -1.520320e-05 +2 1.000000e-01 -2.028107e-05 +3 1.500000e-01 -2.326589e-05 +4 2.000000e-01 -2.600640e-05 +5 2.500000e-01 -2.874121e-05 +6 3.000000e-01 -3.159943e-05 +7 3.500000e-01 -3.452233e-05 +8 4.000000e-01 -3.754211e-05 +9 4.500000e-01 -4.066277e-05 +10 5.000000e-01 -4.388716e-05 +11 5.500000e-01 -4.721758e-05 +12 6.000000e-01 -5.065609e-05 +13 6.500000e-01 -5.420460e-05 +14 7.000000e-01 -5.780873e-05 +15 7.500000e-01 -6.158181e-05 +16 8.000000e-01 -6.547025e-05 +17 8.500000e-01 -6.947576e-05 +18 9.000000e-01 -7.360001e-05 +19 9.500000e-01 -7.784467e-05 +20 1.000000e+00 -8.221136e-05 +21 1.050000e+00 -8.670171e-05 +22 1.100000e+00 -9.131731e-05 +23 1.150000e+00 -9.605973e-05 +24 1.200000e+00 -1.009306e-04 +25 1.250000e+00 -1.059315e-04 +26 1.300000e+00 -1.110646e-04 +27 1.350000e+00 -1.163323e-04 +28 1.400000e+00 -1.217388e-04 +29 1.450000e+00 -1.272914e-04 +30 1.500000e+00 -1.330036e-04 +31 1.550000e+00 -1.389002e-04 +32 1.600000e+00 -1.450260e-04 +33 1.650000e+00 -1.516416e-04 +34 1.700000e+00 -1.585978e-04 +35 1.750000e+00 -1.662590e-04 +36 1.800000e+00 -1.749903e-04 +37 0.000000e+00 3.929327e-17 +38 5.000000e-02 -2.571957e-04 +39 1.000000e-01 -4.656110e-04 +40 1.500000e-01 -6.285928e-04 +41 2.000000e-01 -7.497574e-04 +42 2.500000e-01 -8.342322e-04 +43 3.000000e-01 -8.907105e-04 +44 3.500000e-01 -9.304113e-04 +45 4.000000e-01 -9.620082e-04 +46 4.500000e-01 -9.899594e-04 +47 5.000000e-01 -1.016859e-03 +48 5.500000e-01 -1.041954e-03 +49 6.000000e-01 -1.066786e-03 +50 6.500000e-01 -1.091479e-03 +51 7.000000e-01 -1.116113e-03 +52 7.500000e-01 -1.140740e-03 +53 8.000000e-01 -1.165394e-03 +54 8.500000e-01 -1.190098e-03 + +Index v-sweep vds#branch +-------------------------------------------------------------------------------- +55 9.000000e-01 -1.214868e-03 +56 9.500000e-01 -1.239714e-03 +57 1.000000e+00 -1.264643e-03 +58 1.050000e+00 -1.289660e-03 +59 1.100000e+00 -1.314767e-03 +60 1.150000e+00 -1.339966e-03 +61 1.200000e+00 -1.365258e-03 +62 1.250000e+00 -1.390644e-03 +63 1.300000e+00 -1.416122e-03 +64 1.350000e+00 -1.441693e-03 +65 1.400000e+00 -1.467356e-03 +66 1.450000e+00 -1.493111e-03 +67 1.500000e+00 -1.518961e-03 +68 1.550000e+00 -1.544914e-03 +69 1.600000e+00 -1.570993e-03 +70 1.650000e+00 -1.597248e-03 +71 1.700000e+00 -1.623781e-03 +72 1.750000e+00 -1.651113e-03 +73 1.800000e+00 -1.679208e-03 +74 0.000000e+00 7.768174e-17 +75 5.000000e-02 -3.703606e-04 +76 1.000000e-01 -6.987097e-04 +77 1.500000e-01 -9.868153e-04 +78 2.000000e-01 -1.236346e-03 +79 2.500000e-01 -1.448849e-03 +80 3.000000e-01 -1.625787e-03 +81 3.500000e-01 -1.768734e-03 +82 4.000000e-01 -1.880044e-03 +83 4.500000e-01 -1.964114e-03 +84 5.000000e-01 -2.027894e-03 +85 5.500000e-01 -2.078850e-03 +86 6.000000e-01 -2.122513e-03 +87 6.500000e-01 -2.163764e-03 +88 7.000000e-01 -2.200380e-03 +89 7.500000e-01 -2.235939e-03 +90 8.000000e-01 -2.270810e-03 +91 8.500000e-01 -2.305222e-03 +92 9.000000e-01 -2.339322e-03 +93 9.500000e-01 -2.373211e-03 +94 1.000000e+00 -2.406955e-03 +95 1.050000e+00 -2.440601e-03 +96 1.100000e+00 -2.474182e-03 +97 1.150000e+00 -2.507722e-03 +98 1.200000e+00 -2.541239e-03 +99 1.250000e+00 -2.574745e-03 +100 1.300000e+00 -2.608249e-03 +101 1.350000e+00 -2.641757e-03 +102 1.400000e+00 -2.675275e-03 +103 1.450000e+00 -2.708806e-03 +104 1.500000e+00 -2.742352e-03 +105 1.550000e+00 -2.775916e-03 +106 1.600000e+00 -2.809500e-03 +107 1.650000e+00 -2.843110e-03 +108 1.700000e+00 -2.876761e-03 +109 1.750000e+00 -2.910490e-03 +110 1.800000e+00 -2.944372e-03 +111 0.000000e+00 1.277867e-16 +112 5.000000e-02 -4.308334e-04 + +Index v-sweep vds#branch +-------------------------------------------------------------------------------- +113 1.000000e-01 -8.263597e-04 +114 1.500000e-01 -1.187687e-03 +115 2.000000e-01 -1.515890e-03 +116 2.500000e-01 -1.811981e-03 +117 3.000000e-01 -2.076896e-03 +118 3.500000e-01 -2.311479e-03 +119 4.000000e-01 -2.516468e-03 +120 4.500000e-01 -2.692525e-03 +121 5.000000e-01 -2.840396e-03 +122 5.500000e-01 -2.961404e-03 +123 6.000000e-01 -3.058327e-03 +124 6.500000e-01 -3.135898e-03 +125 7.000000e-01 -3.199804e-03 +126 7.500000e-01 -3.254954e-03 +127 8.000000e-01 -3.306976e-03 +128 8.500000e-01 -3.352566e-03 +129 9.000000e-01 -3.396395e-03 +130 9.500000e-01 -3.439035e-03 +131 1.000000e+00 -3.480844e-03 +132 1.050000e+00 -3.522054e-03 +133 1.100000e+00 -3.562820e-03 +134 1.150000e+00 -3.603252e-03 +135 1.200000e+00 -3.643425e-03 +136 1.250000e+00 -3.683395e-03 +137 1.300000e+00 -3.723200e-03 +138 1.350000e+00 -3.762871e-03 +139 1.400000e+00 -3.802430e-03 +140 1.450000e+00 -3.841894e-03 +141 1.500000e+00 -3.881274e-03 +142 1.550000e+00 -3.920582e-03 +143 1.600000e+00 -3.959824e-03 +144 1.650000e+00 -3.999006e-03 +145 1.700000e+00 -4.038132e-03 +146 1.750000e+00 -4.077210e-03 +147 1.800000e+00 -4.116248e-03 +148 0.000000e+00 1.891469e-16 +149 5.000000e-02 -4.656895e-04 +150 1.000000e-01 -9.014901e-04 +151 1.500000e-01 -1.308142e-03 +152 2.000000e-01 -1.686379e-03 +153 2.500000e-01 -2.036909e-03 +154 3.000000e-01 -2.360404e-03 +155 3.500000e-01 -2.657496e-03 +156 4.000000e-01 -2.928762e-03 +157 4.500000e-01 -3.174713e-03 +158 5.000000e-01 -3.395772e-03 +159 5.500000e-01 -3.592274e-03 +160 6.000000e-01 -3.764489e-03 +161 6.500000e-01 -3.912770e-03 +162 7.000000e-01 -4.037949e-03 +163 7.500000e-01 -4.141974e-03 +164 8.000000e-01 -4.228292e-03 +165 8.500000e-01 -4.301284e-03 +166 9.000000e-01 -4.369062e-03 +167 9.500000e-01 -4.425420e-03 +168 1.000000e+00 -4.478293e-03 +169 1.050000e+00 -4.528861e-03 +170 1.100000e+00 -4.577833e-03 + +Index v-sweep vds#branch +-------------------------------------------------------------------------------- +171 1.150000e+00 -4.625657e-03 +172 1.200000e+00 -4.672632e-03 +173 1.250000e+00 -4.718958e-03 +174 1.300000e+00 -4.764777e-03 +175 1.350000e+00 -4.810191e-03 +176 1.400000e+00 -4.855270e-03 +177 1.450000e+00 -4.900071e-03 +178 1.500000e+00 -4.944634e-03 +179 1.550000e+00 -4.988988e-03 +180 1.600000e+00 -5.033157e-03 +181 1.650000e+00 -5.077161e-03 +182 1.700000e+00 -5.121011e-03 +183 1.750000e+00 -5.164721e-03 +184 1.800000e+00 -5.208298e-03 + + + + diff --git a/tests/bsim4/test10.cir b/tests/bsim4/test10.cir new file mode 100644 index 000000000..7f534bd92 --- /dev/null +++ b/tests/bsim4/test10.cir @@ -0,0 +1,14 @@ +** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +** Circuit Description ** +m1 2 1 0 0 p1 L=0.13u W=10.0u rgeoMod=1 +vgs 1 0 -1.8 +vds 2 0 -1.8 + +.dc vds 0 -1.8 -0.05 vgs -0.3 -1.8 -0.3 + +.options Temp=100.0 +.print dc v(1) i(vds) + +.include modelcard.pmos +.end diff --git a/tests/bsim4/test10.out b/tests/bsim4/test10.out new file mode 100644 index 000000000..ea0274ab7 --- /dev/null +++ b/tests/bsim4/test10.out @@ -0,0 +1,246 @@ + +No. of Data Rows : 222 + +Circuit: ** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +Doing analysis at TEMP = 373.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. +-------------------------------------------------------------------------------- +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 -3.000000e-01 -1.311633e-18 +1 -5.000000e-02 -3.000000e-01 6.295608e-09 +2 -1.000000e-01 -3.000000e-01 8.312678e-09 +3 -1.500000e-01 -3.000000e-01 9.616409e-09 +4 -2.000000e-01 -3.000000e-01 1.086702e-08 +5 -2.500000e-01 -3.000000e-01 1.216043e-08 +6 -3.000000e-01 -3.000000e-01 1.350623e-08 +7 -3.500000e-01 -3.000000e-01 1.491400e-08 +8 -4.000000e-01 -3.000000e-01 1.638754e-08 +9 -4.500000e-01 -3.000000e-01 1.792978e-08 +10 -5.000000e-01 -3.000000e-01 1.954340e-08 +11 -5.500000e-01 -3.000000e-01 2.123101e-08 +12 -6.000000e-01 -3.000000e-01 2.299523e-08 +13 -6.500000e-01 -3.000000e-01 2.483872e-08 +14 -7.000000e-01 -3.000000e-01 2.676419e-08 +15 -7.500000e-01 -3.000000e-01 2.877444e-08 +16 -8.000000e-01 -3.000000e-01 3.087232e-08 +17 -8.500000e-01 -3.000000e-01 3.306078e-08 +18 -9.000000e-01 -3.000000e-01 3.534283e-08 +19 -9.500000e-01 -3.000000e-01 3.772158e-08 +20 -1.000000e+00 -3.000000e-01 4.020022e-08 +21 -1.050000e+00 -3.000000e-01 4.278201e-08 +22 -1.100000e+00 -3.000000e-01 4.547034e-08 +23 -1.150000e+00 -3.000000e-01 4.826868e-08 +24 -1.200000e+00 -3.000000e-01 5.118064e-08 +25 -1.250000e+00 -3.000000e-01 5.421003e-08 +26 -1.300000e+00 -3.000000e-01 5.736100e-08 +27 -1.350000e+00 -3.000000e-01 6.063841e-08 +28 -1.400000e+00 -3.000000e-01 6.404849e-08 +29 -1.450000e+00 -3.000000e-01 6.760014e-08 +30 -1.500000e+00 -3.000000e-01 7.130723e-08 +31 -1.550000e+00 -3.000000e-01 7.519258e-08 +32 -1.600000e+00 -3.000000e-01 7.929438e-08 +33 -1.650000e+00 -3.000000e-01 8.367632e-08 +34 -1.700000e+00 -3.000000e-01 8.844284e-08 +35 -1.750000e+00 -3.000000e-01 9.376153e-08 +36 -1.800000e+00 -3.000000e-01 9.989507e-08 +37 0.000000e+00 -6.000000e-01 -9.409391e-18 +38 -5.000000e-02 -6.000000e-01 9.446743e-06 +39 -1.000000e-01 -6.000000e-01 1.310337e-05 +40 -1.500000e-01 -6.000000e-01 1.496078e-05 +41 -2.000000e-01 -6.000000e-01 1.653526e-05 +42 -2.500000e-01 -6.000000e-01 1.808514e-05 +43 -3.000000e-01 -6.000000e-01 1.965635e-05 +44 -3.500000e-01 -6.000000e-01 2.130351e-05 +45 -4.000000e-01 -6.000000e-01 2.298053e-05 +46 -4.500000e-01 -6.000000e-01 2.470850e-05 +47 -5.000000e-01 -6.000000e-01 2.646251e-05 +48 -5.500000e-01 -6.000000e-01 2.829610e-05 +49 -6.000000e-01 -6.000000e-01 3.018443e-05 +50 -6.500000e-01 -6.000000e-01 3.212839e-05 +51 -7.000000e-01 -6.000000e-01 3.412886e-05 +52 -7.500000e-01 -6.000000e-01 3.618668e-05 +53 -8.000000e-01 -6.000000e-01 3.830269e-05 +54 -8.500000e-01 -6.000000e-01 4.047773e-05 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +55 -9.000000e-01 -6.000000e-01 4.271262e-05 +56 -9.500000e-01 -6.000000e-01 4.500818e-05 +57 -1.000000e+00 -6.000000e-01 4.736523e-05 +58 -1.050000e+00 -6.000000e-01 4.978458e-05 +59 -1.100000e+00 -6.000000e-01 5.226703e-05 +60 -1.150000e+00 -6.000000e-01 5.481340e-05 +61 -1.200000e+00 -6.000000e-01 5.742449e-05 +62 -1.250000e+00 -6.000000e-01 6.010117e-05 +63 -1.300000e+00 -6.000000e-01 6.284441e-05 +64 -1.350000e+00 -6.000000e-01 6.565547e-05 +65 -1.400000e+00 -6.000000e-01 6.853632e-05 +66 -1.450000e+00 -6.000000e-01 7.149032e-05 +67 -1.500000e+00 -6.000000e-01 7.452373e-05 +68 -1.550000e+00 -6.000000e-01 7.764807e-05 +69 -1.600000e+00 -6.000000e-01 8.088430e-05 +70 -1.650000e+00 -6.000000e-01 8.435740e-05 +71 -1.700000e+00 -6.000000e-01 8.799395e-05 +72 -1.750000e+00 -6.000000e-01 9.196988e-05 +73 -1.800000e+00 -6.000000e-01 9.646187e-05 +74 0.000000e+00 -9.000000e-01 -2.853929e-17 +75 -5.000000e-02 -9.000000e-01 1.445355e-04 +76 -1.000000e-01 -9.000000e-01 2.660718e-04 +77 -1.500000e-01 -9.000000e-01 3.657323e-04 +78 -2.000000e-01 -9.000000e-01 4.447311e-04 +79 -2.500000e-01 -9.000000e-01 5.046019e-04 +80 -3.000000e-01 -9.000000e-01 5.477507e-04 +81 -3.500000e-01 -9.000000e-01 5.781317e-04 +82 -4.000000e-01 -9.000000e-01 6.006846e-04 +83 -4.500000e-01 -9.000000e-01 6.193534e-04 +84 -5.000000e-01 -9.000000e-01 6.362830e-04 +85 -5.500000e-01 -9.000000e-01 6.527249e-04 +86 -6.000000e-01 -9.000000e-01 6.683758e-04 +87 -6.500000e-01 -9.000000e-01 6.839594e-04 +88 -7.000000e-01 -9.000000e-01 6.995298e-04 +89 -7.500000e-01 -9.000000e-01 7.151211e-04 +90 -8.000000e-01 -9.000000e-01 7.307550e-04 +91 -8.500000e-01 -9.000000e-01 7.464455e-04 +92 -9.000000e-01 -9.000000e-01 7.622014e-04 +93 -9.500000e-01 -9.000000e-01 7.780283e-04 +94 -1.000000e+00 -9.000000e-01 7.939298e-04 +95 -1.050000e+00 -9.000000e-01 8.099081e-04 +96 -1.100000e+00 -9.000000e-01 8.259644e-04 +97 -1.150000e+00 -9.000000e-01 8.420992e-04 +98 -1.200000e+00 -9.000000e-01 8.583126e-04 +99 -1.250000e+00 -9.000000e-01 8.746044e-04 +100 -1.300000e+00 -9.000000e-01 8.909740e-04 +101 -1.350000e+00 -9.000000e-01 9.074206e-04 +102 -1.400000e+00 -9.000000e-01 9.239436e-04 +103 -1.450000e+00 -9.000000e-01 9.405421e-04 +104 -1.500000e+00 -9.000000e-01 9.572158e-04 +105 -1.550000e+00 -9.000000e-01 9.739659e-04 +106 -1.600000e+00 -9.000000e-01 9.907967e-04 +107 -1.650000e+00 -9.000000e-01 1.007720e-03 +108 -1.700000e+00 -9.000000e-01 1.024763e-03 +109 -1.750000e+00 -9.000000e-01 1.041984e-03 +110 -1.800000e+00 -9.000000e-01 1.059496e-03 +111 0.000000e+00 -1.200000e+00 -5.728902e-17 +112 -5.000000e-02 -1.200000e+00 2.140754e-04 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +113 -1.000000e-01 -1.200000e+00 4.081394e-04 +114 -1.500000e-01 -1.200000e+00 5.827826e-04 +115 -2.000000e-01 -1.200000e+00 7.385905e-04 +116 -2.500000e-01 -1.200000e+00 8.761372e-04 +117 -3.000000e-01 -1.200000e+00 9.959931e-04 +118 -3.500000e-01 -1.200000e+00 1.098747e-03 +119 -4.000000e-01 -1.200000e+00 1.185063e-03 +120 -4.500000e-01 -1.200000e+00 1.255820e-03 +121 -5.000000e-01 -1.200000e+00 1.312391e-03 +122 -5.500000e-01 -1.200000e+00 1.357009e-03 +123 -6.000000e-01 -1.200000e+00 1.392751e-03 +124 -6.500000e-01 -1.200000e+00 1.422780e-03 +125 -7.000000e-01 -1.200000e+00 1.450835e-03 +126 -7.500000e-01 -1.200000e+00 1.475104e-03 +127 -8.000000e-01 -1.200000e+00 1.498610e-03 +128 -8.500000e-01 -1.200000e+00 1.521664e-03 +129 -9.000000e-01 -1.200000e+00 1.544442e-03 +130 -9.500000e-01 -1.200000e+00 1.567048e-03 +131 -1.000000e+00 -1.200000e+00 1.589549e-03 +132 -1.050000e+00 -1.200000e+00 1.611989e-03 +133 -1.100000e+00 -1.200000e+00 1.634395e-03 +134 -1.150000e+00 -1.200000e+00 1.656788e-03 +135 -1.200000e+00 -1.200000e+00 1.679182e-03 +136 -1.250000e+00 -1.200000e+00 1.701586e-03 +137 -1.300000e+00 -1.200000e+00 1.724007e-03 +138 -1.350000e+00 -1.200000e+00 1.746448e-03 +139 -1.400000e+00 -1.200000e+00 1.768914e-03 +140 -1.450000e+00 -1.200000e+00 1.791406e-03 +141 -1.500000e+00 -1.200000e+00 1.813926e-03 +142 -1.550000e+00 -1.200000e+00 1.836474e-03 +143 -1.600000e+00 -1.200000e+00 1.859051e-03 +144 -1.650000e+00 -1.200000e+00 1.881657e-03 +145 -1.700000e+00 -1.200000e+00 1.904293e-03 +146 -1.750000e+00 -1.200000e+00 1.926961e-03 +147 -1.800000e+00 -1.200000e+00 1.949670e-03 +148 0.000000e+00 -1.500000e+00 -9.565718e-17 +149 -5.000000e-02 -1.500000e+00 2.497801e-04 +150 -1.000000e-01 -1.500000e+00 4.827905e-04 +151 -1.500000e-01 -1.500000e+00 6.993911e-04 +152 -2.000000e-01 -1.500000e+00 8.999450e-04 +153 -2.500000e-01 -1.500000e+00 1.084809e-03 +154 -3.000000e-01 -1.500000e+00 1.254330e-03 +155 -3.500000e-01 -1.500000e+00 1.408851e-03 +156 -4.000000e-01 -1.500000e+00 1.548703e-03 +157 -4.500000e-01 -1.500000e+00 1.674216e-03 +158 -5.000000e-01 -1.500000e+00 1.785723e-03 +159 -5.500000e-01 -1.500000e+00 1.883583e-03 +160 -6.000000e-01 -1.500000e+00 1.968229e-03 +161 -6.500000e-01 -1.500000e+00 2.040279e-03 +162 -7.000000e-01 -1.500000e+00 2.100721e-03 +163 -7.500000e-01 -1.500000e+00 2.151123e-03 +164 -8.000000e-01 -1.500000e+00 2.193631e-03 +165 -8.500000e-01 -1.500000e+00 2.230556e-03 +166 -9.000000e-01 -1.500000e+00 2.265389e-03 +167 -9.500000e-01 -1.500000e+00 2.295838e-03 +168 -1.000000e+00 -1.500000e+00 2.325114e-03 +169 -1.050000e+00 -1.500000e+00 2.353650e-03 +170 -1.100000e+00 -1.500000e+00 2.381696e-03 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +171 -1.150000e+00 -1.500000e+00 2.409408e-03 +172 -1.200000e+00 -1.500000e+00 2.436884e-03 +173 -1.250000e+00 -1.500000e+00 2.464192e-03 +174 -1.300000e+00 -1.500000e+00 2.491375e-03 +175 -1.350000e+00 -1.500000e+00 2.518465e-03 +176 -1.400000e+00 -1.500000e+00 2.545485e-03 +177 -1.450000e+00 -1.500000e+00 2.572449e-03 +178 -1.500000e+00 -1.500000e+00 2.599370e-03 +179 -1.550000e+00 -1.500000e+00 2.626256e-03 +180 -1.600000e+00 -1.500000e+00 2.653113e-03 +181 -1.650000e+00 -1.500000e+00 2.679944e-03 +182 -1.700000e+00 -1.500000e+00 2.706754e-03 +183 -1.750000e+00 -1.500000e+00 2.733545e-03 +184 -1.800000e+00 -1.500000e+00 2.760318e-03 +185 0.000000e+00 -1.800000e+00 -1.433956e-16 +186 -5.000000e-02 -1.800000e+00 2.692839e-04 +187 -1.000000e-01 -1.800000e+00 5.245069e-04 +188 -1.500000e-01 -1.800000e+00 7.659006e-04 +189 -2.000000e-01 -1.800000e+00 9.937023e-04 +190 -2.500000e-01 -1.800000e+00 1.208147e-03 +191 -3.000000e-01 -1.800000e+00 1.409468e-03 +192 -3.500000e-01 -1.800000e+00 1.597892e-03 +193 -4.000000e-01 -1.800000e+00 1.773642e-03 +194 -4.500000e-01 -1.800000e+00 1.936937e-03 +195 -5.000000e-01 -1.800000e+00 2.087991e-03 +196 -5.500000e-01 -1.800000e+00 2.227012e-03 +197 -6.000000e-01 -1.800000e+00 2.354206e-03 +198 -6.500000e-01 -1.800000e+00 2.469779e-03 +199 -7.000000e-01 -1.800000e+00 2.573945e-03 +200 -7.500000e-01 -1.800000e+00 2.666947e-03 +201 -8.000000e-01 -1.800000e+00 2.749101e-03 +202 -8.500000e-01 -1.800000e+00 2.820876e-03 +203 -9.000000e-01 -1.800000e+00 2.883026e-03 +204 -9.500000e-01 -1.800000e+00 2.936718e-03 +205 -1.000000e+00 -1.800000e+00 2.983521e-03 +206 -1.050000e+00 -1.800000e+00 3.027463e-03 +207 -1.100000e+00 -1.800000e+00 3.064789e-03 +208 -1.150000e+00 -1.800000e+00 3.099909e-03 +209 -1.200000e+00 -1.800000e+00 3.133615e-03 +210 -1.250000e+00 -1.800000e+00 3.166381e-03 +211 -1.300000e+00 -1.800000e+00 3.198499e-03 +212 -1.350000e+00 -1.800000e+00 3.230154e-03 +213 -1.400000e+00 -1.800000e+00 3.261465e-03 +214 -1.450000e+00 -1.800000e+00 3.292516e-03 +215 -1.500000e+00 -1.800000e+00 3.323363e-03 +216 -1.550000e+00 -1.800000e+00 3.354044e-03 +217 -1.600000e+00 -1.800000e+00 3.384590e-03 +218 -1.650000e+00 -1.800000e+00 3.415020e-03 +219 -1.700000e+00 -1.800000e+00 3.445350e-03 +220 -1.750000e+00 -1.800000e+00 3.475592e-03 +221 -1.800000e+00 -1.800000e+00 3.505753e-03 + + + + diff --git a/tests/bsim4/test11.cir b/tests/bsim4/test11.cir new file mode 100644 index 000000000..2e0307f64 --- /dev/null +++ b/tests/bsim4/test11.cir @@ -0,0 +1,14 @@ +** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +** Circuit Description ** +m1 2 1 0 3 p1 L=0.13u W=10.0u rgeoMod=1 +vgs 1 0 -1.8 +vds 2 0 -0.1 +vbs 3 0 0.0 + +.dc vgs 0.6 -1.8 -0.05 vds -0.1 -1.8 -0.3 + +.print dc v(2) i(vds) + +.include modelcard.pmos +.end diff --git a/tests/bsim4/test11.out b/tests/bsim4/test11.out new file mode 100644 index 000000000..d5e4ed4b9 --- /dev/null +++ b/tests/bsim4/test11.out @@ -0,0 +1,373 @@ + +No. of Data Rows : 343 + +Circuit: ** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. +-------------------------------------------------------------------------------- +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +0 6.000000e-01 -1.000000e-01 1.053433e-13 +1 5.500000e-01 -1.000000e-01 1.053433e-13 +2 5.000000e-01 -1.000000e-01 1.053381e-13 +3 4.500000e-01 -1.000000e-01 1.053381e-13 +4 4.000000e-01 -1.000000e-01 1.053381e-13 +5 3.500000e-01 -1.000000e-01 1.053381e-13 +6 3.000000e-01 -1.000000e-01 1.053381e-13 +7 2.500000e-01 -1.000000e-01 1.053433e-13 +8 2.000000e-01 -1.000000e-01 1.053746e-13 +9 1.500000e-01 -1.000000e-01 1.055621e-13 +10 1.000000e-01 -1.000000e-01 1.066196e-13 +11 5.000000e-02 -1.000000e-01 1.125219e-13 +12 6.938894e-17 -1.000000e-01 1.452423e-13 +13 -5.000000e-02 -1.000000e-01 3.269107e-13 +14 -1.000000e-01 -1.000000e-01 2.620955e-12 +15 -1.500000e-01 -1.000000e-01 1.406335e-11 +16 -2.000000e-01 -1.000000e-01 7.748692e-11 +17 -2.500000e-01 -1.000000e-01 4.282413e-10 +18 -3.000000e-01 -1.000000e-01 2.357714e-09 +19 -3.500000e-01 -1.000000e-01 1.284094e-08 +20 -4.000000e-01 -1.000000e-01 6.824786e-08 +21 -4.500000e-01 -1.000000e-01 3.450883e-07 +22 -5.000000e-01 -1.000000e-01 1.602571e-06 +23 -5.500000e-01 -1.000000e-01 6.667155e-06 +24 -6.000000e-01 -1.000000e-01 2.454873e-05 +25 -6.500000e-01 -1.000000e-01 7.402310e-05 +26 -7.000000e-01 -1.000000e-01 1.616656e-04 +27 -7.500000e-01 -1.000000e-01 2.605501e-04 +28 -8.000000e-01 -1.000000e-01 3.473995e-04 +29 -8.500000e-01 -1.000000e-01 4.187323e-04 +30 -9.000000e-01 -1.000000e-01 4.779357e-04 +31 -9.500000e-01 -1.000000e-01 5.285765e-04 +32 -1.000000e+00 -1.000000e-01 5.729916e-04 +33 -1.050000e+00 -1.000000e-01 6.125777e-04 +34 -1.100000e+00 -1.000000e-01 6.481917e-04 +35 -1.150000e+00 -1.000000e-01 6.804027e-04 +36 -1.200000e+00 -1.000000e-01 7.096260e-04 +37 -1.250000e+00 -1.000000e-01 7.361889e-04 +38 -1.300000e+00 -1.000000e-01 7.603635e-04 +39 -1.350000e+00 -1.000000e-01 7.823838e-04 +40 -1.400000e+00 -1.000000e-01 8.024538e-04 +41 -1.450000e+00 -1.000000e-01 8.207542e-04 +42 -1.500000e+00 -1.000000e-01 8.382248e-04 +43 -1.550000e+00 -1.000000e-01 8.533799e-04 +44 -1.600000e+00 -1.000000e-01 8.672045e-04 +45 -1.650000e+00 -1.000000e-01 8.797900e-04 +46 -1.700000e+00 -1.000000e-01 8.911945e-04 +47 -1.750000e+00 -1.000000e-01 9.015505e-04 +48 -1.800000e+00 -1.000000e-01 9.109508e-04 +49 6.000000e-01 -4.000000e-01 4.054948e-13 +50 5.500000e-01 -4.000000e-01 4.054948e-13 +51 5.000000e-01 -4.000000e-01 4.054532e-13 +52 4.500000e-01 -4.000000e-01 4.054532e-13 +53 4.000000e-01 -4.000000e-01 4.054532e-13 +54 3.500000e-01 -4.000000e-01 4.054532e-13 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +55 3.000000e-01 -4.000000e-01 4.054948e-13 +56 2.500000e-01 -4.000000e-01 4.054532e-13 +57 2.000000e-01 -4.000000e-01 4.055782e-13 +58 1.500000e-01 -4.000000e-01 4.059741e-13 +59 1.000000e-01 -4.000000e-01 4.082246e-13 +60 5.000000e-02 -4.000000e-01 4.210189e-13 +61 6.938894e-17 -4.000000e-01 4.919505e-13 +62 -5.000000e-02 -4.000000e-01 8.856582e-13 +63 -1.000000e-01 -4.000000e-01 5.856723e-12 +64 -1.500000e-01 -4.000000e-01 3.065043e-11 +65 -2.000000e-01 -4.000000e-01 1.680583e-10 +66 -2.500000e-01 -4.000000e-01 9.277083e-10 +67 -3.000000e-01 -4.000000e-01 5.103023e-09 +68 -3.500000e-01 -4.000000e-01 2.774359e-08 +69 -4.000000e-01 -4.000000e-01 1.468447e-07 +70 -4.500000e-01 -4.000000e-01 7.353415e-07 +71 -5.000000e-01 -4.000000e-01 3.338377e-06 +72 -5.500000e-01 -4.000000e-01 1.319997e-05 +73 -6.000000e-01 -4.000000e-01 4.441826e-05 +74 -6.500000e-01 -4.000000e-01 1.226379e-04 +75 -7.000000e-01 -4.000000e-01 2.643684e-04 +76 -7.500000e-01 -4.000000e-01 4.498766e-04 +77 -8.000000e-01 -4.000000e-01 6.463003e-04 +78 -8.500000e-01 -4.000000e-01 8.369758e-04 +79 -9.000000e-01 -4.000000e-01 1.019100e-03 +80 -9.500000e-01 -4.000000e-01 1.193931e-03 +81 -1.000000e+00 -4.000000e-01 1.362343e-03 +82 -1.050000e+00 -4.000000e-01 1.524080e-03 +83 -1.100000e+00 -4.000000e-01 1.678241e-03 +84 -1.150000e+00 -4.000000e-01 1.823917e-03 +85 -1.200000e+00 -4.000000e-01 1.960572e-03 +86 -1.250000e+00 -4.000000e-01 2.088110e-03 +87 -1.300000e+00 -4.000000e-01 2.206758e-03 +88 -1.350000e+00 -4.000000e-01 2.316937e-03 +89 -1.400000e+00 -4.000000e-01 2.419155e-03 +90 -1.450000e+00 -4.000000e-01 2.513944e-03 +91 -1.500000e+00 -4.000000e-01 2.601830e-03 +92 -1.550000e+00 -4.000000e-01 2.683313e-03 +93 -1.600000e+00 -4.000000e-01 2.758855e-03 +94 -1.650000e+00 -4.000000e-01 2.831515e-03 +95 -1.700000e+00 -4.000000e-01 2.895805e-03 +96 -1.750000e+00 -4.000000e-01 2.955220e-03 +97 -1.800000e+00 -4.000000e-01 3.010142e-03 +98 6.000000e-01 -7.000000e-01 7.054953e-13 +99 5.500000e-01 -7.000000e-01 7.054953e-13 +100 5.000000e-01 -7.000000e-01 7.054953e-13 +101 4.500000e-01 -7.000000e-01 7.054953e-13 +102 4.000000e-01 -7.000000e-01 7.054953e-13 +103 3.500000e-01 -7.000000e-01 7.054953e-13 +104 3.000000e-01 -7.000000e-01 7.054953e-13 +105 2.500000e-01 -7.000000e-01 7.055370e-13 +106 2.000000e-01 -7.000000e-01 7.056203e-13 +107 1.500000e-01 -7.000000e-01 7.063288e-13 +108 1.000000e-01 -7.000000e-01 7.103297e-13 +109 5.000000e-02 -7.000000e-01 7.324593e-13 +110 6.938894e-17 -7.000000e-01 8.552768e-13 +111 -5.000000e-02 -7.000000e-01 1.537253e-12 +112 -1.000000e-01 -7.000000e-01 1.014752e-11 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +113 -1.500000e-01 -7.000000e-01 5.308920e-11 +114 -2.000000e-01 -7.000000e-01 2.910367e-10 +115 -2.500000e-01 -7.000000e-01 1.606021e-09 +116 -3.000000e-01 -7.000000e-01 8.827245e-09 +117 -3.500000e-01 -7.000000e-01 4.790289e-08 +118 -4.000000e-01 -7.000000e-01 2.524887e-07 +119 -4.500000e-01 -7.000000e-01 1.252997e-06 +120 -5.000000e-01 -7.000000e-01 5.585099e-06 +121 -5.500000e-01 -7.000000e-01 2.131146e-05 +122 -6.000000e-01 -7.000000e-01 6.737595e-05 +123 -6.500000e-01 -7.000000e-01 1.712400e-04 +124 -7.000000e-01 -7.000000e-01 3.420905e-04 +125 -7.500000e-01 -7.000000e-01 5.521809e-04 +126 -8.000000e-01 -7.000000e-01 7.682496e-04 +127 -8.500000e-01 -7.000000e-01 9.764634e-04 +128 -9.000000e-01 -7.000000e-01 1.176393e-03 +129 -9.500000e-01 -7.000000e-01 1.371063e-03 +130 -1.000000e+00 -7.000000e-01 1.564035e-03 +131 -1.050000e+00 -7.000000e-01 1.754034e-03 +132 -1.100000e+00 -7.000000e-01 1.943493e-03 +133 -1.150000e+00 -7.000000e-01 2.132260e-03 +134 -1.200000e+00 -7.000000e-01 2.319970e-03 +135 -1.250000e+00 -7.000000e-01 2.506153e-03 +136 -1.300000e+00 -7.000000e-01 2.690263e-03 +137 -1.350000e+00 -7.000000e-01 2.871676e-03 +138 -1.400000e+00 -7.000000e-01 3.049678e-03 +139 -1.450000e+00 -7.000000e-01 3.223449e-03 +140 -1.500000e+00 -7.000000e-01 3.392077e-03 +141 -1.550000e+00 -7.000000e-01 3.554608e-03 +142 -1.600000e+00 -7.000000e-01 3.710151e-03 +143 -1.650000e+00 -7.000000e-01 3.853708e-03 +144 -1.700000e+00 -7.000000e-01 3.992381e-03 +145 -1.750000e+00 -7.000000e-01 4.122561e-03 +146 -1.800000e+00 -7.000000e-01 4.248549e-03 +147 6.000000e-01 -1.000000e+00 1.068053e-11 +148 5.500000e-01 -1.000000e+00 2.883105e-12 +149 5.000000e-01 -1.000000e+00 1.295147e-12 +150 4.500000e-01 -1.000000e+00 7.157753e-13 +151 4.000000e-01 -1.000000e+00 9.612435e-13 +152 3.500000e-01 -1.000000e+00 1.000793e-12 +153 3.000000e-01 -1.000000e+00 1.005169e-12 +154 2.500000e-01 -1.000000e+00 1.005461e-12 +155 2.000000e-01 -1.000000e+00 1.005670e-12 +156 1.500000e-01 -1.000000e+00 1.006836e-12 +157 1.000000e-01 -1.000000e+00 1.013088e-12 +158 5.000000e-02 -1.000000e+00 1.047887e-12 +159 6.938894e-17 -1.000000e+00 1.241011e-12 +160 -5.000000e-02 -1.000000e+00 3.679648e-12 +161 -1.000000e-01 -1.000000e+00 1.584766e-11 +162 -1.500000e-01 -1.000000e+00 8.334383e-11 +163 -2.000000e-01 -1.000000e+00 4.572878e-10 +164 -2.500000e-01 -1.000000e+00 2.523001e-09 +165 -3.000000e-01 -1.000000e+00 1.385599e-08 +166 -3.500000e-01 -1.000000e+00 7.504499e-08 +167 -4.000000e-01 -1.000000e+00 3.938163e-07 +168 -4.500000e-01 -1.000000e+00 1.936595e-06 +169 -5.000000e-01 -1.000000e+00 8.485155e-06 +170 -5.500000e-01 -1.000000e+00 3.142262e-05 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +171 -6.000000e-01 -1.000000e+00 9.467395e-05 +172 -6.500000e-01 -1.000000e+00 2.260744e-04 +173 -7.000000e-01 -1.000000e+00 4.259223e-04 +174 -7.500000e-01 -1.000000e+00 6.588455e-04 +175 -8.000000e-01 -1.000000e+00 8.917477e-04 +176 -8.500000e-01 -1.000000e+00 1.113416e-03 +177 -9.000000e-01 -1.000000e+00 1.325142e-03 +178 -9.500000e-01 -1.000000e+00 1.530761e-03 +179 -1.000000e+00 -1.000000e+00 1.734408e-03 +180 -1.050000e+00 -1.000000e+00 1.934576e-03 +181 -1.100000e+00 -1.000000e+00 2.134194e-03 +182 -1.150000e+00 -1.000000e+00 2.333285e-03 +183 -1.200000e+00 -1.000000e+00 2.531697e-03 +184 -1.250000e+00 -1.000000e+00 2.729216e-03 +185 -1.300000e+00 -1.000000e+00 2.925615e-03 +186 -1.350000e+00 -1.000000e+00 3.120678e-03 +187 -1.400000e+00 -1.000000e+00 3.314197e-03 +188 -1.450000e+00 -1.000000e+00 3.505980e-03 +189 -1.500000e+00 -1.000000e+00 3.695839e-03 +190 -1.550000e+00 -1.000000e+00 3.883587e-03 +191 -1.600000e+00 -1.000000e+00 4.069031e-03 +192 -1.650000e+00 -1.000000e+00 4.251827e-03 +193 -1.700000e+00 -1.000000e+00 4.430777e-03 +194 -1.750000e+00 -1.000000e+00 4.606047e-03 +195 -1.800000e+00 -1.000000e+00 4.777380e-03 +196 6.000000e-01 -1.300000e+00 8.362057e-09 +197 5.500000e-01 -1.300000e+00 3.522663e-09 +198 5.000000e-01 -1.300000e+00 1.364808e-09 +199 4.500000e-01 -1.300000e+00 4.803444e-10 +200 4.000000e-01 -1.300000e+00 1.515781e-10 +201 3.500000e-01 -1.300000e+00 4.256969e-11 +202 3.000000e-01 -1.300000e+00 1.098172e-11 +203 2.500000e-01 -1.300000e+00 3.183502e-12 +204 2.000000e-01 -1.300000e+00 1.596002e-12 +205 1.500000e-01 -1.300000e+00 1.017880e-12 +206 1.000000e-01 -1.300000e+00 1.272517e-12 +207 5.000000e-02 -1.300000e+00 1.363703e-12 +208 6.938894e-17 -1.300000e+00 1.654847e-12 +209 -5.000000e-02 -1.300000e+00 5.275774e-12 +210 -1.000000e-01 -1.300000e+00 2.334040e-11 +211 -1.500000e-01 -1.300000e+00 1.235370e-10 +212 -2.000000e-01 -1.300000e+00 6.785474e-10 +213 -2.500000e-01 -1.300000e+00 3.743146e-09 +214 -3.000000e-01 -1.300000e+00 2.053884e-08 +215 -3.500000e-01 -1.300000e+00 1.110052e-07 +216 -4.000000e-01 -1.300000e+00 5.798099e-07 +217 -4.500000e-01 -1.300000e+00 2.824338e-06 +218 -5.000000e-01 -1.300000e+00 1.216558e-05 +219 -5.500000e-01 -1.300000e+00 4.381842e-05 +220 -6.000000e-01 -1.300000e+00 1.266458e-04 +221 -6.500000e-01 -1.300000e+00 2.872540e-04 +222 -7.000000e-01 -1.300000e+00 5.159576e-04 +223 -7.500000e-01 -1.300000e+00 7.707164e-04 +224 -8.000000e-01 -1.300000e+00 1.019445e-03 +225 -8.500000e-01 -1.300000e+00 1.253652e-03 +226 -9.000000e-01 -1.300000e+00 1.476245e-03 +227 -9.500000e-01 -1.300000e+00 1.691768e-03 +228 -1.000000e+00 -1.300000e+00 1.903422e-03 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +229 -1.050000e+00 -1.300000e+00 2.112962e-03 +230 -1.100000e+00 -1.300000e+00 2.321196e-03 +231 -1.150000e+00 -1.300000e+00 2.528898e-03 +232 -1.200000e+00 -1.300000e+00 2.735120e-03 +233 -1.250000e+00 -1.300000e+00 2.940286e-03 +234 -1.300000e+00 -1.300000e+00 3.144232e-03 +235 -1.350000e+00 -1.300000e+00 3.346802e-03 +236 -1.400000e+00 -1.300000e+00 3.547851e-03 +237 -1.450000e+00 -1.300000e+00 3.747256e-03 +238 -1.500000e+00 -1.300000e+00 3.944904e-03 +239 -1.550000e+00 -1.300000e+00 4.140698e-03 +240 -1.600000e+00 -1.300000e+00 4.334549e-03 +241 -1.650000e+00 -1.300000e+00 4.526249e-03 +242 -1.700000e+00 -1.300000e+00 4.714691e-03 +243 -1.750000e+00 -1.300000e+00 4.900243e-03 +244 -1.800000e+00 -1.300000e+00 5.082877e-03 +245 6.000000e-01 -1.600000e+00 4.226580e-07 +246 5.500000e-01 -1.600000e+00 2.472012e-07 +247 5.000000e-01 -1.600000e+00 1.389354e-07 +248 4.500000e-01 -1.600000e+00 7.468366e-08 +249 4.000000e-01 -1.600000e+00 3.818570e-08 +250 3.500000e-01 -1.600000e+00 1.845185e-08 +251 3.000000e-01 -1.600000e+00 8.362710e-09 +252 2.500000e-01 -1.600000e+00 3.523112e-09 +253 2.000000e-01 -1.600000e+00 1.365167e-09 +254 1.500000e-01 -1.600000e+00 4.806707e-10 +255 1.000000e-01 -1.600000e+00 1.519178e-10 +256 5.000000e-02 -1.600000e+00 4.305651e-11 +257 6.938894e-17 -1.600000e+00 1.230831e-11 +258 -5.000000e-02 -1.600000e+00 9.179983e-12 +259 -1.000000e-01 -1.600000e+00 3.351009e-11 +260 -1.500000e-01 -1.600000e+00 1.769999e-10 +261 -2.000000e-01 -1.600000e+00 9.730466e-10 +262 -2.500000e-01 -1.600000e+00 5.366649e-09 +263 -3.000000e-01 -1.600000e+00 2.941904e-08 +264 -3.500000e-01 -1.600000e+00 1.586379e-07 +265 -4.000000e-01 -1.600000e+00 8.244776e-07 +266 -4.500000e-01 -1.600000e+00 3.976325e-06 +267 -5.000000e-01 -1.600000e+00 1.683113e-05 +268 -5.500000e-01 -1.600000e+00 5.898676e-05 +269 -6.000000e-01 -1.600000e+00 1.639771e-04 +270 -6.500000e-01 -1.600000e+00 3.552730e-04 +271 -7.000000e-01 -1.600000e+00 6.123887e-04 +272 -7.500000e-01 -1.600000e+00 8.878737e-04 +273 -8.000000e-01 -1.600000e+00 1.151491e-03 +274 -8.500000e-01 -1.600000e+00 1.397530e-03 +275 -9.000000e-01 -1.600000e+00 1.630401e-03 +276 -9.500000e-01 -1.600000e+00 1.855275e-03 +277 -1.000000e+00 -1.600000e+00 2.075622e-03 +278 -1.050000e+00 -1.600000e+00 2.293332e-03 +279 -1.100000e+00 -1.600000e+00 2.509301e-03 +280 -1.150000e+00 -1.600000e+00 2.723879e-03 +281 -1.200000e+00 -1.600000e+00 2.937146e-03 +282 -1.250000e+00 -1.600000e+00 3.149056e-03 +283 -1.300000e+00 -1.600000e+00 3.359516e-03 +284 -1.350000e+00 -1.600000e+00 3.568420e-03 +285 -1.400000e+00 -1.600000e+00 3.775666e-03 +286 -1.450000e+00 -1.600000e+00 3.981160e-03 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +287 -1.500000e+00 -1.600000e+00 4.184820e-03 +288 -1.550000e+00 -1.600000e+00 4.386574e-03 +289 -1.600000e+00 -1.600000e+00 4.586354e-03 +290 -1.650000e+00 -1.600000e+00 4.783603e-03 +291 -1.700000e+00 -1.600000e+00 4.979429e-03 +292 -1.750000e+00 -1.600000e+00 5.170974e-03 +293 -1.800000e+00 -1.600000e+00 5.359664e-03 +294 6.000000e-01 -1.900000e+00 5.558005e-06 +295 5.500000e-01 -1.900000e+00 3.851706e-06 +296 5.000000e-01 -1.900000e+00 2.611205e-06 +297 4.500000e-01 -1.900000e+00 1.728116e-06 +298 4.000000e-01 -1.900000e+00 1.113828e-06 +299 3.500000e-01 -1.900000e+00 6.972779e-07 +300 3.000000e-01 -1.900000e+00 4.226666e-07 +301 2.500000e-01 -1.900000e+00 2.472064e-07 +302 2.000000e-01 -1.900000e+00 1.389384e-07 +303 1.500000e-01 -1.900000e+00 7.468544e-08 +304 1.000000e-01 -1.900000e+00 3.818680e-08 +305 5.000000e-02 -1.900000e+00 1.845279e-08 +306 6.938894e-17 -1.900000e+00 8.364750e-09 +307 -5.000000e-02 -1.900000e+00 3.532227e-09 +308 -1.000000e-01 -1.900000e+00 1.414029e-09 +309 -1.500000e-01 -1.900000e+00 7.501743e-10 +310 -2.000000e-01 -1.900000e+00 1.643177e-09 +311 -2.500000e-01 -1.900000e+00 8.273807e-09 +312 -3.000000e-01 -1.900000e+00 4.509279e-08 +313 -3.500000e-01 -1.900000e+00 2.425032e-07 +314 -4.000000e-01 -1.900000e+00 1.253432e-06 +315 -4.500000e-01 -1.900000e+00 5.977844e-06 +316 -5.000000e-01 -1.900000e+00 2.478547e-05 +317 -5.500000e-01 -1.900000e+00 8.385634e-05 +318 -6.000000e-01 -1.900000e+00 2.210890e-04 +319 -6.500000e-01 -1.900000e+00 4.504568e-04 +320 -7.000000e-01 -1.900000e+00 7.365916e-04 +321 -7.500000e-01 -1.900000e+00 1.029472e-03 +322 -8.000000e-01 -1.900000e+00 1.303858e-03 +323 -8.500000e-01 -1.900000e+00 1.557941e-03 +324 -9.000000e-01 -1.900000e+00 1.797817e-03 +325 -9.500000e-01 -1.900000e+00 2.029257e-03 +326 -1.000000e+00 -1.900000e+00 2.255938e-03 +327 -1.050000e+00 -1.900000e+00 2.479832e-03 +328 -1.100000e+00 -1.900000e+00 2.701869e-03 +329 -1.150000e+00 -1.900000e+00 2.922416e-03 +330 -1.200000e+00 -1.900000e+00 3.141556e-03 +331 -1.250000e+00 -1.900000e+00 3.359246e-03 +332 -1.300000e+00 -1.900000e+00 3.575391e-03 +333 -1.350000e+00 -1.900000e+00 3.789885e-03 +334 -1.400000e+00 -1.900000e+00 4.002626e-03 +335 -1.450000e+00 -1.900000e+00 4.213523e-03 +336 -1.500000e+00 -1.900000e+00 4.422498e-03 +337 -1.550000e+00 -1.900000e+00 4.629487e-03 +338 -1.600000e+00 -1.900000e+00 4.834431e-03 +339 -1.650000e+00 -1.900000e+00 5.036778e-03 +340 -1.700000e+00 -1.900000e+00 5.236201e-03 +341 -1.750000e+00 -1.900000e+00 5.432710e-03 +342 -1.800000e+00 -1.900000e+00 5.626317e-03 + + + + diff --git a/tests/bsim4/test12.cir b/tests/bsim4/test12.cir new file mode 100644 index 000000000..5145d5e24 --- /dev/null +++ b/tests/bsim4/test12.cir @@ -0,0 +1,15 @@ +** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +** Circuit Description ** +m1 2 1 0 3 p1 L=0.13u W=10.0u rgeoMod=1 +vgs 1 0 -1.8 +vds 2 0 -0.1 +vbs 3 0 0.0 + + +.dc vgs 0.6 -1.8 -0.05 vbs 0 1.8 0.3 + +.print dc v(2) i(vds) + +.include modelcard.pmos +.end diff --git a/tests/bsim4/test12.out b/tests/bsim4/test12.out new file mode 100644 index 000000000..5e1110ce4 --- /dev/null +++ b/tests/bsim4/test12.out @@ -0,0 +1,373 @@ + +No. of Data Rows : 343 + +Circuit: ** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. +-------------------------------------------------------------------------------- +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +0 6.000000e-01 -1.000000e-01 1.053433e-13 +1 5.500000e-01 -1.000000e-01 1.053433e-13 +2 5.000000e-01 -1.000000e-01 1.053381e-13 +3 4.500000e-01 -1.000000e-01 1.053381e-13 +4 4.000000e-01 -1.000000e-01 1.053381e-13 +5 3.500000e-01 -1.000000e-01 1.053381e-13 +6 3.000000e-01 -1.000000e-01 1.053381e-13 +7 2.500000e-01 -1.000000e-01 1.053433e-13 +8 2.000000e-01 -1.000000e-01 1.053746e-13 +9 1.500000e-01 -1.000000e-01 1.055621e-13 +10 1.000000e-01 -1.000000e-01 1.066196e-13 +11 5.000000e-02 -1.000000e-01 1.125219e-13 +12 6.938894e-17 -1.000000e-01 1.452423e-13 +13 -5.000000e-02 -1.000000e-01 3.269107e-13 +14 -1.000000e-01 -1.000000e-01 2.620955e-12 +15 -1.500000e-01 -1.000000e-01 1.406335e-11 +16 -2.000000e-01 -1.000000e-01 7.748692e-11 +17 -2.500000e-01 -1.000000e-01 4.282413e-10 +18 -3.000000e-01 -1.000000e-01 2.357714e-09 +19 -3.500000e-01 -1.000000e-01 1.284094e-08 +20 -4.000000e-01 -1.000000e-01 6.824786e-08 +21 -4.500000e-01 -1.000000e-01 3.450883e-07 +22 -5.000000e-01 -1.000000e-01 1.602571e-06 +23 -5.500000e-01 -1.000000e-01 6.667155e-06 +24 -6.000000e-01 -1.000000e-01 2.454873e-05 +25 -6.500000e-01 -1.000000e-01 7.402310e-05 +26 -7.000000e-01 -1.000000e-01 1.616656e-04 +27 -7.500000e-01 -1.000000e-01 2.605501e-04 +28 -8.000000e-01 -1.000000e-01 3.473995e-04 +29 -8.500000e-01 -1.000000e-01 4.187323e-04 +30 -9.000000e-01 -1.000000e-01 4.779357e-04 +31 -9.500000e-01 -1.000000e-01 5.285765e-04 +32 -1.000000e+00 -1.000000e-01 5.729916e-04 +33 -1.050000e+00 -1.000000e-01 6.125777e-04 +34 -1.100000e+00 -1.000000e-01 6.481917e-04 +35 -1.150000e+00 -1.000000e-01 6.804027e-04 +36 -1.200000e+00 -1.000000e-01 7.096260e-04 +37 -1.250000e+00 -1.000000e-01 7.361889e-04 +38 -1.300000e+00 -1.000000e-01 7.603635e-04 +39 -1.350000e+00 -1.000000e-01 7.823838e-04 +40 -1.400000e+00 -1.000000e-01 8.024538e-04 +41 -1.450000e+00 -1.000000e-01 8.207542e-04 +42 -1.500000e+00 -1.000000e-01 8.382248e-04 +43 -1.550000e+00 -1.000000e-01 8.533799e-04 +44 -1.600000e+00 -1.000000e-01 8.672045e-04 +45 -1.650000e+00 -1.000000e-01 8.797900e-04 +46 -1.700000e+00 -1.000000e-01 8.911945e-04 +47 -1.750000e+00 -1.000000e-01 9.015505e-04 +48 -1.800000e+00 -1.000000e-01 9.109508e-04 +49 6.000000e-01 -1.000000e-01 4.054480e-13 +50 5.500000e-01 -1.000000e-01 4.054480e-13 +51 5.000000e-01 -1.000000e-01 4.054480e-13 +52 4.500000e-01 -1.000000e-01 4.054480e-13 +53 4.000000e-01 -1.000000e-01 4.054480e-13 +54 3.500000e-01 -1.000000e-01 4.054480e-13 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +55 3.000000e-01 -1.000000e-01 4.054428e-13 +56 2.500000e-01 -1.000000e-01 4.054480e-13 +57 2.000000e-01 -1.000000e-01 4.054584e-13 +58 1.500000e-01 -1.000000e-01 4.055053e-13 +59 1.000000e-01 -1.000000e-01 4.058074e-13 +60 5.000000e-02 -1.000000e-01 4.074953e-13 +61 6.938894e-17 -1.000000e-01 4.171640e-13 +62 -5.000000e-02 -1.000000e-01 4.722745e-13 +63 -1.000000e-01 -1.000000e-01 7.865592e-13 +64 -1.500000e-01 -1.000000e-01 4.925366e-12 +65 -2.000000e-01 -1.000000e-01 2.616004e-11 +66 -2.500000e-01 -1.000000e-01 1.469813e-10 +67 -3.000000e-01 -1.000000e-01 8.322223e-10 +68 -3.500000e-01 -1.000000e-01 4.688914e-09 +69 -4.000000e-01 -1.000000e-01 2.601228e-08 +70 -4.500000e-01 -1.000000e-01 1.393991e-07 +71 -5.000000e-01 -1.000000e-01 6.986384e-07 +72 -5.500000e-01 -1.000000e-01 3.159203e-06 +73 -6.000000e-01 -1.000000e-01 1.267917e-05 +74 -6.500000e-01 -1.000000e-01 4.359406e-05 +75 -7.000000e-01 -1.000000e-01 1.133675e-04 +76 -7.500000e-01 -1.000000e-01 2.090984e-04 +77 -8.000000e-01 -1.000000e-01 3.009464e-04 +78 -8.500000e-01 -1.000000e-01 3.775701e-04 +79 -9.000000e-01 -1.000000e-01 4.406115e-04 +80 -9.500000e-01 -1.000000e-01 4.939148e-04 +81 -1.000000e+00 -1.000000e-01 5.402921e-04 +82 -1.050000e+00 -1.000000e-01 5.814446e-04 +83 -1.100000e+00 -1.000000e-01 6.183893e-04 +84 -1.150000e+00 -1.000000e-01 6.517756e-04 +85 -1.200000e+00 -1.000000e-01 6.820598e-04 +86 -1.250000e+00 -1.000000e-01 7.095920e-04 +87 -1.300000e+00 -1.000000e-01 7.346585e-04 +88 -1.350000e+00 -1.000000e-01 7.575033e-04 +89 -1.400000e+00 -1.000000e-01 7.783383e-04 +90 -1.450000e+00 -1.000000e-01 7.973504e-04 +91 -1.500000e+00 -1.000000e-01 8.155081e-04 +92 -1.550000e+00 -1.000000e-01 8.312821e-04 +93 -1.600000e+00 -1.000000e-01 8.456874e-04 +94 -1.650000e+00 -1.000000e-01 8.588178e-04 +95 -1.700000e+00 -1.000000e-01 8.707327e-04 +96 -1.750000e+00 -1.000000e-01 8.815690e-04 +97 -1.800000e+00 -1.000000e-01 8.914223e-04 +98 6.000000e-01 -1.000000e-01 7.054589e-13 +99 5.500000e-01 -1.000000e-01 7.054589e-13 +100 5.000000e-01 -1.000000e-01 7.054589e-13 +101 4.500000e-01 -1.000000e-01 7.054589e-13 +102 4.000000e-01 -1.000000e-01 7.054589e-13 +103 3.500000e-01 -1.000000e-01 7.054589e-13 +104 3.000000e-01 -1.000000e-01 7.054537e-13 +105 2.500000e-01 -1.000000e-01 7.054537e-13 +106 2.000000e-01 -1.000000e-01 7.054537e-13 +107 1.500000e-01 -1.000000e-01 7.054641e-13 +108 1.000000e-01 -1.000000e-01 7.055735e-13 +109 5.000000e-02 -1.000000e-01 7.062038e-13 +110 6.938894e-17 -1.000000e-01 7.098556e-13 +111 -5.000000e-02 -1.000000e-01 7.310528e-13 +112 -1.000000e-01 -1.000000e-01 8.540578e-13 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +113 -1.500000e-01 -1.000000e-01 1.568213e-12 +114 -2.000000e-01 -1.000000e-01 1.124001e-11 +115 -2.500000e-01 -1.000000e-01 6.179035e-11 +116 -3.000000e-01 -1.000000e-01 3.542409e-10 +117 -3.500000e-01 -1.000000e-01 2.037532e-09 +118 -4.000000e-01 -1.000000e-01 1.160910e-08 +119 -4.500000e-01 -1.000000e-01 6.454323e-08 +120 -5.000000e-01 -1.000000e-01 3.407946e-07 +121 -5.500000e-01 -1.000000e-01 1.644733e-06 +122 -6.000000e-01 -1.000000e-01 7.056112e-06 +123 -6.500000e-01 -1.000000e-01 2.645105e-05 +124 -7.000000e-01 -1.000000e-01 7.899503e-05 +125 -7.500000e-01 -1.000000e-01 1.668572e-04 +126 -8.000000e-01 -1.000000e-01 2.611309e-04 +127 -8.500000e-01 -1.000000e-01 3.424309e-04 +128 -9.000000e-01 -1.000000e-01 4.091598e-04 +129 -9.500000e-01 -1.000000e-01 4.649938e-04 +130 -1.000000e+00 -1.000000e-01 5.131646e-04 +131 -1.050000e+00 -1.000000e-01 5.556954e-04 +132 -1.100000e+00 -1.000000e-01 5.937812e-04 +133 -1.150000e+00 -1.000000e-01 6.281607e-04 +134 -1.200000e+00 -1.000000e-01 6.593349e-04 +135 -1.250000e+00 -1.000000e-01 6.876773e-04 +136 -1.300000e+00 -1.000000e-01 7.134881e-04 +137 -1.350000e+00 -1.000000e-01 7.370203e-04 +138 -1.400000e+00 -1.000000e-01 7.584928e-04 +139 -1.450000e+00 -1.000000e-01 7.780980e-04 +140 -1.500000e+00 -1.000000e-01 7.960063e-04 +141 -1.550000e+00 -1.000000e-01 8.131182e-04 +142 -1.600000e+00 -1.000000e-01 8.280060e-04 +143 -1.650000e+00 -1.000000e-01 8.415898e-04 +144 -1.700000e+00 -1.000000e-01 8.539293e-04 +145 -1.750000e+00 -1.000000e-01 8.651649e-04 +146 -1.800000e+00 -1.000000e-01 8.753946e-04 +147 6.000000e-01 -1.000000e-01 1.005454e-12 +148 5.500000e-01 -1.000000e-01 1.005454e-12 +149 5.000000e-01 -1.000000e-01 1.005454e-12 +150 4.500000e-01 -1.000000e-01 1.005454e-12 +151 4.000000e-01 -1.000000e-01 1.005454e-12 +152 3.500000e-01 -1.000000e-01 1.005454e-12 +153 3.000000e-01 -1.000000e-01 1.005454e-12 +154 2.500000e-01 -1.000000e-01 1.005449e-12 +155 2.000000e-01 -1.000000e-01 1.005454e-12 +156 1.500000e-01 -1.000000e-01 1.005465e-12 +157 1.000000e-01 -1.000000e-01 1.005511e-12 +158 5.000000e-02 -1.000000e-01 1.005782e-12 +159 6.938894e-17 -1.000000e-01 1.007413e-12 +160 -5.000000e-02 -1.000000e-01 1.017009e-12 +161 -1.000000e-01 -1.000000e-01 1.073432e-12 +162 -1.500000e-01 -1.000000e-01 1.405340e-12 +163 -2.000000e-01 -1.000000e-01 5.994637e-12 +164 -2.500000e-01 -1.000000e-01 3.032618e-11 +165 -3.000000e-01 -1.000000e-01 1.730916e-10 +166 -3.500000e-01 -1.000000e-01 1.007739e-09 +167 -4.000000e-01 -1.000000e-01 5.844859e-09 +168 -4.500000e-01 -1.000000e-01 3.330892e-08 +169 -5.000000e-01 -1.000000e-01 1.823863e-07 +170 -5.500000e-01 -1.000000e-01 9.254345e-07 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +171 -6.000000e-01 -1.000000e-01 4.196855e-06 +172 -6.500000e-01 -1.000000e-01 1.673706e-05 +173 -7.000000e-01 -1.000000e-01 5.538080e-05 +174 -7.500000e-01 -1.000000e-01 1.326368e-04 +175 -8.000000e-01 -1.000000e-01 2.267089e-04 +176 -8.500000e-01 -1.000000e-01 3.118361e-04 +177 -9.000000e-01 -1.000000e-01 3.820465e-04 +178 -9.500000e-01 -1.000000e-01 4.403014e-04 +179 -1.000000e+00 -1.000000e-01 4.901418e-04 +180 -1.050000e+00 -1.000000e-01 5.339128e-04 +181 -1.100000e+00 -1.000000e-01 5.729989e-04 +182 -1.150000e+00 -1.000000e-01 6.082355e-04 +183 -1.200000e+00 -1.000000e-01 6.401714e-04 +184 -1.250000e+00 -1.000000e-01 6.692046e-04 +185 -1.300000e+00 -1.000000e-01 6.956488e-04 +186 -1.350000e+00 -1.000000e-01 7.197656e-04 +187 -1.400000e+00 -1.000000e-01 7.417799e-04 +188 -1.450000e+00 -1.000000e-01 7.618890e-04 +189 -1.500000e+00 -1.000000e-01 7.802672e-04 +190 -1.550000e+00 -1.000000e-01 7.978332e-04 +191 -1.600000e+00 -1.000000e-01 8.131313e-04 +192 -1.650000e+00 -1.000000e-01 8.271000e-04 +193 -1.700000e+00 -1.000000e-01 8.397997e-04 +194 -1.750000e+00 -1.000000e-01 8.513742e-04 +195 -1.800000e+00 -1.000000e-01 8.619231e-04 +196 6.000000e-01 -1.000000e-01 1.305449e-12 +197 5.500000e-01 -1.000000e-01 1.305449e-12 +198 5.000000e-01 -1.000000e-01 1.305449e-12 +199 4.500000e-01 -1.000000e-01 1.305449e-12 +200 4.000000e-01 -1.000000e-01 1.305449e-12 +201 3.500000e-01 -1.000000e-01 1.305449e-12 +202 3.000000e-01 -1.000000e-01 1.305449e-12 +203 2.500000e-01 -1.000000e-01 1.305444e-12 +204 2.000000e-01 -1.000000e-01 1.305449e-12 +205 1.500000e-01 -1.000000e-01 1.305449e-12 +206 1.000000e-01 -1.000000e-01 1.305470e-12 +207 5.000000e-02 -1.000000e-01 1.305616e-12 +208 6.938894e-17 -1.000000e-01 1.306434e-12 +209 -5.000000e-02 -1.000000e-01 1.311347e-12 +210 -1.000000e-01 -1.000000e-01 1.340525e-12 +211 -1.500000e-01 -1.000000e-01 1.513842e-12 +212 -2.000000e-01 -1.000000e-01 3.948583e-12 +213 -2.500000e-01 -1.000000e-01 1.699758e-11 +214 -3.000000e-01 -1.000000e-01 9.437757e-11 +215 -3.500000e-01 -1.000000e-01 5.520057e-10 +216 -4.000000e-01 -1.000000e-01 3.240746e-09 +217 -4.500000e-01 -1.000000e-01 1.879280e-08 +218 -5.000000e-01 -1.000000e-01 1.056120e-07 +219 -5.500000e-01 -1.000000e-01 5.567452e-07 +220 -6.000000e-01 -1.000000e-01 2.645132e-06 +221 -6.500000e-01 -1.000000e-01 1.107608e-05 +222 -7.000000e-01 -1.000000e-01 3.948527e-05 +223 -7.500000e-01 -1.000000e-01 1.054628e-04 +224 -8.000000e-01 -1.000000e-01 1.970015e-04 +225 -8.500000e-01 -1.000000e-01 2.849527e-04 +226 -9.000000e-01 -1.000000e-01 3.583700e-04 +227 -9.500000e-01 -1.000000e-01 4.189336e-04 +228 -1.000000e+00 -1.000000e-01 4.703411e-04 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +229 -1.050000e+00 -1.000000e-01 5.152422e-04 +230 -1.100000e+00 -1.000000e-01 5.552166e-04 +231 -1.150000e+00 -1.000000e-01 5.912023e-04 +232 -1.200000e+00 -1.000000e-01 6.237980e-04 +233 -1.250000e+00 -1.000000e-01 6.534269e-04 +234 -1.300000e+00 -1.000000e-01 6.804163e-04 +235 -1.350000e+00 -1.000000e-01 7.050357e-04 +236 -1.400000e+00 -1.000000e-01 7.275156e-04 +237 -1.450000e+00 -1.000000e-01 7.480576e-04 +238 -1.500000e+00 -1.000000e-01 7.668395e-04 +239 -1.550000e+00 -1.000000e-01 7.847955e-04 +240 -1.600000e+00 -1.000000e-01 8.004459e-04 +241 -1.650000e+00 -1.000000e-01 8.147450e-04 +242 -1.700000e+00 -1.000000e-01 8.277540e-04 +243 -1.750000e+00 -1.000000e-01 8.396192e-04 +244 -1.800000e+00 -1.000000e-01 8.504421e-04 +245 6.000000e-01 -1.000000e-01 1.605450e-12 +246 5.500000e-01 -1.000000e-01 1.605450e-12 +247 5.000000e-01 -1.000000e-01 1.605450e-12 +248 4.500000e-01 -1.000000e-01 1.605450e-12 +249 4.000000e-01 -1.000000e-01 1.605450e-12 +250 3.500000e-01 -1.000000e-01 1.605450e-12 +251 3.000000e-01 -1.000000e-01 1.605450e-12 +252 2.500000e-01 -1.000000e-01 1.605440e-12 +253 2.000000e-01 -1.000000e-01 1.605440e-12 +254 1.500000e-01 -1.000000e-01 1.605450e-12 +255 1.000000e-01 -1.000000e-01 1.605455e-12 +256 5.000000e-02 -1.000000e-01 1.605528e-12 +257 6.938894e-17 -1.000000e-01 1.605997e-12 +258 -5.000000e-02 -1.000000e-01 1.608763e-12 +259 -1.000000e-01 -1.000000e-01 1.625355e-12 +260 -1.500000e-01 -1.000000e-01 1.724694e-12 +261 -2.000000e-01 -1.000000e-01 2.319397e-12 +262 -2.500000e-01 -1.000000e-01 1.077465e-11 +263 -3.000000e-01 -1.000000e-01 5.643791e-11 +264 -3.500000e-01 -1.000000e-01 3.288995e-10 +265 -4.000000e-01 -1.000000e-01 1.946339e-09 +266 -4.500000e-01 -1.000000e-01 1.143047e-08 +267 -5.000000e-01 -1.000000e-01 6.547438e-08 +268 -5.500000e-01 -1.000000e-01 3.553720e-07 +269 -6.000000e-01 -1.000000e-01 1.754825e-06 +270 -6.500000e-01 -1.000000e-01 7.654593e-06 +271 -7.000000e-01 -1.000000e-01 2.883555e-05 +272 -7.500000e-01 -1.000000e-01 8.429165e-05 +273 -8.000000e-01 -1.000000e-01 1.715501e-04 +274 -8.500000e-01 -1.000000e-01 2.612726e-04 +275 -9.000000e-01 -1.000000e-01 3.375596e-04 +276 -9.500000e-01 -1.000000e-01 4.003045e-04 +277 -1.000000e+00 -1.000000e-01 4.531845e-04 +278 -1.050000e+00 -1.000000e-01 4.991215e-04 +279 -1.100000e+00 -1.000000e-01 5.398909e-04 +280 -1.150000e+00 -1.000000e-01 5.765356e-04 +281 -1.200000e+00 -1.000000e-01 6.097065e-04 +282 -1.250000e+00 -1.000000e-01 6.398523e-04 +283 -1.300000e+00 -1.000000e-01 6.673136e-04 +284 -1.350000e+00 -1.000000e-01 6.923677e-04 +285 -1.400000e+00 -1.000000e-01 7.152502e-04 +286 -1.450000e+00 -1.000000e-01 7.361663e-04 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +287 -1.500000e+00 -1.000000e-01 7.552969e-04 +288 -1.550000e+00 -1.000000e-01 7.728028e-04 +289 -1.600000e+00 -1.000000e-01 7.895454e-04 +290 -1.650000e+00 -1.000000e-01 8.041291e-04 +291 -1.700000e+00 -1.000000e-01 8.174051e-04 +292 -1.750000e+00 -1.000000e-01 8.295213e-04 +293 -1.800000e+00 -1.000000e-01 8.405807e-04 +294 6.000000e-01 -1.000000e-01 1.905456e-12 +295 5.500000e-01 -1.000000e-01 1.905456e-12 +296 5.000000e-01 -1.000000e-01 1.905456e-12 +297 4.500000e-01 -1.000000e-01 1.905456e-12 +298 4.000000e-01 -1.000000e-01 1.905456e-12 +299 3.500000e-01 -1.000000e-01 1.905456e-12 +300 3.000000e-01 -1.000000e-01 1.905456e-12 +301 2.500000e-01 -1.000000e-01 1.905450e-12 +302 2.000000e-01 -1.000000e-01 1.905450e-12 +303 1.500000e-01 -1.000000e-01 1.905450e-12 +304 1.000000e-01 -1.000000e-01 1.905456e-12 +305 5.000000e-02 -1.000000e-01 1.905513e-12 +306 6.938894e-17 -1.000000e-01 1.905784e-12 +307 -5.000000e-02 -1.000000e-01 1.907482e-12 +308 -1.000000e-01 -1.000000e-01 1.917682e-12 +309 -1.500000e-01 -1.000000e-01 1.979164e-12 +310 -2.000000e-01 -1.000000e-01 2.349653e-12 +311 -2.500000e-01 -1.000000e-01 7.670671e-12 +312 -3.000000e-01 -1.000000e-01 3.661008e-11 +313 -3.500000e-01 -1.000000e-01 2.105057e-10 +314 -4.000000e-01 -1.000000e-01 1.251164e-09 +315 -4.500000e-01 -1.000000e-01 7.416967e-09 +316 -5.000000e-01 -1.000000e-01 4.309824e-08 +317 -5.500000e-01 -1.000000e-01 2.392296e-07 +318 -6.000000e-01 -1.000000e-01 1.219303e-06 +319 -6.500000e-01 -1.000000e-01 5.508608e-06 +320 -7.000000e-01 -1.000000e-01 2.164994e-05 +321 -7.500000e-01 -1.000000e-01 6.804211e-05 +322 -8.000000e-01 -1.000000e-01 1.499620e-04 +323 -8.500000e-01 -1.000000e-01 2.404579e-04 +324 -9.000000e-01 -1.000000e-01 3.192332e-04 +325 -9.500000e-01 -1.000000e-01 3.840128e-04 +326 -1.000000e+00 -1.000000e-01 4.382706e-04 +327 -1.050000e+00 -1.000000e-01 4.851582e-04 +328 -1.100000e+00 -1.000000e-01 5.266408e-04 +329 -1.150000e+00 -1.000000e-01 5.638672e-04 +330 -1.200000e+00 -1.000000e-01 5.975408e-04 +331 -1.250000e+00 -1.000000e-01 6.281361e-04 +332 -1.300000e+00 -1.000000e-01 6.560069e-04 +333 -1.350000e+00 -1.000000e-01 6.814376e-04 +334 -1.400000e+00 -1.000000e-01 7.046687e-04 +335 -1.450000e+00 -1.000000e-01 7.259087e-04 +336 -1.500000e+00 -1.000000e-01 7.453413e-04 +337 -1.550000e+00 -1.000000e-01 7.631294e-04 +338 -1.600000e+00 -1.000000e-01 7.801450e-04 +339 -1.650000e+00 -1.000000e-01 7.949756e-04 +340 -1.700000e+00 -1.000000e-01 8.084827e-04 +341 -1.750000e+00 -1.000000e-01 8.208161e-04 +342 -1.800000e+00 -1.000000e-01 8.320800e-04 + + + + diff --git a/tests/bsim4/test13.cir b/tests/bsim4/test13.cir new file mode 100644 index 000000000..9a5437ac0 --- /dev/null +++ b/tests/bsim4/test13.cir @@ -0,0 +1,16 @@ +** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +** Circuit Description ** +m1 2 1 0 3 p1 L=0.13u W=10.0u rgeoMod=1 +vgs 1 0 -1.8 +vds 2 0 -0.1 +vbs 3 0 0.0 + +.dc vgs 0.6 -1.8 -0.05 vbs 0 1.8 0.3 + +.options Temp=-55.0 + +.print dc v(2) i(vds) + +.include modelcard.pmos +.end diff --git a/tests/bsim4/test13.out b/tests/bsim4/test13.out new file mode 100644 index 000000000..9b4a7dc11 --- /dev/null +++ b/tests/bsim4/test13.out @@ -0,0 +1,373 @@ + +No. of Data Rows : 343 + +Circuit: ** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +Doing analysis at TEMP = 218.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. +-------------------------------------------------------------------------------- +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +0 6.000000e-01 -1.000000e-01 1.000140e-13 +1 5.500000e-01 -1.000000e-01 1.000140e-13 +2 5.000000e-01 -1.000000e-01 1.000140e-13 +3 4.500000e-01 -1.000000e-01 1.000140e-13 +4 4.000000e-01 -1.000000e-01 1.000140e-13 +5 3.500000e-01 -1.000000e-01 1.000140e-13 +6 3.000000e-01 -1.000000e-01 1.000140e-13 +7 2.500000e-01 -1.000000e-01 1.000036e-13 +8 2.000000e-01 -1.000000e-01 1.000036e-13 +9 1.500000e-01 -1.000000e-01 1.000036e-13 +10 1.000000e-01 -1.000000e-01 1.000140e-13 +11 5.000000e-02 -1.000000e-01 1.000140e-13 +12 6.938894e-17 -1.000000e-01 1.000557e-13 +13 -5.000000e-02 -1.000000e-01 1.005037e-13 +14 -1.000000e-01 -1.000000e-01 1.053433e-13 +15 -1.500000e-01 -1.000000e-01 1.564269e-13 +16 -2.000000e-01 -1.000000e-01 1.978252e-12 +17 -2.500000e-01 -1.000000e-01 1.994950e-11 +18 -3.000000e-01 -1.000000e-01 2.095691e-10 +19 -3.500000e-01 -1.000000e-01 2.200152e-09 +20 -4.000000e-01 -1.000000e-01 2.275714e-08 +21 -4.500000e-01 -1.000000e-01 2.247340e-07 +22 -5.000000e-01 -1.000000e-01 1.970906e-06 +23 -5.500000e-01 -1.000000e-01 1.397400e-05 +24 -6.000000e-01 -1.000000e-01 7.365232e-05 +25 -6.500000e-01 -1.000000e-01 2.370287e-04 +26 -7.000000e-01 -1.000000e-01 4.527689e-04 +27 -7.500000e-01 -1.000000e-01 6.395102e-04 +28 -8.000000e-01 -1.000000e-01 7.881050e-04 +29 -8.500000e-01 -1.000000e-01 9.103097e-04 +30 -9.000000e-01 -1.000000e-01 1.014445e-03 +31 -9.500000e-01 -1.000000e-01 1.105033e-03 +32 -1.000000e+00 -1.000000e-01 1.184722e-03 +33 -1.050000e+00 -1.000000e-01 1.255310e-03 +34 -1.100000e+00 -1.000000e-01 1.318151e-03 +35 -1.150000e+00 -1.000000e-01 1.374332e-03 +36 -1.200000e+00 -1.000000e-01 1.424749e-03 +37 -1.250000e+00 -1.000000e-01 1.470148e-03 +38 -1.300000e+00 -1.000000e-01 1.511160e-03 +39 -1.350000e+00 -1.000000e-01 1.548316e-03 +40 -1.400000e+00 -1.000000e-01 1.582069e-03 +41 -1.450000e+00 -1.000000e-01 1.614254e-03 +42 -1.500000e+00 -1.000000e-01 1.642148e-03 +43 -1.550000e+00 -1.000000e-01 1.667670e-03 +44 -1.600000e+00 -1.000000e-01 1.691063e-03 +45 -1.650000e+00 -1.000000e-01 1.712509e-03 +46 -1.700000e+00 -1.000000e-01 1.732109e-03 +47 -1.750000e+00 -1.000000e-01 1.750095e-03 +48 -1.800000e+00 -1.000000e-01 1.766627e-03 +49 6.000000e-01 -1.000000e-01 4.000093e-13 +50 5.500000e-01 -1.000000e-01 3.495612e-13 +51 5.000000e-01 -1.000000e-01 3.579380e-13 +52 4.500000e-01 -1.000000e-01 4.000093e-13 +53 4.000000e-01 -1.000000e-01 4.000093e-13 +54 3.500000e-01 -1.000000e-01 4.000093e-13 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +55 3.000000e-01 -1.000000e-01 4.000093e-13 +56 2.500000e-01 -1.000000e-01 4.000041e-13 +57 2.000000e-01 -1.000000e-01 4.000041e-13 +58 1.500000e-01 -1.000000e-01 4.000041e-13 +59 1.000000e-01 -1.000000e-01 4.000041e-13 +60 5.000000e-02 -1.000000e-01 4.000093e-13 +61 6.938894e-17 -1.000000e-01 4.000145e-13 +62 -5.000000e-02 -1.000000e-01 4.000927e-13 +63 -1.000000e-01 -1.000000e-01 4.009887e-13 +64 -1.500000e-01 -1.000000e-01 4.108762e-13 +65 -2.000000e-01 -1.000000e-01 5.193000e-13 +66 -2.500000e-01 -1.000000e-01 4.628199e-12 +67 -3.000000e-01 -1.000000e-01 4.674813e-11 +68 -3.500000e-01 -1.000000e-01 5.073093e-10 +69 -4.000000e-01 -1.000000e-01 5.503024e-09 +70 -4.500000e-01 -1.000000e-01 5.830146e-08 +71 -5.000000e-01 -1.000000e-01 5.751220e-07 +72 -5.500000e-01 -1.000000e-01 4.812646e-06 +73 -6.000000e-01 -1.000000e-01 3.120318e-05 +74 -6.500000e-01 -1.000000e-01 1.369037e-04 +75 -7.000000e-01 -1.000000e-01 3.404264e-04 +76 -7.500000e-01 -1.000000e-01 5.484232e-04 +77 -8.000000e-01 -1.000000e-01 7.160392e-04 +78 -8.500000e-01 -1.000000e-01 8.508939e-04 +79 -9.000000e-01 -1.000000e-01 9.638939e-04 +80 -9.500000e-01 -1.000000e-01 1.061246e-03 +81 -1.000000e+00 -1.000000e-01 1.146382e-03 +82 -1.050000e+00 -1.000000e-01 1.221474e-03 +83 -1.100000e+00 -1.000000e-01 1.288090e-03 +84 -1.150000e+00 -1.000000e-01 1.347463e-03 +85 -1.200000e+00 -1.000000e-01 1.400593e-03 +86 -1.250000e+00 -1.000000e-01 1.448313e-03 +87 -1.300000e+00 -1.000000e-01 1.491317e-03 +88 -1.350000e+00 -1.000000e-01 1.530193e-03 +89 -1.400000e+00 -1.000000e-01 1.565437e-03 +90 -1.450000e+00 -1.000000e-01 1.599012e-03 +91 -1.500000e+00 -1.000000e-01 1.628026e-03 +92 -1.550000e+00 -1.000000e-01 1.654532e-03 +93 -1.600000e+00 -1.000000e-01 1.678791e-03 +94 -1.650000e+00 -1.000000e-01 1.701001e-03 +95 -1.700000e+00 -1.000000e-01 1.721275e-03 +96 -1.750000e+00 -1.000000e-01 1.739859e-03 +97 -1.800000e+00 -1.000000e-01 1.756921e-03 +98 6.000000e-01 -1.000000e-01 7.000202e-13 +99 5.500000e-01 -1.000000e-01 6.547764e-13 +100 5.000000e-01 -1.000000e-01 6.621060e-13 +101 4.500000e-01 -1.000000e-01 7.000202e-13 +102 4.000000e-01 -1.000000e-01 7.000202e-13 +103 3.500000e-01 -1.000000e-01 7.000202e-13 +104 3.000000e-01 -1.000000e-01 7.000202e-13 +105 2.500000e-01 -1.000000e-01 7.000098e-13 +106 2.000000e-01 -1.000000e-01 7.000098e-13 +107 1.500000e-01 -1.000000e-01 7.000098e-13 +108 1.000000e-01 -1.000000e-01 7.000098e-13 +109 5.000000e-02 -1.000000e-01 7.000098e-13 +110 6.938894e-17 -1.000000e-01 7.000098e-13 +111 -5.000000e-02 -1.000000e-01 7.000255e-13 +112 -1.000000e-01 -1.000000e-01 7.002495e-13 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +113 -1.500000e-01 -1.000000e-01 7.028490e-13 +114 -2.000000e-01 -1.000000e-01 7.319332e-13 +115 -2.500000e-01 -1.000000e-01 1.059137e-12 +116 -3.000000e-01 -1.000000e-01 1.397368e-11 +117 -3.500000e-01 -1.000000e-01 1.497285e-10 +118 -4.000000e-01 -1.000000e-01 1.667059e-09 +119 -4.500000e-01 -1.000000e-01 1.838014e-08 +120 -5.000000e-01 -1.000000e-01 1.941441e-07 +121 -5.500000e-01 -1.000000e-01 1.824911e-06 +122 -6.000000e-01 -1.000000e-01 1.373996e-05 +123 -6.500000e-01 -1.000000e-01 7.519044e-05 +124 -7.000000e-01 -1.000000e-01 2.440422e-04 +125 -7.500000e-01 -1.000000e-01 4.626221e-04 +126 -8.000000e-01 -1.000000e-01 6.490223e-04 +127 -8.500000e-01 -1.000000e-01 7.969260e-04 +128 -9.000000e-01 -1.000000e-01 9.186653e-04 +129 -9.500000e-01 -1.000000e-01 1.022421e-03 +130 -1.000000e+00 -1.000000e-01 1.112595e-03 +131 -1.050000e+00 -1.000000e-01 1.191803e-03 +132 -1.100000e+00 -1.000000e-01 1.261848e-03 +133 -1.150000e+00 -1.000000e-01 1.324105e-03 +134 -1.200000e+00 -1.000000e-01 1.379679e-03 +135 -1.250000e+00 -1.000000e-01 1.429481e-03 +136 -1.300000e+00 -1.000000e-01 1.474269e-03 +137 -1.350000e+00 -1.000000e-01 1.514679e-03 +138 -1.400000e+00 -1.000000e-01 1.551250e-03 +139 -1.450000e+00 -1.000000e-01 1.584438e-03 +140 -1.500000e+00 -1.000000e-01 1.616069e-03 +141 -1.550000e+00 -1.000000e-01 1.643440e-03 +142 -1.600000e+00 -1.000000e-01 1.668464e-03 +143 -1.650000e+00 -1.000000e-01 1.691347e-03 +144 -1.700000e+00 -1.000000e-01 1.712213e-03 +145 -1.750000e+00 -1.000000e-01 1.731321e-03 +146 -1.800000e+00 -1.000000e-01 1.748849e-03 +147 6.000000e-01 -1.000000e-01 1.000016e-12 +148 5.500000e-01 -1.000000e-01 9.576681e-13 +149 5.000000e-01 -1.000000e-01 9.643935e-13 +150 4.500000e-01 -1.000000e-01 1.000016e-12 +151 4.000000e-01 -1.000000e-01 1.000016e-12 +152 3.500000e-01 -1.000000e-01 1.000016e-12 +153 3.000000e-01 -1.000000e-01 1.000016e-12 +154 2.500000e-01 -1.000000e-01 1.000010e-12 +155 2.000000e-01 -1.000000e-01 1.000010e-12 +156 1.500000e-01 -1.000000e-01 1.000010e-12 +157 1.000000e-01 -1.000000e-01 1.000010e-12 +158 5.000000e-02 -1.000000e-01 1.000010e-12 +159 6.938894e-17 -1.000000e-01 1.000010e-12 +160 -5.000000e-02 -1.000000e-01 1.000021e-12 +161 -1.000000e-01 -1.000000e-01 1.000083e-12 +162 -1.500000e-01 -1.000000e-01 1.000917e-12 +163 -2.000000e-01 -1.000000e-01 1.010502e-12 +164 -2.500000e-01 -1.000000e-01 1.120119e-12 +165 -3.000000e-01 -1.000000e-01 5.578425e-12 +166 -3.500000e-01 -1.000000e-01 5.336977e-11 +167 -4.000000e-01 -1.000000e-01 5.985739e-10 +168 -4.500000e-01 -1.000000e-01 6.763685e-09 +169 -5.000000e-01 -1.000000e-01 7.448424e-08 +170 -5.500000e-01 -1.000000e-01 7.568568e-07 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +171 -6.000000e-01 -1.000000e-01 6.405911e-06 +172 -6.500000e-01 -1.000000e-01 4.094217e-05 +173 -7.000000e-01 -1.000000e-01 1.677541e-04 +174 -7.500000e-01 -1.000000e-01 3.824803e-04 +175 -8.000000e-01 -1.000000e-01 5.856423e-04 +176 -8.500000e-01 -1.000000e-01 7.469806e-04 +177 -9.000000e-01 -1.000000e-01 8.775063e-04 +178 -9.500000e-01 -1.000000e-01 9.874408e-04 +179 -1.000000e+00 -1.000000e-01 1.082350e-03 +180 -1.050000e+00 -1.000000e-01 1.165377e-03 +181 -1.100000e+00 -1.000000e-01 1.238578e-03 +182 -1.150000e+00 -1.000000e-01 1.303478e-03 +183 -1.200000e+00 -1.000000e-01 1.361283e-03 +184 -1.250000e+00 -1.000000e-01 1.412979e-03 +185 -1.300000e+00 -1.000000e-01 1.459386e-03 +186 -1.350000e+00 -1.000000e-01 1.501186e-03 +187 -1.400000e+00 -1.000000e-01 1.538955e-03 +188 -1.450000e+00 -1.000000e-01 1.573180e-03 +189 -1.500000e+00 -1.000000e-01 1.605778e-03 +190 -1.550000e+00 -1.000000e-01 1.633928e-03 +191 -1.600000e+00 -1.000000e-01 1.659635e-03 +192 -1.650000e+00 -1.000000e-01 1.683119e-03 +193 -1.700000e+00 -1.000000e-01 1.704513e-03 +194 -1.750000e+00 -1.000000e-01 1.724088e-03 +195 -1.800000e+00 -1.000000e-01 1.742030e-03 +196 6.000000e-01 -1.000000e-01 1.300011e-12 +197 5.500000e-01 -1.000000e-01 1.259351e-12 +198 5.000000e-01 -1.000000e-01 1.265712e-12 +199 4.500000e-01 -1.000000e-01 1.300011e-12 +200 4.000000e-01 -1.000000e-01 1.300011e-12 +201 3.500000e-01 -1.000000e-01 1.300011e-12 +202 3.000000e-01 -1.000000e-01 1.300011e-12 +203 2.500000e-01 -1.000000e-01 1.300006e-12 +204 2.000000e-01 -1.000000e-01 1.300006e-12 +205 1.500000e-01 -1.000000e-01 1.300006e-12 +206 1.000000e-01 -1.000000e-01 1.300006e-12 +207 5.000000e-02 -1.000000e-01 1.300006e-12 +208 6.938894e-17 -1.000000e-01 1.300006e-12 +209 -5.000000e-02 -1.000000e-01 1.300011e-12 +210 -1.000000e-01 -1.000000e-01 1.300037e-12 +211 -1.500000e-01 -1.000000e-01 1.300349e-12 +212 -2.000000e-01 -1.000000e-01 1.304022e-12 +213 -2.500000e-01 -1.000000e-01 1.346713e-12 +214 -3.000000e-01 -1.000000e-01 3.122914e-12 +215 -3.500000e-01 -1.000000e-01 2.244580e-11 +216 -4.000000e-01 -1.000000e-01 2.462142e-10 +217 -4.500000e-01 -1.000000e-01 2.822977e-09 +218 -5.000000e-01 -1.000000e-01 3.193633e-08 +219 -5.500000e-01 -1.000000e-01 3.417556e-07 +220 -6.000000e-01 -1.000000e-01 3.165605e-06 +221 -6.500000e-01 -1.000000e-01 2.276255e-05 +222 -7.000000e-01 -1.000000e-01 1.121941e-04 +223 -7.500000e-01 -1.000000e-01 3.096741e-04 +224 -8.000000e-01 -1.000000e-01 5.253813e-04 +225 -8.500000e-01 -1.000000e-01 7.002467e-04 +226 -9.000000e-01 -1.000000e-01 8.396772e-04 +227 -9.500000e-01 -1.000000e-01 9.556465e-04 +228 -1.000000e+00 -1.000000e-01 1.055051e-03 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +229 -1.050000e+00 -1.000000e-01 1.141646e-03 +230 -1.100000e+00 -1.000000e-01 1.217773e-03 +231 -1.150000e+00 -1.000000e-01 1.285111e-03 +232 -1.200000e+00 -1.000000e-01 1.344967e-03 +233 -1.250000e+00 -1.000000e-01 1.398401e-03 +234 -1.300000e+00 -1.000000e-01 1.446286e-03 +235 -1.350000e+00 -1.000000e-01 1.489353e-03 +236 -1.400000e+00 -1.000000e-01 1.528211e-03 +237 -1.450000e+00 -1.000000e-01 1.563379e-03 +238 -1.500000e+00 -1.000000e-01 1.596852e-03 +239 -1.550000e+00 -1.000000e-01 1.625707e-03 +240 -1.600000e+00 -1.000000e-01 1.652030e-03 +241 -1.650000e+00 -1.000000e-01 1.676055e-03 +242 -1.700000e+00 -1.000000e-01 1.697924e-03 +243 -1.750000e+00 -1.000000e-01 1.717917e-03 +244 -1.800000e+00 -1.000000e-01 1.736230e-03 +245 6.000000e-01 -1.000000e-01 1.600006e-12 +246 5.500000e-01 -1.000000e-01 1.560352e-12 +247 5.000000e-01 -1.000000e-01 1.566478e-12 +248 4.500000e-01 -1.000000e-01 1.600006e-12 +249 4.000000e-01 -1.000000e-01 1.600006e-12 +250 3.500000e-01 -1.000000e-01 1.600006e-12 +251 3.000000e-01 -1.000000e-01 1.600006e-12 +252 2.500000e-01 -1.000000e-01 1.600001e-12 +253 2.000000e-01 -1.000000e-01 1.600001e-12 +254 1.500000e-01 -1.000000e-01 1.600001e-12 +255 1.000000e-01 -1.000000e-01 1.600001e-12 +256 5.000000e-02 -1.000000e-01 1.600001e-12 +257 6.938894e-17 -1.000000e-01 1.599996e-12 +258 -5.000000e-02 -1.000000e-01 1.600001e-12 +259 -1.000000e-01 -1.000000e-01 1.600022e-12 +260 -1.500000e-01 -1.000000e-01 1.600152e-12 +261 -2.000000e-01 -1.000000e-01 1.601746e-12 +262 -2.500000e-01 -1.000000e-01 1.620500e-12 +263 -3.000000e-01 -1.000000e-01 1.840546e-12 +264 -3.500000e-01 -1.000000e-01 1.115918e-11 +265 -4.000000e-01 -1.000000e-01 1.135965e-10 +266 -4.500000e-01 -1.000000e-01 1.309090e-09 +267 -5.000000e-01 -1.000000e-01 1.508075e-08 +268 -5.500000e-01 -1.000000e-01 1.671311e-07 +269 -6.000000e-01 -1.000000e-01 1.656125e-06 +270 -6.500000e-01 -1.000000e-01 1.310155e-05 +271 -7.000000e-01 -1.000000e-01 7.433153e-05 +272 -7.500000e-01 -1.000000e-01 2.460842e-04 +273 -8.000000e-01 -1.000000e-01 4.682998e-04 +274 -8.500000e-01 -1.000000e-01 6.562694e-04 +275 -9.000000e-01 -1.000000e-01 8.047150e-04 +276 -9.500000e-01 -1.000000e-01 9.266171e-04 +277 -1.000000e+00 -1.000000e-01 1.030313e-03 +278 -1.050000e+00 -1.000000e-01 1.120257e-03 +279 -1.100000e+00 -1.000000e-01 1.199105e-03 +280 -1.150000e+00 -1.000000e-01 1.268699e-03 +281 -1.200000e+00 -1.000000e-01 1.330446e-03 +282 -1.250000e+00 -1.000000e-01 1.385477e-03 +283 -1.300000e+00 -1.000000e-01 1.434719e-03 +284 -1.350000e+00 -1.000000e-01 1.478943e-03 +285 -1.400000e+00 -1.000000e-01 1.518796e-03 +286 -1.450000e+00 -1.000000e-01 1.554821e-03 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +287 -1.500000e+00 -1.000000e-01 1.587479e-03 +288 -1.550000e+00 -1.000000e-01 1.618587e-03 +289 -1.600000e+00 -1.000000e-01 1.645466e-03 +290 -1.650000e+00 -1.000000e-01 1.669979e-03 +291 -1.700000e+00 -1.000000e-01 1.692276e-03 +292 -1.750000e+00 -1.000000e-01 1.712646e-03 +293 -1.800000e+00 -1.000000e-01 1.731292e-03 +294 6.000000e-01 -1.000000e-01 1.900017e-12 +295 5.500000e-01 -1.000000e-01 1.860941e-12 +296 5.000000e-01 -1.000000e-01 1.866906e-12 +297 4.500000e-01 -1.000000e-01 1.900017e-12 +298 4.000000e-01 -1.000000e-01 1.900017e-12 +299 3.500000e-01 -1.000000e-01 1.900017e-12 +300 3.000000e-01 -1.000000e-01 1.900017e-12 +301 2.500000e-01 -1.000000e-01 1.900012e-12 +302 2.000000e-01 -1.000000e-01 1.900012e-12 +303 1.500000e-01 -1.000000e-01 1.900012e-12 +304 1.000000e-01 -1.000000e-01 1.900012e-12 +305 5.000000e-02 -1.000000e-01 1.900012e-12 +306 6.938894e-17 -1.000000e-01 1.900007e-12 +307 -5.000000e-02 -1.000000e-01 1.900012e-12 +308 -1.000000e-01 -1.000000e-01 1.900017e-12 +309 -1.500000e-01 -1.000000e-01 1.900080e-12 +310 -2.000000e-01 -1.000000e-01 1.900851e-12 +311 -2.500000e-01 -1.000000e-01 1.909951e-12 +312 -3.000000e-01 -1.000000e-01 2.017771e-12 +313 -3.500000e-01 -1.000000e-01 6.650994e-12 +314 -4.000000e-01 -1.000000e-01 5.807508e-11 +315 -4.500000e-01 -1.000000e-01 6.644380e-10 +316 -5.000000e-01 -1.000000e-01 7.748401e-09 +317 -5.500000e-01 -1.000000e-01 8.798682e-08 +318 -6.000000e-01 -1.000000e-01 9.162442e-07 +319 -6.500000e-01 -1.000000e-01 7.841838e-06 +320 -7.000000e-01 -1.000000e-01 4.957594e-05 +321 -7.500000e-01 -1.000000e-01 1.928879e-04 +322 -8.000000e-01 -1.000000e-01 4.148182e-04 +323 -8.500000e-01 -1.000000e-01 6.148280e-04 +324 -9.000000e-01 -1.000000e-01 7.723238e-04 +325 -9.500000e-01 -1.000000e-01 9.000715e-04 +326 -1.000000e+00 -1.000000e-01 1.007875e-03 +327 -1.050000e+00 -1.000000e-01 1.100966e-03 +328 -1.100000e+00 -1.000000e-01 1.182347e-03 +329 -1.150000e+00 -1.000000e-01 1.254030e-03 +330 -1.200000e+00 -1.000000e-01 1.317521e-03 +331 -1.250000e+00 -1.000000e-01 1.374020e-03 +332 -1.300000e+00 -1.000000e-01 1.424506e-03 +333 -1.350000e+00 -1.000000e-01 1.469791e-03 +334 -1.400000e+00 -1.000000e-01 1.510552e-03 +335 -1.450000e+00 -1.000000e-01 1.547358e-03 +336 -1.500000e+00 -1.000000e-01 1.580691e-03 +337 -1.550000e+00 -1.000000e-01 1.612429e-03 +338 -1.600000e+00 -1.000000e-01 1.639812e-03 +339 -1.650000e+00 -1.000000e-01 1.664767e-03 +340 -1.700000e+00 -1.000000e-01 1.687450e-03 +341 -1.750000e+00 -1.000000e-01 1.708159e-03 +342 -1.800000e+00 -1.000000e-01 1.727105e-03 + + + + diff --git a/tests/bsim4/test14.cir b/tests/bsim4/test14.cir new file mode 100644 index 000000000..ba84ca61b --- /dev/null +++ b/tests/bsim4/test14.cir @@ -0,0 +1,16 @@ +** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +** Circuit Description ** +m1 2 1 0 3 p1 L=0.13u W=10.0u rgeoMod=1 +vgs 1 0 -1.8 +vds 2 0 -0.1 +vbs 3 0 0.0 + +.dc vgs 0.6 -1.8 -0.05 vbs 0 1.8 0.3 + +.options Temp=100.0 + +.print dc v(2) i(vds) + +.include modelcard.pmos +.end diff --git a/tests/bsim4/test14.out b/tests/bsim4/test14.out new file mode 100644 index 000000000..2248014d2 --- /dev/null +++ b/tests/bsim4/test14.out @@ -0,0 +1,373 @@ + +No. of Data Rows : 343 + +Circuit: ** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +Doing analysis at TEMP = 373.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. +-------------------------------------------------------------------------------- +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +0 6.000000e-01 -1.000000e-01 8.862897e-11 +1 5.500000e-01 -1.000000e-01 8.862897e-11 +2 5.000000e-01 -1.000000e-01 8.862897e-11 +3 4.500000e-01 -1.000000e-01 8.862897e-11 +4 4.000000e-01 -1.000000e-01 8.862899e-11 +5 3.500000e-01 -1.000000e-01 8.862905e-11 +6 3.000000e-01 -1.000000e-01 8.862929e-11 +7 2.500000e-01 -1.000000e-01 8.863027e-11 +8 2.000000e-01 -1.000000e-01 8.863419e-11 +9 1.500000e-01 -1.000000e-01 8.864972e-11 +10 1.000000e-01 -1.000000e-01 8.871136e-11 +11 5.000000e-02 -1.000000e-01 8.895608e-11 +12 6.938894e-17 -1.000000e-01 8.992748e-11 +13 -5.000000e-02 -1.000000e-01 9.722733e-11 +14 -1.000000e-01 -1.000000e-01 1.227320e-10 +15 -1.500000e-01 -1.000000e-01 2.237541e-10 +16 -2.000000e-01 -1.000000e-01 6.229575e-10 +17 -2.500000e-01 -1.000000e-01 2.193122e-09 +18 -3.000000e-01 -1.000000e-01 8.312678e-09 +19 -3.500000e-01 -1.000000e-01 3.175047e-08 +20 -4.000000e-01 -1.000000e-01 1.187353e-07 +21 -4.500000e-01 -1.000000e-01 4.254085e-07 +22 -5.000000e-01 -1.000000e-01 1.432836e-06 +23 -5.500000e-01 -1.000000e-01 4.496335e-06 +24 -6.000000e-01 -1.000000e-01 1.310337e-05 +25 -6.500000e-01 -1.000000e-01 3.422650e-05 +26 -7.000000e-01 -1.000000e-01 7.383397e-05 +27 -7.500000e-01 -1.000000e-01 1.264975e-04 +28 -8.000000e-01 -1.000000e-01 1.799950e-04 +29 -8.500000e-01 -1.000000e-01 2.269490e-04 +30 -9.000000e-01 -1.000000e-01 2.660718e-04 +31 -9.500000e-01 -1.000000e-01 2.986796e-04 +32 -1.000000e+00 -1.000000e-01 3.264093e-04 +33 -1.050000e+00 -1.000000e-01 3.505164e-04 +34 -1.100000e+00 -1.000000e-01 3.718408e-04 +35 -1.150000e+00 -1.000000e-01 3.909279e-04 +36 -1.200000e+00 -1.000000e-01 4.081394e-04 +37 -1.250000e+00 -1.000000e-01 4.237284e-04 +38 -1.300000e+00 -1.000000e-01 4.378829e-04 +39 -1.350000e+00 -1.000000e-01 4.507515e-04 +40 -1.400000e+00 -1.000000e-01 4.624575e-04 +41 -1.450000e+00 -1.000000e-01 4.731063e-04 +42 -1.500000e+00 -1.000000e-01 4.832583e-04 +43 -1.550000e+00 -1.000000e-01 4.920202e-04 +44 -1.600000e+00 -1.000000e-01 4.999776e-04 +45 -1.650000e+00 -1.000000e-01 5.071829e-04 +46 -1.700000e+00 -1.000000e-01 5.136722e-04 +47 -1.750000e+00 -1.000000e-01 5.195232e-04 +48 -1.800000e+00 -1.000000e-01 5.247911e-04 +49 6.000000e-01 -1.000000e-01 9.306154e-11 +50 5.500000e-01 -1.000000e-01 9.306153e-11 +51 5.000000e-01 -1.000000e-01 9.306154e-11 +52 4.500000e-01 -1.000000e-01 9.306154e-11 +53 4.000000e-01 -1.000000e-01 9.306153e-11 +54 3.500000e-01 -1.000000e-01 9.306156e-11 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +55 3.000000e-01 -1.000000e-01 9.306164e-11 +56 2.500000e-01 -1.000000e-01 9.306199e-11 +57 2.000000e-01 -1.000000e-01 9.306340e-11 +58 1.500000e-01 -1.000000e-01 9.306914e-11 +59 1.000000e-01 -1.000000e-01 9.309237e-11 +60 5.000000e-02 -1.000000e-01 9.318664e-11 +61 6.938894e-17 -1.000000e-01 9.356902e-11 +62 -5.000000e-02 -1.000000e-01 9.653937e-11 +63 -1.000000e-01 -1.000000e-01 1.071610e-10 +64 -1.500000e-01 -1.000000e-01 1.501843e-10 +65 -2.000000e-01 -1.000000e-01 3.241766e-10 +66 -2.500000e-01 -1.000000e-01 1.025588e-09 +67 -3.000000e-01 -1.000000e-01 3.835190e-09 +68 -3.500000e-01 -1.000000e-01 1.494946e-08 +69 -4.000000e-01 -1.000000e-01 5.788919e-08 +70 -4.500000e-01 -1.000000e-01 2.170643e-07 +71 -5.000000e-01 -1.000000e-01 7.708651e-07 +72 -5.500000e-01 -1.000000e-01 2.551472e-06 +73 -6.000000e-01 -1.000000e-01 7.836172e-06 +74 -6.500000e-01 -1.000000e-01 2.197896e-05 +75 -7.000000e-01 -1.000000e-01 5.256613e-05 +76 -7.500000e-01 -1.000000e-01 9.974459e-05 +77 -8.000000e-01 -1.000000e-01 1.526339e-04 +78 -8.500000e-01 -1.000000e-01 2.012714e-04 +79 -9.000000e-01 -1.000000e-01 2.423406e-04 +80 -9.500000e-01 -1.000000e-01 2.764963e-04 +81 -1.000000e+00 -1.000000e-01 3.053579e-04 +82 -1.050000e+00 -1.000000e-01 3.303093e-04 +83 -1.100000e+00 -1.000000e-01 3.523033e-04 +84 -1.150000e+00 -1.000000e-01 3.719569e-04 +85 -1.200000e+00 -1.000000e-01 3.896727e-04 +86 -1.250000e+00 -1.000000e-01 4.057258e-04 +87 -1.300000e+00 -1.000000e-01 4.203160e-04 +88 -1.350000e+00 -1.000000e-01 4.335982e-04 +89 -1.400000e+00 -1.000000e-01 4.456992e-04 +90 -1.450000e+00 -1.000000e-01 4.567265e-04 +91 -1.500000e+00 -1.000000e-01 4.667741e-04 +92 -1.550000e+00 -1.000000e-01 4.763605e-04 +93 -1.600000e+00 -1.000000e-01 4.846538e-04 +94 -1.650000e+00 -1.000000e-01 4.921824e-04 +95 -1.700000e+00 -1.000000e-01 4.989817e-04 +96 -1.750000e+00 -1.000000e-01 5.051308e-04 +97 -1.800000e+00 -1.000000e-01 5.106854e-04 +98 6.000000e-01 -1.000000e-01 9.336192e-11 +99 5.500000e-01 -1.000000e-01 9.336191e-11 +100 5.000000e-01 -1.000000e-01 9.336192e-11 +101 4.500000e-01 -1.000000e-01 9.336192e-11 +102 4.000000e-01 -1.000000e-01 9.336191e-11 +103 3.500000e-01 -1.000000e-01 9.336192e-11 +104 3.000000e-01 -1.000000e-01 9.336195e-11 +105 2.500000e-01 -1.000000e-01 9.336211e-11 +106 2.000000e-01 -1.000000e-01 9.336275e-11 +107 1.500000e-01 -1.000000e-01 9.336537e-11 +108 1.000000e-01 -1.000000e-01 9.337619e-11 +109 5.000000e-02 -1.000000e-01 9.342069e-11 +110 6.938894e-17 -1.000000e-01 9.360382e-11 +111 -5.000000e-02 -1.000000e-01 9.435743e-11 +112 -1.000000e-01 -1.000000e-01 1.003408e-10 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +113 -1.500000e-01 -1.000000e-01 1.220584e-10 +114 -2.000000e-01 -1.000000e-01 2.112427e-10 +115 -2.500000e-01 -1.000000e-01 5.766312e-10 +116 -3.000000e-01 -1.000000e-01 2.066572e-09 +117 -3.500000e-01 -1.000000e-01 8.085015e-09 +118 -4.000000e-01 -1.000000e-01 3.195481e-08 +119 -4.500000e-01 -1.000000e-01 1.235036e-07 +120 -5.000000e-01 -1.000000e-01 4.557679e-07 +121 -5.500000e-01 -1.000000e-01 1.573433e-06 +122 -6.000000e-01 -1.000000e-01 5.034051e-06 +123 -6.500000e-01 -1.000000e-01 1.482331e-05 +124 -7.000000e-01 -1.000000e-01 3.825696e-05 +125 -7.500000e-01 -1.000000e-01 7.943451e-05 +126 -8.000000e-01 -1.000000e-01 1.305234e-04 +127 -8.500000e-01 -1.000000e-01 1.801350e-04 +128 -9.000000e-01 -1.000000e-01 2.228574e-04 +129 -9.500000e-01 -1.000000e-01 2.584303e-04 +130 -1.000000e+00 -1.000000e-01 2.883322e-04 +131 -1.050000e+00 -1.000000e-01 3.140396e-04 +132 -1.100000e+00 -1.000000e-01 3.366118e-04 +133 -1.150000e+00 -1.000000e-01 3.567391e-04 +134 -1.200000e+00 -1.000000e-01 3.748672e-04 +135 -1.250000e+00 -1.000000e-01 3.912944e-04 +136 -1.300000e+00 -1.000000e-01 4.062332e-04 +137 -1.350000e+00 -1.000000e-01 4.198451e-04 +138 -1.400000e+00 -1.000000e-01 4.322603e-04 +139 -1.450000e+00 -1.000000e-01 4.435888e-04 +140 -1.500000e+00 -1.000000e-01 4.539257e-04 +141 -1.550000e+00 -1.000000e-01 4.637956e-04 +142 -1.600000e+00 -1.000000e-01 4.723566e-04 +143 -1.650000e+00 -1.000000e-01 4.801428e-04 +144 -1.700000e+00 -1.000000e-01 4.871891e-04 +145 -1.750000e+00 -1.000000e-01 4.935758e-04 +146 -1.800000e+00 -1.000000e-01 4.993592e-04 +147 6.000000e-01 -1.000000e-01 9.366191e-11 +148 5.500000e-01 -1.000000e-01 9.366191e-11 +149 5.000000e-01 -1.000000e-01 9.366191e-11 +150 4.500000e-01 -1.000000e-01 9.366191e-11 +151 4.000000e-01 -1.000000e-01 9.366191e-11 +152 3.500000e-01 -1.000000e-01 9.366191e-11 +153 3.000000e-01 -1.000000e-01 9.366194e-11 +154 2.500000e-01 -1.000000e-01 9.366200e-11 +155 2.000000e-01 -1.000000e-01 9.366234e-11 +156 1.500000e-01 -1.000000e-01 9.366374e-11 +157 1.000000e-01 -1.000000e-01 9.366954e-11 +158 5.000000e-02 -1.000000e-01 9.369370e-11 +159 6.938894e-17 -1.000000e-01 9.379411e-11 +160 -5.000000e-02 -1.000000e-01 9.421170e-11 +161 -1.000000e-01 -1.000000e-01 9.758134e-11 +162 -1.500000e-01 -1.000000e-01 1.099515e-10 +163 -2.000000e-01 -1.000000e-01 1.613122e-10 +164 -2.500000e-01 -1.000000e-01 3.741797e-10 +165 -3.000000e-01 -1.000000e-01 1.253190e-09 +166 -3.500000e-01 -1.000000e-01 4.856129e-09 +167 -4.000000e-01 -1.000000e-01 1.940927e-08 +168 -4.500000e-01 -1.000000e-01 7.658995e-08 +169 -5.000000e-01 -1.000000e-01 2.907678e-07 +170 -5.500000e-01 -1.000000e-01 1.038041e-06 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +171 -6.000000e-01 -1.000000e-01 3.435202e-06 +172 -6.500000e-01 -1.000000e-01 1.048667e-05 +173 -7.000000e-01 -1.000000e-01 2.860362e-05 +174 -7.500000e-01 -1.000000e-01 6.405818e-05 +175 -8.000000e-01 -1.000000e-01 1.125545e-04 +176 -8.500000e-01 -1.000000e-01 1.624807e-04 +177 -9.000000e-01 -1.000000e-01 2.065353e-04 +178 -9.500000e-01 -1.000000e-01 2.433783e-04 +179 -1.000000e+00 -1.000000e-01 2.742314e-04 +180 -1.050000e+00 -1.000000e-01 3.006206e-04 +181 -1.100000e+00 -1.000000e-01 3.237003e-04 +182 -1.150000e+00 -1.000000e-01 3.442320e-04 +183 -1.200000e+00 -1.000000e-01 3.627045e-04 +184 -1.250000e+00 -1.000000e-01 3.794402e-04 +185 -1.300000e+00 -1.000000e-01 3.946642e-04 +186 -1.350000e+00 -1.000000e-01 4.085449e-04 +187 -1.400000e+00 -1.000000e-01 4.212160e-04 +188 -1.450000e+00 -1.000000e-01 4.327895e-04 +189 -1.500000e+00 -1.000000e-01 4.433618e-04 +190 -1.550000e+00 -1.000000e-01 4.534626e-04 +191 -1.600000e+00 -1.000000e-01 4.622416e-04 +192 -1.650000e+00 -1.000000e-01 4.702378e-04 +193 -1.700000e+00 -1.000000e-01 4.774857e-04 +194 -1.750000e+00 -1.000000e-01 4.840662e-04 +195 -1.800000e+00 -1.000000e-01 4.900363e-04 +196 6.000000e-01 -1.000000e-01 9.396191e-11 +197 5.500000e-01 -1.000000e-01 9.396190e-11 +198 5.000000e-01 -1.000000e-01 9.396191e-11 +199 4.500000e-01 -1.000000e-01 9.396191e-11 +200 4.000000e-01 -1.000000e-01 9.396190e-11 +201 3.500000e-01 -1.000000e-01 9.396192e-11 +202 3.000000e-01 -1.000000e-01 9.396192e-11 +203 2.500000e-01 -1.000000e-01 9.396197e-11 +204 2.000000e-01 -1.000000e-01 9.396215e-11 +205 1.500000e-01 -1.000000e-01 9.396298e-11 +206 1.000000e-01 -1.000000e-01 9.396646e-11 +207 5.000000e-02 -1.000000e-01 9.398099e-11 +208 6.938894e-17 -1.000000e-01 9.404192e-11 +209 -5.000000e-02 -1.000000e-01 9.429738e-11 +210 -1.000000e-01 -1.000000e-01 9.536812e-11 +211 -1.500000e-01 -1.000000e-01 1.041116e-10 +212 -2.000000e-01 -1.000000e-01 1.364640e-10 +213 -2.500000e-01 -1.000000e-01 2.717200e-10 +214 -3.000000e-01 -1.000000e-01 8.355156e-10 +215 -3.500000e-01 -1.000000e-01 3.171480e-09 +216 -4.000000e-01 -1.000000e-01 1.273388e-08 +217 -4.500000e-01 -1.000000e-01 5.097803e-08 +218 -5.000000e-01 -1.000000e-01 1.976898e-07 +219 -5.500000e-01 -1.000000e-01 7.248722e-07 +220 -6.000000e-01 -1.000000e-01 2.467869e-06 +221 -6.500000e-01 -1.000000e-01 7.752447e-06 +222 -7.000000e-01 -1.000000e-01 2.202313e-05 +223 -7.500000e-01 -1.000000e-01 5.244746e-05 +224 -8.000000e-01 -1.000000e-01 9.795355e-05 +225 -8.500000e-01 -1.000000e-01 1.475558e-04 +226 -9.000000e-01 -1.000000e-01 1.927224e-04 +227 -9.500000e-01 -1.000000e-01 2.306813e-04 +228 -1.000000e+00 -1.000000e-01 2.623970e-04 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +229 -1.050000e+00 -1.000000e-01 2.894014e-04 +230 -1.100000e+00 -1.000000e-01 3.129295e-04 +231 -1.150000e+00 -1.000000e-01 3.338102e-04 +232 -1.200000e+00 -1.000000e-01 3.525740e-04 +233 -1.250000e+00 -1.000000e-01 3.695672e-04 +234 -1.300000e+00 -1.000000e-01 3.850276e-04 +235 -1.350000e+00 -1.000000e-01 3.991301e-04 +236 -1.400000e+00 -1.000000e-01 4.120122e-04 +237 -1.450000e+00 -1.000000e-01 4.237876e-04 +238 -1.500000e+00 -1.000000e-01 4.345539e-04 +239 -1.550000e+00 -1.000000e-01 4.443968e-04 +240 -1.600000e+00 -1.000000e-01 4.538042e-04 +241 -1.650000e+00 -1.000000e-01 4.619734e-04 +242 -1.700000e+00 -1.000000e-01 4.693877e-04 +243 -1.750000e+00 -1.000000e-01 4.761285e-04 +244 -1.800000e+00 -1.000000e-01 4.822530e-04 +245 6.000000e-01 -1.000000e-01 9.426191e-11 +246 5.500000e-01 -1.000000e-01 9.426190e-11 +247 5.000000e-01 -1.000000e-01 9.426190e-11 +248 4.500000e-01 -1.000000e-01 9.426190e-11 +249 4.000000e-01 -1.000000e-01 9.426191e-11 +250 3.500000e-01 -1.000000e-01 9.426190e-11 +251 3.000000e-01 -1.000000e-01 9.426192e-11 +252 2.500000e-01 -1.000000e-01 9.426195e-11 +253 2.000000e-01 -1.000000e-01 9.426206e-11 +254 1.500000e-01 -1.000000e-01 9.426260e-11 +255 1.000000e-01 -1.000000e-01 9.426484e-11 +256 5.000000e-02 -1.000000e-01 9.427435e-11 +257 6.938894e-17 -1.000000e-01 9.431441e-11 +258 -5.000000e-02 -1.000000e-01 9.448344e-11 +259 -1.000000e-01 -1.000000e-01 9.519643e-11 +260 -1.500000e-01 -1.000000e-01 1.010761e-10 +261 -2.000000e-01 -1.000000e-01 1.229826e-10 +262 -2.500000e-01 -1.000000e-01 2.151913e-10 +263 -3.000000e-01 -1.000000e-01 6.023589e-10 +264 -3.500000e-01 -1.000000e-01 2.219807e-09 +265 -4.000000e-01 -1.000000e-01 8.908286e-09 +266 -4.500000e-01 -1.000000e-01 3.601956e-08 +267 -5.000000e-01 -1.000000e-01 1.419522e-07 +268 -5.500000e-01 -1.000000e-01 5.317247e-07 +269 -6.000000e-01 -1.000000e-01 1.853993e-06 +270 -6.500000e-01 -1.000000e-01 5.963745e-06 +271 -7.000000e-01 -1.000000e-01 1.746966e-05 +272 -7.500000e-01 -1.000000e-01 4.368956e-05 +273 -8.000000e-01 -1.000000e-01 8.612477e-05 +274 -8.500000e-01 -1.000000e-01 1.351917e-04 +275 -9.000000e-01 -1.000000e-01 1.809926e-04 +276 -9.500000e-01 -1.000000e-01 2.199121e-04 +277 -1.000000e+00 -1.000000e-01 2.524010e-04 +278 -1.050000e+00 -1.000000e-01 2.799577e-04 +279 -1.100000e+00 -1.000000e-01 3.038823e-04 +280 -1.150000e+00 -1.000000e-01 3.250650e-04 +281 -1.200000e+00 -1.000000e-01 3.440765e-04 +282 -1.250000e+00 -1.000000e-01 3.612858e-04 +283 -1.300000e+00 -1.000000e-01 3.769431e-04 +284 -1.350000e+00 -1.000000e-01 3.912297e-04 +285 -1.400000e+00 -1.000000e-01 4.042867e-04 +286 -1.450000e+00 -1.000000e-01 4.162294e-04 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +287 -1.500000e+00 -1.000000e-01 4.271565e-04 +288 -1.550000e+00 -1.000000e-01 4.371543e-04 +289 -1.600000e+00 -1.000000e-01 4.467138e-04 +290 -1.650000e+00 -1.000000e-01 4.550270e-04 +291 -1.700000e+00 -1.000000e-01 4.625795e-04 +292 -1.750000e+00 -1.000000e-01 4.694536e-04 +293 -1.800000e+00 -1.000000e-01 4.757065e-04 +294 6.000000e-01 -1.000000e-01 9.456192e-11 +295 5.500000e-01 -1.000000e-01 9.456191e-11 +296 5.000000e-01 -1.000000e-01 9.456191e-11 +297 4.500000e-01 -1.000000e-01 9.456191e-11 +298 4.000000e-01 -1.000000e-01 9.456192e-11 +299 3.500000e-01 -1.000000e-01 9.456191e-11 +300 3.000000e-01 -1.000000e-01 9.456191e-11 +301 2.500000e-01 -1.000000e-01 9.456193e-11 +302 2.000000e-01 -1.000000e-01 9.456202e-11 +303 1.500000e-01 -1.000000e-01 9.456239e-11 +304 1.000000e-01 -1.000000e-01 9.456395e-11 +305 5.000000e-02 -1.000000e-01 9.457058e-11 +306 6.938894e-17 -1.000000e-01 9.459873e-11 +307 -5.000000e-02 -1.000000e-01 9.471806e-11 +308 -1.000000e-01 -1.000000e-01 9.522397e-11 +309 -1.500000e-01 -1.000000e-01 9.942910e-11 +310 -2.000000e-01 -1.000000e-01 1.151843e-10 +311 -2.500000e-01 -1.000000e-01 1.818628e-10 +312 -3.000000e-01 -1.000000e-01 4.634621e-10 +313 -3.500000e-01 -1.000000e-01 1.647568e-09 +314 -4.000000e-01 -1.000000e-01 6.582848e-09 +315 -4.500000e-01 -1.000000e-01 2.679629e-08 +316 -5.000000e-01 -1.000000e-01 1.069168e-07 +317 -5.500000e-01 -1.000000e-01 4.073854e-07 +318 -6.000000e-01 -1.000000e-01 1.449109e-06 +319 -6.500000e-01 -1.000000e-01 4.755609e-06 +320 -7.000000e-01 -1.000000e-01 1.426667e-05 +321 -7.500000e-01 -1.000000e-01 3.708092e-05 +322 -8.000000e-01 -1.000000e-01 7.658575e-05 +323 -8.500000e-01 -1.000000e-01 1.247626e-04 +324 -9.000000e-01 -1.000000e-01 1.710460e-04 +325 -9.500000e-01 -1.000000e-01 2.107759e-04 +326 -1.000000e+00 -1.000000e-01 2.439482e-04 +327 -1.050000e+00 -1.000000e-01 2.719960e-04 +328 -1.100000e+00 -1.000000e-01 2.962692e-04 +329 -1.150000e+00 -1.000000e-01 3.177127e-04 +330 -1.200000e+00 -1.000000e-01 3.369346e-04 +331 -1.250000e+00 -1.000000e-01 3.543251e-04 +332 -1.300000e+00 -1.000000e-01 3.701464e-04 +333 -1.350000e+00 -1.000000e-01 3.845859e-04 +334 -1.400000e+00 -1.000000e-01 3.977878e-04 +335 -1.450000e+00 -1.000000e-01 4.098691e-04 +336 -1.500000e+00 -1.000000e-01 4.209295e-04 +337 -1.550000e+00 -1.000000e-01 4.310558e-04 +338 -1.600000e+00 -1.000000e-01 4.407415e-04 +339 -1.650000e+00 -1.000000e-01 4.491743e-04 +340 -1.700000e+00 -1.000000e-01 4.568418e-04 +341 -1.750000e+00 -1.000000e-01 4.638267e-04 +342 -1.800000e+00 -1.000000e-01 4.701866e-04 + + + + diff --git a/tests/bsim4/test2.cir b/tests/bsim4/test2.cir new file mode 100644 index 000000000..c69a10d09 --- /dev/null +++ b/tests/bsim4/test2.cir @@ -0,0 +1,15 @@ +** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +** Circuit Description ** +m1 2 1 0 0 n1 L=0.13u W=10.0u rgeoMod=1 +vgs 1 0 1.8 +vds 2 0 1.8 + +.dc vds 0 1.8 0.05 vgs 0 1.8 0.3 + +.options Temp=-55.0 + +.print dc v(1) i(vds) + +.include modelcard.nmos +.end diff --git a/tests/bsim4/test2.out b/tests/bsim4/test2.out new file mode 100644 index 000000000..05cb622de --- /dev/null +++ b/tests/bsim4/test2.out @@ -0,0 +1,286 @@ + +No. of Data Rows : 259 + +Circuit: ** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +Doing analysis at TEMP = 218.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. +-------------------------------------------------------------------------------- +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 0.000000e+00 2.251601e-34 +1 5.000000e-02 0.000000e+00 -5.028052e-14 +2 1.000000e-01 0.000000e+00 -1.001808e-13 +3 1.500000e-01 0.000000e+00 -1.502086e-13 +4 2.000000e-01 0.000000e+00 -2.002469e-13 +5 2.500000e-01 0.000000e+00 -2.502817e-13 +6 3.000000e-01 0.000000e+00 -3.003270e-13 +7 3.500000e-01 0.000000e+00 -3.503861e-13 +8 4.000000e-01 0.000000e+00 -4.004452e-13 +9 4.500000e-01 0.000000e+00 -4.504766e-13 +10 5.000000e-01 0.000000e+00 -5.004940e-13 +11 5.500000e-01 0.000000e+00 -5.506156e-13 +12 6.000000e-01 0.000000e+00 -6.006539e-13 +13 6.500000e-01 0.000000e+00 -6.507616e-13 +14 7.000000e-01 0.000000e+00 -7.008277e-13 +15 7.500000e-01 0.000000e+00 -7.509354e-13 +16 8.000000e-01 0.000000e+00 -8.009459e-13 +17 8.500000e-01 0.000000e+00 -8.510536e-13 +18 9.000000e-01 0.000000e+00 -9.012030e-13 +19 9.500000e-01 0.000000e+00 -9.513524e-13 +20 1.000000e+00 0.000000e+00 -1.001405e-12 +21 1.050000e+00 0.000000e+00 -1.051457e-12 +22 1.100000e+00 0.000000e+00 -1.101648e-12 +23 1.150000e+00 0.000000e+00 -1.151756e-12 +24 1.200000e+00 0.000000e+00 -1.201863e-12 +25 1.250000e+00 0.000000e+00 -1.251915e-12 +26 1.300000e+00 0.000000e+00 -1.302190e-12 +27 1.350000e+00 0.000000e+00 -1.352325e-12 +28 1.400000e+00 0.000000e+00 -1.403017e-12 +29 1.450000e+00 0.000000e+00 -1.462876e-12 +30 1.500000e+00 0.000000e+00 -1.614505e-12 +31 1.550000e+00 0.000000e+00 -3.431067e-12 +32 1.600000e+00 0.000000e+00 -1.127998e-11 +33 1.650000e+00 0.000000e+00 -4.291980e-11 +34 1.700000e+00 0.000000e+00 -1.519840e-10 +35 1.750000e+00 0.000000e+00 -4.808186e-10 +36 1.800000e+00 0.000000e+00 -1.365384e-09 +37 0.000000e+00 3.000000e-01 1.891504e-18 +38 5.000000e-02 3.000000e-01 -1.602532e-10 +39 1.000000e-01 3.000000e-01 -2.112590e-10 +40 1.500000e-01 3.000000e-01 -2.567684e-10 +41 2.000000e-01 3.000000e-01 -3.026839e-10 +42 2.500000e-01 3.000000e-01 -3.542990e-10 +43 3.000000e-01 3.000000e-01 -4.081028e-10 +44 3.500000e-01 3.000000e-01 -4.656505e-10 +45 4.000000e-01 3.000000e-01 -5.271871e-10 +46 4.500000e-01 3.000000e-01 -5.929510e-10 +47 5.000000e-01 3.000000e-01 -6.631850e-10 +48 5.500000e-01 3.000000e-01 -7.381394e-10 +49 6.000000e-01 3.000000e-01 -8.180751e-10 +50 6.500000e-01 3.000000e-01 -9.032639e-10 +51 7.000000e-01 3.000000e-01 -9.939905e-10 +52 7.500000e-01 3.000000e-01 -1.090553e-09 +53 8.000000e-01 3.000000e-01 -1.193262e-09 +54 8.500000e-01 3.000000e-01 -1.302444e-09 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +55 9.000000e-01 3.000000e-01 -1.418441e-09 +56 9.500000e-01 3.000000e-01 -1.541611e-09 +57 1.000000e+00 3.000000e-01 -1.672328e-09 +58 1.050000e+00 3.000000e-01 -1.810983e-09 +59 1.100000e+00 3.000000e-01 -1.957988e-09 +60 1.150000e+00 3.000000e-01 -2.113773e-09 +61 1.200000e+00 3.000000e-01 -2.278791e-09 +62 1.250000e+00 3.000000e-01 -2.453524e-09 +63 1.300000e+00 3.000000e-01 -2.638494e-09 +64 1.350000e+00 3.000000e-01 -2.834287e-09 +65 1.400000e+00 3.000000e-01 -3.041603e-09 +66 1.450000e+00 3.000000e-01 -3.261346e-09 +67 1.500000e+00 3.000000e-01 -3.494785e-09 +68 1.550000e+00 3.000000e-01 -3.743827e-09 +69 1.600000e+00 3.000000e-01 -4.011471e-09 +70 1.650000e+00 3.000000e-01 -4.302511e-09 +71 1.700000e+00 3.000000e-01 -4.624621e-09 +72 1.750000e+00 3.000000e-01 -4.989975e-09 +73 1.800000e+00 3.000000e-01 -5.417700e-09 +74 0.000000e+00 6.000000e-01 1.314361e-17 +75 5.000000e-02 6.000000e-01 -4.383438e-05 +76 1.000000e-01 6.000000e-01 -5.690885e-05 +77 1.500000e-01 6.000000e-01 -6.568577e-05 +78 2.000000e-01 6.000000e-01 -7.406846e-05 +79 2.500000e-01 6.000000e-01 -8.234394e-05 +80 3.000000e-01 6.000000e-01 -9.105090e-05 +81 3.500000e-01 6.000000e-01 -9.993850e-05 +82 4.000000e-01 6.000000e-01 -1.091055e-04 +83 4.500000e-01 6.000000e-01 -1.185630e-04 +84 5.000000e-01 6.000000e-01 -1.283180e-04 +85 5.500000e-01 6.000000e-01 -1.383757e-04 +86 6.000000e-01 6.000000e-01 -1.487401e-04 +87 6.500000e-01 6.000000e-01 -1.592591e-04 +88 7.000000e-01 6.000000e-01 -1.702454e-04 +89 7.500000e-01 6.000000e-01 -1.815475e-04 +90 8.000000e-01 6.000000e-01 -1.931675e-04 +91 8.500000e-01 6.000000e-01 -2.051076e-04 +92 9.000000e-01 6.000000e-01 -2.173695e-04 +93 9.500000e-01 6.000000e-01 -2.299548e-04 +94 1.000000e+00 6.000000e-01 -2.428650e-04 +95 1.050000e+00 6.000000e-01 -2.561011e-04 +96 1.100000e+00 6.000000e-01 -2.696644e-04 +97 1.150000e+00 6.000000e-01 -2.835557e-04 +98 1.200000e+00 6.000000e-01 -2.977760e-04 +99 1.250000e+00 6.000000e-01 -3.123262e-04 +100 1.300000e+00 6.000000e-01 -3.272086e-04 +101 1.350000e+00 6.000000e-01 -3.424273e-04 +102 1.400000e+00 6.000000e-01 -3.579918e-04 +103 1.450000e+00 6.000000e-01 -3.739224e-04 +104 1.500000e+00 6.000000e-01 -3.902598e-04 +105 1.550000e+00 6.000000e-01 -4.070823e-04 +106 1.600000e+00 6.000000e-01 -4.245326e-04 +107 1.650000e+00 6.000000e-01 -4.433914e-04 +108 1.700000e+00 6.000000e-01 -4.632834e-04 +109 1.750000e+00 6.000000e-01 -4.853120e-04 +110 1.800000e+00 6.000000e-01 -5.106203e-04 +111 0.000000e+00 9.000000e-01 3.929327e-17 +112 5.000000e-02 9.000000e-01 -5.608116e-04 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +113 1.000000e-01 9.000000e-01 -9.872410e-04 +114 1.500000e-01 9.000000e-01 -1.292086e-03 +115 2.000000e-01 9.000000e-01 -1.490713e-03 +116 2.500000e-01 9.000000e-01 -1.611278e-03 +117 3.000000e-01 9.000000e-01 -1.689343e-03 +118 3.500000e-01 9.000000e-01 -1.748402e-03 +119 4.000000e-01 9.000000e-01 -1.798945e-03 +120 4.500000e-01 9.000000e-01 -1.846954e-03 +121 5.000000e-01 9.000000e-01 -1.890374e-03 +122 5.500000e-01 9.000000e-01 -1.932876e-03 +123 6.000000e-01 9.000000e-01 -1.974780e-03 +124 6.500000e-01 9.000000e-01 -2.016297e-03 +125 7.000000e-01 9.000000e-01 -2.057568e-03 +126 7.500000e-01 9.000000e-01 -2.098688e-03 +127 8.000000e-01 9.000000e-01 -2.139722e-03 +128 8.500000e-01 9.000000e-01 -2.180716e-03 +129 9.000000e-01 9.000000e-01 -2.221701e-03 +130 9.500000e-01 9.000000e-01 -2.262700e-03 +131 1.000000e+00 9.000000e-01 -2.303730e-03 +132 1.050000e+00 9.000000e-01 -2.344803e-03 +133 1.100000e+00 9.000000e-01 -2.385927e-03 +134 1.150000e+00 9.000000e-01 -2.427107e-03 +135 1.200000e+00 9.000000e-01 -2.468348e-03 +136 1.250000e+00 9.000000e-01 -2.509652e-03 +137 1.300000e+00 9.000000e-01 -2.551021e-03 +138 1.350000e+00 9.000000e-01 -2.592456e-03 +139 1.400000e+00 9.000000e-01 -2.633961e-03 +140 1.450000e+00 9.000000e-01 -2.675545e-03 +141 1.500000e+00 9.000000e-01 -2.717232e-03 +142 1.550000e+00 9.000000e-01 -2.759077e-03 +143 1.600000e+00 9.000000e-01 -2.801197e-03 +144 1.650000e+00 9.000000e-01 -2.844178e-03 +145 1.700000e+00 9.000000e-01 -2.888052e-03 +146 1.750000e+00 9.000000e-01 -2.933882e-03 +147 1.800000e+00 9.000000e-01 -2.983142e-03 +148 0.000000e+00 1.200000e+00 7.736934e-17 +149 5.000000e-02 1.200000e+00 -7.502740e-04 +150 1.000000e-01 1.200000e+00 -1.394897e-03 +151 1.500000e-01 1.200000e+00 -1.939530e-03 +152 2.000000e-01 1.200000e+00 -2.388654e-03 +153 2.500000e-01 1.200000e+00 -2.745385e-03 +154 3.000000e-01 1.200000e+00 -3.013158e-03 +155 3.500000e-01 1.200000e+00 -3.201947e-03 +156 4.000000e-01 1.200000e+00 -3.332833e-03 +157 4.500000e-01 1.200000e+00 -3.429215e-03 +158 5.000000e-01 1.200000e+00 -3.507025e-03 +159 5.500000e-01 1.200000e+00 -3.574790e-03 +160 6.000000e-01 1.200000e+00 -3.639194e-03 +161 6.500000e-01 1.200000e+00 -3.696875e-03 +162 7.000000e-01 1.200000e+00 -3.752734e-03 +163 7.500000e-01 1.200000e+00 -3.807321e-03 +164 8.000000e-01 1.200000e+00 -3.860996e-03 +165 8.500000e-01 1.200000e+00 -3.914001e-03 +166 9.000000e-01 1.200000e+00 -3.966506e-03 +167 9.500000e-01 1.200000e+00 -4.018630e-03 +168 1.000000e+00 1.200000e+00 -4.070458e-03 +169 1.050000e+00 1.200000e+00 -4.122052e-03 +170 1.100000e+00 1.200000e+00 -4.173460e-03 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +171 1.150000e+00 1.200000e+00 -4.224716e-03 +172 1.200000e+00 1.200000e+00 -4.275846e-03 +173 1.250000e+00 1.200000e+00 -4.326871e-03 +174 1.300000e+00 1.200000e+00 -4.377806e-03 +175 1.350000e+00 1.200000e+00 -4.428663e-03 +176 1.400000e+00 1.200000e+00 -4.479450e-03 +177 1.450000e+00 1.200000e+00 -4.530176e-03 +178 1.500000e+00 1.200000e+00 -4.580851e-03 +179 1.550000e+00 1.200000e+00 -4.631488e-03 +180 1.600000e+00 1.200000e+00 -4.682121e-03 +181 1.650000e+00 1.200000e+00 -4.732818e-03 +182 1.700000e+00 1.200000e+00 -4.783727e-03 +183 1.750000e+00 1.200000e+00 -4.835527e-03 +184 1.800000e+00 1.200000e+00 -4.888404e-03 +185 0.000000e+00 1.500000e+00 1.277867e-16 +186 5.000000e-02 1.500000e+00 -8.474121e-04 +187 1.000000e-01 1.500000e+00 -1.610267e-03 +188 1.500000e-01 1.500000e+00 -2.291933e-03 +189 2.000000e-01 1.500000e+00 -2.895362e-03 +190 2.500000e-01 1.500000e+00 -3.422837e-03 +191 3.000000e-01 1.500000e+00 -3.875655e-03 +192 3.500000e-01 1.500000e+00 -4.253941e-03 +193 4.000000e-01 1.500000e+00 -4.557499e-03 +194 4.500000e-01 1.500000e+00 -4.789495e-03 +195 5.000000e-01 1.500000e+00 -4.961318e-03 +196 5.500000e-01 1.500000e+00 -5.090703e-03 +197 6.000000e-01 1.500000e+00 -5.193835e-03 +198 6.500000e-01 1.500000e+00 -5.281455e-03 +199 7.000000e-01 1.500000e+00 -5.363671e-03 +200 7.500000e-01 1.500000e+00 -5.434773e-03 +201 8.000000e-01 1.500000e+00 -5.502675e-03 +202 8.500000e-01 1.500000e+00 -5.568316e-03 +203 9.000000e-01 1.500000e+00 -5.632310e-03 +204 9.500000e-01 1.500000e+00 -5.695066e-03 +205 1.000000e+00 1.500000e+00 -5.756872e-03 +206 1.050000e+00 1.500000e+00 -5.817929e-03 +207 1.100000e+00 1.500000e+00 -5.878382e-03 +208 1.150000e+00 1.500000e+00 -5.938340e-03 +209 1.200000e+00 1.500000e+00 -5.997883e-03 +210 1.250000e+00 1.500000e+00 -6.057071e-03 +211 1.300000e+00 1.500000e+00 -6.115952e-03 +212 1.350000e+00 1.500000e+00 -6.174561e-03 +213 1.400000e+00 1.500000e+00 -6.232926e-03 +214 1.450000e+00 1.500000e+00 -6.291071e-03 +215 1.500000e+00 1.500000e+00 -6.349011e-03 +216 1.550000e+00 1.500000e+00 -6.406764e-03 +217 1.600000e+00 1.500000e+00 -6.464343e-03 +218 1.650000e+00 1.500000e+00 -6.521770e-03 +219 1.700000e+00 1.500000e+00 -6.579080e-03 +220 1.750000e+00 1.500000e+00 -6.636350e-03 +221 1.800000e+00 1.500000e+00 -6.693743e-03 +222 0.000000e+00 1.800000e+00 1.891469e-16 +223 5.000000e-02 1.800000e+00 -9.036920e-04 +224 1.000000e-01 1.800000e+00 -1.737519e-03 +225 1.500000e-01 1.800000e+00 -2.503695e-03 +226 2.000000e-01 1.800000e+00 -3.204279e-03 +227 2.500000e-01 1.800000e+00 -3.841077e-03 +228 3.000000e-01 1.800000e+00 -4.415505e-03 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +229 3.500000e-01 1.800000e+00 -4.928401e-03 +230 4.000000e-01 1.800000e+00 -5.379768e-03 +231 4.500000e-01 1.800000e+00 -5.768612e-03 +232 5.000000e-01 1.800000e+00 -6.093435e-03 +233 5.500000e-01 1.800000e+00 -6.354520e-03 +234 6.000000e-01 1.800000e+00 -6.557754e-03 +235 6.500000e-01 1.800000e+00 -6.715491e-03 +236 7.000000e-01 1.800000e+00 -6.841903e-03 +237 7.500000e-01 1.800000e+00 -6.948287e-03 +238 8.000000e-01 1.800000e+00 -7.047410e-03 +239 8.500000e-01 1.800000e+00 -7.131196e-03 +240 9.000000e-01 1.800000e+00 -7.210319e-03 +241 9.500000e-01 1.800000e+00 -7.286144e-03 +242 1.000000e+00 1.800000e+00 -7.359549e-03 +243 1.050000e+00 1.800000e+00 -7.431125e-03 +244 1.100000e+00 1.800000e+00 -7.501281e-03 +245 1.150000e+00 1.800000e+00 -7.570308e-03 +246 1.200000e+00 1.800000e+00 -7.638416e-03 +247 1.250000e+00 1.800000e+00 -7.705759e-03 +248 1.300000e+00 1.800000e+00 -7.772453e-03 +249 1.350000e+00 1.800000e+00 -7.838588e-03 +250 1.400000e+00 1.800000e+00 -7.904230e-03 +251 1.450000e+00 1.800000e+00 -7.969434e-03 +252 1.500000e+00 1.800000e+00 -8.034241e-03 +253 1.550000e+00 1.800000e+00 -8.098684e-03 +254 1.600000e+00 1.800000e+00 -8.162790e-03 +255 1.650000e+00 1.800000e+00 -8.226581e-03 +256 1.700000e+00 1.800000e+00 -8.290079e-03 +257 1.750000e+00 1.800000e+00 -8.353309e-03 +258 1.800000e+00 1.800000e+00 -8.416310e-03 + + + + diff --git a/tests/bsim4/test3.cir b/tests/bsim4/test3.cir new file mode 100644 index 000000000..f4cba1117 --- /dev/null +++ b/tests/bsim4/test3.cir @@ -0,0 +1,15 @@ +** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +** Circuit Description ** +m1 2 1 0 0 n1 L=0.13u W=10.0u rgeoMod=1 +vgs 1 0 1.8 +vds 2 0 1.8 + +.dc vds 0 1.8 0.05 vgs 0 1.8 0.3 + +.options Temp=100.0 + +.print dc v(1) i(vds) + +.include modelcard.nmos +.end diff --git a/tests/bsim4/test3.out b/tests/bsim4/test3.out new file mode 100644 index 000000000..b23b89858 --- /dev/null +++ b/tests/bsim4/test3.out @@ -0,0 +1,286 @@ + +No. of Data Rows : 259 + +Circuit: ** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +Doing analysis at TEMP = 373.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. +-------------------------------------------------------------------------------- +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 0.000000e+00 2.615082e-28 +1 5.000000e-02 0.000000e+00 -7.499006e-11 +2 1.000000e-01 0.000000e+00 -9.107176e-11 +3 1.500000e-01 0.000000e+00 -9.476917e-11 +4 2.000000e-01 0.000000e+00 -9.654871e-11 +5 2.500000e-01 0.000000e+00 -9.659554e-11 +6 3.000000e-01 0.000000e+00 -9.696489e-11 +7 3.500000e-01 0.000000e+00 -9.741758e-11 +8 4.000000e-01 0.000000e+00 -9.790390e-11 +9 4.500000e-01 0.000000e+00 -9.841394e-11 +10 5.000000e-01 0.000000e+00 -9.894625e-11 +11 5.500000e-01 0.000000e+00 -9.950118e-11 +12 6.000000e-01 0.000000e+00 -1.000793e-10 +13 6.500000e-01 0.000000e+00 -1.006817e-10 +14 7.000000e-01 0.000000e+00 -1.013089e-10 +15 7.500000e-01 0.000000e+00 -1.019620e-10 +16 8.000000e-01 0.000000e+00 -1.026417e-10 +17 8.500000e-01 0.000000e+00 -1.033491e-10 +18 9.000000e-01 0.000000e+00 -1.040851e-10 +19 9.500000e-01 0.000000e+00 -1.048506e-10 +20 1.000000e+00 0.000000e+00 -1.056466e-10 +21 1.050000e+00 0.000000e+00 -1.064742e-10 +22 1.100000e+00 0.000000e+00 -1.073345e-10 +23 1.150000e+00 0.000000e+00 -1.082285e-10 +24 1.200000e+00 0.000000e+00 -1.091573e-10 +25 1.250000e+00 0.000000e+00 -1.101222e-10 +26 1.300000e+00 0.000000e+00 -1.111244e-10 +27 1.350000e+00 0.000000e+00 -1.121655e-10 +28 1.400000e+00 0.000000e+00 -1.132478e-10 +29 1.450000e+00 0.000000e+00 -1.143821e-10 +30 1.500000e+00 0.000000e+00 -1.156553e-10 +31 1.550000e+00 0.000000e+00 -1.176379e-10 +32 1.600000e+00 0.000000e+00 -1.277695e-10 +33 1.650000e+00 0.000000e+00 -1.607404e-10 +34 1.700000e+00 0.000000e+00 -2.712528e-10 +35 1.750000e+00 0.000000e+00 -6.017036e-10 +36 1.800000e+00 0.000000e+00 -1.488133e-09 +37 0.000000e+00 3.000000e-01 1.902980e-18 +38 5.000000e-02 3.000000e-01 -6.649294e-09 +39 1.000000e-01 3.000000e-01 -8.780198e-09 +40 1.500000e-01 3.000000e-01 -1.015796e-08 +41 2.000000e-01 3.000000e-01 -1.147970e-08 +42 2.500000e-01 3.000000e-01 -1.284685e-08 +43 3.000000e-01 3.000000e-01 -1.426934e-08 +44 3.500000e-01 3.000000e-01 -1.575738e-08 +45 4.000000e-01 3.000000e-01 -1.731494e-08 +46 4.500000e-01 3.000000e-01 -1.894516e-08 +47 5.000000e-01 3.000000e-01 -2.065085e-08 +48 5.500000e-01 3.000000e-01 -2.243479e-08 +49 6.000000e-01 3.000000e-01 -2.429974e-08 +50 6.500000e-01 3.000000e-01 -2.624852e-08 +51 7.000000e-01 3.000000e-01 -2.828400e-08 +52 7.500000e-01 3.000000e-01 -3.040913e-08 +53 8.000000e-01 3.000000e-01 -3.262694e-08 +54 8.500000e-01 3.000000e-01 -3.494054e-08 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +55 9.000000e-01 3.000000e-01 -3.735313e-08 +56 9.500000e-01 3.000000e-01 -3.986799e-08 +57 1.000000e+00 3.000000e-01 -4.248849e-08 +58 1.050000e+00 3.000000e-01 -4.521811e-08 +59 1.100000e+00 3.000000e-01 -4.806041e-08 +60 1.150000e+00 3.000000e-01 -5.101907e-08 +61 1.200000e+00 3.000000e-01 -5.409791e-08 +62 1.250000e+00 3.000000e-01 -5.730097e-08 +63 1.300000e+00 3.000000e-01 -6.063263e-08 +64 1.350000e+00 3.000000e-01 -6.409806e-08 +65 1.400000e+00 3.000000e-01 -6.770382e-08 +66 1.450000e+00 3.000000e-01 -7.145934e-08 +67 1.500000e+00 3.000000e-01 -7.537929e-08 +68 1.550000e+00 3.000000e-01 -7.948780e-08 +69 1.600000e+00 3.000000e-01 -8.382526e-08 +70 1.650000e+00 3.000000e-01 -8.845901e-08 +71 1.700000e+00 3.000000e-01 -9.349949e-08 +72 1.750000e+00 3.000000e-01 -9.912390e-08 +73 1.800000e+00 3.000000e-01 -1.056100e-07 +74 0.000000e+00 6.000000e-01 1.314774e-17 +75 5.000000e-02 6.000000e-01 -8.300951e-06 +76 1.000000e-01 6.000000e-01 -1.138766e-05 +77 1.500000e-01 6.000000e-01 -1.300583e-05 +78 2.000000e-01 6.000000e-01 -1.441279e-05 +79 2.500000e-01 6.000000e-01 -1.580458e-05 +80 3.000000e-01 6.000000e-01 -1.724263e-05 +81 3.500000e-01 6.000000e-01 -1.871478e-05 +82 4.000000e-01 6.000000e-01 -2.023270e-05 +83 4.500000e-01 6.000000e-01 -2.179851e-05 +84 5.000000e-01 6.000000e-01 -2.341360e-05 +85 5.500000e-01 6.000000e-01 -2.507908e-05 +86 6.000000e-01 6.000000e-01 -2.677009e-05 +87 6.500000e-01 6.000000e-01 -2.853879e-05 +88 7.000000e-01 6.000000e-01 -3.036067e-05 +89 7.500000e-01 6.000000e-01 -3.223660e-05 +90 8.000000e-01 6.000000e-01 -3.416743e-05 +91 8.500000e-01 6.000000e-01 -3.615402e-05 +92 9.000000e-01 6.000000e-01 -3.819720e-05 +93 9.500000e-01 6.000000e-01 -4.029782e-05 +94 1.000000e+00 6.000000e-01 -4.245672e-05 +95 1.050000e+00 6.000000e-01 -4.467474e-05 +96 1.100000e+00 6.000000e-01 -4.695271e-05 +97 1.150000e+00 6.000000e-01 -4.929148e-05 +98 1.200000e+00 6.000000e-01 -5.169189e-05 +99 1.250000e+00 6.000000e-01 -5.415484e-05 +100 1.300000e+00 6.000000e-01 -5.668135e-05 +101 1.350000e+00 6.000000e-01 -5.927271e-05 +102 1.400000e+00 6.000000e-01 -6.193091e-05 +103 1.450000e+00 6.000000e-01 -6.465933e-05 +104 1.500000e+00 6.000000e-01 -6.746415e-05 +105 1.550000e+00 6.000000e-01 -7.035666e-05 +106 1.600000e+00 6.000000e-01 -7.335728e-05 +107 1.650000e+00 6.000000e-01 -7.658698e-05 +108 1.700000e+00 6.000000e-01 -7.997467e-05 +109 1.750000e+00 6.000000e-01 -8.368999e-05 +110 1.800000e+00 6.000000e-01 -8.790274e-05 +111 0.000000e+00 9.000000e-01 3.929328e-17 +112 5.000000e-02 9.000000e-01 -1.406737e-04 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +113 1.000000e-01 9.000000e-01 -2.572735e-04 +114 1.500000e-01 9.000000e-01 -3.510370e-04 +115 2.000000e-01 9.000000e-01 -4.233798e-04 +116 2.500000e-01 9.000000e-01 -4.762855e-04 +117 3.000000e-01 9.000000e-01 -5.131015e-04 +118 3.500000e-01 9.000000e-01 -5.389114e-04 +119 4.000000e-01 9.000000e-01 -5.588479e-04 +120 4.500000e-01 9.000000e-01 -5.761543e-04 +121 5.000000e-01 9.000000e-01 -5.927447e-04 +122 5.500000e-01 9.000000e-01 -6.082144e-04 +123 6.000000e-01 9.000000e-01 -6.236076e-04 +124 6.500000e-01 9.000000e-01 -6.389838e-04 +125 7.000000e-01 9.000000e-01 -6.543821e-04 +126 7.500000e-01 9.000000e-01 -6.698270e-04 +127 8.000000e-01 9.000000e-01 -6.853342e-04 +128 8.500000e-01 9.000000e-01 -7.009139e-04 +129 9.000000e-01 9.000000e-01 -7.165721e-04 +130 9.500000e-01 9.000000e-01 -7.323128e-04 +131 1.000000e+00 9.000000e-01 -7.481385e-04 +132 1.050000e+00 9.000000e-01 -7.640504e-04 +133 1.100000e+00 9.000000e-01 -7.800491e-04 +134 1.150000e+00 9.000000e-01 -7.961347e-04 +135 1.200000e+00 9.000000e-01 -8.123069e-04 +136 1.250000e+00 9.000000e-01 -8.285651e-04 +137 1.300000e+00 9.000000e-01 -8.449085e-04 +138 1.350000e+00 9.000000e-01 -8.613364e-04 +139 1.400000e+00 9.000000e-01 -8.778478e-04 +140 1.450000e+00 9.000000e-01 -8.944419e-04 +141 1.500000e+00 9.000000e-01 -9.111188e-04 +142 1.550000e+00 9.000000e-01 -9.278804e-04 +143 1.600000e+00 9.000000e-01 -9.447333e-04 +144 1.650000e+00 9.000000e-01 -9.616940e-04 +145 1.700000e+00 9.000000e-01 -9.787991e-04 +146 1.750000e+00 9.000000e-01 -9.961230e-04 +147 1.800000e+00 9.000000e-01 -1.013807e-03 +148 0.000000e+00 1.200000e+00 7.768174e-17 +149 5.000000e-02 1.200000e+00 -2.121807e-04 +150 1.000000e-01 1.200000e+00 -4.032916e-04 +151 1.500000e-01 1.200000e+00 -5.739693e-04 +152 2.000000e-01 1.200000e+00 -7.248457e-04 +153 2.500000e-01 1.200000e+00 -8.565449e-04 +154 3.000000e-01 1.200000e+00 -9.696981e-04 +155 3.500000e-01 1.200000e+00 -1.064988e-03 +156 4.000000e-01 1.200000e+00 -1.143257e-03 +157 4.500000e-01 1.200000e+00 -1.205763e-03 +158 5.000000e-01 1.200000e+00 -1.254586e-03 +159 5.500000e-01 1.200000e+00 -1.292854e-03 +160 6.000000e-01 1.200000e+00 -1.324129e-03 +161 6.500000e-01 1.200000e+00 -1.351329e-03 +162 7.000000e-01 1.200000e+00 -1.377187e-03 +163 7.500000e-01 1.200000e+00 -1.400530e-03 +164 8.000000e-01 1.200000e+00 -1.423377e-03 +165 8.500000e-01 1.200000e+00 -1.445927e-03 +166 9.000000e-01 1.200000e+00 -1.468296e-03 +167 9.500000e-01 1.200000e+00 -1.490559e-03 +168 1.000000e+00 1.200000e+00 -1.512761e-03 +169 1.050000e+00 1.200000e+00 -1.534936e-03 +170 1.100000e+00 1.200000e+00 -1.557103e-03 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +171 1.150000e+00 1.200000e+00 -1.579277e-03 +172 1.200000e+00 1.200000e+00 -1.601468e-03 +173 1.250000e+00 1.200000e+00 -1.623682e-03 +174 1.300000e+00 1.200000e+00 -1.645926e-03 +175 1.350000e+00 1.200000e+00 -1.668201e-03 +176 1.400000e+00 1.200000e+00 -1.690509e-03 +177 1.450000e+00 1.200000e+00 -1.712853e-03 +178 1.500000e+00 1.200000e+00 -1.735233e-03 +179 1.550000e+00 1.200000e+00 -1.757649e-03 +180 1.600000e+00 1.200000e+00 -1.780101e-03 +181 1.650000e+00 1.200000e+00 -1.802590e-03 +182 1.700000e+00 1.200000e+00 -1.825117e-03 +183 1.750000e+00 1.200000e+00 -1.847688e-03 +184 1.800000e+00 1.200000e+00 -1.870316e-03 +185 0.000000e+00 1.500000e+00 1.277867e-16 +186 5.000000e-02 1.500000e+00 -2.480825e-04 +187 1.000000e-01 1.500000e+00 -4.783088e-04 +188 1.500000e-01 1.500000e+00 -6.910798e-04 +189 2.000000e-01 1.500000e+00 -8.867980e-04 +190 2.500000e-01 1.500000e+00 -1.065858e-03 +191 3.000000e-01 1.500000e+00 -1.228645e-03 +192 3.500000e-01 1.500000e+00 -1.375536e-03 +193 4.000000e-01 1.500000e+00 -1.506903e-03 +194 4.500000e-01 1.500000e+00 -1.623120e-03 +195 5.000000e-01 1.500000e+00 -1.724587e-03 +196 5.500000e-01 1.500000e+00 -1.811784e-03 +197 6.000000e-01 1.500000e+00 -1.885388e-03 +198 6.500000e-01 1.500000e+00 -1.946493e-03 +199 7.000000e-01 1.500000e+00 -1.996858e-03 +200 7.500000e-01 1.500000e+00 -2.038888e-03 +201 8.000000e-01 1.500000e+00 -2.075144e-03 +202 8.500000e-01 1.500000e+00 -2.109273e-03 +203 9.000000e-01 1.500000e+00 -2.139026e-03 +204 9.500000e-01 1.500000e+00 -2.167667e-03 +205 1.000000e+00 1.500000e+00 -2.195615e-03 +206 1.050000e+00 1.500000e+00 -2.223111e-03 +207 1.100000e+00 1.500000e+00 -2.250302e-03 +208 1.150000e+00 1.500000e+00 -2.277281e-03 +209 1.200000e+00 1.500000e+00 -2.304113e-03 +210 1.250000e+00 1.500000e+00 -2.330838e-03 +211 1.300000e+00 1.500000e+00 -2.357488e-03 +212 1.350000e+00 1.500000e+00 -2.384081e-03 +213 1.400000e+00 1.500000e+00 -2.410634e-03 +214 1.450000e+00 1.500000e+00 -2.437157e-03 +215 1.500000e+00 1.500000e+00 -2.463656e-03 +216 1.550000e+00 1.500000e+00 -2.490139e-03 +217 1.600000e+00 1.500000e+00 -2.516609e-03 +218 1.650000e+00 1.500000e+00 -2.543068e-03 +219 1.700000e+00 1.500000e+00 -2.569519e-03 +220 1.750000e+00 1.500000e+00 -2.595963e-03 +221 1.800000e+00 1.500000e+00 -2.622401e-03 +222 0.000000e+00 1.800000e+00 1.891469e-16 +223 5.000000e-02 1.800000e+00 -2.683796e-04 +224 1.000000e-01 1.800000e+00 -5.215864e-04 +225 1.500000e-01 1.800000e+00 -7.598877e-04 +226 2.000000e-01 1.800000e+00 -9.835559e-04 +227 2.500000e-01 1.800000e+00 -1.192860e-03 +228 3.000000e-01 1.800000e+00 -1.388066e-03 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +229 3.500000e-01 1.800000e+00 -1.569431e-03 +230 4.000000e-01 1.800000e+00 -1.737210e-03 +231 4.500000e-01 1.800000e+00 -1.891649e-03 +232 5.000000e-01 1.800000e+00 -2.032991e-03 +233 5.500000e-01 1.800000e+00 -2.161474e-03 +234 6.000000e-01 1.800000e+00 -2.277337e-03 +235 6.500000e-01 1.800000e+00 -2.380835e-03 +236 7.000000e-01 1.800000e+00 -2.472267e-03 +237 7.500000e-01 1.800000e+00 -2.552038e-03 +238 8.000000e-01 1.800000e+00 -2.620788e-03 +239 8.500000e-01 1.800000e+00 -2.679551e-03 +240 9.000000e-01 1.800000e+00 -2.729870e-03 +241 9.500000e-01 1.800000e+00 -2.773658e-03 +242 1.000000e+00 1.800000e+00 -2.814836e-03 +243 1.050000e+00 1.800000e+00 -2.850213e-03 +244 1.100000e+00 1.800000e+00 -2.883809e-03 +245 1.150000e+00 1.800000e+00 -2.916270e-03 +246 1.200000e+00 1.800000e+00 -2.947975e-03 +247 1.250000e+00 1.800000e+00 -2.979156e-03 +248 1.300000e+00 1.800000e+00 -3.009961e-03 +249 1.350000e+00 1.800000e+00 -3.040489e-03 +250 1.400000e+00 1.800000e+00 -3.070806e-03 +251 1.450000e+00 1.800000e+00 -3.100959e-03 +252 1.500000e+00 1.800000e+00 -3.130981e-03 +253 1.550000e+00 1.800000e+00 -3.160894e-03 +254 1.600000e+00 1.800000e+00 -3.190717e-03 +255 1.650000e+00 1.800000e+00 -3.220462e-03 +256 1.700000e+00 1.800000e+00 -3.250138e-03 +257 1.750000e+00 1.800000e+00 -3.279752e-03 +258 1.800000e+00 1.800000e+00 -3.309309e-03 + + + + diff --git a/tests/bsim4/test4.cir b/tests/bsim4/test4.cir new file mode 100644 index 000000000..d02edf4a6 --- /dev/null +++ b/tests/bsim4/test4.cir @@ -0,0 +1,13 @@ +** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +** Circuit Description ** +m1 2 1 0 0 n1 L=0.13u W=10.0u rgeoMod=1 +vgs 1 0 1.8 +vds 2 0 1.8 + +.dc vgs -0.6 1.8 0.05 vds 0.1 1.8 0.3 + +.print dc v(2) i(vds) + +.include modelcard.nmos +.end diff --git a/tests/bsim4/test4.out b/tests/bsim4/test4.out new file mode 100644 index 000000000..8473dd284 --- /dev/null +++ b/tests/bsim4/test4.out @@ -0,0 +1,373 @@ + +No. of Data Rows : 343 + +Circuit: ** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. +-------------------------------------------------------------------------------- +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +0 -6.000000e-01 1.000000e-01 -1.053433e-13 +1 -5.500000e-01 1.000000e-01 -1.053381e-13 +2 -5.000000e-01 1.000000e-01 -1.053381e-13 +3 -4.500000e-01 1.000000e-01 -1.053381e-13 +4 -4.000000e-01 1.000000e-01 -1.053381e-13 +5 -3.500000e-01 1.000000e-01 -1.053381e-13 +6 -3.000000e-01 1.000000e-01 -1.053381e-13 +7 -2.500000e-01 1.000000e-01 -1.053433e-13 +8 -2.000000e-01 1.000000e-01 -1.053746e-13 +9 -1.500000e-01 1.000000e-01 -1.055881e-13 +10 -1.000000e-01 1.000000e-01 -1.067915e-13 +11 -5.000000e-02 1.000000e-01 -1.134283e-13 +12 -6.938894e-17 1.000000e-01 -1.503215e-13 +13 5.000000e-02 1.000000e-01 -3.551353e-13 +14 1.000000e-01 1.000000e-01 -2.935115e-12 +15 1.500000e-01 1.000000e-01 -1.566228e-11 +16 2.000000e-01 1.000000e-01 -8.495561e-11 +17 2.500000e-01 1.000000e-01 -4.587771e-10 +18 3.000000e-01 1.000000e-01 -2.451491e-09 +19 3.500000e-01 1.000000e-01 -1.288139e-08 +20 4.000000e-01 1.000000e-01 -6.576226e-08 +21 4.500000e-01 1.000000e-01 -3.189860e-07 +22 5.000000e-01 1.000000e-01 -1.423874e-06 +23 5.500000e-01 1.000000e-01 -5.700334e-06 +24 6.000000e-01 1.000000e-01 -2.028107e-05 +25 6.500000e-01 1.000000e-01 -6.115468e-05 +26 7.000000e-01 1.000000e-01 -1.401423e-04 +27 7.500000e-01 1.000000e-01 -2.381533e-04 +28 8.000000e-01 1.000000e-01 -3.288473e-04 +29 8.500000e-01 1.000000e-01 -4.039627e-04 +30 9.000000e-01 1.000000e-01 -4.656109e-04 +31 9.500000e-01 1.000000e-01 -5.175148e-04 +32 1.000000e+00 1.000000e-01 -5.624409e-04 +33 1.050000e+00 1.000000e-01 -6.021255e-04 +34 1.100000e+00 1.000000e-01 -6.376387e-04 +35 1.150000e+00 1.000000e-01 -6.696726e-04 +36 1.200000e+00 1.000000e-01 -6.987096e-04 +37 1.250000e+00 1.000000e-01 -7.251131e-04 +38 1.300000e+00 1.000000e-01 -7.491736e-04 +39 1.350000e+00 1.000000e-01 -7.711336e-04 +40 1.400000e+00 1.000000e-01 -7.912009e-04 +41 1.450000e+00 1.000000e-01 -8.095565e-04 +42 1.500000e+00 1.000000e-01 -8.271110e-04 +43 1.550000e+00 1.000000e-01 -8.424342e-04 +44 1.600000e+00 1.000000e-01 -8.564796e-04 +45 1.650000e+00 1.000000e-01 -8.693573e-04 +46 1.700000e+00 1.000000e-01 -8.811666e-04 +47 1.750000e+00 1.000000e-01 -8.919969e-04 +48 1.800000e+00 1.000000e-01 -9.019285e-04 +49 -6.000000e-01 4.000000e-01 -4.054948e-13 +50 -5.500000e-01 4.000000e-01 -4.054948e-13 +51 -5.000000e-01 4.000000e-01 -4.054948e-13 +52 -4.500000e-01 4.000000e-01 -4.054948e-13 +53 -4.000000e-01 4.000000e-01 -4.054532e-13 +54 -3.500000e-01 4.000000e-01 -4.054532e-13 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +55 -3.000000e-01 4.000000e-01 -4.054948e-13 +56 -2.500000e-01 4.000000e-01 -4.054948e-13 +57 -2.000000e-01 4.000000e-01 -4.055782e-13 +58 -1.500000e-01 4.000000e-01 -4.060366e-13 +59 -1.000000e-01 4.000000e-01 -4.085997e-13 +60 -5.000000e-02 4.000000e-01 -4.229985e-13 +61 -6.938894e-17 4.000000e-01 -5.029736e-13 +62 5.000000e-02 4.000000e-01 -9.467960e-13 +63 1.000000e-01 4.000000e-01 -6.537512e-12 +64 1.500000e-01 4.000000e-01 -3.411507e-11 +65 2.000000e-01 4.000000e-01 -1.842403e-10 +66 2.500000e-01 4.000000e-01 -9.938582e-10 +67 3.000000e-01 4.000000e-01 -5.306233e-09 +68 3.500000e-01 4.000000e-01 -2.783546e-08 +69 4.000000e-01 4.000000e-01 -1.415694e-07 +70 4.500000e-01 4.000000e-01 -6.807869e-07 +71 5.000000e-01 4.000000e-01 -2.979872e-06 +72 5.500000e-01 4.000000e-01 -1.142584e-05 +73 6.000000e-01 4.000000e-01 -3.754210e-05 +74 6.500000e-01 4.000000e-01 -1.032228e-04 +75 7.000000e-01 4.000000e-01 -2.278937e-04 +76 7.500000e-01 4.000000e-01 -4.015784e-04 +77 8.000000e-01 4.000000e-01 -5.934894e-04 +78 8.500000e-01 4.000000e-01 -7.823530e-04 +79 9.000000e-01 4.000000e-01 -9.620082e-04 +80 9.500000e-01 4.000000e-01 -1.132967e-03 +81 1.000000e+00 4.000000e-01 -1.296641e-03 +82 1.050000e+00 4.000000e-01 -1.453594e-03 +83 1.100000e+00 4.000000e-01 -1.603554e-03 +84 1.150000e+00 4.000000e-01 -1.745888e-03 +85 1.200000e+00 4.000000e-01 -1.880044e-03 +86 1.250000e+00 4.000000e-01 -2.005773e-03 +87 1.300000e+00 4.000000e-01 -2.123140e-03 +88 1.350000e+00 4.000000e-01 -2.232442e-03 +89 1.400000e+00 4.000000e-01 -2.334105e-03 +90 1.450000e+00 4.000000e-01 -2.428616e-03 +91 1.500000e+00 4.000000e-01 -2.516468e-03 +92 1.550000e+00 4.000000e-01 -2.598145e-03 +93 1.600000e+00 4.000000e-01 -2.674103e-03 +94 1.650000e+00 4.000000e-01 -2.747345e-03 +95 1.700000e+00 4.000000e-01 -2.812913e-03 +96 1.750000e+00 4.000000e-01 -2.873959e-03 +97 1.800000e+00 4.000000e-01 -2.930812e-03 +98 -6.000000e-01 7.000000e-01 -7.054953e-13 +99 -5.500000e-01 7.000000e-01 -7.055370e-13 +100 -5.000000e-01 7.000000e-01 -7.054953e-13 +101 -4.500000e-01 7.000000e-01 -7.054953e-13 +102 -4.000000e-01 7.000000e-01 -7.054953e-13 +103 -3.500000e-01 7.000000e-01 -7.054953e-13 +104 -3.000000e-01 7.000000e-01 -7.054953e-13 +105 -2.500000e-01 7.000000e-01 -7.054953e-13 +106 -2.000000e-01 7.000000e-01 -7.056203e-13 +107 -1.500000e-01 7.000000e-01 -7.064122e-13 +108 -1.000000e-01 7.000000e-01 -7.109548e-13 +109 -5.000000e-02 7.000000e-01 -7.359184e-13 +110 -6.938894e-17 7.000000e-01 -8.743641e-13 +111 5.000000e-02 7.000000e-01 -1.643192e-12 +112 1.000000e-01 7.000000e-01 -1.132668e-11 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +113 1.500000e-01 7.000000e-01 -5.908992e-11 +114 2.000000e-01 7.000000e-01 -3.190605e-10 +115 2.500000e-01 7.000000e-01 -1.720559e-09 +116 3.000000e-01 7.000000e-01 -9.179210e-09 +117 3.500000e-01 7.000000e-01 -4.806947e-08 +118 4.000000e-01 7.000000e-01 -2.435405e-07 +119 4.500000e-01 7.000000e-01 -1.161624e-06 +120 5.000000e-01 7.000000e-01 -5.002322e-06 +121 5.500000e-01 7.000000e-01 -1.859566e-05 +122 6.000000e-01 7.000000e-01 -5.786491e-05 +123 6.500000e-01 7.000000e-01 -1.473897e-04 +124 7.000000e-01 7.000000e-01 -3.013086e-04 +125 7.500000e-01 7.000000e-01 -5.010570e-04 +126 8.000000e-01 7.000000e-01 -7.135553e-04 +127 8.500000e-01 7.000000e-01 -9.197979e-04 +128 9.000000e-01 7.000000e-01 -1.116080e-03 +129 9.500000e-01 7.000000e-01 -1.304641e-03 +130 1.000000e+00 7.000000e-01 -1.488276e-03 +131 1.050000e+00 7.000000e-01 -1.670162e-03 +132 1.100000e+00 7.000000e-01 -1.848332e-03 +133 1.150000e+00 7.000000e-01 -2.025066e-03 +134 1.200000e+00 7.000000e-01 -2.200280e-03 +135 1.250000e+00 7.000000e-01 -2.373737e-03 +136 1.300000e+00 7.000000e-01 -2.545124e-03 +137 1.350000e+00 7.000000e-01 -2.714074e-03 +138 1.400000e+00 7.000000e-01 -2.880170e-03 +139 1.450000e+00 7.000000e-01 -3.042938e-03 +140 1.500000e+00 7.000000e-01 -3.201844e-03 +141 1.550000e+00 7.000000e-01 -3.356292e-03 +142 1.600000e+00 7.000000e-01 -3.505654e-03 +143 1.650000e+00 7.000000e-01 -3.649308e-03 +144 1.700000e+00 7.000000e-01 -3.786710e-03 +145 1.750000e+00 7.000000e-01 -3.917460e-03 +146 1.800000e+00 7.000000e-01 -4.041350e-03 +147 -6.000000e-01 1.000000e+00 -1.068062e-11 +148 -5.500000e-01 1.000000e+00 -2.883147e-12 +149 -5.000000e-01 1.000000e+00 -1.295189e-12 +150 -4.500000e-01 1.000000e+00 -7.159003e-13 +151 -4.000000e-01 1.000000e+00 -9.612435e-13 +152 -3.500000e-01 1.000000e+00 -1.000793e-12 +153 -3.000000e-01 1.000000e+00 -1.005169e-12 +154 -2.500000e-01 1.000000e+00 -1.005544e-12 +155 -2.000000e-01 1.000000e+00 -1.005670e-12 +156 -1.500000e-01 1.000000e+00 -1.007045e-12 +157 -1.000000e-01 1.000000e+00 -1.014088e-12 +158 -5.000000e-02 1.000000e+00 -1.053221e-12 +159 -6.938894e-17 1.000000e+00 -1.270892e-12 +160 5.000000e-02 1.000000e+00 -4.020302e-12 +161 1.000000e-01 1.000000e+00 -1.770130e-11 +162 1.500000e-01 1.000000e+00 -9.277598e-11 +163 2.000000e-01 1.000000e+00 -5.013315e-10 +164 2.500000e-01 1.000000e+00 -2.702982e-09 +165 3.000000e-01 1.000000e+00 -1.440923e-08 +166 3.500000e-01 1.000000e+00 -7.531919e-08 +167 4.000000e-01 1.000000e+00 -3.800563e-07 +168 4.500000e-01 1.000000e+00 -1.797766e-06 +169 5.000000e-01 1.000000e+00 -7.622615e-06 +170 5.500000e-01 1.000000e+00 -2.759126e-05 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +171 6.000000e-01 1.000000e+00 -8.227257e-05 +172 6.500000e-01 1.000000e+00 -1.978285e-04 +173 7.000000e-01 1.000000e+00 -3.813996e-04 +174 7.500000e-01 1.000000e+00 -6.058360e-04 +175 8.000000e-01 1.000000e+00 -8.364798e-04 +176 8.500000e-01 1.000000e+00 -1.056653e-03 +177 9.000000e-01 1.000000e+00 -1.264685e-03 +178 9.500000e-01 1.000000e+00 -1.463874e-03 +179 1.000000e+00 1.000000e+00 -1.657517e-03 +180 1.050000e+00 1.000000e+00 -1.849198e-03 +181 1.100000e+00 1.000000e+00 -2.036765e-03 +182 1.150000e+00 1.000000e+00 -2.222889e-03 +183 1.200000e+00 1.000000e+00 -2.407632e-03 +184 1.250000e+00 1.000000e+00 -2.590929e-03 +185 1.300000e+00 1.000000e+00 -2.772665e-03 +186 1.350000e+00 1.000000e+00 -2.952709e-03 +187 1.400000e+00 1.000000e+00 -3.130937e-03 +188 1.450000e+00 1.000000e+00 -3.307227e-03 +189 1.500000e+00 1.000000e+00 -3.481469e-03 +190 1.550000e+00 1.000000e+00 -3.653557e-03 +191 1.600000e+00 1.000000e+00 -3.823388e-03 +192 1.650000e+00 1.000000e+00 -3.990858e-03 +193 1.700000e+00 1.000000e+00 -4.155859e-03 +194 1.750000e+00 1.000000e+00 -4.318274e-03 +195 1.800000e+00 1.000000e+00 -4.477971e-03 +196 -6.000000e-01 1.300000e+00 -8.362057e-09 +197 -5.500000e-01 1.300000e+00 -3.522663e-09 +198 -5.000000e-01 1.300000e+00 -1.364808e-09 +199 -4.500000e-01 1.300000e+00 -4.803444e-10 +200 -4.000000e-01 1.300000e+00 -1.515782e-10 +201 -3.500000e-01 1.300000e+00 -4.256977e-11 +202 -3.000000e-01 1.300000e+00 -1.098164e-11 +203 -2.500000e-01 1.300000e+00 -3.183585e-12 +204 -2.000000e-01 1.300000e+00 -1.596002e-12 +205 -1.500000e-01 1.300000e+00 -1.018130e-12 +206 -1.000000e-01 1.300000e+00 -1.274017e-12 +207 -5.000000e-02 1.300000e+00 -1.371705e-12 +208 -6.938894e-17 1.300000e+00 -1.699357e-12 +209 5.000000e-02 1.300000e+00 -5.781464e-12 +210 1.000000e-01 1.300000e+00 -2.609215e-11 +211 1.500000e-01 1.300000e+00 -1.375391e-10 +212 2.000000e-01 1.300000e+00 -7.439221e-10 +213 2.500000e-01 1.300000e+00 -4.010242e-09 +214 3.000000e-01 1.300000e+00 -2.136013e-08 +215 3.500000e-01 1.300000e+00 -1.114317e-07 +216 4.000000e-01 1.300000e+00 -5.598558e-07 +217 4.500000e-01 1.300000e+00 -2.625414e-06 +218 5.000000e-01 1.300000e+00 -1.096026e-05 +219 5.500000e-01 1.300000e+00 -3.868937e-05 +220 6.000000e-01 1.300000e+00 -1.111310e-04 +221 6.500000e-01 1.300000e+00 -2.547171e-04 +222 7.000000e-01 1.300000e+00 -4.681950e-04 +223 7.500000e-01 1.300000e+00 -7.164101e-04 +224 8.000000e-01 1.300000e+00 -9.641340e-04 +225 8.500000e-01 1.300000e+00 -1.197288e-03 +226 9.000000e-01 1.300000e+00 -1.416169e-03 +227 9.500000e-01 1.300000e+00 -1.625032e-03 +228 1.000000e+00 1.300000e+00 -1.827599e-03 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +229 1.050000e+00 1.300000e+00 -2.027907e-03 +230 1.100000e+00 1.300000e+00 -2.223376e-03 +231 1.150000e+00 1.300000e+00 -2.417073e-03 +232 1.200000e+00 1.300000e+00 -2.609122e-03 +233 1.250000e+00 1.300000e+00 -2.799515e-03 +234 1.300000e+00 1.300000e+00 -2.988188e-03 +235 1.350000e+00 1.300000e+00 -3.175061e-03 +236 1.400000e+00 1.300000e+00 -3.360056e-03 +237 1.450000e+00 1.300000e+00 -3.543101e-03 +238 1.500000e+00 1.300000e+00 -3.724134e-03 +239 1.550000e+00 1.300000e+00 -3.903102e-03 +240 1.600000e+00 1.300000e+00 -4.079960e-03 +241 1.650000e+00 1.300000e+00 -4.254673e-03 +242 1.700000e+00 1.300000e+00 -4.427208e-03 +243 1.750000e+00 1.300000e+00 -4.597540e-03 +244 1.800000e+00 1.300000e+00 -4.765646e-03 +245 -6.000000e-01 1.600000e+00 -4.226580e-07 +246 -5.500000e-01 1.600000e+00 -2.472012e-07 +247 -5.000000e-01 1.600000e+00 -1.389354e-07 +248 -4.500000e-01 1.600000e+00 -7.468366e-08 +249 -4.000000e-01 1.600000e+00 -3.818570e-08 +250 -3.500000e-01 1.600000e+00 -1.845185e-08 +251 -3.000000e-01 1.600000e+00 -8.362710e-09 +252 -2.500000e-01 1.600000e+00 -3.523112e-09 +253 -2.000000e-01 1.600000e+00 -1.365167e-09 +254 -1.500000e-01 1.600000e+00 -4.806715e-10 +255 -1.000000e-01 1.600000e+00 -1.519221e-10 +256 -5.000000e-02 1.600000e+00 -4.308002e-11 +257 -6.938894e-17 1.600000e+00 -1.243917e-11 +258 5.000000e-02 1.600000e+00 -9.905719e-12 +259 1.000000e-01 1.600000e+00 -3.745917e-11 +260 1.500000e-01 1.600000e+00 -1.970889e-10 +261 2.000000e-01 1.600000e+00 -1.066824e-09 +262 2.500000e-01 1.600000e+00 -5.749703e-09 +263 3.000000e-01 1.600000e+00 -3.059731e-08 +264 3.500000e-01 1.600000e+00 -1.592793e-07 +265 4.000000e-01 1.600000e+00 -7.965616e-07 +266 4.500000e-01 1.600000e+00 -3.701435e-06 +267 5.000000e-01 1.600000e+00 -1.520705e-05 +268 5.500000e-01 1.600000e+00 -5.235820e-05 +269 6.000000e-01 1.600000e+00 -1.451576e-04 +270 6.500000e-01 1.600000e+00 -3.186611e-04 +271 7.000000e-01 1.600000e+00 -5.619767e-04 +272 7.500000e-01 1.600000e+00 -8.328801e-04 +273 8.000000e-01 1.600000e+00 -1.096629e-03 +274 8.500000e-01 1.600000e+00 -1.341967e-03 +275 9.000000e-01 1.600000e+00 -1.571068e-03 +276 9.500000e-01 1.600000e+00 -1.789050e-03 +277 1.000000e+00 1.600000e+00 -2.000003e-03 +278 1.050000e+00 1.600000e+00 -2.208399e-03 +279 1.100000e+00 1.600000e+00 -2.411198e-03 +280 1.150000e+00 1.600000e+00 -2.611853e-03 +281 1.200000e+00 1.600000e+00 -2.810540e-03 +282 1.250000e+00 1.600000e+00 -3.007295e-03 +283 1.300000e+00 1.600000e+00 -3.202096e-03 +284 1.350000e+00 1.600000e+00 -3.394899e-03 +285 1.400000e+00 1.600000e+00 -3.585655e-03 +286 1.450000e+00 1.600000e+00 -3.774321e-03 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +287 1.500000e+00 1.600000e+00 -3.960860e-03 +288 1.550000e+00 1.600000e+00 -4.145240e-03 +289 1.600000e+00 1.600000e+00 -4.327441e-03 +290 1.650000e+00 1.600000e+00 -4.507443e-03 +291 1.700000e+00 1.600000e+00 -4.685237e-03 +292 1.750000e+00 1.600000e+00 -4.860815e-03 +293 1.800000e+00 1.600000e+00 -5.034175e-03 +294 -6.000000e-01 1.900000e+00 -5.558005e-06 +295 -5.500000e-01 1.900000e+00 -3.851706e-06 +296 -5.000000e-01 1.900000e+00 -2.611205e-06 +297 -4.500000e-01 1.900000e+00 -1.728116e-06 +298 -4.000000e-01 1.900000e+00 -1.113828e-06 +299 -3.500000e-01 1.900000e+00 -6.972779e-07 +300 -3.000000e-01 1.900000e+00 -4.226666e-07 +301 -2.500000e-01 1.900000e+00 -2.472064e-07 +302 -2.000000e-01 1.900000e+00 -1.389384e-07 +303 -1.500000e-01 1.900000e+00 -7.468544e-08 +304 -1.000000e-01 1.900000e+00 -3.818681e-08 +305 -5.000000e-02 1.900000e+00 -1.845283e-08 +306 -6.938894e-17 1.900000e+00 -8.364950e-09 +307 5.000000e-02 1.900000e+00 -3.533341e-09 +308 1.000000e-01 1.900000e+00 -1.421838e-09 +309 1.500000e-01 1.900000e+00 -7.845401e-10 +310 2.000000e-01 1.900000e+00 -1.790119e-09 +311 2.500000e-01 1.900000e+00 -8.863330e-09 +312 3.000000e-01 1.900000e+00 -4.690228e-08 +313 3.500000e-01 1.900000e+00 -2.435373e-07 +314 4.000000e-01 1.900000e+00 -1.211761e-06 +315 4.500000e-01 1.900000e+00 -5.573477e-06 +316 5.000000e-01 1.900000e+00 -2.247347e-05 +317 5.500000e-01 1.900000e+00 -7.497436e-05 +318 6.000000e-01 1.900000e+00 -1.981612e-04 +319 6.500000e-01 1.900000e+00 -4.103625e-04 +320 7.000000e-01 1.900000e+00 -6.857581e-04 +321 7.500000e-01 1.900000e+00 -9.766406e-04 +322 8.000000e-01 1.900000e+00 -1.252229e-03 +323 8.500000e-01 1.900000e+00 -1.505707e-03 +324 9.000000e-01 1.900000e+00 -1.741495e-03 +325 9.500000e-01 1.900000e+00 -1.965576e-03 +326 1.000000e+00 1.900000e+00 -2.182350e-03 +327 1.050000e+00 1.900000e+00 -2.396471e-03 +328 1.100000e+00 1.900000e+00 -2.604788e-03 +329 1.150000e+00 1.900000e+00 -2.810871e-03 +330 1.200000e+00 1.900000e+00 -3.014902e-03 +331 1.250000e+00 1.900000e+00 -3.216917e-03 +332 1.300000e+00 1.900000e+00 -3.416893e-03 +333 1.350000e+00 1.900000e+00 -3.614783e-03 +334 1.400000e+00 1.900000e+00 -3.810539e-03 +335 1.450000e+00 1.900000e+00 -4.004116e-03 +336 1.500000e+00 1.900000e+00 -4.195478e-03 +337 1.550000e+00 1.900000e+00 -4.384598e-03 +338 1.600000e+00 1.900000e+00 -4.571458e-03 +339 1.650000e+00 1.900000e+00 -4.756047e-03 +340 1.700000e+00 1.900000e+00 -4.938360e-03 +341 1.750000e+00 1.900000e+00 -5.118398e-03 +342 1.800000e+00 1.900000e+00 -5.296166e-03 + + + + diff --git a/tests/bsim4/test5.cir b/tests/bsim4/test5.cir new file mode 100644 index 000000000..fb2176e41 --- /dev/null +++ b/tests/bsim4/test5.cir @@ -0,0 +1,14 @@ +** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +** Circuit Description ** +m1 2 1 0 3 n1 L=0.13u W=10.0u rgeoMod=1 +vgs 1 0 1.8 +vbs 3 0 0 +vds 2 0 0.1 + +.dc vgs -0.6 1.8 0.05 vbs 0.0 -1.8 -0.3 + +.print dc v(2) i(vds) + +.include modelcard.nmos +.end diff --git a/tests/bsim4/test5.out b/tests/bsim4/test5.out new file mode 100644 index 000000000..d5960101a --- /dev/null +++ b/tests/bsim4/test5.out @@ -0,0 +1,373 @@ + +No. of Data Rows : 343 + +Circuit: ** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. +-------------------------------------------------------------------------------- +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +0 -6.000000e-01 1.000000e-01 -1.053433e-13 +1 -5.500000e-01 1.000000e-01 -1.053381e-13 +2 -5.000000e-01 1.000000e-01 -1.053381e-13 +3 -4.500000e-01 1.000000e-01 -1.053381e-13 +4 -4.000000e-01 1.000000e-01 -1.053381e-13 +5 -3.500000e-01 1.000000e-01 -1.053381e-13 +6 -3.000000e-01 1.000000e-01 -1.053381e-13 +7 -2.500000e-01 1.000000e-01 -1.053433e-13 +8 -2.000000e-01 1.000000e-01 -1.053746e-13 +9 -1.500000e-01 1.000000e-01 -1.055881e-13 +10 -1.000000e-01 1.000000e-01 -1.067915e-13 +11 -5.000000e-02 1.000000e-01 -1.134283e-13 +12 -6.938894e-17 1.000000e-01 -1.503215e-13 +13 5.000000e-02 1.000000e-01 -3.551353e-13 +14 1.000000e-01 1.000000e-01 -2.935115e-12 +15 1.500000e-01 1.000000e-01 -1.566228e-11 +16 2.000000e-01 1.000000e-01 -8.495561e-11 +17 2.500000e-01 1.000000e-01 -4.587771e-10 +18 3.000000e-01 1.000000e-01 -2.451491e-09 +19 3.500000e-01 1.000000e-01 -1.288139e-08 +20 4.000000e-01 1.000000e-01 -6.576226e-08 +21 4.500000e-01 1.000000e-01 -3.189860e-07 +22 5.000000e-01 1.000000e-01 -1.423874e-06 +23 5.500000e-01 1.000000e-01 -5.700334e-06 +24 6.000000e-01 1.000000e-01 -2.028107e-05 +25 6.500000e-01 1.000000e-01 -6.115468e-05 +26 7.000000e-01 1.000000e-01 -1.401423e-04 +27 7.500000e-01 1.000000e-01 -2.381533e-04 +28 8.000000e-01 1.000000e-01 -3.288473e-04 +29 8.500000e-01 1.000000e-01 -4.039627e-04 +30 9.000000e-01 1.000000e-01 -4.656109e-04 +31 9.500000e-01 1.000000e-01 -5.175148e-04 +32 1.000000e+00 1.000000e-01 -5.624409e-04 +33 1.050000e+00 1.000000e-01 -6.021255e-04 +34 1.100000e+00 1.000000e-01 -6.376387e-04 +35 1.150000e+00 1.000000e-01 -6.696726e-04 +36 1.200000e+00 1.000000e-01 -6.987096e-04 +37 1.250000e+00 1.000000e-01 -7.251131e-04 +38 1.300000e+00 1.000000e-01 -7.491736e-04 +39 1.350000e+00 1.000000e-01 -7.711336e-04 +40 1.400000e+00 1.000000e-01 -7.912009e-04 +41 1.450000e+00 1.000000e-01 -8.095565e-04 +42 1.500000e+00 1.000000e-01 -8.271110e-04 +43 1.550000e+00 1.000000e-01 -8.424342e-04 +44 1.600000e+00 1.000000e-01 -8.564796e-04 +45 1.650000e+00 1.000000e-01 -8.693573e-04 +46 1.700000e+00 1.000000e-01 -8.811666e-04 +47 1.750000e+00 1.000000e-01 -8.919969e-04 +48 1.800000e+00 1.000000e-01 -9.019285e-04 +49 -6.000000e-01 1.000000e-01 -4.054584e-13 +50 -5.500000e-01 1.000000e-01 -4.054480e-13 +51 -5.000000e-01 1.000000e-01 -4.054480e-13 +52 -4.500000e-01 1.000000e-01 -4.054480e-13 +53 -4.000000e-01 1.000000e-01 -4.054480e-13 +54 -3.500000e-01 1.000000e-01 -4.054480e-13 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +55 -3.000000e-01 1.000000e-01 -4.054480e-13 +56 -2.500000e-01 1.000000e-01 -4.054480e-13 +57 -2.000000e-01 1.000000e-01 -4.054636e-13 +58 -1.500000e-01 1.000000e-01 -4.055157e-13 +59 -1.000000e-01 1.000000e-01 -4.058439e-13 +60 -5.000000e-02 1.000000e-01 -4.077610e-13 +61 -6.938894e-17 1.000000e-01 -4.186539e-13 +62 5.000000e-02 1.000000e-01 -4.807867e-13 +63 1.000000e-01 1.000000e-01 -8.350955e-13 +64 1.500000e-01 1.000000e-01 -5.442219e-12 +65 2.000000e-01 1.000000e-01 -2.863319e-11 +66 2.500000e-01 1.000000e-01 -1.573011e-10 +67 3.000000e-01 1.000000e-01 -8.640302e-10 +68 3.500000e-01 1.000000e-01 -4.691843e-09 +69 4.000000e-01 1.000000e-01 -2.495427e-08 +70 4.500000e-01 1.000000e-01 -1.278660e-07 +71 5.000000e-01 1.000000e-01 -6.136250e-07 +72 5.500000e-01 1.000000e-01 -2.666593e-06 +73 6.000000e-01 1.000000e-01 -1.030170e-05 +74 6.500000e-01 1.000000e-01 -3.473506e-05 +75 7.000000e-01 1.000000e-01 -9.355607e-05 +76 7.500000e-01 1.000000e-01 -1.841545e-04 +77 8.000000e-01 1.000000e-01 -2.784998e-04 +78 8.500000e-01 1.000000e-01 -3.594809e-04 +79 9.000000e-01 1.000000e-01 -4.258014e-04 +80 9.500000e-01 1.000000e-01 -4.809818e-04 +81 1.000000e+00 1.000000e-01 -5.282512e-04 +82 1.050000e+00 1.000000e-01 -5.697270e-04 +83 1.100000e+00 1.000000e-01 -6.067034e-04 +84 1.150000e+00 1.000000e-01 -6.399926e-04 +85 1.200000e+00 1.000000e-01 -6.701408e-04 +86 1.250000e+00 1.000000e-01 -6.975465e-04 +87 1.300000e+00 1.000000e-01 -7.225210e-04 +88 1.350000e+00 1.000000e-01 -7.453207e-04 +89 1.400000e+00 1.000000e-01 -7.661633e-04 +90 1.450000e+00 1.000000e-01 -7.852375e-04 +91 1.500000e+00 1.000000e-01 -8.034845e-04 +92 1.550000e+00 1.000000e-01 -8.194286e-04 +93 1.600000e+00 1.000000e-01 -8.340548e-04 +94 1.650000e+00 1.000000e-01 -8.474773e-04 +95 1.700000e+00 1.000000e-01 -8.597990e-04 +96 1.750000e+00 1.000000e-01 -8.711120e-04 +97 1.800000e+00 1.000000e-01 -8.814995e-04 +98 -6.000000e-01 1.000000e-01 -7.054641e-13 +99 -5.500000e-01 1.000000e-01 -7.054589e-13 +100 -5.000000e-01 1.000000e-01 -7.054589e-13 +101 -4.500000e-01 1.000000e-01 -7.054589e-13 +102 -4.000000e-01 1.000000e-01 -7.054537e-13 +103 -3.500000e-01 1.000000e-01 -7.054589e-13 +104 -3.000000e-01 1.000000e-01 -7.054589e-13 +105 -2.500000e-01 1.000000e-01 -7.054433e-13 +106 -2.000000e-01 1.000000e-01 -7.054589e-13 +107 -1.500000e-01 1.000000e-01 -7.054745e-13 +108 -1.000000e-01 1.000000e-01 -7.055891e-13 +109 -5.000000e-02 1.000000e-01 -7.062976e-13 +110 -6.938894e-17 1.000000e-01 -7.104235e-13 +111 5.000000e-02 1.000000e-01 -7.343035e-13 +112 1.000000e-01 1.000000e-01 -8.729941e-13 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +113 1.500000e-01 1.000000e-01 -2.728154e-12 +114 2.000000e-01 1.000000e-01 -1.224820e-11 +115 2.500000e-01 1.000000e-01 -6.605421e-11 +116 3.000000e-01 1.000000e-01 -3.674069e-10 +117 3.500000e-01 1.000000e-01 -2.035533e-09 +118 4.000000e-01 1.000000e-01 -1.110584e-08 +119 4.500000e-01 1.000000e-01 -5.890399e-08 +120 5.000000e-01 1.000000e-01 -2.967646e-07 +121 5.500000e-01 1.000000e-01 -1.372660e-06 +122 6.000000e-01 1.000000e-01 -5.663029e-06 +123 6.500000e-01 1.000000e-01 -2.058576e-05 +124 7.000000e-01 1.000000e-01 -6.244120e-05 +125 7.500000e-01 1.000000e-01 -1.411355e-04 +126 8.000000e-01 1.000000e-01 -2.354817e-04 +127 8.500000e-01 1.000000e-01 -3.211673e-04 +128 9.000000e-01 1.000000e-01 -3.919075e-04 +129 9.500000e-01 1.000000e-01 -4.502539e-04 +130 1.000000e+00 1.000000e-01 -4.997296e-04 +131 1.050000e+00 1.000000e-01 -5.428292e-04 +132 1.100000e+00 1.000000e-01 -5.810902e-04 +133 1.150000e+00 1.000000e-01 -6.154581e-04 +134 1.200000e+00 1.000000e-01 -6.465490e-04 +135 1.250000e+00 1.000000e-01 -6.747989e-04 +136 1.300000e+00 1.000000e-01 -7.005406e-04 +137 1.350000e+00 1.000000e-01 -7.240435e-04 +138 1.400000e+00 1.000000e-01 -7.455346e-04 +139 1.450000e+00 1.000000e-01 -7.652095e-04 +140 1.500000e+00 1.000000e-01 -7.832392e-04 +141 1.550000e+00 1.000000e-01 -8.004982e-04 +142 1.600000e+00 1.000000e-01 -8.156085e-04 +143 1.650000e+00 1.000000e-01 -8.294855e-04 +144 1.700000e+00 1.000000e-01 -8.422343e-04 +145 1.750000e+00 1.000000e-01 -8.539497e-04 +146 1.800000e+00 1.000000e-01 -8.647170e-04 +147 -6.000000e-01 1.000000e-01 -1.005465e-12 +148 -5.500000e-01 1.000000e-01 -1.005454e-12 +149 -5.000000e-01 1.000000e-01 -1.005454e-12 +150 -4.500000e-01 1.000000e-01 -1.005454e-12 +151 -4.000000e-01 1.000000e-01 -1.005449e-12 +152 -3.500000e-01 1.000000e-01 -1.005454e-12 +153 -3.000000e-01 1.000000e-01 -1.005454e-12 +154 -2.500000e-01 1.000000e-01 -1.005449e-12 +155 -2.000000e-01 1.000000e-01 -1.005454e-12 +156 -1.500000e-01 1.000000e-01 -1.005465e-12 +157 -1.000000e-01 1.000000e-01 -1.005511e-12 +158 -5.000000e-02 1.000000e-01 -1.005824e-12 +159 -6.938894e-17 1.000000e-01 -1.007663e-12 +160 5.000000e-02 1.000000e-01 -1.018473e-12 +161 1.000000e-01 1.000000e-01 -1.082095e-12 +162 1.500000e-01 1.000000e-01 -1.454304e-12 +163 2.000000e-01 1.000000e-01 -6.470930e-12 +164 2.500000e-01 1.000000e-01 -3.236013e-11 +165 3.000000e-01 1.000000e-01 -1.793786e-10 +166 3.500000e-01 1.000000e-01 -1.005629e-09 +167 4.000000e-01 1.000000e-01 -5.580880e-09 +168 4.500000e-01 1.000000e-01 -3.029343e-08 +169 5.000000e-01 1.000000e-01 -1.578260e-07 +170 5.500000e-01 1.000000e-01 -7.650224e-07 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +171 6.000000e-01 1.000000e-01 -3.332558e-06 +172 6.500000e-01 1.000000e-01 -1.282304e-05 +173 7.000000e-01 1.000000e-01 -4.231400e-05 +174 7.500000e-01 1.000000e-01 -1.077520e-04 +175 8.000000e-01 1.000000e-01 -1.987391e-04 +176 8.500000e-01 1.000000e-01 -2.876520e-04 +177 9.000000e-01 1.000000e-01 -3.624241e-04 +178 9.500000e-01 1.000000e-01 -4.238139e-04 +179 1.000000e+00 1.000000e-01 -4.753905e-04 +180 1.050000e+00 1.000000e-01 -5.199910e-04 +181 1.100000e+00 1.000000e-01 -5.594043e-04 +182 1.150000e+00 1.000000e-01 -5.947186e-04 +183 1.200000e+00 1.000000e-01 -6.266256e-04 +184 1.250000e+00 1.000000e-01 -6.556008e-04 +185 1.300000e+00 1.000000e-01 -6.819989e-04 +186 1.350000e+00 1.000000e-01 -7.061022e-04 +187 1.400000e+00 1.000000e-01 -7.281463e-04 +188 1.450000e+00 1.000000e-01 -7.483329e-04 +189 1.500000e+00 1.000000e-01 -7.668381e-04 +190 1.550000e+00 1.000000e-01 -7.845557e-04 +191 1.600000e+00 1.000000e-01 -8.000784e-04 +192 1.650000e+00 1.000000e-01 -8.143419e-04 +193 1.700000e+00 1.000000e-01 -8.274538e-04 +194 1.750000e+00 1.000000e-01 -8.395112e-04 +195 1.800000e+00 1.000000e-01 -8.506012e-04 +196 -6.000000e-01 1.000000e-01 -1.305460e-12 +197 -5.500000e-01 1.000000e-01 -1.305449e-12 +198 -5.000000e-01 1.000000e-01 -1.305449e-12 +199 -4.500000e-01 1.000000e-01 -1.305449e-12 +200 -4.000000e-01 1.000000e-01 -1.305444e-12 +201 -3.500000e-01 1.000000e-01 -1.305449e-12 +202 -3.000000e-01 1.000000e-01 -1.305449e-12 +203 -2.500000e-01 1.000000e-01 -1.305449e-12 +204 -2.000000e-01 1.000000e-01 -1.305449e-12 +205 -1.500000e-01 1.000000e-01 -1.305449e-12 +206 -1.000000e-01 1.000000e-01 -1.305470e-12 +207 -5.000000e-02 1.000000e-01 -1.305632e-12 +208 -6.938894e-17 1.000000e-01 -1.306564e-12 +209 5.000000e-02 1.000000e-01 -1.312097e-12 +210 1.000000e-01 1.000000e-01 -1.344989e-12 +211 1.500000e-01 1.000000e-01 -1.539363e-12 +212 2.000000e-01 1.000000e-01 -4.200448e-12 +213 2.500000e-01 1.000000e-01 -1.808099e-11 +214 3.000000e-01 1.000000e-01 -9.772865e-11 +215 3.500000e-01 1.000000e-01 -5.504001e-10 +216 4.000000e-01 1.000000e-01 -3.090177e-09 +217 4.500000e-01 1.000000e-01 -1.704934e-08 +218 5.000000e-01 1.000000e-01 -9.096811e-08 +219 5.500000e-01 1.000000e-01 -4.566926e-07 +220 6.000000e-01 1.000000e-01 -2.080334e-06 +221 6.500000e-01 1.000000e-01 -8.388251e-06 +222 7.000000e-01 1.000000e-01 -2.941887e-05 +223 7.500000e-01 1.000000e-01 -8.251241e-05 +224 8.000000e-01 1.000000e-01 -1.676541e-04 +225 8.500000e-01 1.000000e-01 -2.581943e-04 +226 9.000000e-01 1.000000e-01 -3.364864e-04 +227 9.500000e-01 1.000000e-01 -4.007634e-04 +228 1.000000e+00 1.000000e-01 -4.543436e-04 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +229 1.050000e+00 1.000000e-01 -5.003445e-04 +230 1.100000e+00 1.000000e-01 -5.408040e-04 +231 1.150000e+00 1.000000e-01 -5.769593e-04 +232 1.200000e+00 1.000000e-01 -6.095812e-04 +233 1.250000e+00 1.000000e-01 -6.391867e-04 +234 1.300000e+00 1.000000e-01 -6.661525e-04 +235 1.350000e+00 1.000000e-01 -6.907740e-04 +236 1.400000e+00 1.000000e-01 -7.132947e-04 +237 1.450000e+00 1.000000e-01 -7.339221e-04 +238 1.500000e+00 1.000000e-01 -7.528365e-04 +239 1.550000e+00 1.000000e-01 -7.709488e-04 +240 1.600000e+00 1.000000e-01 -7.868262e-04 +241 1.650000e+00 1.000000e-01 -8.014221e-04 +242 1.700000e+00 1.000000e-01 -8.148462e-04 +243 1.750000e+00 1.000000e-01 -8.271975e-04 +244 1.800000e+00 1.000000e-01 -8.385647e-04 +245 -6.000000e-01 1.000000e-01 -1.605455e-12 +246 -5.500000e-01 1.000000e-01 -1.605450e-12 +247 -5.000000e-01 1.000000e-01 -1.605450e-12 +248 -4.500000e-01 1.000000e-01 -1.605450e-12 +249 -4.000000e-01 1.000000e-01 -1.605440e-12 +250 -3.500000e-01 1.000000e-01 -1.605450e-12 +251 -3.000000e-01 1.000000e-01 -1.605450e-12 +252 -2.500000e-01 1.000000e-01 -1.605450e-12 +253 -2.000000e-01 1.000000e-01 -1.605440e-12 +254 -1.500000e-01 1.000000e-01 -1.605450e-12 +255 -1.000000e-01 1.000000e-01 -1.605460e-12 +256 -5.000000e-02 1.000000e-01 -1.605544e-12 +257 -6.938894e-17 1.000000e-01 -1.606070e-12 +258 5.000000e-02 1.000000e-01 -1.609190e-12 +259 1.000000e-01 1.000000e-01 -1.627892e-12 +260 1.500000e-01 1.000000e-01 -1.739285e-12 +261 2.000000e-01 1.000000e-01 -2.396976e-12 +262 2.500000e-01 1.000000e-01 -1.140535e-11 +263 3.000000e-01 1.000000e-01 -5.838957e-11 +264 3.500000e-01 1.000000e-01 -3.277394e-10 +265 4.000000e-01 1.000000e-01 -1.854038e-09 +266 4.500000e-01 1.000000e-01 -1.035120e-08 +267 5.000000e-01 1.000000e-01 -5.620144e-08 +268 5.500000e-01 1.000000e-01 -2.897168e-07 +269 6.000000e-01 1.000000e-01 -1.368444e-06 +270 6.500000e-01 1.000000e-01 -5.742357e-06 +271 7.000000e-01 1.000000e-01 -2.109411e-05 +272 7.500000e-01 1.000000e-01 -6.380498e-05 +273 8.000000e-01 1.000000e-01 -1.417050e-04 +274 8.500000e-01 1.000000e-01 -2.323490e-04 +275 9.000000e-01 1.000000e-01 -3.135605e-04 +276 9.500000e-01 1.000000e-01 -3.805282e-04 +277 1.000000e+00 1.000000e-01 -4.360097e-04 +278 1.050000e+00 1.000000e-01 -4.833205e-04 +279 1.100000e+00 1.000000e-01 -5.247358e-04 +280 1.150000e+00 1.000000e-01 -5.616433e-04 +281 1.200000e+00 1.000000e-01 -5.948956e-04 +282 1.250000e+00 1.000000e-01 -6.250520e-04 +283 1.300000e+00 1.000000e-01 -6.525118e-04 +284 1.350000e+00 1.000000e-01 -6.775830e-04 +285 1.400000e+00 1.000000e-01 -7.005168e-04 +286 1.450000e+00 1.000000e-01 -7.215259e-04 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +287 1.500000e+00 1.000000e-01 -7.407946e-04 +288 1.550000e+00 1.000000e-01 -7.584842e-04 +289 1.600000e+00 1.000000e-01 -7.754334e-04 +290 1.650000e+00 1.000000e-01 -7.903161e-04 +291 1.700000e+00 1.000000e-01 -8.040101e-04 +292 1.750000e+00 1.000000e-01 -8.166153e-04 +293 1.800000e+00 1.000000e-01 -8.282222e-04 +294 -6.000000e-01 1.000000e-01 -1.905466e-12 +295 -5.500000e-01 1.000000e-01 -1.905456e-12 +296 -5.000000e-01 1.000000e-01 -1.905456e-12 +297 -4.500000e-01 1.000000e-01 -1.905456e-12 +298 -4.000000e-01 1.000000e-01 -1.905450e-12 +299 -3.500000e-01 1.000000e-01 -1.905456e-12 +300 -3.000000e-01 1.000000e-01 -1.905456e-12 +301 -2.500000e-01 1.000000e-01 -1.905456e-12 +302 -2.000000e-01 1.000000e-01 -1.905450e-12 +303 -1.500000e-01 1.000000e-01 -1.905450e-12 +304 -1.000000e-01 1.000000e-01 -1.905456e-12 +305 -5.000000e-02 1.000000e-01 -1.905508e-12 +306 -6.938894e-17 1.000000e-01 -1.905826e-12 +307 5.000000e-02 1.000000e-01 -1.907732e-12 +308 1.000000e-01 1.000000e-01 -1.919235e-12 +309 1.500000e-01 1.000000e-01 -1.988197e-12 +310 2.000000e-01 1.000000e-01 -2.397887e-12 +311 2.500000e-01 1.000000e-01 -8.066036e-12 +312 3.000000e-01 1.000000e-01 -3.783388e-11 +313 3.500000e-01 1.000000e-01 -2.096625e-10 +314 4.000000e-01 1.000000e-01 -1.190920e-09 +315 4.500000e-01 1.000000e-01 -6.707421e-09 +316 5.000000e-01 1.000000e-01 -3.689754e-08 +317 5.500000e-01 1.000000e-01 -1.940829e-07 +318 6.000000e-01 1.000000e-01 -9.438692e-07 +319 6.500000e-01 1.000000e-01 -4.098477e-06 +320 7.000000e-01 1.000000e-01 -1.562471e-05 +321 7.500000e-01 1.000000e-01 -5.009754e-05 +322 8.000000e-01 1.000000e-01 -1.203453e-04 +323 8.500000e-01 1.000000e-01 -2.098047e-04 +324 9.000000e-01 1.000000e-01 -2.932966e-04 +325 9.500000e-01 1.000000e-01 -3.627211e-04 +326 1.000000e+00 1.000000e-01 -4.199904e-04 +327 1.050000e+00 1.000000e-01 -4.685233e-04 +328 1.100000e+00 1.000000e-01 -5.108127e-04 +329 1.150000e+00 1.000000e-01 -5.483946e-04 +330 1.200000e+00 1.000000e-01 -5.822039e-04 +331 1.250000e+00 1.000000e-01 -6.128430e-04 +332 1.300000e+00 1.000000e-01 -6.407336e-04 +333 1.350000e+00 1.000000e-01 -6.661958e-04 +334 1.400000e+00 1.000000e-01 -6.894882e-04 +335 1.450000e+00 1.000000e-01 -7.108285e-04 +336 1.500000e+00 1.000000e-01 -7.304043e-04 +337 1.550000e+00 1.000000e-01 -7.483799e-04 +338 1.600000e+00 1.000000e-01 -7.656052e-04 +339 1.650000e+00 1.000000e-01 -7.807369e-04 +340 1.700000e+00 1.000000e-01 -7.946647e-04 +341 1.750000e+00 1.000000e-01 -8.074900e-04 +342 1.800000e+00 1.000000e-01 -8.193043e-04 + + + + diff --git a/tests/bsim4/test6.cir b/tests/bsim4/test6.cir new file mode 100644 index 000000000..d27f44272 --- /dev/null +++ b/tests/bsim4/test6.cir @@ -0,0 +1,16 @@ +** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +** Circuit Description ** +m1 2 1 0 3 n1 L=0.13u W=10.0u rgeoMod=1 +vgs 1 0 1.8 +vbs 3 0 0 +vds 2 0 0.1 + +.dc vgs -0.6 1.8 0.05 vbs 0.0 -1.8 -0.3 + +.options Temp=-55.0 + +.print dc v(2) i(vds) + +.include modelcard.nmos +.end diff --git a/tests/bsim4/test6.out b/tests/bsim4/test6.out new file mode 100644 index 000000000..87b8350a9 --- /dev/null +++ b/tests/bsim4/test6.out @@ -0,0 +1,373 @@ + +No. of Data Rows : 343 + +Circuit: ** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +Doing analysis at TEMP = 218.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. +-------------------------------------------------------------------------------- +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +0 -6.000000e-01 1.000000e-01 -1.000193e-13 +1 -5.500000e-01 1.000000e-01 -1.000140e-13 +2 -5.000000e-01 1.000000e-01 -1.000140e-13 +3 -4.500000e-01 1.000000e-01 -1.000140e-13 +4 -4.000000e-01 1.000000e-01 -1.000140e-13 +5 -3.500000e-01 1.000000e-01 -1.000140e-13 +6 -3.000000e-01 1.000000e-01 -1.000140e-13 +7 -2.500000e-01 1.000000e-01 -1.000140e-13 +8 -2.000000e-01 1.000000e-01 -1.000036e-13 +9 -1.500000e-01 1.000000e-01 -1.000036e-13 +10 -1.000000e-01 1.000000e-01 -1.000036e-13 +11 -5.000000e-02 1.000000e-01 -1.000193e-13 +12 -6.938894e-17 1.000000e-01 -1.000609e-13 +13 5.000000e-02 1.000000e-01 -1.005767e-13 +14 1.000000e-01 1.000000e-01 -1.060205e-13 +15 1.500000e-01 1.000000e-01 -1.632721e-13 +16 2.000000e-01 1.000000e-01 -2.138088e-12 +17 2.500000e-01 1.000000e-01 -2.095813e-11 +18 3.000000e-01 1.000000e-01 -2.112590e-10 +19 3.500000e-01 1.000000e-01 -2.108749e-09 +20 4.000000e-01 1.000000e-01 -2.058580e-08 +21 4.500000e-01 1.000000e-01 -1.914133e-07 +22 5.000000e-01 1.000000e-01 -1.594072e-06 +23 5.500000e-01 1.000000e-01 -1.088875e-05 +24 6.000000e-01 1.000000e-01 -5.690869e-05 +25 6.500000e-01 1.000000e-01 -1.958667e-04 +26 7.000000e-01 1.000000e-01 -4.067024e-04 +27 7.500000e-01 1.000000e-01 -6.019727e-04 +28 8.000000e-01 1.000000e-01 -7.571507e-04 +29 8.500000e-01 1.000000e-01 -8.822754e-04 +30 9.000000e-01 1.000000e-01 -9.872392e-04 +31 9.500000e-01 1.000000e-01 -1.077715e-03 +32 1.000000e+00 1.000000e-01 -1.156931e-03 +33 1.050000e+00 1.000000e-01 -1.226942e-03 +34 1.100000e+00 1.000000e-01 -1.289219e-03 +35 1.150000e+00 1.000000e-01 -1.344899e-03 +36 1.200000e+00 1.000000e-01 -1.394895e-03 +37 1.250000e+00 1.000000e-01 -1.439964e-03 +38 1.300000e+00 1.000000e-01 -1.480733e-03 +39 1.350000e+00 1.000000e-01 -1.517732e-03 +40 1.400000e+00 1.000000e-01 -1.551408e-03 +41 1.450000e+00 1.000000e-01 -1.583555e-03 +42 1.500000e+00 1.000000e-01 -1.611520e-03 +43 1.550000e+00 1.000000e-01 -1.637176e-03 +44 1.600000e+00 1.000000e-01 -1.660762e-03 +45 1.650000e+00 1.000000e-01 -1.682484e-03 +46 1.700000e+00 1.000000e-01 -1.702527e-03 +47 1.750000e+00 1.000000e-01 -1.721048e-03 +48 1.800000e+00 1.000000e-01 -1.738190e-03 +49 -6.000000e-01 1.000000e-01 -4.000145e-13 +50 -5.500000e-01 1.000000e-01 -3.431484e-13 +51 -5.000000e-01 1.000000e-01 -3.525775e-13 +52 -4.500000e-01 1.000000e-01 -4.000093e-13 +53 -4.000000e-01 1.000000e-01 -4.000093e-13 +54 -3.500000e-01 1.000000e-01 -4.000093e-13 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +55 -3.000000e-01 1.000000e-01 -4.000093e-13 +56 -2.500000e-01 1.000000e-01 -4.000093e-13 +57 -2.000000e-01 1.000000e-01 -4.000041e-13 +58 -1.500000e-01 1.000000e-01 -4.000041e-13 +59 -1.000000e-01 1.000000e-01 -4.000041e-13 +60 -5.000000e-02 1.000000e-01 -4.000093e-13 +61 -6.938894e-17 1.000000e-01 -4.000145e-13 +62 5.000000e-02 1.000000e-01 -4.001031e-13 +63 1.000000e-01 1.000000e-01 -4.011241e-13 +64 1.500000e-01 1.000000e-01 -4.121890e-13 +65 2.000000e-01 1.000000e-01 -5.316568e-13 +66 2.500000e-01 1.000000e-01 -4.838082e-12 +67 3.000000e-01 1.000000e-01 -4.703627e-11 +68 3.500000e-01 1.000000e-01 -4.848215e-10 +69 4.000000e-01 1.000000e-01 -4.952508e-09 +70 4.500000e-01 1.000000e-01 -4.913976e-08 +71 5.000000e-01 1.000000e-01 -4.554164e-07 +72 5.500000e-01 1.000000e-01 -3.639573e-06 +73 6.000000e-01 1.000000e-01 -2.298240e-05 +74 6.500000e-01 1.000000e-01 -1.044271e-04 +75 7.000000e-01 1.000000e-01 -2.874956e-04 +76 7.500000e-01 1.000000e-01 -5.002994e-04 +77 8.000000e-01 1.000000e-01 -6.774004e-04 +78 8.500000e-01 1.000000e-01 -8.176252e-04 +79 9.000000e-01 1.000000e-01 -9.328098e-04 +80 9.500000e-01 1.000000e-01 -1.030783e-03 +81 1.000000e+00 1.000000e-01 -1.115879e-03 +82 1.050000e+00 1.000000e-01 -1.190684e-03 +83 1.100000e+00 1.000000e-01 -1.256954e-03 +84 1.150000e+00 1.000000e-01 -1.315998e-03 +85 1.200000e+00 1.000000e-01 -1.368855e-03 +86 1.250000e+00 1.000000e-01 -1.416370e-03 +87 1.300000e+00 1.000000e-01 -1.459244e-03 +88 1.350000e+00 1.000000e-01 -1.498062e-03 +89 1.400000e+00 1.000000e-01 -1.533320e-03 +90 1.450000e+00 1.000000e-01 -1.566943e-03 +91 1.500000e+00 1.000000e-01 -1.596103e-03 +92 1.550000e+00 1.000000e-01 -1.622813e-03 +93 1.600000e+00 1.000000e-01 -1.647329e-03 +94 1.650000e+00 1.000000e-01 -1.669878e-03 +95 1.700000e+00 1.000000e-01 -1.690655e-03 +96 1.750000e+00 1.000000e-01 -1.709832e-03 +97 1.800000e+00 1.000000e-01 -1.727561e-03 +98 -6.000000e-01 1.000000e-01 -7.000255e-13 +99 -5.500000e-01 1.000000e-01 -6.491189e-13 +100 -5.000000e-01 1.000000e-01 -6.573602e-13 +101 -4.500000e-01 1.000000e-01 -7.000202e-13 +102 -4.000000e-01 1.000000e-01 -7.000202e-13 +103 -3.500000e-01 1.000000e-01 -7.000202e-13 +104 -3.000000e-01 1.000000e-01 -7.000202e-13 +105 -2.500000e-01 1.000000e-01 -7.000202e-13 +106 -2.000000e-01 1.000000e-01 -7.000098e-13 +107 -1.500000e-01 1.000000e-01 -7.000098e-13 +108 -1.000000e-01 1.000000e-01 -7.000098e-13 +109 -5.000000e-02 1.000000e-01 -7.000098e-13 +110 -6.938894e-17 1.000000e-01 -7.000098e-13 +111 5.000000e-02 1.000000e-01 -7.000411e-13 +112 1.000000e-01 1.000000e-01 -7.002911e-13 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +113 1.500000e-01 1.000000e-01 -7.031824e-13 +114 2.000000e-01 1.000000e-01 -7.352360e-13 +115 2.500000e-01 1.000000e-01 -1.086112e-12 +116 3.000000e-01 1.000000e-01 -1.404007e-11 +117 3.500000e-01 1.000000e-01 -1.428505e-10 +118 4.000000e-01 1.000000e-01 -1.495753e-09 +119 4.500000e-01 1.000000e-01 -1.540009e-08 +120 5.000000e-01 1.000000e-01 -1.517171e-07 +121 5.500000e-01 1.000000e-01 -1.347013e-06 +122 6.000000e-01 1.000000e-01 -9.797405e-06 +123 6.500000e-01 1.000000e-01 -5.381220e-05 +124 7.000000e-01 1.000000e-01 -1.919330e-04 +125 7.500000e-01 1.000000e-01 -4.049762e-04 +126 8.000000e-01 1.000000e-01 -6.020026e-04 +127 8.500000e-01 1.000000e-01 -7.579984e-04 +128 9.000000e-01 1.000000e-01 -8.835910e-04 +129 9.500000e-01 1.000000e-01 -9.888551e-04 +130 1.000000e+00 1.000000e-01 -1.079488e-03 +131 1.050000e+00 1.000000e-01 -1.158728e-03 +132 1.100000e+00 1.000000e-01 -1.228653e-03 +133 1.150000e+00 1.000000e-01 -1.290760e-03 +134 1.200000e+00 1.000000e-01 -1.346207e-03 +135 1.250000e+00 1.000000e-01 -1.395930e-03 +136 1.300000e+00 1.000000e-01 -1.440696e-03 +137 1.350000e+00 1.000000e-01 -1.481147e-03 +138 1.400000e+00 1.000000e-01 -1.517819e-03 +139 1.450000e+00 1.000000e-01 -1.551166e-03 +140 1.500000e+00 1.000000e-01 -1.582985e-03 +141 1.550000e+00 1.000000e-01 -1.610626e-03 +142 1.600000e+00 1.000000e-01 -1.635966e-03 +143 1.650000e+00 1.000000e-01 -1.659245e-03 +144 1.700000e+00 1.000000e-01 -1.680670e-03 +145 1.750000e+00 1.000000e-01 -1.700426e-03 +146 1.800000e+00 1.000000e-01 -1.718671e-03 +147 -6.000000e-01 1.000000e-01 -1.000021e-12 +148 -5.500000e-01 1.000000e-01 -9.525524e-13 +149 -5.000000e-01 1.000000e-01 -9.600905e-13 +150 -4.500000e-01 1.000000e-01 -1.000016e-12 +151 -4.000000e-01 1.000000e-01 -1.000016e-12 +152 -3.500000e-01 1.000000e-01 -1.000016e-12 +153 -3.000000e-01 1.000000e-01 -1.000016e-12 +154 -2.500000e-01 1.000000e-01 -1.000016e-12 +155 -2.000000e-01 1.000000e-01 -1.000010e-12 +156 -1.500000e-01 1.000000e-01 -1.000010e-12 +157 -1.000000e-01 1.000000e-01 -1.000010e-12 +158 -5.000000e-02 1.000000e-01 -1.000010e-12 +159 -6.938894e-17 1.000000e-01 -1.000016e-12 +160 5.000000e-02 1.000000e-01 -1.000021e-12 +161 1.000000e-01 1.000000e-01 -1.000088e-12 +162 1.500000e-01 1.000000e-01 -1.001037e-12 +163 2.000000e-01 1.000000e-01 -1.011580e-12 +164 2.500000e-01 1.000000e-01 -1.129090e-12 +165 3.000000e-01 1.000000e-01 -5.597340e-12 +166 3.500000e-01 1.000000e-01 -5.088697e-11 +167 4.000000e-01 1.000000e-01 -5.360411e-10 +168 4.500000e-01 1.000000e-01 -5.646190e-09 +169 5.000000e-01 1.000000e-01 -5.773047e-08 +170 5.500000e-01 1.000000e-01 -5.487256e-07 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +171 6.000000e-01 1.000000e-01 -4.447973e-06 +172 6.500000e-01 1.000000e-01 -2.802096e-05 +173 7.000000e-01 1.000000e-01 -1.229255e-04 +174 7.500000e-01 1.000000e-01 -3.183337e-04 +175 8.000000e-01 1.000000e-01 -5.299480e-04 +176 8.500000e-01 1.000000e-01 -7.019582e-04 +177 9.000000e-01 1.000000e-01 -8.382860e-04 +178 9.500000e-01 1.000000e-01 -9.507825e-04 +179 1.000000e+00 1.000000e-01 -1.046723e-03 +180 1.050000e+00 1.000000e-01 -1.130127e-03 +181 1.100000e+00 1.000000e-01 -1.203447e-03 +182 1.150000e+00 1.000000e-01 -1.268377e-03 +183 1.200000e+00 1.000000e-01 -1.326202e-03 +184 1.250000e+00 1.000000e-01 -1.377943e-03 +185 1.300000e+00 1.000000e-01 -1.424435e-03 +186 1.350000e+00 1.000000e-01 -1.466369e-03 +187 1.400000e+00 1.000000e-01 -1.504323e-03 +188 1.450000e+00 1.000000e-01 -1.538783e-03 +189 1.500000e+00 1.000000e-01 -1.571640e-03 +190 1.550000e+00 1.000000e-01 -1.600121e-03 +191 1.600000e+00 1.000000e-01 -1.626202e-03 +192 1.650000e+00 1.000000e-01 -1.650135e-03 +193 1.700000e+00 1.000000e-01 -1.672141e-03 +194 1.750000e+00 1.000000e-01 -1.692413e-03 +195 1.800000e+00 1.000000e-01 -1.711119e-03 +196 -6.000000e-01 1.000000e-01 -1.300016e-12 +197 -5.500000e-01 1.000000e-01 -1.254668e-12 +198 -5.000000e-01 1.000000e-01 -1.261758e-12 +199 -4.500000e-01 1.000000e-01 -1.300011e-12 +200 -4.000000e-01 1.000000e-01 -1.300011e-12 +201 -3.500000e-01 1.000000e-01 -1.300011e-12 +202 -3.000000e-01 1.000000e-01 -1.300011e-12 +203 -2.500000e-01 1.000000e-01 -1.300011e-12 +204 -2.000000e-01 1.000000e-01 -1.300006e-12 +205 -1.500000e-01 1.000000e-01 -1.300006e-12 +206 -1.000000e-01 1.000000e-01 -1.300006e-12 +207 -5.000000e-02 1.000000e-01 -1.300006e-12 +208 -6.938894e-17 1.000000e-01 -1.300011e-12 +209 5.000000e-02 1.000000e-01 -1.300011e-12 +210 1.000000e-01 1.000000e-01 -1.300037e-12 +211 1.500000e-01 1.000000e-01 -1.300386e-12 +212 2.000000e-01 1.000000e-01 -1.304449e-12 +213 2.500000e-01 1.000000e-01 -1.350204e-12 +214 3.000000e-01 1.000000e-01 -3.129239e-12 +215 3.500000e-01 1.000000e-01 -2.142343e-11 +216 4.000000e-01 1.000000e-01 -2.202598e-10 +217 4.500000e-01 1.000000e-01 -2.350796e-09 +218 5.000000e-01 1.000000e-01 -2.462174e-08 +219 5.500000e-01 1.000000e-01 -2.446827e-07 +220 6.000000e-01 1.000000e-01 -2.149122e-06 +221 6.500000e-01 1.000000e-01 -1.508672e-05 +222 7.000000e-01 1.000000e-01 -7.729684e-05 +223 7.500000e-01 1.000000e-01 -2.434538e-04 +224 8.000000e-01 1.000000e-01 -4.613683e-04 +225 8.500000e-01 1.000000e-01 -6.487612e-04 +226 9.000000e-01 1.000000e-01 -7.961391e-04 +227 9.500000e-01 1.000000e-01 -9.158882e-04 +228 1.000000e+00 1.000000e-01 -1.016971e-03 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +229 1.050000e+00 1.000000e-01 -1.104319e-03 +230 1.100000e+00 1.000000e-01 -1.180813e-03 +231 1.150000e+00 1.000000e-01 -1.248365e-03 +232 1.200000e+00 1.000000e-01 -1.308386e-03 +233 1.250000e+00 1.000000e-01 -1.361986e-03 +234 1.300000e+00 1.000000e-01 -1.410062e-03 +235 1.350000e+00 1.000000e-01 -1.453353e-03 +236 1.400000e+00 1.000000e-01 -1.492477e-03 +237 1.450000e+00 1.000000e-01 -1.527951e-03 +238 1.500000e+00 1.000000e-01 -1.561753e-03 +239 1.550000e+00 1.000000e-01 -1.590997e-03 +240 1.600000e+00 1.000000e-01 -1.617747e-03 +241 1.650000e+00 1.000000e-01 -1.642271e-03 +242 1.700000e+00 1.000000e-01 -1.664800e-03 +243 1.750000e+00 1.000000e-01 -1.685537e-03 +244 1.800000e+00 1.000000e-01 -1.704657e-03 +245 -6.000000e-01 1.000000e-01 -1.600017e-12 +246 -5.500000e-01 1.000000e-01 -1.556012e-12 +247 -5.000000e-01 1.000000e-01 -1.562790e-12 +248 -4.500000e-01 1.000000e-01 -1.600006e-12 +249 -4.000000e-01 1.000000e-01 -1.600006e-12 +250 -3.500000e-01 1.000000e-01 -1.600006e-12 +251 -3.000000e-01 1.000000e-01 -1.600006e-12 +252 -2.500000e-01 1.000000e-01 -1.600006e-12 +253 -2.000000e-01 1.000000e-01 -1.600001e-12 +254 -1.500000e-01 1.000000e-01 -1.600001e-12 +255 -1.000000e-01 1.000000e-01 -1.600001e-12 +256 -5.000000e-02 1.000000e-01 -1.600001e-12 +257 -6.938894e-17 1.000000e-01 -1.600001e-12 +258 5.000000e-02 1.000000e-01 -1.600006e-12 +259 1.000000e-01 1.000000e-01 -1.600022e-12 +260 1.500000e-01 1.000000e-01 -1.600168e-12 +261 2.000000e-01 1.000000e-01 -1.601923e-12 +262 2.500000e-01 1.000000e-01 -1.622032e-12 +263 3.000000e-01 1.000000e-01 -1.849173e-12 +264 3.500000e-01 1.000000e-01 -1.069001e-11 +265 4.000000e-01 1.000000e-01 -1.016146e-10 +266 4.500000e-01 1.000000e-01 -1.088318e-09 +267 5.000000e-01 1.000000e-01 -1.158497e-08 +268 5.500000e-01 1.000000e-01 -1.186226e-07 +269 6.000000e-01 1.000000e-01 -1.104044e-06 +270 6.500000e-01 1.000000e-01 -8.463593e-06 +271 7.000000e-01 1.000000e-01 -4.876417e-05 +272 7.500000e-01 1.000000e-01 -1.823243e-04 +273 8.000000e-01 1.000000e-01 -3.970985e-04 +274 8.500000e-01 1.000000e-01 -5.980989e-04 +275 9.000000e-01 1.000000e-01 -7.566963e-04 +276 9.500000e-01 1.000000e-01 -8.837459e-04 +277 1.000000e+00 1.000000e-01 -9.898422e-04 +278 1.050000e+00 1.000000e-01 -1.080944e-03 +279 1.100000e+00 1.000000e-01 -1.160416e-03 +280 1.150000e+00 1.000000e-01 -1.230408e-03 +281 1.200000e+00 1.000000e-01 -1.292466e-03 +282 1.250000e+00 1.000000e-01 -1.347781e-03 +283 1.300000e+00 1.000000e-01 -1.397314e-03 +284 1.350000e+00 1.000000e-01 -1.441852e-03 +285 1.400000e+00 1.000000e-01 -1.482048e-03 +286 1.450000e+00 1.000000e-01 -1.518449e-03 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +287 1.500000e+00 1.000000e-01 -1.551516e-03 +288 1.550000e+00 1.000000e-01 -1.583052e-03 +289 1.600000e+00 1.000000e-01 -1.610409e-03 +290 1.650000e+00 1.000000e-01 -1.635468e-03 +291 1.700000e+00 1.000000e-01 -1.658470e-03 +292 1.750000e+00 1.000000e-01 -1.679627e-03 +293 1.800000e+00 1.000000e-01 -1.699121e-03 +294 -6.000000e-01 1.000000e-01 -1.900022e-12 +295 -5.500000e-01 1.000000e-01 -1.856893e-12 +296 -5.000000e-01 1.000000e-01 -1.863462e-12 +297 -4.500000e-01 1.000000e-01 -1.900017e-12 +298 -4.000000e-01 1.000000e-01 -1.900017e-12 +299 -3.500000e-01 1.000000e-01 -1.900017e-12 +300 -3.000000e-01 1.000000e-01 -1.900017e-12 +301 -2.500000e-01 1.000000e-01 -1.900017e-12 +302 -2.000000e-01 1.000000e-01 -1.900012e-12 +303 -1.500000e-01 1.000000e-01 -1.900012e-12 +304 -1.000000e-01 1.000000e-01 -1.900012e-12 +305 -5.000000e-02 1.000000e-01 -1.900012e-12 +306 -6.938894e-17 1.000000e-01 -1.900012e-12 +307 5.000000e-02 1.000000e-01 -1.900012e-12 +308 1.000000e-01 1.000000e-01 -1.900012e-12 +309 1.500000e-01 1.000000e-01 -1.900085e-12 +310 2.000000e-01 1.000000e-01 -1.900934e-12 +311 2.500000e-01 1.000000e-01 -1.910686e-12 +312 3.000000e-01 1.000000e-01 -2.021964e-12 +313 3.500000e-01 1.000000e-01 -6.415028e-12 +314 4.000000e-01 1.000000e-01 -5.202046e-11 +315 4.500000e-01 1.000000e-01 -5.518104e-10 +316 5.000000e-01 1.000000e-01 -5.937215e-09 +317 5.500000e-01 1.000000e-01 -6.206962e-08 +318 6.000000e-01 1.000000e-01 -6.022249e-07 +319 6.500000e-01 1.000000e-01 -4.955723e-06 +320 7.000000e-01 1.000000e-01 -3.133270e-05 +321 7.500000e-01 1.000000e-01 -1.349761e-04 +322 8.000000e-01 1.000000e-01 -3.382617e-04 +323 8.500000e-01 1.000000e-01 -5.499627e-04 +324 9.000000e-01 1.000000e-01 -7.196956e-04 +325 9.500000e-01 1.000000e-01 -8.540791e-04 +326 1.000000e+00 1.000000e-01 -9.650757e-04 +327 1.050000e+00 1.000000e-01 -1.059756e-03 +328 1.100000e+00 1.000000e-01 -1.142026e-03 +329 1.150000e+00 1.000000e-01 -1.214292e-03 +330 1.200000e+00 1.000000e-01 -1.278236e-03 +331 1.250000e+00 1.000000e-01 -1.335136e-03 +332 1.300000e+00 1.000000e-01 -1.386011e-03 +333 1.350000e+00 1.000000e-01 -1.431693e-03 +334 1.400000e+00 1.000000e-01 -1.472871e-03 +335 1.450000e+00 1.000000e-01 -1.510119e-03 +336 1.500000e+00 1.000000e-01 -1.543920e-03 +337 1.550000e+00 1.000000e-01 -1.576141e-03 +338 1.600000e+00 1.000000e-01 -1.604049e-03 +339 1.650000e+00 1.000000e-01 -1.629594e-03 +340 1.700000e+00 1.000000e-01 -1.653025e-03 +341 1.750000e+00 1.000000e-01 -1.674561e-03 +342 1.800000e+00 1.000000e-01 -1.694392e-03 + + + + diff --git a/tests/bsim4/test7.cir b/tests/bsim4/test7.cir new file mode 100644 index 000000000..b429c8be1 --- /dev/null +++ b/tests/bsim4/test7.cir @@ -0,0 +1,16 @@ +** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +** Circuit Description ** +m1 2 1 0 3 n1 L=0.13u W=10.0u rgeoMod=1 +vgs 1 0 1.8 +vbs 3 0 0 +vds 2 0 0.1 + +.dc vgs -0.6 1.8 0.05 vbs 0.0 -1.8 -0.3 + +.options Temp=100.0 + +.print dc v(2) i(vds) + +.include modelcard.nmos +.end diff --git a/tests/bsim4/test7.out b/tests/bsim4/test7.out new file mode 100644 index 000000000..109b23b46 --- /dev/null +++ b/tests/bsim4/test7.out @@ -0,0 +1,373 @@ + +No. of Data Rows : 343 + +Circuit: ** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +Doing analysis at TEMP = 373.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +** NMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. +-------------------------------------------------------------------------------- +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +0 -6.000000e-01 1.000000e-01 -8.862897e-11 +1 -5.500000e-01 1.000000e-01 -8.862897e-11 +2 -5.000000e-01 1.000000e-01 -8.862898e-11 +3 -4.500000e-01 1.000000e-01 -8.862898e-11 +4 -4.000000e-01 1.000000e-01 -8.862898e-11 +5 -3.500000e-01 1.000000e-01 -8.862906e-11 +6 -3.000000e-01 1.000000e-01 -8.862933e-11 +7 -2.500000e-01 1.000000e-01 -8.863045e-11 +8 -2.000000e-01 1.000000e-01 -8.863486e-11 +9 -1.500000e-01 1.000000e-01 -8.865236e-11 +10 -1.000000e-01 1.000000e-01 -8.872185e-11 +11 -5.000000e-02 1.000000e-01 -8.899775e-11 +12 -6.938894e-17 1.000000e-01 -9.009288e-11 +13 5.000000e-02 1.000000e-01 -9.832248e-11 +14 1.000000e-01 1.000000e-01 -1.270075e-10 +15 1.500000e-01 1.000000e-01 -2.395713e-10 +16 2.000000e-01 1.000000e-01 -6.777450e-10 +17 2.500000e-01 1.000000e-01 -2.366195e-09 +18 3.000000e-01 1.000000e-01 -8.780198e-09 +19 3.500000e-01 1.000000e-01 -3.261874e-08 +20 4.000000e-01 1.000000e-01 -1.182088e-07 +21 4.500000e-01 1.000000e-01 -4.097573e-07 +22 5.000000e-01 1.000000e-01 -1.334680e-06 +23 5.500000e-01 1.000000e-01 -4.045208e-06 +24 6.000000e-01 1.000000e-01 -1.138766e-05 +25 6.500000e-01 1.000000e-01 -2.917740e-05 +26 7.000000e-01 1.000000e-01 -6.387909e-05 +27 7.500000e-01 1.000000e-01 -1.134781e-04 +28 8.000000e-01 1.000000e-01 -1.670628e-04 +29 8.500000e-01 1.000000e-01 -2.160167e-04 +30 9.000000e-01 1.000000e-01 -2.572735e-04 +31 9.500000e-01 1.000000e-01 -2.915340e-04 +32 1.000000e+00 1.000000e-01 -3.203461e-04 +33 1.050000e+00 1.000000e-01 -3.450892e-04 +34 1.100000e+00 1.000000e-01 -3.667545e-04 +35 1.150000e+00 1.000000e-01 -3.860071e-04 +36 1.200000e+00 1.000000e-01 -4.032916e-04 +37 1.250000e+00 1.000000e-01 -4.189138e-04 +38 1.300000e+00 1.000000e-01 -4.330942e-04 +39 1.350000e+00 1.000000e-01 -4.460007e-04 +40 1.400000e+00 1.000000e-01 -4.577671e-04 +41 1.450000e+00 1.000000e-01 -4.685048e-04 +42 1.500000e+00 1.000000e-01 -4.787609e-04 +43 1.550000e+00 1.000000e-01 -4.876744e-04 +44 1.600000e+00 1.000000e-01 -4.958154e-04 +45 1.650000e+00 1.000000e-01 -5.032483e-04 +46 1.700000e+00 1.000000e-01 -5.100316e-04 +47 1.750000e+00 1.000000e-01 -5.162178e-04 +48 1.800000e+00 1.000000e-01 -5.218546e-04 +49 -6.000000e-01 1.000000e-01 -9.306153e-11 +50 -5.500000e-01 1.000000e-01 -9.306154e-11 +51 -5.000000e-01 1.000000e-01 -9.306154e-11 +52 -4.500000e-01 1.000000e-01 -9.306154e-11 +53 -4.000000e-01 1.000000e-01 -9.306154e-11 +54 -3.500000e-01 1.000000e-01 -9.306156e-11 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +55 -3.000000e-01 1.000000e-01 -9.306167e-11 +56 -2.500000e-01 1.000000e-01 -9.306206e-11 +57 -2.000000e-01 1.000000e-01 -9.306365e-11 +58 -1.500000e-01 1.000000e-01 -9.307010e-11 +59 -1.000000e-01 1.000000e-01 -9.309630e-11 +60 -5.000000e-02 1.000000e-01 -9.320258e-11 +61 -6.938894e-17 1.000000e-01 -9.363366e-11 +62 5.000000e-02 1.000000e-01 -9.698234e-11 +63 1.000000e-01 1.000000e-01 -1.089282e-10 +64 1.500000e-01 1.000000e-01 -1.568615e-10 +65 2.000000e-01 1.000000e-01 -3.477797e-10 +66 2.500000e-01 1.000000e-01 -1.101546e-09 +67 3.000000e-01 1.000000e-01 -4.042850e-09 +68 3.500000e-01 1.000000e-01 -1.532364e-08 +69 4.000000e-01 1.000000e-01 -5.742622e-08 +70 4.500000e-01 1.000000e-01 -2.079320e-07 +71 5.000000e-01 1.000000e-01 -7.129407e-07 +72 5.500000e-01 1.000000e-01 -2.278331e-06 +73 6.000000e-01 1.000000e-01 -6.749697e-06 +74 6.500000e-01 1.000000e-01 -1.840185e-05 +75 7.000000e-01 1.000000e-01 -4.412485e-05 +76 7.500000e-01 1.000000e-01 -8.677524e-05 +77 8.000000e-01 1.000000e-01 -1.384578e-04 +78 8.500000e-01 1.000000e-01 -1.885660e-04 +79 9.000000e-01 1.000000e-01 -2.318957e-04 +80 9.500000e-01 1.000000e-01 -2.679957e-04 +81 1.000000e+00 1.000000e-01 -2.982016e-04 +82 1.050000e+00 1.000000e-01 -3.239762e-04 +83 1.100000e+00 1.000000e-01 -3.464319e-04 +84 1.150000e+00 1.000000e-01 -3.663250e-04 +85 1.200000e+00 1.000000e-01 -3.841570e-04 +86 1.250000e+00 1.000000e-01 -4.002674e-04 +87 1.300000e+00 1.000000e-01 -4.148955e-04 +88 1.350000e+00 1.000000e-01 -4.282200e-04 +89 1.400000e+00 1.000000e-01 -4.403811e-04 +90 1.450000e+00 1.000000e-01 -4.514940e-04 +91 1.500000e+00 1.000000e-01 -4.621163e-04 +92 1.550000e+00 1.000000e-01 -4.713717e-04 +93 1.600000e+00 1.000000e-01 -4.798406e-04 +94 1.650000e+00 1.000000e-01 -4.875887e-04 +95 1.700000e+00 1.000000e-01 -4.946750e-04 +96 1.750000e+00 1.000000e-01 -5.011530e-04 +97 1.800000e+00 1.000000e-01 -5.070710e-04 +98 -6.000000e-01 1.000000e-01 -9.336192e-11 +99 -5.500000e-01 1.000000e-01 -9.336192e-11 +100 -5.000000e-01 1.000000e-01 -9.336192e-11 +101 -4.500000e-01 1.000000e-01 -9.336192e-11 +102 -4.000000e-01 1.000000e-01 -9.336191e-11 +103 -3.500000e-01 1.000000e-01 -9.336192e-11 +104 -3.000000e-01 1.000000e-01 -9.336197e-11 +105 -2.500000e-01 1.000000e-01 -9.336214e-11 +106 -2.000000e-01 1.000000e-01 -9.336285e-11 +107 -1.500000e-01 1.000000e-01 -9.336582e-11 +108 -1.000000e-01 1.000000e-01 -9.337801e-11 +109 -5.000000e-02 1.000000e-01 -9.342817e-11 +110 -6.938894e-17 1.000000e-01 -9.363464e-11 +111 5.000000e-02 1.000000e-01 -9.448421e-11 +112 1.000000e-01 1.000000e-01 -1.012154e-10 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +113 1.500000e-01 1.000000e-01 -1.254096e-10 +114 2.000000e-01 1.000000e-01 -2.232495e-10 +115 2.500000e-01 1.000000e-01 -6.157445e-10 +116 3.000000e-01 1.000000e-01 -2.174314e-09 +117 3.500000e-01 1.000000e-01 -8.274559e-09 +118 4.000000e-01 1.000000e-01 -3.162328e-08 +119 4.500000e-01 1.000000e-01 -1.178464e-07 +120 5.000000e-01 1.000000e-01 -4.191511e-07 +121 5.500000e-01 1.000000e-01 -1.395839e-06 +122 6.000000e-01 1.000000e-01 -4.306534e-06 +123 6.500000e-01 1.000000e-01 -1.226607e-05 +124 7.000000e-01 1.000000e-01 -3.136770e-05 +125 7.500000e-01 1.000000e-01 -6.715314e-05 +126 8.000000e-01 1.000000e-01 -1.156304e-04 +127 8.500000e-01 1.000000e-01 -1.659977e-04 +128 9.000000e-01 1.000000e-01 -2.109421e-04 +129 9.500000e-01 1.000000e-01 -2.486877e-04 +130 1.000000e+00 1.000000e-01 -2.801810e-04 +131 1.050000e+00 1.000000e-01 -3.068995e-04 +132 1.100000e+00 1.000000e-01 -3.300585e-04 +133 1.150000e+00 1.000000e-01 -3.505032e-04 +134 1.200000e+00 1.000000e-01 -3.687939e-04 +135 1.250000e+00 1.000000e-01 -3.853049e-04 +136 1.300000e+00 1.000000e-01 -4.002958e-04 +137 1.350000e+00 1.000000e-01 -4.139565e-04 +138 1.400000e+00 1.000000e-01 -4.264336e-04 +139 1.450000e+00 1.000000e-01 -4.378460e-04 +140 1.500000e+00 1.000000e-01 -4.482938e-04 +141 1.550000e+00 1.000000e-01 -4.582889e-04 +142 1.600000e+00 1.000000e-01 -4.670192e-04 +143 1.650000e+00 1.000000e-01 -4.750186e-04 +144 1.700000e+00 1.000000e-01 -4.823467e-04 +145 1.750000e+00 1.000000e-01 -4.890575e-04 +146 1.800000e+00 1.000000e-01 -4.951999e-04 +147 -6.000000e-01 1.000000e-01 -9.366191e-11 +148 -5.500000e-01 1.000000e-01 -9.366191e-11 +149 -5.000000e-01 1.000000e-01 -9.366191e-11 +150 -4.500000e-01 1.000000e-01 -9.366191e-11 +151 -4.000000e-01 1.000000e-01 -9.366191e-11 +152 -3.500000e-01 1.000000e-01 -9.366191e-11 +153 -3.000000e-01 1.000000e-01 -9.366194e-11 +154 -2.500000e-01 1.000000e-01 -9.366202e-11 +155 -2.000000e-01 1.000000e-01 -9.366240e-11 +156 -1.500000e-01 1.000000e-01 -9.366398e-11 +157 -1.000000e-01 1.000000e-01 -9.367052e-11 +158 -5.000000e-02 1.000000e-01 -9.369774e-11 +159 -6.938894e-17 1.000000e-01 -9.381095e-11 +160 5.000000e-02 1.000000e-01 -9.428172e-11 +161 1.000000e-01 1.000000e-01 -9.807244e-11 +162 1.500000e-01 1.000000e-01 -1.118525e-10 +163 2.000000e-01 1.000000e-01 -1.681895e-10 +164 2.500000e-01 1.000000e-01 -3.967791e-10 +165 3.000000e-01 1.000000e-01 -1.315769e-09 +166 3.500000e-01 1.000000e-01 -4.964149e-09 +167 4.000000e-01 1.000000e-01 -1.917552e-08 +168 4.500000e-01 1.000000e-01 -7.287390e-08 +169 5.000000e-01 1.000000e-01 -2.662297e-07 +170 5.500000e-01 1.000000e-01 -9.157017e-07 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +171 6.000000e-01 1.000000e-01 -2.921530e-06 +172 6.500000e-01 1.000000e-01 -8.607067e-06 +173 7.000000e-01 1.000000e-01 -2.304803e-05 +174 7.500000e-01 1.000000e-01 -5.279791e-05 +175 8.000000e-01 1.000000e-01 -9.744023e-05 +176 8.500000e-01 1.000000e-01 -1.472519e-04 +177 9.000000e-01 1.000000e-01 -1.933385e-04 +178 9.500000e-01 1.000000e-01 -2.325093e-04 +179 1.000000e+00 1.000000e-01 -2.651752e-04 +180 1.050000e+00 1.000000e-01 -2.927566e-04 +181 1.100000e+00 1.000000e-01 -3.165474e-04 +182 1.150000e+00 1.000000e-01 -3.374752e-04 +183 1.200000e+00 1.000000e-01 -3.561579e-04 +184 1.250000e+00 1.000000e-01 -3.730049e-04 +185 1.300000e+00 1.000000e-01 -3.882961e-04 +186 1.350000e+00 1.000000e-01 -4.022330e-04 +187 1.400000e+00 1.000000e-01 -4.149687e-04 +188 1.450000e+00 1.000000e-01 -4.266259e-04 +189 1.500000e+00 1.000000e-01 -4.373067e-04 +190 1.550000e+00 1.000000e-01 -4.475297e-04 +191 1.600000e+00 1.000000e-01 -4.564733e-04 +192 1.650000e+00 1.000000e-01 -4.646777e-04 +193 1.700000e+00 1.000000e-01 -4.722031e-04 +194 1.750000e+00 1.000000e-01 -4.791040e-04 +195 1.800000e+00 1.000000e-01 -4.854297e-04 +196 -6.000000e-01 1.000000e-01 -9.396192e-11 +197 -5.500000e-01 1.000000e-01 -9.396191e-11 +198 -5.000000e-01 1.000000e-01 -9.396191e-11 +199 -4.500000e-01 1.000000e-01 -9.396190e-11 +200 -4.000000e-01 1.000000e-01 -9.396191e-11 +201 -3.500000e-01 1.000000e-01 -9.396192e-11 +202 -3.000000e-01 1.000000e-01 -9.396192e-11 +203 -2.500000e-01 1.000000e-01 -9.396197e-11 +204 -2.000000e-01 1.000000e-01 -9.396219e-11 +205 -1.500000e-01 1.000000e-01 -9.396312e-11 +206 -1.000000e-01 1.000000e-01 -9.396704e-11 +207 -5.000000e-02 1.000000e-01 -9.398341e-11 +208 -6.938894e-17 1.000000e-01 -9.405212e-11 +209 5.000000e-02 1.000000e-01 -9.434010e-11 +210 1.000000e-01 1.000000e-01 -9.668775e-11 +211 1.500000e-01 1.000000e-01 -1.052955e-10 +212 2.000000e-01 1.000000e-01 -1.407784e-10 +213 2.500000e-01 1.000000e-01 -2.859909e-10 +214 3.000000e-01 1.000000e-01 -8.751869e-10 +215 3.500000e-01 1.000000e-01 -3.238919e-09 +216 4.000000e-01 1.000000e-01 -1.256509e-08 +217 4.500000e-01 1.000000e-01 -4.840193e-08 +218 5.000000e-01 1.000000e-01 -1.803823e-07 +219 5.500000e-01 1.000000e-01 -6.363995e-07 +220 6.000000e-01 1.000000e-01 -2.087914e-06 +221 6.500000e-01 1.000000e-01 -6.323625e-06 +222 7.000000e-01 1.000000e-01 -1.752175e-05 +223 7.500000e-01 1.000000e-01 -4.230854e-05 +224 8.000000e-01 1.000000e-01 -8.298306e-05 +225 8.500000e-01 1.000000e-01 -1.316419e-04 +226 9.000000e-01 1.000000e-01 -1.784346e-04 +227 9.500000e-01 1.000000e-01 -2.188031e-04 +228 1.000000e+00 1.000000e-01 -2.525216e-04 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +229 1.050000e+00 1.000000e-01 -2.808877e-04 +230 1.100000e+00 1.000000e-01 -3.052471e-04 +231 1.150000e+00 1.000000e-01 -3.266010e-04 +232 1.200000e+00 1.000000e-01 -3.456221e-04 +233 1.250000e+00 1.000000e-01 -3.627541e-04 +234 1.300000e+00 1.000000e-01 -3.782971e-04 +235 1.350000e+00 1.000000e-01 -3.924638e-04 +236 1.400000e+00 1.000000e-01 -4.054137e-04 +237 1.450000e+00 1.000000e-01 -4.172731e-04 +238 1.500000e+00 1.000000e-01 -4.281465e-04 +239 1.550000e+00 1.000000e-01 -4.385575e-04 +240 1.600000e+00 1.000000e-01 -4.476772e-04 +241 1.650000e+00 1.000000e-01 -4.560509e-04 +242 1.700000e+00 1.000000e-01 -4.637393e-04 +243 1.750000e+00 1.000000e-01 -4.707973e-04 +244 1.800000e+00 1.000000e-01 -4.772746e-04 +245 -6.000000e-01 1.000000e-01 -9.426192e-11 +246 -5.500000e-01 1.000000e-01 -9.426191e-11 +247 -5.000000e-01 1.000000e-01 -9.426191e-11 +248 -4.500000e-01 1.000000e-01 -9.426191e-11 +249 -4.000000e-01 1.000000e-01 -9.426191e-11 +250 -3.500000e-01 1.000000e-01 -9.426191e-11 +251 -3.000000e-01 1.000000e-01 -9.426191e-11 +252 -2.500000e-01 1.000000e-01 -9.426195e-11 +253 -2.000000e-01 1.000000e-01 -9.426209e-11 +254 -1.500000e-01 1.000000e-01 -9.426269e-11 +255 -1.000000e-01 1.000000e-01 -9.426522e-11 +256 -5.000000e-02 1.000000e-01 -9.427593e-11 +257 -6.938894e-17 1.000000e-01 -9.432110e-11 +258 5.000000e-02 1.000000e-01 -9.451167e-11 +259 1.000000e-01 1.000000e-01 -9.531548e-11 +260 1.500000e-01 1.000000e-01 -1.018706e-10 +261 2.000000e-01 1.000000e-01 -1.258948e-10 +262 2.500000e-01 1.000000e-01 -2.248734e-10 +263 3.000000e-01 1.000000e-01 -6.293544e-10 +264 3.500000e-01 1.000000e-01 -2.265131e-09 +265 4.000000e-01 1.000000e-01 -8.782163e-09 +266 4.500000e-01 1.000000e-01 -3.414445e-08 +267 5.000000e-01 1.000000e-01 -1.291729e-07 +268 5.500000e-01 1.000000e-01 -4.649717e-07 +269 6.000000e-01 1.000000e-01 -1.561305e-06 +270 6.500000e-01 1.000000e-01 -4.840080e-06 +271 7.000000e-01 1.000000e-01 -1.376980e-05 +272 7.500000e-01 1.000000e-01 -3.462674e-05 +273 8.000000e-01 1.000000e-01 -7.153611e-05 +274 8.500000e-01 1.000000e-01 -1.186678e-04 +275 9.000000e-01 1.000000e-01 -1.657966e-04 +276 9.500000e-01 1.000000e-01 -2.071422e-04 +277 1.000000e+00 1.000000e-01 -2.417904e-04 +278 1.050000e+00 1.000000e-01 -2.708632e-04 +279 1.100000e+00 1.000000e-01 -2.957326e-04 +280 1.150000e+00 1.000000e-01 -3.174625e-04 +281 1.200000e+00 1.000000e-01 -3.367766e-04 +282 1.250000e+00 1.000000e-01 -3.541515e-04 +283 1.300000e+00 1.000000e-01 -3.699066e-04 +284 1.350000e+00 1.000000e-01 -3.842654e-04 +285 1.400000e+00 1.000000e-01 -3.973937e-04 +286 1.450000e+00 1.000000e-01 -4.094212e-04 + +Index v-sweep v(2) vds#branch +-------------------------------------------------------------------------------- +287 1.500000e+00 1.000000e-01 -4.204544e-04 +288 1.550000e+00 1.000000e-01 -4.305835e-04 +289 1.600000e+00 1.000000e-01 -4.402876e-04 +290 1.650000e+00 1.000000e-01 -4.488018e-04 +291 1.700000e+00 1.000000e-01 -4.566256e-04 +292 1.750000e+00 1.000000e-01 -4.638142e-04 +293 1.800000e+00 1.000000e-01 -4.704175e-04 +294 -6.000000e-01 1.000000e-01 -9.456192e-11 +295 -5.500000e-01 1.000000e-01 -9.456192e-11 +296 -5.000000e-01 1.000000e-01 -9.456192e-11 +297 -4.500000e-01 1.000000e-01 -9.456192e-11 +298 -4.000000e-01 1.000000e-01 -9.456192e-11 +299 -3.500000e-01 1.000000e-01 -9.456191e-11 +300 -3.000000e-01 1.000000e-01 -9.456192e-11 +301 -2.500000e-01 1.000000e-01 -9.456194e-11 +302 -2.000000e-01 1.000000e-01 -9.456203e-11 +303 -1.500000e-01 1.000000e-01 -9.456244e-11 +304 -1.000000e-01 1.000000e-01 -9.456422e-11 +305 -5.000000e-02 1.000000e-01 -9.457169e-11 +306 -6.938894e-17 1.000000e-01 -9.460342e-11 +307 5.000000e-02 1.000000e-01 -9.473794e-11 +308 1.000000e-01 1.000000e-01 -9.530830e-11 +309 1.500000e-01 1.000000e-01 -9.999640e-11 +310 2.000000e-01 1.000000e-01 -1.172733e-10 +311 2.500000e-01 1.000000e-01 -1.888370e-10 +312 3.000000e-01 1.000000e-01 -4.829541e-10 +313 3.500000e-01 1.000000e-01 -1.679961e-09 +314 4.000000e-01 1.000000e-01 -6.485162e-09 +315 4.500000e-01 1.000000e-01 -2.536994e-08 +316 5.000000e-01 1.000000e-01 -9.708249e-08 +317 5.500000e-01 1.000000e-01 -3.550705e-07 +318 6.000000e-01 1.000000e-01 -1.215402e-06 +319 6.500000e-01 1.000000e-01 -3.843036e-06 +320 7.000000e-01 1.000000e-01 -1.116656e-05 +321 7.500000e-01 1.000000e-01 -2.897496e-05 +322 8.000000e-01 1.000000e-01 -6.250938e-05 +323 8.500000e-01 1.000000e-01 -1.079365e-04 +324 9.000000e-01 1.000000e-01 -1.551111e-04 +325 9.500000e-01 1.000000e-01 -1.972299e-04 +326 1.000000e+00 1.000000e-01 -2.326855e-04 +327 1.050000e+00 1.000000e-01 -2.623870e-04 +328 1.100000e+00 1.000000e-01 -2.877095e-04 +329 1.150000e+00 1.000000e-01 -3.097696e-04 +330 1.200000e+00 1.000000e-01 -3.293369e-04 +331 1.250000e+00 1.000000e-01 -3.469185e-04 +332 1.300000e+00 1.000000e-01 -3.628520e-04 +333 1.350000e+00 1.000000e-01 -3.773714e-04 +334 1.400000e+00 1.000000e-01 -3.906482e-04 +335 1.450000e+00 1.000000e-01 -4.028153e-04 +336 1.500000e+00 1.000000e-01 -4.139811e-04 +337 1.550000e+00 1.000000e-01 -4.242371e-04 +338 1.600000e+00 1.000000e-01 -4.340653e-04 +339 1.650000e+00 1.000000e-01 -4.426963e-04 +340 1.700000e+00 1.000000e-01 -4.506327e-04 +341 1.750000e+00 1.000000e-01 -4.579299e-04 +342 1.800000e+00 1.000000e-01 -4.646381e-04 + + + + diff --git a/tests/bsim4/test8.cir b/tests/bsim4/test8.cir new file mode 100644 index 000000000..222d3f626 --- /dev/null +++ b/tests/bsim4/test8.cir @@ -0,0 +1,13 @@ +** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +** Circuit Description ** +m1 2 1 0 0 p1 L=0.13u W=10.0u rgeoMod=1 +vgs 1 0 -1.8 +vds 2 0 -1.8 + +.dc vds 0 -1.8 -0.05 vgs 0 -1.8 -0.3 + +.print dc v(1) i(vds) + +.include modelcard.pmos +.end diff --git a/tests/bsim4/test8.out b/tests/bsim4/test8.out new file mode 100644 index 000000000..268bd084b --- /dev/null +++ b/tests/bsim4/test8.out @@ -0,0 +1,286 @@ + +No. of Data Rows : 259 + +Circuit: ** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. +-------------------------------------------------------------------------------- +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 0.000000e+00 -1.375069e-29 +1 -5.000000e-02 0.000000e+00 1.747624e-13 +2 -1.000000e-01 0.000000e+00 1.967844e-13 +3 -1.500000e-01 0.000000e+00 2.523446e-13 +4 -2.000000e-01 0.000000e+00 3.160316e-13 +5 -2.500000e-01 0.000000e+00 3.811009e-13 +6 -3.000000e-01 0.000000e+00 4.470869e-13 +7 -3.500000e-01 0.000000e+00 5.140246e-13 +8 -4.000000e-01 0.000000e+00 5.819000e-13 +9 -4.500000e-01 0.000000e+00 6.507269e-13 +10 -5.000000e-01 0.000000e+00 7.206027e-13 +11 -5.500000e-01 0.000000e+00 7.915829e-13 +12 -6.000000e-01 0.000000e+00 8.635841e-13 +13 -6.500000e-01 0.000000e+00 9.368217e-13 +14 -7.000000e-01 0.000000e+00 1.011268e-12 +15 -7.500000e-01 0.000000e+00 1.087048e-12 +16 -8.000000e-01 0.000000e+00 1.163980e-12 +17 -8.500000e-01 0.000000e+00 1.242427e-12 +18 -9.000000e-01 0.000000e+00 1.322291e-12 +19 -9.500000e-01 0.000000e+00 1.403572e-12 +20 -1.000000e+00 0.000000e+00 1.486423e-12 +21 -1.050000e+00 0.000000e+00 1.570899e-12 +22 -1.100000e+00 0.000000e+00 1.657014e-12 +23 -1.150000e+00 0.000000e+00 1.744880e-12 +24 -1.200000e+00 0.000000e+00 1.834579e-12 +25 -1.250000e+00 0.000000e+00 1.926140e-12 +26 -1.300000e+00 0.000000e+00 2.019757e-12 +27 -1.350000e+00 0.000000e+00 2.115236e-12 +28 -1.400000e+00 0.000000e+00 2.213520e-12 +29 -1.450000e+00 0.000000e+00 2.323224e-12 +30 -1.500000e+00 0.000000e+00 2.527280e-12 +31 -1.550000e+00 0.000000e+00 4.400438e-12 +32 -1.600000e+00 0.000000e+00 1.230828e-11 +33 -1.650000e+00 0.000000e+00 4.401162e-11 +34 -1.700000e+00 0.000000e+00 1.531452e-10 +35 -1.750000e+00 0.000000e+00 4.820579e-10 +36 -1.800000e+00 0.000000e+00 1.366714e-09 +37 0.000000e+00 -3.000000e-01 -1.305626e-18 +38 -5.000000e-02 -3.000000e-01 1.804718e-09 +39 -1.000000e-01 -3.000000e-01 2.357714e-09 +40 -1.500000e-01 -3.000000e-01 2.777053e-09 +41 -2.000000e-01 -3.000000e-01 3.197810e-09 +42 -2.500000e-01 -3.000000e-01 3.637349e-09 +43 -3.000000e-01 -3.000000e-01 4.100109e-09 +44 -3.500000e-01 -3.000000e-01 4.588173e-09 +45 -4.000000e-01 -3.000000e-01 5.103023e-09 +46 -4.500000e-01 -3.000000e-01 5.645973e-09 +47 -5.000000e-01 -3.000000e-01 6.218292e-09 +48 -5.500000e-01 -3.000000e-01 6.821257e-09 +49 -6.000000e-01 -3.000000e-01 7.456171e-09 +50 -6.500000e-01 -3.000000e-01 8.124373e-09 +51 -7.000000e-01 -3.000000e-01 8.827245e-09 +52 -7.500000e-01 -3.000000e-01 9.566213e-09 +53 -8.000000e-01 -3.000000e-01 1.034276e-08 +54 -8.500000e-01 -3.000000e-01 1.115840e-08 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +55 -9.000000e-01 -3.000000e-01 1.201472e-08 +56 -9.500000e-01 -3.000000e-01 1.291335e-08 +57 -1.000000e+00 -3.000000e-01 1.385599e-08 +58 -1.050000e+00 -3.000000e-01 1.484438e-08 +59 -1.100000e+00 -3.000000e-01 1.588034e-08 +60 -1.150000e+00 -3.000000e-01 1.696574e-08 +61 -1.200000e+00 -3.000000e-01 1.810254e-08 +62 -1.250000e+00 -3.000000e-01 1.929283e-08 +63 -1.300000e+00 -3.000000e-01 2.053884e-08 +64 -1.350000e+00 -3.000000e-01 2.184317e-08 +65 -1.400000e+00 -3.000000e-01 2.320902e-08 +66 -1.450000e+00 -3.000000e-01 2.464077e-08 +67 -1.500000e+00 -3.000000e-01 2.614499e-08 +68 -1.550000e+00 -3.000000e-01 2.773207e-08 +69 -1.600000e+00 -3.000000e-01 2.941904e-08 +70 -1.650000e+00 -3.000000e-01 3.123383e-08 +71 -1.700000e+00 -3.000000e-01 3.322180e-08 +72 -1.750000e+00 -3.000000e-01 3.545534e-08 +73 -1.800000e+00 -3.000000e-01 3.804766e-08 +74 0.000000e+00 -6.000000e-01 -9.408570e-18 +75 -5.000000e-02 -6.000000e-01 1.819787e-05 +76 -1.000000e-01 -6.000000e-01 2.454873e-05 +77 -1.500000e-01 -6.000000e-01 2.808775e-05 +78 -2.000000e-01 -6.000000e-01 3.125422e-05 +79 -2.500000e-01 -6.000000e-01 3.439801e-05 +80 -3.000000e-01 -6.000000e-01 3.765444e-05 +81 -3.500000e-01 -6.000000e-01 4.098478e-05 +82 -4.000000e-01 -6.000000e-01 4.441828e-05 +83 -4.500000e-01 -6.000000e-01 4.795969e-05 +84 -5.000000e-01 -6.000000e-01 5.161213e-05 +85 -5.500000e-01 -6.000000e-01 5.537803e-05 +86 -6.000000e-01 -6.000000e-01 5.920134e-05 +87 -6.500000e-01 -6.000000e-01 6.319919e-05 +88 -7.000000e-01 -6.000000e-01 6.731618e-05 +89 -7.500000e-01 -6.000000e-01 7.155397e-05 +90 -8.000000e-01 -6.000000e-01 7.591415e-05 +91 -8.500000e-01 -6.000000e-01 8.039830e-05 +92 -9.000000e-01 -6.000000e-01 8.500793e-05 +93 -9.500000e-01 -6.000000e-01 8.974455e-05 +94 -1.000000e+00 -6.000000e-01 9.460961e-05 +95 -1.050000e+00 -6.000000e-01 9.960455e-05 +96 -1.100000e+00 -6.000000e-01 1.047308e-04 +97 -1.150000e+00 -6.000000e-01 1.099897e-04 +98 -1.200000e+00 -6.000000e-01 1.153826e-04 +99 -1.250000e+00 -6.000000e-01 1.209111e-04 +100 -1.300000e+00 -6.000000e-01 1.265769e-04 +101 -1.350000e+00 -6.000000e-01 1.323823e-04 +102 -1.400000e+00 -6.000000e-01 1.383314e-04 +103 -1.450000e+00 -6.000000e-01 1.444314e-04 +104 -1.500000e+00 -6.000000e-01 1.506959e-04 +105 -1.550000e+00 -6.000000e-01 1.571504e-04 +106 -1.600000e+00 -6.000000e-01 1.638412e-04 +107 -1.650000e+00 -6.000000e-01 1.710389e-04 +108 -1.700000e+00 -6.000000e-01 1.785910e-04 +109 -1.750000e+00 -6.000000e-01 1.868781e-04 +110 -1.800000e+00 -6.000000e-01 1.962841e-04 +111 0.000000e+00 -9.000000e-01 -2.853929e-17 +112 -5.000000e-02 -9.000000e-01 2.624487e-04 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +113 -1.000000e-01 -9.000000e-01 4.779357e-04 +114 -1.500000e-01 -9.000000e-01 6.496158e-04 +115 -2.000000e-01 -9.000000e-01 7.807058e-04 +116 -2.500000e-01 -9.000000e-01 8.752738e-04 +117 -3.000000e-01 -9.000000e-01 9.400100e-04 +118 -3.500000e-01 -9.000000e-01 9.848288e-04 +119 -4.000000e-01 -9.000000e-01 1.019100e-03 +120 -4.500000e-01 -9.000000e-01 1.048435e-03 +121 -5.000000e-01 -9.000000e-01 1.076336e-03 +122 -5.500000e-01 -9.000000e-01 1.101776e-03 +123 -6.000000e-01 -9.000000e-01 1.126846e-03 +124 -6.500000e-01 -9.000000e-01 1.151705e-03 +125 -7.000000e-01 -9.000000e-01 1.176454e-03 +126 -7.500000e-01 -9.000000e-01 1.201158e-03 +127 -8.000000e-01 -9.000000e-01 1.225860e-03 +128 -8.500000e-01 -9.000000e-01 1.250590e-03 +129 -9.000000e-01 -9.000000e-01 1.275367e-03 +130 -9.500000e-01 -9.000000e-01 1.300203e-03 +131 -1.000000e+00 -9.000000e-01 1.325107e-03 +132 -1.050000e+00 -9.000000e-01 1.350087e-03 +133 -1.100000e+00 -9.000000e-01 1.375145e-03 +134 -1.150000e+00 -9.000000e-01 1.400285e-03 +135 -1.200000e+00 -9.000000e-01 1.425507e-03 +136 -1.250000e+00 -9.000000e-01 1.450813e-03 +137 -1.300000e+00 -9.000000e-01 1.476203e-03 +138 -1.350000e+00 -9.000000e-01 1.501676e-03 +139 -1.400000e+00 -9.000000e-01 1.527233e-03 +140 -1.450000e+00 -9.000000e-01 1.552872e-03 +141 -1.500000e+00 -9.000000e-01 1.578596e-03 +142 -1.550000e+00 -9.000000e-01 1.604412e-03 +143 -1.600000e+00 -9.000000e-01 1.630337e-03 +144 -1.650000e+00 -9.000000e-01 1.656410e-03 +145 -1.700000e+00 -9.000000e-01 1.682718e-03 +146 -1.750000e+00 -9.000000e-01 1.709425e-03 +147 -1.800000e+00 -9.000000e-01 1.737321e-03 +148 0.000000e+00 -1.200000e+00 -5.728902e-17 +149 -5.000000e-02 -1.200000e+00 3.749321e-04 +150 -1.000000e-01 -1.200000e+00 7.096261e-04 +151 -1.500000e-01 -1.200000e+00 1.005763e-03 +152 -2.000000e-01 -1.200000e+00 1.264935e-03 +153 -2.500000e-01 -1.200000e+00 1.488617e-03 +154 -3.000000e-01 -1.200000e+00 1.678174e-03 +155 -3.500000e-01 -1.200000e+00 1.834943e-03 +156 -4.000000e-01 -1.200000e+00 1.960572e-03 +157 -4.500000e-01 -1.200000e+00 2.057905e-03 +158 -5.000000e-01 -1.200000e+00 2.132063e-03 +159 -5.500000e-01 -1.200000e+00 2.189959e-03 +160 -6.000000e-01 -1.200000e+00 2.237930e-03 +161 -6.500000e-01 -1.200000e+00 2.280241e-03 +162 -7.000000e-01 -1.200000e+00 2.320648e-03 +163 -7.500000e-01 -1.200000e+00 2.357304e-03 +164 -8.000000e-01 -1.200000e+00 2.393029e-03 +165 -8.500000e-01 -1.200000e+00 2.428133e-03 +166 -9.000000e-01 -1.200000e+00 2.462815e-03 +167 -9.500000e-01 -1.200000e+00 2.497205e-03 +168 -1.000000e+00 -1.200000e+00 2.531390e-03 +169 -1.050000e+00 -1.200000e+00 2.565432e-03 +170 -1.100000e+00 -1.200000e+00 2.599372e-03 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +171 -1.150000e+00 -1.200000e+00 2.633242e-03 +172 -1.200000e+00 -1.200000e+00 2.667063e-03 +173 -1.250000e+00 -1.200000e+00 2.700851e-03 +174 -1.300000e+00 -1.200000e+00 2.734619e-03 +175 -1.350000e+00 -1.200000e+00 2.768374e-03 +176 -1.400000e+00 -1.200000e+00 2.802124e-03 +177 -1.450000e+00 -1.200000e+00 2.835872e-03 +178 -1.500000e+00 -1.200000e+00 2.869623e-03 +179 -1.550000e+00 -1.200000e+00 2.903379e-03 +180 -1.600000e+00 -1.200000e+00 2.937141e-03 +181 -1.650000e+00 -1.200000e+00 2.970916e-03 +182 -1.700000e+00 -1.200000e+00 3.004712e-03 +183 -1.750000e+00 -1.200000e+00 3.038553e-03 +184 -1.800000e+00 -1.200000e+00 3.072493e-03 +185 0.000000e+00 -1.500000e+00 -9.565718e-17 +186 -5.000000e-02 -1.500000e+00 4.354321e-04 +187 -1.000000e-01 -1.500000e+00 8.374453e-04 +188 -1.500000e-01 -1.500000e+00 1.207057e-03 +189 -2.000000e-01 -1.500000e+00 1.545258e-03 +190 -2.500000e-01 -1.500000e+00 1.852993e-03 +191 -3.000000e-01 -1.500000e+00 2.131144e-03 +192 -3.500000e-01 -1.500000e+00 2.380518e-03 +193 -4.000000e-01 -1.500000e+00 2.601830e-03 +194 -4.500000e-01 -1.500000e+00 2.795700e-03 +195 -5.000000e-01 -1.500000e+00 2.962690e-03 +196 -5.500000e-01 -1.500000e+00 3.103487e-03 +197 -6.000000e-01 -1.500000e+00 3.219414e-03 +198 -6.500000e-01 -1.500000e+00 3.313211e-03 +199 -7.000000e-01 -1.500000e+00 3.389336e-03 +200 -7.500000e-01 -1.500000e+00 3.452945e-03 +201 -8.000000e-01 -1.500000e+00 3.511871e-03 +202 -8.500000e-01 -1.500000e+00 3.560972e-03 +203 -9.000000e-01 -1.500000e+00 3.607372e-03 +204 -9.500000e-01 -1.500000e+00 3.652013e-03 +205 -1.000000e+00 -1.500000e+00 3.695452e-03 +206 -1.050000e+00 -1.500000e+00 3.738037e-03 +207 -1.100000e+00 -1.500000e+00 3.780000e-03 +208 -1.150000e+00 -1.500000e+00 3.821496e-03 +209 -1.200000e+00 -1.500000e+00 3.862634e-03 +210 -1.250000e+00 -1.500000e+00 3.903490e-03 +211 -1.300000e+00 -1.500000e+00 3.944121e-03 +212 -1.350000e+00 -1.500000e+00 3.984568e-03 +213 -1.400000e+00 -1.500000e+00 4.024859e-03 +214 -1.450000e+00 -1.500000e+00 4.065020e-03 +215 -1.500000e+00 -1.500000e+00 4.105066e-03 +216 -1.550000e+00 -1.500000e+00 4.145010e-03 +217 -1.600000e+00 -1.500000e+00 4.184864e-03 +218 -1.650000e+00 -1.500000e+00 4.224635e-03 +219 -1.700000e+00 -1.500000e+00 4.264329e-03 +220 -1.750000e+00 -1.500000e+00 4.303952e-03 +221 -1.800000e+00 -1.500000e+00 4.343510e-03 +222 0.000000e+00 -1.800000e+00 -1.433956e-16 +223 -5.000000e-02 -1.800000e+00 4.691969e-04 +224 -1.000000e-01 -1.800000e+00 9.104853e-04 +225 -1.500000e-01 -1.800000e+00 1.324520e-03 +226 -2.000000e-01 -1.800000e+00 1.711953e-03 +227 -2.500000e-01 -1.800000e+00 2.073419e-03 +228 -3.000000e-01 -1.800000e+00 2.409527e-03 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +229 -3.500000e-01 -1.800000e+00 2.720857e-03 +230 -4.000000e-01 -1.800000e+00 3.007950e-03 +231 -4.500000e-01 -1.800000e+00 3.271299e-03 +232 -5.000000e-01 -1.800000e+00 3.511336e-03 +233 -5.500000e-01 -1.800000e+00 3.728419e-03 +234 -6.000000e-01 -1.800000e+00 3.922821e-03 +235 -6.500000e-01 -1.800000e+00 4.094749e-03 +236 -7.000000e-01 -1.800000e+00 4.244457e-03 +237 -7.500000e-01 -1.800000e+00 4.372535e-03 +238 -8.000000e-01 -1.800000e+00 4.480443e-03 +239 -8.500000e-01 -1.800000e+00 4.570933e-03 +240 -9.000000e-01 -1.800000e+00 4.647791e-03 +241 -9.500000e-01 -1.800000e+00 4.719165e-03 +242 -1.000000e+00 -1.800000e+00 4.778224e-03 +243 -1.050000e+00 -1.800000e+00 4.833323e-03 +244 -1.100000e+00 -1.800000e+00 4.885794e-03 +245 -1.150000e+00 -1.800000e+00 4.936443e-03 +246 -1.200000e+00 -1.800000e+00 4.985784e-03 +247 -1.250000e+00 -1.800000e+00 5.034152e-03 +248 -1.300000e+00 -1.800000e+00 5.081777e-03 +249 -1.350000e+00 -1.800000e+00 5.128818e-03 +250 -1.400000e+00 -1.800000e+00 5.175391e-03 +251 -1.450000e+00 -1.800000e+00 5.221578e-03 +252 -1.500000e+00 -1.800000e+00 5.267439e-03 +253 -1.550000e+00 -1.800000e+00 5.313021e-03 +254 -1.600000e+00 -1.800000e+00 5.358358e-03 +255 -1.650000e+00 -1.800000e+00 5.403477e-03 +256 -1.700000e+00 -1.800000e+00 5.448399e-03 +257 -1.750000e+00 -1.800000e+00 5.493140e-03 +258 -1.800000e+00 -1.800000e+00 5.537712e-03 + + + + diff --git a/tests/bsim4/test9.cir b/tests/bsim4/test9.cir new file mode 100644 index 000000000..f99156d9f --- /dev/null +++ b/tests/bsim4/test9.cir @@ -0,0 +1,15 @@ +** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +** Circuit Description ** +m1 2 1 0 0 p1 L=0.13u W=10.0u rgeoMod=1 +vgs 1 0 -1.8 +vds 2 0 -1.8 + +.dc vds 0 -1.8 -0.05 vgs 0 -1.8 -0.3 + +.options Temp=-55 + +.print dc v(1) i(vds) + +.include modelcard.pmos +.end diff --git a/tests/bsim4/test9.out b/tests/bsim4/test9.out new file mode 100644 index 000000000..fe1b1f21c --- /dev/null +++ b/tests/bsim4/test9.out @@ -0,0 +1,286 @@ + +No. of Data Rows : 259 + +Circuit: ** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. + +Doing analysis at TEMP = 218.150000 and TNOM = 300.150000 +Warning: This model is BSIM4.2.1; you specified a wrong version number. +** PMOSFET: Benchmarking Implementation of BSIM4.1.0 by Weidong Liu 10/11/2000. +-------------------------------------------------------------------------------- +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 0.000000e+00 -2.897181e-34 +1 -5.000000e-02 0.000000e+00 5.024926e-14 +2 -1.000000e-01 0.000000e+00 1.001651e-13 +3 -1.500000e-01 0.000000e+00 1.501774e-13 +4 -2.000000e-01 0.000000e+00 2.002261e-13 +5 -2.500000e-01 0.000000e+00 2.502505e-13 +6 -3.000000e-01 0.000000e+00 3.002853e-13 +7 -3.500000e-01 0.000000e+00 3.503444e-13 +8 -4.000000e-01 0.000000e+00 4.003827e-13 +9 -4.500000e-01 0.000000e+00 4.504141e-13 +10 -5.000000e-01 0.000000e+00 5.004732e-13 +11 -5.500000e-01 0.000000e+00 5.505323e-13 +12 -6.000000e-01 0.000000e+00 6.005706e-13 +13 -6.500000e-01 0.000000e+00 6.506366e-13 +14 -7.000000e-01 0.000000e+00 7.007027e-13 +15 -7.500000e-01 0.000000e+00 7.508104e-13 +16 -8.000000e-01 0.000000e+00 8.008209e-13 +17 -8.500000e-01 0.000000e+00 8.509286e-13 +18 -9.000000e-01 0.000000e+00 9.010363e-13 +19 -9.500000e-01 0.000000e+00 9.511440e-13 +20 -1.000000e+00 0.000000e+00 1.001196e-12 +21 -1.050000e+00 0.000000e+00 1.051290e-12 +22 -1.100000e+00 0.000000e+00 1.101398e-12 +23 -1.150000e+00 0.000000e+00 1.151506e-12 +24 -1.200000e+00 0.000000e+00 1.201697e-12 +25 -1.250000e+00 0.000000e+00 1.251749e-12 +26 -1.300000e+00 0.000000e+00 1.301856e-12 +27 -1.350000e+00 0.000000e+00 1.351992e-12 +28 -1.400000e+00 0.000000e+00 1.402767e-12 +29 -1.450000e+00 0.000000e+00 1.462543e-12 +30 -1.500000e+00 0.000000e+00 1.614172e-12 +31 -1.550000e+00 0.000000e+00 3.430567e-12 +32 -1.600000e+00 0.000000e+00 1.127965e-11 +33 -1.650000e+00 0.000000e+00 4.291939e-11 +34 -1.700000e+00 0.000000e+00 1.519836e-10 +35 -1.750000e+00 0.000000e+00 4.808182e-10 +36 -1.800000e+00 0.000000e+00 1.365383e-09 +37 0.000000e+00 -3.000000e-01 -1.303081e-18 +38 -5.000000e-02 -3.000000e-01 1.589716e-10 +39 -1.000000e-01 -3.000000e-01 2.095691e-10 +40 -1.500000e-01 -3.000000e-01 2.547142e-10 +41 -2.000000e-01 -3.000000e-01 3.002615e-10 +42 -2.500000e-01 -3.000000e-01 3.514624e-10 +43 -3.000000e-01 -3.000000e-01 4.048342e-10 +44 -3.500000e-01 -3.000000e-01 4.619196e-10 +45 -4.000000e-01 -3.000000e-01 5.229614e-10 +46 -4.500000e-01 -3.000000e-01 5.881962e-10 +47 -5.000000e-01 -3.000000e-01 6.578647e-10 +48 -5.500000e-01 -3.000000e-01 7.322152e-10 +49 -6.000000e-01 -3.000000e-01 8.115063e-10 +50 -6.500000e-01 -3.000000e-01 8.960077e-10 +51 -7.000000e-01 -3.000000e-01 9.860017e-10 +52 -7.500000e-01 -3.000000e-01 1.081784e-09 +53 -8.000000e-01 -3.000000e-01 1.183662e-09 +54 -8.500000e-01 -3.000000e-01 1.291961e-09 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +55 -9.000000e-01 -3.000000e-01 1.407019e-09 +56 -9.500000e-01 -3.000000e-01 1.529190e-09 +57 -1.000000e+00 -3.000000e-01 1.658847e-09 +58 -1.050000e+00 -3.000000e-01 1.796377e-09 +59 -1.100000e+00 -3.000000e-01 1.942187e-09 +60 -1.150000e+00 -3.000000e-01 2.096706e-09 +61 -1.200000e+00 -3.000000e-01 2.260381e-09 +62 -1.250000e+00 -3.000000e-01 2.433691e-09 +63 -1.300000e+00 -3.000000e-01 2.617153e-09 +64 -1.350000e+00 -3.000000e-01 2.811349e-09 +65 -1.400000e+00 -3.000000e-01 3.016972e-09 +66 -1.450000e+00 -3.000000e-01 3.234920e-09 +67 -1.500000e+00 -3.000000e-01 3.466450e-09 +68 -1.550000e+00 -3.000000e-01 3.713454e-09 +69 -1.600000e+00 -3.000000e-01 3.978905e-09 +70 -1.650000e+00 -3.000000e-01 4.267560e-09 +71 -1.700000e+00 -3.000000e-01 4.587029e-09 +72 -1.750000e+00 -3.000000e-01 4.949382e-09 +73 -1.800000e+00 -3.000000e-01 5.373575e-09 +74 0.000000e+00 -6.000000e-01 -9.408024e-18 +75 -5.000000e-02 -6.000000e-01 5.630617e-05 +76 -1.000000e-01 -6.000000e-01 7.365262e-05 +77 -1.500000e-01 -6.000000e-01 8.438245e-05 +78 -2.000000e-01 -6.000000e-01 9.425966e-05 +79 -2.500000e-01 -6.000000e-01 1.040786e-04 +80 -3.000000e-01 -6.000000e-01 1.140734e-04 +81 -3.500000e-01 -6.000000e-01 1.244879e-04 +82 -4.000000e-01 -6.000000e-01 1.350713e-04 +83 -4.500000e-01 -6.000000e-01 1.459467e-04 +84 -5.000000e-01 -6.000000e-01 1.569711e-04 +85 -5.500000e-01 -6.000000e-01 1.684496e-04 +86 -6.000000e-01 -6.000000e-01 1.802376e-04 +87 -6.500000e-01 -6.000000e-01 1.923373e-04 +88 -7.000000e-01 -6.000000e-01 2.047507e-04 +89 -7.500000e-01 -6.000000e-01 2.174793e-04 +90 -8.000000e-01 -6.000000e-01 2.305241e-04 +91 -8.500000e-01 -6.000000e-01 2.438861e-04 +92 -9.000000e-01 -6.000000e-01 2.575658e-04 +93 -9.500000e-01 -6.000000e-01 2.715636e-04 +94 -1.000000e+00 -6.000000e-01 2.858798e-04 +95 -1.050000e+00 -6.000000e-01 3.005144e-04 +96 -1.100000e+00 -6.000000e-01 3.154672e-04 +97 -1.150000e+00 -6.000000e-01 3.307381e-04 +98 -1.200000e+00 -6.000000e-01 3.463268e-04 +99 -1.250000e+00 -6.000000e-01 3.622331e-04 +100 -1.300000e+00 -6.000000e-01 3.784581e-04 +101 -1.350000e+00 -6.000000e-01 3.950050e-04 +102 -1.400000e+00 -6.000000e-01 4.118824e-04 +103 -1.450000e+00 -6.000000e-01 4.291101e-04 +104 -1.500000e+00 -6.000000e-01 4.467292e-04 +105 -1.550000e+00 -6.000000e-01 4.648199e-04 +106 -1.600000e+00 -6.000000e-01 4.835302e-04 +107 -1.650000e+00 -6.000000e-01 5.036561e-04 +108 -1.700000e+00 -6.000000e-01 5.248431e-04 +109 -1.750000e+00 -6.000000e-01 5.482280e-04 +110 -1.800000e+00 -6.000000e-01 5.750105e-04 +111 0.000000e+00 -9.000000e-01 -2.853929e-17 +112 -5.000000e-02 -9.000000e-01 5.728409e-04 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +113 -1.000000e-01 -9.000000e-01 1.014447e-03 +114 -1.500000e-01 -9.000000e-01 1.337478e-03 +115 -2.000000e-01 -9.000000e-01 1.555254e-03 +116 -2.500000e-01 -9.000000e-01 1.690637e-03 +117 -3.000000e-01 -9.000000e-01 1.776875e-03 +118 -3.500000e-01 -9.000000e-01 1.839907e-03 +119 -4.000000e-01 -9.000000e-01 1.892454e-03 +120 -4.500000e-01 -9.000000e-01 1.939920e-03 +121 -5.000000e-01 -9.000000e-01 1.985779e-03 +122 -5.500000e-01 -9.000000e-01 2.028570e-03 +123 -6.000000e-01 -9.000000e-01 2.070645e-03 +124 -6.500000e-01 -9.000000e-01 2.112249e-03 +125 -7.000000e-01 -9.000000e-01 2.153547e-03 +126 -7.500000e-01 -9.000000e-01 2.194647e-03 +127 -8.000000e-01 -9.000000e-01 2.235624e-03 +128 -8.500000e-01 -9.000000e-01 2.276532e-03 +129 -9.000000e-01 -9.000000e-01 2.317406e-03 +130 -9.500000e-01 -9.000000e-01 2.358274e-03 +131 -1.000000e+00 -9.000000e-01 2.399154e-03 +132 -1.050000e+00 -9.000000e-01 2.440059e-03 +133 -1.100000e+00 -9.000000e-01 2.481001e-03 +134 -1.150000e+00 -9.000000e-01 2.521985e-03 +135 -1.200000e+00 -9.000000e-01 2.563017e-03 +136 -1.250000e+00 -9.000000e-01 2.604100e-03 +137 -1.300000e+00 -9.000000e-01 2.645236e-03 +138 -1.350000e+00 -9.000000e-01 2.686426e-03 +139 -1.400000e+00 -9.000000e-01 2.727676e-03 +140 -1.450000e+00 -9.000000e-01 2.768991e-03 +141 -1.500000e+00 -9.000000e-01 2.810393e-03 +142 -1.550000e+00 -9.000000e-01 2.851929e-03 +143 -1.600000e+00 -9.000000e-01 2.893701e-03 +144 -1.650000e+00 -9.000000e-01 2.936225e-03 +145 -1.700000e+00 -9.000000e-01 2.979542e-03 +146 -1.750000e+00 -9.000000e-01 3.024609e-03 +147 -1.800000e+00 -9.000000e-01 3.072775e-03 +148 0.000000e+00 -1.200000e+00 -5.706238e-17 +149 -5.000000e-02 -1.200000e+00 7.635936e-04 +150 -1.000000e-01 -1.200000e+00 1.424750e-03 +151 -1.500000e-01 -1.200000e+00 1.989151e-03 +152 -2.000000e-01 -1.200000e+00 2.461473e-03 +153 -2.500000e-01 -1.200000e+00 2.845061e-03 +154 -3.000000e-01 -1.200000e+00 3.142549e-03 +155 -3.500000e-01 -1.200000e+00 3.359794e-03 +156 -4.000000e-01 -1.200000e+00 3.512181e-03 +157 -4.500000e-01 -1.200000e+00 3.621991e-03 +158 -5.000000e-01 -1.200000e+00 3.707724e-03 +159 -5.500000e-01 -1.200000e+00 3.780335e-03 +160 -6.000000e-01 -1.200000e+00 3.848583e-03 +161 -6.500000e-01 -1.200000e+00 3.908208e-03 +162 -7.000000e-01 -1.200000e+00 3.965581e-03 +163 -7.500000e-01 -1.200000e+00 4.021392e-03 +164 -8.000000e-01 -1.200000e+00 4.076089e-03 +165 -8.500000e-01 -1.200000e+00 4.129970e-03 +166 -9.000000e-01 -1.200000e+00 4.183242e-03 +167 -9.500000e-01 -1.200000e+00 4.236048e-03 +168 -1.000000e+00 -1.200000e+00 4.288492e-03 +169 -1.050000e+00 -1.200000e+00 4.340648e-03 +170 -1.100000e+00 -1.200000e+00 4.392572e-03 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +171 -1.150000e+00 -1.200000e+00 4.444306e-03 +172 -1.200000e+00 -1.200000e+00 4.495881e-03 +173 -1.250000e+00 -1.200000e+00 4.547320e-03 +174 -1.300000e+00 -1.200000e+00 4.598643e-03 +175 -1.350000e+00 -1.200000e+00 4.649864e-03 +176 -1.400000e+00 -1.200000e+00 4.700993e-03 +177 -1.450000e+00 -1.200000e+00 4.752039e-03 +178 -1.500000e+00 -1.200000e+00 4.803012e-03 +179 -1.550000e+00 -1.200000e+00 4.853925e-03 +180 -1.600000e+00 -1.200000e+00 4.904802e-03 +181 -1.650000e+00 -1.200000e+00 4.955696e-03 +182 -1.700000e+00 -1.200000e+00 5.006723e-03 +183 -1.750000e+00 -1.200000e+00 5.058402e-03 +184 -1.800000e+00 -1.200000e+00 5.110934e-03 +185 0.000000e+00 -1.500000e+00 -9.565718e-17 +186 -5.000000e-02 -1.500000e+00 8.608964e-04 +187 -1.000000e-01 -1.500000e+00 1.640861e-03 +188 -1.500000e-01 -1.500000e+00 2.343118e-03 +189 -2.000000e-01 -1.500000e+00 2.970575e-03 +190 -2.500000e-01 -1.500000e+00 3.525643e-03 +191 -3.000000e-01 -1.500000e+00 4.009978e-03 +192 -3.500000e-01 -1.500000e+00 4.424206e-03 +193 -4.000000e-01 -1.500000e+00 4.767994e-03 +194 -4.500000e-01 -1.500000e+00 5.041644e-03 +195 -5.000000e-01 -1.500000e+00 5.250303e-03 +196 -5.500000e-01 -1.500000e+00 5.406944e-03 +197 -6.000000e-01 -1.500000e+00 5.528132e-03 +198 -6.500000e-01 -1.500000e+00 5.627452e-03 +199 -7.000000e-01 -1.500000e+00 5.719101e-03 +200 -7.500000e-01 -1.500000e+00 5.795096e-03 +201 -8.000000e-01 -1.500000e+00 5.866768e-03 +202 -8.500000e-01 -1.500000e+00 5.935452e-03 +203 -9.000000e-01 -1.500000e+00 6.001991e-03 +204 -9.500000e-01 -1.500000e+00 6.066940e-03 +205 -1.000000e+00 -1.500000e+00 6.130679e-03 +206 -1.050000e+00 -1.500000e+00 6.193476e-03 +207 -1.100000e+00 -1.500000e+00 6.255518e-03 +208 -1.150000e+00 -1.500000e+00 6.316946e-03 +209 -1.200000e+00 -1.500000e+00 6.377861e-03 +210 -1.250000e+00 -1.500000e+00 6.438341e-03 +211 -1.300000e+00 -1.500000e+00 6.498444e-03 +212 -1.350000e+00 -1.500000e+00 6.558217e-03 +213 -1.400000e+00 -1.500000e+00 6.617694e-03 +214 -1.450000e+00 -1.500000e+00 6.676905e-03 +215 -1.500000e+00 -1.500000e+00 6.735869e-03 +216 -1.550000e+00 -1.500000e+00 6.794607e-03 +217 -1.600000e+00 -1.500000e+00 6.853133e-03 +218 -1.650000e+00 -1.500000e+00 6.911466e-03 +219 -1.700000e+00 -1.500000e+00 6.969631e-03 +220 -1.750000e+00 -1.500000e+00 7.027679e-03 +221 -1.800000e+00 -1.500000e+00 7.085718e-03 +222 0.000000e+00 -1.800000e+00 -1.433956e-16 +223 -5.000000e-02 -1.800000e+00 9.159540e-04 +224 -1.000000e-01 -1.800000e+00 1.765920e-03 +225 -1.500000e-01 -1.800000e+00 2.551928e-03 +226 -2.000000e-01 -1.800000e+00 3.275903e-03 +227 -2.500000e-01 -1.800000e+00 3.939593e-03 +228 -3.000000e-01 -1.800000e+00 4.544486e-03 + +Index v-sweep v(1) vds#branch +-------------------------------------------------------------------------------- +229 -3.500000e-01 -1.800000e+00 5.091673e-03 +230 -4.000000e-01 -1.800000e+00 5.581668e-03 +231 -4.500000e-01 -1.800000e+00 6.014184e-03 +232 -5.000000e-01 -1.800000e+00 6.388040e-03 +233 -5.500000e-01 -1.800000e+00 6.701776e-03 +234 -6.000000e-01 -1.800000e+00 6.955884e-03 +235 -6.500000e-01 -1.800000e+00 7.156095e-03 +236 -7.000000e-01 -1.800000e+00 7.313766e-03 +237 -7.500000e-01 -1.800000e+00 7.441740e-03 +238 -8.000000e-01 -1.800000e+00 7.550358e-03 +239 -8.500000e-01 -1.800000e+00 7.651861e-03 +240 -9.000000e-01 -1.800000e+00 7.738128e-03 +241 -9.500000e-01 -1.800000e+00 7.819606e-03 +242 -1.000000e+00 -1.800000e+00 7.897668e-03 +243 -1.050000e+00 -1.800000e+00 7.973205e-03 +244 -1.100000e+00 -1.800000e+00 8.046820e-03 +245 -1.150000e+00 -1.800000e+00 8.118933e-03 +246 -1.200000e+00 -1.800000e+00 8.189841e-03 +247 -1.250000e+00 -1.800000e+00 8.259763e-03 +248 -1.300000e+00 -1.800000e+00 8.328858e-03 +249 -1.350000e+00 -1.800000e+00 8.397248e-03 +250 -1.400000e+00 -1.800000e+00 8.465025e-03 +251 -1.450000e+00 -1.800000e+00 8.532260e-03 +252 -1.500000e+00 -1.800000e+00 8.599010e-03 +253 -1.550000e+00 -1.800000e+00 8.665318e-03 +254 -1.600000e+00 -1.800000e+00 8.731220e-03 +255 -1.650000e+00 -1.800000e+00 8.796745e-03 +256 -1.700000e+00 -1.800000e+00 8.861915e-03 +257 -1.750000e+00 -1.800000e+00 8.926755e-03 +258 -1.800000e+00 -1.800000e+00 8.991293e-03 + + + + diff --git a/tests/check.sh b/tests/check.sh new file mode 100644 index 000000000..bc4166876 --- /dev/null +++ b/tests/check.sh @@ -0,0 +1,15 @@ +#! /bin/sh + +NGSPICE=$1 +TEST=$2 + +DIFFPIPE="Analysis|CPU|memory|Date|Note|Sun|Mon|Tue|Wed|Thu|Fri|Sat|Jan|Feb|Mar|Apr|Jun|Jul|Aug|Sep|Oct|Nov|Dec" + +testname=`basename $TEST .cir` +testdir=`dirname $TEST` +$NGSPICE --batch $testdir/$testname.cir 2>&1 | egrep -v $DIFFPIPE > $testname.test +if diff -u $testdir/$testname.out $testname.test; then + rm $testname.test + exit 0 +fi +exit 1 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/filters/Makefile.am b/tests/filters/Makefile.am new file mode 100644 index 000000000..702241915 --- /dev/null +++ b/tests/filters/Makefile.am @@ -0,0 +1,12 @@ +## Process this file with automake to produce Makefile.in + +TESTS = \ + lowpass.cir + +TESTS_ENVIRONMENT = $(SHELL) $(srcdir)/../check.sh $(top_builddir)/src/ngspice + +EXTRA_DIST = \ + $(TESTS) \ + $(TESTS:.cir=.out) + +MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/filters/lowpass.cir b/tests/filters/lowpass.cir new file mode 100644 index 000000000..0ae7dc5b6 --- /dev/null +++ b/tests/filters/lowpass.cir @@ -0,0 +1,13 @@ +A Simple AC Run + +.OPTIONS LIST NODE POST TRANS +.OP +.AC DEC 10 1k 1Meg +.PRINT AC V(2) + +V1 1 0 DC 0 AC 1 SIN 0 1 1K 0 0 DISTOF1 0 DISTOF2 0 +R1 1 2 10k +R2 2 0 10k +C1 2 0 1n + +.END diff --git a/tests/filters/lowpass.out b/tests/filters/lowpass.out new file mode 100644 index 000000000..5fcc213b9 --- /dev/null +++ b/tests/filters/lowpass.out @@ -0,0 +1,107 @@ + +No. of Data Rows : 31 + +No. of Data Rows : 1 + +Circuit: A Simple AC Run + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 +a simple ac run +.op +.ac dec 10 1k 1meg +v1 1 0 dc 0 ac 1 sin 0 1 1k 0 0 distof1 0 distof2 0 +r1 1 2 10k +r2 2 0 10k +c1 2 0 1n +.options list node post trans +.end + Node Voltage + ---- ------- + ---- ------- + V(2) 0.000000e+00 + V(1) 0.000000e+00 + + Source Current + ------ ------- + + v1#branch 0.000000e+00 + + Capacitor models (Fixed capacitor) + model C + + cj 0 + cjsw 0 + defw 1e-05 + narrow 0 + + Resistor models (Simple linear resistor) + model R + + rsh 0 + narrow 0 + short 0 + tc1 0 + tc2 0 + defw 1e-05 + + Capacitor: Fixed capacitor + device c1 + model C +capacitance 1e-09 + i 0 + p 0 + + Resistor: Simple linear resistor + device r2 r1 + model R R + resistance 10000 10000 + ac 0 0 + i 0 0 + p 0 0 + + Vsource: Independent voltage source + device v1 + dc 0 + acmag 1 + i 0 + p -0 + + A Simple AC Run +-------------------------------------------------------------------------------- +Index frequency v(2) +-------------------------------------------------------------------------------- +0 1.000000e+03, 0.000000e+00 4.995070e-01, -1.569248e-02 +1 1.258925e+03, 0.000000e+00 4.992191e-01, -1.974427e-02 +2 1.584893e+03, 0.000000e+00 4.987635e-01, -2.483388e-02 +3 1.995262e+03, 0.000000e+00 4.980431e-01, -3.121884e-02 +4 2.511886e+03, 0.000000e+00 4.969056e-01, -3.921243e-02 +5 3.162278e+03, 0.000000e+00 4.951134e-01, -4.918748e-02 +6 3.981072e+03, 0.000000e+00 4.922993e-01, -6.157141e-02 +7 5.011872e+03, 0.000000e+00 4.879042e-01, -7.682179e-02 +8 6.309573e+03, 0.000000e+00 4.810969e-01, -9.536356e-02 +9 7.943282e+03, 0.000000e+00 4.706888e-01, -1.174583e-01 +10 1.000000e+04, 0.000000e+00 4.550849e-01, -1.429691e-01 +11 1.258925e+04, 0.000000e+00 4.323679e-01, -1.710028e-01 +12 1.584893e+04, 0.000000e+00 4.006689e-01, -1.994966e-01 +13 1.995262e+04, 0.000000e+00 3.589592e-01, -2.250064e-01 +14 2.511886e+04, 0.000000e+00 3.081227e-01, -2.431496e-01 +15 3.162278e+04, 0.000000e+00 2.516406e-01, -2.499946e-01 +16 3.981072e+04, 0.000000e+00 1.949905e-01, -2.438728e-01 +17 5.011872e+04, 0.000000e+00 1.437140e-01, -2.262814e-01 +18 6.309573e+04, 0.000000e+00 1.014372e-01, -2.010698e-01 +19 7.943282e+04, 0.000000e+00 6.918213e-02, -1.726410e-01 +20 1.000000e+05, 0.000000e+00 4.599983e-02, -1.445127e-01 +21 1.258925e+05, 0.000000e+00 3.004398e-02, -1.188249e-01 +22 1.584893e+05, 0.000000e+00 1.938636e-02, -9.652642e-02 +23 1.995262e+05, 0.000000e+00 1.240953e-02, -7.778670e-02 +24 2.511886e+05, 0.000000e+00 7.902266e-03, -6.235934e-02 +25 3.162278e+05, 0.000000e+00 5.015244e-03, -4.982439e-02 +26 3.981072e+05, 0.000000e+00 3.176162e-03, -3.972396e-02 +27 5.011872e+05, 0.000000e+00 2.008732e-03, -3.162801e-02 +28 6.309573e+05, 0.000000e+00 1.269306e-03, -2.516032e-02 +29 7.943282e+05, 0.000000e+00 8.016290e-04, -2.000430e-02 +30 1.000000e+06, 0.000000e+00 5.060931e-04, -1.589938e-02 + + + + 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 diff --git a/tests/maketest.sh b/tests/maketest.sh new file mode 100644 index 000000000..aa08b2290 --- /dev/null +++ b/tests/maketest.sh @@ -0,0 +1,11 @@ +#! /bin/sh + +NGSPICE=/usr/local/bin/ngspice +TEST=$1 + +DIFFPIPE="Analysis|CPU|memory|Date|Note|Mon|Tue|Wed|Thu|Fri|Sat|Sun" + +testname=$(basename $TEST .cir) +testdir=$(dirname $TEST) +$NGSPICE < $testdir/$testname.cir 2>&1 | egrep -v $DIFFPIPE > $testname.test +exit 0 diff --git a/tests/mesa/Makefile.am b/tests/mesa/Makefile.am new file mode 100644 index 000000000..a2012f52c --- /dev/null +++ b/tests/mesa/Makefile.am @@ -0,0 +1,20 @@ +## Process this file with automake to produce Makefile.in + +TESTS = \ + mesa11.cir \ + mesa13.cir \ + mesa14.cir \ + mesa15.cir \ + mesa21.cir \ + mesa.cir \ + mesgout.cir \ + mesinv.cir \ + mesosc.cir + +TESTS_ENVIRONMENT = $(SHELL) $(srcdir)/../check.sh $(top_builddir)/src/ngspice + +EXTRA_DIST = \ + $(TESTS) \ + $(TESTS:.cir=.out) + +MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/mesa/mesa.cir b/tests/mesa/mesa.cir new file mode 100644 index 000000000..d72c3aec5 --- /dev/null +++ b/tests/mesa/mesa.cir @@ -0,0 +1,14 @@ +* DCFL GaAs MESFET Gate\ +* Taken from macspice3f4 + +vdd 1 0 dc 3 +vin 3 0 dc 0 +z1 2 3 0 enha l=1u w=10u +z2 1 2 2 depl l=1u w=10u + +.model enha nmf level=2 rd=31 rs=31 vto=0.1 astar=0 +.model depl nmf level=2 rd=31 rs=31 vto=-1.0 astar=0 + +.dc vin 0 3.0 0.05 +.print dc v(2) vin#branch +.end diff --git a/tests/mesa/mesa.out b/tests/mesa/mesa.out new file mode 100644 index 000000000..22fc3cf32 --- /dev/null +++ b/tests/mesa/mesa.out @@ -0,0 +1,78 @@ + +No. of Data Rows : 61 + +Circuit: * DCFL GaAs MESFET Gate\ + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 + * DCFL GaAs MESFET Gate\ +-------------------------------------------------------------------------------- +Index v-sweep v(2) vin#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 2.992148e+00 1.222711e-07 +1 5.000000e-02 2.986117e+00 1.099225e-07 +2 1.000000e-01 2.978089e+00 9.838788e-08 +3 1.500000e-01 2.968344e+00 8.771704e-08 +4 2.000000e-01 2.957063e+00 7.792439e-08 +5 2.500000e-01 2.944276e+00 6.897674e-08 +6 3.000000e-01 2.929921e+00 6.082587e-08 +7 3.500000e-01 2.913878e+00 5.341886e-08 +8 4.000000e-01 2.895974e+00 4.670201e-08 +9 4.500000e-01 2.875963e+00 4.062119e-08 +10 5.000000e-01 2.853472e+00 3.512135e-08 +11 5.500000e-01 2.827936e+00 3.014608e-08 +12 6.000000e-01 2.798466e+00 2.563696e-08 +13 6.500000e-01 2.763633e+00 2.153243e-08 +14 7.000000e-01 2.721042e+00 1.776623e-08 +15 7.500000e-01 2.666534e+00 1.426655e-08 +16 8.000000e-01 2.592776e+00 1.096376e-08 +17 8.500000e-01 2.488055e+00 7.822830e-09 +18 9.000000e-01 2.340785e+00 5.018686e-09 +19 9.500000e-01 2.154051e+00 2.857908e-09 +20 1.000000e+00 1.945616e+00 1.453456e-09 +21 1.050000e+00 1.727796e+00 6.363525e-10 +22 1.100000e+00 1.500026e+00 1.869188e-10 +23 1.150000e+00 1.255138e+00 -4.361426e-11 +24 1.200000e+00 9.959858e-01 -1.421939e-10 +25 1.250000e+00 7.599885e-01 -1.684468e-10 +26 1.300000e+00 5.955970e-01 -1.674984e-10 +27 1.350000e+00 4.965958e-01 -1.608449e-10 +28 1.400000e+00 4.345031e-01 -1.536079e-10 +29 1.450000e+00 3.919482e-01 -1.465451e-10 +30 1.500000e+00 3.604795e-01 -1.398283e-10 +31 1.550000e+00 3.358282e-01 -1.333661e-10 +32 1.600000e+00 3.156600e-01 -1.271478e-10 +33 1.650000e+00 2.985995e-01 -1.211613e-10 +34 1.700000e+00 2.837831e-01 -1.153979e-10 +35 1.750000e+00 2.706382e-01 -1.098519e-10 +36 1.800000e+00 2.587662e-01 -1.045193e-10 +37 1.850000e+00 2.478763e-01 -9.939647e-11 +38 1.900000e+00 2.377452e-01 -9.448016e-11 +39 1.950000e+00 2.281900e-01 -8.972881e-11 +40 2.000000e+00 2.190482e-01 -8.522613e-11 +41 2.050000e+00 2.101553e-01 -8.091491e-11 +42 2.100000e+00 2.013138e-01 -7.678971e-11 +43 2.150000e+00 1.922195e-01 -7.284381e-11 +44 2.200000e+00 1.821999e-01 -6.900427e-11 +45 2.250000e+00 1.673580e-01 -6.520570e-11 +46 2.300000e+00 1.621070e-01 -6.188351e-11 +47 2.350000e+00 1.618962e-01 -5.892837e-11 +48 2.400000e+00 1.617131e-01 -5.608733e-11 +49 2.450000e+00 1.615536e-01 -5.338316e-11 +50 2.500000e+00 1.614140e-01 -5.081171e-11 +51 2.550000e+00 1.612915e-01 -4.836871e-11 +52 2.600000e+00 1.611837e-01 -4.604980e-11 +53 2.650000e+00 1.610885e-01 -4.385056e-11 +54 2.700000e+00 1.610043e-01 -4.176655e-11 + +Index v-sweep v(2) vin#branch +-------------------------------------------------------------------------------- +55 2.750000e+00 1.609295e-01 -3.979332e-11 +56 2.800000e+00 1.608629e-01 -3.792647e-11 +57 2.850000e+00 1.608035e-01 -3.616164e-11 +58 2.900000e+00 1.607505e-01 -3.449451e-11 +59 2.950000e+00 1.607029e-01 -3.292086e-11 +60 3.000000e+00 1.606602e-01 -3.143656e-11 + + + + diff --git a/tests/mesa/mesa11.cir b/tests/mesa/mesa11.cir new file mode 100644 index 000000000..2a22e1860 --- /dev/null +++ b/tests/mesa/mesa11.cir @@ -0,0 +1,17 @@ +* Mesa Level 2 test +* Taken from macspice3f4 archive. + +vds 1 0 +vids 1 2 dc 0 +vgs 3 0 dc 0 +z1 2 3 0 mesmod l=1u w=20u + +.op +.dc vds 0 2 0.05 vgs -1.2 0 0.4 +.print DC vids#branch + +.model mesmod nmf level=2 +*d=0.12u mu=0.23 vs=1.5e5 m=2.5 +*+ vto=-1.26 eta=1.73 lambda=0.045 sigma0=0.081 vsigma=0.1 +*+ vsigmat=1 rd=31 rs=31 +.end diff --git a/tests/mesa/mesa11.out b/tests/mesa/mesa11.out new file mode 100644 index 000000000..d490746db --- /dev/null +++ b/tests/mesa/mesa11.out @@ -0,0 +1,313 @@ +Warning: vds: has no value, DC 0 assumed + +No. of Data Rows : 164 + +No. of Data Rows : 1 + +Circuit: * Mesa Level 2 test + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 + Node Voltage + ---- ------- + ---- ------- + V(3) 0.000000e+00 + V(2) 0.000000e+00 + V(1) 0.000000e+00 + + Source Current + ------ ------- + + vds#branch 0.000000e+00 + vids#branch 0.000000e+00 + vgs#branch 0.000000e+00 + + MESA models (GaAs MESFET model) + model mesmod + + vt0 -1.26 + vto -1.26 + lambda 0.045 + lambdahf 0.045 + beta 0.0085 + vs 150000 + rd 0 + rs 0 + rg 0 + ri 0 + rf 0 + rdi 0 + rsi 0 + phib 8.01096e-20 + phib1 0 + tphib 0 + astar 40000 + ggr 40 + del 0.04 + xchi 0.033 + tggr 0.033 + n 1 + eta 1.73 + m 2.5 + mc 3 + alpha 0 + sigma0 0.081 + vsigmat 1.01 + vsigma 0.1 + mu 0.23 + theta 0 + mu1 0 + mu2 0 + d 1.2e-07 + nd 2e+23 + du 3.5e-08 + ndu 1e+22 + th 1e-08 + ndelta 6e+24 + delta 5 + tc 0 + tvto 0 + alphat 0 + tlambda 1.79769e+308 + teta0 1.79769e+308 + teta1 0 + tmu 300.15 + xtm0 0 + xtm1 0 + xtm2 0 + ks 0 + vsg 0 + tf 300.15 + flo 0 + delfo 0 + ag 0 + rtc1 0 + rtc2 0 + zeta 1 + level 2 + nmax 2e+16 + gamma 3 + epsi 1.08411e-10 + cas 1 + cbs 1 + type 1076316916 + gd 2.50927e-312 + gs 2.50927e-312 + vcrit 2.50927e-312 + + MESA: GaAs MESFET model + device z1 + model mesmod + off 0 + l 1e-06 + w 2e-05 + icvds 0 + icvgs 0 + td 300.15 + ts 300.15 + dnode 2 + gnode 3 + snode 0 + dprimenode 2 + sprimenode 0 + gprimenode 3 + vgs 0 + vgd 0 + cg 0 + cd 0 + cgd 0 + gm 0 + gds 0.00641271 + ggs 6.40329e-09 + ggd 6.40329e-09 + qgs 1.52287e-14 + cqgs 0 + qgd 1.52287e-14 + cqgd 0 + cs -0 + p 0 + + Vsource: Independent voltage source + device vgs vids vds + dc 0 0 0 + acmag 0 0 0 + i 0 0 0 + p -0 -0 -0 + + * Mesa Level 2 test +-------------------------------------------------------------------------------- +Index v-sweep vids#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 6.287335e-09 +1 5.000000e-02 8.247766e-06 +2 1.000000e-01 9.608412e-06 +3 1.500000e-01 1.042152e-05 +4 2.000000e-01 1.119220e-05 +5 2.500000e-01 1.198395e-05 +6 3.000000e-01 1.281268e-05 +7 3.500000e-01 1.368463e-05 +8 4.000000e-01 1.460330e-05 +9 4.500000e-01 1.557114e-05 +10 5.000000e-01 1.659018e-05 +11 5.500000e-01 1.766219e-05 +12 6.000000e-01 1.878878e-05 +13 6.500000e-01 1.997145e-05 +14 7.000000e-01 2.121159e-05 +15 7.500000e-01 2.251051e-05 +16 8.000000e-01 2.386942e-05 +17 8.500000e-01 2.528944e-05 +18 9.000000e-01 2.677159e-05 +19 9.500000e-01 2.831681e-05 +20 1.000000e+00 2.992592e-05 +21 1.050000e+00 3.159969e-05 +22 1.100000e+00 3.333876e-05 +23 1.150000e+00 3.514371e-05 +24 1.200000e+00 3.701500e-05 +25 1.250000e+00 3.895303e-05 +26 1.300000e+00 4.095811e-05 +27 1.350000e+00 4.303049e-05 +28 1.400000e+00 4.517034e-05 +29 1.450000e+00 4.737775e-05 +30 1.500000e+00 4.965278e-05 +31 1.550000e+00 5.199542e-05 +32 1.600000e+00 5.440564e-05 +33 1.650000e+00 5.688333e-05 +34 1.700000e+00 5.942841e-05 +35 1.750000e+00 6.204072e-05 +36 1.800000e+00 6.472013e-05 +37 1.850000e+00 6.746649e-05 +38 1.900000e+00 7.027964e-05 +39 1.950000e+00 7.315944e-05 +40 2.000000e+00 7.610576e-05 +41 0.000000e+00 2.351178e-09 +42 5.000000e-02 1.018087e-04 +43 1.000000e-01 1.847282e-04 +44 1.500000e-01 2.386501e-04 +45 2.000000e-01 2.712839e-04 +46 2.500000e-01 2.921130e-04 +47 3.000000e-01 3.067955e-04 +48 3.500000e-01 3.182098e-04 +49 4.000000e-01 3.278093e-04 +50 4.500000e-01 3.363569e-04 +51 5.000000e-01 3.442738e-04 +52 5.500000e-01 3.518038e-04 +53 6.000000e-01 3.590950e-04 +54 6.500000e-01 3.662405e-04 + +Index v-sweep vids#branch +-------------------------------------------------------------------------------- +55 7.000000e-01 3.733014e-04 +56 7.500000e-01 3.803188e-04 +57 8.000000e-01 3.873212e-04 +58 8.500000e-01 3.943289e-04 +59 9.000000e-01 4.013566e-04 +60 9.500000e-01 4.084152e-04 +61 1.000000e+00 4.155130e-04 +62 1.050000e+00 4.226565e-04 +63 1.100000e+00 4.298504e-04 +64 1.150000e+00 4.370990e-04 +65 1.200000e+00 4.444052e-04 +66 1.250000e+00 4.517719e-04 +67 1.300000e+00 4.592011e-04 +68 1.350000e+00 4.666948e-04 +69 1.400000e+00 4.742544e-04 +70 1.450000e+00 4.818814e-04 +71 1.500000e+00 4.895770e-04 +72 1.550000e+00 4.973421e-04 +73 1.600000e+00 5.051779e-04 +74 1.650000e+00 5.130851e-04 +75 1.700000e+00 5.210646e-04 +76 1.750000e+00 5.291171e-04 +77 1.800000e+00 5.372433e-04 +78 1.850000e+00 5.454439e-04 +79 1.900000e+00 5.537195e-04 +80 1.950000e+00 5.620708e-04 +81 2.000000e+00 5.704982e-04 +82 0.000000e+00 7.393328e-10 +83 5.000000e-02 2.028727e-04 +84 1.000000e-01 3.953294e-04 +85 1.500000e-01 5.615118e-04 +86 2.000000e-01 6.933551e-04 +87 2.500000e-01 7.926170e-04 +88 3.000000e-01 8.660732e-04 +89 3.500000e-01 9.209439e-04 +90 4.000000e-01 9.629829e-04 +91 4.500000e-01 9.962679e-04 +92 5.000000e-01 1.023556e-03 +93 5.500000e-01 1.046686e-03 +94 6.000000e-01 1.066890e-03 +95 6.500000e-01 1.085002e-03 +96 7.000000e-01 1.101595e-03 +97 7.500000e-01 1.117072e-03 +98 8.000000e-01 1.131718e-03 +99 8.500000e-01 1.145739e-03 +100 9.000000e-01 1.159289e-03 +101 9.500000e-01 1.172479e-03 +102 1.000000e+00 1.185396e-03 +103 1.050000e+00 1.198106e-03 +104 1.100000e+00 1.210659e-03 +105 1.150000e+00 1.223096e-03 +106 1.200000e+00 1.235447e-03 +107 1.250000e+00 1.247739e-03 +108 1.300000e+00 1.259991e-03 +109 1.350000e+00 1.272221e-03 +110 1.400000e+00 1.284441e-03 +111 1.450000e+00 1.296664e-03 +112 1.500000e+00 1.308898e-03 + +Index v-sweep vids#branch +-------------------------------------------------------------------------------- +113 1.550000e+00 1.321152e-03 +114 1.600000e+00 1.333432e-03 +115 1.650000e+00 1.345744e-03 +116 1.700000e+00 1.358093e-03 +117 1.750000e+00 1.370482e-03 +118 1.800000e+00 1.382916e-03 +119 1.850000e+00 1.395398e-03 +120 1.900000e+00 1.407930e-03 +121 1.950000e+00 1.420515e-03 +122 2.000000e+00 1.433155e-03 +123 0.000000e+00 7.163208e-25 +124 5.000000e-02 3.203183e-04 +125 1.000000e-01 6.320067e-04 +126 1.500000e-01 9.201977e-04 +127 2.000000e-01 1.172110e-03 +128 2.500000e-01 1.381625e-03 +129 3.000000e-01 1.549618e-03 +130 3.500000e-01 1.681428e-03 +131 4.000000e-01 1.783965e-03 +132 4.500000e-01 1.863838e-03 +133 5.000000e-01 1.926569e-03 +134 5.500000e-01 1.976453e-03 +135 6.000000e-01 2.016720e-03 +136 6.500000e-01 2.049754e-03 +137 7.000000e-01 2.077307e-03 +138 7.500000e-01 2.100670e-03 +139 8.000000e-01 2.120796e-03 +140 8.500000e-01 2.138397e-03 +141 9.000000e-01 2.154010e-03 +142 9.500000e-01 2.168042e-03 +143 1.000000e+00 2.180803e-03 +144 1.050000e+00 2.192537e-03 +145 1.100000e+00 2.203432e-03 +146 1.150000e+00 2.213637e-03 +147 1.200000e+00 2.223270e-03 +148 1.250000e+00 2.232427e-03 +149 1.300000e+00 2.241184e-03 +150 1.350000e+00 2.249604e-03 +151 1.400000e+00 2.257737e-03 +152 1.450000e+00 2.265627e-03 +153 1.500000e+00 2.273307e-03 +154 1.550000e+00 2.280808e-03 +155 1.600000e+00 2.288153e-03 +156 1.650000e+00 2.295363e-03 +157 1.700000e+00 2.302457e-03 +158 1.750000e+00 2.309448e-03 +159 1.800000e+00 2.316350e-03 +160 1.850000e+00 2.323173e-03 +161 1.900000e+00 2.329927e-03 +162 1.950000e+00 2.336620e-03 +163 2.000000e+00 2.343260e-03 + + + + diff --git a/tests/mesa/mesa13.cir b/tests/mesa/mesa13.cir new file mode 100644 index 000000000..2ec31a8ee --- /dev/null +++ b/tests/mesa/mesa13.cir @@ -0,0 +1,14 @@ +* MESA1 - Gate Leakage Test +* Taken from macspice3f4 +* + +z1 0 2 0 mesmod l=1u w=20u +vgs 1 0 dc 0 +vig 1 2 dc 0 +.model mesmod nmf(level=2 rd=31 rs=31 rg=10) + +.dc vgs -3 0.4 0.05 +.print vig#branch + +.end + diff --git a/tests/mesa/mesa13.out b/tests/mesa/mesa13.out new file mode 100644 index 000000000..b630000c3 --- /dev/null +++ b/tests/mesa/mesa13.out @@ -0,0 +1,4 @@ +Warning: no nodes given: .print vig#branch + +Circuit: * MESA1 - Gate Leakage Test + diff --git a/tests/mesa/mesa14.cir b/tests/mesa/mesa14.cir new file mode 100644 index 000000000..0be8e301e --- /dev/null +++ b/tests/mesa/mesa14.cir @@ -0,0 +1,17 @@ +* MESA1 - DCFL GaAs MESFET Gate +* Taken from macspice3f4 +* +* Removed: jsdf = 0 in modelcards + +vdd 1 0 dc 3 +vin 3 0 dc 0 +z1 2 3 0 enha l=1u w=10u +z2 1 2 2 depl l=1u w=10u + +.model enha nmf level=2 rd=31 rs=31 vto=0.1 +.model depl nmf level=2 rd=31 rs=31 vto=-1.0 + +.dc vin 0 3.0 0.05 +.print DC V(2) + +.end diff --git a/tests/mesa/mesa14.out b/tests/mesa/mesa14.out new file mode 100644 index 000000000..c94ddc393 --- /dev/null +++ b/tests/mesa/mesa14.out @@ -0,0 +1,78 @@ + +No. of Data Rows : 61 + +Circuit: * MESA1 - DCFL GaAs MESFET Gate + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 + * MESA1 - DCFL GaAs MESFET Gate +-------------------------------------------------------------------------------- +Index v-sweep v(2) +-------------------------------------------------------------------------------- +0 0.000000e+00 2.992148e+00 +1 5.000000e-02 2.986117e+00 +2 1.000000e-01 2.978089e+00 +3 1.500000e-01 2.968344e+00 +4 2.000000e-01 2.957064e+00 +5 2.500000e-01 2.944285e+00 +6 3.000000e-01 2.929989e+00 +7 3.500000e-01 2.914358e+00 +8 4.000000e-01 2.898823e+00 +9 4.500000e-01 2.886782e+00 +10 5.000000e-01 2.879373e+00 +11 5.500000e-01 2.875035e+00 +12 6.000000e-01 2.872468e+00 +13 6.500000e-01 2.870970e+00 +14 7.000000e-01 2.870185e+00 +15 7.500000e-01 2.869884e+00 +16 8.000000e-01 2.869935e+00 +17 8.500000e-01 2.870251e+00 +18 9.000000e-01 2.870770e+00 +19 9.500000e-01 2.871450e+00 +20 1.000000e+00 2.872259e+00 +21 1.050000e+00 2.873173e+00 +22 1.100000e+00 2.874171e+00 +23 1.150000e+00 2.875241e+00 +24 1.200000e+00 2.876369e+00 +25 1.250000e+00 2.877545e+00 +26 1.300000e+00 2.878763e+00 +27 1.350000e+00 2.880015e+00 +28 1.400000e+00 2.881295e+00 +29 1.450000e+00 2.882599e+00 +30 1.500000e+00 2.883922e+00 +31 1.550000e+00 2.885262e+00 +32 1.600000e+00 2.886614e+00 +33 1.650000e+00 2.887978e+00 +34 1.700000e+00 2.889345e+00 +35 1.750000e+00 2.890725e+00 +36 1.800000e+00 2.892109e+00 +37 1.850000e+00 2.893495e+00 +38 1.900000e+00 2.894884e+00 +39 1.950000e+00 2.896273e+00 +40 2.000000e+00 2.897662e+00 +41 2.050000e+00 2.899050e+00 +42 2.100000e+00 2.900436e+00 +43 2.150000e+00 2.901820e+00 +44 2.200000e+00 2.903201e+00 +45 2.250000e+00 2.904579e+00 +46 2.300000e+00 2.905954e+00 +47 2.350000e+00 2.907325e+00 +48 2.400000e+00 2.908693e+00 +49 2.450000e+00 2.910058e+00 +50 2.500000e+00 2.911421e+00 +51 2.550000e+00 2.912781e+00 +52 2.600000e+00 2.914141e+00 +53 2.650000e+00 2.915502e+00 +54 2.700000e+00 2.916866e+00 + +Index v-sweep v(2) +-------------------------------------------------------------------------------- +55 2.750000e+00 2.918237e+00 +56 2.800000e+00 2.919618e+00 +57 2.850000e+00 2.921018e+00 +58 2.900000e+00 2.922445e+00 +59 2.950000e+00 2.923914e+00 +60 3.000000e+00 2.925448e+00 + + + + diff --git a/tests/mesa/mesa15.cir b/tests/mesa/mesa15.cir new file mode 100644 index 000000000..a65a99b08 --- /dev/null +++ b/tests/mesa/mesa15.cir @@ -0,0 +1,15 @@ +* MESA1 subtreshold characteristics (T=400) +* Taken form macspice3f4 + +vds 1 0 dc 0.1 +vids 1 2 dc 0 +vgs 3 0 dc 0 + +z1 2 3 0 mesmod l=1u w=20u ts=400 td=400 +.model mesmod nmf level=2 rd=31 rs=31 + +.dc vgs -3 0 0.05 +.print DC vids#branch + +.end + diff --git a/tests/mesa/mesa15.out b/tests/mesa/mesa15.out new file mode 100644 index 000000000..88ef011ec --- /dev/null +++ b/tests/mesa/mesa15.out @@ -0,0 +1,78 @@ + +No. of Data Rows : 61 + +Circuit: * MESA1 subtreshold characteristics (T=400) + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 + * MESA1 subtreshold characteristics (T=400) +-------------------------------------------------------------------------------- +Index v-sweep vids#branch +-------------------------------------------------------------------------------- +0 -3.000000e+00 4.125058e-03 +1 -2.950000e+00 3.943238e-03 +2 -2.900000e+00 3.767131e-03 +3 -2.850000e+00 3.597267e-03 +4 -2.800000e+00 3.433783e-03 +5 -2.750000e+00 3.276220e-03 +6 -2.700000e+00 3.124729e-03 +7 -2.650000e+00 2.978839e-03 +8 -2.600000e+00 2.838102e-03 +9 -2.550000e+00 2.703221e-03 +10 -2.500000e+00 2.573561e-03 +11 -2.450000e+00 2.448971e-03 +12 -2.400000e+00 2.329301e-03 +13 -2.350000e+00 2.214402e-03 +14 -2.300000e+00 2.104128e-03 +15 -2.250000e+00 1.999387e-03 +16 -2.200000e+00 1.897774e-03 +17 -2.150000e+00 1.800385e-03 +18 -2.100000e+00 1.707077e-03 +19 -2.050000e+00 1.617714e-03 +20 -2.000000e+00 1.532163e-03 +21 -1.950000e+00 1.450294e-03 +22 -1.900000e+00 1.371981e-03 +23 -1.850000e+00 1.297103e-03 +24 -1.800000e+00 1.225546e-03 +25 -1.750000e+00 1.157203e-03 +26 -1.700000e+00 1.091976e-03 +27 -1.650000e+00 1.029782e-03 +28 -1.600000e+00 9.705574e-04 +29 -1.550000e+00 9.142605e-04 +30 -1.500000e+00 8.608839e-04 +31 -1.450000e+00 8.104610e-04 +32 -1.400000e+00 7.630782e-04 +33 -1.350000e+00 7.188914e-04 +34 -1.300000e+00 6.781458e-04 +35 -1.250000e+00 6.411910e-04 +36 -1.200000e+00 6.084624e-04 +37 -1.150000e+00 5.803980e-04 +38 -1.100000e+00 5.572778e-04 +39 -1.050000e+00 5.390362e-04 +40 -1.000000e+00 5.251551e-04 +41 -9.500000e-01 5.147423e-04 +42 -9.000000e-01 5.067823e-04 +43 -8.500000e-01 5.004073e-04 +44 -8.000000e-01 4.950394e-04 +45 -7.500000e-01 4.903818e-04 +46 -7.000000e-01 4.863324e-04 +47 -6.500000e-01 4.828927e-04 +48 -6.000000e-01 4.799856e-04 +49 -5.500000e-01 4.779171e-04 +50 -5.000000e-01 4.765745e-04 +51 -4.500000e-01 4.759752e-04 +52 -4.000000e-01 4.761212e-04 +53 -3.500000e-01 4.770035e-04 +54 -3.000000e-01 4.786067e-04 + +Index v-sweep vids#branch +-------------------------------------------------------------------------------- +55 -2.500000e-01 4.809070e-04 +56 -2.000000e-01 4.838512e-04 +57 -1.500000e-01 4.872975e-04 +58 -1.000000e-01 4.908874e-04 +59 -5.000000e-02 4.937605e-04 +60 -2.289835e-15 4.939065e-04 + + + + diff --git a/tests/mesa/mesa21.cir b/tests/mesa/mesa21.cir new file mode 100644 index 000000000..6c89dff61 --- /dev/null +++ b/tests/mesa/mesa21.cir @@ -0,0 +1,17 @@ +* Mesa Test +* Taken from macspice3f4 + +z1 3 2 0 mesmod l=1u w=150u +vgs 2 0 dc 0 +vds 1 0 dc 0 +vids 1 3 dc 0 + +.model mesmod nmf level=3 rdi=2.7 rsi=2.7 mu=0.2 m=2.2 vto=-2.04 ++ eta=1.5 lambda=0.04 tc=0.001 sigma0=0.02 vsigma=0.1 vsigmat=1.37 ++ delta=5 beta=0.0085 + +.dc vds 0 4 0.05 vgs -1.5 0.5 0.5 +.print vids#branch + +.end + diff --git a/tests/mesa/mesa21.out b/tests/mesa/mesa21.out new file mode 100644 index 000000000..895250f77 --- /dev/null +++ b/tests/mesa/mesa21.out @@ -0,0 +1,4 @@ +Warning: no nodes given: .print vids#branch + +Circuit: * Mesa Test + diff --git a/tests/mesa/mesgout.cir b/tests/mesa/mesgout.cir new file mode 100644 index 000000000..72f8b5afb --- /dev/null +++ b/tests/mesa/mesgout.cir @@ -0,0 +1,35 @@ +* Simulation of MESFET output conductance +* Taken from macspice3f4 +* + +rd 1 2 20 +z1 3 4 0 driver l=1u w=10u +rs 5 0 20 +vgs 4 0 dc 0.5 ac 0.01 +vds 1 0 dc 1.0 +vid 2 3 dc 0 + +.model driver nmf ++ level=2 +*+ jsdf=1e-100 ++ n=1.44 ++ rd=0 ++ rs=0 ++ vs=1.5e5 ++ mu=0.25 ++ d=2e-7 ++ vto=0.1 ++ m=2 ++ lambda=0 ++ sigma0=0 ++ delfo=5 ++ flo=0.5 ++ tf=100000 ++ lambdahf=120 + +.ac DEC 10 0.001 1e6 + +.print ac V(3) + +.end + diff --git a/tests/mesa/mesgout.out b/tests/mesa/mesgout.out new file mode 100644 index 000000000..87d4bf437 --- /dev/null +++ b/tests/mesa/mesgout.out @@ -0,0 +1,108 @@ + +No. of Data Rows : 91 + +Circuit: * Simulation of MESFET output conductance + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 + * Simulation of MESFET output conductance +-------------------------------------------------------------------------------- +Index frequency v(3) +-------------------------------------------------------------------------------- +0 1.000000e-03, 0.000000e+00 -8.965836e-04, 6.902362e-19 +1 1.258925e-03, 0.000000e+00 -8.966291e-04, 8.689560e-19 +2 1.584893e-03, 0.000000e+00 -8.966864e-04, 1.093951e-18 +3 1.995262e-03, 0.000000e+00 -8.967585e-04, 1.377203e-18 +4 2.511886e-03, 0.000000e+00 -8.968492e-04, 1.733796e-18 +5 3.162278e-03, 0.000000e+00 -8.969635e-04, 2.182721e-18 +6 3.981072e-03, 0.000000e+00 -8.971074e-04, 2.747884e-18 +7 5.011872e-03, 0.000000e+00 -8.972885e-04, 3.459383e-18 +8 6.309573e-03, 0.000000e+00 -8.975165e-04, 4.355108e-18 +9 7.943282e-03, 0.000000e+00 -8.978035e-04, 5.482761e-18 +10 1.000000e-02, 0.000000e+00 -8.981649e-04, 6.902395e-18 +11 1.258925e-02, 0.000000e+00 -8.986199e-04, 8.689612e-18 +12 1.584893e-02, 0.000000e+00 -8.991926e-04, 1.093959e-17 +13 1.995262e-02, 0.000000e+00 -8.999137e-04, 1.377216e-17 +14 2.511886e-02, 0.000000e+00 -9.008215e-04, 1.733817e-17 +15 3.162278e-02, 0.000000e+00 -9.019645e-04, 2.182754e-17 +16 3.981072e-02, 0.000000e+00 -9.034034e-04, 2.747936e-17 +17 5.011872e-02, 0.000000e+00 -9.052150e-04, 3.459464e-17 +18 6.309573e-02, 0.000000e+00 -9.074958e-04, 4.355236e-17 +19 7.943282e-02, 0.000000e+00 -9.103672e-04, 5.482962e-17 +20 1.000000e-01, 0.000000e+00 -9.139824e-04, 6.902710e-17 +21 1.258925e-01, 0.000000e+00 -9.185336e-04, 8.690104e-17 +22 1.584893e-01, 0.000000e+00 -9.242630e-04, 1.094036e-16 +23 1.995262e-01, 0.000000e+00 -9.314747e-04, 1.377335e-16 +24 2.511886e-01, 0.000000e+00 -9.405505e-04, 1.733999e-16 +25 3.162278e-01, 0.000000e+00 -9.519685e-04, 2.183031e-16 +26 3.981072e-01, 0.000000e+00 -9.663249e-04, 2.748353e-16 +27 5.011872e-01, 0.000000e+00 -9.843591e-04, 3.460081e-16 +28 6.309573e-01, 0.000000e+00 -1.006979e-03, 4.356124e-16 +29 7.943282e-01, 0.000000e+00 -1.035279e-03, 5.484192e-16 +30 1.000000e+00, 0.000000e+00 -1.070545e-03, 6.904308e-16 +31 1.258925e+00, 0.000000e+00 -1.114211e-03, 8.691951e-16 +32 1.584893e+00, 0.000000e+00 -1.167731e-03, 1.094197e-15 +33 1.995262e+00, 0.000000e+00 -1.232294e-03, 1.377343e-15 +34 2.511886e+00, 0.000000e+00 -1.308280e-03, 1.733570e-15 +35 3.162278e+00, 0.000000e+00 -1.394424e-03, 2.181614e-15 +36 3.981072e+00, 0.000000e+00 -1.486819e-03, 2.745011e-15 +37 5.011872e+00, 0.000000e+00 -1.578371e-03, 3.453445e-15 +38 6.309573e+00, 0.000000e+00 -1.659776e-03, 4.344535e-15 +39 7.943282e+00, 0.000000e+00 -1.722639e-03, 5.466032e-15 +40 1.000000e+01, 0.000000e+00 -1.763385e-03, 6.878303e-15 +41 1.258925e+01, 0.000000e+00 -1.784787e-03, 8.657178e-15 +42 1.584893e+01, 0.000000e+00 -1.793547e-03, 1.089764e-14 +43 1.995262e+01, 0.000000e+00 -1.796207e-03, 1.371889e-14 +44 2.511886e+01, 0.000000e+00 -1.796769e-03, 1.727095e-14 +45 3.162278e+01, 0.000000e+00 -1.796845e-03, 2.174281e-14 +46 3.981072e+01, 0.000000e+00 -1.796851e-03, 2.737258e-14 +47 5.011872e+01, 0.000000e+00 -1.796851e-03, 3.446003e-14 +48 6.309573e+01, 0.000000e+00 -1.796851e-03, 4.338261e-14 +49 7.943282e+01, 0.000000e+00 -1.796851e-03, 5.461547e-14 +50 1.000000e+02, 0.000000e+00 -1.796851e-03, 6.875681e-14 +51 1.258925e+02, 0.000000e+00 -1.796851e-03, 8.655969e-14 +52 1.584893e+02, 0.000000e+00 -1.796851e-03, 1.089722e-13 +53 1.995262e+02, 0.000000e+00 -1.796851e-03, 1.371879e-13 +54 2.511886e+02, 0.000000e+00 -1.796851e-03, 1.727093e-13 + +Index frequency v(3) +-------------------------------------------------------------------------------- +55 3.162278e+02, 0.000000e+00 -1.796851e-03, 2.174281e-13 +56 3.981072e+02, 0.000000e+00 -1.796851e-03, 2.737258e-13 +57 5.011872e+02, 0.000000e+00 -1.796851e-03, 3.446003e-13 +58 6.309573e+02, 0.000000e+00 -1.796851e-03, 4.338261e-13 +59 7.943282e+02, 0.000000e+00 -1.796851e-03, 5.461547e-13 +60 1.000000e+03, 0.000000e+00 -1.796851e-03, 6.875681e-13 +61 1.258925e+03, 0.000000e+00 -1.796851e-03, 8.655969e-13 +62 1.584893e+03, 0.000000e+00 -1.796851e-03, 1.089722e-12 +63 1.995262e+03, 0.000000e+00 -1.796851e-03, 1.371879e-12 +64 2.511886e+03, 0.000000e+00 -1.796851e-03, 1.727093e-12 +65 3.162278e+03, 0.000000e+00 -1.796851e-03, 2.174281e-12 +66 3.981072e+03, 0.000000e+00 -1.796851e-03, 2.737258e-12 +67 5.011872e+03, 0.000000e+00 -1.796851e-03, 3.446003e-12 +68 6.309573e+03, 0.000000e+00 -1.796851e-03, 4.338261e-12 +69 7.943282e+03, 0.000000e+00 -1.796851e-03, 5.461547e-12 +70 1.000000e+04, 0.000000e+00 -1.796851e-03, 6.875681e-12 +71 1.258925e+04, 0.000000e+00 -1.796851e-03, 8.655969e-12 +72 1.584893e+04, 0.000000e+00 -1.796851e-03, 1.089722e-11 +73 1.995262e+04, 0.000000e+00 -1.796851e-03, 1.371879e-11 +74 2.511886e+04, 0.000000e+00 -1.796851e-03, 1.727093e-11 +75 3.162278e+04, 0.000000e+00 -1.796851e-03, 2.174281e-11 +76 3.981072e+04, 0.000000e+00 -1.796851e-03, 2.737258e-11 +77 5.011872e+04, 0.000000e+00 -1.796851e-03, 3.446003e-11 +78 6.309573e+04, 0.000000e+00 -1.796851e-03, 4.338261e-11 +79 7.943282e+04, 0.000000e+00 -1.796851e-03, 5.461547e-11 +80 1.000000e+05, 0.000000e+00 -1.796851e-03, 6.875681e-11 +81 1.258925e+05, 0.000000e+00 -1.796851e-03, 8.655969e-11 +82 1.584893e+05, 0.000000e+00 -1.796851e-03, 1.089722e-10 +83 1.995262e+05, 0.000000e+00 -1.796851e-03, 1.371879e-10 +84 2.511886e+05, 0.000000e+00 -1.796851e-03, 1.727093e-10 +85 3.162278e+05, 0.000000e+00 -1.796851e-03, 2.174281e-10 +86 3.981072e+05, 0.000000e+00 -1.796851e-03, 2.737258e-10 +87 5.011872e+05, 0.000000e+00 -1.796851e-03, 3.446003e-10 +88 6.309573e+05, 0.000000e+00 -1.796851e-03, 4.338261e-10 +89 7.943282e+05, 0.000000e+00 -1.796851e-03, 5.461547e-10 +90 1.000000e+06, 0.000000e+00 -1.796851e-03, 6.875681e-10 + + + + diff --git a/tests/mesa/mesinv.cir b/tests/mesa/mesinv.cir new file mode 100644 index 000000000..457ddebe8 --- /dev/null +++ b/tests/mesa/mesinv.cir @@ -0,0 +1,47 @@ +* Mesfet Inverter with ungated load/Wload=2e-6 +* Taken from macspice3f4 package +* +* Output node is 70 +* + +bl1 10 40 i=0.0005*tanh(v(10,40)/0.0005/1120)*(1+v(10,40)*0.027) +bl2 20 50 i=0.0005*tanh(v(20,50)/0.0005/1120)*(1+v(20,50)*0.027) + +zd1 70 2 0 driver l=0.7u w=20u +zd2 80 70 0 driver l=0.7u w=20u + +rdl1 1 10 20 +rdl2 1 20 20 +rsl1 40 70 20 +rsl2 50 80 20 + +vin 1000 0 dc 0 +vdd 2000 0 dc 1.6 +visrc 2000 1 dc 0 +vig 1000 2 dc 0 + +.model driver nmf ++ level=2 ++ n=1.44 ++ rd=20 ++ rs=20 ++ ri=10 ++ rf=10 ++ vs=1.9e5 ++ mu=0.25 ++ d=1e-7 ++ vto=0.15 ++ m=2 ++ lambda=0.15 ++ sigma0=0.02 ++ vsigmat=0.5 + +*.nodeset v(10)=1.6 v(40)=1.6 v(70)=1.6 v(20)=0.2 v(50)=0.2 +*+ v(80)=0.2 + +.dc vin 0 1 0.01 + +.print dc v(70) + +.end + diff --git a/tests/mesa/mesinv.out b/tests/mesa/mesinv.out new file mode 100644 index 000000000..bafe0e05e --- /dev/null +++ b/tests/mesa/mesinv.out @@ -0,0 +1,118 @@ + +No. of Data Rows : 101 + +Circuit: * Mesfet Inverter with ungated load/Wload=2e-6 + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 + * Mesfet Inverter with ungated load/Wload=2e-6 +-------------------------------------------------------------------------------- +Index v-sweep v(70) +-------------------------------------------------------------------------------- +0 0.000000e+00 5.924361e-01 +1 1.000000e-02 5.924266e-01 +2 2.000000e-02 5.924150e-01 +3 3.000000e-02 5.924009e-01 +4 4.000000e-02 5.923837e-01 +5 5.000000e-02 5.923628e-01 +6 6.000000e-02 5.923376e-01 +7 7.000000e-02 5.923072e-01 +8 8.000000e-02 5.922706e-01 +9 9.000000e-02 5.922268e-01 +10 1.000000e-01 5.921744e-01 +11 1.100000e-01 5.921119e-01 +12 1.200000e-01 5.920374e-01 +13 1.300000e-01 5.919488e-01 +14 1.400000e-01 5.918436e-01 +15 1.500000e-01 5.917188e-01 +16 1.600000e-01 5.915710e-01 +17 1.700000e-01 5.913965e-01 +18 1.800000e-01 5.911910e-01 +19 1.900000e-01 5.909499e-01 +20 2.000000e-01 5.906683e-01 +21 2.100000e-01 5.903409e-01 +22 2.200000e-01 5.899623e-01 +23 2.300000e-01 5.895270e-01 +24 2.400000e-01 5.890297e-01 +25 2.500000e-01 5.884649e-01 +26 2.600000e-01 5.878276e-01 +27 2.700000e-01 5.871129e-01 +28 2.800000e-01 5.863163e-01 +29 2.900000e-01 5.854335e-01 +30 3.000000e-01 5.844605e-01 +31 3.100000e-01 5.833935e-01 +32 3.200000e-01 5.822287e-01 +33 3.300000e-01 5.809623e-01 +34 3.400000e-01 5.795901e-01 +35 3.500000e-01 5.781075e-01 +36 3.600000e-01 5.765093e-01 +37 3.700000e-01 5.747892e-01 +38 3.800000e-01 5.729398e-01 +39 3.900000e-01 5.709521e-01 +40 4.000000e-01 5.688151e-01 +41 4.100000e-01 5.665157e-01 +42 4.200000e-01 5.640376e-01 +43 4.300000e-01 5.613612e-01 +44 4.400000e-01 5.584622e-01 +45 4.500000e-01 5.553106e-01 +46 4.600000e-01 5.518691e-01 +47 4.700000e-01 5.480905e-01 +48 4.800000e-01 5.439146e-01 +49 4.900000e-01 5.392629e-01 +50 5.000000e-01 5.340310e-01 +51 5.100000e-01 5.280766e-01 +52 5.200000e-01 5.211990e-01 +53 5.300000e-01 5.131045e-01 +54 5.400000e-01 5.033434e-01 + +Index v-sweep v(70) +-------------------------------------------------------------------------------- +55 5.500000e-01 4.911924e-01 +56 5.600000e-01 4.753952e-01 +57 5.700000e-01 4.539713e-01 +58 5.800000e-01 4.244135e-01 +59 5.900000e-01 3.876541e-01 +60 6.000000e-01 3.514843e-01 +61 6.100000e-01 3.221191e-01 +62 6.200000e-01 3.002658e-01 +63 6.300000e-01 2.846144e-01 +64 6.400000e-01 2.737513e-01 +65 6.500000e-01 2.665589e-01 +66 6.600000e-01 2.621996e-01 +67 6.700000e-01 2.600819e-01 +68 6.800000e-01 2.597376e-01 +69 6.900000e-01 2.608215e-01 +70 7.000000e-01 2.630686e-01 +71 7.100000e-01 2.662719e-01 +72 7.200000e-01 2.702685e-01 +73 7.300000e-01 2.749285e-01 +74 7.400000e-01 2.801474e-01 +75 7.500000e-01 2.858405e-01 +76 7.600000e-01 2.919385e-01 +77 7.700000e-01 2.983841e-01 +78 7.800000e-01 3.051299e-01 +79 7.900000e-01 3.121360e-01 +80 8.000000e-01 3.193687e-01 +81 8.100000e-01 3.267991e-01 +82 8.200000e-01 3.344025e-01 +83 8.300000e-01 3.421572e-01 +84 8.400000e-01 3.500441e-01 +85 8.500000e-01 3.580459e-01 +86 8.600000e-01 3.661472e-01 +87 8.700000e-01 3.743331e-01 +88 8.800000e-01 3.825898e-01 +89 8.900000e-01 3.909037e-01 +90 9.000000e-01 3.992614e-01 +91 9.100000e-01 4.076488e-01 +92 9.200000e-01 4.160519e-01 +93 9.300000e-01 4.244554e-01 +94 9.400000e-01 4.328433e-01 +95 9.500000e-01 4.411989e-01 +96 9.600000e-01 4.495040e-01 +97 9.700000e-01 4.577402e-01 +98 9.800000e-01 4.658884e-01 +99 9.900000e-01 4.739299e-01 +100 1.000000e+00 4.818466e-01 + + + + diff --git a/tests/mesa/mesosc.cir b/tests/mesa/mesosc.cir new file mode 100644 index 000000000..bd292331c --- /dev/null +++ b/tests/mesa/mesosc.cir @@ -0,0 +1,40 @@ +* Mesfet Ring Oscillator with ungated load +* Taken form macspice3f4 +* + +.subckt mesinv 10 20 3 +* Node 10: Power Supply +* Node 20: Input +* Node 30: Output +rdl 10 1 20 +bl1 1 2 i=0.00025*tanh(v(1,2)/0.00025/2240)*(1+v(1,2)*0.027) +rsl 2 3 20 +zd 3 20 0 driver l=0.7u w=20u +ci 3 0 20f +.ends mesinv + +.model driver nmf level=2 n=1.44 rd=20 rs=20 vs=1.9e5 ++ mu=0.25 d=1e-7 vto=0.15 m=2 lambda=0.15 sigma0=0.02 ++ vsigmat=0.5 + +vdd 1 0 dc 1.6 + +xinv01 1 2 3 mesinv +xinv02 1 3 4 mesinv +xinv03 1 4 5 mesinv +xinv04 1 5 6 mesinv +xinv05 1 6 7 mesinv +xinv06 1 7 8 mesinv +xinv07 1 8 9 mesinv +xinv08 1 9 10 mesinv +xinv09 1 10 11 mesinv +xinv10 1 11 12 mesinv +xinv11 1 12 2000 mesinv + +vnoise 2000 2 dc 0 pwl(0 0 0.2n 0 0.3n 0.1 0.4n 0) + +.tran 1p 5n 1n 20p + +.print tran V(8) + +.end diff --git a/tests/mesa/mesosc.out b/tests/mesa/mesosc.out new file mode 100644 index 000000000..48a5b9915 --- /dev/null +++ b/tests/mesa/mesosc.out @@ -0,0 +1,268 @@ + +Circuit: * Mesfet Ring Oscillator with ungated load + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 + +Initial Transient Solution +-------------------------- + +Node Voltage +---- ------- +1 1.6 +inv01:1 1.59501 +inv01:2 0.437524 +3 0.432531 +2 0.432531 +inv02:1 1.59501 +inv02:2 0.437524 +4 0.432531 +inv03:1 1.59501 +inv03:2 0.437524 +5 0.432531 +inv04:1 1.59501 +inv04:2 0.437524 +6 0.432531 +inv05:1 1.59501 +inv05:2 0.437524 +7 0.432531 +inv06:1 1.59501 +inv06:2 0.437524 +8 0.432531 +inv07:1 1.59501 +inv07:2 0.437524 +9 0.432531 +inv08:1 1.59501 +inv08:2 0.437524 +10 0.432531 +inv09:1 1.59501 +inv09:2 0.437524 +11 0.432531 +inv10:1 1.59501 +inv10:2 0.437524 +12 0.432531 +inv11:1 1.59501 +inv11:2 0.437524 +2000 0.432531 +vnoise#branch 9.80682e-06 +vdd#branch -0.00274651 + + Reference value : 1.01000e-09 Reference value : 2.89000e-09 Reference value : 4.81000e-09 +No. of Data Rows : 201 + * Mesfet Ring Oscillator with ungated load +-------------------------------------------------------------------------------- +Index time v(8) +-------------------------------------------------------------------------------- +0 1.010000e-09 3.973711e-01 +1 1.030000e-09 2.946081e-01 +2 1.050000e-09 2.117092e-01 +3 1.070000e-09 1.572303e-01 +4 1.090000e-09 1.293171e-01 +5 1.110000e-09 1.186598e-01 +6 1.130000e-09 1.156708e-01 +7 1.150000e-09 1.151043e-01 +8 1.170000e-09 1.149294e-01 +9 1.190000e-09 1.149571e-01 +10 1.210000e-09 1.149146e-01 +11 1.230000e-09 1.149612e-01 +12 1.250000e-09 1.149192e-01 +13 1.270000e-09 1.149617e-01 +14 1.290000e-09 1.149206e-01 +15 1.310000e-09 1.149627e-01 +16 1.330000e-09 1.149168e-01 +17 1.350000e-09 1.148248e-01 +18 1.370000e-09 1.143588e-01 +19 1.390000e-09 1.170177e-01 +20 1.410000e-09 1.427655e-01 +21 1.430000e-09 2.162097e-01 +22 1.450000e-09 3.304225e-01 +23 1.470000e-09 4.572213e-01 +24 1.490000e-09 5.419430e-01 +25 1.510000e-09 5.605499e-01 +26 1.530000e-09 5.567486e-01 +27 1.550000e-09 5.560532e-01 +28 1.570000e-09 5.549382e-01 +29 1.590000e-09 5.544866e-01 +30 1.610000e-09 5.542368e-01 +31 1.630000e-09 5.542268e-01 +32 1.650000e-09 5.541876e-01 +33 1.670000e-09 5.542118e-01 +34 1.690000e-09 5.541883e-01 +35 1.710000e-09 5.542116e-01 +36 1.730000e-09 5.541894e-01 +37 1.750000e-09 5.542108e-01 +38 1.770000e-09 5.541899e-01 +39 1.790000e-09 5.542212e-01 +40 1.810000e-09 5.542194e-01 +41 1.830000e-09 5.535085e-01 +42 1.850000e-09 5.466530e-01 +43 1.870000e-09 5.192749e-01 +44 1.890000e-09 4.533767e-01 +45 1.910000e-09 3.527324e-01 +46 1.930000e-09 2.559481e-01 +47 1.950000e-09 1.850300e-01 +48 1.970000e-09 1.425183e-01 +49 1.990000e-09 1.233472e-01 +50 2.010000e-09 1.168263e-01 +51 2.030000e-09 1.153295e-01 +52 2.050000e-09 1.149964e-01 +53 2.070000e-09 1.149410e-01 +54 2.090000e-09 1.149339e-01 + +Index time v(8) +-------------------------------------------------------------------------------- +55 2.110000e-09 1.149387e-01 +56 2.130000e-09 1.149395e-01 +57 2.150000e-09 1.149412e-01 +58 2.170000e-09 1.149403e-01 +59 2.190000e-09 1.149421e-01 +60 2.210000e-09 1.149422e-01 +61 2.230000e-09 1.149126e-01 +62 2.250000e-09 1.146328e-01 +63 2.270000e-09 1.145616e-01 +64 2.290000e-09 1.230523e-01 +65 2.310000e-09 1.689190e-01 +66 2.330000e-09 2.619861e-01 +67 2.350000e-09 3.862734e-01 +68 2.370000e-09 5.027781e-01 +69 2.390000e-09 5.565723e-01 +70 2.410000e-09 5.584197e-01 +71 2.430000e-09 5.565958e-01 +72 2.450000e-09 5.554527e-01 +73 2.470000e-09 5.547150e-01 +74 2.490000e-09 5.543380e-01 +75 2.510000e-09 5.542264e-01 +76 2.530000e-09 5.542074e-01 +77 2.550000e-09 5.541971e-01 +78 2.570000e-09 5.542022e-01 +79 2.590000e-09 5.541978e-01 +80 2.610000e-09 5.542025e-01 +81 2.630000e-09 5.541984e-01 +82 2.650000e-09 5.542017e-01 +83 2.670000e-09 5.542008e-01 +84 2.690000e-09 5.542258e-01 +85 2.710000e-09 5.541322e-01 +86 2.730000e-09 5.518485e-01 +87 2.750000e-09 5.380756e-01 +88 2.770000e-09 4.951084e-01 +89 2.790000e-09 4.104886e-01 +90 2.810000e-09 3.069976e-01 +91 2.830000e-09 2.206905e-01 +92 2.850000e-09 1.625594e-01 +93 2.870000e-09 1.316729e-01 +94 2.890000e-09 1.194356e-01 +95 2.910000e-09 1.158426e-01 +96 2.930000e-09 1.151376e-01 +97 2.950000e-09 1.149409e-01 +98 2.970000e-09 1.149521e-01 +99 2.990000e-09 1.149196e-01 +100 3.010000e-09 1.149554e-01 +101 3.030000e-09 1.149246e-01 +102 3.050000e-09 1.149563e-01 +103 3.070000e-09 1.149258e-01 +104 3.090000e-09 1.149571e-01 +105 3.110000e-09 1.149250e-01 +106 3.130000e-09 1.148554e-01 +107 3.150000e-09 1.144055e-01 +108 3.170000e-09 1.160558e-01 +109 3.190000e-09 1.366452e-01 +110 3.210000e-09 2.038028e-01 +111 3.230000e-09 3.138040e-01 +112 3.250000e-09 4.413524e-01 + +Index time v(8) +-------------------------------------------------------------------------------- +113 3.270000e-09 5.349395e-01 +114 3.290000e-09 5.606761e-01 +115 3.310000e-09 5.569114e-01 +116 3.330000e-09 5.562202e-01 +117 3.350000e-09 5.550393e-01 +118 3.370000e-09 5.545265e-01 +119 3.390000e-09 5.542612e-01 +120 3.410000e-09 5.542180e-01 +121 3.430000e-09 5.542000e-01 +122 3.450000e-09 5.542001e-01 +123 3.470000e-09 5.541998e-01 +124 3.490000e-09 5.542002e-01 +125 3.510000e-09 5.542006e-01 +126 3.530000e-09 5.541999e-01 +127 3.550000e-09 5.542004e-01 +128 3.570000e-09 5.542078e-01 +129 3.590000e-09 5.542334e-01 +130 3.610000e-09 5.537351e-01 +131 3.630000e-09 5.482916e-01 +132 3.650000e-09 5.245778e-01 +133 3.670000e-09 4.641302e-01 +134 3.690000e-09 3.659969e-01 +135 3.710000e-09 2.669401e-01 +136 3.730000e-09 1.924169e-01 +137 3.750000e-09 1.464090e-01 +138 3.770000e-09 1.248486e-01 +139 3.790000e-09 1.172631e-01 +140 3.810000e-09 1.154039e-01 +141 3.830000e-09 1.150264e-01 +142 3.850000e-09 1.149325e-01 +143 3.870000e-09 1.149447e-01 +144 3.890000e-09 1.149275e-01 +145 3.910000e-09 1.149499e-01 +146 3.930000e-09 1.149307e-01 +147 3.950000e-09 1.149506e-01 +148 3.970000e-09 1.149318e-01 +149 3.990000e-09 1.149522e-01 +150 4.010000e-09 1.149130e-01 +151 4.030000e-09 1.146998e-01 +152 4.050000e-09 1.144244e-01 +153 4.070000e-09 1.207589e-01 +154 4.090000e-09 1.605884e-01 +155 4.110000e-09 2.482521e-01 +156 4.130000e-09 3.702888e-01 +157 4.150000e-09 4.910555e-01 +158 4.170000e-09 5.536382e-01 +159 4.190000e-09 5.591035e-01 +160 4.210000e-09 5.566311e-01 +161 4.230000e-09 5.556160e-01 +162 4.250000e-09 5.547671e-01 +163 4.270000e-09 5.543790e-01 +164 4.290000e-09 5.542225e-01 +165 4.310000e-09 5.542175e-01 +166 4.330000e-09 5.541894e-01 +167 4.350000e-09 5.542097e-01 +168 4.370000e-09 5.541904e-01 +169 4.390000e-09 5.542097e-01 +170 4.410000e-09 5.541913e-01 + +Index time v(8) +-------------------------------------------------------------------------------- +171 4.430000e-09 5.542087e-01 +172 4.450000e-09 5.541931e-01 +173 4.470000e-09 5.542283e-01 +174 4.490000e-09 5.541733e-01 +175 4.510000e-09 5.524985e-01 +176 4.530000e-09 5.410664e-01 +177 4.550000e-09 5.030024e-01 +178 4.570000e-09 4.235879e-01 +179 4.590000e-09 3.200091e-01 +180 4.610000e-09 2.303519e-01 +181 4.630000e-09 1.684996e-01 +182 4.650000e-09 1.343909e-01 +183 4.670000e-09 1.203751e-01 +184 4.690000e-09 1.160546e-01 +185 4.710000e-09 1.151850e-01 +186 4.730000e-09 1.149496e-01 +187 4.750000e-09 1.149523e-01 +188 4.770000e-09 1.149197e-01 +189 4.790000e-09 1.149545e-01 +190 4.810000e-09 1.149251e-01 +191 4.830000e-09 1.149557e-01 +192 4.850000e-09 1.149263e-01 +193 4.870000e-09 1.149564e-01 +194 4.890000e-09 1.149272e-01 +195 4.910000e-09 1.148833e-01 +196 4.930000e-09 1.144651e-01 +197 4.950000e-09 1.153822e-01 +198 4.970000e-09 1.315176e-01 +199 4.990000e-09 1.923424e-01 +200 5.000000e-09 2.420233e-01 + + + + diff --git a/tests/polezero/Makefile.am b/tests/polezero/Makefile.am new file mode 100644 index 000000000..9a29ff8ab --- /dev/null +++ b/tests/polezero/Makefile.am @@ -0,0 +1,14 @@ +## Process this file with automake to produce Makefile.in + +TESTS = \ + filt_multistage.cir \ + filt_rc.cir \ + filt_bridge_t.cir + +TESTS_ENVIRONMENT = $(SHELL) $(srcdir)/../check.sh $(top_builddir)/src/ngspice + +EXTRA_DIST = \ + $(TESTS) \ + $(TESTS:.cir=.out) + +MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/polezero/filt_bridge_t.cir b/tests/polezero/filt_bridge_t.cir new file mode 100644 index 000000000..fd2f40aa1 --- /dev/null +++ b/tests/polezero/filt_bridge_t.cir @@ -0,0 +1,12 @@ +BRIDGE-T FILTER +V1 1 0 12 AC 1 +C1 1 2 1U +C2 2 3 1U +R3 2 0 1K +R4 1 3 1K +* +.OP +.PZ 1 0 3 0 VOL PZ +.PRINT PZ ALL +* +.END diff --git a/tests/polezero/filt_bridge_t.out b/tests/polezero/filt_bridge_t.out new file mode 100644 index 000000000..1c3603032 --- /dev/null +++ b/tests/polezero/filt_bridge_t.out @@ -0,0 +1,75 @@ + +No. of Data Rows : 1 + +No. of Data Rows : 1 + +Circuit: BRIDGE-T FILTER + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 + Node Voltage + ---- ------- + ---- ------- + V(3) 1.200000e+01 + V(2) 0.000000e+00 + V(1) 1.200000e+01 + + Source Current + ------ ------- + + v1#branch 0.000000e+00 + + Capacitor models (Fixed capacitor) + model C + + cj 0 + cjsw 0 + defw 1e-05 + narrow 0 + + Resistor models (Simple linear resistor) + model R + + rsh 0 + narrow 0 + short 0 + tc1 0 + tc2 0 + defw 1e-05 + + Capacitor: Fixed capacitor + device c2 c1 + model C C +capacitance 1e-06 1e-06 + i 0 0 + p 0 0 + + Resistor: Simple linear resistor + device r4 r3 + model R R + resistance 1000 1000 + ac 0 0 + i 0 0 + p 0 0 + + Vsource: Independent voltage source + device v1 + dc 12 + acmag 1 + i 0 + p -0 + + BRIDGE-T FILTER +-------------------------------------------------------------------------------- +Index pole(1) pole(2) +-------------------------------------------------------------------------------- +0 -2.618034e+03, 0.000000e+00 -3.819660e+02, 0.000000e+00 + + BRIDGE-T FILTER +-------------------------------------------------------------------------------- +Index zero(1) zero(2) +-------------------------------------------------------------------------------- +0 -1.000000e+03, 0.000000e+00 -1.000000e+03, 0.000000e+00 + + + + diff --git a/tests/polezero/filt_multistage.cir b/tests/polezero/filt_multistage.cir new file mode 100644 index 000000000..3f262fe5e --- /dev/null +++ b/tests/polezero/filt_multistage.cir @@ -0,0 +1,13 @@ +Multistage filter +v1 1 0 0 ac 1.0 +r1 1 2 1k +c1 2 0 10p +e2 3 0 2 0 10 +r2 3 4 1k +c2 4 0 1.25p +e3 5 0 4 0 10 +r3 5 6 1k +c3 6 0 .02p +.pz 1 0 6 0 vol pz +.print pz all +.end diff --git a/tests/polezero/filt_multistage.out b/tests/polezero/filt_multistage.out new file mode 100644 index 000000000..c62b0970c --- /dev/null +++ b/tests/polezero/filt_multistage.out @@ -0,0 +1,21 @@ + +No. of Data Rows : 1 + +Circuit: Multistage filter + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 + Multistage filter +-------------------------------------------------------------------------------- +Index pole(1) pole(2) +-------------------------------------------------------------------------------- +0 -5.000000e+10, 0.000000e+00 -8.000000e+08, 0.000000e+00 + + Multistage filter +-------------------------------------------------------------------------------- +Index pole(3) +-------------------------------------------------------------------------------- +0 -1.000000e+08, 0.000000e+00 + + + + diff --git a/tests/polezero/filt_rc.cir b/tests/polezero/filt_rc.cir new file mode 100644 index 000000000..c59ac16b4 --- /dev/null +++ b/tests/polezero/filt_rc.cir @@ -0,0 +1,7 @@ +RC filter +v1 1 0 0 ac 1.0 +r1 1 2 1k +c1 2 0 10p +.pz 1 0 2 0 vol pz +.print pz all +.end diff --git a/tests/polezero/filt_rc.out b/tests/polezero/filt_rc.out new file mode 100644 index 000000000..9c8df0aee --- /dev/null +++ b/tests/polezero/filt_rc.out @@ -0,0 +1,15 @@ + +No. of Data Rows : 1 + +Circuit: RC filter + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 + RC filter +-------------------------------------------------------------------------------- +Index all +-------------------------------------------------------------------------------- +0 -1.000000e+08, 0.000000e+00 + + + + diff --git a/tests/resistance/Makefile.am b/tests/resistance/Makefile.am new file mode 100644 index 000000000..6eb7647fc --- /dev/null +++ b/tests/resistance/Makefile.am @@ -0,0 +1,14 @@ +## Process this file with automake to produce Makefile.in + +TESTS = \ + res_array.cir \ + res_simple.cir \ + res_partition.cir + +TESTS_ENVIRONMENT = $(SHELL) $(srcdir)/../check.sh $(top_builddir)/src/ngspice + +EXTRA_DIST = \ + $(TESTS) \ + $(TESTS:.cir=.out) + +MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/resistance/res_array.cir b/tests/resistance/res_array.cir new file mode 100644 index 000000000..522b75a9d --- /dev/null +++ b/tests/resistance/res_array.cir @@ -0,0 +1,27 @@ +A paralled resistor array + +Vin 1 0 DC 1 SIN (0 1 100MEG 1NS 0.0) AC 1 + +VR1 1 2 DC 0 +R1 2 0 10K + +VR2 1 3 DC 0 +R2 3 0 10K ac=5K + +VR3 1 4 DC 0 +R3 4 0 rmodel1 L=11u W=2u ac=2.5k + +VR4 1 5 DC 0 +R4 5 0 10K ac=5k m=2 +.model rmodel1 R RSH = 1000 NARROW = 1u + +VR5 1 6 DC 0 +R5 6 0 10 ac=5 scale=1K + +.OP +.TRAN 1ns 10ns +.AC DEC 100 1MEG 100MEG +.PRINT TRAN I(VR1), I(VR2), I(VR3), I(VR4),I(VR5) +.PRINT AC I(VR1), I(VR2), I(VR3), I(VR4),I(VR5) + +.END diff --git a/tests/resistance/res_array.out b/tests/resistance/res_array.out new file mode 100644 index 000000000..237bee010 --- /dev/null +++ b/tests/resistance/res_array.out @@ -0,0 +1,1303 @@ + +No. of Data Rows : 201 + +No. of Data Rows : 1 + +Circuit: A paralled resistor array + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 + +Initial Transient Solution +-------------------------- + +Node Voltage +---- ------- +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +vr5#branch 0 +vr4#branch 0 +vr3#branch 0 +vr2#branch 0 +vr1#branch 0 +vin#branch 0 + + +No. of Data Rows : 60 + Node Voltage + ---- ------- + ---- ------- + V(6) 1.000000e+00 + V(5) 1.000000e+00 + V(4) 1.000000e+00 + V(3) 1.000000e+00 + V(2) 1.000000e+00 + V(1) 1.000000e+00 + + Source Current + ------ ------- + + vin#branch -5.90909e-04 + vr1#branch 1.000000e-04 + vr2#branch 1.000000e-04 + vr3#branch 9.090909e-05 + vr4#branch 2.000000e-04 + vr5#branch 1.000000e-04 + + Resistor models (Simple linear resistor) + model rmodel1 R + + rsh 1000 0 + narrow 1e-06 0 + short 0 0 + tc1 0 0 + tc2 0 0 + defw 1e-05 1e-05 + + Resistor: Simple linear resistor + device r3 r5 r4 + model rmodel1 R R + resistance 11000 10 10000 + ac 2500 5 5000 + i -5.3435e-05 -5.87785e-05 -0.000117557 + p 3.14083e-05 3.45492e-05 6.90983e-05 + + Resistor: Simple linear resistor + device r2 r1 + model R R + resistance 10000 10000 + ac 5000 0 + i -5.87785e-05 -5.87785e-05 + p 3.45492e-05 3.45492e-05 + + Vsource: Independent voltage source + device vr5 vr4 vr3 + dc 0 0 0 + acmag 0 0 0 + i -5.87785e-05 -0.000117557 -5.3435e-05 + p 0 0 0 + + Vsource: Independent voltage source + device vr2 vr1 vin + dc 0 0 1 + acmag 0 0 1 + i -5.87785e-05 -5.87785e-05 0.000347328 + p 0 0 0.000204154 + + A paralled resistor array +-------------------------------------------------------------------------------- +Index time vr1#branch vr2#branch vr3#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 +1 5.000000e-13 0.000000e+00 0.000000e+00 0.000000e+00 +2 1.000000e-12 0.000000e+00 0.000000e+00 0.000000e+00 +3 2.000000e-12 0.000000e+00 0.000000e+00 0.000000e+00 +4 4.000000e-12 0.000000e+00 0.000000e+00 0.000000e+00 +5 8.000000e-12 0.000000e+00 0.000000e+00 0.000000e+00 +6 1.600000e-11 0.000000e+00 0.000000e+00 0.000000e+00 +7 3.200000e-11 0.000000e+00 0.000000e+00 0.000000e+00 +8 6.400000e-11 0.000000e+00 0.000000e+00 0.000000e+00 +9 1.280000e-10 0.000000e+00 0.000000e+00 0.000000e+00 +10 2.560000e-10 0.000000e+00 0.000000e+00 0.000000e+00 +11 4.560000e-10 0.000000e+00 0.000000e+00 0.000000e+00 +12 6.560000e-10 0.000000e+00 0.000000e+00 0.000000e+00 +13 8.560000e-10 0.000000e+00 0.000000e+00 0.000000e+00 +14 1.056000e-09 3.517858e-06 3.517858e-06 3.198053e-06 +15 1.256000e-09 1.601568e-05 1.601568e-05 1.455971e-05 +16 1.456000e-09 2.826093e-05 2.826093e-05 2.569176e-05 +17 1.656000e-09 4.006049e-05 4.006049e-05 3.641863e-05 +18 1.856000e-09 5.122827e-05 5.122827e-05 4.657116e-05 +19 2.056000e-09 6.158815e-05 6.158815e-05 5.598923e-05 +20 2.256000e-09 7.097675e-05 7.097675e-05 6.452432e-05 +21 2.456000e-09 7.924600e-05 7.924600e-05 7.204182e-05 +22 2.656000e-09 8.626549e-05 8.626549e-05 7.842318e-05 +23 2.856000e-09 9.192453e-05 9.192453e-05 8.356776e-05 +24 3.056000e-09 9.613386e-05 9.613386e-05 8.739442e-05 +25 3.256000e-09 9.882711e-05 9.882711e-05 8.984282e-05 +26 3.456000e-09 9.996179e-05 9.996179e-05 9.087435e-05 +27 3.656000e-09 9.952001e-05 9.952001e-05 9.047274e-05 +28 3.856000e-09 9.750874e-05 9.750874e-05 8.864431e-05 +29 4.056000e-09 9.395971e-05 9.395971e-05 8.541792e-05 +30 4.256000e-09 8.892887e-05 8.892887e-05 8.084443e-05 +31 4.456000e-09 8.249557e-05 8.249557e-05 7.499597e-05 +32 4.656000e-09 7.476127e-05 7.476127e-05 6.796479e-05 +33 4.856000e-09 6.584793e-05 6.584793e-05 5.986176e-05 +34 5.056000e-09 5.589614e-05 5.589614e-05 5.081467e-05 +35 5.256000e-09 4.506283e-05 4.506283e-05 4.096621e-05 +36 5.456000e-09 3.351885e-05 3.351885e-05 3.047168e-05 +37 5.656000e-09 2.144626e-05 2.144626e-05 1.949660e-05 +38 5.856000e-09 9.035447e-06 9.035447e-06 8.214043e-06 +39 6.056000e-09 -3.517858e-06 -3.517858e-06 -3.198053e-06 +40 6.256000e-09 -1.601568e-05 -1.601568e-05 -1.455971e-05 +41 6.456000e-09 -2.826093e-05 -2.826093e-05 -2.569176e-05 +42 6.656000e-09 -4.006049e-05 -4.006049e-05 -3.641863e-05 +43 6.856000e-09 -5.122827e-05 -5.122827e-05 -4.657116e-05 +44 7.056000e-09 -6.158815e-05 -6.158815e-05 -5.598923e-05 +45 7.256000e-09 -7.097675e-05 -7.097675e-05 -6.452432e-05 +46 7.456000e-09 -7.924600e-05 -7.924600e-05 -7.204182e-05 +47 7.656000e-09 -8.626549e-05 -8.626549e-05 -7.842318e-05 +48 7.856000e-09 -9.192453e-05 -9.192453e-05 -8.356776e-05 +49 8.056000e-09 -9.613386e-05 -9.613386e-05 -8.739442e-05 +50 8.256000e-09 -9.882711e-05 -9.882711e-05 -8.984282e-05 +51 8.456000e-09 -9.996179e-05 -9.996179e-05 -9.087435e-05 +52 8.656000e-09 -9.952001e-05 -9.952001e-05 -9.047274e-05 +53 8.856000e-09 -9.750874e-05 -9.750874e-05 -8.864431e-05 +54 9.056000e-09 -9.395971e-05 -9.395971e-05 -8.541792e-05 + +Index time vr1#branch vr2#branch vr3#branch +-------------------------------------------------------------------------------- +55 9.256000e-09 -8.892887e-05 -8.892887e-05 -8.084443e-05 +56 9.456000e-09 -8.249557e-05 -8.249557e-05 -7.499597e-05 +57 9.656000e-09 -7.476127e-05 -7.476127e-05 -6.796479e-05 +58 9.856000e-09 -6.584793e-05 -6.584793e-05 -5.986176e-05 +59 1.000000e-08 -5.877853e-05 -5.877853e-05 -5.343502e-05 + + A paralled resistor array +-------------------------------------------------------------------------------- +Index time vr4#branch vr5#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 0.000000e+00 0.000000e+00 +1 5.000000e-13 0.000000e+00 0.000000e+00 +2 1.000000e-12 0.000000e+00 0.000000e+00 +3 2.000000e-12 0.000000e+00 0.000000e+00 +4 4.000000e-12 0.000000e+00 0.000000e+00 +5 8.000000e-12 0.000000e+00 0.000000e+00 +6 1.600000e-11 0.000000e+00 0.000000e+00 +7 3.200000e-11 0.000000e+00 0.000000e+00 +8 6.400000e-11 0.000000e+00 0.000000e+00 +9 1.280000e-10 0.000000e+00 0.000000e+00 +10 2.560000e-10 0.000000e+00 0.000000e+00 +11 4.560000e-10 0.000000e+00 0.000000e+00 +12 6.560000e-10 0.000000e+00 0.000000e+00 +13 8.560000e-10 0.000000e+00 0.000000e+00 +14 1.056000e-09 7.035716e-06 3.517858e-06 +15 1.256000e-09 3.203137e-05 1.601568e-05 +16 1.456000e-09 5.652187e-05 2.826093e-05 +17 1.656000e-09 8.012098e-05 4.006049e-05 +18 1.856000e-09 1.024565e-04 5.122827e-05 +19 2.056000e-09 1.231763e-04 6.158815e-05 +20 2.256000e-09 1.419535e-04 7.097675e-05 +21 2.456000e-09 1.584920e-04 7.924600e-05 +22 2.656000e-09 1.725310e-04 8.626549e-05 +23 2.856000e-09 1.838491e-04 9.192453e-05 +24 3.056000e-09 1.922677e-04 9.613386e-05 +25 3.256000e-09 1.976542e-04 9.882711e-05 +26 3.456000e-09 1.999236e-04 9.996179e-05 +27 3.656000e-09 1.990400e-04 9.952001e-05 +28 3.856000e-09 1.950175e-04 9.750874e-05 +29 4.056000e-09 1.879194e-04 9.395971e-05 +30 4.256000e-09 1.778577e-04 8.892887e-05 +31 4.456000e-09 1.649911e-04 8.249557e-05 +32 4.656000e-09 1.495225e-04 7.476127e-05 +33 4.856000e-09 1.316959e-04 6.584793e-05 +34 5.056000e-09 1.117923e-04 5.589614e-05 +35 5.256000e-09 9.012565e-05 4.506283e-05 +36 5.456000e-09 6.703770e-05 3.351885e-05 +37 5.656000e-09 4.289252e-05 2.144626e-05 +38 5.856000e-09 1.807089e-05 9.035447e-06 +39 6.056000e-09 -7.035716e-06 -3.517858e-06 +40 6.256000e-09 -3.203137e-05 -1.601568e-05 +41 6.456000e-09 -5.652187e-05 -2.826093e-05 +42 6.656000e-09 -8.012098e-05 -4.006049e-05 +43 6.856000e-09 -1.024565e-04 -5.122827e-05 +44 7.056000e-09 -1.231763e-04 -6.158815e-05 +45 7.256000e-09 -1.419535e-04 -7.097675e-05 +46 7.456000e-09 -1.584920e-04 -7.924600e-05 +47 7.656000e-09 -1.725310e-04 -8.626549e-05 +48 7.856000e-09 -1.838491e-04 -9.192453e-05 +49 8.056000e-09 -1.922677e-04 -9.613386e-05 +50 8.256000e-09 -1.976542e-04 -9.882711e-05 +51 8.456000e-09 -1.999236e-04 -9.996179e-05 +52 8.656000e-09 -1.990400e-04 -9.952001e-05 +53 8.856000e-09 -1.950175e-04 -9.750874e-05 +54 9.056000e-09 -1.879194e-04 -9.395971e-05 + +Index time vr4#branch vr5#branch +-------------------------------------------------------------------------------- +55 9.256000e-09 -1.778577e-04 -8.892887e-05 +56 9.456000e-09 -1.649911e-04 -8.249557e-05 +57 9.656000e-09 -1.495225e-04 -7.476127e-05 +58 9.856000e-09 -1.316959e-04 -6.584793e-05 +59 1.000000e-08 -1.175571e-04 -5.877853e-05 + + A paralled resistor array +-------------------------------------------------------------------------------- +Index frequency vr1#branch +-------------------------------------------------------------------------------- +0 1.000000e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +1 1.023293e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +2 1.047129e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +3 1.071519e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +4 1.096478e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +5 1.122018e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +6 1.148154e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +7 1.174898e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +8 1.202264e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +9 1.230269e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +10 1.258925e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +11 1.288250e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +12 1.318257e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +13 1.348963e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +14 1.380384e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +15 1.412538e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +16 1.445440e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +17 1.479108e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +18 1.513561e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +19 1.548817e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +20 1.584893e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +21 1.621810e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +22 1.659587e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +23 1.698244e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +24 1.737801e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +25 1.778279e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +26 1.819701e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +27 1.862087e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +28 1.905461e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +29 1.949845e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +30 1.995262e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +31 2.041738e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +32 2.089296e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +33 2.137962e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +34 2.187762e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +35 2.238721e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +36 2.290868e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +37 2.344229e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +38 2.398833e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +39 2.454709e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +40 2.511886e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +41 2.570396e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +42 2.630268e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +43 2.691535e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +44 2.754229e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +45 2.818383e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +46 2.884032e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +47 2.951209e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +48 3.019952e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +49 3.090295e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +50 3.162278e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +51 3.235937e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +52 3.311311e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +53 3.388442e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +54 3.467369e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 + +Index frequency vr1#branch +-------------------------------------------------------------------------------- +55 3.548134e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +56 3.630781e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +57 3.715352e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +58 3.801894e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +59 3.890451e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +60 3.981072e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +61 4.073803e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +62 4.168694e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +63 4.265795e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +64 4.365158e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +65 4.466836e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +66 4.570882e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +67 4.677351e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +68 4.786301e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +69 4.897788e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +70 5.011872e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +71 5.128614e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +72 5.248075e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +73 5.370318e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +74 5.495409e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +75 5.623413e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +76 5.754399e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +77 5.888437e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +78 6.025596e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +79 6.165950e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +80 6.309573e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +81 6.456542e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +82 6.606934e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +83 6.760830e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +84 6.918310e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +85 7.079458e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +86 7.244360e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +87 7.413102e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +88 7.585776e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +89 7.762471e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +90 7.943282e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +91 8.128305e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +92 8.317638e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +93 8.511380e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +94 8.709636e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +95 8.912509e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +96 9.120108e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +97 9.332543e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +98 9.549926e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +99 9.772372e+06, 0.000000e+00 1.000000e-04, 0.000000e+00 +100 1.000000e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +101 1.023293e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +102 1.047129e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +103 1.071519e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +104 1.096478e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +105 1.122018e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +106 1.148154e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +107 1.174898e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +108 1.202264e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +109 1.230269e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +110 1.258925e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +111 1.288250e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +112 1.318257e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 + +Index frequency vr1#branch +-------------------------------------------------------------------------------- +113 1.348963e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +114 1.380384e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +115 1.412538e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +116 1.445440e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +117 1.479108e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +118 1.513561e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +119 1.548817e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +120 1.584893e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +121 1.621810e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +122 1.659587e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +123 1.698244e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +124 1.737801e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +125 1.778279e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +126 1.819701e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +127 1.862087e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +128 1.905461e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +129 1.949845e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +130 1.995262e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +131 2.041738e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +132 2.089296e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +133 2.137962e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +134 2.187762e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +135 2.238721e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +136 2.290868e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +137 2.344229e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +138 2.398833e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +139 2.454709e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +140 2.511886e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +141 2.570396e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +142 2.630268e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +143 2.691535e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +144 2.754229e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +145 2.818383e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +146 2.884032e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +147 2.951209e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +148 3.019952e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +149 3.090295e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +150 3.162278e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +151 3.235937e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +152 3.311311e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +153 3.388442e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +154 3.467369e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +155 3.548134e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +156 3.630781e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +157 3.715352e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +158 3.801894e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +159 3.890451e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +160 3.981072e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +161 4.073803e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +162 4.168694e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +163 4.265795e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +164 4.365158e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +165 4.466836e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +166 4.570882e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +167 4.677351e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +168 4.786301e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +169 4.897788e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +170 5.011872e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 + +Index frequency vr1#branch +-------------------------------------------------------------------------------- +171 5.128614e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +172 5.248075e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +173 5.370318e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +174 5.495409e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +175 5.623413e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +176 5.754399e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +177 5.888437e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +178 6.025596e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +179 6.165950e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +180 6.309573e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +181 6.456542e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +182 6.606934e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +183 6.760830e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +184 6.918310e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +185 7.079458e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +186 7.244360e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +187 7.413102e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +188 7.585776e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +189 7.762471e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +190 7.943282e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +191 8.128305e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +192 8.317638e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +193 8.511380e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +194 8.709636e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +195 8.912509e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +196 9.120108e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +197 9.332543e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +198 9.549926e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +199 9.772372e+07, 0.000000e+00 1.000000e-04, 0.000000e+00 +200 1.000000e+08, 0.000000e+00 1.000000e-04, 0.000000e+00 + + A paralled resistor array +-------------------------------------------------------------------------------- +Index frequency vr2#branch +-------------------------------------------------------------------------------- +0 1.000000e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +1 1.023293e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +2 1.047129e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +3 1.071519e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +4 1.096478e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +5 1.122018e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +6 1.148154e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +7 1.174898e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +8 1.202264e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +9 1.230269e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +10 1.258925e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +11 1.288250e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +12 1.318257e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +13 1.348963e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +14 1.380384e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +15 1.412538e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +16 1.445440e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +17 1.479108e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +18 1.513561e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +19 1.548817e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +20 1.584893e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +21 1.621810e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +22 1.659587e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +23 1.698244e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +24 1.737801e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +25 1.778279e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +26 1.819701e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +27 1.862087e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +28 1.905461e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +29 1.949845e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +30 1.995262e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +31 2.041738e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +32 2.089296e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +33 2.137962e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +34 2.187762e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +35 2.238721e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +36 2.290868e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +37 2.344229e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +38 2.398833e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +39 2.454709e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +40 2.511886e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +41 2.570396e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +42 2.630268e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +43 2.691535e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +44 2.754229e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +45 2.818383e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +46 2.884032e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +47 2.951209e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +48 3.019952e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +49 3.090295e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +50 3.162278e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +51 3.235937e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +52 3.311311e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +53 3.388442e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +54 3.467369e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 + +Index frequency vr2#branch +-------------------------------------------------------------------------------- +55 3.548134e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +56 3.630781e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +57 3.715352e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +58 3.801894e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +59 3.890451e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +60 3.981072e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +61 4.073803e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +62 4.168694e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +63 4.265795e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +64 4.365158e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +65 4.466836e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +66 4.570882e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +67 4.677351e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +68 4.786301e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +69 4.897788e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +70 5.011872e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +71 5.128614e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +72 5.248075e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +73 5.370318e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +74 5.495409e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +75 5.623413e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +76 5.754399e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +77 5.888437e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +78 6.025596e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +79 6.165950e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +80 6.309573e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +81 6.456542e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +82 6.606934e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +83 6.760830e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +84 6.918310e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +85 7.079458e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +86 7.244360e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +87 7.413102e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +88 7.585776e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +89 7.762471e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +90 7.943282e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +91 8.128305e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +92 8.317638e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +93 8.511380e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +94 8.709636e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +95 8.912509e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +96 9.120108e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +97 9.332543e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +98 9.549926e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +99 9.772372e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +100 1.000000e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +101 1.023293e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +102 1.047129e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +103 1.071519e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +104 1.096478e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +105 1.122018e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +106 1.148154e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +107 1.174898e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +108 1.202264e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +109 1.230269e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +110 1.258925e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +111 1.288250e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +112 1.318257e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 + +Index frequency vr2#branch +-------------------------------------------------------------------------------- +113 1.348963e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +114 1.380384e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +115 1.412538e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +116 1.445440e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +117 1.479108e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +118 1.513561e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +119 1.548817e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +120 1.584893e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +121 1.621810e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +122 1.659587e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +123 1.698244e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +124 1.737801e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +125 1.778279e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +126 1.819701e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +127 1.862087e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +128 1.905461e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +129 1.949845e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +130 1.995262e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +131 2.041738e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +132 2.089296e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +133 2.137962e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +134 2.187762e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +135 2.238721e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +136 2.290868e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +137 2.344229e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +138 2.398833e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +139 2.454709e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +140 2.511886e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +141 2.570396e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +142 2.630268e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +143 2.691535e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +144 2.754229e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +145 2.818383e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +146 2.884032e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +147 2.951209e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +148 3.019952e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +149 3.090295e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +150 3.162278e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +151 3.235937e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +152 3.311311e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +153 3.388442e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +154 3.467369e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +155 3.548134e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +156 3.630781e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +157 3.715352e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +158 3.801894e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +159 3.890451e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +160 3.981072e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +161 4.073803e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +162 4.168694e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +163 4.265795e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +164 4.365158e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +165 4.466836e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +166 4.570882e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +167 4.677351e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +168 4.786301e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +169 4.897788e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +170 5.011872e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 + +Index frequency vr2#branch +-------------------------------------------------------------------------------- +171 5.128614e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +172 5.248075e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +173 5.370318e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +174 5.495409e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +175 5.623413e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +176 5.754399e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +177 5.888437e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +178 6.025596e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +179 6.165950e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +180 6.309573e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +181 6.456542e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +182 6.606934e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +183 6.760830e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +184 6.918310e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +185 7.079458e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +186 7.244360e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +187 7.413102e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +188 7.585776e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +189 7.762471e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +190 7.943282e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +191 8.128305e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +192 8.317638e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +193 8.511380e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +194 8.709636e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +195 8.912509e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +196 9.120108e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +197 9.332543e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +198 9.549926e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +199 9.772372e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +200 1.000000e+08, 0.000000e+00 2.000000e-04, 0.000000e+00 + + A paralled resistor array +-------------------------------------------------------------------------------- +Index frequency vr3#branch +-------------------------------------------------------------------------------- +0 1.000000e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +1 1.023293e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +2 1.047129e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +3 1.071519e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +4 1.096478e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +5 1.122018e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +6 1.148154e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +7 1.174898e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +8 1.202264e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +9 1.230269e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +10 1.258925e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +11 1.288250e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +12 1.318257e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +13 1.348963e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +14 1.380384e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +15 1.412538e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +16 1.445440e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +17 1.479108e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +18 1.513561e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +19 1.548817e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +20 1.584893e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +21 1.621810e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +22 1.659587e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +23 1.698244e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +24 1.737801e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +25 1.778279e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +26 1.819701e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +27 1.862087e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +28 1.905461e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +29 1.949845e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +30 1.995262e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +31 2.041738e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +32 2.089296e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +33 2.137962e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +34 2.187762e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +35 2.238721e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +36 2.290868e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +37 2.344229e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +38 2.398833e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +39 2.454709e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +40 2.511886e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +41 2.570396e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +42 2.630268e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +43 2.691535e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +44 2.754229e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +45 2.818383e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +46 2.884032e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +47 2.951209e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +48 3.019952e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +49 3.090295e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +50 3.162278e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +51 3.235937e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +52 3.311311e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +53 3.388442e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +54 3.467369e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 + +Index frequency vr3#branch +-------------------------------------------------------------------------------- +55 3.548134e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +56 3.630781e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +57 3.715352e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +58 3.801894e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +59 3.890451e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +60 3.981072e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +61 4.073803e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +62 4.168694e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +63 4.265795e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +64 4.365158e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +65 4.466836e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +66 4.570882e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +67 4.677351e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +68 4.786301e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +69 4.897788e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +70 5.011872e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +71 5.128614e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +72 5.248075e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +73 5.370318e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +74 5.495409e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +75 5.623413e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +76 5.754399e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +77 5.888437e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +78 6.025596e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +79 6.165950e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +80 6.309573e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +81 6.456542e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +82 6.606934e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +83 6.760830e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +84 6.918310e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +85 7.079458e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +86 7.244360e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +87 7.413102e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +88 7.585776e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +89 7.762471e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +90 7.943282e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +91 8.128305e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +92 8.317638e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +93 8.511380e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +94 8.709636e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +95 8.912509e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +96 9.120108e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +97 9.332543e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +98 9.549926e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +99 9.772372e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +100 1.000000e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +101 1.023293e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +102 1.047129e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +103 1.071519e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +104 1.096478e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +105 1.122018e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +106 1.148154e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +107 1.174898e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +108 1.202264e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +109 1.230269e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +110 1.258925e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +111 1.288250e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +112 1.318257e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 + +Index frequency vr3#branch +-------------------------------------------------------------------------------- +113 1.348963e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +114 1.380384e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +115 1.412538e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +116 1.445440e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +117 1.479108e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +118 1.513561e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +119 1.548817e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +120 1.584893e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +121 1.621810e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +122 1.659587e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +123 1.698244e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +124 1.737801e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +125 1.778279e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +126 1.819701e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +127 1.862087e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +128 1.905461e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +129 1.949845e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +130 1.995262e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +131 2.041738e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +132 2.089296e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +133 2.137962e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +134 2.187762e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +135 2.238721e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +136 2.290868e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +137 2.344229e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +138 2.398833e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +139 2.454709e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +140 2.511886e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +141 2.570396e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +142 2.630268e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +143 2.691535e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +144 2.754229e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +145 2.818383e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +146 2.884032e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +147 2.951209e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +148 3.019952e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +149 3.090295e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +150 3.162278e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +151 3.235937e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +152 3.311311e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +153 3.388442e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +154 3.467369e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +155 3.548134e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +156 3.630781e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +157 3.715352e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +158 3.801894e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +159 3.890451e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +160 3.981072e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +161 4.073803e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +162 4.168694e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +163 4.265795e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +164 4.365158e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +165 4.466836e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +166 4.570882e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +167 4.677351e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +168 4.786301e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +169 4.897788e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +170 5.011872e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 + +Index frequency vr3#branch +-------------------------------------------------------------------------------- +171 5.128614e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +172 5.248075e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +173 5.370318e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +174 5.495409e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +175 5.623413e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +176 5.754399e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +177 5.888437e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +178 6.025596e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +179 6.165950e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +180 6.309573e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +181 6.456542e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +182 6.606934e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +183 6.760830e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +184 6.918310e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +185 7.079458e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +186 7.244360e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +187 7.413102e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +188 7.585776e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +189 7.762471e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +190 7.943282e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +191 8.128305e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +192 8.317638e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +193 8.511380e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +194 8.709636e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +195 8.912509e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +196 9.120108e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +197 9.332543e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +198 9.549926e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +199 9.772372e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +200 1.000000e+08, 0.000000e+00 4.000000e-04, 0.000000e+00 + + A paralled resistor array +-------------------------------------------------------------------------------- +Index frequency vr4#branch +-------------------------------------------------------------------------------- +0 1.000000e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +1 1.023293e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +2 1.047129e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +3 1.071519e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +4 1.096478e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +5 1.122018e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +6 1.148154e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +7 1.174898e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +8 1.202264e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +9 1.230269e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +10 1.258925e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +11 1.288250e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +12 1.318257e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +13 1.348963e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +14 1.380384e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +15 1.412538e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +16 1.445440e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +17 1.479108e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +18 1.513561e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +19 1.548817e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +20 1.584893e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +21 1.621810e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +22 1.659587e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +23 1.698244e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +24 1.737801e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +25 1.778279e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +26 1.819701e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +27 1.862087e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +28 1.905461e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +29 1.949845e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +30 1.995262e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +31 2.041738e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +32 2.089296e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +33 2.137962e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +34 2.187762e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +35 2.238721e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +36 2.290868e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +37 2.344229e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +38 2.398833e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +39 2.454709e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +40 2.511886e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +41 2.570396e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +42 2.630268e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +43 2.691535e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +44 2.754229e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +45 2.818383e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +46 2.884032e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +47 2.951209e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +48 3.019952e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +49 3.090295e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +50 3.162278e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +51 3.235937e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +52 3.311311e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +53 3.388442e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +54 3.467369e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 + +Index frequency vr4#branch +-------------------------------------------------------------------------------- +55 3.548134e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +56 3.630781e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +57 3.715352e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +58 3.801894e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +59 3.890451e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +60 3.981072e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +61 4.073803e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +62 4.168694e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +63 4.265795e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +64 4.365158e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +65 4.466836e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +66 4.570882e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +67 4.677351e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +68 4.786301e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +69 4.897788e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +70 5.011872e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +71 5.128614e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +72 5.248075e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +73 5.370318e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +74 5.495409e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +75 5.623413e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +76 5.754399e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +77 5.888437e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +78 6.025596e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +79 6.165950e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +80 6.309573e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +81 6.456542e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +82 6.606934e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +83 6.760830e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +84 6.918310e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +85 7.079458e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +86 7.244360e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +87 7.413102e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +88 7.585776e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +89 7.762471e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +90 7.943282e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +91 8.128305e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +92 8.317638e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +93 8.511380e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +94 8.709636e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +95 8.912509e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +96 9.120108e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +97 9.332543e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +98 9.549926e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +99 9.772372e+06, 0.000000e+00 4.000000e-04, 0.000000e+00 +100 1.000000e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +101 1.023293e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +102 1.047129e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +103 1.071519e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +104 1.096478e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +105 1.122018e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +106 1.148154e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +107 1.174898e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +108 1.202264e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +109 1.230269e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +110 1.258925e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +111 1.288250e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +112 1.318257e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 + +Index frequency vr4#branch +-------------------------------------------------------------------------------- +113 1.348963e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +114 1.380384e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +115 1.412538e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +116 1.445440e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +117 1.479108e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +118 1.513561e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +119 1.548817e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +120 1.584893e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +121 1.621810e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +122 1.659587e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +123 1.698244e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +124 1.737801e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +125 1.778279e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +126 1.819701e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +127 1.862087e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +128 1.905461e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +129 1.949845e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +130 1.995262e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +131 2.041738e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +132 2.089296e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +133 2.137962e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +134 2.187762e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +135 2.238721e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +136 2.290868e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +137 2.344229e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +138 2.398833e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +139 2.454709e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +140 2.511886e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +141 2.570396e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +142 2.630268e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +143 2.691535e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +144 2.754229e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +145 2.818383e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +146 2.884032e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +147 2.951209e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +148 3.019952e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +149 3.090295e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +150 3.162278e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +151 3.235937e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +152 3.311311e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +153 3.388442e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +154 3.467369e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +155 3.548134e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +156 3.630781e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +157 3.715352e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +158 3.801894e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +159 3.890451e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +160 3.981072e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +161 4.073803e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +162 4.168694e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +163 4.265795e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +164 4.365158e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +165 4.466836e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +166 4.570882e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +167 4.677351e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +168 4.786301e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +169 4.897788e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +170 5.011872e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 + +Index frequency vr4#branch +-------------------------------------------------------------------------------- +171 5.128614e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +172 5.248075e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +173 5.370318e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +174 5.495409e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +175 5.623413e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +176 5.754399e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +177 5.888437e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +178 6.025596e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +179 6.165950e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +180 6.309573e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +181 6.456542e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +182 6.606934e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +183 6.760830e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +184 6.918310e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +185 7.079458e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +186 7.244360e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +187 7.413102e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +188 7.585776e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +189 7.762471e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +190 7.943282e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +191 8.128305e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +192 8.317638e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +193 8.511380e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +194 8.709636e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +195 8.912509e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +196 9.120108e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +197 9.332543e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +198 9.549926e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +199 9.772372e+07, 0.000000e+00 4.000000e-04, 0.000000e+00 +200 1.000000e+08, 0.000000e+00 4.000000e-04, 0.000000e+00 + + A paralled resistor array +-------------------------------------------------------------------------------- +Index frequency vr5#branch +-------------------------------------------------------------------------------- +0 1.000000e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +1 1.023293e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +2 1.047129e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +3 1.071519e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +4 1.096478e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +5 1.122018e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +6 1.148154e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +7 1.174898e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +8 1.202264e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +9 1.230269e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +10 1.258925e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +11 1.288250e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +12 1.318257e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +13 1.348963e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +14 1.380384e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +15 1.412538e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +16 1.445440e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +17 1.479108e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +18 1.513561e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +19 1.548817e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +20 1.584893e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +21 1.621810e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +22 1.659587e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +23 1.698244e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +24 1.737801e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +25 1.778279e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +26 1.819701e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +27 1.862087e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +28 1.905461e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +29 1.949845e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +30 1.995262e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +31 2.041738e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +32 2.089296e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +33 2.137962e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +34 2.187762e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +35 2.238721e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +36 2.290868e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +37 2.344229e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +38 2.398833e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +39 2.454709e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +40 2.511886e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +41 2.570396e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +42 2.630268e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +43 2.691535e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +44 2.754229e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +45 2.818383e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +46 2.884032e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +47 2.951209e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +48 3.019952e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +49 3.090295e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +50 3.162278e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +51 3.235937e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +52 3.311311e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +53 3.388442e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +54 3.467369e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 + +Index frequency vr5#branch +-------------------------------------------------------------------------------- +55 3.548134e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +56 3.630781e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +57 3.715352e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +58 3.801894e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +59 3.890451e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +60 3.981072e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +61 4.073803e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +62 4.168694e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +63 4.265795e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +64 4.365158e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +65 4.466836e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +66 4.570882e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +67 4.677351e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +68 4.786301e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +69 4.897788e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +70 5.011872e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +71 5.128614e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +72 5.248075e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +73 5.370318e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +74 5.495409e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +75 5.623413e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +76 5.754399e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +77 5.888437e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +78 6.025596e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +79 6.165950e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +80 6.309573e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +81 6.456542e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +82 6.606934e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +83 6.760830e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +84 6.918310e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +85 7.079458e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +86 7.244360e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +87 7.413102e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +88 7.585776e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +89 7.762471e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +90 7.943282e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +91 8.128305e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +92 8.317638e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +93 8.511380e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +94 8.709636e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +95 8.912509e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +96 9.120108e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +97 9.332543e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +98 9.549926e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +99 9.772372e+06, 0.000000e+00 2.000000e-04, 0.000000e+00 +100 1.000000e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +101 1.023293e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +102 1.047129e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +103 1.071519e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +104 1.096478e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +105 1.122018e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +106 1.148154e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +107 1.174898e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +108 1.202264e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +109 1.230269e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +110 1.258925e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +111 1.288250e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +112 1.318257e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 + +Index frequency vr5#branch +-------------------------------------------------------------------------------- +113 1.348963e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +114 1.380384e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +115 1.412538e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +116 1.445440e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +117 1.479108e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +118 1.513561e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +119 1.548817e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +120 1.584893e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +121 1.621810e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +122 1.659587e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +123 1.698244e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +124 1.737801e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +125 1.778279e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +126 1.819701e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +127 1.862087e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +128 1.905461e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +129 1.949845e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +130 1.995262e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +131 2.041738e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +132 2.089296e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +133 2.137962e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +134 2.187762e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +135 2.238721e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +136 2.290868e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +137 2.344229e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +138 2.398833e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +139 2.454709e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +140 2.511886e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +141 2.570396e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +142 2.630268e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +143 2.691535e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +144 2.754229e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +145 2.818383e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +146 2.884032e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +147 2.951209e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +148 3.019952e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +149 3.090295e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +150 3.162278e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +151 3.235937e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +152 3.311311e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +153 3.388442e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +154 3.467369e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +155 3.548134e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +156 3.630781e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +157 3.715352e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +158 3.801894e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +159 3.890451e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +160 3.981072e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +161 4.073803e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +162 4.168694e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +163 4.265795e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +164 4.365158e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +165 4.466836e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +166 4.570882e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +167 4.677351e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +168 4.786301e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +169 4.897788e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +170 5.011872e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 + +Index frequency vr5#branch +-------------------------------------------------------------------------------- +171 5.128614e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +172 5.248075e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +173 5.370318e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +174 5.495409e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +175 5.623413e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +176 5.754399e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +177 5.888437e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +178 6.025596e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +179 6.165950e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +180 6.309573e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +181 6.456542e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +182 6.606934e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +183 6.760830e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +184 6.918310e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +185 7.079458e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +186 7.244360e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +187 7.413102e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +188 7.585776e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +189 7.762471e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +190 7.943282e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +191 8.128305e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +192 8.317638e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +193 8.511380e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +194 8.709636e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +195 8.912509e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +196 9.120108e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +197 9.332543e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +198 9.549926e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +199 9.772372e+07, 0.000000e+00 2.000000e-04, 0.000000e+00 +200 1.000000e+08, 0.000000e+00 2.000000e-04, 0.000000e+00 + + + + diff --git a/tests/resistance/res_partition.cir b/tests/resistance/res_partition.cir new file mode 100644 index 000000000..7a44accd4 --- /dev/null +++ b/tests/resistance/res_partition.cir @@ -0,0 +1,10 @@ +* Resistive partition with different ratios for AC/DC (Print V(2)) + +vin 1 0 DC 1V AC 1V +r1 1 2 5K +r2 2 0 5K ac=15k + +.OP +.AC DEC 10 1 10K +.print ac v(2) +.END diff --git a/tests/resistance/res_partition.out b/tests/resistance/res_partition.out new file mode 100644 index 000000000..6af45802c --- /dev/null +++ b/tests/resistance/res_partition.out @@ -0,0 +1,93 @@ + +No. of Data Rows : 41 + +No. of Data Rows : 1 + +Circuit: * Resistive partition with different ratios for AC/DC (Print V(2)) + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 + Node Voltage + ---- ------- + ---- ------- + V(2) 5.000000e-01 + V(1) 1.000000e+00 + + Source Current + ------ ------- + + vin#branch -1.00000e-04 + + Resistor models (Simple linear resistor) + model R + + rsh 0 + narrow 0 + short 0 + tc1 0 + tc2 0 + defw 1e-05 + + Resistor: Simple linear resistor + device r2 r1 + model R R + resistance 5000 5000 + ac 15000 0 + i 0.0001 0.0001 + p 5e-05 5e-05 + + Vsource: Independent voltage source + device vin + dc 1 + acmag 1 + i -0.0001 + p 0.0001 + + * Resistive partition with different ratios for AC/DC (Print V(2)) +-------------------------------------------------------------------------------- +Index frequency v(2) +-------------------------------------------------------------------------------- +0 1.000000e+00, 0.000000e+00 7.500000e-01, 0.000000e+00 +1 1.258925e+00, 0.000000e+00 7.500000e-01, 0.000000e+00 +2 1.584893e+00, 0.000000e+00 7.500000e-01, 0.000000e+00 +3 1.995262e+00, 0.000000e+00 7.500000e-01, 0.000000e+00 +4 2.511886e+00, 0.000000e+00 7.500000e-01, 0.000000e+00 +5 3.162278e+00, 0.000000e+00 7.500000e-01, 0.000000e+00 +6 3.981072e+00, 0.000000e+00 7.500000e-01, 0.000000e+00 +7 5.011872e+00, 0.000000e+00 7.500000e-01, 0.000000e+00 +8 6.309573e+00, 0.000000e+00 7.500000e-01, 0.000000e+00 +9 7.943282e+00, 0.000000e+00 7.500000e-01, 0.000000e+00 +10 1.000000e+01, 0.000000e+00 7.500000e-01, 0.000000e+00 +11 1.258925e+01, 0.000000e+00 7.500000e-01, 0.000000e+00 +12 1.584893e+01, 0.000000e+00 7.500000e-01, 0.000000e+00 +13 1.995262e+01, 0.000000e+00 7.500000e-01, 0.000000e+00 +14 2.511886e+01, 0.000000e+00 7.500000e-01, 0.000000e+00 +15 3.162278e+01, 0.000000e+00 7.500000e-01, 0.000000e+00 +16 3.981072e+01, 0.000000e+00 7.500000e-01, 0.000000e+00 +17 5.011872e+01, 0.000000e+00 7.500000e-01, 0.000000e+00 +18 6.309573e+01, 0.000000e+00 7.500000e-01, 0.000000e+00 +19 7.943282e+01, 0.000000e+00 7.500000e-01, 0.000000e+00 +20 1.000000e+02, 0.000000e+00 7.500000e-01, 0.000000e+00 +21 1.258925e+02, 0.000000e+00 7.500000e-01, 0.000000e+00 +22 1.584893e+02, 0.000000e+00 7.500000e-01, 0.000000e+00 +23 1.995262e+02, 0.000000e+00 7.500000e-01, 0.000000e+00 +24 2.511886e+02, 0.000000e+00 7.500000e-01, 0.000000e+00 +25 3.162278e+02, 0.000000e+00 7.500000e-01, 0.000000e+00 +26 3.981072e+02, 0.000000e+00 7.500000e-01, 0.000000e+00 +27 5.011872e+02, 0.000000e+00 7.500000e-01, 0.000000e+00 +28 6.309573e+02, 0.000000e+00 7.500000e-01, 0.000000e+00 +29 7.943282e+02, 0.000000e+00 7.500000e-01, 0.000000e+00 +30 1.000000e+03, 0.000000e+00 7.500000e-01, 0.000000e+00 +31 1.258925e+03, 0.000000e+00 7.500000e-01, 0.000000e+00 +32 1.584893e+03, 0.000000e+00 7.500000e-01, 0.000000e+00 +33 1.995262e+03, 0.000000e+00 7.500000e-01, 0.000000e+00 +34 2.511886e+03, 0.000000e+00 7.500000e-01, 0.000000e+00 +35 3.162278e+03, 0.000000e+00 7.500000e-01, 0.000000e+00 +36 3.981072e+03, 0.000000e+00 7.500000e-01, 0.000000e+00 +37 5.011872e+03, 0.000000e+00 7.500000e-01, 0.000000e+00 +38 6.309573e+03, 0.000000e+00 7.500000e-01, 0.000000e+00 +39 7.943282e+03, 0.000000e+00 7.500000e-01, 0.000000e+00 +40 1.000000e+04, 0.000000e+00 7.500000e-01, 0.000000e+00 + + + + diff --git a/tests/resistance/res_simple.cir b/tests/resistance/res_simple.cir new file mode 100644 index 000000000..5c8c2783a --- /dev/null +++ b/tests/resistance/res_simple.cir @@ -0,0 +1,9 @@ +A simple resistor with a voltage source + +R1 1 0 10k +V1 1 0 DC 1 + +.TRAN 1ns 6ns +.PRINT TRAN I(V1) + +.END diff --git a/tests/resistance/res_simple.out b/tests/resistance/res_simple.out new file mode 100644 index 000000000..2d8bd3fe6 --- /dev/null +++ b/tests/resistance/res_simple.out @@ -0,0 +1,86 @@ + +Circuit: A simple resistor with a voltage source + +Doing analysis at TEMP = 300.150000 and TNOM = 300.150000 + +Initial Transient Solution +-------------------------- + +Node Voltage +---- ------- +1 1 +v1#branch -0.0001 + + +No. of Data Rows : 60 + A simple resistor with a voltage source +-------------------------------------------------------------------------------- +Index time v1#branch +-------------------------------------------------------------------------------- +0 0.000000e+00 -1.000000e-04 +1 3.000000e-13 -1.000000e-04 +2 6.000000e-13 -1.000000e-04 +3 1.200000e-12 -1.000000e-04 +4 2.400000e-12 -1.000000e-04 +5 4.800000e-12 -1.000000e-04 +6 9.600000e-12 -1.000000e-04 +7 1.920000e-11 -1.000000e-04 +8 3.840000e-11 -1.000000e-04 +9 7.680000e-11 -1.000000e-04 +10 1.536000e-10 -1.000000e-04 +11 2.736000e-10 -1.000000e-04 +12 3.936000e-10 -1.000000e-04 +13 5.136000e-10 -1.000000e-04 +14 6.336000e-10 -1.000000e-04 +15 7.536000e-10 -1.000000e-04 +16 8.736000e-10 -1.000000e-04 +17 9.936000e-10 -1.000000e-04 +18 1.113600e-09 -1.000000e-04 +19 1.233600e-09 -1.000000e-04 +20 1.353600e-09 -1.000000e-04 +21 1.473600e-09 -1.000000e-04 +22 1.593600e-09 -1.000000e-04 +23 1.713600e-09 -1.000000e-04 +24 1.833600e-09 -1.000000e-04 +25 1.953600e-09 -1.000000e-04 +26 2.073600e-09 -1.000000e-04 +27 2.193600e-09 -1.000000e-04 +28 2.313600e-09 -1.000000e-04 +29 2.433600e-09 -1.000000e-04 +30 2.553600e-09 -1.000000e-04 +31 2.673600e-09 -1.000000e-04 +32 2.793600e-09 -1.000000e-04 +33 2.913600e-09 -1.000000e-04 +34 3.033600e-09 -1.000000e-04 +35 3.153600e-09 -1.000000e-04 +36 3.273600e-09 -1.000000e-04 +37 3.393600e-09 -1.000000e-04 +38 3.513600e-09 -1.000000e-04 +39 3.633600e-09 -1.000000e-04 +40 3.753600e-09 -1.000000e-04 +41 3.873600e-09 -1.000000e-04 +42 3.993600e-09 -1.000000e-04 +43 4.113600e-09 -1.000000e-04 +44 4.233600e-09 -1.000000e-04 +45 4.353600e-09 -1.000000e-04 +46 4.473600e-09 -1.000000e-04 +47 4.593600e-09 -1.000000e-04 +48 4.713600e-09 -1.000000e-04 +49 4.833600e-09 -1.000000e-04 +50 4.953600e-09 -1.000000e-04 +51 5.073600e-09 -1.000000e-04 +52 5.193600e-09 -1.000000e-04 +53 5.313600e-09 -1.000000e-04 +54 5.433600e-09 -1.000000e-04 + +Index time v1#branch +-------------------------------------------------------------------------------- +55 5.553600e-09 -1.000000e-04 +56 5.673600e-09 -1.000000e-04 +57 5.793600e-09 -1.000000e-04 +58 5.913600e-09 -1.000000e-04 +59 6.000000e-09 -1.000000e-04 + + + +