I'm working on a picture (code given below) and I've stumbled onto two problems:
- Lines drawn from the DRAM to the GPGPU don't connect properly. Also, when regenerating the picture the DRAM and GPGPU grows apart. How do I solve this?
- The "zoom" lines from the GPGPU to the cluster go over the cluster. How do I make the cluster "lay on top of" the zoom lines?
Here's an example of what it currently looks like (the zoom lines look messed up due to the constant shifting of the DRAM described in problem 1):

Much obliged if anyone could help me with this.
\documentclass[a4paper, 11pt]{article}
% Load packages
\usepackage{tikz}
\usepackage[sc,osf]{mathpazo}
% Load TikZ libraries
\usetikzlibrary{shapes,arrows}
\usetikzlibrary{fit}
\usetikzlibrary{backgrounds}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}
% Define colors
\definecolor{lightGrey}{rgb}{0.9, 0.9, 0.9}
\definecolor{shade0}{named}{white}
\definecolor{shade1}{named}{lightGrey}
\definecolor{shade2}{rgb}{0.8, 0.8, 0.8}
\definecolor{shade3}{rgb}{0.65, 0.65, 0.65}
\definecolor{shade4}{rgb}{0.45, 0.45, 0.45}
% Text settings
\newcommand{\figureTextSize}{\tiny}
% Figure element lengths
\newlength{\gpgpuElemSize}
\setlength{\gpgpuElemSize}{8mm}
\newlength{\gpgpuElemSep}
\setlength{\gpgpuElemSep}{1mm}
% TikZ styles
\newcommand{\arrowStyle}{stealth}
\newcommand{\lineThickness}{semithick}
\tikzstyle{box} = [%
draw,
rectangle,
\lineThickness,
]
\begin{document}
\begingroup
\figureTextSize
\newcommand{\drawSM}{%
\begin{tikzpicture}[remember picture]
% SPs
\foreach \y in {1, ..., 4} {%
\foreach \x in {1, ..., 2} {%
\ifnum \x=1
\ifnum \y=1
\node [sp] (sp\y-\x) {SP};
\else
\pgfmathtruncatemacro\prevY{\y-1}
\node [sp, below=of sp\prevY-\x] (sp\y-\x) {SP};
\fi
\else
\pgfmathtruncatemacro\prevX{\x-1}
\node [sp, right=of sp\y-\prevX] (sp\y-\x) {SP};
\fi
}
}
% SFUs
\foreach \i in {1, ..., 2} {%
\ifnum \i=1
\path let \p1 = (sp1-1.south west),
\p2 = (sp1-2.north east)
in
node [%
sfu,
minimum width=\x2-\x1-\pgflinewidth,
below right,
] at ([%
yshift={-0.5\gpgpuElemSep},
] sp4-1.south west) (sfu\i) {SFU};
\else
\pgfmathtruncatemacro\prevI{\i-1}
\path let \p1 = (sp1-1.south west),
\p2 = (sp1-2.north east)
in
node [%
sfu,
minimum width=\x2-\x1-\pgflinewidth,
below=of sfu\prevI,
] (sfu\i) {SFU};
\fi
}
% Fetch/Dispatch
\node [issuer, right=of sp1-2] (issuer) {Fetch/Dispatch};
% Register file
\node [register, below=of issuer] (register) {Registers};
% Instruction cache
\node [cache, below=of register] (icache) {Inst. cache};
% Constant cach
\node [cache, below=of icache] (ccache) {Constant cache};
% Shared memory
\path let \p1 = (sfu2.south west),
\p2 = (sfu1.north east),
\p3 = (ccache.south west),
\p4 = (ccache.north east)
in
node [%
memory,
minimum width=\x4-\x3-\pgflinewidth,
minimum height=\y2-\y1-\pgflinewidth,
below=of ccache,
] (sharedmem) {%
\begin{tabular}{c}
Shared \\
memory
\end{tabular}
};
\end{tikzpicture}
}
\begin{tikzpicture}[%
auto,
>=\arrowStyle,
remember picture,
every node/.style={%
node distance=0.5\gpgpuElemSep,
},
splitted/.style={%
rectangle split,
rectangle split parts=2,
rectangle split draw splits=false,
},
gpgpu/.style={%
box,
fill=shade2,
splitted,
},
gpgpu-part/.style={%
box,
fill=shade3,
minimum size=10mm,
},
dram/.style={%
box,
fill=shade1,
minimum width=8mm,
minimum height=5mm,
node distance=\gpgpuElemSep,
},
connection/.style={%
<->,
\lineThickness,
},
cluster/.style={%
box,
fill=shade3,
splitted,
},
sm/.style={%
cluster,
fill=shade0,
},
sp/.style={%
box,
fill=shade1,
minimum size=0.5\gpgpuElemSize,
inner sep=0pt,
},
sfu/.style={%
sp,
},
register/.style={%
box,
fill=shade2,
minimum height=0.5\gpgpuElemSize,
minimum width=2\gpgpuElemSize,
inner sep=0pt,
},
cache/.style={%
register,
},
memory/.style={%
register,
},
issuer/.style={%
register,
fill=shade3,
},
zoom-line/.style={%
\lineThickness,
dashed,
},
]
\node (all-parts) {%
\begin{tikzpicture}[remember picture]
% GPGPU - zoomed out
\node [gpgpu] (gpgpu) {%
GPGPU
\nodepart{two}
\begin{tikzpicture}[remember picture]
% Clusters
\foreach \y in {1, ..., 3} {%
\foreach \x in {1, ..., 4} {%
\ifnum \x=1
\ifnum \y=1
\node [gpgpu-part] (gp\y-\x) {};
\else
\pgfmathtruncatemacro\prevY{\y-1}
\node [gpgpu-part, below=of gp\prevY-\x] (gp\y-\x) {};
\fi
\else
\pgfmathtruncatemacro\prevX{\x-1}
\node [gpgpu-part, right=of gp\y-\prevX] (gp\y-\x) {};
\fi
}
}
\end{tikzpicture}
};
% DRAMs
\node [below=of gpgpu, yshift=-2\gpgpuElemSep] {%
\begin{tikzpicture}[remember picture]
\foreach \i in {1, ..., 5} {%
\ifnum \i=1
\node [dram] (dram\i) {DRAM};
\else
\pgfmathtruncatemacro\prevI{\i-1}
\node [dram, right=of dram\prevI] (dram\i) {DRAM};
\fi
% Connect DRAM with GPGPU
\draw [connection] (dram\i) -- (dram\i |- gpgpu.south);
}
\end{tikzpicture}
};
\end{tikzpicture}
};
% Cluster - in detail
\node [cluster, right=of all-parts, xshift=4\gpgpuElemSep] (cluster-big) {%
Cluster
\nodepart{two}
\begin{tikzpicture}[remember picture]
% SMs
\node [sm] (sm1) {SM \nodepart{two}\drawSM};
\node [sm, right=of sm1] (sm2) {SM \nodepart{two}\drawSM};
% Texture memory
\path let \p1 = (sm1.south west),
\p2 = (sm2.north east)
in
node [%
memory,
minimum width=\x2-\x1-\pgflinewidth,
below right,
] at ([%
yshift={-0.5\gpgpuElemSep},
] sm1.south west) (texturemem) {Texture memory};
\end{tikzpicture}
};
% Zoom lines
\draw [zoom-line] (gp2-4.north west) -- (cluster-big.north west);
\draw [zoom-line] (gp2-4.north east) -- (cluster-big.north east);
\draw [zoom-line] (gp2-4.south west) -- (cluster-big.south west);
\draw [zoom-line] (gp2-4.south east) -- (cluster-big.south east);
\end{tikzpicture}
\endgroup
\end{document}
