From d3caa547babcd923fbdb72366f0b974c0c0cc62c Mon Sep 17 00:00:00 2001 From: Cary R Date: Wed, 13 Aug 2008 13:58:49 -0700 Subject: [PATCH 1/3] Print an error for automatic tasks or functions. This patch adds code to recognize and report that automatic task or functions are not currently supported. --- lexor_keyword.gperf | 1 + parse.y | 63 ++++++++++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/lexor_keyword.gperf b/lexor_keyword.gperf index 980b33c89..9cb72b281 100644 --- a/lexor_keyword.gperf +++ b/lexor_keyword.gperf @@ -25,6 +25,7 @@ assign, GN_KEYWORDS_1364_1995, K_assign atan, GN_KEYWORDS_VAMS_2_3, K_atan atan2, GN_KEYWORDS_VAMS_2_3, K_atan2 atanh, GN_KEYWORDS_VAMS_2_3, K_atanh +automatic, GN_KEYWORDS_1364_2001, K_automatic begin, GN_KEYWORDS_1364_1995, K_begin bool, GN_KEYWORDS_ICARUS, K_bool buf, GN_KEYWORDS_1364_1995, K_buf diff --git a/parse.y b/parse.y index 7382eae6b..8f180090d 100644 --- a/parse.y +++ b/parse.y @@ -205,7 +205,7 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2) %token K_PSTAR K_STARP %token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER %token K_abs K_abstol K_access K_acos K_acosh K_asin K_analog K_asinh -%token K_atan K_atanh K_atan2 +%token K_atan K_atanh K_atan2 K_automatic %token K_always K_and K_assign K_begin K_bool K_buf K_bufif0 K_bufif1 K_case %token K_casex K_casez K_ceil K_cmos K_continuous K_cos K_cosh %token K_ddt_nature K_deassign K_default K_defparam K_disable K_discrete @@ -2094,41 +2094,41 @@ module_item statements in the task body. But we continue to accept it as an extension. */ - | K_task IDENTIFIER ';' + | K_task automatic_opt IDENTIFIER ';' { assert(current_task == 0); - current_task = pform_push_task_scope($2); + current_task = pform_push_task_scope($3); FILE_NAME(current_task, @1); } task_item_list_opt statement_or_null K_endtask - { current_task->set_ports($5); - current_task->set_statement($6); + { current_task->set_ports($6); + current_task->set_statement($7); pform_pop_scope(); current_task = 0; - delete[]$2; + delete[]$3; } - | K_task IDENTIFIER + | K_task automatic_opt IDENTIFIER { assert(current_task == 0); - current_task = pform_push_task_scope($2); + current_task = pform_push_task_scope($3); FILE_NAME(current_task, @1); } '(' task_port_decl_list ')' ';' block_item_decls_opt statement_or_null K_endtask - { current_task->set_ports($5); - current_task->set_statement($9); + { current_task->set_ports($6); + current_task->set_statement($10); pform_pop_scope(); current_task = 0; - delete[]$2; + delete[]$3; } - | K_task IDENTIFIER error K_endtask + | K_task automatic_opt IDENTIFIER error K_endtask { pform_pop_scope(); current_task = 0; - delete[]$2; + delete[]$3; } /* The function declaration rule matches the function declaration @@ -2136,42 +2136,42 @@ module_item definitions in the func_body to take on the scope of the function instead of the module. */ - | K_function function_range_or_type_opt IDENTIFIER ';' + | K_function automatic_opt function_range_or_type_opt IDENTIFIER ';' { assert(current_function == 0); - current_function = pform_push_function_scope($3); + current_function = pform_push_function_scope($4); FILE_NAME(current_function, @1); } function_item_list statement K_endfunction - { current_function->set_ports($6); - current_function->set_statement($7); - current_function->set_return($2); + { current_function->set_ports($7); + current_function->set_statement($8); + current_function->set_return($3); pform_pop_scope(); current_function = 0; - delete[]$3; + delete[]$4; } - | K_function function_range_or_type_opt IDENTIFIER + | K_function automatic_opt function_range_or_type_opt IDENTIFIER { assert(current_function == 0); - current_function = pform_push_function_scope($3); + current_function = pform_push_function_scope($4); FILE_NAME(current_function, @1); } '(' task_port_decl_list ')' ';' block_item_decls_opt statement K_endfunction - { current_function->set_ports($6); - current_function->set_statement($10); - current_function->set_return($2); + { current_function->set_ports($7); + current_function->set_statement($11); + current_function->set_return($3); pform_pop_scope(); current_function = 0; - delete[]$3; + delete[]$4; } - | K_function function_range_or_type_opt IDENTIFIER error K_endfunction + | K_function automatic_opt function_range_or_type_opt IDENTIFIER error K_endfunction { pform_pop_scope(); current_task = 0; - delete[]$3; + delete[]$4; } /* A generate region can contain further module items. Actually, it @@ -2278,6 +2278,15 @@ module_item { yyerror(@1, "error: Malformed $attribute parameter list."); } ; +automatic_opt + : K_automatic + { yyerror(@1, "sorry: automatic tasks/functions are not " + "currently supported."); + yyerrok; + } + | {} + ; + generate_if : K_if '(' expression ')' { pform_start_generate_if(@1, $3); } generate_case_items From 1f5b11246e7bd6befc2e3110bbe7dc81b5a13c06 Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 14 Aug 2008 12:40:53 -0700 Subject: [PATCH 2/3] Correctly pass a concatenation elaboration error. Because Icarus tries to elaborate as much as it can even after an error has occurred we need to check for these errors during elaboration. This patch prevent an undefined identifier from crashing the compiler. --- elaborate.cc | 4 ++-- net_nex_input.cc | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/elaborate.cc b/elaborate.cc index ad7c273ab..332c976eb 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -2649,8 +2649,8 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope, } NexusSet*nset = enet->nex_input(rem_out); if (nset == 0) { - cerr << get_fileline() << ": internal error: No NexusSet" - << " from statement." << endl; + cerr << get_fileline() << ": error: Unable to elaborate:" + << endl; enet->dump(cerr, 6); des->errors += 1; return enet; diff --git a/net_nex_input.cc b/net_nex_input.cc index 2a68c2a8b..0f97c2a44 100644 --- a/net_nex_input.cc +++ b/net_nex_input.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2007 Stephen Williams (steve@icarus.com) + * Copyright (c) 2002-2008 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 @@ -53,8 +53,13 @@ NexusSet* NetEBinary::nex_input(bool rem_out) NexusSet* NetEConcat::nex_input(bool rem_out) { + if (parms_[0] == NULL) return NULL; NexusSet*result = parms_[0]->nex_input(rem_out); for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) { + if (parms_[idx] == NULL) { + delete result; + return NULL; + } NexusSet*tmp = parms_[idx]->nex_input(rem_out); result->add(*tmp); delete tmp; @@ -98,6 +103,10 @@ NexusSet* NetESelect::nex_input(bool rem_out) { NexusSet*result = base_? base_->nex_input(rem_out) : new NexusSet(); NexusSet*tmp = expr_->nex_input(rem_out); + if (tmp == NULL) { + delete result; + return NULL; + } result->add(*tmp); delete tmp; return result; @@ -381,4 +390,3 @@ NexusSet* NetWhile::nex_input(bool rem_out) delete tmp; return result; } - From 2c1426a44dae3b5e18bdcdb4bd17415033d9b0e5 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Fri, 15 Aug 2008 23:58:59 +0100 Subject: [PATCH 3/3] Patch to ensure functions are evaluated immediately. This patch causes a thread that is created to evaluate a function to be executed immediately. The parent thread is resumed when the function thread terminates. --- vvp/vthread.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/vvp/vthread.cc b/vvp/vthread.cc index b83cfc397..86d8ed5dd 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -2076,7 +2076,14 @@ bool of_FORK(vthread_t thr, vvp_code_t cp) thr->fork_count += 1; - schedule_vthread(child, 0, true); + /* If the new child was created to evaluate a function, + run it immediately, then return to this thread. */ + if (cp->scope->base.vpi_type->type_code == vpiFunction) { + child->is_scheduled = 1; + vthread_run(child); + } else { + schedule_vthread(child, 0, true); + } return true; }