In the below testcase, a small delay chain is setup using assign statements, from delay_0 to delay_1 to delay_2. The value assigned to out, delay_0 or delay_2 is determined by switch statement.
Instead of data being passed from delay_0 to delay_1 to delay_2, an incorrect value is passed from delay_0 to delay_1. It seems like it might be getting a value from delay_2 instead of delay_0 (from some experimentation).
gtkwave screenshot attached, you can see the bogus transition at 3.1ns
This was discovered in s20121218-427-g320f6d0 but also is confirmed to exist in s20130827.
Testcase:
`timescale 1ps / 1ps
module test();
reg clk = 0;
reg [1:0] dly = 0;
reg t = 1;
reg [1:0] dly_r; reg out = 0; wire delay_0, delay_1, delay_2; initial begin $dumpfile("tmp.vcd"); $dumpvars(0); #2900 t = 0; dly = 2; #1000 $finish; end always #1000 clk <= ~clk; always @(posedge clk) dly_r = dly; assign delay_0 = t ? 1'bx : 1'b1; assign #100 delay_1 = delay_0; assign #100 delay_2 = delay_1; always @(dly_r) begin case (dly_r) 0: assign out = delay_0; 2: assign out = delay_2; endcase end
endmodule
This is the same test program, but with the 'assign #100 delay_2 = delay_1;' removed. From this, it appears that delay_1 is getting its value from delay_2 instead of delay_0.
Last edit: Russ Dill 2014-02-23
The bug is in the vvp code that handles the procedural continuous assignments to 'out'. Changing your final 'always' block to
will work round the bug (and is probably a bit more efficient as well).
This bug is reduced from a form found in the Xilinx simulation libraries. If they use that design pattern in one place, its likely that its found in other places too.
When I use that workaround in the original code, I get 'internal warning: NetCAssign::nex_input() not implemented.'
That will be because you haven't removed the "assign" keywords from the assignments, so they are still being treated as continuous assignments.
Not a particularly helpful warning message, I agree. What it means is that the variables on the RHS of the continuous assignments are not being included in the sensitivity list for the always block. Given that they are continuous assignments, and hence permanently sensitive to those variables, this won't affect the simulated behaviour, but still, this should be tidied up.
I've pushed a fix for this to the git master branch.