Elaborate logical and/or to account for special properties.

The arguments of logical and/or are self determined, and the width is
fixed as 1 bit. Account for this special behavior by creating the
PEBLogic class.
This commit is contained in:
Stephen Williams 2008-10-29 20:31:26 -07:00
parent b7d3276e4d
commit ea057a7574
6 changed files with 108 additions and 8 deletions

View File

@ -73,6 +73,16 @@ PEBComp::~PEBComp()
{
}
PEBLogic::PEBLogic(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{
assert(op == 'a' || op == 'o');
}
PEBLogic::~PEBLogic()
{
}
PEBShift::PEBShift(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{

19
PExpr.h
View File

@ -497,6 +497,25 @@ class PEBComp : public PEBinary {
NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
};
/*
* This derived class is for handling logical expressions: && and ||.
*/
class PEBLogic : public PEBinary {
public:
explicit PEBLogic(char op, PExpr*l, PExpr*r);
~PEBLogic();
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&flag);
NetExpr* elaborate_expr(Design*des, NetScope*scope,
int expr_width, bool sys_task_arg) const;
NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
};
class PEBShift : public PEBinary {
public:

View File

@ -294,11 +294,12 @@ NetExpr* PEBinary::elaborate_expr_base_(Design*des,
case 'a':
case 'o':
lp = condition_reduce(lp);
rp = condition_reduce(rp);
tmp = new NetEBLogic(op_, lp, rp);
tmp->set_line(*this);
break;
cerr << get_fileline() << ": internal error: "
<< "Elaboration of " << human_readable_op(op_)
<< " Should have been handled in NetEBLogic::elaborate."
<< endl;
des->errors += 1;
return 0;
case 'p':
tmp = new NetEBPow(op_, lp, rp);
@ -799,6 +800,54 @@ NetExpr* PEBComp::elaborate_expr(Design*des, NetScope*scope,
return tmp;
}
unsigned PEBLogic::test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type_out,
bool&unsized_flag)
{
expr_type_ = IVL_VT_LOGIC;
expr_width_ = 1;
expr_type_out = expr_type_;
return expr_width_;
}
NetExpr*PEBLogic::elaborate_expr(Design*des, NetScope*scope,
int expr_width_dummp, bool sys_task_arg) const
{
assert(left_);
assert(right_);
// The left and right expressions are self-determined and
// independent. Run their test_width methods independently. We
// don't need the widths here, but we do need the expressions
// to calculate their self-determined width and type.
bool left_flag = false;
ivl_variable_type_t left_type = IVL_VT_NO_TYPE;
left_->test_width(des, scope, 0, 0, left_type, left_flag);
bool right_flag = false;
ivl_variable_type_t right_type = IVL_VT_NO_TYPE;
right_->test_width(des, scope, 0, 0, right_type, right_flag);
NetExpr*lp = elab_and_eval(des, scope, left_, -1);
NetExpr*rp = elab_and_eval(des, scope, right_, -1);
if ((lp == 0) || (rp == 0)) {
delete lp;
delete rp;
return 0;
}
lp = condition_reduce(lp);
rp = condition_reduce(rp);
NetEBLogic*tmp = new NetEBLogic(op_, lp, rp);
tmp->set_line(*this);
tmp->set_width(1);
return tmp;
}
unsigned PEBShift::test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type__,

View File

@ -81,6 +81,28 @@ NetExpr*PEBComp::elaborate_pexpr(Design*des, NetScope*scope) const
return tmp;
}
NetExpr*PEBLogic::elaborate_pexpr(Design*des, NetScope*scope) const
{
NetExpr*lp = left_->elaborate_pexpr(des, scope);
NetExpr*rp = right_->elaborate_pexpr(des, scope);
if ((lp == 0) || (rp == 0)) {
delete lp;
delete rp;
return 0;
}
NetEBLogic*tmp = new NetEBLogic(op_, lp, rp);
tmp->set_line(*this);
bool flag = tmp->set_width(1);
if (flag == false) {
cerr << get_fileline() << ": internal error: "
"expression bit width of comparison != 1." << endl;
des->errors += 1;
}
return tmp;
}
/*
* Event though parameters are not generally sized, parameter
* expressions can include concatenation expressions. This requires

View File

@ -3270,7 +3270,7 @@ class NetEBLogic : public NetEBinary {
NetEBLogic(char op, NetExpr*l, NetExpr*r);
~NetEBLogic();
virtual bool set_width(unsigned w, bool last_chance);
virtual bool set_width(unsigned w, bool last_chance =false);
virtual NetEBLogic* dup_expr() const;
virtual NetEConst* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*, NetScope*scope);

View File

@ -1034,12 +1034,12 @@ expression
$$ = tmp;
}
| expression K_LOR expression
{ PEBinary*tmp = new PEBinary('o', $1, $3);
{ PEBinary*tmp = new PEBLogic('o', $1, $3);
FILE_NAME(tmp, @2);
$$ = tmp;
}
| expression K_LAND expression
{ PEBinary*tmp = new PEBinary('a', $1, $3);
{ PEBinary*tmp = new PEBLogic('a', $1, $3);
FILE_NAME(tmp, @2);
$$ = tmp;
}