Integrated Capacitors

Capacitors are important in realizing most circuits.

A capacitor stores energy in an electric field between two “plates”. The basic equation for a capacitor is $C=\epsilon\frac{A}{d}$. As with most integrated devices, there are trade-offs between the desired aspects of the device and the undesired elements. Many different kinds of capacitors are available that make different trade-offs. The important properties we want in capacitors are:

1. Cost
2. Capacitor density: capacitance per unit area
3. parasitic capacitance: capacitance to other nodes besides the two plates we are interested in
4. parasitic resistance
5. parasitic inductance
6. leakage: appears as a parallel resistor
7. Breakdown voltage

Metal-Oxide-Metal (MOM) Capacitors

MOM capacitors are the most straight forward capacitors available in an integrated circuit process. They are especially useful in advanced digital optimized CMOS processes with many layers of interconnects. Several geometries can be used (from lowest to highest density): parallel plate, interdigitated (with or without via stack), rotative, and fractal. Vertical bars or vertical parallel plates usually give the best capacitance density, with slightly different trade-offs for C vs Q ($= \frac{1}{\omega RC}$).

MOM capacitors can be inexpensive for small values: no extra masks are required. But the low density makes large capacitors quite expensive in silicon area. Modern processes actively try to reduce interconnect parasitics using low-K dielectrics, so cap density trend is probably going lower. Some low-K dielectrics can have low breakdown voltages. The parasitic inductance and resistance will depend on the geometry.

Pros: no extra masks, or process options needed, good linearity

Cons: moderate bottom plate parasitic, low density, high series inductance and resistance, possibly low breakdown voltage,

MIM Capacitors

MIM capacitors are formed by sandwiching a thin dielectric between two metal layers. Typically the dielectric thickness is much smaller than IMD thickness. This requires more masks for the top electrode as well as the dielectric.

Pros: lower bottom plate parasitic, high density, good linearity, low

Cons: extra mask cost (offset by potentially lower area)

MOSCAP

Every MOSFET has a capacitor at it’s heart. All one needs to do is connect the source and drain together to make bottom plate and the gate serves as top plate. This capacitor is available in every process, but suffers from a severe limitation: It’s highly non-linear as the effective gate thickness is dependent on the bias applied. The applied gate voltage can change the concentration of carriers (holes or electrons) in the channel. At some voltage, the channel can be depleted of all carriers and the capacitance reaches a minimum. Voltages higher or lower will collect carriers in the channel and create a capacitor of reasonable value.

Enhanced MOSCAP on highly-doped diffusion

The obvious way to improve the MOSCAP linearity is to make sure the channel cannot be depleted. This improves the linearity a lot, to about 2-5% total variation. It is usually done with NMOS device because it is naturally in accumulation mode. Adding an extra implant pushes it further into accumulation. One extra mask can help achieve a better trade-off of density and cost.

Summary

Depending on the process available, the density, cost and linearity requirements, one can use one or more of MOM, MIM, MOSCAP, or enhanced MOSCAP. MOM is cheap, lowest density, and most linear. MIM cap is the most expensive, good density, and very linear. MOSCAP is cheapest, high density, and very non-linear. Enhanced MOSCAP is cheap, high-density, and somewhat linear.

Xyce on macOS Sierra

Xyce is a great free simulator. I recently tried to fire it up on macOS Sierra and ran into a dependency issue. I want to use the Open MPI version to take advantage of multiple cores. The version of Open MPI installed on my system is at a different path and a different version compared to the one Xyce was compiled with. Fortunately, on macOS there’s an easy work around:

otool -L /usr/local/Xyce-Release-6.5.0-OPENMPI-OPENSOURCE/bin/Xyce
install_name_tool -change \
/opt/openmpi/x86_64-icc-12.1/1.8.2/lib/libmpi_cxx.1.dylib \
/usr/local/opt/open-mpi/lib/libmpi_cxx.dylib \
/usr/local/Xyce-Release-6.5.0-OPENMPI-OPENSOURCE/bin/Xyce
install_name_tool -change \
/opt/openmpi/x86_64-icc-12.1/1.8.2/lib/libmpi.1.dylib \
/usr/local/opt/open-mpi/lib/libmpi.dylib \
/usr/local/Xyce-Release-6.5.0-OPENMPI-OPENSOURCE/bin/Xyce


It seems to run fine now.

gm/Id method

The traditional circuit bias and sizing method using square law, as described in textbooks, is cumbersome and not very accurate in today’s sub-micron technologies. Unfortunately, the prevalent textbooks being rather old, still teach the square law method.

A more modern method using “gm/Id” of the transistor has been known since 1996 (Silviera, et. al. 1996), but hasn’t made its way into many designers’ toolkits. Instead of trying to explain it here, I suggest reading Bernhard E Boser’s (2011) lecture notes.

If you’d like to try this yourself, I have created an example testbench for ngspice using 45nm predictive technology models from ASU and a python script to post-process it.

If you find an error, have an idea for improving it, or just want to discuss this generally, please leave a reply or contact me.

Silveira, F., D. Flandre, and P. G.A Jespers. “A gm/ID Based Methodology for the Design of CMOS Analog Circuits and Its Application to the Synthesis of a Silicon-on-Insulator Micropower OTA.” IEEE Journal of Solid-State Circuits 31, no. 9 (September 1996): 1314–19. doi:10.1109/4.535416.
Boser, Bernhard E. “Analog Design Using gm/Id and Ft Metrics,” 2011. http://www.eecs.berkeley.edu/~boser/presentations/2011-12%20OTA%20gm%20Id.pdf.

ngspice raw and numpy

Numpy makes it almost trivial to read ngspice raw binary files into python:

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 # MIT license: https://opensource.org/licenses/MIT # for a more complete library. Isotel's version is GPL licensed from __future__ import division import numpy as np BSIZE_SP = 512 # Max size of a line of data; we don't want to read the # whole file to find a line, in case file does not have # expected structure. MDATA_LIST = [b'title', b'date', b'plotname', b'flags', b'no. variables', b'no. points', b'dimensions', b'command', b'option'] def rawread(fname: str): """Read ngspice binary raw files. Return tuple of the data, and the plot metadata. The dtype of the data contains field names. This is not very robust yet, and only supports ngspice. >>> darr, mdata = rawread('test.py') >>> darr.dtype.names >>> plot(np.real(darr['frequency']), np.abs(darr['v(out)'])) """ # Example header of raw file # Title: rc band pass example circuit # Date: Sun Feb 21 11:29:14 2016 # Plotname: AC Analysis # Flags: complex # No. Variables: 3 # No. Points: 41 # Variables: # 0 frequency frequency grid=3 # 1 v(out) voltage # 2 v(in) voltage # Binary: fp = open(fname, 'rb') plot = {} count = 0 arrs = [] plots = [] while (True): try: mdata = fp.readline(BSIZE_SP).split(b':', maxsplit=1) except: raise if len(mdata) == 2: if mdata[0].lower() in MDATA_LIST: plot[mdata[0].lower()] = mdata[1].strip() if mdata[0].lower() == b'variables': nvars = int(plot[b'no. variables']) npoints = int(plot[b'no. points']) plot['varnames'] = [] plot['varunits'] = [] for varn in range(nvars): varspec = (fp.readline(BSIZE_SP).strip() .decode('ascii').split()) assert(varn == int(varspec[0])) plot['varnames'].append(varspec[1]) plot['varunits'].append(varspec[2]) if mdata[0].lower() == b'binary': rowdtype = np.dtype({'names': plot['varnames'], 'formats': [np.complex_ if b'complex' in plot[b'flags'] else np.float_]*nvars}) # We should have all the metadata by now arrs.append(np.fromfile(fp, dtype=rowdtype, count=npoints)) plots.append(plot) fp.readline() # Read to the end of line else: break return (arrs, plots) if __name__ == '__main__': arrs, plots = rawread('test.raw') print(arrs) # Local Variables: # mode: python # End:
view raw rawread.py hosted with ❤ by GitHub

Verilog-A and overall accuracy settings

Fast-spice, or multi-rate simulators use different time-steps for each partition in a circuit. This can have some interesting consequences when used along with Verilog-A models.

Verilog-A allows one to use model some aspects of the circuit behavior using events. Unfortunately, sometimes the containing partition of the Verilog-A model uses very aggressive optimization for reducing the number of time-steps evaluated. This can cause the simulator to never evaluate the Verilog-A event.

In this case one has to set fairly conservative settings for the containing block. So all the speed gain from the Verilog-A model is lost in the conservative settings for the next block. Watch out for the gotcha!

A better Bash command-prompt

Bash sets the command prompt using the variable PS1, which is evaluated every time the prompt is printed. The following script, stolen from various parts of the internet (sorry, I didn’t keep references), is quite handy. It lists the username, host, working directory, and git/svn branch.

#!/usr/bin/bash
if [[ $- == *i* ]] ; then function parse_git_branch () { git name-rev HEAD 2>/dev/null | sed 's#HEAD\ $$.*$$#git:\1#' } function parse_svn_branch() { local rurl=svn info --show-item relative-url 2>/dev/null [[ -n "$rurl" ]] && echo "svn:${rurl}@svn info --show-item revision" } function proml() { local BOLD="$(tput bold)$" local RED="$(tput setaf 1)$" local GREEN="$(tput setaf 2)$" local YELLOW="$(tput setaf 3)$" local BLUE="$(tput setaf 4)$" local PURPLE="$(tput setaf 5)$" local CYAN="$(tput setaf 6)$" local WHITE="$(tput setaf 7)$" local GRAY="$(tput setaf 8)$" local DEFAULT="$(tput sgr0)$" PS1="${PURPLE}\u${GREEN}@\h${YELLOW}\w${CYAN} " PS1+="\parse_git_branch\\parse_svn_branch\${DEFAULT}\n> "
}
proml
fi


Free SPICE simulators

Free SPICE simulators are great for practicing circuit design. There are a few free ones that are actively developed:
1. LTspice
2. ngspice
3. Xyce

LTspice comes bundled with a full suite for circuit design: schematic editor, simulator, and waveform viewer. It is actively developed, reasonably fast and very easy to use.

ngspice has a lot more features, including some scripting, and optional integration with TCL (tclspice), or even GPU processing (CUSPICE). ngspice is also Free (as in freedom) software licensed under the modified BSD license.

Xyce is developed at Sandia National Laboratories. It’s main feature is support for parallel multi-core simulation. Xyce is also Free software licensed under GPL v3.