|
From: Victor B. <vi...@ty...> - 2006-02-08 10:54:23
|
Hi Bill and All,
the included document may help somewhat. This is the instruction on how to
implement SPICE model (refers to original SPICE, not ngspice). Still, may be
usefull, as ngspice was based on Berkeley SPICE.
Regards,
Victor
NEW MODEL IMPLEMENTATION IN SPICE3
===================================================
SPICE VERSIONS 3E2 AND 3F5
Conor Donnelly (original document) 6-12-95
Victor Bourenkov (changes for SPICE3F5) 25-2-00
0. GENERAL
----------
Contacts: Markku Tavasti ********@******.fi
*********** ** **,
***** Tampere,
Finland.
/for questions related to the implementation of the MOS9
model in the SPICE3e2/
Contacts: Victor Bourenkov vi...@nm...
NMRC, Lee Maltings
Prospect Row, Cork
Ireland.
/for questions related to the implementation of the BSIM3
model in the SPICE3f5/
This document can be used as general help for adding device models to
SPICE3. Order of appearance of subjects is quite random!
You should read books 'ANALYSIS OF PERFORMANCE AND CONVERGENCE ISSUES
FOR CIRCUIT SIMULATION', 'ADDING DEVICES TO SPICE3' and 'THE SPICE3
IMPLEMENTATION GUIDE'. All by Thomas Linwood Quarles of UC Berkeley.
0.1 NOTES
---------
To start with, before modifying anything, it is recommended to copy the whole
SPICE directory into a new location so it would be possible to experiment with
no fear if something goes wrong.
In this document we will refer to the root SPICE3 directory as spice3/.
Where ever you meet <dev> replace it with your own device model name.
1. FILES MODIFIED WHEN NEW MODEL ADDED
--------------------------------------
See Device manual, page 15.
1.1 src/lib/inp/inpdomod.c
In this file you have add entry for desired device name. Copy the
existing code, change the level number (it could be any integer number).
This number do not have to be the same as the number (or character) you will
use as 'level' identifier in a circuit description.
See next.
1.2 src/lib/inp/inpfindl.c
(this was most changed in ngspice)
Looks the line if there is word 'level' and then tries to find
number. At the moment, it's supporting levels 1-9, if you want to use
something else, use 0 or a,b,c,d,....
It have to be single character. Yeah, I agree, stupid. If you will use
a letter, say, 'a', SPICE will produce a warning, saying that there is
a "error in line xx, parameter 'a' is not found" or somethig similar.
But don't worry, it won't affect anything.
1.3. src/lib/inp/inp2<letter>.c
For checking legal device-names for <letter>. For MOS see inp2m.c.
1.4 src/bin/config.c
Here you have to add nesessary include statements. Quite obvious
when you see it.( Look for <dev>itf.h , <dev>/dev>itf.h, and #ifdef DEV_<dev> )
1.5. conf/defaults
In devices list, add your device. Remember that your device name is
name for directory.
1.6 util/lib/make_def.bd -- for spice3e2
util/skeleton/make_def.bd -- for spice3f5
In this file add your device to ALL_DEVICES list.
So that's it. That should be all you need to modify to put new model in. As
long as your model is ok.
2. MODEL FILES TO BE CREATED
----------------------------
Where ever you meet <dev> replace it with your own device model name.
A brief description of each file follows.
(all files from now on are in
src/include - spice3e2
src/lib/dev/<dev> - spice3f5 )
2.1 <dev>itf.h
This describes the interface to spice. It gives the function names which
are called for specific operation, like loading, setting device
parameters, asking values, etc. See pages 5 and 51 in device guide.
Difference between the versions of SPICE: (diff -u <3e2> <3f5>)
34a35
> DEV_DEFAULT
40a42
> NULL,
I.e. put DEV_DEFAULT after "<DEV>mPTable," and "NULL," between
two "<DEV>setup" in "SPICEdev <DEV>info" structure. NULL here is
a pointer to the <DEV>unsetup procedure. If you have this subroutine,
put its name here.
2.2. <dev>ext.h
Declarations of functions used in model.
2.3 <dev>def.h
Declaration of structures for instance and model. The model structure
maintains a linked list of model types. The instance structure maintains
a linked list of instances for each model type. In the instance structure
you include nodes, statetable elements, pointers to conductance-matrix,
all instance parameters.....
Also include labels (#define) for parameters. These labels are
later used in lots of places. Make sure you don't have overlapping numbers
in labels!
NOTE: There is a difference in the format of the file in different
versions of SPICE.
For SPICE3e2 the s<DEV>instance structure must look like:
typedef struct sBSIM3instance
{
struct sBSIM3model *BSIM3modPtr;
struct sBSIM3instance *BSIM3nextInstance;
IFuid BSIM3name;
int BSIM3dNode;
int BSIM3gNode;
---- and so on ---
For SPICE3f5 the s<DEV>instance looks slightly different:
typedef struct sBSIM3instance
{
struct sBSIM3model *BSIM3modPtr;
struct sBSIM3instance *BSIM3nextInstance;
IFuid BSIM3name;
int BSIM3states; /* index into state table for this device */
int BSIM3dNode;
int BSIM3gNode;
---- and so on ---
(all files from now on are in src/lib/dev )
2.4 <dev>.c
This is file for describing all your instance and model input/output
parameters. PArameters are given with macros IP, IOP,OP and P. They stand
for input, input/output, output, and nothing. P-macro is useful when you
want your model to recognise some parameter, but you have not implemented it.
Then spice will only give warning that parameter is not implemented.
Structure is :
IOP("vsb" , DEV_VSB, IF_REAL, "Voltage...."),
where vsb is the string which is used in spice inputfile to set it,
DEL_VSB is unique label,(from <dev>def.h), IF_REAL is type, and rest of it
is description.
File also includes names for nodes, in char *<dev>names[].
2.5 <dev>param.c (or <dev>par.c)
Includes function to put given parameters to instance. Make sure to use
right kind of value of union (ivalue, rvalue..) See src/include/ifsim.h
for details of different values.
Many people set also some flag to indicate that something is already set.
2.6. <dev>mparam.c
Parameters for model. Same thing as previous.
2.7. <dev>ask.c , <dev>mask.c
Files serving questions for parameters, variables, etc. Same thing than
two previous ones, execept reverse.
2.8. <dev>del.c
Deleting single instance and all datastructures allocated by model.
2.9. <dev>mdel.c
Deletion routine for model. See previous.
2.10. <dev>set.c
This routine is most commonly used to check that all needed parameters are
set, and, if not doing setting default values to them. Mostly checking is
based on flags (DEVwhatsoeverGiven).
This is performed after reading of inputfile is done.
2.11 <dev>temp.c
This is routine to perform parameter pre-prosessing and clipping. It is
called once for each temperature analysis is performed.
2.12. <dev>getic.c or <dev>setic.c
To initialise device votages if initial conditions are given in input
file.
2.13. <dev>ld.c or <dev>load.c
This function is called most often. Should be optimised as much as possible.
It is getting voltages, from state[1] (previous timepoint), from
ckt->RHSold (solution of previous iteration), or even making a guess.
God guess is something to put device to state where it is turned on, but
current is quite zero.
After getting needed values, this routine computes currents, charges, their
derivatives. Here is list where to put what:
state0, put in all the values you are using in statable. Make sure you are
using state0, which is this timepoint, state1 is previous, etc.
ckt->rhs, righthand side, Currents. They are added ( += ), NOT assigned.
To Y-matrix, with those mystical matrix-element pointers. This is the
Conductance matrix in nodal votage representation of circuit.
Here is small example for mosfet:
S D G B
-------------------------------------------
S | Ss Sd Sg Sb
--------------------------------------------
D | Ds Dd Dg Db
--------------------------------------------
G | Gs Gd Gg Gb
--------------------------------------------
B | Bs Bd Bg Bb
-----------------------------------------------
All the elements Ss, Dd, Gg, Bb you have to ADD (not assign) sum of
conductances aplied to that node (as far as you know, in respect of this
device).
All the other elements you substract conductance between nodes. That
means, for node Gs you substract dIg/dVs (derivative of current from/to
gate derivated in respect of source voltage)
This is to DC part of those conductances, then for AC/Trancient part
something follows:
Derivative of charge represents capacitance. For example, dQd/dVs is
representing capacitance between drain and source, but capacitances are
not symmetrical in mos, which means you have to calculate them both ways.
To get conductances from capacitance, you can use NIintegrate (from
src/lib/dev/ni/niiteg.c) or simply multiply capacitance with ckt->CKTag0.
In fact, both are doing the same thing, NIintegrate is also manipulating
statetable elements and calculating eqvivalent current source. NIintegrate
is used only for capacitors for which we know charge.
Remember to save capacitances for ACload.
2.14. <dev>trunc.c
Calculating truncation error for capacitors. Uses CKTerr function.
2.15 <dev>acld.c
Performs calculation for ac small signal analyses. Maybe guite simple,
using stored capacitances, and multiplying them with ckt->CKTomega.
After it same kind of loading of Y-matrix (conductance) as in <dev>load
2.16. <dev>cvtestc or <dev>conv.c
Testing if solution has converged. If more iteration is needed, inclerement
ckt->CKTnoncon.
|