From 46350da5f0f3c623cb9fe05003d7e2b8506d14a7 Mon Sep 17 00:00:00 2001 From: Cary R Date: Fri, 3 Apr 2009 18:55:48 -0700 Subject: [PATCH 1/6] Add support for empty task port lists with a warning. The standard does not allow this, but it appears that other simulators do. This patch adds the functionality, but prints a warning message for the invalid task definition. --- parse.y | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/parse.y b/parse.y index 1f9ac0d11..ec9c9169c 100644 --- a/parse.y +++ b/parse.y @@ -2137,12 +2137,12 @@ module_item delete[]$3; } - | K_task automatic_opt IDENTIFIER + | K_task automatic_opt IDENTIFIER '(' { assert(current_task == 0); current_task = pform_push_task_scope($3, $2); FILE_NAME(current_task, @1); } - '(' task_port_decl_list ')' ';' + task_port_decl_list ')' ';' block_item_decls_opt statement_or_null K_endtask @@ -2152,6 +2152,24 @@ module_item current_task = 0; delete[]$3; } + + | K_task automatic_opt IDENTIFIER '(' ')' ';' + { assert(current_task == 0); + current_task = pform_push_task_scope($3, $2); + FILE_NAME(current_task, @1); + } + block_item_decls_opt + statement_or_null + K_endtask + { current_task->set_ports(0); + current_task->set_statement($9); + pform_pop_scope(); + current_task = 0; + cerr << @3 << ": warning: task definition for \"" << $3 + << "\" has an empty port declaration list!" << endl; + delete[]$3; + } + | K_task automatic_opt IDENTIFIER error K_endtask { pform_pop_scope(); From d074a37a2d691edd2008c81608a493cd8376aece Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 6 Apr 2009 17:11:14 -0700 Subject: [PATCH 2/6] For div/mod only sign extend if both arguments are signed. Only sign extend the operands for division or modulus if both of them are signed. Previously only the individual operand signedness was being considered. --- elab_expr.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index a018593d4..b54fbdb09 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -419,10 +419,8 @@ NetExpr* PEBinary::elaborate_expr_base_bits_(Design*des, // If either of the arguments is unsigned, then process both // of them as unsigned. This only impacts the padding that is // done to get the operands to the expr_wid. - if (! lp->has_sign()) - rp->cast_signed(false); - if (! rp->has_sign()) - lp->cast_signed(false); + if (! lp->has_sign()) rp->cast_signed(false); + if (! rp->has_sign()) lp->cast_signed(false); if (expr_wid > 0) { if (type_is_vectorable(lp->expr_type())) @@ -453,6 +451,12 @@ NetExpr* PEBinary::elaborate_expr_base_div_(Design*des, } } + // If either of the arguments is unsigned, then process both + // of them as unsigned. This only impacts the padding that is + // done to get the operands to the expr_wid. + if (! lp->has_sign()) rp->cast_signed(false); + if (! rp->has_sign()) lp->cast_signed(false); + /* The original elaboration of the left and right expressions already tried to elaborate to the expr_wid. If the expressions are not that width by now, then they need to be From 4b2e5e591466d68f4d8f5cdcad1efbe2882f284e Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 7 Apr 2009 10:22:26 -0700 Subject: [PATCH 3/6] Check for both the library and include file when adding history. When adding history (add_history) use both the existence of the library and the header file to determine if history can be supported. Add a new USE_HISTORY that is the and of these two. --- vvp/config.h.in | 9 +++++++++ vvp/stop.cc | 8 ++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/vvp/config.h.in b/vvp/config.h.in index a9d5605f1..71691a402 100644 --- a/vvp/config.h.in +++ b/vvp/config.h.in @@ -44,6 +44,7 @@ # undef HAVE_MALLOC_H # undef HAVE_LIBREADLINE # undef HAVE_READLINE_READLINE_H +# undef HAVE_LIBHISTORY # undef HAVE_READLINE_HISTORY_H # undef HAVE_INTTYPES_H # undef HAVE_LROUND @@ -63,6 +64,14 @@ #endif #endif +/* Figure if I can use history. */ +#undef USE_HISTORY +#ifdef HAVE_LIBHISTORY +#ifdef HAVE_READLINE_HISTORY_H +# define USE_HISTORY +#endif +#endif + #ifndef MODULE_DIR # define MODULE_DIR "." #endif diff --git a/vvp/stop.cc b/vvp/stop.cc index 07b6e2af8..b20230fd8 100644 --- a/vvp/stop.cc +++ b/vvp/stop.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2007 Stephen Williams (steve@icarus.com) + * Copyright (c) 2003-2009 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 @@ -30,10 +30,10 @@ # include "schedule.h" # include # include -#ifdef HAVE_READLINE_READLINE_H +#ifdef USE_READLINE # include #endif -#ifdef HAVE_READLINE_HISTORY_H +#ifdef USE_HISTORY # include #endif # include @@ -499,7 +499,7 @@ void stop_handler(int rc) first += 1; if (first[0] != 0) { -#ifdef HAVE_READLINE_HISTORY_H +#ifdef USE_HISTORY add_history(first); #endif invoke_command(first); From a7741d2bd5cb53bf5ddafd34317ba858070ecfb7 Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 7 Apr 2009 14:25:36 -0700 Subject: [PATCH 4/6] Use the port that has already been fetched. This patch reuses the port that has already been fetched vs fetching it again. --- vvp/logic.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vvp/logic.cc b/vvp/logic.cc index 827ccbd64..471c9103d 100644 --- a/vvp/logic.cc +++ b/vvp/logic.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2008 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2009 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 @@ -49,7 +49,7 @@ void vvp_fun_boolean_::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit, if (input_[port] .eeq( bit )) return; - input_[ptr.port()] = bit; + input_[port] = bit; if (net_ == 0) { net_ = ptr.ptr(); schedule_generic(this, 0, false); From 5e723bfd614b37ef1d3fcf64714a50fb340d6ebc Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 7 Apr 2009 18:31:42 -0700 Subject: [PATCH 5/6] Add support for recursive modules inside generate blocks This patch adds support for recursive module loops if the loop contains a generate block. The assumption is that the user is doing the right thing in the generate block to make the loop terminate. For this case there is also a check that limits the number of loops (default 10). This prevents the system from crashing when the user did not correctly terminate the looping structure. The limit can be changed by the user if needed. --- compiler.h | 8 +++++++- elab_scope.cc | 37 ++++++++++++++++++++++++++++++------- main.cc | 5 +++++ 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/compiler.h b/compiler.h index c70c50d2b..e604e4da2 100644 --- a/compiler.h +++ b/compiler.h @@ -1,7 +1,7 @@ #ifndef __compiler_H #define __compiler_H /* - * Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2009 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 @@ -36,6 +36,12 @@ */ extern unsigned integer_width; +/* + * This is the maximum number of recursive module loops allowed within + * a generate block. + */ +extern unsigned recursive_mod_limit; + /* The TIME_WIDTH is the width of time variables. */ #ifndef TIME_WIDTH # define TIME_WIDTH 64 diff --git a/elab_scope.cc b/elab_scope.cc index 5ee6861de..03bb3664a 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -919,21 +919,44 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const // check for recursive instantiation by scanning the current // scope and its parents. Look for a module instantiation of // the same module, but farther up in the scope. - + unsigned rl_count = 0; + bool in_genblk = false; for (NetScope*scn = sc ; scn ; scn = scn->parent()) { - if (scn->type() != NetScope::MODULE) + // We need to know if we are inside a generate block to allow + // recursive instances. + if (scn->type() == NetScope::GENBLOCK) { + in_genblk = true; continue; + } - if (strcmp(mod->mod_name(), scn->module_name()) != 0) + if (scn->type() != NetScope::MODULE) continue; + + if (strcmp(mod->mod_name(), scn->module_name()) != 0) continue; + + // We allow nested scopes if they are inside a generate block, + // but only to a certain nesting depth. + if (in_genblk) { + rl_count += 1; + if (rl_count > recursive_mod_limit) { + cerr << get_fileline() << ": error: instance " + << scope_path(sc) << "." << get_name() + << " of module " << mod->mod_name() + << " is nested too deep." << endl; + cerr << get_fileline() << ": : check for " + "proper recursion termination or increase the " + "limit (" << recursive_mod_limit + << ") with the -pRECURSIVE_MOD_LIMIT flag." + << endl; + des->errors += 1; + return; + } continue; + } cerr << get_fileline() << ": error: You cannot instantiate " << "module " << mod->mod_name() << " within itself." << endl; - cerr << get_fileline() << ": : The offending instance is " - << scope_path(sc) << "." << get_name() << " within " - << scope_path(scn) << "." << endl; - + << get_name() << " within " << scope_path(scn) << "." << endl; des->errors += 1; return; } diff --git a/main.cc b/main.cc index f4b18ab01..c692a154a 100644 --- a/main.cc +++ b/main.cc @@ -133,6 +133,7 @@ bool debug_optimizer = false; */ bool disable_virtual_pins = false; unsigned long array_size_limit = 16777216; // Minimum required by IEEE-1364? +unsigned recursive_mod_limit = 10; /* * Verbose messages enabled. @@ -717,9 +718,13 @@ int main(int argc, char*argv[]) const char *flag_tmp = flags["DISABLE_VIRTUAL_PINS"]; if (flag_tmp) disable_virtual_pins = strcmp(flag_tmp,"true")==0; + flag_tmp = flags["ARRAY_SIZE_LIMIT"]; if (flag_tmp) array_size_limit = strtoul(flag_tmp,NULL,0); + flag_tmp = flags["RECURSIVE_MOD_LIMIT"]; + if (flag_tmp) recursive_mod_limit = strtoul(flag_tmp,NULL,0); + /* Parse the input. Make the pform. */ int rc = pform_parse(argv[optind]); From 047828ded0e6a3713062ea74cbf97741ec505bc3 Mon Sep 17 00:00:00 2001 From: Cary R Date: Wed, 8 Apr 2009 15:09:19 -0700 Subject: [PATCH 6/6] Allow macro expansions to take arguments with multiple arguments. This patch allows a macro expansion to have an argument which itself has multiple arguments (handle nested ","). --- ivlpp/lexor.lex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ivlpp/lexor.lex b/ivlpp/lexor.lex index dbe9371b5..a6e652c5e 100644 --- a/ivlpp/lexor.lex +++ b/ivlpp/lexor.lex @@ -599,7 +599,8 @@ keywords (include|define|undef|ifdef|ifndef|else|elseif|endif) "(" { macro_add_to_arg(0); ma_parenthesis_level++; } -"," { macro_finish_arg(); } +"," { if (ma_parenthesis_level > 0) macro_add_to_arg(0); + else macro_finish_arg(); } ")" { if (ma_parenthesis_level > 0) {