libsidplayfp  2.0.2
Public Member Functions | List of all members
reSIDfp::Integrator Class Reference

#include <Integrator.h>

Public Member Functions

 Integrator (const unsigned short *vcr_kVg, const unsigned short *vcr_n_Ids_term, const unsigned short *opamp_rev, unsigned short kVddt, unsigned short n_snake)
 
void setVw (unsigned short Vw)
 
int solve (int vi)
 

Detailed Description

Find output voltage in inverting integrator SID op-amp circuits, using a single fixpoint iteration step.

A circuit diagram of a MOS 6581 integrator is shown below.

               ---C---
              |       |
vi -----Rw-------[A>----- vo
     |      | vx
      --Rs--

From Kirchoff's current law it follows that

IRw + IRs + ICr = 0

Using the formula for current through a capacitor, i = C*dv/dt, we get

IRw + IRs + C*(vc - vc0)/dt = 0
dt/C*(IRw + IRs) + vc - vc0 = 0
vc = vc0 - n*(IRw(vi,vx) + IRs(vi,vx))

which may be rewritten as the following iterative fixpoint function:

vc = vc0 - n*(IRw(vi,g(vc)) + IRs(vi,g(vc)))

To accurately calculate the currents through Rs and Rw, we need to use transistor models. Rs has a gate voltage of Vdd = 12V, and can be assumed to always be in triode mode. For Rw, the situation is rather more complex, as it turns out that this transistor will operate in both subthreshold, triode, and saturation modes.

The Shichman-Hodges transistor model routinely used in textbooks may be written as follows:

Ids = 0                          , Vgst < 0               (subthreshold mode)
Ids = K/2*W/L*(2*Vgst - Vds)*Vds , Vgst >= 0, Vds < Vgst  (triode mode)
Ids = K/2*W/L*Vgst^2             , Vgst >= 0, Vds >= Vgst (saturation mode)

where K = u*Cox (transconductance coefficient) W/L = ratio between substrate width and length Vgst = Vg - Vs - Vt (overdrive voltage)

This transistor model is also called the quadratic model.

Note that the equation for the triode mode can be reformulated as independent terms depending on Vgs and Vgd, respectively, by the following substitution:

Vds = Vgst - (Vgst - Vds) = Vgst - Vgdt

Ids = K/2*W/L*(2*Vgst - Vds)*Vds
= K/2*W/L*(2*Vgst - (Vgst - Vgdt)*(Vgst - Vgdt)
= K/2*W/L*(Vgst + Vgdt)*(Vgst - Vgdt)
= K/2*W/L*(Vgst^2 - Vgdt^2)

This turns out to be a general equation which covers both the triode and saturation modes (where the second term is 0 in saturation mode). The equation is also symmetrical, i.e. it can calculate negative currents without any change of parameters (since the terms for drain and source are identical except for the sign).

FIXME: Subthreshold as function of Vgs, Vgd.

Ids = I0*e^(Vgst/(n*VT))       , Vgst < 0               (subthreshold mode)

The remaining problem with the textbook model is that the transition from subthreshold the triode/saturation is not continuous.

Realizing that the subthreshold and triode/saturation modes may both be defined by independent (and equal) terms of Vgs and Vds, respectively, the corresponding terms can be blended into (equal) continuous functions suitable for table lookup.

The EKV model (Enz, Krummenacher and Vittoz) essentially performs this blending using an elegant mathematical formulation:

Ids = Is * (if - ir)
Is = (2 * u*Cox * Ut^2)/k * W/L
if = ln^2(1 + e^((k*(Vg - Vt) - Vs)/(2*Ut))
ir = ln^2(1 + e^((k*(Vg - Vt) - Vd)/(2*Ut))

For our purposes, the EKV model preserves two important properties discussed above:

Rw in the circuit diagram above is a VCR (voltage controlled resistor), as shown in the circuit diagram below.

                 Vw

                 |
         Vdd     |
            |---|
           _|_   |
         --    --| Vg
        |      __|__
        |      -----  Rw
        |      |   |
vi ------------     -------- vo

In order to calculalate the current through the VCR, its gate voltage must be determined.

Assuming triode mode and applying Kirchoff's current law, we get the following equation for Vg:

u*Cox/2*W/L*((Vddt - Vg)^2 - (Vddt - vi)^2 + (Vddt - Vg)^2 - (Vddt - Vw)^2) = 0
2*(Vddt - Vg)^2 - (Vddt - vi)^2 - (Vddt - Vw)^2 = 0
(Vddt - Vg) = sqrt(((Vddt - vi)^2 + (Vddt - Vw)^2)/2)

Vg = Vddt - sqrt(((Vddt - vi)^2 + (Vddt - Vw)^2)/2)

The documentation for this class was generated from the following file: