Support chained events.

This commit is contained in:
steve 2000-04-15 02:25:32 +00:00
parent 62c6422724
commit d033509359
3 changed files with 79 additions and 11 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: t-vvm.cc,v 1.135 2000/04/14 23:31:53 steve Exp $"
#ident "$Id: t-vvm.cc,v 1.136 2000/04/15 02:25:32 steve Exp $"
#endif
# include <iostream>
@ -150,6 +150,8 @@ class target_vvm : public target_t {
map<verinum,unsigned,less_verinum>number_constants;
unsigned number_counter;
unsigned selector_counter;
};
@ -745,6 +747,7 @@ void target_vvm::start_design(ostream&os, const Design*mod)
string_counter = 1;
number_counter = 1;
nexus_wire_counter = 1;
selector_counter = 0;
init_code << "static void design_init()" << endl;
init_code << "{" << endl;
@ -2418,13 +2421,34 @@ bool target_vvm::proc_wait(ostream&os, const NetEvWait*wait)
defn << " thr->step_ = &" << thread_class_ << "_step_"
<< out_step << "_;" << endl;
for (unsigned idx = 0 ; idx < wait->nevents() ; idx+= 1) {
const NetEvent*ev = wait->event(idx);
assert(ev);
string ename = mangle(ev->full_name());
defn << " " << ename << ".wait(thr); // "
<< wait->get_line() << ": @" << ev->full_name()
<< "..." << endl;
if (wait->nevents() == 1) {
const NetEvent*ev = wait->event(0);
assert(ev);
string ename = mangle(ev->full_name());
defn << " " << ename << ".wait(thr); // "
<< wait->get_line() << ": @" << ev->full_name()
<< "..." << endl;
} else {
/* If there are many events to wait for, generate a
selector that is a vvm_sync that I chain to the
source vvm_sync objects. Then, wait on the selector
object instead. */
unsigned id = selector_counter++;
os << "static vvm_sync selector_" << id << ";" << endl;
for (unsigned idx = 0 ; idx < wait->nevents() ; idx+= 1) {
const NetEvent*ev = wait->event(idx);
assert(ev);
string ename = mangle(ev->full_name());
init_code << " selector_" << id
<< ".chain_sync(&" << ename << "); // "
<< wait->get_line() << ": @" << ev->full_name()
<< "..." << endl;
}
defn << " selector_" << id << ".wait(thr);"
<< endl;
}
defn << " return false;" << endl;
@ -2541,6 +2565,9 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
* Revision 1.136 2000/04/15 02:25:32 steve
* Support chained events.
*
* Revision 1.135 2000/04/14 23:31:53 steve
* No more class derivation from vvm_thread.
*

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: vvm_gates.h,v 1.56 2000/04/10 05:26:07 steve Exp $"
#ident "$Id: vvm_gates.h,v 1.57 2000/04/15 02:25:32 steve Exp $"
#endif
# include "vvm.h"
@ -795,7 +795,15 @@ 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 various event source classes that receive
* events and trigger the associated vvm_sync object.
*
* CHAINING
* A thread can only wait on one vvm_sync object. To get the effect of
* waiting on many vvm_sync objects, vvm_sync objects can be
* chained. That is, a vvm_sync object can be configured to receive
* triggers from other vvm_sync objects. That is the job of the
* chain_sync() method.
*/
class vvm_sync {
public:
@ -804,9 +812,15 @@ class vvm_sync {
void wait(vvm_thread*);
void wakeup();
// Receive triggers from the specified source.
void chain_sync(vvm_sync*src);
private:
vvm_thread*hold_;
vvm_sync**tgt_;
unsigned ntgt_;
private: // not implemented
vvm_sync(const vvm_sync&);
vvm_sync& operator= (const vvm_sync&);
@ -873,6 +887,9 @@ class vvm_posedge : public vvm_nexus::recvr_t {
/*
* $Log: vvm_gates.h,v $
* Revision 1.57 2000/04/15 02:25:32 steve
* Support chained events.
*
* Revision 1.56 2000/04/10 05:26:07 steve
* All events now use the NetEvent class.
*

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: vvm_pevent.cc,v 1.8 2000/04/12 16:08:46 steve Exp $"
#ident "$Id: vvm_pevent.cc,v 1.9 2000/04/15 02:25:32 steve Exp $"
#endif
# include "vvm.h"
@ -25,7 +25,7 @@
# include "vvm_thread.h"
vvm_sync::vvm_sync()
: hold_(0)
: hold_(0), tgt_(0), ntgt_(0)
{
}
@ -45,9 +45,30 @@ void vvm_sync::wakeup()
assert(tmp->sync_back_ == this);
tmp->sync_back_ = 0;
tmp->thread_yield();
for (unsigned idx = 0 ; idx < ntgt_ ; idx += 1)
tgt_[idx]->wakeup();
}
}
void vvm_sync::chain_sync(vvm_sync*src)
{
if (src->ntgt_ == 0) {
src->tgt_ = new vvm_sync*[1];
src->tgt_[0] = this;
src->ntgt_ = 1;
} else {
vvm_sync**tmp = new vvm_sync*[src->ntgt_+1];
for (unsigned idx = 0 ; idx < src->ntgt_ ; idx += 1)
tmp[idx] = src->tgt_[idx];
tmp[src->ntgt_] = this;
src->ntgt_ += 1;
delete [] src->tgt_;
src->tgt_ = tmp;
}
}
vvm_posedge::vvm_posedge(vvm_sync*tgt)
: sync_(tgt)
@ -136,6 +157,9 @@ void vvm_anyedge::take_value(unsigned key, vpip_bit_t val)
/*
* $Log: vvm_pevent.cc,v $
* Revision 1.9 2000/04/15 02:25:32 steve
* Support chained events.
*
* Revision 1.8 2000/04/12 16:08:46 steve
* Backwards sense of assert test.
*