Skip to content
Browse files

Fix support for indexed part select in continuous assign l-values.

  • Loading branch information...
1 parent 46d86ad commit c2ff3d501ccc3431ea3b666e46ef135ecd2396a2 steve committed
Showing with 135 additions and 61 deletions.
  1. +132 −60 elab_net.cc
  2. +3 −1 parse.y
View
192 elab_net.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
# include "config.h"
@@ -1884,69 +1884,138 @@ NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const
bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
unsigned&midx, unsigned&lidx) const
{
- if (msb_ && lsb_) {
- verinum*mval = msb_->eval_const(des, scope);
- assert(mval);
- verinum*lval = lsb_->eval_const(des, scope);
- assert(lval);
-
- midx = sig->sb_to_idx(mval->as_long());
- lidx = sig->sb_to_idx(lval->as_long());
-
- /* Detect reversed indices of a part select. */
- if (lidx > midx) {
- cerr << get_line() << ": error: Part select "
- << sig->name() << "[" << mval->as_long() << ":"
- << lval->as_long() << "] indices reversed." << endl;
- cerr << get_line() << ": : Did you mean "
- << sig->name() << "[" << lval->as_long() << ":"
- << mval->as_long() << "]?" << endl;
- unsigned tmp = midx;
- midx = lidx;
- lidx = tmp;
- des->errors += 1;
- }
+ switch (sel_) {
+ default:
+ cerr << get_line() << ": internal error: "
+ << "Unexpected sel_ value = " << sel_ << endl;
+ assert(0);
+ break;
- /* Detect a part select out of range. */
- if (midx >= sig->vector_width()) {
- cerr << get_line() << ": error: Part select "
- << sig->name() << "[" << mval->as_long() << ":"
- << lval->as_long() << "] out of range." << endl;
- midx = sig->vector_width() - 1;
- lidx = 0;
- des->errors += 1;
- }
+ case PEIdent::SEL_IDX_DO:
+ case PEIdent::SEL_IDX_UP: {
+ assert(msb_);
+ assert(lsb_);
+ assert(idx_.empty());
- } else if (!idx_.empty()) {
- assert(msb_ == 0);
- assert(lsb_ == 0);
- assert(idx_.size() == 1);
- verinum*mval = idx_[0]->eval_const(des, scope);
- if (mval == 0) {
- cerr << get_line() << ": error: Index of " << path_ <<
- " needs to be constant in this context." <<
- endl;
- cerr << get_line() << ": : Index expression is: "
- << *(idx_[0]) << endl;
- des->errors += 1;
- return false;
- }
- assert(mval);
+ NetExpr*tmp_ex = elab_and_eval(des, scope, msb_);
+ NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
+ assert(tmp);
- midx = sig->sb_to_idx(mval->as_long());
- if (midx >= sig->vector_width()) {
- cerr << get_line() << ": error: Index " << sig->name()
- << "[" << mval->as_long() << "] out of range."
- << endl;
- des->errors += 1;
- midx = 0;
- }
- lidx = midx;
+ long midx_val = tmp->value().as_long();
+ midx = sig->sb_to_idx(midx_val);
+ delete tmp_ex;
- } else {
- assert(msb_ == 0 && lsb_ == 0);
- midx = sig->vector_width() - 1;
- lidx = 0;
+ 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. */
+ if (lidx > midx) {
+ cerr << get_line() << ": error: Part select "
+ << sig->name() << "[" << midx_val << ":"
+ << lidx_val << "] indices reversed." << endl;
+ cerr << get_line() << ": : Did you mean "
+ << sig->name() << "[" << lidx_val << ":"
+ << midx_val << "]?" << endl;
+ unsigned tmp = midx;
+ midx = lidx;
+ lidx = tmp;
+ des->errors += 1;
+ }
+
+ /* Detect a part select out of range. */
+ if (midx >= sig->vector_width()) {
+ cerr << get_line() << ": error: Part select "
+ << sig->name() << "[" << midx_val << ":"
+ << midx_val << "] out of range." << endl;
+ midx = sig->vector_width() - 1;
+ lidx = 0;
+ des->errors += 1;
+ }
+ break;
+ }
+
+ case PEIdent::SEL_NONE:
+ if (!idx_.empty()) {
+ assert(msb_ == 0);
+ assert(lsb_ == 0);
+ assert(idx_.size() == 1);
+ verinum*mval = idx_[0]->eval_const(des, scope);
+ if (mval == 0) {
+ cerr << get_line() << ": error: Index of " << path_ <<
+ " needs to be constant in this context." <<
+ endl;
+ cerr << get_line() << ": : Index expression is: "
+ << *(idx_[0]) << endl;
+ des->errors += 1;
+ return false;
+ }
+ assert(mval);
+
+ midx = sig->sb_to_idx(mval->as_long());
+ if (midx >= sig->vector_width()) {
+ cerr << get_line() << ": error: Index " << sig->name()
+ << "[" << mval->as_long() << "] out of range."
+ << endl;
+ des->errors += 1;
+ midx = 0;
+ }
+ lidx = midx;
+
+ } 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);
+ midx = sig->vector_width() - 1;
+ lidx = 0;
+ }
+ break;
}
return true;
@@ -2662,6 +2731,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
/*
* $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
* Clean up index expression error message.
*
View
4 parse.y
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#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
# include "config.h"
@@ -1287,6 +1287,7 @@ indexed_identifier
}
| indexed_identifier '[' expression ']'
{ PEIdent*tmp = $1;
+ tmp->sel_ = PEIdent::SEL_NONE;
tmp->idx_.push_back($3);
$$ = tmp;
}
@@ -2224,6 +2225,7 @@ port_reference
}
wtmp->msb_ = $3;
wtmp->lsb_ = $5;
+ wtmp->sel_ = PEIdent::SEL_PART;
Module::port_t*ptmp = new Module::port_t;
ptmp->name = perm_string();
ptmp->expr = svector<PEIdent*>(1);

0 comments on commit c2ff3d5

Please sign in to comment.
Something went wrong with that request. Please try again.