diff --git a/ivl_target.h b/ivl_target.h index 7d145c76a..e9b61df72 100644 --- a/ivl_target.h +++ b/ivl_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: ivl_target.h,v 1.38 2001/03/29 02:52:39 steve Exp $" +#ident "$Id: ivl_target.h,v 1.39 2001/03/30 05:49:52 steve Exp $" #endif #ifdef __cplusplus @@ -250,6 +250,7 @@ typedef enum ivl_statement_type_e { IVL_ST_CONDIT, IVL_ST_DELAY, IVL_ST_DELAYX, + IVL_ST_FORK, IVL_ST_STASK, IVL_ST_TRIGGER, IVL_ST_WAIT, @@ -671,9 +672,9 @@ extern ivl_statement_type_t ivl_statement_type(ivl_statement_t net); * statement types can be passed to the function. */ - /* IVL_ST_BLOCK */ + /* IVL_ST_BLOCK, IVL_ST_FORK */ extern unsigned ivl_stmt_block_count(ivl_statement_t net); - /* IVL_ST_BLOCK */ + /* IVL_ST_BLOCK, IVL_ST_FORK */ extern ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net, unsigned i); /* IVL_ST_CONDIT */ extern ivl_expr_t ivl_stmt_cond_expr(ivl_statement_t net); @@ -720,6 +721,9 @@ _END_DECL /* * $Log: ivl_target.h,v $ + * Revision 1.39 2001/03/30 05:49:52 steve + * Generate code for fork/join statements. + * * Revision 1.38 2001/03/29 02:52:39 steve * Add unary ~ operator to tgt-vvp. * diff --git a/t-dll-api.cc b/t-dll-api.cc index e0f578412..fbae3d3e6 100644 --- a/t-dll-api.cc +++ b/t-dll-api.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-dll-api.cc,v 1.26 2001/03/29 03:47:38 steve Exp $" +#ident "$Id: t-dll-api.cc,v 1.27 2001/03/30 05:49:52 steve Exp $" #endif # include "t-dll.h" @@ -557,16 +557,27 @@ extern "C" ivl_statement_type_t ivl_statement_type(ivl_statement_t net) extern "C" unsigned ivl_stmt_block_count(ivl_statement_t net) { - assert(net->type_ == IVL_ST_BLOCK); - return net->u_.block_.nstmt_; + switch (net->type_) { + case IVL_ST_BLOCK: + case IVL_ST_FORK: + return net->u_.block_.nstmt_; + default: + assert(0); + return 0; + } } extern "C" ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net, unsigned i) { - assert(net->type_ == IVL_ST_BLOCK); - assert(i < net->u_.block_.nstmt_); - return net->u_.block_.stmt_ + i; + switch (net->type_) { + case IVL_ST_BLOCK: + case IVL_ST_FORK: + return net->u_.block_.stmt_ + i; + default: + assert(0); + return 0; + } } extern "C" ivl_expr_t ivl_stmt_cond_expr(ivl_statement_t net) @@ -716,6 +727,9 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net) /* * $Log: t-dll-api.cc,v $ + * Revision 1.27 2001/03/30 05:49:52 steve + * Generate code for fork/join statements. + * * Revision 1.26 2001/03/29 03:47:38 steve * Behavioral trigger statements. * diff --git a/t-dll-proc.cc b/t-dll-proc.cc index 135b1e41d..6f829a610 100644 --- a/t-dll-proc.cc +++ b/t-dll-proc.cc @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll-proc.cc,v 1.14 2001/03/29 03:47:38 steve Exp $" +#ident "$Id: t-dll-proc.cc,v 1.15 2001/03/30 05:49:52 steve Exp $" #endif # include "target.h" @@ -152,7 +152,9 @@ bool dll_target::proc_block(const NetBlock*net) it, so fill in the block fields of the existing statement, and generate the contents for the statement array. */ - stmt_cur_->type_ = IVL_ST_BLOCK; + stmt_cur_->type_ = (net->type() == NetBlock::SEQU) + ? IVL_ST_BLOCK + : IVL_ST_FORK; stmt_cur_->u_.block_.nstmt_ = count; stmt_cur_->u_.block_.stmt_ = (struct ivl_statement_s*) calloc(count, sizeof(struct ivl_statement_s)); @@ -356,6 +358,9 @@ void dll_target::proc_while(const NetWhile*net) /* * $Log: t-dll-proc.cc,v $ + * Revision 1.15 2001/03/30 05:49:52 steve + * Generate code for fork/join statements. + * * Revision 1.14 2001/03/29 03:47:38 steve * Behavioral trigger statements. * diff --git a/t-dll.h b/t-dll.h index c7017d194..ad8205269 100644 --- a/t-dll.h +++ b/t-dll.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll.h,v 1.26 2001/03/29 02:52:39 steve Exp $" +#ident "$Id: t-dll.h,v 1.27 2001/03/30 05:49:52 steve Exp $" #endif # include "target.h" @@ -341,7 +341,7 @@ struct ivl_statement_s { ivl_expr_t rval_; } assign_; - struct { /* IVL_ST_BLOCK */ + struct { /* IVL_ST_BLOCK, IVL_ST_FORK */ struct ivl_statement_s*stmt_; unsigned nstmt_; } block_; @@ -387,6 +387,9 @@ struct ivl_statement_s { /* * $Log: t-dll.h,v $ + * Revision 1.27 2001/03/30 05:49:52 steve + * Generate code for fork/join statements. + * * Revision 1.26 2001/03/29 02:52:39 steve * Add unary ~ operator to tgt-vvp. * diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 9601f810f..6e1f9c145 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: stub.c,v 1.31 2001/03/29 02:52:39 steve Exp $" +#ident "$Id: stub.c,v 1.32 2001/03/30 05:49:52 steve Exp $" #endif /* @@ -187,6 +187,17 @@ static void show_statement(ivl_statement_t net, unsigned ind) show_statement(ivl_stmt_sub_stmt(net), ind+2); break; + case IVL_ST_FORK: { + unsigned cnt = ivl_stmt_block_count(net); + fprintf(out, "%*sfork\n", ind, ""); + for (idx = 0 ; idx < cnt ; idx += 1) { + ivl_statement_t cur = ivl_stmt_block_stmt(net, idx); + show_statement(cur, ind+4); + } + fprintf(out, "%*sjoin\n", ind, ""); + break; + } + case IVL_ST_NOOP: fprintf(out, "%*s/* noop */;\n", ind, ""); break; @@ -449,6 +460,9 @@ DECLARE_CYGWIN_DLL(DllMain); /* * $Log: stub.c,v $ + * Revision 1.32 2001/03/30 05:49:52 steve + * Generate code for fork/join statements. + * * Revision 1.31 2001/03/29 02:52:39 steve * Add unary ~ operator to tgt-vvp. * diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 0b5291f1f..c1ee332c4 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvp_process.c,v 1.11 2001/03/29 03:47:38 steve Exp $" +#ident "$Id: vvp_process.c,v 1.12 2001/03/30 05:49:53 steve Exp $" #endif # include "vvp_priv.h" @@ -185,6 +185,44 @@ static int show_stmt_delay(ivl_statement_t net) return rc; } +static int show_stmt_fork(ivl_statement_t net) +{ + unsigned idx; + int rc = 0; + static int transient_id = 0; + unsigned cnt = ivl_stmt_block_count(net); + + int out = transient_id++; + + /* Draw a fork statement for all but one of the threads of the + fork/join. Send the threads off to a bit of code where they + are implemented. */ + for (idx = 0 ; idx < cnt-1 ; idx += 1) { + fprintf(vvp_out, " %%fork t_%u;\n", transient_id+idx); + } + + /* Draw code to execute the remaining thread in the current + thread, then generate enough joins to merge back together. */ + rc += show_statement(ivl_stmt_block_stmt(net, cnt-1)); + + for (idx = 0 ; idx < cnt-1 ; idx += 1) { + fprintf(vvp_out, " %%join;\n"); + } + fprintf(vvp_out, " %%jmp t_%u;\n", out); + + for (idx = 0 ; idx < cnt-1 ; idx += 1) { + fprintf(vvp_out, "t_%u\n", transient_id+idx); + rc += show_statement(ivl_stmt_block_stmt(net, idx)); + fprintf(vvp_out, " %%end;\n"); + } + + /* This is the label for the out. Use this to branck around + the implementations of all the child threads. */ + fprintf(vvp_out, "t_%u\n", out); + + return rc; +} + /* * noop statements are implemented by doing nothing. */ @@ -277,6 +315,10 @@ static int show_statement(ivl_statement_t net) rc += show_stmt_delay(net); break; + case IVL_ST_FORK: + rc += show_stmt_fork(net); + break; + case IVL_ST_NOOP: rc += show_stmt_noop(net); break; @@ -302,50 +344,7 @@ static int show_statement(ivl_statement_t net) return rc; } -#if 0 -static void show_stmt_event_wait(ivl_statement_t net) -{ - ivl_edge_type_t edge = ivl_stmt_edge(net); - ivl_nexus_t nex; - const char*estr = ""; - - assert(ivl_stmt_pins(net) == 1); - nex = ivl_stmt_pin(net, 0); - - switch (edge) { - case IVL_EDGE_POS: - estr = "posedge"; - break; - case IVL_EDGE_NEG: - estr = "negedge"; - break; - case IVL_EDGE_ANY: - estr = "anyedge"; - break; - } - - fprintf(vvp_out, "L_%s .event %s, ", ivl_nexus_name(nex), estr); - draw_nexus_input(nex); - fprintf(vvp_out, ";\n"); - -} -#endif -#if 0 -static void show_stmt_events(ivl_statement_t net) -{ - switch (ivl_statement_type(net)) { - case IVL_ST_WAIT: - show_stmt_event_wait(net); - return; - case IVL_ST_DELAY: - show_stmt_events(ivl_stmt_sub_stmt(net)); - return; - default: - return; - } -} -#endif /* * The process as a whole is surrounded by this code. We generate a @@ -361,11 +360,7 @@ int draw_process(ivl_process_t net, void*x) local_count = 0; fprintf(vvp_out, " .scope S_%s;\n", ivl_scope_name(scope)); -#if 0 - /* Show any .event statements that are needed to support this - thread. */ - show_stmt_events(stmt); -#endif + /* Generate the entry label. Just give the thread a number so that we ar certain the label is unique. */ fprintf(vvp_out, "T_%d\n", thread_count); @@ -399,6 +394,9 @@ int draw_process(ivl_process_t net, void*x) /* * $Log: vvp_process.c,v $ + * Revision 1.12 2001/03/30 05:49:53 steve + * Generate code for fork/join statements. + * * Revision 1.11 2001/03/29 03:47:38 steve * Behavioral trigger statements. *