Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tgt-vvp: Support nested lvalues for all property types #1201

Merged
merged 2 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions ivtest/ivltests/sv_class_prop_nest_darray1.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Check that nested dynamic array typed class properties can be used as
// lvalues.

module test;

bit failed = 1'b0;

`define check(val, exp) do \
if (val !== exp) begin \
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
failed = 1'b1; \
end \
while(0)

class C;
C c;
int d[];
endclass

initial begin
C c1, c2;
int d[];

c1 = new;
c1.c = new;
c2 = c1.c;

d = new[2];
d[0] = 10;
c1.c.d = d;

d = c2.d;
`check(d[0], 10);

if (!failed) begin
$display("PASSED");
end
end

endmodule
38 changes: 38 additions & 0 deletions ivtest/ivltests/sv_class_prop_nest_obj1.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Check that nested object typed class properties can be used as lvalues.

module test;

bit failed = 1'b0;

`define check(val, exp) do \
if (val !== exp) begin \
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
failed = 1'b1; \
end \
while(0)

class C;
C c;
integer i;
endclass

initial begin
C c1, c2, c3;

c1 = new;
c1.c = new;
c2 = c1.c;

c3 = new;
c3.i = 10;
c1.c.c = c3;
c3 = c2.c;

`check(c3.i, 10);

if (!failed) begin
$display("PASSED");
end
end

endmodule
34 changes: 34 additions & 0 deletions ivtest/ivltests/sv_class_prop_nest_real1.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Check that nested real typed class properties can be used as lvalues.

module test;

bit failed = 1'b0;

`define check(val, exp) do \
if (val != exp) begin \
$display("FAILED(%0d). '%s' expected %f, got %f", `__LINE__, `"val`", exp, val); \
failed = 1'b1; \
end \
while(0)

class C;
C c;
real r;
endclass

initial begin
C c1, c2;

c1 = new;
c1.c = new;
c2 = c1.c;

c1.c.r = 12.3;
`check(c2.r, 12.3);

if (!failed) begin
$display("PASSED");
end
end

endmodule
34 changes: 34 additions & 0 deletions ivtest/ivltests/sv_class_prop_nest_str1.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Check that nested string typed class properties can be used as lvalues.

module test;

bit failed = 1'b0;

`define check(val, exp) do \
if (val != exp) begin \
$display("FAILED(%0d). '%s' expected %s, got %s", `__LINE__, `"val`", exp, val); \
failed = 1'b1; \
end \
while(0)

class C;
C c;
string s;
endclass

initial begin
C c1, c2;

c1 = new;
c1.c = new;
c2 = c1.c;

c1.c.s = "Hello";
`check(c2.s, "Hello");

if (!failed) begin
$display("PASSED");
end
end

endmodule
34 changes: 34 additions & 0 deletions ivtest/ivltests/sv_class_prop_nest_vec1.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Check that nested vector typed class properties can be used as lvalues.

module test;

bit failed = 1'b0;

`define check(val, exp) do \
if (val !== exp) begin \
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
failed = 1'b1; \
end \
while(0)

class C;
C c;
int i;
endclass

initial begin
C c1, c2;

c1 = new;
c1.c = new;
c2 = c1.c;

