Elaborate `parameter` as non-overridable where required

For modules, programs and interfaces that have a parameter port list, a
parameter declared inside the scope's body is supposed to be elaborated as
a local parameter.

TThis is described in the Verilog LRM (1364-2005) section 4.10.1 ("Module
parameters") and the SystemVerilog LRM (1800-2017) section 6.20.1
("Parameter declaration syntax").

Implement this by marking a parameter declared in such a way as
non-overridable.

Note that a parameter declared within a named block, function or task can
still be overridden, even if the module has a parameter port list.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2022-02-05 12:04:55 +01:00
parent 96a1cbf7b2
commit 673b40b78c
2 changed files with 10 additions and 2 deletions

View File

@ -116,6 +116,7 @@ class LexicalScope {
SymbolType symbol_type() const; SymbolType symbol_type() const;
}; };
std::map<perm_string,param_expr_t*>parameters; std::map<perm_string,param_expr_t*>parameters;
bool has_parameter_port_list;
// Defined types in the scope. // Defined types in the scope.
std::map<perm_string,data_type_t*>typedefs; std::map<perm_string,data_type_t*>typedefs;

View File

@ -1384,6 +1384,7 @@ void pform_startmodule(const struct vlltype&loc, const char*name,
void pform_start_parameter_port_list() void pform_start_parameter_port_list()
{ {
pform_in_parameter_port_list = true; pform_in_parameter_port_list = true;
pform_peek_scope()->has_parameter_port_list = true;
} }
void pform_end_parameter_port_list() void pform_end_parameter_port_list()
@ -3264,6 +3265,13 @@ void pform_set_parameter(const struct vlltype&loc,
overridable = false; overridable = false;
} }
bool in_module = dynamic_cast<Module*>(scope) &&
scope == pform_cur_module.front();
if (!pform_in_parameter_port_list && in_module &&
scope->has_parameter_port_list)
overridable = false;
Module::param_expr_t*parm = new Module::param_expr_t(); Module::param_expr_t*parm = new Module::param_expr_t();
FILE_NAME(parm, loc); FILE_NAME(parm, loc);
@ -3278,8 +3286,7 @@ void pform_set_parameter(const struct vlltype&loc,
scope->parameters[name] = parm; scope->parameters[name] = parm;
// Only a module keeps the position of the parameter. // Only a module keeps the position of the parameter.
if (overridable && if (overridable && in_module)
(dynamic_cast<Module*>(scope)) && (scope == pform_cur_module.front()))
pform_cur_module.front()->param_names.push_back(name); pform_cur_module.front()->param_names.push_back(name);
} }