Merge pull request #952 from larsclausen/2state-arith
Make result of binary operations 2-state if inputs are 2-state
This commit is contained in:
commit
44bc9cba03
|
|
@ -807,7 +807,7 @@ NetEConst* NetEBLogic::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||||
{
|
{
|
||||||
// NetEBLogic arguments should have already been reduced so real is not possible.
|
// NetEBLogic arguments should have already been reduced so real is not possible.
|
||||||
ivl_assert(*this, (l->expr_type() != IVL_VT_REAL) && (r->expr_type() != IVL_VT_REAL));
|
ivl_assert(*this, (l->expr_type() != IVL_VT_REAL) && (r->expr_type() != IVL_VT_REAL));
|
||||||
ivl_assert(*this, expr_type() == IVL_VT_LOGIC);
|
ivl_assert(*this, expr_type() == IVL_VT_LOGIC || expr_type() == IVL_VT_BOOL);
|
||||||
|
|
||||||
const NetEConst*lc = dynamic_cast<const NetEConst*>(l);
|
const NetEConst*lc = dynamic_cast<const NetEConst*>(l);
|
||||||
const NetEConst*rc = dynamic_cast<const NetEConst*>(r);
|
const NetEConst*rc = dynamic_cast<const NetEConst*>(r);
|
||||||
|
|
@ -943,7 +943,7 @@ NetExpr* NetEBMinMax::eval_tree_real_(const NetExpr*l, const NetExpr*r) const
|
||||||
NetExpr* NetEBMinMax::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
NetExpr* NetEBMinMax::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||||
{
|
{
|
||||||
if (expr_type() == IVL_VT_REAL) return eval_tree_real_(l,r);
|
if (expr_type() == IVL_VT_REAL) return eval_tree_real_(l,r);
|
||||||
ivl_assert(*this, expr_type() == IVL_VT_LOGIC);
|
ivl_assert(*this, expr_type() == IVL_VT_LOGIC || expr_type() == IVL_VT_BOOL);
|
||||||
|
|
||||||
const NetEConst*lc = dynamic_cast<const NetEConst*>(l);
|
const NetEConst*lc = dynamic_cast<const NetEConst*>(l);
|
||||||
const NetEConst*rc = dynamic_cast<const NetEConst*>(r);
|
const NetEConst*rc = dynamic_cast<const NetEConst*>(r);
|
||||||
|
|
@ -996,7 +996,7 @@ NetExpr* NetEBMult::eval_tree_real_(const NetExpr*l, const NetExpr*r) const
|
||||||
NetExpr* NetEBMult::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
NetExpr* NetEBMult::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||||
{
|
{
|
||||||
if (expr_type() == IVL_VT_REAL) return eval_tree_real_(l,r);
|
if (expr_type() == IVL_VT_REAL) return eval_tree_real_(l,r);
|
||||||
ivl_assert(*this, expr_type() == IVL_VT_LOGIC);
|
ivl_assert(*this, expr_type() == IVL_VT_LOGIC || expr_type() == IVL_VT_BOOL);
|
||||||
|
|
||||||
const NetEConst*lc = dynamic_cast<const NetEConst*>(l);
|
const NetEConst*lc = dynamic_cast<const NetEConst*>(l);
|
||||||
const NetEConst*rc = dynamic_cast<const NetEConst*>(r);
|
const NetEConst*rc = dynamic_cast<const NetEConst*>(r);
|
||||||
|
|
@ -1034,7 +1034,7 @@ NetExpr* NetEBPow::eval_tree_real_(const NetExpr*l, const NetExpr*r) const
|
||||||
NetExpr* NetEBPow::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
NetExpr* NetEBPow::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||||
{
|
{
|
||||||
if (expr_type() == IVL_VT_REAL) return eval_tree_real_(l,r);
|
if (expr_type() == IVL_VT_REAL) return eval_tree_real_(l,r);
|
||||||
ivl_assert(*this, expr_type() == IVL_VT_LOGIC);
|
ivl_assert(*this, expr_type() == IVL_VT_LOGIC || expr_type() == IVL_VT_BOOL);
|
||||||
|
|
||||||
const NetEConst*lc = dynamic_cast<const NetEConst*>(l);
|
const NetEConst*lc = dynamic_cast<const NetEConst*>(l);
|
||||||
const NetEConst*rc = dynamic_cast<const NetEConst*>(r);
|
const NetEConst*rc = dynamic_cast<const NetEConst*>(r);
|
||||||
|
|
|
||||||
55
net_expr.cc
55
net_expr.cc
|
|
@ -111,15 +111,23 @@ NetEBAdd::~NetEBAdd()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ivl_variable_type_t arith_expr_type(const NetExpr *l, const NetExpr *r)
|
||||||
|
{
|
||||||
|
if (l->expr_type() == IVL_VT_REAL ||
|
||||||
|
r->expr_type() == IVL_VT_REAL)
|
||||||
|
return IVL_VT_REAL;
|
||||||
|
|
||||||
|
if (l->expr_type() == IVL_VT_LOGIC ||
|
||||||
|
r->expr_type() == IVL_VT_LOGIC)
|
||||||
|
return IVL_VT_LOGIC;
|
||||||
|
|
||||||
|
return IVL_VT_BOOL;
|
||||||
|
}
|
||||||
|
|
||||||
ivl_variable_type_t NetEBAdd::expr_type() const
|
ivl_variable_type_t NetEBAdd::expr_type() const
|
||||||
{
|
{
|
||||||
if (left_->expr_type() == IVL_VT_REAL)
|
return arith_expr_type(left_, right_);
|
||||||
return IVL_VT_REAL;
|
|
||||||
|
|
||||||
if (right_->expr_type() == IVL_VT_REAL)
|
|
||||||
return IVL_VT_REAL;
|
|
||||||
|
|
||||||
return IVL_VT_LOGIC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -171,6 +179,8 @@ ivl_variable_type_t NetEBDiv::expr_type() const
|
||||||
if (right_->expr_type() == IVL_VT_REAL)
|
if (right_->expr_type() == IVL_VT_REAL)
|
||||||
return IVL_VT_REAL;
|
return IVL_VT_REAL;
|
||||||
|
|
||||||
|
// div is always 4-state, even if both inputs are 2-state because division
|
||||||
|
// by 0 can yield 'x
|
||||||
return IVL_VT_LOGIC;
|
return IVL_VT_LOGIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -185,12 +195,7 @@ NetEBMinMax::~NetEBMinMax()
|
||||||
|
|
||||||
ivl_variable_type_t NetEBMinMax::expr_type() const
|
ivl_variable_type_t NetEBMinMax::expr_type() const
|
||||||
{
|
{
|
||||||
if (left_->expr_type() == IVL_VT_REAL)
|
return arith_expr_type(left_, right_);
|
||||||
return IVL_VT_REAL;
|
|
||||||
if (right_->expr_type() == IVL_VT_REAL)
|
|
||||||
return IVL_VT_REAL;
|
|
||||||
|
|
||||||
return IVL_VT_LOGIC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NetEBMult::NetEBMult(char op__, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag)
|
NetEBMult::NetEBMult(char op__, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag)
|
||||||
|
|
@ -204,13 +209,7 @@ NetEBMult::~NetEBMult()
|
||||||
|
|
||||||
ivl_variable_type_t NetEBMult::expr_type() const
|
ivl_variable_type_t NetEBMult::expr_type() const
|
||||||
{
|
{
|
||||||
if (left_->expr_type() == IVL_VT_REAL)
|
return arith_expr_type(left_, right_);
|
||||||
return IVL_VT_REAL;
|
|
||||||
|
|
||||||
if (right_->expr_type() == IVL_VT_REAL)
|
|
||||||
return IVL_VT_REAL;
|
|
||||||
|
|
||||||
return IVL_VT_LOGIC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NetEBPow::NetEBPow(char op__, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag)
|
NetEBPow::NetEBPow(char op__, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag)
|
||||||
|
|
@ -224,12 +223,7 @@ NetEBPow::~NetEBPow()
|
||||||
|
|
||||||
ivl_variable_type_t NetEBPow::expr_type() const
|
ivl_variable_type_t NetEBPow::expr_type() const
|
||||||
{
|
{
|
||||||
if (right_->expr_type() == IVL_VT_REAL)
|
return arith_expr_type(left_, right_);
|
||||||
return IVL_VT_REAL;
|
|
||||||
if (left_->expr_type() == IVL_VT_REAL)
|
|
||||||
return IVL_VT_REAL;
|
|
||||||
|
|
||||||
return IVL_VT_LOGIC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NetEBShift::NetEBShift(char op__, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag)
|
NetEBShift::NetEBShift(char op__, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag)
|
||||||
|
|
@ -246,6 +240,15 @@ bool NetEBShift::has_width() const
|
||||||
return left_->has_width();
|
return left_->has_width();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ivl_variable_type_t NetEBShift::expr_type() const
|
||||||
|
{
|
||||||
|
if (left_->expr_type() == IVL_VT_LOGIC ||
|
||||||
|
right_->expr_type() == IVL_VT_LOGIC)
|
||||||
|
return IVL_VT_LOGIC;
|
||||||
|
|
||||||
|
return IVL_VT_BOOL;
|
||||||
|
}
|
||||||
|
|
||||||
NetEConcat::NetEConcat(unsigned cnt, unsigned r, ivl_variable_type_t vt)
|
NetEConcat::NetEConcat(unsigned cnt, unsigned r, ivl_variable_type_t vt)
|
||||||
: parms_(cnt), repeat_(r), expr_type_(vt)
|
: parms_(cnt), repeat_(r), expr_type_(vt)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
18
netlist.cc
18
netlist.cc
|
|
@ -2257,6 +2257,15 @@ NetEBBits::~NetEBBits()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ivl_variable_type_t NetEBBits::expr_type() const
|
||||||
|
{
|
||||||
|
if (left_->expr_type() == IVL_VT_LOGIC ||
|
||||||
|
right_->expr_type() == IVL_VT_LOGIC)
|
||||||
|
return IVL_VT_LOGIC;
|
||||||
|
|
||||||
|
return IVL_VT_BOOL;
|
||||||
|
}
|
||||||
|
|
||||||
NetEBinary::NetEBinary(char op__, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag)
|
NetEBinary::NetEBinary(char op__, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag)
|
||||||
: op_(op__), left_(l), right_(r)
|
: op_(op__), left_(l), right_(r)
|
||||||
{
|
{
|
||||||
|
|
@ -2284,6 +2293,15 @@ NetEBLogic::~NetEBLogic()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ivl_variable_type_t NetEBLogic::expr_type() const
|
||||||
|
{
|
||||||
|
if (left_->expr_type() == IVL_VT_LOGIC ||
|
||||||
|
right_->expr_type() == IVL_VT_LOGIC)
|
||||||
|
return IVL_VT_LOGIC;
|
||||||
|
|
||||||
|
return IVL_VT_BOOL;
|
||||||
|
}
|
||||||
|
|
||||||
NetEConst::NetEConst(const verinum&val)
|
NetEConst::NetEConst(const verinum&val)
|
||||||
: NetExpr(val.len()), value_(val)
|
: NetExpr(val.len()), value_(val)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4248,6 +4248,8 @@ class NetEBBits : public NetEBinary {
|
||||||
virtual NetEBBits* dup_expr() const;
|
virtual NetEBBits* dup_expr() const;
|
||||||
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
|
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
|
||||||
|
|
||||||
|
ivl_variable_type_t expr_type() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetEConst* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
|
NetEConst* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
|
||||||
};
|
};
|
||||||
|
|
@ -4309,6 +4311,8 @@ class NetEBLogic : public NetEBinary {
|
||||||
virtual NetEBLogic* dup_expr() const;
|
virtual NetEBLogic* dup_expr() const;
|
||||||
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
|
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
|
||||||
|
|
||||||
|
ivl_variable_type_t expr_type() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetEConst* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
|
NetEConst* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
|
||||||
};
|
};
|
||||||
|
|
@ -4392,6 +4396,8 @@ class NetEBShift : public NetEBinary {
|
||||||
virtual NetEBShift* dup_expr() const;
|
virtual NetEBShift* dup_expr() const;
|
||||||
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
|
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
|
||||||
|
|
||||||
|
ivl_variable_type_t expr_type() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetEConst* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
|
NetEConst* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -884,8 +884,8 @@ static int show_stmt_assign_sig_string(ivl_statement_t net)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(ivl_expr_width(rval)==8);
|
|
||||||
draw_eval_vec4(rval);
|
draw_eval_vec4(rval);
|
||||||
|
resize_vec4_wid(rval, 8);
|
||||||
|
|
||||||
/* Calculate the character select for the word. */
|
/* Calculate the character select for the word. */
|
||||||
int mux_word = allocate_word();
|
int mux_word = allocate_word();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue