Add logical support for real values and error for invalid real arguments.
This patch adds logical support for real values (!, && and ||). It also prints an appropriate error message when a real value is incorrectly given to an operator that does not allow real arguments (bit-wise, reduction, shift and repeat/concatenation).
This commit is contained in:
parent
c2d1038c29
commit
93ad8ff95f
75
elab_expr.cc
75
elab_expr.cc
|
|
@ -408,6 +408,14 @@ NetExpr* PEBinary::elaborate_expr_base_bits_(Design*des,
|
|||
NetExpr*lp, NetExpr*rp,
|
||||
int expr_wid) const
|
||||
{
|
||||
if (lp->expr_type() == IVL_VT_REAL || rp->expr_type() == IVL_VT_REAL) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< human_readable_op(op_)
|
||||
<< " operator may not have REAL operands." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If either of the arguments is unsigned, then process both
|
||||
// of them as unsigned. This only impacts the padding that is
|
||||
// done to get the operands to the expr_wid.
|
||||
|
|
@ -437,8 +445,8 @@ NetExpr* PEBinary::elaborate_expr_base_div_(Design*des,
|
|||
baseline Verilog. But we allow it in our extended
|
||||
form of Verilog. */
|
||||
if (op_ == '%' && ! gn_icarus_misc_flag) {
|
||||
if (lp->expr_type()==IVL_VT_REAL ||
|
||||
rp->expr_type()==IVL_VT_REAL) {
|
||||
if (lp->expr_type() == IVL_VT_REAL ||
|
||||
rp->expr_type() == IVL_VT_REAL) {
|
||||
cerr << get_fileline() << ": error: Modulus operator "
|
||||
"may not have REAL operands." << endl;
|
||||
des->errors += 1;
|
||||
|
|
@ -465,6 +473,14 @@ NetExpr* PEBinary::elaborate_expr_base_lshift_(Design*des,
|
|||
NetExpr*lp, NetExpr*rp,
|
||||
int expr_wid) const
|
||||
{
|
||||
if (lp->expr_type() == IVL_VT_REAL || rp->expr_type() == IVL_VT_REAL) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< human_readable_op(op_)
|
||||
<< " operator may not have REAL operands." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetExpr*tmp;
|
||||
|
||||
long use_wid = lp->expr_width();
|
||||
|
|
@ -570,6 +586,14 @@ NetExpr* PEBinary::elaborate_expr_base_rshift_(Design*des,
|
|||
NetExpr*lp, NetExpr*rp,
|
||||
int expr_wid) const
|
||||
{
|
||||
if (lp->expr_type() == IVL_VT_REAL || rp->expr_type() == IVL_VT_REAL) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< human_readable_op(op_)
|
||||
<< " operator may not have REAL operands." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetExpr*tmp;
|
||||
|
||||
long use_wid = lp->expr_width();
|
||||
|
|
@ -853,7 +877,8 @@ NetExpr* PEBComp::elaborate_expr(Design*des, NetScope*scope,
|
|||
rp->expr_type() == IVL_VT_REAL) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< human_readable_op(op_)
|
||||
<< "may not have real operands." << endl;
|
||||
<< " operator may not have REAL operands." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1534,6 +1559,14 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
|
|||
if (repeat_) {
|
||||
NetExpr*tmp = elab_and_eval(des, scope, repeat_, -1);
|
||||
assert(tmp);
|
||||
|
||||
if (tmp->expr_type() == IVL_VT_REAL) {
|
||||
cerr << tmp->get_fileline() << ": error: concatenation "
|
||||
<< "repeat expression can not be REAL." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEConst*rep = dynamic_cast<NetEConst*>(tmp);
|
||||
|
||||
if (rep == 0) {
|
||||
|
|
@ -1543,6 +1576,7 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
|
|||
cerr << get_fileline() << ": : The expression is: "
|
||||
<< *tmp << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!rep->value().is_defined()) {
|
||||
|
|
@ -1597,8 +1631,15 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
|
|||
ex->set_line(*parms_[idx]);
|
||||
|
||||
if (! ex->has_width()) {
|
||||
cerr << ex->get_fileline() << ": error: operand of "
|
||||
<< "concatenation has indefinite width: "
|
||||
cerr << ex->get_fileline() << ": error: "
|
||||
<< "concatenation operand has indefinite width: "
|
||||
<< *ex << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if (ex->expr_type() == IVL_VT_REAL) {
|
||||
cerr << ex->get_fileline() << ": error: "
|
||||
<< "concatenation operand can not be REAL: "
|
||||
<< *ex << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
|
@ -3219,7 +3260,7 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
|
|||
constant value. */
|
||||
verireal val = - ipr->value();
|
||||
tmp = new NetECReal(val);
|
||||
tmp->set_line( *ip );
|
||||
tmp->set_line(*this);
|
||||
delete ip;
|
||||
|
||||
} else {
|
||||
|
|
@ -3262,12 +3303,25 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
|
|||
else
|
||||
res = verinum::V1;
|
||||
|
||||
verinum vres (res, 1, true);
|
||||
tmp = new NetEConst(vres);
|
||||
tmp->set_line(*this);
|
||||
delete ip;
|
||||
} else if (NetECReal*ipr = dynamic_cast<NetECReal*>(ip)) {
|
||||
verinum::V res;
|
||||
if (ipr->value().as_double() == 0.0) res = verinum::V1;
|
||||
else res = verinum::V0;
|
||||
verinum vres (res, 1, true);
|
||||
tmp = new NetEConst(vres);
|
||||
tmp->set_line(*this);
|
||||
delete ip;
|
||||
} else {
|
||||
tmp = new NetEUReduce(op_, ip);
|
||||
if (ip->expr_type() == IVL_VT_REAL) {
|
||||
tmp = new NetEBComp('e', ip,
|
||||
new NetECReal(verireal(0.0)));
|
||||
} else {
|
||||
tmp = new NetEUReduce(op_, ip);
|
||||
}
|
||||
tmp->set_line(*this);
|
||||
}
|
||||
break;
|
||||
|
|
@ -3278,6 +3332,13 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
|
|||
case 'A': // Reduction NAND (~&)
|
||||
case 'N': // Reduction NOR (~|)
|
||||
case 'X': // Reduction NXOR (~^)
|
||||
if (ip->expr_type() == IVL_VT_REAL) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< human_readable_op(op_, true)
|
||||
<< " operator may not have a REAL operand." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
tmp = new NetEUReduce(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
break;
|
||||
|
|
|
|||
27
netmisc.cc
27
netmisc.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -233,6 +233,24 @@ NetNet* make_const_x(Design*des, NetScope*scope, unsigned long wid)
|
|||
|
||||
NetExpr* condition_reduce(NetExpr*expr)
|
||||
{
|
||||
if (expr->expr_type() == IVL_VT_REAL) {
|
||||
if (NetECReal *tmp = dynamic_cast<NetECReal*>(expr)) {
|
||||
verinum::V res;
|
||||
if (tmp->value().as_double() == 0.0) res = verinum::V0;
|
||||
else res = verinum::V1;
|
||||
verinum vres (res, 1, true);
|
||||
NetExpr *rtn = new NetEConst(vres);
|
||||
rtn->set_line(*expr);
|
||||
delete expr;
|
||||
return rtn;
|
||||
}
|
||||
|
||||
NetExpr *rtn = new NetEBComp('n', expr,
|
||||
new NetECReal(verireal(0.0)));
|
||||
rtn->set_line(*expr);
|
||||
return rtn;
|
||||
}
|
||||
|
||||
if (expr->expr_width() == 1)
|
||||
return expr;
|
||||
|
||||
|
|
@ -388,7 +406,7 @@ std::list<hname_t> eval_scope_path(Design*des, NetScope*scope,
|
|||
/*
|
||||
* Human readable version of op. Used in elaboration error messages.
|
||||
*/
|
||||
const char *human_readable_op(const char op)
|
||||
const char *human_readable_op(const char op, bool unary)
|
||||
{
|
||||
const char *type;
|
||||
switch (op) {
|
||||
|
|
@ -418,7 +436,10 @@ const char *human_readable_op(const char op)
|
|||
case 'e': type = "=="; break;
|
||||
case 'n': type = "!="; break;
|
||||
case 'E': type = "==="; break; // Case equality
|
||||
case 'N': type = "!=="; break; // Case inequality
|
||||
case 'N':
|
||||
if (unary) type = "~|"; // NOR
|
||||
else type = "!=="; // Case inequality
|
||||
break;
|
||||
|
||||
case 'l': type = "<<(<)"; break; // Left shifts
|
||||
case 'r': type = ">>"; break; // Logical right shift
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __netmisc_H
|
||||
#define __netmisc_H
|
||||
/*
|
||||
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -210,7 +210,7 @@ extern bool type_is_vectorable(ivl_variable_type_t type);
|
|||
/*
|
||||
* Return a human readable version of the operator.
|
||||
*/
|
||||
const char *human_readable_op(const char op);
|
||||
const char *human_readable_op(const char op, bool unary = false);
|
||||
|
||||
/*
|
||||
* Is the expression a constant value and if so what is its logical
|
||||
|
|
|
|||
Loading…
Reference in New Issue