From edf741106da7a176b2c5652fd158bab6871ae9ee Mon Sep 17 00:00:00 2001 From: Cary R Date: Fri, 25 Jan 2013 10:26:26 -0800 Subject: [PATCH] V0.9: Handle undefined L-value selects L-value bit selects were incorrectly converting an undefined index to 0. L-value part selects were asserting if an undefined index was given. This patch unifies how all these are handle (including indexed part selects). The base is set to an undefined value and an appropriate width is used. A warning message is always printed since this is not a simple out of range issue. It is the responsibility of the code generator to skip the assignment, but we always want to execute the R-value since it could have a side effect. --- elab_lval.cc | 49 +++++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/elab_lval.cc b/elab_lval.cc index cb7bfd2fb..813372d7b 100644 --- a/elab_lval.cc +++ b/elab_lval.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com) + * Copyright (c) 2000-2013 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 @@ -336,6 +336,7 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des, ivl_assert(*this, index_tail.lsb == 0); NetNet*reg = lv->sig(); + assert(reg); // These are not used, but they need to have a default value. ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE; @@ -350,8 +351,20 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des, long lsb = 0; if (NetEConst*index_con = dynamic_cast (mux)) { - lsb = index_con->value().as_long(); - mux = 0; + // The index has a constant defined value. + if (index_con->value().is_defined()) { + lsb = index_con->value().as_long(); + mux = 0; + // The index is undefined. + } else { + cerr << get_fileline() << ": warning: L-value bit select of " + << reg->name(); + if (reg->array_dimensions() > 0) cerr << "[]"; + cerr << " has an undefined index." << endl; + + lv->set_part(new NetEConst(verinum(verinum::Vx)), 1); + return true; + } } if (mux) { @@ -393,14 +406,21 @@ bool PEIdent::elaborate_lval_net_part_(Design*des, long msb, lsb; bool parts_defined_flag; bool flag = calculate_parts_(des, scope, msb, lsb, parts_defined_flag); - if (!flag) - return false; - - ivl_assert(*this, parts_defined_flag); + if (!flag) return false; NetNet*reg = lv->sig(); assert(reg); + if (! parts_defined_flag) { + cerr << get_fileline() << ": warning: L-value part select of " + << reg->name(); + if (reg->array_dimensions() > 0) cerr << "[]"; + cerr << " has an undefined index." << endl; + lv->set_part(new NetEConst(verinum(verinum::Vx)), 1); + return true; + } + + if (msb == reg->msb() && lsb == reg->lsb()) { /* Part select covers the entire vector. Simplest case. */ @@ -517,17 +537,10 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des, } } } else { - if (warn_ob_select) { - cerr << get_fileline() << ": warning: " << reg->name(); - if (reg->array_dimensions() > 0) cerr << "[]"; - cerr << "['bx"; - if (use_sel == index_component_t::SEL_IDX_UP) { - cerr << "+:"; - } else { - cerr << "-:"; - } - cerr << wid << "] is always outside vector." << endl; - } + cerr << get_fileline() << ": warning: L-value indexed part " + << "select of " << reg->name(); + if (reg->array_dimensions() > 0) cerr << "[]"; + cerr << " has an undefined base." << endl; } } else { /* Correct the mux for the range of the vector. */