From 9f5ad34e358442f3dccf60f3f4dadb6b54dc090b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 10 Feb 2022 10:13:22 +0100 Subject: [PATCH] Track whether a parameter is overridable Parameters declared in certain scopes behave like local parameters and can not be overridden. Rather than making those parameters a localparam track whether a parameter can be overridden. This allows to generate better error messages when trying to override the parameter. Signed-off-by: Lars-Peter Clausen --- PScope.h | 4 +++- elab_scope.cc | 2 +- net_scope.cc | 12 +++++++++++- netlist.h | 4 +++- pform.cc | 6 +++++- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/PScope.h b/PScope.h index 05117ac9b..037974860 100644 --- a/PScope.h +++ b/PScope.h @@ -101,7 +101,7 @@ class LexicalScope { this map. */ struct param_expr_t : public PNamedItem { inline param_expr_t() : data_type(0), expr(0), range(0), - local_flag(false) { } + local_flag(false), overridable(true) { } // Type information. data_type_t*data_type; // Value expression @@ -110,6 +110,8 @@ class LexicalScope { range_t*range; // Whether it is a local parameter bool local_flag; + // Whether the parameter can be overridden + bool overridable; SymbolType symbol_type() const; }; diff --git a/elab_scope.cc b/elab_scope.cc index 66128fa12..183321043 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -126,7 +126,7 @@ static void collect_parm_item(Design*des, NetScope*scope, perm_string name, // don't try to elaborate it here, because there may be references to // other parameters still being located during scope elaboration. scope->set_parameter(name, is_annotatable, cur.expr, cur.data_type, - cur.local_flag, range_list, cur); + cur.local_flag, cur.overridable, range_list, cur); } diff --git a/net_scope.cc b/net_scope.cc index 5abdf0b77..61ca017d4 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -305,7 +305,7 @@ const netenum_t*NetScope::find_enumeration_for_name(const Design*des, perm_strin */ void NetScope::set_parameter(perm_string key, bool is_annotatable, PExpr*val, data_type_t*val_type, - bool local_flag, + bool local_flag, bool overridable, NetScope::range_t*range_list, const LineInfo&file_line) { @@ -315,6 +315,7 @@ void NetScope::set_parameter(perm_string key, bool is_annotatable, ref.val_type = val_type; ref.val_scope = this; ref.local_flag = local_flag; + ref.overridable = overridable; ivl_assert(file_line, ref.range == 0); ref.range = range_list; ref.val = 0; @@ -400,6 +401,15 @@ void NetScope::replace_parameter(Design *des, perm_string key, PExpr*val, NetSco des->errors++; return; } + if (!ref.overridable) { + cerr << val->get_fileline() << ": error: " + << "Cannot override parameter `" << key << "` in `" + << scope_path(this) << "`. Parameter cannot be overriden " + << "in the scope it has been declared in." + << endl; + des->errors++; + return; + } ref.val_expr = val; ref.val_scope = scope; diff --git a/netlist.h b/netlist.h index a5babeb4e..66268b93e 100644 --- a/netlist.h +++ b/netlist.h @@ -968,7 +968,7 @@ class NetScope : public Definitions, public Attrib { struct range_t; void set_parameter(perm_string name, bool is_annotatable, PExpr*val, data_type_t*data_type, - bool local_flag, + bool local_flag, bool overridable, NetScope::range_t*range_list, const LineInfo&file_line); void set_parameter(perm_string name, NetExpr*val, @@ -1227,6 +1227,8 @@ class NetScope : public Definitions, public Attrib { bool is_annotatable; // Is this a localparam? bool local_flag; + // Can it be overriden? + bool overridable; // range constraints struct range_t*range; // Expression value and type (elaborated versoins of val_expr/val_type) diff --git a/pform.cc b/pform.cc index 6c3fbbde4..3498417c8 100644 --- a/pform.cc +++ b/pform.cc @@ -3232,6 +3232,9 @@ void pform_set_parameter(const struct vlltype&loc, is_local ? "localparam" : "parameter"); return; } + + bool overridable = !is_local; + if (scope == pform_cur_generate && !is_local) { VLerror("parameter declarations are not permitted in generate blocks"); return; @@ -3247,11 +3250,12 @@ void pform_set_parameter(const struct vlltype&loc, parm->data_type = data_type; parm->range = value_range; parm->local_flag = is_local; + parm->overridable = overridable; scope->parameters[name] = parm; // Only a module keeps the position of the parameter. - if (!is_local && + if (overridable && (dynamic_cast(scope)) && (scope == pform_cur_module.front())) pform_cur_module.front()->param_names.push_back(name); }