#ifdef SYSTEMC /* * $Id: Return_Address_Stack_transition.cpp 81 2008-04-15 18:40:01Z rosiere $ * * [ Description ] * */ #include "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Return_Address_Stack/include/Return_Address_Stack.h" namespace morpheo { namespace behavioural { namespace core { namespace multi_front_end { namespace front_end { namespace prediction_unit { namespace return_address_stack { #undef FUNCTION #define FUNCTION "Return_Address_Stack::transition" void Return_Address_Stack::transition (void) { log_printf(FUNC,Return_Address_Stack,FUNCTION,"Begin"); if (PORT_READ(in_NRESET)==0) { for (uint32_t i=0; i<_param->_nb_context; i++) { reg_TOP [i] = 0; reg_BOTTOM [i] = 0; reg_NB_ELT [i] = 0; reg_PREDICT_TOP [i] = 0; reg_PREDICT_BOTTOM [i] = 0; reg_PREDICT_NB_ELT [i] = 0; for (uint32_t j=0; j<_param->_size_queue [i]; j++) { reg_stack[i][j]._val = false; reg_stack[i][j]._predict = false; reg_stack[i][j]._miss = false; } } } else { // =================================================================== // =====[ PREDICT ]=================================================== // =================================================================== for (uint32_t i=0; i<_param->_nb_inst_predict; i++) if (PORT_READ(in_PREDICT_VAL [i]) and internal_PREDICT_ACK [i]) { log_printf(TRACE,Return_Address_Stack,FUNCTION,"PREDICT[%d] : Transaction",i); Tcontext_t context = (_param->_have_port_context_id)?PORT_READ(in_PREDICT_CONTEXT_ID [i]):0; Tcontrol_t push = PORT_READ(in_PREDICT_PUSH [i]); Tptr_t top_old = reg_PREDICT_TOP [context]; Tptr_t top_new = top_old; Tptr_t bottom_old = reg_PREDICT_BOTTOM [context]; log_printf(TRACE,Return_Address_Stack,FUNCTION," * context : %d",context); // Hit : push or (val and not miss and not empty) // Miss : ifetch is stall, no update if (internal_PREDICT_HIT [i]) { log_printf(TRACE,Return_Address_Stack,FUNCTION," * before"); log_printf(TRACE,Return_Address_Stack,FUNCTION," * reg_predict_top : %d",reg_PREDICT_TOP [context]); log_printf(TRACE,Return_Address_Stack,FUNCTION," * reg_predict_bottom : %d",reg_PREDICT_BOTTOM [context]); log_printf(TRACE,Return_Address_Stack,FUNCTION," * reg_predict_nb_elt : %d",reg_PREDICT_NB_ELT [context]); if (push) { // push : increase the top (circular) top_new = (top_old+1)%_param->_size_queue[context]; reg_stack [context][top_new]._val = true; // New addr reg_stack [context][top_new]._predict = true; // Is speculative (erase a old addr (or not)) //reg_stack [context][top_new]._miss = ; reg_stack [context][top_new]._address = PORT_READ(in_PREDICT_ADDRESS_PUSH [i]); // the stack is full, erase the most old stack // Test if full if (reg_PREDICT_NB_ELT[context]==_param->_size_queue[context]) reg_PREDICT_BOTTOM [context] = (bottom_old+1)%_param->_size_queue[context]; // A new data is write : the stack is not empty if (reg_PREDICT_NB_ELT[context]< _param->_size_queue[context]) reg_PREDICT_NB_ELT[context]++; } else { // pop // top_new = (top_old==0)?(_param->_size_queue[context]-1):(top_old-1); //reg_stack [context][top_new]._val = ; //reg_stack [context][top_new]._predict = ; //reg_stack [context][top_new]._miss = ; //reg_stack [context][top_new]._address = ; // the stack is empty if (reg_PREDICT_NB_ELT[context]>0) { top_new = (top_old==0)?(_param->_size_queue[context]-1):(top_old-1); reg_PREDICT_NB_ELT[context] --; } } reg_PREDICT_TOP [context] = top_new; log_printf(TRACE,Return_Address_Stack,FUNCTION," * after"); log_printf(TRACE,Return_Address_Stack,FUNCTION," * reg_predict_top : %d",reg_PREDICT_TOP [context]); log_printf(TRACE,Return_Address_Stack,FUNCTION," * reg_predict_bottom : %d",reg_PREDICT_BOTTOM [context]); log_printf(TRACE,Return_Address_Stack,FUNCTION," * reg_predict_nb_elt : %d",reg_PREDICT_NB_ELT [context]); } } // =================================================================== // =====[ DECOD ]===================================================== // =================================================================== for (uint32_t i=0; i<_param->_nb_inst_decod; i++) if (PORT_READ(in_DECOD_VAL [i]) and internal_DECOD_ACK [i]) { log_printf(TRACE,Return_Address_Stack,FUNCTION,"DECOD[%d] : Transaction",i); Tcontext_t context = (_param->_have_port_context_id)?PORT_READ(in_DECOD_CONTEXT_ID [i]):0; Tcontrol_t push = PORT_READ(in_DECOD_PUSH [i]); Tptr_t top_old = reg_TOP [context]; Tptr_t top_new = top_old; Tptr_t bottom_old = reg_BOTTOM [context]; //Tcontrol_t hit = internal_DECOD_HIT [i]; Tcontrol_t miss = PORT_READ(in_DECOD_MISS_PREDICTION [i]); log_printf(TRACE,Return_Address_Stack,FUNCTION," * context : %d",context); log_printf(TRACE,Return_Address_Stack,FUNCTION," * before"); log_printf(TRACE,Return_Address_Stack,FUNCTION," * reg_top : %d",reg_TOP [context]); log_printf(TRACE,Return_Address_Stack,FUNCTION," * reg_bottom : %d",reg_BOTTOM [context]); log_printf(TRACE,Return_Address_Stack,FUNCTION," * reg_nb_elt : %d",reg_NB_ELT [context]); if (push) { // push : increase the top (circular) top_new = (top_old+1)%_param->_size_queue[context]; reg_stack [context][top_new]._val = true; // New address reg_stack [context][top_new]._predict = false; // No speculative reg_stack [context][top_new]._miss = false; reg_stack [context][top_new]._address = PORT_READ(in_DECOD_ADDRESS_PUSH [i]); // Test if full : if true, then icrease the bottom (erase the most old stack) if (reg_NB_ELT[context]==_param->_size_queue[context]) reg_BOTTOM [context] = (bottom_old+1)%_param->_size_queue[context]; // A new data is write : the stack is not empty if (reg_NB_ELT[context]< _param->_size_queue[context]) reg_NB_ELT[context]++; } else { // pop // top_new = (top_old==0)?(_param->_size_queue[context]-1):(top_old-1); //reg_stack [context][top_new]._val = ; //reg_stack [context][top_new]._predict = ; //reg_stack [context][top_new]._miss = ; //reg_stack [context][top_new]._address = ; // the stack is empty if (reg_NB_ELT[context]>0) { top_new = (top_old==0)?(_param->_size_queue[context]-1):(top_old-1); reg_NB_ELT[context] --; } } reg_TOP [context] = top_new; log_printf(TRACE,Return_Address_Stack,FUNCTION," * after"); log_printf(TRACE,Return_Address_Stack,FUNCTION," * reg_top : %d",reg_TOP [context]); log_printf(TRACE,Return_Address_Stack,FUNCTION," * reg_bottom : %d",reg_BOTTOM [context]); log_printf(TRACE,Return_Address_Stack,FUNCTION," * reg_nb_elt : %d",reg_NB_ELT [context]); // have previous miss of ifetch ? // 2 miss : // 1) miss predict : is very limited (local at context), can be update very quickly // 2) miss decod : result is in commit stage ... if (miss) { reg_PREDICT_BOTTOM [context] = reg_BOTTOM [context]; reg_PREDICT_TOP [context] = reg_TOP [context]; reg_PREDICT_NB_ELT [context] = reg_NB_ELT [context]; // Scan full assoc !!! for (uint32_t j=0; j<_param->_size_queue [i]; j++) // Test if this slot is tagged with "predict" : if true, tagged as miss if (reg_stack [context][j]._predict) { reg_stack [context][j]._predict = false; reg_stack [context][j]._miss = true; } } } // =================================================================== // =====[ UPDATE ]=================================================== // =================================================================== for (uint32_t i=0; i<_param->_nb_inst_update; i++) if (PORT_READ(in_UPDATE_VAL [i]) and internal_UPDATE_ACK [i]) { ERRORMORPHEO(FUNCTION,"Fonction ŕ implémenter !!!!!!!!!!!!"); // Tcontrol_t miss = PORT_READ(in_UPDATE_MISS_PREDICTION [i]); // // // if (miss) // { // Tcontrol_t context = (_param->_have_port_context_id)?PORT_READ(in_UPDATE_CONTEXT_ID [i]):0; // Tcontrol_t ifetch = PORT_READ(in_UPDATE_PREDICTION_IFETCH [i]); // Tcontrol_t push = PORT_READ(in_UPDATE_PUSH [i]); // Tptr_t index = PORT_READ(in_UPDATE_INDEX [i]); // Taddress_t address = PORT_READ(in_UPDATE_ADDRESS [i]); // if (push) // { // // // push // // top_new = (top_old+1)%_param->_size_queue[context]; // // reg_stack [context][index]._val = true; // // reg_stack [context][index]._predict = false; // // reg_stack [context][index]._miss = false; // // reg_stack [context][index]._address = PORT_READ(in_UPDATE_ADDRESS [i]); // } // else // { // // //reg_stack [context][top_new]._val = ; // // //reg_stack [context][top_new]._predict = ; // // //reg_stack [context][top_new]._miss = ; // // //reg_stack [context][top_new]._address = ; // } // // // // Mouais bof ....... // // // reg_PREDICT_TOP [context] = index; // } } } #if defined(STATISTICS) or defined(VHDL_TESTBENCH) end_cycle (); #endif log_printf(FUNC,Return_Address_Stack,FUNCTION,"End"); }; }; // end namespace return_address_stack }; // end namespace prediction_unit }; // end namespace front_end }; // end namespace multi_front_end }; // end namespace core }; // end namespace behavioural }; // end namespace morpheo #endif