Support concat assignment to packed array (#3446).

This commit is contained in:
Wilson Snyder 2022-06-03 21:32:13 -04:00
parent ada58465b2
commit 59dc2853e3
6 changed files with 91 additions and 22 deletions

View File

@ -20,10 +20,11 @@ Verilator 4.223 devel
* Add -f<optimization> options to replace -O<letter> options (#3436).
* Changed --no-merge-const-pool to -fno-merge-const-pool (#3436).
* Support compile time trace signal selection with tracing_on/off (#3323). [Shunyao CAD]
* Add assert when VerilatedContext is mis-deleted (#3121). [Rupert Swarbrick]
* Define VM_TRACE_VCD when tracing in VCD format. [Geza Lore, Shunyao CAD]
* Support non-ANSI interface port declarations (#3439). [Geza Lore, Shunyao CAD]
* Support concat assignment to packed array (#3446).
* Improve conditional merging optimization (#3125). [Geza Lore, Shunyao CAD]
* Define VM_TRACE_VCD when tracing in VCD format. [Geza Lore, Shunyao CAD]
* Add assert when VerilatedContext is mis-deleted (#3121). [Rupert Swarbrick]
* Fix hang with large case statement optimization (#3405). [Mike Urbach]
* Fix 'with' operator with type casting (#3387). [xiak95]
* Fix incorrect conditional merging (#3409). [Raynard Qiao]

View File

@ -8538,6 +8538,7 @@ public:
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
AstNode* itemsp() const { return op2p(); } // op2 = AstPatReplicate, AstPatMember, etc
void addItemsp(AstNode* nodep) { addOp2p(nodep); }
};
class AstPatMember final : public AstNodeMath {
// Verilog '{a} or '{a{b}}

View File

@ -504,6 +504,7 @@ private:
// width: LHS + RHS
AstNodeDType* const vdtypep = m_vup->dtypeNullSkipRefp();
userIterate(vdtypep, WidthVP(SELF, BOTH).p());
// Conversions
if (VN_IS(vdtypep, QueueDType)) {
// Queue "element 0" is lhsp, so we need to swap arguments
auto* const newp = new AstConsQueue(nodep->fileline(), nodep->rhsp()->unlinkFrBack(),
@ -521,6 +522,16 @@ private:
userIterateChildren(newp, m_vup);
return;
}
if (VN_IS(vdtypep, UnpackArrayDType)) {
auto* const newp = new AstPattern{nodep->fileline(), nullptr};
patConcatConvertRecurse(newp, nodep);
nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
userIterate(newp, m_vup);
return;
}
// Concat handling
if (m_vup->prelim()) {
if (VN_IS(vdtypep, AssocArrayDType) //
|| VN_IS(vdtypep, DynArrayDType) //
@ -662,7 +673,8 @@ private:
}
AstNodeDType* const vdtypep = m_vup->dtypeNullSkipRefp();
if (VN_IS(vdtypep, QueueDType) || VN_IS(vdtypep, DynArrayDType)) {
if (VN_IS(vdtypep, QueueDType) || VN_IS(vdtypep, DynArrayDType)
|| VN_IS(vdtypep, UnpackArrayDType)) {
if (times != 1)
nodep->v3warn(E_UNSUPPORTED, "Unsupported: Non-1 replication to form "
<< vdtypep->prettyDTypeNameQ()
@ -674,7 +686,7 @@ private:
VL_DO_DANGLING(pushDeletep(nodep), nodep);
return;
}
if (VN_IS(vdtypep, AssocArrayDType) || VN_IS(vdtypep, UnpackArrayDType)) {
if (VN_IS(vdtypep, AssocArrayDType)) {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: Replication to form "
<< vdtypep->prettyDTypeNameQ() << " data type");
}
@ -6231,6 +6243,21 @@ private:
return patmap;
}
void patConcatConvertRecurse(AstPattern* patternp, AstConcat* nodep) {
if (AstConcat* lhsp = VN_CAST(nodep->lhsp(), Concat)) {
patConcatConvertRecurse(patternp, lhsp);
} else {
patternp->addItemsp(new AstPatMember{nodep->lhsp()->fileline(),
nodep->lhsp()->unlinkFrBack(), nullptr, nullptr});
}
if (AstConcat* rhsp = VN_CAST(nodep->rhsp(), Concat)) {
patConcatConvertRecurse(patternp, rhsp);
} else {
patternp->addItemsp(new AstPatMember{nodep->rhsp()->fileline(),
nodep->rhsp()->unlinkFrBack(), nullptr, nullptr});
}
}
void makeOpenArrayShell(AstNodeFTaskRef* nodep) {
UINFO(4, "Replicate openarray function " << nodep->taskp() << endl);
AstNodeFTask* const oldTaskp = nodep->taskp();

View File

@ -0,0 +1,21 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2022 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
scenarios(simulator => 1);
compile(
);
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -0,0 +1,36 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2022 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t(/*AUTOARG*/
// Inputs
clk
);
input clk;
wire [31:0] arr [0:7];
assign arr[0:7] = {
{16'hffff, 16'h0000},
{16'h0000, 16'h0000},
{16'h0a0a, 16'h0000},
{16'ha0a0, 16'h0000},
{16'hffff, 16'h0000},
{16'h0000, 16'h0000},
{16'h0a0a, 16'h0000},
{16'ha0a0, 16'h0000}
};
int cyc = 0;
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 9) begin
if (arr[0] !== 32'hffff0000) $stop;
if (arr[7] !== 32'ha0a00000) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule

View File

@ -1,23 +1,6 @@
%Error-UNSUPPORTED: t/t_unpacked_concat_bad.v:17:46: Unsupported: Replication to form 'bit[31:0]$[1:0]' data type
%Error-UNSUPPORTED: t/t_unpacked_concat_bad.v:17:46: Unsupported: Non-1 replication to form 'bit[31:0]$[1:0]' data type
: ... In instance t
17 | localparam bit_int_t count_bits [1:0] = {2{$bits(count_t)}};
| ^
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Warning-WIDTHCONCAT: t/t_unpacked_concat_bad.v:17:47: Unsized numbers/parameters not allowed in replications.
: ... In instance t
17 | localparam bit_int_t count_bits [1:0] = {2{$bits(count_t)}};
| ^~~~~
... Use "/* verilator lint_off WIDTHCONCAT */" and lint_on around source to disable this message.
%Error-UNSUPPORTED: t/t_unpacked_concat_bad.v:18:45: Unsupported: Replication to form 'bit[31:0]$[1:0]' data type
: ... In instance t
18 | localparam bit_int_t count_bitsc [1:0] = {$bits(count_t), $bits(count_t)};
| ^
%Warning-WIDTHCONCAT: t/t_unpacked_concat_bad.v:18:46: Unsized numbers/parameters not allowed in concatenations.
: ... In instance t
18 | localparam bit_int_t count_bitsc [1:0] = {$bits(count_t), $bits(count_t)};
| ^~~~~
%Warning-WIDTHCONCAT: t/t_unpacked_concat_bad.v:18:60: Unsized numbers/parameters not allowed in replications.
: ... In instance t
18 | localparam bit_int_t count_bitsc [1:0] = {$bits(count_t), $bits(count_t)};
| ^
%Error: Exiting due to