Honor declaration order for module-body specparams
The LRM section 6.20.5 permits `specparam` declarations both in a
module body and in a `specify` block. It states:
A specify parameter declared outside a specify block shall be declared
before it is referenced.
Currently all specparams retain a declaration position of zero, making a
later module-body declaration visible to an earlier expression:
module test;
wire value;
assign value = delay;
specparam delay = 1;
endmodule
Record the source position for module-body specparams. Track when the
parser is inside a `specify` block so the outside-block restriction is
not applied there.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
2556b5f073
commit
dd403e7ea0
7
parse.y
7
parse.y
|
|
@ -48,6 +48,7 @@ static bool param_is_type = false;
|
|||
static type_restrict_t param_type_restrict;
|
||||
static bool in_gen_region = false;
|
||||
static std::list<pform_range_t>* specparam_active_range = 0;
|
||||
static bool in_specify_block = false;
|
||||
|
||||
/* Port declaration lists use this structure for context. */
|
||||
static struct {
|
||||
|
|
@ -5887,12 +5888,15 @@ module_item
|
|||
yyerror(@1, "error: specify blocks are not allowed "
|
||||
"in interfaces.");
|
||||
pform_error_in_generate(@1, "specify block");
|
||||
in_specify_block = true;
|
||||
}
|
||||
|
||||
specify_item_list_opt K_endspecify
|
||||
{ in_specify_block = false; }
|
||||
|
||||
| K_specify error K_endspecify
|
||||
{ yyerror(@1, "error: Syntax error in specify block");
|
||||
in_specify_block = false;
|
||||
yyerrok;
|
||||
}
|
||||
|
||||
|
|
@ -7005,7 +7009,8 @@ specify_path_identifiers
|
|||
|
||||
specparam
|
||||
: identifier_name '=' expr_mintypmax
|
||||
{ pform_set_specparam(@1, lex_strings.make($1), specparam_active_range, $3);
|
||||
{ pform_set_specparam(@1, lex_strings.make($1), specparam_active_range, $3,
|
||||
!in_specify_block);
|
||||
delete[]$1;
|
||||
}
|
||||
| PATHPULSE_IDENTIFIER '=' expression
|
||||
|
|
|
|||
7
pform.cc
7
pform.cc
|
|
@ -3167,7 +3167,8 @@ void pform_set_parameter(const struct vlltype&loc,
|
|||
}
|
||||
|
||||
void pform_set_specparam(const struct vlltype&loc, perm_string name,
|
||||
list<pform_range_t>*range, PExpr*expr)
|
||||
list<pform_range_t> *range, PExpr *expr,
|
||||
bool check_decl_order)
|
||||
{
|
||||
ivl_assert(loc, !pform_cur_module.empty());
|
||||
Module*scope = pform_cur_module.front();
|
||||
|
|
@ -3187,6 +3188,10 @@ void pform_set_specparam(const struct vlltype&loc, perm_string name,
|
|||
parm->expr = expr;
|
||||
parm->range = 0;
|
||||
|
||||
// Only module-body specparams follow lexical order.
|
||||
if (check_decl_order)
|
||||
parm->lexical_pos = loc.lexical_pos;
|
||||
|
||||
if (range) {
|
||||
ivl_assert(loc, range->size() == 1);
|
||||
parm->data_type = new vector_type_t(IVL_VT_LOGIC, false, range);
|
||||
|
|
|
|||
4
pform.h
4
pform.h
|
|
@ -414,8 +414,8 @@ extern void pform_set_parameter(const struct vlltype&loc,
|
|||
PExpr*expr, LexicalScope::range_t*value_range);
|
||||
extern void pform_set_specparam(const struct vlltype&loc,
|
||||
perm_string name,
|
||||
std::list<pform_range_t>*range,
|
||||
PExpr*expr);
|
||||
std::list<pform_range_t> *range,
|
||||
PExpr *expr, bool check_decl_order);
|
||||
extern void pform_set_defparam(const pform_name_t&name, PExpr*expr);
|
||||
|
||||
extern void pform_make_let(const struct vlltype&loc,
|
||||
|
|
|
|||
Loading…
Reference in New Issue