Published 2009-08-01 |
Author:
Martin Scharrer

Example of a custom node shape for drawing D flip-flops. The shape is used to draw a serial shift register.

Do you have a question regarding this example, TikZ or LaTeX in general? Just ask in the
**LaTeX Forum**.

Oder frag auf Deutsch auf TeXwelt.de.
En français: TeXnique.fr.

```
% D flip-flops (DFFs) and shift register
% Author: Martin Scharrer
\documentclass[a4paper,landscape]{article}
\usepackage{pgf,tikz}
\usetikzlibrary{calc,arrows}
\usepackage{amsmath}
\usepackage[left=1cm,right=1cm]{geometry}
\pagestyle{empty}
\makeatletter
% Data Flip Flip (DFF) shape
\pgfdeclareshape{dff}{
% The 'minimum width' and 'minimum height' keys, not the content, determine
% the size
\savedanchor\northeast{%
\pgfmathsetlength\pgf@x{\pgfshapeminwidth}%
\pgfmathsetlength\pgf@y{\pgfshapeminheight}%
\pgf@x=0.5\pgf@x
\pgf@y=0.5\pgf@y
}
% This is redundant, but makes some things easier:
\savedanchor\southwest{%
\pgfmathsetlength\pgf@x{\pgfshapeminwidth}%
\pgfmathsetlength\pgf@y{\pgfshapeminheight}%
\pgf@x=-0.5\pgf@x
\pgf@y=-0.5\pgf@y
}
% Inherit from rectangle
\inheritanchorborder[from=rectangle]
% Define same anchor a normal rectangle has
\anchor{center}{\pgfpointorigin}
\anchor{north}{\northeast \pgf@x=0pt}
\anchor{east}{\northeast \pgf@y=0pt}
\anchor{south}{\southwest \pgf@x=0pt}
\anchor{west}{\southwest \pgf@y=0pt}
\anchor{north east}{\northeast}
\anchor{north west}{\northeast \pgf@x=-\pgf@x}
\anchor{south west}{\southwest}
\anchor{south east}{\southwest \pgf@x=-\pgf@x}
\anchor{text}{
\pgfpointorigin
\advance\pgf@x by -.5\wd\pgfnodeparttextbox%
\advance\pgf@y by -.5\ht\pgfnodeparttextbox%
\advance\pgf@y by +.5\dp\pgfnodeparttextbox%
}
% Define anchors for signal ports
\anchor{D}{
\pgf@process{\northeast}%
\pgf@x=-1\pgf@x%
\pgf@y=.5\pgf@y%
}
\anchor{CLK}{
\pgf@process{\northeast}%
\pgf@x=-1\pgf@x%
\pgf@y=-.66666\pgf@y%
}
\anchor{CE}{
\pgf@process{\northeast}%
\pgf@x=-1\pgf@x%
\pgf@y=-0.33333\pgf@y%
}
\anchor{Q}{
\pgf@process{\northeast}%
\pgf@y=.5\pgf@y%
}
\anchor{Qn}{
\pgf@process{\northeast}%
\pgf@y=-.5\pgf@y%
}
\anchor{R}{
\pgf@process{\northeast}%
\pgf@x=0pt%
}
\anchor{S}{
\pgf@process{\northeast}%
\pgf@x=0pt%
\pgf@y=-\pgf@y%
}
% Draw the rectangle box and the port labels
\backgroundpath{
% Rectangle box
\pgfpathrectanglecorners{\southwest}{\northeast}
% Angle (>) for clock input
\pgf@anchor@dff@CLK
\pgf@xa=\pgf@x \pgf@ya=\pgf@y
\pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgf@xc=\pgf@x \pgf@yc=\pgf@y
\pgfmathsetlength\pgf@x{1.6ex} % size depends on font size
\advance\pgf@ya by \pgf@x
\advance\pgf@xb by \pgf@x
\advance\pgf@yc by -\pgf@x
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
\pgfclosepath
% Draw port labels
\begingroup
\tikzset{flip flop/port labels} % Use font from this style
\tikz@textfont
\pgf@anchor@dff@D
\pgftext[left,base,at={\pgfpoint{\pgf@x}{\pgf@y}},x=\pgfshapeinnerxsep]{\raisebox{-0.75ex}{D}}
\pgf@anchor@dff@CE
\pgftext[left,base,at={\pgfpoint{\pgf@x}{\pgf@y}},x=\pgfshapeinnerxsep]{\raisebox{-0.75ex}{CE}}
\pgf@anchor@dff@Q
\pgftext[right,base,at={\pgfpoint{\pgf@x}{\pgf@y}},x=-\pgfshapeinnerxsep]{\raisebox{-.75ex}{Q}}
\pgf@anchor@dff@Qn
\pgftext[right,base,at={\pgfpoint{\pgf@x}{\pgf@y}},x=-\pgfshapeinnerxsep]{\raisebox{-.75ex}{$\overline{\mbox{Q}}$}}
\pgf@anchor@dff@R
\pgftext[top,at={\pgfpoint{\pgf@x}{\pgf@y}},y=-\pgfshapeinnerysep]{R}
\pgf@anchor@dff@S
\pgftext[bottom,at={\pgfpoint{\pgf@x}{\pgf@y}},y=\pgfshapeinnerysep]{S}
\endgroup
}
}
% Key to add font macros to the current font
\tikzset{add font/.code={\expandafter\def\expandafter\tikz@textfont\expandafter{\tikz@textfont#1}}}
% Define default style for this node
\tikzset{flip flop/port labels/.style={font=\sffamily\scriptsize}}
\tikzset{every dff node/.style={draw,minimum width=2cm,minimum
height=2.828427125cm,very thick,inner sep=1mm,outer sep=0pt,cap=round,add
font=\sffamily}}
\makeatother
\begin{document}
\begin{tikzpicture}[font=\sffamily,>=triangle 45]
\def\N{7} % Number of Flip-Flops minus one
% Place FFs
\foreach \m in {0,...,\N}
\node [shape=dff] (DFF\m) at ($ 3*(\m,0) $) {Bit \#\m};
% Connect FFs (Q1 with D1, etc.)
\def\p{0} % Used to save the previous number
\foreach \m in {1,...,\N} { % Note that it starts with 1, not 0
\draw [->] (DFF\p.Q) -- (DFF\m.D);
\global\let\p\m
}
% Connect and label data in- and output port
\draw [<-] (DFF0.D) -- +(-1,0) node [anchor=east] {input} ;
\draw [->] (DFF\N.Q) -- +(1,0) node [anchor=west] {output};
% 'Reset' port label
\path (DFF0) +(-2cm,+2cm) coordinate (temp)
node [anchor=east] {reset};
% Connect resets
\foreach \m in {0,...,\N}
\draw [->] (temp) -| (DFF\m.R);
% 'Set' port label
\path (DFF0) +(-2cm,-2cm) coordinate (temp)
node [anchor=east] {set};
% Connect sets
\foreach \m in {0,...,\N}
\draw [->] (temp) -| (DFF\m.S);
% Clock port label
\path (DFF0) +(-2cm,-2.5cm) coordinate (temp)
node [anchor=east] {clock};
\foreach \m in {0,...,\N}
\draw [->] (temp) -| ($ (DFF\m.CLK) + (-5mm,0) $) --(DFF\m.CLK);
% Clock port label
\path (DFF0) +(-2cm,-3cm) coordinate (temp)
node [anchor=east] {clock enable};
\foreach \m in {0,...,\N}
\draw [->] (temp) -| ($ (DFF\m.CE) + (-7.5mm,0) $) --(DFF\m.CE);
\end{tikzpicture}
\end{document}
```

## Comments

Thanks for the example!

I have a question though.

When computing the location of the 'text' anchor, you use pgfnodeparttextbox. The PGF manual says that this should be avoided:

"The problem is that the box \pgfnodeparttextbox will most likely not have the correct size when the anchor is computed. After all, the anchor position might be recomputed at a time when several other nodes have been created."

Taken from page 483 of Manual 2.0

The code above seems to work fine, however, and I don't know any good alternative.

Does anyone else know a good alternative which achieves the same functionality but without pgfnodeparttextbox?

Thanks.

This is the same for home contents and general car insurance. Something basic is usually perceived as only what is required by law, meaning basic liability. When looking for your Auto insurance Kettering, ensure that the insurance agency charges you fairly for the service provided.

Very good website you have here but I was wanting to know if you knew of any community forums that cover the same topics talked about in this article?

I'd really like to be a part of community where I can get feed-back from other knowledgeable people that share the same interest. If you have any suggestions, please let me know.

Bless you!

Adding comments is currently not enabled.