Real variable support for increment/decrement operator
Signed-off-by: Prasad Joshi <prasad@canopusconsultancy.com>
This commit is contained in:
parent
5311aeaa19
commit
95d58cbc42
29
elab_expr.cc
29
elab_expr.cc
|
|
@ -3634,20 +3634,15 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
|
|||
<< "vector slice." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
} else if (t == IVL_VT_REAL) {
|
||||
/*
|
||||
* TODO: Need to modify draw_unary_real() to support
|
||||
* operations on real variables
|
||||
*/
|
||||
cerr << get_fileline() << ": sorry: "
|
||||
<< human_readable_op(op_, true)
|
||||
<< " operation is not yet supported on "
|
||||
<< "reals." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
} else if (t == IVL_VT_LOGIC || t == IVL_VT_BOOL) {
|
||||
if (dynamic_cast<NetEConst *> (ip)) {
|
||||
/* invalid operand: operand is a constant number */
|
||||
} else if (t == IVL_VT_LOGIC || t == IVL_VT_BOOL ||
|
||||
t == IVL_VT_REAL) {
|
||||
|
||||
if (dynamic_cast<NetEConst *> (ip) ||
|
||||
dynamic_cast<NetECReal*> (ip)) {
|
||||
/*
|
||||
* invalid operand: operand is a constant
|
||||
* or real number
|
||||
*/
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "inappropriate use of "
|
||||
<< human_readable_op(op_, true)
|
||||
|
|
@ -3656,6 +3651,12 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* **** Valid use of operator ***
|
||||
* For REAL variables draw_unary_real() is ivoked during
|
||||
* evaluation and for LOGIC/BOOLEAN draw_unary_expr()
|
||||
* is called for evaluation.
|
||||
*/
|
||||
tmp = new NetEUnary(op_, ip, expr_wid, signed_flag_);
|
||||
tmp->set_line(*this);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
# include <stdlib.h>
|
||||
# include <math.h>
|
||||
# include <assert.h>
|
||||
# include <stdbool.h>
|
||||
|
||||
static unsigned long word_alloc_mask = 0x0f;
|
||||
|
||||
|
|
@ -442,6 +443,84 @@ static int draw_ternary_real(ivl_expr_t expr)
|
|||
return res;
|
||||
}
|
||||
|
||||
static int increment(ivl_expr_t e, int s, bool pre)
|
||||
{
|
||||
ivl_signal_t sig;
|
||||
int r;
|
||||
int one;
|
||||
|
||||
sig = ivl_expr_signal(e);
|
||||
r = s;
|
||||
|
||||
/* create a temporary word to hold value 1.0 */
|
||||
one = allocate_word();
|
||||
fprintf(vvp_out, " %%loadi/wr %d, 1, 0x1000; load 1.0\n", one);
|
||||
|
||||
if (!pre) {
|
||||
/*
|
||||
* post-increment must return the non-incremented value.
|
||||
* Therefore, copy the current value in a new word and return
|
||||
* it.
|
||||
*/
|
||||
r = allocate_word();
|
||||
fprintf(vvp_out, " %%mov/wr %d, %d;\n", r, s);
|
||||
}
|
||||
|
||||
fprintf(vvp_out, " %%add/wr %d, %d;\n", s, one);
|
||||
fprintf(vvp_out, " %%set/wr v%p_0, %d;\n", sig, s);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline int pre_increment(ivl_expr_t e, int s)
|
||||
{
|
||||
return increment(e, s, true);
|
||||
}
|
||||
|
||||
static inline int post_increment(ivl_expr_t e, int s)
|
||||
{
|
||||
return increment(e, s, false);
|
||||
}
|
||||
|
||||
static int decrement(ivl_expr_t e, int s, bool pre)
|
||||
{
|
||||
ivl_signal_t sig;
|
||||
int r;
|
||||
int one;
|
||||
|
||||
sig = ivl_expr_signal(e);
|
||||
r = s;
|
||||
|
||||
/* create a temporary word to hold value 1.0 */
|
||||
one = allocate_word();
|
||||
fprintf(vvp_out, " %%loadi/wr %d, 1, 0x1000; load 1.0\n", one);
|
||||
|
||||
if (!pre) {
|
||||
/*
|
||||
* post-decrement must return the non-incremented value.
|
||||
* Therefore, copy the current value in a new word and return
|
||||
* it.
|
||||
*/
|
||||
r = allocate_word();
|
||||
fprintf(vvp_out, " %%mov/wr %d, %d;\n", r, s);
|
||||
}
|
||||
|
||||
fprintf(vvp_out, " %%sub/wr %d, %d;\n", s, one);
|
||||
fprintf(vvp_out, " %%set/wr v%p_0, %d;\n", sig, s);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline int pre_decrement(ivl_expr_t e, int s)
|
||||
{
|
||||
return decrement(e, s, true);
|
||||
}
|
||||
|
||||
static inline int post_decrement(ivl_expr_t e, int s)
|
||||
{
|
||||
return decrement(e, s, false);
|
||||
}
|
||||
|
||||
static int draw_unary_real(ivl_expr_t expr)
|
||||
{
|
||||
ivl_expr_t sube;
|
||||
|
|
@ -494,6 +573,20 @@ static int draw_unary_real(ivl_expr_t expr)
|
|||
assert(0);
|
||||
}
|
||||
|
||||
switch (ivl_expr_opcode(expr)) {
|
||||
case 'I':
|
||||
return pre_increment(sube, sub);
|
||||
|
||||
case 'i':
|
||||
return post_increment(sube, sub);
|
||||
|
||||
case 'D':
|
||||
return pre_decrement(sube, sub);
|
||||
|
||||
case 'd':
|
||||
return post_decrement(sube, sub);
|
||||
}
|
||||
|
||||
fprintf(stderr, "vvp.tgt error: unhandled real unary operator: %c.\n",
|
||||
ivl_expr_opcode(expr));
|
||||
assert(0);
|
||||
|
|
|
|||
Loading…
Reference in New Issue