From fe3dd3a559badd9a25993b85040e5afe98041b85 Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 14 May 2009 09:32:15 -0700 Subject: [PATCH] Add support for initializing outputs declared as output reg. The standard allows an output declared as "output reg" to be given an initialization assignment in the output declaration. this patch adds that functionality. Specifically: output reg out = 1'b0; works as expected. --- netmisc.cc | 1 + parse.y | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/netmisc.cc b/netmisc.cc index 4840ca0f2..183d9d47e 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -416,6 +416,7 @@ const char *human_readable_op(const char op, bool unary) case '-': type = "-"; break; case '*': type = "*"; break; case '/': type = "/"; break; + case '%': type = "%"; break; case '<': type = "<"; break; case '>': type = ">"; break; diff --git a/parse.y b/parse.y index 24ef79d2d..764d99ffc 100644 --- a/parse.y +++ b/parse.y @@ -80,6 +80,22 @@ static stack current_block_stack; const static struct str_pair_t pull_strength = { PGate::PULL, PGate::PULL }; const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG }; +static list >* make_port_list(char*id, PExpr*expr) +{ + list >*tmp = new list >; + tmp->push_back(make_pair(lex_strings.make(id), expr)); + delete[]id; + return tmp; +} +static list >* make_port_list(list >*tmp, + char*id, PExpr*expr) +{ + tmp->push_back(make_pair(lex_strings.make(id), expr)); + delete[]id; + return tmp; +} + static list* list_from_identifier(char*id) { list*tmp = new list; @@ -146,6 +162,9 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2) strdup. They can be put into lists with the texts type. */ char*text; list*perm_strings; + + list >*port_list; + pform_name_t*pform_name; ivl_discipline_t discipline; @@ -260,7 +279,9 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2) %type udp_initial_expr_opt %type register_variable net_variable real_variable -%type register_variable_list net_variable_list real_variable_list list_of_identifiers +%type register_variable_list net_variable_list +%type real_variable_list list_of_identifiers +%type list_of_port_identifiers %type net_decl_assign net_decl_assigns @@ -1647,6 +1668,17 @@ list_of_identifiers { $$ = list_from_identifier($1, $3); } ; +list_of_port_identifiers + : IDENTIFIER + { $$ = make_port_list($1, 0); } + | IDENTIFIER '=' expression + { $$ = make_port_list($1, $3); } + | list_of_port_identifiers ',' IDENTIFIER + { $$ = make_port_list($1, $3, 0); } + | list_of_port_identifiers ',' IDENTIFIER '=' expression + { $$ = make_port_list($1, $3, $5); } + ; + /* The list_of_ports and list_of_port_declarations rules are the port list formats for module ports. The list_of_ports_opt rule is @@ -1991,9 +2023,20 @@ module_item SR_BOTH); } - | K_output var_type signed_opt range_opt list_of_identifiers ';' - { pform_makewire(@1, $4, $3, $5, $2, NetNet::POUTPUT, - IVL_VT_NO_TYPE, 0, SR_BOTH); + | K_output var_type signed_opt range_opt list_of_port_identifiers ';' + { list >::const_iterator pp; + list*tmp = new list; + for (pp = $5->begin(); pp != $5->end(); pp++) { + tmp->push_back((*pp).first); + } + pform_makewire(@1, $4, $3, tmp, $2, NetNet::POUTPUT, + IVL_VT_NO_TYPE, 0, SR_BOTH); + for (pp = $5->begin(); pp != $5->end(); pp++) { + if ((*pp).second) { + pform_make_reginit(@1, (*pp).first, (*pp).second); + } + } + delete $5; } /* var_type declaration (reg variables) cannot be input or output,