Support map() method for associative and wildcard arrays (#7344)
This commit is contained in:
parent
e0b4d5ad44
commit
092d3d4de0
|
|
@ -1145,6 +1145,13 @@ public:
|
||||||
if (it == m_map.rend()) return VlQueue<T_Key>{};
|
if (it == m_map.rend()) return VlQueue<T_Key>{};
|
||||||
return VlQueue<T_Key>::consV(it->first);
|
return VlQueue<T_Key>::consV(it->first);
|
||||||
}
|
}
|
||||||
|
// Map method (IEEE 1800-2023 7.12.5)
|
||||||
|
template <typename T_Func>
|
||||||
|
VlQueue<WithFuncReturnType<T_Func>> map(T_Func with_func) const {
|
||||||
|
VlQueue<WithFuncReturnType<T_Func>> out;
|
||||||
|
for (const auto& i : m_map) out.push_back(with_func(i.first, i.second));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
// Reduction operators
|
// Reduction operators
|
||||||
VlQueue<T_Value> min() const {
|
VlQueue<T_Value> min() const {
|
||||||
|
|
|
||||||
|
|
@ -4035,9 +4035,16 @@ class WidthVisitor final : public VNVisitor {
|
||||||
newp->dtypep(queueDTypeIndexedBy(adtypep->subDTypep()));
|
newp->dtypep(queueDTypeIndexedBy(adtypep->subDTypep()));
|
||||||
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
||||||
} else if (nodep->name() == "map") {
|
} else if (nodep->name() == "map") {
|
||||||
nodep->v3warn(E_UNSUPPORTED,
|
AstWith* const withp
|
||||||
"Unsupported: Wildcard array 'map' method (IEEE 1800-2023 7.12.5)");
|
= methodWithClause(nodep, true, false, adtypep->subDTypep(),
|
||||||
nodep->dtypeFrom(adtypep->subDTypep()); // Best guess
|
adtypep->findStringDType(), adtypep->subDTypep());
|
||||||
|
methodOkArguments(nodep, 0, 0);
|
||||||
|
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||||
|
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||||
|
VCMethod::ARRAY_MAP};
|
||||||
|
newp->withp(withp);
|
||||||
|
newp->dtypep(queueDTypeIndexedBy(withp ? withp->dtypep() : adtypep->subDTypep()));
|
||||||
|
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
||||||
} else {
|
} else {
|
||||||
nodep->v3error("Unknown wildcard associative array method " << nodep->prettyNameQ());
|
nodep->v3error("Unknown wildcard associative array method " << nodep->prettyNameQ());
|
||||||
nodep->dtypeFrom(adtypep->subDTypep()); // Best guess
|
nodep->dtypeFrom(adtypep->subDTypep()); // Best guess
|
||||||
|
|
@ -4148,9 +4155,15 @@ class WidthVisitor final : public VNVisitor {
|
||||||
newp->dtypep(queueDTypeIndexedBy(adtypep->keyDTypep()));
|
newp->dtypep(queueDTypeIndexedBy(adtypep->keyDTypep()));
|
||||||
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
||||||
} else if (nodep->name() == "map") {
|
} else if (nodep->name() == "map") {
|
||||||
nodep->v3warn(E_UNSUPPORTED,
|
AstWith* const withp = methodWithClause(nodep, true, false, adtypep->subDTypep(),
|
||||||
"Unsupported: Associative array 'map' method (IEEE 1800-2023 7.12.5)");
|
adtypep->keyDTypep(), adtypep->subDTypep());
|
||||||
nodep->dtypeFrom(adtypep->subDTypep()); // Best guess
|
methodOkArguments(nodep, 0, 0);
|
||||||
|
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||||
|
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||||
|
VCMethod::ARRAY_MAP};
|
||||||
|
newp->withp(withp);
|
||||||
|
newp->dtypep(queueDTypeIndexedBy(withp ? withp->dtypep() : adtypep->subDTypep()));
|
||||||
|
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
||||||
} else {
|
} else {
|
||||||
nodep->v3error("Unknown built-in associative array method " << nodep->prettyNameQ());
|
nodep->v3error("Unknown built-in associative array method " << nodep->prettyNameQ());
|
||||||
nodep->dtypeFrom(adtypep->subDTypep()); // Best guess
|
nodep->dtypeFrom(adtypep->subDTypep()); // Best guess
|
||||||
|
|
|
||||||
|
|
@ -208,6 +208,13 @@ module t;
|
||||||
b = points_q.sum with (vec_len_squared(item) inside {5, 17, 20});
|
b = points_q.sum with (vec_len_squared(item) inside {5, 17, 20});
|
||||||
`checkh(b, 1'b1);
|
`checkh(b, 1'b1);
|
||||||
|
|
||||||
|
// Map method (IEEE 1800-2023 7.12.5)
|
||||||
|
q = '{1: 100, 2: 200, 3: 300};
|
||||||
|
qv = q.map(el) with (el / 100);
|
||||||
|
`checkp(qv, "'{'h1, 'h2, 'h3}");
|
||||||
|
qv = q.map(el) with (el.index * 10);
|
||||||
|
`checkp(qv, "'{'ha, 'h14, 'h1e}");
|
||||||
|
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
%Error-UNSUPPORTED: t/t_assoc_method_map.v:19:13: Unsupported: Associative array 'map' method (IEEE 1800-2023 7.12.5)
|
|
||||||
: ... note: In instance 't'
|
|
||||||
19 | res = a.map(el) with (el == 2);
|
|
||||||
| ^~~
|
|
||||||
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
|
||||||
%Error: Exiting due to
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
|
||||||
#
|
|
||||||
# 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-FileCopyrightText: 2024 Wilson Snyder
|
|
||||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
|
||||||
|
|
||||||
import vltest_bootstrap
|
|
||||||
|
|
||||||
test.scenarios('vlt')
|
|
||||||
|
|
||||||
test.lint(fails=True, expect_filename=test.golden_filename)
|
|
||||||
|
|
||||||
test.passes()
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
// DESCRIPTION: Verilator: Verilog Test module
|
|
||||||
//
|
|
||||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
|
||||||
// SPDX-FileCopyrightText: 2024 Wilson Snyder
|
|
||||||
// SPDX-License-Identifier: CC0-1.0
|
|
||||||
|
|
||||||
// verilog_format: off
|
|
||||||
`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);
|
|
||||||
// verilog_format: on
|
|
||||||
|
|
||||||
module t;
|
|
||||||
|
|
||||||
initial begin
|
|
||||||
automatic int res[];
|
|
||||||
automatic int a[int] = '{1: 100, 2: 200, 3: 300};
|
|
||||||
|
|
||||||
// TODO results not known to be correct
|
|
||||||
res = a.map(el) with (el == 2);
|
|
||||||
`checkh(res.size, 3);
|
|
||||||
`checkh(res[0], 0);
|
|
||||||
`checkh(res[1], 1);
|
|
||||||
`checkh(res[2], 0);
|
|
||||||
end
|
|
||||||
endmodule
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
%Error-UNSUPPORTED: t/t_assoc_wildcard_map.v:19:13: Unsupported: Wildcard array 'map' method (IEEE 1800-2023 7.12.5)
|
|
||||||
: ... note: In instance 't'
|
|
||||||
19 | res = a.map(el) with (el == 2);
|
|
||||||
| ^~~
|
|
||||||
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
|
||||||
%Error: Exiting due to
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
|
||||||
#
|
|
||||||
# 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-FileCopyrightText: 2024 Wilson Snyder
|
|
||||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
|
||||||
|
|
||||||
import vltest_bootstrap
|
|
||||||
|
|
||||||
test.scenarios('vlt')
|
|
||||||
|
|
||||||
test.lint(fails=True, expect_filename=test.golden_filename)
|
|
||||||
|
|
||||||
test.passes()
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
// DESCRIPTION: Verilator: Verilog Test module
|
|
||||||
//
|
|
||||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
|
||||||
// SPDX-FileCopyrightText: 2023 Wilson Snyder
|
|
||||||
// SPDX-License-Identifier: CC0-1.0
|
|
||||||
|
|
||||||
// verilog_format: off
|
|
||||||
`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);
|
|
||||||
// verilog_format: on
|
|
||||||
|
|
||||||
module t;
|
|
||||||
|
|
||||||
initial begin
|
|
||||||
automatic int res[];
|
|
||||||
automatic int a [*] = '{1: 100, 2: 200, 3: 300};
|
|
||||||
|
|
||||||
// TODO results not known to be correct
|
|
||||||
res = a.map(el) with (el == 2);
|
|
||||||
`checkh(res.size, 3);
|
|
||||||
`checkh(res[0], 0);
|
|
||||||
`checkh(res[1], 1);
|
|
||||||
`checkh(res[2], 0);
|
|
||||||
end
|
|
||||||
endmodule
|
|
||||||
|
|
@ -150,6 +150,11 @@ module t;
|
||||||
b = points_q.sum with (vec_len_squared(item) inside {5, 17, 20});
|
b = points_q.sum with (vec_len_squared(item) inside {5, 17, 20});
|
||||||
`checkh(b, 1'b1);
|
`checkh(b, 1'b1);
|
||||||
|
|
||||||
|
// Map method (IEEE 1800-2023 7.12.5)
|
||||||
|
q = '{"a": 100, "b": 200, "c": 300};
|
||||||
|
qv = q.map(el) with (el / 100);
|
||||||
|
`checkp(qv, "'{'h1, 'h2, 'h3}");
|
||||||
|
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue