immed_self_notif.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// immed_self_notif.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: immed_self_notif.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// Change to the semantics of immediate self-notification to match Verilog semantics
32
33#define SC_INCLUDE_DYNAMIC_PROCESSES
34#include <systemc>
35
36using namespace sc_core;
37using std::cout;
38using std::endl;
39
40struct Top: sc_module
41{
42  Top(sc_module_name _name)
43  {
44    SC_THREAD(T1);
45      sensitive << ev1;
46
47    SC_THREAD(T2);
48      sensitive << ev1;
49
50    SC_THREAD(T3);
51
52    SC_THREAD(T4);
53      sensitive << ev3;
54
55    SC_METHOD(M1);
56      sensitive << ev5;
57
58    SC_METHOD(M2);
59
60    SC_METHOD(M3);
61
62    SC_THREAD(yield_test);
63
64    end_of_t2   = false;
65    m1_run      = false;
66    m2_run      = false;
67    m3_run      = false;
68    first_yield = true;
69    yield_count = 0;
70    yield_test_run = false;
71  }
72
73  sc_event ev1, ev2, ev3, ev4, ev5, ev6, ev7;
74  bool end_of_t2;
75  bool m1_run;
76  bool m2_run;
77  bool m3_run;
78
79  sc_event yield_event_1, yield_event_2;
80  bool first_yield;
81  int yield_count;
82  bool yield_test_run;
83
84  void T1()
85  {
86    wait(SC_ZERO_TIME);
87    ev1.notify();
88    sc_assert( sc_delta_count() == 1 );
89    wait(ev1);
90    sc_assert( false );
91  }
92
93  void T2()
94  {
95    wait(ev1);
96    sc_assert( sc_delta_count() == 1 );
97    end_of_t2 = true;
98  }
99
100  void T3()
101  {
102    wait(SC_ZERO_TIME);
103    ev2.notify();
104    sc_assert( sc_delta_count() == 1 );
105    wait(ev2);
106    sc_assert( false );
107  }
108
109  void T4()
110  {
111    wait(SC_ZERO_TIME);
112    ev3.notify();
113    sc_assert( sc_delta_count() == 1 );
114    wait(ev4);
115    sc_assert( false );
116  }
117
118  void M1()
119  {
120    sc_assert( !m1_run );
121    ev5.notify();
122    m1_run = true;
123  }
124
125  void M2()
126  {
127    sc_assert( !m2_run );
128    ev6.notify();
129    next_trigger(ev6);
130    m2_run = true;
131  }
132
133  void M3()
134  {
135    sc_assert( !m3_run );
136    next_trigger(ev7);
137    ev7.notify();
138    m3_run = true;
139  }
140
141  void yield_test()
142  {
143    sc_assert( sc_delta_count() == 0 );
144    wait(SC_ZERO_TIME);
145    sc_assert( sc_delta_count() == 1 );
146
147    yield();
148    sc_spawn(sc_bind( &Top::yield_test_child, this));
149    yield();
150    sc_spawn(sc_bind( &Top::yield_test_child, this));
151    yield();
152
153    sc_assert( sc_delta_count() == 1 );
154    wait(1, SC_MS);
155    unsigned int delta_count = sc_delta_count();
156
157    yield();
158    sc_spawn(sc_bind( &Top::yield_test_child, this));
159    yield();
160    sc_spawn(sc_bind( &Top::yield_test_child, this));
161    yield();
162
163    sc_assert( sc_delta_count() == delta_count );
164    yield_test_run = true;
165  }
166
167  void yield_test_child()
168  {
169    yield();
170  }
171
172  void yield()
173  {
174    ++yield_count;
175    if (first_yield)
176    {
177      sc_spawn(sc_bind(&Top::yield_helper, this));
178      first_yield = false;
179    }
180    else
181      yield_event_1.notify();
182    wait(yield_event_2);
183  }
184
185  void yield_helper()
186  {
187    yield_event_2.notify();
188    while (true)
189    {
190      wait(yield_event_1);
191      yield_event_2.notify();
192    }
193  }
194
195  SC_HAS_PROCESS(Top);
196};
197
198
199int sc_main(int argc, char* argv[])
200{
201  Top top("top");
202
203  sc_start();
204
205  sc_assert( top.end_of_t2 );
206  sc_assert( top.m1_run );
207  sc_assert( top.m2_run );
208  sc_assert( top.m3_run );
209  sc_assert( top.first_yield == false );
210  sc_assert( top.yield_count == 10 );
211  sc_assert( top.yield_test_run );
212
213  cout << endl << "Success" << endl;
214  return 0;
215}
216
217