diff --git a/elab_sig.cc b/elab_sig.cc index 9f762c5ad..6f778f669 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -144,10 +144,12 @@ static void sig_check_port_type(Design*des, NetScope*scope, return; /* If the signal is an input and is also declared as a - reg, then report an error. */ + reg, then report an error. In SystemVerilog a input + is allowed to be a register. It will get converted + to a unresolved wire when the port is connected. */ if (sig->port_type() == NetNet::PINPUT && - sig->type() == NetNet::REG) { + sig->type() == NetNet::REG && !gn_var_can_be_uwire()) { cerr << wire->get_fileline() << ": error: Port `" << wire->basename() << "` of module `" << scope->module_name() diff --git a/elaborate.cc b/elaborate.cc index 6357d6f14..6a38d8b16 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -1533,6 +1533,13 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const delete tmp_expr; if (!sig->get_lineno()) sig->set_line(*this); + if (ptype == NetNet::PINPUT && gn_var_can_be_uwire()) { + for (unsigned int i = 0; i < prts.size(); i++) { + if (prts[i]->type() == NetNet::REG) + prts[i]->type(NetNet::UNRESOLVED_WIRE); + } + } + if (need_bufz_for_input_port(prts)) { NetBUFZ*tmp = new NetBUFZ(scope, scope->local_symbol(), sig->vector_width(), true); diff --git a/ivtest/ivltests/sv_var_block.v b/ivtest/ivltests/sv_var_block.v new file mode 100644 index 000000000..e5a6590cb --- /dev/null +++ b/ivtest/ivltests/sv_var_block.v @@ -0,0 +1,50 @@ +// Check that the var keyword is supported for variable declarations in blocks + +`define check(val, exp) \ + if (val !== exp) begin \ + $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ + failed = 1'b1; \ + end + +module test; + + bit failed = 1'b0; + + initial begin + var x; + var [7:0] y; + var signed [8:0] z; + var logic [9:0] w; + + x = 1'b1; + y = 8'd10; + z = -8'sd1; + w = 8'd20; + + `check(x, 1'b1) + `check(y, 10) + `check(z, -1) + `check(w, 20) + + // var should default to logic and allow x state + x = 1'bx; + y = 8'hxx; + z = 8'hxx; + w = 8'hxx; + + `check(x, 1'bx) + `check(y, 8'hxx) + `check(z, 8'hxx) + `check(w, 8'hxx) + + `check($bits(x), 1) + `check($bits(y), 8) + `check($bits(z), 9) + `check($bits(w), 10) + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_var_for.v b/ivtest/ivltests/sv_var_for.v new file mode 100644 index 000000000..f676125b0 --- /dev/null +++ b/ivtest/ivltests/sv_var_for.v @@ -0,0 +1,17 @@ +// Check that var keyword is supported in for loop variable declarations + +module test; + + initial begin + int j; + for (var int i = 0; i < 10; i++) begin + j = i; + end + if (j == 9) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_var_for_fail.v b/ivtest/ivltests/sv_var_for_fail.v new file mode 100644 index 000000000..827613d5c --- /dev/null +++ b/ivtest/ivltests/sv_var_for_fail.v @@ -0,0 +1,13 @@ +// Check that it is an error to not declare the data type in for loops, even +// when using var + +module test; + + initial begin + // The data type is not optional in a for loop, even when using var + for (var [7:0] i = 0; i < 10; i++) begin + end + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/sv_var_function.v b/ivtest/ivltests/sv_var_function.v new file mode 100644 index 000000000..829454ca7 --- /dev/null +++ b/ivtest/ivltests/sv_var_function.v @@ -0,0 +1,41 @@ +// Check that the var keyword is supported for function ports + +`define check(val, exp) \ + if (val !== exp) begin \ + $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ + return 1'b1; \ + end \ + return 1'b0; + +module test; + + function bit f1 (var int x); + `check(x, 10) + endfunction + + function bit f2 (input var int x); + `check(x, 20) + endfunction + + function bit f3 (var [7:0] x); + `check(x, 30) + endfunction + + function bit f4 (input var [7:0] x); + `check(x, 40) + endfunction + + initial begin + bit failed; + + failed = f1(10); + failed |= f2(20); + failed |= f3(30); + failed |= f4(40); + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_var_module.v b/ivtest/ivltests/sv_var_module.v new file mode 100644 index 000000000..0b63786dd --- /dev/null +++ b/ivtest/ivltests/sv_var_module.v @@ -0,0 +1,50 @@ +// Check that the var keyword is supported for variable declarations in modules + +`define check(val, exp) \ + if (val !== exp) begin \ + $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ + failed = 1'b1; \ + end + +module test; + + var x; + var [7:0] y; + var signed [8:0] z; + var logic [9:0] w; + + bit failed = 1'b0; + + initial begin + x = 1'b1; + y = 8'd10; + z = -8'sd1; + w = 8'd20; + + `check(x, 1'b1) + `check(y, 10) + `check(z, -1) + `check(w, 20) + + // var should default to logic and allow x state + x = 1'bx; + y = 8'hxx; + z = 8'hxx; + w = 8'hxx; + + `check(x, 1'bx) + `check(y, 8'hxx) + `check(z, 8'hxx) + `check(w, 8'hxx) + + `check($bits(x), 1) + `check($bits(y), 8) + `check($bits(z), 9) + `check($bits(w), 10) + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_var_module_inout1.v b/ivtest/ivltests/sv_var_module_inout1.v new file mode 100644 index 000000000..4e07e8178 --- /dev/null +++ b/ivtest/ivltests/sv_var_module_inout1.v @@ -0,0 +1,11 @@ +// Check that using the var keyword for module ANSI inout ports results in an error + +module test #( + inout var x +); + + initial begin + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/sv_var_module_inout2.v b/ivtest/ivltests/sv_var_module_inout2.v new file mode 100644 index 000000000..cb0f68026 --- /dev/null +++ b/ivtest/ivltests/sv_var_module_inout2.v @@ -0,0 +1,10 @@ +// Check that using the var keyword for module non-ANSI inout ports results in an error + +module test; + inout var x; + + initial begin + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/sv_var_module_input1.v b/ivtest/ivltests/sv_var_module_input1.v new file mode 100644 index 000000000..d23a9dca0 --- /dev/null +++ b/ivtest/ivltests/sv_var_module_input1.v @@ -0,0 +1,61 @@ +// Check that the var keyword is supported for module ANSI input ports + +bit failed = 1'b0; + +`define check(val, exp) \ + if (val !== exp) begin \ + $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ + failed = 1'b1; \ + end + +module M #( + parameter VAL_X = 0, + parameter VAL_Y = 0, + parameter VAL_Z = 0, + parameter VAL_W = 0 +) ( + input var x, + input var [7:0] y, + input var signed [7:0] z, + input var logic [7:0] w +); + + initial begin + `check(x, VAL_X) + `check(y, VAL_Y) + `check(z, VAL_Z) + `check(w, VAL_W) + end + +endmodule + +module test; + + M #( + .VAL_X (1'b1), + .VAL_Y (8'd10), + .VAL_Z (-8'sd1), + .VAL_W (8'd20) + ) i_m1 ( + .x (1'b1), + .y (8'd10), + .z (-8'sd1), + .w (8'd20) + ); + + // When unconnected it should default to x, rather z + M #( + .VAL_X (1'bx), + .VAL_Y (8'hx), + .VAL_Z (8'hx), + .VAL_W (8'hx) + ) i_m2 (); + + initial begin + #1 + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_var_module_input2.v b/ivtest/ivltests/sv_var_module_input2.v new file mode 100644 index 000000000..5ec7702fc --- /dev/null +++ b/ivtest/ivltests/sv_var_module_input2.v @@ -0,0 +1,60 @@ +// Check that the var keyword is supported for module non-ANSI input ports + +bit failed = 1'b0; + +`define check(val, exp) \ + if (val !== exp) begin \ + $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ + failed = 1'b1; \ + end + +module M(x, y, z, w); + parameter VAL_X = 0; + parameter VAL_Y = 0; + parameter VAL_Z = 0; + parameter VAL_W = 0; + + input var x; + input var [7:0] y; + input var signed [7:0] z; + input var logic [7:0] w; + + initial begin + `check(x, VAL_X) + `check(y, VAL_Y) + `check(z, VAL_Z) + `check(w, VAL_W) + end + +endmodule + +module test; + + M #( + .VAL_X (1'b1), + .VAL_Y (8'd10), + .VAL_Z (-8'sd1), + .VAL_W (8'd20) + ) i_m1 ( + .x (1'b1), + .y (8'd10), + .z (-8'sd1), + .w (8'd20) + ); + + // When unconnected it should default to x, rather z + M #( + .VAL_X (1'bx), + .VAL_Y (8'hx), + .VAL_Z (8'hx), + .VAL_W (8'hx) + ) i_m2 (); + + initial begin + #1 + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_var_module_output1.v b/ivtest/ivltests/sv_var_module_output1.v new file mode 100644 index 000000000..1e64aff13 --- /dev/null +++ b/ivtest/ivltests/sv_var_module_output1.v @@ -0,0 +1,81 @@ +// Check that the var keyword is supported for module ANSI output ports + +bit failed = 1'b0; + +`define check(val, exp) \ + if (val !== exp) begin \ + $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ + failed = 1'b1; \ + end + +module M #( + parameter VAL_X = 0, + parameter VAL_Y = 0, + parameter VAL_Z = 0, + parameter VAL_W = 0 +) ( + output var x, + output var [7:0] y, + output var signed [7:0] z, + output var logic [7:0] w +); + + assign x = VAL_X; + assign y = VAL_Y; + assign z = VAL_Z; + assign w = VAL_W; + +endmodule + +module test; + + logic x1; + logic x2; + logic [7:0] y1; + logic [7:0] y2; + logic signed [7:0] z1; + logic signed [7:0] z2; + logic [7:0] w1; + logic [7:0] w2; + + M #( + .VAL_X (1'b1), + .VAL_Y (10), + .VAL_Z (-1), + .VAL_W (20) + ) i_m1 ( + .x (x1), + .y (y1), + .z (z1), + .w (w1) + ); + + // The type for var should default to logic, check that the value can be X + M #( + .VAL_X (1'bx), + .VAL_Y (8'hxx), + .VAL_Z (8'hxx), + .VAL_W (8'hxx) + ) i_m2 ( + .x (x2), + .y (y2), + .z (z2), + .w (w2) + ); + + initial begin + `check(x1, 1'b1) + `check(y1, 10) + `check(z1, -1) + `check(w1, 20) + `check(x2, 1'bx) + `check(y2, 8'hxx) + `check(z2, 8'hxx) + `check(w2, 8'hxx) + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_var_module_output2.v b/ivtest/ivltests/sv_var_module_output2.v new file mode 100644 index 000000000..ca7962c9d --- /dev/null +++ b/ivtest/ivltests/sv_var_module_output2.v @@ -0,0 +1,80 @@ +// Check that the var keyword is supported for module non-ANSI output ports + +bit failed = 1'b0; + +`define check(val, exp) \ + if (val !== exp) begin \ + $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ + failed = 1'b1; \ + end + +module M(x, y, z, w); + parameter VAL_X = 0; + parameter VAL_Y = 0; + parameter VAL_Z = 0; + parameter VAL_W = 0; + + output var x; + output var [7:0] y; + output var signed [7:0] z; + output var logic [7:0] w; + + assign x = VAL_X; + assign y = VAL_Y; + assign z = VAL_Z; + assign w = VAL_W; + +endmodule + +module test; + + logic x1; + logic x2; + logic [7:0] y1; + logic [7:0] y2; + logic signed [7:0] z1; + logic signed [7:0] z2; + logic [7:0] w1; + logic [7:0] w2; + + M #( + .VAL_X (1'b1), + .VAL_Y (10), + .VAL_Z (-1), + .VAL_W (20) + ) i_m1 ( + .x (x1), + .y (y1), + .z (z1), + .w (w1) + ); + + // The type for var should default to logic, check that the value can be X + M #( + .VAL_X (1'bx), + .VAL_Y (8'hxx), + .VAL_Z (8'hxx), + .VAL_W (8'hxx) + ) i_m2 ( + .x (x2), + .y (y2), + .z (z2), + .w (w2) + ); + + initial begin + `check(x1, 1'b1) + `check(y1, 10) + `check(z1, -1) + `check(w1, 20) + `check(x2, 1'bx) + `check(y2, 8'hxx) + `check(z2, 8'hxx) + `check(w2, 8'hxx) + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_var_package.v b/ivtest/ivltests/sv_var_package.v new file mode 100644 index 000000000..4030a9c7f --- /dev/null +++ b/ivtest/ivltests/sv_var_package.v @@ -0,0 +1,53 @@ +// Check that the var keyword is supported for variable declarations in packages + +`define check(val, exp) \ + if (val !== exp) begin \ + $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ + failed = 1'b1; \ + end + +package P; + var x; + var [7:0] y; + var signed [8:0] z; + var logic [9:0] w; +endpackage + +module test; + import P::*; + + bit failed = 1'b0; + + initial begin + x = 1'b1; + y = 8'd10; + z = -8'sd1; + w = 8'd20; + + `check(x, 1'b1) + `check(y, 10) + `check(z, -1) + `check(w, 20) + + // var should default to logic and allow x state + x = 1'bx; + y = 8'hxx; + z = 8'hxx; + w = 8'hxx; + + `check(x, 1'bx) + `check(y, 8'hxx) + `check(z, 8'hxx) + `check(w, 8'hxx) + + `check($bits(x), 1) + `check($bits(y), 8) + `check($bits(z), 9) + `check($bits(w), 10) + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_var_task.v b/ivtest/ivltests/sv_var_task.v new file mode 100644 index 000000000..70ee3fb7f --- /dev/null +++ b/ivtest/ivltests/sv_var_task.v @@ -0,0 +1,48 @@ +// Check that the var keyword is supported for task ports + +bit failed = 1'b0; + +`define check(val, exp) \ + if (val !== exp) begin \ + $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ + failed = 1'b1; \ + end + +module test; + + task t1 (var int x); + `check(x, 10) + endtask + + task t2 (input var int x, output var int y); + `check(x, 20) + y = x; + endtask + + task t3 (var [7:0] x); + `check(x, 30) + endtask + + task t4 (input var [7:0] x, output var [7:0] y); + `check(x, 40) + y = x; + endtask + + initial begin + int o1; + logic [7:0] o2; + + t1(10); + t2(20, o1); + t3(30); + t4(40, o2); + + `check(o1, 20) + `check(o2, 40) + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index d21ffab1b..c01b065bb 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -694,8 +694,21 @@ sv_uwire1 normal,-g2009 ivltests sv_uwire2 normal,-g2009 ivltests sv_uwire3 normal,-g2009 ivltests sv_uwire4 normal,-g2009 ivltests +sv_var_block normal,-g2005-sv ivltests +sv_var_for normal,-g2005-sv ivltests +sv_var_for_fail CE,-g2005-sv ivltests +sv_var_function normal,-g2005-sv ivltests sv_var_init1 normal,-g2009 ivltests sv_var_init2 normal,-g2009 ivltests +sv_var_module normal,-g2005-sv ivltests +sv_var_module_inout1 CE,-g2005-sv ivltests +sv_var_module_inout2 CE,-g2005-sv ivltests +sv_var_module_input1 normal,-g2005-sv ivltests +sv_var_module_input2 normal,-g2005-sv ivltests +sv_var_module_output1 normal,-g2005-sv ivltests +sv_var_module_output2 normal,-g2005-sv ivltests +sv_var_package normal,-g2005-sv ivltests +sv_var_task normal,-g2005-sv ivltests sv_wildcard_import1 normal,-g2009 ivltests sv_wildcard_import2 normal,-g2009 ivltests sv_wildcard_import3 normal,-g2009 ivltests diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index 76d24a9ee..0f0b72526 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -942,6 +942,17 @@ sv_port_default10 normal,-g2009,-pallowsigned=1 ivltests sv_port_default11 normal,-g2009,-pallowsigned=1 ivltests sv_root_func normal,-g2009,-pallowsigned=1 ivltests gold=sv_root_func.gold sv_root_task normal,-g2009,-pallowsigned=1 ivltests gold=sv_root_task.gold +sv_var_block normal,-g2005-sv,-pallowsigned=1 ivltests +sv_var_for normal,-g2005-sv,-pallowsigned=1 ivltests +sv_var_function normal,-g2005-sv,-pallowsigned=1 ivltests +sv_var_module normal,-g2005-sv,-pallowsigned=1 ivltests +# Inputs can not be reg in Verilog 95, so the translated code will fail +sv_var_module_input1 TE,-g2005-sv,-pallowsigned=1 ivltests +sv_var_module_input2 TE,-g2005-sv,-pallowsigned=1 ivltests +sv_var_module_output1 normal,-g2005-sv,-pallowsigned=1 ivltests +sv_var_module_output2 normal,-g2005-sv,-pallowsigned=1 ivltests +sv_var_package normal,-g2005-sv,-pallowsigned=1 ivltests +sv_var_task normal,-g2005-sv,-pallowsigned=1 ivltests test_dispwided normal,-pallowsigned=1 ivltests gold=test_dispwided.gold test_inc_dec normal,-g2009,-pallowsigned=1 ivltests test_enumsystem normal,-g2009,-pallowsigned=1,ivltests/enumsystem.vhd ivltests diff --git a/parse.y b/parse.y index f56ebbb27..1295aaa94 100644 --- a/parse.y +++ b/parse.y @@ -682,7 +682,7 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector variable_dimension %type dimensions_opt dimensions -%type net_type net_type_opt +%type net_type net_type_opt net_type_or_var net_type_or_var_opt %type gatetype switchtype %type port_direction port_direction_opt %type integer_vector_type @@ -1173,6 +1173,14 @@ data_declaration /* IEEE1800-2005: A.2.1.3 */ } pform_makewire(@2, 0, str_strength, $3, NetNet::IMPLICIT_REG, data_type, $1); } + | attribute_list_opt K_var data_type_or_implicit list_of_variable_decl_assignments ';' + { data_type_t*data_type = $3; + if (data_type == 0) { + data_type = new vector_type_t(IVL_VT_LOGIC, false, 0); + FILE_NAME(data_type, @2); + } + pform_make_var(@2, $4, data_type, $1); + } | attribute_list_opt K_event event_variable_list ';' { if ($3) pform_make_events(@2, $3); } @@ -1638,7 +1646,7 @@ loop_statement /* IEEE1800-2005: A.6.8 */ // statement in a synthetic named block. We can name the block // after the variable that we are creating, that identifier is // safe in the controlling scope. - | K_for '(' data_type IDENTIFIER '=' expression ';' expression ';' for_step ')' + | K_for '(' K_var_opt data_type IDENTIFIER '=' expression ';' expression ';' for_step ')' { static unsigned for_counter = 0; char for_block_name [64]; snprintf(for_block_name, sizeof for_block_name, "$ivl_for_loop%u", for_counter); @@ -1648,18 +1656,18 @@ loop_statement /* IEEE1800-2005: A.6.8 */ listassign_list; decl_assignment_t*tmp_assign = new decl_assignment_t; - tmp_assign->name = lex_strings.make($4); + tmp_assign->name = lex_strings.make($5); assign_list.push_back(tmp_assign); - pform_make_var(@4, &assign_list, $3); + pform_make_var(@5, &assign_list, $4); } statement_or_null { pform_name_t tmp_hident; - tmp_hident.push_back(name_component_t(lex_strings.make($4))); + tmp_hident.push_back(name_component_t(lex_strings.make($5))); - PEIdent*tmp_ident = pform_new_ident(@4, tmp_hident); - FILE_NAME(tmp_ident, @4); + PEIdent*tmp_ident = pform_new_ident(@5, tmp_hident); + FILE_NAME(tmp_ident, @5); - PForStatement*tmp_for = new PForStatement(tmp_ident, $6, $8, $10, $13); + PForStatement*tmp_for = new PForStatement(tmp_ident, $7, $9, $11, $14); FILE_NAME(tmp_for, @1); pform_pop_scope(); @@ -1669,7 +1677,7 @@ loop_statement /* IEEE1800-2005: A.6.8 */ current_block_stack.pop(); tmp_blk->set_statement(tmp_for_list); $$ = tmp_blk; - delete[]$4; + delete[]$5; } | K_forever statement_or_null @@ -2318,8 +2326,8 @@ task_declaration /* IEEE1800-2005: A.2.7 */ tf_port_declaration /* IEEE1800-2005: A.2.7 */ - : port_direction data_type_or_implicit list_of_port_identifiers ';' - { $$ = pform_make_task_ports(@1, $1, $2, $3, true); + : port_direction K_var_opt data_type_or_implicit list_of_port_identifiers ';' + { $$ = pform_make_task_ports(@1, $1, $3, $4, true); } ; @@ -2334,25 +2342,25 @@ tf_port_declaration /* IEEE1800-2005: A.2.7 */ tf_port_item /* IEEE1800-2005: A.2.7 */ - : port_direction_opt data_type_or_implicit IDENTIFIER dimensions_opt tf_port_item_expr_opt + : port_direction_opt K_var_opt data_type_or_implicit IDENTIFIER dimensions_opt tf_port_item_expr_opt { std::vector*tmp; NetNet::PortType use_port_type = $1; - if ((use_port_type == NetNet::PIMPLICIT) && (gn_system_verilog() || ($2 == 0))) + if ((use_port_type == NetNet::PIMPLICIT) && (gn_system_verilog() || ($3 == 0))) use_port_type = port_declaration_context.port_type; - list* port_list = make_port_list($3, $4, 0); + list* port_list = make_port_list($4, $5, 0); if (use_port_type == NetNet::PIMPLICIT) { yyerror(@1, "error: missing task/function port direction."); use_port_type = NetNet::PINPUT; // for error recovery } - if (($2 == 0) && ($1==NetNet::PIMPLICIT)) { + if (($3 == 0) && ($1==NetNet::PIMPLICIT)) { // Detect special case this is an undecorated // identifier and we need to get the declaration from // left context. - if ($4 != 0) { - yyerror(@4, "internal error: How can there be an unpacked range here?\n"); + if ($5 != 0) { + yyerror(@5, "internal error: How can there be an unpacked range here?\n"); } - tmp = pform_make_task_ports(@3, use_port_type, + tmp = pform_make_task_ports(@4, use_port_type, port_declaration_context.data_type, port_list); @@ -2361,25 +2369,25 @@ tf_port_item /* IEEE1800-2005: A.2.7 */ // indicate the type. Save the type for any right // context that may come later. port_declaration_context.port_type = use_port_type; - if ($2 == 0) { - $2 = new vector_type_t(IVL_VT_LOGIC, false, 0); - FILE_NAME($2, @3); + if ($3 == 0) { + $3 = new vector_type_t(IVL_VT_LOGIC, false, 0); + FILE_NAME($3, @4); } - port_declaration_context.data_type = $2; - tmp = pform_make_task_ports(@3, use_port_type, $2, port_list); + port_declaration_context.data_type = $3; + tmp = pform_make_task_ports(@3, use_port_type, $3, port_list); } $$ = tmp; - if ($5) { + if ($6) { assert(tmp->size()==1); - tmp->front().defe = $5; + tmp->front().defe = $6; } } /* Rules to match error cases... */ - | port_direction_opt data_type_or_implicit IDENTIFIER error - { yyerror(@3, "error: Error in task/function port item after port name %s.", $3); + | port_direction_opt K_var_opt data_type_or_implicit IDENTIFIER error + { yyerror(@3, "error: Error in task/function port item after port name %s.", $4); yyerrok; $$ = 0; } @@ -2511,7 +2519,7 @@ variable_dimension /* IEEE1800-2005: A.2.5 */ } ; -variable_lifetime +variable_lifetime_opt : lifetime { if (pform_requires_sv(@1, "Overriding default variable lifetime") && $1 != pform_peek_scope()->default_lifetime) { @@ -2520,6 +2528,7 @@ variable_lifetime } var_lifetime = $1; } + | ; /* Verilog-2001 supports attribute lists, which can be attached to a @@ -2592,21 +2601,23 @@ block_item_decl /* variable declarations. Note that data_type can be 0 if we are recovering from an error. */ - : data_type list_of_variable_decl_assignments ';' - { if ($1) pform_make_var(@1, $2, $1, attributes_in_context); + : K_var variable_lifetime_opt data_type_or_implicit list_of_variable_decl_assignments ';' + { data_type_t*data_type = $3; + if (data_type == 0) { + data_type = new vector_type_t(IVL_VT_LOGIC, false, 0); + FILE_NAME(data_type, @1); + } + pform_make_var(@1, $4, data_type, attributes_in_context); + var_lifetime = LexicalScope::INHERITED; } - | variable_lifetime data_type list_of_variable_decl_assignments ';' + | variable_lifetime_opt data_type list_of_variable_decl_assignments ';' { if ($2) pform_make_var(@2, $3, $2, attributes_in_context); var_lifetime = LexicalScope::INHERITED; } /* The extra `reg` is not valid (System)Verilog, this is a iverilog extension. */ - | K_reg data_type list_of_variable_decl_assignments ';' - { if ($2) pform_make_var(@2, $3, $2, attributes_in_context); - } - - | variable_lifetime K_reg data_type list_of_variable_decl_assignments ';' + | variable_lifetime_opt K_reg data_type list_of_variable_decl_assignments ';' { if ($3) pform_make_var(@3, $4, $3, attributes_in_context); var_lifetime = LexicalScope::INHERITED; } @@ -2628,13 +2639,16 @@ block_item_decl /* Recover from errors that happen within variable lists. Use the trailing semi-colon to resync the parser. */ - | K_integer error ';' - { yyerror(@1, "error: syntax error in integer variable list."); + | K_var variable_lifetime_opt data_type_or_implicit error ';' + { yyerror(@1, "error: syntax error in variable list."); yyerrok; } - - | K_time error ';' - { yyerror(@1, "error: syntax error in time variable list."); + | variable_lifetime_opt data_type error ';' + { yyerror(@1, "error: syntax error in variable list."); + yyerrok; + } + | K_event error ';' + { yyerror(@1, "error: syntax error in event variable list."); yyerrok; } @@ -4385,7 +4399,7 @@ list_of_port_declarations ; port_declaration - : attribute_list_opt K_input net_type_opt data_type_or_implicit IDENTIFIER dimensions_opt + : attribute_list_opt K_input net_type_or_var_opt data_type_or_implicit IDENTIFIER dimensions_opt { Module::port_t*ptmp; perm_string name = lex_strings.make($5); data_type_t*use_type = $4; @@ -4413,7 +4427,7 @@ port_declaration delete[]$4; $$ = ptmp; } - | attribute_list_opt K_input net_type_opt data_type_or_implicit IDENTIFIER '=' expression + | attribute_list_opt K_input net_type_or_var_opt data_type_or_implicit IDENTIFIER '=' expression { pform_requires_sv(@6, "Default port value"); Module::port_t*ptmp; perm_string name = lex_strings.make($5); @@ -4457,7 +4471,7 @@ port_declaration delete[]$4; $$ = ptmp; } - | attribute_list_opt K_output net_type_opt data_type_or_implicit IDENTIFIER dimensions_opt + | attribute_list_opt K_output net_type_or_var_opt data_type_or_implicit IDENTIFIER dimensions_opt { Module::port_t*ptmp; perm_string name = lex_strings.make($5); data_type_t*use_dtype = $4; @@ -4501,7 +4515,7 @@ port_declaration delete[]$4; $$ = ptmp; } - | attribute_list_opt K_output net_type_opt data_type_or_implicit IDENTIFIER '=' expression + | attribute_list_opt K_output net_type_or_var_opt data_type_or_implicit IDENTIFIER '=' expression { Module::port_t*ptmp; perm_string name = lex_strings.make($5); NetNet::Type use_type = $3; @@ -4521,13 +4535,6 @@ port_declaration } ; - - -net_type_opt - : net_type { $$ = $1; } - | { $$ = NetNet::IMPLICIT; } - ; - /* * The signed_opt rule will return "true" if K_signed is present, * for "false" otherwise. This rule corresponds to the declaration @@ -4864,7 +4871,7 @@ module_item input wire signed [h:l] ; This creates the wire and sets the port type all at once. */ - | attribute_list_opt port_direction net_type data_type_or_implicit list_of_port_identifiers ';' + | attribute_list_opt port_direction net_type_or_var data_type_or_implicit list_of_port_identifiers ';' { pform_module_define_port(@2, $5, $2, $3, $4, $1); } | attribute_list_opt port_direction K_wreal list_of_port_identifiers ';' @@ -4923,7 +4930,7 @@ module_item pform_module_define_port(@2, $4, NetNet::POUTPUT, use_type, $3, $1); } - | attribute_list_opt port_direction net_type data_type_or_implicit error ';' + | attribute_list_opt port_direction net_type_or_var data_type_or_implicit error ';' { yyerror(@2, "error: Invalid variable list in port declaration."); if ($1) delete $1; if ($4) delete $4; @@ -5386,6 +5393,20 @@ net_type | K_uwire { $$ = NetNet::UNRESOLVED_WIRE; } ; +net_type_opt + : net_type { $$ = $1; } + | { $$ = NetNet::IMPLICIT; } + ; + +net_type_or_var + : net_type { $$ = $1; } + | K_var { $$ = NetNet::REG; } + +net_type_or_var_opt + : net_type_opt { $$ = $1; } + | K_var { $$ = NetNet::REG; } + ; + /* The param_type rule is just the data_type_or_implicit rule wrapped with an assignment to para_data_type with the figured data type. This is used by parameter_assign, which is found to the right of @@ -7024,3 +7045,4 @@ unique_priority K_genvar_opt : K_genvar { $$ = true; } | { $$ = false; } ; K_static_opt : K_static { $$ = true; } | { $$ = false; } ; K_virtual_opt : K_virtual { $$ = true; } | { $$ = false; } ; +K_var_opt : K_var | ;