elaborate complex l-values

This commit is contained in:
steve 2000-09-10 02:18:16 +00:00
parent b6ce313e91
commit 8a69c54886
5 changed files with 270 additions and 142 deletions

View File

@ -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
*/ */
#if !defined(WINNT) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: design_dump.cc,v 1.95 2000/09/02 20:54:20 steve Exp $" #ident "$Id: design_dump.cc,v 1.96 2000/09/10 02:18:16 steve Exp $"
#endif #endif
/* /*
@ -422,41 +422,43 @@ void NetProcTop::dump(ostream&o, unsigned ind) const
statement_->dump(o, ind+2); statement_->dump(o, ind+2);
} }
void NetAssignBase::dump_lval(ostream&o) const
{
o << "" << "{" << lval_->name();
if (lval_->bmux())
o << "[" << *lval_->bmux() << "]";
for (NetAssign_*cur = lval_->more ; cur ; cur = cur->more) {
o << ", " << cur->name();
if (cur->bmux())
o << "[" << *cur->bmux() << "]";
}
o << "}";
}
/* Dump an assignment statement */ /* Dump an assignment statement */
void NetAssign::dump(ostream&o, unsigned ind) const void NetAssign::dump(ostream&o, unsigned ind) const
{ {
o << setw(ind) << ""; o << setw(ind) << "";
dump_lval(o);
if (l_val(0)->bmux()) { o << " = ";
o << l_val(0)->name() << "[" << *l_val(0)->bmux() << "] = ";
if (l_val(0)->rise_time()) if (l_val(0)->rise_time())
o << "#" << l_val(0)->rise_time() << " "; o << "#" << l_val(0)->rise_time() << " ";
o << *rval() << ";" << endl; o << *rval() << ";" << endl;
} else {
o << l_val(0)->name() << " = ";
if (l_val(0)->rise_time())
o << "#" << l_val(0)->rise_time() << " ";
o << *rval() << ";" << endl;
}
} }
void NetAssignNB::dump(ostream&o, unsigned ind) const void NetAssignNB::dump(ostream&o, unsigned ind) const
{ {
o << setw(ind) << ""; o << setw(ind) << "";
dump_lval(o);
if (l_val(0)->bmux()) { o << " <= ";
o << l_val(0)->name() << "[" << *l_val(0)->bmux() << "] <= ";
if (l_val(0)->rise_time()) if (l_val(0)->rise_time())
o << "#" << l_val(0)->rise_time() << " "; o << "#" << l_val(0)->rise_time() << " ";
o << *rval() << ";" << endl; o << *rval() << ";" << endl;
} else {
o << l_val(0)->name() << " <= ";
if (l_val(0)->rise_time())
o << "#" << l_val(0)->rise_time() << " ";
o << *rval() << ";" << endl;
}
} }
void NetAssignMem::dump(ostream&o, unsigned ind) const void NetAssignMem::dump(ostream&o, unsigned ind) const
@ -967,6 +969,9 @@ void Design::dump(ostream&o) const
/* /*
* $Log: design_dump.cc,v $ * $Log: design_dump.cc,v $
* Revision 1.96 2000/09/10 02:18:16 steve
* elaborate complex l-values
*
* Revision 1.95 2000/09/02 20:54:20 steve * Revision 1.95 2000/09/02 20:54:20 steve
* Rearrange NetAssign to make NetAssign_ separate. * Rearrange NetAssign to make NetAssign_ separate.
* *

View File

@ -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
*/ */
#if !defined(WINNT) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_lval.cc,v 1.1 2000/09/09 15:21:26 steve Exp $" #ident "$Id: elab_lval.cc,v 1.2 2000/09/10 02:18:16 steve Exp $"
#endif #endif
# include "PExpr.h" # include "PExpr.h"
@ -79,23 +79,31 @@ NetAssign_* PExpr::elaborate_lval(Design*des, NetScope*scope) const
/* /*
* Concatenation expressions can appear as l-values. Handle them here. * Concatenation expressions can appear as l-values. Handle them here.
* XXXX For now, cheat and use elaborate_net to cope.
*/ */
NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
{ {
#if 0
NetNet*ll = elaborate_net(des, scope->name(), 0, 0, 0, 0, NetNet*ll = elaborate_net(des, scope->name(), 0, 0, 0, 0,
Link::STRONG, Link::STRONG); Link::STRONG, Link::STRONG);
if (ll == 0) { if (ll != 0) {
cerr << get_line() << ": Assignment l-value too complex." NetAssign_*lv = new NetAssign_(scope->local_symbol(),
<< endl; ll->pin_count());
return 0;
}
NetAssign_*lv = new NetAssign_(scope->local_symbol(), ll->pin_count());
for (unsigned idx = 0 ; idx < ll->pin_count() ; idx += 1) for (unsigned idx = 0 ; idx < ll->pin_count() ; idx += 1)
connect(lv->pin(idx), ll->pin(idx)); connect(lv->pin(idx), ll->pin(idx));
des->add_node(lv); des->add_node(lv);
return lv; return lv;
}
#endif
NetAssign_*res = 0;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope);
assert(tmp);
tmp->more = res;
res = tmp;
}
return res;
} }
/* /*
@ -195,7 +203,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
NetAssign_ the width of the target reg and attach a NetAssign_ the width of the target reg and attach a
bmux to select the target bit. */ bmux to select the target bit. */
unsigned wid = reg->pin_count(); unsigned wid = reg->pin_count();
lv = new NetAssign_(scope->local_symbol(), wid); lv = new NetAssign_(des->local_symbol(scope->name()), wid);
for (unsigned idx = 0 ; idx < wid ; idx += 1) for (unsigned idx = 0 ; idx < wid ; idx += 1)
connect(lv->pin(idx), reg->pin(idx)); connect(lv->pin(idx), reg->pin(idx));
@ -210,7 +218,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
unsigned wid = (msb >= lsb)? (msb-lsb+1) : (lsb-msb+1); unsigned wid = (msb >= lsb)? (msb-lsb+1) : (lsb-msb+1);
assert(wid <= reg->pin_count()); assert(wid <= reg->pin_count());
lv = new NetAssign_(scope->local_symbol(), wid); lv = new NetAssign_(des->local_symbol(scope->name()), wid);
unsigned off = reg->sb_to_idx(lsb); unsigned off = reg->sb_to_idx(lsb);
assert((off+wid) <= reg->pin_count()); assert((off+wid) <= reg->pin_count());
for (unsigned idx = 0 ; idx < wid ; idx += 1) for (unsigned idx = 0 ; idx < wid ; idx += 1)
@ -226,6 +234,9 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
/* /*
* $Log: elab_lval.cc,v $ * $Log: elab_lval.cc,v $
* Revision 1.2 2000/09/10 02:18:16 steve
* elaborate complex l-values
*
* Revision 1.1 2000/09/09 15:21:26 steve * Revision 1.1 2000/09/09 15:21:26 steve
* move lval elaboration to PExpr virtual methods. * move lval elaboration to PExpr virtual methods.
* *

View File

@ -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
*/ */
#if !defined(WINNT) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_assign.cc,v 1.3 2000/09/07 00:06:53 steve Exp $" #ident "$Id: net_assign.cc,v 1.4 2000/09/10 02:18:16 steve Exp $"
#endif #endif
# include "netlist.h" # include "netlist.h"
@ -34,10 +34,12 @@ NetAssign_::NetAssign_(const string&n, unsigned w)
pin(idx).set_name("P", idx); pin(idx).set_name("P", idx);
} }
more = 0;
} }
NetAssign_::~NetAssign_() NetAssign_::~NetAssign_()
{ {
assert( more == 0 );
if (bmux_) delete bmux_; if (bmux_) delete bmux_;
} }
@ -66,7 +68,12 @@ NetAssignBase::NetAssignBase(NetAssign_*lv, NetExpr*rv)
NetAssignBase::~NetAssignBase() NetAssignBase::~NetAssignBase()
{ {
if (rval_) delete rval_; if (rval_) delete rval_;
if (lval_) delete lval_; while (lval_) {
NetAssign_*tmp = lval_;
lval_ = tmp->more;
tmp->more = 0;
delete tmp;
}
} }
NetExpr* NetAssignBase::rval() NetExpr* NetAssignBase::rval()
@ -87,20 +94,40 @@ void NetAssignBase::set_rval(NetExpr*r)
NetAssign_* NetAssignBase::l_val(unsigned idx) NetAssign_* NetAssignBase::l_val(unsigned idx)
{ {
NetAssign_*cur = lval_;
while (idx > 0) {
if (cur == 0)
return cur;
cur = cur->more;
idx -= 1;
}
assert(idx == 0); assert(idx == 0);
return lval_; return cur;
} }
const NetAssign_* NetAssignBase::l_val(unsigned idx) const const NetAssign_* NetAssignBase::l_val(unsigned idx) const
{ {
const NetAssign_*cur = lval_;
while (idx > 0) {
if (cur == 0)
return cur;
cur = cur->more;
idx -= 1;
}
assert(idx == 0); assert(idx == 0);
return lval_; return cur;
} }
unsigned NetAssignBase::lwidth() const unsigned NetAssignBase::lwidth() const
{ {
assert(lval_); unsigned sum = 0;
return lval_->lwidth(); for (NetAssign_*cur = lval_ ; cur ; cur = cur->more)
sum += cur->lwidth();
return sum;
} }
@ -124,6 +151,9 @@ NetAssignNB::~NetAssignNB()
/* /*
* $Log: net_assign.cc,v $ * $Log: net_assign.cc,v $
* Revision 1.4 2000/09/10 02:18:16 steve
* elaborate complex l-values
*
* Revision 1.3 2000/09/07 00:06:53 steve * Revision 1.3 2000/09/07 00:06:53 steve
* encapsulate access to the l-value expected width. * encapsulate access to the l-value expected width.
* *

View File

@ -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
*/ */
#if !defined(WINNT) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netlist.h,v 1.161 2000/09/07 00:06:53 steve Exp $" #ident "$Id: netlist.h,v 1.162 2000/09/10 02:18:16 steve Exp $"
#endif #endif
/* /*
@ -1128,6 +1128,11 @@ class NetProc : public LineInfo {
* assignment has its effect. The NetAssign_ class is not to be * assignment has its effect. The NetAssign_ class is not to be
* derived from. * derived from.
* *
* The collection is arranged from lsb up to msb, and represents the
* concatenation of l-values. The elaborator may collapse some
* concatenations into a single NetAssign_. The "more" member of the
* NetAssign_ object points to the next most significant bits of l-value.
*
* NOTE: The elaborator will make an effort to match the width of the * NOTE: The elaborator will make an effort to match the width of the
* r-value to the with of the l-value, but targets and functions * r-value to the with of the l-value, but targets and functions
* should know that this is not a guarantee. * should know that this is not a guarantee.
@ -1154,6 +1159,9 @@ class NetAssign_ : public NetNode {
virtual bool emit_node(struct target_t*) const; virtual bool emit_node(struct target_t*) const;
virtual void dump_node(ostream&, unsigned ind) const; virtual void dump_node(ostream&, unsigned ind) const;
// This pointer is for keeping simple lists.
NetAssign_* more;
private: private:
NetExpr*bmux_; NetExpr*bmux_;
}; };
@ -1178,6 +1186,8 @@ class NetAssignBase : public NetProc {
// accounts for any grouping of NetAssign_ objects that might happen. // accounts for any grouping of NetAssign_ objects that might happen.
unsigned lwidth() const; unsigned lwidth() const;
void dump_lval(ostream&) const;
private: private:
NetAssign_*lval_; NetAssign_*lval_;
NetExpr *rval_; NetExpr *rval_;
@ -2752,6 +2762,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/* /*
* $Log: netlist.h,v $ * $Log: netlist.h,v $
* Revision 1.162 2000/09/10 02:18:16 steve
* elaborate complex l-values
*
* Revision 1.161 2000/09/07 00:06:53 steve * Revision 1.161 2000/09/07 00:06:53 steve
* encapsulate access to the l-value expected width. * encapsulate access to the l-value expected width.
* *

213
t-vvm.cc
View File

@ -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
*/ */
#if !defined(WINNT) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: t-vvm.cc,v 1.172 2000/09/08 17:08:10 steve Exp $" #ident "$Id: t-vvm.cc,v 1.173 2000/09/10 02:18:16 steve Exp $"
#endif #endif
# include <iostream> # include <iostream>
@ -174,6 +174,10 @@ class target_vvm : public target_t {
virtual void net_probe(const NetEvProbe*); virtual void net_probe(const NetEvProbe*);
virtual bool process(const NetProcTop*); virtual bool process(const NetProcTop*);
virtual void proc_assign(const NetAssign*); virtual void proc_assign(const NetAssign*);
void proc_assign_rval(const NetAssign_*, const NetEConst*,
unsigned off);
void proc_assign_rval(const NetAssign_*, const string&,
unsigned wid, unsigned off);
virtual void proc_assign_mem(const NetAssignMem*); virtual void proc_assign_mem(const NetAssignMem*);
virtual void proc_assign_nb(const NetAssignNB*); virtual void proc_assign_nb(const NetAssignNB*);
virtual void proc_assign_mem_nb(const NetAssignMemNB*); virtual void proc_assign_mem_nb(const NetAssignMemNB*);
@ -2140,39 +2144,46 @@ void target_vvm::start_process(ostream&os, const NetProcTop*proc)
} }
/* /*
* This method generates code for a procedural assignment. The lval is * This method handles the special case of the assignment of a
* a signal, but the assignment should generate code to go to all the * constant r-value to the l-value. In this case, I can set specific
* connected devices/events. * values to each of the bits instead of calculating bit values or
* even reading values from a vpip_bit_t elsewhere.
*/ */
void target_vvm::proc_assign(const NetAssign*net) void target_vvm::proc_assign_rval(const NetAssign_*lv,
const NetEConst*rv,
unsigned off)
{ {
const verinum value = rv->value();
/* Detect the very special (and very common) case that the /* This condition catches the special case of assigning to a
rvalue is a constant in this assignment. I this case, there non-constant bit select. This cal be something like:
is no reason to go scan the expression, and in the process
generate bunches of temporaries. */
if (const NetEConst*rc = dynamic_cast<const NetEConst*>(net->rval())) { a[idx] = x;
const verinum value = rc->value(); For this sort of assignment, I only need a single bit of
the r-value. That bit is written into a single bit of the
target using a generated switch statement, where each case
of the switch assignes to a specific nexus. This is not
unreasonable because there aren't typically all that many
bits in the l-value. */
if (net->l_val(0)->bmux()) { if (lv->bmux()) {
// This is a bit select. Assign the low bit of the // This is a bit select. Assign the low bit of the
// constant to the selected bit of the lval. // constant to the selected bit of the lval.
const char*rval = vvm_val_name(value.get(0), const char*rval = vvm_val_name(value.get(off),
Link::STRONG, Link::STRONG,
Link::STRONG); Link::STRONG);
string bval = emit_proc_rval(this, net->l_val(0)->bmux()); string bval = emit_proc_rval(this, lv->bmux());
defn << " switch (" << bval defn << " switch (" << bval
<< ".as_unsigned()) {" << endl; << ".as_unsigned()) {" << endl;
for (unsigned idx = 0; idx < net->l_val(0)->pin_count(); idx += 1) { for (unsigned idx = 0; idx < lv->pin_count(); idx += 1) {
string nexus = net->l_val(0)->pin(idx).nexus()->name(); string nexus = lv->pin(idx).nexus()->name();
unsigned ncode = nexus_wire_map[nexus]; unsigned ncode = nexus_wire_map[nexus];
defn << " case " << idx << ":" << endl; defn << " case " << idx << ":" << endl;
@ -2187,20 +2198,110 @@ void target_vvm::proc_assign(const NetAssign*net)
return; return;
} }
for (unsigned idx = 0 ; idx < net->l_val(0)->pin_count() ; idx += 1) {
string nexus = net->l_val(0)->pin(idx).nexus()->name(); /* We've handled the case of bit selects, so here we know that
we are doing a good ol' assignment to an l-value. So for
the entire width of the l-value, assign constant bit values
to the appropriate nexus. */
for (unsigned idx = 0 ; idx < lv->pin_count() ; idx += 1) {
string nexus = lv->pin(idx).nexus()->name();
unsigned ncode = nexus_wire_map[nexus]; unsigned ncode = nexus_wire_map[nexus];
verinum::V val = idx < value.len() verinum::V val = (idx+off) < value.len()
? value.get(idx) ? value.get(idx+off)
: verinum::V0; : verinum::V0;
const char*rval = vvm_val_name(val, const char*rval = vvm_val_name(val, Link::STRONG, Link::STRONG);
Link::STRONG,
Link::STRONG);
defn << " nexus_wire_table[" <<ncode<< "]" defn << " nexus_wire_table[" <<ncode<< "]"
<< ".reg_assign(" << rval << ");" << endl; << ".reg_assign(" << rval << ");" << endl;
} }
}
/*
* This method does the grunt work of generating an assignment given a
* generated rval result.
*/
void target_vvm::proc_assign_rval(const NetAssign_*lv,
const string&rval,
unsigned wid, unsigned off)
{
assert(lv);
/* Now, if there is a mux on the l-value, generate a code to
assign a single bit to one of the bits of the
l-value. Otherwise, generate code for a complete
assignment. */
if (lv->bmux()) {
// This is a bit select. Assign the low bit of the rval
// to the selected bit of the lval.
string bval = emit_proc_rval(this, lv->bmux());
defn << " switch (" << bval << ".as_unsigned()) {" << endl;
for (unsigned idx = 0 ; idx < lv->pin_count() ; idx += 1) {
string nexus = lv->pin(idx).nexus()->name();
unsigned ncode = nexus_wire_map[nexus];
defn << " case " << idx << ":" << endl;
defn << " nexus_wire_table["<<ncode<<"]"
<< ".reg_assign(" << rval << "["<<off<<"]);" << endl;
defn << " break;" << endl;
}
defn << " }" << endl;
} else {
unsigned min_count = lv->pin_count();
if ((wid-off) < min_count)
min_count = wid - off;
for (unsigned idx = 0 ; idx < min_count ; idx += 1) {
string nexus = lv->pin(idx).nexus()->name();
unsigned ncode = nexus_wire_map[nexus];
defn << " nexus_wire_table["<<ncode<<"].reg_assign("
<< rval << "[" << (idx+off) << "]);" << endl;
}
for (unsigned idx = min_count; idx < lv->pin_count(); idx += 1) {
string nexus = lv->pin(idx).nexus()->name();
unsigned ncode = nexus_wire_map[nexus];
defn << " nexus_wire_table["<<ncode<<"]"
<< ".reg_assign(St0);" << endl;
}
}
}
/*
* This method generates code for a procedural assignment. The lval is
* a signal, but the assignment should generate code to go to all the
* connected devices/events.
*/
void target_vvm::proc_assign(const NetAssign*net)
{
/* Detect the very special (and very common) case that the
rvalue is a constant value. In this case, there is no
reason to go scan the expression, and in the process
generate bunches of temporaries. */
if (const NetEConst*rc = dynamic_cast<const NetEConst*>(net->rval())) {
const NetAssign_*cur = net->l_val(0);
unsigned off = 0;
unsigned idx = 0;
while (cur != 0) {
proc_assign_rval(cur, rc, off);
off += cur->lwidth();
idx += 1;
cur = net->l_val(idx);
}
return; return;
} }
@ -2218,12 +2319,11 @@ void target_vvm::proc_assign(const NetAssign*net)
if (const NetESignal*rs = dynamic_cast<const NetESignal*>(net->rval())) { if (const NetESignal*rs = dynamic_cast<const NetESignal*>(net->rval())) {
if (net->l_val(0)->pin_count() > rs->pin_count()) { if (net->lwidth() > rs->pin_count()) {
rval = emit_proc_rval(this, net->rval()); rval = emit_proc_rval(this, net->rval());
} else { } else {
assert((net->l_val(0)->pin_count() <= rs->pin_count())
|| (net->l_val(0)->bmux() && (rs->pin_count() >= 1)));
rval = mangle(rs->name()) + ".bits"; rval = mangle(rs->name()) + ".bits";
} }
@ -2235,52 +2335,15 @@ void target_vvm::proc_assign(const NetAssign*net)
defn << " // " << net->get_line() << ": " << endl; defn << " // " << net->get_line() << ": " << endl;
{ const NetAssign_*cur = net->l_val(0);
/* Now, if there is a mux on the l-value, generate a code to unsigned wid = net->rval()->expr_width();
assign a single bit to one of the bits of the unsigned off = 0;
l-value. Otherwise, generate code for a complete unsigned idx = 0;
assignment. */ while (cur != 0) {
proc_assign_rval(cur, rval, wid, off);
if (net->l_val(0)->bmux()) { off += cur->lwidth();
idx += 1;
// This is a bit select. Assign the low bit of the rval cur = net->l_val(idx);
// to the selected bit of the lval.
string bval = emit_proc_rval(this, net->l_val(0)->bmux());
defn << " switch (" << bval << ".as_unsigned()) {" << endl;
for (unsigned idx = 0 ; idx < net->l_val(0)->pin_count() ; idx += 1) {
string nexus = net->l_val(0)->pin(idx).nexus()->name();
unsigned ncode = nexus_wire_map[nexus];
defn << " case " << idx << ":" << endl;
defn << " nexus_wire_table["<<ncode<<"]"
<< ".reg_assign(" << rval << "[0]);" << endl;
defn << " break;" << endl;
}
defn << " }" << endl;
} else {
unsigned min_count = net->l_val(0)->pin_count();
if (net->rval()->expr_width() < min_count)
min_count = net->rval()->expr_width();
for (unsigned idx = 0 ; idx < min_count ; idx += 1) {
string nexus = net->l_val(0)->pin(idx).nexus()->name();
unsigned ncode = nexus_wire_map[nexus];
defn << " nexus_wire_table["<<ncode<<"].reg_assign("
<< rval << "[" << idx << "]);" << endl;
}
for (unsigned idx = min_count; idx < net->l_val(0)->pin_count(); idx += 1) {
string nexus = net->l_val(0)->pin(idx).nexus()->name();
unsigned ncode = nexus_wire_map[nexus];
defn << " nexus_wire_table["<<ncode<<"]"
<< ".reg_assign(St0);" << endl;
} }
} }
} }
@ -2320,6 +2383,9 @@ void target_vvm::proc_assign_nb(const NetAssignNB*net)
string rval = emit_proc_rval(this, net->rval()); string rval = emit_proc_rval(this, net->rval());
const unsigned long delay = net->l_val(0)->rise_time(); const unsigned long delay = net->l_val(0)->rise_time();
// XXXX I cannot handle this yet.
assert(net->l_val(1) == 0);
if (net->l_val(0)->bmux()) { if (net->l_val(0)->bmux()) {
/* If the l-value has a bit select, set the output bit /* If the l-value has a bit select, set the output bit
to only the desired bit. Evaluate the index and use to only the desired bit. Evaluate the index and use
@ -3116,6 +3182,9 @@ extern const struct target tgt_vvm = {
}; };
/* /*
* $Log: t-vvm.cc,v $ * $Log: t-vvm.cc,v $
* Revision 1.173 2000/09/10 02:18:16 steve
* elaborate complex l-values
*
* Revision 1.172 2000/09/08 17:08:10 steve * Revision 1.172 2000/09/08 17:08:10 steve
* initialize vlog info. * initialize vlog info.
* *