Fix support for indexed part select in continuous assign l-values.
This commit is contained in:
parent
46d86ad276
commit
c2ff3d501c
102
elab_net.cc
102
elab_net.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: elab_net.cc,v 1.179 2006/04/10 00:32:14 steve Exp $"
|
#ident "$Id: elab_net.cc,v 1.180 2006/04/24 05:15:07 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -1884,23 +1884,77 @@ NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const
|
||||||
bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||||
unsigned&midx, unsigned&lidx) const
|
unsigned&midx, unsigned&lidx) const
|
||||||
{
|
{
|
||||||
if (msb_ && lsb_) {
|
switch (sel_) {
|
||||||
verinum*mval = msb_->eval_const(des, scope);
|
default:
|
||||||
assert(mval);
|
cerr << get_line() << ": internal error: "
|
||||||
verinum*lval = lsb_->eval_const(des, scope);
|
<< "Unexpected sel_ value = " << sel_ << endl;
|
||||||
assert(lval);
|
assert(0);
|
||||||
|
break;
|
||||||
|
|
||||||
midx = sig->sb_to_idx(mval->as_long());
|
case PEIdent::SEL_IDX_DO:
|
||||||
lidx = sig->sb_to_idx(lval->as_long());
|
case PEIdent::SEL_IDX_UP: {
|
||||||
|
assert(msb_);
|
||||||
|
assert(lsb_);
|
||||||
|
assert(idx_.empty());
|
||||||
|
|
||||||
|
NetExpr*tmp_ex = elab_and_eval(des, scope, msb_);
|
||||||
|
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
||||||
|
assert(tmp);
|
||||||
|
|
||||||
|
long midx_val = tmp->value().as_long();
|
||||||
|
midx = sig->sb_to_idx(midx_val);
|
||||||
|
delete tmp_ex;
|
||||||
|
|
||||||
|
tmp_ex = elab_and_eval(des, scope, lsb_);
|
||||||
|
tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
||||||
|
assert(tmp);
|
||||||
|
|
||||||
|
long wid = tmp->value().as_long();
|
||||||
|
delete tmp_ex;
|
||||||
|
|
||||||
|
if (sel_ == PEIdent::SEL_IDX_UP)
|
||||||
|
lidx = sig->sb_to_idx(midx_val+wid-1);
|
||||||
|
else
|
||||||
|
lidx = sig->sb_to_idx(midx_val-wid+1);
|
||||||
|
|
||||||
|
if (midx < lidx) {
|
||||||
|
long tmp = midx;
|
||||||
|
midx = lidx;
|
||||||
|
lidx = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PEIdent::SEL_PART: {
|
||||||
|
assert(msb_);
|
||||||
|
assert(lsb_);
|
||||||
|
assert(idx_.empty());
|
||||||
|
|
||||||
|
NetExpr*tmp_ex = elab_and_eval(des, scope, msb_);
|
||||||
|
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
||||||
|
assert(tmp);
|
||||||
|
|
||||||
|
long midx_val = tmp->value().as_long();
|
||||||
|
midx = sig->sb_to_idx(midx_val);
|
||||||
|
delete tmp_ex;
|
||||||
|
|
||||||
|
tmp_ex = elab_and_eval(des, scope, lsb_);
|
||||||
|
tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
||||||
|
assert(tmp);
|
||||||
|
|
||||||
|
long lidx_val = tmp->value().as_long();
|
||||||
|
lidx = sig->sb_to_idx(lidx_val);
|
||||||
|
delete tmp_ex;
|
||||||
|
|
||||||
/* Detect reversed indices of a part select. */
|
/* Detect reversed indices of a part select. */
|
||||||
if (lidx > midx) {
|
if (lidx > midx) {
|
||||||
cerr << get_line() << ": error: Part select "
|
cerr << get_line() << ": error: Part select "
|
||||||
<< sig->name() << "[" << mval->as_long() << ":"
|
<< sig->name() << "[" << midx_val << ":"
|
||||||
<< lval->as_long() << "] indices reversed." << endl;
|
<< lidx_val << "] indices reversed." << endl;
|
||||||
cerr << get_line() << ": : Did you mean "
|
cerr << get_line() << ": : Did you mean "
|
||||||
<< sig->name() << "[" << lval->as_long() << ":"
|
<< sig->name() << "[" << lidx_val << ":"
|
||||||
<< mval->as_long() << "]?" << endl;
|
<< midx_val << "]?" << endl;
|
||||||
unsigned tmp = midx;
|
unsigned tmp = midx;
|
||||||
midx = lidx;
|
midx = lidx;
|
||||||
lidx = tmp;
|
lidx = tmp;
|
||||||
|
|
@ -1910,14 +1964,17 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||||
/* Detect a part select out of range. */
|
/* Detect a part select out of range. */
|
||||||
if (midx >= sig->vector_width()) {
|
if (midx >= sig->vector_width()) {
|
||||||
cerr << get_line() << ": error: Part select "
|
cerr << get_line() << ": error: Part select "
|
||||||
<< sig->name() << "[" << mval->as_long() << ":"
|
<< sig->name() << "[" << midx_val << ":"
|
||||||
<< lval->as_long() << "] out of range." << endl;
|
<< midx_val << "] out of range." << endl;
|
||||||
midx = sig->vector_width() - 1;
|
midx = sig->vector_width() - 1;
|
||||||
lidx = 0;
|
lidx = 0;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (!idx_.empty()) {
|
case PEIdent::SEL_NONE:
|
||||||
|
if (!idx_.empty()) {
|
||||||
assert(msb_ == 0);
|
assert(msb_ == 0);
|
||||||
assert(lsb_ == 0);
|
assert(lsb_ == 0);
|
||||||
assert(idx_.size() == 1);
|
assert(idx_.size() == 1);
|
||||||
|
|
@ -1944,10 +2001,22 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||||
lidx = midx;
|
lidx = midx;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if (msb_ || lsb_) {
|
||||||
|
cerr << get_line() << ": internal error: "
|
||||||
|
<< "Unexpected msb_/lsb_ values?" << endl;
|
||||||
|
if (msb_)
|
||||||
|
cerr << get_line() << " : "
|
||||||
|
<< *msb_ << endl;
|
||||||
|
if (lsb_)
|
||||||
|
cerr << get_line() << " : "
|
||||||
|
<< *lsb_ << endl;
|
||||||
|
}
|
||||||
assert(msb_ == 0 && lsb_ == 0);
|
assert(msb_ == 0 && lsb_ == 0);
|
||||||
midx = sig->vector_width() - 1;
|
midx = sig->vector_width() - 1;
|
||||||
lidx = 0;
|
lidx = 0;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -2662,6 +2731,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_net.cc,v $
|
* $Log: elab_net.cc,v $
|
||||||
|
* Revision 1.180 2006/04/24 05:15:07 steve
|
||||||
|
* Fix support for indexed part select in continuous assign l-values.
|
||||||
|
*
|
||||||
* Revision 1.179 2006/04/10 00:32:14 steve
|
* Revision 1.179 2006/04/10 00:32:14 steve
|
||||||
* Clean up index expression error message.
|
* Clean up index expression error message.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
4
parse.y
4
parse.y
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: parse.y,v 1.215 2006/04/17 04:35:49 steve Exp $"
|
#ident "$Id: parse.y,v 1.216 2006/04/24 05:15:07 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -1287,6 +1287,7 @@ indexed_identifier
|
||||||
}
|
}
|
||||||
| indexed_identifier '[' expression ']'
|
| indexed_identifier '[' expression ']'
|
||||||
{ PEIdent*tmp = $1;
|
{ PEIdent*tmp = $1;
|
||||||
|
tmp->sel_ = PEIdent::SEL_NONE;
|
||||||
tmp->idx_.push_back($3);
|
tmp->idx_.push_back($3);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -2224,6 +2225,7 @@ port_reference
|
||||||
}
|
}
|
||||||
wtmp->msb_ = $3;
|
wtmp->msb_ = $3;
|
||||||
wtmp->lsb_ = $5;
|
wtmp->lsb_ = $5;
|
||||||
|
wtmp->sel_ = PEIdent::SEL_PART;
|
||||||
Module::port_t*ptmp = new Module::port_t;
|
Module::port_t*ptmp = new Module::port_t;
|
||||||
ptmp->name = perm_string();
|
ptmp->name = perm_string();
|
||||||
ptmp->expr = svector<PEIdent*>(1);
|
ptmp->expr = svector<PEIdent*>(1);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue