Merge branch 'pre-master' into bt_dev

This commit is contained in:
Brian Taylor 2022-12-16 16:52:39 -08:00
commit 3860d07574
114 changed files with 188685 additions and 258 deletions

4
.gitignore vendored
View File

@ -86,3 +86,7 @@ src/spicelib/parser/inpptree-parser.c
src/spicelib/parser/inpptree-parser.h
# Visual Studio Code user options files
.vscode/
test_cases/diode/__pycache__/*
test_cases/diode/test_osdi/*
test_cases/diode/test_built_in/*

View File

@ -74,6 +74,7 @@ Dietmar Warning,
Michael Widlok,
Charles D.H. Williams,
Antony Wilson,
Pascal Kuthe,
and many others...
If someone helped in the development and has not been inserted in this list

380
COPYING
View File

@ -31,6 +31,9 @@ unnamed MIT license, compatible to New BSD
ngspice/src/spicelib/devices/adms/admst
LGPLv2.1
* all files in ngspice/src/osdi
MPLv2.0
ngspice/src/spicelib/devices/ndev
public domain
@ -568,3 +571,380 @@ LICENSE
permitted in any medium without royalty provided the copyright notice
and this notice are preserved. This file is offered as-is, without any
warranty.
-----------------------------MPLv2.0 - OSDI--------------------------------
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

8
Dockerfile Normal file
View File

@ -0,0 +1,8 @@
FROM python:3.10.4-bullseye
# python installation
RUN apt-get update && apt-get -y install bc bison flex libxaw7 libxaw7-dev libx11-6 libx11-dev libreadline8 libxmu6
RUN apt-get update && apt-get -y install build-essential libtool gperf libxml2 libxml2-dev libxml-libxml-perl libgd-perl
RUN apt-get update && apt-get -y install g++ gfortran make cmake libfl-dev libfftw3-dev
RUN pip install pytest numpy pandas

33
README_OSDI.md Normal file
View File

@ -0,0 +1,33 @@
# OSDI implementation for NGSPICE
OSDI (Open Source Device Interface) is a simulator independent device interface, that is used by the OpenVAF compiler.
Implementing this interface in NGSPICE allows loading Verilog-A models compiled by OpenVAF.
The interface is fixed and does not require the compiler to know about NGSPICE during compilation.
NGSPICE also doesn't need to know anything about the compiled models at compilation.
Therefore, these models can be loaded dynamically at runtime.
To that end the `osdi` command is provided.
It allows loading a dynamic library conforming to OSDI.
Example usage: `osdi diode.osdi`.
If used within a netlist the command requires the `pre_` prefix.
This ensures that the devices are loaded before the netlist is parsed.
Example usage: `pre_osdi diode.osdi`
If a relative path is provided to the `osdi` command in a netlist, it will resolve that path **relative to the netlist**, not relative to current working directory.
This ensures that netlists can be simulated from any directory
## Build Instructions
To compile NGSPICE with OSDI support ensure that the `--enable-predictor` and `--enable-osdi` flags are used.
The `compile_linus.sh` file enables these flags by default.
## Example/Test Case
A simple handwritten diode can be found in `test_cases/diode/diode.c`.
In the same directory a script named `test_diode.py` is provided that will compile this model and run some example simulations.
After the script has finished the compilation result `diode.osdi` and the netlist can then be found in `test_cases/diode/test_osdi`.

View File

@ -52,14 +52,14 @@ if test "$1" = "d"; then
echo "configuring for 64 bit debug"
echo
# You may add --enable-adms to the following command for adding adms generated devices
../configure --with-x --enable-xspice --enable-cider --with-readline=yes --enable-openmp CFLAGS="-g -m64 -O0 -Wall -Wno-unused-but-set-variable" LDFLAGS="-m64 -g"
../configure --with-x --enable-xspice --enable-cider --enable-predictor --enable-osdi --with-readline=yes --enable-openmp CFLAGS="-g -m64 -O0 -Wall -Wno-unused-but-set-variable" LDFLAGS="-m64 -g"
else
cd release
if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi
echo "configuring for 64 bit release"
echo
# You may add --enable-adms to the following command for adding adms generated devices
../configure --with-x --enable-xspice --enable-cider --with-readline=yes --enable-openmp --disable-debug CFLAGS="-m64 -O2" LDFLAGS="-m64 -s"
../configure --with-x --enable-xspice --enable-cider --enable-predictor --enable-osdi --with-readline=yes --enable-openmp --disable-debug CFLAGS="-m64 -O2" LDFLAGS="-m64 -s"
fi
if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi

View File

@ -53,14 +53,14 @@ if test "$1" = "d"; then
echo "configuring for 64 bit debug"
echo
# You may add --enable-adms to the following command for adding adms generated devices
../configure --with-wingui --enable-xspice --enable-cider --enable-openmp prefix="C:/Spice64d" CFLAGS="-g -m64 -O0 -Wall -Wno-unused-but-set-variable" LDFLAGS="-g -m64"
../configure --with-wingui --enable-xspice --enable-cider --enable-openmp --enable-osdi --enable-predictor prefix="C:/Spice64d" CFLAGS="-g -m64 -O0 -Wall -Wno-unused-but-set-variable" LDFLAGS="-g -m64"
else
cd release
if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi
echo "configuring for 64 bit release"
echo
# You may add --enable-adms to the following command for adding adms generated devices
../configure --with-wingui --enable-xspice --enable-cider --enable-openmp --disable-debug prefix="C:/Spice64" CFLAGS="-m64 -O2" LDFLAGS="-m64 -s"
../configure --with-wingui --enable-xspice --enable-cider --enable-openmp --enable-osdi --enable-predictor --disable-debug prefix="C:/Spice64" CFLAGS="-m64 -O2" LDFLAGS="-m64 -s"
fi
if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi

View File

@ -146,6 +146,10 @@ AC_ARG_ENABLE([oldapps],
AC_ARG_ENABLE([xspice],
[AS_HELP_STRING([--enable-xspice], [Enable XSPICE enhancements])])
# --enable-osdi: define OSDI in the code. This is for osdi support
AC_ARG_ENABLE([osdi],
[AS_HELP_STRING([--enable-osdi], [Enable OSDI integration])])
# --enable-cider: define CIDER in the code. This is for CIDER support
AC_ARG_ENABLE([cider],
[AS_HELP_STRING([--enable-cider], [Enable CIDER enhancements])])
@ -1156,7 +1160,18 @@ if test "x$enable_xspice" = xyes; then
AC_SUBST([VIS_CFLAGS])
else
XSPICEINIT="*"
if test "x$enable_osdi" = xyes; then\
case $host_os in
*mingw* | *msys* | *cygwin* | *solaris* )
XSPICEDLLIBS=""
;;
* )
XSPICEDLLIBS="-ldl"
;;
esac
fi
fi
AC_SUBST([XSPICEINIT])
AC_SUBST([XSPICEDLLIBS])
@ -1165,6 +1180,36 @@ AM_CONDITIONAL([XSPICE_WANTED], [test "x$enable_xspice" = xyes])
AM_CONDITIONAL([SHORT_CHECK_WANTED], [test "x$enable_shortcheck" = xyes])
if test "x$enable_osdi" = xyes; then
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
[AS_VAR_SET(CACHEVAR,[yes])],
[AS_VAR_SET(CACHEVAR,[no])])
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
AS_VAR_IF(CACHEVAR,yes,
[m4_default([$2], :)],
[m4_default([$3], :)])
AS_VAR_POPDEF([CACHEVAR])dnl
])dnl AX_CHECK_COMPILE_FLAGS
AX_CHECK_COMPILE_FLAG([-std=gnu11], [
CFLAGS="$CFLAGS -std=gnu11"
LDLAGS="$LDLAGS -std=gnu11"
], [
echo "C compiler cannot compile C11 code"
exit -1
])
AC_MSG_RESULT([OSDI features included])
AC_DEFINE([OSDI], [1], [The OSDI enhancements])
fi
AM_CONDITIONAL([OSDI_WANTED], [test "x$enable_osdi" = xyes])
# Add CIDER enhancements to ngspice.
if test "x$enable_cider" = xyes; then
AC_MSG_RESULT([CIDER features enabled])
@ -1444,6 +1489,7 @@ AC_CONFIG_FILES([Makefile
src/xspice/enh/Makefile
src/xspice/ipc/Makefile
src/xspice/idn/Makefile
src/osdi/Makefile
tests/Makefile
tests/bsim1/Makefile
tests/bsim2/Makefile

View File

@ -0,0 +1,75 @@
*** SPICE Models
*** Models created by Daniel Foty.
*** (c) 2001, Gilgamesh Associates and EPFL All rights reserved.
*** These models are provided without warranty or support.
*** These models represent a completely fictitious 0.15um process, and do
*** NOT correspond to any real silicon process. They are provided expressly for
*** use in the examples provided in this text, and should not be used for any
*** real silicon product design.
*** NMOS EKV MOSFET Model ***************************************************
*** Level=44 in WinSPICE and ELDO, Level=55 in ADM/HSPICE, Level=5 in PSPICE,
*** Level=EKV in Spectre
*** Lmin=0.15u Wmin=1.05u (If Scale=0.15u then Lmin=1 and Wmin=7)
*—————
.MODEL nmos nmos
+ LEVEL=44
*** Setup Parameters
+ UPDATE=2.6
*** Process Related Model Parameters
+ COX=9.083E-3 XJ=0.15E-6
*** Intrinsic Model Parameters
+ VTO=0.4 GAMMA=0.71 PHI=0.97 KP=453E-6
+ E0=88.0E6 UCRIT=4.0E6
+ DL=-0.05E-6 DW=-0.02E-6
+ LAMBDA = 0.30 LETA=0.28 WETA=0
+ Q0=280E-6 LK=0.5E-6
*** Substrate Current Parameters
+ IBN=1.0 IBA=200E6 IBB=350E6
*** Intrinsic Model Temperature Parameters
+ TNOM=27.0 TCV=1.5E-3 BEX=-1.5 UCEX=1.7 IBBT=0
*** 1/f Noise Model Parameters
+ KF=1E-27 AF=1
*** Series Resistance and Area Calculation Parameters
+ HDIF=0.24e-6 ACM=3 RSH=5.0 RS=1250.526
+ RD=1250.526 LDIF=0.07e-6
*** Junction Current Parameters
+ JS=1.0E-6 JSW=5.0E-11 XTI=0 N=1.5
*** Junction Capacitances Parameters
+ CJ=1.0E-3 CJSW=2.0E-10 CJGATE=5.0E-10
+ MJ=0.5 MJSW=0.3 PB=0.9 PBSW=0.9 FC=0.5
*** Gate Overlap Capacitances
+ CGSO=3.0E-10 CGDO=3.0E-10 CGBO=3.0E-11
*** PMOS EKV MOSFET Model ***************************************************
*** Level=44 in WinSPICE and ELDO, Level=55 in ADM/HSPICE, Level=5 in PSPICE,
*** Level=EKV in Spectre
*** Lmin=0.15u Wmin=1.05u (If Scale=0.15u then Lmin=1 and Wmin=7)
*—————
.MODEL pmos pmos
+ LEVEL = 44
*** Setup Parameters
+ UPDATE = 2.6
*** Process Related Model Parameters
+ COX=9.083E-3 XJ=0.15E-6
*** Intrinsic Model Parameters
+ VTO=-0.4 GAMMA=0.69 PHI=0.87 KP=92.15E-6
+ E0=51.0E6 UCRIT=18.0E6
+ DL=-0.05E-6 DW=-0.03E-6
+ LAMBDA=1.1 LETA=0.45 WETA=0
+ Q0=200E-6 LK=0.6E-6
*** Substrate Current Parameters
+ IBN=1.0 IBA=0.0 IBB=300E6
*** Intrinsic Model Temperature Parameters
+ TNOM=25.0 TCV=-1.4E-3 BEX=-1.4 UCEX=2.0 IBBT=0.0
*** 1/f Noise Model Parameters
+ KF=1.0E-28 AF=1
*** Series Resistance and Area Calculation Parameters
+ HDIF=0.24E-6 ACM=3 RSH=5.0 RS=3145.263
+ RD=3145.263 LDIF=0.07e-6
*** Junction Current Parameters
+ JS=1.0E-7 JSW=5.0E-12 XTI=0 N=1.8
*** Junction Capacitances Parameters
+ CJ=1.3E-3 CJSW=2.5E-10 CJGATE=5.5E-10
+ MJ=0.5 MJSW=0.35 PB=0.9 PBSW=0.9 FC=0.5
*** Gate Overlap Capacitances
+ CGSO=3.2E-10 CGDO=3.2E-10 CGBO=3.0E-11

View File

@ -0,0 +1,157 @@
**********************************************************************
* EKV v2.6 parameters for 0.5um CMOS C. EPFL-LEG, 1999
* ----------------------------------
*
* ELDO (LEVEL = 44) / PSPICE (LEVEL = 5) example parameter set
* for the EKV v2.6 model is provided for NMOS and PMOS.
*
*
* IMPORTANT NOTES:
* ----------------
*
* Parameters do not correspond to a particular technology but
* have reasonable values for standard 0.5um CMOS.
* Not intended for use in real design.
*
* Includes all intrinsic model parameters. An example set for
* extrinsic model parameters is provided.
*
* Geometry range: W >= 0.8um, L >= 0.5um
* Voltage range: |Vgb| < 3.3V, |Vdb| < 3.3V, |Vsb| < 2V
*
* For use with either simulator, comment/uncomment respective lines.
* Use of extrinsic model parameters and models (series resistance,
* junction currents/capacitances) is in general simulator-dependent.
*
**********************************************************************
* EKV v2.6 NMOS
*---------------
.MODEL NCH EKV_VA
*+ LEVEL = 44
*** Setup Parameters
*+ UPDATE = 2.6
*+ XQC = 0.4
+ TYPE = 1
*** Process Related Model Parameters
+ COX = 3.45E-3
+ XJ = 0.15E-6
*** Intrinsic Model Parameters
+ VTO = 0.6
+ GAMMA = 0.71
+ PHI = 0.97
+ KP = 150E-6
+ E0 = 88.0E6
+ UCRIT = 4.5E6
+ DL = -0.05E-6
+ DW = -0.02E-6
+ LAMBDA = 0.23
+ LETA = 0.28
+ WETA = 0.05
+ Q0 = 280E-6
+ LK = 0.5E-6
*** Substrate Current Parameters
+ IBN = 1.0
+ IBA = 200E6
+ IBB = 350E6
*** Intrinsic Model Temperature Parameters
+ TNOM = 25.0
+ TCV = 1.5E-3
+ BEX = -1.5
+ UCEX = 1.7
+ IBBT = 0.0
*** 1/f Noise Model Parameters
+ KF = 1E-27
+ AF = 1
*** Short-Distance Matching Statistical Parameters (for MC simulation only)
*+ AVTO = 0 DEV = 10.0E-3 ; ELDO v4.6
*+ AGAMMA = 0 DEV = 10.0E-3 ; ELDO v4.6
*+ AKP = 0 DEV = 25.0E-3 ; ELDO v4.6
*** Series Resistance and Area Calulation Parameters
*+ RLEV = 3
+ HDIF = 0.9E-6
+ RSH = 510
*** Junction Current Parameters
*+ ALEV = 3
+ JS = 8.0E-6
+ JSW = 1.5E-10
+ XTI = 0
+ N = 1.5
*** Junction Capacitances Parameters
+ CJ = 8.0E-4
+ CJSW = 3.0E-10
+ MJ = 0.5
+ MJSW = 0.3
+ PB = 0.9
+ PBSW = 0.5
+ FC = 0.5
*** Gate Overlap Capacitances
+ CGSO = 1.5E-10
+ CGDO = 1.5E-10
+ CGBO = 4.0E-10
* EKV v2.6 PMOS
*---------------
.MODEL PCH EKV_VA
*+ LEVEL = 44
*** Setup Parameters
*+ UPDATE = 2.6
*+ XQC = 0.4
+ TYPE = -1
*** Process Related Model Parameters
+ COX = 3.45E-3
+ XJ = 0.15E-6
*** Intrinsic Model Parameters
+ VTO = -0.55
+ GAMMA = 0.69
+ PHI = 0.87
+ KP = 35.0E-6
+ E0 = 51.0E6
+ UCRIT = 18.0E6
+ DL = -0.05E-6
+ DW = -0.03E-6
+ LAMBDA = 1.1
+ LETA = 0.45
+ WETA = 0.0
+ Q0 = 200E-6
+ LK = 0.6E-6
*** Substrate Current Parameters
+ IBN = 1.0
+ IBA = 10E6
+ IBB = 300E6
*** Intrinsic Model Temperature Parameters
+ TNOM = 25.0
+ TCV = -1.4E-3
+ BEX = -1.4
+ UCEX = 2.0
+ IBBT = 0.0
*** 1/f Noise Model Parameters
+ KF = 1.0E-28
+ AF = 1
*** Short-Distance Matching Statistical Parameters (for MC simulation only)
*+ AVTO = 0 DEV = 10.0E-3 ; ELDO v4.6
*+ AGAMMA = 0 DEV = 10.0E-3 ; ELDO v4.6
*+ AKP = 0 DEV = 25.0E-3 ; ELDO v4.6
*** Series Resistance and Area Calulation Parameters
*+ RLEV = 3
+ HDIF = 0.9E-6
+ RSH = 990
*** Junction Current Parameters
*+ ALEV = 3
+ JS = 4.0E-5
+ JSW = 7.0E-10
+ XTI = 0
+ N = 1.8
*** Junction Capacitances Parameters
+ CJ = 8.0E-4
+ CJSW = 4.0E-10
+ MJ = 0.5
+ MJSW = 0.35
+ PB = 0.9
+ PBSW = 0.8
+ FC = 0.5
*** Gate Overlap Capacitances
+ CGSO = 1.5E-10
+ CGDO = 1.5E-10
+ CGBO = 4.0E-10

View File

@ -0,0 +1,41 @@
* EKV 2.6
* simple inverter
.param Vcc = 1.8
* model definitions:
*.model .MODEL PCH EKV_VA type=-1
*.model .MODEL NCH EKV_VA type=1
.include Modelcards/ekv26_0u5.par
* the voltage sources:
Vdd vdd gnd DC 'Vcc'
V1 in gnd pulse(0 'Vcc' 0p 200p 100p 1n 2n)
Vmeas vss 0 0
Xnot1 in vdd vss out not1
*Rout out 0 1k
.subckt not1 a vdd vss z
Np1 z a vdd vdd pch W=2u L=0.5u as=0.26235p ad=0.26235p ps=2.51u pd=2.51u
Nn1 z a vss vss nch W=1u L=0.5u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u
c3 a vss 0.384f
c2 z vss 0.576f
.ends
* simulation command:
.tran 10ps 10ns
.dc V1 0 'vcc' 'vcc/100'
.control
pre_osdi test_osdi_win/ekv26_mod.osdi
run
*set nolegend
set xbrushwidth=3
plot in out
plot dc1.out
plot dc1.i(Vmeas)
rusage
.endc
.end

View File

@ -0,0 +1,922 @@
/*
EKV MOS model version 2.6 rev.15 with documentation at: http://ekv.epfl.ch
Matthias Bucher, Christophe Lallement, Christian Enz, Fabien Theodoloz, Francois Krummenacher
Electronics Laboratories, Swiss Federal Institute of Technology Lausanne, Switzerland
This Verilog-A was developed by Wladek Grabinski with modifications
by Tiburon Design Automation (www.tiburon-da.com).
This software has been provided pursuant to a License Agreement containing restrictions on its use.
It may not be copied or distributed in any form or medium, disclosed to third parties,
reverse engineered or used in any manner not provided for in said License Agreement
except with the prior written authorization.
Licensed under the Educational Community License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://opensource.org/licenses/ECL-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
either express or implied. See the License for the specific language governing permissions
and limitations under the License.
$RCSfile: ekv.va,v $ $Revision: 1.9 $ $Date: 2003/12/17 01:20:10 $
$RCSfile: ekv.va,v $ $Revision: 2.6.15 $ $Date: 2020/05/29 11:50:10 $
*/
/*
`include "disciplines.vams"
`include "constants.vams"
`include "compact.vams"
*/
// Macros for the model/instance parameters
//
// MPRxx model parameter real
// MPIxx model parameter integer
// IPRxx instance parameter real
// IPIxx instance parameter integer
// ||
// cc closed lower bound, closed upper bound
// oo open lower bound, open upper bound
// co closed lower bound, open upper bound
// oc open lower bound, closed upper bound
// cz closed lower bound=0, open upper bound=inf
// oz open lower bound=0, open upper bound=inf
// nb no bounds
// ex no bounds with exclude
// sw switch(integer only, values 0=false and 1=true)
// ty switch(integer only, values -1=p-type and +1=n-type)
//
// IPM instance parameter mFactor(multiplicity, implicit for LRM 2.2)
// OPP operating point parameter, includes units and description for printing
`define OPP(nam,uni,des) (* units=uni, desc=des *) real nam;
`define OPM(nam,uni,des) (* units=uni, desc=des, multiplicity="multiply" *) real nam;
`define OPD(nam,uni,des) (* units=uni, desc=des, multiplicity="divide" *) real nam;
`define MPRnb(nam,def,uni, des) (* units=uni, desc=des *) parameter real nam=def;
`define MPRex(nam,def,uni,exc, des) (* units=uni, desc=des *) parameter real nam=def exclude exc;
`define MPRcc(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter real nam=def from[lwr:upr];
`define MPRoo(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter real nam=def from(lwr:upr);
`define MPRco(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter real nam=def from[lwr:upr);
`define MPRoc(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter real nam=def from(lwr:upr];
`define MPRcz(nam,def,uni, des) (* units=uni, desc=des *) parameter real nam=def from[ 0:inf);
`define MPRoz(nam,def,uni, des) (* units=uni, desc=des *) parameter real nam=def from( 0:inf);
`define MPInb(nam,def,uni, des) (* units=uni, desc=des *) parameter integer nam=def;
`define MPIex(nam,def,uni,exc, des) (* units=uni, desc=des *) parameter integer nam=def exclude exc;
`define MPIcc(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter integer nam=def from[lwr:upr];
`define MPIoo(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter integer nam=def from(lwr:upr);
`define MPIco(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter integer nam=def from[lwr:upr);
`define MPIoc(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter integer nam=def from(lwr:upr];
`define MPIcz(nam,def,uni, des) (* units=uni, desc=des *) parameter integer nam=def from[ 0:inf);
`define MPIoz(nam,def,uni, des) (* units=uni, desc=des *) parameter integer nam=def from( 0:inf);
`define MPIsw(nam,def,uni, des) (* units=uni, desc=des *) parameter integer nam=def from[ 0: 1];
`define MPIty(nam,def,uni, des) (* units=uni, desc=des *) parameter integer nam=def from[ -1: 1] exclude 0;
`define IPRnb(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter real nam=def;
`define IPRex(nam,def,uni,exc, des) (* units=uni, type = "instance", desc=des *) parameter real nam=def exclude exc;
`define IPRcc(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from[lwr:upr];
`define IPRoo(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from(lwr:upr);
`define IPRco(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from[lwr:upr);
`define IPRoc(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from(lwr:upr];
`define IPRcz(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from[ 0:inf);
`define IPRoz(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from( 0:inf);
`define IPInb(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def;
`define IPIex(nam,def,uni,exc, des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def exclude exc;
`define IPIcc(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from[lwr:upr];
`define IPIoo(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from(lwr:upr);
`define IPIco(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from[lwr:upr);
`define IPIoc(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from(lwr:upr];
`define IPIcz(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from[ 0:inf);
`define IPIoz(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from( 0:inf);
`define BPRco(nam, def, uni, lwr, upr, des) (* units = uni, type = "instance", desc = des *) parameter real nam = def from[lwr : upr);
`define BPRoz(nam, def, uni, des) (* units = uni, type = "instance", desc = des *) parameter real nam = def from(0.0 : inf);
`define BPRcz(nam, def, uni, des) (* units = uni, type = "instance", desc = des *) parameter real nam = def from[0.0 : inf);
`define BPIcc(nam, def, uni, lwr, upr, des) (* units = uni, type = "instance", desc = des *) parameter integer nam = def from[lwr : upr];
`define BPInb(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def;
`define BPRnb(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter real nam=def;
// includes: in case we do not want to include any other file [AB:040902]
// we can just add the following section in this file
// AB: i hope this may help our code to be easily transported
//----------------------------------------
// from disciplines.h we need:
// Electrical
// Current in amperes
nature Current
units = "A";
access = I;
idt_nature = Charge;
`ifdef CURRENT_ABSTOL
abstol = `CURRENT_ABSTOL;
`else
abstol = 1e-12;
`endif
endnature
// Charge in coulombs
nature Charge
units = "coul";
access = Q;
ddt_nature = Current;
`ifdef CHARGE_ABSTOL
abstol = `CHARGE_ABSTOL;
`else
abstol = 1e-14;
`endif
endnature
// Potential in volts
nature Voltage
units = "V";
access = V;
idt_nature = Flux;
`ifdef VOLTAGE_ABSTOL
abstol = `VOLTAGE_ABSTOL;
`else
abstol = 1e-6;
`endif
endnature
// Flux in Webers
nature Flux
units = "Wb";
access = Phi;
ddt_nature = Voltage;
`ifdef FLUX_ABSTOL
abstol = `FLUX_ABSTOL;
`else
abstol = 1e-9;
`endif
endnature
// Conservative discipline
discipline electrical
potential Voltage;
flow Current;
enddiscipline
// Signal flow disciplines
discipline voltage
potential Voltage;
enddiscipline
discipline current
potential Current;
enddiscipline
//from constants.h we need
`define C_EPSSIL 1.03594314e-10
`define C_EPSOX 34.5e-12
`define C_QE 1.602e-19
`define C_K 1.3807e-23
`define P_K 1.3806226e-23
`define P_EPS0 8.85418792394420013968e-12
`define P_CELSIUS0 273.15
`define POS_MIN 1.0E-6
`define SQRT2 1.4142135623730950488016887242097
`define ONE3RD 0.33333333333333333333333333333333
`define ONESQRT2 0.70710678118654752440084436210485
//if any other constant is needed it may be copied from the constants.h and be put above.
//------------------------------------------ end of includes
`define FWD 1
`define REV -1
// AB 040902
`define NOT_GIVEN -1.0e21
`define DEFAULT_TNOM 25
module ekv_va(d,g,s,b);
// %%DEVICE_CLASS=MOS(NMOS:TYPE=1,PMOS:TYPE=-1)%%
// Node definitions
inout d,g,s,b; // external nodes
electrical d,g,s,b; // external nodes
// Branch definitions
branch (d,s) ds;
branch (d,b) db;
branch (s,b) sb;
branch (g,b) gb;
// * Local variables
real tmp1, tmp2, tmp3; // temporary variables
real VGprime, GAMMAprime;// short and narrow channel effect
real VP, VPprime; // pinch-off voltage
real if_, ir, irprime; // normalized currents
real VDSS, VDSSprime;// saturation voltage
real deltaL, Leq; // channel length reduction
real beta; // transconductance factor
real n; // slope factor
real Ispec; // specific current
real Vt; // k*T/q
real gm, gms, gmbs, gds;
real isub, Isub;
real inv_Vt, Vt_01, Vt_2, Vt_4, Vt_Vt, Vt_Vt_2, Vt_Vt_16;
real eps_COX, eps_COX_W, eps_COX_L;
real Lc, Lc_LAMBDA, IBN_2, T0, T1, eta_qi;
real inv_UCRIT, Lc_UCRIT, Lc_IBB, IBA_IBB;
integer Mode;
real WETA_W, LETA_L;
real E0_Q_1, AWL;
real T, KP_Weff;
real Eg, refEg, deltaT, ratioT, Tnom;
real VTO_T, VTO_S, KP_T, UCRIT_T, IBB_T, PHI_T, GAMMA_S;
real sqrt_Lprime_Lmin;
real GAMMAstar, sqrt_GAMMAstar;
real big_sqrt_VP;
real big_sqrt_VP0, VP0;
real PHI_VD, PHI_VS;
real sqrt_PHI;
real sqrt_PHI_VP, sqrt_PHI_VD, sqrt_PHI_VS;
real sqrt_PHI_VD_Vt, sqrt_PHI_VS_Vt;
real Vds, deltaV_2, Vip;
real VDSS_sqrt, sqrt_VDSS_deltaV, sqrt_Vds_VDSS_deltaV;
real VDSSprime_sqrt, sqrt_VDSSprime_deltaV, sqrt_Vds_VDSSprime_deltaV;
real if_ir;
real sqrt_if, sqrt_ir, sqrt_irprime;
real dif_dv, dir_dv, dirprime_dv;
// Charge related variables
real sif, sir, sif2, sir2, sif3, sir3;
real sif_sir_2;
real qi, qb;
real QD, QS, QI, QB, QG;
real VP_PHI_eps, sqrt_PHI_VP_2, WLCox;
real n_Vt_COX, n_1, n_1_n;
// Variables used for derivatives computation
real dVP_dVD, dVP_dVG, dVP_dVS;
real dif_dVD, dif_dVS, dif_dVG;
real dir_dVD, dir_dVS, dir_dVG;
real dVDSS_dVD, dVDSS_dVG, dVDSS_dVS;
real ddeltaV_dVD, ddeltaV_dVG, ddeltaV_dVS;
real dVip_dVD, dVip_dVG, dVip_dVS;
real dVDSSprime_dVD, dVDSSprime_dVG, dVDSSprime_dVS;
real dirprime_dVD, dirprime_dVG, dirprime_dVS;
real dLeq_dVD, dLeq_dVG, dLeq_dVS;
real dbeta_dVD, dbeta_dVG, dbeta_dVS;
real VGstar, sqrt_VGstar;
real VG, VD, VS;
real Von, Vdsat, Id, Ibd;
real Gn;
real GAMMA_sqrt_PHI, Lmin, Lprime, T0_GAMMA_1, THETA_VP_1, Vc;
real Vdsprime, Vt_Vc, dGAMMAprime_dVD, dGAMMAprime_dVG, dGAMMAprime_dVS;
real dVPprime_dVD, dVPprime_dVG, dVPprime_dVS, ddeltaL_dVD, ddeltaL_dVG;
real ddeltaL_dVS, dn_dVD, dn_dVG, dn_dVS;
real log_Vc_Vt, sqrt_PHI_VP0, sqrt_VP_Vt;
real Lc_IBB_Vib, Vib, dIsub_factor, exp_ib;
real inv_Vib, sqrt_PHI_VP2_2;
real V0, deltaVFB, vL;
real dQI_dVD, dQI_dVS, dQI_dVG;
real dQB_dVD, dQB_dVS, dQB_dVG;
real Leff, Weff;
real RSeff, RDeff;
real yk, z0, zk;
real EPSOX, epssil;
real ddt_QD, ddt_QS;
//DIODES realted variables [AB: 040902]
real as_i, ad_i, ps_i, pd_i, v_di_b, v_si_b;
real temp_arg, tmp0;
real js_t, jsw_t, jswg_t;
real pb_t, pbsw_t, pbswg_t;
real cj_t, cjsw_t, cjswg_t;
real njts_t, njtssw_t, njtsswg_t;
real is_d, arg_d, is_s, arg_s;
real f_breakdown_d, f_breakdown_s, idb_tun, isb_tun;
real csb_d, cssw_d, csswg_d;
real csb_s, cssw_s, csswg_s;
real qjd, qjs;
// parameter definitions
parameter integer TYPE = 1 from [-1:1] exclude 0; // NMOS=1, PMOS=-1
parameter integer Noise = 1 from [0:1]; // Set to zero to prevent noise calculation
parameter real Trise = 0.0 from [-inf:inf]; // Difference sim. temp and device temp [C deg]
// parameter real Temp = -`NOT_GIVEN from [`P_CELSIUS0:inf]; // Device temp [C]
//AB: the parameter name Temp is not working for no obvious reason; changed to TEMP
parameter real TEMP = -`NOT_GIVEN from [`P_CELSIUS0:inf]; // Device temp [C]
parameter real TNOM = -`NOT_GIVEN; // Temperature [C]
// Instance parameters
// - intrinsic model
`IPRoz( L ,1.0e-5 ,"m" ,"Length" )
`IPRoz( W ,1.0e-5 ,"m" ,"Total width including fingers" )
`IPIco( M ,1 ,"" ,1 ,inf ,"Parallel multiplier" )
`IPIco( NS ,1 ,"" ,1 ,inf ,"Series multiplier" )
`BPRnb( DTEMP ,0.0 ,"K" ,"Offset of device temperature" )
// - external parasitics
`IPRcz( AS ,0.0 ,"m^2" ,"Source-to-substrate junction area" )
`IPRcz( AD ,0.0 ,"m^2" ,"Drain-to-substrate junction area" )
`IPRcz( PS ,0.0 ,"m" ,"Source-to-substrate junction perimeter" )
`IPRcz( PD ,0.0 ,"m" ,"Drain-to-substrate junction perimeter" )
`IPRcz( NRS ,1.0 ,"" ,"Number of squares in source" )
`IPRcz( NRD ,1.0 ,"" ,"Number of squares in drain" )
// *** Process related parameters
parameter real COX = 2.0E-3 from [0.0:inf]; // Gate oxide capacitance per unit area [F]
parameter real XJ = 300E-9 from [0.0:inf]; // Junction depth [m]
//*** Threshold voltage/substrate effect parameters (long-channel)
parameter real VTO = 0.5 from [-inf:inf]; // Long-channel threshold voltage [V]
parameter real TCV = 1.0e-3; // Threshold voltage temperature coefficient [V/K]
parameter real GAMMA = 0.7 from [0.0:inf]; // Body effect parameter
parameter real PHI = 0.5 from [0.2:inf]; // Bulk Fermi potential [V]
//*** Mobility parameters (long-channel) ***
parameter real KP = 150E-6 from [0.0:inf]; // Transconductance parameter [A/V/V]
parameter real BEX = -1.5; // Mobility temperature exponent
parameter real THETA = 0.0 from [0.0:inf]; // Mobility reduction coefficient [1/V]
parameter real E0 = 1.0E8; // Mobility reduction coefficient [V/m]
//*** Velocity sat./channel length mod. parameters (short-channel)
parameter real UCRIT = 2.0E6 from [0.0:inf]; // Longitudinal critical field [V/m]
parameter real UCEX = 0.8; // Longitudinal critical field temperature exponent
parameter real LAMBDA = 0.8 from [0.0:inf]; // Depletion length coefficient (channel length modulation)
//*** Process related parameters
parameter real DL = -0.01E-6; // Channel width correction [m]
parameter real DW = -0.01E-6; // Channel length correction [m]
//*** Threshold voltage/substrate effect parameter (narrow-channel)
parameter real WETA = 0.2 from [0.0:inf]; // Narrow-channel effect coefficient
//*** Threshold voltage/substrate effect parameters (short-channel)
parameter real LETA = 0.3 from [0.0:inf]; // Short-channel effect coefficient
parameter real Q0 = 230E-6 from [0.0:inf]; // Reverse short channel effect peak charge density
parameter real LK = 0.4E-6 from [0.0:inf]; // Reverse short channel effect characteristic length [m]
//*** Substrate current parameters
parameter real IBA = 5.0E8 from [0.0:inf]; // First impact ionization coefficient [1/m]
parameter real IBB = 4.0E8 from [0.0:inf]; // Second impact ionization coefficient [V/m]
parameter real IBBT = 9.0e-4; // Temperature coefficient for IBB [1/K]
parameter real IBN = 1.0 from [0.0:inf]; // Saturation voltage factor for impact ionization
//*** Series resistance parameters
parameter real RSH = 0.0 from [0.0:inf]; // Sheet resistance [Ohms]
parameter real HDIF = 0.5E-6 from [0.0:inf]; // Sheet resistance multipler
//*** for MC analysis fk 25/05/97
parameter real AVTO = 1E-6 from [0.0:inf]; // Area related threshold voltage mismatch parameter [Vm]
parameter real AKP = 1E-6 from [0.0:inf]; // Area related gain mismatch parameter [m]
parameter real AGAMMA = 1E-6 from [0.0:inf]; // Area related body effect mismatch parameter [sqr(V) m]
parameter real AF = 1.0 from (0:inf); // Flicker noise exponent
parameter real KF = 0.0 from [0:inf); // Flicker noise coefficient
//*** JUNCTION DRAIN-BULK AND SOURCE-BULK AREA, CURRENT, CAPACITANCE [AB:040902]
parameter real xd_n = 1.0 from [0.0:inf);
parameter real xd_js = 1.0E-09 from [0.0:inf);
parameter real xd_jsw = 1.0E-12 from [0.0:inf);
parameter real xd_jswg = 1.0E-12 from [0.0:inf);
parameter real xd_mj = 0.900 from [0.0:1.0];
parameter real xd_mjsw = 0.700 from [0.0:1.0];
parameter real xd_mjswg = 0.700 from [0.0:1.0];
parameter real xd_pb = 0.800 from (0.0:inf);
parameter real xd_pbsw = 0.600 from (0.0:inf);
parameter real xd_pbswg = 0.600 from (0.0:inf);
parameter real xd_cj = 1.0E-09 from [0.0:inf);
parameter real xd_cjsw = 1.0E-12 from [0.0:inf);
parameter real xd_cjswg = 1.0E-12 from [0.0:inf);
parameter real xd_gmin = 0.0 from [0.0:inf);
parameter real xd_xjbv = 0.0 from [0.0:inf);
parameter real xd_bv = 10.0 from [0.0:inf);
parameter real xd_njts = 1.0 from [0.0:inf);
parameter real xd_njtssw = 1.0 from [0.0:inf);
parameter real xd_njtsswg = 1.0 from [0.0:inf);
parameter real xd_vts = 0.0 from [0.0:inf);
parameter real xd_vtssw = 0.0 from [0.0:inf);
parameter real xd_vtsswg = 0.0 from [0.0:inf);
parameter real tp_xti = 3.0 from (-inf:inf);
parameter real tp_cj = 0.0 from (-inf:inf);
parameter real tp_cjsw = 0.0 from (-inf:inf);
parameter real tp_cjswg = 0.0 from (-inf:inf);
parameter real tp_pb = 0.0 from (-inf:inf);
parameter real tp_pbsw = 0.0 from (-inf:inf);
parameter real tp_pbswg = 0.0 from (-inf:inf);
parameter real tp_njts = 0.0 from [0.0:inf);
parameter real tp_njtssw = 0.0 from [0.0:inf);
parameter real tp_njtsswg = 0.0 from [0.0:inf);
analog begin
// Set constant
EPSOX = 3.9 * `P_EPS0;
epssil = 11.7 * `P_EPS0;
Ibd = 0.0;
// The following are necessary to prevent memory states being reserved:
THETA_VP_1 = 0.0;
VPprime = 0.0;
sqrt_VP_Vt = 0.0;
// Geometry, voltage and temperature independent model variables
eps_COX = epssil/COX;
Lc = sqrt(eps_COX*XJ);
Lc_LAMBDA = Lc * LAMBDA;
eps_COX_W = 3.0 * eps_COX * WETA;
eps_COX_L = eps_COX * LETA;
IBN_2 = IBN + IBN;
T0 = COX / (epssil*E0);
V0 = (Q0+Q0) / COX;
eta_qi = TYPE > 0 ? 0.5 : 0.3333333333333;
/* Model working variables, geometry and voltage independent,
* which need to be updated after temperature change
* EKV model internal variables depending on temperature.
*/
/* If Temp is explicitly specified, use that value
otherwise use Tckt+Trise */
if (TEMP == -`NOT_GIVEN) //AB: 040902 Temp -> TEMP
T = $temperature + Trise;
else
T = TEMP + `P_CELSIUS0; //AB: 040902 Temp -> TEMP
if (TNOM == -`NOT_GIVEN)
Tnom = `DEFAULT_TNOM + `P_CELSIUS0;
else
Tnom = TNOM + `P_CELSIUS0;
Vt = $vt(T);
Vt_01 = 0.1 * Vt;
inv_Vt = 1.0 / Vt;
Vt_2 = Vt + Vt;
Vt_4 = Vt_2 + Vt_2;
Vt_Vt = Vt * Vt;
Vt_Vt_2 = Vt_Vt + Vt_Vt;
Vt_Vt_16 = 16.0 * Vt_Vt;
Eg = 1.16 - 7.02e-4 * T * T / (T + 1108.0);
refEg = 1.16 - (7.02e-4*Tnom*Tnom) / (Tnom + 1108.0);
deltaT = T - Tnom;
ratioT = T / Tnom;
VTO_T = VTO - TCV * deltaT;
KP_T = KP * pow(ratioT, BEX);
UCRIT_T = UCRIT * pow(ratioT, UCEX);
IBB_T = IBB * (1.0 + IBBT * deltaT);
PHI_T = PHI * ratioT - 3.0 * Vt * ln(ratioT) - refEg * ratioT + Eg;
// !! mb 99/07/30 prevents PHI from becoming smaller than 0.2
tmp1 = 0.2;
tmp2 = PHI_T - tmp1;
PHI_T = 0.5*(tmp2 + sqrt(tmp2*tmp2 + Vt*Vt)) + tmp1;
sqrt_PHI = sqrt(PHI_T);
inv_UCRIT = 1.0/UCRIT_T;
Lc_UCRIT = Lc * UCRIT_T;
Lc_IBB = Lc * IBB_T;
IBA_IBB = IBA / IBB_T;
/* VTO, KP and GAMMA with variation for MC analysis if required.
* The default value for model parameters AVTO, AKP and AGAMMA
* is set to 1e-6 to allow meaningful sensitivity analysis. Only
* the deviation from this value has to be taken into account
*/
// wg: for userc.c and verilog implementations
Leff = L + DL;
// wg: for userc.c and verilog implementations
Weff = W + DW;
Vc = UCRIT_T*Leff; // NOTE: use L if necessary
log_Vc_Vt = Vt*(ln(0.5*Vc*inv_Vt)-0.6); // mb 98/02/05 (r1)
// de-normalization
AWL = 1.0/sqrt(Weff*Leff);
if (TYPE > 0)
VTO_S = ((AVTO != 1e-6) ? AWL*(AVTO - 1e-6) + VTO_T : VTO_T);
else
VTO_S = ((AVTO != 1e-6) ? AWL*(1e-6 - AVTO) - VTO_T: -VTO_T);
KP_Weff = Weff * ((AKP != 1e-6) ? KP_T*(1 + (AKP - 1e-6)*AWL) : KP_T);
GAMMA_S = ((AGAMMA !=1e-6) ? GAMMA + (AGAMMA - 1e-6)*AWL : GAMMA);
GAMMA_sqrt_PHI = GAMMA_S*sqrt_PHI;
/* ************************************
* STATIC MODEL EQUATIONS
* *************************************/
// VGprime:
if (V0 == 0.0)
deltaVFB = 0.0;
// else begin : VGprime //AB: 040902 VGPrime is also a variable and
else begin : VGprime_block //AB: 040902 VGPrime -> VGprime_block
real sqv;
// mb 99/03/26 corrected for multiple device number
vL = 0.28 * (Leff/(LK*NS) - 0.1);
sqv = 1.0 / (1.0 + 0.5*(vL + sqrt(vL*vL + 1.936e-3)));
deltaVFB = V0 * sqv * sqv;
end
VG = TYPE * V(g,b); // wg 22/04/08 corrected for device TYPE
VS = TYPE * V(s,b);
VD = TYPE * V(d,b);
if (VD - VS < 0) begin
Mode = `REV;
T1 = VS;
VS = VD;
VD = T1;
end
else
Mode = `FWD;
// VGB = VGS - VBS;
// VBD = VBS - VDS;
VGstar = VG - VTO_S - deltaVFB + PHI_T + GAMMA_sqrt_PHI;
sqrt_VGstar = sqrt(VGstar*VGstar + 2.0*Vt_Vt_16);
VGprime = 0.5*(VGstar + sqrt_VGstar);
// Pinch-off voltage VP, limited to VP >= -PHI
PHI_VS = PHI_T+VS;
sqrt_PHI_VS_Vt = sqrt(PHI_VS*PHI_VS+Vt_Vt_16);
sqrt_PHI_VS = sqrt(0.5*(PHI_VS+sqrt_PHI_VS_Vt));
PHI_VD = PHI_T+VD;
sqrt_PHI_VD_Vt = sqrt(PHI_VD*PHI_VD+Vt_Vt_16);
sqrt_PHI_VD = sqrt(0.5*(PHI_VD+sqrt_PHI_VD_Vt));
WETA_W = eps_COX_W * M / Weff;
LETA_L = eps_COX_L * NS / Leff;
// mb: symmetric version of GAMMAprime necessary with charges model
big_sqrt_VP0 = sqrt(VGprime + 0.25*GAMMA_S*GAMMA_S);
VP0 = VGprime - PHI_T - GAMMA_S*(big_sqrt_VP0 - 0.5*GAMMA_S);
sqrt_PHI_VP0 = sqrt(VP0+PHI_T+Vt_01);
GAMMAstar = GAMMA_S - LETA_L * (sqrt_PHI_VS+sqrt_PHI_VD) +
WETA_W * sqrt_PHI_VP0;
// keep GAMMAprime from becoming negative
sqrt_GAMMAstar = sqrt(GAMMAstar*GAMMAstar+Vt_01);
GAMMAprime = 0.5*(GAMMAstar+sqrt_GAMMAstar);
big_sqrt_VP = sqrt(VGprime+0.25*GAMMAprime*GAMMAprime);
VP = VGprime-PHI_T-GAMMAprime*(big_sqrt_VP-0.5*GAMMAprime);
// Forward normalized current:
tmp1 = (VP - VS) * inv_Vt;
if (tmp1 > -0.35) begin
z0 = 2.0/(1.3 + tmp1 - ln(tmp1 + 1.6));
zk = (2.0 + z0)/(1.0 + tmp1 + ln(z0));
yk = (1.0 + tmp1 + ln(zk))/(2.0 + zk);
end else begin
if (tmp1 > -15.0) begin
z0 = 1.55 + exp(-tmp1);
zk = (2.0 + z0)/(1.0 + tmp1 + ln(z0));
yk = (1.0 + tmp1 + ln(zk))/(2.0 + zk);
end else begin
if (tmp1 > -23.0) begin
yk = 1.0/(2.0 + exp(-tmp1));
end else begin
yk = exp(tmp1) + 1E-64;
end
end
end
if_ = yk*(1.0 + yk);
sqrt_if = sqrt(if_);
dif_dv = yk;
// Saturation voltage:
Vt_Vc = Vt / Vc;
VDSS_sqrt = sqrt(0.25+sqrt_if*Vt_Vc);
VDSS = Vc*(VDSS_sqrt-0.5);
Vds = 0.5*(VD-VS);
deltaV_2 = Vt_Vt_16*(LAMBDA*(sqrt_if-
VDSS*inv_Vt)+15.625e-3);
sqrt_VDSS_deltaV = sqrt(VDSS*VDSS+deltaV_2);
sqrt_Vds_VDSS_deltaV = sqrt((Vds-VDSS)*(Vds-VDSS)+deltaV_2);
Vip = sqrt_VDSS_deltaV-sqrt_Vds_VDSS_deltaV;
VDSSprime_sqrt = sqrt(0.25+(sqrt_if-0.75*ln(if_))*Vt_Vc);
VDSSprime = Vc*(VDSSprime_sqrt-0.5)+log_Vc_Vt;
// Reverse normalized current:
Vdsprime = Vds-VDSSprime; // mb 97/07/18 introduced Vdsprime
sqrt_VDSSprime_deltaV = sqrt(VDSSprime*VDSSprime+deltaV_2);
sqrt_Vds_VDSSprime_deltaV = sqrt(Vdsprime*Vdsprime+deltaV_2);
tmp1 = (VP-Vds-VS-sqrt_VDSSprime_deltaV+
sqrt_Vds_VDSSprime_deltaV)*inv_Vt;
// include -> Charge F(x) interpolate function
if (tmp1 > -0.35) begin
z0 = 2.0/(1.3 + tmp1 - ln(tmp1 + 1.6));
zk = (2.0 + z0)/(1.0 + tmp1 + ln(z0));
yk = (1.0 + tmp1 + ln(zk))/(2.0 + zk);
end else begin
if (tmp1 > -15.0) begin
z0 = 1.55 + exp(-tmp1);
zk = (2.0 + z0)/(1.0 + tmp1 + ln(z0));
yk = (1.0 + tmp1 + ln(zk))/(2.0 + zk);
end else begin
if (tmp1 > -23.0) begin
yk = 1.0/(2.0 + exp(-tmp1));
end else begin
yk = exp(tmp1) + 1E-64;
end
end
end
irprime = yk*(1.0 + yk);
sqrt_irprime = sqrt(irprime);
dirprime_dv = yk;
/* Channel length modulation & mobility reduction due
* to longitudinal field */
deltaL = Lc_LAMBDA*ln(1.0+(Vds-Vip)/Lc_UCRIT);
Lprime = Leff-deltaL+(Vds+Vip)*inv_UCRIT;
Lmin = 0.1*Leff;
sqrt_Lprime_Lmin = sqrt(Lprime*Lprime+Lmin*Lmin);
Leq = 0.5*(Lprime+sqrt_Lprime_Lmin);
// Transconductance factor:
// Mobility reduction due to vertical field
// Reverse normalized current:
// ratioV_ir
tmp1 = (VP - VD) * inv_Vt;
if (tmp1 > -0.35) begin
z0 = 2.0/(1.3 + tmp1 - ln(tmp1 + 1.6));
zk = (2.0 + z0)/(1.0 + tmp1 + ln(z0));
yk = (1.0 + tmp1 + ln(zk))/(2.0 + zk);
end else begin
if (tmp1 > -15.0) begin
z0 = 1.55 + exp(-tmp1);
zk = (2.0 + z0)/(1.0 + tmp1 + ln(z0));
yk = (1.0 + tmp1 + ln(zk))/(2.0 + zk);
end else begin
if (tmp1 > -23.0) begin
yk = 1.0/(2.0 + exp(-tmp1));
end else begin
yk = exp(tmp1) + 1E-64;
end
end
end
ir = yk*(1.0 + yk);
sqrt_ir = sqrt(ir);
dir_dv = yk;
sif2 = 0.25+if_;
sir2 = 0.25+ir;
sif = sqrt(sif2);
sir = sqrt(sir2);
sif_sir_2 = (sif+sir)*(sif+sir);
VP_PHI_eps = VP+PHI_T+1.0e-6;
sqrt_PHI_VP_2 = 2.0*sqrt(VP_PHI_eps);
n_1 = GAMMA_S/sqrt_PHI_VP_2;
n_1_n = GAMMA_S/(sqrt_PHI_VP_2 + GAMMA_S);
// Normalized inversion charge (qi=QI/WLCox)
qi = -(1.0+n_1)*Vt*((0.66666666+0.66666666)*
(sir2+sir*sif+sif2)/(sif+sir) - 1.0);
// Normalized depletion charge (qb=QB/WLCox), for depletion to inversion
qb = -0.5*GAMMA_S*sqrt_PHI_VP_2 - n_1_n*qi;
if (E0 == 0.0) begin
/* NOTE: this version of the simple mobility model from prior
* versions of the EKV model is reinstated.
* In case E0 is *not* specified, this
* simple mobility model is used according to THETA, if specified.
* VPprime:
* mb eliminated discontinuity of derivative of 1+THETA*VP
*/
sqrt_VP_Vt = sqrt(VP*VP + Vt_Vt_2);
VPprime = 0.5 * (VP + sqrt_VP_Vt);
THETA_VP_1 = 1.0+THETA*VPprime;
beta = KP_Weff / (Leq * THETA_VP_1); // mb 97/07/18
end
else begin
/* new model for mobility reduction, linked to the charges model
* mb 98/10/11 (r10) introduced fabs(Eeff) (jpm)
* E0_Q_1 = 1.0 + T0 * abs(qb+eta_qi*qi);
*/
if ((qb + eta_qi*qi) > 0.0)
E0_Q_1 = 1.0 + T0*(qb + eta_qi*qi);
else
E0_Q_1 = 1.0 - T0*(qb + eta_qi*qi);
T0_GAMMA_1 = 1.0 + T0*GAMMA_sqrt_PHI;
beta = KP_Weff * T0_GAMMA_1 / (Leq * E0_Q_1);
end
/* Slope factor: mb introduced new formula to avoid divergence
* of n for VP->-PHI */
sqrt_PHI_VP = sqrt(PHI_T+VP+Vt_4); // mb 95/12/19 introduced Vt_4
n = 1.0 + GAMMA_S/(2.0*sqrt_PHI_VP);
// Drain current:
if_ir = if_-irprime;
Ispec = Vt_Vt_2 * n * beta;
Id = Ispec * if_ir;
/* Return threshold voltage
* Von = Vth(Vs) = Vto + Gamma*(sqrt(Phi + Vsb)-sqrt(Phi)) */
Von = VTO_S + GAMMAprime*(sqrt_PHI_VS - sqrt_PHI);
// Return saturation voltage (estimate)
Vdsat = Vt * (2.0*sqrt_if + 4.0);
// Return equivalent conductance for thermal noise calculation
Gn = beta * abs(qi);
/* Pinch-off voltage derivatives:
* mb 97/09/14 symmetric version of GAMMAprime necessary with
* charges model
* mb 99/05/10 (r12) New VGprime formulation (REVISION III) allows
* VP derivatives to be expressed with a single equation
*/
tmp1 = GAMMAprime / (sqrt_GAMMAstar+sqrt_GAMMAstar);
tmp2 = VGprime/sqrt_VGstar; // dVGprime_dVG
dGAMMAprime_dVD = -LETA_L * tmp1 * sqrt_PHI_VD / sqrt_PHI_VD_Vt;
dGAMMAprime_dVS = -LETA_L * tmp1 * sqrt_PHI_VS / sqrt_PHI_VS_Vt;
dGAMMAprime_dVG = WETA_W * tmp1 * (big_sqrt_VP0-0.5*GAMMA_S) /
(big_sqrt_VP0*sqrt_PHI_VP0) * tmp2;
tmp3 = (VP+PHI_T) / big_sqrt_VP;
dVP_dVD = -tmp3 * dGAMMAprime_dVD;
dVP_dVS = -tmp3 * dGAMMAprime_dVS;
dVP_dVG = -tmp3 * dGAMMAprime_dVG + (1.0 -
GAMMAprime/(big_sqrt_VP+big_sqrt_VP)) * tmp2;
// Forward normalized current derivatives:
tmp1 = dif_dv * inv_Vt; // mb 95/08/28, 97/04/21
dif_dVD = tmp1 * dVP_dVD;
dif_dVS = tmp1 * (dVP_dVS-1.0);
dif_dVG = tmp1 * dVP_dVG;
// Saturation voltage derivatives:
tmp1 = Vt / (4.0*VDSS_sqrt*sqrt_if);
dVDSS_dVD = tmp1 * dif_dVD;
dVDSS_dVS = tmp1 * dif_dVS;
dVDSS_dVG = tmp1 * dif_dVG;
// deltaV derivatives:
tmp1 = (Vt_4+Vt_4) * LAMBDA;
tmp2 = Vt / (sqrt_if+sqrt_if);
ddeltaV_dVD = tmp1 * (dif_dVD*tmp2 - dVDSS_dVD);
ddeltaV_dVS = tmp1 * (dif_dVS*tmp2 - dVDSS_dVS);
ddeltaV_dVG = tmp1 * (dif_dVG*tmp2 - dVDSS_dVG);
// Vip derivatives:
tmp1 = 1.0 / sqrt_VDSS_deltaV;
tmp2 = 1.0 / sqrt_Vds_VDSS_deltaV;
tmp3 = Vds-VDSS;
dVip_dVD = (VDSS*dVDSS_dVD + ddeltaV_dVD) * tmp1 -
(tmp3 * (0.5-dVDSS_dVD) + ddeltaV_dVD) * tmp2;
dVip_dVS = (VDSS*dVDSS_dVS + ddeltaV_dVS) * tmp1 -
(tmp3 * (-0.5-dVDSS_dVS) + ddeltaV_dVS) * tmp2;
dVip_dVG = (VDSS*dVDSS_dVG + ddeltaV_dVG) * tmp1 -
(tmp3 * -dVDSS_dVG + ddeltaV_dVG) * tmp2;
// VDSSprime derivatives:
tmp1 = Vt * (sqrt_if-1.5)/(4.0*VDSSprime_sqrt*if_);
dVDSSprime_dVD = tmp1 * dif_dVD;
dVDSSprime_dVS = tmp1 * dif_dVS;
dVDSSprime_dVG = tmp1 * dif_dVG;
// Reverse normalized current derivatives:
tmp1 = dirprime_dv * inv_Vt; // mb 95/08/28, 97/04/21
tmp2 = 1.0 / sqrt_VDSSprime_deltaV; // mb 97/04/21
tmp3 = 1.0 / sqrt_Vds_VDSSprime_deltaV;
dirprime_dVD = tmp1 * (dVP_dVD-0.5 -
(VDSSprime*dVDSSprime_dVD+ddeltaV_dVD) * tmp2 +
(Vdsprime*(0.5-dVDSSprime_dVD)+ddeltaV_dVD) * tmp3);
dirprime_dVS = tmp1 * (dVP_dVS-0.5 -
(VDSSprime*dVDSSprime_dVS+ddeltaV_dVS) * tmp2 +
(Vdsprime*(-0.5-dVDSSprime_dVS)+ddeltaV_dVS) * tmp3);
dirprime_dVG = tmp1*(dVP_dVG -
(VDSSprime*dVDSSprime_dVG+ddeltaV_dVG) * tmp2 +
(Vdsprime*(-dVDSSprime_dVG)+ddeltaV_dVG) * tmp3);
// Channel length modulation & mobility reduction derivatives:
// deltaL derivatives:
tmp1 = Lc_LAMBDA / (Lc_UCRIT+Vds-Vip);
ddeltaL_dVD = tmp1 * (0.5-dVip_dVD);
ddeltaL_dVS = tmp1 * (-0.5-dVip_dVS);
ddeltaL_dVG = -tmp1 * dVip_dVG;
// Leq derivatives:
tmp1 = 1.0 / sqrt_Lprime_Lmin; // in fact dLeq_dVX/Leq
dLeq_dVD = tmp1 * (-ddeltaL_dVD + (0.5+dVip_dVD)*inv_UCRIT);
dLeq_dVS = tmp1 * (-ddeltaL_dVS + (-0.5+dVip_dVS)*inv_UCRIT);
dLeq_dVG = tmp1 * (-ddeltaL_dVG + dVip_dVG*inv_UCRIT);
// Transconductance factor derivatives:
tmp1 = dir_dv*inv_Vt;
dir_dVD = tmp1 * (dVP_dVD-1.0);
dir_dVS = tmp1 * dVP_dVS;
dir_dVG = tmp1 * dVP_dVG;
tmp1 = -(1.0+n_1)*Vt*0.66666666/sif_sir_2;
tmp2 = tmp1*(sif+2.0*sir);
tmp3 = tmp1*(sir+2.0*sif);
tmp1 = -n_1*qi/((2.0+n_1+n_1)*VP_PHI_eps);
dQI_dVD = tmp1 * dVP_dVD + tmp2 * dif_dVD + tmp3 * dir_dVD;
dQI_dVS = tmp1 * dVP_dVS + tmp2 * dif_dVS + tmp3 * dir_dVS;
dQI_dVG = tmp1 * dVP_dVG + tmp2 * dif_dVG + tmp3 * dir_dVG;
tmp1 = (1.0+n_1)-qi/(2.0*(1.0+n_1)*VP_PHI_eps);
dQB_dVD = -n_1_n * (tmp1 * dVP_dVD + dQI_dVD);
dQB_dVS = -n_1_n * (tmp1 * dVP_dVS + dQI_dVS);
dQB_dVG = -n_1_n * (tmp1 * dVP_dVG + dQI_dVG);
if (E0 == 0.0) begin
tmp1 = THETA * VPprime / (THETA_VP_1 * sqrt_VP_Vt);
// VPprime derivatives:
dVPprime_dVD = tmp1 * dVP_dVD;
dVPprime_dVS = tmp1 * dVP_dVS;
dVPprime_dVG = tmp1 * dVP_dVG;
dbeta_dVD = -dLeq_dVD - dVPprime_dVD; // in fact dbeta_dVX / beta
dbeta_dVS = -dLeq_dVS - dVPprime_dVS;
dbeta_dVG = -dLeq_dVG - dVPprime_dVG;
end
else begin
tmp1 = T0 / E0_Q_1;
dbeta_dVD = -dLeq_dVD + tmp1 * (dQB_dVD+eta_qi*dQI_dVD);
dbeta_dVS = -dLeq_dVS + tmp1 * (dQB_dVS+eta_qi*dQI_dVS);
dbeta_dVG = -dLeq_dVG + tmp1 * (dQB_dVG+eta_qi*dQI_dVG);
end
// Slope factor derivatives:
tmp1 = -GAMMA_S/(4.0*n*sqrt_PHI_VP*(PHI_T+VP+Vt_4));// mb 95/12/19
dn_dVD = tmp1 * dVP_dVD;
dn_dVS = tmp1 * dVP_dVS;
dn_dVG = tmp1 * dVP_dVG;
// Transconductances:
gds = Ispec*((dn_dVD + dbeta_dVD)*if_ir + dif_dVD - dirprime_dVD);
gms = -Ispec*((dn_dVS + dbeta_dVS)*if_ir + dif_dVS - dirprime_dVS);
gm = Ispec*((dn_dVG + dbeta_dVG)*if_ir + dif_dVG - dirprime_dVG);
gmbs = gms - gm - gds;
// S/D resistance corrections including W and DW
RSeff = (RSH*HDIF)/(Weff-DW);
RDeff = (RSH*HDIF)/(Weff-DW);
tmp1 = 1.0/(1.0 + gms*RSeff + gds*RDeff);
Id = Id*tmp1;
/****** Impact ionization current ******
* mb 95/12/19 introduced impact ionization
* This current component is flowing from the intrinsic drain terminal
* to the bulk (for NMOS) in parallel with the junction current.
* The simulator should also take into account the corresponding
* conductances.
*/
// Substrate current:
Vib = VD-VS-IBN_2*VDSS;
if ((Vib > 0.0) && (IBA_IBB > 0.0)) begin
inv_Vib = 1.0/Vib;
Lc_IBB_Vib = -Lc_IBB*inv_Vib;
if (Lc_IBB_Vib < -35.0) // math precision check
Lc_IBB_Vib = -35.0;
exp_ib = exp(Lc_IBB_Vib);
isub = IBA_IBB*Vib*exp_ib;
Isub = isub*Id;
dIsub_factor = Isub*inv_Vib*(1.0-Lc_IBB_Vib);
end
else begin
Lc_IBB_Vib = 0.0;
Isub = 0.0;
end
// END: substrate current computation
Ibd = Ibd - Isub;
// --- Charge calculations ---
WLCox = Weff * Leff * COX;
sif3 = sif*sif2;
sir3 = sir*sir2;
tmp1 = sqrt(PHI_T + 0.5 * VP);
sqrt_PHI_VP2_2 = tmp1+tmp1;
n_Vt_COX = (1.0 + GAMMAprime/sqrt_PHI_VP2_2) * Vt*WLCox;
QD = -n_Vt_COX*(0.266666666*(3.0*sir3+6.0*sir2*sif+4.0*
sir*sif2+2.0*sif3)/sif_sir_2 - 0.5);
QS = -n_Vt_COX*(0.266666666*(3.0*sif3+6.0*sif2*sir+4.0*
sif*sir2+2.0*sir3)/sif_sir_2 - 0.5);
QI = QS + QD;
QB = WLCox * (-0.5*GAMMAprime*sqrt_PHI_VP_2 + VGprime - VGstar) -
QI*GAMMAprime/(GAMMAprime+sqrt_PHI_VP2_2);
QG = -QI -QB;
I(ds) <+ TYPE * Mode * Id; // wg 22/04/08 corrected for device TYPE
ddt_QD = ddt(QD);
ddt_QS = ddt(QS);
if (Mode == `FWD) begin
I(db) <+ TYPE * ddt_QD; // wg 22/04/08 corrected for device TYPE
I(sb) <+ TYPE * ddt_QS;
I(db) <+ TYPE * Isub;
end
else begin
I(sb) <+ TYPE * ddt_QD; // wg 22/04/08 corrected for device TYPE
I(db) <+ TYPE * ddt_QS;
I(sb) <+ TYPE * Isub;
end
I(gb) <+ TYPE * ddt(QG); // wg 22/04/08 corrected for device TYPE
// if (Noise) begin : Noise //AB: 040902 Noise is also a variable and
if (Noise) begin : Noise_block //AB: 040902 Noise -> Noise_block
real S_flicker, S_thermal;
S_thermal = 4 * `P_K * T * Gn;
S_flicker = KF * gm * gm / (Weff * NS * Leff * COX);
I(ds) <+ white_noise(S_thermal, "thermal") +
flicker_noise(S_flicker, AF, "flicker");
end
///////////////////////////////////
//EXTRINSIC PART: JUNCTION DIODES//
///////////////////////////////////
//diode area and perimeter computation
if ((AS == 0.0) && (HDIF>0.0)) as_i = 2.0*HDIF*Weff;
else as_i = AS;
if ((PS == 0.0) && (HDIF>0.0)) ps_i = 4.0*HDIF+1.0*Weff;
else ps_i = PS;
if ((AD == 0.0) && (HDIF>0.0)) ad_i = 2.0*HDIF*Weff;
else ad_i = AD;
if ((PD == 0.0) && (HDIF>0.0)) pd_i = 4.0*HDIF+1.0*Weff;
else pd_i = PD;
//temperature update for diodes
temp_arg = exp((refEg/$vt(Tnom) - Eg/Vt + tp_xti*ln(ratioT))/xd_n);
js_t = xd_js*temp_arg;
jsw_t = xd_jsw*temp_arg;
jswg_t = xd_jswg*temp_arg;
pb_t = xd_pb - tp_pb*deltaT;
pbsw_t = xd_pbsw - tp_pbsw*deltaT;
pbswg_t = xd_pbswg - tp_pbswg*deltaT;
cj_t = xd_cj*(1.0+tp_cj*deltaT);
cjsw_t = xd_cjsw*(1.0+tp_cjsw*deltaT);
cjswg_t = xd_cjswg*(1.0+tp_cjswg*deltaT);
njts_t = xd_njts*(1.0+(ratioT-1.0)*tp_njts);
njtssw_t = xd_njtssw*(1.0+(ratioT-1.0)*tp_njtssw);
njtsswg_t = xd_njtsswg*(1.0+(ratioT-1.0)*tp_njtsswg);
//DC
v_di_b = TYPE*V(d,b);
v_si_b = TYPE*V(s,b);
//DRAIN - BULK
is_d = js_t*ad_i+jsw_t*pd_i+jswg_t*Weff;
arg_d = -v_di_b*ratioT/(Vt*xd_n);
if (arg_d < -40.0) arg_d = -40.0;
tmp0 = (-v_di_b+xd_bv)*ratioT/(Vt*xd_n);
if (tmp0>70) f_breakdown_d = 1.0;
else f_breakdown_d = 1.0 + xd_xjbv*exp(-tmp0);
// TRAP-ASSISTED TUNNELING CURRENT
idb_tun = -Weff*jswg_t*(exp(v_di_b*ratioT/(Vt*njtsswg_t) * xd_vtsswg/max(xd_vtsswg+v_di_b,1.0e-3))-1.0);
idb_tun = idb_tun - pd_i*jsw_t*(exp(v_di_b*ratioT/(Vt*njtssw_t) * xd_vtssw/max(xd_vtssw+v_di_b,1.0e-3))-1.0);
idb_tun = idb_tun - ad_i*js_t*(exp(v_di_b*ratioT/(Vt*njts_t) * xd_vts/max(xd_vts+v_di_b,1.0e-3))-1.0);
I(d,b) <+ (is_d * (1.0 - exp(arg_d))*f_breakdown_d+v_di_b*xd_gmin + idb_tun)*TYPE*M;
//SOURCE - BULK
is_s = js_t*as_i+jsw_t*ps_i+jswg_t*Weff;
arg_s = -v_si_b*ratioT/(Vt*xd_n);
if (arg_s < -40.0) arg_s = -40.0;
tmp0 = (-v_si_b+xd_bv)*ratioT/(Vt*xd_n);
if (tmp0>70) f_breakdown_s = 1.0;
else f_breakdown_s = 1.0 + xd_xjbv*exp(-tmp0);
// TRAP-ASSISTED TUNNELING CURRENT
isb_tun = -Weff*jswg_t*(exp(v_si_b*ratioT/(Vt*njtsswg_t) * xd_vtsswg/max(xd_vtsswg+v_si_b,1.0e-3))-1.0);
isb_tun = isb_tun - ps_i*jsw_t*(exp(v_si_b*ratioT/(Vt*njtssw_t) * xd_vtssw/max(xd_vtssw+v_si_b,1.0e-3))-1.0);
isb_tun = isb_tun - as_i*js_t*(exp(v_si_b*ratioT/(Vt*njts_t) * xd_vts/max(xd_vts+v_si_b,1.0e-3))-1.0);
I(s,b) <+ (is_s * (1.0 - exp(arg_s))*f_breakdown_s+v_si_b*xd_gmin + isb_tun)*TYPE*M;
//AC
//DRAIN - BULK
if (v_di_b>0.0)
begin
csb_d = cj_t * ad_i * exp(-xd_mj*ln(1.0+v_di_b/pb_t));
cssw_d = cjsw_t * pd_i * exp(-xd_mjsw*ln(1.0+v_di_b/pbsw_t));
csswg_d = cjswg_t * Weff * exp(-xd_mjswg*ln(1.0+v_di_b/pbswg_t));
end
else
begin
csb_d = cj_t * ad_i * (1.0 - xd_mj*v_di_b/pb_t);
cssw_d = cjsw_t * pd_i * (1.0 - xd_mjsw*v_di_b/pbsw_t);
csswg_d = cjswg_t * Weff * (1.0 - xd_mjswg*v_di_b/pbswg_t);
end
qjd = (csb_d+cssw_d+csswg_d) * v_di_b;
I(d,b) <+ ddt(qjd)*TYPE*M;
//SOURCE - BULK
if (v_si_b>0.0)
begin
csb_s = cj_t * as_i * exp(-xd_mj*ln(1.0+v_si_b/pb_t));
cssw_s = cjsw_t * ps_i * exp(-xd_mjsw*ln(1.0+v_si_b/pbsw_t));
csswg_s = cjswg_t * Weff * exp(-xd_mjswg*ln(1.0+v_si_b/pbswg_t));
end
else
begin
csb_s = cj_t * as_i * (1.0 - xd_mj*v_si_b/pb_t);
cssw_s = cjsw_t * ps_i * (1.0 - xd_mjsw*v_si_b/pbsw_t);
csswg_s = cjswg_t * Weff * (1.0 - xd_mjswg*v_si_b/pbswg_t);
end
qjs = (csb_s+cssw_s+csswg_s) * v_si_b;
I(s,b) <+ ddt(qjs)*TYPE*M;
//END OF DIODES
end
endmodule

View File

@ -0,0 +1,27 @@
OSDI EKV 2.6 NMOS Test
*.options abstol=1e-15
* one voltage source per MOS terminal:
VD dd 0 1
VG gg 0 1
VS ss 0 0
VB bb 0 0
* model definitions:
*.model .MODEL NCH EKV_VA type=1
.include Modelcards/ekv26_0u5.par
*OSDI EKV:
N1 dd gg ss bb nch W=5e-6 L=0.5e-6
.control
pre_osdi test_osdi_win/ekv26_mod.osdi
set xbrushwidth=3
* a DC sweep: drain, gate
dc Vd 0 1.6 0.01 VG 0 1.6 0.2
* plot source current
plot i(VS)
.endc
.end

View File

@ -0,0 +1,28 @@
OSDI EKV 2.6 PMOS Test
*.options abstol=1e-15
* one voltage source per MOS terminal:
VD dd 0 -1
VG gg 0 -1
VS ss 0 0
VB bb 0 0
* model definitions:
*.model .MODEL PCH EKV_VA type=-1
.include Modelcards/ekv26_0u5.par
*OSDI EKV:
N1 dd gg ss bb pch W=5e-6 L=5e-7
.control
pre_osdi test_osdi_win/ekv26_mod.osdi
set xbrushwidth=3
* a DC sweep: drain, gate
*op
dc Vd 0 -1.8 -0.01 VG 0 -1.8 -0.2
* plot source current
plot i(VS)
.endc
.end

View File

@ -0,0 +1 @@
Place ekv26_mod.osdi here.

59
examples/osdi/README Normal file
View File

@ -0,0 +1,59 @@
A 'quick and dirty' howto for OpenVAF and OSDI:
Example BSIMBULK
Tested under MS Windows 10
Have OpenVAF compiler available.
Sources will be available soon.
Download BSIMBULK model from http://www.bsim.berkeley.edu/models/bsimbulk/
Open bsimbulk.va in a text editor
Search for the module name, here:
module bsimbulk(d, g, s, b, t);
The module name 'bsimbulk' will become the new model type in the .model statement
.model mname type ( pname1 = pval1 pname2 = pval2 ... ).
Compile bsimbulk.va with OpenVAF to obtain bsimbulk.osdi
Put bsimbulk.osdi into directory bsimbulk/test_osdi_win
Search for suitable model parameters
BSIMBULK107 distro does not contain any parameters
BSIMBULK106 does contain a model parameter file model.l among the benchmark tests
Put model.l into directory bsimbulk/Modelcards
Edit model.l:
Check if model type is 'bsimbulk' (it is already)
Choose a model name for mname (nch or pch may be o.k., or BSIMBULK_osdi_N or ...)
There are NMOS and PMOS parameters in the same file here.
Create a ngspice netlist in directory bsimbulk, e.g. bb_IDvsVG.cir.
*** BSIMBULK107 Id versus Vgs ***
* the voltage sources
Vd dd 0 50m
Vg gg 0 1
Vs ss 0 0
Vb bb 0 0
* load the model parameter sets
.include Modelcards/model.l
* the call to the transistor (OSDI devices always start with N !)
NMN1 dd gg ss bb BSIMBULK_osdi_N W=500n L=90n
* the .control section
.control
* load the model dynamically
pre_osdi test_osdi_win/bsimbulk107.osdi
* the dc simulation
dc Vg 0 1.5 0.01 Vb 0 -1.6 -0.4
* plotting
set xbrushwidth=3
plot I(Vs)
.endc
.end
*********************************
So we have two OSDI specific actions in the netlist:
load the model by
pre_osdi test_osdi_win/bsimbulk107.osdi
instantiate the transistor by
NMN1 dd gg ss bb BSIMBULK_osdi_N W=500n L=90n

View File

@ -0,0 +1,641 @@
* model parameters fron BSIMBULK 106.2
.model BSIMBULK_osdi_N bsimbulk
+level=77
+TYPE = 1
+GEOMOD = 0
+RGEOMOD = 0
+COVMOD = 1
+RDSMOD = 0
+GIDLMOD = 1
+IGCMOD = 0
+IGBMOD = 0
+LLONG = 2e-6
+WWIDE = 1e-5
+XL = -1.7e-8
+XW = 1.1e-8
+LINT = 0
+WINT = 0
+DLC = 0
+DWC = 0
+TOXE = 1.74e-9
+TOXP = 1.7e-9
+NDEP = 4.6e23
+NSD = 1e26
+NGATE = 8.5e25
+VFB = -1.02
+EPSROX = 3.9
+EPSRSUB = 11.9
+NI0SUB = 1.1e16
+XJ = 1.5e-7
+DMCG = 0
+DMDG = 0
+DMCGT = 0
+CIT = 1e-8
+CDSCD = 0.001
+CDSCB = 0
+CDSCBL = 0.007
+CDSCBLEXP = 1
+NFACTOR = 0.002
+NFACTORL = 2.1e-8
+NFACTORLEXP = 6.264
+NDEPL1 = 0.096
+NDEPLEXP1 = 1
+NDEPL2 = -0.0032
+NDEPLEXP2 = 2.05
+DVTP0 = 7.5e-7
+DVTP1 = -4.4e-7
+NDEPW = -0.1548
+NDEPWEXP = 0.7441
+NDEPWL = 0
+NDEPWLEXP = 0.2
+K2W = 0
+AGIDL = 3.728e-8
+AGIDLL = -0.04815
+AGIDLW = -0.0341
+BGIDL = 8.123e9
+CGIDL = 1.21e-6
+EGIDL = -2.952
+PHIN = 0.05
+K2L = 0.001636
+K2 = -0.014
+ETA0 = 8.416e-6
+ETAB = -5.561e-5
+ETABEXP = 2.155
+DSUB = 3
+VSAT = 6.4e4
+VSATW = 0.05
+VSATWEXP = 1
+DELTA = 0.15
+DELTAL = 0.1
+DELTALEXP = 1e-5
+U0 = 0.04546
+ETAMOB = 1.5
+U0L = 0.025
+U0LEXP = 0.95
+UA = 0.4007
+UAW = 0.05
+UAWEXP = 1
+UAL = 0.00475
+UALEXP = 1.118
+EUW = -0.02
+EUWEXP = 1
+EUL = 0.001
+EULEXP = 1
+EU = 1.9
+UDL = 1e-15
+UDLEXP = 1
+UD = 1.042e-5
+UCS = 2
+UCW = 0
+UCWEXP = 1
+UC = 1e-07
+UCL = 2.5e4
+UCLEXP = 1
+PCLM = 0.15
+PCLML = 0.01
+PCLMLEXP = 0.4
+PCLMG = 0
+PSCBE1 = 5
+PSCBE2 = 1.29e-12
+PDITS = 0
+PDITSL = 0
+PDITSD = 0
+RSWMIN = 0
+RSW = 100
+RDWMIN = 0
+RDW = 100
+RDSW = 20
+RDSWMIN = 0
+PRWG = 1
+PRWB = 0
+WR = 1
+RSH = 0
+PDIBLCB = 0
+PDIBLC = 0.01
+PDIBLCL = 1e-5
+PDIBLCLEXP = 1e-6
+PVAG = 0
+PTWG = 0.2
+PTWGL = 3e4
+PTWGLEXP = 5e-6
+FPROUT = 0
+CF = 0
+CFRCOEFF = 1
+CGSO = 2.5e-10
+CGDO = 2.5e-10
+CGSL = 1.2e-10
+CGDL = 1.2e-10
+CKAPPAS = 1.25
+CKAPPAD = 1.25
+CGBO = 0
+ADOS = 0
+BDOS = 1
+QM0 = 0.001
+ETAQM = 0.54
+NDEPCV = 8e23
+VFBCV = -0.95
+VSATCV = 1e5
+PCLMCV = 0
+PSAT = 0.46
+PSATL = 6
+PSATLEXP = 0.06
+TNFACTOR = 0
+TETA0 = 0
+UTE = -1.4
+UTEL = -0.001
+UA1 = -0.0011
+UA1L = 0
+UC1 = 0
+UD1 = 0
+UD1L = 0
+UCSTE = -0.005
+PRT = 0
+AT = -0.05
+ATL = -0.1
+TDELTA = -0.0048
+PTWGT = -0.002
+PTWGTL = 0.01
+KT1 = -0.115
+KT1EXP = 1
+KT1L = 1.286e-9
+KT2 = -0.003157
+K2LEXP = 1.698
+K2WEXP = 0.005
+TBGASUB = 0
+AIGS = 0.0136
+BIGS = 0.00171
+CIGS = 0.075
+AIGSL = 0
+AIGD = 0.0136
+BIGD = 0.00171
+CIGD = 0.075
+AIGDL = 0
+AIGC = 0.01285
+LAIGC = 2.132e-6
+BIGC = 0.0013
+CIGC = 0.013
+AIGCL = -0.01227
+PIGCD = 1
+PIGCDL = 6.196
+AIGBINV = 0.015
+BIGBINV = 0.000949
+CIGBINV = 0.006
+EIGBINV = 1.1
+NIGBINV = 3
+AIGBACC = 0.01751
+BIGBACC = 8.307
+CIGBACC = -898.7
+NIGBACC = 1
+LPSAT = 0
+WPSAT = 0
+PPSAT = 0
+PSATB = 0
+PSATX = 3
+WVSAT = 0
+PVSAT = 0
+WPTWG = 0
+PPTWG = 0
+TNOM = 25
+WDVTP0 = 0
+WDVTP1 = 0
+LUTE = 0.04574
+LUA1 = 8.365e-5
+LAT = 0
+DVTP2 = 0
+DVTP3 = 0
+DVTP4 = 0
+DVTP5 = 0
+VSATL = 1350
+VSATLEXP = 0.00033
+SCA = 0
+SCB = 0
+SCC = 0
+SC = 0
.model BSIMBULK_osdi_P bsimbulk
+level=77
+TYPE = -1
+GEOMOD = 0
+RGEOMOD = 0
+RGATEMOD = 0
+RBODYMOD = 0
+IGCMOD = 0
+IGBMOD = 0
+COVMOD = 1
+RDSMOD = 2
+GIDLMOD = 0
+TNOIMOD = 0
+SHMOD = 0
+TOXE = 2.34e-9
+TOXP = 1.925e-9
+DTOX = 0
+EPSROX = 3.9
+TNOM = 25
+XL = 0
+XW = 0
+LINT = 0
+LLONG = 1000000
+LL = 0
+LW = 0
+LWL = 0
+LLN = 1
+LWN = 1
+WINT = -9.0134104e-9
+WL = 0
+WW = 0
+WWL = 0
+WLN = 1
+WWN = 1
+WWIDE = 1000000
+DLC = 0
+LLC = 0
+LWC = 0
+LWLC = 0
+DWC = 0
+WLC = 0
+WWC = 0
+WWLC = 0
+JSS = 0.0001
+JSD = 0.0001
+JSWS = 0
+JSWD = 0
+JSWGS = 0
+JSWGD = 0
+NJS = 1
+NJD = 1
+IJTHSFWD = 0.1
+IJTHDFWD = 0.1
+IJTHSREV = 0.1
+IJTHDREV = 0.1
+BVS = 10
+BVD = 10
+XJBVS = 1
+XJBVD = 1
+JTSS = 0
+JTSD = 0
+JTSSWS = 0
+JTSSWD = 0
+JTSSWGS = 0
+JTSSWGD = 0
+JTWEFF = 0
+NJTS = 20
+NJTSD = 20
+NJTSSW = 20
+NJTSSWD = 20
+NJTSSWG = 20
+NJTSSWGD = 20
+VTSS = 10
+VTSD = 10
+VTSSWS = 10
+VTSSWD = 10
+VTSSWGS = 10
+VTSSWGD = 10
+CJS = 0.0005
+CJD = 0.0005
+CJSWS = 5e-10
+CJSWD = 5e-10
+CJSWGS = 0
+CJSWGD = 0
+PBS = 1
+PBD = 1
+PBSWS = 1
+PBSWD = 1
+PBSWGS = 1
+PBSWGD = 1
+MJS = 0.5
+MJD = 0.5
+MJSWS = 0.33
+MJSWD = 0.33
+MJSWGS = 0.33
+MJSWGD = 0.33
+TPB = 0
+TCJ = 0
+TPBSW = 0
+TCJSW = 0
+TPBSWG = 0
+TCJSWG = 0
+XTIS = 3
+XTID = 3
+XTSS = 0.02
+XTSD = 0.02
+XTSSWS = 0.02
+XTSSWD = 0.02
+XTSSWGS = 0.02
+XTSSWGD = 0.02
+TNJTS = 0
+TNJTSD = 0
+TNJTSSW = 0
+TNJTSSWD = 0
+TNJTSSWG = 0
+TNJTSSWGD = 0
+NOIA = 6.25e40
+NOIB = 3.125e25
+NOIC = 8.75e8
+EM = 41000000
+EF = 1
+LINTNOI = 0
+NTNOI = 1
+TNOIA = 0
+TNOIB = 0
+TNOIC = 0
+RNOIA = 0.577
+RNOIB = 0.5164
+RNOIC = 0.395
+DWJ = 0
+DMCG = 0
+DMCI = 0
+DMDG = 0
+DMCGT = 0
+XGW = 0
+XGL = 0
+GBMIN = 1e-12
+RSHG = 0.1
+RBPB = 50
+RBPD = 50
+RBPS = 50
+RBDB = 50
+RBSB = 50
+RBPS0 = 50
+RBPSL = 0
+RBPSW = 0
+RBPSNF = 0
+RBPD0 = 50
+RBPDL = 0
+RBPDW = 0
+RBPDNF = 0
+RBPBX0 = 100
+RBPBXL = 0
+RBPBXW = 0
+RBPBXNF = 0
+RBPBY0 = 100
+RBPBYL = 0
+RBPBYW = 0
+RBPBYNF = 0
+RBSBX0 = 100
+RBSBY0 = 100
+RBDBX0 = 100
+RBDBY0 = 100
+RBSDBXL = 0
+RBSDBXW = 0
+RBSDBXNF = 0
+RBSDBYL = 0
+RBSDBYW = 0
+RBSDBYNF = 0
+XRCRG1 = 12
+XRCRG2 = 1
+NGCON = 1
+NDEP = 8.062e23
+NDEPL1 = 1.2139
+NDEPLEXP1 = 1.9088
+NDEPL2 = -1.1825
+NDEPLEXP2 = 1.9173
+NDEPW = 0.065035
+NDEPWEXP = 0.48882
+NDEPWL = 0.00040893
+NDEPWLEXP = 1.3273
+EASUB = 4.05
+NI0SUB = 1.1e16
+BG0SUB = 1.17
+EPSRSUB = 11.9
+XJ = 1.5e-7
+VFB = -1.2108
+VFBSDOFF = 0
+NSD = 1e26
+DVTP0 = 1.8335e-7
+DVTP1 = 220.59
+DVTP2 = 9.6351e-10
+DVTP3 = 0.89017
+DVTP4 = 98.728
+DVTP5 = 5.1435e-17
+PHIN = 0.045
+ETA0 = 0.0051075
+ETAB = -0.010908157
+ETABEXP = 0.09999
+DSUB = 1.0667
+K2 = -0.093146
+K2L = 0.065574
+K2LEXP = 0.79778
+K2W = 0.030809
+K2WEXP = 0.87253
+CIT = 1.0136148e-5
+CDSCD = 0.0011509049
+CDSCDL = -0.00048388809
+CDSCDLEXP = 0.13963388
+CDSCB = 9.9995516e-6
+CDSCBL = 1.4756534e-9
+CDSCBLEXP = 1
+NFACTOR = 0.0017201
+NFACTORL = 1.7832e-6
+NFACTORLEXP = 0.99988
+NFACTORW = 0.11149
+NFACTORWEXP = 0.8993
+NFACTORWL = -0.01386
+U0 = 0.04004
+U0L = 0.58676
+U0LEXP = 0.11151
+ETAMOB = 4.0947
+UA = 0.4298
+UAL = -0.0087246
+UALEXP = 1.3647
+UAW = 0.11575
+UAWEXP = 0.4385
+UAWL = -7.027e-5
+EU = 1.3371
+EUL = 0.0021948
+EULEXP = 1.4769
+EUW = -0.0031666
+EUWEXP = 1.9366
+EUWL = -0.00013929
+UD = 0.0093995
+UDL = 0.067484
+UDLEXP = 0.099452
+UCS = 0.9999
+UC = 4.91e-6
+UCL = 0.001096
+UCLEXP = 0.0015937
+VSAT = 9609100
+VSATL = 6.8282
+VSATLEXP = 0.086396
+VSATW = 0.016834
+VSATWEXP = 3.0172
+VSATCVL = 0
+VSATCVLEXP = 1
+VSATCVW = 0
+VSATCVWEXP = 1
+DELTA = 0.1779
+DELTAL = 0.1269
+DELTALEXP = 0.18156
+PCLM = 0
+PCLML = 0
+PCLMLEXP = 1e-13
+PCLMG = 0
+PCLMCVL = 0
+PCLMCVLEXP = 1
+PSCBE1 = 4.24e8
+PSCBE2 = 1e-8
+PDITS = 0.85536
+PDITSL = 8473.9
+PDITSD = 0
+PDIBLC = 0.005
+PDIBLCL = 0
+PDIBLCLEXP = 1
+PDIBLCB = -0.49995
+PVAG = 1
+FPROUT = 0
+FPROUTL = 0
+FPROUTLEXP = 1
+PTWG = 0.09999
+PTWGL = 0.069993
+PTWGLEXP = 0.0009999
+PSAT = 1e-13
+PSATL = 0
+PSATLEXP = 1
+PSATB = 0.9999
+PSATX = 1e-13
+RSH = 0
+PRWG = 1
+PRWB = 0.010098993
+PRWBL = 0.00070000265
+PRWBLEXP = 1
+WR = 1
+RSWMIN = 0
+RSW = 10
+RSWL = 0
+RSWLEXP = 1
+RDWMIN = 0
+RDW = 10
+RDWL = 0
+RDWLEXP = 1
+RDSWMIN = 0
+RDSW = 0
+RDSWL = 0.0007
+RDSWLEXP = 1e-7
+ALPHA0 = 0
+ALPHA0L = 0
+ALPHA0LEXP = 1
+BETA0 = 0
+AGIDL = 0
+AGIDLL = 0
+AGIDLW = 0
+BGIDL = 2.3e9
+CGIDL = 0.5
+EGIDL = 0.8
+AGISL = 0
+AGISLL = 0
+AGISLW = 0
+BGISL = 2.3e9
+CGISL = 0.5
+EGISL = 0.00171
+AIGBACC = 0.00171
+BIGBACC = 0.00171
+CIGBACC = 0.075
+NIGBACC = 1
+AIGBINV = 0.0111
+BIGBINV = 0.000949
+CIGBINV = 0.006
+EIGBINV = 1.1
+NIGBINV = 3
+AIGC = 0.0136
+AIGCL = 3
+AIGCW = 0.0136
+BIGC = 0.00171
+CIGC = 0.075
+AIGS = 0.0136
+AIGSL = 0.075
+AIGSW = 0.0136
+AIGD = 0.0136
+AIGDL = 0
+AIGDW = 0.0136
+BIGS = 0.00171
+BIGD = 0.00171
+CIGS = 0.075
+CIGD = 0.075
+TOXREF = 0.075
+NTOX = 1
+POXEDGE = 1
+PIGCD = 1
+PIGCDL = 1
+NDEPCV = 4.598e23
+NDEPCVL1 = 0
+NDEPCVLEXP1 = 1
+NDEPCVL2 = 0
+NDEPCVLEXP2 = 2
+NDEPCVW = 0
+NDEPCVWEXP = 1
+NDEPCVWL = 0
+NDEPCVWLEXP = 1
+NGATE = 7.764e25
+CF = 0
+CFRCOEFF = 1
+CGSO = 187.0e-12
+CGDO = 187.0e-12
+CGBO = 0
+CGSL = 130.0e-12
+CGDL = 130.0e-12
+CKAPPAS = 1.6
+CKAPPAD = 1.6
+ADOS = 221.4
+BDOS = 1.350
+QM0 = 405.7e-6
+ETAQM = 848.5e-3
+VFBCV = -996.0e-3
+VFBCVL = 0
+VFBCVLEXP = 1
+VFBCVW = 0
+VFBCVWEXP = 1
+VFBCVWL = 0
+VFBCVWLEXP = 1
+TBGASUB = 0.000473
+TBGBSUB = 636
+TDELTA = 0
+PTWGT = 0
+IIT = 0
+TGIDL = 0
+IGT = 0
+KT1 = -0.11
+KT1L = 0
+KT2 = 0.022
+KT1EXP = 1
+UTE = -1.5
+UA1 = 0.001
+UD1 = 0
+UC1 = -5.6e-11
+UCSTE = -0.004775
+PRT = 0
+AT = -0.00156
+SCA = 0
+SCB = 0
+SCC = 0
+SC = 0
+KU0WE = 0
+KVTH0WE = 0
+K2WE = 0
+WEB = 0
+WEC = 0
+SCREF = 1e-6
+SA = 0
+SB = 0
+SD = 0
+SAREF = 1e-6
+SBREF = 1e-6
+WLOD = 0
+KVSAT = 0
+KU0 = 0
+TKU0 = 0
+LKU0 = 0
+WKU0 = 0
+PKU0 = 0
+LLODKU0 = 0
+WLODKU0 = 0
+KVTH0 = 0
+LKVTH0 = 0
+WKVTH0 = 0
+PKVTH0 = 0
+LLODVTH = 0
+WLODVTH = 0
+STK2 = 0
+LODK2 = 1
+STETA0 = 0
+LODETA0 = 1
+RTH0 = 1e7
+MOBSCALE = 1

View File

@ -0,0 +1,40 @@
* BSIMBULK model vers. 107
* simple inverter
.param Vcc = 1.2
.csparam vcc='Vcc'
* Path to the models
.include Modelcards/model.l
* the voltage sources:
Vdd vdd gnd DC 'Vcc'
V1 in gnd pulse(0 'Vcc' 0p 200p 100p 1n 2n)
Vmeas vss 0 0
Xnot1 in vdd vss out not1
*Rout out 0 1k
.subckt not1 a vdd vss z
Np1 z a vdd vdd BSIMBULK_osdi_P l=0.1u w=1u as=0.26235p ad=0.26235p ps=2.51u pd=2.51u
Nn1 z a vss vss BSIMBULK_osdi_N l=0.1u w=0.5u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u
c3 a vss 0.384f
c2 z vss 0.576f
.ends
* simulation command:
.tran 10ps 10ns
.dc V1 0 'vcc' 'vcc/100'
.control
pre_osdi test_osdi_win/bsimbulk107.osdi
run
*set nolegend
set xbrushwidth=3
plot in out
plot dc1.out
plot dc1.i(Vmeas)
rusage
.endc
.end

View File

@ -0,0 +1,41 @@
* BSIMBULK model vers. 107
* simple 5-stage ring oscillator
.param Vcc = 1.2
.csparam vcc='Vcc'
* Path to the models
.include Modelcards/model.l
* the voltage sources:
Vdd vdd gnd DC 'Vcc'
V1 in gnd pulse(0 'Vcc' 0p 200p 100p 1n 2n)
Vmeas vss 0 0
Xnot1 in vdd vss in2 not1
Xnot2 in2 vdd vss in3 not1
Xnot3 in3 vdd vss in4 not1
Xnot4 in4 vdd vss in5 not1
Xnot5 in5 vdd vss in not1
*Rout out 0 1k
.subckt not1 a vdd vss z
Np1 z a vdd vdd BSIMBULK_osdi_P l=0.1u w=1u as=0.26235p ad=0.26235p ps=2.51u pd=2.51u
Nn1 z a vss vss BSIMBULK_osdi_N l=0.1u w=0.5u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u
c3 a vss 0.384f
c2 z vss 0.576f
.ends
* simulation command:
.tran 10p 10n uic
.control
pre_osdi test_osdi_win/bsimbulk107.osdi
run
set xbrushwidth=3
plot in
rusage
.endc
.end

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
OSDI BSIMBULK NMOS Test
*.options abstol=1e-15
* one voltage source per MOS terminal:
VD dd 0 1
VG gg 0 1
VS ss 0 0
VB bb 0 0
* model definitions:
*.model BSIMBULK_osdi_N bsimbulk type=1
.include Modelcards/model.l
*OSDI BSIMBULK:
N1 dd gg ss bb BSIMBULK_osdi_N W=500n L=90n
.control
pre_osdi test_osdi_win/bsimbulk107.osdi
set xbrushwidth=3
* a DC sweep: drain, gate
dc Vd 0 1.6 0.01 VG 0 1.6 0.2
* plot source current
plot i(VS)
.endc
.end

View File

@ -0,0 +1,29 @@
OSDI BSIMBULK PMOS Test
*.options abstol=1e-15
* one voltage source per MOS terminal:
VD dd 0 -1
VG gg 0 -1
VS ss 0 0
VB bb 0 0
* model definitions:
*.model BSIMBULK_osdi_P bsimbulk type=-1
.include Modelcards/model.l
*OSDI BSIMBULK:
*
N1 dd gg ss bb BSIMBULK_osdi_P W=500n L=90n
.control
pre_osdi test_osdi_win/bsimbulk107.osdi
set xbrushwidth=3
* a DC sweep: drain, gate
*op
dc Vd 0 -1.8 -0.01 VG 0 -1.8 -0.2
* plot source current
plot i(VS)
.endc
.end

View File

@ -0,0 +1,45 @@
*** NMOS and PMOS transistors BSIMBULK (Id-Vgs, Vbs) (Id-Vds, Vgs) (Id-Vgs, T) ***
Nn1 2 1 3 4 BSIMBULK_osdi_N l=0.1u w=0.5u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u
vgsn 1 0 3.5
vdsn 2 0 0.1
vssn 3 0 0
vbsn 4 0 0
Np1 22 11 33 44 BSIMBULK_osdi_P l=0.1u w=1u as=0.26235p ad=0.26235p ps=2.51u pd=2.51u
vgsp 11 0 -3.5
vdsp 22 0 -0.1
vssp 33 0 0
vbsp 44 0 0
* BSIMBULK modelparameters for BSIMBULK106, Berkeley
.include Modelcards/model.l
.control
* Load the models dynamically
pre_osdi test_osdi_win/bsimbulk107.osdi
set xgridwidth=2
set xbrushwidth=3
* NMOS
dc vgsn 0 1.5 0.05 vbsn 0 -1.5 -0.3
plot vssn#branch ylabel 'Id vs. Vgs, Vbs 0 ... -1.5'
plot abs(vssn#branch) ylog ylabel 'Id vs. Vgs, Vbs 0 ... -1.5'
dc vdsn 0 1.6 0.01 vgsn 0 1.6 0.2
plot vssn#branch ylabel 'Id vs. Vds, Vgs 0 ... 1.6'
dc vgsn 0 1.5 0.05 temp -40 160 40
plot vssn#branch ylabel 'Id vs. Vds, Temp. -40 ... 160'
plot abs(vssn#branch) ylog ylabel 'Id vs. Vds, Temp. -40 ... 160'
* PMOS
dc vgsp 0 -1.5 -0.05 vbsp 0 1.5 0.3
plot vssp#branch ylabel 'Id vs. Vgs, Vbs 0 ... 1.5'
plot abs(vssp#branch) ylog ylabel 'Id vs. Vgs, Vbs 0 ... 1.5'
dc vdsp 0 -1.6 -0.01 vgsp 0 -1.6 -0.2
plot vssp#branch ylabel 'Id vs. Vds, Vgs 0 ... -1.6'
dc vgsp 0 -1.5 -0.05 temp -40 160 40
plot vssp#branch ylabel 'Id vs. Vds, Temp. -40 ... 160'
plot abs(vssp#branch) ylog ylabel 'Id vs. Vds, Temp. -40 ... 160'
.endc
.end

View File

@ -0,0 +1 @@
Place bsimbulk107.osdi here.

View File

@ -0,0 +1,137 @@
******** BSIM-MG 105 Sample Modelcard for NMOS ********
** The BSIM-MG sample modelcard below was not extracted/obtained
** from/based on any real technologies. It should not be used for any
** other purposes except for benchmarking the implementation of BSIM-MG
** against BSIM Team's standard results
.model BSIMCMG_osdi_N BSIMCMG_va
+ BULKMOD = 1
+ CGEOMOD = 0
+ TYPE = 1
+ GEOMOD = 0
+ GIDLMOD = 1
+ IGBMOD = 0
+ IGCMOD = 1
+ IIMOD = 0
+ NGATE = 0
+ NQSMOD = 0
+ RDSMOD = 0
+ RGATEMOD = 0
+ RGEOMOD = 0
+ NSEG = 5
+ SDTERM = 0
+ SHMOD = 0
+ AGIDL = 1.00E-12
+ AGISL = 1.00E-12
+ AIGC = 0.014
+ AIGD = 0.0115
+ AIGS = 0.0115
+ AT = 0.001
+ BG0SUB = 1.17
+ BGIDL = 1.00E+07
+ BGISL = 1.00E+07
+ BIGC = 0.005
+ BIGD = 0.00332
+ BIGS = 0.00332
+ CDSC = 0.01
+ CDSCD = 0.01
+ CFD = 0.20E-10
+ CFS = 0.20E-10
+ CGBL = 0
+ CGBO = 0
+ CGDL = 0
+ CGDO = 1e-10
+ CGSL = 0
+ CGSO = 1e-10
+ CIGC = 0.25
+ CIGD = 0.35
+ CIGS = 0.35
+ CIT = 0
+ CKAPPAD = 0.6
+ CKAPPAS = 0.6
+ CTH0 = 0.000001243
+ DELTAVSAT = 0.5
+ DELTAW = 0
+ DELTAWCV = 0
+ DLBIN = 0
+ DLC = 0
+ DLCIGD = 1.00E-09
+ DLCIGS = 1.00E-09
+ DROUT = 1
+ DSUB = 0.5
+ DVT0 = 0.05
+ DVT1 = 0.5
+ DVTSHIFT = 0
+ EASUB = 4.05
+ EGIDL = 0.35
+ EGISL = 0.35
+ EOT = 1.50E-09
+ EOTACC = 1.00E-10
+ EOTBOX = 1.40E-07
+ EPSROX = 3.9
+ EPSRSP = 3.9
+ EPSRSUB = 11.9
+ ETA0 = 0.05
+ ETAMOB = 2
+ ETAQM = 0.54
+ EU = 1.2
+ HFIN = 3.00E-08
+ IGT = 2.5
+ K1RSCE = 0
+ KSATIV = 2
+ KT1 = 0
+ KT1L = 0
+ LINT = -2.00E-09
+ LPE0 = 0
+ LCDSCD = 5.00E-05
+ LCDSCDR = 5.00E-05
+ LRDSW = 0.2
+ LVSAT = 0
+ MEXP = 4
+ NBODY = 1.00E+22
+ NC0SUB = 2.86E+25
+ NI0SUB = 1.10E+16
+ NSD = 2.00E+26
+ PCLM = 0.05
+ PCLMCV = 0.013
+ PCLMG = 0
+ PDIBL1 = 0
+ PDIBL2 = 0.002
+ PHIG = 4.39
+ PHIN = 0.05
+ POXEDGE = 1.1
+ PQM = 0.66
+ PRT = 0
+ PTWG = 0
+ PTWGT = 0.004
+ PVAG = 0
+ QM0 = 0.001
+ QMFACTOR = 2.5
+ RDSW = 200
+ RDSWMIN = 0
+ RDWMIN = 0
+ RSHD = 0
+ RSHS = 0
+ RSWMIN = 0
+ RTH0 = 0.225
+ TBGASUB = 0.000473
+ TBGBSUB = 636
+ TGIDL = -0.007
+ TMEXP = 0
+ TNOM = 25
+ TOXP = 2.10E-09
+ U0 = 0.025
+ UA = 0.55
+ UA1 = 0.001032
+ UCS = 1
+ UCSTE = -0.004775
+ UD = 0
+ UD1 = 0
+ UP = 0
+ UTE = -0.7
+ UTL = 0
+ VSAT = 80000
+ WR = 1
+ WTH0 = 2.60E-07
+ XL = 0

View File

@ -0,0 +1,138 @@
******** BSIM-MG 105 Sample Modelcard for PMOS ********
** The BSIM-MG sample modelcard below was not extracted/obtained
** from/based on any real technologies. It should not be used for any
** other purposes except for benchmarking the implementation of BSIM-MG
** against BSIM Team's standard results
*.model pmos1 PMOS level=17
.model BSIMCMG_osdi_P BSIMCMG_va
+BULKMOD = 1
+ CGEOMOD = 0
+ TYPE = 0
+ GEOMOD = 0
+ GIDLMOD = 1
+ IGBMOD = 0
+ IGCMOD = 1
+ IIMOD = 0
+ NGATE = 0
+ NQSMOD = 0
+ RDSMOD = 0
+ RGATEMOD = 0
+ RGEOMOD = 0
+ NSEG = 5
+ SDTERM = 0
+ SHMOD = 0
+ AGIDL = 2E-12
+ AGISL = 2E-12
+ AIGC = 0.007
+ AIGD = 0.006
+ AIGS = 0.006
+ AT = 0.0008234
+ BG0SUB = 1.17
+ BGIDL = 1.50E+08
+ BGISL = 1.50E+08
+ BIGC = 0.0015
+ BIGD = 0.001944
+ BIGS = 0.001944
+ CDSC = 0.003469
+ CDSCD = 0.001486
+ CFD = 0.2e-10
+ CFS = 0.2e-10
+ CGBL = 0
+ CGBO = 0
+ CGDL = 0
+ CGDO = 1E-10
+ CGSL = 0
+ CGSO = 1E-10
+ CIGC = 1
+ CIGD = 1
+ CIGS = 1
+ CIT = 0
+ CKAPPAD = 0.6
+ CKAPPAS = 0.6
+ CTH0 = 1.243E-06
+ DELTAVSAT = 11.56
+ DELTAW = 0
+ DELTAWCV = -1.00E-08
+ DLBIN = 0
+ DLC = -9.2E-09
+ DLCIGD = 5.00E-09
+ DLCIGS = 5.00E-09
+ DROUT = 4.97
+ DSUB = 0.5
+ DVT0 = 0.05006
+ DVT1 = 0.4
+ DVTSHIFT = 0
+ EASUB = 4.05
+ EGIDL = 1.142
+ EGISL = 1.142
+ EOT = 2.10E-09
+ EOTACC = 3.00E-10
+ EOTBOX = 1.40E-07
+ EPSROX = 3.9
+ EPSRSP = 3.9
+ EPSRSUB = 11.9
+ ETA0 = 0.03952
+ ETAMOB = 4
+ ETAQM = 0.54
+ EU = 0.05
+ HFIN = 3.00E-08
+ IGT = 3.5
+ K1RSCE = 0
+ KSATIV = 1.592
+ KT1 = 0.08387
+ KT1L = 0
+ LINT = -2.5E-09
+ LPE0 = 0
+ LCDSCD = 0
+ LCDSCDR = 0
+ LRDSW = 1.3
+ LVSAT = 1441
+ MEXP = 2.491
+ NBODY = 1E+22
+ NC0SUB = 2.86E+25
+ NI0SUB = 1.1E+16
+ NSD = 2E+26
+ PCLM = 0.01
+ PCLMCV = 0.013
+ PCLMG = 1
+ PDIBL1 = 800
+ PDIBL2 = 0.005704
+ PHIG = 4.678
+ PHIN = 0.05
+ POXEDGE = 1.152
+ PQM = 0.66
+ PRT = 0.002477
+ PTWG = 6.322
+ PTWGT = 0.0015
+ PVAG = 200
+ QM0 = 2.183E-12
+ QMFACTOR = 0
+ RDSW = 190.6
+ RDSWMIN = 0
+ RDWMIN = 0
+ RSHD = 0
+ RSHS = 0
+ RSWMIN = 0
+ RTH0 = 0.15
+ TBGASUB = 0.000473
+ TBGBSUB = 636
+ TGIDL = -0.01
+ TMEXP = 0
+ TNOM = 25
+ TOXP = 2.1E-09
+ U0 = 0.02935
+ UA = 1.133
+ UA1 = 0.00134
+ UCS = 0.2672
+ UCSTE = 0
+ UD = 0.0105
+ UD1 = 0
+ UP = 0
+ UTE = 0
+ UTL = 0.001
+ VSAT = 48390
+ WR = 1
+ WTH0 = 2.60E-07
+ XL = 0

View File

@ -0,0 +1,38 @@
*Sample netlist for BSIM-CMG
*Ring Oscillator
.include Modelcards/modelcard.nmos
.include Modelcards/modelcard.pmos
* --- Voltage Sources ---
vdd supply 0 dc=1.0
Vss ss 0 0
* --- Inverter Subcircuit ---
.subckt mg_inv vin vout vdd ss
NP1 vout vin vdd vdd BSIMCMG_osdi_P TFIN=15n L=40n NFIN=10 NRS=1 NRD=1
NN1 vout vin ss ss BSIMCMG_osdi_N TFIN=15n L=40n NFIN=10 NRS=1 NRD=1 D=40n
.ends
* --- Inverter ---
Xinv1 vi 1 supply ss mg_inv
Xinv2 1 2 supply ss mg_inv
Xinv3 2 3 supply ss mg_inv
Xinv4 3 4 supply ss mg_inv
Xinv5 4 vi supply ss mg_inv
Xinv6 vi vo supply 0 mg_inv
* --- Transient Analysis ---
.tran 0.1p 1n
.control
pre_osdi test_osdi_win/bsimcmg.osdi
set xbrushwidth=3
run
plot i(vss)
plot v(vo)
.endc
.end

View File

@ -0,0 +1,36 @@
*Sample netlist for BSIM-CMG
* (exec-spice "ngspice %s" t)
*Inverter Transient
.include Modelcards/modelcard.nmos
.include Modelcards/modelcard.pmos
* --- Voltage Sources ---
vdd supply 0 dc=1.0
vsig vi 0 dc=0.5 sin (0.5 0.5 1MEG)
* --- Inverter Subcircuit ---
.subckt mg_inv vin vout vdd gnd
NP1 vout vin vdd vdd BSIMCMG_osdi_P
NN1 vout vin gnd gnd BSIMCMG_osdi_N
.ends
* --- Inverter ---
Xinv1 vi 1 supply 0 mg_inv
Xinv2 1 2 supply 0 mg_inv
Xinv3 2 3 supply 0 mg_inv
Xinv4 3 4 supply 0 mg_inv
Xinv5 4 vo supply 0 mg_inv
* --- Transient Analysis ---
.tran 20n 5u
.print tran v(vi) v(vo)
.control
pre_osdi test_osdi_win/bsimcmg.osdi
set xbrushwidth=3
run
plot v(vi) v(vo)
.endc
.end

View File

@ -0,0 +1,28 @@
OSDI BSIMCMG Test
*.options abstol=1e-15
* one voltage source per MOS terminal:
VD dd 0 1
VG gg 0 1
VS ss 0 0
VB bb 0 0
* model definitions:
*.model bsim4_osdi bsim4va
.include Modelcards/modelcard.nmos
*OSDI BSIM4:
* Where to put instance parameters channel width and length?
N1 dd gg ss bb BSIMCMG_osdi_N ; W=5u L=0.2u
.control
pre_osdi test_osdi_win/bsimcmg.osdi
set xbrushwidth=3
* a DC sweep: drain, gate
dc Vd 0 2.5 0.01 VG 0 2.5 0.5
* plot source current
plot i(VS)
.endc
.end

View File

@ -0,0 +1,28 @@
OSDI BSIMCMG Test
*.options abstol=1e-15
* one voltage source per MOS terminal:
VD dd 0 -1
VG gg 0 -1
VS ss 0 0
VB bb 0 0
* model definitions:
*
.include Modelcards/modelcard.pmos
*OSDI BSIMCMG:
* Where to put instance parameters channel width and length?
N1 dd gg ss bb BSIMCMG_osdi_P
.control
pre_osdi test_osdi_win/bsimcmg.osdi
set xbrushwidth=3
* a DC sweep: drain, gate
dc Vd 0 -1.8 -0.01 VG 0 -1.8 -0.3
* plot source current
plot i(VS)
.endc
.end

View File

@ -0,0 +1,54 @@
*Sample netlist for BSIM-MG
* (exec-spice "ngspice %s" t)
*17-stage ring oscillator
.include Modelcards/modelcard.nmos
.include Modelcards/modelcard.pmos
* --- Voltage Sources ---
vdd supply 0 dc=1.0
* --- Inverter Subcircuit ---
.subckt mg_inv vin vout vdd gnd
NP1 vout vin vdd vdd BSIMCMG_osdi_P
NN1 vout vin gnd gnd BSIMCMG_osdi_N
.ends
* --- 17 Stage Ring oscillator ---
Xinv1 1 2 supply 0 mg_inv
Xinv2 2 3 supply 0 mg_inv
Xinv3 3 4 supply 0 mg_inv
Xinv4 4 5 supply 0 mg_inv
Xinv5 5 6 supply 0 mg_inv
Xinv6 6 7 supply 0 mg_inv
Xinv7 7 8 supply 0 mg_inv
Xinv8 8 9 supply 0 mg_inv
Xinv9 9 10 supply 0 mg_inv
Xinv10 10 11 supply 0 mg_inv
Xinv11 11 12 supply 0 mg_inv
Xinv12 12 13 supply 0 mg_inv
Xinv13 13 14 supply 0 mg_inv
Xinv14 14 15 supply 0 mg_inv
Xinv15 15 16 supply 0 mg_inv
Xinv16 16 17 supply 0 mg_inv
Xinv17 17 1 supply 0 mg_inv
* --- Initial Condition ---
.ic v(1)=1
.tran 1p 1n
.measure tran t1 when v(1)=0.5 cross=1
.measure tran t2 when v(1)=0.5 cross=7
.measure tran period param='(t2-t1)/3'
.measure tran frequency param='3/(t2-t1)'
.measure tran delay_per_stage param='period/34'
.control
pre_osdi test_osdi_win/bsimcmg.osdi
set xbrushwidth=3
run
plot v(1)
.endc
.end

View File

@ -0,0 +1,27 @@
*Sample netlist for BSIM-CMG
* (exec-spice "ngspice %s" t)
*Inverter DC
.include Modelcards/modelcard.nmos
.include Modelcards/modelcard.pmos
* --- Voltage Sources ---
vdd supply 0 dc=1.0
vsig vin 0 dc=0.5 sin (0.5 0.5 1MEG)
NP1 vout vin supply supply BSIMCMG_osdi_P
NN1 vout vin 0 0 BSIMCMG_osdi_N
* --- DC Analysis ---
*.dc vsig 0 1 0.01
* --- Transient Analysis ---
.tran 10n 2u
.control
pre_osdi test_osdi_win/bsimcmg.osdi
set xbrushwidth=3
run
plot v(vout) v(vin)
.endc
.end

View File

@ -0,0 +1 @@
Place bsimcmg.osdi here.

View File

@ -0,0 +1,43 @@
ECL DFF HICUM2.4 test case
*
V6 D GND dc 0 PULSE(-.25 0 0 1P 1P .25N .50N)
V5 D_BAR GND dc 0 PULSE(0 -.25 0 1P 1P .25N .50N)
V4 CLK GND dc 0 PULSE(-0.9 -1.2 0 1P 1P .125N .25N)
V3 CLK_BAR GND dc 0 PULSE(-1.2 -0.9 0 1P 1P .125N .25N)
VVCS NET2 GND DC -0.8
R6 GND NET6 800
R5 GND NET11 800
R4 NET12 VEE 350
VVEE VEE GND DC -2.0
R3 GND NET10 800
R2 NET13 VEE 350
R1 GND Q 800
XQVLGNPN16 NET7 CLK_BAR NET4 VEE dt hicumL0V1p1_c_sbt
XQVLGNPN15 NET5 CLK NET3 VEE dt hicumL0V1p1_c_sbt
XQVLGNPN14 NET1dt Q NET7 VEE dt hicumL0V1p1_c_sbt
XQVLGNPN13 Q NET6 NET9 VEE dt hicumL0V1p1_c_sbt
XQVLGNPN12 NET6 NET11 NET5 VEE dt hicumL0V1p1_c_sbt
XQVLGNPN11 NET11 D_BAR NET8 VEE dt hicumL0V1p1_c_sbt
XQVLGNPN1dt NET4 NET2 NET13 VEE dt hicumL0V1p1_c_sbt
XQVLGNPN9 NET3 NET2 NET12 VEE dt hicumL0V1p1_c_sbt
XQVLGNPN8 NET8 CLK_BAR NET3 VEE dt hicumL0V1p1_c_sbt
XQVLGNPN7 NET9 CLK NET4 VEE dt hicumL0V1p1_c_sbt
XQVLGNPN6 Q NET1dt NET7 VEE dt hicumL0V1p1_c_sbt
XQVLGNPN5 NET1dt NET11 NET9 VEE dt hicumL0V1p1_c_sbt
XQVLGNPN4 NET11 NET6 NET5 VEE dt hicumL0V1p1_c_sbt
XQVLGNPN3 NET6 D NET8 VEE dt hicumL0V1p1_c_sbt
Rdt dt 0 1G
*
.include Modelcards/model-card-hicumL0V1p11_mod.lib
.SAVE V(D) V(CLK) V(Q)
.control
pre_osdi test_osdi_win/HICUML0-2.osdi
TRAN 0.25p 5n
rusage
set color0=white
set xbrushwidth=2
plot V(D) V(CLK) V(Q) ylimit -1.2 0.2
*quit
.endc
.END

View File

@ -0,0 +1,59 @@
ECL DFF VBIC test case
*
V6 D GND PULSE(-.25 0 0 1P 1P .25N .50N)
V5 D_BAR GND PULSE(0 -.25 0 1P 1P .25N .50N)
V4 CLK GND PULSE(-0.9 -1.2 0 1P 1P .125N .25N)
V3 CLK_BAR GND PULSE(-1.2 -0.9 0 1P 1P .125N .25N)
VVCS NET2 GND DC -0.8
R6 GND NET6 800
R5 GND NET11 800
R4 NET12 VEE 350
VVEE VEE GND DC -2.0
R3 GND NET10 800
R2 NET13 VEE 350
R1 GND Q 800
QVLGNPN16 NET7 CLK_BAR NET4 VEE NPN_VBIC_VLG
QVLGNPN15 NET5 CLK NET3 VEE NPN_VBIC_VLG
QVLGNPN14 NET10 Q NET7 VEE NPN_VBIC_VLG
QVLGNPN13 Q NET6 NET9 VEE NPN_VBIC_VLG
QVLGNPN12 NET6 NET11 NET5 VEE NPN_VBIC_VLG
QVLGNPN11 NET11 D_BAR NET8 VEE NPN_VBIC_VLG
QVLGNPN10 NET4 NET2 NET13 VEE NPN_VBIC_VLG
QVLGNPN9 NET3 NET2 NET12 VEE NPN_VBIC_VLG
QVLGNPN8 NET8 CLK_BAR NET3 VEE NPN_VBIC_VLG
QVLGNPN7 NET9 CLK NET4 VEE NPN_VBIC_VLG
QVLGNPN6 Q NET10 NET7 VEE NPN_VBIC_VLG
QVLGNPN5 NET10 NET11 NET9 VEE NPN_VBIC_VLG
QVLGNPN4 NET11 NET6 NET5 VEE NPN_VBIC_VLG
QVLGNPN3 NET6 D NET8 VEE NPN_VBIC_VLG
*
.MODEL NPN_VBIC_VLG NPN LEVEL=4
+TNOM = 27 RCI = 1E3 RCX = 50
+VO = 1.5 GAMM = 3.402097E-11 HRCF = 1
+RBX = 243 RBI = 20 RE = 30
+RS = 0 RBP = 0 IS = 8.084033E-18
+NF = 1 NR = 1.005 FC = 0.5
+CJE = 2.083234E-15 PE = 0.8793669 ME = 0.3108762
+CJC = 1.803275E-15 PC = 0.5512188 MC = 0.4454263
+CJCP = 8E-15 PS = 0.66956 MS = 0.2243
+IBEI = 4.542609E-20 WBE = 1 NEI = 1
+IBEN = 3.275162E-16 NEN = 1.5543186 IBCI = 3.594252E-19
+NCI = 0.996 IBCN = 1.717776E-17 NCN = 1.202521
+AVC1 = 3E-4 AVC2 = 1E-5 ISP = 1.332E-19
+WSP = 1 NFP = 1 IBEIP = 0
+IBENP = 0 IBCIP = 0 NCIP = 1
+IBCNP = 0 NCNP = 2 VEF = 109.6523
+VER = 2.2052435 IKF = 6.03524E-3 IKR = 1.807895E-4
+IKP = 2.908576E-5 TF = 1.1E-12 XTF = 21.5423
+VTF = 12.4758677 ITF = 0.0175231 TR = 2.23542E-9
.SAVE V(D) V(CLK) V(Q)
.control
TRAN 0.25p 5n
rusage
set color0=white
set xbrushwidth=2
plot V(D) V(CLK) V(Q)
*quit
.endc
.END

View File

@ -0,0 +1,46 @@
.title ECL nor gate ring oscillator, 9 stages, 734 MHz
.include "Modelcards/model-card-hicumL0V1p11_mod.lib"
.subckt nor in1 in2 a1 a2 vee GND
XQ1 Net-_R1-Pad2_ IN1 Net-_Q1-Pad3_ VEE DT1 hicumL0V1p1_c_sbt
XQ2 Net-_R1-Pad2_ IN2 Net-_Q1-Pad3_ VEE DT1 hicumL0V1p1_c_sbt
XQ3 Net-_R2-Pad2_ Net-_R3-Pad2_ Net-_Q1-Pad3_ VEE DT1 hicumL0V1p1_c_sbt
XQ4 GND Net-_R2-Pad2_ A1 VEE DT1 hicumL0V1p1_c_sbt
XQ5 GND Net-_R1-Pad2_ A2 VEE DT1 hicumL0V1p1_c_sbt
Rt1 DT1 0 1G
R1 GND Net-_R1-Pad2_ 220
R2 GND Net-_R2-Pad2_ 220
R3 GND Net-_R3-Pad2_ 575
R4 Net-_R3-Pad2_ VEE 1.92k
R5 Net-_Q1-Pad3_ VEE 780
Ra1 A1 VEE 510
Ra2 A2 VEE 510
.ends
X1 out9 out9 a1 out1 vee gnd nor
X2 out1 out1 a2 out2 vee gnd nor
X3 out2 out2 a3 out3 vee gnd nor
X4 out3 out3 a4 out4 vee gnd nor
X5 out4 out4 a5 out5 vee gnd nor
X6 out5 out5 a2 out6 vee gnd nor
X7 out6 out6 a3 out7 vee gnd nor
X8 out7 out7 a4 out8 vee gnd nor
X9 out8 out8 a5 out9 vee gnd nor
V1 VEE GND -5.2
.tran 0.02n 200n
.control
pre_osdi test_osdi_win/HICUML0-2.osdi
run
rusage
plot out9 xlimit 100n 110n
linearize out9
fft out9
plot mag(out9) xlimit 0 2G ylimit 0 0.5
.endc
.end

View File

@ -0,0 +1,25 @@
.title KiCad schematic
.include "Modelcards/model-card-hicumL0V1p11_mod.lib"
V2 IN1 GND dc -1.75 pulse(-1.75 -0.9 0 1n 1n 5u 10u)
V1 VEE GND -5.2
Ra1 A1 VEE 510
XQ5 GND Net-_Q1-Pad1_ A2 VEE DT hicumL0V1p1_c_sbt
XQ4 GND Net-_Q3-Pad1_ A1 VEE DT hicumL0V1p1_c_sbt
R4 Net-_Q3-Pad2_ VEE 1.92k
XQ2 Net-_Q1-Pad1_ IN2 Net-_Q1-Pad3_ VEE DT hicumL0V1p1_c_sbt
XQ1 Net-_Q1-Pad1_ IN1 Net-_Q1-Pad3_ VEE DT hicumL0V1p1_c_sbt
R5 Net-_Q1-Pad3_ VEE 780
XQ3 Net-_Q3-Pad1_ Net-_Q3-Pad2_ Net-_Q1-Pad3_ VEE DT hicumL0V1p1_c_sbt
R2 GND Net-_Q3-Pad1_ 220
R1 GND Net-_Q1-Pad1_ 220
R3 GND Net-_Q3-Pad2_ 575
Ra2 A2 VEE 510
V3 In2 GND dc -1.75 pulse(-1.75 -0.9 0 1n 1n 2.5u 5u)
Rt1 DT GND 1G
.tran 0.1n 100u
.control
pre_osdi test_osdi_win/HICUML0-2.osdi
run
plot a1 a2+2 in1+4 in2+6
.endc
.end

View File

@ -0,0 +1,303 @@
{
"board": {
"layer_presets": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_label_syntax": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "ECL-RO.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12.0,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.25,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6.0
}
],
"meta": {
"version": 2
},
"net_colors": null
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"specctra_dsn": "",
"step": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"drawing": {
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "Spice",
"ngspice": {
"fix_include_paths": true,
"fix_passive_vals": false,
"meta": {
"version": 0
},
"model_mode": 4,
"workbook_filename": "555bip.wbk"
},
"page_layout_descr_file": "",
"plot_directory": "",
"spice_adjust_passive_values": false,
"spice_external_command": "C:\\Spice64\\bin\\ngspice-2022-osdi.exe \"%I\"",
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"35461762-06be-4c9e-bf12-e38db35c4dcf",
""
]
],
"text_variables": {}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,107 @@
(kicad_symbol_lib (version 20211014) (generator kicad_symbol_editor)
(symbol "npn" (pin_numbers hide) (pin_names (offset 0) hide) (in_bom yes) (on_board yes)
(property "Reference" "Q1" (id 0) (at 6.096 1.6511 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "npn" (id 1) (at 6.096 -0.8889 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" "" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27) italic) hide)
)
(property "Datasheet" "" (id 3) (at -2.54 0 0)
(effects (font (size 1.27 1.27)) (justify left) hide)
)
(property "Spice_Primitive" "Q" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Spice_Model" "NP" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Spice_Netlist_Enabled" "Y" (id 6) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Spice_Lib_File" "bipmod.lib" (id 7) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "Transistor Double NPN" (id 8) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "100mA IC, 30V Vce, Double NPN Transistors, Current mirror configuration, SOT-143" (id 9) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_fp_filters" "SOT?143*" (id 10) (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "npn_0_0"
(pin passive line (at 6.604 -5.08 90) (length 2.54)
(name "S" (effects (font (size 1.27 1.27))))
(number "4" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 8.128 -5.08 90) (length 2.54)
(name "DT" (effects (font (size 1.27 1.27))))
(number "5" (effects (font (size 1.27 1.27))))
)
)
(symbol "npn_0_1"
(polyline
(pts
(xy 2.54 0)
(xy 3.302 0)
)
(stroke (width 0.1524) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy 5.08 -2.54)
(xy 3.175 -0.635)
)
(stroke (width 0) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy 5.08 2.54)
(xy 3.175 0.635)
)
(stroke (width 0) (type default) (color 0 0 0 0))
(fill (type none))
)
(polyline
(pts
(xy 3.175 -1.905)
(xy 3.175 1.905)
(xy 3.175 1.905)
)
(stroke (width 0.508) (type default) (color 0 0 0 0))
(fill (type outline))
)
(polyline
(pts
(xy 3.81 -1.778)
(xy 4.318 -1.27)
(xy 4.826 -2.286)
(xy 3.81 -1.778)
(xy 3.81 -1.778)
)
(stroke (width 0) (type default) (color 0 0 0 0))
(fill (type outline))
)
)
(symbol "npn_1_1"
(pin passive line (at 5.08 5.08 270) (length 2.54)
(name "C" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 0 0 0) (length 2.54)
(name "B" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 5.08 -5.08 90) (length 2.54)
(name "E" (effects (font (size 1.27 1.27))))
(number "3" (effects (font (size 1.27 1.27))))
)
)
)
)

View File

@ -0,0 +1,3 @@
(sym_lib_table
(lib (name "ECL_Bip")(type "KiCad")(uri "${KIPRJMOD}/ECL_Bip.kicad_sym")(options "")(descr ""))
)

View File

@ -0,0 +1,40 @@
********************************************************************************
********************************************************************************
* HICUM Level0 Version 1.1 model cards for testing
********************************************************************************
********************************************************************************
* 1D transistor: Isothermal Simulation and Temperature dependence
********************************************************************************
********************************************************************************
* Complete transistor: Isothermal Simulation with substrate diode
********************************************************************************
.subckt hicumL0V1p1_c_sbt c b e s dt
*qhcm0 c b e s dt hic0_full
nqhcm0 c b e s dt hic0_full
*.model hic0_full npn
.ends
.model hic0_full hicumL0va
+ level=7 is=1.3525E-18 vef=8.0 iqf=3.0e-2 iqr=1e6
+ iqfh=1e6 tfh=1e-8 ibes=1.16E-20 mbe=1.015 ires=1.16e-16 mre=2.0 ibcs=1.16e-20
+ mbc=1.015 mcf=1.0 mcr=1 kavl=0.9488 eavl=11.96e10 alkav=0.825e-4
+ aleav=0.196e-3 rbi0=71.76 rbx=8.83 fgeo=0.73 re=12.534 rcx=9.165 iscs=1.0e-17 msc=1.0
+ cje0=8.11e-15 vde=0.95 ze=0.5 aje=1.8 cjci0=1.16e-15 vdci=0.8 zci=0.333
+ vptci=46 cjcx0=5.4e-15 vdcx=0.7 zcx=0.333 vptcx=100 fbc=0.1526 vr0e=1.6 vr0c=8.0
+ cjs0=3.64e-14 vds=0.6 zs=0.447 vpts=100 t0=4.75e-12 dt0h=2.1e-12 tbvl=4.0e-12
+ tef0=1.8e-12 gte=1.4 thcs=30.0e-12 ahc=0.75 tr=0.0 rci0=127.8 vlim=0.7
+ vces=0.1 vpt=5 cbepar=1.13e-15 cbcpar=2.97e-15 kf=1.43e-8 af=2.0 vgb=1.17
+ alt0=0.0 kt0=0.0 zetaci=1.6 alvs=1.0e-3 alces=0.4e-3 zetarbi=0.588
+ zetarbx=0.206 zetarcx=0.223 zetare=0.0 vge=1.1386 vgc=1.1143 vgs=1.15 f1vg=-1.02377e-4
+ f2vg=4.3215e-4 zetact=3.5 zetabet=4.0 rth=0.0 cth=0.0
+ tnom=27.0 type=1 ; npn=1 pnp=0
*+ dt=0.0
********************************************************************************
* Complete test transistor: default
********************************************************************************
.subckt hicumL0V11_default c b e s dt
qhcm0 c b e s dt hic0_full
.ends hicumL0V11_default
********************************************************************************

View File

@ -0,0 +1,23 @@
Bip model in subckt Gummel Test Ic=f(Vc,Vb)
VB B 0 0.5
VC C 0 1.0
VS S 0 0.0
X1 C B 0 S bip_default
.control
dc vb 0.2 1.4 0.01
plot abs(i(vc)) abs(i(vb)) abs(i(vs)) ylimit 0.1p 100m ylog
plot abs(i(vc))/abs(i(vb)) vs abs(i(vc)) xlog xlimit 100p 100m ylimit 0 200 retraceplot
.endc
********************************************************************************
* Complete test transistor: default
********************************************************************************
.subckt bip_default c b e s
qhcm0 c b e s hic0_full
.model hic0_full npn
.ends hicumL0V11_default
********************************************************************************
.end

View File

@ -0,0 +1,20 @@
HICUM0 Gummel Test Ic=f(Vc,Vb)
VB B 0 0.5
VC C 0 1.0
VS S 0 0.0
*AQ1 C B 0 S DT hicumL0V1p1_c_sbt
XQ1 C B 0 S DT hicumL0V1p1_c_sbt
Rdt dt 0 1G
.control
pre_osdi test_osdi_win/HICUML0-2.osdi
dc vb 0.2 1.4 0.01
set xbrushwidth=2
plot abs(i(vc)) abs(i(vb)) abs(i(vs)) ylimit 0.1p 100m ylog
plot abs(i(vc))/abs(i(vb)) vs abs(i(vc)) xlog xlimit 100p 100m ylimit 0 200 retraceplot
.endc
.include Modelcards/model-card-hicumL0V1p11_mod.lib
.end

View File

@ -0,0 +1,20 @@
HICUM0 Output Test Ic=f(Vc,Ib)
IB 0 B 200n
VC C 0 2.0
VS S 0 0.0
X1 C B 0 S DT hicumL0V1p1_c_sbt
Rdt dt 0 1G
.control
pre_osdi test_osdi_win/HICUML0-2.osdi
dc vc 0.0 3.0 0.05 ib 10u 100u 10u
set xbrushwidth=2
plot abs(i(vc))
*plot v(dt)
.endc
.include Modelcards/model-card-hicumL0V1p11_mod.lib
.end

View File

@ -0,0 +1 @@
Place HICUML0-2.osdi here.

View File

@ -0,0 +1,35 @@
HICUM0 Output Test Ic=f(Vc,Ib)
IB 0 B 200n
VC C 0 2.0
VS S 0 0.0
Q1 C B 0 S NPN_VBIC_VLG
.control
dc vc 0.0 5.0 0.05 ib 10u 100u 10u
run
plot abs(i(vc))
plot v(dt)
.endc
.MODEL NPN_VBIC_VLG NPN LEVEL=4
+TNOM = 27 RCI = 1E3 RCX = 50
+VO = 1.5 GAMM = 3.402097E-11 HRCF = 1
+RBX = 243 RBI = 20 RE = 30
+RS = 0 RBP = 0 IS = 8.084033E-18
+NF = 1 NR = 1.005 FC = 0.5
+CJE = 2.083234E-15 PE = 0.8793669 ME = 0.3108762
+CJC = 1.803275E-15 PC = 0.5512188 MC = 0.4454263
+CJCP = 8E-15 PS = 0.66956 MS = 0.2243
+IBEI = 4.542609E-20 WBE = 1 NEI = 1
+IBEN = 3.275162E-16 NEN = 1.5543186 IBCI = 3.594252E-19
+NCI = 0.996 IBCN = 1.717776E-17 NCN = 1.202521
+AVC1 = 3E-4 AVC2 = 1E-5 ISP = 1.332E-19
+WSP = 1 NFP = 1 IBEIP = 0
+IBENP = 0 IBCIP = 0 NCIP = 1
+IBCNP = 0 NCNP = 2 VEF = 109.6523
+VER = 2.2052435 IKF = 6.03524E-3 IKR = 1.807895E-4
+IKP = 2.908576E-5 TF = 1.1E-12 XTF = 21.5423
+VTF = 12.4758677 ITF = 0.0175231 TR = 2.23542E-9
.end

View File

@ -0,0 +1,76 @@
*MEXTRAM modelcard
.model BJTRF1 bjt504tva
*+ LEVEL=6
+MULT=1.000E+00
+TREF=25.000E+00
+DTA=0.000E+00
+EXMOD=1.000E+00
+EXPHI=0.000E+00
+EXAVL=1.000E+00
+IS=23.571E-18
+IK=231.660E-03
+VER=2.100E+00
+VEF=36.001E+00
+BF=186.538E+00
+IBF=1.140E-15
+MLF=2.000E+00
+XIBI=0.000E+00
+BRI=9.231E+00
+IBR=61.600E-15
+VLR=400.000E-03
+XEXT=648.148E-03
+WAVL=1.064E-06
+VAVL=3.330E+00
+SFH=882.471E-03
+RE=949.668E-03
+RBC=27.769E+00
+RBV=32.004E+00
+RCBLX=1.0
+RCBLI=1.0
+RCC=18.026E+00
+RCV=237.417E+00
+SCRCV=882.839E+00
+IHC=3.370E-03
+AXI=300.000E-03
+CJE=55.566E-15
+VDE=900.000E-03
+PE=500.000E-03
+XCJE=52.478E-03
+CJC=25.153E-15
+VDC=660.000E-03
+PC=450.000E-03
+XP=310.000E-03
+MC=500.000E-03
+XCJC=122.100E-03
+MTAU=1.000E+00
+TAUE=6.200E-12
+TAUB=977.273E-15
+TEPI=7.980E-12
+TAUR=64.400E-12
+DEG=0.000E+00
+XREC=0.000E+00
+AQBO=701.246E-03
+AE=308.246E-03
+AB=846.000E-03
+AEPI=2.500E+00
+AEX=619.000E-03
+AC=1.580E+00
+DVGBF=52.000E-03
+DVGBR=0.000E+00
+VGB=1.197E+00
+VGC=1.200E+00
+VGJ=1.200E+00
+DVGTE=1.202E+00
+AF=2.350E+00
+KF=47.298E-09
+KFN=1.000E-09
+ISS=18.480E-18
+IKS=219.348E-06
+CJS=146.628E-15
+VDS=542.048E-03
+PS=314.095E-03
+VGS=1.221E+00
+AS=1.580E+00
+RTH=300
+CTH=3E-09

View File

@ -0,0 +1,18 @@
MEXTRAM Gummel Test Ic,b,s=f(Vc,Ib)
.include Modelcards/mex_model.lib
VB B 0 0.5
VC C 0 2.0
VS S 0 0.0
NQ1 C B 0 S DT BJTRF1
.control
pre_osdi test_osdi_win/bjt504t.osdi
dc vb 0.2 1.4 0.01
plot abs(i(vc)) abs(i(vb)) abs(i(vs)) ylog xlimit 0.3 1.4 ylimit 1e-12 100e-3
plot abs(i(vc))/abs(i(vb)) vs abs(-i(vc)) xlog xlimit 1e-09 10e-3 ylimit 0 150
.endc
.end

View File

@ -0,0 +1,16 @@
MEXTRAM Output Test Ic=f(Vc,Ib)
.include Modelcards/mex_model.lib
IB 0 b 1u
VC C 0 2.0
VS S 0 0.0
NQ1 C B 0 S T BJTRF1
.control
pre_osdi test_osdi_win/bjt504t.osdi
dc vc 0 6.0 0.05 ib 1u 8u 1u
plot abs(i(vc)) xlabel Vce title Output-Characteristic
.endc
.end

View File

@ -0,0 +1 @@
Place bjt505.osdi here.

View File

@ -0,0 +1,641 @@
* model parameters fron BSIMBULK 106.2
.model BSIMBULK_osdi_N bsimbulk
+level=77
+TYPE = 1
+GEOMOD = 0
+RGEOMOD = 0
+COVMOD = 1
+RDSMOD = 0
+GIDLMOD = 1
+IGCMOD = 0
+IGBMOD = 0
+LLONG = 2e-6
+WWIDE = 1e-5
+XL = -1.7e-8
+XW = 1.1e-8
+LINT = 0
+WINT = 0
+DLC = 0
+DWC = 0
+TOXE = 1.74e-9
+TOXP = 1.7e-9
+NDEP = 4.6e23
+NSD = 1e26
+NGATE = 8.5e25
+VFB = -1.02
+EPSROX = 3.9
+EPSRSUB = 11.9
+NI0SUB = 1.1e16
+XJ = 1.5e-7
+DMCG = 0
+DMDG = 0
+DMCGT = 0
+CIT = 1e-8
+CDSCD = 0.001
+CDSCB = 0
+CDSCBL = 0.007
+CDSCBLEXP = 1
+NFACTOR = 0.002
+NFACTORL = 2.1e-8
+NFACTORLEXP = 6.264
+NDEPL1 = 0.096
+NDEPLEXP1 = 1
+NDEPL2 = -0.0032
+NDEPLEXP2 = 2.05
+DVTP0 = 7.5e-7
+DVTP1 = -4.4e-7
+NDEPW = -0.1548
+NDEPWEXP = 0.7441
+NDEPWL = 0
+NDEPWLEXP = 0.2
+K2W = 0
+AGIDL = 3.728e-8
+AGIDLL = -0.04815
+AGIDLW = -0.0341
+BGIDL = 8.123e9
+CGIDL = 1.21e-6
+EGIDL = -2.952
+PHIN = 0.05
+K2L = 0.001636
+K2 = -0.014
+ETA0 = 8.416e-6
+ETAB = -5.561e-5
+ETABEXP = 2.155
+DSUB = 3
+VSAT = 6.4e4
+VSATW = 0.05
+VSATWEXP = 1
+DELTA = 0.15
+DELTAL = 0.1
+DELTALEXP = 1e-5
+U0 = 0.04546
+ETAMOB = 1.5
+U0L = 0.025
+U0LEXP = 0.95
+UA = 0.4007
+UAW = 0.05
+UAWEXP = 1
+UAL = 0.00475
+UALEXP = 1.118
+EUW = -0.02
+EUWEXP = 1
+EUL = 0.001
+EULEXP = 1
+EU = 1.9
+UDL = 1e-15
+UDLEXP = 1
+UD = 1.042e-5
+UCS = 2
+UCW = 0
+UCWEXP = 1
+UC = 1e-07
+UCL = 2.5e4
+UCLEXP = 1
+PCLM = 0.15
+PCLML = 0.01
+PCLMLEXP = 0.4
+PCLMG = 0
+PSCBE1 = 5
+PSCBE2 = 1.29e-12
+PDITS = 0
+PDITSL = 0
+PDITSD = 0
+RSWMIN = 0
+RSW = 100
+RDWMIN = 0
+RDW = 100
+RDSW = 20
+RDSWMIN = 0
+PRWG = 1
+PRWB = 0
+WR = 1
+RSH = 0
+PDIBLCB = 0
+PDIBLC = 0.01
+PDIBLCL = 1e-5
+PDIBLCLEXP = 1e-6
+PVAG = 0
+PTWG = 0.2
+PTWGL = 3e4
+PTWGLEXP = 5e-6
+FPROUT = 0
+CF = 0
+CFRCOEFF = 1
+CGSO = 2.5e-10
+CGDO = 2.5e-10
+CGSL = 1.2e-10
+CGDL = 1.2e-10
+CKAPPAS = 1.25
+CKAPPAD = 1.25
+CGBO = 0
+ADOS = 0
+BDOS = 1
+QM0 = 0.001
+ETAQM = 0.54
+NDEPCV = 8e23
+VFBCV = -0.95
+VSATCV = 1e5
+PCLMCV = 0
+PSAT = 0.46
+PSATL = 6
+PSATLEXP = 0.06
+TNFACTOR = 0
+TETA0 = 0
+UTE = -1.4
+UTEL = -0.001
+UA1 = -0.0011
+UA1L = 0
+UC1 = 0
+UD1 = 0
+UD1L = 0
+UCSTE = -0.005
+PRT = 0
+AT = -0.05
+ATL = -0.1
+TDELTA = -0.0048
+PTWGT = -0.002
+PTWGTL = 0.01
+KT1 = -0.115
+KT1EXP = 1
+KT1L = 1.286e-9
+KT2 = -0.003157
+K2LEXP = 1.698
+K2WEXP = 0.005
+TBGASUB = 0
+AIGS = 0.0136
+BIGS = 0.00171
+CIGS = 0.075
+AIGSL = 0
+AIGD = 0.0136
+BIGD = 0.00171
+CIGD = 0.075
+AIGDL = 0
+AIGC = 0.01285
+LAIGC = 2.132e-6
+BIGC = 0.0013
+CIGC = 0.013
+AIGCL = -0.01227
+PIGCD = 1
+PIGCDL = 6.196
+AIGBINV = 0.015
+BIGBINV = 0.000949
+CIGBINV = 0.006
+EIGBINV = 1.1
+NIGBINV = 3
+AIGBACC = 0.01751
+BIGBACC = 8.307
+CIGBACC = -898.7
+NIGBACC = 1
+LPSAT = 0
+WPSAT = 0
+PPSAT = 0
+PSATB = 0
+PSATX = 3
+WVSAT = 0
+PVSAT = 0
+WPTWG = 0
+PPTWG = 0
+TNOM = 25
+WDVTP0 = 0
+WDVTP1 = 0
+LUTE = 0.04574
+LUA1 = 8.365e-5
+LAT = 0
+DVTP2 = 0
+DVTP3 = 0
+DVTP4 = 0
+DVTP5 = 0
+VSATL = 1350
+VSATLEXP = 0.00033
+SCA = 0
+SCB = 0
+SCC = 0
+SC = 0
.model BSIMBULK_osdi_P bsimbulk
+level=77
+TYPE = -1
+GEOMOD = 0
+RGEOMOD = 0
+RGATEMOD = 0
+RBODYMOD = 0
+IGCMOD = 0
+IGBMOD = 0
+COVMOD = 1
+RDSMOD = 2
+GIDLMOD = 0
+TNOIMOD = 0
+SHMOD = 0
+TOXE = 2.34e-9
+TOXP = 1.925e-9
+DTOX = 0
+EPSROX = 3.9
+TNOM = 25
+XL = 0
+XW = 0
+LINT = 0
+LLONG = 1000000
+LL = 0
+LW = 0
+LWL = 0
+LLN = 1
+LWN = 1
+WINT = -9.0134104e-9
+WL = 0
+WW = 0
+WWL = 0
+WLN = 1
+WWN = 1
+WWIDE = 1000000
+DLC = 0
+LLC = 0
+LWC = 0
+LWLC = 0
+DWC = 0
+WLC = 0
+WWC = 0
+WWLC = 0
+JSS = 0.0001
+JSD = 0.0001
+JSWS = 0
+JSWD = 0
+JSWGS = 0
+JSWGD = 0
+NJS = 1
+NJD = 1
+IJTHSFWD = 0.1
+IJTHDFWD = 0.1
+IJTHSREV = 0.1
+IJTHDREV = 0.1
+BVS = 10
+BVD = 10
+XJBVS = 1
+XJBVD = 1
+JTSS = 0
+JTSD = 0
+JTSSWS = 0
+JTSSWD = 0
+JTSSWGS = 0
+JTSSWGD = 0
+JTWEFF = 0
+NJTS = 20
+NJTSD = 20
+NJTSSW = 20
+NJTSSWD = 20
+NJTSSWG = 20
+NJTSSWGD = 20
+VTSS = 10
+VTSD = 10
+VTSSWS = 10
+VTSSWD = 10
+VTSSWGS = 10
+VTSSWGD = 10
+CJS = 0.0005
+CJD = 0.0005
+CJSWS = 5e-10
+CJSWD = 5e-10
+CJSWGS = 0
+CJSWGD = 0
+PBS = 1
+PBD = 1
+PBSWS = 1
+PBSWD = 1
+PBSWGS = 1
+PBSWGD = 1
+MJS = 0.5
+MJD = 0.5
+MJSWS = 0.33
+MJSWD = 0.33
+MJSWGS = 0.33
+MJSWGD = 0.33
+TPB = 0
+TCJ = 0
+TPBSW = 0
+TCJSW = 0
+TPBSWG = 0
+TCJSWG = 0
+XTIS = 3
+XTID = 3
+XTSS = 0.02
+XTSD = 0.02
+XTSSWS = 0.02
+XTSSWD = 0.02
+XTSSWGS = 0.02
+XTSSWGD = 0.02
+TNJTS = 0
+TNJTSD = 0
+TNJTSSW = 0
+TNJTSSWD = 0
+TNJTSSWG = 0
+TNJTSSWGD = 0
+NOIA = 6.25e40
+NOIB = 3.125e25
+NOIC = 8.75e8
+EM = 41000000
+EF = 1
+LINTNOI = 0
+NTNOI = 1
+TNOIA = 0
+TNOIB = 0
+TNOIC = 0
+RNOIA = 0.577
+RNOIB = 0.5164
+RNOIC = 0.395
+DWJ = 0
+DMCG = 0
+DMCI = 0
+DMDG = 0
+DMCGT = 0
+XGW = 0
+XGL = 0
+GBMIN = 1e-12
+RSHG = 0.1
+RBPB = 50
+RBPD = 50
+RBPS = 50
+RBDB = 50
+RBSB = 50
+RBPS0 = 50
+RBPSL = 0
+RBPSW = 0
+RBPSNF = 0
+RBPD0 = 50
+RBPDL = 0
+RBPDW = 0
+RBPDNF = 0
+RBPBX0 = 100
+RBPBXL = 0
+RBPBXW = 0
+RBPBXNF = 0
+RBPBY0 = 100
+RBPBYL = 0
+RBPBYW = 0
+RBPBYNF = 0
+RBSBX0 = 100
+RBSBY0 = 100
+RBDBX0 = 100
+RBDBY0 = 100
+RBSDBXL = 0
+RBSDBXW = 0
+RBSDBXNF = 0
+RBSDBYL = 0
+RBSDBYW = 0
+RBSDBYNF = 0
+XRCRG1 = 12
+XRCRG2 = 1
+NGCON = 1
+NDEP = 8.062e23
+NDEPL1 = 1.2139
+NDEPLEXP1 = 1.9088
+NDEPL2 = -1.1825
+NDEPLEXP2 = 1.9173
+NDEPW = 0.065035
+NDEPWEXP = 0.48882
+NDEPWL = 0.00040893
+NDEPWLEXP = 1.3273
+EASUB = 4.05
+NI0SUB = 1.1e16
+BG0SUB = 1.17
+EPSRSUB = 11.9
+XJ = 1.5e-7
+VFB = -1.2108
+VFBSDOFF = 0
+NSD = 1e26
+DVTP0 = 1.8335e-7
+DVTP1 = 220.59
+DVTP2 = 9.6351e-10
+DVTP3 = 0.89017
+DVTP4 = 98.728
+DVTP5 = 5.1435e-17
+PHIN = 0.045
+ETA0 = 0.0051075
+ETAB = -0.010908157
+ETABEXP = 0.09999
+DSUB = 1.0667
+K2 = -0.093146
+K2L = 0.065574
+K2LEXP = 0.79778
+K2W = 0.030809
+K2WEXP = 0.87253
+CIT = 1.0136148e-5
+CDSCD = 0.0011509049
+CDSCDL = -0.00048388809
+CDSCDLEXP = 0.13963388
+CDSCB = 9.9995516e-6
+CDSCBL = 1.4756534e-9
+CDSCBLEXP = 1
+NFACTOR = 0.0017201
+NFACTORL = 1.7832e-6
+NFACTORLEXP = 0.99988
+NFACTORW = 0.11149
+NFACTORWEXP = 0.8993
+NFACTORWL = -0.01386
+U0 = 0.04004
+U0L = 0.58676
+U0LEXP = 0.11151
+ETAMOB = 4.0947
+UA = 0.4298
+UAL = -0.0087246
+UALEXP = 1.3647
+UAW = 0.11575
+UAWEXP = 0.4385
+UAWL = -7.027e-5
+EU = 1.3371
+EUL = 0.0021948
+EULEXP = 1.4769
+EUW = -0.0031666
+EUWEXP = 1.9366
+EUWL = -0.00013929
+UD = 0.0093995
+UDL = 0.067484
+UDLEXP = 0.099452
+UCS = 0.9999
+UC = 4.91e-6
+UCL = 0.001096
+UCLEXP = 0.0015937
+VSAT = 9609100
+VSATL = 6.8282
+VSATLEXP = 0.086396
+VSATW = 0.016834
+VSATWEXP = 3.0172
+VSATCVL = 0
+VSATCVLEXP = 1
+VSATCVW = 0
+VSATCVWEXP = 1
+DELTA = 0.1779
+DELTAL = 0.1269
+DELTALEXP = 0.18156
+PCLM = 0
+PCLML = 0
+PCLMLEXP = 1e-13
+PCLMG = 0
+PCLMCVL = 0
+PCLMCVLEXP = 1
+PSCBE1 = 4.24e8
+PSCBE2 = 1e-8
+PDITS = 0.85536
+PDITSL = 8473.9
+PDITSD = 0
+PDIBLC = 0.005
+PDIBLCL = 0
+PDIBLCLEXP = 1
+PDIBLCB = -0.49995
+PVAG = 1
+FPROUT = 0
+FPROUTL = 0
+FPROUTLEXP = 1
+PTWG = 0.09999
+PTWGL = 0.069993
+PTWGLEXP = 0.0009999
+PSAT = 1e-13
+PSATL = 0
+PSATLEXP = 1
+PSATB = 0.9999
+PSATX = 1e-13
+RSH = 0
+PRWG = 1
+PRWB = 0.010098993
+PRWBL = 0.00070000265
+PRWBLEXP = 1
+WR = 1
+RSWMIN = 0
+RSW = 10
+RSWL = 0
+RSWLEXP = 1
+RDWMIN = 0
+RDW = 10
+RDWL = 0
+RDWLEXP = 1
+RDSWMIN = 0
+RDSW = 0
+RDSWL = 0.0007
+RDSWLEXP = 1e-7
+ALPHA0 = 0
+ALPHA0L = 0
+ALPHA0LEXP = 1
+BETA0 = 0
+AGIDL = 0
+AGIDLL = 0
+AGIDLW = 0
+BGIDL = 2.3e9
+CGIDL = 0.5
+EGIDL = 0.8
+AGISL = 0
+AGISLL = 0
+AGISLW = 0
+BGISL = 2.3e9
+CGISL = 0.5
+EGISL = 0.00171
+AIGBACC = 0.00171
+BIGBACC = 0.00171
+CIGBACC = 0.075
+NIGBACC = 1
+AIGBINV = 0.0111
+BIGBINV = 0.000949
+CIGBINV = 0.006
+EIGBINV = 1.1
+NIGBINV = 3
+AIGC = 0.0136
+AIGCL = 3
+AIGCW = 0.0136
+BIGC = 0.00171
+CIGC = 0.075
+AIGS = 0.0136
+AIGSL = 0.075
+AIGSW = 0.0136
+AIGD = 0.0136
+AIGDL = 0
+AIGDW = 0.0136
+BIGS = 0.00171
+BIGD = 0.00171
+CIGS = 0.075
+CIGD = 0.075
+TOXREF = 0.075
+NTOX = 1
+POXEDGE = 1
+PIGCD = 1
+PIGCDL = 1
+NDEPCV = 4.598e23
+NDEPCVL1 = 0
+NDEPCVLEXP1 = 1
+NDEPCVL2 = 0
+NDEPCVLEXP2 = 2
+NDEPCVW = 0
+NDEPCVWEXP = 1
+NDEPCVWL = 0
+NDEPCVWLEXP = 1
+NGATE = 7.764e25
+CF = 0
+CFRCOEFF = 1
+CGSO = 187.0e-12
+CGDO = 187.0e-12
+CGBO = 0
+CGSL = 130.0e-12
+CGDL = 130.0e-12
+CKAPPAS = 1.6
+CKAPPAD = 1.6
+ADOS = 221.4
+BDOS = 1.350
+QM0 = 405.7e-6
+ETAQM = 848.5e-3
+VFBCV = -996.0e-3
+VFBCVL = 0
+VFBCVLEXP = 1
+VFBCVW = 0
+VFBCVWEXP = 1
+VFBCVWL = 0
+VFBCVWLEXP = 1
+TBGASUB = 0.000473
+TBGBSUB = 636
+TDELTA = 0
+PTWGT = 0
+IIT = 0
+TGIDL = 0
+IGT = 0
+KT1 = -0.11
+KT1L = 0
+KT2 = 0.022
+KT1EXP = 1
+UTE = -1.5
+UA1 = 0.001
+UD1 = 0
+UC1 = -5.6e-11
+UCSTE = -0.004775
+PRT = 0
+AT = -0.00156
+SCA = 0
+SCB = 0
+SCC = 0
+SC = 0
+KU0WE = 0
+KVTH0WE = 0
+K2WE = 0
+WEB = 0
+WEC = 0
+SCREF = 1e-6
+SA = 0
+SB = 0
+SD = 0
+SAREF = 1e-6
+SBREF = 1e-6
+WLOD = 0
+KVSAT = 0
+KU0 = 0
+TKU0 = 0
+LKU0 = 0
+WKU0 = 0
+PKU0 = 0
+LLODKU0 = 0
+WLODKU0 = 0
+KVTH0 = 0
+LKVTH0 = 0
+WKVTH0 = 0
+PKVTH0 = 0
+LLODVTH = 0
+WLODVTH = 0
+STK2 = 0
+LODK2 = 1
+STETA0 = 0
+LODETA0 = 1
+RTH0 = 1e7
+MOBSCALE = 1

View File

@ -0,0 +1,283 @@
* psp_VA_and_CMC_ref_data 103.3.0 asym_nmos_t
* LEVEL=103.0
* https://www.cea.fr/cea-tech/leti/pspsupport/Documents/Level%20103.3.3/psp_VA_and_CMC_ref_data.tar.gz
.model nch psp103va level=69
+type=1
+TR=27.0
+DTA=0
+SWGEO=1
+QMC=1.0
+LVARO=-10.0E-9
+LVARL=0
+LVARW=0
+LAP=10.0E-9
+WVARO=10.0E-9
+WVARL=0
+WVARW=0
+WOT=0
+DLQ=0
+DWQ=0
+VFBO=-1.1
+VFBL=0
+VFBW=0
+VFBLW=0
+STVFBO=5.0E-4
+STVFBL=0
+STVFBW=0
+STVFBLW=0
+TOXO=1.5E-9
+EPSROXO=3.9
+NSUBO=3.0E+23
+NSUBW=0
+WSEG=1.5E-10
+NPCK=1.0E+24
+NPCKW=0
+WSEGP=0.9E-8
+LPCK=5.5E-8
+LPCKW=0
+FOL1=2.0E-2
+FOL2=5.0E-6
+FACNEFFACO=0.8
+FACNEFFACL=0
+FACNEFFACW=0
+FACNEFFACLW=0
+GFACNUDO=0.1
+GFACNUDL=0
+GFACNUDLEXP=1
+GFACNUDW=0
+GFACNUDLW=0
+VSBNUDO=0
+DVSBNUDO=1
+VNSUBO=0
+NSLPO=0.05
+DNSUBO=0
+DPHIBO=0
+DPHIBL=0
+DPHIBLEXP=1.0
+DPHIBW=0
+DPHIBLW=0
+DELVTACO=0
+DELVTACL=0
+DELVTACLEXP=1
+DELVTACW=0
+DELVTACLW=0
+NPO=1.5E+26
+NPL=10.0E-18
+CTO=5.0E-15
+CTL=4.0E-2
+CTLEXP=0.6
+CTW=0
+CTLW=0
+TOXOVO=1.5E-9
+TOXOVDO=2.0E-9
+LOV=10.0E-9
+LOVD=0
+NOVO=7.5E+25
+NOVDO=5.0e+25
+CFL=3.0E-4
+CFLEXP=2.0
+CFW=5.0E-3
+CFBO=0.3
+UO=3.5E-2
+FBET1=-0.3
+FBET1W=0.15
+LP1=1.5E-7
+LP1W=-2.5E-2
+FBET2=50.0
+LP2=8.5E-10
+BETW1=5.0E-2
+BETW2=-2.0E-2
+WBET=5.0E-10
+STBETO=1.75
+STBETL=-2.0E-2
+STBETW=-2.0E-3
+STBETLW=-3.0E-3
+MUEO=0.6
+MUEW=-1.2E-2
+STMUEO=0.5
+THEMUO=2.75
+STTHEMUO=-0.1
+CSO=1.0E-2
+CSL=0
+CSLEXP=1
+CSW=0
+CSLW=0
+STCSO=-5.0
+XCORO=0.15
+XCORL=2.0E-3
+XCORW=-3.0E-2
+XCORLW=-3.5E-3
+STXCORO=1.25
+FETAO=1
+RSW1=50
+RSW2=5.0E-2
+STRSO=-2.0
+RSBO=0
+RSGO=0
+THESATO=1.0E-6
+THESATL=0.6
+THESATLEXP=0.75
+THESATW=-1.0E-2
+THESATLW=0
+STTHESATO=1.5
+STTHESATL=-2.5E-2
+STTHESATW=-2.0E-2
+STTHESATLW=-5.0E-3
+THESATBO=0.15
+THESATGO=0.75
+AXO=20
+AXL=0.2
+ALPL=7.0E-3
+ALPLEXP=0.6
+ALPW=5.0E-2
+ALP1L1=2.5E-2
+ALP1LEXP=0.4
+ALP1L2=0.1
+ALP1W=8.5E-3
+ALP2L1=0.5
+ALP2LEXP=0
+ALP2L2=0.5
+ALP2W=-0.2
+VPO=0.25
+A1O=1.0
+A1L=0
+A1W=0
+A2O=10.0
+STA2O=-0.5
+A3O=1.0
+A3L=0
+A3W=0
+A4O=0
+A4L=0
+A4W=0
+GCOO=5.0
+IGINVLW=50.0
+IGOVW=10.0
+IGOVDW=0
+STIGO=1.5
+GC2O=1.0
+GC3O=-1.0
+CHIBO=3.1
+AGIDLW=50.0
+AGIDLDW=0
+BGIDLO=35.0
+BGIDLDO=41
+STBGIDLO=-5.0E-4
+STBGIDLDO=0
+CGIDLO=0.15
+CGIDLDO=0
+CGBOVL=0
+CFRW=5.0E-17
+CFRDW=0
+FNTO=1
+NFALW=8.0E+22
+NFBLW=3.0E7
+NFCLW=0
+RGO=0
+RINT=0
+RVPOLY=0
+RSHG=0
+DLSIL=0
+RBULKO=0
+RWELLO=0
+RJUNDO=0
+RJUNSO=0
+SWJUNEXP=0
+TRJ=27.0
+IMAX=1.0E3
+VJUNREF=2.5
+FJUNQ=0.03
+CJORBOT=1.0E-3
+CJORSTI=1.0E-9
+CJORGAT=0.5E-9
+VBIRBOT=0.75
+VBIRSTI=1.0
+VBIRGAT=0.75
+PBOT=0.35
+PSTI=0.35
+PGAT=0.6
+PHIGBOT=1.16
+PHIGSTI=1.16
+PHIGGAT=1.16
+IDSATRBOT=5.0E-9
+IDSATRSTI=1.0E-18
+IDSATRGAT=1.0E-18
+CSRHBOT=5.0E2
+CSRHSTI=0
+CSRHGAT=1.0E3
+XJUNSTI=1.0E-8
+XJUNGAT=1.0E-9
+CTATBOT=5.0E2
+CTATSTI=0
+CTATGAT=1.0E3
+MEFFTATBOT=0.25
+MEFFTATSTI=0.25
+MEFFTATGAT=0.25
+CBBTBOT=1.0E-12
+CBBTSTI=1.0E-18
+CBBTGAT=1.0E-18
+FBBTRBOT=1.0E9
+FBBTRSTI=1.0E9
+FBBTRGAT=1.0E9
+STFBBTBOT=-1.0E-3
+STFBBTSTI=-1.0E-3
+STFBBTGAT=-1.0E-2
+VBRBOT=10.0
+VBRSTI=10.0
+VBRGAT=10.0
+PBRBOT=3
+PBRSTI=4
+PBRGAT=3
+VJUNREFD=2.5
+FJUNQD=0.03
+CJORBOTD=1.0E-3
+CJORSTID=1.0E-9
+CJORGATD=1.0E-9
+VBIRBOTD=1.0
+VBIRSTID=1.0
+VBIRGATD=1.0
+PBOTD=0.5
+PSTID=0.5
+PGATD=0.5
+PHIGBOTD=1.16
+PHIGSTID=1.16
+PHIGGATD=1.16
+IDSATRBOTD=1.0E-12
+IDSATRSTID=1.0E-18
+IDSATRGATD=1.0E-18
+CSRHBOTD=1.0E+2
+CSRHSTID=1.0E-4
+CSRHGATD=1.0E-4
+XJUNSTID=1.0E-7
+XJUNGATD=1.0E-7
+CTATBOTD=1.0E+2
+CTATSTID=1.0E-4
+CTATGATD=1.0E-4
+MEFFTATBOTD=0.25
+MEFFTATSTID=0.25
+MEFFTATGATD=0.25
+CBBTBOTD=1.0E-12
+CBBTSTID=1.0E-18
+CBBTGATD=1.0E-18
+FBBTRBOTD=1.0E9
+FBBTRSTID=1.0E9
+FBBTRGATD=1.0E9
+STFBBTBOTD=-1.0E-3
+STFBBTSTID=-1.0E-3
+STFBBTGATD=-1.0E-3
+VBRBOTD=10.0
+VBRSTID=10.0
+VBRGATD=10.0
+PBRBOTD=4
+PBRSTID=4
+PBRGATD=4
* thermal parameters
*+RTHO=1.1E4
*+RTHW1=990.5
*+RTHW2=14.4
*+RTHLW=15.0
*+CTHO =1.0E-7
*+CTHW1=1.0e-8
*+CTHW2=1.5
*+CTHLW=4.0
*+STRTHO=1.3

View File

@ -0,0 +1,283 @@
* psp_VA_and_CMC_ref_data 103.3.0 asym_pmos_t
* LEVEL=103.0
* https://www.cea.fr/cea-tech/leti/pspsupport/Documents/Level%20103.3.3/psp_VA_and_CMC_ref_data.tar.gz
.model pch psp103va level=69
+TYPE=-1
+TR=27.0
+DTA=0
+SWGEO=1
+QMC=1.0
+LVARO=-10.0E-9
+LVARL=0
+LVARW=0
+LAP=10.0E-9
+WVARO=10.0E-9
+WVARL=0
+WVARW=0
+WOT=0
+DLQ=0
+DWQ=0
+VFBO=-1.1
+VFBL=0
+VFBW=0
+VFBLW=0
+STVFBO=5.0E-4
+STVFBL=0
+STVFBW=0
+STVFBLW=0
+TOXO=1.5E-9
+EPSROXO=3.9
+NSUBO=3.0E+23
+NSUBW=0
+WSEG=1.5E-10
+NPCK=1.0E+24
+NPCKW=0
+WSEGP=0.9E-8
+LPCK=5.5E-8
+LPCKW=0
+FOL1=2.0E-2
+FOL2=5.0E-6
+FACNEFFACO=0.8
+FACNEFFACL=0
+FACNEFFACW=0
+FACNEFFACLW=0
+GFACNUDO=0.1
+GFACNUDL=0
+GFACNUDLEXP=1
+GFACNUDW=0
+GFACNUDLW=0
+VSBNUDO=0
+DVSBNUDO=1
+VNSUBO=0
+NSLPO=0.05
+DNSUBO=0
+DPHIBO=0
+DPHIBL=0
+DPHIBLEXP=1.0
+DPHIBW=0
+DPHIBLW=0
+DELVTACO=0
+DELVTACL=0
+DELVTACLEXP=1
+DELVTACW=0
+DELVTACLW=0
+NPO=1.5E+26
+NPL=10.0E-18
+CTO=5.0E-15
+CTL=4.0E-2
+CTLEXP=0.6
+CTW=0
+CTLW=0
+TOXOVO=1.5E-9
+TOXOVDO=2.0E-9
+LOV=10.0E-9
+LOVD=0
+NOVO=7.5E+25
+NOVDO=5.0e+25
+CFL=3.0E-4
+CFLEXP=2.0
+CFW=5.0E-3
+CFBO=0.3
+UO=3.5E-2
+FBET1=-0.3
+FBET1W=0.15
+LP1=1.5E-7
+LP1W=-2.5E-2
+FBET2=50.0
+LP2=8.5E-10
+BETW1=5.0E-2
+BETW2=-2.0E-2
+WBET=5.0E-10
+STBETO=1.75
+STBETL=-2.0E-2
+STBETW=-2.0E-3
+STBETLW=-3.0E-3
+MUEO=0.6
+MUEW=-1.2E-2
+STMUEO=0.5
+THEMUO=2.75
+STTHEMUO=-0.1
+CSO=1.0E-2
+CSL=0
+CSLEXP=1
+CSW=0
+CSLW=0
+STCSO=-5.0
+XCORO=0.15
+XCORL=2.0E-3
+XCORW=-3.0E-2
+XCORLW=-3.5E-3
+STXCORO=1.25
+FETAO=1
+RSW1=50
+RSW2=5.0E-2
+STRSO=-2.0
+RSBO=0
+RSGO=0
+THESATO=1.0E-6
+THESATL=0.6
+THESATLEXP=0.75
+THESATW=-1.0E-2
+THESATLW=0
+STTHESATO=1.5
+STTHESATL=-2.5E-2
+STTHESATW=-2.0E-2
+STTHESATLW=-5.0E-3
+THESATBO=0.15
+THESATGO=0.75
+AXO=20
+AXL=0.2
+ALPL=7.0E-3
+ALPLEXP=0.6
+ALPW=5.0E-2
+ALP1L1=2.5E-2
+ALP1LEXP=0.4
+ALP1L2=0.1
+ALP1W=8.5E-3
+ALP2L1=0.5
+ALP2LEXP=0
+ALP2L2=0.5
+ALP2W=-0.2
+VPO=0.25
+A1O=1.0
+A1L=0
+A1W=0
+A2O=10.0
+STA2O=-0.5
+A3O=1.0
+A3L=0
+A3W=0
+A4O=0
+A4L=0
+A4W=0
+GCOO=5.0
+IGINVLW=50.0
+IGOVW=10.0
+IGOVDW=0
+STIGO=1.5
+GC2O=1.0
+GC3O=-1.0
+CHIBO=3.1
+AGIDLW=50.0
+AGIDLDW=0
+BGIDLO=35.0
+BGIDLDO=41
+STBGIDLO=-5.0E-4
+STBGIDLDO=0
+CGIDLO=0.15
+CGIDLDO=0
+CGBOVL=0
+CFRW=5.0E-17
+CFRDW=0
+FNTO=1
+NFALW=8.0E+22
+NFBLW=3.0E7
+NFCLW=0
+RGO=0
+RINT=0
+RVPOLY=0
+RSHG=0
+DLSIL=0
+RBULKO=0
+RWELLO=0
+RJUNDO=0
+RJUNSO=0
+SWJUNEXP=0
+TRJ=27.0
+IMAX=1.0E3
+VJUNREF=2.5
+FJUNQ=0.03
+CJORBOT=1.0E-3
+CJORSTI=1.0E-9
+CJORGAT=0.5E-9
+VBIRBOT=0.75
+VBIRSTI=1.0
+VBIRGAT=0.75
+PBOT=0.35
+PSTI=0.35
+PGAT=0.6
+PHIGBOT=1.16
+PHIGSTI=1.16
+PHIGGAT=1.16
+IDSATRBOT=5.0E-9
+IDSATRSTI=1.0E-18
+IDSATRGAT=1.0E-18
+CSRHBOT=5.0E2
+CSRHSTI=0
+CSRHGAT=1.0E3
+XJUNSTI=1.0E-8
+XJUNGAT=1.0E-9
+CTATBOT=5.0E2
+CTATSTI=0
+CTATGAT=1.0E3
+MEFFTATBOT=0.25
+MEFFTATSTI=0.25
+MEFFTATGAT=0.25
+CBBTBOT=1.0E-12
+CBBTSTI=1.0E-18
+CBBTGAT=1.0E-18
+FBBTRBOT=1.0E9
+FBBTRSTI=1.0E9
+FBBTRGAT=1.0E9
+STFBBTBOT=-1.0E-3
+STFBBTSTI=-1.0E-3
+STFBBTGAT=-1.0E-2
+VBRBOT=10.0
+VBRSTI=10.0
+VBRGAT=10.0
+PBRBOT=3
+PBRSTI=4
+PBRGAT=3
+VJUNREFD=2.5
+FJUNQD=0.03
+CJORBOTD=1.0E-3
+CJORSTID=1.0E-9
+CJORGATD=1.0E-9
+VBIRBOTD=1.0
+VBIRSTID=1.0
+VBIRGATD=1.0
+PBOTD=0.5
+PSTID=0.5
+PGATD=0.5
+PHIGBOTD=1.16
+PHIGSTID=1.16
+PHIGGATD=1.16
+IDSATRBOTD=1.0E-12
+IDSATRSTID=1.0E-18
+IDSATRGATD=1.0E-18
+CSRHBOTD=1.0E+2
+CSRHSTID=1.0E-4
+CSRHGATD=1.0E-4
+XJUNSTID=1.0E-7
+XJUNGATD=1.0E-7
+CTATBOTD=1.0E+2
+CTATSTID=1.0E-4
+CTATGATD=1.0E-4
+MEFFTATBOTD=0.25
+MEFFTATSTID=0.25
+MEFFTATGATD=0.25
+CBBTBOTD=1.0E-12
+CBBTSTID=1.0E-18
+CBBTGATD=1.0E-18
+FBBTRBOTD=1.0E9
+FBBTRSTID=1.0E9
+FBBTRGATD=1.0E9
+STFBBTBOTD=-1.0E-3
+STFBBTSTID=-1.0E-3
+STFBBTGATD=-1.0E-3
+VBRBOTD=10.0
+VBRSTID=10.0
+VBRGATD=10.0
+PBRBOTD=4
+PBRSTID=4
+PBRGATD=4
* thermal parameters
*+RTHO=1.1E4
*+RTHW1=990.5
*+RTHW2=14.4
*+RTHLW=15.0
*+CTHO =1.0E-7
*+CTHW1=1.0e-8
*+CTHW2=1.5
*+CTHLW=4.0
*+STRTHO=1.3

View File

@ -0,0 +1,80 @@
* Mix up two models
* BSIMBULK model vers. 107
* PSP model vers. 103
* simple 5-stage ring oscillator
* Power supply
.param Vcc = 1.2
* Path to the models
.include Modelcards/model.l
.include Modelcards/psp103_nmos-2.mod
.include Modelcards/psp103_pmos-2.mod
* The voltage sources:
Vdd vdd gnd DC 'Vcc'
V1 in gnd pulse(0 'Vcc' 0p 200p 100p 1n 2n)
Vmeas vss 0 0
* The circuit: five stages
Xnot1 in vdd vss in2 notbb
Xnot2 in2 vdd vss in3 notpsp
Xnot3 in3 vdd vss in4 notbb
Xnot4 in4 vdd vss in5 notpsp
Xnot5 in5 vdd vss in notbb
* Inverter BSIMBULK
.subckt notbb a vdd vss z
Np1 z a vdd vdd BSIMBULK_osdi_P l=0.1u w=1u as=0.26235p ad=0.26235p ps=2.51u pd=2.51u
Nn1 z a vss vss BSIMBULK_osdi_N l=0.1u w=0.5u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u
c3 a vss 0.384f
c2 z vss 0.576f
.ends
* Inverter PSP
.subckt notpsp a vdd vss z
nmp1 z a vdd vdd pch
+l=0.1u
+w=1u
+sa=0.0e+00
+sb=0.0e+00
+absource=1.0e-12
+lssource=1.0e-06
+lgsource=1.0e-06
+abdrain=1.0e-12
+lsdrain=1.0e-06
+lgdrain=1.0e-06
+mult=1.0e+00
nmn1 z a vss vss nch
+l=0.1u
+w=1u
+sa=0.0e+00
+sb=0.0e+00
+absource=1.0e-12
+lssource=1.0e-06
+lgsource=1.0e-06
+abdrain=1.0e-12
+lsdrain=1.0e-06
+lgdrain=1.0e-06
+mult=1.0e+00
c3 a vss 0.384f
c2 z vss 0.576f
.ends
* Simulation command:
.tran 10p 10n uic
.control
* Load the models dynamically
pre_osdi test_osdi_win/bsimbulk107.osdi test_osdi_win/psp103.osdi
* Run the simulation
run
* Plotting
set xbrushwidth=3
plot in
* Resource usage
rusage
.endc
.end

View File

@ -0,0 +1,40 @@
* BSIMBULK model vers. 107
* simple inverter
.param Vcc = 1.2
.csparam vcc='Vcc'
* Path to the models
.include Modelcards/model.l
* the voltage sources:
Vdd vdd gnd DC 'Vcc'
V1 in gnd pulse(0 'Vcc' 0p 200p 100p 1n 2n)
Vmeas vss 0 0
Xnot1 in vdd vss out not1
*Rout out 0 1k
.subckt not1 a vdd vss z
Np1 z a vdd vdd BSIMBULK_osdi_P l=0.1u w=1u as=0.26235p ad=0.26235p ps=2.51u pd=2.51u
Nn1 z a vss vss BSIMBULK_osdi_N l=0.1u w=0.5u as=0.131175p ad=0.131175p ps=1.52u pd=1.52u
c3 a vss 0.384f
c2 z vss 0.576f
.ends
* simulation command:
.tran 10ps 10ns
.dc V1 0 'vcc' 'vcc/100'
.control
pre_osdi test_osdi_win/bsimbulk107.osdi
run
*set nolegend
set xbrushwidth=3
plot in out
plot dc1.out
plot dc1.i(Vmeas)
rusage
.endc
.end

View File

@ -0,0 +1,66 @@
* PSP models
* simple inverter
.param Vcc = 1.2
.csparam vcc='Vcc'
* Path to the models
.include Modelcards/psp103_nmos-2.mod
.include Modelcards/psp103_pmos-2.mod
* the voltage sources:
Vdd vdd gnd DC 'Vcc'
V1 in gnd pulse(0 'Vcc' 0p 200p 100p 1n 2n)
Vmeas vss 0 0
Xnot1 in vdd vss out not1
*Rout out 0 1k
.subckt not1 a vdd vss z
*m01 z a vdd vdd pch l=0.1u w=1u as=0.26235 ad=0.26235 ps=2.51 pd=2.51
nmp1 z a vdd vdd pch
+l=0.1u
+w=1u
+sa=0.0e+00
+sb=0.0e+00
+absource=1.0e-12
+lssource=1.0e-06
+lgsource=1.0e-06
+abdrain=1.0e-12
+lsdrain=1.0e-06
+lgdrain=1.0e-06
+mult=1.0e+00
*m02 z a vss vss nch l=0.1u w=0.5u as=0.131175 ad=0.131175 ps=1.52 pd=1.52
nmn1 z a vss vss nch
+l=0.1u
+w=1u
+sa=0.0e+00
+sb=0.0e+00
+absource=1.0e-12
+lssource=1.0e-06
+lgsource=1.0e-06
+abdrain=1.0e-12
+lsdrain=1.0e-06
+lgdrain=1.0e-06
+mult=1.0e+00
c3 a vss 0.384f
c2 z vss 0.576f
.ends
* simulation command:
.tran 10ps 10ns
.dc V1 0 'vcc' 'vcc/100'
.control
pre_osdi test_osdi_win/psp103.osdi
run
*set nolegend
set xbrushwidth=2
plot in out
plot dc1.out
plot dc1.i(Vmeas)
rusage
.endc
.end

View File

@ -0,0 +1 @@
Place bsimbulk107.osdi and psp103.osdi here.

View File

@ -0,0 +1,283 @@
* psp_VA_and_CMC_ref_data 103.3.0 asym_nmos_t
* LEVEL=103.0
* https://www.cea.fr/cea-tech/leti/pspsupport/Documents/Level%20103.3.3/psp_VA_and_CMC_ref_data.tar.gz
.model nch psp103va level=69
+type=1
+TR=27.0
+DTA=0
+SWGEO=1
+QMC=1.0
+LVARO=-10.0E-9
+LVARL=0
+LVARW=0
+LAP=10.0E-9
+WVARO=10.0E-9
+WVARL=0
+WVARW=0
+WOT=0
+DLQ=0
+DWQ=0
+VFBO=-1.1
+VFBL=0
+VFBW=0
+VFBLW=0
+STVFBO=5.0E-4
+STVFBL=0
+STVFBW=0
+STVFBLW=0
+TOXO=1.5E-9
+EPSROXO=3.9
+NSUBO=3.0E+23
+NSUBW=0
+WSEG=1.5E-10
+NPCK=1.0E+24
+NPCKW=0
+WSEGP=0.9E-8
+LPCK=5.5E-8
+LPCKW=0
+FOL1=2.0E-2
+FOL2=5.0E-6
+FACNEFFACO=0.8
+FACNEFFACL=0
+FACNEFFACW=0
+FACNEFFACLW=0
+GFACNUDO=0.1
+GFACNUDL=0
+GFACNUDLEXP=1
+GFACNUDW=0
+GFACNUDLW=0
+VSBNUDO=0
+DVSBNUDO=1
+VNSUBO=0
+NSLPO=0.05
+DNSUBO=0
+DPHIBO=0
+DPHIBL=0
+DPHIBLEXP=1.0
+DPHIBW=0
+DPHIBLW=0
+DELVTACO=0
+DELVTACL=0
+DELVTACLEXP=1
+DELVTACW=0
+DELVTACLW=0
+NPO=1.5E+26
+NPL=10.0E-18
+CTO=5.0E-15
+CTL=4.0E-2
+CTLEXP=0.6
+CTW=0
+CTLW=0
+TOXOVO=1.5E-9
+TOXOVDO=2.0E-9
+LOV=10.0E-9
+LOVD=0
+NOVO=7.5E+25
+NOVDO=5.0e+25
+CFL=3.0E-4
+CFLEXP=2.0
+CFW=5.0E-3
+CFBO=0.3
+UO=3.5E-2
+FBET1=-0.3
+FBET1W=0.15
+LP1=1.5E-7
+LP1W=-2.5E-2
+FBET2=50.0
+LP2=8.5E-10
+BETW1=5.0E-2
+BETW2=-2.0E-2
+WBET=5.0E-10
+STBETO=1.75
+STBETL=-2.0E-2
+STBETW=-2.0E-3
+STBETLW=-3.0E-3
+MUEO=0.6
+MUEW=-1.2E-2
+STMUEO=0.5
+THEMUO=2.75
+STTHEMUO=-0.1
+CSO=1.0E-2
+CSL=0
+CSLEXP=1
+CSW=0
+CSLW=0
+STCSO=-5.0
+XCORO=0.15
+XCORL=2.0E-3
+XCORW=-3.0E-2
+XCORLW=-3.5E-3
+STXCORO=1.25
+FETAO=1
+RSW1=50
+RSW2=5.0E-2
+STRSO=-2.0
+RSBO=0
+RSGO=0
+THESATO=1.0E-6
+THESATL=0.6
+THESATLEXP=0.75
+THESATW=-1.0E-2
+THESATLW=0
+STTHESATO=1.5
+STTHESATL=-2.5E-2
+STTHESATW=-2.0E-2
+STTHESATLW=-5.0E-3
+THESATBO=0.15
+THESATGO=0.75
+AXO=20
+AXL=0.2
+ALPL=7.0E-3
+ALPLEXP=0.6
+ALPW=5.0E-2
+ALP1L1=2.5E-2
+ALP1LEXP=0.4
+ALP1L2=0.1
+ALP1W=8.5E-3
+ALP2L1=0.5
+ALP2LEXP=0
+ALP2L2=0.5
+ALP2W=-0.2
+VPO=0.25
+A1O=1.0
+A1L=0
+A1W=0
+A2O=10.0
+STA2O=-0.5
+A3O=1.0
+A3L=0
+A3W=0
+A4O=0
+A4L=0
+A4W=0
+GCOO=5.0
+IGINVLW=50.0
+IGOVW=10.0
+IGOVDW=0
+STIGO=1.5
+GC2O=1.0
+GC3O=-1.0
+CHIBO=3.1
+AGIDLW=50.0
+AGIDLDW=0
+BGIDLO=35.0
+BGIDLDO=41
+STBGIDLO=-5.0E-4
+STBGIDLDO=0
+CGIDLO=0.15
+CGIDLDO=0
+CGBOVL=0
+CFRW=5.0E-17
+CFRDW=0
+FNTO=1
+NFALW=8.0E+22
+NFBLW=3.0E7
+NFCLW=0
+RGO=0
+RINT=0
+RVPOLY=0
+RSHG=0
+DLSIL=0
+RBULKO=0
+RWELLO=0
+RJUNDO=0
+RJUNSO=0
+SWJUNEXP=0
+TRJ=27.0
+IMAX=1.0E3
+VJUNREF=2.5
+FJUNQ=0.03
+CJORBOT=1.0E-3
+CJORSTI=1.0E-9
+CJORGAT=0.5E-9
+VBIRBOT=0.75
+VBIRSTI=1.0
+VBIRGAT=0.75
+PBOT=0.35
+PSTI=0.35
+PGAT=0.6
+PHIGBOT=1.16
+PHIGSTI=1.16
+PHIGGAT=1.16
+IDSATRBOT=5.0E-9
+IDSATRSTI=1.0E-18
+IDSATRGAT=1.0E-18
+CSRHBOT=5.0E2
+CSRHSTI=0
+CSRHGAT=1.0E3
+XJUNSTI=1.0E-8
+XJUNGAT=1.0E-9
+CTATBOT=5.0E2
+CTATSTI=0
+CTATGAT=1.0E3
+MEFFTATBOT=0.25
+MEFFTATSTI=0.25
+MEFFTATGAT=0.25
+CBBTBOT=1.0E-12
+CBBTSTI=1.0E-18
+CBBTGAT=1.0E-18
+FBBTRBOT=1.0E9
+FBBTRSTI=1.0E9
+FBBTRGAT=1.0E9
+STFBBTBOT=-1.0E-3
+STFBBTSTI=-1.0E-3
+STFBBTGAT=-1.0E-2
+VBRBOT=10.0
+VBRSTI=10.0
+VBRGAT=10.0
+PBRBOT=3
+PBRSTI=4
+PBRGAT=3
+VJUNREFD=2.5
+FJUNQD=0.03
+CJORBOTD=1.0E-3
+CJORSTID=1.0E-9
+CJORGATD=1.0E-9
+VBIRBOTD=1.0
+VBIRSTID=1.0
+VBIRGATD=1.0
+PBOTD=0.5
+PSTID=0.5
+PGATD=0.5
+PHIGBOTD=1.16
+PHIGSTID=1.16
+PHIGGATD=1.16
+IDSATRBOTD=1.0E-12
+IDSATRSTID=1.0E-18
+IDSATRGATD=1.0E-18
+CSRHBOTD=1.0E+2
+CSRHSTID=1.0E-4
+CSRHGATD=1.0E-4
+XJUNSTID=1.0E-7
+XJUNGATD=1.0E-7
+CTATBOTD=1.0E+2
+CTATSTID=1.0E-4
+CTATGATD=1.0E-4
+MEFFTATBOTD=0.25
+MEFFTATSTID=0.25
+MEFFTATGATD=0.25
+CBBTBOTD=1.0E-12
+CBBTSTID=1.0E-18
+CBBTGATD=1.0E-18
+FBBTRBOTD=1.0E9
+FBBTRSTID=1.0E9
+FBBTRGATD=1.0E9
+STFBBTBOTD=-1.0E-3
+STFBBTSTID=-1.0E-3
+STFBBTGATD=-1.0E-3
+VBRBOTD=10.0
+VBRSTID=10.0
+VBRGATD=10.0
+PBRBOTD=4
+PBRSTID=4
+PBRGATD=4
* thermal parameters
*+RTHO=1.1E4
*+RTHW1=990.5
*+RTHW2=14.4
*+RTHLW=15.0
*+CTHO =1.0E-7
*+CTHW1=1.0e-8
*+CTHW2=1.5
*+CTHLW=4.0
*+STRTHO=1.3

View File

@ -0,0 +1,283 @@
* psp_VA_and_CMC_ref_data 103.3.0 asym_pmos_t
* LEVEL=103.0
* https://www.cea.fr/cea-tech/leti/pspsupport/Documents/Level%20103.3.3/psp_VA_and_CMC_ref_data.tar.gz
.model pch psp103va level=69
+TYPE=-1
+TR=27.0
+DTA=0
+SWGEO=1
+QMC=1.0
+LVARO=-10.0E-9
+LVARL=0
+LVARW=0
+LAP=10.0E-9
+WVARO=10.0E-9
+WVARL=0
+WVARW=0
+WOT=0
+DLQ=0
+DWQ=0
+VFBO=-1.1
+VFBL=0
+VFBW=0
+VFBLW=0
+STVFBO=5.0E-4
+STVFBL=0
+STVFBW=0
+STVFBLW=0
+TOXO=1.5E-9
+EPSROXO=3.9
+NSUBO=3.0E+23
+NSUBW=0
+WSEG=1.5E-10
+NPCK=1.0E+24
+NPCKW=0
+WSEGP=0.9E-8
+LPCK=5.5E-8
+LPCKW=0
+FOL1=2.0E-2
+FOL2=5.0E-6
+FACNEFFACO=0.8
+FACNEFFACL=0
+FACNEFFACW=0
+FACNEFFACLW=0
+GFACNUDO=0.1
+GFACNUDL=0
+GFACNUDLEXP=1
+GFACNUDW=0
+GFACNUDLW=0
+VSBNUDO=0
+DVSBNUDO=1
+VNSUBO=0
+NSLPO=0.05
+DNSUBO=0
+DPHIBO=0
+DPHIBL=0
+DPHIBLEXP=1.0
+DPHIBW=0
+DPHIBLW=0
+DELVTACO=0
+DELVTACL=0
+DELVTACLEXP=1
+DELVTACW=0
+DELVTACLW=0
+NPO=1.5E+26
+NPL=10.0E-18
+CTO=5.0E-15
+CTL=4.0E-2
+CTLEXP=0.6
+CTW=0
+CTLW=0
+TOXOVO=1.5E-9
+TOXOVDO=2.0E-9
+LOV=10.0E-9
+LOVD=0
+NOVO=7.5E+25
+NOVDO=5.0e+25
+CFL=3.0E-4
+CFLEXP=2.0
+CFW=5.0E-3
+CFBO=0.3
+UO=3.5E-2
+FBET1=-0.3
+FBET1W=0.15
+LP1=1.5E-7
+LP1W=-2.5E-2
+FBET2=50.0
+LP2=8.5E-10
+BETW1=5.0E-2
+BETW2=-2.0E-2
+WBET=5.0E-10
+STBETO=1.75
+STBETL=-2.0E-2
+STBETW=-2.0E-3
+STBETLW=-3.0E-3
+MUEO=0.6
+MUEW=-1.2E-2
+STMUEO=0.5
+THEMUO=2.75
+STTHEMUO=-0.1
+CSO=1.0E-2
+CSL=0
+CSLEXP=1
+CSW=0
+CSLW=0
+STCSO=-5.0
+XCORO=0.15
+XCORL=2.0E-3
+XCORW=-3.0E-2
+XCORLW=-3.5E-3
+STXCORO=1.25
+FETAO=1
+RSW1=50
+RSW2=5.0E-2
+STRSO=-2.0
+RSBO=0
+RSGO=0
+THESATO=1.0E-6
+THESATL=0.6
+THESATLEXP=0.75
+THESATW=-1.0E-2
+THESATLW=0
+STTHESATO=1.5
+STTHESATL=-2.5E-2
+STTHESATW=-2.0E-2
+STTHESATLW=-5.0E-3
+THESATBO=0.15
+THESATGO=0.75
+AXO=20
+AXL=0.2
+ALPL=7.0E-3
+ALPLEXP=0.6
+ALPW=5.0E-2
+ALP1L1=2.5E-2
+ALP1LEXP=0.4
+ALP1L2=0.1
+ALP1W=8.5E-3
+ALP2L1=0.5
+ALP2LEXP=0
+ALP2L2=0.5
+ALP2W=-0.2
+VPO=0.25
+A1O=1.0
+A1L=0
+A1W=0
+A2O=10.0
+STA2O=-0.5
+A3O=1.0
+A3L=0
+A3W=0
+A4O=0
+A4L=0
+A4W=0
+GCOO=5.0
+IGINVLW=50.0
+IGOVW=10.0
+IGOVDW=0
+STIGO=1.5
+GC2O=1.0
+GC3O=-1.0
+CHIBO=3.1
+AGIDLW=50.0
+AGIDLDW=0
+BGIDLO=35.0
+BGIDLDO=41
+STBGIDLO=-5.0E-4
+STBGIDLDO=0
+CGIDLO=0.15
+CGIDLDO=0
+CGBOVL=0
+CFRW=5.0E-17
+CFRDW=0
+FNTO=1
+NFALW=8.0E+22
+NFBLW=3.0E7
+NFCLW=0
+RGO=0
+RINT=0
+RVPOLY=0
+RSHG=0
+DLSIL=0
+RBULKO=0
+RWELLO=0
+RJUNDO=0
+RJUNSO=0
+SWJUNEXP=0
+TRJ=27.0
+IMAX=1.0E3
+VJUNREF=2.5
+FJUNQ=0.03
+CJORBOT=1.0E-3
+CJORSTI=1.0E-9
+CJORGAT=0.5E-9
+VBIRBOT=0.75
+VBIRSTI=1.0
+VBIRGAT=0.75
+PBOT=0.35
+PSTI=0.35
+PGAT=0.6
+PHIGBOT=1.16
+PHIGSTI=1.16
+PHIGGAT=1.16
+IDSATRBOT=5.0E-9
+IDSATRSTI=1.0E-18
+IDSATRGAT=1.0E-18
+CSRHBOT=5.0E2
+CSRHSTI=0
+CSRHGAT=1.0E3
+XJUNSTI=1.0E-8
+XJUNGAT=1.0E-9
+CTATBOT=5.0E2
+CTATSTI=0
+CTATGAT=1.0E3
+MEFFTATBOT=0.25
+MEFFTATSTI=0.25
+MEFFTATGAT=0.25
+CBBTBOT=1.0E-12
+CBBTSTI=1.0E-18
+CBBTGAT=1.0E-18
+FBBTRBOT=1.0E9
+FBBTRSTI=1.0E9
+FBBTRGAT=1.0E9
+STFBBTBOT=-1.0E-3
+STFBBTSTI=-1.0E-3
+STFBBTGAT=-1.0E-2
+VBRBOT=10.0
+VBRSTI=10.0
+VBRGAT=10.0
+PBRBOT=3
+PBRSTI=4
+PBRGAT=3
+VJUNREFD=2.5
+FJUNQD=0.03
+CJORBOTD=1.0E-3
+CJORSTID=1.0E-9
+CJORGATD=1.0E-9
+VBIRBOTD=1.0
+VBIRSTID=1.0
+VBIRGATD=1.0
+PBOTD=0.5
+PSTID=0.5
+PGATD=0.5
+PHIGBOTD=1.16
+PHIGSTID=1.16
+PHIGGATD=1.16
+IDSATRBOTD=1.0E-12
+IDSATRSTID=1.0E-18
+IDSATRGATD=1.0E-18
+CSRHBOTD=1.0E+2
+CSRHSTID=1.0E-4
+CSRHGATD=1.0E-4
+XJUNSTID=1.0E-7
+XJUNGATD=1.0E-7
+CTATBOTD=1.0E+2
+CTATSTID=1.0E-4
+CTATGATD=1.0E-4
+MEFFTATBOTD=0.25
+MEFFTATSTID=0.25
+MEFFTATGATD=0.25
+CBBTBOTD=1.0E-12
+CBBTSTID=1.0E-18
+CBBTGATD=1.0E-18
+FBBTRBOTD=1.0E9
+FBBTRSTID=1.0E9
+FBBTRGATD=1.0E9
+STFBBTBOTD=-1.0E-3
+STFBBTSTID=-1.0E-3
+STFBBTGATD=-1.0E-3
+VBRBOTD=10.0
+VBRSTID=10.0
+VBRGATD=10.0
+PBRBOTD=4
+PBRSTID=4
+PBRGATD=4
* thermal parameters
*+RTHO=1.1E4
*+RTHW1=990.5
*+RTHW2=14.4
*+RTHLW=15.0
*+CTHO =1.0E-7
*+CTHW1=1.0e-8
*+CTHW2=1.5
*+CTHLW=4.0
*+STRTHO=1.3

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
*** NMOS and PMOS transistors PSP 103.8 (Id-Vgs, Vbs) (Id-Vds, Vgs) (Id-Vgs, T) ***
nmn1 2 1 3 4 nch
+l=0.1u
+w=1u
+sa=0.0e+00
+sb=0.0e+00
+absource=1.0e-12
+lssource=1.0e-06
+lgsource=1.0e-06
+abdrain=1.0e-12
+lsdrain=1.0e-06
+lgdrain=1.0e-06
+mult=1.0e+00
vgsn 1 0 3.5
vdsn 2 0 0.1
vssn 3 0 0
vbsn 4 0 0
nmp1 22 11 33 44 pch
+l=0.1u
+w=1u
+sa=0.0e+00
+sb=0.0e+00
+absource=1.0e-12
+lssource=1.0e-06
+lgsource=1.0e-06
+abdrain=1.0e-12
+lsdrain=1.0e-06
+lgdrain=1.0e-06
+mult=1.0e+00
vgsp 11 0 -3.5
vdsp 22 0 -0.1
vssp 33 0 0
vbsp 44 0 0
* PSP modelparameters for PSP 103.3
.include Modelcards/psp103_nmos-2.mod
.include Modelcards/psp103_pmos-2.mod
.control
* Load the models dynamically
pre_osdi test_osdi_win/psp103.osdi
set xgridwidth=2
set xbrushwidth=3
* NMOS
dc vgsn 0 1.5 0.05 vbsn 0 -1.5 -0.3
plot vssn#branch ylabel 'Id vs. Vgs, Vbs 0 ... -1.5'
plot abs(vssn#branch) ylog ylabel 'Id vs. Vgs, Vbs 0 ... -1.5'
dc vdsn 0 1.6 0.01 vgsn 0 1.6 0.2
plot vssn#branch ylabel 'Id vs. Vds, Vgs 0 ... 1.6'
dc vgsn 0 1.5 0.05 temp -40 160 40
plot vssn#branch ylabel 'Id vs. Vds, Temp. -40 ... 160'
plot abs(vssn#branch) ylog ylabel 'Id vs. Vds, Temp. -40 ... 160'
* PMOS
dc vgsp 0 -1.5 -0.05 vbsp 0 1.5 0.3
plot vssp#branch ylabel 'Id vs. Vgs, Vbs 0 ... 1.5'
plot abs(vssp#branch) ylog ylabel 'Id vs. Vgs, Vbs 0 ... 1.5'
dc vdsp 0 -1.6 -0.01 vgsp 0 -1.6 -0.2
plot vssp#branch ylabel 'Id vs. Vds, Vgs 0 ... -1.6'
dc vgsp 0 -1.5 -0.05 temp -40 160 40
plot vssp#branch ylabel 'Id vs. Vds, Temp. -40 ... 160'
plot abs(vssp#branch) ylog ylabel 'Id vs. Vds, Temp. -40 ... 160'
.endc
.end

View File

@ -0,0 +1,66 @@
* PSP models
* simple inverter
.param Vcc = 1.2
.csparam vcc='Vcc'
* Path to the models
.include Modelcards/psp103_nmos-2.mod
.include Modelcards/psp103_pmos-2.mod
* the voltage sources:
Vdd vdd gnd DC 'Vcc'
V1 in gnd pulse(0 'Vcc' 0p 200p 100p 1n 2n)
Vmeas vss 0 0
Xnot1 in vdd vss out not1
*Rout out 0 1k
.subckt not1 a vdd vss z
*m01 z a vdd vdd pch l=0.1u w=1u as=0.26235 ad=0.26235 ps=2.51 pd=2.51
nmp1 z a vdd vdd pch
+l=0.1u
+w=1u
+sa=0.0e+00
+sb=0.0e+00
+absource=1.0e-12
+lssource=1.0e-06
+lgsource=1.0e-06
+abdrain=1.0e-12
+lsdrain=1.0e-06
+lgdrain=1.0e-06
+mult=1.0e+00
*m02 z a vss vss nch l=0.1u w=0.5u as=0.131175 ad=0.131175 ps=1.52 pd=1.52
nmn1 z a vss vss nch
+l=0.1u
+w=1u
+sa=0.0e+00
+sb=0.0e+00
+absource=1.0e-12
+lssource=1.0e-06
+lgsource=1.0e-06
+abdrain=1.0e-12
+lsdrain=1.0e-06
+lgdrain=1.0e-06
+mult=1.0e+00
c3 a vss 0.384f
c2 z vss 0.576f
.ends
* simulation command:
.tran 10ps 10ns
.dc V1 0 'vcc' 'vcc/100'
.control
pre_osdi test_osdi_win/psp103.osdi
run
*set nolegend
set xbrushwidth=2
plot in out
plot dc1.out
plot dc1.i(Vmeas)
rusage
.endc
.end

View File

@ -0,0 +1,33 @@
psp103 nch output
*
vd d 0 dc 0.05
vg g 0 dc 0.0
vs s 0 dc 0.0
vb b 0 dc 0.0
nm1 d g s b nch
+l=0.1u
+w=1u
+sa=0.0e+00
+sb=0.0e+00
+absource=1.0e-12
+lssource=1.0e-06
+lgsource=1.0e-06
+abdrain=1.0e-12
+lsdrain=1.0e-06
+lgdrain=1.0e-06
+mult=1.0e+00
*
.option temp=21
.include Modelcards/psp103_nmos-2.mod
*.include Modelcards/psp103_nmos.mod
.control
pre_osdi test_osdi_win/psp103.osdi
dc vd 0 2.0 0.05 vg 0 1.5 0.25
plot i(vs)
dc vg 0 1.5 0.05 vb 0 -3.0 -1
plot i(vs)
.endc
.end

View File

@ -0,0 +1,33 @@
psp103 pch output
*
vd d 0 dc -0.1
vg g 0 dc 0.0
vs s 0 dc 0.0
vb b 0 dc 0.0
nm1 d g s b pch
+l=0.1u
+w=1u
+sa=0.0e+00
+sb=0.0e+00
+absource=1.0e-12
+lssource=1.0e-06
+lgsource=1.0e-06
+abdrain=1.0e-12
+lsdrain=1.0e-06
+lgdrain=1.0e-06
+mult=1.0e+00
*
.option temp=21
.control
pre_osdi test_osdi_win/psp103.osdi
dc vd 0 -2.0 -0.05 vg 0 -1.5 -0.25 ; saturation
plot i(vs)
dc vg 0 -1.5 -0.05 vb 0 3.0 1
plot i(vs)
.endc
*
.include Modelcards/psp103_pmos-2.mod
.end

View File

@ -0,0 +1,66 @@
* PSP models
* simple 5-stage ring oscillator
.param Vcc = 1.2
.csparam vcc='Vcc'
* Path to the models
.include Modelcards/psp103_nmos-2.mod
.include Modelcards/psp103_pmos-2.mod
* the voltage sources:
Vdd vdd gnd DC 'Vcc'
V1 in gnd pulse(0 'Vcc' 0p 200p 100p 1n 2n)
Vmeas vss 0 0
Xnot1 in vdd vss in2 not1
Xnot2 in2 vdd vss in3 not1
Xnot3 in3 vdd vss in4 not1
Xnot4 in4 vdd vss in5 not1
Xnot5 in5 vdd vss in not1
*Rout out 0 1k
.subckt not1 a vdd vss z
*m01 z a vdd vdd pch l=0.1u w=1u as=0.26235 ad=0.26235 ps=2.51 pd=2.51
nmp1 z a vdd vdd pch
+l=0.1u
+w=1u
+sa=0.0e+00
+sb=0.0e+00
+absource=1.0e-12
+lssource=1.0e-06
+lgsource=1.0e-06
+abdrain=1.0e-12
+lsdrain=1.0e-06
+lgdrain=1.0e-06
+mult=1.0e+00
*m02 z a vss vss nch l=0.1u w=0.5u as=0.131175 ad=0.131175 ps=1.52 pd=1.52
nmn1 z a vss vss nch
+l=0.1u
+w=1u
+sa=0.0e+00
+sb=0.0e+00
+absource=1.0e-12
+lssource=1.0e-06
+lgsource=1.0e-06
+abdrain=1.0e-12
+lsdrain=1.0e-06
+lgdrain=1.0e-06
+mult=1.0e+00
c3 a vss 0.384f
c2 z vss 0.576f
.ends
* simulation command:
.tran 10p 10n uic
.control
pre_osdi test_osdi_win/psp103.osdi
run
set xbrushwidth=3
plot in
rusage
.endc
.end

View File

@ -0,0 +1,32 @@
psp103 nch transfer
*
vd d 0 dc 0.1
vg g 0 dc 0.0
vs s 0 dc 0.0
vb b 0 dc 0.0
nm1 d g s b nch
+l=1.0e-06
+w=10.0e-06
+sa=0.0e+00
+sb=0.0e+00
+absource=1.0e-12
+lssource=1.0e-06
+lgsource=1.0e-06
+abdrain=1.0e-12
+lsdrain=1.0e-06
+lgdrain=1.0e-06
+mult=1.0e+00
*
.option temp=21
.control
pre_osdi test_osdi_win/psp103.osdi
set xbrushwidth=2
dc vg 0 1.5 0.02 vb -3 0 0.5
plot abs(i(vd))
dc vg -0.3 1.5 0.01 vb -3 0 0.5
plot abs(i(vd)) ylog ylimit 1e-12 1e-03
.endc
*
.include Modelcards/psp103_nmos-2.mod
.end

View File

@ -0,0 +1 @@
Place psp103.osdi and juncap200.osdi here.

View File

@ -0,0 +1,16 @@
r2_cmc
v1 1 0 10
NRr2_cmc 1 0 rmodel w=1u l=20u isnoisy=1
* Poly resistor, r2_cmc model
.model rmodel r2_cmc(level=2 rsh=200 xl=0.2u xw=-0.05u p3=0.12 q3=1.6 p2=0.015 q2=3.8 tc1=1.5e-4 tc2=7e-7)
.control
pre_osdi test_osdi_win/r2_cmc.osdi
op
let res = v(1) / -v1#branch
print res
.endc
.end

View File

@ -0,0 +1 @@
Place r2_cmc.osdi here.

View File

@ -1,46 +1,48 @@
*****Single NMOS and PMOS Transistor For BSIM3 threshold voltage check (Id-Vgs) (Id-Vds) ***
*** Single NMOS and PMOS Transistor BSIM3 (Id-Vgs, Vbs) (Id-Vds, Vgs) (Id-Vgs, T) ***
M1 2 1 3 4 n1 W=1u L=0.35u Pd=1.5u Ps=1.5u ad=1.5p as=1.5p
vgs 1 0 3.5
vds 2 0 0.1
vss 3 0 0
vbs 4 0 0
vgsn 1 0 3.5
vdsn 2 0 0.1
vssn 3 0 0
vbsn 4 0 0
M2 22 11 33 44 p1 W=2.5u L=0.35u Pd=3u Ps=3u ad=2.5p as=2.5p
vgsp 11 0 -3.5
vdsp 22 0 -0.1
vgsp 11 0 -3.5
vdsp 22 0 -0.1
vssp 33 0 0
vbsp 44 0 0
.options Temp=27.0
* BSIM3v3.3.0 model with modified default parameters 0.18µm
.model n1 nmos level=49 version=3.3.0 tox=3.5n nch=2.4e17 nsub=5e16 vth0=0.15
.model p1 pmos level=49 version=3.3.0 tox=3.5n nch=2.5e17 nsub=5e16 vth0=-0.15
*.include ./Modelcards/modelcard.nmos ; Berkeley model cards limited to L >= 0.35µm
*.include ./Modelcards/modelcard.pmos ; Berkeley model cards limited to L >= 0.35µm
* update of the default parameters required
*.model n1 NMOS level=49 version=3.3.0 ; nearly no current due to VT > 2 V ?
*.model p1 PMOS level=49 version=3.3.0
* BSIM3v3.3.0 model with parameters provided by Berkeley
*.include modelcard.nmos
*.include modelcard.pmos
.control
set xgridwidth=2
set xbrushwidth=3
dc vgs 0 1.5 0.05 vbs 0 -2.5 -0.5
plot vss#branch
dc vds 0 2 0.05 vgs 0 2 0.4
plot vss#branch
* NMOS
dc vgsn 0 1.5 0.05 vbsn 0 -2.5 -0.5
plot vssn#branch ylabel 'Id vs. Vgs, Vbs 0 ... -2.5'
plot abs(vssn#branch) ylog ylabel 'Id vs. Vgs, Vbs 0 ... -2.5'
dc vdsn 0 2 0.05 vgsn 0 2 0.4
plot vssn#branch ylabel 'Id vs. Vds, Vgs 0 ... 2'
dc vgsn 0 1.5 0.05 temp -40 160 40
plot vssn#branch ylabel 'Id vs. Vds, Temp. -40 ... 160'
plot abs(vssn#branch) ylog ylabel 'Id vs. Vds, Temp. -40 ... 160'
* PMOS
dc vgsp 0 -1.5 -0.05 vbsp 0 2.5 0.5
plot vssp#branch
plot vssp#branch ylabel 'Id vs. Vgs, Vbs 0 ... 2.5'
plot abs(vssp#branch) ylog ylabel 'Id vs. Vgs, Vbs 0 ... 2.5'
dc vdsp 0 -2 -0.05 vgsp 0 -2 -0.4
plot vssp#branch
plot vssp#branch ylabel 'Id vs. Vds, Vgs 0 ... -2'
dc vgsp 0 -1.5 -0.05 temp -40 160 40
plot vssp#branch ylabel 'Id vs. Vds, Temp. -40 ... 160'
plot abs(vssp#branch) ylog ylabel 'Id vs. Vds, Temp. -40 ... 160'
.endc
.end

View File

@ -7,6 +7,10 @@ if XSPICE_WANTED
SUBDIRS += xspice
endif
if OSDI_WANTED
SUBDIRS += osdi
endif
if CIDER_WANTED
SUBDIRS += ciderlib
endif
@ -97,6 +101,8 @@ DYNAMIC_DEVICELIBS = \
@VLADEV@
## Build ngspice first:
## compile the icon:
@ -116,6 +122,8 @@ ngspice_CPPFLAGS = $(AM_CPPFLAGS) -DSIMULATOR
if WINGUI
ngspice_LDFLAGS = -municode $(AM_LDFLAGS)
ngspice_SOURCES += winmain.c hist_info.c
else
ngspice_LDFLAGS =
endif
ngspice_LDADD = \
@ -157,9 +165,9 @@ ngspice_LDADD += \
xspice/evt/libevtxsp.la \
xspice/enh/libenhxsp.la \
xspice/ipc/libipcxsp.la \
xspice/idn/libidnxsp.la \
@XSPICEDLLIBS@
xspice/idn/libidnxsp.la
endif
ngspice_LDADD += @XSPICEDLLIBS@
ngspice_LDADD += \
frontend/parser/libparser.la \
@ -175,6 +183,10 @@ ngspice_LDADD += \
ciderlib/support/libcidersuprt.la
endif
if OSDI_WANTED
ngspice_LDADD += osdi/libosdi.la
endif
ngspice_LDADD += \
maths/deriv/libderiv.la \
maths/cmaths/libcmaths.la \
@ -439,9 +451,9 @@ libspice_la_LIBADD += \
xspice/evt/libevtxsp.la \
xspice/enh/libenhxsp.la \
xspice/ipc/libipcxsp.la \
xspice/idn/libidnxsp.la \
@XSPICEDLLIBS@
xspice/idn/libidnxsp.la
endif
libspice_la_LIBADD += @XSPICEDLLIBS@
libspice_la_LIBADD += \
frontend/parser/libparser.la \
@ -457,6 +469,11 @@ libspice_la_LIBADD += \
ciderlib/support/libcidersuprt.la
endif
if OSDI_WANTED
libspice_la_LIBADD += osdi/libosdi.la
endif
libspice_la_LIBADD += \
maths/deriv/libderiv.la \
maths/cmaths/libcmaths.la \
@ -558,9 +575,9 @@ libngspice_la_LIBADD += \
xspice/evt/libevtxsp.la \
xspice/enh/libenhxsp.la \
xspice/ipc/libipcxsp.la \
xspice/idn/libidnxsp.la \
@XSPICEDLLIBS@
xspice/idn/libidnxsp.la
endif
libngspice_la_LIBADD += @XSPICEDLLIBS@
libngspice_la_LIBADD += \
frontend/parser/libparser.la \
@ -576,6 +593,9 @@ libngspice_la_LIBADD += \
ciderlib/support/libcidersuprt.la
endif
libngspice_la_LIBADD += osdi/libosdi.la
libngspice_la_LIBADD += \
maths/deriv/libderiv.la \
maths/cmaths/libcmaths.la \

View File

@ -18,6 +18,21 @@ void com_codemodel(wordlist *wl)
}
#endif
#ifdef OSDI
void com_osdi(wordlist *wl)
{
wordlist *ww;
for (ww = wl; ww; ww = ww->wl_next)
if (load_osdi(ww->wl_word)) {
fprintf(cp_err, "Error: Library %s couldn't be loaded!\n", ww->wl_word);
if (ft_stricterror)
controlled_exit(EXIT_BAD);
}
}
#endif
#ifdef DEVLIB
void com_use(wordlist *wl)

View File

@ -5,6 +5,10 @@
void com_codemodel(wordlist *wl);
#endif
#ifdef OSDI
void com_osdi(wordlist *wl);
#endif
#ifdef DEVLIB
void com_use(wordlist *wl);
#endif

View File

@ -268,6 +268,12 @@ struct comm spcp_coms[] = {
NULL,
"library library ... : Loads the code model libraries." } ,
#endif
#ifdef OSDI
{ "osdi", com_osdi, FALSE, TRUE,
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
NULL,
"library library ... : Loads a osdi library." } ,
#endif
#ifdef DEVLIB
{ "use", com_use, FALSE, TRUE,
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,

View File

@ -18,6 +18,7 @@ Author: 1985 Wayne A. Christopher
#include "ngspice/fteinp.h"
#include "inp.h"
#include "ngspice/osdiitf.h"
#include "runcoms.h"
#include "inpcom.h"
#include "circuits.h"
@ -565,7 +566,6 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
if (fp) {
cp_vset("inputdir", CP_STRING, dir_name);
}
tfree(dir_name);
/* if nothing came back from inp_readall, e.g. after calling ngspice without parameters,
just close fp and return to caller */
@ -740,8 +740,16 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
before the circuit structure is set up */
if (pre_controls) {
pre_controls = wl_reverse(pre_controls);
for (wl = pre_controls; wl; wl = wl->wl_next)
for (wl = pre_controls; wl; wl = wl->wl_next){
#ifdef OSDI
inputdir = dir_name;
#endif
cp_evloop(wl->wl_word);
}
#ifdef OSDI
inputdir = NULL;
#endif
wl_free(pre_controls);
}
@ -1108,18 +1116,29 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
of commands. Thus this is delegated to a function using a third thread, that
only starts when the background thread has finished (sharedspice.c).*/
#ifdef SHARED_MODULE
for (wl = controls; wl; wl = wl->wl_next)
for (wl = controls; wl; wl = wl->wl_next){
#ifdef OSDI
inputdir = dir_name;
#endif
if (cp_getvar("controlswait", CP_BOOL, NULL, 0)) {
exec_controls(wl_copy(wl));
break;
}
else
cp_evloop(wl->wl_word);
}
#else
for (wl = controls; wl; wl = wl->wl_next)
for (wl = controls; wl; wl = wl->wl_next){
#ifdef OSDI
inputdir = dir_name;
#endif
cp_evloop(wl->wl_word);
}
#endif
wl_free(controls);
#ifdef OSDI
inputdir = NULL;
#endif
}
/* Now reset everything. Pop the control stack, and fix up the IO
@ -1131,6 +1150,9 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
cp_curerr = lasterr;
tfree(tt);
tfree(dir_name);
return 0;
}

View File

@ -11,6 +11,7 @@ Author: 1985 Wayne A. Christopher
/* Note: Must include shlwapi.h before ngspice header defining BOOL due
* to conflict */
#include <stdio.h>
#ifdef _WIN32
#include <shlwapi.h> /* for definition of PathIsRelativeA() */
#pragma comment(lib, "Shlwapi.lib")
@ -1563,6 +1564,8 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name,
!ciprefix("wrdata", buffer) &&
!ciprefix(".lib", buffer) && !ciprefix(".inc", buffer) &&
!ciprefix("codemodel", buffer) &&
!ciprefix("osdi", buffer) &&
!ciprefix("pre_osdi", buffer) &&
!ciprefix("echo", buffer) && !ciprefix("shell", buffer) &&
!ciprefix("source", buffer) && !ciprefix("cd ", buffer) &&
!ciprefix("load", buffer) && !ciprefix("setcs", buffer)) {
@ -2052,16 +2055,6 @@ static void inp_chk_for_multi_in_vcvs(struct card *c, int *line_number)
(fcn_b = strstr(line, "nor(")) != NULL ||
(fcn_b = strstr(line, "or(")) != NULL) &&
isspace_c(fcn_b[-1])) {
char keep, *comma_ptr, *xy_values1[5], *xy_values2[5];
char *out_str, *ctrl_nodes_str,
*xy_values1_b = NULL, *ref_str, *fcn_name,
*fcn_e = NULL, *out_b, *out_e, *ref_e;
char *m_instance, *m_model;
char *xy_values2_b = NULL, *xy_values1_e = NULL,
*ctrl_nodes_b = NULL, *ctrl_nodes_e = NULL;
int xy_count1, xy_count2;
bool ok = FALSE;
#ifndef XSPICE
fprintf(stderr,
"\n"
@ -2073,7 +2066,16 @@ static void inp_chk_for_multi_in_vcvs(struct card *c, int *line_number)
"instructions\n",
*line_number, line);
controlled_exit(EXIT_BAD);
#endif
#else
char keep, *comma_ptr, *xy_values1[5], *xy_values2[5];
char *out_str, *ctrl_nodes_str,
*xy_values1_b = NULL, *ref_str, *fcn_name,
*fcn_e = NULL, *out_b, *out_e, *ref_e;
char *m_instance, *m_model;
char *xy_values2_b = NULL, *xy_values1_e = NULL,
*ctrl_nodes_b = NULL, *ctrl_nodes_e = NULL;
int xy_count1, xy_count2;
bool ok = FALSE;
do {
ref_e = skip_non_ws(line);
@ -2174,6 +2176,7 @@ static void inp_chk_for_multi_in_vcvs(struct card *c, int *line_number)
*c->line = '*';
c = insert_new_line(c, m_instance, (*line_number)++, c->linenum_orig);
c = insert_new_line(c, m_model, (*line_number)++, c->linenum_orig);
#endif
}
}
}
@ -2352,6 +2355,8 @@ static char *get_subckt_model_name(char *line)
name = skip_non_ws(line); // eat .subckt|.model
name = skip_ws(name);
end_ptr = skip_non_ws(name);
return copy_substring(name, end_ptr);
@ -4705,6 +4710,28 @@ int get_number_terminals(char *c)
}
break;
}
#ifdef OSDI
case 'n': /* Recognize an unknown number of nodes by stopping at tokens with '=' */
{
i = 0;
char* cc, * ccfree;
cc = copy(c);
/* required to make m= 1 a single token m=1 */
ccfree = cc = inp_remove_ws(cc);
/* find the first token with "off", "tnodeout", "thermal" or "=" in the line*/
while ((i < 20) && (*cc != '\0')) {
char* inst = gettok_instance(&cc);
strncpy(nam_buf, inst, sizeof(nam_buf) - 1);
txfree(inst);
if (i > 2 && (strchr(nam_buf, '=')))
break;
i++;
}
tfree(ccfree);
return i - 2;
break;
}
#endif
default:
return 0;
break;
@ -9978,7 +10005,8 @@ static char inp_get_elem_ident(char *type)
return 'm';
if (cieq(type, "res"))
return 'r';
/* xspice code models do not have unique type names */
/* xspice code models do not have unique type names,
but could also be an OSDI/OpenVAF model. */
else
return 'a';
}
@ -10258,7 +10286,7 @@ void inp_rem_unused_models(struct nscope *root, struct card *deck)
struct modellist *m =
inp_find_model(card->level, elem_model_name);
if (m) {
if (*curr_line != m->elemb)
if (*curr_line != m->elemb && !(*curr_line == 'n' && m->elemb == 'a'))
fprintf(stderr,
"warning, model type mismatch in line\n "
"%s\n",
@ -10288,7 +10316,7 @@ void inp_rem_unused_models(struct nscope *root, struct card *deck)
* only correct UTF-8. It also spots UTF-8 sequences that could cause
* trouble if converted to UTF-16, namely surrogate characters
* (U+D800..U+DFFF) and non-Unicode positions (U+FFFE..U+FFFF).
* In addition we check for some ngspice-specific characters like µ etc.*/
* In addition we check for some ngspice-specific characters like <EFBFBD> etc.*/
#ifndef EXT_ASC
static unsigned char*
utf8_check(unsigned char *s)
@ -10298,12 +10326,12 @@ utf8_check(unsigned char *s)
/* 0xxxxxxx */
s++;
else if (*s == 0xb5) {
/* translate ansi micro µ to u */
/* translate ansi micro <EFBFBD> to u */
*s = 'u';
s++;
}
else if (s[0] == 0xc2 && s[1] == 0xb5) {
/* translate utf-8 micro µ to u */
/* translate utf-8 micro <EFBFBD> to u */
s[0] = 'u';
/* remove second byte */
unsigned char *y = s + 1;

View File

@ -1241,6 +1241,7 @@ translate(struct card *deck, char *formal, char *actual, char *scname, const cha
case '$':
continue;
#ifdef XSPICE
/*=================== case A ====================*/
/* gtri - add - wbk - 10/23/90 - process A devices specially */
@ -1437,6 +1438,8 @@ translate(struct card *deck, char *formal, char *actual, char *scname, const cha
/* FIXME anothet hack: if no models found for m devices, set number of nodes to 4 */
if (!modnames && *(c->line) == 'm')
nnodes = get_number_terminals(c->line);
else if (*(c->line) == 'n')
nnodes = get_number_terminals(c->line);
else
nnodes = numnodes(c->line, subs, modnames);
while (--nnodes >= 0) {
@ -1687,7 +1690,6 @@ numnodes(const char *line, struct subs *subs, wordlist const *modnames)
/* Paolo Nenzi Jan-2001 */
/* If model names equal node names, this code will fail! */
if ((c == 'm') || (c == 'p') || (c == 'q') || (c == 'd')) { /* IF this is a mos, cpl, bjt or diode */
char *s = nexttok(line); /* Skip the instance name */
int gotit = 0;

View File

@ -7,7 +7,8 @@
#define ngspice_CKTDEFS_H
#include "ngspice/typedefs.h"
/* ensure config is always included to avoid missmatching type definitions*/
#include "ngspice/config.h"
/* gtri - evt - wbk - 5/20/91 - add event-driven and enhancements data */
#ifdef XSPICE

View File

@ -299,6 +299,10 @@ struct IFdevice {
#endif
int flags; /* DEV_ */
#ifdef OSDI
const void *registry_entry;
#endif
};

View File

@ -0,0 +1,32 @@
/*
* This file is part of the OSDI component of NGSPICE.
* Copyright© 2022 SemiMod GmbH.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Author: Pascal Kuthe <pascal.kuthe@semimod.de>
*/
#pragma once
#include "ngspice/devdefs.h"
#include <stdint.h>
typedef struct OsdiRegistryEntry {
const void *descriptor;
uint32_t inst_offset;
uint32_t dt;
uint32_t temp;
} OsdiRegistryEntry;
typedef struct OsdiObjectFile {
OsdiRegistryEntry *entrys;
int num_entries;
} OsdiObjectFile;
extern OsdiObjectFile load_object_file(const char *path);
extern SPICEdev *osdi_create_spicedev(const OsdiRegistryEntry *entry);
extern char *inputdir;

25
src/osdi/Makefile.am Normal file
View File

@ -0,0 +1,25 @@
## Process this file with automake to produce Makefile.in
noinst_LTLIBRARIES = libosdi.la
libosdi_la_SOURCES = \
osdi.h \
osdidefs.h \
osdiext.h \
osdiinit.c \
osdiload.c \
osdiacld.c \
osdiparam.c \
osdiregistry.c \
osdisetup.c \
osdiitf.h \
osditrunc.c \
osdipzld.c \
osdicallbacks.c
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
AM_CFLAGS = $(STATIC)
MAINTAINERCLEANFILES = Makefile.in

209
src/osdi/osdi.h Normal file
View File

@ -0,0 +1,209 @@
/*
* This file is part of the OSDI component of NGSPICE.
* Copyright© 2022 SemiMod GmbH.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* This file is automatically generated by header.lua to match
* the OSDI specfication. DO NOT EDIT MANUALLY
*
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#define OSDI_VERSION_MAJOR_CURR 0
#define OSDI_VERSION_MINOR_CURR 3
#define PARA_TY_MASK 3
#define PARA_TY_REAL 0
#define PARA_TY_INT 1
#define PARA_TY_STR 2
#define PARA_KIND_MASK (3 << 30)
#define PARA_KIND_MODEL (0 << 30)
#define PARA_KIND_INST (1 << 30)
#define PARA_KIND_OPVAR (2 << 30)
#define ACCESS_FLAG_READ 0
#define ACCESS_FLAG_SET 1
#define ACCESS_FLAG_INSTANCE 4
#define JACOBIAN_ENTRY_RESIST_CONST 1
#define JACOBIAN_ENTRY_REACT_CONST 2
#define JACOBIAN_ENTRY_RESIST 4
#define JACOBIAN_ENTRY_REACT 8
#define CALC_RESIST_RESIDUAL 1
#define CALC_REACT_RESIDUAL 2
#define CALC_RESIST_JACOBIAN 4
#define CALC_REACT_JACOBIAN 8
#define CALC_NOISE 16
#define CALC_OP 32
#define CALC_RESIST_LIM_RHS 64
#define CALC_REACT_LIM_RHS 128
#define ENABLE_LIM 256
#define INIT_LIM 512
#define ANALYSIS_NOISE 1024
#define ANALYSIS_DC 2048
#define ANALYSIS_AC 4096
#define ANALYSIS_TRAN 8192
#define ANALYSIS_IC 16384
#define ANALYSIS_STATIC 32768
#define ANALYSIS_NODESET 65536
#define EVAL_RET_FLAG_LIM 1
#define EVAL_RET_FLAG_FATAL 2
#define EVAL_RET_FLAG_FINISH 4
#define EVAL_RET_FLAG_STOP 8
#define LOG_LVL_MASK 8
#define LOG_LVL_DEBUG 0
#define LOG_LVL_DISPLAY 1
#define LOG_LVL_INFO 2
#define LOG_LVL_WARN 3
#define LOG_LVL_ERR 4
#define LOG_LVL_FATAL 5
#define LOG_FMT_ERR 16
#define INIT_ERR_OUT_OF_BOUNDS 1
typedef struct OsdiLimFunction {
char *name;
uint32_t num_args;
void *func_ptr;
}OsdiLimFunction;
typedef struct OsdiSimParas {
char **names;
double *vals;
char **names_str;
char **vals_str;
}OsdiSimParas;
typedef struct OsdiSimInfo {
OsdiSimParas paras;
double abstime;
double *prev_solve;
double *prev_state;
double *next_state;
uint32_t flags;
}OsdiSimInfo;
typedef union OsdiInitErrorPayload {
uint32_t parameter_id;
}OsdiInitErrorPayload;
typedef struct OsdiInitError {
uint32_t code;
OsdiInitErrorPayload payload;
}OsdiInitError;
typedef struct OsdiInitInfo {
uint32_t flags;
uint32_t num_errors;
OsdiInitError *errors;
}OsdiInitInfo;
typedef struct OsdiNodePair {
uint32_t node_1;
uint32_t node_2;
}OsdiNodePair;
typedef struct OsdiJacobianEntry {
OsdiNodePair nodes;
uint32_t react_ptr_off;
uint32_t flags;
}OsdiJacobianEntry;
typedef struct OsdiNode {
char *name;
char *units;
char *residual_units;
uint32_t resist_residual_off;
uint32_t react_residual_off;
uint32_t resist_limit_rhs_off;
uint32_t react_limit_rhs_off;
bool is_flow;
}OsdiNode;
typedef struct OsdiParamOpvar {
char **name;
uint32_t num_alias;
char *description;
char *units;
uint32_t flags;
uint32_t len;
}OsdiParamOpvar;
typedef struct OsdiNoiseSource {
char *name;
OsdiNodePair nodes;
}OsdiNoiseSource;
typedef struct OsdiDescriptor {
char *name;
uint32_t num_nodes;
uint32_t num_terminals;
OsdiNode *nodes;
uint32_t num_jacobian_entries;
OsdiJacobianEntry *jacobian_entries;
uint32_t num_collapsible;
OsdiNodePair *collapsible;
uint32_t collapsed_offset;
OsdiNoiseSource *noise_sources;
uint32_t num_noise_src;
uint32_t num_params;
uint32_t num_instance_params;
uint32_t num_opvars;
OsdiParamOpvar *param_opvar;
uint32_t node_mapping_offset;
uint32_t jacobian_ptr_resist_offset;
uint32_t num_states;
uint32_t state_idx_off;
uint32_t bound_step_offset;
uint32_t instance_size;
uint32_t model_size;
void *(*access)(void *inst, void *model, uint32_t id, uint32_t flags);
void (*setup_model)(void *handle, void *model, OsdiSimParas *sim_params,
OsdiInitInfo *res);
void (*setup_instance)(void *handle, void *inst, void *model,
double temperature, uint32_t num_terminals,
OsdiSimParas *sim_params, OsdiInitInfo *res);
uint32_t (*eval)(void *handle, void *inst, void *model, const OsdiSimInfo *info);
void (*load_noise)(void *inst, void *model, double freq, double *noise_dens,
double *ln_noise_dens);
void (*load_residual_resist)(void *inst, void* model, double *dst);
void (*load_residual_react)(void *inst, void* model, double *dst);
void (*load_limit_rhs_resist)(void *inst, void* model, double *dst);
void (*load_limit_rhs_react)(void *inst, void* model, double *dst);
void (*load_spice_rhs_dc)(void *inst, void* model, double *dst,
double* prev_solve);
void (*load_spice_rhs_tran)(void *inst, void* model, double *dst,
double* prev_solve, double alpha);
void (*load_jacobian_resist)(void *inst, void* model);
void (*load_jacobian_react)(void *inst, void* model, double alpha);
void (*load_jacobian_tran)(void *inst, void* model, double alpha);
}OsdiDescriptor;

44
src/osdi/osdiacld.c Normal file
View File

@ -0,0 +1,44 @@
/*
* This file is part of the OSDI component of NGSPICE.
* Copyright© 2022 SemiMod GmbH.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Author: Pascal Kuthe <pascal.kuthe@semimod.de>
*/
#include "ngspice/iferrmsg.h"
#include "ngspice/memory.h"
#include "ngspice/ngspice.h"
#include "ngspice/typedefs.h"
#include "osdi.h"
#include "osdidefs.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int OSDIacLoad(GENmodel *inModel, CKTcircuit *ckt) {
GENmodel *gen_model;
GENinstance *gen_inst;
OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel);
const OsdiDescriptor *descr = entry->descriptor;
for (gen_model = inModel; gen_model; gen_model = gen_model->GENnextModel) {
void *model = osdi_model_data(gen_model);
for (gen_inst = gen_model->GENinstances; gen_inst;
gen_inst = gen_inst->GENnextInstance) {
void *inst = osdi_instance_data(entry, gen_inst);
// nothing to calculate just load the matrix entries calculated during
// operating point iterations
descr->load_jacobian_resist(inst, model);
descr->load_jacobian_react(inst, model, ckt->CKTomega);
}
}
return (OK);
}

88
src/osdi/osdicallbacks.c Normal file
View File

@ -0,0 +1,88 @@
#include "ngspice/devdefs.h"
#include "osdidefs.h"
void osdi_log(void *handle_, char *msg, uint32_t lvl) {
OsdiNgspiceHandle *handle = handle_;
FILE *dst = stdout;
switch (lvl & LOG_LVL_MASK) {
case LOG_LVL_DEBUG:
printf("OSDI(debug) %s: ", handle->name);
break;
case LOG_LVL_DISPLAY:
printf("OSDI %s: ", handle->name);
break;
case LOG_LVL_INFO:
printf("OSDI(info) %s: ", handle->name);
break;
case LOG_LVL_WARN:
fprintf(stderr, "OSDI(warn) %s: ", handle->name);
dst = stderr;
break;
case LOG_LVL_ERR:
fprintf(stderr, "OSDI(err) %s: ", handle->name);
dst = stderr;
break;
case LOG_LVL_FATAL:
fprintf(stderr, "OSDI(fatal) %s: ", handle->name);
dst = stderr;
break;
default:
fprintf(stderr, "OSDI(unkown) %s", handle->name);
break;
}
if (lvl & LOG_FMT_ERR) {
fprintf(dst, "failed to format\"%s\"\n", msg);
} else {
fprintf(dst, "%s", msg);
}
}
double osdi_pnjlim(bool init, bool *check, double vnew, double vold, double vt,
double vcrit) {
if (init) {
*check = true;
return vcrit;
}
int icheck = 0;
double res = DEVpnjlim(vnew, vold, vt, vcrit, &icheck);
*check = icheck != 0;
return res;
}
double osdi_limvds(bool init, bool *check, double vnew, double vold) {
if (init) {
*check = true;
return 0.1;
}
double res = DEVlimvds(vnew, vold);
if (res != vnew) {
*check = true;
}
return res;
}
double osdi_fetlim(bool init, bool *check, double vnew, double vold,
double vto) {
if (init) {
*check = true;
return vto + 0.1;
}
double res = DEVfetlim(vnew, vold, vto);
if (res != vnew) {
*check = true;
}
return res;
}
double osdi_limitlog(bool init, bool *check, double vnew, double vold,
double LIM_TOL) {
if (init) {
*check = true;
return 0.0;
}
int icheck = 0;
double res = DEVlimitlog(vnew, vold, LIM_TOL, &icheck);
*check = icheck != 0;
return res;
}

101
src/osdi/osdidefs.h Normal file
View File

@ -0,0 +1,101 @@
/*
* This file is part of the OSDI component of NGSPICE.
* Copyright© 2022 SemiMod GmbH.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Author: Pascal Kuthe <pascal.kuthe@semimod.de>
*/
#pragma once
#include "ngspice/cktdefs.h"
#include "ngspice/complex.h"
#include "ngspice/fteext.h"
#include "ngspice/gendefs.h"
#include "ngspice/ifsim.h"
#include "ngspice/ngspice.h"
#include "ngspice/noisedef.h"
#include "ngspice/typedefs.h"
#include "osdi.h"
#include "osdiext.h"
#include <stddef.h>
#include <stdint.h>
#ifdef _MSC_VER
typedef struct {
long long __max_align_ll ;
long double __max_align_ld;
/* _Float128 is defined as a basic type, so max_align_t must be
sufficiently aligned for it. This code must work in C++, so we
use __float128 here; that is only available on some
architectures, but only on i386 is extra alignment needed for
__float128. */
#ifdef __i386__
__float128 __max_align_f128 __attribute__((__aligned__(__alignof(__float128))));
#endif
} max_align_t;
#endif
#ifdef _MSC_VER
#define MAX_ALIGN 8
#else
#define MAX_ALIGN sizeof(max_align_t)
#endif
#ifndef _MSC_VER
#define ALIGN(pow) __attribute__((aligned(pow)))
#else
#define ALIGN(pow) __declspec(align(pow))
#endif
typedef struct OsdiExtraInstData {
double dt;
double temp;
bool temp_given;
bool dt_given;
uint32_t eval_flags;
} ALIGN(MAX_ALIGN) OsdiExtraInstData;
typedef struct OsdiModelData {
GENmodel gen;
max_align_t data;
} OsdiModelData;
extern size_t osdi_instance_data_off(const OsdiRegistryEntry *entry);
extern void *osdi_instance_data(const OsdiRegistryEntry *entry, GENinstance *inst);
extern OsdiExtraInstData *osdi_extra_instance_data(const OsdiRegistryEntry *entry,
GENinstance *inst);
extern size_t osdi_model_data_off(void);
extern void *osdi_model_data(GENmodel *model);
extern void *osdi_model_data_from_inst(GENinstance *inst);
extern OsdiRegistryEntry *osdi_reg_entry_model(const GENmodel *model);
extern OsdiRegistryEntry *osdi_reg_entry_inst(const GENinstance *inst);
typedef struct OsdiNgspiceHandle {
uint32_t kind;
char *name;
} OsdiNgspiceHandle;
/* values returned by $simparam*/
OsdiSimParas get_simparams(const CKTcircuit *ckt);
typedef void (*osdi_log_ptr)(void *handle, char *msg, uint32_t lvl);
void osdi_log(void *handle_, char *msg, uint32_t lvl);
typedef void (*osdi_log_ptr)(void *handle, char *msg, uint32_t lvl);
double osdi_pnjlim(bool init, bool *icheck, double vnew, double vold, double vt,
double vcrit);
double osdi_limvds(bool init, bool *icheck, double vnew, double vold);
double osdi_limitlog(bool init, bool *icheck, double vnew, double vold,
double LIM_TOL);
double osdi_fetlim(bool init, bool *icheck, double vnew, double vold,
double vto);

36
src/osdi/osdiext.h Normal file
View File

@ -0,0 +1,36 @@
/*
* This file is part of the OSDI component of NGSPICE.
* Copyright© 2022 SemiMod GmbH.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Author: Pascal Kuthe <pascal.kuthe@semimod.de>
*/
#pragma once
#include "ngspice/gendefs.h"
#include "ngspice/smpdefs.h"
#include <stdint.h>
#include "ngspice/osdiitf.h"
extern int OSDImParam(int, IFvalue *, GENmodel *);
extern int OSDIparam(int, IFvalue *, GENinstance *, IFvalue *);
extern int OSDIsetup(SMPmatrix *, GENmodel *, CKTcircuit *, int *);
extern int OSDIunsetup(GENmodel *, CKTcircuit *);
extern int OSDIask(CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *);
extern int OSDIload(GENmodel *, CKTcircuit *);
extern int OSDItemp(GENmodel *, CKTcircuit *);
extern int OSDIacLoad(GENmodel *, CKTcircuit *);
extern int OSDItrunc(GENmodel *, CKTcircuit *, double *);
extern int OSDIpzLoad(GENmodel*, CKTcircuit*, SPcomplex*);
/* extern int OSDIconvTest(GENmodel*,CKTcircuit*); */
/* extern int OSDImDelete(GENmodel*); */
/* extern int OSDIgetic(GENmodel*,CKTcircuit*); */
/* extern int OSDImAsk(CKTcircuit*,GENmodel*,int,IFvalue*); */
/* extern int OSDInoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); */
/* extern int OSDIsoaCheck(CKTcircuit *, GENmodel *); */

187
src/osdi/osdiinit.c Normal file
View File

@ -0,0 +1,187 @@
/*
* This file is part of the OSDI component of NGSPICE.
* Copyright© 2022 SemiMod GmbH.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Author: Pascal Kuthe <pascal.kuthe@semimod.de>
*/
#include "ngspice/stringutil.h"
#include "ngspice/config.h"
#include "ngspice/devdefs.h"
#include "ngspice/iferrmsg.h"
#include "ngspice/memory.h"
#include "ngspice/ngspice.h"
#include "ngspice/typedefs.h"
#include "osdi.h"
#include "osdidefs.h"
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
/*
* This function converts the information in (a list of) OsdiParamOpvar in
* descr->param_opvar to the internal ngspice representation (IFparm).
*/
static int write_param_info(IFparm **dst, const OsdiDescriptor *descr,
uint32_t start, uint32_t end) {
for (uint32_t i = start; i < end; i++) {
OsdiParamOpvar *para = &descr->param_opvar[i];
uint32_t num_names = para->num_alias + 1;
int dataType = IF_ASK;
if ((para->flags & (uint32_t)PARA_KIND_OPVAR) == 0) {
dataType |= IF_SET;
}
switch (para->flags & PARA_TY_MASK) {
case PARA_TY_REAL:
dataType |= IF_REAL;
break;
case PARA_TY_INT:
dataType |= IF_INTEGER;
break;
case PARA_TY_STR:
dataType |= IF_STRING;
break;
default:
errRtn = "get_osdi_info";
errMsg = tprintf("Unkown OSDI type %d for parameter %s!",
para->flags & PARA_TY_MASK, para->name[0]);
return -1;
}
if (para->len != 0) {
dataType |= IF_VECTOR;
}
for (uint32_t j = 0; j < num_names; j++) {
if (j != 0) {
dataType = IF_UNINTERESTING;
}
char *para_name = copy(para->name[j]);
strtolower(para_name);
(*dst)[j] = (IFparm){.keyword = para_name,
.id = (int)i,
.description = para->description,
.dataType = dataType};
}
*dst += num_names;
}
return 0;
}
/**
* This function creates a SPICEdev instance for a specific OsdiDescriptor by
* populating the SPICEdev struct with descriptor specific metadata and pointers
* to the descriptor independent functions.
* */
extern SPICEdev *osdi_create_spicedev(const OsdiRegistryEntry *entry) {
const OsdiDescriptor *descr = entry->descriptor;
// allocate and fill terminal names array
char **termNames = TMALLOC(char *, descr->num_terminals);
for (uint32_t i = 0; i < descr->num_terminals; i++) {
termNames[i] = descr->nodes[i].name;
}
// allocate and fill instance params (and opvars)
int *num_instance_para_names = TMALLOC(int, 1);
for (uint32_t i = 0; i < descr->num_instance_params; i++) {
*num_instance_para_names += (int)(1 + descr->param_opvar[i].num_alias);
}
for (uint32_t i = descr->num_params;
i < descr->num_opvars + descr->num_params; i++) {
*num_instance_para_names += (int)(1 + descr->param_opvar[i].num_alias);
}
if (entry->dt != UINT32_MAX) {
*num_instance_para_names += 1;
}
if (entry->temp != UINT32_MAX) {
*num_instance_para_names += 1;
}
IFparm *instance_para_names = TMALLOC(IFparm, *num_instance_para_names);
IFparm *dst = instance_para_names;
if (entry->dt != UINT32_MAX) {
dst[0] = (IFparm){"dt", (int)entry->dt, IF_REAL | IF_SET,
"Instance delta temperature"};
dst += 1;
}
if (entry->temp != UINT32_MAX) {
dst[0] = (IFparm){"temp", (int)entry->temp, IF_REAL | IF_SET,
"Instance temperature"};
dst += 1;
}
write_param_info(&dst, descr, 0, descr->num_instance_params);
write_param_info(&dst, descr, descr->num_params,
descr->num_params + descr->num_opvars);
// allocate and fill model params
int *num_model_para_names = TMALLOC(int, 1);
for (uint32_t i = descr->num_instance_params; i < descr->num_params; i++) {
*num_model_para_names += (int)(1 + descr->param_opvar[i].num_alias);
}
IFparm *model_para_names = TMALLOC(IFparm, *num_model_para_names);
dst = model_para_names;
write_param_info(&dst, descr, descr->num_instance_params, descr->num_params);
// Allocate SPICE device
SPICEdev *OSDIinfo = TMALLOC(SPICEdev, 1);
// fill information
OSDIinfo->DEVpublic = (IFdevice){
.name = descr->name,
.description = "A simulator independent device loaded with OSDI",
// TODO why extra indirection? Optional ports?
.terms = (int *)&descr->num_terminals,
.numNames = (int *)&descr->num_terminals,
.termNames = termNames,
.numInstanceParms = num_instance_para_names,
.instanceParms = instance_para_names,
.numModelParms = num_model_para_names,
.modelParms = model_para_names,
.flags = DEV_DEFAULT,
.registry_entry = (void *)entry,
};
size_t inst_off = entry->inst_offset;
int *inst_size = TMALLOC(int, 1);
*inst_size =
(int)(inst_off + descr->instance_size + sizeof(OsdiExtraInstData));
OSDIinfo->DEVinstSize = inst_size;
size_t model_off = osdi_model_data_off();
int *model_size = TMALLOC(int, 1);
*model_size = (int)(model_off + descr->model_size);
OSDIinfo->DEVmodSize = model_size;
// fill generic functions
OSDIinfo->DEVparam = OSDIparam;
OSDIinfo->DEVmodParam = OSDImParam;
OSDIinfo->DEVask = OSDIask;
OSDIinfo->DEVsetup = OSDIsetup;
OSDIinfo->DEVpzSetup = OSDIsetup;
OSDIinfo->DEVtemperature = OSDItemp;
OSDIinfo->DEVunsetup = OSDIunsetup;
OSDIinfo->DEVload = OSDIload;
OSDIinfo->DEVacLoad = OSDIacLoad;
OSDIinfo->DEVpzLoad = OSDIpzLoad;
OSDIinfo->DEVtrunc = OSDItrunc;
return OSDIinfo;
}

261
src/osdi/osdiload.c Normal file
View File

@ -0,0 +1,261 @@
/*
* This file is part of the OSDI component of NGSPICE.
* Copyright© 2022 SemiMod GmbH.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Author: Pascal Kuthe <pascal.kuthe@semimod.de>
*/
#include "ngspice/iferrmsg.h"
#include "ngspice/memory.h"
#include "ngspice/ngspice.h"
#include "ngspice/typedefs.h"
#include "osdi.h"
#include "osdidefs.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#define NUM_SIM_PARAMS 5
char *sim_params[NUM_SIM_PARAMS + 1] = {
"gdev", "gmin", "tnom", "simulatorVersion", "sourceScaleFactor", NULL};
char *sim_params_str[1] = {NULL};
double sim_param_vals[NUM_SIM_PARAMS] = {0, 0, 0, 0, 0};
/* values returned by $simparam*/
OsdiSimParas get_simparams(const CKTcircuit *ckt) {
double simulatorVersion = strtod(PACKAGE_VERSION, NULL);
double gdev = ckt->CKTgmin;
double sourceScaleFactor = ckt->CKTsrcFact;
double gmin = ((ckt->CKTgmin) > (ckt->CKTdiagGmin)) ? (ckt->CKTgmin)
: (ckt->CKTdiagGmin);
double sim_param_vals_[NUM_SIM_PARAMS] = {
gdev, gmin, ckt->CKTnomTemp, simulatorVersion, sourceScaleFactor};
memcpy(&sim_param_vals, &sim_param_vals_, sizeof(double) * NUM_SIM_PARAMS);
OsdiSimParas sim_params_ = {.names = sim_params,
.vals = (double *)&sim_param_vals,
.names_str = sim_params_str,
.vals_str = NULL};
return sim_params_;
}
static void eval(const OsdiDescriptor *descr, const GENinstance *gen_inst,
void *inst, OsdiExtraInstData *extra_inst_data,
const void *model, const OsdiSimInfo *sim_info) {
OsdiNgspiceHandle handle =
(OsdiNgspiceHandle){.kind = 3, .name = gen_inst->GENname};
/* TODO initial conditions? */
extra_inst_data->eval_flags = descr->eval(&handle, inst, model, sim_info);
}
static void load(CKTcircuit *ckt, const GENinstance *gen_inst, void *model,
void *inst, OsdiExtraInstData *extra_inst_data, bool is_tran,
bool is_init_tran, const OsdiDescriptor *descr) {
double dump;
if (is_tran) {
/* load dc matrix and capacitances (charge derivative multiplied with
* CKTag[0]) */
descr->load_jacobian_tran(inst, model, ckt->CKTag[0]);
/* load static rhs and dynamic linearized rhs (SUM Vb * dIa/dVb)*/
descr->load_spice_rhs_tran(inst, model, ckt->CKTrhs, ckt->CKTrhsOld,
ckt->CKTag[0]);
uint32_t *node_mapping =
(uint32_t *)(((char *)inst) + descr->node_mapping_offset);
/* use numeric integration to obtain the remainer of the RHS*/
int state = gen_inst->GENstate + (int)descr->num_states;
for (uint32_t i = 0; i < descr->num_nodes; i++) {
if (descr->nodes[i].react_residual_off != UINT32_MAX) {
double residual_react =
*((double *)(((char *)inst) + descr->nodes[i].react_residual_off));
/* store charges in state vector*/
ckt->CKTstate0[state] = residual_react;
if (is_init_tran) {
ckt->CKTstate1[state] = residual_react;
}
/* we only care about the numeric integration itself not ceq/geq
because those are already calculated by load_jacobian_tran and
load_spice_rhs_tran*/
NIintegrate(ckt, &dump, &dump, 0, state);
/* add the numeric derivative to the rhs */
ckt->CKTrhs[node_mapping[i]] -= ckt->CKTstate0[state + 1];
if (is_init_tran) {
ckt->CKTstate1[state + 1] = ckt->CKTstate0[state + 1];
}
state += 2;
}
}
} else {
/* copy internal derivatives into global matrix */
descr->load_jacobian_resist(inst, model);
/* calculate spice RHS from internal currents and store into global RHS
*/
descr->load_spice_rhs_dc(inst, model, ckt->CKTrhs, ckt->CKTrhsOld);
}
}
extern int OSDIload(GENmodel *inModel, CKTcircuit *ckt) {
OsdiNgspiceHandle handle;
GENmodel *gen_model;
GENinstance *gen_inst;
double dump;
bool is_init_smsig = ckt->CKTmode & MODEINITSMSIG;
bool is_sweep = ckt->CKTmode & MODEDCTRANCURVE;
bool is_dc = ckt->CKTmode & (MODEDCOP | MODEDCTRANCURVE);
bool is_ac = ckt->CKTmode & (MODEAC | MODEINITSMSIG);
bool is_tran = ckt->CKTmode & (MODETRAN);
bool is_tran_op = ckt->CKTmode & (MODETRANOP);
bool is_init_tran = ckt->CKTmode & MODEINITTRAN;
bool is_init_junc = ckt->CKTmode & MODEINITJCT;
OsdiSimInfo sim_info = {
.paras = get_simparams(ckt),
.abstime = is_tran ? ckt->CKTtime : 0.0,
.prev_solve = ckt->CKTrhsOld,
.prev_state = ckt->CKTstates[0],
.next_state = ckt->CKTstates[0],
.flags = CALC_RESIST_JACOBIAN,
};
if (is_init_smsig || is_sweep) {
sim_info.flags |= CALC_OP;
}
if (is_dc) {
sim_info.flags |= ANALYSIS_DC | ANALYSIS_STATIC;
}
if (!is_init_smsig) {
sim_info.flags |= CALC_RESIST_RESIDUAL | ENABLE_LIM | CALC_RESIST_LIM_RHS;
}
if (is_tran) {
sim_info.flags |= CALC_REACT_JACOBIAN | CALC_REACT_RESIDUAL |
CALC_REACT_LIM_RHS | ANALYSIS_TRAN;
}
if (is_tran_op) {
sim_info.flags |= ANALYSIS_TRAN;
}
if (is_ac) {
sim_info.flags |= CALC_REACT_JACOBIAN | ANALYSIS_AC;
}
if (is_init_tran) {
sim_info.flags |= ANALYSIS_IC | ANALYSIS_STATIC;
}
if (is_init_junc) {
sim_info.flags |= INIT_LIM;
}
if (ckt->CKTmode & MODEACNOISE) {
sim_info.flags |= CALC_NOISE | ANALYSIS_NOISE;
}
int ret = OK;
OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel);
const OsdiDescriptor *descr = entry->descriptor;
uint32_t eval_flags = 0;
#ifdef USE_OMP
/* use openmp 3.0 tasks to parallelize linked list transveral */
#pragma omp parallel
#pragma omp single
{
for (gen_model = inModel; gen_model; gen_model = gen_model->GENnextModel) {
void *model = osdi_model_data(gen_model);
for (gen_inst = gen_model->GENinstances; gen_inst;
gen_inst = gen_inst->GENnextInstance) {
void *inst = osdi_instance_data(entry, gen_inst);
OsdiExtraInstData *extra_inst_data =
osdi_extra_instance_data(entry, gen_inst);
#pragma omp task firstprivate(gen_inst, inst, extra_inst_data, model)
eval(descr, gen_inst, inst, extra_inst_data, model, &sim_info);
}
}
}
/* init small signal analysis does not require loading values into
* matrix/rhs*/
if (is_init_smsig) {
return ret;
}
for (gen_model = inModel; gen_model; gen_model = gen_model->GENnextModel) {
void *model = osdi_model_data(gen_model);
for (gen_inst = gen_model->GENinstances; gen_inst;
gen_inst = gen_inst->GENnextInstance) {
void *inst = osdi_instance_data(entry, gen_inst);
OsdiExtraInstData *extra_inst_data =
osdi_extra_instance_data(entry, gen_inst);
load(ckt, gen_inst, model, inst, extra_inst_data, is_tran, is_init_tran,
descr);
eval_flags |= extra_inst_data->eval_flags;
}
}
#else
for (gen_model = inModel; gen_model; gen_model = gen_model->GENnextModel) {
void *model = osdi_model_data(gen_model);
for (gen_inst = gen_model->GENinstances; gen_inst;
gen_inst = gen_inst->GENnextInstance) {
void *inst = osdi_instance_data(entry, gen_inst);
OsdiExtraInstData *extra_inst_data =
osdi_extra_instance_data(entry, gen_inst);
eval(descr, gen_inst, inst, extra_inst_data, model, &sim_info);
/* init small signal analysis does not require loading values into
* matrix/rhs*/
if (!is_init_smsig) {
load(ckt, gen_inst, model, inst, extra_inst_data, is_tran, is_init_tran,
descr);
eval_flags |= extra_inst_data->eval_flags;
}
}
}
#endif
/* call to $fatal in Verilog-A abort simulation!*/
if (eval_flags & EVAL_RET_FLAG_FATAL) {
return E_PANIC;
}
if (eval_flags & EVAL_RET_FLAG_LIM) {
ckt->CKTnoncon++;
ckt->CKTtroubleElt = gen_inst;
}
if (eval_flags & EVAL_RET_FLAG_STOP) {
return E_PAUSE;
}
return OK;
}

164
src/osdi/osdiparam.c Normal file
View File

@ -0,0 +1,164 @@
/*
* This file is part of the OSDI component of NGSPICE.
* Copyright© 2022 SemiMod GmbH.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Author: Pascal Kuthe <pascal.kuthe@semimod.de>
*/
#include "ngspice/iferrmsg.h"
#include "ngspice/ngspice.h"
#include "ngspice/typedefs.h"
#include "osdidefs.h"
#include <stdint.h>
#include <string.h>
static int osdi_param_access(OsdiParamOpvar *param_info, bool write_value,
IFvalue *value, void *ptr) {
size_t len;
void *val_ptr;
switch (param_info->flags & PARA_TY_MASK) {
case PARA_TY_REAL:
len = sizeof(double);
if (param_info->len) {
len *= param_info->len;
val_ptr = &value->v.vec.rVec;
} else {
val_ptr = &value->rValue;
}
break;
case PARA_TY_INT:
len = sizeof(int);
if (param_info->len) {
len *= param_info->len;
val_ptr = &value->v.vec.iVec;
} else {
val_ptr = &value->iValue;
}
break;
case PARA_TY_STR:
len = sizeof(char *);
if (param_info->len) {
len *= param_info->len;
val_ptr = &value->v.vec.cVec;
} else {
val_ptr = &value->cValue;
}
break;
default:
return (E_PARMVAL);
}
if (write_value) {
memcpy(val_ptr, ptr, len);
} else {
memcpy(ptr, val_ptr, len);
}
return OK;
}
static int osdi_write_param(void *dst, IFvalue *value, int param,
const OsdiDescriptor *descr) {
if (dst == NULL) {
return (E_PANIC);
}
OsdiParamOpvar *param_info = &descr->param_opvar[param];
if (param_info->len) {
if ((uint32_t)value->v.numValue != param_info->len) {
return (E_PARMVAL);
}
}
return osdi_param_access(param_info, false, value, dst);
}
extern int OSDIparam(int param, IFvalue *value, GENinstance *instPtr,
IFvalue *select) {
NG_IGNORE(select);
OsdiRegistryEntry *entry = osdi_reg_entry_inst(instPtr);
const OsdiDescriptor *descr = entry->descriptor;
if (param >= (int)descr->num_instance_params) {
// special handling for temperature parameters
OsdiExtraInstData *inst = osdi_extra_instance_data(entry, instPtr);
if (param == (int)entry->dt) {
inst->dt = value->rValue;
inst->dt_given = true;
return (OK);
}
if (param == (int)entry->temp) {
inst->temp = value->rValue;
inst->temp_given = true;
return (OK);
}
return (E_BADPARM);
}
void *inst = osdi_instance_data(entry, instPtr);
void *dst = descr->access(inst, NULL, (uint32_t)param,
ACCESS_FLAG_SET | ACCESS_FLAG_INSTANCE);
return osdi_write_param(dst, value, param, descr);
}
extern int OSDImParam(int param, IFvalue *value, GENmodel *modelPtr) {
OsdiRegistryEntry *entry = osdi_reg_entry_model(modelPtr);
const OsdiDescriptor *descr = entry->descriptor;
if (param > (int)descr->num_params ||
param < (int)descr->num_instance_params) {
return (E_BADPARM);
}
void *model = osdi_model_data(modelPtr);
void *dst = descr->access(NULL, model, (uint32_t)param, ACCESS_FLAG_SET);
return osdi_write_param(dst, value, param, descr);
}
static int osdi_read_param(void *src, IFvalue *value, int id,
const OsdiDescriptor *descr) {
if (src == NULL) {
return (E_PANIC);
}
OsdiParamOpvar *param_info = &descr->param_opvar[id];
if (param_info->len) {
value->v.numValue = (int)param_info->len;
}
return osdi_param_access(param_info, true, value, src);
}
extern int OSDIask(CKTcircuit *ckt, GENinstance *instPtr, int id,
IFvalue *value, IFvalue *select) {
NG_IGNORE(select);
NG_IGNORE(ckt);
OsdiRegistryEntry *entry = osdi_reg_entry_inst(instPtr);
void *inst = osdi_instance_data(entry, instPtr);
void *model = osdi_model_data_from_inst(instPtr);
const OsdiDescriptor *descr = entry->descriptor;
if (id >= (int)(descr->num_params + descr->num_opvars)) {
return (E_BADPARM);
}
uint32_t flags = ACCESS_FLAG_READ;
if (id < (int)descr->num_instance_params) {
flags |= ACCESS_FLAG_INSTANCE;
}
void *src = descr->access(inst, model, (uint32_t)id, flags);
return osdi_read_param(src, value, id, descr);
}

49
src/osdi/osdipzld.c Normal file
View File

@ -0,0 +1,49 @@
/*
* This file is part of the OSDI component of NGSPICE.
* Copyright© 2022 SemiMod GmbH.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Author: Pascal Kuthe <pascal.kuthe@semimod.de>
*/
#include "ngspice/iferrmsg.h"
#include "ngspice/memory.h"
#include "ngspice/ngspice.h"
#include "ngspice/typedefs.h"
#include "osdi.h"
#include "osdidefs.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int OSDIpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) {
NG_IGNORE(ckt);
GENmodel *gen_model;
GENinstance *gen_inst;
OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel);
const OsdiDescriptor *descr = entry->descriptor;
for (gen_model = inModel; gen_model; gen_model = gen_model->GENnextModel) {
void *model = osdi_model_data(gen_model);
for (gen_inst = gen_model->GENinstances; gen_inst;
gen_inst = gen_inst->GENnextInstance) {
void *inst = osdi_instance_data(entry, gen_inst);
// nothing to calculate just load the matrix entries calculated during
// operating point iterations
// the load_jacobian_tran function migh seem weird here but all this does
// is adding J_resist + J_react * a to every matrix entry (real part).
// J_resist are the conductances (normal matrix entries) and J_react the
// capcitances
descr->load_jacobian_tran(inst, model, s->real);
descr->load_jacobian_react(inst, model, s->imag);
}
}
return (OK);
}

430
src/osdi/osdiregistry.c Normal file
View File

@ -0,0 +1,430 @@
/*
* This file is part of the OSDI component of NGSPICE.
* Copyright© 2022 SemiMod GmbH.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Author: Pascal Kuthe <pascal.kuthe@semimod.de>
*/
#include "ngspice/hash.h"
#include "ngspice/memory.h"
#include "ngspice/stringutil.h"
#include "osdidefs.h"
#include <sys/stat.h>
#include "osdi.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if (!defined HAS_WINGUI) && (!defined __MINGW32__) && (!defined _MSC_VER)
#include <dlfcn.h> /* to load libraries*/
#define OPENLIB(path) dlopen(path, RTLD_NOW | RTLD_LOCAL)
#define GET_SYM(lib, sym) dlsym(lib, sym)
#define FREE_DLERR_MSG(msg)
#else /* ifdef HAS_WINGUI */
#undef BOOLEAN
#include <windows.h>
#include <shlwapi.h>
#define OPENLIB(path) LoadLibrary(path)
#define GET_SYM(lib, sym) ((void *)GetProcAddress(lib, sym))
char *dlerror(void);
#define FREE_DLERR_MSG(msg) free_dlerr_msg(msg)
static void free_dlerr_msg(char *msg);
#endif /* ifndef HAS_WINGUI */
char *inputdir = NULL;
/* Returns true if path is an absolute path and false if it is a
* relative path. No check is done for the existance of the path. */
inline static bool is_absolute_pathname(const char *path) {
#ifdef _WIN32
return !PathIsRelativeA(path);
#else
return path[0] == DIR_TERM;
#endif
} /* end of funciton is_absolute_pathname */
/*-------------------------------------------------------------------------*
Look up the variable sourcepath and try everything in the list in order
if the file isn't in . and it isn't an abs path name.
*-------------------------------------------------------------------------*/
static char *resolve_path(const char *name) {
struct stat st;
#if defined(_WIN32)
/* If variable 'mingwpath' is set: convert mingw /d/... to d:/... */
if (cp_getvar("mingwpath", CP_BOOL, NULL, 0) && name[0] == DIR_TERM_LINUX &&
isalpha_c(name[1]) && name[2] == DIR_TERM_LINUX) {
DS_CREATE(ds, 100);
if (ds_cat_str(&ds, name) != 0) {
fprintf(stderr, "Unable to copy string while resolving path");
controlled_exit(EXIT_FAILURE);
}
char *const buf = ds_get_buf(&ds);
buf[0] = buf[1];
buf[1] = ':';
char *const resolved_path = resolve_path(buf);
ds_free(&ds);
return resolved_path;
}
#endif
/* just try it */
if (stat(name, &st) == 0)
return copy(name);
#if !defined(EXT_ASC) && (defined(__MINGW32__) || defined(_MSC_VER))
wchar_t wname[BSIZE_SP];
if (MultiByteToWideChar(CP_UTF8, 0, name, -1, wname,
2 * (int)strlen(name) + 1) == 0) {
fprintf(stderr, "UTF-8 to UTF-16 conversion failed with 0x%x\n",
GetLastError());
fprintf(stderr, "%s could not be converted\n", name);
return NULL;
}
if (_waccess(wname, 0) == 0)
return copy(name);
#endif
return (char *)NULL;
} /* end of function inp_pathresolve */
static char *resolve_input_path(const char *name) {
/* if name is an absolute path name,
* or if we haven't anything to prepend anyway
*/
if (is_absolute_pathname(name)) {
return resolve_path(name);
}
if (name[0] == '~' && name[1] == '/') {
char *const y = cp_tildexpand(name);
if (y) {
char *const r = resolve_path(y);
txfree(y);
return r;
}
}
/*
* If called from a script inputdir != NULL so try relativ to that dir
* Otherwise try relativ to the current workdir
*/
if (inputdir) {
DS_CREATE(ds, 100);
int rc_ds = 0;
rc_ds |= ds_cat_str(&ds, inputdir); /* copy the dir name */
const size_t n = ds_get_length(&ds); /* end of copied dir name */
/* Append a directory separator if not present already */
const char ch_last = n > 0 ? inputdir[n - 1] : '\0';
if (ch_last != DIR_TERM
#ifdef _WIN32
&& ch_last != DIR_TERM_LINUX
#endif
) {
rc_ds |= ds_cat_char(&ds, DIR_TERM);
}
rc_ds |= ds_cat_str(&ds, name); /* append the file name */
if (rc_ds != 0) {
(void)fprintf(cp_err, "Unable to build \"dir\" path name "
"in inp_pathresolve_at");
controlled_exit(EXIT_FAILURE);
}
char *const r = resolve_path(ds_get_buf(&ds));
ds_free(&ds);
return r;
} else {
DS_CREATE(ds, 100);
if (ds_cat_printf(&ds, ".%c%s", DIR_TERM, name) != 0) {
(void)fprintf(cp_err,
"Unable to build \".\" path name in inp_pathresolve_at");
controlled_exit(EXIT_FAILURE);
}
char *const r = resolve_path(ds_get_buf(&ds));
ds_free(&ds);
if (r != (char *)NULL) {
return r;
}
}
return NULL;
} /* end of function inp_pathresolve_at */
/**
* Calculates the offset that the OSDI instance data has from the beginning of
* the instance data allocated by ngspice. This offset is non trivial because
* ngspice must store the terminal pointers before the remaining instance
* data. As a result the offset is not constant and a variable amount of
* padding must be inserted to ensure correct alginment.
*/
static size_t calc_osdi_instance_data_off(const OsdiDescriptor *descr) {
size_t res = sizeof(GENinstance) /* generic data */
+ descr->num_terminals * sizeof(int);
size_t padding = sizeof(max_align_t) - res % sizeof(max_align_t);
if (padding == sizeof(max_align_t)) {
padding = 0;
}
return res + padding;
}
#define INVALID_OBJECT \
(OsdiObjectFile) { .num_entries = -1 }
#define EMPTY_OBJECT \
(OsdiObjectFile) {NULL, 0}
#define ERR_AND_RET \
error = dlerror(); \
printf("Error opening osdi lib \"%s\": %s\n", path, error); \
FREE_DLERR_MSG(error); \
return INVALID_OBJECT;
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define GET_CONST(name, ty) \
sym = GET_SYM(handle, STRINGIFY(name)); \
if (!sym) { \
ERR_AND_RET \
} \
const ty name = *((ty *)sym);
#define GET_PTR(name, ty) \
sym = GET_SYM(handle, STRINGIFY(name)); \
if (!sym) { \
ERR_AND_RET \
} \
const ty *name = (ty *)sym;
#define INIT_CALLBACK(name, ty) \
sym = GET_SYM(handle, STRINGIFY(name)); \
if (sym) { \
ty *slot = (ty *)sym; \
*slot = name; \
}
#define IS_LIM_FUN(fun_name, num_args_, val) \
if (strcmp(lim_table[i].name, fun_name) == 0) { \
if (lim_table[i].num_args == num_args_) { \
lim_table[i].func_ptr = (void *)val; \
continue; \
} else { \
expected_args = num_args_; \
} \
}
static NGHASHPTR known_object_files = NULL;
#define DUMMYDATA ((void *)42)
/**
* Loads an object file from the hard drive with the platform equivalent of
* dlopen. This function checks that the OSDI version of the object file is
* valid and then writes all data into the `registry`.
* If any errors occur an appropriate message is written to errMsg
*
* @param PATH path A path to the shared object file
* @param uint32_t* len The amount of entries already written into `registry`
* @param uint32_t* capacity The amount of space available in `registry`
* before reallocation is required
* @returns -1 on error, 0 otherwise
*/
extern OsdiObjectFile load_object_file(const char *input) {
void *handle;
char *error;
const void *sym;
/* ensure the hashtable exists */
if (!known_object_files) {
known_object_files = nghash_init_pointer(8);
}
const char *path = resolve_input_path(input);
if (!path) {
printf("Error opening osdi lib \"%s\": No such file or directory!\n",
input);
return INVALID_OBJECT;
}
handle = OPENLIB(path);
if (!handle) {
ERR_AND_RET
}
/* Keep track of loaded shared object files to avoid loading the same model
* multiple times. We use the handle as a key because the same SO will always
* return the SAME pointer as long as dlclose is not called.
* nghash_insert returns NULL if the key (handle) was not already in the table
* and the data (DUMMYDATA) that was previously insered (!= NULL) otherwise*/
if (nghash_insert(known_object_files, handle, DUMMYDATA)) {
return EMPTY_OBJECT;
}
GET_CONST(OSDI_VERSION_MAJOR, uint32_t);
GET_CONST(OSDI_VERSION_MINOR, uint32_t);
if (OSDI_VERSION_MAJOR != OSDI_VERSION_MAJOR_CURR ||
OSDI_VERSION_MINOR != OSDI_VERSION_MINOR_CURR) {
printf("NGSPICE only supports OSDI v%d.%d but \"%s\" targets v%d.%d!",
OSDI_VERSION_MAJOR_CURR, OSDI_VERSION_MINOR_CURR, path,
OSDI_VERSION_MAJOR, OSDI_VERSION_MINOR);
return INVALID_OBJECT;
}
GET_CONST(OSDI_NUM_DESCRIPTORS, uint32_t);
GET_PTR(OSDI_DESCRIPTORS, OsdiDescriptor);
INIT_CALLBACK(osdi_log, osdi_log_ptr)
uint32_t lim_table_len = 0;
sym = GET_SYM(handle, "OSDI_LIM_TABLE_LEN");
if (sym) {
lim_table_len = *((uint32_t *)sym);
}
sym = GET_SYM(handle, "OSDI_LIM_TABLE");
OsdiLimFunction *lim_table = NULL;
if (sym) {
lim_table = (OsdiLimFunction *)sym;
} else {
lim_table_len = 0;
}
for (uint32_t i = 0; i < lim_table_len; i++) {
int expected_args = -1;
IS_LIM_FUN("pnjlim", 2, osdi_pnjlim)
IS_LIM_FUN("limvds", 0, osdi_limvds)
IS_LIM_FUN("fetlim", 1, osdi_fetlim)
IS_LIM_FUN("limitlog", 1, osdi_limitlog)
if (expected_args == -1) {
printf("warning(osdi): unkown $limit function \"%s\"", lim_table[i].name);
} else {
printf("warning(osdi): unexpected number of arguments %i (expected %i) "
"for \"%s\", ignoring...",
lim_table[i].num_args, expected_args, lim_table[i].name);
}
}
OsdiRegistryEntry *dst = TMALLOC(OsdiRegistryEntry, OSDI_NUM_DESCRIPTORS);
for (uint32_t i = 0; i < OSDI_NUM_DESCRIPTORS; i++) {
const OsdiDescriptor *descr = &OSDI_DESCRIPTORS[i];
uint32_t dt = descr->num_params + descr->num_opvars;
uint32_t temp = descr->num_params + descr->num_opvars + 1;
for (uint32_t param_id = 0; param_id < descr->num_params; param_id++) {
OsdiParamOpvar *param = &descr->param_opvar[param_id];
for (uint32_t j = 0; j < 1 + param->num_alias; j++) {
char *name = param->name[j];
if (!strcmp(name, "dt")) {
dt = UINT32_MAX;
} else if (!strcasecmp(name, "dtemp") || !strcasecmp(name, "dt")) {
dt = param_id;
} else if (!strcmp(name, "temp")) {
temp = UINT32_MAX;
} else if (!strcasecmp(name, "temp") ||
!strcasecmp(name, "temperature")) {
temp = param_id;
}
}
}
size_t inst_off = calc_osdi_instance_data_off(descr);
dst[i] = (OsdiRegistryEntry){
.descriptor = descr,
.inst_offset = (uint32_t)inst_off,
.dt = dt,
.temp = temp,
};
}
return (OsdiObjectFile){
.entrys = dst,
.num_entries = (int)OSDI_NUM_DESCRIPTORS,
};
}
inline size_t osdi_instance_data_off(const OsdiRegistryEntry *entry) {
return entry->inst_offset;
}
inline void *osdi_instance_data(const OsdiRegistryEntry *entry,
GENinstance *inst) {
return (void *)(((char *)inst) + osdi_instance_data_off(entry));
}
inline OsdiExtraInstData *
osdi_extra_instance_data(const OsdiRegistryEntry *entry, GENinstance *inst) {
OsdiDescriptor *descr = (OsdiDescriptor *)entry->descriptor;
return (OsdiExtraInstData *)(((char *)inst) + entry->inst_offset +
descr->instance_size);
}
inline size_t osdi_model_data_off(void) {
return offsetof(OsdiModelData, data);
}
inline void *osdi_model_data(GENmodel *model) {
return (void *)&((OsdiModelData *)model)->data;
}
inline void *osdi_model_data_from_inst(GENinstance *inst) {
return osdi_model_data(inst->GENmodPtr);
}
inline OsdiRegistryEntry *osdi_reg_entry_model(const GENmodel *model) {
return (OsdiRegistryEntry *)ft_sim->devices[model->GENmodType]
->registry_entry;
}
inline OsdiRegistryEntry *osdi_reg_entry_inst(const GENinstance *inst) {
return osdi_reg_entry_model(inst->GENmodPtr);
}
#if defined(__MINGW32__) || defined(HAS_WINGUI) || defined(_MSC_VER)
/* For reporting error message if formatting fails */
static const char errstr_fmt[] =
"Unable to find message in dlerr(). System code = %lu";
static char errstr[sizeof errstr_fmt - 3 + 3 * sizeof(unsigned long)];
#if !defined (XSPICE)
char *dlerror(void) {
LPVOID lpMsgBuf;
DWORD rc = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf, 0, NULL);
if (rc == 0) { /* FormatMessage failed */
(void)sprintf(errstr, errstr_fmt, (unsigned long)GetLastError());
return errstr;
}
return lpMsgBuf; /* Return the formatted message */
} /* end of function dlerror */
#endif
/* Free message related to dynamic loading */
static void free_dlerr_msg(char *msg) {
if (msg != errstr) { /* msg is an allocation */
LocalFree(msg);
}
} /* end of function free_dlerr_msg */
#endif /* Windows emulation of dlerr */

410
src/osdi/osdisetup.c Normal file
View File

@ -0,0 +1,410 @@
/*
* This file is part of the OSDI component of NGSPICE.
* Copyright© 2022 SemiMod GmbH.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Author: Pascal Kuthe <pascal.kuthe@semimod.de>
*/
#include "ngspice/iferrmsg.h"
#include "ngspice/memory.h"
#include "ngspice/ngspice.h"
#include "ngspice/typedefs.h"
#include "osdi.h"
#include "osdidefs.h"
#include <stdint.h>
#include <stdio.h>
#include <string.h>
/*
* Handles any errors raised by the setup_instance and setup_model functions
*/
static int handle_init_info(OsdiInitInfo info, const OsdiDescriptor *descr) {
if (info.flags & (EVAL_RET_FLAG_FATAL | EVAL_RET_FLAG_FINISH)) {
return (E_PANIC);
}
if (info.num_errors == 0) {
return (OK);
}
for (uint32_t i = 0; i < info.num_errors; i++) {
OsdiInitError *err = &info.errors[i];
switch (err->code) {
case INIT_ERR_OUT_OF_BOUNDS: {
char *param = descr->param_opvar[err->payload.parameter_id].name[0];
printf("Parameter %s is out of bounds!\n", param);
break;
}
default:
printf("Unkown OSDO init error code %d!\n", err->code);
}
}
free(info.errors);
errMsg = tprintf("%i errors occurred during initalization", info.num_errors);
return (E_PRIVATE);
}
/*
* The OSDI instance data contains the `node_mapping` array.
* Here an index is stored for each node. This function initializes this array
* with its indicies {0, 1, 2, 3, .., n}.
* The node collapsing information generated by setup_instance is used to
* replace these initial indicies with those that a node is collapsed into.
* For example collapsing nodes i and j sets node_mapping[i] = j.
*
* Terminals can never be collapsed in ngspice because they are allocated by
* ngspice instead of OSDI. Therefore any node collapsing that involves nodes
* `i < connected_terminals` is ignored.
*
* @param const OsdiDescriptor *descr The OSDI descriptor
* @param void *inst The instance data connected_terminals
* @param uint32_t connected_terminals The number of terminals that are not
* internal nodes.
*
* @returns The number of nodes required after collapsing.
* */
static uint32_t collapse_nodes(const OsdiDescriptor *descr, void *inst,
uint32_t connected_terminals) {
/* access data inside instance */
uint32_t *node_mapping =
(uint32_t *)(((char *)inst) + descr->node_mapping_offset);
bool *collapsed = (bool *)(((char *)inst) + descr->collapsed_offset);
/* without collapsing just return the total number of nodes */
uint32_t num_nodes = descr->num_nodes;
/* populate nodes with themselves*/
for (uint32_t i = 0; i < descr->num_nodes; i++) {
node_mapping[i] = i;
}
for (uint32_t i = 0; i < descr->num_collapsible; i++) {
/* check if the collapse hint (V(x,y) <+ 0) was executed */
if (!collapsed[i]) {
continue;
}
uint32_t from = descr->collapsible[i].node_1;
uint32_t to = descr->collapsible[i].node_2;
/* terminals created by the simulator cannot be collapsed
*/
if (node_mapping[from] < connected_terminals &&
(to == UINT32_MAX || node_mapping[to] < connected_terminals ||
node_mapping[to] == UINT32_MAX)) {
continue;
}
/* ensure that to is always the smaller node */
if (to != UINT32_MAX && node_mapping[from] < node_mapping[to]) {
uint32_t temp = from;
from = to;
to = temp;
}
from = node_mapping[from];
if (to != UINT32_MAX) {
to = node_mapping[to];
}
/* replace nodes mapped to from with to and reduce the number of nodes */
for (uint32_t j = 0; j < descr->num_nodes; j++) {
if (node_mapping[j] == from) {
node_mapping[j] = to;
} else if (node_mapping[j] > from && node_mapping[j] != UINT32_MAX) {
node_mapping[j] -= 1;
}
}
num_nodes -= 1;
}
return num_nodes;
}
/* replace node mapping local to the current instance (created by
* collapse_nodes) with global node indicies allocated with CKTmkVolt */
static void write_node_mapping(const OsdiDescriptor *descr, void *inst,
uint32_t *nodes) {
uint32_t *node_mapping =
(uint32_t *)(((char *)inst) + descr->node_mapping_offset);
for (uint32_t i = 0; i < descr->num_nodes; i++) {
if (node_mapping[i] == UINT32_MAX) {
/* gnd node */
node_mapping[i] = 0;
} else {
node_mapping[i] = nodes[node_mapping[i]];
}
}
}
/* NGSPICE state vectors for an instance are always continous so we just write
* state_start .. state_start + num_state to state_idx */
static void write_state_ids(const OsdiDescriptor *descr, void *inst,
uint32_t state_start) {
uint32_t *state_idx = (uint32_t *)(((char *)inst) + descr->state_idx_off);
for (uint32_t i = 0; i < descr->num_states; i++) {
state_idx[i] = state_start + i;
}
}
static int init_matrix(SMPmatrix *matrix, const OsdiDescriptor *descr,
void *inst) {
uint32_t *node_mapping =
(uint32_t *)(((char *)inst) + descr->node_mapping_offset);
double **jacobian_ptr_resist =
(double **)(((char *)inst) + descr->jacobian_ptr_resist_offset);
for (uint32_t i = 0; i < descr->num_jacobian_entries; i++) {
uint32_t equation = descr->jacobian_entries[i].nodes.node_1;
uint32_t unkown = descr->jacobian_entries[i].nodes.node_2;
equation = node_mapping[equation];
unkown = node_mapping[unkown];
double *ptr = SMPmakeElt(matrix, (int)equation, (int)unkown);
if (ptr == NULL) {
return (E_NOMEM);
}
jacobian_ptr_resist[i] = ptr;
uint32_t react_off = descr->jacobian_entries[i].react_ptr_off;
// complex number for ac analysis
if (react_off != UINT32_MAX) {
double **jacobian_ptr_react = (double **)(((char *)inst) + react_off);
*jacobian_ptr_react = ptr + 1;
}
}
return (OK);
}
int OSDIsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
int *states) {
OsdiInitInfo init_info;
OsdiNgspiceHandle handle;
GENmodel *gen_model;
int res;
int error;
CKTnode *tmp;
GENinstance *gen_inst;
int err;
OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel);
const OsdiDescriptor *descr = entry->descriptor;
OsdiSimParas sim_params_ = get_simparams(ckt);
OsdiSimParas *sim_params = &sim_params_;
/* setup a temporary buffer */
uint32_t *node_ids = TMALLOC(uint32_t, descr->num_nodes);
/* determine the number of states required by each instance */
int num_states = (int)descr->num_states;
for (uint32_t i = 0; i < descr->num_nodes; i++) {
if (descr->nodes[i].react_residual_off != UINT32_MAX) {
num_states += 2;
}
}
for (gen_model = inModel; gen_model; gen_model = gen_model->GENnextModel) {
void *model = osdi_model_data(gen_model);
/* setup model parameter (setup_model)*/
handle = (OsdiNgspiceHandle){.kind = 1, .name = gen_model->GENmodName};
descr->setup_model((void *)&handle, model, sim_params, &init_info);
res = handle_init_info(init_info, descr);
if (res) {
errRtn = "OSDI setup_model";
continue;
}
for (gen_inst = gen_model->GENinstances; gen_inst;
gen_inst = gen_inst->GENnextInstance) {
void *inst = osdi_instance_data(entry, gen_inst);
/* special handling for temperature parameters */
double temp = ckt->CKTtemp;
OsdiExtraInstData *extra_inst_data =
osdi_extra_instance_data(entry, gen_inst);
if (extra_inst_data->temp_given) {
temp = extra_inst_data->temp;
}
if (extra_inst_data->dt_given) {
temp += extra_inst_data->dt;
}
/* find number of connected ports to allow evaluation of $port_connected
* and to handle node collapsing correctly later
* */
int *terminals = (int *)(gen_inst + 1);
uint32_t connected_terminals = descr->num_terminals;
for (uint32_t i = 0; i < descr->num_terminals; i++) {
if (terminals[i] == -1) {
connected_terminals = i;
break;
}
}
/* calculate op independent data, init instance parameters and determine
which collapsing occurs*/
handle = (OsdiNgspiceHandle){.kind = 2, .name = gen_inst->GENname};
descr->setup_instance((void *)&handle, inst, model, temp,
connected_terminals, sim_params, &init_info);
res = handle_init_info(init_info, descr);
if (res) {
errRtn = "OSDI setup_instance";
continue;
}
/* setup the instance nodes */
uint32_t num_nodes = collapse_nodes(descr, inst, connected_terminals);
/* copy terminals */
memcpy(node_ids, gen_inst + 1, sizeof(int) * connected_terminals);
/* create internal nodes as required */
for (uint32_t i = connected_terminals; i < num_nodes; i++) {
// TODO handle currents correctly
if (descr->nodes[i].is_flow) {
error = CKTmkCur(ckt, &tmp, gen_inst->GENname, descr->nodes[i].name);
} else {
error = CKTmkVolt(ckt, &tmp, gen_inst->GENname, descr->nodes[i].name);
}
if (error)
return (error);
node_ids[i] = (uint32_t)tmp->number;
// TODO nodeset?
}
write_node_mapping(descr, inst, node_ids);
/* now that we have the node mapping we can create the matrix entries */
err = init_matrix(matrix, descr, inst);
if (err) {
return err;
}
/* reserve space in the state vector*/
gen_inst->GENstate = *states;
write_state_ids(descr, inst, (uint32_t)*states);
*states += num_states;
}
}
free(node_ids);
return (OK);
}
/* OSDI does not differentiate between setup and temperature update so we just
* call the setup routines again and assume that node collapsing (and therefore
* node mapping) stays the same
*/
extern int OSDItemp(GENmodel *inModel, CKTcircuit *ckt) {
OsdiInitInfo init_info;
OsdiNgspiceHandle handle;
GENmodel *gen_model;
int res;
GENinstance *gen_inst;
OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel);
const OsdiDescriptor *descr = entry->descriptor;
OsdiSimParas sim_params_ = get_simparams(ckt);
OsdiSimParas *sim_params = &sim_params_;
for (gen_model = inModel; gen_model != NULL;
gen_model = gen_model->GENnextModel) {
void *model = osdi_model_data(gen_model);
handle = (OsdiNgspiceHandle){.kind = 4, .name = gen_model->GENmodName};
descr->setup_model((void *)&handle, model, sim_params, &init_info);
res = handle_init_info(init_info, descr);
if (res) {
errRtn = "OSDI setup_model (OSDItemp)";
continue;
}
for (gen_inst = gen_model->GENinstances; gen_inst != NULL;
gen_inst = gen_inst->GENnextInstance) {
void *inst = osdi_instance_data(entry, gen_inst);
// special handleing for temperature parameters
double temp = ckt->CKTtemp;
OsdiExtraInstData *extra_inst_data =
osdi_extra_instance_data(entry, gen_inst);
if (extra_inst_data->temp_given) {
temp = extra_inst_data->temp;
}
if (extra_inst_data->dt_given) {
temp += extra_inst_data->dt;
}
handle = (OsdiNgspiceHandle){.kind = 2, .name = gen_inst->GENname};
/* find number of connected ports to allow evaluation of $port_connected
* and to handle node collapsing correctly later
* */
int *terminals = (int *)(gen_inst + 1);
uint32_t connected_terminals = descr->num_terminals;
for (uint32_t i = 0; i < descr->num_terminals; i++) {
if (terminals[i] == -1) {
connected_terminals = i;
break;
}
}
descr->setup_instance((void *)&handle, inst, model, temp,
connected_terminals, sim_params, &init_info);
res = handle_init_info(init_info, descr);
if (res) {
errRtn = "OSDI setup_instance (OSDItemp)";
continue;
}
// TODO check that there are no changes in node collapse?
}
}
return (OK);
}
/* delete internal nodes
*/
extern int OSDIunsetup(GENmodel *inModel, CKTcircuit *ckt) {
GENmodel *gen_model;
GENinstance *gen_inst;
int num;
OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel);
const OsdiDescriptor *descr = entry->descriptor;
for (gen_model = inModel; gen_model != NULL;
gen_model = gen_model->GENnextModel) {
for (gen_inst = gen_model->GENinstances; gen_inst != NULL;
gen_inst = gen_inst->GENnextInstance) {
void *inst = osdi_instance_data(entry, gen_inst);
// reset is collapsible
bool *collapsed = (bool *)(((char *)inst) + descr->collapsed_offset);
memset(collapsed, 0, sizeof(bool) * descr->num_collapsible);
uint32_t *node_mapping =
(uint32_t *)(((char *)inst) + descr->node_mapping_offset);
for (uint32_t i = 0; i < descr->num_nodes; i++) {
num = (int)node_mapping[i];
// hand coded implementations just know which nodes were collapsed
// however nodes may be collapsed multiple times so we can't easily use
// an approach like that instead we delete all nodes
// Deleting twiche with CKLdltNNum is fine (entry is already removed
// from the linked list and therefore no action is taken).
// However CKTdltNNum (rightfully) throws an error when trying to delete
// an external node. Therefore we need to check for each node that it is
// an internal node
if (ckt->prev_CKTlastNode->number &&
num > ckt->prev_CKTlastNode->number) {
CKTdltNNum(ckt, num);
}
}
}
}
return (OK);
}

43
src/osdi/osditrunc.c Normal file
View File

@ -0,0 +1,43 @@
/*
* This file is part of the OSDI component of NGSPICE.
* Copyright© 2022 SemiMod GmbH.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Author: Pascal Kuthe <pascal.kuthe@semimod.de>
*/
#include "ngspice/cktdefs.h"
#include "osdidefs.h"
int OSDItrunc(GENmodel *in_model, CKTcircuit *ckt, double *timestep) {
OsdiRegistryEntry *entry = osdi_reg_entry_model(in_model);
const OsdiDescriptor *descr = entry->descriptor;
uint32_t offset = descr->bound_step_offset;
bool has_boundstep = offset != UINT32_MAX;
offset += entry->inst_offset;
for (GENmodel *model = in_model; model; model = model->GENnextModel) {
for (GENinstance *inst = model->GENinstances; inst;
inst = inst->GENnextInstance) {
if (has_boundstep) {
double *del = (double *)(((char *)inst) + offset);
if (*del < *timestep) {
*timestep = *del;
}
}
int state = inst->GENstate;
for (uint32_t i = 0; i < descr->num_nodes; i++) {
if (descr->nodes[i].react_residual_off != UINT32_MAX) {
CKTterr(state, ckt, timestep);
state += 2;
}
}
}
}
return 0;
}

View File

@ -44,9 +44,7 @@ CKTaccept(CKTcircuit *ckt)
}
ckt->CKTsols[0]=temp;
size = SMPmatSize(ckt->CKTmatrix);
for(i=0;i<=size;i++) {
ckt->CKTsols[0][i]=ckt->CKTrhs[i];
}
memcpy(ckt->CKTsols[0], ckt->CKTrhs, (size + 1)*sizeof(double));
#endif /* PREDICTOR */
return(OK);
}

View File

@ -356,11 +356,7 @@ void load_alldevs(void){
}
#endif
/*-------------------- XSPICE additions below ----------------------*/
#ifdef XSPICE
#include "ngspice/mif.h"
#include "ngspice/cm.h"
#include "ngspice/cpextern.h"
#if defined(XSPICE) || defined(OSDI)
#include "ngspice/fteext.h" /* for ft_sim */
#include "ngspice/cktdefs.h" /* for DEVmaxnum */
@ -379,7 +375,14 @@ static void relink(void) {
return;
}
int add_device(int n, SPICEdev **devs, int flag){
#endif
/*-------------------- XSPICE additions below ----------------------*/
#ifdef XSPICE
#include "ngspice/cm.h"
#include "ngspice/cpextern.h"
#include "ngspice/mif.h"
int add_device(int n, SPICEdev **devs, int flag) {
int i;
int dnum = DEVNUM + n;
DEVices = TREALLOC(SPICEdev *, DEVices, dnum);
@ -566,3 +569,35 @@ static void free_dlerr_msg(char *msg)
#endif /* Windows emulation of dlopen, dlsym, and dlerr */
#endif
/*-------------------- end of XSPICE additions ----------------------*/
#ifdef OSDI
#include "ngspice/osdiitf.h"
static int osdi_add_device(int n, OsdiRegistryEntry *devs) {
int i;
int dnum = DEVNUM + n;
DEVices = TREALLOC(SPICEdev *, DEVices, dnum);
#ifdef XSPICE
DEVicesfl = TREALLOC(int, DEVicesfl, dnum);
#endif
for (i = 0; i < n; i++) {
#ifdef TRACE
printf("Added device: %s\n", devs[i]->DEVpublic.name);
#endif
DEVices[DEVNUM + i] = osdi_create_spicedev(&devs[i]);
}
DEVNUM += n;
relink();
return 0;
}
int load_osdi(const char *path) {
OsdiObjectFile file = load_object_file(path);
if (file.num_entries < 0) {
return file.num_entries;
}
osdi_add_device(file.num_entries, file.entrys);
return 0;
}
#endif

View File

@ -15,5 +15,9 @@ int DEVflag(int type);
void load_alldevs(void);
int load_dev(char *name);
#endif
#ifdef OSDI
int load_osdi(const char *);
#endif
#endif

View File

@ -21,7 +21,6 @@ libinp_la_SOURCES = \
inp2k.c \
inp2l.c \
inp2m.c \
inp2n.c \
inp2o.c \
inp2p.c \
inp2q.c \
@ -71,6 +70,11 @@ libinp_la_SOURCES = \
sperror.c \
inpxx.h
if OSDI_WANTED
libinp_la_SOURCES += inp2n.c
endif
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include -I$(top_srcdir)/src/frontend
AM_CFLAGS = $(STATIC)
AM_YFLAGS = -d

View File

@ -1,127 +1,100 @@
/**********
Permit to use it as your wish.
Author: 2007 Gong Ding, gdiso@ustc.edu
University of Science and Technology of China
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Thomas L. Quarles
Modified: 2001 Paolo Nenzi (Cider Integration)
**********/
#include "ngspice/ngspice.h"
#ifdef NDEV
#include <stdio.h>
#include "ngspice/devdefs.h"
#include "ngspice/fteext.h"
#include "ngspice/ifsim.h"
#include "ngspice/inpdefs.h"
#include "../devices/ndev/ndevdefs.h"
#include "ngspice/inpmacs.h"
#include "ngspice/fteext.h"
#include "inpxx.h"
#include <stdio.h>
void INP2N(CKTcircuit *ckt, INPtables * tab, struct card *current)
{
/* parse a numerical device card */
/* Nname <node> <node> [<node> ...] [<mname>] */
/* The NUMD should have a private .model card */
void INP2N(CKTcircuit *ckt, INPtables *tab, struct card *current) {
/* Mname <node> <node> <node> <node> <model> [L=<val>]
* [W=<val>] [AD=<val>] [AS=<val>] [PD=<val>]
* [PS=<val>] [NRD=<val>] [NRS=<val>] [OFF]
* [IC=<val>,<val>,<val>]
*/
int mytype; /* the type we determine NDEV 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 NDEV's name */
char *model; /* the name of the NDEV's model */
int term; /* the number of node */
char *nnamex; /* serve as a temporary name */
char *nname[7]; /* the array of CKT node's name */
char *bname[7]; /* the array of NDEV electrode's name */
CKTnode *node[7]; /* the array of CKT node's node pointer */
int error; /* error code temporary */
int i;
INPmodel *thismodel; /* pointer to model structure describing our model */
GENmodel *mdfast = NULL; /* pointer to the actual model */
GENinstance *fast; /* pointer to the actual instance */
NDEVinstance *pinst;
int waslead; /* flag to indicate that funny unlabeled number was found */
double leadval; /* actual value of unlabeled number */
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 */
// limit to at most 20 nodes
const int max_i = 20;
CKTnode *node[20];
int error; /* error code temporary */
int numnodes; /* flag indicating 4 or 5 (or 6 or 7) nodes */
GENinstance *fast; /* pointer to the actual instance */
int waslead; /* flag to indicate that funny unlabeled number was found */
double leadval; /* actual value of unlabeled number */
INPmodel *thismodel; /* pointer to model description for user's model */
GENmodel *mdfast; /* pointer to the actual model */
int i;
mytype = INPtypelook("NDEV");
if (mytype < 0) {
LITERR("Device type NDEV not supported by this binary\n");
return;
line = current->line;
INPgetNetTok(&line, &name, 1);
INPinsert(&name, tab);
for (i = 0;; i++) {
char *token;
INPgetNetTok(&line, &token, 1);
if (i >= 2) {
txfree(INPgetMod(ckt, token, &thismodel, tab));
/* /1* check if using model binning -- pass in line since need 'l' and 'w' *1/ */
/* if (!thismodel) */
/* txfree(INPgetModBin(ckt, token, &thismodel, tab, line)); */
if (thismodel) {
INPinsert(&token, tab);
break;
}
}
line = current->line;
INPgetTok(&line, &name, 1);
INPinsert(&name, tab);
/* get the node number here */
saveline=line;
term = 0;
do {
INPgetNetTok(&line, &nnamex, 1);
term++;
}while(*nnamex);
line=saveline;
term=(term-2)/2;
if (term > 7) {
LITERR("Numerical device has too many nodes, the limitation is 7\n");
return;
if (i >= max_i) {
LITERR("could not find a valid modelname");
return;
}
for(i=0;i<term;i++) {
INPgetNetTok(&line, &nname[i], 1);
INPgetNetTok(&line, &bname[i], 1);
INPtermInsert(ckt, &nname[i], tab, &node[i]);
}
INPtermInsert(ckt, &token, tab, &node[i]);
}
saveline = line; /* save then old pointer */
type = thismodel->INPmodType;
mdfast = thismodel->INPmodfast;
IFdevice *dev = ft_sim->devices[type];
INPgetNetTok(&line, &model, 1);
if (*model) {
/* token isn't null */
if (INPlookMod(model)) {
/* If this is a valid model connect it */
INPinsert(&model, tab);
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 {
LITERR("Numerical device should always have a model card\n");
return;
}
IFC(newInstance, (ckt, mdfast, &fast, name));
} else {
LITERR("Numerical device should always have a model card\n");
return;
}
for(i=0;i<term;i++) {
IFC(bindNode, (ckt, fast, i+1, node[i]));
}
/* save acture terminal number to instance */
pinst = (NDEVinstance *)fast;
pinst->term = term;
for(i=0;i<term;i++) {
pinst->bname[i]=bname[i];
pinst->node[i]=node[i];
}
PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab));
if (waslead) {
LITERR("The numerical device was lead berfor.\n");
return;
}
if (!dev->registry_entry) {
LITERR("incorrect model type! Expected OSDI device");
return;
}
if (i == 0) {
LITERR("not enough nodes");
return;
}
if (i > *dev->terms) {
LITERR("too many nodes connected to instance");
return;
}
numnodes = i;
IFC(newInstance, (ckt, mdfast, &fast, name));
for (i = 0; i < *dev->terms; i++)
if (i < numnodes)
IFC(bindNode, (ckt, fast, i + 1, node[i]));
else
GENnode(fast)[i] = -1;
PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab));
if (waslead)
LITERR(" error: no unlabeled parameter permitted on osdi devices\n");
}
#else
int Dummy1;
#endif

View File

@ -679,7 +679,7 @@ char *INPdomodel(CKTcircuit *ckt, struct card *image, INPtables * tab)
/* -------- Default action --------- */
else {
#ifndef XSPICE
#if !defined(XSPICE) && !defined(OSDI)
type = -1;
err = tprintf("unknown model type %s - ignored\n", type_name);
#else

Some files were not shown because too many files have changed in this diff Show More