From 03e8ef0b0fbe8ff7f572e4e61e1f6c1712f5133d Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Thu, 12 Dec 2024 14:51:48 +0100 Subject: [PATCH] Fix wildcard equality and inside operators for non-fourstate expressions (#5673) --- src/V3Tristate.cpp | 6 +++--- src/V3Unknown.cpp | 8 +++++--- test_regress/t/t_eq_wild.py | 18 ++++++++++++++++++ test_regress/t/t_eq_wild.v | 21 +++++++++++++++++++++ test_regress/t/t_eq_wild_unsup.out | 6 ++++++ test_regress/t/t_eq_wild_unsup.py | 16 ++++++++++++++++ test_regress/t/t_eq_wild_unsup.v | 19 +++++++++++++++++++ test_regress/t/t_inside_queue_elem.py | 18 ++++++++++++++++++ test_regress/t/t_inside_queue_elem.v | 18 ++++++++++++++++++ 9 files changed, 124 insertions(+), 6 deletions(-) create mode 100755 test_regress/t/t_eq_wild.py create mode 100644 test_regress/t/t_eq_wild.v create mode 100644 test_regress/t/t_eq_wild_unsup.out create mode 100755 test_regress/t/t_eq_wild_unsup.py create mode 100644 test_regress/t/t_eq_wild_unsup.v create mode 100755 test_regress/t/t_inside_queue_elem.py create mode 100644 test_regress/t/t_inside_queue_elem.v diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index 950de4da3..0846b085a 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -1412,9 +1412,9 @@ class TristateVisitor final : public TristateBaseVisitor { } } void visitEqNeqWild(AstNodeBiop* nodep) { - if (!VN_IS(nodep->rhsp(), Const)) { - nodep->v3warn(E_UNSUPPORTED, // Says spac. - "Unsupported: RHS of ==? or !=? must be constant to be synthesizable"); + if (!VN_IS(nodep->rhsp(), Const) && nodep->rhsp()->dtypep()->isFourstate()) { + nodep->v3warn(E_UNSUPPORTED, + "Unsupported: RHS of ==? or !=? is fourstate but not a constant"); // rhs we want to keep X/Z intact, so otherwise ignore } iterateAndNextNull(nodep->lhsp()); diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index e649c02cd..258fa5ab1 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -237,9 +237,11 @@ class UnknownVisitor final : public VNVisitor { AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); AstNodeExpr* newp; if (!VN_IS(rhsp, Const)) { - nodep->v3warn(E_UNSUPPORTED, "Unsupported: RHS of ==? or !=? must be " - "constant to be synthesizable"); // Says spec. - // Replace with anything that won't cause more errors + if (rhsp->dtypep()->isFourstate()) { + nodep->v3warn( + E_UNSUPPORTED, + "Unsupported: RHS of ==? or !=? is fourstate but not a constant"); + } newp = new AstEq{nodep->fileline(), lhsp, rhsp}; } else { // X or Z's become mask, ala case statements. diff --git a/test_regress/t/t_eq_wild.py b/test_regress/t/t_eq_wild.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_eq_wild.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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_eq_wild.v b/test_regress/t/t_eq_wild.v new file mode 100644 index 000000000..7777eb6a3 --- /dev/null +++ b/test_regress/t/t_eq_wild.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +function bit get_1_or_0(bit get_1); + return get_1 ? 1'b1 : 1'b0; +endfunction + +module t (/*AUTOARG*/); + + initial begin + if (get_1_or_0(0) ==? get_1_or_0(1)) $stop; + if (!(get_1_or_0(0) !=? get_1_or_0(1))) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_eq_wild_unsup.out b/test_regress/t/t_eq_wild_unsup.out new file mode 100644 index 000000000..94c1a1f65 --- /dev/null +++ b/test_regress/t/t_eq_wild_unsup.out @@ -0,0 +1,6 @@ +%Error-UNSUPPORTED: t/t_eq_wild_unsup.v:13:13: Unsupported: RHS of ==? or !=? is fourstate but not a constant + : ... note: In instance 't' + 13 | if (1 ==? get_x_or_0(0)) $stop; + | ^~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error: Exiting due to diff --git a/test_regress/t/t_eq_wild_unsup.py b/test_regress/t/t_eq_wild_unsup.py new file mode 100755 index 000000000..e33e10acf --- /dev/null +++ b/test_regress/t/t_eq_wild_unsup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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_eq_wild_unsup.v b/test_regress/t/t_eq_wild_unsup.v new file mode 100644 index 000000000..9e7f8b7c6 --- /dev/null +++ b/test_regress/t/t_eq_wild_unsup.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, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +function logic get_x_or_0(logic get_x); + return get_x ? 1'bx : 1'b0; +endfunction + +module t; + initial begin + if (1 ==? get_x_or_0(0)) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_inside_queue_elem.py b/test_regress/t/t_inside_queue_elem.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_inside_queue_elem.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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_inside_queue_elem.v b/test_regress/t/t_inside_queue_elem.v new file mode 100644 index 000000000..2854757bd --- /dev/null +++ b/test_regress/t/t_inside_queue_elem.v @@ -0,0 +1,18 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/); + + initial begin + int q[$] = {1, 2}; + if (!(1 inside {q[0], q[1]})) $stop; + if (3 inside {q[0], q[1]}) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule