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