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/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/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; } - 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 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; }