From 4a1f17e75f20931cbb6f974813f46e3a41ae30f6 Mon Sep 17 00:00:00 2001 From: Zubin Jain Date: Thu, 14 May 2026 22:58:16 +0800 Subject: [PATCH] Fix force of unpacked arrays (#7579) (#7580) Fixes #7579. --- docs/CONTRIBUTORS | 1 + src/V3Force.cpp | 7 ++++++- test_regress/t/t_force_struct_trace.py | 18 ++++++++++++++++++ test_regress/t/t_force_struct_trace.v | 21 +++++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100755 test_regress/t/t_force_struct_trace.py create mode 100644 test_regress/t/t_force_struct_trace.v diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 003c09f13..649e68340 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -318,3 +318,4 @@ emmettifelts Ícaro Lima Yogish Sekhar 24bit-xjkp +Zubin Jain diff --git a/src/V3Force.cpp b/src/V3Force.cpp index 7764cffcd..5731f53d4 100644 --- a/src/V3Force.cpp +++ b/src/V3Force.cpp @@ -1123,7 +1123,12 @@ class ForceReplaceVisitor final : public VNVisitor { return; } - AstVarRef* const baseRefp = m_state.getOneVarRef(nodep); + AstNode* const basep = AstArraySel::baseFromp(nodep, true); + AstVarRef* const baseRefp = VN_CAST(basep, VarRef); + if (!baseRefp) { + iterateChildren(nodep); + return; + } AstVar* const varp = baseRefp->varp(); const ForceState::VarForceInfo* const varInfo = m_state.getVarInfo(varp); // Skip non-forceable reads, reads we intentionally protected earlier, and intermediate diff --git a/test_regress/t/t_force_struct_trace.py b/test_regress/t/t_force_struct_trace.py new file mode 100755 index 000000000..2089dade6 --- /dev/null +++ b/test_regress/t/t_force_struct_trace.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# 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=["--trace"]) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_force_struct_trace.v b/test_regress/t/t_force_struct_trace.v new file mode 100644 index 000000000..3dd1aeb83 --- /dev/null +++ b/test_regress/t/t_force_struct_trace.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Minimal reproducer for Verilator 5.048 internal error: +// V3Force.cpp:216: `force` assignment has no VarRef on LHS +// +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 Zubin Jain +// SPDX-License-Identifier: CC0-1.0 + +module t; + logic forced_sig; + typedef struct { + logic [1:0] d[0:1]; + } payload_t; + payload_t s; + initial begin + force forced_sig = 1'b1; + $finish(0); + end +endmodule