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
|
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2022 by Antmicro Ltd.
// SPDX-License-Identifier: CC0-1.0
`ifdef TEST_VERBOSE
`define WRITE_VERBOSE(args) $write args
`else
`define WRITE_VERBOSE(args)
`endif
`define STRINGIFY(text) `"text`"
//========================================================================
// Various expression tests. The macro generates a module with the desired
// input and tested expression.
//
`define EXPR_TEST(name, test_edges, inputs, expr) \
module t_``name inputs; \
logic[$bits(expr)-1:0] last = 0; \
always @(expr) begin \
if ($bits(expr) > 1) begin \
`WRITE_VERBOSE(("[%0t] %s [changed] %s=%0x, last=%0x\n", $time, `STRINGIFY(name), `STRINGIFY(expr), expr, last)); \
end \
if ($time > 0 && (expr) == last) $stop; \
last <= expr; \
end \
generate if (test_edges) begin \
always @(posedge expr) begin \
`WRITE_VERBOSE(("[%0t] %s [posedge] %s=%0x, last=%0x\n", $time, `STRINGIFY(name), `STRINGIFY(expr), expr, last)); \
if ($time > 0 && ({1'b0, ~(expr)}[0] || last[0])) $stop; \
end \
always @(negedge expr) begin \
`WRITE_VERBOSE(("[%0t] %s [negedge] %s=%0x, last=%0x\n", $time, `STRINGIFY(name), `STRINGIFY(expr), expr, last)); \
if ($time > 0 && ({1'b0, expr}[0] || ~last[0])) $stop; \
end \
end endgenerate \
endmodule
`EXPR_TEST(xor, 1, (input a, b), b^a)
`EXPR_TEST(nand, 1, (input a, b, c), ~(c&b&a))
`EXPR_TEST(concat1, 1, (input a, b, c), {{a, b},c,a,{2{a,b,c}}})
`EXPR_TEST(reduce, 1, (input[3:0] v), v[0]^v[1]^v[2]^v[3])
`EXPR_TEST(concat2, 1, (input[3:0] v), {{v[0]|v[1]},v[1]|v[2],{4{v[2]|v[3]}}})
`EXPR_TEST(add, 0, (input int i, j), i+j)
`EXPR_TEST(lt, 1, (input int i, j), i<j)
`EXPR_TEST(array, 0, (input int t[5]), t[4])
`EXPR_TEST(array_complex, 0, (input int t[5], int cyc), t[cyc / 4])
`EXPR_TEST(queue, 0, (input int q[$]), q[0])
`EXPR_TEST(queue_mul, 0, (input int q[$], int i), q[0]*i)
`ifdef UNSUP
function int id(int x); return x; endfunction
`EXPR_TEST(func, 0, (input int cyc), id(cyc))
`endif
//========================================================================
// Class tests (special case as V3Width doesn't always properly handle
// out-of-module classes
//
`ifndef NO_CLASS
`define CLASS_TEST(name, expr) \
module t_``name(input int k); \
class Cls; \
int k; \
function int get_k(); return k; endfunction \
endclass \
Cls obj = new; \
assign obj.k = k; \
int last = 0; \
always @(expr) begin \
`WRITE_VERBOSE(("[%0t] %s [changed] %s=%0x, last=%0x\n", $time, `STRINGIFY(name), `STRINGIFY(expr), expr, last)); \
if ($time > 0 && expr == last) $stop; \
last <= expr; \
end \
endmodule
`CLASS_TEST(class, obj.k)
`ifdef UNSUP
`CLASS_TEST(method, obj.get_k())
`endif
`endif
//========================================================================
// $c test has to be written out explicitly as the STRINGIFY macro can't handle it
//
module t_cstmt;
logic last = 0;
always @($c("vlSelf->clk")) begin
if ($time > 0 && logic'($c("vlSelf->clk")) == last) $stop;
last <= logic'($c("vlSelf->clk"));
end
always @(posedge $c("vlSelf->clk")) begin
`WRITE_VERBOSE(("[%0t] cstmt [posedge] $c(\"vlSelf->clk\")=%0b, last=%b\n", $time, $c("vlSelf->clk"), last));
if ($time > 0 && (~logic'($c("vlSelf->clk")) || last)) $stop;
end
always @(negedge $c("vlSelf->clk")) begin
`WRITE_VERBOSE(("[%0t] cstmt [negedge] $c(\"vlSelf->clk\")=%0b, last=%b\n", $time, $c("vlSelf->clk"), last));
if ($time > 0 && (logic'($c("vlSelf->clk")) || !last)) $stop;
end
endmodule
module t(/*AUTOARG*/
// Inputs
clk
);
input clk;
logic a = 0, b = 0, c = 0;
t_xor u_xor(.*);
t_nand u_nand(.*);
t_concat1 u_concat1(.*);
logic[3:0] v = '0;
t_reduce u_reduce(.*);
t_concat2 u_concat2(.*);
int i = 0, j = 0;
t_add u_add(.*);
t_lt u_lt(.*);
int t[5] = {0, 1, 2, 3, 4};
t_array u_array(.*);
t_array_complex u_array_complex(.*);
int q[$];
t_queue u_queue(.*);
t_queue_mul u_queue_mul(.*);
`ifdef UNSUP
t_func u_func(.*);
`endif
int k;
assign k = i + j;
`ifndef NO_CLASS
t_class u_class(.*);
`ifdef UNSUP
t_method u_method(.*);
`endif
`endif
t_cstmt u_cstmt();
int cyc = 0;
always @(posedge clk) begin
cyc <= cyc + 1;
// a, b, c
a <= ~a;
if (cyc % 2 == 0) b <= ~b;
else c <= ~c;
// v
if (cyc % 3 == 0) v[0] <= 1;
else v <= v << 1;
// i, j
i <= i + 2;
if (cyc % 2 == 0) j <= j + 4;
// t
t[cyc % 5] <= t[cyc % 5] + cyc;
// q
q.push_front(cyc);
`WRITE_VERBOSE(("[%0t] values: clk=%b, cyc=%0d, a=%b, b=%b, v=%b, i=%0x, j=%0x, t=[%0x, %0x, %0x, %0x, %0x], obj.k=%0x\n",
$time, clk, cyc, a, b, v, i, j, t[0], t[1], t[2], t[3], t[4], k));
`WRITE_VERBOSE((" q=%p\n", q));
if (cyc == 20) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
|