Fix packed array deduction (#6046)

This commit is contained in:
Todd Strader 2025-05-31 07:55:00 -04:00 committed by GitHub
parent 79de1ff507
commit cfbcfd913c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 73 additions and 12 deletions

View File

@ -2353,9 +2353,8 @@ class LinkDotResolveVisitor final : public VNVisitor {
std::map<AstNode*, AstPin*> m_usedPins; // Pin used in this cell, map to duplicate
std::map<std::string, AstNodeModule*> m_modulesToRevisit; // Modules to revisit a second time
AstNode* m_lastDeferredp = nullptr; // Last node which requested a revisit of its module
bool m_maybePackedArray
= false; // Array select parse trees may actually be packed array datatypes
AstNodeDType* m_packedArrayDtp = nullptr; // Datatype reference for packed array
bool m_inPackedArray = false; // Currently traversing a packed array tree
struct DotStates final {
DotPosition m_dotPos; // Scope part of dotted resolution
@ -2811,7 +2810,7 @@ class LinkDotResolveVisitor final : public VNVisitor {
// Early return() above when deleted
}
void visit(AstDot* nodep) override {
// Legal under a DOT: AstDot, AstParseRef, AstPackageRef, AstNodeSel
// Legal under a DOT: AstDot, AstParseRef, AstPackageRef, AstNodeSel, AstPackArrayDType
// also a DOT can be part of an expression, but only above plus
// AstFTaskRef are legal children
// Dot(PackageRef, ParseRef(text))
@ -3404,7 +3403,7 @@ class LinkDotResolveVisitor final : public VNVisitor {
if (ok) {
AstRefDType* const refp = new AstRefDType{nodep->fileline(), nodep->name()};
refp->typedefp(defp);
if (m_maybePackedArray) {
if (VN_IS(nodep->backp(), SelExtract)) {
m_packedArrayDtp = refp;
} else {
replaceWithCheckBreak(nodep, refp);
@ -4058,11 +4057,7 @@ class LinkDotResolveVisitor final : public VNVisitor {
AstNodeDType* packedArrayDtp = nullptr; // Datatype reference for packed array
{
VL_RESTORER(m_packedArrayDtp);
{
VL_RESTORER(m_maybePackedArray);
m_maybePackedArray = true;
iterateAndNextNull(nodep->fromp());
}
iterateAndNextNull(nodep->fromp());
symIterateNull(nodep->rhsp(), m_curSymp);
symIterateNull(nodep->thsp(), m_curSymp);
@ -4074,7 +4069,7 @@ class LinkDotResolveVisitor final : public VNVisitor {
= new AstPackArrayDType(nodep->fileline(), m_packedArrayDtp, newRangep);
newArrayTypep->childDTypep(m_packedArrayDtp);
newArrayTypep->refDTypep(nullptr);
if (m_maybePackedArray) {
if (VN_IS(nodep->backp(), SelExtract)) {
packedArrayDtp = newArrayTypep;
} else {
replaceWithCheckBreak(nodep, newArrayTypep);
@ -4576,8 +4571,13 @@ class LinkDotResolveVisitor final : public VNVisitor {
void visit(AstAttrOf* nodep) override { iterateChildren(nodep); }
void visit(AstNode* nodep) override {
LINKDOT_VISIT_START();
checkNoDot(nodep);
VL_RESTORER(m_inPackedArray);
if (VN_IS(nodep, PackArrayDType)) {
m_inPackedArray = true;
} else if (!m_inPackedArray) {
LINKDOT_VISIT_START();
checkNoDot(nodep);
}
iterateChildren(nodep);
}

View File

@ -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()

View File

@ -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, 2025 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
localparam int width = 8;
typedef logic [width-1:0] [15:0] two_dee_t;
typedef logic[$clog2(width)-1:0] index_t;
two_dee_t the_two_dee;
initial begin
the_two_dee[index_t'(5)][7:0] = 8'hab;
the_two_dee[index_t'(5)][15:8] = 8'h12;
end
always @ (posedge clk) begin
if (the_two_dee[5] != 16'h12ab) $stop();
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -4,6 +4,10 @@
// without warranty, 2019 by Todd Strader.
// SPDX-License-Identifier: CC0-1.0
package some_package;
typedef logic [15:0] two_bytes_t;
endpackage
module foo
#(parameter type bar = logic)
(output int bar_size);
@ -54,6 +58,11 @@ module t();
foo #(.bar (some_struct_t [2:0] [5:0]))
foo_inst5 (.bar_size (bar_size5));
int bar_size6;
foo #(.bar (some_package::two_bytes_t [4-1:0]))
foo_inst6 (.bar_size (bar_size6));
localparam bar_bits = 13;
int bar_size_wrapper;
@ -106,6 +115,11 @@ module t();
bar_size5, $bits(some_struct_t) * 3 * 6);
$stop();
end
if (bar_size6 != $bits(some_package::two_bytes_t)*4) begin
$display("%m: bar_size6 != bits of some_package::two_bytes_t * 4 (%0d, %0d)",
bar_size6, $bits(some_package::two_bytes_t) * 4);
$stop();
end
if (bar_size_wrapper != bar_bits) begin
$display("%m: bar_size_wrapper != bar_bits (%0d, %0d)",
bar_size_wrapper, bar_bits);