1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20// event_list.cpp -- test for
21//
22//  Original Author: John Aynsley, Doulos, Inc.
23//
24// MODIFICATION LOG - modifiers, enter your name, affiliation, date and
25//
26// $Log: event_list.cpp,v $
27// Revision 1.3  2011/09/05 21:23:30  acg
28//  Philipp A. Hartmann: eliminate compiler warnings.
29//
30// Revision 1.2  2011/05/08 19:18:46  acg
31//  Andy Goodrich: remove extraneous + prefixes from git diff.
32//
33
34// Event lists. A thread waits on a list of events built dynamically from a multiport
35
36#include <systemc>
37
38using namespace sc_core;
39using std::cout;
40using std::endl;
41
42struct Mod: sc_module
43{
44  sc_port<sc_signal_in_if<int>, 0> p; // Multiport
45
46  Mod(sc_module_name _name)
47  {
48    SC_THREAD(T1);
49    SC_THREAD(T2);
50  }
51
52  void T1()
53  {
54    for (;;)
55    {
56      wait(all_events());
57      cout << "M::T1 awoke with " << p[0]->read() << p[1]->read() << p[2]->read()
58           << " at " << sc_time_stamp() << " on list" << endl;
59    }
60  }
61  void T2()
62  {
63    for (;;)
64    {
65      wait( p[0]->default_event() | p[1]->default_event() );
66      cout << "M::T2 awoke with " << p[0]->read() << p[1]->read() << p[2]->read()
67           << " at " << sc_time_stamp() << " on list" << endl;
68    }
69  }
70  sc_event_or_list all_events() const
71  {
72    sc_assert( p.size() == 3 );
73
74    sc_event_or_list or_list;
75    for (int i = 0; i < p.size(); i++)
76      or_list |= p[i]->default_event();
77
78    sc_assert( or_list.size() == 3 );
79    return or_list;
80  }
81
82  SC_HAS_PROCESS(Mod);
83};
84
85struct Top: sc_module
86{
87  Top(sc_module_name _name)
88  : finished(false)
89  , count(0)
90  {
91    m = new Mod("m");
92    m->p.bind(sig1);
93    m->p.bind(sig2);
94    m->p.bind(sig3);
95    SC_THREAD(T);
96    SC_METHOD(M);
97  }
98
99  ~Top()
100  {
101    sc_assert( finished );
102    sc_assert( count == 4 );
103    sc_assert( sc_get_status() == SC_PAUSED );
104    sc_assert( sc_is_running() == true );
105    cout << "~T() called" << endl;
106  }
107
108  sc_signal<int> sig1, sig2, sig3;
109  Mod* m;
110
111  sc_event e1, e2, e3, e4;
112  bool finished;
113
114  void T()
115  {
116    sig1.write(0);
117    sig2.write(0);
118    sig3.write(0);
119
120    wait(10, SC_NS);
121    sig1.write(1);
122    wait(10, SC_NS);
123    sig1.write(2);
124
125    wait(10, SC_NS);
126    sig2.write(1);
127    wait(10, SC_NS);
128    sig2.write(2);
129
130    wait(10, SC_NS);
131    sig3.write(1);
132    wait(10, SC_NS);
133    sig3.write(2);
134
135    sc_time start;
136    start = sc_time_stamp();
137
138    e1.notify(10, SC_NS);
139    e2.notify(20, SC_NS);
140
141    sc_event_and_list list1 = e1 & e2;
142    sc_assert( list1.size() == 2 );
143
144    wait( list1 );
145    cout << "Awoke at " << sc_time_stamp() << endl;
146    sc_assert( sc_time_stamp() - start == sc_time(20, SC_NS) );
147
148    start = sc_time_stamp();
149    e1.notify(11, SC_NS);
150    e2.notify(21, SC_NS);
151
152    sc_event_and_list list2;
153    list2 &= e1;
154    list2 &= e2;
155    sc_assert( list2.size() == 2 );
156
157    wait( list2);
158    cout << "Awoke at " << sc_time_stamp() << endl;
159    sc_assert( sc_time_stamp() - start == sc_time(21, SC_NS) );
160
161    start = sc_time_stamp();
162    e1.notify(14, SC_NS);
163    e2.notify(24, SC_NS);
164
165    sc_event_and_list list3 = list2 & e2;
166    sc_assert( list3.size() == 2 );
167
168    wait( list3 );
169    cout << "Awoke at " << sc_time_stamp() << endl;
170    sc_assert( sc_time_stamp() - start == sc_time(24, SC_NS) );
171
172    start = sc_time_stamp();
173    e1.notify(100, SC_NS);
174    e2.notify(200, SC_NS);
175
176    sc_event_and_list list4;
177    list4 = list3 & e2;
178    sc_assert( list4.size() == 2 );
179    wait( list4 );
180    cout << "Awoke at " << sc_time_stamp() << endl;
181    sc_assert( sc_time_stamp() - start == sc_time(200, SC_NS) );
182
183    start = sc_time_stamp();
184    e1.notify(101, SC_NS);
185    e2.notify(202, SC_NS);
186
187    sc_event_and_list list5 = list3 & list4;
188    sc_assert( list5.size() == 2 );
189    wait( list5 );
190    cout << "Awoke at " << sc_time_stamp() << endl;
191    sc_assert( sc_time_stamp() - start == sc_time(202, SC_NS) );
192
193    sc_event_and_list list6 = e1;
194    sc_assert( list6.size() == 1 );
195
196    start = sc_time_stamp();
197    e1.notify(500, SC_NS);
198    wait(list6);
199    sc_assert( sc_time_stamp() - start == sc_time(500, SC_NS) );
200
201
202    start = sc_time_stamp();
203    e1.notify(1000, SC_NS);
204    wait(e1 | e2 | e3);
205    cout << "Awoke at " << sc_time_stamp() << endl;
206    sc_assert( sc_time_stamp() - start == sc_time(1000, SC_NS) );
207
208    start = sc_time_stamp();
209    e1.notify(1002, SC_NS);
210    e2.notify(1001, SC_NS);
211    e3.notify(1000, SC_NS);
212
213    wait(e1 & e2 & e3);
214    cout << "Awoke at " << sc_time_stamp() << endl;
215    sc_assert( sc_time_stamp() - start == sc_time(1002, SC_NS) );
216
217    start = sc_time_stamp();
218    e1.notify(2000, SC_NS);
219
220    sc_event_or_list list7;
221    list7 = e1 | e2;
222    list7 = list7 | e3;
223    list7 |= e4;
224    wait(list7);
225    cout << "Awoke at " << sc_time_stamp() << endl;
226    sc_assert( sc_time_stamp() - start == sc_time(2000, SC_NS) );
227
228    start = sc_time_stamp();
229    e1.notify(3000, SC_NS);
230    list7 = e2 | e3;
231    list7 = e1 | list7;
232    wait(list7);
233    cout << "Awoke at " << sc_time_stamp() << endl;
234    sc_assert( sc_time_stamp() - start == sc_time(3000, SC_NS) );
235
236    list1 = e1;
237    list2 = e2;
238    e1.notify(SC_ZERO_TIME);
239    wait(list1);
240    e2.notify(SC_ZERO_TIME);
241    wait(list2);
242
243    list1.swap(list2);
244
245    e1.notify(SC_ZERO_TIME);
246    wait(list2);
247    e2.notify(SC_ZERO_TIME);
248    wait(list1);
249
250    finished = true;
251  }
252
253  sc_event v1, v2, v3, v4;
254  sc_event_or_list  or_list1,  or_list2;
255  sc_event_and_list and_list1, and_list2;
256  int count;
257
258  void M()
259  {
260    switch (count)
261    {
262      case 0:
263      {
264        sc_assert( sc_time_stamp() == sc_time(0, SC_NS) );
265        or_list1 = v1 | v2;
266        or_list2 = v3 | v4;
267        v2.notify(10, SC_NS);
268        next_trigger(or_list1 | or_list2);
269        break;
270      }
271      case 1:
272      {
273        sc_assert( sc_time_stamp() == sc_time(10, SC_NS) );
274        and_list1 = v1 & v2;
275        and_list2 = v3 & v4;
276        v1.notify(1, SC_NS);
277        v2.notify(2, SC_NS);
278        v3.notify(3, SC_NS);
279        v4.notify(4, SC_NS);
280        next_trigger(and_list1 & and_list2);
281        break;
282      }
283      case 2:
284      {
285        sc_assert( sc_time_stamp() == sc_time(14, SC_NS) );
286        and_list1 = v1 & v2 & v2 & v1;
287        sc_assert( and_list1.size() == 2 );
288        v1.notify(1, SC_NS);
289        v2.notify(2, SC_NS);
290        next_trigger(and_list1);
291        break;
292      }
293      case 3:
294      {
295        sc_assert( sc_time_stamp() == sc_time(16, SC_NS) );
296        break;
297      }
298    }
299    ++count;
300  }
301
302  SC_HAS_PROCESS(Top);
303};
304
305int sc_main(int argc, char* argv[])
306{
307  Top top("top");
308
309  sc_start();
310
311  sc_assert( sc_get_status() == SC_PAUSED );
312  sc_assert( sc_is_running() );
313  sc_assert( sc_pending_activity() == false );
314
315  cout << endl << "Success" << endl;
316  return 0;
317}
318
319