vhdlpp: Support for time expressions.
This commit is contained in:
parent
4068c172f4
commit
d6ff1946f9
|
|
@ -564,3 +564,25 @@ ExpNew::~ExpNew()
|
|||
{
|
||||
delete size_;
|
||||
}
|
||||
|
||||
ExpTime::ExpTime(uint64_t amount, timeunit_t unit)
|
||||
: amount_(amount), unit_(unit)
|
||||
{
|
||||
}
|
||||
|
||||
double ExpTime::to_fs() const
|
||||
{
|
||||
double val = amount_;
|
||||
|
||||
switch(unit_) {
|
||||
case FS: break;
|
||||
case PS: val *= 1e3; break;
|
||||
case NS: val *= 1e6; break;
|
||||
case US: val *= 1e9; break;
|
||||
case MS: val *= 1e12; break;
|
||||
case S: val *= 1e15; break;
|
||||
default: ivl_assert(*this, false); break;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -838,4 +838,26 @@ class ExpNew : public Expression {
|
|||
Expression*size_;
|
||||
};
|
||||
|
||||
class ExpTime : public Expression {
|
||||
public:
|
||||
typedef enum { FS, PS, NS, US, MS, S } timeunit_t;
|
||||
|
||||
ExpTime(uint64_t amount, timeunit_t unit);
|
||||
|
||||
Expression*clone() const { return new ExpTime(amount_, unit_); }
|
||||
|
||||
int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype);
|
||||
void write_to_stream(std::ostream&) const;
|
||||
int emit(ostream&out, Entity*ent, ScopeBase*scope);
|
||||
bool evaluate(ScopeBase*scope, int64_t&val) const;
|
||||
bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const;
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
|
||||
private:
|
||||
// Returns the time value expressed in femtoseconds
|
||||
double to_fs() const;
|
||||
uint64_t amount_;
|
||||
timeunit_t unit_;
|
||||
};
|
||||
|
||||
#endif /* IVL_expression_H */
|
||||
|
|
|
|||
|
|
@ -112,3 +112,8 @@ void ExpShift::dump(ostream&out, int indent) const
|
|||
dump_operands(out, indent+4);
|
||||
}
|
||||
|
||||
void ExpTime::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "Time ";
|
||||
write_to_stream(out);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1133,3 +1133,10 @@ int ExpUNot::elaborate_expr(Entity*, ScopeBase*, const VType*ltype)
|
|||
set_type(ltype);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ExpTime::elaborate_expr(Entity*, ScopeBase*, const VType*)
|
||||
{
|
||||
set_type(&primitive_INTEGER);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1068,3 +1068,19 @@ int ExpNew::emit(ostream&out, Entity*ent, ScopeBase*scope)
|
|||
out << "]";
|
||||
return errors;
|
||||
}
|
||||
|
||||
int ExpTime::emit(ostream&out, Entity*, ScopeBase*)
|
||||
{
|
||||
out << amount_;
|
||||
|
||||
switch(unit_) {
|
||||
case FS: out << "fs"; break;
|
||||
case PS: out << "ps"; break;
|
||||
case NS: out << "ns"; break;
|
||||
case US: out << "us"; break;
|
||||
case MS: out << "ms"; break;
|
||||
case S: out << "s"; break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
# include "expression.h"
|
||||
# include "architec.h"
|
||||
# include <ivl_assert.h>
|
||||
# include <limits>
|
||||
|
||||
bool Expression::evaluate(ScopeBase*, int64_t&) const
|
||||
{
|
||||
|
|
@ -245,3 +246,22 @@ bool ExpShift::evaluate(ScopeBase*scope, int64_t&val) const
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExpTime::evaluate(ScopeBase*, int64_t&val) const
|
||||
{
|
||||
double v = to_fs();
|
||||
|
||||
if(v > std::numeric_limits<int64_t>::max()) {
|
||||
val = std::numeric_limits<int64_t>::max();
|
||||
cerr << get_fileline() << ": sorry: Time value is higher than the "
|
||||
<< "handled limit, reduced to " << val << " fs." << endl;
|
||||
}
|
||||
|
||||
val = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExpTime::evaluate(Entity*, ScopeBase*, int64_t&val) const
|
||||
{
|
||||
return evaluate(NULL, NULL, val);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -297,3 +297,17 @@ void ExpCast::write_to_stream(ostream&fd) const
|
|||
// SystemVerilog, so no need to use it here
|
||||
base_->write_to_stream(fd);
|
||||
}
|
||||
|
||||
void ExpTime::write_to_stream(ostream&fd) const
|
||||
{
|
||||
fd << amount_;
|
||||
|
||||
switch(unit_) {
|
||||
case FS: fd << " fs"; break;
|
||||
case PS: fd << " ps"; break;
|
||||
case NS: fd << " ns"; break;
|
||||
case US: fd << " us"; break;
|
||||
case MS: fd << " ms"; break;
|
||||
case S: fd << " s"; break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ exponent [eE][-+]?{integer}
|
|||
|
||||
based_literal {integer}#{based_integer}(\.{based_integer})?#{exponent}?
|
||||
based_integer [0-9a-fA-F](_?[0-9a-fA-F])*
|
||||
time {integer}{W}*([fFpPnNuUmM]?[sS])
|
||||
%%
|
||||
|
||||
[ \t\b\f\r] { ; }
|
||||
|
|
|
|||
|
|
@ -391,6 +391,7 @@ const VTypePrimitive primitive_NATURAL(VTypePrimitive::NATURAL);
|
|||
const VTypePrimitive primitive_REAL(VTypePrimitive::REAL);
|
||||
const VTypePrimitive primitive_STDLOGIC(VTypePrimitive::STDLOGIC, true);
|
||||
const VTypePrimitive primitive_CHARACTER(VTypePrimitive::CHARACTER);
|
||||
const VTypePrimitive primitive_TIME(VTypePrimitive::TIME);
|
||||
|
||||
static const VTypeArray primitive_BIT_VECTOR(&primitive_BIT, vector<VTypeArray::range_t> (1));
|
||||
static const VTypeArray primitive_BOOL_VECTOR(&primitive_BOOLEAN, vector<VTypeArray::range_t> (1));
|
||||
|
|
@ -407,6 +408,7 @@ void generate_global_types(ActiveScope*res)
|
|||
res->use_name(perm_string::literal("bit_vector"),&primitive_BIT_VECTOR);
|
||||
res->use_name(perm_string::literal("string"), &primitive_STRING);
|
||||
res->use_name(perm_string::literal("natural"), &primitive_NATURAL);
|
||||
res->use_name(perm_string::literal("time"), &primitive_TIME);
|
||||
}
|
||||
|
||||
void emit_std_types(ostream&out)
|
||||
|
|
@ -431,6 +433,7 @@ bool is_global_type(perm_string name)
|
|||
if (name == "natural") return true;
|
||||
if (name == "signed") return true;
|
||||
if (name == "unsigned") return true;
|
||||
if (name == "time") return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1835,6 +1835,32 @@ primary
|
|||
delete[]$1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| INT_LITERAL IDENTIFIER
|
||||
{ ExpTime::timeunit_t unit = ExpTime::FS;
|
||||
|
||||
if(!strcasecmp($2, "us"))
|
||||
unit = ExpTime::US;
|
||||
else if(!strcasecmp($2, "ms"))
|
||||
unit = ExpTime::MS;
|
||||
else if(!strcasecmp($2, "ns"))
|
||||
unit = ExpTime::NS;
|
||||
else if(!strcasecmp($2, "s"))
|
||||
unit = ExpTime::S;
|
||||
else if(!strcasecmp($2, "ps"))
|
||||
unit = ExpTime::PS;
|
||||
else if(!strcasecmp($2, "fs"))
|
||||
unit = ExpTime::FS;
|
||||
else
|
||||
errormsg(@2, "Invalid time unit (accepted are fs, ps, ns, us, ms, s).");
|
||||
|
||||
if($1 < 0)
|
||||
errormsg(@1, "Time cannot be negative.");
|
||||
|
||||
ExpTime*tmp = new ExpTime($1, unit);
|
||||
FILE_NAME(tmp, @1);
|
||||
delete[] $2;
|
||||
$$ = tmp;
|
||||
}
|
||||
|
||||
/*XXXX Caught up in element_association_list?
|
||||
| '(' expression ')'
|
||||
|
|
|
|||
|
|
@ -76,6 +76,9 @@ void VTypePrimitive::show(ostream&out) const
|
|||
case STDLOGIC:
|
||||
out << "STD_LOGIC";
|
||||
break;
|
||||
case TIME:
|
||||
out << "TIME";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ class VTypeERROR : public VType {
|
|||
class VTypePrimitive : public VType {
|
||||
|
||||
public:
|
||||
enum type_t { BOOLEAN, BIT, INTEGER, NATURAL, REAL, STDLOGIC, CHARACTER };
|
||||
enum type_t { BOOLEAN, BIT, INTEGER, NATURAL, REAL, STDLOGIC, CHARACTER, TIME };
|
||||
|
||||
public:
|
||||
VTypePrimitive(type_t tt, bool packed = false);
|
||||
|
|
@ -187,6 +187,7 @@ extern const VTypePrimitive primitive_NATURAL;
|
|||
extern const VTypePrimitive primitive_REAL;
|
||||
extern const VTypePrimitive primitive_STDLOGIC;
|
||||
extern const VTypePrimitive primitive_CHARACTER;
|
||||
extern const VTypePrimitive primitive_TIME;
|
||||
|
||||
/*
|
||||
* An array is a compound N-dimensional array of element type. The
|
||||
|
|
|
|||
|
|
@ -169,6 +169,9 @@ int VTypePrimitive::emit_primitive_type(ostream&out) const
|
|||
case CHARACTER:
|
||||
out << "char";
|
||||
break;
|
||||
case TIME:
|
||||
out << "time";
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -168,6 +168,9 @@ void VTypePrimitive::write_to_stream(ostream&fd) const
|
|||
case BOOLEAN:
|
||||
fd << "boolean";
|
||||
break;
|
||||
case TIME:
|
||||
fd << "time";
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
fd << "/* PRIMITIVE: " << type_ << " */";
|
||||
|
|
|
|||
Loading…
Reference in New Issue