Drawing circuit diagrams using CircuiTikZ

As I need to draw cmos circuits for illustration’s purpose as well as publication’s requirement, I want to find a high quality decent way of drawing circuits. I tried to export/print the file out of Cadence Virtuoso, but it is far from satisfactory, there are other types of online and local programs for drawing circuits, but I feel that they are still not acceptable in terms of how it is presented. I thus decided to find LaTeX based packages that can draw circuits and create ones that could be as beautiful as equations typesetted by LaTeX. I found this package named circuitikz that is able to do so. You could also grab the manual from the ctan site.

So why the package has such weird name, as you gain more info, you can see the implications from the name. PGF/TikZ is a pair of languages that are capable of producing vector based images from a geometric/algebraic description. PGF is a lower-level language, while TikZ is a set of higher-level macros that use PGF. it is a recursive acronym for “TikZ ist kein Zeichenprogramm” (German for “TikZ is not a drawing program”). Thus as you can see CircuiTikZ is built upon TikZ that is able to generate vector based circuit diagrams. Even through the final product is amazing, there are still lots of work to be placed in order to draw any circuits you want to.

In this tutorial, I will refer to this blog that draws the 2 stage cmos OmAmp circuit. The reason that I chose this one is that I love the styles of the circuit diagram and how it provides additional tools for helping you drawing circuits.

LaTeX environment

I just want to generate a circuit schematic, thus I don’t what a document of any kind, I just care about it would output a file that shows the schematic completely, which is simpler for further processes. In the LaTeX document, the following wrapper should be placed.

\documentclass[class=standalone]{standalone}
\usepackage{circuitikz}

\begin{document}
\begin{tikzpicture}
%--------start graphics code --------
%--------end graphics code ----------
\end{tikzpicture}
\end{document}

Reference grids

In the article, it also provides the grids that could help you to determine where to put the element in the schematic. Once the typesetting process is done and you are satisified with the location of each element as well as its wires, you could comment out the grids.

%Grid for intial drawing.
%Comment next three lines once typesetting finished
\def\figHt{6};
\def\figWd{10};
\draw[step=0.5,very thin, black!20] (-0.5,-0.5) grid (\figWd,\figHt);
\foreach \x in {0,...,\figWd} {\node [anchor=north] at (\x,-0.5) {\x};}
\foreach \y in {0,...,\figHt} {\node [anchor=east] at (-0.5,\y) {\y};}

In the above snippet, the figure width and height are defined for the tikzpicture, it then generates the grid inside the diagram with thin line. What’s more, it would also provides the number index for each vertical and horizontal line. It can help you pinpoint the location that you want to work on as you need to provide the specific coordinates in the graph for your wires, electronics and theie notations.

CMOS Styles

There are different kinds of cmos element representations, in this and this discussions, users want different styles of cmos representations than the default one. It turns out that you could do that quite easily using the following line.

\ctikzset{tripoles/pmos style/emptycircle, tripoles/mos style/arrows}

The following snippet shows all the available cmos symbol styles:

\documentclass[class=standalone]{standalone}
\usepackage{circuitikz}

\begin{document}
\begin{tikzpicture}
%--------start graphics code --------
%Grid for intial drawing.
%Comment next three lines once typesetting finished
\def\figHt{5};
\def\figWd{9.5};
\draw[step=0.5,very thin, black!20] (-0.5,-0.5) grid (\figWd,\figHt);
\foreach \x in {0,...,\figWd} {\node [anchor=north] at (\x,-0.5) {\x};}
\foreach \y in {0,...,\figHt} {\node [anchor=east] at (-0.5,\y) {\y};}
    \draw (1,1) node[ nmos ] {};
    \node [align=center] at (0.5,-0.1) {default};
    \draw (1,4) node[ pmos ] {};
    \node [align=center] at (0.5,2.8) {default};
    \node [align=center] at (4.5,2.8) {empty\\circle};
    \ctikzset{tripoles/mos style/arrows}
    \draw (3,1) node[ nmos ] {};
    \node [align=center] at (2.5,-0.1) {with arrows};
    \draw (3,4) node[ pmos ] {};
    \node [align=center] at (2.5,2.8) {with arrows};
    \ctikzset{tripoles/mos style/no arrows, emptycircle}
    \draw (5,1) node[ nmos ] {};
    \draw (5,4) node[ pmos ] {};
    \ctikzset{tripoles/mos style/arrows, emptycircle}
    \draw (7,1) node[ nmos ] {};
    \node [align=center] at (6.7, 2.8) {empty circle\\with arrows};
    \draw (7,4) node[ pmos ] {};
    \node [align=center] at (8.5,3.9) {pmos\\symbls};
    \node [align=center] at (8.5,0.9) {nmos\\symbls};
\end{tikzpicture}
\end{document}

The output graph is show as follows:

2 stage OmAmp Schematic

The 2 stage OmAmp schematic based on the blog could be shown as follows, then I will present the source code.

The code may print out some errors during typesetting but it works on my machine:

\documentclass[class=standalone]{standalone}
\usepackage{circuitikz}

\begin{document}
\begin{tikzpicture}
%--------start graphics code --------
%Grid for intial drawing.
%Comment next three lines once typesetting finished
\def\figHt{6};
\def\figWd{10};
\draw[step=0.5,very thin, black!20] (-0.5,-0.5) grid (\figWd,\figHt);
\foreach \x in {0,...,\figWd} {\node [anchor=north] at (\x,-0.5) {\x};}
\foreach \y in {0,...,\figHt} {\node [anchor=east] at (-0.5,\y) {\y};}
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%% NMOS current mirror %%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\coordinate (ref_node1) at (0,0);
\coordinate (ref_node1T) at ($(ref_node1)+(0,\figHt)$); 
%Instantiation of components
\draw (ref_node1) node[nmos,anchor=source,xscale=-1] (Mt1){};
\draw (ref_node1T) to [I] (Mt1.drain);
%Inter-connections
\draw (Mt1.drain) node[circ] -| (Mt1.gate);
% Numbering the components
\draw (Mt1) node[]{$M_{t1}$};
%Ground and Vdd lines
\draw (Mt1.source) node[ground]{}; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%% Differential pair  %%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\coordinate (ref_node) at (4.5,0); 
\coordinate (ref_nodeT) at ($(ref_node)+(0,\figHt)$); 
%Component instantiation
\ctikzset{tripoles/pmos style/emptycircle, tripoles/mos style/arrows}
\draw (ref_node) node[nmos,anchor=source] (M0){}
      (ref_node) ++(-1.5,2) node[nmos, anchor=source] (M1){}
      (ref_node) ++(1.5,2) node[nmos, anchor=source, xscale=-1] (M2){}
      (ref_nodeT) ++(-1.5,0) node[pmos, anchor=source, xscale=-1] (M3){}
      (ref_nodeT) ++(1.5,0) node[pmos, anchor=source] (M4){} ;
%Inter-connections
\draw (M1.drain) -- (M3.drain)node[circ] -| (M3.gate) node[circ] -- (M4.gate);
\draw (M4.drain) -- (M2.drain);
\draw (M1.source) |- (M0.drain) node[circ] -| (M2.source);
% Numbering the components
\draw (M0) node[]{$M_0$}
      (M1) node[]{$M_1$}
      (M2) node[] {$M_2$}
      (M3) node[] {$M_3$}
      (M4) node[]{$M_4$};
\draw (M1.gate) node[ocirc] node[left] {$v_{ip}$}
      (M2.gate) node[ocirc] node[right]{$v_{im}$};
  %    (M2.drain) node[circ] -- ++(0.5,0) node[ocirc](vout){} node[right]{$v_{out}$};
%Ground and Vdd lines
\draw (M0.source) node[ground]{};
%\draw (M3.source) -- ++(1.5,0) node[anchor=south] {$V_{DD}$} -- (M4.source);
 
 
%###########################################%
%%%%%%%%%% common source amplifier %%%%%%%%%%
%###########################################%
\coordinate (ref_node2) at (9,0);
\coordinate (ref_node2T) at ($(ref_node2)+(0,\figHt)$);
%Instantiation of components
\draw (ref_node2) node[nmos,anchor=source] (M20){};
\draw (ref_node2T)node[pmos,anchor=source] (M21){}; 
%Inter-connections 
\draw (M20.drain) -- (M21.drain) ;
% Numbering the components and naming the nodes
\draw (M20) node[]{$M_{20}$};
\draw (M21) node[]{$M_{21}$};
\draw (M20.drain) node[circ] 
           -- ++(0.5,0) node[ocirc] node[right]{$v_{out}$};
%Ground and Vdd lines
\draw (M20.source) node[ground]{}; 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%% TOP LEVEL INTERCONNECTIONS %%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\draw (Mt1.gate) node[circ] -- (M0.gate) -- (M20.gate);
\draw (ref_node1T) |- (M3.source) node[circ]{} 
      to node[above]{$V_{DD}$} (M4.source)node[circ]{}  -- (M21.source);
\draw ($(ref_nodeT)+(1.5,-2)$) node[circ]{} to +(0.5,0)  
      coordinate (capnode) to [C,l=$C_c$] ($(ref_node2T)+(0,-2)$) node[circ]{};
\draw (capnode) node[circ]{} |- (M21.gate) ;
%--------end graphics code ----------
\end{tikzpicture}
\end{document}

Conclusion

I’m able to generate high quality circuit schematics using the CircuiTikZ package, but there are a lot of things to learn to optimize the figure and make the graph for informative. Those graphs can be used in publications, presentations, blogs, one place it could be used is for printing out the graph and making analysis on the page.


Posted

in

by

Tags:

Comments

Leave a Reply

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

🧭