Merge pull request #658 from larsclausen/class-in-module
Handle multiple instances of modules with class definitions
This commit is contained in:
commit
658d4f5eee
|
|
@ -496,29 +496,30 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||||
<< endl;
|
<< 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;
|
const netclass_t*use_base_class = 0;
|
||||||
if (base_class) {
|
if (use_type->base_type) {
|
||||||
use_base_class = base_class->save_elaborated_type;
|
ivl_type_t base_type = use_type->base_type->elaborate_type(des, scope);
|
||||||
if (use_base_class == 0) {
|
use_base_class = dynamic_cast<const netclass_t *>(base_type);
|
||||||
|
if (!use_base_class) {
|
||||||
cerr << pclass->get_fileline() << ": error: "
|
cerr << pclass->get_fileline() << ": error: "
|
||||||
<< "Base class " << base_class->name
|
<< "Base type of " << use_type->name
|
||||||
<< " not found." << endl;
|
<< " is not a class." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
netclass_t*use_class = new netclass_t(use_type->name, use_base_class);
|
netclass_t*use_class = new netclass_t(use_type->name, use_base_class);
|
||||||
|
|
||||||
ivl_assert(*pclass, use_type->save_elaborated_type == 0);
|
// If this is a package we need to remember the elaborated type so that
|
||||||
use_type->save_elaborated_type = use_class;
|
// 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 = new NetScope(scope, hname_t(pclass->pscope_name()),
|
||||||
NetScope::CLASS, scope->unit());
|
NetScope::CLASS, scope->unit());
|
||||||
|
|
|
||||||
|
|
@ -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);
|
if (save_elaborated_type)
|
||||||
return save_elaborated_type;
|
return save_elaborated_type;
|
||||||
|
return scope->find_class(des, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -478,6 +478,7 @@ sv_class_empty_item normal,-g2009 ivltests
|
||||||
sv_class_extends_scoped normal,-g2009 ivltests
|
sv_class_extends_scoped normal,-g2009 ivltests
|
||||||
sv_class_localparam normal,-g2009 ivltests
|
sv_class_localparam normal,-g2009 ivltests
|
||||||
sv_class_new_init normal,-g2009 ivltests
|
sv_class_new_init normal,-g2009 ivltests
|
||||||
|
sv_class_in_module_decl normal,-g2009 ivltests
|
||||||
sv_darray1 normal,-g2009 ivltests
|
sv_darray1 normal,-g2009 ivltests
|
||||||
sv_darray2 normal,-g2009 ivltests
|
sv_darray2 normal,-g2009 ivltests
|
||||||
sv_darray3 normal,-g2009 ivltests
|
sv_darray3 normal,-g2009 ivltests
|
||||||
|
|
|
||||||
|
|
@ -376,6 +376,7 @@ sv_class_empty_item CE,-g2009 ivltests
|
||||||
sv_class_extends_scoped CE,-g2009 ivltests
|
sv_class_extends_scoped CE,-g2009 ivltests
|
||||||
sv_class_localparam CE,-g2009 ivltests
|
sv_class_localparam CE,-g2009 ivltests
|
||||||
sv_class_new_init 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_end_label CE,-g2009 ivltests # Also generate
|
||||||
sv_foreach2 CE,-g2009,-pallowsigned=1 ivltests
|
sv_foreach2 CE,-g2009,-pallowsigned=1 ivltests
|
||||||
sv_foreach3 CE,-g2009 ivltests
|
sv_foreach3 CE,-g2009 ivltests
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
netclass_t::netclass_t(perm_string name, netclass_t*sup)
|
netclass_t::netclass_t(perm_string name, const netclass_t*super)
|
||||||
: name_(name), super_(sup), class_scope_(0), definition_scope_(0)
|
: name_(name), super_(super), class_scope_(0), definition_scope_(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ class PExpr;
|
||||||
|
|
||||||
class netclass_t : public ivl_type_s {
|
class netclass_t : public ivl_type_s {
|
||||||
public:
|
public:
|
||||||
netclass_t(perm_string class_name, netclass_t*par);
|
netclass_t(perm_string class_name, const netclass_t*super);
|
||||||
~netclass_t();
|
~netclass_t();
|
||||||
|
|
||||||
// Set the property of the class during elaboration. Set the
|
// Set the property of the class during elaboration. Set the
|
||||||
|
|
@ -120,7 +120,7 @@ class netclass_t : public ivl_type_s {
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
// If this is derived from another base class, point to it
|
// If this is derived from another base class, point to it
|
||||||
// here.
|
// here.
|
||||||
netclass_t*super_;
|
const netclass_t*super_;
|
||||||
// Map property names to property table index.
|
// Map property names to property table index.
|
||||||
std::map<perm_string,size_t> properties_;
|
std::map<perm_string,size_t> properties_;
|
||||||
// Vector of properties.
|
// Vector of properties.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue