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// sc_delta_count.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: sc_delta_count.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// sc_delta_count, including notifications across pauses
32
33#define SC_INCLUDE_DYNAMIC_PROCESSES
34
35#include <systemc>
36using namespace sc_core;
37using std::cout;
38using std::endl;
39
40struct Top: sc_module
41{
42  Top(sc_module_name _name)
43  {
44
45    SC_THREAD(T);
46
47    SC_METHOD(M);
48      sensitive << ev << ev2 << ev3;
49      dont_initialize();
50      m = sc_get_current_process_handle();
51
52    sc_assert( sc_delta_count() == 0 );
53    count = 0;
54    reached_end = false;
55  }
56
57  void start_of_simulation()
58  {
59    sc_assert( sc_delta_count() == 0 );
60  }
61
62  sc_process_handle m;
63  sc_event ev, ev2, ev3;
64  int count;
65  sc_time last_time;
66  bool reached_end;
67
68  void T()
69  {
70    sc_assert( sc_delta_count() == 0 );
71
72    count = 1;
73    ev.notify();
74    wait(SC_ZERO_TIME);
75    sc_assert( sc_delta_count() == 1 );
76
77    count = 2;
78    ev.notify();
79    wait(SC_ZERO_TIME);
80    sc_assert( sc_delta_count() == 2 );
81
82    count = 3;
83    ev.notify(SC_ZERO_TIME);
84    wait(SC_ZERO_TIME);
85    sc_assert( sc_delta_count() == 3 );
86
87    count = 4;
88    ev.notify(1, SC_NS);
89    wait(SC_ZERO_TIME);
90    sc_assert( sc_delta_count() == 4 );
91
92    count = 5;
93    wait(1, SC_NS);
94    ev.notify(1, SC_NS);
95    sc_assert( sc_delta_count() == 5 );
96
97    count = 6;
98    wait(2, SC_NS);
99    sc_assert( sc_delta_count() == 7 );
100
101    count = 7;
102    m.disable();
103    ev.notify(1, SC_NS);
104    wait(2, SC_NS);
105    sc_assert( sc_delta_count() == 8 );
106
107    count = 8;
108    m.enable();
109    ev .notify();
110    ev2.notify(1, SC_NS);
111    ev3.notify(2, SC_NS);
112    wait(3, SC_NS);
113    sc_assert( sc_delta_count() == 11 );
114
115    count = 9;
116    last_time = sc_time_stamp();
117    sc_pause(); // 1st pause
118    wait(ev);
119    sc_assert( sc_delta_count() == 12 );
120
121    count = 10;
122    last_time = sc_time_stamp();
123    sc_pause(); // 2nd pause
124    wait(ev);
125    sc_assert( sc_delta_count() == 13 );
126
127    count = 11;
128    last_time = sc_time_stamp();
129    sc_pause(); // 3rd pause
130    wait(ev);
131    sc_assert( sc_delta_count() == 14 );
132
133    count = 12;
134    last_time = sc_time_stamp();
135    sc_pause(); // 4th pause
136    wait(ev);
137    sc_assert( sc_delta_count() == 15 );
138
139    count = 13;
140    last_time = sc_time_stamp();
141    sc_pause(); // 5th pause
142    wait(ev);
143    sc_assert( sc_delta_count() == 16 );
144
145     count = 14;
146     wait(ev);
147     sc_assert( sc_delta_count() == 17 );
148
149    last_time = sc_time_stamp();
150    reached_end = true;
151    sc_stop();
152  }
153
154  void M()
155  {
156    cout << "M() awoke at " << sc_time_stamp() << endl;
157    switch (count)
158    {
159      case  0: sc_assert( false ); break;
160      case  1: sc_assert( sc_delta_count() == 0 ); break;
161      case  2: sc_assert( sc_delta_count() == 1 ); break;
162      case  3: sc_assert( sc_delta_count() == 3 ); break;
163      case  4: sc_assert( false ); break;
164      case  5: sc_assert( sc_delta_count() == 5 ); break;
165      case  6: sc_assert( sc_delta_count() == 6 ); break;
166      case  7: sc_assert( false ); break;
167      case  8: sc_assert( sc_delta_count() == 8 ||
168                         sc_delta_count() == 9 ||
169                         sc_delta_count() == 10 ); break;
170      case  9: sc_assert( sc_delta_count() == 12 ); break;
171      case 10: sc_assert( sc_delta_count() == 13 ); break;
172      case 11: sc_assert( sc_delta_count() == 14 ); break;
173      case 12: sc_assert( sc_delta_count() == 15 ); break;
174      case 13: sc_assert( sc_delta_count() == 16 ); break;
175      case 14: sc_assert( sc_delta_count() == 17 ); break;
176    }
177  }
178
179  SC_HAS_PROCESS(Top);
180};
181
182int sc_main(int argc, char* argv[])
183{
184  sc_assert( sc_delta_count() == 0 );
185
186  Top top("top");
187
188  sc_start();
189
190  sc_assert( sc_delta_count() == 12 );
191  sc_assert( sc_get_status() == SC_PAUSED );
192  top.ev.notify();  // Wake from 1st pause on immed notification
193
194  sc_start();
195  sc_assert( sc_delta_count() == 13 );
196  sc_assert( sc_get_status() == SC_PAUSED );
197  sc_assert( sc_pending_activity_at_current_time() == false );
198  sc_assert( sc_pending_activity_at_future_time() == false );
199
200  sc_start(SC_ZERO_TIME);
201  sc_assert( sc_delta_count() == 13 );
202
203  sc_assert( sc_get_status() == SC_PAUSED );
204  sc_start(SC_ZERO_TIME);
205  sc_assert( sc_delta_count() == 13 );
206  sc_assert( top.last_time == sc_time_stamp() );
207
208  sc_start(1, SC_NS);
209  sc_assert( sc_delta_count() == 13 );
210  sc_assert( top.count == 10 );
211  // sc_assert( top.last_time == sc_time_stamp() );
212
213  top.ev.notify(SC_ZERO_TIME); // Wake from 2nd pause on delta notification
214  sc_start(1, SC_NS);
215  sc_assert( sc_delta_count() == 14 );
216  sc_assert( top.last_time == sc_time_stamp() );
217
218  top.ev.notify(1, SC_NS);   // Wake from 3rd pause on timed notification
219  sc_start(2, SC_NS);
220  sc_assert( sc_delta_count() == 15 );
221  sc_assert( top.last_time == sc_time_stamp() );
222
223  top.ev.notify(2, SC_NS);   // Future notification beyond the subsequent start
224  sc_assert( sc_pending_activity_at_current_time() == false );
225  sc_assert( sc_pending_activity_at_future_time() == true );
226  sc_start(1, SC_NS);
227  sc_assert( sc_delta_count() == 15 );
228
229  sc_start();
230  sc_assert( sc_delta_count() == 16 );
231  sc_assert( top.last_time == sc_time_stamp() );
232
233  top.ev.notify();  // Wake from 5th pause on immed notification
234  sc_start(SC_ZERO_TIME);
235  sc_assert( sc_delta_count() == 17 );
236  sc_assert( top.last_time == sc_time_stamp() );
237
238  sc_assert( sc_get_status() == SC_PAUSED );
239
240  top.ev.notify(1, SC_NS);   // Future notification before calling sc_stop
241  sc_start(2, SC_NS);
242
243  sc_assert( sc_get_status() == SC_STOPPED );
244  sc_assert( sc_end_of_simulation_invoked() );
245  sc_assert( top.last_time == sc_time_stamp() );
246  sc_assert( top.reached_end );
247
248  cout << endl << "Success" << endl;
249  return 0;
250}
251