172 lines
4.2 KiB
Systemverilog
172 lines
4.2 KiB
Systemverilog
// DESCRIPTION: Verilator: Verilog Test module
|
|
//
|
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
|
// SPDX-FileCopyrightText: 2026 Wilson Snyder
|
|
// SPDX-License-Identifier: CC0-1.0
|
|
|
|
// Disabling a named fork..join / fork..join_any block from one of its own
|
|
// branches must terminate the sibling branches, including any that are
|
|
// suspended on a delay. This is the join/join_any analogue of the
|
|
// fork..join_none cases in t_disable_inside (#6591): the bug was that a sibling
|
|
// spawned later in source order registered its process for kill only after the
|
|
// disabling branch had already issued the kill, so the sibling survived and its
|
|
// $stop fired one time unit later.
|
|
|
|
// verilog_format: off
|
|
`define stop $stop
|
|
`define checkt(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0t exp=%0t (%t !== %t)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
|
|
// verilog_format: on
|
|
|
|
module t;
|
|
|
|
// fork..join: the disabling branch comes first, the delayed sibling second.
|
|
initial begin
|
|
fork : fork_blk2
|
|
begin
|
|
`checkt($time, 0);
|
|
disable fork_blk2;
|
|
$stop;
|
|
end
|
|
begin
|
|
`checkt($time, 0);
|
|
#1 $stop;
|
|
end
|
|
join
|
|
end
|
|
|
|
// fork..join: the delayed sibling comes first, the disabling branch second.
|
|
initial begin
|
|
fork : fork_blk3
|
|
begin
|
|
`checkt($time, 0);
|
|
#1 $stop;
|
|
end
|
|
begin
|
|
`checkt($time, 0);
|
|
disable fork_blk3;
|
|
$stop;
|
|
end
|
|
join
|
|
end
|
|
|
|
// fork..join: the delayed sibling also contains an unreachable disable, which
|
|
// makes LinkJump wrap its registration in a JumpBlock. It must still register
|
|
// before the synthetic fork-start delay so the earlier disable kills it.
|
|
initial begin
|
|
fork : fork_blk_wrap
|
|
begin
|
|
`checkt($time, 0);
|
|
disable fork_blk_wrap;
|
|
$stop;
|
|
end
|
|
begin
|
|
`checkt($time, 0);
|
|
#1;
|
|
if ($c("false")) disable fork_blk_wrap;
|
|
$stop;
|
|
end
|
|
join
|
|
end
|
|
|
|
// fork..join_any: the disabling branch comes first, the delayed sibling second.
|
|
initial begin
|
|
fork : fork_blk2a
|
|
begin
|
|
`checkt($time, 0);
|
|
disable fork_blk2a;
|
|
$stop;
|
|
end
|
|
begin
|
|
`checkt($time, 0);
|
|
#1 $stop;
|
|
end
|
|
join_any
|
|
end
|
|
|
|
// fork..join_any: the delayed sibling comes first, the disabling branch second.
|
|
initial begin
|
|
fork : fork_blk3a
|
|
begin
|
|
`checkt($time, 0);
|
|
#1 $stop;
|
|
end
|
|
begin
|
|
`checkt($time, 0);
|
|
disable fork_blk3a;
|
|
$stop;
|
|
end
|
|
join_any
|
|
end
|
|
|
|
// fork..join_any: the delayed sibling's own unreachable disable again forces a
|
|
// JumpBlock wrapper around its registration.
|
|
initial begin
|
|
fork : fork_blk_wrap_any
|
|
begin
|
|
`checkt($time, 0);
|
|
disable fork_blk_wrap_any;
|
|
$stop;
|
|
end
|
|
begin
|
|
`checkt($time, 0);
|
|
#1;
|
|
if ($c("false")) disable fork_blk_wrap_any;
|
|
$stop;
|
|
end
|
|
join_any
|
|
end
|
|
|
|
// fork..join that can be disabled, but takes the path where disable is not
|
|
// reached: both branches must run to completion with their timing intact.
|
|
initial begin
|
|
fork : fork_blk4
|
|
begin
|
|
`checkt($time, 0);
|
|
if ($c("false")) begin
|
|
disable fork_blk4;
|
|
$stop;
|
|
end
|
|
#1;
|
|
`checkt($time, 1);
|
|
end
|
|
begin
|
|
`checkt($time, 0);
|
|
#1;
|
|
`checkt($time, 1);
|
|
end
|
|
join
|
|
end
|
|
|
|
// Deeply nested fork..join: the named fork is several levels deep inside other
|
|
// forks and one of its own branches disables it. The delayed sibling at that
|
|
// deep level must still be killed, so the fix has to work when the disable-able
|
|
// fork is itself nested inside other (suspending) forks.
|
|
initial begin
|
|
fork
|
|
begin
|
|
fork
|
|
begin
|
|
fork : fork_deep
|
|
begin
|
|
`checkt($time, 0);
|
|
disable fork_deep;
|
|
$stop;
|
|
end
|
|
begin
|
|
`checkt($time, 0);
|
|
#1 $stop;
|
|
end
|
|
join
|
|
end
|
|
join
|
|
end
|
|
join
|
|
end
|
|
|
|
initial begin
|
|
#10;
|
|
$write("*-* All Finished *-*\n");
|
|
$finish;
|
|
end
|
|
endmodule
|