# How to improve the creation of digital circuits in PGF?

I am currently designing a piece of hardware and wanted to document this in a Latex document. Luckily, there is circuitikz and pgf to work with. The building block I am interested in are not included in circuitikz so I decided to follow the guide for creating a multipole component here. Here are the blocks I have already drawn:

As an example here is the code for the decoder:

\usepackage{tikz}
\usepackage{circuitikz}

\usetikzlibrary{calc,positioning,shapes.misc}

\tikzstyle{bus} = [near end, rotate=-110, strike out, draw, scale=0.6]
\def \busx {0.5pt}
\def \busy {2.5pt}

% ---------------
% Decoder
% ---------------
\pgfpoint{-1.8cm}{-1.0cm}
\pgfgetlastxy{\xdcsub}{\ydcsub}
\pgfpoint{-1.4cm}{-1.0cm}
\pgfgetlastxy{\xdcand}{\ydcand}
\pgfpoint{-1.0cm}{-1.0cm}
\pgfgetlastxy{\xdcor}{\ydcor}
\pgfpoint{-0.6cm}{-1.0cm}
\pgfgetlastxy{\xdcxor}{\ydcxor}
\pgfpoint{-0.2cm}{-1.0cm}
\pgfgetlastxy{\xdcnot}{\ydcnot}

\pgfpoint{0.2cm}{-1.0cm}
\pgfgetlastxy{\xdcdir}{\ydcdir}
\pgfpoint{0.6cm}{-1.0cm}
\pgfgetlastxy{\xdcrot}{\ydcrot}
\pgfpoint{1.0cm}{-1.0cm}
\pgfgetlastxy{\xdcar}{\ydcar}
\pgfpoint{1.4cm}{-1.0cm}
\pgfgetlastxy{\xdcmul}{\ydcmul}
\pgfpoint{1.8cm}{-1.0cm}
\pgfgetlastxy{\xdcop}{\ydcop}

\pgfpoint{0cm}{1.0cm}
\pgfgetlastxy{\xinop}{\yinop}

\pgfdeclareshape{decoder}{
\inheritsavedanchors[from=rectangle]
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{east}
\inheritanchor[from=rectangle]{north west}
\inheritanchor[from=rectangle]{south east}
\inheritanchor[from=rectangle]{south west}
\inheritanchor[from=rectangle]{north east}
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{base}
\inheritanchor[from=rectangle]{base east}
\inheritanchor[from=rectangle]{base west}
\inheritanchor[from=rectangle]{mid}
\inheritanchor[from=rectangle]{mid east}
\inheritanchor[from=rectangle]{mid west}
\anchor{center}{\pgfpointorigin}

\savedanchor\pindcsub{\pgfpoint{\xdcsub}{\ydcsub - 0.5cm}}
\anchor{sub}{\pindcsub}
\savedanchor\pindcand{\pgfpoint{\xdcand}{\ydcand - 0.5cm}}
\anchor{and}{\pindcand}
\savedanchor\pindcor{\pgfpoint{\xdcor}{\ydcor - 0.5cm}}
\anchor{or}{\pindcor}
\savedanchor\pindcxor{\pgfpoint{\xdcxor}{\ydcxor - 0.5cm}}
\anchor{xor}{\pindcxor}
\savedanchor\pindcnot{\pgfpoint{\xdcnot}{\ydcnot - 0.5cm}}
\anchor{not}{\pindcnot}
\savedanchor\pindcdir{\pgfpoint{\xdcdir}{\ydcdir - 0.5cm}}
\anchor{dir}{\pindcdir}
\savedanchor\pindcrot{\pgfpoint{\xdcrot}{\ydcrot - 0.5cm}}
\anchor{rot}{\pindcrot}
\savedanchor\pindcar{\pgfpoint{\xdcar}{\ydcar - 0.5cm}}
\anchor{ar}{\pindcar}
\savedanchor\pindcmul{\pgfpoint{\xdcmul}{\ydcmul - 0.5cm}}
\anchor{mul}{\pindcmul}
\savedanchor\pindcop{\pgfpoint{\xdcop}{\ydcop - 0.5cm}}
\anchor{s}{\pindcop}

\savedanchor\piniop{\pgfpoint{\xinop}{\yinop + 0.5cm}}
\anchor{iop}{\piniop}

\foregroundpath{
\pgfsetlinewidth{0.8pt}
\pgfpathrectanglecorners{\pgfpoint{2.2cm}{1.0cm}}{\pgfpoint{-2.2cm}{-1.0cm}}
\pgfusepath{draw}

\pgfsetlinewidth{0.4pt}
{\fontfamily{phv}\selectfont
\pgftext[at={\pgfpointorigin}]{\large Decoder}

\pgftext[top,at={\pgfpoint{\xinop - 0.1cm}{\yinop - 0.3cm}},rotate=90]{\scriptsize OP}
\draw[line width=1pt] (\xinop,\yinop) -- node[bus,rotate=90] (bus) {} ++(0,0.5cm);
\node[circle] at ($(bus.west)+(\busx-2pt,\busy-8pt)$) {\tiny 5};

\pgftext[bottom,at={\pgfpoint{\xdcsub + 0.1cm}{\ydcsub + 0.3cm}},rotate=90]{\scriptsize SUB}
\draw (\xdcsub,\ydcsub) -- ++(0,-0.5cm);

\pgftext[bottom,at={\pgfpoint{\xdcand + 0.1cm}{\ydcand + 0.3cm}},rotate=90]{\scriptsize AND}
\draw (\xdcand,\ydcand) -- ++(0,-0.5cm);

\pgftext[bottom,at={\pgfpoint{\xdcor + 0.1cm}{\ydcor + 0.3cm}},rotate=90]{\scriptsize OR}
\draw (\xdcor,\ydcor) -- ++(0,-0.5cm);

\pgftext[bottom,at={\pgfpoint{\xdcxor + 0.1cm}{\ydcxor + 0.3cm}},rotate=90]{\scriptsize XOR}
\draw (\xdcxor,\ydcxor) -- ++(0,-0.5cm);

\pgftext[bottom,at={\pgfpoint{\xdcnot + 0.1cm}{\ydcnot + 0.3cm}},rotate=90]{\scriptsize NOT}
\draw (\xdcnot,\ydcnot) -- ++(0,-0.5cm);

\pgftext[bottom,at={\pgfpoint{\xdcdir + 0.1cm}{\ydcdir + 0.3cm}},rotate=90]{\scriptsize DIR}
\draw (\xdcdir,\ydcdir) -- ++(0,-0.5cm);

\pgftext[bottom,at={\pgfpoint{\xdcrot + 0.1cm}{\ydcrot + 0.3cm}},rotate=90]{\scriptsize ROT}
\draw (\xdcrot,\ydcrot) -- ++(0,-0.5cm);

\pgftext[bottom,at={\pgfpoint{\xdcar + 0.1cm}{\ydcar + 0.3cm}},rotate=90]{\scriptsize AR}
\draw (\xdcar,\ydcar) -- ++(0,-0.5cm);

\pgftext[bottom,at={\pgfpoint{\xdcmul + 0.1cm}{\ydcmul + 0.3cm}},rotate=90]{\scriptsize MUL}
\draw (\xdcmul,\ydcmul) -- ++(0,-0.5cm);

\pgftext[bottom,at={\pgfpoint{\xdcop + 0.1cm}{\ydcop + 0.3cm}},rotate=90]{\scriptsize RES}
\draw[line width=1pt] (\xdcop,\ydcop) -- node[bus,rotate=90] (bus) {} ++(0,-0.5cm);
\node[circle] at ($(bus.west)+(-\busx-2pt,\busy)$) {\tiny 3};
}
}
}


The other ones have a similar structure. I was now wondering if there is a less verbose / more automated way to create these blocks as they are extremely time consuming to make.

• Welcome to TeX.SX! – egreg Feb 1 at 16:36
• Anything repeated exactly, like the inherited anchors, could be put into a macro and reused (I created \compass for standard anchors). Some things could be done using loops. See tex.stackexchange.com/questions/187068/… and tex.stackexchange.com/questions/372993/… – John Kormylo Feb 1 at 20:33
• I might note that many of the recent changes in circuitikz consist of using macros to generate more than one component. This simplifies the code, but makes modifications more difficult. \drawfetcore is used for all FETs, for example. – John Kormylo Feb 1 at 20:44
• @JohnKormylo Thanks for the links. Where do I find \compass is it included in circuitikz or would I have to define it myself? – aaron Feb 1 at 20:54
• There is a copy in tex.stackexchange.com/questions/222424/… – John Kormylo Feb 2 at 19:49