fork-join support in vvm.

This commit is contained in:
steve 2000-04-15 19:51:30 +00:00
parent d033509359
commit 7484feceb5
5 changed files with 130 additions and 25 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: netlist.cc,v 1.113 2000/04/12 20:02:53 steve Exp $"
#ident "$Id: netlist.cc,v 1.114 2000/04/15 19:51:30 steve Exp $"
#endif
# include <cassert>
@ -1590,6 +1590,22 @@ void NetBlock::append(NetProc*cur)
}
}
const NetProc* NetBlock::proc_first() const
{
if (last_ == 0)
return 0;
return last_->next_;
}
const NetProc* NetBlock::proc_next(const NetProc*cur) const
{
if (cur == last_)
return 0;
return cur->next_;
}
NetBUFZ::NetBUFZ(const string&n)
: NetNode(n, 2)
{
@ -2446,6 +2462,9 @@ bool NetUDP::sequ_glob_(string input, char output)
/*
* $Log: netlist.cc,v $
* Revision 1.114 2000/04/15 19:51:30 steve
* fork-join support in vvm.
*
* Revision 1.113 2000/04/12 20:02:53 steve
* Finally remove the NetNEvent and NetPEvent classes,
* Get synthesis working with the NetEvWait class,

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.121 2000/04/12 20:02:53 steve Exp $"
#ident "$Id: netlist.h,v 1.122 2000/04/15 19:51:30 steve Exp $"
#endif
/*
@ -996,7 +996,7 @@ class NetUDP_COMB : public NetNode {
* linked into the netlist. However, elaborating a process may cause
* special nodes to be created to handle things like events.
*/
class NetProc : public LineInfo {
class NetProc : public LineInfo {
public:
explicit NetProc();
@ -1143,12 +1143,14 @@ class NetAssignMemNB : public NetAssignMem_ {
private:
};
/* A block is stuff like begin-end blocks, that contain an ordered
list of NetProc statements.
NOTE: The emit method calls the target->proc_block function but
does not recurse. It is up to the target-supplied proc_block
function to call emit_recurse. */
/*
* A block is stuff like begin-end blocks, that contain an ordered
* list of NetProc statements.
*
* NOTE: The emit method calls the target->proc_block function but
* does not recurse. It is up to the target-supplied proc_block
* function to call emit_recurse.
*/
class NetBlock : public NetProc {
public:
@ -1161,7 +1163,14 @@ class NetBlock : public NetProc {
void append(NetProc*);
const NetProc*proc_first() const;
const NetProc*proc_next(const NetProc*cur) const;
// This version of emit_recurse scans all the statements of
// the begin-end block sequentially. It is typically of use
// for sequential blocks.
void emit_recurse(ostream&, struct target_t*) const;
virtual bool emit_proc(ostream&, struct target_t*) const;
virtual int match_proc(struct proc_match_t*);
virtual void dump(ostream&, unsigned ind) const;
@ -2344,6 +2353,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.122 2000/04/15 19:51:30 steve
* fork-join support in vvm.
*
* Revision 1.121 2000/04/12 20:02:53 steve
* Finally remove the NetNEvent and NetPEvent classes,
* Get synthesis working with the NetEvWait class,

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: parse.y,v 1.89 2000/04/12 04:23:58 steve Exp $"
#ident "$Id: parse.y,v 1.90 2000/04/15 19:51:30 steve Exp $"
#endif
# include "parse_misc.h"
@ -430,6 +430,12 @@ event_expression_list
delete $3;
$$ = tmp;
}
| event_expression_list ',' event_expression
{ svector<PEEvent*>*tmp = new svector<PEEvent*>(*$1, *$3);
delete $1;
delete $3;
$$ = tmp;
}
;
event_expression

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.136 2000/04/15 02:25:32 steve Exp $"
#ident "$Id: t-vvm.cc,v 1.137 2000/04/15 19:51:30 steve Exp $"
#endif
# include <iostream>
@ -957,15 +957,6 @@ void target_vvm::task_def(ostream&os, const NetTaskDef*def)
os << "static bool " << name << "_step_0_(vvm_thread*thr);" << endl;
#if 0
os << "class " << name << " : public vvm_thread {" << endl;
os << " public:" << endl;
os << " " << name << "(vvm_thread*th)" << endl;
os << " { step_ = " << name << "_step_0_; back_ = th; }" << endl;
os << " ~" << name << "() { }" << endl;
os << "};" << endl;
#endif
defn << "static bool " << name << "_step_0_(vvm_thread*thr) {" << endl;
def->proc()->emit_proc(os, this);
@ -1984,11 +1975,81 @@ void target_vvm::proc_assign_mem_nb(ostream&os, const NetAssignMemNB*amem)
bool target_vvm::proc_block(ostream&os, const NetBlock*net)
{
if (net->type() == NetBlock::PARA) {
cerr << "sorry: vvm cannot emit parallel blocks." << endl;
return false;
if (net->type() == NetBlock::SEQU) {
net->emit_recurse(os, this);
return true;
}
net->emit_recurse(os, this);
unsigned exit_step = thread_step_ + 1;
thread_step_ += 1;
const NetProc*cur;
unsigned cnt = 0;
unsigned idx;
// Declare the exit step...
os << "static bool " << thread_class_ << "_step_" << exit_step
<< "_(vvm_thread*thr);" << endl;
// Declare the first steps for all the threads to be created,
// and count those threads while I'm at it.
for (cur = net->proc_first() ; cur ; cur = net->proc_next(cur)) {
cnt += 1;
os << "static bool " << thread_class_ << "_step_"
<< (exit_step+cnt) << "_(vvm_thread*thr);" << endl;
}
thread_step_ += cnt;
// Write the code to start all the threads, then pause the
// current thread.
defn << " thr->callee_ = new vvm_thread["<<cnt<<"];" << endl;
defn << " thr->ncallee_ = " << cnt << ";" << endl;
for (idx = 0 ; idx < cnt ; idx += 1) {
defn << " thr->callee_["<<idx<<"].back_ = thr;" << endl;
defn << " thr->callee_["<<idx<<"].step_ = &"
<< thread_class_ << "_step_" << (exit_step+idx+1)
<< "_;" << endl;
defn << " thr->callee_["<<idx<<"].thread_yield();" << endl;
}
defn << " thr->step_ = &" << thread_class_ << "_step_"
<< exit_step << "_;" << endl;
defn << " return false;" << endl;
defn << "}" << endl;
// Generate the thread steps. At the end of the thread proc,
// write code to manage the join.
for (idx = 0, cur = net->proc_first()
; cur ; idx +=1, cur = net->proc_next(cur)) {
defn << "static bool " << thread_class_ << "_step_"
<< (exit_step+idx+1) << "_(vvm_thread*thr) {" << endl;
cur->emit_proc(os, this);
defn << " thr->back_->ncallee_ -= 1;" << endl;
defn << " if (thr->back_->ncallee_ == 0)" << endl;
defn << " thr->back_->thread_yield();" << endl;
defn << " return false;" << endl;
defn << "}" << endl;
}
// Finally, start the exit step.
defn << "static bool " << thread_class_ << "_step_" << exit_step
<< "_(vvm_thread*thr) {" << endl;
defn << " delete[]thr->callee_;" << endl;
defn << " thr->callee_ = 0;" << endl;
return true;
}
@ -2565,6 +2626,9 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
* Revision 1.137 2000/04/15 19:51:30 steve
* fork-join support in vvm.
*
* Revision 1.136 2000/04/15 02:25:32 steve
* Support chained events.
*

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_thread.h,v 1.8 2000/04/15 01:44:59 steve Exp $"
#ident "$Id: vvm_thread.h,v 1.9 2000/04/15 19:51:30 steve Exp $"
#endif
# include "vvm.h"
@ -85,6 +85,7 @@ class vvm_thread {
// These members are used to handle task invocations.
vvm_thread*callee_;
unsigned ncallee_;
vvm_thread*back_;
// The sync class uses this to list all the threads blocked on it.
@ -94,6 +95,9 @@ class vvm_thread {
/*
* $Log: vvm_thread.h,v $
* Revision 1.9 2000/04/15 19:51:30 steve
* fork-join support in vvm.
*
* Revision 1.8 2000/04/15 01:44:59 steve
* Document the calling convention.
*