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_pause.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_pause.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_pause, sc_get_status, sc_is_running 32 33#define SC_INCLUDE_DYNAMIC_PROCESSES 34 35#include <systemc> 36using namespace sc_core; 37using std::cout; 38using std::endl; 39using std::hex; 40 41struct my_interface: virtual sc_interface 42{ 43 virtual void schedule_events_while_paused() = 0; 44}; 45 46struct M: sc_module, private my_interface 47{ 48 sc_export<my_interface> xport; 49 50 SC_CTOR(M) 51 { 52 cout << "sc_get_status() == " << hex << sc_get_status() << " CTOR in " << name() << endl; 53 sc_assert( sc_get_status() == SC_BEFORE_END_OF_ELABORATION ); 54 sc_assert( sc_is_running() == false ); 55 56 xport.bind(*this); 57 58 sc_spawn(sc_bind(&M::T, this)); 59 60 SC_THREAD(on_immed_event); 61 SC_THREAD(on_delta_event); 62 SC_THREAD(on_timed_event); 63 } 64 65 sc_signal<int> sig1, sig2, sig3, sig4; 66 sc_event immed_event; 67 sc_event delta_event; 68 sc_event timed_event; 69 70 void before_end_of_elaboration() 71 { 72 cout << "sc_get_status() == " << hex << sc_get_status() << " before_end_of_elaboration in " << name() << endl; 73 sc_assert( sc_get_status() == SC_BEFORE_END_OF_ELABORATION ); 74 sc_assert( sc_is_running() == false ); 75 sig1.write(1); 76 timed_event.notify(1234, SC_NS); 77 sc_pause(); // Should be ignored 78 } 79 80 void end_of_elaboration() 81 { 82 cout << "sc_get_status() == " << hex << sc_get_status() << " end_of_elaboration in " << name() << endl; 83 sc_assert( sc_get_status() == SC_END_OF_ELABORATION ); 84 sc_assert( sc_is_running() == false ); 85 sig2.write(2); 86 sc_pause(); // Should be ignored 87 } 88 89 void start_of_simulation() 90 { 91 cout << "sc_get_status() == " << hex << sc_get_status() << " start_of_simulation in " << name() << endl; 92 sc_assert( sc_get_status() == SC_START_OF_SIMULATION ); 93 sc_assert( sc_is_running() == false ); 94 sig3.write(3); 95 sig4.write(0); 96 sc_pause(); // Should be ignored 97 } 98 99 void end_of_simulation() 100 { 101 cout << "sc_get_status() == " << hex << sc_get_status() << " end_of_simulation in " << name() << endl;; 102 sc_assert( sc_get_status() == SC_END_OF_SIMULATION ); 103 sc_assert( sc_is_running() == false ); 104 } 105 106 void T() 107 { 108 sc_assert( sig1.read() == 1 ); 109 sc_assert( sig2.read() == 2 ); 110 sc_assert( sig3.read() == 3 ); 111 } 112 113 void on_immed_event() 114 { 115 wait(immed_event); 116 cout << "on_immed_event() awoke\n"; 117 118 // Should run in 1st eval phase after pause 119 sc_assert( sig4.read() == 0 ); 120 } 121 122 void on_delta_event() 123 { 124 wait(delta_event); 125 cout << "on_delta_event() awoke\n"; 126 127 // Should run in 2nd eval phase after pause 128 sc_assert( sig4.read() == 4 ); 129 } 130 131 void on_timed_event() 132 { 133 wait(timed_event); 134 cout << "on_timed_event() awoke\n"; 135 136 sc_assert( sig1.read() == 1 ); 137 sc_assert( sig2.read() == 2 ); 138 sc_assert( sig3.read() == 3 ); 139 sc_assert( sig4.read() == 0 ); 140 sc_assert( sc_time_stamp() == sc_time(1234, SC_NS) ); 141 } 142 143private: 144 145 void schedule_events_while_paused() 146 { 147 sig4.write(4); 148 immed_event.notify(); 149 delta_event.notify(SC_ZERO_TIME); 150 151 // Should be able to instantiate an sc_object while paused 152 mut = new sc_mutex("mut"); 153 sem = new sc_semaphore("sem", 1); 154 } 155 156 sc_mutex* mut; 157 sc_semaphore* sem; 158}; 159 160SC_MODULE(Top) 161{ 162 SC_CTOR(Top) 163 { 164 cout << "sc_get_status() == " << hex << sc_get_status() << " CTOR in " << name() << endl; 165 sc_assert( sc_get_status() == SC_ELABORATION ); 166 sc_assert( sc_is_running() == false ); 167 SC_THREAD(T); 168 169 sc_spawn_options opt; 170 opt.spawn_method(); 171 opt.set_sensitivity( &timed_ev ); 172 opt.set_sensitivity( &delta_ev ); 173 opt.dont_initialize(); 174 sc_spawn(sc_bind(&Top::ev_handler, this), "ev_handler", &opt); 175 176 SC_METHOD(immed_ev_handler); 177 sensitive << immed_ev; 178 dont_initialize(); 179 180 immed_ev_delta = 0; 181 sc_assert( sc_delta_count() == 0 ); 182 } 183 184 ~Top() 185 { 186 sc_assert( sc_get_status() == SC_STOPPED ); 187 sc_assert( sc_is_running() == false ); 188 } 189 190 M* m; 191 sc_event timed_ev; 192 sc_event delta_ev; 193 sc_event immed_ev; 194 unsigned immed_ev_delta; 195 sc_signal<int> sig; 196 197 void before_end_of_elaboration() 198 { 199 cout << "sc_get_status() == " << hex << sc_get_status() << " before_end_of_elaboration in " << name() << endl; 200 sc_assert( sc_get_status() == SC_BEFORE_END_OF_ELABORATION ); 201 sc_assert( sc_is_running() == false ); 202 203 m = new M("m"); 204 } 205 206 void end_of_elaboration() 207 { 208 cout << "sc_get_status() == " << hex << sc_get_status() << " end_of_elaboration in " << name() << endl; 209 sc_assert( sc_get_status() == SC_END_OF_ELABORATION ); 210 sc_assert( sc_is_running() == false ); 211 } 212 213 void start_of_simulation() 214 { 215 cout << "sc_get_status() == " << hex << sc_get_status() << " start_of_simulation in " << name() << endl; 216 sc_assert( sc_get_status() == SC_START_OF_SIMULATION ); 217 sc_assert( sc_is_running() == false ); 218 } 219 220 void end_of_simulation() 221 { 222 cout << "sc_get_status() == " << hex << sc_get_status() << " end_of_simulation in " << name() << endl; 223 sc_assert( sc_get_status() == SC_END_OF_SIMULATION ); 224 sc_assert( sc_is_running() == false ); 225 sc_assert( immed_ev_delta == 999 ); 226 } 227 228 void T() 229 { 230 cout << "sc_get_status() == " << hex << sc_get_status() << " PROCESS in " << name() << endl; 231 sc_assert( sc_delta_count() == 0 ); 232 sc_assert( sig.read() == 42 ); 233 sc_assert( sc_get_status() == SC_RUNNING ); 234 sc_assert( sc_is_running() == true ); 235 wait(timed_ev); 236 sc_assert( sc_time_stamp() == sc_time(42, SC_US) ); 237 sc_assert( sc_get_status() == SC_RUNNING ); 238 sc_assert( sc_is_running() == true ); 239 240 sc_pause(); 241 cout << "sc_get_status() == " << hex << sc_get_status() << " PROCESS after sc_pause in " << name() << endl; 242 sc_assert( sc_time_stamp() == sc_time(42, SC_US) ); 243 sc_assert( sc_get_status() == SC_RUNNING ); 244 sc_assert( sc_is_running() == true ); 245 wait(SC_ZERO_TIME); 246 sc_assert( sc_get_status() == SC_RUNNING ); 247 sc_assert( sc_is_running() == true ); 248 249 sc_pause(); 250 cout << "sc_get_status() == " << hex << sc_get_status() << " PROCESS after sc_pause in " << name() << endl; 251 sc_assert( sc_time_stamp() == sc_time(42, SC_US) ); 252 sc_assert( sc_get_status() == SC_RUNNING ); 253 sc_assert( sc_is_running() == true ); 254 wait(2, SC_US); 255 sc_assert( sc_time_stamp() == sc_time(44, SC_US) ); 256 sc_assert( sc_get_status() == SC_RUNNING ); 257 sc_assert( sc_is_running() == true ); 258 259 sc_stop(); 260 cout << "sc_get_status() == " << hex << sc_get_status() << " PROCESS after sc_stop() in " << name() << endl;; 261 sc_assert( sc_time_stamp() == sc_time(44, SC_US) ); 262 sc_assert( sc_get_status() == SC_RUNNING ); 263 sc_assert( sc_is_running() == true ); 264 265 sc_pause(); 266 sc_assert( sc_get_status() == SC_RUNNING ); 267 } 268 269 void ev_handler() 270 { 271 cout << "sc_get_status() == " << hex << sc_get_status() << " METHOD in " << name() << endl; 272 sc_assert( sc_get_status() == SC_RUNNING ); 273 sc_assert( sig.read() == 42 ); 274 275 static bool first = true; 276 if (first) 277 { 278 sc_assert( sc_time_stamp() == SC_ZERO_TIME ); 279 first = false; 280 } 281 else 282 sc_assert( sc_time_stamp() == sc_time(42, SC_US) ); 283 } 284 285 void immed_ev_handler() 286 { 287 sc_assert( sc_time_stamp() == sc_time(42, SC_US) ); 288 sc_assert( sc_delta_count() == immed_ev_delta ); 289 immed_ev_delta = 999; 290 } 291}; 292 293void spawned_while_paused() 294{ 295 cout << "spawned_while_paused() awoke" << endl; 296 sc_assert( sc_time_stamp() == sc_time(42, SC_US) ); 297 sc_assert( sc_get_status() == SC_RUNNING ); 298 sc_assert( sc_pending_activity() == true ); 299} 300 301int sc_main(int argc, char* argv[]) 302{ 303 sc_assert( sc_delta_count() == 0 ); 304 cout << "sc_get_status() == " << hex << sc_get_status() << " ELAB" << endl; 305 sc_assert( sc_get_status() == SC_ELABORATION ); 306 sc_assert( sc_is_running() == false ); 307 Top top("top"); 308 309 sc_pause(); // Should be ignored 310 311 // Schedule some update requests and events 312 top.sig.write(42); 313 top.timed_ev.notify(42, SC_US); 314 top.delta_ev.notify(SC_ZERO_TIME); 315 sc_assert( sc_get_status() == SC_ELABORATION ); 316 sc_assert( sc_delta_count() == 0 ); 317 318 sc_start(); 319 cout << "sc_get_status() == " << hex << sc_get_status() << " PAUSED" << endl; 320 sc_assert( sc_get_status() == SC_PAUSED ); 321 sc_assert( sc_is_running() == true ); 322 sc_assert( sc_time_stamp() == sc_time(42, SC_US) ); 323 324 sc_start(1, SC_US); 325 cout << "sc_get_status() == " << hex << sc_get_status() << " PAUSED" << endl; 326 sc_assert( sc_get_status() == SC_PAUSED ); 327 sc_assert( sc_is_running() == true ); 328 sc_assert( sc_time_stamp() == sc_time(42, SC_US) ); 329 330 // Schedule an immediate notification 331 top.immed_ev.notify(); 332 top.immed_ev_delta = sc_delta_count(); 333 334 // IMC while paused 335 top.m->xport->schedule_events_while_paused(); 336 337 sc_process_handle h = sc_spawn(&spawned_while_paused); 338 sc_assert( h.valid() ); 339 340 sc_start(); 341 cout << "sc_get_status() == " << hex << sc_get_status() << " STOPPED" << endl; 342 sc_assert( sc_get_status() == SC_STOPPED ); 343 sc_assert( sc_is_running() == false ); 344 sc_assert( sc_time_stamp() == sc_time(44, SC_US) ); 345 346 cout << endl << "Success" << endl; 347 return 0; 348} 349