// Wait notify Block on all multiple events

#include "systemc.h"

SC_MODULE(channel) {

   // Refinable ports
   sc_inslave<int > in_p2;
   sc_outmaster<int > out_p2;
   
   sc_event e1,e2,e3,e4,e5,e6,e7,e8,e9,e10;
   sc_event e11,e12,e13,e14,e15,e16,e17,e18,e19,e20;
   sc_event e21,e22,e23,e24,e25,e26,e27,e28,e29,e30;
   sc_event e31,e32,e33,e34,e35,e36,e37,e38,e39,e40;
   sc_event e41,e42,e43,e44,e45,e46,e47,e48,e49,e50;
   
   sc_in_clk clk;
   
   int tmp;
   int data, prev;
      
   // Slave process to determine the data change & generate an event.
   void chan_f0() {
      data = in_p2; // Reads in the data from master
      
      // Check Data change, if so generate event
      if(prev != data) {
         prev = data;
	 sc_time t1(0, sc_ns);
         e1.notify(t1);e2.notify(t1);e3.notify(t1);e4.notify(t1);e5.notify(t1);
         e6.notify(t1);e7.notify(t1);e8.notify(t1);e9.notify(t1);e10.notify(t1);
         e11.notify(t1);e12.notify(t1);e13.notify(t1);e14.notify(t1);e15.notify(t1);
         e16.notify(t1);e17.notify(t1);e18.notify(t1);e19.notify(t1);e20.notify(t1);
         e21.notify(t1);e22.notify(t1);e23.notify(t1);e24.notify(t1);e25.notify(t1);
         e26.notify(t1);e27.notify(t1);e28.notify(t1);e29.notify(t1);e30.notify(t1);
         e31.notify(t1);e32.notify(t1);e33.notify(t1);e34.notify(t1);e35.notify(t1);
         e36.notify(t1);e37.notify(t1);e38.notify(t1);e39.notify(t1);e40.notify(t1);
         e41.notify(t1);e42.notify(t1);e43.notify(t1);e44.notify(t1);e45.notify(t1);
         e46.notify(t1);e47.notify(t1);e48.notify(t1);e49.notify(t1);e50.notify(t1);
         cout << " chan_f0: data events notified" << endl;
      }
      wait(); // Static sensitivity wait
   }
   
   // Clock sensitve process waits to obtain an event notification & transfers data 
   void chan_f1() {
      while(true) {
         cout << "chan_f1: waiting for event notification: Time = " << sc_time_stamp() << endl;
         
         // wait on 50 events
         wait( e1 & e2  & e3  & e4  & e5  & e6  & e7  & e8  & e9  & e10 &
              e11 & e12 & e13 & e14 & e15 & e16 & e17 & e18 & e19 & e20 &
              e21 & e22 & e23 & e24 & e25 & e26 & e27 & e28 & e29 & e30 &
              e31 & e32 & e33 & e34 & e35 & e36 & e37 & e38 & e39 & e40 &
              e41 & e42 & e43 & e44 & e45 & e46 & e47 & e48 & e49 & e50);  
         // wait on all multiple events
      }
   }
   
   //Constructor to create & initialize an instance & data structures.
   SC_CTOR(channel) {
      SC_SLAVE(chan_f0,in_p2); // Slave thread sensitive to input
      SC_THREAD(chan_f1); // Clock sensitive thread
         sensitive_pos << clk;
      tmp = 0;
      prev = data = 0;
      cout << endl << "chan ctor : intializing ..... " << endl << endl;
   }
};
   
