#ifdef SYSTEMC
/*
 * $Id: RegisterFile_Monolithic_transition.cpp 138 2010-05-12 17:34:01Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/Generic/RegisterFile/RegisterFile_Monolithic/include/RegisterFile_Monolithic.h"

namespace morpheo                    {
namespace behavioural                {
namespace generic                    {
namespace registerfile               {
namespace registerfile_monolithic    {

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

    if (PORT_READ(in_NRESET) == 0)
      {
        if (_param->_have_init_value)
          {
            for (uint32_t i=0; i<_param->_nb_word; ++i)
              reg_DATA[i] = fromString<Tdata_t>(_param->_init_value);
          }
        else
          {
            for (uint32_t i=0; i<_param->_nb_word; ++i)
              reg_DATA[i] = 0;
          }
      }
    else
      {
#ifdef STATISTICS
        uint32_t stat_nb_read      =0;
        uint32_t stat_nb_write     =0;
        uint32_t stat_nb_read_write=0;
#endif
        for (uint32_t i=0; i<_param->_nb_port_write; i++)
          {
            log_printf(TRACE,RegisterFile,FUNCTION,"  * WRITE [%d] : %d",i,PORT_READ(in_WRITE_VAL[i]));

            // Have a write?
            if ( PORT_READ(in_WRITE_VAL[i]) == true)
              {
#ifdef STATISTICS
                stat_nb_write++;
#endif

// #ifdef STATISTICS
//                 if (usage_is_set(_usage,USE_STATISTICS))
//                   (*_stat_nb_write) ++;
// #endif    

                Taddress_t address = (_param->_have_port_address)?PORT_READ(in_WRITE_ADDRESS[i]):0;
                Tdata_t    data    = PORT_READ(in_WRITE_DATA   [i]);

                log_printf(TRACE,RegisterFile,FUNCTION,"    * address : %d",address);
                log_printf(TRACE,RegisterFile,FUNCTION,"    * gloup");
                log_printf(TRACE,RegisterFile,FUNCTION,"    * data    : %d",data);
                
                log_printf(TRACE,RegisterFile,FUNCTION,"  * [%d] <- %.8x",static_cast<uint32_t>(address),static_cast<uint32_t>(data));

#ifdef DEBUG_TEST
                if (address >= _param->_nb_word)
                  throw ERRORMORPHEO(FUNCTION,toString(_("Address (%d) is invalid (size : %d).\n"),address,_param->_nb_word));
#endif
                
                // Write in registerFile
                reg_DATA[address] = data;
              }
          }
        for (uint32_t i=0; i<_param->_nb_port_read_write; i++)
          {
            log_printf(TRACE,RegisterFile,FUNCTION,"  * READ_WRITE [%d] : %d",i,PORT_READ(in_READ_WRITE_VAL[i]));

            // Have a read_write?
            if (PORT_READ(in_READ_WRITE_VAL[i]) == true)
              {
#ifdef STATISTICS
                stat_nb_read_write++;
#endif

                if (PORT_READ(in_READ_WRITE_RW [i]) == RW_WRITE)
                  {
// #ifdef STATISTICS
//                     if (usage_is_set(_usage,USE_STATISTICS))
//                       (*_stat_nb_write) ++;
// #endif    
                    
                    Taddress_t address = (_param->_have_port_address)?PORT_READ(in_READ_WRITE_ADDRESS[i]):0;
                    Tdata_t    data    = PORT_READ(in_READ_WRITE_WDATA  [i]);
                    
                    log_printf(TRACE,RegisterFile,FUNCTION,"  * [%d] <- %.8x",static_cast<uint32_t>(address),static_cast<uint32_t>(data));
                    

#ifdef DEBUG_TEST
                if (address >= _param->_nb_word)
                  throw ERRORMORPHEO(FUNCTION,toString(_("Address (%d) is invalid (size : %d).\n"),address,_param->_nb_word));
#endif

                    // Write in registerFile
                    reg_DATA[address] = data;
                  }
// #ifdef STATISTICS
//                 else
//                   {
//                     if (usage_is_set(_usage,USE_STATISTICS))
//                       (*_stat_nb_read) ++;
//                   }
// #endif    
              }
          }

        
#ifdef STATISTICS
        if (usage_is_set(_usage,USE_STATISTICS))
          {
            for (uint32_t i=0; i<_param->_nb_port_read; i++)
              if ( PORT_READ(in_READ_VAL [i]) == 1)
                {
                  stat_nb_read ++;
                  // (*_stat_nb_read) ++;
                }

            if (_param->_nb_port_read>0)
            (*_stat_port_read      ) += stat_nb_read;
            if (_param->_nb_port_write>0)
            (*_stat_port_write     ) += stat_nb_write;
            if (_param->_nb_port_read_write>0)
            (*_stat_port_read_write) += stat_nb_read_write;
          }
#endif    
      }

#if defined(DEBUG_RegisterFile_Monolithic) and DEBUG_RegisterFile_Monolithic and (DEBUG >= DEBUG_TRACE)
# if 1
    {
      log_printf(TRACE,RegisterFile,FUNCTION,"  * Dump RegisterFile");

      uint32_t limit = 4;
      
      for (uint32_t i=0; i<_param->_nb_word; i+=limit)
        {
          std::string str = "";
          
          for (uint32_t j=0; j<limit; j++)
            {
              uint32_t index = i+j;
              if (index >= _param->_nb_word)
                break;
              else
                str+=toString("[%.4d] %.8x ",index,reg_DATA[index]);
            }

          log_printf(TRACE,RegisterFile,FUNCTION,"  %s",str.c_str());
        }
    }
# endif
#endif

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

    log_end(RegisterFile_Monolithic,FUNCTION);
  };

}; // end namespace registerfile_monolithic
}; // end namespace registerfile 
}; // end namespace generic
}; // end namespace behavioural          
}; // end namespace morpheo              
#endif
