SPICE MODELS - MOS x VDMOS


#1

Hello, now that ngspice is integrated within EESCHEMA several issues will arise and become common among users.

First and foremost the REQUIRED setup into each system of the “SPICE LIBRARY”
or SPICE stuff - most likely will lead to another ENVIRONMENT VARIABLE like setup
This is how I manage my system and likely to be others.

Second is the LICENSE inevitable problem.
As all know SPICE REQUIRES Third-Part MODELS. Mostly proprietary.

MODELS will require association (already in place in the dialog)

But MODELS TODAY are becoming increasingly diverted from original SPICE3F

My problem at the moment is
** HOW TO CONVERT already available MODELS to proper use (license and format)
** HOW TO SOLVE THE VDMOS to MOS (Level=X) SPICE use
** IF a common base MODEL repository should be considered to mitigate this

or … it will be completely adhoc each setup per si with no central organization

That impacts any setup organization or workstation flow.

If anyone has any method or clever way to CONVERT VDMOS to MOS
or GENERIC PSPICE to standard SPICE3F

Please drop a note to help - it is really hard to have a lot of VDMOS
models without direct use in SPICE (aka NGSPICE)

Thank you all folks
Regards
Paul


#2

From ngspice side: I am working on a ngspice version that translates PSPICE device models to ngspice.
See https://sourceforge.net/p/ngspice/discussion/ngspice-tips/thread/7838169b/ for more information.

Questions andd feedback are welcome!


#3

Hello good news. That is great.

I was reading some comments there and several folks were actually doing as myself by translating PSPICE models into SPICE3F.

I have some scripts that automate this task creating a readable
ngspice compatible parameter model from a PSPICE lib file

It is obviously a crude PERL MAPPING HASH but it does the job.
For example the DIODE HASH

%DIODE_HASH = (

junction dc parms

BV  => [ 'Reverse breakdown voltage'         ,   $inf  ], # infinite
IBV => [ 'Reverse breakdown current'         ,  '1e-3' ],
IK  => [ 'Forward knee current'              ,  '1e-3' ], #=IKF
IKF => [ 'Forward knee current'              ,  '1e-3' ], #=IK
IKR => [ 'Reverse knee current'              ,  '1e-3' ],
IS  => [ 'Saturation current'                , '1e-14' ], #=JS
JS  => [ 'Saturation current'                , '1e-14' ], #=IS
JSW => [ 'Sidewall saturation current'       , '1e-14' ],
N   => [ 'Emission coefficient'              ,     '1' ],
RS  => [ 'Ohmic    resistance'               ,     '0' ],

junction capacitance parms

CJO => [ 'Zero bias junction capacitance'    ,     '0' ], #=CJ0
CJ0 => [ 'Zero bias junction capacitance'    ,     '0' ], #=CJO
CJP => [ 'Zero bias junction sidewall cap'   ,     '0' ], #=CJSW
CJSW=> [ 'Zero bias junction sidewall cap'   ,     '0' ], #=CJP
FC  => [ 'Forward bias depletion capacitance',   '0.5' ],
FCS => [ 'Coeff forward bias depletion cap'  ,   '0.5' ],
M   => [ 'Junction grading coefficient'      ,   '0.5' ], 
MJ  => [ 'Junction grading coefficient'      ,   '0.5' ], #=M
MJSW=> [ 'Periphery junction grading coeff'  ,   '0.33'],
VJ  => [ 'Junction potential'                ,     '1' ], #=PB
PB  => [ 'Junction potential'                ,     '1' ], #=VJ
PHP => [ 'Periphery junction potencial'      ,     '1' ],
TT  => [ 'Transit time'                      ,     '0' ],

temperature

EG  => [ 'Activation energy'                 ,  '1.11' ], 
XTI => [ 'IS temperature exponent'           ,   '3.0' ], 

noise

KF  => [ 'Flicker noise coefficient'         ,     '0' ],
AF  => [ 'Flicker noise exponent'            ,     '1' ],

);

That HASH maps the DIODE model with defaults that can be fed
by the PSPICE specific model - EACH model will generate a lib entry

A BJT and a MOS HASH already exists but parameters
are far more deviated from PSPICE to SPICE.

As soon as possible I will read the approach used on the code…

Good news… PSPICE has several libraries available
But VDMOS seems required for today MOSFETs
Convergence is still a big problem without the model

I will post here after reading code

Thanks for your reply
Regards
Paul


#4

To be honest, I do not exactly understand your point concerning VDMOS models. You are talking about models for MOS power devices, right?

These models are typically ‘lumped element’ models, organized as subcircuits (.subckt …) and embedded in a circuit by calling them via a x line. Inside of the subcircuit they use the SPICE standard models (R, C, MOS level=1 or 3, D etc.). You cannot translate the subcircuit into a simple standard MOS model. ngspice adds the subcircuit to the netlist by an .include statement and adds it to the circuit netlist by a call to x…

I am not sure if KiCad is supporting this approach (when calling ngspice, use the ngspice .include statement for adding the model), but I guess it does because many vendor OpAmp models use the same approach (being PSPICE subcircuits that contain transistors, voltage sources, R , C and other basic SPICE devices).

Included in the ngspice git branch PSPICEComp3 there is an example of a call to an Infineon power transistor (see file ngspice\p-to-n-examples\Optimos_out.cir). The original subcircuit formulation is according to some PSPICE conventions that are incompatible to ngspice. The new option in ngspice translates this to ngspice syntax.

So basically VDMOS should be treated like OpAmp. PSPICE compatibility for these lumped element models is achieved by adding them with .include to the ngspice netlist and setting a flag ‘set ngbehavior=ps’ into the file ‘.spiceinit’.

This has been a lot of ‘ngspice speech’. Maybe we should contact the KiCad developers to discuss the issue.


#5

Well we have several “open” models ready to use.

Mostly they come from PSPICE which also mostly is compatible with SPICE parameters. Some few are different and exclusive.

This is the point where my parser is able to “translate” or map those identical parameters and just comment those not handled.

The DIODE model example should put things a bit clear.
The parsers maps a PSPICE .model diode() to a plain SPICE line.

Now enters the more complex BJT parameters and MOS parameters. There are so many different parameters in .model NPN/PNP and .model NJF/PJF that mapping those is more tricky.

Now we enter the new era of MOS devices:

  • SOME ARE SUBCKTs.
  • but some (from LTSPICE) define a .model .MOS() entry line
    using their own .model VDMOS() line.

If somebody, just like me, happens to have an LTSPICE ready circuit that contains models defined with their VDMOS parameter list…

And they have a complete library ready to use…
that just needs to be “mapped” from VDMOS model entry
to plain SPICE .model MOS() entry.

For example:

.model IRF6617 VDMOS(Rg=2 Vto=2.42 Rd=4.5m Rs=.8m Rb=3m Kp=60 lambda=.01 mtriode=3 Cgdmax=.7n Cgdmin=.15n Cgs=1.1n Cjo=.5n Is=1.5p ksubthres=.1 mfg=International_Rectifier Vds=30 Ron=8m Qg=11n)

The current VDMOS lib from LTSPICE contains about 1000
MOS models ready to use. None of them defined as SUBCKT.

Just their plain VDMOS parameter list.
My parser can translate a PSPICE .model MOS()
to SPICE .model MOS()

but not the LTSPICE VDMOS to MOS …

The most basic MOS HASH contains a rather different
parameter entry from VDMOS lines.

Example:

my %MOSHASH = (
  AF     => [ 'Flicker noise exponent'                                                             ,'',     '1.0'  ],
  CBD    => [ 'Zero-bias B-D junction capacitance'                                                 ,'',     '0.0'  ],
  CBS    => [ 'Zero-bias B-S junction capacitance'                                                 ,'',     '0.0'  ],
  CGBO   => [ 'Gate-bulk overlap capacitance per meter channel width'                              ,'',     '0.0'  ],
  CGDO   => [ 'Gate-drain overlap capacitance per meter channel width'                             ,'',     '0.0'  ],
  CGSO   => [ 'Gate-source overlap capacitance per meter channel width'                            ,'',     '0.0'  ],
  CJ     => [ 'Zero-bias bulk junction bottom cap. per sq-meter of junction area'                  ,'',     '0.0'  ],
  CJSW   => [ 'Zero-bias bulk junction sidewall cap. per meter of junction perimeter'              ,'',     '0.0'  ],
  DELTA  => [ 'Width effect on threshold voltage (MOS2 and MOS3)'                                  ,'',     '0.0'  ],
  ETA    => [ 'Static feedback (MOS3 only)'                                                        ,'',     '0.0'  ],
  FC     => [ 'Coefficient for forward-bias depletion capacitance formula'                         ,'',     '0.5'  ],
  GAMMA  => [ 'Bulk threshold parameter'                                                           ,'',     '0.0'  ],
  IS     => [ 'Bulk junction saturation current (I_{S})'                                           ,'', '1.0e-14'  ], 
  JS     => [ 'Bulk junction saturation current (I_{S})'                                           ,'', '1.0e-14'  ], 
  KAPPA  => [ 'Saturation field factor (MOS3 only)'                                                ,'',     '0.2'  ],
  KF     => [ 'Flicker noise coefficient'                                                          ,'',     '0.0'  ],
  KP     => [ 'Transconductance parameter'                                                         ,'',  '2.0e-5'  ],
  LAMBDA => [ 'Channel length modulation (MOS1 and MOS2 only) (\lambda)'                           ,'',     '0.0'  ],
  LD     => [ 'Lateral diffusion'                                                                  ,'',     '0.0'  ],
  LEVEL  => [ 'Model index'                                                                        ,'',       '1'  ],
  MJ     => [ 'Bulk junction bottom grading coeff.'                                                ,'',     '0.5'  ],
  MJSW   => [ 'Bulk junction sidewall grading coeff.'                                              ,'',    '0.33'  ],
  NEFF   => [ 'Total channel-charge (fixed and mobile) coefficient (MOS2 only)'                    ,'',     '1.0'  ],
  NFS    => [ 'Fast surface state density'                                                         ,'',     '0.0'  ],
  NSS    => [ 'Surface state density'                                                              ,'',     '0.0'  ],
  NSUB   => [ 'Substrate doping'                                                                   ,'',     '0.0'  ],
  PB     => [ 'Bulk junction potential'                                                            ,'',     '0.8'  ],
  PHI    => [ 'Surface potential (U)'                                                              ,'',     '0.6'  ],
  RD     => [ 'Drain ohmic resistance'                                                             ,'',     '0.0'  ],
  RS     => [ 'Source ohmic resistance'                                                            ,'',     '0.0'  ],
  RSH    => [ 'Drain and source diffusion sheet resistance'                                        ,'',     '0.0'  ],
  THETA  => [ 'Mobility modulation (MOS3 only)'                                                    ,'',     '0.0'  ],
  TNOM   => [ 'Parameter measurement temperature'                                                  ,'',      '27'  ],
  TOX    => [ 'Oxide thickness'                                                                    ,'',  '1.0e-7'  ],
  TPG    => [ 'Type of gate material: +1 opp. to substrate, -1 same as substrate, 0 Al gate'       ,'',     '1.0'  ],
  UCRIT  => [ 'Critical field for mobility degradation (MOS2 only)'                                ,'',   '1.0e4'  ],
  UEXP   => [ 'Critical field exponent in mobility degradation (MOS2 only)'                        ,'',     '0.0'  ],
  UO     => [ 'Surface mobility'                                                                   ,'',     '600'  ],
  UTRA   => [ 'Transverse field coeff. (mobility) (deleted for MOS2)'                              ,'',     '0.0'  ],
  VMAX   => [ 'Maximum drift velocity of carriers'                                                 ,'',     '0.0'  ],
  VTO    => [ 'Zero-bias threshold voltage (V_{T0})'                                               ,'',     '0.0'  ],
  XJ     => [ 'Metallurgical junction depth'                                                       ,'',     '0.0'  ],
);

To be all clear there is no attempt to TRANSLATE SUBCKT
whatsoever. Just the plain diode/BJT/FET/MOS models
adding the LTSPICE VDMOS as a last resource to have
their good list of models available.

Just download the “standard.mos” lib file from LTSPICE
to have the complete lib set.

Note as well that the thing is to “CONVERT” ready
available models to standard SPICE model.

Not changing a single line of code of current NGSPICE.
Plain out of the box.

The parser which i am trying already does that
with 90% success for DIODES and BJT and some FETs

But not MOS. And by no means the VDMOS
which are the most recent and powerful MOSFETs

Hope that sorts out the POV.

Regards
Paul


#7

So let’s talk about intrinsic (not subcircuit) MOS models. What is a model? It is a set of equations, that allows to calculate currents and capacitances as a function of gate, drain and bulk voltages. These models are hard-coded into the simulator. The most simple model is the MOS1 model. Soon it became apparent that its set of equations does not describe reality good enough for more advanced devices, so we got MOS3, BSIM3, BSIM4, BSIMBULK, etc., each new model more complex and sophisticated, all hard coded in the simulator.

A model should be generic enough to describe various MOS devices. For a specific device you need to select a model (e.g. MOS1) and provide a set of model parameters (.model line) that is dedicated to this model, and is obtained by comparing and optimizing the results from the equations (using the model parameter set for the calculation) with the measured device. A model is selected by the ‘level’ parameter in the .model line, e.g. level=3 for the MOS3 model. If ‘level’ is omitted, the MOS1 model is selected by default.

