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// sync_reset.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: sync_reset.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// sync_reset_on/off 32 33#define SC_INCLUDE_DYNAMIC_PROCESSES 34 35#include <systemc> 36 37using namespace sc_core; 38using std::cout; 39using std::endl; 40 41struct M2: sc_module 42{ 43 M2(sc_module_name _name) 44 { 45 SC_THREAD(ticker); 46 SC_THREAD(calling); 47 SC_THREAD(target1); 48 t1 = sc_get_current_process_handle(); 49 50 sc_spawn_options opt; 51 opt.spawn_method(); 52 opt.dont_initialize(); 53 opt.set_sensitivity( &t1.reset_event() ); 54 sc_spawn(sc_bind( &M2::reset_handler, this ), "reset_handler", &opt); 55 56 SC_THREAD(target2); 57 t2 = sc_get_current_process_handle(); 58 59 SC_METHOD(target3); 60 sensitive << ev; 61 t3 = sc_get_current_process_handle(); 62 63 count = 1; 64 f0 = f1 = f2 = f3 = f4 = f5 = f6 = f7 = f8 = f9 = 0; 65 f10 = f11 = f12 = f13 = f14 = f15 = f16 = f17 = f18 = f19 = 0; 66 f20 = f21 = f22 = f23 = f24 = f25 = f26 = f27 = f28 = f29 = 0; 67 f30 = f31 = f32 = f33 = f34 = f35 = f36 = f37 = f38 = f39 = 0; 68 f40 = f41 = f42 = f43 = f44 = f45 = f46 = f47 = f48 = f49 = 0; 69 } 70 71 sc_process_handle t1, t2, t3; 72 sc_event ev; 73 int count; 74 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 int f30, f31, f32, f33, f34, f35, f36, f37, f38, f39; 79 int f40, f41, f42, f43, f44, f45, f46, f47, f48, f49; 80 81 void ticker() 82 { 83 for (;;) 84 { 85 wait(10, SC_NS); 86 sc_assert( !sc_is_unwinding() ); 87 ev.notify(); 88 } 89 } 90 91 void calling() 92 { 93 count = 1; 94 wait(15, SC_NS); 95 // Target runs at 10 NS 96 97 count = 2; 98 t1.sync_reset_on(); 99 // Target does not run at 15 NS 100 101 wait(10, SC_NS); 102 // Target is reset at 20 NS 103 104 count = 3; 105 wait(10, SC_NS); 106 // Target is reset again at 30 NS 107 108 count = 4; 109 t1.sync_reset_off(); 110 // Target does not run at 35 NS 111 112 wait(10, SC_NS); 113 // Target runs at 40 NS 114 115 count = 5; 116 t1.sync_reset_off(); 117 // Double sync_reset_off 118 119 wait(10, SC_NS); 120 // Target runs at 50 NS 121 122 count = 6; 123 t1.sync_reset_on(); 124 t1.disable(); 125 wait(10, SC_NS); 126 // Target does not run at 60 NS 127 128 count = 7; 129 t1.enable(); 130 // Target does not run at 65 NS 131 wait(10, SC_NS); 132 // Target reset at 70 NS 133 134 count = 8; 135 t1.disable(); 136 wait(10, SC_NS); 137 // Target does not run at 80 NS 138 139 count = 9; 140 t1.sync_reset_off(); 141 wait(10, SC_NS); 142 // Target still disabled at 90 NS 143 144 count = 10; 145 t1.enable(); 146 wait(10, SC_NS); 147 // Target runs at 100 NS 148 149 count = 11; 150 t1.suspend(); 151 wait(10, SC_NS); 152 // Target does not run at 110 NS 153 154 count = 12; 155 wait(10, SC_NS); 156 // Target still suspended at 120 NS 157 158 count = 13; 159 t1.resume(); 160 // Target runs at 125 NS 161 wait(1, SC_NS); 162 163 count = 14; 164 wait(9, SC_NS); 165 // Target runs again at 130 NS 166 167 count = 15; 168 t1.sync_reset_on(); 169 // Double sync_reset_on 170 wait(10, SC_NS); 171 // Target reset at 140 NS 172 173 count = 16; 174 t1.sync_reset_off(); 175 wait(10, SC_NS); 176 // Target runs at 150 NS 177 178 count = 17; 179 t1.sync_reset_off(); 180 wait(10, SC_NS); 181 // Target runs at 160 NS 182 183 count = 18; 184 t1.sync_reset_on(); 185 wait(10, SC_NS); 186 // Target reset at 170 NS 187 188 count = 19; 189 t1.reset(); 190 // Target reset at 175 NS 191 wait(SC_ZERO_TIME); 192 193 count = 20; 194 wait(1, SC_NS); 195 t1.reset(); 196 // Target reset at 176 NS 197 198 count = 21; 199 t1.reset(); 200 // Target reset at 176 NS 201 wait(1, SC_NS); 202 203 count = 22; 204 wait(8, SC_NS); 205 // Target reset at 180 NS 206 207 count = 23; 208 wait(10, SC_NS); 209 // Target reset at 190 NS 210 211 count = 24; 212 t1.sync_reset_off(); 213 wait(10, SC_NS); 214 // Target runs at 200 NS 215 216 count = 25; 217 wait(10, SC_NS); 218 // Target runs at 210 NS 219 220 count = 26; 221 t1.reset(); 222 wait(SC_ZERO_TIME); 223 // Target reset at 215 224 225 t1.disable(); // Close it down 226 wait(sc_time(300, SC_NS) - sc_time_stamp()); 227 228 count = 27; 229 t2.resume(); 230 wait(SC_ZERO_TIME); 231 232 count = 28; 233 wait(15, SC_NS); 234 235 count = 29; 236 t2.sync_reset_on(); 237 wait(10, SC_NS); 238 239 t2.sync_reset_off(); 240 t2.suspend(); 241 wait(sc_time(405, SC_NS) - sc_time_stamp()); 242 243 count = 30; 244 t3.resume(); 245 wait(SC_ZERO_TIME); 246 247 count = 31; 248 wait(10, SC_NS); 249 250 count = 32; 251 t3.sync_reset_on(); 252 wait(10, SC_NS); 253 254 sc_stop(); 255 } 256 257 void target1() 258 { 259 //cout << "Target1 called/reset at " << sc_time_stamp() << " count = " << count << endl; 260 switch (count) 261 { 262 case 1: sc_assert( sc_time_stamp() == sc_time(0, SC_NS) ); f0=1; break; 263 case 2: sc_assert( sc_time_stamp() == sc_time(20, SC_NS) ); f1=1; break; 264 case 3: sc_assert( sc_time_stamp() == sc_time(30, SC_NS) ); f2=1; break; 265 case 7: sc_assert( sc_time_stamp() == sc_time(70, SC_NS) ); f3=1; break; 266 case 15: sc_assert( sc_time_stamp() == sc_time(140, SC_NS) ); f4=1; break; 267 case 18: sc_assert( sc_time_stamp() == sc_time(170, SC_NS) ); f5=1; break; 268 case 19: sc_assert( sc_time_stamp() == sc_time(175, SC_NS) ); f6=1; break; 269 case 20: sc_assert( sc_time_stamp() == sc_time(176, SC_NS) ); f7=1; break; 270 case 21: sc_assert( sc_time_stamp() == sc_time(176, SC_NS) ); f8=1; break; 271 case 22: sc_assert( sc_time_stamp() == sc_time(180, SC_NS) ); f9=1; break; 272 case 23: sc_assert( sc_time_stamp() == sc_time(190, SC_NS) ); f10=1; break; 273 case 26: sc_assert( sc_time_stamp() == sc_time(215, SC_NS) ); f11=1; break; 274 default: sc_assert( false ); break; 275 } 276 277 for (;;) 278 { 279 try { 280 wait(ev); 281 //cout << "Target1 awoke at " << sc_time_stamp() << " count = " << count << endl; 282 sc_assert( !sc_is_unwinding() ); 283 switch (count) 284 { 285 case 1: sc_assert( sc_time_stamp() == sc_time(10, SC_NS) ); f12=1; break; 286 case 4: sc_assert( sc_time_stamp() == sc_time(40, SC_NS) ); f13=1; break; 287 case 5: sc_assert( sc_time_stamp() == sc_time(50, SC_NS) ); f14=1; break; 288 case 10: sc_assert( sc_time_stamp() == sc_time(100, SC_NS) ); f15=1; break; 289 case 13: sc_assert( sc_time_stamp() == sc_time(125, SC_NS) ); f16=1; break; 290 case 14: sc_assert( sc_time_stamp() == sc_time(130, SC_NS) ); f17=1; break; 291 case 16: sc_assert( sc_time_stamp() == sc_time(150, SC_NS) ); f18=1; break; 292 case 17: sc_assert( sc_time_stamp() == sc_time(160, SC_NS) ); f19=1; break; 293 case 24: sc_assert( sc_time_stamp() == sc_time(200, SC_NS) ); f20=1; break; 294 case 25: sc_assert( sc_time_stamp() == sc_time(210, SC_NS) ); f21=1; break; 295 default: sc_assert( false ); break; 296 } 297 } 298 catch (const sc_unwind_exception& ex) { 299 sc_assert( sc_is_unwinding() ); 300 sc_assert( ex.is_reset() ); 301 throw ex; 302 } 303 } 304 } 305 306 void reset_handler() 307 { 308 //cout << "reset_handler awoke at " << sc_time_stamp() << " count = " << count << endl; 309 sc_assert( !sc_is_unwinding() ); 310 switch (count) 311 { 312 case 2: sc_assert( sc_time_stamp() == sc_time(20, SC_NS) ); f22=1; break; 313 case 3: sc_assert( sc_time_stamp() == sc_time(30, SC_NS) ); f23=1; break; 314 case 7: sc_assert( sc_time_stamp() == sc_time(70, SC_NS) ); f24=1; break; 315 case 15: sc_assert( sc_time_stamp() == sc_time(140, SC_NS) ); f27=1; break;; 316 case 18: sc_assert( sc_time_stamp() == sc_time(170, SC_NS) ); f28=1; break; 317 case 19: sc_assert( sc_time_stamp() == sc_time(175, SC_NS) ); f29=1; break; 318 case 21: sc_assert( sc_time_stamp() == sc_time(176, SC_NS) ); f31=1; break; 319 case 22: sc_assert( sc_time_stamp() == sc_time(180, SC_NS) ); f32=1; break; 320 case 23: sc_assert( sc_time_stamp() == sc_time(190, SC_NS) ); f33=1; break; 321 case 26: sc_assert( sc_time_stamp() == sc_time(215, SC_NS) ); f34=1; break; 322 default: sc_assert( false ); break; 323 } 324 } 325 326 void target2() 327 { 328 if (sc_delta_count() == 0) 329 t2.suspend(); // Hack to work around not being able to call suspend during elab 330 331 switch (count) 332 { 333 case 27: sc_assert( sc_time_stamp() == sc_time(300, SC_NS) ); f35=1; break; 334 case 29: sc_assert( sc_time_stamp() == sc_time(320, SC_NS) ); f37=1; break; 335 default: sc_assert( false ); break; 336 } 337 while(1) 338 { 339 try { 340 wait(10, SC_NS); 341 } 342 catch (const sc_unwind_exception& e) { 343 switch (count) 344 { 345 case 29: sc_assert( sc_time_stamp() == sc_time(320, SC_NS) ); f38=1; break; 346 default: sc_assert( false ); break; 347 } 348 throw e; 349 } 350 switch (count) 351 { 352 case 28: sc_assert( sc_time_stamp() == sc_time(310, SC_NS) ); f36=1; break; 353 default: sc_assert( false ); break; 354 } 355 } 356 } 357 358 void target3() 359 { 360 if (sc_delta_count() == 0) 361 t3.suspend(); // Hack to work around not being able to call suspend during elab 362 363 switch (count) 364 { 365 case 1: sc_assert( sc_time_stamp() == sc_time(0, SC_NS) ); break; 366 case 30: sc_assert( sc_time_stamp() == sc_time(405, SC_NS) ); f39=1; break; 367 case 31: sc_assert( sc_time_stamp() == sc_time(410, SC_NS) ); f40=1; break; 368 case 32: sc_assert( sc_time_stamp() == sc_time(420, SC_NS) ); f41=1; break; 369 default: sc_assert( false ); break; 370 } 371 } 372 373 SC_HAS_PROCESS(M2); 374}; 375 376int sc_main(int argc, char* argv[]) 377{ 378 M2 m("m"); 379 380 sc_start(); 381 382 sc_assert(m.f0); 383 sc_assert(m.f1); 384 sc_assert(m.f2); 385 sc_assert(m.f3); 386 sc_assert(m.f4); 387 sc_assert(m.f5); 388 sc_assert(m.f6); 389 sc_assert(m.f7); 390 sc_assert(m.f8); 391 sc_assert(m.f9); 392 sc_assert(m.f10); 393 sc_assert(m.f11); 394 sc_assert(m.f12); 395 sc_assert(m.f13); 396 sc_assert(m.f14); 397 sc_assert(m.f15); 398 sc_assert(m.f16); 399 sc_assert(m.f17); 400 sc_assert(m.f18); 401 sc_assert(m.f19); 402 sc_assert(m.f20); 403 sc_assert(m.f21); 404 sc_assert(m.f22); 405 sc_assert(m.f23); 406 sc_assert(m.f24); 407 sc_assert(m.f27); 408 sc_assert(m.f28); 409 sc_assert(m.f29); 410 sc_assert(m.f31); 411 sc_assert(m.f32); 412 sc_assert(m.f33); 413 sc_assert(m.f34); 414 sc_assert(m.f35); 415 sc_assert(m.f36); 416 sc_assert(m.f37); 417 sc_assert(m.f38); 418 sc_assert(m.f39); 419 sc_assert(m.f40); 420 sc_assert(m.f41); 421 422 cout << endl << "Success" << endl; 423 return 0; 424} 425 426