From 7b4fda87850caf0c7ec6e1f127a74418193ec6db Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Wed, 1 Oct 2008 22:38:53 -0700 Subject: [PATCH] Process arguments to bitwise operator using singned/unsigned rules. The arguments to bitwise operators are padded if *either* of the operands is unsigned. This is according to the sign/unsigned expression rules of Verilog, and also matches the behavior of the "Big-3." --- elab_expr.cc | 8 ++++++++ net_expr.cc | 3 +++ netlist.cc | 3 +++ 3 files changed, 14 insertions(+) diff --git a/elab_expr.cc b/elab_expr.cc index 1c93c7ce8..b5894a617 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -355,6 +355,14 @@ NetExpr* PEBinary::elaborate_expr_base_bits_(Design*des, NetExpr*lp, NetExpr*rp, int expr_wid) const { + // 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. + if (! lp->has_sign()) + rp->cast_signed(false); + if (! rp->has_sign()) + lp->cast_signed(false); + if (expr_wid > 0) { if (type_is_vectorable(lp->expr_type())) lp = pad_to_width(lp, expr_wid); diff --git a/net_expr.cc b/net_expr.cc index 96f46d298..6b1a9fccd 100644 --- a/net_expr.cc +++ b/net_expr.cc @@ -127,6 +127,9 @@ ivl_variable_type_t NetEBAdd::expr_type() const NetEBComp::NetEBComp(char op, NetExpr*l, NetExpr*r) : NetEBinary(op, l, r) { + // The output of compare is always unsigned. + cast_signed_base_(false); + if (NetEConst*tmp = dynamic_cast(r)) do { if (tmp->has_width()) diff --git a/netlist.cc b/netlist.cc index 88bfeb384..20a9284ff 100644 --- a/netlist.cc +++ b/netlist.cc @@ -2073,6 +2073,9 @@ NetEBBits* NetEBBits::dup_expr() const NetEBinary::NetEBinary(char op, NetExpr*l, NetExpr*r) : op_(op), left_(l), right_(r) { + // Binary expressions of all sorts are signed if both the + // arguments are signed. + cast_signed_base_( left_->has_sign() && right_->has_sign()); } NetEBinary::~NetEBinary()