Merge branch 'pre-master' into bt_dev

This commit is contained in:
Brian Taylor 2023-04-01 09:12:34 -07:00
commit 2213edca55
25 changed files with 385 additions and 103 deletions

View File

@ -63,11 +63,6 @@ Table of contents
12.4 BSIMSOI - SOI model (partially/full depleted devices) 12.4 BSIMSOI - SOI model (partially/full depleted devices)
12.5 SOI3 - STAG SOI3 Model 12.5 SOI3 - STAG SOI3 Model
13. Verilog-A models 13. Verilog-A models
13.1 EKV MOS model
13.2 PSP MOS model 102
13.3 PSP MOS model 103
13.4 HICUM0 Bipolar Model
13.5 Mextram Bipolar Model
14. XSPICE code models 14. XSPICE code models
15. Digital Building Blocks (U instances) 15. Digital Building Blocks (U instances)
@ -831,8 +826,8 @@ will be updated every time the device specific code is altered or changed to ref
13.7 PSP 103.8 13.7 PSP 103.8
13.8 r2_cmc 13.8 r2_cmc
More may be made available, user compiled models are possible as well More models are available at https://github.com/dwarning/VA-Models,
(See ngspice manual, chapter 13). user compiled models are possible as well (See ngspice manual, chapter 13).
14. XSpice code models 14. XSpice code models

6
FAQ
View File

@ -1,7 +1,7 @@
Ngspice F.A.Q.Version 2.9 (ngspice-39 release) Ngspice F.A.Q.Version 2.9 (ngspice-40 release)
Maintained by Holger Vogt Maintained by Holger Vogt
Last update: Jan 24 2023 Last update: Mar 24 2023
This document contains the Frequently Asked Questions (and Answers) This document contains the Frequently Asked Questions (and Answers)
for ngspice project. for ngspice project.
@ -252,7 +252,7 @@
The latest version released is: The latest version released is:
* ngspice-39 (released on Jan 31 2023) * ngspice-40 (released on Mar 26 2023)
2.2. What are the latest features in the current release? 2.2. What are the latest features in the current release?

20
INSTALL
View File

@ -1,7 +1,7 @@
Ngspice installation instructions Ngspice installation instructions
================================= =================================
Important notice: since ngspice-35 there has been an update Important notice: since ngspice-39 there has been an update
to the XSPICE code models (analog.cm etc.). Therefore it to the XSPICE code models (analog.cm etc.). Therefore it
is not sufficient to only re-make the main executable, is not sufficient to only re-make the main executable,
you will have to compile and install the code models as well, you will have to compile and install the code models as well,
@ -28,7 +28,7 @@ Table of contents
8 Operation Controls 8 Operation Controls
9 NGSPICE COMPILATION UNDER WINDOWS OS 9 NGSPICE COMPILATION UNDER WINDOWS OS
9.1 How to make ngspice with MINGW and MSYS 9.1 How to make ngspice with MINGW and MSYS
9.2 make ngspice with MS Visual Studio 2019 or 2022 9.2 make ngspice with MS Visual Studio 2022
9.3 make ngspice with pure CYGWIN 9.3 make ngspice with pure CYGWIN
9.4 ngspice console app with MINGW or CYGWIN 9.4 ngspice console app with MINGW or CYGWIN
9.5 cross compiling ngspice for Windows from LINUX 9.5 cross compiling ngspice for Windows from LINUX
@ -580,9 +580,9 @@ This file describes the procedures to install ngspice from sources.
script compile_min_shared.sh. script compile_min_shared.sh.
9.2 make ngspice with MS Visual Studio 2019 and 2022 9.2 make ngspice with MS Visual Studio 2022
ngspice may be compiled with MS Visual Studio 2019 or newer. ngspice may be compiled with MS Visual Studio 2022 or newer.
CIDER and XSPICE are included, the code models for XSPICE CIDER and XSPICE are included, the code models for XSPICE
(*.cm) are made as well. (*.cm) are made as well.
@ -594,13 +594,13 @@ This file describes the procedures to install ngspice from sources.
The directory (visualc) with its files The directory (visualc) with its files
vngspice.sln (project starter) and vngspice.sln (project starter) and
vngspice.vcproj (project contents) vngspice.vcproj (project contents)
allows to compile and link ngspice with MS Visual Studio 2019. allows to compile and link ngspice with MS Visual Studio 2022.
/visualc/include contains a dedicated config.h file. It contains the /visualc/include contains a dedicated config.h file. It contains the
preprocessor definitions required to properly compile the code. preprocessor definitions required to properly compile the code.
strings.h has been necessary during setting up the project. strings.h has been necessary during setting up the project.
Install Microsoft Visual Studio 2019 Community with C/C++. For Install Microsoft Visual Studio 2022 Community with C/C++. For
example, the German edition is available at no cost from example, the German edition is available at no cost from
https://www.visualstudio.com/de/vs/community/. https://www.visualstudio.com/de/vs/community/.
@ -612,7 +612,7 @@ This file describes the procedures to install ngspice from sources.
Goto /ngspice/visualc. Goto /ngspice/visualc.
Start MS Visual Studio 2019 by double click onto vngspice.sln. Start MS Visual Studio 2022 by double click onto vngspice.sln.
After MS Visual Studio has opened up, select debug or release version After MS Visual Studio has opened up, select debug or release version
by checking 'Build' , 'Configuration Manager', 'Debug' or 'ReleaseOmp'. by checking 'Build' , 'Configuration Manager', 'Debug' or 'ReleaseOmp'.
@ -722,11 +722,9 @@ cross-compile-shared.sh.
sudo port install automake autoconf libtool bison flex ncurses xorg-libXaw sudo port install automake autoconf libtool bison flex ncurses xorg-libXaw
readline fontconfig freetype libomp SM ICE readline fontconfig freetype libomp SM ICE
4. Execute this command: 4. Execute this command:
./autogen.sh or ./autogen.sh --adms (if you want to enable ADMS) ./autogen.sh
5. Configure NGSPICE invoking "./configure". A complete set of feature is: 5. Configure NGSPICE invoking "./configure". A complete set of feature is:
./configure --enable-cider --enable-xspice --enable-openmp --enable-pss --with-readline=yes --enable-debug=no ./configure --enable-cider --enable-xspice --enable-openmp --enable-pss --with-readline=yes --enable-debug=no
or (if you want to enable ADMS)
./configure --enable-adms --enable-cider --enable-xspice --enable-openmp --enable-pss --with-readline=yes --enable-debug=no
6. Compile NGSPICE invoking "make -j4" 6. Compile NGSPICE invoking "make -j4"
7. Install NGSPICE invoking "make install" or "sudo make install" 7. Install NGSPICE invoking "make install" or "sudo make install"
@ -749,7 +747,7 @@ Resulting dependencies of ngspice
/usr/lib/libSystem.B.dylib /usr/lib/libSystem.B.dylib
/usr/local/lib/gcc/11/libgcc_s.1.dylib /usr/local/lib/gcc/11/libgcc_s.1.dylib
10.5 About compilers 10.4 About compilers
A compile script compile_macos_clang.sh contains all necessary steps for compiling A compile script compile_macos_clang.sh contains all necessary steps for compiling
with the Xcode clang/llvm compiler. This compiler however does not support -fopenmp. with the Xcode clang/llvm compiler. This compiler however does not support -fopenmp.
Therefore you may download and install gcc, e.g. from Homebrew and run the new Therefore you may download and install gcc, e.g. from Homebrew and run the new

View File

@ -4,10 +4,10 @@ SUBDIRS = src man tests
DIST_SUBDIRS = src man tests DIST_SUBDIRS = src man tests
EXTRA_DIST = FAQ autogen.sh Stuarts_Poly_Notes \ EXTRA_DIST = FAQ autogen.sh Stuarts_Poly_Notes \
ANALYSES BUGS AUTHORS ChangeLog \ ANALYSES BUGS AUTHORS INSTALL \
DEVICES NEWS README README.tcl \ DEVICES INTERNALS NEWS README README.tcl README.optran\
README.shared-xspice README.vdmos \ README.shared-xspice README.vdmos README_OSDI.md\
README.adms README.utf8 \ README_OSDI_howto README.cpl-gc README.utf8 \
examples m4 visualc \ examples m4 visualc \
cross-compile.sh cross-compile-shared.sh \ cross-compile.sh cross-compile-shared.sh \
compile_min.sh compile_linux.sh compile_min_shared.sh \ compile_min.sh compile_linux.sh compile_min_shared.sh \

19
NEWS
View File

@ -1,3 +1,22 @@
Ngspice-40, Mar 31st, 2023
============
- New features:
+ VBIC: Add optional parameters for determining the operation region
+ VBIC: Add bvbe, bvbc, bvce, bvsub as SOA parameters
+ Add inertial delay to all basic digital code models, make it available
for U devices
+ VDMOS default parameters are now similar to IRF540 IRF9540
+ Add function atanh to .control section
+ Add a scale factor 'a' (atto, 1e-18)
- Bug fixes:
+ ngspice-40 is mostly a bug-fix release. In conjunction with KiCad and
shared ngspice, inappropriate user inputs have led to crashing ngspice.
+ bugs no. 331, 619, 620, 624 have been fixed
+ 9 crash bugs (double delete, access NULL pointer etc) removed which have
occurred mostly due to incomplete or faulty inputs.
+ Memory leaks removed
Ngspice-39, Jan 31st, 2023 Ngspice-39, Jan 31st, 2023
============ ============
- New features: - New features:

View File

@ -24,10 +24,4 @@ To compile NGSPICE with OSDI support ensure that the `--enable-predictor` and `-
The `compile_linux.sh` file enables these flags by default. The `compile_linux.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

@ -16,7 +16,7 @@
# problem to the user. # problem to the user.
AC_PREREQ([2.59]) AC_PREREQ([2.59])
m4_define([ngspice_major_version], [39+]) m4_define([ngspice_major_version], [40+])
m4_define([ngspice_minor_version], [0]) m4_define([ngspice_minor_version], [0])
m4_define([ngspice_version], m4_define([ngspice_version],
[ngspice_major_version]) [ngspice_major_version])
@ -117,7 +117,7 @@ LT_INIT([shared static])
# --> Set 'LT_NGSPICE_AGE' to 0. # --> Set 'LT_NGSPICE_AGE' to 0.
LT_NGSPICE_CURRENT=0 LT_NGSPICE_CURRENT=0
LT_NGSPICE_REVISION=6 LT_NGSPICE_REVISION=7
LT_NGSPICE_AGE=1 LT_NGSPICE_AGE=1
LIBNGSPICE_SO_VERSION=$LT_NGSPICE_CURRENT.$LT_NGSPICE_REVISION.$LT_NGSPICE_AGE LIBNGSPICE_SO_VERSION=$LT_NGSPICE_CURRENT.$LT_NGSPICE_REVISION.$LT_NGSPICE_AGE

View File

@ -0,0 +1,43 @@
ADDER - 4 BIT ALL-74HC00-GATE BINARY ADDER WITH AUTOMATIC BRIDGING
* behavioral gate description
* Automatic A/D insertion using bi-directional bridges
* The NAND gates in the adder have a "family" parameter that determines
* the A/D and D/A bridges that are inserted. For A/D a subcircuit is
* used, defined by the file bridge_demo_family_d_in.subcir. For D/A
* the following interpreter variable sets up the bridges with non-default
* output levels.
.control
pre_set auto_bridge_demo_family_d_out =
+ ( ".model auto_da dac_bridge(out_high='%g-0.7' out_low=0.9 )"
+ "auto_bridge%d [ %s ] [ %s ] auto_da" 1000 )
.endc
.param vcc=5 tripdt=6n
*
* 2-input NAND gate
* vcc 2 /4.5/5 /6
* tpd 25n/9n/7n/7n
* tr 19n/7n / /6n
*** Subcircuit definition: copy of 74HCng_auto.lib with "family" parameter
.SUBCKT 74HC00 in1 in2 out NVCC NVGND vcc1={vcc} tripdt1={tripdt}
.param td1={1e-9*(9-3-3)*4.0/(vcc1-0.5)}
.param Rout={60*4.0/(vcc1-0.5)} ; standard output driver
a6 [in1 in2] dout nand1
.model nand1 d_nand(rise_delay = {td1} fall_delay = {td1}
+ input_load = 0.5e-12) family="demo_family"
Rout dout out {Rout}
.ends
.param vcc=3 tripdt=6n
.include ../adder_common.inc
.END

View File

@ -0,0 +1,11 @@
* Subcircuit for analogue to digital converter
.subckt bridge_demo_family_d_in in out vcc=3.3
* For no good reason the voltage is reduced before A/D converion
r1 in in2 1k
r2 in2 0 1k
adc [ in2 ] [ out ] lv_adc
.model lv_adc adc_bridge in_low={vcc/4} in_high={vcc/4}
.ends

View File

@ -0,0 +1,23 @@
Level shift by auto-bridges with different VCCs.
* A level shifter made by placing digital buffers in subcircuits.
.param vcc=5 ; Circuit-wide default for auto-bridge levels (not used)
.subckt buffer in out vcc=3 ; These subcircuits default to 3V.
abuf in out buf
.ends
.model buf d_buffer
vin in 0 sin(1.5 1.5 100k)
xb1 in mid buffer ; ADC bridge with VCC=3V will be used.
xb2 mid out buffer vcc=6 ; DAC bridge with 6V swing will be used,
rload out 0 10k ; Analog node forces bridge insertion,
.control
tran 100n 30u
plot in out
.endc
.end

View File

@ -250,7 +250,7 @@ inp_list(FILE *file, struct card *deck, struct card *extras, int type)
Xprintf(file, "%s\n", here->error); Xprintf(file, "%s\n", here->error);
} }
else if ((*here->line != '*') && (type == LS_RUNNABLE)) { else if ((*here->line != '*') && (type == LS_RUNNABLE)) {
Xprintf(file, "%s\n", upper(here->line)); Xprintf(file, "%s\n", here->line);
if (here->error) if (here->error)
Xprintf(file, "%s\n", here->error); Xprintf(file, "%s\n", here->error);
} }
@ -279,7 +279,7 @@ inp_list(FILE *file, struct card *deck, struct card *extras, int type)
continue; continue;
if (type == LS_PHYSICAL) if (type == LS_PHYSICAL)
Xprintf(file, "%6d : %s\n", Xprintf(file, "%6d : %s\n",
here->linenum, upper(here->line)); here->linenum, upper(here->line));
else else
Xprintf(file, "%s\n", upper(here->line)); Xprintf(file, "%s\n", upper(here->line));
if (here->error && (type == LS_PHYSICAL)) if (here->error && (type == LS_PHYSICAL))
@ -291,7 +291,7 @@ inp_list(FILE *file, struct card *deck, struct card *extras, int type)
continue; continue;
if (type == LS_PHYSICAL) if (type == LS_PHYSICAL)
Xprintf(file, "%6d : %s\n", Xprintf(file, "%6d : %s\n",
there->linenum, upper(there->line)); there->linenum, upper(there->line));
else else
Xprintf(file, "%s\n", upper(there->line)); Xprintf(file, "%s\n", upper(there->line));
if (there->error && (type == LS_PHYSICAL)) if (there->error && (type == LS_PHYSICAL))

View File

@ -169,7 +169,6 @@ static void inp_check_syntax(struct card *deck);
static char *inp_spawn_brace(char *s); static char *inp_spawn_brace(char *s);
static char *inp_pathresolve(const char *name);
static char *inp_pathresolve_at(const char *name, const char *dir); static char *inp_pathresolve_at(const char *name, const char *dir);
char *search_plain_identifier(char *str, const char *identifier); char *search_plain_identifier(char *str, const char *identifier);
@ -1756,7 +1755,7 @@ FILE *inp_pathopen(const char *name, const char *mode)
if the file isn't in . and it isn't an abs path name. if the file isn't in . and it isn't an abs path name.
*-------------------------------------------------------------------------*/ *-------------------------------------------------------------------------*/
static char *inp_pathresolve(const char *name) char *inp_pathresolve(const char *name)
{ {
struct variable *v; struct variable *v;
struct stat st; struct stat st;
@ -9822,6 +9821,19 @@ static void inp_check_syntax(struct card *deck)
controlled_exit(EXIT_BAD); controlled_exit(EXIT_BAD);
} }
/* When '.probe alli' is set, disable auto bridging and set a flag */
for (card = deck; card; card = card->nextcard) {
char* cut_line = card->line;
if (ciprefix(".probe", cut_line) && search_plain_identifier(cut_line, "alli")) {
int i = 0;
bool bi = TRUE;
cp_vset("auto_bridge", CP_NUM, &i);
cp_vset("probe_alli_given", CP_BOOL, &bi);
break;
}
}
for (ii = 0; ii < 10; ii++) for (ii = 0; ii < 10; ii++)
subs[ii] = NULL; subs[ii] = NULL;

View File

@ -8,5 +8,5 @@
struct card *insert_new_line(struct card *card, char *line, struct card *insert_new_line(struct card *card, char *line,
int linenum, int linenum_orig); int linenum, int linenum_orig);
char *inp_pathresolve(const char *name);
#endif #endif

View File

@ -55,6 +55,7 @@ noinst_HEADERS = \
hlpdefs.h \ hlpdefs.h \
iferrmsg.h \ iferrmsg.h \
ifsim.h \ ifsim.h \
inertial.h \
inpdefs.h \ inpdefs.h \
inpmacs.h \ inpmacs.h \
inpptree.h \ inpptree.h \

View File

@ -97,7 +97,7 @@ are of type bool if sharedspice.h is used externally.
*/ */
#ifndef NGSPICE_PACKAGE_VERSION #ifndef NGSPICE_PACKAGE_VERSION
#define NGSPICE_PACKAGE_VERSION "39+" #define NGSPICE_PACKAGE_VERSION "40"
#endif #endif
/* we have NG_BOOL instead of BOOL */ /* we have NG_BOOL instead of BOOL */
#ifndef HAS_NG_BOOL #ifndef HAS_NG_BOOL

View File

@ -184,7 +184,13 @@ IFparm VBICmPTable[] = { /* model parameters */
IOP("vbc_max", VBIC_MOD_VBC_MAX, IF_REAL, "maximum voltage B-C junction"), IOP("vbc_max", VBIC_MOD_VBC_MAX, IF_REAL, "maximum voltage B-C junction"),
IOPR("bvbc", VBIC_MOD_VBC_MAX, IF_REAL, "maximum voltage B-C junction"), IOPR("bvbc", VBIC_MOD_VBC_MAX, IF_REAL, "maximum voltage B-C junction"),
IOP("vce_max", VBIC_MOD_VCE_MAX, IF_REAL, "maximum voltage C-E branch"), IOP("vce_max", VBIC_MOD_VCE_MAX, IF_REAL, "maximum voltage C-E branch"),
IOPR("bvce", VBIC_MOD_VCE_MAX, IF_REAL, "maximum voltage C-E branch") IOPR("bvce", VBIC_MOD_VCE_MAX, IF_REAL, "maximum voltage C-E branch"),
IOP("vsub_max", VBIC_MOD_VSUB_MAX, IF_REAL, "maximum voltage C-substrate branch"),
IOPR("bvsub", VBIC_MOD_VSUB_MAX, IF_REAL, "maximum voltage C-substrate branch"),
IOP("vbefwd", VBIC_MOD_VBEFWD_MAX, IF_REAL, "maximum forward voltage B-E junction"),
IOP("vbcfwd", VBIC_MOD_VBCFWD_MAX, IF_REAL, "maximum forward voltage B-C junction"),
IOP("vsubfwd", VBIC_MOD_VSUBFWD_MAX, IF_REAL, "maximum forward voltage C-substrate junction"),
IOP("selft", VBIC_MOD_SELFT, IF_INTEGER, "0: self-heating off, 1: self-heating on")
}; };
char *VBICnames[] = { char *VBICnames[] = {

View File

@ -457,6 +457,7 @@ typedef struct sVBICmodel { /* model structure for a vbic */
double VBICtempExpAVC; double VBICtempExpAVC;
double VBICthermalResist; double VBICthermalResist;
double VBICthermalCapacitance; double VBICthermalCapacitance;
int VBICselft;
double VBICpunchThroughVoltageBC; double VBICpunchThroughVoltageBC;
double VBICdeplCapCoeff1; double VBICdeplCapCoeff1;
double VBICfixedCapacitanceCS; double VBICfixedCapacitanceCS;
@ -484,6 +485,10 @@ typedef struct sVBICmodel { /* model structure for a vbic */
double VBICvbeMax; /* maximum voltage over B-E junction */ double VBICvbeMax; /* maximum voltage over B-E junction */
double VBICvbcMax; /* maximum voltage over B-C junction */ double VBICvbcMax; /* maximum voltage over B-C junction */
double VBICvceMax; /* maximum voltage over C-E branch */ double VBICvceMax; /* maximum voltage over C-E branch */
double VBICvsubMax; /* maximum voltage over C-substrate branch */
double VBICvbcfwdMax; /* maximum forward voltage over B-C junction */
double VBICvbefwdMax; /* maximum forward voltage over C-E branch */
double VBICvsubfwdMax; /* maximum forward voltage over C-substrate branch */
unsigned VBICtnomGiven : 1; unsigned VBICtnomGiven : 1;
unsigned VBICextCollResistGiven : 1; unsigned VBICextCollResistGiven : 1;
@ -571,6 +576,7 @@ typedef struct sVBICmodel { /* model structure for a vbic */
unsigned VBICtempExpNFGiven : 1; unsigned VBICtempExpNFGiven : 1;
unsigned VBICtempExpAVCGiven : 1; unsigned VBICtempExpAVCGiven : 1;
unsigned VBICthermalResistGiven : 1; unsigned VBICthermalResistGiven : 1;
unsigned VBICselftGiven : 1;
unsigned VBICthermalCapacitanceGiven : 1; unsigned VBICthermalCapacitanceGiven : 1;
unsigned VBICpunchThroughVoltageBCGiven : 1; unsigned VBICpunchThroughVoltageBCGiven : 1;
unsigned VBICdeplCapCoeff1Given : 1; unsigned VBICdeplCapCoeff1Given : 1;
@ -598,6 +604,10 @@ typedef struct sVBICmodel { /* model structure for a vbic */
unsigned VBICvbeMaxGiven : 1; unsigned VBICvbeMaxGiven : 1;
unsigned VBICvbcMaxGiven : 1; unsigned VBICvbcMaxGiven : 1;
unsigned VBICvceMaxGiven : 1; unsigned VBICvceMaxGiven : 1;
unsigned VBICvsubMaxGiven : 1;
unsigned VBICvbcfwdMaxGiven : 1;
unsigned VBICvbefwdMaxGiven : 1;
unsigned VBICvsubfwdMaxGiven : 1;
} VBICmodel; } VBICmodel;
#ifndef NPN #ifndef NPN
@ -734,6 +744,11 @@ enum {
VBIC_MOD_VBE_MAX, VBIC_MOD_VBE_MAX,
VBIC_MOD_VBC_MAX, VBIC_MOD_VBC_MAX,
VBIC_MOD_VCE_MAX, VBIC_MOD_VCE_MAX,
VBIC_MOD_VSUB_MAX,
VBIC_MOD_VBEFWD_MAX,
VBIC_MOD_VBCFWD_MAX,
VBIC_MOD_VSUBFWD_MAX,
VBIC_MOD_SELFT,
}; };
/* device questions */ /* device questions */

View File

@ -363,12 +363,27 @@ VBICmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
case VBIC_MOD_VCE_MAX: case VBIC_MOD_VCE_MAX:
value->rValue = here->VBICvceMax; value->rValue = here->VBICvceMax;
return(OK); return(OK);
case VBIC_MOD_VSUB_MAX:
value->rValue = here->VBICvsubMax;
return(OK);
case VBIC_MOD_VBEFWD_MAX:
value->rValue = here->VBICvbefwdMax;
return(OK);
case VBIC_MOD_VBCFWD_MAX:
value->rValue = here->VBICvbcfwdMax;
return(OK);
case VBIC_MOD_VSUBFWD_MAX:
value->rValue = here->VBICvsubfwdMax;
return(OK);
case VBIC_MOD_TYPE: case VBIC_MOD_TYPE:
if (here->VBICtype == NPN) if (here->VBICtype == NPN)
value->sValue = "npn"; value->sValue = "npn";
else else
value->sValue = "pnp"; value->sValue = "pnp";
return(OK); return(OK);
case VBIC_MOD_SELFT:
value->iValue = here->VBICselft;
return(OK);
default: default:
return(E_BADPARM); return(E_BADPARM);
} }

View File

@ -509,6 +509,26 @@ VBICmParam(int param, IFvalue *value, GENmodel *inModel)
mods->VBICvceMax = value->rValue; mods->VBICvceMax = value->rValue;
mods->VBICvceMaxGiven = TRUE; mods->VBICvceMaxGiven = TRUE;
break; break;
case VBIC_MOD_VSUB_MAX:
mods->VBICvsubMax = value->rValue;
mods->VBICvsubMaxGiven = TRUE;
break;
case VBIC_MOD_VBEFWD_MAX:
mods->VBICvbefwdMax = value->rValue;
mods->VBICvbefwdMaxGiven = TRUE;
break;
case VBIC_MOD_VBCFWD_MAX:
mods->VBICvbcfwdMax = value->rValue;
mods->VBICvbcfwdMaxGiven = TRUE;
break;
case VBIC_MOD_VSUBFWD_MAX:
mods->VBICvsubfwdMax = value->rValue;
mods->VBICvsubfwdMaxGiven = TRUE;
break;
case VBIC_MOD_SELFT:
mods->VBICselft = value->iValue;
mods->VBICselftGiven = TRUE;
break;
default: default:
return(E_BADPARM); return(E_BADPARM);
} }

