#ifdef SYSTEMC //#if defined(STATISTICS) or defined(VHDL_TESTBENCH) /* * $Id: Load_store_unit_function_speculative_load_access_genMoore.cpp 138 2010-05-12 17:34:01Z rosiere $ * * [ 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_access_genMoore" void Load_store_unit::function_speculative_load_access_genMoore (void) { log_begin(Load_store_unit,FUNCTION); log_function(Load_store_unit,FUNCTION,_name.c_str()); if (PORT_READ(in_NRESET)) { // ~~~~~[ Interface "memory_out" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tcontext_t memory_out_context_id = 0; Tcontext_t memory_out_front_end_id = 0; Tcontext_t memory_out_ooo_engine_id = 0; Tpacket_t memory_out_packet_id = 0; Tcontrol_t memory_out_cancel = 0; Tcontrol_t memory_out_write_rd = 0; Tgeneral_address_t memory_out_num_reg_rd = 0; Tgeneral_data_t memory_out_data_rd = 0; // Tcontrol_t memory_out_write_re = 0; // Tspecial_address_t memory_out_num_reg_re = 0; // Tspecial_data_t memory_out_data_re = 0; Tcontrol_t memory_out_no_sequence = 0; Texception_t memory_out_exception = 0; internal_MEMORY_OUT_VAL = 0; // Test store and load queue log_printf(TRACE,Load_store_unit,FUNCTION," * Test MEMORY_OUT"); log_printf(TRACE,Load_store_unit,FUNCTION," * Load queue"); for (internal_MEMORY_OUT_PTR=0; internal_MEMORY_OUT_PTR<_param->_size_load_queue; internal_MEMORY_OUT_PTR++) // for (uin32_t i=0; (i<_param->_size_load_queue) and not (find_load); i++) { // internal_MEMORY_OUT_PTR = (reg_LOAD_QUEUE_PTR_READ+1)%_param->_size_load_queue; internal_MEMORY_OUT_VAL = ((_load_queue[internal_MEMORY_OUT_PTR]._state == LOAD_QUEUE_COMMIT_CHECK) or (_load_queue[internal_MEMORY_OUT_PTR]._state == LOAD_QUEUE_COMMIT)); if (internal_MEMORY_OUT_VAL) { log_printf(TRACE,Load_store_unit,FUNCTION," * find : %d",internal_MEMORY_OUT_PTR); internal_MEMORY_OUT_SELECT_QUEUE = (_load_queue[internal_MEMORY_OUT_PTR]._state == LOAD_QUEUE_COMMIT_CHECK)?SELECT_LOAD_QUEUE_SPECULATIVE:SELECT_LOAD_QUEUE; memory_out_context_id = _load_queue [internal_MEMORY_OUT_PTR]._context_id; memory_out_front_end_id = _load_queue [internal_MEMORY_OUT_PTR]._front_end_id; memory_out_ooo_engine_id = _load_queue [internal_MEMORY_OUT_PTR]._ooo_engine_id; memory_out_packet_id = _load_queue [internal_MEMORY_OUT_PTR]._packet_id ; memory_out_cancel = _load_queue [internal_MEMORY_OUT_PTR]._cancel ; memory_out_write_rd = _load_queue [internal_MEMORY_OUT_PTR]._write_rd ; memory_out_num_reg_rd = _load_queue [internal_MEMORY_OUT_PTR]._num_reg_rd; Tdcache_data_t data_old = _load_queue [internal_MEMORY_OUT_PTR]._rdata; Tdcache_data_t data_new = extend(_param->_size_general_data, data_old >> _load_queue [internal_MEMORY_OUT_PTR]._shift, _load_queue [internal_MEMORY_OUT_PTR]._is_load_signed, _load_queue [internal_MEMORY_OUT_PTR]._access_size); log_printf(TRACE,Load_store_unit,FUNCTION," * data (old) : %.8x",data_old); log_printf(TRACE,Load_store_unit,FUNCTION," * data (new) : %.8x",data_new); log_printf(TRACE,Load_store_unit,FUNCTION," * address : %.8x",_load_queue [internal_MEMORY_OUT_PTR]._address); log_printf(TRACE,Load_store_unit,FUNCTION," * rdata : %.8x",_load_queue [internal_MEMORY_OUT_PTR]._rdata); log_printf(TRACE,Load_store_unit,FUNCTION," * shift : %d",_load_queue [internal_MEMORY_OUT_PTR]._shift); log_printf(TRACE,Load_store_unit,FUNCTION," * signed? : %d",_load_queue [internal_MEMORY_OUT_PTR]._is_load_signed); log_printf(TRACE,Load_store_unit,FUNCTION," * access_size : %d",_load_queue [internal_MEMORY_OUT_PTR]._access_size); Texception_t exception = _load_queue [internal_MEMORY_OUT_PTR]._exception; bool have_exception = ((exception != EXCEPTION_MEMORY_NONE) and (exception != EXCEPTION_MEMORY_MISS_SPECULATION)); // if exception, rdata content the address of load, else content read data. memory_out_data_rd = (have_exception)?data_old:data_new; memory_out_exception = (_load_queue[internal_MEMORY_OUT_PTR]._state == LOAD_QUEUE_COMMIT_CHECK)?EXCEPTION_MEMORY_LOAD_SPECULATIVE:exception; log_printf(TRACE,Load_store_unit,FUNCTION," * exception : %d",exception); log_printf(TRACE,Load_store_unit,FUNCTION," * exception : %d",memory_out_exception); break; // we have find a entry !!! stop the search } } if (not internal_MEMORY_OUT_VAL) { log_printf(TRACE,Load_store_unit,FUNCTION," * Store queue"); for (uint32_t i=0; i<_param->_size_store_queue; ++i) { internal_MEMORY_OUT_PTR = (reg_STORE_QUEUE_PTR_READ+i)%_param->_size_store_queue; // Can retire an store instruction if : // * state is commit // * none load must check this store bool val_head = ((i==0) and (_store_queue [internal_MEMORY_OUT_PTR]._state == STORE_QUEUE_COMMIT) and (_store_queue [internal_MEMORY_OUT_PTR]._send_commit == true) and (reg_STORE_QUEUE_NB_CHECK [internal_MEMORY_OUT_PTR] == 0) ); bool val_commit = ((_store_queue [internal_MEMORY_OUT_PTR]._state != STORE_QUEUE_EMPTY) and (_store_queue [internal_MEMORY_OUT_PTR]._send_commit == false)); if (val_head or val_commit) { log_printf(TRACE,Load_store_unit,FUNCTION," * find : %d",internal_MEMORY_OUT_PTR); internal_MEMORY_OUT_VAL = 1; internal_MEMORY_OUT_SELECT_QUEUE = SELECT_STORE_QUEUE; memory_out_context_id = _store_queue [internal_MEMORY_OUT_PTR]._context_id; memory_out_front_end_id = _store_queue [internal_MEMORY_OUT_PTR]._front_end_id; memory_out_ooo_engine_id = _store_queue [internal_MEMORY_OUT_PTR]._ooo_engine_id; memory_out_packet_id = _store_queue [internal_MEMORY_OUT_PTR]._packet_id ; memory_out_cancel = _store_queue [internal_MEMORY_OUT_PTR]._cancel; // memory_out_write_rd // memory_out_num_reg_rd memory_out_data_rd = _store_queue [internal_MEMORY_OUT_PTR]._address; // to the exception memory_out_exception = _store_queue [internal_MEMORY_OUT_PTR]._exception; memory_out_no_sequence = val_commit; break; // find an entry } } } // write output if (_param->_have_port_context_id) PORT_WRITE(out_MEMORY_OUT_CONTEXT_ID [0], memory_out_context_id ); if (_param->_have_port_front_end_id) PORT_WRITE(out_MEMORY_OUT_FRONT_END_ID [0], memory_out_front_end_id ); if (_param->_have_port_ooo_engine_id) PORT_WRITE(out_MEMORY_OUT_OOO_ENGINE_ID[0], memory_out_ooo_engine_id); if (_param->_have_port_rob_ptr) PORT_WRITE(out_MEMORY_OUT_PACKET_ID [0], memory_out_packet_id ); // PORT_WRITE(out_MEMORY_OUT_OPERATION [0], memory_out_operation ); // PORT_WRITE(out_MEMORY_OUT_TYPE [0], TYPE_MEMORY ); PORT_WRITE(out_MEMORY_OUT_CANCEL [0], memory_out_cancel ); PORT_WRITE(out_MEMORY_OUT_WRITE_RD [0], memory_out_write_rd ); PORT_WRITE(out_MEMORY_OUT_NUM_REG_RD [0], memory_out_num_reg_rd ); PORT_WRITE(out_MEMORY_OUT_DATA_RD [0], memory_out_data_rd ); // PORT_WRITE(out_MEMORY_OUT_WRITE_RE [0], memory_out_write_re ); // PORT_WRITE(out_MEMORY_OUT_NUM_REG_RE [0], memory_out_num_reg_re ); // PORT_WRITE(out_MEMORY_OUT_DATA_RE [0], memory_out_data_re ); PORT_WRITE(out_MEMORY_OUT_WRITE_RE [0], 0); PORT_WRITE(out_MEMORY_OUT_NUM_REG_RE [0], 0); PORT_WRITE(out_MEMORY_OUT_DATA_RE [0], 0); PORT_WRITE(out_MEMORY_OUT_EXCEPTION [0], memory_out_exception ); PORT_WRITE(out_MEMORY_OUT_NO_SEQUENCE [0], memory_out_no_sequence );// hack #ifdef DEBUG PORT_WRITE(out_MEMORY_OUT_ADDRESS [0], memory_out_data_rd); #else PORT_WRITE(out_MEMORY_OUT_ADDRESS [0], 0); #endif // ~~~~~[ Interface "dache_req" ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tcontext_t dcache_req_context_id = 0; Tpacket_t dcache_req_packet_id = 0; Tdcache_address_t dcache_req_address = 0; Tdcache_type_t dcache_req_type = 0; Tdcache_data_t dcache_req_wdata = 0; log_printf(TRACE,Load_store_unit,FUNCTION," * Test DCACHE_REQ"); internal_DCACHE_REQ_VAL = 0; internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ = (*_speculative_access_queue_control)[0]; // Test store and load queue if (_speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._state == SPECULATIVE_ACCESS_QUEUE_WAIT_CACHE) { log_printf(TRACE,Load_store_unit,FUNCTION," * speculative_access_queue [%d]",internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ); internal_DCACHE_REQ_VAL = 1; internal_DCACHE_REQ_SELECT_QUEUE = SELECT_LOAD_QUEUE_SPECULATIVE; if (_param->_have_port_dcache_context_id) { Tcontext_t context_id = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._context_id; Tcontext_t front_end_id = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._front_end_id; Tcontext_t ooo_engine_id = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._ooo_engine_id; dcache_req_context_id = ((ooo_engine_id<<(_param->_size_context_id + _param->_size_front_end_id )) | (front_end_id <<(_param->_size_context_id)) | (context_id)); } dcache_req_packet_id = DCACHE_REQ_IS_LOAD(_speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._load_queue_ptr_write); dcache_req_address = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._address;// & _param->_mask_address_msb; dcache_req_type = operation_to_dcache_type(_speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._operation); // log_printf(TRACE,Load_store_unit,FUNCTION," * address : %.8x",_speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._address); // log_printf(TRACE,Load_store_unit,FUNCTION," * mask : %.8x",_param->_mask_address_msb); log_printf(TRACE,Load_store_unit,FUNCTION," * dcache_req_address : %.8x",dcache_req_address); #ifdef SYSTEMC_VHDL_COMPATIBILITY dcache_req_wdata = 0; #endif } else { // Test an store must be commited. if (_store_queue [reg_STORE_QUEUE_PTR_READ]._state == STORE_QUEUE_VALID_NO_SPECULATIVE) { internal_DCACHE_REQ_VAL = 1; internal_DCACHE_REQ_SELECT_QUEUE = SELECT_STORE_QUEUE; if (_param->_have_port_dcache_context_id) { Tcontext_t context_id = _store_queue [reg_STORE_QUEUE_PTR_READ]._context_id; Tcontext_t front_end_id = _store_queue [reg_STORE_QUEUE_PTR_READ]._front_end_id; Tcontext_t ooo_engine_id = _store_queue [reg_STORE_QUEUE_PTR_READ]._ooo_engine_id; dcache_req_context_id = ((ooo_engine_id<<(_param->_size_context_id + _param->_size_front_end_id )) | (front_end_id <<(_param->_size_context_id)) | (context_id)); } // FIXME : il peut avoir plusieurs store avec le même paquet_id ... pour l'instant pas très grave car pas de retour (enfin seul les bus error sont des retours) dcache_req_packet_id = DCACHE_REQ_IS_STORE(reg_STORE_QUEUE_PTR_READ); dcache_req_address = _store_queue [reg_STORE_QUEUE_PTR_READ]._address; dcache_req_type = operation_to_dcache_type(_store_queue [reg_STORE_QUEUE_PTR_READ]._operation); dcache_req_wdata = _store_queue [reg_STORE_QUEUE_PTR_READ]._wdata; } } if (_param->_have_port_dcache_context_id) PORT_WRITE(out_DCACHE_REQ_CONTEXT_ID[0], dcache_req_context_id); PORT_WRITE(out_DCACHE_REQ_PACKET_ID [0], dcache_req_packet_id ); PORT_WRITE(out_DCACHE_REQ_ADDRESS [0], dcache_req_address ); PORT_WRITE(out_DCACHE_REQ_TYPE [0], dcache_req_type ); PORT_WRITE(out_DCACHE_REQ_WDATA [0], dcache_req_wdata ); } else { // Reset internal_MEMORY_OUT_VAL = 0; // internal_MEMORY_OUT_PTR =0 // internal_MEMORY_OUT_SELECT_QUEUE = SELECT_STORE_QUEUE; internal_DCACHE_REQ_VAL = 0; internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ = 0; // internal_DCACHE_REQ_SELECT_QUEUE = SELECT_LOAD_QUEUE_SPECULATIVE; } // Write output PORT_WRITE(out_MEMORY_OUT_VAL [0], internal_MEMORY_OUT_VAL); PORT_WRITE(out_DCACHE_REQ_VAL [0], internal_DCACHE_REQ_VAL); log_end(Load_store_unit,FUNCTION); }; }; // 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