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// throw_it.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: throw_it.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 method throw_it
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_THREAD(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_THREAD(target5);
60      async_reset_signal_is(areset, true);
61      sensitive << ev;
62      t5 = sc_get_current_process_handle();
63      t5.disable();
64
65    count = 0;
66    f0 = f1 = f2 = f3 = f4 = f5 = f6 = f7 = f8 = f9 = 0;
67    f10 = f11 = f12 = f13 = f14 = f15 = f16 = f17 = f18 = f19 = 0;
68    f20 = f21 = f22 = f23 = f24 = f25 = f26 = f27 = f28 = f29 = 0;
69  }
70
71  sc_process_handle t1, t2, t3, t4, t5;
72  sc_event ev;
73  sc_signal<bool> areset;
74  int count;
75  int f0, f1, f2, f3, f4, f5, f6, f7, f8, f9;
76  int f10, f11, f12, f13, f14, f15, f16, f17, f18, f19;
77  int f20, f21, f22, f23, f24, f25, f26, f27, f28, f29;
78
79  std::exception ex;
80
81  void start_of_simulation()
82  {
83    try {
84      t1.throw_it(ex);
85    }
86    catch (std::exception ex) {
87      f1 = 1;
88      sc_assert( t1.valid() );
89      sc_assert( !t1.terminated() );
90    }
91  }
92
93  void calling()
94  {
95    wait(SC_ZERO_TIME);
96
97    count = 1;
98    ev.notify(5, SC_NS);
99    wait(10, SC_NS);
100
101    count = 2;
102    t1.throw_it(ex);
103    sc_assert( t1.valid() );
104    sc_assert( !t1.terminated() );
105    sc_assert(f4);
106    wait(10, SC_NS);
107
108    count = 3;
109    t4.throw_it(ex); // Throw exception in method process
110    sc_assert( t4.valid() );
111    sc_assert( !t4.terminated() );
112    wait(sc_time(200, SC_NS) - sc_time_stamp());
113
114    count = 4;
115    t1.suspend();
116    ev.notify(5, SC_NS);
117    wait(10, SC_NS);
118
119    count = 5;
120    t1.throw_it(ex);
121    wait(10, SC_NS);
122
123    count = 6;
124    t1.throw_it(ex);
125    sc_assert( t1.valid() );
126    sc_assert( !t1.terminated() );
127    wait(10, SC_NS);
128
129    count = 7;
130    t1.resume();
131    wait(sc_time(300, SC_NS) - sc_time_stamp());
132
133    count = 8;
134    t1.disable();
135    ev.notify(5, SC_NS);
136    wait(10, SC_NS);
137
138    count = 9;
139    t1.throw_it(ex);
140    wait(10, SC_NS);
141
142    count = 10;
143    t1.throw_it(ex);
144    wait(10, SC_NS);
145
146    count = 11;
147    t1.enable();
148    wait(sc_time(400, SC_NS) - sc_time_stamp());
149
150    count = 12;
151    t1.sync_reset_on();
152    ev.notify(5, SC_NS);
153    wait(10, SC_NS);
154    wait(sc_time(400, SC_NS) - sc_time_stamp());
155
156    count = 13;
157    t1.throw_it(ex);
158    wait(10, SC_NS);
159
160    count = 14;
161    t1.throw_it(ex);
162    wait(10, SC_NS);
163
164    count = 15;
165    t1.sync_reset_off();
166    wait(sc_time(500, SC_NS) - sc_time_stamp());
167
168    count = 16;
169    ev.notify();
170    t1.throw_it(ex);
171    wait(10, SC_NS);
172
173    count = 17;
174    t1.reset();
175    wait(sc_time(600, SC_NS) - sc_time_stamp());
176
177    count = 18;
178    t1.disable();
179    t5.enable();
180    areset.write(false);
181    wait(10, SC_NS);
182
183    count = 19;
184    ev.notify();
185    wait(10, SC_NS);
186
187    count = 20;
188    ev.notify();
189    wait(10, SC_NS);
190
191    count = 21;
192    areset.write(true);
193    wait(10, SC_NS);
194
195    count = 22;
196    t5.throw_it(ex);
197    wait(10, SC_NS);
198
199    count = 23;
200    ev.notify();
201    wait(10, SC_NS);
202
203    count = 24;
204    t5.throw_it(ex);
205    wait(10, SC_NS);
206
207    count = 25;
208    areset.write(false);
209    wait(sc_time(700, SC_NS) - sc_time_stamp());
210
211    count = 26;
212    ev.notify();
213    wait(10, SC_NS);
214    // async_reset_signal_is ?
215  }
216
217  void target1() // Target for throw_it from calling()
218  {
219    switch (count)
220    {
221      case  0: sc_assert( sc_time_stamp() == sc_time(  0, SC_NS) ); f2=1; break;
222      case 12: sc_assert( sc_time_stamp() == sc_time(405, SC_NS) ); f13=1; break;
223      case 17: sc_assert( sc_time_stamp() == sc_time(510, SC_NS) ); f19=1; break;
224      default: sc_assert( false ); break;
225    }
226
227    for (;;)
228    {
229      try {
230        wait(ev);
231        switch (count)
232        {
233          case  1: sc_assert( sc_time_stamp() == sc_time(5, SC_NS) ); f3=1; break;
234          case  7: sc_assert( sc_time_stamp() == sc_time(230, SC_NS) ); f9=1; break;
235          default: sc_assert( false ); break;
236        }
237      }
238      catch (const std::exception& ex) {
239        switch (count)
240        {
241          case  2: sc_assert( !sc_is_unwinding() );
242                   sc_assert( sc_time_stamp() == sc_time( 10, SC_NS) ); f4=1; break;
243          case  5: sc_assert( sc_time_stamp() == sc_time(210, SC_NS) ); f7=1; break;
244          case  6: sc_assert( sc_time_stamp() == sc_time(220, SC_NS) ); f8=1; break;
245          case  9: sc_assert( sc_time_stamp() == sc_time(310, SC_NS) ); f10=1; break;
246          case 10: sc_assert( sc_time_stamp() == sc_time(320, SC_NS) ); f11=1; break;
247          case 12: sc_assert( sc_is_unwinding() );
248                   sc_assert( sc_time_stamp() == sc_time(405, SC_NS) ); f12=1;
249                   throw dynamic_cast<const sc_unwind_exception&>(ex);
250          case 13: sc_assert( !sc_is_unwinding() );
251                   sc_assert( sc_time_stamp() == sc_time(410, SC_NS) ); f14=1; break;
252          case 14: sc_assert( sc_time_stamp() == sc_time(420, SC_NS) ); f15=1; break;
253          case 16: sc_assert( sc_time_stamp() == sc_time(500, SC_NS) ); f16=1; break;
254          case 17: sc_assert( sc_is_unwinding() );
255                   sc_assert( sc_time_stamp() == sc_time(510, SC_NS) ); f18=1;
256                   throw dynamic_cast<const sc_unwind_exception&>(ex);
257          default: sc_assert( false ); break;
258        }
259      }
260    }
261  }
262
263  void target2()
264  {
265    wait(100, SC_NS);
266    try {
267      t2.throw_it(ex);  // Process throws an exception to itself
268      sc_assert( false );
269    }
270    catch (std::exception ex) {
271      sc_assert( t2.valid() );
272      sc_assert( !t2.terminated() );
273      f5 = 1;
274      t3.throw_it(ex);
275    }
276  }
277
278  void target3() // Target for throw_it from target2()
279  {
280    try {
281      wait(1, SC_US);
282    }
283    catch (std::exception ex) {
284      sc_assert( t3.valid() );
285      sc_assert( !t3.terminated() );
286      f6 = 1;
287    }
288  }
289
290  void target4() // SC_METHOD, target for throw_it from calling()
291  {
292    t4.throw_it(ex); // Method process throws exception to itself
293    if (count != 0)
294      sc_assert( false );
295  }
296
297  void target5() // Target for throw_it from calling() + async_reset_signal
298  {
299    switch (count)
300    {
301      case 19: sc_assert( sc_time_stamp() == sc_time(610, SC_NS) ); f20=1; break;
302      case 21: sc_assert( sc_time_stamp() == sc_time(630, SC_NS) ); f23=1; break;
303      case 23: sc_assert( sc_time_stamp() == sc_time(650, SC_NS) ); f26=1; break;
304      default: sc_assert( false ); break;
305    }
306
307    for (;;)
308    {
309      try {
310        wait();
311
312        switch (count)
313        {
314          case 20: sc_assert( sc_time_stamp() == sc_time(620, SC_NS) ); f21=1; break;
315          case 26: sc_assert( sc_time_stamp() == sc_time(700, SC_NS) ); f28=1; break;
316          default: sc_assert( false ); break;
317        }
318      }
319      catch (const std::exception& ex) {
320        switch (count)
321        {
322          case 21: sc_assert( sc_is_unwinding() );
323                   sc_assert( sc_time_stamp() == sc_time(630, SC_NS) ); f22=1;
324                   throw dynamic_cast<const sc_unwind_exception&>(ex);
325          case 22: sc_assert( !sc_is_unwinding() );
326                   sc_assert( sc_time_stamp() == sc_time(640, SC_NS) ); f24=1; break;
327          case 23: sc_assert( sc_is_unwinding() );
328                   sc_assert( sc_time_stamp() == sc_time(650, SC_NS) ); f25=1;
329                   throw dynamic_cast<const sc_unwind_exception&>(ex);
330          case 24: sc_assert( !sc_is_unwinding() );
331                   sc_assert( sc_time_stamp() == sc_time(660, SC_NS) ); f27=1; break;
332          default: sc_assert( false ); break;
333        }
334      }
335    }
336  }
337
338  SC_HAS_PROCESS(Top);
339};
340
341int sc_main(int argc, char* argv[])
342{
343  Top top("top");
344
345  sc_start();
346
347  sc_assert( top.f1 );
348  sc_assert( top.f2 );
349  sc_assert( top.f3 );
350  sc_assert( top.f4 );
351  sc_assert( top.f5 );
352  sc_assert( top.f6 );
353  sc_assert( top.f7 );
354  sc_assert( top.f8 );
355  sc_assert( top.f9 );
356  sc_assert( top.f10 );
357  sc_assert( top.f11 );
358  sc_assert( top.f12 );
359  sc_assert( top.f13 );
360  sc_assert( top.f14 );
361  sc_assert( top.f15 );
362  sc_assert( top.f16 );
363  sc_assert( top.f18 );
364  sc_assert( top.f19 );
365  sc_assert( top.f20 );
366  sc_assert( top.f21 );
367  sc_assert( top.f22 );
368  sc_assert( top.f23 );
369  sc_assert( top.f24 );
370  sc_assert( top.f25 );
371  sc_assert( top.f26 );
372  sc_assert( top.f27 );
373  sc_assert( top.f28 );
374
375  cout << endl << "Success" << endl;
376  return 0;
377}
378
379