View File

@ -391,6 +391,21 @@ VBICsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
if(!model->VBICvceMaxGiven) { if(!model->VBICvceMaxGiven) {
model->VBICvceMax = 1e99; model->VBICvceMax = 1e99;
} }
if(!model->VBICvsubMaxGiven) {
model->VBICvsubMax = 1e99;
}
if (!model->VBICvbefwdMaxGiven) {
model->VBICvbefwdMax = 0.2;
}
if (!model->VBICvbcfwdMaxGiven) {
model->VBICvbcfwdMax = 0.2;
}
if (!model->VBICvsubfwdMaxGiven) {
model->VBICvsubfwdMax = 0.2;
}
if(!model->VBICselftGiven) {
model->VBICselft = 0;
}
/* loop through all the instances of the model */ /* loop through all the instances of the model */
for (here = VBICinstances(model); here != NULL ; for (here = VBICinstances(model); here != NULL ;
@ -472,7 +487,8 @@ VBICsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
} }
} }
if((model->VBICthermalResistGiven) && (model->VBICthermalResist > 0.0)) if((model->VBICthermalResistGiven) && (model->VBICthermalResist > 0.0)
&& model->VBICselftGiven && model->VBICselft == 1)
here->VBIC_selfheat = 1; here->VBIC_selfheat = 1;
else else
here->VBIC_selfheat = 0; here->VBIC_selfheat = 0;

View File

