我刚刚开始使用 TikZ,这个框图是我的第一件艺术品。为什么是艺术品?因为这花了我很长时间,而且我感觉如果我对 TikZ 有更深入的了解,绘制这种图表可以大大简化。你能帮我找到简化此图表的方法或找到合适的库吗?
基本上,它是数字电路的框图,描述了该电路的基本构成块。(如果您想知道该电路的用途,请参考:https://github.com/Xilinx/XilinxVirtualCable,这是一个具有类似目标的项目)。
\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}
答案1
实际上这是非常好的代码。我做了一些修改:
由于
arrows
已弃用,我改为使用arrows.meta
。不幸的是,latex'
和stealth'
不可用,所以我改用最相似的箭头,即>={Stealth}
。您可以继续使用arrows
,它与和一起可用,arrows.spaced
以实现兼容性,但它们被视为已弃用。我把你的 tikzset 放在了序言中。这不是必需的,这只是我的个人偏好,因为我发现它更有条理:
设置和选项 -> 序言
实际代码 -> 文档我通常先绘制所有节点,然后绘制所有边。这是为了更好的可读性,但这仍然是个人喜好。
由于您的大多数节点
rectangle,draw=black, top color=white,text centered
在每种节点样式中都重复出现,因此我添加了另一种样式,并basic
使用这些选项。然后,如果您basic
在其他节点样式中编写,则将包括所有这些选项,不同之处在于现在您没有过于拥挤的样式选项。请参阅代码。小黑圈指定为
branch/.style={fill,circle,minimum size=2pt,inner sep=0pt},
在它们周围创造了一个白色空间:
这是因为您没有设置默认为正的外部 sep。如果您将其设置为 0,则仍然有空间,但是如果您将其设置为
-1pt
,则:顺便说一句,如果你说
inner/outer sep=0
,则无需指定pt, cm,ex,em
等等。只需 0 即可。
我不认为还有其他事情,也许我可以修复间距Control/Status
- 让我知道,你的代码写得很好,特别是如果这是你的第一个代码。
输出
代码
\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}