Fix packed array structure replication.

This commit is contained in:
Wilson Snyder 2023-02-13 07:47:35 -05:00
parent 3f4b7af8a1
commit 50929e5d43
4 changed files with 57 additions and 2 deletions

View File

@ -46,6 +46,7 @@ Verilator 5.007 devel
* Fix class field linking when a super classes is a param (#3949). [Ryszard Rozak, Antmicro Ltd] * Fix class field linking when a super classes is a param (#3949). [Ryszard Rozak, Antmicro Ltd]
* Fix CMake bad C identifiers (#3948) (#3951). [Zixi Li] * Fix CMake bad C identifiers (#3948) (#3951). [Zixi Li]
* Fix build on HP PA architecture. (#3954) [John David Anglin] * Fix build on HP PA architecture. (#3954) [John David Anglin]
* Fix packed array structure replication.
Verilator 5.006 2023-01-22 Verilator 5.006 2023-01-22

View File

@ -58,6 +58,7 @@ class SliceVisitor final : public VNVisitor {
// STATE // STATE
AstNode* m_assignp = nullptr; // Assignment we are under AstNode* m_assignp = nullptr; // Assignment we are under
bool m_assignError = false; // True if the current assign already has an error bool m_assignError = false; // True if the current assign already has an error
bool m_okInitArray = false; // Allow InitArray children
// METHODS // METHODS
AstNodeExpr* cloneAndSel(AstNode* nodep, int elements, int offset) { AstNodeExpr* cloneAndSel(AstNode* nodep, int elements, int offset) {
@ -163,8 +164,14 @@ class SliceVisitor final : public VNVisitor {
} }
} }
void visit(AstConsPackUOrStruct* nodep) override {
VL_RESTORER(m_okInitArray);
m_okInitArray = true;
iterateChildren(nodep);
}
void visit(AstInitArray* nodep) override { void visit(AstInitArray* nodep) override {
UASSERT_OBJ(!m_assignp, nodep, "Array initialization should have been removed earlier"); UASSERT_OBJ(!m_assignp || m_okInitArray, nodep,
"Array initialization should have been removed earlier");
} }
void expandBiOp(AstNodeBiop* nodep) { void expandBiOp(AstNodeBiop* nodep) {

View File

@ -439,7 +439,7 @@ private:
} else if (VN_IS(basefromp, Const)) { } else if (VN_IS(basefromp, Const)) {
// If it's a PARAMETER[bit], then basefromp may be a constant instead of a varrefp // If it's a PARAMETER[bit], then basefromp may be a constant instead of a varrefp
} else { } else {
nodep->v3fatalSrc("No VarRef or Const under ArraySel"); // Normally one of above, but might have MEMBERSEL or otherwise
} }
// Find range of dtype we are selecting from // Find range of dtype we are selecting from
int declElements = -1; int declElements = -1;

View File

@ -21,6 +21,19 @@ module t(/*AUTOARG*/);
sabcu_t abcu; sabcu_t abcu;
sabcp_t abcp; sabcp_t abcp;
typedef struct {
int a;
int b4[4];
} sab4u_t;
typedef struct packed {
int a;
bit [3:0][31:0] b4;
} sab4p_t;
sab4u_t ab4u[2][3];
sab4p_t ab4p[2][3];
initial begin initial begin
abcp = '{1, 2, 3}; abcp = '{1, 2, 3};
abcu = '{1, 2, 3}; abcu = '{1, 2, 3};
@ -31,6 +44,15 @@ module t(/*AUTOARG*/);
if (abcu.b !== 2) $stop; if (abcu.b !== 2) $stop;
if (abcu.c !== 3) $stop; if (abcu.c !== 3) $stop;
abcp = '{3{40}};
abcu = '{3{40}};
if (abcp.a !== 40) $stop;
if (abcp.b !== 40) $stop;
if (abcp.c !== 40) $stop;
if (abcu.a !== 40) $stop;
if (abcu.b !== 40) $stop;
if (abcu.c !== 40) $stop;
abcp = '{default:4, int:5}; abcp = '{default:4, int:5};
abcu = '{default:4, int:5}; abcu = '{default:4, int:5};
if (abcp.a !== 5) $stop; if (abcp.a !== 5) $stop;
@ -49,6 +71,31 @@ module t(/*AUTOARG*/);
if (abcu.b !== 8) $stop; if (abcu.b !== 8) $stop;
if (abcu.c !== 7) $stop; if (abcu.c !== 7) $stop;
ab4p = '{2{'{3{'{10, '{2{20, 30}}}}}}};
ab4u = '{2{'{3{'{10, '{2{20, 30}}}}}}};
$display("%p", ab4p);
if (ab4p[0][0].a !== 10) $stop;
if (ab4p[0][0].b4[0] !== 30) $stop;
if (ab4p[0][0].b4[1] !== 20) $stop;
if (ab4p[0][0].b4[2] !== 30) $stop;
if (ab4p[0][0].b4[3] !== 20) $stop;
if (ab4p[1][2].a !== 10) $stop;
if (ab4p[1][2].b4[0] !== 30) $stop;
if (ab4p[1][2].b4[1] !== 20) $stop;
if (ab4p[1][2].b4[2] !== 30) $stop;
if (ab4p[1][2].b4[3] !== 20) $stop;
$display("%p", ab4u);
if (ab4u[0][0].a !== 10) $stop;
if (ab4u[0][0].b4[0] !== 20) $stop;
if (ab4u[0][0].b4[1] !== 30) $stop;
if (ab4u[0][0].b4[2] !== 20) $stop;
if (ab4u[0][0].b4[3] !== 30) $stop;
if (ab4u[1][2].a !== 10) $stop;
if (ab4u[1][2].b4[0] !== 20) $stop;
if (ab4u[1][2].b4[1] !== 30) $stop;
if (ab4u[1][2].b4[2] !== 20) $stop;
if (ab4u[1][2].b4[3] !== 30) $stop;
$write("*-* All Finished *-*\n"); $write("*-* All Finished *-*\n");
$finish; $finish;
end end