method_suspends_itself.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// method_suspends_itself.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: method_suspends_itself.cpp,v $
27// Revision 1.3  2011/05/08 19:18:46  acg
28//  Andy Goodrich: remove extraneous + prefixes from git diff.
29//
30
31// Method process uses suspends, resumes, disables, and enables itself
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(ticker);
46    SC_THREAD(calling);
47
48    SC_METHOD(target);
49      sensitive << ev;
50      dont_initialize();
51      t = sc_get_current_process_handle();
52
53    suspend_target = false;
54    resume_target  = false;
55    disable_target = false;
56    enable_target  = false;
57    dynamic_sensitivity = false;
58    f0 = f1 = f2 = f3 = f4 = f5 = f6 = f7 = f8 = f9 = 0;
59    f10 = f11 = f12 = f13 = f14 = f15 = f16 = f17 = f18 = f19 = 0;
60    f20 = f21 = f22 = f23 = f24 = f25 = f26 = f27 = f28 = f29 = 0;
61  }
62
63  sc_process_handle t;
64  sc_event ev, ev2;
65  bool suspend_target;
66  bool resume_target;
67  bool disable_target;
68  bool enable_target;
69  bool dynamic_sensitivity;
70  int  count;
71  int f0, f1, f2, f3, f4, f5, f6, f7, f8, f9;
72  int f10, f11, f12, f13, f14, f15, f16, f17, f18, f19;
73  int f20, f21, f22, f23, f24, f25, f26, f27, f28, f29;
74
75  void ticker()
76  {
77    for (;;)
78    {
79      wait(10, SC_NS);
80      ev.notify();
81    }
82  }
83
84  void calling()
85  {
86    count = 1;
87    wait(15, SC_NS);
88    // Target runs at 10 NS
89
90    count = 2;
91    suspend_target = true;
92    wait(10, SC_NS);
93    // Target runs at 20 NS and suspends itself
94
95    count = 3;
96    suspend_target = false;
97    wait(10, SC_NS);
98    // Target does not run at 30 NS
99
100    count = 4;
101    t.resume();
102    // Target runs at 35 NS
103
104    wait(10, SC_NS);
105    // Target runs at 40 NS
106
107    count = 6;
108    suspend_target = true;
109    resume_target = true;
110    wait(10, SC_NS);
111    // Target runs at 50 NS
112
113    count = 7;
114    resume_target = true;
115    wait(10, SC_NS);
116    // Double resume at 60 NS
117
118    count = 8;
119    suspend_target = true;
120    resume_target = false;
121    wait(10, SC_NS);
122    // Target runs at 70 NS
123
124    count = 9;
125    wait(10, SC_NS);
126    // Double suspend
127    // Target does not run at 80 NS
128
129    count = 10;
130    suspend_target = false;
131    resume_target = false;
132    t.resume();
133    // Target runs at 85 NS
134
135    wait(10, SC_NS);
136    // Target runs at 90 NS
137    sc_assert( count == 11 );
138
139    count = 12;
140    t.suspend();
141    wait(10, SC_NS);
142    // Target does not run at 100 NS
143
144    count = 13;
145    t.resume();
146    // Target runs at 105 NS
147
148    wait(10, SC_NS);
149    // Target runs at 110 NS
150    sc_assert( count == 14 );
151
152    count = 15;
153    t.disable();
154    wait(10, SC_NS);
155    // Target does not run at 120 NS
156
157    count = 16;
158    wait(10, SC_NS);
159    // Target does not run at 130 NS
160
161    count = 17;
162    t.disable();
163    // Double disable
164    wait(10, SC_NS);
165    // Target does not run at 140 NS
166
167    count = 18;
168    t.enable();
169    wait(10, SC_NS);
170    // Target runs at 150 NS
171
172    count = 19;
173    t.enable();
174    // Double enable
175    wait(10, SC_NS);
176    // Target runs at 160 NS
177
178    count = 20;
179    disable_target = true;
180    wait(10, SC_NS);
181    // Target runs at 170 and disables itself
182
183    count = 21;
184    disable_target = false;
185    wait(10, SC_NS);
186    // Target does not run at 180
187
188    count = 22;
189    enable_target = true;
190    wait(10, SC_NS);
191    // Target does not run at 190
192
193    count = 23;
194    wait(10, SC_NS);
195    // Failed to enable it itself, so still does not run at 200
196
197    count = 24;
198    enable_target = false;
199    t.enable();
200    wait(10, SC_NS);
201    // Target runs at 210
202
203    count = 25;
204    disable_target = true;
205    enable_target = true;
206    wait(10, SC_NS);
207    // Target runs at 220 and calls disable -> enable
208
209    count = 26;
210    disable_target = false;
211    enable_target = false;
212    wait(10, SC_NS);
213    // Target runs at 230
214
215    count = 27;
216    t.suspend();
217    wait(10, SC_NS);
218    // Target does not run at 240
219
220    count = 28;
221    t.enable();
222    wait(10, SC_NS);
223    // Has no effect - still suspended at 250
224
225    count = 29;
226    t.disable();
227    wait(10, SC_NS);
228    // Both disabled and suspended at 260
229
230    count = 30;
231    t.enable();
232    wait(10, SC_NS);
233    // Enabled but still suspended
234
235    count = 31;
236    t.resume();
237    // Target resumed at 275 NS
238    wait(SC_ZERO_TIME);
239
240    count = 311;
241    wait(10, SC_NS);
242
243    count = 32;
244    t.disable();
245    wait(10, SC_NS);
246    // Disabled at 290 NS
247
248    count = 33;
249    t.resume();
250    wait(10, SC_NS);
251    // Still disabled at 300 NS
252
253    count = 34;
254    t.suspend();
255    wait(10, SC_NS);
256    // Both disabled and suspended at 310
257
258    count = 35;
259    t.enable();
260    wait(10, SC_NS);
261    // Remains suspended at 320
262
263    count = 36;
264    t.resume();
265    wait(10, SC_NS);
266    // Resumed at 325 NS and runs at 330
267    sc_assert( count == 37 );
268
269    count = 38;
270    suspend_target = true;
271    resume_target = true;
272    disable_target = true;
273    enable_target = true;
274    wait(10, SC_NS);
275    // Runs at 340
276
277    count = 39;
278    suspend_target = true;
279    resume_target = false;
280    disable_target = true;
281    enable_target = true;
282    wait(10, SC_NS);
283    // Runs at 350, when it suspends
284
285    count = 40;
286    suspend_target = false;
287    wait(10, SC_NS);
288    // Suspended at 360
289
290    count = 41;
291    t.resume();
292    wait(10, SC_NS);
293    // Runs at 365 and 370
294    sc_assert( count == 42 );
295
296    sc_assert( t.valid() );
297    sc_assert( t.terminated() == false );
298    sc_assert( t.dynamic() == false );
299    sc_assert( t.get_parent_object() == this );
300    sc_assert( t.get_process_object() != 0 );
301
302    count = 43;
303    t.reset();
304    wait(SC_ZERO_TIME);
305
306    count = 44;
307    dynamic_sensitivity = true;
308    wait(10, SC_NS);
309    // Runs at 380
310
311    count = 45;
312    ev2.notify();
313    wait(1, SC_NS);
314
315    count = 46;
316    ev2.notify();
317    wait(sc_time(400, SC_NS) - sc_time_stamp());
318
319    count = 47;
320    dynamic_sensitivity = false;
321    t.sync_reset_on(); // Still dynamically sensitive to ev2
322    ev2.notify(); // Clears dynamic sensitivity, restores static sensitivity
323
324    count = 48;
325    wait(10, SC_NS);
326
327    count = 49;
328    t.kill();
329
330    if (t.valid())
331      sc_assert( t.terminated() );
332
333    sc_stop();
334  }
335
336  void target()
337  {
338    //cout << "Target called at " << sc_time_stamp() << " count = " << count << endl;
339    switch (count)
340    {
341    case 1: sc_assert( sc_time_stamp() == sc_time(10, SC_NS) ); f0=1; break;
342    case 2: sc_assert( sc_time_stamp() == sc_time(20, SC_NS) ); f1=1; break;
343    case 4: sc_assert( sc_time_stamp() == sc_time(35, SC_NS) ); count = 5; f2=1; break;
344    case 5: sc_assert( sc_time_stamp() == sc_time(40, SC_NS) ); f3=1; break;
345    case 6: sc_assert( sc_time_stamp() == sc_time(50, SC_NS) ); f4=1; break;
346    case 7: sc_assert( sc_time_stamp() == sc_time(60, SC_NS) ); f5=1; break;
347    case 8: sc_assert( sc_time_stamp() == sc_time(70, SC_NS) ); f6=1; break;
348    case 10: sc_assert( sc_time_stamp() == sc_time(85, SC_NS) ); count = 11; f7=1; break;
349    case 11: sc_assert( sc_time_stamp() == sc_time(90, SC_NS) ); f8=1; break;
350    case 13: sc_assert( sc_time_stamp() == sc_time(105, SC_NS) ); count = 14; f9=1; break;
351    case 14: sc_assert( sc_time_stamp() == sc_time(110, SC_NS) ); f10=1; break;
352    case 18: sc_assert( sc_time_stamp() == sc_time(150, SC_NS) ); f11=1; break;
353    case 19: sc_assert( sc_time_stamp() == sc_time(160, SC_NS) ); f12=1; break;
354    case 20: sc_assert( sc_time_stamp() == sc_time(170, SC_NS) ); f13=1; break;
355    case 24: sc_assert( sc_time_stamp() == sc_time(210, SC_NS) ); f14=1; break;
356    case 25: sc_assert( sc_time_stamp() == sc_time(220, SC_NS) ); f15=1; break;
357    case 26: sc_assert( sc_time_stamp() == sc_time(230, SC_NS) ); f16=1; break;
358    case 31: sc_assert( sc_time_stamp() == sc_time(275, SC_NS) ); f17=1; break;
359    case 311:sc_assert( sc_time_stamp() == sc_time(280, SC_NS) ); f18=1; break;
360    case 36: sc_assert( sc_time_stamp() == sc_time(325, SC_NS) ); count = 37; f19=1; break;
361    case 37: sc_assert( sc_time_stamp() == sc_time(330, SC_NS) ); f20=1; break;
362    case 38: sc_assert( sc_time_stamp() == sc_time(340, SC_NS) ); f21=1; break;
363    case 39: sc_assert( sc_time_stamp() == sc_time(350, SC_NS) ); f22=1; break;
364    case 41: sc_assert( sc_time_stamp() == sc_time(365, SC_NS) ); count = 42; f23=1; break;
365    case 42: sc_assert( sc_time_stamp() == sc_time(370, SC_NS) ); f24=1; break;
366    case 43: sc_assert( sc_time_stamp() == sc_time(375, SC_NS) ); f29=1; break; ////////
367    case 44: sc_assert( sc_time_stamp() == sc_time(380, SC_NS) ); f25=1; break;
368    case 45: sc_assert( sc_time_stamp() == sc_time(385, SC_NS) ); f26=1; break;
369    case 46: sc_assert( sc_time_stamp() == sc_time(386, SC_NS) ); f27=1; break;
370    case 48: sc_assert( sc_time_stamp() == sc_time(400, SC_NS) ); f28=1; break;
371    default: sc_assert( false ); break;
372    }
373
374    if (suspend_target)
375      t.suspend();
376    if (resume_target)
377      t.resume();
378    if (disable_target)
379      t.disable();
380    if (enable_target)
381      t.enable();
382    if (dynamic_sensitivity)
383      next_trigger(ev2);
384  }
385
386  SC_HAS_PROCESS(Top);
387};
388
389int sc_main(int argc, char* argv[])
390{
391  Top top("top");
392
393  sc_start();
394
395  sc_assert( top.f0 );
396  sc_assert( top.f1 );
397  sc_assert( top.f2 );
398  sc_assert( top.f3 );
399  sc_assert( top.f4 );
400  sc_assert( top.f5 );
401  sc_assert( top.f6 );
402  sc_assert( top.f7 );
403  sc_assert( top.f8 );
404  sc_assert( top.f9 );
405  sc_assert( top.f10 );
406  sc_assert( top.f11 );
407  sc_assert( top.f12 );
408  sc_assert( top.f13 );
409  sc_assert( top.f14 );
410  sc_assert( top.f15 );
411  sc_assert( top.f16 );
412  sc_assert( top.f17 );
413  sc_assert( top.f18 );
414  sc_assert( top.f19 );
415  sc_assert( top.f20 );
416  sc_assert( top.f21 );
417  sc_assert( top.f22 );
418  sc_assert( top.f23 );
419  sc_assert( top.f24 );
420  sc_assert( top.f25 );
421  sc_assert( top.f26 );
422  sc_assert( top.f27 );
423  sc_assert( top.f28 );
424  sc_assert( top.f29 );
425
426  cout << endl << "Success" << endl;
427  return 0;
428}
429
430