diff --git a/compiler.h b/compiler.h index 4f8bc67d6..3ce69d184 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 e40ddbf76..c464d0141 100644 --- a/driver/iverilog.man +++ b/driver/iverilog.man @@ -254,8 +254,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 @@ -298,6 +298,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 a8968f64d..d7b577696 100644 --- a/driver/main.c +++ b/driver/main.c @@ -471,6 +471,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"); @@ -488,6 +489,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) { @@ -512,6 +519,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 c792d1dcb..1ffe353dd 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());