Support member selects in with clauses (#3775)

This commit is contained in:
Ryszard Rozak 2022-11-23 19:15:10 +01:00 committed by GitHub
parent a83ed6b06f
commit 68f8617f79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 76 additions and 1 deletions

View File

@ -2347,9 +2347,11 @@ private:
VL_DO_DANGLING(pushDeletep(nodep), nodep);
return;
}
if (m_ds.m_dotPos == DP_FINAL && VN_IS(m_ds.m_unlinkedScopep, LambdaArgRef)
if (m_ds.m_dotPos == DP_MEMBER && VN_IS(m_ds.m_dotp->lhsp(), LambdaArgRef)
&& nodep->name() == "index") {
// 'with' statement's 'item.index'
// m_ds.dotp->lhsp() was checked to know if `index` is directly after lambda arg ref.
// If not, treat it as normal member select
iterateChildren(nodep);
const auto newp = new AstLambdaArgRef{
nodep->fileline(), m_ds.m_unlinkedScopep->name() + "__DOT__index", true};
@ -2577,6 +2579,7 @@ private:
nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
ok = true;
m_ds.m_dotPos = DP_MEMBER;
m_ds.m_dotText = "";
}
}

View File

@ -11,6 +11,8 @@
`define checkg(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='%g' exp='%g'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
module t (/*AUTOARG*/);
typedef struct packed { int x, y; } point;
typedef struct packed { point p; int z; } point_3d;
initial begin
int q[$];
int qe[$]; // Empty
@ -19,6 +21,18 @@ module t (/*AUTOARG*/);
int qi[$]; // Index returns
int i;
string v;
string string_q[$];
string string_qv[$];
point_3d points_q[$]; // Same as q and qv, but complex value type
point_3d points_qv[$];
points_q.push_back(point_3d'{point'{1, 2}, 3});
points_q.push_back(point_3d'{point'{2, 3}, 5});
points_q.push_back(point_3d'{point'{1, 4}, 5});
string_q.push_back("a");
string_q.push_back("A");
string_q.push_back("b");
q = '{1, 2, 2, 4, 3};
v = $sformatf("%p", q); `checks(v, "'{'h1, 'h2, 'h2, 'h4, 'h3} ");
@ -46,6 +60,8 @@ module t (/*AUTOARG*/);
`checkh(qv.size(), 0);
qv = q.unique(x) with (x % 2);
`checkh(qv.size(), 2);
string_qv = string_q.unique(s) with (s.toupper);
`checkh(string_qv.size(), 2);
qi = q.unique_index; qv.sort;
// According to 7.12.1 of IEEE Std 1800-2017, it is not specified which index of duplicated value should be returned
`checkh(qi.size(), 4);
@ -73,8 +89,14 @@ module t (/*AUTOARG*/);
v = $sformatf("%p", qv); `checks(v, "'{'h1, 'h3} ");
qv = q.find_first with (item == 2);
v = $sformatf("%p", qv); `checks(v, "'{'h2} ");
points_qv = points_q.find_first with (item.z == 5);
`checkh(points_qv[0].p.y, 3);
points_qv = points_q.find_first with (item.p.x == 1);
`checkh(points_qv[0].p.y, 2);
qv = q.find_last with (item == 2);
v = $sformatf("%p", qv); `checks(v, "'{'h2} ");
string_qv = string_q.find_last(s) with (s.tolower() == "a");
`checks(string_qv[0], "A");
qv = q.find with (item == 20);
`checkh(qv.size, 0);

View File

@ -0,0 +1,10 @@
%Error-UNSUPPORTED: t/t_queue_method3_bad.v:16:52: Unsupported: Member call on object 'SEL' which is a 'BASICDTYPE 'int''
: ... In instance t
16 | points_qv = points_q.find_first(a) with (a.x.index == 0);
| ^~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: Internal Error: t/t_queue_method3_bad.v:16:58: ../V3Width.cpp:#: Node has no type
: ... In instance t
16 | points_qv = points_q.find_first(a) with (a.x.index == 0);
| ^~
... See the manual at https://verilator.org/verilator_doc.html for more assistance.

View File

@ -0,0 +1,19 @@
#!/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 Antmicro Ltd. 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(vlt => 1);
lint(
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -0,0 +1,21 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2022 by Antmicro Ltd.
// SPDX-License-Identifier: CC0-1.0
module t (/*AUTOARG*/);
typedef struct packed { int x, y; } point;
initial begin
point points_q[$];
point points_qv[$];
points_q.push_back(point'{1, 2});
// `index` should be treated as normal member select,
// but the member is not present in the struct
points_qv = points_q.find_first(a) with (a.x.index == 0);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule