Categories
Simulation

More on Subthreshold MOS Design

Following on from my last post, “Designing in the Subthreshold Region with NGSPICE“. In this post I mentioned that unlike designing in the saturation region, device width has little or no effect on device transconductance.

Saturation Region gm

\[ gm= \sqrt{2k’\frac{W}{L}I_{D}} \]

Subthreshold Region gm

\[ gm=\frac{I}{nV_t} \]

Here is a circuit and NGSPICE simulation to demonstrate the point.

NMOS Test Bench
NMOS Test Bench

Here we have 2 NMOS devices configured as diodes each supplied with 1µA pulsed currents

MN1 has dimensions W=L=2µm so as to be in the saturation region with a 1µA source. MN2 has dimensions W=2µm L= 250nm so as to be in the subthreshold region with a 1µA source

We will now set up an NGSPICE simulation to show the effect of varying device width on both devices.

[box style=”2″ ]
.control

set sourcepath = ( /projects/student/data/netlist/nmos/ )
source nmos_tb.net

save all
save @mn1[vgs] @mn1[vth] @mn1[vds] @mn1[vdsat] @mn1[gm] @mn1[gds]
save @mn2[vgs] @mn2[vth] @mn2[vds] @mn2[vdsat] @mn2[gm] @mn2[gds]

foreach width1 100n, 200n, 400n, 800n, 1.6u
alter @mn1 w = $width1

tran 1n 50n

meas tran D1 find v(drain1) AT=50n
meas tran D2 find v(drain2) AT=50n

let vgst1 = (@mn1[vgs]-@mn1[vth])
let vgst2 = (@mn2[vgs]-@mn2[vth])

plot tran1.@mn1[gm] tran2.@mn1[gm] tran3.@mn1[gm] tran4.@mn1[gm] tran5.@mn1[gm]
plot tran1.vgst1 tran2.vgst1 tran3.vgst1 tran4.vgst1 tran5.vgst1

end

foreach width2 2u, 3u, 5u, 10u, 20u
alter @mn2 w = $width2

tran 1n 50n

meas tran D1 find v(drain1) AT=50n
meas tran D2 find v(drain2) AT=50n

let vgst1 = (@mn1[vgs]-@mn1[vth])
let vgst2 = (@mn2[vgs]-@mn2[vth])

plot tran6.@mn2[gm] tran7.@mn2[gm] tran8.@mn2[gm] tran9.@mn2[gm] tran10.@mn2[gm]
plot tran6.vgst2 tran7.vgst2 tran8.vgst2 tran9.vgst2 tran10.vgst2

end

.endc

[/box]

What’s Going On?

What we are doing here is setting the width of MN1 to 100nm, 200nm, 400nm, 800nm and 1.6µm. Each time we set the width of this device, we run a transient simulation. We then plot the values of gm and Vgst of MN1 for each run.

We then set the width of MN2 to 2µm, 3µm, 5µm, 10µm, 20µm and do as before.

Simulation Results

Here are the transconductance and Vgst curves of MN1. Looking first at the Vgst curve, we can see that the looking at the fist run, represented by the red line, through to the last run represented by the brown line, Vgst is above 0V all the time, so we’re in the saturation region.Only just in the case of W=1.6µm.

Looking at the transconductance curves for this device, we see that varying the width of the device changes the transconductance from ~6.5µS to ~18µS. So for a 16X increase in width, we see a 3X change in transconductance

Vgst MN1
Vgst MN1
gm MN1
gm MN1

Here are the transconductance and Vgst curves of MN2. Looking first at the Vgst curve, we can see that the looking at the fist run, represented by the red line, through to the last run represented by the brown line, Vgst is below 0V all the time, so we’re in the subthreshold region.

Looking at the transconductance curves for this device, we see that varying the width of the device changes the transconductance from ~22.5µS to ~24.8µS.

In this case the width of the last run is 10X that of the first, yet we see almost no change in transconductance at all.

Vgst MN2
Vgst MN2
gm MN2
gm MN2

[profile name=”Justin Fisher” role=”CEO Ingenazure LLC” twitter=”https://twitter.com/ingenazure” facebook=”https://www.facebook.com/ingenazure” linkedin=”https://www.linkedin.com/company/ingenazure” ]Ingenazure LLC[/profile]

Categories
Methodology NGSPICE

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;

[one_third][math]gm=\sqrt {2.k’\frac{W}{L}.Id}[/math][/one_third] [one_third]and[/one_third] [one_third_last][math]Ro=\frac{1}{\lambda.Id}[/math][/one_third_last]

[one_third]So[/one_third] [one_third][math]Av\approx\frac{1}{\lambda}.\sqrt \frac{2k’WL}{Id}[/math][/one_third] [one_third_last][/one_third_last]

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:

[one_third][math]gm=\frac{Id}{N.Vt}[/math][/one_third] [one_third]where N is a process constant[/one_third] [one_third_last][math]Ro=\frac{1}{\lambda.Id}[/math][/one_third_last]

[one_third]so[/one_third][one_third][math]Av = gm.Ro = \frac{1}{N.\lambda.Vt}[/math][/one_third][one_third_last][/one_third_last]

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:

[math]Av = gmRo = \frac {VA}{Vt}[/math]

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.

lv_opamp_dc_sweep_tb
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.

[box style=”1″]

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]
[/box]

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.

[box style=”1″]
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]
[/box]

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.

[box style=”1″]
dc v2 0 1 5m
[/box]

Let’s see what gain we have.

[box style=”1″]
plot vgst_mp3 vgst_mp2 vgst_mn7 vgst_mn5
plot av av1 av2
[/box]

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.

[box style=”1]

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

[/box]

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

[box style=”1]
let cc = @m.x1.mp7[cgg]
plot cc
[/box]

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.

RHPZ GDS and GM_MP3
RHPZ GDS and GM_MP3

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.

[box style=”1]
.control
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)
.end
.endc
[/box]

LV Opamp Bode Plot
LV Opamp Bode Plot

[box style=”1]
—-
—-
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
—-
—-
[/box]

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.

[profile name=”Justin Fisher” role=”CEO Ingenazure LLC” twitter=”https://twitter.com/ingenazure” facebook=”https://www.facebook.com/ingenazure” linkedin=”https://www.linkedin.com/pub/justin-fisher/1/255/273″ ]Ingenazure LLC[/profile]

Categories
Methodology NGSPICE Simulation

AC and Stability Analysis in NGSPICE.

To help the reader out, I’ve posted some helpful files dealing with simulating a LM358 opamp macro from ON semiconductor here.

AC Analysis and Breaking the Loop

The above example shows an AC analysis test-bench GSCHEM. In this example the loop is broken by R3 whose value at dc is 1mΩ and is changed to 1TΩ for ac analysis. Doing this enables NGSPICE to converge on a sensible dc operating point for open loop analysis without any imperfections such as input offset forcing the output to one of the supply rails.

But There are 2 Opamps in this Example!

Indeed there are. One major drawback of AC analysis is that it when the loop is broken, it decouples the loop output from its feedback node. In the case of a MOS opamp for instance, that may have been designed for low noise applications, meaning the input pair is quite large, the input capacitance of the opamp an have a major impact on loop stability when coupled with its output impedance and feedback network impedance. Breaking the loop means the interaction between these two impedances is not simulated. This can create misleading results which will not correlate with a transient analysis on the same circuit.

In order to model this combination of impedances, at least to a first order, we add a second opamp to the output of the first.

Simulating the Loop

In this scenario we netlist the schematic, then create a control file as follows. NGSPICE is run on the control file which sources the schematic netlist. It is not run directly on the netlist.

It is important to leave a free line at the top of the control file. See the download material.

[box style=”1 or 2″ background=”IMG URL or Color Value”]

.control
set sourcepath = ( /projects/student/data/netlist/lm358/ )
source lm358_ac_tb.net

save all
ac dec 20 0.01 1G

let phase=180/PI*vp(vout)

echo “—-”
echo “—-”
meas ac gm_db find vdb(vout) when vp(vout)=0
meas ac pm_deg find phase when vdb(vout)=0
meas ac 3db_f when phase=135
meas ac 0db_f when vdb(vout)=0
meas ac dc_gain find vdb(vout) at=1
echo “—-”
echo “—-”

plot vdb(vout) phase
write /projects/student/data/raw/lm358/lm358ac_tb.raw all

.endc

[/box]

What’s Going On Here?

  1. Blank line. This is important.
  2. .control – start of the control file
  3. set sourcepath – This defines the directory where our netlist lives
  4. source – This is the netlist we will be simulating.
  5. save all – Saves all voltage and currents.
  6. ac dec 20 0.01 1G – Performs an ac analysis, 20 points per decade from 10mHz to 1GHz
  7. let phase=180/PI*vp(vout)  – ac analysis in NGSPICE gives us phase in radians. This line converts the phase at node vout to degrees.
  8. meas ac gm_db find vdb(vout) when vp(vout)=0 – Find the value of vout in dB’s when phase =0. This last part could be written “when phase =0” The value is stored to gm_db and is our gain margin.
  9. meas ac pm_deg find phase when vdb(vout)=0 – finds the value of vout phase when vout =0dB and stores it to pm_deg. This is our phase margin.
  10. meas ac 3db_f when phase=135 – measures the frequency when phase is 135 degrees and stores it to 3db_f. Since the opamp in the test-bench is set up in inverting mode, the “dc” phase is 180°. 180-45=135, so this is our dominant pole.
  11. meas ac 0db_f when vdb(vout)=0 – measures the frequency when vout crosses 0dB. This is our unity gain frequency.
  12. meas ac dc_gain find vdb(vout) at=1 – measures the dc gain in dB at 1Hz. This is our dc gain.
  13. plot vdb(vout) phase – gives us our Bode plot. See below.
  14. write /projects/student/data/raw/lm358/lm358ac_tb.raw all – writes the simulation data to a file. Useful if we want to look at the data once NGSPICE has closed down.
  15. .endc – ends the control file

This gives us the following results:

[box style=”1 or 2″ background=”IMG URL or Color Value”]

pm_deg = 9.140923e+01
3db_f = 1.009493e+01
0db_f = 9.142381e+05
dc_gain = 9.908845e+01

Note: We defined gain margin in the measures section, but no gain margin is reported here. Looking at the Bode plot, we see that the phase does not traverse 0° and so gain margin cannot be reported. This is a limitation of the macro-model.

[/box]

AC Bode Plot
AC Analysis Bode Plot

But Is There a More Accurate Method?

As it happens, yes. More than one. Back in the early days of my career, I was working on high frequency control systems for the UK defense industry. We needed to know what the open loop response of our amplifier was to ensure it met our design criteria. These amplifiers were discrete, so severing the loop connection as one can do in an ideal SPICE simulation was not possible. What we did was to use a Nichols Chart in reverse.

Nathanial B. Nichols (1914-1997) was one of the original control theory gurus. He was known mainly for his book “The Theory of Servomechanisms” He gave his name the the Nichols chart.

The principle use of a Nichols chart is to derive the closed loop transfer function of a servo system from its open loop behavior. It follows then that one may derive open loop behavior from the closed loop response. It was always tricky drawing closed loop behavior  on a Nichols chart…but I digress.

The Middlebrook Method

In 1975 Dr R. David Middlebrook (1929 – 2010) published his seminal paper “Measurement of Loop Gain in Feedback Systems” (International Journal of Electronics, Vol 38, No. 4 pages 485-512, 1975)

In this paper Middlebrook describes mathematically how to derive the open loop transfer function of an amplifier from its closed loop behavior, even if the loop is unstable! Middlebrook was also coming at this from a point of view of determining open loop response in a discrete system, so as in my case above, without the use of a SPICE simulator.

His method was to inject (probe) an ac voltage into the feedback loop, sweep the ac over the frequency range of interest then do the same with an ac current source in the same spot. Armed with the closed loop voltage and current sweep information, one can derive the open loop transfer function. This is easily implemented in SPICE.

The Tian Method

In 2001 Tian et.al. derived an even more robust method of obtaining open loop response from a closed loop system. Middlebrook’s method relies on the ac voltage and current sources being orientated in a specific direction. However, it maybe that the user is interested in backward transmission. Tian’s approach is to use a little more math to derive the open loop response of a system regardless of how the ac probes are orientated.

Striving for Small-Signal Stability” Circuits and Devices Magazine, IEEE (Volume:17 , Issue: 1 ) pages 31 – 41  Jan 2001.

Using this approach the mainstream SPICE vendors created a stability analysis tool or STB analysis.

Stability Analysis in NGSPICE

As yet stability analysis (STB) is not included in NGSPICE as a stand-alone routine, however, we can use the Middlebrook and Tian (preferred) methods to do the same thing. It’s a little more involved than it would be in a commercial SPICE environment, but it’s the same thing.

Above is a circuit diagram to carry out our Middlebrook and Tian stability analysis. It’s based on the same opamp macro as before. In this case, since the loop is never broken a second opamp is not necessary to model the closed loop impedance interactions.

In this test-bench, the ac resistor in the previous example is replaced by two voltage sources both of 0V dc (thus the closed loop is maintained) and a 0A ac current source to ground.

We run 2 ac analysis. In the first, we set the ac value of Vprobe1 to 1 and the ac value of Iprobe 1 to zero. In the second the ac values of these 2 sources are reversed.

As in the previous example, we netlist the schematic then create a control file to run in NGSPICE.

It’s important to keep in mind here that unlike ac analysis, stability analysis gives us loop gain as opposed to open loop gain. In the above example, since the ac is injected between the opamp output and the feedback input, the circuit ends up looking like a non-inverting amplifier. In our case, since the feedback network consists of 2 identical resistors, this should look like a gain of 2 – non-inverting rather than 1 – inverting. In this case, the loop gain will be 6dB lower than the open loop gain seen in the ac analysis.

[box style=”1 or 2″ background=”IMG URL or Color Value”]

.control
set sourcepath = ( /projects/student/data/netlist/lm358/ )
source lm358_stb_tb.net

let runs=2
let run=0

alter @Vprobe1[acmag]=1
alter @iprobe1[acmag]=0

dowhile run < runs
set run =”$&run”
set temp = 27

ac dec 20 0.01 1G
write /projects/student/data/raw/lm358/lm358_stb_tb_{$run}.raw all

alter @Vprobe1[acmag]=0
alter @iprobe1[acmag]=1

let run = run + 1

end

let ip11 = ac1.i(vprobe1)
let ip12 = ac1.i(vprobe2)
let ip21 = ac2.i(vprobe1)
let ip22 = ac2.i(vprobe2)
let vprb1 = ac1.probe
let vprb2 = ac2.probe

let mb = 1/(vprb1+ip22)-1

let av = 1/(1/(2*(ip11*vprb2-vprb1*ip21)+vprb1+ip21)-1)

let phase=180/PI*vp(av)
let phase_mb = 180/PI*vp(mb)
plot vdb(av)
plot phase
plot vdb(mb)
plot phase_mb
plot vdb(mb) vdb(av)
plot vdb(av) phase

echo “—-”
echo “—-”

meas ac gm_db find vdb(av) when vp(av)=0
meas ac pm_deg find phase when vdb(av)=0
meas ac 3db_f when phase=135
meas ac 0db_f when vdb(av)=0
meas ac dc_gain find vdb(av) at=0.01
meas ac m6dB when vdB(av)=-6

echo “—-”
echo “—-”

.endc [/box]

What’s Going On Here?

  1. Blank line. This is important.
  2. .control – start of the control file
  3. set sourcepath – This defines the directory where our netlist lives
  4. source – This is the netlist we will be simulating
  5. let runs=2 – the runs variable will be used to efine how many times we run NGSPICE. In this case 2
  6. let run=0 – defines the current run number
  7. alter @Vprobe1[acmag]=1
  8. alter @iprobe1[acmag]=0 – these 2 lines set up the relevant source the ac simulation will use for analysis. In this case, these lines are not strictly necessary. If you look at the circuit diagram above, you will see that this is how those two sources are set up anyway.
  9. dowhile run < runs – this sets up a simulation loop. The following lines will loop back to this point as long as the variable runs is less than the variable run
  10. set run =”$&run”  – creates a variable so we know which run is which when we process the results
  11. set temp = 27 – set the simulation temperature. Irrelevant in this case, but good practice in general
  12. ac dec 20 0.01 1G – Performs an ac analysis, 20 points per decade from 10mHz to 1GHz
  13. write /projects/student/data/raw/lm358/lm358_stb_tb_{$run}.raw all – writes the simulation data to a raw file appended by the run number.
  14. alter @Vprobe1[acmag]=0
  15. alter @iprobe1[acmag]=1 – as per lines 7 and 8 This swaps the sources the ac analysis will use for the second run
  16. let run = run + 1 – increments the run number for the loop
  17. end – ends the loop
  18. let ip11 = ac1.i(vprobe1)
  19. let ip12 = ac1.i(vprobe2)
  20. let ip21 = ac2.i(vprobe1)
  21. let ip22 = ac2.i(vprobe2)
  22. let vprb1 = ac1.probe
  23. let vprb2 = ac2.probe – these lines are added to make the later math simpler to write
  24. let mb = 1/(vprb1+ip22)-1 – this defines the Middlebrook open loop response
  25. let av = 1/(1/(2*(ip11*vprb2-vprb1*ip21)+vprb1+ip21)-1)  – this defines the Tian open loop response
  26. let phase=180/PI*vp(av) – defines the phase of av in degrees
  27. let phase_mb = 180/PI*vp(mb) – defines the phase of mb in degrees
  28. plot vdb(mb) vdb(av) – plots the Middlebrook and Tian voltage gain in dB on the same axis
  29. plot vdb(av) phase – a Bode plot of the Tian method
  30. meas ac gm_db find vdb(av) when vp(av)=0 – finds the voltage gain when the phase goes through zero – our gain margin
  31. meas ac pm_deg find phase when vdb(av)=0 – measures the phase in degrees when av = 0dB – our phase margin
  32. meas ac 3db_f when phase=-45 – measures the frequency where the phase goes thought -45° – This is our dominant pole
  33. meas ac 0db_f when vdb(av)=0 – measures the frequency where the loop gain goes through zero. Since this is loop gain and not open loop gain, this will not be the same as the ac example above.
  34. meas ac dc_gain find vdb(av) at=0.01 – measures the loop gain. This should be 6dB lower than the ac example
  35. meas ac m6dB when vdB(av)=-6 – measures the frequency where the gain curve goes below -6dB. This should be the same as the unity gain bandwidth in the ac example
  36. .endc – ends the control section

This gives us the following results:

[box style=”1 or 2″ background=”IMG URL or Color Value”]

pm_deg = -8.923940e+01
3db_f = 9.988710e+00
0db_f = 4.779122e+05
dc_gain = 9.358252e+01
m6db = 9.538196e+05

Note:

  • As per the ac analysis earlier, we cannot measure gain margin
  • You will notice some subtle differences. The less accurate ac analysis gave us a phase margin of 91.4°. The more accurate Tian method reports  89.23°
  • As expected dc gain is 6dB less than the ac analysis
  • 0dB frequency is not the same as in the ac case, since in this case 0dB is where the loop gain goes through zero. Given that the closed loop gain is 6dB, then the point at which the gain curve goes through -6 should correspond to the ac analysis 0dB frequency. Again, due to inaccuracies in the ac method, we do see a slight difference here.

[/box]

Middlebrook and Tyan methods. AV curves are overlayed showing no difference
Middlebrook and Tian methods. AV curves are overlayed showing no difference
Tyan Method Bode plot
Tian Method Bode plot

This example was derived from work originally carried out by Frank Wiedmann which you can find at https://sites.google.com/site/frankwiedmann/loopgain. Of particular interest is a breakdown of the math used in Middlebrooks general feedback theorem which you can find here.

Special thanks to Robert Larice for invaluable help with the NUTMEG language in NGSPICE.

[profile name=”Justin Fisher” role=”CEO Ingenazure LLC” twitter=”https://twitter.com/ingenazure” facebook=”https://www.facebook.com/ingenazure” linkedin=”https://www.linkedin.com/pub/justin-fisher/1/255/273″ ]Ingenazure LLC[/profile]

Insert math as
Block
Inline
Additional settings
Formula color
Text color
#333333
Type math using LaTeX
Preview
\({}\)
Nothing to preview
Insert