From a5fa468343296e0b3fb7c5cebfede9e7e3588555 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 10 Dec 2020 18:36:06 -0500 Subject: [PATCH] Fix cast from packed structs, broke with $cast (#2684) --- src/V3Width.cpp | 8 ++++---- test_regress/t/t_cast.v | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 188241d8c..4cfa81dd6 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -5990,13 +5990,13 @@ private: toDtp = toDtp->skipRefToEnump(); fromDtp = fromDtp->skipRefToEnump(); if (toDtp == fromDtp) return COMPATIBLE; + bool fromNumericable = VN_IS(fromDtp, BasicDType) || VN_IS(fromDtp, EnumDType) + || VN_IS(fromDtp, NodeUOrStructDType); // UNSUP unpacked struct/unions (treated like BasicDType) if (VN_IS(toDtp, BasicDType) || VN_IS(toDtp, NodeUOrStructDType)) { - if (VN_IS(fromDtp, BasicDType)) return COMPATIBLE; - if (VN_IS(fromDtp, EnumDType)) return COMPATIBLE; - if (VN_IS(fromDtp, NodeUOrStructDType)) return COMPATIBLE; + if (fromNumericable) return COMPATIBLE; } else if (VN_IS(toDtp, EnumDType)) { - if (VN_IS(fromDtp, BasicDType) || VN_IS(fromDtp, EnumDType)) return DYNAMIC_ENUM; + if (fromNumericable) return DYNAMIC_ENUM; } else if (VN_IS(toDtp, ClassRefDType) && VN_IS(fromConstp, Const)) { if (VN_IS(fromConstp, Const) && VN_CAST(fromConstp, Const)->num().isNull()) return COMPATIBLE; diff --git a/test_regress/t/t_cast.v b/test_regress/t/t_cast.v index baccee871..b41caa110 100644 --- a/test_regress/t/t_cast.v +++ b/test_regress/t/t_cast.v @@ -13,12 +13,18 @@ module t; logic [15:0] data; } packed_t; + typedef enum [15:0] { + ONE = 1 + } enum_t; + packed_t pdata; + packed_t pdata_reg; assign pdata.data = 16'h1234; logic [7:0] logic8bit; assign logic8bit = $bits(logic8bit)'(pdata >> 8); mc_t o; + enum_t e; logic [15:0] allones = 16'hffff; parameter FOUR = 4; @@ -55,6 +61,17 @@ module t; if ((FOUR+2)'(allones) !== 6'h3f) $stop; if (50 !== RESULT) $stop; + e = ONE; + if (e != 1) $stop; + if (e != ONE) $stop; + e = enum_t'(ONE); + if (e != ONE) $stop; + e = enum_t'(16'h1); + if (e != ONE) $stop; + pdata_reg.data = 1; + e = enum_t'(pdata_reg); + if (e != ONE) $stop; + o = tocast_t'(4'b1); if (o != 4'b1) $stop;