-
Notifications
You must be signed in to change notification settings - Fork 692
Description
While Verilator doesn't support handling of 'X values directly, it allows setting them to unique random values rather than zeroing them, via the --x-assign
and --x-initial
flags. I have found this feature useful for detecting some errors in my code. However, these flags don't seem to handle 'Z (high-impedance) values, which are always treated as 0.
Is there a way to randomize 'Z values as well?
The following code demonstrates some errors/defects I've encountered:
`timescale 1ns/1ps
module uut (
input logic [2:0] sel,
output logic [15:0] out
);
logic [5:0][15:0] mux;
generate
for (genvar i = 0; i < 5; i++) begin //FIXME(1): should be <= 5
assign mux[i] = {4{4'(i+1)}};
end
endgenerate
assign out = mux[sel]; //FIXME(2): not handling cases 6 and 7
endmodule
module tb;
logic [2:0] sel;
logic [15:0] out;
initial begin
for (int i=0; i<8; i++) begin
sel = 3'(i);
#1;
$display("sel = %h | out = %h", sel, out);
end
$finish;
end
uut uut_inst (.*);
endmodule
In FIXME(2), the developer hasn't considered sel
being 6 or 7, in which case it tries to read from a non-existent element of an array, resulting in out=xxxx. In those cases, the desired behavior in my use case was to output 0, so I was very happy to see that "it worked" in simulation without showing any discrepancies, until I realized that it was actually generating 'X, which might result in synthesis tools generating other values.
Then I was pleased to learn about Verilator's --x-assign unique --x-initial unique
flags, which randomize the value of 'X variables. Randomizing is not a perfect solution, but it is good enough to detect this type of mistake.
However, in FIXME(1), the error results in that not all elements of the array are assigned, so element [5] is left as 'Z. Here, Verilator leaves it as all zeros even if you use the --x-assign
flag. Since Verilator doesn't seem to handle 'Z values at all, it would be nice if --x-assign
also randomized 'Z values and not just 'X values, or if separate --z-assign/--z-initial
flags were provided.
As a note of interest, I found that the plusarg +verilator+rand+reset+2
will sometimes work like this, and randomize the content of 'Z values as well, but not always (I haven't figured out the conditions for it to work/fail yet).
verilator --version = Verilator 5.039 devel rev v5.038-164-g60cbbf0ec (freshly cloned and compiled today)
Note that this version already includes the fix provided in PR #5214, which makes the runtime plusarg +verilator+rand+reset+2
unnecessary.
However, the behavior with and without this runtime option seems to differ, since (as I pointed out) with this option sometimes 'Z is randomized as well.