From 7859de1e4e405e50bbf6062fa4a8a149b0f3f855 Mon Sep 17 00:00:00 2001 From: steve Date: Tue, 10 Nov 1998 00:48:31 +0000 Subject: [PATCH] Add support it vvm target for level-sensitive triggers (i.e. the Verilog wait). Fix display of $time is format strings. --- t-vvm.cc | 89 +++++++++++++++++++++++++++++++------------ vvm/display.cc | 41 +++++++++++++------- vvm/vvm.h | 8 +++- vvm/vvm_bit.cc | 41 ++++++++++++-------- vvm/vvm_gates.h | 8 +++- vvm/vvm_simulation.cc | 9 ++++- vvm/vvm_thread.h | 13 ++++++- 7 files changed, 149 insertions(+), 60 deletions(-) diff --git a/t-vvm.cc b/t-vvm.cc index 5f1679bc7..87a5c6219 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.4 1998/11/09 18:55:34 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.5 1998/11/10 00:48:31 steve Exp $" #endif # include @@ -445,12 +445,12 @@ void target_vvm::start_process(ostream&os, const NetProcTop*proc) os << " { }" << endl; os << " ~thread" << process_counter << "_t() { }" << endl; os << endl; - os << " void go() { (this->*step_)(); }" << endl; + os << " bool go() { return (this->*step_)(); }" << endl; os << " private:" << endl; - os << " void (thread" << process_counter << + os << " bool (thread" << process_counter << "_t::*step_)();" << endl; - os << " void step_0_() {" << endl; + os << " bool step_0_() {" << endl; } /* @@ -566,25 +566,57 @@ void target_vvm::proc_event(ostream&os, const NetPEvent*proc) thread_step_ += 1; os << setw(indent_) << "" << "step_ = &step_" << thread_step_ << "_;" << endl; - os << setw(indent_) << "" << mangle(proc->name()) << - ".wait(vvm_pevent::"; - switch (proc->edge()) { - case NetPEvent::ANYEDGE: - os << "ANYEDGE"; - break; - case NetPEvent::POSEDGE: - os << "POSEDGE"; - break; - case NetPEvent::NEGEDGE: - os << "NEGEDGE"; - break; - case NetPEvent::POSITIVE: - os << "POSITIVE"; - break; + + /* POSITIVE is for the wait construct, and needs to be handled + specially. The structure of the generated code is: + + if (event.get()==V1) { + return true; + } else { + event.wait(vvm_pevent::POSEDGE, this); + return false; + } + + This causes the wait to not even block the thread if the + event value is already positive, otherwise wait for a + rising edge. All the edge triggers look like this: + + event.wait(vvm_pevent::POSEDGE, this); + return false; + + POSEDGE is replaced with the correct type for the desired + edge. */ + + if (proc->edge() == NetPEvent::POSITIVE) { + os << setw(indent_) << "" << "if (" << + mangle(proc->name()) << ".get()==V1) {" << endl; + os << setw(indent_+3) << "" << "return true;" << endl; + os << setw(indent_) << "" << "} else {" << endl; + os << setw(indent_+3) << "" << mangle(proc->name()) << + ".wait(vvm_pevent::POSEDGE, this);" << endl; + os << setw(indent_+3) << "" << "return false;" << endl; + os << setw(indent_) << "" << "}" << endl; + + } else { + os << setw(indent_) << "" << mangle(proc->name()) << + ".wait(vvm_pevent::"; + switch (proc->edge()) { + case NetPEvent::ANYEDGE: + os << "ANYEDGE"; + break; + case NetPEvent::POSITIVE: + case NetPEvent::POSEDGE: + os << "POSEDGE"; + break; + case NetPEvent::NEGEDGE: + os << "NEGEDGE"; + break; + } + os << ", this);" << endl; + os << setw(indent_+3) << "" << "return false;" << endl; } - os << ", this);" << endl; os << " }" << endl; - os << " void step_" << thread_step_ << "_()" << endl; + os << " bool step_" << thread_step_ << "_()" << endl; os << " {" << endl; proc->emit_proc_recurse(os, this); @@ -599,8 +631,9 @@ void target_vvm::proc_delay(ostream&os, const NetPDelay*proc) os << " step_ = &step_" << thread_step_ << "_;" << endl; os << " sim_->thread_delay(" << proc->delay() << ", this);" << endl; + os << " return false;" << endl; os << " }" << endl; - os << " void step_" << thread_step_ << "_()" << endl; + os << " bool step_" << thread_step_ << "_()" << endl; os << " {" << endl; proc->emit_proc_recurse(os, this); @@ -609,10 +642,11 @@ void target_vvm::proc_delay(ostream&os, const NetPDelay*proc) void target_vvm::end_process(ostream&os, const NetProcTop*proc) { if (proc->type() == NetProcTop::KALWAYS) { - os << " step_ = &step_0_;" << endl; - os << " step_0_(); // XXXX" << endl; + os << setw(indent_) << "" << "step_ = &step_0_;" << endl; + os << setw(indent_) << "" << "return true;" << endl; } else { - os << " step_ = 0;" << endl; + os << setw(indent_) << "" << "step_ = 0;" << endl; + os << setw(indent_) << "" << "return false;" << endl; } os << " }" << endl; @@ -628,6 +662,11 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.5 1998/11/10 00:48:31 steve + * Add support it vvm target for level-sensitive + * triggers (i.e. the Verilog wait). + * Fix display of $time is format strings. + * * Revision 1.4 1998/11/09 18:55:34 steve * Add procedural while loops, * Parse procedural for loops, diff --git a/vvm/display.cc b/vvm/display.cc index e6d44b487..87d974fec 100644 --- a/vvm/display.cc +++ b/vvm/display.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: display.cc,v 1.1 1998/11/09 23:44:10 steve Exp $" +#ident "$Id: display.cc,v 1.2 1998/11/10 00:48:31 steve Exp $" #endif # include "vvm.h" @@ -28,31 +28,35 @@ static void format_bit(ostream&os, class vvm_calltf_parm*parm) { switch (parm->type()) { case vvm_calltf_parm::NONE: - cout << "z"; + os << "z"; break; case vvm_calltf_parm::ULONG: - cout << ((parm->as_ulong()&1) ? "0" : "1"); + os << ((parm->as_ulong()&1) ? "0" : "1"); break; case vvm_calltf_parm::STRING: - cout << parm->as_string(); + os << parm->as_string(); break; case vvm_calltf_parm::BITS: - cout << parm->as_bits()->get_bit(0); + os << parm->as_bits()->get_bit(0); break; } } -static void format_dec(ostream&os, class vvm_calltf_parm*parm) +static void format_dec(vvm_simulation*sim, ostream&os, + class vvm_calltf_parm*parm) { switch (parm->type()) { + case vvm_calltf_parm::TIME: + os << sim->get_sim_time(); + break; case vvm_calltf_parm::NONE: - cout << "0"; + os << "0"; break; case vvm_calltf_parm::ULONG: - cout << parm->as_ulong(); + os << parm->as_ulong(); break; case vvm_calltf_parm::STRING: - cout << parm->as_string(); + os << parm->as_string(); break; case vvm_calltf_parm::BITS: { unsigned long val = 0; @@ -62,7 +66,7 @@ static void format_dec(ostream&os, class vvm_calltf_parm*parm) if (bstr->get_bit(idx) == V1) val |= mask; mask <<= 1; } - cout << val; + os << val; break; } } @@ -71,6 +75,9 @@ static void format_dec(ostream&os, class vvm_calltf_parm*parm) static void format_name(ostream&os, class vvm_calltf_parm*parm) { switch (parm->type()) { + case vvm_calltf_parm::TIME: + os << "$time"; + break; case vvm_calltf_parm::NONE: break; case vvm_calltf_parm::ULONG: @@ -85,7 +92,8 @@ static void format_name(ostream&os, class vvm_calltf_parm*parm) } } -static unsigned format(const string&str, unsigned nparms, +static unsigned format(vvm_simulation*sim, const string&str, + unsigned nparms, class vvm_calltf_parm*parms) { char prev = 0; @@ -101,7 +109,7 @@ static unsigned format(const string&str, unsigned nparms, break; case 'd': case 'D': - format_dec(cout, parms+next_parm); + format_dec(sim, cout, parms+next_parm); next_parm += 1; break; case 'm': @@ -144,8 +152,8 @@ void Sdisplay(vvm_simulation*sim, const string&name, cout << parms[idx].as_ulong(); break; case vvm_calltf_parm::STRING: - idx += format(parms[idx].as_string(), - nparms-idx-1, parms+idx+1); + idx += format(sim, parms[idx].as_string(), + nparms-idx-1, parms+idx+1); break; case vvm_calltf_parm::BITS: cout << *parms[idx].as_bits(); @@ -198,6 +206,11 @@ void Smonitor(vvm_simulation*sim, const string&name, /* * $Log: display.cc,v $ + * Revision 1.2 1998/11/10 00:48:31 steve + * Add support it vvm target for level-sensitive + * triggers (i.e. the Verilog wait). + * Fix display of $time is format strings. + * * Revision 1.1 1998/11/09 23:44:10 steve * Add vvm library. * diff --git a/vvm/vvm.h b/vvm/vvm.h index de73f1499..0f360c9dd 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) -#ident "$Id: vvm.h,v 1.1 1998/11/09 23:44:10 steve Exp $" +#ident "$Id: vvm.h,v 1.2 1998/11/10 00:48:31 steve Exp $" #endif # include @@ -81,6 +81,7 @@ class vvm_bits_t { virtual vvm_bit_t get_bit(unsigned idx) const =0; }; +extern ostream& operator << (ostream&os, vvm_bit_t); extern ostream& operator << (ostream&os, const vvm_bits_t&str); /* @@ -214,6 +215,11 @@ class vvm_monitor_t { /* * $Log: vvm.h,v $ + * Revision 1.2 1998/11/10 00:48:31 steve + * Add support it vvm target for level-sensitive + * triggers (i.e. the Verilog wait). + * Fix display of $time is format strings. + * * Revision 1.1 1998/11/09 23:44:10 steve * Add vvm library. * diff --git a/vvm/vvm_bit.cc b/vvm/vvm_bit.cc index 9337fdb9d..d6e942a49 100644 --- a/vvm/vvm_bit.cc +++ b/vvm/vvm_bit.cc @@ -17,29 +17,35 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvm_bit.cc,v 1.1 1998/11/09 23:44:10 steve Exp $" +#ident "$Id: vvm_bit.cc,v 1.2 1998/11/10 00:48:31 steve Exp $" #endif # include "vvm.h" +ostream& operator << (ostream&os, vvm_bit_t bit) +{ + switch (bit) { + case V0: + os << "0"; + break; + case V1: + os << "1"; + break; + case Vx: + os << "x"; + break; + case Vz: + os << "z"; + break; + } + return os; +} + ostream& operator << (ostream&os, const vvm_bits_t&str) { os << str.get_width() << "b'"; for (unsigned idx = str.get_width() ; idx > 0 ; idx -= 1) - switch (str.get_bit(idx)) { - case V0: - os << "0"; - break; - case V1: - os << "1"; - break; - case Vx: - os << "x"; - break; - case Vz: - os << "z"; - break; - } + os << str.get_bit(idx); return os; } @@ -94,6 +100,11 @@ vvm_bit_t add_with_carry(vvm_bit_t l, vvm_bit_t r, vvm_bit_t&carry) /* * $Log: vvm_bit.cc,v $ + * Revision 1.2 1998/11/10 00:48:31 steve + * Add support it vvm target for level-sensitive + * triggers (i.e. the Verilog wait). + * Fix display of $time is format strings. + * * Revision 1.1 1998/11/09 23:44:10 steve * Add vvm library. * diff --git a/vvm/vvm_gates.h b/vvm/vvm_gates.h index 97597a5a2..eeed0fda4 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.1 1998/11/09 23:44:11 steve Exp $" +#ident "$Id: vvm_gates.h,v 1.2 1998/11/10 00:48:31 steve Exp $" #endif # include "vvm.h" @@ -205,6 +205,7 @@ class vvm_pevent { void wait(EDGE, vvm_thread*); void set(vvm_simulation*sim, unsigned, vvm_bit_t val); + vvm_bit_t get() const { return value_; } private: vvm_bit_t value_; @@ -218,6 +219,11 @@ class vvm_pevent { /* * $Log: vvm_gates.h,v $ + * Revision 1.2 1998/11/10 00:48:31 steve + * Add support it vvm target for level-sensitive + * triggers (i.e. the Verilog wait). + * Fix display of $time is format strings. + * * Revision 1.1 1998/11/09 23:44:11 steve * Add vvm library. * diff --git a/vvm/vvm_simulation.cc b/vvm/vvm_simulation.cc index 421ad286c..454750126 100644 --- a/vvm/vvm_simulation.cc +++ b/vvm/vvm_simulation.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvm_simulation.cc,v 1.1 1998/11/09 23:44:11 steve Exp $" +#ident "$Id: vvm_simulation.cc,v 1.2 1998/11/10 00:48:31 steve Exp $" #endif # include "vvm.h" @@ -184,7 +184,7 @@ class delay_event : public vvm_event { public: delay_event(vvm_thread*thr) : thr_(thr) { } - void event_function() { thr_->go(); } + void event_function() { while (thr_->go()) /* empty */; } private: vvm_thread*thr_; }; @@ -210,6 +210,11 @@ void vvm_simulation::thread_active(vvm_thread*thr) /* * $Log: vvm_simulation.cc,v $ + * Revision 1.2 1998/11/10 00:48:31 steve + * Add support it vvm target for level-sensitive + * triggers (i.e. the Verilog wait). + * Fix display of $time is format strings. + * * Revision 1.1 1998/11/09 23:44:11 steve * Add vvm library. * diff --git a/vvm/vvm_thread.h b/vvm/vvm_thread.h index 205a9dd97..3f1ab0d1a 100644 --- a/vvm/vvm_thread.h +++ b/vvm/vvm_thread.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvm_thread.h,v 1.1 1998/11/09 23:44:11 steve Exp $" +#ident "$Id: vvm_thread.h,v 1.2 1998/11/10 00:48:31 steve Exp $" #endif # include "vvm.h" @@ -38,7 +38,11 @@ class vvm_thread { public: explicit vvm_thread(vvm_simulation*sim); virtual ~vvm_thread(); - virtual void go() =0; + + // This method executes a setp of the thread. The engine will + // continue to call go as long as it returns true. The thread + // will return false if it is ready to give up the CPU. + virtual bool go() =0; protected: vvm_simulation*const sim_; @@ -46,6 +50,11 @@ class vvm_thread { /* * $Log: vvm_thread.h,v $ + * Revision 1.2 1998/11/10 00:48:31 steve + * Add support it vvm target for level-sensitive + * triggers (i.e. the Verilog wait). + * Fix display of $time is format strings. + * * Revision 1.1 1998/11/09 23:44:11 steve * Add vvm library. *