Handle bit/part select of array words in nets.
This commit is contained in:
parent
c7d97f4146
commit
129a064e1a
18
PExpr.h
18
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 <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.
|
||||
|
|
|
|||
64
elab_net.cc
64
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="<<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.
|
||||
*
|
||||
|
|
|
|||
15
elaborate.cc
15
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(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.
|
||||
*
|
||||
|
|
|
|||
8
parse.y
8
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<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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue