#ifdef SYSTEMC /* * $Id: Address_management_transition.cpp 84 2008-05-13 18:04:50Z rosiere $ * * [ Description ] * */ #include "Behavioural/Core/Multi_Front_end/Front_end/Ifetch_unit/Address_management/include/Address_management.h" namespace morpheo { namespace behavioural { namespace core { namespace multi_front_end { namespace front_end { namespace ifetch_unit { namespace address_management { #undef FUNCTION #define FUNCTION "Address_management::transition" void Address_management::transition (void) { log_printf(FUNC,Address_management,FUNCTION,"Begin"); if (PORT_READ(in_NRESET) == 0) { // nothing is valid reg_PC_CURRENT_VAL = 0; reg_PC_NEXT_VAL = 0; reg_PC_NEXT_NEXT_VAL = 0; } else { // ========================================= // ===== PREDICT =========================== // ========================================= if (PORT_READ(in_PREDICT_ACK) and internal_PREDICT_VAL) { for (uint32_t i=0; i<_param->_nb_instruction; i++) reg_PC_NEXT_INSTRUCTION_ENABLE [i] = PORT_READ(in_PREDICT_INSTRUCTION_ENABLE [i]); if (_param->_have_port_instruction_ptr) reg_PC_NEXT_INST_IFETCH_PTR = PORT_READ(in_PREDICT_INST_IFETCH_PTR ); reg_PC_NEXT_BRANCH_STATE = PORT_READ(in_PREDICT_BRANCH_STATE ); if (_param->_have_port_branch_update_prediction_id) reg_PC_NEXT_BRANCH_UPDATE_PREDICTION_ID = PORT_READ(in_PREDICT_BRANCH_UPDATE_PREDICTION_ID); reg_PC_NEXT_NEXT_VAL = 1; // address is valid reg_PC_NEXT_NEXT = PORT_READ(in_PREDICT_PC_NEXT ); reg_PC_NEXT_NEXT_IS_DS_TAKE = PORT_READ(in_PREDICT_PC_NEXT_IS_DS_TAKE ); #ifdef STATISTICS (*_stat_nb_transaction_predict) ++; #endif } // ========================================= // ===== ADDRESS =========================== // ========================================= // transaction with icache if ( (internal_ADDRESS_VAL and PORT_READ(in_ADDRESS_ACK)) or not reg_PC_CURRENT_VAL) { #ifdef STATISTICS if (reg_PC_CURRENT_VAL) { (*_stat_nb_transaction_address) ++; for (uint32_t i=0; i<_param->_nb_instruction; i++) if (reg_PC_CURRENT_INSTRUCTION_ENABLE [i] == true) (*_stat_sum_packet_size) ++; } #endif Tcontrol_t pc_next_val = reg_PC_NEXT_VAL and reg_PC_NEXT_NEXT_VAL; // next pc became current pc reg_PC_CURRENT_VAL = pc_next_val; // if pc_next is not valid : don't erase PC and PC_IS_DS_TAKE : this register is send a the predict (to compute pc_next) if (pc_next_val) { reg_PC_CURRENT = reg_PC_NEXT ; reg_PC_CURRENT_IS_DS_TAKE = reg_PC_NEXT_IS_DS_TAKE ; reg_PC_CURRENT_INST_IFETCH_PTR = reg_PC_NEXT_INST_IFETCH_PTR ; reg_PC_CURRENT_BRANCH_STATE = reg_PC_NEXT_BRANCH_STATE ; reg_PC_CURRENT_BRANCH_UPDATE_PREDICTION_ID = reg_PC_NEXT_BRANCH_UPDATE_PREDICTION_ID; for (uint32_t i=0; i<_param->_nb_instruction; i++) reg_PC_CURRENT_INSTRUCTION_ENABLE [i] = reg_PC_NEXT_INSTRUCTION_ENABLE [i]; reg_PC_NEXT_VAL = reg_PC_NEXT_NEXT_VAL ; // if pc_next_next is not valid : don't erase PC_NEXT and PC_NEXT_IS_DS_TAKE : this register is send a the predict (to compute pc_next) if (reg_PC_NEXT_NEXT_VAL) { reg_PC_NEXT = reg_PC_NEXT_NEXT ; reg_PC_NEXT_IS_DS_TAKE = reg_PC_NEXT_NEXT_IS_DS_TAKE; } // invalid next next pc reg_PC_NEXT_NEXT_VAL = 0; } } // ========================================= // ===== EVENT ============================= // ========================================= if (PORT_READ(in_EVENT_VAL) and internal_EVENT_ACK) { log_printf(TRACE,Address_management,FUNCTION,"EVENT : Transaction"); reg_PC_CURRENT_VAL = 0; reg_PC_NEXT_VAL = 1; reg_PC_NEXT = PORT_READ(in_EVENT_ADDRESS); // Event is never is ds_take : // * branch miss speculation : can't be place a branch in delay slot // * load miss speculation : the load is execute, the event_address is the next address (also the destination of branch) // * exception : goto the first instruction of exception handler (also is not in delay slot). reg_PC_NEXT_IS_DS_TAKE = 0; // reg_PC_NEXT_INST_IFETCH_PTR = 0; // reg_PC_NEXT_BRANCH_STATE = BRANCH_STATE_NONE; // reg_PC_NEXT_BRANCH_UPDATE_PREDICTION_ID = 0; // reg_PC_NEXT_INSTRUCTION_ENABLE [0] = 1; // only the instruction at the event address is valid, because we have no information on the branch presence in the instruction bundle. // for (uint32_t i=1; i<_param->_nb_instruction; i++) // reg_PC_NEXT_INSTRUCTION_ENABLE [i] = 0; reg_PC_NEXT_NEXT_VAL = 0; // cancel all prediction (event is send at the predict unit) #ifdef STATISTICS (*_stat_nb_transaction_event) ++; #endif } } #if DEBUG >= DEBUG_TRACE log_printf(TRACE,Address_management,FUNCTION,"Address_Management : "); log_printf(TRACE,Address_management,FUNCTION,"Current : %d %d 0x%x",reg_PC_CURRENT_VAL, reg_PC_CURRENT_IS_DS_TAKE, reg_PC_CURRENT); log_printf(TRACE,Address_management,FUNCTION,"Next : %d %d 0x%x",reg_PC_NEXT_VAL, reg_PC_NEXT_IS_DS_TAKE, reg_PC_NEXT); log_printf(TRACE,Address_management,FUNCTION,"Next_Next : %d %d 0x%x",reg_PC_NEXT_NEXT_VAL, reg_PC_NEXT_NEXT_IS_DS_TAKE, reg_PC_NEXT_NEXT); #endif #if defined(STATISTICS) or defined(VHDL_TESTBENCH) end_cycle (); #endif log_printf(FUNC,Address_management,FUNCTION,"End"); }; }; // end namespace address_management }; // end namespace ifetch_unit }; // end namespace front_end }; // end namespace multi_front_end }; // end namespace core }; // end namespace behavioural }; // end namespace morpheo #endif