vhdlpp: Evaluate power (**) and division remainder (REM) operators.

This commit is contained in:
Maciej Suminski 2015-08-26 17:29:13 +02:00
parent a62a095717
commit 0569474d17
2 changed files with 24 additions and 4 deletions

View File

@ -375,6 +375,22 @@ int ExpArithmetic::emit(ostream&out, Entity*ent, ScopeBase*scope)
{
int errors = 0;
if(fun_ == REM) {
// Special case: division remainder, defined in the VHDL standard 1076-2008/9.2.7
// there is no direct counterpart, therefore output the formula to
// compute a remainder: A rem B = A - (A/B) * B;
out << "((";
errors += emit_operand1(out, ent, scope);
out << ")-((";
errors += emit_operand1(out, ent, scope);
out << ")/(";
errors += emit_operand2(out, ent, scope);
out << "))*(";
errors += emit_operand2(out, ent, scope);
out << "))";
return errors;
}
errors += emit_operand1(out, ent, scope);
switch (fun_) {
@ -396,9 +412,8 @@ int ExpArithmetic::emit(ostream&out, Entity*ent, ScopeBase*scope)
case POW:
out << " ** ";
break;
case REM:
out << " /* ?remainder? */ ";
break;
case REM: // should not happen as it is handled above, suppress warnings
ivl_assert(*this, 0);
case xCONCAT:
ivl_assert(*this, 0);
out << " /* ?concat? */ ";

View File

@ -23,6 +23,7 @@
# include "architec.h"
# include <ivl_assert.h>
# include <limits>
# include <cmath>
bool Expression::evaluate(ScopeBase*, int64_t&) const
{
@ -68,9 +69,13 @@ bool ExpArithmetic::evaluate(ScopeBase*scope, int64_t&val) const
val = val1 % val2;
break;
case REM:
if (val2 == 0)
return false;
val = val1 - (val1 / val2) * val2;
return false;
case POW:
return false;
val = (int64_t) pow(val1, val2);
break;
case xCONCAT: // not possible
return false;
}