c1.c.i = 10;
`check(c2.i, 10);

if (!failed) begin
$display("PASSED");
end
end

endmodule
5 changes: 5 additions & 0 deletions ivtest/regress-vvp.list
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@ sv_chained_constructor5 vvp_tests/sv_chained_constructor5.json
sv_class_prop_assign_op1 vvp_tests/sv_class_prop_assign_op1.json
sv_class_prop_assign_op2 vvp_tests/sv_class_prop_assign_op2.json
sv_class_prop_logic vvp_tests/sv_class_prop_logic.json
sv_class_prop_nest_darray1 vvp_tests/sv_class_prop_nest_darray1.json
sv_class_prop_nest_obj1 vvp_tests/sv_class_prop_nest_obj1.json
sv_class_prop_nest_real1 vvp_tests/sv_class_prop_nest_str1.json
sv_class_prop_nest_str1 vvp_tests/sv_class_prop_nest_real1.json
sv_class_prop_nest_vec1 vvp_tests/sv_class_prop_nest_vec1.json
sv_const1 vvp_tests/sv_const1.json
sv_const2 vvp_tests/sv_const2.json
sv_const3 vvp_tests/sv_const3.json
Expand Down
5 changes: 5 additions & 0 deletions ivtest/vvp_tests/sv_class_prop_nest_darray1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "sv_class_prop_nest_darray1.v",
"iverilog-args" : [ "-g2005-sv" ]
}
5 changes: 5 additions & 0 deletions ivtest/vvp_tests/sv_class_prop_nest_obj1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "sv_class_prop_nest_obj1.v",
"iverilog-args" : [ "-g2005-sv" ]
}
5 changes: 5 additions & 0 deletions ivtest/vvp_tests/sv_class_prop_nest_real1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "sv_class_prop_nest_real1.v",
"iverilog-args" : [ "-g2005-sv" ]
}
5 changes: 5 additions & 0 deletions ivtest/vvp_tests/sv_class_prop_nest_str1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "sv_class_prop_nest_str1.v",
"iverilog-args" : [ "-g2005-sv" ]
}
5 changes: 5 additions & 0 deletions ivtest/vvp_tests/sv_class_prop_nest_vec1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "sv_class_prop_nest_vec1.v",
"iverilog-args" : [ "-g2005-sv" ]
}
49 changes: 19 additions & 30 deletions tgt-vvp/stmt_assign.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,25 +371,27 @@ static ivl_type_t draw_lval_expr(ivl_lval_t lval)
{
ivl_lval_t lval_nest = ivl_lval_nest(lval);
ivl_signal_t lval_sig = ivl_lval_sig(lval);
ivl_type_t sub_type;

if (lval_nest) {
sub_type = draw_lval_expr(lval_nest);
} else {
assert(lval_sig);
sub_type = ivl_signal_net_type(lval_sig);
assert(ivl_type_base(sub_type) == IVL_VT_CLASS);
if (lval_sig) {
fprintf(vvp_out, " %%load/obj v%p_0;\n", lval_sig);
return ivl_signal_net_type(lval_sig);
}

assert (lval_nest);
ivl_type_t sub_type = draw_lval_expr(lval_nest);
assert(ivl_type_base(sub_type) == IVL_VT_CLASS);
if (ivl_lval_idx(lval)) {

if (ivl_lval_idx(lval_nest)) {
fprintf(vvp_out, " ; XXXX Don't know how to handle ivl_lval_idx values here.\n");
}

fprintf(vvp_out, " %%prop/obj %d, 0; draw_lval_expr\n", ivl_lval_property_idx(lval));
int prop_idx = ivl_lval_property_idx(lval_nest);

fprintf(vvp_out, " %%prop/obj %d, 0; Load property %s\n", prop_idx,
ivl_type_prop_name(sub_type, prop_idx));
fprintf(vvp_out, " %%pop/obj 1, 1;\n");
return ivl_type_prop_type(sub_type, ivl_lval_property_idx(lval));

return ivl_type_prop_type(sub_type, prop_idx);
}

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


Expand Down Expand Up @@ -461,19 +462,6 @@ static void store_vec4_to_lval(ivl_statement_t net)
}
clr_word(offset_index);

} else if (nest) {
/* No offset expression, but the l-value is
nested, which probably means that it is a class
member. We will use a property assign
function. */
assert(!lsig);

ivl_type_t sub_type = draw_lval_expr(nest);
assert(ivl_type_base(sub_type) == IVL_VT_CLASS);
fprintf(vvp_out, " %%store/prop/v %d, %u;\n",
ivl_lval_property_idx(lval), lwid);
fprintf(vvp_out, " %%pop/obj 1, 0;\n");

} else {
/* No offset expression, so use simpler store function. */
assert(lsig);
Expand Down Expand Up @@ -1321,17 +1309,14 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net)
int errors = 0;
ivl_lval_t lval = ivl_stmt_lval(net, 0);
ivl_expr_t rval = ivl_stmt_rval(net);
ivl_signal_t sig= ivl_lval_sig(lval);
unsigned lwid = ivl_lval_width(lval);

int prop_idx = ivl_lval_property_idx(lval);


if (prop_idx >= 0) {
ivl_type_t sig_type = ivl_signal_net_type(sig);
ivl_type_t sig_type = draw_lval_expr(lval);
ivl_type_t prop_type = ivl_type_prop_type(sig_type, prop_idx);

fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);

if (ivl_type_base(prop_type) == IVL_VT_BOOL ||
ivl_type_base(prop_type) == IVL_VT_LOGIC) {
assert(ivl_type_packed_dimensions(prop_type) == 0 ||
Expand Down Expand Up @@ -1413,6 +1398,9 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net)
}

} else {
ivl_signal_t sig = ivl_lval_sig(lval);
assert(!ivl_lval_nest(lval));

if (ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN) {
draw_array_pattern(sig, rval, 0);
return 0;
Expand Down Expand Up @@ -1466,7 +1454,8 @@ int show_stmt_assign(ivl_statement_t net)
return show_stmt_assign_sig_queue(net);
}

if (sig && (ivl_signal_data_type(sig) == IVL_VT_CLASS)) {
if ((sig && (ivl_signal_data_type(sig) == IVL_VT_CLASS)) ||
ivl_lval_nest(lval)) {
return show_stmt_assign_sig_cobject(net);
}

Expand Down