Support selects on arbitrary string expressions (#5773)
This commit is contained in:
parent
caa19c0cb3
commit
f753ae2518
|
@ -305,13 +305,19 @@ class WidthSelVisitor final : public VNVisitor {
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (VN_IS(ddtypep, BasicDType) && ddtypep->isString()) {
|
||||
// SELBIT(string, index) -> GETC(string, index)
|
||||
const AstNodeVarRef* const varrefp = VN_CAST(fromp, NodeVarRef);
|
||||
if (!varrefp) {
|
||||
nodep->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported: String array operation on non-variable");
|
||||
AstNodeExpr* exprp = fromp;
|
||||
while (true) {
|
||||
if (AstMemberSel* const memberselp = VN_CAST(exprp, MemberSel)) {
|
||||
exprp = memberselp->fromp();
|
||||
} else if (AstStructSel* const structselp = VN_CAST(exprp, StructSel)) {
|
||||
exprp = structselp->fromp();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
const AstNodeVarRef* const varrefp = VN_CAST(exprp, NodeVarRef);
|
||||
AstNodeExpr* newp;
|
||||
if (varrefp && varrefp->access().isReadOnly()) {
|
||||
if (!varrefp || varrefp->access().isReadOnly()) {
|
||||
newp = new AstGetcN{nodep->fileline(), fromp, rhsp};
|
||||
} else {
|
||||
newp = new AstGetcRefN{nodep->fileline(), fromp, rhsp};
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2025 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
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('vlt')
|
||||
|
||||
test.compile()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
|
@ -0,0 +1,60 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2025 by Antmicro.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
typedef struct {
|
||||
string str;
|
||||
} str_s;
|
||||
|
||||
class c;
|
||||
string str;
|
||||
function new();
|
||||
str = "foo";
|
||||
endfunction
|
||||
function string get_str();
|
||||
return str;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
string str = "bar";
|
||||
|
||||
function string get_str();
|
||||
return str;
|
||||
endfunction
|
||||
|
||||
initial begin
|
||||
c o = new;
|
||||
str_s st = '{"qux"};
|
||||
string sc = {"foo", "bar"};
|
||||
|
||||
// read
|
||||
if (str[0] != "b") $stop;
|
||||
if (get_str()[1] != "a") $stop;
|
||||
if (str[3] != "\0") $stop;
|
||||
if (st.str[2] != "x") $stop;
|
||||
if (st.str[99] != "\0") $stop;
|
||||
if (o.str[0] != "f") $stop;
|
||||
if (o.get_str()[1] != "o") $stop;
|
||||
if (o.str[-1] != "\0") $stop;
|
||||
if (sc[2] != "o") $stop;
|
||||
if ($sformatf("foo%s", "bar")[3] != "b") $stop;
|
||||
if (sc[-1] != "\0") $stop;
|
||||
if (sc[6] != "\0") $stop;
|
||||
if (sc[99] != "\0") $stop;
|
||||
|
||||
// write
|
||||
sc[5] = "z";
|
||||
if (sc != "foobaz") $stop;
|
||||
o.str[0] = "b";
|
||||
if (o.str != "boo") $stop;
|
||||
st.str[2] = "z";
|
||||
if (st.str != "quz") $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
Loading…
Reference in New Issue