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// proc_ctrl_timeout.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: proc_ctrl_timeout.cpp,v $
27// Revision 1.2  2011/05/08 19:18:46  acg
28//  Andy Goodrich: remove extraneous + prefixes from git diff.
29//
30
31// Process control methods interacting with time-out and event lists
32
33#define SC_INCLUDE_DYNAMIC_PROCESSES
34
35#include <systemc>
36
37using namespace sc_core;
38using std::cout;
39using std::endl;
40
41struct Top: sc_module
42{
43  Top(sc_module_name _name)
44  {
45    SC_THREAD(calling);
46
47    SC_THREAD(target1);
48      t1 = sc_get_current_process_handle();
49
50    SC_METHOD(target2);
51      t2 = sc_get_current_process_handle();
52
53    SC_THREAD(target3);
54      t3 = sc_get_current_process_handle();
55
56    SC_METHOD(target4);
57      t4 = sc_get_current_process_handle();
58
59    SC_METHOD(target5);
60      t5 = sc_get_current_process_handle();
61      t5.disable();
62      sensitive << ev4;
63
64    count = 0;
65    f1 = f2 = f3 = f4 = f5 = f6 = f7 = f8 = f9 = f10 = 0;
66    f11 = f12 = f13 = f14 = f15 = f16 = f17 = f18 = f19 = 0;
67    f20 = f21 = f22 = 0;
68  }
69
70  sc_process_handle t1, t2, t3, t4, t5;
71  sc_event ev1, ev2, ev3, ev4;
72  int count;
73  int f1, f2, f3, f4, f5, f6, f7, f8, f9, f10;
74  int f11, f12, f13, f14, f15, f16, f17, f18, f19;
75  int f20, f21, f22;
76
77  void calling()
78  {
79    wait(SC_ZERO_TIME);
80    count = 1;
81    wait(15, SC_NS);
82
83    count = 2;
84    try {
85      t1.disable();
86      sc_assert(false);
87    }
88    catch (sc_exception ex) {
89      //cout << "Exception caught at " << sc_time_stamp() << endl;
90      f7 = 1;
91    }
92
93    try {
94      t2.disable();
95      sc_assert(false);
96    }
97    catch (sc_exception ex) {
98      //cout << "Exception caught at " << sc_time_stamp() << endl;
99      f8 = 1;
100    }
101    wait(SC_ZERO_TIME);
102    t1.kill();
103    t2.kill();
104    ev1.notify();
105    wait(sc_time(100, SC_NS) - sc_time_stamp());
106
107    count = 6;
108    t3.disable();
109    t4.disable();
110    wait(10, SC_NS);
111
112    ev2.notify();
113    wait(10, SC_NS);
114
115    t3.enable();
116    t4.enable();
117    wait(10, SC_NS);
118
119    ev3.notify();
120    wait(10, SC_NS);
121
122    ev2.notify();
123    wait(sc_time(200, SC_NS) - sc_time_stamp());
124
125    count = 7;
126    ev1.notify();
127    wait(10, SC_NS);
128
129    t3.suspend();
130    t4.suspend();
131    wait(10, SC_NS);
132
133    ev2.notify();
134    wait(10, SC_NS);
135
136    t3.resume();
137    t4.resume();
138    wait(10, SC_NS);
139
140    ev3.notify();
141    wait(sc_time(300, SC_NS) - sc_time_stamp());
142
143    count = 8;
144    ev1.notify();
145    wait(10, SC_NS);
146
147    ev2.notify();
148    wait(10, SC_NS);
149
150    t3.reset();
151    count = 9;
152    wait(10, SC_NS);
153
154    ev3.notify();
155    wait(10, SC_NS);
156
157    ev1.notify();
158    wait(10, SC_NS);
159
160    ev2.notify();
161    wait(sc_time(400, SC_NS) - sc_time_stamp());
162    t3.disable();
163    t4.disable();
164
165    // Now target5
166    count = 9;
167    t5.enable();
168    ev4.notify();
169    wait(SC_ZERO_TIME);
170
171    count = 10;
172    ev3.notify(3, SC_NS);
173    ev2.notify(2, SC_NS);
174    ev1.notify(1, SC_NS);
175    wait(10, SC_NS);
176
177    count = 11;
178    t5.reset(); // On reset, dynamic sensit is cleared, then target is called again
179    wait(SC_ZERO_TIME);
180
181    count = 12;
182    ev3.notify(3, SC_NS);
183    ev2.notify(2, SC_NS);
184    ev1.notify(1, SC_NS);
185    wait(10, SC_NS);
186
187    count = 13;
188    ev4.notify();
189    wait(SC_ZERO_TIME);
190
191    count = 14;
192    try {
193      t5.disable();  // Disabling a process waiting on a time-out
194    }
195    catch (sc_exception ex) {
196      //cout << "Exception caught at " << sc_time_stamp() << endl;
197      f21 = 1;
198    }
199    wait(sc_time(500, SC_NS) - sc_time_stamp());
200
201    count = 15;
202    t5.reset();
203    wait(10, SC_NS);
204
205    count = 16;
206    ev4.notify();
207    wait(10, SC_NS);
208
209    sc_stop();
210  }
211
212  void target1()
213  {
214    //cout << "target1() called at " << sc_time_stamp() << " count = " << count << endl;
215    switch (count)
216    {
217        case  0: sc_assert( sc_time_stamp() == sc_time(0, SC_NS) ); f1=1; break;
218        default: sc_assert( false ); break;
219    }
220
221    for (;;)
222    {
223      wait(10, SC_NS);
224      //cout << "target1() awoke at " << sc_time_stamp() << " count = " << count << endl;
225      switch (count)
226      {
227        case  1: sc_assert( sc_time_stamp() == sc_time(10, SC_NS) ); f5=1; break;
228        default: sc_assert( false ); break;
229      }
230    }
231  }
232
233  void target2()
234  {
235    //cout << "target2() called at " << sc_time_stamp() << " count = " << count << endl;
236    switch (count)
237    {
238        case  0: sc_assert( sc_time_stamp() == sc_time(0, SC_NS) ); f2=1; break;
239        case  1: sc_assert( sc_time_stamp() == sc_time(10, SC_NS) ); f6=1; break;
240        default: sc_assert( false ); break;
241    }
242    next_trigger(10, SC_NS);
243  }
244
245  void target3()
246  {
247    //cout << "target3() called at " << sc_time_stamp() << " count = " << count << endl;
248    switch (count)
249    {
250        case  0: sc_assert( sc_time_stamp() == sc_time(0, SC_NS) ); f3=1; break;
251        case  8: sc_assert( sc_time_stamp() == sc_time(320, SC_NS) ); f13=1; break;
252        default: sc_assert( false ); break;
253    }
254
255    for (;;)
256    {
257      wait(ev1 & ev2 & ev3);
258      //cout << "target3() awoke at " << sc_time_stamp() << " count = " << count << endl;
259      switch (count)
260      {
261        case  6: sc_assert( sc_time_stamp() == sc_time(140, SC_NS) ); f9=1; break;
262        case  7: sc_assert( sc_time_stamp() == sc_time(240, SC_NS) ); f11=1; break;
263        case  9: sc_assert( sc_time_stamp() == sc_time(350, SC_NS) ); f15=1; break;
264        default: sc_assert( false ); break;
265      }
266    }
267  }
268
269  void target4()
270  {
271    //cout << "target4() called at " << sc_time_stamp() << " count = " << count << endl;
272    switch (count)
273    {
274        case  0: sc_assert( sc_time_stamp() == sc_time(0, SC_NS) ); f4=1; break;
275        case  6: sc_assert( sc_time_stamp() == sc_time(140, SC_NS) ); f10=1; break;
276        case  7: sc_assert( sc_time_stamp() == sc_time(240, SC_NS) ); f12=1; break;
277        case  9: sc_assert( sc_time_stamp() == sc_time(330, SC_NS) ); f14=1; break;
278        default: sc_assert( false ); break;
279    }
280    next_trigger(ev1 & ev2 & ev3);
281  }
282
283  void target5()
284  {
285    //cout << "target5() called at " << sc_time_stamp() << " count = " << count << endl;
286    switch (count)
287    {
288        case  9: sc_assert( sc_time_stamp() == sc_time(400, SC_NS) ); f16=1; break;
289        case 10: sc_assert( sc_time_stamp() == sc_time(403, SC_NS) ); f17=1; break;
290        case 11: sc_assert( sc_time_stamp() == sc_time(410, SC_NS) ); f18=1; break;
291        case 12: sc_assert( sc_time_stamp() == sc_time(413, SC_NS) ); f19=1; break;
292        case 14: sc_assert( sc_time_stamp() == sc_time(424, SC_NS) );        break;
293        case 15: sc_assert( sc_time_stamp() == sc_time(500, SC_NS) ); f20=1; break;
294        case 16: sc_assert( sc_time_stamp() == sc_time(510, SC_NS) ); f22=1; break;
295        default: sc_assert( false ); break;
296    }
297    if (count < 12)
298      next_trigger(ev1 & ev2 & ev3);
299    else if (count == 12)
300      next_trigger(11, SC_NS, ev3);
301    else if (count > 12)
302      next_trigger();
303  }
304
305  SC_HAS_PROCESS(Top);
306};
307
308int sc_main(int argc, char* argv[])
309{
310  Top top("top");
311
312  sc_start();
313
314  sc_assert( top.f1 );
315  sc_assert( top.f2 );
316  sc_assert( top.f3 );
317  sc_assert( top.f4 );
318  sc_assert( top.f5 );
319  sc_assert( top.f6 );
320  sc_assert( top.f7 );
321  sc_assert( top.f8 );
322  sc_assert( top.f9 );
323  sc_assert( top.f10 );
324  sc_assert( top.f11 );
325  sc_assert( top.f12 );
326  sc_assert( top.f13 );
327  sc_assert( top.f14 );
328  sc_assert( top.f15 );
329  sc_assert( top.f16 );
330  sc_assert( top.f17 );
331  sc_assert( top.f18 );
332  sc_assert( top.f19 );
333  sc_assert( top.f20 );
334  sc_assert( top.f21 );
335  sc_assert( top.f22 );
336
337  cout << endl << "Success" << endl;
338  return 0;
339}
340
341