diff --git a/parse.y b/parse.y index 769c6d553..6270a5fa2 100644 --- a/parse.y +++ b/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* 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 diff --git a/pform.cc b/pform.cc index c33c49dae..955a0651f 100644 --- a/pform.cc +++ b/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*range, PExpr*expr) + list *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); diff --git a/pform.h b/pform.h index d48f6b784..02a719053 100644 --- a/pform.h +++ b/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*range, - PExpr*expr); + std::list *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,