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; for (unsigned idx = 0 ; idx < ll->pin_count() ; idx += 1)
connect(lv->pin(idx), ll->pin(idx));
des->add_node(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;
} }
NetAssign_*lv = new NetAssign_(scope->local_symbol(), ll->pin_count()); return res;
for (unsigned idx = 0 ; idx < ll->pin_count() ; idx += 1)
connect(lv->pin(idx), ll->pin(idx));
des->add_node(lv);
return lv;
} }
/* /*
@ -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.
* *

265
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*);
@ -2139,6 +2143,140 @@ void target_vvm::start_process(ostream&os, const NetProcTop*proc)
<< endl << "{" << endl; << endl << "{" << endl;
} }
/*
* This method handles the special case of the assignment of a
* constant r-value to the l-value. In this case, I can set specific
* 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_rval(const NetAssign_*lv,
const NetEConst*rv,
unsigned off)
{
const verinum value = rv->value();
/* This condition catches the special case of assigning to a
non-constant bit select. This cal be something like:
a[idx] = x;
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 (lv->bmux()) {
// This is a bit select. Assign the low bit of the
// constant to the selected bit of the lval.
const char*rval = vvm_val_name(value.get(off),
Link::STRONG,
Link::STRONG);
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 << ");" << endl;
defn << " break;" << endl;
}
defn << " }" << endl;
return;
}
/* 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];
verinum::V val = (idx+off) < value.len()
? value.get(idx+off)
: verinum::V0;
const char*rval = vvm_val_name(val, Link::STRONG, Link::STRONG);
defn << " nexus_wire_table[" <<ncode<< "]"
<< ".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 * This method generates code for a procedural assignment. The lval is
* a signal, but the assignment should generate code to go to all the * a signal, but the assignment should generate code to go to all the
@ -2148,59 +2286,22 @@ void target_vvm::proc_assign(const NetAssign*net)
{ {
/* Detect the very special (and very common) case that the /* Detect the very special (and very common) case that the
rvalue is a constant in this assignment. I this case, there rvalue is a constant value. In this case, there is no
is no reason to go scan the expression, and in the process reason to go scan the expression, and in the process
generate bunches of temporaries. */ generate bunches of temporaries. */
if (const NetEConst*rc = dynamic_cast<const NetEConst*>(net->rval())) { if (const NetEConst*rc = dynamic_cast<const NetEConst*>(net->rval())) {
const verinum value = rc->value(); const NetAssign_*cur = net->l_val(0);
unsigned off = 0;
if (net->l_val(0)->bmux()) { unsigned idx = 0;
while (cur != 0) {
// This is a bit select. Assign the low bit of the proc_assign_rval(cur, rc, off);
// constant to the selected bit of the lval. off += cur->lwidth();
idx += 1;
const char*rval = vvm_val_name(value.get(0), cur = net->l_val(idx);
Link::STRONG,
Link::STRONG);
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 << ");" << endl;
defn << " break;" << endl;
}
defn << " }" << endl;
return;
} }
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];
verinum::V val = idx < value.len()
? value.get(idx)
: verinum::V0;
const char*rval = vvm_val_name(val,
Link::STRONG,
Link::STRONG);
defn << " nexus_wire_table[" <<ncode<< "]"
<< ".reg_assign(" << rval << ");" << endl;
}
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,53 +2335,16 @@ 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.
* *