diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 6c8578780..604ae8497 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -6082,6 +6082,39 @@ private: // Check using assignment-like context rules // if (debug()) nodep->dumpTree("- checkass: "); UASSERT_OBJ(stage == FINAL, nodep, "Bad width call"); + // Create unpacked byte from string perl IEEE 1800-2017 5.9 + if (AstConst* constp = VN_CAST(rhsp, Const)) { + if (const AstUnpackArrayDType* const arrayp + = VN_CAST(lhsDTypep->skipRefp(), UnpackArrayDType)) { + if (AstBasicDType* basicp = VN_CAST(arrayp->subDTypep()->skipRefp(), BasicDType)) { + if (basicp->width() == 8 && constp->num().isFromString()) { + AstInitArray* newp = new AstInitArray{ + constp->fileline(), lhsDTypep, + new AstConst{constp->fileline(), AstConst::WidthedValue{}, 8, 0}}; + for (int aindex = arrayp->lo(); aindex <= arrayp->hi(); ++aindex) { + int cindex = arrayp->declRange().littleEndian() + ? (arrayp->hi() - aindex) + : (aindex - arrayp->lo()); + V3Number selected{constp, 8}; + selected.opSel(constp->num(), cindex * 8 + 7, cindex * 8); + UINFO(0, " aindex=" << aindex << " cindex=" << cindex + << " c=" << selected << endl); + if (!selected.isFourState()) { + if (const uint32_t c = selected.toUInt()) { + newp->addIndexValuep( + aindex, new AstConst{constp->fileline(), + AstConst::WidthedValue{}, 8, c}); + } + } + } + UINFO(6, " unpackFromString: " << nodep << endl); + rhsp->replaceWith(newp); + VL_DO_DANGLING(pushDeletep(rhsp), rhsp); + rhsp = newp; + } + } + } + } // We iterate and size the RHS based on the result of RHS evaluation checkClassAssign(nodep, side, rhsp, lhsDTypep); const bool lhsStream diff --git a/test_regress/t/t_string_byte.pl b/test_regress/t/t_string_byte.pl new file mode 100755 index 000000000..1aa73f80a --- /dev/null +++ b/test_regress/t/t_string_byte.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2022 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 + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_string_byte.v b/test_regress/t/t_string_byte.v new file mode 100644 index 000000000..58ad58b47 --- /dev/null +++ b/test_regress/t/t_string_byte.v @@ -0,0 +1,29 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2022 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +`define stop $stop +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); + +module t(/*AUTOARG*/); + + // Unpacked byte from string IEEE 1800-2017 5.9 + byte bh[3:0] = "hi2"; + byte bl[0:3] = "lo2"; + + initial begin + `checkh(bh[0], "2"); + `checkh(bh[1], "i"); + `checkh(bh[2], "h"); + `checkh(bh[3], 0); + `checkh(bl[0], 0); + `checkh(bl[1], "l"); + `checkh(bl[2], "o"); + `checkh(bl[3], "2"); + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule