diff --git a/parse.y b/parse.y index a48b84ef1..cc9ef27ec 100644 --- a/parse.y +++ b/parse.y @@ -2234,13 +2234,14 @@ tf_port_list /* IEEE1800-2005: A.2.7 */ timeunits_declaration /* IEEE1800-2005: A.1.2 */ : K_timeunit TIME_LITERAL ';' - { pform_set_timeunit($2); } + { pform_set_timeunit($2, allow_timeunit_decl); } | K_timeunit TIME_LITERAL '/' TIME_LITERAL ';' - { pform_set_timeunit($2); - pform_set_timeprecision($4); + { bool initial_decl = allow_timeunit_decl && allow_timeprec_decl; + pform_set_timeunit($2, initial_decl); + pform_set_timeprec($4, initial_decl); } | K_timeprecision TIME_LITERAL ';' - { pform_set_timeprecision($2); } + { pform_set_timeprec($2, allow_timeprec_decl); } ; /* Allow zero, one, or two declarations. The second declaration might diff --git a/pform.cc b/pform.cc index 029e6cb32..c1a08a29a 100644 --- a/pform.cc +++ b/pform.cc @@ -469,7 +469,9 @@ void pform_set_scope_timescale(const struct vlltype&loc) } if (gn_system_verilog() && (scope->time_unit < scope->time_precision)) { - VLerror("error: a timeprecision is missing or is too large!"); + if (scope->time_unit_is_local || scope->time_prec_is_local) { + VLerror("error: a timeprecision is missing or is too large!"); + } } else { assert(scope->time_unit >= scope->time_precision); } @@ -1098,7 +1100,7 @@ static bool get_time_unit_prec(const char*cp, int &res, bool is_unit) return true; } -void pform_set_timeunit(const char*txt) +void pform_set_timeunit(const char*txt, bool initial_decl) { int val; @@ -1107,7 +1109,7 @@ void pform_set_timeunit(const char*txt) PScopeExtra*scope = dynamic_cast(lexical_scope); assert(scope); - if (allow_timeunit_decl) { + if (initial_decl) { scope->time_unit = val; scope->time_unit_is_local = true; scope->time_unit_is_default = false; @@ -1118,9 +1120,6 @@ void pform_set_timeunit(const char*txt) } else if (scope->time_unit != val) { VLerror(yylloc, "error: repeat timeunit does not match the " "initial timeunit for this scope."); - } else { - // This is a redeclaration, so don't allow any new declarations - allow_timeprec_decl = false; } } @@ -1131,7 +1130,7 @@ int pform_get_timeunit() return scopex->time_unit; } -void pform_set_timeprecision(const char*txt) +void pform_set_timeprec(const char*txt, bool initial_decl) { int val; @@ -1140,7 +1139,7 @@ void pform_set_timeprecision(const char*txt) PScopeExtra*scope = dynamic_cast(lexical_scope); assert(scope); - if (allow_timeprec_decl) { + if (initial_decl) { scope->time_precision = val; scope->time_prec_is_local = true; scope->time_prec_is_default = false; @@ -1151,9 +1150,6 @@ void pform_set_timeprecision(const char*txt) } else if (scope->time_precision != val) { VLerror(yylloc, "error: repeat timeprecision does not match the " "initial timeprecision for this scope."); - } else { - // This is a redeclaration, so don't allow any new declarations - allow_timeunit_decl = false; } } diff --git a/pform.h b/pform.h index b53325404..7157f7c75 100644 --- a/pform.h +++ b/pform.h @@ -567,7 +567,12 @@ extern void parm_to_defparam_list(const string¶m); */ extern bool get_time_unit(const char*cp, int &unit); extern int pform_get_timeunit(); -extern void pform_set_timeunit(const char*txt); -extern void pform_set_timeprecision(const char*txt); +extern void pform_set_timeunit(const char*txt, bool initial_decl); +extern void pform_set_timeprec(const char*txt, bool initial_decl); +/* + * Flags to determine whether this is an initial declaration. + */ +extern bool allow_timeunit_decl; +extern bool allow_timeprec_decl; #endif /* IVL_pform_H */