Fix port assignment to large arrays (#6904).

Fixes #6904.
This commit is contained in:
Wilson Snyder 2026-03-30 19:06:02 -04:00
parent 6aa1690745
commit 62ffe43a82
5 changed files with 46 additions and 6 deletions

View File

@ -74,6 +74,7 @@ Verilator 5.047 devel
* Fix super constructor calls with local variables (#6214) (#6933). [Igor Zaworski, Antmicro Ltd.]
* Fix `local::` false error in randomize() with on parameterized class (#6680) (#7293). [Yilou Wang]
* Fix false recursive definition error (#6769) (#7118). [Alex Zhou]
* Fix port assignment to large arrays (#6904).
* Fix interface localparam dependencies and arbitrary nesting (#6936) (#7128) (#7188) (#7190). [em2machine]
* Fix errant integer promotion (#7012). [Todd Strader]
* Fix randc solver hang with wide variables (#7068) (#7248). [Yilou Wang]

View File

@ -207,7 +207,9 @@ void EmitCBaseVisitorConst::emitVarDecl(const AstVar* nodep, bool asRef) {
if (asRef && refNeedParens) puts(")");
emitDeclArrayBrackets(nodep);
puts(";\n");
} else if (nodep->isPrimaryIO() && basicp && !basicp->isOpaque()) {
} else if (nodep->isPrimaryIO() && basicp && !basicp->isOpaque()
&& !nodep->dtypep()->skipRefp()->isCompound()
&& !VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType)) {
if (nodep->isInout()) {
putns(nodep, "VL_INOUT");
} else if (nodep->isWritable()) {

View File

@ -511,6 +511,8 @@ public:
bool decind = false;
bool rhs = true;
bool reverseUnpack = false; // Set for descending CvtPackedToArray
const AstUnpackArrayDType* const unpackDtp
= VN_CAST(nodep->dtypep()->skipRefp(), UnpackArrayDType);
if (AstSel* const selp = VN_CAST(nodep->lhsp(), Sel)) {
UASSERT_OBJ(selp->widthMin() == selp->widthConst(), selp, "Width mismatch");
if (selp->widthMin() == 1) {
@ -580,10 +582,7 @@ public:
rhs = false;
iterateAndNextConstNull(castp->fromp());
// Descending unpacked dest: reverse after unpack
if (const AstUnpackArrayDType* const unpackDtp
= VN_CAST(nodep->dtypep()->skipRefp(), UnpackArrayDType)) {
if (!unpackDtp->declRange().ascending()) reverseUnpack = true;
}
if (unpackDtp && !unpackDtp->declRange().ascending()) reverseUnpack = true;
} else if (const AstCvtArrayToArray* const castp
= VN_CAST(nodep->rhsp(), CvtArrayToArray)) {
if (castp->reverse()) {
@ -608,6 +607,7 @@ public:
// and means using '=' and bypasses using emitConstantW.
// Whuch we don't want to do as slows compiler down.
&& !VN_IS(nodep->rhsp(), VarRef) //
&& !VN_IS(nodep->rhsp(), InitArray) //
&& !VN_IS(nodep->rhsp(), AssocSel) //
&& !VN_IS(nodep->rhsp(), MemberSel) //
&& !VN_IS(nodep->rhsp(), StructSel) //
@ -616,7 +616,7 @@ public:
// Wide functions assign into the array directly, don't need separate assign statement
m_wideTempRefp = VN_AS(nodep->lhsp(), VarRef);
paren = false;
} else if (nodep->isWide() && !VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType)
} else if (nodep->isWide() && !unpackDtp
&& !VN_IS(nodep->rhsp(), Const)) {
putnbs(nodep, "VL_ASSIGN_W(");
puts(cvtToStr(nodep->widthMin()) + ", ");
@ -630,6 +630,10 @@ public:
decind = true;
if (!VN_IS(nodep->rhsp(), Const)) ofp()->putBreak();
putns(nodep, "= ");
if (unpackDtp && VN_IS(nodep->rhsp(), InitArray)) {
// Emit "VlUnpacked<type, depth>{{...InitArray...}}"
puts(unpackDtp->cType("", false, false, false));
}
}
if (rhs) iterateAndNextConstNull(nodep->rhsp());
if (paren) puts(")");

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 Wilson Snyder
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
test.compile()
test.execute()
test.passes()

View File

@ -0,0 +1,15 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 Wilson Snyder
// SPDX-License-Identifier: CC0-1.0
module t (
output logic [64:0] output_vec[257]
);
assign output_vec = '{default: 1};
initial $finish;
endmodule