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
|
// DESCRIPTION: Verilator: Verilog Test for short-circuiting in generate "if"
//
// The given generate loops should only access valid bits of mask, since that
// is defined by SIZE. However since the loop range is larger, this only works
// if short-circuited evaluation of the generate loop is in place.
// This file ONLY is placed into the Public Domain, for any use, without
// warranty, 2012 by Jeremy Bennett.
// SPDX-License-Identifier: CC0-1.0
`define MAX_SIZE 4
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
// Set the parameters, so that we use a size less than MAX_SIZE
test_gen
#(.SIZE (2),
.MASK (2'b11))
i_test_gen (.clk (clk));
// This is only a compilation test, but for good measure we do one clock
// cycle.
integer count;
initial begin
count = 0;
end
always @(posedge clk) begin
if (count == 1) begin
$write("*-* All Finished *-*\n");
$finish;
end
else begin
count = count + 1;
end
end
endmodule // t
module test_gen
#( parameter
SIZE = `MAX_SIZE,
MASK = `MAX_SIZE'b0)
(/*AUTOARG*/
// Inputs
clk
);
input clk;
// Generate blocks that rely on short-circuiting of the logic to avoid errors.
generate
genvar g;
for (g = 0; g < `MAX_SIZE; g = g + 1) begin
if ((g < SIZE) && MASK[g]) begin
always @(posedge clk) begin
`ifdef TEST_VERBOSE
$write ("Logical AND generate if MASK [%1d] = %d\n", g, MASK[g]);
`endif
if (g >= SIZE) begin
$stop;
end
end
end
end
endgenerate
generate
for (g = 0; g < `MAX_SIZE; g = g + 1) begin
if (!((g >= SIZE) || ~MASK[g])) begin
always @(posedge clk) begin
`ifdef TEST_VERBOSE
$write ("Logical OR generate if MASK [%1d] = %d\n", g, MASK[g]);
`endif
if (g >= SIZE) begin
$stop;
end
end
end
end
endgenerate
generate
for (g = 0; g < `MAX_SIZE; g = g + 1) begin
if (!((g < SIZE) -> ~MASK[g])) begin
always @(posedge clk) begin
`ifdef TEST_VERBOSE
$write ("Logical infer generate if MASK [%1d] = %d\n", g, MASK[g]);
`endif
if (g >= SIZE) begin
$stop;
end
end
end
end
endgenerate
generate
for (g = 0; g < `MAX_SIZE; g = g + 1) begin
if ( g < SIZE ? MASK[g] : 1'b0) begin
always @(posedge clk) begin
`ifdef TEST_VERBOSE
$write ("Conditional generate if MASK [%1d] = %d\n", g, MASK[g]);
`endif
if (g >= SIZE) begin
$stop;
end
end
end
end
endgenerate
// The other way round
generate
for (g = 0; g < `MAX_SIZE; g = g + 1) begin
if ( g >= SIZE ? 1'b0 : MASK[g]) begin
always @(posedge clk) begin
`ifdef TEST_VERBOSE
$write ("Conditional generate if MASK [%1d] = %d\n", g, MASK[g]);
`endif
if (g >= SIZE) begin
$stop;
end
end
end
end
endgenerate
endmodule
|