diff --git a/ivtest/ivltests/br_gh979.v b/ivtest/ivltests/br_gh979.v new file mode 100644 index 000000000..117f022da --- /dev/null +++ b/ivtest/ivltests/br_gh979.v @@ -0,0 +1,73 @@ +module top; + reg passed; + wire wconst, wfconst, wfconstarg; + wire wdconst = 1'b0; + wire wdfconst = cfunc(); + wire wdfconstarg = func(1'b0); + real rfconst; + + function automatic reg cfunc(); + cfunc = 1'b0; + endfunction + + function automatic reg func(input reg val); + func = val; + endfunction + + function automatic real crfunc(); + crfunc = 2.0; + endfunction + + assign wconst = 1'b1; + assign wfconst = cfunc(); + assign wfconstarg = func(1'b1); + assign rfconst = crfunc(); + + initial begin + passed = 1'b1; + #1; + + if (wconst !== 1'b1) begin + $display("Expected wire constant value to be 1'b1, actual is %b", wconst); + passed = 1'b0; + end + + if (wdconst !== 1'b0) begin + $display("Expected wire decl constant value to be 1'b0, actual is %b", wdconst); + passed = 1'b0; + end + + if (wfconst !== 1'b0) begin + $display("Expected wire constant function value to be 1'b0, actual is %b", wfconst); + passed = 1'b0; + end + + if (wdfconst !== 1'b0) begin + $display("Expected wire decl constant function value to be 1'b0, actual is %b", wdfconst); + passed = 1'b0; + end + + if (rfconst != 2.0) begin + $display("Expected real constant function value to be 2.0, actual is %f", rfconst); + passed = 1'b0; + end + + if (wfconstarg !== 1'b1) begin + $display("Expected wire constant arg function value to be 1'b1, actual is %b", wfconstarg); + passed = 1'b0; + end + + if (wdfconstarg !== 1'b0) begin + $display("Expected wire decl constant arg function value to be 1'b0, actual is %b", wdfconstarg); + passed = 1'b0; + end + + if (cfunc() !== 1'b0) begin + $display("Expected constant function value to be 1'b0, actual is %b", cfunc()); + passed = 1'b0; + end + + if (passed) $display("PASSED"); + end + +endmodule diff --git a/ivtest/ivltests/sv_argumentless_func.v b/ivtest/ivltests/sv_argumentless_func.v index cd32b3299..9666e08ce 100644 --- a/ivtest/ivltests/sv_argumentless_func.v +++ b/ivtest/ivltests/sv_argumentless_func.v @@ -10,10 +10,10 @@ parameter test_parameter = test_func(); logic [7:0] test_alwayscomb; always_comb test_alwayscomb = test_func(); -// logic [7:0] test_assign; -// assign test_assign = test_func(); +logic [7:0] test_assign; +assign test_assign = test_func(); -// wire [7:0] test_wire = test_func(); +wire [7:0] test_wire = test_func(); logic [7:0] test_alwaysff; logic clk; @@ -37,15 +37,15 @@ initial begin $finish; end - // if (test_assign !== test_func()) begin - // $display("FAILED -- test_assign=%h, expect %h", test_assign, test_func()); - // $finish; - // end + if (test_assign !== test_func()) begin + $display("FAILED -- test_assign=%h, expect %h", test_assign, test_func()); + $finish; + end - // if (test_wire !== test_func()) begin - // $display("FAILED -- test_wire=%h, expect %h", test_wire, test_func()); - // $finish; - // end + if (test_wire !== test_func()) begin + $display("FAILED -- test_wire=%h, expect %h", test_wire, test_func()); + $finish; + end clk = 0; #1; @@ -57,7 +57,7 @@ initial begin end $display("PASSED"); - $finish; + $finish(0); end endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index e0f601791..297d7292e 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -994,6 +994,7 @@ br_gh823a CE,-g2012 ivltests br_gh823b CE,-g2012 ivltests br_gh840a CE,-g2012 ivltests br_gh840b CE,-g2012 ivltests +br_gh979 normal,-g2012 ivltests bitsel_real_idx CE,-g2012 ivltests gold=bitsel_real_idx.gold partsel_real_idx CE,-g2012 ivltests gold=partsel_real_idx.gold ipsdownsel_real_idx CE,-g2012 ivltests gold=ipsdownsel_real_idx.gold diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index 5e99f8524..c4a659958 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2022 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2023 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 @@ -2072,22 +2072,20 @@ static void draw_lpm_ufunc(ivl_lpm_t net) for (idx = 0 ; idx < ninp ; idx += 1) input_strings[idx] = draw_net_input(ivl_lpm_data(net, idx)); - if (ivl_lpm_trigger(net)) - fprintf(vvp_out, "L_%p%s .ufunc/e TD_%s, %u, E_%p", net, dly, - vvp_mangle_id(ivl_scope_name(def)), - ivl_lpm_width(net), ivl_lpm_trigger(net)); - else - fprintf(vvp_out, "L_%p%s .ufunc%s TD_%s, %u", net, dly, type_string, - vvp_mangle_id(ivl_scope_name(def)), - ivl_lpm_width(net)); - fprintf(vvp_out, ", "); + if (ivl_lpm_trigger(net)) { + assert(ninp > 0); + fprintf(vvp_out, "L_%p%s .ufunc/e TD_%s, %u, E_%p", net, dly, + vvp_mangle_id(ivl_scope_name(def)), + ivl_lpm_width(net), ivl_lpm_trigger(net)); + } else + fprintf(vvp_out, "L_%p%s .ufunc%s TD_%s, %u", net, dly, type_string, + vvp_mangle_id(ivl_scope_name(def)), + ivl_lpm_width(net)); /* Print all the net signals that connect to the input of the function. */ for (idx = 0 ; idx < ninp ; idx += 1) { - fprintf(vvp_out, "%s", input_strings[idx]); - if (idx != ninp-1) - fprintf(vvp_out, ", "); + fprintf(vvp_out, ", %s", input_strings[idx]); } free(input_strings); @@ -2107,8 +2105,10 @@ static void draw_lpm_ufunc(ivl_lpm_t net) fprintf(vvp_out, "v%p_0", psig); } - if (ninp > 0) - fprintf(vvp_out, ")"); + if (ninp == 0) + fprintf(vvp_out, ","); + else + fprintf(vvp_out, ")"); #if 0 /* Now print the reference to the signal from which the result is collected. */ diff --git a/vvp/parse.y b/vvp/parse.y index 1551e59bc..68466e2a5 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -1,7 +1,7 @@ %{ /* - * Copyright (c) 2001-2022 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2023 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 @@ -258,24 +258,19 @@ statement other thread code that is automatically invoked if any of the bits in the symbols list change. */ + | T_LABEL K_UFUNC_REAL T_SYMBOL ',' T_NUMBER ',' T_SYMBOL ';' + { compile_ufunc_real($1, $3, $5, 0, 0, 0, 0, $7, strdup("E_0x0")); } | T_LABEL K_UFUNC_REAL T_SYMBOL ',' T_NUMBER ',' symbols '(' symbols ')' T_SYMBOL ';' { compile_ufunc_real($1, $3, $5, $7.cnt, $7.vect, $9.cnt, $9.vect, $11, 0); } - | T_LABEL K_UFUNC_REAL T_SYMBOL ',' T_NUMBER ',' T_SYMBOL ';' - { compile_ufunc_real($1, $3, $5, 0, 0, 0, 0, $7, 0); } - + | T_LABEL K_UFUNC_VEC4 T_SYMBOL ',' T_NUMBER ',' T_SYMBOL ';' + { compile_ufunc_vec4($1, $3, $5, 0, 0, 0, 0, $7, strdup("E_0x0")); } | T_LABEL K_UFUNC_VEC4 T_SYMBOL ',' T_NUMBER ',' symbols '(' symbols ')' T_SYMBOL ';' { compile_ufunc_vec4($1, $3, $5, $7.cnt, $7.vect, $9.cnt, $9.vect, $11, 0); } - | T_LABEL K_UFUNC_VEC4 T_SYMBOL ',' T_NUMBER ',' T_SYMBOL ';' - { compile_ufunc_vec4($1, $3, $5, 0, 0, 0, 0, $7, 0); } - | T_LABEL K_UFUNC_E T_SYMBOL ',' T_NUMBER ',' T_SYMBOL ',' symbols '(' symbols ')' T_SYMBOL ';' { compile_ufunc_vec4($1, $3, $5, $9.cnt, $9.vect, $11.cnt, $11.vect, $13, $7); } - | T_LABEL K_UFUNC_E T_SYMBOL ',' T_NUMBER ',' T_SYMBOL ',' T_SYMBOL ';' - { compile_ufunc_vec4($1, $3, $5, 0, 0, 0, 0, $7, 0); } - /* Resolver statements are very much like functors. They are compiled to functors of a different mode. */