diff --git a/PExpr.h b/PExpr.h index c1ad14840..9f2ae6c16 100644 --- a/PExpr.h +++ b/PExpr.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: PExpr.h,v 1.88 2007/05/24 04:07:11 steve Exp $" +#ident "$Id: PExpr.h,v 1.89 2007/06/04 02:19:07 steve Exp $" #endif # include @@ -343,18 +343,6 @@ class PEIdent : public PExpr { NetScope*found) const; public: -#if 0 - // Use these to support part-select operators. - PExpr*msb_; - PExpr*lsb_; - - enum { SEL_NONE, SEL_PART, SEL_IDX_UP, SEL_IDX_DO } sel_; - - // If this is a reference to a memory/array, this is the index - // expression. If this is a reference to a vector, this is a - // bit select. - std::vector idx_; -#endif NetNet* elaborate_net_array_(Design*des, NetScope*scope, NetNet*sig, unsigned lwidth, @@ -381,6 +369,7 @@ class PEIdent : public PExpr { bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig, unsigned&midx, unsigned&lidx) const; + NetNet*process_select_(Design*des, NetScope*scope, NetNet*sig) const; }; @@ -668,6 +657,9 @@ class PECallFunction : public PExpr { /* * $Log: PExpr.h,v $ + * Revision 1.89 2007/06/04 02:19:07 steve + * Handle bit/part select of array words in nets. + * * Revision 1.88 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. diff --git a/elab_net.cc b/elab_net.cc index 5dc2be4c9..9a3a6a0e7 100644 --- a/elab_net.cc +++ b/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.205 2007/06/02 03:42:12 steve Exp $" +#ident "$Id: elab_net.cc,v 1.206 2007/06/04 02:19:07 steve Exp $" #endif # include "config.h" @@ -1758,6 +1758,45 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope, return sig; } +NetNet* PEIdent::process_select_(Design*des, NetScope*scope, + NetNet*sig) const +{ + + // If there are more index items then there are array + // dimensions, then treat them as word part selects. For + // example, if this is a memory array, then array dimensions + // is 1 and + unsigned midx, lidx; + if (! eval_part_select_(des, scope, sig, midx, lidx)) + return sig; + + unsigned part_count = midx-lidx+1; + + // Maybe this is a full-width constant part select? If + // so, do nothing. + if (part_count == sig->vector_width()) + return sig; + + if (debug_elaborate) { + cerr << get_line() << ": debug: Elaborate part select" + << " of word from " << sig->name() << "[base="<set_line(*sig); + des->add_node(ps); + + NetNet*tmp = new NetNet(scope, scope->local_symbol(), + NetNet::WIRE, part_count-1, 0); + tmp->data_type( sig->data_type() ); + tmp->local_flag(true); + connect(tmp->pin(0), ps->pin(0)); + + return tmp; +} + NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope, NetNet*sig, unsigned lwidth, const NetExpr* rise, @@ -1773,6 +1812,10 @@ NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope, ivl_assert(*this, index_head.msb != 0); ivl_assert(*this, index_head.lsb == 0); + if (debug_elaborate) + cerr << get_line() << ": debug: elaborate array " + << name_tail.name << " with index " << index_head << endl; + NetExpr*index_ex = elab_and_eval(des, scope, index_head.msb, -1); if (index_ex == 0) return 0; @@ -1812,6 +1855,12 @@ NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope, tmp->local_flag(true); tmp->data_type(sig->data_type()); connect(tmp->pin(0), sig->pin(index)); + + // If there are more indices then needed to get to the + // word, then there is a part/bit select for the word. + if (name_tail.index.size() > sig->array_dimensions()) + tmp = process_select_(des, scope, tmp); + return tmp; } @@ -1836,6 +1885,7 @@ NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope, tmp->local_flag(true); tmp->data_type(sig->data_type()); connect(tmp->pin(0), mux->pin_Result()); +#if 0 // If there are more index items then there are array // dimensions, then treat them as word part selects. For @@ -1870,7 +1920,11 @@ NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope, tmp = tmp2; } while (0); +#else + if (name_tail.index.size() > sig->array_dimensions()) + tmp = process_select_(des, scope, sig); +#endif return tmp; } @@ -2160,14 +2214,13 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig, case index_component_t::SEL_BIT: if (name_tail.index.size() > sig->array_dimensions()) { - const index_component_t&index_head = name_tail.index.front(); - verinum*mval = index_head.msb->eval_const(des, scope); + verinum*mval = index_tail.msb->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: " - << *index_head.msb << endl; + << *index_tail.msb << endl; des->errors += 1; return false; } @@ -2963,6 +3016,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, /* * $Log: elab_net.cc,v $ + * Revision 1.206 2007/06/04 02:19:07 steve + * Handle bit/part select of array words in nets. + * * Revision 1.205 2007/06/02 03:42:12 steve * Properly evaluate scope path expressions. * diff --git a/elaborate.cc b/elaborate.cc index 99a57587f..a44c56717 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elaborate.cc,v 1.372 2007/06/02 03:42:12 steve Exp $" +#ident "$Id: elaborate.cc,v 1.373 2007/06/04 02:19:07 steve Exp $" #endif # include "config.h" @@ -123,8 +123,14 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const return; } - assert(rid); - assert(rid->pin_count() == 1); + ivl_assert(*this, rid); + if (rid->pin_count() != 1) { + cerr << get_line() << ": internal error: " + << "Invalid elaborate_net results here:" << endl; + rid->dump_net(cerr, 4); + des->errors += 1; + } + ivl_assert(*this, rid->pin_count() == 1); /* If the right hand net is the same type as the left side net (i.e., WIRE/WIRE) then it is enough to just @@ -3420,6 +3426,9 @@ Design* elaborate(listroots) /* * $Log: elaborate.cc,v $ + * Revision 1.373 2007/06/04 02:19:07 steve + * Handle bit/part select of array words in nets. + * * Revision 1.372 2007/06/02 03:42:12 steve * Properly evaluate scope path expressions. * diff --git a/parse.y b/parse.y index e025fec99..4c598d4a8 100644 --- a/parse.y +++ b/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.237 2007/05/24 04:07:12 steve Exp $" +#ident "$Id: parse.y,v 1.238 2007/06/04 02:19:07 steve Exp $" #endif # include "config.h" @@ -3588,7 +3588,7 @@ udp_port_decl { $$ = pform_make_udp_input_ports($2); } | K_output IDENTIFIER ';' { pform_name_t pname; - pname.push_back(lex_strings.make($2)); + pname.push_back(name_component_t(lex_strings.make($2))); PWire*pp = new PWire(pname, NetNet::IMPLICIT, NetNet::POUTPUT, IVL_VT_LOGIC); svector*tmp = new svector(1); (*tmp)[0] = pp; @@ -3597,7 +3597,7 @@ udp_port_decl } | K_reg IDENTIFIER ';' { pform_name_t pname; - pname.push_back(lex_strings.make($2)); + pname.push_back(name_component_t(lex_strings.make($2))); PWire*pp = new PWire(pname, NetNet::REG, NetNet::PIMPLICIT, IVL_VT_LOGIC); svector*tmp = new svector(1); (*tmp)[0] = pp; @@ -3606,7 +3606,7 @@ udp_port_decl } | K_reg K_output IDENTIFIER ';' { pform_name_t pname; - pname.push_back(lex_strings.make($3)); + pname.push_back(name_component_t(lex_strings.make($3))); PWire*pp = new PWire(pname, NetNet::REG, NetNet::POUTPUT, IVL_VT_LOGIC); svector*tmp = new svector(1); (*tmp)[0] = pp; diff --git a/pform_dump.cc b/pform_dump.cc index f18fcf7e3..8f97a3485 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: pform_dump.cc,v 1.100 2007/06/02 03:42:13 steve Exp $" +#ident "$Id: pform_dump.cc,v 1.101 2007/06/04 02:19:07 steve Exp $" #endif # include "config.h" @@ -78,6 +78,30 @@ ostream& operator<< (ostream&out, perm_string that) return out; } +ostream& operator<< (ostream&out, const index_component_t&that) +{ + out << "["; + switch (that.sel) { + case index_component_t::SEL_BIT: + out << *that.msb; + break; + case index_component_t::SEL_PART: + out << *that.msb << ":" << *that.lsb; + break; + case index_component_t::SEL_IDX_UP: + out << *that.msb << "+:" << *that.lsb; + break; + case index_component_t::SEL_IDX_DO: + out << *that.msb << "-:" << *that.lsb; + break; + default: + out << "???"; + break; + } + out << "]"; + return out; + } + ostream& operator<< (ostream&out, const name_component_t&that) { out << that.name.str(); @@ -86,25 +110,7 @@ ostream& operator<< (ostream&out, const name_component_t&that) for (index_it_t idx = that.index.begin() ; idx != that.index.end() ; idx++) { - out << "["; - switch ((*idx).sel) { - case index_component_t::SEL_BIT: - out << *(*idx).msb; - break; - case index_component_t::SEL_PART: - out << *(*idx).msb << ":" << *(*idx).lsb; - break; - case index_component_t::SEL_IDX_UP: - out << *(*idx).msb << "+:" << *(*idx).lsb; - break; - case index_component_t::SEL_IDX_DO: - out << *(*idx).msb << "-:" << *(*idx).lsb; - break; - default: - out << "???"; - break; - } - out << "]"; + out << *idx; } return out; } @@ -1067,6 +1073,9 @@ void PUdp::dump(ostream&out) const /* * $Log: pform_dump.cc,v $ + * Revision 1.101 2007/06/04 02:19:07 steve + * Handle bit/part select of array words in nets. + * * Revision 1.100 2007/06/02 03:42:13 steve * Properly evaluate scope path expressions. * diff --git a/pform_types.h b/pform_types.h index 94b15ee7d..151da1569 100644 --- a/pform_types.h +++ b/pform_types.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: pform_types.h,v 1.1 2007/05/24 04:07:12 steve Exp $" +#ident "$Id: pform_types.h,v 1.2 2007/06/04 02:19:07 steve Exp $" #endif // This for the perm_string type. @@ -43,7 +43,7 @@ struct index_component_t { }; struct name_component_t { - name_component_t(perm_string n) : name(n) { } + explicit name_component_t(perm_string n) : name(n) { } ~name_component_t() { } perm_string name; @@ -67,6 +67,8 @@ inline perm_string peek_tail_name(const pform_name_t&that) return that.back().name; } -extern std::ostream& operator<< (std::ostream&o, const pform_name_t&); +extern std::ostream& operator<< (std::ostream&out, const pform_name_t&); +extern std::ostream& operator<< (std::ostream&out, const name_component_t&that); +extern std::ostream& operator<< (std::ostream&out, const index_component_t&that); #endif