Skip to content

Commit

Permalink
Fix NBAs to unpacked arrays of unpacked structs
Browse files Browse the repository at this point in the history
This happened to work before verilator#5516, by creating a whole shadow copy of
the entire array. Revert back to that behaviour for now, it will be
slow, but works still.

Fixes verilator#5590
  • Loading branch information
gezalore committed Nov 10, 2024
1 parent 77ef2cd commit bac7de8
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 3 deletions.
11 changes: 8 additions & 3 deletions src/V3Delayed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,11 @@ class DelayedVisitor final : public VNVisitor {
const AstNodeDType* const dtypep = vscp->dtypep()->skipRefp();
// Unpacked arrays
if (const AstUnpackArrayDType* const uaDTypep = VN_CAST(dtypep, UnpackArrayDType)) {
// Basic underlying type of elements, if any.
AstBasicDType* const basicp = uaDTypep->basicp();
// If used in a loop, we must have a dynamic commit queue. (Also works in suspendables)
if (vscpInfo.m_inLoop) {
// Arrays with compound element types are currently not supported in loops
AstBasicDType* const basicp = uaDTypep->basicp();
if (!basicp
|| !(basicp->isIntegralOrPacked() //
|| basicp->isDouble() //
Expand All @@ -266,8 +267,12 @@ class DelayedVisitor final : public VNVisitor {
}
// In a suspendable of fork, we must use the unique flag scheme, TODO: why?
if (vscpInfo.m_inSuspOrFork) return Scheme::FlagUnique;
// Otherwise use the shared flag scheme
return Scheme::FlagShared;
// Otherwise if an array of packed/basic elements, use the shared flag scheme
if (basicp) return Scheme::FlagShared;
// Finally fall back on the shadow variable scheme, e.g. for
// arrays of unpacked structs. This will be slow.
// TODO: generic LHS scheme as discussed in #5092
return Scheme::ShadowVar;
}

// In a suspendable of fork, we must use the unique flag scheme, TODO: why?
Expand Down
18 changes: 18 additions & 0 deletions test_regress/t/t_nba_struct_array.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2024 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(check_finished=True)

test.passes()
93 changes: 93 additions & 0 deletions test_regress/t/t_nba_struct_array.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@

// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2024 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0

`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0)

module t(clk);
input clk;

logic [31:0] cyc = 0;
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 99) begin
$write("*-* All Finished *-*\n");
$finish;
end
end

`define at_posedge_clk_on_cycle(n) always @(posedge clk) if (cyc == n)

struct {
int foo;
int bar;
} arr [2];

initial begin
arr[0].foo = 0;
arr[0].bar = 100;
arr[1].foo = 0;
arr[1].bar = 100;
end

`at_posedge_clk_on_cycle(0) begin
for (int i = 0; i < 2; ++i) begin
`checkh(arr[i].foo, 0);
`checkh(arr[i].bar, 100);
end
end
`at_posedge_clk_on_cycle(1) begin
for (int i = 0; i < 2; ++i) begin
`checkh(arr[i].foo, 0);
`checkh(arr[i].bar, 100);
end
arr[0].foo <= 0;
arr[0].bar <= -0;
arr[1].foo <= 1;
arr[1].bar <= -1;
for (int i = 0; i < 2; ++i) begin
`checkh(arr[i].foo, 0);
`checkh(arr[i].bar, 100);
end
end
`at_posedge_clk_on_cycle(2) begin
for (int i = 0; i < 2; ++i) begin
`checkh(arr[i].foo, i);
`checkh(arr[i].bar, -i);
end
arr[0].foo <= ~0;
arr[0].bar <= 0;
arr[1].foo <= ~1;
arr[1].bar <= 1;
for (int i = 0; i < 2; ++i) begin
`checkh(arr[i].foo, i);
`checkh(arr[i].bar, -i);
end
end
`at_posedge_clk_on_cycle(3) begin
for (int i = 0; i < 2; ++i) begin
`checkh(arr[i].foo, ~i);
`checkh(arr[i].bar, i);
end
arr[0].foo <= -1;
arr[0].bar <= -2;
arr[1].foo <= -1;
arr[1].bar <= -2;
for (int i = 0; i < 2; ++i) begin
`checkh(arr[i].foo, ~i);
`checkh(arr[i].bar, i);
end
end
`at_posedge_clk_on_cycle(4) begin
for (int i = 0; i < 2; ++i) begin
`checkh(arr[i].foo, -1);
`checkh(arr[i].bar, -2);
end
end


endmodule

0 comments on commit bac7de8

Please sign in to comment.