tikz-pgf – How to Draw a Register Map with TikZ

tablestikz-pgf

I was wondering if there was a way to easily draw a register map (like the one below) in LaTeX, possibly in TikZ?

enter image description here

The closest I've gotten is just using the tabular environment and that's not even close to what I want, my result is listed below.

\begin{table}[h!]
\begin{tabular}{p{20pt} p{20pt} p{20pt} p{20pt} p{20pt} p{20pt} p{20pt} p{20pt} p{20pt} p{20pt} p{20pt} p{20pt} p{20pt} p{20pt} p{20pt}  >{\centering\arraybackslash}m{20pt}}
\centering 15 & \centering 14 & \centering 13 & \centering 12 & \centering 11 & \centering 10 & \centering 9 & \centering 8 & \centering 7 & \centering 6 & \centering 5 & \centering 4 & \centering 3 & \centering 2 & \centering 1 & 0\\\hline
\multicolumn{1}{|c|}{SEL} & 
\multicolumn{1}{c|}{SEL} & 
\multicolumn{1}{c|}{SEL} & 
\multicolumn{5}{|c|}{\cellcolor{gray!25}} & 
\multicolumn{1}{c|}{DIR} & 
\multicolumn{7}{c|}{PWM} \\\hline
\end{tabular}
\end{table}

enter image description here

Best Answer

enter image description here

Late to the question here, but this should be workable. I'm not certain if I have the right semantics for the different fields, but this should be relatively easy to adapt:

\documentclass{standalone}
\usepackage{tikz}

\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}

\newcommand{\bitrect}[2]{
  \begin{pgfonlayer}{foreground}
    \draw [thick] (0,0) rectangle (#1,1);
    \pgfmathsetmacro\result{#1-1}
    \foreach \x in {1,...,\result}
      \draw [thick] (\x,1) -- (\x, 0.8);
  \end{pgfonlayer}
%  \node [below left, align=right] at (0,0) {Type \\ Reset};
  \bitlabels{#1}{#2}
}
\newcommand{\rwbits}[3]{
  \draw [thick] (#1,0) rectangle ++(#2,1) node[pos=0.5]{#3};
  \pgfmathsetmacro\start{#1+0.5}
  \pgfmathsetmacro\finish{#1+#2-0.5}
%  \foreach \x in {\start,...,\finish}
%    \node [below, align=center] at (\x, 0) {R/W \\ 0};
}
\newcommand{\robits}[3]{
  \begin{pgfonlayer}{background}
    \draw [thick, fill=lightgray] (#1,0) rectangle ++(#2,1) node[pos=0.5]{#3};
  \end{pgfonlayer}
  \pgfmathsetmacro\start{#1+0.5}
  \pgfmathsetmacro\finish{#1+#2-0.5}
%  \foreach \x in {\start,...,\finish}
%    \node [below, align=center] at (\x, 0) {RO \\ 0};
}
\newcommand{\bitlabels}[2]{
  \foreach \bit in {1,...,#1}{
     \pgfmathsetmacro\result{#2}
     \node [above] at (\bit-0.5, 1) {\pgfmathprintnumber{\result}};
   }
}

\begin{document}
\begin{tikzpicture}
\bitrect{16}{16-\bit}
\rwbits{0}{1}{SEL}
\rwbits{1}{1}{SEL}
\rwbits{2}{1}{SEL}
\robits{3}{5}{}
\rwbits{8}{1}{DIR}
\rwbits{9}{7}{PWM}
\end{tikzpicture}
\end{document}

Other variations using this preamble include grouping the SEL bits similar to the PWM bits:

enter image description here

\begin{tikzpicture}
\bitrect{16}{16-\bit}
\rwbits{0}{3}{SEL}
\robits{3}{5}{}
\rwbits{8}{1}{DIR}
\rwbits{9}{7}{PWM}
\end{tikzpicture}

or the first example you gave:

enter image description here

\begin{tikzpicture}
% make sure to uncomment \foreach loops in \robits and \rwbits, and last node in \bitrect
% 16 bits, indices decreasing from 31...16
\bitrect{16}{32-\bit} % {length}{index label expression}
\rwbits{0}{3}{INTD} % {start bit}{length}{label}
\robits{3}{5}{reserved} % {start bit}{length}{label}
\rwbits{8}{3}{INTC}
\robits{11}{5}{reserved}
\end{tikzpicture}
Related Question