Monday, July 30, 2012

Worst-Case and Temperature Analysis with LTSpice

In a previous posting (here) I discussed using Linear Technology's SPICE program (LTSpice IV) to perform Monte Carlo and Worst Case circuit analysis.

When doing these sorts of analyses, I usually also want to know how the circuit performs at temperature extremes  to ensure that, given the temperature characteristics of semiconductor junctions, the circuit's performance is still acceptable.  So, while analyzing the circuit for worst-case component variations, I can simultaneously use the SPICE .step command to step the temperature (in degrees Celsius) over the range I'm interested in.

Here's a simple circuit demonstrating this:

 (click on image to enlarge)

This is a comparator circuit in which the reference voltage is set by a zener diode, D1.  I'd like to know how this circuit performs at the temperature extremes of -55 and +125 degrees C, as well as how it performs for the worst-case resistor values, given their tolerance of 1%.  So there are two .step commands:  one to vary temperature and one to vary resistor values.

Because I'm only interested in the two temperature extremes and not in any intermediary temperatures, I'm going to define the temperature to step from -55 degrees to +125 degrees in a single step of 180 degrees.  The command is:

.step temp -55 125 180

(Note that if I wanted to step the temperature between these two limits in, say, 10 degree increments,  the command would be:  .step temp -55 125 10).

The second .step command defines that there will be 50 runs, for each of which the values of the resistors will be randomly varied between their worst-case values (as defined by their tolerances).

So we have two .step commands, one which will vary temperature between 2 values, and the other which will perform 50 worst-case runs.  Spice nests the step commands, so, overall, there will be a total of 100 runs performed (2 temp runs for each of the 50 worst-case runs).

This circuit has hysteresis (via R7), but what effect will it have on the switching threshold, given that a zener is used for the reference voltage?  I'll define the input voltage source V1 to linearly ramp up from 9 to 15V and then to ramp back down to 9V over a 1 second period (there may be a simpler way of doing this with SPICE, but this method works, too), to check performance during low-to-high and high-to-low transitions.

Below are the plots from the 80 runs, showing how the comparator threshold changes due to component tolerances and temperature variations (component tolerance, even though 1%, results in the greatest variation in performance).  The left half of the plot shows the comparator threshold as the input voltage increases from low to high, and the right half shows it as the input voltage decreases from high to low.

 (click on image to enlarge)
Here's a plot showing how the voltage at the node "V+" (the node attached to the zener diode) changes between the two temperature extremes (there's about a 50 mV delta):

  (click on image to enlarge)

Additional Notes

1.  As mentioned, this circuit has two step sweeps:  one for temp and one for run (in which the resistor values are varied for worst-case analysis).  Note that LTSpice allows step sweeps to be nested up to three deep.

2.  LTSpice is available, for free, from Linear Technology, and can be found here.

Sunday, July 29, 2012

Monte Carlo and Worst-Case Circuit Analysis using LTSpice

SPICE is a handy tool for evaluating circuits without having to first breadboard them, and through its "directives," it provides a powerful method for analyzing how a circuit might perform with components exhibiting real-world tolerances.

One such method of "real-world" analysis is Monte Carlo analysis, which, with each new analysis run, randomly varies parameters (within their user-defined limits) to give the user a useful picture of actual circuit performance.

However, as a circuit designer, I'm most often interested in worst-case performance.  That is, I want to know how a circuit performs at the extremes of component values, to ensure that  I've met whatever design specification I'm designing to.  And although Monte Carlo analysis can tell me what the performance is at these limits, if the circuit contains many components, it can take quite a lot of runs before its random selection of parameter values happens to simultaneously correspond to the worst-case limits of all of the components (and it's quite possible that I'll never see the true worst-case limits -- after all, it's a matter of chance).

To truly evaluate performance at a circuit's worst-case limits, we can perform a "worst-case" analysis in lieu of a Monte Carlo analysis.  This analysis has an added advantage, too, in that not as many runs are required to ensure that we've truly evaluated all of the components over all possible variations in their tolerances -- after all, we don't need to measure between the tolerances limits (which is what Monte Carlo analysis does).  For example, if one of the components is a 10K ohm resistor with a 5% tolerance, worst-case analysis will only use resistance values of 10.5K and 9.5K for this component  and not any other value between these limits (whereas Monte Carlo analysis would randomly use any value between, and including, these limits).

Linear Technology's LTSpice can handle both Monte Carlo analysis as well as worst-case analysis.  Unfortunately, it's not obvious how to do this from their "Help Topics."  For example, "Monte Carlo", when entered into LTSpice's search field, returns no results.  Not much use, that!

Nevertheless, LTSpice does indeed have a pre-defined Monte Carlo function.  This is the "mc" function, and a search of the Help Topics for "mc" will point to the .PARAM topic, and under this heading we find the function mc (x,y), which, when invoked, returns a "random number between x*(1+y) and x*(1-y) with uniform distribution."

To use this function, rather than define a resistor's value as, say, 10K, we define it as "{mc(10K,0.05)}", where 10K is its nominal value, and 0.05 is its tolerance (5%).  (An example will follow below).

OK, so the predefined mc function handles Monte Carlo analysis, but there is no pre-defined "worst case" function.   We need to create this ourselves, but it's not too difficult.  This can be done using Spice's ".function" directive.  Here's an example of a function for worst-case analysis (we'll use this later, too):

     .function wc_a(nom,tola) if (run == 1, nom, if(flat(1)>0,nom*(1+tola),nom*(1-tola)))

In this definition:
  • .function is the Spice directive for defining a function.
  • wc_a is the name I've given this instance of this worst-case function.
  • nom is the "nominal" value (e.g. 10K for a 10K resistor).
  • tola is the tolerance (defined elsewhere with a .param directive (e.g. 0.1 for a 10% tolerance)).
  • run is a variable (defined elsewhere in the .step directive) identifying the current run count).
  • flat(1) is a Spice function that returns a random number between -1 and 1. 
(Note that the definition of .function and flat can both be found in LTSpice Help).
So how do we use this function we've just defined?

Take as an example a 10K ohm resistor.  Normally, we'd just label its value in the LTSpice schematic as "10K".  However, to vary its value between its worst-case values, we instead use a more complex label for its value.  Rather than entering "10K", in this case we'll enter "{wc_a(10K,tola)}" into the component's value field.  (Note the use of the curlicue brackets).

So what happens when we run the analysis?

If this is the first analysis run (run is defined elsewhere in the .step directive and simply is the current run being performed), then, because run = 1, the function returns the value assigned to nom, in this case, 10K.

But for each new run after the first run, and for each component defined with a wc_a function, the function flat(1) is re-evaluated for that component.  If the random result returned from flat(1) is greater than 0, then the tolerance is added to the component's nominal value (e.g. for a resistor whose nominal (nom) value is 10K, if tola is 0.1 (10% tolerance), the resistor's value is set to 11K).  Otherwise, the tolerance is subtracted from the component's nominal value (e.g. the 10K resistor is set to 9K).

Here's a demonstration of both Monte Carlo and Worst Case analysis.  Consider this basic circuit: 

(Click on image to enlarge)

Given these component values, a frequency sweep of the input from 1 Hz to 1KHz shows that the circuit has the following gain and phase transfer function when measured at its Vout node:

(Click on image to enlarge)

But what happens when the component values vary over their tolerance range?  Let's suppose that the resistors have 10% tolerance and the capacitors have 20% tolerance.  Let's perform a Monte Carlo analysis on this circuit, given these tolerance values. The same circuit, but now set up with its Monte-Carlo functions and .param directives, looks like this:

(Click on image to enlarge)

(Note that within the "mc" function, I'm not setting the tolarance field to an actual number (although I could have done it this way, too).  Instead, I'm using a separate directive (.param) to define the tolerances (in this case, 10% and 20%) globally.)

Running the Monte Carlo analysis 1000 times (via the directive ".step param run 1 1000 1") gives us the following spread of gain and phase plots:

(Click on image to enlarge)

But we can't be sure that we've truly evaluated worst-case performance.  So let's instead use our new "worst-case" function for a worst-case evaluation.  Because there are two component tolerances for the components in the schematic (the resistors are 10% and capacitors are 20%), we'll define two worst-case functions:  wc_a and wc_b.  The function wc_a will vary the value of those components whose tolerance is labeled "tola" (in this example, tola = 10%).  Similarly, the function wc_b will vary the value of those components whose tolerance is labeled "tolb" (in this example, tolb = 20%).

The schematic, with its new Spice directives and functions, now looks like this:

(Click on image to enlarge)

And the analysis output, after 40 runs, looks like this:

(Click on image to enlarge)

Note the discrete intervals between plots.  This is because the worst-case analysis is only using component values that are at the +/- tolerance limits for each component, and not any intermediary values (except for the first of the 40 plots, which uses the nominal component values for its analysis).


Further information on Worst-Case and Temperature Analysis can be found here:

Also -- there may be easier ways of doing both Monte Carlo and Worst Case analysis with LTSpice.  The approaches above are the methods I've gleaned from LTSpice's Help and from Googling the Internet.  If there are better ways to do these, please let me know!

[Note: (21 September 2012)  For a possible way of simplifying worst-case analysis, see the comment section below.]


LTSpice is available for free from Linear Technology.  You can find it here.