Skip to content

Commit 27bae7e

Browse files
authored
Merge pull request #1201 from larsclausen/nested-lvalue-types
tgt-vvp: Support nested lvalues for all property types
2 parents b794b9c + e2008c9 commit 27bae7e

12 files changed

+229
-30
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Check that nested dynamic array typed class properties can be used as
2+
// lvalues.
3+
4+
module test;
5+
6+
bit failed = 1'b0;
7+
8+
`define check(val, exp) do \
9+
if (val !== exp) begin \
10+
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
11+
failed = 1'b1; \
12+
end \
13+
while(0)
14+
15+
class C;
16+
C c;
17+
int d[];
18+
endclass
19+
20+
initial begin
21+
C c1, c2;
22+
int d[];
23+
24+
c1 = new;
25+
c1.c = new;
26+
c2 = c1.c;
27+
28+
d = new[2];
29+
d[0] = 10;
30+
c1.c.d = d;
31+
32+
d = c2.d;
33+
`check(d[0], 10);
34+
35+
if (!failed) begin
36+
$display("PASSED");
37+
end
38+
end
39+
40+
endmodule
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Check that nested object typed class properties can be used as lvalues.
2+
3+
module test;
4+
5+
bit failed = 1'b0;
6+
7+
`define check(val, exp) do \
8+
if (val !== exp) begin \
9+
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
10+
failed = 1'b1; \
11+
end \
12+
while(0)
13+
14+
class C;
15+
C c;
16+
integer i;
17+
endclass
18+
19+
initial begin
20+
C c1, c2, c3;
21+
22+
c1 = new;
23+
c1.c = new;
24+
c2 = c1.c;
25+
26+
c3 = new;
27+
c3.i = 10;
28+
c1.c.c = c3;
29+
c3 = c2.c;
30+
31+
`check(c3.i, 10);
32+
33+
if (!failed) begin
34+
$display("PASSED");
35+
end
36+
end
37+
38+
endmodule
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Check that nested real typed class properties can be used as lvalues.
2+
3+
module test;
4+
5+
bit failed = 1'b0;
6+
7+
`define check(val, exp) do \
8+
if (val != exp) begin \
9+
$display("FAILED(%0d). '%s' expected %f, got %f", `__LINE__, `"val`", exp, val); \
10+
failed = 1'b1; \
11+
end \
12+
while(0)
13+
14+
class C;
15+
C c;
16+
real r;
17+
endclass
18+
19+
initial begin
20+
C c1, c2;
21+
22+
c1 = new;
23+
c1.c = new;
24+
c2 = c1.c;
25+
26+
c1.c.r = 12.3;
27+
`check(c2.r, 12.3);
28+
29+
if (!failed) begin
30+
$display("PASSED");
31+
end
32+
end
33+
34+
endmodule
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Check that nested string typed class properties can be used as lvalues.
2+
3+
module test;
4+
5+
bit failed = 1'b0;
6+
7+
`define check(val, exp) do \
8+
if (val != exp) begin \
9+
$display("FAILED(%0d). '%s' expected %s, got %s", `__LINE__, `"val`", exp, val); \
10+
failed = 1'b1; \
11+
end \
12+
while(0)
13+
14+
class C;
15+
C c;
16+
string s;
17+
endclass
18+
19+
initial begin
20+
C c1, c2;
21+
22+
c1 = new;
23+
c1.c = new;
24+
c2 = c1.c;
25+
26+
c1.c.s = "Hello";
27+
`check(c2.s, "Hello");
28+
29+
if (!failed) begin
30+
$display("PASSED");
31+
end
32+
end
33+
34+
endmodule
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Check that nested vector typed class properties can be used as lvalues.
2+
3+
module test;
4+
5+
bit failed = 1'b0;
6+
7+
`define check(val, exp) do \
8+
if (val !== exp) begin \
9+
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
10+
failed = 1'b1; \
11+
end \
12+
while(0)
13+
14+
class C;
15+
C c;
16+
int i;
17+
endclass
18+
19+
initial begin
20+
C c1, c2;
21+
22+
c1 = new;
23+
c1.c = new;
24+
c2 = c1.c;
25+
26+
c1.c.i = 10;
27+
`check(c2.i, 10);
28+
29+
if (!failed) begin
30+
$display("PASSED");
31+
end
32+
end
33+
34+
endmodule

ivtest/regress-vvp.list

+5
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ sv_chained_constructor5 vvp_tests/sv_chained_constructor5.json
225225
sv_class_prop_assign_op1 vvp_tests/sv_class_prop_assign_op1.json
226226
sv_class_prop_assign_op2 vvp_tests/sv_class_prop_assign_op2.json
227227
sv_class_prop_logic vvp_tests/sv_class_prop_logic.json
228+
sv_class_prop_nest_darray1 vvp_tests/sv_class_prop_nest_darray1.json
229+
sv_class_prop_nest_obj1 vvp_tests/sv_class_prop_nest_obj1.json
230+
sv_class_prop_nest_real1 vvp_tests/sv_class_prop_nest_str1.json
231+
sv_class_prop_nest_str1 vvp_tests/sv_class_prop_nest_real1.json
232+
sv_class_prop_nest_vec1 vvp_tests/sv_class_prop_nest_vec1.json
228233
sv_const1 vvp_tests/sv_const1.json
229234
sv_const2 vvp_tests/sv_const2.json
230235
sv_const3 vvp_tests/sv_const3.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type" : "normal",
3+
"source" : "sv_class_prop_nest_darray1.v",
4+
"iverilog-args" : [ "-g2005-sv" ]
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type" : "normal",
3+
"source" : "sv_class_prop_nest_obj1.v",
4+
"iverilog-args" : [ "-g2005-sv" ]
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type" : "normal",
3+
"source" : "sv_class_prop_nest_real1.v",
4+
"iverilog-args" : [ "-g2005-sv" ]
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type" : "normal",
3+
"source" : "sv_class_prop_nest_str1.v",
4+
"iverilog-args" : [ "-g2005-sv" ]
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type" : "normal",
3+
"source" : "sv_class_prop_nest_vec1.v",
4+
"iverilog-args" : [ "-g2005-sv" ]
5+
}

tgt-vvp/stmt_assign.c

+19-30
Original file line numberDiff line numberDiff line change
@@ -371,25 +371,27 @@ static ivl_type_t draw_lval_expr(ivl_lval_t lval)
371371
{
372372
ivl_lval_t lval_nest = ivl_lval_nest(lval);
373373
ivl_signal_t lval_sig = ivl_lval_sig(lval);
374-
ivl_type_t sub_type;
375374

376-
if (lval_nest) {
377-
sub_type = draw_lval_expr(lval_nest);
378-
} else {
379-
assert(lval_sig);
380-
sub_type = ivl_signal_net_type(lval_sig);
381-
assert(ivl_type_base(sub_type) == IVL_VT_CLASS);
375+
if (lval_sig) {
382376
fprintf(vvp_out, " %%load/obj v%p_0;\n", lval_sig);
377+
return ivl_signal_net_type(lval_sig);
383378
}
384379

380+
assert (lval_nest);
381+
ivl_type_t sub_type = draw_lval_expr(lval_nest);
385382
assert(ivl_type_base(sub_type) == IVL_VT_CLASS);
386-
if (ivl_lval_idx(lval)) {
383+
384+
if (ivl_lval_idx(lval_nest)) {
387385
fprintf(vvp_out, " ; XXXX Don't know how to handle ivl_lval_idx values here.\n");
388386
}
389387

390-
fprintf(vvp_out, " %%prop/obj %d, 0; draw_lval_expr\n", ivl_lval_property_idx(lval));
388+
int prop_idx = ivl_lval_property_idx(lval_nest);
389+
390+
fprintf(vvp_out, " %%prop/obj %d, 0; Load property %s\n", prop_idx,
391+
ivl_type_prop_name(sub_type, prop_idx));
391392
fprintf(vvp_out, " %%pop/obj 1, 1;\n");
392-
return ivl_type_prop_type(sub_type, ivl_lval_property_idx(lval));
393+
394+
return ivl_type_prop_type(sub_type, prop_idx);
393395
}
394396

395397
/*
@@ -407,7 +409,6 @@ static void store_vec4_to_lval(ivl_statement_t net)
407409
for (unsigned lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) {
408410
ivl_lval_t lval = ivl_stmt_lval(net,lidx);
409411
ivl_signal_t lsig = ivl_lval_sig(lval);
410-
ivl_lval_t nest = ivl_lval_nest(lval);
411412
unsigned lwid = ivl_lval_width(lval);
412413

413414

@@ -461,19 +462,6 @@ static void store_vec4_to_lval(ivl_statement_t net)
461462
}
462463
clr_word(offset_index);
463464

464-
} else if (nest) {
465-
/* No offset expression, but the l-value is
466-
nested, which probably means that it is a class
467-
member. We will use a property assign
468-
function. */
469-
assert(!lsig);
470-
471-
ivl_type_t sub_type = draw_lval_expr(nest);
472-
assert(ivl_type_base(sub_type) == IVL_VT_CLASS);
473-
fprintf(vvp_out, " %%store/prop/v %d, %u;\n",
474-
ivl_lval_property_idx(lval), lwid);
475-
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
476-
477465
} else {
478466
/* No offset expression, so use simpler store function. */
479467
assert(lsig);
@@ -1321,17 +1309,14 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net)
13211309
int errors = 0;
13221310
ivl_lval_t lval = ivl_stmt_lval(net, 0);
13231311
ivl_expr_t rval = ivl_stmt_rval(net);
1324-
ivl_signal_t sig= ivl_lval_sig(lval);
13251312
unsigned lwid = ivl_lval_width(lval);
1326-
13271313
int prop_idx = ivl_lval_property_idx(lval);
13281314

1315+
13291316
if (prop_idx >= 0) {
1330-
ivl_type_t sig_type = ivl_signal_net_type(sig);
1317+
ivl_type_t sig_type = draw_lval_expr(lval);
13311318
ivl_type_t prop_type = ivl_type_prop_type(sig_type, prop_idx);
13321319

1333-
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
1334-
13351320
if (ivl_type_base(prop_type) == IVL_VT_BOOL ||
13361321
ivl_type_base(prop_type) == IVL_VT_LOGIC) {
13371322
assert(ivl_type_packed_dimensions(prop_type) == 0 ||
@@ -1413,6 +1398,9 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net)
14131398
}
14141399

14151400
} else {
1401+
ivl_signal_t sig = ivl_lval_sig(lval);
1402+
assert(!ivl_lval_nest(lval));
1403+
14161404
if (ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN) {
14171405
draw_array_pattern(sig, rval, 0);
14181406
return 0;
@@ -1466,7 +1454,8 @@ int show_stmt_assign(ivl_statement_t net)
14661454
return show_stmt_assign_sig_queue(net);
14671455
}
14681456

1469-
if (sig && (ivl_signal_data_type(sig) == IVL_VT_CLASS)) {
1457+
if ((sig && (ivl_signal_data_type(sig) == IVL_VT_CLASS)) ||
1458+
ivl_lval_nest(lval)) {
14701459
return show_stmt_assign_sig_cobject(net);
14711460
}
14721461

0 commit comments

Comments
 (0)