verilator/test_regress/t/t_assert_ctl_pass_actions.v

215 lines
5.0 KiB
Systemverilog

// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 Antmicro
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkd(gotv, expv) do if ((gotv) !== (expv)) begin \
$write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", \
`__FILE__, `__LINE__, (gotv), (expv), `"gotv`", `"expv`"); \
`stop; \
end while (0)
// verilog_format: on
`ifdef VERILATOR
// The '$c(1)' is there to prevent inlining of the signal by V3Gate.
`define IMPURE_ONE ($c(1))
`else
// Use standard $random. The chance of getting 2 consecutive zeroes is negligible.
`define IMPURE_ONE (|($random | $random))
`endif
interface AssertCtlIface;
bit run_initial = 0;
bit initial_done = 0;
int fails = 0;
function void clear();
fails = 0;
endfunction
function void assert_off();
$assertcontrol(4, 2, 1);
endfunction
function void assert_on();
$assertcontrol(3, 2, 1);
endfunction
function void fail_check();
assert (0) `stop; else fails++;
endfunction
function void run_checks();
assert_off();
fail_check();
assert_on();
fail_check();
endfunction
initial begin
wait (run_initial);
run_checks();
initial_done = 1;
end
endinterface
module t;
bit clk = 0;
int imm_passes = 0;
int imm_fails = 0;
int vacuous_passes = 0;
int nonvacuous_passes = 0;
int concurrent_fails = 0;
int class_fails = 0;
class AssertCtlClass;
function void assert_off();
$assertcontrol(4, 2, 1);
endfunction
function void assert_on();
$assertcontrol(3, 2, 1);
endfunction
function void fail_check();
assert (0) `stop; else class_fails++;
endfunction
endclass
AssertCtlClass assert_ctl_class;
AssertCtlIface assert_ctl_iface();
virtual AssertCtlIface v_assert_ctl_iface = assert_ctl_iface;
always #5 clk = !clk;
default clocking @(posedge clk);
endclocking
assert property (@(posedge clk) 1'b0 |-> ##1 1'b1) begin
vacuous_passes++;
end else
`stop;
assert property (@(posedge clk) 1'b1 |-> ##1 1'b1) begin
nonvacuous_passes++;
end else
`stop;
assert property (@(posedge clk) 1'b1 |-> ##1 1'b0) begin
end else
concurrent_fails++;
task automatic tick_and_check(input int exp_vacuous, input int exp_nonvacuous,
input int exp_concurrent_fails);
@(posedge clk);
#2;
`checkd(vacuous_passes, exp_vacuous);
`checkd(nonvacuous_passes, exp_nonvacuous);
`checkd(concurrent_fails, exp_concurrent_fails);
endtask
initial begin
assert_ctl_class = new;
$assertcontrol(4, 16, 1);
$assertcontrol(5, 16, 1);
$assertcontrol(3*`IMPURE_ONE, 2*`IMPURE_ONE);
$assertcontrol(3, 255, 7);
$assertcontrol(6, 255, 7);
$assertcontrol(8, 255, 7);
assert (1) imm_passes++; else `stop;
`checkd(imm_passes, 1);
$assertcontrol(1, 2, 1);
$assertcontrol(4, 2, 1);
assert (1) imm_passes++; else `stop;
`checkd(imm_passes, 2);
$assertcontrol(2, 2, 1);
$assertcontrol(4, 2, 1);
assert (1) imm_passes++; else `stop;
`checkd(imm_passes, 2);
$assertcontrol(3, 2, 1);
$assertcontrol(1, 2, 1);
$assertcontrol(7, 2, 1);
assert (1) imm_passes++; else `stop;
`checkd(imm_passes, 3);
$assertcontrol(2, 2, 1);
$assertcontrol(7, 2, 1);
assert (1) imm_passes++; else `stop;
`checkd(imm_passes, 3);
$assertcontrol(10, 2, 1);
assert (1) imm_passes++; else `stop;
`checkd(imm_passes, 4);
$assertcontrol(11, 2, 1);
assert (1) imm_passes++; else `stop;
`checkd(imm_passes, 5);
$assertcontrol(6, 2, 1);
assert (0) `stop; else imm_fails++;
`checkd(imm_fails, 1);
$assertcontrol(1, 2, 1);
$assertcontrol(9, 2, 1);
assert (0) `stop; else imm_fails++;
`checkd(imm_fails, 2);
$assertcontrol(2, 2, 1);
$assertcontrol(9, 2, 1);
assert (0) `stop; else imm_fails++;
`checkd(imm_fails, 2);
$assertcontrol(8, 2, 1);
assert (0) `stop; else imm_fails++;
`checkd(imm_fails, 3);
assert_ctl_class.assert_off();
assert_ctl_class.fail_check();
`checkd(class_fails, 0);
assert_ctl_class.assert_on();
assert_ctl_class.fail_check();
`checkd(class_fails, 1);
assert_ctl_iface.run_initial = 1;
wait (assert_ctl_iface.initial_done);
`checkd(assert_ctl_iface.fails, 1);
assert_ctl_iface.clear();
assert_ctl_iface.run_checks();
`checkd(assert_ctl_iface.fails, 1);
assert_ctl_iface.clear();
v_assert_ctl_iface.run_checks();
`checkd(assert_ctl_iface.fails, 1);
$assertcontrol(9, 1, 1);
tick_and_check(1, 0, 0);
tick_and_check(2, 1, 0);
$assertcontrol(11, 1, 1);
tick_and_check(2, 2, 0);
$assertcontrol(7, 1, 1);
tick_and_check(2, 2, 0);
$assertcontrol(10, 1, 1);
tick_and_check(2, 3, 0);
$assertcontrol(6, 1, 1);
tick_and_check(3, 4, 0);
$assertcontrol(8, 1, 1);
tick_and_check(4, 5, 1);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule