odds_and_ends.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// odds_and_ends.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: odds_and_ends.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// Quick test of new features in 1666-2011
32
33#define SC_INCLUDE_DYNAMIC_PROCESSES
34
35#include <systemc>
36using namespace sc_core;
37using std::cout;
38using std::endl;
39
40SC_MODULE(Top)
41{
42  SC_CTOR(Top)
43  {
44    SC_THREAD(gen);
45    SC_THREAD(T1);
46      h1 = sc_get_current_process_handle();
47    SC_THREAD(T2);
48      h2 = sc_get_current_process_handle();
49
50    // Complete for mutex
51    SC_THREAD(task1);
52    SC_THREAD(task2);
53
54    SC_METHOD(reset_handler);
55      dont_initialize();
56      sensitive << h2.reset_event();
57
58    SC_METHOD(kill_handler);
59      dont_initialize();
60      sensitive << h2.terminated_event();
61
62    SC_THREAD(T3);
63
64    end_of_T1 = end_of_T3 = T3A_called = T3B_called = false;
65  }
66
67  sc_event ev;
68
69  sc_process_handle h1, h2;
70  bool end_of_T1, end_of_T3;
71
72  void gen()
73  {
74    for (;;)
75    {
76      wait(10, SC_NS);
77      ev.notify();
78    }
79  }
80
81  void T1()
82  {
83    wait(25, SC_NS);
84    cout << "suspend at " << sc_time_stamp() << endl;
85    h2.suspend();
86    wait(20, SC_NS);
87    cout << "resume at " << sc_time_stamp() << endl;
88    h2.resume();
89    wait(20, SC_NS);
90
91    cout << "disable at " << sc_time_stamp() << endl;
92    h2.disable();
93    wait(20, SC_NS);
94    cout << "enable at " << sc_time_stamp() << endl;
95    h2.enable();
96    wait(20, SC_NS);
97
98    h2.reset();
99    wait(20, SC_NS);
100
101    h2.kill();
102    wait(20, SC_NS);
103
104    sc_pause();
105    wait(50, SC_NS);
106    sc_stop();
107    end_of_T1 = true;
108  }
109
110  void T2()
111  {
112    for (;;)
113    {
114      wait(ev);
115      cout << "T2 at " << sc_time_stamp() << endl;
116    }
117  }
118
119  void task1()
120  {
121    resource();
122    sc_assert( sc_time_stamp() == sc_time(10, SC_NS) || sc_time_stamp() == sc_time(20, SC_NS) );
123    cout << "task1 or task2 completed" << endl;
124  }
125
126  void task2()
127  {
128    resource();
129    sc_assert( sc_time_stamp() == sc_time(10, SC_NS) || sc_time_stamp() == sc_time(20, SC_NS) );
130    cout << "task1 or task2 completed" << endl;
131  }
132
133  void resource()
134  {
135    sc_mutex mut;
136    mut.lock();
137    wait(10, SC_NS);
138    mut.unlock();
139  }
140
141  void reset_handler()
142  {
143    cout << "reset_handler() called at " << sc_time_stamp() << endl;
144    sc_assert( sc_time_stamp() == sc_time(105, SC_NS) );
145    sc_assert( !sc_is_unwinding() );
146  }
147
148  void kill_handler()
149  {
150    cout << "kill_handler() called at " << sc_time_stamp() << endl;
151    sc_assert( sc_time_stamp() == sc_time(125, SC_NS) );
152    sc_assert( !sc_is_unwinding() );
153  }
154
155  void T3()
156  {
157    wait(10, SC_NS);
158    SC_FORK
159      t3a = sc_spawn(sc_bind( &Top::T3A, this)),
160      t3b = sc_spawn(sc_bind( &Top::T3B, this))
161    SC_JOIN
162    if (t3a.valid()) sc_assert( t3a.terminated() );
163    if (t3b.valid()) sc_assert( t3b.terminated() );
164    end_of_T3 = true;
165  }
166
167  sc_process_handle t3a, t3b;
168  bool T3A_called;
169  bool T3B_called;
170
171  void T3A()
172  {
173    sc_assert( sc_time_stamp() == sc_time(10, SC_NS) );
174    wait(5, SC_NS);
175    T3A_called = true;
176  }
177
178  void T3B()
179  {
180    sc_assert( sc_time_stamp() == sc_time(10, SC_NS) );
181    wait(7, SC_NS);
182    T3B_called = true;
183  }
184};
185
186int sc_main(int argc, char* argv[])
187{
188  Top top("top");
189  sc_start();
190
191  while (sc_pending_activity() && sc_get_status() != SC_STOPPED)
192  {
193    cout << "Reentering sc_start at " << sc_time_stamp() << endl;
194    sc_start(sc_time_to_pending_activity());
195  }
196
197  cout << "sc_max_time() = " << sc_max_time() << endl;
198  sc_assert( sc_get_status() == SC_STOPPED );
199
200  sc_assert( top.end_of_T1 );
201  sc_assert( top.end_of_T3 );
202  sc_assert( top.T3A_called );
203  sc_assert( top.T3B_called );
204
205  cout << endl << "Success" << endl;
206  return 0;
207}
208