Add support for SystemVerilog style time literals
SystemVerilog has support for time literals. The time literal for example #10ns, adds a delay of 10ns no matter the time unit currently in effect. For more details please refer to http://iverilog.wikia.com/wiki/Projects#SystemVerilog_Style_Time_Literals Tested-by: Oswaldo Cadenas <oswaldo.cadenas@gmail.com> Signed-off-by: Prasad Joshi <prasadjoshi124@gmail.com>
This commit is contained in:
parent
537b8cba34
commit
2cb9a2360c
17
parse.y
17
parse.y
|
|
@ -975,6 +975,23 @@ delay_value_simple
|
|||
$$ = tmp;
|
||||
delete[]$1;
|
||||
}
|
||||
| TIME_LITERAL
|
||||
{
|
||||
int unit;
|
||||
|
||||
based_size = 0;
|
||||
$$ = 0;
|
||||
if ($1 == 0 || !get_time_unit($1, unit))
|
||||
yyerror(@1, "internal error: delay.");
|
||||
else {
|
||||
double p = pow(10, unit - pform_get_timeunit());
|
||||
double time = atof($1) * p;
|
||||
|
||||
verireal *v = new verireal(time);
|
||||
$$ = new PEFNumber(v);
|
||||
FILE_NAME($$, @1);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
description
|
||||
|
|
|
|||
43
pform.cc
43
pform.cc
|
|
@ -502,6 +502,44 @@ void pform_set_timescale(int unit, int prec,
|
|||
}
|
||||
}
|
||||
|
||||
bool get_time_unit(const char*cp, int &unit)
|
||||
{
|
||||
const char *c;
|
||||
bool rc = true;
|
||||
|
||||
if (strchr(cp, '_')) {
|
||||
VLerror(yylloc, "Invalid timeunit constant ('_' is not "
|
||||
"supported).");
|
||||
return false;
|
||||
}
|
||||
|
||||
c = strpbrk(cp, "munpfs");
|
||||
if (!c)
|
||||
return false;
|
||||
|
||||
if (*c == 's')
|
||||
unit = 0;
|
||||
else if (!strncmp(c, "ms", 2))
|
||||
unit = -3;
|
||||
else if (!strncmp(c, "us", 2))
|
||||
unit = -6;
|
||||
else if (!strncmp(c, "ns", 2))
|
||||
unit = -9;
|
||||
else if (!strncmp(c, "ps", 2))
|
||||
unit = -12;
|
||||
else if (!strncmp(c, "fs", 2))
|
||||
unit = -15;
|
||||
else {
|
||||
rc = false;
|
||||
|
||||
ostringstream msg;
|
||||
msg << "Invalid timeunit scale '" << cp << "'.";
|
||||
VLerror(msg.str().c_str());
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a timeunit or timeprecision value from a string. This is
|
||||
* similar to the code in lexor.lex for the `timescale directive.
|
||||
|
|
@ -611,6 +649,11 @@ void pform_set_timeunit(const char*txt, bool in_module, bool only_check)
|
|||
}
|
||||
}
|
||||
|
||||
int pform_get_timeunit()
|
||||
{
|
||||
return pform_cur_module->time_unit;
|
||||
}
|
||||
|
||||
void pform_set_timeprecision(const char*txt, bool in_module, bool only_check)
|
||||
{
|
||||
int val;
|
||||
|
|
|
|||
2
pform.h
2
pform.h
|
|
@ -434,6 +434,8 @@ extern void parm_to_defparam_list(const string¶m);
|
|||
/*
|
||||
* Tasks to set the timeunit or timeprecision for SystemVerilog.
|
||||
*/
|
||||
extern bool get_time_unit(const char*cp, int &unit);
|
||||
extern int pform_get_timeunit();
|
||||
extern void pform_set_timeunit(const char*txt, bool in_module, bool only_check);
|
||||
extern void pform_set_timeprecision(const char*txt, bool in_module,
|
||||
bool only_check);
|
||||
|
|
|
|||
Loading…
Reference in New Issue