mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Support member selects in with clauses (#3775)
This commit is contained in:
parent
a83ed6b06f
commit
68f8617f79
@ -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 = "";
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
10
test_regress/t/t_queue_method3_bad.out
Normal file
10
test_regress/t/t_queue_method3_bad.out
Normal 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.
|
19
test_regress/t/t_queue_method3_bad.pl
Executable file
19
test_regress/t/t_queue_method3_bad.pl
Executable 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;
|
21
test_regress/t/t_queue_method3_bad.v
Normal file
21
test_regress/t/t_queue_method3_bad.v
Normal 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
|
Loading…
Reference in New Issue
Block a user