Fix packed array deduction (#6046)
This commit is contained in:
parent
79de1ff507
commit
cfbcfd913c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
|
@ -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
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue