Block diagrams in TikZ: Is there a simpler way to draw my block diagram?

I have justed started using TikZ and this block diagram was my first piece of art. Why art? Because it took me ages and I have had the feeling that drawing this kind of diagram could be simplified greatly if I had a deeper understanding of TikZ. Could you help me out to find a way to simplify this diagram or to find a suitable library?

Basically, it is a block diagram of a digital circuit, which describes the basic building blocks of that circuit. (If you are wondering what this circuit is used for, please refer to: https://github.com/Xilinx/XilinxVirtualCable, which is a project with a similiar goal).

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning, calc}
\begin{document}

\begin{figure}
\centering
\begin{tikzpicture}
\def\frow{2.5}
\def\rrow{2.7}
\def\srow{5}
\def\brow{6.5}
\def\trow{8}

\tiny
\tikzset{
bignode/.style={rectangle,draw=black, top color=white, inner    sep=1em,minimum width=1.75cm, minimum height=4.0cm, text centered},
mynode/.style={rectangle,draw=black, top color=white, inner sep=1em,minimum width=1.5cm, minimum height=1cm, text centered},
ifnode/.style={rectangle,dashed,draw=black, top color=white, inner sep=1em,minimum width=1.5cm, minimum height=1cm, text centered, fill=yellow},
fifonode/.style={rectangle,draw=black, top color=white, inner sep=1pt,minimum width=0.9cm, minimum height=0.4cm, text centered},
regnode/.style={rectangle,draw=black, top color=white, inner sep=1pt,minimum width=1.2cm, minimum height=0.4cm, text centered},
sarrow/.style={->, >=latex'},
carrow/.style={<->, >=latex', dashed},
branch/.style={fill,circle,minimum size=2pt,inner sep=0pt},
acaption/.style={below, midway, text width=1cm, align=center}
}
%\draw[help lines] (0,0) grid (10,6);
\node (axi) at (0.5,4.25) {AXI Bus};
\node[bignode, label=above:AXI IF] (axiif) at (\frow,2.5) {};
\node[regnode] (datareg) at (\rrow,4.25) {Data};
\node[regnode] (statusreg) at (\rrow,3.8) {Status};
\node[regnode] (controlreg) at (\rrow,3.35) {Control};

\node[ifnode, label=above:IF IN] (ifin) at (\srow,1) {};
\node[fifonode] (tdofifo) at (\srow+0.25,1.25) {FIFO};
\node[mynode, label=above:IF TIMER] (iftimer) at (\srow,2.5) {};
\node[ifnode, label=above:IF OUT] (ifout) at (\srow,4) {};
\node[fifonode] (tmsfifo) at (\srow+0.25,4.25) {FIFO};
\node[fifonode] (tdififo) at (\srow+0.25,3.75) {FIFO};

\node[mynode, label=above:TMS Serializer] (tmsser) at (\trow,4.75) {};
\node[mynode, label=above:TDI Serializer] (tdiser) at (\trow,3.25) {};
\node[mynode, label=above:TDO Deserializer] (tdodeser) at (\trow,1) {};

\draw [sarrow] (tmsfifo.east) |- ++(right:0.5) |- node[above] {Data} ($(tmsser.west)+(0,0.25)$);
\draw [sarrow] ($(tmsser.east)+(0,0.25)$) -- ++(right:1.25) node [right]{TMS};
\draw [sarrow] (tdififo.east) |- ++(right:0.5) |- node[below] {Data} ($(tdiser.west)+(0,0.25)$);
\draw [sarrow] ($(tdiser.east)+(0,0.25)$) -- ++(right:1.25) node [right]{TDI};
\draw [sarrow, <-] (tdofifo.east) -| ++(right:0.5) |- node[below] {Data} ($(tdodeser.west)+(0,0.25)$);
\draw [sarrow, <-] ($(tdodeser.east)+(0,0.25)$) -- ++(right:1.25) node [right]{TDO};
\draw [sarrow] ($(iftimer.east)+(0,-0.25)$) -- ++(right:4.25) node [right]{TCK};

\draw[sarrow] (iftimer.east) -- ++(right:0.5) node[above] {Timing} -- ++(right:0.5) node [branch](timer_branch){} -- ++(up:0.75) node [branch](timer_branch2){} -- (tdiser.west);
\draw[sarrow] (timer_branch) |- (tdodeser.west);
\draw[sarrow] (timer_branch2) |- (tmsser.west);

\draw[sarrow, <->] (datareg.east) -- ++(right:0.5) node [branch](datab){} -- ++(right:0.7) node [branch](datab2){} -- (tmsfifo.west);
\draw[sarrow] (datab2) |- (tdififo.west);
\draw[sarrow] (datab) |- (tdofifo.west);

\draw[sarrow] (axi) -- ++(right:1.25) node [branch] (axib) {} -- ++(down:0.45) node [branch] (axib2) {} -- (statusreg.west);
\draw[sarrow] (axib) -- (datareg.west);
\draw[sarrow] (axib2) |-  (controlreg.west);

\draw[carrow] (iftimer.west) -- (axiif.east) node [acaption] {Control/ Status};
\draw[carrow] (ifin.west) -- ($(axiif.east)+(0,-1.5)$) node [acaption] {Control/ Status};
\draw[carrow] (ifout.west) -- ($(axiif.east)+(0,1.5)$) node [acaption] {Control/ Status};

\end{tikzpicture}
\medskip
\caption{AXI-JTAG Peripheral}
\end{figure}

\end{document}


Actually that's a very good code. I changed some things:

• Since arrows is deprecated, I added arrows.meta instead. Unfortunately, latex' and stealth' are not available so I switched to the most similar arrow which is >={Stealth}. You're free to keep using arrows, which is available along with arrows.spaced for compatibility but they're considered deprecated.

• I placed your tikzset in the preamble. This is not required, it's just my personal preference since I find it to be more organized:

Settings and options -> Preamble
Actual code -> Document

I also usually draw first all the nodes, then all the edges. This is for better readability, but it's still personal preference.

• Since most of your nodes had rectangle,draw=black, top color=white,text centered repeated in each node style, I added another style called basic with these options. Then if you write basic in the other node styles, all these options will be included, with the difference that now you don't have overcrowded style options. See code for this.

• The little black circles specified as

 branch/.style={fill,circle,minimum size=2pt,inner sep=0pt},


created a white space around them:

This is due to the fact that you didn't set the outer sep which is positive by default. If you set it to 0, there's still space, but if you set it to -1pt, then:

By the way, if you say inner/outer sep=0, you don't need to specify pt, cm,ex,em and so on. Just 0 will do.

I don't think there are other things, maybe I could fix the spacing in Control/Status - let me know, your code was very well written, especially if it was your first.

Code

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows.meta, positioning, calc}

\tikzset{
basic/.style={rectangle,draw=black, top color=white,text centered},
bignode/.style={basic, inner sep=1em,minimum width=1.75cm, minimum height=4.0cm},
mynode/.style={basic, inner sep=1em,minimum width=1.5cm, minimum height=1cm},
ifnode/.style={basic,dashed, inner sep=1em,minimum width=1.5cm, minimum height=1cm, fill=yellow},
fifonode/.style={basic, inner sep=1pt,minimum width=0.9cm, minimum height=0.4cm},
regnode/.style={basic, inner sep=1pt,minimum width=1.2cm, minimum height=0.4cm},
sarrow/.style={->, >={Stealth}},
carrow/.style={<->, >={Stealth}, dashed},
branch/.style={fill,circle,minimum size=2pt,outer sep=-1pt,inner sep=0pt},
acaption/.style={below, midway, text width=1cm, align=center}
}

\begin{document}
\begin{figure}
\centering
\begin{tikzpicture}\tiny
\def\frow{2.5}
\def\rrow{2.7}
\def\srow{5}
\def\brow{6.5}
\def\trow{8}

%\draw[help lines] (0,0) grid (10,6);
\node (axi) at (0.5,4.25) {AXI Bus};
\node[bignode, label=above:AXI IF] (axiif) at (\frow,2.5) {};
\node[regnode] (datareg) at (\rrow,4.25) {Data};
\node[regnode] (statusreg) at (\rrow,3.8) {Status};
\node[regnode] (controlreg) at (\rrow,3.35) {Control};

\node[ifnode, label=above:IF IN] (ifin) at (\srow,1) {};
\node[fifonode] (tdofifo) at (\srow+0.25,1.25) {FIFO};
\node[mynode, label=above:IF TIMER] (iftimer) at (\srow,2.5) {};
\node[ifnode, label=above:IF OUT] (ifout) at (\srow,4) {};
\node[fifonode] (tmsfifo) at (\srow+0.25,4.25) {FIFO};
\node[fifonode] (tdififo) at (\srow+0.25,3.75) {FIFO};

\node[mynode, label=above:TMS Serializer] (tmsser) at (\trow,4.75) {};
\node[mynode, label=above:TDI Serializer] (tdiser) at (\trow,3.25) {};
\node[mynode, label=above:TDO Deserializer] (tdodeser) at (\trow,1) {};

\draw [sarrow] (tmsfifo.east) |- ++(right:0.5) |- node[above] {Data} ($(tmsser.west)+(0,0.25)$);
\draw [sarrow] ($(tmsser.east)+(0,0.25)$) -- ++(right:1.25) node [right]{TMS};
\draw [sarrow] (tdififo.east) |- ++(right:0.5) |- node[below] {Data} ($(tdiser.west)+(0,0.25)$);
\draw [sarrow] ($(tdiser.east)+(0,0.25)$) -- ++(right:1.25) node [right]{TDI};
\draw [sarrow, <-] (tdofifo.east) -| ++(right:0.5) |- node[below] {Data} ($(tdodeser.west)+(0,0.25)$);
\draw [sarrow, <-] ($(tdodeser.east)+(0,0.25)$) -- ++(right:1.25) node [right]{TDO};
\draw [sarrow] ($(iftimer.east)+(0,-0.25)$) -- ++(right:4.25) node [right]{TCK};

\draw[sarrow] (iftimer.east) -- ++(right:0.5) node[above] {Timing} -- ++(right:0.5) node [branch](timer_branch){} -- ++(up:0.75) node [branch](timer_branch2){} -- (tdiser.west);
\draw[sarrow] (timer_branch) |- (tdodeser.west);
\draw[sarrow] (timer_branch2) |- (tmsser.west);

\draw[sarrow, <->] (datareg.east) -- ++(right:0.5) node [branch](datab){} -- ++(right:0.7) node [branch](datab2){} -- (tmsfifo.west);
\draw[sarrow] (datab2) |- (tdififo.west);
\draw[sarrow] (datab) |- (tdofifo.west);

\draw[sarrow] (axi) -- ++(right:1.25) node [branch] (axib) {} -- ++(down:0.45) node [branch] (axib2) {} -- (statusreg.west);
\draw[sarrow] (axib) -- (datareg.west);
\draw[sarrow] (axib2) |-  (controlreg.west);

\draw[carrow] (iftimer.west) -- (axiif.east) node [acaption] {Control/ Status};
\draw[carrow] (ifin.west) -- ($(axiif.east)+(0,-1.5)$) node [acaption] {Control/ Status};
\draw[carrow] (ifout.west) -- ($(axiif.east)+(0,1.5)$) node [acaption] {Control/ Status};

\end{tikzpicture}
\medskip
\caption{AXI-JTAG Peripheral}
\end{figure}
\end{document}

• Without looking up, I believe the ' variants of the arrows are the [round] variants of the new arrows, so latex' = Latex[round] and stealth' = Stealth[round]. — If you use one arrow tip throughout a scope (might as well be a tikzpicture) you should add >=arrowTip to that scope and only use ->, <- and <-> (or the reverse combinations) in path specifications. Specifying >=… and -> (or similar) is not really logical. — With so many paths having the same style it might be a good idea to use edge with a few well-defined to paths. Jun 1, 2015 at 18:30
• @Qrrbrbirlbel Those tips are not the same. :( I tried and zoomed in a lot and they appear differently. Also, the various  <->, -> and <- are meant as exceptions so I didn't touch them, unless I misunderstood what you said. :D Jun 1, 2015 at 18:35
• Thanks a lot for your advice!!! Your positive feedback for this also made my day ;) I entirely agree with you that this Control/Status label was misplaced, I will update that in my own code and if needed update the thread here! kind regards, max Jun 5, 2015 at 7:24