gnucap-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gnucap-devel] Rethinking multi-dimensional "Kneechord" nonlinear co


From: Al Davis
Subject: Re: [Gnucap-devel] Rethinking multi-dimensional "Kneechord" nonlinear convergence
Date: Wed, 15 Dec 2004 23:16:41 -0500
User-agent: KMail/1.7.1

Sorry about the delay in responding.  I was out of the country 
and this one required more thought than the others.

First, don't forget that the semiconductor models are defined in 
the ".model" files.  If there is a ".model" file, the ".h" and 
".cc" files are machine generated and must not be edited.  If 
you delete them they will be regenerated on the next compile, 
by running "modelgen" on the ".model" file.  As far as GPL is 
concerned, I consider those .cc and .h files to be object code.  
They are provided only as a convenience for those who are stuck 
with an improper build system than cannot do hierarchical 
builds.  (Microsoft).

The part you are missing is really pretty simple.  The "poly" 
devices are internal elements to be used as base elements for 
behavioral modeling.  The purpose is to make it so model 
developers don't need to be concerned about simulator internals 
such as convergence and queues.  They provide matrix stamping, 
damping, and convergence checking.  They do no evaluation.

A "poly" element represents a "branch" in Verilog, or a single 
output equation/function in behavioral modeling....
 Y = f(a, b, c, d, e, f, ...)

If you need more than one output you need more than one "poly" 
device ....
  [ Ib Ic ] = f( [ Vb Vc ])
must be represented as:
 Ic = f( [ Vb Vc ])
 Ib = f( [ Vb Vc ])

So, when a model is defined by an equation block and a 
subcircuit, the equation block is evaluated first, then the 
subcircuit.

Elements in a .model file circuit block can have their value 
specified by "value", "eval" or "state".  For this discussion, 
I will refer to those specified as "state".

You might see something like:

    cpoly_g Ice {icol,iemit  ibase,iemit} state=cce_cpoly;

This is a multiple input transconductance, with output current 
source between the first two nodes (icol, iemit), which depends 
on itself (icol,iemit) as a conductance would, and on an input 
(ibase, iemit).  There can be as many inputs (in node pairs) as 
you need.

Let's call the output current "I", the voltage across the output 
nodes "Vo", the voltage across the first input nodes 
(ibase,iemit) "V1", etc.

"State" is a pointer to the output state variable. The 
derivatives follow it. Then later in 
"calculated_parameters" (which is really state variables) you 
see:

      double cce "collector-emitter current";
      double cce_cpoly;
      double go "Small signal output conductance";
      double gm "Small signal transconductance";

The current is:
    I = cce_cpoly + Vo * go + V1 * gm

Where "go" is dI/dVo and "gm" is dI/dV1 .

So, the one named as "state" is the part of the current that 
gets stamped on the right side.  The next variable is dI/dVo, 
the next is dI/dV1 and so on.

More generally, if we have:
    cpoly_g Foo (a b c d e f) state=p;
Then later:
    double p;
    double q;
    double r;
    double s;

Let's define Vo = v(a,b), V1 = v(c,d), V2 = v(e,f)
The current is:
    I = p + Vo * q + V1 * r + V2 * s;

It could be done with multiple admittances and transadmittances, 
but that would be slower.  Older versions of ACS and Gnucap did 
that.

The other poly devices are similar.

"fpoly_g" is the same except that the polynomial is represented 
in a different form.  The "state" is the current (I), then the 
derivatives follow.

"fpoly_c" is the same except that the output variable is charge 
instead of current.

As far as applying the kneechord algorithm, I hope this helps, 
or at least gives enough direction to ask more questions.

You might consider applying it later, in the "load" step.  Then 
you can apply it to the "tr_load" functions in e_element.h. 
Don't worry about "loss" and "shunt"  If you hit all the 
others, you have everything.  That's source, passive, active, 
and extended.  Passive and active are really special cases of 
extended.  There is already a function to manipulate the values 
there.  It's called "dampdiff".  This may be the easiest way to 
do it.

I am considering splitting the damping and loading into separate 
passes.  This should make it easier.  There is a performance 
advantage in splitting them.  Most of the time, damping isn't 
done, so putting damping in a separate loop first eliminates 
all those decisions, one per load.

Does this help?




reply via email to

[Prev in Thread] Current Thread [Next in Thread]