Change the NetAssign_ class to refer to the signal

instead of link into the netlist. This is faster
 and uses less space. Make the NetAssignNB carry
 the delays instead of the NetAssign_ lval objects.

 Change the vvp code generator to support multiple
 l-values, i.e. concatenations of part selects.
This commit is contained in:
steve 2001-08-25 23:50:02 +00:00
parent 794ce68a6c
commit e35ed6e91c
18 changed files with 560 additions and 348 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: design_dump.cc,v 1.116 2001/07/27 04:51:44 steve Exp $"
#ident "$Id: design_dump.cc,v 1.117 2001/08/25 23:50:02 steve Exp $"
#endif
# include "config.h"
@ -237,15 +237,6 @@ void NetMux::dump_node(ostream&o, unsigned ind) const
dump_obj_attr(o, ind+4);
}
void NetAssign_::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Procedural assign (NetAssign_): " << name();
if (bmux())
o << "[" << *bmux() << "]";
o << endl;
dump_node_pins(o, ind+4);
}
void NetBUFZ::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "NetBUFZ: " << name()
@ -417,16 +408,29 @@ void NetProcTop::dump(ostream&o, unsigned ind) const
statement_->dump(o, ind+2);
}
void NetAssign_::dump_lval(ostream&o) const
{
if (sig_) {
o << sig_->name();
if (bmux_) {
o << "[" << *bmux_ << "]";
} else {
o << "[" << (loff_+lwid_-1) << ":" << loff_ << "]";
}
} else {
o << "";
}
}
void NetAssignBase::dump_lval(ostream&o) const
{
o << "" << "{" << lval_->name();
if (lval_->bmux())
o << "[" << *lval_->bmux() << "]";
o << "{";
lval_->dump_lval(o);
for (NetAssign_*cur = lval_->more ; cur ; cur = cur->more) {
o << ", " << cur->name();
if (cur->bmux())
o << "[" << *cur->bmux() << "]";
o << ", ";
cur->dump_lval(o);
}
o << "}";
@ -439,8 +443,10 @@ void NetAssign::dump(ostream&o, unsigned ind) const
dump_lval(o);
o << " = ";
#if 0
if (l_val(0)->rise_time())
o << "#" << l_val(0)->rise_time() << " ";
#endif
o << *rval() << ";" << endl;
}
@ -450,8 +456,10 @@ void NetAssignNB::dump(ostream&o, unsigned ind) const
dump_lval(o);
o << " <= ";
#if 0
if (l_val(0)->rise_time())
o << "#" << l_val(0)->rise_time() << " ";
#endif
o << *rval() << ";" << endl;
}
@ -960,6 +968,15 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.117 2001/08/25 23:50:02 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.116 2001/07/27 04:51:44 steve
* Handle part select expressions as variants of
* NetESignal/IVL_EX_SIGNAL objects, instead of

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elab_lval.cc,v 1.13 2001/07/25 03:10:48 steve Exp $"
#ident "$Id: elab_lval.cc,v 1.14 2001/08/25 23:50:02 steve Exp $"
#endif
# include "config.h"
@ -74,10 +74,7 @@ NetAssign_* PExpr::elaborate_lval(Design*des, NetScope*scope) const
return 0;
}
NetAssign_*lv = new NetAssign_(scope->local_symbol(), ll->pin_count());
for (unsigned idx = 0 ; idx < ll->pin_count() ; idx += 1)
connect(lv->pin(idx), ll->pin(idx));
des->add_node(lv);
NetAssign_*lv = new NetAssign_(ll);
return lv;
}
@ -116,42 +113,15 @@ NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
assert(tmp);
/* If adjacent l-values in the concatenation are not bit
selects, then merge them into a single NetAssign_
object.
If we cannot merge, then just link the new one to the
previous one. */
/* Link the new l-value to the previous one. */
if (res && (res->bmux() == 0) && (tmp->bmux() == 0)) {
unsigned wid1 = tmp->pin_count();
unsigned wid2 = res->pin_count() + tmp->pin_count();
NetAssign_*tmp2 = new NetAssign_(res->name(), wid2);
NetAssign_*last = tmp;
while (last->more)
last = last->more;
assert(tmp->more == 0);
tmp2->more = res->more;
res->more = 0;
for (unsigned idx = 0 ; idx < wid1 ; idx += 1)
connect(tmp2->pin(idx), tmp->pin(idx));
for (unsigned idx = 0 ; idx < res->pin_count() ; idx += 1)
connect(tmp2->pin(idx+wid1), res->pin(idx));
delete res;
delete tmp;
res = tmp2;
des->add_node(res);
} else {
NetAssign_*last = tmp;
while (last->more)
last = last->more;
last->more = res;
res = tmp;
}
last->more = res;
res = tmp;
}
return res;
@ -259,13 +229,9 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
if (mux) {
/* If there is a non-constant bit select, make a
NetAssign_ the width of the target reg and attach a
NetAssign_ to the target reg and attach a
bmux to select the target bit. */
unsigned wid = reg->pin_count();
lv = new NetAssign_(des->local_symbol(scope->name()), wid);
for (unsigned idx = 0 ; idx < wid ; idx += 1)
connect(lv->pin(idx), reg->pin(idx));
lv = new NetAssign_(reg);
lv->set_bmux(mux);
@ -278,8 +244,6 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
unsigned moff = reg->sb_to_idx(msb);
unsigned wid = moff - loff + 1;
lv = new NetAssign_(des->local_symbol(scope->name()), wid);
if (moff < loff) {
cerr << get_line() << ": error: part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
@ -301,20 +265,27 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
return 0;
}
assert(moff < reg->pin_count());
for (unsigned idx = 0 ; idx < wid ; idx += 1)
connect(lv->pin(idx), reg->pin(idx+loff));
lv = new NetAssign_(reg);
lv->set_part(loff, wid);
assert(moff < reg->pin_count());
}
des->add_node(lv);
return lv;
}
/*
* $Log: elab_lval.cc,v $
* Revision 1.14 2001/08/25 23:50:02 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.13 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: elaborate.cc,v 1.219 2001/08/01 05:17:31 steve Exp $"
#ident "$Id: elaborate.cc,v 1.220 2001/08/25 23:50:02 steve Exp $"
#endif
# include "config.h"
@ -927,12 +927,12 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const
if (rise_time || event_) {
string n = des->local_symbol(path);
unsigned wid = lv->pin_count();
unsigned wid = lv->lwidth();
rv->set_width(lv->pin_count());
rv = pad_to_width(rv, lv->pin_count());
rv->set_width(wid);
rv = pad_to_width(rv, wid);
if (! rv->set_width(lv->pin_count())) {
if (! rv->set_width(wid)) {
cerr << get_line() << ": error: Unable to match "
"expression width of " << rv->expr_width() <<
" to l-value width of " << wid << "." << endl;
@ -947,11 +947,7 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const
/* Generate an assignment of the l-value to the temporary... */
n = des->local_symbol(path);
NetAssign_*lvt = new NetAssign_(n, wid);
des->add_node(lvt);
for (unsigned idx = 0 ; idx < wid ; idx += 1)
connect(lvt->pin(idx), tmp->pin(idx));
NetAssign_*lvt = new NetAssign_(tmp);
NetAssign*a1 = new NetAssign(lvt, rv);
a1->set_line(*this);
@ -1078,13 +1074,12 @@ NetProc* PAssignNB::elaborate(Design*des, const string&path) const
unsigned long rise_time, fall_time, decay_time;
delay_.eval_delays(des, path, rise_time, fall_time, decay_time);
lv->rise_time(rise_time);
lv->fall_time(fall_time);
lv->decay_time(decay_time);
/* All done with this node. mark its line number and check it in. */
NetAssignNB*cur = new NetAssignNB(lv, rv);
cur->rise_time(rise_time);
cur->fall_time(fall_time);
cur->decay_time(decay_time);
cur->set_line(*this);
return cur;
}
@ -1409,10 +1404,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, const string&path) const
continue;
NetExpr*rv = parms_[idx]->elaborate_expr(des, scope);
NetAssign_*lv = new NetAssign_("@", port->pin_count());
des->add_node(lv);
for (unsigned pi = 0 ; pi < port->pin_count() ; pi += 1)
connect(port->pin(pi), lv->pin(pi));
NetAssign_*lv = new NetAssign_(port);
NetAssign*pr = new NetAssign(lv, rv);
block->append(pr);
}
@ -1971,10 +1963,7 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const
return 0;
}
assert(sig);
NetAssign_*lv = new NetAssign_("@for-assign", sig->pin_count());
for (unsigned idx = 0 ; idx < lv->pin_count() ; idx += 1)
connect(lv->pin(idx), sig->pin(idx));
des->add_node(lv);
NetAssign_*lv = new NetAssign_(sig);
/* Make the r-value of the initial assignment, and size it
properly. Then use it to build the assignment statement. */
@ -2001,10 +1990,7 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const
statement. Put this into the "body" block. */
sig = des->find_signal(scope, id2->name());
assert(sig);
lv = new NetAssign_("@for-assign", sig->pin_count());
for (unsigned idx = 0 ; idx < lv->pin_count() ; idx += 1)
connect(lv->pin(idx), sig->pin(idx));
des->add_node(lv);
lv = new NetAssign_(sig);
/* Make the rvalue of the increment expression, and size it
for the lvalue. */
@ -2362,6 +2348,15 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.220 2001/08/25 23:50:02 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.219 2001/08/01 05:17:31 steve
* Accept empty port lists to module instantiation.
*

