More array fixes and down indexed part selects can be a lval.
Here are some more array fixes. They are mostly better error messages instead of just asserting and some code cleanup. The one new thing that probably should have been a separate submission is that down indexed part select [base -: width] can now be a lvalue.
This commit is contained in:
parent
51293b6e91
commit
e26b9e72a2
4
PExpr.h
4
PExpr.h
|
|
@ -308,8 +308,8 @@ class PEIdent : public PExpr {
|
||||||
private:
|
private:
|
||||||
NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*) const;
|
NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*) const;
|
||||||
bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
|
bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
|
||||||
bool elaborate_lval_net_idx_up_(Design*, NetScope*, NetAssign_*) const;
|
bool elaborate_lval_net_idx_(Design*, NetScope*, NetAssign_*,
|
||||||
bool elaborate_lval_net_idx_do_(Design*, NetScope*, NetAssign_*) const;
|
index_component_t::ctype_t) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetExpr*elaborate_expr_param(Design*des,
|
NetExpr*elaborate_expr_param(Design*des,
|
||||||
|
|
|
||||||
126
elab_lval.cc
126
elab_lval.cc
|
|
@ -189,15 +189,10 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||||
return lv;
|
return lv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_sel == index_component_t::SEL_IDX_UP) {
|
if (use_sel == index_component_t::SEL_IDX_UP ||
|
||||||
|
use_sel == index_component_t::SEL_IDX_DO) {
|
||||||
NetAssign_*lv = new NetAssign_(reg);
|
NetAssign_*lv = new NetAssign_(reg);
|
||||||
elaborate_lval_net_idx_up_(des, scope, lv);
|
elaborate_lval_net_idx_(des, scope, lv, use_sel);
|
||||||
return lv;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (use_sel == index_component_t::SEL_IDX_DO) {
|
|
||||||
NetAssign_*lv = new NetAssign_(reg);
|
|
||||||
elaborate_lval_net_idx_do_(des, scope, lv);
|
|
||||||
return lv;
|
return lv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -321,6 +316,13 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
|
||||||
ivl_assert(*this, !name_tail.index.empty());
|
ivl_assert(*this, !name_tail.index.empty());
|
||||||
|
|
||||||
const index_component_t&index_head = name_tail.index.front();
|
const index_component_t&index_head = name_tail.index.front();
|
||||||
|
if (index_head.sel == index_component_t::SEL_PART) {
|
||||||
|
cerr << get_line() << ": error: cannot perform a part "
|
||||||
|
<< "select on array " << reg->name() << "." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
|
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
|
||||||
ivl_assert(*this, index_head.msb != 0);
|
ivl_assert(*this, index_head.msb != 0);
|
||||||
ivl_assert(*this, index_head.lsb == 0);
|
ivl_assert(*this, index_head.lsb == 0);
|
||||||
|
|
@ -367,11 +369,9 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
|
||||||
if (use_sel == index_component_t::SEL_PART)
|
if (use_sel == index_component_t::SEL_PART)
|
||||||
elaborate_lval_net_part_(des, scope, lv);
|
elaborate_lval_net_part_(des, scope, lv);
|
||||||
|
|
||||||
if (use_sel == index_component_t::SEL_IDX_UP)
|
if (use_sel == index_component_t::SEL_IDX_UP ||
|
||||||
elaborate_lval_net_idx_up_(des, scope, lv);
|
use_sel == index_component_t::SEL_IDX_DO)
|
||||||
|
elaborate_lval_net_idx_(des, scope, lv, use_sel);
|
||||||
if (use_sel == index_component_t::SEL_IDX_DO)
|
|
||||||
elaborate_lval_net_idx_do_(des, scope, lv);
|
|
||||||
|
|
||||||
return lv;
|
return lv;
|
||||||
}
|
}
|
||||||
|
|
@ -429,9 +429,10 @@ bool PEIdent::elaborate_lval_net_part_(Design*des,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PEIdent::elaborate_lval_net_idx_up_(Design*des,
|
bool PEIdent::elaborate_lval_net_idx_(Design*des,
|
||||||
NetScope*scope,
|
NetScope*scope,
|
||||||
NetAssign_*lv) const
|
NetAssign_*lv,
|
||||||
|
index_component_t::ctype_t use_sel) const
|
||||||
{
|
{
|
||||||
const name_component_t&name_tail = path_.back();;
|
const name_component_t&name_tail = path_.back();;
|
||||||
ivl_assert(*this, !name_tail.index.empty());
|
ivl_assert(*this, !name_tail.index.empty());
|
||||||
|
|
@ -464,6 +465,10 @@ bool PEIdent::elaborate_lval_net_idx_up_(Design*des,
|
||||||
else if (reg->lsb() != 0)
|
else if (reg->lsb() != 0)
|
||||||
base = make_add_expr(base, - reg->lsb());
|
base = make_add_expr(base, - reg->lsb());
|
||||||
|
|
||||||
|
if (use_sel == index_component_t::SEL_IDX_DO && wid > 1 ) {
|
||||||
|
base = make_add_expr(base, 1-(long)wid);
|
||||||
|
}
|
||||||
|
|
||||||
if (debug_elaborate)
|
if (debug_elaborate)
|
||||||
cerr << get_line() << ": debug: Set part select width="
|
cerr << get_line() << ": debug: Set part select width="
|
||||||
<< wid << ", base=" << *base << endl;
|
<< wid << ", base=" << *base << endl;
|
||||||
|
|
@ -473,23 +478,6 @@ bool PEIdent::elaborate_lval_net_idx_up_(Design*des,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PEIdent::elaborate_lval_net_idx_do_(Design*des,
|
|
||||||
NetScope*scope,
|
|
||||||
NetAssign_*lv) const
|
|
||||||
{
|
|
||||||
const name_component_t&name_tail = path_.back();;
|
|
||||||
ivl_assert(*this, !name_tail.index.empty());
|
|
||||||
|
|
||||||
const index_component_t&index_tail = name_tail.index.back();
|
|
||||||
ivl_assert(*this, index_tail.msb != 0);
|
|
||||||
ivl_assert(*this, index_tail.lsb != 0);
|
|
||||||
|
|
||||||
cerr << get_line() << ": internal error: don't know how to "
|
|
||||||
"deal with SEL_IDX_DO in lval?" << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
|
NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
|
||||||
{
|
{
|
||||||
cerr << get_line() << ": error: Constant values not allowed "
|
cerr << get_line() << ": error: Constant values not allowed "
|
||||||
|
|
@ -498,75 +486,3 @@ NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* $Log: elab_lval.cc,v $
|
|
||||||
* Revision 1.44 2007/06/02 03:42:12 steve
|
|
||||||
* Properly evaluate scope path expressions.
|
|
||||||
*
|
|
||||||
* Revision 1.43 2007/05/24 04:07:11 steve
|
|
||||||
* Rework the heirarchical identifier parse syntax and pform
|
|
||||||
* to handle more general combinations of heirarch and bit selects.
|
|
||||||
*
|
|
||||||
* Revision 1.42 2007/03/14 05:06:49 steve
|
|
||||||
* Replace some asserts with ivl_asserts.
|
|
||||||
*
|
|
||||||
* Revision 1.41 2007/03/05 05:59:10 steve
|
|
||||||
* Handle processes within generate loops.
|
|
||||||
*
|
|
||||||
* Revision 1.40 2007/02/27 05:14:38 steve
|
|
||||||
* Detect and warn about lval array index out fo bounds.
|
|
||||||
*
|
|
||||||
* Revision 1.39 2007/02/01 05:25:26 steve
|
|
||||||
* Error message better reflects more general reality.
|
|
||||||
*
|
|
||||||
* Revision 1.38 2007/01/16 05:44:15 steve
|
|
||||||
* Major rework of array handling. Memories are replaced with the
|
|
||||||
* more general concept of arrays. The NetMemory and NetEMemory
|
|
||||||
* classes are removed from the ivl core program, and the IVL_LPM_RAM
|
|
||||||
* lpm type is removed from the ivl_target API.
|
|
||||||
*
|
|
||||||
* Revision 1.37 2006/11/04 06:19:25 steve
|
|
||||||
* Remove last bits of relax_width methods, and use test_width
|
|
||||||
* to calculate the width of an r-value expression that may
|
|
||||||
* contain unsized numbers.
|
|
||||||
*
|
|
||||||
* Revision 1.36 2006/06/02 04:48:50 steve
|
|
||||||
* Make elaborate_expr methods aware of the width that the context
|
|
||||||
* requires of it. In the process, fix sizing of the width of unary
|
|
||||||
* minus is context determined sizes.
|
|
||||||
*
|
|
||||||
* Revision 1.35 2006/04/16 00:54:04 steve
|
|
||||||
* Cleanup lval part select handling.
|
|
||||||
*
|
|
||||||
* Revision 1.34 2006/04/16 00:15:43 steve
|
|
||||||
* Fix part selects in l-values.
|
|
||||||
*
|
|
||||||
* Revision 1.33 2006/02/02 02:43:57 steve
|
|
||||||
* Allow part selects of memory words in l-values.
|
|
||||||
*
|
|
||||||
* Revision 1.32 2005/07/11 16:56:50 steve
|
|
||||||
* Remove NetVariable and ivl_variable_t structures.
|
|
||||||
*
|
|
||||||
* Revision 1.31 2004/12/29 23:55:43 steve
|
|
||||||
* Unify elaboration of l-values for all proceedural assignments,
|
|
||||||
* including assing, cassign and force.
|
|
||||||
*
|
|
||||||
* Generate NetConcat devices for gate outputs that feed into a
|
|
||||||
* vector results. Use this to hande gate arrays. Also let gate
|
|
||||||
* arrays handle vectors of gates when the outputs allow for it.
|
|
||||||
*
|
|
||||||
* Revision 1.30 2004/12/11 02:31:25 steve
|
|
||||||
* Rework of internals to carry vectors through nexus instead
|
|
||||||
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
|
|
||||||
* down this path.
|
|
||||||
*
|
|
||||||
* Revision 1.29 2004/10/04 01:10:52 steve
|
|
||||||
* Clean up spurious trailing white space.
|
|
||||||
*
|
|
||||||
* Revision 1.28 2004/08/28 14:59:44 steve
|
|
||||||
* More detailed error message about bad variable.
|
|
||||||
*
|
|
||||||
* Revision 1.27 2003/09/19 03:30:05 steve
|
|
||||||
* Fix name search in elab_lval.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
|
||||||
17
elab_net.cc
17
elab_net.cc
|
|
@ -2242,7 +2242,13 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||||
case index_component_t::SEL_IDX_UP: {
|
case index_component_t::SEL_IDX_UP: {
|
||||||
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1);
|
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||||
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
||||||
ivl_assert(*this, tmp);
|
if (!tmp) {
|
||||||
|
cerr << get_line() << ": error: indexed part select of "
|
||||||
|
<< sig->name()
|
||||||
|
<< " must be a constant in this context." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
long midx_val = tmp->value().as_long();
|
long midx_val = tmp->value().as_long();
|
||||||
midx = sig->sb_to_idx(midx_val);
|
midx = sig->sb_to_idx(midx_val);
|
||||||
|
|
@ -2430,7 +2436,12 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||||
|
|
||||||
if (sig->array_dimensions() > 0) {
|
if (sig->array_dimensions() > 0) {
|
||||||
|
|
||||||
ivl_assert(*this, !name_tail.index.empty());
|
if (name_tail.index.empty()) {
|
||||||
|
cerr << get_line() << ": error: array " << sig->name()
|
||||||
|
<< " must be used with an index." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const index_component_t&index_head = name_tail.index.front();
|
const index_component_t&index_head = name_tail.index.front();
|
||||||
if (index_head.sel == index_component_t::SEL_PART) {
|
if (index_head.sel == index_component_t::SEL_PART) {
|
||||||
|
|
@ -2459,7 +2470,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||||
<< " to index l-value array." << endl;
|
<< " to index l-value array." << endl;
|
||||||
|
|
||||||
/* The array has a part/bit select at the end. */
|
/* The array has a part/bit select at the end. */
|
||||||
if (name_tail.index.size() == 2) {
|
if (name_tail.index.size() > sig->array_dimensions()) {
|
||||||
if (! eval_part_select_(des, scope, sig, midx, lidx))
|
if (! eval_part_select_(des, scope, sig, midx, lidx))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,7 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
||||||
<< "Invalid elaborate_net results here:" << endl;
|
<< "Invalid elaborate_net results here:" << endl;
|
||||||
rid->dump_net(cerr, 4);
|
rid->dump_net(cerr, 4);
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
ivl_assert(*this, rid->pin_count() == 1);
|
ivl_assert(*this, rid->pin_count() == 1);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue