diff --git a/README.txt b/README.txt index 3eac2dcaa..930710d62 100644 --- a/README.txt +++ b/README.txt @@ -354,10 +354,6 @@ constructs. - Event controls inside non-blocking assignments are not supported. i.e.: a <= @(posedge clk) b; - - Lists of named events of the form @(event_1 or event_2) are not - supported. Named events are otherwise supported, and lists of - other kinds of events are also supported. - - Macro arguments are not supported. `define macros are supported, but they cannot take arguments. diff --git a/ivl.def b/ivl.def index df2dfc47e..1291f1fd9 100644 --- a/ivl.def +++ b/ivl.def @@ -178,11 +178,12 @@ ivl_stmt_cond_false ivl_stmt_cond_true ivl_stmt_delay_expr ivl_stmt_delay_val -ivl_stmt_event +ivl_stmt_events ivl_stmt_lval ivl_stmt_lvals ivl_stmt_lwidth ivl_stmt_name +ivl_stmt_nevent ivl_stmt_nexus ivl_stmt_nexus_count ivl_stmt_parm diff --git a/ivl_target.h b/ivl_target.h index 603843288..f9f4e8a85 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: ivl_target.h,v 1.123 2003/11/08 20:06:21 steve Exp $" +#ident "$Id: ivl_target.h,v 1.124 2003/12/03 02:46:24 steve Exp $" #endif #ifdef __cplusplus @@ -1168,8 +1168,9 @@ extern ivl_statement_t ivl_stmt_cond_true(ivl_statement_t net); extern ivl_expr_t ivl_stmt_delay_expr(ivl_statement_t net); /* IVL_ST_DELAY */ extern unsigned long ivl_stmt_delay_val(ivl_statement_t net); - /* IVL_ST_WAIT */ -extern ivl_event_t ivl_stmt_event(ivl_statement_t net); + /* IVL_ST_WAIT IVL_ST_TRIGGER */ +extern unsigned ivl_stmt_nevent(ivl_statement_t net); +extern ivl_event_t ivl_stmt_events(ivl_statement_t net, unsigned idx); /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_DEASSIGN IVL_ST_FORCE IVL_ST_RELEASE */ extern ivl_lval_t ivl_stmt_lval(ivl_statement_t net, unsigned idx); @@ -1232,6 +1233,9 @@ _END_DECL /* * $Log: ivl_target.h,v $ + * Revision 1.124 2003/12/03 02:46:24 steve + * Add support for wait on list of named events. + * * Revision 1.123 2003/11/08 20:06:21 steve * Spelling fixes in comments. * diff --git a/t-dll-api.cc b/t-dll-api.cc index d2f7db586..219ab0141 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: t-dll-api.cc,v 1.105 2003/11/10 20:59:03 steve Exp $" +#ident "$Id: t-dll-api.cc,v 1.106 2003/12/03 02:46:24 steve Exp $" #endif # include "config.h" @@ -1720,13 +1720,34 @@ extern "C" unsigned long ivl_stmt_delay_val(ivl_statement_t net) return net->u_.delay_.delay_; } -extern "C" ivl_event_t ivl_stmt_event(ivl_statement_t net) +extern "C" unsigned ivl_stmt_nevent(ivl_statement_t net) { switch (net->type_) { case IVL_ST_WAIT: - return net->u_.wait_.event_; + return net->u_.wait_.nevent; + case IVL_ST_TRIGGER: - return net->u_.trig_.event_; + return 1; + + default: + assert(0); + } + return 0; +} + +extern "C" ivl_event_t ivl_stmt_events(ivl_statement_t net, unsigned idx) +{ + switch (net->type_) { + case IVL_ST_WAIT: + assert(idx < net->u_.wait_.nevent); + if (net->u_.wait_.nevent == 1) + return net->u_.wait_.event; + else + return net->u_.wait_.events[idx]; + + case IVL_ST_TRIGGER: + assert(idx == 0); + return net->u_.wait_.event; default: assert(0); } @@ -1913,6 +1934,9 @@ extern "C" ivl_variable_type_t ivl_variable_type(ivl_variable_t net) /* * $Log: t-dll-api.cc,v $ + * Revision 1.106 2003/12/03 02:46:24 steve + * Add support for wait on list of named events. + * * Revision 1.105 2003/11/10 20:59:03 steve * Design::get_flag returns const char* instead of string. * diff --git a/t-dll-proc.cc b/t-dll-proc.cc index 9d578280d..b7d5e6c7c 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: t-dll-proc.cc,v 1.60 2003/06/24 01:38:03 steve Exp $" +#ident "$Id: t-dll-proc.cc,v 1.61 2003/12/03 02:46:24 steve Exp $" #endif # include "config.h" @@ -698,6 +698,7 @@ bool dll_target::proc_trigger(const NetEvTrig*net) assert(stmt_cur_->type_ == IVL_ST_NONE); stmt_cur_->type_ = IVL_ST_TRIGGER; + stmt_cur_->u_.wait_.nevent = 1; /* Locate the event by name. Save the ivl_event_t in the statement so that the generator can find it easily. */ @@ -707,7 +708,7 @@ bool dll_target::proc_trigger(const NetEvTrig*net) for (unsigned idx = 0 ; idx < ev_scope->nevent_ ; idx += 1) { const char*ename = ivl_event_basename(ev_scope->event_[idx]); if (strcmp(ev->name(), ename) == 0) { - stmt_cur_->u_.wait_.event_ = ev_scope->event_[idx]; + stmt_cur_->u_.wait_.event = ev_scope->event_[idx]; break; } } @@ -734,63 +735,71 @@ bool dll_target::proc_wait(const NetEvWait*net) stmt_cur_->u_.wait_.stmt_ = (struct ivl_statement_s*) calloc(1, sizeof(struct ivl_statement_s)); - if (net->nevents() != 1) { - cerr << net->get_line() << ": internal error: " - << "multiple events not supported." << endl; - return false; + stmt_cur_->u_.wait_.nevent = net->nevents(); + if (net->nevents() > 1) { + stmt_cur_->u_.wait_.events = (ivl_event_t*) + calloc(net->nevents(), sizeof(ivl_event_t*)); } - /* Locate the event by name. Save the ivl_event_t in the - statement so that the generator can find it easily. */ - const NetEvent*ev = net->event(0); - ivl_scope_t ev_scope = lookup_scope_(ev->scope()); + for (unsigned edx = 0 ; edx < net->nevents() ; edx += 1) { - for (unsigned idx = 0 ; idx < ev_scope->nevent_ ; idx += 1) { - const char*ename = ivl_event_basename(ev_scope->event_[idx]); - if (strcmp(ev->name(), ename) == 0) { - stmt_cur_->u_.wait_.event_ = ev_scope->event_[idx]; - break; - } - } + /* Locate the event by name. Save the ivl_event_t in the + statement so that the generator can find it easily. */ + const NetEvent*ev = net->event(edx); + ivl_scope_t ev_scope = lookup_scope_(ev->scope()); + ivl_event_t ev_tmp; - /* If this is an event with a probe, then connect up the - pins. This wasn't done during the ::event method because - the signals weren't scanned yet. */ - - if (ev->nprobe() >= 1) { - ivl_event_t evnt = stmt_cur_->u_.wait_.event_; - - unsigned iany = 0; - unsigned ineg = evnt->nany; - unsigned ipos = ineg + evnt->nneg; - - for (unsigned idx = 0 ; idx < ev->nprobe() ; idx += 1) { - const NetEvProbe*pr = ev->probe(idx); - unsigned base = 0; - - switch (pr->edge()) { - case NetEvProbe::ANYEDGE: - base = iany; - iany += pr->pin_count(); + for (unsigned idx = 0 ; idx < ev_scope->nevent_ ; idx += 1) { + const char*ename = ivl_event_basename(ev_scope->event_[idx]); + if (strcmp(ev->name(), ename) == 0) { + ev_tmp = ev_scope->event_[idx]; break; - case NetEvProbe::NEGEDGE: - base = ineg; - ineg += pr->pin_count(); - break; - case NetEvProbe::POSEDGE: - base = ipos; - ipos += pr->pin_count(); - break; - } - - for (unsigned bit = 0; bit < pr->pin_count(); bit += 1) { - ivl_nexus_t nex = (ivl_nexus_t) - pr->pin(bit).nexus()->t_cookie(); - assert(nex); - evnt->pins[base+bit] = nex; } } + if (net->nevents() == 1) + stmt_cur_->u_.wait_.event = ev_tmp; + else + stmt_cur_->u_.wait_.events[edx] = ev_tmp; + + /* If this is an event with a probe, then connect up the + pins. This wasn't done during the ::event method because + the signals weren't scanned yet. */ + + if (ev->nprobe() >= 1) { + unsigned iany = 0; + unsigned ineg = ev_tmp->nany; + unsigned ipos = ineg + ev_tmp->nneg; + + for (unsigned idx = 0 ; idx < ev->nprobe() ; idx += 1) { + const NetEvProbe*pr = ev->probe(idx); + unsigned base = 0; + + switch (pr->edge()) { + case NetEvProbe::ANYEDGE: + base = iany; + iany += pr->pin_count(); + break; + case NetEvProbe::NEGEDGE: + base = ineg; + ineg += pr->pin_count(); + break; + case NetEvProbe::POSEDGE: + base = ipos; + ipos += pr->pin_count(); + break; + } + + for (unsigned bit = 0 + ; bit < pr->pin_count() + ; bit += 1) { + ivl_nexus_t nex = (ivl_nexus_t) + pr->pin(bit).nexus()->t_cookie(); + assert(nex); + ev_tmp->pins[base+bit] = nex; + } + } + } } /* The ivl_statement_t for the wait statement is not complete @@ -833,6 +842,9 @@ void dll_target::proc_while(const NetWhile*net) /* * $Log: t-dll-proc.cc,v $ + * Revision 1.61 2003/12/03 02:46:24 steve + * Add support for wait on list of named events. + * * Revision 1.60 2003/06/24 01:38:03 steve * Various warnings fixed. * diff --git a/t-dll.h b/t-dll.h index 578fe5727..ebe0543a5 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: t-dll.h,v 1.107 2003/11/10 20:59:04 steve Exp $" +#ident "$Id: t-dll.h,v 1.108 2003/12/03 02:46:24 steve Exp $" #endif # include "target.h" @@ -652,16 +652,16 @@ struct ivl_statement_s { ivl_expr_t*parms_; } stask_; - struct { /* IVL_ST_TRIGGER */ - ivl_event_t event_; - } trig_; - struct { /* IVL_ST_UTASK */ ivl_scope_t def; } utask_; - struct { /* IVL_ST_WAIT */ - ivl_event_t event_; + struct { /* IVL_ST_TRIGGER IVL_ST_WAIT */ + unsigned nevent; + union { + ivl_event_t event; + ivl_event_t*events; + }; ivl_statement_t stmt_; } wait_; @@ -683,6 +683,9 @@ struct ivl_variable_s { /* * $Log: t-dll.h,v $ + * Revision 1.108 2003/12/03 02:46:24 steve + * Add support for wait on list of named events. + * * Revision 1.107 2003/11/10 20:59:04 steve * Design::get_flag returns const char* instead of string. * diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 16bf6f375..1ef3a2494 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: stub.c,v 1.82 2003/12/03 01:54:07 steve Exp $" +#ident "$Id: stub.c,v 1.83 2003/12/03 02:46:24 steve Exp $" #endif # include "config.h" @@ -484,14 +484,21 @@ static void show_statement(ivl_statement_t net, unsigned ind) break; case IVL_ST_WAIT: { - ivl_event_t evnt = ivl_stmt_event(net); + fprintf(out, "%*s@(", ind, ""); + const char*comma = ""; - if (evnt == 0) - fprintf(out, "%*s@(/*ERROR*/)\n", ind, ""); - else - fprintf(out, "%*s@(%s)\n", ind, "", - ivl_event_name(evnt)); + for (idx = 0 ; idx < ivl_stmt_nevent(net) ; idx += 1) { + ivl_event_t evnt = ivl_stmt_events(net, idx); + if (evnt == 0) + fprintf(out, "%s/*ERROR*/", comma); + else + fprintf(out, "%s%s", comma, ivl_event_name(evnt)); + + comma = ", "; + } + + fprintf(out, ")\n"); show_statement(ivl_stmt_sub_stmt(net), ind+4); break; } @@ -885,6 +892,9 @@ int target_design(ivl_design_t des) /* * $Log: stub.c,v $ + * Revision 1.83 2003/12/03 02:46:24 steve + * Add support for wait on list of named events. + * * Revision 1.82 2003/12/03 01:54:07 steve * Handle erroneous event lists. * diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index c1d6fa590..e3af20d47 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vvp_process.c,v 1.90 2003/10/25 02:07:57 steve Exp $" +#ident "$Id: vvp_process.c,v 1.91 2003/12/03 02:46:24 steve Exp $" #endif # include "vvp_priv.h" @@ -1223,7 +1223,7 @@ static int show_stmt_repeat(ivl_statement_t net, ivl_scope_t sscope) static int show_stmt_trigger(ivl_statement_t net) { - ivl_event_t ev = ivl_stmt_event(net); + ivl_event_t ev = ivl_stmt_events(net, 0); assert(ev); fprintf(vvp_out, " %%set E_%p, 0;\n", ev); return 0; @@ -1243,9 +1243,23 @@ static int show_stmt_utask(ivl_statement_t net) static int show_stmt_wait(ivl_statement_t net, ivl_scope_t sscope) { - ivl_event_t ev = ivl_stmt_event(net); - fprintf(vvp_out, " %%wait E_%p;\n", ev); + if (ivl_stmt_nevent(net) == 1) { + ivl_event_t ev = ivl_stmt_events(net, 0); + fprintf(vvp_out, " %%wait E_%p;\n", ev); + } else { + unsigned idx; + static unsigned int cascade_counter = 0; + ivl_event_t ev = ivl_stmt_events(net, 0); + fprintf(vvp_out, "Ewait_%u .event/or E_%p", cascade_counter, ev); + + for (idx = 1 ; idx < ivl_stmt_nevent(net) ; idx += 1) { + ev = ivl_stmt_events(net, idx); + fprintf(vvp_out, ", E_%p", ev); + } + fprintf(vvp_out, ";\n %%wait Ewait_%u;\n", cascade_counter); + cascade_counter += 1; + } /* Always clear the expression lookaside after a %wait. Anything can happen while the thread is waiting. */ clear_expression_lookaside(); @@ -1560,6 +1574,9 @@ int draw_func_definition(ivl_scope_t scope) /* * $Log: vvp_process.c,v $ + * Revision 1.91 2003/12/03 02:46:24 steve + * Add support for wait on list of named events. + * * Revision 1.90 2003/10/25 02:07:57 steve * vvp_signal_label does not return a unique string. *