From 631714c50a99b5bb96387d3d74b82c99fdf59efd Mon Sep 17 00:00:00 2001 From: Igor Zaworski Date: Thu, 21 Aug 2025 12:26:30 +0200 Subject: [PATCH] Fix expression type comparison (#6316) --- src/V3Width.cpp | 15 +++++---- test_regress/t/t_type_expression_compare.py | 18 +++++++++++ test_regress/t/t_type_expression_compare.v | 36 +++++++++++++++++++++ 3 files changed, 63 insertions(+), 6 deletions(-) create mode 100755 test_regress/t/t_type_expression_compare.py create mode 100644 test_regress/t/t_type_expression_compare.v diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 694dc36e0..7ce8d1477 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1832,8 +1832,11 @@ class WidthVisitor final : public VNVisitor { break; } case VAttrType::TYPEID: - // Soon to be handled in AstEqT - nodep->dtypeSetSigned32(); + if (AstNodeDType* dtypep = VN_CAST(nodep->fromp(), NodeDType)) { + nodep->dtypep(dtypep); + } else { + nodep->dtypep(VN_AS(nodep->fromp(), NodeExpr)->dtypep()); + } break; case VAttrType::VAR_BASE: // Soon to be handled in V3LinkWidth SEL generation, under attrp() and newSubLsbOf @@ -5199,7 +5202,7 @@ class WidthVisitor final : public VNVisitor { // Deal with case(type(data_type)) if (AstAttrOf* const exprap = VN_CAST(nodep->exprp(), AttrOf)) { if (exprap->attrType() == VAttrType::TYPEID) { - AstNodeDType* const exprDtp = VN_AS(exprap->fromp(), NodeDType); + const AstNodeDType* const exprDtp = exprap->dtypep(); UINFO(9, "case type exprDtp " << exprDtp); // V3Param may have a pointer to this case statement, and we need // dotted references to remain properly named, so rather than @@ -5218,7 +5221,7 @@ class WidthVisitor final : public VNVisitor { condp->v3error( "Case(type) statement requires items that have type() items"); } else { - AstNodeDType* const condDtp = VN_AS(condAttrp->fromp(), NodeDType); + AstNodeDType* const condDtp = condAttrp->dtypep(); if (AstNode::computeCastable(exprDtp, condDtp, nodep) == VCastable::SAMEISH) { hit = true; @@ -7021,8 +7024,8 @@ class WidthVisitor final : public VNVisitor { "Type compare expects type reference"); UASSERT_OBJ(rhsap->attrType() == VAttrType::TYPEID, rhsap, "Type compare expects type reference"); - AstNodeDType* const lhsDtp = VN_AS(lhsap->fromp(), NodeDType); - AstNodeDType* const rhsDtp = VN_AS(rhsap->fromp(), NodeDType); + const AstNodeDType* const lhsDtp = lhsap->dtypep(); + const AstNodeDType* const rhsDtp = rhsap->dtypep(); UINFO(9, "==type lhsDtp " << lhsDtp); UINFO(9, "==type rhsDtp " << lhsDtp); const bool invert = VN_IS(nodep, NeqT); diff --git a/test_regress/t/t_type_expression_compare.py b/test_regress/t/t_type_expression_compare.py new file mode 100755 index 000000000..f989a35fb --- /dev/null +++ b/test_regress/t/t_type_expression_compare.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_type_expression_compare.v b/test_regress/t/t_type_expression_compare.v new file mode 100644 index 000000000..d94e9fc70 --- /dev/null +++ b/test_regress/t/t_type_expression_compare.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 Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +typedef int Int_T; + +module t; + initial begin + Int_T value1 = 7; + int value2 = 13; + real r; + if (type(value1) != type(value2)) $stop; + if (type(value1 + value2) != type(value2 + 18)) $stop; + case (type(value1)) + type(value2): ; + type(r): $stop; + type(chandle): $stop; + type(logic): $stop; + default: $stop; + endcase + case (type(value1 + value2 + 13)) + type(type(value2 + 18 - 40)): ; + type(r): $stop; + type(chandle): $stop; + default: $stop; + endcase + if (type(value1) == type(value2) && type(value1 + value2) == type(value2 + 18)) begin + $write("*-* All Finished *-*\n"); + $finish; + end else begin + $stop; + end + end +endmodule