mirror of
https://github.com/verilator/verilator.git
synced 2024-12-29 10:47:34 +00:00
Fix NBAs to unpacked arrays of unpacked structs (#5603)
This happened to work before #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 #5590
This commit is contained in:
parent
03bd1bfc63
commit
863abdb1f7
@ -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() //
|
||||
@ -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?
|
||||
|
18
test_regress/t/t_nba_struct_array.py
Executable file
18
test_regress/t/t_nba_struct_array.py
Executable file
@ -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
test_regress/t/t_nba_struct_array.v
Normal file
93
test_regress/t/t_nba_struct_array.v
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user