diff --git a/PGenerate.h b/PGenerate.h index d2d293262..24745c7dc 100644 --- a/PGenerate.h +++ b/PGenerate.h @@ -26,10 +26,12 @@ # include # include # include +# include # include "pform_types.h" class Design; class NetScope; +class PClass; class PExpr; class PFunction; class PProcess; @@ -92,9 +94,11 @@ class PGenerate : public PNamedItem, public LexicalScope { std::list gates; void add_gate(PGate*); - // Tasks instantiated within this scheme. + // Definitions instantiated within this scheme. std::map tasks; std::mapfuncs; + std::map classes; + std::vector classes_lexical; // Generate schemes can contain further generate schemes. std::list generate_schemes; diff --git a/elab_scope.cc b/elab_scope.cc index 4b233348d..43d46de3b 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -1324,6 +1324,8 @@ void PGenerate::elaborate_subscope_(Design*des, NetScope*scope) elaborate_scope_enumerations(des, scope, enum_sets); + elaborate_scope_classes(des, scope, classes_lexical); + // Run through the defparams for this scope and save the result // in a table for later final override. diff --git a/elab_sig.cc b/elab_sig.cc index f23145c22..5b752c617 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -607,6 +607,7 @@ bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const elaborate_sig_funcs(des, scope, funcs); elaborate_sig_tasks(des, scope, tasks); + elaborate_sig_classes(des, scope, classes); typedef list::const_iterator generate_it_t; for (generate_it_t cur = generate_schemes.begin() diff --git a/elaborate.cc b/elaborate.cc index ba327a815..e4894fd6e 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -7228,6 +7228,7 @@ bool PGenerate::elaborate_(Design*des, NetScope*scope) const if (result_flag) { elaborate_functions(des, scope, funcs); elaborate_tasks(des, scope, tasks); + elaborate_classes(des, scope, classes); for (const auto gt : gates) gt->elaborate(des, scope); diff --git a/pform.cc b/pform.cc index 59e264326..d9249910c 100644 --- a/pform.cc +++ b/pform.cc @@ -449,6 +449,11 @@ static PScopeExtra* find_nearest_scopex(LexicalScope*scope) return scopex; } +static PGenerate* current_generate_scope() +{ + return lexical_scope == pform_cur_generate ? pform_cur_generate : nullptr; +} + static void add_local_symbol(LexicalScope*scope, perm_string name, PNamedItem*item) { assert(scope); @@ -585,12 +590,16 @@ PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name) PScopeExtra*scopex = find_nearest_scopex(lexical_scope); ivl_assert(loc, scopex); - ivl_assert(loc, !pform_cur_generate); pform_set_scope_timescale(class_scope, scopex); - scopex->classes[name] = class_scope; - scopex->classes_lexical .push_back(class_scope); + if (auto generate_scope = current_generate_scope()) { + generate_scope->classes[name] = class_scope; + generate_scope->classes_lexical.push_back(class_scope); + } else { + scopex->classes[name] = class_scope; + scopex->classes_lexical.push_back(class_scope); + } lexical_scope = class_scope; return class_scope; @@ -632,9 +641,9 @@ PTask* pform_push_task_scope(const struct vlltype&loc, const char*name, pform_set_scope_timescale(task, scopex); - if (pform_cur_generate) { - add_local_symbol(pform_cur_generate, task_name, task); - pform_cur_generate->tasks[task_name] = task; + if (auto generate_scope = current_generate_scope()) { + add_local_symbol(generate_scope, task_name, task); + generate_scope->tasks[task_name] = task; } else { add_local_symbol(scopex, task_name, task); scopex->tasks[task_name] = task; @@ -667,9 +676,9 @@ PFunction* pform_push_function_scope(const struct vlltype&loc, const char*name, pform_set_scope_timescale(func, scopex); - if (pform_cur_generate) { - add_local_symbol(pform_cur_generate, func_name, func); - pform_cur_generate->funcs[func_name] = func; + if (auto generate_scope = current_generate_scope()) { + add_local_symbol(generate_scope, func_name, func); + generate_scope->funcs[func_name] = func; } else { add_local_symbol(scopex, func_name, func);