17
emit.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: emit.cc,v 1.61 2001/07/27 04:51:44 steve Exp $"
#ident "$Id: emit.cc,v 1.62 2001/08/25 23:50:02 steve Exp $"
#endif
# include "config.h"
@ -57,12 +57,6 @@ bool NetAddSub::emit_node(struct target_t*tgt) const
return true;
}
bool NetAssign_::emit_node(struct target_t*tgt) const
{
tgt->net_assign(this);
return true;
}
bool NetCaseCmp::emit_node(struct target_t*tgt) const
{
tgt->net_case_cmp(this);
@ -476,6 +470,15 @@ bool emit(const Design*des, const char*type)
/*
* $Log: emit.cc,v $
* Revision 1.62 2001/08/25 23:50:02 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.61 2001/07/27 04:51:44 steve
* Handle part select expressions as variants of
* NetESignal/IVL_EX_SIGNAL objects, instead of

View File

@ -63,8 +63,10 @@ ivl_lpm_width
ivl_lval_idx
ivl_lval_mem
ivl_lval_mux
ivl_lval_part_off
ivl_lval_pin
ivl_lval_pins
ivl_lval_sig
ivl_memory_basename
ivl_memory_name

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: ivl_target.h,v 1.76 2001/08/10 00:40:45 steve Exp $"
#ident "$Id: ivl_target.h,v 1.77 2001/08/25 23:50:03 steve Exp $"
#endif
#ifdef __cplusplus
@ -551,11 +551,17 @@ extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net);
/* LVAL
* The l-values of assignments are concatenation of ivl_lval_t
* objects. Each l-value has a bunch of connections (in the form of
* ivl_nexus_t objects) and possibly a mux expression. The compiler
* takes care of part selects and nested concatenations. The
* ivl_stmt_lval function pulls ivl_lval_t objects out of the
* statement.
* objects. Each lvi_lval_t object is an assignment to a var or a
* memory, through a bit select, part select or word select.
*
* Var lvals are things like assignments to a part select or a bit
* select. Assignment to the whole variable is a special case of a
* part select, as is a bit select with a constant expression. The
* ivl_lval_pins statement returns the width of the part select for
* the lval. The ivl_lval_pin function returns the nexus to the N-th
* bit of the part select. The compiler takes care of positioning the
* part select so that ivl_lval_pin(net, 0) is the proper bit in the
* signal.
*
* ivl_lval_mux
* If the l-value includes a bit select expression, this method
@ -567,6 +573,14 @@ extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net);
* ivl_memory_t that represents that memory. Otherwise, it
* returns 0.
*
* ivl_lval_sig
* If the l-value is a variable, this method returns the signal
* object that is the target of the assign.
*
* ivl_lval_part_off
* The part select of the signal is based here. This is the
* canonical index of bit-0 of the part select.
*
* ivl_lval_idx
* If the l-value is a memory, this method returns an
* ivl_expr_t that represents the index expression. Otherwise, it
@ -576,14 +590,16 @@ extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net);
* Return an ivl_nexus_t for the connection of the ivl_lval_t.
*
* ivl_lval_pins
* Return the number of pins for this object. */
* Return the number of pins for this object.
*/
extern ivl_expr_t ivl_lval_mux(ivl_lval_t net);
extern ivl_expr_t ivl_lval_idx(ivl_lval_t net);
extern ivl_memory_t ivl_lval_mem(ivl_lval_t net);
extern unsigned ivl_lval_part_off(ivl_lval_t net);
extern unsigned ivl_lval_pins(ivl_lval_t net);
extern ivl_nexus_t ivl_lval_pin(ivl_lval_t net, unsigned idx);
extern ivl_signal_t ivl_lval_sig(ivl_lval_t net);
/* NEXUS
* connections of signals and nodes is handled by single-bit
@ -907,6 +923,15 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* Revision 1.77 2001/08/25 23:50:03 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.76 2001/08/10 00:40:45 steve
* tgt-vvp generates code that skips nets as inputs.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: link_const.cc,v 1.10 2001/07/25 03:10:49 steve Exp $"
#ident "$Id: link_const.cc,v 1.11 2001/08/25 23:50:03 steve Exp $"
#endif
# include "config.h"
@ -44,9 +44,18 @@ bool link_drivers_constant(const Link&lnk)
if (cur->get_dir() == Link::INPUT)
continue;
/* If this is an input or input port of a root module,
/* If this is an input or inout port of a root module,
then the is probably not a constant value. I
certainly don't know what the value is, anyhow. */
certainly don't know what the value is, anyhow. This
can happen in cases like this:
module main(sig);
input sig;
endmodule
If main is a root module (it has no parent) then sig
is not constant because it connects to an unspecified
outside world. */
if (sig = dynamic_cast<const NetNet*>(cur->get_obj())) do {
if (sig->port_type() == NetNet::NOT_A_PORT)
@ -63,7 +72,8 @@ bool link_drivers_constant(const Link&lnk)
/* If the link is PASSIVE then it doesn't count as a
driver if its initial value is Vz. */
driver if its initial value is Vz. PASSIVE nodes
include wires and tri nets. */
if (cur->get_dir() == Link::PASSIVE)
continue;
@ -113,6 +123,15 @@ verinum::V driven_value(const Link&lnk)
/*
* $Log: link_const.cc,v $
* Revision 1.11 2001/08/25 23:50:03 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.10 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_assign.cc,v 1.7 2001/07/25 03:10:49 steve Exp $"
#ident "$Id: net_assign.cc,v 1.8 2001/08/25 23:50:03 steve Exp $"
#endif
# include "config.h"
@ -38,19 +38,18 @@ unsigned count_lval_width(const NetAssign_*idx)
return wid;
}
NetAssign_::NetAssign_(const string&n, unsigned w)
: NetNode(n, w), bmux_(0)
NetAssign_::NetAssign_(NetNet*s)
: sig_(s), bmux_(0)
{
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
pin(idx).set_dir(Link::OUTPUT);
pin(idx).set_name("P", idx);
}
loff_ = 0;
lwid_ = sig_->pin_count();
sig_->incr_eref();
more = 0;
}
NetAssign_::~NetAssign_()
{
if (sig_) sig_->decr_eref();
assert( more == 0 );
if (bmux_) delete bmux_;
}
@ -69,7 +68,34 @@ const NetExpr* NetAssign_::bmux() const
unsigned NetAssign_::lwidth() const
{
if (bmux_) return 1;
else return pin_count();
else return lwid_;
}
const char*NetAssign_::name() const
{
if (sig_) {
return sig_->name();
} else {
return "";
}
}
NetNet* NetAssign_::sig() const
{
assert(sig_);
return sig_;
}
void NetAssign_::set_part(unsigned lo, unsigned lw)
{
loff_ = lo;
lwid_ = lw;
assert(sig_->pin_count() >= (lo + lw));
}
unsigned NetAssign_::get_loff() const
{
return loff_;
}
NetAssignBase::NetAssignBase(NetAssign_*lv, NetExpr*rv)
@ -167,14 +193,56 @@ NetAssign::~NetAssign()
NetAssignNB::NetAssignNB(NetAssign_*lv, NetExpr*rv)
: NetAssignBase(lv, rv)
{
rise_time_ = 0;
fall_time_ = 0;
decay_time_ = 0;
}
NetAssignNB::~NetAssignNB()
{
}
void NetAssignNB::rise_time(unsigned t)
{
rise_time_ = t;
}
void NetAssignNB::fall_time(unsigned t)
{
fall_time_ = t;
}
void NetAssignNB::decay_time(unsigned t)
{
decay_time_ = t;
}
unsigned NetAssignNB::rise_time() const
{
return rise_time_;
}
unsigned NetAssignNB::fall_time() const
{
return fall_time_;
}
unsigned NetAssignNB::decay_time() const
{
return decay_time_;
}
/*
* $Log: net_assign.cc,v $
* Revision 1.8 2001/08/25 23:50:03 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.7 2001/07/25 03:10:49 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netlist.cc,v 1.169 2001/07/27 04:51:44 steve Exp $"
#ident "$Id: netlist.cc,v 1.170 2001/08/25 23:50:03 steve Exp $"
#endif
# include "config.h"
@ -363,16 +363,21 @@ NetNet::NetNet(NetScope*s, const string&n, Type t, long ms, long ls)
assert(s);
verinum::V init_value = verinum::Vz;
Link::DIR dir = Link::PASSIVE;
switch (t) {
case REG:
case IMPLICIT_REG:
init_value = verinum::Vx;
dir = Link::OUTPUT;
break;
case SUPPLY0:
init_value = verinum::V0;
dir = Link::OUTPUT;
break;
case SUPPLY1:
init_value = verinum::V1;
dir = Link::OUTPUT;
break;
default:
break;
@ -380,6 +385,7 @@ NetNet::NetNet(NetScope*s, const string&n, Type t, long ms, long ls)
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
pin(idx).set_name("P", idx);
pin(idx).set_dir(dir);
pin(idx).set_init(init_value);
}
@ -2385,6 +2391,15 @@ const NetProc*NetTaskDef::proc() const
/*
* $Log: netlist.cc,v $
* Revision 1.170 2001/08/25 23:50:03 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.169 2001/07/27 04:51:44 steve
* Handle part select expressions as variants of
* NetESignal/IVL_EX_SIGNAL objects, instead of

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netlist.h,v 1.213 2001/07/27 04:51:44 steve Exp $"
#ident "$Id: netlist.h,v 1.214 2001/08/25 23:50:03 steve Exp $"
#endif
/*
@ -1162,10 +1162,10 @@ class NetProc : public LineInfo {
* should know that this is not a guarantee.
*/
class NetAssign_ : public NetNode {
class NetAssign_ {
public:
NetAssign_(const string&n, unsigned w);
NetAssign_(NetNet*sig);
~NetAssign_();
// If this expression exists, then only a single bit is to be
@ -1173,21 +1173,32 @@ class NetAssign_ : public NetNode {
// the pin that gets the value.
const NetExpr*bmux() const;
unsigned get_loff() const;
void set_bmux(NetExpr*);
void set_part(unsigned loff, unsigned wid);
// Get the width of the r-value that this node expects. This
// method accounts for the presence of the mux, so it not
// nexessarily the same as the pin_count().
unsigned lwidth() const;
virtual bool emit_node(struct target_t*) const;
virtual void dump_node(ostream&, unsigned ind) const;
// Get the name of the underlying object.
const char*name() const;
NetNet* sig() const;
// This pointer is for keeping simple lists.
NetAssign_* more;
void dump_lval(ostream&o) const;
private:
NetNet *sig_;
NetExpr*bmux_;
unsigned loff_;
unsigned lwid_;
};
class NetAssignBase : public NetProc {
@ -1211,6 +1222,7 @@ class NetAssignBase : public NetProc {
// accounts for any grouping of NetAssign_ objects that might happen.
unsigned lwidth() const;
// This dumps all the lval structures.
void dump_lval(ostream&) const;
private:
@ -1236,12 +1248,23 @@ class NetAssignNB : public NetAssignBase {
explicit NetAssignNB(NetAssign_*lv, NetExpr*rv);
~NetAssignNB();
void rise_time(unsigned);
void fall_time(unsigned);
void decay_time(unsigned);
unsigned rise_time() const;
unsigned fall_time() const;
unsigned decay_time() const;
virtual bool emit_proc(struct target_t*) const;
virtual int match_proc(struct proc_match_t*);
virtual void dump(ostream&, unsigned ind) const;
private:
unsigned rise_time_;
unsigned fall_time_;
unsigned decay_time_;
};
/*
@ -2824,6 +2847,15 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.214 2001/08/25 23:50:03 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.213 2001/07/27 04:51:44 steve
* Handle part select expressions as variants of
* NetESignal/IVL_EX_SIGNAL objects, instead of

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: syn-rules.y,v 1.13 2001/07/27 04:51:44 steve Exp $"
#ident "$Id: syn-rules.y,v 1.14 2001/08/25 23:50:03 steve Exp $"
#endif
# include "config.h"
@ -151,11 +151,11 @@ static void make_DFF_CE(Design*des, NetProcTop*top, NetEvWait*wclk,
assert(d);
NetFF*ff = new NetFF(top->scope(), asn->l_val(0)->name(),
asn->l_val(0)->pin_count());
asn->l_val(0)->lwidth());
for (unsigned idx = 0 ; idx < ff->width() ; idx += 1) {
connect(ff->pin_Data(idx), d->bit(idx));
connect(ff->pin_Q(idx), asn->l_val(0)->pin(idx));
connect(ff->pin_Q(idx), asn->l_val(0)->sig()->pin(idx));
}
connect(ff->pin_Clock(), pclk->pin(0));
@ -215,11 +215,11 @@ static void make_initializer(Design*des, NetProcTop*top, NetAssignBase*asn)
NetESignal*rsig = dynamic_cast<NetESignal*> (asn->rval());
assert(rsig);
for (unsigned idx = 0 ; idx < asn->l_val(0)->pin_count() ; idx += 1) {
for (unsigned idx = 0 ; idx < asn->l_val(0)->lwidth() ; idx += 1) {
verinum::V bit = driven_value(rsig->bit(idx));
Nexus*nex = asn->l_val(0)->pin(idx).nexus();
Nexus*nex = asn->l_val(0)->sig()->pin(idx).nexus();
for (Link*cur = nex->first_nlink()
; cur ; cur = cur->next_nlink()) {

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: t-dll-api.cc,v 1.62 2001/08/10 00:40:45 steve Exp $"
#ident "$Id: t-dll-api.cc,v 1.63 2001/08/25 23:50:03 steve Exp $"
#endif
# include "config.h"
@ -730,10 +730,16 @@ extern "C" ivl_memory_t ivl_lval_mem(ivl_lval_t net)
{
assert(net);
if (net->type_ == IVL_LVAL_MEM)
return net->n.mem_;
return net->n.mem;
return 0x0;
}
extern "C" unsigned ivl_lval_part_off(ivl_lval_t net)
{
assert(net);
return net->loff_;
}
extern "C" unsigned ivl_lval_pins(ivl_lval_t net)
{
assert(net);
@ -745,10 +751,13 @@ extern "C" ivl_nexus_t ivl_lval_pin(ivl_lval_t net, unsigned idx)
assert(net);
assert(idx < net->width_);
assert(net->type_ != IVL_LVAL_MEM);
if (net->width_ == 1)
return net->n.pin_;
else
return net->n.pins_[idx];
return ivl_signal_pin(net->n.sig, idx+net->loff_);
}
extern "C" ivl_signal_t ivl_lval_sig(ivl_lval_t net)
{
assert(net);
return net->n.sig;
}
extern "C" const char* ivl_nexus_name(ivl_nexus_t net)
@ -1309,6 +1318,15 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net)
/*
* $Log: t-dll-api.cc,v $
* Revision 1.63 2001/08/25 23:50:03 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.62 2001/08/10 00:40:45 steve
* tgt-vvp generates code that skips nets as inputs.
*

View File

@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: t-dll-proc.cc,v 1.33 2001/07/27 02:41:56 steve Exp $"
#ident "$Id: t-dll-proc.cc,v 1.34 2001/08/25 23:50:03 steve Exp $"
#endif
# include "config.h"
@ -135,22 +135,10 @@ void dll_target::proc_assign(const NetAssign*net)
struct ivl_lval_s*cur = stmt_cur_->u_.assign_.lval_ + idx;
const NetAssign_*asn = net->l_val(idx);
cur->width_ = asn->pin_count();
cur->type_ = IVL_LVAL_REG;
if (cur->width_ > 1) {
cur->n.pins_ = new ivl_nexus_t[cur->width_];
for (unsigned pp = 0 ; pp < cur->width_ ; pp += 1) {
const Nexus*nex = asn->pin(pp).nexus();
assert(nex->t_cookie());
cur->n.pins_[pp] = (ivl_nexus_t)nex->t_cookie();
}
} else {
const Nexus*nex = asn->pin(0).nexus();
assert(nex->t_cookie());
cur->n.pin_ = (ivl_nexus_t)nex->t_cookie();
}
cur->width_ = asn->lwidth();
cur->loff_ = asn->get_loff();
cur->type_ = IVL_LVAL_REG;
cur->n.sig = find_signal(des_.root_, asn->sig());
cur->idx = 0;
if (asn->bmux()) {
@ -173,8 +161,7 @@ void dll_target::proc_assign_nb(const NetAssignNB*net)
{
unsigned cnt = net->l_val_count();
unsigned long delay_val = net->l_val(0)->rise_time();
unsigned long delay_val = net->rise_time();
assert(stmt_cur_);
assert(stmt_cur_->type_ == IVL_ST_NONE);
@ -188,24 +175,10 @@ void dll_target::proc_assign_nb(const NetAssignNB*net)
struct ivl_lval_s*cur = stmt_cur_->u_.assign_.lval_ + idx;
const NetAssign_*asn = net->l_val(idx);
assert(asn->rise_time() == delay_val);
cur->type_ = IVL_LVAL_REG;
cur->width_ = asn->pin_count();
if (cur->width_ > 1) {
cur->n.pins_ = new ivl_nexus_t[cur->width_];
for (unsigned pp = 0 ; pp < cur->width_ ; pp += 1) {
const Nexus*nex = asn->pin(pp).nexus();
assert(nex->t_cookie());
cur->n.pins_[pp] = (ivl_nexus_t)nex->t_cookie();
}
} else {
const Nexus*nex = asn->pin(0).nexus();
assert(nex->t_cookie());
cur->n.pin_ = (ivl_nexus_t)nex->t_cookie();
}
cur->width_ = asn->lwidth();
cur->loff_ = asn->get_loff();
cur->n.sig = find_signal(des_.root_, asn->sig());
cur->idx = 0;
if (asn->bmux()) {
@ -245,9 +218,9 @@ void dll_target::proc_assign_mem(const NetAssignMem*net)
struct ivl_lval_s*cur = stmt_cur_->u_.assign_.lval_;
cur->type_ = IVL_LVAL_MEM;
cur->n.mem_ = lookup_memory_(net->memory());
assert(cur->n.mem_);
cur->width_ = ivl_memory_width(cur->n.mem_);
cur->n.mem = lookup_memory_(net->memory());
assert(cur->n.mem);
cur->width_ = ivl_memory_width(cur->n.mem);
assert(expr_ == 0);
@ -274,8 +247,8 @@ void dll_target::proc_assign_mem_nb(const NetAssignMemNB*net)
struct ivl_lval_s*cur = stmt_cur_->u_.assign_.lval_;
cur->type_ = IVL_LVAL_MEM;
cur->n.mem_ = lookup_memory_(net->memory());
cur->width_ = ivl_memory_width(cur->n.mem_);
cur->n.mem = lookup_memory_(net->memory());
cur->width_ = ivl_memory_width(cur->n.mem);
assert(expr_ == 0);
@ -693,6 +666,15 @@ void dll_target::proc_while(const NetWhile*net)
/*
* $Log: t-dll-proc.cc,v $
* Revision 1.34 2001/08/25 23:50:03 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.33 2001/07/27 02:41:56 steve
* Fix binding of dangling function ports. do not elide them.
*

23
t-dll.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: t-dll.h,v 1.59 2001/08/10 00:40:45 steve Exp $"
#ident "$Id: t-dll.h,v 1.60 2001/08/25 23:50:03 steve Exp $"
#endif
# include "target.h"
@ -289,9 +289,9 @@ struct ivl_lpm_s {
};
/*
* This object contains references to ivl_nexus_t objects that in turn
* are reg nets. This is used by the assignment to represent the
* l-value expressions.
* This object represents l-values to assignments. The l-value can be
* a register bit or part select, or a memory word select with a part
* select.
*/
enum ivl_lval_type_t {
@ -302,12 +302,12 @@ enum ivl_lval_type_t {
struct ivl_lval_s {
unsigned width_ :24;
unsigned loff_ :24;
unsigned type_ : 8;
ivl_expr_t idx;
union {
ivl_nexus_t*pins_;
ivl_nexus_t pin_;
ivl_memory_t mem_;
ivl_signal_t sig;
ivl_memory_t mem;
} n;
};
@ -562,6 +562,15 @@ struct ivl_statement_s {
/*
* $Log: t-dll.h,v $
* Revision 1.60 2001/08/25 23:50:03 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.59 2001/08/10 00:40:45 steve
* tgt-vvp generates code that skips nets as inputs.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: t-vvm.cc,v 1.211 2001/07/27 04:51:44 steve Exp $"
#ident "$Id: t-vvm.cc,v 1.212 2001/08/25 23:50:03 steve Exp $"
#endif
# include "config.h"
@ -168,7 +168,6 @@ class target_vvm : public target_t {
virtual void logic(const NetLogic*);
virtual bool bufz(const NetBUFZ*);
virtual void udp(const NetUDP*);
virtual void net_assign(const NetAssign_*) { }
virtual void net_case_cmp(const NetCaseCmp*);
virtual bool net_cassign(const NetCAssign*);
virtual bool net_const(const NetConst*);
@ -2348,9 +2347,9 @@ void target_vvm::proc_assign_rval(const NetAssign_*lv,
defn << " switch (" << bval
<< ".as_unsigned()) {" << endl;
for (unsigned idx = 0; idx < lv->pin_count(); idx += 1) {
for (unsigned idx = 0; idx < lv->lwidth(); idx += 1) {
string nexus = lv->pin(idx).nexus()->name();
string nexus = lv->sig()->pin(idx).nexus()->name();
unsigned ncode = nexus_wire_map[nexus];
defn << " case " << idx << ":" << endl;
@ -2379,7 +2378,7 @@ void target_vvm::proc_assign_rval(const NetAssign_*lv,
that does the assignment. This is an optimization that
reduces the size of the generated C++. */
unsigned*nexus_map = new unsigned[lv->pin_count()];
unsigned*nexus_map = new unsigned[lv->lwidth()];
bool sequential_flag = true;
bool uniform_flag = true;
@ -2388,8 +2387,8 @@ void target_vvm::proc_assign_rval(const NetAssign_*lv,
: verinum::V0;
unsigned zeros_start = 0;
for (unsigned idx = 0 ; idx < lv->pin_count() ; idx += 1) {
string nexus = lv->pin(idx).nexus()->name();
for (unsigned idx = 0 ; idx < lv->lwidth() ; idx += 1) {
string nexus = lv->sig()->pin(idx).nexus()->name();
nexus_map[idx] = nexus_wire_map[nexus];
verinum::V tmp = (idx+off) < value.len()
@ -2409,18 +2408,18 @@ void target_vvm::proc_assign_rval(const NetAssign_*lv,
}
if (sequential_flag && uniform_flag && (lv->pin_count() > 1)) {
if (sequential_flag && uniform_flag && (lv->lwidth() > 1)) {
const char*rval = vvm_val_name(val, Link::STRONG, Link::STRONG);
unsigned base = nexus_map[0];
defn << " for (unsigned idx = 0 ; idx < "
<< lv->pin_count() << " ; idx += 1)" << endl;
<< lv->lwidth() << " ; idx += 1)" << endl;
defn << " nexus_wire_table[idx+" <<base<< "]"
<< ".reg_assign(" << rval << ");" << endl;
} else if (sequential_flag && (zeros_start < lv->pin_count())) {
} else if (sequential_flag && (zeros_start < lv->lwidth())) {
/* If the nexa are sequential and the high bits are all
zeros, then we can write simple reg_assign statements
@ -2449,13 +2448,13 @@ void target_vvm::proc_assign_rval(const NetAssign_*lv,
unsigned base = nexus_map[zeros_start];
defn << " for (unsigned idx = 0 ; idx < "
<< (lv->pin_count()-zeros_start) << " ; idx += 1)" << endl;
<< (lv->lwidth()-zeros_start) << " ; idx += 1)" << endl;
defn << " nexus_wire_table[idx+" <<base<< "]"
<< ".reg_assign(" << rval << ");" << endl;
} else for (unsigned idx = 0 ; idx < lv->pin_count() ; idx += 1) {
} else for (unsigned idx = 0 ; idx < lv->lwidth() ; idx += 1) {
unsigned ncode = nexus_map[idx];
val = (idx+off) < value.len()
@ -2493,9 +2492,9 @@ void target_vvm::proc_assign_rval(const NetAssign_*lv,
defn << " switch (" << bval << ".as_unsigned()) {" << endl;
for (unsigned idx = 0 ; idx < lv->pin_count() ; idx += 1) {
for (unsigned idx = 0 ; idx < lv->lwidth() ; idx += 1) {
string nexus = lv->pin(idx).nexus()->name();
string nexus = lv->sig()->pin(idx).nexus()->name();
unsigned ncode = nexus_wire_map[nexus];
defn << " case " << idx << ":" << endl;
@ -2509,7 +2508,7 @@ void target_vvm::proc_assign_rval(const NetAssign_*lv,
defn << " }" << endl;
} else {
unsigned min_count = lv->pin_count();
unsigned min_count = lv->lwidth();
if ((wid-off) < min_count)
min_count = wid - off;
@ -2517,9 +2516,9 @@ void target_vvm::proc_assign_rval(const NetAssign_*lv,
the l-value. */
bool sequential_flag = true;
unsigned*nexus_map = new unsigned[lv->pin_count()];
for (unsigned idx = 0 ; idx < lv->pin_count() ; idx += 1) {
string nexus = lv->pin(idx).nexus()->name();
unsigned*nexus_map = new unsigned[lv->lwidth()];
for (unsigned idx = 0 ; idx < lv->lwidth() ; idx += 1) {
string nexus = lv->sig()->pin(idx).nexus()->name();
nexus_map[idx] = nexus_wire_map[nexus];
if ((idx >= 1) && (nexus_map[idx] != (nexus_map[idx-1]+1)))
@ -2544,7 +2543,7 @@ void target_vvm::proc_assign_rval(const NetAssign_*lv,
}
}
for (unsigned idx = min_count; idx < lv->pin_count(); idx += 1) {
for (unsigned idx = min_count; idx < lv->lwidth(); idx += 1) {
unsigned ncode = nexus_map[idx];
defn << " nexus_wire_table["<<ncode<<"]"
<< ".reg_assign(St0);" << endl;
@ -2667,7 +2666,11 @@ void target_vvm::proc_assign_nb_rval(const NetAssign_*lv,
unsigned off)
{
const verinum value = rv->value();
#if 0
const unsigned rise_time = lv->rise_time();
#else
const unsigned rise_time = 0;
#endif
/* This condition catches the special case of assigning to a
non-constant bit select. This cal be something like:
@ -2695,9 +2698,9 @@ void target_vvm::proc_assign_nb_rval(const NetAssign_*lv,
defn << " switch (" << bval
<< ".as_unsigned()) {" << endl;
for (unsigned idx = 0; idx < lv->pin_count(); idx += 1) {
for (unsigned idx = 0; idx < lv->lwidth(); idx += 1) {
string nexus = lv->pin(idx).nexus()->name();
string nexus = lv->sig()->pin(idx).nexus()->name();
unsigned ncode = nexus_wire_map[nexus];
defn << " case " << idx << ":" << endl;
@ -2720,8 +2723,8 @@ void target_vvm::proc_assign_nb_rval(const NetAssign_*lv,
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();
for (unsigned idx = 0 ; idx < lv->lwidth() ; idx += 1) {
string nexus = lv->sig()->pin(idx).nexus()->name();
unsigned ncode = nexus_wire_map[nexus];
verinum::V val = (idx+off) < value.len()
@ -2744,7 +2747,11 @@ void target_vvm::proc_assign_nb_rval(const NetAssign_*lv,
unsigned wid, unsigned off)
{
assert(lv);
#if 0
const unsigned rise_time = lv->rise_time();
#else
const unsigned rise_time = 0;
#endif
/* 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
@ -2759,9 +2766,9 @@ void target_vvm::proc_assign_nb_rval(const NetAssign_*lv,
defn << " switch (" << bval << ".as_unsigned()) {" << endl;
for (unsigned idx = 0 ; idx < lv->pin_count() ; idx += 1) {
for (unsigned idx = 0 ; idx < lv->lwidth() ; idx += 1) {
string nexus = lv->pin(idx).nexus()->name();
string nexus = lv->sig()->pin(idx).nexus()->name();
unsigned ncode = nexus_wire_map[nexus];
defn << " case " << idx << ":" << endl;
@ -2776,12 +2783,12 @@ void target_vvm::proc_assign_nb_rval(const NetAssign_*lv,
defn << " }" << endl;
} else {
unsigned min_count = lv->pin_count();
unsigned min_count = lv->lwidth();
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();
string nexus = lv->sig()->pin(idx).nexus()->name();
unsigned ncode = nexus_wire_map[nexus];
defn << " vvm_delayed_assign(nexus_wire_table["
<<ncode<<"], "
@ -2789,8 +2796,8 @@ void target_vvm::proc_assign_nb_rval(const NetAssign_*lv,
<<rise_time<< ");" << endl;
}
for (unsigned idx = min_count; idx < lv->pin_count(); idx += 1) {
string nexus = lv->pin(idx).nexus()->name();
for (unsigned idx = min_count; idx < lv->lwidth(); idx += 1) {
string nexus = lv->sig()->pin(idx).nexus()->name();
unsigned ncode = nexus_wire_map[nexus];
defn << " vvm_delayed_assign(nexus_wire_table["
<<ncode<<"], St0, " <<rise_time<< ");" << endl;
@ -3645,6 +3652,15 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
* Revision 1.212 2001/08/25 23:50:03 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.211 2001/07/27 04:51:44 steve
* Handle part select expressions as variants of
* NetESignal/IVL_EX_SIGNAL objects, instead of

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: target.cc,v 1.56 2001/07/27 04:51:44 steve Exp $"
#ident "$Id: target.cc,v 1.57 2001/08/25 23:50:03 steve Exp $"
#endif
# include "config.h"
@ -130,12 +130,6 @@ void target_t::lpm_ram_dq(const NetRamDq*)
"Unhandled NetRamDq." << endl;
}
void target_t::net_assign(const NetAssign_*)
{
cerr << "target (" << typeid(*this).name() << "): "
"Unhandled assignment (NetAssign_) node." << endl;
}
void target_t::net_case_cmp(const NetCaseCmp*)
{
cerr << "target (" << typeid(*this).name() << "): "
@ -389,6 +383,15 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/*
* $Log: target.cc,v $
* Revision 1.57 2001/08/25 23:50:03 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.56 2001/07/27 04:51:44 steve
* Handle part select expressions as variants of
* NetESignal/IVL_EX_SIGNAL objects, instead of

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: target.h,v 1.53 2001/07/27 04:51:44 steve Exp $"
#ident "$Id: target.h,v 1.54 2001/08/25 23:50:03 steve Exp $"
#endif
# include "netlist.h"
@ -87,7 +87,6 @@ struct target_t {
virtual void logic(const NetLogic*);
virtual bool bufz(const NetBUFZ*);
virtual void udp(const NetUDP*);
virtual void net_assign(const NetAssign_*);
virtual void net_case_cmp(const NetCaseCmp*);
virtual bool net_cassign(const NetCAssign*);
virtual bool net_const(const NetConst*);
@ -163,6 +162,15 @@ extern const struct target *target_table[];
/*
* $Log: target.h,v $
* Revision 1.54 2001/08/25 23:50:03 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.53 2001/07/27 04:51:44 steve
* Handle part select expressions as variants of
* NetESignal/IVL_EX_SIGNAL objects, instead of

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vvp_process.c,v 1.41 2001/08/16 03:45:17 steve Exp $"
#ident "$Id: vvp_process.c,v 1.42 2001/08/25 23:50:03 steve Exp $"
#endif
# include "vvp_priv.h"
@ -58,7 +58,7 @@ unsigned bitchar_to_idx(char bit)
* instruction to perform the actual assignment, and calculate any
* lvalues and rvalues that need calculating.
*
* The set_to_nexus function takes a particular nexus and generates
* The set_to_lvariable function takes a particular nexus and generates
* the %set statements to assign the value.
*
* The show_stmt_assign function looks at the assign statement, scans
@ -66,21 +66,13 @@ unsigned bitchar_to_idx(char bit)
* nexus.
*/
static void set_to_nexus(ivl_nexus_t nex, unsigned bit)
static void set_to_lvariable(ivl_lval_t lval, unsigned idx, unsigned bit)
{
unsigned idx;
ivl_signal_t sig = ivl_lval_sig(lval);
unsigned part_off = ivl_lval_part_off(lval);
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx);
unsigned pin = ivl_nexus_ptr_pin(ptr);
ivl_signal_t sig = ivl_nexus_ptr_sig(ptr);
if (sig == 0)
continue;
fprintf(vvp_out, " %%set V_%s[%u], %u;\n",
vvp_mangle_id(ivl_signal_name(sig)), pin, bit);
}
fprintf(vvp_out, " %%set V_%s[%u], %u;\n",
vvp_mangle_id(ivl_signal_name(sig)), idx+part_off, bit);
}
static void set_to_memory(ivl_memory_t mem, unsigned idx, unsigned bit)
@ -91,21 +83,15 @@ static void set_to_memory(ivl_memory_t mem, unsigned idx, unsigned bit)
vvp_mangle_id(ivl_memory_name(mem)), bit);
}
static void assign_to_nexus(ivl_nexus_t nex, unsigned bit, unsigned delay)
static void assign_to_lvariable(ivl_lval_t lval, unsigned idx,
unsigned bit, unsigned delay)
{
unsigned idx;
ivl_signal_t sig = ivl_lval_sig(lval);
unsigned part_off = ivl_lval_part_off(lval);
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx);
unsigned pin = ivl_nexus_ptr_pin(ptr);
ivl_signal_t sig = ivl_nexus_ptr_sig(ptr);
if (sig == 0)
continue;
fprintf(vvp_out, " %%assign V_%s[%u], %u, %u;\n",
vvp_mangle_id(ivl_signal_name(sig)), pin, delay, bit);
}
fprintf(vvp_out, " %%assign V_%s[%u], %u, %u;\n",
vvp_mangle_id(ivl_signal_name(sig)),
idx+part_off, delay, bit);
}
static void assign_to_memory(ivl_memory_t mem, unsigned idx,
@ -128,75 +114,92 @@ static int show_stmt_assign(ivl_statement_t net)
about generating code to evaluate the r-value expressions. */
if (ivl_expr_type(rval) == IVL_EX_NUMBER) {
unsigned idx;
unsigned lidx;
const char*bits = ivl_expr_bits(rval);
unsigned wid = ivl_expr_width(rval);
unsigned cur_rbit = 0;
/* XXXX Only single l-value supported for now */
assert(ivl_stmt_lvals(net) == 1);
for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) {
unsigned idx;
unsigned bit_limit = wid - cur_rbit;
lval = ivl_stmt_lval(net, lidx);
lval = ivl_stmt_lval(net, 0);
/* XXXX No mux support yet. */
assert(ivl_lval_mux(lval) == 0);
mem = ivl_lval_mem(lval);
/* XXXX No mux support yet. */
assert(ivl_lval_mux(lval) == 0);
mem = ivl_lval_mem(lval);
if (mem)
draw_memory_index_expr(mem, ivl_lval_idx(lval));
if (mem)
draw_memory_index_expr(mem, ivl_lval_idx(lval));
if (wid > ivl_lval_pins(lval))
wid = ivl_lval_pins(lval);
if (bit_limit > ivl_lval_pins(lval))
bit_limit = ivl_lval_pins(lval);
for (idx = 0 ; idx < wid ; idx += 1)
if (mem)
set_to_memory(mem, idx, bitchar_to_idx(bits[idx]));
else
set_to_nexus(ivl_lval_pin(lval, idx),
bitchar_to_idx(bits[idx]));
for (idx = 0 ; idx < bit_limit ; idx += 1) {
if (mem)
set_to_memory(mem, idx,
bitchar_to_idx(bits[cur_rbit]));
else
set_to_lvariable(lval, idx,
bitchar_to_idx(bits[cur_rbit]));
for (idx = wid ; idx < ivl_lval_pins(lval) ; idx += 1)
if (mem)
set_to_memory(mem, idx, 0);
else
set_to_nexus(ivl_lval_pin(lval, idx), 0);
cur_rbit += 1;
}
for (idx = bit_limit ; idx < ivl_lval_pins(lval) ; idx += 1)
if (mem)
set_to_memory(mem, idx, 0);
else
set_to_lvariable(lval, idx, 0);
}
return 0;
}
{ struct vector_info res = draw_eval_expr(rval);
unsigned wid = res.wid;
unsigned idx;
unsigned lidx;
unsigned cur_rbit = 0;
/* XXXX Only single l-value supported for now */
assert(ivl_stmt_lvals(net) == 1);
for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) {
unsigned idx;
unsigned bit_limit = wid - cur_rbit;
lval = ivl_stmt_lval(net, lidx);
lval = ivl_stmt_lval(net, 0);
/* XXXX No mux support yet. */
assert(ivl_lval_mux(lval) == 0);
mem = ivl_lval_mem(lval);
/* XXXX No mux support yet. */
assert(ivl_lval_mux(lval) == 0);
if (ivl_lval_pins(lval) < wid)
wid = ivl_lval_pins(lval);
mem = ivl_lval_mem(lval);
if (mem)
draw_memory_index_expr(mem, ivl_lval_idx(lval));
if (bit_limit > ivl_lval_pins(lval))
bit_limit = ivl_lval_pins(lval);
for (idx = 0 ; idx < bit_limit ; idx += 1) {
unsigned bidx = res.base < 4
? res.base
: (res.base+cur_rbit);
if (mem)
set_to_memory(mem, idx, bidx);
else
set_to_lvariable(lval, idx, bidx);
cur_rbit += 1;
}
for (idx = bit_limit ; idx < ivl_lval_pins(lval) ; idx += 1)
if (mem)
set_to_memory(mem, idx, 0);
else
set_to_lvariable(lval, idx, 0);
if (mem)
draw_memory_index_expr(mem, ivl_lval_idx(lval));
for (idx = 0 ; idx < wid ; idx += 1) {
unsigned bidx = res.base < 4 ? res.base : (res.base+idx);
if (mem)
set_to_memory(mem, idx, bidx);
else
set_to_nexus(ivl_lval_pin(lval, idx), bidx);
}
for (idx = wid ; idx < ivl_lval_pins(lval) ; idx += 1)
if (mem)
set_to_memory(mem, idx, 0);
else
set_to_nexus(ivl_lval_pin(lval, idx), 0);
clr_vector(res);
}
return 0;
}
@ -219,72 +222,89 @@ static int show_stmt_assign_nb(ivl_statement_t net)
about generating code to evaluate the r-value expressions. */
if (ivl_expr_type(rval) == IVL_EX_NUMBER) {
unsigned idx;
unsigned lidx;
const char*bits = ivl_expr_bits(rval);
unsigned wid = ivl_expr_width(rval);
unsigned cur_rbit = 0;
/* XXXX Only single l-value supported for now */
assert(ivl_stmt_lvals(net) == 1);
for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) {
unsigned idx;
unsigned bit_limit = wid - cur_rbit;
lval = ivl_stmt_lval(net, lidx);
lval = ivl_stmt_lval(net, 0);
/* XXXX No mux support yet. */
assert(ivl_lval_mux(lval) == 0);
mem = ivl_lval_mem(lval);
/* XXXX No mux support yet. */
assert(ivl_lval_mux(lval) == 0);
if (mem)
draw_memory_index_expr(mem, ivl_lval_idx(lval));
if (wid > ivl_lval_pins(lval))
wid = ivl_lval_pins(lval);
for (idx = 0 ; idx < wid ; idx += 1)
mem = ivl_lval_mem(lval);
if (mem)
assign_to_memory(mem, idx,
bitchar_to_idx(bits[idx]), delay);
else
assign_to_nexus(ivl_lval_pin(lval, idx),
bitchar_to_idx(bits[idx]), delay);
for (idx = wid ; idx < ivl_lval_pins(lval) ; idx += 1)
if (mem)
assign_to_memory(mem, idx, 0, delay);
else
assign_to_nexus(ivl_lval_pin(lval, idx), 0, delay);
draw_memory_index_expr(mem, ivl_lval_idx(lval));
if (bit_limit > ivl_lval_pins(lval))
bit_limit = ivl_lval_pins(lval);
for (idx = 0 ; idx < bit_limit ; idx += 1) {
if (mem)
assign_to_memory(mem, idx,
bitchar_to_idx(bits[cur_rbit]),
delay);
else
assign_to_lvariable(lval, idx,
bitchar_to_idx(bits[cur_rbit]),
delay);
cur_rbit += 1;
}
for (idx = bit_limit; idx < ivl_lval_pins(lval); idx += 1)
if (mem)
assign_to_memory(mem, idx, 0, delay);
else
assign_to_lvariable(lval, idx, 0, delay);
}
return 0;
}
{ struct vector_info res = draw_eval_expr(rval);
unsigned wid = res.wid;
unsigned idx;
unsigned lidx;
unsigned cur_rbit = 0;
/* XXXX Only single l-value supported for now */
assert(ivl_stmt_lvals(net) == 1);
for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) {
unsigned idx;
unsigned bit_limit = wid - cur_rbit;
lval = ivl_stmt_lval(net, lidx);
lval = ivl_stmt_lval(net, 0);
/* XXXX No mux support yet. */
assert(ivl_lval_mux(lval) == 0);
mem = ivl_lval_mem(lval);
/* XXXX No mux support yet. */
assert(ivl_lval_mux(lval) == 0);
if (ivl_lval_pins(lval) < wid)
wid = ivl_lval_pins(lval);
mem = ivl_lval_mem(lval);
if (mem)
draw_memory_index_expr(mem, ivl_lval_idx(lval));
if (bit_limit > ivl_lval_pins(lval))
bit_limit = ivl_lval_pins(lval);
for (idx = 0 ; idx < bit_limit ; idx += 1) {
unsigned bidx = res.base < 4
? res.base
: (res.base+cur_rbit);
if (mem)
assign_to_memory(mem, idx, bidx, delay);
else
assign_to_lvariable(lval, idx, bidx, delay);
cur_rbit += 1;
}
for (idx = bit_limit ; idx < ivl_lval_pins(lval) ; idx += 1)
if (mem)
assign_to_memory(mem, idx, 0, delay);
else
assign_to_lvariable(lval, idx, 0, delay);
if (mem)
draw_memory_index_expr(mem, ivl_lval_idx(lval));
for (idx = 0 ; idx < wid ; idx += 1) {
unsigned bidx = res.base < 4 ? res.base : (res.base+idx);
if (mem)
assign_to_memory(mem, idx, bidx, delay);
else
assign_to_nexus(ivl_lval_pin(lval, idx), bidx, delay);
}
for (idx = wid ; idx < ivl_lval_pins(lval) ; idx += 1)
if (mem)
assign_to_memory(mem, idx, 0, delay);
else
assign_to_nexus(ivl_lval_pin(lval, idx), 0, delay);
clr_vector(res);
}
@ -931,6 +951,15 @@ int draw_func_definition(ivl_scope_t scope)
/*
* $Log: vvp_process.c,v $
* Revision 1.42 2001/08/25 23:50:03 steve
* Change the NetAssign_ class to refer to the signal
* instead of link into the netlist. This is faster
* and uses less space. Make the NetAssignNB carry
* the delays instead of the NetAssign_ lval objects.
*
* Change the vvp code generator to support multiple
* l-values, i.e. concatenations of part selects.
*
* Revision 1.41 2001/08/16 03:45:17 steve
* statement ends after while loop labels.
*