mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Fix disable fork and wait fork affecting pending NBA updates (#8483)
This commit is contained in:
@@ -88,6 +88,7 @@ enum NodeFlag : uint8_t {
|
||||
T_FORCES_PROC = 1 << 3, // Forces VlProcess allocation
|
||||
T_NEEDS_PROC = 1 << 4, // Needs access to VlProcess if it's allocated
|
||||
T_HAS_PROC = 1 << 5, // Has VlProcess argument in the signature
|
||||
T_NBA_UPDATE = 1 << 6, // Fork branch of a pending NBA update, which is not a subprocess
|
||||
};
|
||||
|
||||
enum ForkType : uint8_t {
|
||||
@@ -1222,6 +1223,7 @@ class TimingControlVisitor final : public VNVisitor {
|
||||
AstBegin* beginp = VN_CAST(controlp, Begin);
|
||||
if (!beginp) beginp = new AstBegin{nodep->fileline(), "", controlp, false};
|
||||
forkp->addForksp(beginp);
|
||||
addFlags(beginp, T_NBA_UPDATE);
|
||||
controlp = forkp;
|
||||
}
|
||||
UASSERT_OBJ(nodep, controlp, "Assignment should have timing control");
|
||||
@@ -1438,6 +1440,9 @@ class TimingControlVisitor final : public VNVisitor {
|
||||
VL_RESTORER(m_procp);
|
||||
VL_RESTORER(m_hasProcess);
|
||||
m_hasProcess |= hasFlags(nodep, T_HAS_PROC);
|
||||
// A pending NBA update is not a subprocess of the process that scheduled it, so it is
|
||||
// unaffected by 'disable fork' and 'wait fork' (IEEE 1800-2023 9.6.1, 9.6.3)
|
||||
if (hasFlags(nodep, T_NBA_UPDATE)) m_hasProcess = false;
|
||||
m_procp = nodep;
|
||||
if (m_hasProcess) nodep->setNeedProcess();
|
||||
iterateChildren(nodep);
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Pending NBA updates are not subprocesses for disable/wait fork
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of either the GNU Lesser General Public License Version 3
|
||||
# or the Perl Artistic License Version 2.0.
|
||||
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
@@ -0,0 +1,61 @@
|
||||
// DESCRIPTION: Verilator: Pending NBA updates are not subprocesses for disable/wait fork
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
// 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
|
||||
|
||||
interface bus_if;
|
||||
int data;
|
||||
endinterface
|
||||
|
||||
class Cls;
|
||||
virtual bus_if vif;
|
||||
task set(int v);
|
||||
vif.data <= v;
|
||||
endtask
|
||||
endclass
|
||||
|
||||
module t;
|
||||
bit clk;
|
||||
int dly_value;
|
||||
int wait_value;
|
||||
bit [1:0] drive_value;
|
||||
bus_if bus ();
|
||||
Cls obj = new;
|
||||
|
||||
always #5 clk = ~clk;
|
||||
|
||||
default clocking cb @(posedge clk);
|
||||
output drive_value;
|
||||
endclocking
|
||||
|
||||
// 'disable fork' does not cancel pending updates (IEEE 1800-2023 9.6.3)
|
||||
initial begin
|
||||
obj.vif = bus;
|
||||
dly_value <= #2 1;
|
||||
obj.set(2);
|
||||
cb.drive_value <= ##1 3;
|
||||
disable fork;
|
||||
#20;
|
||||
`checkd(dly_value, 1)
|
||||
`checkd(bus.data, 2)
|
||||
`checkd(drive_value, 3)
|
||||
end
|
||||
|
||||
// 'wait fork' does not wait for pending updates (IEEE 1800-2023 9.6.1)
|
||||
initial begin
|
||||
#30;
|
||||
wait_value <= #5 4;
|
||||
wait fork;
|
||||
`checkd($time, 30)
|
||||
#10;
|
||||
`checkd(wait_value, 4)
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Reference in New Issue
Block a user