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 type_restrict_t param_type_restrict;
|
||||||
static bool in_gen_region = false;
|
static bool in_gen_region = false;
|
||||||
static std::list<pform_range_t>* specparam_active_range = 0;
|
static std::list<pform_range_t>* specparam_active_range = 0;
|
||||||
|
static bool in_specify_block = false;
|
||||||
|
|
||||||
/* Port declaration lists use this structure for context. */
|
/* Port declaration lists use this structure for context. */
|
||||||
static struct {
|
static struct {
|
||||||
|
|
@ -5887,12 +5888,15 @@ module_item
|
||||||
yyerror(@1, "error: specify blocks are not allowed "
|
yyerror(@1, "error: specify blocks are not allowed "
|
||||||
"in interfaces.");
|
"in interfaces.");
|
||||||
pform_error_in_generate(@1, "specify block");
|
pform_error_in_generate(@1, "specify block");
|
||||||
|
in_specify_block = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
specify_item_list_opt K_endspecify
|
specify_item_list_opt K_endspecify
|
||||||
|
{ in_specify_block = false; }
|
||||||
|
|
||||||
| K_specify error K_endspecify
|
| K_specify error K_endspecify
|
||||||
{ yyerror(@1, "error: Syntax error in specify block");
|
{ yyerror(@1, "error: Syntax error in specify block");
|
||||||
|
in_specify_block = false;
|
||||||
yyerrok;
|
yyerrok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7005,7 +7009,8 @@ specify_path_identifiers
|
||||||
|
|
||||||
specparam
|
specparam
|
||||||
: identifier_name '=' expr_mintypmax
|
: 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;
|
delete[]$1;
|
||||||
}
|
}
|
||||||
| PATHPULSE_IDENTIFIER '=' expression
|
| 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,
|
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());
|
ivl_assert(loc, !pform_cur_module.empty());
|
||||||
Module*scope = pform_cur_module.front();
|
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->expr = expr;
|
||||||
parm->range = 0;
|
parm->range = 0;
|
||||||
|
|
||||||
|
// Only module-body specparams follow lexical order.
|
||||||
|
if (check_decl_order)
|
||||||
|
parm->lexical_pos = loc.lexical_pos;
|
||||||
|
|
||||||
if (range) {
|
if (range) {
|
||||||
ivl_assert(loc, range->size() == 1);
|
ivl_assert(loc, range->size() == 1);
|
||||||
parm->data_type = new vector_type_t(IVL_VT_LOGIC, false, range);
|
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);
|
PExpr*expr, LexicalScope::range_t*value_range);
|
||||||
extern void pform_set_specparam(const struct vlltype&loc,
|
extern void pform_set_specparam(const struct vlltype&loc,
|
||||||
perm_string name,
|
perm_string name,
|
||||||
std::list<pform_range_t>*range,
|
std::list<pform_range_t> *range,
|
||||||
PExpr*expr);
|
PExpr *expr, bool check_decl_order);
|
||||||
extern void pform_set_defparam(const pform_name_t&name, PExpr*expr);
|
extern void pform_set_defparam(const pform_name_t&name, PExpr*expr);
|
||||||
|
|
||||||
extern void pform_make_let(const struct vlltype&loc,
|
extern void pform_make_let(const struct vlltype&loc,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue