From 5c1d7f3ce95e7b242e8f7d6f2b0f68f1b34a9754 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 28 Jul 2025 02:20:57 -0400 Subject: [PATCH] Fix negate of wide structure selections (#6186). --- Changes | 3 ++- src/V3Cast.cpp | 9 +++++++-- test_regress/t/t_struct_negate.py | 18 ++++++++++++++++++ test_regress/t/t_struct_negate.v | 19 +++++++++++++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) create mode 100755 test_regress/t/t_struct_negate.py create mode 100644 test_regress/t/t_struct_negate.v diff --git a/Changes b/Changes index b0265165d..dbc9eb50d 100644 --- a/Changes +++ b/Changes @@ -47,9 +47,10 @@ Verilator 5.039 devel * Fix virtual interface member propagation (#6175) (#6184). [Yilou Wang] * Fix `--coverage-expr` null pointer dereference (#6181). [Igor Zaworski, Antmicro Ltd.] * Fix conflicting function/class name linking error (#6182). [Igor Zaworski, Antmicro Ltd.] -* Fix automatic task variables in unrolled loops with forks (#6194) (#6201). [Danny Oler] +* Fix negate of wide structure selections (#6186). * Fix VPI signal range order (#6189) (#6200). [Ibrahim Burak Yorulmaz] * Fix structure select causing 'Wide Op' error (#6191). [Danny Oler] +* Fix automatic task variables in unrolled loops with forks (#6194) (#6201). [Danny Oler] * Fix 'driver same component' assertion (#6211) (#6215). [Geza Lore] * Fix `--stats` overridden by skipping identical build (#6220). [Geza Lore] * Fix MODDUP with duplicate packages to take first package (#6222). diff --git a/src/V3Cast.cpp b/src/V3Cast.cpp index 1cdd43a4d..9795de230 100644 --- a/src/V3Cast.cpp +++ b/src/V3Cast.cpp @@ -173,13 +173,13 @@ class CastVisitor final : public VNVisitor { void visit(AstNegate* nodep) override { iterateChildren(nodep); nodep->user1(nodep->lhsp()->user1()); - if (nodep->lhsp()->widthMin() == 1) { + if (nodep->lhsp()->widthMin() == 1 && !nodep->lhsp()->isWide()) { // We want to avoid a GCC "converting of negative value" warning // from our expansion of // out = {32{a out = - (alhsp(), castSize(nodep)); } else { - ensureCast(nodep->lhsp()); + if (nodep->sizeMattersLhs()) ensureCast(nodep->lhsp()); } } void visit(AstVarRef* nodep) override { @@ -221,6 +221,11 @@ class CastVisitor final : public VNVisitor { void visit(AstMemberSel* nodep) override { iterateChildren(nodep); ensureNullChecked(nodep->fromp()); + nodep->user1(true); + } + void visit(AstStructSel* nodep) override { + iterateChildren(nodep); + nodep->user1(true); } // NOPs diff --git a/test_regress/t/t_struct_negate.py b/test_regress/t/t_struct_negate.py new file mode 100755 index 000000000..f989a35fb --- /dev/null +++ b/test_regress/t/t_struct_negate.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() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_struct_negate.v b/test_regress/t/t_struct_negate.v new file mode 100644 index 000000000..6803ef09a --- /dev/null +++ b/test_regress/t/t_struct_negate.v @@ -0,0 +1,19 @@ +// 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 ( + input logic signed [64:0] i_x, + output logic signed [64:0] o_y +); + struct {logic signed [64:0] m_x;} s; + assign s.m_x = i_x; + assign o_y = -s.m_x; + initial begin + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule