From f95f9955c85628b9963250fe3077baa4541ea899 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 29 Mar 2022 16:49:47 +0200 Subject: [PATCH 1/2] Handle assignment to static class properties in class methods Assigning a value to a static class property in a class task or function will currently not write to the static signal, but instead to an otherwise invisible per instance property. E.g. the example below will print 0 when the task `t` is called. ``` class C; static int i; task t; i = 10; $display(i); end endclass ``` Since static class properties are implemented as normal signals just fallback to the default signal handling when an assignment to a static class property is detected. Signed-off-by: Lars-Peter Clausen --- elab_lval.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/elab_lval.cc b/elab_lval.cc index 1da3871d8c..36bee8ac5e 100644 --- a/elab_lval.cc +++ b/elab_lval.cc @@ -393,6 +393,13 @@ NetAssign_* PEIdent::elaborate_lval_method_class_member_(Design*des, if (pidx < 0) return 0; + property_qualifier_t qual = class_type->get_prop_qual(pidx); + + // Static properties are handled as normal signals. Regular symbol + // search will find it. + if (qual.test_static()) + return 0; + NetScope*scope_method = find_method_containing_scope(*this, scope); ivl_assert(*this, scope_method); @@ -428,7 +435,6 @@ NetAssign_* PEIdent::elaborate_lval_method_class_member_(Design*des, // Detect assignment to constant properties. Note that the // initializer constructor MAY assign to constant properties, // as this is how the property gets its value. - property_qualifier_t qual = class_type->get_prop_qual(pidx); if (qual.test_const()) { if (class_type->get_prop_initialized(pidx)) { cerr << get_fileline() << ": error: " From ea55421a0714903e000e659e81e2c6286701f8e1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 30 Mar 2022 10:21:43 +0200 Subject: [PATCH 2/2] Add regression test for accessing static class properties Check that static class properties can be accessed for read and write and that they are shared between all instances of a class type. Check that this works for the following 3 cases * accessing the static property in a class function or task * accessing the static property in a class function or task using `this` * accessing the static property on a class object instance Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/sv_class_static_prop1.v | 30 ++++++++++++++++++++++++ ivtest/ivltests/sv_class_static_prop2.v | 30 ++++++++++++++++++++++++ ivtest/ivltests/sv_class_static_prop3.v | 31 +++++++++++++++++++++++++ ivtest/regress-sv.list | 3 +++ ivtest/regress-vlog95.list | 3 +++ 5 files changed, 97 insertions(+) create mode 100644 ivtest/ivltests/sv_class_static_prop1.v create mode 100644 ivtest/ivltests/sv_class_static_prop2.v create mode 100644 ivtest/ivltests/sv_class_static_prop3.v diff --git a/ivtest/ivltests/sv_class_static_prop1.v b/ivtest/ivltests/sv_class_static_prop1.v new file mode 100644 index 0000000000..1ed34b5fea --- /dev/null +++ b/ivtest/ivltests/sv_class_static_prop1.v @@ -0,0 +1,30 @@ +// Check that static class properties can be accessed for read and write in +// class tasks. Check the property is shared across all instances and has the +// same value for all instances. + +class C; + static int i; + task t; + int x; + x = i; + i = x + 1; + endtask +endclass + +module test; + + C c1 = new; + C c2 = new; + C c3 = new; + + initial begin + c1.t(); + c2.t(); + if (c1.i == 2 && c2.i == 2 && c3.i == 2) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_class_static_prop2.v b/ivtest/ivltests/sv_class_static_prop2.v new file mode 100644 index 0000000000..a176be0496 --- /dev/null +++ b/ivtest/ivltests/sv_class_static_prop2.v @@ -0,0 +1,30 @@ +// Check that static class properties can be accessed for read and write in +// class tasks using `this`. Check the property is shared across all instances +// and has the same value for all instances. + +class C; + static int i; + task t; + int x; + x = this.i; + this.i = x + 1; + endtask +endclass + +module test; + + C c1 = new; + C c2 = new; + C c3 = new; + + initial begin + c1.t(); + c2.t(); + if (c1.i == 2 && c2.i == 2 && c3.i == 2) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_class_static_prop3.v b/ivtest/ivltests/sv_class_static_prop3.v new file mode 100644 index 0000000000..3b1b2fb40d --- /dev/null +++ b/ivtest/ivltests/sv_class_static_prop3.v @@ -0,0 +1,31 @@ +// Check that static class properties can be accessed for read and write on a +// class object. Check the property is shared across all instances and has the +// same value for all instances. + +class C; + static int i; +endclass + +module test; + + C c1 = new; + C c2 = new; + C c3 = new; + + task t(C c); + int x; + x = c.i; + c.i = x + 1; + endtask + + initial begin + t(c1); + t(c2); + if (c1.i == 2 && c2.i == 2 && c3.i == 2) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index 15ea67e72b..af749f4e1a 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -487,6 +487,9 @@ sv_class_extends_scoped normal,-g2009 ivltests sv_class_localparam normal,-g2009 ivltests sv_class_new_init normal,-g2009 ivltests sv_class_in_module_decl normal,-g2009 ivltests +sv_class_static_prop1 normal,-g2009 ivltests +sv_class_static_prop2 normal,-g2009 ivltests +sv_class_static_prop3 normal,-g2009 ivltests sv_class_super1 normal,-g2009 ivltests sv_class_super2 normal,-g2009 ivltests sv_class_task1 normal,-g2009 ivltests diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index b70b1bd665..c4b85936a1 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -383,6 +383,9 @@ 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_static_prop1 CE,-g2009 ivltests +sv_class_static_prop2 CE,-g2009 ivltests +sv_class_static_prop3 CE,-g2009 ivltests sv_class_super1 CE,-g2009 ivltests sv_class_super2 CE,-g2009 ivltests sv_class_task1 CE,-g2009 ivltests