#ifdef SYSTEMC
/*
 * $Id: Context_State_transition.cpp 95 2008-12-16 16:24:26Z rosiere $
 *
 * [ Description ]
 * 
 */

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

namespace morpheo                    {
namespace behavioural {
namespace core {
namespace multi_front_end {
namespace front_end {
namespace context_state {


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

    if (PORT_READ(in_NRESET) == 0)
      {
        for (uint32_t i=0; i<_param->_nb_context; i++)
          {
            reg_STATE            [i] = CONTEXT_STATE_OK;
            reg_INTERRUPT_ENABLE [i] = 0;
          }
      }
    else
      {
        // -------------------------------------------------------------------
        // -----[ BRANCH_EVENT ]----------------------------------------------
        // -------------------------------------------------------------------
        for (uint32_t i=0; i<_param->_nb_context; ++i)
          if (PORT_READ(in_BRANCH_EVENT_VAL [i]) and internal_BRANCH_EVENT_ACK [i])
            {
//               throw ERRORMORPHEO(FUNCTION,_("Not yet implemented (Comming Soon).\n"));

              context_state_t state = reg_STATE [i];

              Tdepth_t   depth      = // (_param->_have_port_depth)?PORT_READ(in_BRANCH_EVENT_DEPTH [i]):
                0;
              Tdepth_t   depth_cur  = reg_EVENT_DEPTH [i];
              Tdepth_t   depth_min  = (_param->_have_port_depth)?PORT_READ(in_DEPTH_MIN [i]):0;
              Tdepth_t   depth_max  = _param->_array_size_depth [i];
              
//               Tdepth_t   depth0     = (depth_cur>=depth_min)?(depth_cur-depth_min):((depth_cur+depth_max-depth_min));
//               Tdepth_t   depth1     = (depth    >=depth_min)?(depth    -depth_min):((depth    +depth_max-depth_min));
              Tdepth_t   depth0     = (depth_cur>=depth_min)?(depth_cur):((depth_cur+depth_max));
              Tdepth_t   depth1     = (depth    >=depth_min)?(depth    ):((depth    +depth_max));

              // priority : miss > excep > spr/sync
              uint8_t    priority0  = (state == CONTEXT_STATE_KO_MISS)?2:((state == EVENT_TYPE_EXCEPTION)?1:0);
              uint8_t    priority1  = 2; // miss

              // is_valid = can modify local information
              //   if context_state_ok : yes
              //   if context_state_ko : test the depth, and the priority of envent

              bool       is_valid   = ((state == CONTEXT_STATE_OK) or
                                       (depth1< depth0) or
                                       ((depth1==depth0) and (priority1>priority0)));

              if (is_valid)
                {
                  Tcontrol_t dest_val = PORT_READ(in_BRANCH_EVENT_ADDRESS_DEST_VAL[i]);
                  reg_STATE                  [i] =  CONTEXT_STATE_KO_MISS;
                  reg_EVENT_ADDRESS          [i] =  PORT_READ(in_BRANCH_EVENT_ADDRESS_SRC  [i])+1; // address delay slot
                  reg_EVENT_ADDRESS_EPCR     [i] =  PORT_READ(in_BRANCH_EVENT_ADDRESS_DEST [i]);   // address_next
                  reg_EVENT_ADDRESS_EPCR_VAL [i] =  dest_val;
                //reg_EVENT_ADDRESS_EEAR     [i] =  0; 
                  reg_EVENT_ADDRESS_EEAR_VAL [i] =  0;
                  reg_EVENT_IS_DELAY_SLOT    [i] =  dest_val;
                  reg_EVENT_IS_DS_TAKE       [i] =  dest_val;
                  reg_EVENT_DEPTH            [i] =  depth;
                }
            }
        
        // -------------------------------------------------------------------
        // -----[ DECOD_EVENT ]-----------------------------------------------
        // -------------------------------------------------------------------

        for (uint32_t i=0; i<_param->_nb_decod_unit; i++)
          if (PORT_READ(in_DECOD_EVENT_VAL [i]) and internal_DECOD_EVENT_ACK [i])
            {
              Tcontext_t context    = (_param->_have_port_context_id )?PORT_READ(in_DECOD_EVENT_CONTEXT_ID [i]):0;
              Tdepth_t   depth      = (_param->_have_port_depth      )?PORT_READ(in_DECOD_EVENT_DEPTH      [i]):0;
              Tdepth_t   depth_cur  = reg_EVENT_DEPTH [context];
              Tdepth_t   depth_min = (_param->_have_port_depth      )?PORT_READ(in_DEPTH_MIN [context]):0;
              Tdepth_t   depth_max  = _param->_array_size_depth [context];
              
//               Tdepth_t   depth0     = (depth_cur>=depth_min)?(depth_cur-depth_min):((depth_cur+depth_max-depth_min));
//               Tdepth_t   depth1     = (depth    >=depth_min)?(depth    -depth_min):((depth    +depth_max-depth_min));
              Tdepth_t   depth0     = (depth_cur>=depth_min)?(depth_cur):((depth_cur+depth_max));
              Tdepth_t   depth1     = (depth    >=depth_min)?(depth    ):((depth    +depth_max));

              context_state_t state = reg_STATE [context];
              Tevent_type_t   type  = PORT_READ(in_DECOD_EVENT_TYPE [i]);
              
              // miss > excep > spr/sync
              uint8_t    priority0  = (state == CONTEXT_STATE_KO_MISS)?2:((state == CONTEXT_STATE_KO_EXCEP)?1:0);
              uint8_t    priority1  = (state == EVENT_TYPE_EXCEPTION)?1:0;

              // is_valid = can modify local information
              //  if context_state_ok : yes
              //  if context_state_ko : test the depth, and the priority of envent

              bool       is_valid   = ((state == CONTEXT_STATE_OK) or
                                       (depth1< depth0) or
                                       ((depth1==depth0) and (priority1>priority0)));

              if (is_valid)
                {
                  // decod : 
                  // type : csync, psync, msync, spr_access (l.mac, l.maci, l.macrc, l.msb, l.mfspr, l.mtspr), exception (l.sys)
                  context_state_t state_next    = state;
                  Taddress_t      address       = PORT_READ(in_DECOD_EVENT_ADDRESS       [i]);
                  Tcontrol_t      is_delay_slot = PORT_READ(in_DECOD_EVENT_IS_DELAY_SLOT [i]);

                  switch (type)
                    {
                    case EVENT_TYPE_EXCEPTION          : 
                      {
                        state_next = CONTEXT_STATE_KO_EXCEP; 

                        break;
                      }
                    case EVENT_TYPE_SPR_ACCESS         : 
                      {
                        state_next = CONTEXT_STATE_KO_SPR  ; 
                        address++; // take next address
                        if (is_delay_slot)
                          throw ERRORMORPHEO(FUNCTION,"SPR access in delay slot, not supported.\n");
                        break;
                      }
                    case EVENT_TYPE_MSYNC              : 
                      {
                        state_next = CONTEXT_STATE_KO_MSYNC;
                        address++;  // take next address
                        if (is_delay_slot)
                          throw ERRORMORPHEO(FUNCTION,"SPR access in delay slot, not supported.\n");
                        break;
                      }
                    case EVENT_TYPE_PSYNC              :
                      {
                        state_next = CONTEXT_STATE_KO_PSYNC;
                        address++;  // take next address
                        if (is_delay_slot)
                          throw ERRORMORPHEO(FUNCTION,"SPR access in delay slot, not supported.\n");
                        break;
                      }
                    case EVENT_TYPE_CSYNC              :
                      {
                        state_next = CONTEXT_STATE_KO_CSYNC;
                        address++;  // take next address
                        if (is_delay_slot)
                          throw ERRORMORPHEO(FUNCTION,"SPR access in delay slot, not supported.\n");
                        break;
                      }               
                    case EVENT_TYPE_NONE               :
                    case EVENT_TYPE_MISS_SPECULATION   :
                    case EVENT_TYPE_BRANCH_NO_ACCURATE :
                    default :
                      {
                        throw ERRORMORPHEO(FUNCTION,toString(_("DECOD_EVENT [%d] : invalid event_type : %s.\n"),i,toString(type).c_str()));
                      }
                    }

                  reg_STATE                  [context] = state_next;
                  reg_EVENT_ADDRESS          [context] = address;
                  reg_EVENT_ADDRESS_EPCR     [context] = PORT_READ(in_DECOD_EVENT_ADDRESS_EPCR  [i]); 
                  reg_EVENT_ADDRESS_EPCR_VAL [context] = 1;
                //reg_EVENT_ADDRESS_EEAR     [context]
                  reg_EVENT_ADDRESS_EEAR_VAL [context] = 0;
                  reg_EVENT_IS_DELAY_SLOT    [context] = is_delay_slot;
                //reg_EVENT_IS_DS_TAKE       [context] = 0;
                  reg_EVENT_DEPTH            [context] = depth;
                }
            }

        // -------------------------------------------------------------------
        // -----[ COMMIT_EVENT ]----------------------------------------------
        // -------------------------------------------------------------------

        if (PORT_READ(in_COMMIT_EVENT_VAL ) and internal_COMMIT_EVENT_ACK )
          {
            Tcontext_t context    = (_param->_have_port_context_id)?PORT_READ(in_COMMIT_EVENT_CONTEXT_ID ):0;
            Tdepth_t   depth      = (_param->_have_port_depth     )?PORT_READ(in_COMMIT_EVENT_DEPTH      ):0;
            Tdepth_t   depth_cur  = reg_EVENT_DEPTH [context];
            Tdepth_t   depth_min = (_param->_have_port_depth     )?PORT_READ(in_DEPTH_MIN [context]):0;
            Tdepth_t   depth_max  = _param->_array_size_depth [context];
            
//             Tdepth_t   depth0     = (depth_cur>=depth_min)?(depth_cur-depth_min):((depth_cur+depth_max-depth_min));
//             Tdepth_t   depth1     = (depth    >=depth_min)?(depth    -depth_min):((depth    +depth_max-depth_min));
            Tdepth_t   depth0     = (depth_cur>=depth_min)?(depth_cur):((depth_cur+depth_max));
            Tdepth_t   depth1     = (depth    >=depth_min)?(depth    ):((depth    +depth_max));

            context_state_t state = reg_STATE [context];
            Tevent_type_t   type  = PORT_READ(in_COMMIT_EVENT_TYPE );
            
            // miss > excep > spr/sync
            uint8_t    priority0  = (state == CONTEXT_STATE_KO_MISS)?2:((state == CONTEXT_STATE_KO_EXCEP)?1:0);
            uint8_t    priority1  = 1; // exception

            // is_valid = can modify local information
            //  if context_state_ok : yes
            //  if context_state_ko : test the depth, and the priority of envent

            bool       is_valid   = ((state == CONTEXT_STATE_OK) or
                                     (depth1< depth0) or
                                     ((depth1==depth0) and (priority1>priority0)));

            if (is_valid)
              {
                // commit
                // type : exception
                context_state_t state_next = state;
                switch (type)
                  {
                  case EVENT_TYPE_EXCEPTION          : {state_next = CONTEXT_STATE_KO_EXCEP; break;}
                  case EVENT_TYPE_SPR_ACCESS         :
                  case EVENT_TYPE_MSYNC              :
                  case EVENT_TYPE_PSYNC              :
                  case EVENT_TYPE_CSYNC              :
                  case EVENT_TYPE_NONE               :
                  case EVENT_TYPE_MISS_SPECULATION   :
                  case EVENT_TYPE_BRANCH_NO_ACCURATE :
                  default :
                    {
                      throw ERRORMORPHEO(FUNCTION,toString(_("COMMIT_EVENT : invalid event_type : %s.\n"),toString(type).c_str()));
                    }
                  }
                reg_STATE                  [context] = state_next;
                reg_EVENT_ADDRESS          [context] = PORT_READ(in_COMMIT_EVENT_ADDRESS          );
                reg_EVENT_ADDRESS_EPCR     [context] = PORT_READ(in_COMMIT_EVENT_ADDRESS_EPCR     ); 
                reg_EVENT_ADDRESS_EPCR_VAL [context] = 1;
                reg_EVENT_ADDRESS_EEAR     [context] = PORT_READ(in_COMMIT_EVENT_ADDRESS_EEAR     ); 
                reg_EVENT_ADDRESS_EEAR_VAL [context] = PORT_READ(in_COMMIT_EVENT_ADDRESS_EEAR_VAL );
                reg_EVENT_IS_DELAY_SLOT    [context] = PORT_READ(in_COMMIT_EVENT_IS_DELAY_SLOT    );
              //reg_EVENT_IS_DS_TAKE       [context] = 0;
                reg_EVENT_DEPTH            [context] = depth;
              }
          }

        // -------------------------------------------------------------------
        // -----[ BRANCH_COMPLETE ]-------------------------------------------
        // -------------------------------------------------------------------

        for (uint32_t i=0; i<_param->_nb_inst_branch_complete; i++)
          if (PORT_READ(in_BRANCH_COMPLETE_VAL [i]) and internal_BRANCH_COMPLETE_ACK [i])
            {
              if (PORT_READ(in_BRANCH_COMPLETE_MISS_PREDICTION [i]))
                {
                  Tcontext_t context    = (_param->_have_port_context_id)?PORT_READ(in_BRANCH_COMPLETE_CONTEXT_ID [i]):0;
                  Tdepth_t   depth      = (_param->_have_port_depth     )?PORT_READ(in_BRANCH_COMPLETE_DEPTH      [i]):0;
                  Tdepth_t   depth_cur  = reg_EVENT_DEPTH [context];
                  Tdepth_t   depth_min = (_param->_have_port_depth     )?PORT_READ(in_DEPTH_MIN [context]):0;
                  Tdepth_t   depth_max  = _param->_array_size_depth [context];
                  
//                   Tdepth_t   depth0     = (depth_cur>=depth_min)?(depth_cur-depth_min):((depth_cur+depth_max-depth_min));
//                   Tdepth_t   depth1     = (depth    >=depth_min)?(depth    -depth_min):((depth    +depth_max-depth_min));
                  Tdepth_t   depth0     = (depth_cur>=depth_min)?(depth_cur):((depth_cur+depth_max));
                  Tdepth_t   depth1     = (depth    >=depth_min)?(depth    ):((depth    +depth_max));
                  
                  context_state_t state = reg_STATE [context];
                  
                  // miss > excep > spr/sync
                  uint8_t    priority0  = (state == CONTEXT_STATE_KO_MISS)?2:((state == CONTEXT_STATE_KO_EXCEP)?1:0);
                  uint8_t    priority1  = 2; // miss
                  
                  // is_valid = can modify local information
                  //  if context_state_ok : yes
                  //  if context_state_ko : test the depth, and the priority of envent
                  
                  bool       is_valid   = ((state == CONTEXT_STATE_OK) or
                                           (depth1< depth0) or
                                           ((depth1==depth0) and (priority1>priority0)));
                  
                  if (is_valid)
                    {
                      // commit
                      Tcontrol_t take = PORT_READ(in_BRANCH_COMPLETE_TAKE [i]);
                      reg_STATE                  [context] = CONTEXT_STATE_KO_MISS;
                      reg_EVENT_ADDRESS          [context] = PORT_READ(in_BRANCH_COMPLETE_ADDRESS_SRC  [i])+1; //DELAY_SLOT
                      reg_EVENT_ADDRESS_EPCR     [context] = PORT_READ(in_BRANCH_COMPLETE_ADDRESS_DEST [i]); 
                      reg_EVENT_ADDRESS_EPCR_VAL [context] = take; // if not take : in sequence
                    //reg_EVENT_ADDRESS_EEAR     [context]; 
                      reg_EVENT_ADDRESS_EEAR_VAL [context] = 0;
                      reg_EVENT_IS_DELAY_SLOT    [context] = take;
                      reg_EVENT_IS_DS_TAKE       [context] = take;
                      reg_EVENT_DEPTH            [context] = depth;
                    }
                }
            }

        // -------------------------------------------------------------------
        // -----[ EVENT ]-----------------------------------------------------
        // -------------------------------------------------------------------
        for (uint32_t i=0; i<_param->_nb_context; i++)
          if (internal_EVENT_VAL [i] and PORT_READ(in_EVENT_ACK [i]))
            {
              // Write pc
              context_state_t state = reg_STATE [i];

              switch (state)
                {
                case CONTEXT_STATE_KO_EXCEP_ADDR :
                  {
                    reg_STATE [i] = CONTEXT_STATE_KO_EXCEP_SPR;
                    break;
                  }
                case CONTEXT_STATE_KO_MISS_ADDR  :
                case CONTEXT_STATE_KO_PSYNC_ADDR :
                case CONTEXT_STATE_KO_CSYNC_ADDR :
                  {
                    reg_STATE [i] = CONTEXT_STATE_OK;
                    break;
                  }
                default :
                  {
#ifdef DEBUG_TEST
                    throw ERRORMORPHEO(FUNCTION,toString(_("SPR[%d], Invalid state : %s.\n"),i,toString(state).c_str()));
#endif
                    break;
                  }
                }
            }

        // -------------------------------------------------------------------
        // -----[ SPR_EVENT ]-------------------------------------------------
        // -------------------------------------------------------------------
        for (uint32_t i=0; i<_param->_nb_context; i++)
          if (internal_SPR_EVENT_VAL [i] and PORT_READ(in_SPR_EVENT_ACK [i]))
            {
              // Write spr
#ifdef DEBUG_TEST
              context_state_t state = reg_STATE [i];
            
              if (state != CONTEXT_STATE_KO_EXCEP_SPR)
                throw ERRORMORPHEO(FUNCTION,toString(_("SPR_EVENT[%d], Invalid state : %s.\n"),i,toString(state).c_str()));
#endif
              
              reg_STATE [i] = CONTEXT_STATE_OK;
            }

        // -------------------------------------------------------------------
        // -----[ next state ]------------------------------------------------
        // -------------------------------------------------------------------
        for (uint32_t i=0; i<_param->_nb_context; i++)
          {
//             uint32_t x = _param->_link_context_to_decod_unit    [i];

            Tcounter_t inst_all = PORT_READ(in_NB_INST_COMMIT_ALL[i]) + PORT_READ(in_NB_INST_DECOD_ALL [i]);
            Tcounter_t inst_mem = PORT_READ(in_NB_INST_COMMIT_MEM[i]) + PORT_READ(in_NB_INST_DECOD_ALL [i]);

            context_state_t state = reg_STATE [i];

            switch (state)
              {
              case CONTEXT_STATE_OK              :
                {
                  // nothing, wait an event
                  break;
                }
              case CONTEXT_STATE_KO_EXCEP        :
                {
                  // Wait end of all instruction
                  if (inst_all == 0)
                    state = CONTEXT_STATE_KO_EXCEP_ADDR;
                  break;
                }
              case CONTEXT_STATE_KO_MISS         :
                {
                  // Wait end of all instruction
                  if (inst_all == 0)
                    state = CONTEXT_STATE_KO_MISS_ADDR;
                  break;
                }
              case CONTEXT_STATE_KO_EXCEP_ADDR   :
                {
                  // nothing, wait the update of internal register (pc)
                  break;
                }
              case CONTEXT_STATE_KO_EXCEP_SPR    :
                {
                  // nothing, wait the update of internal register (epcr, eear, sr, esr)
                  break;
                }
              case CONTEXT_STATE_KO_MISS_ADDR    :
                {
                  // nothing, wait the update of internal register (pc)
                  break;
                }
              case CONTEXT_STATE_KO_PSYNC        :
                {
                  // Wait end of all instruction
                  if (inst_all == 0)
//                  state = CONTEXT_STATE_KO_PSYNC_FLUSH;
                    state = CONTEXT_STATE_KO_PSYNC_ADDR ;
                  break;
                }
//            case CONTEXT_STATE_KO_PSYNC_FLUSH  :
//              {
//                // nothing, wait end of flush (ifetch)
//                break;
//              }
              case CONTEXT_STATE_KO_PSYNC_ADDR   :
                {
                  // nothing, wait the pc write
                  break;
                }
              case CONTEXT_STATE_KO_CSYNC        :
                {
                  // Wait end of all instruction
                  if (inst_all == 0)
                    state = CONTEXT_STATE_KO_CSYNC_ADDR ;
//                  state = CONTEXT_STATE_KO_CSYNC_FLUSH;
                  break;
                }
//            case CONTEXT_STATE_KO_CSYNC_FLUSH  :
//              {
//                // nothing, wait end of flush (all internal structure)
//                break;
//              }
              case CONTEXT_STATE_KO_CSYNC_ADDR   :
                {
                  // nothing, wait the pc write
                  break;
                }
              case CONTEXT_STATE_KO_MSYNC        :
                {
                  // Wait end of memory instruction
                  if (inst_mem == 0)
                    state = CONTEXT_STATE_KO_MSYNC_ISSUE;
                  break;
                }
              case CONTEXT_STATE_KO_MSYNC_ISSUE  :
                {
                  // Wait the msync issue
                  if (inst_mem != 0)
                    state = CONTEXT_STATE_KO_MSYNC_EXEC;
                  break;
                }
              case CONTEXT_STATE_KO_MSYNC_EXEC   :
                {
                  // Wait the end of msync
                  if (inst_mem == 0)
                    state = CONTEXT_STATE_OK;
                  break;
                }
              case CONTEXT_STATE_KO_SPR          :
                {
                  // Wait end of all instruction
                  if (inst_all == 0)
                    state = CONTEXT_STATE_KO_SPR_ISSUE;
                  break;
                }
              case CONTEXT_STATE_KO_SPR_ISSUE    :
                {
                  // Wait the spr_access issue
                  if (inst_all != 0)
                    state = CONTEXT_STATE_KO_SPR_EXEC;
                  break;
                }
              case CONTEXT_STATE_KO_SPR_EXEC     :
                {
                  // Wait the spr_access execution
                  if (inst_all == 0)
                    state = CONTEXT_STATE_OK;
                  break;
                }

              default :
                {
                  throw ERRORMORPHEO(FUNCTION,toString(_("Context[%d], Unknow state : %s.\n"),i,toString(state).c_str()));
                }
              }
            reg_STATE [i] = state;
          }

        for (uint32_t i=0; i<_param->_nb_context; ++i)
          {
            reg_INTERRUPT_ENABLE [i] = PORT_READ(in_INTERRUPT_ENABLE [i]) and PORT_READ(in_SPR_SR_IEE [i]);

            if (reg_INTERRUPT_ENABLE [i])
              throw ERRORMORPHEO(FUNCTION,toString(_("Context[%d], Have an interruption, Not yet supported (Comming Soon).\n"),i));
          }
      }

#if DEBUG >= DEBUG_TRACE
    for (uint32_t i=0; i<_param->_nb_context; i++)
      {
        log_printf(TRACE,Context_State,FUNCTION,"  * Dump Context State [%d]",i);
        log_printf(TRACE,Context_State,FUNCTION,"    * reg_STATE                  : %s"         ,toString(reg_STATE [i]).c_str());
        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_ADDRESS          : 0x%x (0x%x)",reg_EVENT_ADDRESS          [i],reg_EVENT_ADDRESS      [i]<<2);
        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_ADDRESS_EPCR     : 0x%x (0x%x)",reg_EVENT_ADDRESS_EPCR     [i],reg_EVENT_ADDRESS_EPCR [i]<<2); 
        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_ADDRESS_EPCR_VAL : %d"         ,reg_EVENT_ADDRESS_EPCR_VAL [i]);
        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_ADDRESS_EEAR     : 0x%x (0x%x)",reg_EVENT_ADDRESS_EEAR     [i],reg_EVENT_ADDRESS_EEAR [i]<<2); 
        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_ADDRESS_EEAR_VAL : %d"         ,reg_EVENT_ADDRESS_EEAR_VAL [i]);
        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_IS_DELAY_SLOT    : %d"         ,reg_EVENT_IS_DELAY_SLOT    [i]);
        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_IS_DS_TAKE       : %d"         ,reg_EVENT_IS_DS_TAKE       [i]);
        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_DEPTH            : %d"         ,reg_EVENT_DEPTH            [i]);
      }
#endif

#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
    end_cycle ();
#endif

    log_end(Context_State,FUNCTION);
  };

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

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