1
\$\begingroup\$

I have this very basic combinational logic in file tb_shift_right.v:

module tb_shift_right;

    logic a;
    logic b;
    logic c;
    logic s;

    always_comb begin
        s = a ^ b;
        c = a & b;
    end

initial begin
    a = 1'b1;
    b = 1'b0;
    $display("a=%b, b=%b", a, b);
    //#1
    $display("s=%b, c=%b", s, c);
    $finish();
end

endmodule

The driving cpp file comes straight out of the verilator pdf documentation tb_shift_right.cpp:

#include "Vtb_shift_right.h"
#include "verilated.h"

int main(int argc, char **argv)
{
    VerilatedContext *contextp = new VerilatedContext;
    contextp->commandArgs(argc, argv);
    Vtb_shift_right *top = new Vtb_shift_right{contextp};
    while (!contextp->gotFinish())
    {
        top->eval();
    }
    delete top;
    delete contextp;
    return 0;
}

Then I compile it on WSL2 with a verilator compiled from sources (Verilator 5.016 2023-09-16 rev v5.014-149-g57c816f90):

verilator -Wall --timing --exe --build tb_shift_right.cpp --cc tb_shift_right.v

And in the testbench, the output signals are not updated; they are always 0. It does not matter if I use logic or reg as inputs, and logic or wire or reg as outputs. Using always@ does not matter either. If I uncomment the #1 (that is why I need the --timing parameter), then the simulation hangs before the second $display.

Is it supposed to work at all, or am I missing something in Verilog? Or can it be that this is a WSL (Windows Subsystem for Linux) problem?

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

The intent of Verilator is to convert synthesizable Verilog design modules into C++ code; it is not intended to convert Verilog testbench code. Here is a quote from the PDF (Release 5.016, 2023-09-16):

10.3.1 Synthesis Subset
Verilator supports the Synthesis subset with other verification 
constructs being added over time.

I recommend creating a simple design module with inputs and outputs, and just trying to verilate that instead of a full testbench module:

module shift_right (
    input a,
    input b,
    output logic c,
    output logic s
);

    always_comb begin
        s = a ^ b;
        c = a & b;
    end
endmodule

Verilator is supposed to just generate the C++ code from the synthetizable part of Verilog and then you are supposed to write C++ testbenches instead of Verilog testbenches.

\$\endgroup\$
4
  • \$\begingroup\$ Yeah, I tried to verilate modules in the first place. When it did not work, I simplified it until it became obvious that even the most basic combinatorial logic does not work. So either I do not get the most basic of verilog, or it is not supposed to work for some reason. \$\endgroup\$
    – NoiseEHC
    Sep 19, 2023 at 14:59
  • \$\begingroup\$ @NoiseEHC: Do you really need to use Verilator? If not, I recommend you stick to just Verilog. That should simplify things for you. Since my answer solves your main point about why you have problems with veriltaing your code, I suggest you Accept the answer. You can always open new questions if you have further problems. \$\endgroup\$
    – toolic
    Sep 19, 2023 at 15:17
  • \$\begingroup\$ Then sorry, but I do not seem to understand the answer. Does it mean that Verilator is supposed to just generate the C++ code from the synthetizable part of verilog and then I am supposed to write C++ testbenches instead of verilog testbenches? \$\endgroup\$
    – NoiseEHC
    Sep 19, 2023 at 15:32
  • \$\begingroup\$ @NoiseEHC: Yes. I updated the answer. \$\endgroup\$
    – toolic
    Sep 19, 2023 at 15:44
-1
\$\begingroup\$

As it turned out, the above answer was wrong. It is indeed possible to use verilator to create procedural testbenches.

Save the above verilog source to tb_shift_right.sv, then compile it with:

verilator --binary --cc tb_shift_right.sv

For this you will need to compile verilator from source, as --binary is only supported since version 5.something. Mine is this:

verilator --version
Verilator 5.016 2023-09-16 rev v5.014-149-g57c816f90

Note that you need the #1 delay in the code, otherwise the outputs (s and c) are not updated.

\$\endgroup\$
1
  • \$\begingroup\$ Labeling my answer as "wrong" is misleading. I did not say it was impossible to use Verilator to to create testbenches. Please re-read the answer. I quoted directly from the Verilator documentation, which clearly states it is not intended for testbench code. Of course it is possible to use it for some testbench code, but you can't rely on it to support all syntax. \$\endgroup\$
    – toolic
    Oct 2, 2023 at 11:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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