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:
parent
b7d3276e4d
commit
ea057a7574
10
PExpr.cc
10
PExpr.cc
|
|
@ -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
19
PExpr.h
|
|
@ -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:
|
||||
|
|
|
|||
59
elab_expr.cc
59
elab_expr.cc
|
|
@ -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__,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
4
parse.y
4
parse.y
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue