Merge branch 'master' of git://icarus.com/~steve-icarus/verilog into vhdl

This commit is contained in:
Nick Gasson 2008-08-18 15:16:02 +01:00
commit e01b16e586
5 changed files with 57 additions and 32 deletions

View File

@ -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;

View File

@ -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

View File

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

63
parse.y
View File

@ -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

View File

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