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,