Handle bit/part select of array words in nets.

This commit is contained in:
steve 2007-06-04 02:19:07 +00:00
parent c7d97f4146
commit 129a064e1a
6 changed files with 115 additions and 47 deletions

18
PExpr.h
View File

@ -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 <string>
@ -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<PExpr*> 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.

View File

@ -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="<<lidx
<< " wid=" << part_count << "]" << endl;
}
NetPartSelect*ps = new NetPartSelect(sig, lidx, part_count,
NetPartSelect::VP);
ps->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.
*

View File

@ -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(list<perm_string>roots)
/*
* $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.
*

View File

@ -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<PWire*>*tmp = new svector<PWire*>(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<PWire*>*tmp = new svector<PWire*>(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<PWire*>*tmp = new svector<PWire*>(1);
(*tmp)[0] = pp;

View File

@ -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.
*

View File

@ -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