File: t_event_copy.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 (142 lines) | stat: -rw-r--r-- 4,120 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
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2003 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0

`ifdef TEST_VERBOSE
 `define WRITE_VERBOSE(args) $write args
`else
 `define WRITE_VERBOSE(args)
`endif

module t(/*AUTOARG*/
   // Inputs
   clk
   );
   input clk;

   event e1;
   event e2;
   event e3;
   event e4;
`ifndef IVERILOG
   event ev [3:0];
`endif

   int   cyc;

   int last_event;
   always @(e1) begin
      `WRITE_VERBOSE(("[%0t] e1\n", $time));
`ifndef IVERILOG
      if (!e1.triggered) $stop;
`endif
      last_event[1] = 1;
   end

   always @(e2) begin
      `WRITE_VERBOSE(("[%0t] e2\n", $time));
      last_event[2] = 1;
   end

   always @(e3) begin
      `WRITE_VERBOSE(("[%0t] e3\n", $time));
      last_event[3] = 1;
   end

   always @(e4) begin
      `WRITE_VERBOSE(("[%0t] e4\n", $time));
      last_event[4] = 1;
   end

   always @(posedge clk) begin
      `WRITE_VERBOSE(("[%0t] cyc=%0d last_event=%5b\n", $time, cyc, last_event));
      cyc <= cyc + 1;
      if (cyc == 1) begin
         // Check no initial trigger
         if (last_event != 0) $stop;
      end
      //
      else if (cyc == 10) begin
         last_event = 0;
         -> e1;
      end
      else if (cyc == 12) begin
         if (last_event != 32'b10) $stop;
         last_event = 0;
      end
      else if (cyc == 13) begin
         // Check not still triggering
         if (last_event != 0) $stop;
         last_event = 0;
      end
      //
      else if (cyc == 20) begin
         last_event = 0;
`ifdef IVERILOG
         -> e2;
`else
         // Events are both references and events themselves.  I.e. 'event e'
         // declaration means 'event e = new'.  Then e is a reference to that
         // created event.
         //
         // Always having indirection is bad for performance, so Verilator
         // should have 'event e' as an "EVENTVALUE" stored as a char, or
         // ideally a one bit field reference (not vector as that can't be
         // V3Ordered).
         //
         // Then events once copied become EVENTREFs, much like a ClassRef which
         // points to an EVENTVALUE.  Thus a Verilog "event" starts as an
         // EVENTVALUE, and if an assignment is made it becomes an EVENTVALUE
         // and an EVENTREF initing to that EVENTVALUE.
         //
         // All static scheduling for events would go out the window once an
         // event can be pointed to by an EVENTREF, as basically any EVENTREF
         // activation could be activating any event.  A graph algorithm could
         // determine what events/eventrefs are associated and only
         // pessamistically schedule those events (users of EVENTVALUES) that
         // are ever pointed to by an EVENTREF.
         e4 = e3;  // Old handle to e4
         e3 = e2;  // Same event, also triggers e2
         // IEEE 1800-2023 15.5.5.1 says that this causes a merge, and the below
         // should also activate the "old e3".  However we could not find any
         // simulator that actually does this.  Instead the "old e3" becomes
         // unreachable (via old handle), but is reachable by "e4" as assigned
         // earlier.
         ->> e3;  // Delayed
`endif
      end
      else if (cyc == 22) begin
         if (last_event != 32'b100) $stop;
         last_event = 0;
         -> e2;  // IEEE says triggers e3, but does not
      end
      else if (cyc == 24) begin
         if (last_event != 32'b100) $stop;
         last_event = 0;
         -> e4;  // Triggers old e3
      end
      else if (cyc == 26) begin
         if (last_event != 32'b1000) $stop;
         last_event = 0;
      end
      //
      else if (cyc == 30) begin
         last_event = 0;
`ifndef IVERILOG
         e3 = null;
         -> e3;  // Triggers nothing
`endif
      end
      else if (cyc == 32) begin
         if (last_event != 0) $stop;
         last_event = 0;
      end
      else if (cyc == 99) begin
         $write("*-* All Finished *-*\n");
         $finish;
      end
   end

endmodule