diff --git a/design_dump.cc b/design_dump.cc index 16bd5bd4d..2fe9904a3 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: design_dump.cc,v 1.19 1999/05/01 02:57:52 steve Exp $" +#ident "$Id: design_dump.cc,v 1.20 1999/05/01 20:43:55 steve Exp $" #endif /* @@ -251,6 +251,7 @@ void NetNEvent::dump_node(ostream&o, unsigned ind) const o << setw(ind) << "" << "event: "; switch (edge_) { case ANYEDGE: + o << "anyedge "; break; case POSEDGE: o << "posedge "; @@ -263,7 +264,7 @@ void NetNEvent::dump_node(ostream&o, unsigned ind) const break; } - o << name() << endl; + o << name() << " --> " << fore_ptr()->name() << endl; dump_node_pins(o, ind+4); } @@ -562,6 +563,14 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.20 1999/05/01 20:43:55 steve + * Handle wide events, such as @(a) where a has + * many bits in it. + * + * Add to vvm the binary ^ and unary & operators. + * + * Dump events a bit more completely. + * * Revision 1.19 1999/05/01 02:57:52 steve * Handle much more complex event expressions. * diff --git a/elaborate.cc b/elaborate.cc index 0e6042f40..2f04254f8 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: elaborate.cc,v 1.22 1999/05/01 02:57:53 steve Exp $" +#ident "$Id: elaborate.cc,v 1.23 1999/05/01 20:43:55 steve Exp $" #endif /* @@ -883,7 +883,9 @@ NetProc* PEventStatement::elaborate(Design*des, const string&path) const } /* Create a single NetPEvent, and a unique NetNEvent for each - conjuctive event. */ + conjuctive event. An NetNEvent can have many pins only if + it is an ANYEDGE detector. Otherwise, only connect to the + least significant bit of the expression. */ NetPEvent*pe = new NetPEvent(des->local_symbol(path), enet); for (unsigned idx = 0 ; idx < expr_.count() ; idx += 1) { @@ -896,10 +898,15 @@ NetProc* PEventStatement::elaborate(Design*des, const string&path) const return 0; } assert(expr); - NetNEvent*ne = new NetNEvent(des->local_symbol(path), - expr_[idx]->type(), pe); - connect(ne->pin(0), expr->pin(0)); + unsigned pins = (expr_[idx]->type() == NetNEvent::ANYEDGE) + ? expr->pin_count() : 1; + NetNEvent*ne = new NetNEvent(des->local_symbol(path), + pins, expr_[idx]->type(), pe); + + for (unsigned p = 0 ; p < pins ; p += 1) + connect(ne->pin(p), expr->pin(p)); + des->add_node(ne); } @@ -1050,6 +1057,14 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.23 1999/05/01 20:43:55 steve + * Handle wide events, such as @(a) where a has + * many bits in it. + * + * Add to vvm the binary ^ and unary & operators. + * + * Dump events a bit more completely. + * * Revision 1.22 1999/05/01 02:57:53 steve * Handle much more complex event expressions. * diff --git a/netlist.h b/netlist.h index 9856dbdf6..e3b1bc6a7 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: netlist.h,v 1.27 1999/05/01 02:57:53 steve Exp $" +#ident "$Id: netlist.h,v 1.28 1999/05/01 20:43:55 steve Exp $" #endif /* @@ -745,14 +745,17 @@ class NetPEvent : public NetProc, public sref_back { * The NetNEvent is a NetNode that connects to the structural part of * the design. It has only inputs, which cause the side effect of * triggering an event that the procedural part of the design can use. + * + * The NetNEvent may have wide input if is is an ANYEDGE type + * device. This allows detecting changes in wide expressions. */ class NetNEvent : public NetNode, public sref { public: enum Type { ANYEDGE, POSEDGE, NEGEDGE, POSITIVE }; - NetNEvent(const string&ev, Type e, NetPEvent*pe) - : NetNode(ev, 1), sref(pe), edge_(e) { } + NetNEvent(const string&ev, unsigned wid, Type e, NetPEvent*pe) + : NetNode(ev, wid), sref(pe), edge_(e) { } Type type() const { return edge_; } @@ -1152,6 +1155,14 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.28 1999/05/01 20:43:55 steve + * Handle wide events, such as @(a) where a has + * many bits in it. + * + * Add to vvm the binary ^ and unary & operators. + * + * Dump events a bit more completely. + * * Revision 1.27 1999/05/01 02:57:53 steve * Handle much more complex event expressions. * diff --git a/t-vvm.cc b/t-vvm.cc index da86014fd..e8e6f4a5c 100644 --- a/t-vvm.cc +++ b/t-vvm.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: t-vvm.cc,v 1.18 1999/05/01 02:57:53 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.19 1999/05/01 20:43:55 steve Exp $" #endif # include @@ -176,6 +176,10 @@ void vvm_proc_rval::expr_unary(const NetEUnary*expr) os_ << "vvm_unop_not(" << result << ");" << endl; break; + case '&': + os_ << "vvm_unop_and(" << result << ");" + << endl; + break; case '!': os_ << "vvm_unop_lnot(" << result << ");" << endl; @@ -230,6 +234,10 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr) os_ << setw(indent_) << "" << result << " = vvm_binop_or(" << lres << "," << rres << ");" << endl; break; + case '^': + os_ << setw(indent_) << "" << result << " = vvm_binop_xor(" + << lres << "," << rres << ");" << endl; + break; default: cerr << "vvm: Unhandled binary op `" << expr->op() << "': " << *expr << endl; @@ -603,17 +611,17 @@ void target_vvm::net_event(ostream&os, const NetNEvent*gate) os << "static vvm_sync " << pevent << ";" << endl; os << "#endif" << endl; - os << "static vvm_pevent " << mangle(gate->name()) << "(&" << - pevent << ", "; + os << "static vvm_pevent<" << gate->pin_count() << "> " << + mangle(gate->name()) << "(&" << pevent << ", "; switch (gate->type()) { case NetNEvent::POSEDGE: - os << "vvm_pevent::POSEDGE"; + os << "vvm_pevent<" << gate->pin_count() << ">::POSEDGE"; break; case NetNEvent::NEGEDGE: - os << "vvm_pevent::NEGEDGE"; + os << "vvm_pevent<"<< gate->pin_count() << ">::NEGEDGE"; break; case NetNEvent::ANYEDGE: - os << "vvm_pevent::ANYEDGE"; + os << "vvm_pevent<" << gate->pin_count() << ">::ANYEDGE"; break; default: assert(0); @@ -957,6 +965,14 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.19 1999/05/01 20:43:55 steve + * Handle wide events, such as @(a) where a has + * many bits in it. + * + * Add to vvm the binary ^ and unary & operators. + * + * Dump events a bit more completely. + * * Revision 1.18 1999/05/01 02:57:53 steve * Handle much more complex event expressions. * diff --git a/vvm/vvm_func.h b/vvm/vvm_func.h index 68415f2a3..e4bbc811a 100644 --- a/vvm/vvm_func.h +++ b/vvm/vvm_func.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvm_func.h,v 1.3 1999/03/16 04:43:46 steve Exp $" +#ident "$Id: vvm_func.h,v 1.4 1999/05/01 20:43:55 steve Exp $" #endif # include "vvm.h" @@ -45,6 +45,21 @@ vvm_bitset_t vvm_unop_not(const vvm_bitset_t&p) return result; } +/* + * The unary AND is the reduction AND. It returns a single bit. + */ +template +vvm_bitset_t<1> vvm_unop_and(const vvm_bitset_t&r) +{ + vvm_bitset_t<1> res; + res[0] = r[0]; + + for (unsigned idx = 1 ; idx < WIDTH ; idx += 1) { + res[0] = res[0] & r[idx]; + } + return res; +} + /* * The unary OR is the reduction OR. It returns a single bit. */ @@ -124,7 +139,7 @@ vvm_bitset_t vvm_binop_plus(const vvm_bitset_t&l, */ template vvm_bitset_t vvm_binop_minus(const vvm_bitset_t&l, - const vvm_bitset_t&r) + const vvm_bitset_t&r) { vvm_bitset_t res; res = vvm_unop_not(r); @@ -135,6 +150,21 @@ vvm_bitset_t vvm_binop_minus(const vvm_bitset_t&l, return res; } +/* + * The binary ^ (xor) operator is a bitwise XOR of equal width inputs + * to generate the corresponsing output. + */ +template +vvm_bitset_t vvm_binop_xor(const vvm_bitset_t&l, + const vvm_bitset_t&r) +{ + vvm_bitset_t result; + for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) + result[idx] = l[idx] ^ r[idx]; + + return result; +} + /* * Tests for equality are a bit tricky, as they allow for the left and * right subexpressions to have different size. The shorter bitset is @@ -240,6 +270,14 @@ vvm_bitset_t<1> vvm_binop_lor(const vvm_bitset_t&l, /* * $Log: vvm_func.h,v $ + * Revision 1.4 1999/05/01 20:43:55 steve + * Handle wide events, such as @(a) where a has + * many bits in it. + * + * Add to vvm the binary ^ and unary & operators. + * + * Dump events a bit more completely. + * * Revision 1.3 1999/03/16 04:43:46 steve * Add some logical operators. * diff --git a/vvm/vvm_gates.h b/vvm/vvm_gates.h index e0c9edcd4..8e6bd8c08 100644 --- a/vvm/vvm_gates.h +++ b/vvm/vvm_gates.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvm_gates.h,v 1.8 1999/05/01 02:57:53 steve Exp $" +#ident "$Id: vvm_gates.h,v 1.9 1999/05/01 20:43:55 steve Exp $" #endif # include "vvm.h" @@ -367,18 +367,39 @@ class vvm_sync { vvm_sync& operator= (const vvm_sync&); }; -class vvm_pevent { +template class vvm_pevent { public: enum EDGE { ANYEDGE, POSEDGE, NEGEDGE }; - explicit vvm_pevent(vvm_sync*tgt, EDGE e); + explicit vvm_pevent(vvm_sync*tgt, EDGE e) + : target_(tgt), edge_(e) + { for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) + value_[idx] = Vz; + } - void set(vvm_simulation*sim, unsigned, vvm_bit_t val); - vvm_bit_t get() const { return value_; } + vvm_bitset_t get() const { return value_; } + + void set(vvm_simulation*sim, unsigned idx, vvm_bit_t val) + { if (value_[idx] == val) return; + switch (edge_) { + case ANYEDGE: + target_->wakeup(sim); + break; + case POSEDGE: + if (val == V1) + target_->wakeup(sim); + break; + case NEGEDGE: + if (val == V0) + target_->wakeup(sim); + break; + } + value_[idx] = val; + } private: vvm_sync*target_; - vvm_bit_t value_; + vvm_bit_t value_[WIDTH]; EDGE edge_; private: // not implemented @@ -388,6 +409,14 @@ class vvm_pevent { /* * $Log: vvm_gates.h,v $ + * Revision 1.9 1999/05/01 20:43:55 steve + * Handle wide events, such as @(a) where a has + * many bits in it. + * + * Add to vvm the binary ^ and unary & operators. + * + * Dump events a bit more completely. + * * Revision 1.8 1999/05/01 02:57:53 steve * Handle much more complex event expressions. * diff --git a/vvm/vvm_pevent.cc b/vvm/vvm_pevent.cc index 50abb85bb..22ffe5ab4 100644 --- a/vvm/vvm_pevent.cc +++ b/vvm/vvm_pevent.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvm_pevent.cc,v 1.2 1999/05/01 02:57:53 steve Exp $" +#ident "$Id: vvm_pevent.cc,v 1.3 1999/05/01 20:43:55 steve Exp $" #endif # include "vvm.h" @@ -41,33 +41,17 @@ void vvm_sync::wakeup(vvm_simulation*sim) if (tmp) sim->thread_active(tmp); } -vvm_pevent::vvm_pevent(vvm_sync*tgt, EDGE e) -: target_(tgt), value_(V0), edge_(e) -{ -} - -void vvm_pevent::set(vvm_simulation*sim, unsigned, vvm_bit_t val) -{ - if (value_ != val) { - switch (edge_) { - case ANYEDGE: - target_->wakeup(sim); - break; - case POSEDGE: - if (val == V1) - target_->wakeup(sim); - break; - case NEGEDGE: - if (val == V0) - target_->wakeup(sim); - break; - } - value_ = val; - } -} /* * $Log: vvm_pevent.cc,v $ + * Revision 1.3 1999/05/01 20:43:55 steve + * Handle wide events, such as @(a) where a has + * many bits in it. + * + * Add to vvm the binary ^ and unary & operators. + * + * Dump events a bit more completely. + * * Revision 1.2 1999/05/01 02:57:53 steve * Handle much more complex event expressions. *