Merge pull request #658 from larsclausen/class-in-module

Handle multiple instances of modules with class definitions
This commit is contained in:
Stephen Williams 2022-03-27 15:48:56 -07:00 committed by GitHub
commit 658d4f5eee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 58 additions and 22 deletions

View File

@ -496,29 +496,30 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
<< endl;
}
class_type_t*base_class = dynamic_cast<class_type_t*> (use_type->base_type);
if (use_type->base_type && !base_class) {
cerr << pclass->get_fileline() << ": error: "
<< "Base type of " << use_type->name
<< " is not a class." << endl;
des->errors += 1;
}
netclass_t*use_base_class = 0;
if (base_class) {
use_base_class = base_class->save_elaborated_type;
if (use_base_class == 0) {
const netclass_t*use_base_class = 0;
if (use_type->base_type) {
ivl_type_t base_type = use_type->base_type->elaborate_type(des, scope);
use_base_class = dynamic_cast<const netclass_t *>(base_type);
if (!use_base_class) {
cerr << pclass->get_fileline() << ": error: "
<< "Base class " << base_class->name
<< " not found." << endl;
<< "Base type of " << use_type->name
<< " is not a class." << endl;
des->errors += 1;
}
}
netclass_t*use_class = new netclass_t(use_type->name, use_base_class);
ivl_assert(*pclass, use_type->save_elaborated_type == 0);
use_type->save_elaborated_type = use_class;
// If this is a package we need to remember the elaborated type so that
// scoped type references work. Since there is only one instance for each
// package this works. For classes defined in modules there might be
// multiple instances though. Each module instance will have its own class
// type instance, so the same does not work there.
if (scope->type() == NetScope::PACKAGE) {
ivl_assert(*pclass, use_type->save_elaborated_type == 0);
use_type->save_elaborated_type = use_class;
}
NetScope*class_scope = new NetScope(scope, hname_t(pclass->pscope_name()),
NetScope::CLASS, scope->unit());

View File

@ -101,10 +101,11 @@ ivl_type_t atom2_type_t::elaborate_type_raw(Design*des, NetScope*) const
}
}
ivl_type_t class_type_t::elaborate_type_raw(Design*, NetScope*) const
ivl_type_t class_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
{
ivl_assert(*this, save_elaborated_type);
return save_elaborated_type;
if (save_elaborated_type)
return save_elaborated_type;
return scope->find_class(des, name);
}
/*

View File

@ -0,0 +1,32 @@
// Check that it is possible to have multiple instances of a module that defines
// a class and that the actual class types can have different implementations
// based on module parameters.
module M #(
parameter X = 0
);
class C;
function int f;
return X;
endfunction
endclass
C c = new;
endmodule
module test;
M #(10) m1();
M #(20) m2();
initial begin
if (m1.c.f() == 10 && m2.c.f() == 20) begin
$display("PASSED");
end else begin
$display("FAILED");
end
end
endmodule

View File

@ -478,6 +478,7 @@ sv_class_empty_item normal,-g2009 ivltests
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_darray1 normal,-g2009 ivltests
sv_darray2 normal,-g2009 ivltests
sv_darray3 normal,-g2009 ivltests

View File

@ -376,6 +376,7 @@ sv_class_empty_item CE,-g2009 ivltests
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_end_label CE,-g2009 ivltests # Also generate
sv_foreach2 CE,-g2009,-pallowsigned=1 ivltests
sv_foreach3 CE,-g2009 ivltests

View File

@ -23,8 +23,8 @@
using namespace std;
netclass_t::netclass_t(perm_string name, netclass_t*sup)
: name_(name), super_(sup), class_scope_(0), definition_scope_(0)
netclass_t::netclass_t(perm_string name, const netclass_t*super)
: name_(name), super_(super), class_scope_(0), definition_scope_(0)
{
}

View File

@ -35,7 +35,7 @@ class PExpr;
class netclass_t : public ivl_type_s {
public:
netclass_t(perm_string class_name, netclass_t*par);
netclass_t(perm_string class_name, const netclass_t*super);
~netclass_t();
// Set the property of the class during elaboration. Set the
@ -120,7 +120,7 @@ class netclass_t : public ivl_type_s {
perm_string name_;
// If this is derived from another base class, point to it
// here.
netclass_t*super_;
const netclass_t*super_;
// Map property names to property table index.
std::map<perm_string,size_t> properties_;
// Vector of properties.