From b4d5248c67ec83cbcf9b936b9f49711dc94f7c75 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Sat, 5 Mar 2016 17:43:25 +0000 Subject: [PATCH] Fix for br1000 - avoid infinite loop when processes share a for-loop index. --- compiler.h | 7 ++++++- driver/iverilog.man.in | 15 +++++++++++++-- driver/main.c | 13 +++++++++++-- main.cc | 7 +++++++ net_nex_input.cc | 11 ++++++++++- 5 files changed, 47 insertions(+), 6 deletions(-) diff --git a/compiler.h b/compiler.h index a7f5caefb..5ba9f8e8a 100644 --- a/compiler.h +++ b/compiler.h @@ -1,7 +1,7 @@ #ifndef IVL_compiler_H #define IVL_compiler_H /* - * Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2016 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -189,6 +189,11 @@ extern bool gn_strict_ca_eval_flag; standard expression width rules. */ extern bool gn_strict_expr_width_flag; +/* If this flag is true, then don't add a for-loop control variable + to an implicit event_expression list if it is only used inside the + loop. */ +extern bool gn_shared_loop_index_flag; + /* If variables can be converted to uwires by a continuous assignment (assuming no procedural assign, then return true. This will be true for SystemVerilog */ diff --git a/driver/iverilog.man.in b/driver/iverilog.man.in index edc967d11..dfc504bf2 100644 --- a/driver/iverilog.man.in +++ b/driver/iverilog.man.in @@ -1,4 +1,4 @@ -.TH iverilog 1 "Aug 7th, 2015" "" "Version %M.%n%E" +.TH iverilog 1 "Mar 5th, 2016" "" "Version %M.%n%E" .SH NAME iverilog - Icarus Verilog compiler @@ -133,6 +133,17 @@ 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 -gshared-loop-index\fI|\fP-gno-shared-loop-index +Enable (default) or disable the exclusion of for-loop control variables +from implicit event_expression lists. When enabled, if a for-loop control +variable (loop index) is only used inside the for-loop statement, the +compiler will not include it in an implicit event_expression list it +calculates for that statement or any enclosing statement. This allows +the same control variable to be used in multiple processes without risk +of entering an infinite loop caused by each process triggering all other +processes that use the same varaible. For strict compliance with the +standards, this behaviour should be disabled. +.TP 8 .B -I\fIincludedir\fP Append directory \fIincludedir\fP to list of directories searched for Verilog include files. The \fB\-I\fP switch may be used many times @@ -537,7 +548,7 @@ Tips on using, debugging, and developing the compiler can be found at .SH COPYRIGHT .nf -Copyright \(co 2002\-2015 Stephen Williams +Copyright \(co 2002\-2016 Stephen Williams This document can be freely redistributed according to the terms of the GNU General Public License version 2.0 diff --git a/driver/main.c b/driver/main.c index 1103f5f55..a0ab68993 100644 --- a/driver/main.c +++ b/driver/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2015 Stephen Williams (steve@icarus.com) + * Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -128,6 +128,7 @@ const char*gen_icarus = "icarus-misc"; const char*gen_io_range_error = "io-range-error"; 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"; /* Boolean: true means use a default include dir, false means don't */ @@ -739,6 +740,12 @@ static int process_generation(const char*name) else if (strcmp(name,"no-strict-expr-width") == 0) gen_strict_expr_width = "no-strict-expr-width"; + else if (strcmp(name,"shared-loop-index") == 0) + gen_shared_loop_index = "shared-loop-index"; + + else if (strcmp(name,"no-shared-loop-index") == 0) + gen_shared_loop_index = "no-shared-loop-index"; + else if (strcmp(name,"verilog-ams") == 0) gen_verilog_ams = "verilog-ams"; @@ -764,7 +771,8 @@ static int process_generation(const char*name) " icarus-misc | no-icarus-misc\n" " io-range-error | no-io-range-error\n" " strict-ca-eval | no-strict-ca-eval\n" - " strict-expr-width | no-strict-expr-width\n"); + " strict-expr-width | no-strict-expr-width\n" + " shared-loop-index | no-shared-loop-index\n"); return 1; } @@ -1118,6 +1126,7 @@ int main(int argc, char **argv) fprintf(iconfig_file, "generation:%s\n", gen_io_range_error); fprintf(iconfig_file, "generation:%s\n", gen_strict_ca_eval); 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_icarus); fprintf(iconfig_file, "warnings:%s\n", warning_flags); diff --git a/main.cc b/main.cc index bd357aaf7..c9db661b0 100644 --- a/main.cc +++ b/main.cc @@ -108,6 +108,7 @@ bool gn_assertions_flag = true; bool gn_io_range_error_flag = true; bool gn_strict_ca_eval_flag = false; bool gn_strict_expr_width_flag = false; +bool gn_shared_loop_index_flag = true; bool gn_verilog_ams_flag = false; /* @@ -347,6 +348,12 @@ static void process_generation_flag(const char*gen) } else if (strcmp(gen,"no-strict-expr-width") == 0) { gn_strict_expr_width_flag = false; + } else if (strcmp(gen,"shared-loop-index") == 0) { + gn_shared_loop_index_flag = true; + + } else if (strcmp(gen,"no-shared-loop-index") == 0) { + gn_shared_loop_index_flag = false; + } else { } } diff --git a/net_nex_input.cc b/net_nex_input.cc index aff41f281..4cb91fc24 100644 --- a/net_nex_input.cc +++ b/net_nex_input.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2013 Stephen Williams (steve@icarus.com) + * Copyright (c) 2002-2016 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -427,6 +427,15 @@ NexusSet* NetForLoop::nex_input(bool rem_out) result->add(*tmp); delete tmp; + if (gn_shared_loop_index_flag) { + tmp = new NexusSet(); + for (unsigned idx = 0 ; idx < index_->pin_count() ; idx += 1) + tmp->add(index_->pin(idx).nexus(), 0, index_->vector_width()); + + result->rem(*tmp); + delete tmp; + } + return result; }