+1 (970) 672-0419 | Mail: email@ingenazure.com

Designing in the Subthreshold Region with NGSPICE

The subjects of posts here will largely be in response to questions I’m asked by junior engineers. As ever, any material I post will be related to NGSPICE.

Supporting material for this post may be downloaded from here.

With the increased demand for low power, portable applications and the ever shrinking geometry of advanced MOS processes, we see more and more publications regarding sub-threshold design. For engineers, both junior and senior who have never dealt in subthreshold circuit design before, the temptation is to assume that either it’s not so different to normal MOS design in the saturated region or it’s to be avoided at all costs. Neither is correct.

Subthreshold Design Challenges

As for the design challenge aspect of subthreshold versus saturation design, whilst things look the same circuit wise, the way the choices are made regarding device size is completely different.

Recall for a MOS device in the saturated region;


meaning we can use drain current, gate width and gate length to adjust the voltage gain. This turns out not to be the case in in subthreshold design. In subthreshold MOS devices, gm and rout are given as:

where N is a process constant




and Vt is the thermal voltage ~ 26mV at room temperature

meaning the ONLY design variable we have is gate length. Further more gain is inversely proportional to temperature. As an aside, compare the last equation to the gain of a bipolar transistor:

The MOS device is behaving like a bipolar!

Consider the following opamp circuit:

Low Voltage Opamp

Low Voltage Opamp

In this case, we will assume that we are working at a company with its own fab. The fab is just bringing up its 90nm process which contains for now only low voltage (core) CMOS devices. The challenge is to design a simple 2 stage miller compensated opamp that is unity gain stable, inverting, with a 500K feedback resistor and driving a 500ff capacitive load.

We are given a bias current of 1µA and a current consumption budget of > 20µA at room temperature.

For the record, I’m not advocating this design as something I’d recommend for a real chip for various reasons, but it is simple, easy to explain and suits the aim of discussing NGSPICE.

The voltage sources are in this schematic in order to measure current. All sources are set to 0V.

First we will use a dc sweep analysis to check our opamp gain.


Low Voltage Opamp DC Sweep Test Bench


Here we sweep the input voltage from 0 to 1V. VDD is also set to 1V.

We are interested in how the small signal parameters of the devices behave as we sweep the input voltage. In oder to do this and referring to the circuit diagram we add the following to our control file.

save all
save @m.x1.mn7[vgs] @m.x1.mn7[vth] @m.x1.mn7[vds] @m.x1.mn7[vdsat] @m.x1.mn7[gm] @m.x1.mn7[gds]
save @m.x1.mn2[vgs] @m.x1.mn2[vth] @m.x1.mn2[vds] @m.x1.mn2[vdsat] @m.x1.mn2[gm] @m.x1.mn2[gds]
save @m.x1.mn5[vgs] @m.x1.mn5[vth] @m.x1.mn5[vds] @m.x1.mn5[vdsat] @m.x1.mn5[gm] @m.x1.mn5[gds]
save @m.x1.mp2[vgs] @m.x1.mp2[vth] @m.x1.mp2[vds] @m.x1.mp2[vdsat] @m.x1.mp2[gm] @m.x1.mp2[gds]
save @m.x1.mp3[vgs] @m.x1.mp3[vth] @m.x1.mp3[vds] @m.x1.mp3[vdsat] @m.x1.mp3[gm] @m.x1.mp3[gds]
save @m.x1.mp7[vgs] @m.x1.mp7[vth] @m.x1.mp7[vds] @m.x1.mp7[vdsat] @m.x1.mp7[gm] @m.x1.mp7[gds]
save @m.x1.mp8[vgs] @m.x1.mp8[vth] @m.x1.mp8[vds] @m.x1.mp8[vdsat] @m.x1.mp8[gm] @m.x1.mp8[gds]

What this is doing is saving vgs, vth, vds, vdsat, gm, and gds for the devices we might be interested in looking at.

Save all saves all voltages in the circuits and all currents in voltage sources. It does not however save device small signal parameters. If you need to know the exact syntax of the device small signal parameter you might be interested in you can add the following line to your control deck

display all

Now we have this information we can create some definitions.

let rout1     =     1/(@m.x1.mn5[gds]+@m.x1.mp2[gds])
let rout2     =     1/(@m.x1.mn7[gds]+@m.x1.mp3[gds]+2e-6)
let GM1     =     (@m.x1.mn2[gm])
let GM2     =     (@m.x1.mp3[gm])
let av1       =     20*log(GM1*rout1)
let av2       =     20*log(GM2*rout2)
let av         =     av1+av2
let vgst_mn7 = @m.x1.mn7[vgs]-@m.x1.mn7[vth]
let vgst_mp3 = @m.x1.mp3[vgs]-@m.x1.mp3[vth]
let vgst_mn5 = @m.x1.mn5[vgs]-@m.x1.mn5[vth]
let vgst_mp2 = @m.x1.mp2[vgs]-@m.x1.mp2[vth]
let vds_mn7 = v(vout)
let vds_mp3 = v(vdd)-v(vout)
let vdsat_mn7 = @m.x1.mn7[vdsat]
let vdsat_mp3 = @m.x1.mp3[vdsat]

What’s this Doing?

rout1 is the output resistance of the first stage.
rout2 is the output resistance of the second stage. the +2e-6 represents the 500K feedback resistor.
GM1 is the transconductance of the first stage.
GM2 is the transconductance of the second stage

From the above four lines we can create equations for the the gain of the two stages and the overall opamp gain.

vgst_mn7, let vgst_mp3, let vgst_mn5 and let vgst_mp2 are the Vgst’s of MN7, MP3, MN5 and MP2 respectively.

vds_mn7 and vds_mn3 define the drain/source voltages of MN7 and MP3
vdsat_mn7 and vdsat_mp3 define the saturation voltages of MN7 and MP3

Running and Plotting

Adding the following line to our control file will run a dc sweep analysis from 0 to 1V in 5mV increments.

dc v2 0 1 5m

Let’s see what gain we have.

plot vgst_mp3 vgst_mp2 vgst_mn7 vgst_mn5
plot av av1 av2
Device Region

Device Region

Here we can see he typical operating regions of MP2, MN7 and MN5 are subthreshold, since Vgst’s are below 0V. MP3 is operating in the saturation region.


Gain Curves From dc

Gain Curves From a dc Sweep

This is interesting. What this is telling us that in the middle of the sweep where perhaps we might be most interested, stage 1 gain is ~45.6dB, stage 2 gain is ~36.7dB giving us an overall gain of 82.4dB.

Another perhaps more interesting aspect is that this graph clearly shows how the dc operating point drastically effects gain. This demonstrates clearly why, when designing an opamp, one should look at stability at multiple operating points.

What’s going on here is that at zero volts input, with vout at its maximum, MN7 is in the triode region. Due to the interaction of the output resistance of MN7 and the feedback network, MN7 is unable to pull vout to VDD. This causes an offset of about 5mV at the input which in turn causes the output of Stage 1 (s1) to pull almost to ground as the loop tries in vain to pull the output up to the rail. As Vin increase, the current at the output required to keep the loop steady reduces. MN7 gradually comes out of the triode region, the offset reduces and the gain of stage 1 rises to its nominal design value.

As the input voltage rises the the positive supply rail, the output voltage tries to fall to zero. In this case, the loop tries to pull the output of the first stage (s1) all the way to the rail in order to cut off MP3. MN7 enters the triode region at Vin ~950mV meaning the output voltage is limited by the source/drain resistance of MN7 and the feedback network.

Once again all this can be visualized in NGSPICE.

let vds_mn7 = v(vout)
let vds_mp3 = v(vdd)-v(vout)
let vdsat_mn7 = @m.x1.mn7[vdsat]
let vdsat_mp3 = @m.x1.mp3[vdsat]
plot vdsat_mn7 vdsat_mp3 vds_mn7 vds_mp3

VDS VDSAT of MN7 and MP3

VDS VDSAT of MN7 and MP3

As you recall, this theoretical process contains only low voltage NMOS and PMOS devices. This means we are forced to compensate the amplifier with a MOSCAP. In this case, most, though not all of the MOSCAP value can be seen by looking at CGG in the small signal model

let cc = @m.x1.mp7[cgg]
plot cc
Compensation Cap Approximation

Compensation Cap Approximation

Which looks really nasty! Another reminder if one were needed that ac or stability analysis should be carried out over a range of operating conditions.

Another thing we can do is visually compare the 1/gm of MP3 to the 1/gds (rds) of the RHPZ compensation device MP8. This allows us to adjust the size of MP8 to get the correct value to cancel out the right half plane zero.



The Proof of the Pudding!

At this point we’ve carried out a DC sweep analysis on a low voltage opamp using NGSPICE and we have ascertained that the open loop gain should be 82.4dB and the first stage gain 45.6dB for an inverting opamp with Rfb = 500k, VDD=1V and Vin=Vref=0.5V. We can do an AC analysis to see how this correlates.

set sourcepath = ( /projects/student/data/netlist/lv_opamp/ )
source lv_opamp_ac_tb.net

save all
ac dec 20 1 1G

let phase=180/PI*vp(vout)
let mav = -1*vdb(vout)

echo “—-”
echo “—-”
meas ac open_loop_gain find vdb(vout) at=1
meas ac stage_1_gain find vdb(x1.s1) at=1
meas ac dominant_pole when phase=135
meas ac gm_db find mav when vp(vout)=0
meas ac pm_deg find phase when vdb(vout)=0
meas ac pole_2 when phase=45
meas ac gbwp when vdb(vout)=0

echo “—-”
echo “—-”

plot vdb(vout) phase vdb(x1.s1)

LV Opamp Bode Plot

LV Opamp Bode Plot

open_loop_gain = 8.227636e+01
stage_1_gain = 4.561061e+01
dominant_pole = 3.987632e+02
gm_db = 1.351422e+01
pm_deg = 4.695887e+01
pole_2 = 4.678820e+06
gbwp = 4.448977e+06

Stage 1 gain is indeed shown to be 45.6dB while the open loop gain is shown to be 82.2dB, so we have successfully adjusted the gain a 2 stage opamp using nothing but a DC sweep.

We can now use this analysis technique along with AC and/or STB analysis to optimize the design.

Justin Fisher

Ingenazure LLC


Leave a reply

Your email address will not be published. Required fields are marked *

WordPress spam blocked by CleanTalk.
Back to Top