From 46951c778e6828ff1f8d068f62a838360cbf66a5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 4 Oct 2022 12:04:12 +0200 Subject: [PATCH 1/2] Handle default argument values for class function method calls For class function method calls currently only as many arguments as have been supplied are elaborated. Any trailing arguments that might have default values are skipped. This will trigger an assertion later on in the vvp code generator backend. Fix this by making sure that all arguments of the function are evaluated. Note that this already works correctly for class task method calls. Signed-off-by: Lars-Peter Clausen --- elab_expr.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index c643f1466..530f47b7e 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -3185,13 +3185,13 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope, NetNet*res = method->find_signal(method->basename()); ivl_assert(*this, res); - vectorparms; + vector parms(def->port_count()); + ivl_assert(*this, def->port_count() >= 1); NetESignal*ethis = new NetESignal(net); ethis->set_line(*this); - parms.push_back(ethis); + parms[0] = ethis; - parms.resize(1 + parms_.size()); elaborate_arguments_(des, scope, def, false, parms, 1); NetESignal*eres = new NetESignal(res); From 0aef9326ca59c1aa20a380eb83ecdc965be7648b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 4 Oct 2022 15:03:03 +0200 Subject: [PATCH 2/2] Add regression test for class method argument defaults Check that default values for class methods are handled correctly and it is possible to omit any argument. Check it for both functions and tasks. Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/sv_class_method_default1.v | 41 ++++++++++++++++ ivtest/ivltests/sv_class_method_default2.v | 54 ++++++++++++++++++++++ ivtest/regress-sv.list | 2 + ivtest/regress-vlog95.list | 2 + 4 files changed, 99 insertions(+) create mode 100644 ivtest/ivltests/sv_class_method_default1.v create mode 100644 ivtest/ivltests/sv_class_method_default2.v diff --git a/ivtest/ivltests/sv_class_method_default1.v b/ivtest/ivltests/sv_class_method_default1.v new file mode 100644 index 000000000..1900dc476 --- /dev/null +++ b/ivtest/ivltests/sv_class_method_default1.v @@ -0,0 +1,41 @@ +// Check that default values on function methods are supported and it is +// possible to omit any of the arguments. + +class C; + function integer f(integer x = 1, integer y = 2, integer z = 3); + return x + y + z; + endfunction +endclass + +module test; + + C c = new; + + bit failed = 1'b0; + + `define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED. %s, expected %d, got %d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + + initial begin + `check(c.f(), 6); + `check(c.f(4), 9); + `check(c.f(4, ), 9); + `check(c.f(4, , ), 9); + `check(c.f(4, 6), 13); + `check(c.f(4, 6, ), 13); + `check(c.f(4, , 8), 14); + `check(c.f(4, 6, 8), 18); + `check(c.f(, 6), 10); + `check(c.f(, 6, ), 10); + `check(c.f(, 6 ,8), 15); + `check(c.f(, , 8), 11); + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_class_method_default2.v b/ivtest/ivltests/sv_class_method_default2.v new file mode 100644 index 000000000..2294e1f30 --- /dev/null +++ b/ivtest/ivltests/sv_class_method_default2.v @@ -0,0 +1,54 @@ +// Check that default values on task methods are supported and it is possible to +// omit any of the arguments. + +class C; + integer r; + task t(integer x = 1, integer y = 2, integer z = 3); + r = x + y + z; + endtask +endclass + +module test; + + C c = new; + + bit failed = 1'b0; + + `define check(expr, val) \ + if (expr !== val) begin \ + $display("FAILED. %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + + initial begin + c.t(); + `check(c.r, 6); + c.t(4); + `check(c.r, 9); + c.t(4, ); + `check(c.r, 9); + c.t(4, ,); + `check(c.r, 9); + c.t(4, 6); + `check(c.r, 13); + c.t(4, 6, ); + `check(c.r, 13); + c.t(4, , 8); + `check(c.r, 14); + c.t(4, 6, 8); + `check(c.r, 18); + c.t(, 6); + `check(c.r, 10); + c.t(, 6, ); + `check(c.r, 10); + c.t(, 6, 8); + `check(c.r, 15); + c.t(, , 8); + `check(c.r, 11); + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index 9e133585b..dceb1c889 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -527,6 +527,8 @@ sv_class_new_fail1 CE,-g2009 ivltests sv_class_new_fail2 CE,-g2009 ivltests sv_class_new_init normal,-g2009 ivltests sv_class_in_module_decl normal,-g2009 ivltests +sv_class_method_default1 normal,-g2009 ivltests +sv_class_method_default2 normal,-g2009 ivltests sv_class_method_signed1 normal,-g2009 ivltests sv_class_method_signed2 normal,-g2009 ivltests sv_class_property_signed1 normal,-g2009 ivltests diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index a42d24955..0fdd10572 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -407,6 +407,8 @@ sv_class_extends_scoped CE,-g2009 ivltests sv_class_localparam CE,-g2009 ivltests sv_class_new_init CE,-g2009 ivltests sv_class_in_module_decl CE,-g2009 ivltests +sv_class_method_default1 CE,-g2009 ivltests +sv_class_method_default2 CE,-g2009 ivltests sv_class_method_signed1 CE,-g2009,-pallowsigned=1 ivltests sv_class_method_signed2 CE,-g2009,-pallowsigned=1 ivltests sv_class_property_signed1 CE,-g2009,-pallowsigned=1 ivltests