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.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
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
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
View File

@ -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

View File

@ -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
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
============
- 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.
## 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.
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

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);
}
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))

View File

@ -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;

View File

@ -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

View File

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

View File

@ -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

View File

@ -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[] = {

View File

@ -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 */

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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++;
}
}
}
}
}

View File

@ -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. */

View File

@ -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);

View File

@ -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);

View File

@ -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"