From fc49420cb55dbd644cba63b9076c7eb964ac453e Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Sat, 5 Sep 2009 10:15:10 +0100 Subject: [PATCH 01/10] Add user control over implicit sensitivity list warnings. This patch adds two new warning classes that can be enabled or disabled via the -W command line option. The first controls whether a warning is generated if a part select within an always @* statement causes the entire vector to be added to the implicit sensitivity list. The second controls whether a warning is generated if a word select within an always @* statement causes the entire array to be added to the implicit sensitivity list. The first class is not automatically enabled by -Wall, the second class is. --- compiler.h | 5 +++++ driver/iverilog.man | 20 ++++++++++++++++++-- driver/main.c | 19 +++++++++++++++++++ main.cc | 8 ++++++++ net_nex_input.cc | 11 +++++++---- 5 files changed, 57 insertions(+), 6 deletions(-) diff --git a/compiler.h b/compiler.h index a9922baf9..747e411cc 100644 --- a/compiler.h +++ b/compiler.h @@ -88,6 +88,11 @@ extern bool warn_ob_select; /* Warn about structures that may have infinite loops. */ extern bool warn_inf_loop; +/* Warn about always @* statements where a part or word select causes + sensitivity to an entire vector or array. */ +extern bool warn_sens_entire_vec; +extern bool warn_sens_entire_arr; + /* This is true if verbose output is requested. */ extern bool verbose_flag; diff --git a/driver/iverilog.man b/driver/iverilog.man index c81d463eb..ca2c00951 100644 --- a/driver/iverilog.man +++ b/driver/iverilog.man @@ -259,8 +259,8 @@ after a \fB-Wall\fP argument to suppress isolated warning types. .TP 8 .B all -This enables the implicit, portbind, select-range and timescale warning -categories. +This enables the implicit, portbind, select-range, timescale, and +sensitivity-entire-array warning categories. .TP 8 .B implicit @@ -303,6 +303,22 @@ verified. It is expected that many of the warnings will be false positives, since the code treats the value of all variables and signals as indeterminate. +.TP 8 +.B sensitivity-entire-vector +This enables warnings for when a part select within an "always @*" +statement results in the entire vector being added to the implicit +sensitivity list. Although this behaviour is prescribed by the IEEE +standard, it is not what might be expected and can have performance +implications if the vector is large. + +.TP 8 +.B sensitivity-entire-array +This enables warnings for when a word select within an "always @*" +statement results in the entire array being added to the implicit +sensitivity list. Although this behaviour is prescribed by the IEEE +standard, it is not what might be expected and can have performance +implications if the array is large. + .SH "SYSTEM FUNCTION TABLE FILES" If the source file name as a \fB.sft\fP suffix, then it is taken to be a system function table file. A System function table file is used to diff --git a/driver/main.c b/driver/main.c index c75eb09c2..a56ca6ef0 100644 --- a/driver/main.c +++ b/driver/main.c @@ -477,6 +477,7 @@ static void process_warning_switch(const char*name) process_warning_switch("portbind"); process_warning_switch("select-range"); process_warning_switch("timescale"); + process_warning_switch("sensitivity-entire-array"); } else if (strcmp(name,"implicit") == 0) { if (! strchr(warning_flags, 'i')) strcat(warning_flags, "i"); @@ -494,6 +495,12 @@ static void process_warning_switch(const char*name) } else if (strcmp(name,"infloop") == 0) { if (! strchr(warning_flags, 'l')) strcat(warning_flags, "l"); + } else if (strcmp(name,"sensitivity-entire-vector") == 0) { + if (! strchr(warning_flags, 'v')) + strcat(warning_flags, "v"); + } else if (strcmp(name,"sensitivity-entire-array") == 0) { + if (! strchr(warning_flags, 'a')) + strcat(warning_flags, "a"); } else if (strcmp(name,"no-implicit") == 0) { char*cp = strchr(warning_flags, 'i'); if (cp) while (*cp) { @@ -518,6 +525,18 @@ static void process_warning_switch(const char*name) cp[0] = cp[1]; cp += 1; } + } else if (strcmp(name,"no-sensitivity-entire-vector") == 0) { + char*cp = strchr(warning_flags, 'v'); + if (cp) while (*cp) { + cp[0] = cp[1]; + cp += 1; + } + } else if (strcmp(name,"no-sensitivity-entire-array") == 0) { + char*cp = strchr(warning_flags, 'a'); + if (cp) while (*cp) { + cp[0] = cp[1]; + cp += 1; + } } } diff --git a/main.cc b/main.cc index 9a389708f..e0acd91e1 100644 --- a/main.cc +++ b/main.cc @@ -116,6 +116,8 @@ bool warn_timescale = false; bool warn_portbinding = false; bool warn_inf_loop = false; bool warn_ob_select = false; +bool warn_sens_entire_vec = false; +bool warn_sens_entire_arr = false; bool error_implicit = false; @@ -501,6 +503,12 @@ static void read_iconfig_file(const char*ipath) case 't': warn_timescale = true; break; + case 'v': + warn_sens_entire_vec = true; + break; + case 'a': + warn_sens_entire_arr = true; + break; default: break; } diff --git a/net_nex_input.cc b/net_nex_input.cc index a1f81829c..2da521912 100644 --- a/net_nex_input.cc +++ b/net_nex_input.cc @@ -23,6 +23,7 @@ # include # include +# include "compiler.h" # include "netlist.h" # include "netmisc.h" @@ -115,7 +116,7 @@ NexusSet* NetESelect::nex_input(bool rem_out) result->add(*tmp); delete tmp; /* See the comment for NetESignal below. */ - if (base_) { + if (base_ && warn_sens_entire_vec) { cerr << get_fileline() << ": warning: @* is sensitive to all " "bits in '" << *expr_ << "'." << endl; } @@ -151,9 +152,11 @@ NexusSet* NetESignal::nex_input(bool rem_out) tmp = word_->nex_input(rem_out); result->add(*tmp); delete tmp; - cerr << get_fileline() << ": warning: @* is sensitive to all " - << net_->array_count() << " words in array '" - << name() << "'." << endl; + if (warn_sens_entire_arr) { + cerr << get_fileline() << ": warning: @* is sensitive to all " + << net_->array_count() << " words in array '" + << name() << "'." << endl; + } } for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1) result->add(net_->pin(idx).nexus()); From dff6a1ebff8bc33a80626f778659bf89d7823c6a Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 7 Sep 2009 10:55:44 -0700 Subject: [PATCH 02/10] Add file/line information to named events and better expr. error. This patch adds file and line number information to named events. It also modifies the draw_eval_expr_wid() routine to fail with an appropriate message for named events. This checking needs to be pushed into the elaboration stage, but this will give a better message than we had before. --- t-dll-expr.cc | 1 + tgt-vvp/eval_expr.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/t-dll-expr.cc b/t-dll-expr.cc index e4dcbf289..e67caca11 100644 --- a/t-dll-expr.cc +++ b/t-dll-expr.cc @@ -308,6 +308,7 @@ void dll_target::expr_event(const NetEEvent*net) assert(expr_); expr_->type_ = IVL_EX_EVENT; + FILE_NAME(expr_, net); expr_->value_= IVL_VT_VOID; /* Locate the event by name. Save the ivl_event_t in the diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index a41ba97f9..ebe9bb03f 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -2983,6 +2983,12 @@ struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned wid, res.base = 0; res.wid = 0; break; + case IVL_EX_EVENT: + fprintf(stderr, "%s:%u: vvp-tgt error: A named event is not " + "handled in this context (expression).\n", + ivl_expr_file(exp), ivl_expr_lineno(exp)); + exit(1); + break; case IVL_EX_STRING: res = draw_string_expr(exp, wid); From 1b0dd8c8e5e3f95ff6d9f5e26f6a4ecfb002c9b0 Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 7 Sep 2009 16:41:27 -0700 Subject: [PATCH 03/10] Add support for 'bx from a signal to &PV<> &PV<> was just using vpi_get_value() when a signal was driving the select. This incorrectly returned 0 for 'bx or 'bz. This patch adds a check for an undefined value and returns INT_MIN for this case. --- vvp/vpi_signal.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index dfe454d9c..d5a4203e1 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -989,6 +989,15 @@ static int PV_get_base(struct __vpiPV*rfp) /* We return from the symbol base if it is defined. */ if (rfp->sbase != 0) { s_vpi_value val; + /* Check to see if the value is defined. */ + val.format = vpiVectorVal; + vpi_get_value(rfp->sbase, &val); + int words = (vpi_get(vpiSize, rfp->sbase)-1)/32 + 1; + for(int idx = 0; idx < words; idx += 1) { + /* Return INT_MIN to indicate an X base. */ + if (val.value.vector[idx].bval != 0) return INT_MIN; + } + /* The value is defined so get and return it. */ val.format = vpiIntVal; vpi_get_value(rfp->sbase, &val); return val.value.integer; From 4b5047393974ef745792cb25739c1dc14b330175 Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 7 Sep 2009 18:11:52 -0700 Subject: [PATCH 04/10] Fix &A<> to support an undefined word index. This patch adds support to &A<> for an undefined word index. It mostly matches what was done for &PV<>. --- vvp/array.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/vvp/array.cc b/vvp/array.cc index ec99cd09b..577b8cec5 100644 --- a/vvp/array.cc +++ b/vvp/array.cc @@ -30,6 +30,7 @@ #endif # include # include +# include # include # include "compile.h" # include @@ -132,6 +133,15 @@ struct __vpiArrayVthrA { { if (address_handle) { s_vpi_value vp; + /* Check to see if the value is defined. */ + vp.format = vpiVectorVal; + vpi_get_value(address_handle, &vp); + int words = (vpi_get(vpiSize, address_handle)-1)/32 + 1; + for(int idx = 0; idx < words; idx += 1) { + /* Return UINT_MAX to indicate an X base. */ + if (vp.value.vector[idx].bval != 0) return UINT_MAX; + } + /* The value is defined so get and return it. */ vp.format = vpiIntVal; vpi_get_value(address_handle, &vp); return vp.value.integer; @@ -145,7 +155,7 @@ struct __vpiArrayVthrA { vvp_bit4_t bit = vthread_get_bit(vpip_current_vthread, address+idx); tmp.set_bit(idx, bit); } - unsigned long val; + unsigned long val = ULONG_MAX; vector4_to_value(tmp, val); return val; } From 27f032760ebe3019163b58d07ad9a3d8772bc710 Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 8 Sep 2009 17:50:47 -0700 Subject: [PATCH 05/10] Fix .part/v to only use a 32 bit value. To get better functionality in V0.9 and development until we add a select that is sign aware to .part/v this patch uses a 32 bit integer (int) for the select value. This allows a normal Verilog integer to produce the correct results. A warning for smaller signed index vectors is planned, but it needs more input. --- vvp/part.cc | 11 ++++++----- vvp/part.h | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/vvp/part.cc b/vvp/part.cc index a14551205..4e081d287 100644 --- a/vvp/part.cc +++ b/vvp/part.cc @@ -239,7 +239,7 @@ vvp_fun_part_var::~vvp_fun_part_var() } bool vvp_fun_part_var::recv_vec4_(vvp_net_ptr_t port, const vvp_vector4_t&bit, - long&base, vvp_vector4_t&source, + int&base, vvp_vector4_t&source, vvp_vector4_t&ref) { long tmp; @@ -251,9 +251,10 @@ bool vvp_fun_part_var::recv_vec4_(vvp_net_ptr_t port, const vvp_vector4_t&bit, // LONG_MIN is before the vector and is used to // represent a 'bx value on the select input. tmp = LONG_MIN; - // We need a new &PV<> that knows if the index is signed. + // We need a new .part/v that knows if the index is signed. + // For now this will work for a normal integer value. vector4_to_value(bit, tmp, false); - if (tmp == base) return false; + if ((int)tmp == base) return false; base = tmp; break; default: @@ -265,7 +266,7 @@ bool vvp_fun_part_var::recv_vec4_(vvp_net_ptr_t port, const vvp_vector4_t&bit, vvp_vector4_t res (wid_); for (unsigned idx = 0 ; idx < wid_ ; idx += 1) { - long adr = base+idx; + int adr = base+idx; if (adr < 0) continue; if ((unsigned)adr >= source.size()) break; @@ -314,7 +315,7 @@ void vvp_fun_part_var_sa::recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&b struct vvp_fun_part_var_state_s { vvp_fun_part_var_state_s() : base(0) { } - long base; + int base; vvp_vector4_t source; vvp_vector4_t ref; }; diff --git a/vvp/part.h b/vvp/part.h index f42dc6cd3..09f32093c 100644 --- a/vvp/part.h +++ b/vvp/part.h @@ -130,7 +130,7 @@ class vvp_fun_part_var : public vvp_net_fun_t { protected: bool recv_vec4_(vvp_net_ptr_t port, const vvp_vector4_t&bit, - long&base, vvp_vector4_t&source, + int&base, vvp_vector4_t&source, vvp_vector4_t&ref); unsigned wid_; @@ -154,7 +154,7 @@ class vvp_fun_part_var_sa : public vvp_fun_part_var { vvp_context_t); private: - long base_; + int base_; vvp_vector4_t source_; // Save the last output, for detecting change. vvp_vector4_t ref_; From 1b300cb2f6fc42d3ac8862e297b355883893dbc5 Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 10 Sep 2009 18:14:42 -0700 Subject: [PATCH 06/10] Fix another 64 bit problem in a part select. This patch fixes a problem in the .part/v select when the index is undefined. The default value needs to be INT_MIN, so when the long is cast to an int the value is in range. --- vvp/part.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vvp/part.cc b/vvp/part.cc index 4e081d287..9432eabec 100644 --- a/vvp/part.cc +++ b/vvp/part.cc @@ -248,13 +248,13 @@ bool vvp_fun_part_var::recv_vec4_(vvp_net_ptr_t port, const vvp_vector4_t&bit, source = bit; break; case 1: - // LONG_MIN is before the vector and is used to + // INT_MIN is before the vector and is used to // represent a 'bx value on the select input. - tmp = LONG_MIN; + tmp = INT_MIN; // We need a new .part/v that knows if the index is signed. // For now this will work for a normal integer value. vector4_to_value(bit, tmp, false); - if ((int)tmp == base) return false; + if (tmp == (long)base) return false; base = tmp; break; default: From 5a11a8a9c29825bc845e0488a87c4ca8cb7f139c Mon Sep 17 00:00:00 2001 From: Cary R Date: Fri, 11 Sep 2009 08:58:50 -0700 Subject: [PATCH 07/10] Revert one change from previous patch. I was mistaken in changing the cast in the comparison. --- vvp/part.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vvp/part.cc b/vvp/part.cc index 9432eabec..3f5e96caa 100644 --- a/vvp/part.cc +++ b/vvp/part.cc @@ -254,7 +254,7 @@ bool vvp_fun_part_var::recv_vec4_(vvp_net_ptr_t port, const vvp_vector4_t&bit, // We need a new .part/v that knows if the index is signed. // For now this will work for a normal integer value. vector4_to_value(bit, tmp, false); - if (tmp == (long)base) return false; + if ((int)tmp == base) return false; base = tmp; break; default: From 6d5d06cae4199c302aef33a337e70603ba1c561a Mon Sep 17 00:00:00 2001 From: Cary R Date: Wed, 9 Sep 2009 17:27:45 -0700 Subject: [PATCH 08/10] Squash some gcc 4.3.3 warnings. This patch clears all the gcc 4.3.3 warning that can be fixed. The remaining warning is dictated by older versions of the 1364 standard. --- libveriuser/getp.c | 2 ++ tgt-vvp/draw_vpi.c | 2 +- vpi/sys_fileio.c | 6 ++---- vvp/vvp_net.cc | 12 ++++++------ 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/libveriuser/getp.c b/libveriuser/getp.c index 5e074bdd8..9d832e4a4 100644 --- a/libveriuser/getp.c +++ b/libveriuser/getp.c @@ -53,6 +53,8 @@ PLI_INT32 tf_igetp(PLI_INT32 n, void *obj) { value.format = vpiStringVal; vpi_get_value(arg_h, &value); + /* The following may generate a compilation warning, but this + * functionality is required by some versions of the standard. */ rtn = (int) value.value.str; /* Oh my */ } else { value.format = vpiIntVal; diff --git a/tgt-vvp/draw_vpi.c b/tgt-vvp/draw_vpi.c index 0858e672c..2695f56db 100644 --- a/tgt-vvp/draw_vpi.c +++ b/tgt-vvp/draw_vpi.c @@ -217,7 +217,7 @@ static int get_vpi_taskfunc_signal_arg(struct args_info *result, (ivl_expr_width(bexpr) < 8*sizeof(int))) { fprintf(stderr, "%s:%u: tgt-vvp warning: V0.9 may give " "incorrect results for a select with a " - "signed index less than %d bits.\n", + "signed index less than %zu bits.\n", ivl_expr_file(expr), ivl_expr_lineno(expr), 8*sizeof(int)); diff --git a/vpi/sys_fileio.c b/vpi/sys_fileio.c index 2fccdd49e..9961d95b6 100644 --- a/vpi/sys_fileio.c +++ b/vpi/sys_fileio.c @@ -214,7 +214,6 @@ static PLI_INT32 sys_fclose_calltf(PLI_BYTE8*name) vpiHandle fd = vpi_scan(argv); s_vpi_value val; PLI_UINT32 fd_mcd; - char *str = ""; /* This prevents the compiler from complaining. */ errno = 0; vpi_free_object(argv); @@ -225,7 +224,7 @@ static PLI_INT32 sys_fclose_calltf(PLI_BYTE8*name) fd_mcd = val.value.integer; if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) || - ( IS_MCD(fd_mcd) && vpi_mcd_printf(fd_mcd, str) == EOF) || + ( IS_MCD(fd_mcd) && vpi_mcd_printf(fd_mcd, "%s", "") == EOF) || (! fd_mcd)) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); @@ -254,7 +253,6 @@ static PLI_INT32 sys_fflush_calltf(PLI_BYTE8*name) s_vpi_value val; PLI_UINT32 fd_mcd; FILE *fp; - char *str = ""; /* This prevents the compiler from complaining. */ errno = 0; /* If we have no argument then flush all the streams. */ @@ -274,7 +272,7 @@ static PLI_INT32 sys_fflush_calltf(PLI_BYTE8*name) if (fd_mcd == 0) return 0; if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) || - ( IS_MCD(fd_mcd) && vpi_mcd_printf(fd_mcd, str) == EOF) || + ( IS_MCD(fd_mcd) && vpi_mcd_printf(fd_mcd, "%s", "") == EOF) || (! fd_mcd)) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index 825b8ed1f..cdf3cfe67 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -1143,8 +1143,8 @@ vvp_vector4_t& vvp_vector4_t::operator |= (const vvp_vector4_t&that) if (size_ <= BITS_PER_WORD) { unsigned long tmp = abits_val_ | bbits_val_ | that.abits_val_ | that.bbits_val_; - bbits_val_ = (~abits_val_ | bbits_val_) & that.bbits_val_ | - (~that.abits_val_ | that.bbits_val_) & bbits_val_; + bbits_val_ = ((~abits_val_ | bbits_val_) & that.bbits_val_) | + ((~that.abits_val_ | that.bbits_val_) & bbits_val_); abits_val_ = tmp; } else { @@ -1152,10 +1152,10 @@ vvp_vector4_t& vvp_vector4_t::operator |= (const vvp_vector4_t&that) for (unsigned idx = 0; idx < words ; idx += 1) { unsigned long tmp = abits_ptr_[idx] | bbits_ptr_[idx] | that.abits_ptr_[idx] | that.bbits_ptr_[idx]; - bbits_ptr_[idx] = (~abits_ptr_[idx] | bbits_ptr_[idx]) & - that.bbits_ptr_[idx] | - (~that.abits_ptr_[idx] | - that.bbits_ptr_[idx]) & bbits_ptr_[idx]; + bbits_ptr_[idx] = ((~abits_ptr_[idx] | bbits_ptr_[idx]) & + that.bbits_ptr_[idx]) | + ((~that.abits_ptr_[idx] | + that.bbits_ptr_[idx]) & bbits_ptr_[idx]); abits_ptr_[idx] = tmp; } } From 43f41572cba479b39c9ada187dc168ca24abf3bc Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 10 Sep 2009 15:32:09 -0700 Subject: [PATCH 09/10] Fix 64 bit problem in vvp/vpi_signal.c This is based on a suggested fix from Martin. It fixes the crash for two tests in the test suite. As a bonus it is more efficient. --- vvp/vpi_signal.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index d5a4203e1..5e33f2846 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -138,8 +138,8 @@ static void format_vpiBinStrVal(vvp_fun_signal_vec*sig, int base, unsigned wid, s_vpi_value*vp) { char *rbuf = need_result_buf(wid+1, RBUF_VAL); - long offset = wid - 1 + base; long end = base + (signed)wid; + long offset = end - 1; long ssize = (signed)sig->size(); for (long idx = base ; idx < end ; idx += 1) { From 4d57ede0e539a6680b456b2be8018892226661a8 Mon Sep 17 00:00:00 2001 From: Cary R Date: Fri, 11 Sep 2009 19:59:11 -0700 Subject: [PATCH 10/10] Warn that events can not be user task or function arguments. This patch makes events passed as arguments to user tasks or functions a compile time error with an appropriate error message. --- elab_expr.cc | 6 ++++++ elaborate.cc | 7 +++++++ expr_synth.cc | 4 ++++ 3 files changed, 17 insertions(+) diff --git a/elab_expr.cc b/elab_expr.cc index 261539812..89698a49a 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -1488,6 +1488,12 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, def->port(idx)->data_type(), def->port(idx)->vector_width(), tmp); + if (NetEEvent*evt = dynamic_cast (parms[idx])) { + cerr << evt->get_fileline() << ": error: An event '" + << evt->event()->name() << "' can not be a user " + "function argument." << endl; + des->errors += 1; + } if (debug_elaborate) cerr << get_fileline() << ": debug:" << " function " << path_ diff --git a/elaborate.cc b/elaborate.cc index 1ef37368a..ba18d812e 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -2644,6 +2644,13 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const ivl_variable_type_t lv_type = lv->expr_type(); NetExpr*rv = elaborate_rval_expr(des, scope, lv_type, wid, parms_[idx]); + if (NetEEvent*evt = dynamic_cast (rv)) { + cerr << evt->get_fileline() << ": error: An event '" + << evt->event()->name() << "' can not be a user " + "task argument." << endl; + des->errors += 1; + continue; + } if (wid > rv->expr_width()) { rv->set_width(wid); rv = pad_to_width(rv, wid, *this); diff --git a/expr_synth.cc b/expr_synth.cc index 6e4a7f842..444c00bb3 100644 --- a/expr_synth.cc +++ b/expr_synth.cc @@ -1369,6 +1369,10 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root) /* Synthesize the arguments. */ bool errors = false; for (unsigned idx = 0; idx < eparms.count(); idx += 1) { + if (dynamic_cast (parms_[idx])) { + errors = true; + continue; + } NetNet*tmp = parms_[idx]->synthesize(des, scope, root); if (tmp == 0) { cerr << get_fileline() << ": error: Unable to synthesize "