diff --git a/parse.y b/parse.y index 62befcb86..8393b4a88 100644 --- a/parse.y +++ b/parse.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: parse.y,v 1.211 2006/03/25 02:42:58 steve Exp $" +#ident "$Id: parse.y,v 1.212 2006/03/30 05:22:34 steve Exp $" #endif # include "config.h" @@ -1065,36 +1065,63 @@ expr_primary declaration) or an input declaration. There are no output or inout ports. */ function_item - : K_input range_opt list_of_identifiers ';' + : K_input signed_opt range_opt list_of_identifiers ';' { svector*tmp - = pform_make_task_ports(NetNet::PINPUT, false, - $2, $3, - @1.text, @1.first_line); - $$ = tmp; - } - | K_input K_signed range_opt list_of_identifiers ';' - { svector*tmp - = pform_make_task_ports(NetNet::PINPUT, true, + = pform_make_task_ports(NetNet::PINPUT, + IVL_VT_LOGIC, $2, $3, $4, @1.text, @1.first_line); $$ = tmp; } - | K_output range_opt list_of_identifiers ';' + | K_output signed_opt range_opt list_of_identifiers ';' { svector*tmp - = pform_make_task_ports(NetNet::PINPUT, false, - $2, $3, + = pform_make_task_ports(NetNet::PINPUT, + IVL_VT_LOGIC, $2, + $3, $4, @1.text, @1.first_line); $$ = tmp; yyerror(@1, "Functions may not have output ports."); } - | K_inout range_opt list_of_identifiers ';' + | K_inout signed_opt range_opt list_of_identifiers ';' { svector*tmp - = pform_make_task_ports(NetNet::PINPUT, false, - $2, $3, + = pform_make_task_ports(NetNet::PINPUT, + IVL_VT_LOGIC, $2, + $3, $4, @1.text, @1.first_line); $$ = tmp; yyerror(@1, "Functions may not have inout ports."); } + /* When the port is an integer, infer a signed vector of the integer + shape. Generate a range to make it work. */ + + | K_input K_integer list_of_identifiers ';' + { svector*range_stub + = new svector(2); + PExpr*re; + re = new PENumber(new verinum(INTEGER_WIDTH-1, + INTEGER_WIDTH)); + (*range_stub)[0] = re; + re = new PENumber(new verinum(0UL, INTEGER_WIDTH)); + (*range_stub)[1] = re; + svector*tmp + = pform_make_task_ports(NetNet::PINPUT, + IVL_VT_LOGIC, true, + range_stub, $3, + @1.text, @1.first_line); + $$ = tmp; + } + + /* Ports can be real. */ + + | K_input K_real list_of_identifiers ';' + { svector*tmp + = pform_make_task_ports(NetNet::PINPUT, + IVL_VT_REAL, false, + 0, $3, + @1.text, @1.first_line); + $$ = tmp; + } + | block_item_decl { $$ = 0; } ; @@ -1641,7 +1668,7 @@ module_item } | port_type signed_opt range_opt delay3_opt error ';' - { yyerror(@3, "error: Invalid variable list" + { yyerror(@1, "error: Invalid variable list" " in port declaration."); if ($3) delete $3; if ($4) delete $4; @@ -2941,24 +2968,109 @@ statement_opt task_item : block_item_decl { $$ = new svector(0); } - | K_input range_opt list_of_identifiers ';' + + /* The basic port concept. */ + + | K_input signed_opt range_opt list_of_identifiers ';' { svector*tmp - = pform_make_task_ports(NetNet::PINPUT, false, - $2, $3, + = pform_make_task_ports(NetNet::PINPUT, + IVL_VT_LOGIC, $2, + $3, $4, @1.text, @1.first_line); $$ = tmp; } - | K_output range_opt list_of_identifiers ';' + | K_output signed_opt range_opt list_of_identifiers ';' { svector*tmp - = pform_make_task_ports(NetNet::POUTPUT, false, - $2, $3, + = pform_make_task_ports(NetNet::POUTPUT, + IVL_VT_LOGIC, $2, + $3, $4, @1.text, @1.first_line); $$ = tmp; } - | K_inout range_opt list_of_identifiers ';' + | K_inout signed_opt range_opt list_of_identifiers ';' { svector*tmp - = pform_make_task_ports(NetNet::PINOUT, false, - $2, $3, + = pform_make_task_ports(NetNet::PINOUT, + IVL_VT_LOGIC, $2, + $3, $4, + @1.text, @1.first_line); + $$ = tmp; + } + + /* When the port is an integer, infer a signed vector of the integer + shape. Generate a range to make it work. */ + + | K_input K_integer list_of_identifiers ';' + { svector*range_stub + = new svector(2); + PExpr*re; + re = new PENumber(new verinum(INTEGER_WIDTH-1, + INTEGER_WIDTH)); + (*range_stub)[0] = re; + re = new PENumber(new verinum(0UL, INTEGER_WIDTH)); + (*range_stub)[1] = re; + svector*tmp + = pform_make_task_ports(NetNet::PINPUT, + IVL_VT_LOGIC, true, + range_stub, $3, + @1.text, @1.first_line); + $$ = tmp; + } + | K_output K_integer list_of_identifiers ';' + { svector*range_stub + = new svector(2); + PExpr*re; + re = new PENumber(new verinum(INTEGER_WIDTH-1, + INTEGER_WIDTH)); + (*range_stub)[0] = re; + re = new PENumber(new verinum(0UL, INTEGER_WIDTH)); + (*range_stub)[1] = re; + svector*tmp + = pform_make_task_ports(NetNet::POUTPUT, + IVL_VT_LOGIC, true, + range_stub, $3, + @1.text, @1.first_line); + $$ = tmp; + } + | K_inout K_integer list_of_identifiers ';' + { svector*range_stub + = new svector(2); + PExpr*re; + re = new PENumber(new verinum(INTEGER_WIDTH-1, + INTEGER_WIDTH)); + (*range_stub)[0] = re; + re = new PENumber(new verinum(0UL, INTEGER_WIDTH)); + (*range_stub)[1] = re; + svector*tmp + = pform_make_task_ports(NetNet::PINOUT, + IVL_VT_LOGIC, true, + range_stub, $3, + @1.text, @1.first_line); + $$ = tmp; + } + + /* Ports can be real. */ + + | K_input K_real list_of_identifiers ';' + { svector*tmp + = pform_make_task_ports(NetNet::PINPUT, + IVL_VT_REAL, false, + 0, $3, + @1.text, @1.first_line); + $$ = tmp; + } + | K_output K_real list_of_identifiers ';' + { svector*tmp + = pform_make_task_ports(NetNet::POUTPUT, + IVL_VT_REAL, true, + 0, $3, + @1.text, @1.first_line); + $$ = tmp; + } + | K_inout K_real list_of_identifiers ';' + { svector*tmp + = pform_make_task_ports(NetNet::PINOUT, + IVL_VT_REAL, true, + 0, $3, @1.text, @1.first_line); $$ = tmp; } diff --git a/pform.cc b/pform.cc index 25930b5d3..17aa1cb21 100644 --- a/pform.cc +++ b/pform.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: pform.cc,v 1.133 2005/07/11 16:56:51 steve Exp $" +#ident "$Id: pform.cc,v 1.134 2006/03/30 05:22:34 steve Exp $" #endif # include "config.h" @@ -1266,6 +1266,7 @@ void pform_set_port_type(perm_string nm, NetNet::PortType pt, * no output or inout ports. */ svector*pform_make_task_ports(NetNet::PortType pt, + ivl_variable_type_t vtype, bool signed_flag, svector*range, list*names, @@ -1286,8 +1287,7 @@ svector*pform_make_task_ports(NetNet::PortType pt, if (curw) { curw->set_port_type(pt); } else { - curw = new PWire(name, NetNet::IMPLICIT_REG, pt, - IVL_VT_LOGIC); + curw = new PWire(name, NetNet::IMPLICIT_REG, pt, vtype); curw->set_file(file); curw->set_lineno(lineno); pform_cur_module->add_wire(curw); @@ -1596,6 +1596,9 @@ int pform_parse(const char*path, FILE*file) /* * $Log: pform.cc,v $ + * Revision 1.134 2006/03/30 05:22:34 steve + * task/function ports can have types. + * * Revision 1.133 2005/07/11 16:56:51 steve * Remove NetVariable and ivl_variable_t structures. * diff --git a/pform.h b/pform.h index a5767b249..b9138a09b 100644 --- a/pform.h +++ b/pform.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: pform.h,v 1.84 2005/12/05 21:21:18 steve Exp $" +#ident "$Id: pform.h,v 1.85 2006/03/30 05:22:34 steve Exp $" #endif # include "netlist.h" @@ -289,6 +289,7 @@ extern void pform_make_pgassign_list(svector*alist, /* Given a port type and a list of names, make a list of wires that can be used as task port information. */ extern svector*pform_make_task_ports(NetNet::PortType pt, + ivl_variable_type_t vtype, bool signed_flag, svector*range, list*names, @@ -306,6 +307,9 @@ extern void pform_dump(ostream&out, Module*mod); /* * $Log: pform.h,v $ + * Revision 1.85 2006/03/30 05:22:34 steve + * task/function ports can have types. + * * Revision 1.84 2005/12/05 21:21:18 steve * Fixes for stubborn compilers. *