#ifdef SYSTEMC /* * $Id: Address_management_transition.cpp 88 2008-12-10 18:31:39Z 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_begin(Address_management,FUNCTION); log_function(Address_management,FUNCTION,_name.c_str()); if (PORT_READ(in_NRESET) == 0) { // nothing is valid reg_PC_CURRENT_VAL = 0; reg_PC_NEXT_VAL = 1; reg_PC_NEXT = 0x100>>2; 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_inst_ifetch_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_depth) 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 if (usage_is_set(_usage,USE_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 (usage_is_set(_usage,USE_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"); log_printf(TRACE,Address_management,FUNCTION," * IS_DS_TAKE : %d" ,PORT_READ(in_EVENT_IS_DS_TAKE )); log_printf(TRACE,Address_management,FUNCTION," * ADDRESS : %.8x (%.8x)",PORT_READ(in_EVENT_ADDRESS ),PORT_READ(in_EVENT_ADDRESS )<<2); log_printf(TRACE,Address_management,FUNCTION," * ADDRESS_NEXT : %.8x (%.8x)",PORT_READ(in_EVENT_ADDRESS_NEXT ),PORT_READ(in_EVENT_ADDRESS_NEXT )<<2); log_printf(TRACE,Address_management,FUNCTION," * ADDRESS_NEXT_VAL : %d" ,PORT_READ(in_EVENT_ADDRESS_NEXT_VAL)); 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 = PORT_READ(in_EVENT_IS_DS_TAKE); // 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 = PORT_READ(in_EVENT_ADDRESS_NEXT_VAL); reg_PC_NEXT_NEXT = PORT_READ(in_EVENT_ADDRESS_NEXT); reg_PC_NEXT_NEXT_IS_DS_TAKE = 0;//?? // Note : is_ds_take = address_next_val // Because, is not ds take, can continue in sequence #ifdef DEBUG_TEST if (PORT_READ(in_EVENT_ADDRESS_NEXT_VAL) and not PORT_READ(in_EVENT_IS_DS_TAKE)) throw ERRORMORPHEO(FUNCTION,_("Event : address_next_next_val but next is not a ds take")); #endif #ifdef STATISTICS if (usage_is_set(_usage,USE_STATISTICS)) (*_stat_nb_transaction_event) ++; #endif } } #if defined(DEBUG) and (DEBUG >= DEBUG_TRACE) log_printf(TRACE,Address_management,FUNCTION," * Dump PC"); log_printf(TRACE,Address_management,FUNCTION," * Current : %d %d 0x%.8x (%.8x)",reg_PC_CURRENT_VAL , reg_PC_CURRENT_IS_DS_TAKE , reg_PC_CURRENT , reg_PC_CURRENT <<2); log_printf(TRACE,Address_management,FUNCTION," * Next : %d %d 0x%.8x (%.8x)",reg_PC_NEXT_VAL , reg_PC_NEXT_IS_DS_TAKE , reg_PC_NEXT , reg_PC_NEXT <<2); log_printf(TRACE,Address_management,FUNCTION," * Next_Next : %d %d 0x%.8x (%.8x)",reg_PC_NEXT_NEXT_VAL, reg_PC_NEXT_NEXT_IS_DS_TAKE, reg_PC_NEXT_NEXT, reg_PC_NEXT_NEXT<<2); #endif #if defined(STATISTICS) or defined(VHDL_TESTBENCH) end_cycle (); #endif log_end(Address_management,FUNCTION); }; }; // 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