Looking at the VDMOS model from LTSPICE (http://ltwiki.org/LTspiceHelp/LTspiceHelp/M_MOSFET.htm, scrolled down), this a a variant of said MOS1 model (same DC characteristics), but with modified capacitance calculations. These capacitance equations again are hard coded into the simulator. Additional parameters are used to map the model onto real devices. Another implementation of the VDMOS can be found here: http://www.anasoft.co.uk/MOS1Model.htm.

So I think it is not possible to just map the additional VDMOS parameters onto the standard MOS1 model. The capacitance equation is simply not there. It is perhaps possible to create a subcircuit model that does this calculation. If this is not wanted, one has to hardcode the additional equations into the MOS1 model of ngspice and add the VDMOS switch to the .model parameter set.


#8

I see, so without explicit support for yet another
model ngspice will not be able to handle VDMOS.

The current claimed list od supported Levels I
have will have to be extended…

Either way the BJT and plain supported MOS Levels
may be mapped with some tweak here and there…

The available PSPICE libs “open” and ready to use is tempting

Paul


#9

Just a quick tip, you can format code sections and preserve indenting etc with triple backtick, e.g.

```
    some code
```

appears as

    some code

#10

I have added the VDMOS model to ngspice.

The source code is available from the ngspice git branch vdmos at https://sourceforge.net/p/ngspice/ngspice/ci/vdmos/tree/ .

This is a work in progress, a lot of testing might be necessary.


#11

That is great. You don’t miss a thing.

I was playing with the PSPICE version a bit and so far so good. I think that should be integral part of the release version.

I could not find a single reason to not use this as default in ngspice.

I was using a ‘myfunctions’ to implement pwr/pwrs, limit, stp and int and that native is handy.

Some available PSPICE libs (in particular TRIAC libs) are still problematic with complex models not being handled.

But all to all several PSPICE models run natively with that changes.

I think that a single catch ALL (PSPICE and VDMOS) will be much easy to handle. The PSPICE changes are not so huge to impact that much.

I will see this new one asap.

Regards
Paul


#12

Paul,

could you provide a link to the TRIAC models (or list a typical model here) that is not recongnized by the PSPICE option of ngspice? Maybe some simple feature is missing that might be added easily.

Holger


#13

yep available from STMicro…

attached here… I just can not load this library
under any hack… whatever I tried failed…

triac_st.lib.gz (5.6 KB)

Paul


#14

At least this is not a problem with ngspice (actual branch PSPICEComp3, ‘set ngbehavior=ps’ in .spiceinit, XSPICE enabled).

The input file shown below offers a simple TRIAC simulation without any modifications of ngspice.

TRIAC PSPICE test
* using PSPICEComp3 branch

.include triac_st.lib

vin 11 0 sin (0 200 50)

Rload 11 1 100

vk 2 0 0

vg 33 0 pulse 0 5 6m 1u 1u 10u 10m
Rg 33 3 10

* .subckt BTA10-600B A K G

xtriac 1 2 3 BTA10-600B

.tran 0.1m 100m

.control
run
plot v(1)
plot i(vin)
* all in one plot: scale currents by factor 100 and offset it by 300
plot v(1)  (-1)*i(vin)*100+300 (-1)*i(vg)*100+300
.endc

.end

Holger


#15

The very same CIR you have tested ok on my workstation
gives another failure under PSPICE branch…

attached print screen


#16

is missing in .spiceinit or spinit, or .spiceinit is not found.

It may be o.k. if you give this line as a command before loading the circuit, i.e. before issuing the ‘source …’ command.


#17

My spinit contains a lot of definitions including
the required ngbehavior set.

It is globally defined as suggested using
$SPICE_LIB_DIR/scripts/spinit

But from that definition it seems not properly
working. By the way it is indeed fine as ALL MY ALIAS,
ALL COLOR CODES, ALL THINGS are OK UNLESS the
ngbehavior=ps there…

As you suggested by using it manually it worked just fine.
I repeated the test making sure the ngbehavior is set on spinit
but it fails to recognize the set there, succeeds on plain cmd line.

Results are OK on cmd line.
But not using $SPICE_LIB_DIR/scripts/spinit


#18

I have played a bit more with the PSPICE directive trying to find
where it works or not…

So far the only working condition is by setting it manually
on cmd line. By using spinit or .spiceinit the directive is not seen
by the environment.

It looks that an essential call is missing in the code base
to map this directive into the environment

Also, as a suggestion, when using the “all” the PSPICE method
should be recognized as well

Upon loading the program the environ defaults to “all”
even though the directive is set on spinit.

The proper call is missing somewhere in the startup code.

Regards
Paul

NGB


#19

You seem to have found a bug. Is this in KiCad or Spice?
If KiCad, then raise a bug report on Launchpad


#20

This is NGSPICE on command line ONLY.

I don’t think that this fits as a bug by itself.

Note that on cmd line the proper call to setup the variable is
being properly done. Variable set all ok.

But upon initialization this required call should be missing
or it may be located in an order that it is not effective.

Just putting the required call upon initialization will do the trick
of setting the variable and making it available everywhere.

As suggested just calling "set … " is working fine
But that happens to be the only way it works …

Paul


#21

It seems to be strange that manual entering the set command is o.k., but not reading from file spinit.

It happened to me that I had several spinit files sitting around in different locations, and I had to figure out which one was indeed loaded.

To insure that you have edited the right one, please check it by adding a line
echo My real spinit file
right after the
set ngbehavior=ps
command. At starting ngspice, the ‘echo’ line should be printed on top of the ngspice header.