From 7d438b66c8c8e1f45823831fb4ba1acb8e486fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20I=2E=20B=C3=B6ttcher?= Date: Wed, 18 Mar 2026 17:59:33 +0100 Subject: [PATCH] add option -gno-strict-declaration The new option allows parameter, net and events to be used before declaration. With variants -gno-strict-net-declaration for nets and events, -gno-strict-parameter-declaration for parameters. --- Documentation/usage/command_line_flags.rst | 14 ++++++++++---- compiler.h | 11 +++++++++-- driver/iverilog.man.in | 11 ++++++++--- driver/main.c | 19 ++++++++++++++++++- main.cc | 7 +++++++ symbol_search.cc | 16 ++++++++++++++-- 6 files changed, 66 insertions(+), 12 deletions(-) diff --git a/Documentation/usage/command_line_flags.rst b/Documentation/usage/command_line_flags.rst index 68c217a6d..73a2df9e1 100644 --- a/Documentation/usage/command_line_flags.rst +++ b/Documentation/usage/command_line_flags.rst @@ -131,12 +131,18 @@ These flags affect the general behavior of the compiler. containing an unsized constant number, and unsized constant numbers are not truncated to integer width. + * strict-declaration/no-strict-declaration + + * strict-net-declaration/no-net-strict-declaration + * strict-parameter-declaration/no-strict-parameter-declaration - The standards requires that parameters must be declared lexically - before they are used. Using -gno-strict-parameter-declaration - will allow using a parameter before declaration, with a - warning. The warning can be suppressed with -Wno-declaration-after-use. + The standards requires that nets and parameters must be declared + lexically before they are used. Using -gno-strict-declaration + will allow using a net or parameter before declaration, with a + warning. The warning can be suppressed with + -Wno-declaration-after-use. The option can be applied for nets + and parameters separately. * shared-loop-index/no-shared-loop-index diff --git a/compiler.h b/compiler.h index 0b5feca91..d72eb44c3 100644 --- a/compiler.h +++ b/compiler.h @@ -214,12 +214,19 @@ extern bool gn_strict_expr_width_flag; extern bool gn_shared_loop_index_flag; /* If this flag is true (default), then parameters must be declared before - use. `-gno-strict-parameter-declaration` allows to use parameters before + use. `-gno-strict[-parameter]-declaration` allows to use parameters before declaration, as prior to version 13. - A warning is emited with -Wanachronisms (default). + A warning is emited with -Wdeclaration-after-use (default). */ extern bool gn_strict_parameter_declaration; +/* If this flag is true (default), then nets must be declared before + use. `-gno-strict[-net]-declaration` allows to use nets before + declaration, as prior to version 13. + A warning is emited with -Wdeclaration-after-use (default). + */ +extern bool gn_strict_net_declaration; + static inline bool gn_system_verilog(void) { if (generation_flag >= GN_VER2005_SV) diff --git a/driver/iverilog.man.in b/driver/iverilog.man.in index 19ac06361..040bca7b3 100644 --- a/driver/iverilog.man.in +++ b/driver/iverilog.man.in @@ -150,11 +150,16 @@ parameter assignment is evaluated as a lossless expression, as is any expression containing an unsized constant number, and unsized constant numbers are not truncated to integer width. .TP 8 +.B -gstrict-declaration\fI|\fP-gno-strict-declaration +.TP 8 +.B -gstrict-net-declaration\fI|\fP-gno-strict-net-declaration +.TP 8 .B -gstrict-parameter-declaration\fI|\fP-gno-strict-parameter-declaration -The standards requires that parameters must be declared lexically -before they are used. Using \fB\-gno\-strict\-parameter\-declaration\fP +The standards requires that nets and parameters must be declared lexically +before they are used. Using \fB\-gno\-strict\-declaration\fP will allow using a parameter before declaration, with a warning. -The warning can be suppressed with -Wno-declaration-after-use. +The warning can be suppressed with -Wno-declaration-after-use. The +option can be applied for nets and parameters separately. .TP 8 .B -gshared-loop-index\fI|\fP-gno-shared-loop-index Enable (default) or disable the exclusion of for-loop control variables diff --git a/driver/main.c b/driver/main.c index 803e457c6..0e16bf672 100644 --- a/driver/main.c +++ b/driver/main.c @@ -134,6 +134,7 @@ const char*gen_strict_ca_eval = "no-strict-ca-eval"; const char*gen_strict_expr_width = "no-strict-expr-width"; const char*gen_shared_loop_index = "shared-loop-index"; const char*gen_verilog_ams = "no-verilog-ams"; +const char*gen_strict_net_declaration = "strict-net-declaration"; const char*gen_strict_parameter_declaration = "strict-parameter-declaration"; /* Boolean: true means use a default include dir, false means don't */ @@ -826,6 +827,20 @@ static int process_generation(const char*name) else if (strcmp(name,"no-verilog-ams") == 0) gen_verilog_ams = "no-verilog-ams"; + else if (strcmp(name,"strict-declaration") == 0) { + gen_strict_net_declaration = "strict-net-declaration"; + gen_strict_parameter_declaration = "strict-parameter-declaration"; + } + else if (strcmp(name,"no-strict-declaration") == 0) { + gen_strict_net_declaration = "no-strict-net-declaration"; + gen_strict_parameter_declaration = "no-strict-parameter-declaration"; + } + else if (strcmp(name,"strict-net-declaration") == 0) + gen_strict_net_declaration = "strict-net-declaration"; + + else if (strcmp(name,"no-strict-net-declaration") == 0) + gen_strict_net_declaration = "no-strict-net-declaration"; + else if (strcmp(name,"strict-parameter-declaration") == 0) gen_strict_parameter_declaration = "strict-parameter-declaration"; @@ -855,7 +870,8 @@ static int process_generation(const char*name) " strict-ca-eval | no-strict-ca-eval\n" " strict-expr-width | no-strict-expr-width\n" " shared-loop-index | no-shared-loop-index\n" - " strict-parameter-declaration | no-strict-parameter-declaration\n"); + " strict-declaration | no-strict-declaration\n" + " [no-]strict-[net|parameter]-declaration\n"); return 1; } @@ -1403,6 +1419,7 @@ int main(int argc, char **argv) fprintf(iconfig_file, "generation:%s\n", gen_strict_expr_width); fprintf(iconfig_file, "generation:%s\n", gen_shared_loop_index); fprintf(iconfig_file, "generation:%s\n", gen_verilog_ams); + fprintf(iconfig_file, "generation:%s\n", gen_strict_net_declaration); fprintf(iconfig_file, "generation:%s\n", gen_strict_parameter_declaration); fprintf(iconfig_file, "generation:%s\n", gen_icarus); fprintf(iconfig_file, "warnings:%s\n", warning_flags); diff --git a/main.cc b/main.cc index 8e71ef7b3..82f7bec33 100644 --- a/main.cc +++ b/main.cc @@ -118,6 +118,7 @@ bool gn_strict_expr_width_flag = false; bool gn_shared_loop_index_flag = true; bool gn_verilog_ams_flag = false; bool gn_strict_parameter_declaration = true; +bool gn_strict_net_declaration = true; /* * For some generations we allow a system function to be called @@ -394,6 +395,12 @@ static void process_generation_flag(const char*gen) } else if (strcmp(gen,"no-strict-parameter-declaration") == 0) { gn_strict_parameter_declaration = false; + } else if (strcmp(gen,"strict-net-declaration") == 0) { + gn_strict_net_declaration = true; + + } else if (strcmp(gen,"no-strict-net-declaration") == 0) { + gn_strict_net_declaration = false; + } else { } } diff --git a/symbol_search.cc b/symbol_search.cc index 11922e684..8e5d8b40a 100644 --- a/symbol_search.cc +++ b/symbol_search.cc @@ -164,12 +164,18 @@ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope, } if (NetNet*net = scope->find_signal(path_tail.name)) { - if (prefix_scope || (net->lexical_pos() <= lexical_pos)) { + bool decl_after_use = !prefix_scope && !(net->lexical_pos() <= lexical_pos); + if (!gn_strict_net_declaration || !decl_after_use) { path.push_back(path_tail); res->scope = scope; res->net = net; res->type = net->net_type(); res->path_head = path; + if (warn_decl_after_use && decl_after_use) { + cerr << li->get_fileline() + << ": warning: net `" << path_tail.name + << "` used before declaration." << endl; + } return true; } else if (!res->decl_after_use) { res->decl_after_use = net; @@ -177,11 +183,17 @@ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope, } if (NetEvent*eve = scope->find_event(path_tail.name)) { - if (prefix_scope || (eve->lexical_pos() <= lexical_pos)) { + bool decl_after_use = !prefix_scope && !(eve->lexical_pos() <= lexical_pos); + if (!gn_strict_net_declaration || !decl_after_use) { path.push_back(path_tail); res->scope = scope; res->eve = eve; res->path_head = path; + if (warn_decl_after_use && decl_after_use) { + cerr << li->get_fileline() + << ": warning: event `" << path_tail.name + << "` used before declaration." << endl; + } return true; } else if (!res->decl_after_use) { res->decl_after_use = eve;