diff --git a/test_regress/t/t_cover_toggle_option.out b/test_regress/t/t_cover_toggle_option.out new file mode 100644 index 000000000..d68a87d6d --- /dev/null +++ b/test_regress/t/t_cover_toggle_option.out @@ -0,0 +1,211 @@ +// // verilator_coverage annotation + // DESCRIPTION: Verilator: Verilog Test module + // + // This file ONLY is placed under the Creative Commons Public Domain, for + // any use, without warranty, 2008 by Wilson Snyder. + // SPDX-License-Identifier: CC0-1.0 + + module t (/*AUTOARG*/ + // Inputs + clk, check_real, check_array_real, check_string + ); + + 000019 input clk; + input real check_real; // Check issue #2741 + input real check_array_real [1:0]; + input string check_string; // Check issue #2766 + + typedef struct packed { + union packed { + logic ua; + logic ub; + } u; + logic b; + } str_t; + +%000002 reg toggle; initial toggle='0; + +%000002 str_t stoggle; initial stoggle='0; + + union { + real val1; // TODO use bit [7:0] here + real val2; // TODO use bit [3:0] here + } utoggle; + + const reg aconst = '0; + +%000002 reg [1:0][1:0] ptoggle; initial ptoggle=0; + + integer cyc; initial cyc=1; +~000011 wire [7:0] cyc_copy = cyc[7:0]; +%000002 wire toggle_up; + + typedef struct { + int q[$]; + } str_queue_t; + str_queue_t str_queue; + + alpha a1 (/*AUTOINST*/ + // Outputs + .toggle_up (toggle_up), + // Inputs + .clk (clk), + .toggle (toggle), + .cyc_copy (cyc_copy[7:0])); + alpha a2 (/*AUTOINST*/ + // Outputs + .toggle_up (toggle_up), + // Inputs + .clk (clk), + .toggle (toggle), + .cyc_copy (cyc_copy[7:0])); + + beta b1 (/*AUTOINST*/ + // Inputs + .clk (clk), + .toggle_up (toggle_up)); + + off o1 (/*AUTOINST*/ + // Inputs + .clk (clk), + .toggle (toggle)); + + param#(1) p1 (/*AUTOINST*/ + // Inputs + .clk (clk), + .toggle (toggle)); + + param#() p2 (/*AUTOINST*/ + // Inputs + .clk (clk), + .toggle (toggle)); + +%000001 reg [1:0] memory[121:110]; + + wire [1023:0] largeish = {992'h0, cyc}; + // CHECK_COVER_MISSING(-1) + + always @ (posedge clk) begin + if (cyc != 0) begin + cyc <= cyc + 1; + memory[cyc + 'd100] <= memory[cyc + 'd100] + 2'b1; + toggle <= '0; + stoggle.u <= toggle; + stoggle.b <= toggle; + utoggle.val1 <= real'(cyc[7:0]); + ptoggle[0][0] <= toggle; + if (cyc == 3) begin + str_queue.q.push_back(1); + toggle <= '1; + end + if (cyc == 4) begin + if (str_queue.q.size() != 1) $stop; + toggle <= '0; + end + else if (cyc == 10) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + end + + endmodule + + module alpha (/*AUTOARG*/ + // Outputs + toggle_up, + // Inputs + clk, toggle, cyc_copy + ); + + // t.a1 and t.a2 collapse to a count of 2 + + 000038 input clk; + +%000004 input toggle; + // CHECK_COVER(-1,"top.t.a*",4) + // 2 edges * (t.a1 and t.a2) + +~000022 input [7:0] cyc_copy; + // CHECK_COVER(-1,"top.t.a*","cyc_copy[0]",22) + // CHECK_COVER(-2,"top.t.a*","cyc_copy[1]",10) + // CHECK_COVER(-3,"top.t.a*","cyc_copy[2]",4) + // CHECK_COVER(-4,"top.t.a*","cyc_copy[3]",2) + // CHECK_COVER(-5,"top.t.a*","cyc_copy[4]",0) + // CHECK_COVER(-6,"top.t.a*","cyc_copy[5]",0) + // CHECK_COVER(-7,"top.t.a*","cyc_copy[6]",0) + // CHECK_COVER(-8,"top.t.a*","cyc_copy[7]",0) + +%000004 reg toggle_internal; + // CHECK_COVER(-1,"top.t.a*",4) + // 2 edges * (t.a1 and t.a2) + +%000004 output reg toggle_up; + // CHECK_COVER(-1,"top.t.a*",4) + // 2 edges * (t.a1 and t.a2) + + always @ (posedge clk) begin + toggle_internal <= toggle; + toggle_up <= toggle; + end + endmodule + + module beta (/*AUTOARG*/ + // Inputs + clk, toggle_up + ); + + 000019 input clk; + +%000002 input toggle_up; + // CHECK_COVER(-1,"top.t.b1","toggle_up",2) + + /* verilator public_module */ + + always @ (posedge clk) begin + if (0 && toggle_up) begin end + end + endmodule + + module off (/*AUTOARG*/ + // Inputs + clk, toggle + ); + + // verilator coverage_off + input clk; + // CHECK_COVER_MISSING(-1) + + // verilator coverage_on +%000002 input toggle; + // CHECK_COVER(-1,"top.t.o1","toggle",2) + + endmodule + + module param #(parameter P = 2) (/*AUTOARG*/ + // Inputs + clk, toggle + ); + + 000019 input clk; +%000002 input toggle; + +%000001 logic z; + + for (genvar i = 0; i < P; i++) begin +%000002 logic x; + always @ (posedge clk) begin + x <= toggle; + end + for (genvar j = 0; j < 3; j++) begin +%000003 logic [2:0] y; + always @ (negedge clk) begin + y <= {toggle, ~toggle, 1'b1}; + end + end + end + if (P > 1) begin : gen_1 + assign z = 1; + end + endmodule + diff --git a/test_regress/t/t_cover_toggle_option.py b/test_regress/t/t_cover_toggle_option.py new file mode 100755 index 000000000..589c46fdb --- /dev/null +++ b/test_regress/t/t_cover_toggle_option.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.top_filename = "t/t_cover_toggle.v" + +test.compile(verilator_flags2=['--cc --coverage --stats']) + +test.execute() + +# Read the input .v file and do any CHECK_COVER requests +test.inline_checks() + +test.file_grep_not(test.obj_dir + "/coverage.dat", "largeish") + +if test.vlt_all: + test.file_grep(test.stats, r'Coverage, Toggle points joined\s+(\d+)', 27) + +test.run(cmd=[ + os.environ["VERILATOR_ROOT"] + "/bin/verilator_coverage", + "--annotate", + test.obj_dir + "/annotated", + test.obj_dir + "/coverage.dat", + "--filter-type toggle", +], + verilator_run=True) + +test.files_identical(test.obj_dir + "/annotated/t_cover_toggle.v", test.golden_filename) + +test.run(cmd=[ + os.environ["VERILATOR_ROOT"] + "/bin/verilator_coverage", + "--annotate-points", + "--annotate", + test.obj_dir + "/annotated-points", + test.obj_dir + "/coverage.dat", + "--filter-type toggle", +], + verilator_run=True) + +test.files_identical(test.obj_dir + "/annotated-points/t_cover_toggle.v", + "t/" + test.name + "__points.out") + +test.passes() diff --git a/test_regress/t/t_cover_toggle_option__points.out b/test_regress/t/t_cover_toggle_option__points.out new file mode 100644 index 000000000..f73846a2f --- /dev/null +++ b/test_regress/t/t_cover_toggle_option__points.out @@ -0,0 +1,303 @@ +// // verilator_coverage annotation + // DESCRIPTION: Verilator: Verilog Test module + // + // This file ONLY is placed under the Creative Commons Public Domain, for + // any use, without warranty, 2008 by Wilson Snyder. + // SPDX-License-Identifier: CC0-1.0 + + module t (/*AUTOARG*/ + // Inputs + clk, check_real, check_array_real, check_string + ); + + 000019 input clk; ++000019 point: comment=clk hier=top.t + input real check_real; // Check issue #2741 + input real check_array_real [1:0]; + input string check_string; // Check issue #2766 + + typedef struct packed { + union packed { + logic ua; + logic ub; + } u; + logic b; + } str_t; + +%000002 reg toggle; initial toggle='0; +-000002 point: comment=toggle hier=top.t + +%000002 str_t stoggle; initial stoggle='0; +-000002 point: comment=stoggle.b hier=top.t +-000002 point: comment=stoggle.u.ua hier=top.t + + union { + real val1; // TODO use bit [7:0] here + real val2; // TODO use bit [3:0] here + } utoggle; + + const reg aconst = '0; + +%000002 reg [1:0][1:0] ptoggle; initial ptoggle=0; +-000002 point: comment=ptoggle[0][0] hier=top.t +-000000 point: comment=ptoggle[0][1] hier=top.t +-000000 point: comment=ptoggle[1][0] hier=top.t +-000000 point: comment=ptoggle[1][1] hier=top.t + + integer cyc; initial cyc=1; +~000011 wire [7:0] cyc_copy = cyc[7:0]; ++000011 point: comment=cyc_copy[0] hier=top.t +-000005 point: comment=cyc_copy[1] hier=top.t +-000002 point: comment=cyc_copy[2] hier=top.t +-000001 point: comment=cyc_copy[3] hier=top.t +-000000 point: comment=cyc_copy[4] hier=top.t +-000000 point: comment=cyc_copy[5] hier=top.t +-000000 point: comment=cyc_copy[6] hier=top.t +-000000 point: comment=cyc_copy[7] hier=top.t +%000002 wire toggle_up; +-000002 point: comment=toggle_up hier=top.t + + typedef struct { + int q[$]; + } str_queue_t; + str_queue_t str_queue; + + alpha a1 (/*AUTOINST*/ + // Outputs + .toggle_up (toggle_up), + // Inputs + .clk (clk), + .toggle (toggle), + .cyc_copy (cyc_copy[7:0])); + alpha a2 (/*AUTOINST*/ + // Outputs + .toggle_up (toggle_up), + // Inputs + .clk (clk), + .toggle (toggle), + .cyc_copy (cyc_copy[7:0])); + + beta b1 (/*AUTOINST*/ + // Inputs + .clk (clk), + .toggle_up (toggle_up)); + + off o1 (/*AUTOINST*/ + // Inputs + .clk (clk), + .toggle (toggle)); + + param#(1) p1 (/*AUTOINST*/ + // Inputs + .clk (clk), + .toggle (toggle)); + + param#() p2 (/*AUTOINST*/ + // Inputs + .clk (clk), + .toggle (toggle)); + +%000001 reg [1:0] memory[121:110]; +-000001 point: comment=memory[110][0] hier=top.t +-000000 point: comment=memory[110][1] hier=top.t +-000000 point: comment=memory[111][0] hier=top.t +-000000 point: comment=memory[111][1] hier=top.t +-000000 point: comment=memory[112][0] hier=top.t +-000000 point: comment=memory[112][1] hier=top.t +-000000 point: comment=memory[113][0] hier=top.t +-000000 point: comment=memory[113][1] hier=top.t +-000000 point: comment=memory[114][0] hier=top.t +-000000 point: comment=memory[114][1] hier=top.t +-000000 point: comment=memory[115][0] hier=top.t +-000000 point: comment=memory[115][1] hier=top.t +-000000 point: comment=memory[116][0] hier=top.t +-000000 point: comment=memory[116][1] hier=top.t +-000000 point: comment=memory[117][0] hier=top.t +-000000 point: comment=memory[117][1] hier=top.t +-000000 point: comment=memory[118][0] hier=top.t +-000000 point: comment=memory[118][1] hier=top.t +-000000 point: comment=memory[119][0] hier=top.t +-000000 point: comment=memory[119][1] hier=top.t +-000000 point: comment=memory[120][0] hier=top.t +-000000 point: comment=memory[120][1] hier=top.t +-000000 point: comment=memory[121][0] hier=top.t +-000000 point: comment=memory[121][1] hier=top.t + + wire [1023:0] largeish = {992'h0, cyc}; + // CHECK_COVER_MISSING(-1) + + always @ (posedge clk) begin + if (cyc != 0) begin + cyc <= cyc + 1; + memory[cyc + 'd100] <= memory[cyc + 'd100] + 2'b1; + toggle <= '0; + stoggle.u <= toggle; + stoggle.b <= toggle; + utoggle.val1 <= real'(cyc[7:0]); + ptoggle[0][0] <= toggle; + if (cyc == 3) begin + str_queue.q.push_back(1); + toggle <= '1; + end + if (cyc == 4) begin + if (str_queue.q.size() != 1) $stop; + toggle <= '0; + end + else if (cyc == 10) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + end + + endmodule + + module alpha (/*AUTOARG*/ + // Outputs + toggle_up, + // Inputs + clk, toggle, cyc_copy + ); + + // t.a1 and t.a2 collapse to a count of 2 + + 000038 input clk; ++000038 point: comment=clk hier=top.t.a* + +%000004 input toggle; +-000004 point: comment=toggle hier=top.t.a* + // CHECK_COVER(-1,"top.t.a*",4) + // 2 edges * (t.a1 and t.a2) + +~000022 input [7:0] cyc_copy; ++000022 point: comment=cyc_copy[0] hier=top.t.a* ++000010 point: comment=cyc_copy[1] hier=top.t.a* +-000004 point: comment=cyc_copy[2] hier=top.t.a* +-000002 point: comment=cyc_copy[3] hier=top.t.a* +-000000 point: comment=cyc_copy[4] hier=top.t.a* +-000000 point: comment=cyc_copy[5] hier=top.t.a* +-000000 point: comment=cyc_copy[6] hier=top.t.a* +-000000 point: comment=cyc_copy[7] hier=top.t.a* + // CHECK_COVER(-1,"top.t.a*","cyc_copy[0]",22) + // CHECK_COVER(-2,"top.t.a*","cyc_copy[1]",10) + // CHECK_COVER(-3,"top.t.a*","cyc_copy[2]",4) + // CHECK_COVER(-4,"top.t.a*","cyc_copy[3]",2) + // CHECK_COVER(-5,"top.t.a*","cyc_copy[4]",0) + // CHECK_COVER(-6,"top.t.a*","cyc_copy[5]",0) + // CHECK_COVER(-7,"top.t.a*","cyc_copy[6]",0) + // CHECK_COVER(-8,"top.t.a*","cyc_copy[7]",0) + +%000004 reg toggle_internal; +-000004 point: comment=toggle_internal hier=top.t.a* + // CHECK_COVER(-1,"top.t.a*",4) + // 2 edges * (t.a1 and t.a2) + +%000004 output reg toggle_up; +-000004 point: comment=toggle_up hier=top.t.a* + // CHECK_COVER(-1,"top.t.a*",4) + // 2 edges * (t.a1 and t.a2) + + always @ (posedge clk) begin + toggle_internal <= toggle; + toggle_up <= toggle; + end + endmodule + + module beta (/*AUTOARG*/ + // Inputs + clk, toggle_up + ); + + 000019 input clk; ++000019 point: comment=clk hier=top.t.b1 + +%000002 input toggle_up; +-000002 point: comment=toggle_up hier=top.t.b1 + // CHECK_COVER(-1,"top.t.b1","toggle_up",2) + + /* verilator public_module */ + + always @ (posedge clk) begin + if (0 && toggle_up) begin end + end + endmodule + + module off (/*AUTOARG*/ + // Inputs + clk, toggle + ); + + // verilator coverage_off + input clk; + // CHECK_COVER_MISSING(-1) + + // verilator coverage_on +%000002 input toggle; +-000002 point: comment=toggle hier=top.t.o1 + // CHECK_COVER(-1,"top.t.o1","toggle",2) + + endmodule + + module param #(parameter P = 2) (/*AUTOARG*/ + // Inputs + clk, toggle + ); + + 000019 input clk; ++000019 point: comment=clk hier=top.t.p2 ++000019 point: comment=clk hier=top.t.p1 +%000002 input toggle; +-000002 point: comment=toggle hier=top.t.p2 +-000002 point: comment=toggle hier=top.t.p1 + +%000001 logic z; +-000001 point: comment=z hier=top.t.p2 +-000000 point: comment=z hier=top.t.p1 + + for (genvar i = 0; i < P; i++) begin +%000002 logic x; +-000002 point: comment=genblk1[0].x hier=top.t.p2 +-000002 point: comment=genblk1[1].x hier=top.t.p2 +-000002 point: comment=genblk1[0].x hier=top.t.p1 + always @ (posedge clk) begin + x <= toggle; + end + for (genvar j = 0; j < 3; j++) begin +%000003 logic [2:0] y; +-000001 point: comment=genblk1[0].genblk1[0].y[0] hier=top.t.p2 +-000003 point: comment=genblk1[0].genblk1[0].y[1] hier=top.t.p2 +-000002 point: comment=genblk1[0].genblk1[0].y[2] hier=top.t.p2 +-000001 point: comment=genblk1[0].genblk1[1].y[0] hier=top.t.p2 +-000003 point: comment=genblk1[0].genblk1[1].y[1] hier=top.t.p2 +-000002 point: comment=genblk1[0].genblk1[1].y[2] hier=top.t.p2 +-000001 point: comment=genblk1[0].genblk1[2].y[0] hier=top.t.p2 +-000003 point: comment=genblk1[0].genblk1[2].y[1] hier=top.t.p2 +-000002 point: comment=genblk1[0].genblk1[2].y[2] hier=top.t.p2 +-000001 point: comment=genblk1[1].genblk1[0].y[0] hier=top.t.p2 +-000003 point: comment=genblk1[1].genblk1[0].y[1] hier=top.t.p2 +-000002 point: comment=genblk1[1].genblk1[0].y[2] hier=top.t.p2 +-000001 point: comment=genblk1[1].genblk1[1].y[0] hier=top.t.p2 +-000003 point: comment=genblk1[1].genblk1[1].y[1] hier=top.t.p2 +-000002 point: comment=genblk1[1].genblk1[1].y[2] hier=top.t.p2 +-000001 point: comment=genblk1[1].genblk1[2].y[0] hier=top.t.p2 +-000003 point: comment=genblk1[1].genblk1[2].y[1] hier=top.t.p2 +-000002 point: comment=genblk1[1].genblk1[2].y[2] hier=top.t.p2 +-000001 point: comment=genblk1[0].genblk1[0].y[0] hier=top.t.p1 +-000003 point: comment=genblk1[0].genblk1[0].y[1] hier=top.t.p1 +-000002 point: comment=genblk1[0].genblk1[0].y[2] hier=top.t.p1 +-000001 point: comment=genblk1[0].genblk1[1].y[0] hier=top.t.p1 +-000003 point: comment=genblk1[0].genblk1[1].y[1] hier=top.t.p1 +-000002 point: comment=genblk1[0].genblk1[1].y[2] hier=top.t.p1 +-000001 point: comment=genblk1[0].genblk1[2].y[0] hier=top.t.p1 +-000003 point: comment=genblk1[0].genblk1[2].y[1] hier=top.t.p1 +-000002 point: comment=genblk1[0].genblk1[2].y[2] hier=top.t.p1 + always @ (negedge clk) begin + y <= {toggle, ~toggle, 1'b1}; + end + end + end + if (P > 1) begin : gen_1 + assign z = 1; + end + endmodule +