Support inside operator on unpacked arrays and queues (#4751)

This commit is contained in:
Ryszard Rozak 2023-12-12 09:20:22 +01:00 committed by GitHub
parent b65f2509a2
commit a811f2e17d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 123 additions and 42 deletions

View File

@ -613,6 +613,11 @@ public:
m_deque.insert(m_deque.begin() + index, value);
}
// inside (set membership operator)
bool inside(const T_Value& value) const {
return std::find(m_deque.begin(), m_deque.end(), value) != m_deque.end();
}
// Return slice q[lsb:msb]
VlQueue slice(int32_t lsb, int32_t msb) const {
VlQueue out;
@ -1308,6 +1313,11 @@ public:
bool operator==(const VlUnpacked<T_Value, T_Depth>& that) const { return !neq(that); }
bool operator!=(const VlUnpacked<T_Value, T_Depth>& that) { return neq(that); }
// inside (set membership operator)
bool inside(const T_Value& value) const {
return std::find(std::begin(m_storage), std::end(m_storage), value) != std::end(m_storage);
}
void sort() { std::sort(std::begin(m_storage), std::end(m_storage)); }
template <typename Func>
void sort(Func with_func) {

View File

@ -2252,6 +2252,7 @@ void AstCMethodHard::setPurity() {
{"first", false},
{"init", false},
{"insert", false},
{"inside", true},
{"isFired", true},
{"isTriggered", true},
{"join", false},

View File

@ -2555,16 +2555,16 @@ class WidthVisitor final : public VNVisitor {
// Similar logic in V3Case
inewp = irangep->newAndFromInside(nodep->exprp(), irangep->lhsp()->unlinkFrBack(),
irangep->rhsp()->unlinkFrBack());
} else if (VN_IS(itemDtp, UnpackArrayDType)) {
nodep->v3error("Unsupported: inside (set membership operator) on unpacked array");
// Need the AstInside type to persist, then
// for parameters, need V3Simulate support.
// For non-parameters, need runtime support.
continue;
} else if (VN_IS(itemDtp, AssocArrayDType) || VN_IS(itemDtp, DynArrayDType)
} else if (VN_IS(itemDtp, UnpackArrayDType) || VN_IS(itemDtp, DynArrayDType)
|| VN_IS(itemDtp, QueueDType)) {
nodep->v3error(
"Inside operator not legal on non-unpacked arrays (IEEE 1800-2017 11.4.13)");
// Unsupported in parameters
inewp = new AstCMethodHard{itemp->fileline(), itemp->unlinkFrBack(), "inside",
nodep->exprp()->cloneTreePure(true)};
inewp->dtypeSetBit();
inewp->didWidth(true);
} else if (VN_IS(itemDtp, AssocArrayDType)) {
nodep->v3error("Inside operator not specified on associative arrays (IEEE "
"1800-2017 11.4.13)");
continue;
} else {
inewp = AstEqWild::newTyped(itemp->fileline(), nodep->exprp()->cloneTreePure(true),

View File

@ -0,0 +1,5 @@
%Error: t/t_inside_assoc_unsup.v:12:15: Inside operator not specified on associative arrays (IEEE 1800-2017 11.4.13)
: ... note: In instance 't'
12 | m = (10 inside {assoc});
| ^~~~~~
%Error: Exiting due to

View File

@ -5,16 +5,11 @@
// SPDX-License-Identifier: CC0-1.0
module t(/*AUTOARG*/);
int q[$];
int assoc[int];
int dyn[];
bit m;
initial begin
m = (10 inside {q});
m = (10 inside {assoc});
m = (10 inside {dyn});
end
endmodule

21
test_regress/t/t_inside_dyn.pl Executable file
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,22 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2023 by Antmicro Ltd.
// SPDX-License-Identifier: CC0-1.0
module t;
int q[$] = '{1, 2, 3};
bit dyn[] = '{0, 0};
initial begin
if (!(1 inside {q})) $stop;
if (4 inside {q}) $stop;
if (!(4 inside {q, 4})) $stop;
if (!(0 inside {dyn})) $stop;
if (1 inside {dyn}) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -1,13 +0,0 @@
%Error: t/t_inside_queue_bad.v:15:15: Inside operator not legal on non-unpacked arrays (IEEE 1800-2017 11.4.13)
: ... note: In instance 't'
15 | m = (10 inside {q});
| ^~~~~~
%Error: t/t_inside_queue_bad.v:16:15: Inside operator not legal on non-unpacked arrays (IEEE 1800-2017 11.4.13)
: ... note: In instance 't'
16 | m = (10 inside {assoc});
| ^~~~~~
%Error: t/t_inside_queue_bad.v:17:15: Inside operator not legal on non-unpacked arrays (IEEE 1800-2017 11.4.13)
: ... note: In instance 't'
17 | m = (10 inside {dyn});
| ^~~~~~
%Error: Exiting due to

View File

@ -11,13 +11,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(simulator => 1);
compile(
fails => $Self->{vlt_all},
expect_filename => $Self->{golden_filename},
);
execute(
check_finished => 1,
) if !$Self->{vlt_all};
);
ok(1);
1;

View File

@ -10,18 +10,6 @@ module t(/*AUTOARG*/
);
input clk;
localparam int CHECKLIST_P [2:0] = '{0, 1, 2};
localparam HIT_LP = 1;
localparam MISS_LP = 4;
localparam HIT_INSIDE = HIT_LP inside {CHECKLIST_P};
localparam MISS_INSIDE = MISS_LP inside {CHECKLIST_P};
initial begin
if (HIT_INSIDE != 1) $stop;
if (MISS_INSIDE != 0) $stop;
end
integer cyc = 0;
int array [10];

View File

@ -0,0 +1,9 @@
%Error: t/t_inside_unpacked_param.v:13:43: Expecting expression to be constant, but can't convert a CMETHODHARD 'inside' to constant.
: ... note: In instance 't'
13 | localparam HIT_INSIDE = HIT_LP inside {CHECKLIST_P};
| ^~~~~~~~~~~
%Error: t/t_inside_unpacked_param.v:14:45: Expecting expression to be constant, but can't convert a CMETHODHARD 'inside' to constant.
: ... note: In instance 't'
14 | localparam MISS_INSIDE = MISS_LP inside {CHECKLIST_P};
| ^~~~~~~~~~~
%Error: Exiting due to

View File

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

View File

@ -0,0 +1,22 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2020 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t;
localparam int CHECKLIST_P [2:0] = '{0, 1, 2};
localparam HIT_LP = 1;
localparam MISS_LP = 4;
localparam HIT_INSIDE = HIT_LP inside {CHECKLIST_P};
localparam MISS_INSIDE = MISS_LP inside {CHECKLIST_P};
initial begin
if (HIT_INSIDE != 1) $stop;
if (MISS_INSIDE != 0) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule