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)
|
PEBShift::PEBShift(char op, PExpr*l, PExpr*r)
|
||||||
: PEBinary(op, l, 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;
|
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 {
|
class PEBShift : public PEBinary {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
59
elab_expr.cc
59
elab_expr.cc
|
|
@ -294,11 +294,12 @@ NetExpr* PEBinary::elaborate_expr_base_(Design*des,
|
||||||
|
|
||||||
case 'a':
|
case 'a':
|
||||||
case 'o':
|
case 'o':
|
||||||
lp = condition_reduce(lp);
|
cerr << get_fileline() << ": internal error: "
|
||||||
rp = condition_reduce(rp);
|
<< "Elaboration of " << human_readable_op(op_)
|
||||||
tmp = new NetEBLogic(op_, lp, rp);
|
<< " Should have been handled in NetEBLogic::elaborate."
|
||||||
tmp->set_line(*this);
|
<< endl;
|
||||||
break;
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
tmp = new NetEBPow(op_, lp, rp);
|
tmp = new NetEBPow(op_, lp, rp);
|
||||||
|
|
@ -799,6 +800,54 @@ NetExpr* PEBComp::elaborate_expr(Design*des, NetScope*scope,
|
||||||
return tmp;
|
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 PEBShift::test_width(Design*des, NetScope*scope,
|
||||||
unsigned min, unsigned lval,
|
unsigned min, unsigned lval,
|
||||||
ivl_variable_type_t&expr_type__,
|
ivl_variable_type_t&expr_type__,
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,28 @@ NetExpr*PEBComp::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||||
return tmp;
|
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
|
* Event though parameters are not generally sized, parameter
|
||||||
* expressions can include concatenation expressions. This requires
|
* expressions can include concatenation expressions. This requires
|
||||||
|
|
|
||||||
|
|
@ -3270,7 +3270,7 @@ class NetEBLogic : public NetEBinary {
|
||||||
NetEBLogic(char op, NetExpr*l, NetExpr*r);
|
NetEBLogic(char op, NetExpr*l, NetExpr*r);
|
||||||
~NetEBLogic();
|
~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 NetEBLogic* dup_expr() const;
|
||||||
virtual NetEConst* eval_tree(int prune_to_width = -1);
|
virtual NetEConst* eval_tree(int prune_to_width = -1);
|
||||||
virtual NetNet* synthesize(Design*, NetScope*scope);
|
virtual NetNet* synthesize(Design*, NetScope*scope);
|
||||||
|
|
|
||||||
4
parse.y
4
parse.y
|
|
@ -1034,12 +1034,12 @@ expression
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| expression K_LOR expression
|
| expression K_LOR expression
|
||||||
{ PEBinary*tmp = new PEBinary('o', $1, $3);
|
{ PEBinary*tmp = new PEBLogic('o', $1, $3);
|
||||||
FILE_NAME(tmp, @2);
|
FILE_NAME(tmp, @2);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| expression K_LAND expression
|
| expression K_LAND expression
|
||||||
{ PEBinary*tmp = new PEBinary('a', $1, $3);
|
{ PEBinary*tmp = new PEBLogic('a', $1, $3);
|
||||||
FILE_NAME(tmp, @2);
|
FILE_NAME(tmp, @2);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue