Time literals need to be rounded using the time precision
This commit is contained in:
parent
5530fbac9f
commit
7bb8a4463f
16
parse.y
16
parse.y
|
|
@ -3195,7 +3195,7 @@ delay_value_simple
|
|||
: DEC_NUMBER
|
||||
{ verinum*tmp = $1;
|
||||
if (tmp == 0) {
|
||||
yyerror(@1, "internal error: delay.");
|
||||
yyerror(@1, "internal error: decimal delay.");
|
||||
$$ = 0;
|
||||
} else {
|
||||
$$ = new PENumber(tmp);
|
||||
|
|
@ -3206,7 +3206,7 @@ delay_value_simple
|
|||
| REALTIME
|
||||
{ verireal*tmp = $1;
|
||||
if (tmp == 0) {
|
||||
yyerror(@1, "internal error: delay.");
|
||||
yyerror(@1, "internal error: real time delay.");
|
||||
$$ = 0;
|
||||
} else {
|
||||
$$ = new PEFNumber(tmp);
|
||||
|
|
@ -3225,7 +3225,7 @@ delay_value_simple
|
|||
based_size = 0;
|
||||
$$ = 0;
|
||||
if ($1 == 0 || !get_time_unit($1, unit))
|
||||
yyerror(@1, "internal error: delay.");
|
||||
yyerror(@1, "internal error: time literal delay.");
|
||||
else {
|
||||
double p = pow(10.0,
|
||||
(double)(unit - pform_get_timeunit()));
|
||||
|
|
@ -3832,10 +3832,18 @@ expr_primary
|
|||
based_size = 0;
|
||||
$$ = 0;
|
||||
if ($1 == 0 || !get_time_unit($1, unit))
|
||||
yyerror(@1, "internal error: delay.");
|
||||
yyerror(@1, "internal error: time literal.");
|
||||
else {
|
||||
double p = pow(10.0, (double)(unit - pform_get_timeunit()));
|
||||
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);
|
||||
$$ = new PEFNumber(v);
|
||||
|
|
|
|||
7
pform.cc
7
pform.cc
|
|
@ -1213,6 +1213,13 @@ int pform_get_timeunit()
|
|||
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)
|
||||
{
|
||||
int val;
|
||||
|
|
|
|||
1
pform.h
1
pform.h
|
|
@ -594,6 +594,7 @@ 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 int pform_get_timeprec();
|
||||
extern void pform_set_timeunit(const char*txt, bool initial_decl);
|
||||
extern void pform_set_timeprec(const char*txt, bool initial_decl);
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue