Time literals need to be rounded using the time precision

This commit is contained in:
Cary R 2021-02-13 01:10:38 -08:00
parent 5530fbac9f
commit 7bb8a4463f
3 changed files with 20 additions and 4 deletions

16
parse.y
View File

@ -3195,7 +3195,7 @@ delay_value_simple
: DEC_NUMBER : DEC_NUMBER
{ verinum*tmp = $1; { verinum*tmp = $1;
if (tmp == 0) { if (tmp == 0) {
yyerror(@1, "internal error: delay."); yyerror(@1, "internal error: decimal delay.");
$$ = 0; $$ = 0;
} else { } else {
$$ = new PENumber(tmp); $$ = new PENumber(tmp);
@ -3206,7 +3206,7 @@ delay_value_simple
| REALTIME | REALTIME
{ verireal*tmp = $1; { verireal*tmp = $1;
if (tmp == 0) { if (tmp == 0) {
yyerror(@1, "internal error: delay."); yyerror(@1, "internal error: real time delay.");
$$ = 0; $$ = 0;
} else { } else {
$$ = new PEFNumber(tmp); $$ = new PEFNumber(tmp);
@ -3225,7 +3225,7 @@ delay_value_simple
based_size = 0; based_size = 0;
$$ = 0; $$ = 0;
if ($1 == 0 || !get_time_unit($1, unit)) if ($1 == 0 || !get_time_unit($1, unit))
yyerror(@1, "internal error: delay."); yyerror(@1, "internal error: time literal delay.");
else { else {
double p = pow(10.0, double p = pow(10.0,
(double)(unit - pform_get_timeunit())); (double)(unit - pform_get_timeunit()));
@ -3832,10 +3832,18 @@ expr_primary
based_size = 0; based_size = 0;
$$ = 0; $$ = 0;
if ($1 == 0 || !get_time_unit($1, unit)) if ($1 == 0 || !get_time_unit($1, unit))
yyerror(@1, "internal error: delay."); yyerror(@1, "internal error: time literal.");
else { else {
double p = pow(10.0, (double)(unit - pform_get_timeunit())); double p = pow(10.0, (double)(unit - pform_get_timeunit()));
double time = atof($1) * p; double time = atof($1) * p;
// The time value needs to be rounded at the correct digit
// since this is a normal real value and not a delay that
// will be rounded later. This style of rounding is not safe
// for all real values!
int rdigit = pform_get_timeunit() - pform_get_timeprec();
assert(rdigit >= 0);
double scale = pow(10.0, (double)rdigit);
time = round(time*scale)/scale;
verireal *v = new verireal(time); verireal *v = new verireal(time);
$$ = new PEFNumber(v); $$ = new PEFNumber(v);

View File

@ -1213,6 +1213,13 @@ int pform_get_timeunit()
return scopex->time_unit; return scopex->time_unit;
} }
int pform_get_timeprec()
{
PScopeExtra*scopex = find_nearest_scopex(lexical_scope);
assert(scopex);
return scopex->time_precision;
}
void pform_set_timeprec(const char*txt, bool initial_decl) void pform_set_timeprec(const char*txt, bool initial_decl)
{ {
int val; int val;

View File

@ -594,6 +594,7 @@ extern void parm_to_defparam_list(const string&param);
*/ */
extern bool get_time_unit(const char*cp, int &unit); extern bool get_time_unit(const char*cp, int &unit);
extern int pform_get_timeunit(); extern int pform_get_timeunit();
extern int pform_get_timeprec();
extern void pform_set_timeunit(const char*txt, bool initial_decl); extern void pform_set_timeunit(const char*txt, bool initial_decl);
extern void pform_set_timeprec(const char*txt, bool initial_decl); extern void pform_set_timeprec(const char*txt, bool initial_decl);
/* /*