Verilog Lint using Verilator

9217c5e18fc45e85fd429adcfcf74421.png

FPGA design is ruthless, so we need to check it using any software we can get our hands on. Verilator is a Verilog simulator that also supports linting: static analysis of problems in design. Verilator not only finds problems that synthesis tools might miss, but it also runs quickly. Verilator is also well suited for graphics simulation using SDL.

Install Verilator

Linux

Verilator is available in most Linux distribution repositories and is suitable for running on Windows guest Linux systems.

For Debian and Ubuntu-based distributions, Verilator can be installed using apt:

apt update
apt install verilator

Apple system

On macOS, the latest version of Verilator can be installed via the Homebrew package manager:

brew install verilator

To install Verilator for other platforms (such as FreeBSD), see the official Verilator installation guide.

Basic Linting

For standalone modules, linting itself is simple:

verilator --lint-only -Wall foo.v
--lint-only- 告诉 Verilator 进行 lint 但不生成任何仿真输出
-Wall- 打开额外的风格检查

If all goes well, you will not see messages from Verilator.

If Verilator detects a potential problem, it provides clear recommendations, including how to disable warnings. The Verilator manual contains a list of possible warnings.

Let's create a simple "add" module and set up a few issues, then lint it:

`default_nettype none

module add (
    input  wire clk,
    input  wire [3:0] x,
    input  wire [3:0] y,
    output reg z,
    output reg c
    );

    always @(posedge clk) begin
        z <= x + y;
    end
endmodule

Perform lint check

$ verilator --lint-only -Wall add.v
%Warning-WIDTH: add.v:12:11: Operator ASSIGNDLY expects 1 bits on the Assign RHS, but Assign RHS's ADD generates 4 bits.
                           : ... In instance add
   12 |         z <= x + y;
      |           ^~
                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.
%Warning-UNDRIVEN: add.v:8:16: Signal is not driven: 'c'
                             : ... In instance add
    8 |     output reg c
      |                ^
%Error: Exiting due to 2 warning(s)

The first problem is width: x and y are 4 bits wide, but z has no explicit width, so it's only 1 bit wide.

We can ignore the width warning by doing this:

always @(posedge clk) begin
        /* verilator lint_off WIDTH */
        z <= x + y;
        /* verilator lint_on WIDTH */
    end

This simply hides the problem without doing anything about it.

Instead, we can fix the problem by setting the width of z to 4:

output reg [3:0] z,

Although this eliminates the Verilator warning, it may not completely resolve the problem.

For example, what happens if x and y are both 4'b1000? Our addition overflows, calculating the z value of 4'b0000. This example illustrates one of the limitations of linting: it can look at the width of different signals, but it can't account for all the logic applied to them.

So instead of fixing the width of z, we can also use it as the c carry signal, which also solves the "signal not driven" warning:

always @(posedge clk) begin
        {c,z} <= x + y;
    end

Dependencies and paths

What happens if one module depends on another module? Verilator will search the current path for a matching module. If we want to add additional directories to the module search path, we can use -I. For example, if top.v depends on modules in the ../maths directory:

verilator --lint-only -Wall -I../maths top.v

Multiple -I parameters can be used to include multiple directories.

Black boxes and empty modules

Most designs rely on vendor primitives or IP cores without sources, such as using a PLL to generate the clock. When trying to lint a module that references a vendor primitive, you will receive an error like this:

%Error: clock_pix.sv:29:5: Cannot find file containing module: 'MMCME2_BASE'
   29 |     MMCME2_BASE #(
      |     ^~~~~~~~~~~
%Error: clock_pix.sv:29:5: This may be because there's no search path specified with -I<dir>.
   29 |     MMCME2_BASE #(
      |     ^~~~~~~~~~~
        ... Looked in:
             MMCME2_BASE
             MMCME2_BASE.v
             MMCME2_BASE.sv
             obj_dir/MMCME2_BASE
             obj_dir/MMCME2_BASE.v
             obj_dir/MMCME2_BASE.sv

The first idea might be to find a way to exclude MMCME2_BASElint. Alas, Verilog "cannot be checked without careful design, requiring the entire design". We can solve this problem by creating an empty module for the primitive. Empty modules contain IO but no logic.

For example, an empty module is created for Xilinx's BUFG primitive:

module BUFG (
    input  wire logic I,
    output      logic O
    );

    // NULL MODULE

endmodule

Creating an empty module is a bit tedious, but allows you to check the entire design. To use the null module, make sure it is in Verilator's search path (see the previous section).

Linting Waivers

If you need to eliminate linter warnings for larger designs or designs using third-party sources, the /* verilator lint_off */ comment may not work. Starting with Verilator 4.028, it is possible to create Waivers to handle warnings without touching the source code. To learn more, see Stefan Wallentowitz's post Verilator Waivers (https://wallento.cs.hm.edu/post/20200612-verilator-waivers/).

Linting Shell Script

If there are many top-level modules and/or include directories, this can be checked automatically using a Makefile or a simple shell script.

The following shell script lints all top-level modules in the same directory as this script:

#!/bin/sh

DIR=`dirname $0`

echo "## Linting top modules in ${DIR}"
for f in ${DIR}/top_*\.*v; do
    echo "##   Checking ${f}";
    verilator --lint-only -Wall -I${DIR} -I${DIR}/../common $f;
done

You can adjust the -I parameter to suit your own setup. top_*.*v captures files with extensions .v and .sv.

Summarize

Today’s introduction to Verilog Lint about Verilator is like this. This is a powerful tool. I hope those who are interested can try it~

Guess you like

Origin blog.csdn.net/Pieces_thinking/article/details/133110044