// Variable shared between two threads

#include "systemc.h"

SC_MODULE(intf) {
   
   // Refinable ports
   sc_inslave<int > inp2;
   sc_outmaster<int > outp2;
      
   sc_event input_event;
   sc_in_clk clk;
   
   int temp1;
   int data, prev;
   
   // Slave process to determine the data change & generate an event.
   void inter_f0() {
      data = inp2; // Reads in the data from master
      
      // Check Data change, if so generate event
      if (prev != data){
	prev = data;
	sc_time nt(0, sc_ns);
	input_event.notify(nt);
	cout << " inter_f0: data event notified" << endl;
      }
   }

   // Clock sensitive shared variable process waits to obtain an event notification
   void inter_f1() {
      while(true){
	 cout << " inter_f1: before wait :  " << sc_time_stamp() << endl;
         wait(2,sc_ns); // wait for 2 nano sec
 	 cout << " inter_f1: after wait :  " << sc_time_stamp() << endl;
	 wait(input_event); // wait for input event notify
           temp1 = inp2; // Reads in the data from master
      }
   }
   
   // Clock sensitive shared variable process waits to obtain an event notification
   void inter_f2() {
      while(true){
	  cout << " inter_f2: before wait :  " << sc_time_stamp() << endl;
          wait(1,sc_ns); // wait for 1 nano sec
	  cout << " inter_f2: after wait :  " << sc_time_stamp() << endl;
	  wait(input_event); // wait for input event notify
           outp2 = temp1; // Writes the value to slave
	   cout << " inter_f2:input event triggered, inp2 = " << temp1 << endl;
      }
   }
   
   //Constructor to create & initialize an instance & data structures.
   SC_CTOR(intf) {
      SC_SLAVE(inter_f0, inp2); // Slave thread sensitive to input & create events 
      SC_THREAD(inter_f1); // Clock sensitive thread
      sensitive_pos << clk;
      SC_THREAD(inter_f2); // Clock sensitive thread
      sensitive_neg << clk;
      temp1 = 0;
      prev = data = 0;
      cout << endl << " intf ctor : initializing ....." << endl << endl;
   }
};
   
