diff --git a/Changes b/Changes index a02b5f99e..46623b6f5 100644 --- a/Changes +++ b/Changes @@ -119,6 +119,7 @@ Verilator 5.043 devel * Fix false IMPLICITSTATIC on localparam (#6835). [Geza Lore] * Fix randcase under fork (#6843). [Amal Araweelo Almis] * Fix JSON missing `signed` indication (#6845). +* Fix class reference throwing cannot detect changes error (#6851). Verilator 5.042 2025-11-02 diff --git a/src/V3SenExprBuilder.h b/src/V3SenExprBuilder.h index ddbfbbba9..021b73a00 100644 --- a/src/V3SenExprBuilder.h +++ b/src/V3SenExprBuilder.h @@ -58,6 +58,7 @@ private: if (VN_IS(dtypep, PackArrayDType)) return true; if (VN_IS(dtypep, UnpackArrayDType)) return isSupportedDType(dtypep->subDTypep()); if (VN_IS(dtypep, NodeUOrStructDType)) return true; // All are packed at the moment + if (VN_IS(dtypep, ClassRefDType)) return true; // IEEE: reference change, not contents return false; } @@ -125,17 +126,17 @@ private: // Add post update if it does not exist yet if (m_hasPostUpdate.emplace(*exprp).second) { - if (!isSupportedDType(exprp->dtypep())) { + AstNodeDType* const exprDtp = exprp->dtypep()->skipRefp(); + if (!isSupportedDType(exprDtp)) { exprp->v3warn( E_UNSUPPORTED, "Unsupported: Cannot detect changes on expression of complex type " - << exprp->dtypep()->prettyDTypeNameQ() << "\n" + << exprDtp->prettyDTypeNameQ() << "\n" << exprp->warnMore() << "... May be caused by combinational cycles reported with UNOPTFLAT"); return prevp; } - - if (VN_IS(exprp->dtypep()->skipRefp(), UnpackArrayDType)) { + if (VN_IS(exprDtp, UnpackArrayDType)) { AstCMethodHard* const cmhp = new AstCMethodHard{flp, wrPrev(), VCMethod::UNPACKED_ASSIGN, rdCurr()}; cmhp->dtypeSetVoid(); diff --git a/test_regress/t/t_dist_warn_coverage.py b/test_regress/t/t_dist_warn_coverage.py index 0e601d4f0..076454c2a 100755 --- a/test_regress/t/t_dist_warn_coverage.py +++ b/test_regress/t/t_dist_warn_coverage.py @@ -82,7 +82,6 @@ for s in [ 'Unsupported: 4-state numbers in this context', 'Unsupported: Assignments with signal strength with LHS of type:', 'Unsupported: Bind with instance list', - 'Unsupported: Cannot detect changes on expression of complex type', 'Unsupported: Cast to', 'Unsupported: Concatenation to form', 'Unsupported: Creating tristate signal not underneath a module:', diff --git a/test_regress/t/t_timing_at_class.py b/test_regress/t/t_timing_at_class.py new file mode 100755 index 000000000..bd059b0f2 --- /dev/null +++ b/test_regress/t/t_timing_at_class.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. 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-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() diff --git a/test_regress/t/t_timing_at_class.v b/test_regress/t/t_timing_at_class.v new file mode 100644 index 000000000..293d68f8f --- /dev/null +++ b/test_regress/t/t_timing_at_class.v @@ -0,0 +1,89 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by 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\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); +// verilog_format: on + +module t; + + class apb_item; + int addr; + int data; + endclass + + class any_monitor #( + type REQ = int, + RSP = REQ + ); + + REQ req; + RSP rsp; + int req_changes; + int rsp_changes; + + task run_phase(); + $display("[%0t] run_phase", $time); + fork + forever begin + @req; + ++req_changes; + $display("[%0t] req change #%0d", $time, req_changes); + end + forever begin + @rsp; + ++rsp_changes; + $display("[%0t] rsp change #%0d", $time, rsp_changes); + end + join_none + endtask + + endclass + + typedef int int_t; + + any_monitor #(int_t, int_t) imon; + + apb_item creq_item, crsp_item; + any_monitor #(apb_item, apb_item) cmon; + + initial begin + $display("Integer-based test"); + imon = new; + #1; + imon.run_phase(); + #1; + imon.req = 1; // Change + imon.rsp = 2; // Change + #1; + imon.req++; // Change + #1; + `checkd(imon.req_changes, 2); + `checkd(imon.rsp_changes, 1); + + $display("Class-based test"); + creq_item = new; + crsp_item = new; + cmon = new; + #1; + cmon.run_phase(); + #1; + cmon.req = creq_item; // Change + cmon.rsp = crsp_item; // Change + #1; + creq_item.addr++; // Not a change + #1; + cmon.rsp = null; // Change + #1; + `checkd(cmon.req_changes, 1); + `checkd(cmon.rsp_changes, 2); + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_timing_at_dtype_bad.out b/test_regress/t/t_timing_at_dtype_bad.out new file mode 100644 index 000000000..b4eb22942 --- /dev/null +++ b/test_regress/t/t_timing_at_dtype_bad.out @@ -0,0 +1,12 @@ +%Error-UNSUPPORTED: t/t_timing_at_dtype_bad.v:20:12: Unsupported: Cannot detect changes on expression of complex type 'int$[$]' + : ... note: In instance 't::any_monitor__Tz1_TBz1' + : ... May be caused by combinational cycles reported with UNOPTFLAT + 20 | @req; + | ^~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error-UNSUPPORTED: t/t_timing_at_dtype_bad.v:23:12: Unsupported: Cannot detect changes on expression of complex type 'int$[$]' + : ... note: In instance 't::any_monitor__Tz1_TBz1' + : ... May be caused by combinational cycles reported with UNOPTFLAT + 23 | @rsp; + | ^~~ +%Error: Exiting due to diff --git a/test_regress/t/t_timing_at_dtype_bad.py b/test_regress/t/t_timing_at_dtype_bad.py new file mode 100755 index 000000000..f093111b2 --- /dev/null +++ b/test_regress/t/t_timing_at_dtype_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_timing_at_dtype_bad.v b/test_regress/t/t_timing_at_dtype_bad.v new file mode 100644 index 000000000..d6739051a --- /dev/null +++ b/test_regress/t/t_timing_at_dtype_bad.v @@ -0,0 +1,36 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t; + + class any_monitor #( + type REQ = int, + RSP = REQ + ); + + REQ req; + RSP rsp; + + task run_phase(); + fork + forever begin + @req; + end + forever begin + @rsp; + end + join_none + endtask + + endclass + + typedef int q_t[$]; + + any_monitor #(q_t, q_t) imon; + + initial $stop; + +endmodule