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
|
: 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);
|
||||||
|
|
|
||||||
7
pform.cc
7
pform.cc
|
|
@ -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;
|
||||||
|
|
|
||||||
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 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);
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue