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// event_list.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: event_list.cpp,v $ 27// Revision 1.3 2011/09/05 21:23:30 acg 28// Philipp A. Hartmann: eliminate compiler warnings. 29// 30// Revision 1.2 2011/05/08 19:18:46 acg 31// Andy Goodrich: remove extraneous + prefixes from git diff. 32// 33 34// Event lists. A thread waits on a list of events built dynamically from a multiport 35 36#include <systemc> 37 38using namespace sc_core; 39using std::cout; 40using std::endl; 41 42struct Mod: sc_module 43{ 44 sc_port<sc_signal_in_if<int>, 0> p; // Multiport 45 46 Mod(sc_module_name _name) 47 { 48 SC_THREAD(T1); 49 SC_THREAD(T2); 50 } 51 52 void T1() 53 { 54 for (;;) 55 { 56 wait(all_events()); 57 cout << "M::T1 awoke with " << p[0]->read() << p[1]->read() << p[2]->read() 58 << " at " << sc_time_stamp() << " on list" << endl; 59 } 60 } 61 void T2() 62 { 63 for (;;) 64 { 65 wait( p[0]->default_event() | p[1]->default_event() ); 66 cout << "M::T2 awoke with " << p[0]->read() << p[1]->read() << p[2]->read() 67 << " at " << sc_time_stamp() << " on list" << endl; 68 } 69 } 70 sc_event_or_list all_events() const 71 { 72 sc_assert( p.size() == 3 ); 73 74 sc_event_or_list or_list; 75 for (int i = 0; i < p.size(); i++) 76 or_list |= p[i]->default_event(); 77 78 sc_assert( or_list.size() == 3 ); 79 return or_list; 80 } 81 82 SC_HAS_PROCESS(Mod); 83}; 84 85struct Top: sc_module 86{ 87 Top(sc_module_name _name) 88 : finished(false) 89 , count(0) 90 { 91 m = new Mod("m"); 92 m->p.bind(sig1); 93 m->p.bind(sig2); 94 m->p.bind(sig3); 95 SC_THREAD(T); 96 SC_METHOD(M); 97 } 98 99 ~Top() 100 { 101 sc_assert( finished ); 102 sc_assert( count == 4 ); 103 sc_assert( sc_get_status() == SC_PAUSED ); 104 sc_assert( sc_is_running() == true ); 105 cout << "~T() called" << endl; 106 } 107 108 sc_signal<int> sig1, sig2, sig3; 109 Mod* m; 110 111 sc_event e1, e2, e3, e4; 112 bool finished; 113 114 void T() 115 { 116 sig1.write(0); 117 sig2.write(0); 118 sig3.write(0); 119 120 wait(10, SC_NS); 121 sig1.write(1); 122 wait(10, SC_NS); 123 sig1.write(2); 124 125 wait(10, SC_NS); 126 sig2.write(1); 127 wait(10, SC_NS); 128 sig2.write(2); 129 130 wait(10, SC_NS); 131 sig3.write(1); 132 wait(10, SC_NS); 133 sig3.write(2); 134 135 sc_time start; 136 start = sc_time_stamp(); 137 138 e1.notify(10, SC_NS); 139 e2.notify(20, SC_NS); 140 141 sc_event_and_list list1 = e1 & e2; 142 sc_assert( list1.size() == 2 ); 143 144 wait( list1 ); 145 cout << "Awoke at " << sc_time_stamp() << endl; 146 sc_assert( sc_time_stamp() - start == sc_time(20, SC_NS) ); 147 148 start = sc_time_stamp(); 149 e1.notify(11, SC_NS); 150 e2.notify(21, SC_NS); 151 152 sc_event_and_list list2; 153 list2 &= e1; 154 list2 &= e2; 155 sc_assert( list2.size() == 2 ); 156 157 wait( list2); 158 cout << "Awoke at " << sc_time_stamp() << endl; 159 sc_assert( sc_time_stamp() - start == sc_time(21, SC_NS) ); 160 161 start = sc_time_stamp(); 162 e1.notify(14, SC_NS); 163 e2.notify(24, SC_NS); 164 165 sc_event_and_list list3 = list2 & e2; 166 sc_assert( list3.size() == 2 ); 167 168 wait( list3 ); 169 cout << "Awoke at " << sc_time_stamp() << endl; 170 sc_assert( sc_time_stamp() - start == sc_time(24, SC_NS) ); 171 172 start = sc_time_stamp(); 173 e1.notify(100, SC_NS); 174 e2.notify(200, SC_NS); 175 176 sc_event_and_list list4; 177 list4 = list3 & e2; 178 sc_assert( list4.size() == 2 ); 179 wait( list4 ); 180 cout << "Awoke at " << sc_time_stamp() << endl; 181 sc_assert( sc_time_stamp() - start == sc_time(200, SC_NS) ); 182 183 start = sc_time_stamp(); 184 e1.notify(101, SC_NS); 185 e2.notify(202, SC_NS); 186 187 sc_event_and_list list5 = list3 & list4; 188 sc_assert( list5.size() == 2 ); 189 wait( list5 ); 190 cout << "Awoke at " << sc_time_stamp() << endl; 191 sc_assert( sc_time_stamp() - start == sc_time(202, SC_NS) ); 192 193 sc_event_and_list list6 = e1; 194 sc_assert( list6.size() == 1 ); 195 196 start = sc_time_stamp(); 197 e1.notify(500, SC_NS); 198 wait(list6); 199 sc_assert( sc_time_stamp() - start == sc_time(500, SC_NS) ); 200 201 202 start = sc_time_stamp(); 203 e1.notify(1000, SC_NS); 204 wait(e1 | e2 | e3); 205 cout << "Awoke at " << sc_time_stamp() << endl; 206 sc_assert( sc_time_stamp() - start == sc_time(1000, SC_NS) ); 207 208 start = sc_time_stamp(); 209 e1.notify(1002, SC_NS); 210 e2.notify(1001, SC_NS); 211 e3.notify(1000, SC_NS); 212 213 wait(e1 & e2 & e3); 214 cout << "Awoke at " << sc_time_stamp() << endl; 215 sc_assert( sc_time_stamp() - start == sc_time(1002, SC_NS) ); 216 217 start = sc_time_stamp(); 218 e1.notify(2000, SC_NS); 219 220 sc_event_or_list list7; 221 list7 = e1 | e2; 222 list7 = list7 | e3; 223 list7 |= e4; 224 wait(list7); 225 cout << "Awoke at " << sc_time_stamp() << endl; 226 sc_assert( sc_time_stamp() - start == sc_time(2000, SC_NS) ); 227 228 start = sc_time_stamp(); 229 e1.notify(3000, SC_NS); 230 list7 = e2 | e3; 231 list7 = e1 | list7; 232 wait(list7); 233 cout << "Awoke at " << sc_time_stamp() << endl; 234 sc_assert( sc_time_stamp() - start == sc_time(3000, SC_NS) ); 235 236 list1 = e1; 237 list2 = e2; 238 e1.notify(SC_ZERO_TIME); 239 wait(list1); 240 e2.notify(SC_ZERO_TIME); 241 wait(list2); 242 243 list1.swap(list2); 244 245 e1.notify(SC_ZERO_TIME); 246 wait(list2); 247 e2.notify(SC_ZERO_TIME); 248 wait(list1); 249 250 finished = true; 251 } 252 253 sc_event v1, v2, v3, v4; 254 sc_event_or_list or_list1, or_list2; 255 sc_event_and_list and_list1, and_list2; 256 int count; 257 258 void M() 259 { 260 switch (count) 261 { 262 case 0: 263 { 264 sc_assert( sc_time_stamp() == sc_time(0, SC_NS) ); 265 or_list1 = v1 | v2; 266 or_list2 = v3 | v4; 267 v2.notify(10, SC_NS); 268 next_trigger(or_list1 | or_list2); 269 break; 270 } 271 case 1: 272 { 273 sc_assert( sc_time_stamp() == sc_time(10, SC_NS) ); 274 and_list1 = v1 & v2; 275 and_list2 = v3 & v4; 276 v1.notify(1, SC_NS); 277 v2.notify(2, SC_NS); 278 v3.notify(3, SC_NS); 279 v4.notify(4, SC_NS); 280 next_trigger(and_list1 & and_list2); 281 break; 282 } 283 case 2: 284 { 285 sc_assert( sc_time_stamp() == sc_time(14, SC_NS) ); 286 and_list1 = v1 & v2 & v2 & v1; 287 sc_assert( and_list1.size() == 2 ); 288 v1.notify(1, SC_NS); 289 v2.notify(2, SC_NS); 290 next_trigger(and_list1); 291 break; 292 } 293 case 3: 294 { 295 sc_assert( sc_time_stamp() == sc_time(16, SC_NS) ); 296 break; 297 } 298 } 299 ++count; 300 } 301 302 SC_HAS_PROCESS(Top); 303}; 304 305int sc_main(int argc, char* argv[]) 306{ 307 Top top("top"); 308 309 sc_start(); 310 311 sc_assert( sc_get_status() == SC_PAUSED ); 312 sc_assert( sc_is_running() ); 313 sc_assert( sc_pending_activity() == false ); 314 315 cout << endl << "Success" << endl; 316 return 0; 317} 318 319