4

Similar to this question, I want to be able to colour my Verilog HDL code to match the Intel Altera Quartus GUI software typset. I believe there are no packages like matlab-prettifier to automatically render the Verilog HDL.

I have added a image to show what Quartus interprets verilog as below.

Verilog Snapshot

I've started off some listing styling but am not really sure how to work with the [A:B] number formatting that is an orange colour.

    \definecolor{vgreen}{RGB}{104,180,104}
    \definecolor{vblue}{RGB}{49,49,255}
    \definecolor{vorange}{RGB}{255,143,102}
    \lstdefinestyle{verilog-style}
    {
        language=Verilog,
        basicstyle=\small,
        keywordstyle=\color{vblue},
        identifierstyle=\color{black},
        commentstyle=\color{vgreen},
        numbers=left,
        numberstyle={\tiny \color{black}},
        numbersep=10pt,
        tabsize=8
    }
  • Does tex.stackexchange.com/a/42895/647 solve your issue? – TH. Jun 28 '17 at 6:03
  • @TH. Not quite, I think this is a closer bet. – Mr G Jun 28 '17 at 7:35
  • I've found a matching (ie, [is]{\fn}{[}{:}}) that works based on the above example, but when there's more than once space before the matching the function will also be called for that set of spaces not including the first space... – Mr G Jun 28 '17 at 13:55
  • Another issue is that the indexing styles can appear as [A:B] or just as [A]. This is complicated to match to because of the same starting delimeter. – Mr G Jun 28 '17 at 14:08
  • It's been a very long time since I wrote any verilog. Are A and B in [A:B] and [A] always literal numbers? – TH. Jun 28 '17 at 15:19
2

Hack to make this work.

I initially wrote the stuff below about listings really bizarre behavior and then immediately discovered a hack that makes this work. The key is to use moredelim=*[s][\colorIndex]{[}{]} where \colorIndex is a new macro that examines the listings-internal token register \lst@token to decide what to typeset. It also makes : display in a literate style which combines with the * option to moredelim to make this work. Contrary to my assertion at the very bottom of this answer, \lst@token does contain the material to be typeset, but not when ** is given to moredelim which was how I tested.

\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}
\definecolor{vgreen}{RGB}{104,180,104}
\definecolor{vblue}{RGB}{49,49,255}
\definecolor{vorange}{RGB}{255,143,102}

\lstdefinestyle{verilog-style}
{
    language=Verilog,
    basicstyle=\small\ttfamily,
    keywordstyle=\color{vblue},
    identifierstyle=\color{black},
    commentstyle=\color{vgreen},
    numbers=left,
    numberstyle=\tiny\color{black},
    numbersep=10pt,
    tabsize=8,
    moredelim=*[s][\colorIndex]{[}{]},
    literate=*{:}{:}1
}

\makeatletter
\newcommand*\@lbracket{[}
\newcommand*\@rbracket{]}
\newcommand*\@colon{:}
\newcommand*\colorIndex{%
    \edef\@temp{\the\lst@token}%
    \ifx\@temp\@lbracket \color{black}%
    \else\ifx\@temp\@rbracket \color{black}%
    \else\ifx\@temp\@colon \color{black}%
    \else \color{vorange}%
    \fi\fi\fi
}
\makeatother

\usepackage{trace}
\begin{document}

\begin{lstlisting}[style={verilog-style}]
module Mixing {
    ///////// ADC /////////
    inout              ADC_CS_N,
    output             ADC_DIN,
    input              ADC_DOUT,
    output             ADC_SCLK,

    ///////// ADC /////////
    input              AUD_ADCDAT,
    inout              AUD_ADCLRCK,
    inout              AUD_BCLK,
    output             AUD_DACDAT,
    inout              AUD_DACLRCK,
    output             AUD_XCK,

    ///////// clocks /////////
    input              clock2_50,
    input              clock3_50,
    input              clock4_50,
    input              clock_50,

    ///////// HEX /////////
    output      [6:0]  HEX0,
    output      [6:0]  HEX1,
    output      [6:0]  HEX2,
    output      [6:0]  HEX3,
    output      [6:0]  HEX4,
    output      [6:0]  HEX5,

    ///////// FOO /////////
    output      [2]    FOO,
}
\end{lstlisting}
\end{document}

enter image description here

Bizarre listings behavior.

This was initially a nonanswer that was too complicated for a comment. Almost immediately after posting it, I found the workaround above.

The two "obvious" ideas I have for this are the following.

  1. Make : be typeset as literate in black. Combining this with the * or ** option in moredelim typesets the colon in black.
  2. Use the answer you pointed out in the comments to create a new macro \colorIndex that takes one argument and typesets it in orange with brackets surrounding it. This is in conjunction with the is delimiter style.

Unfortunately, this doesn't solve the problem. The argument that get passed to \colorIndex is fairly complicated, it gets used multiple times to style various parts, including the space before the [6:0]!

Here's an example that demonstrates this bizarre behavior.

\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}
\definecolor{vgreen}{RGB}{104,180,104}
\definecolor{vblue}{RGB}{49,49,255}
\definecolor{vorange}{RGB}{255,143,102}

\lstdefinestyle{verilog-style}
{
    language=Verilog,
    basicstyle=\small\ttfamily,
    keywordstyle=\color{vblue},
    identifierstyle=\color{black},
    commentstyle=\color{vgreen},
    numbers=left,
    numberstyle=\tiny\color{black},
    numbersep=10pt,
    tabsize=8,
    literate=*{:}{{\textcolor{black}{:}}}1
}

\newcommand\colorIndex[1]{[\textcolor{vorange}{#1}]}

\begin{document}

No delimiters.
\begin{lstlisting}[style={verilog-style}]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=[s][\color{vorange}]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={[s][\color{vorange}]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=*[s][\color{vorange}]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={*[s][\color{vorange}]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=**[s][\color{vorange}]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={**[s][\color{vorange}]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=[s][\colorIndex]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={[s][\colorIndex]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=*[s][\colorIndex]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={*[s][\colorIndex]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=**[s][\colorIndex]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={**[s][\colorIndex]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\newpage
\verb!moredelim=[is][\color{vorange}]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={[is][\color{vorange}]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=*[is][\color{vorange}]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={*[is][\color{vorange}]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=**[is][\color{vorange}]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={**[is][\color{vorange}]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=[is][\colorIndex]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={[is][\colorIndex]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=*[is][\colorIndex]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={*[is][\colorIndex]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}

\verb!moredelim=**[is][\colorIndex]{[}{]}!
\begin{lstlisting}[
        style={verilog-style},
        moredelim={**[is][\colorIndex]{[}{]}}
    ]
    output      [6:0]  HEX0,
    output      [2]    FOO,
\end{lstlisting}
\end{document}

You can see how the various settings for moredelim change the output. First, using the [s] style of delimiters.

enter image description here

And now using [is].

enter image description here

I really can't explain this behavior. I was hoping to use moredelim=*[s][\colorIndex]{[}{]} and have \colorIndex examine its arguments to decide how to style the various pieces.

I tried poking around at listings internals to see if \colorIndex could determine what it was about to typeset in order to set the appropriate color, but I didn't see anything useful. (There's a \lst@token which is a token register which looks like it's used to fill in the various parts of the line, but it was always empty when \colorIndex was called.)

I don't have time to investigate this further right now, but hopefully someone else will have an idea.

| improve this answer | |
  • I used moredelim too, but didn't have sufficient knowledge of the * option to let another rule inside. Also experienced same spacing errors. Bizzare! This is also the first time I've seen conditionals used in TeX, that's very useful. Perhaps some comments on the core functional pieces of the code will help improve it's readability for people who haven't seen such TeX command use before. I didn't realize you actually need to comment the end of lines to avoid whitespace interfering with your commands! I consider the spaces behavior error as unresolved, but the hack solves the main problem. – Mr G Jun 29 '17 at 8:40
  • It's just testing if \@temp is defined to a single bracket or colon token and if so, setting the color to black (that might actually be unnecessary) otherwise it sets it to orange. TeX conditionals are sufficiently complex that without a specific question about them, a full explanation would likely be long. But briefly, \ifx checks if the following two tokens have the same definition. It doesn't expand the two tokens. Check TeX by Topic for the details. – TH. Jun 29 '17 at 13:48
1

I realise this is quite an old question, but I've had the same issues with needing to put Verilog code in a Latex document. In my case I wanted it to follow the style of Notepad++, but its easy enough to change the colouring to match your preferences.

The accepted answer doesn't work for my needs as it doesn't handle verilog constants well, nor parameter names inside square brackets.

After not finding what I needed, I was able to shamelessly adapter this answer for SuperCollider to work instead with Verilog.

I've attached an example document below with the listing style declarations, which essentially extend the existing Verilog language definition to include highlighting for constants, operators, preprocessor directives, and system commands.

The only one that's a bit iffy is the / operator, which will only highlight if it has a space on either side of it - otherwise the literate that finds it was capturing the comments as well and messing those up.

Example Output of Below Code

Minimal example used to produce the above output:


% Packages

\documentclass{article}

% Code Handling
\usepackage{listings}
\usepackage{xcolor}
\usepackage[lighttt]{lmodern}


\begin{document}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Verilog Code Style
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\definecolor{verilogcommentcolor}{RGB}{104,180,104}
\definecolor{verilogkeywordcolor}{RGB}{49,49,255}
\definecolor{verilogsystemcolor}{RGB}{128,0,255}
\definecolor{verilognumbercolor}{RGB}{255,143,102}
\definecolor{verilogstringcolor}{RGB}{160,160,160}
\definecolor{verilogdefinecolor}{RGB}{128,64,0}
\definecolor{verilogoperatorcolor}{RGB}{0,0,128}

% Verilog style
\lstdefinestyle{prettyverilog}{
   language           = Verilog,
   commentstyle       = \color{verilogcommentcolor},
   alsoletter         = \$'0123456789\`,
   literate           = *{+}{{\verilogColorOperator{+}}}{1}%
                         {-}{{\verilogColorOperator{-}}}{1}%
                         {@}{{\verilogColorOperator{@}}}{1}%
                         {;}{{\verilogColorOperator{;}}}{1}%
                         {*}{{\verilogColorOperator{*}}}{1}%
                         {?}{{\verilogColorOperator{?}}}{1}%
                         {:}{{\verilogColorOperator{:}}}{1}%
                         {<}{{\verilogColorOperator{<}}}{1}%
                         {>}{{\verilogColorOperator{>}}}{1}%
                         {=}{{\verilogColorOperator{=}}}{1}%
                         {!}{{\verilogColorOperator{!}}}{1}%
                         {^}{{\verilogColorOperator{^}}}{1}%
                         {|}{{\verilogColorOperator{|}}}{1}%
                         {=}{{\verilogColorOperator{=}}}{1}%
                         {[}{{\verilogColorOperator{[}}}{1}%
                         {]}{{\verilogColorOperator{]}}}{1}%
                         {(}{{\verilogColorOperator{(}}}{1}%
                         {)}{{\verilogColorOperator{)}}}{1}%
                         {,}{{\verilogColorOperator{,}}}{1}%
                         {.}{{\verilogColorOperator{.}}}{1}%
                         {~}{{\verilogColorOperator{$\sim$}}}{1}%
                         {\%}{{\verilogColorOperator{\%}}}{1}%
                         {\&}{{\verilogColorOperator{\&}}}{1}%
                         {\#}{{\verilogColorOperator{\#}}}{1}%
                         {\ /\ }{{\verilogColorOperator{\ /\ }}}{3}%
                         {\ _}{\ \_}{2}%
                        ,
   morestring         = [s][\color{verilogstringcolor}]{"}{"},%
   identifierstyle    = \color{black},
   vlogdefinestyle    = \color{verilogdefinecolor},
   vlogconstantstyle  = \color{verilognumbercolor},
   vlogsystemstyle    = \color{verilogsystemcolor},
   basicstyle         = \scriptsize\fontencoding{T1}\ttfamily,
   keywordstyle       = \bfseries\color{verilogkeywordcolor},
   numbers            = left,
   numbersep          = 10pt,
   tabsize            = 4,
   escapeinside       = {/*!}{!*/},
   upquote            = true,
   sensitive          = true,
   showstringspaces   = false, %without this there will be a symbol in the places where there is a space
   frame              = single
}


% This is shamelessly stolen and modified from:
% https://github.com/jubobs/sclang-prettifier/blob/master/sclang-prettifier.dtx
\makeatletter

% Language name
\newcommand\language@verilog{Verilog}
\expandafter\lst@NormedDef\expandafter\languageNormedDefd@verilog%
  \expandafter{\language@verilog}
  
% save definition of single quote for testing
\lst@SaveOutputDef{`'}\quotesngl@verilog
\lst@SaveOutputDef{``}\backtick@verilog
\lst@SaveOutputDef{`\$}\dollar@verilog

% Extract first character token in sequence and store in macro 
% firstchar@verilog, per http://tex.stackexchange.com/a/159267/21891
\newcommand\getfirstchar@verilog{}
\newcommand\getfirstchar@@verilog{}
\newcommand\firstchar@verilog{}
\def\getfirstchar@verilog#1{\getfirstchar@@verilog#1\relax}
\def\getfirstchar@@verilog#1#2\relax{\def\firstchar@verilog{#1}}

% Initially empty hook for lst
\newcommand\addedToOutput@verilog{}
\lst@AddToHook{Output}{\addedToOutput@verilog}

% The style used for constants as set in lstdefinestyle
\newcommand\constantstyle@verilog{}
\lst@Key{vlogconstantstyle}\relax%
   {\def\constantstyle@verilog{#1}}

% The style used for defines as set in lstdefinestyle
\newcommand\definestyle@verilog{}
\lst@Key{vlogdefinestyle}\relax%
   {\def\definestyle@verilog{#1}}

% The style used for defines as set in lstdefinestyle
\newcommand\systemstyle@verilog{}
\lst@Key{vlogsystemstyle}\relax%
   {\def\systemstyle@verilog{#1}}

% Counter used to check current character is a digit
\newcount\currentchar@verilog
  
% Processing macro
\newcommand\@ddedToOutput@verilog
{%
   % If we're in \lstpkg{}' processing mode...
   \ifnum\lst@mode=\lst@Pmode%
      % Save the first token in the current identifier to \@getfirstchar
      \expandafter\getfirstchar@verilog\expandafter{\the\lst@token}%
      % Check if the token is a backtick
      \expandafter\ifx\firstchar@verilog\backtick@verilog
         % If so, then this starts a define
         \let\lst@thestyle\definestyle@verilog%
      \else
         % Check if the token is a dollar
         \expandafter\ifx\firstchar@verilog\dollar@verilog
            % If so, then this starts a system command
            \let\lst@thestyle\systemstyle@verilog%
         \else
            % Check if the token starts with a single quote
            \expandafter\ifx\firstchar@verilog\quotesngl@verilog
               % If so, then this starts a constant without length
               \let\lst@thestyle\constantstyle@verilog%
            \else
               \currentchar@verilog=48
               \loop
                  \expandafter\ifnum%
                  \expandafter`\firstchar@verilog=\currentchar@verilog%
                     \let\lst@thestyle\constantstyle@verilog%
                     \let\iterate\relax%
                  \fi
                  \advance\currentchar@verilog by \@ne%
                  \unless\ifnum\currentchar@verilog>57%
               \repeat%
            \fi
         \fi
      \fi
      % ...but override by keyword style if a keyword is detected!
      %\lsthk@DetectKeywords% 
   \fi
}

% Add processing macro only if verilog
\lst@AddToHook{PreInit}{%
  \ifx\lst@language\languageNormedDefd@verilog%
    \let\addedToOutput@verilog\@ddedToOutput@verilog%
  \fi
}

% Colour operators in literate
\newcommand{\verilogColorOperator}[1]
{%
  \ifnum\lst@mode=\lst@Pmode\relax%
   {\bfseries\textcolor{verilogoperatorcolor}{#1}}%
  \else
    #1%
  \fi
}

\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% End Verilog Code Style
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\begin{lstlisting}[style={prettyverilog}]
/*
* A Testbench Example
*/

`timescale 1 ns/100 ps

module SynchronousTestBench_tb (
  input [4:0] notReally
);

// Parameter Declarations
localparam NUM_CYCLES = 50;       //Simulate this many clock cycles.
localparam CLOCK_FREQ = 50000000; //Clock frequency (in Hz)
localparam RST_CYCLES = 2;        //Number of cycles of reset at beginning.

// Test Bench Generated Signals
reg  clock;
reg  reset;

// Device Under Test
// A counter which starts at 8'hAF.
wire [7:0] count;
counter dut (
   .clock(clock     ),
   .reset(reset     ),
   
   .start(8'hAF     ),
   .count(count[7:0])
);

// Reset Logic
initial begin
   reset = 1'b1;                        //Start in reset.
   repeat(RST_CYCLES) @(posedge clock); //Wait for a couple of clocks
   reset = 1'b0;                        //Then clear the reset signal.
end

//Clock generator + simulation time limit.
initial begin
   clock = 1'b0; //Initialise the clock to zero.
end
//Next we convert our clock period to nanoseconds and half it
//to work out how long we must delay for each half clock cycle
//Note how we convert the integer CLOCK_FREQ parameter it a real
real HALF_CLOCK_PERIOD = (1000000000.0 / $itor(CLOCK_FREQ)) / 2.0;

//Now generate the clock
integer half_cycles = 0;
always begin
   //Generate the next half cycle of clock
   #(HALF_CLOCK_PERIOD);          //Delay for half a clock period.
   clock = ~clock;                //Toggle the clock
   half_cycles = half_cycles + 1; //Increment the counter
   
   //Check if we have simulated enough half clock cycles
   if (half_cycles == (2*NUM_CYCLES)) begin 
       //Once the number of cycles has been reached
       half_cycles = 0;
       $stop;
       //Note: We can continue the simualation after this breakpoint using 
       //"run -continue" or "run ### ns" in modelsim.
   end
end
endmodule
\end{lstlisting}

\end{document}


| improve this answer | |

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.