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_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 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/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) { 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]); 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(); 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/logic.cc b/vvp/logic.cc index 62c95fe5e..2ed65d138 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); 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);