From 2d611c43477a5c8f7df90c4d48ab7532d800ce3e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 7 Jan 2024 10:17:10 -0800 Subject: [PATCH] ivtest: pr1002: Avoid race condition The pr1002 test has a always block with the `dataout` in its sensitivity list. It compares `dataout` to `expected_dataout`. Both `dataout` and `expected_dataout` depend on `datain` and are updated in the same cycle. This means there is no guarantee in which order they are updated and the always block might get scheduled before `expected_dataout` has been updated. This can lead to a test failure. To avoid this slightly change the test to use a task to perform the comparison and add an explicit delay before the task is executed so that all updates have a chance to be fully resolved Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/pr1002.v | 47 ++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/ivtest/ivltests/pr1002.v b/ivtest/ivltests/pr1002.v index ce11d5a97..ff8ff7b72 100644 --- a/ivtest/ivltests/pr1002.v +++ b/ivtest/ivltests/pr1002.v @@ -8,29 +8,11 @@ assign dataout = datain >>> 2; reg test_failed; -initial - begin - test_failed = 0; - #1 datain = 14'h0FFF; - #1 datain = 14'h0000; - #1 datain = 14'h1FFF; - #1 datain = 14'h1000; - #1 datain = 14'h2FFF; - #1 datain = 14'h2000; - #1 datain = 14'h3FFF; - #1 datain = 14'h3000; - #2; - if (test_failed) - $display("TEST FAILED :-("); - else - $display("TEST PASSED :-)"); - end - wire signed [15:0] expected_dataout; assign expected_dataout = ($signed({datain[13:2], 2'b0}) / 4) ; -always @(dataout) +task check_data; if (expected_dataout != dataout) begin $display("datain = %d dataout = %h expected = %h ... CHECK FAILED", datain, dataout, expected_dataout); @@ -38,5 +20,32 @@ always @(dataout) end else $display("datain = %d dataout = %d expected = %d ... CHECK PASSED", datain, dataout, expected_dataout); +endtask + +initial + begin + test_failed = 0; + #1 datain = 14'h0FFF; + #0 check_data; // #0 delay to allow the wire to resolve + #1 datain = 14'h0000; + #0 check_data; + #1 datain = 14'h1FFF; + #0 check_data; + #1 datain = 14'h1000; + #0 check_data; + #1 datain = 14'h2FFF; + #0 check_data; + #1 datain = 14'h2000; + #0 check_data; + #1 datain = 14'h3FFF; + #0 check_data; + #1 datain = 14'h3000; + #0 check_data; + #2; + if (test_failed) + $display("TEST FAILED :-("); + else + $display("TEST PASSED :-)"); + end endmodule // top