Support classes in generate blocks
SystemVerilog allows class declarations as module and generate items. Currently a class declaration in a generate block triggers an assert because `pform_push_class_scope()` only records classes in `PScopeExtra` scopes. Add class storage to `PGenerate` and elaborate those classes like module and package classes. When registering task, function or class declarations, only use the current `PGenerate` object as the target if it is also the current lexical scope. This distinction matters for generated classes because `pform_cur_generate` remains set while the class body is parsed, but the current lexical scope has changed to the `PClass`. This records the class declaration in the generate block while leaving methods and constructors in the class scope. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
daadc38f18
commit
7934ab9eeb
|
|
@ -26,10 +26,12 @@
|
|||
# include <list>
|
||||
# include <map>
|
||||
# include <valarray>
|
||||
# include <vector>
|
||||
# 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<PGate*> gates;
|
||||
void add_gate(PGate*);
|
||||
|
||||
// Tasks instantiated within this scheme.
|
||||
// Definitions instantiated within this scheme.
|
||||
std::map<perm_string,PTask*> tasks;
|
||||
std::map<perm_string,PFunction*>funcs;
|
||||
std::map<perm_string,PClass*> classes;
|
||||
std::vector<PClass*> classes_lexical;
|
||||
|
||||
// Generate schemes can contain further generate schemes.
|
||||
std::list<PGenerate*> generate_schemes;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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<PGenerate*>::const_iterator generate_it_t;
|
||||
for (generate_it_t cur = generate_schemes.begin()
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
27
pform.cc
27
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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue