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// child_proc_control.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: child_proc_control.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 methods applied to child processes 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 : count(0) 45 , n(155) 46 , proc_count(0) 47 { 48 SC_THREAD(ctrl); 49 SC_THREAD(observer); 50 51 f0 = f1 = 0; 52 53 given_birth = new bool[n]; 54 55 c0 = new int[n]; 56 c1 = new int[n]; 57 c2 = new int[n]; 58 c3 = new int[n]; 59 c4 = new int[n]; 60 c5 = new int[n]; 61 62 for (int i = 0; i < n; i++) 63 { 64 given_birth[i] = false; 65 c0[i] = c1[i] = c2[i] = c3[i] = c4[i] = c5[i] = 0; 66 } 67 } 68 69 int count; 70 int f0, f1; 71 const int n; 72 int proc_count; 73 bool *given_birth; 74 int *c0, *c1, *c2, *c3 ,*c4, *c5; 75 76 sc_event ev; 77 sc_process_handle ph; 78 sc_event_and_list reset_event_list; 79 sc_event_and_list terminated_event_list; 80 81 void ctrl() 82 { 83 count = 1; 84 ph = sc_spawn(sc_bind(&Top::parent_proc, this)); 85 wait(10, SC_NS); 86 87 count = 2; 88 ph.reset(SC_INCLUDE_DESCENDANTS); 89 wait(10, SC_NS); 90 91 count = 3; 92 ev.notify(); 93 wait(10, SC_NS); 94 95 count = 4; 96 ph.suspend(SC_INCLUDE_DESCENDANTS); 97 wait(10, SC_NS); 98 99 count = 5; 100 ev.notify(); 101 wait(10, SC_NS); 102 103 count = 6; 104 ph.resume(SC_INCLUDE_DESCENDANTS); 105 wait(10, SC_NS); 106 107 count = 7; 108 ph.kill(SC_INCLUDE_DESCENDANTS); 109 wait(10, SC_NS); 110 } 111 112 void observer() 113 { 114 wait(SC_ZERO_TIME); 115 116 wait(reset_event_list); 117 sc_assert(sc_time_stamp() == sc_time(10, SC_NS)); 118 f0 = 1; 119 120 wait(terminated_event_list); 121 sc_assert(sc_time_stamp() == sc_time(60, SC_NS)); 122 f1 = 1; 123 } 124 125 void parent_proc() 126 { 127 sc_process_handle h; 128 int level = 2; 129 for (int i = 0; i < 5; i++) 130 { 131 if (proc_count < n) 132 { 133 h = sc_spawn(sc_bind(&Top::child_proc, this, proc_count++, level)); 134 reset_event_list &= h.reset_event(); 135 terminated_event_list &= h.terminated_event(); 136 } 137 } 138 } 139 140 void child_proc(int i, int level) 141 { 142 //cout << "Child " << i << " called at " << sc_time_stamp() << endl; 143 if (level > 0) 144 if ( !given_birth[i] ) 145 { 146 sc_process_handle h; 147 for (int j = 0; j < 5; j++) 148 { 149 if (proc_count < n) 150 { 151 h = sc_spawn(sc_bind(&Top::child_proc, this, proc_count++, level-1)); 152 reset_event_list &= h.reset_event(); 153 terminated_event_list &= h.terminated_event(); 154 given_birth[i] = true; 155 } 156 } 157 } 158 switch(count) 159 { 160 case 1: sc_assert(sc_time_stamp() == sc_time( 0, SC_NS)); c0[i] = 1; break; 161 case 2: sc_assert(sc_time_stamp() == sc_time(10, SC_NS)); c2[i] = 1; break; 162 default: sc_assert(false); break; 163 } 164 while(true) 165 { 166 try { 167 wait(ev); 168 } 169 catch (const sc_unwind_exception& e) { 170 switch(count) 171 { 172 case 2: sc_assert(sc_time_stamp() == sc_time(10, SC_NS)); 173 sc_assert( e.is_reset() ); c1[i] = 1; break; 174 case 7: sc_assert(sc_time_stamp() == sc_time(60, SC_NS)); 175 sc_assert( !e.is_reset() ); c5[i] = 1; break; 176 default: sc_assert(false); break; 177 } 178 sc_assert( sc_is_unwinding() ); 179 throw e; 180 } 181 switch(count) 182 { 183 case 3: sc_assert(sc_time_stamp() == sc_time(20, SC_NS)); c3[i] = 1; break; 184 case 6: sc_assert(sc_time_stamp() == sc_time(50, SC_NS)); c4[i] = 1; break; 185 default: sc_assert(false); break; 186 } 187 } 188 } 189 190 SC_HAS_PROCESS(Top); 191}; 192 193int sc_main(int argc, char* argv[]) 194{ 195 Top top("top"); 196 197 sc_start(); 198 199 sc_assert( top.proc_count == top.n ); 200 201 sc_assert( top.f0 ); 202 sc_assert( top.f1 ); 203 204 for (int i = 0; i < top.n; i++) 205 { 206 sc_assert( top.c0[i] ); 207 sc_assert( top.c1[i] ); 208 sc_assert( top.c2[i] ); 209 sc_assert( top.c3[i] ); 210 sc_assert( top.c4[i] ); 211 sc_assert( top.c5[i] ); 212 } 213 214 cout << endl << "Success" << endl; 215 return 0; 216} 217 218