Merge branch 'pre-master' into bt_dev
This commit is contained in:
commit
2213edca55
9
DEVICES
9
DEVICES
|
|
@ -63,11 +63,6 @@ Table of contents
|
|||
12.4 BSIMSOI - SOI model (partially/full depleted devices)
|
||||
12.5 SOI3 - STAG SOI3 Model
|
||||
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
|
||||
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.8 r2_cmc
|
||||
|
||||
More may be made available, user compiled models are possible as well
|
||||
(See ngspice manual, chapter 13).
|
||||
More models are available at https://github.com/dwarning/VA-Models,
|
||||
user compiled models are possible as well (See ngspice manual, chapter 13).
|
||||
|
||||
|
||||
14. XSpice code models
|
||||
|
|
|
|||
6
FAQ
6
FAQ
|
|
@ -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
|
||||
Last update: Jan 24 2023
|
||||
Last update: Mar 24 2023
|
||||
|
||||
This document contains the Frequently Asked Questions (and Answers)
|
||||
for ngspice project.
|
||||
|
|
@ -252,7 +252,7 @@
|
|||
|
||||
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?
|
||||
|
|
|
|||
20
INSTALL
20
INSTALL
|
|
@ -1,7 +1,7 @@
|
|||
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
|
||||
is not sufficient to only re-make the main executable,
|
||||
you will have to compile and install the code models as well,
|
||||
|
|
@ -28,7 +28,7 @@ Table of contents
|
|||
8 Operation Controls
|
||||
9 NGSPICE COMPILATION UNDER WINDOWS OS
|
||||
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.4 ngspice console app with MINGW or CYGWIN
|
||||
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.
|
||||
|
||||
|
||||
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
|
||||
(*.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
|
||||
vngspice.sln (project starter) and
|
||||
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
|
||||
preprocessor definitions required to properly compile the code.
|
||||
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
|
||||
https://www.visualstudio.com/de/vs/community/.
|
||||
|
||||
|
|
@ -612,7 +612,7 @@ This file describes the procedures to install ngspice from sources.
|
|||
|
||||
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
|
||||
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
|
||||
readline fontconfig freetype libomp SM ICE
|
||||
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:
|
||||
./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"
|
||||
7. Install NGSPICE invoking "make install" or "sudo make install"
|
||||
|
||||
|
|
@ -749,7 +747,7 @@ Resulting dependencies of ngspice
|
|||
/usr/lib/libSystem.B.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
|
||||
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
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ SUBDIRS = src man tests
|
|||
DIST_SUBDIRS = src man tests
|
||||
|
||||
EXTRA_DIST = FAQ autogen.sh Stuarts_Poly_Notes \
|
||||
ANALYSES BUGS AUTHORS ChangeLog \
|
||||
DEVICES NEWS README README.tcl \
|
||||
README.shared-xspice README.vdmos \
|
||||
README.adms README.utf8 \
|
||||
ANALYSES BUGS AUTHORS INSTALL \
|
||||
DEVICES INTERNALS NEWS README README.tcl README.optran\
|
||||
README.shared-xspice README.vdmos README_OSDI.md\
|
||||
README_OSDI_howto README.cpl-gc README.utf8 \
|
||||
examples m4 visualc \
|
||||
cross-compile.sh cross-compile-shared.sh \
|
||||
compile_min.sh compile_linux.sh compile_min_shared.sh \
|
||||
|
|
|
|||
19
NEWS
19
NEWS
|
|
@ -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
|
||||
============
|
||||
- New features:
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
||||
## 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`.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
# problem to the user.
|
||||
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_version],
|
||||
[ngspice_major_version])
|
||||
|
|
@ -117,7 +117,7 @@ LT_INIT([shared static])
|
|||
# --> Set 'LT_NGSPICE_AGE' to 0.
|
||||
|
||||
LT_NGSPICE_CURRENT=0
|
||||
LT_NGSPICE_REVISION=6
|
||||
LT_NGSPICE_REVISION=7
|
||||
LT_NGSPICE_AGE=1
|
||||
LIBNGSPICE_SO_VERSION=$LT_NGSPICE_CURRENT.$LT_NGSPICE_REVISION.$LT_NGSPICE_AGE
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -250,7 +250,7 @@ inp_list(FILE *file, struct card *deck, struct card *extras, int type)
|
|||
Xprintf(file, "%s\n", here->error);
|
||||
}
|
||||
else if ((*here->line != '*') && (type == LS_RUNNABLE)) {
|
||||
Xprintf(file, "%s\n", upper(here->line));
|
||||
Xprintf(file, "%s\n", here->line);
|
||||
if (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;
|
||||
if (type == LS_PHYSICAL)
|
||||
Xprintf(file, "%6d : %s\n",
|
||||
here->linenum, upper(here->line));
|
||||
here->linenum, upper(here->line));
|
||||
else
|
||||
Xprintf(file, "%s\n", upper(here->line));
|
||||
if (here->error && (type == LS_PHYSICAL))
|
||||
|
|
@ -291,7 +291,7 @@ inp_list(FILE *file, struct card *deck, struct card *extras, int type)
|
|||
continue;
|
||||
if (type == LS_PHYSICAL)
|
||||
Xprintf(file, "%6d : %s\n",
|
||||
there->linenum, upper(there->line));
|
||||
there->linenum, upper(there->line));
|
||||
else
|
||||
Xprintf(file, "%s\n", upper(there->line));
|
||||
if (there->error && (type == LS_PHYSICAL))
|
||||
|
|
|
|||
|
|
@ -169,7 +169,6 @@ static void inp_check_syntax(struct card *deck);
|
|||
|
||||
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);
|
||||
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.
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
static char *inp_pathresolve(const char *name)
|
||||
char *inp_pathresolve(const char *name)
|
||||
{
|
||||
struct variable *v;
|
||||
struct stat st;
|
||||
|
|
@ -9822,6 +9821,19 @@ static void inp_check_syntax(struct card *deck)
|
|||
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++)
|
||||
subs[ii] = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,5 +8,5 @@
|
|||
|
||||
struct card *insert_new_line(struct card *card, char *line,
|
||||
int linenum, int linenum_orig);
|
||||
|
||||
char *inp_pathresolve(const char *name);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ noinst_HEADERS = \
|
|||
hlpdefs.h \
|
||||
iferrmsg.h \
|
||||
ifsim.h \
|
||||
inertial.h \
|
||||
inpdefs.h \
|
||||
inpmacs.h \
|
||||
inpptree.h \
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ are of type bool if sharedspice.h is used externally.
|
|||
*/
|
||||
|
||||
#ifndef NGSPICE_PACKAGE_VERSION
|
||||
#define NGSPICE_PACKAGE_VERSION "39+"
|
||||
#define NGSPICE_PACKAGE_VERSION "40"
|
||||
#endif
|
||||
/* we have NG_BOOL instead of BOOL */
|
||||
#ifndef HAS_NG_BOOL
|
||||
|
|
|
|||
|
|
@ -184,7 +184,13 @@ IFparm VBICmPTable[] = { /* model parameters */
|
|||
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"),
|
||||
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[] = {
|
||||
|
|
|
|||
|
|
@ -457,6 +457,7 @@ typedef struct sVBICmodel { /* model structure for a vbic */
|
|||
double VBICtempExpAVC;
|
||||
double VBICthermalResist;
|
||||
double VBICthermalCapacitance;
|
||||
int VBICselft;
|
||||
double VBICpunchThroughVoltageBC;
|
||||
double VBICdeplCapCoeff1;
|
||||
double VBICfixedCapacitanceCS;
|
||||
|
|
@ -484,6 +485,10 @@ typedef struct sVBICmodel { /* model structure for a vbic */
|
|||
double VBICvbeMax; /* maximum voltage over B-E junction */
|
||||
double VBICvbcMax; /* maximum voltage over B-C junction */
|
||||
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 VBICextCollResistGiven : 1;
|
||||
|
|
@ -571,6 +576,7 @@ typedef struct sVBICmodel { /* model structure for a vbic */
|
|||
unsigned VBICtempExpNFGiven : 1;
|
||||
unsigned VBICtempExpAVCGiven : 1;
|
||||
unsigned VBICthermalResistGiven : 1;
|
||||
unsigned VBICselftGiven : 1;
|
||||
unsigned VBICthermalCapacitanceGiven : 1;
|
||||
unsigned VBICpunchThroughVoltageBCGiven : 1;
|
||||
unsigned VBICdeplCapCoeff1Given : 1;
|
||||
|
|
@ -598,6 +604,10 @@ typedef struct sVBICmodel { /* model structure for a vbic */
|
|||
unsigned VBICvbeMaxGiven : 1;
|
||||
unsigned VBICvbcMaxGiven : 1;
|
||||
unsigned VBICvceMaxGiven : 1;
|
||||
unsigned VBICvsubMaxGiven : 1;
|
||||
unsigned VBICvbcfwdMaxGiven : 1;
|
||||
unsigned VBICvbefwdMaxGiven : 1;
|
||||
unsigned VBICvsubfwdMaxGiven : 1;
|
||||
} VBICmodel;
|
||||
|
||||
#ifndef NPN
|
||||
|
|
@ -734,6 +744,11 @@ enum {
|
|||
VBIC_MOD_VBE_MAX,
|
||||
VBIC_MOD_VBC_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 */
|
||||
|
|
|
|||
|
|
@ -363,12 +363,27 @@ VBICmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
|
|||
case VBIC_MOD_VCE_MAX:
|
||||
value->rValue = here->VBICvceMax;
|
||||
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:
|
||||
if (here->VBICtype == NPN)
|
||||
value->sValue = "npn";
|
||||
else
|
||||
value->sValue = "pnp";
|
||||
return(OK);
|
||||
case VBIC_MOD_SELFT:
|
||||
value->iValue = here->VBICselft;
|
||||
return(OK);
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -509,6 +509,26 @@ VBICmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
mods->VBICvceMax = value->rValue;
|
||||
mods->VBICvceMaxGiven = TRUE;
|
||||
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:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -391,6 +391,21 @@ VBICsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
|||
if(!model->VBICvceMaxGiven) {
|
||||
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 */
|
||||
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;
|
||||
else
|
||||
here->VBIC_selfheat = 0;
|
||||
|
|
|
|||
|
|
@ -17,14 +17,16 @@ VBICsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
|
|||
{
|
||||
VBICmodel *model = (VBICmodel *) inModel;
|
||||
VBICinstance *here;
|
||||
double vbe, vbc, vce; /* actual bjt voltages */
|
||||
double vbe, vbc, vce, vsub; /* actual bjt voltages */
|
||||
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) {
|
||||
warns_vbe = 0;
|
||||
warns_vbc = 0;
|
||||
warns_vce = 0;
|
||||
warns_vsub = 0;
|
||||
warns_op = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
@ -32,39 +34,95 @@ VBICsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
|
|||
|
||||
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] -
|
||||
ckt->CKTrhsOld [here->VBICemitNode]);
|
||||
vbc = fabs(ckt->CKTrhsOld [here->VBICbaseNode] -
|
||||
ckt->CKTrhsOld [here->VBICcollNode]);
|
||||
vce = fabs(ckt->CKTrhsOld [here->VBICcollNode] -
|
||||
ckt->CKTrhsOld [here->VBICemitNode]);
|
||||
vbe = fabs(ckt->CKTrhsOld[here->VBICbaseNode] -
|
||||
ckt->CKTrhsOld[here->VBICemitNode]);
|
||||
vbc = fabs(ckt->CKTrhsOld[here->VBICbaseNode] -
|
||||
ckt->CKTrhsOld[here->VBICcollNode]);
|
||||
vce = fabs(ckt->CKTrhsOld[here->VBICcollNode] -
|
||||
ckt->CKTrhsOld[here->VBICemitNode]);
|
||||
vsub = fabs(ckt->CKTrhsOld[here->VBICcollNode] -
|
||||
ckt->CKTrhsOld[here->VBICsubsNode]);
|
||||
|
||||
if (vbe > model->VBICvbeMax)
|
||||
if (warns_vbe < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"|Vbe|=%g has exceeded Vbe_max=%g\n",
|
||||
vbe, model->VBICvbeMax);
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"|Vbe|=%g has exceeded Vbe_max=%g\n",
|
||||
vbe, model->VBICvbeMax);
|
||||
warns_vbe++;
|
||||
}
|
||||
|
||||
if (vbc > model->VBICvbcMax)
|
||||
if (warns_vbc < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"|Vbc|=%g has exceeded Vbc_max=%g\n",
|
||||
vbc, model->VBICvbcMax);
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"|Vbc|=%g has exceeded Vbc_max=%g\n",
|
||||
vbc, model->VBICvbcMax);
|
||||
warns_vbc++;
|
||||
}
|
||||
|
||||
if (vce > model->VBICvceMax)
|
||||
if (warns_vce < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"|Vce|=%g has exceeded Vce_max=%g\n",
|
||||
vce, model->VBICvceMax);
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"|Vce|=%g has exceeded Vce_max=%g\n",
|
||||
vce, model->VBICvceMax);
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
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
|
||||
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
|
||||
characteristics of the connected device, for example digital devices
|
||||
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.
|
||||
If found, set vcc from the parameter.
|
||||
|
||||
3: If a command interpreter variable "no_auto_bridge_family": exists, go to
|
||||
step 5. Search the connected device instances for a parameter,
|
||||
"family" with a string value. The first one found will be used.
|
||||
If the first character of the value is not '*', the setup card will
|
||||
be ".include bridge_FFFFF_DDD.cir" where FFFFF is the family and
|
||||
DDD is the signal direction for the XSPICE device: "in", "out" or
|
||||
"inout". The device card will be "Xauto_bridge%d %s %s
|
||||
bridge_FFFFF_DDD vcc=%g", so a suitably parameterised subcircuit
|
||||
must be defined in the included file.
|
||||
3: If a command interpreter variable "no_auto_bridge_family": exists,
|
||||
go to step 5. Search the connected XSPICE device instances for a
|
||||
parameter, "family" with a string value. The first one found will
|
||||
be used. If no such instance exists, search for a string-valued
|
||||
parameter, "family", in enclosing subcircuits, as in step 2. If
|
||||
the first character of the value is not '*', the setup card may be
|
||||
".include bridge_FFFFF_TTTT_DDD.subcir" where FFFFF is the family,
|
||||
TTTT is as before and DDD is the signal direction for the XSPICE
|
||||
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
|
||||
"auto_bridge_FFFFF_TTTT_DDD" where FFFFF is the family without '*',
|
||||
TTTT is the node type string and DDD is the direction. So this might be
|
||||
"auto_bridge_74HCT_d_inout" for a digital node. Use the variable's value
|
||||
as in step 6, proceeding to step 5 if checks fail.
|
||||
4: If the first character of "family" was '*', or no file was found,
|
||||
look for a variable "auto_bridge_FFFFF_TTTT_DDD" where FFFFF is the
|
||||
family without '*', TTTT is the node type string and DDD is the
|
||||
direction. So this might be "auto_bridge_74HCT_d_inout" for a
|
||||
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.
|
||||
|
||||
|
|
@ -160,9 +165,9 @@ for device libraries whose devices are defined by subcircuits.
|
|||
|
||||
and invoked by:
|
||||
|
||||
set auto_bridge_d_out_30 = ( ".include test_sub.cir"
|
||||
+ "xauto_buf%d %s %s auto_buf vcc=%g"
|
||||
+ 1 )
|
||||
set auto_bridge_d_out = ( ".include test_sub.subcir"
|
||||
+ "xauto_buf%d %s %s auto_buf vcc=%g"
|
||||
+ 1 )
|
||||
*/
|
||||
|
||||
/* Working information about a type of bridge. */
|
||||
|
|
@ -195,10 +200,15 @@ static struct card *expand_deck(struct card *head)
|
|||
struct card *card, *next;
|
||||
char **pointers;
|
||||
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();
|
||||
save_debug = ft_ngdebug;
|
||||
ft_ngdebug = FALSE;
|
||||
|
||||
/* Count the cards, allocate and fill a pointer array. */
|
||||
|
||||
|
|
@ -221,6 +231,7 @@ static struct card *expand_deck(struct card *head)
|
|||
circarray = pointers;
|
||||
card = inp_readall(NULL, Infile_Path, FALSE, TRUE, NULL);
|
||||
card = inp_subcktexpand(card);
|
||||
ft_ngdebug = save_debug;
|
||||
|
||||
/* Destroy the parameter table that was created in subcircuit/parameter
|
||||
* expansion and restore the previous version.
|
||||
|
|
@ -479,8 +490,8 @@ static struct bridge *find_bridge(Evt_Node_Info_t *event_node,
|
|||
family = NULL;
|
||||
deep = scan_devices(event_node, ckt, &family);
|
||||
|
||||
/* Look for a real parameter (.param type) in the device's subcircuit
|
||||
* and those enclosing it.
|
||||
/* Look for a real parameter (.param type) and perhaps a string-valued
|
||||
* "family" parameter in the device's subcircuit and those enclosing it.
|
||||
*/
|
||||
|
||||
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);
|
||||
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;
|
||||
*dot = '\0';
|
||||
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))
|
||||
family = NULL;
|
||||
|
||||
if (family && *family == '*') {
|
||||
s_family = family + 1;
|
||||
family = NULL; // Not used for matching.
|
||||
if (family) {
|
||||
if (*family == '*') {
|
||||
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 {
|
||||
s_family = NULL;
|
||||
}
|
||||
|
|
@ -523,10 +555,19 @@ static struct bridge *find_bridge(Evt_Node_Info_t *event_node,
|
|||
bridge->direction == direction) {
|
||||
if (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;
|
||||
break;
|
||||
bridge->vcc = vcc;
|
||||
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.
|
||||
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. */
|
||||
|
||||
if (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) {
|
||||
if (s_family) {
|
||||
/* Family variable lookup. */
|
||||
|
||||
snprintf(buff, sizeof buff, "auto_bridge_%s_%s_%s",
|
||||
s_family, type_name, dirs[direction]);
|
||||
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) {
|
||||
|
|
@ -667,8 +708,13 @@ bool Evtcheck_nodes(
|
|||
int nl;
|
||||
|
||||
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
|
||||
}
|
||||
bridge = find_bridge(event_node, ckt, &bridge_list);
|
||||
if (!bridge) {
|
||||
/* Fatal, circuit cannot run. */
|
||||
|
|
|
|||
|
|
@ -303,6 +303,7 @@ void Evt_purge_free_outputs(void)
|
|||
|
||||
for (i = 0; i < g_evt_num_udn_types; ++i) {
|
||||
output_event = g_evt_udn_info[i]->free_list;
|
||||
g_evt_udn_info[i]->free_list = NULL;
|
||||
while (output_event) {
|
||||
next = output_event->next;
|
||||
tfree(output_event->value);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ NON-STANDARD FEATURES
|
|||
|
||||
#include "ngspice/mifproto.h"
|
||||
#include "ngspice/mifdefs.h"
|
||||
#include "ngspice/evt.h"
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#include "ngspice/mifparse.h"
|
||||
|
|
@ -134,8 +135,16 @@ MIFdelete(GENinstance *gen_inst)
|
|||
/* Free the basic port structure allocated in MIFget_port */
|
||||
num_port = here->conn[i]->size;
|
||||
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);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
#define PACKAGE "ngspice"
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "39+"
|
||||
#define VERSION "40+"
|
||||
|
||||
/* Define the directory for executables */
|
||||
#define NGSPICEBINDIR "../bin"
|
||||
|
|
|
|||
Loading…
Reference in New Issue