proc_ctrl_immed.cpp revision 12855:588919e0e4aa
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_immed.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_immed.cpp,v $
27// Revision 1.3  2011/09/01 15:47:15  acg
28//  John Aynsley: correction for immediate method invocation on reset.
29//
30// Revision 1.2  2011/05/08 19:18:46  acg
31//  Andy Goodrich: remove extraneous + prefixes from git diff.
32//
33
34// Process control methods executed immediately in same eval phase
35
36#define SC_INCLUDE_DYNAMIC_PROCESSES
37
38#include <systemc>
39
40using namespace sc_core;
41using std::cout;
42using std::endl;
43
44struct Top: sc_module
45{
46  Top(sc_module_name _name)
47  : count(0), reset_count(0)
48  {
49    SC_THREAD(ctrl);
50    SC_THREAD(target_thread);
51      t = sc_get_current_process_handle();
52
53    SC_METHOD(target_method);
54      sensitive << ev;
55      dont_initialize();
56      m = sc_get_current_process_handle();
57      m.disable();
58
59    SC_METHOD(thread_reset_handler);
60      sensitive << t.reset_event();
61      dont_initialize();
62
63    SC_METHOD(method_reset_handler);
64      sensitive << m.reset_event();
65      dont_initialize();
66
67    SC_METHOD(thread_terminated_handler);
68      sensitive << t.terminated_event();
69      dont_initialize();
70
71    SC_METHOD(method_terminated_handler);
72      sensitive << m.terminated_event();
73      dont_initialize();
74
75    SC_METHOD(yield_helper_method);
76      sensitive << yield_event_1;
77      dont_initialize();
78
79    f0 = f1 = f2 = f3 = f4 = f5 = f6 = f7 = f8 = f9 = 0;
80    f10 = f11 = f12 = f13 = f14 = f15 = f16 = f17 = f18 = f19 = 0;
81    f20 = f21 = f22 = f23 = f24 = f25 = f26 = f27 = f28 = f29 = 0;
82    f30 = f31 = f32 = f33 = f34 = f35 = f36 = f37 = f38 = f39 = 0;
83  }
84
85  sc_event yield_event_1, yield_event_2, target_awoke_event;
86  int count, reset_count;
87  int f0, f1, f2, f3, f4, f5, f6, f7, f8, f9;
88  int f10, f11, f12, f13, f14, f15, f16, f17, f18, f19;
89  int f20, f21, f22, f23, f24, f25, f26, f27, f28, f29;
90  int f30, f31, f32, f33, f34, f35, f36, f37, f38, f39;
91
92  sc_event ev;
93  sc_process_handle t, m;
94  std::exception ex;
95
96  void ctrl()
97  {
98    wait(SC_ZERO_TIME);
99    sc_assert( sc_delta_count() == 1 );
100
101    count = 1;
102    ev.notify();
103    wait(target_awoke_event);
104
105    count = 2;
106    ev.notify();
107    t.suspend();
108    yield();
109
110    count = 2;
111    t.resume();
112    wait(target_awoke_event);
113
114    count = 3;
115    ev.notify();
116    t.disable();
117    wait(target_awoke_event);
118
119    count = 4;
120    ev.notify();
121    yield();
122
123    count = 5;
124    t.enable();
125    yield();
126
127    count = 6;
128    ev.notify();
129    wait(target_awoke_event);
130
131    count = 7;
132    t.suspend();
133    ev.notify();
134    yield();
135
136    count = 8;
137    t.resume();
138    wait(target_awoke_event);
139
140    count = 9;
141    reset_count = 9;
142    t.sync_reset_on();
143    ev.notify();
144    wait(target_awoke_event);
145
146    count = 10;
147    reset_count = 10;
148    ev.notify();
149    wait(target_awoke_event);
150
151    count = 11;
152    t.sync_reset_off();
153    ev.notify();
154    wait(target_awoke_event);
155
156    count = 12;
157    t.resume();
158    t.enable();
159    t.sync_reset_off();
160    yield();
161
162    count = 13;
163    ev.notify();
164    wait(target_awoke_event);
165
166    count = 14;
167    reset_count = 14;
168    t.reset();
169
170    count = 15;
171    ev.notify();
172    wait(target_awoke_event);
173
174    count = 16;
175    reset_count = 16;
176    t.reset();
177
178    count = 17;
179    t.throw_it(ex);
180
181    count = 18;
182    t.kill();
183    yield();
184
185    count = 19;
186    m.enable();
187    ev.notify();
188    wait(target_awoke_event);
189
190    count = 20;
191    ev.notify();
192    m.suspend();
193    yield();
194
195    count = 21;
196    m.resume();
197    wait(target_awoke_event);
198
199    count = 22;
200    m.suspend();
201    ev.notify();
202    yield();
203
204    count = 23;
205    m.resume();
206    wait(target_awoke_event);
207
208    count = 24;
209    m.suspend();
210    ev.notify();
211
212    count = 25;
213    m.resume();
214    wait(target_awoke_event);
215
216    count = 26;
217    reset_count = 26;
218    m.sync_reset_on();
219    ev.notify();
220    wait(target_awoke_event);
221
222    count = 27;
223    m.disable();
224    ev.notify();
225    yield();
226
227    count = 28;
228    reset_count = 28;
229    m.enable();
230    ev.notify();
231    wait(target_awoke_event);
232
233    count = 29;
234    m.sync_reset_off();
235    m.enable();
236    m.resume();
237    yield();
238
239    count = 30;
240    reset_count = 30;
241    m.reset();
242
243    count = 31;
244    m.kill();
245    yield();
246
247    sc_assert( sc_delta_count() == 1 );
248    f27 = 1;
249  }
250
251  void target_thread()
252  {
253    switch (count)
254    {
255      case  0: f0=1; break;
256      case  9: f7=1; break;
257      case 10: f9=1; break;
258      case 14: f13=1; break;
259      case 16: f16=1; break;
260      default: sc_assert(false); break;
261    }
262    while (true)
263    {
264      try {
265        target_awoke_event.notify();
266        wait(ev);
267       }
268      catch (const std::exception& e) {
269        switch (count)
270        {
271          case  9: sc_assert(sc_is_unwinding()); f6=1; break;
272          case 10: sc_assert(sc_is_unwinding()); f8=1; break;
273          case 14: sc_assert(sc_is_unwinding()); f12=1; break;
274          case 16: sc_assert(sc_is_unwinding()); f15=1; break;
275          case 17: sc_assert( !sc_is_unwinding() ); f17=1; break;
276          case 18: sc_assert(sc_is_unwinding()); f19=1; break;
277          default: sc_assert(false); break;
278        }
279        if ( sc_is_unwinding() )
280          throw dynamic_cast<const sc_unwind_exception&>(e);
281      }
282      switch (count)
283      {
284        case  1: f1=1; break;
285        case  2: f2=1; break;
286        case  3: f3=1; break;
287        case  6: f4=1; break;
288        case  8: f5=1; break;
289        case 11: f10=1; break;
290        case 13: f11=1; break;
291        case 15: f14=1; break;
292        case 17: f18=1; break;
293        default: sc_assert(false); break;
294      }
295    }
296  }
297
298  void target_method()
299  {
300    switch (count)
301    {
302      case 19: f20=1; break;
303      case 21: f21=1; break;
304      case 23: f22=1; break;
305      case 25: f23=1; break;
306      case 26: f24=1; break;
307      case 28: f25=1; break;
308      case 30: f26=1; break;
309      default: sc_assert(false); break;
310    }
311    target_awoke_event.notify();
312  }
313
314  void thread_reset_handler()
315  {
316    switch (reset_count)
317    {
318      case  9: f30=1; break;
319      case 10: f31=1; break;
320      case 14: f32=1; break;
321      case 16: f33=1; break;
322      default: sc_assert(false); break;
323    }
324  }
325
326  void method_reset_handler()
327  {
328    switch (reset_count)
329    {
330      case 26: f34=1; break;
331      case 28: f35=1; break;
332      case 30: f36=1; break;
333      default: sc_assert(false); break;
334    }
335  }
336
337  void thread_terminated_handler()
338  {
339    sc_assert(count == 18);
340    sc_assert(sc_delta_count() == 1);
341    f37 = 1;
342  }
343
344  void method_terminated_handler()
345  {
346    sc_assert(count == 31);
347    sc_assert(sc_delta_count() == 1);
348    f38 = 1;
349  }
350
351  void yield()
352  {
353    yield_event_1.notify();
354    wait(yield_event_2);
355  }
356
357  void yield_helper_method()
358  {
359    yield_event_2.notify();
360  }
361
362  SC_HAS_PROCESS(Top);
363};
364
365int sc_main(int argc, char* argv[])
366{
367  Top top("top");
368
369  sc_start();
370
371  sc_assert( top.f0 );
372  sc_assert( top.f1 );
373  sc_assert( top.f2 );
374  sc_assert( top.f3 );
375  sc_assert( top.f4 );
376  sc_assert( top.f5 );
377  sc_assert( top.f6 );
378  sc_assert( top.f7 );
379  sc_assert( top.f8 );
380  sc_assert( top.f9 );
381  sc_assert( top.f10 );
382  sc_assert( top.f11 );
383  sc_assert( top.f12 );
384  sc_assert( top.f13 );
385  sc_assert( top.f14 );
386  sc_assert( top.f15 );
387  sc_assert( top.f16 );
388  sc_assert( top.f17 );
389  sc_assert( top.f18 );
390  sc_assert( top.f19 );
391  sc_assert( top.f20 );
392  sc_assert( top.f21 );
393  sc_assert( top.f22 );
394  sc_assert( top.f23 );
395  sc_assert( top.f24 );
396  sc_assert( top.f25 );
397  sc_assert( top.f26 );
398  sc_assert( top.f27 );
399
400  sc_assert( top.f30 );
401  sc_assert( top.f31 );
402  sc_assert( top.f32 );
403  sc_assert( top.f33 );
404  sc_assert( top.f34 );
405  sc_assert( top.f35 );
406  sc_assert( top.f36 );
407  sc_assert( top.f37 );
408  sc_assert( top.f38 );
409
410  cout << endl << "Success" << endl;
411  return 0;
412}
413
414