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// immed_self_notif.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: immed_self_notif.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// Change to the semantics of immediate self-notification to match Verilog semantics 32 33#define SC_INCLUDE_DYNAMIC_PROCESSES 34#include <systemc> 35 36using namespace sc_core; 37using std::cout; 38using std::endl; 39 40struct Top: sc_module 41{ 42 Top(sc_module_name _name) 43 { 44 SC_THREAD(T1); 45 sensitive << ev1; 46 47 SC_THREAD(T2); 48 sensitive << ev1; 49 50 SC_THREAD(T3); 51 52 SC_THREAD(T4); 53 sensitive << ev3; 54 55 SC_METHOD(M1); 56 sensitive << ev5; 57 58 SC_METHOD(M2); 59 60 SC_METHOD(M3); 61 62 SC_THREAD(yield_test); 63 64 end_of_t2 = false; 65 m1_run = false; 66 m2_run = false; 67 m3_run = false; 68 first_yield = true; 69 yield_count = 0; 70 yield_test_run = false; 71 } 72 73 sc_event ev1, ev2, ev3, ev4, ev5, ev6, ev7; 74 bool end_of_t2; 75 bool m1_run; 76 bool m2_run; 77 bool m3_run; 78 79 sc_event yield_event_1, yield_event_2; 80 bool first_yield; 81 int yield_count; 82 bool yield_test_run; 83 84 void T1() 85 { 86 wait(SC_ZERO_TIME); 87 ev1.notify(); 88 sc_assert( sc_delta_count() == 1 ); 89 wait(ev1); 90 sc_assert( false ); 91 } 92 93 void T2() 94 { 95 wait(ev1); 96 sc_assert( sc_delta_count() == 1 ); 97 end_of_t2 = true; 98 } 99 100 void T3() 101 { 102 wait(SC_ZERO_TIME); 103 ev2.notify(); 104 sc_assert( sc_delta_count() == 1 ); 105 wait(ev2); 106 sc_assert( false ); 107 } 108 109 void T4() 110 { 111 wait(SC_ZERO_TIME); 112 ev3.notify(); 113 sc_assert( sc_delta_count() == 1 ); 114 wait(ev4); 115 sc_assert( false ); 116 } 117 118 void M1() 119 { 120 sc_assert( !m1_run ); 121 ev5.notify(); 122 m1_run = true; 123 } 124 125 void M2() 126 { 127 sc_assert( !m2_run ); 128 ev6.notify(); 129 next_trigger(ev6); 130 m2_run = true; 131 } 132 133 void M3() 134 { 135 sc_assert( !m3_run ); 136 next_trigger(ev7); 137 ev7.notify(); 138 m3_run = true; 139 } 140 141 void yield_test() 142 { 143 sc_assert( sc_delta_count() == 0 ); 144 wait(SC_ZERO_TIME); 145 sc_assert( sc_delta_count() == 1 ); 146 147 yield(); 148 sc_spawn(sc_bind( &Top::yield_test_child, this)); 149 yield(); 150 sc_spawn(sc_bind( &Top::yield_test_child, this)); 151 yield(); 152 153 sc_assert( sc_delta_count() == 1 ); 154 wait(1, SC_MS); 155 unsigned int delta_count = sc_delta_count(); 156 157 yield(); 158 sc_spawn(sc_bind( &Top::yield_test_child, this)); 159 yield(); 160 sc_spawn(sc_bind( &Top::yield_test_child, this)); 161 yield(); 162 163 sc_assert( sc_delta_count() == delta_count ); 164 yield_test_run = true; 165 } 166 167 void yield_test_child() 168 { 169 yield(); 170 } 171 172 void yield() 173 { 174 ++yield_count; 175 if (first_yield) 176 { 177 sc_spawn(sc_bind(&Top::yield_helper, this)); 178 first_yield = false; 179 } 180 else 181 yield_event_1.notify(); 182 wait(yield_event_2); 183 } 184 185 void yield_helper() 186 { 187 yield_event_2.notify(); 188 while (true) 189 { 190 wait(yield_event_1); 191 yield_event_2.notify(); 192 } 193 } 194 195 SC_HAS_PROCESS(Top); 196}; 197 198 199int sc_main(int argc, char* argv[]) 200{ 201 Top top("top"); 202 203 sc_start(); 204 205 sc_assert( top.end_of_t2 ); 206 sc_assert( top.m1_run ); 207 sc_assert( top.m2_run ); 208 sc_assert( top.m3_run ); 209 sc_assert( top.first_yield == false ); 210 sc_assert( top.yield_count == 10 ); 211 sc_assert( top.yield_test_run ); 212 213 cout << endl << "Success" << endl; 214 return 0; 215} 216 217