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// throw_it.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: throw_it.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// Process control method throw_it 32 33#define SC_INCLUDE_DYNAMIC_PROCESSES 34 35#include <systemc> 36 37using namespace sc_core; 38using std::cout; 39using std::endl; 40 41struct Top: sc_module 42{ 43 Top(sc_module_name _name) 44 { 45 SC_THREAD(calling); 46 47 SC_THREAD(target1); 48 t1 = sc_get_current_process_handle(); 49 50 SC_THREAD(target2); 51 t2 = sc_get_current_process_handle(); 52 53 SC_THREAD(target3); 54 t3 = sc_get_current_process_handle(); 55 56 SC_METHOD(target4); 57 t4 = sc_get_current_process_handle(); 58 59 SC_THREAD(target5); 60 async_reset_signal_is(areset, true); 61 sensitive << ev; 62 t5 = sc_get_current_process_handle(); 63 t5.disable(); 64 65 count = 0; 66 f0 = f1 = f2 = f3 = f4 = f5 = f6 = f7 = f8 = f9 = 0; 67 f10 = f11 = f12 = f13 = f14 = f15 = f16 = f17 = f18 = f19 = 0; 68 f20 = f21 = f22 = f23 = f24 = f25 = f26 = f27 = f28 = f29 = 0; 69 } 70 71 sc_process_handle t1, t2, t3, t4, t5; 72 sc_event ev; 73 sc_signal<bool> areset; 74 int count; 75 int f0, f1, f2, f3, f4, f5, f6, f7, f8, f9; 76 int f10, f11, f12, f13, f14, f15, f16, f17, f18, f19; 77 int f20, f21, f22, f23, f24, f25, f26, f27, f28, f29; 78 79 std::exception ex; 80 81 void start_of_simulation() 82 { 83 try { 84 t1.throw_it(ex); 85 } 86 catch (std::exception ex) { 87 f1 = 1; 88 sc_assert( t1.valid() ); 89 sc_assert( !t1.terminated() ); 90 } 91 } 92 93 void calling() 94 { 95 wait(SC_ZERO_TIME); 96 97 count = 1; 98 ev.notify(5, SC_NS); 99 wait(10, SC_NS); 100 101 count = 2; 102 t1.throw_it(ex); 103 sc_assert( t1.valid() ); 104 sc_assert( !t1.terminated() ); 105 sc_assert(f4); 106 wait(10, SC_NS); 107 108 count = 3; 109 t4.throw_it(ex); // Throw exception in method process 110 sc_assert( t4.valid() ); 111 sc_assert( !t4.terminated() ); 112 wait(sc_time(200, SC_NS) - sc_time_stamp()); 113 114 count = 4; 115 t1.suspend(); 116 ev.notify(5, SC_NS); 117 wait(10, SC_NS); 118 119 count = 5; 120 t1.throw_it(ex); 121 wait(10, SC_NS); 122 123 count = 6; 124 t1.throw_it(ex); 125 sc_assert( t1.valid() ); 126 sc_assert( !t1.terminated() ); 127 wait(10, SC_NS); 128 129 count = 7; 130 t1.resume(); 131 wait(sc_time(300, SC_NS) - sc_time_stamp()); 132 133 count = 8; 134 t1.disable(); 135 ev.notify(5, SC_NS); 136 wait(10, SC_NS); 137 138 count = 9; 139 t1.throw_it(ex); 140 wait(10, SC_NS); 141 142 count = 10; 143 t1.throw_it(ex); 144 wait(10, SC_NS); 145 146 count = 11; 147 t1.enable(); 148 wait(sc_time(400, SC_NS) - sc_time_stamp()); 149 150 count = 12; 151 t1.sync_reset_on(); 152 ev.notify(5, SC_NS); 153 wait(10, SC_NS); 154 wait(sc_time(400, SC_NS) - sc_time_stamp()); 155 156 count = 13; 157 t1.throw_it(ex); 158 wait(10, SC_NS); 159 160 count = 14; 161 t1.throw_it(ex); 162 wait(10, SC_NS); 163 164 count = 15; 165 t1.sync_reset_off(); 166 wait(sc_time(500, SC_NS) - sc_time_stamp()); 167 168 count = 16; 169 ev.notify(); 170 t1.throw_it(ex); 171 wait(10, SC_NS); 172 173 count = 17; 174 t1.reset(); 175 wait(sc_time(600, SC_NS) - sc_time_stamp()); 176 177 count = 18; 178 t1.disable(); 179 t5.enable(); 180 areset.write(false); 181 wait(10, SC_NS); 182 183 count = 19; 184 ev.notify(); 185 wait(10, SC_NS); 186 187 count = 20; 188 ev.notify(); 189 wait(10, SC_NS); 190 191 count = 21; 192 areset.write(true); 193 wait(10, SC_NS); 194 195 count = 22; 196 t5.throw_it(ex); 197 wait(10, SC_NS); 198 199 count = 23; 200 ev.notify(); 201 wait(10, SC_NS); 202 203 count = 24; 204 t5.throw_it(ex); 205 wait(10, SC_NS); 206 207 count = 25; 208 areset.write(false); 209 wait(sc_time(700, SC_NS) - sc_time_stamp()); 210 211 count = 26; 212 ev.notify(); 213 wait(10, SC_NS); 214 // async_reset_signal_is ? 215 } 216 217 void target1() // Target for throw_it from calling() 218 { 219 switch (count) 220 { 221 case 0: sc_assert( sc_time_stamp() == sc_time( 0, SC_NS) ); f2=1; break; 222 case 12: sc_assert( sc_time_stamp() == sc_time(405, SC_NS) ); f13=1; break; 223 case 17: sc_assert( sc_time_stamp() == sc_time(510, SC_NS) ); f19=1; break; 224 default: sc_assert( false ); break; 225 } 226 227 for (;;) 228 { 229 try { 230 wait(ev); 231 switch (count) 232 { 233 case 1: sc_assert( sc_time_stamp() == sc_time(5, SC_NS) ); f3=1; break; 234 case 7: sc_assert( sc_time_stamp() == sc_time(230, SC_NS) ); f9=1; break; 235 default: sc_assert( false ); break; 236 } 237 } 238 catch (const std::exception& ex) { 239 switch (count) 240 { 241 case 2: sc_assert( !sc_is_unwinding() ); 242 sc_assert( sc_time_stamp() == sc_time( 10, SC_NS) ); f4=1; break; 243 case 5: sc_assert( sc_time_stamp() == sc_time(210, SC_NS) ); f7=1; break; 244 case 6: sc_assert( sc_time_stamp() == sc_time(220, SC_NS) ); f8=1; break; 245 case 9: sc_assert( sc_time_stamp() == sc_time(310, SC_NS) ); f10=1; break; 246 case 10: sc_assert( sc_time_stamp() == sc_time(320, SC_NS) ); f11=1; break; 247 case 12: sc_assert( sc_is_unwinding() ); 248 sc_assert( sc_time_stamp() == sc_time(405, SC_NS) ); f12=1; 249 throw dynamic_cast<const sc_unwind_exception&>(ex); 250 case 13: sc_assert( !sc_is_unwinding() ); 251 sc_assert( sc_time_stamp() == sc_time(410, SC_NS) ); f14=1; break; 252 case 14: sc_assert( sc_time_stamp() == sc_time(420, SC_NS) ); f15=1; break; 253 case 16: sc_assert( sc_time_stamp() == sc_time(500, SC_NS) ); f16=1; break; 254 case 17: sc_assert( sc_is_unwinding() ); 255 sc_assert( sc_time_stamp() == sc_time(510, SC_NS) ); f18=1; 256 throw dynamic_cast<const sc_unwind_exception&>(ex); 257 default: sc_assert( false ); break; 258 } 259 } 260 } 261 } 262 263 void target2() 264 { 265 wait(100, SC_NS); 266 try { 267 t2.throw_it(ex); // Process throws an exception to itself 268 sc_assert( false ); 269 } 270 catch (std::exception ex) { 271 sc_assert( t2.valid() ); 272 sc_assert( !t2.terminated() ); 273 f5 = 1; 274 t3.throw_it(ex); 275 } 276 } 277 278 void target3() // Target for throw_it from target2() 279 { 280 try { 281 wait(1, SC_US); 282 } 283 catch (std::exception ex) { 284 sc_assert( t3.valid() ); 285 sc_assert( !t3.terminated() ); 286 f6 = 1; 287 } 288 } 289 290 void target4() // SC_METHOD, target for throw_it from calling() 291 { 292 t4.throw_it(ex); // Method process throws exception to itself 293 if (count != 0) 294 sc_assert( false ); 295 } 296 297 void target5() // Target for throw_it from calling() + async_reset_signal 298 { 299 switch (count) 300 { 301 case 19: sc_assert( sc_time_stamp() == sc_time(610, SC_NS) ); f20=1; break; 302 case 21: sc_assert( sc_time_stamp() == sc_time(630, SC_NS) ); f23=1; break; 303 case 23: sc_assert( sc_time_stamp() == sc_time(650, SC_NS) ); f26=1; break; 304 default: sc_assert( false ); break; 305 } 306 307 for (;;) 308 { 309 try { 310 wait(); 311 312 switch (count) 313 { 314 case 20: sc_assert( sc_time_stamp() == sc_time(620, SC_NS) ); f21=1; break; 315 case 26: sc_assert( sc_time_stamp() == sc_time(700, SC_NS) ); f28=1; break; 316 default: sc_assert( false ); break; 317 } 318 } 319 catch (const std::exception& ex) { 320 switch (count) 321 { 322 case 21: sc_assert( sc_is_unwinding() ); 323 sc_assert( sc_time_stamp() == sc_time(630, SC_NS) ); f22=1; 324 throw dynamic_cast<const sc_unwind_exception&>(ex); 325 case 22: sc_assert( !sc_is_unwinding() ); 326 sc_assert( sc_time_stamp() == sc_time(640, SC_NS) ); f24=1; break; 327 case 23: sc_assert( sc_is_unwinding() ); 328 sc_assert( sc_time_stamp() == sc_time(650, SC_NS) ); f25=1; 329 throw dynamic_cast<const sc_unwind_exception&>(ex); 330 case 24: sc_assert( !sc_is_unwinding() ); 331 sc_assert( sc_time_stamp() == sc_time(660, SC_NS) ); f27=1; break; 332 default: sc_assert( false ); break; 333 } 334 } 335 } 336 } 337 338 SC_HAS_PROCESS(Top); 339}; 340 341int sc_main(int argc, char* argv[]) 342{ 343 Top top("top"); 344 345 sc_start(); 346 347 sc_assert( top.f1 ); 348 sc_assert( top.f2 ); 349 sc_assert( top.f3 ); 350 sc_assert( top.f4 ); 351 sc_assert( top.f5 ); 352 sc_assert( top.f6 ); 353 sc_assert( top.f7 ); 354 sc_assert( top.f8 ); 355 sc_assert( top.f9 ); 356 sc_assert( top.f10 ); 357 sc_assert( top.f11 ); 358 sc_assert( top.f12 ); 359 sc_assert( top.f13 ); 360 sc_assert( top.f14 ); 361 sc_assert( top.f15 ); 362 sc_assert( top.f16 ); 363 sc_assert( top.f18 ); 364 sc_assert( top.f19 ); 365 sc_assert( top.f20 ); 366 sc_assert( top.f21 ); 367 sc_assert( top.f22 ); 368 sc_assert( top.f23 ); 369 sc_assert( top.f24 ); 370 sc_assert( top.f25 ); 371 sc_assert( top.f26 ); 372 sc_assert( top.f27 ); 373 sc_assert( top.f28 ); 374 375 cout << endl << "Success" << endl; 376 return 0; 377} 378 379