Real variable support for increment/decrement operator

Signed-off-by: Prasad Joshi <prasad@canopusconsultancy.com>
This commit is contained in:
Prasad Joshi 2011-08-21 08:59:41 +05:30 committed by Stephen Williams
parent 5311aeaa19
commit 95d58cbc42
2 changed files with 108 additions and 14 deletions

View File

@ -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 {

View File

@ -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);