home : articles : How to Find Input Capacitance Using Spice
Spice is the circuit designer's Swiss Army knife. We use it whenever we need to precisely determine the properties of our circuits. This page shows how to find the input capacitance of a node (usually the input of a digital circuit, like an inverter) using Spice.
The First Rule of Using Spice is Don't Use Spice
You build a CMOS inverter for your boss and she asks you what the input capacitance is. You answer: “I'm not sure, but I will find out right away!” What you should have been able to say to her is: “Well, boss, the first thing I did was to familiarize myself with the 12nm CMOS process and I found that the input capacitance is 0.8 fF/μm, so of course my 7μm PMOS, 3μm NMOS inverter has about 8 fF of input capacitance. ” But you didn't say that, because you didn't know. You are a spice monkey.
Don't be so dependent on Spice. You should always be able to predict an approximate answer to simple questions like this without resorting to a Spice simulation. The typical things you should know about the transistor process you are designing in: gate capacitance per unit width of transistor gate (for minimum length), diffusion capacitance per unit area, effective resistance (when used in a digital gate) in Ω·μm, and fanout-of-4 (FO-4) delay. Of course, you need a way to find all these parameters and even though approximations these parameters are very useful for choosing topologies and calculating results to a first order, eventually you need more precise quantities. For those cases, Spice is the right tool.
To paraphrase Sun Tzu in The Art of War:
If you know Spice and yourself, you need not fear the result of a hundred simulations. If you know yourself but not Spice, for every successful simulation you will also suffer a defeat. If you know neither Spice nor yourself, you will succumb in every simulation.
The Spice Deck Using a Data Sweep
One way to find capacitance using Spice is to build two copies of your circuit. One copy is loaded by the capacitive device that you are trying to characterize and the other copy is loaded by a simple capacitance (a C element in Spice) with the amount of capacitance set as a parameter. You then sweep through a series of values for the C, finding the value that causes the circuits to match. The way they match is up to you. Common methods of matching circuits is in terms of rise delay, fall delay, rise time (10% to 90%) or fall time (90% to 10%).
The Spice deck below shows an example of sweeping the capacitance CLOAD to find the input capacitance of the inverter Xinv0_load. We find its capacitance by finding the value of CLOAD that causes the two circuits to have the same average delay—measured from the 50% crossing point of the input waveform to the 50% crossing point of the output waveform and averaged for a rising and falling edge. Once we know this value of CLOAD, we know it is equivalent to the input capacitance of Xinv0_load for the purpose of finding rise/fall time.
The basic structure of the Spice deck below is to instantiate the appropriate power supplies, input signal waveform, the first circuit consisting of inverters Xinv0_driver and Xinv0_load , and the second circuit consisting of Xinv1_drive (the same as Xinv0_driver) and the capacitance parameterized with CLOAD.
The sweep notation in the .tran analysis statement runs multiple simulations with a range of values for the parameter CLOAD.
* Find the input capacitance using sweep method .lib 'my-transistor.lib' TT .temp 25 .param vd=1V * Power supplies Vvdd vdd 0 dc vd Vvss vss 0 dc 0 * Input waveform Vin in 0 PULSE 0 vd 100ps 80ps 80ps 500ps 1u * First circuit, uses the load we are trying to characterize Xinv0_driver mid0 in vdd vss inv WP=2 WN=1 Xinv0_load out0 mid0 vdd vss inv WP=10 WN=5 * Second circuit, uses a parameterized load capacitor Xinv1_driver mid1 in vdd vss inv WP=2 WN=1 Cload mid1 vss CLOAD * Measure rising and falling edge (with respect to the output edge) time delays for * the real copy of the circuit. .measure TRAN tdr TRIG v(in) VAL='0.5*vd' FALL=1 TARG v(mid0) VAL='0.5*vd' RISE=1 .measure TRAN tdf TRIG v(in) VAL='0.5*vd' RISE=1 TARG v(mid0) VAL='0.5*vd' FALL=1 .measure TRAN tdavg PARAM='(tdr+tdf)/2' * Measure the same parameters for the model circuit loaded by CLOAD .measure TRAN tdrc TRIG v(in) VAL='0.5*vd' FALL=1 TARG v(mid1) VAL='0.5*vd' RISE=1 .measure TRAN tdfc TRIG v(in) VAL='0.5*vd' RISE=1 TARG v(mid1) VAL='0.5*vd' FALL=1 .measure TRAN tdavgc PARAM='(tdrc+tdfc)/2' .tran 1ps 1ns SWEEP data = info .data info CLOAD 10fF 11fF 12fF 13fF 14fF 15fF 16fF 17fF 18fF 19fF 20fF .enddata .subckt inv out in pow gnd WP=2u WN=1u mn out in gnd gnd W=WN L=LMIN * assume LMIN is defined in library mp out in pow pow W=WP L=LMIN * assume LMIN is defined in library .ends .probe v(*) .end
Notice that the sweep in this deck steps in increments of 1fF. So if you need a more precise value, either run more steps in the sweep, or do a second sweep, once the first sweep has bracketed the capacitance with within one fF.
Since the real input capacitance of Xinv0_load is nonlinear, even a highly precise sweep of CLOAD is an approximation, albeit one that is quite accurate. You can find the equivalent CLOAD to match some other parameter between the circuits, such as average 10%-to-90% rise/fall time. You will find that the resulting CLOAD will be somewhat different from the one that matches the circuits based on the average %50-to-%50 delay. It's best to match the circuits using the parameter(s) that you will later use CLOAD to find. So if you will be using CLOAD to predict dynamic power consumption, then it's a good idea to match the two circuits based on power consumption.
The Hspice Deck Using Built-in Optimization
There is another, more elegant way to find CLOAD using the built-in optimizer of Hspice, one of the commercial versions of Spice. If you use another flavor of Spice, or a variant like Spectre, there is probably an equivalent way of performing optimization, although the syntax may be slightly different.
The Hspice deck for find the matching CLOAD is presented below. The deck is largely the same as the sweep method above, with a few important changes. One change is the way the parameter CLOAD is initialized. We use the syntax OPTC(15FF, 1fF, 30fF), telling the iterative optimizer to start with 15fF as the initial CLOAD value and to freely range between 1fF and 30fF to find the solution. The second change is the addition of the GOAL=tdavg parameter to the .measure statement that defines tdavgc. This tells tells the optimizer that the it should strive to choose CLOAD such that tdavgc is equal to tdavg. The .tran statement is updated to indicate that this is an optimization analysis and it describes which measure statement to optimize (tdavgc in this case). Finally, we also add the line .model OPT1 opt to signal to Hspice that this is an optimization deck.
* Find the input capacitance using Hspice optimizer .lib 'my-transistor.lib' TT .temp 25 .param vd=1V .param CLOAD=OPTC(15fF, 1fF, 30fF) * Power supplies Vvdd vdd 0 dc vd Vvss vss 0 dc 0 * Input waveform Vin in 0 PULSE 0 vd 100ps 80ps 80ps 500ps 1u * First circuit, uses the load we are trying to characterize Xinv0_driver mid0 in vdd vss inv WP=2 WN=1 Xinv0_load out0 mid0 vdd vss inv WP=10 WN=5 * Second circuit, uses a parameterized load capacitor Xinv1_driver mid1 in vdd vss inv WP=2 WN=1 Cload mid1 vss CLOAD * Measure rising and falling edge (with respect to the output edge) time delays for * the real copy of the circuit. .measure TRAN tdr TRIG v(in) VAL='0.5*vd' FALL=1 TARG v(mid0) VAL='0.5*vd' RISE=1 .measure TRAN tdf TRIG v(in) VAL='0.5*vd' RISE=1 TARG v(mid0) VAL='0.5*vd' FALL=1 .measure TRAN tdavg PARAM='(tdr+tdf)/2' * Measure the same parameters for the model circuit loaded by CLOAD .measure TRAN tdrc TRIG v(in) VAL='0.5*vd' FALL=1 TARG v(mid1) VAL='0.5*vd' RISE=1 .measure TRAN tdfc TRIG v(in) VAL='0.5*vd' RISE=1 TARG v(mid1) VAL='0.5*vd' FALL=1 .measure TRAN tdavgc PARAM='(tdrc+tdfc)/2' GOAL=tdavg * We set the GOAL to tdavg which will cause the optimizer to try * select a CLOAD that forces tdavgc to match tdavg .model OPT1 opt .tran 1ps 1ns SWEEP OPTIMIZE=optc RESULTS=tdavgc MODEL=OPT1 .subckt inv out in pow gnd WP=2u WN=1u mn out in gnd gnd W=WN L=LMIN * assume LMIN is defined in library mp out in pow pow W=WP L=LMIN * assume LMIN is defined in library .ends .probe v(*) .end
This deck is elegant in that there no need to do multiple sweeps. Hspice will find the result to a useful precision. One caveat is that the general view amongst most circuit designers I know is that the Hspice optimizer is a piece of crap. It works just fine for simple optimizations like the one above, but can fail to converge or, even worse, give the wrong answer for optimizations of many variables. This deck is simple enough that I have never encountered a problem using it with the Hspice optimizer. To help Hspice converge to a solution as quickly as possible, it is a good idea to give a reasonable starting point and range for all optimization parameters.
Building A Library
The first time you have to perform a task like finding input capacitance it's worth taking the time to build a good Spice deck, whether you use the sweep method or optimization method or find your own more clever method. You will find that as you have to repeat these tasks, all you will have to do is brush off an old Spice deck, make some minor modifications and you'll be quickly done. Then you can spend your time doing real thinking and less simulating.
Did you find this article helpful? If you have further questions you would like answered in a tutorial article, please let me know, and I will consider writing an article about it.
(This article first posted January 2007.)