File: t_event_control_expr.v

package info (click to toggle)
verilator 5.038-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 162,552 kB
  • sloc: cpp: 139,204; python: 20,931; ansic: 10,222; yacc: 6,000; lex: 1,925; makefile: 1,260; sh: 494; perl: 282; fortran: 22
file content (174 lines) | stat: -rw-r--r-- 5,206 bytes parent folder | download | duplicates (2)
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