#ifdef SYSTEMC
/*
 * $Id: Front_end_Glue_genMealy_event.cpp 119 2009-05-25 17:40:26Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Core/Multi_Front_end/Front_end/Front_end_Glue/include/Front_end_Glue.h"

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_front_end {
namespace front_end {
namespace front_end_glue {

#undef  FUNCTION
#define FUNCTION "Front_end_Glue::genMealy_event"
  void Front_end_Glue::genMealy_event (void)
  {
    log_begin(Front_end_Glue,FUNCTION);
    log_function(Front_end_Glue,FUNCTION,_name.c_str());

    for (uint32_t i=0; i<_param->_nb_context; ++i)
      {
        Taddress_t    address = PORT_READ(in_EVENT_CONTEXT_STATE_ADDRESS [i]);
        PORT_WRITE(out_EVENT_ADDRESS             [i],address);
        PORT_WRITE(out_EVENT_IFETCH_UNIT_ADDRESS [i],address);

        Taddress_t    address_next = PORT_READ(in_EVENT_CONTEXT_STATE_ADDRESS_NEXT [i]);
        PORT_WRITE(out_EVENT_ADDRESS_NEXT             [i],address_next);
        PORT_WRITE(out_EVENT_IFETCH_UNIT_ADDRESS_NEXT [i],address_next);

        Tcontrol_t    address_next_val = PORT_READ(in_EVENT_CONTEXT_STATE_ADDRESS_NEXT_VAL [i]);
        PORT_WRITE(out_EVENT_ADDRESS_NEXT_VAL             [i],address_next_val);
        PORT_WRITE(out_EVENT_IFETCH_UNIT_ADDRESS_NEXT_VAL [i],address_next_val);

        Tcontrol_t    is_ds_take = PORT_READ(in_EVENT_CONTEXT_STATE_IS_DS_TAKE [i]);
        PORT_WRITE(out_EVENT_IS_DS_TAKE             [i],is_ds_take);
        PORT_WRITE(out_EVENT_IFETCH_UNIT_IS_DS_TAKE [i],is_ds_take);

        Tevent_type_t event_type = PORT_READ(in_EVENT_CONTEXT_STATE_TYPE [i]);
        PORT_WRITE(out_EVENT_PREDICTION_UNIT_TYPE [i],event_type);
        
        if (_param->_have_port_depth)
          {
        Tdepth_t      depth = PORT_READ(in_EVENT_CONTEXT_STATE_DEPTH [i]);
        PORT_WRITE(out_EVENT_PREDICTION_UNIT_DEPTH [i],depth);
          }
        Tcontrol_t    flush_only = PORT_READ(in_EVENT_CONTEXT_STATE_FLUSH_ONLY [i]);
        

        Tcontrol_t ack                 = PORT_READ(in_EVENT_ACK                 [i]);
        Tcontrol_t ifetch_unit_ack     = PORT_READ(in_EVENT_IFETCH_UNIT_ACK     [i]);
        Tcontrol_t prediction_unit_ack = PORT_READ(in_EVENT_PREDICTION_UNIT_ACK [i]);
        Tcontrol_t context_state_val   = PORT_READ(in_EVENT_CONTEXT_STATE_VAL   [i]);

        Tcontrol_t val                 = (  not flush_only      and
                                          //ack                 and
                                            ifetch_unit_ack     and
                                            prediction_unit_ack and
                                            context_state_val
                                          
                                          );
//         Tcontrol_t ifetch_unit_val     = (  ack                 and
//                                           //ifetch_unit_ack     and
//                                             prediction_unit_ack and
//                                             context_state_val   
//                                             );
        Tcontrol_t ifetch_unit_val     = (  (
                                             flush_only or
                                             ack              ) and
                                          //ifetch_unit_ack     and
                                            prediction_unit_ack and
                                            context_state_val
                                            );

//         Tcontrol_t prediction_unit_val = (  ack                 and
//                                             ifetch_unit_ack     and
//                                           //prediction_unit_ack and
//                                             context_state_val   
//                                             );

        Tcontrol_t prediction_unit_val = (  (
                                             flush_only or
                                             ack              ) and
                                            ifetch_unit_ack     and
                                          //prediction_unit_ack and
                                            context_state_val
                                            );


        Tcontrol_t context_state_ack   = (  ack                 and
                                            ifetch_unit_ack     and
                                            prediction_unit_ack // and
                                          //context_state_val   
                                            );

        log_printf(TRACE,Front_end_Glue,FUNCTION,"  * val                 %d, ack                 %d",val                ,ack                );
        log_printf(TRACE,Front_end_Glue,FUNCTION,"  * ifetch_unit_val     %d, ifetch_unit_ack     %d",ifetch_unit_val    ,ifetch_unit_ack    );
        log_printf(TRACE,Front_end_Glue,FUNCTION,"  * prediction_unit_val %d, prediction_unit_ack %d",prediction_unit_val,prediction_unit_ack);
        log_printf(TRACE,Front_end_Glue,FUNCTION,"  * context_state_val   %d, context_state_ack   %d",context_state_val  ,context_state_ack  );


        PORT_WRITE(out_EVENT_VAL                 [i], val                );
        PORT_WRITE(out_EVENT_IFETCH_UNIT_VAL     [i], ifetch_unit_val    );
        PORT_WRITE(out_EVENT_PREDICTION_UNIT_VAL [i], prediction_unit_val);
        PORT_WRITE(out_EVENT_CONTEXT_STATE_ACK   [i], context_state_ack  );

#ifdef DEBUG
        log_printf(TRACE,Front_end_Glue,FUNCTION,"  * EVENT Context [%d]",i);
        if (val and ack)
          {
            log_printf(TRACE,Front_end_Glue,FUNCTION,"    * have event");
            log_printf(TRACE,Front_end_Glue,FUNCTION,"    * address          : %.8x (%.8x)",address     ,address     <<2);
            log_printf(TRACE,Front_end_Glue,FUNCTION,"    * address_next     : %.8x (%.8x)",address_next,address_next<<2);
            log_printf(TRACE,Front_end_Glue,FUNCTION,"    * address_next_val : %d",address_next_val);
            log_printf(TRACE,Front_end_Glue,FUNCTION,"    * is_ds_take       : %d",is_ds_take      );
            log_printf(TRACE,Front_end_Glue,FUNCTION,"    * flush_only       : %d",flush_only      );
          }
        else
          log_printf(TRACE,Front_end_Glue,FUNCTION,"    * have not event");
#endif
      }

    log_end(Front_end_Glue,FUNCTION);
  };

}; // end namespace front_end_glue
}; // end namespace front_end
}; // end namespace multi_front_end
}; // end namespace core

}; // end namespace behavioural
}; // end namespace morpheo              
#endif
