From 8dbd64121f0168b9300875c4fc9c6c6d1fdbe7a8 Mon Sep 17 00:00:00 2001 From: steve Date: Mon, 10 Apr 2000 05:26:05 +0000 Subject: [PATCH] All events now use the NetEvent class. --- design_dump.cc | 25 ++++++- elaborate.cc | 148 ++++++++++++++++++++++++++++++++--------- emit.cc | 11 ++- net_design.cc | 14 +++- net_event.cc | 29 +++++++- net_scope.cc | 15 ++++- netlist.h | 36 +++++++++- t-vvm.cc | 108 ++++++++++++++++-------------- target.cc | 12 +++- target.h | 6 +- vvm/vvm.h | 10 ++- vvm/vvm_bit.cc | 19 +++++- vvm/vvm_gates.h | 166 +++++++++++++++------------------------------- vvm/vvm_pevent.cc | 90 ++++++++++++++++++++++++- 14 files changed, 485 insertions(+), 204 deletions(-) diff --git a/design_dump.cc b/design_dump.cc index 7d2a499be..2a2d16583 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) && !defined(macintosh) -#ident "$Id: design_dump.cc,v 1.73 2000/04/04 03:20:15 steve Exp $" +#ident "$Id: design_dump.cc,v 1.74 2000/04/10 05:26:05 steve Exp $" #endif /* @@ -527,6 +527,26 @@ void NetCondit::dump(ostream&o, unsigned ind) const } } +void NetEvProbe::dump_node(ostream&o, unsigned ind) const +{ + o << setw(ind) << ""; + + switch (edge_) { + case ANYEDGE: + o << "anyedge "; + break; + case POSEDGE: + o << "posedge "; + break; + case NEGEDGE: + o << "negedge "; + break; + } + o << setw(ind) << "" << "-> " << event_->full_name() << "; " << endl; + dump_node_pins(o, ind+4); + dump_obj_attr(o, ind+4); +} + void NetEvTrig::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "-> " << event_->name() << "; " @@ -928,6 +948,9 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.74 2000/04/10 05:26:05 steve + * All events now use the NetEvent class. + * * Revision 1.73 2000/04/04 03:20:15 steve * Simulate named event trigger and waits. * diff --git a/elaborate.cc b/elaborate.cc index a0bfb953d..0f26158dc 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) && !defined(macintosh) -#ident "$Id: elaborate.cc,v 1.156 2000/04/09 17:44:30 steve Exp $" +#ident "$Id: elaborate.cc,v 1.157 2000/04/10 05:26:06 steve Exp $" #endif /* @@ -34,13 +34,6 @@ # include "netlist.h" # include "netmisc.h" -string Design::local_symbol(const string&path) -{ - strstream res; - res << "_L" << (lcounter_++) << ends; - return path + "." + res.str(); -} - // Urff, I don't like this global variable. I *will* figure out a // way to get rid of it. But, for now the PGModule::elaborate method @@ -1529,14 +1522,30 @@ NetProc* PDelayStatement::elaborate(Design*des, const string&path) const } /* - * An event statement gets elaborated as a gate net that drives a - * special node, the NetPEvent. The NetPEvent is also a NetProc class - * because execution flows through it. Thus, the NetPEvent connects - * the structural and the behavioral. + * An event statement is an event delay of some sort, attached to a + * statement. Some Verilog examples are: * - * Note that it is possible for the statement_ pointer to be 0. This - * happens when the source has something like "@(E) ;". Note the null - * statement. + * @(posedge CLK) $display("clock rise"); + * @event_1 $display("event triggered."); + * @(data or negedge clk) $display("data or clock fall."); + * + * The elaborated netlist uses the NetEvent, NetEvWait and NetEvProbe + * classes. The NetEvWait class represents the part of the netlist + * that is executed by behavioral code. The process starts waiting on + * the NetEvent when it executes the NetEvWait step. Net NetEvProbe + * and NetEvTrig are structural and behavioral equivilents that + * trigger the event, and awakens any processes blocking in the + * associated wait. + * + * The basic data structure is: + * + * NetEvWait ---/---> NetEvent <----\---- NetEvProbe + * ... | | ... + * NetEvWait ---+ +-----NetEvProbe + * + * That is, many NetEvWait statements may wait on a single NetEvent + * object, and Many NetEvProbe objects may trigger the NetEvent + * object. */ NetProc* PEventStatement::elaborate_st(Design*des, const string&path, NetProc*enet) const @@ -1544,11 +1553,62 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path, NetScope*scope = des->find_scope(path); assert(scope); - /* Handle as a special case the block on an event. In this - case I generate a NetEvWait object to represent me. - XXXX Do I want to move all event handling to NetEvent style - event support? I think I do. */ + /* The Verilog wait () statement is a level + sensitive wait. Handle this special case by elaborating + something like this: + + begin + if (! ) @(posedge ) + + end + + This is equivilent, and uses the existing capapilities of + the netlist format. The resulting netlist should look like + this: + + NetBlock ---+---> NetCondit --+--> + | | + | +--> NetEvWait--> NetEvent + | + +---> + + This is quite a mouthful */ + + + if ((expr_.count() == 1) && (expr_[0]->type() == NetNEvent::POSITIVE)) { + + NetBlock*bl = new NetBlock(NetBlock::SEQU); + + NetNet*ex = expr_[0]->expr()->elaborate_net(des, path, + 1, 0, 0, 0); + if (ex == 0) { + expr_[0]->dump(cerr); + cerr << endl; + des->errors += 1; + return 0; + } + + NetEvent*ev = new NetEvent(scope->local_symbol()); + scope->add_event(ev); + + NetEvWait*we = new NetEvWait(ev, 0); + + NetEvProbe*po = new NetEvProbe(path+"."+scope->local_symbol(), + ev, NetEvProbe::POSEDGE, 1); + connect(po->pin(0), ex->pin(0)); + + des->add_node(po); + + NetESignal*ce = new NetESignal(ex); + NetCondit*co = new NetCondit(new NetEUnary('!', ce), we, 0); + bl->append(co); + bl->append(enet); + return bl; + } + + /* Handle as a special case the block on an event. In this + case I generate a NetEvWait object to represent me. */ if ((expr_.count() == 1) && (expr_[0]->expr() == 0)) { string ename = expr_[0]->name(); @@ -1577,12 +1637,16 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path, } } - /* Create a single NetPEvent, and a unique NetNEvent for each - 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. */ + /* Create A single NetEvent and NetEvWait. Then, create a + NetEvProbe for each conjunctive event in the event + list. The NetEvProbe object al refer back to the NetEvent + object. */ + + NetEvent*ev = new NetEvent(scope->local_symbol()); + scope->add_event(ev); + + NetEvWait*wa = new NetEvWait(ev, enet); - NetPEvent*pe = new NetPEvent(des->local_symbol(path), enet); for (unsigned idx = 0 ; idx < expr_.count() ; idx += 1) { if (expr_[idx]->expr() == 0) { cerr << get_line() << ": sorry: block on named events " @@ -1604,7 +1668,7 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path, NetNet*expr = expr_[idx]->expr()->elaborate_net(des, path, 0, 0, 0, 0); if (expr == 0) { - expr_[0]->dump(cerr); + expr_[idx]->dump(cerr); cerr << endl; des->errors += 1; continue; @@ -1613,16 +1677,35 @@ NetProc* PEventStatement::elaborate_st(Design*des, const string&path, 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)); + NetEvProbe*pr; + switch (expr_[idx]->type()) { + case NetNEvent::POSEDGE: + pr = new NetEvProbe(des->local_symbol(path), ev, + NetEvProbe::POSEDGE, pins); + break; - des->add_node(ne); + case NetNEvent::NEGEDGE: + pr = new NetEvProbe(des->local_symbol(path), ev, + NetEvProbe::NEGEDGE, pins); + break; + + case NetNEvent::ANYEDGE: + pr = new NetEvProbe(des->local_symbol(path), ev, + NetEvProbe::ANYEDGE, pins); + break; + + default: + assert(0); + } + + for (unsigned p = 0 ; p < pr->pin_count() ; p += 1) + connect(pr->pin(p), expr->pin(p)); + + des->add_node(pr); } - return pe; + return wa; } NetProc* PEventStatement::elaborate(Design*des, const string&path) const @@ -2078,6 +2161,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.157 2000/04/10 05:26:06 steve + * All events now use the NetEvent class. + * * Revision 1.156 2000/04/09 17:44:30 steve * Catch event declarations during scope elaborate. * diff --git a/emit.cc b/emit.cc index 305d3af52..37db19093 100644 --- a/emit.cc +++ b/emit.cc @@ -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.37 2000/04/04 03:20:15 steve Exp $" +#ident "$Id: emit.cc,v 1.38 2000/04/10 05:26:06 steve Exp $" #endif /* @@ -248,6 +248,11 @@ void NetCondit::emit_recurse_else(ostream&o, struct target_t*tgt) const else_->emit_proc(o, tgt); } +void NetEvProbe::emit_node(ostream&o, struct target_t*tgt) const +{ + tgt->net_probe(o, this); +} + bool NetEvTrig::emit_proc(ostream&o, struct target_t*tgt) const { return tgt->proc_trigger(o, this); @@ -260,6 +265,7 @@ bool NetEvWait::emit_proc(ostream&o, struct target_t*tgt) const bool NetEvWait::emit_recurse(ostream&o, struct target_t*tgt) const { + if (!statement_) return true; return statement_->emit_proc(o, tgt); } @@ -426,6 +432,9 @@ bool emit(ostream&o, const Design*des, const char*type) /* * $Log: emit.cc,v $ + * Revision 1.38 2000/04/10 05:26:06 steve + * All events now use the NetEvent class. + * * Revision 1.37 2000/04/04 03:20:15 steve * Simulate named event trigger and waits. * diff --git a/net_design.cc b/net_design.cc index 0adc34530..1dce54012 100644 --- a/net_design.cc +++ b/net_design.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: net_design.cc,v 1.3 2000/03/11 03:25:52 steve Exp $" +#ident "$Id: net_design.cc,v 1.4 2000/04/10 05:26:06 steve Exp $" #endif /* @@ -26,6 +26,7 @@ */ # include "netlist.h" +# include static string parse_first_name(string&path) { @@ -64,6 +65,14 @@ Design::~Design() { } +string Design::local_symbol(const string&path) +{ + strstream res; + res << "_L" << (lcounter_++) << ends; + + return path + "." + res.str(); +} + NetScope* Design::make_root_scope(const string&root) { assert(root_scope_ == 0); @@ -539,6 +548,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $Log: net_design.cc,v $ + * Revision 1.4 2000/04/10 05:26:06 steve + * All events now use the NetEvent class. + * * Revision 1.3 2000/03/11 03:25:52 steve * Locate scopes in statements. * diff --git a/net_event.cc b/net_event.cc index ae3f986b7..0129f6211 100644 --- a/net_event.cc +++ b/net_event.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: net_event.cc,v 1.1 2000/04/04 03:20:15 steve Exp $" +#ident "$Id: net_event.cc,v 1.2 2000/04/10 05:26:06 steve Exp $" #endif # include "netlist.h" @@ -58,6 +58,30 @@ const NetEvent* NetEvTrig::event() const return event_; } +NetEvProbe::NetEvProbe(const string&n, NetEvent*tgt, + edge_t t, unsigned p) +: NetNode(n, p), event_(tgt), edge_(t) +{ + for (unsigned idx = 0 ; idx < p ; idx += 1) { + pin(idx).set_dir(Link::INPUT); + pin(idx).set_name("P", idx); + } +} + +NetEvProbe::~NetEvProbe() +{ +} + +NetEvProbe::edge_t NetEvProbe::edge() const +{ + return edge_; +} + +const NetEvent* NetEvProbe::event() const +{ + return event_; +} + NetEvWait::NetEvWait(NetEvent*ev, NetProc*pr) : event_(ev), statement_(pr) { @@ -75,6 +99,9 @@ const NetEvent* NetEvWait::event() const /* * $Log: net_event.cc,v $ + * Revision 1.2 2000/04/10 05:26:06 steve + * All events now use the NetEvent class. + * * Revision 1.1 2000/04/04 03:20:15 steve * Simulate named event trigger and waits. * diff --git a/net_scope.cc b/net_scope.cc index 3d61b030f..a64e1a034 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -17,10 +17,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: net_scope.cc,v 1.2 2000/04/09 17:04:56 steve Exp $" +#ident "$Id: net_scope.cc,v 1.3 2000/04/10 05:26:06 steve Exp $" #endif # include "netlist.h" +# include /* * The NetScope class keeps a scope tree organized. Each node of the @@ -34,6 +35,7 @@ NetScope::NetScope(const string&n) : type_(NetScope::MODULE), name_(n), up_(0), sib_(0), sub_(0) { events_ = 0; + lcounter_ = 0; } NetScope::NetScope(NetScope*up, const string&n, NetScope::TYPE t) @@ -48,6 +50,7 @@ NetScope::~NetScope() { assert(sib_ == 0); assert(sub_ == 0); + lcounter_ = 0; } NetExpr* NetScope::set_parameter(const string&key, NetExpr*expr) @@ -151,9 +154,19 @@ const NetScope* NetScope::parent() const return up_; } +string NetScope::local_symbol() +{ + strstream res; + res << "_l" << (lcounter_++) << ends; + return res.str(); +} + /* * $Log: net_scope.cc,v $ + * Revision 1.3 2000/04/10 05:26:06 steve + * All events now use the NetEvent class. + * * Revision 1.2 2000/04/09 17:04:56 steve * uninitialized event_ list. * diff --git a/netlist.h b/netlist.h index 947fcb131..0d6c84950 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) && !defined(macintosh) -#ident "$Id: netlist.h,v 1.118 2000/04/04 03:20:15 steve Exp $" +#ident "$Id: netlist.h,v 1.119 2000/04/10 05:26:06 steve Exp $" #endif /* @@ -1262,6 +1262,11 @@ class NetCondit : public NetProc { * The NetEvTrig class represents trigger statements. Executing this * statement causes the referenced event to be triggered, which it * turn awakens the waiting threads. + * + * The NetEvProbe class is the structural equivilent of the NetEvTrig, + * in that it is a node and watches bit values that it receives. It + * checks for edges then if appropriate triggers the associated + * NetEvent. */ class NetEvent : public LineInfo { @@ -1321,6 +1326,26 @@ class NetEvWait : public NetProc { NetProc*statement_; }; +class NetEvProbe : public NetNode { + + public: + enum edge_t { ANYEDGE, POSEDGE, NEGEDGE }; + + explicit NetEvProbe(const string&n, NetEvent*tgt, + edge_t t, unsigned p); + ~NetEvProbe(); + + edge_t edge() const; + const NetEvent* event() const; + + virtual void emit_node(ostream&, struct target_t*) const; + virtual void dump_node(ostream&, unsigned ind) const; + + private: + NetEvent*event_; + edge_t edge_; +}; + /* * A forever statement is executed over and over again forever. Or * until its block is disabled. @@ -2181,6 +2206,10 @@ class NetScope { void run_defparams(class Design*); void evaluate_parameters(class Design*); + /* This method generates a non-hierarchical name that is + guaranteed to be unique within this scope. */ + string local_symbol(); + void dump(ostream&) const; void emit_scope(ostream&o, struct target_t*tgt) const; @@ -2203,6 +2232,8 @@ class NetScope { NetScope*up_; NetScope*sib_; NetScope*sub_; + + unsigned lcounter_; }; /* @@ -2368,6 +2399,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.119 2000/04/10 05:26:06 steve + * All events now use the NetEvent class. + * * Revision 1.118 2000/04/04 03:20:15 steve * Simulate named event trigger and waits. * diff --git a/t-vvm.cc b/t-vvm.cc index e55ea2c4b..b71669ad7 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) && !defined(macintosh) -#ident "$Id: t-vvm.cc,v 1.131 2000/04/09 16:55:42 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.132 2000/04/10 05:26:06 steve Exp $" #endif # include @@ -81,6 +81,7 @@ class target_vvm : public target_t { virtual void net_case_cmp(ostream&os, const NetCaseCmp*); virtual void net_const(ostream&os, const NetConst*); virtual void net_event(ostream&os, const NetNEvent*); + virtual void net_probe(ostream&os, const NetEvProbe*); virtual bool process(ostream&os, const NetProcTop*); virtual void proc_assign(ostream&os, const NetAssign*); virtual void proc_assign_mem(ostream&os, const NetAssignMem*); @@ -1760,6 +1761,7 @@ void target_vvm::net_const(ostream&os, const NetConst*gate) */ void target_vvm::net_event(ostream&os, const NetNEvent*gate) { + string gname = mangle(gate->name()); string pevent = mangle(gate->pevent()->name()); os << " /* " << gate->name() << " */" << endl; @@ -1769,21 +1771,28 @@ void target_vvm::net_event(ostream&os, const NetNEvent*gate) os << "static vvm_sync " << pevent << ";" << endl; } - os << "static vvm_pevent<" << gate->pin_count() << "> " << - mangle(gate->name()) << "(&" << pevent << ", "; switch (gate->type()) { + case NetNEvent::POSEDGE: case NetNEvent::POSITIVE: - os << "vvm_pevent<" << gate->pin_count() << ">::POSEDGE"; + assert(gate->pin_count() == 1); + os << "static vvm_posedge " << gname + << "(&" << pevent << ");" << endl; break; + case NetNEvent::NEGEDGE: - os << "vvm_pevent<"<< gate->pin_count() << ">::NEGEDGE"; + assert(gate->pin_count() == 1); + os << "static vvm_negedge " << gname + << "(&" << pevent << ");" << endl; break; + + case NetNEvent::ANYEDGE: - os << "vvm_pevent<" << gate->pin_count() << ">::ANYEDGE"; + assert(gate->pin_count() == 1); + os << "static vvm_anyedge " << gname + << "(&" << pevent << ");" << endl; break; } - os << ");" << endl; /* Connect this device as a receiver to the nexus that is my @@ -1798,6 +1807,44 @@ void target_vvm::net_event(ostream&os, const NetNEvent*gate) } } +void target_vvm::net_probe(ostream&os, const NetEvProbe*net) +{ + string mname = mangle(net->name()); + string mevent = mangle(net->event()->full_name()); + + switch (net->edge()) { + case NetEvProbe::POSEDGE: + assert(net->pin_count() == 1); + os << "static vvm_posedge " << mname + << "(&" << mevent << ");" << endl; + break; + + case NetNEvent::NEGEDGE: + assert(net->pin_count() == 1); + os << "static vvm_negedge " << mname + << "(&" << mevent << ");" << endl; + break; + + + case NetNEvent::ANYEDGE: + os << "static vvm_anyedge " << mname + << "(&" << mevent << ", " << net->pin_count() << ");" << endl; + break; + } + + + /* Connect this device as a receiver to the nexus that is my + source. Write the connect calls into the init code. */ + + for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) { + string nexus = nexus_from_link(&net->pin(idx)); + unsigned ncode = nexus_wire_map[nexus]; + + init_code << " nexus_wire_table["<name()) << ", " << idx << ");" << endl; + } +} + void target_vvm::start_process(ostream&os, const NetProcTop*proc) { process_counter += 1; @@ -2582,6 +2629,9 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.132 2000/04/10 05:26:06 steve + * All events now use the NetEvent class. + * * Revision 1.131 2000/04/09 16:55:42 steve * Donot create tables that have no entries. * @@ -2624,49 +2674,5 @@ extern const struct target tgt_vvm = { * * Revision 1.119 2000/03/20 17:40:33 steve * Do not link adder pins that ar unconnected. - * - * Revision 1.118 2000/03/18 23:22:37 steve - * Update the FF device to nexus style. - * - * Revision 1.117 2000/03/18 02:26:02 steve - * Update bufz to nexus style. - * - * Revision 1.116 2000/03/18 01:26:59 steve - * Generate references into a table of nexus objects instead of - * generating lots of isolated nexus objects. Easier on linkers - * and compilers, - * - * Add missing nexus support for l-value bit selects, - * - * Detemplatize the vvm_mux type. - * - * Fix up the vvm_nexus destructor to disconnect from drivers. - * - * Revision 1.115 2000/03/17 20:21:14 steve - * Detemplatize the vvm_signal_t class. - * - * Revision 1.114 2000/03/17 19:23:59 steve - * nor2 and and2 optimized gates. - * - * Revision 1.113 2000/03/17 17:25:53 steve - * Adder and comparator in nexus style. - * - * Revision 1.112 2000/03/17 03:05:13 steve - * Update vvm_mult to nexus style. - * - * Revision 1.111 2000/03/17 02:22:03 steve - * vvm_clshift implementation without templates. - * - * Revision 1.110 2000/03/16 23:13:49 steve - * Update LPM_MUX to nexus style. - * - * Revision 1.109 2000/03/16 21:47:27 steve - * Update LMP_CLSHIFT to use nexus interface. - * - * Revision 1.108 2000/03/16 19:03:03 steve - * Revise the VVM backend to use nexus objects so that - * drivers and resolution functions can be used, and - * the t-vvm module doesn't need to write a zillion - * output functions. */ diff --git a/target.cc b/target.cc index 6cbec7223..7b4e16700 100644 --- a/target.cc +++ b/target.cc @@ -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.33 2000/04/04 03:20:15 steve Exp $" +#ident "$Id: target.cc,v 1.34 2000/04/10 05:26:06 steve Exp $" #endif # include "target.h" @@ -162,6 +162,13 @@ void target_t::net_event(ostream&os, const NetNEvent*net) net->dump_node(cerr, 4); } +void target_t::net_probe(ostream&os, const NetEvProbe*net) +{ + cerr << "target (" << typeid(*this).name() << "): " + "Unhandled probe trigger node" << endl; + net->dump_node(cerr, 4); +} + bool target_t::process(ostream&os, const NetProcTop*top) { return top->statement()->emit_proc(os, this); @@ -346,6 +353,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex) /* * $Log: target.cc,v $ + * Revision 1.34 2000/04/10 05:26:06 steve + * All events now use the NetEvent class. + * * Revision 1.33 2000/04/04 03:20:15 steve * Simulate named event trigger and waits. * diff --git a/target.h b/target.h index 01fe35bac..f3288d790 100644 --- a/target.h +++ b/target.h @@ -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.32 2000/04/04 03:20:15 steve Exp $" +#ident "$Id: target.h,v 1.33 2000/04/10 05:26:06 steve Exp $" #endif # include "netlist.h" @@ -92,6 +92,7 @@ struct target_t { virtual void net_case_cmp(ostream&os, const NetCaseCmp*); virtual void net_const(ostream&os, const NetConst*); virtual void net_event(ostream&os, const NetNEvent*); + virtual void net_probe(ostream&os, const NetEvProbe*); /* Output a process (called for each process). It is up to the target to recurse if desired. */ @@ -154,6 +155,9 @@ extern const struct target *target_table[]; /* * $Log: target.h,v $ + * Revision 1.33 2000/04/10 05:26:06 steve + * All events now use the NetEvent class. + * * Revision 1.32 2000/04/04 03:20:15 steve * Simulate named event trigger and waits. * diff --git a/vvm/vvm.h b/vvm/vvm.h index cecaee78d..af5a699fb 100644 --- a/vvm/vvm.h +++ b/vvm/vvm.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vvm.h,v 1.35 2000/03/26 16:55:41 steve Exp $" +#ident "$Id: vvm.h,v 1.36 2000/04/10 05:26:06 steve Exp $" #endif # include @@ -90,6 +90,11 @@ inline vpip_bit_t B_NOT(vpip_bit_t l) return StX; } +/* + * These functions return true if the transition from A to B is a + * Verilog type of negedge of posedge. + */ +extern bool negedge(vpip_bit_t from, vpip_bit_t to); extern bool posedge(vpip_bit_t from, vpip_bit_t to); extern ostream& b_output (ostream&os, vpip_bit_t); @@ -121,6 +126,9 @@ class vvm_event { /* * $Log: vvm.h,v $ + * Revision 1.36 2000/04/10 05:26:06 steve + * All events now use the NetEvent class. + * * Revision 1.35 2000/03/26 16:55:41 steve * Remove the vvm_bits_t abstract class. * diff --git a/vvm/vvm_bit.cc b/vvm/vvm_bit.cc index 6c271a43a..4707ea5cd 100644 --- a/vvm/vvm_bit.cc +++ b/vvm/vvm_bit.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vvm_bit.cc,v 1.11 2000/03/26 16:55:41 steve Exp $" +#ident "$Id: vvm_bit.cc,v 1.12 2000/04/10 05:26:07 steve Exp $" #endif # include "vvm.h" @@ -48,6 +48,20 @@ ostream& b_output (ostream&os, vpip_bit_t bit) return os; } +bool negedge(vpip_bit_t from, vpip_bit_t to) +{ + if (B_IS0(from)) + return false; + + if (B_ISX(from) || B_ISZ(from)) + return B_IS0(to); + + if (B_IS1(from)) + return ! B_IS1(to); + + return false; +} + bool posedge(vpip_bit_t from, vpip_bit_t to) { if (B_IS1(from)) @@ -100,6 +114,9 @@ vpip_bit_t add_with_carry(vpip_bit_t l, vpip_bit_t r, vpip_bit_t&carry) /* * $Log: vvm_bit.cc,v $ + * Revision 1.12 2000/04/10 05:26:07 steve + * All events now use the NetEvent class. + * * Revision 1.11 2000/03/26 16:55:41 steve * Remove the vvm_bits_t abstract class. * diff --git a/vvm/vvm_gates.h b/vvm/vvm_gates.h index f9359dc06..3e20f07a3 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) && !defined(macintosh) -#ident "$Id: vvm_gates.h,v 1.55 2000/04/08 05:49:59 steve Exp $" +#ident "$Id: vvm_gates.h,v 1.56 2000/04/10 05:26:07 steve Exp $" #endif # include "vvm.h" @@ -793,13 +793,8 @@ class vvm_bufz : public vvm_nexus::recvr_t, public vvm_nexus::drive_t { /* * Threads use the vvm_sync to wait for something to happen. This - * class cooperates with the vvm_pevent class that is the actual gates - * that receive signals. By handling the suspension and the awakening - * separately, I can trivially handle event OR expressions. - * - * When there is an event expression in the source, the elaborator - * makes NetNEvent objects, which are approximately represented by the - * vvm_pevent class. + * class cooperates with the various event source classes that receive + * events and trigger the associated vvm_sync object. */ class vvm_sync { @@ -817,56 +812,70 @@ class vvm_sync { vvm_sync& operator= (const vvm_sync&); }; -template class vvm_pevent : public vvm_nexus::recvr_t { +class vvm_anyedge : public vvm_nexus::recvr_t { + public: - enum EDGE { ANYEDGE, POSEDGE, NEGEDGE }; + explicit vvm_anyedge(vvm_sync*tgt, unsigned n); + ~vvm_anyedge(); - explicit vvm_pevent(vvm_sync*tgt, EDGE e) - : target_(tgt), edge_(e) - { for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) - value_[idx] = HiZ; - } - - vpip_bit_t get(unsigned idx) const { return value_[idx]; } - - void init_P(int idx, vpip_bit_t val) - { assert(idx < WIDTH); - value_[idx] = val; - } + void init_P(unsigned idx, vpip_bit_t val); private: - void take_value(unsigned key, vpip_bit_t val) { set_P(key, val); } + void take_value(unsigned key, vpip_bit_t val); - void set_P(unsigned idx, vpip_bit_t val) - { if (value_[idx] == val) return; - switch (edge_) { - case ANYEDGE: - target_->wakeup(); - break; - case POSEDGE: - if (B_IS1(val)) - target_->wakeup(); - break; - case NEGEDGE: - if (B_IS0(val)) - target_->wakeup(); - break; - } - value_[idx] = val; - } + vpip_bit_t*val_; + unsigned nval_; - private: - vvm_sync*target_; - vpip_bit_t value_[WIDTH]; - EDGE edge_; + vvm_sync*sync_; private: // not implemented - vvm_pevent(const vvm_pevent&); - vvm_pevent& operator= (const vvm_pevent&); + vvm_anyedge(const vvm_anyedge&); + vvm_anyedge& operator= (const vvm_anyedge&); +}; + +class vvm_negedge : public vvm_nexus::recvr_t { + + public: + explicit vvm_negedge(vvm_sync*tgt); + ~vvm_negedge(); + + void init_P(int idx, vpip_bit_t val); + + private: + void take_value(unsigned key, vpip_bit_t val); + vpip_bit_t val_; + + vvm_sync*sync_; + + private: // not implemented + vvm_negedge(const vvm_negedge&); + vvm_negedge& operator= (const vvm_negedge&); +}; + +class vvm_posedge : public vvm_nexus::recvr_t { + + public: + explicit vvm_posedge(vvm_sync*tgt); + ~vvm_posedge(); + + void init_P(int idx, vpip_bit_t val); + + private: + void take_value(unsigned key, vpip_bit_t val); + vpip_bit_t val_; + + vvm_sync*sync_; + + private: // not implemented + vvm_posedge(const vvm_posedge&); + vvm_posedge& operator= (const vvm_posedge&); }; /* * $Log: vvm_gates.h,v $ + * Revision 1.56 2000/04/10 05:26:07 steve + * All events now use the NetEvent class. + * * Revision 1.55 2000/04/08 05:49:59 steve * Fix memory object compile problems. * @@ -890,70 +899,5 @@ template class vvm_pevent : public vvm_nexus::recvr_t { * Replace the vpip_bit_t with a typedef and * define values for all the different bit * values, including strengths. - * - * Revision 1.48 2000/03/18 23:22:37 steve - * Update the FF device to nexus style. - * - * Revision 1.47 2000/03/18 02:26:02 steve - * Update bufz to nexus style. - * - * Revision 1.46 2000/03/18 01:27:00 steve - * Generate references into a table of nexus objects instead of - * generating lots of isolated nexus objects. Easier on linkers - * and compilers, - * - * Add missing nexus support for l-value bit selects, - * - * Detemplatize the vvm_mux type. - * - * Fix up the vvm_nexus destructor to disconnect from drivers. - * - * Revision 1.45 2000/03/17 19:24:00 steve - * nor2 and and2 optimized gates. - * - * Revision 1.44 2000/03/17 17:25:53 steve - * Adder and comparator in nexus style. - * - * Revision 1.43 2000/03/17 03:36:07 steve - * Remove some useless template parameters. - * - * Revision 1.42 2000/03/17 03:05:13 steve - * Update vvm_mult to nexus style. - * - * Revision 1.41 2000/03/17 02:22:03 steve - * vvm_clshift implementation without templates. - * - * Revision 1.40 2000/03/16 23:13:49 steve - * Update LPM_MUX to nexus style. - * - * Revision 1.39 2000/03/16 21:47:27 steve - * Update LMP_CLSHIFT to use nexus interface. - * - * Revision 1.38 2000/03/16 19:03:04 steve - * Revise the VVM backend to use nexus objects so that - * drivers and resolution functions can be used, and - * the t-vvm module doesn't need to write a zillion - * output functions. - * - * Revision 1.37 2000/02/23 04:43:43 steve - * Some compilers do not accept the not symbol. - * - * Revision 1.36 2000/02/23 02:56:57 steve - * Macintosh compilers do not support ident. - * - * Revision 1.35 2000/01/13 03:35:35 steve - * Multiplication all the way to simulation. - * - * Revision 1.34 1999/12/19 20:57:07 steve - * Proper init_ method prototype. - * - * Revision 1.33 1999/12/16 02:42:15 steve - * Simulate carry output on adders. - * - * Revision 1.32 1999/12/12 19:47:54 steve - * Remove the useless vvm_simulation class. - * - * Revision 1.31 1999/12/05 02:24:09 steve - * Synthesize LPM_RAM_DQ for writes into memories. */ #endif diff --git a/vvm/vvm_pevent.cc b/vvm/vvm_pevent.cc index eda8bbc42..57cdce2f0 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) && !defined(macintosh) -#ident "$Id: vvm_pevent.cc,v 1.5 2000/02/23 02:56:57 steve Exp $" +#ident "$Id: vvm_pevent.cc,v 1.6 2000/04/10 05:26:07 steve Exp $" #endif # include "vvm.h" @@ -43,8 +43,96 @@ void vvm_sync::wakeup() } +vvm_posedge::vvm_posedge(vvm_sync*tgt) +: sync_(tgt) +{ + val_ = StX; +} + +vvm_posedge::~vvm_posedge() +{ +} + +void vvm_posedge::init_P(int, vpip_bit_t val) +{ + val_ = val; +} + +void vvm_posedge::take_value(unsigned, vpip_bit_t val) +{ + if (val == val_) + return; + + if (posedge(val_, val)) + sync_->wakeup(); + + val_ = val; +} + + +vvm_negedge::vvm_negedge(vvm_sync*tgt) +: sync_(tgt) +{ + val_ = StX; +} + +vvm_negedge::~vvm_negedge() +{ +} + +void vvm_negedge::init_P(int, vpip_bit_t val) +{ + val_ = val; +} + +void vvm_negedge::take_value(unsigned, vpip_bit_t val) +{ + if (val == val_) + return; + + if (negedge(val_, val)) + sync_->wakeup(); + + val_ = val; +} + +vvm_anyedge::vvm_anyedge(vvm_sync*tgt, unsigned n) +: nval_(n), sync_(tgt) +{ + val_ = new vpip_bit_t[nval_]; + for (unsigned idx = 0 ; idx < nval_ ; idx += 1) + val_[idx] = StX; +} + +vvm_anyedge::~vvm_anyedge() +{ + delete[]val_; +} + +void vvm_anyedge::init_P(unsigned key, vpip_bit_t val) +{ + assert(key < nval_); + val_[key] = val; +} + +void vvm_anyedge::take_value(unsigned key, vpip_bit_t val) +{ + assert(key < nval_); + if (val == val_[key]) + return; + + if (! B_EQ(val, val_[key])) + sync_->wakeup(); + + val_[key] = val; +} + + /* * $Log: vvm_pevent.cc,v $ + * Revision 1.6 2000/04/10 05:26:07 steve + * All events now use the NetEvent class. + * * Revision 1.5 2000/02/23 02:56:57 steve * Macintosh compilers do not support ident. *