#ifdef SYSTEMC /* * $Id: Ifetch_queue_function_full_assoc_transition.cpp 145 2010-10-13 18:15:51Z rosiere $ * * [ Description ] * */ #include "Behavioural/Core/Multi_Front_end/Front_end/Ifetch_unit/Ifetch_queue/include/Ifetch_queue.h" namespace morpheo { namespace behavioural { namespace core { namespace multi_front_end { namespace front_end { namespace ifetch_unit { namespace ifetch_queue { #undef FUNCTION #define FUNCTION "Ifetch_queue::function_full_assoc_transition" void Ifetch_queue::function_full_assoc_transition (void) { log_begin(Ifetch_queue,FUNCTION); log_function(Ifetch_queue,FUNCTION,_name.c_str()); if (PORT_READ(in_NRESET) == 0) { reg_PTR_READ = 0; reg_PTR_WRITE = 0; for (uint32_t i=0; i<_param->_size_queue; i++) { _queue [i]->_state = IFETCH_QUEUE_STATE_EMPTY; _queue [i]->_address = 0; // not necessary _queue [i]->_inst_ifetch_ptr = 0; // not necessary _queue [i]->_branch_state = 0; // not necessary _queue [i]->_branch_update_prediction_id = 0; // not necessary _queue [i]->_exception = 0; // not necessary for (uint32_t j=0; j<_param->_nb_instruction; j++) { _queue [i]->_instruction [j] = 0; // not necessary _queue [i]->_instruction_enable [j] = 0; // not necessary } } } else { // ========================================================== // =====[ ADDRESS ]========================================== // ========================================================== #ifdef STATISTICS uint32_t stat_nb_inst_fetch=0; #endif if (PORT_READ(in_ADDRESS_VAL) and internal_ADDRESS_ACK) { log_printf(TRACE,Ifetch_queue,FUNCTION," * ADDRESS : Transaction"); log_printf(TRACE,Ifetch_queue,FUNCTION," * reg_PTR_WRITE : %d",reg_PTR_WRITE); log_printf(TRACE,Ifetch_queue,FUNCTION," * ADDRESS : 0x%x",PORT_READ(in_ADDRESS_INSTRUCTION_ADDRESS)); // New slot in ifetch_queue is allocated _queue[reg_PTR_WRITE]->_state = IFETCH_QUEUE_STATE_WAIT_RSP; #ifdef STATISTICS if (usage_is_set(_usage,USE_STATISTICS)) (*_sum_transaction_address) ++; #endif for (uint32_t i=0; i<_param->_nb_instruction; i++) { Tcontrol_t enable = PORT_READ(in_ADDRESS_INSTRUCTION_ENABLE [i]); #ifdef STATISTICS stat_nb_inst_fetch+=enable; #endif _queue[reg_PTR_WRITE]->_instruction_enable [i] = enable; } _queue[reg_PTR_WRITE]->_address = PORT_READ(in_ADDRESS_INSTRUCTION_ADDRESS); _queue[reg_PTR_WRITE]->_inst_ifetch_ptr = (_param->_have_port_inst_ifetch_ptr)?PORT_READ(in_ADDRESS_INST_IFETCH_PTR ):0; _queue[reg_PTR_WRITE]->_branch_state = PORT_READ(in_ADDRESS_BRANCH_STATE); _queue[reg_PTR_WRITE]->_branch_update_prediction_id = (_param->_have_port_depth)?PORT_READ(in_ADDRESS_BRANCH_UPDATE_PREDICTION_ID):0; reg_PTR_WRITE = (reg_PTR_WRITE+1)%_param->_size_queue; } #ifdef STATISTICS if (usage_is_set(_usage,USE_STATISTICS)) (*_stat_nb_inst_fetch)+=stat_nb_inst_fetch; #endif // ========================================================== // =====[ DECOD ]============================================ // ========================================================== bool have_instruction_decod = false; bool have_instruction_enable = false; uint32_t last_ptr = reg_PTR_READ; for (uint32_t i=0; i<_param->_nb_instruction; ++i) { if (internal_DECOD_VAL [i] and PORT_READ(in_DECOD_ACK[i])) { log_printf(TRACE,Ifetch_queue,FUNCTION," * DECOD [%d] : Transaction",i); uint32_t ptr = internal_DECOD_PTR [i]; uint32_t slot = internal_DECOD_SLOT[i]; have_instruction_decod = true; last_ptr = ptr; _queue[ptr]->_instruction_enable [slot] = false; } have_instruction_enable |= _queue[reg_PTR_READ]->_instruction_enable [i]; } // Test if all is decoded if (have_instruction_decod) { // Invalid all ptr while (reg_PTR_READ != last_ptr) { #ifdef DEBUG_TEST bool have_instruction_enable = false; for (uint32_t i=0; i<_param->_nb_instruction; ++i) have_instruction_enable |= _queue[reg_PTR_READ]->_instruction_enable [i]; if (have_instruction_enable) throw ERRORMORPHEO(FUNCTION,toString("Can't free : Ifetch_queue[%d] content an valid instruction.\n",reg_PTR_READ)); #endif _queue[reg_PTR_READ]->_state = IFETCH_QUEUE_STATE_EMPTY; reg_PTR_READ = (reg_PTR_READ+1)%_param->_size_queue; } // For last ptr, test if all instruction is disable bool have_instruction_enable = false; for (uint32_t i=0; i<_param->_nb_instruction; ++i) have_instruction_enable |= _queue[reg_PTR_READ]->_instruction_enable [i]; if (not have_instruction_enable) { _queue[reg_PTR_READ]->_state = IFETCH_QUEUE_STATE_EMPTY; reg_PTR_READ = (reg_PTR_READ+1)%_param->_size_queue; } } // ========================================================== // =====[ ICACHE_RSP ]======================================= // ========================================================== if (PORT_READ(in_ICACHE_RSP_VAL) and internal_ICACHE_RSP_ACK) { log_printf(TRACE,Ifetch_queue,FUNCTION," * ICACHE_RSP : Transaction"); Tpacket_t ptr = (_param->_have_port_ifetch_queue_ptr)?PORT_READ(in_ICACHE_RSP_PACKET_ID):0; for (uint32_t i=0; i<_param->_nb_instruction; i++) _queue[ptr]->_instruction [i] = PORT_READ(in_ICACHE_RSP_INSTRUCTION [i]); switch (PORT_READ(in_ICACHE_RSP_ERROR)) { case ICACHE_ERROR_NONE : _queue[ptr]->_exception = EXCEPTION_IFETCH_NONE ; break; case ICACHE_ERROR_BUS_ERROR : _queue[ptr]->_exception = EXCEPTION_IFETCH_BUS_ERROR; break; default : throw ERRORMORPHEO(FUNCTION,"icache_rsp_error : unknow value."); } switch (_queue[ptr]->_state) { case IFETCH_QUEUE_STATE_WAIT_RSP : _queue[ptr]->_state = IFETCH_QUEUE_STATE_HAVE_RSP; break; case IFETCH_QUEUE_STATE_ERROR_WAIT_RSP : _queue[ptr]->_state = IFETCH_QUEUE_STATE_EMPTY ; break; default : throw ERRORMORPHEO(FUNCTION,"icache_rsp : invalid ifetch_queue state."); } } // ========================================================== // =====[ EVENT_RESET ]====================================== // ========================================================== if (PORT_READ(in_EVENT_RESET_VAL) and internal_EVENT_RESET_ACK) { log_printf(TRACE,Ifetch_queue,FUNCTION," * EVENT_RESET : Transaction"); // Scan all entry of queue and test the status for (uint32_t i=0; i<_param->_size_queue; i++) switch (_queue[i]->_state) { case IFETCH_QUEUE_STATE_ERROR_WAIT_RSP : break; case IFETCH_QUEUE_STATE_WAIT_RSP : _queue[i]->_state = IFETCH_QUEUE_STATE_ERROR_WAIT_RSP; break; default : _queue[i]->_state = IFETCH_QUEUE_STATE_EMPTY ; break; } // all entry is empty (or wait respons to flush) // reset ptr // 1) reg_PTR_READ = reg_PTR_WRITE = = 0 // 2) reg_PTR_READ = reg_PTR_WRITE // In method 1), the probalitie than the entry pointed by reg_PTR_WRITE is a slot with state "error_wait_rsp" is more importate that the method 2) reg_PTR_READ = reg_PTR_WRITE; } #if defined(DEBUG) and (DEBUG >= DEBUG_TRACE) log_printf(TRACE,Ifetch_queue,FUNCTION," * Dump ifetch_queue"); log_printf(TRACE,Ifetch_queue,FUNCTION," * reg_PTR_WRITE : %d",reg_PTR_WRITE); log_printf(TRACE,Ifetch_queue,FUNCTION," * reg_PTR_READ : %d",reg_PTR_READ ); for (uint32_t i=0; i<_param->_size_queue; i++) { uint32_t index=(i+reg_PTR_READ)%_param->_size_queue; log_printf(TRACE,Ifetch_queue,FUNCTION," * [%d] 0x%.8x (0x%.8x) %d - %d %d %d - %s", index, _queue [index]->_address, _queue [index]->_address<<2, _queue [index]->_inst_ifetch_ptr, _queue [index]->_branch_state, _queue [index]->_branch_update_prediction_id, _queue [index]->_exception, toString(_queue [index]->_state).c_str() ); if (_queue [index]->_state != IFETCH_QUEUE_STATE_EMPTY) for (uint32_t j=0; j<_param->_nb_instruction; j++) log_printf(TRACE,Ifetch_queue,FUNCTION," * %d 0x%.8x (0x%.8x)", _queue [index]->_instruction_enable[j], _queue [index]->_instruction[j],(_queue [index]->_address+j)<<2); } #endif #ifdef STATISTICS if (usage_is_set(_usage,USE_STATISTICS)) for (uint32_t i=0; i<_param->_size_queue; i++) switch (_queue[i]->_state) { case IFETCH_QUEUE_STATE_EMPTY : break; case IFETCH_QUEUE_STATE_WAIT_RSP : (*_sum_use_queue_wait_rsp ) ++; break; case IFETCH_QUEUE_STATE_HAVE_RSP : (*_sum_use_queue_have_rsp ) ++; break; case IFETCH_QUEUE_STATE_ERROR_WAIT_RSP : (*_sum_use_queue_error_wait_rsp) ++; break; default : break; } #endif } log_end(Ifetch_queue,FUNCTION); }; }; // end namespace ifetch_queue }; // end namespace ifetch_unit }; // end namespace front_end }; // end namespace multi_front_end }; // end namespace core }; // end namespace behavioural }; // end namespace morpheo #endif