diff --git a/ivtest/ivltests/sv_class_compat1.v b/ivtest/ivltests/sv_class_compat1.v new file mode 100644 index 000000000..be4d94804 --- /dev/null +++ b/ivtest/ivltests/sv_class_compat1.v @@ -0,0 +1,31 @@ +// Check that an object can be assigned to a variable of its base class type + +module test; + + class B; + int x; + + task t; + $display("PASSED"); + endtask + endclass + + class C extends B; + int y; + + task t; + $display("FAILED"); + endtask + endclass + + B b; + C c; + + initial begin + c = new; + b = c; + + b.t; + end + +endmodule diff --git a/ivtest/ivltests/sv_class_compat2.v b/ivtest/ivltests/sv_class_compat2.v new file mode 100644 index 000000000..29eb7bf59 --- /dev/null +++ b/ivtest/ivltests/sv_class_compat2.v @@ -0,0 +1,40 @@ +// Check that an object can be assigned to a variable of base class across more +// than one hierarchy level + +module test; + + class B; + int x; + + task t; + $display("PASSED"); + endtask + endclass + + class C extends B; + int y; + + task t; + $display("FAILED"); + endtask + endclass + + class D extends C; + int z; + + task t; + $display("FAILED"); + endtask + endclass + + B b; + D d; + + initial begin + d = new; + b = d; + + b.t; + end + +endmodule diff --git a/ivtest/ivltests/sv_class_compat_fail1.v b/ivtest/ivltests/sv_class_compat_fail1.v new file mode 100644 index 000000000..e96f018a8 --- /dev/null +++ b/ivtest/ivltests/sv_class_compat_fail1.v @@ -0,0 +1,22 @@ +// Check that an error is reported when trying to assign an object to variable +// of an unrelated class type + +module test; + + class B; + int x; + endclass + + class C; + int y; + endclass + + B b; + C c; + + initial begin + c = new; + b = c; // This should fail, both classes are unrelated + end + +endmodule diff --git a/ivtest/ivltests/sv_class_compat_fail2.v b/ivtest/ivltests/sv_class_compat_fail2.v new file mode 100644 index 000000000..e8563b47f --- /dev/null +++ b/ivtest/ivltests/sv_class_compat_fail2.v @@ -0,0 +1,22 @@ +// Check that an error is reported when trying when trying to assign an object +// of a base class to a variable of a inherited class. + +module test; + + class B; + int x; + endclass + + class C extends B; + int y; + endclass + + B b; + C c; + + initial begin + b = new; + c = b; // This should fail, B is a base class of C + end + +endmodule diff --git a/ivtest/ivltests/sv_class_compat_fail3.v b/ivtest/ivltests/sv_class_compat_fail3.v new file mode 100644 index 000000000..a7301386e --- /dev/null +++ b/ivtest/ivltests/sv_class_compat_fail3.v @@ -0,0 +1,27 @@ +// Check that an error is reported when trying to assign an object to a variable +// that shares a common base class but is not directly related. + +module test; + + class B; + int x; + endclass + + class C extends B; + int y; + endclass + + class D extends B; + int z; + endclass + + C c; + D d; + + initial begin + c = new; + d = c; // This should fail, both C and D inherit from B, but there is no + // direct relationship. + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index c7dea8134..efebe53e8 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -531,6 +531,11 @@ sv_class21 normal,-g2009 ivltests sv_class22 normal,-g2009 ivltests sv_class23 normal,-g2009 ivltests sv_class24 normal,-g2009 ivltests +sv_class_compat1 normal,-g2009 ivltests +sv_class_compat2 normal,-g2009 ivltests +sv_class_compat_fail1 CE,-g2009 ivltests +sv_class_compat_fail2 CE,-g2009 ivltests +sv_class_compat_fail3 CE,-g2009 ivltests sv_class_constructor1 normal,-g2009 ivltests sv_class_constructor_fail CE,-g2009 ivltests sv_class_empty_item normal,-g2009 ivltests diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index 323a0cb1a..324a6d41e 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -404,6 +404,8 @@ sv_class21 CE,-g2009 ivltests sv_class22 CE,-g2009 ivltests sv_class23 CE,-g2009 ivltests sv_class24 CE,-g2009 ivltests +sv_class_compat1 CE,-g2009 ivltests +sv_class_compat2 CE,-g2009 ivltests sv_class_constructor1 CE,-g2009 ivltests sv_class_empty_item CE,-g2009 ivltests sv_class_extends_scoped CE,-g2009 ivltests diff --git a/netclass.cc b/netclass.cc index 3365a8949..99ad5d68a 100644 --- a/netclass.cc +++ b/netclass.cc @@ -195,3 +195,14 @@ const NetExpr* netclass_t::get_parameter(Design *des, perm_string name, { return class_scope_->get_parameter(des, name, par_type); } + +bool netclass_t::test_compatibility(ivl_type_t that) const +{ + for (const netclass_t *class_type = dynamic_cast(that); + class_type; class_type = class_type->get_super()) { + if (class_type == this) + return true; + } + + return false; +} diff --git a/netclass.h b/netclass.h index 0c598fe32..a34487e9b 100644 --- a/netclass.h +++ b/netclass.h @@ -119,6 +119,9 @@ class netclass_t : public ivl_type_s { void set_virtual(bool virtual_class) { virtual_class_ = virtual_class; } bool is_virtual() const { return virtual_class_; } + protected: + bool test_compatibility(ivl_type_t that) const; + private: perm_string name_; // If this is derived from another base class, point to it