diff --git a/elab_expr.cc b/elab_expr.cc index 1ff7b7b67..019381481 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2016 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2017 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it @@ -3141,6 +3141,25 @@ unsigned PEIdent::test_width_method_(Design*des, NetScope*scope, width_mode_t&) } } + // Look for the enumeration attributes. + if (const netenum_t*netenum = net->enumeration()) { + if (member_name == "num") { + expr_type_ = IVL_VT_BOOL; + expr_width_ = 32; + min_width_ = 32; + signed_flag_= true; + return 32; + } + if ((member_name == "first") || (member_name == "last") || + (member_name == "next") || (member_name == "prev")) { + expr_type_ = netenum->base_type(); + expr_width_ = netenum->packed_width();; + min_width_ = expr_width_; + signed_flag_ = netenum->get_signed(); + return expr_width_; + } + } + return 0; } diff --git a/eval_tree.cc b/eval_tree.cc index 1c709f5f2..1da857035 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2016 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2017 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -570,11 +570,10 @@ NetEConst* NetEBComp::eval_eqeq_(bool ne_flag, const NetExpr*le, const NetExpr*r const verinum::V ne_res = ne_flag? verinum::V1 : verinum::V0; verinum::V res = eq_res; - unsigned top = lv.len(); - if (rv.len() < top) - top = rv.len(); - for (unsigned idx = 0 ; idx < top ; idx += 1) { + assert(lv.len() == rv.len()); + + for (unsigned idx = 0 ; idx < lv.len() ; idx += 1) { bool x_bit_present = false; @@ -611,60 +610,6 @@ NetEConst* NetEBComp::eval_eqeq_(bool ne_flag, const NetExpr*le, const NetExpr*r } } - if (res != verinum::Vx) { - verinum::V lpad = verinum::V0; - verinum::V rpad = verinum::V0; - - if (lv.has_sign() && lv.get(lv.len()-1) == verinum::V1) - lpad = verinum::V1; - if (rv.has_sign() && rv.get(rv.len()-1) == verinum::V1) - rpad = verinum::V1; - - for (unsigned idx = top ; idx < lv.len() ; idx += 1) - switch (lv.get(idx)) { - - case verinum::Vx: - case verinum::Vz: - res = verinum::Vx; - break; - - case verinum::V0: - if (res != verinum::Vx && rpad != verinum::V0) - res = ne_res; - break; - - case verinum::V1: - if (res != verinum::Vx && rpad != verinum::V1) - res = ne_res; - break; - - default: - break; - } - - for (unsigned idx = top ; idx < rv.len() ; idx += 1) - switch (rv.get(idx)) { - - case verinum::Vx: - case verinum::Vz: - res = verinum::Vx; - break; - - case verinum::V0: - if (res != verinum::Vx && lpad != verinum::V0) - res = ne_res; - break; - - case verinum::V1: - if (res != verinum::Vx && lpad != verinum::V1) - res = ne_res; - break; - - default: - break; - } - } - NetEConst*result = new NetEConst(verinum(res, 1)); ivl_assert(*this, result); return result; @@ -681,46 +626,14 @@ NetEConst* NetEBComp::eval_eqeqeq_(bool ne_flag, const NetExpr*le, const NetExpr verinum::V res = verinum::V1; - // Find the smallest argument length. - unsigned cnt = lv.len(); - if (cnt > rv.len()) cnt = rv.len(); + assert(lv.len() == rv.len()); - // Check the common bits. - for (unsigned idx = 0 ; idx < cnt ; idx += 1) + for (unsigned idx = 0 ; idx < lv.len() ; idx += 1) if (lv.get(idx) != rv.get(idx)) { res = verinum::V0; break; } - bool is_signed = lv.has_sign() && rv.has_sign(); - - // If the left value is longer check it against the pad bit. - if (res == verinum::V1) { - verinum::V pad = verinum::V0; - if (is_signed) - pad = rv.get(rv.len()-1); - - for (unsigned idx = cnt ; idx < lv.len() ; idx += 1) - if (lv.get(idx) != pad) { - res = verinum::V0; - break; - } - } - - // If the right value is longer check it against the pad bit. - if (res == verinum::V1) { - verinum::V pad = verinum::V0; - if (is_signed) - pad = lv.get(lv.len()-1); - - for (unsigned idx = cnt ; idx < rv.len() ; idx += 1) { - if (rv.get(idx) != pad) { - res = verinum::V0; - break; - } - } - } - if (ne_flag) { if (res == verinum::V0) res = verinum::V1; else res = verinum::V0;