1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2024 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
class cls;
rand int x;
endclass
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc;
initial cyc=1;
logic [63:32] cyc2;
always_comb cyc2 = cyc;
integer some_int;
integer other_int;
logic some_bool;
wire t1 = cyc[0];
wire t2 = cyc[1];
wire t3 = cyc[2];
wire t4 = cyc[3];
localparam bit ONE = 1'b1;
localparam bit ZERO = 1'b0;
function automatic bit invert(bit x);
return ~x;
endfunction
function automatic bit and_oper(bit a, bit b);
return a & b;
endfunction
localparam int num_intfs = 4;
intf the_intfs [num_intfs-1:0] ();
genvar intf_i;
for (intf_i = 0; intf_i < num_intfs; intf_i++) begin
always_comb the_intfs[intf_i].t = cyc[intf_i];
end
always @ (posedge clk) begin
cyc <= cyc + 1;
if ((~cyc[0] && cyc[1]) || (~cyc[2] && cyc[3])) $write("");
if ((~cyc2[32] && cyc2[33]) || (~cyc2[34] && cyc2[35])) $write("");
if ((~the_intfs[0].t && the_intfs[1].t) || (~the_intfs[2].t && the_intfs[3].t)) $write("");
if ((~t1 && t2) || (~t3 && t4)) $write("");
if (t3 && (t1 == t2)) $write("");
if (123 == (124 - 32'(t1 || t2))) $write("");
some_int <= (t2 || t3) ? 345 : 567;
some_bool <= t1 && t2;
if (t1 & t2) $write("");
if ((!t1 && t2) | (~t3 && t4)) $write("");
if (t1 ^ t2) $write("");
if (~(t1 & t2)) $write("");
if (t1 -> t2) $write("");
if (t1 <-> t2) $write("");
if (&cyc[2:0]) $write("");
if (&cyc[3:2]) $write("");
if (|cyc[2:0]) $write("");
if (^cyc[2:0]) $write("");
if (|cyc[2:0] || cyc[3]) $write("");
if (t1 & t2 & 1'b1) $write("");
if (t1 & t2 & 1'b0) $write("");
if (t1 & t2 & ONE) $write("");
if (t1 & t2 & ZERO) $write("");
if (t1 && t2) begin
$write("");
end else if (t1 || t2) begin
$write("");
end
if (invert(t1) && t2) $write("");
if (and_oper(t1, t2)) $write("");
if (t2 && t3) begin
if (t1 && t2) $write("");
end
if (0 == 1) begin
for (int loop_var = 0; loop_var < 1; loop_var++) begin
if (cyc[loop_var] && t2) $write("");
end
end
// stop at the first layer even if there's more to find
if ((cyc[3+32'(t1 && t2)+:2] == cyc[5+32'(t3 || t4)+:2]) || cyc[31]) $write("");
// impossible branches and redundant terms
if ((t1 && t2) && ~(t1 && t3) && (t1 || t4)) $write("");
if ((cyc[0] && cyc[1]) && ~(cyc[0] && cyc[2]) && (cyc[0] || cyc[3])) $write("");
// demonstrate current limitations of term matching scheme
if ((cyc[0] && cyc[1]) && ~(cyc[1-1] && cyc[2]) && (cyc[2-2] || cyc[3])) $write("");
//verilator coverage_off
if (t1 && t2) $write("");
//verilator coverage_on
if ((~t1 && t2)
||
(~t3 && t4)) $write("");
// intentionally testing wonkified expression terms
if (
cyc[
0
] &
cyc
[1]) $write("");
// for now each ternary condition is considered in isolation
other_int <= t1 ? t2 ? 1 : 2 : 3;
// no expression coverage for multi-bit expressions
if ((cyc[1:0] & cyc[3:2]) == 2'b11) $write("");
// truth table is too large
if (^cyc[6:0]) $write("");
// this one is too big even for t_cover_expr_max
if (^cyc) $write("");
if (cyc==9) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
always_comb begin
if (t1 && t2) $write("");
end
logic ta, tb, tc;
initial begin
cls obj = new;
cls null_obj = null;
int q[5];
int qv[$];
q = '{1, 2, 2, 4, 3};
// lambas not handled
// NB: there is a bug w/ tracing find_first (maybe lambdas in general?)
// tracing_off does not work around the bug
qv = q.find_first with (item[0] & item[1]);
ta = '1;
tb = '0;
tc = '0;
while (ta || tb || tc) begin
tc = tb;
tb = ta;
ta = '0;
end
if (!bit'(obj.randomize() with {x < 100;})) $write("");
if (null_obj != null && null_obj.x == 5) $write("");
end
sub the_sub_1 (.p(t1), .q(t2));
sub the_sub_2 (.p(t3), .q(t4));
// TODO -- non-process expressions
sub the_sub_3 (.p(t1 ? t2 : t3), .q(t4));
// TODO
// pragma for expr coverage off / on
// investigate cover point sorting in annotated source
// consider reporting don't care terms
//
// Branches which are statically impossible to reach are still reported.
// E.g.
// -000000 point: comment=(t1=1 && t2=1 && 1'h0=1) => 1 hier=top.t
// These could potentially be pruned, but they currently follow suit for
// what branch coverage does. Perhaps a switch should be added to not
// count statically impossible things.
endmodule
module sub (
input p,
input q
);
always_comb begin
if (p && q) $write("");
end
endmodule
interface intf();
logic t;
endinterface
|