@ -17,14 +17,16 @@ VBICsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
{ {
VBICmodel *model = (VBICmodel *) inModel; VBICmodel *model = (VBICmodel *) inModel;
VBICinstance *here; VBICinstance *here;
double vbe, vbc, vce; /* actual bjt voltages */ double vbe, vbc, vce, vsub; /* actual bjt voltages */
int maxwarns; int maxwarns;
static int warns_vbe = 0, warns_vbc = 0, warns_vce = 0; static int warns_vbe = 0, warns_vbc = 0, warns_vce = 0, warns_vsub = 0, warns_op = 0;
if (!ckt) { if (!ckt) {
warns_vbe = 0; warns_vbe = 0;
warns_vbc = 0; warns_vbc = 0;
warns_vce = 0; warns_vce = 0;
warns_vsub = 0;
warns_op = 0;
return OK; return OK;
} }
@ -32,39 +34,95 @@ VBICsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
for (; model; model = VBICnextModel(model)) { for (; model; model = VBICnextModel(model)) {
for (here = VBICinstances(model); here; here=VBICnextInstance(here)) { for (here = VBICinstances(model); here; here = VBICnextInstance(here)) {
vbe = fabs(ckt->CKTrhsOld [here->VBICbaseNode] - vbe = fabs(ckt->CKTrhsOld[here->VBICbaseNode] -
ckt->CKTrhsOld [here->VBICemitNode]); ckt->CKTrhsOld[here->VBICemitNode]);
vbc = fabs(ckt->CKTrhsOld [here->VBICbaseNode] - vbc = fabs(ckt->CKTrhsOld[here->VBICbaseNode] -
ckt->CKTrhsOld [here->VBICcollNode]); ckt->CKTrhsOld[here->VBICcollNode]);
vce = fabs(ckt->CKTrhsOld [here->VBICcollNode] - vce = fabs(ckt->CKTrhsOld[here->VBICcollNode] -
ckt->CKTrhsOld [here->VBICemitNode]); ckt->CKTrhsOld[here->VBICemitNode]);
vsub = fabs(ckt->CKTrhsOld[here->VBICcollNode] -
ckt->CKTrhsOld[here->VBICsubsNode]);
if (vbe > model->VBICvbeMax) if (vbe > model->VBICvbeMax)
if (warns_vbe < maxwarns) { if (warns_vbe < maxwarns) {
soa_printf(ckt, (GENinstance*) here, soa_printf(ckt, (GENinstance*)here,
"|Vbe|=%g has exceeded Vbe_max=%g\n", "|Vbe|=%g has exceeded Vbe_max=%g\n",
vbe, model->VBICvbeMax); vbe, model->VBICvbeMax);
warns_vbe++; warns_vbe++;
} }
if (vbc > model->VBICvbcMax) if (vbc > model->VBICvbcMax)
if (warns_vbc < maxwarns) { if (warns_vbc < maxwarns) {
soa_printf(ckt, (GENinstance*) here, soa_printf(ckt, (GENinstance*)here,
"|Vbc|=%g has exceeded Vbc_max=%g\n", "|Vbc|=%g has exceeded Vbc_max=%g\n",
vbc, model->VBICvbcMax); vbc, model->VBICvbcMax);
warns_vbc++; warns_vbc++;
} }
if (vce > model->VBICvceMax) if (vce > model->VBICvceMax)
if (warns_vce < maxwarns) { if (warns_vce < maxwarns) {
soa_printf(ckt, (GENinstance*) here, soa_printf(ckt, (GENinstance*)here,
"|Vce|=%g has exceeded Vce_max=%g\n", "|Vce|=%g has exceeded Vce_max=%g\n",
vce, model->VBICvceMax); vce, model->VBICvceMax);
warns_vce++; warns_vce++;
} }
if (vsub > model->VBICvsubMax)
if (warns_vsub < maxwarns) {
soa_printf(ckt, (GENinstance*)here,
"|Vce|=%g has exceeded Vce_max=%g\n",
vsub, model->VBICvsubMax);
warns_vsub++;
}
/* substrate diode is forward biased */
if (model->VBICtype * (ckt->CKTrhsOld[here->VBICsubsNode] -
ckt->CKTrhsOld[here->VBICcollNode]) > model->VBICvsubfwdMax) {
/* substrate leakage */
if (warns_vsub < maxwarns) {
soa_printf(ckt, (GENinstance*)here,
"substrate juntion is forward biased\n");
warns_vsub++;
}
}
/* operating point information */
if (ckt->CKTsoaCheck == 2) {
if (vbe <= model->VBICvbefwdMax && vbc <= model->VBICvbefwdMax) {
/*off*/
if (warns_op < maxwarns) {
soa_printf(ckt, (GENinstance*)here,
"device is off\n");
warns_op++;
}
}
else if (vbe > model->VBICvbefwdMax && vbc > model->VBICvbefwdMax) {
/*saturation*/
if (warns_op < maxwarns) {
soa_printf(ckt, (GENinstance*)here,
"device is in saturation\n");
warns_op++;
}
}
else if (vbe > model->VBICvbefwdMax && vbc <= model->VBICvbefwdMax) {
/*forward*/
if (warns_op < maxwarns) {
soa_printf(ckt, (GENinstance*)here,
"device is forward biased\n");
warns_op++;
}
}
else if (vbe <= model->VBICvbefwdMax && vbc > model->VBICvbefwdMax) {
/*reverse*/
if (warns_op < maxwarns) {
soa_printf(ckt, (GENinstance*)here,
"device is reverse biased\n");
warns_op++;
}
}
}
} }
} }

View File

@ -32,7 +32,7 @@
When using XSPICE to simulate digital devices in a mixed-mode simulation, When using XSPICE to simulate digital devices in a mixed-mode simulation,
bridging devices must be included in the circuit to pass signals between the bridging devices must be included in the circuit to pass signals between the
analogue simulator and XSPICE. Such devices may be included in the netlist, analogue simulator and XSPICE. Such devices may be included in the netlist,
or they may can be inserted automatically. Different types of automatic or they can be inserted automatically. Different types of automatic
bridge may exist in the same circuit, depending on signal direction and bridge may exist in the same circuit, depending on signal direction and
characteristics of the connected device, for example digital devices characteristics of the connected device, for example digital devices
powered by differing voltages. Non-digital XSPICE nodes are supported. powered by differing voltages. Non-digital XSPICE nodes are supported.
@ -95,21 +95,26 @@ for device libraries whose devices are defined by subcircuits.
the enclosing subcircuits for a definition of the parameter. the enclosing subcircuits for a definition of the parameter.
If found, set vcc from the parameter. If found, set vcc from the parameter.
3: If a command interpreter variable "no_auto_bridge_family": exists, go to 3: If a command interpreter variable "no_auto_bridge_family": exists,
step 5. Search the connected device instances for a parameter, go to step 5. Search the connected XSPICE device instances for a
"family" with a string value. The first one found will be used. parameter, "family" with a string value. The first one found will
If the first character of the value is not '*', the setup card will be used. If no such instance exists, search for a string-valued
be ".include bridge_FFFFF_DDD.cir" where FFFFF is the family and parameter, "family", in enclosing subcircuits, as in step 2. If
DDD is the signal direction for the XSPICE device: "in", "out" or the first character of the value is not '*', the setup card may be
"inout". The device card will be "Xauto_bridge%d %s %s ".include bridge_FFFFF_TTTT_DDD.subcir" where FFFFF is the family,
bridge_FFFFF_DDD vcc=%g", so a suitably parameterised subcircuit TTTT is as before and DDD is the signal direction for the XSPICE
must be defined in the included file. device: "in", "out" or "inout". This form will be used only when
the required file can be found. In that case, the device card will
be "Xauto_bridge%d %s %s bridge_FFFFF_TTTT_DDD vcc=%g", so a
suitably parameterised subcircuit must be defined in the included
file.
4: If the first character of "family" was '*', look for a variable 4: If the first character of "family" was '*', or no file was found,
"auto_bridge_FFFFF_TTTT_DDD" where FFFFF is the family without '*', look for a variable "auto_bridge_FFFFF_TTTT_DDD" where FFFFF is the
TTTT is the node type string and DDD is the direction. So this might be family without '*', TTTT is the node type string and DDD is the
"auto_bridge_74HCT_d_inout" for a digital node. Use the variable's value direction. So this might be "auto_bridge_74HCT_d_inout" for a
as in step 6, proceeding to step 5 if checks fail. digital node. Use the variable's value as in step 6, proceeding to
step 5 if checks fail.
5: Look for a variable "auto_bridge_TTTT_DDD" where TTTT and DDD are as before. 5: Look for a variable "auto_bridge_TTTT_DDD" where TTTT and DDD are as before.
@ -160,9 +165,9 @@ for device libraries whose devices are defined by subcircuits.
and invoked by: and invoked by:
set auto_bridge_d_out_30 = ( ".include test_sub.cir" set auto_bridge_d_out = ( ".include test_sub.subcir"
+ "xauto_buf%d %s %s auto_buf vcc=%g" + "xauto_buf%d %s %s auto_buf vcc=%g"
+ 1 ) + 1 )
*/ */
/* Working information about a type of bridge. */ /* Working information about a type of bridge. */
@ -195,10 +200,15 @@ static struct card *expand_deck(struct card *head)
struct card *card, *next; struct card *card, *next;
char **pointers; char **pointers;
int i, dico; int i, dico;
bool save_debug;
/* Save the current parameter symbol table. */ /* Save the current parameter symbol table and debug global.
* Prevent overwriting of debug output in inp_readall().
*/
dico = nupa_add_dicoslist(); dico = nupa_add_dicoslist();
save_debug = ft_ngdebug;
ft_ngdebug = FALSE;
/* Count the cards, allocate and fill a pointer array. */ /* Count the cards, allocate and fill a pointer array. */
@ -221,6 +231,7 @@ static struct card *expand_deck(struct card *head)
circarray = pointers; circarray = pointers;
card = inp_readall(NULL, Infile_Path, FALSE, TRUE, NULL); card = inp_readall(NULL, Infile_Path, FALSE, TRUE, NULL);
card = inp_subcktexpand(card); card = inp_subcktexpand(card);
ft_ngdebug = save_debug;
/* Destroy the parameter table that was created in subcircuit/parameter /* Destroy the parameter table that was created in subcircuit/parameter
* expansion and restore the previous version. * expansion and restore the previous version.
@ -479,8 +490,8 @@ static struct bridge *find_bridge(Evt_Node_Info_t *event_node,
family = NULL; family = NULL;
deep = scan_devices(event_node, ckt, &family); deep = scan_devices(event_node, ckt, &family);
/* Look for a real parameter (.param type) in the device's subcircuit /* Look for a real parameter (.param type) and perhaps a string-valued
* and those enclosing it. * "family" parameter in the device's subcircuit and those enclosing it.
*/ */
snprintf(buff, sizeof buff, "%s", deep); snprintf(buff, sizeof buff, "%s", deep);
@ -490,7 +501,11 @@ static struct bridge *find_bridge(Evt_Node_Info_t *event_node,
snprintf(dot + 1, sizeof buff - (size_t)(dot - buff), "%s", vcc_parm); snprintf(dot + 1, sizeof buff - (size_t)(dot - buff), "%s", vcc_parm);
vcc = nupa_get_param(buff, &ok); vcc = nupa_get_param(buff, &ok);
} }
if (ok) if (!family) {
snprintf(dot + 1, sizeof buff - (size_t)(dot - buff), "family");
family = nupa_get_string_param(buff);
}
if (ok && family)
break; break;
*dot = '\0'; *dot = '\0';
dot = strrchr(buff, '.'); dot = strrchr(buff, '.');
@ -506,12 +521,29 @@ static struct bridge *find_bridge(Evt_Node_Info_t *event_node,
} }
} }
if (!family)
family = nupa_get_string_param("family");
if (family && cp_getvar("no_auto_bridge_family", CP_BOOL, NULL, 0)) if (family && cp_getvar("no_auto_bridge_family", CP_BOOL, NULL, 0))
family = NULL; family = NULL;
if (family && *family == '*') { if (family) {
s_family = family + 1; if (*family == '*') {
family = NULL; // Not used for matching. s_family = family + 1; // Use variable look-up.
} else {
char *fam_inc_path;
/* Check if an include file exists for the family. */
snprintf(buff, sizeof buff, "bridge_%s_%s_%s.subcir",
family, type_name, dirs[direction]);
fam_inc_path = inp_pathresolve(buff);
if (fam_inc_path) {
tfree(fam_inc_path);
s_family = NULL;
} else {
s_family = family; // Use variable look-up.
}
}
} else { } else {
s_family = NULL; s_family = NULL;
} }
@ -523,10 +555,19 @@ static struct bridge *find_bridge(Evt_Node_Info_t *event_node,
bridge->direction == direction) { bridge->direction == direction) {
if (family) { if (family) {
if (!strcmp(family, bridge->family)) { if (!strcmp(family, bridge->family)) {
/* Return vcc for formatting: requires bridge->max == 1. */ if (!s_family && bridge->max == 1) {
/* Set bridge vcc for formatting. */
bridge->vcc = vcc; bridge->vcc = vcc;
break; break;
} else {
/* Using cards from variable, or shared sub-circuit:
* vcc must also match.
*/
if (bridge->vcc == vcc)
break;
}
} }
} else if (bridge->vcc == vcc) { // Match vcc. } else if (bridge->vcc == vcc) { // Match vcc.
break; break;
@ -538,23 +579,23 @@ static struct bridge *find_bridge(Evt_Node_Info_t *event_node,
/* Determine if a bridging element exists, starting with the node type. */ /* Determine if a bridging element exists, starting with the node type. */
if (family) { if (s_family) {
/* Use standard pattern for known parts family. */
snprintf(buff, sizeof buff, ".include bridge_%s_%s.cir",
family, dirs[direction]);
setup = copy(buff);
snprintf(buff, sizeof buff,
"Xauto_bridge%%d %%s %%s bridge_%s_%s vcc=%%g",
family, dirs[direction]);
format = copy(buff);
max = 1;
} else if (s_family) {
/* Family variable lookup. */ /* Family variable lookup. */
snprintf(buff, sizeof buff, "auto_bridge_%s_%s_%s", snprintf(buff, sizeof buff, "auto_bridge_%s_%s_%s",
s_family, type_name, dirs[direction]); s_family, type_name, dirs[direction]);
cp_getvar(buff, CP_LIST, &cvar, sizeof cvar); cp_getvar(buff, CP_LIST, &cvar, sizeof cvar);
} else if (family) {
/* Use standard pattern for known parts family. */
snprintf(buff, sizeof buff, ".include bridge_%s_%s_%s.subcir",
family, type_name, dirs[direction]);
setup = copy(buff);
snprintf(buff, sizeof buff,
"Xauto_bridge%%d %%s %%s bridge_%s_%s_%s vcc=%%g",
family, type_name, dirs[direction]);
format = copy(buff);
max = 1;
} }
if (!format && !cvar) { if (!format && !cvar) {
@ -667,8 +708,13 @@ bool Evtcheck_nodes(
int nl; int nl;
if (strcmp(event_node->name, analog_node->name) == 0) { if (strcmp(event_node->name, analog_node->name) == 0) {
if (show == AB_OFF) if (show == AB_OFF) {
if (cp_getvar("probe_alli_given", CP_BOOL, NULL, 0))
fprintf(stderr, "\nDot command '.probe alli' and digital nodes are not compatible.\n");
FREE(errMsg);
errMsg = copy("Auto bridging is switched off");
return FALSE; // Auto-bridge disabled return FALSE; // Auto-bridge disabled
}
bridge = find_bridge(event_node, ckt, &bridge_list); bridge = find_bridge(event_node, ckt, &bridge_list);
if (!bridge) { if (!bridge) {
/* Fatal, circuit cannot run. */ /* Fatal, circuit cannot run. */

View File

@ -303,6 +303,7 @@ void Evt_purge_free_outputs(void)
for (i = 0; i < g_evt_num_udn_types; ++i) { for (i = 0; i < g_evt_num_udn_types; ++i) {
output_event = g_evt_udn_info[i]->free_list; output_event = g_evt_udn_info[i]->free_list;
g_evt_udn_info[i]->free_list = NULL;
while (output_event) { while (output_event) {
next = output_event->next; next = output_event->next;
tfree(output_event->value); tfree(output_event->value);

View File

@ -43,6 +43,7 @@ NON-STANDARD FEATURES
#include "ngspice/mifproto.h" #include "ngspice/mifproto.h"
#include "ngspice/mifdefs.h" #include "ngspice/mifdefs.h"
#include "ngspice/evt.h"
#if defined(_MSC_VER) || defined(__MINGW32__) #if defined(_MSC_VER) || defined(__MINGW32__)
#include "ngspice/mifparse.h" #include "ngspice/mifparse.h"
@ -134,8 +135,16 @@ MIFdelete(GENinstance *gen_inst)
/* Free the basic port structure allocated in MIFget_port */ /* Free the basic port structure allocated in MIFget_port */
num_port = here->conn[i]->size; num_port = here->conn[i]->size;
for (j = 0; j < num_port; j++) { for (j = 0; j < num_port; j++) {
/* Memory allocated in mif_inp2.c */ Evt_Output_Event_t *evt;
/* Memory allocated in mif_inp2.c and evtload.c. */
FREE(here->conn[i]->port[j]->type_str); FREE(here->conn[i]->port[j]->type_str);
evt = here->conn[i]->port[j]->next_event;
if (evt) {
FREE(evt->value);
FREE(evt);
}
FREE(here->conn[i]->port[j]); FREE(here->conn[i]->port[j]);
} }
FREE(here->conn[i]->port); FREE(here->conn[i]->port);

View File

@ -15,7 +15,7 @@
#define PACKAGE "ngspice" #define PACKAGE "ngspice"
/* Version number of package */ /* Version number of package */
#define VERSION "39+" #define VERSION "40+"
/* Define the directory for executables */ /* Define the directory for executables */
#define NGSPICEBINDIR "../bin" #define NGSPICEBINDIR "../bin"