#ifdef SYSTEMC //#if defined(STATISTICS) or defined(VHDL_TESTBENCH) /* * $Id$ * * [ Description ] * */ #include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Load_store_unit/include/Load_store_unit.h" namespace morpheo { namespace behavioural { namespace core { namespace multi_execute_loop { namespace execute_loop { namespace multi_execute_unit { namespace execute_unit { namespace load_store_unit { #undef FUNCTION #define FUNCTION "Load_store_unit::function_speculative_load_commit_transition" void Load_store_unit::function_speculative_load_commit_transition (void) { log_printf(FUNC,Load_store_unit,FUNCTION,"Begin"); if (PORT_READ(in_NRESET) == 0) { // Reset : clear all queue _speculative_access_queue_control->clear(); internal_MEMORY_STORE_QUEUE_PTR_READ = 0; internal_MEMORY_LOAD_QUEUE_PTR_READ = 0; for (uint32_t i=0; i< _param->_size_store_queue ; i++) _store_queue [i]._state = STORE_QUEUE_EMPTY; for (uint32_t i=0; i< _param->_size_load_queue ; i++) _load_queue [i]._state = LOAD_QUEUE_EMPTY; for (uint32_t i=0; i< _param->_size_speculative_access_queue; i++) _speculative_access_queue [i]._state = SPECULATIVE_ACCESS_QUEUE_EMPTY; } else { //================================================================ // Interface "MEMORY_IN" //================================================================ if ((PORT_READ(in_MEMORY_IN_VAL) == 1) and ( internal_MEMORY_IN_ACK == 1)) { // Test operation : //~~~~~~~~~~~~~~~~~ // store in store_queue // load in speculation_access_queue // others in speculation_access_queue Toperation_t operation = PORT_READ(in_MEMORY_IN_OPERATION); Tgeneral_data_t address = (PORT_READ(in_MEMORY_IN_IMMEDIAT) + PORT_READ(in_MEMORY_IN_DATA_RA )); bool exception_alignement= (mask_memory_access(operation) & address) != 0; if (is_operation_memory_store(operation) == true) { // ======================= // ===== STORE_QUEUE ===== // ======================= // There a two store request type : // - first is operation with address and data // - second is the information of re order buffer : the store become not speculative and can access at the data cache log_printf(TRACE,Load_store_unit,FUNCTION,"store_queue"); log_printf(TRACE,Load_store_unit,FUNCTION," * PUSH"); // Write pointer is define in rename stage : Tlsq_ptr_t index = PORT_READ(in_MEMORY_IN_STORE_QUEUE_PTR_WRITE); log_printf(TRACE,Load_store_unit,FUNCTION," * index : %d",index); // Need read : state and exception. Tstore_queue_state_t old_state = _store_queue [index]._state; Tstore_queue_state_t new_state = old_state; bool update_info = false; Texception_t old_exception = _store_queue [index]._exception; Texception_t new_exception = old_exception; // Compute next state switch (old_state) { case STORE_QUEUE_EMPTY : { if (is_operation_memory_store_head(operation) == true) { new_state = STORE_QUEUE_NO_VALID_NO_SPECULATIVE; // test if is a speculation if (operation == OPERATION_MEMORY_STORE_HEAD_KO) new_exception = EXCEPTION_MEMORY_MISS_SPECULATION; else new_exception = EXCEPTION_MEMORY_NONE; } else { new_state = STORE_QUEUE_VALID_SPECULATIVE; // Test if have an exception if (exception_alignement == true) new_exception = EXCEPTION_MEMORY_ALIGNMENT; else new_exception = EXCEPTION_MEMORY_NONE; update_info = true; } break; } case STORE_QUEUE_NO_VALID_NO_SPECULATIVE : { // if (is_operation_memory_store_head(operation) == false) // { new_state = STORE_QUEUE_VALID_NO_SPECULATIVE; // Test if have a new exception (priority : miss_speculation) if ((old_exception == EXCEPTION_MEMORY_NONE) and (exception_alignement == true)) new_exception = EXCEPTION_MEMORY_ALIGNMENT; update_info = true; break; // } } case STORE_QUEUE_VALID_SPECULATIVE : { // if (is_operation_memory_store_head(operation) == true) // { new_state = STORE_QUEUE_VALID_NO_SPECULATIVE; if (operation == OPERATION_MEMORY_STORE_HEAD_KO) new_exception = EXCEPTION_MEMORY_MISS_SPECULATION; break; // } } case STORE_QUEUE_VALID_NO_SPECULATIVE : case STORE_QUEUE_COMMIT : { ErrorMorpheo(" Invalid state and operation"); } } _store_queue [index]._state = new_state; _store_queue [index]._exception = new_exception; if (update_info == true) { log_printf(TRACE,Load_store_unit,FUNCTION," * Update information"); _store_queue [index]._context_id = PORT_READ(in_MEMORY_IN_CONTEXT_ID ); _store_queue [index]._packet_id = PORT_READ(in_MEMORY_IN_PACKET_ID ); #ifdef HAVE_MEMORY_OUT_OPERATION _store_queue [index]._operation = operation; #endif #ifdef HAVE_MEMORY_OUT_TYPE _store_queue [index]._type = PORT_READ(in_MEMORY_IN_TYPE ); #endif _store_queue [index]._load_queue_ptr_write = PORT_READ(in_MEMORY_IN_LOAD_QUEUE_PTR_WRITE); _store_queue [index]._address = address; _store_queue [index]._wdata = PORT_READ(in_MEMORY_IN_DATA_RB ); // _store_queue [index]._write_rd = PORT_READ(in_MEMORY_IN_WRITE_RD ); // _store_queue [index]._num_reg_rd = PORT_READ(in_MEMORY_IN_NUM_REG_RD ); } } else { // // ==================================== // // ===== SPECULATIVE_ACCESS_QUEUE ===== // // ==================================== // // In speculative access queue, they are many type's request // log_printf(TRACE,Load_store_unit,FUNCTION,"speculative_access_queue"); // log_printf(TRACE,Load_store_unit,FUNCTION," * PUSH"); // // Write in reservation station // uint32_t index = _speculative_access_queue_control->push(); // log_printf(TRACE,Load_store_unit,FUNCTION," * index : %d",index); } } //================================================================ // Interface "MEMORY_OUT" //================================================================ if (( internal_MEMORY_OUT_VAL == 1) and (PORT_READ(in_MEMORY_OUT_ACK) == 1)) { switch (internal_MEMORY_OUT_SELECT_QUEUE) { case SELECT_STORE_QUEUE : { // ======================= // ===== STORE_QUEUE ===== // ======================= // Entry flush and increase the read pointer _store_queue [internal_MEMORY_STORE_QUEUE_PTR_READ]._state = STORE_QUEUE_EMPTY; internal_MEMORY_STORE_QUEUE_PTR_READ = (internal_MEMORY_STORE_QUEUE_PTR_READ+1)%_param->_size_store_queue; break; } case SELECT_LOAD_QUEUE : case SELECT_LOAD_QUEUE_SPECULATIVE : break; } } } log_printf(FUNC,Load_store_unit,FUNCTION,"End"); }; }; // end namespace load_store_unit }; // end namespace execute_unit }; // end namespace multi_execute_unit }; // end namespace execute_loop }; // end namespace multi_execute_loop }; // end namespace core }; // end namespace behavioural }; // end namespace morpheo #endif //#endif