9

I'm using tikz-timing to draw timing diagrams. My last one is a bit super sized, so I was looking for dividers to enhance readability. Some HDL simulators and waveform viewers support that feature to group signals.

My current implementation is hard coded and I'm looking for some advice how I could generalize this feature.

Here is my waveform: Waveform (clickable)

My current code look like this:

\documentclass[convert={density=600,size=2000x800,outext=.png}]{standalone}
% Document encoding, language, hyphenation, bibliography, ...
\usepackage[utf8]{inputenc}              % UTF-8 tex file input incoding
\usepackage[T1]{fontenc}                % Type1 font encoding
\usepackage[ngerman]{babel}              % new german writing rules; must be loaded before microtype
% general packages
\usepackage{courier}                            % set courier font as default for teletype writer (texttt, ttfamily, ...)
\usepackage[usenames,svgnames,table]{xcolor}    % load colors and color-names
% ext. includes, graphics, drawings, diagrams, timing
\usepackage{pgf}                      % primitive drawing library
\usepackage{tikz}                     % PGF frontend, drawing macros
  \usetikzlibrary{arrows.meta}        %    sublibrary extended arrows
\usepackage{tikz-timing}              % spezial TikZ library for waveform/timing diagrams
  \usetikztiminglibrary{advnodes}     %    sublibrary for advanced anchor nodes
  \usetikztiminglibrary{counters}     %    sublibrary for automated content generation
  \usetikztiminglibrary{clockarrows}  %    sublibrary for for arrows on rising/falling edges
  \usetikztiminglibrary{either}       %    sublibrary for new either symbol
  \usetikztiminglibrary{columntype}   %    sublibrary for 
  \usetikztiminglibrary{overlays}     %    sublibrary for overlay generation
  \usetikztiminglibrary{nicetabs}     %    sublibrary for better looking timingtables

\makeatletter     % setting math codes
  \mathcode`,="013B          % set margin for integer to fractional part delimiter sign in numbers; don't interpret comma as list delimiter
\makeatother

\begin{document}
\begin{tikztimingtable}[
  timing/table/header/.style={font=\bf},
  timing/wscale=2,
  timing/nice tabs,
  >=Latex,                                        % override tikz arrows to LaTeX default arrows
]
\\  % empty line for time scale
%      section A
RefClock\_150MHz        & h 58{c}                          13c      92{c} \\
\\  % empty line for divider
%      section B
PowerDown                & [thick,violet]      lN(BA1)h 36H          hN(BA2)l  44L  \\
PowerDownDone            & [thick,orange]  28L  N(BB1)   8H      8H   N(BB2)   38L \\
\\ % empty line for time scale
\extracode
  \makeatletter
  \tableheader{Signalname}{Signalverlauf}
  \tablerules
  % time scale
  \pgfmathsetmacro\twidthnew{\twidth/2}
  \pgfmathsetmacro\nrowsnew{76}
  \draw[->,thick] (0,0)             -- +(\twidth+1,0);
  \draw[->,thick] (0,-\nrowsnew-1)  -- +(\twidth+1,0);
  \foreach \n in {0,1,...,30}
    \pgfmathsetmacro\nnew{int(\n*2)}
    \draw(\nnew,-0.2)              -- +(0,.4)  node[above,inner sep=2pt] {\scalebox{0.75}{\n}}
         (\nnew,-\nrowsnew-1+0.2)  -- +(0,-.4) node[below,inner sep=2pt] {\scalebox{0.75}{\n}};
  \foreach \n in {36,37,...,\twidthnew}
    \pgfmathsetmacro\nnew{int(\n*2)}
    \draw(\nnew,-0.2)              -- +(0,.4)  node[above,inner sep=2pt] {\scalebox{0.75}{\n}}
         (\nnew,-\nrowsnew-1+0.2)  -- +(0,-.4) node[below,inner sep=2pt] {\scalebox{0.75}{\n}};
  % background help lines
  \begin{background}[gray,semitransparent,semithick]
    \horlines{2,4,5,...,11,13,14,15,17,18,...,21,23,24,...,30,32,33,...,40,42,43,...,46}
    \vertlines{0,2,...,60,72,74,...,\twidth}

    \shade[right color=bgred,left color=bgred]  (-18,-2.3)  rectangle +(\twidth+18,-1.2);
    \shade[right color=bgred,left color=bgred]  (-18,-17.5) rectangle +(\twidth+18,-1.2);
    \shade[right color=bgred,left color=bgred]  (-18,-24.3) rectangle +(\twidth+18,-1.2);
    \shade[right color=bgred,left color=bgred]  (-18,-34.3) rectangle +(\twidth+18,-1.2);
    \shade[right color=bgred,left color=bgred]  (-18,-49.6) rectangle +(\twidth+18,-1.2);
    \shade[right color=bgred,left color=bgred]  (-18,-66.4) rectangle +(\twidth+18,-1.2);
  \end{background}
  \begin{pgfonlayer}{background}
    \node[anchor=north west,inner sep=.5pt,fgred]  at (-18,-2.3) {Transceiver Interface};
    \node[anchor=north west,inner sep=.5pt,fgred]  at (-18,-17.5) {Synchronized Interface};
    \node[anchor=north west,inner sep=.5pt,fgred]  at (-18,-24.3) {PowerDown Control};
    \node[anchor=north west,inner sep=.5pt,fgred]  at (-18,-34.3) {ClockNet / CPLL Control};
    \node[anchor=north west,inner sep=.5pt,fgred]  at (-18,-49.6) {GTX Reset Control};
    \node[anchor=north west,inner sep=.5pt,fgred]  at (-18,-66.4) {UserLogic / FSM Control};
  \end{pgfonlayer}
\end{tikztimingtable}
\end{document}

The dividers are described in the last 16 lines. I would like to use anchors to calculate the rectangle boxes and the text nodes, but I could find a way to get the right coordinates.

What would be the best solution?

I think the best solution would be to have a macro \divider{text} which can be placed into the empty line like this.

\\  % empty line for time scale
RefClock\_150MHz        & h 58{c}                          13c      92{c} \\
\divider{Transceiver Interface} \\
PowerDown                & [thick,violet]      lN(BA1)h 36H          hN(BA2)l  44L  \\
PowerDownDone            & [thick,orange]  28L  N(BB1)   8H      8H   N(BB2)   38L \\

What would be the second best solution?

I think having a \divider[linenumber]{text} macro for the \begin{background} environment could also solve the question :).

\begin{background}[gray,semitransparent,semithick]
    \horlines{2,4,5,...,11,13,14,15,17,18,...,21,23,24,...,30,32,33,...,40,42,43,...,46}
    \vertlines{0,2,...,60,72,74,...,\twidth}

    \divider[color=bgred](2){Transceiver Interface};
\end{background}

P.S.
Having such a macro for time scale, too, would be the icing on the cake :)

  • Please complete your code so that it forms a compilable example i.e. can be copy-paste-compiled to reproduce the diagram you want help with. – cfr Mar 31 '15 at 0:48
  • @cfr I added the requested header lines to load documentclass standalone and import tikz-timing. – Paebbels Apr 1 '15 at 8:53
2
+50

Update

Now \divider{text} does the following:

  • creates a node named text;
  • creates a node named left sharing the y-coordinate with (text);
  • creates a node named right sharing the y-coordinate with (text);
  • creates a node named banner span the table from (left) to (right);
  • creates a node inside (banner) and typeset the text.
  • Since we do not know the width of the table before it finishes, all nodes except (text) are created after \extracode.
  • If there are more than one \divider's, nodes are created accordingly, sharing the y-coordinate with the corresponding mother node.

\documentclass[border=60,tikz]{standalone}
\usepackage{tikz-timing}
\usetikzlibrary{fit}
\begin{document}
\makeatletter\gdef\dividers{}
\def\divider#1{
    N(#1)@{
        \g@addto@macro\dividers{
            \path(#1)-|node(left){}(all labels.west)(#1)-|node[shift={(0,1)}](right){}(all rows.east)
            node(banner)[fill=red,opacity=.2,inner sep=0,fit=(left.center)(right.center)]{}
            (banner.west)node[red!80!black,right](text){\scriptsize #1};
        }
    }
}
\begin{tikztimingtable}[timing/wscale=2]
    \\
    RefClock\_150MHz   & h58{c}13c92{c} \\
                       & \divider{Transceiver Interface} \\
    PowerDown          & [thick,violet]lN(BA1)h36HhN(BA2)l44L \\
    PowerDownDone      & [thick,orange]28LN(BB1)8H8HN(BB2)38L \\
                       & \divider{Synchronized Interface} \\
    CC\_Power Down     & [thick,orange]2LN(CA1)37HN(CA2)43L \\
    \\
\extracode
    \tableheader{Signalname}{Signalverlauf}\tablerules
    \draw[blue,->](BA1)to[out=0,in=180](CA1);
    \fulltablegrid
    \dividers
\end{tikztimingtable}
\end{document}

Old Answer

Let us get the thing started.

\documentclass[border=60,tikz]{standalone}
\usepackage{tikz-timing}
\begin{document}
\def\strut{\large\vphantom{/}}
\begin{tikztimingtable}[timing/wscale=2]
    \\
    RefClock\_150MHz   & h58{c}13c92{c} \\
                       & [opacity=0]0D{[fill=red,text=white,opacity=1,xshift=-8cm,right,text width=80cm]\strut\Large Transceiver Interface} \\
    PowerDown          & [thick,violet]lN(BA1)h36HhN(BA2)l44L \\
    PowerDownDone      & [thick,orange]28LN(BB1)8H8HN(BB2)38L \\
                       & [opacity=0]0D{[fill=red,text=white,opacity=1,xshift=-8cm,right,text width=80cm]\strut\Large Synchronized Interface} \\
    CC\_Power Down     & [thick,orange]2LN(CA1)37HN(CA2)43L \\
    \\
\extracode
    \tableheader{Signalname}{Signalverlauf}\tablerules
    \draw[blue,->](BA1)to[out=0,in=180](CA1);
    \begin{background}[gray,semitransparent,semithick]
        \horlines{1,...,8}\vertlines{0,2,...,60,72,74,...,\twidth}
    \end{background}
\end{tikztimingtable}
\end{document}
  • Your solution has several drawbacks: xshift is hard coded as -8cm. A solution which takes max label length into account would be more generic. Secondly my solution uses \twidth to determine how many clock cycles are used, whereas your solution hopes that the diagram is smaller than 80 cm. On the other hand your solution has also an advantage: divider background and label are located in the corresponding line as a one-liner. – Paebbels Apr 1 '15 at 20:18
  • @Paebbels Exactly! I chose to hardcode these two numbers because the widths of both column are already known by you. I mean, you definitely how many signals are there and how long do they sustain. So it is a good start, I guess? – Symbol 1 Apr 2 '15 at 0:30
  • Actually I think the best way is to use \extracode\endextracode to escape from tikz and add a raw row/rule by hand. But this feature is not working. – Symbol 1 Apr 2 '15 at 0:56
  • @Paebbels now the width is calculated automatically. – Symbol 1 Apr 4 '15 at 17:08
  • Sorry for my late answer. I tested your code and it works, if tkiz-timing advnodes is disabled, otherwise a undefined control sequence error occurs: \pgf@anchor@tikztiming coordinate@border ...enter. – Paebbels Apr 8 '15 at 12:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.