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;
|
||||
}
|
||||
|
||||
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());
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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_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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue