Fix NBA to whole arrays (#7583)

Fixes #7575
This commit is contained in:
Geza Lore 2026-05-13 13:20:22 +01:00 committed by GitHub
parent 3381d656c7
commit e485dfe48c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 33 additions and 0 deletions

View File

@ -150,6 +150,7 @@ class DelayedVisitor final : public VNVisitor {
const AstVarRef* m_firstNbaRefp = nullptr;
// Active block 'm_firstNbaRefp' is under
const AstActive* m_fistActivep = nullptr;
bool m_whole = false; // Used on LHS of NBA directly via VarRef
bool m_partial = false; // Used on LHS of NBA under a Sel
bool m_inLoop = false; // Used on LHS of NBA in a loop
bool m_inSuspOrFork = false; // Used on LHS of NBA in suspendable process or fork
@ -414,6 +415,8 @@ class DelayedVisitor final : public VNVisitor {
const AstNodeDType* const dtypep = vscp->dtypep()->skipRefp();
// Unpacked arrays
if (const AstUnpackArrayDType* const uaDTypep = VN_CAST(dtypep, UnpackArrayDType)) {
// If whole array is target of NBA, use ShadowVar
if (vscpInfo.m_whole) return Scheme::ShadowVar;
// Basic underlying type of elements, if any.
const AstBasicDType* const basicp = uaDTypep->basicp();
// If used in a loop, we must have a dynamic commit queue. (Also works in suspendables)
@ -1255,6 +1258,7 @@ class DelayedVisitor final : public VNVisitor {
m_vscps.emplace_back(vscp);
}
// Note usage context
vscpInfo.m_whole |= VN_IS(nodep->lhsp(), VarRef);
vscpInfo.m_partial |= VN_IS(nodep->lhsp(), Sel);
vscpInfo.m_inLoop |= m_inLoop;
vscpInfo.m_inSuspOrFork |= m_inSuspendableOrFork;

View File

@ -17,5 +17,6 @@ test.execute()
test.file_grep(test.stats, r'NBA, variables using ValueQueueWhole scheme\s+(\d+)', 6)
test.file_grep(test.stats, r'NBA, variables using ValueQueuePartial scheme\s+(\d+)', 3)
test.file_grep(test.stats, r'NBA, variables using ShadowVar scheme\s+(\d+)', 3)
test.passes()

View File

@ -297,4 +297,32 @@ module t(clk);
for (int i = 0 ; i < 10; ++i) `checks(array9[i], "cuttlefish");
end
// Case 10: Packed narrow, but whole array also target of NBA directly
typedef logic [31:0] elem10_t;
typedef elem10_t array10_t[128];
array10_t array10;
array10_t array10_init = '{default: 10};
`at_posedge_clk_on_cycle(0) begin
for (int i = 0 ; i < 128; ++i) array10[i] = 0;
for (int i = 0 ; i < 128; ++i) `checkh(array10[i], 0);
end
`at_posedge_clk_on_cycle(1) begin
for (int i = 0 ; i < 128; ++i) `checkh(array10[i], 0);
array10 <= array10_init;
for (int i = 0 ; i < 128; ++i) `checkh(array10[i], 0);
end
`at_posedge_clk_on_cycle(2) begin
for (int i = 0 ; i < 128; ++i) `checkh(array10[i], 10);
for (int i = 64 ; i < 128; ++i) array10[i][4] <= 1'b1;
for (int i = 0 ; i < 128; ++i) `checkh(array10[i], 10);
end
`at_posedge_clk_on_cycle(3) begin
for (int i = 0 ; i < 128; ++i) `checkh(array10[i], i < 64 ? 10 : 26);
for (int i = 0 ; i < 128; ++i) array10[i] <= ~i;
for (int i = 0 ; i < 128; ++i) `checkh(array10[i], i < 64 ? 10 : 26);
end
`at_posedge_clk_on_cycle(4) begin
for (int i = 0 ; i < 128; ++i) `checkh(array10[i], ~i);
end
endmodule